Secrets in argv, and scanners that fail open
A git clone with Authorization on argv is readable from ps, and a scanner that swallows errors is a silent pass. Two fixes from a PR review.
Read the entry →22 entries tagged “GitProxy”.
A git clone with Authorization on argv is readable from ps, and a scanner that swallows errors is a silent pass. Two fixes from a PR review.
Read the entry →A GitHub Actions step failed with Permission denied and exit code 126. The script was committed as 100644 because core.fileMode was off. Here's the fix.
Read the entry →Files missing from a published npm package: our vite UI build landed outside dist, so the files allowlist dropped it. Here's how I found and fixed it.
Read the entry →Passing obj.exec into a list strips this, so stateful plugins crash. Bind it, wrap it, or use an arrow field. Here is the GitProxy fix.
Read the entry →p.chains?.includes(name) dropped every plugin that omitted chains. Optional chaining in a filter is an accidental deny; default with ?? instead.
Read the entry →Record<string, T> types every key as present, so a typo compiled and getChain returned undefined. Thirteen tests failed from one missing key.
Read the entry →How to write a GitProxy plugin: a complete diff-scanning example, how to pick the right chain phase, and why a plugin can load and still never run.
Read the entry →A subclass field declaration overwrites what the base constructor assigned. useDefineForClassFields is why, and declare is the one-line fix.
Read the entry →Package subpath is not defined by exports, plus ts(2307): the file exists, the exports map hides it. Here's how to import a public type instead.
Read the entry →Cannot find package 'plugins' is Node treating a relative path as a package name. Here is the ESM specifier rule, and the one-character fix.
Read the entry →How to design a plugin system: named phases instead of positions, deny-by-default placement, and the defaults that must live outside your constructor.
Read the entry →Vitest 3 test fails with vi.mocked(...).mockResolvedValue is not a function after restoreAllMocks. Here's how to fix it in one line.
Read the entry →Bumping Vitest from 3 to 4 turned my git-proxy CI red while local stayed green. Stale node_modules, broken class mocks, and port clashes. Here's how I fixed each.
Read the entry →Build your own GitHub Actions bot that review pull requests with an LLM: PR Description Checker and Security Scanner.
Read the entry →Build a GitHub Actions bot that triages issues and PRs with an LLM: label, dedupe, security-scan, and run it on Claude, GPT, or Gemini. Here's how I did it.
Read the entry →Moving GitProxy's npm publish from a token to OIDC trusted publishers took a few lines, except for one thing that kept failing.
Read the entry →A Vitest test using expect().toThrow() let a JSON.parse SyntaxError escape and fail the run instead of catching it. Here's why, and the fix.
Read the entry →A containerized Node app failed with EACCES: permission denied, mkdir './.data' after dropping to a non-root user. Here's the cause and the fix.
Read the entry →How to fix all the ESM mocking errors when moving GitProxy's test suite from Mocha, Chai, Sinon and proxyquire to Vitest + TypeScript
Read the entry →Why "NODE_ENV=test" fails on Windows, and the one-line fix with cross-env.
Read the entry →A git-proxy test failed with 'undefined' is not valid JSON after moving from proxyquire to Vitest. Let's look at the cause and how to fix.
Read the entry →I've decided to share every debugging session and feature while building GitProxy in the open.
Read the entry →