@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
package/dist/index.js
CHANGED
|
@@ -801,11 +801,16 @@ var DASH_LOOKALIKES = {
|
|
|
801
801
|
"—": "―"
|
|
802
802
|
};
|
|
803
803
|
var DASH_CHARS = new Set(Object.keys(DASH_LOOKALIKES));
|
|
804
|
+
var PIPE_LOOKALIKE = "|";
|
|
804
805
|
function sanitizeForTokensLine(value) {
|
|
805
806
|
const stripped = stripNewlines(value);
|
|
806
807
|
let result = "";
|
|
807
808
|
for (let i = 0;i < stripped.length; i++) {
|
|
808
809
|
const ch = stripped[i];
|
|
810
|
+
if (ch === "|") {
|
|
811
|
+
result += PIPE_LOOKALIKE;
|
|
812
|
+
continue;
|
|
813
|
+
}
|
|
809
814
|
if (DASH_CHARS.has(ch)) {
|
|
810
815
|
const leftReachable = i === 0 || /\s/.test(stripped[i - 1]);
|
|
811
816
|
const rightReachable = i === stripped.length - 1 || /\s/.test(stripped[i + 1]);
|
|
@@ -857,6 +862,7 @@ function formatBreakdown(summary) {
|
|
|
857
862
|
`);
|
|
858
863
|
}
|
|
859
864
|
// ../../packages/aeg-core/src/claude-code-transcript.ts
|
|
865
|
+
import { createHash } from "node:crypto";
|
|
860
866
|
function summarizeTranscript(jsonl) {
|
|
861
867
|
const seen = new Set;
|
|
862
868
|
const components = {
|
|
@@ -905,7 +911,14 @@ function numberOr(value, fallback) {
|
|
|
905
911
|
function sanitizeKey(value) {
|
|
906
912
|
return value.replace(/[^A-Za-z0-9]+/g, "-");
|
|
907
913
|
}
|
|
914
|
+
function collisionResistantKey(value) {
|
|
915
|
+
const digest = createHash("sha256").update(value).digest("hex");
|
|
916
|
+
return `${sanitizeKey(value)}-${digest}`;
|
|
917
|
+
}
|
|
908
918
|
function transcriptPointerPath(projectDir, tmpDir) {
|
|
919
|
+
return `${tmpDir}/claude-transcript-${collisionResistantKey(projectDir)}.txt`;
|
|
920
|
+
}
|
|
921
|
+
function legacyTranscriptPointerPath(projectDir, tmpDir) {
|
|
909
922
|
return `${tmpDir}/claude-transcript-${sanitizeKey(projectDir)}.txt`;
|
|
910
923
|
}
|
|
911
924
|
function resolvePointer(explicitTranscriptPath, deps) {
|
|
@@ -913,13 +926,15 @@ function resolvePointer(explicitTranscriptPath, deps) {
|
|
|
913
926
|
return { path: explicitTranscriptPath, corroborated: true };
|
|
914
927
|
const projectDir = deps.env.CLAUDE_PROJECT_DIR ?? deps.cwd;
|
|
915
928
|
const tmpDir = deps.env.TMPDIR ?? "/tmp";
|
|
916
|
-
const
|
|
929
|
+
const primaryPointerPath = transcriptPointerPath(projectDir, tmpDir);
|
|
930
|
+
const legacyPointerPath = legacyTranscriptPointerPath(projectDir, tmpDir);
|
|
917
931
|
const currentSessionId = deps.env.CLAUDE_CODE_SESSION_ID;
|
|
918
|
-
|
|
932
|
+
const pointerPath = deps.exists(primaryPointerPath) ? primaryPointerPath : deps.exists(legacyPointerPath) ? legacyPointerPath : undefined;
|
|
933
|
+
if (!pointerPath) {
|
|
919
934
|
return {
|
|
920
935
|
pointerExisted: false,
|
|
921
936
|
corroborated: false,
|
|
922
|
-
error: `No transcript pointer at ${
|
|
937
|
+
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."
|
|
923
938
|
};
|
|
924
939
|
}
|
|
925
940
|
let contents;
|
|
@@ -989,6 +1004,58 @@ function resolveMeteringCapability(deps, explicitTranscriptPath) {
|
|
|
989
1004
|
}
|
|
990
1005
|
return { capable: true, transcriptPath: resolved.path, summary };
|
|
991
1006
|
}
|
|
1007
|
+
// ../../packages/aeg-core/src/metering-io-guard.ts
|
|
1008
|
+
import { closeSync, constants as fsConstants, fstatSync, openSync, readFileSync } from "node:fs";
|
|
1009
|
+
var GUARD_OPEN_FLAGS = fsConstants.O_RDONLY | fsConstants.O_NONBLOCK | fsConstants.O_NOFOLLOW;
|
|
1010
|
+
function isTrustedMeteringStat(stat, ownUid) {
|
|
1011
|
+
if (!stat.isFile())
|
|
1012
|
+
return false;
|
|
1013
|
+
if (typeof ownUid === "number" && stat.uid !== ownUid)
|
|
1014
|
+
return false;
|
|
1015
|
+
return true;
|
|
1016
|
+
}
|
|
1017
|
+
function ownUid() {
|
|
1018
|
+
return typeof process.getuid === "function" ? process.getuid() : undefined;
|
|
1019
|
+
}
|
|
1020
|
+
function guardedOpen(path) {
|
|
1021
|
+
try {
|
|
1022
|
+
return openSync(path, GUARD_OPEN_FLAGS);
|
|
1023
|
+
} catch {
|
|
1024
|
+
return;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
function hardenedExists(path) {
|
|
1028
|
+
const fd = guardedOpen(path);
|
|
1029
|
+
if (fd === undefined)
|
|
1030
|
+
return false;
|
|
1031
|
+
try {
|
|
1032
|
+
return isTrustedMeteringStat(fstatSync(fd), ownUid());
|
|
1033
|
+
} finally {
|
|
1034
|
+
closeSync(fd);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
function hardenedReadFile(path) {
|
|
1038
|
+
const fd = guardedOpen(path);
|
|
1039
|
+
if (fd === undefined) {
|
|
1040
|
+
throw new Error(`refusing to read ${path}: not openable as a plain, non-symlinked file`);
|
|
1041
|
+
}
|
|
1042
|
+
try {
|
|
1043
|
+
if (!isTrustedMeteringStat(fstatSync(fd), ownUid())) {
|
|
1044
|
+
throw new Error(`refusing to read ${path}: not a regular file owned by this user`);
|
|
1045
|
+
}
|
|
1046
|
+
return readFileSync(fd, "utf8");
|
|
1047
|
+
} finally {
|
|
1048
|
+
closeSync(fd);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
function hardenedMeteringDeps() {
|
|
1052
|
+
return {
|
|
1053
|
+
env: process.env,
|
|
1054
|
+
cwd: process.cwd(),
|
|
1055
|
+
exists: hardenedExists,
|
|
1056
|
+
readFile: hardenedReadFile
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
992
1059
|
// ../../packages/aeg-core/src/file-classify.ts
|
|
993
1060
|
function isCodeFile(p) {
|
|
994
1061
|
if (p.endsWith(".md"))
|
|
@@ -1753,16 +1820,16 @@ function checkAdoptable(facts) {
|
|
|
1753
1820
|
}
|
|
1754
1821
|
// src/lib/detect.ts
|
|
1755
1822
|
import { execFile as execFile4 } from "node:child_process";
|
|
1756
|
-
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as
|
|
1823
|
+
import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync7, statSync } from "node:fs";
|
|
1757
1824
|
import { join as join7 } from "node:path";
|
|
1758
1825
|
import { promisify as promisify4 } from "node:util";
|
|
1759
1826
|
|
|
1760
1827
|
// src/lib/artifacts.ts
|
|
1761
|
-
import { readFileSync as
|
|
1828
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
1762
1829
|
import { join as join4 } from "node:path";
|
|
1763
1830
|
|
|
1764
1831
|
// src/commands/doctrine.ts
|
|
1765
|
-
import { existsSync as existsSync2, readdirSync, readFileSync } from "node:fs";
|
|
1832
|
+
import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync2 } from "node:fs";
|
|
1766
1833
|
import { dirname as dirname2, join as join2, sep } from "node:path";
|
|
1767
1834
|
import matter2 from "gray-matter";
|
|
1768
1835
|
|
|
@@ -1800,17 +1867,20 @@ function resolveDoctrineRoot(pkg = packageRoot(import.meta.url)) {
|
|
|
1800
1867
|
if (!pkg.split(sep).includes("node_modules"))
|
|
1801
1868
|
candidates.push(join2(dirname2(dirname2(pkg)), "aeg-root"));
|
|
1802
1869
|
for (const root of candidates) {
|
|
1803
|
-
if (
|
|
1870
|
+
if (hasDoctrineEntry(root))
|
|
1804
1871
|
return root;
|
|
1805
1872
|
}
|
|
1806
1873
|
return null;
|
|
1807
1874
|
}
|
|
1875
|
+
function hasDoctrineEntry(root) {
|
|
1876
|
+
return existsSync2(join2(root, ...ENTRY_SEGMENTS));
|
|
1877
|
+
}
|
|
1808
1878
|
function listRoleNames(root) {
|
|
1809
1879
|
const rolesDir = join2(root, "roles");
|
|
1810
1880
|
if (!existsSync2(rolesDir))
|
|
1811
1881
|
return [];
|
|
1812
1882
|
return readdirSync(rolesDir).filter((name) => name.endsWith(".md")).map((name) => name.slice(0, -".md".length)).filter((roleName) => {
|
|
1813
|
-
const { data } = matter2(
|
|
1883
|
+
const { data } = matter2(readFileSync2(join2(rolesDir, `${roleName}.md`), "utf8"));
|
|
1814
1884
|
return data.actor !== "human";
|
|
1815
1885
|
}).sort();
|
|
1816
1886
|
}
|
|
@@ -1849,7 +1919,7 @@ function doctrineCommand(args) {
|
|
|
1849
1919
|
}
|
|
1850
1920
|
|
|
1851
1921
|
// src/lib/agents-skills-emitter.ts
|
|
1852
|
-
import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as
|
|
1922
|
+
import { existsSync as existsSync3, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "node:fs";
|
|
1853
1923
|
import { join as join3 } from "node:path";
|
|
1854
1924
|
import matter3 from "gray-matter";
|
|
1855
1925
|
var AGENTS_SKILLS_GROUP = "Agent skills (.agents/skills/)";
|
|
@@ -1861,7 +1931,7 @@ function discoverRoleNames(doctrineRoot) {
|
|
|
1861
1931
|
if (!existsSync3(rolesDir))
|
|
1862
1932
|
return [];
|
|
1863
1933
|
return readdirSync2(rolesDir).filter((name) => name.endsWith(".md")).map((name) => name.slice(0, -".md".length)).filter((roleName) => {
|
|
1864
|
-
const { data } = matter3(
|
|
1934
|
+
const { data } = matter3(readFileSync3(join3(rolesDir, `${roleName}.md`), "utf8"));
|
|
1865
1935
|
return data.actor !== "human";
|
|
1866
1936
|
}).sort();
|
|
1867
1937
|
}
|
|
@@ -1933,9 +2003,11 @@ process.stdin.on("end", () => {
|
|
|
1933
2003
|
return
|
|
1934
2004
|
}
|
|
1935
2005
|
if (!hook.transcript_path) return
|
|
2006
|
+
const crypto = require("crypto")
|
|
1936
2007
|
const projectDir = process.env.CLAUDE_PROJECT_DIR || process.cwd()
|
|
1937
2008
|
const tmpDir = process.env.TMPDIR || "/tmp"
|
|
1938
|
-
const
|
|
2009
|
+
const digest = crypto.createHash("sha256").update(projectDir).digest("hex")
|
|
2010
|
+
const key = projectDir.replace(/[^A-Za-z0-9]+/g, "-") + "-" + digest
|
|
1939
2011
|
const pointerPath = tmpDir + "/claude-transcript-" + key + ".txt"
|
|
1940
2012
|
const content = (hook.session_id || "") + "\\t" + hook.transcript_path + "\\n"
|
|
1941
2013
|
const scratchPath = pointerPath + "." + process.pid + "." + Math.random().toString(36).slice(2) + ".tmp"
|
|
@@ -2052,7 +2124,7 @@ function starterConfig() {
|
|
|
2052
2124
|
};
|
|
2053
2125
|
}
|
|
2054
2126
|
function ownVersion() {
|
|
2055
|
-
const pkg = JSON.parse(
|
|
2127
|
+
const pkg = JSON.parse(readFileSync4(join4(packageRoot(import.meta.url), "package.json"), "utf-8"));
|
|
2056
2128
|
return pkg.version;
|
|
2057
2129
|
}
|
|
2058
2130
|
var SETUP_BUN_SHA = "0c5077e51419868618aeaa5fe8019c62421857d6";
|
|
@@ -2962,13 +3034,13 @@ function buildInitOps(ctx) {
|
|
|
2962
3034
|
|
|
2963
3035
|
// src/lib/ops.ts
|
|
2964
3036
|
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
2965
|
-
import { chmodSync, existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as
|
|
3037
|
+
import { chmodSync, existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync6, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
2966
3038
|
import { dirname as dirname4, isAbsolute, join as join6, resolve as resolve2, sep as sep2 } from "node:path";
|
|
2967
3039
|
|
|
2968
3040
|
// src/lib/config.ts
|
|
2969
3041
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
2970
|
-
import { createHash } from "node:crypto";
|
|
2971
|
-
import { existsSync as existsSync4, mkdirSync, readFileSync as
|
|
3042
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
3043
|
+
import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync5, realpathSync, writeFileSync } from "node:fs";
|
|
2972
3044
|
import { homedir } from "node:os";
|
|
2973
3045
|
import { dirname as dirname3, join as join5, resolve } from "node:path";
|
|
2974
3046
|
import { z } from "zod";
|
|
@@ -3301,7 +3373,7 @@ function loadConfig() {
|
|
|
3301
3373
|
if (!path)
|
|
3302
3374
|
return null;
|
|
3303
3375
|
try {
|
|
3304
|
-
const raw = JSON.parse(
|
|
3376
|
+
const raw = JSON.parse(readFileSync5(path, "utf-8"));
|
|
3305
3377
|
return stripGlobalOnlyKeys(VinayaConfigSchema.parse(raw), path);
|
|
3306
3378
|
} catch {
|
|
3307
3379
|
return null;
|
|
@@ -3312,7 +3384,7 @@ function readRepoCiSetup(repoRoot) {
|
|
|
3312
3384
|
if (!existsSync4(p))
|
|
3313
3385
|
return null;
|
|
3314
3386
|
try {
|
|
3315
|
-
return VinayaConfigSchema.parse(JSON.parse(
|
|
3387
|
+
return VinayaConfigSchema.parse(JSON.parse(readFileSync5(p, "utf-8"))).ci?.setup ?? null;
|
|
3316
3388
|
} catch {
|
|
3317
3389
|
return null;
|
|
3318
3390
|
}
|
|
@@ -3323,7 +3395,7 @@ function loadConfigChecked() {
|
|
|
3323
3395
|
return { ok: true, config: null };
|
|
3324
3396
|
let raw;
|
|
3325
3397
|
try {
|
|
3326
|
-
raw = JSON.parse(
|
|
3398
|
+
raw = JSON.parse(readFileSync5(path, "utf-8"));
|
|
3327
3399
|
} catch (err) {
|
|
3328
3400
|
return { ok: false, path, error: `invalid JSON: ${err.message}` };
|
|
3329
3401
|
}
|
|
@@ -3339,7 +3411,7 @@ function readTokensCollectTrustStore(storePath) {
|
|
|
3339
3411
|
try {
|
|
3340
3412
|
if (!existsSync4(storePath))
|
|
3341
3413
|
return {};
|
|
3342
|
-
const raw = JSON.parse(
|
|
3414
|
+
const raw = JSON.parse(readFileSync5(storePath, "utf-8"));
|
|
3343
3415
|
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
3344
3416
|
} catch {
|
|
3345
3417
|
return {};
|
|
@@ -3385,7 +3457,7 @@ function gitBlobHash(absolutePath, cwd) {
|
|
|
3385
3457
|
}
|
|
3386
3458
|
}
|
|
3387
3459
|
function tokensCollectTrustKey(repoGitCommonDir, interpreter, script) {
|
|
3388
|
-
return
|
|
3460
|
+
return createHash2("sha256").update(JSON.stringify([repoGitCommonDir, interpreter, script])).digest("hex");
|
|
3389
3461
|
}
|
|
3390
3462
|
function getTokensCollectTrust(repoGitCommonDir, interpreter, script, storePath = TOKENS_COLLECT_TRUST_PATH) {
|
|
3391
3463
|
const key = tokensCollectTrustKey(repoGitCommonDir, interpreter, script);
|
|
@@ -3455,7 +3527,7 @@ function fileContains(repoRoot, relPath, needle) {
|
|
|
3455
3527
|
const p = resolveManagedBlockPath(repoRoot, relPath);
|
|
3456
3528
|
if (!existsSync5(p))
|
|
3457
3529
|
return false;
|
|
3458
|
-
return
|
|
3530
|
+
return readFileSync6(p, "utf-8").includes(needle);
|
|
3459
3531
|
}
|
|
3460
3532
|
function planInstall(ops, repoRoot, ownedFiles = new Set) {
|
|
3461
3533
|
const entries = [];
|
|
@@ -3565,7 +3637,7 @@ function writeFileWithDirs(target, content, mode) {
|
|
|
3565
3637
|
}
|
|
3566
3638
|
function appendBlock(repoRoot, op) {
|
|
3567
3639
|
const target = resolveManagedBlockPath(repoRoot, op.path);
|
|
3568
|
-
const existing =
|
|
3640
|
+
const existing = readFileSync6(target, "utf-8");
|
|
3569
3641
|
const sep3 = existing.endsWith(`
|
|
3570
3642
|
`) ? `
|
|
3571
3643
|
` : `
|
|
@@ -3687,7 +3759,7 @@ function planEject(manifest, repoRoot) {
|
|
|
3687
3759
|
});
|
|
3688
3760
|
continue;
|
|
3689
3761
|
}
|
|
3690
|
-
const content =
|
|
3762
|
+
const content = readFileSync6(p, "utf-8");
|
|
3691
3763
|
const stripped = stripBlockFromContent(content, b.marker, b.comment);
|
|
3692
3764
|
const removesHost = stripped !== null && blockStripLeavesEmpty(stripped);
|
|
3693
3765
|
actions.push({
|
|
@@ -3739,7 +3811,7 @@ function applyEject(plan, repoRoot) {
|
|
|
3739
3811
|
const p = containedManagedBlockAbs(repoRoot, a.path);
|
|
3740
3812
|
if (p === null)
|
|
3741
3813
|
continue;
|
|
3742
|
-
const content =
|
|
3814
|
+
const content = readFileSync6(p, "utf-8");
|
|
3743
3815
|
const stripped = stripBlockFromContent(content, a.marker, a.comment);
|
|
3744
3816
|
if (stripped === null)
|
|
3745
3817
|
continue;
|
|
@@ -3870,7 +3942,7 @@ function foreignRawHooks(repoRoot) {
|
|
|
3870
3942
|
return activeRawHooks(repoRoot).filter((f) => {
|
|
3871
3943
|
const abs2 = resolveManagedBlockPath(repoRoot, `.git/hooks/${f}`);
|
|
3872
3944
|
try {
|
|
3873
|
-
const stripped = stripBlockFromContent(
|
|
3945
|
+
const stripped = stripBlockFromContent(readFileSync7(abs2, "utf-8"), f, "hash");
|
|
3874
3946
|
return stripped === null || !blockStripLeavesEmpty(stripped);
|
|
3875
3947
|
} catch {
|
|
3876
3948
|
return true;
|
|
@@ -4004,7 +4076,6 @@ function closeStdin() {
|
|
|
4004
4076
|
|
|
4005
4077
|
// src/commands/tokens.ts
|
|
4006
4078
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
4007
|
-
import { existsSync as existsSync7, readFileSync as readFileSync7 } from "node:fs";
|
|
4008
4079
|
import { resolve as resolvePath } from "node:path";
|
|
4009
4080
|
var USAGE = [
|
|
4010
4081
|
'Usage: vinaya tokens --phase "<task-id>: develop" --role Developer',
|
|
@@ -4156,10 +4227,7 @@ function runDeclaredCollect(command, deps) {
|
|
|
4156
4227
|
var COLLECT_COMMAND_TIMEOUT_MS = 30000;
|
|
4157
4228
|
function realDeps() {
|
|
4158
4229
|
return {
|
|
4159
|
-
|
|
4160
|
-
cwd: process.cwd(),
|
|
4161
|
-
exists: existsSync7,
|
|
4162
|
-
readFile: (path) => readFileSync7(path, "utf8"),
|
|
4230
|
+
...hardenedMeteringDeps(),
|
|
4163
4231
|
loadConfig,
|
|
4164
4232
|
repoConfigDir: repoLocalConfigDir,
|
|
4165
4233
|
runScript: (interpreter, scriptAbsolutePath, cwd) => execFileSync4(interpreter, [scriptAbsolutePath], { cwd, encoding: "utf-8", timeout: COLLECT_COMMAND_TIMEOUT_MS }),
|
|
@@ -4813,11 +4881,11 @@ function emitCheckError(error) {
|
|
|
4813
4881
|
}
|
|
4814
4882
|
|
|
4815
4883
|
// src/checks/registry.ts
|
|
4816
|
-
import { existsSync as
|
|
4884
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
4817
4885
|
import { join as join8 } from "node:path";
|
|
4818
4886
|
var DIST_BIN_DIR = join8(packageRoot(import.meta.url), "dist", "checks", "bin");
|
|
4819
4887
|
var SRC_BIN_DIR = join8(packageRoot(import.meta.url), "src", "checks", "bin");
|
|
4820
|
-
var BIN_DIR =
|
|
4888
|
+
var BIN_DIR = existsSync7(DIST_BIN_DIR) ? DIST_BIN_DIR : SRC_BIN_DIR;
|
|
4821
4889
|
var BIN_EXT = BIN_DIR === DIST_BIN_DIR ? ".js" : ".ts";
|
|
4822
4890
|
function bin(name) {
|
|
4823
4891
|
return join8(BIN_DIR, `${name}${BIN_EXT}`);
|
|
@@ -4952,6 +5020,21 @@ var REGISTRY = [
|
|
|
4952
5020
|
},
|
|
4953
5021
|
1
|
|
4954
5022
|
],
|
|
5023
|
+
[
|
|
5024
|
+
{
|
|
5025
|
+
name: "token-report",
|
|
5026
|
+
run: bin("check-token-report"),
|
|
5027
|
+
scope: "diff",
|
|
5028
|
+
timeoutMs: 15000,
|
|
5029
|
+
requiresOpenPr: true,
|
|
5030
|
+
env: {
|
|
5031
|
+
PR_BODY: { optional: true },
|
|
5032
|
+
CLAUDE_PROJECT_DIR: { optional: true },
|
|
5033
|
+
CLAUDE_CODE_SESSION_ID: { optional: true }
|
|
5034
|
+
}
|
|
5035
|
+
},
|
|
5036
|
+
1
|
|
5037
|
+
],
|
|
4955
5038
|
[
|
|
4956
5039
|
{
|
|
4957
5040
|
name: "no-disk-state",
|
|
@@ -5489,7 +5572,7 @@ async function runChecks(specs, opts) {
|
|
|
5489
5572
|
}
|
|
5490
5573
|
|
|
5491
5574
|
// src/roles/plan.ts
|
|
5492
|
-
import { existsSync as
|
|
5575
|
+
import { existsSync as existsSync8, readFileSync as readFileSync9 } from "node:fs";
|
|
5493
5576
|
import { join as join10 } from "node:path";
|
|
5494
5577
|
|
|
5495
5578
|
// ../../packages/sources/src/commands.ts
|
|
@@ -6125,7 +6208,7 @@ function resolveRoles(core, configRoles) {
|
|
|
6125
6208
|
var NO_DOCTRINE_REASON = "no bundled doctrine found next to this CLI install — the doctrine ships inside the @attalabs/vinaya npm package. Reinstall it, or, in a repo that vendors the CLI, run the package's bundle-doctrine script first.";
|
|
6126
6209
|
function readContract(configDir, contractPath) {
|
|
6127
6210
|
const absolute = join10(configDir, contractPath);
|
|
6128
|
-
if (!
|
|
6211
|
+
if (!existsSync8(absolute)) {
|
|
6129
6212
|
return { ok: false, errors: [`contract file "${contractPath}" does not exist (resolved to "${absolute}")`] };
|
|
6130
6213
|
}
|
|
6131
6214
|
try {
|
|
@@ -6424,7 +6507,7 @@ function commitMsgCommand(args) {
|
|
|
6424
6507
|
|
|
6425
6508
|
// src/commands/demo.ts
|
|
6426
6509
|
import { execFileSync as execFileSync8, spawnSync } from "node:child_process";
|
|
6427
|
-
import { existsSync as
|
|
6510
|
+
import { existsSync as existsSync9, readFileSync as readFileSync11, rmSync as rmSync2, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
6428
6511
|
import { isAbsolute as isAbsolute2, join as join11 } from "node:path";
|
|
6429
6512
|
var DEMO_BRANCH_PREFIX = "vinaya/demo-break-";
|
|
6430
6513
|
var FIXTURE_PATH = ".vinaya-demo-brief.md";
|
|
@@ -6467,7 +6550,7 @@ function gitDirAbs(repoRoot) {
|
|
|
6467
6550
|
function recoverFromCrash(repoRoot, statePath) {
|
|
6468
6551
|
const currentBranch = currentBranchName(repoRoot);
|
|
6469
6552
|
let state = null;
|
|
6470
|
-
if (
|
|
6553
|
+
if (existsSync9(statePath)) {
|
|
6471
6554
|
try {
|
|
6472
6555
|
state = JSON.parse(readFileSync11(statePath, "utf-8"));
|
|
6473
6556
|
} catch {
|
|
@@ -6539,14 +6622,14 @@ function cleanup(repoRoot, originalBranch, demoBranch, statePath) {
|
|
|
6539
6622
|
gitCapture(repoRoot, ["clean", "-fd"]);
|
|
6540
6623
|
gitCapture(repoRoot, ["checkout", originalBranch]);
|
|
6541
6624
|
gitCapture(repoRoot, ["branch", "-D", demoBranch]);
|
|
6542
|
-
if (
|
|
6625
|
+
if (existsSync9(statePath))
|
|
6543
6626
|
rmSync2(statePath, { force: true });
|
|
6544
6627
|
}
|
|
6545
6628
|
async function runDemoBreak(repoRoot, args) {
|
|
6546
6629
|
const keep = args.includes("--keep");
|
|
6547
6630
|
const hookDir = resolveHookDir(repoRoot);
|
|
6548
6631
|
const hookPath = resolveManagedBlockPath(repoRoot, `${hookDir}/pre-commit`);
|
|
6549
|
-
if (!
|
|
6632
|
+
if (!existsSync9(hookPath)) {
|
|
6550
6633
|
console.error("Vinaya hooks are not installed in this repo. Run `vinaya init` first.");
|
|
6551
6634
|
return 1;
|
|
6552
6635
|
}
|
|
@@ -6616,7 +6699,7 @@ Attempting to commit…
|
|
|
6616
6699
|
process.stdout.write(`✓ Commit passed — the fix worked.
|
|
6617
6700
|
`);
|
|
6618
6701
|
if (keep) {
|
|
6619
|
-
if (
|
|
6702
|
+
if (existsSync9(statePath))
|
|
6620
6703
|
unlinkSync(statePath);
|
|
6621
6704
|
process.stdout.write(`
|
|
6622
6705
|
--keep: leaving \`${demoBranch}\` checked out for you to inspect. Clean up with:
|
|
@@ -6644,7 +6727,7 @@ async function demoBreakCommand(args) {
|
|
|
6644
6727
|
|
|
6645
6728
|
// src/commands/doctor.ts
|
|
6646
6729
|
import { execFileSync as execFileSync9 } from "node:child_process";
|
|
6647
|
-
import { existsSync as
|
|
6730
|
+
import { existsSync as existsSync12, readdirSync as readdirSync6, readFileSync as readFileSync15, statSync as statSync2 } from "node:fs";
|
|
6648
6731
|
import { delimiter, join as join14 } from "node:path";
|
|
6649
6732
|
|
|
6650
6733
|
// src/lib/self-host.ts
|
|
@@ -6762,14 +6845,14 @@ function detectVendoredVinaya(repoRoot) {
|
|
|
6762
6845
|
}
|
|
6763
6846
|
|
|
6764
6847
|
// src/lib/env-lint.ts
|
|
6765
|
-
import { existsSync as
|
|
6848
|
+
import { existsSync as existsSync10, readFileSync as readFileSync13 } from "node:fs";
|
|
6766
6849
|
var ENV_READ_PATTERN = /\b(?:process\.env|Bun\.env|Deno\.env)\b/;
|
|
6767
6850
|
function checksMissingEnvDeclaration(specs) {
|
|
6768
6851
|
const names = [];
|
|
6769
6852
|
for (const spec of specs) {
|
|
6770
6853
|
if (spec.env)
|
|
6771
6854
|
continue;
|
|
6772
|
-
if (!
|
|
6855
|
+
if (!existsSync10(spec.run))
|
|
6773
6856
|
continue;
|
|
6774
6857
|
let source;
|
|
6775
6858
|
try {
|
|
@@ -6787,7 +6870,7 @@ function envDeclarationWarning(name) {
|
|
|
6787
6870
|
}
|
|
6788
6871
|
|
|
6789
6872
|
// src/lib/registry-write.ts
|
|
6790
|
-
import { existsSync as
|
|
6873
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync3, readFileSync as readFileSync14, writeFileSync as writeFileSync4 } from "node:fs";
|
|
6791
6874
|
import { dirname as dirname6, join as join13 } from "node:path";
|
|
6792
6875
|
var PROJECTS_REGISTRY_PATH = ".vinaya/projects.md";
|
|
6793
6876
|
var CONFIG_FILE_PATH = "vinaya.config.json";
|
|
@@ -6856,7 +6939,7 @@ ${newRow}
|
|
|
6856
6939
|
function planRegistryRow(repoRoot, name, path, specsPath) {
|
|
6857
6940
|
const abs2 = join13(repoRoot, PROJECTS_REGISTRY_PATH);
|
|
6858
6941
|
const line = rowLine(name, path, specsPath);
|
|
6859
|
-
if (!
|
|
6942
|
+
if (!existsSync11(abs2)) {
|
|
6860
6943
|
return { action: "create-host", rowLine: line, path: PROJECTS_REGISTRY_PATH };
|
|
6861
6944
|
}
|
|
6862
6945
|
const existing = readFileSync14(abs2, "utf-8");
|
|
@@ -6884,7 +6967,7 @@ function renderRegistryRowDiffLine(plan) {
|
|
|
6884
6967
|
}
|
|
6885
6968
|
function readProjectEntries(repoRoot) {
|
|
6886
6969
|
const abs2 = join13(repoRoot, CONFIG_FILE_PATH);
|
|
6887
|
-
if (!
|
|
6970
|
+
if (!existsSync11(abs2))
|
|
6888
6971
|
return [];
|
|
6889
6972
|
try {
|
|
6890
6973
|
return VinayaConfigSchema.parse(JSON.parse(readFileSync14(abs2, "utf-8"))).projects ?? [];
|
|
@@ -6932,12 +7015,7 @@ function realDeps4() {
|
|
|
6932
7015
|
nodeVersion: () => process.version,
|
|
6933
7016
|
bunVersion: () => typeof Bun === "undefined" ? null : Bun.version,
|
|
6934
7017
|
packageVersion: readVersion,
|
|
6935
|
-
meteringCapability: () => resolveMeteringCapability(
|
|
6936
|
-
env: process.env,
|
|
6937
|
-
cwd: process.cwd(),
|
|
6938
|
-
exists: existsSync13,
|
|
6939
|
-
readFile: (path) => readFileSync15(path, "utf8")
|
|
6940
|
-
})
|
|
7018
|
+
meteringCapability: () => resolveMeteringCapability(hardenedMeteringDeps())
|
|
6941
7019
|
};
|
|
6942
7020
|
}
|
|
6943
7021
|
var ok = (check, message) => ({ check, severity: "ok", message });
|
|
@@ -6946,7 +7024,7 @@ var warn = (check, message) => ({ check, severity: "warn", message });
|
|
|
6946
7024
|
var error = (check, message) => ({ check, severity: "error", message });
|
|
6947
7025
|
function readConfig(repoRoot) {
|
|
6948
7026
|
const p = join14(repoRoot, CONFIG_PATH);
|
|
6949
|
-
if (!
|
|
7027
|
+
if (!existsSync12(p))
|
|
6950
7028
|
return { kind: "missing" };
|
|
6951
7029
|
let raw;
|
|
6952
7030
|
try {
|
|
@@ -6990,7 +7068,7 @@ function diagnoseInstall(repoRoot, ctx, manifest) {
|
|
|
6990
7068
|
if (op.kind === "create-file") {
|
|
6991
7069
|
const check = labelForPath(op.path);
|
|
6992
7070
|
const abs2 = join14(repoRoot, op.path);
|
|
6993
|
-
const exists =
|
|
7071
|
+
const exists = existsSync12(abs2);
|
|
6994
7072
|
const owned = ownedFiles.has(op.path) || isDefaultedAgentVendorPath(op.path, manifest);
|
|
6995
7073
|
if (!exists) {
|
|
6996
7074
|
findings.push(owned ? error(check, `${op.path} is recorded as vinaya-managed but missing on disk — run \`vinaya upgrade\`.`) : error(check, `${op.path} is not installed — run \`vinaya init\`.`));
|
|
@@ -7015,7 +7093,7 @@ function diagnoseInstall(repoRoot, ctx, manifest) {
|
|
|
7015
7093
|
const check = "hooks";
|
|
7016
7094
|
const abs2 = resolveManagedBlockPath(repoRoot, op.path);
|
|
7017
7095
|
const owned = ownedBlocks.has(blockKey(op.path, op.marker));
|
|
7018
|
-
if (!
|
|
7096
|
+
if (!existsSync12(abs2)) {
|
|
7019
7097
|
findings.push(owned ? error(check, `${op.path} is missing — likely a fresh clone (raw git hooks aren't tracked by git). Run \`vinaya upgrade\` to restore it.`) : info(check, `${op.path} is not installed.`));
|
|
7020
7098
|
continue;
|
|
7021
7099
|
}
|
|
@@ -7068,7 +7146,7 @@ function diagnoseCustomChecks(repoRoot, config) {
|
|
|
7068
7146
|
const findings = [];
|
|
7069
7147
|
for (const [name, entry2] of Object.entries(config.checks ?? {})) {
|
|
7070
7148
|
const scriptAbs = join14(repoRoot, entry2.run);
|
|
7071
|
-
findings.push(
|
|
7149
|
+
findings.push(existsSync12(scriptAbs) ? ok("checks", `custom check '${name}' → ${entry2.run}`) : error("checks", `custom check '${name}' points at a missing script: ${entry2.run}`));
|
|
7072
7150
|
}
|
|
7073
7151
|
return findings;
|
|
7074
7152
|
}
|
|
@@ -7082,7 +7160,7 @@ function listTrackedFiles(repoRoot) {
|
|
|
7082
7160
|
}
|
|
7083
7161
|
function diagnoseDocOwnersHealth(repoRoot) {
|
|
7084
7162
|
const path = join14(repoRoot, DOC_OWNERS_PATH);
|
|
7085
|
-
const content =
|
|
7163
|
+
const content = existsSync12(path) ? readFileSync15(path, "utf-8") : null;
|
|
7086
7164
|
const state = classifyDocOwnersManifest(content);
|
|
7087
7165
|
if (state === "absent" || state === "empty")
|
|
7088
7166
|
return [];
|
|
@@ -7100,7 +7178,7 @@ function diagnoseDocOwnersHealth(repoRoot) {
|
|
|
7100
7178
|
}
|
|
7101
7179
|
if (!isUrlPointer(b.pointer)) {
|
|
7102
7180
|
const pointerPath = join14(repoRoot, pointerToPath(b.pointer));
|
|
7103
|
-
if (!
|
|
7181
|
+
if (!existsSync12(pointerPath)) {
|
|
7104
7182
|
flagged = true;
|
|
7105
7183
|
findings.push(warn("doc-owners", `${DOC_OWNERS_PATH}:${b.lineNum} points to ${b.pointer}, which does not exist on disk. Repoint the ` + "binding, or add the missing doc."));
|
|
7106
7184
|
}
|
|
@@ -7139,11 +7217,11 @@ function listChildDirsForDoctor(dir, repoRoot) {
|
|
|
7139
7217
|
}
|
|
7140
7218
|
function diagnoseBlastRadiusDeprecation(repoRoot, config) {
|
|
7141
7219
|
const derived = deriveWorkspacePackageDomains(readWorkspacesForDoctor(repoRoot), (dir) => listChildDirsForDoctor(dir, repoRoot));
|
|
7142
|
-
const defaults = deriveBuiltinCrossCuttingDefaults((p) =>
|
|
7220
|
+
const defaults = deriveBuiltinCrossCuttingDefaults((p) => existsSync12(join14(repoRoot, p)));
|
|
7143
7221
|
const covered = new Set([...derived, ...defaults]);
|
|
7144
7222
|
const configExtra = new Set(config?.blastRadius?.extraDomains ?? []);
|
|
7145
7223
|
const legacyPath = join14(repoRoot, LEGACY_AEG_PACKAGES_PATH);
|
|
7146
|
-
if (!
|
|
7224
|
+
if (!existsSync12(legacyPath)) {
|
|
7147
7225
|
return [
|
|
7148
7226
|
info("blast-radius", `checkBlastRadiusScope is active via live derivation (${derived.length} packages/* domain(s)) + built-in defaults (${defaults.length} present) — no ${LEGACY_AEG_PACKAGES_PATH}, and the check is not dormant.`)
|
|
7149
7227
|
];
|
|
@@ -7204,7 +7282,7 @@ function diagnoseCheckClassification(config) {
|
|
|
7204
7282
|
return findings;
|
|
7205
7283
|
}
|
|
7206
7284
|
function diagnoseGlobalConfigChecks() {
|
|
7207
|
-
if (!
|
|
7285
|
+
if (!existsSync12(GLOBAL_CONFIG_PATH))
|
|
7208
7286
|
return [];
|
|
7209
7287
|
let raw;
|
|
7210
7288
|
try {
|
|
@@ -7258,7 +7336,7 @@ function coversWorkflowsDir(pattern) {
|
|
|
7258
7336
|
}
|
|
7259
7337
|
function diagnoseCodeowners(repoRoot) {
|
|
7260
7338
|
const path = join14(repoRoot, ".github", "CODEOWNERS");
|
|
7261
|
-
if (!
|
|
7339
|
+
if (!existsSync12(path)) {
|
|
7262
7340
|
return info("codeowners", "no .github/CODEOWNERS — vinaya's workflow files have no required-review protection; see `vinaya init`'s printed recommendation.");
|
|
7263
7341
|
}
|
|
7264
7342
|
let body;
|
|
@@ -7276,7 +7354,7 @@ function diagnoseVinayaOnPath(agents) {
|
|
|
7276
7354
|
return [];
|
|
7277
7355
|
const names = process.platform === "win32" ? ["vinaya.cmd", "vinaya.exe", "vinaya.bat"] : ["vinaya"];
|
|
7278
7356
|
const dirs = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
7279
|
-
const onPath = dirs.some((dir) => names.some((name) =>
|
|
7357
|
+
const onPath = dirs.some((dir) => names.some((name) => existsSync12(join14(dir, name))));
|
|
7280
7358
|
return [
|
|
7281
7359
|
onPath ? ok("vinaya-on-path", "`vinaya` resolves on PATH — agent-native commands will work.") : info("vinaya-on-path", "`vinaya` is not resolvable on PATH — `/vinaya <role>` and the .agents/skills/vinaya-*/SKILL.md files " + 'installed here will fail "command not found" on first use. Run `npm install -g @attalabs/vinaya`.')
|
|
7282
7360
|
];
|
|
@@ -7289,7 +7367,7 @@ function diagnosePrincipals(config) {
|
|
|
7289
7367
|
}
|
|
7290
7368
|
function diagnoseProjectsCoherence(repoRoot, config) {
|
|
7291
7369
|
const registryAbs = join14(repoRoot, PROJECTS_REGISTRY_PATH);
|
|
7292
|
-
const registryNames =
|
|
7370
|
+
const registryNames = existsSync12(registryAbs) ? new Set(parseRegistry(readFileSync15(registryAbs, "utf-8")).map((p) => p.name)) : new Set;
|
|
7293
7371
|
const configNames = new Set((config?.projects ?? []).map((p) => p.name));
|
|
7294
7372
|
if (registryNames.size === 0 && configNames.size === 0)
|
|
7295
7373
|
return [];
|
|
@@ -7316,7 +7394,7 @@ function diagnoseTestCi(repoRoot) {
|
|
|
7316
7394
|
if (typeof testScript !== "string" || testScript.trim() === "")
|
|
7317
7395
|
return [];
|
|
7318
7396
|
const workflowsDir = join14(repoRoot, ".github/workflows");
|
|
7319
|
-
const files =
|
|
7397
|
+
const files = existsSync12(workflowsDir) ? readdirSync6(workflowsDir).filter((name) => statSync2(join14(workflowsDir, name)).isFile()) : [];
|
|
7320
7398
|
const invoked = files.some((name) => {
|
|
7321
7399
|
const content = readFileSync15(join14(workflowsDir, name), "utf-8");
|
|
7322
7400
|
return TEST_INVOCATION_SUBSTRINGS.some((s) => content.includes(s));
|
|
@@ -7409,7 +7487,7 @@ async function doctorCommand(args) {
|
|
|
7409
7487
|
}
|
|
7410
7488
|
|
|
7411
7489
|
// src/commands/eject.ts
|
|
7412
|
-
import { existsSync as
|
|
7490
|
+
import { existsSync as existsSync13, readFileSync as readFileSync16 } from "node:fs";
|
|
7413
7491
|
import { join as join15 } from "node:path";
|
|
7414
7492
|
function realDeps5() {
|
|
7415
7493
|
return {
|
|
@@ -7428,7 +7506,7 @@ function parse(args) {
|
|
|
7428
7506
|
}
|
|
7429
7507
|
function readManifest(repoRoot) {
|
|
7430
7508
|
const p = join15(repoRoot, CONFIG_PATH);
|
|
7431
|
-
if (!
|
|
7509
|
+
if (!existsSync13(p))
|
|
7432
7510
|
return { kind: "none" };
|
|
7433
7511
|
let raw;
|
|
7434
7512
|
try {
|
|
@@ -7522,7 +7600,7 @@ async function ejectCommand(args) {
|
|
|
7522
7600
|
}
|
|
7523
7601
|
|
|
7524
7602
|
// src/commands/init.ts
|
|
7525
|
-
import { existsSync as
|
|
7603
|
+
import { existsSync as existsSync14, readFileSync as readFileSync17, writeFileSync as writeFileSync5 } from "node:fs";
|
|
7526
7604
|
import { join as join16 } from "node:path";
|
|
7527
7605
|
function realDeps6() {
|
|
7528
7606
|
return {
|
|
@@ -7564,7 +7642,7 @@ function parseAgentsFlag(args) {
|
|
|
7564
7642
|
var PRODUCT_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
7565
7643
|
function readManifest2(repoRoot) {
|
|
7566
7644
|
const p = join16(repoRoot, CONFIG_PATH);
|
|
7567
|
-
if (!
|
|
7645
|
+
if (!existsSync14(p))
|
|
7568
7646
|
return null;
|
|
7569
7647
|
try {
|
|
7570
7648
|
return VinayaConfigSchema.parse(JSON.parse(readFileSync17(p, "utf-8"))).managed ?? null;
|
|
@@ -7728,7 +7806,7 @@ import { execFileSync as execFileSync11 } from "node:child_process";
|
|
|
7728
7806
|
|
|
7729
7807
|
// src/lib/forge-write.ts
|
|
7730
7808
|
import { execFileSync as execFileSync10 } from "node:child_process";
|
|
7731
|
-
import { existsSync as
|
|
7809
|
+
import { existsSync as existsSync15, mkdtempSync, readdirSync as readdirSync7, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
7732
7810
|
import { readFileSync as readFileSync18 } from "node:fs";
|
|
7733
7811
|
import { tmpdir } from "node:os";
|
|
7734
7812
|
import { join as join17 } from "node:path";
|
|
@@ -8031,7 +8109,7 @@ function readSharedPackages(root = repoRoot()) {
|
|
|
8031
8109
|
if (!root)
|
|
8032
8110
|
return [];
|
|
8033
8111
|
const derived = deriveWorkspacePackageDomains(readWorkspaceGlobs(root), (dir) => listWorkspaceChildDirs(dir, root));
|
|
8034
|
-
const defaults = deriveBuiltinCrossCuttingDefaults((p) =>
|
|
8112
|
+
const defaults = deriveBuiltinCrossCuttingDefaults((p) => existsSync15(join17(root, p)));
|
|
8035
8113
|
const configExtra = readConfigExtraDomains(root);
|
|
8036
8114
|
return [...new Set([...derived, ...defaults, ...configExtra])];
|
|
8037
8115
|
}
|
|
@@ -8573,7 +8651,7 @@ async function milestoneCloseCommand(args) {
|
|
|
8573
8651
|
}
|
|
8574
8652
|
|
|
8575
8653
|
// src/commands/new-check.ts
|
|
8576
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
8654
|
+
import { chmodSync as chmodSync2, existsSync as existsSync16, mkdirSync as mkdirSync4, readFileSync as readFileSync19, writeFileSync as writeFileSync7 } from "node:fs";
|
|
8577
8655
|
import { join as join18 } from "node:path";
|
|
8578
8656
|
var TEMPLATE_PATH = join18(packageRoot(import.meta.url), "templates", "custom-check.template.ts");
|
|
8579
8657
|
var CHECKS_DIR = join18("scripts", "vinaya-checks");
|
|
@@ -8594,11 +8672,11 @@ function newCheckCommand(args) {
|
|
|
8594
8672
|
process.exit(2);
|
|
8595
8673
|
}
|
|
8596
8674
|
const scriptsDir = join18(process.cwd(), CHECKS_DIR);
|
|
8597
|
-
if (!
|
|
8675
|
+
if (!existsSync16(scriptsDir))
|
|
8598
8676
|
mkdirSync4(scriptsDir, { recursive: true });
|
|
8599
8677
|
const fileStem = name.slice(name.indexOf("/") + 1);
|
|
8600
8678
|
const targetPath = join18(scriptsDir, `${fileStem}.ts`);
|
|
8601
|
-
if (
|
|
8679
|
+
if (existsSync16(targetPath)) {
|
|
8602
8680
|
console.error(`Error: ${targetPath} already exists.`);
|
|
8603
8681
|
process.exit(1);
|
|
8604
8682
|
}
|
|
@@ -8616,7 +8694,7 @@ ${registration}
|
|
|
8616
8694
|
}
|
|
8617
8695
|
|
|
8618
8696
|
// src/commands/new-noop-check.ts
|
|
8619
|
-
import { chmodSync as chmodSync3, existsSync as
|
|
8697
|
+
import { chmodSync as chmodSync3, existsSync as existsSync17, mkdirSync as mkdirSync5, readFileSync as readFileSync20, writeFileSync as writeFileSync8 } from "node:fs";
|
|
8620
8698
|
import { join as join19 } from "node:path";
|
|
8621
8699
|
var TEMPLATE_PATH2 = join19(packageRoot(import.meta.url), "templates", "noop-check.template.ts");
|
|
8622
8700
|
var CHECKS_DIR2 = join19("vinaya", "checks");
|
|
@@ -8634,10 +8712,10 @@ function newNoopCheckCommand(args) {
|
|
|
8634
8712
|
process.exit(2);
|
|
8635
8713
|
}
|
|
8636
8714
|
const checksDir = join19(process.cwd(), CHECKS_DIR2);
|
|
8637
|
-
if (!
|
|
8715
|
+
if (!existsSync17(checksDir))
|
|
8638
8716
|
mkdirSync5(checksDir, { recursive: true });
|
|
8639
8717
|
const targetPath = join19(checksDir, `${name}.ts`);
|
|
8640
|
-
if (
|
|
8718
|
+
if (existsSync17(targetPath)) {
|
|
8641
8719
|
console.error(`Error: ${targetPath} already exists.`);
|
|
8642
8720
|
process.exit(1);
|
|
8643
8721
|
}
|
|
@@ -8663,7 +8741,7 @@ ${registration}
|
|
|
8663
8741
|
}
|
|
8664
8742
|
|
|
8665
8743
|
// src/commands/new-role.ts
|
|
8666
|
-
import { existsSync as
|
|
8744
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync6, readFileSync as readFileSync21, writeFileSync as writeFileSync9 } from "node:fs";
|
|
8667
8745
|
import { join as join20 } from "node:path";
|
|
8668
8746
|
var TEMPLATE_PATH3 = join20(packageRoot(import.meta.url), "templates", "role.template.md");
|
|
8669
8747
|
var ROLES_DIR = join20("vinaya", "roles");
|
|
@@ -8680,11 +8758,11 @@ A bare, un-namespaced key resolves as an OVERRIDE of a core role — a complete
|
|
|
8680
8758
|
process.exit(2);
|
|
8681
8759
|
}
|
|
8682
8760
|
const rolesDir = join20(process.cwd(), ROLES_DIR);
|
|
8683
|
-
if (!
|
|
8761
|
+
if (!existsSync18(rolesDir))
|
|
8684
8762
|
mkdirSync6(rolesDir, { recursive: true });
|
|
8685
8763
|
const roleId = name.slice(name.indexOf("/") + 1);
|
|
8686
8764
|
const targetPath = join20(rolesDir, `${roleId}.md`);
|
|
8687
|
-
if (
|
|
8765
|
+
if (existsSync18(targetPath)) {
|
|
8688
8766
|
console.error(`Error: ${targetPath} already exists.`);
|
|
8689
8767
|
process.exit(1);
|
|
8690
8768
|
}
|
|
@@ -9153,7 +9231,7 @@ function prEditCommand(args) {
|
|
|
9153
9231
|
|
|
9154
9232
|
// src/commands/pr-report.ts
|
|
9155
9233
|
import { execFileSync as execFileSync14, spawnSync as spawnSync2 } from "node:child_process";
|
|
9156
|
-
import { existsSync as
|
|
9234
|
+
import { existsSync as existsSync19, readFileSync as readFileSync22, writeFileSync as writeFileSync10 } from "node:fs";
|
|
9157
9235
|
import { join as join21 } from "node:path";
|
|
9158
9236
|
var EVIDENCE_START = "<!-- AEG:EVIDENCE:START -->";
|
|
9159
9237
|
var EVIDENCE_END = "<!-- AEG:EVIDENCE:END -->";
|
|
@@ -9213,7 +9291,7 @@ function computeGroupA() {
|
|
|
9213
9291
|
function resolveSelfEntry() {
|
|
9214
9292
|
const root = packageRoot(import.meta.url);
|
|
9215
9293
|
const dist = join21(root, "dist", "index.js");
|
|
9216
|
-
return
|
|
9294
|
+
return existsSync19(dist) ? dist : join21(root, "src", "index.ts");
|
|
9217
9295
|
}
|
|
9218
9296
|
var FAILING_STATUSES = new Set(["fail", "error", "timeout"]);
|
|
9219
9297
|
function anyGateFailed(outcomes) {
|
|
@@ -9420,7 +9498,7 @@ async function prReportCommand(args) {
|
|
|
9420
9498
|
throw err;
|
|
9421
9499
|
}
|
|
9422
9500
|
if (writePath) {
|
|
9423
|
-
const existing =
|
|
9501
|
+
const existing = existsSync19(writePath) ? readFileSync22(writePath, "utf8") : "";
|
|
9424
9502
|
const withEvidence = replaceEvidenceBlock(existing, result.blockInner);
|
|
9425
9503
|
const tokensAddition = collectTokensAddition({
|
|
9426
9504
|
phase: phaseOverride ?? derivePhase(),
|
|
@@ -9616,11 +9694,11 @@ async function prVerifyEvidenceCommand(args) {
|
|
|
9616
9694
|
|
|
9617
9695
|
// src/commands/quickstart.ts
|
|
9618
9696
|
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
9619
|
-
import { existsSync as
|
|
9697
|
+
import { existsSync as existsSync21, readFileSync as readFileSync24 } from "node:fs";
|
|
9620
9698
|
import { join as join23 } from "node:path";
|
|
9621
9699
|
|
|
9622
9700
|
// src/lib/doc-owners-write.ts
|
|
9623
|
-
import { existsSync as
|
|
9701
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync7, readFileSync as readFileSync23, writeFileSync as writeFileSync11 } from "node:fs";
|
|
9624
9702
|
import { dirname as dirname7, join as join22 } from "node:path";
|
|
9625
9703
|
function bindingLine(glob, pointer) {
|
|
9626
9704
|
return `${glob} ${pointer}`;
|
|
@@ -9639,7 +9717,7 @@ function appendDocOwnersBinding(content, glob, pointer) {
|
|
|
9639
9717
|
function planDocOwnersBinding(repoRoot3, glob, pointer) {
|
|
9640
9718
|
const abs2 = join22(repoRoot3, DOC_OWNERS_PATH);
|
|
9641
9719
|
const line = bindingLine(glob, pointer);
|
|
9642
|
-
if (!
|
|
9720
|
+
if (!existsSync20(abs2)) {
|
|
9643
9721
|
return { action: "create-host", line, path: DOC_OWNERS_PATH };
|
|
9644
9722
|
}
|
|
9645
9723
|
const existing = readFileSync23(abs2, "utf-8");
|
|
@@ -9716,7 +9794,7 @@ function pointerIsMissingLocalFile(repoRoot3, pointer) {
|
|
|
9716
9794
|
if (/^https?:\/\//i.test(pointer))
|
|
9717
9795
|
return false;
|
|
9718
9796
|
const path = pointer.split("#")[0] ?? pointer;
|
|
9719
|
-
return !
|
|
9797
|
+
return !existsSync21(join23(repoRoot3, path));
|
|
9720
9798
|
}
|
|
9721
9799
|
async function bindDocOwnerLoop(deps, repoRoot3) {
|
|
9722
9800
|
let any = false;
|
|
@@ -9807,12 +9885,7 @@ function realDeps7() {
|
|
|
9807
9885
|
nodeVersion: () => process.version,
|
|
9808
9886
|
bunVersion: () => typeof Bun === "undefined" ? null : Bun.version,
|
|
9809
9887
|
packageVersion: readPackageVersion,
|
|
9810
|
-
meteringCapability: () => resolveMeteringCapability(
|
|
9811
|
-
env: process.env,
|
|
9812
|
-
cwd: process.cwd(),
|
|
9813
|
-
exists: existsSync22,
|
|
9814
|
-
readFile: (path) => readFileSync24(path, "utf8")
|
|
9815
|
-
})
|
|
9888
|
+
meteringCapability: () => resolveMeteringCapability(hardenedMeteringDeps())
|
|
9816
9889
|
},
|
|
9817
9890
|
confirm: async (q, defaultYes) => promptYesNo(q, defaultYes),
|
|
9818
9891
|
ask: async (q) => prompt(q),
|
|
@@ -10347,7 +10420,7 @@ Self-verification: clean — re-parsed VERDICT is bound to head ${headSha}.
|
|
|
10347
10420
|
|
|
10348
10421
|
// src/commands/studio.ts
|
|
10349
10422
|
import { execFile as execFile5, spawn as spawn2 } from "node:child_process";
|
|
10350
|
-
import { existsSync as
|
|
10423
|
+
import { existsSync as existsSync22, readFileSync as readFileSync26, renameSync } from "node:fs";
|
|
10351
10424
|
import net from "node:net";
|
|
10352
10425
|
import { dirname as dirname8, join as join25 } from "node:path";
|
|
10353
10426
|
import { promisify as promisify5 } from "node:util";
|
|
@@ -10404,7 +10477,7 @@ function resolveStudioTarget(cwd, moduleUrl = import.meta.url) {
|
|
|
10404
10477
|
for (;; ) {
|
|
10405
10478
|
const webDir = join25(dir, "apps", "vinaya-studio", "web");
|
|
10406
10479
|
const pkgPath = join25(webDir, "package.json");
|
|
10407
|
-
if (
|
|
10480
|
+
if (existsSync22(pkgPath)) {
|
|
10408
10481
|
try {
|
|
10409
10482
|
const pkg = JSON.parse(readFileSync26(pkgPath, "utf-8"));
|
|
10410
10483
|
if (pkg.name === "@atta/vinaya-studio-web") {
|
|
@@ -10412,7 +10485,7 @@ function resolveStudioTarget(cwd, moduleUrl = import.meta.url) {
|
|
|
10412
10485
|
}
|
|
10413
10486
|
} catch {}
|
|
10414
10487
|
}
|
|
10415
|
-
if (
|
|
10488
|
+
if (existsSync22(join25(dir, ".git")))
|
|
10416
10489
|
break;
|
|
10417
10490
|
const parent = dirname8(dir);
|
|
10418
10491
|
if (parent === dir)
|
|
@@ -10420,7 +10493,7 @@ function resolveStudioTarget(cwd, moduleUrl = import.meta.url) {
|
|
|
10420
10493
|
dir = parent;
|
|
10421
10494
|
}
|
|
10422
10495
|
const standaloneWebDir = join25(packageRoot(moduleUrl), "studio-standalone", "apps", "vinaya-studio", "web");
|
|
10423
|
-
if (
|
|
10496
|
+
if (existsSync22(join25(standaloneWebDir, "server.js"))) {
|
|
10424
10497
|
return { kind: "package", packageDir: standaloneWebDir };
|
|
10425
10498
|
}
|
|
10426
10499
|
return { kind: "missing" };
|
|
@@ -10442,7 +10515,7 @@ function isPortFree(port) {
|
|
|
10442
10515
|
function ensureStudioNodeModules(bundleRoot) {
|
|
10443
10516
|
const real = join25(bundleRoot, "node_modules");
|
|
10444
10517
|
const packed = join25(bundleRoot, STUDIO_NODE_MODULES_PACKED_DIRNAME);
|
|
10445
|
-
if (!
|
|
10518
|
+
if (!existsSync22(real) && existsSync22(packed)) {
|
|
10446
10519
|
renameSync(packed, real);
|
|
10447
10520
|
}
|
|
10448
10521
|
}
|
|
@@ -10501,7 +10574,7 @@ async function runStudio(cwd, args, moduleUrl = import.meta.url) {
|
|
|
10501
10574
|
}
|
|
10502
10575
|
|
|
10503
10576
|
// src/commands/upgrade.ts
|
|
10504
|
-
import { existsSync as
|
|
10577
|
+
import { existsSync as existsSync23, readFileSync as readFileSync27, rmSync as rmSync5, writeFileSync as writeFileSync13 } from "node:fs";
|
|
10505
10578
|
import { join as join26 } from "node:path";
|
|
10506
10579
|
function realDeps8() {
|
|
10507
10580
|
return {
|
|
@@ -10521,7 +10594,7 @@ function flags2(args) {
|
|
|
10521
10594
|
}
|
|
10522
10595
|
function readManifest3(repoRoot3) {
|
|
10523
10596
|
const p = join26(repoRoot3, CONFIG_PATH);
|
|
10524
|
-
if (!
|
|
10597
|
+
if (!existsSync23(p))
|
|
10525
10598
|
return { kind: "missing" };
|
|
10526
10599
|
let raw;
|
|
10527
10600
|
try {
|
|
@@ -10549,7 +10622,7 @@ function writeManifestVersion(repoRoot3, manifest) {
|
|
|
10549
10622
|
}
|
|
10550
10623
|
function stripFor(repoRoot3, path, marker, comment) {
|
|
10551
10624
|
const abs2 = resolveManagedBlockPath(repoRoot3, path);
|
|
10552
|
-
if (!
|
|
10625
|
+
if (!existsSync23(abs2))
|
|
10553
10626
|
return { path, marker, comment, present: false, removesHost: false };
|
|
10554
10627
|
const stripped = stripBlockFromContent(readFileSync27(abs2, "utf-8"), marker, comment);
|
|
10555
10628
|
if (stripped === null)
|
|
@@ -10578,7 +10651,7 @@ function planHookRouting(repoRoot3, manifest, recorded, hooksPathValue) {
|
|
|
10578
10651
|
const blocked = [];
|
|
10579
10652
|
for (const b of legacy) {
|
|
10580
10653
|
const abs2 = resolveManagedBlockPath(repoRoot3, b.path);
|
|
10581
|
-
if (!
|
|
10654
|
+
if (!existsSync23(abs2))
|
|
10582
10655
|
continue;
|
|
10583
10656
|
const stripped = stripBlockFromContent(readFileSync27(abs2, "utf-8"), b.marker, b.comment);
|
|
10584
10657
|
if (stripped === null)
|
|
@@ -10620,7 +10693,7 @@ function planUpgrade(ops, repoRoot3, manifest, routing) {
|
|
|
10620
10693
|
for (const op of ops) {
|
|
10621
10694
|
if (op.kind === "create-file") {
|
|
10622
10695
|
const abs2 = join26(repoRoot3, op.path);
|
|
10623
|
-
const exists =
|
|
10696
|
+
const exists = existsSync23(abs2);
|
|
10624
10697
|
const owned = ownedFiles.has(op.path) || isDefaultedAgentVendorPath(op.path, manifest);
|
|
10625
10698
|
let action;
|
|
10626
10699
|
let triggerChange;
|
|
@@ -10653,7 +10726,7 @@ function planUpgrade(ops, repoRoot3, manifest, routing) {
|
|
|
10653
10726
|
let action;
|
|
10654
10727
|
if (!owned) {
|
|
10655
10728
|
action = "not-installed";
|
|
10656
|
-
} else if (!
|
|
10729
|
+
} else if (!existsSync23(abs2)) {
|
|
10657
10730
|
action = "recreate-host";
|
|
10658
10731
|
hasChanges = true;
|
|
10659
10732
|
} else {
|
|
@@ -10791,7 +10864,7 @@ function applyUpgrade(plan, repoRoot3) {
|
|
|
10791
10864
|
if (!s.present)
|
|
10792
10865
|
continue;
|
|
10793
10866
|
const abs2 = resolveManagedBlockPath(repoRoot3, s.path);
|
|
10794
|
-
if (!
|
|
10867
|
+
if (!existsSync23(abs2))
|
|
10795
10868
|
continue;
|
|
10796
10869
|
const stripped = stripBlockFromContent(readFileSync27(abs2, "utf-8"), s.marker, s.comment);
|
|
10797
10870
|
if (stripped === null)
|