chore(yun-tianming): collapse duplicated signing, retry and cache blocks

Merged
FE
1d ago
+45-40

Summary

  • src/commands/domain.ts: the three-way copy of "which project signs this org mutation in agent mode" (domainDelegate, zoneDelegate, zoneRelease) is now one local helper, signingScope, carrying the constraint comment once. The doc comment describing zoneDelegate was attached to the orgArgOf const declared between them; the const now sits above the comment so the doc lands on the function it describes. The inline --org suffix in domainDelegate's watch hint now uses the existing orgArgOf.
  • src/commands/github.ts: the byte-identical 429-tolerant poll catch in authorizeTerminal and findCallerRepo is one local helper, backOff, that rethrows a non-429 ApiError and returns the next interval.
  • src/commands/upgrade.ts: the read-merge-write cache expression repeated in upgrade (twice) and backgroundCheck is one local helper, recordLatest, returning the written cache so backgroundCheck keeps using it.
  • src/commands/postgres.ts: resolveDbUrl reuses the module's existing resolvePostgres instead of repeating its two lines; resolvePostgres takes the same structural { request } type resolveDbUrl already accepts.
  • src/commands/ssh-config.ts: planCertAuthority ran the pure isSupersededAnchor predicate over every line twice to build the removed set and then its complement; the kept lines are now collected in the same pass.
  • src/agent.ts: agentHeaders called the pure canonicalTarget(path) twice; the single result is hoisted above the first use.

Safety

  • domain.ts signingScope — duplicate collapse: the three copies were textually identical (same deps?.project ?? readProject() fallback, same org check, same projectId ? { projectId } : undefined shape); readProject is still awaited before rawRequest, as before. test/domain.test.ts and test/zone.test.ts assert the exact scope ({ projectId: 'p1' } or undefined) for matched and mismatched --org.
  • domain.ts doc-comment / orgArgOf reorder — pure refactor, reorder declarations of a non-exported const; it is only called at runtime after module evaluation, so the TDZ is unaffected. orgArgOf(opts) is the same expression the hint inlined; test/domain.test.ts checks the hint carries --org org9.
  • github.ts backOff — duplicate collapse: both catch blocks were byte-identical apart from a comment; the helper preserves "non-429 ApiError rethrows, anything else backs off by 5s". test/github-connect.test.ts exercises both authorizeTerminal and findCallerRepo.
  • upgrade.ts recordLatest — duplicate collapse: identical modulo the variable name; the same object is written and returned. test/upgrade-resolver.test.ts and test/upgrade.test.ts run upgrade and backgroundCheck against a temp cache file and assert its contents.
  • postgres.ts resolveDbUrl → resolvePostgres — duplicate collapse: both statements were identical (GET /services${q(branch)} then resolveSoleService(..., 'postgres', service)); the widened parameter type is on a non-exported function. test/db-url.test.ts, test/db-query.test.ts (resolveDbUrl) and test/postgres-access.test.ts (resolvePostgres via dbPublicAccess/dbPrivateAccess) cover both callers.
  • ssh-config.ts planCertAuthority — redundant work removed: isSupersededAnchor is a pure string predicate, so the complement of the removed set is the kept set by construction; order of kept is unchanged. The known_hosts trust anchor, an anchor rotation can be taken back and matched field by field suites in test/ssh-config.test.ts (26 tests) ran, not skipped.
  • agent.ts canonicalTarget hoist — redundant work removed: canonicalTarget is pure (new URL with a fixed base); it was already evaluated before the /agent/sessions check in every path, so a throw happens at the same point. test/agent.test.ts (10 tests) covers bootstrap, project-route and scoped paths.

Verification

Baseline on the untouched tree:

npm run typecheck          # exit 0
npm test                   # 106 files, 2110 passed | 135 skipped, ~31s

Final tree:

npm run typecheck          # exit 0
npm test                   # 106 files, 2110 passed | 135 skipped, ~30s

Targeted runs after each edit: npx vitest run test/domain.test.ts test/zone.test.ts test/agent.test.ts test/github-connect.test.ts test/upgrade-resolver.test.ts test/upgrade.test.ts test/ssh-config.test.ts test/ssh-known-hosts-injection.test.ts test/db-url.test.ts test/postgres-access.test.ts test/db-query.test.ts → 392 passed, 18 skipped (the 18 are the ssh -G block, skipped because ssh is not installed here).

The 135 skips are pre-existing: ssh-keygen and ssh are absent on this machine, so the keygen-gated describe blocks in test/ssh-orchestration.test.ts and the ssh -G block in test/ssh-config.test.ts do not run. There is no lint script. No suite needs a database or Docker.

Deferred findings

  • src/commands/project.ts resolveProjectName (defect): splits cwd and homedir() on / only. On Windows (C:\Users\alice\myapp) the whole path becomes one segment, so the project is created as c-users-alice-myapp and the generic-directory and home-directory guards never trigger. test/create-name.test.ts only uses POSIX paths. A fix (path.basename) changes the created name, so it is the owners' call.
  • src/commands/postgres.ts: the branch/group query-string preamble is repeated in dbAlwaysOn, dbLimits, dbStats, dbVolume, dbRestart (and settingsSuffix is a sixth variant), and the "no manageable instance" guard appears four times with slightly different wording. Those command bodies call ApiClient.load()/requireProject() directly and are not exercised by any test (only their pure helpers are), so left alone.
  • src/commands/compute.ts setDomain/checkDomain: the 409 → domainConflictMessage mapping line is byte-identical in both, and removeDomain repeats the preamble. Covered by the domain-flow tests, but the gain is one line in a 2200-line file; left for a sweep that touches that area.
  • src/commands/auth.ts loginOauth/loginDevice: identical five-line tail (double setSession, /me, persist, same printed line). loginOauth's body has no direct test; not refactored.
  • src/commands/services.ts servicesRemove/servicesRename and src/commands/storage.ts storageGet/storageDelete/storageSetAccess: identical preambles, command bodies not covered by tests; not refactored.
  • src/commands/setup.ts openPromptInput vs canPromptViaTty: two helpers encode the same stdin-TTY / win32 / /dev/tty decision in the same order and can drift apart; canPromptViaTty has no direct test.
  • src/ensure-skills.ts imports resolveSpawnable through the commands/setup.ts re-export rather than from src/spawn.ts; a cross-module import change, so not touched.
  • src/config.ts persistAutoLink walks findProjectRoot once in isHomeLinkTarget and again inside writeProject; the second walk is across a function with side effects between, so left.
  • 40 exported symbols are only referenced inside their own file (full list recorded in the sweep notes); dropping export is an API-surface change and several are intentional test seams, so not changed.
  • The domainStatusLines verdict ladder in compute.ts is repeated three times with differing messages; similar, not identical, so not collapsed.

Filed, not fixed here


Opened by Yun Tianming: nightly sweep 2026-10-23-1000, model claude-fable-5-1, 75 turns, 6 files, 85 changed lines.
Verification: npm run typecheck (exit 0) and npm test (106 files, 2110 passed, 135 skipped, identical to baseline) on the final tree; ssh-keygen/ssh-gated suites skip on this machine.

🤖 Generated with Claude Code


Summary by cubic

Collapses duplicated signing, retry, and cache logic across six command files without changing behavior. The 429-tolerant poll backoff in github.ts, the project-signing scope in domain.ts, and the cache write in upgrade.ts now live in one local helper each; the other changes remove redundant work or reuse existing helpers.

  • planCertAuthority in ssh-config.ts collects kept lines in the same pass that builds the removed set instead of filtering twice.
  • canonicalTarget in agent.ts is now evaluated once instead of twice.
  • A doc comment in domain.ts was moved so it lands on the function it describes, and the inline --org suffix reuses the existing orgArgOf helper.
  • resolveDbUrl in postgres.ts now calls the module's resolvePostgres instead of repeating its two lines.
  • Typecheck passes and all 2110 tests pass, same as baseline; a pre-existing Windows path bug in resolveProjectName was noted but left for the owners.