@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 +9 -0
- package/README.md +6 -2
- package/ROADMAP.md +2 -2
- package/dist/index.js +252 -75
- package/dist/index.js.map +1 -1
- package/docs/RELEASE.md +8 -7
- package/package.json +1 -1
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-
|
|
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
|
-
`# ${
|
|
763
|
+
`# ${profile.title}`,
|
|
632
764
|
"",
|
|
633
|
-
|
|
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
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
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
|
|
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.
|
|
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
|
|
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
|
-
|
|
39
|
-
git
|
|
40
|
-
|
|
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
|
|
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.
|