opencode-courier 0.3.0 → 0.4.1

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 (141) hide show
  1. package/README.md +180 -274
  2. package/dist/index.js +47 -73
  3. package/dist/kernel/protocol.d.ts +20 -0
  4. package/dist/kernel/protocol.js +36 -0
  5. package/dist/kernel/tool.d.ts +5 -0
  6. package/dist/kernel/tool.js +5 -0
  7. package/dist/person/events.d.ts +23 -0
  8. package/dist/person/events.js +113 -0
  9. package/dist/person/form.d.ts +26 -0
  10. package/dist/person/form.js +64 -0
  11. package/dist/person/index.d.ts +17 -0
  12. package/dist/person/index.js +5 -0
  13. package/dist/{relay.d.ts → person/permission.d.ts} +27 -21
  14. package/dist/{relay.js → person/permission.js} +9 -5
  15. package/dist/person/ports.d.ts +58 -0
  16. package/dist/person/ports.js +2 -0
  17. package/dist/{question → person/question}/answer.d.ts +33 -4
  18. package/dist/{question → person/question}/answer.js +43 -8
  19. package/dist/person/question/index.d.ts +7 -0
  20. package/dist/{question → person/question}/index.js +3 -3
  21. package/dist/{question → person/question}/lifecycle.d.ts +1 -1
  22. package/dist/{question → person/question}/pure.d.ts +1 -2
  23. package/dist/{question → person/question}/pure.js +1 -1
  24. package/dist/{question → person/question}/relay.d.ts +1 -1
  25. package/dist/{question → person/question}/relay.js +14 -8
  26. package/dist/{question → person/question}/shared.d.ts +13 -3
  27. package/dist/person/question/shared.js +52 -0
  28. package/dist/person/question/types.d.ts +121 -0
  29. package/dist/person/question/types.js +1 -0
  30. package/dist/person/rpc-handlers.d.ts +160 -0
  31. package/dist/person/rpc-handlers.js +62 -0
  32. package/dist/person/rpc.d.ts +227 -0
  33. package/dist/person/rpc.js +70 -0
  34. package/dist/person/text.d.ts +68 -0
  35. package/dist/person/text.js +262 -0
  36. package/dist/person/tools.d.ts +20 -0
  37. package/dist/person/tools.js +55 -0
  38. package/dist/person/tui.d.ts +46 -0
  39. package/dist/{bounded.d.ts → platform/bounded.d.ts} +4 -0
  40. package/dist/{bounded.js → platform/bounded.js} +4 -0
  41. package/dist/platform/events.d.ts +34 -0
  42. package/dist/platform/events.js +121 -0
  43. package/dist/platform/hub.d.ts +195 -0
  44. package/dist/{hub.js → platform/hub.js} +27 -71
  45. package/dist/{version.js → platform/version.js} +1 -1
  46. package/dist/rpc.d.ts +2 -0
  47. package/dist/rpc.js +3 -0
  48. package/dist/scheduling/index.d.ts +6 -0
  49. package/dist/scheduling/index.js +5 -0
  50. package/dist/{later.d.ts → scheduling/later.d.ts} +7 -3
  51. package/dist/{later.js → scheduling/later.js} +12 -4
  52. package/dist/scheduling/text.d.ts +6 -0
  53. package/dist/scheduling/text.js +10 -0
  54. package/dist/scheduling/tools.d.ts +14 -0
  55. package/dist/scheduling/tools.js +48 -0
  56. package/dist/skill.d.ts +4 -0
  57. package/dist/skill.js +54 -1
  58. package/dist/{cleanup.d.ts → tree/cleanup.d.ts} +1 -27
  59. package/dist/{cleanup.js → tree/cleanup.js} +9 -16
  60. package/dist/tree/context.d.ts +15 -0
  61. package/dist/tree/context.js +34 -0
  62. package/dist/tree/domain.d.ts +101 -0
  63. package/dist/tree/domain.js +68 -0
  64. package/dist/{watch.d.ts → tree/events.d.ts} +10 -37
  65. package/dist/tree/events.js +204 -0
  66. package/dist/tree/forget.d.ts +24 -0
  67. package/dist/tree/forget.js +59 -0
  68. package/dist/tree/group.d.ts +82 -0
  69. package/dist/tree/group.js +203 -0
  70. package/dist/tree/index.d.ts +10 -0
  71. package/dist/tree/index.js +11 -0
  72. package/dist/tree/limits.d.ts +10 -0
  73. package/dist/{limits.js → tree/limits.js} +6 -55
  74. package/dist/tree/panel.d.ts +13 -0
  75. package/dist/tree/panel.js +75 -0
  76. package/dist/tree/ports.d.ts +276 -0
  77. package/dist/tree/ports.js +1 -0
  78. package/dist/tree/report.d.ts +23 -0
  79. package/dist/tree/report.js +33 -0
  80. package/dist/tree/roster.d.ts +27 -0
  81. package/dist/tree/roster.js +62 -0
  82. package/dist/tree/rpc-handlers.d.ts +201 -0
  83. package/dist/tree/rpc-handlers.js +20 -0
  84. package/dist/tree/rpc.d.ts +344 -0
  85. package/dist/tree/rpc.js +83 -0
  86. package/dist/tree/send.d.ts +14 -0
  87. package/dist/tree/send.js +99 -0
  88. package/dist/tree/spawn.d.ts +21 -0
  89. package/dist/tree/spawn.js +173 -0
  90. package/dist/tree/status.d.ts +128 -0
  91. package/dist/tree/status.js +62 -0
  92. package/dist/{stop.d.ts → tree/stop.d.ts} +1 -9
  93. package/dist/{stop.js → tree/stop.js} +9 -13
  94. package/dist/tree/store.d.ts +24 -0
  95. package/dist/tree/store.js +264 -0
  96. package/dist/{tree.d.ts → tree/subtree.d.ts} +5 -6
  97. package/dist/{tree.js → tree/subtree.js} +7 -5
  98. package/dist/tree/summary.d.ts +7 -0
  99. package/dist/tree/summary.js +35 -0
  100. package/dist/tree/text.d.ts +77 -0
  101. package/dist/tree/text.js +287 -0
  102. package/dist/tree/tools.d.ts +54 -0
  103. package/dist/{tools.js → tree/tools.js} +12 -142
  104. package/dist/tree/tui.d.ts +53 -0
  105. package/dist/tui.d.ts +3 -0
  106. package/dist/tui.js +1342 -0
  107. package/dist/webhook/index.d.ts +5 -0
  108. package/dist/webhook/index.js +3 -0
  109. package/dist/{webhook.d.ts → webhook/receiver.d.ts} +17 -23
  110. package/dist/{webhook.js → webhook/receiver.js} +58 -50
  111. package/dist/webhook/subscriptions.d.ts +29 -0
  112. package/dist/webhook/subscriptions.js +52 -0
  113. package/dist/webhook/text.d.ts +23 -0
  114. package/dist/webhook/text.js +82 -0
  115. package/dist/webhook/tools.d.ts +19 -0
  116. package/dist/webhook/tools.js +46 -0
  117. package/package.json +18 -7
  118. package/dist/courier.d.ts +0 -200
  119. package/dist/courier.js +0 -315
  120. package/dist/group.d.ts +0 -86
  121. package/dist/group.js +0 -247
  122. package/dist/hub.d.ts +0 -300
  123. package/dist/limits.d.ts +0 -65
  124. package/dist/notices.d.ts +0 -356
  125. package/dist/notices.js +0 -678
  126. package/dist/question/index.d.ts +0 -6
  127. package/dist/question/shared.js +0 -24
  128. package/dist/report.d.ts +0 -48
  129. package/dist/report.js +0 -88
  130. package/dist/roster.d.ts +0 -93
  131. package/dist/roster.js +0 -206
  132. package/dist/tools.d.ts +0 -94
  133. package/dist/watch.js +0 -474
  134. /package/dist/{question → person/question}/lifecycle.js +0 -0
  135. /package/dist/{question → person/question}/runtime.d.ts +0 -0
  136. /package/dist/{question → person/question}/runtime.js +0 -0
  137. /package/dist/{json.d.ts → platform/json.d.ts} +0 -0
  138. /package/dist/{json.js → platform/json.js} +0 -0
  139. /package/dist/{storage.d.ts → platform/storage.d.ts} +0 -0
  140. /package/dist/{storage.js → platform/storage.js} +0 -0
  141. /package/dist/{version.d.ts → platform/version.d.ts} +0 -0
@@ -0,0 +1,62 @@
1
+ import { lineage, subtree } from "../tree/index.js";
2
+ import { pendingOf } from "./permission.js";
3
+ import { answerForPerson, pendingQuestions } from "./question/index.js";
4
+ import { personRpc } from "./rpc.js";
5
+ /**
6
+ * The permission requests and questions waiting in the courier tree a session is in, from the roster: read from the
7
+ * top of its lineage down, so each session of the tree sees the same inbox.
8
+ */
9
+ export async function asks(ports, sessionID) {
10
+ const { storage } = ports.questions;
11
+ const top = (await lineage(storage, sessionID)).at(-1)?.parentID ?? sessionID;
12
+ const { nodes, truncated } = await subtree(storage, top, ports.maxTotal);
13
+ const waiting = await Promise.all(nodes.map(({ entry }) => Promise.all([
14
+ pendingOf(ports.permissions(), entry.sessionID).catch(() => []),
15
+ pendingQuestions(storage, entry.sessionID).catch(() => []),
16
+ ])));
17
+ return {
18
+ top,
19
+ sessions: nodes.map(({ entry, depth }) => ({
20
+ sessionID: entry.sessionID,
21
+ title: entry.title,
22
+ parentID: entry.parentID,
23
+ depth,
24
+ ...(entry.group ? { group: entry.group } : {}),
25
+ })),
26
+ permissions: nodes.flatMap(({ entry }, index) => waiting[index][0].flatMap((pending) => pending.type === "permission"
27
+ ? [
28
+ {
29
+ sessionID: entry.sessionID,
30
+ requestID: pending.requestID,
31
+ action: pending.action,
32
+ resources: pending.resources,
33
+ ...(pending.save ? { save: pending.save } : {}),
34
+ },
35
+ ]
36
+ : [])),
37
+ questions: nodes.flatMap(({ entry }, index) => waiting[index][1].map(({ requestID, questions, stopped }) => ({
38
+ sessionID: entry.sessionID,
39
+ requestID,
40
+ questions,
41
+ ...(stopped ? { stopped } : {}),
42
+ }))),
43
+ ...(truncated ? { truncated: ports.maxTotal } : {}),
44
+ };
45
+ }
46
+ /** Passes the person's answers to a question on, as courier_answer does; a refusal, such as answers that do not fit, comes back as `problem`. */
47
+ export async function answer(ports, input) {
48
+ try {
49
+ const result = await answerForPerson(ports.questions, input);
50
+ return result.answered ? { answered: true, by: result.by } : { answered: false };
51
+ }
52
+ catch (error) {
53
+ return { answered: false, problem: error instanceof Error ? error.message : String(error) };
54
+ }
55
+ }
56
+ /** Serves the person's RPC at the plugin's location; disposed with the plugin. */
57
+ export function registerPersonRpc(rpc, ports) {
58
+ return rpc.register(personRpc, {
59
+ asks: ({ sessionID }) => asks(ports, sessionID),
60
+ answer: (input) => answer(ports, input),
61
+ });
62
+ }
@@ -0,0 +1,227 @@
1
+ import { Schema } from "effect";
2
+ /** A session of the tree, as the inbox names where an ask comes from. */
3
+ declare const Session: Schema.Struct<{
4
+ readonly sessionID: Schema.String;
5
+ readonly title: Schema.String;
6
+ readonly parentID: Schema.String;
7
+ /** A child of the tree's top session is at depth 1. */
8
+ readonly depth: Schema.Int;
9
+ readonly group: Schema.optionalKey<Schema.String>;
10
+ }>;
11
+ /** A permission request a session of the tree waits on. */
12
+ declare const Permission: Schema.Struct<{
13
+ readonly sessionID: Schema.String;
14
+ readonly requestID: Schema.String;
15
+ readonly action: Schema.String;
16
+ readonly resources: Schema.$Array<Schema.String>;
17
+ /** What "always" would allow from now on; absent when it is not offered. */
18
+ readonly save: Schema.optionalKey<Schema.$Array<Schema.String>>;
19
+ }>;
20
+ /** A question a session of the tree waits on; `stopped` when its call was cut off and the answer goes as a message. */
21
+ declare const Question: Schema.Struct<{
22
+ readonly sessionID: Schema.String;
23
+ readonly requestID: Schema.String;
24
+ readonly questions: Schema.$Array<Schema.Struct<{
25
+ readonly question: Schema.String;
26
+ readonly header: Schema.String;
27
+ readonly options: Schema.$Array<Schema.Struct<{
28
+ readonly label: Schema.String;
29
+ readonly description: Schema.String;
30
+ }>>;
31
+ readonly multiple: Schema.optionalKey<Schema.Boolean>;
32
+ }>>;
33
+ readonly stopped: Schema.optionalKey<Schema.Boolean>;
34
+ }>;
35
+ /** What the sessions of a courier tree wait on the person for, but forms, which the TUI lists itself. */
36
+ declare const Asks: Schema.Struct<{
37
+ /** The session at the top of the tree, which the sessions below were started from. */
38
+ readonly top: Schema.String;
39
+ /** The sessions below the top, in the order a tree is drawn. */
40
+ readonly sessions: Schema.$Array<Schema.Struct<{
41
+ readonly sessionID: Schema.String;
42
+ readonly title: Schema.String;
43
+ readonly parentID: Schema.String;
44
+ /** A child of the tree's top session is at depth 1. */
45
+ readonly depth: Schema.Int;
46
+ readonly group: Schema.optionalKey<Schema.String>;
47
+ }>>;
48
+ readonly permissions: Schema.$Array<Schema.Struct<{
49
+ readonly sessionID: Schema.String;
50
+ readonly requestID: Schema.String;
51
+ readonly action: Schema.String;
52
+ readonly resources: Schema.$Array<Schema.String>;
53
+ /** What "always" would allow from now on; absent when it is not offered. */
54
+ readonly save: Schema.optionalKey<Schema.$Array<Schema.String>>;
55
+ }>>;
56
+ readonly questions: Schema.$Array<Schema.Struct<{
57
+ readonly sessionID: Schema.String;
58
+ readonly requestID: Schema.String;
59
+ readonly questions: Schema.$Array<Schema.Struct<{
60
+ readonly question: Schema.String;
61
+ readonly header: Schema.String;
62
+ readonly options: Schema.$Array<Schema.Struct<{
63
+ readonly label: Schema.String;
64
+ readonly description: Schema.String;
65
+ }>>;
66
+ readonly multiple: Schema.optionalKey<Schema.Boolean>;
67
+ }>>;
68
+ readonly stopped: Schema.optionalKey<Schema.Boolean>;
69
+ }>>;
70
+ /** Set when the tree had more sessions than `maxTotal`, which were not read. */
71
+ readonly truncated: Schema.optionalKey<Schema.Int>;
72
+ }>;
73
+ export type Asks = typeof Asks.Type;
74
+ export type AskedQuestion = typeof Question.Type;
75
+ export type AskedPermission = typeof Permission.Type;
76
+ export type TreeSession = typeof Session.Type;
77
+ /** What answering a question did; `problem` says why nothing was passed on, when it was refused. */
78
+ declare const Answered: Schema.Struct<{
79
+ readonly answered: Schema.Boolean;
80
+ readonly by: Schema.optionalKey<Schema.Literals<readonly ["result", "message"]>>;
81
+ readonly problem: Schema.optionalKey<Schema.String>;
82
+ }>;
83
+ export type Answered = typeof Answered.Type;
84
+ export declare const personRpc: {
85
+ readonly id: "courier-person";
86
+ readonly methods: {
87
+ readonly asks: {
88
+ readonly input: import("effect/StandardSchema").StandardSchemaV1<{
89
+ readonly sessionID: string;
90
+ }, {
91
+ readonly sessionID: string;
92
+ }> & Schema.Struct<{
93
+ readonly sessionID: Schema.String;
94
+ }>;
95
+ readonly output: import("effect/StandardSchema").StandardSchemaV1<{
96
+ readonly questions: readonly {
97
+ readonly sessionID: string;
98
+ readonly requestID: string;
99
+ readonly questions: readonly {
100
+ readonly options: readonly {
101
+ readonly label: string;
102
+ readonly description: string;
103
+ }[];
104
+ readonly question: string;
105
+ readonly header: string;
106
+ readonly multiple?: boolean | undefined;
107
+ }[];
108
+ readonly stopped?: boolean | undefined;
109
+ }[];
110
+ readonly sessions: readonly {
111
+ readonly sessionID: string;
112
+ readonly title: string;
113
+ readonly parentID: string;
114
+ readonly depth: number;
115
+ readonly group?: string | undefined;
116
+ }[];
117
+ readonly permissions: readonly {
118
+ readonly sessionID: string;
119
+ readonly resources: readonly string[];
120
+ readonly requestID: string;
121
+ readonly action: string;
122
+ readonly save?: readonly string[] | undefined;
123
+ }[];
124
+ readonly top: string;
125
+ readonly truncated?: number | undefined;
126
+ }, {
127
+ readonly questions: readonly {
128
+ readonly sessionID: string;
129
+ readonly requestID: string;
130
+ readonly questions: readonly {
131
+ readonly options: readonly {
132
+ readonly label: string;
133
+ readonly description: string;
134
+ }[];
135
+ readonly question: string;
136
+ readonly header: string;
137
+ readonly multiple?: boolean | undefined;
138
+ }[];
139
+ readonly stopped?: boolean | undefined;
140
+ }[];
141
+ readonly sessions: readonly {
142
+ readonly sessionID: string;
143
+ readonly title: string;
144
+ readonly parentID: string;
145
+ readonly depth: number;
146
+ readonly group?: string | undefined;
147
+ }[];
148
+ readonly permissions: readonly {
149
+ readonly sessionID: string;
150
+ readonly resources: readonly string[];
151
+ readonly requestID: string;
152
+ readonly action: string;
153
+ readonly save?: readonly string[] | undefined;
154
+ }[];
155
+ readonly top: string;
156
+ readonly truncated?: number | undefined;
157
+ }> & Schema.Struct<{
158
+ /** The session at the top of the tree, which the sessions below were started from. */
159
+ readonly top: Schema.String;
160
+ /** The sessions below the top, in the order a tree is drawn. */
161
+ readonly sessions: Schema.$Array<Schema.Struct<{
162
+ readonly sessionID: Schema.String;
163
+ readonly title: Schema.String;
164
+ readonly parentID: Schema.String;
165
+ /** A child of the tree's top session is at depth 1. */
166
+ readonly depth: Schema.Int;
167
+ readonly group: Schema.optionalKey<Schema.String>;
168
+ }>>;
169
+ readonly permissions: Schema.$Array<Schema.Struct<{
170
+ readonly sessionID: Schema.String;
171
+ readonly requestID: Schema.String;
172
+ readonly action: Schema.String;
173
+ readonly resources: Schema.$Array<Schema.String>;
174
+ /** What "always" would allow from now on; absent when it is not offered. */
175
+ readonly save: Schema.optionalKey<Schema.$Array<Schema.String>>;
176
+ }>>;
177
+ readonly questions: Schema.$Array<Schema.Struct<{
178
+ readonly sessionID: Schema.String;
179
+ readonly requestID: Schema.String;
180
+ readonly questions: Schema.$Array<Schema.Struct<{
181
+ readonly question: Schema.String;
182
+ readonly header: Schema.String;
183
+ readonly options: Schema.$Array<Schema.Struct<{
184
+ readonly label: Schema.String;
185
+ readonly description: Schema.String;
186
+ }>>;
187
+ readonly multiple: Schema.optionalKey<Schema.Boolean>;
188
+ }>>;
189
+ readonly stopped: Schema.optionalKey<Schema.Boolean>;
190
+ }>>;
191
+ /** Set when the tree had more sessions than `maxTotal`, which were not read. */
192
+ readonly truncated: Schema.optionalKey<Schema.Int>;
193
+ }>;
194
+ };
195
+ readonly answer: {
196
+ readonly input: import("effect/StandardSchema").StandardSchemaV1<{
197
+ readonly sessionID: string;
198
+ readonly requestID: string;
199
+ readonly answers: readonly (readonly string[])[];
200
+ }, {
201
+ readonly sessionID: string;
202
+ readonly requestID: string;
203
+ readonly answers: readonly (readonly string[])[];
204
+ }> & Schema.Struct<{
205
+ readonly sessionID: Schema.String;
206
+ readonly requestID: Schema.String;
207
+ readonly answers: Schema.$Array<Schema.$Array<Schema.String>>;
208
+ }>;
209
+ readonly output: import("effect/StandardSchema").StandardSchemaV1<{
210
+ readonly answered: boolean;
211
+ readonly by?: "result" | "message" | undefined;
212
+ readonly problem?: string | undefined;
213
+ }, {
214
+ readonly answered: boolean;
215
+ readonly by?: "result" | "message" | undefined;
216
+ readonly problem?: string | undefined;
217
+ }> & Schema.Struct<{
218
+ readonly answered: Schema.Boolean;
219
+ readonly by: Schema.optionalKey<Schema.Literals<readonly ["result", "message"]>>;
220
+ readonly problem: Schema.optionalKey<Schema.String>;
221
+ }>;
222
+ };
223
+ };
224
+ readonly events: {};
225
+ };
226
+ export type PersonRpc = typeof personRpc;
227
+ export {};
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The person's RPC, the contract its TUI part, the asks inbox, and its server half share. Standard Schema values,
3
+ * as the tree's; imports only `@opencode/plugin/rpc` and `effect`.
4
+ */
5
+ import { Rpc } from "@opencode/plugin/rpc";
6
+ import { Schema } from "effect";
7
+ const Count = Schema.Int.check(Schema.isGreaterThanOrEqualTo(0));
8
+ /** A session of the tree, as the inbox names where an ask comes from. */
9
+ const Session = Schema.Struct({
10
+ sessionID: Schema.String,
11
+ title: Schema.String,
12
+ parentID: Schema.String,
13
+ /** A child of the tree's top session is at depth 1. */
14
+ depth: Count,
15
+ group: Schema.optionalKey(Schema.String),
16
+ });
17
+ /** A permission request a session of the tree waits on. */
18
+ const Permission = Schema.Struct({
19
+ sessionID: Schema.String,
20
+ requestID: Schema.String,
21
+ action: Schema.String,
22
+ resources: Schema.Array(Schema.String),
23
+ /** What "always" would allow from now on; absent when it is not offered. */
24
+ save: Schema.optionalKey(Schema.Array(Schema.String)),
25
+ });
26
+ /** One question of OpenCode's question tool. */
27
+ const Prompt = Schema.Struct({
28
+ question: Schema.String,
29
+ header: Schema.String,
30
+ options: Schema.Array(Schema.Struct({ label: Schema.String, description: Schema.String })),
31
+ multiple: Schema.optionalKey(Schema.Boolean),
32
+ });
33
+ /** A question a session of the tree waits on; `stopped` when its call was cut off and the answer goes as a message. */
34
+ const Question = Schema.Struct({
35
+ sessionID: Schema.String,
36
+ requestID: Schema.String,
37
+ questions: Schema.Array(Prompt),
38
+ stopped: Schema.optionalKey(Schema.Boolean),
39
+ });
40
+ /** What the sessions of a courier tree wait on the person for, but forms, which the TUI lists itself. */
41
+ const Asks = Schema.Struct({
42
+ /** The session at the top of the tree, which the sessions below were started from. */
43
+ top: Schema.String,
44
+ /** The sessions below the top, in the order a tree is drawn. */
45
+ sessions: Schema.Array(Session),
46
+ permissions: Schema.Array(Permission),
47
+ questions: Schema.Array(Question),
48
+ /** Set when the tree had more sessions than `maxTotal`, which were not read. */
49
+ truncated: Schema.optionalKey(Count),
50
+ });
51
+ /** What answering a question did; `problem` says why nothing was passed on, when it was refused. */
52
+ const Answered = Schema.Struct({
53
+ answered: Schema.Boolean,
54
+ by: Schema.optionalKey(Schema.Literals(["result", "message"])),
55
+ problem: Schema.optionalKey(Schema.String),
56
+ });
57
+ export const personRpc = Rpc.define({
58
+ id: "courier-person",
59
+ methods: {
60
+ asks: {
61
+ input: Schema.toStandardSchemaV1(Schema.Struct({ sessionID: Schema.String })),
62
+ output: Schema.toStandardSchemaV1(Asks),
63
+ },
64
+ answer: {
65
+ input: Schema.toStandardSchemaV1(Schema.Struct({ sessionID: Schema.String, requestID: Schema.String, answers: Schema.Array(Schema.Array(Schema.String)) })),
66
+ output: Schema.toStandardSchemaV1(Answered),
67
+ },
68
+ },
69
+ events: {},
70
+ });
@@ -0,0 +1,68 @@
1
+ import type { Asked, Elsewhere, Form, Outcome, PermissionAnswered, PermissionRequest, Prompt, QuestionAnswered, Reply, Withdrawal } from "./ports.js";
2
+ /**
3
+ * What courier_answer did: a permission request's result carries the reply, a question's whether its
4
+ * answers went out as the result of its call or, since that call had been cut off, as a message.
5
+ */
6
+ export type AnswerResult = PermissionAnswered | QuestionAnswered;
7
+ export declare function answerText(result: AnswerResult): string;
8
+ /**
9
+ * Sent with a rejection that has no reason of its own. OpenCode ends the child's turn on a bare
10
+ * rejection, and the child would never report back; with a message, the call fails and it carries on.
11
+ */
12
+ export declare const REJECTED = "Refused by the session that started you. Do without it, or report back why you cannot.";
13
+ /** How a notice names where the asking session came from, to the session at the top of its lineage. */
14
+ export declare const origin: (startedBy?: string) => string;
15
+ /** For a notice that a session's turn ended without it finishing. */
16
+ export declare const STAYS_QUIET = "and then it does not report back on its own: if it stays quiet, message it with courier_send to have it carry on.";
17
+ /**
18
+ * What the session at the top is told. `startedBy` names the session that started the asking one
19
+ * when that is not the top session itself, but one started from it.
20
+ */
21
+ export declare function permissionNotice(title: string, request: PermissionRequest, startedBy?: string, native?: boolean): string;
22
+ /** What the session told about a permission request is told once it is answered without courier_answer. */
23
+ export declare function permissionSettledNotice(title: string, requestID: string, reply: Reply): string;
24
+ /** The `metadata.kind` of the forms OpenCode's web search asks its provider with. */
25
+ export declare const WEBSEARCH_FORM = "websearch.provider";
26
+ /** A form's `metadata.kind`, when it has one that can go in a notice's envelope. */
27
+ export declare const kindOf: (form: Form) => string | undefined;
28
+ /**
29
+ * What the session at the top is told about a form OpenCode shows in a session started with
30
+ * courier_spawn, which the plugin cannot pass on or answer: only the person can, where OpenCode shows it.
31
+ */
32
+ export declare function formNotice(title: string, form: Form, startedBy?: string, shownIn?: string, top?: string): string;
33
+ /** What the session told about a form is told once it is answered or withdrawn. */
34
+ export declare function formSettledNotice(title: string, formID: string, settled: "answered" | "cancelled"): string;
35
+ /** What OpenCode's question tool tells the asking model once it has the answers. */
36
+ export declare function answeredText(questions: ReadonlyArray<Prompt>, answers: ReadonlyArray<ReadonlyArray<string>>): string;
37
+ declare const CUT_OFF: {
38
+ stopped: string;
39
+ restarted: string;
40
+ };
41
+ /** Why a question's call was cut off: its turn was stopped, or OpenCode restarted or closed its location. */
42
+ export type CutOff = keyof typeof CUT_OFF;
43
+ /** What the top session is told about a question, when it is asked or after its call was cut off. */
44
+ export declare function questionNotice(asked: Asked, cutOff?: CutOff): string;
45
+ /**
46
+ * What the top session is told about a native child's question, which OpenCode shows the person in the
47
+ * top session's own view: they answer it there, so the top session does not ask them again.
48
+ */
49
+ export declare function nativeQuestionNotice(asked: Asked): string;
50
+ /** What the top session is told about a question settled without it. */
51
+ export declare function questionSettledNotice(asked: Asked, how: Elsewhere): string;
52
+ /** The result of a spawned session's question call that the person dismissed through the top session. */
53
+ export declare const DISMISSED = "The person dismissed this question without answering it. Carry on without the answers, or report back with courier_send to the session that started you why you cannot.";
54
+ /** The message a spawned session whose question call was cut off gets, with the top session's outcome. */
55
+ export declare function cutOffAnswer(asked: Asked, outcome: Outcome): string;
56
+ /**
57
+ * What a top session's question call that no waiting question was linked to adds to its result, when
58
+ * questions with the same choices wait: `waiting` lists them.
59
+ */
60
+ export declare function unlinkedNote(waiting: ReadonlyArray<Pick<Asked, "sessionID" | "requestID">>): string;
61
+ /** The result of a linked call withdrawn because its question was settled without it. */
62
+ export declare function withdrawnText(linked: Asked, how: Withdrawal): string;
63
+ /**
64
+ * What a linked call adds to the person's answers about passing them on: `passed` is "result",
65
+ * "message", undefined when it no longer waited, or the error as `error: <message>`.
66
+ */
67
+ export declare function passedNote(linked: Asked, passed: string | undefined): string;
68
+ export {};