zcode-acp-server 0.1.0 → 0.3.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 (223) hide show
  1. package/README.md +192 -9
  2. package/README.zh-CN.md +143 -8
  3. package/dist/backend/client.d.ts +12 -4
  4. package/dist/backend/client.d.ts.map +1 -1
  5. package/dist/backend/client.js +72 -7
  6. package/dist/backend/client.js.map +1 -1
  7. package/dist/backend/credentials.d.ts.map +1 -1
  8. package/dist/backend/credentials.js +2 -1
  9. package/dist/backend/credentials.js.map +1 -1
  10. package/dist/backend/listener.d.ts +12 -4
  11. package/dist/backend/listener.d.ts.map +1 -1
  12. package/dist/backend/listener.js +68 -12
  13. package/dist/backend/listener.js.map +1 -1
  14. package/dist/backend/types.d.ts +1 -1
  15. package/dist/backend/types.d.ts.map +1 -1
  16. package/dist/bin/hub.d.ts +16 -0
  17. package/dist/bin/hub.d.ts.map +1 -0
  18. package/dist/bin/hub.js +41 -0
  19. package/dist/bin/hub.js.map +1 -0
  20. package/dist/bin/quota.d.ts +54 -0
  21. package/dist/bin/quota.d.ts.map +1 -0
  22. package/dist/bin/quota.js +333 -0
  23. package/dist/bin/quota.js.map +1 -0
  24. package/dist/config/auto-compact.d.ts +23 -0
  25. package/dist/config/auto-compact.d.ts.map +1 -0
  26. package/dist/config/auto-compact.js +67 -0
  27. package/dist/config/auto-compact.js.map +1 -0
  28. package/dist/config/mcp-discovery.d.ts +34 -0
  29. package/dist/config/mcp-discovery.d.ts.map +1 -0
  30. package/dist/config/mcp-discovery.js +153 -0
  31. package/dist/config/mcp-discovery.js.map +1 -0
  32. package/dist/config/model-cache.d.ts +12 -1
  33. package/dist/config/model-cache.d.ts.map +1 -1
  34. package/dist/config/model-cache.js +30 -8
  35. package/dist/config/model-cache.js.map +1 -1
  36. package/dist/config/options.d.ts +87 -9
  37. package/dist/config/options.d.ts.map +1 -1
  38. package/dist/config/options.js +248 -45
  39. package/dist/config/options.js.map +1 -1
  40. package/dist/config/plugin-commands.d.ts +24 -0
  41. package/dist/config/plugin-commands.d.ts.map +1 -0
  42. package/dist/config/plugin-commands.js +107 -0
  43. package/dist/config/plugin-commands.js.map +1 -0
  44. package/dist/config/provider-registry.d.ts +60 -0
  45. package/dist/config/provider-registry.d.ts.map +1 -0
  46. package/dist/config/provider-registry.js +128 -0
  47. package/dist/config/provider-registry.js.map +1 -0
  48. package/dist/config/runtime-model.d.ts +54 -18
  49. package/dist/config/runtime-model.d.ts.map +1 -1
  50. package/dist/config/runtime-model.js +105 -61
  51. package/dist/config/runtime-model.js.map +1 -1
  52. package/dist/config/skill-discovery.d.ts +35 -0
  53. package/dist/config/skill-discovery.d.ts.map +1 -0
  54. package/dist/config/skill-discovery.js +188 -0
  55. package/dist/config/skill-discovery.js.map +1 -0
  56. package/dist/handlers/account.d.ts +43 -0
  57. package/dist/handlers/account.d.ts.map +1 -0
  58. package/dist/handlers/account.js +59 -0
  59. package/dist/handlers/account.js.map +1 -0
  60. package/dist/handlers/background-tasks.d.ts +72 -0
  61. package/dist/handlers/background-tasks.d.ts.map +1 -0
  62. package/dist/handlers/background-tasks.js +330 -0
  63. package/dist/handlers/background-tasks.js.map +1 -0
  64. package/dist/handlers/dispatch.d.ts.map +1 -1
  65. package/dist/handlers/dispatch.js +134 -22
  66. package/dist/handlers/dispatch.js.map +1 -1
  67. package/dist/handlers/extensions.d.ts +15 -0
  68. package/dist/handlers/extensions.d.ts.map +1 -1
  69. package/dist/handlers/extensions.js +43 -27
  70. package/dist/handlers/extensions.js.map +1 -1
  71. package/dist/handlers/io.d.ts +31 -3
  72. package/dist/handlers/io.d.ts.map +1 -1
  73. package/dist/handlers/io.js +108 -9
  74. package/dist/handlers/io.js.map +1 -1
  75. package/dist/handlers/replay.d.ts +79 -0
  76. package/dist/handlers/replay.d.ts.map +1 -0
  77. package/dist/handlers/replay.js +252 -0
  78. package/dist/handlers/replay.js.map +1 -0
  79. package/dist/handlers/server-requests.d.ts +20 -4
  80. package/dist/handlers/server-requests.d.ts.map +1 -1
  81. package/dist/handlers/server-requests.js +293 -63
  82. package/dist/handlers/server-requests.js.map +1 -1
  83. package/dist/handlers/session.d.ts +113 -10
  84. package/dist/handlers/session.d.ts.map +1 -1
  85. package/dist/handlers/session.js +932 -277
  86. package/dist/handlers/session.js.map +1 -1
  87. package/dist/handlers/slash.d.ts +37 -1
  88. package/dist/handlers/slash.d.ts.map +1 -1
  89. package/dist/handlers/slash.js +143 -8
  90. package/dist/handlers/slash.js.map +1 -1
  91. package/dist/index.js +76 -12
  92. package/dist/index.js.map +1 -1
  93. package/dist/interaction/adapter.d.ts +19 -33
  94. package/dist/interaction/adapter.d.ts.map +1 -1
  95. package/dist/interaction/adapter.js +80 -79
  96. package/dist/interaction/adapter.js.map +1 -1
  97. package/dist/lazy-sessions.d.ts +35 -0
  98. package/dist/lazy-sessions.d.ts.map +1 -0
  99. package/dist/lazy-sessions.js +98 -0
  100. package/dist/lazy-sessions.js.map +1 -0
  101. package/dist/quota/cache.d.ts +18 -0
  102. package/dist/quota/cache.d.ts.map +1 -0
  103. package/dist/quota/cache.js +32 -0
  104. package/dist/quota/cache.js.map +1 -0
  105. package/dist/quota/client.d.ts +30 -0
  106. package/dist/quota/client.d.ts.map +1 -0
  107. package/dist/quota/client.js +57 -0
  108. package/dist/quota/client.js.map +1 -0
  109. package/dist/quota/color.d.ts +58 -0
  110. package/dist/quota/color.d.ts.map +1 -0
  111. package/dist/quota/color.js +95 -0
  112. package/dist/quota/color.js.map +1 -0
  113. package/dist/quota/combined.d.ts +66 -0
  114. package/dist/quota/combined.d.ts.map +1 -0
  115. package/dist/quota/combined.js +179 -0
  116. package/dist/quota/combined.js.map +1 -0
  117. package/dist/quota/format.d.ts +105 -0
  118. package/dist/quota/format.d.ts.map +1 -0
  119. package/dist/quota/format.js +219 -0
  120. package/dist/quota/format.js.map +1 -0
  121. package/dist/quota/index.d.ts +23 -0
  122. package/dist/quota/index.d.ts.map +1 -0
  123. package/dist/quota/index.js +42 -0
  124. package/dist/quota/index.js.map +1 -0
  125. package/dist/quota/opencode-go/cache.d.ts +17 -0
  126. package/dist/quota/opencode-go/cache.d.ts.map +1 -0
  127. package/dist/quota/opencode-go/cache.js +31 -0
  128. package/dist/quota/opencode-go/cache.js.map +1 -0
  129. package/dist/quota/opencode-go/client.d.ts +28 -0
  130. package/dist/quota/opencode-go/client.d.ts.map +1 -0
  131. package/dist/quota/opencode-go/client.js +48 -0
  132. package/dist/quota/opencode-go/client.js.map +1 -0
  133. package/dist/quota/opencode-go/config.d.ts +37 -0
  134. package/dist/quota/opencode-go/config.d.ts.map +1 -0
  135. package/dist/quota/opencode-go/config.js +58 -0
  136. package/dist/quota/opencode-go/config.js.map +1 -0
  137. package/dist/quota/opencode-go/format.d.ts +36 -0
  138. package/dist/quota/opencode-go/format.d.ts.map +1 -0
  139. package/dist/quota/opencode-go/format.js +87 -0
  140. package/dist/quota/opencode-go/format.js.map +1 -0
  141. package/dist/quota/opencode-go/index.d.ts +30 -0
  142. package/dist/quota/opencode-go/index.d.ts.map +1 -0
  143. package/dist/quota/opencode-go/index.js +108 -0
  144. package/dist/quota/opencode-go/index.js.map +1 -0
  145. package/dist/quota/opencode-go/parse.d.ts +41 -0
  146. package/dist/quota/opencode-go/parse.d.ts.map +1 -0
  147. package/dist/quota/opencode-go/parse.js +75 -0
  148. package/dist/quota/opencode-go/parse.js.map +1 -0
  149. package/dist/quota/opencode-go/types.d.ts +48 -0
  150. package/dist/quota/opencode-go/types.d.ts.map +1 -0
  151. package/dist/quota/opencode-go/types.js +11 -0
  152. package/dist/quota/opencode-go/types.js.map +1 -0
  153. package/dist/quota/parse.d.ts +33 -0
  154. package/dist/quota/parse.d.ts.map +1 -0
  155. package/dist/quota/parse.js +200 -0
  156. package/dist/quota/parse.js.map +1 -0
  157. package/dist/quota/types.d.ts +72 -0
  158. package/dist/quota/types.d.ts.map +1 -0
  159. package/dist/quota/types.js +10 -0
  160. package/dist/quota/types.js.map +1 -0
  161. package/dist/remote/broadcast.d.ts +47 -0
  162. package/dist/remote/broadcast.d.ts.map +1 -0
  163. package/dist/remote/broadcast.js +121 -0
  164. package/dist/remote/broadcast.js.map +1 -0
  165. package/dist/remote/config.d.ts +32 -0
  166. package/dist/remote/config.d.ts.map +1 -0
  167. package/dist/remote/config.js +65 -0
  168. package/dist/remote/config.js.map +1 -0
  169. package/dist/remote/endpoint.d.ts +30 -0
  170. package/dist/remote/endpoint.d.ts.map +1 -0
  171. package/dist/remote/endpoint.js +213 -0
  172. package/dist/remote/endpoint.js.map +1 -0
  173. package/dist/remote/hub-server.d.ts +41 -0
  174. package/dist/remote/hub-server.d.ts.map +1 -0
  175. package/dist/remote/hub-server.js +346 -0
  176. package/dist/remote/hub-server.js.map +1 -0
  177. package/dist/server.d.ts +139 -1
  178. package/dist/server.d.ts.map +1 -1
  179. package/dist/server.js +179 -4
  180. package/dist/server.js.map +1 -1
  181. package/dist/tasks-index.d.ts +14 -4
  182. package/dist/tasks-index.d.ts.map +1 -1
  183. package/dist/tasks-index.js +145 -46
  184. package/dist/tasks-index.js.map +1 -1
  185. package/dist/translators/event-translator.d.ts +33 -0
  186. package/dist/translators/event-translator.d.ts.map +1 -1
  187. package/dist/translators/event-translator.js +101 -0
  188. package/dist/translators/event-translator.js.map +1 -1
  189. package/dist/translators/index.d.ts +1 -1
  190. package/dist/translators/index.d.ts.map +1 -1
  191. package/dist/translators/index.js +1 -1
  192. package/dist/translators/index.js.map +1 -1
  193. package/dist/translators/projection-differ.d.ts +8 -0
  194. package/dist/translators/projection-differ.d.ts.map +1 -1
  195. package/dist/translators/projection-differ.js +19 -9
  196. package/dist/translators/projection-differ.js.map +1 -1
  197. package/dist/translators/tool-helpers.d.ts +28 -0
  198. package/dist/translators/tool-helpers.d.ts.map +1 -1
  199. package/dist/translators/tool-helpers.js +104 -0
  200. package/dist/translators/tool-helpers.js.map +1 -1
  201. package/dist/translators/types.d.ts +38 -1
  202. package/dist/translators/types.d.ts.map +1 -1
  203. package/dist/translators/types.js.map +1 -1
  204. package/dist/utils.d.ts +36 -7
  205. package/dist/utils.d.ts.map +1 -1
  206. package/dist/utils.js +69 -5
  207. package/dist/utils.js.map +1 -1
  208. package/docs/ARCHITECTURE.md +130 -40
  209. package/docs/BACKLOG.md +59 -0
  210. package/docs/DEVELOPMENT.md +31 -0
  211. package/docs/PROTOCOL.md +328 -23
  212. package/docs/REMOTE-CLIENTS.md +260 -0
  213. package/docs/REPLAY-GUIDE.md +131 -0
  214. package/docs/TROUBLESHOOTING.md +131 -14
  215. package/docs/adr/0001-bridge-lifetime-follows-primary-client.md +14 -0
  216. package/docs/adr/0002-stateless-hub-over-per-bridge-acp-endpoints.md +23 -0
  217. package/docs/adr/0003-tail-replay-meta-and-cursor-pagination.md +40 -0
  218. package/docs/agents/domain.md +51 -0
  219. package/docs/agents/issue-tracker.md +22 -0
  220. package/docs/agents/triage-labels.md +15 -0
  221. package/docs/proposals/0001-tail-session-replay.md +136 -0
  222. package/docs/proposals/0002-plan-quota-usage.md +81 -0
  223. package/package.json +10 -6
@@ -0,0 +1,252 @@
1
+ /**
2
+ * Tail replay kernel — slicing, cursor pagination, and the `session/load`
3
+ * replay/`session/load_earlier` handlers (Proposal 0001 / ADR-0003).
4
+ *
5
+ * session/load replays history as session/update notifications; for long
6
+ * sessions that cost is O(full history) on every attach and reconnect. The
7
+ * helpers here slice the fetched messages into turn-aligned batches and page
8
+ * backwards with an opaque cursor. Batches are sent under the per-session
9
+ * replay lock (`withReplayBatch` in io.ts) so a batch never interleaves with
10
+ * live-turn updates for the same session; `replayMessages` is the one sender
11
+ * that bypasses the per-message lock — it only runs inside a batch.
12
+ */
13
+ import { randomUUID } from "node:crypto";
14
+ import { log } from "../utils.js";
15
+ import { throwError, withReplayBatch } from "./io.js";
16
+ /** Upper bound for a requested tail/page size (values above clamp to this). */
17
+ export const MAX_REPLAY_LIMIT = 500;
18
+ /** Page size for `session/load_earlier` when the request omits `limit`. */
19
+ export const DEFAULT_EARLIER_LIMIT = 50;
20
+ /**
21
+ * Indices where a turn starts: every user message, plus 0 so leading
22
+ * non-user messages (system preambles) belong to the first turn.
23
+ */
24
+ function turnStarts(messages) {
25
+ const starts = messages.length > 0 ? [0] : [];
26
+ messages.forEach((m, i) => {
27
+ if (m.info?.role === "user" && i > 0)
28
+ starts.push(i);
29
+ });
30
+ return starts;
31
+ }
32
+ /** Count of turn starts inside [start, end). */
33
+ function turnsInRange(starts, start, end) {
34
+ return starts.filter((s) => s >= start && s < end).length;
35
+ }
36
+ function encodeCursor(messages, index, totalTurns) {
37
+ const anchor = messages[index]?.info?.id;
38
+ const payload = { v: 1, index, totalTurns };
39
+ if (anchor)
40
+ payload.id = anchor;
41
+ return Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
42
+ }
43
+ function decodeCursor(before) {
44
+ try {
45
+ const raw = JSON.parse(Buffer.from(before, "base64url").toString("utf8"));
46
+ if (raw?.v !== 1 ||
47
+ !Number.isInteger(raw.index) ||
48
+ raw.index < 0 ||
49
+ !Number.isInteger(raw.totalTurns)) {
50
+ throw new Error("bad shape");
51
+ }
52
+ return raw;
53
+ }
54
+ catch {
55
+ // Garbage or foreign cursors are indistinguishable from expired ones.
56
+ return throwError(-32602, "cursor expired");
57
+ }
58
+ }
59
+ function buildSlice(messages, starts, start, end) {
60
+ const totalTurns = starts.length;
61
+ return {
62
+ batch: messages.slice(start, end),
63
+ meta: {
64
+ cursor: encodeCursor(messages, start, totalTurns),
65
+ hasMore: start > 0,
66
+ replayedMessages: end - start,
67
+ replayedTurns: turnsInRange(starts, start, end),
68
+ totalMessages: messages.length,
69
+ totalTurns,
70
+ },
71
+ };
72
+ }
73
+ /** The greatest turn start at or before `pos` (0 when none — starts include 0). */
74
+ function alignToTurnStart(starts, pos) {
75
+ let aligned = 0;
76
+ for (const s of starts) {
77
+ if (s <= pos)
78
+ aligned = s;
79
+ else
80
+ break;
81
+ }
82
+ return aligned;
83
+ }
84
+ function clampLimit(limit) {
85
+ return Math.max(0, Math.min(Math.floor(limit), MAX_REPLAY_LIMIT));
86
+ }
87
+ /**
88
+ * Slice the last `limit` messages, aligned back to the start of the turn
89
+ * containing the oldest one — never a mid-turn cut. `limit: 0` attaches with
90
+ * metadata only (cursor anchors at the end of history).
91
+ */
92
+ export function sliceTail(messages, limit) {
93
+ const starts = turnStarts(messages);
94
+ const clamped = clampLimit(limit);
95
+ if (clamped === 0) {
96
+ // Metadata-only attach: an empty batch whose cursor anchors at the end of
97
+ // history, so load_earlier pages the whole tail.
98
+ return buildSlice(messages, starts, messages.length, messages.length);
99
+ }
100
+ if (clamped >= messages.length)
101
+ return buildSlice(messages, starts, 0, messages.length);
102
+ const start = alignToTurnStart(starts, messages.length - clamped);
103
+ return buildSlice(messages, starts, start, messages.length);
104
+ }
105
+ /** Full-history slice (no `_meta.zcode.limit` on session/load). */
106
+ export function fullSlice(messages) {
107
+ return buildSlice(messages, turnStarts(messages), 0, messages.length);
108
+ }
109
+ /**
110
+ * Slice up to `limit` messages strictly older than the `before` cursor.
111
+ * The cursor points into a prefix of history, so turns appended after it was
112
+ * minted keep it valid; only a history that shrank (compaction/truncation)
113
+ * throws `cursor expired` — clients map that to a full re-`session/load`.
114
+ */
115
+ export function sliceBefore(messages, before, limit) {
116
+ const starts = turnStarts(messages);
117
+ const cur = decodeCursor(before);
118
+ if (cur.index > messages.length || cur.totalTurns > starts.length) {
119
+ return throwError(-32602, "cursor expired");
120
+ }
121
+ if (cur.id != null && cur.index < messages.length && messages[cur.index].info?.id !== cur.id) {
122
+ return throwError(-32602, "cursor expired");
123
+ }
124
+ const end = cur.index;
125
+ if (end === 0)
126
+ return buildSlice(messages, starts, 0, 0);
127
+ const clamped = clampLimit(limit);
128
+ const start = clamped === 0 ? end : alignToTurnStart(starts, Math.max(0, end - clamped));
129
+ return buildSlice(messages, starts, start, end);
130
+ }
131
+ /**
132
+ * Read the tail limit from `session/load`'s `_meta.zcode.limit`. The SDK's
133
+ * zod params schema strips unknown top-level keys, so bridge extensions ride
134
+ * in `_meta` (ADR-0003). Returns null when absent/non-finite = full replay.
135
+ */
136
+ export function readTailLimit(params) {
137
+ const zcode = params._meta?.zcode;
138
+ const raw = zcode?.limit;
139
+ if (typeof raw !== "number" || !Number.isFinite(raw))
140
+ return null;
141
+ return clampLimit(raw);
142
+ }
143
+ /** Fetch session/messages from zcode (the bridge's only history source). */
144
+ export async function fetchMessages(server, zcodeSid) {
145
+ const backend = server.ensureBackend();
146
+ const resp = await backend.request(server.nextId(), "session/messages", { sessionId: zcodeSid }, 8000);
147
+ if (resp.error)
148
+ return [];
149
+ const result = (resp.result ?? {});
150
+ return result.messages ?? [];
151
+ }
152
+ /**
153
+ * Strip harness-injected reminder blocks from user text. The agent runtime
154
+ * appends `<system-reminder>…</system-reminder>` blocks (TodoWrite nudges,
155
+ * context handoffs) to user turns as context plumbing — they are not user
156
+ * speech, and replaying them verbatim makes clients render them as user input.
157
+ */
158
+ function stripSystemReminders(text) {
159
+ return text.replace(/<system-reminder>[\s\S]*?<\/system-reminder>/g, "").trim();
160
+ }
161
+ /**
162
+ * Replay messages as session/update notifications, oldest → newest.
163
+ *
164
+ * MUST run inside `withReplayBatch` for the session: this is the one sender
165
+ * that bypasses the per-message lock in sendSessionUpdate (the batch already
166
+ * holds it), which is what makes the batch atomic against live dispatch.
167
+ */
168
+ export async function replayMessages(cx, acpSid, messages) {
169
+ let replayed = 0;
170
+ for (const m of messages) {
171
+ const info = m.info ?? {};
172
+ const role = info.role;
173
+ const mid = info.id ?? `hist_${randomUUID().slice(0, 12)}`;
174
+ for (const p of m.parts ?? []) {
175
+ if (!p || typeof p !== "object")
176
+ continue;
177
+ const ptype = p.type;
178
+ if (ptype === "text") {
179
+ let text = p.text ?? "";
180
+ if (!text)
181
+ continue;
182
+ if (role === "user") {
183
+ text = stripSystemReminders(text);
184
+ if (!text)
185
+ continue;
186
+ }
187
+ await cx.notify("session/update", {
188
+ sessionId: acpSid,
189
+ update: {
190
+ sessionUpdate: role === "user" ? "user_message_chunk" : "agent_message_chunk",
191
+ content: { type: "text", text },
192
+ messageId: mid,
193
+ },
194
+ });
195
+ }
196
+ else if (ptype === "reasoning") {
197
+ const rp = p;
198
+ const text = rp.text ?? rp.content ?? "";
199
+ if (text) {
200
+ await cx.notify("session/update", {
201
+ sessionId: acpSid,
202
+ update: {
203
+ sessionUpdate: "agent_thought_chunk",
204
+ content: { type: "text", text },
205
+ messageId: `thought_${mid}`,
206
+ },
207
+ });
208
+ }
209
+ }
210
+ else if (ptype === "tool") {
211
+ const tp = p;
212
+ const title = tp.title ?? tp.tool ?? "tool call";
213
+ const histToolName = tp.tool ?? "";
214
+ await cx.notify("session/update", {
215
+ sessionId: acpSid,
216
+ update: {
217
+ sessionUpdate: "tool_call",
218
+ toolCallId: tp.id ?? `histtool_${randomUUID().slice(0, 8)}`,
219
+ title,
220
+ kind: "other",
221
+ status: tp.status ?? "completed",
222
+ ...(histToolName ? { _meta: { claudeCode: { toolName: histToolName } } } : {}),
223
+ },
224
+ });
225
+ }
226
+ // patch / step-start / other: skipped (history replay focuses on text + tool summary)
227
+ }
228
+ replayed += 1;
229
+ }
230
+ return replayed;
231
+ }
232
+ /**
233
+ * `session/load_earlier` — deliver one page of history strictly older than
234
+ * the `before` cursor, oldest → newest (clients prepend). Requires the
235
+ * session to already be attached in this bridge; pagination never triggers
236
+ * an implicit backend resume.
237
+ */
238
+ export async function loadEarlier(server, params, cx) {
239
+ const acpSid = params.sessionId;
240
+ const zcodeSid = server.resolveSid(acpSid);
241
+ if (!zcodeSid) {
242
+ return throwError(-32602, "session not registered — attach via session/load first");
243
+ }
244
+ if (!params.before)
245
+ return throwError(-32602, "before (cursor) required");
246
+ const messages = await fetchMessages(server, zcodeSid);
247
+ const slice = sliceBefore(messages, params.before, params.limit ?? DEFAULT_EARLIER_LIMIT);
248
+ await withReplayBatch(acpSid, () => replayMessages(cx, acpSid, slice.batch));
249
+ log(`session/load_earlier: ${slice.meta.replayedMessages} messages before cursor`);
250
+ return { replayMeta: slice.meta };
251
+ }
252
+ //# sourceMappingURL=replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/handlers/replay.ts"],"names":[],"mappings":"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"}
@@ -16,19 +16,35 @@
16
16
  */
17
17
  import type * as acp from "@agentclientprotocol/sdk";
18
18
  import type { ZcodeBackend } from "../backend/client.js";
19
- import type { ZcodeInteractionResponse } from "../backend/types.js";
19
+ import type { ZcodeInteractionResponse, ZcodeInteractionUserInputParams } from "../backend/types.js";
20
20
  import type { PendingTurn, ZcodeAcpServer } from "../server.js";
21
21
  /** A dedup entry tracking reannounced zcode ids + the cached result. */
22
22
  interface DedupEntry {
23
- zcodeIds: number[];
23
+ zcodeIds: Array<number | string>;
24
24
  result?: ZcodeInteractionResponse;
25
25
  }
26
26
  /** Per-server reannounce dedup state (lazy-initialised). */
27
27
  export declare function getPendingInteractions(server: ZcodeAcpServer): Map<string, DedupEntry>;
28
28
  /**
29
- * Drain and handle all pending zcode server→client requests. Returns true if
30
- * any were handled (used by the turn loop to refresh the no-progress timer).
29
+ * Drain and handle pending zcode server→client requests for THIS session only.
30
+ * Returns true if any were handled (used by the turn loop to refresh the
31
+ * no-progress timer).
32
+ *
33
+ * The backend's `serverRequests` queue is shared across all sessions (a single
34
+ * subprocess serves them all). Without filtering, session A's turn loop could
35
+ * pop session B's permission request and forward it to A's client — the popup
36
+ * lands in the wrong session. When `turn` is available we filter by
37
+ * `params.sessionId` so each turn loop only consumes its own requests; others
38
+ * are re-queued for their owner. Without `turn` (tests / non-turn callers) we
39
+ * process everything (legacy behaviour).
31
40
  */
32
41
  export declare function handleServerRequests(server: ZcodeAcpServer, backend: ZcodeBackend, cx: acp.AgentContext, acpSid: string, turn?: PendingTurn): Promise<boolean>;
42
+ /**
43
+ * AskUserQuestion: sequential per-question, multi-select per-option.
44
+ *
45
+ * Single-select: one popup per question; Skip/cancel → overall decline.
46
+ * Multi-select: one Include/Skip popup per option; Include picks comma-joined.
47
+ */
48
+ export declare function handleAskUserQuestion(server: ZcodeAcpServer, cx: acp.AgentContext, acpSid: string, params: ZcodeInteractionUserInputParams, turn?: PendingTurn): Promise<ZcodeInteractionResponse>;
33
49
  export {};
34
50
  //# sourceMappingURL=server-requests.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-requests.d.ts","sourceRoot":"","sources":["../../src/handlers/server-requests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAErD,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAEV,wBAAwB,EAEzB,MAAM,qBAAqB,CAAC;AAkB7B,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGhE,wEAAwE;AACxE,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,wBAAwB,CAAC;CACnC;AAED,4DAA4D;AAC5D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAQtF;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,YAAY,EACrB,EAAE,EAAE,GAAG,CAAC,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,OAAO,CAAC,CAUlB"}
1
+ {"version":3,"file":"server-requests.d.ts","sourceRoot":"","sources":["../../src/handlers/server-requests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,KAAK,GAAG,MAAM,0BAA0B,CAAC;AAErD,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,KAAK,EAEV,wBAAwB,EACxB,+BAA+B,EAChC,MAAM,qBAAqB,CAAC;AAiB7B,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGhE,wEAAwE;AACxE,UAAU,UAAU;IAClB,QAAQ,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,wBAAwB,CAAC;CACnC;AAwCD,4DAA4D;AAC5D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAQtF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,YAAY,EACrB,EAAE,EAAE,GAAG,CAAC,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,OAAO,CAAC,CA8DlB;AA0JD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,EAAE,EAAE,GAAG,CAAC,YAAY,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,+BAA+B,EACvC,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,wBAAwB,CAAC,CA0EnC"}