@oisin-ee/pi-todo 0.7.1 → 0.8.0
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/README.md +4 -4
- package/package.json +1 -1
- package/src/contract-fixture.ts +103 -0
- package/src/display.ts +8 -2
- package/src/gate.ts +79 -0
- package/src/generated/todo_core.d.ts +342 -5
- package/src/generated/todo_core.js +222 -5
- package/src/generated/todo_core_bg.wasm +0 -0
- package/src/generated/todo_core_bg.wasm.d.ts +8 -1
- package/src/guidance.ts +5 -1
- package/src/handoff.ts +84 -0
- package/src/import-fixture.ts +63 -0
- package/src/index.ts +17 -43
- package/src/lease-fixture.ts +95 -0
- package/src/provider-fixture.ts +50 -0
- package/src/provider.ts +289 -0
- package/src/registration-fixture.ts +126 -0
- package/src/repository.ts +31 -0
- package/src/runtime-fixture.ts +209 -0
- package/src/schema.ts +86 -0
- package/src/seed-fixture.ts +35 -0
- package/src/seed-transport.ts +52 -0
- package/src/source.ts +33 -3
- package/src/state.ts +78 -1
- package/src/tool.ts +15 -14
- package/src/wasm.ts +26 -0
package/README.md
CHANGED
|
@@ -82,14 +82,14 @@ Outside the terminal UI, `/todos` prints the list instead.
|
|
|
82
82
|
|
|
83
83
|
## Shared work display
|
|
84
84
|
|
|
85
|
-
When a compatible pi-
|
|
86
|
-
Tasks remain on the current Pi session branch.
|
|
87
|
-
Pi-todo owns the renderer in both standalone and shared views.
|
|
85
|
+
When a compatible pi-dogsled extension is active, its work widget replaces the standalone todo widget.
|
|
86
|
+
Tasks remain on the current Pi session branch. Dogsled receives a read-only presentation capability through `pi.events`.
|
|
87
|
+
Pi-todo owns the renderer in both standalone and shared views. Dogsled hosts it above the editor without opening a popup.
|
|
88
88
|
Alt+J/K scrolls the hosted rows. Alt+I toggles their expansion. Ordinary editor keys remain unchanged.
|
|
89
89
|
`/todos` and Alt+T request the shared Todos view. `/todos list` still prints the full list.
|
|
90
90
|
When shared presentation ends, the standalone widget returns without changing task state.
|
|
91
91
|
|
|
92
|
-
The [version 2 display contract](https://github.com/oisin-ee/
|
|
92
|
+
The [version 2 display contract](https://github.com/oisin-ee/dogsled/blob/main/docs/pi-work.md)
|
|
93
93
|
defines the snapshot request, acknowledgement, release, and read-only view events.
|
|
94
94
|
Incompatible versions leave the standalone widget available. Rendering failures restore it without changing saved tasks.
|
|
95
95
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { TodoParams, TodoSession } from "./tool.ts";
|
|
2
|
+
import { STATE_ENTRY } from "./state.ts";
|
|
3
|
+
import type { SessionEntry } from "@earendil-works/pi-coding-agent";
|
|
4
|
+
import type { TodoList } from "./wasm.ts";
|
|
5
|
+
import { runTodo } from "./tool.ts";
|
|
6
|
+
|
|
7
|
+
interface Fixture {
|
|
8
|
+
readonly entries: SessionEntry[];
|
|
9
|
+
readonly session: TodoSession;
|
|
10
|
+
readonly call: (params: TodoParams) => TodoList;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a branch-backed caller using the real tool and WASM core.
|
|
15
|
+
* @param {readonly unknown[]} snapshots Existing stored snapshots.
|
|
16
|
+
* @returns {Fixture} The tool caller and Pi append seam.
|
|
17
|
+
*/
|
|
18
|
+
const first = 0,
|
|
19
|
+
second = 1,
|
|
20
|
+
third = 2,
|
|
21
|
+
last = -1,
|
|
22
|
+
fixture = (snapshots: readonly unknown[] = []): Fixture => {
|
|
23
|
+
const entries = snapshots.map((data): SessionEntry => ({
|
|
24
|
+
customType: STATE_ENTRY,
|
|
25
|
+
data,
|
|
26
|
+
id: crypto.randomUUID(),
|
|
27
|
+
parentId: null,
|
|
28
|
+
timestamp: "2026-10-20T00:00:00Z",
|
|
29
|
+
type: "custom",
|
|
30
|
+
})),
|
|
31
|
+
session: TodoSession = {
|
|
32
|
+
append: (customType, data): void => {
|
|
33
|
+
entries.push({
|
|
34
|
+
customType,
|
|
35
|
+
data,
|
|
36
|
+
id: crypto.randomUUID(),
|
|
37
|
+
parentId: entries.at(last)?.id ?? null,
|
|
38
|
+
timestamp: "2026-10-20T00:00:00Z",
|
|
39
|
+
type: "custom",
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
branch: () => entries,
|
|
43
|
+
sessionId: "test-session",
|
|
44
|
+
};
|
|
45
|
+
return { call: (params) => runTodo(params, session).details, entries, session };
|
|
46
|
+
},
|
|
47
|
+
/**
|
|
48
|
+
* A complete self-assigned contract for deterministic behavior tests.
|
|
49
|
+
* @returns {NonNullable<TodoParams["contract"]>} Authored contract fields.
|
|
50
|
+
*/
|
|
51
|
+
contract = (): NonNullable<TodoParams["contract"]> => ({
|
|
52
|
+
acceptance: {
|
|
53
|
+
argv: ["moon", "run", "todo-core:test"],
|
|
54
|
+
cwd: ".",
|
|
55
|
+
expected: "passes",
|
|
56
|
+
kind: "command",
|
|
57
|
+
},
|
|
58
|
+
assignment: { kind: "self" },
|
|
59
|
+
deliverable: "Executable task contracts",
|
|
60
|
+
dependsOn: [],
|
|
61
|
+
scope: { generates: [], owns: ["src/"], reads: ["README.md"], repositoryId: "oisinpi" },
|
|
62
|
+
}),
|
|
63
|
+
/**
|
|
64
|
+
* Returns the runtime ID from the first root in a tool result.
|
|
65
|
+
* @param {TodoList} list Real tool result.
|
|
66
|
+
* @returns {string} Runtime ID.
|
|
67
|
+
*/
|
|
68
|
+
firstId = (list: TodoList): string => {
|
|
69
|
+
const id = list.tasks.at(first)?.unit?.reference.unitId;
|
|
70
|
+
if (id === undefined) {
|
|
71
|
+
throw new Error("Expected a runtime unit ID");
|
|
72
|
+
}
|
|
73
|
+
return id;
|
|
74
|
+
},
|
|
75
|
+
/**
|
|
76
|
+
* Requires a root identity at a known fixture position.
|
|
77
|
+
* @param {TodoList} list Tool result.
|
|
78
|
+
* @param {number} index Root position.
|
|
79
|
+
* @returns {string} Runtime ID.
|
|
80
|
+
*/
|
|
81
|
+
rootId = (list: TodoList, index: number): string => {
|
|
82
|
+
const id = list.tasks.at(index)?.unit?.reference.unitId;
|
|
83
|
+
if (id === undefined) {
|
|
84
|
+
throw new Error("Expected root identity");
|
|
85
|
+
}
|
|
86
|
+
return id;
|
|
87
|
+
},
|
|
88
|
+
/**
|
|
89
|
+
* Requires a child identity from the first outcome.
|
|
90
|
+
* @param {TodoList} list Tool result.
|
|
91
|
+
* @param {number} index Child position.
|
|
92
|
+
* @returns {string} Runtime ID.
|
|
93
|
+
*/
|
|
94
|
+
childId = (list: TodoList, index: number): string => {
|
|
95
|
+
const id = list.tasks.at(first)?.subtasks?.at(index)?.unit?.reference.unitId;
|
|
96
|
+
if (id === undefined) {
|
|
97
|
+
throw new Error("Expected child identity");
|
|
98
|
+
}
|
|
99
|
+
return id;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
export { childId, contract, first, firstId, fixture, last, rootId, second, third };
|
|
103
|
+
export type { Fixture };
|
package/src/display.ts
CHANGED
|
@@ -41,8 +41,14 @@ const emptyCount = 0,
|
|
|
41
41
|
active = list.tasks.flatMap((task) => [
|
|
42
42
|
...(task.status === "in_progress" ? [task.content] : []),
|
|
43
43
|
...(task.subtasks ?? [])
|
|
44
|
-
.filter(
|
|
45
|
-
|
|
44
|
+
.filter(
|
|
45
|
+
(child: Readonly<Pick<Subtask, "content" | "status">>) =>
|
|
46
|
+
child.status === "in_progress",
|
|
47
|
+
)
|
|
48
|
+
.map(
|
|
49
|
+
(child: Readonly<Pick<Subtask, "content" | "status">>) =>
|
|
50
|
+
`${task.content} → ${child.content}`,
|
|
51
|
+
),
|
|
46
52
|
]),
|
|
47
53
|
current =
|
|
48
54
|
active.length > emptyCount
|
package/src/gate.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { TaskProvider } from "./provider.ts";
|
|
3
|
+
import { ownsTodo } from "./lifecycle.ts";
|
|
4
|
+
|
|
5
|
+
/** Exact structured reads and workflow controls, never command-text inference. */
|
|
6
|
+
const controls = new Set([
|
|
7
|
+
"ask",
|
|
8
|
+
"codemode",
|
|
9
|
+
"interview",
|
|
10
|
+
"todo",
|
|
11
|
+
"tool_search",
|
|
12
|
+
"read",
|
|
13
|
+
"ls",
|
|
14
|
+
"find",
|
|
15
|
+
"grep",
|
|
16
|
+
"hypa_read",
|
|
17
|
+
"hypa_ls",
|
|
18
|
+
"hypa_find",
|
|
19
|
+
"hypa_grep",
|
|
20
|
+
"web_search",
|
|
21
|
+
"web_fetch",
|
|
22
|
+
"lsp_diagnostics",
|
|
23
|
+
"ctx_search",
|
|
24
|
+
"ctx_stats",
|
|
25
|
+
"mcp__codebase_memory__search_graph",
|
|
26
|
+
"mcp__codebase_memory__get_code_snippet",
|
|
27
|
+
"mcp__codebase_memory__trace_path",
|
|
28
|
+
"mcp__codebase_memory__detect_changes",
|
|
29
|
+
"hindsight_search_knowledge_pages",
|
|
30
|
+
"hindsight_list_knowledge_pages",
|
|
31
|
+
"hindsight_read_knowledge_page",
|
|
32
|
+
"hindsight_reflect",
|
|
33
|
+
"hindsight_sync_status",
|
|
34
|
+
"hindsight_diagnose",
|
|
35
|
+
"hindsight_capture_initiative",
|
|
36
|
+
"mcp__dogsled__spawn",
|
|
37
|
+
"mcp__dogsled__send",
|
|
38
|
+
"mcp__dogsled__cancel",
|
|
39
|
+
"mcp__dogsled__close",
|
|
40
|
+
"mcp__dogsled__stop",
|
|
41
|
+
"mcp__dogsled__read",
|
|
42
|
+
"mcp__dogsled__status",
|
|
43
|
+
"mcp__dogsled__inbox",
|
|
44
|
+
]),
|
|
45
|
+
/**
|
|
46
|
+
* Checks actual calls and leases execution-bearing calls.
|
|
47
|
+
* @param {Readonly<ExtensionAPI>} pi Runtime hooks and metadata.
|
|
48
|
+
* @param {Readonly<TaskProvider>} provider Task state and leases.
|
|
49
|
+
*/
|
|
50
|
+
registerGate = (
|
|
51
|
+
pi: Readonly<Pick<ExtensionAPI, "on" | "getAllTools">>,
|
|
52
|
+
provider: Readonly<TaskProvider>,
|
|
53
|
+
): void => {
|
|
54
|
+
pi.on("tool_call", (event: Readonly<{ toolName: string; toolCallId: string }>, ctx) => {
|
|
55
|
+
if (!ownsTodo(pi)) {
|
|
56
|
+
return { block: false };
|
|
57
|
+
}
|
|
58
|
+
provider.context(ctx);
|
|
59
|
+
if (controls.has(event.toolName)) {
|
|
60
|
+
return { block: false };
|
|
61
|
+
}
|
|
62
|
+
const active = provider.capability().active();
|
|
63
|
+
if (!active.ok || active.value === null) {
|
|
64
|
+
return {
|
|
65
|
+
block: true,
|
|
66
|
+
reason: active.ok
|
|
67
|
+
? "Start a complete self-assigned leaf with todo before shell, code, mutation, or unknown tools."
|
|
68
|
+
: active.error.message,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
provider.lease(event.toolCallId, active.value.ref);
|
|
72
|
+
return { block: false };
|
|
73
|
+
});
|
|
74
|
+
pi.on("tool_execution_end", (event: Readonly<{ toolCallId: string }>) => {
|
|
75
|
+
provider.release(event.toolCallId);
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export { registerGate };
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
/* tslint:disable */
|
|
2
2
|
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* A draft leaf; local keys are resolved only within its creation request.
|
|
5
|
+
*/
|
|
6
|
+
export interface DraftItem {
|
|
7
|
+
content: string;
|
|
8
|
+
key?: string | undefined;
|
|
9
|
+
contract?: ContractDraft;
|
|
10
|
+
}
|
|
11
|
+
|
|
3
12
|
/**
|
|
4
13
|
* A leaf work unit. Grandchildren are not accepted.
|
|
5
14
|
*/
|
|
6
15
|
export interface Subtask {
|
|
7
16
|
content: string;
|
|
8
17
|
status: Status;
|
|
18
|
+
unit?: Unit;
|
|
9
19
|
}
|
|
10
20
|
|
|
11
21
|
/**
|
|
@@ -23,6 +33,27 @@ export interface Task {
|
|
|
23
33
|
content: string;
|
|
24
34
|
status: Status;
|
|
25
35
|
subtasks?: Subtask[];
|
|
36
|
+
unit?: Unit;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Atomic claim snapshot and its exported result.
|
|
41
|
+
*/
|
|
42
|
+
export interface ClaimChange {
|
|
43
|
+
list: TodoList;
|
|
44
|
+
persist: boolean;
|
|
45
|
+
value: ClaimResult;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Author-editable fields. A draft can omit fields but cannot supply invalid values.
|
|
50
|
+
*/
|
|
51
|
+
export interface ContractDraft {
|
|
52
|
+
deliverable?: string;
|
|
53
|
+
scope?: Scope;
|
|
54
|
+
acceptance?: Acceptance;
|
|
55
|
+
dependsOn?: string[];
|
|
56
|
+
assignment?: Assignment;
|
|
26
57
|
}
|
|
27
58
|
|
|
28
59
|
/**
|
|
@@ -33,13 +64,149 @@ export interface ReminderHistory {
|
|
|
33
64
|
}
|
|
34
65
|
|
|
35
66
|
/**
|
|
36
|
-
*
|
|
67
|
+
* Branch provenance of one immutable contract revision.
|
|
68
|
+
*/
|
|
69
|
+
export interface UnitRef {
|
|
70
|
+
sessionId: string;
|
|
71
|
+
unitId: string;
|
|
72
|
+
revision: number;
|
|
73
|
+
/**
|
|
74
|
+
* Empty only until the containing Pi entry has been appended and read.
|
|
75
|
+
*/
|
|
76
|
+
contractEntryId: string;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Child creation never accepts another outcome.
|
|
81
|
+
*/
|
|
82
|
+
export type LeafItem = string | DraftItem;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Complete contract projection used at the component boundary.
|
|
86
|
+
*/
|
|
87
|
+
export interface UnitContract {
|
|
88
|
+
ref: UnitRef;
|
|
89
|
+
title: string;
|
|
90
|
+
deliverable: string;
|
|
91
|
+
scope: Scope;
|
|
92
|
+
acceptance: Acceptance;
|
|
93
|
+
dependsOn: string[];
|
|
94
|
+
assignment: Assignment;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Completed prerequisite revision frozen at claim time.
|
|
99
|
+
*/
|
|
100
|
+
export interface Prerequisite {
|
|
101
|
+
unitId: string;
|
|
102
|
+
completedRevision: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Concrete WASM settlement response.
|
|
107
|
+
*/
|
|
108
|
+
export interface SettlementChange {
|
|
109
|
+
list: TodoList;
|
|
110
|
+
persist: boolean;
|
|
111
|
+
value: SettlementResult;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Desired executor, not a process or a model override.
|
|
116
|
+
*/
|
|
117
|
+
export type Assignment = { kind: "self" } | { kind: "worker"; profile: string };
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Durable accepted event identity survives a new binding or revision.
|
|
121
|
+
*/
|
|
122
|
+
export interface AcceptedEvent {
|
|
123
|
+
origin: UnitRef;
|
|
124
|
+
execution: ExecutionRef;
|
|
125
|
+
eventId: string;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Evidence for an execution which obtained an export digest.
|
|
130
|
+
*/
|
|
131
|
+
export type BoundResult = { kind: "returned"; evidence: EvidenceRef } | { kind: "stopped"; evidence?: EvidenceRef; reason: string };
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Evidence requirement. Creating a command does not execute it.
|
|
135
|
+
*/
|
|
136
|
+
export type Acceptance = { kind: "command"; cwd: string; argv: string[]; expected: string } | { kind: "review"; artifact: string; criterion: string };
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Exact revision/execution correlation, not runtime worker state.
|
|
140
|
+
*/
|
|
141
|
+
export interface TaskBinding {
|
|
142
|
+
contract: UnitRef;
|
|
143
|
+
execution: ExecutionRef;
|
|
144
|
+
exportDigest: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Exactly the binding and export persisted in the claim snapshot.
|
|
149
|
+
*/
|
|
150
|
+
export interface ClaimResult {
|
|
151
|
+
binding: TaskBinding;
|
|
152
|
+
exported: TaskExport;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Executor-owned release facts; unknown outcomes never release a hold.
|
|
157
|
+
*/
|
|
158
|
+
export type Settlement = { version: number; eventId: string; binding: TaskBinding; result: BoundResult } | { version: number; eventId: string; origin: UnitRef; execution: ExecutionRef; result: UnstartedResult };
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Executor-owned transport; task semantics are validated here.
|
|
162
|
+
*/
|
|
163
|
+
export interface Seed {
|
|
164
|
+
version: number;
|
|
165
|
+
execution: ExecutionRef;
|
|
166
|
+
binding: TaskBinding;
|
|
167
|
+
exported: TaskExport;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Export envelope; the digest excludes only its own field.
|
|
172
|
+
*/
|
|
173
|
+
export interface TaskExport {
|
|
174
|
+
version: number;
|
|
175
|
+
provider: string;
|
|
176
|
+
contract: UnitContract;
|
|
177
|
+
prerequisites: Prerequisite[];
|
|
178
|
+
brief: string;
|
|
179
|
+
digest: string;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Frozen import and its local session, not an executor lifecycle record.
|
|
184
|
+
*/
|
|
185
|
+
export interface ImportedUnit {
|
|
186
|
+
seed: Seed;
|
|
187
|
+
localSessionId: string;
|
|
188
|
+
seal: Seal | undefined;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* IDs address migrated tasks; exact labels address only legacy records.
|
|
37
193
|
*/
|
|
38
194
|
export interface Request {
|
|
39
195
|
op: Operation;
|
|
40
196
|
items?: readonly Item[] | undefined;
|
|
41
197
|
task?: string | undefined;
|
|
42
198
|
parent?: string | undefined;
|
|
199
|
+
contract?: ContractDraft | undefined;
|
|
200
|
+
start?: string | undefined;
|
|
201
|
+
evidence?: string | undefined;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Immutable local completion evidence. Pi derives the containing entry ID on replay.
|
|
206
|
+
*/
|
|
207
|
+
export interface Seal {
|
|
208
|
+
entryId: string;
|
|
209
|
+
disposition: Status;
|
|
43
210
|
}
|
|
44
211
|
|
|
45
212
|
/**
|
|
@@ -50,25 +217,99 @@ export interface WidgetRow {
|
|
|
50
217
|
text: string;
|
|
51
218
|
}
|
|
52
219
|
|
|
220
|
+
/**
|
|
221
|
+
* Opaque executor identity; no process interpretation belongs here.
|
|
222
|
+
*/
|
|
223
|
+
export interface ExecutionRef {
|
|
224
|
+
executor: string;
|
|
225
|
+
ownerId: string;
|
|
226
|
+
requestId: string;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Optimistic claim identity, supplied by a cooperating extension.
|
|
231
|
+
*/
|
|
232
|
+
export interface ClaimInput {
|
|
233
|
+
expected: UnitRef;
|
|
234
|
+
execution: ExecutionRef;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Ordered digest projection. Struct declaration order is the wire order.
|
|
239
|
+
*/
|
|
240
|
+
export interface ExportData {
|
|
241
|
+
version: number;
|
|
242
|
+
provider: string;
|
|
243
|
+
contract: UnitContract;
|
|
244
|
+
prerequisites: Prerequisite[];
|
|
245
|
+
brief: string;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Precommit abandonment has no export digest.
|
|
250
|
+
*/
|
|
251
|
+
export type UnstartedResult = { kind: "not_started"; reason: string };
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Provider acknowledgement, including closure after activation ends.
|
|
255
|
+
*/
|
|
256
|
+
export interface ImportReceipt {
|
|
257
|
+
version: number;
|
|
258
|
+
execution: ExecutionRef;
|
|
259
|
+
unitRef: UnitRef;
|
|
260
|
+
digest: string;
|
|
261
|
+
localSessionId: string;
|
|
262
|
+
seal: Seal | undefined;
|
|
263
|
+
}
|
|
264
|
+
|
|
53
265
|
/**
|
|
54
266
|
* Relevant facts in branch order, including proposed boundary entries.
|
|
55
267
|
*/
|
|
56
268
|
export type ReminderFact = { kind: "user" } | { kind: "snapshot"; list: TodoList } | { kind: "reminder" };
|
|
57
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Repository-relative declared scope, not a filesystem permission grant.
|
|
272
|
+
*/
|
|
273
|
+
export interface Scope {
|
|
274
|
+
repositoryId: string;
|
|
275
|
+
owns: string[];
|
|
276
|
+
reads: string[];
|
|
277
|
+
generates: string[];
|
|
278
|
+
}
|
|
279
|
+
|
|
58
280
|
/**
|
|
59
281
|
* Root creation accepts standalone outcomes or outcomes with leaf work units.
|
|
60
282
|
*/
|
|
61
|
-
export type Item = string | { content: string; subtasks:
|
|
283
|
+
export type Item = string | { content: string; subtasks: LeafItem[] } | DraftItem;
|
|
62
284
|
|
|
63
285
|
/**
|
|
64
286
|
* Semantic styling for a terminal row.
|
|
65
287
|
*/
|
|
66
288
|
export type WidgetKind = "heading" | "active" | "upcoming" | "done" | "dropped" | "summary";
|
|
67
289
|
|
|
290
|
+
/**
|
|
291
|
+
* Stored task metadata, independent of process execution state.
|
|
292
|
+
*/
|
|
293
|
+
export interface Unit {
|
|
294
|
+
reference: UnitRef;
|
|
295
|
+
draft: ContractDraft;
|
|
296
|
+
localSessionId?: string;
|
|
297
|
+
acceptanceEvidence?: string;
|
|
298
|
+
binding?: TaskBinding;
|
|
299
|
+
frozenExportJson?: string;
|
|
300
|
+
evidence?: EvidenceRef[];
|
|
301
|
+
acceptedEvents?: AcceptedEvent[];
|
|
302
|
+
/**
|
|
303
|
+
* The last claimed revision cannot launch again after settlement.
|
|
304
|
+
*/
|
|
305
|
+
attemptedRevision?: number;
|
|
306
|
+
imported?: ImportedUnit;
|
|
307
|
+
}
|
|
308
|
+
|
|
68
309
|
/**
|
|
69
310
|
* Supported model-facing operations.
|
|
70
311
|
*/
|
|
71
|
-
export type Operation = "init" | "start" | "done" | "drop" | "append" | "view";
|
|
312
|
+
export type Operation = "init" | "start" | "done" | "drop" | "append" | "view" | "update";
|
|
72
313
|
|
|
73
314
|
/**
|
|
74
315
|
* The state of one outcome or work unit.
|
|
@@ -82,6 +323,47 @@ export interface TodoList {
|
|
|
82
323
|
tasks: Task[];
|
|
83
324
|
}
|
|
84
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Trusted runtime identity, separate from agent-authored tool parameters.
|
|
328
|
+
*/
|
|
329
|
+
export interface MutationContext {
|
|
330
|
+
sessionId: string;
|
|
331
|
+
mutationId: string;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Untrusted worker result reference, never acceptance.
|
|
336
|
+
*/
|
|
337
|
+
export interface EvidenceRef {
|
|
338
|
+
execution: ExecutionRef;
|
|
339
|
+
resultId: string;
|
|
340
|
+
summary: string;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* Validated local activation, not a worker-state projection.
|
|
345
|
+
*/
|
|
346
|
+
export interface ActiveUnit {
|
|
347
|
+
ref: UnitRef;
|
|
348
|
+
localSessionId: string;
|
|
349
|
+
seeded: boolean;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Whether settlement changed this branch.
|
|
354
|
+
*/
|
|
355
|
+
export interface SettlementResult {
|
|
356
|
+
applied: boolean;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Reads validated current-session activation.
|
|
362
|
+
*
|
|
363
|
+
* # Errors
|
|
364
|
+
* Rejects invalid persisted state.
|
|
365
|
+
*/
|
|
366
|
+
export function active(list: TodoList, session_id: string): ActiveUnit | undefined;
|
|
85
367
|
|
|
86
368
|
/**
|
|
87
369
|
* Applies one validated operation.
|
|
@@ -90,7 +372,15 @@ export interface TodoList {
|
|
|
90
372
|
*
|
|
91
373
|
* Throws for malformed input or a rejected operation.
|
|
92
374
|
*/
|
|
93
|
-
export function apply(list: TodoList, request:
|
|
375
|
+
export function apply(list: TodoList, request: unknown, context: MutationContext): Change;
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Validates and atomically freezes a worker contract.
|
|
379
|
+
*
|
|
380
|
+
* # Errors
|
|
381
|
+
* Rejects malformed requests, stale origins and competing claims.
|
|
382
|
+
*/
|
|
383
|
+
export function claim(list: TodoList, input: string, session_id: string): ClaimChange;
|
|
94
384
|
|
|
95
385
|
/**
|
|
96
386
|
* Computes completion policy from branch facts.
|
|
@@ -101,6 +391,22 @@ export function apply(list: TodoList, request: Request): Change;
|
|
|
101
391
|
*/
|
|
102
392
|
export function completion_reminder(facts: ReminderHistory): string | undefined;
|
|
103
393
|
|
|
394
|
+
/**
|
|
395
|
+
* Imports one validated seed into a fresh worker session.
|
|
396
|
+
*
|
|
397
|
+
* # Errors
|
|
398
|
+
* Rejects invalid seed, repository identity or existing work.
|
|
399
|
+
*/
|
|
400
|
+
export function import_unit(list: TodoList, input: string, session_id: string, repository_id: string): Change;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Reads immutable import acknowledgement and closure evidence.
|
|
404
|
+
*
|
|
405
|
+
* # Errors
|
|
406
|
+
* Rejects invalid persisted state.
|
|
407
|
+
*/
|
|
408
|
+
export function imported(list: TodoList, session_id: string): ImportReceipt | undefined;
|
|
409
|
+
|
|
104
410
|
/**
|
|
105
411
|
* Replaces the whole list with `items`.
|
|
106
412
|
*
|
|
@@ -110,6 +416,14 @@ export function completion_reminder(facts: ReminderHistory): string | undefined;
|
|
|
110
416
|
*/
|
|
111
417
|
export function init(items: string[]): TodoList;
|
|
112
418
|
|
|
419
|
+
/**
|
|
420
|
+
* Reads a complete task contract.
|
|
421
|
+
*
|
|
422
|
+
* # Errors
|
|
423
|
+
* Rejects unknown IDs or incomplete contracts.
|
|
424
|
+
*/
|
|
425
|
+
export function inspect(list: TodoList, id: string): UnitContract;
|
|
426
|
+
|
|
113
427
|
/**
|
|
114
428
|
* Validates a stored snapshot. It comes from the session file, so it is typed
|
|
115
429
|
* `unknown` and checked here, by the type that owns its shape.
|
|
@@ -120,6 +434,22 @@ export function init(items: string[]): TodoList;
|
|
|
120
434
|
*/
|
|
121
435
|
export function parse(snapshot: unknown): TodoList;
|
|
122
436
|
|
|
437
|
+
/**
|
|
438
|
+
* Prevents mutations of revisions with an in-flight tool call.
|
|
439
|
+
*
|
|
440
|
+
* # Errors
|
|
441
|
+
* Rejects closure, replacement or alteration of any leased revision.
|
|
442
|
+
*/
|
|
443
|
+
export function protect(before: TodoList, after: TodoList, leases: UnitRef[]): void;
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Records an executor's exact release evidence, never acceptance.
|
|
447
|
+
*
|
|
448
|
+
* # Errors
|
|
449
|
+
* Rejects malformed or mismatched settlements.
|
|
450
|
+
*/
|
|
451
|
+
export function settle(list: TodoList, input: string, session_id: string): SettlementChange;
|
|
452
|
+
|
|
123
453
|
/**
|
|
124
454
|
* The model-facing summary of `list`.
|
|
125
455
|
*
|
|
@@ -142,10 +472,17 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
|
|
142
472
|
|
|
143
473
|
export interface InitOutput {
|
|
144
474
|
readonly memory: WebAssembly.Memory;
|
|
145
|
-
readonly
|
|
475
|
+
readonly active: (a: number, b: number, c: number, d: number) => void;
|
|
476
|
+
readonly apply: (a: number, b: number, c: number, d: number) => void;
|
|
477
|
+
readonly claim: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
|
146
478
|
readonly completion_reminder: (a: number, b: number) => void;
|
|
479
|
+
readonly import_unit: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
|
|
480
|
+
readonly imported: (a: number, b: number, c: number, d: number) => void;
|
|
147
481
|
readonly init: (a: number, b: number, c: number) => void;
|
|
482
|
+
readonly inspect: (a: number, b: number, c: number, d: number) => void;
|
|
148
483
|
readonly parse: (a: number, b: number) => void;
|
|
484
|
+
readonly protect: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
485
|
+
readonly settle: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
|
|
149
486
|
readonly view: (a: number, b: number) => void;
|
|
150
487
|
readonly widget: (a: number, b: number, c: number) => void;
|
|
151
488
|
readonly __wbindgen_export: (a: number, b: number) => number;
|