@webpieces/pr-gate 0.3.288 → 0.3.289

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/pr-gate",
3
- "version": "0.3.288",
3
+ "version": "0.3.289",
4
4
  "description": "Gated PR system: 3-point squash-merge, merge validation gate, and red/yellow/green PR dashboard. Standalone scripts, no Nx dependency required.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
@@ -23,7 +23,7 @@
23
23
  "directory": "packages/tooling/pr-gate"
24
24
  },
25
25
  "dependencies": {
26
- "@webpieces/rules-config": "0.3.288"
26
+ "@webpieces/rules-config": "0.3.289"
27
27
  },
28
28
  "publishConfig": {
29
29
  "access": "public"
@@ -2,13 +2,30 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.openPrForBranch = openPrForBranch;
4
4
  const child_process_1 = require("child_process");
5
+ const rules_config_1 = require("@webpieces/rules-config");
5
6
  const branch_naming_1 = require("./branch-naming");
7
+ const SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
6
8
  // The open PR (if any) tracking a feature branch, looked up by its STABLE base name (the PR always
7
- // lives on `base`, never on the numbered generation basewp2/basewp3/…). Best-effort: a missing or
8
- // unauthenticated `gh` (or any failure) degrades to '' = "no open PR" rather than crashing — mirrors
9
- // detectMergedPr's contract so the guard never blocks on tooling absence.
9
+ // lives on `base`, never on the numbered generation basewp2/basewp3/…). Returns '' ONLY when GitHub
10
+ // answered and there is genuinely no open PR.
11
+ //
12
+ // This is a HARD GATE, not an advisory hint: it FAILS FAST if `gh` cannot answer (not installed, not
13
+ // authenticated, offline). We must NOT degrade "couldn't ask GitHub" into "no PR" — a 3-point update
14
+ // makes a new branch generation and the existing PR would be left pointing at the OLD branch (stale),
15
+ // so running wp-update-start blind when a PR might exist is exactly the disaster we are guarding
16
+ // against. Refuse rather than guess.
10
17
  function openPrForBranch(repoRoot, currentBranch) {
11
- const result = (0, child_process_1.spawnSync)('gh', ['pr', 'list', '--head', (0, branch_naming_1.baseBranchName)(currentBranch), '--state', 'open', '--json', 'number', '--jq', '.[0].number'], { cwd: repoRoot, encoding: 'utf8' });
12
- return result.status === 0 ? (result.stdout ?? '').trim() : '';
18
+ const base = (0, branch_naming_1.baseBranchName)(currentBranch);
19
+ const result = (0, child_process_1.spawnSync)('gh', ['pr', 'list', '--head', base, '--state', 'open', '--json', 'number', '--jq', '.[0].number'], { cwd: repoRoot, encoding: 'utf8' });
20
+ if (result.status !== 0) {
21
+ const detail = (result.stderr ?? '').trim() || (result.error ? result.error.message : 'gh exited non-zero');
22
+ throw new rules_config_1.CliExitError(2, '\n' + SEP + '❌ Could not ask GitHub whether an open PR exists for this branch\n' + SEP + '\n' +
23
+ `gh failed for base branch "${base}": ${detail}\n\n` +
24
+ 'This check must NOT be skipped: a 3-point update creates a NEW branch generation, so if a\n' +
25
+ 'PR already exists, wp-update-start would leave it pointing at the OLD branch. Fix gh first\n' +
26
+ '(install / `gh auth login` / restore network), then re-run — or, if a PR does exist, use\n' +
27
+ 'the PR flow: pnpm wp-start-upsert-pr → /wp-merge → pnpm wp-finish-upsert-pr\n');
28
+ }
29
+ return (result.stdout ?? '').trim();
13
30
  }
14
31
  //# sourceMappingURL=open-pr-check.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"open-pr-check.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/pr-gate/src/scripts/workflow/open-pr-check.ts"],"names":[],"mappings":";;AAOA,0CAMC;AAbD,iDAA0C;AAC1C,mDAAiD;AAEjD,mGAAmG;AACnG,kGAAkG;AAClG,qGAAqG;AACrG,0EAA0E;AAC1E,SAAgB,eAAe,CAAC,QAAgB,EAAE,aAAqB;IACnE,MAAM,MAAM,GAAG,IAAA,yBAAS,EACpB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAA,8BAAc,EAAC,aAAa,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAC3H,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CACtC,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC","sourcesContent":["import { spawnSync } from 'child_process';\nimport { baseBranchName } from './branch-naming';\n\n// The open PR (if any) tracking a feature branch, looked up by its STABLE base name (the PR always\n// lives on `base`, never on the numbered generation basewp2/basewp3/…). Best-effort: a missing or\n// unauthenticated `gh` (or any failure) degrades to '' = \"no open PR\" rather than crashing — mirrors\n// detectMergedPr's contract so the guard never blocks on tooling absence.\nexport function openPrForBranch(repoRoot: string, currentBranch: string): string {\n const result = spawnSync(\n 'gh', ['pr', 'list', '--head', baseBranchName(currentBranch), '--state', 'open', '--json', 'number', '--jq', '.[0].number'],\n { cwd: repoRoot, encoding: 'utf8' },\n );\n return result.status === 0 ? (result.stdout ?? '').trim() : '';\n}\n"]}
1
+ {"version":3,"file":"open-pr-check.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/pr-gate/src/scripts/workflow/open-pr-check.ts"],"names":[],"mappings":";;AAeA,0CAkBC;AAjCD,iDAA0C;AAC1C,0DAAuD;AACvD,mDAAiD;AAEjD,MAAM,GAAG,GAAG,0DAA0D,CAAC;AAEvE,mGAAmG;AACnG,oGAAoG;AACpG,8CAA8C;AAC9C,EAAE;AACF,qGAAqG;AACrG,qGAAqG;AACrG,sGAAsG;AACtG,iGAAiG;AACjG,qCAAqC;AACrC,SAAgB,eAAe,CAAC,QAAgB,EAAE,aAAqB;IACnE,MAAM,IAAI,GAAG,IAAA,8BAAc,EAAC,aAAa,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAA,yBAAS,EACpB,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAC,EAClG,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CACtC,CAAC;IACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QAC5G,MAAM,IAAI,2BAAY,CAAC,CAAC,EACpB,IAAI,GAAG,GAAG,GAAG,oEAAoE,GAAG,GAAG,GAAG,IAAI;YAC9F,8BAA8B,IAAI,MAAM,MAAM,MAAM;YACpD,6FAA6F;YAC7F,8FAA8F;YAC9F,4FAA4F;YAC5F,+EAA+E,CAClF,CAAC;IACN,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACxC,CAAC","sourcesContent":["import { spawnSync } from 'child_process';\nimport { CliExitError } from '@webpieces/rules-config';\nimport { baseBranchName } from './branch-naming';\n\nconst SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n';\n\n// The open PR (if any) tracking a feature branch, looked up by its STABLE base name (the PR always\n// lives on `base`, never on the numbered generation basewp2/basewp3/…). Returns '' ONLY when GitHub\n// answered and there is genuinely no open PR.\n//\n// This is a HARD GATE, not an advisory hint: it FAILS FAST if `gh` cannot answer (not installed, not\n// authenticated, offline). We must NOT degrade \"couldn't ask GitHub\" into \"no PR\" a 3-point update\n// makes a new branch generation and the existing PR would be left pointing at the OLD branch (stale),\n// so running wp-update-start blind when a PR might exist is exactly the disaster we are guarding\n// against. Refuse rather than guess.\nexport function openPrForBranch(repoRoot: string, currentBranch: string): string {\n const base = baseBranchName(currentBranch);\n const result = spawnSync(\n 'gh', ['pr', 'list', '--head', base, '--state', 'open', '--json', 'number', '--jq', '.[0].number'],\n { cwd: repoRoot, encoding: 'utf8' },\n );\n if (result.status !== 0) {\n const detail = (result.stderr ?? '').trim() || (result.error ? result.error.message : 'gh exited non-zero');\n throw new CliExitError(2,\n '\\n' + SEP + '❌ Could not ask GitHub whether an open PR exists for this branch\\n' + SEP + '\\n' +\n `gh failed for base branch \"${base}\": ${detail}\\n\\n` +\n 'This check must NOT be skipped: a 3-point update creates a NEW branch generation, so if a\\n' +\n 'PR already exists, wp-update-start would leave it pointing at the OLD branch. Fix gh first\\n' +\n '(install / `gh auth login` / restore network), then re-run — or, if a PR does exist, use\\n' +\n 'the PR flow: pnpm wp-start-upsert-pr → /wp-merge → pnpm wp-finish-upsert-pr\\n',\n );\n }\n return (result.stdout ?? '').trim();\n}\n"]}
@@ -13,18 +13,21 @@ const run_update_1 = require("./workflow/run-update");
13
13
  // on CONFLICT it writes the 3-point context + merge process doc and hands back — you resolve, then
14
14
  // run `wp-update-end` to finalize. It NEVER creates a PR (that is the wp-*-upsert-pr flow).
15
15
  const SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
16
- // wp-update-start is the "sync but keep editing, no PR" flow: it does NOT run the build gate, write
17
- // review.json, or update the PR body/dashboard. So if a PR is already open, force the PR flow instead
18
- // (wp-start-upsert-pr wp-finish-upsert-pr), which pushes + rebuilds the dashboard + updates the PR.
16
+ // If a PR is already OPEN for this branch, wp-update-start must refuse. The 3-point update squash-
17
+ // merges onto a NEW branch generation (base basewp2), and the existing PR stays pinned to the old
18
+ // branch so running the update-only flow would leave the PR pointing at stale, pre-merge code. The
19
+ // PR flow (wp-start-upsert-pr → wp-finish-upsert-pr) is the ONLY correct path once a PR exists: it
20
+ // re-merges main AND updates the PR. Fail fast and steer there. (openPrForBranch itself fails fast if
21
+ // GitHub can't be reached — we never assume "no PR" when we simply couldn't ask.)
19
22
  function assertNoOpenPr(repoRoot) {
20
23
  const branch = (0, child_process_1.execSync)('git rev-parse --abbrev-ref HEAD', { cwd: repoRoot, encoding: 'utf8' }).trim();
21
24
  const openPr = (0, open_pr_check_1.openPrForBranch)(repoRoot, branch);
22
25
  if (openPr === '')
23
26
  return;
24
27
  throw new rules_config_1.CliExitError(2, '\n' + SEP + `⛔ An open PR (#${openPr}) already tracks this branch\n` + SEP + '\n' +
25
- 'wp-update-start is the "sync from main and keep editing" flow it does NOT run the build\n' +
26
- `gate, refresh review.json, or update the PR body/dashboard, so PR #${openPr} would go stale.\n` +
27
- 'Use the PR flow instead — it merges main AND keeps the PR in sync:\n' +
28
+ 'wp-update-start does a 3-point squash-merge onto a NEW branch generation (base basewp2),\n' +
29
+ `but PR #${openPr} is pinned to the current branch so it would be left pointing at stale,\n` +
30
+ 'pre-merge code. Use the PR flow instead — it re-merges main AND updates the PR:\n' +
28
31
  ' 1. pnpm wp-start-upsert-pr\n' +
29
32
  ' 2. /wp-merge (only if conflicts)\n' +
30
33
  ' 3. pnpm wp-finish-upsert-pr\n');
@@ -33,7 +36,8 @@ async function main() {
33
36
  const repoRoot = (0, child_process_1.execSync)('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
34
37
  // Refresh the AI-facing workflow doc so it's present + current for any failure message to cite.
35
38
  (0, rules_config_1.writeTemplate)(repoRoot, 'webpieces.git-workflow.md');
36
- // An open PR means the PR flow (which pushes) must be used — wp-update-start does not push.
39
+ // An open PR means the PR flow must be used — a 3-point update would strand the PR on the old
40
+ // branch generation. Fails fast if GitHub can't be reached (never guesses "no PR").
37
41
  assertNoOpenPr(repoRoot);
38
42
  const outcome = await (0, run_update_1.runUpdateFromMain)(repoRoot, 'wp-update-start', 'wp-update-end');
39
43
  if (outcome === 'conflict') {
@@ -1 +1 @@
1
- {"version":3,"file":"wp-update-start.js","sourceRoot":"","sources":["../../../../../../packages/tooling/pr-gate/src/scripts/wp-update-start.ts"],"names":[],"mappings":";;;AAiBA,wCAaC;AAED,oBAqBC;AApDD,iDAAyC;AACzC,0DAA+E;AAC/E,4DAA2D;AAC3D,sDAA0D;AAE1D,oGAAoG;AACpG,2FAA2F;AAC3F,sGAAsG;AACtG,mGAAmG;AACnG,4FAA4F;AAE5F,MAAM,GAAG,GAAG,0DAA0D,CAAC;AAEvE,oGAAoG;AACpG,sGAAsG;AACtG,sGAAsG;AACtG,SAAgB,cAAc,CAAC,QAAgB;IAC3C,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,iCAAiC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvG,MAAM,MAAM,GAAG,IAAA,+BAAe,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO;IAC1B,MAAM,IAAI,2BAAY,CAAC,CAAC,EACpB,IAAI,GAAG,GAAG,GAAG,kBAAkB,MAAM,gCAAgC,GAAG,GAAG,GAAG,IAAI;QAClF,6FAA6F;QAC7F,sEAAsE,MAAM,oBAAoB;QAChG,sEAAsE;QACtE,gCAAgC;QAChC,wCAAwC;QACxC,iCAAiC,CACpC,CAAC;AACN,CAAC;AAEM,KAAK,UAAU,IAAI;IACtB,MAAM,QAAQ,GAAG,IAAA,wBAAQ,EAAC,+BAA+B,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxF,gGAAgG;IAChG,IAAA,4BAAa,EAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAC;IAErD,4FAA4F;IAC5F,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzB,MAAM,OAAO,GAAG,MAAM,IAAA,8BAAiB,EAAC,QAAQ,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;IACtF,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QACzB,4FAA4F;QAC5F,MAAM,IAAI,2BAAY,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,KAAK,mBAAmB,EAAE,CAAC;QAClC,MAAM,IAAI,2BAAY,CAAC,CAAC,EACpB,IAAI,GAAG,GAAG,GAAG,6CAA6C,GAAG,GAAG,GAAG,IAAI;YACvE,kEAAkE;YAClE,wBAAwB,CAC3B,CAAC;IACN,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;AAC5F,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;IAAE,IAAA,sBAAO,EAAC,IAAI,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { execSync } from 'child_process';\nimport { writeTemplate, CliExitError, runMain } from '@webpieces/rules-config';\nimport { openPrForBranch } from './workflow/open-pr-check';\nimport { runUpdateFromMain } from './workflow/run-update';\n\n// wp-update-start: the \"sync this feature branch from main\" entry point (the redirect target of the\n// redirect-how-to-merge-main guard). It runs the FULL 3-point squash-update via the shared\n// runUpdateFromMain engine: on a CLEAN merge it finalizes everything (no need to call wp-update-end);\n// on CONFLICT it writes the 3-point context + merge process doc and hands back — you resolve, then\n// run `wp-update-end` to finalize. It NEVER creates a PR (that is the wp-*-upsert-pr flow).\n\nconst SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n';\n\n// wp-update-start is the \"sync but keep editing, no PR\" flow: it does NOT run the build gate, write\n// review.json, or update the PR body/dashboard. So if a PR is already open, force the PR flow instead\n// (wp-start-upsert-pr → wp-finish-upsert-pr), which pushes + rebuilds the dashboard + updates the PR.\nexport function assertNoOpenPr(repoRoot: string): void {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd: repoRoot, encoding: 'utf8' }).trim();\n const openPr = openPrForBranch(repoRoot, branch);\n if (openPr === '') return;\n throw new CliExitError(2,\n '\\n' + SEP + `⛔ An open PR (#${openPr}) already tracks this branch\\n` + SEP + '\\n' +\n 'wp-update-start is the \"sync from main and keep editing\" flow it does NOT run the build\\n' +\n `gate, refresh review.json, or update the PR body/dashboard, so PR #${openPr} would go stale.\\n` +\n 'Use the PR flow instead — it merges main AND keeps the PR in sync:\\n' +\n ' 1. pnpm wp-start-upsert-pr\\n' +\n ' 2. /wp-merge (only if conflicts)\\n' +\n ' 3. pnpm wp-finish-upsert-pr\\n',\n );\n}\n\nexport async function main(): Promise<void> {\n const repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();\n // Refresh the AI-facing workflow doc so it's present + current for any failure message to cite.\n writeTemplate(repoRoot, 'webpieces.git-workflow.md');\n\n // An open PR means the PR flow (which pushes) must be used — wp-update-start does not push.\n assertNoOpenPr(repoRoot);\n\n const outcome = await runUpdateFromMain(repoRoot, 'wp-update-start', 'wp-update-end');\n if (outcome === 'conflict') {\n // Context + marker + merge process doc already written by merge-start; hand back to the AI.\n throw new CliExitError(2, '');\n }\n if (outcome === 'unvalidatedResume') {\n throw new CliExitError(1,\n '\\n' + SEP + '⏸️ Merge in progress — not yet validated\\n' + SEP + '\\n' +\n 'Resolve the remaining conflicts in the working tree, then run:\\n' +\n ' pnpm wp-update-end\\n',\n );\n }\n process.stdout.write('\\n✅ Updated from main — clean. No need to call wp-update-end.\\n');\n}\n\nif (require.main === module) runMain(main);\n"]}
1
+ {"version":3,"file":"wp-update-start.js","sourceRoot":"","sources":["../../../../../../packages/tooling/pr-gate/src/scripts/wp-update-start.ts"],"names":[],"mappings":";;;AAoBA,wCAaC;AAED,oBAsBC;AAxDD,iDAAyC;AACzC,0DAA+E;AAC/E,4DAA2D;AAC3D,sDAA0D;AAE1D,oGAAoG;AACpG,2FAA2F;AAC3F,sGAAsG;AACtG,mGAAmG;AACnG,4FAA4F;AAE5F,MAAM,GAAG,GAAG,0DAA0D,CAAC;AAEvE,mGAAmG;AACnG,oGAAoG;AACpG,qGAAqG;AACrG,mGAAmG;AACnG,sGAAsG;AACtG,kFAAkF;AAClF,SAAgB,cAAc,CAAC,QAAgB;IAC3C,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,iCAAiC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACvG,MAAM,MAAM,GAAG,IAAA,+BAAe,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO;IAC1B,MAAM,IAAI,2BAAY,CAAC,CAAC,EACpB,IAAI,GAAG,GAAG,GAAG,kBAAkB,MAAM,gCAAgC,GAAG,GAAG,GAAG,IAAI;QAClF,8FAA8F;QAC9F,WAAW,MAAM,6EAA6E;QAC9F,mFAAmF;QACnF,gCAAgC;QAChC,wCAAwC;QACxC,iCAAiC,CACpC,CAAC;AACN,CAAC;AAEM,KAAK,UAAU,IAAI;IACtB,MAAM,QAAQ,GAAG,IAAA,wBAAQ,EAAC,+BAA+B,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxF,gGAAgG;IAChG,IAAA,4BAAa,EAAC,QAAQ,EAAE,2BAA2B,CAAC,CAAC;IAErD,8FAA8F;IAC9F,oFAAoF;IACpF,cAAc,CAAC,QAAQ,CAAC,CAAC;IAEzB,MAAM,OAAO,GAAG,MAAM,IAAA,8BAAiB,EAAC,QAAQ,EAAE,iBAAiB,EAAE,eAAe,CAAC,CAAC;IACtF,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;QACzB,4FAA4F;QAC5F,MAAM,IAAI,2BAAY,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,KAAK,mBAAmB,EAAE,CAAC;QAClC,MAAM,IAAI,2BAAY,CAAC,CAAC,EACpB,IAAI,GAAG,GAAG,GAAG,6CAA6C,GAAG,GAAG,GAAG,IAAI;YACvE,kEAAkE;YAClE,wBAAwB,CAC3B,CAAC;IACN,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;AAC5F,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;IAAE,IAAA,sBAAO,EAAC,IAAI,CAAC,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { execSync } from 'child_process';\nimport { writeTemplate, CliExitError, runMain } from '@webpieces/rules-config';\nimport { openPrForBranch } from './workflow/open-pr-check';\nimport { runUpdateFromMain } from './workflow/run-update';\n\n// wp-update-start: the \"sync this feature branch from main\" entry point (the redirect target of the\n// redirect-how-to-merge-main guard). It runs the FULL 3-point squash-update via the shared\n// runUpdateFromMain engine: on a CLEAN merge it finalizes everything (no need to call wp-update-end);\n// on CONFLICT it writes the 3-point context + merge process doc and hands back — you resolve, then\n// run `wp-update-end` to finalize. It NEVER creates a PR (that is the wp-*-upsert-pr flow).\n\nconst SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n';\n\n// If a PR is already OPEN for this branch, wp-update-start must refuse. The 3-point update squash-\n// merges onto a NEW branch generation (base → basewp2), and the existing PR stays pinned to the old\n// branch so running the update-only flow would leave the PR pointing at stale, pre-merge code. The\n// PR flow (wp-start-upsert-pr → wp-finish-upsert-pr) is the ONLY correct path once a PR exists: it\n// re-merges main AND updates the PR. Fail fast and steer there. (openPrForBranch itself fails fast if\n// GitHub can't be reached — we never assume \"no PR\" when we simply couldn't ask.)\nexport function assertNoOpenPr(repoRoot: string): void {\n const branch = execSync('git rev-parse --abbrev-ref HEAD', { cwd: repoRoot, encoding: 'utf8' }).trim();\n const openPr = openPrForBranch(repoRoot, branch);\n if (openPr === '') return;\n throw new CliExitError(2,\n '\\n' + SEP + `⛔ An open PR (#${openPr}) already tracks this branch\\n` + SEP + '\\n' +\n 'wp-update-start does a 3-point squash-merge onto a NEW branch generation (base basewp2),\\n' +\n `but PR #${openPr} is pinned to the current branch so it would be left pointing at stale,\\n` +\n 'pre-merge code. Use the PR flow instead — it re-merges main AND updates the PR:\\n' +\n ' 1. pnpm wp-start-upsert-pr\\n' +\n ' 2. /wp-merge (only if conflicts)\\n' +\n ' 3. pnpm wp-finish-upsert-pr\\n',\n );\n}\n\nexport async function main(): Promise<void> {\n const repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();\n // Refresh the AI-facing workflow doc so it's present + current for any failure message to cite.\n writeTemplate(repoRoot, 'webpieces.git-workflow.md');\n\n // An open PR means the PR flow must be used — a 3-point update would strand the PR on the old\n // branch generation. Fails fast if GitHub can't be reached (never guesses \"no PR\").\n assertNoOpenPr(repoRoot);\n\n const outcome = await runUpdateFromMain(repoRoot, 'wp-update-start', 'wp-update-end');\n if (outcome === 'conflict') {\n // Context + marker + merge process doc already written by merge-start; hand back to the AI.\n throw new CliExitError(2, '');\n }\n if (outcome === 'unvalidatedResume') {\n throw new CliExitError(1,\n '\\n' + SEP + '⏸️ Merge in progress — not yet validated\\n' + SEP + '\\n' +\n 'Resolve the remaining conflicts in the working tree, then run:\\n' +\n ' pnpm wp-update-end\\n',\n );\n }\n process.stdout.write('\\n✅ Updated from main — clean. No need to call wp-update-end.\\n');\n}\n\nif (require.main === module) runMain(main);\n"]}