@ordewell/core 0.9.0 → 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-DpaaFdit.d.ts → IFileSystem-BjiyCQ8O.d.ts} +3 -1
- package/dist/{IFileSystem-_m7HdoxJ.d.mts → IFileSystem-Cy-TAWvu.d.mts} +3 -1
- package/dist/{IRunner-BiQio8gJ.d.ts → IRunner-Corods20.d.ts} +389 -67
- package/dist/{IRunner-CxiymkP_.d.mts → IRunner-D6YfbmHn.d.mts} +389 -67
- package/dist/{chunk-QUARDKVT.mjs → chunk-OOZWSUIE.mjs} +2 -2
- package/dist/chunk-OOZWSUIE.mjs.map +1 -0
- package/dist/index.d.mts +357 -198
- package/dist/index.d.ts +357 -198
- package/dist/index.js +2388 -511
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2365 -496
- package/dist/index.mjs.map +1 -1
- package/dist/{plan-utils-P3PIEwNa.d.mts → plan-utils-BmUp_Lko.d.mts} +3 -3
- package/dist/{plan-utils-6rUr7ZOx.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.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 +1 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +1 -0
- package/dist/testing.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-QUARDKVT.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 {
|
|
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,192 +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}.
|
|
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.
|
|
75
38
|
*/
|
|
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.
|
|
99
|
-
*/
|
|
100
|
-
declare const GIT_READONLY_SUBCOMMANDS: string[];
|
|
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
|
-
/** The planner's standing approvals (ADR-0026); an `ask` command they cover carries {@link CommandClassification.allowedBy}. */
|
|
131
|
-
allow?: PlannerAllowlist;
|
|
132
|
-
}
|
|
133
|
-
type CommandTier = 'auto' | 'ask' | 'refuse';
|
|
134
|
-
interface CommandClassification {
|
|
135
|
-
tier: CommandTier;
|
|
136
|
-
/** What a grant covers, for `ask`. Derived from the non-auto segments only. */
|
|
137
|
-
scope: string;
|
|
138
|
-
/** Populated for `refuse`: why, in a sentence the model can act on. */
|
|
139
|
-
reason?: string;
|
|
140
|
-
/** For `ask`: the allowlist rule that pre-approves every part of the command that needed asking. */
|
|
141
|
-
allowedBy?: string;
|
|
142
|
-
}
|
|
143
|
-
/**
|
|
144
|
-
* Classify one command line. Output redirection is refused outright unless the
|
|
145
|
-
* target provably writes nothing — `/dev/null`, or an fd duplication like
|
|
146
|
-
* `2>&1` — since a planner that writes files has stopped being a planner.
|
|
147
|
-
*/
|
|
148
|
-
declare function classifyCommand(command: string, opts?: CommandPolicyOptions): CommandClassification;
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Which interpreter runs the planner's `bash` tool, and in which language.
|
|
152
|
-
*
|
|
153
|
-
* `AUTO_COMMANDS` — the read-only tier that runs with no prompt — is `ls`, `cat`,
|
|
154
|
-
* `wc`, `head`, `tail`, `du`, `df`, `file`, `sort`, `uniq`, `basename`, `find`,
|
|
155
|
-
* `grep`. That set is POSIX, and passing it to `shell: true` on Windows means
|
|
156
|
-
* cmd.exe, where most of those names do not exist and `find` is an unrelated
|
|
157
|
-
* program that returns plausible wrong output instead of an error. The planner's
|
|
158
|
-
* whole research surface degraded to guessing, quietly.
|
|
159
|
-
*
|
|
160
|
-
* Rather than write a Windows dialect of every research command — a second
|
|
161
|
-
* behavior to keep in step forever — this finds a POSIX shell to run the
|
|
162
|
-
* existing ones in. Git for Windows ships a full one, and git is already a
|
|
163
|
-
* prerequisite for everything Ordewell does, so in practice it is there. Failing
|
|
164
|
-
* that, cmd.exe is used and the classifier is told so, because the one thing
|
|
165
|
-
* that must never happen is classifying a command in one language and running it
|
|
166
|
-
* in another: `commandPolicy` reads {@link ResearchShell.dialect} for exactly
|
|
167
|
-
* that reason.
|
|
168
|
-
*
|
|
169
|
-
* POSIX resolves to `{ file: null }`, meaning "use `shell: true`" — byte for
|
|
170
|
-
* byte what the adapters did before this module existed.
|
|
171
|
-
*
|
|
172
|
-
* Windows paths are built with `path.win32` explicitly, not the host-flavoured
|
|
173
|
-
* `path`, so the probe is the same on a Windows host as it is under a Linux
|
|
174
|
-
* test runner.
|
|
175
|
-
*/
|
|
176
|
-
type ShellDialect = 'posix' | 'cmd';
|
|
177
|
-
interface ResearchShell {
|
|
178
|
-
/**
|
|
179
|
-
* Executable that takes a command string, or null to use the host default
|
|
180
|
-
* via `shell: true`.
|
|
181
|
-
*/
|
|
182
|
-
file: string | null;
|
|
183
|
-
/** Arguments preceding the command string. */
|
|
184
|
-
args: string[];
|
|
185
|
-
/** The language the command string will be interpreted in. */
|
|
186
|
-
dialect: ShellDialect;
|
|
187
|
-
/**
|
|
188
|
-
* Directory holding this shell's POSIX utilities, when it brings its own.
|
|
189
|
-
* Prepended to PATH for the search subprocesses (`grep`, `tree`) that
|
|
190
|
-
* `execFile` starts without a shell, so they resolve too.
|
|
191
|
-
*/
|
|
192
|
-
utilsDir: string | null;
|
|
193
|
-
}
|
|
194
|
-
interface ResearchShellDeps {
|
|
195
|
-
platform?: NodeJS.Platform;
|
|
196
|
-
exists?: (candidate: string) => boolean;
|
|
197
|
-
env?: NodeJS.ProcessEnv;
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* The shell the planner's `bash` tool should use on this host. Resolved once per
|
|
201
|
-
* process — the answer cannot change while Ordewell runs, and the probe costs a
|
|
202
|
-
* handful of `stat` calls.
|
|
203
|
-
*/
|
|
204
|
-
declare function resolveResearchShell(deps?: ResearchShellDeps): ResearchShell;
|
|
205
|
-
/** Test seam: drop the per-process cache so the next call re-probes. */
|
|
206
|
-
declare function clearResearchShellCache(): void;
|
|
207
|
-
/**
|
|
208
|
-
* PATH for the search subprocesses the adapters start without a shell, with the
|
|
209
|
-
* research shell's own utilities in front. Without this, `grep` — the fallback
|
|
210
|
-
* when ripgrep is absent — is unresolvable on a Windows box even when a
|
|
211
|
-
* perfectly good `grep.exe` sits in the Git tree beside the shell.
|
|
212
|
-
*/
|
|
213
|
-
declare function researchToolsPath(shell: ResearchShell, basePath: string | undefined): string;
|
|
214
|
-
/**
|
|
215
|
-
* A message explaining a degraded research surface, or null when there is
|
|
216
|
-
* nothing to explain. Surfaced by the adapters on the first refused command so
|
|
217
|
-
* the limitation is visible rather than inferred from bad answers.
|
|
218
|
-
*/
|
|
219
|
-
declare function researchShellWarning(shell: ResearchShell): string | null;
|
|
39
|
+
type ResolveAll = (host: string) => Promise<string[]>;
|
|
220
40
|
|
|
221
41
|
/**
|
|
222
42
|
* The policy half of the planner's filesystem: path confinement, the tiered
|
|
@@ -231,7 +51,10 @@ declare function researchShellWarning(shell: ResearchShell): string | null;
|
|
|
231
51
|
* record.
|
|
232
52
|
*/
|
|
233
53
|
declare abstract class BaseFileSystem implements IFileSystem {
|
|
54
|
+
private readonly resolveWebHost;
|
|
234
55
|
private approval;
|
|
56
|
+
private outboundSecrets;
|
|
57
|
+
constructor(resolveWebHost?: ResolveAll);
|
|
235
58
|
/**
|
|
236
59
|
* The interpreter `execBashImpl` will hand the command to. Owned here rather
|
|
237
60
|
* than per-adapter because {@link classifyCommand} has to be told the same
|
|
@@ -241,6 +64,7 @@ declare abstract class BaseFileSystem implements IFileSystem {
|
|
|
241
64
|
protected readonly researchShell: ResearchShell;
|
|
242
65
|
/** Surfaces inject the human channel here; without it, external access is denied. */
|
|
243
66
|
setApproval(approval: IApproval): void;
|
|
67
|
+
setOutboundSecrets(secrets: () => Iterable<string>): void;
|
|
244
68
|
abstract getWorkspaceRoot(): string;
|
|
245
69
|
protected abstract readFileImpl(absPath: string, opts?: ReadFileOpts): Promise<ToolOutcome>;
|
|
246
70
|
protected abstract globImpl(pattern: string, absRoot: string, headLimit: number): Promise<ToolOutcome>;
|
|
@@ -292,8 +116,95 @@ declare abstract class BaseFileSystem implements IFileSystem {
|
|
|
292
116
|
bash(command: string, signal?: AbortSignal): Promise<ToolOutcome>;
|
|
293
117
|
}
|
|
294
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
|
+
|
|
295
199
|
interface IWebFetcher {
|
|
296
|
-
|
|
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;
|
|
297
208
|
fetch(url: string): Promise<ToolOutcome>;
|
|
298
209
|
/**
|
|
299
210
|
* Optional web search. A fetcher without it makes the `web_search` tool
|
|
@@ -301,6 +212,13 @@ interface IWebFetcher {
|
|
|
301
212
|
* degradation `fetch` already uses when no fetcher is wired at all.
|
|
302
213
|
*/
|
|
303
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;
|
|
304
222
|
}
|
|
305
223
|
|
|
306
224
|
/**
|
|
@@ -331,6 +249,195 @@ declare function resolveWithin(root: string, target: string, from?: string): Res
|
|
|
331
249
|
/** The directory a grant covers for `target` — its parent for files, itself for directories. */
|
|
332
250
|
declare function grantScopeFor(abs: string, kind: 'file' | 'directory'): string;
|
|
333
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
|
+
|
|
334
441
|
/**
|
|
335
442
|
* The bridge between "core needs an answer" and "a human somewhere is looking
|
|
336
443
|
* at a UI". Core cannot prompt: the human may be at a browser, a TUI, a CLI
|
|
@@ -608,6 +715,7 @@ declare abstract class BaseConfig implements IConfig {
|
|
|
608
715
|
get worktreeLinks(): string[];
|
|
609
716
|
get conflictRepairAttempts(): number;
|
|
610
717
|
get approvalMode(): ApprovalModeSetting;
|
|
718
|
+
get webReadBudget(): number;
|
|
611
719
|
get approvalDefaults(): boolean;
|
|
612
720
|
get approvalPreApproved(): string[];
|
|
613
721
|
protected static detectProvider(fallback: AiProvider): AiProvider;
|
|
@@ -861,6 +969,16 @@ type LiveOutputLookup = (taskId: string, opts: LiveTailOptions) => LiveTail | nu
|
|
|
861
969
|
*/
|
|
862
970
|
declare function renderTaskQueryAnswer(query: TaskQuery, tasks: readonly Task[], catalog: TaskQueryCatalog, liveOutput?: LiveOutputLookup): string;
|
|
863
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
|
+
|
|
864
982
|
interface CliAgentAiServiceDeps extends Partial<AgentProcessDeps> {
|
|
865
983
|
/** Overrides adapter construction. Tests supply a fake agent; production picks by runner id. */
|
|
866
984
|
createAdapter?: (runner: string, deps: AgentProcessDeps) => AgentAdapter | null;
|
|
@@ -868,6 +986,8 @@ interface CliAgentAiServiceDeps extends Partial<AgentProcessDeps> {
|
|
|
868
986
|
workspaceRoot?: () => string;
|
|
869
987
|
/** Where a conversation's planner tools are served (ADR-0022). Absent: no conversation can start. */
|
|
870
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;
|
|
871
991
|
}
|
|
872
992
|
/**
|
|
873
993
|
* A coding agent driven as Ordewell's planner (ADR-0009).
|
|
@@ -888,6 +1008,7 @@ declare class CliAgentAiService implements IAiService {
|
|
|
888
1008
|
private readonly processDeps;
|
|
889
1009
|
private readonly makeAdapter;
|
|
890
1010
|
private readonly workspaceRoot;
|
|
1011
|
+
private environmentSecrets;
|
|
891
1012
|
private adapter;
|
|
892
1013
|
/**
|
|
893
1014
|
* The agent's own session id, kept across a process death so the next turn
|
|
@@ -897,9 +1018,18 @@ declare class CliAgentAiService implements IAiService {
|
|
|
897
1018
|
private lastNativeSessionId;
|
|
898
1019
|
/** `gate` is what the agent's own tool requests are decided against; absent, only Ordewell's tools are allowed (ADR-0026). */
|
|
899
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;
|
|
900
1027
|
private readonly mcpServer;
|
|
1028
|
+
private readonly projectServerApprovals;
|
|
901
1029
|
/** The planner token the running process was spawned with; revoked with the process (ADR-0022, A3). */
|
|
902
1030
|
private plannerToken;
|
|
1031
|
+
/** The {@link PlannerStartOptions.nativeSearch} the running process was spawned with. */
|
|
1032
|
+
private adapterNativeSearch;
|
|
903
1033
|
private activeAbort;
|
|
904
1034
|
/**
|
|
905
1035
|
* Every subagent this conversation has reported starting, and finishing.
|
|
@@ -922,6 +1052,7 @@ declare class CliAgentAiService implements IAiService {
|
|
|
922
1052
|
plannerToolsAttached(): boolean;
|
|
923
1053
|
/** The agent's own session id, a resumption hint only — Ordewell's transcript is authoritative (T4). */
|
|
924
1054
|
nativeSessionId(): string | null;
|
|
1055
|
+
heldSecrets(): readonly string[];
|
|
925
1056
|
reset(): void;
|
|
926
1057
|
startConversation(req: ConversationRequest): Promise<ConversationTurn>;
|
|
927
1058
|
continueConversation(userMessage: string, onProgress: (progress: ResearchProgress) => void, signal?: AbortSignal): Promise<ConversationTurn>;
|
|
@@ -952,13 +1083,27 @@ declare class CliAgentAiService implements IAiService {
|
|
|
952
1083
|
private startWithTools;
|
|
953
1084
|
/** Kill the planner process, and with it the token it was spawned with. */
|
|
954
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;
|
|
955
1088
|
/**
|
|
956
1089
|
* The live agent process, restarted from its own session id if it died
|
|
957
1090
|
* between turns. Resume is a hint: when it fails, the caller's next
|
|
958
1091
|
* `startConversation` reseeds from Ordewell's transcript, which is the same
|
|
959
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).
|
|
960
1098
|
*/
|
|
961
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;
|
|
962
1107
|
private plannerModel;
|
|
963
1108
|
/**
|
|
964
1109
|
* A plan from one-shot agent sessions: only what a submit_plan call
|
|
@@ -1077,6 +1222,8 @@ type ConversationTurn =
|
|
|
1077
1222
|
researchLog: ResearchLogEntry[];
|
|
1078
1223
|
};
|
|
1079
1224
|
interface IAiService {
|
|
1225
|
+
/** Credential values from the harness planner's effective environment, for the outbound secret check. */
|
|
1226
|
+
heldSecrets?(): readonly string[];
|
|
1080
1227
|
/**
|
|
1081
1228
|
* Begin the planner conversation: collect workspace context, run the
|
|
1082
1229
|
* research/tool loop, and return the first planner turn. The service
|
|
@@ -2654,7 +2801,8 @@ declare const ORDEWELL_SETTABLE_ENV: readonly string[];
|
|
|
2654
2801
|
* a known escalation from "can change a setting" to "can run code as the user":
|
|
2655
2802
|
*
|
|
2656
2803
|
* - The approval-mode and pre-approved-scope variables switch the consent gate
|
|
2657
|
-
* 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.
|
|
2658
2806
|
* - The settings-path override is honoured by the settings service, which
|
|
2659
2807
|
* creates directories recursively when persisting — admitting it turns the
|
|
2660
2808
|
* same write into an arbitrary-path file write.
|
|
@@ -2743,8 +2891,11 @@ declare abstract class StdioAgentAdapter implements AgentAdapter {
|
|
|
2743
2891
|
/** What this process is to the user — a planner or a task's runner — for the words a failure is reported in. */
|
|
2744
2892
|
protected role: 'planner' | 'task';
|
|
2745
2893
|
constructor(deps: AgentProcessDeps);
|
|
2746
|
-
/**
|
|
2747
|
-
|
|
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;
|
|
2748
2899
|
/** The bytes written to stdin to open one user turn. Must end with a newline. */
|
|
2749
2900
|
protected abstract turnPayload(message: string): string;
|
|
2750
2901
|
/**
|
|
@@ -2829,7 +2980,7 @@ declare class ClaudeCodeAdapter extends StdioAgentAdapter implements TaskModeAge
|
|
|
2829
2980
|
private readonly steers;
|
|
2830
2981
|
/** The last turn's `result` ended it, so a steer's echo now opens a turn the CLI started for that message. */
|
|
2831
2982
|
private turnClosed;
|
|
2832
|
-
protected spawnSpec(opts: AgentStartOptions): SpawnSpec;
|
|
2983
|
+
protected spawnSpec(opts: AgentStartOptions, workspace: Record<string, string>): SpawnSpec;
|
|
2833
2984
|
/**
|
|
2834
2985
|
* A task's run: the manifest decides what its mode and effort mean
|
|
2835
2986
|
* (ADR-0001), and this adds only the protocol around them. No tool list and
|
|
@@ -2838,6 +2989,13 @@ declare class ClaudeCodeAdapter extends StdioAgentAdapter implements TaskModeAge
|
|
|
2838
2989
|
* without it `-p` refuses them silently and nothing can ever surface one.
|
|
2839
2990
|
*/
|
|
2840
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;
|
|
2841
2999
|
/** The file holding the token lives exactly as long as the process that reads it. */
|
|
2842
3000
|
private ordewellServerArgs;
|
|
2843
3001
|
private removeMcpConfig;
|
|
@@ -3235,7 +3393,7 @@ declare class OpenCodeAdapter implements TaskModeAgentAdapter {
|
|
|
3235
3393
|
* only 2.x answers `/api/info` with its version. A 1.x server — or one that
|
|
3236
3394
|
* answers with anything else — keeps the 1.x protocol this class speaks.
|
|
3237
3395
|
*/
|
|
3238
|
-
private
|
|
3396
|
+
private v2Version;
|
|
3239
3397
|
private role;
|
|
3240
3398
|
/**
|
|
3241
3399
|
* Turn one settled assistant message into events. The settled response is
|
|
@@ -3303,6 +3461,7 @@ declare class OpenCodeAdapter implements TaskModeAgentAdapter {
|
|
|
3303
3461
|
private request;
|
|
3304
3462
|
private headers;
|
|
3305
3463
|
nativeSessionId(): string | null;
|
|
3464
|
+
unusableProjectServers(): ProjectMcpServer[];
|
|
3306
3465
|
/** Asks the server, which lists every MCP server it has with the state of its connection. */
|
|
3307
3466
|
mcpAttached(): Promise<boolean>;
|
|
3308
3467
|
/** 2.x lists its servers as `{ name, status: { status } }`, and only once it has started connecting them. */
|
|
@@ -5938,4 +6097,4 @@ declare const DEFAULT_MAX_PARALLEL = 5;
|
|
|
5938
6097
|
*/
|
|
5939
6098
|
declare function parseMaxParallel(value: unknown): number | null;
|
|
5940
6099
|
|
|
5941
|
-
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 };
|