@electric-agent/studio 1.0.0 → 1.1.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 (68) hide show
  1. package/dist/active-sessions.d.ts +28 -0
  2. package/dist/active-sessions.d.ts.map +1 -0
  3. package/dist/active-sessions.js +50 -0
  4. package/dist/active-sessions.js.map +1 -0
  5. package/dist/bridge/claude-code-docker.d.ts +59 -0
  6. package/dist/bridge/claude-code-docker.d.ts.map +1 -0
  7. package/dist/bridge/claude-code-docker.js +258 -0
  8. package/dist/bridge/claude-code-docker.js.map +1 -0
  9. package/dist/bridge/claude-code-sprites.d.ts +49 -0
  10. package/dist/bridge/claude-code-sprites.d.ts.map +1 -0
  11. package/dist/bridge/claude-code-sprites.js +231 -0
  12. package/dist/bridge/claude-code-sprites.js.map +1 -0
  13. package/dist/bridge/claude-md-generator.d.ts +24 -0
  14. package/dist/bridge/claude-md-generator.d.ts.map +1 -0
  15. package/dist/bridge/claude-md-generator.js +299 -0
  16. package/dist/bridge/claude-md-generator.js.map +1 -0
  17. package/dist/bridge/index.d.ts +3 -0
  18. package/dist/bridge/index.d.ts.map +1 -1
  19. package/dist/bridge/index.js +3 -0
  20. package/dist/bridge/index.js.map +1 -1
  21. package/dist/bridge/stream-json-parser.d.ts +30 -0
  22. package/dist/bridge/stream-json-parser.d.ts.map +1 -0
  23. package/dist/bridge/stream-json-parser.js +207 -0
  24. package/dist/bridge/stream-json-parser.js.map +1 -0
  25. package/dist/client/assets/index-BeZ6CTGd.css +1 -0
  26. package/dist/client/assets/index-DRLXdDNp.js +241 -0
  27. package/dist/client/index.html +2 -2
  28. package/dist/index.d.ts +5 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +4 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/project-utils.d.ts +2 -1
  33. package/dist/project-utils.d.ts.map +1 -1
  34. package/dist/project-utils.js +2 -6
  35. package/dist/project-utils.js.map +1 -1
  36. package/dist/registry.d.ts +52 -0
  37. package/dist/registry.d.ts.map +1 -0
  38. package/dist/registry.js +204 -0
  39. package/dist/registry.js.map +1 -0
  40. package/dist/room-registry.d.ts +40 -0
  41. package/dist/room-registry.d.ts.map +1 -0
  42. package/dist/room-registry.js +112 -0
  43. package/dist/room-registry.js.map +1 -0
  44. package/dist/sandbox/sprites-bootstrap.d.ts.map +1 -1
  45. package/dist/sandbox/sprites-bootstrap.js +7 -1
  46. package/dist/sandbox/sprites-bootstrap.js.map +1 -1
  47. package/dist/sandbox/sprites.d.ts +5 -0
  48. package/dist/sandbox/sprites.d.ts.map +1 -1
  49. package/dist/sandbox/sprites.js +22 -2
  50. package/dist/sandbox/sprites.js.map +1 -1
  51. package/dist/server.d.ts +9 -2
  52. package/dist/server.d.ts.map +1 -1
  53. package/dist/server.js +616 -58
  54. package/dist/server.js.map +1 -1
  55. package/dist/sessions.d.ts +2 -0
  56. package/dist/sessions.d.ts.map +1 -1
  57. package/dist/sessions.js.map +1 -1
  58. package/dist/shared-sessions.d.ts +16 -0
  59. package/dist/shared-sessions.d.ts.map +1 -0
  60. package/dist/shared-sessions.js +52 -0
  61. package/dist/shared-sessions.js.map +1 -0
  62. package/dist/streams.d.ts +8 -0
  63. package/dist/streams.d.ts.map +1 -1
  64. package/dist/streams.js +22 -0
  65. package/dist/streams.js.map +1 -1
  66. package/package.json +15 -2
  67. package/dist/client/assets/index-CK__1-6e.css +0 -1
  68. package/dist/client/assets/index-DKL-jl7t.js +0 -241
@@ -0,0 +1,28 @@
1
+ import type { SessionInfo } from "./sessions.js";
2
+ /**
3
+ * Lightweight in-memory session store for the current server lifetime.
4
+ *
5
+ * Sessions are private to each user (stored in their browser's localStorage).
6
+ * The server only tracks active sessions for sandbox/bridge management.
7
+ * This store is NOT persisted — it resets on server restart.
8
+ */
9
+ export declare class ActiveSessions {
10
+ private sessions;
11
+ private transcriptToSession;
12
+ add(session: SessionInfo): void;
13
+ get(id: string): SessionInfo | undefined;
14
+ update(id: string, update: Partial<SessionInfo>): void;
15
+ delete(id: string): boolean;
16
+ /** Check if a session exists in the active store. */
17
+ has(id: string): boolean;
18
+ /**
19
+ * Look up the EA session ID for a Claude Code transcript path.
20
+ * Returns undefined if no mapping exists or the session has been deleted.
21
+ */
22
+ getByTranscript(transcriptPath: string): string | undefined;
23
+ /**
24
+ * Map a transcript path to an EA session ID.
25
+ */
26
+ mapTranscript(transcriptPath: string, sessionId: string): void;
27
+ }
28
+ //# sourceMappingURL=active-sessions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"active-sessions.d.ts","sourceRoot":"","sources":["../src/active-sessions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD;;;;;;GAMG;AACH,qBAAa,cAAc;IAC1B,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,mBAAmB,CAA4B;IAEvD,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAI/B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAIxC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,IAAI;IAStD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI3B,qDAAqD;IACrD,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAMxB;;;OAGG;IACH,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAM3D;;OAEG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;CAG9D"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Lightweight in-memory session store for the current server lifetime.
3
+ *
4
+ * Sessions are private to each user (stored in their browser's localStorage).
5
+ * The server only tracks active sessions for sandbox/bridge management.
6
+ * This store is NOT persisted — it resets on server restart.
7
+ */
8
+ export class ActiveSessions {
9
+ sessions = new Map();
10
+ transcriptToSession = new Map();
11
+ add(session) {
12
+ this.sessions.set(session.id, session);
13
+ }
14
+ get(id) {
15
+ return this.sessions.get(id);
16
+ }
17
+ update(id, update) {
18
+ const session = this.sessions.get(id);
19
+ if (session) {
20
+ Object.assign(session, update, {
21
+ lastActiveAt: new Date().toISOString(),
22
+ });
23
+ }
24
+ }
25
+ delete(id) {
26
+ return this.sessions.delete(id);
27
+ }
28
+ /** Check if a session exists in the active store. */
29
+ has(id) {
30
+ return this.sessions.has(id);
31
+ }
32
+ // --- Transcript → Session Mapping (for Claude Code hook integration) ---
33
+ /**
34
+ * Look up the EA session ID for a Claude Code transcript path.
35
+ * Returns undefined if no mapping exists or the session has been deleted.
36
+ */
37
+ getByTranscript(transcriptPath) {
38
+ const sessionId = this.transcriptToSession.get(transcriptPath);
39
+ if (!sessionId)
40
+ return undefined;
41
+ return this.sessions.has(sessionId) ? sessionId : undefined;
42
+ }
43
+ /**
44
+ * Map a transcript path to an EA session ID.
45
+ */
46
+ mapTranscript(transcriptPath, sessionId) {
47
+ this.transcriptToSession.set(transcriptPath, sessionId);
48
+ }
49
+ }
50
+ //# sourceMappingURL=active-sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"active-sessions.js","sourceRoot":"","sources":["../src/active-sessions.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IAClB,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAA;IACzC,mBAAmB,GAAG,IAAI,GAAG,EAAkB,CAAA;IAEvD,GAAG,CAAC,OAAoB;QACvB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;IACvC,CAAC;IAED,GAAG,CAAC,EAAU;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC7B,CAAC;IAED,MAAM,CAAC,EAAU,EAAE,MAA4B;QAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QACrC,IAAI,OAAO,EAAE,CAAC;YACb,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE;gBAC9B,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACtC,CAAC,CAAA;QACH,CAAC;IACF,CAAC;IAED,MAAM,CAAC,EAAU;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAChC,CAAC;IAED,qDAAqD;IACrD,GAAG,CAAC,EAAU;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC7B,CAAC;IAED,0EAA0E;IAE1E;;;OAGG;IACH,eAAe,CAAC,cAAsB;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;QAC9D,IAAI,CAAC,SAAS;YAAE,OAAO,SAAS,CAAA;QAChC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;IAC5D,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,cAAsB,EAAE,SAAiB;QACtD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,CAAA;IACxD,CAAC;CACD"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * SessionBridge implementation that runs Claude Code CLI inside a Docker
3
+ * container via `docker exec -i`, communicating via stream-json NDJSON.
4
+ *
5
+ * The bridge translates Claude Code's stream-json output into EngineEvents
6
+ * and writes them to the Durable Stream for the UI. User messages and
7
+ * gate responses are sent to Claude Code's stdin.
8
+ */
9
+ import type { EngineEvent } from "@electric-agent/protocol";
10
+ import type { StreamConnectionInfo } from "../streams.js";
11
+ import type { SessionBridge } from "./types.js";
12
+ export interface ClaudeCodeDockerConfig {
13
+ /** Initial prompt (the user's app description or task) */
14
+ prompt: string;
15
+ /** Working directory inside the container */
16
+ cwd: string;
17
+ /** Model to use (default: claude-sonnet-4-6) */
18
+ model?: string;
19
+ /** Allowed tools (default: all standard tools) */
20
+ allowedTools?: string[];
21
+ /** Additional CLI flags */
22
+ extraFlags?: string[];
23
+ }
24
+ export declare class ClaudeCodeDockerBridge implements SessionBridge {
25
+ readonly sessionId: string;
26
+ readonly streamUrl: string;
27
+ readonly streamHeaders: Record<string, string>;
28
+ private containerId;
29
+ private config;
30
+ private writer;
31
+ private parser;
32
+ private agentEventCallbacks;
33
+ private completeCallbacks;
34
+ private closed;
35
+ private proc;
36
+ constructor(sessionId: string, connection: StreamConnectionInfo, containerId: string, config: ClaudeCodeDockerConfig);
37
+ emit(event: EngineEvent): Promise<void>;
38
+ /**
39
+ * Send a follow-up user message to Claude Code via stdin.
40
+ * Used for iteration requests (the user types a new message in the UI).
41
+ */
42
+ sendCommand(cmd: Record<string, unknown>): Promise<void>;
43
+ /**
44
+ * Send a gate response back to Claude Code as a user message.
45
+ * For ask_user_question gates, the user's answer becomes a follow-up message.
46
+ */
47
+ sendGateResponse(gate: string, value: Record<string, unknown>): Promise<void>;
48
+ onAgentEvent(cb: (event: EngineEvent) => void): void;
49
+ onComplete(cb: (success: boolean) => void): void;
50
+ start(): Promise<void>;
51
+ close(): void;
52
+ private handleLine;
53
+ private dispatchEvent;
54
+ /**
55
+ * Write a user message to Claude Code's stdin in stream-json format.
56
+ */
57
+ private writeUserMessage;
58
+ }
59
+ //# sourceMappingURL=claude-code-docker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-docker.d.ts","sourceRoot":"","sources":["../../src/bridge/claude-code-docker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAE9D,MAAM,WAAW,sBAAsB;IACtC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAA;IACX,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAcD,qBAAa,sBAAuB,YAAW,aAAa;IAC3D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE9C,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,mBAAmB,CAA0C;IACrE,OAAO,CAAC,iBAAiB,CAAwC;IACjE,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,IAAI,CAA4B;gBAGvC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,oBAAoB,EAChC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,sBAAsB;IAezB,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAM7C;;;OAGG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9D;;;OAGG;IACG,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAiCnF,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;IAIpD,UAAU,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAI1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8E5B,KAAK,IAAI,IAAI;IAiBb,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,aAAa;IA4CrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAQxB"}
@@ -0,0 +1,258 @@
1
+ /**
2
+ * SessionBridge implementation that runs Claude Code CLI inside a Docker
3
+ * container via `docker exec -i`, communicating via stream-json NDJSON.
4
+ *
5
+ * The bridge translates Claude Code's stream-json output into EngineEvents
6
+ * and writes them to the Durable Stream for the UI. User messages and
7
+ * gate responses are sent to Claude Code's stdin.
8
+ */
9
+ import { spawn } from "node:child_process";
10
+ import * as readline from "node:readline";
11
+ import { DurableStream } from "@durable-streams/client";
12
+ import { ts } from "@electric-agent/protocol";
13
+ import { createStreamJsonParser } from "./stream-json-parser.js";
14
+ const DEFAULT_ALLOWED_TOOLS = [
15
+ "Read",
16
+ "Write",
17
+ "Edit",
18
+ "Bash",
19
+ "Glob",
20
+ "Grep",
21
+ "WebSearch",
22
+ "TodoWrite",
23
+ "AskUserQuestion",
24
+ ];
25
+ export class ClaudeCodeDockerBridge {
26
+ sessionId;
27
+ streamUrl;
28
+ streamHeaders;
29
+ containerId;
30
+ config;
31
+ writer;
32
+ parser = createStreamJsonParser();
33
+ agentEventCallbacks = [];
34
+ completeCallbacks = [];
35
+ closed = false;
36
+ proc = null;
37
+ constructor(sessionId, connection, containerId, config) {
38
+ this.sessionId = sessionId;
39
+ this.streamUrl = connection.url;
40
+ this.streamHeaders = connection.headers;
41
+ this.containerId = containerId;
42
+ this.config = config;
43
+ this.writer = new DurableStream({
44
+ url: connection.url,
45
+ headers: connection.headers,
46
+ contentType: "application/json",
47
+ });
48
+ }
49
+ async emit(event) {
50
+ if (this.closed)
51
+ return;
52
+ const msg = { source: "server", ...event };
53
+ await this.writer.append(JSON.stringify(msg));
54
+ }
55
+ /**
56
+ * Send a follow-up user message to Claude Code via stdin.
57
+ * Used for iteration requests (the user types a new message in the UI).
58
+ */
59
+ async sendCommand(cmd) {
60
+ if (this.closed || !this.proc?.stdin?.writable)
61
+ return;
62
+ // For iteration: send the request as a user message to Claude Code's stdin
63
+ if (cmd.command === "iterate" && typeof cmd.request === "string") {
64
+ this.writeUserMessage(cmd.request);
65
+ return;
66
+ }
67
+ // For initial "new" command: this is handled in start() via the prompt
68
+ // Other commands are ignored — Claude Code doesn't understand them
69
+ console.log(`[claude-code-docker] Ignoring unsupported command: ${cmd.command}`);
70
+ }
71
+ /**
72
+ * Send a gate response back to Claude Code as a user message.
73
+ * For ask_user_question gates, the user's answer becomes a follow-up message.
74
+ */
75
+ async sendGateResponse(gate, value) {
76
+ if (this.closed || !this.proc?.stdin?.writable)
77
+ return;
78
+ if (gate === "ask_user_question" || gate.startsWith("ask_user_question:")) {
79
+ const answer = value.answer || "";
80
+ this.writeUserMessage(answer);
81
+ return;
82
+ }
83
+ if (gate === "clarification") {
84
+ const answers = value.answers;
85
+ if (answers?.length) {
86
+ this.writeUserMessage(answers.join("\n"));
87
+ }
88
+ return;
89
+ }
90
+ if (gate === "approval") {
91
+ const decision = value.decision || "approve";
92
+ this.writeUserMessage(decision);
93
+ return;
94
+ }
95
+ if (gate === "continue") {
96
+ const proceed = value.proceed;
97
+ this.writeUserMessage(proceed ? "continue" : "stop");
98
+ return;
99
+ }
100
+ // Generic: send the value as JSON
101
+ this.writeUserMessage(JSON.stringify(value));
102
+ }
103
+ onAgentEvent(cb) {
104
+ this.agentEventCallbacks.push(cb);
105
+ }
106
+ onComplete(cb) {
107
+ this.completeCallbacks.push(cb);
108
+ }
109
+ async start() {
110
+ if (this.closed)
111
+ return;
112
+ const allowedTools = this.config.allowedTools ?? DEFAULT_ALLOWED_TOOLS;
113
+ const model = this.config.model ?? "claude-sonnet-4-6";
114
+ // Build the claude CLI command
115
+ const claudeArgs = [
116
+ "-p",
117
+ this.config.prompt,
118
+ "--output-format",
119
+ "stream-json",
120
+ "--verbose",
121
+ "--model",
122
+ model,
123
+ "--dangerously-skip-permissions",
124
+ "--allowedTools",
125
+ allowedTools.join(","),
126
+ ...(this.config.extraFlags ?? []),
127
+ ];
128
+ // Escape for bash
129
+ const escapedArgs = claudeArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
130
+ const cmd = `cd '${this.config.cwd}' && claude ${escapedArgs}`;
131
+ // Note: do NOT use -i flag — Claude Code detects interactive stdin and blocks
132
+ // waiting for input even when -p is provided. Without -i, stdout flows normally.
133
+ this.proc = spawn("docker", ["exec", this.containerId, "bash", "-c", cmd], {
134
+ stdio: ["pipe", "pipe", "pipe"],
135
+ });
136
+ console.log(`[claude-code-docker] Started: session=${this.sessionId} container=${this.containerId} pid=${this.proc.pid}`);
137
+ console.log(`[claude-code-docker] cmd: ${cmd}`);
138
+ // Read stdout line by line (stream-json NDJSON)
139
+ if (this.proc.stdout) {
140
+ const rl = readline.createInterface({
141
+ input: this.proc.stdout,
142
+ terminal: false,
143
+ });
144
+ rl.on("line", (line) => {
145
+ if (this.closed)
146
+ return;
147
+ console.log(`[claude-code-docker:stdout] ${line.slice(0, 120)}...`);
148
+ this.handleLine(line);
149
+ });
150
+ }
151
+ // Log stderr
152
+ if (this.proc.stderr) {
153
+ const stderrRl = readline.createInterface({
154
+ input: this.proc.stderr,
155
+ terminal: false,
156
+ });
157
+ stderrRl.on("line", (line) => {
158
+ if (!this.closed) {
159
+ console.error(`[claude-code-docker:stderr] ${line}`);
160
+ }
161
+ });
162
+ }
163
+ // Handle process exit
164
+ this.proc.on("exit", (code) => {
165
+ console.log(`[claude-code-docker] Process exited: code=${code} session=${this.sessionId}`);
166
+ // If process exits without a session_end event, emit one
167
+ if (!this.closed) {
168
+ const endEvent = {
169
+ type: "session_end",
170
+ success: code === 0,
171
+ ts: ts(),
172
+ };
173
+ this.dispatchEvent(endEvent);
174
+ }
175
+ });
176
+ }
177
+ close() {
178
+ this.closed = true;
179
+ if (this.proc) {
180
+ try {
181
+ this.proc.stdin?.end();
182
+ this.proc.kill("SIGTERM");
183
+ }
184
+ catch {
185
+ // Process may already be dead
186
+ }
187
+ this.proc = null;
188
+ }
189
+ }
190
+ // -----------------------------------------------------------------------
191
+ // Private helpers
192
+ // -----------------------------------------------------------------------
193
+ handleLine(line) {
194
+ const trimmed = line.trim();
195
+ if (!trimmed)
196
+ return;
197
+ const events = this.parser.parse(trimmed);
198
+ for (const event of events) {
199
+ this.dispatchEvent(event);
200
+ }
201
+ }
202
+ dispatchEvent(event) {
203
+ // Write to Durable Stream for UI
204
+ const msg = { source: "agent", ...event };
205
+ this.writer.append(JSON.stringify(msg)).catch(() => { });
206
+ // Detect dev:start in Bash tool_use → emit app_ready for the UI preview
207
+ if (event.type === "pre_tool_use" && event.tool_name === "Bash") {
208
+ const cmd = event.tool_input?.command;
209
+ if (typeof cmd === "string" && /\bdev:start\b/.test(cmd)) {
210
+ const appReady = { type: "app_ready", ts: ts() };
211
+ const appReadyMsg = { source: "agent", ...appReady };
212
+ this.writer.append(JSON.stringify(appReadyMsg)).catch(() => { });
213
+ for (const cb of this.agentEventCallbacks) {
214
+ try {
215
+ cb(appReady);
216
+ }
217
+ catch {
218
+ // Swallow
219
+ }
220
+ }
221
+ }
222
+ }
223
+ // Dispatch to callbacks
224
+ for (const cb of this.agentEventCallbacks) {
225
+ try {
226
+ cb(event);
227
+ }
228
+ catch {
229
+ // Swallow callback errors
230
+ }
231
+ }
232
+ // Detect session_end
233
+ if (event.type === "session_end" && "success" in event) {
234
+ const success = event.success;
235
+ for (const cb of this.completeCallbacks) {
236
+ try {
237
+ cb(success);
238
+ }
239
+ catch {
240
+ // Swallow callback errors
241
+ }
242
+ }
243
+ }
244
+ }
245
+ /**
246
+ * Write a user message to Claude Code's stdin in stream-json format.
247
+ */
248
+ writeUserMessage(content) {
249
+ if (!this.proc?.stdin?.writable)
250
+ return;
251
+ const msg = JSON.stringify({
252
+ type: "user",
253
+ message: { role: "user", content },
254
+ });
255
+ this.proc.stdin.write(`${msg}\n`);
256
+ }
257
+ }
258
+ //# sourceMappingURL=claude-code-docker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-docker.js","sourceRoot":"","sources":["../../src/bridge/claude-code-docker.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAqB,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC7D,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AAEvD,OAAO,EAAE,EAAE,EAAE,MAAM,0BAA0B,CAAA;AAE7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAgBhE,MAAM,qBAAqB,GAAG;IAC7B,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,WAAW;IACX,WAAW;IACX,iBAAiB;CACjB,CAAA;AAED,MAAM,OAAO,sBAAsB;IACzB,SAAS,CAAQ;IACjB,SAAS,CAAQ;IACjB,aAAa,CAAwB;IAEtC,WAAW,CAAQ;IACnB,MAAM,CAAwB;IAC9B,MAAM,CAAe;IACrB,MAAM,GAAG,sBAAsB,EAAE,CAAA;IACjC,mBAAmB,GAAwC,EAAE,CAAA;IAC7D,iBAAiB,GAAsC,EAAE,CAAA;IACzD,MAAM,GAAG,KAAK,CAAA;IACd,IAAI,GAAwB,IAAI,CAAA;IAExC,YACC,SAAiB,EACjB,UAAgC,EAChC,WAAmB,EACnB,MAA8B;QAE9B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAC1B,IAAI,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,CAAA;QAC/B,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,OAAO,CAAA;QACvC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QAEpB,IAAI,CAAC,MAAM,GAAG,IAAI,aAAa,CAAC;YAC/B,GAAG,EAAE,UAAU,CAAC,GAAG;YACnB,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,WAAW,EAAE,kBAAkB;SAC/B,CAAC,CAAA;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAkB;QAC5B,IAAI,IAAI,CAAC,MAAM;YAAE,OAAM;QACvB,MAAM,GAAG,GAAkB,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAA;QACzD,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAA;IAC9C,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,WAAW,CAAC,GAA4B;QAC7C,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ;YAAE,OAAM;QAEtD,2EAA2E;QAC3E,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAClE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;YAClC,OAAM;QACP,CAAC;QAED,uEAAuE;QACvE,mEAAmE;QACnE,OAAO,CAAC,GAAG,CAAC,sDAAsD,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IACjF,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,gBAAgB,CAAC,IAAY,EAAE,KAA8B;QAClE,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ;YAAE,OAAM;QAEtD,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAC3E,MAAM,MAAM,GAAI,KAAK,CAAC,MAAiB,IAAI,EAAE,CAAA;YAC7C,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAA;YAC7B,OAAM;QACP,CAAC;QAED,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,OAA+B,CAAA;YACrD,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;gBACrB,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAA;YAC1C,CAAC;YACD,OAAM;QACP,CAAC;QAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACzB,MAAM,QAAQ,GAAI,KAAK,CAAC,QAAmB,IAAI,SAAS,CAAA;YACxD,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAA;YAC/B,OAAM;QACP,CAAC;QAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAkB,CAAA;YACxC,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;YACpD,OAAM;QACP,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAC7C,CAAC;IAED,YAAY,CAAC,EAAgC;QAC5C,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAClC,CAAC;IAED,UAAU,CAAC,EAA8B;QACxC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChC,CAAC;IAED,KAAK,CAAC,KAAK;QACV,IAAI,IAAI,CAAC,MAAM;YAAE,OAAM;QAEvB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,qBAAqB,CAAA;QACtE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,mBAAmB,CAAA;QAEtD,+BAA+B;QAC/B,MAAM,UAAU,GAAG;YAClB,IAAI;YACJ,IAAI,CAAC,MAAM,CAAC,MAAM;YAClB,iBAAiB;YACjB,aAAa;YACb,WAAW;YACX,SAAS;YACT,KAAK;YACL,gCAAgC;YAChC,gBAAgB;YAChB,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;SACjC,CAAA;QAED,kBAAkB;QAClB,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACpF,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,eAAe,WAAW,EAAE,CAAA;QAE9D,8EAA8E;QAC9E,iFAAiF;QACjF,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE;YAC1E,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAC/B,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,CACV,yCAAyC,IAAI,CAAC,SAAS,cAAc,IAAI,CAAC,WAAW,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAC5G,CAAA;QACD,OAAO,CAAC,GAAG,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAA;QAE/C,gDAAgD;QAChD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;gBACnC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;gBACvB,QAAQ,EAAE,KAAK;aACf,CAAC,CAAA;YAEF,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACtB,IAAI,IAAI,CAAC,MAAM;oBAAE,OAAM;gBACvB,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAA;gBACnE,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAA;YACtB,CAAC,CAAC,CAAA;QACH,CAAC;QAED,aAAa;QACb,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,QAAQ,CAAC,eAAe,CAAC;gBACzC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;gBACvB,QAAQ,EAAE,KAAK;aACf,CAAC,CAAA;YACF,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC5B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBAClB,OAAO,CAAC,KAAK,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAA;gBACrD,CAAC;YACF,CAAC,CAAC,CAAA;QACH,CAAC;QAED,sBAAsB;QACtB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YAC7B,OAAO,CAAC,GAAG,CAAC,6CAA6C,IAAI,YAAY,IAAI,CAAC,SAAS,EAAE,CAAC,CAAA;YAC1F,yDAAyD;YACzD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBAClB,MAAM,QAAQ,GAAgB;oBAC7B,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,IAAI,KAAK,CAAC;oBACnB,EAAE,EAAE,EAAE,EAAE;iBACR,CAAA;gBACD,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;YAC7B,CAAC;QACF,CAAC,CAAC,CAAA;IACH,CAAC;IAED,KAAK;QACJ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAA;QAClB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC;gBACJ,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,CAAA;gBACtB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YAC1B,CAAC;YAAC,MAAM,CAAC;gBACR,8BAA8B;YAC/B,CAAC;YACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QACjB,CAAC;IACF,CAAC;IAED,0EAA0E;IAC1E,kBAAkB;IAClB,0EAA0E;IAElE,UAAU,CAAC,IAAY;QAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACzC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;QAC1B,CAAC;IACF,CAAC;IAEO,aAAa,CAAC,KAAkB;QACvC,iCAAiC;QACjC,MAAM,GAAG,GAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAA;QACxD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;QAEvD,wEAAwE;QACxE,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,SAAS,KAAK,MAAM,EAAE,CAAC;YACjE,MAAM,GAAG,GAAI,KAAK,CAAC,UAAsC,EAAE,OAAO,CAAA;YAClE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1D,MAAM,QAAQ,GAAgB,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAA;gBAC7D,MAAM,WAAW,GAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAA;gBACnE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBAC/D,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;oBAC3C,IAAI,CAAC;wBACJ,EAAE,CAAC,QAAQ,CAAC,CAAA;oBACb,CAAC;oBAAC,MAAM,CAAC;wBACR,UAAU;oBACX,CAAC;gBACF,CAAC;YACF,CAAC;QACF,CAAC;QAED,wBAAwB;QACxB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3C,IAAI,CAAC;gBACJ,EAAE,CAAC,KAAK,CAAC,CAAA;YACV,CAAC;YAAC,MAAM,CAAC;gBACR,0BAA0B;YAC3B,CAAC;QACF,CAAC;QAED,qBAAqB;QACrB,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,SAAS,IAAI,KAAK,EAAE,CAAC;YACxD,MAAM,OAAO,GAAI,KAA4C,CAAC,OAAO,CAAA;YACrE,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBACzC,IAAI,CAAC;oBACJ,EAAE,CAAC,OAAO,CAAC,CAAA;gBACZ,CAAC;gBAAC,MAAM,CAAC;oBACR,0BAA0B;gBAC3B,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,OAAe;QACvC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ;YAAE,OAAM;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC;YAC1B,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;SAClC,CAAC,CAAA;QACF,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAA;IAClC,CAAC;CACD"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * SessionBridge implementation that runs Claude Code CLI inside a Sprites
3
+ * sandbox via the Sprites SDK session API, communicating via stream-json NDJSON.
4
+ *
5
+ * The bridge translates Claude Code's stream-json output into EngineEvents
6
+ * and writes them to the Durable Stream for the UI. User messages and
7
+ * gate responses are sent to Claude Code's stdin.
8
+ */
9
+ import type { EngineEvent } from "@electric-agent/protocol";
10
+ import type { Sprite } from "@fly/sprites";
11
+ import type { StreamConnectionInfo } from "../streams.js";
12
+ import type { SessionBridge } from "./types.js";
13
+ export interface ClaudeCodeSpritesConfig {
14
+ /** Initial prompt (the user's app description or task) */
15
+ prompt: string;
16
+ /** Working directory inside the sprite */
17
+ cwd: string;
18
+ /** Model to use (default: claude-sonnet-4-6) */
19
+ model?: string;
20
+ /** Allowed tools (default: all standard tools) */
21
+ allowedTools?: string[];
22
+ /** Additional CLI flags */
23
+ extraFlags?: string[];
24
+ }
25
+ export declare class ClaudeCodeSpritesBridge implements SessionBridge {
26
+ readonly sessionId: string;
27
+ readonly streamUrl: string;
28
+ readonly streamHeaders: Record<string, string>;
29
+ private sprite;
30
+ private config;
31
+ private writer;
32
+ private parser;
33
+ private agentEventCallbacks;
34
+ private completeCallbacks;
35
+ private closed;
36
+ private cmd;
37
+ constructor(sessionId: string, connection: StreamConnectionInfo, sprite: Sprite, config: ClaudeCodeSpritesConfig);
38
+ emit(event: EngineEvent): Promise<void>;
39
+ sendCommand(cmd: Record<string, unknown>): Promise<void>;
40
+ sendGateResponse(gate: string, value: Record<string, unknown>): Promise<void>;
41
+ onAgentEvent(cb: (event: EngineEvent) => void): void;
42
+ onComplete(cb: (success: boolean) => void): void;
43
+ start(): Promise<void>;
44
+ close(): void;
45
+ private handleLine;
46
+ private dispatchEvent;
47
+ private writeUserMessage;
48
+ }
49
+ //# sourceMappingURL=claude-code-sprites.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-sprites.d.ts","sourceRoot":"","sources":["../../src/bridge/claude-code-sprites.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,cAAc,CAAA;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAA;AAI9D,MAAM,WAAW,uBAAuB;IACvC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,GAAG,EAAE,MAAM,CAAA;IACX,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAcD,qBAAa,uBAAwB,YAAW,aAAa;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE9C,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,mBAAmB,CAA0C;IACrE,OAAO,CAAC,iBAAiB,CAAwC;IACjE,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,GAAG,CAA6B;gBAGvC,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,oBAAoB,EAChC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,uBAAuB;IAe1B,IAAI,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAMvC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxD,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAgCnF,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;IAIpD,UAAU,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAI1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoE5B,KAAK,IAAI,IAAI;IAgBb,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,aAAa;IAyCrB,OAAO,CAAC,gBAAgB;CAQxB"}