@kenkaiiii/ggcoder 5.44.3 → 5.46.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 +3 -1
- 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 +97 -0
- package/assets/skills/lean/references/playbooks.md +107 -0
- 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 +2 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +41 -0
- package/dist/core/agent-session.js.map +1 -1
- 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/settings-manager.d.ts +1 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +5 -0
- package/dist/core/settings-manager.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/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/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/ui/App.d.ts +3 -0
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +35 -1
- package/dist/ui/App.js.map +1 -1
- package/package.json +4 -4
|
@@ -5,6 +5,12 @@
|
|
|
5
5
|
* blocked), false positives are not (a mutating command would slip through).
|
|
6
6
|
* Plan mode gates bash on `isReadOnlyCommand`; anything this function cannot
|
|
7
7
|
* prove is read-only falls back to the existing plan-mode block.
|
|
8
|
+
*
|
|
9
|
+
* A command-name allowlist alone is not proof: several allowlisted utilities
|
|
10
|
+
* mutate through flags (`git branch -D`, `find -delete`, `date -s`,
|
|
11
|
+
* `sort -o file`), take create-shaped operands (`git tag v1`), or execute
|
|
12
|
+
* repo-configured code (`git diff --ext-diff`). Each carries a per-flag
|
|
13
|
+
* policy below.
|
|
8
14
|
*/
|
|
9
15
|
/** Read-only utilities allowed as the leading command word of every segment. */
|
|
10
16
|
const READ_ONLY_COMMANDS = new Set([
|
|
@@ -48,7 +54,9 @@ const READ_ONLY_COMMANDS = new Set([
|
|
|
48
54
|
"readlink",
|
|
49
55
|
"jq",
|
|
50
56
|
"yq",
|
|
51
|
-
|
|
57
|
+
// No awk: its `system()` built-in is arbitrary shell execution and cannot
|
|
58
|
+
// be screened by flags. Deny-by-default costs a blocked read-only call at
|
|
59
|
+
// worst; allowing it costs plan mode running `rm`.
|
|
52
60
|
]);
|
|
53
61
|
/** Read-only git subcommands. Everything else (commit, push, …) is rejected. */
|
|
54
62
|
const READ_ONLY_GIT_SUBCOMMANDS = new Set([
|
|
@@ -99,9 +107,74 @@ function leadingWord(segment) {
|
|
|
99
107
|
function tokens(segment) {
|
|
100
108
|
return segment.split(/\s+/).filter((token) => token.length > 0);
|
|
101
109
|
}
|
|
110
|
+
/** True if any token equals `flag` or is `flag=value`. */
|
|
111
|
+
function hasFlag(parts, ...flags) {
|
|
112
|
+
return parts.some((part) => flags.some((flag) => part === flag || part.startsWith(`${flag}=`)));
|
|
113
|
+
}
|
|
114
|
+
/** Non-flag tokens of `parts`. */
|
|
115
|
+
function positionals(parts) {
|
|
116
|
+
return parts.filter((part) => !part.startsWith("-"));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* True if any token is a cluster of short flags containing one of `letters`
|
|
120
|
+
* (`-df` = `-d -f`; GNU getopt and git parse-options both accept clusters, so
|
|
121
|
+
* exact-token flag checks alone can be bypassed with `sort -ro`, `date -su`,
|
|
122
|
+
* `git branch -df`). Long flags (`--…`) never match: two leading dashes fail
|
|
123
|
+
* the letter run.
|
|
124
|
+
*/
|
|
125
|
+
function hasClusteredShortFlag(parts, letters) {
|
|
126
|
+
return parts.some((part) => {
|
|
127
|
+
const match = /^-([a-zA-Z]+)\d*$/.exec(part);
|
|
128
|
+
return match !== null && [...match[1]].some((ch) => letters.has(ch));
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// --- git subcommand flag policies -------------------------------------------
|
|
132
|
+
/** Listing flags that make `git branch`/`git tag` operands filters rather
|
|
133
|
+
* than create/delete targets. Without one, a positional operand creates. */
|
|
134
|
+
const GIT_LIST_FLAGS = ["--list", "-l"];
|
|
135
|
+
/** Short-flag letters that make `git branch` mutate or execute (d/D delete, m/M
|
|
136
|
+
* move, c/C copy, f force, u upstream). `a`/`v` listing letters excluded. */
|
|
137
|
+
const GIT_BRANCH_DANGEROUS_LETTERS = new Set(["d", "D", "m", "M", "c", "C", "f", "u"]);
|
|
138
|
+
/** Same for `git tag` (d/D delete, f force, a annotate, s sign, u local-user,
|
|
139
|
+
* m message, e edit). `n`/`l` listing letters excluded. */
|
|
140
|
+
const GIT_TAG_DANGEROUS_LETTERS = new Set(["d", "D", "f", "a", "s", "u", "m", "e"]);
|
|
141
|
+
function isReadOnlyGitBranch(rest) {
|
|
142
|
+
if (hasFlag(rest, "-d", "-D", "--delete", "-m", "-M", "--move", "-c", "-C", "--copy", "-f", "--force", "-u", "--set-upstream-to", "--unset-upstream", "--edit-description") ||
|
|
143
|
+
hasClusteredShortFlag(rest, GIT_BRANCH_DANGEROUS_LETTERS)) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
return positionals(rest).length === 0 || hasFlag(rest, ...GIT_LIST_FLAGS);
|
|
147
|
+
}
|
|
148
|
+
function isReadOnlyGitTag(rest) {
|
|
149
|
+
if (hasFlag(rest, "-d", "--delete", "-f", "--force", "-a", "--annotate", "-s", "--sign", "-u", "--local-user", "-m", "--message", "-e", "--edit") ||
|
|
150
|
+
hasClusteredShortFlag(rest, GIT_TAG_DANGEROUS_LETTERS)) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
return positionals(rest).length === 0 || hasFlag(rest, ...GIT_LIST_FLAGS);
|
|
154
|
+
}
|
|
155
|
+
function isReadOnlyGitRemote(rest) {
|
|
156
|
+
const operands = positionals(rest);
|
|
157
|
+
if (operands.length === 0)
|
|
158
|
+
return true; // bare `git remote [-v]` lists
|
|
159
|
+
const sub = operands[0];
|
|
160
|
+
if (sub === "get-url")
|
|
161
|
+
return true;
|
|
162
|
+
// `git remote show` contacts the remote (network, askpass helpers);
|
|
163
|
+
// read-only only with --no-query.
|
|
164
|
+
if (sub === "show")
|
|
165
|
+
return hasFlag(rest, "-n", "--no-query");
|
|
166
|
+
return false; // add, rename, remove, set-url, set-head, prune, update …
|
|
167
|
+
}
|
|
168
|
+
function isReadOnlyGitReflog(rest) {
|
|
169
|
+
// `expire` and `delete` rewrite reflog history.
|
|
170
|
+
const sub = positionals(rest)[0];
|
|
171
|
+
return sub !== "expire" && sub !== "delete";
|
|
172
|
+
}
|
|
102
173
|
function isReadOnlyGit(segment) {
|
|
103
174
|
const parts = tokens(segment);
|
|
104
|
-
// parts[0] === "git"; find the first non-flag token as the subcommand.
|
|
175
|
+
// parts[0] === "git"; find the first non-flag token as the subcommand. A
|
|
176
|
+
// global flag with a value (`git -C /tmp branch`) puts the value here and
|
|
177
|
+
// denies — fail-closed, and `-C` escapes the workspace anyway.
|
|
105
178
|
let subcommand = "";
|
|
106
179
|
for (let i = 1; i < parts.length; i += 1) {
|
|
107
180
|
const part = parts[i];
|
|
@@ -112,17 +185,102 @@ function isReadOnlyGit(segment) {
|
|
|
112
185
|
}
|
|
113
186
|
if (!READ_ONLY_GIT_SUBCOMMANDS.has(subcommand))
|
|
114
187
|
return false;
|
|
115
|
-
|
|
188
|
+
const rest = parts.slice(parts.indexOf(subcommand) + 1);
|
|
116
189
|
if (subcommand === "config") {
|
|
117
|
-
|
|
118
|
-
return
|
|
190
|
+
// `git config` is read-only only with --get (or --list / --get-all).
|
|
191
|
+
return hasFlag(rest, "--get", "--get-all", "--list", "-l");
|
|
192
|
+
}
|
|
193
|
+
// log/show/diff can execute repo-configured external diff/textconv
|
|
194
|
+
// drivers. The --no- forms (which disable them) stay allowed: exact match.
|
|
195
|
+
if (subcommand === "log" || subcommand === "show" || subcommand === "diff") {
|
|
196
|
+
if (rest.includes("--ext-diff") || rest.includes("--textconv"))
|
|
197
|
+
return false;
|
|
119
198
|
}
|
|
199
|
+
if (subcommand === "branch")
|
|
200
|
+
return isReadOnlyGitBranch(rest);
|
|
201
|
+
if (subcommand === "tag")
|
|
202
|
+
return isReadOnlyGitTag(rest);
|
|
203
|
+
if (subcommand === "remote")
|
|
204
|
+
return isReadOnlyGitRemote(rest);
|
|
205
|
+
if (subcommand === "reflog")
|
|
206
|
+
return isReadOnlyGitReflog(rest);
|
|
120
207
|
return true;
|
|
121
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* sed script text that could execute a command or write a file: GNU's `e`
|
|
211
|
+
* command (`e cmd`, `1e`, `/re/e`, `{ e ...`), the `s///...e` exec flag, or
|
|
212
|
+
* the `w`/`W` write commands. Applied to ALL candidate script text - every
|
|
213
|
+
* non-flag token joined plus long-flag `=values` - so quoting or splitting a
|
|
214
|
+
* script across whitespace cannot hide the command from it. False positives
|
|
215
|
+
* (a filename shaped like `1e`) merely block a read-only call.
|
|
216
|
+
*/
|
|
217
|
+
function sedScriptUnsafe(text) {
|
|
218
|
+
// `e`/`w`/`W` at a command position: script start, after `;` `{` `}`/`)`, or
|
|
219
|
+
// directly after an address (`1e`, `$e`, `/re/e`, `2w out`).
|
|
220
|
+
if (/(^|[\s;{}()])([0-9,$~/\\][^\s;{}]*)?[ewW](\s|$|\\)/.test(text))
|
|
221
|
+
return true;
|
|
222
|
+
// Exec flag on a substitution, any delimiter: `s/x/y/e`, `s#x#y#ge`.
|
|
223
|
+
if (/s(.).*\1[0-9A-Za-z]*e/.test(text))
|
|
224
|
+
return true;
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
122
227
|
function isReadOnlySed(segment) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
228
|
+
const rest = tokens(segment).slice(1);
|
|
229
|
+
// In-place edit (`-i`, `-i.bak`, `--in-place`) or a script read from a file
|
|
230
|
+
// (`-f`, `--file`) - the file's contents cannot be inspected here.
|
|
231
|
+
if (rest.some((part) => part.startsWith("-i") ||
|
|
232
|
+
part.startsWith("--in-place") ||
|
|
233
|
+
part.startsWith("-f") ||
|
|
234
|
+
part.startsWith("--file"))) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
// A short-flag cluster longer than two characters carries an attached value
|
|
238
|
+
// that cannot be attributed (`-es/a/b/`, `-i.bak`, even the pure `-nE`);
|
|
239
|
+
// only single-letter flags pass. Long `--flags` are words, not clusters.
|
|
240
|
+
if (rest.some((part) => /^-[a-zA-Z]./.test(part)))
|
|
241
|
+
return false;
|
|
242
|
+
// Fail closed on compound scripts: `;`/`{`/`}` chain commands across token
|
|
243
|
+
// boundaries (`sed 's/a/b/; e x' f`), so compound scripts are never provably
|
|
244
|
+
// read-only here.
|
|
245
|
+
const scriptText = rest
|
|
246
|
+
.filter((part) => !part.startsWith("-"))
|
|
247
|
+
.map((part) => part.replace(/^['"]|['"]$/g, ""))
|
|
248
|
+
.join(" ");
|
|
249
|
+
const flagValues = rest
|
|
250
|
+
.filter((part) => part.startsWith("--") && part.includes("="))
|
|
251
|
+
.map((part) => part.slice(part.indexOf("=") + 1).replace(/^['"]|['"]$/g, ""))
|
|
252
|
+
.join(" ");
|
|
253
|
+
const all = `${scriptText} ${flagValues}`;
|
|
254
|
+
if (/;|\{|\}/.test(all))
|
|
255
|
+
return false;
|
|
256
|
+
return !sedScriptUnsafe(all);
|
|
257
|
+
}
|
|
258
|
+
// --- plain-utility flag policies --------------------------------------------
|
|
259
|
+
function isReadOnlyUtility(command, parts) {
|
|
260
|
+
const rest = parts.slice(1);
|
|
261
|
+
switch (command) {
|
|
262
|
+
case "date":
|
|
263
|
+
// `-s`/`--set` sets the system clock, also when clustered (`-su`).
|
|
264
|
+
return !hasFlag(rest, "-s", "--set") && !hasClusteredShortFlag(rest, new Set(["s"]));
|
|
265
|
+
case "find":
|
|
266
|
+
// -exec/-ok (and their -dir variants) run arbitrary commands; the rest
|
|
267
|
+
// write files.
|
|
268
|
+
return !rest.some((part) => part === "-delete" ||
|
|
269
|
+
part.startsWith("-exec") ||
|
|
270
|
+
part.startsWith("-ok") ||
|
|
271
|
+
part.startsWith("-fprint") ||
|
|
272
|
+
part === "-fls");
|
|
273
|
+
case "sort":
|
|
274
|
+
// `-o` writes a file, also when clustered (`-ro`).
|
|
275
|
+
return !hasFlag(rest, "-o", "--output") && !hasClusteredShortFlag(rest, new Set(["o"]));
|
|
276
|
+
case "tree":
|
|
277
|
+
return !hasFlag(rest, "-o", "--output-file") && !hasClusteredShortFlag(rest, new Set(["o"]));
|
|
278
|
+
case "yq":
|
|
279
|
+
// -i edits in place; --split-exp/-s write one file per document.
|
|
280
|
+
return !hasFlag(rest, "-i", "--in-place", "-s", "--split-exp");
|
|
281
|
+
default:
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
126
284
|
}
|
|
127
285
|
export function hasUnsafeShellSyntax(segment) {
|
|
128
286
|
return DANGEROUS_TOKENS.some((token) => segment.includes(token)) || /&\s*$/.test(segment);
|
|
@@ -131,12 +289,13 @@ function isReadOnlySegment(segment) {
|
|
|
131
289
|
// Keep shell-syntax policy shared with semantic verification classification.
|
|
132
290
|
if (hasUnsafeShellSyntax(segment))
|
|
133
291
|
return false;
|
|
292
|
+
const parts = tokens(segment);
|
|
134
293
|
const command = leadingWord(segment);
|
|
135
294
|
if (command === "git")
|
|
136
295
|
return isReadOnlyGit(segment);
|
|
137
296
|
if (command === "sed")
|
|
138
297
|
return isReadOnlySed(segment);
|
|
139
|
-
return READ_ONLY_COMMANDS.has(command);
|
|
298
|
+
return READ_ONLY_COMMANDS.has(command) && isReadOnlyUtility(command, parts);
|
|
140
299
|
}
|
|
141
300
|
/**
|
|
142
301
|
* Returns true only when every segment of the command is provably read-only.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-only-bash.js","sourceRoot":"","sources":["../../src/tools/read-only-bash.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"read-only-bash.js","sourceRoot":"","sources":["../../src/tools/read-only-bash.ts"],"names":[],"mappings":"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"}
|
|
@@ -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"}
|
package/dist/ui/App.d.ts
CHANGED
|
@@ -36,6 +36,8 @@ export interface AppProps {
|
|
|
36
36
|
version: string;
|
|
37
37
|
showTokenUsage?: boolean;
|
|
38
38
|
idealReviewEnabled?: boolean;
|
|
39
|
+
/** Kill switch for the pre-stop verification gate (default on). */
|
|
40
|
+
verificationGateEnabled?: boolean;
|
|
39
41
|
onSlashCommand?: (input: string) => Promise<string | null>;
|
|
40
42
|
loggedInProviders?: Provider[];
|
|
41
43
|
credentialsByProvider?: Record<string, {
|
|
@@ -165,6 +167,7 @@ export interface AppProps {
|
|
|
165
167
|
planMode?: boolean;
|
|
166
168
|
sessionStats?: SessionStats;
|
|
167
169
|
idealReviewEnabled?: boolean;
|
|
170
|
+
verificationGateEnabled?: boolean;
|
|
168
171
|
};
|
|
169
172
|
}
|
|
170
173
|
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":"AAoBA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,aAAa,EAEnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,qBAAqB,CAAC;AACtE,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
|
@@ -14,6 +14,7 @@ import {} from "@kenkaiiii/gg-ai";
|
|
|
14
14
|
import { downscaleForPreview, extractMediaPaths } from "../utils/image.js";
|
|
15
15
|
import { buildSubAgentCompletionFollowUp, } from "../core/subagent-manager.js";
|
|
16
16
|
import { buildProcessCompletionFollowUp } from "../core/process-gate.js";
|
|
17
|
+
import { VerificationGate, isCodeFilePath, isVerificationCommand, } from "../core/verification-gate.js";
|
|
17
18
|
import { useAgentLoop } from "./hooks/useAgentLoop.js";
|
|
18
19
|
import { useTranscriptHistory } from "./hooks/useTranscriptHistory.js";
|
|
19
20
|
import { createWebSearchTool } from "../tools/web-search.js";
|
|
@@ -253,6 +254,9 @@ export function App(props) {
|
|
|
253
254
|
createSessionStats({ sessionId: props.sessionStore?.sessionId ?? props.sessionId }));
|
|
254
255
|
const [idealReviewEnabled, setIdealReviewEnabled] = useState(props.sessionStore?.idealReviewEnabled ?? props.idealReviewEnabled ?? true);
|
|
255
256
|
const idealReviewEnabledRef = useRef(idealReviewEnabled);
|
|
257
|
+
/** Pre-stop verification gate: code edited this run, nothing proved it since. */
|
|
258
|
+
const verificationGateRef = useRef(new VerificationGate());
|
|
259
|
+
const verificationGateEnabledRef = useRef(props.sessionStore?.verificationGateEnabled ?? props.verificationGateEnabled ?? true);
|
|
256
260
|
/**
|
|
257
261
|
* Languages whose style packs are currently injected into the system prompt.
|
|
258
262
|
* Grown by `maybeInjectLanguagePacks` after `write`/`bash` tool results when
|
|
@@ -929,7 +933,28 @@ export function App(props) {
|
|
|
929
933
|
return next;
|
|
930
934
|
});
|
|
931
935
|
}, []),
|
|
932
|
-
onToolEnd: useCallback((toolCallId, name, result, isError, durationMs, details) => {
|
|
936
|
+
onToolEnd: useCallback((toolCallId, name, result, isError, durationMs, details, args) => {
|
|
937
|
+
// Verification-gate bookkeeping, mirroring AgentSession.trackHookEvent:
|
|
938
|
+
// successful code mutations vs completed foreground verification runs.
|
|
939
|
+
if (!isError && args) {
|
|
940
|
+
const filePath = String(args.file_path ?? "");
|
|
941
|
+
if ((name === "edit" || name === "write") && isCodeFilePath(filePath)) {
|
|
942
|
+
verificationGateRef.current.recordMutation(filePath);
|
|
943
|
+
}
|
|
944
|
+
if (name === "bash" &&
|
|
945
|
+
!args.run_in_background &&
|
|
946
|
+
isVerificationCommand(String(args.command ?? ""))) {
|
|
947
|
+
verificationGateRef.current.recordVerification();
|
|
948
|
+
}
|
|
949
|
+
// Reading the final output of an EXITED background verification run
|
|
950
|
+
// counts as verification — mirrors AgentSession.trackHookEvent.
|
|
951
|
+
if (name === "task_output") {
|
|
952
|
+
const proc = props.processManager?.list().find((p) => p.id === args.id);
|
|
953
|
+
if (proc && proc.exitCode !== null && isVerificationCommand(proc.command)) {
|
|
954
|
+
verificationGateRef.current.recordVerification();
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
}
|
|
933
958
|
recordToolEnd(sessionStatsRef.current, name, isError, durationMs);
|
|
934
959
|
setLiveToolFeed((prev) => prev.map((entry) => entry.id === toolCallId
|
|
935
960
|
? { ...entry, status: "done", isError, result, details }
|
|
@@ -1339,12 +1364,21 @@ export function App(props) {
|
|
|
1339
1364
|
if (gate.runStartedAt !== runStartedAt) {
|
|
1340
1365
|
gate.runStartedAt = runStartedAt;
|
|
1341
1366
|
gate.injected = 0;
|
|
1367
|
+
verificationGateRef.current.reset();
|
|
1342
1368
|
}
|
|
1343
1369
|
const processFollowUp = buildProcessCompletionFollowUp(props.processManager?.list() ?? [], runStartedAt, gate.injected);
|
|
1344
1370
|
if (processFollowUp) {
|
|
1345
1371
|
gate.injected += 1;
|
|
1346
1372
|
return processFollowUp;
|
|
1347
1373
|
}
|
|
1374
|
+
// Verification gate: code was edited but no test/typecheck/lint/build
|
|
1375
|
+
// completed since the last edit — block "done" until it runs (or the
|
|
1376
|
+
// budget escalates to an honest unverified statement).
|
|
1377
|
+
if (verificationGateEnabledRef.current) {
|
|
1378
|
+
const verificationFollowUp = verificationGateRef.current.followUp();
|
|
1379
|
+
if (verificationFollowUp)
|
|
1380
|
+
return verificationFollowUp;
|
|
1381
|
+
}
|
|
1348
1382
|
const steps = planStepsRef.current;
|
|
1349
1383
|
if (steps.length === 0 || !approvedPlanPathRef.current)
|
|
1350
1384
|
return null;
|