@namzu/sdk 52.4.0 → 52.6.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 +33 -0
- package/dist/authorization/gate.d.ts +11 -0
- package/dist/authorization/gate.d.ts.map +1 -1
- package/dist/authorization/gate.js +35 -0
- package/dist/authorization/gate.js.map +1 -1
- package/dist/authorization/removal.js +11 -6
- package/dist/authorization/removal.js.map +1 -1
- package/dist/authorization/rules.d.ts.map +1 -1
- package/dist/authorization/rules.js +30 -2
- package/dist/authorization/rules.js.map +1 -1
- package/dist/authorization/shell-paths.d.ts +20 -0
- package/dist/authorization/shell-paths.d.ts.map +1 -1
- package/dist/authorization/shell-paths.js +254 -52
- package/dist/authorization/shell-paths.js.map +1 -1
- package/dist/bridge/acp/server.d.ts +8 -0
- package/dist/bridge/acp/server.d.ts.map +1 -1
- package/dist/bridge/acp/server.js +7 -0
- package/dist/bridge/acp/server.js.map +1 -1
- package/dist/manager/resident/outbox.d.ts +4 -4
- package/dist/public-runtime.d.ts +2 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +4 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +1 -0
- package/dist/public-types.d.ts.map +1 -1
- package/dist/runtime/query/auto-review/classifier.d.ts +130 -0
- package/dist/runtime/query/auto-review/classifier.d.ts.map +1 -0
- package/dist/runtime/query/auto-review/classifier.js +244 -0
- package/dist/runtime/query/auto-review/classifier.js.map +1 -0
- package/dist/runtime/query/auto-review/index.d.ts +7 -0
- package/dist/runtime/query/auto-review/index.d.ts.map +1 -0
- package/dist/runtime/query/auto-review/index.js +4 -0
- package/dist/runtime/query/auto-review/index.js.map +1 -0
- package/dist/runtime/query/auto-review/prompt.d.ts +20 -0
- package/dist/runtime/query/auto-review/prompt.d.ts.map +1 -0
- package/dist/runtime/query/auto-review/prompt.js +89 -0
- package/dist/runtime/query/auto-review/prompt.js.map +1 -0
- package/dist/runtime/query/auto-review/rules.d.ts +49 -0
- package/dist/runtime/query/auto-review/rules.d.ts.map +1 -0
- package/dist/runtime/query/auto-review/rules.js +81 -0
- package/dist/runtime/query/auto-review/rules.js.map +1 -0
- package/dist/runtime/query/auto-review/transcript.d.ts +59 -0
- package/dist/runtime/query/auto-review/transcript.d.ts.map +1 -0
- package/dist/runtime/query/auto-review/transcript.js +116 -0
- package/dist/runtime/query/auto-review/transcript.js.map +1 -0
- package/dist/runtime/query/auto-review/verdict.d.ts +21 -0
- package/dist/runtime/query/auto-review/verdict.d.ts.map +1 -0
- package/dist/runtime/query/auto-review/verdict.js +45 -0
- package/dist/runtime/query/auto-review/verdict.js.map +1 -0
- package/dist/runtime/query/executor.d.ts +7 -0
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +26 -2
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.js +2 -2
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +0 -9
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js +11 -2
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +39 -0
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/path-escalation.d.ts.map +1 -1
- package/dist/runtime/query/path-escalation.js +43 -10
- package/dist/runtime/query/path-escalation.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +14 -0
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +88 -1
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +504 -11
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +2 -0
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/classifier-input.d.ts +9 -0
- package/dist/tools/builtins/classifier-input.d.ts.map +1 -0
- package/dist/tools/builtins/classifier-input.js +20 -0
- package/dist/tools/builtins/classifier-input.js.map +1 -0
- package/dist/tools/builtins/code-analysis.d.ts +2 -0
- package/dist/tools/builtins/code-analysis.d.ts.map +1 -1
- package/dist/tools/builtins/code-analysis.js +196 -119
- package/dist/tools/builtins/code-analysis.js.map +1 -1
- package/dist/tools/builtins/computer-use.d.ts +10 -10
- package/dist/tools/builtins/edit-apply.d.ts.map +1 -1
- package/dist/tools/builtins/edit-apply.js +30 -12
- package/dist/tools/builtins/edit-apply.js.map +1 -1
- package/dist/tools/builtins/edit-match.d.ts +47 -0
- package/dist/tools/builtins/edit-match.d.ts.map +1 -0
- package/dist/tools/builtins/edit-match.js +262 -0
- package/dist/tools/builtins/edit-match.js.map +1 -0
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +12 -0
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/monitor.d.ts.map +1 -1
- package/dist/tools/builtins/monitor.js +3 -0
- package/dist/tools/builtins/monitor.js.map +1 -1
- package/dist/tools/builtins/web.d.ts.map +1 -1
- package/dist/tools/builtins/web.js +3 -0
- package/dist/tools/builtins/web.js.map +1 -1
- package/dist/tools/builtins/write-file.d.ts.map +1 -1
- package/dist/tools/builtins/write-file.js +6 -0
- package/dist/tools/builtins/write-file.js.map +1 -1
- package/dist/tools/defineTool.d.ts +2 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +1 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/types/acp/index.d.ts +7 -0
- package/dist/types/acp/index.d.ts.map +1 -1
- package/dist/types/code-analysis/index.d.ts +54 -3
- package/dist/types/code-analysis/index.d.ts.map +1 -1
- package/dist/types/hitl/index.d.ts +45 -1
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/tool/index.d.ts +16 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/package.json +1 -1
- package/src/authorization/gate.ts +35 -0
- package/src/authorization/removal.ts +12 -6
- package/src/authorization/rules.ts +27 -2
- package/src/authorization/shell-paths.ts +264 -51
- package/src/bridge/acp/server.ts +20 -0
- package/src/public-runtime.ts +18 -0
- package/src/public-types.ts +11 -0
- package/src/runtime/query/auto-review/classifier.ts +404 -0
- package/src/runtime/query/auto-review/index.ts +23 -0
- package/src/runtime/query/auto-review/prompt.ts +97 -0
- package/src/runtime/query/auto-review/rules.ts +106 -0
- package/src/runtime/query/auto-review/transcript.ts +159 -0
- package/src/runtime/query/auto-review/verdict.ts +50 -0
- package/src/runtime/query/executor.ts +29 -2
- package/src/runtime/query/index.ts +2 -2
- package/src/runtime/query/iteration/phases/context.ts +17 -3
- package/src/runtime/query/iteration/phases/tool-review.ts +41 -0
- package/src/runtime/query/path-escalation.ts +44 -9
- package/src/runtime/query/resume-pending.ts +14 -0
- package/src/runtime/query/review-policy.ts +591 -14
- package/src/tools/builtins/bash.ts +3 -0
- package/src/tools/builtins/classifier-input.ts +19 -0
- package/src/tools/builtins/code-analysis.ts +211 -119
- package/src/tools/builtins/edit-apply.ts +31 -12
- package/src/tools/builtins/edit-match.ts +274 -0
- package/src/tools/builtins/edit.ts +13 -0
- package/src/tools/builtins/monitor.ts +4 -0
- package/src/tools/builtins/web.ts +3 -0
- package/src/tools/builtins/write-file.ts +6 -0
- package/src/tools/defineTool.ts +3 -0
- package/src/types/acp/index.ts +7 -0
- package/src/types/code-analysis/index.ts +51 -3
- package/src/types/hitl/index.ts +49 -1
- package/src/types/tool/index.ts +17 -0
|
@@ -38,6 +38,8 @@ export interface ShellInvocation {
|
|
|
38
38
|
readonly program: string
|
|
39
39
|
/** Its arguments, as the shell passes them. */
|
|
40
40
|
readonly args: readonly ShellWord[]
|
|
41
|
+
/** The redirections written on this command itself, when the lexer attached them. */
|
|
42
|
+
readonly redirections?: readonly ShellRedirection[]
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
/** What the lexer found, in the shape this module and the removal check share. */
|
|
@@ -50,13 +52,20 @@ export interface ShellReading {
|
|
|
50
52
|
|
|
51
53
|
const EXEC_FLAGS = new Set(['-exec', '-execdir', '-ok', '-okdir'])
|
|
52
54
|
|
|
53
|
-
function invocationOf(
|
|
55
|
+
function invocationOf(
|
|
56
|
+
words: readonly ShellWord[],
|
|
57
|
+
redirections?: readonly ShellRedirection[],
|
|
58
|
+
): ShellInvocation | undefined {
|
|
54
59
|
if (words.length === 0) return undefined
|
|
55
60
|
const step = unwrapReexecChain(words)
|
|
56
61
|
if (!('rest' in step)) return undefined
|
|
57
62
|
const [head, ...args] = step.rest
|
|
58
63
|
if (head === undefined || head.expands) return undefined
|
|
59
|
-
return {
|
|
64
|
+
return {
|
|
65
|
+
program: basename(head.value),
|
|
66
|
+
args,
|
|
67
|
+
...(redirections !== undefined ? { redirections } : {}),
|
|
68
|
+
}
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
/** Every program a line runs, and every redirection it carries. */
|
|
@@ -64,7 +73,7 @@ export function readShellLine(line: string, dialect: ShellDialect): ShellReading
|
|
|
64
73
|
const lexed = lexShellCommandLine(line, { dialect })
|
|
65
74
|
const invocations: ShellInvocation[] = []
|
|
66
75
|
for (const command of lexed.commands) {
|
|
67
|
-
const own = invocationOf(command.words.slice(command.assignments))
|
|
76
|
+
const own = invocationOf(command.words.slice(command.assignments), command.redirections)
|
|
68
77
|
if (own === undefined) continue
|
|
69
78
|
invocations.push(own)
|
|
70
79
|
if (own.program !== 'find') continue
|
|
@@ -102,8 +111,20 @@ export interface ShellPathUse {
|
|
|
102
111
|
readonly via: string
|
|
103
112
|
/** True when the word is decided at runtime and `path` is not what it will be. */
|
|
104
113
|
readonly unresolved: boolean
|
|
114
|
+
/**
|
|
115
|
+
* Where a relative `path` starts from, when an earlier `cd` in the line moved
|
|
116
|
+
* the shell. Absent: the directory the line began in. Only a `cd` to one
|
|
117
|
+
* literal relative directory is followed; anything else is `unknown`.
|
|
118
|
+
*/
|
|
119
|
+
readonly directory?: ShellDirectory
|
|
105
120
|
}
|
|
106
121
|
|
|
122
|
+
/** Where a `cd` earlier in the line left the shell, relative to where the line began. */
|
|
123
|
+
export type ShellDirectory =
|
|
124
|
+
| { readonly relative: string }
|
|
125
|
+
/** A `cd` to a runtime-decided, absolute, `~` or `-` target, or a `pushd`/`popd`/`chdir`. */
|
|
126
|
+
| { readonly unknown: true }
|
|
127
|
+
|
|
107
128
|
export interface ShellPathAccess {
|
|
108
129
|
readonly uses: readonly ShellPathUse[]
|
|
109
130
|
/** A `cd`, `pushd`, `popd` or `chdir` runs somewhere in the line. */
|
|
@@ -150,6 +171,105 @@ function operands(args: Args): ShellWord[] {
|
|
|
150
171
|
return out
|
|
151
172
|
}
|
|
152
173
|
|
|
174
|
+
/** `value` as a word that keeps whether `from` will still be expanded by the shell. */
|
|
175
|
+
function derived(from: ShellWord, value: string): ShellWord {
|
|
176
|
+
return { ...from, text: value, value }
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Operands of `cp` and `mv`. GNU lets a flag follow an operand, and the
|
|
181
|
+
* destination can be a flag's value: `--target-directory=D`, `--target-directory D`,
|
|
182
|
+
* `-tD`, `-t D`, also inside a cluster (`-at D`, `-rtD`). Reading the operands
|
|
183
|
+
* alone would miss the attached and the trailing forms.
|
|
184
|
+
*/
|
|
185
|
+
function copyOperands(args: Args): ShellWord[] {
|
|
186
|
+
const out: ShellWord[] = []
|
|
187
|
+
let afterDashes = false
|
|
188
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
189
|
+
const arg = args[i] as ShellWord
|
|
190
|
+
const text = arg.value
|
|
191
|
+
if (afterDashes || text === '-' || !text.startsWith('-')) {
|
|
192
|
+
out.push(arg)
|
|
193
|
+
continue
|
|
194
|
+
}
|
|
195
|
+
if (text === '--') {
|
|
196
|
+
afterDashes = true
|
|
197
|
+
continue
|
|
198
|
+
}
|
|
199
|
+
if (text.startsWith('--')) {
|
|
200
|
+
const eq = text.indexOf('=')
|
|
201
|
+
const name = eq >= 0 ? text.slice(0, eq) : text
|
|
202
|
+
if (name === '--target-directory') {
|
|
203
|
+
if (eq >= 0) out.push(derived(arg, text.slice(eq + 1)))
|
|
204
|
+
else if (args[i + 1] !== undefined) {
|
|
205
|
+
out.push(args[i + 1] as ShellWord)
|
|
206
|
+
i += 1
|
|
207
|
+
}
|
|
208
|
+
} else if (name === '--suffix' && eq < 0) i += 1
|
|
209
|
+
continue
|
|
210
|
+
}
|
|
211
|
+
for (let j = 1; j < text.length; j += 1) {
|
|
212
|
+
const letter = text[j] as string
|
|
213
|
+
if (letter !== 't' && letter !== 'S') continue
|
|
214
|
+
const rest = text.slice(j + 1)
|
|
215
|
+
if (letter === 't') {
|
|
216
|
+
if (rest !== '') out.push(derived(arg, rest))
|
|
217
|
+
else if (args[i + 1] !== undefined) {
|
|
218
|
+
out.push(args[i + 1] as ShellWord)
|
|
219
|
+
i += 1
|
|
220
|
+
}
|
|
221
|
+
} else if (rest === '') i += 1
|
|
222
|
+
break
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return out
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* The files `touch` reads: `--reference=F`, `--reference F`, `-rF`, `-r F`
|
|
230
|
+
* (also in a cluster). They are not written, but a path outside the roots is
|
|
231
|
+
* the same question whichever way it is opened.
|
|
232
|
+
*/
|
|
233
|
+
function touchReferences(args: Args): ShellWord[] {
|
|
234
|
+
const out: ShellWord[] = []
|
|
235
|
+
let afterDashes = false
|
|
236
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
237
|
+
const arg = args[i] as ShellWord
|
|
238
|
+
const text = arg.value
|
|
239
|
+
if (afterDashes || text === '-' || !text.startsWith('-')) continue
|
|
240
|
+
if (text === '--') {
|
|
241
|
+
afterDashes = true
|
|
242
|
+
continue
|
|
243
|
+
}
|
|
244
|
+
if (text.startsWith('--')) {
|
|
245
|
+
const eq = text.indexOf('=')
|
|
246
|
+
const name = eq >= 0 ? text.slice(0, eq) : text
|
|
247
|
+
if (name === '--reference') {
|
|
248
|
+
if (eq >= 0) out.push(derived(arg, text.slice(eq + 1)))
|
|
249
|
+
else if (args[i + 1] !== undefined) {
|
|
250
|
+
out.push(args[i + 1] as ShellWord)
|
|
251
|
+
i += 1
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
continue
|
|
255
|
+
}
|
|
256
|
+
for (let j = 1; j < text.length; j += 1) {
|
|
257
|
+
const letter = text[j] as string
|
|
258
|
+
if (letter !== 'r' && letter !== 'd' && letter !== 't') continue
|
|
259
|
+
const rest = text.slice(j + 1)
|
|
260
|
+
if (letter === 'r') {
|
|
261
|
+
if (rest !== '') out.push(derived(arg, rest))
|
|
262
|
+
else if (args[i + 1] !== undefined) {
|
|
263
|
+
out.push(args[i + 1] as ShellWord)
|
|
264
|
+
i += 1
|
|
265
|
+
}
|
|
266
|
+
} else if (rest === '') i += 1
|
|
267
|
+
break
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return out
|
|
271
|
+
}
|
|
272
|
+
|
|
153
273
|
interface FlagTable {
|
|
154
274
|
readonly booleanShort: string
|
|
155
275
|
readonly valuedShort: string
|
|
@@ -681,11 +801,11 @@ const EXTRACTORS: Readonly<Record<string, (args: Args) => ShellWord[]>> = {
|
|
|
681
801
|
ls: lsOperands,
|
|
682
802
|
find: findOperands,
|
|
683
803
|
mkdir: operands,
|
|
684
|
-
touch:
|
|
804
|
+
touch: touchOperands,
|
|
685
805
|
rm: operands,
|
|
686
806
|
rmdir: operands,
|
|
687
|
-
mv:
|
|
688
|
-
cp:
|
|
807
|
+
mv: copyOperands,
|
|
808
|
+
cp: copyOperands,
|
|
689
809
|
cat: operands,
|
|
690
810
|
head: operands,
|
|
691
811
|
tail: operands,
|
|
@@ -845,6 +965,38 @@ const EXTRACTORS: Readonly<Record<string, (args: Args) => ShellWord[]>> = {
|
|
|
845
965
|
git: gitOperands,
|
|
846
966
|
}
|
|
847
967
|
|
|
968
|
+
/**
|
|
969
|
+
* Operands of `touch`: the files it changes, with the values of `-d`, `-t` and
|
|
970
|
+
* `-r`/`--reference` taken out (they are a date, a stamp and a file that is read).
|
|
971
|
+
*/
|
|
972
|
+
function touchOperands(args: Args): ShellWord[] {
|
|
973
|
+
const out: ShellWord[] = []
|
|
974
|
+
let afterDashes = false
|
|
975
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
976
|
+
const arg = args[i] as ShellWord
|
|
977
|
+
const text = arg.value
|
|
978
|
+
if (afterDashes || text === '-' || !text.startsWith('-')) {
|
|
979
|
+
out.push(arg)
|
|
980
|
+
continue
|
|
981
|
+
}
|
|
982
|
+
if (text === '--') {
|
|
983
|
+
afterDashes = true
|
|
984
|
+
continue
|
|
985
|
+
}
|
|
986
|
+
if (text.startsWith('--')) {
|
|
987
|
+
if (/^--(?:reference|date|time)$/.test(text)) i += 1
|
|
988
|
+
continue
|
|
989
|
+
}
|
|
990
|
+
for (let j = 1; j < text.length; j += 1) {
|
|
991
|
+
if ('rdt'.includes(text[j] as string)) {
|
|
992
|
+
if (j === text.length - 1) i += 1
|
|
993
|
+
break
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
return out
|
|
998
|
+
}
|
|
999
|
+
|
|
848
1000
|
/** Commands that create or change what their operands name. `sed` is added per call when it edits in place. */
|
|
849
1001
|
const WRITERS = new Set(['mkdir', 'touch', 'rm', 'rmdir', 'mv', 'cp', 'tee'])
|
|
850
1002
|
|
|
@@ -860,68 +1012,129 @@ function editsInPlace(args: Args): boolean {
|
|
|
860
1012
|
})
|
|
861
1013
|
}
|
|
862
1014
|
|
|
1015
|
+
/** The directory a line is in after `invocation`, given the one before it. */
|
|
1016
|
+
function directoryAfter(
|
|
1017
|
+
before: ShellDirectory | undefined,
|
|
1018
|
+
invocation: ShellInvocation,
|
|
1019
|
+
): ShellDirectory {
|
|
1020
|
+
if (before !== undefined && 'unknown' in before) return before
|
|
1021
|
+
if (invocation.program !== 'cd') return { unknown: true }
|
|
1022
|
+
const operands = invocation.args.filter((a) => a.expands || !/^-[LPe@]+$/.test(a.value))
|
|
1023
|
+
const [target, ...extra] = operands
|
|
1024
|
+
if (target === undefined || extra.length > 0 || target.expands || target.value === '') {
|
|
1025
|
+
return { unknown: true }
|
|
1026
|
+
}
|
|
1027
|
+
const value = target.value
|
|
1028
|
+
if (value === '-' || value === '--' || value.startsWith('/') || value.startsWith('~')) {
|
|
1029
|
+
return { unknown: true }
|
|
1030
|
+
}
|
|
1031
|
+
const base = before?.relative
|
|
1032
|
+
return { relative: base === undefined ? value : `${base}/${value}` }
|
|
1033
|
+
}
|
|
1034
|
+
|
|
863
1035
|
/**
|
|
864
1036
|
* The paths `reading` names: positional arguments of the commands in the
|
|
865
1037
|
* table, and the targets of its redirections.
|
|
1038
|
+
*
|
|
1039
|
+
* Each use carries the directory an earlier literal `cd` left the shell in
|
|
1040
|
+
* (see {@link ShellPathUse.directory}), so a caller can tell
|
|
1041
|
+
* `cd packages/sdk && echo x > out.txt` from `cd "$X" && echo x > out.txt`.
|
|
866
1042
|
*/
|
|
867
1043
|
export function shellPathAccess(reading: ShellReading): ShellPathAccess {
|
|
868
1044
|
const uses: ShellPathUse[] = []
|
|
869
1045
|
let changesDirectory = false
|
|
870
|
-
|
|
1046
|
+
let directory: ShellDirectory | undefined
|
|
1047
|
+
const covered = new Set<ShellRedirection>()
|
|
1048
|
+
for (const invocation of reading.invocations) {
|
|
1049
|
+
const { program, args } = invocation
|
|
871
1050
|
if (CD_PROGRAMS.has(program)) changesDirectory = true
|
|
872
1051
|
const extract = EXTRACTORS[program]
|
|
873
|
-
if (extract
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
1052
|
+
if (extract !== undefined) {
|
|
1053
|
+
const access: PathAccess =
|
|
1054
|
+
WRITERS.has(program) || (program === 'sed' && editsInPlace(args)) ? 'write' : 'read'
|
|
1055
|
+
for (const arg of extract(args)) {
|
|
1056
|
+
if (arg.value === '' || isHarmlessTarget(arg.value)) continue
|
|
1057
|
+
uses.push({
|
|
1058
|
+
path: arg.value,
|
|
1059
|
+
access,
|
|
1060
|
+
via: program,
|
|
1061
|
+
unresolved: expandsAtRuntime(arg),
|
|
1062
|
+
...(directory !== undefined ? { directory } : {}),
|
|
1063
|
+
})
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
if (program === 'touch') {
|
|
1067
|
+
for (const arg of touchReferences(args)) {
|
|
1068
|
+
if (arg.value === '' || isHarmlessTarget(arg.value)) continue
|
|
1069
|
+
uses.push({
|
|
1070
|
+
path: arg.value,
|
|
1071
|
+
access: 'read',
|
|
1072
|
+
via: program,
|
|
1073
|
+
unresolved: expandsAtRuntime(arg),
|
|
1074
|
+
...(directory !== undefined ? { directory } : {}),
|
|
1075
|
+
})
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
for (const redirection of invocation.redirections ?? []) {
|
|
1079
|
+
covered.add(redirection)
|
|
1080
|
+
pushRedirection(uses, redirection, directory)
|
|
884
1081
|
}
|
|
1082
|
+
if (CD_PROGRAMS.has(program)) directory = directoryAfter(directory, invocation)
|
|
885
1083
|
}
|
|
886
1084
|
for (const redirection of reading.redirections) {
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
1085
|
+
if (covered.has(redirection)) continue
|
|
1086
|
+
// Not tied to a command the reader saw (a compound command's own), so
|
|
1087
|
+
// where it runs cannot be told once a `cd` is in the line.
|
|
1088
|
+
pushRedirection(uses, redirection, changesDirectory ? { unknown: true } : undefined)
|
|
1089
|
+
}
|
|
1090
|
+
return { uses, changesDirectory }
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
function pushRedirection(
|
|
1094
|
+
uses: ShellPathUse[],
|
|
1095
|
+
redirection: ShellRedirection,
|
|
1096
|
+
directory: ShellDirectory | undefined,
|
|
1097
|
+
): void {
|
|
1098
|
+
const target = redirection.target
|
|
1099
|
+
if (target.value === '' || isHarmlessTarget(target.value)) return
|
|
1100
|
+
const where = directory !== undefined ? { directory } : {}
|
|
1101
|
+
switch (redirection.operator) {
|
|
1102
|
+
case '>':
|
|
1103
|
+
case '>>':
|
|
1104
|
+
case '>|':
|
|
1105
|
+
case '&>':
|
|
1106
|
+
case '&>>':
|
|
1107
|
+
case '<>':
|
|
1108
|
+
uses.push({
|
|
1109
|
+
path: target.value,
|
|
1110
|
+
access: 'write',
|
|
1111
|
+
via: 'redirect',
|
|
1112
|
+
unresolved: expandsAtRuntime(target),
|
|
1113
|
+
...where,
|
|
1114
|
+
})
|
|
1115
|
+
break
|
|
1116
|
+
case '>&':
|
|
1117
|
+
// `>&2` and `>&-` duplicate or close a descriptor; any other word is a file.
|
|
1118
|
+
if (!/^(?:\d+-?|-)$/.test(target.value)) {
|
|
896
1119
|
uses.push({
|
|
897
1120
|
path: target.value,
|
|
898
1121
|
access: 'write',
|
|
899
1122
|
via: 'redirect',
|
|
900
1123
|
unresolved: expandsAtRuntime(target),
|
|
1124
|
+
...where,
|
|
901
1125
|
})
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
uses.push({
|
|
916
|
-
path: target.value,
|
|
917
|
-
access: 'read',
|
|
918
|
-
via: 'redirect',
|
|
919
|
-
unresolved: expandsAtRuntime(target),
|
|
920
|
-
})
|
|
921
|
-
break
|
|
922
|
-
default:
|
|
923
|
-
break
|
|
924
|
-
}
|
|
1126
|
+
}
|
|
1127
|
+
break
|
|
1128
|
+
case '<':
|
|
1129
|
+
uses.push({
|
|
1130
|
+
path: target.value,
|
|
1131
|
+
access: 'read',
|
|
1132
|
+
via: 'redirect',
|
|
1133
|
+
unresolved: expandsAtRuntime(target),
|
|
1134
|
+
...where,
|
|
1135
|
+
})
|
|
1136
|
+
break
|
|
1137
|
+
default:
|
|
1138
|
+
break
|
|
925
1139
|
}
|
|
926
|
-
return { uses, changesDirectory }
|
|
927
1140
|
}
|
package/src/bridge/acp/server.ts
CHANGED
|
@@ -142,6 +142,14 @@ export interface AcpServerOptions {
|
|
|
142
142
|
readonly supportsPromptAttachments?: boolean
|
|
143
143
|
/** The host applies optional effort and permission settings to the exact turn. */
|
|
144
144
|
readonly supportsPromptOptions?: boolean
|
|
145
|
+
/**
|
|
146
|
+
* Which of the newer review modes, `bypass` and `classify`, the gateway
|
|
147
|
+
* applies when a prompt asks for one in its options. Omitted, a prompt that
|
|
148
|
+
* asks for either is refused with an error that says so, before any turn
|
|
149
|
+
* starts, rather than reaching a gateway that cannot honour it. Advertised
|
|
150
|
+
* as `promptPermissionModes` at initialization.
|
|
151
|
+
*/
|
|
152
|
+
readonly promptPermissionModes?: readonly ('bypass' | 'classify')[]
|
|
145
153
|
/** Emit planning notifications only to clients declaring namzu/tasks. */
|
|
146
154
|
readonly supportsTaskNotifications?: boolean
|
|
147
155
|
readonly transport: MCPTransport
|
|
@@ -465,6 +473,9 @@ export class ACPServer {
|
|
|
465
473
|
protocolVersion: ACP_PROTOCOL_VERSION,
|
|
466
474
|
...(this.options.supportsPromptAttachments ? { promptAttachments: true } : {}),
|
|
467
475
|
...(this.options.supportsPromptOptions ? { promptOptions: true } : {}),
|
|
476
|
+
...(this.options.supportsPromptOptions && this.options.promptPermissionModes?.length
|
|
477
|
+
? { promptPermissionModes: [...this.options.promptPermissionModes] }
|
|
478
|
+
: {}),
|
|
468
479
|
agentInfo: this.options.agentInfo,
|
|
469
480
|
// From the registry, per call. A hard-coded list here would be a
|
|
470
481
|
// second definition of the command surface.
|
|
@@ -850,6 +861,15 @@ export class ACPServer {
|
|
|
850
861
|
(permissionMode !== undefined && !isReviewMode(permissionMode))
|
|
851
862
|
)
|
|
852
863
|
throw new AcpError(ACP_ERROR_CODES.INVALID_PARAMS, 'Invalid prompt settings.')
|
|
864
|
+
if (
|
|
865
|
+
(permissionMode === 'bypass' || permissionMode === 'classify') &&
|
|
866
|
+
this.options.promptPermissionModes?.includes(permissionMode) !== true
|
|
867
|
+
) {
|
|
868
|
+
throw new AcpError(
|
|
869
|
+
ACP_ERROR_CODES.INVALID_PARAMS,
|
|
870
|
+
`This agent does not accept the "${permissionMode}" permission mode in prompt settings.`,
|
|
871
|
+
)
|
|
872
|
+
}
|
|
853
873
|
return {
|
|
854
874
|
...(effort
|
|
855
875
|
? { effort: effort as NonNullable<AcpSessionPromptParams['options']>['effort'] }
|
package/src/public-runtime.ts
CHANGED
|
@@ -1431,7 +1431,11 @@ export { AUTO_APPROVE_POLICY_NAME } from './runtime/query/approval-policy.js'
|
|
|
1431
1431
|
// accept-edits, plan, strict — as an `ApprovalPolicy`. See
|
|
1432
1432
|
// `runtime/query/review-policy.ts`.
|
|
1433
1433
|
export {
|
|
1434
|
+
ACCEPT_EDITS_SHELL_COMMANDS,
|
|
1434
1435
|
ACCEPT_EDITS_TOOLS,
|
|
1436
|
+
ASK_RULE_UNATTENDED_REFUSAL,
|
|
1437
|
+
CLASSIFIER_SAFE_TOOLS,
|
|
1438
|
+
CLASSIFIER_TRANSCRIPT_TOO_LONG_FEEDBACK,
|
|
1435
1439
|
OUTSIDE_ROOTS_UNATTENDED_REFUSAL,
|
|
1436
1440
|
PLAN_MODE_REFUSAL,
|
|
1437
1441
|
REVIEW_EXEMPT_WRITES,
|
|
@@ -1440,12 +1444,26 @@ export {
|
|
|
1440
1444
|
SCREEN_CONSENT_DECLINED_FEEDBACK,
|
|
1441
1445
|
SCREEN_CONSENT_UNATTENDED_REFUSAL,
|
|
1442
1446
|
STRICT_MODE_REFUSAL,
|
|
1447
|
+
UNFINISHED_CHECK_UNATTENDED_REFUSAL,
|
|
1443
1448
|
batchNeedsReview,
|
|
1444
1449
|
createReviewHandler,
|
|
1445
1450
|
createReviewPolicy,
|
|
1446
1451
|
isReviewExempt,
|
|
1447
1452
|
isReviewMode,
|
|
1453
|
+
modeReviewsAllowedCalls,
|
|
1448
1454
|
} from './runtime/query/review-policy.js'
|
|
1455
|
+
// The model that decides, in the `classify` review mode, what a person would
|
|
1456
|
+
// otherwise be asked. See `runtime/query/auto-review/`.
|
|
1457
|
+
export {
|
|
1458
|
+
AUTO_REVIEW_DEFAULTS_MARKER,
|
|
1459
|
+
DEFAULT_ALLOW as DEFAULT_AUTO_REVIEW_ALLOW,
|
|
1460
|
+
DEFAULT_AUTO_REVIEW_LIMITS,
|
|
1461
|
+
DEFAULT_HARD_DENY as DEFAULT_AUTO_REVIEW_HARD_DENY,
|
|
1462
|
+
DEFAULT_SOFT_DENY as DEFAULT_AUTO_REVIEW_SOFT_DENY,
|
|
1463
|
+
autoReviewBlockedFeedback,
|
|
1464
|
+
createAutoReviewClassifier,
|
|
1465
|
+
resolveAutoReviewRules,
|
|
1466
|
+
} from './runtime/query/auto-review/index.js'
|
|
1449
1467
|
// What the model is told when a person declines a call without words of their own.
|
|
1450
1468
|
export { DECLINED_TOOL_CALL_FEEDBACK } from './runtime/query/declined.js'
|
|
1451
1469
|
|
package/src/public-types.ts
CHANGED
|
@@ -436,6 +436,17 @@ export type {
|
|
|
436
436
|
CompactionSkipReason,
|
|
437
437
|
} from './compaction/plan.js'
|
|
438
438
|
|
|
439
|
+
export type {
|
|
440
|
+
AutoReviewClassifier,
|
|
441
|
+
AutoReviewClassifierOptions,
|
|
442
|
+
AutoReviewDecision,
|
|
443
|
+
AutoReviewLimits,
|
|
444
|
+
AutoReviewRequest,
|
|
445
|
+
AutoReviewRules,
|
|
446
|
+
AutoReviewStage,
|
|
447
|
+
ResolvedAutoReviewRules,
|
|
448
|
+
} from './runtime/query/auto-review/index.js'
|
|
449
|
+
|
|
439
450
|
export type {
|
|
440
451
|
ReviewExemption,
|
|
441
452
|
ReviewMode,
|