@kingkyylian/handoffkit 0.1.1 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0
4
+
5
+ - Added meaningful target-specific Markdown profiles for Codex, Claude Code, Cursor, and generic handoffs.
6
+ - Made `--for` adjust packet titles, section order, and next-agent action notes while preserving the same collected source facts.
7
+ - Added local secret scanner config discovery for `gitleaks` and `secretlint`.
8
+ - Added scanner installation and config guidance when optional local scanners are unavailable.
9
+ - Fixed secret redaction so scanner names such as `secretlint` are not mistaken for secret assignment keys.
10
+ - Updated tests to cover target profile rendering, unchanged JSON source facts across targets, scanner config discovery, direct `scan-secrets` guidance, and scanner-name redaction.
11
+
3
12
  ## 0.1.1
4
13
 
5
14
  - Added automated release tarball install smoke testing.
package/README.md CHANGED
@@ -104,6 +104,8 @@ Optimize the packet for a target agent:
104
104
  handoffkit pack --for codex --goal "Resume implementation"
105
105
  ```
106
106
 
107
+ Target profiles keep the same collected facts but adjust the title, section order, and next-agent notes for the selected tool. They do not invent project state or call model-specific APIs.
108
+
107
109
  During development:
108
110
 
109
111
  ```sh
@@ -190,7 +192,7 @@ HandoffKit reads local git and filesystem metadata from the current repository:
190
192
  - package manager and verification scripts from the root `package.json`
191
193
  - optional verification results when `--verify` is used
192
194
  - deterministic risk notes from changed file paths
193
- - optional secret scanner availability for `gitleaks` and `secretlint`
195
+ - optional secret scanner availability, local config files, and install guidance for `gitleaks` and `secretlint`
194
196
  - bounded, redacted secret scan results when `--scan-secrets` is used
195
197
 
196
198
  ## What Never Happens
@@ -214,7 +216,7 @@ pnpm pack:dry-run
214
216
 
215
217
  ## Release
216
218
 
217
- Releases are manual and should happen only after CI, package dry-run, and install smoke tests pass. The preferred path is the GitHub `Release` workflow with an `NPM_TOKEN` repository secret so npm provenance is attached to the published package.
219
+ Releases are manual and should happen only after CI, package dry-run, and install smoke tests pass. The preferred path is the GitHub `Release` workflow with an `NPM_TOKEN` repository secret that can publish from CI without an interactive OTP, so npm provenance is attached to the published package.
218
220
 
219
221
  See [docs/RELEASE.md](docs/RELEASE.md) for the release checklist.
220
222
 
@@ -224,6 +226,8 @@ HandoffKit is local-first and deterministic. It reads local git and filesystem s
224
226
 
225
227
  When `--scan-secrets` is used, HandoffKit runs installed local scanners only. It does not install scanners, send code to a service, or fail when `gitleaks` or `secretlint` is missing.
226
228
 
229
+ When scanner config files such as `.gitleaks.toml`, `.gitleaksignore`, `.secretlintrc.*`, or `secretlint.config.*` are present, HandoffKit reports them in the packet so the next agent knows which local policy files exist.
230
+
227
231
  ## License
228
232
 
229
233
  MIT
package/ROADMAP.md CHANGED
@@ -93,11 +93,11 @@ Regex redaction remains the default. HandoffKit detects optional local scanners
93
93
 
94
94
  Scan results are bounded and redacted before rendering.
95
95
 
96
+ Scanner status also reports common local config files such as `.gitleaks.toml`, `.gitleaksignore`, `.secretlintrc.*`, and `secretlint.config.*`. When a scanner is not installed, the packet includes local installation and config guidance without installing anything automatically.
97
+
96
98
  ## Next Up
97
99
 
98
- - Add scanner-specific installation guidance and config discovery.
99
100
  - Make `risk` rules richer by mapping changed files to common failure modes.
100
- - Improve `--for` formats beyond headings, with agent-specific action prompts.
101
101
  - Add transcript parsers for Claude Code, Codex, Cursor, and Gemini exports.
102
102
  - Add a stable `.handoffkit` cache format for verification and resume artifacts.
103
103
 
package/dist/index.js CHANGED
@@ -163,7 +163,7 @@ import fg from "fast-glob";
163
163
 
164
164
  // src/core/redact.ts
165
165
  var REDACTION = "[REDACTED]";
166
- var SECRET_KEY_PATTERN = /(\b[A-Z0-9_.-]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET|ACCESS[_-]?TOKEN|REFRESH[_-]?TOKEN|COOKIE|SESSION|JWT|AUTH_TOKEN)[A-Z0-9_.-]*\b\s*(?:=|:)\s*)(["']?)([^\s"',}]+)/gi;
166
+ var SECRET_KEY_PATTERN = /(\b(?:[A-Z0-9]+[_.-])*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET|ACCESS[_-]?TOKEN|REFRESH[_-]?TOKEN|COOKIE|SESSION|JWT|AUTH_TOKEN)(?:[_.-][A-Z0-9]+)*\b\s*(?:=|:)\s*)(["']?)([^\s"',}]+)/gi;
167
167
  var TOKEN_PATTERNS = [
168
168
  /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}/gi,
169
169
  /\bsk-[A-Za-z0-9_-]{16,}/g,
@@ -369,14 +369,15 @@ import { tmpdir } from "os";
369
369
  import { relative, join as join2 } from "path";
370
370
  import { performance } from "perf_hooks";
371
371
  import { execa as execa2 } from "execa";
372
+ import fg2 from "fast-glob";
372
373
  var MAX_FINDINGS = 20;
373
374
  var ERROR_LIMIT = 2e3;
374
- async function detectSecretScanners() {
375
- const [gitleaks, secretlint] = await Promise.all([scannerStatus("gitleaks"), scannerStatus("secretlint")]);
375
+ async function detectSecretScanners(root = process.cwd()) {
376
+ const [gitleaks, secretlint] = await Promise.all([scannerStatus("gitleaks", root), scannerStatus("secretlint", root)]);
376
377
  return { scanners: [gitleaks, secretlint] };
377
378
  }
378
379
  async function runSecretScanners(root) {
379
- const report = await detectSecretScanners();
380
+ const report = await detectSecretScanners(root);
380
381
  const scans = await Promise.all(report.scanners.map((scanner) => runScanner(root, scanner)));
381
382
  return { ...report, scans };
382
383
  }
@@ -422,14 +423,18 @@ function normalizeSecretlintFindings(rawJson, limit = MAX_FINDINGS, root) {
422
423
  }
423
424
  return findings;
424
425
  }
425
- async function scannerStatus(name) {
426
+ async function scannerStatus(name, root) {
426
427
  const result = await execa2(name, ["--version"], {
427
428
  reject: false
428
429
  }).catch(() => void 0);
430
+ const configFiles = await scannerConfigFiles(name, root);
429
431
  return {
430
432
  name,
431
433
  available: Boolean(result && result.exitCode === 0),
432
- ...result?.stdout ? { version: result.stdout.trim() } : {}
434
+ ...result?.stdout ? { version: result.stdout.trim() } : {},
435
+ configFiles,
436
+ configHint: configHint(name, configFiles),
437
+ installHint: installHint(name)
433
438
  };
434
439
  }
435
440
  async function runScanner(root, scanner) {
@@ -518,6 +523,25 @@ function trimError(output) {
518
523
  return trimmed.length > ERROR_LIMIT ? `${trimmed.slice(0, ERROR_LIMIT)}
519
524
  [truncated]` : trimmed;
520
525
  }
526
+ async function scannerConfigFiles(name, root) {
527
+ const patterns = name === "gitleaks" ? ["gitleaks.toml", ".gitleaks.toml", ".gitleaksignore", ".config/gitleaks/*.toml"] : [".secretlintrc", ".secretlintrc.*", "secretlint.config.*"];
528
+ const matches = await fg2(patterns, {
529
+ cwd: root,
530
+ dot: true,
531
+ onlyFiles: true,
532
+ unique: true
533
+ });
534
+ return matches.sort();
535
+ }
536
+ function configHint(name, configFiles) {
537
+ if (configFiles.length > 0) {
538
+ return `config: ${configFiles.join(", ")}`;
539
+ }
540
+ return name === "gitleaks" ? "config: none detected; optional files include .gitleaks.toml, gitleaks.toml, or .config/gitleaks/*.toml" : "config: none detected; optional files include .secretlintrc.*, .secretlintrc, or secretlint.config.*";
541
+ }
542
+ function installHint(name) {
543
+ return name === "gitleaks" ? "Install gitleaks from https://github.com/gitleaks/gitleaks, then rerun with --scan-secrets." : "Install secretlint from https://github.com/secretlint/secretlint, then rerun with --scan-secrets.";
544
+ }
521
545
 
522
546
  // src/core/verify.ts
523
547
  import { performance as performance2 } from "perf_hooks";
@@ -572,7 +596,7 @@ async function collectHandoffReport(options) {
572
596
  }),
573
597
  detectInstructionFiles(root),
574
598
  detectPackageInfo(root),
575
- options.scanSecrets ? runSecretScanners(root) : detectSecretScanners()
599
+ options.scanSecrets ? runSecretScanners(root) : detectSecretScanners(root)
576
600
  ]);
577
601
  const report = {
578
602
  goal: options.goal,
@@ -625,84 +649,176 @@ function renderJsonReport(report) {
625
649
  `;
626
650
  }
627
651
 
652
+ // src/report/profiles.ts
653
+ var genericOrder = [
654
+ "goal",
655
+ "repository",
656
+ "gitStatus",
657
+ "recentCommits",
658
+ "changedFiles",
659
+ "branchDelta",
660
+ "diffSummary",
661
+ "includedBranchDelta",
662
+ "includedDiff",
663
+ "instructionFiles",
664
+ "package",
665
+ "resume",
666
+ "verification",
667
+ "risk",
668
+ "secretScanning"
669
+ ];
670
+ var profiles = {
671
+ generic: {
672
+ title: "Handoff Packet",
673
+ sectionOrder: genericOrder,
674
+ nextAgentNotes: [
675
+ "Use this packet as the starting context for the next coding session.",
676
+ "Verify commands locally before claiming completion."
677
+ ]
678
+ },
679
+ codex: {
680
+ title: "Codex Handoff Packet",
681
+ sectionOrder: [
682
+ "goal",
683
+ "repository",
684
+ "gitStatus",
685
+ "changedFiles",
686
+ "verification",
687
+ "risk",
688
+ "branchDelta",
689
+ "diffSummary",
690
+ "includedBranchDelta",
691
+ "includedDiff",
692
+ "instructionFiles",
693
+ "package",
694
+ "resume",
695
+ "secretScanning",
696
+ "recentCommits"
697
+ ],
698
+ nextAgentNotes: [
699
+ "Start by reading the goal, repository status, changed files, and verification state.",
700
+ "Use local tools to inspect files before editing; do not assume hidden context.",
701
+ "Keep edits scoped and rerun the relevant verification before reporting completion."
702
+ ]
703
+ },
704
+ claude: {
705
+ title: "Claude Code Handoff Packet",
706
+ sectionOrder: [
707
+ "goal",
708
+ "resume",
709
+ "repository",
710
+ "verification",
711
+ "risk",
712
+ "changedFiles",
713
+ "gitStatus",
714
+ "branchDelta",
715
+ "diffSummary",
716
+ "includedBranchDelta",
717
+ "includedDiff",
718
+ "instructionFiles",
719
+ "package",
720
+ "secretScanning",
721
+ "recentCommits"
722
+ ],
723
+ nextAgentNotes: [
724
+ "Treat this as concise project memory plus current branch state.",
725
+ "Use the resume state to separate completed work from remaining work.",
726
+ "Ask for clarification only when the packet leaves a blocking ambiguity."
727
+ ]
728
+ },
729
+ cursor: {
730
+ title: "Cursor Handoff Packet",
731
+ sectionOrder: [
732
+ "goal",
733
+ "repository",
734
+ "changedFiles",
735
+ "gitStatus",
736
+ "includedDiff",
737
+ "diffSummary",
738
+ "branchDelta",
739
+ "includedBranchDelta",
740
+ "instructionFiles",
741
+ "package",
742
+ "verification",
743
+ "risk",
744
+ "resume",
745
+ "secretScanning",
746
+ "recentCommits"
747
+ ],
748
+ nextAgentNotes: [
749
+ "Open the changed files first to build editor context.",
750
+ "Use instruction files and package scripts to keep edits aligned with the workspace.",
751
+ "Prefer small edits and rerun the detected verification scripts."
752
+ ]
753
+ }
754
+ };
755
+ function profileForTarget(target) {
756
+ return profiles[target] ?? profiles.generic;
757
+ }
758
+
628
759
  // src/report/markdown.ts
629
760
  function renderMarkdownReport(report) {
761
+ const profile = profileForTarget(report.target);
630
762
  const lines = [
631
- `# ${titleForTarget(report.target)}`,
763
+ `# ${profile.title}`,
632
764
  "",
633
- "## Goal",
634
- report.goal,
635
- "",
636
- "## Repository",
637
- `- Repository: \`${report.repository.name}\``,
638
- `- Branch: \`${report.repository.branch}\``,
639
- `- Changed files: ${report.repository.changedFiles.length}`,
640
- "",
641
- "## Git Status",
642
- codeBlock(report.repository.status || "Clean working tree."),
643
- "",
644
- "## Recent Commits",
645
- listOrNone(report.repository.recentCommits.map((commit) => `- ${commit}`)),
646
- "",
647
- "## Changed Files",
648
- listOrNone(report.repository.changedFiles.map((file) => `- \`${file}\``)),
649
- "",
650
- ...renderBaseDiffSummary(report),
651
- "## Diff Summary",
652
- "### Staged",
653
- codeBlock(report.repository.stagedDiffSummary || "No staged diff."),
654
- "",
655
- "### Unstaged",
656
- codeBlock(report.repository.unstagedDiffSummary || "No unstaged diff."),
657
- "",
658
- "## Instruction Files",
659
- renderInstructionFiles(report.instructionFiles),
660
- "",
661
- "## Package",
662
- renderPackage(report.packageInfo),
663
- "",
664
- ...renderResumeSource(report),
665
- ...renderVerification(report),
666
- ...renderRisk(report),
667
- ...renderSecretScanning(report),
765
+ ...profile.sectionOrder.flatMap((section) => renderSection(section, report)),
668
766
  "## Next Agent Notes",
767
+ ...profile.nextAgentNotes.map((note) => `- ${note}`),
669
768
  "- This packet was generated from local git and filesystem state.",
670
769
  "- Likely secrets were redacted from generated output.",
671
770
  "- No LLM APIs were called."
672
771
  ];
673
- if (report.repository.includeDiff && report.repository.diff) {
674
- lines.splice(
675
- lines.indexOf("## Instruction Files"),
676
- 0,
677
- "## Included Diff",
678
- "### Staged Patch",
679
- codeBlock(report.repository.diff.staged || "No staged patch."),
680
- "",
681
- "### Unstaged Patch",
682
- codeBlock(report.repository.diff.unstaged || "No unstaged patch."),
683
- ""
684
- );
685
- }
686
- if (report.repository.includeDiff && report.repository.baseDiff) {
687
- lines.splice(
688
- lines.indexOf("## Included Diff"),
689
- 0,
690
- `## Included Branch Delta Since \`${report.repository.baseRef}\``,
691
- codeBlock(report.repository.baseDiff),
692
- ""
693
- );
694
- }
695
772
  return `${lines.join("\n")}
696
773
  `;
697
774
  }
698
- function titleForTarget(target = "generic") {
699
- const labels = {
700
- generic: "Handoff Packet",
701
- codex: "Codex Handoff Packet",
702
- claude: "Claude Handoff Packet",
703
- cursor: "Cursor Handoff Packet"
704
- };
705
- return labels[target] ?? "Handoff Packet";
775
+ function renderSection(section, report) {
776
+ switch (section) {
777
+ case "goal":
778
+ return ["## Goal", report.goal, ""];
779
+ case "repository":
780
+ return [
781
+ "## Repository",
782
+ `- Repository: \`${report.repository.name}\``,
783
+ `- Branch: \`${report.repository.branch}\``,
784
+ `- Changed files: ${report.repository.changedFiles.length}`,
785
+ ""
786
+ ];
787
+ case "gitStatus":
788
+ return ["## Git Status", codeBlock(report.repository.status || "Clean working tree."), ""];
789
+ case "recentCommits":
790
+ return ["## Recent Commits", listOrNone(report.repository.recentCommits.map((commit) => `- ${commit}`)), ""];
791
+ case "changedFiles":
792
+ return ["## Changed Files", listOrNone(report.repository.changedFiles.map((file) => `- \`${file}\``)), ""];
793
+ case "branchDelta":
794
+ return renderBaseDiffSummary(report);
795
+ case "diffSummary":
796
+ return [
797
+ "## Diff Summary",
798
+ "### Staged",
799
+ codeBlock(report.repository.stagedDiffSummary || "No staged diff."),
800
+ "",
801
+ "### Unstaged",
802
+ codeBlock(report.repository.unstagedDiffSummary || "No unstaged diff."),
803
+ ""
804
+ ];
805
+ case "includedBranchDelta":
806
+ return renderIncludedBranchDelta(report);
807
+ case "includedDiff":
808
+ return renderIncludedDiff(report);
809
+ case "instructionFiles":
810
+ return ["## Instruction Files", renderInstructionFiles(report.instructionFiles), ""];
811
+ case "package":
812
+ return ["## Package", renderPackage(report.packageInfo), ""];
813
+ case "resume":
814
+ return renderResumeSource(report);
815
+ case "verification":
816
+ return renderVerification(report);
817
+ case "risk":
818
+ return renderRisk(report);
819
+ case "secretScanning":
820
+ return renderSecretScanning(report);
821
+ }
706
822
  }
707
823
  function renderBaseDiffSummary(report) {
708
824
  if (!report.repository.baseRef) {
@@ -714,6 +830,30 @@ function renderBaseDiffSummary(report) {
714
830
  ""
715
831
  ];
716
832
  }
833
+ function renderIncludedBranchDelta(report) {
834
+ if (!report.repository.includeDiff || !report.repository.baseDiff) {
835
+ return [];
836
+ }
837
+ return [
838
+ `## Included Branch Delta Since \`${report.repository.baseRef}\``,
839
+ codeBlock(report.repository.baseDiff),
840
+ ""
841
+ ];
842
+ }
843
+ function renderIncludedDiff(report) {
844
+ if (!report.repository.includeDiff || !report.repository.diff) {
845
+ return [];
846
+ }
847
+ return [
848
+ "## Included Diff",
849
+ "### Staged Patch",
850
+ codeBlock(report.repository.diff.staged || "No staged patch."),
851
+ "",
852
+ "### Unstaged Patch",
853
+ codeBlock(report.repository.diff.unstaged || "No unstaged patch."),
854
+ ""
855
+ ];
856
+ }
717
857
  function renderPackage(packageInfo) {
718
858
  if (!packageInfo) {
719
859
  return "No package.json detected.";
@@ -801,12 +941,16 @@ function renderSecretScanning(report) {
801
941
  }
802
942
  function renderSecretScannerReport(secretScanning) {
803
943
  if (!secretScanning.scans) {
804
- return secretScanning.scanners.map((scanner) => `- ${scanner.name}: ${scanner.available ? "available" : "not found"}`).join("\n");
944
+ return secretScanning.scanners.map((scanner) => `- ${scannerStatusLine(scanner)}`).join("\n");
805
945
  }
806
946
  return secretScanning.scans.map((scan) => {
947
+ const status = secretScanning.scanners.find((scanner) => scanner.name === scan.name);
807
948
  const lines = [
808
949
  `- ${scan.name}: ${scan.ran ? `${scan.findings.length} finding(s), exit ${scan.exitCode}` : scan.error ?? "not run"}`
809
950
  ];
951
+ if (status) {
952
+ lines.push(...scannerGuidanceLines(status));
953
+ }
810
954
  for (const finding of scan.findings) {
811
955
  lines.push(` - ${finding.ruleId ? `${finding.ruleId}: ` : ""}${finding.message}${finding.file ? ` (${finding.file}${finding.line ? `:${finding.line}` : ""})` : ""}`);
812
956
  }
@@ -816,6 +960,23 @@ function renderSecretScannerReport(secretScanning) {
816
960
  return lines.join("\n");
817
961
  }).join("\n");
818
962
  }
963
+ function scannerStatusLine(scanner) {
964
+ const config = scanner.configFiles.length > 0 ? `; config: ${scanner.configFiles.join(", ")}` : scanner.available ? "" : `; ${scanner.configHint}`;
965
+ const install = scanner.available ? "" : `; ${scanner.installHint}`;
966
+ return `${scanner.name}: ${scanner.available ? "available" : "not found"}${config}${install}`;
967
+ }
968
+ function scannerGuidanceLines(scanner) {
969
+ const lines = [];
970
+ if (scanner.configFiles.length > 0) {
971
+ lines.push(` - config: ${scanner.configFiles.join(", ")}`);
972
+ } else if (!scanner.available) {
973
+ lines.push(` - ${scanner.configHint}`);
974
+ }
975
+ if (!scanner.available) {
976
+ lines.push(` - ${scanner.installHint}`);
977
+ }
978
+ return lines;
979
+ }
819
980
  function codeBlock(text) {
820
981
  return ["```text", text, "```"].join("\n");
821
982
  }
@@ -1072,7 +1233,11 @@ function createScanSecretsCommand() {
1072
1233
  function renderScanMarkdown(report) {
1073
1234
  const lines = ["# Secret Scan Results", ""];
1074
1235
  for (const scan of report.scans ?? []) {
1236
+ const status = report.scanners.find((scanner) => scanner.name === scan.name);
1075
1237
  lines.push(`- ${scan.name}: ${scan.ran ? `${scan.findings.length} finding(s), exit ${scan.exitCode}` : scan.error ?? "not run"}`);
1238
+ if (status) {
1239
+ lines.push(...scannerGuidanceLines2(status));
1240
+ }
1076
1241
  for (const finding of scan.findings) {
1077
1242
  lines.push(` - ${finding.ruleId ? `${finding.ruleId}: ` : ""}${finding.message}${finding.file ? ` (${finding.file}${finding.line ? `:${finding.line}` : ""})` : ""}`);
1078
1243
  }
@@ -1080,6 +1245,18 @@ function renderScanMarkdown(report) {
1080
1245
  return `${lines.join("\n")}
1081
1246
  `;
1082
1247
  }
1248
+ function scannerGuidanceLines2(scanner) {
1249
+ const lines = [];
1250
+ if (scanner.configFiles.length > 0) {
1251
+ lines.push(` - config: ${scanner.configFiles.join(", ")}`);
1252
+ } else if (!scanner.available) {
1253
+ lines.push(` - ${scanner.configHint}`);
1254
+ }
1255
+ if (!scanner.available) {
1256
+ lines.push(` - ${scanner.installHint}`);
1257
+ }
1258
+ return lines;
1259
+ }
1083
1260
 
1084
1261
  // src/cli/commands/verify.ts
1085
1262
  import { Command as Command5 } from "commander";
@@ -1114,7 +1291,7 @@ function renderVerificationMarkdown(commands) {
1114
1291
  }
1115
1292
 
1116
1293
  // src/cli/index.ts
1117
- var program = new Command6().name("handoffkit").description("Create safe local handoff packets for AI-assisted coding sessions.").summary("Create local-first AI coding session handoff packets.").showHelpAfterError("(run with --help for usage)").version("0.1.1");
1294
+ var program = new Command6().name("handoffkit").description("Create safe local handoff packets for AI-assisted coding sessions.").summary("Create local-first AI coding session handoff packets.").showHelpAfterError("(run with --help for usage)").version("0.2.0");
1118
1295
  program.addCommand(createPackCommand());
1119
1296
  program.addCommand(createVerifyCommand());
1120
1297
  program.addCommand(createRiskCommand());
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/index.ts","../src/cli/commands/pack.ts","../src/core/git.ts","../src/cli/errors.ts","../src/core/instructions.ts","../src/core/redact.ts","../src/core/package-json.ts","../src/core/risk.ts","../src/core/scanners.ts","../src/core/verify.ts","../src/core/collect.ts","../src/cli/output.ts","../src/core/budget.ts","../src/report/json.ts","../src/report/markdown.ts","../src/cli/commands/resume.ts","../src/core/resume.ts","../src/cli/commands/risk.ts","../src/cli/commands/scan-secrets.ts","../src/cli/commands/verify.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\n\nimport { createPackCommand } from \"./commands/pack.js\";\nimport { createResumeCommand } from \"./commands/resume.js\";\nimport { createRiskCommand } from \"./commands/risk.js\";\nimport { createScanSecretsCommand } from \"./commands/scan-secrets.js\";\nimport { createVerifyCommand } from \"./commands/verify.js\";\nimport { formatCliError } from \"./errors.js\";\n\nconst program = new Command()\n .name(\"handoffkit\")\n .description(\"Create safe local handoff packets for AI-assisted coding sessions.\")\n .summary(\"Create local-first AI coding session handoff packets.\")\n .showHelpAfterError(\"(run with --help for usage)\")\n .version(\"0.1.1\");\n\nprogram.addCommand(createPackCommand());\nprogram.addCommand(createVerifyCommand());\nprogram.addCommand(createRiskCommand());\nprogram.addCommand(createScanSecretsCommand());\nprogram.addCommand(createResumeCommand());\n\ntry {\n await program.parseAsync(process.argv);\n} catch (error) {\n process.stderr.write(`${formatCliError(error)}\\n`);\n process.exitCode = 1;\n}\n","import { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { collectHandoffReport } from \"../../core/collect.js\";\nimport { writeRenderedReport } from \"../output.js\";\n\nconst PackCliOptionsSchema = z.object({\n goal: z.string().trim().min(1).default(\"Make your own goal\"),\n output: z.string().optional(),\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\"),\n for: z.enum([\"generic\", \"codex\", \"claude\", \"cursor\"]).default(\"generic\"),\n budget: z.number().int().positive().default(4000),\n includeDiff: z.boolean().default(false),\n diff: z.boolean().default(true),\n since: z.string().trim().min(1).optional(),\n verify: z.boolean().default(false),\n scanSecrets: z.boolean().default(false)\n});\n\nexport function createPackCommand() {\n return new Command(\"pack\")\n .description(\"Create a safe local handoff packet for another AI assistant.\")\n .summary(\"Create a Markdown or JSON packet from the current git state.\")\n .option(\"--goal <text>\", \"handoff goal\", \"Make your own goal\")\n .option(\"--output <path>\", \"write output to a file instead of stdout\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .option(\"--for <agent>\", \"target output: generic, codex, claude, or cursor\", \"generic\")\n .option(\"--budget <tokens>\", \"rough output token budget\", parseBudget, 4000)\n .option(\"--since <ref>\", \"focus committed branch delta on a base ref\")\n .option(\"--verify\", \"run safe verification scripts and include results\")\n .option(\"--scan-secrets\", \"run optional local secret scanners and include bounded results\")\n .option(\"--include-diff\", \"include full staged and unstaged patches\", false)\n .option(\"--no-diff\", \"omit diff summaries and full patches\")\n .action(async (rawOptions) => {\n const options = parseOptions(rawOptions);\n const report = await collectHandoffReport({\n goal: options.goal,\n cwd: process.cwd(),\n ...(options.output ? { output: options.output } : {}),\n format: options.format,\n target: options.for,\n budget: options.budget,\n includeDiff: options.includeDiff,\n includeDiffSummary: options.diff,\n ...(options.since ? { since: options.since } : {}),\n includeVerification: options.verify,\n scanSecrets: options.scanSecrets\n });\n\n await writeRenderedReport(report, options.format, options.budget, options.output);\n });\n}\n\nfunction parseOptions(rawOptions: unknown) {\n const result = PackCliOptionsSchema.safeParse(rawOptions);\n\n if (!result.success) {\n const message = result.error.issues.map((issue) => issue.message).join(\"\\n\");\n throw new Error(`Invalid pack options:\\n${message}`);\n }\n\n return result.data;\n}\n\nfunction parseBudget(value: string) {\n const parsed = Number.parseInt(value, 10);\n\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new Error(\"--budget must be a positive integer.\");\n }\n\n return parsed;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { HandoffKitCliError } from \"../cli/errors.js\";\nimport type { DiffInfo, RepositoryInfo } from \"../types.js\";\n\nconst UNTRACKED_PATCH_CHAR_LIMIT = 20_000;\nconst IGNORED_CHANGED_PATH_PREFIXES = [\"node_modules/\", \"dist/\", \"coverage/\", \".git/\"];\n\nexport interface GitCollectOptions {\n includeDiff: boolean;\n includeDiffSummary: boolean;\n since?: string;\n}\n\nexport async function findGitRoot(cwd: string): Promise<string> {\n const result = await execa(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd,\n reject: false\n });\n\n if (result.exitCode !== 0) {\n throw new HandoffKitCliError([\n \"HandoffKit must be run inside a git repository.\",\n \"Run this command from a git checkout, or initialize one with `git init`.\"\n ].join(\"\\n\"));\n }\n\n return result.stdout.trimEnd();\n}\n\nexport async function collectGitInfo(root: string, options: GitCollectOptions): Promise<RepositoryInfo> {\n const [branch, status, porcelainStatus, recentCommits, stagedDiffSummary, trackedUnstagedDiffSummary, baseInfo] =\n await Promise.all([\n currentBranch(root),\n git(root, [\"status\", \"--short\", \"--branch\"]),\n git(root, [\"status\", \"--porcelain=v1\", \"--untracked-files=all\"]),\n recentCommitLines(root, options.since),\n options.includeDiffSummary ? git(root, [\"diff\", \"--cached\", \"--stat\"]) : Promise.resolve(\"\"),\n options.includeDiffSummary ? git(root, [\"diff\", \"--stat\"]) : Promise.resolve(\"\"),\n options.since ? collectBaseInfo(root, options.since, options.includeDiffSummary, options.includeDiff) : Promise.resolve(undefined)\n ]);\n\n const changedFiles = uniqueSorted([...(baseInfo?.changedFiles ?? []), ...parseChangedFiles(porcelainStatus)]);\n const untrackedFiles = parseUntrackedFiles(porcelainStatus);\n const unstagedDiffSummary = options.includeDiffSummary\n ? joinSections([trackedUnstagedDiffSummary, renderUntrackedSummary(untrackedFiles)])\n : \"\";\n const diff = options.includeDiff ? await collectDiff(root, untrackedFiles) : undefined;\n\n return {\n name: basename(root),\n branch,\n ...(options.since ? { baseRef: options.since } : {}),\n status,\n recentCommits,\n changedFiles,\n ...(baseInfo?.summary ? { baseDiffSummary: baseInfo.summary } : {}),\n stagedDiffSummary,\n unstagedDiffSummary,\n includeDiff: options.includeDiff,\n ...(baseInfo?.patch ? { baseDiff: baseInfo.patch } : {}),\n ...(diff ? { diff } : {})\n };\n}\n\nasync function currentBranch(root: string) {\n const branch = await git(root, [\"branch\", \"--show-current\"]);\n\n if (branch) {\n return branch;\n }\n\n const commit = await git(root, [\"rev-parse\", \"--short\", \"HEAD\"], { allowFailure: true });\n return commit ? `detached:${commit}` : \"unknown\";\n}\n\nasync function recentCommitLines(root: string, since?: string) {\n const args = since ? [\"log\", \"--oneline\", \"-n\", \"10\", `${since}..HEAD`] : [\"log\", \"--oneline\", \"-n\", \"10\"];\n const output = await git(root, args, { allowFailure: true });\n return output ? output.split(\"\\n\") : [];\n}\n\nasync function collectBaseInfo(root: string, since: string, includeDiffSummary: boolean, includeDiff: boolean) {\n await ensureRef(root, since);\n const range = `${since}...HEAD`;\n const [changedFiles, summary, patch] = await Promise.all([\n git(root, [\"diff\", \"--name-only\", range], { allowFailure: true }),\n includeDiffSummary ? git(root, [\"diff\", \"--stat\", range], { allowFailure: true }) : Promise.resolve(\"\"),\n includeDiff ? git(root, [\"diff\", \"--patch\", range], { allowFailure: true }) : Promise.resolve(\"\")\n ]);\n\n return {\n changedFiles: changedFiles ? changedFiles.split(\"\\n\").filter(Boolean) : [],\n summary,\n patch\n };\n}\n\nasync function ensureRef(root: string, ref: string) {\n const result = await execa(\"git\", [\"rev-parse\", \"--verify\", `${ref}^{commit}`], {\n cwd: root,\n reject: false\n });\n\n if (result.exitCode !== 0) {\n throw new Error(`Could not resolve --since ref: ${ref}`);\n }\n}\n\nasync function collectDiff(root: string, untrackedFiles: string[]): Promise<DiffInfo> {\n const [staged, unstagedTracked, untracked] = await Promise.all([\n git(root, [\"diff\", \"--cached\", \"--patch\"]),\n git(root, [\"diff\", \"--patch\"]),\n untrackedPatch(root, untrackedFiles)\n ]);\n\n return { staged, unstaged: joinSections([unstagedTracked, untracked]) };\n}\n\nasync function git(root: string, args: string[], options: { allowFailure?: boolean } = {}) {\n const result = await execa(\"git\", args, {\n cwd: root,\n reject: false\n });\n\n if (result.exitCode !== 0 && !options.allowFailure) {\n throw new Error(result.stderr || `git ${args.join(\" \")} failed`);\n }\n\n return result.stdout.trim();\n}\n\nfunction parseChangedFiles(status: string) {\n const files = status\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .filter(Boolean)\n .map((line) => line.slice(line[2] === \" \" ? 3 : 2).trim())\n .map((path) => (path.includes(\" -> \") ? path.split(\" -> \").at(-1) ?? path : path))\n .map((path) => path.replace(/^\"|\"$/g, \"\"));\n\n return uniqueSorted(files.filter((file) => !isIgnoredChangedPath(file)));\n}\n\nfunction parseUntrackedFiles(status: string) {\n return status\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .filter((line) => line.startsWith(\"?? \"))\n .map((line) => line.slice(3).trim())\n .map((path) => path.replace(/^\"|\"$/g, \"\"))\n .filter((file) => !isIgnoredChangedPath(file))\n .sort();\n}\n\nfunction renderUntrackedSummary(files: string[]) {\n if (files.length === 0) {\n return \"\";\n }\n\n return files.map((file) => `${file} | untracked`).join(\"\\n\");\n}\n\nasync function untrackedPatch(root: string, files: string[]) {\n const patches = await Promise.all(\n files.map(async (file) => {\n const content = await readFile(`${root}/${file}`, \"utf8\");\n const trimmedContent =\n content.length > UNTRACKED_PATCH_CHAR_LIMIT\n ? `${content.slice(0, UNTRACKED_PATCH_CHAR_LIMIT).trimEnd()}\\n[truncated]`\n : content.trimEnd();\n\n return [`Untracked file: ${file}`, \"```text\", trimmedContent, \"```\"].join(\"\\n\");\n })\n );\n\n return patches.join(\"\\n\\n\");\n}\n\nfunction joinSections(sections: string[]) {\n return sections.filter(Boolean).join(\"\\n\\n\").trim();\n}\n\nfunction uniqueSorted(files: string[]) {\n return [...new Set(files.filter((file) => !isIgnoredChangedPath(file)))].sort();\n}\n\nfunction isIgnoredChangedPath(file: string) {\n return IGNORED_CHANGED_PATH_PREFIXES.some((prefix) => file === prefix.slice(0, -1) || file.startsWith(prefix));\n}\n","export class HandoffKitCliError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"HandoffKitCliError\";\n }\n}\n\nexport function formatCliError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return message.trim();\n}\n","import { readFile, stat } from \"node:fs/promises\";\n\nimport fg from \"fast-glob\";\n\nimport type { InstructionFile } from \"../types.js\";\nimport { redactText } from \"./redact.js\";\n\nconst INSTRUCTION_PATTERNS = [\n \"**/AGENTS.md\",\n \"**/CLAUDE.md\",\n \"**/GEMINI.md\",\n \".cursor/rules\",\n \".cursor/rules/**/*\",\n \".github/copilot-instructions.md\"\n];\n\nconst PREVIEW_CHAR_LIMIT = 1200;\n\nexport async function detectInstructionFiles(root: string): Promise<InstructionFile[]> {\n const paths = await fg(INSTRUCTION_PATTERNS, {\n cwd: root,\n dot: true,\n onlyFiles: false,\n unique: true,\n ignore: [\"**/.git/**\", \"**/node_modules/**\", \"**/dist/**\", \"**/coverage/**\"]\n });\n\n return Promise.all(paths.sort().map((path) => instructionFile(root, path)));\n}\n\nasync function instructionFile(root: string, path: string): Promise<InstructionFile> {\n return {\n path,\n kind: instructionKind(path),\n preview: await readPreview(root, path)\n };\n}\n\nasync function readPreview(root: string, path: string) {\n const fullPath = `${root}/${path}`;\n const metadata = await stat(fullPath);\n\n if (!metadata.isFile()) {\n return \"Directory rule set detected.\";\n }\n\n const content = await readFile(fullPath, \"utf8\");\n const normalized = content.replace(/\\r\\n/g, \"\\n\").trim();\n const preview =\n normalized.length > PREVIEW_CHAR_LIMIT ? `${normalized.slice(0, PREVIEW_CHAR_LIMIT).trimEnd()}\\n[truncated]` : normalized;\n\n return redactText(preview);\n}\n\nfunction instructionKind(path: string): InstructionFile[\"kind\"] {\n if (path.endsWith(\"AGENTS.md\")) {\n return \"agents\";\n }\n\n if (path.endsWith(\"CLAUDE.md\")) {\n return \"claude\";\n }\n\n if (path.endsWith(\"GEMINI.md\")) {\n return \"gemini\";\n }\n\n if (path === \".cursor/rules\" || path.startsWith(\".cursor/rules/\")) {\n return \"cursor\";\n }\n\n if (path === \".github/copilot-instructions.md\") {\n return \"copilot\";\n }\n\n return \"instruction\";\n}\n","const REDACTION = \"[REDACTED]\";\n\nconst SECRET_KEY_PATTERN =\n /(\\b[A-Z0-9_.-]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET|ACCESS[_-]?TOKEN|REFRESH[_-]?TOKEN|COOKIE|SESSION|JWT|AUTH_TOKEN)[A-Z0-9_.-]*\\b\\s*(?:=|:)\\s*)([\"']?)([^\\s\"',}]+)/gi;\n\nconst TOKEN_PATTERNS: RegExp[] = [\n /\\bBearer\\s+[A-Za-z0-9._~+/=-]{12,}/gi,\n /\\bsk-[A-Za-z0-9_-]{16,}/g,\n /\\bgh[pousr]_[A-Za-z0-9_]{16,}/g,\n /\\bnpm_[A-Za-z0-9_-]{16,}/g,\n /\\bxox[baprs]-[A-Za-z0-9-]{16,}/g,\n /\\bAIza[0-9A-Za-z_-]{20,}/g,\n /\\bAKIA[0-9A-Z]{16}\\b/g,\n /\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b/g,\n /\\/\\/([^/\\s:@]+):([^@\\s/]+)@/g\n];\n\nexport function redactText(input: string): string {\n let output = input.replace(\n /-----BEGIN ([A-Z ]*PRIVATE KEY)-----[\\s\\S]*?-----END \\1-----/g,\n (_match, keyType: string) => `-----BEGIN ${keyType}-----\\n${REDACTION}\\n-----END ${keyType}-----`\n );\n\n output = output.replace(SECRET_KEY_PATTERN, (_match, prefix: string, quote: string) => {\n return `${prefix}${quote}${REDACTION}${quote}`;\n });\n\n output = output.replace(/\\bBearer\\s+[A-Za-z0-9._~+/=-]{12,}/gi, \"Bearer [REDACTED]\");\n output = output.replace(/\\/\\/([^/\\s:@]+):([^@\\s/]+)@/g, \"//[REDACTED]@\");\n\n for (const pattern of TOKEN_PATTERNS.slice(1, -1)) {\n output = output.replace(pattern, REDACTION);\n }\n\n return output;\n}\n","import { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { z } from \"zod\";\n\nimport type { PackageInfo, VerificationScript } from \"../types.js\";\n\nconst PackageJsonSchema = z.object({\n name: z.string().optional(),\n packageManager: z.string().optional(),\n scripts: z.record(z.string(), z.string()).optional()\n});\n\nconst VERIFY_SCRIPT_ORDER = [\"build\", \"test\", \"typecheck\", \"lint\", \"check\", \"verify\", \"ci\"];\nconst VERIFY_SCRIPT_PREFIX = /^(build|test|typecheck|lint|check|verify|ci)(:|$)/;\n\nexport async function detectPackageInfo(root: string): Promise<PackageInfo | undefined> {\n const packageJsonPath = join(root, \"package.json\");\n\n if (!(await pathExists(packageJsonPath))) {\n return undefined;\n }\n\n const rawPackageJson = await readFile(packageJsonPath, \"utf8\");\n const packageJson = PackageJsonSchema.parse(JSON.parse(rawPackageJson));\n const packageManager = await detectPackageManager(root, packageJson.packageManager);\n const verificationScripts = detectVerificationScripts(packageJson.scripts ?? {});\n\n return {\n ...(packageJson.name ? { name: packageJson.name } : {}),\n ...(packageManager ? { packageManager } : {}),\n verificationScripts\n };\n}\n\nexport async function detectPackageManager(root: string, packageManagerField?: string) {\n if (packageManagerField) {\n return packageManagerField.split(\"@\")[0] || packageManagerField;\n }\n\n const lockfiles: Array<[string, string]> = [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"package-lock.json\", \"npm\"],\n [\"bun.lock\", \"bun\"],\n [\"bun.lockb\", \"bun\"]\n ];\n\n for (const [lockfile, manager] of lockfiles) {\n if (await pathExists(join(root, lockfile))) {\n return manager;\n }\n }\n\n return undefined;\n}\n\nexport function detectVerificationScripts(scripts: Record<string, string>): VerificationScript[] {\n return Object.entries(scripts)\n .filter(([name]) => VERIFY_SCRIPT_PREFIX.test(name))\n .sort(([left], [right]) => {\n const leftIndex = orderIndex(left);\n const rightIndex = orderIndex(right);\n\n if (leftIndex !== rightIndex) {\n return leftIndex - rightIndex;\n }\n\n return left.localeCompare(right);\n })\n .map(([name, command]) => ({ name, command }));\n}\n\nasync function pathExists(path: string) {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction orderIndex(name: string) {\n const baseName = name.split(\":\")[0] ?? name;\n const index = VERIFY_SCRIPT_ORDER.indexOf(baseName);\n return index === -1 ? VERIFY_SCRIPT_ORDER.length : index;\n}\n","import type { HandoffReport, RiskReport, RiskNote } from \"../types.js\";\n\nexport function analyzeRisk(report: HandoffReport): RiskReport {\n const files = report.repository.changedFiles;\n const notes: RiskNote[] = [];\n\n if (files.some((file) => /(^|\\/)(redact|secret|auth|token|security)/i.test(file))) {\n notes.push({\n severity: \"high\",\n title: \"Security-sensitive code changed\",\n detail: \"Review redaction, auth, token, or secret-handling changes carefully before handoff.\"\n });\n }\n\n if (files.some((file) => file === \"package.json\" || file.endsWith(\"-lock.yaml\") || file.endsWith(\"lock.json\"))) {\n notes.push({\n severity: \"medium\",\n title: \"Dependency or package metadata changed\",\n detail: \"Run install/build verification and check package publishing metadata.\"\n });\n }\n\n if (files.some((file) => file.startsWith(\".github/workflows/\"))) {\n notes.push({\n severity: \"medium\",\n title: \"CI workflow changed\",\n detail: \"Confirm GitHub Actions still passes after push.\"\n });\n }\n\n const sourceFiles = files.filter((file) => file.startsWith(\"src/\") && file.endsWith(\".ts\"));\n const testFiles = files.filter((file) => file.startsWith(\"tests/\") && file.endsWith(\".test.ts\"));\n\n if (sourceFiles.length > 0 && testFiles.length === 0) {\n notes.push({\n severity: \"medium\",\n title: \"Source changed without matching tests\",\n detail: `Review test coverage for ${sourceFiles.slice(0, 5).join(\", \")}.`\n });\n }\n\n if (notes.length === 0) {\n notes.push({\n severity: \"low\",\n title: \"No obvious local risk signals\",\n detail: \"No deterministic risk rule matched the current changed file set.\"\n });\n }\n\n return { notes };\n}\n","import { mkdtemp, readFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { relative, join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { execa } from \"execa\";\n\nimport type { SecretFinding, SecretScannerReport, SecretScannerStatus, SecretScanResult } from \"../types.js\";\nimport { redactText } from \"./redact.js\";\n\nconst MAX_FINDINGS = 20;\nconst ERROR_LIMIT = 2000;\n\nexport async function detectSecretScanners(): Promise<SecretScannerReport> {\n const [gitleaks, secretlint] = await Promise.all([scannerStatus(\"gitleaks\"), scannerStatus(\"secretlint\")]);\n return { scanners: [gitleaks, secretlint] };\n}\n\nexport async function runSecretScanners(root: string): Promise<SecretScannerReport> {\n const report = await detectSecretScanners();\n const scans = await Promise.all(report.scanners.map((scanner) => runScanner(root, scanner)));\n return { ...report, scans };\n}\n\nexport function formatScannerSummary(report: SecretScannerReport): string {\n const availability = report.scanners\n .map((scanner) => `${scanner.name}: ${scanner.available ? \"available\" : \"not found\"}`)\n .join(\"\\n\");\n\n if (!report.scans) {\n return availability;\n }\n\n const scans = report.scans\n .map((scan) => `${scan.name}: ${scan.ran ? `${scan.findings.length} finding(s)` : scan.error ?? \"not run\"}`)\n .join(\"\\n\");\n\n return `${availability}\\n${scans}`;\n}\n\nexport function normalizeGitleaksFindings(rawJson: string, limit = MAX_FINDINGS): SecretFinding[] {\n const parsed = safeJson(rawJson);\n\n if (!Array.isArray(parsed)) {\n return [];\n }\n\n return parsed.slice(0, limit).map((finding) => {\n const ruleId = stringValue(finding.RuleID);\n const file = stringValue(finding.File);\n const line = numberValue(finding.StartLine);\n\n return {\n ...(ruleId ? { ruleId } : {}),\n message: redactText(stringValue(finding.Description) || \"Secret finding\"),\n ...(file ? { file } : {}),\n ...(line ? { line } : {})\n };\n });\n}\n\nexport function normalizeSecretlintFindings(rawJson: string, limit = MAX_FINDINGS, root?: string): SecretFinding[] {\n const parsed = safeJson(rawJson);\n\n if (!Array.isArray(parsed)) {\n return [];\n }\n\n const findings: SecretFinding[] = [];\n\n for (const fileResult of parsed) {\n const messages = Array.isArray(fileResult.messages) ? fileResult.messages : [];\n\n for (const message of messages) {\n if (findings.length >= limit) {\n return findings;\n }\n\n const filePath = stringValue(fileResult.filePath);\n const ruleId = stringValue(message.ruleId);\n const line = numberValue(message.line);\n findings.push({\n ...(ruleId ? { ruleId } : {}),\n message: redactText(stringValue(message.message) || \"Secret finding\"),\n ...(filePath ? { file: root ? relative(root, filePath) || filePath : filePath } : {}),\n ...(line ? { line } : {})\n });\n }\n }\n\n return findings;\n}\n\nasync function scannerStatus(name: \"gitleaks\" | \"secretlint\"): Promise<SecretScannerStatus> {\n const result = await execa(name, [\"--version\"], {\n reject: false\n }).catch(() => undefined);\n\n return {\n name,\n available: Boolean(result && result.exitCode === 0),\n ...(result?.stdout ? { version: result.stdout.trim() } : {})\n };\n}\n\nasync function runScanner(root: string, scanner: SecretScannerStatus): Promise<SecretScanResult> {\n if (!scanner.available) {\n return {\n name: scanner.name,\n available: false,\n ran: false,\n findings: [],\n error: \"Scanner binary not found.\",\n truncated: false\n };\n }\n\n return scanner.name === \"gitleaks\" ? runGitleaks(root) : runSecretlint(root);\n}\n\nasync function runGitleaks(root: string): Promise<SecretScanResult> {\n const started = performance.now();\n const tempDir = await mkdtemp(join(tmpdir(), \"handoffkit-gitleaks-\"));\n const reportPath = join(tempDir, \"report.json\");\n const result = await execa(\n \"gitleaks\",\n [\"dir\", root, \"--no-banner\", \"--no-color\", \"--redact=100\", \"--report-format\", \"json\", \"--report-path\", reportPath, \"--max-target-megabytes\", \"2\"],\n { reject: false, all: true }\n );\n const rawReport = await readFile(reportPath, \"utf8\").catch(() => \"[]\");\n const findings = normalizeGitleaksFindings(rawReport);\n\n return {\n name: \"gitleaks\",\n available: true,\n ran: result.exitCode === 0 || result.exitCode === 1,\n exitCode: result.exitCode ?? 1,\n durationMs: Math.round(performance.now() - started),\n findings,\n ...(result.exitCode && result.exitCode > 1 ? { error: redactText(trimError(result.all ?? result.stderr ?? \"\")) } : {}),\n truncated: countJsonArray(rawReport) > findings.length\n };\n}\n\nasync function runSecretlint(root: string): Promise<SecretScanResult> {\n const started = performance.now();\n const result = await execa(\"secretlint\", [\"**/*\", \"--format\", \"json\", \"--no-color\"], {\n cwd: root,\n reject: false,\n all: true\n });\n const rawOutput = result.stdout || result.all || \"[]\";\n const findings = normalizeSecretlintFindings(rawOutput, MAX_FINDINGS, root);\n\n return {\n name: \"secretlint\",\n available: true,\n ran: result.exitCode === 0 || result.exitCode === 1,\n exitCode: result.exitCode ?? 1,\n durationMs: Math.round(performance.now() - started),\n findings,\n ...(result.exitCode && result.exitCode > 1 ? { error: redactText(trimError(result.all ?? result.stderr ?? \"\")) } : {}),\n truncated: countSecretlintMessages(rawOutput) > findings.length\n };\n}\n\nfunction safeJson(rawJson: string): unknown {\n try {\n return JSON.parse(rawJson || \"[]\");\n } catch {\n return [];\n }\n}\n\nfunction stringValue(value: unknown) {\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction numberValue(value: unknown) {\n return typeof value === \"number\" ? value : undefined;\n}\n\nfunction countJsonArray(rawJson: string) {\n const parsed = safeJson(rawJson);\n return Array.isArray(parsed) ? parsed.length : 0;\n}\n\nfunction countSecretlintMessages(rawJson: string) {\n const parsed = safeJson(rawJson);\n\n if (!Array.isArray(parsed)) {\n return 0;\n }\n\n return parsed.reduce((count, fileResult) => {\n return count + (Array.isArray(fileResult.messages) ? fileResult.messages.length : 0);\n }, 0);\n}\n\nfunction trimError(output: string) {\n const trimmed = output.trim();\n return trimmed.length > ERROR_LIMIT ? `${trimmed.slice(0, ERROR_LIMIT)}\\n[truncated]` : trimmed;\n}\n","import { performance } from \"node:perf_hooks\";\n\nimport { execa } from \"execa\";\n\nimport type { PackageInfo, VerificationReport, VerificationResult, VerificationScript } from \"../types.js\";\nimport { detectPackageInfo } from \"./package-json.js\";\n\nconst VERIFY_ORDER = [\"typecheck\", \"lint\", \"test\", \"build\"];\nconst OUTPUT_LIMIT = 4000;\n\nexport function selectVerificationScripts(packageInfo: PackageInfo | undefined): VerificationScript[] {\n if (!packageInfo) {\n return [];\n }\n\n return VERIFY_ORDER.flatMap((name) => packageInfo.verificationScripts.filter((script) => script.name === name));\n}\n\nexport async function runVerification(root: string): Promise<VerificationReport> {\n const packageInfo = await detectPackageInfo(root);\n const scripts = selectVerificationScripts(packageInfo);\n const commands: VerificationResult[] = [];\n\n for (const script of scripts) {\n commands.push(await runScript(root, packageInfo?.packageManager ?? \"npm\", script));\n }\n\n return { commands };\n}\n\nasync function runScript(root: string, packageManager: string, script: VerificationScript): Promise<VerificationResult> {\n const started = performance.now();\n const command = `${packageManager} run ${script.name}`;\n const result = await execa(packageManager, [\"run\", script.name], {\n cwd: root,\n reject: false,\n all: true\n });\n\n return {\n name: script.name,\n command,\n exitCode: result.exitCode ?? 1,\n durationMs: Math.round(performance.now() - started),\n output: trimOutput(result.all ?? result.stdout ?? result.stderr ?? \"\")\n };\n}\n\nfunction trimOutput(output: string) {\n const normalized = output.trim();\n return normalized.length > OUTPUT_LIMIT ? `${normalized.slice(-OUTPUT_LIMIT)}\\n[trimmed]` : normalized;\n}\n","import type { HandoffReport, PackOptions } from \"../types.js\";\nimport { collectGitInfo, findGitRoot } from \"./git.js\";\nimport { detectInstructionFiles } from \"./instructions.js\";\nimport { detectPackageInfo } from \"./package-json.js\";\nimport { analyzeRisk } from \"./risk.js\";\nimport { detectSecretScanners, runSecretScanners } from \"./scanners.js\";\nimport { runVerification } from \"./verify.js\";\n\nexport async function collectHandoffReport(options: PackOptions): Promise<HandoffReport> {\n const root = await findGitRoot(options.cwd);\n const [repository, instructionFiles, packageInfo, secretScanning] = await Promise.all([\n collectGitInfo(root, {\n includeDiff: options.includeDiff && options.includeDiffSummary,\n includeDiffSummary: options.includeDiffSummary,\n ...(options.since ? { since: options.since } : {})\n }),\n detectInstructionFiles(root),\n detectPackageInfo(root),\n options.scanSecrets ? runSecretScanners(root) : detectSecretScanners()\n ]);\n\n const report: HandoffReport = {\n goal: options.goal,\n target: options.target,\n repository,\n instructionFiles,\n ...(packageInfo ? { packageInfo } : {}),\n ...(options.resumeSource ? { resumeSource: options.resumeSource } : {}),\n ...(options.includeVerification ? { verification: await runVerification(root) } : {}),\n secretScanning,\n budget: {\n requestedTokens: options.budget,\n estimatedTokens: 0,\n wasTrimmed: false\n }\n };\n\n report.risk = analyzeRisk(report);\n return report;\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport { applyMarkdownBudget, estimateTokens } from \"../core/budget.js\";\nimport { redactText } from \"../core/redact.js\";\nimport { renderJsonReport } from \"../report/json.js\";\nimport { renderMarkdownReport } from \"../report/markdown.js\";\nimport type { HandoffReport, OutputFormat } from \"../types.js\";\n\nexport async function writeRenderedReport(report: HandoffReport, format: OutputFormat, budget: number, output?: string) {\n const rendered = redactText(renderOutput(report, format, budget));\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, rendered, \"utf8\");\n process.stderr.write(`Wrote handoff packet to ${outputPath}\\n`);\n return;\n }\n\n process.stdout.write(rendered);\n}\n\nfunction renderOutput(report: HandoffReport, format: OutputFormat, budget: number) {\n if (format === \"json\") {\n const rendered = renderJsonReport(report);\n report.budget.estimatedTokens = estimateTokens(rendered);\n return renderJsonReport(report);\n }\n\n const firstRender = renderMarkdownReport(report);\n const budgeted = applyMarkdownBudget(firstRender, budget);\n report.budget.estimatedTokens = budgeted.estimatedTokens;\n report.budget.wasTrimmed = budgeted.wasTrimmed;\n\n if (budgeted.wasTrimmed) {\n return budgeted.text;\n }\n\n return renderMarkdownReport(report);\n}\n","export function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\nexport function applyMarkdownBudget(text: string, budget: number) {\n const estimatedTokens = estimateTokens(text);\n\n if (estimatedTokens <= budget) {\n return { text, estimatedTokens, wasTrimmed: false };\n }\n\n const notice = `\\n\\n> Output trimmed to fit --budget ${budget}. Re-run with a larger budget or --output for the full packet.\\n`;\n const charLimit = Math.max(0, budget * 4 - notice.length);\n const trimmed = `${text.slice(0, charLimit).trimEnd()}${notice}`;\n\n return {\n text: trimmed,\n estimatedTokens: estimateTokens(trimmed),\n wasTrimmed: true\n };\n}\n","import type { HandoffReport } from \"../types.js\";\n\nexport function renderJsonReport(report: HandoffReport): string {\n return `${JSON.stringify(report, null, 2)}\\n`;\n}\n","import type { HandoffReport, PackageInfo, ResumeItem, ResumeState } from \"../types.js\";\n\nexport function renderMarkdownReport(report: HandoffReport): string {\n const lines: string[] = [\n `# ${titleForTarget(report.target)}`,\n \"\",\n \"## Goal\",\n report.goal,\n \"\",\n \"## Repository\",\n `- Repository: \\`${report.repository.name}\\``,\n `- Branch: \\`${report.repository.branch}\\``,\n `- Changed files: ${report.repository.changedFiles.length}`,\n \"\",\n \"## Git Status\",\n codeBlock(report.repository.status || \"Clean working tree.\"),\n \"\",\n \"## Recent Commits\",\n listOrNone(report.repository.recentCommits.map((commit) => `- ${commit}`)),\n \"\",\n \"## Changed Files\",\n listOrNone(report.repository.changedFiles.map((file) => `- \\`${file}\\``)),\n \"\",\n ...renderBaseDiffSummary(report),\n \"## Diff Summary\",\n \"### Staged\",\n codeBlock(report.repository.stagedDiffSummary || \"No staged diff.\"),\n \"\",\n \"### Unstaged\",\n codeBlock(report.repository.unstagedDiffSummary || \"No unstaged diff.\"),\n \"\",\n \"## Instruction Files\",\n renderInstructionFiles(report.instructionFiles),\n \"\",\n \"## Package\",\n renderPackage(report.packageInfo),\n \"\",\n ...renderResumeSource(report),\n ...renderVerification(report),\n ...renderRisk(report),\n ...renderSecretScanning(report),\n \"## Next Agent Notes\",\n \"- This packet was generated from local git and filesystem state.\",\n \"- Likely secrets were redacted from generated output.\",\n \"- No LLM APIs were called.\"\n ];\n\n if (report.repository.includeDiff && report.repository.diff) {\n lines.splice(\n lines.indexOf(\"## Instruction Files\"),\n 0,\n \"## Included Diff\",\n \"### Staged Patch\",\n codeBlock(report.repository.diff.staged || \"No staged patch.\"),\n \"\",\n \"### Unstaged Patch\",\n codeBlock(report.repository.diff.unstaged || \"No unstaged patch.\"),\n \"\"\n );\n }\n\n if (report.repository.includeDiff && report.repository.baseDiff) {\n lines.splice(\n lines.indexOf(\"## Included Diff\"),\n 0,\n `## Included Branch Delta Since \\`${report.repository.baseRef}\\``,\n codeBlock(report.repository.baseDiff),\n \"\"\n );\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction titleForTarget(target = \"generic\") {\n const labels: Record<string, string> = {\n generic: \"Handoff Packet\",\n codex: \"Codex Handoff Packet\",\n claude: \"Claude Handoff Packet\",\n cursor: \"Cursor Handoff Packet\"\n };\n\n return labels[target] ?? \"Handoff Packet\";\n}\n\nfunction renderBaseDiffSummary(report: HandoffReport) {\n if (!report.repository.baseRef) {\n return [];\n }\n\n return [\n `## Branch Delta Since \\`${report.repository.baseRef}\\``,\n codeBlock(report.repository.baseDiffSummary || \"No committed branch delta detected.\"),\n \"\"\n ];\n}\n\nfunction renderPackage(packageInfo: PackageInfo | undefined) {\n if (!packageInfo) {\n return \"No package.json detected.\";\n }\n\n const lines = [\n packageInfo.name ? `- Package: \\`${packageInfo.name}\\`` : undefined,\n packageInfo.packageManager ? `- Package manager: \\`${packageInfo.packageManager}\\`` : undefined\n ].filter((line): line is string => Boolean(line));\n\n if (packageInfo.verificationScripts.length > 0) {\n const prefix = packageInfo.packageManager ?? \"npm\";\n lines.push(\"- Verification scripts:\");\n lines.push(...packageInfo.verificationScripts.map((script) => ` - \\`${prefix} ${script.name}\\``));\n } else {\n lines.push(\"- Verification scripts: none detected.\");\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction renderInstructionFiles(instructionFiles: HandoffReport[\"instructionFiles\"]) {\n if (instructionFiles.length === 0) {\n return \"None detected.\";\n }\n\n return instructionFiles\n .map((file) => [`- \\`${file.path}\\` (${file.kind})`, codeBlock(file.preview || \"No preview available.\")].join(\"\\n\"))\n .join(\"\\n\\n\");\n}\n\nfunction renderResumeSource(report: HandoffReport) {\n if (!report.resumeSource) {\n return [];\n }\n\n return [\n \"## Resume Source\",\n `- Source: \\`${report.resumeSource.path}\\``,\n codeBlock(report.resumeSource.preview),\n \"\",\n ...renderResumeState(report.resumeSource.state)\n ];\n}\n\nfunction renderResumeState(state: ResumeState | undefined) {\n if (!state) {\n return [];\n }\n\n return [\n \"## Resume State\",\n renderResumeItems(\"Completed\", state.completed),\n renderResumeItems(\"Remaining\", state.remaining),\n renderResumeItems(\"Failed Commands\", state.failedCommands),\n renderResumeItems(\"Open Questions\", state.openQuestions),\n renderResumeItems(\"Verification\", state.verification),\n state.nextSafestAction ? `- Next safest action: ${state.nextSafestAction}` : \"- Next safest action: none detected.\",\n \"\"\n ];\n}\n\nfunction renderResumeItems(title: string, items: ResumeItem[]) {\n return [`### ${title}`, listOrNone(items.map((item) => `- ${item.text}`))].join(\"\\n\");\n}\n\nfunction renderVerification(report: HandoffReport) {\n if (!report.verification) {\n return [];\n }\n\n return [\n \"## Verification\",\n report.verification.commands.length > 0\n ? report.verification.commands\n .map((command) =>\n [`- \\`${command.command}\\` exited ${command.exitCode} in ${command.durationMs}ms`, codeBlock(command.output || \"No output.\")]\n .join(\"\\n\")\n )\n .join(\"\\n\\n\")\n : \"No safe verification scripts detected.\",\n \"\"\n ];\n}\n\nfunction renderRisk(report: HandoffReport) {\n if (!report.risk) {\n return [];\n }\n\n return [\n \"## Risk Notes\",\n report.risk.notes.map((note) => `- **${note.severity}**: ${note.title} - ${note.detail}`).join(\"\\n\"),\n \"\"\n ];\n}\n\nfunction renderSecretScanning(report: HandoffReport) {\n if (!report.secretScanning) {\n return [];\n }\n\n return [\n report.secretScanning.scans ? \"## Secret Scan Results\" : \"## Secret Scanner Availability\",\n renderSecretScannerReport(report.secretScanning),\n \"\"\n ];\n}\n\nfunction renderSecretScannerReport(secretScanning: NonNullable<HandoffReport[\"secretScanning\"]>) {\n if (!secretScanning.scans) {\n return secretScanning.scanners.map((scanner) => `- ${scanner.name}: ${scanner.available ? \"available\" : \"not found\"}`).join(\"\\n\");\n }\n\n return secretScanning.scans\n .map((scan) => {\n const lines = [\n `- ${scan.name}: ${scan.ran ? `${scan.findings.length} finding(s), exit ${scan.exitCode}` : scan.error ?? \"not run\"}`\n ];\n\n for (const finding of scan.findings) {\n lines.push(` - ${finding.ruleId ? `${finding.ruleId}: ` : \"\"}${finding.message}${finding.file ? ` (${finding.file}${finding.line ? `:${finding.line}` : \"\"})` : \"\"}`);\n }\n\n if (scan.truncated) {\n lines.push(\" - Additional findings were truncated.\");\n }\n\n return lines.join(\"\\n\");\n })\n .join(\"\\n\");\n}\n\nfunction codeBlock(text: string) {\n return [\"```text\", text, \"```\"].join(\"\\n\");\n}\n\nfunction listOrNone(items: string[]) {\n return items.length > 0 ? items.join(\"\\n\") : \"None detected.\";\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { collectHandoffReport } from \"../../core/collect.js\";\nimport { createResumeSource } from \"../../core/resume.js\";\nimport { writeRenderedReport } from \"../output.js\";\n\nconst ResumeOptionsSchema = z.object({\n goal: z.string().trim().min(1).default(\"Resume interrupted AI coding session\"),\n output: z.string().optional(),\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\"),\n for: z.enum([\"generic\", \"codex\", \"claude\", \"cursor\"]).default(\"generic\"),\n budget: z.number().int().positive().default(4000)\n});\n\nexport function createResumeCommand() {\n return new Command(\"resume\")\n .description(\"Create a fresh handoff packet using a previous handoff as resume context.\")\n .summary(\"Merge a previous handoff or transcript with fresh repo state.\")\n .argument(\"<path>\", \"previous handoff or transcript file\")\n .option(\"--goal <text>\", \"new handoff goal\", \"Resume interrupted AI coding session\")\n .option(\"--output <path>\", \"write output to a file instead of stdout\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .option(\"--for <agent>\", \"target output: generic, codex, claude, or cursor\", \"generic\")\n .option(\"--budget <tokens>\", \"rough output token budget\", parseBudget, 4000)\n .action(async (path: string, rawOptions) => {\n const options = ResumeOptionsSchema.parse(rawOptions);\n const source = createResumeSource(path, await readFile(path, \"utf8\"));\n const report = await collectHandoffReport({\n goal: options.goal,\n cwd: process.cwd(),\n ...(options.output ? { output: options.output } : {}),\n format: options.format,\n target: options.for,\n budget: options.budget,\n includeDiff: false,\n includeDiffSummary: true,\n includeVerification: false,\n scanSecrets: false,\n resumeSource: source\n });\n\n await writeRenderedReport(report, options.format, options.budget, options.output);\n });\n}\n\nfunction parseBudget(value: string) {\n const parsed = Number.parseInt(value, 10);\n\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new Error(\"--budget must be a positive integer.\");\n }\n\n return parsed;\n}\n","import type { ResumeSource, ResumeState } from \"../types.js\";\nimport { redactText } from \"./redact.js\";\n\nconst RESUME_PREVIEW_LIMIT = 3000;\nconst SECTION_ALIASES = {\n completed: [/^completed$/i, /^done$/i, /^done this session$/i, /^what changed$/i, /^implemented$/i],\n remaining: [/^remaining$/i, /^next steps$/i, /^todo$/i, /^to do$/i],\n failedCommands: [/^failed commands$/i, /^failures$/i, /^errors$/i],\n openQuestions: [/^open questions$/i, /^open questions \\/ risks$/i, /^open questions and risks$/i, /^questions$/i, /^blockers$/i],\n verification: [/^verification$/i, /^tests$/i, /^validation$/i]\n} as const;\n\ntype ResumeSection = keyof typeof SECTION_ALIASES;\n\nexport function createResumeSource(path: string, content: string): ResumeSource {\n const normalized = content.replace(/\\r\\n/g, \"\\n\").trim();\n const preview =\n normalized.length > RESUME_PREVIEW_LIMIT ? `${normalized.slice(0, RESUME_PREVIEW_LIMIT).trimEnd()}\\n[truncated]` : normalized;\n const state = parseResumeState(normalized);\n\n return {\n path,\n preview: redactText(preview),\n ...(hasResumeState(state) ? { state } : {})\n };\n}\n\nexport function parseResumeState(content: string): ResumeState {\n const state: ResumeState = {\n completed: [],\n remaining: [],\n failedCommands: [],\n openQuestions: [],\n verification: []\n };\n let section: ResumeSection | undefined;\n let heading: string | undefined;\n\n for (const rawLine of content.replace(/\\r\\n/g, \"\\n\").split(\"\\n\")) {\n const line = rawLine.trim();\n const headingMatch = line.match(/^#{1,4}\\s+(.+)$/);\n\n if (headingMatch) {\n const headingText = headingMatch[1];\n if (!headingText) {\n continue;\n }\n\n heading = headingText.trim();\n section = sectionForHeading(heading);\n continue;\n }\n\n if (!section) {\n continue;\n }\n\n const item = normalizeListItem(line);\n if (item) {\n state[section].push({ text: redactText(item), ...(heading ? { sourceHeading: redactText(heading) } : {}) });\n }\n }\n\n const next = state.remaining[0] ?? state.openQuestions[0] ?? state.failedCommands[0];\n if (next) {\n state.nextSafestAction = next.text;\n }\n\n return state;\n}\n\nfunction sectionForHeading(heading: string): ResumeSection | undefined {\n const normalized = normalizeHeading(heading);\n\n for (const [section, patterns] of Object.entries(SECTION_ALIASES)) {\n if (patterns.some((pattern) => pattern.test(normalized))) {\n return section as ResumeSection;\n }\n }\n\n return undefined;\n}\n\nfunction normalizeListItem(line: string) {\n const match = line.match(/^[-*]\\s+(.+)$/) ?? line.match(/^\\d+\\.\\s+(.+)$/);\n return match?.[1]?.trim();\n}\n\nfunction normalizeHeading(heading: string) {\n return heading.trim().replace(/:$/, \"\").replace(/\\s*\\/\\s*/g, \" / \").replace(/\\s+/g, \" \");\n}\n\nfunction hasResumeState(state: ResumeState) {\n return (\n state.completed.length > 0 ||\n state.remaining.length > 0 ||\n state.failedCommands.length > 0 ||\n state.openQuestions.length > 0 ||\n state.verification.length > 0\n );\n}\n","import { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { collectHandoffReport } from \"../../core/collect.js\";\n\nconst RiskOptionsSchema = z.object({\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\")\n});\n\nexport function createRiskCommand() {\n return new Command(\"risk\")\n .description(\"Show deterministic risk notes for the current handoff.\")\n .summary(\"Show deterministic risk notes from changed files.\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .action(async (rawOptions) => {\n const options = RiskOptionsSchema.parse(rawOptions);\n const report = await collectHandoffReport({\n goal: \"Review local risk\",\n cwd: process.cwd(),\n format: options.format,\n target: \"generic\",\n budget: 4000,\n includeDiff: false,\n includeDiffSummary: false,\n includeVerification: false,\n scanSecrets: false\n });\n\n if (options.format === \"json\") {\n process.stdout.write(`${JSON.stringify(report.risk, null, 2)}\\n`);\n return;\n }\n\n process.stdout.write(`# Risk Notes\\n\\n${report.risk?.notes.map((note) => `- **${note.severity}**: ${note.title} - ${note.detail}`).join(\"\\n\")}\\n`);\n });\n}\n","import { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { findGitRoot } from \"../../core/git.js\";\nimport { redactText } from \"../../core/redact.js\";\nimport { runSecretScanners } from \"../../core/scanners.js\";\n\nconst ScanSecretsOptionsSchema = z.object({\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\")\n});\n\nexport function createScanSecretsCommand() {\n return new Command(\"scan-secrets\")\n .description(\"Run optional local secret scanners and print bounded redacted results.\")\n .summary(\"Run optional local secret scanners.\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .action(async (rawOptions) => {\n const options = ScanSecretsOptionsSchema.parse(rawOptions);\n const root = await findGitRoot(process.cwd());\n const report = await runSecretScanners(root);\n\n if (options.format === \"json\") {\n process.stdout.write(redactText(`${JSON.stringify(report, null, 2)}\\n`));\n return;\n }\n\n process.stdout.write(redactText(renderScanMarkdown(report)));\n });\n}\n\nfunction renderScanMarkdown(report: Awaited<ReturnType<typeof runSecretScanners>>) {\n const lines = [\"# Secret Scan Results\", \"\"];\n\n for (const scan of report.scans ?? []) {\n lines.push(`- ${scan.name}: ${scan.ran ? `${scan.findings.length} finding(s), exit ${scan.exitCode}` : scan.error ?? \"not run\"}`);\n\n for (const finding of scan.findings) {\n lines.push(` - ${finding.ruleId ? `${finding.ruleId}: ` : \"\"}${finding.message}${finding.file ? ` (${finding.file}${finding.line ? `:${finding.line}` : \"\"})` : \"\"}`);\n }\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n","import { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { findGitRoot } from \"../../core/git.js\";\nimport { redactText } from \"../../core/redact.js\";\nimport { runVerification } from \"../../core/verify.js\";\nimport type { VerificationResult } from \"../../types.js\";\n\nconst VerifyOptionsSchema = z.object({\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\")\n});\n\nexport function createVerifyCommand() {\n return new Command(\"verify\")\n .description(\"Run safe local verification scripts.\")\n .summary(\"Run safe detected verification scripts.\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .action(async (rawOptions) => {\n const options = VerifyOptionsSchema.parse(rawOptions);\n const root = await findGitRoot(process.cwd());\n const verification = await runVerification(root);\n\n if (options.format === \"json\") {\n process.stdout.write(redactText(`${JSON.stringify(verification, null, 2)}\\n`));\n return;\n }\n\n process.stdout.write(redactText(renderVerificationMarkdown(verification.commands)));\n });\n}\n\nfunction renderVerificationMarkdown(commands: VerificationResult[]) {\n const lines = [\"# Verification\", \"\"];\n\n if (commands.length === 0) {\n lines.push(\"No safe verification scripts detected.\");\n } else {\n for (const command of commands) {\n lines.push(`- \\`${command.command}\\` exited ${command.exitCode} in ${command.durationMs}ms`);\n }\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n"],"mappings":"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","names":["Command","z","readFile","readFile","readFile","readFile","join","execa","execa","join","readFile","performance","execa","performance","execa","z","readFile","Command","z","z","Command","parseBudget","readFile","Command","z","z","Command","Command","z","z","Command","Command","z","z","Command","Command"]}
1
+ {"version":3,"sources":["../src/cli/index.ts","../src/cli/commands/pack.ts","../src/core/git.ts","../src/cli/errors.ts","../src/core/instructions.ts","../src/core/redact.ts","../src/core/package-json.ts","../src/core/risk.ts","../src/core/scanners.ts","../src/core/verify.ts","../src/core/collect.ts","../src/cli/output.ts","../src/core/budget.ts","../src/report/json.ts","../src/report/profiles.ts","../src/report/markdown.ts","../src/cli/commands/resume.ts","../src/core/resume.ts","../src/cli/commands/risk.ts","../src/cli/commands/scan-secrets.ts","../src/cli/commands/verify.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\n\nimport { createPackCommand } from \"./commands/pack.js\";\nimport { createResumeCommand } from \"./commands/resume.js\";\nimport { createRiskCommand } from \"./commands/risk.js\";\nimport { createScanSecretsCommand } from \"./commands/scan-secrets.js\";\nimport { createVerifyCommand } from \"./commands/verify.js\";\nimport { formatCliError } from \"./errors.js\";\n\nconst program = new Command()\n .name(\"handoffkit\")\n .description(\"Create safe local handoff packets for AI-assisted coding sessions.\")\n .summary(\"Create local-first AI coding session handoff packets.\")\n .showHelpAfterError(\"(run with --help for usage)\")\n .version(\"0.2.0\");\n\nprogram.addCommand(createPackCommand());\nprogram.addCommand(createVerifyCommand());\nprogram.addCommand(createRiskCommand());\nprogram.addCommand(createScanSecretsCommand());\nprogram.addCommand(createResumeCommand());\n\ntry {\n await program.parseAsync(process.argv);\n} catch (error) {\n process.stderr.write(`${formatCliError(error)}\\n`);\n process.exitCode = 1;\n}\n","import { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { collectHandoffReport } from \"../../core/collect.js\";\nimport { writeRenderedReport } from \"../output.js\";\n\nconst PackCliOptionsSchema = z.object({\n goal: z.string().trim().min(1).default(\"Make your own goal\"),\n output: z.string().optional(),\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\"),\n for: z.enum([\"generic\", \"codex\", \"claude\", \"cursor\"]).default(\"generic\"),\n budget: z.number().int().positive().default(4000),\n includeDiff: z.boolean().default(false),\n diff: z.boolean().default(true),\n since: z.string().trim().min(1).optional(),\n verify: z.boolean().default(false),\n scanSecrets: z.boolean().default(false)\n});\n\nexport function createPackCommand() {\n return new Command(\"pack\")\n .description(\"Create a safe local handoff packet for another AI assistant.\")\n .summary(\"Create a Markdown or JSON packet from the current git state.\")\n .option(\"--goal <text>\", \"handoff goal\", \"Make your own goal\")\n .option(\"--output <path>\", \"write output to a file instead of stdout\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .option(\"--for <agent>\", \"target output: generic, codex, claude, or cursor\", \"generic\")\n .option(\"--budget <tokens>\", \"rough output token budget\", parseBudget, 4000)\n .option(\"--since <ref>\", \"focus committed branch delta on a base ref\")\n .option(\"--verify\", \"run safe verification scripts and include results\")\n .option(\"--scan-secrets\", \"run optional local secret scanners and include bounded results\")\n .option(\"--include-diff\", \"include full staged and unstaged patches\", false)\n .option(\"--no-diff\", \"omit diff summaries and full patches\")\n .action(async (rawOptions) => {\n const options = parseOptions(rawOptions);\n const report = await collectHandoffReport({\n goal: options.goal,\n cwd: process.cwd(),\n ...(options.output ? { output: options.output } : {}),\n format: options.format,\n target: options.for,\n budget: options.budget,\n includeDiff: options.includeDiff,\n includeDiffSummary: options.diff,\n ...(options.since ? { since: options.since } : {}),\n includeVerification: options.verify,\n scanSecrets: options.scanSecrets\n });\n\n await writeRenderedReport(report, options.format, options.budget, options.output);\n });\n}\n\nfunction parseOptions(rawOptions: unknown) {\n const result = PackCliOptionsSchema.safeParse(rawOptions);\n\n if (!result.success) {\n const message = result.error.issues.map((issue) => issue.message).join(\"\\n\");\n throw new Error(`Invalid pack options:\\n${message}`);\n }\n\n return result.data;\n}\n\nfunction parseBudget(value: string) {\n const parsed = Number.parseInt(value, 10);\n\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new Error(\"--budget must be a positive integer.\");\n }\n\n return parsed;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\n\nimport { execa } from \"execa\";\n\nimport { HandoffKitCliError } from \"../cli/errors.js\";\nimport type { DiffInfo, RepositoryInfo } from \"../types.js\";\n\nconst UNTRACKED_PATCH_CHAR_LIMIT = 20_000;\nconst IGNORED_CHANGED_PATH_PREFIXES = [\"node_modules/\", \"dist/\", \"coverage/\", \".git/\"];\n\nexport interface GitCollectOptions {\n includeDiff: boolean;\n includeDiffSummary: boolean;\n since?: string;\n}\n\nexport async function findGitRoot(cwd: string): Promise<string> {\n const result = await execa(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n cwd,\n reject: false\n });\n\n if (result.exitCode !== 0) {\n throw new HandoffKitCliError([\n \"HandoffKit must be run inside a git repository.\",\n \"Run this command from a git checkout, or initialize one with `git init`.\"\n ].join(\"\\n\"));\n }\n\n return result.stdout.trimEnd();\n}\n\nexport async function collectGitInfo(root: string, options: GitCollectOptions): Promise<RepositoryInfo> {\n const [branch, status, porcelainStatus, recentCommits, stagedDiffSummary, trackedUnstagedDiffSummary, baseInfo] =\n await Promise.all([\n currentBranch(root),\n git(root, [\"status\", \"--short\", \"--branch\"]),\n git(root, [\"status\", \"--porcelain=v1\", \"--untracked-files=all\"]),\n recentCommitLines(root, options.since),\n options.includeDiffSummary ? git(root, [\"diff\", \"--cached\", \"--stat\"]) : Promise.resolve(\"\"),\n options.includeDiffSummary ? git(root, [\"diff\", \"--stat\"]) : Promise.resolve(\"\"),\n options.since ? collectBaseInfo(root, options.since, options.includeDiffSummary, options.includeDiff) : Promise.resolve(undefined)\n ]);\n\n const changedFiles = uniqueSorted([...(baseInfo?.changedFiles ?? []), ...parseChangedFiles(porcelainStatus)]);\n const untrackedFiles = parseUntrackedFiles(porcelainStatus);\n const unstagedDiffSummary = options.includeDiffSummary\n ? joinSections([trackedUnstagedDiffSummary, renderUntrackedSummary(untrackedFiles)])\n : \"\";\n const diff = options.includeDiff ? await collectDiff(root, untrackedFiles) : undefined;\n\n return {\n name: basename(root),\n branch,\n ...(options.since ? { baseRef: options.since } : {}),\n status,\n recentCommits,\n changedFiles,\n ...(baseInfo?.summary ? { baseDiffSummary: baseInfo.summary } : {}),\n stagedDiffSummary,\n unstagedDiffSummary,\n includeDiff: options.includeDiff,\n ...(baseInfo?.patch ? { baseDiff: baseInfo.patch } : {}),\n ...(diff ? { diff } : {})\n };\n}\n\nasync function currentBranch(root: string) {\n const branch = await git(root, [\"branch\", \"--show-current\"]);\n\n if (branch) {\n return branch;\n }\n\n const commit = await git(root, [\"rev-parse\", \"--short\", \"HEAD\"], { allowFailure: true });\n return commit ? `detached:${commit}` : \"unknown\";\n}\n\nasync function recentCommitLines(root: string, since?: string) {\n const args = since ? [\"log\", \"--oneline\", \"-n\", \"10\", `${since}..HEAD`] : [\"log\", \"--oneline\", \"-n\", \"10\"];\n const output = await git(root, args, { allowFailure: true });\n return output ? output.split(\"\\n\") : [];\n}\n\nasync function collectBaseInfo(root: string, since: string, includeDiffSummary: boolean, includeDiff: boolean) {\n await ensureRef(root, since);\n const range = `${since}...HEAD`;\n const [changedFiles, summary, patch] = await Promise.all([\n git(root, [\"diff\", \"--name-only\", range], { allowFailure: true }),\n includeDiffSummary ? git(root, [\"diff\", \"--stat\", range], { allowFailure: true }) : Promise.resolve(\"\"),\n includeDiff ? git(root, [\"diff\", \"--patch\", range], { allowFailure: true }) : Promise.resolve(\"\")\n ]);\n\n return {\n changedFiles: changedFiles ? changedFiles.split(\"\\n\").filter(Boolean) : [],\n summary,\n patch\n };\n}\n\nasync function ensureRef(root: string, ref: string) {\n const result = await execa(\"git\", [\"rev-parse\", \"--verify\", `${ref}^{commit}`], {\n cwd: root,\n reject: false\n });\n\n if (result.exitCode !== 0) {\n throw new Error(`Could not resolve --since ref: ${ref}`);\n }\n}\n\nasync function collectDiff(root: string, untrackedFiles: string[]): Promise<DiffInfo> {\n const [staged, unstagedTracked, untracked] = await Promise.all([\n git(root, [\"diff\", \"--cached\", \"--patch\"]),\n git(root, [\"diff\", \"--patch\"]),\n untrackedPatch(root, untrackedFiles)\n ]);\n\n return { staged, unstaged: joinSections([unstagedTracked, untracked]) };\n}\n\nasync function git(root: string, args: string[], options: { allowFailure?: boolean } = {}) {\n const result = await execa(\"git\", args, {\n cwd: root,\n reject: false\n });\n\n if (result.exitCode !== 0 && !options.allowFailure) {\n throw new Error(result.stderr || `git ${args.join(\" \")} failed`);\n }\n\n return result.stdout.trim();\n}\n\nfunction parseChangedFiles(status: string) {\n const files = status\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .filter(Boolean)\n .map((line) => line.slice(line[2] === \" \" ? 3 : 2).trim())\n .map((path) => (path.includes(\" -> \") ? path.split(\" -> \").at(-1) ?? path : path))\n .map((path) => path.replace(/^\"|\"$/g, \"\"));\n\n return uniqueSorted(files.filter((file) => !isIgnoredChangedPath(file)));\n}\n\nfunction parseUntrackedFiles(status: string) {\n return status\n .split(\"\\n\")\n .map((line) => line.trimEnd())\n .filter((line) => line.startsWith(\"?? \"))\n .map((line) => line.slice(3).trim())\n .map((path) => path.replace(/^\"|\"$/g, \"\"))\n .filter((file) => !isIgnoredChangedPath(file))\n .sort();\n}\n\nfunction renderUntrackedSummary(files: string[]) {\n if (files.length === 0) {\n return \"\";\n }\n\n return files.map((file) => `${file} | untracked`).join(\"\\n\");\n}\n\nasync function untrackedPatch(root: string, files: string[]) {\n const patches = await Promise.all(\n files.map(async (file) => {\n const content = await readFile(`${root}/${file}`, \"utf8\");\n const trimmedContent =\n content.length > UNTRACKED_PATCH_CHAR_LIMIT\n ? `${content.slice(0, UNTRACKED_PATCH_CHAR_LIMIT).trimEnd()}\\n[truncated]`\n : content.trimEnd();\n\n return [`Untracked file: ${file}`, \"```text\", trimmedContent, \"```\"].join(\"\\n\");\n })\n );\n\n return patches.join(\"\\n\\n\");\n}\n\nfunction joinSections(sections: string[]) {\n return sections.filter(Boolean).join(\"\\n\\n\").trim();\n}\n\nfunction uniqueSorted(files: string[]) {\n return [...new Set(files.filter((file) => !isIgnoredChangedPath(file)))].sort();\n}\n\nfunction isIgnoredChangedPath(file: string) {\n return IGNORED_CHANGED_PATH_PREFIXES.some((prefix) => file === prefix.slice(0, -1) || file.startsWith(prefix));\n}\n","export class HandoffKitCliError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"HandoffKitCliError\";\n }\n}\n\nexport function formatCliError(error: unknown) {\n const message = error instanceof Error ? error.message : String(error);\n return message.trim();\n}\n","import { readFile, stat } from \"node:fs/promises\";\n\nimport fg from \"fast-glob\";\n\nimport type { InstructionFile } from \"../types.js\";\nimport { redactText } from \"./redact.js\";\n\nconst INSTRUCTION_PATTERNS = [\n \"**/AGENTS.md\",\n \"**/CLAUDE.md\",\n \"**/GEMINI.md\",\n \".cursor/rules\",\n \".cursor/rules/**/*\",\n \".github/copilot-instructions.md\"\n];\n\nconst PREVIEW_CHAR_LIMIT = 1200;\n\nexport async function detectInstructionFiles(root: string): Promise<InstructionFile[]> {\n const paths = await fg(INSTRUCTION_PATTERNS, {\n cwd: root,\n dot: true,\n onlyFiles: false,\n unique: true,\n ignore: [\"**/.git/**\", \"**/node_modules/**\", \"**/dist/**\", \"**/coverage/**\"]\n });\n\n return Promise.all(paths.sort().map((path) => instructionFile(root, path)));\n}\n\nasync function instructionFile(root: string, path: string): Promise<InstructionFile> {\n return {\n path,\n kind: instructionKind(path),\n preview: await readPreview(root, path)\n };\n}\n\nasync function readPreview(root: string, path: string) {\n const fullPath = `${root}/${path}`;\n const metadata = await stat(fullPath);\n\n if (!metadata.isFile()) {\n return \"Directory rule set detected.\";\n }\n\n const content = await readFile(fullPath, \"utf8\");\n const normalized = content.replace(/\\r\\n/g, \"\\n\").trim();\n const preview =\n normalized.length > PREVIEW_CHAR_LIMIT ? `${normalized.slice(0, PREVIEW_CHAR_LIMIT).trimEnd()}\\n[truncated]` : normalized;\n\n return redactText(preview);\n}\n\nfunction instructionKind(path: string): InstructionFile[\"kind\"] {\n if (path.endsWith(\"AGENTS.md\")) {\n return \"agents\";\n }\n\n if (path.endsWith(\"CLAUDE.md\")) {\n return \"claude\";\n }\n\n if (path.endsWith(\"GEMINI.md\")) {\n return \"gemini\";\n }\n\n if (path === \".cursor/rules\" || path.startsWith(\".cursor/rules/\")) {\n return \"cursor\";\n }\n\n if (path === \".github/copilot-instructions.md\") {\n return \"copilot\";\n }\n\n return \"instruction\";\n}\n","const REDACTION = \"[REDACTED]\";\n\nconst SECRET_KEY_PATTERN =\n /(\\b(?:[A-Z0-9]+[_.-])*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PASSWD|PRIVATE[_-]?KEY|CLIENT[_-]?SECRET|ACCESS[_-]?TOKEN|REFRESH[_-]?TOKEN|COOKIE|SESSION|JWT|AUTH_TOKEN)(?:[_.-][A-Z0-9]+)*\\b\\s*(?:=|:)\\s*)([\"']?)([^\\s\"',}]+)/gi;\n\nconst TOKEN_PATTERNS: RegExp[] = [\n /\\bBearer\\s+[A-Za-z0-9._~+/=-]{12,}/gi,\n /\\bsk-[A-Za-z0-9_-]{16,}/g,\n /\\bgh[pousr]_[A-Za-z0-9_]{16,}/g,\n /\\bnpm_[A-Za-z0-9_-]{16,}/g,\n /\\bxox[baprs]-[A-Za-z0-9-]{16,}/g,\n /\\bAIza[0-9A-Za-z_-]{20,}/g,\n /\\bAKIA[0-9A-Z]{16}\\b/g,\n /\\beyJ[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\.[A-Za-z0-9_-]{8,}\\b/g,\n /\\/\\/([^/\\s:@]+):([^@\\s/]+)@/g\n];\n\nexport function redactText(input: string): string {\n let output = input.replace(\n /-----BEGIN ([A-Z ]*PRIVATE KEY)-----[\\s\\S]*?-----END \\1-----/g,\n (_match, keyType: string) => `-----BEGIN ${keyType}-----\\n${REDACTION}\\n-----END ${keyType}-----`\n );\n\n output = output.replace(SECRET_KEY_PATTERN, (_match, prefix: string, quote: string) => {\n return `${prefix}${quote}${REDACTION}${quote}`;\n });\n\n output = output.replace(/\\bBearer\\s+[A-Za-z0-9._~+/=-]{12,}/gi, \"Bearer [REDACTED]\");\n output = output.replace(/\\/\\/([^/\\s:@]+):([^@\\s/]+)@/g, \"//[REDACTED]@\");\n\n for (const pattern of TOKEN_PATTERNS.slice(1, -1)) {\n output = output.replace(pattern, REDACTION);\n }\n\n return output;\n}\n","import { access, readFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { z } from \"zod\";\n\nimport type { PackageInfo, VerificationScript } from \"../types.js\";\n\nconst PackageJsonSchema = z.object({\n name: z.string().optional(),\n packageManager: z.string().optional(),\n scripts: z.record(z.string(), z.string()).optional()\n});\n\nconst VERIFY_SCRIPT_ORDER = [\"build\", \"test\", \"typecheck\", \"lint\", \"check\", \"verify\", \"ci\"];\nconst VERIFY_SCRIPT_PREFIX = /^(build|test|typecheck|lint|check|verify|ci)(:|$)/;\n\nexport async function detectPackageInfo(root: string): Promise<PackageInfo | undefined> {\n const packageJsonPath = join(root, \"package.json\");\n\n if (!(await pathExists(packageJsonPath))) {\n return undefined;\n }\n\n const rawPackageJson = await readFile(packageJsonPath, \"utf8\");\n const packageJson = PackageJsonSchema.parse(JSON.parse(rawPackageJson));\n const packageManager = await detectPackageManager(root, packageJson.packageManager);\n const verificationScripts = detectVerificationScripts(packageJson.scripts ?? {});\n\n return {\n ...(packageJson.name ? { name: packageJson.name } : {}),\n ...(packageManager ? { packageManager } : {}),\n verificationScripts\n };\n}\n\nexport async function detectPackageManager(root: string, packageManagerField?: string) {\n if (packageManagerField) {\n return packageManagerField.split(\"@\")[0] || packageManagerField;\n }\n\n const lockfiles: Array<[string, string]> = [\n [\"pnpm-lock.yaml\", \"pnpm\"],\n [\"yarn.lock\", \"yarn\"],\n [\"package-lock.json\", \"npm\"],\n [\"bun.lock\", \"bun\"],\n [\"bun.lockb\", \"bun\"]\n ];\n\n for (const [lockfile, manager] of lockfiles) {\n if (await pathExists(join(root, lockfile))) {\n return manager;\n }\n }\n\n return undefined;\n}\n\nexport function detectVerificationScripts(scripts: Record<string, string>): VerificationScript[] {\n return Object.entries(scripts)\n .filter(([name]) => VERIFY_SCRIPT_PREFIX.test(name))\n .sort(([left], [right]) => {\n const leftIndex = orderIndex(left);\n const rightIndex = orderIndex(right);\n\n if (leftIndex !== rightIndex) {\n return leftIndex - rightIndex;\n }\n\n return left.localeCompare(right);\n })\n .map(([name, command]) => ({ name, command }));\n}\n\nasync function pathExists(path: string) {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nfunction orderIndex(name: string) {\n const baseName = name.split(\":\")[0] ?? name;\n const index = VERIFY_SCRIPT_ORDER.indexOf(baseName);\n return index === -1 ? VERIFY_SCRIPT_ORDER.length : index;\n}\n","import type { HandoffReport, RiskReport, RiskNote } from \"../types.js\";\n\nexport function analyzeRisk(report: HandoffReport): RiskReport {\n const files = report.repository.changedFiles;\n const notes: RiskNote[] = [];\n\n if (files.some((file) => /(^|\\/)(redact|secret|auth|token|security)/i.test(file))) {\n notes.push({\n severity: \"high\",\n title: \"Security-sensitive code changed\",\n detail: \"Review redaction, auth, token, or secret-handling changes carefully before handoff.\"\n });\n }\n\n if (files.some((file) => file === \"package.json\" || file.endsWith(\"-lock.yaml\") || file.endsWith(\"lock.json\"))) {\n notes.push({\n severity: \"medium\",\n title: \"Dependency or package metadata changed\",\n detail: \"Run install/build verification and check package publishing metadata.\"\n });\n }\n\n if (files.some((file) => file.startsWith(\".github/workflows/\"))) {\n notes.push({\n severity: \"medium\",\n title: \"CI workflow changed\",\n detail: \"Confirm GitHub Actions still passes after push.\"\n });\n }\n\n const sourceFiles = files.filter((file) => file.startsWith(\"src/\") && file.endsWith(\".ts\"));\n const testFiles = files.filter((file) => file.startsWith(\"tests/\") && file.endsWith(\".test.ts\"));\n\n if (sourceFiles.length > 0 && testFiles.length === 0) {\n notes.push({\n severity: \"medium\",\n title: \"Source changed without matching tests\",\n detail: `Review test coverage for ${sourceFiles.slice(0, 5).join(\", \")}.`\n });\n }\n\n if (notes.length === 0) {\n notes.push({\n severity: \"low\",\n title: \"No obvious local risk signals\",\n detail: \"No deterministic risk rule matched the current changed file set.\"\n });\n }\n\n return { notes };\n}\n","import { mkdtemp, readFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport { relative, join } from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { execa } from \"execa\";\nimport fg from \"fast-glob\";\n\nimport type { SecretFinding, SecretScannerReport, SecretScannerStatus, SecretScanResult } from \"../types.js\";\nimport { redactText } from \"./redact.js\";\n\nconst MAX_FINDINGS = 20;\nconst ERROR_LIMIT = 2000;\n\nexport async function detectSecretScanners(root = process.cwd()): Promise<SecretScannerReport> {\n const [gitleaks, secretlint] = await Promise.all([scannerStatus(\"gitleaks\", root), scannerStatus(\"secretlint\", root)]);\n return { scanners: [gitleaks, secretlint] };\n}\n\nexport async function runSecretScanners(root: string): Promise<SecretScannerReport> {\n const report = await detectSecretScanners(root);\n const scans = await Promise.all(report.scanners.map((scanner) => runScanner(root, scanner)));\n return { ...report, scans };\n}\n\nexport function formatScannerSummary(report: SecretScannerReport): string {\n const availability = report.scanners.map(formatScannerStatus).join(\"\\n\");\n\n if (!report.scans) {\n return availability;\n }\n\n const scans = report.scans\n .map((scan) => `${scan.name}: ${scan.ran ? `${scan.findings.length} finding(s)` : scan.error ?? \"not run\"}`)\n .join(\"\\n\");\n\n return `${availability}\\n${scans}`;\n}\n\nexport function normalizeGitleaksFindings(rawJson: string, limit = MAX_FINDINGS): SecretFinding[] {\n const parsed = safeJson(rawJson);\n\n if (!Array.isArray(parsed)) {\n return [];\n }\n\n return parsed.slice(0, limit).map((finding) => {\n const ruleId = stringValue(finding.RuleID);\n const file = stringValue(finding.File);\n const line = numberValue(finding.StartLine);\n\n return {\n ...(ruleId ? { ruleId } : {}),\n message: redactText(stringValue(finding.Description) || \"Secret finding\"),\n ...(file ? { file } : {}),\n ...(line ? { line } : {})\n };\n });\n}\n\nexport function normalizeSecretlintFindings(rawJson: string, limit = MAX_FINDINGS, root?: string): SecretFinding[] {\n const parsed = safeJson(rawJson);\n\n if (!Array.isArray(parsed)) {\n return [];\n }\n\n const findings: SecretFinding[] = [];\n\n for (const fileResult of parsed) {\n const messages = Array.isArray(fileResult.messages) ? fileResult.messages : [];\n\n for (const message of messages) {\n if (findings.length >= limit) {\n return findings;\n }\n\n const filePath = stringValue(fileResult.filePath);\n const ruleId = stringValue(message.ruleId);\n const line = numberValue(message.line);\n findings.push({\n ...(ruleId ? { ruleId } : {}),\n message: redactText(stringValue(message.message) || \"Secret finding\"),\n ...(filePath ? { file: root ? relative(root, filePath) || filePath : filePath } : {}),\n ...(line ? { line } : {})\n });\n }\n }\n\n return findings;\n}\n\nasync function scannerStatus(name: \"gitleaks\" | \"secretlint\", root: string): Promise<SecretScannerStatus> {\n const result = await execa(name, [\"--version\"], {\n reject: false\n }).catch(() => undefined);\n const configFiles = await scannerConfigFiles(name, root);\n\n return {\n name,\n available: Boolean(result && result.exitCode === 0),\n ...(result?.stdout ? { version: result.stdout.trim() } : {}),\n configFiles,\n configHint: configHint(name, configFiles),\n installHint: installHint(name)\n };\n}\n\nasync function runScanner(root: string, scanner: SecretScannerStatus): Promise<SecretScanResult> {\n if (!scanner.available) {\n return {\n name: scanner.name,\n available: false,\n ran: false,\n findings: [],\n error: \"Scanner binary not found.\",\n truncated: false\n };\n }\n\n return scanner.name === \"gitleaks\" ? runGitleaks(root) : runSecretlint(root);\n}\n\nasync function runGitleaks(root: string): Promise<SecretScanResult> {\n const started = performance.now();\n const tempDir = await mkdtemp(join(tmpdir(), \"handoffkit-gitleaks-\"));\n const reportPath = join(tempDir, \"report.json\");\n const result = await execa(\n \"gitleaks\",\n [\"dir\", root, \"--no-banner\", \"--no-color\", \"--redact=100\", \"--report-format\", \"json\", \"--report-path\", reportPath, \"--max-target-megabytes\", \"2\"],\n { reject: false, all: true }\n );\n const rawReport = await readFile(reportPath, \"utf8\").catch(() => \"[]\");\n const findings = normalizeGitleaksFindings(rawReport);\n\n return {\n name: \"gitleaks\",\n available: true,\n ran: result.exitCode === 0 || result.exitCode === 1,\n exitCode: result.exitCode ?? 1,\n durationMs: Math.round(performance.now() - started),\n findings,\n ...(result.exitCode && result.exitCode > 1 ? { error: redactText(trimError(result.all ?? result.stderr ?? \"\")) } : {}),\n truncated: countJsonArray(rawReport) > findings.length\n };\n}\n\nasync function runSecretlint(root: string): Promise<SecretScanResult> {\n const started = performance.now();\n const result = await execa(\"secretlint\", [\"**/*\", \"--format\", \"json\", \"--no-color\"], {\n cwd: root,\n reject: false,\n all: true\n });\n const rawOutput = result.stdout || result.all || \"[]\";\n const findings = normalizeSecretlintFindings(rawOutput, MAX_FINDINGS, root);\n\n return {\n name: \"secretlint\",\n available: true,\n ran: result.exitCode === 0 || result.exitCode === 1,\n exitCode: result.exitCode ?? 1,\n durationMs: Math.round(performance.now() - started),\n findings,\n ...(result.exitCode && result.exitCode > 1 ? { error: redactText(trimError(result.all ?? result.stderr ?? \"\")) } : {}),\n truncated: countSecretlintMessages(rawOutput) > findings.length\n };\n}\n\nfunction safeJson(rawJson: string): unknown {\n try {\n return JSON.parse(rawJson || \"[]\");\n } catch {\n return [];\n }\n}\n\nfunction stringValue(value: unknown) {\n return typeof value === \"string\" ? value : \"\";\n}\n\nfunction numberValue(value: unknown) {\n return typeof value === \"number\" ? value : undefined;\n}\n\nfunction countJsonArray(rawJson: string) {\n const parsed = safeJson(rawJson);\n return Array.isArray(parsed) ? parsed.length : 0;\n}\n\nfunction countSecretlintMessages(rawJson: string) {\n const parsed = safeJson(rawJson);\n\n if (!Array.isArray(parsed)) {\n return 0;\n }\n\n return parsed.reduce((count, fileResult) => {\n return count + (Array.isArray(fileResult.messages) ? fileResult.messages.length : 0);\n }, 0);\n}\n\nfunction trimError(output: string) {\n const trimmed = output.trim();\n return trimmed.length > ERROR_LIMIT ? `${trimmed.slice(0, ERROR_LIMIT)}\\n[truncated]` : trimmed;\n}\n\nfunction formatScannerStatus(scanner: SecretScannerStatus) {\n const config = scanner.configFiles.length > 0 ? `; config: ${scanner.configFiles.join(\", \")}` : scanner.available ? \"\" : `; ${scanner.configHint}`;\n const install = scanner.available ? \"\" : `; ${scanner.installHint}`;\n return `${scanner.name}: ${scanner.available ? \"available\" : \"not found\"}${config}${install}`;\n}\n\nasync function scannerConfigFiles(name: \"gitleaks\" | \"secretlint\", root: string) {\n const patterns =\n name === \"gitleaks\"\n ? [\"gitleaks.toml\", \".gitleaks.toml\", \".gitleaksignore\", \".config/gitleaks/*.toml\"]\n : [\".secretlintrc\", \".secretlintrc.*\", \"secretlint.config.*\"];\n\n const matches = await fg(patterns, {\n cwd: root,\n dot: true,\n onlyFiles: true,\n unique: true\n });\n\n return matches.sort();\n}\n\nfunction configHint(name: \"gitleaks\" | \"secretlint\", configFiles: string[]) {\n if (configFiles.length > 0) {\n return `config: ${configFiles.join(\", \")}`;\n }\n\n return name === \"gitleaks\"\n ? \"config: none detected; optional files include .gitleaks.toml, gitleaks.toml, or .config/gitleaks/*.toml\"\n : \"config: none detected; optional files include .secretlintrc.*, .secretlintrc, or secretlint.config.*\";\n}\n\nfunction installHint(name: \"gitleaks\" | \"secretlint\") {\n return name === \"gitleaks\"\n ? \"Install gitleaks from https://github.com/gitleaks/gitleaks, then rerun with --scan-secrets.\"\n : \"Install secretlint from https://github.com/secretlint/secretlint, then rerun with --scan-secrets.\";\n}\n","import { performance } from \"node:perf_hooks\";\n\nimport { execa } from \"execa\";\n\nimport type { PackageInfo, VerificationReport, VerificationResult, VerificationScript } from \"../types.js\";\nimport { detectPackageInfo } from \"./package-json.js\";\n\nconst VERIFY_ORDER = [\"typecheck\", \"lint\", \"test\", \"build\"];\nconst OUTPUT_LIMIT = 4000;\n\nexport function selectVerificationScripts(packageInfo: PackageInfo | undefined): VerificationScript[] {\n if (!packageInfo) {\n return [];\n }\n\n return VERIFY_ORDER.flatMap((name) => packageInfo.verificationScripts.filter((script) => script.name === name));\n}\n\nexport async function runVerification(root: string): Promise<VerificationReport> {\n const packageInfo = await detectPackageInfo(root);\n const scripts = selectVerificationScripts(packageInfo);\n const commands: VerificationResult[] = [];\n\n for (const script of scripts) {\n commands.push(await runScript(root, packageInfo?.packageManager ?? \"npm\", script));\n }\n\n return { commands };\n}\n\nasync function runScript(root: string, packageManager: string, script: VerificationScript): Promise<VerificationResult> {\n const started = performance.now();\n const command = `${packageManager} run ${script.name}`;\n const result = await execa(packageManager, [\"run\", script.name], {\n cwd: root,\n reject: false,\n all: true\n });\n\n return {\n name: script.name,\n command,\n exitCode: result.exitCode ?? 1,\n durationMs: Math.round(performance.now() - started),\n output: trimOutput(result.all ?? result.stdout ?? result.stderr ?? \"\")\n };\n}\n\nfunction trimOutput(output: string) {\n const normalized = output.trim();\n return normalized.length > OUTPUT_LIMIT ? `${normalized.slice(-OUTPUT_LIMIT)}\\n[trimmed]` : normalized;\n}\n","import type { HandoffReport, PackOptions } from \"../types.js\";\nimport { collectGitInfo, findGitRoot } from \"./git.js\";\nimport { detectInstructionFiles } from \"./instructions.js\";\nimport { detectPackageInfo } from \"./package-json.js\";\nimport { analyzeRisk } from \"./risk.js\";\nimport { detectSecretScanners, runSecretScanners } from \"./scanners.js\";\nimport { runVerification } from \"./verify.js\";\n\nexport async function collectHandoffReport(options: PackOptions): Promise<HandoffReport> {\n const root = await findGitRoot(options.cwd);\n const [repository, instructionFiles, packageInfo, secretScanning] = await Promise.all([\n collectGitInfo(root, {\n includeDiff: options.includeDiff && options.includeDiffSummary,\n includeDiffSummary: options.includeDiffSummary,\n ...(options.since ? { since: options.since } : {})\n }),\n detectInstructionFiles(root),\n detectPackageInfo(root),\n options.scanSecrets ? runSecretScanners(root) : detectSecretScanners(root)\n ]);\n\n const report: HandoffReport = {\n goal: options.goal,\n target: options.target,\n repository,\n instructionFiles,\n ...(packageInfo ? { packageInfo } : {}),\n ...(options.resumeSource ? { resumeSource: options.resumeSource } : {}),\n ...(options.includeVerification ? { verification: await runVerification(root) } : {}),\n secretScanning,\n budget: {\n requestedTokens: options.budget,\n estimatedTokens: 0,\n wasTrimmed: false\n }\n };\n\n report.risk = analyzeRisk(report);\n return report;\n}\n","import { mkdir, writeFile } from \"node:fs/promises\";\nimport { dirname, resolve } from \"node:path\";\n\nimport { applyMarkdownBudget, estimateTokens } from \"../core/budget.js\";\nimport { redactText } from \"../core/redact.js\";\nimport { renderJsonReport } from \"../report/json.js\";\nimport { renderMarkdownReport } from \"../report/markdown.js\";\nimport type { HandoffReport, OutputFormat } from \"../types.js\";\n\nexport async function writeRenderedReport(report: HandoffReport, format: OutputFormat, budget: number, output?: string) {\n const rendered = redactText(renderOutput(report, format, budget));\n\n if (output) {\n const outputPath = resolve(process.cwd(), output);\n await mkdir(dirname(outputPath), { recursive: true });\n await writeFile(outputPath, rendered, \"utf8\");\n process.stderr.write(`Wrote handoff packet to ${outputPath}\\n`);\n return;\n }\n\n process.stdout.write(rendered);\n}\n\nfunction renderOutput(report: HandoffReport, format: OutputFormat, budget: number) {\n if (format === \"json\") {\n const rendered = renderJsonReport(report);\n report.budget.estimatedTokens = estimateTokens(rendered);\n return renderJsonReport(report);\n }\n\n const firstRender = renderMarkdownReport(report);\n const budgeted = applyMarkdownBudget(firstRender, budget);\n report.budget.estimatedTokens = budgeted.estimatedTokens;\n report.budget.wasTrimmed = budgeted.wasTrimmed;\n\n if (budgeted.wasTrimmed) {\n return budgeted.text;\n }\n\n return renderMarkdownReport(report);\n}\n","export function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\nexport function applyMarkdownBudget(text: string, budget: number) {\n const estimatedTokens = estimateTokens(text);\n\n if (estimatedTokens <= budget) {\n return { text, estimatedTokens, wasTrimmed: false };\n }\n\n const notice = `\\n\\n> Output trimmed to fit --budget ${budget}. Re-run with a larger budget or --output for the full packet.\\n`;\n const charLimit = Math.max(0, budget * 4 - notice.length);\n const trimmed = `${text.slice(0, charLimit).trimEnd()}${notice}`;\n\n return {\n text: trimmed,\n estimatedTokens: estimateTokens(trimmed),\n wasTrimmed: true\n };\n}\n","import type { HandoffReport } from \"../types.js\";\n\nexport function renderJsonReport(report: HandoffReport): string {\n return `${JSON.stringify(report, null, 2)}\\n`;\n}\n","import type { AgentTarget } from \"../types.js\";\n\nexport type ReportSectionKey =\n | \"goal\"\n | \"repository\"\n | \"gitStatus\"\n | \"recentCommits\"\n | \"changedFiles\"\n | \"branchDelta\"\n | \"diffSummary\"\n | \"includedBranchDelta\"\n | \"includedDiff\"\n | \"instructionFiles\"\n | \"package\"\n | \"resume\"\n | \"verification\"\n | \"risk\"\n | \"secretScanning\";\n\nexport interface ReportProfile {\n title: string;\n sectionOrder: ReportSectionKey[];\n nextAgentNotes: string[];\n}\n\nconst genericOrder: ReportSectionKey[] = [\n \"goal\",\n \"repository\",\n \"gitStatus\",\n \"recentCommits\",\n \"changedFiles\",\n \"branchDelta\",\n \"diffSummary\",\n \"includedBranchDelta\",\n \"includedDiff\",\n \"instructionFiles\",\n \"package\",\n \"resume\",\n \"verification\",\n \"risk\",\n \"secretScanning\"\n];\n\nconst profiles: Record<AgentTarget, ReportProfile> = {\n generic: {\n title: \"Handoff Packet\",\n sectionOrder: genericOrder,\n nextAgentNotes: [\n \"Use this packet as the starting context for the next coding session.\",\n \"Verify commands locally before claiming completion.\"\n ]\n },\n codex: {\n title: \"Codex Handoff Packet\",\n sectionOrder: [\n \"goal\",\n \"repository\",\n \"gitStatus\",\n \"changedFiles\",\n \"verification\",\n \"risk\",\n \"branchDelta\",\n \"diffSummary\",\n \"includedBranchDelta\",\n \"includedDiff\",\n \"instructionFiles\",\n \"package\",\n \"resume\",\n \"secretScanning\",\n \"recentCommits\"\n ],\n nextAgentNotes: [\n \"Start by reading the goal, repository status, changed files, and verification state.\",\n \"Use local tools to inspect files before editing; do not assume hidden context.\",\n \"Keep edits scoped and rerun the relevant verification before reporting completion.\"\n ]\n },\n claude: {\n title: \"Claude Code Handoff Packet\",\n sectionOrder: [\n \"goal\",\n \"resume\",\n \"repository\",\n \"verification\",\n \"risk\",\n \"changedFiles\",\n \"gitStatus\",\n \"branchDelta\",\n \"diffSummary\",\n \"includedBranchDelta\",\n \"includedDiff\",\n \"instructionFiles\",\n \"package\",\n \"secretScanning\",\n \"recentCommits\"\n ],\n nextAgentNotes: [\n \"Treat this as concise project memory plus current branch state.\",\n \"Use the resume state to separate completed work from remaining work.\",\n \"Ask for clarification only when the packet leaves a blocking ambiguity.\"\n ]\n },\n cursor: {\n title: \"Cursor Handoff Packet\",\n sectionOrder: [\n \"goal\",\n \"repository\",\n \"changedFiles\",\n \"gitStatus\",\n \"includedDiff\",\n \"diffSummary\",\n \"branchDelta\",\n \"includedBranchDelta\",\n \"instructionFiles\",\n \"package\",\n \"verification\",\n \"risk\",\n \"resume\",\n \"secretScanning\",\n \"recentCommits\"\n ],\n nextAgentNotes: [\n \"Open the changed files first to build editor context.\",\n \"Use instruction files and package scripts to keep edits aligned with the workspace.\",\n \"Prefer small edits and rerun the detected verification scripts.\"\n ]\n }\n};\n\nexport function profileForTarget(target: AgentTarget): ReportProfile {\n return profiles[target] ?? profiles.generic;\n}\n","import type { HandoffReport, PackageInfo, ResumeItem, ResumeState } from \"../types.js\";\nimport { profileForTarget, type ReportSectionKey } from \"./profiles.js\";\n\nexport function renderMarkdownReport(report: HandoffReport): string {\n const profile = profileForTarget(report.target);\n const lines: string[] = [\n `# ${profile.title}`,\n \"\",\n ...profile.sectionOrder.flatMap((section) => renderSection(section, report)),\n \"## Next Agent Notes\",\n ...profile.nextAgentNotes.map((note) => `- ${note}`),\n \"- This packet was generated from local git and filesystem state.\",\n \"- Likely secrets were redacted from generated output.\",\n \"- No LLM APIs were called.\"\n ];\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction renderSection(section: ReportSectionKey, report: HandoffReport) {\n switch (section) {\n case \"goal\":\n return [\"## Goal\", report.goal, \"\"];\n case \"repository\":\n return [\n \"## Repository\",\n `- Repository: \\`${report.repository.name}\\``,\n `- Branch: \\`${report.repository.branch}\\``,\n `- Changed files: ${report.repository.changedFiles.length}`,\n \"\"\n ];\n case \"gitStatus\":\n return [\"## Git Status\", codeBlock(report.repository.status || \"Clean working tree.\"), \"\"];\n case \"recentCommits\":\n return [\"## Recent Commits\", listOrNone(report.repository.recentCommits.map((commit) => `- ${commit}`)), \"\"];\n case \"changedFiles\":\n return [\"## Changed Files\", listOrNone(report.repository.changedFiles.map((file) => `- \\`${file}\\``)), \"\"];\n case \"branchDelta\":\n return renderBaseDiffSummary(report);\n case \"diffSummary\":\n return [\n \"## Diff Summary\",\n \"### Staged\",\n codeBlock(report.repository.stagedDiffSummary || \"No staged diff.\"),\n \"\",\n \"### Unstaged\",\n codeBlock(report.repository.unstagedDiffSummary || \"No unstaged diff.\"),\n \"\"\n ];\n case \"includedBranchDelta\":\n return renderIncludedBranchDelta(report);\n case \"includedDiff\":\n return renderIncludedDiff(report);\n case \"instructionFiles\":\n return [\"## Instruction Files\", renderInstructionFiles(report.instructionFiles), \"\"];\n case \"package\":\n return [\"## Package\", renderPackage(report.packageInfo), \"\"];\n case \"resume\":\n return renderResumeSource(report);\n case \"verification\":\n return renderVerification(report);\n case \"risk\":\n return renderRisk(report);\n case \"secretScanning\":\n return renderSecretScanning(report);\n }\n}\n\nfunction renderBaseDiffSummary(report: HandoffReport) {\n if (!report.repository.baseRef) {\n return [];\n }\n\n return [\n `## Branch Delta Since \\`${report.repository.baseRef}\\``,\n codeBlock(report.repository.baseDiffSummary || \"No committed branch delta detected.\"),\n \"\"\n ];\n}\n\nfunction renderIncludedBranchDelta(report: HandoffReport) {\n if (!report.repository.includeDiff || !report.repository.baseDiff) {\n return [];\n }\n\n return [\n `## Included Branch Delta Since \\`${report.repository.baseRef}\\``,\n codeBlock(report.repository.baseDiff),\n \"\"\n ];\n}\n\nfunction renderIncludedDiff(report: HandoffReport) {\n if (!report.repository.includeDiff || !report.repository.diff) {\n return [];\n }\n\n return [\n \"## Included Diff\",\n \"### Staged Patch\",\n codeBlock(report.repository.diff.staged || \"No staged patch.\"),\n \"\",\n \"### Unstaged Patch\",\n codeBlock(report.repository.diff.unstaged || \"No unstaged patch.\"),\n \"\"\n ];\n}\n\nfunction renderPackage(packageInfo: PackageInfo | undefined) {\n if (!packageInfo) {\n return \"No package.json detected.\";\n }\n\n const lines = [\n packageInfo.name ? `- Package: \\`${packageInfo.name}\\`` : undefined,\n packageInfo.packageManager ? `- Package manager: \\`${packageInfo.packageManager}\\`` : undefined\n ].filter((line): line is string => Boolean(line));\n\n if (packageInfo.verificationScripts.length > 0) {\n const prefix = packageInfo.packageManager ?? \"npm\";\n lines.push(\"- Verification scripts:\");\n lines.push(...packageInfo.verificationScripts.map((script) => ` - \\`${prefix} ${script.name}\\``));\n } else {\n lines.push(\"- Verification scripts: none detected.\");\n }\n\n return lines.join(\"\\n\");\n}\n\nfunction renderInstructionFiles(instructionFiles: HandoffReport[\"instructionFiles\"]) {\n if (instructionFiles.length === 0) {\n return \"None detected.\";\n }\n\n return instructionFiles\n .map((file) => [`- \\`${file.path}\\` (${file.kind})`, codeBlock(file.preview || \"No preview available.\")].join(\"\\n\"))\n .join(\"\\n\\n\");\n}\n\nfunction renderResumeSource(report: HandoffReport) {\n if (!report.resumeSource) {\n return [];\n }\n\n return [\n \"## Resume Source\",\n `- Source: \\`${report.resumeSource.path}\\``,\n codeBlock(report.resumeSource.preview),\n \"\",\n ...renderResumeState(report.resumeSource.state)\n ];\n}\n\nfunction renderResumeState(state: ResumeState | undefined) {\n if (!state) {\n return [];\n }\n\n return [\n \"## Resume State\",\n renderResumeItems(\"Completed\", state.completed),\n renderResumeItems(\"Remaining\", state.remaining),\n renderResumeItems(\"Failed Commands\", state.failedCommands),\n renderResumeItems(\"Open Questions\", state.openQuestions),\n renderResumeItems(\"Verification\", state.verification),\n state.nextSafestAction ? `- Next safest action: ${state.nextSafestAction}` : \"- Next safest action: none detected.\",\n \"\"\n ];\n}\n\nfunction renderResumeItems(title: string, items: ResumeItem[]) {\n return [`### ${title}`, listOrNone(items.map((item) => `- ${item.text}`))].join(\"\\n\");\n}\n\nfunction renderVerification(report: HandoffReport) {\n if (!report.verification) {\n return [];\n }\n\n return [\n \"## Verification\",\n report.verification.commands.length > 0\n ? report.verification.commands\n .map((command) =>\n [`- \\`${command.command}\\` exited ${command.exitCode} in ${command.durationMs}ms`, codeBlock(command.output || \"No output.\")]\n .join(\"\\n\")\n )\n .join(\"\\n\\n\")\n : \"No safe verification scripts detected.\",\n \"\"\n ];\n}\n\nfunction renderRisk(report: HandoffReport) {\n if (!report.risk) {\n return [];\n }\n\n return [\n \"## Risk Notes\",\n report.risk.notes.map((note) => `- **${note.severity}**: ${note.title} - ${note.detail}`).join(\"\\n\"),\n \"\"\n ];\n}\n\nfunction renderSecretScanning(report: HandoffReport) {\n if (!report.secretScanning) {\n return [];\n }\n\n return [\n report.secretScanning.scans ? \"## Secret Scan Results\" : \"## Secret Scanner Availability\",\n renderSecretScannerReport(report.secretScanning),\n \"\"\n ];\n}\n\nfunction renderSecretScannerReport(secretScanning: NonNullable<HandoffReport[\"secretScanning\"]>) {\n if (!secretScanning.scans) {\n return secretScanning.scanners.map((scanner) => `- ${scannerStatusLine(scanner)}`).join(\"\\n\");\n }\n\n return secretScanning.scans\n .map((scan) => {\n const status = secretScanning.scanners.find((scanner) => scanner.name === scan.name);\n const lines = [\n `- ${scan.name}: ${scan.ran ? `${scan.findings.length} finding(s), exit ${scan.exitCode}` : scan.error ?? \"not run\"}`\n ];\n\n if (status) {\n lines.push(...scannerGuidanceLines(status));\n }\n\n for (const finding of scan.findings) {\n lines.push(` - ${finding.ruleId ? `${finding.ruleId}: ` : \"\"}${finding.message}${finding.file ? ` (${finding.file}${finding.line ? `:${finding.line}` : \"\"})` : \"\"}`);\n }\n\n if (scan.truncated) {\n lines.push(\" - Additional findings were truncated.\");\n }\n\n return lines.join(\"\\n\");\n })\n .join(\"\\n\");\n}\n\nfunction scannerStatusLine(scanner: NonNullable<HandoffReport[\"secretScanning\"]>[\"scanners\"][number]) {\n const config = scanner.configFiles.length > 0 ? `; config: ${scanner.configFiles.join(\", \")}` : scanner.available ? \"\" : `; ${scanner.configHint}`;\n const install = scanner.available ? \"\" : `; ${scanner.installHint}`;\n return `${scanner.name}: ${scanner.available ? \"available\" : \"not found\"}${config}${install}`;\n}\n\nfunction scannerGuidanceLines(scanner: NonNullable<HandoffReport[\"secretScanning\"]>[\"scanners\"][number]) {\n const lines: string[] = [];\n\n if (scanner.configFiles.length > 0) {\n lines.push(` - config: ${scanner.configFiles.join(\", \")}`);\n } else if (!scanner.available) {\n lines.push(` - ${scanner.configHint}`);\n }\n\n if (!scanner.available) {\n lines.push(` - ${scanner.installHint}`);\n }\n\n return lines;\n}\n\nfunction codeBlock(text: string) {\n return [\"```text\", text, \"```\"].join(\"\\n\");\n}\n\nfunction listOrNone(items: string[]) {\n return items.length > 0 ? items.join(\"\\n\") : \"None detected.\";\n}\n","import { readFile } from \"node:fs/promises\";\n\nimport { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { collectHandoffReport } from \"../../core/collect.js\";\nimport { createResumeSource } from \"../../core/resume.js\";\nimport { writeRenderedReport } from \"../output.js\";\n\nconst ResumeOptionsSchema = z.object({\n goal: z.string().trim().min(1).default(\"Resume interrupted AI coding session\"),\n output: z.string().optional(),\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\"),\n for: z.enum([\"generic\", \"codex\", \"claude\", \"cursor\"]).default(\"generic\"),\n budget: z.number().int().positive().default(4000)\n});\n\nexport function createResumeCommand() {\n return new Command(\"resume\")\n .description(\"Create a fresh handoff packet using a previous handoff as resume context.\")\n .summary(\"Merge a previous handoff or transcript with fresh repo state.\")\n .argument(\"<path>\", \"previous handoff or transcript file\")\n .option(\"--goal <text>\", \"new handoff goal\", \"Resume interrupted AI coding session\")\n .option(\"--output <path>\", \"write output to a file instead of stdout\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .option(\"--for <agent>\", \"target output: generic, codex, claude, or cursor\", \"generic\")\n .option(\"--budget <tokens>\", \"rough output token budget\", parseBudget, 4000)\n .action(async (path: string, rawOptions) => {\n const options = ResumeOptionsSchema.parse(rawOptions);\n const source = createResumeSource(path, await readFile(path, \"utf8\"));\n const report = await collectHandoffReport({\n goal: options.goal,\n cwd: process.cwd(),\n ...(options.output ? { output: options.output } : {}),\n format: options.format,\n target: options.for,\n budget: options.budget,\n includeDiff: false,\n includeDiffSummary: true,\n includeVerification: false,\n scanSecrets: false,\n resumeSource: source\n });\n\n await writeRenderedReport(report, options.format, options.budget, options.output);\n });\n}\n\nfunction parseBudget(value: string) {\n const parsed = Number.parseInt(value, 10);\n\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new Error(\"--budget must be a positive integer.\");\n }\n\n return parsed;\n}\n","import type { ResumeSource, ResumeState } from \"../types.js\";\nimport { redactText } from \"./redact.js\";\n\nconst RESUME_PREVIEW_LIMIT = 3000;\nconst SECTION_ALIASES = {\n completed: [/^completed$/i, /^done$/i, /^done this session$/i, /^what changed$/i, /^implemented$/i],\n remaining: [/^remaining$/i, /^next steps$/i, /^todo$/i, /^to do$/i],\n failedCommands: [/^failed commands$/i, /^failures$/i, /^errors$/i],\n openQuestions: [/^open questions$/i, /^open questions \\/ risks$/i, /^open questions and risks$/i, /^questions$/i, /^blockers$/i],\n verification: [/^verification$/i, /^tests$/i, /^validation$/i]\n} as const;\n\ntype ResumeSection = keyof typeof SECTION_ALIASES;\n\nexport function createResumeSource(path: string, content: string): ResumeSource {\n const normalized = content.replace(/\\r\\n/g, \"\\n\").trim();\n const preview =\n normalized.length > RESUME_PREVIEW_LIMIT ? `${normalized.slice(0, RESUME_PREVIEW_LIMIT).trimEnd()}\\n[truncated]` : normalized;\n const state = parseResumeState(normalized);\n\n return {\n path,\n preview: redactText(preview),\n ...(hasResumeState(state) ? { state } : {})\n };\n}\n\nexport function parseResumeState(content: string): ResumeState {\n const state: ResumeState = {\n completed: [],\n remaining: [],\n failedCommands: [],\n openQuestions: [],\n verification: []\n };\n let section: ResumeSection | undefined;\n let heading: string | undefined;\n\n for (const rawLine of content.replace(/\\r\\n/g, \"\\n\").split(\"\\n\")) {\n const line = rawLine.trim();\n const headingMatch = line.match(/^#{1,4}\\s+(.+)$/);\n\n if (headingMatch) {\n const headingText = headingMatch[1];\n if (!headingText) {\n continue;\n }\n\n heading = headingText.trim();\n section = sectionForHeading(heading);\n continue;\n }\n\n if (!section) {\n continue;\n }\n\n const item = normalizeListItem(line);\n if (item) {\n state[section].push({ text: redactText(item), ...(heading ? { sourceHeading: redactText(heading) } : {}) });\n }\n }\n\n const next = state.remaining[0] ?? state.openQuestions[0] ?? state.failedCommands[0];\n if (next) {\n state.nextSafestAction = next.text;\n }\n\n return state;\n}\n\nfunction sectionForHeading(heading: string): ResumeSection | undefined {\n const normalized = normalizeHeading(heading);\n\n for (const [section, patterns] of Object.entries(SECTION_ALIASES)) {\n if (patterns.some((pattern) => pattern.test(normalized))) {\n return section as ResumeSection;\n }\n }\n\n return undefined;\n}\n\nfunction normalizeListItem(line: string) {\n const match = line.match(/^[-*]\\s+(.+)$/) ?? line.match(/^\\d+\\.\\s+(.+)$/);\n return match?.[1]?.trim();\n}\n\nfunction normalizeHeading(heading: string) {\n return heading.trim().replace(/:$/, \"\").replace(/\\s*\\/\\s*/g, \" / \").replace(/\\s+/g, \" \");\n}\n\nfunction hasResumeState(state: ResumeState) {\n return (\n state.completed.length > 0 ||\n state.remaining.length > 0 ||\n state.failedCommands.length > 0 ||\n state.openQuestions.length > 0 ||\n state.verification.length > 0\n );\n}\n","import { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { collectHandoffReport } from \"../../core/collect.js\";\n\nconst RiskOptionsSchema = z.object({\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\")\n});\n\nexport function createRiskCommand() {\n return new Command(\"risk\")\n .description(\"Show deterministic risk notes for the current handoff.\")\n .summary(\"Show deterministic risk notes from changed files.\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .action(async (rawOptions) => {\n const options = RiskOptionsSchema.parse(rawOptions);\n const report = await collectHandoffReport({\n goal: \"Review local risk\",\n cwd: process.cwd(),\n format: options.format,\n target: \"generic\",\n budget: 4000,\n includeDiff: false,\n includeDiffSummary: false,\n includeVerification: false,\n scanSecrets: false\n });\n\n if (options.format === \"json\") {\n process.stdout.write(`${JSON.stringify(report.risk, null, 2)}\\n`);\n return;\n }\n\n process.stdout.write(`# Risk Notes\\n\\n${report.risk?.notes.map((note) => `- **${note.severity}**: ${note.title} - ${note.detail}`).join(\"\\n\")}\\n`);\n });\n}\n","import { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { findGitRoot } from \"../../core/git.js\";\nimport { redactText } from \"../../core/redact.js\";\nimport { runSecretScanners } from \"../../core/scanners.js\";\nimport type { SecretScannerReport, SecretScannerStatus } from \"../../types.js\";\n\nconst ScanSecretsOptionsSchema = z.object({\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\")\n});\n\nexport function createScanSecretsCommand() {\n return new Command(\"scan-secrets\")\n .description(\"Run optional local secret scanners and print bounded redacted results.\")\n .summary(\"Run optional local secret scanners.\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .action(async (rawOptions) => {\n const options = ScanSecretsOptionsSchema.parse(rawOptions);\n const root = await findGitRoot(process.cwd());\n const report = await runSecretScanners(root);\n\n if (options.format === \"json\") {\n process.stdout.write(redactText(`${JSON.stringify(report, null, 2)}\\n`));\n return;\n }\n\n process.stdout.write(redactText(renderScanMarkdown(report)));\n });\n}\n\nexport function renderScanMarkdown(report: SecretScannerReport) {\n const lines = [\"# Secret Scan Results\", \"\"];\n\n for (const scan of report.scans ?? []) {\n const status = report.scanners.find((scanner) => scanner.name === scan.name);\n lines.push(`- ${scan.name}: ${scan.ran ? `${scan.findings.length} finding(s), exit ${scan.exitCode}` : scan.error ?? \"not run\"}`);\n\n if (status) {\n lines.push(...scannerGuidanceLines(status));\n }\n\n for (const finding of scan.findings) {\n lines.push(` - ${finding.ruleId ? `${finding.ruleId}: ` : \"\"}${finding.message}${finding.file ? ` (${finding.file}${finding.line ? `:${finding.line}` : \"\"})` : \"\"}`);\n }\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction scannerGuidanceLines(scanner: SecretScannerStatus) {\n const lines: string[] = [];\n\n if (scanner.configFiles.length > 0) {\n lines.push(` - config: ${scanner.configFiles.join(\", \")}`);\n } else if (!scanner.available) {\n lines.push(` - ${scanner.configHint}`);\n }\n\n if (!scanner.available) {\n lines.push(` - ${scanner.installHint}`);\n }\n\n return lines;\n}\n","import { Command } from \"commander\";\nimport { z } from \"zod\";\n\nimport { findGitRoot } from \"../../core/git.js\";\nimport { redactText } from \"../../core/redact.js\";\nimport { runVerification } from \"../../core/verify.js\";\nimport type { VerificationResult } from \"../../types.js\";\n\nconst VerifyOptionsSchema = z.object({\n format: z.enum([\"markdown\", \"json\"]).default(\"markdown\")\n});\n\nexport function createVerifyCommand() {\n return new Command(\"verify\")\n .description(\"Run safe local verification scripts.\")\n .summary(\"Run safe detected verification scripts.\")\n .option(\"--format <format>\", \"output format: markdown or json\", \"markdown\")\n .action(async (rawOptions) => {\n const options = VerifyOptionsSchema.parse(rawOptions);\n const root = await findGitRoot(process.cwd());\n const verification = await runVerification(root);\n\n if (options.format === \"json\") {\n process.stdout.write(redactText(`${JSON.stringify(verification, null, 2)}\\n`));\n return;\n }\n\n process.stdout.write(redactText(renderVerificationMarkdown(verification.commands)));\n });\n}\n\nfunction renderVerificationMarkdown(commands: VerificationResult[]) {\n const lines = [\"# Verification\", \"\"];\n\n if (commands.length === 0) {\n lines.push(\"No safe verification scripts detected.\");\n } else {\n for (const command of commands) {\n lines.push(`- \\`${command.command}\\` exited ${command.exitCode} in ${command.durationMs}ms`);\n }\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n"],"mappings":"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","names":["Command","z","readFile","readFile","readFile","readFile","join","execa","fg","execa","join","readFile","fg","performance","execa","performance","execa","z","readFile","Command","z","z","Command","parseBudget","readFile","Command","z","z","Command","Command","z","z","Command","scannerGuidanceLines","Command","z","z","Command","Command"]}
package/docs/RELEASE.md CHANGED
@@ -9,7 +9,7 @@ HandoffKit releases are intentionally manual. A release should prove that the so
9
9
  - Node.js 22 or newer
10
10
  - pnpm via Corepack
11
11
 
12
- For GitHub Actions publishing, add an `NPM_TOKEN` repository secret with publish access. Without that secret, the `Release` workflow can run verification but cannot publish.
12
+ For GitHub Actions publishing, add an `NPM_TOKEN` repository secret with publish access. The token must be usable from CI without an interactive one-time password; for npm accounts with publish 2FA, use a granular token with package write access and 2FA bypass enabled, or configure npm trusted publishing. Without a valid publish token, the `Release` workflow can run verification but cannot publish.
13
13
 
14
14
  ## Before Tagging
15
15
 
@@ -35,15 +35,16 @@ The script packs the current package, installs it into a clean temporary git rep
35
35
  After CI passes on `main`:
36
36
 
37
37
  ```sh
38
- git tag v0.1.0
39
- git push origin v0.1.0
40
- gh release create v0.1.0 --repo kingkyylian/handoffkit --title "HandoffKit v0.1.0" --notes-file /private/tmp/handoffkit-v0.1.0-release-notes.md
38
+ version=0.2.0
39
+ git tag "v${version}"
40
+ git push origin "v${version}"
41
+ gh release create "v${version}" --repo kingkyylian/handoffkit --title "HandoffKit v${version}" --notes-file "/private/tmp/handoffkit-v${version}-release-notes.md"
41
42
  ```
42
43
 
43
44
  Preferred publish path:
44
45
 
45
46
  ```sh
46
- gh workflow run Release --repo kingkyylian/handoffkit --ref v0.1.0
47
+ gh workflow run Release --repo kingkyylian/handoffkit --ref "v${version}"
47
48
  ```
48
49
 
49
50
  Fallback local publish path when `NPM_TOKEN` is not configured:
@@ -55,8 +56,8 @@ npm --cache ./.npm-cache publish --provenance --access public
55
56
  ## After Publishing
56
57
 
57
58
  ```sh
58
- npm view @kingkyylian/handoffkit version
59
- pnpm dlx @kingkyylian/handoffkit pack --goal "Registry smoke" --format json --no-diff
59
+ npm view "@kingkyylian/handoffkit@${version}" version --registry=https://registry.npmjs.org/
60
+ pnpm dlx "@kingkyylian/handoffkit@${version}" pack --goal "Registry smoke" --format json --no-diff
60
61
  ```
61
62
 
62
63
  The published version should match the tag, and the registry smoke command should exit successfully inside a git repository.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kingkyylian/handoffkit",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "description": "Clean handoff packets for interrupted AI coding sessions.",
5
5
  "type": "module",
6
6
  "license": "MIT",