sparkecoder 0.1.6 → 0.1.8
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/agent/index.js +2 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +130 -35
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +125 -34
- package/dist/index.js.map +1 -1
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +125 -34
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/tools/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.d.ts
CHANGED
|
@@ -96,6 +96,7 @@ interface TerminalMeta {
|
|
|
96
96
|
createdAt: string;
|
|
97
97
|
sessionId: string;
|
|
98
98
|
background: boolean;
|
|
99
|
+
name?: string;
|
|
99
100
|
}
|
|
100
101
|
interface TerminalResult {
|
|
101
102
|
id: string;
|
|
@@ -134,6 +135,7 @@ declare function runSync(command: string, workingDirectory: string, options: {
|
|
|
134
135
|
declare function runBackground(command: string, workingDirectory: string, options: {
|
|
135
136
|
sessionId: string;
|
|
136
137
|
terminalId?: string;
|
|
138
|
+
name?: string;
|
|
137
139
|
}): Promise<TerminalResult>;
|
|
138
140
|
/**
|
|
139
141
|
* Get logs from a terminal
|
package/dist/index.js
CHANGED
|
@@ -1131,7 +1131,8 @@ async function runBackground(command, workingDirectory, options) {
|
|
|
1131
1131
|
cwd: workingDirectory,
|
|
1132
1132
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1133
1133
|
sessionId: options.sessionId,
|
|
1134
|
-
background: true
|
|
1134
|
+
background: true,
|
|
1135
|
+
name: options.name
|
|
1135
1136
|
}, workingDirectory);
|
|
1136
1137
|
const logFile = join2(logDir, "output.log");
|
|
1137
1138
|
const wrappedCommand = `(${command}) 2>&1 | tee -a ${shellEscape(logFile)}`;
|
|
@@ -3969,7 +3970,10 @@ terminals2.post(
|
|
|
3969
3970
|
return c.json({ error: "tmux is not installed. Background terminals require tmux." }, 400);
|
|
3970
3971
|
}
|
|
3971
3972
|
const workingDirectory = body.cwd || session.workingDirectory;
|
|
3972
|
-
const result = await runBackground(body.command, workingDirectory, {
|
|
3973
|
+
const result = await runBackground(body.command, workingDirectory, {
|
|
3974
|
+
sessionId,
|
|
3975
|
+
name: body.name
|
|
3976
|
+
});
|
|
3973
3977
|
return c.json({
|
|
3974
3978
|
id: result.id,
|
|
3975
3979
|
name: body.name || null,
|
|
@@ -3993,7 +3997,7 @@ terminals2.get("/:sessionId/terminals", async (c) => {
|
|
|
3993
3997
|
const running = await isRunning(meta.id);
|
|
3994
3998
|
return {
|
|
3995
3999
|
id: meta.id,
|
|
3996
|
-
name: null,
|
|
4000
|
+
name: meta.name || null,
|
|
3997
4001
|
command: meta.command,
|
|
3998
4002
|
cwd: meta.cwd,
|
|
3999
4003
|
status: running ? "running" : "stopped",
|
|
@@ -4077,10 +4081,17 @@ terminals2.post(
|
|
|
4077
4081
|
"/:sessionId/terminals/:terminalId/write",
|
|
4078
4082
|
zValidator4("json", writeSchema),
|
|
4079
4083
|
async (c) => {
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
+
const terminalId = c.req.param("terminalId");
|
|
4085
|
+
const body = c.req.valid("json");
|
|
4086
|
+
const isRunning2 = await isRunning(terminalId);
|
|
4087
|
+
if (!isRunning2) {
|
|
4088
|
+
return c.json({ error: "Terminal is not running" }, 400);
|
|
4089
|
+
}
|
|
4090
|
+
const success = await sendInput(terminalId, body.input, { pressEnter: false });
|
|
4091
|
+
if (!success) {
|
|
4092
|
+
return c.json({ error: "Failed to write to terminal" }, 500);
|
|
4093
|
+
}
|
|
4094
|
+
return c.json({ success: true, written: body.input.length });
|
|
4084
4095
|
}
|
|
4085
4096
|
);
|
|
4086
4097
|
terminals2.post("/:sessionId/terminals/kill-all", async (c) => {
|
|
@@ -4089,12 +4100,12 @@ terminals2.post("/:sessionId/terminals/kill-all", async (c) => {
|
|
|
4089
4100
|
if (!session) {
|
|
4090
4101
|
return c.json({ error: "Session not found" }, 404);
|
|
4091
4102
|
}
|
|
4092
|
-
const
|
|
4103
|
+
const sessionTerminals = await listSessionTerminals(sessionId, session.workingDirectory);
|
|
4093
4104
|
let killed = 0;
|
|
4094
|
-
for (const
|
|
4095
|
-
const
|
|
4096
|
-
if (
|
|
4097
|
-
const success = await killTerminal(id);
|
|
4105
|
+
for (const terminal of sessionTerminals) {
|
|
4106
|
+
const isRunning2 = await isRunning(terminal.id);
|
|
4107
|
+
if (isRunning2) {
|
|
4108
|
+
const success = await killTerminal(terminal.id);
|
|
4098
4109
|
if (success) killed++;
|
|
4099
4110
|
}
|
|
4100
4111
|
}
|
|
@@ -4392,6 +4403,33 @@ async function findWebPort(preferredPort) {
|
|
|
4392
4403
|
}
|
|
4393
4404
|
return { port: preferredPort, alreadyRunning: false };
|
|
4394
4405
|
}
|
|
4406
|
+
function hasProductionBuild(webDir) {
|
|
4407
|
+
const buildIdPath = join3(webDir, ".next", "BUILD_ID");
|
|
4408
|
+
return existsSync7(buildIdPath);
|
|
4409
|
+
}
|
|
4410
|
+
function runCommand(command, args, cwd, env) {
|
|
4411
|
+
return new Promise((resolve7) => {
|
|
4412
|
+
const child = spawn(command, args, {
|
|
4413
|
+
cwd,
|
|
4414
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
4415
|
+
env,
|
|
4416
|
+
shell: true
|
|
4417
|
+
});
|
|
4418
|
+
let output = "";
|
|
4419
|
+
child.stdout?.on("data", (data) => {
|
|
4420
|
+
output += data.toString();
|
|
4421
|
+
});
|
|
4422
|
+
child.stderr?.on("data", (data) => {
|
|
4423
|
+
output += data.toString();
|
|
4424
|
+
});
|
|
4425
|
+
child.on("close", (code) => {
|
|
4426
|
+
resolve7({ success: code === 0, output });
|
|
4427
|
+
});
|
|
4428
|
+
child.on("error", (err) => {
|
|
4429
|
+
resolve7({ success: false, output: err.message });
|
|
4430
|
+
});
|
|
4431
|
+
});
|
|
4432
|
+
}
|
|
4395
4433
|
async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false) {
|
|
4396
4434
|
const webDir = getWebDirectory();
|
|
4397
4435
|
if (!webDir) {
|
|
@@ -4403,39 +4441,90 @@ async function startWebUI(apiPort, webPort = DEFAULT_WEB_PORT, quiet = false) {
|
|
|
4403
4441
|
if (!quiet) console.log(` \u2713 Web UI already running at http://localhost:${actualPort}`);
|
|
4404
4442
|
return { process: null, port: actualPort };
|
|
4405
4443
|
}
|
|
4406
|
-
const
|
|
4407
|
-
const
|
|
4408
|
-
const
|
|
4444
|
+
const usePnpm = existsSync7(join3(webDir, "pnpm-lock.yaml"));
|
|
4445
|
+
const useNpm = !usePnpm && existsSync7(join3(webDir, "package-lock.json"));
|
|
4446
|
+
const pkgManager = usePnpm ? "pnpm" : useNpm ? "npm" : "npx";
|
|
4447
|
+
const { NODE_OPTIONS, TSX_TSCONFIG_PATH, ...cleanEnv } = process.env;
|
|
4448
|
+
const webEnv = {
|
|
4449
|
+
...cleanEnv,
|
|
4450
|
+
NEXT_PUBLIC_API_URL: `http://127.0.0.1:${apiPort}`
|
|
4451
|
+
};
|
|
4452
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
4453
|
+
let command;
|
|
4454
|
+
let args;
|
|
4455
|
+
if (isProduction) {
|
|
4456
|
+
if (!hasProductionBuild(webDir)) {
|
|
4457
|
+
if (!quiet) console.log(" \u{1F4E6} Building Web UI for production...");
|
|
4458
|
+
const buildArgs = pkgManager === "npx" ? ["next", "build"] : ["run", "build"];
|
|
4459
|
+
const buildResult = await runCommand(pkgManager, buildArgs, webDir, webEnv);
|
|
4460
|
+
if (!buildResult.success) {
|
|
4461
|
+
if (!quiet) console.error(" \u274C Web UI build failed");
|
|
4462
|
+
return { process: null, port: actualPort };
|
|
4463
|
+
}
|
|
4464
|
+
if (!quiet) console.log(" \u2713 Web UI build complete");
|
|
4465
|
+
}
|
|
4466
|
+
command = pkgManager;
|
|
4467
|
+
args = pkgManager === "npx" ? ["next", "start", "-p", String(actualPort)] : ["run", "start", "-p", String(actualPort)];
|
|
4468
|
+
} else {
|
|
4469
|
+
command = pkgManager;
|
|
4470
|
+
args = pkgManager === "npx" ? ["next", "dev", "-p", String(actualPort)] : ["run", "dev", "-p", String(actualPort)];
|
|
4471
|
+
}
|
|
4409
4472
|
const child = spawn(command, args, {
|
|
4410
4473
|
cwd: webDir,
|
|
4411
4474
|
stdio: ["ignore", "pipe", "pipe"],
|
|
4412
|
-
env:
|
|
4413
|
-
|
|
4414
|
-
|
|
4415
|
-
},
|
|
4416
|
-
detached: false
|
|
4475
|
+
env: webEnv,
|
|
4476
|
+
detached: false,
|
|
4477
|
+
shell: true
|
|
4417
4478
|
});
|
|
4479
|
+
const startupTimeout = 3e4;
|
|
4418
4480
|
let started = false;
|
|
4419
|
-
|
|
4420
|
-
|
|
4421
|
-
|
|
4422
|
-
|
|
4423
|
-
if (!
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4481
|
+
let exited = false;
|
|
4482
|
+
let exitCode = null;
|
|
4483
|
+
const startedPromise = new Promise((resolve7) => {
|
|
4484
|
+
const timeout = setTimeout(() => {
|
|
4485
|
+
if (!started && !exited) {
|
|
4486
|
+
resolve7(false);
|
|
4487
|
+
}
|
|
4488
|
+
}, startupTimeout);
|
|
4489
|
+
child.stdout?.on("data", (data) => {
|
|
4490
|
+
const output = data.toString();
|
|
4491
|
+
if (!started && (output.includes("Ready") || output.includes("started") || output.includes("localhost"))) {
|
|
4492
|
+
started = true;
|
|
4493
|
+
clearTimeout(timeout);
|
|
4494
|
+
resolve7(true);
|
|
4495
|
+
}
|
|
4496
|
+
});
|
|
4427
4497
|
child.stderr?.on("data", (data) => {
|
|
4428
4498
|
const output = data.toString();
|
|
4429
4499
|
if (output.toLowerCase().includes("error")) {
|
|
4430
|
-
console.error(` Web UI error: ${output.trim()}`);
|
|
4500
|
+
if (!quiet) console.error(` Web UI error: ${output.trim().slice(0, 200)}`);
|
|
4431
4501
|
}
|
|
4432
4502
|
});
|
|
4433
|
-
|
|
4434
|
-
|
|
4435
|
-
|
|
4503
|
+
child.on("error", (err) => {
|
|
4504
|
+
if (!quiet) console.error(` \u274C Web UI spawn error: ${err.message}`);
|
|
4505
|
+
clearTimeout(timeout);
|
|
4506
|
+
resolve7(false);
|
|
4507
|
+
});
|
|
4508
|
+
child.on("exit", (code) => {
|
|
4509
|
+
exited = true;
|
|
4510
|
+
exitCode = code;
|
|
4511
|
+
if (!started) {
|
|
4512
|
+
clearTimeout(timeout);
|
|
4513
|
+
resolve7(false);
|
|
4514
|
+
}
|
|
4515
|
+
webUIProcess = null;
|
|
4516
|
+
});
|
|
4436
4517
|
});
|
|
4437
4518
|
webUIProcess = child;
|
|
4438
|
-
|
|
4519
|
+
const didStart = await startedPromise;
|
|
4520
|
+
if (!didStart) {
|
|
4521
|
+
if (exited && exitCode !== 0) {
|
|
4522
|
+
if (!quiet) console.error(` \u274C Web UI failed to start (exit code: ${exitCode})`);
|
|
4523
|
+
} else if (!exited) {
|
|
4524
|
+
if (!quiet) console.log(` \u26A0 Web UI startup timed out, continuing anyway...`);
|
|
4525
|
+
}
|
|
4526
|
+
}
|
|
4527
|
+
return { process: child, port: actualPort, started: didStart };
|
|
4439
4528
|
}
|
|
4440
4529
|
function stopWebUI() {
|
|
4441
4530
|
if (webUIProcess) {
|
|
@@ -4529,11 +4618,13 @@ async function startServer(options = {}) {
|
|
|
4529
4618
|
hostname: host
|
|
4530
4619
|
});
|
|
4531
4620
|
let webPort;
|
|
4621
|
+
let webStarted;
|
|
4532
4622
|
if (options.webUI !== false) {
|
|
4533
4623
|
const result = await startWebUI(port, options.webPort || DEFAULT_WEB_PORT, options.quiet);
|
|
4534
4624
|
webPort = result.port;
|
|
4625
|
+
webStarted = result.started;
|
|
4535
4626
|
}
|
|
4536
|
-
return { app, port, host, webPort };
|
|
4627
|
+
return { app, port, host, webPort, webStarted };
|
|
4537
4628
|
}
|
|
4538
4629
|
function stopServer() {
|
|
4539
4630
|
stopWebUI();
|