@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,231 @@
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 * as readline from "node:readline";
10
+ import { DurableStream } from "@durable-streams/client";
11
+ import { ts } from "@electric-agent/protocol";
12
+ import { createStreamJsonParser } from "./stream-json-parser.js";
13
+ const SPRITES_SESSION_ID = "claude-code-session";
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 ClaudeCodeSpritesBridge {
26
+ sessionId;
27
+ streamUrl;
28
+ streamHeaders;
29
+ sprite;
30
+ config;
31
+ writer;
32
+ parser = createStreamJsonParser();
33
+ agentEventCallbacks = [];
34
+ completeCallbacks = [];
35
+ closed = false;
36
+ cmd = null;
37
+ constructor(sessionId, connection, sprite, config) {
38
+ this.sessionId = sessionId;
39
+ this.streamUrl = connection.url;
40
+ this.streamHeaders = connection.headers;
41
+ this.sprite = sprite;
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
+ async sendCommand(cmd) {
56
+ if (this.closed || !this.cmd)
57
+ return;
58
+ if (cmd.command === "iterate" && typeof cmd.request === "string") {
59
+ this.writeUserMessage(cmd.request);
60
+ return;
61
+ }
62
+ console.log(`[claude-code-sprites] Ignoring unsupported command: ${cmd.command}`);
63
+ }
64
+ async sendGateResponse(gate, value) {
65
+ if (this.closed || !this.cmd)
66
+ return;
67
+ if (gate === "ask_user_question" || gate.startsWith("ask_user_question:")) {
68
+ const answer = value.answer || "";
69
+ this.writeUserMessage(answer);
70
+ return;
71
+ }
72
+ if (gate === "clarification") {
73
+ const answers = value.answers;
74
+ if (answers?.length) {
75
+ this.writeUserMessage(answers.join("\n"));
76
+ }
77
+ return;
78
+ }
79
+ if (gate === "approval") {
80
+ const decision = value.decision || "approve";
81
+ this.writeUserMessage(decision);
82
+ return;
83
+ }
84
+ if (gate === "continue") {
85
+ const proceed = value.proceed;
86
+ this.writeUserMessage(proceed ? "continue" : "stop");
87
+ return;
88
+ }
89
+ this.writeUserMessage(JSON.stringify(value));
90
+ }
91
+ onAgentEvent(cb) {
92
+ this.agentEventCallbacks.push(cb);
93
+ }
94
+ onComplete(cb) {
95
+ this.completeCallbacks.push(cb);
96
+ }
97
+ async start() {
98
+ if (this.closed)
99
+ return;
100
+ const allowedTools = this.config.allowedTools ?? DEFAULT_ALLOWED_TOOLS;
101
+ const model = this.config.model ?? "claude-sonnet-4-6";
102
+ // Build the claude CLI command
103
+ const claudeArgs = [
104
+ "-p",
105
+ this.config.prompt,
106
+ "--output-format",
107
+ "stream-json",
108
+ "--verbose",
109
+ "--model",
110
+ model,
111
+ "--dangerously-skip-permissions",
112
+ "--allowedTools",
113
+ allowedTools.join(","),
114
+ ...(this.config.extraFlags ?? []),
115
+ ];
116
+ // Escape for bash — use bash -c with properly escaped args
117
+ const escapedArgs = claudeArgs.map((a) => `'${a.replace(/'/g, "'\\''")}'`).join(" ");
118
+ const fullCmd = `source /etc/profile.d/npm-global.sh 2>/dev/null; source /etc/profile.d/electric-agent.sh 2>/dev/null; cd '${this.config.cwd}' && claude ${escapedArgs}`;
119
+ this.cmd = this.sprite.createSession("bash", ["-c", fullCmd], {
120
+ detachable: true,
121
+ sessionId: SPRITES_SESSION_ID,
122
+ });
123
+ console.log(`[claude-code-sprites] Started: session=${this.sessionId}`);
124
+ // Read stdout line by line (stream-json NDJSON)
125
+ const rl = readline.createInterface({
126
+ input: this.cmd.stdout,
127
+ terminal: false,
128
+ });
129
+ rl.on("line", (line) => {
130
+ if (this.closed)
131
+ return;
132
+ this.handleLine(line);
133
+ });
134
+ // Log stderr
135
+ const stderrRl = readline.createInterface({
136
+ input: this.cmd.stderr,
137
+ terminal: false,
138
+ });
139
+ stderrRl.on("line", (line) => {
140
+ if (!this.closed) {
141
+ console.error(`[claude-code-sprites:stderr] ${line}`);
142
+ }
143
+ });
144
+ // Handle process exit
145
+ this.cmd.on("exit", (code) => {
146
+ console.log(`[claude-code-sprites] Process exited: code=${code} session=${this.sessionId}`);
147
+ if (!this.closed) {
148
+ const endEvent = {
149
+ type: "session_end",
150
+ success: code === 0,
151
+ ts: ts(),
152
+ };
153
+ this.dispatchEvent(endEvent);
154
+ }
155
+ });
156
+ }
157
+ close() {
158
+ this.closed = true;
159
+ if (this.cmd) {
160
+ try {
161
+ this.cmd.kill();
162
+ }
163
+ catch {
164
+ // Process may already be dead
165
+ }
166
+ this.cmd = null;
167
+ }
168
+ }
169
+ // -----------------------------------------------------------------------
170
+ // Private helpers
171
+ // -----------------------------------------------------------------------
172
+ handleLine(line) {
173
+ const trimmed = line.trim();
174
+ if (!trimmed)
175
+ return;
176
+ const events = this.parser.parse(trimmed);
177
+ for (const event of events) {
178
+ this.dispatchEvent(event);
179
+ }
180
+ }
181
+ dispatchEvent(event) {
182
+ const msg = { source: "agent", ...event };
183
+ this.writer.append(JSON.stringify(msg)).catch(() => { });
184
+ // Detect dev:start in Bash tool_use → emit app_ready for the UI preview
185
+ if (event.type === "pre_tool_use" && event.tool_name === "Bash") {
186
+ const cmd = event.tool_input?.command;
187
+ if (typeof cmd === "string" && /\bdev:start\b/.test(cmd)) {
188
+ const appReady = { type: "app_ready", ts: ts() };
189
+ const appReadyMsg = { source: "agent", ...appReady };
190
+ this.writer.append(JSON.stringify(appReadyMsg)).catch(() => { });
191
+ for (const cb of this.agentEventCallbacks) {
192
+ try {
193
+ cb(appReady);
194
+ }
195
+ catch {
196
+ // Swallow
197
+ }
198
+ }
199
+ }
200
+ }
201
+ for (const cb of this.agentEventCallbacks) {
202
+ try {
203
+ cb(event);
204
+ }
205
+ catch {
206
+ // Swallow callback errors
207
+ }
208
+ }
209
+ if (event.type === "session_end" && "success" in event) {
210
+ const success = event.success;
211
+ for (const cb of this.completeCallbacks) {
212
+ try {
213
+ cb(success);
214
+ }
215
+ catch {
216
+ // Swallow callback errors
217
+ }
218
+ }
219
+ }
220
+ }
221
+ writeUserMessage(content) {
222
+ if (!this.cmd)
223
+ return;
224
+ const msg = JSON.stringify({
225
+ type: "user",
226
+ message: { role: "user", content },
227
+ });
228
+ this.cmd.stdin.write(`${msg}\n`);
229
+ }
230
+ }
231
+ //# sourceMappingURL=claude-code-sprites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-sprites.js","sourceRoot":"","sources":["../../src/bridge/claude-code-sprites.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Generates CLAUDE.md files for project workspaces.
3
+ *
4
+ * Two variants:
5
+ * - `generateClaudeMd()` — for Claude Code mode (streamlined, no redundant instructions)
6
+ * - `generateElectricAgentClaudeMd()` — for electric-agent mode (full instructions for the SDK agent)
7
+ */
8
+ export interface ClaudeMdOptions {
9
+ /** The user's app description */
10
+ description: string;
11
+ /** Project name (kebab-case) */
12
+ projectName: string;
13
+ /** Absolute path to the project inside the sandbox */
14
+ projectDir: string;
15
+ /** Whether this is an iteration (vs initial generation) */
16
+ isIteration?: boolean;
17
+ /** Iteration request text (if isIteration) */
18
+ iterationRequest?: string;
19
+ /** Sandbox runtime — affects environment-specific instructions */
20
+ runtime?: "docker" | "sprites" | "daytona";
21
+ }
22
+ export declare function generateClaudeMd(opts: ClaudeMdOptions): string;
23
+ export declare function generateElectricAgentClaudeMd(opts: ClaudeMdOptions): string;
24
+ //# sourceMappingURL=claude-md-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-md-generator.d.ts","sourceRoot":"","sources":["../../src/bridge/claude-md-generator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,eAAe;IAC/B,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAA;IACnB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAA;IAClB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,kEAAkE;IAClE,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAA;CAC1C;AAMD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CA8B9D;AAMD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAoC3E"}
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Generates CLAUDE.md files for project workspaces.
3
+ *
4
+ * Two variants:
5
+ * - `generateClaudeMd()` — for Claude Code mode (streamlined, no redundant instructions)
6
+ * - `generateElectricAgentClaudeMd()` — for electric-agent mode (full instructions for the SDK agent)
7
+ */
8
+ // ---------------------------------------------------------------------------
9
+ // Claude Code variant
10
+ // ---------------------------------------------------------------------------
11
+ export function generateClaudeMd(opts) {
12
+ const sections = [];
13
+ sections.push(`# ${opts.projectName}`);
14
+ sections.push("");
15
+ sections.push(PROJECT_CONTEXT);
16
+ sections.push("");
17
+ if (!opts.isIteration) {
18
+ sections.push("## Current Task");
19
+ sections.push(opts.description);
20
+ sections.push("");
21
+ }
22
+ sections.push(SCAFFOLD_STRUCTURE);
23
+ sections.push("");
24
+ sections.push(DRIZZLE_WORKFLOW);
25
+ sections.push("");
26
+ sections.push(GUARDRAILS);
27
+ sections.push("");
28
+ sections.push(PLAYBOOK_INSTRUCTIONS);
29
+ sections.push("");
30
+ sections.push(INFRASTRUCTURE);
31
+ sections.push("");
32
+ sections.push(devServerInstructions(opts.runtime));
33
+ sections.push("");
34
+ sections.push(SSR_RULES);
35
+ sections.push("");
36
+ return sections.join("\n");
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // Electric Agent variant
40
+ // ---------------------------------------------------------------------------
41
+ export function generateElectricAgentClaudeMd(opts) {
42
+ const sections = [];
43
+ sections.push(`# ${opts.projectName}`);
44
+ sections.push("");
45
+ sections.push(PROJECT_CONTEXT);
46
+ sections.push("");
47
+ if (!opts.isIteration) {
48
+ sections.push("## Current Task");
49
+ sections.push(opts.description);
50
+ sections.push("");
51
+ }
52
+ sections.push(SCAFFOLD_STRUCTURE);
53
+ sections.push("");
54
+ sections.push(DRIZZLE_WORKFLOW);
55
+ sections.push("");
56
+ sections.push(GUARDRAILS);
57
+ sections.push("");
58
+ sections.push(PLAYBOOK_INSTRUCTIONS_AGENT);
59
+ sections.push("");
60
+ sections.push(BUILD_INSTRUCTIONS);
61
+ sections.push("");
62
+ sections.push(devServerInstructions(opts.runtime));
63
+ sections.push("");
64
+ sections.push(ARCHITECTURE_REFERENCE);
65
+ sections.push("");
66
+ sections.push(GIT_INSTRUCTIONS);
67
+ sections.push("");
68
+ sections.push(SSR_RULES);
69
+ sections.push("");
70
+ sections.push(ERROR_HANDLING);
71
+ sections.push("");
72
+ return sections.join("\n");
73
+ }
74
+ // ---------------------------------------------------------------------------
75
+ // Shared sections (used by both variants)
76
+ // ---------------------------------------------------------------------------
77
+ const PROJECT_CONTEXT = "## Project Context\nThis is a reactive, real-time application built with Electric SQL + TanStack DB + Drizzle ORM + TanStack Start.";
78
+ const SCAFFOLD_STRUCTURE = `## Scaffold Structure (DO NOT EXPLORE)
79
+ The project is scaffolded from a known template. DO NOT read or explore scaffold files before coding. You already know the structure:
80
+ - src/db/schema.ts — placeholder Drizzle schema (you will overwrite)
81
+ - src/db/zod-schemas.ts — placeholder Zod derivation (you will overwrite)
82
+ - src/db/index.ts — Drizzle client setup (do not modify)
83
+ - src/db/utils.ts — parseDates + generateTxId helpers (do not modify)
84
+ - src/lib/electric-proxy.ts — Electric shape proxy helper (do not modify)
85
+ - src/components/ClientOnly.tsx — SSR wrapper (do not modify, just import when needed)
86
+ - src/routes/__root.tsx — root layout with SSR (do not add ssr:false here)
87
+ - tests/helpers/schema-test-utils.ts — generateValidRow/generateRowWithout (do not modify)
88
+
89
+ DO NOT use Bash/ls/find to explore the project. DO NOT read files you aren't about to modify. Start writing code.`;
90
+ const DRIZZLE_WORKFLOW = `## Drizzle Workflow (CRITICAL)
91
+ Always follow this order:
92
+ 1. Edit src/db/schema.ts (Drizzle pgTable definitions)
93
+ 2. Edit src/db/zod-schemas.ts (derive Zod schemas via createSelectSchema/createInsertSchema from drizzle-zod — NEVER hand-write Zod schemas — ALWAYS import z from "zod/v4" and override ALL timestamp columns with z.union([z.date(), z.string()]).default(() => new Date()) — the .default() is required so collection.insert() works without timestamps)
94
+ 3. Create collection files in src/db/collections/ (import from ../zod-schemas)
95
+ 4. Create API routes (proxy + mutation)
96
+ 5. Create UI components`;
97
+ const GUARDRAILS = `## Guardrails (MUST FOLLOW)
98
+
99
+ ### Protected Files — DO NOT MODIFY
100
+ - docker-compose.yml
101
+ - tsconfig.json
102
+ - biome.json
103
+ - pnpm-lock.yaml
104
+ - postgres.conf
105
+ - vitest.config.ts
106
+ - Caddyfile
107
+
108
+ ### Import Rules
109
+ - Use "zod/v4" (NOT "zod") for all Zod imports
110
+ - Use "lucide-react" for icons (NOT @radix-ui/react-icons)
111
+ - Use "@radix-ui/themes" for Radix components (NOT @radix-ui/react-*)
112
+ - Use "react-router" for routing (NOT react-router-dom)
113
+
114
+ ### Dependency Rules
115
+ - NEVER remove existing dependencies from package.json
116
+ - Only add new dependencies
117
+
118
+ ### Schema Rules
119
+ - ALL timestamp columns MUST use: z.union([z.date(), z.string()]).default(() => new Date())
120
+ - NEVER use z.coerce.date() — it breaks TanStack DB
121
+ - ALL tables MUST have REPLICA IDENTITY FULL (auto-applied by migration hook)
122
+ - UUID primary keys with defaultRandom()
123
+ - timestamp({ withTimezone: true }) for all dates
124
+ - snake_case for SQL table/column names
125
+ - Foreign keys with onDelete: "cascade" where appropriate`;
126
+ function devServerInstructions(runtime) {
127
+ if (runtime === "sprites" || runtime === "daytona") {
128
+ return `## Dev Server & Migrations
129
+ ### Dev Server
130
+ - \`pnpm dev:start\` — start the Vite dev server in the background
131
+ - \`pnpm dev:stop\` — stop the dev server
132
+ - \`pnpm dev:restart\` — stop then start
133
+
134
+ The app is exposed on the VITE_PORT environment variable (default: 5173).
135
+ The database and Electric sync service are remote (cloud-hosted) — there is no local Postgres or Docker.
136
+
137
+ ### Migrations (CRITICAL)
138
+ After modifying src/db/schema.ts, ALWAYS run migrations:
139
+ \`\`\`bash
140
+ pnpm drizzle-kit generate # generate SQL from schema changes
141
+ pnpm drizzle-kit migrate # apply migration to the database
142
+ \`\`\`
143
+
144
+ ### Sprites Environment Gotchas
145
+ - npm global binaries are NOT in PATH by default. If you need to run a globally installed tool, source the profile first: \`source /etc/profile.d/npm-global.sh\`
146
+ - Node.js is managed via nvm at \`/.sprite/languages/node/nvm/\`
147
+ - The sandbox is a cloud micro-VM — there is no Docker, no docker-compose, no local Postgres
148
+ - The database connection string is in DATABASE_URL (remote Neon Postgres)
149
+
150
+ ### Workflow
151
+ After finishing ALL code generation: run migrations, then \`pnpm dev:start\` so the user can preview the app.`;
152
+ }
153
+ return `## Dev Server & Migrations
154
+ ### Dev Server
155
+ - \`pnpm dev:start\` — start Vite + Postgres + Electric in the background
156
+ - \`pnpm dev:stop\` — stop all background services
157
+ - \`pnpm dev:restart\` — stop then start
158
+
159
+ The app is exposed on the VITE_PORT environment variable (default: 5173).
160
+
161
+ ### Migrations (CRITICAL)
162
+ After modifying src/db/schema.ts, ALWAYS run migrations:
163
+ \`\`\`bash
164
+ pnpm dev:start # start Postgres (needed for migrate)
165
+ pnpm drizzle-kit generate # generate SQL from schema changes
166
+ pnpm drizzle-kit migrate # apply migration to the database
167
+ \`\`\`
168
+
169
+ ### Workflow
170
+ After finishing ALL code generation: run migrations, then \`pnpm dev:start\` so the user can preview the app.`;
171
+ }
172
+ const SSR_RULES = `## SSR Configuration (CRITICAL)
173
+ NEVER add ssr: false to __root.tsx — it renders the HTML shell and must always SSR.
174
+ Instead, add ssr: false to each LEAF route that uses useLiveQuery or collections.
175
+ This is needed because useLiveQuery uses useSyncExternalStore without getServerSnapshot.`;
176
+ // ---------------------------------------------------------------------------
177
+ // Claude Code–only sections
178
+ // ---------------------------------------------------------------------------
179
+ const PLAYBOOK_INSTRUCTIONS = `## Playbooks (Domain Knowledge — MUST READ)
180
+ Playbook SKILL.md files contain critical API usage patterns. Read them BEFORE writing code for each phase.
181
+
182
+ ### Available Skills
183
+ Read with the Read tool at these exact paths:
184
+
185
+ **Electric SQL** (\`node_modules/@electric-sql/playbook/skills/\`):
186
+ - \`electric/SKILL.md\` — core Electric concepts and shape API
187
+ - \`electric-tanstack-integration/SKILL.md\` — how Electric + TanStack DB work together (READ FIRST)
188
+ - \`electric-quickstart/SKILL.md\` — quickstart patterns
189
+ - \`electric-security-check/SKILL.md\` — security best practices
190
+ - \`tanstack-start-quickstart/SKILL.md\` — TanStack Start framework patterns
191
+ - \`deploying-electric/SKILL.md\` — deployment configuration
192
+ - \`electric-go-live/SKILL.md\` — production checklist
193
+
194
+ **TanStack DB** (\`node_modules/@tanstack/db-playbook/skills/\`):
195
+ - \`tanstack-db/SKILL.md\` — collections, useLiveQuery, mutations (CRITICAL — read before writing any UI)
196
+
197
+ **Durable Streams** (\`node_modules/@durable-streams/playbook/skills/\`):
198
+ - \`durable-streams/SKILL.md\` — event streaming patterns
199
+ - \`durable-state/SKILL.md\` — state management
200
+ - \`durable-streams-dev-setup/SKILL.md\` — development setup
201
+
202
+ ### Reading Order
203
+ 1. \`electric-tanstack-integration/SKILL.md\` — integration rules and guardrails
204
+ 2. \`tanstack-db/SKILL.md\` — collections, queries, mutations API
205
+ 3. \`electric/SKILL.md\` — shape API for proxy routes
206
+ 4. Other skills as needed for your current phase
207
+
208
+ ### Important
209
+ - ONLY read playbooks relevant to your current phase
210
+ - Do NOT use include_references — the SKILL.md content is sufficient`;
211
+ const INFRASTRUCTURE = `## Infrastructure (Pre-configured — DO NOT MODIFY)
212
+ The database (Postgres) and Electric sync service are already provisioned and configured via environment variables:
213
+ - \`DATABASE_URL\` — Postgres connection string
214
+ - \`ELECTRIC_URL\` — Electric sync service URL
215
+ - \`ELECTRIC_SOURCE_ID\` / \`ELECTRIC_SECRET\` — Electric Cloud auth (if using cloud mode)
216
+
217
+ These are read by:
218
+ - \`src/db/index.ts\` — Drizzle client (DO NOT MODIFY)
219
+ - \`drizzle.config.ts\` — Drizzle Kit migrations (DO NOT MODIFY)
220
+ - \`src/lib/electric-proxy.ts\` — Electric shape proxy for API routes (DO NOT MODIFY)
221
+
222
+ You do NOT need to set up database connections or configure Electric. Just define your schema, run migrations, and write your app.`;
223
+ // ---------------------------------------------------------------------------
224
+ // Electric Agent–only sections
225
+ // ---------------------------------------------------------------------------
226
+ const PLAYBOOK_INSTRUCTIONS_AGENT = `## Playbooks (Domain Knowledge)
227
+ Playbook skill files are available in node_modules. Read them before implementing each phase:
228
+
229
+ ### How to Read Playbooks
230
+ Use the Read tool to read playbook SKILL.md files:
231
+ - \`node_modules/@electric-sql/playbook/skills/<name>/SKILL.md\`
232
+ - \`node_modules/@tanstack/db-playbook/skills/<name>/SKILL.md\`
233
+ - \`node_modules/@durable-streams/playbook/skills/<name>/SKILL.md\`
234
+
235
+ ### Required Reading Order
236
+ 1. Read the electric-app-guardrails playbook FIRST (critical integration rules)
237
+ 2. Read "schemas" before writing Drizzle schemas
238
+ 3. Read "collections" before creating collection files
239
+ 4. Read "mutations" before creating mutation routes
240
+ 5. Read "live-queries" before creating UI with useLiveQuery
241
+
242
+ ### Important
243
+ - ONLY read playbooks relevant to your current phase
244
+ - Do NOT use include_references — the SKILL.md content is sufficient`;
245
+ const BUILD_INSTRUCTIONS = `## Build & Test
246
+ Run these commands to verify your work:
247
+ - \`pnpm run build\` — TypeScript compilation
248
+ - \`pnpm run check\` — Biome lint + format check
249
+ - \`pnpm test\` — Run tests (if tests/ directory exists)
250
+
251
+ Build only twice during initial generation: once after finishing all code, once after tests.
252
+ During iterations, build after completing changes.`;
253
+ const ARCHITECTURE_REFERENCE = `## Architecture Reference
254
+
255
+ ### Writing ARCHITECTURE.md (Initial Generation)
256
+ After ALL tasks are complete and the build passes, write ARCHITECTURE.md in the project root as your FINAL action. This is a concise navigation index — not documentation. Keep it under 1500 tokens.
257
+
258
+ Format:
259
+ \`\`\`
260
+ # [App Name] — Architecture Reference
261
+ _Last updated: [ISO date]_
262
+
263
+ ## App Description
264
+ [1-2 sentences]
265
+
266
+ ## Data Model
267
+ ### [EntityName] (\`table_name\`)
268
+ - **Columns**: id (uuid PK), title (text), created_at (timestamptz)
269
+ - **Relations**: [none | field → table.id cascade]
270
+ - **Collection**: src/db/collections/[entity].ts
271
+
272
+ ## API Routes
273
+ | Method | Path | File | Purpose |
274
+
275
+ ## UI Routes & Components
276
+ | Route | File | Description |
277
+
278
+ ### Key Components
279
+ - src/components/X.tsx — [one line: what it renders]
280
+
281
+ ## Styling
282
+ - CSS files: [file: purpose]
283
+ \`\`\`
284
+
285
+ ### Using ARCHITECTURE.md (Iteration Mode)
286
+ On iterations, read ARCHITECTURE.md to understand the app structure. Use it to locate files — do NOT scan the filesystem.`;
287
+ const GIT_INSTRUCTIONS = `## Git & GitHub CLI
288
+ You have git and gh CLI available via Bash. Use them when needed:
289
+ - \`git status\` / \`git diff --stat\` — check current state
290
+ - \`git add -A && git commit -m "type(scope): description"\` — commit changes
291
+ - \`git push -u origin main\` — push to remote
292
+ - \`gh repo create "org/name" --private --source . --remote origin --push\` — create repo
293
+ - \`gh pr create --title "..." --body "..."\` — create PR
294
+ Commit types: feat, fix, refactor, style, chore, docs, test`;
295
+ const ERROR_HANDLING = `## Error Handling
296
+ Before fixing any error, check _agent/errors.md for previous attempts at the same fix.
297
+ If you see the same error has failed before, try a different approach.
298
+ After fixing an error, log the outcome.`;
299
+ //# sourceMappingURL=claude-md-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-md-generator.js","sourceRoot":"","sources":["../../src/bridge/claude-md-generator.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,9 @@
1
+ export { ClaudeCodeDockerBridge, type ClaudeCodeDockerConfig } from "./claude-code-docker.js";
2
+ export { ClaudeCodeSpritesBridge, type ClaudeCodeSpritesConfig } from "./claude-code-sprites.js";
1
3
  export { DaytonaSessionBridge } from "./daytona.js";
2
4
  export { DockerStdioBridge } from "./docker-stdio.js";
3
5
  export { HostedStreamBridge } from "./hosted.js";
4
6
  export { SpritesStdioBridge } from "./sprites.js";
7
+ export { createStreamJsonParser } from "./stream-json-parser.js";
5
8
  export type { AgentEvent, ServerCommand, ServerGateResponse, SessionBridge, StreamMessage, } from "./types.js";
6
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,YAAY,EACX,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAC7F,OAAO,EAAE,uBAAuB,EAAE,KAAK,uBAAuB,EAAE,MAAM,0BAA0B,CAAA;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA;AAChE,YAAY,EACX,UAAU,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,aAAa,GACb,MAAM,YAAY,CAAA"}
@@ -1,5 +1,8 @@
1
+ export { ClaudeCodeDockerBridge } from "./claude-code-docker.js";
2
+ export { ClaudeCodeSpritesBridge } from "./claude-code-sprites.js";
1
3
  export { DaytonaSessionBridge } from "./daytona.js";
2
4
  export { DockerStdioBridge } from "./docker-stdio.js";
3
5
  export { HostedStreamBridge } from "./hosted.js";
4
6
  export { SpritesStdioBridge } from "./sprites.js";
7
+ export { createStreamJsonParser } from "./stream-json-parser.js";
5
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bridge/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAA+B,MAAM,yBAAyB,CAAA;AAC7F,OAAO,EAAE,uBAAuB,EAAgC,MAAM,0BAA0B,CAAA;AAChG,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAA"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Translates Claude Code `--output-format stream-json` NDJSON messages
3
+ * into EngineEvent arrays compatible with the existing bridge/UI pipeline.
4
+ *
5
+ * Claude Code emits lines like:
6
+ * {"type":"system","subtype":"init","session_id":"...","tools":[...]}
7
+ * {"type":"assistant","message":{"content":[{"type":"text","text":"..."}]}}
8
+ * {"type":"user","message":{"content":[{"type":"tool_result","tool_use_id":"...","content":"..."}]}}
9
+ * {"type":"result","subtype":"success","cost_usd":0.12,"num_turns":5}
10
+ *
11
+ * This parser converts each line into zero or more EngineEvent objects.
12
+ */
13
+ import type { EngineEvent } from "@electric-agent/protocol";
14
+ export interface StreamJsonParserState {
15
+ /** Map tool_use_id → tool_name for correlating post_tool_use events */
16
+ toolNames: Map<string, string>;
17
+ /** Accumulated cost from result messages */
18
+ totalCost: number;
19
+ /** Claude Code session ID from init */
20
+ sessionId: string | null;
21
+ }
22
+ /**
23
+ * Create a new stateful parser. The returned `parse` function converts
24
+ * a single raw JSON line from Claude Code into zero or more EngineEvents.
25
+ */
26
+ export declare function createStreamJsonParser(): {
27
+ state: StreamJsonParserState;
28
+ parse(line: string): EngineEvent[];
29
+ };
30
+ //# sourceMappingURL=stream-json-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-json-parser.d.ts","sourceRoot":"","sources":["../../src/bridge/stream-json-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AA+D3D,MAAM,WAAW,qBAAqB;IACrC,uEAAuE;IACvE,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CACxB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB;;gBASxB,MAAM,GAAG,WAAW,EAAE;EAInC"}