opencode-courier 0.13.8 → 0.14.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 +7 -9
- package/dist/index.d.ts +0 -8
- package/dist/index.js +6 -53
- package/dist/kernel/protocol.d.ts +0 -14
- package/dist/kernel/protocol.js +1 -15
- package/dist/kernel/tool.d.ts +0 -2
- package/dist/kernel/tool.js +0 -1
- package/dist/memory/domain.d.ts +6 -85
- package/dist/memory/domain.js +7 -63
- package/dist/memory/events.d.ts +0 -11
- package/dist/memory/events.js +1 -12
- package/dist/memory/forget.d.ts +0 -5
- package/dist/memory/forget.js +0 -4
- package/dist/memory/index.js +0 -2
- package/dist/memory/lessons.d.ts +0 -8
- package/dist/memory/lessons.js +0 -9
- package/dist/memory/note.d.ts +0 -9
- package/dist/memory/note.js +0 -5
- package/dist/memory/pin.d.ts +0 -5
- package/dist/memory/pin.js +0 -4
- package/dist/memory/ports.d.ts +2 -22
- package/dist/memory/recall.d.ts +0 -5
- package/dist/memory/recall.js +0 -12
- package/dist/memory/record.d.ts +0 -4
- package/dist/memory/record.js +8 -31
- package/dist/memory/rpc-handlers.d.ts +3 -6
- package/dist/memory/rpc-handlers.js +0 -6
- package/dist/memory/rpc.d.ts +6 -19
- package/dist/memory/rpc.js +1 -16
- package/dist/memory/store.d.ts +0 -5
- package/dist/memory/store.js +1 -16
- package/dist/memory/sweep.d.ts +0 -4
- package/dist/memory/sweep.js +0 -4
- package/dist/memory/text.d.ts +0 -25
- package/dist/memory/text.js +6 -36
- package/dist/memory/tools.d.ts +0 -2
- package/dist/memory/tools.js +0 -2
- package/dist/memory/tui.d.ts +1 -35
- package/dist/person/events.d.ts +0 -16
- package/dist/person/events.js +3 -30
- package/dist/person/form.d.ts +0 -9
- package/dist/person/form.js +0 -10
- package/dist/person/index.d.ts +0 -2
- package/dist/person/permission.d.ts +0 -34
- package/dist/person/permission.js +2 -28
- package/dist/person/ports.d.ts +0 -16
- package/dist/person/ports.js +0 -1
- package/dist/person/question/answer.d.ts +0 -28
- package/dist/person/question/answer.js +0 -49
- package/dist/person/question/index.js +0 -2
- package/dist/person/question/lifecycle.d.ts +0 -26
- package/dist/person/question/lifecycle.js +1 -32
- package/dist/person/question/pure.d.ts +0 -11
- package/dist/person/question/pure.js +0 -11
- package/dist/person/question/relay.d.ts +0 -1
- package/dist/person/question/relay.js +5 -67
- package/dist/person/question/runtime.d.ts +0 -14
- package/dist/person/question/runtime.js +1 -26
- package/dist/person/question/shared.d.ts +0 -17
- package/dist/person/question/shared.js +0 -20
- package/dist/person/question/types.d.ts +0 -44
- package/dist/person/rpc-handlers.d.ts +0 -7
- package/dist/person/rpc-handlers.js +0 -6
- package/dist/person/rpc.d.ts +0 -20
- package/dist/person/rpc.js +0 -16
- package/dist/person/text.d.ts +0 -45
- package/dist/person/text.js +2 -54
- package/dist/person/tools.d.ts +0 -3
- package/dist/person/tools.js +1 -3
- package/dist/person/tui.d.ts +0 -21
- package/dist/platform/bounded.d.ts +0 -8
- package/dist/platform/bounded.js +0 -8
- package/dist/platform/events.d.ts +0 -18
- package/dist/platform/events.js +3 -22
- package/dist/platform/hub.d.ts +0 -113
- package/dist/platform/hub.js +1 -76
- package/dist/platform/json.d.ts +0 -3
- package/dist/platform/json.js +1 -3
- package/dist/platform/storage.d.ts +0 -7
- package/dist/platform/storage.js +0 -6
- package/dist/platform/version.d.ts +0 -9
- package/dist/platform/version.js +0 -8
- package/dist/rpc.js +0 -1
- package/dist/scheduling/index.d.ts +0 -1
- package/dist/scheduling/index.js +0 -1
- package/dist/scheduling/later.d.ts +0 -11
- package/dist/scheduling/later.js +0 -14
- package/dist/scheduling/text.d.ts +0 -1
- package/dist/scheduling/text.js +0 -1
- package/dist/scheduling/tools.d.ts +0 -1
- package/dist/scheduling/tools.js +1 -5
- package/dist/skill.d.ts +1 -9
- package/dist/skill.js +4 -12
- package/dist/tree/cleanup.d.ts +0 -20
- package/dist/tree/cleanup.js +0 -26
- package/dist/tree/context.d.ts +0 -5
- package/dist/tree/context.js +0 -8
- package/dist/tree/domain.d.ts +0 -64
- package/dist/tree/domain.js +7 -45
- package/dist/tree/events.d.ts +0 -36
- package/dist/tree/events.js +4 -49
- package/dist/tree/forget.d.ts +0 -15
- package/dist/tree/forget.js +0 -18
- package/dist/tree/group.d.ts +0 -22
- package/dist/tree/group.js +1 -37
- package/dist/tree/index.d.ts +2 -2
- package/dist/tree/index.js +1 -3
- package/dist/tree/limits.d.ts +0 -4
- package/dist/tree/limits.js +1 -12
- package/dist/tree/mascot.d.ts +0 -25
- package/dist/tree/mascot.js +1 -32
- package/dist/tree/model.d.ts +0 -5
- package/dist/tree/model.js +2 -15
- package/dist/tree/nudge.d.ts +0 -11
- package/dist/tree/nudge.js +3 -16
- package/dist/tree/panel.d.ts +0 -8
- package/dist/tree/panel.js +3 -16
- package/dist/tree/ports.d.ts +2 -138
- package/dist/tree/report.d.ts +0 -10
- package/dist/tree/report.js +0 -11
- package/dist/tree/roster.d.ts +0 -21
- package/dist/tree/roster.js +0 -21
- package/dist/tree/rpc-handlers.d.ts +6 -1
- package/dist/tree/rpc-handlers.js +0 -5
- package/dist/tree/rpc.d.ts +9 -109
- package/dist/tree/rpc.js +2 -38
- package/dist/tree/running.d.ts +0 -6
- package/dist/tree/running.js +2 -10
- package/dist/tree/send.d.ts +0 -4
- package/dist/tree/send.js +4 -31
- package/dist/tree/spawn.d.ts +0 -7
- package/dist/tree/spawn.js +6 -47
- package/dist/tree/standing.d.ts +0 -8
- package/dist/tree/standing.js +1 -11
- package/dist/tree/status.d.ts +0 -8
- package/dist/tree/status.js +1 -9
- package/dist/tree/stop.d.ts +2 -9
- package/dist/tree/stop.js +58 -25
- package/dist/tree/store.d.ts +0 -8
- package/dist/tree/store.js +4 -38
- package/dist/tree/subtree.d.ts +8 -26
- package/dist/tree/subtree.js +37 -35
- package/dist/tree/summary.d.ts +0 -4
- package/dist/tree/summary.js +0 -8
- package/dist/tree/text.d.ts +1 -44
- package/dist/tree/text.js +5 -65
- package/dist/tree/tools.d.ts +0 -6
- package/dist/tree/tools.js +4 -8
- package/dist/tree/tui.d.ts +0 -81
- package/dist/tree/wake.d.ts +0 -30
- package/dist/tree/wake.js +5 -39
- package/dist/tui.js +22 -8
- package/package.json +8 -9
- package/dist/webhook/index.d.ts +0 -5
- package/dist/webhook/index.js +0 -3
- package/dist/webhook/receiver.d.ts +0 -80
- package/dist/webhook/receiver.js +0 -339
- package/dist/webhook/subscriptions.d.ts +0 -29
- package/dist/webhook/subscriptions.js +0 -52
- package/dist/webhook/text.d.ts +0 -23
- package/dist/webhook/text.js +0 -82
- package/dist/webhook/tools.d.ts +0 -19
- package/dist/webhook/tools.js +0 -46
package/dist/tree/ports.d.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The tree's ports, what it needs of the plugin context and of other modules, and the data types they and
|
|
3
|
-
* its texts take; those its pure rules take are declared in `domain.ts` and re-exported here.
|
|
4
|
-
*/
|
|
5
1
|
import type { Plugin } from "@opencode/plugin";
|
|
6
2
|
import type { Status } from "../kernel/protocol.js";
|
|
7
3
|
import type { Storage } from "../platform/storage.js";
|
|
@@ -9,236 +5,142 @@ import type { Limits, Member, ModelRef, RosterEntry } from "./domain.js";
|
|
|
9
5
|
export type { Artifacts, HeldReport, LeftMember, Limits, Member, ModelRef, RosterEntry, Standing } from "./domain.js";
|
|
10
6
|
type Context = Plugin.Context;
|
|
11
7
|
export type RosterStorage = Storage;
|
|
12
|
-
/** How a session's wait for a report ended: it reported to its parent, or its turn failed or was interrupted. */
|
|
13
8
|
export type Settled = "report" | "failed" | "interrupted";
|
|
14
|
-
/** The notes kept of a spawned session's report state; docs/maintainers/architecture.md has each. */
|
|
15
9
|
export type ReportField = "prompt" | "settled" | "progress" | "told" | "stopped" | "nudged";
|
|
16
|
-
/** A report note as read: when it was made, and for `settled` how the wait ended, the report's status or a failure's `resumesAt`, as stored. */
|
|
17
10
|
export interface ReportNote {
|
|
18
11
|
readonly at: number | undefined;
|
|
19
12
|
readonly by: unknown;
|
|
20
13
|
readonly status: unknown;
|
|
21
14
|
readonly resumesAt: unknown;
|
|
22
15
|
}
|
|
23
|
-
/** A stored value, as `Storage` gives and takes it. */
|
|
24
16
|
export type Stored = Parameters<Storage["set"]>[1];
|
|
25
|
-
/** The report keys found, by the session they are about. */
|
|
26
17
|
export type ReportKeys = ReadonlyMap<string, ReadonlyArray<string>>;
|
|
27
|
-
/**
|
|
28
|
-
* A spawned session as kept: its roster entry under its parent, the reverse index that finds it, and its report
|
|
29
|
-
* state, which go together. The reverse index is only an index: a session it does not name is looked for in the roster.
|
|
30
|
-
*/
|
|
31
18
|
export interface ChildStore {
|
|
32
|
-
/** Records a child under its parent, then indexes it; a failed index write is left to a scan and the next load. */
|
|
33
19
|
record(entry: RosterEntry): Promise<void>;
|
|
34
|
-
/** Removes a child's entry and, at once and best effort, its reverse key and report state; only the entry's removal can fail it. */
|
|
35
20
|
remove(parentID: string, sessionID: string): Promise<void>;
|
|
36
|
-
/** A session's roster entry under a parent, if it is there. */
|
|
37
21
|
entry(parentID: string, sessionID: string): Promise<RosterEntry | undefined>;
|
|
38
|
-
/** A parent's children, oldest first. */
|
|
39
22
|
children(parentID: string): Promise<RosterEntry[]>;
|
|
40
|
-
/** Every parent's children. */
|
|
41
23
|
all(): Promise<RosterEntry[]>;
|
|
42
|
-
/** A session's roster entries: one for the parent that started it, none if courier_spawn did not. */
|
|
43
24
|
entriesOf(sessionID: string): Promise<RosterEntry[]>;
|
|
44
|
-
/** The session that started a session, by the reverse index alone, without scanning the roster. */
|
|
45
25
|
indexedParent(sessionID: string): Promise<string | undefined>;
|
|
46
|
-
/** The sessions above a session, its parent first, by the reverse index alone: empty when it does not name the session. */
|
|
47
26
|
indexedAncestors(sessionID: string): Promise<ReadonlyArray<string>>;
|
|
48
|
-
/** A session's roster entry, by the reverse index alone, without scanning the roster. */
|
|
49
27
|
indexedEntry(sessionID: string): Promise<RosterEntry | undefined>;
|
|
50
|
-
/**
|
|
51
|
-
* The roster entries from a session up to the top, its own first, ending with the entry whose parent
|
|
52
|
-
* courier_spawn did not start; empty when courier_spawn did not start the session.
|
|
53
|
-
*/
|
|
54
28
|
lineage(sessionID: string): Promise<RosterEntry[]>;
|
|
55
|
-
/** `lineage` by the reverse index alone: empty, without scanning the roster, when it does not name the session. */
|
|
56
29
|
indexedLineage(sessionID: string): Promise<RosterEntry[]>;
|
|
57
|
-
/** Writes the reverse keys missing or stale for the given entries, the whole roster, and drops those whose entry is gone. */
|
|
58
30
|
backfill(entries: ReadonlyArray<RosterEntry>): Promise<void>;
|
|
59
|
-
/** The given notes of a session's report state, read at once. */
|
|
60
31
|
notes<F extends ReportField>(sessionID: string, fields: ReadonlyArray<F>): Promise<{
|
|
61
32
|
readonly [K in F]: ReportNote;
|
|
62
33
|
}>;
|
|
63
|
-
/** Notes that a prompt or message reached a spawned session at `at`, unless a later one is noted. */
|
|
64
34
|
prompted(sessionID: string, at: number): Promise<void>;
|
|
65
|
-
/**
|
|
66
|
-
* Notes how a spawned session's wait for a report ended at `at`, with its report's status or, for a failed turn, when the
|
|
67
|
-
* provider's limit lifts (`resumesAt`), unless a later end is noted.
|
|
68
|
-
*/
|
|
69
35
|
settled(sessionID: string, by: Settled, at: number, status?: Status, resumesAt?: number): Promise<void>;
|
|
70
|
-
/** Notes that a spawned session messaged its parent without a status at `at`, unless a later one is noted. */
|
|
71
36
|
progressed(sessionID: string, at: number): Promise<void>;
|
|
72
|
-
/** Notes that a spawned session's parent was told at `at` that a turn ended without a report, unless a later telling is noted. */
|
|
73
37
|
told(sessionID: string, at: number): Promise<void>;
|
|
74
|
-
/** Takes back the note `told` made at `at`; a later one stays, and one that cannot be read goes. */
|
|
75
38
|
untold(sessionID: string, at: number): Promise<void>;
|
|
76
|
-
/** Notes that courier_stop stopped a spawned session at `at`. */
|
|
77
39
|
stopped(sessionID: string, at: number): Promise<void>;
|
|
78
|
-
/** Notes that a spawned session was reminded at `at` to report, with the reminder's inbox id once it is admitted. */
|
|
79
40
|
nudged(sessionID: string, at: number, inboxID?: string): Promise<void>;
|
|
80
|
-
/** When a spawned session was last reminded to report, and the reminder's inbox id. */
|
|
81
41
|
nudgeOf(sessionID: string): Promise<{
|
|
82
42
|
readonly at: number | undefined;
|
|
83
43
|
readonly inboxID?: string;
|
|
84
44
|
}>;
|
|
85
|
-
/** A `settled` or `progress` note as stored, for `restore` to put back. */
|
|
86
45
|
peek(sessionID: string, field: "settled" | "progress"): Promise<Stored | undefined>;
|
|
87
|
-
/** Puts back a note `peek` read; one that was not there is removed. */
|
|
88
46
|
restore(sessionID: string, field: "settled" | "progress", value: Stored | undefined): Promise<void>;
|
|
89
|
-
/** Drops a session's report state. */
|
|
90
47
|
forgetReport(sessionID: string): Promise<void>;
|
|
91
|
-
/** Every report key, by the session it is about. */
|
|
92
48
|
reported(): Promise<ReportKeys>;
|
|
93
|
-
/** Removes report keys `reported` found, each best effort. */
|
|
94
49
|
dropReported(keys: ReadonlyArray<string>): Promise<void>;
|
|
95
50
|
}
|
|
96
|
-
/**
|
|
97
|
-
* A courier message waiting in a session's inbox, watched until it is delivered: `running` while the session runs a
|
|
98
|
-
* turn, which takes it at its next step; `idleAt` since the session was last seen idle with it waiting.
|
|
99
|
-
*/
|
|
100
51
|
export interface Wake {
|
|
101
52
|
readonly sessionID: string;
|
|
102
53
|
readonly inboxID: string;
|
|
103
|
-
/** When OpenCode enqueued it. */
|
|
104
54
|
readonly at: number;
|
|
105
|
-
/** Its text and description, which waking the session again sends under the same inbox id. */
|
|
106
55
|
readonly text: string;
|
|
107
56
|
readonly description?: string;
|
|
108
57
|
readonly running: boolean;
|
|
109
58
|
readonly idleAt?: number;
|
|
110
|
-
/** When the scheduler woke the session again, the message still waiting. */
|
|
111
59
|
readonly rewoken?: number;
|
|
112
|
-
/** When the session was found still not woken after that: it is stalled. */
|
|
113
60
|
readonly stalled?: number;
|
|
114
61
|
}
|
|
115
62
|
export interface WakeStore {
|
|
116
|
-
/** Writes a watched message, replacing what was kept of it. */
|
|
117
63
|
put(wake: Wake): Promise<void>;
|
|
118
|
-
/** The messages watched in a session's inbox. */
|
|
119
64
|
of(sessionID: string): Promise<Wake[]>;
|
|
120
|
-
/** Every message watched. */
|
|
121
65
|
all(): Promise<Wake[]>;
|
|
122
|
-
/** Stops watching a message: delivered, cancelled, or its session gone. */
|
|
123
66
|
remove(sessionID: string, inboxID: string): Promise<void>;
|
|
124
67
|
}
|
|
125
|
-
/** A member of a join group with where it is kept. */
|
|
126
68
|
export interface Membership extends Member {
|
|
127
69
|
readonly parentID: string;
|
|
128
70
|
readonly group: string;
|
|
129
71
|
readonly sessionID: string;
|
|
130
72
|
}
|
|
131
|
-
/** The members of parents' join groups, each with its held report or how it left; a value that is not a member reads as none. */
|
|
132
73
|
export interface GroupStore {
|
|
133
|
-
/** A session's member in a parent's group, if it is one. */
|
|
134
74
|
member(parentID: string, group: string, sessionID: string): Promise<Member | undefined>;
|
|
135
|
-
/** The members of every group. */
|
|
136
75
|
all(): Promise<Membership[]>;
|
|
137
|
-
/** The members of a parent's groups. */
|
|
138
76
|
ofParent(parentID: string): Promise<Membership[]>;
|
|
139
|
-
/** The members of one group. */
|
|
140
77
|
ofGroup(parentID: string, group: string): Promise<Membership[]>;
|
|
141
|
-
/** Writes a member in place of what was kept for it. */
|
|
142
78
|
put(parentID: string, group: string, sessionID: string, member: Member): Promise<void>;
|
|
143
|
-
/** Removes a member whatever it holds. */
|
|
144
79
|
remove(parentID: string, group: string, sessionID: string): Promise<void>;
|
|
145
80
|
}
|
|
146
|
-
/** A report held with its group: which group, and how many of its members have reported so far, when that could be read. */
|
|
147
81
|
export interface Held {
|
|
148
82
|
readonly group: string;
|
|
149
83
|
readonly reported?: number;
|
|
150
84
|
readonly members?: number;
|
|
151
85
|
}
|
|
152
|
-
/**
|
|
153
|
-
* What courier_send did; `report` says whether the message was noted as the sender's report to the session
|
|
154
|
-
* that started it, and `held` that it was held with the sender's group rather than delivered, with no `messageID`.
|
|
155
|
-
*/
|
|
156
86
|
export interface Sent {
|
|
157
87
|
readonly messageID?: string;
|
|
158
88
|
readonly status?: Status;
|
|
159
89
|
readonly report?: boolean;
|
|
160
90
|
readonly held?: Held;
|
|
161
|
-
/** The status it was sent with to a session below the sender, where a status means nothing. */
|
|
162
91
|
readonly dropped?: Status;
|
|
163
92
|
}
|
|
164
|
-
/**
|
|
165
|
-
* What the `context` hook remembers of a session: its depth, null for one nobody spawned that has started none, and
|
|
166
|
-
* whether it carries the role entry (`ROLE_KEY`), which then names its role in place of the hook's system part.
|
|
167
|
-
*/
|
|
168
93
|
export interface Role {
|
|
169
94
|
readonly depth: number | null;
|
|
170
95
|
readonly entry: boolean;
|
|
171
96
|
}
|
|
172
|
-
/** The keyed session entries, missing on a host before 2.2.0 (every copy's ports carry the host's `session`): an entry is then skipped. */
|
|
173
97
|
export type Instructions = Partial<Pick<Context["session"], "instructions">>;
|
|
174
|
-
|
|
98
|
+
export type Lister = Partial<Pick<Context["session"], "list">>;
|
|
175
99
|
export interface Entry {
|
|
176
100
|
readonly key: string;
|
|
177
101
|
readonly value: string;
|
|
178
102
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Supplies the entries other modules write to a spawned session below `maxDepth` before its prompt, and to a root at its
|
|
181
|
-
* first spawn beside its role; `src/index.ts` composes it from the modules' suppliers, as it does the `Waits` port.
|
|
182
|
-
*/
|
|
183
103
|
export type Entries = () => Promise<ReadonlyArray<Entry>>;
|
|
184
|
-
/** What writing a parent's `standing` entry needs: the tools', the watcher's and the scheduler's ports all have these. */
|
|
185
104
|
export interface StandingPorts {
|
|
186
105
|
readonly storage: RosterStorage;
|
|
187
106
|
readonly now: () => number;
|
|
188
107
|
readonly session?: Instructions;
|
|
189
108
|
readonly log?: (message: string) => void;
|
|
190
109
|
}
|
|
191
|
-
/** The slice of the plugin context the courier tools use; tests pass a fake. */
|
|
192
110
|
export interface CourierPorts {
|
|
193
|
-
|
|
194
|
-
readonly session: Pick<Context["session"], "create" | "prompt" | "synthetic" | "get" | "context" | "interrupt"> & Instructions;
|
|
195
|
-
/** The entries of other modules a spawned session gets before its prompt, the memory's lessons; none when not given. */
|
|
111
|
+
readonly session: Pick<Context["session"], "create" | "prompt" | "synthetic" | "get" | "context" | "interrupt"> & Instructions & Lister;
|
|
196
112
|
readonly entries?: Entries;
|
|
197
113
|
readonly agent: Pick<Context["agent"], "get">;
|
|
198
114
|
readonly worktree: Pick<Context["worktree"], "create" | "remove">;
|
|
199
|
-
/** The project of the plugin's location; an isolated child's worktree is made in it, and removed from it. */
|
|
200
115
|
readonly projectID: string;
|
|
201
|
-
/** The commit a directory's checkout is on, or undefined; recorded as an isolated child's base. */
|
|
202
116
|
readonly head: (directory: string) => Promise<string | undefined>;
|
|
203
|
-
/** Whether a directory's checkout has uncommitted changes, or undefined when git cannot tell. */
|
|
204
117
|
readonly dirty: (directory: string) => Promise<boolean | undefined>;
|
|
205
118
|
readonly storage: RosterStorage;
|
|
206
119
|
readonly directory: string;
|
|
207
120
|
readonly now: () => number;
|
|
208
|
-
/** The permission requests and questions a session waits on, wherever they are pending. */
|
|
209
121
|
readonly pending: (sessionID: string) => Promise<ReadonlyArray<Pending>>;
|
|
210
|
-
/** The forms a session shows, which only the person can answer: web search's, a plugin's; not the question tool's. */
|
|
211
122
|
readonly forms: (sessionID: string) => Promise<ReadonlyArray<ShownForm>>;
|
|
212
|
-
/** The models available, each with its context window and variants, as courier_spawn checks a choice and the panel reads a session's context use. */
|
|
213
123
|
readonly models: () => Promise<ReadonlyArray<KnownModel>>;
|
|
214
|
-
/** OpenCode's default model here, which a session with no model of its own runs on; undefined when there is none. */
|
|
215
124
|
readonly defaultModel: () => Promise<ModelRef | undefined>;
|
|
216
125
|
readonly limits: Limits;
|
|
217
|
-
/** The `nativeChildren` option: a child started without isolate and without `native` is created with OpenCode's own `parentID`. */
|
|
218
126
|
readonly nativeChildren?: boolean;
|
|
219
127
|
readonly gate: SpawnGate;
|
|
220
|
-
/** The roles the `context` hook remembers; a parent's is dropped when it starts a child, a root's kept once its entry is written. */
|
|
221
128
|
readonly roles: Map<string, Role>;
|
|
222
|
-
/** Has the scheduler deliver what is due now rather than at its next tick: a group a report has just completed. */
|
|
223
129
|
readonly nudge: () => void;
|
|
224
130
|
readonly log: (message: string) => void;
|
|
225
131
|
}
|
|
226
|
-
/** A model's context window in tokens, as the panel and the memory read a session's context use by. */
|
|
227
132
|
export interface ModelWindow {
|
|
228
133
|
readonly providerID: string;
|
|
229
134
|
readonly id: string;
|
|
230
135
|
readonly context: number;
|
|
231
136
|
}
|
|
232
|
-
/** A model OpenCode lists, as `CourierPorts.models` gives it: its window, and the ids of its variants. */
|
|
233
137
|
export interface KnownModel extends ModelWindow {
|
|
234
138
|
readonly variants: ReadonlyArray<string>;
|
|
235
139
|
}
|
|
236
|
-
/** A form a session shows, as `CourierPorts.forms` lists it; `person/` keeps them. */
|
|
237
140
|
export interface ShownForm {
|
|
238
141
|
readonly id: string;
|
|
239
142
|
readonly title: string;
|
|
240
143
|
}
|
|
241
|
-
/** One question a session waits on, as `Pending` shows it; `person/`'s `Prompt` has these fields. */
|
|
242
144
|
export interface PendingPrompt {
|
|
243
145
|
readonly question: string;
|
|
244
146
|
readonly header: string;
|
|
@@ -248,7 +150,6 @@ export interface PendingPrompt {
|
|
|
248
150
|
}>;
|
|
249
151
|
readonly multiple?: boolean;
|
|
250
152
|
}
|
|
251
|
-
/** A request a session waits on until someone answers it: a permission request, or a question it asked. */
|
|
252
153
|
export type Pending = {
|
|
253
154
|
readonly type: "permission";
|
|
254
155
|
readonly requestID: string;
|
|
@@ -259,19 +160,13 @@ export type Pending = {
|
|
|
259
160
|
readonly type: "question";
|
|
260
161
|
readonly requestID: string;
|
|
261
162
|
readonly questions: ReadonlyArray<PendingPrompt>;
|
|
262
|
-
/** Its question call was cut off; the answer reaches it as a message. */
|
|
263
163
|
readonly stopped?: true;
|
|
264
164
|
};
|
|
265
|
-
/** A spawn past its limit check: its parent, the top of its tree, and its child once created. */
|
|
266
165
|
export interface Reservation {
|
|
267
166
|
readonly parentID: string;
|
|
268
167
|
readonly top: string;
|
|
269
168
|
sessionID?: string;
|
|
270
169
|
}
|
|
271
|
-
/**
|
|
272
|
-
* The spawns under way in the process, under a fixed process-wide key outside the hub, so spawns in
|
|
273
|
-
* other locations and copies count them; `turn` runs the limit checks one at a time.
|
|
274
|
-
*/
|
|
275
170
|
export interface SpawnGate {
|
|
276
171
|
readonly reserved: Set<Reservation>;
|
|
277
172
|
turn: Promise<unknown>;
|
|
@@ -282,7 +177,6 @@ export interface LimitPorts {
|
|
|
282
177
|
readonly limits: Limits;
|
|
283
178
|
readonly gate: SpawnGate;
|
|
284
179
|
}
|
|
285
|
-
/** What courier_cleanup did: removed the worktree, found it gone, kept it and why, or forgot a child with none; `group`, one it dropped the child from. */
|
|
286
180
|
export type CleanupResult = {
|
|
287
181
|
readonly sessionID: string;
|
|
288
182
|
readonly directory: string;
|
|
@@ -296,34 +190,22 @@ export type CleanupResult = {
|
|
|
296
190
|
readonly changes: readonly string[];
|
|
297
191
|
readonly commits: readonly string[];
|
|
298
192
|
};
|
|
299
|
-
/** What would be lost by removing a worktree. */
|
|
300
193
|
export interface WorktreeState {
|
|
301
|
-
/** Paths with uncommitted changes, untracked files included, as `git status --porcelain` lists them. */
|
|
302
194
|
readonly changes: readonly string[];
|
|
303
|
-
/**
|
|
304
|
-
* Commits reachable from the worktree's HEAD but from no branch, tag or remote-tracking ref, nor
|
|
305
|
-
* from the commit the worktree was made from, newest first.
|
|
306
|
-
*/
|
|
307
195
|
readonly commits: readonly string[];
|
|
308
196
|
}
|
|
309
197
|
export interface CleanupPorts {
|
|
310
198
|
readonly storage: RosterStorage;
|
|
311
199
|
readonly worktree: Pick<Context["worktree"], "remove">;
|
|
312
|
-
/** The project of the plugin's location, for roster entries recorded before they carried their project. */
|
|
313
200
|
readonly projectID: string;
|
|
314
|
-
/** The worktree's state, or undefined when its directory no longer exists; `base` is the commit it was made from. */
|
|
315
201
|
readonly inspect: (directory: string, base?: string) => Promise<WorktreeState | undefined>;
|
|
316
|
-
/** When a member still out is dropped from its group. */
|
|
317
202
|
readonly now: () => number;
|
|
318
|
-
/** Has the scheduler deliver what is due now: a group the forgotten child may have been the last member out of. */
|
|
319
203
|
readonly nudge: () => void;
|
|
320
|
-
/** For the parent's `standing` entry once the child is forgotten; without them it is left as it was. */
|
|
321
204
|
readonly session?: Instructions;
|
|
322
205
|
readonly log?: (message: string) => void;
|
|
323
206
|
}
|
|
324
207
|
export interface StopPorts {
|
|
325
208
|
readonly courier: CourierPorts;
|
|
326
|
-
/** Cancels the messages scheduled for a session; the ids of those cancelled. */
|
|
327
209
|
readonly cancelScheduled: (sessionID: string) => Promise<ReadonlyArray<string>>;
|
|
328
210
|
readonly cleanup: CleanupPorts;
|
|
329
211
|
}
|
|
@@ -333,49 +215,31 @@ export interface GroupPorts {
|
|
|
333
215
|
readonly now: () => number;
|
|
334
216
|
readonly log: (message: string) => void;
|
|
335
217
|
}
|
|
336
|
-
/** The error of OpenCode's `session.execution.failed` event. */
|
|
337
218
|
export interface ExecutionError {
|
|
338
219
|
readonly type: string;
|
|
339
220
|
readonly message: string;
|
|
340
221
|
readonly status?: number;
|
|
341
|
-
/** How long the provider asked to wait before trying again, counted from the event's `created`; set by rate and quota limits and some provider errors. */
|
|
342
222
|
readonly retryAfterMs?: number;
|
|
343
223
|
}
|
|
344
224
|
export interface WatchPorts {
|
|
345
225
|
readonly storage: RosterStorage;
|
|
346
|
-
/** `context` reads the last reply of a session that ended its turn without reporting; `get` is what every member joins with too. */
|
|
347
226
|
readonly session: Pick<Context["session"], "synthetic" | "context" | "get"> & Instructions;
|
|
348
227
|
readonly event: Pick<Context["event"], "subscribe">;
|
|
349
|
-
/** The permission domains of every loaded location, which the `Waits` suppliers ask; an isolated child's are in its worktree's. */
|
|
350
228
|
readonly permissions: () => Iterable<Pick<Context["permission"], "list">>;
|
|
351
|
-
/** The clock, in epoch milliseconds, for an event that carries no `created`. */
|
|
352
229
|
readonly now: () => number;
|
|
353
230
|
readonly log: (message: string) => void;
|
|
354
|
-
/** Has the scheduler deliver what is due now rather than at its next tick: a group completed, or its parent's turn ended. */
|
|
355
231
|
readonly nudge: () => void;
|
|
356
232
|
}
|
|
357
|
-
/**
|
|
358
|
-
* What every plugin instance in the process shares. Several subscriptions and copies see the same
|
|
359
|
-
* events, so each is claimed synchronously and handled once.
|
|
360
|
-
*/
|
|
361
233
|
export interface WatchState {
|
|
362
234
|
readonly seen: Set<string>;
|
|
363
|
-
/** The type of each item enqueued for a spawned session, by inbox id, for its delivery to look up. */
|
|
364
235
|
readonly inbox: Map<string, string>;
|
|
365
236
|
}
|
|
366
|
-
/**
|
|
367
|
-
* Whether a session waits, since `since`, on what the tree does not keep: asked by the silent-turn
|
|
368
|
-
* rule after the tree's own checks, through the watcher's ports; `src/index.ts` composes it.
|
|
369
|
-
*/
|
|
370
237
|
export type Waits = (ports: Pick<WatchPorts, "storage" | "permissions">, sessionID: string, since: number) => Promise<boolean>;
|
|
371
238
|
export interface ContextPorts {
|
|
372
239
|
readonly storage: RosterStorage;
|
|
373
240
|
readonly limits: Limits;
|
|
374
|
-
/** Each session's role once looked up; a session nobody spawned reads as depth null until it starts one. */
|
|
375
241
|
readonly roles: Map<string, Role>;
|
|
376
|
-
/** The keyed session entries, listed when a session's role is looked up; missing on a host before 2.2.0, which gets the system part. */
|
|
377
242
|
readonly instructions?: Context["session"]["instructions"];
|
|
378
|
-
/** Tools of other modules hidden from a leaf alongside courier_spawn; `src/index.ts` names courier_recall and courier_note. */
|
|
379
243
|
readonly hiddenFromLeaf?: ReadonlyArray<string>;
|
|
380
244
|
readonly log: (message: string) => void;
|
|
381
245
|
}
|
package/dist/tree/report.d.ts
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { type Status } from "../kernel/protocol.js";
|
|
2
2
|
import type { ChildStore } from "./ports.js";
|
|
3
3
|
type Notes = Pick<ChildStore, "notes">;
|
|
4
|
-
/** Whether courier_stop stopped a session after its last prompt, or with none noted, at all. */
|
|
5
4
|
export declare function stoppedSincePrompt(children: Notes, sessionID: string): Promise<boolean>;
|
|
6
|
-
/** The status of a spawned session's last report to its parent, if it has reported with one. */
|
|
7
5
|
export declare function lastStatus(children: Notes, sessionID: string): Promise<Status | undefined>;
|
|
8
|
-
/**
|
|
9
|
-
* What is known of a spawned session's report: when a prompt last reached it, and whether since then it owes one, has
|
|
10
|
-
* messaged its parent without a status, or failed (`resumesAt`: until when) or was interrupted. Undefined before this was kept.
|
|
11
|
-
*/
|
|
12
6
|
export declare function reportOf(children: Notes, sessionID: string): Promise<{
|
|
13
7
|
resumesAt?: number | undefined;
|
|
14
8
|
prompt: number;
|
|
@@ -16,9 +10,5 @@ export declare function reportOf(children: Notes, sessionID: string): Promise<{
|
|
|
16
10
|
progressed: boolean;
|
|
17
11
|
ended: boolean;
|
|
18
12
|
} | undefined>;
|
|
19
|
-
/**
|
|
20
|
-
* Whether its parent still waits on a spawned session's report: it owes one, and the parent has not
|
|
21
|
-
* been told since its last prompt that it ended a turn without one.
|
|
22
|
-
*/
|
|
23
13
|
export declare function awaited(children: Notes, sessionID: string): Promise<boolean>;
|
|
24
14
|
export {};
|
package/dist/tree/report.js
CHANGED
|
@@ -1,20 +1,13 @@
|
|
|
1
1
|
import { isStatus } from "../kernel/protocol.js";
|
|
2
|
-
/** Whether `at` is known and no earlier than the prompt at `prompt`. */
|
|
3
2
|
const since = (at, prompt) => at !== undefined && at >= prompt;
|
|
4
|
-
/** Whether courier_stop stopped a session after its last prompt, or with none noted, at all. */
|
|
5
3
|
export async function stoppedSincePrompt(children, sessionID) {
|
|
6
4
|
const { stopped, prompt } = await children.notes(sessionID, ["stopped", "prompt"]);
|
|
7
5
|
return stopped.at !== undefined && (prompt.at === undefined || stopped.at >= prompt.at);
|
|
8
6
|
}
|
|
9
|
-
/** The status of a spawned session's last report to its parent, if it has reported with one. */
|
|
10
7
|
export async function lastStatus(children, sessionID) {
|
|
11
8
|
const { status } = (await children.notes(sessionID, ["settled"])).settled;
|
|
12
9
|
return isStatus(status) ? status : undefined;
|
|
13
10
|
}
|
|
14
|
-
/**
|
|
15
|
-
* What is known of a spawned session's report: when a prompt last reached it, and whether since then it owes one, has
|
|
16
|
-
* messaged its parent without a status, or failed (`resumesAt`: until when) or was interrupted. Undefined before this was kept.
|
|
17
|
-
*/
|
|
18
11
|
export async function reportOf(children, sessionID) {
|
|
19
12
|
const { prompt, settled, progress } = await children.notes(sessionID, ["prompt", "settled", "progress"]);
|
|
20
13
|
const promptAt = prompt.at;
|
|
@@ -30,10 +23,6 @@ export async function reportOf(children, sessionID) {
|
|
|
30
23
|
...(resumesAt === undefined ? {} : { resumesAt }),
|
|
31
24
|
};
|
|
32
25
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Whether its parent still waits on a spawned session's report: it owes one, and the parent has not
|
|
35
|
-
* been told since its last prompt that it ended a turn without one.
|
|
36
|
-
*/
|
|
37
26
|
export async function awaited(children, sessionID) {
|
|
38
27
|
const { prompt, settled, told } = await children.notes(sessionID, ["prompt", "settled", "told"]);
|
|
39
28
|
return prompt.at !== undefined && !since(settled.at, prompt.at) && !since(told.at, prompt.at);
|
package/dist/tree/roster.d.ts
CHANGED
|
@@ -2,21 +2,10 @@ import { type Status } from "../kernel/protocol.js";
|
|
|
2
2
|
import { type Exists } from "./domain.js";
|
|
3
3
|
import type { RosterEntry, RosterStorage } from "./ports.js";
|
|
4
4
|
export { RETENTION_MS, type Exists } from "./domain.js";
|
|
5
|
-
/** Every parent's children. */
|
|
6
5
|
export declare function allEntries(storage: RosterStorage): Promise<RosterEntry[]>;
|
|
7
|
-
/**
|
|
8
|
-
* The roster entries from a session up to the top, its own first, ending with the entry whose parent
|
|
9
|
-
* courier_spawn did not start; empty when courier_spawn did not start the session.
|
|
10
|
-
*/
|
|
11
6
|
export declare function lineage(storage: RosterStorage, sessionID: string): Promise<RosterEntry[]>;
|
|
12
|
-
/** `lineage` by the reverse index alone: empty, without scanning the roster, when it does not name the session. */
|
|
13
7
|
export declare function indexedLineage(storage: RosterStorage, sessionID: string): Promise<RosterEntry[]>;
|
|
14
|
-
/** The sessions a session started, oldest first, expired entries included. */
|
|
15
8
|
export declare function childrenOf(storage: RosterStorage, parentID: string): Promise<RosterEntry[]>;
|
|
16
|
-
/**
|
|
17
|
-
* What another module reads of a spawned session's report: `known` once a prompt was noted, whether it `owes` one, how
|
|
18
|
-
* its wait `ended` when not by a report, the `status` of its last report, and whether courier_stop `stopped` it since its last prompt.
|
|
19
|
-
*/
|
|
20
9
|
export interface ReportState {
|
|
21
10
|
readonly known: boolean;
|
|
22
11
|
readonly owes: boolean;
|
|
@@ -25,17 +14,7 @@ export interface ReportState {
|
|
|
25
14
|
readonly stopped: boolean;
|
|
26
15
|
}
|
|
27
16
|
export declare function reportState(storage: RosterStorage, sessionID: string): Promise<ReportState>;
|
|
28
|
-
/**
|
|
29
|
-
* The top of a spawned session's lineage, where its permission requests and questions go, since the
|
|
30
|
-
* person is there. Throws unless the session was spawned and `callerID` is that top; `what` names it.
|
|
31
|
-
*/
|
|
32
17
|
export declare function answeringTop(storage: RosterStorage, sessionID: string, callerID: string, what: string): Promise<string>;
|
|
33
|
-
/** `domain.ts`'s `isExpired`, asking the file system whether an isolated child's worktree is still there unless a test passes a fake. */
|
|
34
18
|
export declare const isExpired: (entry: RosterEntry, now: number, exists?: Exists) => boolean;
|
|
35
|
-
/** A parent's children, oldest first, after dropping the expired ones. */
|
|
36
19
|
export declare function current(storage: RosterStorage, parentID: string, now: number, exists?: Exists): Promise<RosterEntry[]>;
|
|
37
|
-
/**
|
|
38
|
-
* On loading: drops expired entries of every parent, then brings the reverse index in line with
|
|
39
|
-
* what is left (`backfill`) and drops report state with no entry (`dropOrphanedReports`).
|
|
40
|
-
*/
|
|
41
20
|
export declare function pruneExpired(storage: RosterStorage, now: number, exists?: Exists): Promise<void>;
|
package/dist/tree/roster.js
CHANGED
|
@@ -5,22 +5,15 @@ import { forgetChild, forgetReports } from "./forget.js";
|
|
|
5
5
|
import { stoppedSincePrompt } from "./report.js";
|
|
6
6
|
import { childStore } from "./store.js";
|
|
7
7
|
export { RETENTION_MS } from "./domain.js";
|
|
8
|
-
/** Every parent's children. */
|
|
9
8
|
export async function allEntries(storage) {
|
|
10
9
|
return childStore(storage).all();
|
|
11
10
|
}
|
|
12
|
-
/**
|
|
13
|
-
* The roster entries from a session up to the top, its own first, ending with the entry whose parent
|
|
14
|
-
* courier_spawn did not start; empty when courier_spawn did not start the session.
|
|
15
|
-
*/
|
|
16
11
|
export async function lineage(storage, sessionID) {
|
|
17
12
|
return childStore(storage).lineage(sessionID);
|
|
18
13
|
}
|
|
19
|
-
/** `lineage` by the reverse index alone: empty, without scanning the roster, when it does not name the session. */
|
|
20
14
|
export async function indexedLineage(storage, sessionID) {
|
|
21
15
|
return childStore(storage).indexedLineage(sessionID);
|
|
22
16
|
}
|
|
23
|
-
/** The sessions a session started, oldest first, expired entries included. */
|
|
24
17
|
export async function childrenOf(storage, parentID) {
|
|
25
18
|
return childStore(storage).children(parentID);
|
|
26
19
|
}
|
|
@@ -38,10 +31,6 @@ export async function reportState(storage, sessionID) {
|
|
|
38
31
|
stopped,
|
|
39
32
|
};
|
|
40
33
|
}
|
|
41
|
-
/**
|
|
42
|
-
* The top of a spawned session's lineage, where its permission requests and questions go, since the
|
|
43
|
-
* person is there. Throws unless the session was spawned and `callerID` is that top; `what` names it.
|
|
44
|
-
*/
|
|
45
34
|
export async function answeringTop(storage, sessionID, callerID, what) {
|
|
46
35
|
const chain = await lineage(storage, sessionID);
|
|
47
36
|
if (!chain.length)
|
|
@@ -51,31 +40,21 @@ export async function answeringTop(storage, sessionID, callerID, what) {
|
|
|
51
40
|
throw new Error(`${sessionID}'s ${what} go to ${top}, the session at the top of the sessions started from it with courier_spawn; ${callerID} cannot answer them.`);
|
|
52
41
|
return top;
|
|
53
42
|
}
|
|
54
|
-
/** `domain.ts`'s `isExpired`, asking the file system whether an isolated child's worktree is still there unless a test passes a fake. */
|
|
55
43
|
export const isExpired = (entry, now, exists = existsSync) => expiredBy(entry, now, exists);
|
|
56
|
-
/** Forgets the given entries that are expired at `now`, and returns the rest. */
|
|
57
44
|
async function dropExpired(storage, entries, now, exists) {
|
|
58
45
|
const expired = new Set(entries.filter((entry) => isExpired(entry, now, exists)));
|
|
59
46
|
await Promise.all([...expired].map((entry) => forgetChild(storage, entry.parentID, entry.sessionID, entry.group)));
|
|
60
47
|
return entries.filter((entry) => !expired.has(entry));
|
|
61
48
|
}
|
|
62
|
-
/** A parent's children, oldest first, after dropping the expired ones. */
|
|
63
49
|
export async function current(storage, parentID, now, exists = existsSync) {
|
|
64
50
|
return dropExpired(storage, await childStore(storage).children(parentID), now, exists);
|
|
65
51
|
}
|
|
66
|
-
/**
|
|
67
|
-
* On loading: drops expired entries of every parent, then brings the reverse index in line with
|
|
68
|
-
* what is left (`backfill`) and drops report state with no entry (`dropOrphanedReports`).
|
|
69
|
-
*/
|
|
70
52
|
export async function pruneExpired(storage, now, exists = existsSync) {
|
|
71
53
|
const children = childStore(storage);
|
|
72
|
-
// Report keys are read before the roster: courier_spawn writes a child's entry before its first
|
|
73
|
-
// report key, so a session seen here that spawns during the sweep has its entry in the read below.
|
|
74
54
|
const reported = await children.reported().catch(() => new Map());
|
|
75
55
|
const entries = await dropExpired(storage, await children.all(), now, exists);
|
|
76
56
|
await Promise.all([children.backfill(entries), dropOrphanedReports(storage, reported, entries)]);
|
|
77
57
|
}
|
|
78
|
-
/** Removes the report keys read of sessions that have no roster entry. */
|
|
79
58
|
async function dropOrphanedReports(storage, reported, entries) {
|
|
80
59
|
const sessions = new Set(entries.map((entry) => entry.sessionID));
|
|
81
60
|
await forgetReports(storage, reported, [...reported.keys()].filter((sessionID) => !sessions.has(sessionID)));
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Plugin } from "@opencode/plugin";
|
|
2
2
|
import type { StopPorts } from "./ports.js";
|
|
3
|
-
/** Serves the tree's RPC at the plugin's location, through the same use cases as the tools; disposed with the plugin. */
|
|
4
3
|
export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "register">, ports: StopPorts): Promise<import("@opencode/plugin/promise/rpc").RpcRegistration<{
|
|
5
4
|
readonly id: "courier";
|
|
6
5
|
readonly methods: {
|
|
@@ -74,6 +73,7 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
74
73
|
})[];
|
|
75
74
|
readonly stopped?: boolean | undefined;
|
|
76
75
|
readonly stalled?: number | undefined;
|
|
76
|
+
readonly subagent?: boolean | undefined;
|
|
77
77
|
readonly group?: {
|
|
78
78
|
readonly name: string;
|
|
79
79
|
readonly standing: string;
|
|
@@ -117,6 +117,7 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
117
117
|
})[];
|
|
118
118
|
readonly stopped?: boolean | undefined;
|
|
119
119
|
readonly stalled?: number | undefined;
|
|
120
|
+
readonly subagent?: boolean | undefined;
|
|
120
121
|
readonly group?: {
|
|
121
122
|
readonly name: string;
|
|
122
123
|
readonly standing: string;
|
|
@@ -161,6 +162,7 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
161
162
|
})[];
|
|
162
163
|
readonly stopped?: boolean | undefined;
|
|
163
164
|
readonly stalled?: number | undefined;
|
|
165
|
+
readonly subagent?: boolean | undefined;
|
|
164
166
|
readonly group?: {
|
|
165
167
|
readonly name: string;
|
|
166
168
|
readonly standing: string;
|
|
@@ -204,6 +206,7 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
204
206
|
})[];
|
|
205
207
|
readonly stopped?: boolean | undefined;
|
|
206
208
|
readonly stalled?: number | undefined;
|
|
209
|
+
readonly subagent?: boolean | undefined;
|
|
207
210
|
readonly group?: {
|
|
208
211
|
readonly name: string;
|
|
209
212
|
readonly standing: string;
|
|
@@ -248,6 +251,7 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
248
251
|
}>>;
|
|
249
252
|
readonly isolated: import("effect/Schema").Boolean;
|
|
250
253
|
readonly native: import("effect/Schema").optionalKey<import("effect/Schema").Boolean>;
|
|
254
|
+
readonly subagent: import("effect/Schema").optionalKey<import("effect/Schema").Boolean>;
|
|
251
255
|
readonly model: import("effect/Schema").optionalKey<import("effect/Schema").String>;
|
|
252
256
|
readonly created: import("effect/Schema").Number;
|
|
253
257
|
readonly idle: import("effect/Schema").optionalKey<import("effect/Schema").Number>;
|
|
@@ -290,6 +294,7 @@ export declare function registerTreeRpc(rpc: Pick<Plugin.Context["rpc"], "regist
|
|
|
290
294
|
}>>;
|
|
291
295
|
readonly isolated: import("effect/Schema").Boolean;
|
|
292
296
|
readonly native: import("effect/Schema").optionalKey<import("effect/Schema").Boolean>;
|
|
297
|
+
readonly subagent: import("effect/Schema").optionalKey<import("effect/Schema").Boolean>;
|
|
293
298
|
readonly model: import("effect/Schema").optionalKey<import("effect/Schema").String>;
|
|
294
299
|
readonly created: import("effect/Schema").Number;
|
|
295
300
|
readonly idle: import("effect/Schema").optionalKey<import("effect/Schema").Number>;
|
|
@@ -6,7 +6,6 @@ import { treeRpc } from "./rpc.js";
|
|
|
6
6
|
import { stop } from "./stop.js";
|
|
7
7
|
import { childStore } from "./store.js";
|
|
8
8
|
import { summary } from "./summary.js";
|
|
9
|
-
/** Serves the tree's RPC at the plugin's location, through the same use cases as the tools; disposed with the plugin. */
|
|
10
9
|
export function registerTreeRpc(rpc, ports) {
|
|
11
10
|
const refused = (cause) => (cause instanceof Error ? cause.message : String(cause));
|
|
12
11
|
return rpc.register(treeRpc, {
|
|
@@ -31,10 +30,6 @@ export function registerTreeRpc(rpc, ports) {
|
|
|
31
30
|
},
|
|
32
31
|
});
|
|
33
32
|
}
|
|
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
33
|
async function forget(ports, by, sessionID) {
|
|
39
34
|
const chain = await childStore(ports.courier.storage).lineage(sessionID);
|
|
40
35
|
if (!chain.length)
|