opencode-courier 0.11.1 → 0.13.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 +19 -14
- package/dist/index.js +19 -6
- package/dist/kernel/protocol.d.ts +2 -0
- package/dist/kernel/protocol.js +4 -0
- package/dist/memory/events.js +3 -1
- package/dist/memory/index.d.ts +2 -1
- package/dist/memory/index.js +2 -1
- package/dist/memory/lessons.d.ts +12 -0
- package/dist/memory/lessons.js +56 -0
- package/dist/memory/note.js +3 -0
- package/dist/memory/ports.d.ts +3 -1
- package/dist/memory/text.d.ts +11 -0
- package/dist/memory/text.js +22 -1
- package/dist/memory/tools.js +2 -1
- package/dist/person/events.js +4 -1
- package/dist/person/permission.d.ts +1 -1
- package/dist/person/permission.js +1 -1
- package/dist/person/question/answer.d.ts +1 -1
- package/dist/person/question/answer.js +1 -1
- package/dist/person/question/lifecycle.d.ts +1 -1
- package/dist/person/question/lifecycle.js +1 -1
- package/dist/person/question/relay.js +1 -1
- package/dist/platform/events.d.ts +10 -2
- package/dist/platform/events.js +38 -8
- package/dist/skill.d.ts +1 -1
- package/dist/skill.js +97 -45
- package/dist/tree/cleanup.js +2 -0
- package/dist/tree/context.d.ts +2 -2
- package/dist/tree/context.js +26 -10
- package/dist/tree/domain.d.ts +32 -2
- package/dist/tree/domain.js +28 -2
- package/dist/tree/events.js +21 -1
- package/dist/tree/group.js +3 -0
- package/dist/tree/index.d.ts +1 -1
- package/dist/tree/model.d.ts +18 -0
- package/dist/tree/model.js +65 -0
- package/dist/tree/panel.js +3 -2
- package/dist/tree/ports.d.ts +59 -13
- package/dist/tree/roster.d.ts +3 -11
- package/dist/tree/roster.js +4 -10
- package/dist/tree/rpc-handlers.d.ts +6 -0
- package/dist/tree/rpc.d.ts +16 -0
- package/dist/tree/rpc.js +4 -0
- package/dist/tree/send.js +46 -19
- package/dist/tree/spawn.d.ts +8 -0
- package/dist/tree/spawn.js +74 -21
- package/dist/tree/standing.d.ts +17 -0
- package/dist/tree/standing.js +90 -0
- package/dist/tree/status.d.ts +35 -19
- package/dist/tree/status.js +6 -6
- package/dist/tree/stop.js +3 -0
- package/dist/tree/store.js +4 -2
- package/dist/tree/subtree.d.ts +16 -8
- package/dist/tree/text.d.ts +48 -6
- package/dist/tree/text.js +113 -8
- package/dist/tree/tools.d.ts +3 -3
- package/dist/tree/tools.js +24 -20
- package/dist/tui.js +8 -0
- package/package.json +6 -6
package/dist/tree/tools.js
CHANGED
|
@@ -4,10 +4,10 @@ import { rethrow } from "../kernel/tool.js";
|
|
|
4
4
|
import { cleanup } from "./cleanup.js";
|
|
5
5
|
import { send } from "./send.js";
|
|
6
6
|
import { spawn } from "./spawn.js";
|
|
7
|
-
import { listChildren
|
|
7
|
+
import { listChildren } from "./status.js";
|
|
8
8
|
import { stop } from "./stop.js";
|
|
9
9
|
import { tree } from "./subtree.js";
|
|
10
|
-
import { childrenText, cleanupText, sendText, spawnText,
|
|
10
|
+
import { childrenText, cleanupText, sendText, spawnText, stopText, treeText } from "./text.js";
|
|
11
11
|
/**
|
|
12
12
|
* The tree's courier tools: their input schemas, descriptions, and what each returns. The descriptions are
|
|
13
13
|
* model-facing like the texts in `text.ts`, and snapshotted with them in `test/notices.test.ts`.
|
|
@@ -16,10 +16,26 @@ export const SpawnInput = Schema.Struct({
|
|
|
16
16
|
task: Schema.String.annotate({ description: "What the new session should do. It is told who started it and how to report back." }),
|
|
17
17
|
title: Schema.optional(Schema.String.annotate({ description: "Session title; defaults to the task's first line." })),
|
|
18
18
|
agent: Schema.optional(Schema.String.annotate({ description: "Agent to run the session with; defaults to the default agent." })),
|
|
19
|
+
model: Schema.optional(Schema.String.annotate({
|
|
20
|
+
description: "The model to run the session on, as provider/model (opencode/gpt-5-nano). Leave it unset for your own model, or the " +
|
|
21
|
+
"agent's own if it names one. Refused when OpenCode does not list it here.",
|
|
22
|
+
})),
|
|
23
|
+
variant: Schema.optional(Schema.String.annotate({
|
|
24
|
+
description: "The model's variant, its reasoning effort as OpenCode names it (low, medium, high, or another the model has). Leave " +
|
|
25
|
+
"it unset for the chosen model's own; with a model of your own choosing, that is the model's default. Refused when " +
|
|
26
|
+
"the model has no such variant.",
|
|
27
|
+
})),
|
|
19
28
|
isolate: Schema.optional(Schema.Boolean.annotate({ description: "Run the session in its own git worktree so parallel sessions don't share files. From a session that is itself " +
|
|
20
29
|
"isolated, the worktree starts from your current commit, not your uncommitted changes: commit first. The session " +
|
|
21
30
|
"commits on a branch named courier/<its session ID> and names it in its report; merge that branch yourself.",
|
|
22
31
|
})),
|
|
32
|
+
native: Schema.optional(Schema.Boolean.annotate({
|
|
33
|
+
description: "true starts the session as your OpenCode subagent: it leaves OpenCode's session lists for your subagent tab, the " +
|
|
34
|
+
"person answers its permission requests and questions in the view of the nearest session above it that is not a " +
|
|
35
|
+
"subagent, usually the top one, and deleting your session deletes it. false starts a standalone session, whatever the " +
|
|
36
|
+
"plugin's nativeChildren option says; unset, that option decides. Refused with isolate: true, as a subagent runs in " +
|
|
37
|
+
"its parent's directory.",
|
|
38
|
+
})),
|
|
23
39
|
group: Schema.optional(Schema.String.annotate({
|
|
24
40
|
description: "A join group: start the sessions of one batch with the same name, and their reports are held and delivered " +
|
|
25
41
|
"to you in one message once every one of them has reported and your turn has ended, instead of one turn per " +
|
|
@@ -45,9 +61,6 @@ export const SendInput = Schema.Struct({
|
|
|
45
61
|
}).annotate({ description: "With a report: what you produced, listed in the message after your text in a fixed layout." })),
|
|
46
62
|
queue: Schema.optional(Schema.Boolean.annotate({ description: "Wait until the target's current turn ends instead of steering it now." })),
|
|
47
63
|
});
|
|
48
|
-
export const StatusInput = Schema.Struct({
|
|
49
|
-
sessionID: Schema.String.annotate({ description: "The session to look at." }),
|
|
50
|
-
});
|
|
51
64
|
export const ChildrenInput = Schema.Struct({
|
|
52
65
|
sessionID: Schema.optional(Schema.String.annotate({ description: "The session whose children to list; defaults to this one." })),
|
|
53
66
|
});
|
|
@@ -72,10 +85,11 @@ export function addTreeTools(tools, ports) {
|
|
|
72
85
|
tools.add({
|
|
73
86
|
name: "courier_spawn",
|
|
74
87
|
options: { codemode: false },
|
|
75
|
-
description: "Start a new OpenCode session on a task and return immediately. It runs on your model
|
|
88
|
+
description: "Start a new OpenCode session on a task and return immediately. It runs on your model, unless you name a model or a " +
|
|
89
|
+
"variant (reasoning effort) fit for the task. The session reports " +
|
|
76
90
|
"back with courier_send, which wakes this session, and you are told if its turn fails or ends without a report " +
|
|
77
91
|
"instead, it waits for a permission or it asks a question. Give a batch of parallel sessions one group name to " +
|
|
78
|
-
"be woken once, with all their reports, instead of once per report. DO NOT poll it or call
|
|
92
|
+
"be woken once, with all their reports, instead of once per report. DO NOT poll it or call courier_children in a " +
|
|
79
93
|
"loop: once you have started the sessions you need, end your turn by replying without calling more tools; each " +
|
|
80
94
|
"report, or each group's reports, starts a new turn in which you carry on. For long tasks, also courier_later a " +
|
|
81
95
|
"check-in for yourself in case it never reports, and courier_cancel it when it does.",
|
|
@@ -91,7 +105,8 @@ export function addTreeTools(tools, ports) {
|
|
|
91
105
|
description: "Deliver a message to another OpenCode session. If that session is idle, OpenCode starts a new turn for it. " +
|
|
92
106
|
"Use it to report back to the session that started you, with a status (done, partial, blocked or failed) and " +
|
|
93
107
|
"the artifacts you produced, or to steer a session you started. The status is carried as an attribute of the " +
|
|
94
|
-
"message; without one, a message to the session that started you is progress, not your report.
|
|
108
|
+
"message; without one, a message to the session that started you is progress, not your report. A message to a " +
|
|
109
|
+
"session you started carries no status: one given is dropped. If you were " +
|
|
95
110
|
"started in a group, a report with status done, partial or failed is held and delivered with the group's other " +
|
|
96
111
|
"reports; the result says so, and nothing more is needed from you.",
|
|
97
112
|
input: SendInput,
|
|
@@ -100,23 +115,12 @@ export function addTreeTools(tools, ports) {
|
|
|
100
115
|
return { content: sendText(input.sessionID, delivered), metadata: delivered };
|
|
101
116
|
},
|
|
102
117
|
});
|
|
103
|
-
tools.add({
|
|
104
|
-
name: "courier_status",
|
|
105
|
-
options: { codemode: false },
|
|
106
|
-
description: "Look once at a session's state and its last reply, e.g. on a scheduled check-in. Not for waiting: " +
|
|
107
|
-
"sessions you started report back on their own.",
|
|
108
|
-
input: StatusInput,
|
|
109
|
-
execute: async (input) => {
|
|
110
|
-
const result = await status(ports.courier, input).catch(rethrow("courier_status"));
|
|
111
|
-
return { content: statusText(result), metadata: result };
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
118
|
tools.add({
|
|
115
119
|
name: "courier_children",
|
|
116
120
|
options: { codemode: false },
|
|
117
121
|
description: "List the sessions this one started with courier_spawn, with each one's state and last reply, and for one " +
|
|
118
122
|
"started in a group, its group and whether its report is held, still out, or released, e.g. after a " +
|
|
119
|
-
"compaction or restart.
|
|
123
|
+
"compaction or restart. For a one-off look, e.g. on a scheduled check-in, not for waiting: sessions you started report back on their own.",
|
|
120
124
|
input: ChildrenInput,
|
|
121
125
|
execute: async (input, context) => {
|
|
122
126
|
const listed = await listChildren(ports.courier, input.sessionID || context.sessionID).catch(rethrow("courier_children"));
|
package/dist/tui.js
CHANGED
|
@@ -1457,6 +1457,8 @@ var Row = Schema3.Struct({
|
|
|
1457
1457
|
report: Schema3.optionalKey(Schema3.Struct({ state: Schema3.Literals(["owed", "reported", "ended"]), status: Schema3.optionalKey(Schema3.String), progressed: Schema3.Boolean })),
|
|
1458
1458
|
group: Schema3.optionalKey(Schema3.Struct({ name: Schema3.String, standing: Schema3.String })),
|
|
1459
1459
|
isolated: Schema3.Boolean,
|
|
1460
|
+
native: Schema3.optionalKey(Schema3.Boolean),
|
|
1461
|
+
model: Schema3.optionalKey(Schema3.String),
|
|
1460
1462
|
created: Schema3.Number,
|
|
1461
1463
|
idle: Schema3.optionalKey(Schema3.Number),
|
|
1462
1464
|
cost: Schema3.optionalKey(Schema3.Number),
|
|
@@ -1740,6 +1742,12 @@ function statusParts(row, now = Date.now()) {
|
|
|
1740
1742
|
}, {
|
|
1741
1743
|
text: row.isolated ? "isolated" : "",
|
|
1742
1744
|
kind: "plain"
|
|
1745
|
+
}, {
|
|
1746
|
+
text: row.native ? "native" : "",
|
|
1747
|
+
kind: "plain"
|
|
1748
|
+
}, {
|
|
1749
|
+
text: row.model ?? "",
|
|
1750
|
+
kind: "plain"
|
|
1743
1751
|
}];
|
|
1744
1752
|
return parts.filter((part) => part.text);
|
|
1745
1753
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-courier",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Multi-session orchestration for OpenCode V2: spawn child sessions, be woken by them. No polling.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ivo Pogace <71701666+ivopogace@users.noreply.github.com>",
|
|
@@ -56,14 +56,14 @@
|
|
|
56
56
|
"test:e2e": "e2e/run.sh"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@opencode/plugin": "2.
|
|
59
|
+
"@opencode/plugin": "2.2.0",
|
|
60
60
|
"effect": "4.0.1"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
|
-
"@opencode/plugin": "2.
|
|
64
|
-
"@opencode/theme": "2.
|
|
65
|
-
"@opentui/core": "0.
|
|
66
|
-
"@opentui/solid": "0.
|
|
63
|
+
"@opencode/plugin": "2.2.0",
|
|
64
|
+
"@opencode/theme": "2.2.0",
|
|
65
|
+
"@opentui/core": "0.7.0",
|
|
66
|
+
"@opentui/solid": "0.7.0",
|
|
67
67
|
"@types/bun": "1.4.2",
|
|
68
68
|
"@types/node": "26.6.4",
|
|
69
69
|
"effect": "4.0.1",
|