opencode-courier 0.7.2 → 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 +122 -135
- package/dist/index.js +24 -4
- package/dist/memory/domain.d.ts +119 -0
- package/dist/memory/domain.js +84 -0
- package/dist/memory/events.d.ts +26 -0
- package/dist/memory/events.js +46 -0
- package/dist/memory/forget.d.ts +10 -0
- package/dist/memory/forget.js +20 -0
- package/dist/memory/index.d.ts +10 -0
- package/dist/memory/index.js +11 -0
- package/dist/memory/note.d.ts +37 -0
- package/dist/memory/note.js +29 -0
- package/dist/memory/ports.d.ts +44 -0
- package/dist/memory/ports.js +1 -0
- package/dist/memory/recall.d.ts +27 -0
- package/dist/memory/recall.js +48 -0
- package/dist/memory/record.d.ts +7 -0
- package/dist/memory/record.js +92 -0
- package/dist/memory/rpc-handlers.d.ts +134 -0
- package/dist/memory/rpc-handlers.js +23 -0
- package/dist/memory/rpc.d.ts +227 -0
- package/dist/memory/rpc.js +60 -0
- package/dist/memory/store.d.ts +10 -0
- package/dist/memory/store.js +90 -0
- package/dist/memory/sweep.d.ts +4 -0
- package/dist/memory/sweep.js +12 -0
- package/dist/memory/text.d.ts +27 -0
- package/dist/memory/text.js +95 -0
- package/dist/memory/tools.d.ts +16 -0
- package/dist/memory/tools.js +78 -0
- package/dist/memory/tui.d.ts +73 -0
- package/dist/person/rpc.d.ts +4 -4
- package/dist/platform/json.d.ts +1 -0
- package/dist/platform/json.js +1 -0
- package/dist/platform/version.js +2 -2
- package/dist/rpc.d.ts +1 -0
- package/dist/rpc.js +1 -0
- package/dist/skill.js +10 -3
- package/dist/tree/context.d.ts +2 -2
- package/dist/tree/context.js +4 -3
- package/dist/tree/index.d.ts +6 -5
- package/dist/tree/index.js +5 -4
- package/dist/tree/mascot.d.ts +50 -0
- package/dist/tree/mascot.js +171 -0
- package/dist/tree/panel.d.ts +3 -1
- package/dist/tree/panel.js +17 -3
- package/dist/tree/ports.d.ts +12 -2
- package/dist/tree/roster.d.ts +17 -0
- package/dist/tree/roster.js +24 -0
- package/dist/tree/rpc-handlers.d.ts +21 -18
- package/dist/tree/rpc.d.ts +26 -18
- package/dist/tree/rpc.js +2 -0
- package/dist/tree/status.d.ts +5 -5
- package/dist/tree/subtree.d.ts +2 -2
- package/dist/tree/text.js +2 -1
- package/dist/tree/tui.d.ts +115 -8
- package/dist/tui.js +1269 -222
- package/package.json +4 -4
package/dist/tree/ports.d.ts
CHANGED
|
@@ -164,6 +164,8 @@ export interface CourierPorts {
|
|
|
164
164
|
readonly pending: (sessionID: string) => Promise<ReadonlyArray<Pending>>;
|
|
165
165
|
/** The forms a session shows, which only the person can answer: web search's, a plugin's; not the question tool's. */
|
|
166
166
|
readonly forms: (sessionID: string) => Promise<ReadonlyArray<ShownForm>>;
|
|
167
|
+
/** The context windows of the models available, by provider and model id, as the panel reads a session's context use. */
|
|
168
|
+
readonly windows: () => Promise<ReadonlyArray<ModelWindow>>;
|
|
167
169
|
readonly limits: Limits;
|
|
168
170
|
/** The `nativeChildren` option: a child started without isolate is created with OpenCode's own `parentID`. */
|
|
169
171
|
readonly nativeChildren?: boolean;
|
|
@@ -174,6 +176,12 @@ export interface CourierPorts {
|
|
|
174
176
|
readonly nudge: () => void;
|
|
175
177
|
readonly log: (message: string) => void;
|
|
176
178
|
}
|
|
179
|
+
/** A model's context window in tokens, as `CourierPorts.windows` lists it. */
|
|
180
|
+
export interface ModelWindow {
|
|
181
|
+
readonly providerID: string;
|
|
182
|
+
readonly id: string;
|
|
183
|
+
readonly context: number;
|
|
184
|
+
}
|
|
177
185
|
/** A form a session shows, as `CourierPorts.forms` lists it; `person/` keeps them. */
|
|
178
186
|
export interface ShownForm {
|
|
179
187
|
readonly id: string;
|
|
@@ -278,8 +286,8 @@ export interface ExecutionError {
|
|
|
278
286
|
}
|
|
279
287
|
export interface WatchPorts {
|
|
280
288
|
readonly storage: RosterStorage;
|
|
281
|
-
/** `context` reads the last reply of a session that ended its turn without reporting. */
|
|
282
|
-
readonly session: Pick<Context["session"], "synthetic" | "context">;
|
|
289
|
+
/** `context` reads the last reply of a session that ended its turn without reporting; `get` is what every member joins with too. */
|
|
290
|
+
readonly session: Pick<Context["session"], "synthetic" | "context" | "get">;
|
|
283
291
|
readonly event: Pick<Context["event"], "subscribe">;
|
|
284
292
|
/** The permission domains of every loaded location, which the `Waits` suppliers ask; an isolated child's are in its worktree's. */
|
|
285
293
|
readonly permissions: () => Iterable<Pick<Context["permission"], "list">>;
|
|
@@ -308,5 +316,7 @@ export interface ContextPorts {
|
|
|
308
316
|
readonly limits: Limits;
|
|
309
317
|
/** Each session's depth once looked up: null for one nobody spawned that has started none, until it starts one. */
|
|
310
318
|
readonly roles: Map<string, number | null>;
|
|
319
|
+
/** Tools of other modules hidden from a leaf alongside courier_spawn; `src/index.ts` names courier_recall and courier_note. */
|
|
320
|
+
readonly hiddenFromLeaf?: ReadonlyArray<string>;
|
|
311
321
|
readonly log: (message: string) => void;
|
|
312
322
|
}
|
package/dist/tree/roster.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Status } from "../kernel/protocol.js";
|
|
1
2
|
import type { RosterEntry, RosterStorage } from "./ports.js";
|
|
2
3
|
/**
|
|
3
4
|
* Entries older than this are dropped when their parent's roster is read, and on plugin setup,
|
|
@@ -11,6 +12,22 @@ export declare function allEntries(storage: RosterStorage): Promise<RosterEntry[
|
|
|
11
12
|
* courier_spawn did not start; empty when courier_spawn did not start the session.
|
|
12
13
|
*/
|
|
13
14
|
export declare function lineage(storage: RosterStorage, sessionID: string): Promise<RosterEntry[]>;
|
|
15
|
+
/** `lineage` by the reverse index alone: empty, without scanning the roster, when it does not name the session. */
|
|
16
|
+
export declare function indexedLineage(storage: RosterStorage, sessionID: string): Promise<RosterEntry[]>;
|
|
17
|
+
/** The sessions a session started, oldest first, expired entries included. */
|
|
18
|
+
export declare function childrenOf(storage: RosterStorage, parentID: string): Promise<RosterEntry[]>;
|
|
19
|
+
/**
|
|
20
|
+
* What another module reads of a spawned session's report: `known` once a prompt was noted, whether it `owes` one, how
|
|
21
|
+
* its wait `ended` when not by a report, the `status` of its last report, and whether courier_stop `stopped` it since its last prompt.
|
|
22
|
+
*/
|
|
23
|
+
export interface ReportState {
|
|
24
|
+
readonly known: boolean;
|
|
25
|
+
readonly owes: boolean;
|
|
26
|
+
readonly ended?: "failed" | "interrupted";
|
|
27
|
+
readonly status?: Status;
|
|
28
|
+
readonly stopped: boolean;
|
|
29
|
+
}
|
|
30
|
+
export declare function reportState(storage: RosterStorage, sessionID: string): Promise<ReportState>;
|
|
14
31
|
/**
|
|
15
32
|
* The top of a spawned session's lineage, where its permission requests and questions go, since the
|
|
16
33
|
* person is there. Throws unless the session was spawned and `callerID` is that top; `what` names it.
|
package/dist/tree/roster.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
|
+
import { isStatus } from "../kernel/protocol.js";
|
|
2
3
|
import { forgetChild, forgetReports } from "./forget.js";
|
|
4
|
+
import { stoppedSincePrompt } from "./report.js";
|
|
3
5
|
import { childStore } from "./store.js";
|
|
4
6
|
/**
|
|
5
7
|
* Entries older than this are dropped when their parent's roster is read, and on plugin setup,
|
|
@@ -17,6 +19,28 @@ export async function allEntries(storage) {
|
|
|
17
19
|
export async function lineage(storage, sessionID) {
|
|
18
20
|
return childStore(storage).lineage(sessionID);
|
|
19
21
|
}
|
|
22
|
+
/** `lineage` by the reverse index alone: empty, without scanning the roster, when it does not name the session. */
|
|
23
|
+
export async function indexedLineage(storage, sessionID) {
|
|
24
|
+
return childStore(storage).indexedLineage(sessionID);
|
|
25
|
+
}
|
|
26
|
+
/** The sessions a session started, oldest first, expired entries included. */
|
|
27
|
+
export async function childrenOf(storage, parentID) {
|
|
28
|
+
return childStore(storage).children(parentID);
|
|
29
|
+
}
|
|
30
|
+
export async function reportState(storage, sessionID) {
|
|
31
|
+
const children = childStore(storage);
|
|
32
|
+
const [{ prompt, settled }, stopped] = await Promise.all([children.notes(sessionID, ["prompt", "settled"]), stoppedSincePrompt(children, sessionID)]);
|
|
33
|
+
const known = prompt.at !== undefined;
|
|
34
|
+
const done = known && settled.at !== undefined && settled.at >= prompt.at;
|
|
35
|
+
const by = settled.by;
|
|
36
|
+
return {
|
|
37
|
+
known,
|
|
38
|
+
owes: known && !done,
|
|
39
|
+
...(done && (by === "failed" || by === "interrupted") ? { ended: by } : {}),
|
|
40
|
+
...(isStatus(settled.status) ? { status: settled.status } : {}),
|
|
41
|
+
stopped,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
20
44
|
/**
|
|
21
45
|
* The top of a spawned session's lineage, where its permission requests and questions go, since the
|
|
22
46
|
* person is there. Throws unless the session was spawned and `callerID` is that top; `what` names it.
|
|
@@ -56,11 +56,11 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
56
56
|
readonly rows: readonly {
|
|
57
57
|
readonly sessionID: string;
|
|
58
58
|
readonly title: string;
|
|
59
|
-
readonly parentID: string;
|
|
60
59
|
readonly depth: number;
|
|
61
|
-
readonly created: number;
|
|
62
60
|
readonly isolated: boolean;
|
|
63
|
-
readonly
|
|
61
|
+
readonly parentID: string;
|
|
62
|
+
readonly created: number;
|
|
63
|
+
readonly state: "stalled" | "running" | "idle" | "gone" | "waiting";
|
|
64
64
|
readonly waits: readonly ({
|
|
65
65
|
readonly type: "permission";
|
|
66
66
|
readonly action: string;
|
|
@@ -72,24 +72,25 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
72
72
|
readonly type: "form";
|
|
73
73
|
readonly title: string;
|
|
74
74
|
})[];
|
|
75
|
+
readonly stopped?: boolean | undefined;
|
|
76
|
+
readonly stalled?: number | undefined;
|
|
75
77
|
readonly group?: {
|
|
76
78
|
readonly name: string;
|
|
77
79
|
readonly standing: string;
|
|
78
80
|
} | undefined;
|
|
79
|
-
readonly
|
|
80
|
-
readonly
|
|
81
|
+
readonly cost?: number | undefined;
|
|
82
|
+
readonly context?: number | undefined;
|
|
83
|
+
readonly outcome?: "failed" | "interrupted" | "succeeded" | undefined;
|
|
81
84
|
readonly report?: {
|
|
82
85
|
readonly progressed: boolean;
|
|
83
|
-
readonly state: "
|
|
86
|
+
readonly state: "ended" | "reported" | "owed";
|
|
84
87
|
readonly status?: string | undefined;
|
|
85
88
|
} | undefined;
|
|
86
|
-
readonly
|
|
87
|
-
readonly outcome?: "failed" | "interrupted" | "succeeded" | undefined;
|
|
89
|
+
readonly idle?: number | undefined;
|
|
88
90
|
readonly tool?: {
|
|
89
91
|
readonly name: string;
|
|
90
92
|
readonly at: number;
|
|
91
93
|
} | undefined;
|
|
92
|
-
readonly cost?: number | undefined;
|
|
93
94
|
}[];
|
|
94
95
|
readonly stalled?: number | undefined;
|
|
95
96
|
readonly truncated?: number | undefined;
|
|
@@ -97,11 +98,11 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
97
98
|
readonly rows: readonly {
|
|
98
99
|
readonly sessionID: string;
|
|
99
100
|
readonly title: string;
|
|
100
|
-
readonly parentID: string;
|
|
101
101
|
readonly depth: number;
|
|
102
|
-
readonly created: number;
|
|
103
102
|
readonly isolated: boolean;
|
|
104
|
-
readonly
|
|
103
|
+
readonly parentID: string;
|
|
104
|
+
readonly created: number;
|
|
105
|
+
readonly state: "stalled" | "running" | "idle" | "gone" | "waiting";
|
|
105
106
|
readonly waits: readonly ({
|
|
106
107
|
readonly type: "permission";
|
|
107
108
|
readonly action: string;
|
|
@@ -113,24 +114,25 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
113
114
|
readonly type: "form";
|
|
114
115
|
readonly title: string;
|
|
115
116
|
})[];
|
|
117
|
+
readonly stopped?: boolean | undefined;
|
|
118
|
+
readonly stalled?: number | undefined;
|
|
116
119
|
readonly group?: {
|
|
117
120
|
readonly name: string;
|
|
118
121
|
readonly standing: string;
|
|
119
122
|
} | undefined;
|
|
120
|
-
readonly
|
|
121
|
-
readonly
|
|
123
|
+
readonly cost?: number | undefined;
|
|
124
|
+
readonly context?: number | undefined;
|
|
125
|
+
readonly outcome?: "failed" | "interrupted" | "succeeded" | undefined;
|
|
122
126
|
readonly report?: {
|
|
123
127
|
readonly progressed: boolean;
|
|
124
|
-
readonly state: "
|
|
128
|
+
readonly state: "ended" | "reported" | "owed";
|
|
125
129
|
readonly status?: string | undefined;
|
|
126
130
|
} | undefined;
|
|
127
|
-
readonly
|
|
128
|
-
readonly outcome?: "failed" | "interrupted" | "succeeded" | undefined;
|
|
131
|
+
readonly idle?: number | undefined;
|
|
129
132
|
readonly tool?: {
|
|
130
133
|
readonly name: string;
|
|
131
134
|
readonly at: number;
|
|
132
135
|
} | undefined;
|
|
133
|
-
readonly cost?: number | undefined;
|
|
134
136
|
}[];
|
|
135
137
|
readonly stalled?: number | undefined;
|
|
136
138
|
readonly truncated?: number | undefined;
|
|
@@ -157,6 +159,7 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
157
159
|
readonly created: import("effect/Schema").Number;
|
|
158
160
|
readonly idle: import("effect/Schema").optionalKey<import("effect/Schema").Number>;
|
|
159
161
|
readonly cost: import("effect/Schema").optionalKey<import("effect/Schema").Number>;
|
|
162
|
+
readonly context: import("effect/Schema").optionalKey<import("effect/Schema").Number>;
|
|
160
163
|
readonly tool: import("effect/Schema").optionalKey<import("effect/Schema").Struct<{
|
|
161
164
|
readonly name: import("effect/Schema").String;
|
|
162
165
|
readonly at: import("effect/Schema").Number;
|
package/dist/tree/rpc.d.ts
CHANGED
|
@@ -63,6 +63,8 @@ declare const Row: Schema.Struct<{
|
|
|
63
63
|
readonly idle: Schema.optionalKey<Schema.Number>;
|
|
64
64
|
/** What it has cost so far, in US dollars. */
|
|
65
65
|
readonly cost: Schema.optionalKey<Schema.Number>;
|
|
66
|
+
/** How full its context is, as a fraction of the model's window; left out when the model or its limit cannot be read. */
|
|
67
|
+
readonly context: Schema.optionalKey<Schema.Number>;
|
|
66
68
|
/** Its last tool call, and when it was made. */
|
|
67
69
|
readonly tool: Schema.optionalKey<Schema.Struct<{
|
|
68
70
|
readonly name: Schema.String;
|
|
@@ -116,6 +118,8 @@ declare const Tree: Schema.Struct<{
|
|
|
116
118
|
readonly idle: Schema.optionalKey<Schema.Number>;
|
|
117
119
|
/** What it has cost so far, in US dollars. */
|
|
118
120
|
readonly cost: Schema.optionalKey<Schema.Number>;
|
|
121
|
+
/** How full its context is, as a fraction of the model's window; left out when the model or its limit cannot be read. */
|
|
122
|
+
readonly context: Schema.optionalKey<Schema.Number>;
|
|
119
123
|
/** Its last tool call, and when it was made. */
|
|
120
124
|
readonly tool: Schema.optionalKey<Schema.Struct<{
|
|
121
125
|
readonly name: Schema.String;
|
|
@@ -219,11 +223,11 @@ export declare const treeRpc: {
|
|
|
219
223
|
readonly rows: readonly {
|
|
220
224
|
readonly sessionID: string;
|
|
221
225
|
readonly title: string;
|
|
222
|
-
readonly parentID: string;
|
|
223
226
|
readonly depth: number;
|
|
224
|
-
readonly created: number;
|
|
225
227
|
readonly isolated: boolean;
|
|
226
|
-
readonly
|
|
228
|
+
readonly parentID: string;
|
|
229
|
+
readonly created: number;
|
|
230
|
+
readonly state: "stalled" | "running" | "idle" | "gone" | "waiting";
|
|
227
231
|
readonly waits: readonly ({
|
|
228
232
|
readonly type: "permission";
|
|
229
233
|
readonly action: string;
|
|
@@ -235,24 +239,25 @@ export declare const treeRpc: {
|
|
|
235
239
|
readonly type: "form";
|
|
236
240
|
readonly title: string;
|
|
237
241
|
})[];
|
|
242
|
+
readonly stopped?: boolean | undefined;
|
|
243
|
+
readonly stalled?: number | undefined;
|
|
238
244
|
readonly group?: {
|
|
239
245
|
readonly name: string;
|
|
240
246
|
readonly standing: string;
|
|
241
247
|
} | undefined;
|
|
242
|
-
readonly
|
|
243
|
-
readonly
|
|
248
|
+
readonly cost?: number | undefined;
|
|
249
|
+
readonly context?: number | undefined;
|
|
250
|
+
readonly outcome?: "failed" | "interrupted" | "succeeded" | undefined;
|
|
244
251
|
readonly report?: {
|
|
245
252
|
readonly progressed: boolean;
|
|
246
|
-
readonly state: "
|
|
253
|
+
readonly state: "ended" | "reported" | "owed";
|
|
247
254
|
readonly status?: string | undefined;
|
|
248
255
|
} | undefined;
|
|
249
|
-
readonly
|
|
250
|
-
readonly outcome?: "failed" | "interrupted" | "succeeded" | undefined;
|
|
256
|
+
readonly idle?: number | undefined;
|
|
251
257
|
readonly tool?: {
|
|
252
258
|
readonly name: string;
|
|
253
259
|
readonly at: number;
|
|
254
260
|
} | undefined;
|
|
255
|
-
readonly cost?: number | undefined;
|
|
256
261
|
}[];
|
|
257
262
|
readonly stalled?: number | undefined;
|
|
258
263
|
readonly truncated?: number | undefined;
|
|
@@ -260,11 +265,11 @@ export declare const treeRpc: {
|
|
|
260
265
|
readonly rows: readonly {
|
|
261
266
|
readonly sessionID: string;
|
|
262
267
|
readonly title: string;
|
|
263
|
-
readonly parentID: string;
|
|
264
268
|
readonly depth: number;
|
|
265
|
-
readonly created: number;
|
|
266
269
|
readonly isolated: boolean;
|
|
267
|
-
readonly
|
|
270
|
+
readonly parentID: string;
|
|
271
|
+
readonly created: number;
|
|
272
|
+
readonly state: "stalled" | "running" | "idle" | "gone" | "waiting";
|
|
268
273
|
readonly waits: readonly ({
|
|
269
274
|
readonly type: "permission";
|
|
270
275
|
readonly action: string;
|
|
@@ -276,24 +281,25 @@ export declare const treeRpc: {
|
|
|
276
281
|
readonly type: "form";
|
|
277
282
|
readonly title: string;
|
|
278
283
|
})[];
|
|
284
|
+
readonly stopped?: boolean | undefined;
|
|
285
|
+
readonly stalled?: number | undefined;
|
|
279
286
|
readonly group?: {
|
|
280
287
|
readonly name: string;
|
|
281
288
|
readonly standing: string;
|
|
282
289
|
} | undefined;
|
|
283
|
-
readonly
|
|
284
|
-
readonly
|
|
290
|
+
readonly cost?: number | undefined;
|
|
291
|
+
readonly context?: number | undefined;
|
|
292
|
+
readonly outcome?: "failed" | "interrupted" | "succeeded" | undefined;
|
|
285
293
|
readonly report?: {
|
|
286
294
|
readonly progressed: boolean;
|
|
287
|
-
readonly state: "
|
|
295
|
+
readonly state: "ended" | "reported" | "owed";
|
|
288
296
|
readonly status?: string | undefined;
|
|
289
297
|
} | undefined;
|
|
290
|
-
readonly
|
|
291
|
-
readonly outcome?: "failed" | "interrupted" | "succeeded" | undefined;
|
|
298
|
+
readonly idle?: number | undefined;
|
|
292
299
|
readonly tool?: {
|
|
293
300
|
readonly name: string;
|
|
294
301
|
readonly at: number;
|
|
295
302
|
} | undefined;
|
|
296
|
-
readonly cost?: number | undefined;
|
|
297
303
|
}[];
|
|
298
304
|
readonly stalled?: number | undefined;
|
|
299
305
|
readonly truncated?: number | undefined;
|
|
@@ -332,6 +338,8 @@ export declare const treeRpc: {
|
|
|
332
338
|
readonly idle: Schema.optionalKey<Schema.Number>;
|
|
333
339
|
/** What it has cost so far, in US dollars. */
|
|
334
340
|
readonly cost: Schema.optionalKey<Schema.Number>;
|
|
341
|
+
/** How full its context is, as a fraction of the model's window; left out when the model or its limit cannot be read. */
|
|
342
|
+
readonly context: Schema.optionalKey<Schema.Number>;
|
|
335
343
|
/** Its last tool call, and when it was made. */
|
|
336
344
|
readonly tool: Schema.optionalKey<Schema.Struct<{
|
|
337
345
|
readonly name: Schema.String;
|
package/dist/tree/rpc.js
CHANGED
|
@@ -53,6 +53,8 @@ const Row = Schema.Struct({
|
|
|
53
53
|
idle: Schema.optionalKey(Schema.Number),
|
|
54
54
|
/** What it has cost so far, in US dollars. */
|
|
55
55
|
cost: Schema.optionalKey(Schema.Number),
|
|
56
|
+
/** How full its context is, as a fraction of the model's window; left out when the model or its limit cannot be read. */
|
|
57
|
+
context: Schema.optionalKey(Schema.Number),
|
|
56
58
|
/** Its last tool call, and when it was made. */
|
|
57
59
|
tool: Schema.optionalKey(Schema.Struct({ name: Schema.String, at: Schema.Number })),
|
|
58
60
|
waits: Schema.Array(Wait),
|
package/dist/tree/status.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export declare function lastReply(messages: Awaited<ReturnType<Context["session"
|
|
|
27
27
|
export declare function listChildren(ports: CourierPorts, parentID: string): Promise<({
|
|
28
28
|
group: {
|
|
29
29
|
name: string;
|
|
30
|
-
report: "failed" | "interrupted" | "
|
|
30
|
+
report: "failed" | "interrupted" | "out" | "unknown" | "deleted" | "dropped" | "held" | "released";
|
|
31
31
|
};
|
|
32
32
|
directory: string;
|
|
33
33
|
isolated: boolean;
|
|
@@ -57,7 +57,7 @@ export declare function listChildren(ports: CourierPorts, parentID: string): Pro
|
|
|
57
57
|
error: string;
|
|
58
58
|
group: {
|
|
59
59
|
name: string;
|
|
60
|
-
report: "failed" | "interrupted" | "
|
|
60
|
+
report: "failed" | "interrupted" | "out" | "unknown" | "deleted" | "dropped" | "held" | "released";
|
|
61
61
|
};
|
|
62
62
|
directory: string;
|
|
63
63
|
isolated: boolean;
|
|
@@ -77,7 +77,7 @@ export declare function listChildren(ports: CourierPorts, parentID: string): Pro
|
|
|
77
77
|
export declare function described(ports: CourierPorts, entry: RosterEntry): Promise<{
|
|
78
78
|
group: {
|
|
79
79
|
name: string;
|
|
80
|
-
report: "failed" | "interrupted" | "
|
|
80
|
+
report: "failed" | "interrupted" | "out" | "unknown" | "deleted" | "dropped" | "held" | "released";
|
|
81
81
|
};
|
|
82
82
|
directory: string;
|
|
83
83
|
isolated: boolean;
|
|
@@ -107,7 +107,7 @@ export declare function described(ports: CourierPorts, entry: RosterEntry): Prom
|
|
|
107
107
|
error: string;
|
|
108
108
|
group: {
|
|
109
109
|
name: string;
|
|
110
|
-
report: "failed" | "interrupted" | "
|
|
110
|
+
report: "failed" | "interrupted" | "out" | "unknown" | "deleted" | "dropped" | "held" | "released";
|
|
111
111
|
};
|
|
112
112
|
directory: string;
|
|
113
113
|
isolated: boolean;
|
|
@@ -124,5 +124,5 @@ export declare function described(ports: CourierPorts, entry: RosterEntry): Prom
|
|
|
124
124
|
title: string;
|
|
125
125
|
}>;
|
|
126
126
|
/** A child's standing in the join group its roster entry names, `unknown` when that cannot be read. */
|
|
127
|
-
export declare function standingIn(ports: Pick<CourierPorts, "storage">, entry: RosterEntry, group: string): Promise<"failed" | "interrupted" | "
|
|
127
|
+
export declare function standingIn(ports: Pick<CourierPorts, "storage">, entry: RosterEntry, group: string): Promise<"failed" | "interrupted" | "out" | "unknown" | "deleted" | "dropped" | "held" | "released">;
|
|
128
128
|
export {};
|
package/dist/tree/subtree.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export declare function tree(ports: CourierPorts, rootID: string): Promise<{
|
|
|
60
60
|
depth: number;
|
|
61
61
|
group: {
|
|
62
62
|
name: string;
|
|
63
|
-
report: "failed" | "interrupted" | "
|
|
63
|
+
report: "failed" | "interrupted" | "out" | "unknown" | "deleted" | "dropped" | "held" | "released";
|
|
64
64
|
};
|
|
65
65
|
directory: string;
|
|
66
66
|
isolated: boolean;
|
|
@@ -104,7 +104,7 @@ export declare function tree(ports: CourierPorts, rootID: string): Promise<{
|
|
|
104
104
|
error: string;
|
|
105
105
|
group: {
|
|
106
106
|
name: string;
|
|
107
|
-
report: "failed" | "interrupted" | "
|
|
107
|
+
report: "failed" | "interrupted" | "out" | "unknown" | "deleted" | "dropped" | "held" | "released";
|
|
108
108
|
};
|
|
109
109
|
directory: string;
|
|
110
110
|
isolated: boolean;
|
package/dist/tree/text.js
CHANGED
|
@@ -64,7 +64,8 @@ export function rolePart(depth, limits) {
|
|
|
64
64
|
const budget = `At most ${maxChildren} of the sessions you start run at once, and ${maxTotal} in the whole tree.`;
|
|
65
65
|
if (depth === null)
|
|
66
66
|
return (`${ROLE_PREFIX} root, no sessions started yet. Before a task that touches several files or areas, load the ` +
|
|
67
|
-
`${SKILL_ID} skill
|
|
67
|
+
`${SKILL_ID} skill, call courier_recall once for how earlier trees in this project were split and how they went, ` +
|
|
68
|
+
`and decide whether to split it across sessions (doing it yourself is fine), and say ` +
|
|
68
69
|
`which in one line of your reply: ${SPLIT_LINE}`);
|
|
69
70
|
if (depth === 0)
|
|
70
71
|
return (`${ROLE_PREFIX} root orchestrator. You started sessions with courier_spawn, and they may start their own, ` +
|
package/dist/tree/tui.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode/plugin/tui";
|
|
2
|
+
import { RGBA, type EasingFunctions } from "@opentui/core";
|
|
3
|
+
import { type Accessor } from "solid-js";
|
|
4
|
+
import { type MascotState, type Token } from "./mascot.js";
|
|
2
5
|
import { type Forgotten, type Row, type Stopped, type Summary, type Wait } from "./rpc.js";
|
|
3
6
|
type Context = Plugin.Context;
|
|
4
7
|
/** The events after which a summary may read differently: a turn started or ended, a request or form, a session made or removed. */
|
|
@@ -11,6 +14,62 @@ export declare const PANEL_SETTLE_MS = 1000;
|
|
|
11
14
|
export declare const PANEL = "courier-tree";
|
|
12
15
|
/** How often the panel redraws its running times and how long ago each last tool call was. */
|
|
13
16
|
export declare const TICK_MS = 1000;
|
|
17
|
+
/** The panel's animation frame: the spinner's step, and how often a flash or the bar's easing moves. */
|
|
18
|
+
export declare const FRAME_MS = 90;
|
|
19
|
+
/** How long a row's background takes to fade back from its flash after its report arrives: the report's hold. */
|
|
20
|
+
export declare const FLASH_MS = 1500;
|
|
21
|
+
/** How long the header's bar takes to grow, or shrink, to its new length. */
|
|
22
|
+
export declare const BAR_MS = 450;
|
|
23
|
+
/** Whether the panel animates: unless the TUI part's options say `"animations": false`, as the plugin API has no TUI setting for it. */
|
|
24
|
+
export declare function animationsOn(options: Readonly<Record<string, unknown>> | undefined): boolean;
|
|
25
|
+
/** A value eased over the panel's frames by OpenTUI's `Timeline`; reading it in a computation follows the frames. */
|
|
26
|
+
export type Tween = {
|
|
27
|
+
readonly value: () => number;
|
|
28
|
+
readonly done: () => boolean;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The panel's one timer: a frame every `FRAME_MS` while a tween moves or an `animates` predicate holds, every `every` while
|
|
32
|
+
* only slower ones do, none otherwise, with animations off or once the panel is gone. `frame` counts in `FRAME_MS`.
|
|
33
|
+
*/
|
|
34
|
+
export type Motion = {
|
|
35
|
+
readonly enabled: boolean;
|
|
36
|
+
readonly frame: Accessor<number>;
|
|
37
|
+
readonly animates: (when: Accessor<boolean>, every?: number) => void;
|
|
38
|
+
readonly tween: (from: number, to: number, duration: number, ease: EasingFunctions) => Tween;
|
|
39
|
+
};
|
|
40
|
+
/** The panel's `Motion`, owned by the computation it is made in. */
|
|
41
|
+
export declare function createMotion(enabled: boolean): Motion;
|
|
42
|
+
/**
|
|
43
|
+
* Each row's flash, by session, from a read of the rows to the next that finds its report turned to `reported`; not on
|
|
44
|
+
* the first read. `strength` is a row's, 1 when its report arrives down to 0; `reported` holds for `FLASH_MS` after one.
|
|
45
|
+
*/
|
|
46
|
+
export declare function createFlashes(motion: Motion, rows: Accessor<ReadonlyArray<Row>>): {
|
|
47
|
+
strength: (sessionID: string) => number;
|
|
48
|
+
reported: () => boolean;
|
|
49
|
+
};
|
|
50
|
+
/** The header bar's filled cells, eased over `BAR_MS` to its new length once it is shown, at once when it first is. */
|
|
51
|
+
export declare function createBarFill(motion: Motion, counts: Accessor<{
|
|
52
|
+
reported: number;
|
|
53
|
+
started: number;
|
|
54
|
+
}>): () => number;
|
|
55
|
+
/** True for `FLASH_MS` after a read of the tree finds a session the one before it did not have; not on the first read. */
|
|
56
|
+
export declare function createSpawns(motion: Motion, rows: Accessor<ReadonlyArray<Row> | undefined>): () => boolean;
|
|
57
|
+
/** Digby's state for the tree's rows, by `summaryLine`'s priority, unless a report or a spawn just arrived. */
|
|
58
|
+
export declare function mascotState(rows: ReadonlyArray<Row>, { reported, spawned }?: {
|
|
59
|
+
reported?: boolean | undefined;
|
|
60
|
+
spawned?: boolean | undefined;
|
|
61
|
+
}): MascotState;
|
|
62
|
+
/** What the tree's sessions do, as the header's second line says it: "1 waiting on you · 2 running"; empty with none live. */
|
|
63
|
+
export declare function countsLine(rows: ReadonlyArray<Row>): string;
|
|
64
|
+
/** The panel's size below which it shows no header glyph, so the header keeps to one line and its bar is not cut. */
|
|
65
|
+
export declare const GLYPH_ROWS = 12;
|
|
66
|
+
export declare const GLYPH_COLUMNS = 54;
|
|
67
|
+
/** The empty panel's height from which it shows the 16×16. */
|
|
68
|
+
export declare const ART_ROWS = 14;
|
|
69
|
+
/** The rows left free below the tree's last row from which the 16×16 shows there. */
|
|
70
|
+
export declare const BELOW_ROWS = 10;
|
|
71
|
+
/** `tint` over `rest` by `amount`, from 0 (all `rest`) to 1 (all `tint`). */
|
|
72
|
+
export declare function blend(tint: RGBA, rest: RGBA, amount: number): RGBA;
|
|
14
73
|
/**
|
|
15
74
|
* The status entry's text, such as "courier 1 waiting on you · 2 running · group pair 1/2"; empty when there is nothing to show.
|
|
16
75
|
* Within `maxWidth` it keeps whole parts, most important first, and counts the groups it drops: "· +2 groups".
|
|
@@ -23,17 +82,47 @@ export declare function parts(rows: ReadonlyArray<Row>, parentID: string): {
|
|
|
23
82
|
reported: number;
|
|
24
83
|
started: number;
|
|
25
84
|
};
|
|
26
|
-
/**
|
|
27
|
-
export declare function
|
|
85
|
+
/** How many of a bar's `width` cells are filled for the parts reported. */
|
|
86
|
+
export declare function filledCells({ reported, started }: {
|
|
28
87
|
reported: number;
|
|
29
88
|
started: number;
|
|
30
|
-
}, width?: number):
|
|
89
|
+
}, width?: number): number;
|
|
90
|
+
/** A bar of parts reported, `width` cells wide: "[████░░░░░░] 2/5 reported"; `filled` cells of it while it eases to its length. */
|
|
91
|
+
export declare function bar(counts: {
|
|
92
|
+
reported: number;
|
|
93
|
+
started: number;
|
|
94
|
+
}, width?: number, filled?: number): string;
|
|
31
95
|
/** What a paused session waits on, such as "asks permission: shell echo hi" or "shows a form: Web Search". */
|
|
32
96
|
export declare function waitLine(wait: Wait): string;
|
|
33
97
|
/** What a row's session is doing, its report and its group standing: "idle · reported done · group pair held". */
|
|
34
98
|
export declare function statusLine(row: Row): string;
|
|
35
|
-
/**
|
|
36
|
-
export declare function
|
|
99
|
+
/** The parts of `statusLine`, each with the row part the panel colours it as. */
|
|
100
|
+
export declare function statusParts(row: Row): {
|
|
101
|
+
text: string;
|
|
102
|
+
kind: "state" | "report" | "plain";
|
|
103
|
+
}[];
|
|
104
|
+
type Feedback<Color> = {
|
|
105
|
+
text: {
|
|
106
|
+
feedback: Record<"error" | "warning" | "success" | "info", {
|
|
107
|
+
base: Color;
|
|
108
|
+
}>;
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
/** The running mark's frames, one every `FRAME_MS`. */
|
|
112
|
+
export declare const SPINNER: string[];
|
|
113
|
+
/**
|
|
114
|
+
* The one cell a row's state shows and its theme colour, the blank cell of one with no mark: this is the only place that
|
|
115
|
+
* chooses them. A running row spins through `SPINNER` at the panel's `frame`, and shows `•` with none (animations off).
|
|
116
|
+
*/
|
|
117
|
+
export declare function rowMark<Color>(row: Row, theme: Feedback<Color>, frame?: number): {
|
|
118
|
+
mark: string;
|
|
119
|
+
color: Color | undefined;
|
|
120
|
+
};
|
|
121
|
+
/** Past this fraction of its window, a session's context use is shown in the warning colour. */
|
|
122
|
+
export declare const CONTEXT_WARN = 0.8;
|
|
123
|
+
/** A leaf's activity: how long it has run, its last tool call and how long ago, its context use and its cost. */
|
|
124
|
+
export declare function activityParts(row: Row, now: number): string[];
|
|
125
|
+
export declare const activityLine: (row: Row, now: number) => string;
|
|
37
126
|
/** What a stalled session's row, or the panel of one, says of it: "a message waits in its inbox since 2m 05s, woken again in vain". */
|
|
38
127
|
export declare function stalledLine(since: number, now: number): string;
|
|
39
128
|
/** The lines a row shows under its title: an orchestrator's bar, a paused or stalled session's wait, or else a live leaf's activity. */
|
|
@@ -49,13 +138,31 @@ export declare function addTreeStatus(ctx: Context, onWaiting?: (sessionID: stri
|
|
|
49
138
|
export declare function stoppedLine({ stopped, cancelled }: Stopped): string;
|
|
50
139
|
/** The toast after a forget, as courier_cleanup reports it: forgotten, its worktree removed or already gone, or kept and why. */
|
|
51
140
|
export declare function forgottenLine(title: string, result: Forgotten): string;
|
|
52
|
-
/** The
|
|
141
|
+
/** The one place Digby's pixel tokens take a theme colour. */
|
|
142
|
+
export declare const digbyColours: (theme: Context["theme"]) => Record<Token, RGBA>;
|
|
143
|
+
/**
|
|
144
|
+
* A row's background at rest: the selection's while the panel has the keyboard, else one step quieter under the pointer,
|
|
145
|
+
* else none, the panel's.
|
|
146
|
+
*/
|
|
147
|
+
export declare function restBackground(theme: Context["theme"], { selected, hovered }: {
|
|
148
|
+
selected: boolean;
|
|
149
|
+
hovered: boolean;
|
|
150
|
+
}): RGBA | undefined;
|
|
151
|
+
/** The usage the `/courier` command shows for an input it does not know, before the further verbs' lines. */
|
|
53
152
|
export declare const USAGE = "/courier tree opens the session tree; /courier stop [session] stops a session and those under it";
|
|
153
|
+
/** A further verb of the `/courier` command, which another module's TUI part supplies: what it runs, and its line of the usage. */
|
|
154
|
+
export type Verb = {
|
|
155
|
+
readonly run: () => void;
|
|
156
|
+
readonly usage: string;
|
|
157
|
+
};
|
|
158
|
+
/** The usage with the further verbs' lines. */
|
|
159
|
+
export declare const usageWith: (verbs: Readonly<Record<string, Verb>>) => string;
|
|
54
160
|
/**
|
|
55
161
|
* Adds the tree panel to the `session.panel` slot, opened by `/courier tree` or the palette, which follows the person
|
|
56
|
-
* between sessions until closed, and `/courier stop <session>`, which stops a session under the open one once confirmed
|
|
162
|
+
* between sessions until closed, and `/courier stop <session>`, which stops a session under the open one once confirmed;
|
|
163
|
+
* `verbs` are the command's further verbs, by name.
|
|
57
164
|
*/
|
|
58
|
-
export declare function addTreePanel(ctx: Context): () => void;
|
|
165
|
+
export declare function addTreePanel(ctx: Context, verbs?: Readonly<Record<string, Verb>>): () => void;
|
|
59
166
|
/**
|
|
60
167
|
* Draws the person's attention when reports arrive: a join group's reports, released to the session that started them,
|
|
61
168
|
* and a child's report to its parent, with the `subagent_done` sound. Read from the courier's own delivery metadata.
|