@attalabs/vinaya 0.21.0 → 0.22.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/README.md +3 -2
- package/aeg-root/enforcement.md +2 -1
- package/aeg-root/roles/archivist.md +1 -1
- package/aeg-root/roles/planner.md +1 -1
- package/aeg-root/templates/pr-report-template.md +2 -0
- package/aeg-root/tranche-model.md +3 -3
- package/dist/checks/bin/check-body-bare-digits.js +115 -9
- package/dist/checks/bin/check-branch-topology.js +111 -5
- package/dist/checks/bin/check-brief-shape.js +111 -5
- package/dist/checks/bin/check-changeset-coverage.js +113 -7
- package/dist/checks/bin/check-closes-n.js +111 -5
- package/dist/checks/bin/check-coherence.js +115 -9
- package/dist/checks/bin/check-dead-branch-push.js +111 -5
- package/dist/checks/bin/check-dispatch-readiness.js +116 -10
- package/dist/checks/bin/check-doc-coverage-push.js +116 -10
- package/dist/checks/bin/check-doc-coverage.js +116 -10
- package/dist/checks/bin/check-doctrine-portability.js +115 -9
- package/dist/checks/bin/check-evidence-fresh.js +111 -5
- package/dist/checks/bin/check-first-push-dispatch.js +113 -7
- package/dist/checks/bin/check-issue-assignment.js +111 -5
- package/dist/checks/bin/check-main-branch-refusal.js +111 -5
- package/dist/checks/bin/check-no-disk-state.js +111 -5
- package/dist/checks/bin/check-quoted-command.js +121 -12
- package/dist/checks/bin/check-reader-resolvable-prose.js +152 -20
- package/dist/checks/bin/check-registry-gates.js +131 -10
- package/dist/checks/bin/check-retired-vocabulary.js +144 -12
- package/dist/checks/bin/check-review-gate.js +113 -7
- package/dist/checks/bin/check-single-plan-pr.js +111 -5
- package/dist/checks/bin/check-test-plan.js +111 -5
- package/dist/checks/bin/check-token-collection-wired.js +113 -7
- package/dist/checks/bin/check-token-report.js +4096 -0
- package/dist/checks/bin/check-workspace-escape.js +113 -7
- package/dist/index.js +177 -104
- package/package.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/BUILD_ID +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/build-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/prerender-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/backlog/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/[name]/tranches/[slug]/tasks/[taskId]/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/projects/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page/server-reference-manifest.json +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page.js.nft.json +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/app/studio/tranches/page_client-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/1q96_modules_@clerk_nextjs_dist_esm_app-router_client_keyless-creator-reader_0lom2js.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0053k9k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0112h-k._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__02c71kv._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/{[root-of-the-server]__0ozbaq0._.js → [root-of-the-server]__069-_41._.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0o771t1._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__0puovz5._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1hs0dcu._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/[root-of-the-server]__1wc4-ip._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_03x_w6q._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0gvm3og._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0lwxg63._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_0o54suy._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1-6rzip._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1mrtj0f._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/_1n0cnq-._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/apps_vinaya-studio_web_src_app_studio_06it6s-._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/node_modules_1vo08dj._.js +2 -2
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_animate_components_index_ts_186fje1._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_brutal_components_index_ts_0n_lcc4._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_retro_components_index_ts_0wvpm_z._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/chunks/ssr/packages_ui_libraries_retro_components_index_ts_1_cfi48._.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/middleware-build-manifest.js +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/server/pages/500.html +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.js +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/server/server-reference-manifest.json +3 -3
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/00pi8vhg8w6gi.js +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0r4i_ks9z02bw.js → 03q0q9n6-xah8.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0vc2u252q5q6o.js +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1k916ih3p4nsg.js → 13g16cu00g570.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1hufpuody6vjv.js +1 -0
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2hmannd4bjhzy.js → 1sfxfunirkcr6.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1t2kft7bxzuxn.js → 206ajg8f1a-_h.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1hfhxjy577l5d.js → 267o-tsrnuwnv.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{25kbt5k-xb2a5.js → 279qq4twinc97.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{112g08xpx3kro.js → 2ka8dg687auhj.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{0up5x3jg-cwov.js → 2rn89uwtf2lwc.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2_k6j1o9q5nn4.js → 37hnluhzj9bei.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{3mqu_uhluy19i.css → 3qc67qhcvbg0o.css} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{1yqs2zgvwa4p1.js → 3zugx9esh2x51.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/0_jnwbarv-cqk.js +0 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/1ybrihl5_aocy.js +0 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/3r5efmleneaco.js +0 -1
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → Fmyc42qzLwFcWWHLLNy-G}/_buildManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → Fmyc42qzLwFcWWHLLNy-G}/_clientMiddlewareManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{crNCHQ9uAgKOYC6DKkZma → Fmyc42qzLwFcWWHLLNy-G}/_ssgManifest.js +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/checks/bin/check-retired-vocabulary.ts
|
|
4
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
4
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync4, statSync } from "node:fs";
|
|
5
5
|
import { join as join5, resolve as resolve2 } from "node:path";
|
|
6
6
|
// ../../packages/aeg-core/src/gate-audience.ts
|
|
7
7
|
var GATE_AUDIENCE = {
|
|
@@ -1792,6 +1792,99 @@ var DERIVED_STATUSES = [
|
|
|
1792
1792
|
"incoherent"
|
|
1793
1793
|
];
|
|
1794
1794
|
var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
|
|
1795
|
+
// ../../packages/aeg-core/src/parse-ledger.ts
|
|
1796
|
+
function rowFromCells(cells) {
|
|
1797
|
+
if (cells.length < 7)
|
|
1798
|
+
return null;
|
|
1799
|
+
const phase = (cells[0] ?? "").trim();
|
|
1800
|
+
if (!phase)
|
|
1801
|
+
return null;
|
|
1802
|
+
return {
|
|
1803
|
+
phase,
|
|
1804
|
+
role: (cells[1] ?? "").trim(),
|
|
1805
|
+
agentModel: (cells[2] ?? "").trim(),
|
|
1806
|
+
tokensIn: parseIntCell(cells[3] ?? ""),
|
|
1807
|
+
tokensOut: parseIntCell(cells[4] ?? ""),
|
|
1808
|
+
cost: parseCostCell(cells[5] ?? ""),
|
|
1809
|
+
date: (cells[6] ?? "").trim()
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1812
|
+
function parseIntCell(cell) {
|
|
1813
|
+
const trimmed = cell.replace(/`/g, "").trim();
|
|
1814
|
+
if (!trimmed || isEmDashOrDash(trimmed))
|
|
1815
|
+
return null;
|
|
1816
|
+
const normalized = trimmed.replace(/[,_\s]/g, "");
|
|
1817
|
+
if (!/^-?\d+$/.test(normalized))
|
|
1818
|
+
return null;
|
|
1819
|
+
return Number(normalized);
|
|
1820
|
+
}
|
|
1821
|
+
function parseCostCell(cell) {
|
|
1822
|
+
const trimmed = cell.replace(/`/g, "").trim();
|
|
1823
|
+
if (!trimmed || isEmDashOrDash(trimmed))
|
|
1824
|
+
return null;
|
|
1825
|
+
const normalized = trimmed.replace(/^\$/, "").replace(/[,_\s]/g, "");
|
|
1826
|
+
if (!/^-?\d+(\.\d+)?$/.test(normalized))
|
|
1827
|
+
return null;
|
|
1828
|
+
return Number(normalized);
|
|
1829
|
+
}
|
|
1830
|
+
function isEmDashOrDash(s) {
|
|
1831
|
+
const t = s.trim();
|
|
1832
|
+
return t === "—" || t === "-" || t === "–";
|
|
1833
|
+
}
|
|
1834
|
+
// ../../packages/aeg-core/src/parse-token-report.ts
|
|
1835
|
+
var TOKEN_REPORT_HEADING = /^\s*(?:#{1,6}\s*Token report\s*|\*\*Token report\*\*)\s*$/i;
|
|
1836
|
+
var INLINE_FIELD_LIST = /Phase:\s*([^|]+?)\s*\|\s*Role:\s*([^|]+?)\s*\|\s*Agent\/Model:\s*([^|]+?)\s*\|\s*Tokens in:\s*([^|]+?)\s*\|\s*Tokens out:\s*([^|]+?)\s*\|\s*Cost:\s*([^|]+?)\s*\|\s*Date:\s*(.+?)\s*$/im;
|
|
1837
|
+
function parseTokenReportEntries(body) {
|
|
1838
|
+
const lines = body.split(/\r?\n/);
|
|
1839
|
+
const headingIdxs = [];
|
|
1840
|
+
lines.forEach((line, i) => {
|
|
1841
|
+
if (TOKEN_REPORT_HEADING.test(line))
|
|
1842
|
+
headingIdxs.push(i);
|
|
1843
|
+
});
|
|
1844
|
+
const out = [];
|
|
1845
|
+
for (let h = 0;h < headingIdxs.length; h++) {
|
|
1846
|
+
const start = headingIdxs[h] + 1;
|
|
1847
|
+
const end = h + 1 < headingIdxs.length ? headingIdxs[h + 1] : lines.length;
|
|
1848
|
+
const section = lines.slice(start, end).join(`
|
|
1849
|
+
`);
|
|
1850
|
+
const tableRows = parseTableSection(section);
|
|
1851
|
+
if (tableRows.length > 0) {
|
|
1852
|
+
out.push(...tableRows);
|
|
1853
|
+
continue;
|
|
1854
|
+
}
|
|
1855
|
+
const inlineRow = parseInlineFieldList(section);
|
|
1856
|
+
if (inlineRow)
|
|
1857
|
+
out.push(inlineRow);
|
|
1858
|
+
}
|
|
1859
|
+
return out;
|
|
1860
|
+
}
|
|
1861
|
+
function parseTableSection(section) {
|
|
1862
|
+
const lines = section.split(/\r?\n/);
|
|
1863
|
+
let i = 0;
|
|
1864
|
+
for (;i < lines.length; i++) {
|
|
1865
|
+
if ((lines[i] ?? "").trim().startsWith("|"))
|
|
1866
|
+
break;
|
|
1867
|
+
}
|
|
1868
|
+
if (i + 1 >= lines.length)
|
|
1869
|
+
return [];
|
|
1870
|
+
i += 2;
|
|
1871
|
+
const out = [];
|
|
1872
|
+
for (;i < lines.length; i++) {
|
|
1873
|
+
const trimmed = (lines[i] ?? "").trim();
|
|
1874
|
+
if (!trimmed.startsWith("|"))
|
|
1875
|
+
break;
|
|
1876
|
+
const row = rowFromCells(splitTableRow(trimmed));
|
|
1877
|
+
if (row)
|
|
1878
|
+
out.push(row);
|
|
1879
|
+
}
|
|
1880
|
+
return out;
|
|
1881
|
+
}
|
|
1882
|
+
function parseInlineFieldList(section) {
|
|
1883
|
+
const m = section.match(INLINE_FIELD_LIST);
|
|
1884
|
+
if (!m)
|
|
1885
|
+
return null;
|
|
1886
|
+
return rowFromCells([m[1], m[2], m[3], m[4], m[5], m[6], m[7]]);
|
|
1887
|
+
}
|
|
1795
1888
|
// ../../packages/aeg-core/src/report-tokens.ts
|
|
1796
1889
|
var DASH_LOOKALIKES = {
|
|
1797
1890
|
"-": "‑",
|
|
@@ -1800,6 +1893,7 @@ var DASH_LOOKALIKES = {
|
|
|
1800
1893
|
};
|
|
1801
1894
|
var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
|
|
1802
1895
|
// ../../packages/aeg-core/src/claude-code-transcript.ts
|
|
1896
|
+
import { createHash } from "node:crypto";
|
|
1803
1897
|
function summarizeTranscript(jsonl) {
|
|
1804
1898
|
const seen = new Set;
|
|
1805
1899
|
const components = {
|
|
@@ -1848,7 +1942,14 @@ function numberOr(value, fallback) {
|
|
|
1848
1942
|
function sanitizeKey(value) {
|
|
1849
1943
|
return value.replace(/[^A-Za-z0-9]+/g, "-");
|
|
1850
1944
|
}
|
|
1945
|
+
function collisionResistantKey(value) {
|
|
1946
|
+
const digest = createHash("sha256").update(value).digest("hex");
|
|
1947
|
+
return `${sanitizeKey(value)}-${digest}`;
|
|
1948
|
+
}
|
|
1851
1949
|
function transcriptPointerPath(projectDir, tmpDir) {
|
|
1950
|
+
return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
|
|
1951
|
+
}
|
|
1952
|
+
function legacyTranscriptPointerPath(projectDir, tmpDir) {
|
|
1852
1953
|
return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
|
|
1853
1954
|
}
|
|
1854
1955
|
function resolvePointer(explicitTranscriptPath, deps) {
|
|
@@ -1856,13 +1957,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
|
|
|
1856
1957
|
return { path: explicitTranscriptPath, corroborated: true };
|
|
1857
1958
|
const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
|
|
1858
1959
|
const tmpDir = deps.env.TMPDIR ?? "/tmp";
|
|
1859
|
-
const
|
|
1960
|
+
const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
|
|
1961
|
+
const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
|
|
1860
1962
|
const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
|
|
1861
|
-
|
|
1963
|
+
const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
|
|
1964
|
+
if (!pointerPath) {
|
|
1862
1965
|
return {
|
|
1863
1966
|
pointerExisted: false,
|
|
1864
1967
|
corroborated: false,
|
|
1865
|
-
error: `No transcript pointer at ${
|
|
1968
|
+
error: `No transcript pointer at ${primaryPointerPath} (nor its pre-migration name ${legacyPointerPath}) ` + "and no --transcript given. Either this repo installs no track-transcript.sh Stop hook (lacking one " + "is not a defect — name the transcript directly instead), or no session has completed a turn yet."
|
|
1866
1969
|
};
|
|
1867
1970
|
}
|
|
1868
1971
|
let contents;
|
|
@@ -1937,6 +2040,9 @@ function isTokenCollectionWiringBroken(capability) {
|
|
|
1937
2040
|
return false;
|
|
1938
2041
|
return capability.reason !== "no-transcript-resolved";
|
|
1939
2042
|
}
|
|
2043
|
+
// ../../packages/aeg-core/src/metering-io-guard.ts
|
|
2044
|
+
import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
|
|
2045
|
+
var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
|
|
1940
2046
|
// ../../packages/aeg-core/src/file-classify.ts
|
|
1941
2047
|
function isCodeFile(p) {
|
|
1942
2048
|
if (p.endsWith(".md"))
|
|
@@ -2143,7 +2249,7 @@ function overrideActive(opts) {
|
|
|
2143
2249
|
return false;
|
|
2144
2250
|
}
|
|
2145
2251
|
// ../../packages/aeg-core/src/premise-check.ts
|
|
2146
|
-
import { createHash } from "node:crypto";
|
|
2252
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
2147
2253
|
var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
|
|
2148
2254
|
function isPremiseHeader(line) {
|
|
2149
2255
|
const stripped = line.replace(/[*#]/g, "").trim();
|
|
@@ -2188,7 +2294,7 @@ function checkPremises(assertions, fileReader) {
|
|
|
2188
2294
|
} else if (a.kind === "absent" && content.includes(a.value)) {
|
|
2189
2295
|
failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
|
|
2190
2296
|
} else if (a.kind === "sha256") {
|
|
2191
|
-
const actual =
|
|
2297
|
+
const actual = createHash2("sha256").update(content).digest("hex");
|
|
2192
2298
|
if (actual !== a.value.toLowerCase()) {
|
|
2193
2299
|
failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
|
|
2194
2300
|
}
|
|
@@ -3915,7 +4021,7 @@ function findWorkspaceEscapes(files, knownPaths, workspaceDirs = DEFAULT_WORKSPA
|
|
|
3915
4021
|
return findings;
|
|
3916
4022
|
}
|
|
3917
4023
|
// src/commands/doctrine.ts
|
|
3918
|
-
import { existsSync as existsSync2, readdirSync, readFileSync } from "node:fs";
|
|
4024
|
+
import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync2 } from "node:fs";
|
|
3919
4025
|
import { dirname as dirname2, join as join2, sep } from "node:path";
|
|
3920
4026
|
import matter2 from "gray-matter";
|
|
3921
4027
|
|
|
@@ -3943,15 +4049,18 @@ function resolveDoctrineRoot(pkg = packageRoot(import.meta.url)) {
|
|
|
3943
4049
|
if (!pkg.split(sep).includes("node_modules"))
|
|
3944
4050
|
candidates.push(join2(dirname2(dirname2(pkg)), "aeg-root"));
|
|
3945
4051
|
for (const root of candidates) {
|
|
3946
|
-
if (
|
|
4052
|
+
if (hasDoctrineEntry(root))
|
|
3947
4053
|
return root;
|
|
3948
4054
|
}
|
|
3949
4055
|
return null;
|
|
3950
4056
|
}
|
|
4057
|
+
function hasDoctrineEntry(root) {
|
|
4058
|
+
return existsSync2(join2(root, ...ENTRY_SEGMENTS));
|
|
4059
|
+
}
|
|
3951
4060
|
|
|
3952
4061
|
// src/lib/config.ts
|
|
3953
4062
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
3954
|
-
import { existsSync as existsSync3, mkdirSync, readFileSync as
|
|
4063
|
+
import { existsSync as existsSync3, mkdirSync, readFileSync as readFileSync3, realpathSync, writeFileSync } from "node:fs";
|
|
3955
4064
|
import { homedir } from "node:os";
|
|
3956
4065
|
import { dirname as dirname3, join as join3, resolve } from "node:path";
|
|
3957
4066
|
import { z } from "zod";
|
|
@@ -4244,7 +4353,7 @@ function loadConfig() {
|
|
|
4244
4353
|
if (!path)
|
|
4245
4354
|
return null;
|
|
4246
4355
|
try {
|
|
4247
|
-
const raw = JSON.parse(
|
|
4356
|
+
const raw = JSON.parse(readFileSync3(path, "utf-8"));
|
|
4248
4357
|
return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
|
|
4249
4358
|
} catch {
|
|
4250
4359
|
return null;
|
|
@@ -4326,7 +4435,19 @@ function resolveChangedFiles(base = process.env.BASE_SHA || "origin/main") {
|
|
|
4326
4435
|
|
|
4327
4436
|
// src/checks/bin/check-retired-vocabulary.ts
|
|
4328
4437
|
var CHECK_NAME = "retired-vocabulary";
|
|
4329
|
-
|
|
4438
|
+
function resolveCheckDoctrineRoot() {
|
|
4439
|
+
const configured = loadConfig()?.proseGates?.doctrineRoot;
|
|
4440
|
+
if (configured !== undefined)
|
|
4441
|
+
return configured;
|
|
4442
|
+
const root = repoRoot();
|
|
4443
|
+
if (root !== null) {
|
|
4444
|
+
const candidate = join5(root, "aeg-root");
|
|
4445
|
+
if (hasDoctrineEntry(candidate))
|
|
4446
|
+
return candidate;
|
|
4447
|
+
}
|
|
4448
|
+
return resolveDoctrineRoot();
|
|
4449
|
+
}
|
|
4450
|
+
var DOCTRINE_ROOT = resolveCheckDoctrineRoot();
|
|
4330
4451
|
function isSweptFile(name) {
|
|
4331
4452
|
return /\.(md|ts|tsx|yml)$/.test(name) || name === "doc-owners" || name === "packages";
|
|
4332
4453
|
}
|
|
@@ -4356,9 +4477,20 @@ function collect(dir, out = []) {
|
|
|
4356
4477
|
return out;
|
|
4357
4478
|
}
|
|
4358
4479
|
function readAll(paths) {
|
|
4359
|
-
return paths.map((p) => ({ path: p, content:
|
|
4480
|
+
return paths.map((p) => ({ path: p, content: readFileSync4(p, "utf8") }));
|
|
4360
4481
|
}
|
|
4361
4482
|
function main() {
|
|
4483
|
+
if (DOCTRINE_ROOT === null) {
|
|
4484
|
+
console.log(`${CHECK_NAME}: doctrine root unresolvable — sweep did not run.`);
|
|
4485
|
+
emitCheckError({
|
|
4486
|
+
schema: CHECK_SCHEMA_VERSION,
|
|
4487
|
+
check: CHECK_NAME,
|
|
4488
|
+
severity: "error",
|
|
4489
|
+
message: "doctrine root unresolvable: no aeg-root found at the repo root under check, and no bundled copy found " + "relative to this package's own install.",
|
|
4490
|
+
agent_recovery_prompt: "Set proseGates.doctrineRoot in vinaya.config.json to the doctrine tree this repo actually uses, or " + "confirm aeg-root/ exists at the repo root (or that this package's own bundled aeg-root/ is present)."
|
|
4491
|
+
});
|
|
4492
|
+
process.exit(2);
|
|
4493
|
+
}
|
|
4362
4494
|
const paths = collect(DOCTRINE_ROOT);
|
|
4363
4495
|
const files = readAll(paths);
|
|
4364
4496
|
const findings = scanRetiredVocabulary(files);
|
|
@@ -1791,6 +1791,99 @@ var DERIVED_STATUSES = [
|
|
|
1791
1791
|
"incoherent"
|
|
1792
1792
|
];
|
|
1793
1793
|
var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
|
|
1794
|
+
// ../../packages/aeg-core/src/parse-ledger.ts
|
|
1795
|
+
function rowFromCells(cells) {
|
|
1796
|
+
if (cells.length < 7)
|
|
1797
|
+
return null;
|
|
1798
|
+
const phase = (cells[0] ?? "").trim();
|
|
1799
|
+
if (!phase)
|
|
1800
|
+
return null;
|
|
1801
|
+
return {
|
|
1802
|
+
phase,
|
|
1803
|
+
role: (cells[1] ?? "").trim(),
|
|
1804
|
+
agentModel: (cells[2] ?? "").trim(),
|
|
1805
|
+
tokensIn: parseIntCell(cells[3] ?? ""),
|
|
1806
|
+
tokensOut: parseIntCell(cells[4] ?? ""),
|
|
1807
|
+
cost: parseCostCell(cells[5] ?? ""),
|
|
1808
|
+
date: (cells[6] ?? "").trim()
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
function parseIntCell(cell) {
|
|
1812
|
+
const trimmed = cell.replace(/`/g, "").trim();
|
|
1813
|
+
if (!trimmed || isEmDashOrDash(trimmed))
|
|
1814
|
+
return null;
|
|
1815
|
+
const normalized = trimmed.replace(/[,_\s]/g, "");
|
|
1816
|
+
if (!/^-?\d+$/.test(normalized))
|
|
1817
|
+
return null;
|
|
1818
|
+
return Number(normalized);
|
|
1819
|
+
}
|
|
1820
|
+
function parseCostCell(cell) {
|
|
1821
|
+
const trimmed = cell.replace(/`/g, "").trim();
|
|
1822
|
+
if (!trimmed || isEmDashOrDash(trimmed))
|
|
1823
|
+
return null;
|
|
1824
|
+
const normalized = trimmed.replace(/^\$/, "").replace(/[,_\s]/g, "");
|
|
1825
|
+
if (!/^-?\d+(\.\d+)?$/.test(normalized))
|
|
1826
|
+
return null;
|
|
1827
|
+
return Number(normalized);
|
|
1828
|
+
}
|
|
1829
|
+
function isEmDashOrDash(s) {
|
|
1830
|
+
const t = s.trim();
|
|
1831
|
+
return t === "—" || t === "-" || t === "–";
|
|
1832
|
+
}
|
|
1833
|
+
// ../../packages/aeg-core/src/parse-token-report.ts
|
|
1834
|
+
var TOKEN_REPORT_HEADING = /^\s*(?:#{1,6}\s*Token report\s*|\*\*Token report\*\*)\s*$/i;
|
|
1835
|
+
var INLINE_FIELD_LIST = /Phase:\s*([^|]+?)\s*\|\s*Role:\s*([^|]+?)\s*\|\s*Agent\/Model:\s*([^|]+?)\s*\|\s*Tokens in:\s*([^|]+?)\s*\|\s*Tokens out:\s*([^|]+?)\s*\|\s*Cost:\s*([^|]+?)\s*\|\s*Date:\s*(.+?)\s*$/im;
|
|
1836
|
+
function parseTokenReportEntries(body) {
|
|
1837
|
+
const lines = body.split(/\r?\n/);
|
|
1838
|
+
const headingIdxs = [];
|
|
1839
|
+
lines.forEach((line, i) => {
|
|
1840
|
+
if (TOKEN_REPORT_HEADING.test(line))
|
|
1841
|
+
headingIdxs.push(i);
|
|
1842
|
+
});
|
|
1843
|
+
const out = [];
|
|
1844
|
+
for (let h = 0;h < headingIdxs.length; h++) {
|
|
1845
|
+
const start = headingIdxs[h] + 1;
|
|
1846
|
+
const end = h + 1 < headingIdxs.length ? headingIdxs[h + 1] : lines.length;
|
|
1847
|
+
const section = lines.slice(start, end).join(`
|
|
1848
|
+
`);
|
|
1849
|
+
const tableRows = parseTableSection(section);
|
|
1850
|
+
if (tableRows.length > 0) {
|
|
1851
|
+
out.push(...tableRows);
|
|
1852
|
+
continue;
|
|
1853
|
+
}
|
|
1854
|
+
const inlineRow = parseInlineFieldList(section);
|
|
1855
|
+
if (inlineRow)
|
|
1856
|
+
out.push(inlineRow);
|
|
1857
|
+
}
|
|
1858
|
+
return out;
|
|
1859
|
+
}
|
|
1860
|
+
function parseTableSection(section) {
|
|
1861
|
+
const lines = section.split(/\r?\n/);
|
|
1862
|
+
let i = 0;
|
|
1863
|
+
for (;i < lines.length; i++) {
|
|
1864
|
+
if ((lines[i] ?? "").trim().startsWith("|"))
|
|
1865
|
+
break;
|
|
1866
|
+
}
|
|
1867
|
+
if (i + 1 >= lines.length)
|
|
1868
|
+
return [];
|
|
1869
|
+
i += 2;
|
|
1870
|
+
const out = [];
|
|
1871
|
+
for (;i < lines.length; i++) {
|
|
1872
|
+
const trimmed = (lines[i] ?? "").trim();
|
|
1873
|
+
if (!trimmed.startsWith("|"))
|
|
1874
|
+
break;
|
|
1875
|
+
const row = rowFromCells(splitTableRow(trimmed));
|
|
1876
|
+
if (row)
|
|
1877
|
+
out.push(row);
|
|
1878
|
+
}
|
|
1879
|
+
return out;
|
|
1880
|
+
}
|
|
1881
|
+
function parseInlineFieldList(section) {
|
|
1882
|
+
const m = section.match(INLINE_FIELD_LIST);
|
|
1883
|
+
if (!m)
|
|
1884
|
+
return null;
|
|
1885
|
+
return rowFromCells([m[1], m[2], m[3], m[4], m[5], m[6], m[7]]);
|
|
1886
|
+
}
|
|
1794
1887
|
// ../../packages/aeg-core/src/report-tokens.ts
|
|
1795
1888
|
var DASH_LOOKALIKES = {
|
|
1796
1889
|
"-": "‑",
|
|
@@ -1799,6 +1892,7 @@ var DASH_LOOKALIKES = {
|
|
|
1799
1892
|
};
|
|
1800
1893
|
var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
|
|
1801
1894
|
// ../../packages/aeg-core/src/claude-code-transcript.ts
|
|
1895
|
+
import { createHash } from "node:crypto";
|
|
1802
1896
|
function summarizeTranscript(jsonl) {
|
|
1803
1897
|
const seen = new Set;
|
|
1804
1898
|
const components = {
|
|
@@ -1847,7 +1941,14 @@ function numberOr(value, fallback) {
|
|
|
1847
1941
|
function sanitizeKey(value) {
|
|
1848
1942
|
return value.replace(/[^A-Za-z0-9]+/g, "-");
|
|
1849
1943
|
}
|
|
1944
|
+
function collisionResistantKey(value) {
|
|
1945
|
+
const digest = createHash("sha256").update(value).digest("hex");
|
|
1946
|
+
return `${sanitizeKey(value)}-${digest}`;
|
|
1947
|
+
}
|
|
1850
1948
|
function transcriptPointerPath(projectDir, tmpDir) {
|
|
1949
|
+
return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
|
|
1950
|
+
}
|
|
1951
|
+
function legacyTranscriptPointerPath(projectDir, tmpDir) {
|
|
1851
1952
|
return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
|
|
1852
1953
|
}
|
|
1853
1954
|
function resolvePointer(explicitTranscriptPath, deps) {
|
|
@@ -1855,13 +1956,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
|
|
|
1855
1956
|
return { path: explicitTranscriptPath, corroborated: true };
|
|
1856
1957
|
const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
|
|
1857
1958
|
const tmpDir = deps.env.TMPDIR ?? "/tmp";
|
|
1858
|
-
const
|
|
1959
|
+
const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
|
|
1960
|
+
const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
|
|
1859
1961
|
const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
|
|
1860
|
-
|
|
1962
|
+
const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
|
|
1963
|
+
if (!pointerPath) {
|
|
1861
1964
|
return {
|
|
1862
1965
|
pointerExisted: false,
|
|
1863
1966
|
corroborated: false,
|
|
1864
|
-
error: `No transcript pointer at ${
|
|
1967
|
+
error: `No transcript pointer at ${primaryPointerPath} (nor its pre-migration name ${legacyPointerPath}) ` + "and no --transcript given. Either this repo installs no track-transcript.sh Stop hook (lacking one " + "is not a defect — name the transcript directly instead), or no session has completed a turn yet."
|
|
1865
1968
|
};
|
|
1866
1969
|
}
|
|
1867
1970
|
let contents;
|
|
@@ -1936,6 +2039,9 @@ function isTokenCollectionWiringBroken(capability) {
|
|
|
1936
2039
|
return false;
|
|
1937
2040
|
return capability.reason !== "no-transcript-resolved";
|
|
1938
2041
|
}
|
|
2042
|
+
// ../../packages/aeg-core/src/metering-io-guard.ts
|
|
2043
|
+
import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
|
|
2044
|
+
var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
|
|
1939
2045
|
// ../../packages/aeg-core/src/file-classify.ts
|
|
1940
2046
|
function isCodeFile(p) {
|
|
1941
2047
|
if (p.endsWith(".md"))
|
|
@@ -2142,7 +2248,7 @@ function overrideActive(opts) {
|
|
|
2142
2248
|
return false;
|
|
2143
2249
|
}
|
|
2144
2250
|
// ../../packages/aeg-core/src/premise-check.ts
|
|
2145
|
-
import { createHash } from "node:crypto";
|
|
2251
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
2146
2252
|
var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
|
|
2147
2253
|
function isPremiseHeader(line) {
|
|
2148
2254
|
const stripped = line.replace(/[*#]/g, "").trim();
|
|
@@ -2187,7 +2293,7 @@ function checkPremises(assertions, fileReader) {
|
|
|
2187
2293
|
} else if (a.kind === "absent" && content.includes(a.value)) {
|
|
2188
2294
|
failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
|
|
2189
2295
|
} else if (a.kind === "sha256") {
|
|
2190
|
-
const actual =
|
|
2296
|
+
const actual = createHash2("sha256").update(content).digest("hex");
|
|
2191
2297
|
if (actual !== a.value.toLowerCase()) {
|
|
2192
2298
|
failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
|
|
2193
2299
|
}
|
|
@@ -3922,7 +4028,7 @@ function emitCheckError(error) {
|
|
|
3922
4028
|
|
|
3923
4029
|
// src/lib/config.ts
|
|
3924
4030
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
3925
|
-
import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
4031
|
+
import { existsSync, mkdirSync, readFileSync as readFileSync2, realpathSync, writeFileSync } from "node:fs";
|
|
3926
4032
|
import { homedir } from "node:os";
|
|
3927
4033
|
import { dirname, join, resolve } from "node:path";
|
|
3928
4034
|
import { z } from "zod";
|
|
@@ -4215,7 +4321,7 @@ function loadConfig() {
|
|
|
4215
4321
|
if (!path)
|
|
4216
4322
|
return null;
|
|
4217
4323
|
try {
|
|
4218
|
-
const raw = JSON.parse(
|
|
4324
|
+
const raw = JSON.parse(readFileSync2(path, "utf-8"));
|
|
4219
4325
|
return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
|
|
4220
4326
|
} catch {
|
|
4221
4327
|
return null;
|
|
@@ -1791,6 +1791,99 @@ var DERIVED_STATUSES = [
|
|
|
1791
1791
|
"incoherent"
|
|
1792
1792
|
];
|
|
1793
1793
|
var DERIVABLE_STATUSES = DERIVED_STATUSES.filter((s) => s !== "backlog");
|
|
1794
|
+
// ../../packages/aeg-core/src/parse-ledger.ts
|
|
1795
|
+
function rowFromCells(cells) {
|
|
1796
|
+
if (cells.length < 7)
|
|
1797
|
+
return null;
|
|
1798
|
+
const phase = (cells[0] ?? "").trim();
|
|
1799
|
+
if (!phase)
|
|
1800
|
+
return null;
|
|
1801
|
+
return {
|
|
1802
|
+
phase,
|
|
1803
|
+
role: (cells[1] ?? "").trim(),
|
|
1804
|
+
agentModel: (cells[2] ?? "").trim(),
|
|
1805
|
+
tokensIn: parseIntCell(cells[3] ?? ""),
|
|
1806
|
+
tokensOut: parseIntCell(cells[4] ?? ""),
|
|
1807
|
+
cost: parseCostCell(cells[5] ?? ""),
|
|
1808
|
+
date: (cells[6] ?? "").trim()
|
|
1809
|
+
};
|
|
1810
|
+
}
|
|
1811
|
+
function parseIntCell(cell) {
|
|
1812
|
+
const trimmed = cell.replace(/`/g, "").trim();
|
|
1813
|
+
if (!trimmed || isEmDashOrDash(trimmed))
|
|
1814
|
+
return null;
|
|
1815
|
+
const normalized = trimmed.replace(/[,_\s]/g, "");
|
|
1816
|
+
if (!/^-?\d+$/.test(normalized))
|
|
1817
|
+
return null;
|
|
1818
|
+
return Number(normalized);
|
|
1819
|
+
}
|
|
1820
|
+
function parseCostCell(cell) {
|
|
1821
|
+
const trimmed = cell.replace(/`/g, "").trim();
|
|
1822
|
+
if (!trimmed || isEmDashOrDash(trimmed))
|
|
1823
|
+
return null;
|
|
1824
|
+
const normalized = trimmed.replace(/^\$/, "").replace(/[,_\s]/g, "");
|
|
1825
|
+
if (!/^-?\d+(\.\d+)?$/.test(normalized))
|
|
1826
|
+
return null;
|
|
1827
|
+
return Number(normalized);
|
|
1828
|
+
}
|
|
1829
|
+
function isEmDashOrDash(s) {
|
|
1830
|
+
const t = s.trim();
|
|
1831
|
+
return t === "—" || t === "-" || t === "–";
|
|
1832
|
+
}
|
|
1833
|
+
// ../../packages/aeg-core/src/parse-token-report.ts
|
|
1834
|
+
var TOKEN_REPORT_HEADING = /^\s*(?:#{1,6}\s*Token report\s*|\*\*Token report\*\*)\s*$/i;
|
|
1835
|
+
var INLINE_FIELD_LIST = /Phase:\s*([^|]+?)\s*\|\s*Role:\s*([^|]+?)\s*\|\s*Agent\/Model:\s*([^|]+?)\s*\|\s*Tokens in:\s*([^|]+?)\s*\|\s*Tokens out:\s*([^|]+?)\s*\|\s*Cost:\s*([^|]+?)\s*\|\s*Date:\s*(.+?)\s*$/im;
|
|
1836
|
+
function parseTokenReportEntries(body) {
|
|
1837
|
+
const lines = body.split(/\r?\n/);
|
|
1838
|
+
const headingIdxs = [];
|
|
1839
|
+
lines.forEach((line, i) => {
|
|
1840
|
+
if (TOKEN_REPORT_HEADING.test(line))
|
|
1841
|
+
headingIdxs.push(i);
|
|
1842
|
+
});
|
|
1843
|
+
const out = [];
|
|
1844
|
+
for (let h = 0;h < headingIdxs.length; h++) {
|
|
1845
|
+
const start = headingIdxs[h] + 1;
|
|
1846
|
+
const end = h + 1 < headingIdxs.length ? headingIdxs[h + 1] : lines.length;
|
|
1847
|
+
const section = lines.slice(start, end).join(`
|
|
1848
|
+
`);
|
|
1849
|
+
const tableRows = parseTableSection(section);
|
|
1850
|
+
if (tableRows.length > 0) {
|
|
1851
|
+
out.push(...tableRows);
|
|
1852
|
+
continue;
|
|
1853
|
+
}
|
|
1854
|
+
const inlineRow = parseInlineFieldList(section);
|
|
1855
|
+
if (inlineRow)
|
|
1856
|
+
out.push(inlineRow);
|
|
1857
|
+
}
|
|
1858
|
+
return out;
|
|
1859
|
+
}
|
|
1860
|
+
function parseTableSection(section) {
|
|
1861
|
+
const lines = section.split(/\r?\n/);
|
|
1862
|
+
let i = 0;
|
|
1863
|
+
for (;i < lines.length; i++) {
|
|
1864
|
+
if ((lines[i] ?? "").trim().startsWith("|"))
|
|
1865
|
+
break;
|
|
1866
|
+
}
|
|
1867
|
+
if (i + 1 >= lines.length)
|
|
1868
|
+
return [];
|
|
1869
|
+
i += 2;
|
|
1870
|
+
const out = [];
|
|
1871
|
+
for (;i < lines.length; i++) {
|
|
1872
|
+
const trimmed = (lines[i] ?? "").trim();
|
|
1873
|
+
if (!trimmed.startsWith("|"))
|
|
1874
|
+
break;
|
|
1875
|
+
const row = rowFromCells(splitTableRow(trimmed));
|
|
1876
|
+
if (row)
|
|
1877
|
+
out.push(row);
|
|
1878
|
+
}
|
|
1879
|
+
return out;
|
|
1880
|
+
}
|
|
1881
|
+
function parseInlineFieldList(section) {
|
|
1882
|
+
const m = section.match(INLINE_FIELD_LIST);
|
|
1883
|
+
if (!m)
|
|
1884
|
+
return null;
|
|
1885
|
+
return rowFromCells([m[1], m[2], m[3], m[4], m[5], m[6], m[7]]);
|
|
1886
|
+
}
|
|
1794
1887
|
// ../../packages/aeg-core/src/report-tokens.ts
|
|
1795
1888
|
var DASH_LOOKALIKES = {
|
|
1796
1889
|
"-": "‑",
|
|
@@ -1799,6 +1892,7 @@ var DASH_LOOKALIKES = {
|
|
|
1799
1892
|
};
|
|
1800
1893
|
var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
|
|
1801
1894
|
// ../../packages/aeg-core/src/claude-code-transcript.ts
|
|
1895
|
+
import { createHash } from "node:crypto";
|
|
1802
1896
|
function summarizeTranscript(jsonl) {
|
|
1803
1897
|
const seen = new Set;
|
|
1804
1898
|
const components = {
|
|
@@ -1847,7 +1941,14 @@ function numberOr(value, fallback) {
|
|
|
1847
1941
|
function sanitizeKey(value) {
|
|
1848
1942
|
return value.replace(/[^A-Za-z0-9]+/g, "-");
|
|
1849
1943
|
}
|
|
1944
|
+
function collisionResistantKey(value) {
|
|
1945
|
+
const digest = createHash("sha256").update(value).digest("hex");
|
|
1946
|
+
return `${sanitizeKey(value)}-${digest}`;
|
|
1947
|
+
}
|
|
1850
1948
|
function transcriptPointerPath(projectDir, tmpDir) {
|
|
1949
|
+
return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
|
|
1950
|
+
}
|
|
1951
|
+
function legacyTranscriptPointerPath(projectDir, tmpDir) {
|
|
1851
1952
|
return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
|
|
1852
1953
|
}
|
|
1853
1954
|
function resolvePointer(explicitTranscriptPath, deps) {
|
|
@@ -1855,13 +1956,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
|
|
|
1855
1956
|
return { path: explicitTranscriptPath, corroborated: true };
|
|
1856
1957
|
const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
|
|
1857
1958
|
const tmpDir = deps.env.TMPDIR ?? "/tmp";
|
|
1858
|
-
const
|
|
1959
|
+
const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
|
|
1960
|
+
const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
|
|
1859
1961
|
const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
|
|
1860
|
-
|
|
1962
|
+
const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
|
|
1963
|
+
if (!pointerPath) {
|
|
1861
1964
|
return {
|
|
1862
1965
|
pointerExisted: false,
|
|
1863
1966
|
corroborated: false,
|
|
1864
|
-
error: `No transcript pointer at ${
|
|
1967
|
+
error: `No transcript pointer at ${primaryPointerPath} (nor its pre-migration name ${legacyPointerPath}) ` + "and no --transcript given. Either this repo installs no track-transcript.sh Stop hook (lacking one " + "is not a defect — name the transcript directly instead), or no session has completed a turn yet."
|
|
1865
1968
|
};
|
|
1866
1969
|
}
|
|
1867
1970
|
let contents;
|
|
@@ -1936,6 +2039,9 @@ function isTokenCollectionWiringBroken(capability) {
|
|
|
1936
2039
|
return false;
|
|
1937
2040
|
return capability.reason !== "no-transcript-resolved";
|
|
1938
2041
|
}
|
|
2042
|
+
// ../../packages/aeg-core/src/metering-io-guard.ts
|
|
2043
|
+
import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
|
|
2044
|
+
var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
|
|
1939
2045
|
// ../../packages/aeg-core/src/file-classify.ts
|
|
1940
2046
|
function isCodeFile(p) {
|
|
1941
2047
|
if (p.endsWith(".md"))
|
|
@@ -2142,7 +2248,7 @@ function overrideActive(opts) {
|
|
|
2142
2248
|
return false;
|
|
2143
2249
|
}
|
|
2144
2250
|
// ../../packages/aeg-core/src/premise-check.ts
|
|
2145
|
-
import { createHash } from "node:crypto";
|
|
2251
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
2146
2252
|
var ASSERTION_KINDS = new Set(["contains", "absent", "sha256"]);
|
|
2147
2253
|
function isPremiseHeader(line) {
|
|
2148
2254
|
const stripped = line.replace(/[*#]/g, "").trim();
|
|
@@ -2187,7 +2293,7 @@ function checkPremises(assertions, fileReader) {
|
|
|
2187
2293
|
} else if (a.kind === "absent" && content.includes(a.value)) {
|
|
2188
2294
|
failures.push(`premise-check: ${a.path} now contains "${a.value}", but the brief pinned it absent — the premise has moved; re-dig before proceeding.`);
|
|
2189
2295
|
} else if (a.kind === "sha256") {
|
|
2190
|
-
const actual =
|
|
2296
|
+
const actual = createHash2("sha256").update(content).digest("hex");
|
|
2191
2297
|
if (actual !== a.value.toLowerCase()) {
|
|
2192
2298
|
failures.push(`premise-check: ${a.path} sha256 mismatch (brief pinned ${a.value}, file is now ${actual}) — the file changed since this brief was authored; re-dig before proceeding.`);
|
|
2193
2299
|
}
|