@dungle-scrubs/harness-cli-normalizer 0.4.6 → 0.5.1
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 +43 -3
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +5 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +65 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/help.d.ts +2 -2
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +25 -7
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/inspect.d.ts.map +1 -1
- package/dist/cli/inspect.js +63 -24
- package/dist/cli/inspect.js.map +1 -1
- package/dist/cli/refuse.d.ts +14 -0
- package/dist/cli/refuse.d.ts.map +1 -0
- package/dist/cli/refuse.js +38 -0
- package/dist/cli/refuse.js.map +1 -0
- package/dist/cli/resume-guard.d.ts +18 -0
- package/dist/cli/resume-guard.d.ts.map +1 -0
- package/dist/cli/resume-guard.js +26 -0
- package/dist/cli/resume-guard.js.map +1 -0
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +16 -54
- package/dist/cli/run.js.map +1 -1
- package/dist/interpretation/argv.d.ts +3 -0
- package/dist/interpretation/argv.d.ts.map +1 -1
- package/dist/interpretation/argv.js +2 -0
- package/dist/interpretation/argv.js.map +1 -1
- package/dist/interpretation/hints.d.ts.map +1 -1
- package/dist/interpretation/hints.js +4 -0
- package/dist/interpretation/hints.js.map +1 -1
- package/dist/interpretation/resolve-options.d.ts.map +1 -1
- package/dist/interpretation/resolve-options.js +124 -3
- package/dist/interpretation/resolve-options.js.map +1 -1
- package/dist/interpretation/support.d.ts +1 -0
- package/dist/interpretation/support.d.ts.map +1 -1
- package/dist/interpretation/support.js +29 -0
- package/dist/interpretation/support.js.map +1 -1
- package/dist/interpretation/tool-selection.d.ts +6 -16
- package/dist/interpretation/tool-selection.d.ts.map +1 -1
- package/dist/interpretation/tool-selection.js +205 -85
- package/dist/interpretation/tool-selection.js.map +1 -1
- package/dist/interpretation/tool-vocabulary.d.ts +38 -0
- package/dist/interpretation/tool-vocabulary.d.ts.map +1 -0
- package/dist/interpretation/tool-vocabulary.js +142 -0
- package/dist/interpretation/tool-vocabulary.js.map +1 -0
- package/dist/interpretation/turn-options.d.ts.map +1 -1
- package/dist/interpretation/turn-options.js +107 -2
- package/dist/interpretation/turn-options.js.map +1 -1
- package/dist/interpretation/vocabulary.d.ts +1 -0
- package/dist/interpretation/vocabulary.d.ts.map +1 -1
- package/dist/interpretation/vocabulary.js +5 -0
- package/dist/interpretation/vocabulary.js.map +1 -1
- package/dist/knowledge/claude-code.d.ts.map +1 -1
- package/dist/knowledge/claude-code.js +14 -13
- package/dist/knowledge/claude-code.js.map +1 -1
- package/dist/knowledge/codex.d.ts.map +1 -1
- package/dist/knowledge/codex.js +10 -4
- package/dist/knowledge/codex.js.map +1 -1
- package/dist/knowledge/descriptor.d.ts +16 -1
- package/dist/knowledge/descriptor.d.ts.map +1 -1
- package/dist/knowledge/descriptor.js +18 -1
- package/dist/knowledge/descriptor.js.map +1 -1
- package/dist/knowledge/muse.d.ts.map +1 -1
- package/dist/knowledge/muse.js +18 -3
- package/dist/knowledge/muse.js.map +1 -1
- package/dist/knowledge/overrides.d.ts.map +1 -1
- package/dist/knowledge/overrides.js +3 -2
- package/dist/knowledge/overrides.js.map +1 -1
- package/dist/knowledge/pi.d.ts.map +1 -1
- package/dist/knowledge/pi.js +8 -7
- package/dist/knowledge/pi.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/args.ts +5 -0
- package/src/cli/config.ts +88 -0
- package/src/cli/help.ts +25 -7
- package/src/cli/inspect.ts +61 -20
- package/src/cli/refuse.ts +50 -0
- package/src/cli/resume-guard.ts +35 -0
- package/src/cli/run.ts +16 -71
- package/src/interpretation/argv.ts +5 -0
- package/src/interpretation/hints.ts +8 -0
- package/src/interpretation/resolve-options.ts +129 -3
- package/src/interpretation/support.ts +30 -0
- package/src/interpretation/tool-selection.ts +225 -101
- package/src/interpretation/tool-vocabulary.ts +183 -0
- package/src/interpretation/turn-options.ts +99 -2
- package/src/interpretation/vocabulary.ts +5 -0
- package/src/knowledge/claude-code.ts +14 -13
- package/src/knowledge/codex.ts +10 -4
- package/src/knowledge/descriptor.ts +37 -2
- package/src/knowledge/muse.ts +18 -3
- package/src/knowledge/overrides.ts +4 -2
- package/src/knowledge/pi.ts +8 -7
|
@@ -14,7 +14,9 @@ import { DISCOVERY_FACETS, resolveRender, TURN_OPTION_KEYS } from "../knowledge/
|
|
|
14
14
|
import type { DiscoveryOptions, TurnOptions } from "./argv.js";
|
|
15
15
|
import { hintFor } from "./hints.js";
|
|
16
16
|
import { ArgvRefusalError } from "./refusal.js";
|
|
17
|
-
import {
|
|
17
|
+
import { renderToolSelection } from "./tool-selection.js";
|
|
18
|
+
import { READ_PRESET } from "./tool-vocabulary.js";
|
|
19
|
+
import { CLEAN_SELECTOR, resolveModel, validateAccess, validateEffort } from "./vocabulary.js";
|
|
18
20
|
|
|
19
21
|
// TOML-quoted value for config-kv: JSON.stringify is sufficient for the
|
|
20
22
|
// closed vocabularies that may use it (enum, effort) - no value contains a
|
|
@@ -34,6 +36,20 @@ export const renderTurnOptions = (
|
|
|
34
36
|
): string[] => {
|
|
35
37
|
const sequences: string[][] = [];
|
|
36
38
|
|
|
39
|
+
const accessRaw = opts.access;
|
|
40
|
+
if (accessRaw !== undefined) {
|
|
41
|
+
const v = validateAccess(accessRaw);
|
|
42
|
+
if (!v.ok) {
|
|
43
|
+
throw new ArgvRefusalError({
|
|
44
|
+
issue: "invalid-option-value",
|
|
45
|
+
harness: h.name,
|
|
46
|
+
option: "access",
|
|
47
|
+
supported: ["read", "write"],
|
|
48
|
+
detail: String(accessRaw),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
37
53
|
for (const key of TURN_OPTION_KEYS) {
|
|
38
54
|
const spec = h.turnOptions[key];
|
|
39
55
|
const raw = (opts as unknown as Record<string, unknown>)[key];
|
|
@@ -166,9 +182,85 @@ export const renderTurnOptions = (
|
|
|
166
182
|
continue;
|
|
167
183
|
}
|
|
168
184
|
|
|
185
|
+
// Access is opt-in-only, no profile default; dispatch to tool-selection for the preset.
|
|
186
|
+
if (key === "access") {
|
|
187
|
+
if (raw === undefined) continue;
|
|
188
|
+
if (spec === undefined) {
|
|
189
|
+
throw new ArgvRefusalError({
|
|
190
|
+
issue: "unsupported-option",
|
|
191
|
+
harness: h.name,
|
|
192
|
+
option: key,
|
|
193
|
+
supported: Object.keys(h.turnOptions).length ? Object.keys(h.turnOptions) : ["(none)"],
|
|
194
|
+
detail: String(raw),
|
|
195
|
+
hint: hintFor(h.name, key),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
const v = validateAccess(raw as string);
|
|
199
|
+
if (!v.ok) {
|
|
200
|
+
throw new ArgvRefusalError({
|
|
201
|
+
issue: "invalid-option-value",
|
|
202
|
+
harness: h.name,
|
|
203
|
+
option: key,
|
|
204
|
+
supported: ["read", "write"],
|
|
205
|
+
detail: String(raw),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
// When discovery.tools is off, the read preset must not re-enable tools.
|
|
209
|
+
if (raw === "read" && opts.discovery?.tools === false) {
|
|
210
|
+
if (spec.kind === "tool-preset") continue;
|
|
211
|
+
}
|
|
212
|
+
switch (spec.kind) {
|
|
213
|
+
case "tool-preset": {
|
|
214
|
+
if (raw === "write") break;
|
|
215
|
+
const toolMapForHarness = (opts as { toolMap?: Record<string, Record<string, string>> })
|
|
216
|
+
.toolMap?.[h.name];
|
|
217
|
+
const filtered = (READ_PRESET as readonly string[]).filter((c) => {
|
|
218
|
+
if (toolMapForHarness?.[c] !== undefined) return true;
|
|
219
|
+
if (h.tools.builtins.some((b) => b.canonical === c)) return true;
|
|
220
|
+
if (h.tools.categories.some((cat) => (cat.canonical as readonly string[]).includes(c)))
|
|
221
|
+
return true;
|
|
222
|
+
return false;
|
|
223
|
+
});
|
|
224
|
+
if (filtered.length === 0) break;
|
|
225
|
+
const rendered = renderToolSelection(h, {
|
|
226
|
+
include: filtered as unknown as string[],
|
|
227
|
+
toolMap: toolMapForHarness,
|
|
228
|
+
});
|
|
229
|
+
if (rendered.tokens.length > 0) sequences.push([...rendered.tokens]);
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
case "flag-value": {
|
|
233
|
+
const fv = spec as Extract<typeof spec, { kind: "flag-value" }>;
|
|
234
|
+
const mapped = fv.values[raw as string];
|
|
235
|
+
if (mapped !== undefined) sequences.push([fv.flag, mapped]);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
case "flag-list-by-value": {
|
|
239
|
+
const fl = spec as Extract<typeof spec, { kind: "flag-list-by-value" }>;
|
|
240
|
+
const list = fl.flags[raw as string] ?? [];
|
|
241
|
+
if (list.length > 0) sequences.push([...list]);
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
default: {
|
|
245
|
+
const _exhaustive: never = spec as never;
|
|
246
|
+
throw new ArgvRefusalError({
|
|
247
|
+
issue: "invalid-option-value",
|
|
248
|
+
harness: h.name,
|
|
249
|
+
option: key,
|
|
250
|
+
supported: [],
|
|
251
|
+
detail: String(_exhaustive),
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
|
|
169
258
|
// Non-discovery keys
|
|
170
|
-
// Handle enum default on launch
|
|
259
|
+
// Handle enum default on launch. An access preset already claimed the
|
|
260
|
+
// sandbox flag on harnesses that express access through it (codex);
|
|
261
|
+
// the enum default must not emit a second --sandbox.
|
|
171
262
|
if (raw === undefined) {
|
|
263
|
+
if (key === "sandbox" && opts.access !== undefined) continue;
|
|
172
264
|
if (
|
|
173
265
|
spec !== undefined &&
|
|
174
266
|
spec.kind === "enum" &&
|
|
@@ -430,6 +522,11 @@ export const renderTurnOptions = (
|
|
|
430
522
|
case "discovery":
|
|
431
523
|
// already handled
|
|
432
524
|
break;
|
|
525
|
+
case "tool-preset":
|
|
526
|
+
case "flag-value":
|
|
527
|
+
case "flag-list-by-value":
|
|
528
|
+
// access-only kinds - handled above for key === "access"
|
|
529
|
+
break;
|
|
433
530
|
default: {
|
|
434
531
|
const _exhaustive: never = spec as never;
|
|
435
532
|
throw new ArgvRefusalError({
|
|
@@ -57,6 +57,11 @@ export const validateModel = (h: HarnessDescriptor, model: string): Validated =>
|
|
|
57
57
|
/** Validate an effort against the ladder that applies to the pick: the
|
|
58
58
|
* model's own ladder where the harness constrains per model (codex), else
|
|
59
59
|
* the harness-wide ladder. */
|
|
60
|
+
export const validateAccess = (value: string): Validated => {
|
|
61
|
+
if (value === "read" || value === "write") return { ok: true, id: value };
|
|
62
|
+
return { ok: false, reason: `unknown access ${JSON.stringify(value)}; accepted: read, write` };
|
|
63
|
+
};
|
|
64
|
+
|
|
60
65
|
export const validateEffort = (h: HarnessDescriptor, effort: string, model?: string): Validated => {
|
|
61
66
|
let ladder = h.vocabulary.efforts;
|
|
62
67
|
if (model !== undefined && h.vocabulary.effortsByModel !== undefined) {
|
|
@@ -177,6 +177,7 @@ export const claudeCode: HarnessDescriptor = deepFreeze({
|
|
|
177
177
|
},
|
|
178
178
|
},
|
|
179
179
|
},
|
|
180
|
+
access: { kind: "tool-preset", render: { kind: "flag-value", flag: "--allowedTools" } },
|
|
180
181
|
},
|
|
181
182
|
// Phase 0 fixtures: claude-tool-interplay.md. include is a permission
|
|
182
183
|
// grant (Bash, Edit stay visible under --allowedTools Read); only the
|
|
@@ -191,19 +192,19 @@ export const claudeCode: HarnessDescriptor = deepFreeze({
|
|
|
191
192
|
includeIsStrictAllowlist: false,
|
|
192
193
|
composable: true,
|
|
193
194
|
builtins: [
|
|
194
|
-
{ name: "Bash", defaultEnabled: true },
|
|
195
|
-
{ name: "Edit", defaultEnabled: true },
|
|
196
|
-
{ name: "Glob", defaultEnabled: true },
|
|
197
|
-
{ name: "Grep", defaultEnabled: true },
|
|
198
|
-
{ name: "Read", defaultEnabled: true },
|
|
199
|
-
{ name: "Write", defaultEnabled: true },
|
|
200
|
-
{ name: "WebFetch", defaultEnabled: true },
|
|
201
|
-
{ name: "WebSearch", defaultEnabled: true },
|
|
202
|
-
{ name: "Monitor", defaultEnabled: true },
|
|
203
|
-
{ name: "Task", defaultEnabled: true },
|
|
204
|
-
{ name: "Skill", defaultEnabled: true },
|
|
205
|
-
{ name: "NotebookEdit", defaultEnabled: true },
|
|
206
|
-
{ name: "LSP", defaultEnabled: true },
|
|
195
|
+
{ name: "Bash", defaultEnabled: true, canonical: "shell" },
|
|
196
|
+
{ name: "Edit", defaultEnabled: true, canonical: "edit" },
|
|
197
|
+
{ name: "Glob", defaultEnabled: true, canonical: "glob" },
|
|
198
|
+
{ name: "Grep", defaultEnabled: true, canonical: "grep" },
|
|
199
|
+
{ name: "Read", defaultEnabled: true, canonical: "read" },
|
|
200
|
+
{ name: "Write", defaultEnabled: true, canonical: "write" },
|
|
201
|
+
{ name: "WebFetch", defaultEnabled: true, canonical: "web-fetch" },
|
|
202
|
+
{ name: "WebSearch", defaultEnabled: true, canonical: "web-search" },
|
|
203
|
+
{ name: "Monitor", defaultEnabled: true, canonical: null },
|
|
204
|
+
{ name: "Task", defaultEnabled: true, canonical: "subagent" },
|
|
205
|
+
{ name: "Skill", defaultEnabled: true, canonical: "skill" },
|
|
206
|
+
{ name: "NotebookEdit", defaultEnabled: true, canonical: null },
|
|
207
|
+
{ name: "LSP", defaultEnabled: true, canonical: null },
|
|
207
208
|
],
|
|
208
209
|
categories: [],
|
|
209
210
|
denySemantics: "remove-from-set",
|
package/src/knowledge/codex.ts
CHANGED
|
@@ -122,6 +122,12 @@ export const codexCli: HarnessDescriptor = deepFreeze({
|
|
|
122
122
|
render: { kind: "flag-value", flag: "--sandbox" },
|
|
123
123
|
resumeRender: null,
|
|
124
124
|
},
|
|
125
|
+
access: {
|
|
126
|
+
kind: "flag-value",
|
|
127
|
+
flag: "--sandbox",
|
|
128
|
+
values: { read: "read-only", write: "workspace-write" },
|
|
129
|
+
render: { kind: "flag-value", flag: "--sandbox" },
|
|
130
|
+
},
|
|
125
131
|
},
|
|
126
132
|
// Phase 0 fixtures: codex-tool-surface.md. No name lists anywhere -
|
|
127
133
|
// not on the CLI, not in config.toml. Control is feature booleans
|
|
@@ -136,10 +142,10 @@ export const codexCli: HarnessDescriptor = deepFreeze({
|
|
|
136
142
|
composable: false,
|
|
137
143
|
builtins: [],
|
|
138
144
|
categories: [
|
|
139
|
-
{ key: "shell", disableFlag: null, configKey: "features.shell_tool" },
|
|
140
|
-
{ key: "exec", disableFlag: null, configKey: "features.unified_exec" },
|
|
141
|
-
{ key: "web", disableFlag: null, configKey: "web_search" },
|
|
142
|
-
{ key: "view-image", disableFlag: null, configKey: "tools.view_image" },
|
|
145
|
+
{ key: "shell", disableFlag: null, configKey: "features.shell_tool", canonical: [] },
|
|
146
|
+
{ key: "exec", disableFlag: null, configKey: "features.unified_exec", canonical: [] },
|
|
147
|
+
{ key: "web", disableFlag: null, configKey: "web_search", canonical: [] },
|
|
148
|
+
{ key: "view-image", disableFlag: null, configKey: "tools.view_image", canonical: [] },
|
|
143
149
|
],
|
|
144
150
|
denySemantics: "no-lists",
|
|
145
151
|
},
|
|
@@ -26,6 +26,21 @@ export const deepFreeze = <T>(value: T): T => {
|
|
|
26
26
|
return value;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
+
export const CANONICAL_TOOLS = deepFreeze([
|
|
30
|
+
"read",
|
|
31
|
+
"edit",
|
|
32
|
+
"write",
|
|
33
|
+
"shell",
|
|
34
|
+
"grep",
|
|
35
|
+
"glob",
|
|
36
|
+
"list",
|
|
37
|
+
"web-fetch",
|
|
38
|
+
"web-search",
|
|
39
|
+
"subagent",
|
|
40
|
+
"skill",
|
|
41
|
+
] as const);
|
|
42
|
+
export type CanonicalTool = (typeof CANONICAL_TOOLS)[number];
|
|
43
|
+
|
|
29
44
|
export type StreamingGranularity = "token" | "message" | "none";
|
|
30
45
|
|
|
31
46
|
export type HarnessMode = "headless-turn" | "headless-session" | "interactive";
|
|
@@ -95,6 +110,7 @@ export const TURN_OPTION_KEYS = deepFreeze([
|
|
|
95
110
|
// that strips the payload changes every bare run's semantics.
|
|
96
111
|
"systemPrompt",
|
|
97
112
|
"appendSystemPrompt",
|
|
113
|
+
"access",
|
|
98
114
|
] as const);
|
|
99
115
|
export type TurnOptionKey = (typeof TURN_OPTION_KEYS)[number];
|
|
100
116
|
|
|
@@ -141,6 +157,17 @@ export type TurnOptionSpec =
|
|
|
141
157
|
readonly values: readonly string[];
|
|
142
158
|
readonly default?: string;
|
|
143
159
|
})
|
|
160
|
+
/** Access preset: read/write dimension with per-harness rendering. */
|
|
161
|
+
| (SpecBase & { readonly kind: "tool-preset" })
|
|
162
|
+
| (SpecBase & {
|
|
163
|
+
readonly kind: "flag-value";
|
|
164
|
+
readonly flag: string;
|
|
165
|
+
readonly values: Readonly<Record<string, string>>;
|
|
166
|
+
})
|
|
167
|
+
| (SpecBase & {
|
|
168
|
+
readonly kind: "flag-list-by-value";
|
|
169
|
+
readonly flags: Readonly<Record<string, readonly string[]>>;
|
|
170
|
+
})
|
|
144
171
|
/** Ladder comes from vocabulary.efforts / effortsByModel, not from here. */
|
|
145
172
|
| (SpecBase & { readonly kind: "effort" })
|
|
146
173
|
/** Open selector, CLEAN_SELECTOR-validated. */
|
|
@@ -187,8 +214,14 @@ export const getOptionRender = (
|
|
|
187
214
|
spec: TurnOptionSpec,
|
|
188
215
|
phase: "launch" | "resume",
|
|
189
216
|
): OptionRender | null => {
|
|
190
|
-
if (
|
|
191
|
-
|
|
217
|
+
if (
|
|
218
|
+
spec.kind === "discovery" ||
|
|
219
|
+
spec.kind === "tool-preset" ||
|
|
220
|
+
spec.kind === "flag-value" ||
|
|
221
|
+
spec.kind === "flag-list-by-value"
|
|
222
|
+
)
|
|
223
|
+
return null;
|
|
224
|
+
return resolveRender(spec as SpecBase, phase);
|
|
192
225
|
};
|
|
193
226
|
|
|
194
227
|
export interface HarnessDescriptor {
|
|
@@ -405,11 +438,13 @@ export interface HarnessDescriptor {
|
|
|
405
438
|
readonly builtins: ReadonlyArray<{
|
|
406
439
|
readonly name: string;
|
|
407
440
|
readonly defaultEnabled: boolean;
|
|
441
|
+
readonly canonical: CanonicalTool | null;
|
|
408
442
|
}>;
|
|
409
443
|
readonly categories: ReadonlyArray<{
|
|
410
444
|
readonly key: "shell" | "write" | "web" | "exec" | "view-image";
|
|
411
445
|
readonly disableFlag: string | null;
|
|
412
446
|
readonly configKey: string | null;
|
|
447
|
+
readonly canonical: readonly CanonicalTool[];
|
|
413
448
|
}>;
|
|
414
449
|
readonly denySemantics: "remove-from-set" | "policy-gate" | "no-lists";
|
|
415
450
|
};
|
package/src/knowledge/muse.ts
CHANGED
|
@@ -109,6 +109,11 @@ export const museCode: HarnessDescriptor = deepFreeze({
|
|
|
109
109
|
max: 10000,
|
|
110
110
|
render: { kind: "flag-value", flag: "--max-model-steps" },
|
|
111
111
|
},
|
|
112
|
+
access: {
|
|
113
|
+
kind: "flag-list-by-value",
|
|
114
|
+
flags: { read: ["--disable-write", "--disable-shell"], write: [] },
|
|
115
|
+
render: { kind: "flag-list", flags: ["--disable-write", "--disable-shell"] },
|
|
116
|
+
},
|
|
112
117
|
},
|
|
113
118
|
// Phase 0 fixtures: muse-category-flags.md. No name lists; category
|
|
114
119
|
// switches are enforcement gates - tools stay listed in the catalog but
|
|
@@ -124,9 +129,19 @@ export const museCode: HarnessDescriptor = deepFreeze({
|
|
|
124
129
|
composable: false,
|
|
125
130
|
builtins: [],
|
|
126
131
|
categories: [
|
|
127
|
-
{
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
{
|
|
133
|
+
key: "write",
|
|
134
|
+
disableFlag: "--disable-write",
|
|
135
|
+
configKey: null,
|
|
136
|
+
canonical: ["write", "edit"],
|
|
137
|
+
},
|
|
138
|
+
{ key: "shell", disableFlag: "--disable-shell", configKey: null, canonical: ["shell"] },
|
|
139
|
+
{
|
|
140
|
+
key: "web",
|
|
141
|
+
disableFlag: "--disable-web-tools",
|
|
142
|
+
configKey: null,
|
|
143
|
+
canonical: ["web-fetch", "web-search"],
|
|
144
|
+
},
|
|
130
145
|
],
|
|
131
146
|
denySemantics: "policy-gate",
|
|
132
147
|
},
|
|
@@ -25,12 +25,14 @@ import { piCli } from "./pi.js";
|
|
|
25
25
|
|
|
26
26
|
export type DescriptorSet = Partial<Record<HarnessName, HarnessDescriptor>>;
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
const SHARED_DESCRIPTORS: DescriptorSet = {
|
|
29
29
|
claude: claudeCode,
|
|
30
30
|
codex: codexCli,
|
|
31
31
|
pi: piCli,
|
|
32
32
|
muse: museCode,
|
|
33
|
-
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const defaultDescriptors = (): DescriptorSet => SHARED_DESCRIPTORS;
|
|
34
36
|
|
|
35
37
|
/** Tracks which descriptors were produced by an override file and what their
|
|
36
38
|
* matcher counts are, so the execution layer can emit `matcherOverrides` on
|
package/src/knowledge/pi.ts
CHANGED
|
@@ -154,6 +154,7 @@ export const piCli: HarnessDescriptor = deepFreeze({
|
|
|
154
154
|
},
|
|
155
155
|
},
|
|
156
156
|
},
|
|
157
|
+
access: { kind: "tool-preset", render: { kind: "flag-value", flag: "--tools" } },
|
|
157
158
|
},
|
|
158
159
|
// Phase 0 fixtures: pi-both-tool-flags.md. Both list flags legal at once;
|
|
159
160
|
// exclude subtracts from include. --tools is strict over BUILT-INS but
|
|
@@ -166,13 +167,13 @@ export const piCli: HarnessDescriptor = deepFreeze({
|
|
|
166
167
|
includeIsStrictAllowlist: true,
|
|
167
168
|
composable: true,
|
|
168
169
|
builtins: [
|
|
169
|
-
{ name: "read", defaultEnabled: true },
|
|
170
|
-
{ name: "bash", defaultEnabled: true },
|
|
171
|
-
{ name: "edit", defaultEnabled: true },
|
|
172
|
-
{ name: "write", defaultEnabled: true },
|
|
173
|
-
{ name: "grep", defaultEnabled: false },
|
|
174
|
-
{ name: "find", defaultEnabled: false },
|
|
175
|
-
{ name: "ls", defaultEnabled: false },
|
|
170
|
+
{ name: "read", defaultEnabled: true, canonical: "read" },
|
|
171
|
+
{ name: "bash", defaultEnabled: true, canonical: "shell" },
|
|
172
|
+
{ name: "edit", defaultEnabled: true, canonical: "edit" },
|
|
173
|
+
{ name: "write", defaultEnabled: true, canonical: "write" },
|
|
174
|
+
{ name: "grep", defaultEnabled: false, canonical: "grep" },
|
|
175
|
+
{ name: "find", defaultEnabled: false, canonical: "glob" },
|
|
176
|
+
{ name: "ls", defaultEnabled: false, canonical: "list" },
|
|
176
177
|
],
|
|
177
178
|
categories: [],
|
|
178
179
|
denySemantics: "remove-from-set",
|