This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
npm install # install dependencies (nsec-tree, @forgesworn/shamir-words, @scure/bip39)
npm test # run all tests (92 tests across 5 files)
node --test test/cli.test.js # run a single test file
node ./bin/nsec-tree.js --help # run the CLIDependencies are real npm packages. The sibling-directory fallback in src/deps.js is for local multi-repo development only — npm install is the standard path.
Node >= 22 required. ESM-only ("type": "module").
This is the application layer for the nsec-tree identity hierarchy. It owns CLI grammar, I/O, profiles, and formatting — not cryptography.
Key files:
bin/nsec-tree.js— entrypoint, delegates torunCli()src/cli.js— command dispatch and logic. Each command group (root,derive,export,prove,verify,shamir,profile,inspect,explain) has its ownhandle*function. Custom arg parser (not a framework) —BOOLEAN_OPTIONSandVALUE_OPTIONSsets define the grammar.src/format.js— ANSI colour, box-drawing, tree rendering, label-value formatting. ExportscreateFormatter({ colour })factory. Decoupled fromprocess.stdout— receives acolourboolean from cli.js based on TTY detection andNO_COLORenv var. Fixed 60-char content width.src/explain.js— five mini-tutorials (model, proofs, recovery, paths, offline). Each topic receives a formatter and returns rich text.src/deps.js— runtime dependency loading. Direct npm imports with sibling-directory fallback for local dev.src/profile-store.js— profile CRUD, stored as JSON in~/.nsec-tree/profiles/
Dependency boundary: all crypto operations go through libraries loaded by deps.js:
nsec-tree— root creation, derivation, proofs, verification@forgesworn/shamir-words— Shamir split/recover@scure/bip39— mnemonic generation/validation
Test files:
test/helpers.js— sharedMemoryIoclass andTEST_MNEMONICtest/cli.test.js— command behaviour happy paths + contextual next-steps (28 tests)test/errors.test.js— error paths and validation (21 tests)test/profile.test.js— profile lifecycle integration (5 tests)test/format.test.js— format module unit tests, CLI formatting integration,--no-hints, env var, npx detection (25 tests)test/explain.test.js— explain topic tests (12 tests)
Testing pattern: tests construct a MemoryIo instance and pass it to runCli(argv, io, options). MemoryIo accepts isStdoutTty to control colour output. Set io.commandPrefix to test npx detection. options.profileBaseDir redirects profile storage to a temp directory. No mocking of libraries.
- British English in user-facing text
- Two root types:
mnemonic-backed(recoverable, supports Shamir) andnsec-backed(tree-capable, no phrase recovery) — always preserve this distinction - Every command supports
--json(stable, machine-readable) and human-readable text by default --quietemits bare values with no formatting--no-hintssuppresses "Try next" suggestions;NSEC_TREE_NO_HINTS=1does the same permanently- Human-mode output follows a HATEOAS pattern — every command shows contextual "Try next" suggestions guiding the user to the logical next step. When
--no-hintsor the env var is set,fmt.nextStepsis replaced with a no-op returningnull, whichfmt.section()filters out. - npx detection:
io.commandPrefixdefaults tonsec-treebut showsnpx nsec-treewhen the CLI detects it was invoked via npx (checks for_npxinprocess.argv[1]). All hint commands use this prefix. - Human-mode output uses
fmt.warning()for sensitive content (mnemonics, nsecs, shares) - Secret files written with mode
0o600, directories with0o700 - Path segments validated by
PATH_SEGMENT_RE: lowercase, shell-friendly, max 32 chars, optional@indexsuffix - Colour respects TTY detection and
NO_COLORenv var
GitHub Actions (.github/workflows/ci.yml) runs npm ci then npm test. No external repo dependencies.