opencara 0.105.1 → 0.105.3
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/bin.js +86 -2
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
uptime
|
|
14
14
|
} from "node:os";
|
|
15
15
|
import { statfsSync } from "node:fs";
|
|
16
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
16
17
|
|
|
17
18
|
// src/config/store.ts
|
|
18
19
|
import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from "node:fs";
|
|
@@ -1205,7 +1206,7 @@ function resolveLocalAcpAdapter(command, args) {
|
|
|
1205
1206
|
}
|
|
1206
1207
|
|
|
1207
1208
|
// src/commands/run.ts
|
|
1208
|
-
var PKG_VERSION = "0.105.
|
|
1209
|
+
var PKG_VERSION = "0.105.3";
|
|
1209
1210
|
var LOG_FLUSH_MS = 800;
|
|
1210
1211
|
var MAX_CHUNK_SIZE = 4 * 1024;
|
|
1211
1212
|
async function run(opts = {}) {
|
|
@@ -1281,6 +1282,11 @@ async function executeJob(job, client) {
|
|
|
1281
1282
|
if (flushTimer) return;
|
|
1282
1283
|
flushTimer = setTimeout(flush, LOG_FLUSH_MS);
|
|
1283
1284
|
};
|
|
1285
|
+
if (isInternalCommand(job.spec)) {
|
|
1286
|
+
flush();
|
|
1287
|
+
await runInternalCommand(job, client);
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1284
1290
|
if (!job.spec.acp) {
|
|
1285
1291
|
flush();
|
|
1286
1292
|
const message = `legacy stdin-JSON dispatch removed in v0.30 \u2014 orchestrator must send spec.acp. Got command: ${job.spec.command}.`;
|
|
@@ -1322,6 +1328,63 @@ async function executeJob(job, client) {
|
|
|
1322
1328
|
acpControllers.delete(runId);
|
|
1323
1329
|
}
|
|
1324
1330
|
}
|
|
1331
|
+
function isInternalCommand(spec) {
|
|
1332
|
+
return spec.command === "opencara" && Array.isArray(spec.args) && spec.args[0] === "internal";
|
|
1333
|
+
}
|
|
1334
|
+
async function runInternalCommand(job, client, opts = {}) {
|
|
1335
|
+
const runId = job.run.id;
|
|
1336
|
+
const args = job.spec.args ?? [];
|
|
1337
|
+
const binPath = opts.binPath ?? process.argv[1];
|
|
1338
|
+
const nodePath = opts.nodePath ?? process.execPath;
|
|
1339
|
+
if (!binPath) {
|
|
1340
|
+
client.send({
|
|
1341
|
+
type: "done",
|
|
1342
|
+
runId,
|
|
1343
|
+
status: "failed",
|
|
1344
|
+
errorMessage: "internal: process.argv[1] missing \u2014 cannot re-invoke bin"
|
|
1345
|
+
});
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
let seq = 0;
|
|
1349
|
+
const emit = (stream, chunk) => {
|
|
1350
|
+
let remaining = chunk;
|
|
1351
|
+
while (remaining.length > 0) {
|
|
1352
|
+
const take = remaining.slice(0, MAX_CHUNK_SIZE);
|
|
1353
|
+
client.send({ type: "log", runId, seq: seq++, stream, chunk: take });
|
|
1354
|
+
remaining = remaining.slice(MAX_CHUNK_SIZE);
|
|
1355
|
+
}
|
|
1356
|
+
};
|
|
1357
|
+
const child = spawn3(nodePath, [binPath, ...args], {
|
|
1358
|
+
cwd: job.spec.cwd,
|
|
1359
|
+
env: job.spec.env ? { ...process.env, ...job.spec.env } : process.env,
|
|
1360
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
1361
|
+
});
|
|
1362
|
+
child.stdout.setEncoding("utf8");
|
|
1363
|
+
child.stdout.on("data", (c) => emit("stdout", c));
|
|
1364
|
+
child.stderr.setEncoding("utf8");
|
|
1365
|
+
child.stderr.on("data", (c) => emit("stderr", c));
|
|
1366
|
+
const { exitCode, errorMessage } = await new Promise((resolve) => {
|
|
1367
|
+
let done = false;
|
|
1368
|
+
child.on("error", (err) => {
|
|
1369
|
+
if (done) return;
|
|
1370
|
+
done = true;
|
|
1371
|
+
resolve({ exitCode: 1, errorMessage: `internal spawn error: ${err.message}` });
|
|
1372
|
+
});
|
|
1373
|
+
child.on("close", (code, signal) => {
|
|
1374
|
+
if (done) return;
|
|
1375
|
+
done = true;
|
|
1376
|
+
resolve({ exitCode: code ?? (signal ? 1 : 0) });
|
|
1377
|
+
});
|
|
1378
|
+
});
|
|
1379
|
+
client.send({
|
|
1380
|
+
type: "done",
|
|
1381
|
+
runId,
|
|
1382
|
+
status: exitCode === 0 ? "succeeded" : "failed",
|
|
1383
|
+
exitCode,
|
|
1384
|
+
...errorMessage ? { errorMessage } : {}
|
|
1385
|
+
});
|
|
1386
|
+
console.log(`[opencara] job ${runId.slice(-8)} (internal) \u2192 exit=${exitCode}`);
|
|
1387
|
+
}
|
|
1325
1388
|
function collectSystemInfo() {
|
|
1326
1389
|
try {
|
|
1327
1390
|
const cpuList = cpus();
|
|
@@ -1470,7 +1533,17 @@ function worktreeCreate(args) {
|
|
|
1470
1533
|
mkdirSync2(sessionDir, { recursive: true });
|
|
1471
1534
|
if (existsSync4(join2(checkoutDir, ".git"))) {
|
|
1472
1535
|
git(checkoutDir, ["fetch", "origin"]);
|
|
1473
|
-
|
|
1536
|
+
if (refExists(checkoutDir, `refs/remotes/origin/${branch}`)) {
|
|
1537
|
+
git(checkoutDir, ["checkout", "-B", branch, `origin/${branch}`]);
|
|
1538
|
+
} else if (refExists(checkoutDir, `refs/heads/${branch}`)) {
|
|
1539
|
+
git(checkoutDir, ["checkout", branch]);
|
|
1540
|
+
} else if (fromBranch) {
|
|
1541
|
+
git(checkoutDir, ["checkout", "-B", branch, `origin/${fromBranch}`]);
|
|
1542
|
+
} else {
|
|
1543
|
+
fail(
|
|
1544
|
+
`worktree create: '${branch}' missing locally and on origin/, no --from-branch to fall back to`
|
|
1545
|
+
);
|
|
1546
|
+
}
|
|
1474
1547
|
} else {
|
|
1475
1548
|
mkdirSync2(checkoutDir, { recursive: true });
|
|
1476
1549
|
const cloneArgs = ["-c", `credential.helper=${HELPER_SNIPPET}`, "clone"];
|
|
@@ -1572,6 +1645,17 @@ function worktreeRemove(args) {
|
|
|
1572
1645
|
function git(cwd, args) {
|
|
1573
1646
|
execFileSync("git", args, { cwd, stdio: ["ignore", "ignore", "inherit"] });
|
|
1574
1647
|
}
|
|
1648
|
+
function refExists(cwd, ref) {
|
|
1649
|
+
try {
|
|
1650
|
+
execFileSync("git", ["rev-parse", "--verify", "--quiet", ref], {
|
|
1651
|
+
cwd,
|
|
1652
|
+
stdio: ["ignore", "ignore", "ignore"]
|
|
1653
|
+
});
|
|
1654
|
+
return true;
|
|
1655
|
+
} catch {
|
|
1656
|
+
return false;
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1575
1659
|
function pickFlag(argv, name) {
|
|
1576
1660
|
const i = argv.indexOf(name);
|
|
1577
1661
|
if (i === -1) return void 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencara",
|
|
3
|
-
"version": "0.105.
|
|
3
|
+
"version": "0.105.3",
|
|
4
4
|
"description": "OpenCara agent-host CLI: register a machine as an agent host and run dispatched agents.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"dev": "tsx watch src/bin.ts",
|
|
39
39
|
"start": "node dist/bin.js",
|
|
40
40
|
"typecheck": "tsc -b",
|
|
41
|
-
"test": "node --import tsx --test --test-reporter=spec src/acp/__tests__/*.test.ts src/mcp/__tests__/*.test.ts src/runner/__tests__/*.test.ts src/bin/__tests__/*.test.ts",
|
|
41
|
+
"test": "node --import tsx --test --test-reporter=spec src/acp/__tests__/*.test.ts src/mcp/__tests__/*.test.ts src/runner/__tests__/*.test.ts src/bin/__tests__/*.test.ts src/commands/__tests__/*.test.ts",
|
|
42
42
|
"acp:spike": "tsx src/acp/spike.ts",
|
|
43
43
|
"mcp:smoke": "tsx src/mcp/smoke.ts",
|
|
44
44
|
"clean": "rm -rf dist *.tsbuildinfo"
|