@ordewell/core 0.4.23 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ITerminalRunner-CuNYBnqK.d.mts → ITerminalRunner-DCjsa2-I.d.mts} +31 -1
- package/dist/{ITerminalRunner-Da1gIAFX.d.ts → ITerminalRunner-H1yT8LTy.d.ts} +31 -1
- package/dist/{ModeResolver-mtIWrLXn.d.mts → ModeResolver-DVJ7HV3k.d.mts} +1 -1
- package/dist/{ModeResolver-Ob-ihQbI.d.ts → ModeResolver-Dkig8ghQ.d.ts} +1 -1
- package/dist/Task-BxQkPlXO.d.mts +664 -0
- package/dist/Task-BxQkPlXO.d.ts +664 -0
- package/dist/{chunk-O2MFTRHA.mjs → chunk-GWPIYDQW.mjs} +29 -5
- package/dist/chunk-GWPIYDQW.mjs.map +1 -0
- package/dist/{chunk-T4KGVP4N.mjs → chunk-JVMDEHRQ.mjs} +1 -1
- package/dist/chunk-JVMDEHRQ.mjs.map +1 -0
- package/dist/chunk-T2S5O36I.mjs +103 -0
- package/dist/chunk-T2S5O36I.mjs.map +1 -0
- package/dist/{chunk-MKUTJDT2.mjs → chunk-XWOUIA6A.mjs} +2 -2
- package/dist/index.d.mts +614 -104
- package/dist/index.d.ts +614 -104
- package/dist/index.js +3780 -1209
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3747 -1291
- package/dist/index.mjs.map +1 -1
- package/dist/order-labels.d.mts +1 -1
- package/dist/order-labels.d.ts +1 -1
- package/dist/{parsing-BJoHbA-t.d.ts → parsing-CF_grC29.d.ts} +2 -2
- package/dist/{parsing-BWfpLch9.d.mts → parsing-DRp4dPC0.d.mts} +2 -2
- package/dist/parsing.d.mts +3 -3
- package/dist/parsing.d.ts +3 -3
- package/dist/parsing.js.map +1 -1
- package/dist/parsing.mjs +2 -2
- package/dist/{plan-utils-DJm2a7Zp.d.ts → plan-utils-CkNbqAmS.d.ts} +63 -5
- package/dist/{plan-utils-s6VL8NDF.d.mts → plan-utils-CtB3_Ovf.d.mts} +63 -5
- package/dist/plan-utils.d.mts +3 -3
- package/dist/plan-utils.d.ts +3 -3
- package/dist/plan-utils.js +7 -0
- package/dist/plan-utils.js.map +1 -1
- package/dist/plan-utils.mjs +6 -2
- package/dist/testing.d.mts +93 -3
- package/dist/testing.d.ts +93 -3
- package/dist/testing.js +200 -0
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +179 -0
- package/dist/testing.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/Task-4rDGr8Su.d.mts +0 -271
- package/dist/Task-4rDGr8Su.d.ts +0 -271
- package/dist/chunk-O2MFTRHA.mjs.map +0 -1
- package/dist/chunk-T4KGVP4N.mjs.map +0 -1
- /package/dist/{chunk-MKUTJDT2.mjs.map → chunk-XWOUIA6A.mjs.map} +0 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { D as DiscoveredMode, M as Message,
|
|
3
|
-
import { f as IFileSystem, R as ReadFileOpts, T as ToolOutcome, d as GrepOptions, c as GlobOptions, b as FindSymbolOptions, I as IConfig, A as AiProvider, r as ProviderModelLists, i as ITerminalSession, h as ITerminalRunner, w as RunnerRegistry, k as OrchestratorOption, u as RunnerInvocation, g as IPluginStore, v as RunnerPluginManifest, t as ResolveContext } from './ITerminalRunner-
|
|
4
|
-
export { a as AllProviderModels, C as CatalogModel, D as DiscoveryCommand, F as FetchAllProviderModelsOptions, G as GREP_DEFAULT_HEAD_LIMIT, e as GrepOutputMode, M as ModelCatalog, j as ModelShortcut, O as ORCHESTRATOR_SHORTCUTS, P as PluginCloneFn, l as PluginEntry, m as PluginFeatures, n as PluginMode, o as PluginModelDiscovery, p as PluginRunnerDef, q as ProviderCredentialSource, s as ProviderModelsResult, S as SEARCH_EXCLUSIONS, x as collectProviderCredentials, y as enabledRunners, z as fetchAllProviderModels, B as isReservedRunnerName, E as knownModelId, H as resolveModelShortcut, J as resolveProvider, K as toOrchestratorOptions } from './ITerminalRunner-
|
|
1
|
+
import { F as RunnerId, u as PlanStatus, L as LegacyPlanState, k as IsolationMergeResult, g as IsolationLandedTask, I as IWorktreeIsolation, w as RepoGroupLayout, a as DiscoveredModel, T as Task, y as ResearchProgress, x as ResearchLogEntry, C as ConversationMessage, V as TaskSnapshot, d as IsolationHandoff, J as TaskIsolation, r as IsolationView, P as PlanIsolation, Q as QueuedMessage, A as ActiveTaskSession, E as ResearchToolType, t as PlanState, a3 as Verdict } from './Task-BxQkPlXO.js';
|
|
2
|
+
export { D as DiscoveredMode, b as IntegrationDisposal, c as IsolationAvailability, e as IsolationHandoffRepo, f as IsolationInactiveReason, h as IsolationLanding, i as IsolationMergeBlock, j as IsolationMergeBlockReason, l as IsolationOutcome, m as IsolationRepo, n as IsolationRun, o as IsolationTaskRecord, p as IsolationTaskRepo, q as IsolationTaskStatus, M as Message, s as PlanModificationWarnings, v as PreparedTask, R as RepairEvidence, z as ResearchStep, B as ResearchStepOutcome, S as StreamEvent, G as StreamStepEvent, H as StreamThinkingEvent, K as TaskIsolationState, N as TaskMode, O as TaskModelAssignment, U as TaskOutputSummary, W as TaskStatus, X as TaskType, Y as TaskWithParent, Z as ThinkingBlock, _ as UserPromptEntry, $ as UserStep, a0 as ValidationCheck, a1 as ValidationContext, a2 as ValidationResult, a4 as VerificationCheck, a5 as addTaskToPlan, a6 as createEmptyPlan, a7 as createTask, a8 as emptyWarnings, a9 as flattenTasks, aa as flattenTasksWithParents, ab as migrateLegacyPlan, ac as migratePlanState, ad as migrateTask, ae as removeTaskFromPlan, af as renumberTasks, ag as updateTaskInPlan, ah as validateModifiedPlan, ai as warningsText } from './Task-BxQkPlXO.js';
|
|
3
|
+
import { f as IFileSystem, R as ReadFileOpts, T as ToolOutcome, d as GrepOptions, c as GlobOptions, b as FindSymbolOptions, I as IConfig, A as AiProvider, r as ProviderModelLists, i as ITerminalSession, h as ITerminalRunner, w as RunnerRegistry, k as OrchestratorOption, u as RunnerInvocation, g as IPluginStore, v as RunnerPluginManifest, t as ResolveContext } from './ITerminalRunner-H1yT8LTy.js';
|
|
4
|
+
export { a as AllProviderModels, C as CatalogModel, D as DiscoveryCommand, F as FetchAllProviderModelsOptions, G as GREP_DEFAULT_HEAD_LIMIT, e as GrepOutputMode, M as ModelCatalog, j as ModelShortcut, O as ORCHESTRATOR_SHORTCUTS, P as PluginCloneFn, l as PluginEntry, m as PluginFeatures, n as PluginMode, o as PluginModelDiscovery, p as PluginRunnerDef, q as ProviderCredentialSource, s as ProviderModelsResult, S as SEARCH_EXCLUSIONS, x as collectProviderCredentials, y as enabledRunners, z as fetchAllProviderModels, B as isReservedRunnerName, E as knownModelId, H as resolveModelShortcut, J as resolveProvider, K as toOrchestratorOptions } from './ITerminalRunner-H1yT8LTy.js';
|
|
5
5
|
import { I as IApproval, d as ApprovalRequest, a as ApprovalMode } from './ApprovalPolicy-BVhGdECT.js';
|
|
6
6
|
export { A as ApprovalKind, b as ApprovalPolicy, c as ApprovalPolicyOptions, e as ApprovalSource, D as DENY_ALL } from './ApprovalPolicy-BVhGdECT.js';
|
|
7
|
-
import {
|
|
8
|
-
export {
|
|
9
|
-
import {
|
|
10
|
-
export {
|
|
7
|
+
import { T as TaskOp, f as SessionBroadcaster, h as SessionNotice } from './plan-utils-CkNbqAmS.js';
|
|
8
|
+
export { A as Adr0013IsolationRun, a as Adr0013PlanIsolation, b as Adr0013TaskRecord, c as ApplyTaskOpsResult, C as CHECKPOINT_TRUNCATE_LENGTH, S as SerializedPlan, d as SerializedTask, e as SerializedTaskStatus, g as SessionMessage, i as TaskRef, j as applyTaskOps, k as canMergeTasks, l as canSetDependencies, m as canSplitTask, n as capConflictFiles, o as classifyOutcome, p as dependencyCandidates, q as dependentsOf, r as executionSummary, s as migratePlanIsolation, t as parseTaskOpsJson, u as serializePlan, v as serializeTask, w as serializeTaskStatus, x as summarizeToolCall, y as textHasTaskOps, z as truncateCheckpointSummary } from './plan-utils-CkNbqAmS.js';
|
|
9
|
+
import { R as RunnerModeInfo } from './ModeResolver-Dkig8ghQ.js';
|
|
10
|
+
export { M as ManifestLookup, b as buildModeGuide, f as filteredBuildModes, r as resolveDefaultMode, a as resolveTaskMode, c as runnerModesFrom } from './ModeResolver-Dkig8ghQ.js';
|
|
11
11
|
import { ChildProcess } from 'child_process';
|
|
12
12
|
import { EventEmitter } from 'events';
|
|
13
|
-
import { b as PlanParseError } from './parsing-
|
|
14
|
-
export { P as PLAN_ENVELOPE_KEY, a as PartialPlanTask, T as TASK_OPS_ENVELOPE_KEY, c as TASK_QUERY_ENVELOPE_KEY, d as checkDepsResolve, e as checkImmutableLog, f as checkInProgress, g as checkNoCycles, h as checkUniqueIds, i as escapeControlCharsInStrings, j as extractJsonObject, k as extractObjectWithBalance, l as extractObjectsWithKey, m as looksLikePlanAttempt, p as parsePartialPlan, n as parsePlanJson, s as stripModelNoise, o as stripTrailingCommas, v as validatePlanModification } from './parsing-
|
|
13
|
+
import { b as PlanParseError } from './parsing-CF_grC29.js';
|
|
14
|
+
export { P as PLAN_ENVELOPE_KEY, a as PartialPlanTask, T as TASK_OPS_ENVELOPE_KEY, c as TASK_QUERY_ENVELOPE_KEY, d as checkDepsResolve, e as checkImmutableLog, f as checkInProgress, g as checkNoCycles, h as checkUniqueIds, i as escapeControlCharsInStrings, j as extractJsonObject, k as extractObjectWithBalance, l as extractObjectsWithKey, m as looksLikePlanAttempt, p as parsePartialPlan, n as parsePlanJson, s as stripModelNoise, o as stripTrailingCommas, v as validatePlanModification } from './parsing-CF_grC29.js';
|
|
15
15
|
export { resolveOrderLabel, taskOrderLabel } from './order-labels.js';
|
|
16
16
|
|
|
17
17
|
interface SessionMeta {
|
|
@@ -523,6 +523,11 @@ declare abstract class BaseConfig implements IConfig {
|
|
|
523
523
|
get researchMaxFileSize(): number;
|
|
524
524
|
get planMapEnabled(): boolean;
|
|
525
525
|
get autonomousMode(): boolean;
|
|
526
|
+
get worktreeIsolation(): boolean;
|
|
527
|
+
get worktreeSetupCommand(): string | undefined;
|
|
528
|
+
get workspaceRepos(): string[];
|
|
529
|
+
get worktreeLinks(): string[];
|
|
530
|
+
get conflictRepairAttempts(): number;
|
|
526
531
|
get approvalMode(): ApprovalMode;
|
|
527
532
|
get approvalPreApproved(): string[];
|
|
528
533
|
protected static detectProvider(fallback: AiProvider): AiProvider;
|
|
@@ -553,6 +558,35 @@ interface INotification {
|
|
|
553
558
|
confirm(msg: string, options: string[]): Promise<string | undefined>;
|
|
554
559
|
}
|
|
555
560
|
|
|
561
|
+
/**
|
|
562
|
+
* How "Merge all" went, in words every surface shares. `group` is whether the
|
|
563
|
+
* run spans more than a lone repo at `.`; only a merge into every repository
|
|
564
|
+
* has something to say about that. `repaired` names the landed tasks that only
|
|
565
|
+
* landed after a conflict repair (ADR-0015), so a clean-looking merge still
|
|
566
|
+
* points review at what changed to get there.
|
|
567
|
+
*/
|
|
568
|
+
declare function describeMergeResult(result: IsolationMergeResult, branch: string, group: boolean, repaired?: IsolationLandedTask[]): {
|
|
569
|
+
level: 'info' | 'warn' | 'error';
|
|
570
|
+
message: string;
|
|
571
|
+
};
|
|
572
|
+
|
|
573
|
+
type GitExecFn = (file: string, args: string[], opts: {
|
|
574
|
+
cwd?: string;
|
|
575
|
+
env: NodeJS.ProcessEnv;
|
|
576
|
+
}) => Promise<{
|
|
577
|
+
stdout: string;
|
|
578
|
+
stderr: string;
|
|
579
|
+
}>;
|
|
580
|
+
interface WorktreeIsolationDeps {
|
|
581
|
+
config: Pick<IConfig, 'worktreeIsolation' | 'worktreeSetupCommand' | 'workspaceRepos' | 'worktreeLinks'>;
|
|
582
|
+
/** Test seam: every git invocation goes through this. */
|
|
583
|
+
execFileImpl?: GitExecFn;
|
|
584
|
+
resolvePath?: () => Promise<string>;
|
|
585
|
+
platform?: NodeJS.Platform;
|
|
586
|
+
mintRunId?: () => string;
|
|
587
|
+
}
|
|
588
|
+
declare function createWorktreeIsolation(deps: WorktreeIsolationDeps): IWorktreeIsolation;
|
|
589
|
+
|
|
556
590
|
interface ILogger {
|
|
557
591
|
warn(scope: string, message: string, err?: unknown): void;
|
|
558
592
|
}
|
|
@@ -628,9 +662,75 @@ interface PlannerRuntimeToggles {
|
|
|
628
662
|
* every planner signature used to carry positionally — where a thirteenth
|
|
629
663
|
* parameter was the only place left to put a new toggle.
|
|
630
664
|
*/
|
|
665
|
+
/**
|
|
666
|
+
* Where the run's tasks will work: `false` in the shared workspace root;
|
|
667
|
+
* otherwise each in its own worktree of every repo of the group (ADR-0013,
|
|
668
|
+
* ADR-0014), which is what decides if tasks on the same file must be ordered.
|
|
669
|
+
*/
|
|
670
|
+
type IsolatedExecution = false | RepoGroupLayout;
|
|
631
671
|
interface PlannerModes {
|
|
632
672
|
autonomousDefault: boolean;
|
|
633
673
|
verification: boolean;
|
|
674
|
+
/** Not a toggle: a fact about the run. */
|
|
675
|
+
isolatedExecution: IsolatedExecution;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/** Context of one task attempt, enough to locate its transcript. */
|
|
679
|
+
interface TranscriptQuery {
|
|
680
|
+
runner: string;
|
|
681
|
+
/** The task's working directory (the agent's cwd at spawn). */
|
|
682
|
+
cwd: string;
|
|
683
|
+
/** When the agent process started, ISO — used to reject older sessions. */
|
|
684
|
+
startedAt?: string;
|
|
685
|
+
/**
|
|
686
|
+
* The task's completion marker UUID. The prompt carries it, so a transcript
|
|
687
|
+
* that does not contain it belongs to some other task — parallel attempts in
|
|
688
|
+
* one cwd are otherwise indistinguishable by directory and recency.
|
|
689
|
+
*/
|
|
690
|
+
marker: string;
|
|
691
|
+
}
|
|
692
|
+
/** Reads the agent's own session transcript for a task's final answer. */
|
|
693
|
+
interface TranscriptReader {
|
|
694
|
+
/** Last assistant-authored prose, clamped to `maxChars` from the end, or null. */
|
|
695
|
+
finalAssistantText(query: TranscriptQuery, maxChars?: number): Promise<string | null>;
|
|
696
|
+
}
|
|
697
|
+
/** The part of a task attempt its output is looked up by. */
|
|
698
|
+
interface TaskOutputAttempt {
|
|
699
|
+
readonly taskId: string;
|
|
700
|
+
readonly runner: string;
|
|
701
|
+
/** Null when the attempt ended before its working directory was settled. */
|
|
702
|
+
readonly cwd: string | null;
|
|
703
|
+
readonly startedAt: string;
|
|
704
|
+
/** The completion marker UUID the attempt's prompt carried. */
|
|
705
|
+
readonly completionMarker: string;
|
|
706
|
+
}
|
|
707
|
+
interface LiveTailOptions {
|
|
708
|
+
maxLines: number;
|
|
709
|
+
/** A previous {@link LiveTail.nextOffset}: only output after it is rendered. */
|
|
710
|
+
sinceOffset?: number;
|
|
711
|
+
}
|
|
712
|
+
interface LiveTail {
|
|
713
|
+
/** Clean terminal render, not raw ANSI. */
|
|
714
|
+
text: string;
|
|
715
|
+
/** Total output received so far; pass it back as `sinceOffset` to read only what follows. */
|
|
716
|
+
nextOffset: number;
|
|
717
|
+
running: boolean;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* The one owner of a task attempt's output: what it printed while running
|
|
721
|
+
* and what it answered once it ended.
|
|
722
|
+
*/
|
|
723
|
+
interface TaskOutputSource {
|
|
724
|
+
/** Start capturing a session; replaces any earlier capture of the task. */
|
|
725
|
+
attach(taskId: string, session: ITerminalSession): void;
|
|
726
|
+
/** Stop capturing the task's session; what was captured stays readable. */
|
|
727
|
+
detach(taskId: string): void;
|
|
728
|
+
/** Drop every capture (a new plan reuses task ids). */
|
|
729
|
+
reset(): void;
|
|
730
|
+
/** The attempt's final answer: its transcript first, the clean terminal render otherwise. */
|
|
731
|
+
finalText(attempt: TaskOutputAttempt, doneToken: string): Promise<string>;
|
|
732
|
+
/** Recent output of the task's latest capture, or null if it never had one. */
|
|
733
|
+
liveTail(taskId: string, opts: LiveTailOptions): LiveTail | null;
|
|
634
734
|
}
|
|
635
735
|
|
|
636
736
|
/**
|
|
@@ -648,8 +748,19 @@ interface PlannerModes {
|
|
|
648
748
|
* lives in PlanRepair alongside the plan and task-ops envelopes.
|
|
649
749
|
*/
|
|
650
750
|
/** The long fields a query may ask for. Everything else is already in the plan block. */
|
|
651
|
-
declare const TASK_QUERY_FIELDS: readonly ["description", "prompt", "userSteps", "verdict", "outputSummary", "userStoriesCovered"];
|
|
751
|
+
declare const TASK_QUERY_FIELDS: readonly ["description", "prompt", "userSteps", "verdict", "outputSummary", "userStoriesCovered", "output"];
|
|
652
752
|
type TaskQueryField = typeof TASK_QUERY_FIELDS[number];
|
|
753
|
+
/** Lines a `output` read returns when the query sets no count. */
|
|
754
|
+
declare const OUTPUT_LINES_DEFAULT = 80;
|
|
755
|
+
/** Hard cap on `outputLines` — the tail read is bounded however the planner asks. */
|
|
756
|
+
declare const OUTPUT_LINES_MAX = 400;
|
|
757
|
+
/**
|
|
758
|
+
* Character budget the rendered answer converges to. A running output tail is
|
|
759
|
+
* the only part with no natural bound — a runner may print for minutes — so
|
|
760
|
+
* the tail absorbs the clamp; everything else (task bodies, the catalog cap)
|
|
761
|
+
* is bounded upstream.
|
|
762
|
+
*/
|
|
763
|
+
declare const TASK_QUERY_ANSWER_MAX_CHARS = 20000;
|
|
653
764
|
interface TaskQuery {
|
|
654
765
|
/** Task references to read in full — an id, "#order", a bare order, or a title. */
|
|
655
766
|
tasks: string[];
|
|
@@ -657,6 +768,10 @@ interface TaskQuery {
|
|
|
657
768
|
fields?: TaskQueryField[];
|
|
658
769
|
/** Also return the full runner/model catalog with labels, variants and mode descriptions. */
|
|
659
770
|
catalog: boolean;
|
|
771
|
+
/** Line count for `output` reads. Clamped at render to [1, {@link OUTPUT_LINES_MAX}]. */
|
|
772
|
+
outputLines?: number;
|
|
773
|
+
/** A previous answer's next offset: the output tail then covers only what came after it. */
|
|
774
|
+
outputSince?: number;
|
|
660
775
|
}
|
|
661
776
|
declare function textHasTaskQuery(text: string): boolean;
|
|
662
777
|
/** Parse a `{"taskQuery":...}` reply. Throws PlanParseError when the JSON is unusable. */
|
|
@@ -685,12 +800,19 @@ declare const TASK_QUERY_ANSWER_OR_OPS: string;
|
|
|
685
800
|
declare const TASK_QUERY_PROTOCOL: string[];
|
|
686
801
|
/** The one-line reminder the per-turn plan block carries, so the protocol has a single owner. */
|
|
687
802
|
declare const TASK_QUERY_REMINDER = "- To READ a task in full (prompt, user steps, verdict, output, user stories) or the whole model/mode catalog before editing, reply with ONLY {\"taskQuery\":{\"tasks\":[\"<id or #order>\"],\"catalog\":true}} \u2014 it changes nothing, and you then reply again with your ops.";
|
|
803
|
+
/**
|
|
804
|
+
* Where an `output` read is answered from: the orchestrator's live capture of
|
|
805
|
+
* the task's latest attempt. Injected so this module stays planner-side and
|
|
806
|
+
* never imports the orchestrator.
|
|
807
|
+
*/
|
|
808
|
+
type LiveOutputLookup = (taskId: string, opts: LiveTailOptions) => LiveTail | null;
|
|
688
809
|
/**
|
|
689
810
|
* Render the injected answer to one read. Never persisted — it is context for
|
|
690
811
|
* the planner's next reply and nothing else — so it is built fresh from live
|
|
691
|
-
* state on every query rather than cached.
|
|
812
|
+
* state on every query rather than cached. `liveOutput` backs the `output`
|
|
813
|
+
* field; omitting it reads as "nothing captured".
|
|
692
814
|
*/
|
|
693
|
-
declare function renderTaskQueryAnswer(query: TaskQuery, tasks: Task[], catalog: TaskQueryCatalog): string;
|
|
815
|
+
declare function renderTaskQueryAnswer(query: TaskQuery, tasks: Task[], catalog: TaskQueryCatalog, liveOutput?: LiveOutputLookup): string;
|
|
694
816
|
|
|
695
817
|
declare abstract class AbstractTerminalSession implements ITerminalSession {
|
|
696
818
|
id: string;
|
|
@@ -967,6 +1089,7 @@ declare class HeadlessRunner extends AbstractRunner<HeadlessSession> {
|
|
|
967
1089
|
private hasScriptCmd;
|
|
968
1090
|
private resolvePath;
|
|
969
1091
|
private launchDeps;
|
|
1092
|
+
private spawnCount;
|
|
970
1093
|
/**
|
|
971
1094
|
* Session shape: a piped subprocess is not a terminal, so runners get their
|
|
972
1095
|
* non-interactive subcommand. The VS Code runner owns a pseudoterminal and
|
|
@@ -976,6 +1099,13 @@ declare class HeadlessRunner extends AbstractRunner<HeadlessSession> {
|
|
|
976
1099
|
*/
|
|
977
1100
|
protected readonly defaultInteractive: boolean;
|
|
978
1101
|
constructor(deps?: HeadlessRunnerDeps);
|
|
1102
|
+
/**
|
|
1103
|
+
* Unique per spawn, not per task: a retry reuses its task id and ids often
|
|
1104
|
+
* share a prefix, and a shared registry key let the old attempt's exit
|
|
1105
|
+
* unregister the new one. Unlike TmuxRunner, nothing outside this process
|
|
1106
|
+
* keys on the id, so a counter is enough to scope it to the attempt.
|
|
1107
|
+
*/
|
|
1108
|
+
protected nextSessionId(taskId: string): string;
|
|
979
1109
|
protected createSession(id: string, taskId: string): HeadlessSession;
|
|
980
1110
|
/** Everything up to, but not including, spawning — so a surface that owns its own child reaches the same decisions. */
|
|
981
1111
|
protected prepareLaunch(opts: RunnerSpawnOptions, ptyOptions?: PtyWrapOptions): Promise<PreparedLaunch>;
|
|
@@ -1233,6 +1363,8 @@ interface ConversationRequest {
|
|
|
1233
1363
|
runnerModes?: Record<RunnerId, RunnerModeInfo[]>;
|
|
1234
1364
|
autonomousDefault?: boolean;
|
|
1235
1365
|
verificationEnabled?: boolean;
|
|
1366
|
+
/** Where tasks will run (ADR-0013, ADR-0014): in worktrees, the prompt drops file-overlap ordering and describes a repo group. */
|
|
1367
|
+
isolatedExecution?: IsolatedExecution;
|
|
1236
1368
|
signal?: AbortSignal;
|
|
1237
1369
|
/**
|
|
1238
1370
|
* Persisted dialogue to seed a resumed conversation (session reload). The
|
|
@@ -1308,6 +1440,13 @@ interface IAiService {
|
|
|
1308
1440
|
* `continueConversation`, restart instead so the new model takes effect.
|
|
1309
1441
|
*/
|
|
1310
1442
|
conversationMatchesConfig?(): boolean;
|
|
1443
|
+
/**
|
|
1444
|
+
* Optional: prune bulky raw tool output out of the live conversation, in
|
|
1445
|
+
* place, keeping subagent digests. Returns the characters removed. Absent
|
|
1446
|
+
* where the backend holds no tool transcript to prune (a harness planner's
|
|
1447
|
+
* agent owns its own context).
|
|
1448
|
+
*/
|
|
1449
|
+
pruneContext?(): number;
|
|
1311
1450
|
/**
|
|
1312
1451
|
* One-shot research + plan for non-conversational surfaces (CLI `plan --goal`,
|
|
1313
1452
|
* web REST). Never asks questions — it plans with what it can find.
|
|
@@ -1391,6 +1530,7 @@ declare abstract class BaseAiService {
|
|
|
1391
1530
|
abstract reset(): void;
|
|
1392
1531
|
abstract ensureInit(): void;
|
|
1393
1532
|
hasActiveConversation(): boolean;
|
|
1533
|
+
pruneContext(): number;
|
|
1394
1534
|
protected startAbortScope(callerSignal?: AbortSignal): AbortSignal | undefined;
|
|
1395
1535
|
protected stopAbortScope(): void;
|
|
1396
1536
|
sendPlanningPrompt(prompt: string, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): Promise<Task[]>;
|
|
@@ -1626,10 +1766,39 @@ interface OrchestratorObserver {
|
|
|
1626
1766
|
taskTitle: string;
|
|
1627
1767
|
summary: string;
|
|
1628
1768
|
}): void;
|
|
1769
|
+
/** The isolation run record changed and should be persisted with the plan. */
|
|
1770
|
+
onIsolationChanged?(): void;
|
|
1771
|
+
/** A run did not start: the tree is dirty, and the user picks stash or no isolation. `repos` names the dirty repos of a group. */
|
|
1772
|
+
onIsolationBlocked?(data: {
|
|
1773
|
+
reason: 'dirty';
|
|
1774
|
+
repos: string[];
|
|
1775
|
+
}): void;
|
|
1776
|
+
/** An isolated run settled; emitted before `onExecutionComplete`, which surfaces treat as terminal. */
|
|
1777
|
+
onIsolationHandoff?(handoff: IsolationHandoff): void;
|
|
1778
|
+
/**
|
|
1779
|
+
* What a run says about how it isolates — the fallback to the workspace root,
|
|
1780
|
+
* shared paths, copies, a stash. Beside the notification channel, which a
|
|
1781
|
+
* daemon may leave unwired, so a surface without toasts can still show it.
|
|
1782
|
+
*/
|
|
1783
|
+
onIsolationNotice?(data: {
|
|
1784
|
+
level: 'info' | 'warn';
|
|
1785
|
+
message: string;
|
|
1786
|
+
}): void;
|
|
1787
|
+
}
|
|
1788
|
+
type AttemptPhase = 'starting' | 'running' | 'integrating';
|
|
1789
|
+
/** Read-only view of a task's live attempt. */
|
|
1790
|
+
interface TaskAttemptSnapshot {
|
|
1791
|
+
taskId: string;
|
|
1792
|
+
attempt: number;
|
|
1793
|
+
phase: AttemptPhase;
|
|
1794
|
+
sessionId: string | null;
|
|
1795
|
+
runner: string;
|
|
1796
|
+
cwd: string | null;
|
|
1797
|
+
startedAt: string;
|
|
1629
1798
|
}
|
|
1630
1799
|
/**
|
|
1631
1800
|
* The pure scheduler. Owns execution state (`running`, `planStatus`,
|
|
1632
|
-
* `reviewApproved`,
|
|
1801
|
+
* `reviewApproved`, the live task attempts, `messageQueue`) and the verifier.
|
|
1633
1802
|
* All task-shaped state — the plan tree, the flat index, the completed set
|
|
1634
1803
|
* — lives in {@link PlanStore}, injected at construction. The orchestrator
|
|
1635
1804
|
* calls `store.markCompleted(id)` / `store.markFailed(id)` instead of mutating
|
|
@@ -1641,15 +1810,16 @@ declare class TaskOrchestrator {
|
|
|
1641
1810
|
private config;
|
|
1642
1811
|
private notifications;
|
|
1643
1812
|
private terminalRunner;
|
|
1813
|
+
private output;
|
|
1644
1814
|
private store;
|
|
1645
|
-
private
|
|
1646
|
-
private startingTaskIds;
|
|
1815
|
+
private attempts;
|
|
1647
1816
|
private verifier;
|
|
1648
1817
|
private running;
|
|
1649
1818
|
private planStatus;
|
|
1650
1819
|
private messageQueue;
|
|
1651
1820
|
private reviewApproved;
|
|
1652
1821
|
private retryCounts;
|
|
1822
|
+
private spawnCounts;
|
|
1653
1823
|
/**
|
|
1654
1824
|
* Tasks pulled out of auto-scheduling (user-cancelled or failed to spawn).
|
|
1655
1825
|
* They stay 'pending' — "not executed" — but the scheduler skips them until
|
|
@@ -1657,18 +1827,33 @@ declare class TaskOrchestrator {
|
|
|
1657
1827
|
* task whose spawn always throws.
|
|
1658
1828
|
*/
|
|
1659
1829
|
private onHold;
|
|
1830
|
+
private isolation;
|
|
1831
|
+
/** The plan's isolation run (ADR-0013). Outlives one run: a resumed plan continues it. */
|
|
1832
|
+
private isolationRun;
|
|
1833
|
+
/** Copied paths already reported for the current run: every task gets the same copies. */
|
|
1834
|
+
private reportedCopies;
|
|
1835
|
+
/**
|
|
1836
|
+
* How the open run executes; null while no run is open. A run is one
|
|
1837
|
+
* Execute-Plan or one manual task run, from its start until it settles or
|
|
1838
|
+
* is stopped.
|
|
1839
|
+
*/
|
|
1840
|
+
private runMode;
|
|
1841
|
+
/** Resolver task id → the conflicted task it resolves; see {@link linkConflictResolver}. */
|
|
1842
|
+
private resolvers;
|
|
1843
|
+
private opening;
|
|
1844
|
+
/** The start a dirty tree turned away, replayed once the user chooses how to go on. */
|
|
1845
|
+
private blockedStart;
|
|
1846
|
+
/** The dirty repos behind {@link blockedStart}, for the stash notice. */
|
|
1847
|
+
private blockedRepos;
|
|
1660
1848
|
private registry;
|
|
1661
1849
|
private workspaceRootFn;
|
|
1662
1850
|
private observers;
|
|
1663
1851
|
private tddEnabled;
|
|
1664
|
-
|
|
1665
|
-
* Spawn context per active task, for locating the agent's own session
|
|
1666
|
-
* transcript at verdict time (issue #16). Cleared with the session entry.
|
|
1667
|
-
*/
|
|
1668
|
-
private taskSpawnContext;
|
|
1669
|
-
constructor(config: IConfig, notifications: INotification, terminalRunner: ITerminalRunner, store?: PlanStore);
|
|
1852
|
+
constructor(config: IConfig, notifications: INotification, terminalRunner: ITerminalRunner, store?: PlanStore, output?: TaskOutputSource, isolation?: IWorktreeIsolation);
|
|
1670
1853
|
/** Advisory silence timestamp for a task's live runner, or null if not idle. */
|
|
1671
1854
|
getIdleSince(taskId: string): string | null;
|
|
1855
|
+
/** Recent clean output of a task's latest attempt, running or ended; null if it never ran. */
|
|
1856
|
+
getLiveOutput(taskId: string, opts: LiveTailOptions): LiveTail | null;
|
|
1672
1857
|
get storeInstance(): PlanStore;
|
|
1673
1858
|
setWorkspaceRoot(fn: () => string): void;
|
|
1674
1859
|
setRegistry(registry: RunnerRegistry): void;
|
|
@@ -1694,8 +1879,48 @@ declare class TaskOrchestrator {
|
|
|
1694
1879
|
get isReviewApproved(): boolean;
|
|
1695
1880
|
get status(): 'approved' | 'running' | 'completed';
|
|
1696
1881
|
get activeTaskIds(): string[];
|
|
1882
|
+
/** Task id → session id of every attempt whose runner is up; a spawn in flight has no session yet. */
|
|
1697
1883
|
get activeSessionMap(): Map<string, string>;
|
|
1884
|
+
getAttempt(taskId: string): TaskAttemptSnapshot | undefined;
|
|
1885
|
+
/** Where a task's isolated work stands; null when the plan has no isolation run to speak of. */
|
|
1886
|
+
getTaskIsolation(taskId: string): TaskIsolation | null;
|
|
1887
|
+
/**
|
|
1888
|
+
* The plan's isolation as a surface shows it, for one with no stream to have
|
|
1889
|
+
* told it — a reconnected webview, a session just loaded. Null without a run.
|
|
1890
|
+
*/
|
|
1891
|
+
isolationView(): IsolationView | null;
|
|
1892
|
+
getAttemptSession(taskId: string): ITerminalSession | undefined;
|
|
1698
1893
|
get queuedCount(): number;
|
|
1894
|
+
/** A run is waiting on the user to stash or to go on without isolation. */
|
|
1895
|
+
get awaitingIsolationChoice(): boolean;
|
|
1896
|
+
/**
|
|
1897
|
+
* Take over a plan's persisted isolation, or none for a plan that has not
|
|
1898
|
+
* isolated yet. Whatever a crashed process left behind for the run — a
|
|
1899
|
+
* worktree still marked active, a directory no record owns — is pruned,
|
|
1900
|
+
* while kept, failed and conflicted worktrees stay for the user.
|
|
1901
|
+
*
|
|
1902
|
+
* Deliberately silent on the observer: adopting is not a change to persist,
|
|
1903
|
+
* and a host that adopts without persisting (VS Code's restore) would
|
|
1904
|
+
* otherwise write a new session file on every reload.
|
|
1905
|
+
*/
|
|
1906
|
+
adoptIsolation(state: PlanIsolation | null): Promise<void>;
|
|
1907
|
+
reviewRunDiff(): Promise<string>;
|
|
1908
|
+
/**
|
|
1909
|
+
* "Merge all": the run's integration branches into whatever the user has
|
|
1910
|
+
* checked out, in every repo or none. Once everything merged, the run has
|
|
1911
|
+
* nothing left to hand over, so it is cleared up and forgotten; a branch
|
|
1912
|
+
* the user's HEAD somehow does not contain stays for the next run's sweep.
|
|
1913
|
+
*/
|
|
1914
|
+
mergeRun(): Promise<IsolationMergeResult>;
|
|
1915
|
+
private clearMergedRun;
|
|
1916
|
+
/** Worktrees and task branches go; the integration branch and the record stay for review and merge. */
|
|
1917
|
+
cleanupRun(): Promise<void>;
|
|
1918
|
+
/** The run and everything it made go, and the plan forgets it; the next run starts afresh. */
|
|
1919
|
+
discardRun(): Promise<void>;
|
|
1920
|
+
private forgetRun;
|
|
1921
|
+
private requireRun;
|
|
1922
|
+
/** What the plan persists of isolated execution; null when no run ever isolated. */
|
|
1923
|
+
get isolationRecord(): PlanIsolation | null;
|
|
1699
1924
|
queueMessage(text: string): void;
|
|
1700
1925
|
getQueuedMessages(): QueuedMessage[];
|
|
1701
1926
|
setQueuedMessages(messages: QueuedMessage[]): void;
|
|
@@ -1718,7 +1943,63 @@ declare class TaskOrchestrator {
|
|
|
1718
1943
|
stop(): void;
|
|
1719
1944
|
onUserTaskComplete(taskId: string): Promise<void>;
|
|
1720
1945
|
private onVerdict;
|
|
1946
|
+
private afterVerdict;
|
|
1947
|
+
/**
|
|
1948
|
+
* A repair's verdict decides only whether its work may try to land. It never
|
|
1949
|
+
* replaces the verdict the task's own work earned, and a repair that does not
|
|
1950
|
+
* land leaves the task waiting on the user — never a failed task, so never a
|
|
1951
|
+
* halted run.
|
|
1952
|
+
*/
|
|
1953
|
+
private settleRepair;
|
|
1954
|
+
/**
|
|
1955
|
+
* Evidence before the queue: the repair's work is committed and checked, and
|
|
1956
|
+
* only then merged, through the same serialized landing as any other task —
|
|
1957
|
+
* so a repair the tip has moved past again is a fresh conflict, not a pass.
|
|
1958
|
+
*/
|
|
1959
|
+
private landRepair;
|
|
1960
|
+
private landedRepair;
|
|
1961
|
+
/** A repair that did not land leaves the task as its conflict did: waiting on the user, worktree and refs kept. */
|
|
1962
|
+
private unrepaired;
|
|
1963
|
+
private describeEvidence;
|
|
1964
|
+
/**
|
|
1965
|
+
* Merge a passed attempt's worktree. The attempt stays live while it waits on
|
|
1966
|
+
* the module's merge queue, so a cancel, retry or stop in that window still
|
|
1967
|
+
* wins, and nothing counts the task as done before its work is on the
|
|
1968
|
+
* integration branch.
|
|
1969
|
+
*/
|
|
1970
|
+
private integrate;
|
|
1971
|
+
/** A worktree whose work is not on the integration branch yet. */
|
|
1972
|
+
private hasUnlandedWork;
|
|
1973
|
+
private integrateWork;
|
|
1974
|
+
/** Settle a task whose work passed, by what its integration reported. */
|
|
1975
|
+
private landPassed;
|
|
1976
|
+
private landUnmerged;
|
|
1977
|
+
/** The repair a conflicted task is owed next; null when repair is off, used up, or there is no isolated run to repair it in. */
|
|
1978
|
+
private nextRepair;
|
|
1979
|
+
private noRepairReason;
|
|
1980
|
+
/**
|
|
1981
|
+
* Mark which added task resolves which conflict. The resolver merges the
|
|
1982
|
+
* conflicted task's branch by hand in its own worktree; once that lands, the
|
|
1983
|
+
* conflicted task's branch is already on the integration branch and it can
|
|
1984
|
+
* land in turn — through the same merge, so a resolver that did not really
|
|
1985
|
+
* bring it along conflicts again instead of being taken at its word.
|
|
1986
|
+
*/
|
|
1987
|
+
linkConflictResolver(resolverId: string, conflictedId: string): void;
|
|
1988
|
+
private landResolved;
|
|
1989
|
+
/**
|
|
1990
|
+
* Let go of a task's worktree. `keep` leaves it and its branch for
|
|
1991
|
+
* inspection; otherwise both go. A merge still in flight finishes first, so
|
|
1992
|
+
* the worktree is never torn down underneath it.
|
|
1993
|
+
*/
|
|
1994
|
+
private releaseWorktree;
|
|
1721
1995
|
getReadyTasks(): Task[];
|
|
1996
|
+
/**
|
|
1997
|
+
* In an isolated run a dependency is met once its work is on the integration
|
|
1998
|
+
* branch, not merely once it passed: the dependent's worktree is cut from
|
|
1999
|
+
* that branch, so starting earlier would hand it a tree without the work it
|
|
2000
|
+
* depends on.
|
|
2001
|
+
*/
|
|
2002
|
+
private dependencyMet;
|
|
1722
2003
|
isBlocked(task: Task): boolean;
|
|
1723
2004
|
/**
|
|
1724
2005
|
* Cancel a running (or scheduled) task: kill its session and return it to
|
|
@@ -1728,12 +2009,10 @@ declare class TaskOrchestrator {
|
|
|
1728
2009
|
cancelTask(taskId: string): Promise<void>;
|
|
1729
2010
|
/**
|
|
1730
2011
|
* Let go of a task that is leaving the plan. A live runner is cancelled
|
|
1731
|
-
* through {@link cancelTask}
|
|
1732
|
-
* process dies; a spawn still in flight is dropped from `startingTaskIds`,
|
|
2012
|
+
* through {@link cancelTask}; a spawn still in flight just loses its attempt,
|
|
1733
2013
|
* which is what makes {@link startTask} kill the session it is about to
|
|
1734
|
-
* receive. The id's
|
|
1735
|
-
* kept for a task that no longer exists would be inherited by nothing
|
|
1736
|
-
* leaves `isRunning` reading true forever.
|
|
2014
|
+
* receive. The id's cross-attempt bookkeeping goes too — a hold or retry
|
|
2015
|
+
* count kept for a task that no longer exists would be inherited by nothing.
|
|
1737
2016
|
*/
|
|
1738
2017
|
releaseTask(taskId: string): Promise<void>;
|
|
1739
2018
|
markTaskComplete(taskId: string): Promise<void>;
|
|
@@ -1779,6 +2058,75 @@ declare class TaskOrchestrator {
|
|
|
1779
2058
|
};
|
|
1780
2059
|
tick(): Promise<void>;
|
|
1781
2060
|
private startTask;
|
|
2061
|
+
/**
|
|
2062
|
+
* A spawn whose attempt ended while it was in flight: kill what it produced
|
|
2063
|
+
* and take back the claim it made. Only the claim — whatever ended the
|
|
2064
|
+
* attempt may have decided the task since (mark complete, cancel, retry).
|
|
2065
|
+
*/
|
|
2066
|
+
private abandonSpawn;
|
|
2067
|
+
private repairPrompt;
|
|
2068
|
+
/**
|
|
2069
|
+
* The one place an attempt's working directory is decided. Async so a
|
|
2070
|
+
* per-attempt workspace (worktree isolation, #12) can be prepared here.
|
|
2071
|
+
*/
|
|
2072
|
+
private resolveAttemptCwd;
|
|
2073
|
+
private tell;
|
|
2074
|
+
private reportCopies;
|
|
2075
|
+
/**
|
|
2076
|
+
* Open a run if none is: decide once, at its start, whether it executes in
|
|
2077
|
+
* worktrees. `resume` is what a dirty tree parks until the user chooses how
|
|
2078
|
+
* to go on. Resolves false when the run did not start.
|
|
2079
|
+
*/
|
|
2080
|
+
private openRun;
|
|
2081
|
+
/**
|
|
2082
|
+
* Whether the run in force, or else the next one, gives each task its own
|
|
2083
|
+
* worktrees, and of which repo group — what the planner is told, since it
|
|
2084
|
+
* decides whether tasks on the same file have to be ordered and which shared
|
|
2085
|
+
* paths two tasks must not edit at once. A tree that would block counts as
|
|
2086
|
+
* not isolating: the user may yet run without isolation, and ordering is
|
|
2087
|
+
* the safe rule then.
|
|
2088
|
+
*/
|
|
2089
|
+
plannerIsolation(): Promise<IsolatedExecution>;
|
|
2090
|
+
private decideRun;
|
|
2091
|
+
private activate;
|
|
2092
|
+
/** What earlier runs left merged in the group goes; a failure here is worth a word, never a stopped run. */
|
|
2093
|
+
private sweep;
|
|
2094
|
+
/**
|
|
2095
|
+
* The plan's run carries on while anything has landed on its integration
|
|
2096
|
+
* branch: a resumed plan's dependents must start from a tip that holds their
|
|
2097
|
+
* predecessors' work, and a fresh branch from the checked-out commit does not.
|
|
2098
|
+
*/
|
|
2099
|
+
private continuableRun;
|
|
2100
|
+
/**
|
|
2101
|
+
* A run with nothing landed holds only superseded attempts, so it goes whole.
|
|
2102
|
+
* One that cannot be continued for another reason — it ran from a different
|
|
2103
|
+
* workspace path — keeps its integration branch in each repo that has not
|
|
2104
|
+
* merged it: only the user gives landed work up.
|
|
2105
|
+
*/
|
|
2106
|
+
private mintRun;
|
|
2107
|
+
/** Close the open run. An isolated one hands its integration branch over for review. */
|
|
2108
|
+
private closeRun;
|
|
2109
|
+
/**
|
|
2110
|
+
* Replay the start a dirty tree turned away. `stash` puts the user's tracked
|
|
2111
|
+
* changes on the git stash first, so the run isolates; `shared` runs this one
|
|
2112
|
+
* run in the workspace root, knowingly.
|
|
2113
|
+
*/
|
|
2114
|
+
continueBlockedRun(how: 'stash' | 'shared'): Promise<void>;
|
|
2115
|
+
/**
|
|
2116
|
+
* The one way an attempt ends. Dropping the record is itself what
|
|
2117
|
+
* invalidates a spawn still in flight ({@link startTask} kills the session
|
|
2118
|
+
* it receives for an attempt that is no longer current).
|
|
2119
|
+
*
|
|
2120
|
+
* A user interruption also bumps the verifier's generation *before* stopping
|
|
2121
|
+
* the runner: some runners (e.g. tmux) fire onExit synchronously from
|
|
2122
|
+
* stop(), and if that exit reaches VerdictEngine under the still-valid
|
|
2123
|
+
* generation it delivers a verdict that marks the task 'completed' for one
|
|
2124
|
+
* tick — long enough for the scheduler to start a dependent task. A verdict
|
|
2125
|
+
* leaves the runner up so its terminal stays readable, and stop/load reset
|
|
2126
|
+
* the whole verifier themselves.
|
|
2127
|
+
*/
|
|
2128
|
+
private endAttempt;
|
|
2129
|
+
private endAllAttempts;
|
|
1782
2130
|
}
|
|
1783
2131
|
|
|
1784
2132
|
/**
|
|
@@ -1821,6 +2169,8 @@ interface ModifyDuringExecutionRequest {
|
|
|
1821
2169
|
runnerModes?: Record<RunnerId, RunnerModeInfo[]>;
|
|
1822
2170
|
autonomousDefault?: boolean;
|
|
1823
2171
|
perRunnerAllowlist?: Partial<Record<RunnerId, string[]>>;
|
|
2172
|
+
/** Where the run in force puts each task (ADR-0013, ADR-0014). */
|
|
2173
|
+
isolatedExecution?: IsolatedExecution;
|
|
1824
2174
|
}
|
|
1825
2175
|
interface ModifyDuringExecutionResult {
|
|
1826
2176
|
pendingTasks: Task[];
|
|
@@ -2333,6 +2683,39 @@ declare function mapAgentTool(name: string): MappedTool;
|
|
|
2333
2683
|
*/
|
|
2334
2684
|
declare function normalizeAgentArgs(tool: ResearchToolType, args: Record<string, unknown>): Record<string, unknown>;
|
|
2335
2685
|
|
|
2686
|
+
/**
|
|
2687
|
+
* A conversation edit (rewind, fork) the conversation refused because the
|
|
2688
|
+
* request itself is wrong — no such message, nothing to fork. Transport-agnostic
|
|
2689
|
+
* like `PlanEditError`: a route maps it to a status, core carries none.
|
|
2690
|
+
*/
|
|
2691
|
+
declare class ConversationEditError extends Error {
|
|
2692
|
+
constructor(message: string);
|
|
2693
|
+
}
|
|
2694
|
+
/**
|
|
2695
|
+
* Refused because a planner turn is in flight. Distinct from a bad request:
|
|
2696
|
+
* the same call succeeds once the turn settles, and the turn would otherwise
|
|
2697
|
+
* append its reply to a transcript that no longer holds the message it
|
|
2698
|
+
* answers.
|
|
2699
|
+
*/
|
|
2700
|
+
declare class ConversationBusyError extends ConversationEditError {
|
|
2701
|
+
constructor(operation: string);
|
|
2702
|
+
}
|
|
2703
|
+
/** A user message a rewind can fork the conversation from just before. */
|
|
2704
|
+
interface RewindTarget {
|
|
2705
|
+
/** Position in the transcript — what {@link PlannerConversation.cloneBefore} takes. */
|
|
2706
|
+
index: number;
|
|
2707
|
+
preview: string;
|
|
2708
|
+
/** The whole message — the preview cuts it to one line, and a surface confirming the rewind quotes it. */
|
|
2709
|
+
content: string;
|
|
2710
|
+
timestamp: string;
|
|
2711
|
+
}
|
|
2712
|
+
/** What a compaction left behind. */
|
|
2713
|
+
interface ConversationCompaction {
|
|
2714
|
+
summary: string;
|
|
2715
|
+
/** Transcript entries kept verbatim after the summary entry. */
|
|
2716
|
+
keptMessages: number;
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2336
2719
|
declare const BUILTIN_SKILL_NAMES: readonly ["grilling", "to-spec", "improve-codebase-architecture"];
|
|
2337
2720
|
interface SkillMetadata {
|
|
2338
2721
|
name: string;
|
|
@@ -2423,6 +2806,16 @@ declare function resolveSkillInvocation(text: string, skillsService: Pick<Skills
|
|
|
2423
2806
|
* settings (tdd, verification) are read live via the `settings` callback so a toggle
|
|
2424
2807
|
* between generate and execute takes effect.
|
|
2425
2808
|
*/
|
|
2809
|
+
/** Where a fork landed: the new session's id, and what adopting it needs. */
|
|
2810
|
+
interface ConversationFork {
|
|
2811
|
+
sessionId: string;
|
|
2812
|
+
goal: string;
|
|
2813
|
+
workspace: string;
|
|
2814
|
+
}
|
|
2815
|
+
/** A fork made by a rewind, and the full text of the message it was made just before. */
|
|
2816
|
+
interface ConversationRewind extends ConversationFork {
|
|
2817
|
+
rewoundMessage: string;
|
|
2818
|
+
}
|
|
2426
2819
|
interface SessionDeps {
|
|
2427
2820
|
config: IConfig;
|
|
2428
2821
|
notifications: INotification;
|
|
@@ -2434,6 +2827,8 @@ interface SessionDeps {
|
|
|
2434
2827
|
fsAdapter: IFileSystem;
|
|
2435
2828
|
/** Emits plan-lifecycle events to the surface. Transport-agnostic. */
|
|
2436
2829
|
broadcast: SessionBroadcaster;
|
|
2830
|
+
/** Where {@link SessionNotice}s go, for a host whose `notifications` are not seen by the user. */
|
|
2831
|
+
onNotice?: (notice: SessionNotice) => void;
|
|
2437
2832
|
/** Shared across sessions — sole producer of model catalogs and routing lists. */
|
|
2438
2833
|
modelResolver: ModelResolver;
|
|
2439
2834
|
/** Live runtime settings (tdd, verification). Read at each operation that needs them. */
|
|
@@ -2457,6 +2852,17 @@ interface SessionDeps {
|
|
|
2457
2852
|
* over the session's workspace root.
|
|
2458
2853
|
*/
|
|
2459
2854
|
skillsService?: SkillsService;
|
|
2855
|
+
/**
|
|
2856
|
+
* Where a task's output and final answer are read. Defaults to the agents'
|
|
2857
|
+
* own transcripts under the user's home; tests inject one that never
|
|
2858
|
+
* touches the disk.
|
|
2859
|
+
*/
|
|
2860
|
+
taskOutput?: TaskOutputSource;
|
|
2861
|
+
/**
|
|
2862
|
+
* Git worktree isolation (ADR-0013). Defaults to git itself, gated by
|
|
2863
|
+
* `config.worktreeIsolation`; tests inject `FakeWorktreeIsolation`.
|
|
2864
|
+
*/
|
|
2865
|
+
isolation?: IWorktreeIsolation;
|
|
2460
2866
|
}
|
|
2461
2867
|
/**
|
|
2462
2868
|
* The per-session execution stack — deepened from a wiring bag into the
|
|
@@ -2486,6 +2892,7 @@ declare class Session {
|
|
|
2486
2892
|
private goal;
|
|
2487
2893
|
private workspace;
|
|
2488
2894
|
private broadcast;
|
|
2895
|
+
private onNotice?;
|
|
2489
2896
|
private modelResolver;
|
|
2490
2897
|
private fsAdapter;
|
|
2491
2898
|
private approvals;
|
|
@@ -2498,6 +2905,7 @@ declare class Session {
|
|
|
2498
2905
|
private readonly hostSessionId?;
|
|
2499
2906
|
private currentSessionId;
|
|
2500
2907
|
private readonly skillsService;
|
|
2908
|
+
private readonly conversation;
|
|
2501
2909
|
constructor(deps: SessionDeps);
|
|
2502
2910
|
/**
|
|
2503
2911
|
* The planner transport for the provider configured *right now* (ADR-0009).
|
|
@@ -2531,6 +2939,7 @@ declare class Session {
|
|
|
2531
2939
|
get planTasks(): Task[];
|
|
2532
2940
|
private attachObserver;
|
|
2533
2941
|
private buildObserver;
|
|
2942
|
+
private broadcastStatus;
|
|
2534
2943
|
private translateProgress;
|
|
2535
2944
|
/** Persists PlanStore state to disk. PlanStore is the single authority;
|
|
2536
2945
|
* LegacyPlanState.tasks is populated only here, at persist time. */
|
|
@@ -2541,8 +2950,8 @@ declare class Session {
|
|
|
2541
2950
|
* A new plan starts from zero: drop the live planner conversation and every
|
|
2542
2951
|
* task, log, and queued message left over from a previous plan on this
|
|
2543
2952
|
* Session. Without this, a long-lived Session (VS Code hosts exactly one)
|
|
2544
|
-
* leaks the previous session's tasks into
|
|
2545
|
-
* is told they are the CURRENT plan and re-presents them as its draft.
|
|
2953
|
+
* leaks the previous session's tasks into the per-turn plan block — the
|
|
2954
|
+
* model is told they are the CURRENT plan and re-presents them as its draft.
|
|
2546
2955
|
*/
|
|
2547
2956
|
private beginFreshPlan;
|
|
2548
2957
|
/**
|
|
@@ -2611,8 +3020,8 @@ declare class Session {
|
|
|
2611
3020
|
generatePlan(goal: string, runners: RunnerId[], options?: GeneratePlanOptions): Promise<LegacyPlanState>;
|
|
2612
3021
|
/**
|
|
2613
3022
|
* Kick off the planner conversation (ADR-0002): research + the first planner
|
|
2614
|
-
* message. The
|
|
2615
|
-
*
|
|
3023
|
+
* message. The conversation itself — transcript, live model context, turn
|
|
3024
|
+
* settlement — is {@link PlannerConversation}'s; the Session hosts it.
|
|
2616
3025
|
*/
|
|
2617
3026
|
startPlanning(goal: string, runners: RunnerId[], options?: GeneratePlanOptions): Promise<LegacyPlanState>;
|
|
2618
3027
|
/**
|
|
@@ -2621,69 +3030,31 @@ declare class Session {
|
|
|
2621
3030
|
*/
|
|
2622
3031
|
continueConversation(userMessage: string, options?: GeneratePlanOptions): Promise<LegacyPlanState>;
|
|
2623
3032
|
/**
|
|
2624
|
-
*
|
|
2625
|
-
*
|
|
2626
|
-
*
|
|
2627
|
-
*
|
|
2628
|
-
*
|
|
2629
|
-
* coding-agent subprocess can only be reached this way.
|
|
2630
|
-
*
|
|
2631
|
-
* Draining here — outside {@link repairLoop} — is what keeps reads free of
|
|
2632
|
-
* the repair budget. A planner that looks a task up and *then* fumbles its
|
|
2633
|
-
* ops JSON still gets its two corrective retries; charging it for the read
|
|
2634
|
-
* would cost it the chance to fix the edit.
|
|
2635
|
-
*/
|
|
2636
|
-
private drainTaskQueries;
|
|
2637
|
-
/**
|
|
2638
|
-
* Render one read out of live state. Never persisted to the transcript: the
|
|
2639
|
-
* detail is context for the planner's next reply, and re-sending it on every
|
|
2640
|
-
* later turn is exactly the cost this channel exists to avoid.
|
|
2641
|
-
*/
|
|
2642
|
-
private taskQueryAnswer;
|
|
2643
|
-
/**
|
|
2644
|
-
* Drive a planner turn to a persisted, broadcast outcome. Task edits apply
|
|
2645
|
-
* atomically; validation failures are fed back to the model for up to 2
|
|
2646
|
-
* silent retries, then surfaced as a message with the plan untouched. The
|
|
2647
|
-
* first turn (startPlanning) and every later turn route through here — one
|
|
2648
|
-
* path, not two.
|
|
3033
|
+
* Copy this conversation and its task list into a new persisted session and
|
|
3034
|
+
* answer its id. This session is untouched — not even its live planner
|
|
3035
|
+
* context, so the original carries on exactly where it was. The fork holds
|
|
3036
|
+
* no run (see {@link forkPlanState}); a host adopts it like any saved
|
|
3037
|
+
* session, and its first message replays the copied transcript.
|
|
2649
3038
|
*/
|
|
2650
|
-
|
|
3039
|
+
forkConversation(): ConversationFork;
|
|
2651
3040
|
/**
|
|
2652
|
-
*
|
|
2653
|
-
*
|
|
2654
|
-
*
|
|
2655
|
-
*
|
|
2656
|
-
*
|
|
2657
|
-
*
|
|
2658
|
-
* Built from the allowlist-filtered view (`filterModelsForPrompt`), the same
|
|
2659
|
-
* one the system prompt used — a restricted allowlist stays a hard bound on
|
|
2660
|
-
* every turn, not just the first. {@link models} itself is never
|
|
2661
|
-
* filtered: `coerceAssignments` needs the full discovered catalog alongside
|
|
2662
|
-
* the allowlist to resolve labels and clamp effort to real variants.
|
|
2663
|
-
*
|
|
2664
|
-
* Reads `this.plan.runners` live, so a runner admitted mid-session by a
|
|
2665
|
-
* retarget (`admitRunner`) is filtered and shown like every other — there is
|
|
2666
|
-
* no separate "originally selected" list to fall stale.
|
|
3041
|
+
* Fork the conversation from just before a user message (a transcript
|
|
3042
|
+
* position from {@link rewindTargets}): the fork holds everything said
|
|
3043
|
+
* before it and the current task list, like {@link forkConversation}, and
|
|
3044
|
+
* this session keeps its whole history. The message's full text comes back
|
|
3045
|
+
* so a surface can offer it for resending.
|
|
2667
3046
|
*/
|
|
2668
|
-
|
|
3047
|
+
rewindConversation(userMessageIndex: number): ConversationRewind;
|
|
3048
|
+
private saveFork;
|
|
2669
3049
|
/**
|
|
2670
|
-
*
|
|
2671
|
-
*
|
|
2672
|
-
*
|
|
2673
|
-
* are
|
|
3050
|
+
* Condense the conversation on the user's say-so: a hidden planner turn
|
|
3051
|
+
* summarises it, and the summary replaces everything but the last two
|
|
3052
|
+
* exchanges. Conversation only — the tasks, and any run
|
|
3053
|
+
* executing them, are untouched. Atomic: a failed or stopped turn changes
|
|
3054
|
+
* nothing.
|
|
2674
3055
|
*/
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
private applyTaskOpsTurn;
|
|
2678
|
-
/**
|
|
2679
|
-
* Resume a persisted dialogue onto a fresh AI-service conversation — either
|
|
2680
|
-
* because the in-memory one is gone (session reload, extension restart), or
|
|
2681
|
-
* because {@link continueConversation} found it stale against the planner
|
|
2682
|
-
* config now in effect (a harness planner's model/effort switched mid-chat).
|
|
2683
|
-
* The saved transcript seeds the new conversation; no LLM call happens
|
|
2684
|
-
* before the user's message is sent.
|
|
2685
|
-
*/
|
|
2686
|
-
private resumeConversation;
|
|
3056
|
+
compactConversation(signal?: AbortSignal): Promise<ConversationCompaction>;
|
|
3057
|
+
rewindTargets(): RewindTarget[];
|
|
2687
3058
|
/** Whether the planner conversation is live (started and not yet committed to a plan). */
|
|
2688
3059
|
get isConversationActive(): boolean;
|
|
2689
3060
|
/**
|
|
@@ -2695,10 +3066,22 @@ declare class Session {
|
|
|
2695
3066
|
* bare /unknown through to be mis-resolved.
|
|
2696
3067
|
*/
|
|
2697
3068
|
private resolveSkillInvocation;
|
|
2698
|
-
/**
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
3069
|
+
/**
|
|
3070
|
+
* The one place planning discovers what it may draw from: the runners'
|
|
3071
|
+
* models (cached for later effort clamping), their modes, and the settings
|
|
3072
|
+
* in force. `filteredModels` is the allowlisted view a prompt may show;
|
|
3073
|
+
* `modelsByRunner` stays whole because coercion needs real labels and variants.
|
|
3074
|
+
*/
|
|
3075
|
+
private plannerCatalog;
|
|
3076
|
+
private conversationOpening;
|
|
3077
|
+
/**
|
|
3078
|
+
* Load planner-produced tasks, coerced to the allowlist read live — it may
|
|
3079
|
+
* have changed since planning started. An edit on an armed scheduler is
|
|
3080
|
+
* reconciled rather than reloaded: `loadPlan` clears the on-hold set and the
|
|
3081
|
+
* review approval, so a task the user cancelled would be re-armed and
|
|
3082
|
+
* re-spawned by the re-tick that follows.
|
|
3083
|
+
*/
|
|
3084
|
+
private adoptPlannerTasks;
|
|
2702
3085
|
/**
|
|
2703
3086
|
* PRD mode: when the planner writes the full markdown PRD, save it to
|
|
2704
3087
|
* .scratch/<slug>/PRD.md (Matt Pocock to-prd convention) and keep it on the plan.
|
|
@@ -2724,6 +3107,43 @@ declare class Session {
|
|
|
2724
3107
|
get queuedCount(): number;
|
|
2725
3108
|
getTask(taskId: string): Task | undefined;
|
|
2726
3109
|
get isReviewApproved(): boolean;
|
|
3110
|
+
/** Replay a run a dirty tree blocked, after stashing the tracked changes. */
|
|
3111
|
+
continueWithStash(): Promise<void>;
|
|
3112
|
+
/** Replay a run a dirty tree blocked, in the workspace root, for this run only. */
|
|
3113
|
+
continueWithoutIsolation(): Promise<void>;
|
|
3114
|
+
/**
|
|
3115
|
+
* Each task's isolation mark and the run's handoff, read from the run record.
|
|
3116
|
+
* The stream reports changes only; a surface that (re)connects or loads a
|
|
3117
|
+
* session asks here instead.
|
|
3118
|
+
*/
|
|
3119
|
+
isolationView(): IsolationView | null;
|
|
3120
|
+
/** The run's integration branch against its base ref, as a unified diff. */
|
|
3121
|
+
reviewRunDiff(): Promise<string>;
|
|
3122
|
+
/**
|
|
3123
|
+
* "Merge all": each repo's integration branch into whatever the user has
|
|
3124
|
+
* checked out there — every repo, or none if any cannot take it. The one
|
|
3125
|
+
* irreversible step of isolated execution, so this explicit call is the
|
|
3126
|
+
* only way it ever happens.
|
|
3127
|
+
*/
|
|
3128
|
+
mergeRun(): Promise<IsolationMergeResult>;
|
|
3129
|
+
/** Remove the run's worktrees and task branches; keep its integration branch to review or merge. */
|
|
3130
|
+
cleanupRun(): Promise<void>;
|
|
3131
|
+
/**
|
|
3132
|
+
* Give the whole run up, integration branch included. The plan is not
|
|
3133
|
+
* rewritten: a task that landed there stays completed until the user says
|
|
3134
|
+
* otherwise (Mark not done), because only they know whether they kept the work.
|
|
3135
|
+
*/
|
|
3136
|
+
discardRun(): Promise<void>;
|
|
3137
|
+
private requireSettledRun;
|
|
3138
|
+
/**
|
|
3139
|
+
* The opt-in way through a merge conflict: add an AI task, on the conflicted
|
|
3140
|
+
* task's own runner and model, that merges its branch by hand in a worktree
|
|
3141
|
+
* of its own. When that task lands, the conflicted one lands through it (see
|
|
3142
|
+
* {@link TaskOrchestrator.linkConflictResolver}). The automatic answer to a
|
|
3143
|
+
* conflict is a repair, a new attempt of the same task (ADR-0015); a task is
|
|
3144
|
+
* only ever added to the plan by this call.
|
|
3145
|
+
*/
|
|
3146
|
+
resolveConflictAsTask(taskId: string): Promise<LegacyPlanState | null>;
|
|
2727
3147
|
stopExecution(): void;
|
|
2728
3148
|
/**
|
|
2729
3149
|
* The one mutation seam: every structural plan mutation runs the same
|
|
@@ -2740,7 +3160,7 @@ declare class Session {
|
|
|
2740
3160
|
* queues — so a task the edit just unblocked would sit ready and never
|
|
2741
3161
|
* start. `tick()` no-ops while the scheduler is idle, so this costs nothing
|
|
2742
3162
|
* during plain planning. The planner-driven path re-ticks in
|
|
2743
|
-
* {@link
|
|
3163
|
+
* {@link PlannerConversation} instead (`afterEdit`); it must not tick twice.
|
|
2744
3164
|
*/
|
|
2745
3165
|
private editPlan;
|
|
2746
3166
|
/**
|
|
@@ -2860,25 +3280,31 @@ declare function globalDataDir(): string;
|
|
|
2860
3280
|
*/
|
|
2861
3281
|
declare function migrateOldConfigDir(): void;
|
|
2862
3282
|
|
|
2863
|
-
type VerdictListener = (taskId: string, verdict: Verdict
|
|
3283
|
+
type VerdictListener = (taskId: string, verdict: Verdict) => void;
|
|
2864
3284
|
type CheckpointListener = (taskId: string, summary: string) => void;
|
|
2865
3285
|
/** Fires on every idleSince transition (null→timestamp on silence, timestamp→null on resume/teardown). */
|
|
2866
3286
|
type IdleListener = (taskId: string, idleSince: string | null) => void;
|
|
2867
3287
|
declare class VerdictEngine {
|
|
2868
3288
|
private markerSeen;
|
|
2869
|
-
private
|
|
2870
|
-
private
|
|
3289
|
+
private markerTails;
|
|
3290
|
+
private checkpointCarry;
|
|
2871
3291
|
private pausedSessions;
|
|
2872
3292
|
private listeners;
|
|
2873
3293
|
private checkpointListeners;
|
|
2874
3294
|
private idleListeners;
|
|
2875
3295
|
/**
|
|
2876
|
-
* Per-task generation
|
|
3296
|
+
* Per-task generation. Replaced on every watch(), clear() and verdict.
|
|
2877
3297
|
* Stale callbacks (from a prior session whose generation doesn't match
|
|
2878
3298
|
* the current one) bail out instead of delivering a verdict for the
|
|
2879
3299
|
* wrong session.
|
|
2880
3300
|
*/
|
|
2881
3301
|
private generations;
|
|
3302
|
+
/**
|
|
3303
|
+
* Generations come from one counter that {@link reset} never rewinds: a
|
|
3304
|
+
* per-task count restarted at 1 after a reset, and the next watch handed a
|
|
3305
|
+
* session that outlived the reset the same generation as its successor.
|
|
3306
|
+
*/
|
|
3307
|
+
private lastGeneration;
|
|
2882
3308
|
private idleTimers;
|
|
2883
3309
|
private idleSince;
|
|
2884
3310
|
onVerdict(listener: VerdictListener): void;
|
|
@@ -2901,12 +3327,16 @@ declare class VerdictEngine {
|
|
|
2901
3327
|
approveCheckpoint(taskId: string): void;
|
|
2902
3328
|
rejectCheckpoint(taskId: string, reason: string): void;
|
|
2903
3329
|
/**
|
|
2904
|
-
* Attach to a spawned session:
|
|
3330
|
+
* Attach to a spawned session: scan the output tail for the task's completion
|
|
2905
3331
|
* marker (delivering a verdict immediately while leaving interactive sessions
|
|
2906
3332
|
* open), scan for checkpoint markers, and on exit produce a failed verdict
|
|
2907
3333
|
* when the marker was never observed.
|
|
2908
3334
|
*/
|
|
2909
3335
|
watch(task: Task, session: ITerminalSession): void;
|
|
3336
|
+
/** Scan only the new text plus the unmatched carry, so a long run stays linear. */
|
|
3337
|
+
private scanCheckpoints;
|
|
3338
|
+
private bumpGeneration;
|
|
3339
|
+
private forget;
|
|
2910
3340
|
/** Manual "Mark complete" override: a pass verdict that bypasses evidence. */
|
|
2911
3341
|
markComplete(task: Task): Verdict;
|
|
2912
3342
|
/** Clear verification state for a task (used on retry). */
|
|
@@ -2916,6 +3346,49 @@ declare class VerdictEngine {
|
|
|
2916
3346
|
private decide;
|
|
2917
3347
|
}
|
|
2918
3348
|
|
|
3349
|
+
/**
|
|
3350
|
+
* Owns one bounded raw buffer per task attempt, fed from the attempt's
|
|
3351
|
+
* session, and reads final answers from the agent's transcript through an
|
|
3352
|
+
* injected {@link TranscriptReader}.
|
|
3353
|
+
*/
|
|
3354
|
+
declare class BufferedTaskOutputSource implements TaskOutputSource {
|
|
3355
|
+
private captures;
|
|
3356
|
+
private transcripts;
|
|
3357
|
+
private maxBufferChars;
|
|
3358
|
+
constructor(opts?: {
|
|
3359
|
+
transcripts?: TranscriptReader;
|
|
3360
|
+
maxBufferChars?: number;
|
|
3361
|
+
});
|
|
3362
|
+
attach(taskId: string, session: ITerminalSession): void;
|
|
3363
|
+
detach(taskId: string): void;
|
|
3364
|
+
reset(): void;
|
|
3365
|
+
finalText(attempt: TaskOutputAttempt, doneToken: string): Promise<string>;
|
|
3366
|
+
liveTail(taskId: string, opts: LiveTailOptions): LiveTail | null;
|
|
3367
|
+
private append;
|
|
3368
|
+
}
|
|
3369
|
+
|
|
3370
|
+
/**
|
|
3371
|
+
* Read a task's final answer from the agent's own session transcript — the
|
|
3372
|
+
* clean, structured record the agent writes about itself — instead of
|
|
3373
|
+
* reconstructing what a TUI painted (issue #16, built on #14's render).
|
|
3374
|
+
*
|
|
3375
|
+
* These stores are private and undocumented and DO rotate (OpenCode migrated
|
|
3376
|
+
* from files to SQLite mid-2026). Every reader is therefore defensive: any
|
|
3377
|
+
* missing file, unparseable line, or shape drift returns null and the caller
|
|
3378
|
+
* falls back to the terminal capture. Nothing here is a hard dependency.
|
|
3379
|
+
*
|
|
3380
|
+
* Directory and recency only narrow the candidates: with several attempts in
|
|
3381
|
+
* one cwd the newest session is whichever task finished last. A transcript is
|
|
3382
|
+
* accepted only when its content carries the task's completion marker.
|
|
3383
|
+
*/
|
|
3384
|
+
declare class HomeTranscriptReader implements TranscriptReader {
|
|
3385
|
+
private readonly home;
|
|
3386
|
+
constructor(opts?: {
|
|
3387
|
+
homeDir?: string;
|
|
3388
|
+
});
|
|
3389
|
+
finalAssistantText(query: TranscriptQuery, maxChars?: number): Promise<string | null>;
|
|
3390
|
+
}
|
|
3391
|
+
|
|
2919
3392
|
/**
|
|
2920
3393
|
* The ids a runner may actually run: the user's allowlist with the ids that
|
|
2921
3394
|
* provably belong to a *different* runner dropped. `undefined` means no
|
|
@@ -2999,9 +3472,18 @@ declare function buildResearchToolsPrompt(): string;
|
|
|
2999
3472
|
* never a task plan.
|
|
3000
3473
|
*/
|
|
3001
3474
|
declare function buildSubagentSystemPrompt(): string;
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3475
|
+
/**
|
|
3476
|
+
* Facts about who plans and where tasks will run, as opposed to the user's
|
|
3477
|
+
* mode toggles: they change what the prompt can promise, not what it asks for.
|
|
3478
|
+
*/
|
|
3479
|
+
interface ConversationVariant {
|
|
3480
|
+
/** Harness planner (ADR-0009): the agent owns its own tools and research budget. */
|
|
3481
|
+
harness?: boolean;
|
|
3482
|
+
/** 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). */
|
|
3483
|
+
isolatedExecution?: IsolatedExecution;
|
|
3484
|
+
}
|
|
3485
|
+
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;
|
|
3486
|
+
/** The one-shot planner's core rules for tasks that share the workspace root. */
|
|
3005
3487
|
declare const CORE_PLANNER_PROMPT: string;
|
|
3006
3488
|
declare function buildResearchPrompt(userGoal: string, context: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, modes?: PlannerModes): string;
|
|
3007
3489
|
declare function buildPlanWithResults(userGoal: string, context: string, researchResults: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, modes?: PlannerModes): string;
|
|
@@ -3009,7 +3491,7 @@ declare function buildModifyPlanPrompt(existingPlan: LegacyPlanState, userReques
|
|
|
3009
3491
|
declare function modelContextBlock(modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>, autonomousDefault?: boolean): string;
|
|
3010
3492
|
declare function executionLogBlock(executionLog: TaskSnapshot[]): string;
|
|
3011
3493
|
declare function pendingEditRulesBlock(): string;
|
|
3012
|
-
declare function buildModifyDuringExecutionPrompt(executionLog: TaskSnapshot[], pendingTasks: string, userMessage: string, modelsByRunner: Partial<Record<RunnerId, DiscoveredModel[]>>, runners: RunnerId[], runnerModes?: Record<RunnerId, RunnerModeInfo[]>,
|
|
3494
|
+
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;
|
|
3013
3495
|
/**
|
|
3014
3496
|
* User-message prompt for a planner-driven merge: asks the model to combine the
|
|
3015
3497
|
* selected tasks into one. Routed through the conversation loop, so the
|
|
@@ -3023,6 +3505,34 @@ declare function buildMergePrompt(taskIds: string[], tasks: Task[]): string;
|
|
|
3023
3505
|
* the user does not hand-type the parts.
|
|
3024
3506
|
*/
|
|
3025
3507
|
declare function buildSplitPrompt(taskId: string, tasks: Task[]): string;
|
|
3508
|
+
/**
|
|
3509
|
+
* Runner prompt for the opt-in task that resolves an integration conflict
|
|
3510
|
+
* (ADR-0013). The resolver's own worktree starts at the integration tip, so the
|
|
3511
|
+
* merge it performs is exactly the one that conflicted; the conflicted task
|
|
3512
|
+
* then lands through that merge. Ordewell never resolves a conflict itself.
|
|
3513
|
+
*
|
|
3514
|
+
* In a repo group (ADR-0014) the conflict in one repo rolled the task back in
|
|
3515
|
+
* all of them, so the resolver merges the branch in every repo the task
|
|
3516
|
+
* changed, not only the one that conflicted.
|
|
3517
|
+
*/
|
|
3518
|
+
declare function buildConflictResolutionPrompt(task: Task, conflict: {
|
|
3519
|
+
branch: string;
|
|
3520
|
+
repos: string[];
|
|
3521
|
+
conflictRepo?: string;
|
|
3522
|
+
}, integrationBranch: string): string;
|
|
3523
|
+
/**
|
|
3524
|
+
* Runner prompt for a conflict repair (ADR-0015): a new attempt of the
|
|
3525
|
+
* conflicted task itself, in its kept worktree, so the merge runs the other
|
|
3526
|
+
* way round from {@link buildConflictResolutionPrompt} — the integration tip
|
|
3527
|
+
* into the task's branch. Whether it worked is decided by the evidence checks
|
|
3528
|
+
* and the landing that follow, never by the agent's word.
|
|
3529
|
+
*/
|
|
3530
|
+
declare function buildConflictRepairPrompt(task: Task, conflict: {
|
|
3531
|
+
branch: string;
|
|
3532
|
+
repos: string[];
|
|
3533
|
+
conflictRepo?: string;
|
|
3534
|
+
conflictFiles?: string[];
|
|
3535
|
+
}, integrationBranch: string): string;
|
|
3026
3536
|
|
|
3027
3537
|
/**
|
|
3028
3538
|
* The one owner of "the model emitted something unusable — correct it and
|
|
@@ -3677,4 +4187,4 @@ declare class PlannerModelMemory {
|
|
|
3677
4187
|
recall(provider: string, catalog: PlannerModelCandidate[]): PlannerModelRecall;
|
|
3678
4188
|
}
|
|
3679
4189
|
|
|
3680
|
-
export { ALLOWED_PLUGIN_HOSTS, ALL_PROVIDERS, AUTO_COMMANDS, AbstractRunner, AbstractTerminalSession, ActiveTaskSession, type AgentAdapter, type AgentAdapterFactory, type AgentEvent, type AgentProcessDeps, type AgentStartOptions, AiProvider, ApprovalMode, ApprovalRequest, BUILTIN_SKILL_NAMES, BaseAiService, BaseConfig, BaseFileSystem, CLAUDE_CODE_MANIFEST, CLI_PROVIDERS, CMD_EXE_MAX_COMMAND_LINE, CORE_PLANNER_PROMPT, type CappedRows, type CheckpointListener, ClaudeCodeAdapter, CliAgentAiService, type CliAgentAiServiceDeps, CodexAdapter, type CommandClassification, CommandLineTooLongError, type CommandTier, type ComposeOptions, ConsoleLogger, ContextCollector, ConversationMessage, type ConversationRequest, type ConversationTurn, DAEMON_SUBPROTOCOL, DAEMON_TOKEN_SUBPROTOCOL_PREFIX, DiscoveredModel, EmbeddedNewlineError, type EnvAdmission, EnvConfig, type ExecFileFn, type ExecImpl, ExecutableNotFoundError, FindSymbolOptions, FsPluginStore, GIT_READONLY_SUBCOMMANDS, GeminiService, GlobOptions, type GrepInvocation, GrepOptions, type HasBinFn, HeadlessRunner, type HeadlessRunnerDeps, HeadlessSession, type IAiService, IApproval, IConfig, IFileSystem, type ILogger, type INotification, IPluginStore, ITerminalRunner, ITerminalSession, JSON_REPAIR_INSTRUCTION, type KillTreeDeps, type LaunchDeps, type LaunchPlan, LegacyPlanState, LineBuffer, type MappedTool, ModelResolver, type ModelResolverDeps, type ModifyPlanRequest, type NotificationAction, OPENCODE_MANIFEST, ORDEWELL_SETTABLE_ENV, OpenAiService, OpenCodeAdapter, type OrchestratorObserver, OrchestratorOption, PLUGIN_NAME_PATTERN, PROVIDER_CREDENTIAL_ENV, PROVIDER_DETECT_PRIORITY, PROVIDER_LABEL, PROVIDER_PRIORITY, PROVIDER_SHORT_LABEL, type PendingApproval, PendingApprovals, type PendingApprovalsOptions, PlanEditError, PlanParseError, type PlanRequest, PlanState, PlanStatus, PlanStore, Planner, type PlannerModelCandidate, type PlannerModelChoice, PlannerModelMemory, type PlannerModelRecall, type PlannerModelStore, type PlannerReplyClassification, type PlannerRuntimeToggles, type PluginSource, type PrdBlock, type PreparedLaunch, type PriorOutput, type ProbeFn, ProviderModelLists, type ProviderRegistration, type PtySize, type PtyWrapOptions, QueuedMessage, REFUSED_COMMANDS, ReadFileOpts, type RepairLoopOpts, type RepairVerdict, type ResearchChat, ResearchLogEntry, ResearchProgress, type ResearchShell, type ResearchShellDeps, ResearchToolType, type ResearchTurn, ResolveContext, type RunnerCatalog, RunnerId, RunnerInstallation, RunnerInvocation, type RunnerMode, RunnerModeInfo, RunnerPluginManifest, RunnerRegistry, type RunnerSpawnOptions, SETTINGS_ENV_ALLOWLIST, SETTINGS_ENV_REFUSED, STATE_DIR, STOPPED_TOOL_RESULT, SYMBOL_LANGUAGES, Session, SessionBroadcaster, type SessionData, type SessionDeps, type SessionMeta, type SessionPlanner, type SessionRuntimeSettings, SettingsService, type ShellDialect, type SkillInfo, type SkillMetadata, SkillsService, type SpawnSpec, StdioAgentAdapter, TASK_QUERY_ANSWER_OR_OPS, TASK_QUERY_FIELDS, TASK_QUERY_PROTOCOL, TASK_QUERY_REMINDER, TRUNCATED_PLAN_REPAIR_INSTRUCTION, Task, TaskOp, TaskOrchestrator, type TaskQuery, type TaskQueryCatalog, type TaskQueryField, TaskSnapshot, TmuxRunner, type TmuxRunnerDeps, type TokenCarriers, type ToolCall, ToolOutcome, type ToolResult, type UserSettings, Verdict, VerdictEngine, type VerdictListener, WINDOWS_MAX_COMMAND_LINE, type WorkspaceCheckDeps, WorkspaceNotAProjectError, WorkspaceNotFoundError, type WorkspaceProjectCheckDeps, admitSettingsEnv, applyHeadLimit, assertInstallablePluginUrl, assertPlainPluginName, assertWorkspaceExists, assertWorkspaceIsProject, augmentPromptWithPriorOutputs, augmentedPath, bearerHeaderValue, buildConversationSystemPrompt, buildFallbackGrepArgs, buildGlobArgs, buildGrepArgs, buildMergePrompt, buildModifyDuringExecutionPrompt, buildModifyPlanPrompt, buildPlanWithResults, buildResearchPrompt, buildResearchToolsPrompt, buildRunnerInvocation, buildShellInvocation, buildSplitPrompt, buildSubagentSystemPrompt, clampThinkingEffort, classifyCommand, classifyPlannerReply, classifyPluginSource, clearAugmentedPathCache, clearDaemonToken, clearResearchShellCache, clearState, clipboardCopyCommand, coerceAssignments, collectDirectDependencyOutputs, composeAugmentedPrompt, configuredProviders, createAiService, createSkillsService, daemonTokenPath, defaultLogger, definitionPattern, deleteSession, discoverGeminiModels, effectiveAllowlist, ensureDir, ensureStateDirIgnored, executionLogBlock, extractPrdBlock, extractPresentedToken, filterFallbackByAnchoredInclude, filterModelsForPrompt, formatSearchOutput, generatePlanWithRepair, getLatestSession, getProviderMeta, getSettingsPath, getStateDir, globalDataDir, grantScopeFor, hasTmux, includeGlobFor, isCliProvider, isExecutableResolved, isOpenAiProvider, isPlainPluginName, isValidManifest, killTree, languageForId, listSessions, loadSession, loadSessionPlanState, loadState, mapAgentTool, migrateOldConfigDir, mintDaemonToken, mintSessionId, modelContextBlock, modifyValidationFeedback, normalizeAgentArgs, normalizeGeminiModel, parseTaskQueryJson, pendingEditRulesBlock, planDirectLaunch, planShellLaunch, posixShellQuote, prefixModelId, providerForRunner, reEmitPlanPrompt, reEmitTaskOpsPrompt, reEmitTaskQueryPrompt, readDaemonToken, referencePattern, renderPlanMap, renderPriorOutputs, renderTaskQueryAnswer, repairLoop, researchShellWarning, researchToolsPath, resolveArgs, resolvePluginInstallDir, resolveProviderFromPrefix, resolveResearchShell, resolveSkillInvocation, resolveWithin, retargetTaskRunner, runnerAssignment, runnerForProvider, sanitizeSlug, savePrdMarkdown, saveSession, saveState, sessionRuntimeSettings, stateExists, stripAnsi, stripModelPrefix, summarizeOutput, taskOpsRejectedPrompt, taskQuerySignature, textHasTaskQuery, tmuxSessionName, tmuxSocketName, tmuxWindowName, tokenSubprotocols, tokensMatch, truncatedPlanReEmitPrompt, wellKnownBinDirs, windowsCommandLine, withPath, wrapWithPty };
|
|
4190
|
+
export { ALLOWED_PLUGIN_HOSTS, ALL_PROVIDERS, AUTO_COMMANDS, AbstractRunner, AbstractTerminalSession, ActiveTaskSession, type AgentAdapter, type AgentAdapterFactory, type AgentEvent, type AgentProcessDeps, type AgentStartOptions, AiProvider, ApprovalMode, ApprovalRequest, BUILTIN_SKILL_NAMES, BaseAiService, BaseConfig, BaseFileSystem, BufferedTaskOutputSource, CLAUDE_CODE_MANIFEST, CLI_PROVIDERS, CMD_EXE_MAX_COMMAND_LINE, CORE_PLANNER_PROMPT, type CappedRows, type CheckpointListener, ClaudeCodeAdapter, CliAgentAiService, type CliAgentAiServiceDeps, CodexAdapter, type CommandClassification, CommandLineTooLongError, type CommandTier, type ComposeOptions, ConsoleLogger, ContextCollector, ConversationBusyError, type ConversationCompaction, ConversationEditError, type ConversationFork, ConversationMessage, type ConversationRequest, type ConversationRewind, type ConversationTurn, type ConversationVariant, DAEMON_SUBPROTOCOL, DAEMON_TOKEN_SUBPROTOCOL_PREFIX, DiscoveredModel, EmbeddedNewlineError, type EnvAdmission, EnvConfig, type ExecFileFn, type ExecImpl, ExecutableNotFoundError, FindSymbolOptions, FsPluginStore, GIT_READONLY_SUBCOMMANDS, GeminiService, type GitExecFn, GlobOptions, type GrepInvocation, GrepOptions, type HasBinFn, HeadlessRunner, type HeadlessRunnerDeps, HeadlessSession, HomeTranscriptReader, type IAiService, IApproval, IConfig, IFileSystem, type ILogger, type INotification, IPluginStore, ITerminalRunner, ITerminalSession, IWorktreeIsolation, IsolationHandoff, IsolationLandedTask, IsolationMergeResult, IsolationView, JSON_REPAIR_INSTRUCTION, type KillTreeDeps, type LaunchDeps, type LaunchPlan, LegacyPlanState, LineBuffer, type LiveOutputLookup, type LiveTail, type LiveTailOptions, type MappedTool, ModelResolver, type ModelResolverDeps, type ModifyPlanRequest, type NotificationAction, OPENCODE_MANIFEST, ORDEWELL_SETTABLE_ENV, OUTPUT_LINES_DEFAULT, OUTPUT_LINES_MAX, OpenAiService, OpenCodeAdapter, type OrchestratorObserver, OrchestratorOption, 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, PlanState, PlanStatus, PlanStore, Planner, type PlannerModelCandidate, type PlannerModelChoice, PlannerModelMemory, type PlannerModelRecall, type PlannerModelStore, type PlannerReplyClassification, type PlannerRuntimeToggles, type PluginSource, type PrdBlock, type PreparedLaunch, type PriorOutput, type ProbeFn, ProviderModelLists, type ProviderRegistration, type PtySize, type PtyWrapOptions, QueuedMessage, REFUSED_COMMANDS, ReadFileOpts, type RepairLoopOpts, type RepairVerdict, RepoGroupLayout, type ResearchChat, ResearchLogEntry, ResearchProgress, type ResearchShell, type ResearchShellDeps, ResearchToolType, type ResearchTurn, ResolveContext, type RewindTarget, type RunnerCatalog, RunnerId, RunnerInstallation, RunnerInvocation, type RunnerMode, RunnerModeInfo, RunnerPluginManifest, RunnerRegistry, type RunnerSpawnOptions, SETTINGS_ENV_ALLOWLIST, SETTINGS_ENV_REFUSED, STATE_DIR, STOPPED_TOOL_RESULT, SYMBOL_LANGUAGES, Session, SessionBroadcaster, type SessionData, type SessionDeps, type SessionMeta, SessionNotice, type SessionPlanner, type SessionRuntimeSettings, SettingsService, type ShellDialect, type SkillInfo, type SkillMetadata, SkillsService, type SpawnSpec, StdioAgentAdapter, 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, TaskIsolation, TaskOp, TaskOrchestrator, type TaskOutputAttempt, type TaskOutputSource, type TaskQuery, type TaskQueryCatalog, type TaskQueryField, TaskSnapshot, TmuxRunner, type TmuxRunnerDeps, type TokenCarriers, type ToolCall, ToolOutcome, type ToolResult, type TranscriptQuery, type TranscriptReader, type UserSettings, Verdict, VerdictEngine, type VerdictListener, WINDOWS_MAX_COMMAND_LINE, type WorkspaceCheckDeps, WorkspaceNotAProjectError, WorkspaceNotFoundError, type WorkspaceProjectCheckDeps, type WorktreeIsolationDeps, admitSettingsEnv, applyHeadLimit, assertInstallablePluginUrl, assertPlainPluginName, assertWorkspaceExists, assertWorkspaceIsProject, augmentPromptWithPriorOutputs, augmentedPath, bearerHeaderValue, buildConflictRepairPrompt, buildConflictResolutionPrompt, buildConversationSystemPrompt, buildFallbackGrepArgs, buildGlobArgs, buildGrepArgs, buildMergePrompt, buildModifyDuringExecutionPrompt, buildModifyPlanPrompt, buildPlanWithResults, buildResearchPrompt, buildResearchToolsPrompt, buildRunnerInvocation, buildShellInvocation, buildSplitPrompt, buildSubagentSystemPrompt, clampThinkingEffort, classifyCommand, classifyPlannerReply, classifyPluginSource, clearAugmentedPathCache, clearDaemonToken, clearResearchShellCache, clearState, clipboardCopyCommand, coerceAssignments, collectDirectDependencyOutputs, composeAugmentedPrompt, configuredProviders, createAiService, createSkillsService, createWorktreeIsolation, daemonTokenPath, defaultLogger, definitionPattern, deleteSession, describeMergeResult, discoverGeminiModels, effectiveAllowlist, ensureDir, ensureStateDirIgnored, executionLogBlock, extractPrdBlock, extractPresentedToken, filterFallbackByAnchoredInclude, filterModelsForPrompt, formatSearchOutput, generatePlanWithRepair, getLatestSession, getProviderMeta, getSettingsPath, getStateDir, globalDataDir, grantScopeFor, hasTmux, includeGlobFor, isCliProvider, isExecutableResolved, isOpenAiProvider, isPlainPluginName, isValidManifest, killTree, languageForId, listSessions, loadSession, loadSessionPlanState, loadState, mapAgentTool, migrateOldConfigDir, mintDaemonToken, mintSessionId, modelContextBlock, modifyValidationFeedback, normalizeAgentArgs, normalizeGeminiModel, parseTaskQueryJson, pendingEditRulesBlock, planDirectLaunch, planShellLaunch, posixShellQuote, prefixModelId, providerForRunner, reEmitPlanPrompt, reEmitTaskOpsPrompt, reEmitTaskQueryPrompt, readDaemonToken, referencePattern, renderPlanMap, renderPriorOutputs, renderTaskQueryAnswer, repairLoop, researchShellWarning, researchToolsPath, resolveArgs, resolvePluginInstallDir, resolveProviderFromPrefix, resolveResearchShell, resolveSkillInvocation, resolveWithin, retargetTaskRunner, runnerAssignment, runnerForProvider, sanitizeSlug, savePrdMarkdown, saveSession, saveState, sessionRuntimeSettings, stateExists, stripAnsi, stripModelPrefix, summarizeOutput, taskOpsRejectedPrompt, taskQuerySignature, textHasTaskQuery, tmuxSessionName, tmuxSocketName, tmuxWindowName, tokenSubprotocols, tokensMatch, truncatedPlanReEmitPrompt, wellKnownBinDirs, windowsCommandLine, withPath, wrapWithPty };
|