@prestyj/cli 5.12.0 → 5.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -36
- package/assets/skills/bulletproof/SKILL.md +158 -0
- package/assets/skills/bulletproof/references/agent-surface.md +82 -0
- package/assets/skills/bulletproof/references/audit-protocol.md +147 -0
- package/assets/skills/bulletproof/references/platform-playbooks.md +176 -0
- package/assets/skills/bulletproof/references/provenance.md +45 -0
- package/assets/skills/bulletproof/references/secure-defaults.md +108 -0
- package/assets/skills/bulletproof/references/supply-chain.md +76 -0
- package/assets/skills/bulletproof/references/threat-landscape.md +74 -0
- package/assets/skills/bulletproof/references/verification.md +65 -0
- package/assets/skills/durable/SKILL.md +111 -0
- package/assets/skills/durable/references/backups-and-runtime.md +86 -0
- package/assets/skills/durable/references/migrations-and-schema.md +79 -0
- package/assets/skills/lean/SKILL.md +110 -0
- package/assets/skills/lean/references/memory-and-processes.md +98 -0
- package/assets/skills/lean/references/playbooks.md +107 -0
- package/dist/app-sidecar-auth-broadcast.test.js +42 -7
- package/dist/app-sidecar-auth-broadcast.test.js.map +1 -1
- package/dist/app-sidecar.js +92 -28
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli/mcp.js +30 -10
- package/dist/cli/mcp.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -4
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +15 -0
- package/dist/config.js.map +1 -1
- package/dist/config.test.js +36 -1
- package/dist/config.test.js.map +1 -1
- package/dist/core/agent-session-compaction.test.js +60 -0
- package/dist/core/agent-session-compaction.test.js.map +1 -1
- package/dist/core/agent-session-review-coverage.test.js +51 -0
- package/dist/core/agent-session-review-coverage.test.js.map +1 -1
- package/dist/core/agent-session-verification-gate.test.d.ts +2 -0
- package/dist/core/agent-session-verification-gate.test.d.ts.map +1 -0
- package/dist/core/agent-session-verification-gate.test.js +135 -0
- package/dist/core/agent-session-verification-gate.test.js.map +1 -0
- package/dist/core/agent-session.d.ts +34 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +126 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agents.js +2 -2
- package/dist/core/agents.js.map +1 -1
- package/dist/core/api-benchmark.d.ts +1 -1
- package/dist/core/api-benchmark.js +2 -2
- package/dist/core/auth-providers.js +1 -1
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/autopilot-gate.test.js +7 -4
- package/dist/core/autopilot-gate.test.js.map +1 -1
- package/dist/core/bundled-agents.d.ts.map +1 -1
- package/dist/core/bundled-agents.js +4 -1
- package/dist/core/bundled-agents.js.map +1 -1
- package/dist/core/compaction/token-estimator.test.js +1 -1
- package/dist/core/event-bus.d.ts +11 -1
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +1 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/event-bus.test.d.ts +2 -0
- package/dist/core/event-bus.test.d.ts.map +1 -0
- package/dist/core/event-bus.test.js +33 -0
- package/dist/core/event-bus.test.js.map +1 -0
- package/dist/core/mcp/defaults.d.ts +3 -1
- package/dist/core/mcp/defaults.d.ts.map +1 -1
- package/dist/core/mcp/defaults.js +9 -2
- package/dist/core/mcp/defaults.js.map +1 -1
- package/dist/core/mcp/defaults.test.d.ts +2 -0
- package/dist/core/mcp/defaults.test.d.ts.map +1 -0
- package/dist/core/mcp/defaults.test.js +60 -0
- package/dist/core/mcp/defaults.test.js.map +1 -0
- package/dist/core/process-manager-wake.test.d.ts +2 -0
- package/dist/core/process-manager-wake.test.d.ts.map +1 -0
- package/dist/core/process-manager-wake.test.js +96 -0
- package/dist/core/process-manager-wake.test.js.map +1 -0
- package/dist/core/process-manager.d.ts +39 -1
- package/dist/core/process-manager.d.ts.map +1 -1
- package/dist/core/process-manager.js +146 -2
- package/dist/core/process-manager.js.map +1 -1
- package/dist/core/prompt-commands.d.ts.map +1 -1
- package/dist/core/prompt-commands.js.map +1 -1
- package/dist/core/provider-cache.e2e.test.d.ts +2 -0
- package/dist/core/provider-cache.e2e.test.d.ts.map +1 -0
- package/dist/core/provider-cache.e2e.test.js +125 -0
- package/dist/core/provider-cache.e2e.test.js.map +1 -0
- package/dist/core/session-injections.test.d.ts +2 -0
- package/dist/core/session-injections.test.d.ts.map +1 -0
- package/dist/core/session-injections.test.js +117 -0
- package/dist/core/session-injections.test.js.map +1 -0
- package/dist/core/session-reconstructability.test.d.ts +2 -0
- package/dist/core/session-reconstructability.test.d.ts.map +1 -0
- package/dist/core/session-reconstructability.test.js +105 -0
- package/dist/core/session-reconstructability.test.js.map +1 -0
- package/dist/core/settings-manager.d.ts +10 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +36 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills-routing.test.js +46 -0
- package/dist/core/skills-routing.test.js.map +1 -1
- package/dist/core/skills.js +1 -1
- package/dist/core/skills.js.map +1 -1
- package/dist/core/verification-gate.d.ts +55 -0
- package/dist/core/verification-gate.d.ts.map +1 -0
- package/dist/core/verification-gate.js +188 -0
- package/dist/core/verification-gate.js.map +1 -0
- package/dist/core/verification-gate.test.d.ts +2 -0
- package/dist/core/verification-gate.test.d.ts.map +1 -0
- package/dist/core/verification-gate.test.js +102 -0
- package/dist/core/verification-gate.test.js.map +1 -0
- package/dist/modes/acp-mode.test.js +6 -4
- package/dist/modes/acp-mode.test.js.map +1 -1
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +47 -1
- package/dist/system-prompt.js.map +1 -1
- package/dist/system-prompt.test.js +86 -6
- package/dist/system-prompt.test.js.map +1 -1
- package/dist/system-prompt.tiering.test.js +6 -3
- package/dist/system-prompt.tiering.test.js.map +1 -1
- package/dist/tools/bash.d.ts +4 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +57 -3
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/bash.test.js +37 -0
- package/dist/tools/bash.test.js.map +1 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +37 -4
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/edit.test.js +44 -0
- package/dist/tools/edit.test.js.map +1 -1
- package/dist/tools/prompt-hints.d.ts.map +1 -1
- package/dist/tools/prompt-hints.js +1 -0
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/read-only-bash.d.ts +6 -0
- package/dist/tools/read-only-bash.d.ts.map +1 -1
- package/dist/tools/read-only-bash.js +168 -9
- package/dist/tools/read-only-bash.js.map +1 -1
- package/dist/tools/read-only-bash.test.js +49 -0
- package/dist/tools/read-only-bash.test.js.map +1 -1
- package/dist/tools/skill.js +1 -0
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/tool-catalog.test.d.ts +2 -0
- package/dist/tools/tool-catalog.test.d.ts.map +1 -0
- package/dist/tools/tool-catalog.test.js +124 -0
- package/dist/tools/tool-catalog.test.js.map +1 -0
- package/dist/ui/App.d.ts +3 -0
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +39 -3
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/app-items.d.ts +2 -0
- package/dist/ui/app-items.d.ts.map +1 -1
- package/dist/ui/app-items.js +2 -0
- package/dist/ui/app-items.js.map +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts +1 -1
- package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
- package/dist/ui/hooks/useAgentLoop.js.map +1 -1
- package/dist/ui/login.js +1 -1
- package/dist/ui/login.js.map +1 -1
- package/dist/utils/image.d.ts.map +1 -1
- package/dist/utils/image.js.map +1 -1
- package/package.json +7 -7
|
@@ -15,6 +15,23 @@ describe("isReadOnlyCommand", () => {
|
|
|
15
15
|
["echo", "echo hi"],
|
|
16
16
|
["multi read pipe", "git log | head -20 | wc -l"],
|
|
17
17
|
["rg search", "rg -n pattern src"],
|
|
18
|
+
["git branch list", "git branch -a"],
|
|
19
|
+
["git branch list pattern", "git branch --list feat-*"],
|
|
20
|
+
["git tag list", "git tag -l"],
|
|
21
|
+
["git remote verbose", "git remote -v"],
|
|
22
|
+
["git remote get-url", "git remote get-url origin"],
|
|
23
|
+
["git remote show no-query", "git remote show -n origin"],
|
|
24
|
+
["git reflog", "git reflog -5"],
|
|
25
|
+
["find by name", "find . -name '*.ts' -maxdepth 2"],
|
|
26
|
+
["date read", "date"],
|
|
27
|
+
["date format read", "date '+%Y-%m-%d'"],
|
|
28
|
+
["sort read", "sort file.txt"],
|
|
29
|
+
["tree read", "tree src"],
|
|
30
|
+
["yq read", "yq '.a.b' config.yaml"],
|
|
31
|
+
["git log no-ext-diff", "git log --no-ext-diff"],
|
|
32
|
+
["git branch cluster listing", "git branch -av"],
|
|
33
|
+
["sort key read", "sort -k2,2 file.txt"],
|
|
34
|
+
["git tag numeric list", "git tag -n5"],
|
|
18
35
|
];
|
|
19
36
|
const blocked = [
|
|
20
37
|
["rm", "rm -rf x"],
|
|
@@ -36,6 +53,38 @@ describe("isReadOnlyCommand", () => {
|
|
|
36
53
|
["empty", ""],
|
|
37
54
|
["unknown command", "mytool --do-stuff"],
|
|
38
55
|
["awk write", "awk '{print > \"out\"}' f"],
|
|
56
|
+
["awk exec", "awk 'BEGIN { system(\"rm -rf x\") }' f"],
|
|
57
|
+
["git branch delete", "git branch -D main"],
|
|
58
|
+
["git branch move", "git branch -m old new"],
|
|
59
|
+
["git branch create", "git branch feature-x"],
|
|
60
|
+
["git tag delete", "git tag -d v1"],
|
|
61
|
+
["git tag create", "git tag v1.0"],
|
|
62
|
+
["git remote set-url", "git remote set-url origin https://evil.example"],
|
|
63
|
+
["git remote add", "git remote add upstream ../x"],
|
|
64
|
+
["git remote show queries", "git remote show origin"],
|
|
65
|
+
["git reflog expire", "git reflog expire --expire=now --all"],
|
|
66
|
+
["git diff ext-diff", "git diff --ext-diff"],
|
|
67
|
+
["git show textconv", "git show --textconv HEAD"],
|
|
68
|
+
["date set clock", "date -s '12:00:00'"],
|
|
69
|
+
["find delete", "find . -name '*.ts' -delete"],
|
|
70
|
+
["find exec", "find . -type f -exec rm {} +"],
|
|
71
|
+
["find fprint", "find . -fprintf /tmp/x '%p'"],
|
|
72
|
+
["sort output file", "sort -o out.txt in.txt"],
|
|
73
|
+
["tree output file", "tree -o tree.txt"],
|
|
74
|
+
["yq in place", "yq -i '.a = 1' config.yaml"],
|
|
75
|
+
["yq split", "yq '.[]' -s 'doc-~.yaml' in.yaml"],
|
|
76
|
+
["sed exec command", "sed '1e date' f"],
|
|
77
|
+
["sed exec flag", "sed 's/x/y/e' f"],
|
|
78
|
+
["sed compound exec", "sed 's/a/b/; e touch /tmp/pwn' f"],
|
|
79
|
+
["sed expression flag exec", "sed --expression='e date' f"],
|
|
80
|
+
["sed e as next token", "sed -e 'e date' f"],
|
|
81
|
+
["sed script from file", "sed -f transform.sed input.txt"],
|
|
82
|
+
["sed in-place with backup suffix", "sed -i.bak s/a/b/ f"],
|
|
83
|
+
["sed write command", "sed '2w /tmp/out' f"],
|
|
84
|
+
["sed attached value flag", "sed -es/a/b/ f"],
|
|
85
|
+
["git branch cluster delete", "git branch -df main"],
|
|
86
|
+
["sort cluster output", "sort -ro out.txt in.txt"],
|
|
87
|
+
["date cluster set", "date -su 12:00"],
|
|
39
88
|
];
|
|
40
89
|
it.each(allowed)("allows %s", (_label, command) => {
|
|
41
90
|
expect(isReadOnlyCommand(command)).toBe(true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-only-bash.test.js","sourceRoot":"","sources":["../../src/tools/read-only-bash.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,MAAM,OAAO,GAAoC;QAC/C,CAAC,YAAY,EAAE,YAAY,CAAC;QAC5B,CAAC,iBAAiB,EAAE,sBAAsB,CAAC;QAC3C,CAAC,YAAY,EAAE,eAAe,CAAC;QAC/B,CAAC,YAAY,EAAE,gBAAgB,CAAC;QAChC,CAAC,kBAAkB,EAAE,6BAA6B,CAAC;QACnD,CAAC,iBAAiB,EAAE,kBAAkB,CAAC;QACvC,CAAC,YAAY,EAAE,YAAY,CAAC;QAC5B,CAAC,UAAU,EAAE,iBAAiB,CAAC;QAC/B,CAAC,gBAAgB,EAAE,4BAA4B,CAAC;QAChD,CAAC,IAAI,EAAE,QAAQ,CAAC;QAChB,CAAC,MAAM,EAAE,SAAS,CAAC;QACnB,CAAC,iBAAiB,EAAE,4BAA4B,CAAC;QACjD,CAAC,WAAW,EAAE,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"read-only-bash.test.js","sourceRoot":"","sources":["../../src/tools/read-only-bash.test.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/skill.js
CHANGED
|
@@ -38,6 +38,7 @@ function generateSkillDescription(skills) {
|
|
|
38
38
|
.join("\n");
|
|
39
39
|
return (`Invoke a skill by name to get specialized instructions for a task. ` +
|
|
40
40
|
`Before acting, invoke a skill when the request matches its scope and respect explicit exclusions. ` +
|
|
41
|
+
`Invoke as soon as the work enters a skill's scope — while building or when checking — not only for reviews. ` +
|
|
41
42
|
`Match the work rather than the topic, skip it for routine or narrow changes, and do not re-invoke a skill already loaded in this conversation.\n\n` +
|
|
42
43
|
`Available skills:\n${list}`);
|
|
43
44
|
}
|
package/dist/tools/skill.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/tools/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IAC7D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;CACpF,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,uEAAuE;IACvE,qEAAqE;IACrE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvE,OAAO;QACL,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,wBAAwB,CAAC,MAAM,CAAC;QAC7C,UAAU;QACV,KAAK,CAAC,OAAO,CAAC,KAAK;YACjB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACtD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvD,OAAO,iBAAiB,KAAK,CAAC,KAAK,kCAAkC,SAAS,IAAI,MAAM,EAAE,CAAC;YAC7F,CAAC;YAED,MAAM,KAAK,GAAG,CAAC,wBAAwB,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;YACvD,IAAI,KAAK,CAAC,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,yBAAyB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAClE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAC9C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9C,CAAC;YACD,KAAK,CAAC,IAAI,CACR,yLAAyL,CAC1L,CAAC;YACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,MAAe;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,4DAA4D,CAAC;IACtE,CAAC;IAED,MAAM,IAAI,GAAG,MAAM;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,IAAI,gBAAgB,EAAE,CAAC;SACnE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO,CACL,qEAAqE;QACrE,oGAAoG;QACpG,oJAAoJ;QACpJ,sBAAsB,IAAI,EAAE,CAC7B,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"skill.js","sourceRoot":"","sources":["../../src/tools/skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,iCAAiC,CAAC;IAC7D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6CAA6C,CAAC;CACpF,CAAC,CAAC;AAEH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,uEAAuE;IACvE,qEAAqE;IACrE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAEvE,OAAO;QACL,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,wBAAwB,CAAC,MAAM,CAAC;QAC7C,UAAU;QACV,KAAK,CAAC,OAAO,CAAC,KAAK;YACjB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACtD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvD,OAAO,iBAAiB,KAAK,CAAC,KAAK,kCAAkC,SAAS,IAAI,MAAM,EAAE,CAAC;YAC7F,CAAC;YAED,MAAM,KAAK,GAAG,CAAC,wBAAwB,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;YACvD,IAAI,KAAK,CAAC,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,yBAAyB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAClE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;YAC9C,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,mBAAmB,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9C,CAAC;YACD,KAAK,CAAC,IAAI,CACR,yLAAyL,CAC1L,CAAC;YACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,wBAAwB,CAAC,MAAe;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,4DAA4D,CAAC;IACtE,CAAC;IAED,MAAM,IAAI,GAAG,MAAM;SAChB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,IAAI,gBAAgB,EAAE,CAAC;SACnE,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO,CACL,qEAAqE;QACrE,oGAAoG;QACpG,8GAA8G;QAC9G,oJAAoJ;QACpJ,sBAAsB,IAAI,EAAE,CAC7B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-catalog.test.d.ts","sourceRoot":"","sources":["../../src/tools/tool-catalog.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-catalog pin: the schemas this repo ships are the schemas we think we ship.
|
|
3
|
+
*
|
|
4
|
+
* Builds the REAL default tool array via `createTools()` — the same factory every
|
|
5
|
+
* session entry point (agent-session, CLI, interactive) uses — serializes each
|
|
6
|
+
* tool with `resolveToolSchema` (the exact encoding provider requests carry),
|
|
7
|
+
* and pins the canonicalized catalog against a committed snapshot.
|
|
8
|
+
*
|
|
9
|
+
* Why: an accidental schema/description edit is silent. It changes what every
|
|
10
|
+
* model sees on every request, and invalidates the cached prompt prefix, without
|
|
11
|
+
* failing any test that isn't explicitly looking. This test is the test that is
|
|
12
|
+
* explicitly looking (deepseek-harness takeaway: CI-verified tool catalog).
|
|
13
|
+
*
|
|
14
|
+
* Regenerate after an INTENTIONAL schema change:
|
|
15
|
+
* UPDATE_TOOL_CATALOG=1 pnpm vitest run tools/tool-catalog.test.ts
|
|
16
|
+
* and review the snapshot diff like any code diff.
|
|
17
|
+
*/
|
|
18
|
+
import { describe, it, expect } from "vitest";
|
|
19
|
+
import { createHash } from "node:crypto";
|
|
20
|
+
import fs from "node:fs";
|
|
21
|
+
import os from "node:os";
|
|
22
|
+
import path from "node:path";
|
|
23
|
+
import { resolveToolSchema } from "@prestyj/ai";
|
|
24
|
+
import { createTools } from "./index.js";
|
|
25
|
+
import { BUILTIN_TOOL_NAMES } from "./prompt-hints.js";
|
|
26
|
+
const SNAPSHOT_PATH = path.join(import.meta.dirname, "tool-catalog.snapshot.json");
|
|
27
|
+
/**
|
|
28
|
+
* Tools a bare `createTools()` call cannot register: each needs a session-level
|
|
29
|
+
* option (agent-session supplies it) rather than being a factory default. A name
|
|
30
|
+
* moving between this set and the built catalog is itself a reviewable diff —
|
|
31
|
+
* it changes the default model-visible surface.
|
|
32
|
+
*/
|
|
33
|
+
const OPT_IN_TOOLS = new Set([
|
|
34
|
+
"tool_search", // registered by AgentSession.ensureToolSearchTool()
|
|
35
|
+
"web_search", // provider-gated: non-anthropic providers only
|
|
36
|
+
"subagent", // needs agents[] + provider + model
|
|
37
|
+
"spawn_agent", // subagent control tools (same gate)
|
|
38
|
+
"send_message",
|
|
39
|
+
"followup_task",
|
|
40
|
+
"wait_agent",
|
|
41
|
+
"list_agents",
|
|
42
|
+
"interrupt_agent",
|
|
43
|
+
"skill", // needs configured skills
|
|
44
|
+
"enter_plan", // needs onEnterPlan callback
|
|
45
|
+
"exit_plan", // needs onExitPlan callback
|
|
46
|
+
"generate_image", // gated on OpenAI auth
|
|
47
|
+
]);
|
|
48
|
+
/** Deterministic JSON: object keys sorted at every depth, stable stringification. */
|
|
49
|
+
function canonical(value) {
|
|
50
|
+
return JSON.stringify(value, (_key, v) => v && typeof v === "object" && !Array.isArray(v)
|
|
51
|
+
? Object.fromEntries(Object.entries(v).sort(([a], [b]) => (a < b ? -1 : 1)))
|
|
52
|
+
: v);
|
|
53
|
+
}
|
|
54
|
+
async function buildCatalog() {
|
|
55
|
+
// Fixed temp cwd so no tool state leaks between runs; descriptions do not
|
|
56
|
+
// embed cwd (verified — factories use static description text).
|
|
57
|
+
const cwd = fs.mkdtempSync(path.join(os.tmpdir(), "ez-tool-catalog-"));
|
|
58
|
+
try {
|
|
59
|
+
const { tools } = await createTools(cwd);
|
|
60
|
+
return tools.map((tool) => {
|
|
61
|
+
const entry = {
|
|
62
|
+
name: tool.name,
|
|
63
|
+
description: tool.description,
|
|
64
|
+
schema: resolveToolSchema(tool),
|
|
65
|
+
};
|
|
66
|
+
return { ...entry, hash: createHash("sha256").update(canonical(entry)).digest("hex") };
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
fs.rmSync(cwd, { recursive: true, force: true });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
describe("tool catalog snapshot", () => {
|
|
74
|
+
it("pins the default tool catalog (schemas the model actually receives)", async () => {
|
|
75
|
+
const catalog = await buildCatalog();
|
|
76
|
+
// Duplicate names would mean a registry bug, not a schema change.
|
|
77
|
+
const names = catalog.map((t) => t.name);
|
|
78
|
+
expect(new Set(names).size, `duplicate tool names: ${names.join(", ")}`).toBe(names.length);
|
|
79
|
+
const snapshot = {
|
|
80
|
+
version: 1,
|
|
81
|
+
// Sorted for a stable, reviewable diff (order in the array is append-only
|
|
82
|
+
// and guarded separately by system-prompt.tiering.test.ts).
|
|
83
|
+
tools: [...catalog].sort((a, b) => (a.name < b.name ? -1 : 1)),
|
|
84
|
+
};
|
|
85
|
+
const serialized = `${JSON.stringify(snapshot, null, 2)}\n`;
|
|
86
|
+
if (process.env.UPDATE_TOOL_CATALOG === "1") {
|
|
87
|
+
fs.writeFileSync(SNAPSHOT_PATH, serialized);
|
|
88
|
+
console.log(`[tool-catalog] wrote ${catalog.length} tools to ${SNAPSHOT_PATH}`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
expect(fs.existsSync(SNAPSHOT_PATH), "snapshot missing — run with UPDATE_TOOL_CATALOG=1").toBe(true);
|
|
92
|
+
const pinned = fs.readFileSync(SNAPSHOT_PATH, "utf8");
|
|
93
|
+
// Compare per-tool hashes first: on mismatch the diff shows exactly WHICH
|
|
94
|
+
// tool changed, not a wall of JSON.
|
|
95
|
+
const pinnedNames = JSON.parse(pinned).tools.map((t) => t.name);
|
|
96
|
+
expect(names.sort()).toEqual(pinnedNames);
|
|
97
|
+
if (serialized !== pinned) {
|
|
98
|
+
const changed = snapshot.tools
|
|
99
|
+
.filter((t) => {
|
|
100
|
+
const pinnedTool = JSON.parse(pinned).tools.find((p) => p.name === t.name);
|
|
101
|
+
return !pinnedTool || pinnedTool.hash !== t.hash;
|
|
102
|
+
})
|
|
103
|
+
.map((t) => t.name);
|
|
104
|
+
const subject = changed.length > 0 ? changed.join(", ") : "snapshot formatting/extra keys";
|
|
105
|
+
throw new Error(`Tool catalog drifted: ${subject}. If intentional, regenerate with ` +
|
|
106
|
+
`UPDATE_TOOL_CATALOG=1 pnpm vitest run tools/tool-catalog.test.ts and review the diff. ` +
|
|
107
|
+
`Schema changes alter every request and invalidate cached prefixes — they deserve eyes.`);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
it("keeps the default surface complete: every built-in is either live or documented opt-in", async () => {
|
|
111
|
+
const catalog = await buildCatalog();
|
|
112
|
+
const live = new Set(catalog.map((t) => t.name));
|
|
113
|
+
for (const name of BUILTIN_TOOL_NAMES) {
|
|
114
|
+
expect(live.has(name) || OPT_IN_TOOLS.has(name), `${name} is neither in the default catalog nor the OPT_IN_TOOLS set — ` +
|
|
115
|
+
`the completeness guard can no longer account for it`).toBe(true);
|
|
116
|
+
}
|
|
117
|
+
// And the inverse: nothing rides along that the registry doesn't know.
|
|
118
|
+
const known = new Set([...BUILTIN_TOOL_NAMES, ...OPT_IN_TOOLS]);
|
|
119
|
+
for (const name of live) {
|
|
120
|
+
expect(known.has(name), `unregistered tool ${name} reached the default catalog`).toBe(true);
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=tool-catalog.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-catalog.test.js","sourceRoot":"","sources":["../../src/tools/tool-catalog.test.ts"],"names":[],"mappings":"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"}
|
package/dist/ui/App.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export interface AppProps {
|
|
|
49
49
|
showTokenUsage?: boolean;
|
|
50
50
|
idealReviewEnabled?: boolean;
|
|
51
51
|
autoApprovePlans?: boolean;
|
|
52
|
+
/** Kill switch for the pre-stop verification gate (default on). */
|
|
53
|
+
verificationGateEnabled?: boolean;
|
|
52
54
|
onSlashCommand?: (input: string) => Promise<string | null>;
|
|
53
55
|
loggedInProviders?: Provider[];
|
|
54
56
|
credentialsByProvider?: Record<string, {
|
|
@@ -190,6 +192,7 @@ export interface AppProps {
|
|
|
190
192
|
idealReviewEnabled?: boolean;
|
|
191
193
|
autoApprovePlans?: boolean;
|
|
192
194
|
taskRunning?: boolean;
|
|
195
|
+
verificationGateEnabled?: boolean;
|
|
193
196
|
};
|
|
194
197
|
}
|
|
195
198
|
export declare function App(props: AppProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/ui/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAqBA,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,aAAa,EAAoB,MAAM,aAAa,CAAC;AAEhG,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"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"}
|
package/dist/ui/App.js
CHANGED
|
@@ -15,6 +15,7 @@ import {} from "@prestyj/ai";
|
|
|
15
15
|
import { downscaleForPreview, extractMediaPaths } from "../utils/image.js";
|
|
16
16
|
import { buildSubAgentCompletionFollowUp, } from "../core/subagent-manager.js";
|
|
17
17
|
import { buildProcessCompletionFollowUp } from "../core/process-gate.js";
|
|
18
|
+
import { VerificationGate, isCodeFilePath, isVerificationCommand, } from "../core/verification-gate.js";
|
|
18
19
|
import { useAgentLoop } from "./hooks/useAgentLoop.js";
|
|
19
20
|
import { useTranscriptHistory } from "./hooks/useTranscriptHistory.js";
|
|
20
21
|
import { createWebSearchTool } from "../tools/web-search.js";
|
|
@@ -67,7 +68,7 @@ import { formatGoalVerifierCompletionEvent, formatGoalWorkerCompletionEvent, } f
|
|
|
67
68
|
import { buildGoalFinalSummarySections, buildGoalSummaryRows, goalPassedDetail, } from "./goal-summary.js";
|
|
68
69
|
import { addLinesChanged, buildSessionSummary, createSessionStats, recordServerToolCall, recordToolEnd, recordTurnEnd, } from "./session-summary.js";
|
|
69
70
|
import { compactHistory, getNextGeneratedItemId, isActiveItem, isSameAssistantText, normalizeAssistantText, partitionCompleted, pinStreamingTextBeforeToolBoundary, removeItemsWithIds, uniqueItemsById, } from "./item-helpers.js";
|
|
70
|
-
import { IDEAL_HOOK_NOTICE_TEXT, LOOP_BREAK_NOTICE_TEXT, REGROUNDING_NOTICE_TEXT, TRUNCATED_CONTINUING_NOTICE_TEXT, TRUNCATED_INCOMPLETE_NOTICE_TEXT, TRUNCATED_PROVIDER_ERROR_NOTICE_TEXT, TRUNCATED_REFUSAL_NOTICE_TEXT, lastVisibleTranscriptItem, } from "./app-items.js";
|
|
71
|
+
import { IDEAL_HOOK_NOTICE_TEXT, LOOP_BREAK_NOTICE_TEXT, REGROUNDING_NOTICE_TEXT, TRUNCATED_CONTINUING_NOTICE_TEXT, TRUNCATED_INCOMPLETE_NOTICE_TEXT, TRUNCATED_EMPTY_RESPONSE_NOTICE_TEXT, TRUNCATED_PROVIDER_ERROR_NOTICE_TEXT, TRUNCATED_REFUSAL_NOTICE_TEXT, lastVisibleTranscriptItem, } from "./app-items.js";
|
|
71
72
|
export { buildUserContentWithAttachments, routePromptCommandInput } from "./prompt-routing.js";
|
|
72
73
|
export { getNextThinkingLevel } from "./thinking-level.js";
|
|
73
74
|
export { getChatControlsLayoutDecision, getDoneFlushDecision, getScrollStabilizationDecision, getStaticHistoryKey, hasParagraphBreakLiveUserMessage, isTallLiveUserMessage, shouldHideHistoryForOverlayView, shouldHideStaticItemsForOverlayView, shouldStabilizeOverlayPaneRerender, shouldTopSpaceAfterPrintedAgentBoundary, shouldTopSpaceAssistantAfterToolBoundary, shouldTopSpaceStreamingAssistant, } from "./layout-decisions.js";
|
|
@@ -403,6 +404,9 @@ export function App(props) {
|
|
|
403
404
|
const idealReviewEnabledRef = useRef(idealReviewEnabled);
|
|
404
405
|
const [autoApprovePlansEnabled, setAutoApprovePlansEnabled] = useState(props.sessionStore?.autoApprovePlans ?? props.autoApprovePlans ?? true);
|
|
405
406
|
const autoApprovePlansEnabledRef = useRef(autoApprovePlansEnabled);
|
|
407
|
+
/** Pre-stop verification gate: code edited this run, nothing proved it since. */
|
|
408
|
+
const verificationGateRef = useRef(new VerificationGate());
|
|
409
|
+
const verificationGateEnabledRef = useRef(props.sessionStore?.verificationGateEnabled ?? props.verificationGateEnabled ?? true);
|
|
406
410
|
/**
|
|
407
411
|
* Languages whose style packs are currently injected into the system prompt.
|
|
408
412
|
* Grown by `maybeInjectLanguagePacks` after `write`/`bash` tool results when
|
|
@@ -1176,7 +1180,28 @@ export function App(props) {
|
|
|
1176
1180
|
return next;
|
|
1177
1181
|
});
|
|
1178
1182
|
}, []),
|
|
1179
|
-
onToolEnd: useCallback((toolCallId, name, result, isError, durationMs, details) => {
|
|
1183
|
+
onToolEnd: useCallback((toolCallId, name, result, isError, durationMs, details, args) => {
|
|
1184
|
+
// Verification-gate bookkeeping, mirroring AgentSession.trackHookEvent:
|
|
1185
|
+
// successful code mutations vs completed foreground verification runs.
|
|
1186
|
+
if (!isError && args) {
|
|
1187
|
+
const filePath = String(args.file_path ?? "");
|
|
1188
|
+
if ((name === "edit" || name === "write") && isCodeFilePath(filePath)) {
|
|
1189
|
+
verificationGateRef.current.recordMutation(filePath);
|
|
1190
|
+
}
|
|
1191
|
+
if (name === "bash" &&
|
|
1192
|
+
!args.run_in_background &&
|
|
1193
|
+
isVerificationCommand(String(args.command ?? ""))) {
|
|
1194
|
+
verificationGateRef.current.recordVerification();
|
|
1195
|
+
}
|
|
1196
|
+
// Reading the final output of an EXITED background verification run
|
|
1197
|
+
// counts as verification — mirrors AgentSession.trackHookEvent.
|
|
1198
|
+
if (name === "task_output") {
|
|
1199
|
+
const proc = props.processManager?.list().find((p) => p.id === args.id);
|
|
1200
|
+
if (proc && proc.exitCode !== null && isVerificationCommand(proc.command)) {
|
|
1201
|
+
verificationGateRef.current.recordVerification();
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1180
1205
|
recordToolEnd(sessionStatsRef.current, name, isError, durationMs);
|
|
1181
1206
|
setLiveToolFeed((prev) => prev.map((entry) => entry.id === toolCallId
|
|
1182
1207
|
? { ...entry, status: "done", isError, result, details }
|
|
@@ -1629,12 +1654,21 @@ export function App(props) {
|
|
|
1629
1654
|
if (gate.runStartedAt !== runStartedAt) {
|
|
1630
1655
|
gate.runStartedAt = runStartedAt;
|
|
1631
1656
|
gate.injected = 0;
|
|
1657
|
+
verificationGateRef.current.reset();
|
|
1632
1658
|
}
|
|
1633
1659
|
const processFollowUp = buildProcessCompletionFollowUp(props.processManager?.list() ?? [], runStartedAt, gate.injected);
|
|
1634
1660
|
if (processFollowUp) {
|
|
1635
1661
|
gate.injected += 1;
|
|
1636
1662
|
return processFollowUp;
|
|
1637
1663
|
}
|
|
1664
|
+
// Verification gate: code was edited but no test/typecheck/lint/build
|
|
1665
|
+
// completed since the last edit — block "done" until it runs (or the
|
|
1666
|
+
// budget escalates to an honest unverified statement).
|
|
1667
|
+
if (verificationGateEnabledRef.current) {
|
|
1668
|
+
const verificationFollowUp = verificationGateRef.current.followUp();
|
|
1669
|
+
if (verificationFollowUp)
|
|
1670
|
+
return verificationFollowUp;
|
|
1671
|
+
}
|
|
1638
1672
|
const steps = planStepsRef.current;
|
|
1639
1673
|
if (steps.length === 0 || !approvedPlanPathRef.current)
|
|
1640
1674
|
return null;
|
|
@@ -1673,7 +1707,9 @@ export function App(props) {
|
|
|
1673
1707
|
: TRUNCATED_INCOMPLETE_NOTICE_TEXT
|
|
1674
1708
|
: reason === "refusal"
|
|
1675
1709
|
? TRUNCATED_REFUSAL_NOTICE_TEXT
|
|
1676
|
-
:
|
|
1710
|
+
: reason === "empty_response"
|
|
1711
|
+
? TRUNCATED_EMPTY_RESPONSE_NOTICE_TEXT
|
|
1712
|
+
: TRUNCATED_PROVIDER_ERROR_NOTICE_TEXT;
|
|
1677
1713
|
setLiveItems((prev) => [
|
|
1678
1714
|
...prev,
|
|
1679
1715
|
{ kind: "ideal_hook", text, tone: "warning", id: getId() },
|