@ordewell/core 0.7.2 → 0.8.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.
Files changed (50) hide show
  1. package/README.md +9 -6
  2. package/dist/{IFileSystem-B5asBRDa.d.mts → IFileSystem-D96mT-bm.d.ts} +1 -1
  3. package/dist/{IFileSystem-CbCmUDBn.d.ts → IFileSystem-DXJCRw5x.d.mts} +1 -1
  4. package/dist/IRunner-CGCihlGQ.d.ts +1165 -0
  5. package/dist/IRunner-XVUddYVX.d.mts +1165 -0
  6. package/dist/{ModeResolver-DtfhWeVL.d.ts → ModeResolver-DE-o2lRF.d.mts} +2 -2
  7. package/dist/{ModeResolver-DcqAho4y.d.mts → ModeResolver-EWlpmVAy.d.ts} +2 -2
  8. package/dist/Task-1Q19y7sZ.d.mts +1122 -0
  9. package/dist/Task-1Q19y7sZ.d.ts +1122 -0
  10. package/dist/{chunk-OUIQWNS3.mjs → chunk-2M4X3VB7.mjs} +15 -5
  11. package/dist/chunk-2M4X3VB7.mjs.map +1 -0
  12. package/dist/{chunk-AJ5KDO6V.mjs → chunk-BLLIBCCS.mjs} +117 -198
  13. package/dist/chunk-BLLIBCCS.mjs.map +1 -0
  14. package/dist/{chunk-MZYZS7B3.mjs → chunk-UUU46PVQ.mjs} +68 -8
  15. package/dist/chunk-UUU46PVQ.mjs.map +1 -0
  16. package/dist/index.d.mts +517 -714
  17. package/dist/index.d.ts +517 -714
  18. package/dist/index.js +5013 -6371
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.mjs +3276 -4590
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/order-labels.d.mts +1 -4
  23. package/dist/order-labels.d.ts +1 -4
  24. package/dist/{parsing-COFGUEWx.d.ts → parsing-CZdp2p_n.d.ts} +5 -3
  25. package/dist/{parsing-D0uo-Icd.d.mts → parsing-GgUJoYKs.d.mts} +5 -3
  26. package/dist/parsing.d.mts +3 -6
  27. package/dist/parsing.d.ts +3 -6
  28. package/dist/parsing.js +25 -4
  29. package/dist/parsing.js.map +1 -1
  30. package/dist/parsing.mjs +2 -2
  31. package/dist/{plan-utils-CdW3mxt5.d.mts → plan-utils-BMayhGBj.d.mts} +89 -12
  32. package/dist/{plan-utils-D4Z8UyLL.d.ts → plan-utils-Cv48fe7r.d.ts} +89 -12
  33. package/dist/plan-utils.d.mts +4 -4
  34. package/dist/plan-utils.d.ts +4 -4
  35. package/dist/plan-utils.js +120 -65
  36. package/dist/plan-utils.js.map +1 -1
  37. package/dist/plan-utils.mjs +7 -3
  38. package/dist/testing.d.mts +12 -24
  39. package/dist/testing.d.ts +12 -24
  40. package/dist/testing.js +24 -28
  41. package/dist/testing.js.map +1 -1
  42. package/dist/testing.mjs +17 -27
  43. package/dist/testing.mjs.map +1 -1
  44. package/package.json +1 -1
  45. package/skills/tdd/SKILL.md +19 -0
  46. package/dist/Task-BpzIbunq.d.mts +0 -2599
  47. package/dist/Task-BpzIbunq.d.ts +0 -2599
  48. package/dist/chunk-AJ5KDO6V.mjs.map +0 -1
  49. package/dist/chunk-MZYZS7B3.mjs.map +0 -1
  50. package/dist/chunk-OUIQWNS3.mjs.map +0 -1
package/dist/index.d.ts CHANGED
@@ -1,16 +1,18 @@
1
- import { b0 as RunnerId, ay as PlanStatus, ac as LegacyPlanState, M as IApproval, p as ApprovalRequest, k as ApprovalDecision, j as ApprovalAnswer, P as ITerminalRunner, N as IConfig, h as AiProvider, aN as ProviderModelLists, m as ApprovalMode, $ as IsolationMergeResult, X as IsolationLandedTask, R as IWorktreeIsolation, a8 as IsolationTaskStatus, av as PlanIsolation, b5 as RunnerTransport, aV as RepoGroupLayout, Q as ITerminalSession, z as DiscoveredModel, bi as Task, f as AgentProcessDeps, c as AgentAdapter, as as OrdewellMcpServer, aX as ResearchProgress, aW as ResearchLogEntry, w as ConversationMessage, aB as PlannerToolHandler, bF as UsageRecord, bu as TaskSnapshot, r as AwaitingReason, U as IsolationHandoff, a4 as IsolationRun, a5 as IsolationTaskRecord, bk as TaskIsolation, a9 as IsolationView, a0 as IsolationOutcome, aU as RepairEvidence, bD as TreeSnapshot, bM as Verdict, b3 as RunnerRegistry, aS as QueuedTaskMessage, aR as QueuedMessage, b as ActiveTaskSession, ar as OrchestratorOption, bn as TaskModeAgentAdapter, g as AgentStartOptions, e as AgentEvent, a_ as ResearchToolType, aC as PlannerUsage, n as ApprovalPolicy, ax as PlanState, bj as TaskCompleteArgs, t as CheckpointAnswer, b1 as RunnerInvocation, A as AbstractRunner, a as AbstractTerminalSession, b6 as RunnerVersionProbe, bb as StructuredSessionCapability, bv as TaskStartOptions, bx as TaskTokenScope, bc as StructuredTurnEnd, ba as StructuredEvent, b4 as RunnerSpawnOptions, O as IPluginStore, b2 as RunnerPluginManifest, a$ as ResolveContext, bt as TaskRunnerFlags } from './Task-BpzIbunq.js';
2
- export { d as AgentAdapterFactory, i as AllProviderModels, l as ApprovalKind, o as ApprovalPolicyOptions, q as ApprovalSource, B as BlockingPrompt, C as CMD_EXE_MAX_COMMAND_LINE, s as CatalogModel, u as CheckpointArgs, v as CommandLineTooLongError, D as DEFAULT_RUNNERS, x as DENY_ALL, y as DiscoveredMode, E as DiscoveryCommand, F as EditPlanArgs, G as EmbeddedNewlineError, H as ExecutableNotFoundError, I as FetchAllProviderModelsOptions, J as HeadlessRunner, K as HeadlessRunnerDeps, L as HeadlessSession, S as IntegrationDisposal, T as IsolationAvailability, V as IsolationHandoffRepo, W as IsolationInactiveReason, Y as IsolationLanding, Z as IsolationMergeBlock, _ as IsolationMergeBlockReason, a1 as IsolationPruneResult, a2 as IsolationRemoval, a3 as IsolationRepo, a6 as IsolationTaskRef, a7 as IsolationTaskRepo, aa as LaunchDeps, ab as LaunchPlan, ad as LineBuffer, ae as ListModelsArgs, af as ListRunnersArgs, ag as McpClientConfig, ah as McpCredential, ai as McpTool, aj as McpToolContext, ak as McpToolReply, al as Message, am as ModelCatalog, an as ModelShortcut, ao as ORCHESTRATOR_SHORTCUTS, ap as ORDEWELL_MCP_PATH, aq as ORDEWELL_MCP_SERVER_NAME, at as OwnerOnlyFile, au as PLANNER_TOOLS, aw as PlanModificationWarnings, az as PlannerStartOptions, aA as PlannerTokenScope, aD as PluginCloneFn, aE as PluginEntry, aF as PluginFeatures, aG as PluginMode, aH as PluginModelDiscovery, aI as PluginRunnerDef, aJ as PreparedLaunch, aK as PreparedTask, aL as PreservedWork, aM as ProviderCredentialSource, aO as ProviderModelsResult, aP as PtySize, aQ as PtyWrapOptions, aT as RefusedRemoval, aY as ResearchStep, aZ as ResearchStepOutcome, b7 as StreamEvent, b8 as StreamStepEvent, b9 as StreamThinkingEvent, bd as SubagentLogEntry, be as SubagentOutcome, bf as SubmitPlanArgs, bg as TASK_COMPLETE_TOOL, bh as TASK_TOOLS, bl as TaskIsolationState, bm as TaskMode, bo as TaskModeUnsupportedError, bp as TaskModelAssignment, bq as TaskOutputArgs, br as TaskOutputSummary, bs as TaskQueryArgs, bw as TaskStatus, by as TaskToolHandler, bz as TaskTransport, bA as TaskType, bB as TaskWithParent, bC as ThinkingBlock, bE as UsageLine, bG as UsageTotals, bH as UserPromptEntry, bI as UserStep, bJ as ValidationCheck, bK as ValidationContext, bL as ValidationResult, bN as VerificationCheck, bO as WINDOWS_MAX_COMMAND_LINE, bP as addPlannerUsage, bQ as addTaskToPlan, bR as addUsage, bS as approvalScopes, bT as buildShellInvocation, bU as collectProviderCredentials, bV as createEmptyPlan, bW as createTask, bX as emptyWarnings, bY as enabledRunners, bZ as fetchAllProviderModels, b_ as flattenTasks, b$ as flattenTasksWithParents, c0 as inheritedOps, c1 as isAwaitingReason, c2 as isExecutableResolved, c3 as isGranted, c4 as isMeasured, c5 as isReservedRunnerName, c6 as isRunnerApproval, c7 as isRunnerTransport, c8 as isStructuredSession, c9 as keepExecutionState, ca as knownModelId, cb as mcpClientConfig, cc as migrateLegacyPlan, cd as migratePlanState, ce as migrateTask, cf as opsFlag, cg as ownerOnlyConfigFile, ch as partedPromptUsage, ci as planDirectLaunch, cj as planShellLaunch, ck as plannerContextFill, cl as posixShellQuote, cm as removeTaskFromPlan, cn as renumberTasks, co as resolveModelShortcut, cp as resolveProvider, cq as sharedMcpServer, cr as stripAnsi, cs as toApprovalDecision, ct as toOrchestratorOptions, cu as updateTaskInPlan, cv as usageLine, cw as validateModifiedPlan, cx as warningsText, cy as windowsCommandLine, cz as wrapWithPty } from './Task-BpzIbunq.js';
3
- import { B as TaskOp, M as MergeGateView, j as EditCatalog, s as SessionBroadcaster, A as ApplyTaskOpsResult, t as SessionMessage, u as SessionNotice, y as TaskLogEvent } from './plan-utils-D4Z8UyLL.js';
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 SerializedPlan, q as SerializedTask, r as SerializedTaskStatus, v as SubagentBlock, w as SubagentChild, x as SubagentStatus, T as TakenPrompt, z as TaskLogView, F as TaskRef, H as TaskRowAction, I as TaskRowContext, J as TaskRowIsolation, K as TaskRowKind, Q as TaskRowPlacement, R as TaskRowSubject, U as TaskRowView, V as TaskStatusKind, W as ThinkingDisplayBlock, X as ToolBlock, Y as ToolHeadline, Z as ToolStatus, _ as TurnGate, $ as UsageBlock, a0 as aheadOfDraft, a1 as applyTaskOps, a2 as approvalLabel, a3 as awaitingLabel, a4 as canMergeTasks, a5 as canSetDependencies, a6 as canSplitTask, a7 as capConflictFiles, a8 as classifyOutcome, a9 as coalesceTaskLog, aa as dependencyCandidates, ab as dependentsNotice, ac as dependentsOf, ad as diffRows, ae as diffStat, af as diffSummary, ag as digestTaskLog, ah as drainNext, ai as executionSummary, aj as followTurn, ak as fromTranscript, al as hasHiddenDetail, am as holdPrompt, an as isTaskRunning, ao as markAction, ap as markRequestFor, aq as namedRepos, ar as newTaskFields, as as opsEditable, at as outputLines, au as outputPreview, av as parseTaskOpsJson, aw as pastGateConfirmation, ax as reduceConversation, ay as reduceTaskLog, az as replayTaskLog, aA as runnerToolSubject, aB as serializePlan, aC as serializeTask, aD as serializeTaskStatus, aE as stopTurn, aF as summarizeToolCall, aG as taskRowActions, aH as taskRowView, aI as taskStartedNotice, aJ as taskStatusKind, aK as textHasTaskOps, aL as titledRefs, aM as toTaskLogEvent, aN as toolHeadline, aO as trimToolOutput, aP as truncateCheckpointSummary, aQ as unsendAll, aR as unsendLatest } from './plan-utils-D4Z8UyLL.js';
5
- import { I as IFileSystem, R as ReadFileOpts, T as ToolOutcome, b as GrepOptions, a as GlobOptions, F as FindSymbolOptions } from './IFileSystem-CbCmUDBn.js';
6
- export { G as GREP_DEFAULT_HEAD_LIMIT, c as GrepOutputMode, S as SEARCH_EXCLUSIONS } from './IFileSystem-CbCmUDBn.js';
7
- import { R as RunnerModeInfo } from './ModeResolver-DtfhWeVL.js';
8
- 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-DtfhWeVL.js';
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.js';
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.js';
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-Cv48fe7r.js';
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-Cv48fe7r.js';
5
+ import { I as IFileSystem, R as ReadFileOpts, T as ToolOutcome, b as GrepOptions, a as GlobOptions, F as FindSymbolOptions } from './IFileSystem-D96mT-bm.js';
6
+ export { G as GREP_DEFAULT_HEAD_LIMIT, c as GrepOutputMode, S as SEARCH_EXCLUSIONS } from './IFileSystem-D96mT-bm.js';
7
+ import { I as IApproval, m as ApprovalRequest, h as ApprovalDecision, g as ApprovalAnswer, s as IRunner, r as IConfig, e as AiProvider, W as ProviderModelLists, j as ApprovalMode, t as IRunnerSession, c as AgentProcessDeps, A as AgentAdapter, P as OrdewellMcpServer, U as PlannerToolHandler, a2 as RunnerRegistry, Y as QueuedTaskMessage, N as OrchestratorOption, aa as TaskModeAgentAdapter, d as AgentStartOptions, b as AgentEvent, k as ApprovalPolicy, a9 as TaskCompleteArgs, o as CheckpointAnswer, a5 as StructuredTurnEnd, a4 as StructuredEvent, af as TaskStartOptions, ag as TaskTokenScope, $ as RunnerManifest, ae as TaskRunnerFlags } from './IRunner-CGCihlGQ.js';
8
+ export { a as AgentAdapterFactory, f as AllProviderModels, i as ApprovalKind, l as ApprovalPolicyOptions, n as ApprovalSource, C as CatalogModel, p as CheckpointArgs, D as DENY_ALL, q as DiscoveryCommand, E as EditPlanArgs, F as FetchAllProviderModelsOptions, L as LineBuffer, u as ListModelsArgs, v as ListRunnersArgs, w as LoadSkillArgs, M as McpClientConfig, x as McpCredential, y as McpTool, z as McpToolContext, B as McpToolReply, G as ModelCatalog, H as ModelShortcut, O as ORCHESTRATOR_SHORTCUTS, J as ORDEWELL_MCP_PATH, K as ORDEWELL_MCP_SERVER_NAME, Q as OwnerOnlyFile, R as PLANNER_TOOLS, S as PlannerStartOptions, T as PlannerTokenScope, V as ProviderCredentialSource, X as ProviderModelsResult, Z as RunnerEntry, _ as RunnerFeatures, a0 as RunnerMode, a1 as RunnerModelDiscovery, a3 as SpawnFn, a6 as SubmitPlanArgs, a7 as TASK_COMPLETE_TOOL, a8 as TASK_TOOLS, ab as TaskModeUnsupportedError, ac as TaskOutputArgs, ad as TaskQueryArgs, ah as TaskToolHandler, ai as approvalScopes, aj as collectProviderCredentials, ak as enabledRunners, al as fetchAllProviderModels, am as isGranted, an as isRunnerApproval, ao as knownModelId, ap as mcpClientConfig, aq as ownerOnlyConfigFile, ar as resolveModelShortcut, as as resolveProvider, at as sharedMcpServer, au as toApprovalDecision, av as toOrchestratorOptions } from './IRunner-CGCihlGQ.js';
9
+ import { R as RunnerModeInfo } from './ModeResolver-EWlpmVAy.js';
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-EWlpmVAy.js';
9
11
  import { ChildProcess } from 'child_process';
10
- import { b as PlanParseError } from './parsing-COFGUEWx.js';
11
- export { P as PLAN_ENVELOPE_KEY, a as PartialPlanTask, c as PlanTaskError, d as PlanTasksResult, T as TASK_OPS_ENVELOPE_KEY, e as TASK_QUERY_ENVELOPE_KEY, f as checkDepsResolve, g as checkImmutableLog, h as checkInProgress, i as checkNoCycles, j as checkUniqueIds, k as escapeControlCharsInStrings, l as extractJsonObject, m as extractObjectWithBalance, n as extractObjectsWithKey, o as looksLikePlanAttempt, p as opensWithJsonObject, q as parsePartialPlan, r as parsePlanJson, s as stripModelNoise, t as stripTrailingCommas, v as validatePlanModification, u as validatePlanTasks } from './parsing-COFGUEWx.js';
12
+ import { b as PlanParseError } from './parsing-CZdp2p_n.js';
13
+ export { P as PLAN_ENVELOPE_KEY, a as PartialPlanTask, c as PlanTaskError, d as PlanTasksResult, T as TASK_OPS_ENVELOPE_KEY, e as TASK_QUERY_ENVELOPE_KEY, f as checkDepsResolve, g as checkImmutableLog, h as checkInProgress, i as checkNoCycles, j as checkUniqueIds, k as escapeControlCharsInStrings, l as extractJsonObject, m as extractObjectWithBalance, n as extractObjectsWithKey, o as looksLikePlanAttempt, p as opensWithJsonObject, q as parsePartialPlan, r as parsePlanJson, s as requestedSkills, t as stripModelNoise, u as stripTrailingCommas, v as validatePlanModification, w as validatePlanTasks } from './parsing-CZdp2p_n.js';
14
+ import { EventEmitter } from 'events';
12
15
  export { resolveOrderLabel, taskOrderLabel, taskRef, titledTaskRef } from './order-labels.js';
13
- import 'events';
14
16
  import 'zod/v4';
15
17
 
16
18
  interface SessionMeta {
@@ -410,7 +412,7 @@ declare class RunnerApprovals {
410
412
  /** The open request ids of each live structured session. */
411
413
  private readonly open;
412
414
  constructor(approvals: PendingApprovals);
413
- wrap(runner: ITerminalRunner): ITerminalRunner;
415
+ wrap(runner: IRunner): IRunner;
414
416
  /** How many of a task's runner requests wait for an answer — what "waiting for approval" is derived from. */
415
417
  waiting(taskId: string): number;
416
418
  private watch;
@@ -700,86 +702,31 @@ declare class ConsoleLogger implements ILogger {
700
702
  }
701
703
  declare const defaultLogger: ILogger;
702
704
 
703
- interface UserSettings {
704
- tdd: {
705
- enabled: boolean;
706
- };
707
- verification: {
708
- enabled: boolean;
709
- };
710
- modelAllowlist?: Record<string, string[]>;
711
- /** Last model (and its thinking effort) the user chose for each planner backend, keyed by AiProvider id. */
712
- plannerModels?: Record<string, {
713
- model: string;
714
- effort?: string;
715
- }>;
716
- /**
717
- * Runners the user picked for planning. Absent — not empty — is what falls
718
- * back to the environment's defaults; `[]` is a deliberate "none of them".
719
- */
720
- enabledRunners?: string[];
721
- /**
722
- * How tasks' runners are driven (ADR-0018). A run copies it onto its plan
723
- * when it starts, so a change applies from the next run.
724
- */
725
- runnerTransport: RunnerTransport;
726
- }
727
705
  /**
728
- * Where the user's toggles live. `ORDEWELL_SETTINGS_PATH` overrides it so several
729
- * Ordewell processes on one machine can hold *different* settings at the same
730
- * time. Without it the file is a single shared mutable global: the benchmark
731
- * harness runs parallel lanes that each pin the mode toggles, and because
732
- * `getAll()` re-reads whenever the mtime moves, a lane needing a toggle
733
- * `true` would silently plan with `false` the moment another lane pinned its
734
- * own — turning an A/B of that toggle into a comparison of one condition
735
- * against itself.
706
+ * Task skills end to end (ADR-0024): a skill reaches a runner only by being
707
+ * attached to its task in the plan, and Ordewell puts its body in the task's
708
+ * prompt — so it works the same on every runner, and nothing is written to a
709
+ * harness's own skills directory.
736
710
  */
737
- declare function getSettingsPath(): string;
738
- declare class SettingsService {
739
- private filePath;
740
- private cache;
741
- private cachedMtimeMs;
711
+ /** Where a task's skill names are looked up: global first, then the workspace folders it reads. */
712
+ interface SkillLookup extends Pick<SkillsService, 'findSkill' | 'searchedDirs'> {
742
713
  /**
743
- * Whether the transport on disk (or just set) is the user's own choice.
744
- * Writing the default back out would turn it into one, and a later change of
745
- * default would then never reach this user.
714
+ * Set when tasks get worktrees: of `skills`, the workspace ones git will not
715
+ * carry into them, each SKILL.md path mapped to the folder to commit,
716
+ * relative to the workspace root.
746
717
  */
747
- private transportChosen;
748
- constructor(filePath?: string);
749
- getAll(): UserSettings;
750
- private fileMtimeMs;
751
- getTdd(): boolean;
752
- setTdd(enabled: boolean): void;
753
- getVerification(): boolean;
754
- setVerification(enabled: boolean): void;
755
- getRunnerTransport(): RunnerTransport;
756
- setRunnerTransport(transport: RunnerTransport): void;
757
- getModelAllowlist(runner: string): string[] | undefined;
758
- setModelAllowlist(runner: string, ids: string[] | undefined): void;
759
- getPlannerModel(provider: string): {
760
- model: string;
761
- effort?: string;
762
- } | undefined;
763
- setPlannerModel(provider: string, entry: {
764
- model: string;
765
- effort?: string;
766
- } | undefined): void;
767
- getEnabledRunners(): string[] | undefined;
768
- setEnabledRunners(ids: string[]): void;
769
- private load;
770
- private persist;
771
- }
772
-
773
- /** How the same toggle is named once a host has read it off disk. */
774
- interface PlannerRuntimeToggles {
775
- tddEnabled: boolean;
776
- verificationEnabled: boolean;
718
+ uncommitted?(skills: readonly SkillInfo[]): Promise<Map<string, string>>;
777
719
  }
778
720
  /**
779
- * The planner-facing mode set for one operation. Replaces the boolean tail that
780
- * every planner signature used to carry positionally — where a thirteenth
781
- * parameter was the only place left to put a new toggle.
721
+ * Where a workspace's skills are read, known without asking git: the repos
722
+ * of its group in layout order (`['.']` for one repository), and whether
723
+ * tasks will get worktrees, which only a committed skill reaches.
782
724
  */
725
+ interface SkillLayout {
726
+ repos: readonly string[];
727
+ worktrees: boolean;
728
+ }
729
+
783
730
  /**
784
731
  * Where the run's tasks will work: `false` in the shared workspace root;
785
732
  * otherwise each in its own worktree of every repo of the group (ADR-0013,
@@ -788,47 +735,24 @@ interface PlannerRuntimeToggles {
788
735
  type IsolatedExecution = false | RepoGroupLayout;
789
736
  interface PlannerModes {
790
737
  autonomousDefault: boolean;
791
- verification: boolean;
792
738
  /** Not a toggle: a fact about the run. */
793
739
  isolatedExecution: IsolatedExecution;
740
+ /**
741
+ * Where the run's tasks will look their skills up (ADR-0024), also a fact
742
+ * about the run. A plan attaching a planner skill is refused against it,
743
+ * and a coding agent's submit_plan call is refused in its turn rather than
744
+ * accepted and then failed. Absent: the plan is not checked.
745
+ */
746
+ taskSkills?: SkillLookup;
794
747
  }
795
748
 
796
- /** Context of one task attempt, enough to locate its transcript. */
797
- interface TranscriptQuery {
798
- runner: string;
799
- /** The task's working directory (the agent's cwd at spawn). */
800
- cwd: string;
801
- /** When the agent process started, ISO — used to reject older sessions. */
802
- startedAt?: string;
803
- /**
804
- * The task's completion marker UUID. The prompt carries it, so a transcript
805
- * that does not contain it belongs to some other task — parallel attempts in
806
- * one cwd are otherwise indistinguishable by directory and recency.
807
- */
808
- marker: string;
809
- }
810
- /** Reads the agent's own session transcript for a task's final answer. */
811
- interface TranscriptReader {
812
- /** Last assistant-authored prose, clamped to `maxChars` from the end, or null. */
813
- finalAssistantText(query: TranscriptQuery, maxChars?: number): Promise<string | null>;
814
- }
815
- /** The part of a task attempt its output is looked up by. */
816
- interface TaskOutputAttempt {
817
- readonly taskId: string;
818
- readonly runner: string;
819
- /** Null when the attempt ended before its working directory was settled. */
820
- readonly cwd: string | null;
821
- readonly startedAt: string;
822
- /** The completion marker UUID the attempt's prompt carried. */
823
- readonly completionMarker: string;
824
- }
825
749
  interface LiveTailOptions {
826
750
  maxLines: number;
827
751
  /** A previous {@link LiveTail.nextOffset}: only output after it is rendered. */
828
752
  sinceOffset?: number;
829
753
  }
830
754
  interface LiveTail {
831
- /** Clean terminal render, not raw ANSI. */
755
+ /** Plain text, escapes and control characters removed. */
832
756
  text: string;
833
757
  /** Total output received so far; pass it back as `sinceOffset` to read only what follows. */
834
758
  nextOffset: number;
@@ -840,13 +764,13 @@ interface LiveTail {
840
764
  */
841
765
  interface TaskOutputSource {
842
766
  /** Start capturing a session; replaces any earlier capture of the task. */
843
- attach(taskId: string, session: ITerminalSession): void;
767
+ attach(taskId: string, session: IRunnerSession): void;
844
768
  /** Stop capturing the task's session; what was captured stays readable. */
845
769
  detach(taskId: string): void;
846
770
  /** Drop every capture (a new plan reuses task ids). */
847
771
  reset(): void;
848
- /** The attempt's final answer: its transcript first, the clean terminal render otherwise. */
849
- finalText(attempt: TaskOutputAttempt, doneToken: string): Promise<string>;
772
+ /** The task's final answer: the summary its runner reported through `task_complete`, else what its last turn said. */
773
+ finalText(taskId: string): string;
850
774
  /** Recent output of the task's latest capture, or null if it never had one. */
851
775
  liveTail(taskId: string, opts: LiveTailOptions): LiveTail | null;
852
776
  }
@@ -866,7 +790,7 @@ interface TaskOutputSource {
866
790
  * lives in PlanRepair alongside the plan and task-ops envelopes.
867
791
  */
868
792
  /** The long fields a query may ask for. Everything else is already in the plan block. */
869
- declare const TASK_QUERY_FIELDS: readonly ["description", "prompt", "userSteps", "verdict", "outputSummary", "userStoriesCovered", "output"];
793
+ declare const TASK_QUERY_FIELDS: readonly ["description", "prompt", "userSteps", "verdict", "outputSummary", "userStoriesCovered", "skills", "output"];
870
794
  type TaskQueryField = typeof TASK_QUERY_FIELDS[number];
871
795
  /** Lines a `output` read returns when the query sets no count. */
872
796
  declare const OUTPUT_LINES_DEFAULT = 80;
@@ -937,7 +861,7 @@ interface CliAgentAiServiceDeps extends Partial<AgentProcessDeps> {
937
861
  createAdapter?: (runner: string, deps: AgentProcessDeps) => AgentAdapter | null;
938
862
  /** Workspace root the agent explores. Defaults to the host process's cwd. */
939
863
  workspaceRoot?: () => string;
940
- /** Where a conversation's planner tools are served (ADR-0022). Absent: every planner gets the envelopes. */
864
+ /** Where a conversation's planner tools are served (ADR-0022). Absent: no conversation can start. */
941
865
  mcpServer?: OrdewellMcpServer;
942
866
  }
943
867
  /**
@@ -947,8 +871,8 @@ interface CliAgentAiServiceDeps extends Partial<AgentProcessDeps> {
947
871
  * `GeminiService`. It deliberately does **not** extend {@link BaseAiService}:
948
872
  * that class's body is Ordewell executing research tools on a model's behalf,
949
873
  * which is precisely the part a coding agent replaces. What it reuses instead
950
- * is everything above the transport — `settleReply` (reply classification
951
- * and the bounded corrective retries), `parsePlanJson`, the `ResearchProgress` events the
874
+ * is everything above the transport — `settleReply` (the empty-reply nudge
875
+ * and the turn's settling), the plan validator, the `ResearchProgress` events the
952
876
  * four surfaces already render. That is why this backend reaches VS Code, the
953
877
  * web UI, the CLI and the TUI without any of them learning a coding agent is
954
878
  * on the other end.
@@ -970,8 +894,6 @@ declare class CliAgentAiService implements IAiService {
970
894
  private readonly mcpServer;
971
895
  /** The planner token the running process was spawned with; revoked with the process (ADR-0022, A3). */
972
896
  private plannerToken;
973
- /** Whether the running planner was spawned with its tools and the CLI reported them connected. */
974
- private toolsAttached;
975
897
  private activeAbort;
976
898
  /**
977
899
  * Every subagent this conversation has reported starting, and finishing.
@@ -990,7 +912,7 @@ declare class CliAgentAiService implements IAiService {
990
912
  * on the old model. No conversation yet is vacuously "current".
991
913
  */
992
914
  conversationMatchesConfig(): boolean;
993
- /** Whether this conversation's planner submits through the Ordewell MCP server rather than the envelopes. */
915
+ /** Always: a conversation whose planner cannot reach the Ordewell MCP server fails to start rather than falling back to the envelopes. */
994
916
  plannerToolsAttached(): boolean;
995
917
  /** The agent's own session id, a resumption hint only — Ordewell's transcript is authoritative (T4). */
996
918
  nativeSessionId(): string | null;
@@ -1019,7 +941,8 @@ declare class CliAgentAiService implements IAiService {
1019
941
  * mode from here without changing this signature.
1020
942
  */
1021
943
  private startAdapter;
1022
- /** Spawn with the Ordewell server injected. False, with nothing left running, when it did not connect. */
944
+ private newAdapter;
945
+ /** One spawn with the Ordewell server injected: the adapter once the runner reports it connected, otherwise why not, with nothing left running. */
1023
946
  private startWithTools;
1024
947
  /** Kill the planner process, and with it the token it was spawned with. */
1025
948
  private disposeAdapter;
@@ -1031,12 +954,18 @@ declare class CliAgentAiService implements IAiService {
1031
954
  */
1032
955
  private ensureAdapter;
1033
956
  private plannerModel;
957
+ /**
958
+ * A plan from one-shot agent sessions: only what a submit_plan call
959
+ * accepted, never the reply text, so a plan the tool refused cannot come
960
+ * back in as the JSON the agent echoed. A session that ends without an
961
+ * accepted call is followed by one corrective session, then fails.
962
+ */
963
+ private submittedPlan;
1034
964
  /**
1035
965
  * A single agent session that answers one prompt and exits. Used by every
1036
- * non-conversational entry point; the plan is parsed from the reply text by
1037
- * the same extractor the conversational path uses. Its envelope streams to
1038
- * the plan display, as a vendor planner's one-shot does, and the prose
1039
- * around it is not streamed at all, since no turn is open to show it in.
966
+ * non-conversational entry point. A plan-shaped envelope in its text
967
+ * streams to the plan display, as a vendor planner's one-shot does, and the
968
+ * prose around it is not streamed at all, since no turn is open to show it in.
1040
969
  */
1041
970
  private oneShot;
1042
971
  researchAndPlan(userDescription: string, runners: RunnerId[], modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, fs: IFileSystem, onProgress: (progress: ResearchProgress) => void, _fetcher?: IWebFetcher, runnerModes?: Record<RunnerId, RunnerModeInfo[]>, modes?: PlannerModes, signal?: AbortSignal): Promise<{
@@ -1074,7 +1003,6 @@ interface ConversationRequest {
1074
1003
  fetcher?: IWebFetcher;
1075
1004
  runnerModes?: Record<RunnerId, RunnerModeInfo[]>;
1076
1005
  autonomousDefault?: boolean;
1077
- verificationEnabled?: boolean;
1078
1006
  /**
1079
1007
  * The planner model's context window when the catalog knows it. Threaded here
1080
1008
  * so a usage record can carry it (and the UI can show context fill); absent
@@ -1097,6 +1025,12 @@ interface ConversationRequest {
1097
1025
  */
1098
1026
  initialMessage?: string;
1099
1027
  plannerTools?: PlannerToolsOffer;
1028
+ /**
1029
+ * The workspace's skill catalog. Every planner is shown the task skills it
1030
+ * may attach; only one with tools is shown the planner skills, which load
1031
+ * through `load_skill` alone (ADR-0024).
1032
+ */
1033
+ skills?: readonly SkillInfo[];
1100
1034
  }
1101
1035
  /**
1102
1036
  * One planner turn's outcome. The planner talks to the user (`message`),
@@ -1195,6 +1129,11 @@ interface IAiService {
1195
1129
  * and cheap in every implementation, so callers never gate it.
1196
1130
  */
1197
1131
  reset(): void;
1132
+ /**
1133
+ * A one-shot plan from a prompt the caller built, so built for this
1134
+ * planner's transport: one with {@link plannerToolsAttached} is asked for a
1135
+ * submit_plan call, never JSON in its reply.
1136
+ */
1198
1137
  sendPlanningPrompt(prompt: string, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): Promise<Task[]>;
1199
1138
  }
1200
1139
  /**
@@ -1467,7 +1406,8 @@ declare class PlanStore {
1467
1406
  unblockDependents(id: string): void;
1468
1407
  setTaskVerdict(id: string, verdict: Task['verdict']): void;
1469
1408
  setTaskOutputSummary(id: string, summary: Task['outputSummary']): void;
1470
- setTaskTransport(id: string, transport: Task['transport']): void;
1409
+ setTaskRunnerSessionId(id: string, runnerSessionId: string | undefined): void;
1410
+ setTaskAttemptSkills(id: string, skills: Task['attemptSkills']): void;
1471
1411
  /**
1472
1412
  * Widen the plan's runner set. Retargeting a task onto a runner the plan has
1473
1413
  * not used before has to land here as well as on the plan state, or
@@ -1488,23 +1428,12 @@ type IsolationNoticeLevel = 'info' | 'warn' | 'error';
1488
1428
  interface IsolationRunListener {
1489
1429
  /** The run record changed and should be persisted with the plan. */
1490
1430
  changed(): void;
1491
- /**
1492
- * A run opened — the one moment shared by Execute, a manual task run and
1493
- * a force start, so whatever a run pins for its whole length is read here.
1494
- * Whether it isolates is decided later, at its first change task.
1495
- */
1496
- opened(): void;
1497
1431
  /** A run did not start: `repos` of the group have tracked changes. */
1498
1432
  blocked(repos: string[]): void;
1499
1433
  /** An isolated run closed and handed its integration branches over. */
1500
1434
  handoff(handoff: IsolationHandoff): void;
1501
1435
  /** Already said through the notifications; also for a surface that shows no toasts. */
1502
1436
  notice(level: IsolationNoticeLevel, message: string): void;
1503
- /**
1504
- * These tasks' worktrees are about to be removed. An agent left running in
1505
- * one would sit in a deleted directory, so it has to go first.
1506
- */
1507
- releasing(taskIds: string[]): void;
1508
1437
  }
1509
1438
  interface IsolationRunControllerDeps {
1510
1439
  isolation: IWorktreeIsolation;
@@ -1601,6 +1530,15 @@ declare class IsolationRunController {
1601
1530
  * the safe rule then.
1602
1531
  */
1603
1532
  plannerLayout(): Promise<IsolatedExecution>;
1533
+ /**
1534
+ * Where the workspace's skills are read, and whether tasks get worktrees.
1535
+ * Read synchronously inside a planner turn or a chip edit, so it comes from
1536
+ * the files, not git or the planner's last layout: a restored session is
1537
+ * right from its first edit. The run's repos while it isolates; otherwise
1538
+ * the group the workspace holds, in worktrees unless isolation is off or
1539
+ * this run chose to share the root.
1540
+ */
1541
+ skillLayout(): SkillLayout;
1604
1542
  /**
1605
1543
  * Go on with the start a dirty tree turned away. `stash` puts the user's
1606
1544
  * tracked changes on the git stash first, so the run isolates; `shared` runs
@@ -1932,8 +1870,8 @@ interface OrchestratorObserver {
1932
1870
  }): void;
1933
1871
  }
1934
1872
  /**
1935
- * A message or interrupt a task cannot take: it is not running, it runs on the
1936
- * terminal transport, or it is waiting on something a message does not answer.
1873
+ * A message or interrupt a task cannot take: it is not running, or it is
1874
+ * waiting on something a message does not answer.
1937
1875
  * The request is wrong, not the orchestrator, so a surface says why.
1938
1876
  */
1939
1877
  declare class TaskControlError extends Error {
@@ -1949,6 +1887,7 @@ interface TaskAttemptSnapshot {
1949
1887
  runner: string;
1950
1888
  cwd: string | null;
1951
1889
  startedAt: string;
1890
+ skills: readonly TaskSkillSnapshot[];
1952
1891
  }
1953
1892
  /**
1954
1893
  * The wiring a {@link TaskOrchestrator} runs on, every collaborator resolved.
@@ -1959,7 +1898,7 @@ interface TaskAttemptSnapshot {
1959
1898
  interface TaskOrchestratorDeps {
1960
1899
  config: IConfig;
1961
1900
  notifications: INotification;
1962
- terminalRunner: ITerminalRunner;
1901
+ runner: IRunner;
1963
1902
  store: PlanStore;
1964
1903
  output: TaskOutputSource;
1965
1904
  /** The plan's isolation run and the open run's lifecycle (ADR-0013). */
@@ -1971,10 +1910,8 @@ interface TaskOrchestratorDeps {
1971
1910
  workspaceRoot: () => string;
1972
1911
  /** The workspace's own variables for a task's cwd (ADR-0016). */
1973
1912
  workspaceEnv: (cwd: string) => Promise<WorkspaceEnv>;
1974
- /** Read live at each spawn, so a toggle takes effect on the next task. */
1975
- tddEnabled: () => boolean;
1976
- /** Read once as a run opens, never per spawn (ADR-0018, S1). */
1977
- runnerTransport: () => RunnerTransport;
1913
+ /** The skill catalog over workspace roots, as {@link workspaceSkillRoots} orders them — read at each spawn. */
1914
+ skillsAt: (roots: readonly string[]) => SkillLookup;
1978
1915
  /** What the task's last saved attempt did, or null when it left no log (ADR-0020). */
1979
1916
  previousAttemptFromLog: (taskId: string) => string | null;
1980
1917
  }
@@ -1986,15 +1923,14 @@ interface TaskOrchestratorDeps {
1986
1923
  interface TaskOrchestratorOptions {
1987
1924
  config: IConfig;
1988
1925
  notifications: INotification;
1989
- terminalRunner: ITerminalRunner;
1926
+ runner: IRunner;
1990
1927
  store?: PlanStore;
1991
1928
  output?: TaskOutputSource;
1992
1929
  isolation?: IWorktreeIsolation;
1993
1930
  registry?: RunnerRegistry | null;
1994
1931
  workspaceRoot?: () => string;
1995
1932
  workspaceEnv?: (cwd: string) => Promise<WorkspaceEnv>;
1996
- tddEnabled?: () => boolean;
1997
- runnerTransport?: () => RunnerTransport;
1933
+ skillsAt?: (roots: readonly string[]) => SkillLookup;
1998
1934
  previousAttemptFromLog?: (taskId: string) => string | null;
1999
1935
  }
2000
1936
  /**
@@ -2003,14 +1939,14 @@ interface TaskOrchestratorOptions {
2003
1939
  * All task-shaped state — the plan tree, the flat index, the completed set
2004
1940
  * — lives in {@link PlanStore}, injected at construction. The orchestrator
2005
1941
  * calls `store.markCompleted(id)` / `store.markFailed(id)` instead of mutating
2006
- * task state directly. A task completes only after the runner emits its
2007
- * per-task completion marker; process exit without that evidence is a visible
2008
- * failure and does not unblock dependent work.
1942
+ * task state directly. A task completes only after the runner reports it done
1943
+ * through `task_complete` on its attempt's token; process exit without that
1944
+ * evidence is a visible failure and does not unblock dependent work.
2009
1945
  */
2010
1946
  declare class TaskOrchestrator {
2011
1947
  private config;
2012
1948
  private notifications;
2013
- private terminalRunner;
1949
+ private runner;
2014
1950
  private store;
2015
1951
  private output;
2016
1952
  private attempts;
@@ -2021,8 +1957,6 @@ declare class TaskOrchestrator {
2021
1957
  private reviewApproved;
2022
1958
  private retryCounts;
2023
1959
  private spawnCounts;
2024
- /** The terminal a verdict left open, by task; see {@link LingeringRunners}. */
2025
- private lingering;
2026
1960
  /**
2027
1961
  * A full-plan run a failure paused. Retrying the failed task is the explicit
2028
1962
  * resume the pause waits for — without this a retry only reset the task to
@@ -2061,20 +1995,13 @@ declare class TaskOrchestrator {
2061
1995
  private registry;
2062
1996
  private workspaceRootFn;
2063
1997
  private observers;
2064
- private tddEnabled;
2065
- private readRunnerTransport;
1998
+ private skillsAt;
2066
1999
  private previousAttemptFromLog;
2067
- /**
2068
- * The setting as the latest run copied it when it opened. Every spawn of
2069
- * that run uses this, so flipping the setting mid-run changes the next run
2070
- * only — the plan, not a live setting, says what runs (ADR-0001).
2071
- */
2072
- private planTransport;
2073
2000
  constructor(deps: TaskOrchestratorDeps);
2074
2001
  /**
2075
2002
  * The composition root: resolves every optional collaborator and wires the
2076
2003
  * isolation listener that the constructor cannot, because it needs the
2077
- * instance's own (private) emit and lingering seams. Nothing else in the
2004
+ * instance's own (private) emit seam. Nothing else in the
2078
2005
  * codebase constructs an orchestrator, so this is the one place defaults
2079
2006
  * live — a host or test supplies what it cares about and gets the rest.
2080
2007
  */
@@ -2083,7 +2010,7 @@ declare class TaskOrchestrator {
2083
2010
  getIdleSince(taskId: string): string | null;
2084
2011
  /**
2085
2012
  * What an ops retry is told about the attempt before. The saved log is read
2086
- * whether or not the session was reloaded, so both behave alike; the terminal
2013
+ * whether or not the session was reloaded, so both behave alike; the output
2087
2014
  * buffer is the fallback for a runner that has no log. A reload clears the
2088
2015
  * attempt count along with the buffer, so a retry made since is what says
2089
2016
  * there was an attempt to report on.
@@ -2120,13 +2047,13 @@ declare class TaskOrchestrator {
2120
2047
  forceSendQueuedTaskMessage(taskId: string, id: string): boolean;
2121
2048
  /** Take back a message still queued behind a turn; false once it was delivered. */
2122
2049
  removeQueuedTaskMessage(taskId: string, id: string): boolean;
2123
- /** Stop a structured task's running turn; it then waits for input like any turn that ends without its marker. */
2050
+ /** Stop a structured task's running turn; it then waits for input like any turn that ends without a `task_complete` call. */
2124
2051
  interruptTask(taskId: string): Promise<void>;
2125
2052
  /** What is waiting for a structured task's turn to end; empty for any other task. */
2126
2053
  getQueuedTaskMessages(taskId: string): QueuedTaskMessage[];
2127
- private structuredSession;
2054
+ private runnerSession;
2128
2055
  /**
2129
- * A structured turn that ended without the done marker (ADR-0018, W1). No
2056
+ * A structured turn that ended without a `task_complete` call (ADR-0018, W1). No
2130
2057
  * verdict is guessed: the task waits for input, unless a checkpoint in the
2131
2058
  * same turn already has it waiting, or a queued message went straight out —
2132
2059
  * the session never passes through idle then, so nothing flickers.
@@ -2172,12 +2099,7 @@ declare class TaskOrchestrator {
2172
2099
  * the task has started, and for every other task.
2173
2100
  */
2174
2101
  getMergeGate(taskId: string): string[];
2175
- private watchBlockingPrompts;
2176
- /** The transport the plan's latest run copied from the setting; null before its first run. */
2177
- get runnerTransport(): RunnerTransport | null;
2178
- /** Take over a saved plan's copied transport. The next run copies the setting afresh. */
2179
- adoptRunnerTransport(transport: RunnerTransport | null): void;
2180
- queueMessage(text: string): void;
2102
+ queueMessage(text: string, skills?: readonly SkillLoad[]): void;
2181
2103
  getQueuedMessages(): QueuedMessage[];
2182
2104
  /** Take one unsent message back out of the queue; false when it was never there (or already drained). */
2183
2105
  removeQueuedMessage(id: string): boolean;
@@ -2351,13 +2273,14 @@ declare class TaskOrchestrator {
2351
2273
  * unwound (both leave `startTask` with nothing further to announce).
2352
2274
  */
2353
2275
  private spawnAttempt;
2276
+ /** For a skill the main checkout has, the folder a worktree only gets once it is committed. */
2277
+ private uncommittedSkillFolder;
2354
2278
  /**
2355
- * Say on the task how this attempt is driven, when its plan asked for the
2356
- * structured transport; a terminal plan's tasks record nothing. A structured
2357
- * request that came back a terminal session is a fallback, and says why —
2358
- * a host without a router included — never a silent downgrade.
2279
+ * The roots whose `.ordewell/skills/` an attempt at `cwd` reads: in a repo
2280
+ * group, `cwd` holds each repo — a worktree of it when isolated, the
2281
+ * workspace's own checkout when not — and no folder of its own (ADR-0014).
2359
2282
  */
2360
- private recordTransport;
2283
+ private skillRoots;
2361
2284
  /**
2362
2285
  * A continue whose runner never announced the session it was told to
2363
2286
  * resume. Nothing was continued, and nothing fresh was started in its place.
@@ -2383,12 +2306,11 @@ declare class TaskOrchestrator {
2383
2306
  * it receives for an attempt that is no longer current).
2384
2307
  *
2385
2308
  * A user interruption also bumps the verifier's generation *before* stopping
2386
- * the runner: some runners (e.g. tmux) fire onExit synchronously from
2309
+ * the runner: a runner may fire onExit synchronously from
2387
2310
  * stop(), and if that exit reaches VerdictEngine under the still-valid
2388
2311
  * generation it delivers a verdict that marks the task 'completed' for one
2389
- * tick — long enough for the scheduler to start a dependent task. A verdict
2390
- * leaves a terminal runner up so its screen stays readable (a structured one
2391
- * ends), and stop/load reset the whole verifier themselves.
2312
+ * tick — long enough for the scheduler to start a dependent task. Stop and
2313
+ * load reset the whole verifier themselves.
2392
2314
  */
2393
2315
  private endAttempt;
2394
2316
  /** Kept on the task once the attempt ends, so a continue can resume it after a reload (ADR-0018, K1). */
@@ -2411,9 +2333,13 @@ interface PlanRequest {
2411
2333
  autonomousDefault?: boolean;
2412
2334
  signal?: AbortSignal;
2413
2335
  perRunnerAllowlist?: Partial<Record<RunnerId, string[]>>;
2414
- /** The mode toggles this run honours. `modesFor('one-shot', …)` decides which apply. */
2415
2336
  modes?: PlannerModes;
2416
2337
  }
2338
+ /** A generated plan, and what its skill check warned about. */
2339
+ interface GeneratedPlan extends LegacyPlanState {
2340
+ /** Names not found yet, or no skill could have; the plan still lands. Absent means none, or not checked. */
2341
+ skillWarnings?: string[];
2342
+ }
2417
2343
  interface ModifyPlanRequest {
2418
2344
  existingPlan: LegacyPlanState;
2419
2345
  userRequest: string;
@@ -2438,10 +2364,14 @@ interface ModifyDuringExecutionRequest {
2438
2364
  perRunnerAllowlist?: Partial<Record<RunnerId, string[]>>;
2439
2365
  /** Where the run in force puts each task (ADR-0013, ADR-0014). */
2440
2366
  isolatedExecution?: IsolatedExecution;
2367
+ /** The workspace's skill catalog under its repo group's layout, which the rewritten tasks' skills are checked against. */
2368
+ skills: SkillLookup;
2441
2369
  }
2442
2370
  interface ModifyDuringExecutionResult {
2443
2371
  pendingTasks: Task[];
2444
2372
  message: string;
2373
+ /** Skill names not found yet; the edit still lands, as a submitted plan's does. Absent means none. */
2374
+ skillWarnings?: string[];
2445
2375
  }
2446
2376
  /**
2447
2377
  * Owns one-shot plan generation and plan modification — the "planning is a
@@ -2460,8 +2390,12 @@ declare class Planner {
2460
2390
  private readonly resolveAiService;
2461
2391
  constructor(config: IConfig, aiService: IAiService | (() => IAiService));
2462
2392
  private get aiService();
2463
- /** One-shot plan generation for non-conversational surfaces. Never asks questions. */
2464
- generate(req: PlanRequest): Promise<LegacyPlanState>;
2393
+ /**
2394
+ * One-shot plan generation for non-conversational surfaces. Never asks
2395
+ * questions. A plan attaching a planner skill to a task is refused, not
2396
+ * returned: there is no conversation to send it back through.
2397
+ */
2398
+ generate(req: PlanRequest): Promise<GeneratedPlan>;
2465
2399
  modify(req: ModifyPlanRequest): Promise<{
2466
2400
  tasks: Task[];
2467
2401
  }>;
@@ -2557,9 +2491,7 @@ declare class RunnerInstallation {
2557
2491
  * typing a real goal is the failure this exists to prevent.
2558
2492
  *
2559
2493
  * "Usable" is deliberately shallow: the binary answers `--version`, and the
2560
- * runner has a connector to plan over. Plugin runners have none yet: a
2561
- * manifest-level planner capability, so a plugin can declare itself
2562
- * plannable, is a follow-up. Whether the user's subscription is
2494
+ * runner has a connector to plan over. Whether the user's subscription is
2563
2495
  * live cannot be known without spending a turn on it, so an expired login
2564
2496
  * surfaces where it actually bites — as the agent's own error text on the
2565
2497
  * first turn.
@@ -2744,7 +2676,7 @@ interface EnvAdmission {
2744
2676
  */
2745
2677
  declare function admitSettingsEnv(env: Record<string, unknown>): EnvAdmission;
2746
2678
 
2747
- /** Whether a runner's tasks can run on the structured transport (ADR-0018, S3). */
2679
+ /** Whether Ordewell can run a runner's tasks (ADR-0018, S3). */
2748
2680
  declare function supportsTaskMode(runner: string): boolean;
2749
2681
  /** The adapter that drives one task. Throws {@link TaskModeUnsupportedError} for a runner without a connector. */
2750
2682
  declare function createTaskAdapter(runner: string, deps: AgentProcessDeps): TaskModeAgentAdapter;
@@ -2869,7 +2801,7 @@ declare class ClaudeCodeAdapter extends StdioAgentAdapter implements TaskModeAge
2869
2801
  * A task's turn whose `result` arrived while background work was still open.
2870
2802
  * The CLI reports that result when the model stops talking, then opens a turn
2871
2803
  * of its own when the work finishes; a turn ended at the first result would
2872
- * lose everything said after it, the completion marker included.
2804
+ * lose everything done after it, the `task_complete` call included.
2873
2805
  */
2874
2806
  private resultHeld;
2875
2807
  private followOnTimer;
@@ -2889,8 +2821,7 @@ declare class ClaudeCodeAdapter extends StdioAgentAdapter implements TaskModeAge
2889
2821
  /**
2890
2822
  * A task's run: the manifest decides what its mode and effort mean
2891
2823
  * (ADR-0001), and this adds only the protocol around them. No tool list and
2892
- * no system prompt — the task's prompt is its first turn, as on the terminal
2893
- * transport. `--permission-prompt-tool stdio` routes the questions the mode
2824
+ * no system prompt — the task's prompt is its first turn. `--permission-prompt-tool stdio` routes the questions the mode
2894
2825
  * leaves open to the control channel, where the adapter must answer them;
2895
2826
  * without it `-p` refuses them silently and nothing can ever surface one.
2896
2827
  */
@@ -3253,8 +3184,8 @@ declare class OpenCodeAdapter implements TaskModeAgentAdapter {
3253
3184
  /**
3254
3185
  * Whatever of the turn's own messages the stream missed. Each part is
3255
3186
  * emitted once, so a turn the stream saw whole adds nothing here; one that
3256
- * lost its last text part still reaches the plain-text channel, where the
3257
- * done marker is looked for.
3187
+ * lost its last text part still reaches the plain-text channel, which a
3188
+ * summary falls back to.
3258
3189
  */
3259
3190
  private readBack;
3260
3191
  /**
@@ -3398,8 +3329,7 @@ interface RunnerCatalog {
3398
3329
  * models by the manifest's `preferredPatterns`; the mode is the catalog's
3399
3330
  * `defaultMode`).
3400
3331
  *
3401
- * An empty catalog means discovery failed or the runner is a plugin we have no
3402
- * list for — not that the runner offers nothing. That field is left out of the
3332
+ * An empty catalog means discovery failed — not that the runner offers nothing. That field is left out of the
3403
3333
  * patch and the runner validates last, matching `coerceAssignments`.
3404
3334
  */
3405
3335
  declare function runnerAssignment(catalog: RunnerCatalog, current?: Pick<Task, 'assignedModel' | 'taskMode'>): Partial<Task>;
@@ -3509,6 +3439,43 @@ interface ForkedDialogue {
3509
3439
  researchLog: ResearchLogEntry[];
3510
3440
  }
3511
3441
 
3442
+ /** A user's message as sent, and the skills its `/name` tokens load. */
3443
+ interface SkillInvocation {
3444
+ text: string;
3445
+ skills: SkillLoad[];
3446
+ }
3447
+ /**
3448
+ * A path with the home directory written `~`, for a notice or listing. On
3449
+ * Windows the drive letter's case is not significant and the separators are
3450
+ * rendered `/`, so the same skill reads alike wherever the session reloads.
3451
+ */
3452
+ declare function abbreviateHome(file: string, home?: string, platform?: NodeJS.Platform): string;
3453
+ /**
3454
+ * Resolve the `/skill-name` tokens in a message to snapshots of the skills they
3455
+ * name. Pure and exported so surfaces can resolve without a full Session. The text itself is never rewritten.
3456
+ *
3457
+ * Every distinct skill named loads, once, in the order first named. A token
3458
+ * naming no skill is plain text, wherever it stands — a whole message of
3459
+ * `/unknown` included: embedded in a sentence it is as likely to be incidental
3460
+ * text (a path, an example command) as a typo'd invocation. So is one naming
3461
+ * a skill with `user-invocable: false`, which only the model may invoke.
3462
+ */
3463
+ declare function resolveSkillInvocation(text: string, skillsService: Pick<SkillsService, 'findSkill'>, home?: string): SkillInvocation;
3464
+ /**
3465
+ * What the planner receives for a user message: the bodies of the skills it
3466
+ * loaded, then the message as the user wrote it. The one composition for a
3467
+ * live send and for a replay of the transcript, so a resumed conversation
3468
+ * hands the planner what the live one did.
3469
+ */
3470
+ declare function plannerMessage(text: string, loads: readonly SkillLoad[]): string;
3471
+ /**
3472
+ * The transcript as the planner is to see it on a replay: each user message
3473
+ * carries the skills loaded after it, composed by {@link plannerMessage}, and
3474
+ * the load entries themselves are folded away. Sessions saved before skill
3475
+ * loads existed hold the expanded text in the message and replay unchanged.
3476
+ */
3477
+ declare function plannerTranscript(history: readonly ConversationMessage[]): ConversationMessage[];
3478
+
3512
3479
  /**
3513
3480
  * The planner turn (see CONTEXT.md): the one piece of planner work that holds
3514
3481
  * the conversation, from its claim to its settled outcome. Its signal is what a
@@ -3571,11 +3538,15 @@ interface PlannerConversationHost {
3571
3538
  broadcastPlan(turnId?: string): void;
3572
3539
  /** Validate a batch against live state. Pure — nothing is applied. */
3573
3540
  validateOps(ops: TaskOp[]): ApplyTaskOpsResult;
3541
+ /** The workspace's skill catalog under its repo group's layout, which the skills a plan or edit attaches are checked against. */
3542
+ taskSkills(): SkillLookup;
3543
+ /** Tell the user something the transcript does not carry. */
3544
+ notice(level: SessionNotice['level'], message: string): void;
3574
3545
  /** Load planner-produced tasks: an edit keeps run state, a commit starts over. Returns how many landed. */
3575
3546
  adoptTasks(tasks: readonly Task[], how: 'edit' | 'commit'): number;
3576
3547
  capturePrd(text: string): void;
3577
3548
  /** Park a structural edit until the next batch boundary. Returns the queue length. */
3578
- queueEdit(userMessage: string): number;
3549
+ queueEdit(message: SkillInvocation): number;
3579
3550
  /** Wake a scheduler an applied edit may have unblocked. */
3580
3551
  afterEdit(): Promise<void>;
3581
3552
  /** The planner turn was stopped or abandoned: whatever it is waiting on (a parked approval) will never be answered. */
@@ -3647,8 +3618,6 @@ interface TranscriptSnapshot {
3647
3618
  }
3648
3619
  interface ReplyOptions {
3649
3620
  signal?: AbortSignal;
3650
- /** The user's words before skill expansion — what a mid-run queue replays later. */
3651
- verbatim?: string;
3652
3621
  }
3653
3622
  /**
3654
3623
  * The planner conversation (ADR-0002), end to end: the persisted dialogue
@@ -3700,6 +3669,7 @@ declare class PlannerConversation {
3700
3669
  private claim;
3701
3670
  /** The user turn being answered, for what the host raises during it — an approval the turn's research asks for. */
3702
3671
  get currentTurnId(): string | undefined;
3672
+ recordPlannerSkill(skill: SkillLoad): boolean;
3703
3673
  /**
3704
3674
  * Hand the open turn a plan (already validated) or a task edit. The turn
3705
3675
  * settles with it exactly as with the same plan or ops parsed out of its
@@ -3729,6 +3699,7 @@ declare class PlannerConversation {
3729
3699
  timestamp?: string;
3730
3700
  kind?: ConversationMessage['kind'];
3731
3701
  }): void;
3702
+ private appendEntries;
3732
3703
  /** Swap the whole transcript. The live context no longer matches it, so pair with {@link reset}. */
3733
3704
  replace(messages: readonly ConversationMessage[]): void;
3734
3705
  snapshot(): TranscriptSnapshot | null;
@@ -3800,6 +3771,13 @@ declare class PlannerConversation {
3800
3771
  * Call inside the host's mutation ritual.
3801
3772
  */
3802
3773
  recordQueuedEdits(messages: string[], taskCount: number): void;
3774
+ /**
3775
+ * What the skill check of a landed plan or edit warned about, kept in the
3776
+ * transcript so every surface shows it, on reload too, and not only the
3777
+ * planner that may have read it in a tool result. Call inside the host's
3778
+ * mutation ritual, so the broadcast plan carries it.
3779
+ */
3780
+ recordSkillWarnings(warnings: readonly string[], timestamp?: string): void;
3803
3781
  /**
3804
3782
  * Queued edits the between-batches drain could not apply. Recorded so the
3805
3783
  * transcript does not go on promising a change that never landed. Call
@@ -3810,13 +3788,13 @@ declare class PlannerConversation {
3810
3788
  * Open the conversation on the host's fresh plan: the goal is its first
3811
3789
  * message. `prepare` (discovery) runs inside the turn, so a stop reaches it.
3812
3790
  */
3813
- start(goal: string, prepare: () => Promise<ConversationOpening>, signal?: AbortSignal): Promise<LegacyPlanState>;
3791
+ start(goal: SkillInvocation, prepare: () => Promise<ConversationOpening>, signal?: AbortSignal): Promise<LegacyPlanState>;
3814
3792
  /**
3815
3793
  * Every later user message, from the transcript append to a persisted
3816
3794
  * outcome. A turn that throws before anything was persisted takes its own
3817
3795
  * writes back out, so session memory never drifts from disk and the UI.
3818
3796
  */
3819
- reply(message: string, options?: ReplyOptions): Promise<LegacyPlanState>;
3797
+ reply(message: string | SkillInvocation, options?: ReplyOptions): Promise<LegacyPlanState>;
3820
3798
  private replyTurn;
3821
3799
  /**
3822
3800
  * Whether a settled structural edit reaches work a runner is executing. Only
@@ -3834,6 +3812,14 @@ declare class PlannerConversation {
3834
3812
  * call hands back is a fragment of an answer to a dialogue that is gone.
3835
3813
  */
3836
3814
  private assertCurrent;
3815
+ /**
3816
+ * {@link assertCurrent} on the far side of an await that precedes a plan
3817
+ * mutation: the skill check waits on git, and a stop, rewind or session
3818
+ * switch in that window drops the edit instead of landing it on whatever
3819
+ * plan is current by then. A stop counts here because nothing has landed
3820
+ * yet — the user asked for the turn to end before it changed the plan.
3821
+ */
3822
+ private assertStillCurrent;
3837
3823
  /**
3838
3824
  * A live conversation is only safe to continue in-place when it also
3839
3825
  * matches the model/effort configured right now — a harness planner's
@@ -3848,6 +3834,7 @@ declare class PlannerConversation {
3848
3834
  */
3849
3835
  private userTurn;
3850
3836
  private requirePlan;
3837
+ /** The message as typed, then one entry per skill it loaded, sharing its timestamp so a reload keeps them together. */
3851
3838
  private recordUser;
3852
3839
  private recordResearch;
3853
3840
  /**
@@ -3892,6 +3879,8 @@ declare class PlannerConversation {
3892
3879
  * one path, not two.
3893
3880
  */
3894
3881
  private settle;
3882
+ /** A name not found at submit only warns: a task the attaching one depends on may create it. */
3883
+ private warnSkills;
3895
3884
  /** Validate + commit a task_ops turn atomically. Returns the errors on rejection (plan untouched). */
3896
3885
  private applyTaskOps;
3897
3886
  /** Commit a settled (non-task_ops) turn through the host's mutation ritual. */
@@ -3920,42 +3909,48 @@ declare class PlannerConversation {
3920
3909
  private currentPlanLines;
3921
3910
  }
3922
3911
 
3923
- declare const BUILTIN_SKILL_NAMES: readonly ["grilling", "to-spec", "improve-codebase-architecture"];
3924
- interface SkillMetadata {
3925
- name: string;
3926
- description: string;
3927
- disableModelInvocation?: boolean;
3912
+ interface UserSettings {
3913
+ modelAllowlist?: Record<string, string[]>;
3914
+ /** Last model (and its thinking effort) the user chose for each planner backend, keyed by AiProvider id. */
3915
+ plannerModels?: Record<string, {
3916
+ model: string;
3917
+ effort?: string;
3918
+ }>;
3919
+ /**
3920
+ * Runners the user picked for planning. Absent — not empty — is what falls
3921
+ * back to the environment's defaults; `[]` is a deliberate "none of them".
3922
+ */
3923
+ enabledRunners?: string[];
3924
+ }
3925
+ /**
3926
+ * The model allowlist, remembered planner models and enabled runners are shared
3927
+ * across processes by default. `ORDEWELL_SETTINGS_PATH` lets independent runs
3928
+ * use separate files: otherwise a write in one run would change another's
3929
+ * settings when `getAll()` detects the new mtime.
3930
+ */
3931
+ declare function getSettingsPath(): string;
3932
+ declare class SettingsService {
3933
+ private filePath;
3934
+ private cache;
3935
+ private cachedMtimeMs;
3936
+ constructor(filePath?: string);
3937
+ getAll(): UserSettings;
3938
+ private fileMtimeMs;
3939
+ getModelAllowlist(runner: string): string[] | undefined;
3940
+ setModelAllowlist(runner: string, ids: string[] | undefined): void;
3941
+ getPlannerModel(provider: string): {
3942
+ model: string;
3943
+ effort?: string;
3944
+ } | undefined;
3945
+ setPlannerModel(provider: string, entry: {
3946
+ model: string;
3947
+ effort?: string;
3948
+ } | undefined): void;
3949
+ getEnabledRunners(): string[] | undefined;
3950
+ setEnabledRunners(ids: string[]): void;
3951
+ private load;
3952
+ private persist;
3928
3953
  }
3929
- interface SkillInfo {
3930
- name: string;
3931
- description: string;
3932
- metadata: SkillMetadata;
3933
- /** Full content of SKILL.md with frontmatter stripped */
3934
- content: string;
3935
- /** Absolute path to the SKILL.md file */
3936
- path: string;
3937
- /** Whether this came from global (~/.ordewell/skills/) or local (.ordewell/skills/) */
3938
- source: 'global' | 'local';
3939
- }
3940
- declare class SkillsService {
3941
- private workspaceRoot?;
3942
- constructor(workspaceRoot?: string | undefined);
3943
- private localDir;
3944
- private globalDir;
3945
- private readSeedManifest;
3946
- private recordSeed;
3947
- /** A seed the user never edited: safe to replace with a newer built-in. */
3948
- private isUntouchedSeed;
3949
- private seed;
3950
- seedBuiltinSkill(name: string): boolean;
3951
- /** Removes a retired built-in's seed from the global dir, but only if it's untouched by the user. */
3952
- private isUnmodifiedRetiredSeed;
3953
- private pruneRetired;
3954
- findSkill(name: string): SkillInfo | undefined;
3955
- listSkills(): SkillInfo[];
3956
- getSkillContent(name: string): string | undefined;
3957
- }
3958
- declare function createSkillsService(workspaceRoot?: string): SkillsService;
3959
3954
 
3960
3955
  /** The `planner_usage` member of the session broadcast union. */
3961
3956
  type PlannerUsageMessage = Extract<SessionMessage, {
@@ -4098,31 +4093,11 @@ interface GeneratePlanOptions {
4098
4093
  type SessionPlanner = Pick<Planner, 'generate' | 'modifyDuringExecution'>;
4099
4094
  /** Runtime prefs read live — may toggle between operations. */
4100
4095
  interface SessionRuntimeSettings {
4101
- tddEnabled: boolean;
4102
- verificationEnabled?: boolean;
4103
4096
  modelAllowlist?: Record<string, string[]>;
4104
- /** Read once as a run starts, never per spawn (ADR-0018, S1). Absent means terminal. */
4105
- runnerTransport?: RunnerTransport;
4106
4097
  /** Absent means the user never chose, and `config.enabledRunners` (the host's defaults) decides. */
4107
4098
  enabledRunners?: RunnerId[];
4108
4099
  }
4109
4100
  declare function sessionRuntimeSettings(settings: UserSettings): SessionRuntimeSettings;
4110
- /**
4111
- * Resolve `/skill-name` invocations to their skill's markdown content. Pure
4112
- * and exported so surfaces and verification can drive substitution without a
4113
- * full Session.
4114
- *
4115
- * A message that is *only* `/skill-name` keeps the legacy whole-message
4116
- * behaviour: an unknown skill becomes a notice naming what IS available,
4117
- * instead of a bare slash token a runner would mis-resolve in its own skills
4118
- * directory. Anywhere else in a message, a matching token is spliced in place
4119
- * (surrounding text is untouched); a token that doesn't name a real skill is
4120
- * left as plain text rather than raising a notice, since embedded in a
4121
- * sentence it's as likely to be incidental text (a path, an example command)
4122
- * as a typo'd invocation. The same skill name repeated only expands its first
4123
- * occurrence — later repeats stay literal.
4124
- */
4125
- declare function resolveSkillInvocation(text: string, skillsService: Pick<SkillsService, 'findSkill' | 'listSkills'>): string;
4126
4101
  /** Where a fork landed: the new session's id, and what adopting it needs. */
4127
4102
  interface ConversationFork {
4128
4103
  sessionId: string;
@@ -4138,14 +4113,14 @@ type SaveSession = (plan: LegacyPlanState, goal: string, workspace: string, sess
4138
4113
  /**
4139
4114
  * Everything a delivery surface constructs to host a session. Structural config
4140
4115
  * (orchestratorModel, providerModelLists) is snapshotted inside `config` at
4141
- * construction and never re-read from the environment. Runtime settings (tdd,
4142
- * verification, enabled runners) are read live via the `settings` callback so a
4116
+ * construction and never re-read from the environment. Runtime settings
4117
+ * (enabled runners) are read live via the `settings` callback so a
4143
4118
  * toggle between operations takes effect.
4144
4119
  */
4145
4120
  interface SessionDeps {
4146
4121
  config: IConfig;
4147
4122
  notifications: INotification;
4148
- runner: ITerminalRunner;
4123
+ runner: IRunner;
4149
4124
  registry: RunnerRegistry;
4150
4125
  /** Resolves the workspace root for the orchestrator (lazy — VS Code can change it). */
4151
4126
  workspaceRoot: () => string;
@@ -4157,7 +4132,7 @@ interface SessionDeps {
4157
4132
  onNotice?: (notice: SessionNotice) => void;
4158
4133
  /** Shared across sessions — sole producer of model catalogs and routing lists. */
4159
4134
  modelResolver: ModelResolver;
4160
- /** Live runtime settings (tdd, verification, enabled runners). Read at each operation that needs them. */
4135
+ /** Live runtime settings (enabled runners). Read at each operation that needs them. */
4161
4136
  settings: () => SessionRuntimeSettings;
4162
4137
  /**
4163
4138
  * Host-assigned session id. When set, every persist writes under this id so
@@ -4178,11 +4153,7 @@ interface SessionDeps {
4178
4153
  * over the session's workspace root.
4179
4154
  */
4180
4155
  skillsService?: SkillsService;
4181
- /**
4182
- * Where a task's output and final answer are read. Defaults to the agents'
4183
- * own transcripts under the user's home; tests inject one that never
4184
- * touches the disk.
4185
- */
4156
+ /** Where a task's output and final answer are read. */
4186
4157
  taskOutput?: TaskOutputSource;
4187
4158
  /**
4188
4159
  * Git worktree isolation (ADR-0013). Defaults to git itself, gated by
@@ -4209,6 +4180,7 @@ interface SessionParts {
4209
4180
  workspace: string;
4210
4181
  fsAdapter: IFileSystem;
4211
4182
  broadcast: SessionBroadcaster;
4183
+ notifications: INotification;
4212
4184
  onNotice?: (notice: SessionNotice) => void;
4213
4185
  modelResolver: ModelResolver;
4214
4186
  settings: () => SessionRuntimeSettings;
@@ -4224,7 +4196,7 @@ interface SessionParts {
4224
4196
  approvals: PendingApprovals;
4225
4197
  approvalPolicy: ApprovalPolicy;
4226
4198
  fetcher: IWebFetcher;
4227
- skillsService: Pick<SkillsService, 'findSkill' | 'listSkills'>;
4199
+ skillsService: Pick<SkillsService, 'findSkill' | 'listSkills' | 'searchedDirs' | 'forRoot'>;
4228
4200
  saveSession: SaveSession;
4229
4201
  /** The conversation's host is the Session itself, so only the Session can make it. */
4230
4202
  conversation: (host: PlannerConversationHost) => PlannerConversation;
@@ -4255,6 +4227,7 @@ declare class Session {
4255
4227
  private goal;
4256
4228
  private workspace;
4257
4229
  private readonly broadcast;
4230
+ private readonly notifications;
4258
4231
  private readonly onNotice?;
4259
4232
  private readonly modelResolver;
4260
4233
  private readonly fsAdapter;
@@ -4424,14 +4397,20 @@ declare class Session {
4424
4397
  /** Whether the planner conversation is live (started and not yet committed to a plan). */
4425
4398
  get isConversationActive(): boolean;
4426
4399
  /**
4427
- * Intercept a skill invocation (/skill-name) and substitute the skill's
4428
- * markdown content BEFORE the message reaches the planner. Prevents runners
4429
- * (Claude Code, OpenCode) from trying to resolve the skill in their own
4430
- * directory instead of .ordewell/skills/. An unknown skill is surfaced to
4431
- * the planner as a notice naming what IS available, rather than passing a
4432
- * bare /unknown through to be mis-resolved.
4400
+ * The skills a message's `/skill-name` tokens load, snapshotted here so the
4401
+ * planner gets Ordewell's skill rather than a runner (Claude Code, OpenCode)
4402
+ * resolving the token in its own skills directory. The message stays as
4403
+ * typed.
4433
4404
  */
4434
4405
  private resolveSkillInvocation;
4406
+ /**
4407
+ * The one catalog every planner path reads — its skill catalogs, `/name`,
4408
+ * and the check of what a plan or an edit attaches — over the folders the
4409
+ * workspace's tasks will read at spawn.
4410
+ */
4411
+ private workspaceSkills;
4412
+ /** The catalog over workspace `roots`; the workspace root alone is the session's own. */
4413
+ private skillsAt;
4435
4414
  private conversationOpening;
4436
4415
  /**
4437
4416
  * Load planner-produced tasks, coerced to the allowlist read live — it may
@@ -4478,6 +4457,8 @@ declare class Session {
4478
4457
  */
4479
4458
  processQueuedMessages(): Promise<void>;
4480
4459
  private drainQueue;
4460
+ /** Said through both channels: a host shows one or the other, never both (the daemon's toasts are no-ops). */
4461
+ private notice;
4481
4462
  private applyQueuedEdits;
4482
4463
  /**
4483
4464
  * Every finished task as the log records it: this run's own entries, plus
@@ -4497,8 +4478,7 @@ declare class Session {
4497
4478
  sendTaskMessage(taskId: string, text: string): string;
4498
4479
  /**
4499
4480
  * Force send (ADR-0023, F1): interrupt the task's running turn and deliver
4500
- * this message next. Throws `TaskControlError` where a plain message would,
4501
- * and for a task on the terminal transport.
4481
+ * this message next. Throws `TaskControlError` where a plain message would.
4502
4482
  */
4503
4483
  forceSendTaskMessage(taskId: string, text: string): string;
4504
4484
  forceSendQueuedTaskMessage(taskId: string, id: string): boolean;
@@ -4703,17 +4683,18 @@ interface OkResponse {
4703
4683
  ok: boolean;
4704
4684
  }
4705
4685
  /**
4706
- * A plan as the planner routes return it: the session's plan state itself, not
4707
- * the `SerializedPlan` a websocket `plan_generated` carries. The two differ —
4686
+ * A plan as the planner routes return it: the session's plan state, not the
4687
+ * `SerializedPlan` a websocket `plan_generated` carries. The two differ —
4708
4688
  * this one holds raw tasks and the dialogue's bookkeeping — and a client that
4709
- * reads either reads only the fields it needs.
4689
+ * reads either reads only the fields it needs. Skill bodies stay in the
4690
+ * session: loads and attempt snapshots arrive as notices.
4710
4691
  */
4711
4692
  interface PlanResponse {
4712
- plan: LegacyPlanState;
4693
+ plan: SurfacePlan;
4713
4694
  }
4714
4695
  /** `POST /plans/:id/resolve-conflict`: `null` when the session had no conflict to hand a resolver task. */
4715
4696
  interface ResolveConflictResponse {
4716
- plan: LegacyPlanState | null;
4697
+ plan: SurfacePlan | null;
4717
4698
  }
4718
4699
  /** What `GET /api/models` returns, and what the pool's provider discovery produces. */
4719
4700
  interface ModelsResponse {
@@ -4730,7 +4711,9 @@ interface ModelsResponse {
4730
4711
  }
4731
4712
  /** One-shot planning answers in the phase-tagged shape a saved session is read back in. */
4732
4713
  interface GeneratePlanResponse extends Pick<ModelsResponse, 'models' | 'modelsByRunner'> {
4733
- plan: PlanState;
4714
+ plan: SurfacePlanState;
4715
+ /** The host notes the plan's transcript records, a skill check's warnings among them, which the phase-tagged plan does not carry. */
4716
+ notes?: string[];
4734
4717
  }
4735
4718
  interface ExecuteResponse {
4736
4719
  status: 'running';
@@ -4767,7 +4750,7 @@ type IsolationMergeResponse = IsolationMergeResult;
4767
4750
  interface ConversationForkResponse {
4768
4751
  sessionId: string;
4769
4752
  goal: string;
4770
- plan: LegacyPlanState;
4753
+ plan: SurfacePlan;
4771
4754
  }
4772
4755
  /** A fork made by a rewind, with the full text of the message it was made just before. */
4773
4756
  interface ConversationRewindResponse extends ConversationForkResponse {
@@ -4793,10 +4776,10 @@ interface RunnersResponse {
4793
4776
  /** Sessions: a saved one comes off its file, a live one from the pool's store. */
4794
4777
  interface SessionResponse {
4795
4778
  meta: SessionMeta;
4796
- plan: PlanState;
4779
+ plan: SurfacePlanState;
4797
4780
  }
4798
4781
  interface AdoptSessionResponse extends OkResponse {
4799
- plan: LegacyPlanState;
4782
+ plan: SurfacePlan;
4800
4783
  goal: string;
4801
4784
  }
4802
4785
  interface TaskLogAttemptsResponse {
@@ -4813,11 +4796,8 @@ interface SettingsResponse {
4813
4796
  aiProvider: AiProvider;
4814
4797
  plannerThinkingEffort: string;
4815
4798
  maxParallel: number;
4816
- tdd: UserSettings['tdd'];
4817
- verification: UserSettings['verification'];
4818
4799
  modelAllowlist: UserSettings['modelAllowlist'];
4819
4800
  plannerModels: UserSettings['plannerModels'];
4820
- runnerTransport: RunnerTransport;
4821
4801
  }
4822
4802
  /** What `PATCH /api/settings` answers: the settings as they now stand, plus what the write itself decided. */
4823
4803
  interface SettingsUpdateResponse extends SettingsResponse {
@@ -4837,9 +4817,6 @@ interface CommandDescriptor {
4837
4817
  interface CommandsResponse {
4838
4818
  commands: CommandDescriptor[];
4839
4819
  }
4840
- interface CommandResponse extends OkResponse {
4841
- settings: SettingsResponse;
4842
- }
4843
4820
  interface WorkspacesResponse {
4844
4821
  workspaces: string[];
4845
4822
  }
@@ -4873,7 +4850,7 @@ declare class AlreadyExecutingError extends Error {
4873
4850
 
4874
4851
  /**
4875
4852
  * Where Ordewell keeps machine-global data (settings, daemon tokens, caches,
4876
- * user plugins). A single home for everything not tied to a project directory,
4853
+ * credentials). A single home for everything not tied to a project directory,
4877
4854
  * so per-project state in `.ordewell/` and global state never collide.
4878
4855
  */
4879
4856
  declare function globalDataDir(): string;
@@ -4900,22 +4877,14 @@ type CheckpointWithdrawnListener = (taskId: string) => void;
4900
4877
  /** Fires on every idleSince transition (null→timestamp on silence, timestamp→null on resume/teardown). */
4901
4878
  type IdleListener = (taskId: string, idleSince: string | null) => void;
4902
4879
  declare class VerdictEngine {
4903
- private markerSeen;
4904
4880
  private pendingVerdicts;
4905
- private structuredSessions;
4906
- private markerTails;
4907
- private checkpointCarry;
4908
- private pausedSessions;
4881
+ private sessions;
4909
4882
  private listeners;
4910
4883
  private checkpointListeners;
4911
4884
  private withdrawnListeners;
4912
- /**
4913
- * The open `checkpoint` tool call per task (ADR-0022, V5): settling it is how
4914
- * an answer reaches a runner that asked through the tool, where the marker's
4915
- * answer is typed into the session instead.
4916
- */
4885
+ /** The open `checkpoint` tool call per task (ADR-0022, V5): settling it is how an answer reaches the runner. */
4917
4886
  private toolCheckpoints;
4918
- /** The question a task's checkpoint asks, whole, for as long as it waits — by either route. */
4887
+ /** The question a task's checkpoint asks, whole, for as long as it waits. */
4919
4888
  private checkpointQuestions;
4920
4889
  private idleListeners;
4921
4890
  /**
@@ -4957,32 +4926,22 @@ declare class VerdictEngine {
4957
4926
  private touchIdle;
4958
4927
  /** Tear down idle tracking for a task; broadcasts the null transition if it was idle. */
4959
4928
  private clearIdle;
4960
- /**
4961
- * Submit a synchronized resume token to the paused session. An interactive
4962
- * TUI only accepts the Enter keystroke (`\r`) — a `\n` types the token into
4963
- * its composer without sending it, leaving the agent paused until a human
4964
- * presses Enter. A line-oriented piped session has no composer; it reads a
4965
- * `\n`-terminated line, and the leading newline flushes a partial line.
4966
- */
4967
- private resumeToken;
4968
4929
  /** What a task's waiting checkpoint asks, untruncated; undefined when none waits. */
4969
4930
  getCheckpointQuestion(taskId: string): string | undefined;
4970
4931
  approveCheckpoint(taskId: string): void;
4971
4932
  rejectCheckpoint(taskId: string, reason: string): void;
4972
4933
  /**
4973
- * Attach to a spawned session: scan the output tail for the task's completion
4974
- * marker (delivering a verdict immediately while leaving interactive sessions
4975
- * open), scan for checkpoint markers, and on exit produce a failed verdict
4976
- * when the marker was never observed. A structured session's `task_complete`
4977
- * call is evidence too (ADR-0022, V2): whichever signal comes first decides.
4934
+ * Attach to a spawned session. The runner's `task_complete` call on the
4935
+ * attempt's token is the only completion evidence (ADR-0022, V2); a session
4936
+ * that exits before one gets a failed verdict.
4978
4937
  *
4979
4938
  * Returns the attempt's generation, what {@link signalComplete} is checked against.
4980
4939
  */
4981
- watch(task: Task, session: ITerminalSession): number;
4940
+ watch(task: Task, session: IRunnerSession): number;
4982
4941
  /**
4983
4942
  * The runner's own `task_complete` call (ADR-0022, V1/V3): settles the
4984
- * attempt exactly as the marker does, unless that attempt is no longer the
4985
- * task's current one or another signal already settled it.
4943
+ * attempt, unless that attempt is no longer the task's current one or an
4944
+ * earlier call already settled it.
4986
4945
  */
4987
4946
  signalComplete(taskId: string, generation: number, report: TaskCompleteArgs): void;
4988
4947
  /** The runner was told something after its evidence so far, so only what it reports from here counts. */
@@ -4990,9 +4949,8 @@ declare class VerdictEngine {
4990
4949
  private acceptVerdict;
4991
4950
  private publishVerdict;
4992
4951
  /**
4993
- * The runner's `checkpoint` call (ADR-0022, V5): raised through the same
4994
- * listeners as the marker, so the task waits on the user the same way, and
4995
- * settled by {@link approveCheckpoint} or {@link rejectCheckpoint}. It is
4952
+ * The runner's `checkpoint` call (ADR-0022, V5): the task waits on the
4953
+ * user until it is settled by {@link approveCheckpoint} or {@link rejectCheckpoint}. It is
4996
4954
  * withdrawn, never left hanging, once the attempt is over or the call goes.
4997
4955
  */
4998
4956
  raiseCheckpoint(taskId: string, generation: number, question: string, signal: AbortSignal): Promise<CheckpointAnswer>;
@@ -5001,8 +4959,6 @@ declare class VerdictEngine {
5001
4959
  private withdrawToolCheckpoint;
5002
4960
  private approvalOpened;
5003
4961
  private approvalClosed;
5004
- /** Scan only the new text plus the unmatched carry, so a long run stays linear. */
5005
- private scanCheckpoints;
5006
4962
  private bumpGeneration;
5007
4963
  private forget;
5008
4964
  /** Manual "Mark complete" override: a pass verdict that bypasses evidence. */
@@ -5013,54 +4969,23 @@ declare class VerdictEngine {
5013
4969
  private ceaseTracking;
5014
4970
  /** Drop all tracking state (used on stop / loadPlan). */
5015
4971
  reset(): void;
5016
- private decide;
5017
4972
  }
5018
4973
 
5019
- /**
5020
- * Owns one bounded raw buffer per task attempt, fed from the attempt's
5021
- * session, and reads final answers from the agent's transcript through an
5022
- * injected {@link TranscriptReader}.
5023
- */
4974
+ /** Owns one bounded output buffer per task attempt, fed from the attempt's session. */
5024
4975
  declare class BufferedTaskOutputSource implements TaskOutputSource {
5025
4976
  private captures;
5026
- private transcripts;
5027
4977
  private maxBufferChars;
5028
4978
  constructor(opts?: {
5029
- transcripts?: TranscriptReader;
5030
4979
  maxBufferChars?: number;
5031
4980
  });
5032
- attach(taskId: string, session: ITerminalSession): void;
4981
+ attach(taskId: string, session: IRunnerSession): void;
5033
4982
  detach(taskId: string): void;
5034
4983
  reset(): void;
5035
- finalText(attempt: TaskOutputAttempt, doneToken: string): Promise<string>;
4984
+ finalText(taskId: string): string;
5036
4985
  liveTail(taskId: string, opts: LiveTailOptions): LiveTail | null;
5037
4986
  private append;
5038
4987
  }
5039
4988
 
5040
- /**
5041
- * Read a task's final answer from the agent's own session transcript — the
5042
- * clean, structured record the agent writes about itself — instead of
5043
- * reconstructing what a TUI painted (issue #16, built on #14's render).
5044
- *
5045
- * These stores are private and undocumented and DO rotate (OpenCode migrated
5046
- * from files to SQLite mid-2026). Every reader is therefore defensive: any
5047
- * missing file, unparseable line, or shape drift returns null and the caller
5048
- * falls back to the terminal capture. Nothing here is a hard dependency.
5049
- *
5050
- * Directory and recency only narrow the candidates: with several attempts in
5051
- * one cwd the newest session is whichever task finished last. A transcript is
5052
- * accepted only when its content carries the task's completion marker.
5053
- */
5054
- declare class HomeTranscriptReader implements TranscriptReader {
5055
- private readonly home;
5056
- private readonly claudeConfigDirs;
5057
- constructor(opts?: {
5058
- homeDir?: string;
5059
- workspaceEnv?: (cwd: string) => Promise<Record<string, string>>;
5060
- });
5061
- finalAssistantText(query: TranscriptQuery, maxChars?: number): Promise<string | null>;
5062
- }
5063
-
5064
4989
  /**
5065
4990
  * The ids a runner may actually run: the user's allowlist with the ids that
5066
4991
  * provably belong to a *different* runner dropped. `undefined` means no
@@ -5070,7 +4995,7 @@ declare class HomeTranscriptReader implements TranscriptReader {
5070
4995
  * allowlisted for Claude Code does not limit it — it points it at something it
5071
4996
  * cannot spawn, and the plan only dies once a task is already running. But
5072
4997
  * "this runner didn't list it" is not enough to call an id wrong: discovery can
5073
- * be stale, and a plugin runner may have no list at all. What settles it is
4998
+ * be stale or return no list at all. What settles it is
5074
4999
  * whether *another* runner listed the id. So:
5075
5000
  *
5076
5001
  * - listed for this runner → keep;
@@ -5107,26 +5032,30 @@ declare function buildResearchToolsPrompt(): string;
5107
5032
  declare function buildSubagentSystemPrompt(): string;
5108
5033
  /**
5109
5034
  * Facts about who plans and where tasks will run, as opposed to the user's
5110
- * mode toggles: they change what the prompt can promise, not what it asks for.
5035
+ * choices: they change what the prompt can promise, not what it asks for.
5111
5036
  */
5112
5037
  interface ConversationVariant {
5113
- /** Harness planner (ADR-0009): the agent owns its own tools and research budget. */
5038
+ /**
5039
+ * Harness planner (ADR-0009): the agent owns its own tools and research
5040
+ * budget, and reads the catalog and submits the plan through Ordewell's MCP
5041
+ * tools (ADR-0022). An API planner speaks the JSON envelopes instead.
5042
+ */
5114
5043
  harness?: boolean;
5115
- /** The planner reads the catalog and submits the plan through Ordewell's MCP tools (ADR-0022), not the JSON envelope. */
5116
- plannerTools?: boolean;
5044
+ /** The skill catalog: task skills it can attach on every path, planner skills it can load only with tools. */
5045
+ skills?: readonly SkillInfo[];
5117
5046
  /** Every AI task gets its own worktree (ADR-0013), so file overlap no longer forces an order; of every repo of a group (ADR-0014). */
5118
5047
  isolatedExecution?: IsolatedExecution;
5119
5048
  }
5120
- declare function buildConversationSystemPrompt(goal: string, context: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean, verificationEnabled?: boolean, variant?: ConversationVariant): string;
5049
+ declare function buildConversationSystemPrompt(goal: string, context: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean, variant?: ConversationVariant): string;
5121
5050
  /** The one-shot planner's core rules for tasks that share the workspace root. */
5122
5051
  declare const CORE_PLANNER_PROMPT: string;
5123
5052
  declare function buildResearchPrompt(userGoal: string, context: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, modes?: PlannerModes): string;
5124
- declare function buildPlanWithResults(userGoal: string, context: string, researchResults: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, modes?: PlannerModes): string;
5125
- declare function buildModifyPlanPrompt(existingPlan: LegacyPlanState, userRequest: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, aiflowContext?: string, runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): string;
5053
+ declare function buildPlanWithResults(userGoal: string, context: string, researchResults: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, modes?: PlannerModes, tools?: boolean): string;
5054
+ declare function buildModifyPlanPrompt(existingPlan: LegacyPlanState, userRequest: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, aiflowContext?: string, runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean, tools?: boolean): string;
5126
5055
  declare function modelContextBlock(modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): string;
5127
5056
  declare function executionLogBlock(executionLog: TaskSnapshot[]): string;
5128
5057
  declare function pendingEditRulesBlock(): string;
5129
- declare function buildModifyDuringExecutionPrompt(executionLog: TaskSnapshot[], pendingTasks: string, userMessage: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, modes?: Pick<PlannerModes, 'autonomousDefault' | 'isolatedExecution'>): string;
5058
+ declare function buildModifyDuringExecutionPrompt(executionLog: TaskSnapshot[], pendingTasks: string, userMessage: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, modes?: Pick<PlannerModes, 'autonomousDefault' | 'isolatedExecution'>, tools?: boolean): string;
5130
5059
  /**
5131
5060
  * User-message prompt for a planner-driven merge: asks the model to combine the
5132
5061
  * selected tasks into one. Routed through the conversation loop, so the
@@ -5230,6 +5159,14 @@ declare const JSON_REPAIR_INSTRUCTION: string;
5230
5159
  declare const TRUNCATED_PLAN_REPAIR_INSTRUCTION: string;
5231
5160
  /** A plan attempt was botched (invalid or truncated JSON): re-emit the whole plan. */
5232
5161
  declare function reEmitPlanPrompt(detail: string): string;
5162
+ /**
5163
+ * A planner that submits through Ordewell's tools ended without an accepted
5164
+ * plan, or one it submitted was refused: call the tool again. A plan written
5165
+ * in its reply is never read (ADR-0025), so asking for JSON would be ignored.
5166
+ */
5167
+ declare function resubmitPlanPrompt(errors: string[]): string;
5168
+ /** A tool planner's task edit was refused as its turn settled: correct it through edit_plan. */
5169
+ declare function resubmitEditPrompt(errors: string[]): string;
5233
5170
  /** A plan emission was truncated mid-JSON; the caller may also have compacted the history to free input context. */
5234
5171
  declare function truncatedPlanReEmitPrompt(historyCompacted: boolean): string;
5235
5172
  /** A task-ops attempt was botched (unparseable JSON): re-emit the ops object. */
@@ -5238,8 +5175,8 @@ declare function reEmitTaskOpsPrompt(detail: string): string;
5238
5175
  declare function reEmitTaskQueryPrompt(detail: string): string;
5239
5176
  /** Task ops parsed but failed semantic validation (cycles, unknown refs, locked tasks). */
5240
5177
  declare function taskOpsRejectedPrompt(errors: string[]): string;
5241
- /** A modified plan failed validation during execution: full re-prompt feedback block. */
5242
- declare function modifyValidationFeedback(errors: string[]): string;
5178
+ /** A modified plan failed validation during execution: full re-prompt feedback block, asking for the planner's own transport. */
5179
+ declare function modifyValidationFeedback(errors: string[], tools?: boolean): string;
5243
5180
  type PlannerReplyClassification = {
5244
5181
  kind: 'plan';
5245
5182
  tasks: Task[];
@@ -5289,23 +5226,6 @@ declare function classifyPlannerReply(text: string, opts: {
5289
5226
  */
5290
5227
  declare function generatePlanWithRepair(generate: (repairHint?: string) => Promise<string>, runners: RunnerId[], maxAttempts?: number, runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): Promise<Task[]>;
5291
5228
 
5292
- type RunnerMode = string;
5293
-
5294
- declare function buildRunnerInvocation(opts: {
5295
- runner: string;
5296
- prompt: string;
5297
- modelId?: string;
5298
- thinkingEffort?: string;
5299
- modelVariants?: string[];
5300
- mode?: RunnerMode;
5301
- headless?: boolean;
5302
- interactive?: boolean;
5303
- cwd?: string;
5304
- /** The installed runner's `--version`, for a manifest whose command line differs by major version. */
5305
- runnerVersion?: string;
5306
- registry: RunnerRegistry;
5307
- }): RunnerInvocation;
5308
-
5309
5229
  interface PriorOutput {
5310
5230
  order: number;
5311
5231
  title: string;
@@ -5318,18 +5238,6 @@ declare function summarizeOutput(reviewReason: string | undefined, output: strin
5318
5238
  capturedAt: string;
5319
5239
  };
5320
5240
  declare function collectDirectDependencyOutputs(task: Task, allTasks: readonly Task[]): PriorOutput[];
5321
- /**
5322
- * Break marker tokens carried in a predecessor's captured output. Interactive
5323
- * runners echo the prompt they are given, and the watcher scans that terminal
5324
- * output — a quoted marker would settle this task on the previous one's
5325
- * evidence. Hyphenated rather than spaced: the scanner also reads a
5326
- * whitespace-flattened view of the terminal, which would rejoin a space.
5327
- *
5328
- * A completion marker also loses its id: transcripts are bound to a task by
5329
- * that id, and a dependent's transcript quoting it would answer for the
5330
- * predecessor the next time the predecessor runs.
5331
- */
5332
- declare function defuseMarkers(text: string): string;
5333
5241
  declare function renderPriorOutputs(outputs: PriorOutput[]): string;
5334
5242
  declare function augmentPromptWithPriorOutputs(task: Task, allTasks: readonly Task[]): string;
5335
5243
  /**
@@ -5344,11 +5252,10 @@ declare function renderPlanMap(planTasks: readonly Task[], currentTaskId: string
5344
5252
  interface ComposeOptions {
5345
5253
  planMapEnabled?: boolean;
5346
5254
  planMapMaxEntries?: number;
5347
- tddEnabled?: boolean;
5255
+ /** The task's skills as resolved where this attempt runs. */
5256
+ skills?: readonly TaskSkillSnapshot[];
5348
5257
  /** An ops task's last attempt, as its output ended (ADR-0020); absent on a first attempt. */
5349
5258
  previousAttempt?: string;
5350
- /** The runner is given the `task_complete` and `checkpoint` tools (ADR-0022); the markers stay as their fallback. */
5351
- completionTool?: boolean;
5352
5259
  }
5353
5260
  declare function composeAugmentedPrompt(task: Task, allTasks: readonly Task[], opts?: ComposeOptions): string;
5354
5261
  /**
@@ -5359,143 +5266,44 @@ declare function composeAugmentedPrompt(task: Task, allTasks: readonly Task[], o
5359
5266
  */
5360
5267
  declare function composeContinuationPrompt(task: Task, message: string, opts?: {
5361
5268
  ops?: boolean;
5362
- completionTool?: boolean;
5363
5269
  }): string;
5364
5270
 
5365
- type ExecFileFn = (command: string, args: string[]) => Promise<{
5366
- stdout: string;
5367
- stderr: string;
5368
- }>;
5369
- /** Test seam: every OS touchpoint is injectable; production uses the defaults. */
5370
- interface TmuxRunnerDeps {
5371
- port: number;
5372
- execFileImpl?: ExecFileFn;
5373
- resolvePath?: () => Promise<string>;
5374
- pollIntervalMs?: number;
5375
- logDir?: string;
5376
- clipboardCommand?: () => string | null;
5377
- /** Reads the runner's version, for a manifest whose command line differs by major version. */
5378
- runnerVersion?: RunnerVersionProbe;
5379
- }
5380
- declare class TmuxSession extends AbstractTerminalSession {
5381
- private tmuxSession;
5382
- private windowName;
5383
- private execFileImpl;
5384
- private pollIntervalMs;
5385
- private logPath;
5386
- private socket;
5387
- /** A tmux window is a real TTY running the agent's TUI, so it submits on Enter. */
5388
- readonly interactive = true;
5389
- private outputBuffer;
5390
- private offset;
5391
- private timer;
5392
- private quietPolls;
5393
- private misses;
5394
- private looking;
5395
- constructor(id: string, taskId: string, tmuxSession: string, windowName: string, execFileImpl: ExecFileFn, pollIntervalMs: number, logPath: string, socket: string);
5396
- private get target();
5397
- /** Every tmux call must name the daemon's own socket; an unprefixed one
5398
- * silently targets the shared default server (see `tmuxSocketName`). */
5399
- private tmux;
5400
- /**
5401
- * Runs the invocation in a fresh tmux window, tailed via `pipe-pane` into a
5402
- * log file rather than polling `capture-pane` snapshots — a byte-exact
5403
- * stream needs no diff/resync heuristics. The command is wrapped so the
5404
- * window survives its own exit (an `exec`'d login shell), which is what
5405
- * lets the user keep poking at a finished task's terminal.
5406
- */
5407
- start(command: string, args: string[], cwd: string, env?: Record<string, string>): Promise<void>;
5408
- private poll;
5409
- /** Emit what the log gained since the last read; false when it gained nothing. */
5410
- private readLog;
5411
- /**
5412
- * The sentinel is printed by the wrapper shell, so a window closed from
5413
- * outside — killed by the user, or with the whole tmux server — never prints
5414
- * it, and the session would count as running forever. A silent window is
5415
- * therefore looked up by exact name (a `-t` target falls back to another
5416
- * window once its own is gone), and once it is confirmed missing the session
5417
- * ends as a kill does. Whatever the log still held is read first, so a
5418
- * completion marker printed just before the close still counts.
5419
- */
5420
- private checkWindow;
5421
- /**
5422
- * A task finishing (or being killed) stops observation, but never the
5423
- * window itself on the sentinel path — only `kill()` closes the window.
5424
- * Piping is turned off and the log file removed either way, so a finished
5425
- * task doesn't leave a `cat` process appending to it for the rest of the
5426
- * daemon's life.
5427
- */
5428
- private finish;
5429
- kill(): void;
5430
- getOutput(): string;
5431
- write(text: string): void;
5432
- }
5433
- /**
5434
- * Runs tasks in a real tmux window instead of a piped subprocess, so a user
5435
- * can open a genuine, interactive terminal on any task (running or
5436
- * finished) from outside Ordewell's own process. `ITerminalSession` hides the
5437
- * transport from `VerdictEngine`/`PoolAwareRunner`, so orchestration is
5438
- * unchanged — this is a drop-in replacement for `HeadlessRunner`.
5439
- */
5440
- declare class TmuxRunner extends AbstractRunner<TmuxSession> {
5441
- private sessionName;
5442
- private socket;
5443
- private execFileImpl;
5444
- private resolvePath;
5445
- private pollIntervalMs;
5446
- private logDir;
5447
- private clipboardCommand;
5448
- private runnerVersion;
5449
- /** Retries get a freshly named window so a failed attempt's output stays inspectable. */
5450
- private attempts;
5451
- private ready;
5452
- constructor(deps: TmuxRunnerDeps);
5453
- /**
5454
- * Reaps a session orphaned by a crashed prior daemon on the same port, then
5455
- * creates a fresh one. Memoized: `spawn` awaits it too, so a task spawned
5456
- * before startup's own call has settled never lands in a missing session —
5457
- * and a settled failure clears the memo so the next spawn can retry.
5458
- */
5459
- ensureSession(): Promise<void>;
5460
- /** Every tmux call must name this daemon's socket; see `tmuxSocketName`. */
5461
- private tmux;
5462
- private createFreshSession;
5463
- /**
5464
- * Gives an attached runner terminal wheel/PageUp scrolling over a deep
5465
- * scrollback, and a mouse selection that reaches the system clipboard — none
5466
- * of which a default tmux session does. Server-wide scoping is harmless: the
5467
- * daemon owns a private socket (`tmuxSocketName`).
5468
- *
5469
- * `mouse on` is what costs the emulator's own drag-select, so tmux must hand
5470
- * the selection back out itself: via a clipboard binary when there is one,
5471
- * and via OSC 52 (`set-clipboard`) for what that cannot cover, such as
5472
- * viewing over SSH. Naming the binary on the binding as well as in
5473
- * `copy-command` keeps drag-to-copy working on tmux older than 3.2, which has
5474
- * no `copy-command`.
5475
- */
5476
- private configureScrolling;
5477
- /**
5478
- * Called on daemon shutdown — the one guarantee against leaked tmux
5479
- * processes. Kills the whole server, not just the session: the socket
5480
- * belongs to this daemon alone, so nothing else can be on it, and a runner
5481
- * that somehow escaped its session would otherwise keep running (and keep
5482
- * billing) unattached for as long as the server lived.
5483
- */
5484
- killSession(): Promise<void>;
5485
- spawn(opts: {
5486
- taskId: string;
5487
- runner: string;
5488
- prompt: string;
5489
- modelId?: string;
5490
- thinkingEffort?: string;
5491
- modelVariants?: string[];
5492
- mode?: string;
5493
- headless?: boolean;
5494
- cwd: string;
5495
- registry?: RunnerRegistry;
5496
- planSessionId?: string;
5497
- env?: Record<string, string>;
5498
- }): Promise<ITerminalSession>;
5271
+ /** One source for the spawn options, so a runner built on this base cannot drift from the interface. */
5272
+ type RunnerSpawnOptions = Parameters<IRunner['spawn']>[0];
5273
+ declare abstract class AbstractRunnerSession implements IRunnerSession {
5274
+ id: string;
5275
+ taskId: string;
5276
+ protected exited: boolean;
5277
+ protected outputEmitter: EventEmitter<any>;
5278
+ protected exitEmitter: EventEmitter<any>;
5279
+ constructor(id: string, taskId: string);
5280
+ protected baseHandleExit(code: number): void;
5281
+ onOutput(callback: (text: string) => void): void;
5282
+ onExit(callback: (code: number) => void): void;
5283
+ abstract kill(): void;
5284
+ abstract getOutput(): string;
5285
+ abstract write(text: string): void;
5286
+ abstract turnState(): 'working' | 'idle';
5287
+ abstract onTurnEnd(listener: (reason: StructuredTurnEnd) => void): void;
5288
+ abstract onEvent(listener: (event: StructuredEvent) => void): void;
5289
+ abstract sendMessage(text: string): string;
5290
+ abstract forceSend(text: string): string;
5291
+ abstract forceSendQueued(id: string): boolean;
5292
+ abstract removeQueued(id: string): boolean;
5293
+ abstract queued(): QueuedTaskMessage[];
5294
+ abstract interrupt(): Promise<void>;
5295
+ abstract nativeSessionId(): string | null;
5296
+ abstract answerPermission(id: string, decision: ApprovalDecision): boolean;
5297
+ abstract onTaskComplete(listener: (report: TaskCompleteArgs) => void): void;
5298
+ abstract onToolCheckpoint(handler: (question: string, signal: AbortSignal) => Promise<CheckpointAnswer>): void;
5299
+ }
5300
+ declare abstract class AbstractRunner<S extends IRunnerSession> implements IRunner {
5301
+ protected sessions: Map<string, S>;
5302
+ get activeCount(): number;
5303
+ stop(sessionId: string): void;
5304
+ stopAll(): void;
5305
+ protected registerSession(id: string, session: S): void;
5306
+ abstract spawn(opts: RunnerSpawnOptions): Promise<IRunnerSession>;
5499
5307
  }
5500
5308
 
5501
5309
  interface StructuredRunnerDeps {
@@ -5513,26 +5321,27 @@ interface SessionLaunch {
5513
5321
  createAdapter: (runner: string, deps: AgentProcessDeps) => TaskModeAgentAdapter;
5514
5322
  startOptions: TaskStartOptions;
5515
5323
  interruptGraceMs: number;
5516
- /** Where this attempt's task tools are served, when its runner takes them (ADR-0022). */
5517
- tools?: {
5324
+ /** Where this attempt's task tools are served (ADR-0022). */
5325
+ tools: {
5518
5326
  server: OrdewellMcpServer;
5519
5327
  scope: TaskTokenScope;
5520
5328
  };
5329
+ onNotice?: (message: string) => void;
5521
5330
  }
5522
5331
  /**
5523
5332
  * One task driven over its runner's programmatic protocol (ADR-0018). It *is*
5524
- * an `ITerminalSession`, so everything downstream of `onOutput` is unchanged;
5525
- * what a terminal cannot do sits on {@link StructuredSessionCapability}.
5333
+ * an `IRunnerSession`, with plain output and structured events.
5526
5334
  *
5527
5335
  * Ordewell owns the message queue (M1). A message sent mid-turn is handed to a
5528
5336
  * runner that can take one at its next step (ADR-0023); otherwise it waits for
5529
5337
  * the turn to end rather than being typed into a runner that is busy.
5530
5338
  */
5531
- declare class StructuredSession extends AbstractTerminalSession implements StructuredSessionCapability {
5339
+ declare class StructuredSession extends AbstractRunnerSession {
5532
5340
  private readonly launch;
5533
- readonly transport: "structured";
5534
5341
  private adapter;
5535
5342
  private adapterStarted;
5343
+ private adapterAttached;
5344
+ private startupExit;
5536
5345
  /** Bumped whenever the adapter is replaced, so the old one's late events and exit are ignored. */
5537
5346
  private generation;
5538
5347
  private output;
@@ -5558,16 +5367,25 @@ declare class StructuredSession extends AbstractTerminalSession implements Struc
5558
5367
  private toolToken;
5559
5368
  private checkpointHandler;
5560
5369
  constructor(id: string, taskId: string, launch: SessionLaunch);
5561
- /** Start the runner and send the task's prompt as its first turn. */
5370
+ /**
5371
+ * Start the runner with the attempt's tools attached and send the task's
5372
+ * prompt as its first turn. `task_complete` is the only way a task reports
5373
+ * it is done, so a runner without the tools is never sent the task: it is
5374
+ * killed and respawned once, and a second failure fails the start.
5375
+ */
5562
5376
  start(prompt: string): Promise<void>;
5563
5377
  getOutput(): string;
5564
5378
  onTaskComplete(listener: (report: TaskCompleteArgs) => void): void;
5565
5379
  onToolCheckpoint(handler: (question: string, signal: AbortSignal) => Promise<CheckpointAnswer>): void;
5566
5380
  /**
5567
- * A server that cannot start costs the task its tools, not its run: the
5568
- * prompt still teaches the marker (ADR-0022, S2).
5381
+ * One spawn of the runner on a fresh token. Null once the runner reports
5382
+ * the server connected — or once the session ended meanwhile, which leaves
5383
+ * nothing to start; otherwise why not, with the process killed and the
5384
+ * token revoked. A runner that cannot be spawned at all throws instead:
5385
+ * spawning it again would fail the same way.
5569
5386
  */
5570
- private issueTools;
5387
+ private startAttached;
5388
+ private startWithTools;
5571
5389
  private revokeTools;
5572
5390
  protected baseHandleExit(code: number): void;
5573
5391
  /**
@@ -5657,8 +5475,7 @@ declare class StructuredSession extends AbstractTerminalSession implements Struc
5657
5475
  /**
5658
5476
  * The structured transport (ADR-0018): a task's runner as a plain child
5659
5477
  * process speaking its protocol — no tmux, no `script` (W2). Only runners
5660
- * with a task-mode connector can be spawned here; routing the rest to the
5661
- * terminal transport is the caller's decision, not a silent downgrade here.
5478
+ * with a task-mode connector can be spawned here.
5662
5479
  */
5663
5480
  declare class StructuredRunner extends AbstractRunner<StructuredSession> {
5664
5481
  private spawnCount;
@@ -5667,44 +5484,7 @@ declare class StructuredRunner extends AbstractRunner<StructuredSession> {
5667
5484
  private readonly interruptGraceMs;
5668
5485
  private readonly mcp;
5669
5486
  constructor(deps?: StructuredRunnerDeps);
5670
- spawn(opts: RunnerSpawnOptions): Promise<ITerminalSession>;
5671
- }
5672
-
5673
- interface TransportRoute {
5674
- transport: RunnerTransport;
5675
- /** Why a structured request runs on the terminal instead, in words a surface shows as is. */
5676
- fallback?: string;
5677
- }
5678
- /**
5679
- * Where one task runs (ADR-0018, S3): structured only when the plan asks for
5680
- * it and the task's runner has a task-mode connector. Anything else runs on
5681
- * the terminal, and a structured request says why.
5682
- */
5683
- declare function routeTransport(requested: RunnerTransport | undefined, runner: string, registry?: RunnerRegistry | null): TransportRoute;
5684
- /**
5685
- * The runner a host hands the orchestrator: its own terminal runner (tmux,
5686
- * headless, the VS Code terminal) and the structured one behind a single
5687
- * `ITerminalRunner`, picking per spawn by {@link routeTransport}.
5688
- *
5689
- * `stopAll` and `activeCount` reach both inner runners, so a host that shares
5690
- * one across plans (the daemon's tmux) keeps its per-plan wrapper above this.
5691
- */
5692
- declare class TransportRouter implements ITerminalRunner {
5693
- private readonly runners;
5694
- /**
5695
- * Session ids the structured runner owns; every other id is the terminal's.
5696
- * Kept past exit, so a stop that arrives late never reaches the terminal
5697
- * runner with an id it does not know.
5698
- */
5699
- private readonly structuredIds;
5700
- constructor(runners: {
5701
- terminal: ITerminalRunner;
5702
- structured: ITerminalRunner;
5703
- });
5704
- get activeCount(): number;
5705
- spawn(opts: RunnerSpawnOptions): Promise<ITerminalSession>;
5706
- stop(sessionId: string): void;
5707
- stopAll(): void;
5487
+ spawn(opts: RunnerSpawnOptions): Promise<IRunnerSession>;
5708
5488
  }
5709
5489
 
5710
5490
  /** Whether a task can be continued in its saved runner session (ADR-0018, K1), and in which. */
@@ -5717,9 +5497,8 @@ type Continuability = {
5717
5497
  };
5718
5498
  /**
5719
5499
  * The rule every surface offers Continue by and the orchestrator enforces: a
5720
- * completed or failed task whose last attempt ran structured and left a
5721
- * session id behind. A conflict is resolved by its repair, not a new turn, and
5722
- * a terminal task has no session Ordewell can reach — Retry covers both.
5500
+ * completed or failed task whose last attempt left a session id behind. A
5501
+ * conflict is resolved by its repair, not a new turn — Retry covers it.
5723
5502
  */
5724
5503
  declare function continuability(task: Task): Continuability;
5725
5504
  declare function canContinue(task: Task): boolean;
@@ -5739,8 +5518,7 @@ interface TaskLogRecorderDeps {
5739
5518
  * batches, so what a surface saw live and what it reloads are one sequence.
5740
5519
  *
5741
5520
  * It sits around the runner rather than inside the orchestrator, which stays
5742
- * unaware of logs; a terminal-transport session has no event stream and is
5743
- * passed through untouched.
5521
+ * unaware of logs.
5744
5522
  */
5745
5523
  declare class TaskLogRecorder {
5746
5524
  private readonly deps;
@@ -5748,10 +5526,130 @@ declare class TaskLogRecorder {
5748
5526
  private readonly flushMs;
5749
5527
  private readonly logger;
5750
5528
  constructor(deps: TaskLogRecorderDeps);
5751
- wrap(runner: ITerminalRunner): ITerminalRunner;
5752
- /** Start a new attempt's log for `session` and keep it until the session exits. */
5753
- record(taskId: string, session: ITerminalSession & StructuredSessionCapability): void;
5529
+ wrap(runner: IRunner): IRunner;
5530
+ /** Start a new attempt's log for `session`, opening with the skills it was given, and keep it until the session exits. */
5531
+ record(taskId: string, session: IRunnerSession, skills?: readonly TaskSkillSnapshot[]): void;
5532
+ }
5533
+
5534
+ declare function stripAnsi(text: string): string;
5535
+
5536
+ /**
5537
+ * cmd.exe's command-line buffer. A longer line is truncated rather than
5538
+ * rejected, which would corrupt a planner's system prompt or a task's prompt
5539
+ * mid-sentence and produce a confident answer to half a question — so the
5540
+ * batch route refuses instead. See {@link CommandLineTooLongError}.
5541
+ */
5542
+ declare const CMD_EXE_MAX_COMMAND_LINE = 8191;
5543
+ /**
5544
+ * CreateProcess's own ceiling, which the native and PowerShell routes are
5545
+ * bounded by instead. Windows truncates here too, so the same refusal applies —
5546
+ * it is simply four times further away.
5547
+ */
5548
+ declare const WINDOWS_MAX_COMMAND_LINE = 32767;
5549
+ interface LaunchPlan {
5550
+ /** The executable handed to `spawn()`. */
5551
+ file: string;
5552
+ /** Arguments for `file`. Pass verbatim when {@link verbatim} is set. */
5553
+ args: string[];
5554
+ /**
5555
+ * Windows batch route only: `args` is already a quoted command line and must
5556
+ * not be re-quoted. Maps to `windowsVerbatimArguments` for `spawn`.
5557
+ */
5558
+ verbatim?: boolean;
5559
+ }
5560
+ /** Test seam: every OS touchpoint is injectable, and production uses the defaults. */
5561
+ interface LaunchDeps {
5562
+ platform?: NodeJS.Platform;
5563
+ /** The PATH executables are looked up on. Defaults to the augmented PATH. */
5564
+ resolvePath?: () => Promise<string>;
5565
+ /** True when `candidate` names an existing file. */
5566
+ exists?: (candidate: string) => boolean;
5567
+ /** Absolute path to the Windows command interpreter. */
5568
+ comSpec?: () => string;
5569
+ /** Absolute path to Windows PowerShell. */
5570
+ powerShell?: () => string;
5571
+ /** PATHEXT, as the environment reports it. */
5572
+ pathExt?: () => string;
5573
+ }
5574
+ /**
5575
+ * Thrown when a command's arguments do not fit the buffer of the only
5576
+ * interpreter that can start it. Windows truncates rather than rejecting, and a
5577
+ * system prompt cut off mid-sentence makes the planner answer half a question
5578
+ * confidently — the silent success this repo refuses — so this is raised
5579
+ * instead. `TaskOrchestrator.startTask` catches it and holds the task, so the
5580
+ * message is what the user reads: it names the fix, because they cannot infer
5581
+ * it from a truncated prompt.
5582
+ */
5583
+ declare class CommandLineTooLongError extends Error {
5584
+ readonly command: string;
5585
+ readonly length: number;
5586
+ readonly limit: number;
5587
+ constructor(command: string, length: number, limit?: number);
5588
+ }
5589
+ /**
5590
+ * Thrown when only a batch shim resolved for a multi-line argument. cmd.exe
5591
+ * reads up to the first CR/LF and discards the rest with no error and exit code
5592
+ * 0 — quoting does not help — so the agent would get the first paragraph of its
5593
+ * prompt without the instruction to report through `task_complete`, then exit looking successful.
5594
+ */
5595
+ declare class EmbeddedNewlineError extends Error {
5596
+ readonly command: string;
5597
+ constructor(command: string);
5598
+ }
5599
+ /**
5600
+ * Thrown when `command` cannot be resolved to a real file. Kept distinguishable
5601
+ * from `WorkspaceNotFoundError` (utils/workspace) even though both a missing
5602
+ * cwd and a missing binary surface as the same `spawn` ENOENT to Node — the two
5603
+ * are checked, and named, separately so the failure names the actual cause.
5604
+ */
5605
+ declare class ExecutableNotFoundError extends Error {
5606
+ readonly command: string;
5607
+ readonly searchedPath: string;
5608
+ constructor(command: string, searchedPath: string);
5754
5609
  }
5610
+ /**
5611
+ * Whether `command` actually resolves to a file, given the plan
5612
+ * {@link planDirectLaunch} produced for it and the PATH it was resolved
5613
+ * against.
5614
+ *
5615
+ * POSIX is deliberately identity in `planDirectLaunch` (execvp does its own
5616
+ * PATH search), so the search is repeated here instead. Windows already did
5617
+ * the search inside `planDirectLaunch` — signalled by the returned file
5618
+ * differing from the bare command name it was given; an unresolved command
5619
+ * comes back unchanged.
5620
+ */
5621
+ declare function isExecutableResolved(command: string, plan: LaunchPlan, PATH: string, deps?: LaunchDeps): boolean;
5622
+ /** The verbatim command line cmd.exe receives after `/d /s /c`, before wrapping. */
5623
+ declare function windowsCommandLine(file: string, args: string[]): string;
5624
+ /**
5625
+ * How to start `command` with `args` through `spawn()`, with no shell.
5626
+ *
5627
+ * POSIX returns its input unchanged — execvp already searches PATH, and adding
5628
+ * a resolution step there would be a new way for a working setup to break.
5629
+ *
5630
+ * Windows resolves the command against PATH × PATHEXT, preferring a native
5631
+ * executable (spawned directly) over a batch shim (through cmd.exe) over a
5632
+ * PowerShell script shim (through `powershell.exe -File`). A command that
5633
+ * resolves to nothing is returned unchanged, so the caller's existing ENOENT —
5634
+ * which names what the user typed — is what surfaces rather than a second,
5635
+ * vaguer error from here.
5636
+ *
5637
+ * The tiers are tried in preference order and the first that *fits* wins, with
5638
+ * one deliberate exception: an overflowing batch shim does not fall through to
5639
+ * PowerShell. Overflow means a very large prompt, which is precisely where
5640
+ * `-File` argument fidelity is least worth betting on, and where a clear held
5641
+ * task beats a plausibly-mangled one. So capacity does not reorder the tiers —
5642
+ * a `.ps1` beside a too-long `.cmd` still raises.
5643
+ *
5644
+ * A line break does reorder them: cmd.exe cannot carry one at any length, so a
5645
+ * `.ps1` beside a `.cmd` wins, and a lone `.cmd` raises.
5646
+ *
5647
+ * @throws {CommandLineTooLongError} when the selected route's buffer cannot
5648
+ * carry the arguments.
5649
+ * @throws {EmbeddedNewlineError} when the arguments span lines and only the
5650
+ * batch route resolved.
5651
+ */
5652
+ declare function planDirectLaunch(command: string, args: string[], deps?: LaunchDeps): Promise<LaunchPlan>;
5755
5653
 
5756
5654
  /**
5757
5655
  * A workspace path that does not exist, or exists but is not a directory.
@@ -5918,137 +5816,42 @@ declare function clearAugmentedPathCache(): void;
5918
5816
  */
5919
5817
  declare function withPath(base: NodeJS.ProcessEnv, resolvedPath: string, overrides?: Record<string, string>): NodeJS.ProcessEnv;
5920
5818
 
5921
- /** One shared tmux session per daemon, scoped by port so multiple daemons never collide. */
5922
- declare function tmuxSessionName(port: number): string;
5923
- /**
5924
- * Each daemon gets its own tmux *server*, not just its own session name.
5925
- *
5926
- * A plain `tmux new-session` attaches to whatever server already owns the
5927
- * default socket, and a session created on an existing server inherits that
5928
- * **server's** environment — not the environment of the process that asked for
5929
- * it (tmux only refreshes `update-environment` vars, and only on attach). So a
5930
- * daemon started with, say, a particular provider API key would silently hand
5931
- * its runners a stale key left behind by whoever started the server first,
5932
- * possibly hours earlier under a different configuration entirely.
5933
- *
5934
- * A private socket makes the server a child of this daemon, so the runner
5935
- * inherits the daemon's environment the way any child process would, and
5936
- * `kill-server` at shutdown is authoritative — a runner cannot outlive the
5937
- * daemon by hiding on a shared server. Users attaching by hand need the same
5938
- * flag: `tmux -L ordewell-<port> attach -t ordewell-<port>`.
5939
- */
5940
- declare function tmuxSocketName(port: number): string;
5941
- /**
5942
- * tmux window targeting breaks on `:` and other punctuation, so ids are
5943
- * slugged. Task ids are only unique within one plan ("task-1" is every
5944
- * planner's favourite), so the window is also scoped by the plan session id —
5945
- * without it, the second plan run in a daemon's lifetime would collide with
5946
- * the first plan's still-open windows and pipe its output into the wrong one.
5947
- */
5948
- declare function tmuxWindowName(taskId: string, planSessionId?: string): string;
5949
- type ProbeFn = () => void;
5950
- /** Feature-detects tmux the same way `HeadlessRunner` detects `script`. */
5951
- declare function hasTmux(probe?: ProbeFn): boolean;
5952
5819
  type HasBinFn = (bin: string) => boolean;
5953
5820
  /**
5954
5821
  * Shell command tmux should pipe a copy-mode selection into, so selecting text
5955
- * in a task's terminal puts it on the *system* clipboard rather than in a tmux
5822
+ * in a tmux pane puts it on the *system* clipboard rather than in a tmux
5956
5823
  * paste buffer no other application can read. Preferred over tmux's OSC 52
5957
5824
  * bridge, which plenty of emulators (VTE before 0.76, xterm without
5958
5825
  * `allowWindowOps`) drop on the floor.
5959
5826
  */
5960
5827
  declare function clipboardCopyCommand(hasBin?: HasBinFn, platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv): string | null;
5961
5828
 
5962
- declare class FsPluginStore implements IPluginStore {
5963
- getUserPluginsDir(): string;
5964
- listUserPluginDirs(): string[];
5965
- listDir(dir: string): string[];
5966
- loadManifest(pluginDir: string): RunnerPluginManifest | null;
5967
- copyDir(sourceDir: string, destDir: string): void;
5968
- removeDir(dir: string): void;
5969
- ensureDir(dir: string): void;
5970
- writeFile(filePath: string, content: string): void;
5971
- readFile(filePath: string): string | null;
5972
- dirExists(path: string): boolean;
5973
- exists(path: string): boolean;
5974
- }
5975
-
5976
- /**
5977
- * Shape check for a manifest read off disk or out of a cloned repository. The
5978
- * name is constrained here rather than at each install route, so every store
5979
- * implementation gets the same guarantee that a manifest name is a plain
5980
- * segment and never a traversal sequence.
5981
- */
5982
- declare function isValidManifest(obj: unknown): obj is RunnerPluginManifest;
5983
-
5984
- /**
5985
- * A plugin name is a single plain path segment: alphanumeric at both ends,
5986
- * dots/dashes/underscores in between. This is what keeps a manifest name from
5987
- * being a traversal sequence (`..`, `../../etc`), an absolute path, or a
5988
- * dash-prefixed string that a downstream tool reads as a flag.
5989
- */
5990
- declare const PLUGIN_NAME_PATTERN: RegExp;
5991
- declare function isPlainPluginName(name: unknown): name is string;
5992
- declare function assertPlainPluginName(name: unknown): asserts name is string;
5993
- /**
5994
- * Resolve where a plugin of this name installs, and assert the result is still
5995
- * a direct child of the plugins directory. Validation and use share this one
5996
- * call so they cannot disagree about the path being checked.
5997
- */
5998
- declare function resolvePluginInstallDir(pluginsDir: string, name: unknown): string;
5999
-
6000
- /** Hosts a plugin may be cloned from. Exact hostname match, case-insensitive. */
6001
- declare const ALLOWED_PLUGIN_HOSTS: readonly string[];
6002
- type PluginSource = {
6003
- kind: 'git';
6004
- url: string;
6005
- } | {
6006
- kind: 'path';
6007
- path: string;
6008
- };
6009
- /**
6010
- * Validate a plugin repository URL. Requires an ordinary HTTPS repository on an
6011
- * allowed host, which is also what rejects git's transport helpers (`ext::`,
6012
- * `git://`, `ssh://`, `file://`) — they never reach the clone because they are
6013
- * not the https scheme.
6014
- *
6015
- * Returns the parsed URL so callers clone the normalised form they validated.
6016
- */
6017
- declare function assertInstallablePluginUrl(url: unknown): URL;
6018
- /**
6019
- * Decide whether an install source names a remote repository or a local
6020
- * directory. Anything that carries a scheme or looks like an scp-style remote
6021
- * goes down the URL route so it is rejected as a bad URL rather than silently
6022
- * retried as a (nonexistent) directory.
6023
- */
6024
- declare function classifyPluginSource(source: string): PluginSource;
5829
+ declare function removedPluginNotice(dataDir?: string): string | undefined;
6025
5830
 
6026
- declare function resolveArgs(manifest: RunnerPluginManifest, ctx: ResolveContext): RunnerInvocation;
6027
- /**
6028
- * The manifest's meaning of a task's mode and effort, for a runner driven over
6029
- * its programmatic protocol rather than a command line built from
6030
- * `argsTemplate` (ADR-0018, C1). The effort stays a raw id behind the same
6031
- * `{{if thinking}}` gate as the template path: how an effort reaches the
6032
- * runner is protocol, which each adapter owns.
6033
- */
6034
- declare function resolveTaskRunnerFlags(manifest: RunnerPluginManifest, ctx: Pick<ResolveContext, 'mode' | 'model' | 'thinkingEffort'>): TaskRunnerFlags;
5831
+ declare function resolveTaskRunnerFlags(manifest: RunnerManifest, ctx: {
5832
+ mode: string;
5833
+ model?: string;
5834
+ thinkingEffort?: string;
5835
+ }): TaskRunnerFlags;
6035
5836
 
6036
- declare const CLAUDE_CODE_MANIFEST: RunnerPluginManifest;
5837
+ declare const CLAUDE_CODE_MANIFEST: RunnerManifest;
6037
5838
 
6038
- declare const OPENCODE_MANIFEST: RunnerPluginManifest;
5839
+ declare const OPENCODE_MANIFEST: RunnerManifest;
6039
5840
 
6040
5841
  declare const STATE_DIR = ".ordewell";
6041
5842
  declare function ensureDir(dir: string): void;
6042
5843
  declare function getStateDir(baseDir?: string): string;
6043
5844
  /**
6044
- * A match-everything ignore rule, written *inside* the state directory. A
6045
- * `.gitignore` containing `*` inside a directory excludes that directory's
6046
- * whole contents, itself included, so plans and sessions stop being
6047
- * accidentally committable — without ever touching a file the developer wrote.
6048
- * Editing their root `.gitignore` would be the intrusive version of this.
6049
- *
6050
- * Idempotent, and never overwrites an existing file: a developer who has
6051
- * customised these rules (to commit their plans deliberately, say) keeps them.
5845
+ * Ignores the state directory's contents except this file and `skills/`, so a
5846
+ * project's skills are committed and reach every task worktree through git —
5847
+ * the bootstrap never links `.ordewell/` (ADR-0013). Plans and sessions stay
5848
+ * uncommittable without touching a file the developer wrote; editing their
5849
+ * root `.gitignore` would be the intrusive version of this.
5850
+ */
5851
+ declare const STATE_DIR_IGNORE = "*\n!.gitignore\n!skills/\n!skills/**\n";
5852
+ /**
5853
+ * Idempotent, and never overwrites a file the developer customised (to commit
5854
+ * their plans deliberately, say). Only the exact legacy rule is upgraded.
6052
5855
  */
6053
5856
  declare function ensureStateDirIgnored(baseDir?: string): void;
6054
5857
 
@@ -6102,7 +5905,7 @@ declare function sanitizeSlug(raw: string): string;
6102
5905
  declare function savePrdMarkdown(workspace: string, slug: string, markdown: string): string;
6103
5906
 
6104
5907
  /** How many AI tasks may run at once: `ORDEWELL_MAX_PARALLEL`, `/parallel`, `ordewell.maxParallelSessions`. */
6105
- declare const DEFAULT_MAX_PARALLEL = 3;
5908
+ declare const DEFAULT_MAX_PARALLEL = 5;
6106
5909
  /**
6107
5910
  * A usable limit from what a user typed or a setting holds: any whole number
6108
5911
  * of at least 1 — there is no ceiling, the machine and the runners' own rate
@@ -6111,4 +5914,4 @@ declare const DEFAULT_MAX_PARALLEL = 3;
6111
5914
  */
6112
5915
  declare function parseMaxParallel(value: unknown): number | null;
6113
5916
 
6114
- export { ALLOWED_PLUGIN_HOSTS, ALL_PROVIDERS, AUTO_COMMANDS, AbstractRunner, AbstractTerminalSession, ActiveTaskSession, type AdoptSessionResponse, type Adr0013IsolationRun, type Adr0013PlanIsolation, type Adr0013TaskRecord, AgentAdapter, AgentEvent, AgentProcessDeps, AgentStartOptions, AiProvider, AlreadyExecutingError, ApplyTaskOpsResult, ApprovalAnswer, type ApprovalAnswerResponse, ApprovalDecision, ApprovalMode, ApprovalPolicy, ApprovalRequest, type ApprovalsResponse, type AskOptions, AwaitingReason, BUILTIN_SKILL_NAMES, BaseAiService, BaseConfig, BaseFileSystem, BufferedTaskOutputSource, CLAUDE_CODE_MANIFEST, CLI_PROVIDERS, CORE_PLANNER_PROMPT, type CancelPlanningResponse, type CappedRows, CheckpointAnswer, type CheckpointListener, ClaudeCodeAdapter, CliAgentAiService, type CliAgentAiServiceDeps, CodexAdapter, type CommandClassification, type CommandDescriptor, type CommandResponse, type CommandTier, 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, type DaemonErrorCode, DiscoveredModel, type EnvAdmission, EnvConfig, type ErrorBody, type ExecFileFn, type ExecImpl, type ExecuteResponse, FindSymbolOptions, type ForceSendResponse, FsPluginStore, GIT_READONLY_SUBCOMMANDS, GREP_PCRE_PROBE_ARGS, GeminiService, type GeneratePlanResponse, type GitExecFn, GlobOptions, type GrepInvocation, GrepOptions, type GrepRegex, HARNESS_PLANNER_REASON, type HasBinFn, HomeTranscriptReader, type IAiService, IApproval, IConfig, IFileSystem, type ILogger, type INotification, IPluginStore, ITerminalRunner, ITerminalSession, IWorktreeIsolation, type IsolationDiffResponse, IsolationHandoff, IsolationLandedTask, type IsolationMergeResponse, IsolationMergeResult, IsolationOutcome, IsolationRun, IsolationTaskRecord, IsolationTaskStatus, IsolationView, JSON_REPAIR_INSTRUCTION, type KillTreeDeps, 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, PLUGIN_NAME_PATTERN, 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 PlannerRuntimeToggles, type PlannerSubmission, PlannerToolHandler, PlannerTurnDiscardedError, PlannerTurnStoppedError, type PlannerUsability, PlannerUsage, type PluginSource, type PrdBlock, type PrdResponse, type PriorOutput, type ProbeFn, ProviderModelLists, type ProviderRegistration, QueuedMessage, QueuedTaskMessage, REFUSED_COMMANDS, ReadFileOpts, type RemoveMessageResponse, RepairEvidence, type RepairLoopOpts, type RepairVerdict, RepoGroupLayout, type ResearchChat, ResearchLogEntry, ResearchProgress, type ResearchShell, type ResearchShellDeps, ResearchToolType, type ResearchTurn, type ResolveConflictResponse, ResolveContext, type RewindTarget, type RewindTargetsResponse, RunnerApprovals, type RunnerCatalog, type RunnerEntry, RunnerId, RunnerInstallation, RunnerInvocation, type RunnerMode, RunnerModeInfo, RunnerPluginManifest, RunnerRegistry, RunnerSpawnOptions, RunnerTransport, type RunnersResponse, SETTINGS_ENV_ALLOWLIST, SETTINGS_ENV_REFUSED, STATE_DIR, STOPPED_TOOL_RESULT, SYMBOL_LANGUAGES, type SaveSession, Session, SessionBroadcaster, type SessionData, type SessionDeps, type SessionListResponse, SessionMessage, type SessionMeta, SessionNotFoundError, SessionNotice, type SessionPlanner, type SessionResponse, type SessionRuntimeSettings, type SettingsResponse, SettingsService, type SettingsUpdateResponse, type ShellDialect, type SkillInfo, type SkillMetadata, SkillsService, type SpawnSpec, StdioAgentAdapter, type StopResponse, StructuredEvent, StructuredRunner, type StructuredRunnerDeps, StructuredSession, StructuredSessionCapability, StructuredTurnEnd, 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 TaskOutputAttempt, type TaskOutputSource, type TaskQuery, type TaskQueryCatalog, type TaskQueryField, TaskRunnerFlags, TaskSnapshot, TaskStartOptions, TaskTokenScope, TmuxRunner, type TmuxRunnerDeps, type TokenCarriers, type ToolCall, ToolOutcome, type ToolResult, type TranscriptQuery, type TranscriptReader, type TransportRoute, TransportRouter, TreeSnapshot, UsageRecord, type UserSettings, Verdict, VerdictEngine, type VerdictListener, type WorkspaceCheckDeps, WorkspaceNotAProjectError, WorkspaceNotFoundError, type WorkspaceProjectCheckDeps, type WorkspacesResponse, type WorktreeIsolationDeps, admitSettingsEnv, applyHeadLimit, assertInstallablePluginUrl, assertPlainPluginName, assertWorkspaceExists, assertWorkspaceIsProject, augmentPromptWithPriorOutputs, augmentedPath, bearerHeaderValue, buildConflictRepairPrompt, buildConflictResolutionPrompt, buildConversationSystemPrompt, buildFallbackGrepArgs, buildGlobArgs, buildGrepArgs, buildMergePrompt, buildModifyDuringExecutionPrompt, buildModifyPlanPrompt, buildPlanWithResults, buildResearchPrompt, buildResearchToolsPrompt, buildRunnerInvocation, buildSplitPrompt, buildSubagentSystemPrompt, canContinue, clampThinkingEffort, classifyCommand, classifyPlannerReply, classifyPluginSource, clearAugmentedPathCache, clearDaemonToken, clearResearchShellCache, clearState, clipboardCopyCommand, coerceAssignments, collectDirectDependencyOutputs, composeAugmentedPrompt, composeContinuationPrompt, configuredProviders, continuability, createAiService, createSession, createSkillsService, createTaskAdapter, createWorktreeIsolation, daemonTokenPath, defaultLogger, definitionPattern, defuseMarkers, deleteSession, describeMergeResult, discoverGeminiModels, effectiveAllowlist, ensureDir, ensurePrivateDir, ensureStateDirIgnored, executionLogBlock, extractPrdBlock, extractPresentedToken, filterFallbackByAnchoredInclude, filterModelsForPrompt, formatSearchOutput, generatePlanWithRepair, getLatestSession, getProviderMeta, getSettingsPath, getStateDir, globalDataDir, grantScopeFor, grepRegexFromProbe, hasTmux, idSegment, includeGlobFor, isCliProvider, isOpenAiProvider, isPlainPluginName, isValidManifest, killTree, languageForId, listSessions, listTaskLogAttempts, loadSession, loadSessionPlanState, loadState, mapAgentTool, migrateOldConfigDir, migratePlanIsolation, mintDaemonToken, mintSessionId, modelContextBlock, modifyValidationFeedback, normalizeAgentArgs, normalizeGeminiModel, openTaskLog, parseMaxParallel, parseTaskQueryJson, pendingEditRulesBlock, plannerBackendEntries, prefixModelId, providerForRunner, reEmitPlanPrompt, reEmitTaskOpsPrompt, reEmitTaskQueryPrompt, readDaemonToken, readTaskLog, referencePattern, renderPlanMap, renderPriorOutputs, renderTaskQueryAnswer, repairLoop, researchShellWarning, researchToolsPath, resolveArgs, resolvePluginInstallDir, resolveProviderFromPrefix, resolveResearchShell, resolveSkillInvocation, resolveTaskRunnerFlags, resolveWithin, retargetTaskRunner, routeTransport, runnerAssignment, runnerForProvider, sanitizeSlug, savePrdMarkdown, saveSession, saveState, sessionDataDir, sessionRuntimeSettings, stateExists, stripModelPrefix, summarizeOutput, supportsTaskMode, taskOpsRejectedPrompt, taskQuerySignature, textHasTaskQuery, tmuxSessionName, tmuxSocketName, tmuxWindowName, tokenSubprotocols, tokensMatch, truncatedPlanReEmitPrompt, wellKnownBinDirs, withPath, writePrivateFile };
5917
+ export { ALL_PROVIDERS, AUTO_COMMANDS, AbstractRunner, AbstractRunnerSession, ActiveTaskSession, type AdoptSessionResponse, type Adr0013IsolationRun, type Adr0013PlanIsolation, type Adr0013TaskRecord, AgentAdapter, AgentEvent, AgentProcessDeps, AgentStartOptions, AiProvider, AlreadyExecutingError, ApplyTaskOpsResult, ApprovalAnswer, type ApprovalAnswerResponse, ApprovalDecision, ApprovalMode, 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 CancelPlanningResponse, type CappedRows, CheckpointAnswer, type CheckpointListener, ClaudeCodeAdapter, CliAgentAiService, type CliAgentAiServiceDeps, CodexAdapter, type CommandClassification, type CommandDescriptor, CommandLineTooLongError, type CommandTier, 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, type DaemonErrorCode, DiscoveredModel, EmbeddedNewlineError, type EnvAdmission, EnvConfig, type ErrorBody, type ExecImpl, ExecutableNotFoundError, type ExecuteResponse, FindSymbolOptions, type ForceSendResponse, GIT_READONLY_SUBCOMMANDS, GREP_PCRE_PROBE_ARGS, GeminiService, type GeneratePlanResponse, type GitExecFn, GlobOptions, type GrepInvocation, GrepOptions, type GrepRegex, HARNESS_PLANNER_REASON, type HasBinFn, type IAiService, IApproval, IConfig, IFileSystem, type ILogger, type INotification, IRunner, IRunnerSession, 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, REFUSED_COMMANDS, ReadFileOpts, type RemoveMessageResponse, RepairEvidence, type RepairLoopOpts, type RepairVerdict, RepoGroupLayout, type ResearchChat, ResearchLogEntry, ResearchProgress, type ResearchShell, type ResearchShellDeps, 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, Session, SessionBroadcaster, type SessionData, type SessionDeps, type SessionListResponse, SessionMessage, type SessionMeta, SessionNotFoundError, SessionNotice, type SessionPlanner, type SessionResponse, type SessionRuntimeSettings, type SettingsResponse, SettingsService, type SettingsUpdateResponse, type ShellDialect, 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 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, classifyCommand, classifyPlannerReply, clearAugmentedPathCache, clearDaemonToken, clearResearchShellCache, 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, mapAgentTool, migrateOldConfigDir, migratePlanIsolation, mintDaemonToken, mintSessionId, modelContextBlock, modifyValidationFeedback, normalizeAgentArgs, normalizeGeminiModel, openTaskLog, parseMaxParallel, parseTaskQueryJson, pendingEditRulesBlock, planDirectLaunch, plannerBackendEntries, plannerMessage, plannerTranscript, prefixModelId, providerForRunner, reEmitPlanPrompt, reEmitTaskOpsPrompt, reEmitTaskQueryPrompt, readDaemonToken, readTaskLog, referencePattern, removedPluginNotice, renderPlanMap, renderPriorOutputs, renderTaskQueryAnswer, repairLoop, researchShellWarning, researchToolsPath, resolveProviderFromPrefix, resolveResearchShell, resolveSkillInvocation, resolveTaskRunnerFlags, resolveWithin, resubmitEditPrompt, resubmitPlanPrompt, retargetTaskRunner, runnerAssignment, runnerForProvider, sanitizeSlug, savePrdMarkdown, saveSession, saveState, sessionDataDir, sessionRuntimeSettings, stateExists, stripAnsi, stripModelPrefix, summarizeOutput, supportsTaskMode, taskOpsRejectedPrompt, taskQuerySignature, textHasTaskQuery, tokenSubprotocols, tokensMatch, truncatedPlanReEmitPrompt, wellKnownBinDirs, windowsCommandLine, withPath, writePrivateFile };