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.
Files changed (59) hide show
  1. package/README.md +19 -14
  2. package/dist/index.js +19 -6
  3. package/dist/kernel/protocol.d.ts +2 -0
  4. package/dist/kernel/protocol.js +4 -0
  5. package/dist/memory/events.js +3 -1
  6. package/dist/memory/index.d.ts +2 -1
  7. package/dist/memory/index.js +2 -1
  8. package/dist/memory/lessons.d.ts +12 -0
  9. package/dist/memory/lessons.js +56 -0
  10. package/dist/memory/note.js +3 -0
  11. package/dist/memory/ports.d.ts +3 -1
  12. package/dist/memory/text.d.ts +11 -0
  13. package/dist/memory/text.js +22 -1
  14. package/dist/memory/tools.js +2 -1
  15. package/dist/person/events.js +4 -1
  16. package/dist/person/permission.d.ts +1 -1
  17. package/dist/person/permission.js +1 -1
  18. package/dist/person/question/answer.d.ts +1 -1
  19. package/dist/person/question/answer.js +1 -1
  20. package/dist/person/question/lifecycle.d.ts +1 -1
  21. package/dist/person/question/lifecycle.js +1 -1
  22. package/dist/person/question/relay.js +1 -1
  23. package/dist/platform/events.d.ts +10 -2
  24. package/dist/platform/events.js +38 -8
  25. package/dist/skill.d.ts +1 -1
  26. package/dist/skill.js +97 -45
  27. package/dist/tree/cleanup.js +2 -0
  28. package/dist/tree/context.d.ts +2 -2
  29. package/dist/tree/context.js +26 -10
  30. package/dist/tree/domain.d.ts +32 -2
  31. package/dist/tree/domain.js +28 -2
  32. package/dist/tree/events.js +21 -1
  33. package/dist/tree/group.js +3 -0
  34. package/dist/tree/index.d.ts +1 -1
  35. package/dist/tree/model.d.ts +18 -0
  36. package/dist/tree/model.js +65 -0
  37. package/dist/tree/panel.js +3 -2
  38. package/dist/tree/ports.d.ts +59 -13
  39. package/dist/tree/roster.d.ts +3 -11
  40. package/dist/tree/roster.js +4 -10
  41. package/dist/tree/rpc-handlers.d.ts +6 -0
  42. package/dist/tree/rpc.d.ts +16 -0
  43. package/dist/tree/rpc.js +4 -0
  44. package/dist/tree/send.js +46 -19
  45. package/dist/tree/spawn.d.ts +8 -0
  46. package/dist/tree/spawn.js +74 -21
  47. package/dist/tree/standing.d.ts +17 -0
  48. package/dist/tree/standing.js +90 -0
  49. package/dist/tree/status.d.ts +35 -19
  50. package/dist/tree/status.js +6 -6
  51. package/dist/tree/stop.js +3 -0
  52. package/dist/tree/store.js +4 -2
  53. package/dist/tree/subtree.d.ts +16 -8
  54. package/dist/tree/text.d.ts +48 -6
  55. package/dist/tree/text.js +113 -8
  56. package/dist/tree/tools.d.ts +3 -3
  57. package/dist/tree/tools.js +24 -20
  58. package/dist/tui.js +8 -0
  59. package/package.json +6 -6
@@ -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, status } from "./status.js";
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, statusText, stopText, treeText } from "./text.js";
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. The session reports " +
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 courier_status in a " +
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. If you were " +
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. Like courier_status, for a one-off look, not for waiting.",
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.11.1",
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.1.4",
59
+ "@opencode/plugin": "2.2.0",
60
60
  "effect": "4.0.1"
61
61
  },
62
62
  "devDependencies": {
63
- "@opencode/plugin": "2.1.4",
64
- "@opencode/theme": "2.1.4",
65
- "@opentui/core": "0.6.8",
66
- "@opentui/solid": "0.6.8",
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",