@attalabs/vinaya 0.23.0 → 0.24.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 +1 -0
- package/dist/checks/bin/check-body-bare-digits.js +7 -1
- package/dist/checks/bin/check-branch-topology.js +27 -1
- package/dist/checks/bin/check-brief-shape.js +7 -1
- package/dist/checks/bin/check-changeset-coverage.js +7 -1
- package/dist/checks/bin/check-closes-n.js +27 -1
- package/dist/checks/bin/check-coherence.js +27 -1
- package/dist/checks/bin/check-dead-branch-push.js +7 -1
- package/dist/checks/bin/check-dispatch-readiness.js +27 -1
- package/dist/checks/bin/check-doc-coverage-push.js +7 -1
- package/dist/checks/bin/check-doc-coverage.js +7 -1
- package/dist/checks/bin/check-doctrine-no-procedures.js +7 -1
- package/dist/checks/bin/check-doctrine-portability.js +7 -1
- package/dist/checks/bin/check-evidence-fresh.js +7 -1
- package/dist/checks/bin/check-exec-bits.js +7 -1
- package/dist/checks/bin/check-first-push-dispatch.js +27 -1
- package/dist/checks/bin/check-issue-assignment.js +27 -1
- package/dist/checks/bin/check-main-branch-refusal.js +13 -2
- package/dist/checks/bin/check-no-disk-state.js +7 -1
- package/dist/checks/bin/check-pr-report-density.js +7 -1
- package/dist/checks/bin/check-quoted-command.js +38 -12
- package/dist/checks/bin/check-reader-resolvable-prose.js +38 -12
- package/dist/checks/bin/check-registry-gates.js +7 -1
- package/dist/checks/bin/check-retired-vocabulary.js +38 -12
- package/dist/checks/bin/check-review-gate.js +7 -1
- package/dist/checks/bin/check-single-plan-pr.js +7 -1
- package/dist/checks/bin/check-test-plan.js +7 -1
- package/dist/checks/bin/check-token-collection-wired.js +7 -1
- package/dist/checks/bin/check-token-report.js +7 -1
- package/dist/checks/bin/check-workspace-escape.js +7 -1
- package/dist/index.js +362 -87
- package/package.json +1 -1
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/anchored-region.ts +9 -4
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/blast-radius-domains.ts +7 -1
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/brief-render.ts +462 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/brief-validation.ts +405 -4
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/coherence-checks.ts +19 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/consumer-enumeration.ts +75 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/dispatch-gate.ts +44 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doctrine-no-procedures.ts +94 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/doctrine-portability.ts +128 -5
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/gate-audience.ts +3 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/index.ts +25 -3
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/parse-token-report.ts +17 -5
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/pr-report-density.ts +116 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/premise-check.ts +35 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/quoted-command.ts +3 -3
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/review-gate.ts +116 -7
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/review-status.ts +200 -0
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/test-plan-gate.ts +25 -12
- package/studio-standalone/_node_modules/@attalabs/aeg-core/src/verdict-extraction.ts +70 -11
- 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/api/coherence/route.js.nft.json +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/[root-of-the-server]__02a-3g8._.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]__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]__1mcitst._.js → [root-of-the-server]__1pndh3_._.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/_1fqw88f._.js +2 -2
- 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_projects_[name]_tranches_[slug]_05ufo8i._.js +3 -3
- 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/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/{0jer_drkl1e4r.js → 0zebsmmk1bvnb.js} +4 -4
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{20x-t0a0v129z.js → 1uogpj5w2n5ju.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/.next/static/chunks/{2ou_81ahqw31e.js → 3m1kgax7j2vgs.js} +1 -1
- package/studio-standalone/apps/vinaya-studio/web/package.json +2 -2
- /package/studio-standalone/_node_modules/@attalabs/vinaya/studio-standalone/_node_modules/@attalabs/vinaya/studio-standalone/_node_modules/@attalabs/{aeg-core → vinaya/studio-standalone/_node_modules/@attalabs/aeg-core}/bin/verify-coherence.ts +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5xy_GA7G5KRuE3HDumIiw → QY2GhiI47-765D9DHGy1I}/_buildManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5xy_GA7G5KRuE3HDumIiw → QY2GhiI47-765D9DHGy1I}/_clientMiddlewareManifest.js +0 -0
- /package/studio-standalone/apps/vinaya-studio/web/.next/static/{5xy_GA7G5KRuE3HDumIiw → QY2GhiI47-765D9DHGy1I}/_ssgManifest.js +0 -0
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { dirname as dirname9, join as join29 } from "node:path";
|
|
|
6
6
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
7
7
|
|
|
8
8
|
// src/commands/archive.ts
|
|
9
|
-
import { execFileSync as
|
|
9
|
+
import { execFileSync as execFileSync6 } from "node:child_process";
|
|
10
10
|
// ../../packages/aeg-forge-state/src/strip-code.ts
|
|
11
11
|
function maskCode(body) {
|
|
12
12
|
const fill = (line) => " ".repeat(line.length);
|
|
@@ -3444,6 +3444,7 @@ import { readFileSync as readFileSync4 } from "node:fs";
|
|
|
3444
3444
|
import { join as join4 } from "node:path";
|
|
3445
3445
|
|
|
3446
3446
|
// src/commands/doctrine.ts
|
|
3447
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
3447
3448
|
import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync2 } from "node:fs";
|
|
3448
3449
|
import { dirname as dirname2, join as join2, sep } from "node:path";
|
|
3449
3450
|
import matter2 from "gray-matter";
|
|
@@ -3477,10 +3478,29 @@ function packageRoot(moduleUrl) {
|
|
|
3477
3478
|
|
|
3478
3479
|
// src/commands/doctrine.ts
|
|
3479
3480
|
var ENTRY_SEGMENTS = ["skills", "aeg", "SKILL.md"];
|
|
3480
|
-
function resolveDoctrineRoot(pkg = packageRoot(import.meta.url)) {
|
|
3481
|
+
function resolveDoctrineRoot(pkg = packageRoot(import.meta.url), cwd = process.cwd()) {
|
|
3482
|
+
return resolveDoctrineRootInfo(pkg, cwd)?.root ?? null;
|
|
3483
|
+
}
|
|
3484
|
+
function gitToplevel(cwd) {
|
|
3485
|
+
try {
|
|
3486
|
+
return execFileSync2("git", ["-C", cwd, "rev-parse", "--show-toplevel"], {
|
|
3487
|
+
encoding: "utf8",
|
|
3488
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
3489
|
+
}).trim();
|
|
3490
|
+
} catch {
|
|
3491
|
+
return null;
|
|
3492
|
+
}
|
|
3493
|
+
}
|
|
3494
|
+
function resolveDoctrineRootInfo(pkg = packageRoot(import.meta.url), cwd = process.cwd()) {
|
|
3495
|
+
const toplevel = gitToplevel(cwd);
|
|
3496
|
+
if (toplevel !== null) {
|
|
3497
|
+
const treeRoot = join2(toplevel, "aeg-root");
|
|
3498
|
+
if (existsSync2(join2(treeRoot, "roles")))
|
|
3499
|
+
return { root: treeRoot, source: "tree" };
|
|
3500
|
+
}
|
|
3481
3501
|
const fromSource = !pkg.split(sep).includes("node_modules");
|
|
3482
|
-
const
|
|
3483
|
-
return hasDoctrineEntry(
|
|
3502
|
+
const bundleRoot = fromSource ? join2(dirname2(dirname2(pkg)), "aeg-root") : join2(pkg, "aeg-root");
|
|
3503
|
+
return hasDoctrineEntry(bundleRoot) ? { root: bundleRoot, source: "bundle" } : null;
|
|
3484
3504
|
}
|
|
3485
3505
|
var ROLE_ALIASES = { "code-reviewer": "reviewer" };
|
|
3486
3506
|
function hasDoctrineEntry(root) {
|
|
@@ -3550,21 +3570,24 @@ function discoverRoleNames(doctrineRoot) {
|
|
|
3550
3570
|
function agentSkillPath(roleName) {
|
|
3551
3571
|
return `.agents/skills/vinaya-${roleName}/SKILL.md`;
|
|
3552
3572
|
}
|
|
3553
|
-
function
|
|
3573
|
+
function doctrineInvocation(selfHost) {
|
|
3574
|
+
return selfHost ? `bun ${selfHost.dir}/src/index.ts doctrine` : "vinaya doctrine";
|
|
3575
|
+
}
|
|
3576
|
+
function renderAgentSkill(roleName, selfHost = null) {
|
|
3554
3577
|
const roleTitle = formatRoleTitle(roleName);
|
|
3555
3578
|
return `---
|
|
3556
3579
|
name: vinaya-${roleName}
|
|
3557
3580
|
description: Act as the AEG ${roleTitle} for this repo.
|
|
3558
3581
|
---
|
|
3559
|
-
Run
|
|
3582
|
+
Run \`${doctrineInvocation(selfHost)} --role ${roleName}\` and follow its output as your operating instructions for this session.
|
|
3560
3583
|
`;
|
|
3561
3584
|
}
|
|
3562
|
-
function buildAgentsSkillsOps(doctrineRoot) {
|
|
3585
|
+
function buildAgentsSkillsOps(doctrineRoot, selfHost = null) {
|
|
3563
3586
|
const roles = discoverRoleNames(doctrineRoot);
|
|
3564
3587
|
return roles.map((role) => ({
|
|
3565
3588
|
kind: "create-file",
|
|
3566
3589
|
path: agentSkillPath(role),
|
|
3567
|
-
content: renderAgentSkill(role),
|
|
3590
|
+
content: renderAgentSkill(role, selfHost),
|
|
3568
3591
|
group: AGENTS_SKILLS_GROUP
|
|
3569
3592
|
}));
|
|
3570
3593
|
}
|
|
@@ -3572,20 +3595,24 @@ function buildAgentsSkillsOps(doctrineRoot) {
|
|
|
3572
3595
|
// src/lib/claude-command-emitter.ts
|
|
3573
3596
|
var CLAUDE_COMMAND_GROUP = "Claude Code command (.claude/commands/)";
|
|
3574
3597
|
var CLAUDE_COMMAND_PATH = ".claude/commands/vinaya.md";
|
|
3575
|
-
function
|
|
3598
|
+
function doctrineInvocation2(selfHost) {
|
|
3599
|
+
return selfHost ? `bun ${selfHost.dir}/src/index.ts doctrine` : "vinaya doctrine";
|
|
3600
|
+
}
|
|
3601
|
+
function renderClaudeCommand(selfHost = null) {
|
|
3602
|
+
const invocation = doctrineInvocation2(selfHost);
|
|
3576
3603
|
return `---
|
|
3577
3604
|
description: Act as an AEG role for this repo.
|
|
3578
|
-
allowed-tools: Bash(
|
|
3605
|
+
allowed-tools: Bash(${invocation} *)
|
|
3579
3606
|
---
|
|
3580
|
-
|
|
3607
|
+
!\`${invocation} --role "$ARGUMENTS"\`
|
|
3581
3608
|
`;
|
|
3582
3609
|
}
|
|
3583
|
-
function buildClaudeCommandOps() {
|
|
3610
|
+
function buildClaudeCommandOps(selfHost = null) {
|
|
3584
3611
|
return [
|
|
3585
3612
|
{
|
|
3586
3613
|
kind: "create-file",
|
|
3587
3614
|
path: CLAUDE_COMMAND_PATH,
|
|
3588
|
-
content: renderClaudeCommand(),
|
|
3615
|
+
content: renderClaudeCommand(selfHost),
|
|
3589
3616
|
group: CLAUDE_COMMAND_GROUP
|
|
3590
3617
|
}
|
|
3591
3618
|
];
|
|
@@ -3681,16 +3708,19 @@ function buildClaudeStopHookOps() {
|
|
|
3681
3708
|
// src/lib/gemini-command-emitter.ts
|
|
3682
3709
|
var GEMINI_COMMAND_GROUP = "Gemini CLI command (.gemini/commands/)";
|
|
3683
3710
|
var GEMINI_COMMAND_PATH = ".gemini/commands/vinaya.toml";
|
|
3684
|
-
function
|
|
3711
|
+
function doctrineInvocation3(selfHost) {
|
|
3712
|
+
return selfHost ? `bun ${selfHost.dir}/src/index.ts doctrine` : "vinaya doctrine";
|
|
3713
|
+
}
|
|
3714
|
+
function renderGeminiCommand(selfHost = null) {
|
|
3685
3715
|
return `description = "Act as an AEG role for this repo."
|
|
3686
|
-
prompt = "!{
|
|
3716
|
+
prompt = "!{${doctrineInvocation3(selfHost)} --role {{args}}}"
|
|
3687
3717
|
`;
|
|
3688
3718
|
}
|
|
3689
|
-
function buildGeminiCommandOp() {
|
|
3719
|
+
function buildGeminiCommandOp(selfHost = null) {
|
|
3690
3720
|
return {
|
|
3691
3721
|
kind: "create-file",
|
|
3692
3722
|
path: GEMINI_COMMAND_PATH,
|
|
3693
|
-
content: renderGeminiCommand(),
|
|
3723
|
+
content: renderGeminiCommand(selfHost),
|
|
3694
3724
|
group: GEMINI_COMMAND_GROUP
|
|
3695
3725
|
};
|
|
3696
3726
|
}
|
|
@@ -4388,8 +4418,19 @@ function preCommitBody(selfHost) {
|
|
|
4388
4418
|
${hookRun(selfHost, "check --all --diff-only --local --skip-full")}`;
|
|
4389
4419
|
}
|
|
4390
4420
|
function prePushBody(selfHost) {
|
|
4391
|
-
|
|
4421
|
+
const base = `# Vinaya pre-push gate. Runs branch/dispatch checks before the push leaves.
|
|
4422
|
+
# Forward git's own pre-push stdin (one "<local ref> <local sha> <remote
|
|
4423
|
+
# ref> <remote sha>" line per ref being pushed) so main-branch-refusal can
|
|
4424
|
+
# tell a tag-only push apart from one that also carries a branch ref.
|
|
4425
|
+
VINAYA_PUSH_REFS="$(cat)"
|
|
4426
|
+
export VINAYA_PUSH_REFS
|
|
4392
4427
|
${hookRun(selfHost, "check --all --local")}`;
|
|
4428
|
+
if (!selfHost)
|
|
4429
|
+
return base;
|
|
4430
|
+
return `${base}
|
|
4431
|
+
# Ring 0: the affected test suite. A failing test refuses the push with
|
|
4432
|
+
# its own output (#407, O4).
|
|
4433
|
+
bunx turbo test --affected || exit 1`;
|
|
4393
4434
|
}
|
|
4394
4435
|
function commitMsgBody(selfHost) {
|
|
4395
4436
|
return `# Vinaya commit-message gate. Validates the message's first line against
|
|
@@ -4751,14 +4792,14 @@ function buildInitOps(ctx) {
|
|
|
4751
4792
|
if (!doctrineRoot) {
|
|
4752
4793
|
throw new Error('vinaya init: --agents includes "skills" but no bundled doctrine was found next to this CLI install — ' + "cannot discover agent-skill roles. Reinstall @attalabs/vinaya, or run bundle-doctrine first in a repo " + "that vendors the CLI.");
|
|
4753
4794
|
}
|
|
4754
|
-
ops.push(...buildAgentsSkillsOps(doctrineRoot));
|
|
4795
|
+
ops.push(...buildAgentsSkillsOps(doctrineRoot, ctx.selfHost));
|
|
4755
4796
|
}
|
|
4756
4797
|
if (ctx.agents.has("claude")) {
|
|
4757
|
-
ops.push(...buildClaudeCommandOps());
|
|
4798
|
+
ops.push(...buildClaudeCommandOps(ctx.selfHost));
|
|
4758
4799
|
ops.push(...buildClaudeStopHookOps());
|
|
4759
4800
|
}
|
|
4760
4801
|
if (ctx.agents.has("gemini")) {
|
|
4761
|
-
ops.push(buildGeminiCommandOp());
|
|
4802
|
+
ops.push(buildGeminiCommandOp(ctx.selfHost));
|
|
4762
4803
|
}
|
|
4763
4804
|
if (ctx.agents.size > 0) {
|
|
4764
4805
|
const affected = [];
|
|
@@ -4784,12 +4825,12 @@ function buildInitOps(ctx) {
|
|
|
4784
4825
|
}
|
|
4785
4826
|
|
|
4786
4827
|
// src/lib/ops.ts
|
|
4787
|
-
import { execFileSync as
|
|
4828
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
4788
4829
|
import { chmodSync, existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync6, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
4789
4830
|
import { dirname as dirname4, isAbsolute, join as join6, resolve as resolve2, sep as sep2 } from "node:path";
|
|
4790
4831
|
|
|
4791
4832
|
// src/lib/config.ts
|
|
4792
|
-
import { execFileSync as
|
|
4833
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
4793
4834
|
import { createHash as createHash2 } from "node:crypto";
|
|
4794
4835
|
import { existsSync as existsSync4, mkdirSync, readFileSync as readFileSync5, realpathSync, writeFileSync } from "node:fs";
|
|
4795
4836
|
import { homedir } from "node:os";
|
|
@@ -5062,7 +5103,7 @@ function trustAnchorRepo() {
|
|
|
5062
5103
|
return validated;
|
|
5063
5104
|
}
|
|
5064
5105
|
try {
|
|
5065
|
-
const url =
|
|
5106
|
+
const url = execFileSync3("git", ["remote", "get-url", "origin"], {
|
|
5066
5107
|
encoding: "utf-8",
|
|
5067
5108
|
stdio: ["ignore", "pipe", "pipe"]
|
|
5068
5109
|
}).trim();
|
|
@@ -5076,7 +5117,7 @@ function ghFetchTrustAnchorConfig() {
|
|
|
5076
5117
|
const repo = trustAnchorRepo();
|
|
5077
5118
|
if (!repo)
|
|
5078
5119
|
throw new Error("could not resolve repo identity for the trust-anchor read");
|
|
5079
|
-
return
|
|
5120
|
+
return execFileSync3("gh", ["api", `repos/${repo}/contents/${LOCAL_CONFIG_FILENAME}`, "--jq", ".content"], {
|
|
5080
5121
|
encoding: "utf-8",
|
|
5081
5122
|
stdio: ["ignore", "pipe", "pipe"]
|
|
5082
5123
|
});
|
|
@@ -5177,7 +5218,7 @@ function writeTokensCollectTrustStore(storePath, store) {
|
|
|
5177
5218
|
var GIT_IDENTITY_TIMEOUT_MS = 5000;
|
|
5178
5219
|
function gitCommonDir(cwd = process.cwd()) {
|
|
5179
5220
|
try {
|
|
5180
|
-
const raw =
|
|
5221
|
+
const raw = execFileSync3("git", ["rev-parse", "--git-common-dir"], {
|
|
5181
5222
|
cwd,
|
|
5182
5223
|
encoding: "utf-8",
|
|
5183
5224
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -5196,7 +5237,7 @@ function repoLocalConfigDir() {
|
|
|
5196
5237
|
}
|
|
5197
5238
|
function gitBlobHash(absolutePath, cwd) {
|
|
5198
5239
|
try {
|
|
5199
|
-
const raw =
|
|
5240
|
+
const raw = execFileSync3("git", ["hash-object", absolutePath], {
|
|
5200
5241
|
cwd,
|
|
5201
5242
|
encoding: "utf-8",
|
|
5202
5243
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -5247,7 +5288,7 @@ function resolveManagedBlockPath(repoRoot, opPath) {
|
|
|
5247
5288
|
}
|
|
5248
5289
|
function gitCommonDir2(repoRoot) {
|
|
5249
5290
|
try {
|
|
5250
|
-
const commonDir =
|
|
5291
|
+
const commonDir = execFileSync4("git", ["-C", repoRoot, "rev-parse", "--git-common-dir"], {
|
|
5251
5292
|
encoding: "utf8"
|
|
5252
5293
|
}).trim();
|
|
5253
5294
|
if (commonDir === "")
|
|
@@ -5826,7 +5867,7 @@ function closeStdin() {
|
|
|
5826
5867
|
}
|
|
5827
5868
|
|
|
5828
5869
|
// src/commands/tokens.ts
|
|
5829
|
-
import { execFileSync as
|
|
5870
|
+
import { execFileSync as execFileSync5 } from "node:child_process";
|
|
5830
5871
|
import { resolve as resolvePath } from "node:path";
|
|
5831
5872
|
var USAGE = [
|
|
5832
5873
|
'Usage: vinaya tokens --phase "<task-id>: develop" --role Developer',
|
|
@@ -5981,7 +6022,7 @@ function realDeps() {
|
|
|
5981
6022
|
...hardenedMeteringDeps(),
|
|
5982
6023
|
loadConfig,
|
|
5983
6024
|
repoConfigDir: repoLocalConfigDir,
|
|
5984
|
-
runScript: (interpreter, scriptAbsolutePath, cwd) =>
|
|
6025
|
+
runScript: (interpreter, scriptAbsolutePath, cwd) => execFileSync5(interpreter, [scriptAbsolutePath], { cwd, encoding: "utf-8", timeout: COLLECT_COMMAND_TIMEOUT_MS }),
|
|
5985
6026
|
warn: (message) => console.error(message),
|
|
5986
6027
|
gitCommonDir,
|
|
5987
6028
|
scriptContentHash: gitBlobHash,
|
|
@@ -6107,7 +6148,7 @@ function renderArchiveTokensLine(capability, phase, role) {
|
|
|
6107
6148
|
return { line: formatTokensLine({ phase, role, summary: capability.summary }), dangling: null };
|
|
6108
6149
|
}
|
|
6109
6150
|
function sh(args, input) {
|
|
6110
|
-
return
|
|
6151
|
+
return execFileSync6(args[0], args.slice(1), { encoding: "utf8", input, env: process.env }).trim();
|
|
6111
6152
|
}
|
|
6112
6153
|
function shJson(args) {
|
|
6113
6154
|
return JSON.parse(sh(args));
|
|
@@ -6321,7 +6362,7 @@ async function archiveTrancheCommand(args) {
|
|
|
6321
6362
|
}
|
|
6322
6363
|
|
|
6323
6364
|
// src/commands/audit.ts
|
|
6324
|
-
import { execFileSync as
|
|
6365
|
+
import { execFileSync as execFileSync7 } from "node:child_process";
|
|
6325
6366
|
function ring2Accelerated2() {
|
|
6326
6367
|
return loadConfig()?.rings?.ring2_asyncAudits === true;
|
|
6327
6368
|
}
|
|
@@ -6340,7 +6381,7 @@ var DIRECT_PUSH_MARKER = `<!-- ${DIRECT_PUSH_LABEL} -->`;
|
|
|
6340
6381
|
var DIRECT_PUSH_LABEL_DESCRIPTION = "A commit landed on main with no associated merged PR (ring-2 detection)";
|
|
6341
6382
|
function shSoft(args, input) {
|
|
6342
6383
|
try {
|
|
6343
|
-
return
|
|
6384
|
+
return execFileSync7(args[0], args.slice(1), {
|
|
6344
6385
|
encoding: "utf8",
|
|
6345
6386
|
input,
|
|
6346
6387
|
timeout: COMMAND_TIMEOUT_MS
|
|
@@ -6364,7 +6405,7 @@ function shSoftJson(args) {
|
|
|
6364
6405
|
}
|
|
6365
6406
|
}
|
|
6366
6407
|
function sh2(args, input) {
|
|
6367
|
-
return
|
|
6408
|
+
return execFileSync7(args[0], args.slice(1), { encoding: "utf8", input }).trim();
|
|
6368
6409
|
}
|
|
6369
6410
|
function listTaskBranches() {
|
|
6370
6411
|
const out = shSoft(["git", "ls-remote", "--heads", "origin", "task/*"]);
|
|
@@ -6625,7 +6666,7 @@ async function auditCommand(args) {
|
|
|
6625
6666
|
|
|
6626
6667
|
// src/commands/brief.ts
|
|
6627
6668
|
import { createHash as createHash3 } from "node:crypto";
|
|
6628
|
-
import { execFileSync as
|
|
6669
|
+
import { execFileSync as execFileSync9 } from "node:child_process";
|
|
6629
6670
|
import { existsSync as existsSync7, readFileSync as readFileSync9, readdirSync as readdirSync5, writeFileSync as writeFileSync3 } from "node:fs";
|
|
6630
6671
|
import { join as join9 } from "node:path";
|
|
6631
6672
|
|
|
@@ -7112,6 +7153,26 @@ var COMMANDS = [
|
|
|
7112
7153
|
"Never reimplements or edits `init`/`init product`/`demo break`/`doctor` — it only calls their existing, unmodified entry points in sequence."
|
|
7113
7154
|
],
|
|
7114
7155
|
status: "shipped"
|
|
7156
|
+
},
|
|
7157
|
+
{
|
|
7158
|
+
name: "release",
|
|
7159
|
+
description: "Run this repo's own publish sequence in one command, refusing to start unless every precondition holds",
|
|
7160
|
+
flags: [
|
|
7161
|
+
{
|
|
7162
|
+
flag: "--dry-run",
|
|
7163
|
+
description: "Run the preconditions only and print the plan; publishes nothing"
|
|
7164
|
+
},
|
|
7165
|
+
{
|
|
7166
|
+
flag: "--allow-any-commit",
|
|
7167
|
+
description: "Skip the check that HEAD's commit is a Version Packages commit"
|
|
7168
|
+
}
|
|
7169
|
+
],
|
|
7170
|
+
details: [
|
|
7171
|
+
"Refuses unless HEAD is the default branch, the working tree is clean, HEAD equals `origin/<default>` (after `git fetch origin`), HEAD's commit subject starts with `Chore(release): Version packages` (unless `--allow-any-commit`), and `npm whoami` exits `0` — each its own refusal naming the fix.",
|
|
7172
|
+
"Then streams `bun install --frozen-lockfile`, `bun run build`, `bun run changeset:publish`, and `git push origin --tags` — a real push, so the repo's own generated pre-push hook sees it exactly as any other push would. After it, prints `npm view <pkg> version` for every tag now on HEAD, noting registry lag on `@attalabs/vinaya` (observed ~20 minutes) when it still shows the previous version.",
|
|
7173
|
+
'This is the one procedure named in `apps/cli/specs/self-hosting.md`, "How the published version is produced" — publishing itself stays manual and human-triggered; this command only removes the hand-typed four-step recipe.'
|
|
7174
|
+
],
|
|
7175
|
+
status: "shipped"
|
|
7115
7176
|
}
|
|
7116
7177
|
];
|
|
7117
7178
|
// ../../packages/sources/src/doctrine-file-adapter.ts
|
|
@@ -7155,7 +7216,7 @@ var StateSourceConfigSchema = z2.discriminatedUnion("kind", [
|
|
|
7155
7216
|
z2.object({ kind: z2.literal("file"), root: z2.string().optional() })
|
|
7156
7217
|
]);
|
|
7157
7218
|
// src/checks/edge-resolve.ts
|
|
7158
|
-
import { execFileSync as
|
|
7219
|
+
import { execFileSync as execFileSync8 } from "node:child_process";
|
|
7159
7220
|
var DIRECT_ISSUE_REF = /#(\d+)/;
|
|
7160
7221
|
var issueCache = new Map;
|
|
7161
7222
|
function fetchIssueState(num, repo) {
|
|
@@ -7164,7 +7225,7 @@ function fetchIssueState(num, repo) {
|
|
|
7164
7225
|
return issueCache.get(key) ?? null;
|
|
7165
7226
|
let out = null;
|
|
7166
7227
|
try {
|
|
7167
|
-
const raw =
|
|
7228
|
+
const raw = execFileSync8("gh", [
|
|
7168
7229
|
"issue",
|
|
7169
7230
|
"view",
|
|
7170
7231
|
String(num),
|
|
@@ -7277,7 +7338,7 @@ var DOC_OWNERS_PATH2 = ".vinaya/doc-owners";
|
|
|
7277
7338
|
var TEMPLATE_PATH = "aeg-root/templates/brief-template.md";
|
|
7278
7339
|
function git(args) {
|
|
7279
7340
|
try {
|
|
7280
|
-
return
|
|
7341
|
+
return execFileSync9("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
7281
7342
|
} catch {
|
|
7282
7343
|
return "";
|
|
7283
7344
|
}
|
|
@@ -7304,7 +7365,7 @@ async function resolveToken() {
|
|
|
7304
7365
|
if (process.env.GH_TOKEN)
|
|
7305
7366
|
return process.env.GH_TOKEN;
|
|
7306
7367
|
try {
|
|
7307
|
-
return
|
|
7368
|
+
return execFileSync9("gh", ["auth", "token"], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim() || null;
|
|
7308
7369
|
} catch {
|
|
7309
7370
|
return null;
|
|
7310
7371
|
}
|
|
@@ -7465,7 +7526,7 @@ ${result.missing.map((m) => ` - ${m}`).join(`
|
|
|
7465
7526
|
}
|
|
7466
7527
|
|
|
7467
7528
|
// src/commands/check.ts
|
|
7468
|
-
import { execFileSync as
|
|
7529
|
+
import { execFileSync as execFileSync10 } from "node:child_process";
|
|
7469
7530
|
import { dirname as dirname5 } from "node:path";
|
|
7470
7531
|
|
|
7471
7532
|
// src/checks/contract.ts
|
|
@@ -8418,7 +8479,7 @@ async function buildRolePlan(configDir, configRoles) {
|
|
|
8418
8479
|
// src/commands/check.ts
|
|
8419
8480
|
function git2(args) {
|
|
8420
8481
|
try {
|
|
8421
|
-
return
|
|
8482
|
+
return execFileSync10("git", args, { encoding: "utf8" }).trim();
|
|
8422
8483
|
} catch {
|
|
8423
8484
|
return "";
|
|
8424
8485
|
}
|
|
@@ -8682,14 +8743,14 @@ function commitMsgCommand(args) {
|
|
|
8682
8743
|
}
|
|
8683
8744
|
|
|
8684
8745
|
// src/commands/demo.ts
|
|
8685
|
-
import { execFileSync as
|
|
8746
|
+
import { execFileSync as execFileSync11, spawnSync } from "node:child_process";
|
|
8686
8747
|
import { existsSync as existsSync10, readFileSync as readFileSync12, rmSync as rmSync2, unlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
8687
8748
|
import { isAbsolute as isAbsolute2, join as join12 } from "node:path";
|
|
8688
8749
|
var DEMO_BRANCH_PREFIX = "vinaya/demo-break-";
|
|
8689
8750
|
var FIXTURE_PATH = ".vinaya-demo-brief.md";
|
|
8690
8751
|
var STATE_FILENAME = "vinaya-demo-state.json";
|
|
8691
8752
|
function gitCapture(repoRoot, args) {
|
|
8692
|
-
return
|
|
8753
|
+
return execFileSync11("git", args, { cwd: repoRoot, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
8693
8754
|
}
|
|
8694
8755
|
function currentBranchName(repoRoot) {
|
|
8695
8756
|
try {
|
|
@@ -8700,7 +8761,7 @@ function currentBranchName(repoRoot) {
|
|
|
8700
8761
|
}
|
|
8701
8762
|
function branchExists(repoRoot, name) {
|
|
8702
8763
|
try {
|
|
8703
|
-
|
|
8764
|
+
execFileSync11("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${name}`], {
|
|
8704
8765
|
cwd: repoRoot,
|
|
8705
8766
|
stdio: ["ignore", "pipe", "pipe"]
|
|
8706
8767
|
});
|
|
@@ -8902,7 +8963,7 @@ async function demoBreakCommand(args) {
|
|
|
8902
8963
|
}
|
|
8903
8964
|
|
|
8904
8965
|
// src/commands/doctor.ts
|
|
8905
|
-
import { execFileSync as
|
|
8966
|
+
import { execFileSync as execFileSync12 } from "node:child_process";
|
|
8906
8967
|
import { existsSync as existsSync13, readdirSync as readdirSync7, readFileSync as readFileSync16, statSync as statSync2 } from "node:fs";
|
|
8907
8968
|
import { delimiter, join as join15 } from "node:path";
|
|
8908
8969
|
|
|
@@ -9328,7 +9389,7 @@ function diagnoseCustomChecks(repoRoot, config) {
|
|
|
9328
9389
|
}
|
|
9329
9390
|
function listTrackedFiles(repoRoot) {
|
|
9330
9391
|
try {
|
|
9331
|
-
return
|
|
9392
|
+
return execFileSync12("git", ["ls-files"], { cwd: repoRoot, encoding: "utf-8" }).split(`
|
|
9332
9393
|
`).map((s) => s.trim()).filter(Boolean);
|
|
9333
9394
|
} catch {
|
|
9334
9395
|
return [];
|
|
@@ -9593,10 +9654,15 @@ function symbolFor(severity) {
|
|
|
9593
9654
|
return "✗";
|
|
9594
9655
|
}
|
|
9595
9656
|
}
|
|
9596
|
-
function printReport(findings, healthy) {
|
|
9657
|
+
function printReport(findings, healthy, doctrineInfo) {
|
|
9597
9658
|
process.stdout.write(`vinaya doctor
|
|
9598
9659
|
|
|
9599
9660
|
`);
|
|
9661
|
+
if (doctrineInfo) {
|
|
9662
|
+
process.stdout.write(`doctrine: ${doctrineInfo.root} (${doctrineInfo.source})
|
|
9663
|
+
|
|
9664
|
+
`);
|
|
9665
|
+
}
|
|
9600
9666
|
for (const f of findings) {
|
|
9601
9667
|
process.stdout.write(`${symbolFor(f.severity)} [${f.check}] ${f.message}
|
|
9602
9668
|
`);
|
|
@@ -9612,6 +9678,7 @@ async function runDoctor(args, deps) {
|
|
|
9612
9678
|
console.error("Error: not a git repository. Run `vinaya doctor` from inside your repo.");
|
|
9613
9679
|
return 1;
|
|
9614
9680
|
}
|
|
9681
|
+
const doctrineInfo = resolveDoctrineRootInfo(undefined, repo.repoRoot);
|
|
9615
9682
|
const configRead = readConfig(repo.repoRoot);
|
|
9616
9683
|
const findings = [];
|
|
9617
9684
|
let hasDrift = false;
|
|
@@ -9654,7 +9721,7 @@ async function runDoctor(args, deps) {
|
|
|
9654
9721
|
if (jsonOutput) {
|
|
9655
9722
|
printJson({ healthy, findings });
|
|
9656
9723
|
} else {
|
|
9657
|
-
printReport(findings, healthy);
|
|
9724
|
+
printReport(findings, healthy, doctrineInfo);
|
|
9658
9725
|
}
|
|
9659
9726
|
return healthy ? 0 : 1;
|
|
9660
9727
|
}
|
|
@@ -9978,10 +10045,10 @@ async function initProductCommand(args) {
|
|
|
9978
10045
|
}
|
|
9979
10046
|
|
|
9980
10047
|
// src/commands/issue.ts
|
|
9981
|
-
import { execFileSync as
|
|
10048
|
+
import { execFileSync as execFileSync14 } from "node:child_process";
|
|
9982
10049
|
|
|
9983
10050
|
// src/lib/forge-write.ts
|
|
9984
|
-
import { execFileSync as
|
|
10051
|
+
import { execFileSync as execFileSync13 } from "node:child_process";
|
|
9985
10052
|
import { existsSync as existsSync16, mkdtempSync, readdirSync as readdirSync8, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "node:fs";
|
|
9986
10053
|
import { readFileSync as readFileSync19 } from "node:fs";
|
|
9987
10054
|
import { tmpdir } from "node:os";
|
|
@@ -10075,7 +10142,7 @@ function ensureTrancheLabelExists(slug) {
|
|
|
10075
10142
|
const name = trancheLabel(slug);
|
|
10076
10143
|
let existing;
|
|
10077
10144
|
try {
|
|
10078
|
-
const out =
|
|
10145
|
+
const out = execFileSync13("gh", ["label", "list", "--json", "name", "--limit", "200"], {
|
|
10079
10146
|
encoding: "utf8",
|
|
10080
10147
|
stdio: ["ignore", "pipe", "pipe"]
|
|
10081
10148
|
});
|
|
@@ -10088,7 +10155,7 @@ function ensureTrancheLabelExists(slug) {
|
|
|
10088
10155
|
if (existing.some((l) => l.name === name))
|
|
10089
10156
|
return;
|
|
10090
10157
|
try {
|
|
10091
|
-
|
|
10158
|
+
execFileSync13("gh", ["label", "create", name, "--color", TRANCHE_LABEL_COLOR, "--description", `Tranche: ${slug}`], {
|
|
10092
10159
|
encoding: "utf8",
|
|
10093
10160
|
stdio: ["ignore", "pipe", "pipe"]
|
|
10094
10161
|
});
|
|
@@ -10240,7 +10307,7 @@ function validateForgeWrite(input) {
|
|
|
10240
10307
|
}
|
|
10241
10308
|
function git3(args) {
|
|
10242
10309
|
try {
|
|
10243
|
-
return
|
|
10310
|
+
return execFileSync13("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
10244
10311
|
} catch {
|
|
10245
10312
|
return "";
|
|
10246
10313
|
}
|
|
@@ -10335,7 +10402,7 @@ function locateBodyOrRefuse(ghArgs, retryCommand) {
|
|
|
10335
10402
|
function fetchForgeLabels(issueRef) {
|
|
10336
10403
|
let out;
|
|
10337
10404
|
try {
|
|
10338
|
-
out =
|
|
10405
|
+
out = execFileSync14("gh", ["issue", "view", issueRef, "--json", "labels"], {
|
|
10339
10406
|
encoding: "utf8",
|
|
10340
10407
|
stdio: ["ignore", "pipe", "pipe"]
|
|
10341
10408
|
});
|
|
@@ -10363,7 +10430,7 @@ function reportPass(json, command) {
|
|
|
10363
10430
|
function runGhWrite(ghCmd, ghArgs, bodyResult, json) {
|
|
10364
10431
|
const { finalArgs, cleanup: cleanup2 } = resolveShippableArgs(ghArgs, bodyResult);
|
|
10365
10432
|
try {
|
|
10366
|
-
const out =
|
|
10433
|
+
const out = execFileSync14("gh", [...ghCmd, ...finalArgs], { encoding: "utf8", stdio: ["ignore", "pipe", "inherit"] });
|
|
10367
10434
|
const url = out.trim();
|
|
10368
10435
|
if (json)
|
|
10369
10436
|
printJson({ validated: true, written: true, url });
|
|
@@ -10449,13 +10516,13 @@ function issueEditCommand(args) {
|
|
|
10449
10516
|
}
|
|
10450
10517
|
|
|
10451
10518
|
// src/commands/milestone.ts
|
|
10452
|
-
import { execFileSync as
|
|
10519
|
+
import { execFileSync as execFileSync15 } from "node:child_process";
|
|
10453
10520
|
var RETRY_CREATE2 = "vinaya milestone create --title <title> --body-file <path>";
|
|
10454
10521
|
var RETRY_ADOPT = "vinaya milestone adopt --target <title> --slug <slug> [--slug <slug> ...]";
|
|
10455
10522
|
var RETRY_EDIT2 = "vinaya milestone edit <n> --body-file <path>";
|
|
10456
10523
|
var RETRY_CLOSE = "vinaya milestone close --slug <slug>";
|
|
10457
10524
|
function sh3(args, input) {
|
|
10458
|
-
return
|
|
10525
|
+
return execFileSync15(args[0], args.slice(1), {
|
|
10459
10526
|
encoding: "utf8",
|
|
10460
10527
|
input,
|
|
10461
10528
|
env: process.env,
|
|
@@ -10955,7 +11022,7 @@ ${registration}
|
|
|
10955
11022
|
}
|
|
10956
11023
|
|
|
10957
11024
|
// src/commands/pr.ts
|
|
10958
|
-
import { execFileSync as
|
|
11025
|
+
import { execFileSync as execFileSync16 } from "node:child_process";
|
|
10959
11026
|
import { rmSync as rmSync4, writeFileSync as writeFileSync11 } from "node:fs";
|
|
10960
11027
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
10961
11028
|
import { join as join22 } from "node:path";
|
|
@@ -11250,7 +11317,7 @@ var RETRY_CREATE3 = "vinaya pr create --validate-only …";
|
|
|
11250
11317
|
var RETRY_EDIT3 = "vinaya pr edit <n> --validate-only …";
|
|
11251
11318
|
function git4(args) {
|
|
11252
11319
|
try {
|
|
11253
|
-
return
|
|
11320
|
+
return execFileSync16("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
11254
11321
|
} catch {
|
|
11255
11322
|
return "";
|
|
11256
11323
|
}
|
|
@@ -11284,7 +11351,7 @@ function reportPass2(json, command) {
|
|
|
11284
11351
|
function runGhWrite2(ghCmd, ghArgs, bodyResult, json) {
|
|
11285
11352
|
const { finalArgs, cleanup: cleanup2 } = resolveShippableArgs(ghArgs, bodyResult);
|
|
11286
11353
|
try {
|
|
11287
|
-
const out =
|
|
11354
|
+
const out = execFileSync16("gh", [...ghCmd, ...finalArgs], { encoding: "utf8", stdio: ["ignore", "pipe", "inherit"] });
|
|
11288
11355
|
const url = out.trim();
|
|
11289
11356
|
if (json)
|
|
11290
11357
|
printJson({ validated: true, written: true, url });
|
|
@@ -11299,7 +11366,7 @@ function runGhWrite2(ghCmd, ghArgs, bodyResult, json) {
|
|
|
11299
11366
|
function fetchPrForgeContext(prRef) {
|
|
11300
11367
|
let viewOut;
|
|
11301
11368
|
try {
|
|
11302
|
-
viewOut =
|
|
11369
|
+
viewOut = execFileSync16("gh", ["pr", "view", prRef, "--json", "headRefName,files"], {
|
|
11303
11370
|
encoding: "utf8",
|
|
11304
11371
|
stdio: ["ignore", "pipe", "pipe"]
|
|
11305
11372
|
});
|
|
@@ -11353,7 +11420,7 @@ ${brief}
|
|
|
11353
11420
|
const tmp = join22(tmpdir2(), `vinaya-pr-create-brief-${process.pid}-${Date.now()}.md`);
|
|
11354
11421
|
writeFileSync11(tmp, commentBody);
|
|
11355
11422
|
try {
|
|
11356
|
-
|
|
11423
|
+
execFileSync16("gh", ["pr", "comment", prNumber, "--body-file", tmp], {
|
|
11357
11424
|
encoding: "utf8",
|
|
11358
11425
|
stdio: ["ignore", "pipe", "pipe"]
|
|
11359
11426
|
});
|
|
@@ -11476,7 +11543,7 @@ function prEditCommand(args) {
|
|
|
11476
11543
|
}
|
|
11477
11544
|
|
|
11478
11545
|
// src/commands/pr-report.ts
|
|
11479
|
-
import { execFileSync as
|
|
11546
|
+
import { execFileSync as execFileSync17, spawnSync as spawnSync2 } from "node:child_process";
|
|
11480
11547
|
import { existsSync as existsSync20, mkdtempSync as mkdtempSync2, readFileSync as readFileSync23, rmSync as rmSync5, writeFileSync as writeFileSync12 } from "node:fs";
|
|
11481
11548
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
11482
11549
|
import { join as join23 } from "node:path";
|
|
@@ -11484,14 +11551,14 @@ var EVIDENCE_START = "<!-- AEG:EVIDENCE:START -->";
|
|
|
11484
11551
|
var EVIDENCE_END = "<!-- AEG:EVIDENCE:END -->";
|
|
11485
11552
|
function git5(args) {
|
|
11486
11553
|
try {
|
|
11487
|
-
return
|
|
11554
|
+
return execFileSync17("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
11488
11555
|
} catch {
|
|
11489
11556
|
return "";
|
|
11490
11557
|
}
|
|
11491
11558
|
}
|
|
11492
11559
|
function gh(args) {
|
|
11493
11560
|
try {
|
|
11494
|
-
return
|
|
11561
|
+
return execFileSync17("gh", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
11495
11562
|
} catch (err) {
|
|
11496
11563
|
const stderr = err.stderr;
|
|
11497
11564
|
throw new Error(String(stderr ?? err.message).trim() || "gh command failed");
|
|
@@ -11510,7 +11577,7 @@ class GitCommandError extends Error {
|
|
|
11510
11577
|
}
|
|
11511
11578
|
function gitStrict(args) {
|
|
11512
11579
|
try {
|
|
11513
|
-
return
|
|
11580
|
+
return execFileSync17("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
11514
11581
|
} catch (err) {
|
|
11515
11582
|
const stderr = err.stderr;
|
|
11516
11583
|
throw new GitCommandError(args, String(stderr ?? err.message).trim() || "non-zero exit");
|
|
@@ -12028,7 +12095,7 @@ The AEG:EVIDENCE block was still written to ${writePath}.`);
|
|
|
12028
12095
|
}
|
|
12029
12096
|
|
|
12030
12097
|
// src/commands/pr-verify-evidence.ts
|
|
12031
|
-
import { execFileSync as
|
|
12098
|
+
import { execFileSync as execFileSync18 } from "node:child_process";
|
|
12032
12099
|
|
|
12033
12100
|
// src/commands/pr-verify-evidence-logic.ts
|
|
12034
12101
|
function publishedMergeBase(region) {
|
|
@@ -12115,10 +12182,10 @@ function renderVerdict(verdict) {
|
|
|
12115
12182
|
|
|
12116
12183
|
// src/commands/pr-verify-evidence.ts
|
|
12117
12184
|
function gh2(args) {
|
|
12118
|
-
return
|
|
12185
|
+
return execFileSync18("gh", args, { encoding: "utf8", maxBuffer: 32 * 1024 * 1024 });
|
|
12119
12186
|
}
|
|
12120
12187
|
function assertCleanWorktree() {
|
|
12121
|
-
const dirty =
|
|
12188
|
+
const dirty = execFileSync18("git", ["status", "--porcelain"], {
|
|
12122
12189
|
encoding: "utf8",
|
|
12123
12190
|
cwd: repoRoot2()
|
|
12124
12191
|
}).trim();
|
|
@@ -12155,7 +12222,7 @@ function assertRepoRootCwd() {
|
|
|
12155
12222
|
process.exit(2);
|
|
12156
12223
|
}
|
|
12157
12224
|
function repoRoot2() {
|
|
12158
|
-
return
|
|
12225
|
+
return execFileSync18("git", ["rev-parse", "--show-toplevel"], { encoding: "utf8" }).trim();
|
|
12159
12226
|
}
|
|
12160
12227
|
async function prVerifyEvidenceCommand(args) {
|
|
12161
12228
|
const prRef = args[0] && !args[0].startsWith("-") ? args[0] : undefined;
|
|
@@ -12179,7 +12246,7 @@ async function prVerifyEvidenceCommand(args) {
|
|
|
12179
12246
|
process.exit(1);
|
|
12180
12247
|
return;
|
|
12181
12248
|
}
|
|
12182
|
-
const localHead =
|
|
12249
|
+
const localHead = execFileSync18("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim();
|
|
12183
12250
|
if (!forgeHead) {
|
|
12184
12251
|
process.stderr.write(`pr verify-evidence: REFUSED — could not read #${prRef}'s head from the forge, so the verdict cannot be bound to a commit.
|
|
12185
12252
|
`);
|
|
@@ -12202,7 +12269,7 @@ async function prVerifyEvidenceCommand(args) {
|
|
|
12202
12269
|
}
|
|
12203
12270
|
|
|
12204
12271
|
// src/commands/quickstart.ts
|
|
12205
|
-
import { execFileSync as
|
|
12272
|
+
import { execFileSync as execFileSync19 } from "node:child_process";
|
|
12206
12273
|
import { existsSync as existsSync22, readFileSync as readFileSync25 } from "node:fs";
|
|
12207
12274
|
import { join as join25 } from "node:path";
|
|
12208
12275
|
|
|
@@ -12402,7 +12469,7 @@ function realDeps7() {
|
|
|
12402
12469
|
};
|
|
12403
12470
|
}
|
|
12404
12471
|
function execGit(repoRoot3, args) {
|
|
12405
|
-
return
|
|
12472
|
+
return execFileSync19("git", args, { cwd: repoRoot3, encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
12406
12473
|
}
|
|
12407
12474
|
function errorDetail(err) {
|
|
12408
12475
|
const stderr = err.stderr;
|
|
@@ -12535,8 +12602,212 @@ async function quickstartCommand(args) {
|
|
|
12535
12602
|
process.exit(await runQuickstart(args, realDeps7()));
|
|
12536
12603
|
}
|
|
12537
12604
|
|
|
12605
|
+
// src/commands/release.ts
|
|
12606
|
+
import { execFileSync as execFileSync20 } from "node:child_process";
|
|
12607
|
+
function realDeps8() {
|
|
12608
|
+
const git6 = (args) => {
|
|
12609
|
+
try {
|
|
12610
|
+
return execFileSync20("git", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
12611
|
+
} catch {
|
|
12612
|
+
return null;
|
|
12613
|
+
}
|
|
12614
|
+
};
|
|
12615
|
+
return {
|
|
12616
|
+
currentBranch() {
|
|
12617
|
+
const branch = git6(["symbolic-ref", "--quiet", "--short", "HEAD"]);
|
|
12618
|
+
return branch === null || branch === "" ? null : branch;
|
|
12619
|
+
},
|
|
12620
|
+
defaultBranch() {
|
|
12621
|
+
const ref = git6(["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"]);
|
|
12622
|
+
if (ref === null || !ref.startsWith("origin/"))
|
|
12623
|
+
return null;
|
|
12624
|
+
const branch = ref.slice("origin/".length);
|
|
12625
|
+
return branch === "" ? null : branch;
|
|
12626
|
+
},
|
|
12627
|
+
fetchOrigin() {
|
|
12628
|
+
try {
|
|
12629
|
+
execFileSync20("git", ["fetch", "origin"], { stdio: "inherit" });
|
|
12630
|
+
return true;
|
|
12631
|
+
} catch {
|
|
12632
|
+
return false;
|
|
12633
|
+
}
|
|
12634
|
+
},
|
|
12635
|
+
treeIsClean() {
|
|
12636
|
+
const status = git6(["status", "--porcelain"]);
|
|
12637
|
+
return status === "";
|
|
12638
|
+
},
|
|
12639
|
+
headSha() {
|
|
12640
|
+
return git6(["rev-parse", "HEAD"]);
|
|
12641
|
+
},
|
|
12642
|
+
defaultBranchSha(defaultBranch) {
|
|
12643
|
+
return git6(["rev-parse", `origin/${defaultBranch}`]);
|
|
12644
|
+
},
|
|
12645
|
+
headSubject() {
|
|
12646
|
+
return git6(["log", "-1", "--format=%s"]) ?? "";
|
|
12647
|
+
},
|
|
12648
|
+
npmWhoami() {
|
|
12649
|
+
try {
|
|
12650
|
+
execFileSync20("npm", ["whoami"], { stdio: "ignore" });
|
|
12651
|
+
return true;
|
|
12652
|
+
} catch {
|
|
12653
|
+
return false;
|
|
12654
|
+
}
|
|
12655
|
+
},
|
|
12656
|
+
runStreamed(cmd, args) {
|
|
12657
|
+
execFileSync20(cmd, args, { stdio: "inherit" });
|
|
12658
|
+
},
|
|
12659
|
+
tagsAtHead() {
|
|
12660
|
+
const tags = git6(["tag", "--points-at", "HEAD"]);
|
|
12661
|
+
if (tags === null || tags === "")
|
|
12662
|
+
return [];
|
|
12663
|
+
return tags.split(`
|
|
12664
|
+
`).filter((t) => t.length > 0);
|
|
12665
|
+
},
|
|
12666
|
+
npmViewVersion(pkg) {
|
|
12667
|
+
try {
|
|
12668
|
+
const out = execFileSync20("npm", ["view", pkg, "version"], {
|
|
12669
|
+
encoding: "utf8",
|
|
12670
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
12671
|
+
}).trim();
|
|
12672
|
+
return out === "" ? null : out;
|
|
12673
|
+
} catch {
|
|
12674
|
+
return null;
|
|
12675
|
+
}
|
|
12676
|
+
},
|
|
12677
|
+
log(message) {
|
|
12678
|
+
process.stdout.write(`${message}
|
|
12679
|
+
`);
|
|
12680
|
+
}
|
|
12681
|
+
};
|
|
12682
|
+
}
|
|
12683
|
+
var RELEASE_PLAN = [
|
|
12684
|
+
["bun", "install", "--frozen-lockfile"],
|
|
12685
|
+
["bun", "run", "build"],
|
|
12686
|
+
["bun", "run", "changeset:publish"],
|
|
12687
|
+
["git", "push", "origin", "--tags"]
|
|
12688
|
+
];
|
|
12689
|
+
function parseTag(tag) {
|
|
12690
|
+
const at = tag.lastIndexOf("@");
|
|
12691
|
+
if (at <= 0)
|
|
12692
|
+
return null;
|
|
12693
|
+
return { pkg: tag.slice(0, at), version: tag.slice(at + 1) };
|
|
12694
|
+
}
|
|
12695
|
+
function runRelease(opts, deps) {
|
|
12696
|
+
const current = deps.currentBranch();
|
|
12697
|
+
const defaultBranch = deps.defaultBranch();
|
|
12698
|
+
if (defaultBranch === null) {
|
|
12699
|
+
return {
|
|
12700
|
+
ok: false,
|
|
12701
|
+
message: "vinaya release: could not determine this repo's default branch (no resolvable `origin/HEAD`) — run `git remote set-head origin -a` first."
|
|
12702
|
+
};
|
|
12703
|
+
}
|
|
12704
|
+
if (current !== defaultBranch) {
|
|
12705
|
+
return {
|
|
12706
|
+
ok: false,
|
|
12707
|
+
message: `vinaya release: HEAD is on \`${current ?? "(detached)"}\`, not the default branch \`${defaultBranch}\` — check out \`${defaultBranch}\` first.`
|
|
12708
|
+
};
|
|
12709
|
+
}
|
|
12710
|
+
if (!deps.treeIsClean()) {
|
|
12711
|
+
return {
|
|
12712
|
+
ok: false,
|
|
12713
|
+
message: "vinaya release: working tree is dirty — commit or stash your changes first."
|
|
12714
|
+
};
|
|
12715
|
+
}
|
|
12716
|
+
if (!deps.fetchOrigin()) {
|
|
12717
|
+
return {
|
|
12718
|
+
ok: false,
|
|
12719
|
+
message: "vinaya release: `git fetch origin` failed — check your network/auth and try again."
|
|
12720
|
+
};
|
|
12721
|
+
}
|
|
12722
|
+
const head = deps.headSha();
|
|
12723
|
+
const originSha = deps.defaultBranchSha(defaultBranch);
|
|
12724
|
+
if (head === null || originSha === null || head !== originSha) {
|
|
12725
|
+
return {
|
|
12726
|
+
ok: false,
|
|
12727
|
+
message: `vinaya release: HEAD does not equal \`origin/${defaultBranch}\` — run \`git pull --ff-only\` first.`
|
|
12728
|
+
};
|
|
12729
|
+
}
|
|
12730
|
+
const subject = deps.headSubject();
|
|
12731
|
+
if (!opts.allowAnyCommit && !subject.startsWith("Chore(release): Version packages")) {
|
|
12732
|
+
return {
|
|
12733
|
+
ok: false,
|
|
12734
|
+
message: `vinaya release: HEAD's commit "${subject}" is not a Version Packages commit — merge the Version Packages PR first, or pass \`--allow-any-commit\`.`
|
|
12735
|
+
};
|
|
12736
|
+
}
|
|
12737
|
+
if (!deps.npmWhoami()) {
|
|
12738
|
+
return {
|
|
12739
|
+
ok: false,
|
|
12740
|
+
message: "vinaya release: `npm whoami` failed — run `npm login` first."
|
|
12741
|
+
};
|
|
12742
|
+
}
|
|
12743
|
+
if (opts.dryRun) {
|
|
12744
|
+
return { ok: true, dryRun: true, plan: RELEASE_PLAN };
|
|
12745
|
+
}
|
|
12746
|
+
const ranSteps = [];
|
|
12747
|
+
let publishedAlready = false;
|
|
12748
|
+
for (const step of RELEASE_PLAN) {
|
|
12749
|
+
const [cmd, ...args] = step;
|
|
12750
|
+
deps.log(`vinaya release: running \`${step.join(" ")}\``);
|
|
12751
|
+
try {
|
|
12752
|
+
deps.runStreamed(cmd, args);
|
|
12753
|
+
} catch (error2) {
|
|
12754
|
+
const reason = error2 instanceof Error ? error2.message : String(error2);
|
|
12755
|
+
if (!publishedAlready) {
|
|
12756
|
+
return { ok: false, message: `vinaya release: \`${step.join(" ")}\` failed — ${reason}` };
|
|
12757
|
+
}
|
|
12758
|
+
const recoveryCommand = RELEASE_PLAN.slice(ranSteps.length).map((s) => s.join(" ")).join(" && ");
|
|
12759
|
+
return {
|
|
12760
|
+
ok: false,
|
|
12761
|
+
message: `vinaya release: \`${step.join(" ")}\` failed after publish already succeeded — packages are on the registry, the release is not finished. Ran: ${ranSteps.map((s) => s.join(" ")).join(", ") || "(nothing)"}. Failed: \`${step.join(" ")}\` — ${reason}. Finish by hand: \`${recoveryCommand}\``,
|
|
12762
|
+
ranSteps: [...ranSteps],
|
|
12763
|
+
failedStep: step,
|
|
12764
|
+
recoveryCommand
|
|
12765
|
+
};
|
|
12766
|
+
}
|
|
12767
|
+
deps.log(`vinaya release: \`${step.join(" ")}\` done`);
|
|
12768
|
+
ranSteps.push(step);
|
|
12769
|
+
if (cmd === "bun" && args.join(" ") === "run changeset:publish")
|
|
12770
|
+
publishedAlready = true;
|
|
12771
|
+
}
|
|
12772
|
+
const published = [];
|
|
12773
|
+
for (const tag of deps.tagsAtHead()) {
|
|
12774
|
+
const parsed = parseTag(tag);
|
|
12775
|
+
if (parsed === null)
|
|
12776
|
+
continue;
|
|
12777
|
+
const registryVersion = deps.npmViewVersion(parsed.pkg);
|
|
12778
|
+
const lagExpected = parsed.pkg === "@attalabs/vinaya" && registryVersion !== parsed.version;
|
|
12779
|
+
published.push({ tag, pkg: parsed.pkg, version: parsed.version, registryVersion, lagExpected });
|
|
12780
|
+
}
|
|
12781
|
+
return { ok: true, dryRun: false, published };
|
|
12782
|
+
}
|
|
12783
|
+
async function releaseCommand(args) {
|
|
12784
|
+
const dryRun = args.includes("--dry-run");
|
|
12785
|
+
const allowAnyCommit = args.includes("--allow-any-commit");
|
|
12786
|
+
const deps = realDeps8();
|
|
12787
|
+
const outcome = runRelease({ dryRun, allowAnyCommit }, deps);
|
|
12788
|
+
if (!outcome.ok) {
|
|
12789
|
+
console.error(outcome.message);
|
|
12790
|
+
process.exit(1);
|
|
12791
|
+
}
|
|
12792
|
+
if (outcome.dryRun) {
|
|
12793
|
+
deps.log("vinaya release --dry-run: preconditions pass. Plan:");
|
|
12794
|
+
for (const step of outcome.plan)
|
|
12795
|
+
deps.log(` ${step.join(" ")}`);
|
|
12796
|
+
process.exit(0);
|
|
12797
|
+
}
|
|
12798
|
+
for (const p of outcome.published) {
|
|
12799
|
+
const registry = p.registryVersion ?? "(not found)";
|
|
12800
|
+
if (p.lagExpected) {
|
|
12801
|
+
deps.log(`${p.tag}: npm view reports \`${registry}\` — registry lag expected (~20 min)`);
|
|
12802
|
+
} else {
|
|
12803
|
+
deps.log(`${p.tag}: npm view reports \`${registry}\``);
|
|
12804
|
+
}
|
|
12805
|
+
}
|
|
12806
|
+
process.exit(0);
|
|
12807
|
+
}
|
|
12808
|
+
|
|
12538
12809
|
// src/commands/review-post.ts
|
|
12539
|
-
import { execFileSync as
|
|
12810
|
+
import { execFileSync as execFileSync21 } from "node:child_process";
|
|
12540
12811
|
import { readFileSync as readFileSync26, rmSync as rmSync6, writeFileSync as writeFileSync14 } from "node:fs";
|
|
12541
12812
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
12542
12813
|
import { join as join26 } from "node:path";
|
|
@@ -12925,7 +13196,7 @@ function normalizeSecurityVerdict(raw) {
|
|
|
12925
13196
|
}
|
|
12926
13197
|
function gh3(args) {
|
|
12927
13198
|
try {
|
|
12928
|
-
return
|
|
13199
|
+
return execFileSync21("gh", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] }).trim();
|
|
12929
13200
|
} catch (err) {
|
|
12930
13201
|
const stderr = err.stderr;
|
|
12931
13202
|
throw new Error(String(stderr ?? err.message).trim() || "gh command failed");
|
|
@@ -12945,7 +13216,7 @@ function resolveHeadRefName(pr) {
|
|
|
12945
13216
|
}
|
|
12946
13217
|
function shaFromLsRemote(branch) {
|
|
12947
13218
|
try {
|
|
12948
|
-
const out =
|
|
13219
|
+
const out = execFileSync21("git", ["ls-remote", "origin", `refs/heads/${branch}`], {
|
|
12949
13220
|
encoding: "utf8",
|
|
12950
13221
|
stdio: ["ignore", "pipe", "pipe"]
|
|
12951
13222
|
}).trim();
|
|
@@ -13007,13 +13278,13 @@ function fetchComments(pr) {
|
|
|
13007
13278
|
}
|
|
13008
13279
|
function computeChangedRanges(pr, judgedHead, resolvedHead) {
|
|
13009
13280
|
try {
|
|
13010
|
-
|
|
13281
|
+
execFileSync21("git", ["fetch", "origin", resolvedHead], { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
13011
13282
|
} catch (err) {
|
|
13012
13283
|
refuseCmd(`Could not compute the round-two diff for PR ${pr}: \`git fetch origin ${resolvedHead}\` failed (${err instanceof Error ? err.message : String(err)}) — the PR's current head is not reachable from this worktree's origin remote.`, "Confirm the PR head is pushed to origin and reachable, then re-run.");
|
|
13013
13284
|
}
|
|
13014
13285
|
let out;
|
|
13015
13286
|
try {
|
|
13016
|
-
out =
|
|
13287
|
+
out = execFileSync21("git", ["diff", `${judgedHead}...${resolvedHead}`, "-U0"], {
|
|
13017
13288
|
encoding: "utf8",
|
|
13018
13289
|
stdio: ["ignore", "pipe", "pipe"]
|
|
13019
13290
|
});
|
|
@@ -13312,11 +13583,11 @@ Self-verification: clean — re-parsed VERDICT is bound to head ${headSha}.
|
|
|
13312
13583
|
}
|
|
13313
13584
|
|
|
13314
13585
|
// src/commands/review-status.ts
|
|
13315
|
-
import { execFileSync as
|
|
13586
|
+
import { execFileSync as execFileSync22 } from "node:child_process";
|
|
13316
13587
|
var MAX_ROUNDS = 3;
|
|
13317
13588
|
function fetchPr(prNumber) {
|
|
13318
13589
|
try {
|
|
13319
|
-
const out =
|
|
13590
|
+
const out = execFileSync22("gh", ["pr", "view", prNumber, "--json", "comments,headRefOid,baseRefName"], {
|
|
13320
13591
|
encoding: "utf8",
|
|
13321
13592
|
stdio: ["ignore", "pipe", "pipe"]
|
|
13322
13593
|
});
|
|
@@ -13327,7 +13598,7 @@ function fetchPr(prNumber) {
|
|
|
13327
13598
|
}
|
|
13328
13599
|
function behindBy(base) {
|
|
13329
13600
|
try {
|
|
13330
|
-
const out =
|
|
13601
|
+
const out = execFileSync22("git", ["rev-list", "--count", `HEAD..origin/${base}`], {
|
|
13331
13602
|
encoding: "utf8",
|
|
13332
13603
|
stdio: ["ignore", "pipe", "pipe"]
|
|
13333
13604
|
}).trim();
|
|
@@ -13526,7 +13797,7 @@ async function runStudio(cwd, args, moduleUrl = import.meta.url) {
|
|
|
13526
13797
|
// src/commands/upgrade.ts
|
|
13527
13798
|
import { existsSync as existsSync24, readFileSync as readFileSync28, rmSync as rmSync7, writeFileSync as writeFileSync15 } from "node:fs";
|
|
13528
13799
|
import { join as join28 } from "node:path";
|
|
13529
|
-
function
|
|
13800
|
+
function realDeps9() {
|
|
13530
13801
|
return {
|
|
13531
13802
|
detectRepo: detectGitRepo,
|
|
13532
13803
|
hookDirFor: resolveHookDir,
|
|
@@ -13921,16 +14192,16 @@ Vinaya upgraded.
|
|
|
13921
14192
|
return 0;
|
|
13922
14193
|
}
|
|
13923
14194
|
async function upgradeCommand(args) {
|
|
13924
|
-
process.exit(await runUpgrade(args,
|
|
14195
|
+
process.exit(await runUpgrade(args, realDeps9()));
|
|
13925
14196
|
}
|
|
13926
14197
|
|
|
13927
14198
|
// src/commands/waiver.ts
|
|
13928
|
-
import { execFileSync as
|
|
14199
|
+
import { execFileSync as execFileSync23 } from "node:child_process";
|
|
13929
14200
|
function labelFor(kind) {
|
|
13930
14201
|
return kind === "docs" ? WAIVER_LABEL : WAIVER_LABEL_REVIEW;
|
|
13931
14202
|
}
|
|
13932
14203
|
function gh4(args) {
|
|
13933
|
-
return
|
|
14204
|
+
return execFileSync23("gh", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"], env: process.env }).trim();
|
|
13934
14205
|
}
|
|
13935
14206
|
function detectPrNumber() {
|
|
13936
14207
|
try {
|
|
@@ -14030,8 +14301,8 @@ Reason: ${reason}`];
|
|
|
14030
14301
|
}
|
|
14031
14302
|
process.stdout.write(`Applying \`${label2}\` to PR #${prNumber} under your authenticated \`gh\` identity — vinaya never fabricates an actor.
|
|
14032
14303
|
`);
|
|
14033
|
-
|
|
14034
|
-
|
|
14304
|
+
execFileSync23("gh", editArgs, { stdio: "inherit", env: process.env });
|
|
14305
|
+
execFileSync23("gh", commentArgs, { stdio: "inherit", env: process.env });
|
|
14035
14306
|
process.stdout.write(`
|
|
14036
14307
|
✓ Label applied and reason posted as a PR comment.
|
|
14037
14308
|
`);
|
|
@@ -14227,6 +14498,10 @@ try {
|
|
|
14227
14498
|
await waiverCommand(args);
|
|
14228
14499
|
break;
|
|
14229
14500
|
}
|
|
14501
|
+
case "release": {
|
|
14502
|
+
await releaseCommand(args);
|
|
14503
|
+
break;
|
|
14504
|
+
}
|
|
14230
14505
|
case "quickstart": {
|
|
14231
14506
|
await quickstartCommand(args);
|
|
14232
14507
|
break;
|