I'm Ngo Quoc Viet, a fullstack engineer focused on practical open-source maintenance. I use reproducible diagnostics, test evidence, and agent-assisted implementation to turn concrete upstream issues into narrow, reviewable patches.
| Character stat | Current build |
|---|---|
| Class | Fullstack Engineer / OSS Contributor |
| Experience | Nearly 4 years across product and outsourced projects |
| Party role | Project-level Dev Lead experience in healthcare systems |
| Main quests | Developer platforms, AI tooling, MCP, desktop apps, Windows DX |
| Play style | Reproduce the issue → ship a narrow fix → add regression coverage → follow through on review |
My favorite contributions are the ones maintainers can immediately use: broken runtime paths, cross-platform bugs, stale setup flows, incorrect API behavior, missing safety checks, and tests that prevent the same regression from returning.
Public contribution data for NgoQuocViet2001, refreshed 2026-11-05. The merged count covers public PRs submitted from this account and accepted into repositories it does not own during the preceding 12 months.
| Stat | Total | Meaning |
|---|---|---|
| Merged quests | 179 | External PRs merged by community maintainers in the last 12 months |
| Worlds visited | 73 | Community repositories with at least one merged contribution |
| Active quests | 90 | External PRs currently open for maintainer review |
The most recent merges, newest first. Earlier merged work is summarized in the Guild History table below.
| Project | PR | Quest result | Merged |
|---|---|---|---|
| MikroORM | #8518 | Reads the collation, inline check and generated expression of the first column during SQLite introspection, so a collated or enum primary key no longer makes getUpdateSchemaSQL() rebuild the table right after schema.create(). |
2026-11-04 |
| Puppeteer | #15694 | Records the buildIdAlias in the cache metadata even when the build is already installed, so launch chrome@canary finds a cached Canary build and an alias that pointed to an older build is updated. |
2026-11-03 |
| TypeScript-DOM-lib-generator | #2576 | Matches the member name as a whole word when bolding it in generated MDN comments, so the DOMPointReadOnly.y comment bolds the standalone y instead of the last letter of DOMPointReadOnly. |
2026-11-03 |
| Redux Toolkit | #5472 | Stops merging name[] array params, and name[prop] params that clash with a plain name param, into one object, so the codegen no longer emits empty-key array wrappers or duplicate keys that fail tsc. |
2026-11-03 |
| Chai | #1893 | Makes .empty throw .empty was passed a function for async, generator and async generator functions too, as in chai 4, instead of passing them as objects with no own keys. |
2026-11-03 |
| Vue DevTools | #1181 | Lists the records from router.getRoutes() once on the Pages tab instead of also walking each record's children, so nested routes no longer appear twice with relative paths that navigate to the wrong URL. |
2026-11-03 |
| Unhead | #1028 | Ends extracted <script>, <style> and <title> content at the first closing tag, as browsers do, so a quote in a comment or regex no longer leaves script source as text in <head> or merges adjacent scripts. |
2026-11-03 |
| Pinia | #3203 | Removes stale getters and actions at the start of _hotUpdate, before the new definitions are applied, so a property that switches between getter, action and state during HMR no longer becomes undefined until a reload. |
2026-11-03 |
| tRPC | #7721 | Passes each page's cursor and direction to the procedure in the fetchInfinite, prefetchInfinite and infiniteQueryOptions server-side helpers, falling back to initialCursor, so prefetched infinite queries fetch the requested pages instead of repeating the first one. |
2026-11-02 |
| marked | #4161 | Ends a block quote before a lazy line that follows a table, as cmark-gfm does, so the unquoted line renders as a paragraph after the quote instead of inside it. | 2026-11-02 |
| Mongoose | #16634 | Converts ObjectId keys to strings in MongooseMap#has(), as get(), set() and delete() already do, so has(userId) returns true for a key that get(userId) finds. |
2026-11-01 |
| Inquirer.js | #2371 | Merges the locale strings in @inquirer/i18n prompts before the user's theme, so a custom maskedText, keysHelpTip or confirm keyword is no longer replaced, and a custom keysHelpTip receives the translated labels. |
2026-10-31 |
| vscode-js-debug | #2445 | Leaves % unescaped in a logpoint message that interpolates no {expression}, since console.log only applies format specifiers when it gets more than one argument, so 50% done no longer logs as 50%% done. |
2026-10-31 |
| Vue Test Utils | #2983 | Treats any DOM Node ref as an element in findComponent({ ref }), not only an HTMLElement, so a ref on an <svg> returns an empty wrapper instead of throwing a TypeError. |
2026-10-30 |
| Pake | #1426 | Decodes the percent-encoded last URL path segment when naming downloads, as browsers do, so a link to Annual%20Report.pdf saves as Annual Report.pdf, while unsafe or malformed names keep their encoded form. |
2026-10-30 |
| Ghost | #32355 | Closes the outermost format the next text lacks, with every format nested inside it, in the Lexical HTML renderer, so bold that ends while italic continues no longer spreads onto italic-only text in posts and newsletters. | 2026-10-30 |
| vscode-languageserver-node | #1931 | Accepts relative patterns in NotebookDocumentFilter.is, as TextDocumentFilter.is already does, so the client's asDocumentSelector no longer drops a notebook filter with a relative pattern or turns it into a plain language filter. |
2026-10-30 |
| Go-MySQL-Driver | #1832 | Flips the inverted unknown-collation check in the handshake, so charset=utf8mb4&collation=utf8mb4_0900_as_ci connects and sets the collation with SET NAMES, while an unknown collation without charset fails instead of silently using the default. |
2026-10-30 |
| Solid | #4424 | Reads a getter class through the props object when h merges it with selector classes, so a component forwarding props to h("button.btn", props) gets a reactive merged class instead of throwing Invalid property descriptor. |
2026-10-30 |
| Xinference | #5915 | Replaces a dangling cache symlink when an image, audio, video or world model with a local model_uri is launched, so re-registering a model after moving its weights no longer fails every launch with FileExistsError. |
2026-10-30 |
| MiniJinja | #991 | Formats floats like Python's str() in the pycompat str.format when no precision is given, so floats keep all their digits and '{}'.format(1234567.0) gives 1234567.0 instead of 1.23457e+06. |
2026-10-29 |
| dotenv | #1078 | Exits with the shell's 128 + signal status when the command started by dotenv run dies from a signal Node ignores, such as SIGPIPE, so piping its output into head no longer hangs the pipeline. |
2026-10-29 |
| Knip | #2254 | Escapes pipe characters in symbols in the markdown reporter, so a duplicate export row keeps its three cells instead of putting default under Location, the file path under Severity and dropping the severity. |
2026-10-29 |
| VitePress | #5555 | Compares the code block language case-insensitively in isShell, so the copy button strips the $ prompt from Bash, SH, Shell and ZSH blocks the same way it does for bash instead of copying it. |
2026-10-29 |
| eslint-plugin-vue | #3211 | Applies the ignore and ignoreParents options of vue/no-deprecated-slot-attribute to v-bind:slot as well, so --fix no longer rewrites a bound slot under an ignored web component into <template v-slot:[...]>. |
2026-10-29 |
| Ghost | #32192 | Maps the kg-style-accent class to accent and only converts inline button colours when parsing CTA cards from HTML, so brand colour buttons are no longer stored as #00NaNNaN and keep the accent style in newsletters. |
2026-10-27 |
| vscode-js-debug | #2441 | Keeps the outer range's end when Range.simplify merges a range nested inside it, so the step skipList for WASM/DWARF frames no longer cuts off the tail of a region that should be skipped. |
2026-10-26 |
| vscode-languageserver-node | #1918 | Counts the change annotations passed to new WorkspaceChange(edit) and skips ids already in use, so wrapping an existing WorkspaceEdit keeps its labels and needsConfirmation and adding an annotation no longer throws Id 1 is already in use. |
2026-10-26 |
| MiniJinja | #979 | Splits a comma-separated attribute list in the Go sort filter and, in Go and Rust, compares the string parts of such composite keys case-insensitively like Jinja2, so sort(attribute="name, state") no longer returns items in their original order. |
2026-10-26 |
| insta | #952 | Checks unsigned-to-signed conversions with try_from in Content::as_i64 and as_i128 and adds a u128 fallback for JSON map keys, so assert_json_snapshot! wr
8000
ites a u64::MAX key as 18446744073709551615 instead of -1. |
2026-10-26 |
| Vue DevTools | #1179 | Treats only ancestors on the current path as circular in encodeValue, so a value repeated without a cycle, like the same Date in start and end, shows as a real value in component state instead of [Circular value:N]. |
2026-10-26 |
| Solid | #4258 | Decodes character references in static attribute values of html templates once when the template is built, so placeholder="Search…" shows Search… and & in an href or component prop becomes &. |
2026-10-25 |
| VitePress | #5550 | Treats a code fence as closed only by a fence line at least as long as the opener with no info string, and passes that state to nested includes, so fenced includes no longer render @include-start markers with the build machine's path. |
2026-10-24 |
| Inquirer.js | #2330 | Treats an empty VISUAL or EDITOR as unset in @inquirer/external-editor, so export VISUAL= with EDITOR=nano opens nano again instead of failing every edit() call and editor prompt with LaunchEditorError. |
2026-10-23 |
| Puppeteer | #15650 | Maps the Space key to ' ' in the WebDriver BiDi input layer, so keyboard.press('Space') types a space in Firefox and in Chrome over BiDi, as it already does over CDP, instead of throwing Unknown key: "Space". |
2026-10-23 |
| Community project | Merged quests | Contribution territory |
|---|---|---|
| HakanSeven12/OpenCADStudio | 16 | CAD geometry, commands, expression evaluation, dimension styling, unit formatting, DWG rendering, Windows file locking, and printer integration |
| slidevjs/slidev | 11 | Base-path routing, reactive frontmatter, addon preprocessing, test lifecycle cleanup, local exports, scaffold setup, slide-patch bounds, parser input validation, Monaco write-back paths, and code-fence language parsing |
| mountain-loop/yaak | 9 | Curl import parsing, shell-safe curl and gRPCurl export, OAuth 1.0 PLAINTEXT signing, JSON template escaping, Postman API key import, UUID v6 timestamps, and XPath attribute and text-node values |
| tinyhumansai/openhuman | 9 | Desktop OAuth, deep links, packaging, startup cleanup, RPC security, AppImage release safety, Windows contributor setup, and Windows installer failure reporting |
| CJackHwang/ds2api | 8 | OpenAI-compatible routes, streaming, citations, tool output, Vercel sync, and file metadata |
| github/spec-kit | 6 | Development agent symlinks, safe Kiro multi-install behavior, authentication host matching, workflow step-type validation, and workflow expression indexing and grouping |
| Anil-matcha/Open-Generative-AI | 5 | Local AI model storage, onboarding, endpoint fallback, startup feedback, and reproducible setup |
| earthtojake/text-to-cad | 5 | Windows SMB write resilience, cross-language CAD selector and label parity, and DXF arc angle parsing |
| microsoft/vscode-languageserver-node | 5 | JSON-RPC parallelism slot accounting, semantic-token delta baselines, notebook cell-map cleanup for deleted cells, change-annotation preservation in wrapped workspace edits, and relative-pattern notebook document filters |
| Crosstalk-Solutions/project-nomad | 4 | Offline content download reliability, benchmark startup correctness, orphaned download-job handling, and chat stream cleanup |
| DayuanJiang/next-ai-draw-io | 4 | MCP diagram edit consistency, stale-state protection, multi-page export preservation, and admin settings path validation |
| drawdb-io/drawdb | 4 | Clipboard schema validation, self-referencing foreign keys, SQL literal escaping for enum values, and SQL Server export of fieldless custom types |
| jdx/mise | 4 | Filesystem-safe install linking, portable generated bootstrap paths, and nushell and elvish activation correctness |
| repowise-dev/repowise | 4 | Health-analysis precision, sink-reachability sharing, wiki page scoping, and CLI exit-code correctness |
| markedjs/marked | 3 | CommonMark link reference label normalization and block quote lazy-continuation boundaries after headings, thematic breaks, HTML blocks, and tables |
| microsoft/vscode-js-debug | 3 | Zero-directory matching for middle ** in skipFiles globs, contained-range merging in step skip lists, and literal % in logpoint messages that interpolate nothing |
| neurosnap/zmx | 3 | Session wildcard matching, prefixed picker behavior, and nested-session documentation |
| puppeteer/puppeteer | 3 | Cookie deletion filters by domain, path, URL, and partition key, WebDriver BiDi Space key input, and alias recording for already installed browser builds |
| SBoudrias/Inquirer.js | 3 | Whitespace-only input handling in number prompts, empty VISUAL and EDITOR fallback in the external editor, and user theme precedence over locale defaults in localized prompts |
| tt-a1i/archify | 3 | CLI validation, renderer-bound safety, and full-width text measurement |
| Automattic/mongoose | 2 | ReadPreference instance handling for index and collection auto-creation and ObjectId key lookups in MongooseMap#has() |
| logto-io/logto | 2 | Tenant initialization error observability and accurate contributor prerequisites |
| microsoft/vscode-css-languageservice | 2 | CSS Color 4 rgb() completions and ICSS :import property linting |
| mitsuhiko/minijinja | 2 | Multi-attribute sort filter keys and str()-style float formatting in str.format |
| nodejs/undici | 2 | Decompression encoding lookup safety and cookie Expires serialization |
| ruvnet/RuView | 2 | ESP32 swarm configuration validation and mesh-to-dashboard documentation |
| solidjs/solid | 2 | Character reference decoding in static html template attributes and selector-class merging with getter class props in h |
| TryGhost/Ghost | 2 | CTA card accent button colours parsed from HTML and overlapping text-format nesting in the Lexical HTML renderer |
| tw93/Pake | 2 | CLI startup independence from native image dependencies and percent-encoded file name decoding for downloads |
| virgiliojr94/book-to-skill | 2 | Literal handling for bracketed input paths and invisible-carrier sanitization |
| vitejs/vite | 2 | Config-bundle resource cleanup on failed generation and srcset density-descriptor parsing |
| vuejs/devtools | 2 | Ancestor-only circular reference detection in value encoding and one row per route on the Pages tab |
| vuejs/vitepress | 2 | Include marker handling inside nested code fences and shell prompt stripping for uppercase fence languages |
| xorbitsai/inference | 2 | Truthful ban accounting in bulk unban responses and dangling model_uri cache link replacement for image, audio, video, and world models |
Community repositories with one merged contribution so far:
| Community project | Contribution territory |
|---|---|
| 3b1b/manim | Graph point lookup on manual curves outside unit x-ranges |
| addyosmani/agent-skills | Eval grader-result validation and summary integrity |
| agegr/pi-web | Wrapper process lifecycle, signal forwarding, and exit statuses |
| cathrynlavery/diagram-design | Accessible keyboard navigation for diagram gallery choices |
| chaijs/chai | .empty rejection of async and generator functions |
| esengine/DeepSeek-Reasonix | Remote install manifest size enforcement |
| go-sql-driver/mysql | Unknown collation handling in the handshake with and without a charset |
| honojs/hono | Base-path resolution for regex route params |
| infiniflow/ragflow | CLI benchmark failure accounting by response envelope |
| microsoft/AI-For-Beginners | Quiz completion driven by each quiz's own question count |
| microsoft/TypeScript-DOM-lib-generator | Whole-word member name bolding in MDN doc comments |
| mikro-orm/mikro-orm | First-column definitions in SQLite table introspection |
| mitsuhiko/insta | JSON snapshot map keys for large unsigned integers |
| motdotla/dotenv | CLI exit status for commands killed by SIGPIPE |
| NVIDIA-NeMo/Switchyard | Nested protocol metadata normalization and header precedence |
| NVIDIA/cuda-rust | Early validation for variadic CUDA device extern declarations |
| OmniNull/OmniWM | Complete public CLI and IPC command reference |
| opengeos/GeoLibre | Geographic-to-planar projection for buffer processing |
| pacifio/atlas | Agent turn epoch handling and late transcript events |
| paperless-ngx/paperless-ngx | Sanity-check data correctness and regression coverage |
| pingdotgg/t3code | Cross-platform repository symlink integrity |
| pnpm/pnpm | Prerelease range-style preservation across TypeScript and Rust update paths |
| pranshuparmar/witr | Localized Windows netstat listener detection |
| python-poetry/poetry | Extension wheel tag handling in the build tests |
| reduxjs/redux-toolkit | Bracketed query parameter grouping in RTK Query OpenAPI codegen |
| rollup/rollup | CRLF-safe line-break removal when suppressing ASI |
| rorkai/App-Store-Connect-CLI | CLI argument validation before authentication |
| supertone-oss-archive/supertonic | Multi-language CLI option documentation |
| TheJoeFin/Text-Grab | Language-aware Latin correction across OCR capture paths |
| trpc/trpc | Cursor forwarding in createServerSideHelpers infinite helpers |
| unjs/unhead | Closing-tag detection for extracted script, style, and title content |
| vectorize-io/hindsight | Weekend-relative date resolution |
| vuejs/eslint-plugin-vue | ignore and ignoreParents options for v-bind:slot in no-deprecated-slot-attribute |
| vuejs/pinia | HMR updates for store properties that change kind |
| vuejs/test-utils | findComponent ref lookups on SVG and other non-HTML elements |
| webpro-nl/knip | Pipe escaping for symbols in the markdown reporter |
| withastro/astro | Page-directory boundary correctness and regression coverage |
| xuanyustudio/LocalMiniDrama | Volcengine Omni endpoint routing for custom video providers |
| ZSeven-W/openpencil | CLI positional argument forwarding |
The newest open contributions waiting for maintainer review, ordered by creation time. 90 are open in total; the 20 most recent are listed here.
| Project | PR | Quest in progress |
|---|---|---|
| msgspec | #1320 | Caps the integer part of each ISO 8601 duration segment at the largest timedelta in seconds rather than 2**47, so day counts like P106751991167301D raise ValidationError instead of wrapping to a wrong timedelta or a bare OverflowError. |
| Floating UI | #3540 | Skips disabled cells when useListNavigation or Composite loops vertically in a grid with cols > 1, so ArrowUp from the top row lands on the nearest enabled item in the column and ArrowDown wraps even when every cell below is disabled. |
| concurrently | #640 | Registers a command as an input target under its name only when it has one, so with --handle-input a line like :observer.start() goes unchanged to the default target instead of reaching the last unnamed command with its colon stripped. |
| insta | #958 | Writes an indentation indicator such as |2- for YAML literal blocks whose first line starts with a space or tab, so with INSTA_YAML_BLOCK_STYLE=1 that leading whitespace survives a read and the snapshot file still parses. |
| eslint-plugin-vue | #3231 | Makes a bare <!-- eslint-enable --> in <template> clear rule-specific block disables, and <!-- eslint-enable vue/no-v-html --> re-enable that rule under a bare <!-- eslint-disable -->, so template directives turn rules back on where ESLint does instead of keeping them off until </template>. |
| indicatif | #854 | Makes MultiProgress::add and the insert* methods return an existing member unchanged, as documented, so re-adding a bar no longer moves it or leaves a stale slot that stops finished bars from being pruned. |
| Crossterm | #1159 | Implements Ord and PartialOrd for KeyEvent on the same case-normalized fields that eq and hash use, so a BTreeMap or BTreeSet keyed by KeyEvent or Event finds Shift+letter bindings that a HashMap already finds. |
| Sarama | #3848 | Unlocks txnLock before the transactional mocks.AsyncProducer reports a message sent outside a transaction, so the violation fails fast instead of blocking BeginTxn, CommitTxn, TxnStatus and the next input until the go test timeout. |
| zerolog | #826 | Computes TimeFormatUnixMs and TimeFormatUnixMicro values the way UnixMilli and UnixMicro do instead of dividing UnixNano, so times before 1678 or after 2262, like the zero time.Time, are no longer logged as unrelated dates. |
| unimport | #579 | Checks for leftover Vue directives with String#search instead of RE_DIRECTIVE.test(), so the global regex keeps no stale lastIndex and a repeated or following transform no longer skips directive imports or drops the resolveDirective import. |
| Magicast | #188 | Builds non-identifier keys of assigned objects as StringLiteral nodes, so the object proxy can read, list, delete and overwrite a key like "@" it just wrote, and a second deepMergeObject merges instead of adding a duplicate key. |
| vscode-pull-request-github | #9097 | Decodes the percent-encoded path of blob permalinks before the local file check, so links in PR and issue overviews to files like docs/My Notes.md or app/[slug]/page.tsx open locally instead of staying plain GitHub links. |
| jq | #3695 | Passes every digit of a number literal to jvp_strtod() rather than rounding to 17 significant digits first, so 100000000000000041 * 1 prints 100000000000000050 like a --disable-decnum build instead of 100000000000000030. |
| Koa | #2022 | Gives a JSON null body the same status and length handling as a string body, so ctx.type = 'json'; ctx.body = null responds 200 instead of 404 and no longer keeps a stale Content-Length that leaves clients waiting. |
| vscode-eslint | #2251 | Adds the problem's fixability to the rule severity cache key, so an eslint.rules.customizations entry with fixable applies to each problem instead of letting the first problem of a rule like eqeqeq decide for all later ones. |
| Supabase JS SDK | #2790 | Writes the Resources: header with its colon when signInWithWeb3 builds a Sign-In-With-Solana message for a wallet without signIn(), so the Auth server parses messages that list resources instead of rejecting them with 400 validation_failed. |
| Payload | #19049 | Sends fallback-locale=false when an SDK call passes fallbackLocale: false, so the REST API turns locale fallback off instead of filling untranslated localized fields with default-locale content. |
| Hugging Face Datasets | #8891 | Ignores .md and .toml files other than task.toml and instruction.md when inferring the builder, so folders with a LICENSE.md or pyproject.toml beside their data load with the json, csv or fasta builder instead of failing as a Harbor dataset. |
| {fmt} | #4999 | Uses the native or generic string the path formatter selected for wide output too, so L"{:g}" prints C:/foo on Windows like "{:g}" does instead of ignoring g, and wide {:g} and {:?g} keep the generic form on POSIX. |
| PixiJS | #12335 | Reads x and y into locals before writing in math-extras Point.rotate, so |
| Inventory slot | Equipped tools |
|---|---|
| Frontend | JavaScript, TypeScript, React, Vue, Next.js, Vite, Tailwind CSS |
| Backend | Node.js, C#, ASP.NET, PHP, Laravel, Python, Java, Go, Rust |
| Data stores | MySQL, PostgreSQL, MongoDB, Redis |
| Infrastructure | AWS, Linux, Docker, Nginx, CI/CD, GitHub Actions, VPS operations |
| AI developer tooling | Codex, MCP, Claude Code, OpenAI-compatible APIs, agent workflows |
| Product toolkit | Git, GitHub, Figma, Postman, VS Code |
- AI developer tooling: MCP servers, Codex integrations, context optimization, local analytics, safe upgrade paths.
- Windows-first reliability: PowerShell,
pwsh,cmd, Git Bash, WSL, symlink restrictions, desktop deep links, packaging quirks. - API and data correctness: OpenAI-compatible routes, streaming behavior, file metadata, citation markers, validation, and counting semantics.
- Release safety: dependency checks, runtime guards, reproducible setup, CI and test lifecycle fixes.
- Maintainer-friendly delivery: narrow diffs, issue-backed scope, concrete tests, concise validation, and follow-up fixes.
| Project | What it equips |
|---|---|
| codex-keyring | Native multi-account manager for Codex with aliases, health checks, and failover support |
| codex-observatory | Local Codex usage analytics, token trends, model breakdowns, and dashboard views |
| google-workspace-mcp | MCP server for structured Google Docs and Sheets extraction with image-aware output |
- Fullstack delivery across product and outsourced environments, with project bootstrapping, reusable component design, code review, Git flow, mentoring, and internal training.
- Project-level Dev Lead experience in healthcare systems, including BA/QC/developer coordination and legacy-parity work.
- Hands-on deployment and support across AWS, Linux, Docker, Nginx, CI/CD, VPS, staging, and production environments.
- AWS Certified Solutions Architect – Associate, scored 861/1000.
Open to OSS collaboration, maintainer support, developer tooling, automation, and practical fullstack/internal-tool work.