weclaude 0.0.4

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 (56) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/cli/wrc.sh +168 -0
  4. package/commands/wrc.md +7 -0
  5. package/config.example.jsonc +75 -0
  6. package/dist/cli/init.js +216 -0
  7. package/dist/cli/init.js.map +1 -0
  8. package/dist/cli/sync.js +130 -0
  9. package/dist/cli/sync.js.map +1 -0
  10. package/dist/daemon/approval.js +366 -0
  11. package/dist/daemon/approval.js.map +1 -0
  12. package/dist/daemon/ask.js +97 -0
  13. package/dist/daemon/ask.js.map +1 -0
  14. package/dist/daemon/cc-bridge.js +173 -0
  15. package/dist/daemon/cc-bridge.js.map +1 -0
  16. package/dist/daemon/claim.js +76 -0
  17. package/dist/daemon/claim.js.map +1 -0
  18. package/dist/daemon/http.js +82 -0
  19. package/dist/daemon/http.js.map +1 -0
  20. package/dist/daemon/inbound.js +145 -0
  21. package/dist/daemon/inbound.js.map +1 -0
  22. package/dist/daemon/index.js +85 -0
  23. package/dist/daemon/index.js.map +1 -0
  24. package/dist/daemon/mirror-bridge.js +539 -0
  25. package/dist/daemon/mirror-bridge.js.map +1 -0
  26. package/dist/daemon/outbound.js +33 -0
  27. package/dist/daemon/outbound.js.map +1 -0
  28. package/dist/daemon/pending.js +27 -0
  29. package/dist/daemon/pending.js.map +1 -0
  30. package/dist/daemon/redact.js +27 -0
  31. package/dist/daemon/redact.js.map +1 -0
  32. package/dist/daemon/session-cache.js +66 -0
  33. package/dist/daemon/session-cache.js.map +1 -0
  34. package/dist/daemon/sessions.js +35 -0
  35. package/dist/daemon/sessions.js.map +1 -0
  36. package/dist/daemon/ws.js +67 -0
  37. package/dist/daemon/ws.js.map +1 -0
  38. package/dist/mcp/server.js +82 -0
  39. package/dist/mcp/server.js.map +1 -0
  40. package/dist/shared/config-writer.js +39 -0
  41. package/dist/shared/config-writer.js.map +1 -0
  42. package/dist/shared/config.js +139 -0
  43. package/dist/shared/config.js.map +1 -0
  44. package/dist/shared/log.js +18 -0
  45. package/dist/shared/log.js.map +1 -0
  46. package/dist/shared/paths.js +6 -0
  47. package/dist/shared/paths.js.map +1 -0
  48. package/docs/DESIGN-INIT.md +125 -0
  49. package/docs/ONBOARDING.md +118 -0
  50. package/hooks/hooks.json +16 -0
  51. package/hooks/pre-tool-use.sh +81 -0
  52. package/launchd/com.cc-wecom.daemon.plist.template +45 -0
  53. package/package.json +77 -0
  54. package/scripts/install.sh +50 -0
  55. package/scripts/uninstall.sh +26 -0
  56. package/systemd/cc-wecom.service.template +17 -0
@@ -0,0 +1,539 @@
1
+ // Mirror-mode bridge.
2
+ //
3
+ // Strategy: a running interactive `claude` exposes no local IPC. Its only
4
+ // shared surface is the append-only transcript at
5
+ // ~/.claude/projects/<encoded(cwd)>/<session-id>.jsonl
6
+ // So:
7
+ // • Inbound (WeCom → claude): spawn `claude --resume <sid> -p <text>` —
8
+ // writes a new user/assistant turn into the SAME jsonl. Serialized per
9
+ // session to avoid concurrent writers stomping each other.
10
+ // • Outbound (claude → WeCom): tail that jsonl from the current EOF; every
11
+ // new `assistant` line gets pushed to a configured WeCom chat.
12
+ //
13
+ // Caveat: the user shouldn't be hammering the same session in their local TTY
14
+ // while a `--resume` injection is in flight; Claude Code locks aren't strict.
15
+ import { spawn } from "node:child_process";
16
+ import { existsSync, readdirSync, statSync, watch, openSync, readSync, closeSync } from "node:fs";
17
+ import { join, dirname } from "node:path";
18
+ import { expandHome } from "../shared/paths.js";
19
+ // Same PATH augmentation logic as cc-bridge: launchd / systemd start the daemon
20
+ // with a stripped PATH that often lacks nvm / homebrew, breaking spawn(claudeBin).
21
+ const NODE_BIN_DIR = dirname(process.execPath);
22
+ const augmentedPath = (orig) => {
23
+ const extras = [
24
+ NODE_BIN_DIR,
25
+ "/opt/homebrew/bin",
26
+ "/usr/local/bin",
27
+ `${process.env.HOME ?? ""}/.local/bin`,
28
+ ].filter(Boolean);
29
+ const seen = new Set();
30
+ return [orig ?? "", ...extras]
31
+ .flatMap((p) => p.split(":"))
32
+ .filter((p) => {
33
+ if (!p || seen.has(p))
34
+ return false;
35
+ seen.add(p);
36
+ return true;
37
+ })
38
+ .join(":");
39
+ };
40
+ // Claude Code encodes a project's cwd into a directory name by replacing each
41
+ // `/` with `-`. Absolute path `/Users/foo/bar` → `-Users-foo-bar`.
42
+ const encodeProjectDir = (absCwd) => absCwd.replace(/\//g, "-");
43
+ const resolveSession = (cfg, log) => {
44
+ const cwd = expandHome(cfg.wrc.cwd);
45
+ const projectDir = join(expandHome(cfg.wrc.mirror.projectsDir), encodeProjectDir(cwd));
46
+ if (!existsSync(projectDir)) {
47
+ log.error({ projectDir }, "mirror: project dir not found (no claude session ever ran in cwd?)");
48
+ return undefined;
49
+ }
50
+ const pinned = cfg.wrc.mirror.sessionId.trim();
51
+ if (pinned) {
52
+ const p = join(projectDir, `${pinned}.jsonl`);
53
+ if (!existsSync(p)) {
54
+ log.error({ p }, "mirror: pinned sessionId jsonl missing");
55
+ return undefined;
56
+ }
57
+ return { sessionId: pinned, jsonlPath: p };
58
+ }
59
+ // auto-pick latest
60
+ const candidates = readdirSync(projectDir)
61
+ .filter((n) => n.endsWith(".jsonl"))
62
+ .map((n) => ({ name: n, mtime: statSync(join(projectDir, n)).mtimeMs }))
63
+ .sort((a, b) => b.mtime - a.mtime);
64
+ if (candidates.length === 0) {
65
+ log.error({ projectDir }, "mirror: no .jsonl in project dir");
66
+ return undefined;
67
+ }
68
+ const top = candidates[0];
69
+ return {
70
+ sessionId: top.name.replace(/\.jsonl$/, ""),
71
+ jsonlPath: join(projectDir, top.name),
72
+ };
73
+ };
74
+ const stripPrincipalPrefix = (s) => {
75
+ const i = s.indexOf(":");
76
+ return i >= 0 ? s.slice(i + 1) : s;
77
+ };
78
+ const truncate = (s, max) => s.length <= max ? s : `${s.slice(0, max)}…(+${s.length - max})`;
79
+ const renderToolInput = (input) => {
80
+ try {
81
+ const json = JSON.stringify(input ?? {}, null, 0);
82
+ return truncate(json, 600);
83
+ }
84
+ catch {
85
+ return "{}";
86
+ }
87
+ };
88
+ const renderToolResult = (block, max) => {
89
+ const c = block.content;
90
+ if (typeof c === "string")
91
+ return truncate(c, max);
92
+ if (!Array.isArray(c))
93
+ return "";
94
+ return truncate(c
95
+ .map((b) => (typeof b?.text === "string" ? b.text : b?.tool_name ? `→ ${b.tool_name}` : ""))
96
+ .filter(Boolean)
97
+ .join("\n"), max);
98
+ };
99
+ // Render one transcript line into tagged items. Caller decides batching.
100
+ const renderLine = (raw, deps) => {
101
+ let line;
102
+ try {
103
+ line = JSON.parse(raw);
104
+ }
105
+ catch {
106
+ return [];
107
+ }
108
+ if (line.isMeta || line.isSidechain)
109
+ return [];
110
+ const out = [];
111
+ if (line.type === "user") {
112
+ const c = line.message?.content;
113
+ if (typeof c === "string") {
114
+ const text = c.trim();
115
+ if (!text)
116
+ return [];
117
+ if (!deps.includeUser)
118
+ return [];
119
+ if (deps.isOwnInject(text))
120
+ return []; // dedupe WeCom→CLI echo
121
+ // Blockquote each line; no heading. Distinguishes from assistant text
122
+ // without screaming "🧑 user" at the top of every turn.
123
+ const quoted = text.split("\n").map((l) => `> ${l}`).join("\n");
124
+ out.push({ kind: "text", body: quoted });
125
+ }
126
+ else if (Array.isArray(c) && deps.includeToolResults) {
127
+ for (const b of c) {
128
+ if (b?.type === "tool_result") {
129
+ const body = renderToolResult(b, deps.toolResultMaxChars);
130
+ if (body) {
131
+ out.push({
132
+ kind: "tool",
133
+ body: `**↩ tool_result** \`${b.tool_use_id?.slice(-8) ?? ""}\`\n${body}`,
134
+ });
135
+ }
136
+ }
137
+ }
138
+ }
139
+ return out;
140
+ }
141
+ if (line.type === "assistant") {
142
+ const blocks = line.message?.content;
143
+ if (!Array.isArray(blocks))
144
+ return [];
145
+ for (const b of blocks) {
146
+ if (b?.type === "text" && typeof b.text === "string") {
147
+ const t = b.text.trim();
148
+ if (t)
149
+ out.push({ kind: "text", body: t });
150
+ }
151
+ else if (b?.type === "tool_use" && deps.includeTools) {
152
+ out.push({
153
+ kind: "tool",
154
+ body: `**🔧 ${b.name ?? "tool"}**\n\`\`\`json\n${renderToolInput(b.input)}\n\`\`\``,
155
+ });
156
+ }
157
+ // thinking blocks intentionally skipped
158
+ }
159
+ return out;
160
+ }
161
+ return [];
162
+ };
163
+ const splitChunks = (s, max) => {
164
+ if (s.length <= max)
165
+ return [s];
166
+ const out = [];
167
+ for (let i = 0; i < s.length; i += max)
168
+ out.push(s.slice(i, i + max));
169
+ return out;
170
+ };
171
+ export const startMirrorTail = (deps) => {
172
+ const { jsonlPath, log } = deps;
173
+ // Start at EOF — don't re-emit history.
174
+ let offset = statSync(jsonlPath).size;
175
+ let buffer = "";
176
+ let stopped = false;
177
+ const drain = () => {
178
+ if (stopped)
179
+ return;
180
+ let size;
181
+ try {
182
+ size = statSync(jsonlPath).size;
183
+ }
184
+ catch {
185
+ return;
186
+ }
187
+ if (size < offset) {
188
+ // file truncated/rotated — reset to new EOF
189
+ offset = size;
190
+ buffer = "";
191
+ return;
192
+ }
193
+ if (size === offset)
194
+ return;
195
+ const fd = openSync(jsonlPath, "r");
196
+ try {
197
+ const len = size - offset;
198
+ const buf = Buffer.alloc(len);
199
+ readSync(fd, buf, 0, len, offset);
200
+ offset = size;
201
+ buffer += buf.toString("utf8");
202
+ }
203
+ finally {
204
+ closeSync(fd);
205
+ }
206
+ let nl;
207
+ while ((nl = buffer.indexOf("\n")) !== -1) {
208
+ const line = buffer.slice(0, nl);
209
+ buffer = buffer.slice(nl + 1);
210
+ if (!line.trim())
211
+ continue;
212
+ for (const item of renderLine(line, deps))
213
+ deps.onItem(item);
214
+ }
215
+ };
216
+ // fs.watch fires on append on macOS/Linux. We also poll on a slow timer as
217
+ // belt-and-suspenders for editors/filesystems that drop events.
218
+ let watcher;
219
+ try {
220
+ watcher = watch(jsonlPath, { persistent: false }, () => drain());
221
+ }
222
+ catch (e) {
223
+ log.warn({ err: e.message }, "fs.watch failed; relying on poll");
224
+ }
225
+ const poll = setInterval(drain, 1000);
226
+ log.info({ jsonlPath, startOffset: offset }, "mirror tail started");
227
+ return {
228
+ stop: () => {
229
+ stopped = true;
230
+ watcher?.close();
231
+ clearInterval(poll);
232
+ },
233
+ };
234
+ };
235
+ const injectViaTmux = (target, text, log) => {
236
+ log.info({ target, len: text.length }, "mirror inject (tmux)");
237
+ return new Promise((resolve) => {
238
+ // 1. load text into tmux paste buffer (handles multi-line / unicode safely)
239
+ const loader = spawn("tmux", ["load-buffer", "-"], { stdio: ["pipe", "ignore", "pipe"] });
240
+ let lerr = "";
241
+ loader.stderr?.on("data", (c) => (lerr += c.toString("utf8")));
242
+ loader.on("error", (e) => resolve({ ok: false, reason: `tmux not found: ${e.message}` }));
243
+ loader.on("close", (code) => {
244
+ if (code !== 0) {
245
+ resolve({ ok: false, reason: `tmux load-buffer exit ${code}: ${lerr.slice(-200)}` });
246
+ return;
247
+ }
248
+ // 2. paste with bracketed-paste (-p) so claude treats it as one chunk,
249
+ // not auto-submitting on embedded newlines.
250
+ const paster = spawn("tmux", ["paste-buffer", "-p", "-d", "-t", target], {
251
+ stdio: ["ignore", "ignore", "pipe"],
252
+ });
253
+ let perr = "";
254
+ paster.stderr?.on("data", (c) => (perr += c.toString("utf8")));
255
+ paster.on("close", (c2) => {
256
+ if (c2 !== 0) {
257
+ resolve({ ok: false, reason: `tmux paste-buffer exit ${c2}: ${perr.slice(-200)}` });
258
+ return;
259
+ }
260
+ // 3. tiny delay so paste settles in claude's input box, then Enter to submit.
261
+ setTimeout(() => {
262
+ const enter = spawn("tmux", ["send-keys", "-t", target, "Enter"], { stdio: "ignore" });
263
+ enter.on("close", () => resolve({ ok: true }));
264
+ enter.on("error", (e) => resolve({ ok: false, reason: `tmux send-keys: ${e.message}` }));
265
+ }, 120);
266
+ });
267
+ });
268
+ loader.stdin?.end(text);
269
+ });
270
+ };
271
+ const injectViaSpawn = (args) => {
272
+ const { text, cfg, log, sessionId } = args;
273
+ const cliArgs = [
274
+ "-p",
275
+ text,
276
+ "--resume",
277
+ sessionId,
278
+ "--output-format",
279
+ "stream-json",
280
+ "--verbose",
281
+ ...cfg.wrc.extraArgs,
282
+ ];
283
+ log.info({ sessionId, claudeBin: cfg.wrc.claudeBin, len: text.length }, "mirror inject");
284
+ return new Promise((resolve) => {
285
+ const proc = spawn(cfg.wrc.claudeBin, cliArgs, {
286
+ cwd: expandHome(cfg.wrc.cwd),
287
+ env: { ...process.env, PATH: augmentedPath(process.env.PATH) },
288
+ stdio: ["ignore", "ignore", "pipe"],
289
+ });
290
+ let stderrTail = "";
291
+ let spawnError;
292
+ proc.on("error", (err) => {
293
+ spawnError = err;
294
+ });
295
+ proc.stderr?.on("data", (chunk) => {
296
+ stderrTail = (stderrTail + chunk.toString("utf8")).slice(-1500);
297
+ });
298
+ proc.on("close", (code) => {
299
+ if (spawnError) {
300
+ log.error({ err: spawnError.message }, "mirror spawn error");
301
+ resolve({ ok: false, reason: `spawn ${cfg.wrc.claudeBin}: ${spawnError.message}` });
302
+ return;
303
+ }
304
+ if (code !== 0) {
305
+ log.error({ code, stderrTail: stderrTail.slice(-400) }, "mirror inject non-zero");
306
+ resolve({ ok: false, reason: `claude exited ${code}: ${stderrTail.slice(-300)}` });
307
+ return;
308
+ }
309
+ resolve({ ok: true });
310
+ });
311
+ });
312
+ };
313
+ const inject = (args) => args.cfg.wrc.mirror.tmuxTarget.trim()
314
+ ? injectViaTmux(args.cfg.wrc.mirror.tmuxTarget.trim(), args.text, args.log)
315
+ : injectViaSpawn(args);
316
+ const queues = new Map();
317
+ const enqueue = (key, job) => {
318
+ const prev = queues.get(key) ?? Promise.resolve();
319
+ const next = prev.then(job, job).catch(() => undefined);
320
+ queues.set(key, next.finally(() => {
321
+ if (queues.get(key) === next)
322
+ queues.delete(key);
323
+ }));
324
+ return next;
325
+ };
326
+ export const startMirror = (deps) => {
327
+ const { cfg, log, client } = deps;
328
+ let state;
329
+ // Ring buffer of recently-injected user texts to suppress WeCom→CLI echo.
330
+ const INJECT_TTL_MS = 60_000;
331
+ const recentInjects = [];
332
+ const rememberInject = (text) => {
333
+ const t = text.trim();
334
+ if (!t)
335
+ return;
336
+ recentInjects.push({ text: t, ts: Date.now() });
337
+ if (recentInjects.length > 64)
338
+ recentInjects.shift();
339
+ };
340
+ const isOwnInject = (text) => {
341
+ const now = Date.now();
342
+ const t = text.trim();
343
+ for (let i = recentInjects.length - 1; i >= 0; i--) {
344
+ const e = recentInjects[i];
345
+ if (now - e.ts > INJECT_TTL_MS)
346
+ continue;
347
+ if (e.text === t)
348
+ return true;
349
+ }
350
+ return false;
351
+ };
352
+ // ── Typewriter stream lifecycle ────────────────────────────────────
353
+ // For a WeCom→Claude turn we hold the inbound frame and keep updating ONE
354
+ // markdown via replyStream as transcript items arrive. Tool calls + text
355
+ // accumulate into a single growing message. Idle timer finalizes the turn
356
+ // (finish=true) when no new content arrives for IDLE_END_MS.
357
+ const FLUSH_MS = 250;
358
+ const IDLE_END_MS = 30_000;
359
+ const STREAM_SOFT_CAP = 18_000; // WeCom stream content limit ~20480 bytes
360
+ let injectStream;
361
+ const flushStream = async (s) => {
362
+ s.flushTimer = undefined;
363
+ if (s.closed || s.acc === s.lastSent)
364
+ return;
365
+ const content = s.acc;
366
+ s.lastSent = content;
367
+ try {
368
+ await client.replyStream(s.frame, s.streamId, content || " ", false);
369
+ }
370
+ catch (e) {
371
+ log.warn({ err: e.message }, "stream flush failed");
372
+ }
373
+ };
374
+ const scheduleFlush = (s) => {
375
+ if (s.flushTimer || s.closed)
376
+ return;
377
+ s.flushTimer = setTimeout(() => void flushStream(s), FLUSH_MS);
378
+ };
379
+ const closeStream = async (s) => {
380
+ if (s.closed)
381
+ return;
382
+ s.closed = true;
383
+ if (s.flushTimer) {
384
+ clearTimeout(s.flushTimer);
385
+ s.flushTimer = undefined;
386
+ }
387
+ if (s.idleTimer) {
388
+ clearTimeout(s.idleTimer);
389
+ s.idleTimer = undefined;
390
+ }
391
+ try {
392
+ await client.replyStream(s.frame, s.streamId, s.acc || " ", true);
393
+ }
394
+ catch (e) {
395
+ log.warn({ err: e.message }, "stream finish failed");
396
+ }
397
+ s.closedResolve();
398
+ };
399
+ const resetIdle = (s) => {
400
+ if (s.idleTimer)
401
+ clearTimeout(s.idleTimer);
402
+ s.idleTimer = setTimeout(() => void closeStream(s), IDLE_END_MS);
403
+ };
404
+ const openStream = (frame, streamId) => {
405
+ let resolve;
406
+ const closedPromise = new Promise((r) => { resolve = r; });
407
+ const s = {
408
+ frame, streamId,
409
+ acc: "", lastSent: "",
410
+ capped: false, closed: false,
411
+ closedResolve: resolve, closedPromise,
412
+ };
413
+ return s;
414
+ };
415
+ // Standalone fallback (no active stream → TTY-origin content). Per-item
416
+ // markdown push, serialized to keep order.
417
+ let standalonePending = Promise.resolve();
418
+ const sendStandalone = (content) => {
419
+ if (!state)
420
+ return;
421
+ const chatId = stripPrincipalPrefix(state.target);
422
+ const chunks = splitChunks(content, cfg.wrc.mirror.chunkChars);
423
+ standalonePending = standalonePending
424
+ .then(async () => {
425
+ for (const c of chunks) {
426
+ try {
427
+ await client.sendMessage(chatId, { msgtype: "markdown", markdown: { content: c } });
428
+ }
429
+ catch (e) {
430
+ log.warn({ err: e.message }, "standalone push failed");
431
+ }
432
+ }
433
+ })
434
+ .catch(() => undefined);
435
+ };
436
+ const onItem = (item) => {
437
+ const s = injectStream;
438
+ if (s && !s.closed) {
439
+ if (s.capped)
440
+ return;
441
+ const sep = s.acc ? "\n\n---\n\n" : "";
442
+ const next = s.acc + sep + item.body;
443
+ if (next.length > STREAM_SOFT_CAP) {
444
+ s.acc = `${s.acc}${sep}…(truncated, see Claude TTY for full output)`;
445
+ s.capped = true;
446
+ }
447
+ else {
448
+ s.acc = next;
449
+ }
450
+ resetIdle(s);
451
+ scheduleFlush(s);
452
+ return;
453
+ }
454
+ sendStandalone(item.body);
455
+ };
456
+ const resolveTarget = (override) => (override?.trim() || cfg.wrc.mirror.pushChat.trim() || cfg.defaultChat.trim());
457
+ const attach = ({ sessionId, jsonlPath, target: targetOverride }) => {
458
+ const target = resolveTarget(targetOverride);
459
+ if (!target)
460
+ return { ok: false, reason: "no target chat (set wrc.mirror.pushChat or defaultChat, or pass target)" };
461
+ if (!existsSync(jsonlPath))
462
+ return { ok: false, reason: `jsonl missing: ${jsonlPath}` };
463
+ state?.tail.stop();
464
+ const tail = startMirrorTail({
465
+ jsonlPath,
466
+ log: log.child({ sub: "tail" }),
467
+ includeUser: cfg.wrc.mirror.includeUser,
468
+ includeTools: cfg.wrc.mirror.includeTools,
469
+ includeToolResults: cfg.wrc.mirror.includeToolResults,
470
+ toolResultMaxChars: cfg.wrc.mirror.toolResultMaxChars,
471
+ isOwnInject,
472
+ onItem,
473
+ });
474
+ state = { sessionId, jsonlPath, target, tail };
475
+ log.info({ sessionId, jsonlPath, target }, "mirror attached");
476
+ return { ok: true, sessionId, jsonlPath, target };
477
+ };
478
+ // Best-effort: if config can resolve a session at boot, auto-attach.
479
+ const resolved = resolveSession(cfg, log);
480
+ if (resolved) {
481
+ const r = attach({ sessionId: resolved.sessionId, jsonlPath: resolved.jsonlPath });
482
+ if (!r.ok)
483
+ log.warn({ reason: r.reason }, "mirror: auto-attach skipped");
484
+ }
485
+ else {
486
+ log.warn("mirror: no session resolved at boot — waiting for /mirror/attach");
487
+ }
488
+ return {
489
+ attach,
490
+ status: () => state
491
+ ? { attached: true, sessionId: state.sessionId, jsonlPath: state.jsonlPath, target: state.target }
492
+ : { attached: false },
493
+ shutdown: () => {
494
+ if (injectStream && !injectStream.closed)
495
+ void closeStream(injectStream);
496
+ state?.tail.stop();
497
+ },
498
+ dispatch: async ({ principal, text, frame, streamId }) => {
499
+ if (!state) {
500
+ try {
501
+ await client.replyStream(frame, streamId, "[mirror] not attached — run `/wrc mirror` inside the target Claude session", true);
502
+ }
503
+ catch {
504
+ /* ignore */
505
+ }
506
+ return;
507
+ }
508
+ // Eager ack so WeCom doesn't time out the inbound frame while this turn
509
+ // sits in the per-session inject queue.
510
+ try {
511
+ await client.replyStream(frame, streamId, "…", false);
512
+ }
513
+ catch (e) {
514
+ log.warn({ err: e.message }, "stream initial ack failed");
515
+ }
516
+ const sid = state.sessionId;
517
+ await enqueue(sid, async () => {
518
+ const s = openStream(frame, streamId);
519
+ injectStream = s;
520
+ resetIdle(s);
521
+ const r = await inject({ text, cfg, log: log.child({ principal }), sessionId: sid });
522
+ if (!r.ok) {
523
+ s.acc = `[mirror] ✗ ${r.reason ?? "failed"}`;
524
+ await closeStream(s);
525
+ if (injectStream === s)
526
+ injectStream = undefined;
527
+ return;
528
+ }
529
+ rememberInject(text);
530
+ // Hold the queue until the stream finalizes (idle-driven by tail) so
531
+ // back-to-back messages don't interleave their tool/text streams.
532
+ await s.closedPromise;
533
+ if (injectStream === s)
534
+ injectStream = undefined;
535
+ });
536
+ },
537
+ };
538
+ };
539
+ //# sourceMappingURL=mirror-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mirror-bridge.js","sourceRoot":"","sources":["../../daemon/mirror-bridge.ts"],"names":[],"mappings":"AAAA,sBAAsB;AACtB,EAAE;AACF,0EAA0E;AAC1E,kDAAkD;AAClD,yDAAyD;AACzD,MAAM;AACN,0EAA0E;AAC1E,2EAA2E;AAC3E,+DAA+D;AAC/D,6EAA6E;AAC7E,mEAAmE;AACnE,EAAE;AACF,8EAA8E;AAC9E,8EAA8E;AAC9E,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAkB,MAAM,SAAS,CAAC;AAClH,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAI1C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,gFAAgF;AAChF,mFAAmF;AACnF,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAC/C,MAAM,aAAa,GAAG,CAAC,IAAwB,EAAU,EAAE;IACzD,MAAM,MAAM,GAAG;QACb,YAAY;QACZ,mBAAmB;QACnB,gBAAgB;QAChB,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,aAAa;KACvC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAClB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,MAAM,CAAC;SAC3B,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAC5B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACZ,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACpC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;SACD,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC,CAAC;AAEF,8EAA8E;AAC9E,mEAAmE;AACnE,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAOhF,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,GAAW,EAA+B,EAAE;IAC/E,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;IACvF,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,GAAG,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE,oEAAoE,CAAC,CAAC;QAChG,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,MAAM,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACnB,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,wCAAwC,CAAC,CAAC;YAC3D,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAC7C,CAAC;IACD,mBAAmB;IACnB,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC;SACvC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;SACnC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;SACvE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,GAAG,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE,kCAAkC,CAAC,CAAC;QAC9D,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;IAC3B,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;QAC3C,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC;KACtC,CAAC;AACJ,CAAC,CAAC;AAqCF,MAAM,oBAAoB,GAAG,CAAC,CAAS,EAAU,EAAE;IACjD,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,GAAW,EAAU,EAAE,CAClD,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,GAAG,GAAG,CAAC;AAElE,MAAM,eAAe,GAAG,CAAC,KAAc,EAAU,EAAE;IACjD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAClD,OAAO,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,KAAmB,EAAE,GAAW,EAAU,EAAE;IACpE,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC;IACxB,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,QAAQ,CACb,CAAC;SACE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC3F,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,IAAI,CAAC,EACb,GAAG,CACJ,CAAC;AACJ,CAAC,CAAC;AAUF,yEAAyE;AACzE,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,IAAc,EAAgB,EAAE;IAC/D,IAAI,IAAoB,CAAC;IACzB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,CAAC;IAE/C,MAAM,GAAG,GAAiB,EAAE,CAAC;IAE7B,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;QAChC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,IAAI;gBAAE,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,WAAW;gBAAE,OAAO,EAAE,CAAC;YACjC,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;gBAAE,OAAO,EAAE,CAAC,CAAC,wBAAwB;YAC/D,sEAAsE;YACtE,wDAAwD;YACxD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAChE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3C,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACvD,KAAK,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClB,IAAI,CAAC,EAAE,IAAI,KAAK,aAAa,EAAE,CAAC;oBAC9B,MAAM,IAAI,GAAG,gBAAgB,CAAC,CAAC,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;oBAC1D,IAAI,IAAI,EAAE,CAAC;wBACT,GAAG,CAAC,IAAI,CAAC;4BACP,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,uBAAuB,CAAC,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,EAAE;yBACzE,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;QACrC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,OAAO,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACrD,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACxB,IAAI,CAAC;oBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;YAC7C,CAAC;iBAAM,IAAI,CAAC,EAAE,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACvD,GAAG,CAAC,IAAI,CAAC;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,QAAQ,CAAC,CAAC,IAAI,IAAI,MAAM,mBAAmB,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU;iBACpF,CAAC,CAAC;YACL,CAAC;YACD,wCAAwC;QAC1C,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,CAAS,EAAE,GAAW,EAAY,EAAE;IACvD,IAAI,CAAC,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAChC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,GAAG;QAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACtE,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,IAAc,EAAc,EAAE;IAC5D,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAEhC,wCAAwC;IACxC,IAAI,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;IACtC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,IAAI,OAAO;YAAE,OAAO;QACpB,IAAI,IAAY,CAAC;QACjB,IAAI,CAAC;YACH,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;YAClB,4CAA4C;YAC5C,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,GAAG,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;QACD,IAAI,IAAI,KAAK,MAAM;YAAE,OAAO;QAC5B,MAAM,EAAE,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC;YAC1B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9B,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;YAClC,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;gBAAS,CAAC;YACT,SAAS,CAAC,EAAE,CAAC,CAAC;QAChB,CAAC;QACD,IAAI,EAAU,CAAC;QACf,OAAO,CAAC,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBAAE,SAAS;YAC3B,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC,CAAC;IAEF,2EAA2E;IAC3E,gEAAgE;IAChE,IAAI,OAA8B,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAG,CAAW,CAAC,OAAO,EAAE,EAAE,kCAAkC,CAAC,CAAC;IAC9E,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEtC,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;IAEpE,OAAO;QACL,IAAI,EAAE,GAAG,EAAE;YACT,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,EAAE,KAAK,EAAE,CAAC;YACjB,aAAa,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAkBF,MAAM,aAAa,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,GAAW,EAA6C,EAAE;IAC7G,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,sBAAsB,CAAC,CAAC;IAC/D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,4EAA4E;QAC5E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1F,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAC1F,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YAC1B,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrF,OAAO;YACT,CAAC;YACD,uEAAuE;YACvE,+CAA+C;YAC/C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE;gBACvE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC;aACpC,CAAC,CAAC;YACH,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACvE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE;gBACxB,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;oBACb,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,0BAA0B,EAAE,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;oBACpF,OAAO;gBACT,CAAC;gBACD,8EAA8E;gBAC9E,UAAU,CAAC,GAAG,EAAE;oBACd,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;oBACvF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC/C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC3F,CAAC,EAAE,GAAG,CAAC,CAAC;YACV,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,IAAgB,EAA6C,EAAE;IACrF,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC3C,MAAM,OAAO,GAAG;QACd,IAAI;QACJ,IAAI;QACJ,UAAU;QACV,SAAS;QACT,iBAAiB;QACjB,aAAa;QACb,WAAW;QACX,GAAG,GAAG,CAAC,GAAG,CAAC,SAAS;KACrB,CAAC;IACF,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC;IACzF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE;YAC7C,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;YAC5B,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YAC9D,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC;SACpC,CAAC,CAAC;QACH,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,IAAI,UAA6B,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACvB,UAAU,GAAG,GAAG,CAAC;QACnB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,UAAU,GAAG,CAAC,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,UAAU,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,UAAU,CAAC,OAAO,EAAE,EAAE,oBAAoB,CAAC,CAAC;gBAC7D,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,GAAG,CAAC,GAAG,CAAC,SAAS,KAAK,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACpF,OAAO;YACT,CAAC;YACD,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC;gBAClF,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,IAAI,KAAK,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;gBACnF,OAAO;YACT,CAAC;YACD,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG,CAAC,IAAgB,EAA6C,EAAE,CAC7E,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE;IACnC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;IAC3E,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AAI3B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;AAChD,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE,GAAQ,EAAiB,EAAE;IACvD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACxD,MAAM,CAAC,GAAG,CACR,GAAG,EACH,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE;QAChB,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;YAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACnD,CAAC,CAAC,CACH,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AA4CF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAgB,EAAgB,EAAE;IAC5D,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAClC,IAAI,KAA8B,CAAC;IAEnC,0EAA0E;IAC1E,MAAM,aAAa,GAAG,MAAM,CAAC;IAC7B,MAAM,aAAa,GAAwC,EAAE,CAAC;IAC9D,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;QAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC;YAAE,OAAO;QACf,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,aAAa,CAAC,MAAM,GAAG,EAAE;YAAE,aAAa,CAAC,KAAK,EAAE,CAAC;IACvD,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,IAAY,EAAW,EAAE;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,KAAK,IAAI,CAAC,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACnD,MAAM,CAAC,GAAG,aAAa,CAAC,CAAC,CAAE,CAAC;YAC5B,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE,GAAG,aAAa;gBAAE,SAAS;YACzC,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;QAChC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,sEAAsE;IACtE,0EAA0E;IAC1E,yEAAyE;IACzE,0EAA0E;IAC1E,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,GAAG,CAAC;IACrB,MAAM,WAAW,GAAG,MAAM,CAAC;IAC3B,MAAM,eAAe,GAAG,MAAM,CAAC,CAAC,0CAA0C;IAc1E,IAAI,YAAsC,CAAC;IAE3C,MAAM,WAAW,GAAG,KAAK,EAAE,CAAe,EAAiB,EAAE;QAC3D,CAAC,CAAC,UAAU,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,QAAQ;YAAE,OAAO;QAC7C,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC;QACtB,CAAC,CAAC,QAAQ,GAAG,OAAO,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,OAAO,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAG,CAAW,CAAC,OAAO,EAAE,EAAE,qBAAqB,CAAC,CAAC;QACjE,CAAC;IACH,CAAC,CAAC;IACF,MAAM,aAAa,GAAG,CAAC,CAAe,EAAQ,EAAE;QAC9C,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO;QACrC,CAAC,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACjE,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,KAAK,EAAE,CAAe,EAAiB,EAAE;QAC3D,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO;QACrB,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;QAChB,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;YAAC,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;YAAC,CAAC,CAAC,UAAU,GAAG,SAAS,CAAC;QAAC,CAAC;QAC3E,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC;YAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YAAC,CAAC,CAAC,SAAS,GAAG,SAAS,CAAC;QAAC,CAAC;QACxE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,EAAE,IAAI,CAAC,CAAC;QACpE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAG,CAAW,CAAC,OAAO,EAAE,EAAE,sBAAsB,CAAC,CAAC;QAClE,CAAC;QACD,CAAC,CAAC,aAAa,EAAE,CAAC;IACpB,CAAC,CAAC;IACF,MAAM,SAAS,GAAG,CAAC,CAAe,EAAQ,EAAE;QAC1C,IAAI,CAAC,CAAC,SAAS;YAAE,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC3C,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IACnE,CAAC,CAAC;IACF,MAAM,UAAU,GAAG,CAAC,KAAqB,EAAE,QAAgB,EAAgB,EAAE;QAC3E,IAAI,OAAoB,CAAC;QACzB,MAAM,aAAa,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,GAAiB;YACtB,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;YACrB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK;YAC5B,aAAa,EAAE,OAAO,EAAE,aAAa;SACtC,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC,CAAC;IAEF,wEAAwE;IACxE,2CAA2C;IAC3C,IAAI,iBAAiB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1C,MAAM,cAAc,GAAG,CAAC,OAAe,EAAQ,EAAE;QAC/C,IAAI,CAAC,KAAK;YAAE,OAAO;QACnB,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC/D,iBAAiB,GAAG,iBAAiB;aAClC,IAAI,CAAC,KAAK,IAAI,EAAE;YACf,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtF,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAG,CAAW,CAAC,OAAO,EAAE,EAAE,wBAAwB,CAAC,CAAC;gBACpE,CAAC;YACH,CAAC;QACH,CAAC,CAAC;aACD,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,CAAC,IAAgB,EAAQ,EAAE;QACxC,MAAM,CAAC,GAAG,YAAY,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,CAAC,MAAM;gBAAE,OAAO;YACrB,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;YACvC,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC;YACrC,IAAI,IAAI,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;gBAClC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,GAAG,8CAA8C,CAAC;gBACrE,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACN,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC;YACf,CAAC;YACD,SAAS,CAAC,CAAC,CAAC,CAAC;YACb,aAAa,CAAC,CAAC,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;QACD,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,QAAiB,EAAU,EAAE,CAClD,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;IAEjF,MAAM,MAAM,GAAG,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,cAAc,EAAc,EAAgB,EAAE;QAC5F,MAAM,MAAM,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yEAAyE,EAAE,CAAC;QACrH,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,SAAS,EAAE,EAAE,CAAC;QACxF,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,GAAG,eAAe,CAAC;YAC3B,SAAS;YACT,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;YAC/B,WAAW,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW;YACvC,YAAY,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY;YACzC,kBAAkB,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB;YACrD,kBAAkB,EAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB;YACrD,WAAW;YACX,MAAM;SACP,CAAC,CAAC;QACH,KAAK,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC/C,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC;QAC9D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;IACpD,CAAC,CAAC;IAEF,qEAAqE;IACrE,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAC1C,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC;QACnF,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,6BAA6B,CAAC,CAAC;IAC3E,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO;QACL,MAAM;QACN,MAAM,EAAE,GAAG,EAAE,CACX,KAAK;YACH,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;YAClG,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE;QACzB,QAAQ,EAAE,GAAG,EAAE;YACb,IAAI,YAAY,IAAI,CAAC,YAAY,CAAC,MAAM;gBAAE,KAAK,WAAW,CAAC,YAAY,CAAC,CAAC;YACzE,KAAK,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACrB,CAAC;QACD,QAAQ,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE;YACvD,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,IAAI,CAAC;oBACH,MAAM,MAAM,CAAC,WAAW,CACtB,KAAK,EACL,QAAQ,EACR,4EAA4E,EAC5E,IAAI,CACL,CAAC;gBACJ,CAAC;gBAAC,MAAM,CAAC;oBACP,YAAY;gBACd,CAAC;gBACD,OAAO;YACT,CAAC;YACD,wEAAwE;YACxE,wCAAwC;YACxC,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YACxD,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAG,CAAW,CAAC,OAAO,EAAE,EAAE,2BAA2B,CAAC,CAAC;YACvE,CAAC;YACD,MAAM,GAAG,GAAG,KAAK,CAAC,SAAS,CAAC;YAC5B,MAAM,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;gBAC5B,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBACtC,YAAY,GAAG,CAAC,CAAC;gBACjB,SAAS,CAAC,CAAC,CAAC,CAAC;gBACb,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;gBACrF,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;oBACV,CAAC,CAAC,GAAG,GAAG,cAAc,CAAC,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;oBAC7C,MAAM,WAAW,CAAC,CAAC,CAAC,CAAC;oBACrB,IAAI,YAAY,KAAK,CAAC;wBAAE,YAAY,GAAG,SAAS,CAAC;oBACjD,OAAO;gBACT,CAAC;gBACD,cAAc,CAAC,IAAI,CAAC,CAAC;gBACrB,qEAAqE;gBACrE,kEAAkE;gBAClE,MAAM,CAAC,CAAC,aAAa,CAAC;gBACtB,IAAI,YAAY,KAAK,CAAC;oBAAE,YAAY,GAAG,SAAS,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { json, readBody } from "./http.js";
2
+ const stripPrefix = (s) => {
3
+ const i = s.indexOf(":");
4
+ return i >= 0 ? s.slice(i + 1) : s;
5
+ };
6
+ export const makeMessageHandler = (client, log) => {
7
+ return async (req, res) => {
8
+ const body = (await readBody(req));
9
+ const chat = body.chat ?? "";
10
+ const content = body.markdown ?? body.text ?? "";
11
+ if (!chat || !content) {
12
+ json(res, 400, { ok: false, error: "missing chat or text" });
13
+ return;
14
+ }
15
+ if (!client.isConnected) {
16
+ json(res, 503, { ok: false, error: "ws_disconnected" });
17
+ return;
18
+ }
19
+ try {
20
+ await client.sendMessage(stripPrefix(chat), {
21
+ msgtype: "markdown",
22
+ markdown: { content },
23
+ });
24
+ log.info({ chat, len: content.length }, "tx markdown");
25
+ json(res, 200, { ok: true });
26
+ }
27
+ catch (e) {
28
+ log.error({ err: e.message }, "send failed");
29
+ json(res, 502, { ok: false, error: e.message });
30
+ }
31
+ };
32
+ };
33
+ //# sourceMappingURL=outbound.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound.js","sourceRoot":"","sources":["../../daemon/outbound.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,WAAW,GAAG,CAAC,CAAS,EAAU,EAAE;IACxC,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC,CAAC;AAQF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAgB,EAAE,GAAW,EAAW,EAAE;IAC3E,OAAO,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;QACxB,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAoB,CAAC;QACtD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QACjD,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE;gBAC1C,OAAO,EAAE,UAAU;gBACnB,QAAQ,EAAE,EAAE,OAAO,EAAE;aACtB,CAAC,CAAC;YACH,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC;YACvD,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAG,CAAW,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;YACxD,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,CAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -0,0 +1,27 @@
1
+ // Pending request store: req_id → resolver. In-memory, daemon-lifetime.
2
+ // Used for both PreToolUse approvals and any other "send card → wait click" flows.
3
+ import { randomUUID } from "node:crypto";
4
+ const store = new Map();
5
+ export const createPending = ({ meta, timeoutMs }) => {
6
+ const reqId = randomUUID();
7
+ const promise = new Promise((resolve, reject) => {
8
+ const timer = setTimeout(() => {
9
+ store.delete(reqId);
10
+ reject(new Error("pending_timeout"));
11
+ }, timeoutMs);
12
+ store.set(reqId, { meta, resolve, reject, timer });
13
+ });
14
+ return { reqId, promise };
15
+ };
16
+ export const resolvePending = (reqId, decision) => {
17
+ const p = store.get(reqId);
18
+ if (!p)
19
+ return false;
20
+ clearTimeout(p.timer);
21
+ store.delete(reqId);
22
+ p.resolve(decision);
23
+ return true;
24
+ };
25
+ export const getPending = (reqId) => store.get(reqId)?.meta;
26
+ export const listPending = () => Array.from(store.entries()).map(([reqId, p]) => ({ reqId, meta: p.meta }));
27
+ //# sourceMappingURL=pending.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending.js","sourceRoot":"","sources":["../../daemon/pending.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,mFAAmF;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAqBzC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;AAYzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,EAAE,IAAI,EAAE,SAAS,EAAqB,EAAiB,EAAE;IACrF,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACvC,CAAC,EAAE,SAAS,CAAC,CAAC;QACd,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC5B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,QAAkB,EAAW,EAAE;IAC3E,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACtB,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,KAAa,EAA2B,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;AAE7F,MAAM,CAAC,MAAM,WAAW,GAAG,GAAgD,EAAE,CAC3E,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC"}