Benjamin Diedrichsen 7862fab809 [docs] keyman: rewrite the README, close the audit
Phase 9 of packages/keyman/docs/PLAN.md; closes AUDIT §5.2, §5.3, §5.4, §5.5,
and the §4 one-liners no phase had claimed (§4.1–§4.4, §3.7).

The README is the only document that ships (package.json files: dist,
README.md, LICENSE), and it described four of nine menu entries, invented key
rotation, told the user to run ssh-keygen by hand, asked them to write a
.gitignore keyman now writes, and mentioned none of the command line. It is
rewritten against the code: every operation, the rotate/retire sequence, the
id_ prefix and what happens to keys without it, installation with the scope
mapping (never a bare --registry, which would send 55 transitive dependencies
to a registry that has never heard of them), the configuration semantics
including which relative path resolves against what, and the Phase 5 migration
for a split vault.

The CLI section is helpText() verbatim, with tests/readme.test.ts asserting the
two are identical and that every menu label appears — so a flag or an operation
added later fails the gate instead of shipping undocumented. That is the part
that keeps this from drifting again.

Also: index.ts loses the bin's shebang (it is only ever imported), exports the
config types so a consumer can name what loadConfig returns, and re-exports the
update module wholesale rather than half of it by name — verified by importing
the built dist/index.js and reading its keys. The narrow surface is now a
comment stating the rule rather than an accident.

AUDIT.md marks all 30 findings closed except the second half of §1.8, keeping
each finding's text as the record with what closed it quoted underneath, the
way DOCS-AUDIT.md does. PLAN.md gains a status section naming the three
deviations. Root CLAUDE.md records the keyman architecture as it now is,
including the deliberate `resolution` divergence from nopy.

DOCS-AUDIT.md §2.10, §6.4 and the §7 keyman-config entry are amended in the
working tree but left unstaged, since that file carries unrelated WIP.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 17:57:00 +02:00
2026-07-29 13:21:04 +02:00
2026-07-27 13:09:00 +02:00
2026-07-29 13:21:04 +02:00
2026-07-29 13:21:04 +02:00
2026-07-29 13:21:04 +02:00
2026-07-29 13:07:34 +02:00
2026-07-29 13:21:04 +02:00
2026-07-27 17:07:18 +02:00
2026-07-29 13:21:04 +02:00
2026-07-29 13:21:04 +02:00
2026-07-29 13:21:04 +02:00

ansiblings

Infrastructure tooling monorepo: two published CLIs plus the pyinfra "cubes" they deploy.

Path Package Binary What it is
packages/nopy @bitsquare/nopy nopy interactive pyinfra script management and execution
packages/keyman @bitsquare/keyman keyman SSH key management with age encryption
cubes/ the deployment units nopy runs
npm install -g @bitsquare/nopy @bitsquare/keyman

See each package's README for usage, and README.PUBLISH.md for how they get published.

Development

Requires Node ≥ 22 (the repo pins 24 in .nvmrc) and pnpm — the version is pinned by packageManager, so corepack enable is enough.

pnpm install
Command Does
pnpm run build compiles both packages with tsc
pnpm run typecheck tsc --build --noEmit across the workspace
pnpm run lint Biome check
pnpm run lint:fix Biome check with fixes applied
pnpm test vitest, both packages
pnpm run test:coverage vitest with the coverage gate
pnpm run coverage:summary renders the last coverage run as a Markdown table

typescript is on the 7.x native compiler, so tsc is the fast one — there is no separate tsgo binary to keep in sync. Each package also has a dev-run script (pnpm --filter @bitsquare/nopy run nopy) that executes the TypeScript sources directly through tsx.

Git hooks

Installed by simple-git-hooks on pnpm install, configured in the root package.json:

  • pre-commit — Biome check with fixes, on staged files only, re-staging what it fixed. Fast; blocks only on problems it cannot fix itself.
  • pre-pushlint:citypechecktest:coverage. This is the same gate CI runs, so a push that survives it will not surprise you on the runner.

Set SKIP_SIMPLE_GIT_HOOKS=1 to bypass either one; re-install them after changing the config with pnpm exec simple-git-hooks.

Coverage

Both packages hold a hard 85 % branch floor, enforced by coverage.thresholds in their vitest.config.ts rather than by a CI-only flag — pnpm run test:coverage fails the same way locally, in the pre-push hook, and on the runner. Barrel files and CLI argv wiring are excluded; everything with behaviour in it is not.

S
Description
No description provided
Readme MIT 1.3 MiB
Languages
TypeScript 87.7%
JavaScript 8.1%
Python 3.9%
Dockerfile 0.2%
Shell 0.1%