@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
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { W as RunnerId, E as PlanStatus, L as LegacyPlanState, n as IsolationMergeResult, j as IsolationLandedTask, I as IWorktreeIsolation, w as IsolationTaskStatus, P as PlanIsolation, a3 as SkillsService, _ as SkillInfo, N as RepoGroupLayout, c as DiscoveredModel, a9 as Task, S as ResearchProgress, O as ResearchLogEntry, C as ConversationMessage, ao as UsageRecord, ah as TaskSnapshot, a as AwaitingReason, g as IsolationHandoff, s as IsolationRun, t as IsolationTaskRecord, aa as TaskIsolation, x as IsolationView, o as IsolationOutcome, K as RepairEvidence, am as TreeSnapshot, av as Verdict, ag as TaskSkillSnapshot, $ as SkillLoad, Q as QueuedMessage, A as ActiveTaskSession, V as ResearchToolType, G as PlannerUsage, z as PlanState } from './Task-1Q19y7sZ.mjs';
|
|
2
2
|
export { B as BUILTIN_SKILL_NAMES, D as DEFAULT_RUNNERS, b as DiscoveredMode, d as IntegrationDisposal, e as InvalidSkill, f as IsolationAvailability, h as IsolationHandoffRepo, i as IsolationInactiveReason, k as IsolationLanding, l as IsolationMergeBlock, m as IsolationMergeBlockReason, p as IsolationPruneResult, q as IsolationRemoval, r as IsolationRepo, u as IsolationTaskRef, v as IsolationTaskRepo, M as Message, y as PlanModificationWarnings, F as PlannerTaskView, H as PreparedTask, J as PreservedWork, R as RefusedRemoval, T as ResearchStep, U as ResearchStepOutcome, X as ShadowedSkill, Y as SkillAppliesTo, Z as SkillCatalog, a0 as SkillLoadNotice, a1 as SkillMetadata, a2 as SkillSource, a4 as StreamEvent, a5 as StreamStepEvent, a6 as StreamThinkingEvent, a7 as SubagentLogEntry, a8 as SubagentOutcome, ab as TaskIsolationState, ac as TaskMode, ad as TaskModelAssignment, ae as TaskOutputSummary, af as TaskSkillNotice, ai as TaskStatus, aj as TaskType, ak as TaskWithParent, al as ThinkingBlock, an as UsageLine, ap as UsageTotals, aq as UserPromptEntry, ar as UserStep, as as ValidationCheck, at as ValidationContext, au as ValidationResult, aw as VerificationCheck, ax as addPlannerUsage, ay as addTaskToPlan, az as addUsage, aA as createEmptyPlan, aB as createSkillsService, aC as createTask, aD as emptyWarnings, aE as flattenTasks, aF as flattenTasksWithParents, aG as inheritedOps, aH as inheritedSkills, aI as isAwaitingReason, aJ as isMeasured, aK as isSkillName, aL as isUserMessage, aM as keepExecutionState, aN as migrateLegacyPlan, aO as migrateLoadedTasks, aP as migratePlanState, aQ as migrateTask, aR as opsFlag, aS as partedPromptUsage, aT as plannerContextFill, aU as plannerTaskView, aV as removeTaskFromPlan, aW as renumberTasks, aX as skillNames, aY as updateTaskInPlan, aZ as usageLine, a_ as validateModifiedPlan, a$ as warningsText } from './Task-1Q19y7sZ.mjs';
|
|
3
|
-
import { R as TaskOp, M as MergeGateView, j as EditCatalog, u as SessionBroadcaster, A as ApplyTaskOpsResult, w as SessionNotice, v as SessionMessage, K as TaskLogEvent, H as SurfacePlan, I as SurfacePlanState } from './plan-utils-
|
|
4
|
-
export { a as ApprovalBlock, b as ApprovalStatus, C as CHECKPOINT_TRUNCATE_LENGTH, c as ConversationInput, d as ConversationView, D as DiffRow, e as DiffRowKind, f as DiffStat, g as DisplayBlock, E as EMPTY_CONVERSATION, h as EMPTY_HOLD, i as EMPTY_TASK_LOG, G as GatedConversation, L as LocalEntry, k as MessageBlock, l as MessageRole, N as NOT_STARTED, m as NO_TURN, n as NewTaskFields, O as OutputPreview, P as PlanBlock, o as PlanMarkerStatus, p as PromptHold, S as SerializedConversationMessage, q as SerializedPlan, r as SerializedQueuedMessage, s as SerializedTask, t as SerializedTaskStatus, x as SkillLoadBlock, y as SkillToken, z as SubagentBlock, B as SubagentChild, F as SubagentStatus, J as SurfaceTask, T as TakenPrompt, Q as TaskLogView, U as TaskRef, V as TaskRowAction, W as TaskRowContext, X as TaskRowIsolation, Y as TaskRowKind, Z as TaskRowPlacement, _ as TaskRowSubject, $ as TaskRowView, a0 as TaskStatusKind, a1 as ThinkingDisplayBlock, a2 as ToolBlock, a3 as ToolHeadline, a4 as ToolStatus, a5 as TurnGate, a6 as UsageBlock, a7 as aheadOfDraft, a8 as applyTaskOps, a9 as approvalLabel, aa as awaitingLabel, ab as canMergeTasks, ac as canSetDependencies, ad as canSplitTask, ae as capConflictFiles, af as classifyOutcome, ag as coalesceTaskLog, ah as dependencyCandidates, ai as dependentsNotice, aj as dependentsOf, ak as diffRows, al as diffStat, am as diffSummary, an as digestTaskLog, ao as drainNext, ap as executionSummary, aq as followTurn, ar as fromTranscript, as as hasHiddenDetail, at as holdPrompt, au as isTaskRunning, av as loadedSkillTokens, aw as markAction, ax as markRequestFor, ay as namedRepos, az as newTaskFields, aA as opsEditable, aB as outputLines, aC as outputPreview, aD as parseTaskOpsJson, aE as pastGateConfirmation, aF as reduceConversation, aG as reduceTaskLog, aH as replayTaskLog, aI as runnerToolSubject, aJ as serializePlan, aK as serializeTask, aL as serializeTaskStatus, aM as skillTokens, aN as stopTurn, aO as summarizeToolCall, aP as surfacePlan, aQ as surfacePlanState, aR as taskLogForSurface, aS as taskRowActions, aT as taskRowView, aU as taskStartedNotice, aV as taskStatusKind, aW as textHasTaskOps, aX as titledRefs, aY as toTaskLogEvent, aZ as toolHeadline, a_ as trimToolOutput, a$ as truncateCheckpointSummary, b0 as unsendAll, b1 as unsendLatest } from './plan-utils-
|
|
5
|
-
import { I as IFileSystem, R as ReadFileOpts, T as ToolOutcome, b as GrepOptions, a as GlobOptions, F as FindSymbolOptions } from './IFileSystem-
|
|
6
|
-
export { G as GREP_DEFAULT_HEAD_LIMIT, c as GrepOutputMode, S as SEARCH_EXCLUSIONS } from './IFileSystem-
|
|
7
|
-
import { I as IApproval,
|
|
8
|
-
export {
|
|
3
|
+
import { R as TaskOp, M as MergeGateView, j as EditCatalog, u as SessionBroadcaster, A as ApplyTaskOpsResult, w as SessionNotice, v as SessionMessage, K as TaskLogEvent, H as SurfacePlan, I as SurfacePlanState } from './plan-utils-BmUp_Lko.mjs';
|
|
4
|
+
export { a as ApprovalBlock, b as ApprovalStatus, C as CHECKPOINT_TRUNCATE_LENGTH, c as ConversationInput, d as ConversationView, D as DiffRow, e as DiffRowKind, f as DiffStat, g as DisplayBlock, E as EMPTY_CONVERSATION, h as EMPTY_HOLD, i as EMPTY_TASK_LOG, G as GatedConversation, L as LocalEntry, k as MessageBlock, l as MessageRole, N as NOT_STARTED, m as NO_TURN, n as NewTaskFields, O as OutputPreview, P as PlanBlock, o as PlanMarkerStatus, p as PromptHold, S as SerializedConversationMessage, q as SerializedPlan, r as SerializedQueuedMessage, s as SerializedTask, t as SerializedTaskStatus, x as SkillLoadBlock, y as SkillToken, z as SubagentBlock, B as SubagentChild, F as SubagentStatus, J as SurfaceTask, T as TakenPrompt, Q as TaskLogView, U as TaskRef, V as TaskRowAction, W as TaskRowContext, X as TaskRowIsolation, Y as TaskRowKind, Z as TaskRowPlacement, _ as TaskRowSubject, $ as TaskRowView, a0 as TaskStatusKind, a1 as ThinkingDisplayBlock, a2 as ToolBlock, a3 as ToolHeadline, a4 as ToolStatus, a5 as TurnGate, a6 as UsageBlock, a7 as aheadOfDraft, a8 as applyTaskOps, a9 as approvalLabel, aa as awaitingLabel, ab as canMergeTasks, ac as canSetDependencies, ad as canSplitTask, ae as capConflictFiles, af as classifyOutcome, ag as coalesceTaskLog, ah as dependencyCandidates, ai as dependentsNotice, aj as dependentsOf, ak as diffRows, al as diffStat, am as diffSummary, an as digestTaskLog, ao as drainNext, ap as executionSummary, aq as followTurn, ar as fromTranscript, as as hasHiddenDetail, at as holdPrompt, au as isTaskRunning, av as loadedSkillTokens, aw as markAction, ax as markRequestFor, ay as namedRepos, az as newTaskFields, aA as opsEditable, aB as outputLines, aC as outputPreview, aD as parseTaskOpsJson, aE as pastGateConfirmation, aF as reduceConversation, aG as reduceTaskLog, aH as replayTaskLog, aI as runnerToolSubject, aJ as serializePlan, aK as serializeTask, aL as serializeTaskStatus, aM as skillTokens, aN as stopTurn, aO as summarizeToolCall, aP as surfacePlan, aQ as surfacePlanState, aR as taskLogForSurface, aS as taskRowActions, aT as taskRowView, aU as taskStartedNotice, aV as taskStatusKind, aW as textHasTaskOps, aX as titledRefs, aY as toTaskLogEvent, aZ as toolHeadline, a_ as trimToolOutput, a$ as truncateCheckpointSummary, b0 as unsendAll, b1 as unsendLatest } from './plan-utils-BmUp_Lko.mjs';
|
|
5
|
+
import { I as IFileSystem, R as ReadFileOpts, T as ToolOutcome, b as GrepOptions, a as GlobOptions, F as FindSymbolOptions } from './IFileSystem-Cy-TAWvu.mjs';
|
|
6
|
+
export { G as GREP_DEFAULT_HEAD_LIMIT, c as GrepOutputMode, S as SEARCH_EXCLUSIONS } from './IFileSystem-Cy-TAWvu.mjs';
|
|
7
|
+
import { a7 as ResearchShell, I as IApproval, o as ApprovalRequest, i as ApprovalDecision, h as ApprovalAnswer, y as IRunner, x as IConfig, f as AiProvider, a3 as ProviderModelLists, l as ApprovalModeSetting, z as IRunnerSession, d as AgentProcessDeps, a as AgentAdapter, W as OrdewellMcpServer, a0 as PlannerToolHandler, af as RunnerRegistry, a5 as QueuedTaskMessage, V as OrchestratorOption, ap as TaskModeAgentAdapter, e as AgentStartOptions, c as AgentEvent, a1 as ProjectMcpServer, m as ApprovalPolicy, ao as TaskCompleteArgs, q as CheckpointAnswer, ak as StructuredTurnEnd, aj as StructuredEvent, au as TaskStartOptions, av as TaskTokenScope, ac as RunnerManifest, at as TaskRunnerFlags } from './IRunner-D6YfbmHn.mjs';
|
|
8
|
+
export { A as AUTO_COMMANDS, b as AgentAdapterFactory, g as AllProviderModels, j as ApprovalKind, k as ApprovalMode, n as ApprovalPolicyOptions, p as ApprovalSource, C as CatalogModel, r as CheckpointArgs, s as CommandClassification, t as CommandTier, u as CommandWords, D as DEFAULT_PLANNER_ALLOWLIST, v as DENY_ALL, w as DiscoveryCommand, E as EditPlanArgs, F as FetchAllProviderModelsOptions, G as GIT_READONLY_SUBCOMMANDS, L as LineBuffer, B as ListModelsArgs, H as ListRunnersArgs, J as LoadSkillArgs, M as McpClientConfig, K as McpCredential, N as McpTool, O as McpToolContext, P as McpToolReply, Q as ModelCatalog, R as ModelShortcut, S as ORCHESTRATOR_SHORTCUTS, T as ORDEWELL_MCP_PATH, U as ORDEWELL_MCP_SERVER_NAME, X as OwnerOnlyFile, Y as PLANNER_TOOLS, Z as PlannerAllowlist, _ as PlannerStartOptions, $ as PlannerTokenScope, a2 as ProviderCredentialSource, a4 as ProviderModelsResult, a6 as REFUSED_COMMANDS, a8 as ResearchShellDeps, a9 as RunCommandArgs, aa as RunnerEntry, ab as RunnerFeatures, ad as RunnerMode, ae as RunnerModelDiscovery, ag as ShellDialect, ah as SpawnFn, ai as StandingDecision, al as SubmitPlanArgs, am as TASK_COMPLETE_TOOL, an as TASK_TOOLS, aq as TaskModeUnsupportedError, ar as TaskOutputArgs, as as TaskQueryArgs, aw as TaskToolHandler, ax as approvalScopes, ay as classifyCommand, az as clearResearchShellCache, aA as collectProviderCredentials, aB as commandAllowedBy, aC as effectiveApprovalMode, aD as enabledRunners, aE as fetchAllProviderModels, aF as isGranted, aG as isRunnerApproval, aH as knownModelId, aI as mcpClientConfig, aJ as ownerOnlyConfigFile, aK as parseAllowlist, aL as parseApprovalModeSetting, aM as researchShellWarning, aN as researchToolsPath, aO as resolveModelShortcut, aP as resolveProvider, aQ as resolveResearchShell, aR as scopeAllowed, aS as sharedMcpServer, aT as toApprovalDecision, aU as toOrchestratorOptions, aV as toolAllowed } from './IRunner-D6YfbmHn.mjs';
|
|
9
9
|
import { R as RunnerModeInfo } from './ModeResolver-DE-o2lRF.mjs';
|
|
10
10
|
export { M as ManifestLookup, a as autonomyLevelLabel, b as buildModeGuide, f as filteredBuildModes, p as parseAutonomyLevel, r as resolveDefaultMode, c as resolveTaskMode, d as runnerModesFrom } from './ModeResolver-DE-o2lRF.mjs';
|
|
11
11
|
import { ChildProcess } from 'child_process';
|
|
@@ -31,188 +31,12 @@ interface SessionData {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* cloud control plane (`az`, `gh`), reproducing a failure (`npm test`), or
|
|
39
|
-
* shaping output (`jq`). The old allowlist refused all of that, so the model's
|
|
40
|
-
* only escape was to guess.
|
|
41
|
-
*
|
|
42
|
-
* Three tiers replace the flat allowlist:
|
|
43
|
-
*
|
|
44
|
-
* auto read-only inspection — runs with no prompt (the historical list)
|
|
45
|
-
* ask anything else that is not obviously destructive — one approval,
|
|
46
|
-
* remembered for the rest of the session at `scope` granularity
|
|
47
|
-
* refuse writes, privilege escalation, and anything that would smuggle
|
|
48
|
-
* arbitrary code past this classifier — never runs, never prompts
|
|
49
|
-
*
|
|
50
|
-
* `refuse` is deliberately not promptable. A planner that can `rm` is a planner
|
|
51
|
-
* that can silently break the workspace it was asked to reason about, and the
|
|
52
|
-
* architecture already says mutation belongs to the runners.
|
|
53
|
-
*
|
|
54
|
-
* Classification walks every segment of the command line (pipes, `&&`, `;`, and
|
|
55
|
-
* command substitution) rather than matching substrings against the raw string.
|
|
56
|
-
* The old substring denylist both over-matched (`ls docs/removed` tripped `rm`)
|
|
57
|
-
* and under-matched (`$(rm -rf /)` was invisible once chaining was allowed).
|
|
58
|
-
*
|
|
59
|
-
* A segment is classified by the command that will actually execute, not by the
|
|
60
|
-
* name at the front of it: wrappers are unwrapped first, recursively, so
|
|
61
|
-
* `timeout 10 env nice rm -rf x` is an `rm`. See {@link WRAPPER_FAMILY}. A
|
|
62
|
-
* runner that feeds its command arguments nobody can see is unwrapped the same
|
|
63
|
-
* way but never runs unprompted ({@link XARGS_TARGETS}), and one that hands its
|
|
64
|
-
* command to a shell is refused ({@link REFUSED_RUNNERS}).
|
|
65
|
-
*
|
|
66
|
-
* A permitted binary is permitted with the flags it is known to be read-only
|
|
67
|
-
* with, not with any flag at all: several of them will run a helper program or
|
|
68
|
-
* write a file when asked to, so `auto` is a per-binary flag allowlist and an
|
|
69
|
-
* unrecognised flag is refused. See {@link FLAG_POLICY}.
|
|
70
|
-
*
|
|
71
|
-
* The lexer is dialect-aware, because the interpreter that will actually run
|
|
72
|
-
* the command decides what the tokens are, and getting that wrong is not a
|
|
73
|
-
* cosmetic error here — it is the difference between classifying what runs and
|
|
74
|
-
* classifying something else. See {@link Dialect}.
|
|
75
|
-
*/
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* `env` is deliberately absent. Given a command it is a wrapper, classified by
|
|
79
|
-
* what it actually runs (see {@link WRAPPER_FAMILY}); given none it prints the
|
|
80
|
-
* whole process environment — provider credentials included — into the research
|
|
81
|
-
* log, which is a disclosure the developer should get to see coming.
|
|
82
|
-
*
|
|
83
|
-
* Membership here is necessary but not sufficient: every name in this list also
|
|
84
|
-
* declares the flags it is read-only with in {@link FLAG_POLICY}.
|
|
85
|
-
*/
|
|
86
|
-
declare const AUTO_COMMANDS: string[];
|
|
87
|
-
/**
|
|
88
|
-
* `ls-remote` is deliberately absent, and it is the one entry here that is
|
|
89
|
-
* read-only against the repository. It reaches the network: it contacts
|
|
90
|
-
* whatever host the named remote or URL resolves to, which routes around the
|
|
91
|
-
* web fetcher's per-origin approval and its request-forgery guard. So it
|
|
92
|
-
* prompts rather than running silently.
|
|
93
|
-
*
|
|
94
|
-
* Prompting only became the right answer once {@link scopeFor} widened. Under
|
|
95
|
-
* the old scope it would have been remembered as `git ls-remote`, so one
|
|
96
|
-
* approval of the workspace's own remote would have authorised a listing
|
|
97
|
-
* against any host at all — which is the same hole with an approval dialog in
|
|
98
|
-
* front of it. The scope now carries the destination.
|
|
34
|
+
* The SSRF guard for anything that leaves the machine on the planner's behalf.
|
|
35
|
+
* An unguarded `http://169.254.169.254/` would hand a prompt-injected planner
|
|
36
|
+
* the cloud metadata credentials, so every outbound host is vetted here: IP
|
|
37
|
+
* literals by range, names by every address DNS answers with.
|
|
99
38
|
*/
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Never runs, with or without approval.
|
|
103
|
-
*
|
|
104
|
-
* The `cmd.exe` builtins at the end matter as much as the POSIX names above
|
|
105
|
-
* them. `del`, `rd`, `move`, and friends mutate exactly what `rm` and `mv` do,
|
|
106
|
-
* and on Windows they are what a model reaches for — so without them the whole
|
|
107
|
-
* refusal tier was bypassable on that platform by writing the command the way
|
|
108
|
-
* the platform spells it. Listed unconditionally rather than per-platform: a
|
|
109
|
-
* POSIX box has no `del` to refuse, so the extra names cost nothing there.
|
|
110
|
-
*/
|
|
111
|
-
declare const REFUSED_COMMANDS: string[];
|
|
112
|
-
/**
|
|
113
|
-
* Options threaded through classification.
|
|
114
|
-
*
|
|
115
|
-
* `dialect` is keyed to the interpreter rather than the OS on purpose: a Windows
|
|
116
|
-
* host that has Git Bash runs the planner's commands in a POSIX shell (see
|
|
117
|
-
* {@link resolveResearchShell}), and classifying those under cmd.exe rules
|
|
118
|
-
* would be the same mismatch in the other direction. Callers pass the dialect of
|
|
119
|
-
* the shell they are actually going to use; omitting it falls back to the host
|
|
120
|
-
* default.
|
|
121
|
-
*/
|
|
122
|
-
interface CommandPolicyOptions {
|
|
123
|
-
dialect?: ShellDialect;
|
|
124
|
-
/**
|
|
125
|
-
* `CDPATH` is set in the environment the command will run in. A relative
|
|
126
|
-
* `cd` may then land in a directory the command line never names, so `cd`
|
|
127
|
-
* stops being navigation the classifier can follow.
|
|
128
|
-
*/
|
|
129
|
-
cdpathSet?: boolean;
|
|
130
|
-
}
|
|
131
|
-
type CommandTier = 'auto' | 'ask' | 'refuse';
|
|
132
|
-
interface CommandClassification {
|
|
133
|
-
tier: CommandTier;
|
|
134
|
-
/** What a grant covers, for `ask`. Derived from the non-auto segments only. */
|
|
135
|
-
scope: string;
|
|
136
|
-
/** Populated for `refuse`: why, in a sentence the model can act on. */
|
|
137
|
-
reason?: string;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Classify one command line. Output redirection is refused outright unless the
|
|
141
|
-
* target provably writes nothing — `/dev/null`, or an fd duplication like
|
|
142
|
-
* `2>&1` — since a planner that writes files has stopped being a planner.
|
|
143
|
-
*/
|
|
144
|
-
declare function classifyCommand(command: string, opts?: CommandPolicyOptions): CommandClassification;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Which interpreter runs the planner's `bash` tool, and in which language.
|
|
148
|
-
*
|
|
149
|
-
* `AUTO_COMMANDS` — the read-only tier that runs with no prompt — is `ls`, `cat`,
|
|
150
|
-
* `wc`, `head`, `tail`, `du`, `df`, `file`, `sort`, `uniq`, `basename`, `find`,
|
|
151
|
-
* `grep`. That set is POSIX, and passing it to `shell: true` on Windows means
|
|
152
|
-
* cmd.exe, where most of those names do not exist and `find` is an unrelated
|
|
153
|
-
* program that returns plausible wrong output instead of an error. The planner's
|
|
154
|
-
* whole research surface degraded to guessing, quietly.
|
|
155
|
-
*
|
|
156
|
-
* Rather than write a Windows dialect of every research command — a second
|
|
157
|
-
* behavior to keep in step forever — this finds a POSIX shell to run the
|
|
158
|
-
* existing ones in. Git for Windows ships a full one, and git is already a
|
|
159
|
-
* prerequisite for everything Ordewell does, so in practice it is there. Failing
|
|
160
|
-
* that, cmd.exe is used and the classifier is told so, because the one thing
|
|
161
|
-
* that must never happen is classifying a command in one language and running it
|
|
162
|
-
* in another: `commandPolicy` reads {@link ResearchShell.dialect} for exactly
|
|
163
|
-
* that reason.
|
|
164
|
-
*
|
|
165
|
-
* POSIX resolves to `{ file: null }`, meaning "use `shell: true`" — byte for
|
|
166
|
-
* byte what the adapters did before this module existed.
|
|
167
|
-
*
|
|
168
|
-
* Windows paths are built with `path.win32` explicitly, not the host-flavoured
|
|
169
|
-
* `path`, so the probe is the same on a Windows host as it is under a Linux
|
|
170
|
-
* test runner.
|
|
171
|
-
*/
|
|
172
|
-
type ShellDialect = 'posix' | 'cmd';
|
|
173
|
-
interface ResearchShell {
|
|
174
|
-
/**
|
|
175
|
-
* Executable that takes a command string, or null to use the host default
|
|
176
|
-
* via `shell: true`.
|
|
177
|
-
*/
|
|
178
|
-
file: string | null;
|
|
179
|
-
/** Arguments preceding the command string. */
|
|
180
|
-
args: string[];
|
|
181
|
-
/** The language the command string will be interpreted in. */
|
|
182
|
-
dialect: ShellDialect;
|
|
183
|
-
/**
|
|
184
|
-
* Directory holding this shell's POSIX utilities, when it brings its own.
|
|
185
|
-
* Prepended to PATH for the search subprocesses (`grep`, `tree`) that
|
|
186
|
-
* `execFile` starts without a shell, so they resolve too.
|
|
187
|
-
*/
|
|
188
|
-
utilsDir: string | null;
|
|
189
|
-
}
|
|
190
|
-
interface ResearchShellDeps {
|
|
191
|
-
platform?: NodeJS.Platform;
|
|
192
|
-
exists?: (candidate: string) => boolean;
|
|
193
|
-
env?: NodeJS.ProcessEnv;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* The shell the planner's `bash` tool should use on this host. Resolved once per
|
|
197
|
-
* process — the answer cannot change while Ordewell runs, and the probe costs a
|
|
198
|
-
* handful of `stat` calls.
|
|
199
|
-
*/
|
|
200
|
-
declare function resolveResearchShell(deps?: ResearchShellDeps): ResearchShell;
|
|
201
|
-
/** Test seam: drop the per-process cache so the next call re-probes. */
|
|
202
|
-
declare function clearResearchShellCache(): void;
|
|
203
|
-
/**
|
|
204
|
-
* PATH for the search subprocesses the adapters start without a shell, with the
|
|
205
|
-
* research shell's own utilities in front. Without this, `grep` — the fallback
|
|
206
|
-
* when ripgrep is absent — is unresolvable on a Windows box even when a
|
|
207
|
-
* perfectly good `grep.exe` sits in the Git tree beside the shell.
|
|
208
|
-
*/
|
|
209
|
-
declare function researchToolsPath(shell: ResearchShell, basePath: string | undefined): string;
|
|
210
|
-
/**
|
|
211
|
-
* A message explaining a degraded research surface, or null when there is
|
|
212
|
-
* nothing to explain. Surfaced by the adapters on the first refused command so
|
|
213
|
-
* the limitation is visible rather than inferred from bad answers.
|
|
214
|
-
*/
|
|
215
|
-
declare function researchShellWarning(shell: ResearchShell): string | null;
|
|
39
|
+
type ResolveAll = (host: string) => Promise<string[]>;
|
|
216
40
|
|
|
217
41
|
/**
|
|
218
42
|
* The policy half of the planner's filesystem: path confinement, the tiered
|
|
@@ -227,7 +51,10 @@ declare function researchShellWarning(shell: ResearchShell): string | null;
|
|
|
227
51
|
* record.
|
|
228
52
|
*/
|
|
229
53
|
declare abstract class BaseFileSystem implements IFileSystem {
|
|
54
|
+
private readonly resolveWebHost;
|
|
230
55
|
private approval;
|
|
56
|
+
private outboundSecrets;
|
|
57
|
+
constructor(resolveWebHost?: ResolveAll);
|
|
231
58
|
/**
|
|
232
59
|
* The interpreter `execBashImpl` will hand the command to. Owned here rather
|
|
233
60
|
* than per-adapter because {@link classifyCommand} has to be told the same
|
|
@@ -237,6 +64,7 @@ declare abstract class BaseFileSystem implements IFileSystem {
|
|
|
237
64
|
protected readonly researchShell: ResearchShell;
|
|
238
65
|
/** Surfaces inject the human channel here; without it, external access is denied. */
|
|
239
66
|
setApproval(approval: IApproval): void;
|
|
67
|
+
setOutboundSecrets(secrets: () => Iterable<string>): void;
|
|
240
68
|
abstract getWorkspaceRoot(): string;
|
|
241
69
|
protected abstract readFileImpl(absPath: string, opts?: ReadFileOpts): Promise<ToolOutcome>;
|
|
242
70
|
protected abstract globImpl(pattern: string, absRoot: string, headLimit: number): Promise<ToolOutcome>;
|
|
@@ -288,8 +116,95 @@ declare abstract class BaseFileSystem implements IFileSystem {
|
|
|
288
116
|
bash(command: string, signal?: AbortSignal): Promise<ToolOutcome>;
|
|
289
117
|
}
|
|
290
118
|
|
|
119
|
+
/**
|
|
120
|
+
* The one decision every planner web read goes through, whichever runner
|
|
121
|
+
* plans and whichever path carries the bytes (ADR-0027). A fetch names the
|
|
122
|
+
* URL it reads; a search names its query and the provider that receives it.
|
|
123
|
+
*/
|
|
124
|
+
type WebRead = {
|
|
125
|
+
kind: 'fetch';
|
|
126
|
+
url: string;
|
|
127
|
+
}
|
|
128
|
+
/** `provider` keys the grant; `providerLabel`, when given, names it to the person asked. */
|
|
129
|
+
| {
|
|
130
|
+
kind: 'search';
|
|
131
|
+
query: string;
|
|
132
|
+
provider: string;
|
|
133
|
+
providerLabel?: string;
|
|
134
|
+
note?: string;
|
|
135
|
+
};
|
|
136
|
+
/** A refusal's `reason` is written for the planner: it says what to do next. */
|
|
137
|
+
type WebReadDecision = {
|
|
138
|
+
allowed: true;
|
|
139
|
+
} | {
|
|
140
|
+
allowed: false;
|
|
141
|
+
reason: string;
|
|
142
|
+
};
|
|
143
|
+
interface DecideOptions {
|
|
144
|
+
/**
|
|
145
|
+
* Research subagents run in the background where nothing can prompt
|
|
146
|
+
* (ADR-0008, T6). When false, a read that would ask is refused with the gap
|
|
147
|
+
* to report, rather than raising a prompt nobody can answer.
|
|
148
|
+
*/
|
|
149
|
+
prompting?: boolean;
|
|
150
|
+
}
|
|
151
|
+
interface WebReadPolicyOptions {
|
|
152
|
+
approval: IApproval;
|
|
153
|
+
/** The secrets Ordewell holds — provider keys, MCP tokens — read per request. */
|
|
154
|
+
secrets?: () => Iterable<string>;
|
|
155
|
+
/** Defaults to `process.env`; its credential-named values are secrets too. */
|
|
156
|
+
env?: () => Record<string, string | undefined>;
|
|
157
|
+
/** How many web reads one planner turn may make; read per request, so a settings change applies at once. */
|
|
158
|
+
budget?: () => number;
|
|
159
|
+
/** The planner turn in progress; a new one starts a new budget. */
|
|
160
|
+
turn?: () => string | undefined;
|
|
161
|
+
/** Override DNS resolution (every answer for a name) in tests. */
|
|
162
|
+
resolveHost?: ResolveAll;
|
|
163
|
+
}
|
|
164
|
+
declare const DEFAULT_WEB_READ_BUDGET = 40;
|
|
165
|
+
declare class WebReadPolicy {
|
|
166
|
+
private readonly approval;
|
|
167
|
+
private readonly resolveHost;
|
|
168
|
+
private readonly secrets;
|
|
169
|
+
private readonly env;
|
|
170
|
+
private readonly budget;
|
|
171
|
+
private readonly turn;
|
|
172
|
+
private spent;
|
|
173
|
+
constructor(opts: WebReadPolicyOptions);
|
|
174
|
+
/**
|
|
175
|
+
* Every check that needs no network runs first, then the budget and the
|
|
176
|
+
* approval, and only then is a fetch's host resolved: a lookup is itself a
|
|
177
|
+
* request, so `<data>.attacker.example` would leave through DNS even for a
|
|
178
|
+
* read that is then excluded, over budget or declined.
|
|
179
|
+
*/
|
|
180
|
+
decide(read: WebRead, opts?: DecideOptions): Promise<WebReadDecision>;
|
|
181
|
+
private subagentRefusal;
|
|
182
|
+
/**
|
|
183
|
+
* Whether a search through `provider` would run without asking anyone, for
|
|
184
|
+
* a runner whose own search raises no request and is set on or off when
|
|
185
|
+
* its session starts (ADR-0027). A zero budget disables it; no query is
|
|
186
|
+
* known yet, so secrets and individual reads cannot be checked or counted.
|
|
187
|
+
*/
|
|
188
|
+
searchesUnasked(provider: string): boolean;
|
|
189
|
+
/** The last check, the one that leaves the machine: every DNS answer for the host must be public. */
|
|
190
|
+
private resolved;
|
|
191
|
+
private refuse;
|
|
192
|
+
private vetFetch;
|
|
193
|
+
private vetSearch;
|
|
194
|
+
private spend;
|
|
195
|
+
private refund;
|
|
196
|
+
private carriesSecret;
|
|
197
|
+
}
|
|
198
|
+
|
|
291
199
|
interface IWebFetcher {
|
|
292
|
-
|
|
200
|
+
/**
|
|
201
|
+
* The web-read policy's decision (ADR-0027), for a read this fetcher will
|
|
202
|
+
* carry or one a runner carries natively, such as Claude's `WebFetch`.
|
|
203
|
+
* `fetch` and `search` decide for themselves; never call both.
|
|
204
|
+
*/
|
|
205
|
+
decide(read: WebRead): Promise<WebReadDecision>;
|
|
206
|
+
/** Whether a runner's own search through `provider` would run unasked; see `WebReadPolicy.searchesUnasked`. */
|
|
207
|
+
searchesUnasked?(provider: string): boolean;
|
|
293
208
|
fetch(url: string): Promise<ToolOutcome>;
|
|
294
209
|
/**
|
|
295
210
|
* Optional web search. A fetcher without it makes the `web_search` tool
|
|
@@ -297,6 +212,13 @@ interface IWebFetcher {
|
|
|
297
212
|
* degradation `fetch` already uses when no fetcher is wired at all.
|
|
298
213
|
*/
|
|
299
214
|
search?(query: string): Promise<ToolOutcome>;
|
|
215
|
+
/**
|
|
216
|
+
* A variant of this fetcher for a research subagent: same policy, cache,
|
|
217
|
+
* transport and budget, but a read that would ask a person is refused
|
|
218
|
+
* instead (ADR-0027, ADR-0008 T6). Absent means subagents get no web tools
|
|
219
|
+
* and the `fetch`/`web_search` tools report themselves unavailable.
|
|
220
|
+
*/
|
|
221
|
+
forSubagent?(): IWebFetcher;
|
|
300
222
|
}
|
|
301
223
|
|
|
302
224
|
/**
|
|
@@ -327,6 +249,195 @@ declare function resolveWithin(root: string, target: string, from?: string): Res
|
|
|
327
249
|
/** The directory a grant covers for `target` — its parent for files, itself for directories. */
|
|
328
250
|
declare function grantScopeFor(abs: string, kind: 'file' | 'directory'): string;
|
|
329
251
|
|
|
252
|
+
/**
|
|
253
|
+
* A web-search backend behind a narrow seam (ADR-0027). The fetcher carries
|
|
254
|
+
* the bytes through its vetted transport; a provider owns only the endpoint,
|
|
255
|
+
* how to read its results, and how it reacts when it pushes back. `id` flows
|
|
256
|
+
* into the web-read policy's `search` decision, so an approval names the third
|
|
257
|
+
* party that receives the query.
|
|
258
|
+
*
|
|
259
|
+
* One provider exists today (DuckDuckGo's lite endpoint, zero-configuration).
|
|
260
|
+
* The seam exists so adding another is one class, not a refactor.
|
|
261
|
+
*/
|
|
262
|
+
/** One search result: a title, its URL, and an optional snippet. */
|
|
263
|
+
interface SearchHit {
|
|
264
|
+
title: string;
|
|
265
|
+
url: string;
|
|
266
|
+
snippet?: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* The fetcher's vetted page fetch, as a provider sees it. `status` is carried
|
|
270
|
+
* so a provider can tell 429/403 ("pushed back") from a plain error, and the
|
|
271
|
+
* body so it can tell a results page from a challenge.
|
|
272
|
+
*/
|
|
273
|
+
type SearchPage = {
|
|
274
|
+
ok: true;
|
|
275
|
+
status: number;
|
|
276
|
+
body: string;
|
|
277
|
+
} | {
|
|
278
|
+
ok: false;
|
|
279
|
+
status?: number;
|
|
280
|
+
error: string;
|
|
281
|
+
};
|
|
282
|
+
type SearchTransport = (url: string) => Promise<SearchPage>;
|
|
283
|
+
/**
|
|
284
|
+
* What one lookup produced. `blocked` means the provider pushed back and
|
|
285
|
+
* marked itself unavailable; `none` is a plain 200 with nothing parseable,
|
|
286
|
+
* which is not a block; `error` is anything else that went wrong.
|
|
287
|
+
*/
|
|
288
|
+
type SearchOutcome = {
|
|
289
|
+
kind: 'hits';
|
|
290
|
+
hits: SearchHit[];
|
|
291
|
+
} | {
|
|
292
|
+
kind: 'none';
|
|
293
|
+
} | {
|
|
294
|
+
kind: 'blocked';
|
|
295
|
+
reason: string;
|
|
296
|
+
} | {
|
|
297
|
+
kind: 'error';
|
|
298
|
+
error: string;
|
|
299
|
+
};
|
|
300
|
+
interface ISearchProvider {
|
|
301
|
+
/** The id that names this backend in the web-read policy's `search` decision. */
|
|
302
|
+
readonly id: string;
|
|
303
|
+
/** The human name shown wherever the query's destination is named. */
|
|
304
|
+
readonly name: string;
|
|
305
|
+
/** Whether a recent push-back has left the provider in cooldown; no request may go out. */
|
|
306
|
+
coolingDown(): boolean;
|
|
307
|
+
/** Run one query through `get`, which fetches through the fetcher's pinned transport. */
|
|
308
|
+
search(query: string, get: SearchTransport): Promise<SearchOutcome>;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
declare function looksLikeChallenge(html: string): boolean;
|
|
312
|
+
/**
|
|
313
|
+
* Pull result links out of the lite endpoint's markup. A result's snippet is
|
|
314
|
+
* looked for only between its link and the next one: a result with no snippet
|
|
315
|
+
* must not borrow its neighbour's.
|
|
316
|
+
*/
|
|
317
|
+
declare function parseSearchHits(html: string): SearchHit[];
|
|
318
|
+
/**
|
|
319
|
+
* The provider's shared instance: one process-wide provider means the cooldown
|
|
320
|
+
* a push-back starts is seen by every session, not just the one that hit it.
|
|
321
|
+
* `now` is injectable so tests drive the cooldown without waiting.
|
|
322
|
+
*/
|
|
323
|
+
declare class DuckDuckGoSearchProvider implements ISearchProvider {
|
|
324
|
+
readonly id = "duckduckgo";
|
|
325
|
+
readonly name = "DuckDuckGo";
|
|
326
|
+
private failures;
|
|
327
|
+
private cooldownUntil;
|
|
328
|
+
private readonly now;
|
|
329
|
+
constructor(now?: () => number);
|
|
330
|
+
coolingDown(): boolean;
|
|
331
|
+
search(query: string, get: SearchTransport): Promise<SearchOutcome>;
|
|
332
|
+
private block;
|
|
333
|
+
}
|
|
334
|
+
/** The one provider every session's fetcher shares, so a cooldown is process-wide. */
|
|
335
|
+
declare const sharedSearchProvider: DuckDuckGoSearchProvider;
|
|
336
|
+
|
|
337
|
+
interface CachedPage {
|
|
338
|
+
body: string;
|
|
339
|
+
isHtml: boolean;
|
|
340
|
+
}
|
|
341
|
+
interface WebResponseCacheOptions {
|
|
342
|
+
ttlMs?: number;
|
|
343
|
+
maxEntries?: number;
|
|
344
|
+
maxBytes?: number;
|
|
345
|
+
now?: () => number;
|
|
346
|
+
}
|
|
347
|
+
declare class WebResponseCache {
|
|
348
|
+
private readonly entries;
|
|
349
|
+
private readonly ttlMs;
|
|
350
|
+
private readonly maxEntries;
|
|
351
|
+
private readonly maxBytes;
|
|
352
|
+
private readonly now;
|
|
353
|
+
private bytes;
|
|
354
|
+
constructor(opts?: WebResponseCacheOptions);
|
|
355
|
+
getFetch(url: string): CachedPage | undefined;
|
|
356
|
+
/** `maxAgeMs` is the response's own freshness; it shortens the TTL, never extends it. */
|
|
357
|
+
setFetch(url: string, page: CachedPage, maxAgeMs?: number): void;
|
|
358
|
+
getSearch(providerAndQuery: string): SearchHit[] | undefined;
|
|
359
|
+
setSearch(providerAndQuery: string, hits: SearchHit[]): void;
|
|
360
|
+
private get;
|
|
361
|
+
private set;
|
|
362
|
+
private delete;
|
|
363
|
+
}
|
|
364
|
+
/** The one cache every session's fetcher shares, so a page fetched once is reused across planners. */
|
|
365
|
+
declare const sharedWebResponseCache: WebResponseCache;
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* The concrete `fetch`/`web_search` implementation, in core so the web server
|
|
369
|
+
* and the VS Code extension share one behavior.
|
|
370
|
+
*
|
|
371
|
+
* Whether a read happens is the web-read policy's to decide (ADR-0027); this
|
|
372
|
+
* carries it. A redirect to another origin is put to the policy again here,
|
|
373
|
+
* since it saw only the first URL. Search goes through a pluggable provider
|
|
374
|
+
* behind the same transport; results and pages are cached in an injected,
|
|
375
|
+
* process-wide cache that saves the network but never the decision.
|
|
376
|
+
*/
|
|
377
|
+
/** The slice of a `fetch` Response the fetcher reads; the platform `fetch` satisfies it. */
|
|
378
|
+
interface WebResponse {
|
|
379
|
+
ok: boolean;
|
|
380
|
+
status: number;
|
|
381
|
+
headers: {
|
|
382
|
+
get(name: string): string | null;
|
|
383
|
+
};
|
|
384
|
+
body: unknown;
|
|
385
|
+
text(): Promise<string>;
|
|
386
|
+
}
|
|
387
|
+
type WebTransport = (url: string, init: {
|
|
388
|
+
signal: AbortSignal;
|
|
389
|
+
headers: Record<string, string>;
|
|
390
|
+
redirect: 'manual';
|
|
391
|
+
}) => Promise<WebResponse>;
|
|
392
|
+
interface HttpWebFetcherOptions {
|
|
393
|
+
policy: WebReadDecider;
|
|
394
|
+
/**
|
|
395
|
+
* Injected in tests; defaults to a node:http(s) transport whose sockets
|
|
396
|
+
* connect only to addresses `resolveHost` answered and the guard vetted.
|
|
397
|
+
*/
|
|
398
|
+
fetchImpl?: WebTransport;
|
|
399
|
+
maxChars?: number;
|
|
400
|
+
timeoutMs?: number;
|
|
401
|
+
/** Override DNS resolution (every answer for a name) in tests. */
|
|
402
|
+
resolveHost?: ResolveAll;
|
|
403
|
+
/** Shared across sessions in production; a fresh one per instance is the test default. */
|
|
404
|
+
cache?: WebResponseCache;
|
|
405
|
+
/** Shared across sessions so the search cooldown is process-wide. */
|
|
406
|
+
searchProvider?: ISearchProvider;
|
|
407
|
+
/** False for a research subagent, which must never prompt (see {@link forSubagent}). */
|
|
408
|
+
prompting?: boolean;
|
|
409
|
+
}
|
|
410
|
+
type WebReadDecider = Pick<WebReadPolicy, 'decide'> & Partial<Pick<WebReadPolicy, 'searchesUnasked'>>;
|
|
411
|
+
declare class HttpWebFetcher implements IWebFetcher {
|
|
412
|
+
private readonly policy;
|
|
413
|
+
private readonly fetchImpl;
|
|
414
|
+
private readonly maxChars;
|
|
415
|
+
private readonly timeoutMs;
|
|
416
|
+
private readonly resolveHost;
|
|
417
|
+
private readonly cache;
|
|
418
|
+
private readonly searchProvider;
|
|
419
|
+
private readonly prompting;
|
|
420
|
+
constructor(opts: HttpWebFetcherOptions);
|
|
421
|
+
decide(read: WebRead): Promise<WebReadDecision>;
|
|
422
|
+
private get decideOptions();
|
|
423
|
+
forSubagent(): IWebFetcher;
|
|
424
|
+
searchesUnasked(provider: string): boolean;
|
|
425
|
+
fetch(url: string): Promise<ToolOutcome>;
|
|
426
|
+
search(query: string): Promise<ToolOutcome>;
|
|
427
|
+
private get;
|
|
428
|
+
private render;
|
|
429
|
+
private getSearchPage;
|
|
430
|
+
private request;
|
|
431
|
+
/**
|
|
432
|
+
* Why a redirect must not be followed, or `undefined` if it may. The policy
|
|
433
|
+
* decided only the first URL, so a hop to another origin is a new read with
|
|
434
|
+
* the same decision; otherwise a redirect would carry the fetch past an
|
|
435
|
+
* exclusion, a Guarded grant or the budget.
|
|
436
|
+
*/
|
|
437
|
+
private refuseRedirect;
|
|
438
|
+
private hop;
|
|
439
|
+
}
|
|
440
|
+
|
|
330
441
|
/**
|
|
331
442
|
* The bridge between "core needs an answer" and "a human somewhere is looking
|
|
332
443
|
* at a UI". Core cannot prompt: the human may be at a browser, a TUI, a CLI
|
|
@@ -603,7 +714,9 @@ declare abstract class BaseConfig implements IConfig {
|
|
|
603
714
|
get workspaceRepos(): string[];
|
|
604
715
|
get worktreeLinks(): string[];
|
|
605
716
|
get conflictRepairAttempts(): number;
|
|
606
|
-
get approvalMode():
|
|
717
|
+
get approvalMode(): ApprovalModeSetting;
|
|
718
|
+
get webReadBudget(): number;
|
|
719
|
+
get approvalDefaults(): boolean;
|
|
607
720
|
get approvalPreApproved(): string[];
|
|
608
721
|
protected static detectProvider(fallback: AiProvider): AiProvider;
|
|
609
722
|
}
|
|
@@ -856,6 +969,16 @@ type LiveOutputLookup = (taskId: string, opts: LiveTailOptions) => LiveTail | nu
|
|
|
856
969
|
*/
|
|
857
970
|
declare function renderTaskQueryAnswer(query: TaskQuery, tasks: readonly Task[], catalog: TaskQueryCatalog, liveOutput?: LiveOutputLookup): string;
|
|
858
971
|
|
|
972
|
+
/**
|
|
973
|
+
* A person's approvals of project MCP servers, kept across sessions
|
|
974
|
+
* (ADR-0028). Keyed by repository root and scope, which names the server
|
|
975
|
+
* and hashes its definition: a changed definition is a new question.
|
|
976
|
+
*/
|
|
977
|
+
interface ProjectServerApprovals {
|
|
978
|
+
approved(repoRoot: string, scope: string): boolean;
|
|
979
|
+
remember(repoRoot: string, scope: string): void;
|
|
980
|
+
}
|
|
981
|
+
|
|
859
982
|
interface CliAgentAiServiceDeps extends Partial<AgentProcessDeps> {
|
|
860
983
|
/** Overrides adapter construction. Tests supply a fake agent; production picks by runner id. */
|
|
861
984
|
createAdapter?: (runner: string, deps: AgentProcessDeps) => AgentAdapter | null;
|
|
@@ -863,6 +986,8 @@ interface CliAgentAiServiceDeps extends Partial<AgentProcessDeps> {
|
|
|
863
986
|
workspaceRoot?: () => string;
|
|
864
987
|
/** Where a conversation's planner tools are served (ADR-0022). Absent: no conversation can start. */
|
|
865
988
|
mcpServer?: OrdewellMcpServer;
|
|
989
|
+
/** A person's approvals of project MCP servers, kept across sessions (ADR-0028). Defaults to Ordewell's data directory. */
|
|
990
|
+
projectServerApprovals?: ProjectServerApprovals;
|
|
866
991
|
}
|
|
867
992
|
/**
|
|
868
993
|
* A coding agent driven as Ordewell's planner (ADR-0009).
|
|
@@ -883,6 +1008,7 @@ declare class CliAgentAiService implements IAiService {
|
|
|
883
1008
|
private readonly processDeps;
|
|
884
1009
|
private readonly makeAdapter;
|
|
885
1010
|
private readonly workspaceRoot;
|
|
1011
|
+
private environmentSecrets;
|
|
886
1012
|
private adapter;
|
|
887
1013
|
/**
|
|
888
1014
|
* The agent's own session id, kept across a process death so the next turn
|
|
@@ -890,10 +1016,20 @@ declare class CliAgentAiService implements IAiService {
|
|
|
890
1016
|
* every session boundary — nothing from one goal may reach the next.
|
|
891
1017
|
*/
|
|
892
1018
|
private lastNativeSessionId;
|
|
1019
|
+
/** `gate` is what the agent's own tool requests are decided against; absent, only Ordewell's tools are allowed (ADR-0026). */
|
|
893
1020
|
private conversation;
|
|
1021
|
+
/**
|
|
1022
|
+
* What the runner's own session-wide search is decided against
|
|
1023
|
+
* (ADR-0027), asked again before every turn: the session's mode, its
|
|
1024
|
+
* exclusions or its budget can change between turns. Absent, it is off.
|
|
1025
|
+
*/
|
|
1026
|
+
private searchesUnasked;
|
|
894
1027
|
private readonly mcpServer;
|
|
1028
|
+
private readonly projectServerApprovals;
|
|
895
1029
|
/** The planner token the running process was spawned with; revoked with the process (ADR-0022, A3). */
|
|
896
1030
|
private plannerToken;
|
|
1031
|
+
/** The {@link PlannerStartOptions.nativeSearch} the running process was spawned with. */
|
|
1032
|
+
private adapterNativeSearch;
|
|
897
1033
|
private activeAbort;
|
|
898
1034
|
/**
|
|
899
1035
|
* Every subagent this conversation has reported starting, and finishing.
|
|
@@ -916,6 +1052,7 @@ declare class CliAgentAiService implements IAiService {
|
|
|
916
1052
|
plannerToolsAttached(): boolean;
|
|
917
1053
|
/** The agent's own session id, a resumption hint only — Ordewell's transcript is authoritative (T4). */
|
|
918
1054
|
nativeSessionId(): string | null;
|
|
1055
|
+
heldSecrets(): readonly string[];
|
|
919
1056
|
reset(): void;
|
|
920
1057
|
startConversation(req: ConversationRequest): Promise<ConversationTurn>;
|
|
921
1058
|
continueConversation(userMessage: string, onProgress: (progress: ResearchProgress) => void, signal?: AbortSignal): Promise<ConversationTurn>;
|
|
@@ -946,13 +1083,27 @@ declare class CliAgentAiService implements IAiService {
|
|
|
946
1083
|
private startWithTools;
|
|
947
1084
|
/** Kill the planner process, and with it the token it was spawned with. */
|
|
948
1085
|
private disposeAdapter;
|
|
1086
|
+
/** Whether the web-read policy lets the runner's own session-wide search run unasked now (ADR-0027). */
|
|
1087
|
+
private nativeSearch;
|
|
949
1088
|
/**
|
|
950
1089
|
* The live agent process, restarted from its own session id if it died
|
|
951
1090
|
* between turns. Resume is a hint: when it fails, the caller's next
|
|
952
1091
|
* `startConversation` reseeds from Ordewell's transcript, which is the same
|
|
953
1092
|
* degradation `restoreChat` already performs on every surface.
|
|
1093
|
+
*
|
|
1094
|
+
* Also restarted when the policy's decision on the runner's own search has
|
|
1095
|
+
* changed since the process was spawned: the running thread would otherwise
|
|
1096
|
+
* keep searching unasked after Full turned Guarded. Codex 0.162 applies
|
|
1097
|
+
* `thread/resume`'s `config.web_search` either way (checked live).
|
|
954
1098
|
*/
|
|
955
1099
|
private ensureAdapter;
|
|
1100
|
+
/**
|
|
1101
|
+
* What the planner gets of the repository's config, its runner being
|
|
1102
|
+
* launched without it (ADR-0028): the instruction files, which are text, in
|
|
1103
|
+
* its system prompt, and the project MCP servers it may start. Decided once
|
|
1104
|
+
* per conversation, so a respawn starts the same servers without asking.
|
|
1105
|
+
*/
|
|
1106
|
+
private repoConfig;
|
|
956
1107
|
private plannerModel;
|
|
957
1108
|
/**
|
|
958
1109
|
* A plan from one-shot agent sessions: only what a submit_plan call
|
|
@@ -1025,6 +1176,12 @@ interface ConversationRequest {
|
|
|
1025
1176
|
*/
|
|
1026
1177
|
initialMessage?: string;
|
|
1027
1178
|
plannerTools?: PlannerToolsOffer;
|
|
1179
|
+
/**
|
|
1180
|
+
* The session's approval policy, which a harness planner's own tool
|
|
1181
|
+
* requests are decided against as the API planner's are (ADR-0026). Absent:
|
|
1182
|
+
* nobody can be asked, so they are denied.
|
|
1183
|
+
*/
|
|
1184
|
+
approval?: IApproval;
|
|
1028
1185
|
/**
|
|
1029
1186
|
* The workspace's skill catalog. Every planner is shown the task skills it
|
|
1030
1187
|
* may attach; only one with tools is shown the planner skills, which load
|
|
@@ -1065,6 +1222,8 @@ type ConversationTurn =
|
|
|
1065
1222
|
researchLog: ResearchLogEntry[];
|
|
1066
1223
|
};
|
|
1067
1224
|
interface IAiService {
|
|
1225
|
+
/** Credential values from the harness planner's effective environment, for the outbound secret check. */
|
|
1226
|
+
heldSecrets?(): readonly string[];
|
|
1068
1227
|
/**
|
|
1069
1228
|
* Begin the planner conversation: collect workspace context, run the
|
|
1070
1229
|
* research/tool loop, and return the first planner turn. The service
|
|
@@ -2642,7 +2801,8 @@ declare const ORDEWELL_SETTABLE_ENV: readonly string[];
|
|
|
2642
2801
|
* a known escalation from "can change a setting" to "can run code as the user":
|
|
2643
2802
|
*
|
|
2644
2803
|
* - The approval-mode and pre-approved-scope variables switch the consent gate
|
|
2645
|
-
* off, so every later command runs unprompted
|
|
2804
|
+
* off, so every later command runs unprompted; the web-read budget bounds
|
|
2805
|
+
* how much a planner may send out unasked in Full.
|
|
2646
2806
|
* - The settings-path override is honoured by the settings service, which
|
|
2647
2807
|
* creates directories recursively when persisting — admitting it turns the
|
|
2648
2808
|
* same write into an arbitrary-path file write.
|
|
@@ -2731,8 +2891,11 @@ declare abstract class StdioAgentAdapter implements AgentAdapter {
|
|
|
2731
2891
|
/** What this process is to the user — a planner or a task's runner — for the words a failure is reported in. */
|
|
2732
2892
|
protected role: 'planner' | 'task';
|
|
2733
2893
|
constructor(deps: AgentProcessDeps);
|
|
2734
|
-
/**
|
|
2735
|
-
|
|
2894
|
+
/**
|
|
2895
|
+
* The command line that starts this agent in its read-only mode, given the
|
|
2896
|
+
* workspace's own variables (ADR-0016) the process will run under.
|
|
2897
|
+
*/
|
|
2898
|
+
protected abstract spawnSpec(opts: AgentStartOptions, workspace: Record<string, string>): SpawnSpec;
|
|
2736
2899
|
/** The bytes written to stdin to open one user turn. Must end with a newline. */
|
|
2737
2900
|
protected abstract turnPayload(message: string): string;
|
|
2738
2901
|
/**
|
|
@@ -2817,7 +2980,7 @@ declare class ClaudeCodeAdapter extends StdioAgentAdapter implements TaskModeAge
|
|
|
2817
2980
|
private readonly steers;
|
|
2818
2981
|
/** The last turn's `result` ended it, so a steer's echo now opens a turn the CLI started for that message. */
|
|
2819
2982
|
private turnClosed;
|
|
2820
|
-
protected spawnSpec(opts: AgentStartOptions): SpawnSpec;
|
|
2983
|
+
protected spawnSpec(opts: AgentStartOptions, workspace: Record<string, string>): SpawnSpec;
|
|
2821
2984
|
/**
|
|
2822
2985
|
* A task's run: the manifest decides what its mode and effort mean
|
|
2823
2986
|
* (ADR-0001), and this adds only the protocol around them. No tool list and
|
|
@@ -2826,6 +2989,13 @@ declare class ClaudeCodeAdapter extends StdioAgentAdapter implements TaskModeAge
|
|
|
2826
2989
|
* without it `-p` refuses them silently and nothing can ever surface one.
|
|
2827
2990
|
*/
|
|
2828
2991
|
private taskSpawnSpec;
|
|
2992
|
+
/**
|
|
2993
|
+
* What user-only settings stop the CLI loading that is not the
|
|
2994
|
+
* repository's to choose (ADR-0028): the user's own local-scope servers,
|
|
2995
|
+
* under the `CLAUDE_CONFIG_DIR` the planner runs with, and the project
|
|
2996
|
+
* servers approved for it.
|
|
2997
|
+
*/
|
|
2998
|
+
private plannerServers;
|
|
2829
2999
|
/** The file holding the token lives exactly as long as the process that reads it. */
|
|
2830
3000
|
private ordewellServerArgs;
|
|
2831
3001
|
private removeMcpConfig;
|
|
@@ -2952,6 +3122,8 @@ declare class CodexAdapter extends StdioAgentAdapter implements TaskModeAgentAda
|
|
|
2952
3122
|
private readonly interruptedTurnIds;
|
|
2953
3123
|
/** A task's approval requests still waiting for an answer, by the request id as a string. */
|
|
2954
3124
|
private readonly openPermissions;
|
|
3125
|
+
/** The tool each MCP server's latest call is for, which names the tool an approval asks about when its question does not. */
|
|
3126
|
+
private readonly mcpCallsInProgress;
|
|
2955
3127
|
/**
|
|
2956
3128
|
* The files each in-flight `fileChange` item touches. Its approval request
|
|
2957
3129
|
* names only the item, and a person deciding needs to see the files.
|
|
@@ -3074,6 +3246,12 @@ declare class CodexAdapter extends StdioAgentAdapter implements TaskModeAgentAda
|
|
|
3074
3246
|
* failed request and plans around, rather than waiting on.
|
|
3075
3247
|
*/
|
|
3076
3248
|
private answerServerRequest;
|
|
3249
|
+
/**
|
|
3250
|
+
* A planner's approval for a tool of the user's own MCP server, held for the
|
|
3251
|
+
* planner's envelope to answer (ADR-0026). Codex names the server; the tool
|
|
3252
|
+
* is in its question, or else the call it last started on that server.
|
|
3253
|
+
*/
|
|
3254
|
+
private holdMcpToolApproval;
|
|
3077
3255
|
/** A tool item entering `inProgress` — announce the call so the timeline moves. */
|
|
3078
3256
|
private emitItemStart;
|
|
3079
3257
|
private emitItemDone;
|
|
@@ -3135,6 +3313,8 @@ declare class OpenCodeAdapter implements TaskModeAgentAdapter {
|
|
|
3135
3313
|
private taskTurn;
|
|
3136
3314
|
/** An abort was posted during the current task turn, so the idle that follows ends it as interrupted. */
|
|
3137
3315
|
private interruptRequested;
|
|
3316
|
+
/** The user's MCP servers, as `/mcp` last listed them: what tells a planner's MCP tool request from a built-in's (ADR-0026). */
|
|
3317
|
+
private mcpServers;
|
|
3138
3318
|
private readonly permissions;
|
|
3139
3319
|
/** Messages handed into the running task turn, until the model reads them (ADR-0023). Kept across turns: the server keeps the message too. */
|
|
3140
3320
|
private readonly steers;
|
|
@@ -3213,7 +3393,7 @@ declare class OpenCodeAdapter implements TaskModeAgentAdapter {
|
|
|
3213
3393
|
* only 2.x answers `/api/info` with its version. A 1.x server — or one that
|
|
3214
3394
|
* answers with anything else — keeps the 1.x protocol this class speaks.
|
|
3215
3395
|
*/
|
|
3216
|
-
private
|
|
3396
|
+
private v2Version;
|
|
3217
3397
|
private role;
|
|
3218
3398
|
/**
|
|
3219
3399
|
* Turn one settled assistant message into events. The settled response is
|
|
@@ -3281,8 +3461,11 @@ declare class OpenCodeAdapter implements TaskModeAgentAdapter {
|
|
|
3281
3461
|
private request;
|
|
3282
3462
|
private headers;
|
|
3283
3463
|
nativeSessionId(): string | null;
|
|
3464
|
+
unusableProjectServers(): ProjectMcpServer[];
|
|
3284
3465
|
/** Asks the server, which lists every MCP server it has with the state of its connection. */
|
|
3285
3466
|
mcpAttached(): Promise<boolean>;
|
|
3467
|
+
/** 2.x lists its servers as `{ name, status: { status } }`, and only once it has started connecting them. */
|
|
3468
|
+
private v2McpStatus;
|
|
3286
3469
|
dispose(): void;
|
|
3287
3470
|
private exitMessage;
|
|
3288
3471
|
}
|
|
@@ -5914,4 +6097,4 @@ declare const DEFAULT_MAX_PARALLEL = 5;
|
|
|
5914
6097
|
*/
|
|
5915
6098
|
declare function parseMaxParallel(value: unknown): number | null;
|
|
5916
6099
|
|
|
5917
|
-
export { ALL_PROVIDERS,
|
|
6100
|
+
export { ALL_PROVIDERS, AbstractRunner, AbstractRunnerSession, ActiveTaskSession, type AdoptSessionResponse, type Adr0013IsolationRun, type Adr0013PlanIsolation, type Adr0013TaskRecord, AgentAdapter, AgentEvent, AgentProcessDeps, AgentStartOptions, AiProvider, AlreadyExecutingError, ApplyTaskOpsResult, ApprovalAnswer, type ApprovalAnswerResponse, ApprovalDecision, ApprovalModeSetting, ApprovalPolicy, ApprovalRequest, type ApprovalsResponse, type AskOptions, AwaitingReason, BaseAiService, BaseConfig, BaseFileSystem, BufferedTaskOutputSource, CLAUDE_CODE_MANIFEST, CLI_PROVIDERS, CMD_EXE_MAX_COMMAND_LINE, CORE_PLANNER_PROMPT, type CachedPage, type CancelPlanningResponse, type CappedRows, CheckpointAnswer, type CheckpointListener, ClaudeCodeAdapter, CliAgentAiService, type CliAgentAiServiceDeps, CodexAdapter, type CommandDescriptor, CommandLineTooLongError, type CommandsResponse, type ComposeOptions, ConsoleLogger, ContextCollector, type Continuability, ConversationBusyError, type ConversationCompactResponse, type ConversationCompaction, ConversationEditError, type ConversationFork, type ConversationForkResponse, ConversationMessage, type ConversationRequest, type ConversationRewind, type ConversationRewindResponse, type ConversationTurn, type ConversationVariant, DAEMON_SUBPROTOCOL, DAEMON_TOKEN_SUBPROTOCOL_PREFIX, DEFAULT_MAX_PARALLEL, DEFAULT_WEB_READ_BUDGET, type DaemonErrorCode, type DecideOptions, DiscoveredModel, DuckDuckGoSearchProvider, EmbeddedNewlineError, type EnvAdmission, EnvConfig, type ErrorBody, type ExecImpl, ExecutableNotFoundError, type ExecuteResponse, FindSymbolOptions, type ForceSendResponse, GREP_PCRE_PROBE_ARGS, GeminiService, type GeneratePlanResponse, type GitExecFn, GlobOptions, type GrepInvocation, GrepOptions, type GrepRegex, HARNESS_PLANNER_REASON, type HasBinFn, HttpWebFetcher, type HttpWebFetcherOptions, type IAiService, IApproval, IConfig, IFileSystem, type ILogger, type INotification, IRunner, IRunnerSession, type ISearchProvider, IWorktreeIsolation, type IsolationDiffResponse, IsolationHandoff, IsolationLandedTask, type IsolationMergeResponse, IsolationMergeResult, IsolationOutcome, IsolationRun, IsolationTaskRecord, IsolationTaskStatus, IsolationView, JSON_REPAIR_INSTRUCTION, type KillTreeDeps, type LaunchDeps, type LaunchPlan, LegacyPlanState, type LiveOutputLookup, type LiveTail, type LiveTailOptions, type MappedTool, type MergeGateEntry, type MergeGateResponse, MergeGateView, ModelResolver, type ModelResolverDeps, type ModelsResponse, type ModifyPlanRequest, NoPlanError, type NotificationAction, OPENCODE_MANIFEST, ORDEWELL_SETTABLE_ENV, OUTPUT_LINES_DEFAULT, OUTPUT_LINES_MAX, type OkResponse, OpenAiService, OpenCodeAdapter, type OrchestratorObserver, OrchestratorOption, OrdewellMcpServer, PROVIDER_CREDENTIAL_ENV, PROVIDER_DETECT_PRIORITY, PROVIDER_LABEL, PROVIDER_PRIORITY, PROVIDER_SHORT_LABEL, type PendingApproval, PendingApprovals, type PendingApprovalsOptions, PlanEditError, PlanIsolation, PlanParseError, type PlanRequest, type PlanResponse, PlanState, PlanStatus, PlanStore, Planner, type PlannerBackendEntry, type PlannerModelCandidate, type PlannerModelChoice, PlannerModelMemory, type PlannerModelRecall, type PlannerModelStore, type PlannerReplyClassification, type PlannerSubmission, PlannerToolHandler, PlannerTurnDiscardedError, PlannerTurnStoppedError, type PlannerUsability, PlannerUsage, type PrdBlock, type PrdResponse, type PriorOutput, ProviderModelLists, type ProviderRegistration, QueuedMessage, QueuedTaskMessage, ReadFileOpts, type RemoveMessageResponse, RepairEvidence, type RepairLoopOpts, type RepairVerdict, RepoGroupLayout, type ResearchChat, ResearchLogEntry, ResearchProgress, ResearchShell, ResearchToolType, type ResearchTurn, type ResolveConflictResponse, type RewindTarget, type RewindTargetsResponse, RunnerApprovals, type RunnerCatalog, RunnerId, RunnerInstallation, RunnerManifest, RunnerModeInfo, RunnerRegistry, type RunnerSpawnOptions, type RunnersResponse, SETTINGS_ENV_ALLOWLIST, SETTINGS_ENV_REFUSED, STATE_DIR, STATE_DIR_IGNORE, STOPPED_TOOL_RESULT, SYMBOL_LANGUAGES, type SaveSession, type SearchHit, type SearchOutcome, type SearchPage, type SearchTransport, Session, SessionBroadcaster, type SessionData, type SessionDeps, type SessionListResponse, SessionMessage, type SessionMeta, SessionNotFoundError, SessionNotice, type SessionPlanner, type SessionResponse, type SessionRuntimeSettings, type SettingsResponse, SettingsService, type SettingsUpdateResponse, SkillInfo, type SkillInvocation, SkillLoad, SkillsService, type SpawnSpec, StdioAgentAdapter, type StopResponse, StructuredEvent, StructuredRunner, type StructuredRunnerDeps, StructuredSession, StructuredTurnEnd, SurfacePlan, SurfacePlanState, TASK_QUERY_ANSWER_MAX_CHARS, TASK_QUERY_ANSWER_OR_OPS, TASK_QUERY_FIELDS, TASK_QUERY_PROTOCOL, TASK_QUERY_REMINDER, TRUNCATED_PLAN_REPAIR_INSTRUCTION, Task, type TaskAttemptSnapshot, TaskCompleteArgs, TaskControlError, TaskIsolation, type TaskLogAttemptsResponse, TaskLogEvent, type TaskLogFile, type TaskLogLocation, TaskLogRecorder, type TaskLogRecorderDeps, type TaskLogResponse, type TaskMessageResponse, TaskModeAgentAdapter, TaskOp, TaskOrchestrator, type TaskOrchestratorDeps, type TaskOrchestratorOptions, type TaskOutputSource, type TaskQuery, type TaskQueryCatalog, type TaskQueryField, TaskRunnerFlags, TaskSkillSnapshot, TaskSnapshot, TaskStartOptions, TaskTokenScope, type TokenCarriers, type ToolCall, ToolOutcome, type ToolResult, TreeSnapshot, UsageRecord, type UserSettings, Verdict, VerdictEngine, type VerdictListener, WINDOWS_MAX_COMMAND_LINE, type WebRead, type WebReadDecision, type WebResponse, WebResponseCache, type WebResponseCacheOptions, type WebTransport, type WorkspaceCheckDeps, WorkspaceNotAProjectError, WorkspaceNotFoundError, type WorkspaceProjectCheckDeps, type WorkspacesResponse, type WorktreeIsolationDeps, abbreviateHome, admitSettingsEnv, applyHeadLimit, assertWorkspaceExists, assertWorkspaceIsProject, augmentPromptWithPriorOutputs, augmentedPath, bearerHeaderValue, buildConflictRepairPrompt, buildConflictResolutionPrompt, buildConversationSystemPrompt, buildFallbackGrepArgs, buildGlobArgs, buildGrepArgs, buildMergePrompt, buildModifyDuringExecutionPrompt, buildModifyPlanPrompt, buildPlanWithResults, buildResearchPrompt, buildResearchToolsPrompt, buildSplitPrompt, buildSubagentSystemPrompt, canContinue, clampThinkingEffort, classifyPlannerReply, clearAugmentedPathCache, clearDaemonToken, clearState, clipboardCopyCommand, coerceAssignments, collectDirectDependencyOutputs, composeAugmentedPrompt, composeContinuationPrompt, configuredProviders, continuability, createAiService, createSession, createTaskAdapter, createWorktreeIsolation, daemonTokenPath, defaultLogger, definitionPattern, deleteSession, describeMergeResult, discoverGeminiModels, effectiveAllowlist, ensureDir, ensurePrivateDir, ensureStateDirIgnored, executionLogBlock, extractPrdBlock, extractPresentedToken, filterFallbackByAnchoredInclude, filterModelsForPrompt, formatSearchOutput, generatePlanWithRepair, getLatestSession, getProviderMeta, getSettingsPath, getStateDir, globalDataDir, grantScopeFor, grepRegexFromProbe, idSegment, includeGlobFor, isCliProvider, isExecutableResolved, isOpenAiProvider, killTree, languageForId, listSessions, listTaskLogAttempts, loadSession, loadSessionPlanState, loadState, looksLikeChallenge, mapAgentTool, migrateOldConfigDir, migratePlanIsolation, mintDaemonToken, mintSessionId, modelContextBlock, modifyValidationFeedback, normalizeAgentArgs, normalizeGeminiModel, openTaskLog, parseMaxParallel, parseSearchHits, parseTaskQueryJson, pendingEditRulesBlock, planDirectLaunch, plannerBackendEntries, plannerMessage, plannerTranscript, prefixModelId, providerForRunner, reEmitPlanPrompt, reEmitTaskOpsPrompt, reEmitTaskQueryPrompt, readDaemonToken, readTaskLog, referencePattern, removedPluginNotice, renderPlanMap, renderPriorOutputs, renderTaskQueryAnswer, repairLoop, resolveProviderFromPrefix, resolveSkillInvocation, resolveTaskRunnerFlags, resolveWithin, resubmitEditPrompt, resubmitPlanPrompt, retargetTaskRunner, runnerAssignment, runnerForProvider, sanitizeSlug, savePrdMarkdown, saveSession, saveState, sessionDataDir, sessionRuntimeSettings, sharedSearchProvider, sharedWebResponseCache, stateExists, stripAnsi, stripModelPrefix, summarizeOutput, supportsTaskMode, taskOpsRejectedPrompt, taskQuerySignature, textHasTaskQuery, tokenSubprotocols, tokensMatch, truncatedPlanReEmitPrompt, wellKnownBinDirs, windowsCommandLine, withPath, writePrivateFile };
|