@ordewell/core 0.11.3 → 0.12.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/AUTHORS.md +3 -1
- package/dist/{ModeResolver-DyXeZ9ib.d.ts → ModeResolver-B64aUZXJ.d.ts} +1 -1
- package/dist/{ModeResolver-BDAgouuE.d.mts → ModeResolver-CA2fUU9h.d.mts} +1 -1
- package/dist/{Task-BL4Idm9r.d.mts → Task-CxGgN6I0.d.mts} +801 -39
- package/dist/{Task-BL4Idm9r.d.ts → Task-CxGgN6I0.d.ts} +801 -39
- package/dist/{chunk-YAFNYNFX.mjs → chunk-2IFKPYPO.mjs} +453 -17
- package/dist/chunk-2IFKPYPO.mjs.map +1 -0
- package/dist/{chunk-MYXMIVWA.mjs → chunk-FX33UKAD.mjs} +8 -6
- package/dist/chunk-FX33UKAD.mjs.map +1 -0
- package/dist/{chunk-QTZ5XTBY.mjs → chunk-PKJTN2PD.mjs} +458 -13
- package/dist/chunk-PKJTN2PD.mjs.map +1 -0
- package/dist/{chunk-7WNLN63J.mjs → chunk-RZ23BMVR.mjs} +599 -124
- package/dist/chunk-RZ23BMVR.mjs.map +1 -0
- package/dist/chunk-UDUATSCJ.mjs +48 -0
- package/dist/chunk-UDUATSCJ.mjs.map +1 -0
- package/dist/{IRunner-DOMtDTVt.d.ts → eventStore-CTCSKS9E.d.ts} +976 -145
- package/dist/{IRunner-ihalYfTo.d.mts → eventStore-CcB8yELZ.d.mts} +976 -145
- package/dist/index.d.mts +905 -164
- package/dist/index.d.ts +905 -164
- package/dist/index.js +12496 -3308
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10830 -2919
- package/dist/index.mjs.map +1 -1
- package/dist/parsing.d.mts +2 -2
- package/dist/parsing.d.ts +2 -2
- package/dist/parsing.js +277 -21
- package/dist/parsing.js.map +1 -1
- package/dist/parsing.mjs +3 -3
- package/dist/plan-utils.d.mts +8 -5
- package/dist/plan-utils.d.ts +8 -5
- package/dist/plan-utils.js +262 -33
- package/dist/plan-utils.js.map +1 -1
- package/dist/plan-utils.mjs +39 -3
- package/dist/{runSettingsText-DVOd7vKC.d.ts → runSettingsText-DFVpe6aU.d.mts} +1996 -895
- package/dist/{runSettingsText-BuLVBlXS.d.mts → runSettingsText-lKLDsyli.d.ts} +1996 -895
- package/dist/testing.d.mts +99 -4
- package/dist/testing.d.ts +99 -4
- package/dist/testing.js +213 -8
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +193 -8
- package/dist/testing.mjs.map +1 -1
- package/docker/task.Dockerfile +22 -0
- package/package.json +3 -1
- package/skills/diagnose/SKILL.md +2 -2
- package/skills/explore/SKILL.md +1 -1
- package/dist/chunk-7WNLN63J.mjs.map +0 -1
- package/dist/chunk-MYXMIVWA.mjs.map +0 -1
- package/dist/chunk-QTZ5XTBY.mjs.map +0 -1
- package/dist/chunk-YAFNYNFX.mjs.map +0 -1
|
@@ -1,119 +1,7 @@
|
|
|
1
1
|
import { ChildProcess } from 'child_process';
|
|
2
|
-
import { aS as Task,
|
|
2
|
+
import { aB as PlannerAllowlist, b3 as RunnerId, az as PlanStatus, aj as LegacyPlanState, ay as PlanState, bk as SkillsService, bf as SkillInfo, aS as RepoGroupLayout, T as IWorktreeIsolation, ab as IsolationRun, X as IsolationHandoff, ax as PlanIsolation, ac as IsolationTaskRecord, bt as TaskIsolation, ag as IsolationView, a6 as IsolationRemoval, bp as Task, aH as PrepareIntent, aL as PreviousWork, J as HandoffCommit, a3 as IsolationOutcome, aP as RepairEvidence, bE as TreeSnapshot, bq as TaskDiffRead, br as TaskDiffResult, a2 as IsolationMergeResult, ai as LandedWork, b0 as RevertWatch, a9 as IsolationRevertResult, bG as UsageRecord, bm as SubagentOutcome, b4 as RunnerSessionCost, p as DiscoveredModel, bJ as VerificationCheck, bz as TaskSkillSnapshot, b7 as ScriptBody, I as HandoffCheck } from './Task-CxGgN6I0.js';
|
|
3
3
|
import { z } from 'zod/v4';
|
|
4
4
|
|
|
5
|
-
/** A script task's time limit when it sets none. */
|
|
6
|
-
declare const DEFAULT_SCRIPT_TIMEOUT_MS: number;
|
|
7
|
-
/** What a script task runs, its time limit filled in. */
|
|
8
|
-
type ScriptBody =
|
|
9
|
-
/** Argument vectors run in order with no shell, stopping at the first that fails. */
|
|
10
|
-
{
|
|
11
|
-
commands: string[][];
|
|
12
|
-
timeoutMs: number;
|
|
13
|
-
}
|
|
14
|
-
/** One script, run by the research shell's interpreter. */
|
|
15
|
-
| {
|
|
16
|
-
script: string;
|
|
17
|
-
timeoutMs: number;
|
|
18
|
-
};
|
|
19
|
-
type BodyFields = Pick<Task, 'type' | 'commands' | 'script' | 'timeoutMs'>;
|
|
20
|
-
/** The body a script task runs; null for any other task, or one whose body the plan's rules refuse. */
|
|
21
|
-
declare function scriptBodyOf(task: BodyFields): ScriptBody | null;
|
|
22
|
-
/**
|
|
23
|
-
* An argument vector as a reader would type it in a shell: a word is quoted
|
|
24
|
-
* only where it needs to be, and one holding a character a reader cannot see
|
|
25
|
-
* is written with escapes (`$'…'`), so a command is always one line and reads
|
|
26
|
-
* as what runs. For reading only; nothing runs it.
|
|
27
|
-
*/
|
|
28
|
-
declare function commandLine(argv: readonly string[]): string;
|
|
29
|
-
/**
|
|
30
|
-
* A script task's body as the approval card shows it (ADR-0035), so the
|
|
31
|
-
* consent is to what will run: each command on a line of its own, or the
|
|
32
|
-
* script as written, then the time limit. A character a reader cannot see in
|
|
33
|
-
* a script, but for its line breaks and tabs, is shown as its code.
|
|
34
|
-
*/
|
|
35
|
-
declare function scriptBodyText(body: ScriptBody): string;
|
|
36
|
-
/**
|
|
37
|
-
* A script task as a row shows it: the body {@link scriptBodyText} gives the
|
|
38
|
-
* approval card, so what the user read when consenting is what the plan lists.
|
|
39
|
-
* A task whose body the plan's rules refuse says so rather than showing nothing.
|
|
40
|
-
*/
|
|
41
|
-
declare function scriptTaskText(task: BodyFields): string;
|
|
42
|
-
/** A time limit in the largest units it is a whole number of: "10 minutes", "90 seconds". */
|
|
43
|
-
declare function timeLimitText(ms: number): string;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* The planner's standing approvals (ADR-0026): what runs without asking
|
|
47
|
-
* anyone, under every approval mode.
|
|
48
|
-
*
|
|
49
|
-
* One entry is one of:
|
|
50
|
-
*
|
|
51
|
-
* - a **command rule**, `gh issue list` or `gcloud * * list`: the binary,
|
|
52
|
-
* then words matched against the command's leading arguments, the ones
|
|
53
|
-
* before its first flag. A command whose leading words match the rule's
|
|
54
|
-
* runs, whatever arguments follow — but the rule must spell out at least
|
|
55
|
-
* the words the command's approval scope holds (ADR-0008, T1), so
|
|
56
|
-
* `az group` never covers `az group delete`, and a one-word read takes a
|
|
57
|
-
* `*` for its argument (`kubectl get *`). `*` stands for one word, and
|
|
58
|
-
* inside a word for any run of characters (`describe-*`). An entry equal
|
|
59
|
-
* to a scope also matches that scope, as pre-approved scopes always did.
|
|
60
|
-
* - an **MCP tool rule**, `mcp:find-*`: a glob over the tool's own name,
|
|
61
|
-
* without the server, case-insensitive.
|
|
62
|
-
* - a **scope pattern**, anything starting with `/`, `~`, `http://`,
|
|
63
|
-
* `https://`, `web_search:`, `mcp__`, `mcp-server:` or a drive letter: matched against an approval's
|
|
64
|
-
* scope as ADR-0008 always matched pre-approved entries, `*` matching any
|
|
65
|
-
* run of characters.
|
|
66
|
-
*
|
|
67
|
-
* A leading `!` excludes instead, and an exclusion wins over every rule. A
|
|
68
|
-
* command exclusion's words are looked for anywhere among the arguments, in
|
|
69
|
-
* order, flags included and case ignored, so `!kubectl *secret*` and
|
|
70
|
-
* `!* --endpoint*` hold wherever the word appears; a lone short flag (`-s`)
|
|
71
|
-
* also holds inside a bundle (`-As`, `-shost`). `*` as its binary covers
|
|
72
|
-
* every command.
|
|
73
|
-
*/
|
|
74
|
-
/** The words a command rule is matched against: a lexed segment's binary and arguments. */
|
|
75
|
-
interface CommandWords {
|
|
76
|
-
binary: string;
|
|
77
|
-
args: readonly string[];
|
|
78
|
-
/** How many leading arguments the command's approval scope holds; a rule must cover at least that many. */
|
|
79
|
-
scopeWords?: number;
|
|
80
|
-
}
|
|
81
|
-
interface RuleWord {
|
|
82
|
-
matches: (word: string) => boolean;
|
|
83
|
-
wildcard: boolean;
|
|
84
|
-
}
|
|
85
|
-
interface CommandRule {
|
|
86
|
-
text: string;
|
|
87
|
-
binary: string;
|
|
88
|
-
words: RuleWord[];
|
|
89
|
-
}
|
|
90
|
-
interface PlannerAllowlist {
|
|
91
|
-
commands: CommandRule[];
|
|
92
|
-
commandExclusions: CommandRule[];
|
|
93
|
-
tools: RegExp[];
|
|
94
|
-
toolExclusions: RegExp[];
|
|
95
|
-
scopes: RegExp[];
|
|
96
|
-
scopeExclusions: RegExp[];
|
|
97
|
-
}
|
|
98
|
-
declare function parseAllowlist(entries: readonly string[]): PlannerAllowlist;
|
|
99
|
-
/** The rule that lets this command run unasked, or undefined when none does or an exclusion holds. */
|
|
100
|
-
declare function commandAllowedBy(list: PlannerAllowlist, command: CommandWords): string | undefined;
|
|
101
|
-
/** Whether an MCP tool, by its own name without the server, runs unasked. */
|
|
102
|
-
declare function toolAllowed(list: PlannerAllowlist, tool: string): boolean;
|
|
103
|
-
/** Whether an approval scope — a directory, an origin, a tool's full name — is pre-approved. */
|
|
104
|
-
declare function scopeAllowed(list: PlannerAllowlist, scope: string): boolean;
|
|
105
|
-
/**
|
|
106
|
-
* Read-only command families that are safe to run unasked: they read, never
|
|
107
|
-
* write a file or change a resource, and need no argument that runs code.
|
|
108
|
-
* Absent on purpose: commands that run the repository's own code (test
|
|
109
|
-
* runners, builds, package scripts, a package manager the repository pins or
|
|
110
|
-
* extends — on an untrusted repository someone else wrote that code), commands
|
|
111
|
-
* a repository's own config can point at another endpoint with the user's
|
|
112
|
-
* credentials (`.npmrc`, `.sentryclirc`, a Terraform or Pulumi backend), and
|
|
113
|
-
* commands whose usual output is a secret.
|
|
114
|
-
*/
|
|
115
|
-
declare const DEFAULT_PLANNER_ALLOWLIST: readonly string[];
|
|
116
|
-
|
|
117
5
|
/**
|
|
118
6
|
* Which interpreter runs the planner's `bash` tool, and in which language.
|
|
119
7
|
*
|
|
@@ -174,6 +62,8 @@ interface ShellLaunch {
|
|
|
174
62
|
* timeout, and stops waiting for output a moment after it exits.
|
|
175
63
|
*/
|
|
176
64
|
wallTimeMs?: number;
|
|
65
|
+
/** A sealed run's memory limit, which its result names if the run was ended at it (ADR-0036 S1). */
|
|
66
|
+
memoryBytes?: number;
|
|
177
67
|
}
|
|
178
68
|
interface ResearchShellDeps {
|
|
179
69
|
platform?: NodeJS.Platform;
|
|
@@ -708,6 +598,12 @@ interface IConfig {
|
|
|
708
598
|
approvalDefaults: boolean;
|
|
709
599
|
/** The user's effect allowlist rules (ADR-0035, `effectAllowlist.ts`), read on every request. It has no defaults. */
|
|
710
600
|
effectAllowlist: string[];
|
|
601
|
+
/**
|
|
602
|
+
* The user's notify command as an argument vector (ADR-0053), read as each
|
|
603
|
+
* new escalation appears; empty when there is none. A repository never sets
|
|
604
|
+
* it, because it would then run a command on the user's machine.
|
|
605
|
+
*/
|
|
606
|
+
notifyCommand: string[];
|
|
711
607
|
/** How many fetches and searches one planner turn may make (ADR-0027). User-only, like the approval settings. */
|
|
712
608
|
webReadBudget: number;
|
|
713
609
|
/**
|
|
@@ -728,6 +624,17 @@ interface IConfig {
|
|
|
728
624
|
}
|
|
729
625
|
declare function enabledRunners(cfg: IConfig): RunnerId[];
|
|
730
626
|
|
|
627
|
+
type NotificationAction = {
|
|
628
|
+
label: string;
|
|
629
|
+
value: string;
|
|
630
|
+
};
|
|
631
|
+
interface INotification {
|
|
632
|
+
info(msg: string): void;
|
|
633
|
+
warn(msg: string): void;
|
|
634
|
+
error(msg: string): void;
|
|
635
|
+
confirm(msg: string, options: string[]): Promise<string | undefined>;
|
|
636
|
+
}
|
|
637
|
+
|
|
731
638
|
interface ToolOutcome {
|
|
732
639
|
success: boolean;
|
|
733
640
|
output: string;
|
|
@@ -738,6 +645,12 @@ interface ToolOutcome {
|
|
|
738
645
|
* names the limit it ran out of rather than blaming the command.
|
|
739
646
|
*/
|
|
740
647
|
timedOut?: boolean;
|
|
648
|
+
/**
|
|
649
|
+
* The signal that ended the child, if one did. The adapters report it, and a
|
|
650
|
+
* sealed run's result reads it for the one that means its memory limit ended
|
|
651
|
+
* the run (ADR-0036 S1).
|
|
652
|
+
*/
|
|
653
|
+
signal?: NodeJS.Signals;
|
|
741
654
|
}
|
|
742
655
|
interface ReadFileOpts {
|
|
743
656
|
maxBytes?: number;
|
|
@@ -864,15 +777,18 @@ interface IFileSystem {
|
|
|
864
777
|
setOutboundSecrets?(secrets: () => Iterable<string>): void;
|
|
865
778
|
/** Where the filesystem tells the session, once, that the planner's shell runs without an OS sandbox here (ADR-0011 B5). */
|
|
866
779
|
setNotice?(notice: (message: string) => void): void;
|
|
867
|
-
/** The session ended: its scratch
|
|
780
|
+
/** The session ended: its scratch directories are removed, and the next command starts fresh ones (ADR-0011 B2). */
|
|
868
781
|
endSession?(): void;
|
|
869
782
|
/** Whether a command can run sealed on this host (ADR-0036 S6); where it cannot, the session's one notice says so. */
|
|
870
783
|
canSeal?(): Promise<boolean>;
|
|
784
|
+
/** The same adapter at another workspace: what a child's planner reads, its code root being a task's worktree (ADR-0055 D5). */
|
|
785
|
+
rootedAt?(workspace: string): IFileSystem;
|
|
871
786
|
/** A read-only task's shell at `site`, held to this session's allowlist and never asking (ADR-0046). */
|
|
872
787
|
taskShell?(site: TaskShellSite): TaskShell;
|
|
873
788
|
}
|
|
874
789
|
|
|
875
|
-
|
|
790
|
+
/** A subplanner's report (ADR-0057 R2): it passes a finding up only by reference, so nothing is reworded on the way, and only its token takes these. */
|
|
791
|
+
declare const subplannerCompleteInput: z.ZodObject<{
|
|
876
792
|
status: z.ZodEnum<{
|
|
877
793
|
failed: "failed";
|
|
878
794
|
done: "done";
|
|
@@ -927,6 +843,8 @@ declare const taskCompleteInput: z.ZodObject<{
|
|
|
927
843
|
url: z.ZodString;
|
|
928
844
|
}, z.core.$strip>]>>>;
|
|
929
845
|
report: z.ZodOptional<z.ZodString>;
|
|
846
|
+
promote: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
847
|
+
open: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
930
848
|
}, z.core.$strip>;
|
|
931
849
|
declare const checkpointInput: z.ZodObject<{
|
|
932
850
|
question: z.ZodString;
|
|
@@ -956,6 +874,24 @@ declare const readTaskInput: z.ZodObject<{
|
|
|
956
874
|
attempt: z.ZodOptional<z.ZodNumber>;
|
|
957
875
|
include_report: z.ZodOptional<z.ZodBoolean>;
|
|
958
876
|
}, z.core.$strip>;
|
|
877
|
+
declare const plannerPostInput: z.ZodObject<{
|
|
878
|
+
type: z.ZodEnum<{
|
|
879
|
+
attempt: "attempt";
|
|
880
|
+
finding: "finding";
|
|
881
|
+
pin: "pin";
|
|
882
|
+
decision: "decision";
|
|
883
|
+
claim: "claim";
|
|
884
|
+
artifact: "artifact";
|
|
885
|
+
contract: "contract";
|
|
886
|
+
assume: "assume";
|
|
887
|
+
scope_change: "scope_change";
|
|
888
|
+
}>;
|
|
889
|
+
title: z.ZodString;
|
|
890
|
+
key: z.ZodOptional<z.ZodString>;
|
|
891
|
+
value: z.ZodOptional<z.ZodString>;
|
|
892
|
+
detail: z.ZodOptional<z.ZodString>;
|
|
893
|
+
files: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
894
|
+
}, z.core.$strip>;
|
|
959
895
|
declare const savePatchInput: z.ZodObject<{}, z.core.$strip>;
|
|
960
896
|
declare const applyPatchInput: z.ZodObject<{
|
|
961
897
|
task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
@@ -1131,17 +1067,10 @@ declare const answerApprovalInput: z.ZodObject<{
|
|
|
1131
1067
|
answer: z.ZodString;
|
|
1132
1068
|
note: z.ZodOptional<z.ZodString>;
|
|
1133
1069
|
}, z.core.$strip>;
|
|
1134
|
-
|
|
1135
|
-
task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
1136
|
-
answer: z.ZodEnum<{
|
|
1137
|
-
approve: "approve";
|
|
1138
|
-
reject: "reject";
|
|
1139
|
-
}>;
|
|
1140
|
-
reason: z.ZodOptional<z.ZodString>;
|
|
1141
|
-
}, z.core.$strip>;
|
|
1142
|
-
type TaskCompleteArgs = z.infer<typeof taskCompleteInput>;
|
|
1070
|
+
type TaskCompleteArgs = z.infer<typeof subplannerCompleteInput>;
|
|
1143
1071
|
type CheckpointArgs = z.infer<typeof checkpointInput>;
|
|
1144
1072
|
type ReadTaskArgs = z.infer<typeof readTaskInput>;
|
|
1073
|
+
type PostArgs = z.infer<typeof plannerPostInput>;
|
|
1145
1074
|
type SavePatchArgs = z.infer<typeof savePatchInput>;
|
|
1146
1075
|
type ApplyPatchArgs = z.infer<typeof applyPatchInput>;
|
|
1147
1076
|
type ListRunnersArgs = z.infer<typeof listRunnersInput>;
|
|
@@ -1162,7 +1091,7 @@ type RetryTaskArgs = z.infer<typeof retryTaskInput>;
|
|
|
1162
1091
|
type MessageTaskArgs = z.infer<typeof messageTaskInput>;
|
|
1163
1092
|
type SkipTaskArgs = z.infer<typeof skipTaskInput>;
|
|
1164
1093
|
type AnswerApprovalArgs = z.infer<typeof answerApprovalInput>;
|
|
1165
|
-
type AnswerCheckpointArgs = z.infer<typeof
|
|
1094
|
+
type AnswerCheckpointArgs = z.infer<typeof delegatingAnswerCheckpointInput>;
|
|
1166
1095
|
type RunScriptArgs = z.infer<typeof runScriptInput>;
|
|
1167
1096
|
/** What a handler answers with. `isError` marks a refusal the caller should act on. */
|
|
1168
1097
|
interface McpToolReply {
|
|
@@ -1176,6 +1105,7 @@ interface McpToolReply {
|
|
|
1176
1105
|
*/
|
|
1177
1106
|
type CheckpointAnswer = {
|
|
1178
1107
|
kind: 'continue';
|
|
1108
|
+
note?: string;
|
|
1179
1109
|
} | {
|
|
1180
1110
|
kind: 'rejected';
|
|
1181
1111
|
reason: string;
|
|
@@ -1193,6 +1123,8 @@ interface TaskToolHandler {
|
|
|
1193
1123
|
checkpoint?: Run<CheckpointArgs>;
|
|
1194
1124
|
/** A handoff the task may read (ADR-0047), from its attempt's log. */
|
|
1195
1125
|
readTask?: Run<ReadTaskArgs>;
|
|
1126
|
+
/** An entry on its plan's board (ADR-0057 R8); only a token with a board lists `post`. */
|
|
1127
|
+
post?: Run<PostArgs>;
|
|
1196
1128
|
/** A read-only task's shell (ADR-0046); only its token lists `run_command`. */
|
|
1197
1129
|
runCommand?: Run<TaskRunCommandArgs>;
|
|
1198
1130
|
/** A read-only task's prototype kept as a patch (ADR-0050); only its token lists `save_patch`. */
|
|
@@ -1204,6 +1136,10 @@ interface TaskToolHandler {
|
|
|
1204
1136
|
webSearch?: Run<WebSearchArgs>;
|
|
1205
1137
|
}
|
|
1206
1138
|
interface PlannerToolHandler {
|
|
1139
|
+
/** A handoff below this plan by reference (ADR-0057 R11); only a planner that may hold delegated tasks lists `read`. */
|
|
1140
|
+
readTask?: Run<ReadTaskArgs>;
|
|
1141
|
+
/** An entry on this node's board (ADR-0057 R8); a planner lists it where `read` is. */
|
|
1142
|
+
post?: Run<PostArgs>;
|
|
1207
1143
|
loadSkill?: Run<LoadSkillArgs>;
|
|
1208
1144
|
runCommand?: Run<RunCommandArgs>;
|
|
1209
1145
|
fetch?: Run<FetchArgs>;
|
|
@@ -1226,6 +1162,9 @@ interface PlannerToolHandler {
|
|
|
1226
1162
|
answerCheckpoint?: Run<AnswerCheckpointArgs>;
|
|
1227
1163
|
mergeAll?: Run<RunPlanArgs>;
|
|
1228
1164
|
runScript?: Run<RunScriptArgs>;
|
|
1165
|
+
/** A subplanner's end and its questions, handled by the parent's attempt (ADR-0055 D5); only its token lists them. */
|
|
1166
|
+
taskComplete?: Run<TaskCompleteArgs>;
|
|
1167
|
+
checkpoint?: Run<CheckpointArgs>;
|
|
1229
1168
|
}
|
|
1230
1169
|
interface McpTool<H> {
|
|
1231
1170
|
name: string;
|
|
@@ -1237,9 +1176,23 @@ interface McpTool<H> {
|
|
|
1237
1176
|
annotations?: {
|
|
1238
1177
|
readOnlyHint: boolean;
|
|
1239
1178
|
};
|
|
1179
|
+
/** An older name a call may still use: it is in no list, so it costs nothing and breaks no prompt cache (ADR-0057 R11). */
|
|
1180
|
+
alias?: string;
|
|
1240
1181
|
/** Validate `args` and hand them to the handler's method for this tool. */
|
|
1241
1182
|
call(handler: H, args: unknown, context: McpToolContext): Promise<McpToolReply>;
|
|
1242
1183
|
}
|
|
1184
|
+
/** A tool set as `tools/list` answers with it: what a runner is sent, and pays for. */
|
|
1185
|
+
declare function toolListing<H>(tools: readonly McpTool<H>[]): {
|
|
1186
|
+
annotations?: {
|
|
1187
|
+
readOnlyHint: boolean;
|
|
1188
|
+
} | undefined;
|
|
1189
|
+
name: string;
|
|
1190
|
+
description: string;
|
|
1191
|
+
inputSchema: {
|
|
1192
|
+
[key: string]: unknown;
|
|
1193
|
+
type: "object";
|
|
1194
|
+
};
|
|
1195
|
+
}[];
|
|
1243
1196
|
/** The task tool whose call settles the attempt (ADR-0022, V1). */
|
|
1244
1197
|
declare const TASK_COMPLETE_TOOL = "task_complete";
|
|
1245
1198
|
/**
|
|
@@ -1266,6 +1219,11 @@ declare const TASK_TOOLS: readonly McpTool<TaskToolHandler>[];
|
|
|
1266
1219
|
* plan's branches.
|
|
1267
1220
|
*/
|
|
1268
1221
|
declare const READ_ONLY_TASK_TOOLS: readonly McpTool<TaskToolHandler>[];
|
|
1222
|
+
/** What a task's token serves (ADR-0057 R11): the flat list itself where it has no board, so a flat run's does not move by a byte. */
|
|
1223
|
+
declare function taskToolSet({ readOnly, board }: {
|
|
1224
|
+
readOnly?: boolean;
|
|
1225
|
+
board?: boolean;
|
|
1226
|
+
}): readonly McpTool<TaskToolHandler>[];
|
|
1269
1227
|
/**
|
|
1270
1228
|
* The planner's execution tools (ADR-0029, #91): each call goes to the
|
|
1271
1229
|
* session's command seam, which checks it, asks the user where consent needs
|
|
@@ -1273,6 +1231,25 @@ declare const READ_ONLY_TASK_TOOLS: readonly McpTool<TaskToolHandler>[];
|
|
|
1273
1231
|
*/
|
|
1274
1232
|
declare const PLANNER_EXECUTION_TOOLS: readonly McpTool<PlannerToolHandler>[];
|
|
1275
1233
|
declare const PLANNER_TOOLS: readonly McpTool<PlannerToolHandler>[];
|
|
1234
|
+
declare const delegatingAnswerCheckpointInput: z.ZodObject<{
|
|
1235
|
+
task: z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>;
|
|
1236
|
+
answer: z.ZodEnum<{
|
|
1237
|
+
approve: "approve";
|
|
1238
|
+
reject: "reject";
|
|
1239
|
+
}>;
|
|
1240
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
1241
|
+
raiseTokens: z.ZodOptional<z.ZodNumber>;
|
|
1242
|
+
}, z.core.$strip>;
|
|
1243
|
+
/**
|
|
1244
|
+
* What a planner's token serves (ADR-0056 M6): the list as a flat planner has
|
|
1245
|
+
* it unless delegation reaches it, so a flat session's tools do not change by
|
|
1246
|
+
* a byte (ADR-0055 D21). A subplanner ends and asks with the tools a runner
|
|
1247
|
+
* does (D4), read-only by the hint since they change no file of the workspace.
|
|
1248
|
+
*/
|
|
1249
|
+
declare function plannerToolSet({ delegates, subplanner }?: {
|
|
1250
|
+
delegates?: boolean;
|
|
1251
|
+
subplanner?: boolean;
|
|
1252
|
+
}): readonly McpTool<PlannerToolHandler>[];
|
|
1276
1253
|
|
|
1277
1254
|
/**
|
|
1278
1255
|
* The Ordewell MCP server (ADR-0022): one loopback listener per process,
|
|
@@ -1291,6 +1268,8 @@ interface TaskTokenScope {
|
|
|
1291
1268
|
attempt: number;
|
|
1292
1269
|
/** A read-only task's attempt (ADR-0046): its token lists `run_command`, `fetch` and `web_search` too, and no other task's does. */
|
|
1293
1270
|
readOnly?: boolean;
|
|
1271
|
+
/** Its plan has a board (ADR-0057 R8): its token lists `post`, and a flat task's does not. */
|
|
1272
|
+
board?: boolean;
|
|
1294
1273
|
}
|
|
1295
1274
|
interface PlannerTokenScope {
|
|
1296
1275
|
sessionId: string;
|
|
@@ -1300,6 +1279,10 @@ interface PlannerTokenScope {
|
|
|
1300
1279
|
* model would otherwise pick over its own.
|
|
1301
1280
|
*/
|
|
1302
1281
|
hidden?: readonly string[];
|
|
1282
|
+
/** Its `submit_plan` takes a delegated task (ADR-0055 D1): a flat planner's list does not change. */
|
|
1283
|
+
delegates?: boolean;
|
|
1284
|
+
/** A subplanner's token (ADR-0055 D5): it serves `task_complete` and `checkpoint` too, which its handler sends to the parent's attempt. */
|
|
1285
|
+
subplanner?: boolean;
|
|
1303
1286
|
}
|
|
1304
1287
|
/** Where a runner reaches the server and what it presents there. Never put either half in a prompt. */
|
|
1305
1288
|
interface McpCredential {
|
|
@@ -1307,6 +1290,8 @@ interface McpCredential {
|
|
|
1307
1290
|
token: string;
|
|
1308
1291
|
/** The planner tools the token hides ({@link PlannerTokenScope.hidden}), so the runner is told of and pre-allows only what it is served. */
|
|
1309
1292
|
hidden?: readonly string[];
|
|
1293
|
+
/** Tools it serves past a flat role's, by their names on the server: a subplanner's (ADR-0055 D5), `read` where it may delegate, and `post` where it has a board (ADR-0057 R11). */
|
|
1294
|
+
extraTools?: readonly string[];
|
|
1310
1295
|
/** The token serves a read-only task's tools ({@link TaskTokenScope.readOnly}), so the runner is told of and pre-allows `run_command`, `fetch` and `web_search`. */
|
|
1311
1296
|
readOnly?: true;
|
|
1312
1297
|
}
|
|
@@ -1361,6 +1346,8 @@ interface McpClientConfig {
|
|
|
1361
1346
|
headers: Record<string, string>;
|
|
1362
1347
|
/** Planner tools the token hides: a runner must neither pre-allow nor mention them. */
|
|
1363
1348
|
hidden?: readonly string[];
|
|
1349
|
+
/** Tools served past a planner's: a subplanner's, to pre-allow with the rest (ADR-0055 D5). */
|
|
1350
|
+
extraTools?: readonly string[];
|
|
1364
1351
|
/** A read-only task's token (ADR-0046): `run_command`, `fetch` and `web_search` are among its tools, for the runner to pre-allow and name. */
|
|
1365
1352
|
readOnly?: true;
|
|
1366
1353
|
}
|
|
@@ -1533,18 +1520,26 @@ interface SandboxProfile {
|
|
|
1533
1520
|
limits?: SandboxLimits;
|
|
1534
1521
|
}
|
|
1535
1522
|
/**
|
|
1536
|
-
* Held by the kernel's resource limits, set before the launcher starts,
|
|
1537
|
-
* by the caller's clock
|
|
1523
|
+
* Held by the kernel's resource limits, set before the launcher starts, by a
|
|
1524
|
+
* watcher beside the launcher, outside the sandbox, and by the caller's clock
|
|
1525
|
+
* (ADR-0036 S1).
|
|
1538
1526
|
*/
|
|
1539
1527
|
interface SandboxLimits {
|
|
1540
1528
|
/** Processes the command may start beyond those its user already runs, which the kernel's limit counts too. */
|
|
1541
1529
|
processes: number;
|
|
1542
1530
|
/**
|
|
1543
|
-
* Bytes of
|
|
1544
|
-
*
|
|
1545
|
-
*
|
|
1531
|
+
* Bytes of real memory the command may hold: resident memory summed across
|
|
1532
|
+
* its processes, which the watcher reads about once a second and ends the
|
|
1533
|
+
* command for passing ({@link MEMORY_LIMIT_SIGNAL}).
|
|
1546
1534
|
*/
|
|
1547
1535
|
memoryBytes: number;
|
|
1536
|
+
/**
|
|
1537
|
+
* Bytes of address space any one of its processes may map: a backstop
|
|
1538
|
+
* against a runaway allocator, not a measure of memory, since V8 reserves
|
|
1539
|
+
* far more than it touches. On macOS, where every program maps hundreds of
|
|
1540
|
+
* gigabytes as it starts, it is counted on top of that.
|
|
1541
|
+
*/
|
|
1542
|
+
addressSpaceBytes: number;
|
|
1548
1543
|
/** Milliseconds before the caller kills the command, and with it every process it started. */
|
|
1549
1544
|
wallTimeMs: number;
|
|
1550
1545
|
}
|
|
@@ -1559,9 +1554,12 @@ interface SandboxInvocation {
|
|
|
1559
1554
|
interface SandboxLaunch {
|
|
1560
1555
|
file: string;
|
|
1561
1556
|
args: string[];
|
|
1557
|
+
/** What `file` starts with. A launcher that runs before the sandbox gets only what the profile keeps of the host's. */
|
|
1562
1558
|
env: NodeJS.ProcessEnv;
|
|
1563
1559
|
/** The profile's wall-time limit: the caller kills the launch with SIGKILL once it has run this long. */
|
|
1564
1560
|
wallTimeMs?: number;
|
|
1561
|
+
/** The profile's memory limit, past which the launch ends by {@link MEMORY_LIMIT_SIGNAL}. */
|
|
1562
|
+
memoryBytes?: number;
|
|
1565
1563
|
}
|
|
1566
1564
|
type SandboxProbe = {
|
|
1567
1565
|
ok: true;
|
|
@@ -1676,7 +1674,12 @@ interface PlannerSandboxDeps {
|
|
|
1676
1674
|
uid?: number;
|
|
1677
1675
|
exec?: ProbeExec;
|
|
1678
1676
|
}
|
|
1679
|
-
/**
|
|
1677
|
+
/**
|
|
1678
|
+
* Time enough for a loop over a repository's files, a pipeline or a short
|
|
1679
|
+
* script, not for a build. The memory is real memory across the run; the
|
|
1680
|
+
* address space is per process and far above what V8 reserves for ordinary
|
|
1681
|
+
* programs (ADR-0036 S1, which records the measurement).
|
|
1682
|
+
*/
|
|
1680
1683
|
declare const SEALED_LIMITS: SandboxLimits;
|
|
1681
1684
|
/**
|
|
1682
1685
|
* A read-only task's sealed runs (ADR-0046): the same resources, with the ten
|
|
@@ -1699,18 +1702,18 @@ interface PlannerShellLaunch {
|
|
|
1699
1702
|
sandboxed: boolean;
|
|
1700
1703
|
}
|
|
1701
1704
|
/**
|
|
1702
|
-
* One session's view of the sandbox:
|
|
1703
|
-
* command and removed when the session ends, and its one
|
|
1704
|
-
* sandbox, or a sealed run in it, cannot run here.
|
|
1705
|
+
* One session's view of the sandbox: a scratch directory for each profile,
|
|
1706
|
+
* made on its first command and removed when the session ends, and its one
|
|
1707
|
+
* notice when the sandbox, or a sealed run in it, cannot run here.
|
|
1705
1708
|
*/
|
|
1706
1709
|
declare class PlannerShellSandbox {
|
|
1707
1710
|
private readonly resolve;
|
|
1708
|
-
private scratch;
|
|
1711
|
+
private readonly scratch;
|
|
1709
1712
|
private noticed;
|
|
1710
1713
|
private notice;
|
|
1711
1714
|
constructor(resolve?: () => Promise<PlannerSandboxAvailability>);
|
|
1712
1715
|
setNotice(notice: (message: string) => void): void;
|
|
1713
|
-
/** The same host's sandbox for another caller, with
|
|
1716
|
+
/** The same host's sandbox for another caller, with scratch directories of its own: a read-only task's (ADR-0046). */
|
|
1714
1717
|
withOwnScratch(): PlannerShellSandbox;
|
|
1715
1718
|
/**
|
|
1716
1719
|
* The launch for one command (B6): the research shell wrapped in the
|
|
@@ -1733,8 +1736,10 @@ declare class PlannerShellSandbox {
|
|
|
1733
1736
|
/**
|
|
1734
1737
|
* The launch for a harness's own shell (ADR-0036 N2): the same sealed profile
|
|
1735
1738
|
* as a sealed run, with the network the harness gives it (N3), plus the
|
|
1736
|
-
* harness's short temporary directory. The workspace stays read-only.
|
|
1737
|
-
*
|
|
1739
|
+
* harness's short temporary directory. The workspace stays read-only. Its
|
|
1740
|
+
* home is a scratch directory of its own, so whatever startup files its shell
|
|
1741
|
+
* reads, a sealed run wrote none of them (S8). Throws where the sandbox
|
|
1742
|
+
* cannot run, so a caller never falls back to the bare shell.
|
|
1738
1743
|
*/
|
|
1739
1744
|
launchNativeShell(opts: {
|
|
1740
1745
|
workspace: string;
|
|
@@ -1743,9 +1748,9 @@ declare class PlannerShellSandbox {
|
|
|
1743
1748
|
shellArgs?: readonly string[];
|
|
1744
1749
|
env?: NodeJS.ProcessEnv;
|
|
1745
1750
|
}): Promise<SandboxLaunch>;
|
|
1746
|
-
/** The scratch directory
|
|
1751
|
+
/** The scratch directory a sealed run gets as `$TMPDIR` and `$HOME`, made if it is not there. */
|
|
1747
1752
|
scratchPath(): string;
|
|
1748
|
-
/** The session ended: its scratch
|
|
1753
|
+
/** The session ended: its scratch directories go, and a next session starts with fresh ones and its own notice. */
|
|
1749
1754
|
end(): void;
|
|
1750
1755
|
private say;
|
|
1751
1756
|
private invocation;
|
|
@@ -1755,6 +1760,689 @@ declare class PlannerShellSandbox {
|
|
|
1755
1760
|
/** A runner's report on the Ordewell server's connection, in one vocabulary for every runner. */
|
|
1756
1761
|
type AttachState = 'connected' | 'pending' | 'failed';
|
|
1757
1762
|
|
|
1763
|
+
interface SessionMeta {
|
|
1764
|
+
id: string;
|
|
1765
|
+
goal: string;
|
|
1766
|
+
runners: RunnerId[];
|
|
1767
|
+
taskCount: number;
|
|
1768
|
+
status: PlanStatus;
|
|
1769
|
+
createdAt: string;
|
|
1770
|
+
updatedAt: string;
|
|
1771
|
+
}
|
|
1772
|
+
interface SessionData {
|
|
1773
|
+
meta: SessionMeta;
|
|
1774
|
+
/** The full plan state — including conversationHistory, prdMarkdown, and queuedMessages. */
|
|
1775
|
+
plan: LegacyPlanState;
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
interface ILogger {
|
|
1779
|
+
warn(scope: string, message: string, err?: unknown): void;
|
|
1780
|
+
}
|
|
1781
|
+
declare class ConsoleLogger implements ILogger {
|
|
1782
|
+
warn(scope: string, message: string, err?: unknown): void;
|
|
1783
|
+
}
|
|
1784
|
+
declare const defaultLogger: ILogger;
|
|
1785
|
+
|
|
1786
|
+
/**
|
|
1787
|
+
* A path segment for an id that came from outside — a session id from a URL,
|
|
1788
|
+
* a task id a planner wrote. A plain id is used as is; anything that could
|
|
1789
|
+
* climb out of its directory, or is not portable as a file name, is hex-encoded.
|
|
1790
|
+
*/
|
|
1791
|
+
declare function idSegment(id: string): string;
|
|
1792
|
+
/**
|
|
1793
|
+
* The directory beside a session's file for what it keeps outside that file —
|
|
1794
|
+
* its task logs (ADR-0018, P1). It goes when the session does. A child's sits
|
|
1795
|
+
* under its root's at every depth, so it goes with its root and no prune or
|
|
1796
|
+
* sweep of a worktree reaches it (ADR-0055 D11).
|
|
1797
|
+
*/
|
|
1798
|
+
declare function sessionDataDir(sessionId: string, baseDir?: string, rootSessionId?: string): string;
|
|
1799
|
+
/** Where a child session's state lives. `baseDir` is the state root: the root Session's workspace, never a worktree. */
|
|
1800
|
+
interface ChildSessionPlace {
|
|
1801
|
+
baseDir: string;
|
|
1802
|
+
rootSessionId: string;
|
|
1803
|
+
sessionId: string;
|
|
1804
|
+
}
|
|
1805
|
+
declare function saveSession(plan: LegacyPlanState, goal: string, baseDir?: string, id?: string): SessionMeta;
|
|
1806
|
+
/** Saved beside the child's logs, in the root's directory; `listSessions` never sees it (ADR-0055 D11). */
|
|
1807
|
+
declare function saveChildSession(plan: LegacyPlanState, goal: string, place: ChildSessionPlace): SessionMeta;
|
|
1808
|
+
/** The ids of every child saved under a root, at any depth. */
|
|
1809
|
+
declare function listChildSessions(rootSessionId: string, baseDir?: string): string[];
|
|
1810
|
+
declare function listSessions(baseDir?: string, logger?: ILogger): SessionMeta[];
|
|
1811
|
+
/** A child is read only through its root, and only when asked for (ADR-0055 D17). */
|
|
1812
|
+
declare function loadChildSession(place: ChildSessionPlace, logger?: ILogger): {
|
|
1813
|
+
meta: SessionMeta;
|
|
1814
|
+
plan: LegacyPlanState;
|
|
1815
|
+
} | null;
|
|
1816
|
+
declare function loadSession(sessionId: string, baseDir?: string, logger?: ILogger): {
|
|
1817
|
+
meta: SessionMeta;
|
|
1818
|
+
plan: LegacyPlanState;
|
|
1819
|
+
} | null;
|
|
1820
|
+
declare function loadSessionPlanState(sessionId: string, baseDir?: string, logger?: ILogger): {
|
|
1821
|
+
meta: SessionMeta;
|
|
1822
|
+
plan: PlanState;
|
|
1823
|
+
} | null;
|
|
1824
|
+
declare function getLatestSession(baseDir?: string, logger?: ILogger): {
|
|
1825
|
+
meta: SessionMeta;
|
|
1826
|
+
plan: LegacyPlanState;
|
|
1827
|
+
} | null;
|
|
1828
|
+
declare function deleteSession(sessionId: string, baseDir?: string, logger?: ILogger): boolean;
|
|
1829
|
+
|
|
1830
|
+
/**
|
|
1831
|
+
* Task skills end to end (ADR-0024): a skill reaches a runner only by being
|
|
1832
|
+
* attached to its task in the plan, and Ordewell puts its body in the task's
|
|
1833
|
+
* prompt — so it works the same on every runner, and nothing is written to a
|
|
1834
|
+
* harness's own skills directory.
|
|
1835
|
+
*/
|
|
1836
|
+
/** Where a task's skill names are looked up: global first, then the workspace folders it reads. */
|
|
1837
|
+
interface SkillLookup extends Pick<SkillsService, 'findSkill' | 'searchedDirs'> {
|
|
1838
|
+
/**
|
|
1839
|
+
* Set when tasks get worktrees: of `skills`, the workspace ones git will not
|
|
1840
|
+
* carry into them, each SKILL.md path mapped to the folder to commit,
|
|
1841
|
+
* relative to the workspace root.
|
|
1842
|
+
*/
|
|
1843
|
+
uncommitted?(skills: readonly SkillInfo[]): Promise<Map<string, string>>;
|
|
1844
|
+
}
|
|
1845
|
+
/**
|
|
1846
|
+
* Where a workspace's skills are read, known without asking git: the repos
|
|
1847
|
+
* of its group in layout order (`['.']` for one repository), and whether
|
|
1848
|
+
* tasks will get worktrees, which only a committed skill reaches.
|
|
1849
|
+
*/
|
|
1850
|
+
interface SkillLayout {
|
|
1851
|
+
repos: readonly string[];
|
|
1852
|
+
worktrees: boolean;
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
/**
|
|
1856
|
+
* Where the run's tasks will work: `false` in the shared workspace root;
|
|
1857
|
+
* otherwise each in its own worktree of every repo of the group (ADR-0013,
|
|
1858
|
+
* ADR-0014), which is what decides if tasks on the same file must be ordered.
|
|
1859
|
+
*/
|
|
1860
|
+
type IsolatedExecution = false | RepoGroupLayout;
|
|
1861
|
+
interface PlannerModes {
|
|
1862
|
+
autonomousDefault: boolean;
|
|
1863
|
+
/** Not a toggle: a fact about the run. */
|
|
1864
|
+
isolatedExecution: IsolatedExecution;
|
|
1865
|
+
/**
|
|
1866
|
+
* Where the run's tasks will look their skills up (ADR-0024), also a fact
|
|
1867
|
+
* about the run. A plan attaching a planner skill is refused against it,
|
|
1868
|
+
* and a coding agent's submit_plan call is refused in its turn rather than
|
|
1869
|
+
* accepted and then failed. Absent: the plan is not checked.
|
|
1870
|
+
*/
|
|
1871
|
+
taskSkills?: SkillLookup;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
type IsolationNoticeLevel = 'info' | 'warn' | 'error';
|
|
1875
|
+
/**
|
|
1876
|
+
* How an attempt that may run in a worktree gets one: fresh, the kept one for
|
|
1877
|
+
* a repair, restoring the previous attempt's work, or fresh and thrown away
|
|
1878
|
+
* whatever it changes, for a read-only task (ADR-0046).
|
|
1879
|
+
*/
|
|
1880
|
+
type AttemptIntent = 'fresh' | 'repair' | 'readOnly' | PrepareIntent;
|
|
1881
|
+
/**
|
|
1882
|
+
* What adopting a persisted run found: nothing to change, landed work git
|
|
1883
|
+
* shows the user has merged since, or a settled run that had nothing left to
|
|
1884
|
+
* hand over and was cleared up.
|
|
1885
|
+
*/
|
|
1886
|
+
type AdoptOutcome = 'unchanged' | 'changed' | 'cleared';
|
|
1887
|
+
interface AttemptWorkspace {
|
|
1888
|
+
cwd: string;
|
|
1889
|
+
worktree: boolean;
|
|
1890
|
+
/** The task workspace holding the attempt's worktrees, which `cwd` is in; set with `worktree` when it was prepared. */
|
|
1891
|
+
workspace?: string;
|
|
1892
|
+
/** Set for a `restore` in a worktree; absent in the checkout, where the previous attempt's edits remain. */
|
|
1893
|
+
previousWork?: PreviousWork;
|
|
1894
|
+
}
|
|
1895
|
+
/**
|
|
1896
|
+
* What the controller reports. It never schedules or emits on its own: the
|
|
1897
|
+
* orchestrator turns these into observer events and decides what runs next.
|
|
1898
|
+
*/
|
|
1899
|
+
interface IsolationRunListener {
|
|
1900
|
+
/**
|
|
1901
|
+
* The run record changed and should be persisted with the plan. `detached`
|
|
1902
|
+
* is set instead when the record that changed is no longer the plan's own —
|
|
1903
|
+
* a release that outlived the plan load that replaced its run — and belongs
|
|
1904
|
+
* to the session that was left.
|
|
1905
|
+
*/
|
|
1906
|
+
changed(detached?: IsolationRun): void;
|
|
1907
|
+
/** A run did not start: `repos` of the group have tracked changes. */
|
|
1908
|
+
blocked(repos: string[]): void;
|
|
1909
|
+
/** An isolated run closed and handed its integration branches over. */
|
|
1910
|
+
handoff(handoff: IsolationHandoff): void;
|
|
1911
|
+
/** The run was cleared up and forgotten: nothing was handed over, or it was discarded. */
|
|
1912
|
+
closed(): void;
|
|
1913
|
+
/** The run is over, discarded or cleared up, whether or not its record stays: nothing it carried goes on (ADR-0045 L5). A Merge all it goes on after is not this. */
|
|
1914
|
+
ended(): void;
|
|
1915
|
+
/** Already said through the notifications; also for a surface that shows no toasts. */
|
|
1916
|
+
notice(level: IsolationNoticeLevel, message: string): void;
|
|
1917
|
+
/** A clean-up took the branches these resolver tasks would merge, and their links with them. */
|
|
1918
|
+
resolversEnded(resolverIds: readonly string[]): void;
|
|
1919
|
+
}
|
|
1920
|
+
interface IsolationRunControllerDeps {
|
|
1921
|
+
isolation: IWorktreeIsolation;
|
|
1922
|
+
config: IConfig;
|
|
1923
|
+
notifications: INotification;
|
|
1924
|
+
workspaceRoot: () => string;
|
|
1925
|
+
/** A child session's state root, which every run it mints keeps (ADR-0055 D11); absent on a flat run. */
|
|
1926
|
+
stateRoot?: string;
|
|
1927
|
+
listener: IsolationRunListener;
|
|
1928
|
+
/**
|
|
1929
|
+
* The tasks no clean-up of the whole run may take a worktree from: an
|
|
1930
|
+
* attempt is running them, or the plan has them in progress or waiting on
|
|
1931
|
+
* the user mid-attempt.
|
|
1932
|
+
*/
|
|
1933
|
+
liveTasks: () => ReadonlySet<string>;
|
|
1934
|
+
/** What a task depends on now, directly or not, read as it lands: the plan may let go of that later, and a revert may not (ADR-0054). */
|
|
1935
|
+
landedOn: (taskId: string) => readonly string[];
|
|
1936
|
+
}
|
|
1937
|
+
/**
|
|
1938
|
+
* The lifecycle of a plan's isolation run (ADR-0013, ADR-0014, ADR-0020),
|
|
1939
|
+
* between the scheduler and the git layer: deciding, at a run's first change
|
|
1940
|
+
* task, whether it executes in worktrees, a blocked run and how it goes on,
|
|
1941
|
+
* each attempt's working directory, releasing worktrees, which landed work the
|
|
1942
|
+
* user has merged, the tree check of an ops task, the handoff when the run
|
|
1943
|
+
* closes, and what the user does with it afterwards. The record it keeps
|
|
1944
|
+
* outlives one run — a resumed plan continues it.
|
|
1945
|
+
*/
|
|
1946
|
+
declare class IsolationRunController {
|
|
1947
|
+
private readonly isolation;
|
|
1948
|
+
private readonly config;
|
|
1949
|
+
private readonly notifications;
|
|
1950
|
+
private readonly workspaceRoot;
|
|
1951
|
+
private readonly stateRoot;
|
|
1952
|
+
private readonly listener;
|
|
1953
|
+
private readonly liveTasks;
|
|
1954
|
+
private readonly landedOn;
|
|
1955
|
+
private run;
|
|
1956
|
+
/** See {@link mergedRun}. */
|
|
1957
|
+
private merged;
|
|
1958
|
+
/** An adoption stays scoped even while cleanup temporarily leaves no run record. */
|
|
1959
|
+
private adoptions;
|
|
1960
|
+
/** Copied paths already reported for the current run: every task gets the same copies. */
|
|
1961
|
+
private reportedCopies;
|
|
1962
|
+
private gitShortfallSaid;
|
|
1963
|
+
private reportedSetupFailures;
|
|
1964
|
+
/**
|
|
1965
|
+
* How the open run executes; null while no run is open, `undecided` until
|
|
1966
|
+
* its first change task asks. A run is one Execute-Plan or one manual task
|
|
1967
|
+
* run, from its start until it settles or is stopped.
|
|
1968
|
+
*/
|
|
1969
|
+
private mode;
|
|
1970
|
+
/** Resolver task id → the conflicted task it resolves; see {@link linkResolver}. */
|
|
1971
|
+
private resolvers;
|
|
1972
|
+
private opening;
|
|
1973
|
+
private opened;
|
|
1974
|
+
/** Bumped by an interrupt, so an activation in flight across it does not open the run it ended. */
|
|
1975
|
+
private activations;
|
|
1976
|
+
/** The start a dirty tree turned away, handed back once the user chooses how to go on. */
|
|
1977
|
+
private blockedStart;
|
|
1978
|
+
/** How many starts it has turned away; a replay can be turned away again in the same run. */
|
|
1979
|
+
private turnedAway;
|
|
1980
|
+
/** The dirty repos behind {@link blockedStart}, for the stash notice. */
|
|
1981
|
+
private blockedRepos;
|
|
1982
|
+
constructor(deps: IsolationRunControllerDeps);
|
|
1983
|
+
/** The plan's run record, open or not; null when the plan has not isolated. */
|
|
1984
|
+
get current(): IsolationRun | null;
|
|
1985
|
+
/** What a child works through: this run's own, so a tree takes one admin lock (ADR-0055 D11). */
|
|
1986
|
+
get childIsolation(): IWorktreeIsolation;
|
|
1987
|
+
/**
|
|
1988
|
+
* The id of the plan's last isolated run once it closed with everything it
|
|
1989
|
+
* landed merged into the user's branch and was cleared up: what tells a
|
|
1990
|
+
* Merge all asked for after it, which has nothing to merge, from one in a
|
|
1991
|
+
* plan that never isolated (ADR-0029). Null while the plan holds a run
|
|
1992
|
+
* record, and once a later run decides how it executes. Saved with the plan.
|
|
1993
|
+
*/
|
|
1994
|
+
get mergedRun(): string | null;
|
|
1995
|
+
get isOpen(): boolean;
|
|
1996
|
+
/** How many runs have opened: what tells one run's launches from the next one's. */
|
|
1997
|
+
get epoch(): number;
|
|
1998
|
+
/** The open run has decided whether it isolates. */
|
|
1999
|
+
get decided(): boolean;
|
|
2000
|
+
/** The open run executes in worktrees. */
|
|
2001
|
+
get isolating(): boolean;
|
|
2002
|
+
/** A run is waiting on the user to stash or to go on without isolation. */
|
|
2003
|
+
get blocked(): boolean;
|
|
2004
|
+
/** How many starts a dirty tree has turned away: what tells one wait on it from the next (ADR-0053). */
|
|
2005
|
+
get blockedStarts(): number;
|
|
2006
|
+
/** What the plan persists of isolated execution; null when no run ever isolated. */
|
|
2007
|
+
get planIsolation(): PlanIsolation | null;
|
|
2008
|
+
/** The one guard of every action on the run: a plan that never isolated is a request refused, not a fault. */
|
|
2009
|
+
requireRun(): IsolationRun;
|
|
2010
|
+
/** A task's record in the open run, only while that run isolates. */
|
|
2011
|
+
openRecord(taskId: string): IsolationTaskRecord | undefined;
|
|
2012
|
+
/** Where a task's isolated work stands; null when the plan has no isolation run to speak of. */
|
|
2013
|
+
taskIsolation(taskId: string): TaskIsolation | null;
|
|
2014
|
+
view(): IsolationView | null;
|
|
2015
|
+
/**
|
|
2016
|
+
* Take over a plan's persisted isolation, or none for a plan that has not
|
|
2017
|
+
* isolated yet. Whatever a crashed process left behind for the run — a
|
|
2018
|
+
* worktree still marked active, a directory no record owns — is pruned,
|
|
2019
|
+
* while kept, failed and conflicted worktrees stay for the user. Then git is
|
|
2020
|
+
* asked which landed work the user has merged since the record was saved:
|
|
2021
|
+
* a settled run whose landed work is all in HEAD has nothing left to hand
|
|
2022
|
+
* over, so it is cleared up as Merge all would have, unless it still holds
|
|
2023
|
+
* work that never landed (ADR-0013).
|
|
2024
|
+
*
|
|
2025
|
+
* Deliberately not reported to the listener: adopting is not a change of the
|
|
2026
|
+
* session's own, and a host that adopts without persisting (VS Code's
|
|
2027
|
+
* restore) would otherwise write a new session file on every reload. What
|
|
2028
|
+
* git changed is returned instead, for the caller to save where it can and
|
|
2029
|
+
* announce. A plan loaded meanwhile supersedes this adoption, which then
|
|
2030
|
+
* touches nothing and resolves `unchanged`. `mergedRun` is the plan's saved
|
|
2031
|
+
* {@link mergedRun}.
|
|
2032
|
+
*/
|
|
2033
|
+
adopt(state: PlanIsolation | null, mergedRun?: string): Promise<AdoptOutcome>;
|
|
2034
|
+
/** Throws, as {@link hostChild} does, for a task with no worktree: read before a carve, so one that cannot seat a child spends nothing. */
|
|
2035
|
+
requireChildSeat(taskId: string): void;
|
|
2036
|
+
/**
|
|
2037
|
+
* The child session a task's worktree is the code root of, named on the
|
|
2038
|
+
* task's record so a reopen knows that worktree is a child's (ADR-0055 D17),
|
|
2039
|
+
* and the same child again once it is. A task with no worktree has nothing
|
|
2040
|
+
* to host one in: a run that shares the workspace root would root the child
|
|
2041
|
+
* in the user's checkout (D12).
|
|
2042
|
+
*/
|
|
2043
|
+
hostChild(taskId: string, mintSessionId: () => string): string;
|
|
2044
|
+
/** The child session seated in a task's worktree, if one is. */
|
|
2045
|
+
childSession(taskId: string): string | undefined;
|
|
2046
|
+
/** A child's run goes, and what that kept or could not let go is said, as a run's own discard says it (ADR-0055 D15). */
|
|
2047
|
+
discardChild(place: ChildSessionPlace): Promise<IsolationRemoval>;
|
|
2048
|
+
/** Open a run if none is, leaving whether it isolates to its first change task. */
|
|
2049
|
+
open(): void;
|
|
2050
|
+
/**
|
|
2051
|
+
* Decide once per run, as its first change task starts, whether it executes
|
|
2052
|
+
* in worktrees (ADR-0020): an ops task needs none, so a run of only ops
|
|
2053
|
+
* tasks never asks. `resume` is what a dirty tree parks until the user
|
|
2054
|
+
* chooses how to go on. Resolves false while the run waits on that choice.
|
|
2055
|
+
*/
|
|
2056
|
+
decide(resume: () => Promise<void>): Promise<boolean>;
|
|
2057
|
+
/**
|
|
2058
|
+
* Whether the run in force, or else the next one, gives each task its own
|
|
2059
|
+
* worktrees, and of which repo group — what the planner is told, since it
|
|
2060
|
+
* decides whether tasks on the same file have to be ordered and which shared
|
|
2061
|
+
* paths two tasks must not edit at once. A tree that would block counts as
|
|
2062
|
+
* not isolating: the user may yet run without isolation, and ordering is
|
|
2063
|
+
* the safe rule then.
|
|
2064
|
+
*/
|
|
2065
|
+
plannerLayout(): Promise<IsolatedExecution>;
|
|
2066
|
+
/**
|
|
2067
|
+
* Where the workspace's skills are read, and whether tasks get worktrees.
|
|
2068
|
+
* Read synchronously inside a planner turn or a chip edit, so it comes from
|
|
2069
|
+
* the files, not git or the planner's last layout: a restored session is
|
|
2070
|
+
* right from its first edit. The run's repos while it isolates; otherwise
|
|
2071
|
+
* the group the workspace holds, in worktrees unless isolation is off or
|
|
2072
|
+
* this run chose to share the root.
|
|
2073
|
+
*/
|
|
2074
|
+
skillLayout(): SkillLayout;
|
|
2075
|
+
/**
|
|
2076
|
+
* Go on with the start a dirty tree turned away. `stash` puts the user's
|
|
2077
|
+
* tracked changes on the git stash first, so the run isolates; `shared` runs
|
|
2078
|
+
* this one run in the workspace root, knowingly; `reread` does nothing to the
|
|
2079
|
+
* tree, so the replay asks about it again (ADR-0053). Returns the parked start
|
|
2080
|
+
* for the caller to replay; null when nothing was parked.
|
|
2081
|
+
*/
|
|
2082
|
+
continueBlocked(how: 'stash' | 'shared' | 'reread'): Promise<(() => Promise<void>) | null>;
|
|
2083
|
+
/**
|
|
2084
|
+
* The working directory of an attempt that may run in a worktree — which
|
|
2085
|
+
* attempts do is the attempt kind's to say (see `attemptKind.attemptWorkspace`):
|
|
2086
|
+
* the worktree prepared for it in an isolated run, the kept one for a
|
|
2087
|
+
* conflict repair, else the workspace root. `worktree` says which. Does not
|
|
2088
|
+
* itself report a worktree it creates as a change — the caller does once
|
|
2089
|
+
* the attempt is committed as running, so a spawn abandoned or failed after
|
|
2090
|
+
* this settles is not misreported as a change that stuck.
|
|
2091
|
+
*/
|
|
2092
|
+
attemptCwd(task: Task, intent: AttemptIntent): Promise<AttemptWorkspace>;
|
|
2093
|
+
/** The workspace root, for an attempt that runs outside any worktree. */
|
|
2094
|
+
workspaceCwd(task: Task): Promise<{
|
|
2095
|
+
cwd: string;
|
|
2096
|
+
worktree: boolean;
|
|
2097
|
+
}>;
|
|
2098
|
+
private reopenCwd;
|
|
2099
|
+
private prepareCwd;
|
|
2100
|
+
/**
|
|
2101
|
+
* Land a task's work on the run's integration branches. The record is
|
|
2102
|
+
* reported changed once the landing is set and before the first merge, so
|
|
2103
|
+
* a crash mid-landing leaves the tips to roll back to, and again once it
|
|
2104
|
+
* settles. A git error is `failed`, never a throw.
|
|
2105
|
+
*/
|
|
2106
|
+
integrate(task: Task, commit?: HandoffCommit): Promise<IsolationOutcome>;
|
|
2107
|
+
private keepLandedOn;
|
|
2108
|
+
/** What a conflict repair's work shows (ADR-0015); git that cannot tell counts against it. */
|
|
2109
|
+
verifyRepair(task: Task): Promise<RepairEvidence>;
|
|
2110
|
+
/** What a repair brings onto the tip it was repaired against (ADR-0055 D14); throws where git cannot say, so nothing lands on a guess. */
|
|
2111
|
+
repairPaths(task: Task): Promise<string[]>;
|
|
2112
|
+
/**
|
|
2113
|
+
* Let go of a task's worktree. `keep` leaves it and its branch for
|
|
2114
|
+
* inspection; otherwise both go. A landing still in flight settles first, so
|
|
2115
|
+
* the worktree is never torn down underneath its merge. Bound to the run
|
|
2116
|
+
* the call was made in: a plan loaded meanwhile adopts its own run, whose
|
|
2117
|
+
* records share these task ids and are not this release's to touch.
|
|
2118
|
+
*/
|
|
2119
|
+
release(taskId: string, opts: {
|
|
2120
|
+
keep: boolean;
|
|
2121
|
+
}, landing?: Promise<unknown> | null): Promise<void>;
|
|
2122
|
+
/**
|
|
2123
|
+
* Close the open run. An isolated one hands its integration branch over for
|
|
2124
|
+
* review — unless everything it landed is merged already, at merge gates or
|
|
2125
|
+
* by the run's automatic Merge all, which leaves nothing to hand over, so it
|
|
2126
|
+
* is cleared up as a Merge all would have.
|
|
2127
|
+
*/
|
|
2128
|
+
close(): Promise<void>;
|
|
2129
|
+
/**
|
|
2130
|
+
* Whether a task's landed work still waits to be merged into the user's
|
|
2131
|
+
* branch — what holds an ops or user task at its merge gate (ADR-0020). A
|
|
2132
|
+
* task with no record never landed anything to wait for.
|
|
2133
|
+
*/
|
|
2134
|
+
awaitsMerge(taskId: string): boolean;
|
|
2135
|
+
/**
|
|
2136
|
+
* Look again for landed work the user has merged — by Merge all, or by hand
|
|
2137
|
+
* with git — or has taken back out. Resolves true when a mark changed.
|
|
2138
|
+
*/
|
|
2139
|
+
refreshInHead(): Promise<boolean>;
|
|
2140
|
+
/** Whether any landed work reads as merged: an answer git can take back, if the user takes the merge out. */
|
|
2141
|
+
get readsMerged(): boolean;
|
|
2142
|
+
/** Mark the run's landed work as git finds it now; true when a mark changed. */
|
|
2143
|
+
private findLanded;
|
|
2144
|
+
/** The run landed something and every landing is in the user's HEAD. */
|
|
2145
|
+
private allMerged;
|
|
2146
|
+
/**
|
|
2147
|
+
* The tracked state of the workspace as an attempt whose tree is checked
|
|
2148
|
+
* starts (see `attemptKind.checksTree`), for {@link filesChangedSince}
|
|
2149
|
+
* (ADR-0020). Null where the check does not run: a run that shares the
|
|
2150
|
+
* workspace root, where every task's edits land in it, or a workspace git
|
|
2151
|
+
* cannot isolate at all.
|
|
2152
|
+
*/
|
|
2153
|
+
snapshotWorkspace(): Promise<TreeSnapshot | null>;
|
|
2154
|
+
/** Tracked files changed since `snapshot`; none when the run has since gone on in the workspace root. */
|
|
2155
|
+
filesChangedSince(snapshot: TreeSnapshot | null): Promise<string[]>;
|
|
2156
|
+
/**
|
|
2157
|
+
* A stop or a plan load: the open run ends without a handoff and a parked
|
|
2158
|
+
* start is dropped. `keepOpen` spares a run the scheduler is still driving.
|
|
2159
|
+
*/
|
|
2160
|
+
interrupt(opts?: {
|
|
2161
|
+
keepOpen?: boolean;
|
|
2162
|
+
}): void;
|
|
2163
|
+
/**
|
|
2164
|
+
* Mark which added task resolves which conflict. The resolver merges the
|
|
2165
|
+
* conflicted task's branch by hand in its own worktree; once that lands, the
|
|
2166
|
+
* conflicted task can land in turn — through the same merge, so a resolver
|
|
2167
|
+
* that did not really bring it along conflicts again instead of being taken
|
|
2168
|
+
* at its word.
|
|
2169
|
+
*/
|
|
2170
|
+
linkResolver(resolverId: string, conflictedId: string): void;
|
|
2171
|
+
/** The conflicted task a landed resolver was added for, forgotten as it is returned. */
|
|
2172
|
+
takeResolver(resolverId: string): string | undefined;
|
|
2173
|
+
/** The tasks added to resolve this task's conflict: one, but for a plan saved before that was the rule (ADR-0015). */
|
|
2174
|
+
resolversOf(conflictedId: string): string[];
|
|
2175
|
+
/** The paths a task's branch changed since its base, by their place in the workspace. Throws where they cannot be read: a verdict that rests on them fails closed (ADR-0055 D6). */
|
|
2176
|
+
changedPaths(taskId: string): Promise<string[]>;
|
|
2177
|
+
/** The branch this run's work lands on, which a board's files are compared with (ADR-0057 R9). */
|
|
2178
|
+
get integrationBranch(): string | undefined;
|
|
2179
|
+
/** See {@link IWorktreeIsolation.blobOn}. */
|
|
2180
|
+
blobOn(branch: string, file: string): Promise<string | null | undefined>;
|
|
2181
|
+
taskDiff(taskId: string, options: TaskDiffRead): Promise<TaskDiffResult>;
|
|
2182
|
+
reviewDiff(): Promise<string>;
|
|
2183
|
+
/**
|
|
2184
|
+
* "Merge all": the run's integration branches into whatever the user has
|
|
2185
|
+
* checked out, in every repo or none. During a run it merges what has
|
|
2186
|
+
* landed so far and the run goes on (ADR-0020): its branches stay for the
|
|
2187
|
+
* tasks still to land. Once a settled run merged everything, it has nothing
|
|
2188
|
+
* left to hand over, so it is cleared up and forgotten; a branch the user's
|
|
2189
|
+
* HEAD somehow does not contain stays for the next run's sweep.
|
|
2190
|
+
*/
|
|
2191
|
+
merge(): Promise<IsolationMergeResult>;
|
|
2192
|
+
/** What git says of landed work a revert would take; see {@link IWorktreeIsolation.readLanded}. */
|
|
2193
|
+
readLanded(taskIds: readonly string[]): Promise<LandedWork>;
|
|
2194
|
+
/**
|
|
2195
|
+
* Revert tasks' landings on the integration branches (ADR-0054). The record
|
|
2196
|
+
* is reported changed once the tips are set and before the first commit,
|
|
2197
|
+
* again as each commit is made, so a crash leaves it to tell them from
|
|
2198
|
+
* anyone's, and once it settles. Bound to the run it was
|
|
2199
|
+
* asked in: a plan loaded meanwhile has records of its own under these ids,
|
|
2200
|
+
* and is saved without what this would write to that run's branches, so it
|
|
2201
|
+
* stops the revert and leaves them as they were.
|
|
2202
|
+
*/
|
|
2203
|
+
revert(taskIds: readonly string[], watch: Omit<RevertWatch, 'persist'>): Promise<IsolationRevertResult>;
|
|
2204
|
+
/**
|
|
2205
|
+
* Worktrees and task branches go; the integration branch and the record stay
|
|
2206
|
+
* for review and merge. Refused while a task of the run is still live.
|
|
2207
|
+
*/
|
|
2208
|
+
cleanup(): Promise<void>;
|
|
2209
|
+
/**
|
|
2210
|
+
* The run and everything it made go, and the plan forgets it; the next run
|
|
2211
|
+
* starts afresh. Refused while a task of the run is still live.
|
|
2212
|
+
*/
|
|
2213
|
+
discard(): Promise<void>;
|
|
2214
|
+
/** The records of tasks still live, whose worktrees no clean-up of the whole run may take. */
|
|
2215
|
+
private liveRecords;
|
|
2216
|
+
private refuseWhileLive;
|
|
2217
|
+
/**
|
|
2218
|
+
* Clear a settled run up once everything it landed is merged — and only
|
|
2219
|
+
* when nothing else is left in it: a live task, or a worktree holding work
|
|
2220
|
+
* that never landed, keeps the whole run, worktrees and branches, rather
|
|
2221
|
+
* than leaving that work to a deletion.
|
|
2222
|
+
*/
|
|
2223
|
+
private clearMerged;
|
|
2224
|
+
/** The records that keep a settled run from being cleared up: live, or holding work that never landed. */
|
|
2225
|
+
private holdouts;
|
|
2226
|
+
/** The run's worktrees and merged branches go; false, said, when git would not let them. */
|
|
2227
|
+
private discardMerged;
|
|
2228
|
+
/** Say what a removal kept back instead of deleting: where the work went, or which worktree stayed. */
|
|
2229
|
+
private report;
|
|
2230
|
+
/** The branches the links' resolvers would merge have gone: the links go, and the scheduler is told of the tasks left. */
|
|
2231
|
+
private endResolvers;
|
|
2232
|
+
/** The run goes from the plan; `merged` names it as {@link mergedRun} when everything it landed was merged. */
|
|
2233
|
+
private forget;
|
|
2234
|
+
private assess;
|
|
2235
|
+
private activate;
|
|
2236
|
+
private begin;
|
|
2237
|
+
/** What earlier runs left merged in the group goes; a failure here is worth a word, never a stopped run. */
|
|
2238
|
+
private sweep;
|
|
2239
|
+
/**
|
|
2240
|
+
* The plan's run carries on while it still has any record: anything landed
|
|
2241
|
+
* means a resumed plan's dependents must start from a tip that holds their
|
|
2242
|
+
* predecessors' work, and anything held — a kept attempt, a conflict, a
|
|
2243
|
+
* repair — is work the user may still want, which a fresh run's mint would
|
|
2244
|
+
* delete. Only a run with no records at all is superseded, and not one that
|
|
2245
|
+
* reverted the tasks it had: a retry starts from its tip (ADR-0054). A record
|
|
2246
|
+
* that names a child holds a code root, on a path that child's own run is tied
|
|
2247
|
+
* to, whether or not a Stop has yet taken it off `active` (ADR-0055 D17).
|
|
2248
|
+
*/
|
|
2249
|
+
private continuableRun;
|
|
2250
|
+
/**
|
|
2251
|
+
* A run with no records at all holds only superseded attempts, so it goes —
|
|
2252
|
+
* but its integration branch only where the user's HEAD contains it, as does
|
|
2253
|
+
* that of a run that cannot be continued for another reason (it ran from a
|
|
2254
|
+
* different workspace path): only the user gives landed work up.
|
|
2255
|
+
*
|
|
2256
|
+
* False when `interrupted` came while git was minting: a newer activation
|
|
2257
|
+
* may be minting its own run, so this one is never installed over it, and
|
|
2258
|
+
* is discarded rather than left as branches no record names.
|
|
2259
|
+
*/
|
|
2260
|
+
private mint;
|
|
2261
|
+
private reportCopies;
|
|
2262
|
+
private reportSetupFailures;
|
|
2263
|
+
/** Said at the first isolated run, where Ordewell first leans on git and where `git-missing` is said; a child's parent has said it already. */
|
|
2264
|
+
private sayGitShortfall;
|
|
2265
|
+
private tell;
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
/** What a backend can be asked to prove (ADR-0059 L3). */
|
|
2269
|
+
type Guarantee = 'fs.hostHidden' | 'fs.writeScope' | 'net.allowlist' | 'net.noMetadata' | 'cred.unreadable' | 'kernel.separate' | 'limits.memory';
|
|
2270
|
+
/** What a probe found: how, and when. Never declared, so an unproven entry relaxes nothing (L3). */
|
|
2271
|
+
interface GuaranteeProof {
|
|
2272
|
+
proven: boolean;
|
|
2273
|
+
by: string;
|
|
2274
|
+
at: string;
|
|
2275
|
+
}
|
|
2276
|
+
type GuaranteeReport = Record<Guarantee, GuaranteeProof>;
|
|
2277
|
+
/**
|
|
2278
|
+
* Who asks, and in what role, which is policy input: a role is resolved to a
|
|
2279
|
+
* {@link LeaseSpec} before a backend sees one. `child-plan` reserves a node
|
|
2280
|
+
* and no slot (ADR-0055 D18). So does `merge`: it starts no session, and it
|
|
2281
|
+
* reaches a checkout, so a backend hears of it.
|
|
2282
|
+
*/
|
|
2283
|
+
interface LeaseRequest {
|
|
2284
|
+
node: {
|
|
2285
|
+
sessionId: string;
|
|
2286
|
+
taskId?: string;
|
|
2287
|
+
};
|
|
2288
|
+
role: 'planner' | 'task' | 'script' | 'child-plan' | 'merge';
|
|
2289
|
+
runner?: RunnerId;
|
|
2290
|
+
}
|
|
2291
|
+
/** Where a lease puts its session. */
|
|
2292
|
+
type LeaseWorkspace = {
|
|
2293
|
+
kind: 'checkout';
|
|
2294
|
+
} | {
|
|
2295
|
+
kind: 'worktree';
|
|
2296
|
+
intent: AttemptIntent;
|
|
2297
|
+
};
|
|
2298
|
+
interface LeaseSpec {
|
|
2299
|
+
/** The attempt's task, as the claim read it; a planner's lease has none. */
|
|
2300
|
+
task?: Task;
|
|
2301
|
+
workspace: LeaseWorkspace;
|
|
2302
|
+
/** Open fails if one of these cannot be proven. */
|
|
2303
|
+
required: readonly Guarantee[];
|
|
2304
|
+
}
|
|
2305
|
+
/** A runner's session, which is what a Continue resumes: the id on the host today, and more behind a container (L2). */
|
|
2306
|
+
interface LeaseSessionState {
|
|
2307
|
+
runner: string;
|
|
2308
|
+
nativeSessionId: string | null;
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* What outlives a lease (L2): a branch is not the whole result. A synchronous
|
|
2312
|
+
* read: the attempt that ends saves the session before anything can read it.
|
|
2313
|
+
*/
|
|
2314
|
+
interface LeaseResult {
|
|
2315
|
+
/** Each repo's branch, by repo path; empty for work with no worktree. */
|
|
2316
|
+
refs: Record<string, string>;
|
|
2317
|
+
sessionState: LeaseSessionState;
|
|
2318
|
+
}
|
|
2319
|
+
/** How a lease's session ended where the host could not watch it (L3); `expired` comes with the first backend that has a time limit. */
|
|
2320
|
+
type LeaseExit = 'oom' | 'killed';
|
|
2321
|
+
/** A runner's launch, as its adapter wrote it for this host. */
|
|
2322
|
+
interface RunnerLaunch {
|
|
2323
|
+
command: string;
|
|
2324
|
+
args: readonly string[];
|
|
2325
|
+
env: Readonly<Record<string, string>>;
|
|
2326
|
+
/** Paths on this host, named in `args`, that the process reads, the one holding its token among them. */
|
|
2327
|
+
files: readonly string[];
|
|
2328
|
+
}
|
|
2329
|
+
/** What this host launches instead. */
|
|
2330
|
+
interface PlacedLaunch {
|
|
2331
|
+
command: string;
|
|
2332
|
+
args: string[];
|
|
2333
|
+
env: Record<string, string>;
|
|
2334
|
+
/** End the process where it runs: killing what this host launched does not reach it. */
|
|
2335
|
+
stop(): void;
|
|
2336
|
+
/** The process has ended. */
|
|
2337
|
+
ended(): void;
|
|
2338
|
+
}
|
|
2339
|
+
/**
|
|
2340
|
+
* Where a lease that does not run its session on this host puts its runner. A
|
|
2341
|
+
* runner is still handed a cwd and nothing more (ADR-0013): only {@link RunnerProcess}
|
|
2342
|
+
* reads this, and an adapter writes the launch it always wrote.
|
|
2343
|
+
*/
|
|
2344
|
+
interface RunnerPlacement {
|
|
2345
|
+
place(launch: RunnerLaunch): Promise<PlacedLaunch>;
|
|
2346
|
+
/** Make a listener on this host's loopback reachable from there, and answer the URL to reach it by (`endpoints.mcp`). */
|
|
2347
|
+
reach(url: string): Promise<string>;
|
|
2348
|
+
/** The blob a file holds there, as git would name it, read where the attempt's work is; undefined for what cannot be read. */
|
|
2349
|
+
blob(file: string): Promise<string | undefined>;
|
|
2350
|
+
}
|
|
2351
|
+
/** One repository of an attempt's worktree, for a backend that keeps a copy of it elsewhere. */
|
|
2352
|
+
interface LeaseRepo {
|
|
2353
|
+
/** Relative to the workspace; `.` for a lone repository. */
|
|
2354
|
+
path: string;
|
|
2355
|
+
/** The repository on this host. */
|
|
2356
|
+
root: string;
|
|
2357
|
+
/** Its worktree for this task. */
|
|
2358
|
+
worktree: string;
|
|
2359
|
+
branch: string;
|
|
2360
|
+
integrationBranch: string;
|
|
2361
|
+
/** What Ordewell linked into the worktree, which is no attempt's work. */
|
|
2362
|
+
linked: readonly string[];
|
|
2363
|
+
}
|
|
2364
|
+
interface OpenLease {
|
|
2365
|
+
workspace: {
|
|
2366
|
+
cwd: string;
|
|
2367
|
+
/** The task workspace holding its worktrees, when it has any. */
|
|
2368
|
+
writable?: string;
|
|
2369
|
+
/** Whether it runs in a worktree prepared for it rather than at the root. */
|
|
2370
|
+
worktree: boolean;
|
|
2371
|
+
/** What became of the previous attempt's work, where a restore was asked for. */
|
|
2372
|
+
previousWork?: PreviousWork;
|
|
2373
|
+
/** Each repository of its worktree, plural as a repo group's are (ADR-0014). */
|
|
2374
|
+
repos?: readonly LeaseRepo[];
|
|
2375
|
+
};
|
|
2376
|
+
guarantees: GuaranteeReport;
|
|
2377
|
+
exportResult(session: LeaseSessionState): LeaseResult;
|
|
2378
|
+
/** Set where the runner does not run on this host. */
|
|
2379
|
+
placement?: RunnerPlacement;
|
|
2380
|
+
/** How its session ended, once it has, where the backend can tell (L3). */
|
|
2381
|
+
ended?(): Promise<LeaseExit | null>;
|
|
2382
|
+
}
|
|
2383
|
+
/**
|
|
2384
|
+
* Taken in the claim's synchronous step (L1). What it reserves is given back at
|
|
2385
|
+
* {@link release}; the workspace it opened need not go with it: a worktree
|
|
2386
|
+
* outlives the lease that made it, for a repair or a continue, so what becomes
|
|
2387
|
+
* of it is {@link ExecutionBackend.letGo}.
|
|
2388
|
+
*/
|
|
2389
|
+
interface ReservedLease {
|
|
2390
|
+
readonly id: string;
|
|
2391
|
+
/** Whether this lease holds a slot: a delegated task's and a merge's do not. */
|
|
2392
|
+
readonly holdsSlot: boolean;
|
|
2393
|
+
/** Runs after the claim, where the workspace is made. Rejects without making one once `signal` has aborted. */
|
|
2394
|
+
open(spec: LeaseSpec, signal: AbortSignal): Promise<OpenLease>;
|
|
2395
|
+
/** Idempotent and synchronous: an attempt's end frees its slot before anything awaits (ADR-0029). */
|
|
2396
|
+
release(reason: string): void;
|
|
2397
|
+
}
|
|
2398
|
+
/** One task's workspace, as a restart finds it. */
|
|
2399
|
+
interface LeaseRecord {
|
|
2400
|
+
taskId: string;
|
|
2401
|
+
status: string;
|
|
2402
|
+
worktrees: readonly string[];
|
|
2403
|
+
}
|
|
2404
|
+
interface ExecutionBackend {
|
|
2405
|
+
/** What it can prove now. */
|
|
2406
|
+
probe(): Promise<GuaranteeReport>;
|
|
2407
|
+
/** Why this may not be reserved now, or null. Synchronous, and changes nothing: it is also asked with no claim to follow. */
|
|
2408
|
+
refusal(request: LeaseRequest): string | null;
|
|
2409
|
+
/** Synchronous, inside the claim. A refusal keeps the Session that asked, for what frees next. */
|
|
2410
|
+
reserve(request: LeaseRequest): {
|
|
2411
|
+
lease: ReservedLease;
|
|
2412
|
+
} | {
|
|
2413
|
+
refused: string;
|
|
2414
|
+
};
|
|
2415
|
+
/** What becomes of a task's workspace, with no lease needed: a kept worktree outlives the one that opened it. */
|
|
2416
|
+
letGo(taskId: string, how: {
|
|
2417
|
+
keep: boolean;
|
|
2418
|
+
landing?: Promise<unknown> | null;
|
|
2419
|
+
reason: string;
|
|
2420
|
+
}): Promise<void>;
|
|
2421
|
+
/** What a restart finds. Starts nothing (ADR-0044). */
|
|
2422
|
+
list(): Promise<readonly LeaseRecord[]>;
|
|
2423
|
+
/**
|
|
2424
|
+
* Bring a task's work to its worktree, for a backend that keeps it elsewhere:
|
|
2425
|
+
* the half of a result that takes time and can be refused (L2). By task, since
|
|
2426
|
+
* a landing can come after its attempt, as a Mark complete does. Absent, the
|
|
2427
|
+
* work is there already. Rejects with why it must not land.
|
|
2428
|
+
*/
|
|
2429
|
+
collect?(taskId: string): Promise<void>;
|
|
2430
|
+
/**
|
|
2431
|
+
* Everything it has running has gone and what was on its way has arrived, as
|
|
2432
|
+
* the Session around it closes. Absent, nothing outlives an attempt's runner.
|
|
2433
|
+
* What a next attempt comes back to stays, and it never rejects.
|
|
2434
|
+
*/
|
|
2435
|
+
settle?(): Promise<void>;
|
|
2436
|
+
/** The workspace root's repositories, where a run knows them: a repo group's root is no repository to ask. */
|
|
2437
|
+
checkoutRepos?(): readonly LeaseRepo[];
|
|
2438
|
+
/**
|
|
2439
|
+
* Let go of what its tree left where only it can reach, as a Clean up gives the
|
|
2440
|
+
* run up. Absent, there is nothing but the worktrees. Reports what it could not
|
|
2441
|
+
* clear, and never rejects: it is no reason for a clean-up to fail.
|
|
2442
|
+
*/
|
|
2443
|
+
reclaim?(): Promise<void>;
|
|
2444
|
+
}
|
|
2445
|
+
|
|
1758
2446
|
/**
|
|
1759
2447
|
* The harness-planner transport contract (ADR-0009).
|
|
1760
2448
|
*
|
|
@@ -2058,6 +2746,10 @@ interface PlannerStartOptions extends AgentStartCommon {
|
|
|
2058
2746
|
* these are the only ones it gets, and each is handed over as parsed.
|
|
2059
2747
|
*/
|
|
2060
2748
|
projectServers?: ProjectMcpServer[];
|
|
2749
|
+
/** The harness's own subagents are off for this session (ADR-0056 M6), each runner by its own switch. Absent means as the harness has them. */
|
|
2750
|
+
noSubagents?: true;
|
|
2751
|
+
/** What a subplanner's process loads of the user's setup (ADR-0057 R11); absent means `user`. */
|
|
2752
|
+
runnerConfig?: TaskRunnerConfig;
|
|
2061
2753
|
}
|
|
2062
2754
|
/**
|
|
2063
2755
|
* What a runner manifest says the task's mode and effort mean (ADR-0001),
|
|
@@ -2074,6 +2766,14 @@ interface TaskRunnerFlags {
|
|
|
2074
2766
|
/** The manifest's further settings for the task's mode, by setting name — see `RunnerFeatures.modeSettings`. */
|
|
2075
2767
|
modeSettings: Record<string, string>;
|
|
2076
2768
|
}
|
|
2769
|
+
/**
|
|
2770
|
+
* What a task runner loads of the user's own setup (the `taskRunnerConfig`
|
|
2771
|
+
* setting): `user` is everything the runner would load for the user,
|
|
2772
|
+
* `minimal` only what a task needs — Ordewell's server, the repository's
|
|
2773
|
+
* instructions — so the user's connectors, skills and settings do not ride in
|
|
2774
|
+
* every attempt's context. Runners that cannot narrow their setup ignore it.
|
|
2775
|
+
*/
|
|
2776
|
+
type TaskRunnerConfig = 'user' | 'minimal';
|
|
2077
2777
|
/** A plan task driven over the runner's programmatic protocol (ADR-0018, C1). */
|
|
2078
2778
|
interface TaskStartOptions extends AgentStartCommon {
|
|
2079
2779
|
kind: 'task';
|
|
@@ -2082,6 +2782,8 @@ interface TaskStartOptions extends AgentStartCommon {
|
|
|
2082
2782
|
/** The task's runner mode id, as the plan names it. */
|
|
2083
2783
|
mode: string;
|
|
2084
2784
|
flags: TaskRunnerFlags;
|
|
2785
|
+
/** What the runner loads of the user's setup; absent means `user`. */
|
|
2786
|
+
runnerConfig?: TaskRunnerConfig;
|
|
2085
2787
|
/** The attempt's work lands as a commit (ADR-0047): its completion contract asks for the message. */
|
|
2086
2788
|
commits?: true;
|
|
2087
2789
|
/**
|
|
@@ -2255,6 +2957,8 @@ interface AgentProcessDeps {
|
|
|
2255
2957
|
workspaceEnv?: (cwd: string) => Promise<Record<string, string>>;
|
|
2256
2958
|
/** Builds the sandbox around a planner's own shell (ADR-0036 N2). Defaults to the host's probe. */
|
|
2257
2959
|
nativeShellSandbox?: () => PlannerShellSandbox;
|
|
2960
|
+
/** Where a lease put this runner, when not on this host (ADR-0059 L5). */
|
|
2961
|
+
placement?: RunnerPlacement;
|
|
2258
2962
|
}
|
|
2259
2963
|
/** Builds the adapter for one runner id, or null when that runner cannot plan. */
|
|
2260
2964
|
type AgentAdapterFactory = (runner: string, deps: AgentProcessDeps) => AgentAdapter | null;
|
|
@@ -2740,7 +3444,7 @@ interface IRunnerSession {
|
|
|
2740
3444
|
* The runner's `task_complete` calls on this attempt's token (ADR-0022):
|
|
2741
3445
|
* the only completion evidence, for `VerdictEngine` to weigh.
|
|
2742
3446
|
*/
|
|
2743
|
-
onTaskComplete(listener: (report: TaskCompleteArgs) => void): void;
|
|
3447
|
+
onTaskComplete(listener: (report: TaskCompleteArgs, refuted?: VerificationCheck) => void): void;
|
|
2744
3448
|
/**
|
|
2745
3449
|
* Answers the runner's `checkpoint` calls (ADR-0022, V5): the call stays
|
|
2746
3450
|
* open until the returned promise settles, and its result is the answer.
|
|
@@ -2782,6 +3486,8 @@ interface IRunner {
|
|
|
2782
3486
|
* manifest's env still wins over them.
|
|
2783
3487
|
*/
|
|
2784
3488
|
env?: Record<string, string>;
|
|
3489
|
+
/** A delegated task's attempt (ADR-0055 D3): the task, for {@link ChildPlanRunner} to give its child. */
|
|
3490
|
+
delegated?: Task;
|
|
2785
3491
|
/** The runner's own session to continue in (ADR-0018, K1). */
|
|
2786
3492
|
resumeSessionId?: string;
|
|
2787
3493
|
/** What was counted of that session's running cost before, so its first turn is counted from there. */
|
|
@@ -2806,6 +3512,8 @@ interface IRunner {
|
|
|
2806
3512
|
* attempt. Runners ignore it; it is for what wraps one to record (task logs).
|
|
2807
3513
|
*/
|
|
2808
3514
|
skills?: readonly TaskSkillSnapshot[];
|
|
3515
|
+
/** Where the attempt's lease put this runner, when not on this host (ADR-0059 L5). */
|
|
3516
|
+
placement?: RunnerPlacement;
|
|
2809
3517
|
/** Something the user should know about how the spawn went that did not stop it — a respawn, most often. */
|
|
2810
3518
|
onNotice?: (message: string) => void;
|
|
2811
3519
|
/**
|
|
@@ -2823,8 +3531,12 @@ interface IRunner {
|
|
|
2823
3531
|
cancelled?: AbortSignal;
|
|
2824
3532
|
/** The attempt's work lands as a commit (ADR-0047): its runner is told to write the message in `task_complete`. */
|
|
2825
3533
|
commits?: true;
|
|
3534
|
+
/** What the runner loads of the user's own setup (the `taskRunnerConfig` setting); absent means all of it. Runners that cannot narrow it ignore it. */
|
|
3535
|
+
runnerConfig?: TaskRunnerConfig;
|
|
2826
3536
|
/** A script task's body (ADR-0035): only the script runner reads it, and it runs nothing else. */
|
|
2827
3537
|
script?: ScriptBody;
|
|
3538
|
+
/** A read-only script's shell (ADR-0055 D8): its body runs sealed there, in the worktree it was cut. */
|
|
3539
|
+
sealed?: TaskShell;
|
|
2828
3540
|
/**
|
|
2829
3541
|
* A read-only attempt's shell (ADR-0046): its token serves `run_command`
|
|
2830
3542
|
* from it, and only an attempt that has one is given that tool.
|
|
@@ -2835,12 +3547,14 @@ interface IRunner {
|
|
|
2835
3547
|
* arrives (ADR-0047): a refusal is the call's result, and nothing is
|
|
2836
3548
|
* recorded. Without one, a `task` reference resolves against no plan.
|
|
2837
3549
|
*/
|
|
2838
|
-
checkHandoff?: (completion: TaskCompleteArgs) => HandoffCheck<TaskCompleteArgs
|
|
3550
|
+
checkHandoff?: (completion: TaskCompleteArgs) => HandoffCheck<TaskCompleteArgs> | Promise<HandoffCheck<TaskCompleteArgs>>;
|
|
2839
3551
|
/**
|
|
2840
|
-
* Answers the attempt's `
|
|
3552
|
+
* Answers the attempt's `read` calls (ADR-0047), against the plan
|
|
2841
3553
|
* and the session's task logs. Without one the call says it is not available.
|
|
2842
3554
|
*/
|
|
2843
|
-
readTask?: (args: ReadTaskArgs) => McpToolReply
|
|
3555
|
+
readTask?: (args: ReadTaskArgs) => McpToolReply | Promise<McpToolReply>;
|
|
3556
|
+
/** Answers the attempt's `post` calls (ADR-0057 R8). Given only where its plan has a board, which is what lists the tool. */
|
|
3557
|
+
post?: (args: PostArgs) => McpToolReply | Promise<McpToolReply>;
|
|
2844
3558
|
/**
|
|
2845
3559
|
* Answers a read-only attempt's `save_patch` calls (ADR-0050): its shell
|
|
2846
3560
|
* captures the worktree's changes and the attempt keeps them. Without one
|
|
@@ -2868,4 +3582,121 @@ interface IRunner {
|
|
|
2868
3582
|
activeCount: number;
|
|
2869
3583
|
}
|
|
2870
3584
|
|
|
2871
|
-
|
|
3585
|
+
declare const BOARD_TYPES: readonly ["finding", "claim", "attempt", "artifact", "contract", "assume", "scope_change", "decision", "pin"];
|
|
3586
|
+
type BoardEntryType = (typeof BOARD_TYPES)[number];
|
|
3587
|
+
/** `file` evidence, with the blobs R9 compares: Ordewell reads both as the entry is posted, so neither is an author's claim. */
|
|
3588
|
+
interface BoardFile {
|
|
3589
|
+
kind: 'file';
|
|
3590
|
+
path: string;
|
|
3591
|
+
/** The file as its author had it, where it could be read. */
|
|
3592
|
+
sha?: string;
|
|
3593
|
+
/** What the board's branch held then, absent where it held no such file. */
|
|
3594
|
+
tip?: string;
|
|
3595
|
+
}
|
|
3596
|
+
/** What an author sends. */
|
|
3597
|
+
interface BoardPost {
|
|
3598
|
+
type: BoardEntryType;
|
|
3599
|
+
title: string;
|
|
3600
|
+
detail?: string;
|
|
3601
|
+
/** What `contested` compares (R9): entries with one key and different values. */
|
|
3602
|
+
key?: string;
|
|
3603
|
+
value?: string;
|
|
3604
|
+
files?: string[];
|
|
3605
|
+
}
|
|
3606
|
+
/** Whose words an entry is, as the token that posted it says and never the entry. */
|
|
3607
|
+
interface BoardAuthor {
|
|
3608
|
+
node: NodePath;
|
|
3609
|
+
/** Its task's label in that plan; absent for that plan's planner. */
|
|
3610
|
+
task?: string;
|
|
3611
|
+
attempt?: number;
|
|
3612
|
+
}
|
|
3613
|
+
interface BoardEntry extends Omit<BoardPost, 'files'> {
|
|
3614
|
+
/** The board it is on, and its number there: together its reference. */
|
|
3615
|
+
node: NodePath;
|
|
3616
|
+
id: number;
|
|
3617
|
+
by: BoardAuthor;
|
|
3618
|
+
at: string;
|
|
3619
|
+
files?: BoardFile[];
|
|
3620
|
+
/** The branch `files` was read against, which is the same for every reader. */
|
|
3621
|
+
branch?: string;
|
|
3622
|
+
/** The entry it was raised from at a landing (R6), which keeps its author. */
|
|
3623
|
+
raisedFrom?: {
|
|
3624
|
+
node: NodePath;
|
|
3625
|
+
id: number;
|
|
3626
|
+
};
|
|
3627
|
+
}
|
|
3628
|
+
/** An entry as the log is told of it: the ledger numbers it and the clock stamps it. */
|
|
3629
|
+
type BoardDraft = Omit<BoardEntry, 'node' | 'id' | 'at'>;
|
|
3630
|
+
|
|
3631
|
+
/** `root/3/2`: the ids from the root down. A node's parent never changes, so neither does this. */
|
|
3632
|
+
type NodePath = string;
|
|
3633
|
+
interface OfNode {
|
|
3634
|
+
/** When it was written: for a reader, and never read by a fold. */
|
|
3635
|
+
at: string;
|
|
3636
|
+
node: NodePath;
|
|
3637
|
+
}
|
|
3638
|
+
type TreeFact = OfNode & (
|
|
3639
|
+
/** A node joined the tree. Below the root its `limit` is carved from its parent, and `kept` of it stays for the subplanner's next turn (ADR-0056 M5). */
|
|
3640
|
+
{
|
|
3641
|
+
kind: 'node_opened';
|
|
3642
|
+
sessionId: string;
|
|
3643
|
+
taskId?: string;
|
|
3644
|
+
limit: number;
|
|
3645
|
+
kept: number;
|
|
3646
|
+
}
|
|
3647
|
+
/** `node` confirmed closed: its parent holds its `limit` no longer, and is charged what it spent. */
|
|
3648
|
+
| {
|
|
3649
|
+
kind: 'node_closed';
|
|
3650
|
+
}
|
|
3651
|
+
/** Tokens as a runner or planner reported them. A turn spends what its node kept first. */
|
|
3652
|
+
| {
|
|
3653
|
+
kind: 'tokens_spent';
|
|
3654
|
+
tokens: number;
|
|
3655
|
+
turn?: true;
|
|
3656
|
+
taskId?: string;
|
|
3657
|
+
attempt?: number;
|
|
3658
|
+
}
|
|
3659
|
+
/** A raise: `tokens` more on `node`'s limit, from its parent's room. */
|
|
3660
|
+
| {
|
|
3661
|
+
kind: 'budget_raised';
|
|
3662
|
+
tokens: number;
|
|
3663
|
+
}
|
|
3664
|
+
/** Its parent's own spending took `tokens` of `node`'s room: `node`'s limit and its parent's `committed` fall together. */
|
|
3665
|
+
| {
|
|
3666
|
+
kind: 'budget_taken';
|
|
3667
|
+
tokens: number;
|
|
3668
|
+
}
|
|
3669
|
+
/** A subplanner parked, keeping `tokens` more for its next turn. */
|
|
3670
|
+
| {
|
|
3671
|
+
kind: 'reserve_kept';
|
|
3672
|
+
tokens: number;
|
|
3673
|
+
}
|
|
3674
|
+
/** The user set the root's limit, the tree's budget, to `limit`. */
|
|
3675
|
+
| {
|
|
3676
|
+
kind: 'limit_set';
|
|
3677
|
+
limit: number;
|
|
3678
|
+
}
|
|
3679
|
+
/** An entry on `node`'s board, whole: a board is a fold of these (ADR-0057 R8). */
|
|
3680
|
+
| {
|
|
3681
|
+
kind: 'board_posted';
|
|
3682
|
+
entry: BoardEntry;
|
|
3683
|
+
});
|
|
3684
|
+
/** A fact as the log holds it: `seq` is its place in the tree's one order, from 1. */
|
|
3685
|
+
type TreeEvent = TreeFact & {
|
|
3686
|
+
seq: number;
|
|
3687
|
+
};
|
|
3688
|
+
|
|
3689
|
+
/**
|
|
3690
|
+
* One append-only log per root (ADR-0058 S3), behind a port so that a daemon
|
|
3691
|
+
* host can back it with SQLite later. Only the host holding the root's session
|
|
3692
|
+
* lease writes it (ADR-0055 D13).
|
|
3693
|
+
*/
|
|
3694
|
+
interface EventStore {
|
|
3695
|
+
/** In order, each batch whole: after a crash a reader finds all of a batch or none of it. Numbers them. */
|
|
3696
|
+
append(events: readonly TreeFact[]): Promise<void>;
|
|
3697
|
+
/** What came after the cursor, at `path` and below when one is named. */
|
|
3698
|
+
read(after: number, path?: NodePath): AsyncIterable<TreeEvent>;
|
|
3699
|
+
close(): Promise<void>;
|
|
3700
|
+
}
|
|
3701
|
+
|
|
3702
|
+
export { type InvokedCommand as $, AUTO_COMMANDS as A, type BashOptions as B, type CatalogModel as C, type CommandClassification as D, type CommandTier as E, ConsoleLogger as F, DENY_ALL as G, type DiscoveryCommand as H, type EditPlanArgs as I, type EventStore as J, type ExecutionBackend as K, type FetchAllProviderModelsOptions as L, type FindSymbolOptions as M, GIT_READONLY_SUBCOMMANDS as N, GREP_DEFAULT_HEAD_LIMIT as O, type GlobOptions as P, type GrepOptions as Q, type GrepOutputMode as R, type Guarantee as S, type GuaranteeReport as T, type IApproval as U, type IConfig as V, type IFileSystem as W, type ILogger as X, type INotification as Y, type IRunner as Z, type IRunnerSession as _, type AgentAdapter as a, type RunnerFeatures as a$, type IsolatedExecution as a0, IsolationRunController as a1, type LeaseRecord as a2, type LeaseRepo as a3, type LeaseRequest as a4, type LeaseSpec as a5, LineBuffer as a6, type ListModelsArgs as a7, type ListRunnersArgs as a8, type LoadSkillArgs as a9, type PlannerSandboxDeps as aA, PlannerShellSandbox as aB, type PlannerStartOptions as aC, type PlannerTokenScope as aD, type PlannerToolHandler as aE, type PostArgs as aF, type ProjectMcpServer as aG, type ProviderCredentialSource as aH, type ProviderModelLists as aI, type ProviderModelsResult as aJ, type QueuedTaskMessage as aK, READ_ONLY_TASK_TOOLS as aL, REFUSED_COMMANDS as aM, type ReadFileOpts as aN, type ReadTaskArgs as aO, type ResearchShell as aP, type ResearchShellDeps as aQ, type ReservedLease as aR, type RetryTaskArgs as aS, type RunCommandArgs as aT, type RunPlanArgs as aU, type RunnerAuthSpec as aV, type RunnerAuthStatus as aW, type RunnerCommand as aX, type RunnerCommandKind as aY, type RunnerEntry as aZ, type RunnerEnv as a_, type McpClientConfig as aa, type McpCredential as ab, type McpRefusal as ac, type McpTool as ad, type McpToolContext as ae, type McpToolReply as af, type MessageTaskArgs as ag, ModelCatalog as ah, type ModelShortcut as ai, type NodePath as aj, type NotificationAction as ak, ORCHESTRATOR_SHORTCUTS as al, ORDEWELL_MCP_PATH as am, ORDEWELL_MCP_SERVER_NAME as an, type OneTaskArgs as ao, type OpenLease as ap, type OrchestratorOption as aq, OrdewellMcpServer as ar, type OwnSealedRuns as as, type OwnerOnlyFile as at, PLANNER_EXECUTION_TOOLS as au, PLANNER_SANDBOX_DOCS as av, PLANNER_TOOLS as aw, type PlannerBackendId as ax, type PlannerModes as ay, type PlannerSandboxAvailability as az, type AgentAdapterFactory as b, fetchAllProviderModels as b$, type RunnerManifest as b0, type RunnerMcpServer as b1, type RunnerMode as b2, type RunnerModelDiscovery as b3, type RunnerModelRef as b4, type RunnerPlacement as b5, RunnerRegistry as b6, SEALED_LIMITS as b7, SEARCH_EXCLUSIONS as b8, type SandboxBackend as b9, type TaskMessageFrom as bA, type TaskModeAgentAdapter as bB, TaskModeUnsupportedError as bC, type TaskOutputArgs as bD, type TaskQueryArgs as bE, type TaskRunCommandArgs as bF, type TaskRunnerConfig as bG, type TaskRunnerFlags as bH, type TaskShell as bI, type TaskShellSite as bJ, type TaskStartOptions as bK, type TaskTokenScope as bL, type TaskToolHandler as bM, type TaskWebReads as bN, type ToolOutcome as bO, type TreeEvent as bP, type TreeFact as bQ, type UsageLimitSignal as bR, approvalScopes as bS, classifyCommand as bT, clearPlannerSandboxCache as bU, clearResearchShellCache as bV, collectProviderCredentials as bW, defaultLogger as bX, deleteSession as bY, effectiveApprovalMode as bZ, enabledRunners as b_, type SandboxInvocation as ba, type SandboxLaunch as bb, type SandboxLimits as bc, type SandboxProfile as bd, type ScriptExit as be, type ScriptFullOutput as bf, type ScriptRun as bg, type ScriptStatus as bh, type SealedAvailability as bi, type SealedRunOptions as bj, type SessionData as bk, type SessionMeta as bl, type ShellDialect as bm, type ShellLaunch as bn, type SkillLookup as bo, type SpawnFn as bp, type StandingDecision as bq, type StructuredEvent as br, type StructuredTurnEnd as bs, type SubmitPlanArgs as bt, TASK_COMPLETE_TOOL as bu, TASK_COMPLETION_CONTRACT as bv, TASK_SEALED_LIMITS as bw, TASK_TOOLS as bx, type TaskCompleteArgs as by, type TaskDiffArgs as bz, type AgentEvent as c, findRunnerCommand as c0, getLatestSession as c1, idSegment as c2, isGranted as c3, isRunnerApproval as c4, knownModelId as c5, listChildSessions as c6, listSessions as c7, loadChildSession as c8, loadSession as c9, loadSessionPlanState as ca, mcpClientConfig as cb, ownerOnlyConfigFile as cc, parseApprovalModeSetting as cd, plannerToolSet as ce, researchShellWarning as cf, researchToolsPath as cg, resolveModelShortcut as ch, resolvePlannerSandbox as ci, resolveProvider as cj, resolveResearchShell as ck, saveChildSession as cl, saveSession as cm, sessionDataDir as cn, sharedMcpServer as co, taskCompletionContract as cp, taskToolSet as cq, toApprovalDecision as cr, toOrchestratorOptions as cs, toolListing as ct, type AgentProcessDeps as d, type AgentStartOptions as e, type AiProvider as f, type AllProviderModels as g, type AnswerApprovalArgs as h, type ApplyPatchArgs as i, type ApprovalAnswer as j, type ApprovalDecision as k, type ApprovalKind as l, type ApprovalMode as m, type ApprovalModeSetting as n, ApprovalPolicy as o, type ApprovalPolicyOptions as p, type ApprovalRequest as q, type ApprovalSource as r, type AttachState as s, type BoardAuthor as t, type BoardDraft as u, type BoardEntry as v, type BoardPost as w, type CheckpointAnswer as x, type CheckpointArgs as y, type ChildSessionPlace as z };
|