@ordewell/core 0.8.1 → 0.9.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/dist/{IFileSystem-D96mT-bm.d.ts → IFileSystem-BjiyCQ8O.d.ts} +3 -1
- package/dist/{IFileSystem-DXJCRw5x.d.mts → IFileSystem-Cy-TAWvu.d.mts} +3 -1
- package/dist/{IRunner-CGCihlGQ.d.ts → IRunner-Corods20.d.ts} +521 -65
- package/dist/{IRunner-XVUddYVX.d.mts → IRunner-D6YfbmHn.d.mts} +521 -65
- package/dist/{chunk-BLLIBCCS.mjs → chunk-OOZWSUIE.mjs} +7 -4
- package/dist/chunk-OOZWSUIE.mjs.map +1 -0
- package/dist/index.d.mts +378 -195
- package/dist/index.d.ts +378 -195
- package/dist/index.js +3042 -552
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3005 -533
- package/dist/index.mjs.map +1 -1
- package/dist/{plan-utils-BMayhGBj.d.mts → plan-utils-BmUp_Lko.d.mts} +3 -3
- package/dist/{plan-utils-Cv48fe7r.d.ts → plan-utils-tWfH48YX.d.ts} +3 -3
- package/dist/plan-utils.d.mts +2 -2
- package/dist/plan-utils.d.ts +2 -2
- package/dist/plan-utils.js +5 -2
- package/dist/plan-utils.js.map +1 -1
- package/dist/plan-utils.mjs +1 -1
- package/dist/testing.d.mts +2 -2
- package/dist/testing.d.ts +2 -2
- package/dist/testing.js +3 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +3 -0
- package/dist/testing.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-BLLIBCCS.mjs.map +0 -1
|
@@ -2,6 +2,361 @@ import { ChildProcess } from 'child_process';
|
|
|
2
2
|
import { ao as UsageRecord, a8 as SubagentOutcome, W as RunnerId, ag as TaskSkillSnapshot } from './Task-1Q19y7sZ.mjs';
|
|
3
3
|
import { z } from 'zod/v4';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* The planner's standing approvals (ADR-0026): what runs without asking
|
|
7
|
+
* anyone, under every approval mode.
|
|
8
|
+
*
|
|
9
|
+
* One entry is one of:
|
|
10
|
+
*
|
|
11
|
+
* - a **command rule**, `gh issue list` or `gcloud * * list`: the binary,
|
|
12
|
+
* then words matched against the command's leading arguments, the ones
|
|
13
|
+
* before its first flag. A command whose leading words match the rule's
|
|
14
|
+
* runs, whatever arguments follow — but the rule must spell out at least
|
|
15
|
+
* the words the command's approval scope holds (ADR-0008, T1), so
|
|
16
|
+
* `az group` never covers `az group delete`, and a one-word read takes a
|
|
17
|
+
* `*` for its argument (`kubectl get *`). `*` stands for one word, and
|
|
18
|
+
* inside a word for any run of characters (`describe-*`). An entry equal
|
|
19
|
+
* to a scope also matches that scope, as pre-approved scopes always did.
|
|
20
|
+
* - an **MCP tool rule**, `mcp:find-*`: a glob over the tool's own name,
|
|
21
|
+
* without the server, case-insensitive.
|
|
22
|
+
* - a **scope pattern**, anything starting with `/`, `~`, `http://`,
|
|
23
|
+
* `https://`, `web_search:`, `mcp__`, `mcp-server:` or a drive letter: matched against an approval's
|
|
24
|
+
* scope as ADR-0008 always matched pre-approved entries, `*` matching any
|
|
25
|
+
* run of characters.
|
|
26
|
+
*
|
|
27
|
+
* A leading `!` excludes instead, and an exclusion wins over every rule. A
|
|
28
|
+
* command exclusion's words are looked for anywhere among the arguments, in
|
|
29
|
+
* order, flags included and case ignored, so `!kubectl *secret*` and
|
|
30
|
+
* `!* --endpoint*` hold wherever the word appears; a lone short flag (`-s`)
|
|
31
|
+
* also holds inside a bundle (`-As`, `-shost`). `*` as its binary covers
|
|
32
|
+
* every command.
|
|
33
|
+
*/
|
|
34
|
+
/** The words a command rule is matched against: a lexed segment's binary and arguments. */
|
|
35
|
+
interface CommandWords {
|
|
36
|
+
binary: string;
|
|
37
|
+
args: readonly string[];
|
|
38
|
+
/** How many leading arguments the command's approval scope holds; a rule must cover at least that many. */
|
|
39
|
+
scopeWords?: number;
|
|
40
|
+
}
|
|
41
|
+
interface RuleWord {
|
|
42
|
+
matches: (word: string) => boolean;
|
|
43
|
+
wildcard: boolean;
|
|
44
|
+
}
|
|
45
|
+
interface CommandRule {
|
|
46
|
+
text: string;
|
|
47
|
+
binary: string;
|
|
48
|
+
words: RuleWord[];
|
|
49
|
+
}
|
|
50
|
+
interface PlannerAllowlist {
|
|
51
|
+
commands: CommandRule[];
|
|
52
|
+
commandExclusions: CommandRule[];
|
|
53
|
+
tools: RegExp[];
|
|
54
|
+
toolExclusions: RegExp[];
|
|
55
|
+
scopes: RegExp[];
|
|
56
|
+
scopeExclusions: RegExp[];
|
|
57
|
+
}
|
|
58
|
+
declare function parseAllowlist(entries: readonly string[]): PlannerAllowlist;
|
|
59
|
+
/** The rule that lets this command run unasked, or undefined when none does or an exclusion holds. */
|
|
60
|
+
declare function commandAllowedBy(list: PlannerAllowlist, command: CommandWords): string | undefined;
|
|
61
|
+
/** Whether an MCP tool, by its own name without the server, runs unasked. */
|
|
62
|
+
declare function toolAllowed(list: PlannerAllowlist, tool: string): boolean;
|
|
63
|
+
/** Whether an approval scope — a directory, an origin, a tool's full name — is pre-approved. */
|
|
64
|
+
declare function scopeAllowed(list: PlannerAllowlist, scope: string): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Read-only command families that are safe to run unasked: they read, never
|
|
67
|
+
* write a file or change a resource, and need no argument that runs code.
|
|
68
|
+
* Absent on purpose: commands that run the repository's own code (test
|
|
69
|
+
* runners, builds, package scripts, a package manager the repository pins or
|
|
70
|
+
* extends — on an untrusted repository someone else wrote that code), commands
|
|
71
|
+
* a repository's own config can point at another endpoint with the user's
|
|
72
|
+
* credentials (`.npmrc`, `.sentryclirc`, a Terraform or Pulumi backend), and
|
|
73
|
+
* commands whose usual output is a secret.
|
|
74
|
+
*/
|
|
75
|
+
declare const DEFAULT_PLANNER_ALLOWLIST: readonly string[];
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Which interpreter runs the planner's `bash` tool, and in which language.
|
|
79
|
+
*
|
|
80
|
+
* `AUTO_COMMANDS` — the read-only tier that runs with no prompt — is `ls`, `cat`,
|
|
81
|
+
* `wc`, `head`, `tail`, `du`, `df`, `file`, `sort`, `uniq`, `basename`, `find`,
|
|
82
|
+
* `grep`. That set is POSIX, and passing it to `shell: true` on Windows means
|
|
83
|
+
* cmd.exe, where most of those names do not exist and `find` is an unrelated
|
|
84
|
+
* program that returns plausible wrong output instead of an error. The planner's
|
|
85
|
+
* whole research surface degraded to guessing, quietly.
|
|
86
|
+
*
|
|
87
|
+
* Rather than write a Windows dialect of every research command — a second
|
|
88
|
+
* behavior to keep in step forever — this finds a POSIX shell to run the
|
|
89
|
+
* existing ones in. Git for Windows ships a full one, and git is already a
|
|
90
|
+
* prerequisite for everything Ordewell does, so in practice it is there. Failing
|
|
91
|
+
* that, cmd.exe is used and the classifier is told so, because the one thing
|
|
92
|
+
* that must never happen is classifying a command in one language and running it
|
|
93
|
+
* in another: `commandPolicy` reads {@link ResearchShell.dialect} for exactly
|
|
94
|
+
* that reason.
|
|
95
|
+
*
|
|
96
|
+
* POSIX resolves to `{ file: null }`, meaning "use `shell: true`" — byte for
|
|
97
|
+
* byte what the adapters did before this module existed.
|
|
98
|
+
*
|
|
99
|
+
* Windows paths are built with `path.win32` explicitly, not the host-flavoured
|
|
100
|
+
* `path`, so the probe is the same on a Windows host as it is under a Linux
|
|
101
|
+
* test runner.
|
|
102
|
+
*/
|
|
103
|
+
type ShellDialect = 'posix' | 'cmd';
|
|
104
|
+
interface ResearchShell {
|
|
105
|
+
/**
|
|
106
|
+
* Executable that takes a command string, or null to use the host default
|
|
107
|
+
* via `shell: true`.
|
|
108
|
+
*/
|
|
109
|
+
file: string | null;
|
|
110
|
+
/** Arguments preceding the command string. */
|
|
111
|
+
args: string[];
|
|
112
|
+
/** The language the command string will be interpreted in. */
|
|
113
|
+
dialect: ShellDialect;
|
|
114
|
+
/**
|
|
115
|
+
* Directory holding this shell's POSIX utilities, when it brings its own.
|
|
116
|
+
* Prepended to PATH for the search subprocesses (`grep`, `tree`) that
|
|
117
|
+
* `execFile` starts without a shell, so they resolve too.
|
|
118
|
+
*/
|
|
119
|
+
utilsDir: string | null;
|
|
120
|
+
}
|
|
121
|
+
interface ResearchShellDeps {
|
|
122
|
+
platform?: NodeJS.Platform;
|
|
123
|
+
exists?: (candidate: string) => boolean;
|
|
124
|
+
env?: NodeJS.ProcessEnv;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* The shell the planner's `bash` tool should use on this host. Resolved once per
|
|
128
|
+
* process — the answer cannot change while Ordewell runs, and the probe costs a
|
|
129
|
+
* handful of `stat` calls.
|
|
130
|
+
*/
|
|
131
|
+
declare function resolveResearchShell(deps?: ResearchShellDeps): ResearchShell;
|
|
132
|
+
/** Test seam: drop the per-process cache so the next call re-probes. */
|
|
133
|
+
declare function clearResearchShellCache(): void;
|
|
134
|
+
/**
|
|
135
|
+
* PATH for the search subprocesses the adapters start without a shell, with the
|
|
136
|
+
* research shell's own utilities in front. Without this, `grep` — the fallback
|
|
137
|
+
* when ripgrep is absent — is unresolvable on a Windows box even when a
|
|
138
|
+
* perfectly good `grep.exe` sits in the Git tree beside the shell.
|
|
139
|
+
*/
|
|
140
|
+
declare function researchToolsPath(shell: ResearchShell, basePath: string | undefined): string;
|
|
141
|
+
/**
|
|
142
|
+
* A message explaining a degraded research surface, or null when there is
|
|
143
|
+
* nothing to explain. Surfaced by the adapters on the first refused command so
|
|
144
|
+
* the limitation is visible rather than inferred from bad answers.
|
|
145
|
+
*/
|
|
146
|
+
declare function researchShellWarning(shell: ResearchShell): string | null;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Tiered classification for the planner's `bash` tool.
|
|
150
|
+
*
|
|
151
|
+
* The planner is a read-only researcher: it never edits files, and the runners
|
|
152
|
+
* do the real work. But research legitimately means running things — querying a
|
|
153
|
+
* cloud control plane (`az`, `gh`), reproducing a failure (`npm test`), or
|
|
154
|
+
* shaping output (`jq`). The old allowlist refused all of that, so the model's
|
|
155
|
+
* only escape was to guess.
|
|
156
|
+
*
|
|
157
|
+
* Three tiers replace the flat allowlist:
|
|
158
|
+
*
|
|
159
|
+
* auto read-only inspection — runs with no prompt (the historical list)
|
|
160
|
+
* ask anything else that is not obviously destructive — one approval,
|
|
161
|
+
* remembered for the rest of the session at `scope` granularity
|
|
162
|
+
* refuse writes, privilege escalation, and anything that would smuggle
|
|
163
|
+
* arbitrary code past this classifier — never runs, never prompts
|
|
164
|
+
*
|
|
165
|
+
* `refuse` is deliberately not promptable. A planner that can `rm` is a planner
|
|
166
|
+
* that can silently break the workspace it was asked to reason about, and the
|
|
167
|
+
* architecture already says mutation belongs to the runners.
|
|
168
|
+
*
|
|
169
|
+
* Classification walks every segment of the command line (pipes, `&&`, `;`, and
|
|
170
|
+
* command substitution) rather than matching substrings against the raw string.
|
|
171
|
+
* The old substring denylist both over-matched (`ls docs/removed` tripped `rm`)
|
|
172
|
+
* and under-matched (`$(rm -rf /)` was invisible once chaining was allowed).
|
|
173
|
+
*
|
|
174
|
+
* A segment is classified by the command that will actually execute, not by the
|
|
175
|
+
* name at the front of it: wrappers are unwrapped first, recursively, so
|
|
176
|
+
* `timeout 10 env nice rm -rf x` is an `rm`. See {@link WRAPPER_FAMILY}. A
|
|
177
|
+
* runner that feeds its command arguments nobody can see is unwrapped the same
|
|
178
|
+
* way but never runs unprompted ({@link XARGS_TARGETS}), and one that hands its
|
|
179
|
+
* command to a shell is refused ({@link REFUSED_RUNNERS}).
|
|
180
|
+
*
|
|
181
|
+
* A permitted binary is permitted with the flags it is known to be read-only
|
|
182
|
+
* with, not with any flag at all: several of them will run a helper program or
|
|
183
|
+
* write a file when asked to, so `auto` is a per-binary flag allowlist and an
|
|
184
|
+
* unrecognised flag is refused. See {@link FLAG_POLICY}.
|
|
185
|
+
*
|
|
186
|
+
* The lexer is dialect-aware, because the interpreter that will actually run
|
|
187
|
+
* the command decides what the tokens are, and getting that wrong is not a
|
|
188
|
+
* cosmetic error here — it is the difference between classifying what runs and
|
|
189
|
+
* classifying something else. See {@link Dialect}.
|
|
190
|
+
*/
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* `env` is deliberately absent. Given a command it is a wrapper, classified by
|
|
194
|
+
* what it actually runs (see {@link WRAPPER_FAMILY}); given none it prints the
|
|
195
|
+
* whole process environment — provider credentials included — into the research
|
|
196
|
+
* log, which is a disclosure the developer should get to see coming.
|
|
197
|
+
*
|
|
198
|
+
* Membership here is necessary but not sufficient: every name in this list also
|
|
199
|
+
* declares the flags it is read-only with in {@link FLAG_POLICY}.
|
|
200
|
+
*/
|
|
201
|
+
declare const AUTO_COMMANDS: string[];
|
|
202
|
+
/**
|
|
203
|
+
* `ls-remote` is deliberately absent, and it is the one entry here that is
|
|
204
|
+
* read-only against the repository. It reaches the network: it contacts
|
|
205
|
+
* whatever host the named remote or URL resolves to, which routes around the
|
|
206
|
+
* web fetcher's per-origin approval and its request-forgery guard. So it
|
|
207
|
+
* prompts rather than running silently.
|
|
208
|
+
*
|
|
209
|
+
* Prompting only became the right answer once {@link scopeFor} widened. Under
|
|
210
|
+
* the old scope it would have been remembered as `git ls-remote`, so one
|
|
211
|
+
* approval of the workspace's own remote would have authorised a listing
|
|
212
|
+
* against any host at all — which is the same hole with an approval dialog in
|
|
213
|
+
* front of it. The scope now carries the destination.
|
|
214
|
+
*/
|
|
215
|
+
declare const GIT_READONLY_SUBCOMMANDS: string[];
|
|
216
|
+
/**
|
|
217
|
+
* Never runs, with or without approval.
|
|
218
|
+
*
|
|
219
|
+
* The `cmd.exe` builtins at the end matter as much as the POSIX names above
|
|
220
|
+
* them. `del`, `rd`, `move`, and friends mutate exactly what `rm` and `mv` do,
|
|
221
|
+
* and on Windows they are what a model reaches for — so without them the whole
|
|
222
|
+
* refusal tier was bypassable on that platform by writing the command the way
|
|
223
|
+
* the platform spells it. Listed unconditionally rather than per-platform: a
|
|
224
|
+
* POSIX box has no `del` to refuse, so the extra names cost nothing there.
|
|
225
|
+
*/
|
|
226
|
+
declare const REFUSED_COMMANDS: string[];
|
|
227
|
+
/**
|
|
228
|
+
* Options threaded through classification.
|
|
229
|
+
*
|
|
230
|
+
* `dialect` is keyed to the interpreter rather than the OS on purpose: a Windows
|
|
231
|
+
* host that has Git Bash runs the planner's commands in a POSIX shell (see
|
|
232
|
+
* {@link resolveResearchShell}), and classifying those under cmd.exe rules
|
|
233
|
+
* would be the same mismatch in the other direction. Callers pass the dialect of
|
|
234
|
+
* the shell they are actually going to use; omitting it falls back to the host
|
|
235
|
+
* default.
|
|
236
|
+
*/
|
|
237
|
+
interface CommandPolicyOptions {
|
|
238
|
+
dialect?: ShellDialect;
|
|
239
|
+
/** Only flags generated from vetted DNS answers by BaseFileSystem, never caller input. */
|
|
240
|
+
trustedWebResolves?: ReadonlySet<string>;
|
|
241
|
+
autonomous?: boolean;
|
|
242
|
+
approvalMode?: 'ask' | 'allow' | 'deny';
|
|
243
|
+
/**
|
|
244
|
+
* `CDPATH` is set in the environment the command will run in. A relative
|
|
245
|
+
* `cd` may then land in a directory the command line never names, so `cd`
|
|
246
|
+
* stops being navigation the classifier can follow.
|
|
247
|
+
*/
|
|
248
|
+
cdpathSet?: boolean;
|
|
249
|
+
/** The planner's standing approvals (ADR-0026); an `ask` command they cover carries {@link CommandClassification.allowedBy}. */
|
|
250
|
+
allow?: PlannerAllowlist;
|
|
251
|
+
}
|
|
252
|
+
type CommandTier = 'auto' | 'ask' | 'refuse';
|
|
253
|
+
interface CommandClassification {
|
|
254
|
+
tier: CommandTier;
|
|
255
|
+
/** A human must approve this invocation even when its origin was already granted. */
|
|
256
|
+
perInvocation?: boolean;
|
|
257
|
+
/** Separate grants for commands that name several origins. */
|
|
258
|
+
scopes?: string[];
|
|
259
|
+
webUrls?: URL[];
|
|
260
|
+
webOutboundTexts?: string[];
|
|
261
|
+
/** What a grant covers, for `ask`. Derived from the non-auto segments only. */
|
|
262
|
+
scope: string;
|
|
263
|
+
/** Populated for `refuse`: why, in a sentence the model can act on. */
|
|
264
|
+
reason?: string;
|
|
265
|
+
/** For `ask`: the allowlist rule that pre-approves every part of the command that needed asking. */
|
|
266
|
+
allowedBy?: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Classify one command line. Output redirection is refused outright unless the
|
|
270
|
+
* target provably writes nothing — `/dev/null`, or an fd duplication like
|
|
271
|
+
* `2>&1` — since a planner that writes files has stopped being a planner.
|
|
272
|
+
*/
|
|
273
|
+
declare function classifyCommand(command: string, opts?: CommandPolicyOptions): CommandClassification;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Decides whether one out-of-envelope capability may run, and remembers the
|
|
277
|
+
* answer for the rest of the session.
|
|
278
|
+
*
|
|
279
|
+
* Grants are keyed on {@link ApprovalRequest.scope}, never on the concrete
|
|
280
|
+
* subject: approving a read of `/tmp/foo/a.log` grants `/tmp/foo/*`, and
|
|
281
|
+
* approving `az group list` grants `az group list`. Without that, a planner
|
|
282
|
+
* doing real research would prompt on every single call and the feature would
|
|
283
|
+
* be unusable.
|
|
284
|
+
*
|
|
285
|
+
* `mode` is the policy floor:
|
|
286
|
+
* ask consult the human channel; no channel means deny (headless, web)
|
|
287
|
+
* allow grant everything the tier system did not already refuse
|
|
288
|
+
* deny grant nothing beyond `preApproved` — the allowlist-only mode
|
|
289
|
+
*
|
|
290
|
+
* Note the ordering: `preApproved` is honored under every mode including
|
|
291
|
+
* `deny`, because it is an explicit operator decision rather than a default.
|
|
292
|
+
* Its entries are allowlist rules (see `plannerAllowlist.ts`), and both it and
|
|
293
|
+
* `mode` may be read afresh on every request, so a settings change applies to
|
|
294
|
+
* the next call.
|
|
295
|
+
*/
|
|
296
|
+
type ApprovalMode = 'ask' | 'allow' | 'deny';
|
|
297
|
+
/**
|
|
298
|
+
* The configured mode. `auto` follows the autonomy level (ADR-0026): Guarded
|
|
299
|
+
* asks, Full runs the allowlist alone and asks nobody, so a planner in Full
|
|
300
|
+
* never waits on a person and never acts outside its standing approvals.
|
|
301
|
+
*/
|
|
302
|
+
type ApprovalModeSetting = ApprovalMode | 'auto';
|
|
303
|
+
declare function effectiveApprovalMode(setting: ApprovalModeSetting, autonomous: boolean, kind?: ApprovalKind): ApprovalMode;
|
|
304
|
+
/** A configured mode as written: `allowlist` is the user-facing name of `deny`, and anything unknown is `auto`. */
|
|
305
|
+
declare function parseApprovalModeSetting(raw: string | undefined): ApprovalModeSetting;
|
|
306
|
+
interface ApprovalPolicyOptions {
|
|
307
|
+
/** Read per request, for the kind being asked about. */
|
|
308
|
+
mode?: ApprovalMode | ((kind: ApprovalKind) => ApprovalMode);
|
|
309
|
+
autonomous?: () => boolean;
|
|
310
|
+
/** Allowlist entries granted up front from config (ADR-0026). */
|
|
311
|
+
preApproved?: readonly string[] | (() => readonly string[]);
|
|
312
|
+
/** The human channel. Absent means there is nobody to ask. */
|
|
313
|
+
ask?: (req: ApprovalRequest) => Promise<boolean>;
|
|
314
|
+
/** Called whenever a decision is reached, for surfacing in a UI or a log. */
|
|
315
|
+
onDecision?: (req: ApprovalRequest, granted: boolean, source: ApprovalSource) => void;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Why a request was decided as it was. The next four are refusals reached
|
|
319
|
+
* before the policy itself is consulted (ADR-0027's web-read guards), handed
|
|
320
|
+
* to {@link ApprovalPolicy.record} so they surface like any other decision:
|
|
321
|
+
* an `!` allowlist exclusion, the scheme and SSRF guard, the outbound secret
|
|
322
|
+
* check, and the per-turn web-read budget. `unsupported` comes after: an
|
|
323
|
+
* approved project MCP server the planner's runner version cannot give the
|
|
324
|
+
* planner as tools of their own (ADR-0028).
|
|
325
|
+
*/
|
|
326
|
+
type ApprovalSource = 'pre-approved' | 'remembered' | 'mode' | 'asked' | 'no-channel' | 'excluded' | 'guard' | 'secret' | 'budget' | 'unsupported';
|
|
327
|
+
declare class ApprovalPolicy implements IApproval {
|
|
328
|
+
private readonly modeOf;
|
|
329
|
+
private readonly autonomousOf;
|
|
330
|
+
private readonly entriesOf;
|
|
331
|
+
private parsed;
|
|
332
|
+
private readonly asker?;
|
|
333
|
+
private readonly onDecision?;
|
|
334
|
+
private readonly granted;
|
|
335
|
+
private readonly refused;
|
|
336
|
+
/** One in-flight ask per scope: a parallel tool round must not prompt twice for the same thing. */
|
|
337
|
+
private readonly inFlight;
|
|
338
|
+
private generation;
|
|
339
|
+
constructor(opts?: ApprovalPolicyOptions);
|
|
340
|
+
request(req: ApprovalRequest): Promise<boolean>;
|
|
341
|
+
commandPolicy(): Pick<CommandPolicyOptions, 'autonomous' | 'approvalMode'>;
|
|
342
|
+
/**
|
|
343
|
+
* What `request` would answer without a person, for a caller that may never
|
|
344
|
+
* prompt (a research subagent): the same standing grants, remembered
|
|
345
|
+
* refusals and mode the interactive path uses, stopping at `ask`.
|
|
346
|
+
*/
|
|
347
|
+
peek(req: ApprovalRequest): StandingDecision;
|
|
348
|
+
private standing;
|
|
349
|
+
/** Report a decision a guard reached before this policy was asked. */
|
|
350
|
+
record(req: ApprovalRequest, granted: boolean, source: ApprovalSource): void;
|
|
351
|
+
grantsUnasked({ kind, scope }: Pick<ApprovalRequest, 'kind' | 'scope'>): boolean;
|
|
352
|
+
/** The standing approvals, parsed from the entries in force now. */
|
|
353
|
+
allowlist(): PlannerAllowlist;
|
|
354
|
+
/** Scopes the user has granted this session — for display and for persistence. */
|
|
355
|
+
grantedScopes(): string[];
|
|
356
|
+
/** Drop every session-scoped decision. Called on session reset. */
|
|
357
|
+
reset(): void;
|
|
358
|
+
}
|
|
359
|
+
|
|
5
360
|
/**
|
|
6
361
|
* The planner's single approval seam. Every capability that reaches beyond the
|
|
7
362
|
* default read-only, in-workspace envelope — a path outside the workspace root,
|
|
@@ -17,11 +372,18 @@ import { z } from 'zod/v4';
|
|
|
17
372
|
/**
|
|
18
373
|
* `runner_tool` is a task runner's own tool request (ADR-0018, A1): it waits
|
|
19
374
|
* for an answer as long as it takes, and never passes through the planner's
|
|
20
|
-
* policy — the runner's mode already decided it needed asking.
|
|
375
|
+
* policy — the runner's mode already decided it needed asking. `mcp_tool` is
|
|
376
|
+
* a harness planner reaching for an MCP tool the user configured (ADR-0026),
|
|
377
|
+
* scoped to that one tool. `web_search` is scoped to the search provider, the
|
|
378
|
+
* party that receives every query (ADR-0027). `mcp_server` is starting an MCP
|
|
379
|
+
* server the repository declares for a planner, scoped to its definition
|
|
380
|
+
* (ADR-0028).
|
|
21
381
|
*/
|
|
22
|
-
type ApprovalKind = 'external_path' | 'shell_command' | 'url_fetch' | 'runner_tool';
|
|
382
|
+
type ApprovalKind = 'external_path' | 'shell_command' | 'url_fetch' | 'web_search' | 'mcp_tool' | 'mcp_server' | 'runner_tool';
|
|
23
383
|
interface ApprovalRequest {
|
|
24
384
|
kind: ApprovalKind;
|
|
385
|
+
/** Credentials, data and redirects need a fresh human answer for each invocation. */
|
|
386
|
+
perInvocation?: boolean;
|
|
25
387
|
/** The concrete thing being asked about: an absolute path, a command line, a URL. */
|
|
26
388
|
subject: string;
|
|
27
389
|
/**
|
|
@@ -41,6 +403,14 @@ interface ApprovalRequest {
|
|
|
41
403
|
taskId?: string;
|
|
42
404
|
/** "Allow for this task" can be offered: the runner proposed its own session-scoped grant. */
|
|
43
405
|
allowForTask?: boolean;
|
|
406
|
+
/**
|
|
407
|
+
* The allowlist rule the command classifier found covering every part of a
|
|
408
|
+
* `shell_command` that asks (ADR-0026). It settles `scope`, never the
|
|
409
|
+
* outside directories in `scopes`.
|
|
410
|
+
*/
|
|
411
|
+
allowedBy?: string;
|
|
412
|
+
/** For `mcp_tool`: the tool's own name, without its server, which allowlist tool rules match. */
|
|
413
|
+
tool?: string;
|
|
44
414
|
}
|
|
45
415
|
/**
|
|
46
416
|
* An answer, from whoever gives it — a person on any surface, or later the
|
|
@@ -61,8 +431,32 @@ declare function toApprovalDecision(answer: ApprovalAnswer): ApprovalDecision;
|
|
|
61
431
|
declare function isGranted(decision: ApprovalDecision): boolean;
|
|
62
432
|
declare function approvalScopes(request: ApprovalRequest): string[];
|
|
63
433
|
declare function isRunnerApproval(request: ApprovalRequest): boolean;
|
|
434
|
+
type StandingDecision = {
|
|
435
|
+
decision: 'allow' | 'deny';
|
|
436
|
+
source: 'pre-approved' | 'remembered' | 'mode';
|
|
437
|
+
} | {
|
|
438
|
+
decision: 'deny';
|
|
439
|
+
source: 'excluded';
|
|
440
|
+
} | {
|
|
441
|
+
decision: 'ask';
|
|
442
|
+
source: 'no-channel';
|
|
443
|
+
};
|
|
64
444
|
interface IApproval {
|
|
65
445
|
request(req: ApprovalRequest): Promise<boolean>;
|
|
446
|
+
/** The standing approvals a command is classified against, when this approval has any (ADR-0026). */
|
|
447
|
+
allowlist?(): PlannerAllowlist;
|
|
448
|
+
commandPolicy?(): Pick<CommandPolicyOptions, 'autonomous' | 'approvalMode'>;
|
|
449
|
+
/** Surface a decision reached before `request` was called, as `request`'s own are. */
|
|
450
|
+
record?(req: ApprovalRequest, granted: boolean, source: ApprovalSource): void;
|
|
451
|
+
/**
|
|
452
|
+
* Resolve a request without a person (ADR-0027): `allow` when it is already
|
|
453
|
+
* granted or the mode allows without asking, `deny` when a refusal is
|
|
454
|
+
* remembered or the mode forbids, `ask` when it would still need a prompt. A
|
|
455
|
+
* background research subagent never prompts, so `ask` means refused.
|
|
456
|
+
*/
|
|
457
|
+
peek?(req: ApprovalRequest): StandingDecision;
|
|
458
|
+
/** Whether `request` would grant this scope now without asking anyone. Nothing is asked or recorded. */
|
|
459
|
+
grantsUnasked?(req: Pick<ApprovalRequest, 'kind' | 'scope'>): boolean;
|
|
66
460
|
}
|
|
67
461
|
/** Denies everything. The safe default when a surface wires no approval channel. */
|
|
68
462
|
declare const DENY_ALL: IApproval;
|
|
@@ -92,6 +486,15 @@ declare const listRunnersInput: z.ZodObject<{}, z.core.$strip>;
|
|
|
92
486
|
declare const listModelsInput: z.ZodObject<{
|
|
93
487
|
runner: z.ZodString;
|
|
94
488
|
}, z.core.$strip>;
|
|
489
|
+
declare const runCommandInput: z.ZodObject<{
|
|
490
|
+
command: z.ZodString;
|
|
491
|
+
}, z.core.$strip>;
|
|
492
|
+
declare const fetchInput: z.ZodObject<{
|
|
493
|
+
url: z.ZodString;
|
|
494
|
+
}, z.core.$strip>;
|
|
495
|
+
declare const webSearchInput: z.ZodObject<{
|
|
496
|
+
query: z.ZodString;
|
|
497
|
+
}, z.core.$strip>;
|
|
95
498
|
declare const loadSkillInput: z.ZodObject<{
|
|
96
499
|
name: z.ZodString;
|
|
97
500
|
}, z.core.$strip>;
|
|
@@ -186,6 +589,9 @@ type CheckpointArgs = z.infer<typeof checkpointInput>;
|
|
|
186
589
|
type ListRunnersArgs = z.infer<typeof listRunnersInput>;
|
|
187
590
|
type ListModelsArgs = z.infer<typeof listModelsInput>;
|
|
188
591
|
type LoadSkillArgs = z.infer<typeof loadSkillInput>;
|
|
592
|
+
type RunCommandArgs = z.infer<typeof runCommandInput>;
|
|
593
|
+
type FetchArgs = z.infer<typeof fetchInput>;
|
|
594
|
+
type WebSearchArgs = z.infer<typeof webSearchInput>;
|
|
189
595
|
type SubmitPlanArgs = z.infer<typeof submitPlanInput>;
|
|
190
596
|
type EditPlanArgs = z.infer<typeof editPlanInput>;
|
|
191
597
|
type TaskQueryArgs = z.infer<typeof taskQueryInput>;
|
|
@@ -220,6 +626,9 @@ interface TaskToolHandler {
|
|
|
220
626
|
}
|
|
221
627
|
interface PlannerToolHandler {
|
|
222
628
|
loadSkill?: Run<LoadSkillArgs>;
|
|
629
|
+
runCommand?: Run<RunCommandArgs>;
|
|
630
|
+
fetch?: Run<FetchArgs>;
|
|
631
|
+
webSearch?: Run<WebSearchArgs>;
|
|
223
632
|
listRunners?: Run<ListRunnersArgs>;
|
|
224
633
|
listModels?: Run<ListModelsArgs>;
|
|
225
634
|
submitPlan?: Run<SubmitPlanArgs>;
|
|
@@ -263,11 +672,19 @@ interface TaskTokenScope {
|
|
|
263
672
|
}
|
|
264
673
|
interface PlannerTokenScope {
|
|
265
674
|
sessionId: string;
|
|
675
|
+
/**
|
|
676
|
+
* Planner tools this token neither lists nor serves, by their names on the
|
|
677
|
+
* server: the ones a runner carries natively instead (ADR-0027), which a
|
|
678
|
+
* model would otherwise pick over its own.
|
|
679
|
+
*/
|
|
680
|
+
hidden?: readonly string[];
|
|
266
681
|
}
|
|
267
682
|
/** Where a runner reaches the server and what it presents there. Never put either half in a prompt. */
|
|
268
683
|
interface McpCredential {
|
|
269
684
|
url: string;
|
|
270
685
|
token: string;
|
|
686
|
+
/** The planner tools the token hides ({@link PlannerTokenScope.hidden}), so the runner is told of and pre-allows only what it is served. */
|
|
687
|
+
hidden?: readonly string[];
|
|
271
688
|
}
|
|
272
689
|
declare class OrdewellMcpServer {
|
|
273
690
|
private readonly grants;
|
|
@@ -281,6 +698,8 @@ declare class OrdewellMcpServer {
|
|
|
281
698
|
get url(): string | undefined;
|
|
282
699
|
issueTaskToken(scope: TaskTokenScope, handler?: TaskToolHandler): Promise<McpCredential>;
|
|
283
700
|
issuePlannerToken(scope: PlannerTokenScope, handler?: PlannerToolHandler): Promise<McpCredential>;
|
|
701
|
+
/** Every token still good here: secrets the outbound check keeps out of a URL (ADR-0027). */
|
|
702
|
+
heldTokens(): string[];
|
|
284
703
|
/** Refuse every later request carrying `token`, and abort the calls it has in flight. */
|
|
285
704
|
revoke(token: string): void;
|
|
286
705
|
dispose(): Promise<void>;
|
|
@@ -297,6 +716,8 @@ interface McpClientConfig {
|
|
|
297
716
|
name: typeof ORDEWELL_MCP_SERVER_NAME;
|
|
298
717
|
url: string;
|
|
299
718
|
headers: Record<string, string>;
|
|
719
|
+
/** Planner tools the token hides: a runner must neither pre-allow nor mention them. */
|
|
720
|
+
hidden?: readonly string[];
|
|
300
721
|
}
|
|
301
722
|
/**
|
|
302
723
|
* The one shape every runner adapter renders its own MCP configuration from.
|
|
@@ -318,6 +739,23 @@ interface OwnerOnlyFile {
|
|
|
318
739
|
*/
|
|
319
740
|
declare function ownerOnlyConfigFile(fileName: string, contents: string): OwnerOnlyFile;
|
|
320
741
|
|
|
742
|
+
/**
|
|
743
|
+
* One MCP server a repository declares. `definition` is the entry as
|
|
744
|
+
* Ordewell parsed it, in the runner's own shape: an approved server is
|
|
745
|
+
* handed to the runner as exactly this, never re-read from the file.
|
|
746
|
+
*/
|
|
747
|
+
interface ProjectMcpServer {
|
|
748
|
+
name: string;
|
|
749
|
+
/** The file that declares it, relative to the workspace. */
|
|
750
|
+
source: string;
|
|
751
|
+
transport: 'stdio' | 'remote';
|
|
752
|
+
/** What would run, as written: the command line, or the URL. */
|
|
753
|
+
target: string;
|
|
754
|
+
/** The variables it sets, or the headers it sends, by name. */
|
|
755
|
+
names: string[];
|
|
756
|
+
definition: Record<string, unknown>;
|
|
757
|
+
}
|
|
758
|
+
|
|
321
759
|
/**
|
|
322
760
|
* The harness-planner transport contract (ADR-0009).
|
|
323
761
|
*
|
|
@@ -400,15 +838,17 @@ type AgentEvent =
|
|
|
400
838
|
digest: string;
|
|
401
839
|
}
|
|
402
840
|
/**
|
|
403
|
-
* The agent asked to do something its mode does not cover.
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
841
|
+
* The agent asked to do something its mode does not cover. Without
|
|
842
|
+
* `decided` the request stays open until {@link AgentAdapter.answerPermission}:
|
|
843
|
+
* a task's for a person (ADR-0018, A1), a planner's for the planner's
|
|
844
|
+
* envelope (ADR-0026). An adapter that cannot hold a planner's request open
|
|
845
|
+
* denies it itself and says so in `decided`, so the turn does not hang.
|
|
407
846
|
*
|
|
408
847
|
* `input` and `suggestions` are the raw request; `suggestions` are the
|
|
409
848
|
* agent's own session-scoped grants, what "Allow for this task" answers with.
|
|
410
|
-
* `decided` marks a request
|
|
411
|
-
*
|
|
849
|
+
* `decided` marks a request already answered — by the adapter, as the
|
|
850
|
+
* manifest says the task's mode does, or as a denial — so it is shown, never asked.
|
|
851
|
+
* `ask` is what a planner's open request is for, in the envelope's terms.
|
|
412
852
|
*/
|
|
413
853
|
| {
|
|
414
854
|
type: 'permission_request';
|
|
@@ -419,6 +859,7 @@ type AgentEvent =
|
|
|
419
859
|
suggestions?: unknown[];
|
|
420
860
|
toolUseId?: string;
|
|
421
861
|
decided?: ApprovalDecision;
|
|
862
|
+
ask?: PlannerAsk;
|
|
422
863
|
}
|
|
423
864
|
/** The agent withdrew an open request — an interrupt cancels the call it was for. It takes no answer now. */
|
|
424
865
|
| {
|
|
@@ -468,6 +909,41 @@ type AgentEvent =
|
|
|
468
909
|
type: 'error';
|
|
469
910
|
message: string;
|
|
470
911
|
};
|
|
912
|
+
/**
|
|
913
|
+
* What a planner's permission request is for, read from the runner's own
|
|
914
|
+
* request by its adapter, so one envelope decides it whichever runner asked
|
|
915
|
+
* (ADR-0026). `other` is anything the envelope never grants a planner.
|
|
916
|
+
*/
|
|
917
|
+
type PlannerAsk =
|
|
918
|
+
/** `scope` is the tool's full name as the runner reports it; `tool` its own name, without the server. */
|
|
919
|
+
{
|
|
920
|
+
kind: 'mcp';
|
|
921
|
+
scope: string;
|
|
922
|
+
tool: string;
|
|
923
|
+
server?: string;
|
|
924
|
+
} | {
|
|
925
|
+
kind: 'fetch';
|
|
926
|
+
url: string;
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
929
|
+
* A search the runner carries itself, at `provider`; Ordewell decides it, it does not run it.
|
|
930
|
+
* `providerLabel` names that party in the approval.
|
|
931
|
+
*/
|
|
932
|
+
| {
|
|
933
|
+
kind: 'search';
|
|
934
|
+
query: string;
|
|
935
|
+
provider: string;
|
|
936
|
+
providerLabel?: string;
|
|
937
|
+
} | {
|
|
938
|
+
kind: 'path';
|
|
939
|
+
path: string;
|
|
940
|
+
directory: boolean;
|
|
941
|
+
}
|
|
942
|
+
/** `note` is why, for a tool the runner knows the planner must not use, in place of the envelope's generic refusal. */
|
|
943
|
+
| {
|
|
944
|
+
kind: 'other';
|
|
945
|
+
note?: string;
|
|
946
|
+
};
|
|
471
947
|
interface AgentStartCommon {
|
|
472
948
|
/** Workspace root. The agent works from here and, in read-only mode, cannot leave it. */
|
|
473
949
|
cwd: string;
|
|
@@ -489,6 +965,20 @@ interface PlannerStartOptions extends AgentStartCommon {
|
|
|
489
965
|
effort?: string;
|
|
490
966
|
/** The Ordewell MCP server to inject, pre-authorized (ADR-0022). Only for an adapter with {@link AgentAdapter.mcpAttached}. */
|
|
491
967
|
mcp?: McpClientConfig;
|
|
968
|
+
/**
|
|
969
|
+
* Whether the runner's own search is on, for a runner whose search raises
|
|
970
|
+
* no permission request and is set on or off when its session starts
|
|
971
|
+
* (ADR-0027). Decided once, before the planner token is issued, so the
|
|
972
|
+
* tools the token serves and the session's config cannot disagree. Absent
|
|
973
|
+
* means off.
|
|
974
|
+
*/
|
|
975
|
+
nativeSearch?: boolean;
|
|
976
|
+
/**
|
|
977
|
+
* The repository's own MCP servers this planner may start, as approved
|
|
978
|
+
* (ADR-0028). The runner is launched without the repository's config, so
|
|
979
|
+
* these are the only ones it gets, and each is handed over as parsed.
|
|
980
|
+
*/
|
|
981
|
+
projectServers?: ProjectMcpServer[];
|
|
492
982
|
}
|
|
493
983
|
/**
|
|
494
984
|
* What a runner manifest says the task's mode and effort mean (ADR-0001),
|
|
@@ -556,6 +1046,18 @@ interface AgentAdapter {
|
|
|
556
1046
|
* adapter that cannot inject the server at all, which cannot run tasks.
|
|
557
1047
|
*/
|
|
558
1048
|
mcpAttached?(): Promise<boolean>;
|
|
1049
|
+
/**
|
|
1050
|
+
* The approved project servers (ADR-0028) this runner started but cannot
|
|
1051
|
+
* give the planner as tools of their own, known once `start` resolved.
|
|
1052
|
+
* Absent on an adapter that gives the planner every one it starts.
|
|
1053
|
+
*/
|
|
1054
|
+
unusableProjectServers?(): ProjectMcpServer[];
|
|
1055
|
+
/**
|
|
1056
|
+
* Answer an open `permission_request`. False when the id is not open — it
|
|
1057
|
+
* was answered, cancelled, or never asked. Absent on an adapter that leaves
|
|
1058
|
+
* no planner request open.
|
|
1059
|
+
*/
|
|
1060
|
+
answerPermission?(id: string, decision: ApprovalDecision): boolean;
|
|
559
1061
|
}
|
|
560
1062
|
/** What an adapter adds to run a task rather than a planner (ADR-0018). */
|
|
561
1063
|
interface TaskModeAgentAdapter extends AgentAdapter {
|
|
@@ -586,10 +1088,6 @@ interface TaskModeAgentAdapter extends AgentAdapter {
|
|
|
586
1088
|
* mid-turn.
|
|
587
1089
|
*/
|
|
588
1090
|
steer?(id: string, text: string): Promise<boolean>;
|
|
589
|
-
/**
|
|
590
|
-
* Answer an open `permission_request`. False when the id is not open — it
|
|
591
|
-
* was answered, cancelled, or never asked.
|
|
592
|
-
*/
|
|
593
1091
|
answerPermission(id: string, decision: ApprovalDecision): boolean;
|
|
594
1092
|
}
|
|
595
1093
|
type SpawnFn = (command: string, args: string[], options: {
|
|
@@ -749,53 +1247,6 @@ interface RunnerEntry {
|
|
|
749
1247
|
manifest: RunnerManifest;
|
|
750
1248
|
}
|
|
751
1249
|
|
|
752
|
-
/**
|
|
753
|
-
* Decides whether one out-of-envelope capability may run, and remembers the
|
|
754
|
-
* answer for the rest of the session.
|
|
755
|
-
*
|
|
756
|
-
* Grants are keyed on {@link ApprovalRequest.scope}, never on the concrete
|
|
757
|
-
* subject: approving a read of `/tmp/foo/a.log` grants `/tmp/foo/*`, and
|
|
758
|
-
* approving `az group list` grants `az group`. Without that, a planner doing
|
|
759
|
-
* real research would prompt on every single call and the feature would be
|
|
760
|
-
* unusable.
|
|
761
|
-
*
|
|
762
|
-
* `mode` is the policy floor:
|
|
763
|
-
* ask consult the human channel; no channel means deny (headless, web)
|
|
764
|
-
* allow grant everything the tier system did not already refuse
|
|
765
|
-
* deny grant nothing beyond `preApproved`
|
|
766
|
-
*
|
|
767
|
-
* Note the ordering: `preApproved` is honored under every mode including
|
|
768
|
-
* `deny`, because it is an explicit operator decision rather than a default.
|
|
769
|
-
*/
|
|
770
|
-
type ApprovalMode = 'ask' | 'allow' | 'deny';
|
|
771
|
-
interface ApprovalPolicyOptions {
|
|
772
|
-
mode?: ApprovalMode;
|
|
773
|
-
/** Scopes granted up front from config. A trailing `*` matches by prefix. */
|
|
774
|
-
preApproved?: string[];
|
|
775
|
-
/** The human channel. Absent means there is nobody to ask. */
|
|
776
|
-
ask?: (req: ApprovalRequest) => Promise<boolean>;
|
|
777
|
-
/** Called whenever a decision is reached, for surfacing in a UI or a log. */
|
|
778
|
-
onDecision?: (req: ApprovalRequest, granted: boolean, source: ApprovalSource) => void;
|
|
779
|
-
}
|
|
780
|
-
type ApprovalSource = 'pre-approved' | 'remembered' | 'mode' | 'asked' | 'no-channel';
|
|
781
|
-
declare class ApprovalPolicy implements IApproval {
|
|
782
|
-
private readonly mode;
|
|
783
|
-
private readonly preApproved;
|
|
784
|
-
private readonly asker?;
|
|
785
|
-
private readonly onDecision?;
|
|
786
|
-
private readonly granted;
|
|
787
|
-
private readonly refused;
|
|
788
|
-
/** One in-flight ask per scope: a parallel tool round must not prompt twice for the same thing. */
|
|
789
|
-
private readonly inFlight;
|
|
790
|
-
private generation;
|
|
791
|
-
constructor(opts?: ApprovalPolicyOptions);
|
|
792
|
-
request(req: ApprovalRequest): Promise<boolean>;
|
|
793
|
-
/** Scopes the user has granted this session — for display and for persistence. */
|
|
794
|
-
grantedScopes(): string[];
|
|
795
|
-
/** Drop every session-scoped decision. Called on session reset. */
|
|
796
|
-
reset(): void;
|
|
797
|
-
}
|
|
798
|
-
|
|
799
1250
|
interface CatalogModel {
|
|
800
1251
|
id: string;
|
|
801
1252
|
name: string;
|
|
@@ -961,13 +1412,18 @@ interface IConfig {
|
|
|
961
1412
|
conflictRepairAttempts: number;
|
|
962
1413
|
/**
|
|
963
1414
|
* What to do when planner research reaches outside its default envelope — an
|
|
964
|
-
* out-of-workspace path,
|
|
965
|
-
* set. `ask` prompts the user (and denies where no surface can
|
|
966
|
-
* headless runs); `allow` and `deny` skip the prompt
|
|
1415
|
+
* out-of-workspace path, a shell command beyond the auto-allowed read-only
|
|
1416
|
+
* set, an MCP tool. `ask` prompts the user (and denies where no surface can
|
|
1417
|
+
* prompt, such as headless runs); `allow` and `deny` skip the prompt
|
|
1418
|
+
* entirely; `auto` follows {@link autonomousMode} (ADR-0026).
|
|
967
1419
|
*/
|
|
968
|
-
approvalMode:
|
|
969
|
-
/**
|
|
1420
|
+
approvalMode: ApprovalModeSetting;
|
|
1421
|
+
/** Allowlist entries granted up front, beside the defaults (ADR-0026, `plannerAllowlist.ts`). */
|
|
970
1422
|
approvalPreApproved: string[];
|
|
1423
|
+
/** Whether the built-in allowlist of read-only command families and MCP tools applies. */
|
|
1424
|
+
approvalDefaults: boolean;
|
|
1425
|
+
/** How many fetches and searches one planner turn may make (ADR-0027). User-only, like the approval settings. */
|
|
1426
|
+
webReadBudget: number;
|
|
971
1427
|
/** Get the base URL for an OpenAI-compatible provider. */
|
|
972
1428
|
getProviderBaseUrl(provider: AiProvider): string;
|
|
973
1429
|
/** Get the API key for a provider. */
|
|
@@ -1162,4 +1618,4 @@ interface IRunner {
|
|
|
1162
1618
|
activeCount: number;
|
|
1163
1619
|
}
|
|
1164
1620
|
|
|
1165
|
-
export { type
|
|
1621
|
+
export { type PlannerTokenScope as $, AUTO_COMMANDS as A, type ListModelsArgs as B, type CatalogModel as C, DEFAULT_PLANNER_ALLOWLIST as D, type EditPlanArgs as E, type FetchAllProviderModelsOptions as F, GIT_READONLY_SUBCOMMANDS as G, type ListRunnersArgs as H, type IApproval as I, type LoadSkillArgs as J, type McpCredential as K, LineBuffer as L, type McpClientConfig as M, type McpTool as N, type McpToolContext as O, type McpToolReply as P, ModelCatalog as Q, type ModelShortcut as R, ORCHESTRATOR_SHORTCUTS as S, ORDEWELL_MCP_PATH as T, ORDEWELL_MCP_SERVER_NAME as U, type OrchestratorOption as V, OrdewellMcpServer as W, type OwnerOnlyFile as X, PLANNER_TOOLS as Y, type PlannerAllowlist as Z, type PlannerStartOptions as _, type AgentAdapter as a, type PlannerToolHandler as a0, type ProjectMcpServer as a1, type ProviderCredentialSource as a2, type ProviderModelLists as a3, type ProviderModelsResult as a4, type QueuedTaskMessage as a5, REFUSED_COMMANDS as a6, type ResearchShell as a7, type ResearchShellDeps as a8, type RunCommandArgs as a9, collectProviderCredentials as aA, commandAllowedBy as aB, effectiveApprovalMode as aC, enabledRunners as aD, fetchAllProviderModels as aE, isGranted as aF, isRunnerApproval as aG, knownModelId as aH, mcpClientConfig as aI, ownerOnlyConfigFile as aJ, parseAllowlist as aK, parseApprovalModeSetting as aL, researchShellWarning as aM, researchToolsPath as aN, resolveModelShortcut as aO, resolveProvider as aP, resolveResearchShell as aQ, scopeAllowed as aR, sharedMcpServer as aS, toApprovalDecision as aT, toOrchestratorOptions as aU, toolAllowed as aV, type RunnerEntry as aa, type RunnerFeatures as ab, type RunnerManifest as ac, type RunnerMode as ad, type RunnerModelDiscovery as ae, RunnerRegistry as af, type ShellDialect as ag, type SpawnFn as ah, type StandingDecision as ai, type StructuredEvent as aj, type StructuredTurnEnd as ak, type SubmitPlanArgs as al, TASK_COMPLETE_TOOL as am, TASK_TOOLS as an, type TaskCompleteArgs as ao, type TaskModeAgentAdapter as ap, TaskModeUnsupportedError as aq, type TaskOutputArgs as ar, type TaskQueryArgs as as, type TaskRunnerFlags as at, type TaskStartOptions as au, type TaskTokenScope as av, type TaskToolHandler as aw, approvalScopes as ax, classifyCommand as ay, clearResearchShellCache as az, type AgentAdapterFactory as b, type AgentEvent as c, type AgentProcessDeps as d, type AgentStartOptions as e, type AiProvider as f, type AllProviderModels as g, type ApprovalAnswer as h, type ApprovalDecision as i, type ApprovalKind as j, type ApprovalMode as k, type ApprovalModeSetting as l, ApprovalPolicy as m, type ApprovalPolicyOptions as n, type ApprovalRequest as o, type ApprovalSource as p, type CheckpointAnswer as q, type CheckpointArgs as r, type CommandClassification as s, type CommandTier as t, type CommandWords as u, DENY_ALL as v, type DiscoveryCommand as w, type IConfig as x, type IRunner as y, type IRunnerSession as z };
|