@rulvar/cli 1.46.0 → 1.47.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/cli.js +1 -1
- package/dist/index.js +11 -9
- package/dist/{io-BXU6hEnw.js → io-BK1hP3Od.js} +70 -3
- package/package.json +7 -7
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { _ as looksLikeFile, a as resumeCommand, c as driveRun, d as attachProgress, f as renderEventLine, g as loadWorkflowModule, h as loadCliConfig, i as inspectCommand, l as reportOutcome, m as assembleEngine, n as HELP, o as runCommand, p as DEFAULT_STORE_DIR, r as runCli, s as runsLsCommand, t as processIo, u as strictExitCode } from "./io-
|
|
1
|
+
import { _ as looksLikeFile, a as resumeCommand, c as driveRun, d as attachProgress, f as renderEventLine, g as loadWorkflowModule, h as loadCliConfig, i as inspectCommand, l as reportOutcome, m as assembleEngine, n as HELP, o as runCommand, p as DEFAULT_STORE_DIR, r as runCli, s as runsLsCommand, t as processIo, u as strictExitCode } from "./io-BK1hP3Od.js";
|
|
2
2
|
import { ConfigError, InvalidResolutionError, JournalCompatibilityError, LeaseHeldError, Replayer, RulvarError, buildDeriverRegistry, costReportFromJournal, maskSecrets, normalizeEntry, readRunMeta, scanJournalCompatibility, validateSchemaSpec } from "@rulvar/core";
|
|
3
3
|
//#region src/server.ts
|
|
4
4
|
/**
|
|
@@ -381,14 +381,16 @@ function createServer(options) {
|
|
|
381
381
|
}
|
|
382
382
|
const outcome = await run.handle.resolveExternal(key, value);
|
|
383
383
|
let resumed = false;
|
|
384
|
-
if (outcome.applied &&
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
384
|
+
if (outcome.applied && outcome.woke !== true) {
|
|
385
|
+
if ((settledSuspended ? run.outcome : await run.handle.result).status === "suspended") {
|
|
386
|
+
const workflow = workflows[run.workflowName];
|
|
387
|
+
if (workflow === void 0) return json(409, { error: {
|
|
388
|
+
code: "config",
|
|
389
|
+
message: `resolution applied, but workflow '${run.workflowName}' is no longer registered; resume it from a worker or a process with the registration`
|
|
390
|
+
} });
|
|
391
|
+
attach(run, engine.resume(run.runId, workflow, { args: run.args }));
|
|
392
|
+
resumed = true;
|
|
393
|
+
}
|
|
392
394
|
}
|
|
393
395
|
return json(200, {
|
|
394
396
|
...outcome,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConfigError, FileModelKnowledgeStore, INBOX_PROPOSAL_TTL_DAYS, JsonlFileStore, claimExpired, claimExpiry, compilePermissionPreset, costReportFromJournal, createEngine, hashRunArgs, parseModelRef, priceUsdOf, proposalStatement, readRunMeta, remeasureQueue, resolvePricing, runProfile, sanitizeTerminalText } from "@rulvar/core";
|
|
1
|
+
import { ConfigError, FileModelKnowledgeStore, INBOX_PROPOSAL_TTL_DAYS, JsonlFileStore, LeaseHeldError, auditRuns, claimExpired, claimExpiry, compilePermissionPreset, costReportFromJournal, createEngine, hashRunArgs, parseModelRef, priceUsdOf, proposalStatement, readRunMeta, reconcileRunMeta, remeasureQueue, resolvePricing, runProfile, sanitizeTerminalText } from "@rulvar/core";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { existsSync, statSync } from "node:fs";
|
|
4
4
|
import { pathToFileURL } from "node:url";
|
|
@@ -443,6 +443,11 @@ const GRAMMAR = {
|
|
|
443
443
|
flags: [STORE],
|
|
444
444
|
note: "(no aliases in v1)"
|
|
445
445
|
},
|
|
446
|
+
"runs audit": {
|
|
447
|
+
command: "runs audit",
|
|
448
|
+
positionals: [],
|
|
449
|
+
flags: [STORE, { name: "repair" }]
|
|
450
|
+
},
|
|
446
451
|
inspect: {
|
|
447
452
|
command: "inspect",
|
|
448
453
|
positionals: ["<runId>"],
|
|
@@ -514,6 +519,8 @@ const GRAMMAR = {
|
|
|
514
519
|
};
|
|
515
520
|
/** The kb dispatch line: subcommands carry their own grammar entries. */
|
|
516
521
|
const KB_FAMILY_USAGE = "usage: rulvar kb <list | inbox | gate | sweep> (no aliases in v1)";
|
|
522
|
+
/** The runs dispatch line: subcommands carry their own grammar entries. */
|
|
523
|
+
const RUNS_FAMILY_USAGE = "usage: rulvar runs <ls | audit> (no aliases in v1)";
|
|
517
524
|
function renderFlags(flags) {
|
|
518
525
|
const tokens = [];
|
|
519
526
|
const renderedGroups = /* @__PURE__ */ new Set();
|
|
@@ -554,6 +561,7 @@ function helpCommandLines() {
|
|
|
554
561
|
GRAMMAR.run,
|
|
555
562
|
GRAMMAR.resume,
|
|
556
563
|
GRAMMAR["runs ls"],
|
|
564
|
+
GRAMMAR["runs audit"],
|
|
557
565
|
GRAMMAR.inspect,
|
|
558
566
|
GRAMMAR.plan
|
|
559
567
|
];
|
|
@@ -854,6 +862,60 @@ async function resumeCommand(argv, context) {
|
|
|
854
862
|
const base = reportOutcome(outcome, context.io);
|
|
855
863
|
return parsed.values.strict === true ? strictExitCode(outcome, base, context.io) : base;
|
|
856
864
|
}
|
|
865
|
+
/**
|
|
866
|
+
* The stranded run probe and reconciler (fenced run state RFC, phase
|
|
867
|
+
* 3): audits every run the catalog lists against its journal, prints
|
|
868
|
+
* the divergences worker sweeps can never see, and with --repair
|
|
869
|
+
* rewrites the sound ones from the journal (under a brief lease when
|
|
870
|
+
* the store is leasable, so a live owner is never raced). Exit 0 when
|
|
871
|
+
* the catalog ends clean; exit 1 while any divergence remains.
|
|
872
|
+
*/
|
|
873
|
+
async function runsAuditCommand(argv, context) {
|
|
874
|
+
const parsed = parseCommand(GRAMMAR["runs audit"], argv);
|
|
875
|
+
const store = parsed.values.store;
|
|
876
|
+
const repair = parsed.values.repair === true;
|
|
877
|
+
const assembled = assembleEngine({
|
|
878
|
+
config: await loadCliConfig(context.cwd),
|
|
879
|
+
...store === void 0 ? {} : { storePath: store },
|
|
880
|
+
cwd: context.cwd
|
|
881
|
+
});
|
|
882
|
+
const audits = await auditRuns(assembled.store);
|
|
883
|
+
if (audits.length === 0) {
|
|
884
|
+
context.io.err("every run is consistent with its journal");
|
|
885
|
+
return 0;
|
|
886
|
+
}
|
|
887
|
+
let remaining = 0;
|
|
888
|
+
for (const audit of audits) {
|
|
889
|
+
const line = `${audit.runId} ${audit.verdict}: ${audit.reason}`;
|
|
890
|
+
if (!repair || audit.repairTo === void 0) {
|
|
891
|
+
context.io.out(sanitizeTerminalText(line));
|
|
892
|
+
remaining += 1;
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
const leasable = assembled.store;
|
|
896
|
+
let lease;
|
|
897
|
+
if (typeof leasable.acquire === "function") try {
|
|
898
|
+
lease = await leasable.acquire(audit.runId, `runs-audit-${String(process.pid)}`);
|
|
899
|
+
} catch (thrown) {
|
|
900
|
+
if (thrown instanceof LeaseHeldError) {
|
|
901
|
+
context.io.out(sanitizeTerminalText(`${line} (leased by a live owner, skipped)`));
|
|
902
|
+
remaining += 1;
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
throw thrown;
|
|
906
|
+
}
|
|
907
|
+
try {
|
|
908
|
+
const result = await reconcileRunMeta(assembled.store, audit.runId, { ...lease === void 0 ? {} : { lease } });
|
|
909
|
+
const wrote = result.audit.repairTo;
|
|
910
|
+
context.io.out(sanitizeTerminalText(result.repaired ? `${line} (repaired to '${String(wrote)}')` : `${line} (not repaired)`));
|
|
911
|
+
if (!result.repaired) remaining += 1;
|
|
912
|
+
} finally {
|
|
913
|
+
if (lease !== void 0 && typeof leasable.release === "function") await leasable.release(lease);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
context.io.err(remaining === 0 ? "every divergence repaired" : `${String(remaining)} divergence(s) remain; suspect verdicts need an operator (https://docs.rulvar.com/contributing/rfc-fenced-run-state)`);
|
|
917
|
+
return remaining === 0 ? 0 : 1;
|
|
918
|
+
}
|
|
857
919
|
async function runsLsCommand(argv, context) {
|
|
858
920
|
const store = parseCommand(GRAMMAR["runs ls"], argv).values.store;
|
|
859
921
|
const metas = await assembleEngine({
|
|
@@ -1364,6 +1426,10 @@ Engine assembly: adapters, defaults, and the workflow registry come from
|
|
|
1364
1426
|
rulvar.config.mjs in the working directory (default export
|
|
1365
1427
|
{ engineOptions?, workflows? }) or from the workflow module's named
|
|
1366
1428
|
exports. --store selects the JsonlFileStore directory (default .rulvar).
|
|
1429
|
+
runs audit compares every run's meta row against its journal and names
|
|
1430
|
+
the divergences worker sweeps cannot see (a stranded run's terminal
|
|
1431
|
+
meta over live journal work); --repair rewrites the sound ones from
|
|
1432
|
+
the journal under a brief lease, exit 1 while any divergence remains.
|
|
1367
1433
|
plan asks the planner model (role plan) to write a workflow script,
|
|
1368
1434
|
lints and self-repairs it, then runs it in the worker sandbox; --dry-run
|
|
1369
1435
|
prints the accepted script without running. Both stages are paid runs
|
|
@@ -1394,8 +1460,9 @@ async function runCli(argv, options) {
|
|
|
1394
1460
|
case "resume": return await resumeCommand(rest, context);
|
|
1395
1461
|
case "runs": {
|
|
1396
1462
|
const [sub, ...subRest] = rest;
|
|
1397
|
-
if (sub
|
|
1398
|
-
return await
|
|
1463
|
+
if (sub === "ls") return await runsLsCommand(subRest, context);
|
|
1464
|
+
if (sub === "audit") return await runsAuditCommand(subRest, context);
|
|
1465
|
+
throw new ConfigError(RUNS_FAMILY_USAGE);
|
|
1399
1466
|
}
|
|
1400
1467
|
case "inspect": return await inspectCommand(rest, context);
|
|
1401
1468
|
case "plan": return await planCommand(rest, context);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rulvar/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.47.0",
|
|
4
4
|
"description": "Rulvar shell: run/resume/runs/inspect/plan/kb commands, TUI progress, createServer, createWorker, OTel exporter.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -22,17 +22,17 @@
|
|
|
22
22
|
"access": "public"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@rulvar/core": "1.
|
|
25
|
+
"@rulvar/core": "1.47.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.20.0",
|
|
29
29
|
"tsdown": "^0.22.3",
|
|
30
30
|
"typescript": "~6.0.3",
|
|
31
|
-
"@rulvar/testing": "1.
|
|
32
|
-
"@rulvar/
|
|
33
|
-
"@rulvar/
|
|
34
|
-
"@rulvar/evals": "1.
|
|
35
|
-
"@rulvar/
|
|
31
|
+
"@rulvar/testing": "1.47.0",
|
|
32
|
+
"@rulvar/plan": "1.47.0",
|
|
33
|
+
"@rulvar/store-sqlite": "1.47.0",
|
|
34
|
+
"@rulvar/evals": "1.47.0",
|
|
35
|
+
"@rulvar/planner": "1.47.0"
|
|
36
36
|
},
|
|
37
37
|
"bin": {
|
|
38
38
|
"rulvar": "./dist/cli.js"
|