@ai-dossier/cli 0.9.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -311,6 +311,254 @@ ai-dossier skill-export my-skill --version 2.0.0 --changelog "Add range support"
311
311
 
312
312
  ---
313
313
 
314
+ ## Runstate — workflow milestones
315
+
316
+ Issue-workflow dossiers (`imboard-ai/git/full-cycle-issue` and friends) record their
317
+ progress by appending a `<!-- runstate:v1 -->` comment to the GitHub issue after every
318
+ phase. That trail is the only run state that survives a session: it is what lets a later
319
+ run resume mid-workflow instead of starting over.
320
+
321
+ Until now the milestone was a markdown heredoc that each agent reproduced by hand, and
322
+ agents silently got it wrong — skipping milestones entirely, or pasting `$(date …)` into
323
+ the comment verbatim. `ai-dossier runstate` makes it a command: the timestamp is filled
324
+ in for you, and phase/status/required keys are validated *before* anything is posted.
325
+
326
+ ```bash
327
+ # Mint the run id once, at the gate phase
328
+ ai-dossier runstate mint --issue 440 # -> r-440-ab56
329
+
330
+ # Post a milestone at the end of each phase
331
+ ai-dossier runstate post --issue 440 \
332
+ --phase setup --status done --run r-440-ab56 \
333
+ --kv branch=feature/440-runstate \
334
+ --kv worktree=/repo/worktrees/feature-440-runstate \
335
+ --kv pool_claimed=false \
336
+ --kv base_branch=main
337
+
338
+ # Read the last milestone back
339
+ ai-dossier runstate last --issue 440 --json
340
+
341
+ # Ask where a run should resume from
342
+ ai-dossier runstate verify --issue 440
343
+ ```
344
+
345
+ ### Subcommands
346
+
347
+ | Command | What it does | Writes? |
348
+ |---|---|---|
349
+ | `post` | Validates and posts one milestone comment via `gh issue comment` | yes |
350
+ | `last` | Prints the most recent milestone on the issue, parsed | no |
351
+ | `verify` | Runs the gate's resume verification and prints `resume_from` + `resume_context` | no |
352
+ | `mint` | Prints a fresh run id (`r-<issue>-<hex>`) | no |
353
+
354
+ `last` and `verify` are strictly read-only — they only run `gh issue view`, `gh pr view`,
355
+ `git ls-remote`/`rev-parse`, and `stat`, so they work fine without push access to the
356
+ repository.
357
+
358
+ Every subcommand takes `--issue <n>` (a positive integer — the number only, not a URL or
359
+ a `#`-prefixed string). `post`, `last`, and `verify` additionally take `--repo
360
+ <owner/name>` (a bare slug, not a URL; defaults to the repository `gh` resolves for the
361
+ current directory) and `--json`. `mint` takes `--issue` and nothing else.
362
+
363
+ `last` prints the milestone's own `key=value` lines, so the output is already in the
364
+ shape a shell or a dossier reads:
365
+
366
+ ```
367
+ $ ai-dossier runstate last --issue 440
368
+ phase=setup
369
+ status=done
370
+ run=r-440-ab56
371
+ at=2026-08-24T07:59:32Z
372
+ branch=feature/440-runstate
373
+ worktree=/repo/worktrees/feature-440-runstate
374
+ pool_claimed=false
375
+ base_branch=main
376
+ next=plan
377
+ ```
378
+
379
+ With `--json` the same keys come back as one flat object; an issue with no milestones
380
+ prints `No runstate milestones on issue #440.` (or `null` under `--json`) and exits 0.
381
+
382
+ ### `post`
383
+
384
+ | Flag | Meaning |
385
+ |---|---|
386
+ | `--issue <n>` | Issue to comment on (required) |
387
+ | `--phase <p>` | `gate`, `setup`, `plan`, `implement`, `review`, `ship`, `report` (required) |
388
+ | `--status <s>` | `done`, `partial`, `blocked`, `awaiting-merge` (required) |
389
+ | `--run <id>` | Run id minted at the gate phase (required) |
390
+ | `--kv <key=value...>` | Phase-specific key, repeatable (and variadic: `--kv a=1 b=2` works too) |
391
+ | `--next <phase>` | Override the computed `next=` line — a phase name or `done` |
392
+ | `--repo <owner/name>` | Target repository (defaults to the current one) |
393
+ | `--dry-run` | Print the comment body instead of posting it |
394
+ | `--json` | Machine-readable output |
395
+
396
+ Validation failures print one actionable message per problem on stderr and exit 1
397
+ **without posting**:
398
+
399
+ ```
400
+ $ ai-dossier runstate post --issue 440 --phase setup --status done --run r-440-ab56 --kv branch=x
401
+ ❌ Phase 'setup' with status 'done' requires worktree= pool_claimed= base_branch= — add with --kv worktree=<value> --kv pool_claimed=<value> --kv base_branch=<value>
402
+ ```
403
+
404
+ A valid `--dry-run` prints the exact body that would be posted:
405
+
406
+ ```
407
+ $ ai-dossier runstate post --issue 440 --phase setup --status done --run r-440-ab56 \
408
+ --kv branch=feature/440-runstate --kv worktree=/repo/worktrees/feature-440-runstate \
409
+ --kv pool_claimed=false --kv base_branch=main --dry-run
410
+ <!-- runstate:v1 -->
411
+ phase=setup status=done run=r-440-ab56 at=2026-08-24T07:59:32Z
412
+ branch=feature/440-runstate
413
+ worktree=/repo/worktrees/feature-440-runstate
414
+ pool_claimed=false
415
+ base_branch=main
416
+ next=plan
417
+ ```
418
+
419
+ Without `--dry-run` a successful post prints `✅ setup done → <comment url>`; `--json`
420
+ returns `{ "posted": true, "url": …, "body": … }` (and `{ "posted": false, "dryRun":
421
+ true, "body": … }` under `--dry-run`). See [When `gh` or `git`
422
+ fails](#when-gh-or-git-fails) for what a failed post prints.
423
+
424
+ ### Phases, statuses, and required keys
425
+
426
+ This table is the executable copy of the "Runstate Milestones" table in
427
+ `imboard-ai/git/full-cycle-issue@3.8.0`:
428
+
429
+ | Phase | Statuses | Required keys |
430
+ |---|---|---|
431
+ | `gate` | `done`, `blocked` | `base_branch` `warnings` |
432
+ | `setup` | `done`, `blocked` | `branch` `worktree` `pool_claimed` `base_branch` |
433
+ | `plan` | `done`, `blocked` | `planning` `head` `open_questions` `visual_review` |
434
+ | `implement` | `done`, `blocked` | `head` `files` `tests_added` `tests_run` `ci_parity` |
435
+ | `review` | `done`, `partial`, `blocked` | `head` `fixed` `escalated` `agents_done` `agents_pending` |
436
+ | `ship` (1st, before the CI wait) | `awaiting-merge` | `pr` `head` `ci_fix_attempts` |
437
+ | `ship` (2nd, after merge + teardown) | `done`, `blocked` | `pr` `merge_commit` `ci_fix_attempts` `cleanup` |
438
+ | `report` | `done` | `pr` `traps_added` |
439
+
440
+ The `Statuses` column is a closed set: a status not listed for a phase is rejected, so
441
+ `report` cannot be `blocked` and only `ship` may be `awaiting-merge`. Any phase that
442
+ *can* report `status=blocked` must also carry `reason=<short-slug>` when it does.
443
+
444
+ `next=` is computed for you: the linear order `gate → setup → plan → implement → review →
445
+ ship → report → done`, except that `blocked` ends the run (`next=done`) and the two
446
+ non-terminal statuses stay in their own phase — `ship`/`awaiting-merge` is followed by a
447
+ second `ship` milestone, and a `partial` review still has agents to run. Use `--next` to
448
+ override.
449
+
450
+ ### Key and value rules
451
+
452
+ Every `--kv` pair is checked before anything is posted:
453
+
454
+ - Keys are `lower_snake_case` (`^[a-z][a-z0-9_]*$`) and may appear at most once.
455
+ - No empty values — omit the key instead.
456
+ - No `$` in values. This is the check that catches an unexpanded `$(date …)` before it
457
+ reaches the issue.
458
+ - One line per value. A newline would split into extra `key=` lines that readers parse as
459
+ real state, so it is rejected for **every** key, including `ac*` ones — collapse it
460
+ (`,` or ` / `) instead.
461
+ - No spaces in values (use `-` or `,`). Only `ac*` keys — `ac`, `ac1`, `ac_results` — are
462
+ exempt, because acceptance-criterion lines are prose. (The newline rule above still
463
+ applies to them.)
464
+ - A value is at most 4000 characters and the whole comment at most 60000 (GitHub rejects
465
+ a longer issue comment with an opaque 422). A milestone is an index, not a report:
466
+ replace a long value with a count or a path to the full text.
467
+ - `worktree=` and `planning=` must be absolute paths, so a resume from a different
468
+ working directory can still find them.
469
+ - `--next` must be a phase name or `done`. It is written to the comment verbatim, so an
470
+ unchecked typo would point the next resume at a phase that does not exist.
471
+ - Comments are append-only: never edit or delete a prior milestone.
472
+
473
+ ### When `gh` or `git` fails
474
+
475
+ Every subcommand exits **1** on failure with the cause *and its fix* on stderr, so a
476
+ calling dossier can branch on the exit code and an agent knows what to do next. The three
477
+ causes that look identical from the outside are reported as three different things:
478
+
479
+ ```
480
+ $ ai-dossier runstate last --issue 440
481
+ ❌ Could not read issue #440: gh is not authenticated.
482
+ Fix: run 'gh auth login', confirm with 'gh auth status', then re-run.
483
+ gh said: To get started with GitHub CLI, please run: gh auth login
484
+ ```
485
+
486
+ | Cause | What you get |
487
+ |---|---|
488
+ | `gh` not on PATH | "'gh' is not installed, or is not on PATH" + the install link |
489
+ | Not logged in | "gh is not authenticated" + `gh auth login` |
490
+ | Issue/PR does not exist | "GitHub could not find it in …" + a nudge to check `--repo` |
491
+ | No permission (403) | "the authenticated account lacks access to …" + `gh auth status` |
492
+ | github.com unreachable | "gh could not reach GitHub" + retry guidance |
493
+ | Anything else | the exit status, and "run the same gh command by hand" |
494
+
495
+ `gh`'s own stderr is **always** echoed on a `gh said:` line, including for causes the CLI
496
+ cannot classify — nothing is swallowed. `gh` exiting 0 with output that is not JSON, or
497
+ with JSON that has no `comments` array, is also a hard failure rather than a silent "no
498
+ milestones": the two must never look alike, because reading a fresh run out of a broken
499
+ response makes a resume start over and throw away finished work.
500
+
501
+ When `post` cannot reach GitHub, it prints the exact `gh issue comment …` command to run
502
+ by hand. The milestone is the only durable record of the phase, so re-running the phase
503
+ costs far more than retrying the comment.
504
+
505
+ ### `verify`
506
+
507
+ `verify` implements `imboard-ai/git/gate-issue`'s resume table. It never trusts the
508
+ comment alone — each claim is checked against reality (is the branch still on the remote,
509
+ does the worktree still exist, does the planning file exist, has HEAD moved, what is the
510
+ PR's state) before it reports where to resume:
511
+
512
+ ```
513
+ $ ai-dossier runstate verify --issue 440
514
+ resume_from=implement
515
+ run_id=r-440-ab56
516
+ verified=branch,worktree,planning
517
+ resume_context={"branch":"feature/440-runstate","worktree":"/repo/worktrees/feature-440-runstate",...}
518
+ ```
519
+
520
+ `resume_from` is a phase name, or one of:
521
+
522
+ | Value | Meaning |
523
+ |---|---|
524
+ | `none` | No milestones on the issue — a fresh run |
525
+ | `ship-wait` | The PR is open and mergeable; re-enter `ship` at the CI wait |
526
+ | `ship-teardown` | The PR is already merged; re-enter `ship` at post-merge cleanup |
527
+ | `done` | The `report` milestone is posted and the issue is closed (`note=already complete`) |
528
+
529
+ A failed check sends the resume *backwards*, never forwards: if the branch is gone from
530
+ the remote or the worktree no longer exists, a `plan`/`implement`/`review` milestone
531
+ still yields `resume_from=setup`. A milestone with `status=blocked` resumes at its own
532
+ phase.
533
+
534
+ `resume_context` is merged across the run's milestones (later ones winning), so a resume
535
+ at `plan` still sees `branch`/`worktree` from the `setup` milestone. (The dossier's own
536
+ table carries only the last milestone's keys; merging is what makes a mid-run resume
537
+ self-sufficient.) If the last three milestones are all `blocked` on the same phase,
538
+ `verify` adds `hard_block=resume-loop` — the run is looping and needs a human.
539
+
540
+ When a check cannot run at all — `git`/`gh` is missing or the remote is unreachable, or
541
+ the milestone's `branch=`/`worktree=`/`pr=` value is not one `verify` will hand to a
542
+ subprocess — that check degrades to "not verified" and `verify` warns instead of failing.
543
+ It still exits 0, because a conservative `resume_from` is the safe direction (redo a phase
544
+ rather than skip one), but the reader needs to know the answer is conservative *because a
545
+ check could not run*. Warnings go to stderr so stdout stays parseable:
546
+
547
+ ```
548
+ ⚠️ verify could not check everything: could not reach 'origin' to confirm branch 'feature/440-runstate' (git exited 128: fatal: 'origin' does not appear to be a git repository) — treating it as missing
549
+ ```
550
+
551
+ Anyone who can comment on the issue can post a `<!-- runstate:v1 -->` body, so the values
552
+ `verify` reads back are untrusted input. Nothing is run through a shell, and a value that
553
+ would be read as a flag (leading `-`) or that is not the absolute path the protocol
554
+ requires is refused rather than passed to `git`/`gh` — it becomes one of the warnings
555
+ above.
556
+
557
+ `--json` returns the same fields as an object (`resume_from`, `run_id`, `verified`,
558
+ `resume_context`, plus `hard_block`, `note`, and `warnings` when they apply).
559
+
560
+ ---
561
+
314
562
  ## Cache and Version Resolution
315
563
 
316
564
  The CLI maintains a local cache at `~/.dossier/cache/`:
@@ -523,6 +771,35 @@ Project registries are merged with user registries. User-configured registries t
523
771
  - ❌ Invalid → Signature failed → **BLOCK**
524
772
  - ⚠️ No signature → Unsigned (warn for high-risk)
525
773
 
774
+ #### Managing trusted keys
775
+
776
+ Trust is a local decision: a valid signature from a key you have not added is
777
+ reported as untrusted, never auto-trusted. Keys live in `~/.dossier/trusted-keys.txt`,
778
+ one `<public-key> <identifier>` per line.
779
+
780
+ ```bash
781
+ ai-dossier keys generate --name my-key # new Ed25519 pair in ~/.dossier/
782
+ ai-dossier keys list # what is trusted right now
783
+ ai-dossier keys add <public-key> <identifier>
784
+ ```
785
+
786
+ `keys add` accepts a raw 44-char base64 key, an SPKI PEM block, or a legacy
787
+ minisign `RWT...` key, and stores the **canonical raw base64** form regardless —
788
+ so a key added in one encoding still matches a signature carrying another.
789
+ Anything it cannot interpret (a typo, a truncated key, a path to a `.pub` file)
790
+ is rejected outright rather than written and silently never matching.
791
+
792
+ > **Passing a PEM needs `--`.** A PEM begins with `-`, which the option parser
793
+ > reads as a flag:
794
+ > ```bash
795
+ > ai-dossier keys add -- "$(cat ~/.dossier/my-key.pub)" "my-key"
796
+ > ```
797
+ > `ai-dossier verify <dossier>` sidesteps this entirely — it prints a
798
+ > ready-to-run `keys add` command with the key already in base64 form.
799
+
800
+ If `keys list` warns about unusable entries, those keys are **not** trusted; the
801
+ warning names the line to fix.
802
+
526
803
  ### 3. Risk Assessment
527
804
 
528
805
  **Analyzes**:
package/dist/cli.js CHANGED
@@ -32,6 +32,7 @@ const pull_1 = require("./commands/pull");
32
32
  const remove_1 = require("./commands/remove");
33
33
  const reset_hooks_1 = require("./commands/reset-hooks");
34
34
  const run_1 = require("./commands/run");
35
+ const runstate_1 = require("./commands/runstate");
35
36
  const search_1 = require("./commands/search");
36
37
  const sign_1 = require("./commands/sign");
37
38
  const skill_export_1 = require("./commands/skill-export");
@@ -95,6 +96,7 @@ Agent-friendly: Run \`ai-dossier --agent\` for machine-readable capabilities.`);
95
96
  (0, history_1.registerHistoryCommand)(commander_1.program);
96
97
  (0, doctor_1.registerDoctorCommand)(commander_1.program);
97
98
  (0, traces_1.registerTracesCommand)(commander_1.program);
99
+ (0, runstate_1.registerRunstateCommand)(commander_1.program);
98
100
  // Hidden
99
101
  (0, prompt_hook_1.registerPromptHookCommand)(commander_1.program);
100
102
  (0, reset_hooks_1.registerResetHooksCommand)(commander_1.program);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6L1D"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2Q1D"}
@@ -8,6 +8,24 @@ const node_crypto_1 = __importDefault(require("node:crypto"));
8
8
  const node_fs_1 = __importDefault(require("node:fs"));
9
9
  const node_os_1 = __importDefault(require("node:os"));
10
10
  const node_path_1 = __importDefault(require("node:path"));
11
+ const core_1 = require("@ai-dossier/core");
12
+ /**
13
+ * A one-line rendering of a rejected key argument, for the error message.
14
+ *
15
+ * Multi-line and overlong values are collapsed so the error stays readable, but
16
+ * the head of the value is kept — that is what lets someone see they pasted a
17
+ * path, a private key, or a truncated string.
18
+ */
19
+ function summarizeKeyArgument(value) {
20
+ const flat = value.trim().replace(/\s+/g, ' ');
21
+ const shown = flat.length > 70 ? `${flat.slice(0, 70)}...` : flat;
22
+ return `"${shown}" (${value.trim().length} chars)`;
23
+ }
24
+ /** Whether an argument looks like someone passed a file path instead of a key. */
25
+ function looksLikeFilePath(value) {
26
+ const trimmed = value.trim();
27
+ return (/^[~.]?\//.test(trimmed) || /\.(pub|pem|key|txt)$/i.test(trimmed) || node_fs_1.default.existsSync(trimmed));
28
+ }
11
29
  function registerKeysCommand(program) {
12
30
  const keysCmd = program.command('keys').description('Manage trusted signing keys');
13
31
  keysCmd
@@ -34,20 +52,18 @@ function registerKeysCommand(program) {
34
52
  const publicPem = publicKey.export({ type: 'spki', format: 'pem' });
35
53
  node_fs_1.default.writeFileSync(privatePath, privatePem, { mode: 0o600 });
36
54
  node_fs_1.default.writeFileSync(publicPath, publicPem, { mode: 0o644 });
37
- // Extract raw public key bytes for base64 sharing
38
- const publicDer = publicKey.export({ type: 'spki', format: 'der' });
39
- // Ed25519 SPKI DER has 12-byte header, raw key is last 32 bytes
40
- const rawPublicKey = publicDer.subarray(publicDer.length - 32);
41
- const publicKeyBase64 = rawPublicKey.toString('base64');
55
+ // The canonical shareable form is the raw 32-byte key in base64 — the same
56
+ // form the signer emits and the trust list stores.
57
+ const publicKeyBase64 = (0, core_1.normalizePublicKey)(publicPem);
42
58
  console.log(`✅ Key pair generated successfully`);
43
59
  console.log(` Name: ${options.name}`);
44
60
  console.log(` Private key: ${privatePath}`);
45
61
  console.log(` Public key: ${publicPath}`);
46
62
  console.log(` Public key (base64): ${publicKeyBase64}`);
47
63
  console.log('\nTo sign a dossier:');
48
- console.log(` dossier sign <file> --method ed25519 --key ${privatePath}`);
64
+ console.log(` ai-dossier sign <file> --method ed25519 --key ${privatePath}`);
49
65
  console.log('\nTo add this public key as trusted:');
50
- console.log(` dossier keys add ${publicKeyBase64} "${options.name}"\n`);
66
+ console.log(` ai-dossier keys add ${publicKeyBase64} "${options.name}"\n`);
51
67
  process.exit(0);
52
68
  });
53
69
  keysCmd
@@ -72,24 +88,34 @@ function registerKeysCommand(program) {
72
88
  });
73
89
  }
74
90
  }
75
- // Load trusted keys
76
- let trustedLines = [];
91
+ // Parse through core so this listing reflects exactly what verification
92
+ // trusts — including legacy multi-line PEM entries, which a line-oriented
93
+ // read here would report as several bogus keys.
94
+ let trustedEntries = [];
95
+ // Lines the parser had to skip. `keys list` is where someone lands when a
96
+ // key "isn't trusted", so this is the one place that must show them.
97
+ let trustedProblems = [];
77
98
  if (node_fs_1.default.existsSync(trustedKeysPath)) {
78
- const content = node_fs_1.default.readFileSync(trustedKeysPath, 'utf8');
79
- trustedLines = content.split('\n').filter((line) => line.trim() && !line.startsWith('#'));
99
+ const parsed = (0, core_1.parseTrustedKeys)(node_fs_1.default.readFileSync(trustedKeysPath, 'utf8'));
100
+ trustedEntries = parsed.entries;
101
+ trustedProblems = parsed.problems;
80
102
  }
81
103
  if (options.json) {
82
- const trusted = trustedLines.map((line) => {
83
- const [key, ...idParts] = line.trim().split(/\s+/);
84
- return { type: 'trusted', public_key: key, identifier: idParts.join(' ') };
85
- });
104
+ const trusted = trustedEntries.map((entry) => ({
105
+ type: 'trusted',
106
+ // As written in the file, plus the canonical form actually compared
107
+ // against a signature — a legacy entry differs between the two.
108
+ public_key: entry.publicKey,
109
+ normalized_public_key: (0, core_1.normalizePublicKey)(entry.publicKey),
110
+ identifier: entry.keyId,
111
+ }));
86
112
  const generated = generatedKeys.map((k) => ({
87
113
  type: 'generated',
88
114
  name: k.name,
89
115
  private_key: k.privatePath,
90
116
  public_key: k.publicPath,
91
117
  }));
92
- console.log(JSON.stringify({ trusted, generated }, null, 2));
118
+ console.log(JSON.stringify({ trusted, generated, problems: trustedProblems }, null, 2));
93
119
  process.exit(0);
94
120
  }
95
121
  // Display generated keys
@@ -107,7 +133,10 @@ function registerKeysCommand(program) {
107
133
  }
108
134
  // Display trusted keys
109
135
  console.log('🔑 Trusted Signing Keys\n');
110
- if (trustedLines.length === 0) {
136
+ // Before the listing: an unterminated PEM block can swallow the rest of the
137
+ // file, so "no trusted keys" may itself be the symptom being explained.
138
+ (0, core_1.reportTrustedKeyProblems)(trustedProblems, trustedKeysPath);
139
+ if (trustedEntries.length === 0) {
111
140
  if (!node_fs_1.default.existsSync(trustedKeysPath)) {
112
141
  console.log('⚠️ No trusted keys file found');
113
142
  console.log(` Location: ${trustedKeysPath}`);
@@ -117,19 +146,20 @@ function registerKeysCommand(program) {
117
146
  console.log(` File exists at: ${trustedKeysPath}`);
118
147
  }
119
148
  console.log('\nTo add a trusted key:');
120
- console.log(' dossier keys add <public-key> <identifier>\n');
149
+ console.log(' ai-dossier keys add <public-key> <identifier>\n');
121
150
  if (generatedKeys.length === 0) {
122
151
  console.log('To generate a new key pair:');
123
- console.log(' dossier keys generate\n');
152
+ console.log(' ai-dossier keys generate\n');
124
153
  }
125
154
  process.exit(0);
126
155
  }
127
- console.log(`Total: ${trustedLines.length} trusted key(s)\n`);
128
- trustedLines.forEach((line, index) => {
129
- const [key, ...idParts] = line.trim().split(/\s+/);
130
- const identifier = idParts.join(' ');
156
+ console.log(`Total: ${trustedEntries.length} trusted key(s)\n`);
157
+ trustedEntries.forEach((entry, index) => {
158
+ // Show the canonical form: a legacy PEM entry is multi-line and would
159
+ // otherwise wreck the listing.
160
+ const key = (0, core_1.normalizePublicKey)(entry.publicKey);
131
161
  const shortKey = key.length > 60 ? `${key.substring(0, 60)}...` : key;
132
- console.log(`${index + 1}. ${identifier}`);
162
+ console.log(`${index + 1}. ${entry.keyId}`);
133
163
  console.log(` ${shortKey}`);
134
164
  console.log();
135
165
  });
@@ -139,29 +169,84 @@ function registerKeysCommand(program) {
139
169
  keysCmd
140
170
  .command('add')
141
171
  .description('Add a trusted signing key')
142
- .argument('<public-key>', 'Public key (base64 or minisign format)')
172
+ .argument('<public-key>', 'Public key: raw base64, SPKI PEM (see below), or minisign')
143
173
  .argument('<identifier>', 'Human-readable identifier (e.g., "dossier-team-2025")')
174
+ // A PEM begins with "-", so commander reads it as an unknown option and the
175
+ // action never runs. The remediation `ai-dossier verify` prints uses raw base64
176
+ // and avoids this, but anyone pasting a PEM or a .pub file hits it — so the
177
+ // escape hatch has to be visible from `--help` and from any parse error.
178
+ .addHelpText('after', '\nAccepted key formats:\n' +
179
+ ' raw Ed25519 public key 44-char base64, e.g. "5kr+/8mNiy...o1M=" (canonical)\n' +
180
+ ' SPKI PEM block "-----BEGIN PUBLIC KEY-----..."\n' +
181
+ ' minisign public key "RWT..." (legacy)\n' +
182
+ '\nWhatever you pass is normalized to the raw base64 form before it is stored,\n' +
183
+ 'so all three end up as the same entry in ~/.dossier/trusted-keys.txt.\n' +
184
+ '\nExamples:\n' +
185
+ ' ai-dossier keys add 5kr+/8mNiy...o1M= "dossier-team-2025"\n' +
186
+ ' ai-dossier keys add -- "$(cat ~/.dossier/default.pub)" "my-key"\n' +
187
+ '\nA PEM starts with "-", which is read as an option — put "--" before it,\n' +
188
+ 'as in the second example. `ai-dossier verify <dossier>` prints a ready-to-run\n' +
189
+ 'command with the key already in base64 form.\n')
190
+ .showHelpAfterError('Note: a PEM starts with "-" and is read as an option — use: ai-dossier keys add -- "<pem>" "<id>"')
144
191
  .action((publicKey, identifier) => {
145
192
  const dossierDir = node_path_1.default.join(node_os_1.default.homedir(), '.dossier');
146
193
  const trustedKeysPath = node_path_1.default.join(dossierDir, 'trusted-keys.txt');
147
194
  console.log('\n🔑 Adding Trusted Key\n');
195
+ // Store the canonical raw-key base64. A PEM argument — what `verify` used to
196
+ // suggest, and what a `.pub` file contains — would otherwise be appended
197
+ // verbatim and shredded by the line-oriented trusted-keys parser.
198
+ const canonicalKey = (0, core_1.normalizePublicKey)(publicKey);
199
+ // Validate positively rather than just rejecting whitespace. normalizePublicKey
200
+ // hands back anything it cannot interpret, so a typo, a truncated key, or a
201
+ // path to a .pub file would otherwise be written as a "trusted key" under a
202
+ // ✅ and only surface much later as `ai-dossier verify` saying "not trusted".
203
+ // KMS-signed dossiers are verified against the key ARN, not the public key,
204
+ // so the ARN is the only thing that can make one trusted.
205
+ if (!(0, core_1.isSupportedPublicKey)(canonicalKey) && !(0, core_1.isKmsKeyIdentifier)(canonicalKey)) {
206
+ console.error('❌ Unrecognized public key format — nothing was added');
207
+ console.error(` Got: ${summarizeKeyArgument(publicKey)}`);
208
+ console.error('\n Expected one of:');
209
+ console.error(' • raw Ed25519 public key — 44-char base64, e.g. "5kr+/8mNiy...o1M="');
210
+ console.error(' • SPKI PEM block — "-----BEGIN PUBLIC KEY-----..."');
211
+ console.error(' • minisign public key — "RWT..."');
212
+ console.error(' • AWS KMS key ARN — "arn:aws:kms:<region>:<account>:key/..."');
213
+ if (looksLikeFilePath(publicKey)) {
214
+ console.error('\n That looks like a file path. Pass the key itself, not its path:');
215
+ console.error(` ai-dossier keys add -- "$(cat ${publicKey})" "${identifier}"`);
216
+ console.error(' (the leading "--" is required: a PEM starts with "-", which the');
217
+ console.error(' option parser would otherwise read as a flag)');
218
+ }
219
+ console.error('\n To print a key you can paste: ai-dossier keys generate');
220
+ console.error(" To get a signer's key: ai-dossier verify <dossier>");
221
+ console.error(' (verify prints a ready-to-run `ai-dossier keys add` command)\n');
222
+ process.exit(1);
223
+ }
224
+ // The identifier is written verbatim into a line-oriented trust file, so a
225
+ // newline in it appends a whole extra entry — a second, unrelated key the
226
+ // user never approved, trusted from then on. Reject rather than escape:
227
+ // there is no legitimate multi-line identifier.
228
+ if (/[\n\r]/.test(identifier)) {
229
+ console.error('❌ Identifier cannot span multiple lines — nothing was added');
230
+ console.error(' One trusted key per line, as "<public-key> <identifier>".\n');
231
+ process.exit(1);
232
+ }
148
233
  if (!node_fs_1.default.existsSync(dossierDir)) {
149
234
  node_fs_1.default.mkdirSync(dossierDir, { recursive: true });
150
235
  console.log(`✅ Created directory: ${dossierDir}`);
151
236
  }
152
237
  if (node_fs_1.default.existsSync(trustedKeysPath)) {
153
238
  const content = node_fs_1.default.readFileSync(trustedKeysPath, 'utf8');
154
- if (content.includes(publicKey)) {
239
+ if ((0, core_1.trustedKeysFromContent)(content).has(canonicalKey)) {
155
240
  console.log('⚠️ This key already exists in trusted keys');
156
241
  console.log(` Location: ${trustedKeysPath}\n`);
157
242
  process.exit(0);
158
243
  }
159
244
  }
160
- const entry = `${publicKey} ${identifier}\n`;
245
+ const entry = `${canonicalKey} ${identifier}\n`;
161
246
  node_fs_1.default.appendFileSync(trustedKeysPath, entry, 'utf8');
162
247
  console.log('✅ Key added successfully');
163
248
  console.log(` Identifier: ${identifier}`);
164
- console.log(` Public Key: ${publicKey.substring(0, 60)}${publicKey.length > 60 ? '...' : ''}`);
249
+ console.log(` Public Key: ${canonicalKey.substring(0, 60)}${canonicalKey.length > 60 ? '...' : ''}`);
165
250
  console.log(` Location: ${trustedKeysPath}`);
166
251
  console.log('\nYou can now verify dossiers signed with this key.\n');
167
252
  process.exit(0);
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgazD"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBzC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiazD"}
@@ -71,7 +71,8 @@ function registerRunCommand(program) {
71
71
  let resolvedFile = file;
72
72
  const isUrl = file.startsWith('http://') || file.startsWith('https://');
73
73
  const isLocalFile = !isUrl && node_fs_1.default.existsSync(node_path_1.default.resolve(file));
74
- const isNested = process.env.CLAUDE_CODE === '1' || process.env.CLAUDECODE === '1';
74
+ const nestedHost = (0, helpers_1.detectNestedHost)();
75
+ const isNested = nestedHost !== null;
75
76
  const log = isNested
76
77
  ? (...args) => console.error(...args)
77
78
  : (...args) => console.log(...args);
@@ -239,8 +240,8 @@ function registerRunCommand(program) {
239
240
  process.stderr.write(`Warning: failed to read dossier summary: ${err.message}\n`);
240
241
  }
241
242
  // Nested session detection
242
- if (process.env.CLAUDE_CODE === '1' || process.env.CLAUDECODE === '1') {
243
- console.error('ℹ️ Running inside Claude Code — outputting dossier content\n');
243
+ if (nestedHost !== null) {
244
+ console.error(`ℹ️ Running inside ${nestedHost} — outputting dossier content\n`);
244
245
  const llmOption = options.llm || config.getConfig('defaultLlm') || 'auto';
245
246
  (0, run_log_1.appendRunLog)({
246
247
  timestamp: new Date().toISOString(),