opencode-courier 0.4.1 → 0.6.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 +38 -25
- package/dist/index.js +7 -4
- package/dist/person/form.d.ts +4 -1
- package/dist/person/form.js +5 -0
- package/dist/person/index.d.ts +2 -1
- package/dist/person/index.js +1 -0
- package/dist/person/permission.d.ts +37 -2
- package/dist/person/permission.js +91 -17
- package/dist/person/ports.d.ts +8 -2
- package/dist/person/rpc-handlers.d.ts +37 -30
- package/dist/person/rpc-handlers.js +26 -16
- package/dist/person/rpc.d.ts +43 -24
- package/dist/person/rpc.js +4 -3
- package/dist/person/text.d.ts +5 -0
- package/dist/person/text.js +21 -19
- package/dist/person/tools.d.ts +1 -1
- package/dist/person/tools.js +23 -12
- package/dist/person/tui.d.ts +23 -12
- package/dist/tree/domain.d.ts +23 -0
- package/dist/tree/domain.js +26 -0
- package/dist/tree/events.d.ts +2 -2
- package/dist/tree/events.js +5 -3
- package/dist/tree/index.d.ts +1 -1
- package/dist/tree/panel.d.ts +7 -2
- package/dist/tree/panel.js +19 -16
- package/dist/tree/ports.d.ts +7 -0
- package/dist/tree/roster.d.ts +5 -0
- package/dist/tree/roster.js +5 -3
- package/dist/tree/rpc-handlers.d.ts +45 -5
- package/dist/tree/rpc-handlers.js +30 -1
- package/dist/tree/rpc.d.ts +79 -19
- package/dist/tree/rpc.js +20 -8
- package/dist/tree/subtree.d.ts +40 -9
- package/dist/tree/subtree.js +40 -19
- package/dist/tree/summary.d.ts +2 -2
- package/dist/tree/summary.js +8 -16
- package/dist/tree/text.js +4 -1
- package/dist/tree/tools.js +2 -1
- package/dist/tree/tui.d.ts +12 -5
- package/dist/tui.js +585 -176
- package/package.json +4 -4
package/dist/tree/panel.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { busy } from "./domain.js";
|
|
2
|
-
import { lastStatus,
|
|
2
|
+
import { lastStatus, stoppedSincePrompt } from "./report.js";
|
|
3
3
|
import { standingIn } from "./status.js";
|
|
4
4
|
import { childStore } from "./store.js";
|
|
5
|
-
import {
|
|
5
|
+
import { readTree } from "./subtree.js";
|
|
6
6
|
/** The last tool call in a session's messages, and when it was made. */
|
|
7
7
|
export function lastTool(messages) {
|
|
8
8
|
for (const message of messages.toReversed()) {
|
|
@@ -18,6 +18,8 @@ export function lastTool(messages) {
|
|
|
18
18
|
export const waitOf = (pending) => pending.type === "permission"
|
|
19
19
|
? { type: "permission", action: pending.action, resources: [...pending.resources] }
|
|
20
20
|
: { type: "question", question: pending.questions[0]?.question ?? "" };
|
|
21
|
+
/** A form a session shows, as the panel says what it waits on. */
|
|
22
|
+
export const formWait = (form) => ({ type: "form", title: form.title });
|
|
21
23
|
/** A session's report since its last prompt, as the panel shows it; none for one spawned before this was kept. */
|
|
22
24
|
function reportRow(report, status) {
|
|
23
25
|
if (!report)
|
|
@@ -28,7 +30,7 @@ function reportRow(report, status) {
|
|
|
28
30
|
return { report: { state: "ended", progressed: report.progressed } };
|
|
29
31
|
return { report: { state: "reported", progressed: report.progressed, ...(status ? { status } : {}) } };
|
|
30
32
|
}
|
|
31
|
-
/** What a session does: waiting on a request to the person, running, idle, or gone when OpenCode no longer knows it. */
|
|
33
|
+
/** What a session does: waiting on a request to the person or a form it shows them, running, idle, or gone when OpenCode no longer knows it. */
|
|
32
34
|
function stateOf(info, waits, running) {
|
|
33
35
|
if (!info)
|
|
34
36
|
return "gone";
|
|
@@ -37,16 +39,13 @@ function stateOf(info, waits, running) {
|
|
|
37
39
|
return running ? "running" : "idle";
|
|
38
40
|
}
|
|
39
41
|
/** One session of the panel: what it is doing, its report and group standing, its last tool call and its cost. */
|
|
40
|
-
async function row(ports, entry, depth) {
|
|
42
|
+
async function row(ports, { entry, depth, info, pending, forms, report }) {
|
|
41
43
|
const { sessionID } = entry;
|
|
42
|
-
const
|
|
43
|
-
const [info, messages, pending, report, status, standing] = await Promise.all([
|
|
44
|
-
ports.session.get({ sessionID }).catch(() => undefined),
|
|
44
|
+
const [messages, status, standing, stopped] = await Promise.all([
|
|
45
45
|
ports.session.context({ sessionID }).catch(() => []),
|
|
46
|
-
ports.
|
|
47
|
-
reportOf(children, sessionID).catch(() => undefined),
|
|
48
|
-
lastStatus(children, sessionID).catch(() => undefined),
|
|
46
|
+
lastStatus(childStore(ports.storage), sessionID).catch(() => undefined),
|
|
49
47
|
entry.group ? standingIn(ports, entry, entry.group) : undefined,
|
|
48
|
+
stoppedSincePrompt(childStore(ports.storage), sessionID).catch(() => false),
|
|
50
49
|
]);
|
|
51
50
|
const running = info !== undefined && busy(info.time);
|
|
52
51
|
const tool = lastTool(messages);
|
|
@@ -55,8 +54,9 @@ async function row(ports, entry, depth) {
|
|
|
55
54
|
parentID: entry.parentID,
|
|
56
55
|
title: info?.title ?? entry.title,
|
|
57
56
|
depth,
|
|
58
|
-
state: stateOf(info, pending.length, running),
|
|
57
|
+
state: stateOf(info, pending.length + forms.length, running),
|
|
59
58
|
...(info?.outcome ? { outcome: info.outcome } : {}),
|
|
59
|
+
...(stopped ? { stopped } : {}),
|
|
60
60
|
...reportRow(report, status),
|
|
61
61
|
...(entry.group && standing ? { group: { name: entry.group, standing } } : {}),
|
|
62
62
|
isolated: entry.isolated,
|
|
@@ -64,12 +64,15 @@ async function row(ports, entry, depth) {
|
|
|
64
64
|
...(info && !running && info.time.idle !== undefined ? { idle: info.time.idle } : {}),
|
|
65
65
|
...(info ? { cost: info.cost } : {}),
|
|
66
66
|
...(tool ? { tool } : {}),
|
|
67
|
-
waits: pending.map(waitOf),
|
|
67
|
+
waits: [...pending.map(waitOf), ...forms.map(formWait)],
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* The tree panel's rows: the sessions under a session as courier_tree lists them, at most `maxTotal`, the live ones
|
|
72
|
+
* first, then the newest, each as `row` reads it; `truncated` counts the older ones left out.
|
|
73
|
+
*/
|
|
71
74
|
export async function panel(ports, rootID) {
|
|
72
|
-
const {
|
|
73
|
-
const rows = await Promise.all(
|
|
74
|
-
return { rows, ...(
|
|
75
|
+
const { kept, leftOut } = await readTree(ports, rootID);
|
|
76
|
+
const rows = await Promise.all(kept.map((node) => row(ports, node)));
|
|
77
|
+
return { rows, ...(leftOut ? { truncated: leftOut } : {}) };
|
|
75
78
|
}
|
package/dist/tree/ports.d.ts
CHANGED
|
@@ -133,6 +133,8 @@ export interface CourierPorts {
|
|
|
133
133
|
readonly now: () => number;
|
|
134
134
|
/** The permission requests and questions a session waits on, wherever they are pending. */
|
|
135
135
|
readonly pending: (sessionID: string) => Promise<ReadonlyArray<Pending>>;
|
|
136
|
+
/** The forms a session shows, which only the person can answer: web search's, a plugin's; not the question tool's. */
|
|
137
|
+
readonly forms: (sessionID: string) => Promise<ReadonlyArray<ShownForm>>;
|
|
136
138
|
readonly limits: Limits;
|
|
137
139
|
/** The `nativeChildren` option: a child started without isolate is created with OpenCode's own `parentID`. */
|
|
138
140
|
readonly nativeChildren?: boolean;
|
|
@@ -143,6 +145,11 @@ export interface CourierPorts {
|
|
|
143
145
|
readonly nudge: () => void;
|
|
144
146
|
readonly log: (message: string) => void;
|
|
145
147
|
}
|
|
148
|
+
/** A form a session shows, as `CourierPorts.forms` lists it; `person/` keeps them. */
|
|
149
|
+
export interface ShownForm {
|
|
150
|
+
readonly id: string;
|
|
151
|
+
readonly title: string;
|
|
152
|
+
}
|
|
146
153
|
/** One question a session waits on, as `Pending` shows it; `person/`'s `Prompt` has these fields. */
|
|
147
154
|
export interface PendingPrompt {
|
|
148
155
|
readonly question: string;
|
package/dist/tree/roster.d.ts
CHANGED
|
@@ -18,6 +18,11 @@ export declare function lineage(storage: RosterStorage, sessionID: string): Prom
|
|
|
18
18
|
export declare function answeringTop(storage: RosterStorage, sessionID: string, callerID: string, what: string): Promise<string>;
|
|
19
19
|
/** Whether a directory still exists; tests pass a fake. */
|
|
20
20
|
export type Exists = (directory: string) => boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether an entry is past retention at `now`: recorded more than `RETENTION_MS` before, unless it is an isolated
|
|
23
|
+
* child whose worktree exists, which is kept so it can still be cleaned up.
|
|
24
|
+
*/
|
|
25
|
+
export declare const isExpired: (entry: RosterEntry, now: number, exists?: Exists) => boolean;
|
|
21
26
|
/** A parent's children, oldest first, after dropping the expired ones. */
|
|
22
27
|
export declare function current(storage: RosterStorage, parentID: string, now: number, exists?: Exists): Promise<RosterEntry[]>;
|
|
23
28
|
/**
|
package/dist/tree/roster.js
CHANGED
|
@@ -31,11 +31,13 @@ export async function answeringTop(storage, sessionID, callerID, what) {
|
|
|
31
31
|
return top;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
34
|
+
* Whether an entry is past retention at `now`: recorded more than `RETENTION_MS` before, unless it is an isolated
|
|
35
|
+
* child whose worktree exists, which is kept so it can still be cleaned up.
|
|
36
36
|
*/
|
|
37
|
+
export const isExpired = (entry, now, exists = existsSync) => now - entry.createdAt > RETENTION_MS && !(entry.isolated && exists(entry.directory));
|
|
38
|
+
/** Forgets the given entries that are expired at `now`, and returns the rest. */
|
|
37
39
|
async function dropExpired(storage, entries, now, exists) {
|
|
38
|
-
const expired = new Set(entries.filter((entry) =>
|
|
40
|
+
const expired = new Set(entries.filter((entry) => isExpired(entry, now, exists)));
|
|
39
41
|
await Promise.all([...expired].map((entry) => forgetChild(storage, entry.parentID, entry.sessionID, entry.group)));
|
|
40
42
|
return entries.filter((entry) => !expired.has(entry));
|
|
41
43
|
}
|
|
@@ -14,24 +14,22 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
14
14
|
}>;
|
|
15
15
|
readonly output: import("effect/StandardSchema").StandardSchemaV1<{
|
|
16
16
|
readonly running: number;
|
|
17
|
+
readonly waiting: number;
|
|
17
18
|
readonly idle: number;
|
|
18
19
|
readonly groups: readonly {
|
|
19
20
|
readonly name: string;
|
|
20
21
|
readonly reported: number;
|
|
21
22
|
readonly members: number;
|
|
22
23
|
}[];
|
|
23
|
-
readonly waiting: number;
|
|
24
|
-
readonly truncated?: number | undefined;
|
|
25
24
|
}, {
|
|
26
25
|
readonly running: number;
|
|
26
|
+
readonly waiting: number;
|
|
27
27
|
readonly idle: number;
|
|
28
28
|
readonly groups: readonly {
|
|
29
29
|
readonly name: string;
|
|
30
30
|
readonly reported: number;
|
|
31
31
|
readonly members: number;
|
|
32
32
|
}[];
|
|
33
|
-
readonly waiting: number;
|
|
34
|
-
readonly truncated?: number | undefined;
|
|
35
33
|
}> & import("effect/Schema").Struct<{
|
|
36
34
|
readonly running: import("effect/Schema").Int;
|
|
37
35
|
readonly waiting: import("effect/Schema").Int;
|
|
@@ -41,7 +39,6 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
41
39
|
readonly reported: import("effect/Schema").Int;
|
|
42
40
|
readonly members: import("effect/Schema").Int;
|
|
43
41
|
}>>;
|
|
44
|
-
readonly truncated: import("effect/Schema").optionalKey<import("effect/Schema").Int>;
|
|
45
42
|
}>;
|
|
46
43
|
};
|
|
47
44
|
readonly tree: {
|
|
@@ -68,11 +65,15 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
68
65
|
} | {
|
|
69
66
|
readonly type: "question";
|
|
70
67
|
readonly question: string;
|
|
68
|
+
} | {
|
|
69
|
+
readonly type: "form";
|
|
70
|
+
readonly title: string;
|
|
71
71
|
})[];
|
|
72
72
|
readonly group?: {
|
|
73
73
|
readonly name: string;
|
|
74
74
|
readonly standing: string;
|
|
75
75
|
} | undefined;
|
|
76
|
+
readonly stopped?: boolean | undefined;
|
|
76
77
|
readonly idle?: number | undefined;
|
|
77
78
|
readonly report?: {
|
|
78
79
|
readonly progressed: boolean;
|
|
@@ -103,11 +104,15 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
103
104
|
} | {
|
|
104
105
|
readonly type: "question";
|
|
105
106
|
readonly question: string;
|
|
107
|
+
} | {
|
|
108
|
+
readonly type: "form";
|
|
109
|
+
readonly title: string;
|
|
106
110
|
})[];
|
|
107
111
|
readonly group?: {
|
|
108
112
|
readonly name: string;
|
|
109
113
|
readonly standing: string;
|
|
110
114
|
} | undefined;
|
|
115
|
+
readonly stopped?: boolean | undefined;
|
|
111
116
|
readonly idle?: number | undefined;
|
|
112
117
|
readonly report?: {
|
|
113
118
|
readonly progressed: boolean;
|
|
@@ -130,6 +135,7 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
130
135
|
readonly depth: import("effect/Schema").Int;
|
|
131
136
|
readonly state: import("effect/Schema").Literals<readonly ["running", "waiting", "idle", "gone"]>;
|
|
132
137
|
readonly outcome: import("effect/Schema").optionalKey<import("effect/Schema").Literals<readonly ["succeeded", "failed", "interrupted"]>>;
|
|
138
|
+
readonly stopped: import("effect/Schema").optionalKey<import("effect/Schema").Boolean>;
|
|
133
139
|
readonly report: import("effect/Schema").optionalKey<import("effect/Schema").Struct<{
|
|
134
140
|
readonly state: import("effect/Schema").Literals<readonly ["owed", "reported", "ended"]>;
|
|
135
141
|
readonly status: import("effect/Schema").optionalKey<import("effect/Schema").String>;
|
|
@@ -154,6 +160,9 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
154
160
|
}>, import("effect/Schema").Struct<{
|
|
155
161
|
readonly type: import("effect/Schema").Literal<"question">;
|
|
156
162
|
readonly question: import("effect/Schema").String;
|
|
163
|
+
}>, import("effect/Schema").Struct<{
|
|
164
|
+
readonly type: import("effect/Schema").Literal<"form">;
|
|
165
|
+
readonly title: import("effect/Schema").String;
|
|
157
166
|
}>]>>;
|
|
158
167
|
}>>;
|
|
159
168
|
readonly truncated: import("effect/Schema").optionalKey<import("effect/Schema").Int>;
|
|
@@ -196,6 +205,37 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
196
205
|
readonly refused: import("effect/StandardSchema").StandardSchemaV1<{}, {}> & import("effect/Schema").Struct<{}>;
|
|
197
206
|
};
|
|
198
207
|
};
|
|
208
|
+
readonly cleanup: {
|
|
209
|
+
readonly input: import("effect/StandardSchema").StandardSchemaV1<{
|
|
210
|
+
readonly sessionID: string;
|
|
211
|
+
readonly by: string;
|
|
212
|
+
}, {
|
|
213
|
+
readonly sessionID: string;
|
|
214
|
+
readonly by: string;
|
|
215
|
+
}> & import("effect/Schema").Struct<{
|
|
216
|
+
readonly sessionID: import("effect/Schema").String;
|
|
217
|
+
readonly by: import("effect/Schema").String;
|
|
218
|
+
}>;
|
|
219
|
+
readonly output: import("effect/StandardSchema").StandardSchemaV1<{
|
|
220
|
+
readonly outcome: "removed" | "gone" | "forgotten";
|
|
221
|
+
} | {
|
|
222
|
+
readonly outcome: "kept";
|
|
223
|
+
readonly reason: string;
|
|
224
|
+
}, {
|
|
225
|
+
readonly outcome: "removed" | "gone" | "forgotten";
|
|
226
|
+
} | {
|
|
227
|
+
readonly outcome: "kept";
|
|
228
|
+
readonly reason: string;
|
|
229
|
+
}> & import("effect/Schema").Union<readonly [import("effect/Schema").Struct<{
|
|
230
|
+
readonly outcome: import("effect/Schema").Literals<readonly ["forgotten", "removed", "gone"]>;
|
|
231
|
+
}>, import("effect/Schema").Struct<{
|
|
232
|
+
readonly outcome: import("effect/Schema").Literal<"kept">;
|
|
233
|
+
readonly reason: import("effect/Schema").String;
|
|
234
|
+
}>]>;
|
|
235
|
+
readonly errors: {
|
|
236
|
+
readonly refused: import("effect/StandardSchema").StandardSchemaV1<{}, {}> & import("effect/Schema").Struct<{}>;
|
|
237
|
+
};
|
|
238
|
+
};
|
|
199
239
|
};
|
|
200
240
|
readonly events: {};
|
|
201
241
|
}>>;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { describeFailure } from "../kernel/protocol.js";
|
|
2
|
+
import { isNotFound } from "../platform/json.js";
|
|
3
|
+
import { cleanup } from "./cleanup.js";
|
|
1
4
|
import { panel } from "./panel.js";
|
|
2
5
|
import { treeRpc } from "./rpc.js";
|
|
3
6
|
import { stop } from "./stop.js";
|
|
7
|
+
import { childStore } from "./store.js";
|
|
4
8
|
import { summary } from "./summary.js";
|
|
5
9
|
/** Serves the tree's RPC at the plugin's location, through the same use cases as the tools; disposed with the plugin. */
|
|
6
10
|
export function registerTreeRpc(rpc, ports) {
|
|
11
|
+
const refused = (cause) => (cause instanceof Error ? cause.message : String(cause));
|
|
7
12
|
return rpc.register(treeRpc, {
|
|
8
13
|
summary: ({ sessionID }) => summary(ports.courier, sessionID),
|
|
9
14
|
tree: ({ sessionID }) => panel(ports.courier, sessionID),
|
|
@@ -13,8 +18,32 @@ export function registerTreeRpc(rpc, ports) {
|
|
|
13
18
|
return { stopped: stopped.map(({ sessionID, title, outcome }) => ({ sessionID, title, outcome })), cancelled: cancelled.length };
|
|
14
19
|
}
|
|
15
20
|
catch (cause) {
|
|
16
|
-
return error("refused",
|
|
21
|
+
return error("refused", refused(cause), {});
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
cleanup: async ({ sessionID, by }, { error }) => {
|
|
25
|
+
try {
|
|
26
|
+
return await forget(ports, by, sessionID);
|
|
27
|
+
}
|
|
28
|
+
catch (cause) {
|
|
29
|
+
return error("refused", refused(cause), {});
|
|
17
30
|
}
|
|
18
31
|
},
|
|
19
32
|
});
|
|
20
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Forgets a session OpenCode no longer knows as courier_cleanup called from its own parent, once `by` is found above it,
|
|
36
|
+
* as courier_stop checks. A session OpenCode still has, or cannot say it lost, is refused: forgetting it loses its report.
|
|
37
|
+
*/
|
|
38
|
+
async function forget(ports, by, sessionID) {
|
|
39
|
+
const chain = await childStore(ports.courier.storage).lineage(sessionID);
|
|
40
|
+
if (!chain.length)
|
|
41
|
+
throw new Error(`${sessionID} was not started with courier_spawn, so there is nothing to forget.`);
|
|
42
|
+
if (!chain.some((entry) => entry.parentID === by))
|
|
43
|
+
throw new Error(`${by} is not above ${sessionID}: only a session above it, in the line of sessions that started it with courier_spawn, can forget it.`);
|
|
44
|
+
const known = await ports.courier.session.get({ sessionID }).then(() => `${sessionID} is still known to OpenCode: only a gone session is forgotten here.`, (error) => (isNotFound(error) ? undefined : describeFailure("session.get", error).message));
|
|
45
|
+
if (known)
|
|
46
|
+
throw new Error(known);
|
|
47
|
+
const result = await cleanup(ports.cleanup, chain[0].parentID, { sessionID });
|
|
48
|
+
return result.outcome === "kept" ? { outcome: "kept", reason: result.reason } : { outcome: result.outcome };
|
|
49
|
+
}
|
package/dist/tree/rpc.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Schema } from "effect";
|
|
2
2
|
/** The sessions started under a session, as the prompt footer's status entry shows them. */
|
|
3
3
|
declare const Summary: Schema.Struct<{
|
|
4
|
-
/** Running, and waiting on no request. */
|
|
4
|
+
/** Running, and waiting on no request or form. */
|
|
5
5
|
readonly running: Schema.Int;
|
|
6
|
-
/** Waiting on a permission request or a
|
|
6
|
+
/** Waiting on a permission request, a question or a form it shows, which go to the person. */
|
|
7
7
|
readonly waiting: Schema.Int;
|
|
8
8
|
/** Not running: done, or waiting for a message. */
|
|
9
9
|
readonly idle: Schema.Int;
|
|
@@ -12,11 +12,9 @@ declare const Summary: Schema.Struct<{
|
|
|
12
12
|
readonly reported: Schema.Int;
|
|
13
13
|
readonly members: Schema.Int;
|
|
14
14
|
}>>;
|
|
15
|
-
/** Set when the subtree had more sessions than `maxTotal`, which were not counted. */
|
|
16
|
-
readonly truncated: Schema.optionalKey<Schema.Int>;
|
|
17
15
|
}>;
|
|
18
16
|
export type Summary = typeof Summary.Type;
|
|
19
|
-
/** A request a session waits on until the person answers it: a permission request,
|
|
17
|
+
/** A request a session waits on until the person answers it: a permission request, its first question, or a form it shows. */
|
|
20
18
|
declare const Wait: Schema.Union<readonly [Schema.Struct<{
|
|
21
19
|
readonly type: Schema.Literal<"permission">;
|
|
22
20
|
readonly action: Schema.String;
|
|
@@ -24,6 +22,9 @@ declare const Wait: Schema.Union<readonly [Schema.Struct<{
|
|
|
24
22
|
}>, Schema.Struct<{
|
|
25
23
|
readonly type: Schema.Literal<"question">;
|
|
26
24
|
readonly question: Schema.String;
|
|
25
|
+
}>, Schema.Struct<{
|
|
26
|
+
readonly type: Schema.Literal<"form">;
|
|
27
|
+
readonly title: Schema.String;
|
|
27
28
|
}>]>;
|
|
28
29
|
/** One session of the tree panel: what courier_tree shows of it, and what it is doing, in epoch milliseconds. */
|
|
29
30
|
declare const Row: Schema.Struct<{
|
|
@@ -32,10 +33,12 @@ declare const Row: Schema.Struct<{
|
|
|
32
33
|
readonly title: Schema.String;
|
|
33
34
|
/** A child of the panel's session is at depth 1. */
|
|
34
35
|
readonly depth: Schema.Int;
|
|
35
|
-
/** `waiting` on a request to the person; `gone` when OpenCode no longer knows it. */
|
|
36
|
+
/** `waiting` on a request to the person or a form it shows them; `gone` when OpenCode no longer knows it. */
|
|
36
37
|
readonly state: Schema.Literals<readonly ["running", "waiting", "idle", "gone"]>;
|
|
37
38
|
/** How its last turn ended. */
|
|
38
39
|
readonly outcome: Schema.optionalKey<Schema.Literals<readonly ["succeeded", "failed", "interrupted"]>>;
|
|
40
|
+
/** Set when courier_stop stopped it since its last prompt. */
|
|
41
|
+
readonly stopped: Schema.optionalKey<Schema.Boolean>;
|
|
39
42
|
/** Its report since its last prompt: still owed, arrived (held with its group or delivered), or its turn ended without one. */
|
|
40
43
|
readonly report: Schema.optionalKey<Schema.Struct<{
|
|
41
44
|
readonly state: Schema.Literals<readonly ["owed", "reported", "ended"]>;
|
|
@@ -65,9 +68,12 @@ declare const Row: Schema.Struct<{
|
|
|
65
68
|
}>, Schema.Struct<{
|
|
66
69
|
readonly type: Schema.Literal<"question">;
|
|
67
70
|
readonly question: Schema.String;
|
|
71
|
+
}>, Schema.Struct<{
|
|
72
|
+
readonly type: Schema.Literal<"form">;
|
|
73
|
+
readonly title: Schema.String;
|
|
68
74
|
}>]>>;
|
|
69
75
|
}>;
|
|
70
|
-
/** The sessions under a session, as courier_tree
|
|
76
|
+
/** The sessions under a session, as courier_tree lists them, in the order a tree is drawn. */
|
|
71
77
|
declare const Tree: Schema.Struct<{
|
|
72
78
|
readonly rows: Schema.$Array<Schema.Struct<{
|
|
73
79
|
readonly sessionID: Schema.String;
|
|
@@ -75,10 +81,12 @@ declare const Tree: Schema.Struct<{
|
|
|
75
81
|
readonly title: Schema.String;
|
|
76
82
|
/** A child of the panel's session is at depth 1. */
|
|
77
83
|
readonly depth: Schema.Int;
|
|
78
|
-
/** `waiting` on a request to the person; `gone` when OpenCode no longer knows it. */
|
|
84
|
+
/** `waiting` on a request to the person or a form it shows them; `gone` when OpenCode no longer knows it. */
|
|
79
85
|
readonly state: Schema.Literals<readonly ["running", "waiting", "idle", "gone"]>;
|
|
80
86
|
/** How its last turn ended. */
|
|
81
87
|
readonly outcome: Schema.optionalKey<Schema.Literals<readonly ["succeeded", "failed", "interrupted"]>>;
|
|
88
|
+
/** Set when courier_stop stopped it since its last prompt. */
|
|
89
|
+
readonly stopped: Schema.optionalKey<Schema.Boolean>;
|
|
82
90
|
/** Its report since its last prompt: still owed, arrived (held with its group or delivered), or its turn ended without one. */
|
|
83
91
|
readonly report: Schema.optionalKey<Schema.Struct<{
|
|
84
92
|
readonly state: Schema.Literals<readonly ["owed", "reported", "ended"]>;
|
|
@@ -108,9 +116,12 @@ declare const Tree: Schema.Struct<{
|
|
|
108
116
|
}>, Schema.Struct<{
|
|
109
117
|
readonly type: Schema.Literal<"question">;
|
|
110
118
|
readonly question: Schema.String;
|
|
119
|
+
}>, Schema.Struct<{
|
|
120
|
+
readonly type: Schema.Literal<"form">;
|
|
121
|
+
readonly title: Schema.String;
|
|
111
122
|
}>]>>;
|
|
112
123
|
}>>;
|
|
113
|
-
/**
|
|
124
|
+
/** How many older sessions the listing left out, when it had more than `maxTotal`: the live ones come first, then the newest. */
|
|
114
125
|
readonly truncated: Schema.optionalKey<Schema.Int>;
|
|
115
126
|
}>;
|
|
116
127
|
export type Row = typeof Row.Type;
|
|
@@ -127,6 +138,14 @@ declare const Stopped: Schema.Struct<{
|
|
|
127
138
|
readonly cancelled: Schema.Int;
|
|
128
139
|
}>;
|
|
129
140
|
export type Stopped = typeof Stopped.Type;
|
|
141
|
+
/** What courier_cleanup did: forgot it, removed its worktree, found that already gone, or kept the worktree, saying why. */
|
|
142
|
+
declare const Forgotten: Schema.Union<readonly [Schema.Struct<{
|
|
143
|
+
readonly outcome: Schema.Literals<readonly ["forgotten", "removed", "gone"]>;
|
|
144
|
+
}>, Schema.Struct<{
|
|
145
|
+
readonly outcome: Schema.Literal<"kept">;
|
|
146
|
+
readonly reason: Schema.String;
|
|
147
|
+
}>]>;
|
|
148
|
+
export type Forgotten = typeof Forgotten.Type;
|
|
130
149
|
export declare const treeRpc: {
|
|
131
150
|
readonly id: "courier";
|
|
132
151
|
readonly methods: {
|
|
@@ -140,28 +159,26 @@ export declare const treeRpc: {
|
|
|
140
159
|
}>;
|
|
141
160
|
readonly output: import("effect/StandardSchema").StandardSchemaV1<{
|
|
142
161
|
readonly running: number;
|
|
162
|
+
readonly waiting: number;
|
|
143
163
|
readonly idle: number;
|
|
144
164
|
readonly groups: readonly {
|
|
145
165
|
readonly name: string;
|
|
146
166
|
readonly reported: number;
|
|
147
167
|
readonly members: number;
|
|
148
168
|
}[];
|
|
149
|
-
readonly waiting: number;
|
|
150
|
-
readonly truncated?: number | undefined;
|
|
151
169
|
}, {
|
|
152
170
|
readonly running: number;
|
|
171
|
+
readonly waiting: number;
|
|
153
172
|
readonly idle: number;
|
|
154
173
|
readonly groups: readonly {
|
|
155
174
|
readonly name: string;
|
|
156
175
|
readonly reported: number;
|
|
157
176
|
readonly members: number;
|
|
158
177
|
}[];
|
|
159
|
-
readonly waiting: number;
|
|
160
|
-
readonly truncated?: number | undefined;
|
|
161
178
|
}> & Schema.Struct<{
|
|
162
|
-
/** Running, and waiting on no request. */
|
|
179
|
+
/** Running, and waiting on no request or form. */
|
|
163
180
|
readonly running: Schema.Int;
|
|
164
|
-
/** Waiting on a permission request or a
|
|
181
|
+
/** Waiting on a permission request, a question or a form it shows, which go to the person. */
|
|
165
182
|
readonly waiting: Schema.Int;
|
|
166
183
|
/** Not running: done, or waiting for a message. */
|
|
167
184
|
readonly idle: Schema.Int;
|
|
@@ -170,8 +187,6 @@ export declare const treeRpc: {
|
|
|
170
187
|
readonly reported: Schema.Int;
|
|
171
188
|
readonly members: Schema.Int;
|
|
172
189
|
}>>;
|
|
173
|
-
/** Set when the subtree had more sessions than `maxTotal`, which were not counted. */
|
|
174
|
-
readonly truncated: Schema.optionalKey<Schema.Int>;
|
|
175
190
|
}>;
|
|
176
191
|
};
|
|
177
192
|
readonly tree: {
|
|
@@ -198,11 +213,15 @@ export declare const treeRpc: {
|
|
|
198
213
|
} | {
|
|
199
214
|
readonly type: "question";
|
|
200
215
|
readonly question: string;
|
|
216
|
+
} | {
|
|
217
|
+
readonly type: "form";
|
|
218
|
+
readonly title: string;
|
|
201
219
|
})[];
|
|
202
220
|
readonly group?: {
|
|
203
221
|
readonly name: string;
|
|
204
222
|
readonly standing: string;
|
|
205
223
|
} | undefined;
|
|
224
|
+
readonly stopped?: boolean | undefined;
|
|
206
225
|
readonly idle?: number | undefined;
|
|
207
226
|
readonly report?: {
|
|
208
227
|
readonly progressed: boolean;
|
|
@@ -233,11 +252,15 @@ export declare const treeRpc: {
|
|
|
233
252
|
} | {
|
|
234
253
|
readonly type: "question";
|
|
235
254
|
readonly question: string;
|
|
255
|
+
} | {
|
|
256
|
+
readonly type: "form";
|
|
257
|
+
readonly title: string;
|
|
236
258
|
})[];
|
|
237
259
|
readonly group?: {
|
|
238
260
|
readonly name: string;
|
|
239
261
|
readonly standing: string;
|
|
240
262
|
} | undefined;
|
|
263
|
+
readonly stopped?: boolean | undefined;
|
|
241
264
|
readonly idle?: number | undefined;
|
|
242
265
|
readonly report?: {
|
|
243
266
|
readonly progressed: boolean;
|
|
@@ -259,10 +282,12 @@ export declare const treeRpc: {
|
|
|
259
282
|
readonly title: Schema.String;
|
|
260
283
|
/** A child of the panel's session is at depth 1. */
|
|
261
284
|
readonly depth: Schema.Int;
|
|
262
|
-
/** `waiting` on a request to the person; `gone` when OpenCode no longer knows it. */
|
|
285
|
+
/** `waiting` on a request to the person or a form it shows them; `gone` when OpenCode no longer knows it. */
|
|
263
286
|
readonly state: Schema.Literals<readonly ["running", "waiting", "idle", "gone"]>;
|
|
264
287
|
/** How its last turn ended. */
|
|
265
288
|
readonly outcome: Schema.optionalKey<Schema.Literals<readonly ["succeeded", "failed", "interrupted"]>>;
|
|
289
|
+
/** Set when courier_stop stopped it since its last prompt. */
|
|
290
|
+
readonly stopped: Schema.optionalKey<Schema.Boolean>;
|
|
266
291
|
/** Its report since its last prompt: still owed, arrived (held with its group or delivered), or its turn ended without one. */
|
|
267
292
|
readonly report: Schema.optionalKey<Schema.Struct<{
|
|
268
293
|
readonly state: Schema.Literals<readonly ["owed", "reported", "ended"]>;
|
|
@@ -292,9 +317,12 @@ export declare const treeRpc: {
|
|
|
292
317
|
}>, Schema.Struct<{
|
|
293
318
|
readonly type: Schema.Literal<"question">;
|
|
294
319
|
readonly question: Schema.String;
|
|
320
|
+
}>, Schema.Struct<{
|
|
321
|
+
readonly type: Schema.Literal<"form">;
|
|
322
|
+
readonly title: Schema.String;
|
|
295
323
|
}>]>>;
|
|
296
324
|
}>>;
|
|
297
|
-
/**
|
|
325
|
+
/** How many older sessions the listing left out, when it had more than `maxTotal`: the live ones come first, then the newest. */
|
|
298
326
|
readonly truncated: Schema.optionalKey<Schema.Int>;
|
|
299
327
|
}>;
|
|
300
328
|
};
|
|
@@ -337,6 +365,38 @@ export declare const treeRpc: {
|
|
|
337
365
|
readonly refused: import("effect/StandardSchema").StandardSchemaV1<{}, {}> & Schema.Struct<{}>;
|
|
338
366
|
};
|
|
339
367
|
};
|
|
368
|
+
/** Forgets `sessionID` as courier_cleanup called from its parent, without `force`; `by` must be above it. */
|
|
369
|
+
readonly cleanup: {
|
|
370
|
+
readonly input: import("effect/StandardSchema").StandardSchemaV1<{
|
|
371
|
+
readonly sessionID: string;
|
|
372
|
+
readonly by: string;
|
|
373
|
+
}, {
|
|
374
|
+
readonly sessionID: string;
|
|
375
|
+
readonly by: string;
|
|
376
|
+
}> & Schema.Struct<{
|
|
377
|
+
readonly sessionID: Schema.String;
|
|
378
|
+
readonly by: Schema.String;
|
|
379
|
+
}>;
|
|
380
|
+
readonly output: import("effect/StandardSchema").StandardSchemaV1<{
|
|
381
|
+
readonly outcome: "removed" | "gone" | "forgotten";
|
|
382
|
+
} | {
|
|
383
|
+
readonly outcome: "kept";
|
|
384
|
+
readonly reason: string;
|
|
385
|
+
}, {
|
|
386
|
+
readonly outcome: "removed" | "gone" | "forgotten";
|
|
387
|
+
} | {
|
|
388
|
+
readonly outcome: "kept";
|
|
389
|
+
readonly reason: string;
|
|
390
|
+
}> & Schema.Union<readonly [Schema.Struct<{
|
|
391
|
+
readonly outcome: Schema.Literals<readonly ["forgotten", "removed", "gone"]>;
|
|
392
|
+
}>, Schema.Struct<{
|
|
393
|
+
readonly outcome: Schema.Literal<"kept">;
|
|
394
|
+
readonly reason: Schema.String;
|
|
395
|
+
}>]>;
|
|
396
|
+
readonly errors: {
|
|
397
|
+
readonly refused: import("effect/StandardSchema").StandardSchemaV1<{}, {}> & Schema.Struct<{}>;
|
|
398
|
+
};
|
|
399
|
+
};
|
|
340
400
|
};
|
|
341
401
|
readonly events: {};
|
|
342
402
|
};
|
package/dist/tree/rpc.js
CHANGED
|
@@ -9,20 +9,19 @@ const Count = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
|
|
|
9
9
|
const Group = Schema.Struct({ name: Schema.String, reported: Count, members: Count });
|
|
10
10
|
/** The sessions started under a session, as the prompt footer's status entry shows them. */
|
|
11
11
|
const Summary = Schema.Struct({
|
|
12
|
-
/** Running, and waiting on no request. */
|
|
12
|
+
/** Running, and waiting on no request or form. */
|
|
13
13
|
running: Count,
|
|
14
|
-
/** Waiting on a permission request or a
|
|
14
|
+
/** Waiting on a permission request, a question or a form it shows, which go to the person. */
|
|
15
15
|
waiting: Count,
|
|
16
16
|
/** Not running: done, or waiting for a message. */
|
|
17
17
|
idle: Count,
|
|
18
18
|
groups: Schema.Array(Group),
|
|
19
|
-
/** Set when the subtree had more sessions than `maxTotal`, which were not counted. */
|
|
20
|
-
truncated: Schema.optionalKey(Count),
|
|
21
19
|
});
|
|
22
|
-
/** A request a session waits on until the person answers it: a permission request,
|
|
20
|
+
/** A request a session waits on until the person answers it: a permission request, its first question, or a form it shows. */
|
|
23
21
|
const Wait = Schema.Union([
|
|
24
22
|
Schema.Struct({ type: Schema.Literal("permission"), action: Schema.String, resources: Schema.Array(Schema.String) }),
|
|
25
23
|
Schema.Struct({ type: Schema.Literal("question"), question: Schema.String }),
|
|
24
|
+
Schema.Struct({ type: Schema.Literal("form"), title: Schema.String }),
|
|
26
25
|
]);
|
|
27
26
|
/** One session of the tree panel: what courier_tree shows of it, and what it is doing, in epoch milliseconds. */
|
|
28
27
|
const Row = Schema.Struct({
|
|
@@ -31,10 +30,12 @@ const Row = Schema.Struct({
|
|
|
31
30
|
title: Schema.String,
|
|
32
31
|
/** A child of the panel's session is at depth 1. */
|
|
33
32
|
depth: Count,
|
|
34
|
-
/** `waiting` on a request to the person; `gone` when OpenCode no longer knows it. */
|
|
33
|
+
/** `waiting` on a request to the person or a form it shows them; `gone` when OpenCode no longer knows it. */
|
|
35
34
|
state: Schema.Literals(["running", "waiting", "idle", "gone"]),
|
|
36
35
|
/** How its last turn ended. */
|
|
37
36
|
outcome: Schema.optionalKey(Schema.Literals(["succeeded", "failed", "interrupted"])),
|
|
37
|
+
/** Set when courier_stop stopped it since its last prompt. */
|
|
38
|
+
stopped: Schema.optionalKey(Schema.Boolean),
|
|
38
39
|
/** Its report since its last prompt: still owed, arrived (held with its group or delivered), or its turn ended without one. */
|
|
39
40
|
report: Schema.optionalKey(Schema.Struct({ state: Schema.Literals(["owed", "reported", "ended"]), status: Schema.optionalKey(Schema.String), progressed: Schema.Boolean })),
|
|
40
41
|
/** Its join group, and its standing there: `held`, `out`, how it left, or `released`. */
|
|
@@ -49,10 +50,10 @@ const Row = Schema.Struct({
|
|
|
49
50
|
tool: Schema.optionalKey(Schema.Struct({ name: Schema.String, at: Schema.Number })),
|
|
50
51
|
waits: Schema.Array(Wait),
|
|
51
52
|
});
|
|
52
|
-
/** The sessions under a session, as courier_tree
|
|
53
|
+
/** The sessions under a session, as courier_tree lists them, in the order a tree is drawn. */
|
|
53
54
|
const Tree = Schema.Struct({
|
|
54
55
|
rows: Schema.Array(Row),
|
|
55
|
-
/**
|
|
56
|
+
/** How many older sessions the listing left out, when it had more than `maxTotal`: the live ones come first, then the newest. */
|
|
56
57
|
truncated: Schema.optionalKey(Count),
|
|
57
58
|
});
|
|
58
59
|
/** What a stop did to each session, deepest first, as courier_stop reports it. */
|
|
@@ -61,6 +62,11 @@ const Stopped = Schema.Struct({
|
|
|
61
62
|
/** How many scheduled messages were cancelled. */
|
|
62
63
|
cancelled: Count,
|
|
63
64
|
});
|
|
65
|
+
/** What courier_cleanup did: forgot it, removed its worktree, found that already gone, or kept the worktree, saying why. */
|
|
66
|
+
const Forgotten = Schema.Union([
|
|
67
|
+
Schema.Struct({ outcome: Schema.Literals(["forgotten", "removed", "gone"]) }),
|
|
68
|
+
Schema.Struct({ outcome: Schema.Literal("kept"), reason: Schema.String }),
|
|
69
|
+
]);
|
|
64
70
|
export const treeRpc = Rpc.define({
|
|
65
71
|
id: "courier",
|
|
66
72
|
methods: {
|
|
@@ -78,6 +84,12 @@ export const treeRpc = Rpc.define({
|
|
|
78
84
|
output: Schema.toStandardSchemaV1(Stopped),
|
|
79
85
|
errors: { refused: Schema.toStandardSchemaV1(Schema.Struct({})) },
|
|
80
86
|
},
|
|
87
|
+
/** Forgets `sessionID` as courier_cleanup called from its parent, without `force`; `by` must be above it. */
|
|
88
|
+
cleanup: {
|
|
89
|
+
input: Schema.toStandardSchemaV1(Schema.Struct({ sessionID: Schema.String, by: Schema.String })),
|
|
90
|
+
output: Schema.toStandardSchemaV1(Forgotten),
|
|
91
|
+
errors: { refused: Schema.toStandardSchemaV1(Schema.Struct({})) },
|
|
92
|
+
},
|
|
81
93
|
},
|
|
82
94
|
events: {},
|
|
83
95
|
});
|