@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
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/models/TreeEvent.ts
|
|
2
|
+
var SESSION_RESERVE_TOKENS = 2e5;
|
|
3
|
+
var ROOT_NODE = "root";
|
|
4
|
+
function childPath(parent, id) {
|
|
5
|
+
return `${parent}/${id}`;
|
|
6
|
+
}
|
|
7
|
+
function parentPath(node) {
|
|
8
|
+
const at = node.lastIndexOf("/");
|
|
9
|
+
return at === -1 ? null : node.slice(0, at);
|
|
10
|
+
}
|
|
11
|
+
function isWithin(node, ancestor) {
|
|
12
|
+
return node === ancestor || node.startsWith(`${ancestor}/`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// src/services/executionLease.ts
|
|
16
|
+
var GUARANTEES = ["fs.hostHidden", "fs.writeScope", "net.allowlist", "net.noMetadata", "cred.unreadable", "kernel.separate", "limits.memory"];
|
|
17
|
+
var LeaseGuaranteeError = class extends Error {
|
|
18
|
+
constructor(unproven) {
|
|
19
|
+
super(`This session requires ${unproven.join(", ")}, which its execution backend could not prove.`);
|
|
20
|
+
this.unproven = unproven;
|
|
21
|
+
this.name = "LeaseGuaranteeError";
|
|
22
|
+
}
|
|
23
|
+
unproven;
|
|
24
|
+
};
|
|
25
|
+
var KeptWorkError = class extends Error {
|
|
26
|
+
constructor(message) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.name = "KeptWorkError";
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
function refuseUnproven(required, report) {
|
|
32
|
+
const unproven = required.filter((guarantee) => !report[guarantee].proven);
|
|
33
|
+
if (unproven.length > 0) throw new LeaseGuaranteeError(unproven);
|
|
34
|
+
}
|
|
35
|
+
var CHECKOUT_BRANCH = "ordewell/checkout";
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
SESSION_RESERVE_TOKENS,
|
|
39
|
+
ROOT_NODE,
|
|
40
|
+
childPath,
|
|
41
|
+
parentPath,
|
|
42
|
+
isWithin,
|
|
43
|
+
GUARANTEES,
|
|
44
|
+
KeptWorkError,
|
|
45
|
+
refuseUnproven,
|
|
46
|
+
CHECKOUT_BRANCH
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=chunk-UDUATSCJ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/models/TreeEvent.ts","../src/services/executionLease.ts"],"sourcesContent":["import type { BoardEntry } from './Board';\n\n/**\n * A live session's allowance for what it has in flight (ADR-0056 M5), which is\n * one model call: a long context's prompt, its cache reads included, and a reply.\n * An estimate: a runner's own subagents add requests nobody sees until their\n * usage arrives.\n */\nexport const SESSION_RESERVE_TOKENS = 200_000;\n\n/*\n * What a tree's log holds (ADR-0058 S3). State is a fold of these, so an event\n * says what was decided, amounts included, and a replay decides nothing. A new\n * kind is a new member of the union: a fold passes over what it does not read.\n */\n\n/** A node's place among its parent's children, counted from 1 and never reused or moved. */\nexport type NodeId = string;\n\n/** `root/3/2`: the ids from the root down. A node's parent never changes, so neither does this. */\nexport type NodePath = string;\n\nexport const ROOT_NODE: NodePath = 'root';\n\nexport function childPath(parent: NodePath, id: NodeId): NodePath {\n return `${parent}/${id}`;\n}\n\n/** The parent of `node`, or null for the root. */\nexport function parentPath(node: NodePath): NodePath | null {\n const at = node.lastIndexOf('/');\n return at === -1 ? null : node.slice(0, at);\n}\n\n/** Whether `node` is `ancestor` or under it. */\nexport function isWithin(node: NodePath, ancestor: NodePath): boolean {\n return node === ancestor || node.startsWith(`${ancestor}/`);\n}\n\ninterface OfNode {\n /** When it was written: for a reader, and never read by a fold. */\n at: string;\n node: NodePath;\n}\n\nexport type TreeFact = OfNode & (\n /** 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). */\n | { kind: 'node_opened'; sessionId: string; taskId?: string; limit: number; kept: number }\n /** `node` confirmed closed: its parent holds its `limit` no longer, and is charged what it spent. */\n | { kind: 'node_closed' }\n /** Tokens as a runner or planner reported them. A turn spends what its node kept first. */\n | { kind: 'tokens_spent'; tokens: number; turn?: true; taskId?: string; attempt?: number }\n /** A raise: `tokens` more on `node`'s limit, from its parent's room. */\n | { kind: 'budget_raised'; tokens: number }\n /** Its parent's own spending took `tokens` of `node`'s room: `node`'s limit and its parent's `committed` fall together. */\n | { kind: 'budget_taken'; tokens: number }\n /** A subplanner parked, keeping `tokens` more for its next turn. */\n | { kind: 'reserve_kept'; tokens: number }\n /** The user set the root's limit, the tree's budget, to `limit`. */\n | { kind: 'limit_set'; limit: number }\n /** An entry on `node`'s board, whole: a board is a fold of these (ADR-0057 R8). */\n | { kind: 'board_posted'; entry: BoardEntry }\n);\n\n/** A fact as the log holds it: `seq` is its place in the tree's one order, from 1. */\nexport type TreeEvent = TreeFact & { seq: number };\n","import type { PreviousWork } from '../interfaces/IWorktreeIsolation';\nimport type { RunnerId, Task } from '../models/Task';\nimport type { AttemptIntent } from './IsolationRunController';\n\n/*\n * The execution lease (ADR-0059): where a session runs, behind one seam, as\n * `LocalWorktreeLease` and the Docker backend need it. What only the egress\n * sidecar and the model gateway need comes with them (ADR-0059 L7).\n */\n\n/** What a backend can be asked to prove (ADR-0059 L3). */\nexport type Guarantee = 'fs.hostHidden' | 'fs.writeScope' | 'net.allowlist' | 'net.noMetadata' | 'cred.unreadable' | 'kernel.separate' | 'limits.memory';\n\nexport const GUARANTEES: readonly Guarantee[] = ['fs.hostHidden', 'fs.writeScope', 'net.allowlist', 'net.noMetadata', 'cred.unreadable', 'kernel.separate', 'limits.memory'];\n\n/** What a probe found: how, and when. Never declared, so an unproven entry relaxes nothing (L3). */\nexport interface GuaranteeProof {\n proven: boolean;\n by: string;\n at: string;\n}\n\nexport type GuaranteeReport = Record<Guarantee, GuaranteeProof>;\n\n/** An open that required a guarantee its backend's probe could not prove. */\nexport class LeaseGuaranteeError extends Error {\n constructor(readonly unproven: readonly Guarantee[]) {\n super(`This session requires ${unproven.join(', ')}, which its execution backend could not prove.`);\n this.name = 'LeaseGuaranteeError';\n }\n}\n\n/**\n * Work its backend would not bring back, which stays where it is and waits on\n * the user (L2): an attempt that meets it fails, and lets go of nothing.\n */\nexport class KeptWorkError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'KeptWorkError';\n }\n}\n\n/** L3's one rule: an open fails on a required entry its probe did not prove, whatever the backend. */\nexport function refuseUnproven(required: readonly Guarantee[], report: GuaranteeReport): void {\n const unproven = required.filter((guarantee) => !report[guarantee].proven);\n if (unproven.length > 0) throw new LeaseGuaranteeError(unproven);\n}\n\n/**\n * Who asks, and in what role, which is policy input: a role is resolved to a\n * {@link LeaseSpec} before a backend sees one. `child-plan` reserves a node\n * and no slot (ADR-0055 D18). So does `merge`: it starts no session, and it\n * reaches a checkout, so a backend hears of it.\n */\nexport interface LeaseRequest {\n node: { sessionId: string; taskId?: string };\n role: 'planner' | 'task' | 'script' | 'child-plan' | 'merge';\n runner?: RunnerId;\n}\n\n/** Where a lease puts its session. */\nexport type LeaseWorkspace = { kind: 'checkout' } | { kind: 'worktree'; intent: AttemptIntent };\n\nexport interface LeaseSpec {\n /** The attempt's task, as the claim read it; a planner's lease has none. */\n task?: Task;\n workspace: LeaseWorkspace;\n /** Open fails if one of these cannot be proven. */\n required: readonly Guarantee[];\n}\n\n/** A runner's session, which is what a Continue resumes: the id on the host today, and more behind a container (L2). */\nexport interface LeaseSessionState {\n runner: string;\n nativeSessionId: string | null;\n}\n\n/**\n * What outlives a lease (L2): a branch is not the whole result. A synchronous\n * read: the attempt that ends saves the session before anything can read it.\n */\nexport interface LeaseResult {\n /** Each repo's branch, by repo path; empty for work with no worktree. */\n refs: Record<string, string>;\n sessionState: LeaseSessionState;\n}\n\n/** 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. */\nexport type LeaseExit = 'oom' | 'killed';\n\n/** A runner's launch, as its adapter wrote it for this host. */\nexport interface RunnerLaunch {\n command: string;\n args: readonly string[];\n env: Readonly<Record<string, string>>;\n /** Paths on this host, named in `args`, that the process reads, the one holding its token among them. */\n files: readonly string[];\n}\n\n/** What this host launches instead. */\nexport interface PlacedLaunch {\n command: string;\n args: string[];\n env: Record<string, string>;\n /** End the process where it runs: killing what this host launched does not reach it. */\n stop(): void;\n /** The process has ended. */\n ended(): void;\n}\n\n/**\n * Where a lease that does not run its session on this host puts its runner. A\n * runner is still handed a cwd and nothing more (ADR-0013): only {@link RunnerProcess}\n * reads this, and an adapter writes the launch it always wrote.\n */\nexport interface RunnerPlacement {\n place(launch: RunnerLaunch): Promise<PlacedLaunch>;\n /** Make a listener on this host's loopback reachable from there, and answer the URL to reach it by (`endpoints.mcp`). */\n reach(url: string): Promise<string>;\n /** The blob a file holds there, as git would name it, read where the attempt's work is; undefined for what cannot be read. */\n blob(file: string): Promise<string | undefined>;\n}\n\n/** What a copy of a checkout is on where a backend keeps it: no ref of the user's is at stake, and it stands on HEAD as it is. */\nexport const CHECKOUT_BRANCH = 'ordewell/checkout';\n\n/** One repository of an attempt's worktree, for a backend that keeps a copy of it elsewhere. */\nexport interface LeaseRepo {\n /** Relative to the workspace; `.` for a lone repository. */\n path: string;\n /** The repository on this host. */\n root: string;\n /** Its worktree for this task. */\n worktree: string;\n branch: string;\n integrationBranch: string;\n /** What Ordewell linked into the worktree, which is no attempt's work. */\n linked: readonly string[];\n}\n\nexport interface OpenLease {\n workspace: {\n cwd: string;\n /** The task workspace holding its worktrees, when it has any. */\n writable?: string;\n /** Whether it runs in a worktree prepared for it rather than at the root. */\n worktree: boolean;\n /** What became of the previous attempt's work, where a restore was asked for. */\n previousWork?: PreviousWork;\n /** Each repository of its worktree, plural as a repo group's are (ADR-0014). */\n repos?: readonly LeaseRepo[];\n };\n guarantees: GuaranteeReport;\n exportResult(session: LeaseSessionState): LeaseResult;\n /** Set where the runner does not run on this host. */\n placement?: RunnerPlacement;\n /** How its session ended, once it has, where the backend can tell (L3). */\n ended?(): Promise<LeaseExit | null>;\n}\n\n/**\n * Taken in the claim's synchronous step (L1). What it reserves is given back at\n * {@link release}; the workspace it opened need not go with it: a worktree\n * outlives the lease that made it, for a repair or a continue, so what becomes\n * of it is {@link ExecutionBackend.letGo}.\n */\nexport interface ReservedLease {\n readonly id: string;\n /** Whether this lease holds a slot: a delegated task's and a merge's do not. */\n readonly holdsSlot: boolean;\n /** Runs after the claim, where the workspace is made. Rejects without making one once `signal` has aborted. */\n open(spec: LeaseSpec, signal: AbortSignal): Promise<OpenLease>;\n /** Idempotent and synchronous: an attempt's end frees its slot before anything awaits (ADR-0029). */\n release(reason: string): void;\n}\n\n/** One task's workspace, as a restart finds it. */\nexport interface LeaseRecord {\n taskId: string;\n status: string;\n worktrees: readonly string[];\n}\n\nexport interface ExecutionBackend {\n /** What it can prove now. */\n probe(): Promise<GuaranteeReport>;\n /** Why this may not be reserved now, or null. Synchronous, and changes nothing: it is also asked with no claim to follow. */\n refusal(request: LeaseRequest): string | null;\n /** Synchronous, inside the claim. A refusal keeps the Session that asked, for what frees next. */\n reserve(request: LeaseRequest): { lease: ReservedLease } | { refused: string };\n /** What becomes of a task's workspace, with no lease needed: a kept worktree outlives the one that opened it. */\n letGo(taskId: string, how: { keep: boolean; landing?: Promise<unknown> | null; reason: string }): Promise<void>;\n /** What a restart finds. Starts nothing (ADR-0044). */\n list(): Promise<readonly LeaseRecord[]>;\n /**\n * Bring a task's work to its worktree, for a backend that keeps it elsewhere:\n * the half of a result that takes time and can be refused (L2). By task, since\n * a landing can come after its attempt, as a Mark complete does. Absent, the\n * work is there already. Rejects with why it must not land.\n */\n collect?(taskId: string): Promise<void>;\n /**\n * Everything it has running has gone and what was on its way has arrived, as\n * the Session around it closes. Absent, nothing outlives an attempt's runner.\n * What a next attempt comes back to stays, and it never rejects.\n */\n settle?(): Promise<void>;\n /** The workspace root's repositories, where a run knows them: a repo group's root is no repository to ask. */\n checkoutRepos?(): readonly LeaseRepo[];\n /**\n * Let go of what its tree left where only it can reach, as a Clean up gives the\n * run up. Absent, there is nothing but the worktrees. Reports what it could not\n * clear, and never rejects: it is no reason for a clean-up to fail.\n */\n reclaim?(): Promise<void>;\n}\n"],"mappings":";AAQO,IAAM,yBAAyB;AAc/B,IAAM,YAAsB;AAE5B,SAAS,UAAU,QAAkB,IAAsB;AAChE,SAAO,GAAG,MAAM,IAAI,EAAE;AACxB;AAGO,SAAS,WAAW,MAAiC;AAC1D,QAAM,KAAK,KAAK,YAAY,GAAG;AAC/B,SAAO,OAAO,KAAK,OAAO,KAAK,MAAM,GAAG,EAAE;AAC5C;AAGO,SAAS,SAAS,MAAgB,UAA6B;AACpE,SAAO,SAAS,YAAY,KAAK,WAAW,GAAG,QAAQ,GAAG;AAC5D;;;ACxBO,IAAM,aAAmC,CAAC,iBAAiB,iBAAiB,iBAAiB,kBAAkB,mBAAmB,mBAAmB,eAAe;AAYpK,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAC7C,YAAqB,UAAgC;AACnD,UAAM,yBAAyB,SAAS,KAAK,IAAI,CAAC,gDAAgD;AAD/E;AAEnB,SAAK,OAAO;AAAA,EACd;AAAA,EAHqB;AAIvB;AAMO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,SAAS,eAAe,UAAgC,QAA+B;AAC5F,QAAM,WAAW,SAAS,OAAO,CAAC,cAAc,CAAC,OAAO,SAAS,EAAE,MAAM;AACzE,MAAI,SAAS,SAAS,EAAG,OAAM,IAAI,oBAAoB,QAAQ;AACjE;AA8EO,IAAM,kBAAkB;","names":[]}
|