@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/README.md
CHANGED
|
@@ -31,6 +31,7 @@ npx @attalabs/vinaya init # or: pnpm dlx / yarn dlx / bunx
|
|
|
31
31
|
| `vinaya milestone edit <n> --body-file <path>` | Edit an existing Milestone's description after the same `checkMilestoneShape` gate `create` runs — the gated replacement for a raw `gh api PATCH` against a Milestone. Only the description changes; the title is untouched. `--validate-only` runs every check without writing; `--json` for the enveloped machine form. |
|
|
32
32
|
| `vinaya milestone close --slug <slug>` | Close a tranche's Milestone — the gated replacement for the raw `gh api .../milestones/<n> -X PATCH -f state=closed` recipe the Tranche Archivist used to run on faith. Resolves the target Milestone the same legacy-or-intent-declared way Issue create auto-attach does, then refuses to close on any mismatch between the label's Issues and the Milestone's natively attached Issues — naming each unattached or foreign Issue and its repair path (`gh issue edit <n> --milestone <title>`, or `vinaya milestone adopt`) — before the PATCH ever reaches the forge. `--validate-only` verifies attachment without closing; `--json` for the enveloped machine form. |
|
|
33
33
|
| `vinaya quickstart [--yes] [--dry-run]` | Guided wizard that runs `init` → optional doc-owners bind → optional project registration → commit → `demo break` → `doctor` → `push` in sequence, prompting between steps. `--yes` forwards straight through to `init` and answers every one of quickstart's own prompts with its documented default (skip the two optional steps, run the refusal-then-fix proof, push) — no prompt is opened at all, so the command completes with no human at the keyboard rather than merely with stdin closed. `--dry-run` also forwards to `init` and stops immediately after its preview — nothing is installed, so no later step runs against an uninstalled repo. |
|
|
34
|
+
| `vinaya release [--dry-run] [--allow-any-commit]` | Run this repo's own publish sequence in one command (`apps/cli/specs/self-hosting.md`, "How the published version is produced"). Refuses unless HEAD is the default branch, the 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. Then streams `bun install --frozen-lockfile`, `bun run build`, `bun run changeset:publish`, and a real `git push origin --tags`, so the repo's own generated pre-push hook sees the push exactly as any other push would. Afterward 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. `--dry-run` stops after the preconditions and prints the plan; publishes nothing. |
|
|
34
35
|
|
|
35
36
|
## Config
|
|
36
37
|
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4915,6 +4921,26 @@ var COMMANDS = [
|
|
|
4915
4921
|
"Never reimplements or edits `init`/`init product`/`demo break`/`doctor` — it only calls their existing, unmodified entry points in sequence."
|
|
4916
4922
|
],
|
|
4917
4923
|
status: "shipped"
|
|
4924
|
+
},
|
|
4925
|
+
{
|
|
4926
|
+
name: "release",
|
|
4927
|
+
description: "Run this repo's own publish sequence in one command, refusing to start unless every precondition holds",
|
|
4928
|
+
flags: [
|
|
4929
|
+
{
|
|
4930
|
+
flag: "--dry-run",
|
|
4931
|
+
description: "Run the preconditions only and print the plan; publishes nothing"
|
|
4932
|
+
},
|
|
4933
|
+
{
|
|
4934
|
+
flag: "--allow-any-commit",
|
|
4935
|
+
description: "Skip the check that HEAD's commit is a Version Packages commit"
|
|
4936
|
+
}
|
|
4937
|
+
],
|
|
4938
|
+
details: [
|
|
4939
|
+
"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.",
|
|
4940
|
+
"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.",
|
|
4941
|
+
'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.'
|
|
4942
|
+
],
|
|
4943
|
+
status: "shipped"
|
|
4918
4944
|
}
|
|
4919
4945
|
];
|
|
4920
4946
|
// ../../packages/sources/src/forge-adapter.ts
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4159,8 +4159,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4159
4159
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4160
4160
|
}
|
|
4161
4161
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4162
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4163
|
+
return pushRefs.split(`
|
|
4164
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4165
|
+
}
|
|
4162
4166
|
function checkMainBranchRefusal(facts) {
|
|
4163
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4167
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4164
4168
|
if (currentSymbolicBranch === null)
|
|
4165
4169
|
return null;
|
|
4166
4170
|
if (defaultBranch === null) {
|
|
@@ -4172,6 +4176,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4172
4176
|
};
|
|
4173
4177
|
}
|
|
4174
4178
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4179
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4180
|
+
return null;
|
|
4175
4181
|
return {
|
|
4176
4182
|
reason: "on-default-branch",
|
|
4177
4183
|
severity: "error",
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4915,6 +4921,26 @@ var COMMANDS = [
|
|
|
4915
4921
|
"Never reimplements or edits `init`/`init product`/`demo break`/`doctor` — it only calls their existing, unmodified entry points in sequence."
|
|
4916
4922
|
],
|
|
4917
4923
|
status: "shipped"
|
|
4924
|
+
},
|
|
4925
|
+
{
|
|
4926
|
+
name: "release",
|
|
4927
|
+
description: "Run this repo's own publish sequence in one command, refusing to start unless every precondition holds",
|
|
4928
|
+
flags: [
|
|
4929
|
+
{
|
|
4930
|
+
flag: "--dry-run",
|
|
4931
|
+
description: "Run the preconditions only and print the plan; publishes nothing"
|
|
4932
|
+
},
|
|
4933
|
+
{
|
|
4934
|
+
flag: "--allow-any-commit",
|
|
4935
|
+
description: "Skip the check that HEAD's commit is a Version Packages commit"
|
|
4936
|
+
}
|
|
4937
|
+
],
|
|
4938
|
+
details: [
|
|
4939
|
+
"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.",
|
|
4940
|
+
"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.",
|
|
4941
|
+
'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.'
|
|
4942
|
+
],
|
|
4943
|
+
status: "shipped"
|
|
4918
4944
|
}
|
|
4919
4945
|
];
|
|
4920
4946
|
// ../../packages/sources/src/forge-adapter.ts
|
|
@@ -4160,8 +4160,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4160
4160
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4161
4161
|
}
|
|
4162
4162
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4163
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4164
|
+
return pushRefs.split(`
|
|
4165
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4166
|
+
}
|
|
4163
4167
|
function checkMainBranchRefusal(facts) {
|
|
4164
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4168
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4165
4169
|
if (currentSymbolicBranch === null)
|
|
4166
4170
|
return null;
|
|
4167
4171
|
if (defaultBranch === null) {
|
|
@@ -4173,6 +4177,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4173
4177
|
};
|
|
4174
4178
|
}
|
|
4175
4179
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4180
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4181
|
+
return null;
|
|
4176
4182
|
return {
|
|
4177
4183
|
reason: "on-default-branch",
|
|
4178
4184
|
severity: "error",
|
|
@@ -4918,6 +4924,26 @@ var COMMANDS = [
|
|
|
4918
4924
|
"Never reimplements or edits `init`/`init product`/`demo break`/`doctor` — it only calls their existing, unmodified entry points in sequence."
|
|
4919
4925
|
],
|
|
4920
4926
|
status: "shipped"
|
|
4927
|
+
},
|
|
4928
|
+
{
|
|
4929
|
+
name: "release",
|
|
4930
|
+
description: "Run this repo's own publish sequence in one command, refusing to start unless every precondition holds",
|
|
4931
|
+
flags: [
|
|
4932
|
+
{
|
|
4933
|
+
flag: "--dry-run",
|
|
4934
|
+
description: "Run the preconditions only and print the plan; publishes nothing"
|
|
4935
|
+
},
|
|
4936
|
+
{
|
|
4937
|
+
flag: "--allow-any-commit",
|
|
4938
|
+
description: "Skip the check that HEAD's commit is a Version Packages commit"
|
|
4939
|
+
}
|
|
4940
|
+
],
|
|
4941
|
+
details: [
|
|
4942
|
+
"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.",
|
|
4943
|
+
"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.",
|
|
4944
|
+
'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.'
|
|
4945
|
+
],
|
|
4946
|
+
status: "shipped"
|
|
4921
4947
|
}
|
|
4922
4948
|
];
|
|
4923
4949
|
// ../../packages/sources/src/forge-adapter.ts
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4160,8 +4160,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4160
4160
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4161
4161
|
}
|
|
4162
4162
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4163
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4164
|
+
return pushRefs.split(`
|
|
4165
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4166
|
+
}
|
|
4163
4167
|
function checkMainBranchRefusal(facts) {
|
|
4164
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4168
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4165
4169
|
if (currentSymbolicBranch === null)
|
|
4166
4170
|
return null;
|
|
4167
4171
|
if (defaultBranch === null) {
|
|
@@ -4173,6 +4177,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4173
4177
|
};
|
|
4174
4178
|
}
|
|
4175
4179
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4180
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4181
|
+
return null;
|
|
4176
4182
|
return {
|
|
4177
4183
|
reason: "on-default-branch",
|
|
4178
4184
|
severity: "error",
|
|
@@ -4918,6 +4924,26 @@ var COMMANDS = [
|
|
|
4918
4924
|
"Never reimplements or edits `init`/`init product`/`demo break`/`doctor` — it only calls their existing, unmodified entry points in sequence."
|
|
4919
4925
|
],
|
|
4920
4926
|
status: "shipped"
|
|
4927
|
+
},
|
|
4928
|
+
{
|
|
4929
|
+
name: "release",
|
|
4930
|
+
description: "Run this repo's own publish sequence in one command, refusing to start unless every precondition holds",
|
|
4931
|
+
flags: [
|
|
4932
|
+
{
|
|
4933
|
+
flag: "--dry-run",
|
|
4934
|
+
description: "Run the preconditions only and print the plan; publishes nothing"
|
|
4935
|
+
},
|
|
4936
|
+
{
|
|
4937
|
+
flag: "--allow-any-commit",
|
|
4938
|
+
description: "Skip the check that HEAD's commit is a Version Packages commit"
|
|
4939
|
+
}
|
|
4940
|
+
],
|
|
4941
|
+
details: [
|
|
4942
|
+
"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.",
|
|
4943
|
+
"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.",
|
|
4944
|
+
'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.'
|
|
4945
|
+
],
|
|
4946
|
+
status: "shipped"
|
|
4921
4947
|
}
|
|
4922
4948
|
];
|
|
4923
4949
|
// ../../packages/sources/src/forge-adapter.ts
|
|
@@ -4158,8 +4158,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4158
4158
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4159
4159
|
}
|
|
4160
4160
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4161
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4162
|
+
return pushRefs.split(`
|
|
4163
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4164
|
+
}
|
|
4161
4165
|
function checkMainBranchRefusal(facts) {
|
|
4162
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4166
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4163
4167
|
if (currentSymbolicBranch === null)
|
|
4164
4168
|
return null;
|
|
4165
4169
|
if (defaultBranch === null) {
|
|
@@ -4171,6 +4175,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4171
4175
|
};
|
|
4172
4176
|
}
|
|
4173
4177
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4178
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4179
|
+
return null;
|
|
4174
4180
|
return {
|
|
4175
4181
|
reason: "on-default-branch",
|
|
4176
4182
|
severity: "error",
|
|
@@ -4158,8 +4158,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4158
4158
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4159
4159
|
}
|
|
4160
4160
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4161
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4162
|
+
return pushRefs.split(`
|
|
4163
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4164
|
+
}
|
|
4161
4165
|
function checkMainBranchRefusal(facts) {
|
|
4162
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4166
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4163
4167
|
if (currentSymbolicBranch === null)
|
|
4164
4168
|
return null;
|
|
4165
4169
|
if (defaultBranch === null) {
|
|
@@ -4171,6 +4175,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4171
4175
|
};
|
|
4172
4176
|
}
|
|
4173
4177
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4178
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4179
|
+
return null;
|
|
4174
4180
|
return {
|
|
4175
4181
|
reason: "on-default-branch",
|
|
4176
4182
|
severity: "error",
|
|
@@ -4158,8 +4158,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4158
4158
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4159
4159
|
}
|
|
4160
4160
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4161
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4162
|
+
return pushRefs.split(`
|
|
4163
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4164
|
+
}
|
|
4161
4165
|
function checkMainBranchRefusal(facts) {
|
|
4162
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4166
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4163
4167
|
if (currentSymbolicBranch === null)
|
|
4164
4168
|
return null;
|
|
4165
4169
|
if (defaultBranch === null) {
|
|
@@ -4171,6 +4175,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4171
4175
|
};
|
|
4172
4176
|
}
|
|
4173
4177
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4178
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4179
|
+
return null;
|
|
4174
4180
|
return {
|
|
4175
4181
|
reason: "on-default-branch",
|
|
4176
4182
|
severity: "error",
|
|
@@ -4159,8 +4159,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4159
4159
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4160
4160
|
}
|
|
4161
4161
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4162
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4163
|
+
return pushRefs.split(`
|
|
4164
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4165
|
+
}
|
|
4162
4166
|
function checkMainBranchRefusal(facts) {
|
|
4163
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4167
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4164
4168
|
if (currentSymbolicBranch === null)
|
|
4165
4169
|
return null;
|
|
4166
4170
|
if (defaultBranch === null) {
|
|
@@ -4172,6 +4176,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4172
4176
|
};
|
|
4173
4177
|
}
|
|
4174
4178
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4179
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4180
|
+
return null;
|
|
4175
4181
|
return {
|
|
4176
4182
|
reason: "on-default-branch",
|
|
4177
4183
|
severity: "error",
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4169,8 +4169,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4169
4169
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4170
4170
|
}
|
|
4171
4171
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4172
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4173
|
+
return pushRefs.split(`
|
|
4174
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4175
|
+
}
|
|
4172
4176
|
function checkMainBranchRefusal(facts) {
|
|
4173
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4177
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4174
4178
|
if (currentSymbolicBranch === null)
|
|
4175
4179
|
return null;
|
|
4176
4180
|
if (defaultBranch === null) {
|
|
@@ -4182,6 +4186,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4182
4186
|
};
|
|
4183
4187
|
}
|
|
4184
4188
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4189
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4190
|
+
return null;
|
|
4185
4191
|
return {
|
|
4186
4192
|
reason: "on-default-branch",
|
|
4187
4193
|
severity: "error",
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4915,6 +4921,26 @@ var COMMANDS = [
|
|
|
4915
4921
|
"Never reimplements or edits `init`/`init product`/`demo break`/`doctor` — it only calls their existing, unmodified entry points in sequence."
|
|
4916
4922
|
],
|
|
4917
4923
|
status: "shipped"
|
|
4924
|
+
},
|
|
4925
|
+
{
|
|
4926
|
+
name: "release",
|
|
4927
|
+
description: "Run this repo's own publish sequence in one command, refusing to start unless every precondition holds",
|
|
4928
|
+
flags: [
|
|
4929
|
+
{
|
|
4930
|
+
flag: "--dry-run",
|
|
4931
|
+
description: "Run the preconditions only and print the plan; publishes nothing"
|
|
4932
|
+
},
|
|
4933
|
+
{
|
|
4934
|
+
flag: "--allow-any-commit",
|
|
4935
|
+
description: "Skip the check that HEAD's commit is a Version Packages commit"
|
|
4936
|
+
}
|
|
4937
|
+
],
|
|
4938
|
+
details: [
|
|
4939
|
+
"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.",
|
|
4940
|
+
"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.",
|
|
4941
|
+
'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.'
|
|
4942
|
+
],
|
|
4943
|
+
status: "shipped"
|
|
4918
4944
|
}
|
|
4919
4945
|
];
|
|
4920
4946
|
// ../../packages/sources/src/forge-adapter.ts
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4915,6 +4921,26 @@ var COMMANDS = [
|
|
|
4915
4921
|
"Never reimplements or edits `init`/`init product`/`demo break`/`doctor` — it only calls their existing, unmodified entry points in sequence."
|
|
4916
4922
|
],
|
|
4917
4923
|
status: "shipped"
|
|
4924
|
+
},
|
|
4925
|
+
{
|
|
4926
|
+
name: "release",
|
|
4927
|
+
description: "Run this repo's own publish sequence in one command, refusing to start unless every precondition holds",
|
|
4928
|
+
flags: [
|
|
4929
|
+
{
|
|
4930
|
+
flag: "--dry-run",
|
|
4931
|
+
description: "Run the preconditions only and print the plan; publishes nothing"
|
|
4932
|
+
},
|
|
4933
|
+
{
|
|
4934
|
+
flag: "--allow-any-commit",
|
|
4935
|
+
description: "Skip the check that HEAD's commit is a Version Packages commit"
|
|
4936
|
+
}
|
|
4937
|
+
],
|
|
4938
|
+
details: [
|
|
4939
|
+
"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.",
|
|
4940
|
+
"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.",
|
|
4941
|
+
'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.'
|
|
4942
|
+
],
|
|
4943
|
+
status: "shipped"
|
|
4918
4944
|
}
|
|
4919
4945
|
];
|
|
4920
4946
|
// ../../packages/sources/src/forge-adapter.ts
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4462,12 +4468,17 @@ function defaultBranch() {
|
|
|
4462
4468
|
function main() {
|
|
4463
4469
|
const currentSymbolicBranchName = currentSymbolicBranch();
|
|
4464
4470
|
const defaultBranchName = defaultBranch();
|
|
4471
|
+
const pushRefs = process.env.VINAYA_PUSH_REFS ?? null;
|
|
4465
4472
|
const finding = checkMainBranchRefusal({
|
|
4466
4473
|
currentSymbolicBranch: currentSymbolicBranchName,
|
|
4467
|
-
defaultBranch: defaultBranchName
|
|
4474
|
+
defaultBranch: defaultBranchName,
|
|
4475
|
+
pushRefs
|
|
4468
4476
|
});
|
|
4469
4477
|
if (finding === null) {
|
|
4470
4478
|
console.log(`${CHECK_NAME}: pass (branch: ${currentSymbolicBranchName ?? "(detached)"})`);
|
|
4479
|
+
if (pushRefs !== null && currentSymbolicBranchName !== null && currentSymbolicBranchName === defaultBranchName) {
|
|
4480
|
+
console.log(`${CHECK_NAME}: tag-only push — no refs/heads/* ref in this push, allowing it from the default branch`);
|
|
4481
|
+
}
|
|
4471
4482
|
process.exit(0);
|
|
4472
4483
|
}
|
|
4473
4484
|
if (finding.reason === "on-default-branch") {
|
|
@@ -4157,8 +4157,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4157
4157
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4158
4158
|
}
|
|
4159
4159
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4160
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4161
|
+
return pushRefs.split(`
|
|
4162
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4163
|
+
}
|
|
4160
4164
|
function checkMainBranchRefusal(facts) {
|
|
4161
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4165
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4162
4166
|
if (currentSymbolicBranch === null)
|
|
4163
4167
|
return null;
|
|
4164
4168
|
if (defaultBranch === null) {
|
|
@@ -4170,6 +4174,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4170
4174
|
};
|
|
4171
4175
|
}
|
|
4172
4176
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4177
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4178
|
+
return null;
|
|
4173
4179
|
return {
|
|
4174
4180
|
reason: "on-default-branch",
|
|
4175
4181
|
severity: "error",
|
|
@@ -4154,8 +4154,12 @@ function isNewDiskStateFile(path, status) {
|
|
|
4154
4154
|
return ANY_DEPTH_TRANCHES_MD.test(path) || TOKENS_FILE.test(path);
|
|
4155
4155
|
}
|
|
4156
4156
|
// ../../packages/aeg-core/src/main-branch-refusal.ts
|
|
4157
|
+
function pushesAnyBranchRef(pushRefs) {
|
|
4158
|
+
return pushRefs.split(`
|
|
4159
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0).some((line) => line.split(/\s+/)[2]?.startsWith("refs/heads/") === true);
|
|
4160
|
+
}
|
|
4157
4161
|
function checkMainBranchRefusal(facts) {
|
|
4158
|
-
const { currentSymbolicBranch, defaultBranch } = facts;
|
|
4162
|
+
const { currentSymbolicBranch, defaultBranch, pushRefs = null } = facts;
|
|
4159
4163
|
if (currentSymbolicBranch === null)
|
|
4160
4164
|
return null;
|
|
4161
4165
|
if (defaultBranch === null) {
|
|
@@ -4167,6 +4171,8 @@ function checkMainBranchRefusal(facts) {
|
|
|
4167
4171
|
};
|
|
4168
4172
|
}
|
|
4169
4173
|
if (currentSymbolicBranch === defaultBranch) {
|
|
4174
|
+
if (pushRefs !== null && !pushesAnyBranchRef(pushRefs))
|
|
4175
|
+
return null;
|
|
4170
4176
|
return {
|
|
4171
4177
|
reason: "on-default-branch",
|
|
4172
4178
|
severity: "error",
|