@electric-agent/agent 1.0.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.
- package/dist/agents/clarifier.d.ts +16 -0
- package/dist/agents/clarifier.d.ts.map +1 -0
- package/dist/agents/clarifier.js +158 -0
- package/dist/agents/clarifier.js.map +1 -0
- package/dist/agents/coder.d.ts +14 -0
- package/dist/agents/coder.d.ts.map +1 -0
- package/dist/agents/coder.js +126 -0
- package/dist/agents/coder.js.map +1 -0
- package/dist/agents/planner.d.ts +6 -0
- package/dist/agents/planner.d.ts.map +1 -0
- package/dist/agents/planner.js +69 -0
- package/dist/agents/planner.js.map +1 -0
- package/dist/agents/prompts.d.ts +9 -0
- package/dist/agents/prompts.d.ts.map +1 -0
- package/dist/agents/prompts.js +231 -0
- package/dist/agents/prompts.js.map +1 -0
- package/dist/cli/headless.d.ts +9 -0
- package/dist/cli/headless.d.ts.map +1 -0
- package/dist/cli/headless.js +506 -0
- package/dist/cli/headless.js.map +1 -0
- package/dist/cli/serve.d.ts +6 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +113 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/engine/message-parser.d.ts +8 -0
- package/dist/engine/message-parser.d.ts.map +1 -0
- package/dist/engine/message-parser.js +106 -0
- package/dist/engine/message-parser.js.map +1 -0
- package/dist/engine/orchestrator.d.ts +50 -0
- package/dist/engine/orchestrator.d.ts.map +1 -0
- package/dist/engine/orchestrator.js +492 -0
- package/dist/engine/orchestrator.js.map +1 -0
- package/dist/engine/stdio-adapter.d.ts +24 -0
- package/dist/engine/stdio-adapter.d.ts.map +1 -0
- package/dist/engine/stdio-adapter.js +139 -0
- package/dist/engine/stdio-adapter.js.map +1 -0
- package/dist/engine/stream-adapter.d.ts +45 -0
- package/dist/engine/stream-adapter.d.ts.map +1 -0
- package/dist/engine/stream-adapter.js +154 -0
- package/dist/engine/stream-adapter.js.map +1 -0
- package/dist/find-env.d.ts +3 -0
- package/dist/find-env.d.ts.map +1 -0
- package/dist/find-env.js +16 -0
- package/dist/find-env.js.map +1 -0
- package/dist/git/index.d.ts +114 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +434 -0
- package/dist/git/index.js.map +1 -0
- package/dist/hooks/block-bash.d.ts +7 -0
- package/dist/hooks/block-bash.d.ts.map +1 -0
- package/dist/hooks/block-bash.js +15 -0
- package/dist/hooks/block-bash.js.map +1 -0
- package/dist/hooks/dependency-guard.d.ts +7 -0
- package/dist/hooks/dependency-guard.d.ts.map +1 -0
- package/dist/hooks/dependency-guard.js +43 -0
- package/dist/hooks/dependency-guard.js.map +1 -0
- package/dist/hooks/guardrail-inject.d.ts +17 -0
- package/dist/hooks/guardrail-inject.d.ts.map +1 -0
- package/dist/hooks/guardrail-inject.js +69 -0
- package/dist/hooks/guardrail-inject.js.map +1 -0
- package/dist/hooks/import-validation.d.ts +7 -0
- package/dist/hooks/import-validation.d.ts.map +1 -0
- package/dist/hooks/import-validation.js +192 -0
- package/dist/hooks/import-validation.js.map +1 -0
- package/dist/hooks/index.d.ts +15 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +42 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/migration-validation.d.ts +9 -0
- package/dist/hooks/migration-validation.d.ts.map +1 -0
- package/dist/hooks/migration-validation.js +62 -0
- package/dist/hooks/migration-validation.js.map +1 -0
- package/dist/hooks/schema-consistency.d.ts +12 -0
- package/dist/hooks/schema-consistency.d.ts.map +1 -0
- package/dist/hooks/schema-consistency.js +72 -0
- package/dist/hooks/schema-consistency.js.map +1 -0
- package/dist/hooks/write-protection.d.ts +7 -0
- package/dist/hooks/write-protection.d.ts.map +1 -0
- package/dist/hooks/write-protection.js +33 -0
- package/dist/hooks/write-protection.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/progress/reporter.d.ts +15 -0
- package/dist/progress/reporter.d.ts.map +1 -0
- package/dist/progress/reporter.js +133 -0
- package/dist/progress/reporter.js.map +1 -0
- package/dist/scaffold/index.d.ts +23 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/index.js +315 -0
- package/dist/scaffold/index.js.map +1 -0
- package/dist/tools/build.d.ts +3 -0
- package/dist/tools/build.d.ts.map +1 -0
- package/dist/tools/build.js +84 -0
- package/dist/tools/build.js.map +1 -0
- package/dist/tools/playbook.d.ts +14 -0
- package/dist/tools/playbook.d.ts.map +1 -0
- package/dist/tools/playbook.js +239 -0
- package/dist/tools/playbook.js.map +1 -0
- package/dist/tools/server.d.ts +3 -0
- package/dist/tools/server.d.ts.map +1 -0
- package/dist/tools/server.js +13 -0
- package/dist/tools/server.js.map +1 -0
- package/dist/working-memory/errors.d.ts +14 -0
- package/dist/working-memory/errors.d.ts.map +1 -0
- package/dist/working-memory/errors.js +89 -0
- package/dist/working-memory/errors.js.map +1 -0
- package/dist/working-memory/session.d.ts +12 -0
- package/dist/working-memory/session.d.ts.map +1 -0
- package/dist/working-memory/session.js +71 -0
- package/dist/working-memory/session.js.map +1 -0
- package/package.json +50 -0
- package/playbooks/electric-app-guardrails/SKILL.md +255 -0
- package/template/.env.example +2 -0
- package/template/Caddyfile +11 -0
- package/template/docker-compose.yml +47 -0
- package/template/drizzle.config.ts +12 -0
- package/template/postgres.conf +4 -0
- package/template/src/components/ClientOnly.tsx +27 -0
- package/template/src/db/index.ts +7 -0
- package/template/src/db/schema.ts +14 -0
- package/template/src/db/utils.ts +31 -0
- package/template/src/db/zod-schemas.ts +14 -0
- package/template/src/lib/electric-proxy.ts +59 -0
- package/template/tests/helpers/schema-test-utils.ts +106 -0
- package/template/vitest.config.ts +7 -0
|
@@ -0,0 +1,506 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { ts } from "@electric-agent/protocol";
|
|
6
|
+
import { runIterate, runNew } from "../engine/orchestrator.js";
|
|
7
|
+
import { createStdioAdapter } from "../engine/stdio-adapter.js";
|
|
8
|
+
import { createStreamAdapter } from "../engine/stream-adapter.js";
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const { version: agentVersion } = require("../../package.json");
|
|
11
|
+
/**
|
|
12
|
+
* Handler for `electric-agent headless`.
|
|
13
|
+
*
|
|
14
|
+
* Communicates via either:
|
|
15
|
+
* 1. Hosted Durable Stream (if DS_URL + DS_SERVICE_ID + DS_SECRET + SESSION_ID are set)
|
|
16
|
+
* 2. stdin/stdout NDJSON (fallback — used in Daytona sandboxes without internet)
|
|
17
|
+
*/
|
|
18
|
+
export async function headlessCommand() {
|
|
19
|
+
const dsUrl = process.env.DS_URL;
|
|
20
|
+
const dsServiceId = process.env.DS_SERVICE_ID;
|
|
21
|
+
const dsSecret = process.env.DS_SECRET;
|
|
22
|
+
const sessionId = process.env.SESSION_ID;
|
|
23
|
+
const useStream = !!(dsUrl && dsServiceId && dsSecret && sessionId);
|
|
24
|
+
let adapter;
|
|
25
|
+
if (useStream) {
|
|
26
|
+
process.stderr.write("[headless] Using stream adapter (Durable Streams)\n");
|
|
27
|
+
const streamUrl = `${dsUrl}/v1/stream/${dsServiceId}/session/${sessionId}`;
|
|
28
|
+
const streamAdapter = createStreamAdapter(streamUrl, dsSecret);
|
|
29
|
+
await streamAdapter.startListening();
|
|
30
|
+
adapter = streamAdapter;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
process.stderr.write("[headless] Using stdio adapter (stdin/stdout NDJSON)\n");
|
|
34
|
+
adapter = createStdioAdapter();
|
|
35
|
+
}
|
|
36
|
+
const { readConfig, waitForCommand, callbacks, close } = adapter;
|
|
37
|
+
// Log agent version so it's visible in the UI stream
|
|
38
|
+
callbacks.onEvent({
|
|
39
|
+
type: "log",
|
|
40
|
+
level: "done",
|
|
41
|
+
message: `electric-agent@${agentVersion}`,
|
|
42
|
+
ts: ts(),
|
|
43
|
+
});
|
|
44
|
+
process.stderr.write(`[headless] electric-agent@${agentVersion}\n`);
|
|
45
|
+
let config;
|
|
46
|
+
try {
|
|
47
|
+
config = await readConfig();
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
const msg = err instanceof Error ? err.message : "Failed to read config";
|
|
51
|
+
process.stderr.write(`Error: ${msg}\n`);
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
close();
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
let projectDir;
|
|
57
|
+
try {
|
|
58
|
+
if (config.command === "new") {
|
|
59
|
+
if (!config.description) {
|
|
60
|
+
process.stderr.write('Error: "description" is required for command "new"\n');
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const baseDir = config.baseDir || process.cwd();
|
|
65
|
+
// Validate gh auth if GH_TOKEN is available
|
|
66
|
+
if (process.env.GH_TOKEN) {
|
|
67
|
+
const ghCmd = "gh auth status";
|
|
68
|
+
const ghToolUseId = `early-gh-${Date.now()}`;
|
|
69
|
+
callbacks.onEvent({
|
|
70
|
+
type: "pre_tool_use",
|
|
71
|
+
tool_name: "bash",
|
|
72
|
+
tool_use_id: ghToolUseId,
|
|
73
|
+
tool_input: { command: ghCmd },
|
|
74
|
+
ts: ts(),
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
const ghOut = execSync(`${ghCmd} 2>&1`, {
|
|
78
|
+
encoding: "utf-8",
|
|
79
|
+
timeout: 10_000,
|
|
80
|
+
env: { ...process.env },
|
|
81
|
+
}).trim();
|
|
82
|
+
callbacks.onEvent({
|
|
83
|
+
type: "post_tool_use",
|
|
84
|
+
tool_use_id: ghToolUseId,
|
|
85
|
+
tool_response: ghOut || "(ok)",
|
|
86
|
+
ts: ts(),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
const stderr = e?.stderr ||
|
|
91
|
+
e?.stdout ||
|
|
92
|
+
"auth check failed";
|
|
93
|
+
callbacks.onEvent({
|
|
94
|
+
type: "post_tool_use",
|
|
95
|
+
tool_use_id: ghToolUseId,
|
|
96
|
+
tool_response: `Error: ${stderr}`,
|
|
97
|
+
ts: ts(),
|
|
98
|
+
});
|
|
99
|
+
callbacks.onEvent({
|
|
100
|
+
type: "log",
|
|
101
|
+
level: "error",
|
|
102
|
+
message: "GitHub CLI auth check failed — repo creation may not work",
|
|
103
|
+
ts: ts(),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const result = await runNew({
|
|
108
|
+
description: config.description,
|
|
109
|
+
projectName: config.projectName,
|
|
110
|
+
baseDir,
|
|
111
|
+
callbacks,
|
|
112
|
+
gitRepoName: config.gitRepoName,
|
|
113
|
+
gitRepoVisibility: config.gitRepoVisibility,
|
|
114
|
+
});
|
|
115
|
+
projectDir = result.projectDir;
|
|
116
|
+
// In sandbox mode, run migrations and start the dev server
|
|
117
|
+
if (process.env.SANDBOX_MODE === "1" && projectDir) {
|
|
118
|
+
await startSandboxDevServer(projectDir, callbacks.onEvent);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else if (config.command === "iterate") {
|
|
122
|
+
if (!config.projectDir) {
|
|
123
|
+
process.stderr.write('Error: "projectDir" is required for command "iterate"\n');
|
|
124
|
+
process.exitCode = 1;
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (!config.request) {
|
|
128
|
+
process.stderr.write('Error: "request" is required for command "iterate"\n');
|
|
129
|
+
process.exitCode = 1;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
projectDir = config.projectDir;
|
|
133
|
+
await runIterate({
|
|
134
|
+
projectDir: config.projectDir,
|
|
135
|
+
userRequest: config.request,
|
|
136
|
+
callbacks,
|
|
137
|
+
resumeSessionId: config.resumeSessionId,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
else if (config.command === "git") {
|
|
141
|
+
if (!config.projectDir) {
|
|
142
|
+
process.stderr.write('Error: "projectDir" is required for command "git"\n');
|
|
143
|
+
process.exitCode = 1;
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (!config.gitOp) {
|
|
147
|
+
process.stderr.write('Error: "gitOp" is required for command "git"\n');
|
|
148
|
+
process.exitCode = 1;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
projectDir = config.projectDir;
|
|
152
|
+
const gitSuccess = executeGitOp(config, callbacks.onEvent);
|
|
153
|
+
callbacks.onEvent({
|
|
154
|
+
type: "session_end",
|
|
155
|
+
success: gitSuccess,
|
|
156
|
+
ts: ts(),
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
process.stderr.write(`Error: Unknown command "${config.command}"\n`);
|
|
161
|
+
process.exitCode = 1;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
167
|
+
process.stderr.write(`Fatal: ${msg}\n`);
|
|
168
|
+
process.exitCode = 1;
|
|
169
|
+
close();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
// Emit session_end for the initial command
|
|
173
|
+
callbacks.onEvent({ type: "session_end", success: true, ts: ts() });
|
|
174
|
+
// Keep listening for iterate commands (Vite HMR picks up changes live)
|
|
175
|
+
if (process.env.SANDBOX_MODE === "1") {
|
|
176
|
+
await listenForIterations(projectDir, waitForCommand, callbacks);
|
|
177
|
+
}
|
|
178
|
+
close();
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Listen for iterate commands and run them.
|
|
182
|
+
* The dev server stays running — Vite HMR handles live reloads.
|
|
183
|
+
*/
|
|
184
|
+
async function listenForIterations(projectDir, waitForCommand, callbacks) {
|
|
185
|
+
while (true) {
|
|
186
|
+
let cmd;
|
|
187
|
+
try {
|
|
188
|
+
cmd = await waitForCommand();
|
|
189
|
+
}
|
|
190
|
+
catch {
|
|
191
|
+
// Stream closed — exit gracefully
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
if (cmd.command === "git") {
|
|
195
|
+
const gitCmd = cmd;
|
|
196
|
+
if (!gitCmd.gitOp || !gitCmd.projectDir) {
|
|
197
|
+
callbacks.onEvent({
|
|
198
|
+
type: "log",
|
|
199
|
+
level: "error",
|
|
200
|
+
message: "git command requires projectDir and gitOp",
|
|
201
|
+
ts: ts(),
|
|
202
|
+
});
|
|
203
|
+
callbacks.onEvent({ type: "session_end", success: false, ts: ts() });
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
// Prefer the agent's known projectDir (from runNew result) over
|
|
207
|
+
// the server-sent one — the agent knows the actual directory.
|
|
208
|
+
const gitSuccess = executeGitOp({ ...gitCmd, projectDir: projectDir || gitCmd.projectDir }, callbacks.onEvent);
|
|
209
|
+
callbacks.onEvent({ type: "session_end", success: gitSuccess, ts: ts() });
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (cmd.command !== "iterate") {
|
|
213
|
+
callbacks.onEvent({
|
|
214
|
+
type: "log",
|
|
215
|
+
level: "error",
|
|
216
|
+
message: `Unexpected command "${cmd.command}" — only "iterate" and "git" are supported after initial run`,
|
|
217
|
+
ts: ts(),
|
|
218
|
+
});
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const iterateDir = cmd.projectDir || projectDir;
|
|
222
|
+
if (!iterateDir || !cmd.request) {
|
|
223
|
+
callbacks.onEvent({
|
|
224
|
+
type: "log",
|
|
225
|
+
level: "error",
|
|
226
|
+
message: "iterate requires projectDir and request",
|
|
227
|
+
ts: ts(),
|
|
228
|
+
});
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
try {
|
|
232
|
+
await runIterate({
|
|
233
|
+
projectDir: iterateDir,
|
|
234
|
+
userRequest: cmd.request,
|
|
235
|
+
callbacks,
|
|
236
|
+
resumeSessionId: cmd.resumeSessionId,
|
|
237
|
+
});
|
|
238
|
+
// Run migrations after code changes (schema may have changed)
|
|
239
|
+
if (iterateDir) {
|
|
240
|
+
runMigrations(iterateDir, callbacks.onEvent);
|
|
241
|
+
}
|
|
242
|
+
callbacks.onEvent({ type: "session_end", success: true, ts: ts() });
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
const msg = err instanceof Error ? err.message : "Unknown error";
|
|
246
|
+
callbacks.onEvent({
|
|
247
|
+
type: "log",
|
|
248
|
+
level: "error",
|
|
249
|
+
message: `Iteration failed: ${msg}`,
|
|
250
|
+
ts: ts(),
|
|
251
|
+
});
|
|
252
|
+
callbacks.onEvent({ type: "session_end", success: false, ts: ts() });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Execute a structured git operation directly via execSync.
|
|
258
|
+
* Returns true on success, false on failure.
|
|
259
|
+
*/
|
|
260
|
+
function executeGitOp(config, emit) {
|
|
261
|
+
const cwd = config.projectDir ?? "";
|
|
262
|
+
const op = config.gitOp ?? "commit";
|
|
263
|
+
const toolUseId = `git-${op}-${Date.now()}`;
|
|
264
|
+
function run(cmd) {
|
|
265
|
+
emit({
|
|
266
|
+
type: "pre_tool_use",
|
|
267
|
+
tool_name: "bash",
|
|
268
|
+
tool_use_id: toolUseId,
|
|
269
|
+
tool_input: { command: cmd },
|
|
270
|
+
ts: ts(),
|
|
271
|
+
});
|
|
272
|
+
try {
|
|
273
|
+
const output = execSync(cmd, {
|
|
274
|
+
cwd,
|
|
275
|
+
encoding: "utf-8",
|
|
276
|
+
timeout: 60_000,
|
|
277
|
+
env: { ...process.env },
|
|
278
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
279
|
+
}).trim();
|
|
280
|
+
emit({
|
|
281
|
+
type: "post_tool_use",
|
|
282
|
+
tool_use_id: toolUseId,
|
|
283
|
+
tool_response: output || "(ok)",
|
|
284
|
+
ts: ts(),
|
|
285
|
+
});
|
|
286
|
+
return output;
|
|
287
|
+
}
|
|
288
|
+
catch (e) {
|
|
289
|
+
const stderr = e?.stderr || "";
|
|
290
|
+
const stdout = e?.stdout || "";
|
|
291
|
+
const detail = stderr || stdout || (e instanceof Error ? e.message : "Command failed");
|
|
292
|
+
emit({
|
|
293
|
+
type: "post_tool_use",
|
|
294
|
+
tool_use_id: toolUseId,
|
|
295
|
+
tool_response: `Error: ${detail}`,
|
|
296
|
+
ts: ts(),
|
|
297
|
+
});
|
|
298
|
+
throw new Error(detail);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
// Verify git repository exists before attempting any operation
|
|
302
|
+
if (!fs.existsSync(path.join(cwd, ".git"))) {
|
|
303
|
+
emit({
|
|
304
|
+
type: "log",
|
|
305
|
+
level: "error",
|
|
306
|
+
message: `Git ${op} skipped — no .git directory found in ${cwd}`,
|
|
307
|
+
ts: ts(),
|
|
308
|
+
});
|
|
309
|
+
return false;
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
switch (op) {
|
|
313
|
+
case "commit": {
|
|
314
|
+
const message = config.gitMessage || "commit";
|
|
315
|
+
run("git add -A");
|
|
316
|
+
try {
|
|
317
|
+
execSync("git diff --cached --quiet", { cwd, stdio: "pipe" });
|
|
318
|
+
emit({
|
|
319
|
+
type: "log",
|
|
320
|
+
level: "done",
|
|
321
|
+
message: "No changes to commit",
|
|
322
|
+
ts: ts(),
|
|
323
|
+
});
|
|
324
|
+
return true;
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
// There are staged changes — proceed
|
|
328
|
+
}
|
|
329
|
+
const safeMsg = message.replace(/"/g, '\\"');
|
|
330
|
+
run(`git commit -m "${safeMsg}"`);
|
|
331
|
+
const hash = run("git rev-parse HEAD");
|
|
332
|
+
emit({
|
|
333
|
+
type: "git_checkpoint",
|
|
334
|
+
commitHash: hash,
|
|
335
|
+
message,
|
|
336
|
+
ts: ts(),
|
|
337
|
+
});
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
case "push": {
|
|
341
|
+
const branch = run("git rev-parse --abbrev-ref HEAD");
|
|
342
|
+
run(`git push -u origin ${branch}`);
|
|
343
|
+
emit({
|
|
344
|
+
type: "log",
|
|
345
|
+
level: "done",
|
|
346
|
+
message: `Pushed to origin/${branch}`,
|
|
347
|
+
ts: ts(),
|
|
348
|
+
});
|
|
349
|
+
return true;
|
|
350
|
+
}
|
|
351
|
+
case "create-repo": {
|
|
352
|
+
const name = config.gitRepoName;
|
|
353
|
+
if (!name) {
|
|
354
|
+
emit({
|
|
355
|
+
type: "log",
|
|
356
|
+
level: "error",
|
|
357
|
+
message: "gitRepoName is required for create-repo",
|
|
358
|
+
ts: ts(),
|
|
359
|
+
});
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
const vis = config.gitRepoVisibility || "private";
|
|
363
|
+
run(`gh repo create "${name}" --${vis} --source . --remote origin --push`);
|
|
364
|
+
emit({
|
|
365
|
+
type: "log",
|
|
366
|
+
level: "done",
|
|
367
|
+
message: `GitHub repo created: ${name} (${vis})`,
|
|
368
|
+
ts: ts(),
|
|
369
|
+
});
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
case "create-pr": {
|
|
373
|
+
const title = config.gitPrTitle || "Changes from electric-agent";
|
|
374
|
+
const body = config.gitPrBody ||
|
|
375
|
+
"Generated by electric-agent.\n\nReview the changes and merge when ready.";
|
|
376
|
+
const safeTitle = title.replace(/"/g, '\\"');
|
|
377
|
+
const safeBody = body.replace(/"/g, '\\"');
|
|
378
|
+
const output = run(`gh pr create --title "${safeTitle}" --body "${safeBody}"`);
|
|
379
|
+
emit({
|
|
380
|
+
type: "log",
|
|
381
|
+
level: "done",
|
|
382
|
+
message: `PR created: ${output}`,
|
|
383
|
+
ts: ts(),
|
|
384
|
+
});
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
default:
|
|
388
|
+
emit({
|
|
389
|
+
type: "log",
|
|
390
|
+
level: "error",
|
|
391
|
+
message: `Unknown git operation: ${op}`,
|
|
392
|
+
ts: ts(),
|
|
393
|
+
});
|
|
394
|
+
return false;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
catch (err) {
|
|
398
|
+
const msg = err instanceof Error ? err.message : "Git operation failed";
|
|
399
|
+
emit({ type: "log", level: "error", message: `Git ${op} failed: ${msg}`, ts: ts() });
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Extract a useful error message from an execSync failure.
|
|
405
|
+
* Node's execSync attaches stderr/stdout as Buffers on the thrown error,
|
|
406
|
+
* but err.message only contains "Command failed: <cmd>" with no detail.
|
|
407
|
+
*/
|
|
408
|
+
function extractExecError(err) {
|
|
409
|
+
if (!(err instanceof Error))
|
|
410
|
+
return "Migration failed";
|
|
411
|
+
const e = err;
|
|
412
|
+
const stderr = e.stderr?.toString().trim();
|
|
413
|
+
const stdout = e.stdout?.toString().trim();
|
|
414
|
+
// Prefer stderr (where drizzle-kit writes errors), fall back to stdout, then message
|
|
415
|
+
return stderr || stdout || e.message;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Run drizzle-kit migrations with retries (DB may not be ready yet).
|
|
419
|
+
*/
|
|
420
|
+
function runMigrations(projectDir, emit) {
|
|
421
|
+
// Verify package.json exists before running pnpm commands
|
|
422
|
+
if (!fs.existsSync(path.join(projectDir, "package.json"))) {
|
|
423
|
+
emit({
|
|
424
|
+
type: "log",
|
|
425
|
+
level: "error",
|
|
426
|
+
message: `Skipping migrations — no package.json found in ${projectDir}`,
|
|
427
|
+
ts: ts(),
|
|
428
|
+
});
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
emit({ type: "log", level: "build", message: "Running migrations...", ts: ts() });
|
|
432
|
+
const maxAttempts = 5;
|
|
433
|
+
const delayMs = 3_000;
|
|
434
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
435
|
+
try {
|
|
436
|
+
execSync("pnpm drizzle-kit migrate", {
|
|
437
|
+
cwd: projectDir,
|
|
438
|
+
stdio: "pipe",
|
|
439
|
+
timeout: 60_000,
|
|
440
|
+
env: { ...process.env },
|
|
441
|
+
});
|
|
442
|
+
emit({ type: "log", level: "done", message: "Migrations complete", ts: ts() });
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
catch (err) {
|
|
446
|
+
const detail = extractExecError(err);
|
|
447
|
+
const isConnectionError = detail.includes("ECONNREFUSED") ||
|
|
448
|
+
detail.includes("ENOTFOUND") ||
|
|
449
|
+
detail.includes("timeout");
|
|
450
|
+
if (isConnectionError && attempt < maxAttempts) {
|
|
451
|
+
emit({
|
|
452
|
+
type: "log",
|
|
453
|
+
level: "build",
|
|
454
|
+
message: `Database not ready, retrying in ${delayMs / 1000}s (attempt ${attempt}/${maxAttempts})...`,
|
|
455
|
+
ts: ts(),
|
|
456
|
+
});
|
|
457
|
+
execSync(`sleep ${delayMs / 1000}`);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
emit({
|
|
461
|
+
type: "log",
|
|
462
|
+
level: "error",
|
|
463
|
+
message: `Migration failed: ${detail}`,
|
|
464
|
+
ts: ts(),
|
|
465
|
+
});
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* After generation completes in sandbox mode:
|
|
473
|
+
* 1. Run drizzle-kit migrate
|
|
474
|
+
* 2. Start pnpm dev via the dev:start script
|
|
475
|
+
* 3. Emit app_ready event
|
|
476
|
+
*/
|
|
477
|
+
async function startSandboxDevServer(projectDir, emit) {
|
|
478
|
+
// Verify the project directory has the expected structure
|
|
479
|
+
if (!fs.existsSync(path.join(projectDir, "package.json"))) {
|
|
480
|
+
emit({
|
|
481
|
+
type: "log",
|
|
482
|
+
level: "error",
|
|
483
|
+
message: `Cannot start dev server — no package.json found in ${projectDir}`,
|
|
484
|
+
ts: ts(),
|
|
485
|
+
});
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
// Step 1: Run migrations
|
|
489
|
+
runMigrations(projectDir, emit);
|
|
490
|
+
// Step 2: Start dev server using the scaffold script (creates PID file)
|
|
491
|
+
emit({
|
|
492
|
+
type: "log",
|
|
493
|
+
level: "done",
|
|
494
|
+
message: "Starting dev server on port 5173...",
|
|
495
|
+
ts: ts(),
|
|
496
|
+
});
|
|
497
|
+
execSync("pnpm dev:start", {
|
|
498
|
+
cwd: projectDir,
|
|
499
|
+
stdio: "pipe",
|
|
500
|
+
timeout: 10_000,
|
|
501
|
+
env: { ...process.env },
|
|
502
|
+
});
|
|
503
|
+
// Step 3: Emit app_ready — the dev server is running in the background
|
|
504
|
+
emit({ type: "app_ready", port: 5173, ts: ts() });
|
|
505
|
+
}
|
|
506
|
+
//# sourceMappingURL=headless.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headless.js","sourceRoot":"","sources":["../../src/cli/headless.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"AASA,wBAAsB,YAAY,CAAC,IAAI,EAAE;IACxC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;CACd,GAAG,OAAO,CAAC,IAAI,CAAC,CA6GhB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { DaytonaSandboxProvider } from "@electric-agent/studio/sandbox/daytona";
|
|
2
|
+
import { getSnapshotStatus } from "@electric-agent/studio/sandbox/daytona-registry";
|
|
3
|
+
import { DockerSandboxProvider } from "@electric-agent/studio/sandbox/docker";
|
|
4
|
+
import { SpritesSandboxProvider } from "@electric-agent/studio/sandbox/sprites";
|
|
5
|
+
import { startWebServer } from "@electric-agent/studio/server";
|
|
6
|
+
import { getStreamConfig } from "@electric-agent/studio/streams";
|
|
7
|
+
import { inferProjectName } from "../agents/clarifier.js";
|
|
8
|
+
export async function serveCommand(opts) {
|
|
9
|
+
const port = opts.port ?? (process.env.PORT ? parseInt(process.env.PORT, 10) : 4400);
|
|
10
|
+
const dataDir = opts.dataDir ?? process.env.DATA_DIR ?? ".electric-agent";
|
|
11
|
+
// Require hosted stream credentials
|
|
12
|
+
const streamConfig = getStreamConfig();
|
|
13
|
+
if (!streamConfig) {
|
|
14
|
+
console.error("Error: DS_URL, DS_SERVICE_ID, and DS_SECRET environment variables are required.");
|
|
15
|
+
console.error("Set these to connect to the hosted Durable Streams service.");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
// Select sandbox provider:
|
|
19
|
+
// SANDBOX_RUNTIME=docker → always Docker
|
|
20
|
+
// SANDBOX_RUNTIME=daytona → always Daytona
|
|
21
|
+
// (unset) → Daytona if DAYTONA_API_KEY is set, otherwise Docker
|
|
22
|
+
const runtime = process.env.SANDBOX_RUNTIME?.toLowerCase();
|
|
23
|
+
let sandbox;
|
|
24
|
+
if (runtime === "docker") {
|
|
25
|
+
sandbox = new DockerSandboxProvider();
|
|
26
|
+
console.log("[serve] Sandbox runtime: Docker (SANDBOX_RUNTIME=docker)");
|
|
27
|
+
}
|
|
28
|
+
else if (runtime === "daytona" || (!runtime && process.env.DAYTONA_API_KEY)) {
|
|
29
|
+
if (!process.env.DAYTONA_API_KEY) {
|
|
30
|
+
console.error("Error: SANDBOX_RUNTIME=daytona requires DAYTONA_API_KEY to be set.");
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
sandbox = new DaytonaSandboxProvider({
|
|
34
|
+
apiKey: process.env.DAYTONA_API_KEY,
|
|
35
|
+
apiUrl: process.env.DAYTONA_API_URL,
|
|
36
|
+
target: process.env.DAYTONA_TARGET,
|
|
37
|
+
});
|
|
38
|
+
console.log(`[serve] Sandbox runtime: Daytona (target: ${process.env.DAYTONA_TARGET ?? "eu"})`);
|
|
39
|
+
// Check snapshot status (non-blocking)
|
|
40
|
+
const { Daytona } = await import("@daytonaio/sdk");
|
|
41
|
+
const daytona = new Daytona({
|
|
42
|
+
apiKey: process.env.DAYTONA_API_KEY,
|
|
43
|
+
apiUrl: process.env.DAYTONA_API_URL,
|
|
44
|
+
target: process.env.DAYTONA_TARGET ?? "eu",
|
|
45
|
+
});
|
|
46
|
+
const snapshotImage = process.env.SANDBOX_IMAGE || "electric-agent-sandbox";
|
|
47
|
+
const status = await getSnapshotStatus(daytona, snapshotImage);
|
|
48
|
+
if (status.exists) {
|
|
49
|
+
console.log(`[serve] Snapshot "${snapshotImage}": ${status.state}`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.log(`[serve] Snapshot "${snapshotImage}" not found — will be created on first sandbox creation`);
|
|
53
|
+
console.log(`[serve] To pre-push: npm run push:sandbox:daytona`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
else if (runtime === "sprites" || (!runtime && process.env.FLY_API_TOKEN)) {
|
|
57
|
+
if (!process.env.FLY_API_TOKEN) {
|
|
58
|
+
console.error("Error: SANDBOX_RUNTIME=sprites requires FLY_API_TOKEN to be set.");
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
sandbox = new SpritesSandboxProvider({
|
|
62
|
+
token: process.env.FLY_API_TOKEN,
|
|
63
|
+
});
|
|
64
|
+
console.log(`[serve] Sandbox runtime: Sprites (Fly.io)`);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
sandbox = new DockerSandboxProvider();
|
|
68
|
+
console.log("[serve] Sandbox runtime: Docker (default)");
|
|
69
|
+
}
|
|
70
|
+
// Determine bridge mode:
|
|
71
|
+
// BRIDGE_MODE=stdio → always stdin/stdout (required for Daytona without internet)
|
|
72
|
+
// BRIDGE_MODE=stream → always hosted Durable Streams (default for Docker & Sprites)
|
|
73
|
+
// (unset) → "stdio" for Daytona, "stream" for Docker/Sprites
|
|
74
|
+
const bridgeModeEnv = process.env.BRIDGE_MODE?.toLowerCase();
|
|
75
|
+
let bridgeMode;
|
|
76
|
+
if (bridgeModeEnv === "stdio") {
|
|
77
|
+
bridgeMode = "stdio";
|
|
78
|
+
}
|
|
79
|
+
else if (bridgeModeEnv === "stream") {
|
|
80
|
+
bridgeMode = "stream";
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
// Default: Daytona uses stdio (required — no internet), others use stream
|
|
84
|
+
bridgeMode = sandbox.runtime === "daytona" ? "stdio" : "stream";
|
|
85
|
+
}
|
|
86
|
+
console.log(`[serve] Bridge mode: ${bridgeMode}`);
|
|
87
|
+
await startWebServer({ port, dataDir, sandbox, streamConfig, bridgeMode, inferProjectName });
|
|
88
|
+
console.log(`\nWeb UI ready at http://127.0.0.1:${port}`);
|
|
89
|
+
if (opts.open) {
|
|
90
|
+
const { exec } = await import("node:child_process");
|
|
91
|
+
const url = `http://127.0.0.1:${port}`;
|
|
92
|
+
const platform = process.platform;
|
|
93
|
+
const cmd = platform === "darwin"
|
|
94
|
+
? `open ${url}`
|
|
95
|
+
: platform === "win32"
|
|
96
|
+
? `start ${url}`
|
|
97
|
+
: `xdg-open ${url}`;
|
|
98
|
+
exec(cmd);
|
|
99
|
+
}
|
|
100
|
+
// Graceful shutdown — force exit on second Ctrl+C
|
|
101
|
+
let shuttingDown = false;
|
|
102
|
+
const shutdown = async () => {
|
|
103
|
+
if (shuttingDown) {
|
|
104
|
+
process.exit(1);
|
|
105
|
+
}
|
|
106
|
+
shuttingDown = true;
|
|
107
|
+
console.log("\nShutting down...");
|
|
108
|
+
process.exit(0);
|
|
109
|
+
};
|
|
110
|
+
process.on("SIGINT", shutdown);
|
|
111
|
+
process.on("SIGTERM", shutdown);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"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"}
|