@kynver-app/runtime 0.1.2 → 0.1.4
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/cli.js +176 -37
- package/dist/cli.js.map +4 -4
- package/dist/index.js +179 -40
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { mkdirSync as mkdirSync5 } from "node:fs";
|
|
5
|
-
import
|
|
5
|
+
import path13 from "node:path";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
8
|
// src/config.ts
|
|
@@ -243,12 +243,12 @@ var DEFAULT_CRITICAL_FREE_BYTES = 15 * 1024 * 1024 * 1024;
|
|
|
243
243
|
var DEFAULT_MAX_USED_PERCENT = 80;
|
|
244
244
|
var DEFAULT_HARD_MAX_USED_PERCENT = 90;
|
|
245
245
|
function observeRunnerDiskGate(input = {}) {
|
|
246
|
-
const
|
|
246
|
+
const path14 = input.diskPath?.trim() || "/";
|
|
247
247
|
const warnBelowBytes = input.diskFreeWarnBytes ?? DEFAULT_WARN_FREE_BYTES;
|
|
248
248
|
const criticalBelowBytes = input.diskFreeCriticalBytes ?? DEFAULT_CRITICAL_FREE_BYTES;
|
|
249
249
|
const maxUsedPercent = input.diskMaxUsedPercent ?? DEFAULT_MAX_USED_PERCENT;
|
|
250
250
|
const hardMaxUsedPercent = input.diskHardMaxUsedPercent ?? DEFAULT_HARD_MAX_USED_PERCENT;
|
|
251
|
-
const stats = statfsSync(
|
|
251
|
+
const stats = statfsSync(path14);
|
|
252
252
|
const freeBytes = Number(stats.bavail) * Number(stats.bsize);
|
|
253
253
|
const totalBytes = Number(stats.blocks) * Number(stats.bsize);
|
|
254
254
|
const usedPercent = totalBytes > 0 ? (totalBytes - freeBytes) / totalBytes * 100 : 100;
|
|
@@ -268,7 +268,7 @@ function observeRunnerDiskGate(input = {}) {
|
|
|
268
268
|
}
|
|
269
269
|
return {
|
|
270
270
|
ok,
|
|
271
|
-
path:
|
|
271
|
+
path: path14,
|
|
272
272
|
freeBytes,
|
|
273
273
|
totalBytes,
|
|
274
274
|
usedPercent,
|
|
@@ -379,7 +379,8 @@ function parseClaudeStream(file) {
|
|
|
379
379
|
for (const line of lines) {
|
|
380
380
|
const event = safeJson(line);
|
|
381
381
|
if (!event) continue;
|
|
382
|
-
const
|
|
382
|
+
const tsMs = event.timestamp_ms;
|
|
383
|
+
const ts = event.timestamp || event.ts || (tsMs ? new Date(tsMs).toISOString() : void 0);
|
|
383
384
|
if (ts) {
|
|
384
385
|
result.firstEventAt ||= ts;
|
|
385
386
|
result.lastEventAt = ts;
|
|
@@ -638,8 +639,8 @@ function observeRunnerResourceGate(input) {
|
|
|
638
639
|
}
|
|
639
640
|
|
|
640
641
|
// src/supervisor.ts
|
|
641
|
-
import { existsSync as
|
|
642
|
-
import
|
|
642
|
+
import { existsSync as existsSync7, mkdirSync as mkdirSync3 } from "node:fs";
|
|
643
|
+
import path7 from "node:path";
|
|
643
644
|
|
|
644
645
|
// src/prompt.ts
|
|
645
646
|
function buildPrompt(input) {
|
|
@@ -699,11 +700,44 @@ var claudeProvider = {
|
|
|
699
700
|
};
|
|
700
701
|
|
|
701
702
|
// src/providers/cursor.ts
|
|
702
|
-
import { closeSync as closeSync2, openSync as openSync2 } from "node:fs";
|
|
703
|
+
import { closeSync as closeSync2, existsSync as existsSync6, openSync as openSync2, readdirSync as readdirSync2 } from "node:fs";
|
|
703
704
|
import { spawn as spawn2 } from "node:child_process";
|
|
705
|
+
import path6 from "node:path";
|
|
704
706
|
var DEFAULT_CURSOR_MODEL = "composer-2.5";
|
|
707
|
+
function latestVersionDir(versionsRoot) {
|
|
708
|
+
if (!existsSync6(versionsRoot)) return null;
|
|
709
|
+
const versions = readdirSync2(versionsRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && /^\d{4}\.\d/.test(entry.name)).map((entry) => entry.name).sort((a, b) => b.localeCompare(a));
|
|
710
|
+
return versions[0] ? path6.join(versionsRoot, versions[0]) : null;
|
|
711
|
+
}
|
|
712
|
+
function resolveBundledCursor(versionDir) {
|
|
713
|
+
const nodeExe = path6.join(versionDir, "node.exe");
|
|
714
|
+
const indexJs = path6.join(versionDir, "index.js");
|
|
715
|
+
if (!existsSync6(nodeExe) || !existsSync6(indexJs)) return null;
|
|
716
|
+
return { executable: nodeExe, prefixArgs: [indexJs], shell: false, detached: true };
|
|
717
|
+
}
|
|
718
|
+
function resolveWindowsCursorSpawn(agentBin) {
|
|
719
|
+
const agentRoot = path6.dirname(agentBin);
|
|
720
|
+
const direct = resolveBundledCursor(agentRoot);
|
|
721
|
+
if (direct) return direct;
|
|
722
|
+
const versionDir = latestVersionDir(path6.join(agentRoot, "versions"));
|
|
723
|
+
return versionDir ? resolveBundledCursor(versionDir) : null;
|
|
724
|
+
}
|
|
725
|
+
function resolveCursorSpawn(agentBin) {
|
|
726
|
+
if (process.platform === "win32" && /\.(cmd|bat)$/i.test(agentBin)) {
|
|
727
|
+
const bundled = resolveWindowsCursorSpawn(agentBin);
|
|
728
|
+
if (bundled) return bundled;
|
|
729
|
+
return { executable: agentBin, prefixArgs: [], shell: true, detached: false };
|
|
730
|
+
}
|
|
731
|
+
return { executable: agentBin, prefixArgs: [], shell: false, detached: true };
|
|
732
|
+
}
|
|
705
733
|
function resolveAgentBin() {
|
|
706
|
-
|
|
734
|
+
const configured = process.env.KYNVER_CURSOR_AGENT_BIN?.trim() || process.env.CURSOR_AGENT_BIN?.trim();
|
|
735
|
+
if (configured) return configured;
|
|
736
|
+
if (process.platform === "win32") {
|
|
737
|
+
const localAgent = path6.join(process.env.LOCALAPPDATA || "", "cursor-agent", "agent.cmd");
|
|
738
|
+
if (existsSync6(localAgent)) return localAgent;
|
|
739
|
+
}
|
|
740
|
+
return "agent";
|
|
707
741
|
}
|
|
708
742
|
var cursorProvider = {
|
|
709
743
|
name: "cursor",
|
|
@@ -712,9 +746,11 @@ var cursorProvider = {
|
|
|
712
746
|
const stdoutFd = openSync2(opts.stdoutPath, "a");
|
|
713
747
|
const stderrFd = openSync2(opts.stderrPath, "a");
|
|
714
748
|
const agentBin = resolveAgentBin();
|
|
749
|
+
const spawnTarget = resolveCursorSpawn(agentBin);
|
|
715
750
|
const child = spawn2(
|
|
716
|
-
|
|
751
|
+
spawnTarget.executable,
|
|
717
752
|
[
|
|
753
|
+
...spawnTarget.prefixArgs,
|
|
718
754
|
"-p",
|
|
719
755
|
"--force",
|
|
720
756
|
"--trust",
|
|
@@ -729,9 +765,13 @@ var cursorProvider = {
|
|
|
729
765
|
],
|
|
730
766
|
{
|
|
731
767
|
cwd: opts.worktreePath,
|
|
732
|
-
detached:
|
|
768
|
+
detached: spawnTarget.detached,
|
|
769
|
+
shell: spawnTarget.shell,
|
|
733
770
|
stdio: ["ignore", stdoutFd, stderrFd],
|
|
734
|
-
env:
|
|
771
|
+
env: {
|
|
772
|
+
...process.env,
|
|
773
|
+
...spawnTarget.prefixArgs.length > 0 ? { CURSOR_INVOKED_AS: path6.basename(agentBin) } : {}
|
|
774
|
+
}
|
|
735
775
|
}
|
|
736
776
|
);
|
|
737
777
|
closeSync2(stdoutFd);
|
|
@@ -769,16 +809,16 @@ function spawnWorkerProcess(run, opts) {
|
|
|
769
809
|
if (run.workers?.[name]) throw new Error(`worker already exists in run ${run.id}: ${name}`);
|
|
770
810
|
if (!opts.task) throw new Error(`missing task text for worker ${name}`);
|
|
771
811
|
const { worktreesDir } = getPaths();
|
|
772
|
-
const workerDir =
|
|
812
|
+
const workerDir = path7.join(runDirectory(run.id), "workers", name);
|
|
773
813
|
mkdirSync3(workerDir, { recursive: true });
|
|
774
|
-
const worktreePath =
|
|
814
|
+
const worktreePath = path7.join(worktreesDir, run.id, name);
|
|
775
815
|
const branch = opts.branch || `agent/${run.id}/${name}`;
|
|
776
|
-
if (
|
|
816
|
+
if (existsSync7(worktreePath)) throw new Error(`worktree path already exists: ${worktreePath}`);
|
|
777
817
|
git(run.repo, ["fetch", "origin", "--prune"], { allowFailure: true });
|
|
778
818
|
git(run.repo, ["worktree", "add", "-b", branch, worktreePath, run.baseCommit], { throwError: true });
|
|
779
|
-
const stdoutPath =
|
|
780
|
-
const stderrPath =
|
|
781
|
-
const heartbeatPath =
|
|
819
|
+
const stdoutPath = path7.join(workerDir, "stdout.jsonl");
|
|
820
|
+
const stderrPath = path7.join(workerDir, "stderr.log");
|
|
821
|
+
const heartbeatPath = path7.join(workerDir, "heartbeat.jsonl");
|
|
782
822
|
const prompt = buildPrompt({
|
|
783
823
|
task: opts.task,
|
|
784
824
|
ownedPaths: opts.ownedPaths || [],
|
|
@@ -827,7 +867,7 @@ function spawnWorkerProcess(run, opts) {
|
|
|
827
867
|
startedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
828
868
|
};
|
|
829
869
|
saveWorker(run.id, worker);
|
|
830
|
-
run.workers = { ...run.workers || {}, [name]: { workerDir, statusPath:
|
|
870
|
+
run.workers = { ...run.workers || {}, [name]: { workerDir, statusPath: path7.join(workerDir, "worker.json") } };
|
|
831
871
|
run.status = "running";
|
|
832
872
|
saveRun(run);
|
|
833
873
|
return worker;
|
|
@@ -1023,7 +1063,7 @@ async function dispatchRun(args) {
|
|
|
1023
1063
|
}
|
|
1024
1064
|
|
|
1025
1065
|
// src/sweep.ts
|
|
1026
|
-
import
|
|
1066
|
+
import path8 from "node:path";
|
|
1027
1067
|
async function sweepRun(args) {
|
|
1028
1068
|
const pipeline = args.pipeline === true || args.pipeline === "true";
|
|
1029
1069
|
try {
|
|
@@ -1035,7 +1075,7 @@ async function sweepRun(args) {
|
|
|
1035
1075
|
const releasedLocalOrphans = [];
|
|
1036
1076
|
for (const name of Object.keys(run.workers || {})) {
|
|
1037
1077
|
const worker = readJson(
|
|
1038
|
-
|
|
1078
|
+
path8.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
1039
1079
|
null
|
|
1040
1080
|
);
|
|
1041
1081
|
if (!worker || !worker.dispatched || !worker.taskId) continue;
|
|
@@ -1078,11 +1118,11 @@ async function sweepRun(args) {
|
|
|
1078
1118
|
}
|
|
1079
1119
|
|
|
1080
1120
|
// src/worktree.ts
|
|
1081
|
-
import { existsSync as
|
|
1082
|
-
import
|
|
1121
|
+
import { existsSync as existsSync8, mkdirSync as mkdirSync4 } from "node:fs";
|
|
1122
|
+
import path10 from "node:path";
|
|
1083
1123
|
|
|
1084
1124
|
// src/validate.ts
|
|
1085
|
-
import
|
|
1125
|
+
import path9 from "node:path";
|
|
1086
1126
|
var RUN_ID_RE = /^[a-z0-9][a-z0-9._-]{0,127}$/i;
|
|
1087
1127
|
function validateRunId(runId) {
|
|
1088
1128
|
const trimmed = runId.trim();
|
|
@@ -1090,7 +1130,7 @@ function validateRunId(runId) {
|
|
|
1090
1130
|
return trimmed;
|
|
1091
1131
|
}
|
|
1092
1132
|
function validateRepo(repo) {
|
|
1093
|
-
const resolved =
|
|
1133
|
+
const resolved = path9.resolve(repo);
|
|
1094
1134
|
if (resolved.includes("..")) throw new Error("repo path must not contain .. segments");
|
|
1095
1135
|
return resolved;
|
|
1096
1136
|
}
|
|
@@ -1101,7 +1141,7 @@ function createRun(args) {
|
|
|
1101
1141
|
ensureGitRepo(repo);
|
|
1102
1142
|
const id = args.id ? validateRunId(String(args.id)) : timestampSlug(String(args.name || "run"));
|
|
1103
1143
|
const dir = runDirectory(id);
|
|
1104
|
-
if (
|
|
1144
|
+
if (existsSync8(dir)) failExists(`run already exists: ${id}`);
|
|
1105
1145
|
mkdirSync4(dir, { recursive: true });
|
|
1106
1146
|
const base = String(args.base || "origin/main");
|
|
1107
1147
|
const baseCommit = git(repo, ["rev-parse", base]).trim();
|
|
@@ -1115,12 +1155,12 @@ function createRun(args) {
|
|
|
1115
1155
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1116
1156
|
workers: {}
|
|
1117
1157
|
};
|
|
1118
|
-
writeJson(
|
|
1158
|
+
writeJson(path10.join(dir, "run.json"), run);
|
|
1119
1159
|
console.log(JSON.stringify({ runId: id, runDir: dir, repo, base, baseCommit }, null, 2));
|
|
1120
1160
|
}
|
|
1121
1161
|
function listRuns() {
|
|
1122
1162
|
const { runsDir } = getPaths();
|
|
1123
|
-
const rows = listRunIds(runsDir).map((id) => readJson(
|
|
1163
|
+
const rows = listRunIds(runsDir).map((id) => readJson(path10.join(runDirectory(id), "run.json"), null)).filter(Boolean).map((run) => ({
|
|
1124
1164
|
id: run.id,
|
|
1125
1165
|
name: run.name,
|
|
1126
1166
|
status: run.status,
|
|
@@ -1135,7 +1175,7 @@ function failExists(message) {
|
|
|
1135
1175
|
}
|
|
1136
1176
|
|
|
1137
1177
|
// src/worker-ops.ts
|
|
1138
|
-
import
|
|
1178
|
+
import path11 from "node:path";
|
|
1139
1179
|
async function tryCompleteWorker(args) {
|
|
1140
1180
|
const worker = loadWorker(String(args.run), String(args.name));
|
|
1141
1181
|
const status = computeWorkerStatus(worker);
|
|
@@ -1228,7 +1268,7 @@ async function completeWorker(args) {
|
|
|
1228
1268
|
function workerStatus(args) {
|
|
1229
1269
|
const worker = loadWorker(String(args.run), String(args.name));
|
|
1230
1270
|
const status = computeWorkerStatus(worker);
|
|
1231
|
-
writeJson(
|
|
1271
|
+
writeJson(path11.join(worker.workerDir, "last-status.json"), status);
|
|
1232
1272
|
console.log(JSON.stringify(status, null, 2));
|
|
1233
1273
|
}
|
|
1234
1274
|
function runStatus(args) {
|
|
@@ -1236,7 +1276,7 @@ function runStatus(args) {
|
|
|
1236
1276
|
const names = Object.keys(run.workers || {});
|
|
1237
1277
|
const workers = names.map((name) => {
|
|
1238
1278
|
const worker = readJson(
|
|
1239
|
-
|
|
1279
|
+
path11.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
1240
1280
|
null
|
|
1241
1281
|
);
|
|
1242
1282
|
if (!worker) {
|
|
@@ -1268,7 +1308,7 @@ function runStatus(args) {
|
|
|
1268
1308
|
needsAttention: workers.filter((w) => w.attention && w.attention !== "ok" && w.attention !== "done").map((w) => w.worker),
|
|
1269
1309
|
workers
|
|
1270
1310
|
};
|
|
1271
|
-
writeJson(
|
|
1311
|
+
writeJson(path11.join(runDirectory(run.id), "last-board.json"), board);
|
|
1272
1312
|
console.log(JSON.stringify(board, null, 2));
|
|
1273
1313
|
}
|
|
1274
1314
|
function tailWorker(args) {
|
|
@@ -1301,7 +1341,7 @@ function stopWorker(args) {
|
|
|
1301
1341
|
}
|
|
1302
1342
|
|
|
1303
1343
|
// src/pipeline-tick.ts
|
|
1304
|
-
import
|
|
1344
|
+
import path12 from "node:path";
|
|
1305
1345
|
|
|
1306
1346
|
// src/workspace-runtime-config.ts
|
|
1307
1347
|
async function fetchWorkspaceRuntimePreferences(agentOsId, args) {
|
|
@@ -1330,7 +1370,7 @@ async function completeFinishedWorkers(runId, args) {
|
|
|
1330
1370
|
const outcomes = [];
|
|
1331
1371
|
for (const name of Object.keys(run.workers || {})) {
|
|
1332
1372
|
const worker = readJson(
|
|
1333
|
-
|
|
1373
|
+
path12.join(runDirectory(run.id), "workers", safeSlug(name), "worker.json"),
|
|
1334
1374
|
null
|
|
1335
1375
|
);
|
|
1336
1376
|
if (!worker?.dispatched || !worker.taskId) continue;
|
|
@@ -1448,6 +1488,101 @@ async function runDaemon(args) {
|
|
|
1448
1488
|
console.error(JSON.stringify({ event: "daemon_stop", runId, agentOsId }));
|
|
1449
1489
|
}
|
|
1450
1490
|
|
|
1491
|
+
// src/plan-progress.ts
|
|
1492
|
+
function parseEvidenceArg(raw) {
|
|
1493
|
+
const idx = raw.indexOf(":");
|
|
1494
|
+
if (idx <= 0) throw new Error(`invalid --evidence ${raw} (expected type:value)`);
|
|
1495
|
+
return { type: raw.slice(0, idx), value: raw.slice(idx + 1) };
|
|
1496
|
+
}
|
|
1497
|
+
async function emitPlanProgress(args) {
|
|
1498
|
+
const planId = required(args, "plan");
|
|
1499
|
+
const agentOsId = (args.agentOsId ? String(args.agentOsId) : loadUserConfig().agentOsId) || "";
|
|
1500
|
+
if (!agentOsId) {
|
|
1501
|
+
console.error("requires --agent-os-id or agentOsId in ~/.kynver/config.json");
|
|
1502
|
+
process.exit(1);
|
|
1503
|
+
}
|
|
1504
|
+
const roleLane = required(args, "role");
|
|
1505
|
+
const status = required(args, "status");
|
|
1506
|
+
const evidence = [];
|
|
1507
|
+
const rawEvidence = args.evidence;
|
|
1508
|
+
if (Array.isArray(rawEvidence)) {
|
|
1509
|
+
for (const item of rawEvidence) evidence.push(parseEvidenceArg(String(item)));
|
|
1510
|
+
} else if (typeof rawEvidence === "string") {
|
|
1511
|
+
evidence.push(parseEvidenceArg(rawEvidence));
|
|
1512
|
+
}
|
|
1513
|
+
const base = resolveBaseUrl(args.baseUrl ? String(args.baseUrl) : void 0);
|
|
1514
|
+
const secret = resolveCallbackSecret(args.secret ? String(args.secret) : void 0);
|
|
1515
|
+
const url = `${base}/api/agent-os/by-id/${encodeURIComponent(agentOsId)}/plans/${encodeURIComponent(planId)}/progress-events`;
|
|
1516
|
+
const body = {
|
|
1517
|
+
rowKey: args.row ? String(args.row) : void 0,
|
|
1518
|
+
rowId: args.rowId ? String(args.rowId) : void 0,
|
|
1519
|
+
taskId: args.task ? String(args.task) : void 0,
|
|
1520
|
+
reviewTaskId: args.reviewTask ? String(args.reviewTask) : void 0,
|
|
1521
|
+
roleLane,
|
|
1522
|
+
status,
|
|
1523
|
+
note: args.note ? String(args.note) : void 0,
|
|
1524
|
+
remainingWork: args.remaining ? String(args.remaining) : void 0,
|
|
1525
|
+
evidence: evidence.length ? evidence : void 0,
|
|
1526
|
+
proposed: args.proposed === true || args.proposed === "true",
|
|
1527
|
+
executorRef: args.executorRef ? String(args.executorRef) : void 0
|
|
1528
|
+
};
|
|
1529
|
+
const res = await fetch(url, {
|
|
1530
|
+
method: "POST",
|
|
1531
|
+
headers: {
|
|
1532
|
+
"Content-Type": "application/json",
|
|
1533
|
+
"X-OpenClaw-Cron-Secret": secret,
|
|
1534
|
+
"X-Kynver-Runtime-Secret": secret
|
|
1535
|
+
},
|
|
1536
|
+
body: JSON.stringify(body)
|
|
1537
|
+
});
|
|
1538
|
+
const text = await res.text();
|
|
1539
|
+
let parsed = null;
|
|
1540
|
+
try {
|
|
1541
|
+
parsed = JSON.parse(text);
|
|
1542
|
+
} catch {
|
|
1543
|
+
parsed = text;
|
|
1544
|
+
}
|
|
1545
|
+
if (!res.ok) {
|
|
1546
|
+
console.error(JSON.stringify({ httpStatus: res.status, response: parsed }, null, 2));
|
|
1547
|
+
process.exit(1);
|
|
1548
|
+
}
|
|
1549
|
+
console.log(JSON.stringify(parsed, null, 2));
|
|
1550
|
+
}
|
|
1551
|
+
async function verifyPlan(args) {
|
|
1552
|
+
const planId = required(args, "plan");
|
|
1553
|
+
const slug = loadUserConfig().agentOsSlug;
|
|
1554
|
+
if (!slug) {
|
|
1555
|
+
console.error("requires agentOsSlug in ~/.kynver/config.json for verify (session route)");
|
|
1556
|
+
process.exit(1);
|
|
1557
|
+
}
|
|
1558
|
+
const base = resolveBaseUrl(args.baseUrl ? String(args.baseUrl) : void 0);
|
|
1559
|
+
const apiKey = process.env.KYNVER_API_KEY;
|
|
1560
|
+
const headers = { "Content-Type": "application/json" };
|
|
1561
|
+
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
1562
|
+
const url = `${base}/api/agent-os/${encodeURIComponent(slug)}/plans/${encodeURIComponent(planId)}/verify`;
|
|
1563
|
+
const res = await fetch(url, {
|
|
1564
|
+
method: "POST",
|
|
1565
|
+
headers,
|
|
1566
|
+
body: JSON.stringify({
|
|
1567
|
+
worktreePath: args.worktree ? String(args.worktree) : void 0,
|
|
1568
|
+
taskId: args.task ? String(args.task) : void 0,
|
|
1569
|
+
humanOverride: args.humanOverride === true || args.humanOverride === "true"
|
|
1570
|
+
})
|
|
1571
|
+
});
|
|
1572
|
+
const text = await res.text();
|
|
1573
|
+
let parsed = null;
|
|
1574
|
+
try {
|
|
1575
|
+
parsed = JSON.parse(text);
|
|
1576
|
+
} catch {
|
|
1577
|
+
parsed = text;
|
|
1578
|
+
}
|
|
1579
|
+
if (!res.ok) {
|
|
1580
|
+
console.error(JSON.stringify({ httpStatus: res.status, response: parsed }, null, 2));
|
|
1581
|
+
process.exit(1);
|
|
1582
|
+
}
|
|
1583
|
+
console.log(JSON.stringify(parsed, null, 2));
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1451
1586
|
// src/cli.ts
|
|
1452
1587
|
function isHelpFlag(arg) {
|
|
1453
1588
|
return arg === "help" || arg === "--help" || arg === "-h";
|
|
@@ -1474,7 +1609,9 @@ function usage(code = 0) {
|
|
|
1474
1609
|
" kynver worker status --run RUN_ID --name worker",
|
|
1475
1610
|
" kynver worker tail --run RUN_ID --name worker [--lines 40] [--raw]",
|
|
1476
1611
|
" kynver worker stop --run RUN_ID --name worker",
|
|
1477
|
-
" kynver worker complete --run RUN_ID --name worker [--agent-os-id AOS_ID] [--task-id TASK_ID] [--base-url URL] [--secret SECRET]"
|
|
1612
|
+
" kynver worker complete --run RUN_ID --name worker [--agent-os-id AOS_ID] [--task-id TASK_ID] [--base-url URL] [--secret SECRET]",
|
|
1613
|
+
" kynver plan progress --plan PLAN_ID --row ROW_KEY --role ROLE --status STATUS [--task TASK_ID] [--note NOTE] [--evidence type:value] [--agent-os-id AOS_ID]",
|
|
1614
|
+
" kynver plan verify --plan PLAN_ID [--worktree PATH] [--task TASK_ID] [--human-override]"
|
|
1478
1615
|
].join("\n")
|
|
1479
1616
|
);
|
|
1480
1617
|
process.exit(code);
|
|
@@ -1484,7 +1621,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1484
1621
|
const scope = argv.shift();
|
|
1485
1622
|
let action;
|
|
1486
1623
|
let rest;
|
|
1487
|
-
if (scope === "run" || scope === "worker") {
|
|
1624
|
+
if (scope === "run" || scope === "worker" || scope === "plan") {
|
|
1488
1625
|
action = argv.shift();
|
|
1489
1626
|
rest = argv;
|
|
1490
1627
|
} else {
|
|
@@ -1497,6 +1634,8 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1497
1634
|
if (scope === "login") return void await runLogin(args);
|
|
1498
1635
|
if (scope === "setup") return void await runSetup(args);
|
|
1499
1636
|
if (scope === "daemon") return void await runDaemon(args);
|
|
1637
|
+
if (scope === "plan" && action === "progress") return void await emitPlanProgress(args);
|
|
1638
|
+
if (scope === "plan" && action === "verify") return void await verifyPlan(args);
|
|
1500
1639
|
if (scope === "run" && action === "create") return createRun(args);
|
|
1501
1640
|
if (scope === "run" && action === "list") return listRuns();
|
|
1502
1641
|
if (scope === "run" && action === "status") return runStatus(args);
|
|
@@ -1509,7 +1648,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1509
1648
|
if (scope === "worker" && action === "complete") return void await completeWorker(args);
|
|
1510
1649
|
unknownCommand(scope, action);
|
|
1511
1650
|
}
|
|
1512
|
-
var isCliEntry = process.argv[1] &&
|
|
1651
|
+
var isCliEntry = process.argv[1] && path13.resolve(process.argv[1]) === path13.resolve(fileURLToPath(import.meta.url));
|
|
1513
1652
|
if (isCliEntry) {
|
|
1514
1653
|
void main().catch((error) => {
|
|
1515
1654
|
console.error(error);
|