@rulvar/cli 1.243.0 → 1.245.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 CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { r as runCli, t as processIo } from "./io-CMAEYzZR.js";
2
+ import { r as runCli, t as processIo } from "./io-DiVKnW2O.js";
3
3
  import { sanitizeTerminalText } from "@rulvar/core";
4
4
  import { inspect } from "node:util";
5
5
  //#region src/cli.ts
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as assembleEngine, a as inspectCommand, b as looksLikeFile, c as resumeCommand, d as driveRun, f as reportOutcome, g as DEFAULT_STORE_DIR, h as renderEventLine, i as costAuditCommand, l as runCommand, m as attachProgress, n as HELP, o as invoiceCommand, p as strictExitCode, r as runCli, s as preflightCommand, t as processIo, u as runsLsCommand, v as loadCliConfig, y as loadWorkflowModule } from "./io-CMAEYzZR.js";
1
+ import { _ as assembleEngine, a as inspectCommand, b as looksLikeFile, c as resumeCommand, d as driveRun, f as reportOutcome, g as DEFAULT_STORE_DIR, h as renderEventLine, i as costAuditCommand, l as runCommand, m as attachProgress, n as HELP, o as invoiceCommand, p as strictExitCode, r as runCli, s as preflightCommand, t as processIo, u as runsLsCommand, v as loadCliConfig, y as loadWorkflowModule } from "./io-DiVKnW2O.js";
2
2
  import { ConfigError, JournalCompatibilityError, LeaseHeldError, Replayer, RulvarError, buildDeriverRegistry, compileSecretMasker, costReportFromJournal, journalPricingSnapshot, maskSecrets, normalizeEntry, persistedTerminalEnvelope, readRunMeta, scanJournalCompatibility, validateDetachedResolution } from "@rulvar/core";
3
3
  //#region src/server.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { ConfigError, FileModelKnowledgeStore, INBOX_PROPOSAL_TTL_DAYS, JsonlFileStore, LeaseHeldError, auditRuns, childRostersFromJournal, claimCoverageOf, claimExpired, claimExpiry, compilePermissionPreset, costReportFromJournal, createEngine, hashRunArgs, hashRunOutput, invoiceFromJournal, journalPricingSnapshot, lastRunSettle, logicalRunTelemetry, parseModelRef, preflightEstimate, priceUsdOf, proposalStatement, readRunMeta, reconcileRunMeta, remeasureQueue, resolvePricing, runProfile, sanitizeTerminalText, toolCalibrationFromJournal } from "@rulvar/core";
1
+ import { ConfigError, FileModelKnowledgeStore, INBOX_PROPOSAL_TTL_DAYS, JsonlFileStore, LeaseHeldError, auditRuns, childRostersFromJournal, claimCoverageOf, claimExpired, claimExpiry, compilePermissionPreset, costReportFromJournal, createEngine, hashRunArgs, hashRunOutput, invoiceFromJournal, journalPricingSnapshot, lastRunSettle, logicalRunTelemetry, parseModelRef, preflightEstimate, priceUsdOf, proposalStatement, readRunMeta, reconcileRunMeta, remeasureQueue, repairLedgerFromJournal, resolvePricing, runProfile, sanitizeTerminalText, toolCalibrationFromJournal } 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";
@@ -1481,8 +1481,31 @@ function auditJournalEntries(entries, basePriceUsd) {
1481
1481
  failed: checks.filter((check) => !check.pass)
1482
1482
  };
1483
1483
  }
1484
+ /**
1485
+ * The per-agentType cut of the invoice rows (RV3906): in dynamic runs
1486
+ * byScope nests every orchestrator spawn under one `agent:<seq>`
1487
+ * bucket, so this is the per-child money surface. Rows journaled
1488
+ * before the field ride the 'unknown' bucket, the fold vocabulary.
1489
+ * Returns undefined when NO row names a type, so pre-RV3906 journals
1490
+ * render byte for byte in both output forms.
1491
+ */
1492
+ function invoiceByAgentType(rows) {
1493
+ if (!rows.some((row) => row.agentType !== void 0)) return;
1494
+ const cut = {};
1495
+ for (const row of rows) {
1496
+ const key = row.agentType ?? "unknown";
1497
+ const bucket = cut[key] ??= {
1498
+ usd: 0,
1499
+ rows: 0
1500
+ };
1501
+ bucket.usd += row.usd ?? 0;
1502
+ bucket.rows += 1;
1503
+ }
1504
+ return cut;
1505
+ }
1484
1506
  /** The one JSON shape of a run's audit, shared by both command forms. */
1485
- function costAuditRunJson(runId, audit) {
1507
+ function costAuditRunJson(runId, audit, repairs) {
1508
+ const byAgentType = invoiceByAgentType(audit.invoice.rows);
1486
1509
  return {
1487
1510
  runId,
1488
1511
  verdict: audit.failed.length === 0 ? "one-denominator" : "divergent",
@@ -1495,8 +1518,11 @@ function costAuditRunJson(runId, audit) {
1495
1518
  totalUsd: audit.invoice.totalUsd,
1496
1519
  rows: audit.invoice.rows.length,
1497
1520
  wireRequests: audit.invoice.cardinality.wireRequests,
1498
- ...audit.invoice.orphanedReceipts === void 0 ? {} : { orphanedReceipts: audit.invoice.orphanedReceipts }
1521
+ ...byAgentType === void 0 ? {} : { byAgentType },
1522
+ ...audit.invoice.orphanedReceipts === void 0 ? {} : { orphanedReceipts: audit.invoice.orphanedReceipts },
1523
+ ...audit.invoice.openIntents === void 0 ? {} : { openIntents: audit.invoice.openIntents }
1499
1524
  },
1525
+ ...repairs === void 0 || repairs.total === 0 ? {} : { repairs },
1500
1526
  checks: audit.checks
1501
1527
  };
1502
1528
  }
@@ -1543,14 +1569,32 @@ async function costAuditCommand(argv, context) {
1543
1569
  });
1544
1570
  if (runId !== void 0) {
1545
1571
  if (await readRunMeta(assembled.store, runId) === void 0) throw new ConfigError(`run '${runId}' not found in the store`);
1546
- const audit = auditJournalEntries(await assembled.store.load(runId), assembled.priceUsd);
1572
+ const entries = await assembled.store.load(runId);
1573
+ const audit = auditJournalEntries(entries, assembled.priceUsd);
1574
+ const repairs = repairLedgerFromJournal(entries, (servedBy, usage) => assembled.priceUsd(servedBy, usage));
1547
1575
  if (json) {
1548
- context.io.out(JSON.stringify(costAuditRunJson(runId, audit), null, 2));
1576
+ context.io.out(JSON.stringify(costAuditRunJson(runId, audit, repairs), null, 2));
1549
1577
  return audit.failed.length === 0 ? 0 : 1;
1550
1578
  }
1551
1579
  context.io.out(`run ${runId}: cost audit (${audit.failed.length === 0 ? "one denominator" : "DIVERGENT"})`);
1552
1580
  context.io.out(`settled: gross $${audit.report.grossUsd.toFixed(4)} | net $${audit.report.totalUsd.toFixed(4)} | wires ${String(audit.report.wireRequests ?? "absent")}`);
1553
1581
  context.io.out(`invoice: total $${audit.invoice.totalUsd.toFixed(4)} | rows ${String(audit.invoice.rows.length)} | wires ${String(audit.invoice.cardinality.wireRequests)}`);
1582
+ const byAgentType = invoiceByAgentType(audit.invoice.rows);
1583
+ if (byAgentType !== void 0) {
1584
+ const cutLine = Object.entries(byAgentType).sort(([, a], [, b]) => b.usd - a.usd).map(([type, bucket]) => `${type} $${bucket.usd.toFixed(4)} (${String(bucket.rows)} rows)`).join(" | ");
1585
+ context.io.out(`by agentType: ${cutLine}`);
1586
+ }
1587
+ if (repairs.total > 0) {
1588
+ const priced = repairs.rounds.filter((row) => row.costUsd !== void 0);
1589
+ const pricedUsd = priced.reduce((sum, row) => sum + (row.costUsd ?? 0), 0);
1590
+ context.io.out(`repairs: total ${String(repairs.total)} | draft ${String(repairs.draft)} | composition ${String(repairs.composition)} | semantic ${String(repairs.semantic)}` + (priced.length === 0 ? "" : ` | priced $${pricedUsd.toFixed(4)} over ${String(priced.length)} repair wire(s)`) + (repairs.unstagedVerdicts === 0 ? "" : ` | ${String(repairs.unstagedVerdicts)} unstaged verdict(s): the journal predates the ledger, counts are a floor`));
1591
+ for (const row of repairs.rounds) context.io.out(` ${row.stage} @${String(row.seq)} | validators ${row.failedValidators.join(", ") || "(none)"}` + (row.sections === void 0 ? "" : ` | sections ${row.sections.join(", ")}`) + (row.wireRef === void 0 ? "" : ` | wire @${String(row.wireRef)}`) + (row.costUsd === void 0 ? "" : ` | ${usdOf(row.costUsd)}`));
1592
+ }
1593
+ const openIntents = audit.invoice.openIntents;
1594
+ if (openIntents !== void 0) {
1595
+ context.io.out(`open intents: ${String(openIntents.count)} wire(s) with unknown outcome (RV4006): an intent was journaled before dispatch and neither a receipt nor a terminal record covers it; reconcile against the provider statement before retrying`);
1596
+ for (const row of openIntents.rows) context.io.out(` agent ${String(row.agentRef)} (${row.scope}) | ordinal ${String(row.ordinal)} attempt ${String(row.attempt)} | ${row.servedBy}` + (row.requestFingerprint === void 0 ? "" : ` | fingerprint ${row.requestFingerprint.slice(0, 16)}…`));
1597
+ }
1554
1598
  const orphaned = audit.invoice.orphanedReceipts;
1555
1599
  if (orphaned !== void 0) {
1556
1600
  context.io.out(`orphaned receipts: $${orphaned.usd.toFixed(4)} | wires ${String(orphaned.wireRequests)} | paid wires the settled terminal does not cover (RV3405), outside the settled totals`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/cli",
3
- "version": "1.243.0",
3
+ "version": "1.245.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.243.0"
25
+ "@rulvar/core": "1.245.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/node": "^22.20.1",
29
29
  "tsdown": "^0.22.14",
30
30
  "typescript": "~6.0.3",
31
- "@rulvar/testing": "1.243.0",
32
- "@rulvar/store-sqlite": "1.243.0",
33
- "@rulvar/planner": "1.243.0",
34
- "@rulvar/plan": "1.243.0",
35
- "@rulvar/evals": "1.243.0"
31
+ "@rulvar/testing": "1.245.0",
32
+ "@rulvar/plan": "1.245.0",
33
+ "@rulvar/planner": "1.245.0",
34
+ "@rulvar/evals": "1.245.0",
35
+ "@rulvar/store-sqlite": "1.245.0"
36
36
  },
37
37
  "bin": {
38
38
  "rulvar": "./dist/cli.js"