@ordewell/core 0.6.0 → 0.6.2

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 (46) hide show
  1. package/dist/{IFileSystem-D4dAl2r8.d.ts → IFileSystem-DuEiG_kA.d.ts} +1 -1
  2. package/dist/{IFileSystem-CFYf4yR2.d.mts → IFileSystem-d_SV7jAH.d.mts} +1 -1
  3. package/dist/{ModeResolver-a4xJFlEp.d.mts → ModeResolver-DIReYAOq.d.mts} +1 -1
  4. package/dist/{ModeResolver-DVYVRbJp.d.ts → ModeResolver-DXxV4n_V.d.ts} +1 -1
  5. package/dist/{Task-CZJr6rmz.d.mts → Task-ib_U0YP7.d.mts} +56 -5
  6. package/dist/{Task-CZJr6rmz.d.ts → Task-ib_U0YP7.d.ts} +56 -5
  7. package/dist/{chunk-2SOVKO7P.mjs → chunk-I6U3PVHL.mjs} +39 -16
  8. package/dist/chunk-I6U3PVHL.mjs.map +1 -0
  9. package/dist/{chunk-EDGUFCIR.mjs → chunk-JRZPSNRO.mjs} +7 -3
  10. package/dist/chunk-JRZPSNRO.mjs.map +1 -0
  11. package/dist/{chunk-OM4D274O.mjs → chunk-M4KXBEFJ.mjs} +5 -3
  12. package/dist/chunk-M4KXBEFJ.mjs.map +1 -0
  13. package/dist/{chunk-C44UWIAD.mjs → chunk-N66ZHFGN.mjs} +2 -2
  14. package/dist/chunk-N66ZHFGN.mjs.map +1 -0
  15. package/dist/index.d.mts +181 -48
  16. package/dist/index.d.ts +181 -48
  17. package/dist/index.js +1207 -127
  18. package/dist/index.js.map +1 -1
  19. package/dist/index.mjs +1153 -105
  20. package/dist/index.mjs.map +1 -1
  21. package/dist/order-labels.d.mts +1 -1
  22. package/dist/order-labels.d.ts +1 -1
  23. package/dist/{parsing-Bd6-b644.d.ts → parsing-C8Z22twN.d.ts} +2 -2
  24. package/dist/{parsing-DIaGZmiQ.d.mts → parsing-DjRJJX-y.d.mts} +2 -2
  25. package/dist/parsing.d.mts +3 -3
  26. package/dist/parsing.d.ts +3 -3
  27. package/dist/parsing.js +5 -2
  28. package/dist/parsing.js.map +1 -1
  29. package/dist/parsing.mjs +2 -2
  30. package/dist/{plan-utils-_T5S7Mnk.d.ts → plan-utils-2K_N5ZJe.d.ts} +30 -4
  31. package/dist/{plan-utils-Ba-l8EZS.d.mts → plan-utils-D94CJ7CA.d.mts} +30 -4
  32. package/dist/plan-utils.d.mts +3 -3
  33. package/dist/plan-utils.d.ts +3 -3
  34. package/dist/plan-utils.js.map +1 -1
  35. package/dist/plan-utils.mjs +2 -2
  36. package/dist/testing.d.mts +14 -5
  37. package/dist/testing.d.ts +14 -5
  38. package/dist/testing.js +30 -3
  39. package/dist/testing.js.map +1 -1
  40. package/dist/testing.mjs +30 -3
  41. package/dist/testing.mjs.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/chunk-2SOVKO7P.mjs.map +0 -1
  44. package/dist/chunk-C44UWIAD.mjs.map +0 -1
  45. package/dist/chunk-EDGUFCIR.mjs.map +0 -1
  46. package/dist/chunk-OM4D274O.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { I as IApproval } from './Task-CZJr6rmz.js';
1
+ import { I as IApproval } from './Task-ib_U0YP7.js';
2
2
 
3
3
  interface ToolOutcome {
4
4
  success: boolean;
@@ -1,4 +1,4 @@
1
- import { I as IApproval } from './Task-CZJr6rmz.mjs';
1
+ import { I as IApproval } from './Task-ib_U0YP7.mjs';
2
2
 
3
3
  interface ToolOutcome {
4
4
  success: boolean;
@@ -1,4 +1,4 @@
1
- import { aG as RunnerId } from './Task-CZJr6rmz.mjs';
1
+ import { aG as RunnerId } from './Task-ib_U0YP7.mjs';
2
2
 
3
3
  interface RunnerModeInfo {
4
4
  id: string;
@@ -1,4 +1,4 @@
1
- import { aG as RunnerId } from './Task-CZJr6rmz.js';
1
+ import { aG as RunnerId } from './Task-ib_U0YP7.js';
2
2
 
3
3
  interface RunnerModeInfo {
4
4
  id: string;
@@ -60,6 +60,11 @@ interface IsolationTaskRepo {
60
60
  linked: string[];
61
61
  /** Whether the task brought commits to this repo; unknown until it first integrates. */
62
62
  changed?: boolean;
63
+ /**
64
+ * The integration tip right after the task landed here: what the user's
65
+ * HEAD must contain for the task's work to count as merged (ADR-0020).
66
+ */
67
+ landedTip?: string;
63
68
  }
64
69
  interface IsolationTaskRecord {
65
70
  taskId: string;
@@ -103,6 +108,12 @@ interface IsolationTaskRecord {
103
108
  * names it in a group of one, prefixed with its repo's path in a group.
104
109
  */
105
110
  repairedFiles?: string[];
111
+ /**
112
+ * Set once the task's landed work is in the checked-out HEAD of every repo
113
+ * it changed — merged into the user's branch, by Merge all or by hand. What
114
+ * a merge gate waits for (ADR-0020).
115
+ */
116
+ inHead?: true;
106
117
  }
107
118
  /**
108
119
  * A task's landing in flight: each changed repo's integration tip from before
@@ -302,6 +313,12 @@ interface IsolationPruneResult {
302
313
  title: string;
303
314
  }>;
304
315
  }
316
+ /**
317
+ * The tracked changes of a workspace's repos at one moment, against each
318
+ * repo's HEAD: repo path → file path → the content it held then. What an ops
319
+ * task's tree check compares against (ADR-0020).
320
+ */
321
+ type TreeSnapshot = Record<string, Record<string, string>>;
305
322
  interface IWorktreeIsolation {
306
323
  /**
307
324
  * A repo group with at least one repo to isolate, a clean tracked tree in
@@ -385,6 +402,24 @@ interface IWorktreeIsolation {
385
402
  pruneOrphans(run: IsolationRun): Promise<IsolationPruneResult>;
386
403
  /** Unified diff of each repo's integration branch against its base ref. */
387
404
  reviewDiff(run: IsolationRun): Promise<string>;
405
+ /**
406
+ * Mark the landed tasks whose work the checked-out HEAD now contains in
407
+ * every repo they changed (`git merge-base --is-ancestor`), and return their
408
+ * ids. Only adds marks: a task found merged stays merged.
409
+ */
410
+ findInHead(run: IsolationRun): Promise<string[]>;
411
+ /**
412
+ * The tracked changes of each committed repo of the workspace's group,
413
+ * except those in `exclude`; null when there is no repo to snapshot.
414
+ * Untracked and ignored files never count.
415
+ */
416
+ snapshotTree(workspaceRoot: string, exclude: readonly string[]): Promise<TreeSnapshot | null>;
417
+ /**
418
+ * Tracked files whose content differs from what `snapshot` recorded: new
419
+ * changes, and further changes to files already changed then. Paths are
420
+ * from the workspace root. A repo git cannot read now is left out.
421
+ */
422
+ changedSince(workspaceRoot: string, snapshot: TreeSnapshot): Promise<string[]>;
388
423
  /**
389
424
  * "Merge all": merge each repo's integration branch into whatever the user
390
425
  * has checked out there. The one irreversible step, so it only ever happens
@@ -392,7 +427,9 @@ interface IWorktreeIsolation {
392
427
  * merge of the user's in progress, no conflict against their HEAD, no
393
428
  * uncommitted edit to a file the merge changes — and unless all pass,
394
429
  * nothing is merged anywhere. Only a merge Ordewell itself just started is
395
- * ever aborted; nothing of the user's is reset.
430
+ * ever aborted; nothing of the user's is reset. Waits for a landing in
431
+ * flight and holds the next back, so a merge during a run takes the
432
+ * integration branches between two landings, never part of one.
396
433
  */
397
434
  mergeIntoCheckedOut(run: IsolationRun): Promise<IsolationMergeResult>;
398
435
  /**
@@ -1796,10 +1833,11 @@ type TaskStatus = 'pending' | 'approved' | 'in_progress' | 'completed' | 'failed
1796
1833
  type TaskMode = string;
1797
1834
  /**
1798
1835
  * Why an `awaiting_user` task waits (ADR-0018, W1): a structured turn that
1799
- * ended without the done marker, a checkpoint question, or work that did not
1800
- * land. Saved, so no surface has to guess it from whether an attempt is live.
1836
+ * ended without the done marker, a checkpoint question, work that did not
1837
+ * land, or an ops task that changed tracked files (ADR-0020). Saved, so no
1838
+ * surface has to guess it from whether an attempt is live.
1801
1839
  */
1802
- type AwaitingReason = 'input' | 'checkpoint' | 'conflict';
1840
+ type AwaitingReason = 'input' | 'checkpoint' | 'conflict' | 'files-changed';
1803
1841
  declare function isAwaitingReason(value: unknown): value is AwaitingReason;
1804
1842
  interface TaskModelAssignment {
1805
1843
  modelId: string;
@@ -1850,6 +1888,19 @@ interface Task {
1850
1888
  transport?: TaskTransport;
1851
1889
  /** Set only while `status` is `awaiting_user`, and not always then — a usage-limit pause has none. */
1852
1890
  awaitingReason?: AwaitingReason;
1891
+ /**
1892
+ * An ops task (ADR-0020): it changes no repository files, runs at the
1893
+ * workspace root rather than in a worktree, and waits for the change tasks
1894
+ * it depends on to be merged into the user's branch. Top-level AI tasks
1895
+ * only; absent means a change task.
1896
+ */
1897
+ ops?: boolean;
1898
+ /**
1899
+ * The dependencies, by title, whose work was not merged into the user's
1900
+ * branch when the user force-started this task past its merge gate
1901
+ * (ADR-0020). Cleared when the task is retried.
1902
+ */
1903
+ forcedPastGate?: string[];
1853
1904
  }
1854
1905
  interface DiscoveredMode {
1855
1906
  id: string;
@@ -2118,4 +2169,4 @@ interface ValidationContext {
2118
2169
  type ValidationCheck = (ctx: ValidationContext) => ValidationResult;
2119
2170
  declare function warningsText(w: PlanModificationWarnings): string | null;
2120
2171
 
2121
- export { type IsolationRun as $, AbstractRunner as A, type BlockingPrompt as B, CMD_EXE_MAX_COMMAND_LINE as C, DENY_ALL as D, EmbeddedNewlineError as E, type FetchAllProviderModelsOptions as F, HeadlessSession as G, HeadlessRunner as H, type IApproval as I, type IConfig as J, type IPluginStore as K, type ITerminalRunner as L, type ITerminalSession as M, type IWorktreeIsolation as N, type IntegrationDisposal as O, type IsolationAvailability as P, type IsolationHandoff as Q, type IsolationHandoffRepo as R, type IsolationInactiveReason as S, type IsolationLandedTask as T, type IsolationLanding as U, type IsolationMergeBlock as V, type IsolationMergeBlockReason as W, type IsolationMergeResult as X, type IsolationOutcome as Y, type IsolationPruneResult as Z, type IsolationRepo as _, AbstractTerminalSession as a, type TaskOutputSummary as a$, type IsolationTaskRecord as a0, type IsolationTaskRepo as a1, type IsolationTaskStatus as a2, type IsolationView as a3, type LaunchDeps as a4, type LaunchPlan as a5, type LegacyPlanState as a6, LineBuffer as a7, type Message as a8, ModelCatalog as a9, type ResearchLogEntry as aA, type ResearchProgress as aB, type ResearchStep as aC, type ResearchStepOutcome as aD, type ResearchToolType as aE, type ResolveContext as aF, type RunnerId as aG, type RunnerInvocation as aH, type RunnerPluginManifest as aI, RunnerRegistry as aJ, type RunnerSpawnOptions as aK, type RunnerTransport as aL, type StreamEvent as aM, type StreamStepEvent as aN, type StreamThinkingEvent as aO, type StructuredEvent as aP, type StructuredSessionCapability as aQ, type StructuredTurnEnd as aR, type SubagentLogEntry as aS, type SubagentOutcome as aT, type Task as aU, type TaskIsolation as aV, type TaskIsolationState as aW, type TaskMode as aX, type TaskModeAgentAdapter as aY, TaskModeUnsupportedError as aZ, type TaskModelAssignment as a_, type ModelShortcut as aa, ORCHESTRATOR_SHORTCUTS as ab, type OrchestratorOption as ac, type PlanIsolation as ad, type PlanModificationWarnings as ae, type PlanState as af, type PlanStatus as ag, type PlannerStartOptions as ah, type PlannerUsage as ai, type PluginCloneFn as aj, type PluginEntry as ak, type PluginFeatures as al, type PluginMode as am, type PluginModelDiscovery as an, type PluginRunnerDef as ao, type PreparedLaunch as ap, type PreparedTask as aq, type ProviderCredentialSource as ar, type ProviderModelLists as as, type ProviderModelsResult as at, type PtySize as au, type PtyWrapOptions as av, type QueuedMessage as aw, type QueuedTaskMessage as ax, type RepairEvidence as ay, type RepoGroupLayout as az, type ActiveTaskSession as b, type TaskRunnerFlags as b0, type TaskSnapshot as b1, type TaskStartOptions as b2, type TaskStatus as b3, type TaskTransport as b4, type TaskType as b5, type TaskWithParent as b6, type ThinkingBlock as b7, type UsageLine as b8, type UsageRecord as b9, isReservedRunnerName as bA, isRunnerApproval as bB, isRunnerTransport as bC, isStructuredSession as bD, keepExecutionState as bE, knownModelId as bF, migrateLegacyPlan as bG, migratePlanState as bH, migrateTask as bI, partedPromptUsage as bJ, planDirectLaunch as bK, planShellLaunch as bL, plannerContextFill as bM, posixShellQuote as bN, removeTaskFromPlan as bO, renumberTasks as bP, resolveModelShortcut as bQ, resolveProvider as bR, stripAnsi as bS, toApprovalDecision as bT, toOrchestratorOptions as bU, updateTaskInPlan as bV, usageLine as bW, validateModifiedPlan as bX, warningsText as bY, windowsCommandLine as bZ, wrapWithPty as b_, type UsageTotals as ba, type UserPromptEntry as bb, type UserStep as bc, type ValidationCheck as bd, type ValidationContext as be, type ValidationResult as bf, type Verdict as bg, type VerificationCheck as bh, WINDOWS_MAX_COMMAND_LINE as bi, addPlannerUsage as bj, addTaskToPlan as bk, addUsage as bl, approvalScopes as bm, buildShellInvocation as bn, collectProviderCredentials as bo, createEmptyPlan as bp, createTask as bq, emptyWarnings as br, enabledRunners as bs, fetchAllProviderModels as bt, flattenTasks as bu, flattenTasksWithParents as bv, isAwaitingReason as bw, isExecutableResolved as bx, isGranted as by, isMeasured as bz, type AgentAdapter as c, type AgentAdapterFactory as d, type AgentEvent as e, type AgentProcessDeps as f, type AgentStartOptions as g, type AiProvider as h, type AllProviderModels as i, type ApprovalAnswer as j, type ApprovalDecision as k, type ApprovalKind as l, type ApprovalMode as m, ApprovalPolicy as n, type ApprovalPolicyOptions as o, type ApprovalRequest as p, type ApprovalSource as q, type AwaitingReason as r, type CatalogModel as s, CommandLineTooLongError as t, type ConversationMessage as u, type DiscoveredMode as v, type DiscoveredModel as w, type DiscoveryCommand as x, ExecutableNotFoundError as y, type HeadlessRunnerDeps as z };
2172
+ export { type IsolationRun as $, AbstractRunner as A, type BlockingPrompt as B, CMD_EXE_MAX_COMMAND_LINE as C, DENY_ALL as D, EmbeddedNewlineError as E, type FetchAllProviderModelsOptions as F, HeadlessSession as G, HeadlessRunner as H, type IApproval as I, type IConfig as J, type IPluginStore as K, type ITerminalRunner as L, type ITerminalSession as M, type IWorktreeIsolation as N, type IntegrationDisposal as O, type IsolationAvailability as P, type IsolationHandoff as Q, type IsolationHandoffRepo as R, type IsolationInactiveReason as S, type IsolationLandedTask as T, type IsolationLanding as U, type IsolationMergeBlock as V, type IsolationMergeBlockReason as W, type IsolationMergeResult as X, type IsolationOutcome as Y, type IsolationPruneResult as Z, type IsolationRepo as _, AbstractTerminalSession as a, type TaskOutputSummary as a$, type IsolationTaskRecord as a0, type IsolationTaskRepo as a1, type IsolationTaskStatus as a2, type IsolationView as a3, type LaunchDeps as a4, type LaunchPlan as a5, type LegacyPlanState as a6, LineBuffer as a7, type Message as a8, ModelCatalog as a9, type ResearchLogEntry as aA, type ResearchProgress as aB, type ResearchStep as aC, type ResearchStepOutcome as aD, type ResearchToolType as aE, type ResolveContext as aF, type RunnerId as aG, type RunnerInvocation as aH, type RunnerPluginManifest as aI, RunnerRegistry as aJ, type RunnerSpawnOptions as aK, type RunnerTransport as aL, type StreamEvent as aM, type StreamStepEvent as aN, type StreamThinkingEvent as aO, type StructuredEvent as aP, type StructuredSessionCapability as aQ, type StructuredTurnEnd as aR, type SubagentLogEntry as aS, type SubagentOutcome as aT, type Task as aU, type TaskIsolation as aV, type TaskIsolationState as aW, type TaskMode as aX, type TaskModeAgentAdapter as aY, TaskModeUnsupportedError as aZ, type TaskModelAssignment as a_, type ModelShortcut as aa, ORCHESTRATOR_SHORTCUTS as ab, type OrchestratorOption as ac, type PlanIsolation as ad, type PlanModificationWarnings as ae, type PlanState as af, type PlanStatus as ag, type PlannerStartOptions as ah, type PlannerUsage as ai, type PluginCloneFn as aj, type PluginEntry as ak, type PluginFeatures as al, type PluginMode as am, type PluginModelDiscovery as an, type PluginRunnerDef as ao, type PreparedLaunch as ap, type PreparedTask as aq, type ProviderCredentialSource as ar, type ProviderModelLists as as, type ProviderModelsResult as at, type PtySize as au, type PtyWrapOptions as av, type QueuedMessage as aw, type QueuedTaskMessage as ax, type RepairEvidence as ay, type RepoGroupLayout as az, type ActiveTaskSession as b, wrapWithPty as b$, type TaskRunnerFlags as b0, type TaskSnapshot as b1, type TaskStartOptions as b2, type TaskStatus as b3, type TaskTransport as b4, type TaskType as b5, type TaskWithParent as b6, type ThinkingBlock as b7, type TreeSnapshot as b8, type UsageLine as b9, isMeasured as bA, isReservedRunnerName as bB, isRunnerApproval as bC, isRunnerTransport as bD, isStructuredSession as bE, keepExecutionState as bF, knownModelId as bG, migrateLegacyPlan as bH, migratePlanState as bI, migrateTask as bJ, partedPromptUsage as bK, planDirectLaunch as bL, planShellLaunch as bM, plannerContextFill as bN, posixShellQuote as bO, removeTaskFromPlan as bP, renumberTasks as bQ, resolveModelShortcut as bR, resolveProvider as bS, stripAnsi as bT, toApprovalDecision as bU, toOrchestratorOptions as bV, updateTaskInPlan as bW, usageLine as bX, validateModifiedPlan as bY, warningsText as bZ, windowsCommandLine as b_, type UsageRecord as ba, type UsageTotals as bb, type UserPromptEntry as bc, type UserStep as bd, type ValidationCheck as be, type ValidationContext as bf, type ValidationResult as bg, type Verdict as bh, type VerificationCheck as bi, WINDOWS_MAX_COMMAND_LINE as bj, addPlannerUsage as bk, addTaskToPlan as bl, addUsage as bm, approvalScopes as bn, buildShellInvocation as bo, collectProviderCredentials as bp, createEmptyPlan as bq, createTask as br, emptyWarnings as bs, enabledRunners as bt, fetchAllProviderModels as bu, flattenTasks as bv, flattenTasksWithParents as bw, isAwaitingReason as bx, isExecutableResolved as by, isGranted as bz, type AgentAdapter as c, type AgentAdapterFactory as d, type AgentEvent as e, type AgentProcessDeps as f, type AgentStartOptions as g, type AiProvider as h, type AllProviderModels as i, type ApprovalAnswer as j, type ApprovalDecision as k, type ApprovalKind as l, type ApprovalMode as m, ApprovalPolicy as n, type ApprovalPolicyOptions as o, type ApprovalRequest as p, type ApprovalSource as q, type AwaitingReason as r, type CatalogModel as s, CommandLineTooLongError as t, type ConversationMessage as u, type DiscoveredMode as v, type DiscoveredModel as w, type DiscoveryCommand as x, ExecutableNotFoundError as y, type HeadlessRunnerDeps as z };
@@ -60,6 +60,11 @@ interface IsolationTaskRepo {
60
60
  linked: string[];
61
61
  /** Whether the task brought commits to this repo; unknown until it first integrates. */
62
62
  changed?: boolean;
63
+ /**
64
+ * The integration tip right after the task landed here: what the user's
65
+ * HEAD must contain for the task's work to count as merged (ADR-0020).
66
+ */
67
+ landedTip?: string;
63
68
  }
64
69
  interface IsolationTaskRecord {
65
70
  taskId: string;
@@ -103,6 +108,12 @@ interface IsolationTaskRecord {
103
108
  * names it in a group of one, prefixed with its repo's path in a group.
104
109
  */
105
110
  repairedFiles?: string[];
111
+ /**
112
+ * Set once the task's landed work is in the checked-out HEAD of every repo
113
+ * it changed — merged into the user's branch, by Merge all or by hand. What
114
+ * a merge gate waits for (ADR-0020).
115
+ */
116
+ inHead?: true;
106
117
  }
107
118
  /**
108
119
  * A task's landing in flight: each changed repo's integration tip from before
@@ -302,6 +313,12 @@ interface IsolationPruneResult {
302
313
  title: string;
303
314
  }>;
304
315
  }
316
+ /**
317
+ * The tracked changes of a workspace's repos at one moment, against each
318
+ * repo's HEAD: repo path → file path → the content it held then. What an ops
319
+ * task's tree check compares against (ADR-0020).
320
+ */
321
+ type TreeSnapshot = Record<string, Record<string, string>>;
305
322
  interface IWorktreeIsolation {
306
323
  /**
307
324
  * A repo group with at least one repo to isolate, a clean tracked tree in
@@ -385,6 +402,24 @@ interface IWorktreeIsolation {
385
402
  pruneOrphans(run: IsolationRun): Promise<IsolationPruneResult>;
386
403
  /** Unified diff of each repo's integration branch against its base ref. */
387
404
  reviewDiff(run: IsolationRun): Promise<string>;
405
+ /**
406
+ * Mark the landed tasks whose work the checked-out HEAD now contains in
407
+ * every repo they changed (`git merge-base --is-ancestor`), and return their
408
+ * ids. Only adds marks: a task found merged stays merged.
409
+ */
410
+ findInHead(run: IsolationRun): Promise<string[]>;
411
+ /**
412
+ * The tracked changes of each committed repo of the workspace's group,
413
+ * except those in `exclude`; null when there is no repo to snapshot.
414
+ * Untracked and ignored files never count.
415
+ */
416
+ snapshotTree(workspaceRoot: string, exclude: readonly string[]): Promise<TreeSnapshot | null>;
417
+ /**
418
+ * Tracked files whose content differs from what `snapshot` recorded: new
419
+ * changes, and further changes to files already changed then. Paths are
420
+ * from the workspace root. A repo git cannot read now is left out.
421
+ */
422
+ changedSince(workspaceRoot: string, snapshot: TreeSnapshot): Promise<string[]>;
388
423
  /**
389
424
  * "Merge all": merge each repo's integration branch into whatever the user
390
425
  * has checked out there. The one irreversible step, so it only ever happens
@@ -392,7 +427,9 @@ interface IWorktreeIsolation {
392
427
  * merge of the user's in progress, no conflict against their HEAD, no
393
428
  * uncommitted edit to a file the merge changes — and unless all pass,
394
429
  * nothing is merged anywhere. Only a merge Ordewell itself just started is
395
- * ever aborted; nothing of the user's is reset.
430
+ * ever aborted; nothing of the user's is reset. Waits for a landing in
431
+ * flight and holds the next back, so a merge during a run takes the
432
+ * integration branches between two landings, never part of one.
396
433
  */
397
434
  mergeIntoCheckedOut(run: IsolationRun): Promise<IsolationMergeResult>;
398
435
  /**
@@ -1796,10 +1833,11 @@ type TaskStatus = 'pending' | 'approved' | 'in_progress' | 'completed' | 'failed
1796
1833
  type TaskMode = string;
1797
1834
  /**
1798
1835
  * Why an `awaiting_user` task waits (ADR-0018, W1): a structured turn that
1799
- * ended without the done marker, a checkpoint question, or work that did not
1800
- * land. Saved, so no surface has to guess it from whether an attempt is live.
1836
+ * ended without the done marker, a checkpoint question, work that did not
1837
+ * land, or an ops task that changed tracked files (ADR-0020). Saved, so no
1838
+ * surface has to guess it from whether an attempt is live.
1801
1839
  */
1802
- type AwaitingReason = 'input' | 'checkpoint' | 'conflict';
1840
+ type AwaitingReason = 'input' | 'checkpoint' | 'conflict' | 'files-changed';
1803
1841
  declare function isAwaitingReason(value: unknown): value is AwaitingReason;
1804
1842
  interface TaskModelAssignment {
1805
1843
  modelId: string;
@@ -1850,6 +1888,19 @@ interface Task {
1850
1888
  transport?: TaskTransport;
1851
1889
  /** Set only while `status` is `awaiting_user`, and not always then — a usage-limit pause has none. */
1852
1890
  awaitingReason?: AwaitingReason;
1891
+ /**
1892
+ * An ops task (ADR-0020): it changes no repository files, runs at the
1893
+ * workspace root rather than in a worktree, and waits for the change tasks
1894
+ * it depends on to be merged into the user's branch. Top-level AI tasks
1895
+ * only; absent means a change task.
1896
+ */
1897
+ ops?: boolean;
1898
+ /**
1899
+ * The dependencies, by title, whose work was not merged into the user's
1900
+ * branch when the user force-started this task past its merge gate
1901
+ * (ADR-0020). Cleared when the task is retried.
1902
+ */
1903
+ forcedPastGate?: string[];
1853
1904
  }
1854
1905
  interface DiscoveredMode {
1855
1906
  id: string;
@@ -2118,4 +2169,4 @@ interface ValidationContext {
2118
2169
  type ValidationCheck = (ctx: ValidationContext) => ValidationResult;
2119
2170
  declare function warningsText(w: PlanModificationWarnings): string | null;
2120
2171
 
2121
- export { type IsolationRun as $, AbstractRunner as A, type BlockingPrompt as B, CMD_EXE_MAX_COMMAND_LINE as C, DENY_ALL as D, EmbeddedNewlineError as E, type FetchAllProviderModelsOptions as F, HeadlessSession as G, HeadlessRunner as H, type IApproval as I, type IConfig as J, type IPluginStore as K, type ITerminalRunner as L, type ITerminalSession as M, type IWorktreeIsolation as N, type IntegrationDisposal as O, type IsolationAvailability as P, type IsolationHandoff as Q, type IsolationHandoffRepo as R, type IsolationInactiveReason as S, type IsolationLandedTask as T, type IsolationLanding as U, type IsolationMergeBlock as V, type IsolationMergeBlockReason as W, type IsolationMergeResult as X, type IsolationOutcome as Y, type IsolationPruneResult as Z, type IsolationRepo as _, AbstractTerminalSession as a, type TaskOutputSummary as a$, type IsolationTaskRecord as a0, type IsolationTaskRepo as a1, type IsolationTaskStatus as a2, type IsolationView as a3, type LaunchDeps as a4, type LaunchPlan as a5, type LegacyPlanState as a6, LineBuffer as a7, type Message as a8, ModelCatalog as a9, type ResearchLogEntry as aA, type ResearchProgress as aB, type ResearchStep as aC, type ResearchStepOutcome as aD, type ResearchToolType as aE, type ResolveContext as aF, type RunnerId as aG, type RunnerInvocation as aH, type RunnerPluginManifest as aI, RunnerRegistry as aJ, type RunnerSpawnOptions as aK, type RunnerTransport as aL, type StreamEvent as aM, type StreamStepEvent as aN, type StreamThinkingEvent as aO, type StructuredEvent as aP, type StructuredSessionCapability as aQ, type StructuredTurnEnd as aR, type SubagentLogEntry as aS, type SubagentOutcome as aT, type Task as aU, type TaskIsolation as aV, type TaskIsolationState as aW, type TaskMode as aX, type TaskModeAgentAdapter as aY, TaskModeUnsupportedError as aZ, type TaskModelAssignment as a_, type ModelShortcut as aa, ORCHESTRATOR_SHORTCUTS as ab, type OrchestratorOption as ac, type PlanIsolation as ad, type PlanModificationWarnings as ae, type PlanState as af, type PlanStatus as ag, type PlannerStartOptions as ah, type PlannerUsage as ai, type PluginCloneFn as aj, type PluginEntry as ak, type PluginFeatures as al, type PluginMode as am, type PluginModelDiscovery as an, type PluginRunnerDef as ao, type PreparedLaunch as ap, type PreparedTask as aq, type ProviderCredentialSource as ar, type ProviderModelLists as as, type ProviderModelsResult as at, type PtySize as au, type PtyWrapOptions as av, type QueuedMessage as aw, type QueuedTaskMessage as ax, type RepairEvidence as ay, type RepoGroupLayout as az, type ActiveTaskSession as b, type TaskRunnerFlags as b0, type TaskSnapshot as b1, type TaskStartOptions as b2, type TaskStatus as b3, type TaskTransport as b4, type TaskType as b5, type TaskWithParent as b6, type ThinkingBlock as b7, type UsageLine as b8, type UsageRecord as b9, isReservedRunnerName as bA, isRunnerApproval as bB, isRunnerTransport as bC, isStructuredSession as bD, keepExecutionState as bE, knownModelId as bF, migrateLegacyPlan as bG, migratePlanState as bH, migrateTask as bI, partedPromptUsage as bJ, planDirectLaunch as bK, planShellLaunch as bL, plannerContextFill as bM, posixShellQuote as bN, removeTaskFromPlan as bO, renumberTasks as bP, resolveModelShortcut as bQ, resolveProvider as bR, stripAnsi as bS, toApprovalDecision as bT, toOrchestratorOptions as bU, updateTaskInPlan as bV, usageLine as bW, validateModifiedPlan as bX, warningsText as bY, windowsCommandLine as bZ, wrapWithPty as b_, type UsageTotals as ba, type UserPromptEntry as bb, type UserStep as bc, type ValidationCheck as bd, type ValidationContext as be, type ValidationResult as bf, type Verdict as bg, type VerificationCheck as bh, WINDOWS_MAX_COMMAND_LINE as bi, addPlannerUsage as bj, addTaskToPlan as bk, addUsage as bl, approvalScopes as bm, buildShellInvocation as bn, collectProviderCredentials as bo, createEmptyPlan as bp, createTask as bq, emptyWarnings as br, enabledRunners as bs, fetchAllProviderModels as bt, flattenTasks as bu, flattenTasksWithParents as bv, isAwaitingReason as bw, isExecutableResolved as bx, isGranted as by, isMeasured as bz, type AgentAdapter as c, type AgentAdapterFactory as d, type AgentEvent as e, type AgentProcessDeps as f, type AgentStartOptions as g, type AiProvider as h, type AllProviderModels as i, type ApprovalAnswer as j, type ApprovalDecision as k, type ApprovalKind as l, type ApprovalMode as m, ApprovalPolicy as n, type ApprovalPolicyOptions as o, type ApprovalRequest as p, type ApprovalSource as q, type AwaitingReason as r, type CatalogModel as s, CommandLineTooLongError as t, type ConversationMessage as u, type DiscoveredMode as v, type DiscoveredModel as w, type DiscoveryCommand as x, ExecutableNotFoundError as y, type HeadlessRunnerDeps as z };
2172
+ export { type IsolationRun as $, AbstractRunner as A, type BlockingPrompt as B, CMD_EXE_MAX_COMMAND_LINE as C, DENY_ALL as D, EmbeddedNewlineError as E, type FetchAllProviderModelsOptions as F, HeadlessSession as G, HeadlessRunner as H, type IApproval as I, type IConfig as J, type IPluginStore as K, type ITerminalRunner as L, type ITerminalSession as M, type IWorktreeIsolation as N, type IntegrationDisposal as O, type IsolationAvailability as P, type IsolationHandoff as Q, type IsolationHandoffRepo as R, type IsolationInactiveReason as S, type IsolationLandedTask as T, type IsolationLanding as U, type IsolationMergeBlock as V, type IsolationMergeBlockReason as W, type IsolationMergeResult as X, type IsolationOutcome as Y, type IsolationPruneResult as Z, type IsolationRepo as _, AbstractTerminalSession as a, type TaskOutputSummary as a$, type IsolationTaskRecord as a0, type IsolationTaskRepo as a1, type IsolationTaskStatus as a2, type IsolationView as a3, type LaunchDeps as a4, type LaunchPlan as a5, type LegacyPlanState as a6, LineBuffer as a7, type Message as a8, ModelCatalog as a9, type ResearchLogEntry as aA, type ResearchProgress as aB, type ResearchStep as aC, type ResearchStepOutcome as aD, type ResearchToolType as aE, type ResolveContext as aF, type RunnerId as aG, type RunnerInvocation as aH, type RunnerPluginManifest as aI, RunnerRegistry as aJ, type RunnerSpawnOptions as aK, type RunnerTransport as aL, type StreamEvent as aM, type StreamStepEvent as aN, type StreamThinkingEvent as aO, type StructuredEvent as aP, type StructuredSessionCapability as aQ, type StructuredTurnEnd as aR, type SubagentLogEntry as aS, type SubagentOutcome as aT, type Task as aU, type TaskIsolation as aV, type TaskIsolationState as aW, type TaskMode as aX, type TaskModeAgentAdapter as aY, TaskModeUnsupportedError as aZ, type TaskModelAssignment as a_, type ModelShortcut as aa, ORCHESTRATOR_SHORTCUTS as ab, type OrchestratorOption as ac, type PlanIsolation as ad, type PlanModificationWarnings as ae, type PlanState as af, type PlanStatus as ag, type PlannerStartOptions as ah, type PlannerUsage as ai, type PluginCloneFn as aj, type PluginEntry as ak, type PluginFeatures as al, type PluginMode as am, type PluginModelDiscovery as an, type PluginRunnerDef as ao, type PreparedLaunch as ap, type PreparedTask as aq, type ProviderCredentialSource as ar, type ProviderModelLists as as, type ProviderModelsResult as at, type PtySize as au, type PtyWrapOptions as av, type QueuedMessage as aw, type QueuedTaskMessage as ax, type RepairEvidence as ay, type RepoGroupLayout as az, type ActiveTaskSession as b, wrapWithPty as b$, type TaskRunnerFlags as b0, type TaskSnapshot as b1, type TaskStartOptions as b2, type TaskStatus as b3, type TaskTransport as b4, type TaskType as b5, type TaskWithParent as b6, type ThinkingBlock as b7, type TreeSnapshot as b8, type UsageLine as b9, isMeasured as bA, isReservedRunnerName as bB, isRunnerApproval as bC, isRunnerTransport as bD, isStructuredSession as bE, keepExecutionState as bF, knownModelId as bG, migrateLegacyPlan as bH, migratePlanState as bI, migrateTask as bJ, partedPromptUsage as bK, planDirectLaunch as bL, planShellLaunch as bM, plannerContextFill as bN, posixShellQuote as bO, removeTaskFromPlan as bP, renumberTasks as bQ, resolveModelShortcut as bR, resolveProvider as bS, stripAnsi as bT, toApprovalDecision as bU, toOrchestratorOptions as bV, updateTaskInPlan as bW, usageLine as bX, validateModifiedPlan as bY, warningsText as bZ, windowsCommandLine as b_, type UsageRecord as ba, type UsageTotals as bb, type UserPromptEntry as bc, type UserStep as bd, type ValidationCheck as be, type ValidationContext as bf, type ValidationResult as bg, type Verdict as bh, type VerificationCheck as bi, WINDOWS_MAX_COMMAND_LINE as bj, addPlannerUsage as bk, addTaskToPlan as bl, addUsage as bm, approvalScopes as bn, buildShellInvocation as bo, collectProviderCredentials as bp, createEmptyPlan as bq, createTask as br, emptyWarnings as bs, enabledRunners as bt, fetchAllProviderModels as bu, flattenTasks as bv, flattenTasksWithParents as bw, isAwaitingReason as bx, isExecutableResolved as by, isGranted as bz, type AgentAdapter as c, type AgentAdapterFactory as d, type AgentEvent as e, type AgentProcessDeps as f, type AgentStartOptions as g, type AiProvider as h, type AllProviderModels as i, type ApprovalAnswer as j, type ApprovalDecision as k, type ApprovalKind as l, type ApprovalMode as m, ApprovalPolicy as n, type ApprovalPolicyOptions as o, type ApprovalRequest as p, type ApprovalSource as q, type AwaitingReason as r, type CatalogModel as s, CommandLineTooLongError as t, type ConversationMessage as u, type DiscoveredMode as v, type DiscoveredModel as w, type DiscoveryCommand as x, ExecutableNotFoundError as y, type HeadlessRunnerDeps as z };
@@ -10,7 +10,7 @@ import {
10
10
  renumberTasks,
11
11
  stripTrailingCommas,
12
12
  updateTaskInPlan
13
- } from "./chunk-EDGUFCIR.mjs";
13
+ } from "./chunk-JRZPSNRO.mjs";
14
14
 
15
15
  // src/models/Usage.ts
16
16
  function partedPromptUsage(parts) {
@@ -850,7 +850,7 @@ function coerceAssignments(tasks, perRunnerAllowlist, allowedRunners, modelsByRu
850
850
  import { v4 as uuidv4 } from "uuid";
851
851
 
852
852
  // src/services/TaskEditValidator.ts
853
- var AI_ONLY_FIELDS = ["assignedModel", "thinkingEffort", "taskMode", "autonomy"];
853
+ var AI_ONLY_FIELDS = ["assignedModel", "thinkingEffort", "taskMode", "autonomy", "ops"];
854
854
  function checkModelAndModeValidity(runner, assignedModel, taskMode, catalog) {
855
855
  if (!catalog) return { ok: true };
856
856
  if (assignedModel) {
@@ -887,6 +887,19 @@ function typeCoherenceCheck(target, changes) {
887
887
  }
888
888
  return { ok: true, clear: target.userSteps && target.userSteps.length > 0 ? ["userSteps"] : [] };
889
889
  }
890
+ var NOT_STARTED = /* @__PURE__ */ new Set(["pending", "approved", "blocked"]);
891
+ function opsCheck(tasks, target, changes) {
892
+ if (!("ops" in changes) || !!changes.ops === !!target.ops) return null;
893
+ if (!NOT_STARTED.has(target.status)) {
894
+ return { ok: false, error: `"${target.title}" has started, so whether it is an ops task is fixed` };
895
+ }
896
+ if (!changes.ops) return null;
897
+ if ((changes.type ?? target.type) !== "ai") return { ok: false, error: `"${target.title}" is a manual task \u2014 only an AI task can be an ops task` };
898
+ if (tasks.some((t) => t.subtasks?.some((s) => s.id === target.id))) {
899
+ return { ok: false, error: `"${target.title}" is a subtask, which runs with its parent \u2014 only a top-level task can be an ops task` };
900
+ }
901
+ return null;
902
+ }
890
903
  function validateTaskEdit(actor, tasks, taskId, changes, catalog) {
891
904
  const target = tasks.find((t) => t.id === taskId);
892
905
  if (!target) return { ok: false, error: "Task not found" };
@@ -900,6 +913,8 @@ function validateTaskEdit(actor, tasks, taskId, changes, catalog) {
900
913
  }
901
914
  const coherence = typeCoherenceCheck(target, changes);
902
915
  if (coherence && !coherence.ok) return coherence;
916
+ const ops = opsCheck(tasks, target, changes);
917
+ if (ops) return ops;
903
918
  const runner = changes.assignedRunner ?? target.assignedRunner;
904
919
  const validity = checkModelAndModeValidity(runner, changes.assignedModel, changes.taskMode, catalog);
905
920
  if (!validity.ok) return validity;
@@ -919,7 +934,8 @@ var UPDATABLE_FIELDS = [
919
934
  "type",
920
935
  "userSteps",
921
936
  "autonomy",
922
- "sliceType"
937
+ "sliceType",
938
+ "ops"
923
939
  ];
924
940
  function taskOpsProtocol(executionNote = "") {
925
941
  const updateChanges = UPDATABLE_FIELDS.map((f) => f === "dependencies" ? '"dependencies"?:["<id or #order>"]' : `"${f}"?`).join(",");
@@ -927,7 +943,7 @@ function taskOpsProtocol(executionNote = "") {
927
943
  "- To modify specific tasks, reply with ONLY this JSON object:",
928
944
  ' {"taskOps": [',
929
945
  ` {"op":"update","taskId":"<id or #order>","changes":{${updateChanges}}},`,
930
- ' {"op":"add","task":{"title","description","prompt","dependencies":["<id or #order>"],"assignedRunner"?,"assignedModel"?},"handle"?:"<name>"},',
946
+ ' {"op":"add","task":{"title","description","prompt","dependencies":["<id or #order>"],"assignedRunner"?,"assignedModel"?,"ops"?},"handle"?:"<name>"},',
931
947
  ' {"op":"remove","taskId":"<id or #order>"},',
932
948
  ' {"op":"reorder","taskIds":["<id or #order>", "... every task exactly once"]}, // only to re-prioritise INDEPENDENT tasks',
933
949
  ' {"op":"merge","taskIds":["<id or #order>", "..."],"merged":{"title","description","prompt"?,"assignedRunner"?,"assignedModel"?,...},"handle"?:"<name>"},',
@@ -1030,6 +1046,14 @@ function refCollidesWithExisting(name, originalFlatAll) {
1030
1046
  if (/^\d+$/.test(orderStr) && originalFlatAll.some((t) => t.order === Number(orderStr))) return true;
1031
1047
  return originalFlatAll.some((t) => t.title === name);
1032
1048
  }
1049
+ function updatableChanges(raw) {
1050
+ const changes = {};
1051
+ for (const key of UPDATABLE_FIELDS) {
1052
+ if (raw && key in raw) changes[key] = raw[key];
1053
+ }
1054
+ if ("ops" in changes) changes.ops = changes.ops === true ? true : void 0;
1055
+ return changes;
1056
+ }
1033
1057
  function findInTasks(tasks, id) {
1034
1058
  return flattenTasks(tasks).find((t) => t.id === id);
1035
1059
  }
@@ -1211,10 +1235,7 @@ function applyTaskOps(currentTasks, ops, runners, catalog) {
1211
1235
  errors.push(`${label}: task "${op.taskId}" no longer exists in this batch (removed, merged, or split by an earlier op)`);
1212
1236
  break;
1213
1237
  }
1214
- const changes = {};
1215
- for (const key of UPDATABLE_FIELDS) {
1216
- if (op.changes && key in op.changes) changes[key] = op.changes[key];
1217
- }
1238
+ const changes = updatableChanges(op.changes);
1218
1239
  if (changes.assignedRunner && !runners.includes(changes.assignedRunner)) {
1219
1240
  errors.push(`${label}: runner "${changes.assignedRunner}" is not in this plan's runner set [${runners.join(", ")}]`);
1220
1241
  break;
@@ -1366,6 +1387,7 @@ function applyTaskOps(currentTasks, ops, runners, catalog) {
1366
1387
  taskMode: spec.taskMode ?? toMerge[0].taskMode,
1367
1388
  autonomy: spec.autonomy ?? toMerge.find((t) => t.autonomy)?.autonomy,
1368
1389
  sliceType: spec.sliceType ?? toMerge.find((t) => t.sliceType)?.sliceType,
1390
+ ops: spec.ops ?? toMerge.every((t) => t.ops),
1369
1391
  userStoriesCovered: spec.userStoriesCovered ?? (toMerge.flatMap((t) => t.userStoriesCovered ?? []).length ? [...new Set(toMerge.flatMap((t) => t.userStoriesCovered ?? []))] : void 0)
1370
1392
  });
1371
1393
  const mergedId = mergedTask.id;
@@ -1446,6 +1468,7 @@ function applyTaskOps(currentTasks, ops, runners, catalog) {
1446
1468
  taskMode: spec.taskMode ?? target.taskMode,
1447
1469
  autonomy: spec.autonomy ?? target.autonomy,
1448
1470
  sliceType: spec.sliceType ?? target.sliceType,
1471
+ ops: spec.ops ?? target.ops,
1449
1472
  userStoriesCovered: spec.userStoriesCovered ?? target.userStoriesCovered
1450
1473
  });
1451
1474
  newTasks.push(nt);
@@ -1481,10 +1504,7 @@ function applyTaskOps(currentTasks, ops, runners, catalog) {
1481
1504
  errors.push(`${label}: "${target.title}" is running and cannot be re-armed`);
1482
1505
  break;
1483
1506
  }
1484
- const changes = {};
1485
- for (const key of UPDATABLE_FIELDS) {
1486
- if (op.changes && key in op.changes) changes[key] = op.changes[key];
1487
- }
1507
+ const changes = updatableChanges(op.changes);
1488
1508
  if (changes.assignedRunner && !runners.includes(changes.assignedRunner)) {
1489
1509
  errors.push(`${label}: runner "${changes.assignedRunner}" is not in this plan's runner set [${runners.join(", ")}]`);
1490
1510
  break;
@@ -1648,10 +1668,11 @@ function serializeTask(t) {
1648
1668
  thinkingEffort: t.thinkingEffort || void 0,
1649
1669
  autonomy: t.autonomy || void 0,
1650
1670
  sliceType: t.sliceType || void 0,
1651
- userStoriesCovered: t.userStoriesCovered || void 0
1671
+ userStoriesCovered: t.userStoriesCovered || void 0,
1672
+ ...t.ops ? { ops: true } : {}
1652
1673
  };
1653
1674
  }
1654
- function serializeTaskStatus(t, idleSince = null, isolation = null, queued = [], awaitingApproval = 0) {
1675
+ function serializeTaskStatus(t, idleSince = null, isolation = null, queued = [], awaitingApproval = 0, mergeGate = []) {
1655
1676
  return {
1656
1677
  id: t.id,
1657
1678
  status: t.status,
@@ -1662,7 +1683,9 @@ function serializeTaskStatus(t, idleSince = null, isolation = null, queued = [],
1662
1683
  ...t.status === "awaiting_user" && t.awaitingReason ? { awaitingReason: t.awaitingReason } : {},
1663
1684
  ...queued.length > 0 ? { queued: queued.map((m) => ({ ...m })) } : {},
1664
1685
  ...canContinue(t) ? { continuable: true } : {},
1665
- ...awaitingApproval > 0 ? { awaitingApproval } : {}
1686
+ ...awaitingApproval > 0 ? { awaitingApproval } : {},
1687
+ ...mergeGate.length > 0 ? { mergeGate: [...mergeGate] } : {},
1688
+ ...t.forcedPastGate?.length ? { forcedPastGate: [...t.forcedPastGate] } : {}
1666
1689
  };
1667
1690
  }
1668
1691
  function serializePlan(plan) {
@@ -2113,4 +2136,4 @@ export {
2113
2136
  hasHiddenDetail,
2114
2137
  taskStartedNotice
2115
2138
  };
2116
- //# sourceMappingURL=chunk-2SOVKO7P.mjs.map
2139
+ //# sourceMappingURL=chunk-I6U3PVHL.mjs.map