@kynver-app/runtime 0.1.3 → 0.1.5
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 +114 -2
- package/dist/cli.js.map +3 -3
- package/dist/index.js +114 -2
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -638,6 +638,16 @@ import path7 from "node:path";
|
|
|
638
638
|
// src/prompt.ts
|
|
639
639
|
function buildPrompt(input) {
|
|
640
640
|
const ownership = input.ownedPaths.length ? `Owned paths: ${input.ownedPaths.join(", ")}. Do not edit outside these paths without stopping and reporting why.` : "Owned paths: unrestricted for this worker, but keep edits tightly scoped.";
|
|
641
|
+
const progressLines = [
|
|
642
|
+
"Structured plan progress (required when planId is set):",
|
|
643
|
+
"- Harness checkpoints only: `kynver plan progress --plan <planId> --row <rowKey> --role implementer --status running|partial|blocked` (the by-id harness route rejects `done` and confirm events).",
|
|
644
|
+
"- When a slice is finished, emit `partial` with evidence (`--evidence pr:<url>`, `--evidence path:<file>`, or `--evidence command:<cmd>`). Do not propose or confirm row `done` from the worker CLI.",
|
|
645
|
+
"- Propose/confirm row `done` is MCP/session only: chat agents use `agent_os_plan_progress_event_append` on the slug route (implementer proposes with `proposed: true`; report_reviewer/deep_reviewer confirm with `proposed: false`).",
|
|
646
|
+
"- When blocked on operator/Ghost/runtime review, create a linked review task (MCP `agent_os_plan_review_task_create` or API) and pass `--review-task <taskId>`.",
|
|
647
|
+
"- Before the completion report: mark completion-report rows partial with evidence; do not skip report review.",
|
|
648
|
+
"- After implementation: wait for report_reviewer then deep_reviewer confirmation (via MCP/session agents) before follow-up rows close.",
|
|
649
|
+
input.planId ? `Active planId: ${input.planId}${input.taskId ? ` \xB7 taskId: ${input.taskId}` : ""}` : "No planId on this worker \u2014 still emit progress when you touch plan-scoped work."
|
|
650
|
+
];
|
|
641
651
|
return [
|
|
642
652
|
"You are running under the Kynver AgentOS runtime.",
|
|
643
653
|
"Immediately state your plan before editing.",
|
|
@@ -647,6 +657,8 @@ function buildPrompt(input) {
|
|
|
647
657
|
"After each major step, append one JSON line to the heartbeat file with fields: ts, phase, summary, changedFiles, blocker.",
|
|
648
658
|
"Final response must include files changed, verification commands, and unresolved risks.",
|
|
649
659
|
"",
|
|
660
|
+
...progressLines,
|
|
661
|
+
"",
|
|
650
662
|
"Task:",
|
|
651
663
|
input.task
|
|
652
664
|
].join("\n");
|
|
@@ -1513,6 +1525,102 @@ async function runDaemon(args) {
|
|
|
1513
1525
|
console.error(JSON.stringify({ event: "daemon_stop", runId, agentOsId }));
|
|
1514
1526
|
}
|
|
1515
1527
|
|
|
1528
|
+
// src/plan-progress.ts
|
|
1529
|
+
function parseEvidenceArg(raw) {
|
|
1530
|
+
const idx = raw.indexOf(":");
|
|
1531
|
+
if (idx <= 0) throw new Error(`invalid --evidence ${raw} (expected type:value)`);
|
|
1532
|
+
return { type: raw.slice(0, idx), value: raw.slice(idx + 1) };
|
|
1533
|
+
}
|
|
1534
|
+
async function emitPlanProgress(args) {
|
|
1535
|
+
const planId = required(args.plan ? String(args.plan) : void 0, "plan");
|
|
1536
|
+
const agentOsId = (args.agentOsId ? String(args.agentOsId) : loadUserConfig().agentOsId) || "";
|
|
1537
|
+
if (!agentOsId) {
|
|
1538
|
+
console.error("requires --agent-os-id or agentOsId in ~/.kynver/config.json");
|
|
1539
|
+
process.exit(1);
|
|
1540
|
+
}
|
|
1541
|
+
const roleLane = required(args.role ? String(args.role) : void 0, "role");
|
|
1542
|
+
const status = required(args.status ? String(args.status) : void 0, "status");
|
|
1543
|
+
const evidence = [];
|
|
1544
|
+
const rawEvidence = args.evidence;
|
|
1545
|
+
if (Array.isArray(rawEvidence)) {
|
|
1546
|
+
for (const item of rawEvidence) evidence.push(parseEvidenceArg(String(item)));
|
|
1547
|
+
} else if (typeof rawEvidence === "string") {
|
|
1548
|
+
evidence.push(parseEvidenceArg(rawEvidence));
|
|
1549
|
+
}
|
|
1550
|
+
const base = resolveBaseUrl(args.baseUrl ? String(args.baseUrl) : void 0);
|
|
1551
|
+
const secret = resolveCallbackSecret(args.secret ? String(args.secret) : void 0);
|
|
1552
|
+
const url = `${base}/api/agent-os/by-id/${encodeURIComponent(agentOsId)}/plans/${encodeURIComponent(planId)}/progress-events`;
|
|
1553
|
+
const cfg = loadUserConfig();
|
|
1554
|
+
const provider = cfg.workerProvider ? `provider:${cfg.workerProvider}` : void 0;
|
|
1555
|
+
const body = {
|
|
1556
|
+
rowKey: args.row ? String(args.row) : void 0,
|
|
1557
|
+
rowId: args.rowId ? String(args.rowId) : void 0,
|
|
1558
|
+
taskId: args.task ? String(args.task) : void 0,
|
|
1559
|
+
reviewTaskId: args.reviewTask ? String(args.reviewTask) : void 0,
|
|
1560
|
+
roleLane,
|
|
1561
|
+
status,
|
|
1562
|
+
note: args.note ? String(args.note) : void 0,
|
|
1563
|
+
remainingWork: args.remaining ? String(args.remaining) : void 0,
|
|
1564
|
+
evidence: evidence.length ? evidence : void 0,
|
|
1565
|
+
proposed: args.proposed === true || args.proposed === "true",
|
|
1566
|
+
executorRef: args.executorRef ? String(args.executorRef) : provider
|
|
1567
|
+
};
|
|
1568
|
+
const res = await fetch(url, {
|
|
1569
|
+
method: "POST",
|
|
1570
|
+
headers: {
|
|
1571
|
+
"Content-Type": "application/json",
|
|
1572
|
+
"X-OpenClaw-Cron-Secret": secret
|
|
1573
|
+
},
|
|
1574
|
+
body: JSON.stringify(body)
|
|
1575
|
+
});
|
|
1576
|
+
const text = await res.text();
|
|
1577
|
+
let parsed = null;
|
|
1578
|
+
try {
|
|
1579
|
+
parsed = JSON.parse(text);
|
|
1580
|
+
} catch {
|
|
1581
|
+
parsed = text;
|
|
1582
|
+
}
|
|
1583
|
+
if (!res.ok) {
|
|
1584
|
+
console.error(JSON.stringify({ httpStatus: res.status, response: parsed }, null, 2));
|
|
1585
|
+
process.exit(1);
|
|
1586
|
+
}
|
|
1587
|
+
console.log(JSON.stringify(parsed, null, 2));
|
|
1588
|
+
}
|
|
1589
|
+
async function verifyPlan(args) {
|
|
1590
|
+
const planId = required(args.plan ? String(args.plan) : void 0, "plan");
|
|
1591
|
+
const slug = loadUserConfig().agentOsSlug;
|
|
1592
|
+
if (!slug) {
|
|
1593
|
+
console.error("requires agentOsSlug in ~/.kynver/config.json for verify (session route)");
|
|
1594
|
+
process.exit(1);
|
|
1595
|
+
}
|
|
1596
|
+
const base = resolveBaseUrl(args.baseUrl ? String(args.baseUrl) : void 0);
|
|
1597
|
+
const apiKey = process.env.KYNVER_API_KEY;
|
|
1598
|
+
const headers = { "Content-Type": "application/json" };
|
|
1599
|
+
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
1600
|
+
const url = `${base}/api/agent-os/${encodeURIComponent(slug)}/plans/${encodeURIComponent(planId)}/verify`;
|
|
1601
|
+
const res = await fetch(url, {
|
|
1602
|
+
method: "POST",
|
|
1603
|
+
headers,
|
|
1604
|
+
body: JSON.stringify({
|
|
1605
|
+
worktreePath: args.worktree ? String(args.worktree) : void 0,
|
|
1606
|
+
taskId: args.task ? String(args.task) : void 0,
|
|
1607
|
+
humanOverride: args.humanOverride === true || args.humanOverride === "true"
|
|
1608
|
+
})
|
|
1609
|
+
});
|
|
1610
|
+
const text = await res.text();
|
|
1611
|
+
let parsed = null;
|
|
1612
|
+
try {
|
|
1613
|
+
parsed = JSON.parse(text);
|
|
1614
|
+
} catch {
|
|
1615
|
+
parsed = text;
|
|
1616
|
+
}
|
|
1617
|
+
if (!res.ok) {
|
|
1618
|
+
console.error(JSON.stringify({ httpStatus: res.status, response: parsed }, null, 2));
|
|
1619
|
+
process.exit(1);
|
|
1620
|
+
}
|
|
1621
|
+
console.log(JSON.stringify(parsed, null, 2));
|
|
1622
|
+
}
|
|
1623
|
+
|
|
1516
1624
|
// src/cli.ts
|
|
1517
1625
|
function isHelpFlag(arg) {
|
|
1518
1626
|
return arg === "help" || arg === "--help" || arg === "-h";
|
|
@@ -1539,7 +1647,9 @@ function usage(code = 0) {
|
|
|
1539
1647
|
" kynver worker status --run RUN_ID --name worker",
|
|
1540
1648
|
" kynver worker tail --run RUN_ID --name worker [--lines 40] [--raw]",
|
|
1541
1649
|
" kynver worker stop --run RUN_ID --name worker",
|
|
1542
|
-
" kynver worker complete --run RUN_ID --name worker [--agent-os-id AOS_ID] [--task-id TASK_ID] [--base-url URL] [--secret SECRET]"
|
|
1650
|
+
" kynver worker complete --run RUN_ID --name worker [--agent-os-id AOS_ID] [--task-id TASK_ID] [--base-url URL] [--secret SECRET]",
|
|
1651
|
+
" 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]",
|
|
1652
|
+
" kynver plan verify --plan PLAN_ID [--worktree PATH] [--task TASK_ID] [--human-override]"
|
|
1543
1653
|
].join("\n")
|
|
1544
1654
|
);
|
|
1545
1655
|
process.exit(code);
|
|
@@ -1549,7 +1659,7 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1549
1659
|
const scope = argv.shift();
|
|
1550
1660
|
let action;
|
|
1551
1661
|
let rest;
|
|
1552
|
-
if (scope === "run" || scope === "worker") {
|
|
1662
|
+
if (scope === "run" || scope === "worker" || scope === "plan") {
|
|
1553
1663
|
action = argv.shift();
|
|
1554
1664
|
rest = argv;
|
|
1555
1665
|
} else {
|
|
@@ -1562,6 +1672,8 @@ async function main(argv = process.argv.slice(2)) {
|
|
|
1562
1672
|
if (scope === "login") return void await runLogin(args);
|
|
1563
1673
|
if (scope === "setup") return void await runSetup(args);
|
|
1564
1674
|
if (scope === "daemon") return void await runDaemon(args);
|
|
1675
|
+
if (scope === "plan" && action === "progress") return void await emitPlanProgress(args);
|
|
1676
|
+
if (scope === "plan" && action === "verify") return void await verifyPlan(args);
|
|
1565
1677
|
if (scope === "run" && action === "create") return createRun(args);
|
|
1566
1678
|
if (scope === "run" && action === "list") return listRuns();
|
|
1567
1679
|
if (scope === "run" && action === "status") return runStatus(args);
|