Commit Graph
6 Commits
Author SHA1 Message Date
thePR0M3TH3ANandClaude Fable 5 0dfeca8a50 fix: a bare seedpass-js printed help and then reported a bogus error
exitOverride() makes commander throw for everything it would otherwise exit
on -- displaying help and its own usage errors included. The handler only
recognised two of its codes, so running `seedpass-js` with no arguments
printed the help and followed it with `error: (outputHelp)`, and unknown
commands had their message printed twice.

Any commander.* code is now commander's business: honour its exit code and
let it own the message. SeedPass's own errors still print as before.

Found by running the command.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-15 14:19:38 -04:00
thePR0M3TH3ANandClaude Fable 5 1864343084 cutover: close gates 5, 6 and 7
Gate 5 (feature parity) -- document import/export ported: `entry
import-document` reads a text file (label defaults to the file stem, type
from the extension) and `entry export-document` writes one back, reproducing
Python's filename sanitization, directory-vs-file destination handling and
overwrite refusal. That was the last concrete item; the three remaining
exclusions (PGP RSA, semantic, api) are now documented decisions rather than
open work, and none of them blocks cutover.

Gate 6 (packaging) -- js/packages/cli/build.mjs bundles the CLI into a
single self-contained ESM file with no runtime dependencies beyond Node 22,
writes a .sha256 beside it, and is wired up as the package `bin` and
`prepack` so npm install/pack produce a working command. --version now
reports a real version stamped at build time. CI builds the bundle and
smoke-tests it from a directory with no node_modules -- version,
capabilities, profile creation, entry creation, reveal -- then uploads it.
Verified locally that the bundle runs standalone outside the workspace.

Gate 7 (migration and rollback) -- docs/typescript_migration_guide.md: the
migration is a no-op (same profiles), so the guide covers what to back up,
how to rehearse against a copy with SEEDPASS_APP_DIR, the two behavioral
differences users will notice, the known exclusions, and seed-only recovery.
Rollback is proven rather than asserted: new cross-impl phase K drives a
profile through the TS CLI -- several entry kinds created, one edited, one
archived -- then checks Python reopens it, sees every change, derives the
same secrets, and can still write to it afterwards.

Also adds js/packages/cli/README.md documenting the reference-first output
model and the scoped-token workflow.

193 core + 49 CLI tests green; 36/36 cross-implementation checks green.
All eight cutover gates are now green.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-14 21:33:28 -04:00
thePR0M3TH3ANandClaude Fable 5 dcb8fc9219 fix: four real bugs found by end-to-end manual testing
Ran the full CLI surface against a freshly generated throwaway seed
(profile -> agent unlock -> all 8 entry kinds -> reveal/sinks -> tokens ->
audit -> backup -> relay sync -> seed-only recovery). Four defects that no
unit test had caught:

- clipboard sink hung the CLI forever. xclip/wl-copy fork a resident
  process to own the X/Wayland selection; it inherited our stdio, so any
  reader of the CLI's stdout blocked indefinitely, and waiting for process
  exit never returned. Now detached with ignored stdio, success declared
  once stdin is flushed.
- 'vault import' read the mnemonic straight from the env, so it failed
  whenever the vault was unlocked through the agent -- the normal path.
- 'vault import' never wrote anything; it only printed a summary. It now
  restores into the active vault, refuses to overwrite a non-empty vault
  without --yes, and keeps the old behavior behind --inspect.
- A corrupt/foreign vault file surfaced the raw codec error "invalid token
  encoding". It now names the actual likely causes.

Also documented the variadic-option limitation that a trailing flag is
lost (commander stops collecting at the next dash-prefixed token): a
quoted command spec now splits on whitespace, no shell involved.

Regression tests for all four. 151 core + 44 CLI tests green.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-14 15:56:34 -04:00
thePR0M3TH3ANandClaude Fable 5 4f2b8a79bf TS port slice 7: entry modify/archive/links + util generate-password
- core entryMod: modify_entry port with the per-kind allowed-field matrix,
  policy merging, blacklisted-field cleanup and timestamp touching;
  archive/restore; typed links (add/remove/get with Python's normalization,
  dedupe on target/relation/note, self-link and missing-target refusal).
- Parity fixture entry_mods.json: the real Python EntryManager applies a
  10-op modification sequence at a later pinned clock; TS replays the same
  ops from the creation state and matches byte-for-byte.
- CLI: entry modify/archive/unarchive/links/link-add/link-remove,
  entry totp-codes (explicit egress, honors --at and archived state),
  util generate-password (Python parity: index 0 + gen v1 defaults, full
  policy flags — v1/v2 outputs verified against password fixtures).
- capabilities: egress command list updated.
- 148 core parity tests (Node + jsdom) + 22 CLI tests green.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-14 13:14:25 -04:00
thePR0M3TH3ANandClaude Fable 5 e91d5d0be2 TS port slice 5: agent-blind provisioning, entry-secret parity, nostr app fix
- core entryOps: add* functions for all creatable kinds rebuild the Python
  EntryManager fixture index byte-for-byte under a pinned clock — field
  shapes, id allocation, independent TOTP derivation-index allocation, and
  Python's ISO timestamp format all verified.
- CLI 'entry add password/totp/key-value/document/seed/managed-account/
  nostr': provision-blind — returns the reference and metadata, never the
  secret the entry represents; tests assert the derived password / imported
  secret / child mnemonic appear nowhere in provisioning output.
- Parity bug found and fixed by the new entry_secrets fixtures: nostr ENTRY
  keys derive via the default BIP-85 app 39 path (EntryManager), not app
  1237 (sync client identity); the CLI had used 1237. Reveal values for
  password/TOTP/nostr/seed/managed-account now match Python retrieval.
- 129 core parity tests (Node + jsdom) + 16 CLI tests green.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-13 21:31:32 -04:00
thePR0M3TH3ANandClaude Fable 5 ab569fe900 TS port slice 4: portable backup, CI, and the agent-blind CLI MVP
- Portable backup (format_version 1): TS imports Python exports, re-exports
  byte-identically under pinned nonce/timestamp, verifies the canonical
  checksum, rejects tampering and unknown versions.
- .github/workflows/ts-parity.yml: typecheck + Node/jsdom parity suite on
  js/ changes, plus a fixture-drift job that regenerates fixtures from
  Python and fails if the committed ones don't match (manifest commit field
  excluded by construction).
- packages/cli — seedpass-js MVP implementing plan section 9.3:
  * reference-first output: entry list/get/search emit sp://entry/<id> refs
    and metadata; secret-bearing fields become has_* flags
  * 'entry reveal' is the only plaintext egress command
  * 'use --clipboard|--exec|--stdin-to' delivers secrets to sinks; --exec
    injects SEEDPASS_SECRET into the child env, never argv or stdout
  * vault export/import over portable backups; capabilities --format json
  * mnemonic comes from SEEDPASS_MNEMONIC env, never the command line
- CLI tests prove the blindness properties: derived password matches the v2
  fixture, TOTP at pinned time, secrets absent from all default output and
  from sink-delivery confirmations.
- 125 core parity tests (Node + jsdom) + 11 CLI tests green.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-13 10:40:56 -04:00