@ai-dossier/cli 0.21.0 → 0.23.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.
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Per-issue token/cost aggregation over `runs.jsonl` (#524).
3
+ *
4
+ * `packages/sched` now writes one `runs.jsonl` entry per dispatch (`unit`
5
+ * set to `issue:<n>`) — this module is the read side: it groups those
6
+ * entries by issue and sums tokens/cost/duration, the number both the pilot
7
+ * and parity gate reports needed and had to approximate from agents'
8
+ * self-reported numbers instead. Pure and dependency-free — no filesystem,
9
+ * no `gh` — so the arithmetic is unit-testable against fixture entries; the
10
+ * command layer (`cli/src/commands/sched.ts`) only reads `runs.jsonl` and
11
+ * renders what this returns.
12
+ */
13
+ import type { RunLogEntry } from '@ai-dossier/core';
14
+ import { issueOfUnit } from '@ai-dossier/sched';
15
+ /**
16
+ * `issue:<n>` → `<n>`; null for anything else (a batch unit, or no unit at
17
+ * all). Re-exported from `@ai-dossier/sched` — that package is both the
18
+ * writer of the `unit` correlation key and the pre-existing owner of this
19
+ * exact parse (`packages/sched/src/journal.ts`); a second, independently
20
+ * maintained regex here was the same class of drift #524 exists to close.
21
+ */
22
+ export { issueOfUnit };
23
+ /** One issue's aggregated dispatch cost. */
24
+ export interface IssueCost {
25
+ issue: number;
26
+ /** Number of runs.jsonl entries (dispatches) attributed to this issue. */
27
+ runs: number;
28
+ /** Null when NO entry for this issue reported the field — never a fabricated 0. */
29
+ input_tokens: number | null;
30
+ output_tokens: number | null;
31
+ cache_creation_tokens: number | null;
32
+ cache_read_tokens: number | null;
33
+ total_cost_usd: number | null;
34
+ duration_ms: number | null;
35
+ }
36
+ /** The whole cohort: per-issue rows plus a totals row. */
37
+ export interface SchedCostReport {
38
+ issues: IssueCost[];
39
+ totals: Omit<IssueCost, 'issue'>;
40
+ }
41
+ /**
42
+ * Build the per-issue cost report from already-read `runs.jsonl` entries.
43
+ *
44
+ * Only entries with an `issue:<n>` `unit` are considered — ordinary
45
+ * `ai-dossier run` entries (no `unit`) and batch entries (`batch:<id>`, not
46
+ * yet dispatched by the engine — see `packages/sched/README.md`'s
47
+ * dispatch-engine section, "Only `issue:<n>` units are dispatched today") are
48
+ * excluded. `issues`, when given, restricts the report to that set (and
49
+ * includes a zero-run row for any issue with no matching entries, so an
50
+ * operator can tell "no cost recorded" from "not asked about"); duplicates in
51
+ * it are collapsed, so an issue cannot be counted twice into `totals`.
52
+ */
53
+ export declare function buildSchedCostReport(entries: RunLogEntry[], issues?: readonly number[]): SchedCostReport;
54
+ //# sourceMappingURL=sched-run-stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sched-run-stats.d.ts","sourceRoot":"","sources":["../src/sched-run-stats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD;;;;;;GAMG;AACH,OAAO,EAAE,WAAW,EAAE,CAAC;AAsBvB,4CAA4C;AAC5C,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;CAClC;AAuBD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,EAAE,EACtB,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,GACzB,eAAe,CAejB"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * Per-issue token/cost aggregation over `runs.jsonl` (#524).
4
+ *
5
+ * `packages/sched` now writes one `runs.jsonl` entry per dispatch (`unit`
6
+ * set to `issue:<n>`) — this module is the read side: it groups those
7
+ * entries by issue and sums tokens/cost/duration, the number both the pilot
8
+ * and parity gate reports needed and had to approximate from agents'
9
+ * self-reported numbers instead. Pure and dependency-free — no filesystem,
10
+ * no `gh` — so the arithmetic is unit-testable against fixture entries; the
11
+ * command layer (`cli/src/commands/sched.ts`) only reads `runs.jsonl` and
12
+ * renders what this returns.
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.issueOfUnit = void 0;
16
+ exports.buildSchedCostReport = buildSchedCostReport;
17
+ const sched_1 = require("@ai-dossier/sched");
18
+ Object.defineProperty(exports, "issueOfUnit", { enumerable: true, get: function () { return sched_1.issueOfUnit; } });
19
+ /** Sum a nullable numeric field across entries, tracking whether any entry actually reported it. */
20
+ function sumField(entries, field) {
21
+ let total = 0;
22
+ let samples = 0;
23
+ for (const entry of entries) {
24
+ const value = entry[field];
25
+ // A non-finite RUNNING TOTAL would render as `-` and blank the whole
26
+ // column — including the TOTAL row — hiding every legitimate run beside
27
+ // it. Skip the addition rather than poisoning the cohort (#524 review).
28
+ if (typeof value === 'number' && Number.isFinite(value) && Number.isFinite(total + value)) {
29
+ total += value;
30
+ samples += 1;
31
+ }
32
+ }
33
+ return { total, samples };
34
+ }
35
+ /** The summable `IssueCost` fields, in table-column order. */
36
+ const SUM_FIELDS = [
37
+ 'input_tokens',
38
+ 'output_tokens',
39
+ 'cache_creation_tokens',
40
+ 'cache_read_tokens',
41
+ 'total_cost_usd',
42
+ 'duration_ms',
43
+ ];
44
+ /** Sum every `SUM_FIELDS` entry across `entries` — the issue-less half of one row. */
45
+ function aggregate(entries) {
46
+ const runs = entries.length;
47
+ const totals = {};
48
+ for (const field of SUM_FIELDS) {
49
+ const { total, samples } = sumField(entries, field);
50
+ totals[field] = samples > 0 ? total : null;
51
+ }
52
+ return { runs, ...totals };
53
+ }
54
+ /**
55
+ * Build the per-issue cost report from already-read `runs.jsonl` entries.
56
+ *
57
+ * Only entries with an `issue:<n>` `unit` are considered — ordinary
58
+ * `ai-dossier run` entries (no `unit`) and batch entries (`batch:<id>`, not
59
+ * yet dispatched by the engine — see `packages/sched/README.md`'s
60
+ * dispatch-engine section, "Only `issue:<n>` units are dispatched today") are
61
+ * excluded. `issues`, when given, restricts the report to that set (and
62
+ * includes a zero-run row for any issue with no matching entries, so an
63
+ * operator can tell "no cost recorded" from "not asked about"); duplicates in
64
+ * it are collapsed, so an issue cannot be counted twice into `totals`.
65
+ */
66
+ function buildSchedCostReport(entries, issues) {
67
+ const byIssue = new Map();
68
+ for (const entry of entries) {
69
+ const issue = (0, sched_1.issueOfUnit)(entry.unit);
70
+ if (issue === null)
71
+ continue;
72
+ const list = byIssue.get(issue);
73
+ if (list)
74
+ list.push(entry);
75
+ else
76
+ byIssue.set(issue, [entry]);
77
+ }
78
+ const selected = issues ? [...new Set(issues)] : [...byIssue.keys()].sort((a, b) => a - b);
79
+ const rows = selected.map((issue) => ({ issue, ...aggregate(byIssue.get(issue) ?? []) }));
80
+ const totals = aggregate(selected.flatMap((issue) => byIssue.get(issue) ?? []));
81
+ return { issues: rows, totals };
82
+ }
83
+ //# sourceMappingURL=sched-run-stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sched-run-stats.js","sourceRoot":"","sources":["../src/sched-run-stats.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-dossier/cli",
3
- "version": "0.21.0",
3
+ "version": "0.23.0",
4
4
  "description": "Create, verify, sign, publish, and run dossiers — portable, signed, versioned skills for any LLM tool. The dossier ⇄ Claude Code skill bridge (install-skill / skill-export).",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {
@@ -53,8 +53,8 @@
53
53
  "registry": "https://registry.npmjs.org"
54
54
  },
55
55
  "dependencies": {
56
- "@ai-dossier/core": "^1.4.1",
57
- "@ai-dossier/sched": "^0.8.0",
56
+ "@ai-dossier/core": "^1.5.0",
57
+ "@ai-dossier/sched": "^0.11.0",
58
58
  "commander": "^12.1.0",
59
59
  "yaml": "^2.8.3"
60
60
  },