@webpieces/ai-hook-rules 0.3.183 → 0.3.185

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.
Files changed (54) hide show
  1. package/package.json +3 -6
  2. package/src/adapters/global-hook.js +3 -3
  3. package/src/adapters/global-hook.js.map +1 -1
  4. package/src/core/disable-directives.d.ts +1 -2
  5. package/src/core/disable-directives.js +17 -31
  6. package/src/core/disable-directives.js.map +1 -1
  7. package/src/core/load-rules.js +2 -0
  8. package/src/core/load-rules.js.map +1 -1
  9. package/src/core/rules/catch-error-pattern.js +2 -1
  10. package/src/core/rules/catch-error-pattern.js.map +1 -1
  11. package/src/core/rules/index.js +1 -0
  12. package/src/core/rules/index.js.map +1 -1
  13. package/src/core/rules/merge-in-progress-guard.d.ts +3 -0
  14. package/src/core/rules/merge-in-progress-guard.js +66 -0
  15. package/src/core/rules/merge-in-progress-guard.js.map +1 -0
  16. package/src/core/rules/no-any-unknown.js +2 -1
  17. package/src/core/rules/no-any-unknown.js.map +1 -1
  18. package/src/core/rules/no-destructure.js +2 -1
  19. package/src/core/rules/no-destructure.js.map +1 -1
  20. package/src/core/rules/no-implicit-any.js +2 -1
  21. package/src/core/rules/no-implicit-any.js.map +1 -1
  22. package/src/core/rules/no-symbol-di-tokens.js +2 -1
  23. package/src/core/rules/no-symbol-di-tokens.js.map +1 -1
  24. package/src/core/rules/no-unmanaged-exceptions.js +2 -1
  25. package/src/core/rules/no-unmanaged-exceptions.js.map +1 -1
  26. package/src/core/rules/pr-creation-guard.js +29 -57
  27. package/src/core/rules/pr-creation-guard.js.map +1 -1
  28. package/src/core/rules/require-return-type.js +2 -1
  29. package/src/core/rules/require-return-type.js.map +1 -1
  30. package/src/core/rules/throw-cause-required.js +2 -1
  31. package/src/core/rules/throw-cause-required.js.map +1 -1
  32. package/src/core/to-error.js +0 -1
  33. package/src/core/to-error.js.map +1 -1
  34. package/src/scripts/git-gatherInfo.d.ts +0 -2
  35. package/src/scripts/git-gatherInfo.js +0 -98
  36. package/src/scripts/git-gatherInfo.js.map +0 -1
  37. package/src/scripts/git-mergeComplete.d.ts +0 -2
  38. package/src/scripts/git-mergeComplete.js +0 -58
  39. package/src/scripts/git-mergeComplete.js.map +0 -1
  40. package/src/scripts/git-updateFromMain.d.ts +0 -2
  41. package/src/scripts/git-updateFromMain.js +0 -290
  42. package/src/scripts/git-updateFromMain.js.map +0 -1
  43. package/src/scripts/workflow/cleanTmp.d.ts +0 -1
  44. package/src/scripts/workflow/cleanTmp.js +0 -57
  45. package/src/scripts/workflow/cleanTmp.js.map +0 -1
  46. package/src/scripts/workflow/git-findForkPoint.d.ts +0 -2
  47. package/src/scripts/workflow/git-findForkPoint.js +0 -120
  48. package/src/scripts/workflow/git-findForkPoint.js.map +0 -1
  49. package/src/scripts/workflow/git-readAiBranchName.d.ts +0 -2
  50. package/src/scripts/workflow/git-readAiBranchName.js +0 -20
  51. package/src/scripts/workflow/git-readAiBranchName.js.map +0 -1
  52. package/src/scripts/workflow/git-validateUpToDate.d.ts +0 -1
  53. package/src/scripts/workflow/git-validateUpToDate.js +0 -72
  54. package/src/scripts/workflow/git-validateUpToDate.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const types_1 = require("../types");
4
+ const rules_config_1 = require("@webpieces/rules-config");
4
5
  const SYMBOL_DI_REGEX = /=\s*Symbol(?:\.for)?\(/;
5
6
  const TEST_PATHS = [/\.test\.ts$/, /\.spec\.ts$/, /__tests__\//];
6
7
  function globToRegex(pattern) {
@@ -62,7 +63,7 @@ const noSymbolDiTokensRule = {
62
63
  if (!SYMBOL_DI_REGEX.test(stripped ?? ''))
63
64
  continue;
64
65
  const lineNum = i + 1;
65
- if (ctx.isLineDisabled(lineNum, 'no-symbol-di-tokens'))
66
+ if (ctx.isLineDisabled(lineNum, rules_config_1.RULE_NAMES.NO_SYMBOL_DI_TOKENS))
66
67
  continue;
67
68
  violations.push(new types_1.Violation(lineNum, ctx.lines[i]?.trim() ?? '', 'Symbol() used as a DI token. Mostly we avoid Symbol if we can — see fix options below.'));
68
69
  }
@@ -1 +1 @@
1
- {"version":3,"file":"no-symbol-di-tokens.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-symbol-di-tokens.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAE1C,MAAM,eAAe,GAAG,wBAAwB,CAAC;AAEjD,MAAM,UAAU,GAAa,CAAC,aAAa,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;AAE3E,SAAS,WAAW,CAAC,OAAe;IAChC,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACb,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACzB,EAAE,IAAI,IAAI,CAAC;gBACX,CAAC,IAAI,CAAC,CAAC;gBACP,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG;oBAAE,CAAC,IAAI,CAAC,CAAC;gBAC/B,SAAS;YACb,CAAC;YACD,EAAE,IAAI,OAAO,CAAC;YACd,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACb,CAAC;QACD,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACb,EAAE,IAAI,MAAM,CAAC;YACb,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACb,CAAC;QACD,IAAI,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YAC/B,EAAE,IAAI,IAAI,GAAG,EAAE,CAAC;YAChB,CAAC,IAAI,CAAC,CAAC;YACP,SAAS;QACb,CAAC;QACD,EAAE,IAAI,EAAE,CAAC;QACT,CAAC,IAAI,CAAC,CAAC;IACX,CAAC;IACD,OAAO,IAAI,MAAM,CAAC,GAAG,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CAAC,YAAoB,EAAE,YAA+B;IACxE,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACxE,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,OAAe,EAAE,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,oBAAoB,GAAa;IACnC,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,oHAAoH;IACjI,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9B,cAAc,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE;IACpC,OAAO,EAAE;QACL,uFAAuF;QACvF,sHAAsH;QACtH,iIAAiI;QACjI,8EAA8E;KACjF;IAED,KAAK,CAAC,GAAgB;QAClB,MAAM,YAAY,GAAI,GAAG,CAAC,OAAO,CAAC,cAAc,CAA0B,IAAI,EAAE,CAAC;QACjF,IAAI,aAAa,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC;YAAE,OAAO,EAAE,CAAC;QAE7D,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;gBAAE,SAAS;YACpD,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,qBAAqB,CAAC;gBAAE,SAAS;YACjE,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAC1B,wFAAwF,CAC3F,CAAC,CAAC;QACP,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAC;AAEF,kBAAe,oBAAoB,CAAC","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\n\nconst SYMBOL_DI_REGEX = /=\\s*Symbol(?:\\.for)?\\(/;\n\nconst TEST_PATHS: RegExp[] = [/\\.test\\.ts$/, /\\.spec\\.ts$/, /__tests__\\//];\n\nfunction globToRegex(pattern: string): RegExp {\n let re = '';\n let i = 0;\n while (i < pattern.length) {\n const ch = pattern[i];\n if (ch === '*') {\n if (pattern[i + 1] === '*') {\n re += '.*';\n i += 2;\n if (pattern[i] === '/') i += 1;\n continue;\n }\n re += '[^/]*';\n i += 1;\n continue;\n }\n if (ch === '?') {\n re += '[^/]';\n i += 1;\n continue;\n }\n if ('.+^$(){}|[]\\\\'.includes(ch)) {\n re += '\\\\' + ch;\n i += 1;\n continue;\n }\n re += ch;\n i += 1;\n }\n return new RegExp('^' + re + '$');\n}\n\nfunction isAllowedPath(relativePath: string, allowedPaths: readonly string[]): boolean {\n if (TEST_PATHS.some((re: RegExp) => re.test(relativePath))) return true;\n return allowedPaths.some((pattern: string) => globToRegex(pattern).test(relativePath));\n}\n\nconst noSymbolDiTokensRule: EditRule = {\n name: 'no-symbol-di-tokens',\n description: 'Disallow Symbol() DI tokens outside explicitly configured paths. Use @provideSingleton() + inject-by-type instead.',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: { allowedPaths: [] },\n fixHint: [\n 'Option 1: Use @provideSingleton() on the class and inject by type — no Symbol needed.',\n 'Option 2: Implement an API interface — import the Symbol from the API definition and use @provideSingletonAs(TOKEN).',\n 'Option 3: External lib class (DataSource, Anthropic, etc.) — bind<Cls>(Cls).toDynamicValue(...).inSingletonScope() — no Symbol.',\n 'Option 4 (last resort): // webpieces-disable no-symbol-di-tokens -- <reason>',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const allowedPaths = (ctx.options['allowedPaths'] as string[] | undefined) ?? [];\n if (isAllowedPath(ctx.relativePath, allowedPaths)) return [];\n\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n if (!SYMBOL_DI_REGEX.test(stripped ?? '')) continue;\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, 'no-symbol-di-tokens')) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i]?.trim() ?? '',\n 'Symbol() used as a DI token. Mostly we avoid Symbol if we can — see fix options below.',\n ));\n }\n return violations;\n },\n};\n\nexport default noSymbolDiTokensRule;\n"]}
1
+ {"version":3,"file":"no-symbol-di-tokens.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-symbol-di-tokens.ts"],"names":[],"mappings":"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","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { RULE_NAMES } from '@webpieces/rules-config';\n\nconst SYMBOL_DI_REGEX = /=\\s*Symbol(?:\\.for)?\\(/;\n\nconst TEST_PATHS: RegExp[] = [/\\.test\\.ts$/, /\\.spec\\.ts$/, /__tests__\\//];\n\nfunction globToRegex(pattern: string): RegExp {\n let re = '';\n let i = 0;\n while (i < pattern.length) {\n const ch = pattern[i];\n if (ch === '*') {\n if (pattern[i + 1] === '*') {\n re += '.*';\n i += 2;\n if (pattern[i] === '/') i += 1;\n continue;\n }\n re += '[^/]*';\n i += 1;\n continue;\n }\n if (ch === '?') {\n re += '[^/]';\n i += 1;\n continue;\n }\n if ('.+^$(){}|[]\\\\'.includes(ch)) {\n re += '\\\\' + ch;\n i += 1;\n continue;\n }\n re += ch;\n i += 1;\n }\n return new RegExp('^' + re + '$');\n}\n\nfunction isAllowedPath(relativePath: string, allowedPaths: readonly string[]): boolean {\n if (TEST_PATHS.some((re: RegExp) => re.test(relativePath))) return true;\n return allowedPaths.some((pattern: string) => globToRegex(pattern).test(relativePath));\n}\n\nconst noSymbolDiTokensRule: EditRule = {\n name: 'no-symbol-di-tokens',\n description: 'Disallow Symbol() DI tokens outside explicitly configured paths. Use @provideSingleton() + inject-by-type instead.',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: { allowedPaths: [] },\n fixHint: [\n 'Option 1: Use @provideSingleton() on the class and inject by type — no Symbol needed.',\n 'Option 2: Implement an API interface — import the Symbol from the API definition and use @provideSingletonAs(TOKEN).',\n 'Option 3: External lib class (DataSource, Anthropic, etc.) — bind<Cls>(Cls).toDynamicValue(...).inSingletonScope() — no Symbol.',\n 'Option 4 (last resort): // webpieces-disable no-symbol-di-tokens -- <reason>',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const allowedPaths = (ctx.options['allowedPaths'] as string[] | undefined) ?? [];\n if (isAllowedPath(ctx.relativePath, allowedPaths)) return [];\n\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n if (!SYMBOL_DI_REGEX.test(stripped ?? '')) continue;\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, RULE_NAMES.NO_SYMBOL_DI_TOKENS)) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i]?.trim() ?? '',\n 'Symbol() used as a DI token. Mostly we avoid Symbol if we can — see fix options below.',\n ));\n }\n return violations;\n },\n};\n\nexport default noSymbolDiTokensRule;\n"]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const types_1 = require("../types");
4
+ const rules_config_1 = require("@webpieces/rules-config");
4
5
  const instruct_ai_writer_1 = require("../instruct-ai-writer");
5
6
  const TRY_PATTERN = /\btry\s*\{/;
6
7
  // Both webpieces-disable and the existing ESLint directive suppress this rule
@@ -28,7 +29,7 @@ const noUnmanagedExceptionsRule = {
28
29
  if (!TRY_PATTERN.test(stripped))
29
30
  continue;
30
31
  const lineNum = i + 1;
31
- if (ctx.isLineDisabled(lineNum, 'no-unmanaged-exceptions'))
32
+ if (ctx.isLineDisabled(lineNum, rules_config_1.RULE_NAMES.NO_UNMANAGED_EXCEPTIONS))
32
33
  continue;
33
34
  if (hasPrecedingDisable(ctx.lines, i))
34
35
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"no-unmanaged-exceptions.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-unmanaged-exceptions.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAC1C,8DAA+D;AAE/D,MAAM,WAAW,GAAG,YAAY,CAAC;AAEjC,8EAA8E;AAC9E,MAAM,eAAe,GAAG,gGAAgG,CAAC;AAEzH,MAAM,yBAAyB,GAAa;IACxC,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EAAE,uHAAuH;IACpI,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9B,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE;QACL,4KAA4K;QAC5K,6GAA6G;QAC7G,yCAAyC;QACzC,2FAA2F;QAC3F,0EAA0E;QAC1E,uEAAuE;QACvE,4FAA4F;QAC5F,oMAAoM;KACvM;IAED,KAAK,CAAC,GAAgB;QAClB,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC1C,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,yBAAyB,CAAC;gBAAE,SAAS;YACrE,IAAI,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;gBAAE,SAAS;YAChD,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACnB,gLAAgL,CACnL,CAAC,CAAC;QACP,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,IAAA,2CAAsB,EAAC,GAAG,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC;QAChG,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAC;AAEF,SAAS,mBAAmB,CAAC,KAAwB,EAAE,GAAW;IAC9D,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAChC,OAAO,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED,kBAAe,yBAAyB,CAAC","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { writeTemplateIfMissing } from '../instruct-ai-writer';\n\nconst TRY_PATTERN = /\\btry\\s*\\{/;\n\n// Both webpieces-disable and the existing ESLint directive suppress this rule\nconst DISABLE_PATTERN = /@webpieces\\/no-unmanaged-exceptions|webpieces-disable\\s+(?:[\\w-]+,\\s*)*no-unmanaged-exceptions/;\n\nconst noUnmanagedExceptionsRule: EditRule = {\n name: 'no-unmanaged-exceptions',\n description: 'try/catch is generally not allowed. Only allowed in chokepoints (filter, globalErrorHandler) or other rare locations.',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: {},\n fixHint: [\n 'Fix Option 1 (preferred): Remove the try/catch — let the exception bubble to the top-level chokepoint (filter, globalErrorHandler) where it is already logged and handled.',\n 'Fix Option 2 (ask the human first): If you genuinely believe this IS a chokepoint, STOP and tell the human:',\n ' - What exception could be thrown here',\n ' - What the current top-level chokepoint is (the try/catch at the top of the call stack)',\n ' - Why throwing to that chokepoint would be wrong in this specific case',\n ' Then ask: \"Should I add a disable comment or remove the try/catch?\"',\n ' Only add // webpieces-disable no-unmanaged-exceptions -- <reason> if the human says yes.',\n 'NOTE: If the code is calling an external process (execSync, fs, network), the correct answer is almost always Option 1 — let it throw. Hooks have a top-level runner that reports errors properly.',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n if (!TRY_PATTERN.test(stripped)) continue;\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, 'no-unmanaged-exceptions')) continue;\n if (hasPrecedingDisable(ctx.lines, i)) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n 'try/catch is generally not allowed. READ .webpieces/instruct-ai/webpieces.exceptions.md to understand why. Only chokepoints (filter, globalErrorHandler) may catch exceptions.',\n ));\n }\n if (violations.length > 0) writeTemplateIfMissing(ctx.workspaceRoot, 'webpieces.exceptions.md');\n return violations;\n },\n};\n\nfunction hasPrecedingDisable(lines: readonly string[], idx: number): boolean {\n if (idx === 0) return false;\n const prevLine = lines[idx - 1];\n return DISABLE_PATTERN.test(prevLine);\n}\n\nexport default noUnmanagedExceptionsRule;\n"]}
1
+ {"version":3,"file":"no-unmanaged-exceptions.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/no-unmanaged-exceptions.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAC1C,0DAAqD;AACrD,8DAA+D;AAE/D,MAAM,WAAW,GAAG,YAAY,CAAC;AAEjC,8EAA8E;AAC9E,MAAM,eAAe,GAAG,gGAAgG,CAAC;AAEzH,MAAM,yBAAyB,GAAa;IACxC,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EAAE,uHAAuH;IACpI,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9B,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE;QACL,4KAA4K;QAC5K,6GAA6G;QAC7G,yCAAyC;QACzC,2FAA2F;QAC3F,0EAA0E;QAC1E,uEAAuE;QACvE,4FAA4F;QAC5F,oMAAoM;KACvM;IAED,KAAK,CAAC,GAAgB;QAClB,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC1C,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,yBAAU,CAAC,uBAAuB,CAAC;gBAAE,SAAS;YAC9E,IAAI,mBAAmB,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;gBAAE,SAAS;YAChD,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACnB,gLAAgL,CACnL,CAAC,CAAC;QACP,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,IAAA,2CAAsB,EAAC,GAAG,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC;QAChG,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAC;AAEF,SAAS,mBAAmB,CAAC,KAAwB,EAAE,GAAW;IAC9D,IAAI,GAAG,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC5B,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAChC,OAAO,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC1C,CAAC;AAED,kBAAe,yBAAyB,CAAC","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { RULE_NAMES } from '@webpieces/rules-config';\nimport { writeTemplateIfMissing } from '../instruct-ai-writer';\n\nconst TRY_PATTERN = /\\btry\\s*\\{/;\n\n// Both webpieces-disable and the existing ESLint directive suppress this rule\nconst DISABLE_PATTERN = /@webpieces\\/no-unmanaged-exceptions|webpieces-disable\\s+(?:[\\w-]+,\\s*)*no-unmanaged-exceptions/;\n\nconst noUnmanagedExceptionsRule: EditRule = {\n name: 'no-unmanaged-exceptions',\n description: 'try/catch is generally not allowed. Only allowed in chokepoints (filter, globalErrorHandler) or other rare locations.',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: {},\n fixHint: [\n 'Fix Option 1 (preferred): Remove the try/catch — let the exception bubble to the top-level chokepoint (filter, globalErrorHandler) where it is already logged and handled.',\n 'Fix Option 2 (ask the human first): If you genuinely believe this IS a chokepoint, STOP and tell the human:',\n ' - What exception could be thrown here',\n ' - What the current top-level chokepoint is (the try/catch at the top of the call stack)',\n ' - Why throwing to that chokepoint would be wrong in this specific case',\n ' Then ask: \"Should I add a disable comment or remove the try/catch?\"',\n ' Only add // webpieces-disable no-unmanaged-exceptions -- <reason> if the human says yes.',\n 'NOTE: If the code is calling an external process (execSync, fs, network), the correct answer is almost always Option 1 — let it throw. Hooks have a top-level runner that reports errors properly.',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n if (!TRY_PATTERN.test(stripped)) continue;\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, RULE_NAMES.NO_UNMANAGED_EXCEPTIONS)) continue;\n if (hasPrecedingDisable(ctx.lines, i)) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n 'try/catch is generally not allowed. READ .webpieces/instruct-ai/webpieces.exceptions.md to understand why. Only chokepoints (filter, globalErrorHandler) may catch exceptions.',\n ));\n }\n if (violations.length > 0) writeTemplateIfMissing(ctx.workspaceRoot, 'webpieces.exceptions.md');\n return violations;\n },\n};\n\nfunction hasPrecedingDisable(lines: readonly string[], idx: number): boolean {\n if (idx === 0) return false;\n const prevLine = lines[idx - 1];\n return DISABLE_PATTERN.test(prevLine);\n}\n\nexport default noUnmanagedExceptionsRule;\n"]}
@@ -1,74 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const child_process_1 = require("child_process");
4
- const fs_1 = require("fs");
5
- const path_1 = require("path");
6
3
  const types_1 = require("../types");
7
4
  const FIX_HINT = [
8
- 'Branch is not up-to-date with origin/main.',
9
- 'Run the squash-update process to sync with main first:',
10
- ' pnpm wp-git-update',
11
- 'Then retry: gh pr create ...',
12
- '',
13
- 'Do NOT use "git merge origin/main" or "git rebase" — these break the 3-point fork-point system.',
14
- 'See docs/git-workflow.md for the full squash-merge update process.',
5
+ 'Direct PR creation is blocked. Create or update a PR ONLY via the gated command:',
6
+ ' pnpm wp-upsert-pr',
7
+ 'It updates the branch from main (3-point merge), runs the real build (nx affected), and',
8
+ 'assembles the PR dashboard then creates/updates the PR itself. A failing build = no PR.',
9
+ 'There is nothing to paste or attest to; the command does the work.',
15
10
  ];
11
+ // Detect every way an agent could open/update a PR directly, so the ONLY path left is
12
+ // `pnpm wp-upsert-pr` (whose internal `gh pr create` runs as a child process the hook
13
+ // never sees). Read-only `gh pr list` / `gh api .../pulls` GET are intentionally allowed.
14
+ function isDirectPrCreation(cmd) {
15
+ if (/\bgh\s+pr\s+(create|edit)\b/.test(cmd))
16
+ return true;
17
+ const ghApiPulls = /\bgh\s+api\b[^\n]*\/pulls\b/.test(cmd);
18
+ if (ghApiPulls && (/--method\s+POST/i.test(cmd) || /-X\s+POST/i.test(cmd) || /\s-f\b/.test(cmd) || /\s-F\b/.test(cmd) || /--field\b/.test(cmd))) {
19
+ return true;
20
+ }
21
+ const curlPulls = /\bcurl\b[^\n]*api\.github\.com[^\n]*\/pulls\b/.test(cmd);
22
+ if (curlPulls && (/-X\s*POST/i.test(cmd) || /--request\s+POST/i.test(cmd) || /(\s-d\b|--data\b)/.test(cmd))) {
23
+ return true;
24
+ }
25
+ return false;
26
+ }
16
27
  const prCreationGuard = {
17
28
  name: 'pr-creation-guard',
18
- description: 'Block PR creation when the branch has not been updated from origin/main via the squash-merge process.',
29
+ description: 'Block direct PR creation/edit (gh pr / gh api / curl) so PRs go only through pnpm wp-upsert-pr.',
19
30
  scope: 'bash',
20
31
  files: [],
21
- defaultOptions: { buildCommand: '', requireTextInPr: '' },
32
+ defaultOptions: {},
22
33
  fixHint: FIX_HINT,
23
34
  check(ctx) {
24
- if (!/gh\s+pr\s+create/.test(ctx.command))
35
+ if (!isDirectPrCreation(ctx.command))
25
36
  return [];
26
- (0, child_process_1.execSync)('git fetch origin main --quiet', { cwd: ctx.workspaceRoot, encoding: 'utf8' });
27
- // spawnSync is used here because exit code 1 means "not an ancestor" (not an error)
28
- const result = (0, child_process_1.spawnSync)('git', ['merge-base', '--is-ancestor', 'origin/main', 'HEAD'], { cwd: ctx.workspaceRoot });
29
- if (result.status !== 0) {
30
- return [new types_1.Violation(1, truncate(ctx.command), [
31
- 'Branch is not up-to-date with origin/main.',
32
- 'Run the squash-update process first:',
33
- ' pnpm wp-git-update',
34
- 'Do NOT use "git merge origin/main" or "git rebase" — these break the 3-point fork-point system.',
35
- 'See docs/git-workflow.md for details.',
36
- 'Then retry: gh pr create',
37
- ].join('\n'))];
38
- }
39
- const buildCmd = ctx.options['buildCommand'];
40
- const requireText = ctx.options['requireTextInPr'];
41
- if (buildCmd && requireText) {
42
- const body = extractPrBody(ctx.command, ctx.workspaceRoot);
43
- if (body !== null && !body.includes(requireText)) {
44
- return [new types_1.Violation(1, truncate(ctx.command), [
45
- 'PR body is missing the required CI confirmation.',
46
- 'Before creating a PR you must run:',
47
- ` ${buildCmd}`,
48
- 'After it passes, add this exact phrase to your PR description:',
49
- ` "${requireText}"`,
50
- ].join('\n'))];
51
- }
52
- }
53
- return [];
37
+ return [new types_1.Violation(1, truncate(ctx.command), [
38
+ 'Direct PR creation/update is blocked.',
39
+ 'Use the gated command instead it runs the build and builds the dashboard:',
40
+ ' pnpm wp-upsert-pr',
41
+ ].join('\n'))];
54
42
  },
55
43
  };
56
- function extractPrBody(command, workspaceRoot) {
57
- const fileMatch = /--body-file\s+(\S+)/.exec(command);
58
- if (fileMatch) {
59
- const resolved = (0, path_1.isAbsolute)(fileMatch[1]) ? fileMatch[1] : (0, path_1.join)(workspaceRoot, fileMatch[1]);
60
- if (!(0, fs_1.existsSync)(resolved))
61
- return null;
62
- return (0, fs_1.readFileSync)(resolved, 'utf8');
63
- }
64
- const doubleQuoteMatch = /--body\s+"((?:[^"\\]|\\.)*)"/.exec(command);
65
- if (doubleQuoteMatch)
66
- return doubleQuoteMatch[1];
67
- const singleQuoteMatch = /--body\s+'((?:[^'\\]|\\.)*)'/.exec(command);
68
- if (singleQuoteMatch)
69
- return singleQuoteMatch[1];
70
- return null;
71
- }
72
44
  function truncate(s) {
73
45
  const MAX = 120;
74
46
  return s.length <= MAX ? s : s.slice(0, MAX) + '…';
@@ -1 +1 @@
1
- {"version":3,"file":"pr-creation-guard.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/pr-creation-guard.ts"],"names":[],"mappings":";;AAAA,iDAAoD;AACpD,2BAA8C;AAC9C,+BAAwC;AAExC,oCAA0C;AAE1C,MAAM,QAAQ,GAAsB;IAChC,4CAA4C;IAC5C,wDAAwD;IACxD,sBAAsB;IACtB,8BAA8B;IAC9B,EAAE;IACF,iGAAiG;IACjG,oEAAoE;CACvE,CAAC;AAEF,MAAM,eAAe,GAAa;IAC9B,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE,uGAAuG;IACpH,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,EAAE;IACT,cAAc,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE;IACzD,OAAO,EAAE,QAAQ;IAEjB,KAAK,CAAC,GAAgB;QAClB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,EAAE,CAAC;QAErD,IAAA,wBAAQ,EAAC,+BAA+B,EAAE,EAAE,GAAG,EAAE,GAAG,CAAC,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QAExF,oFAAoF;QACpF,MAAM,MAAM,GAAG,IAAA,yBAAS,EACpB,KAAK,EAAE,CAAC,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,CAAC,EAC7D,EAAE,GAAG,EAAE,GAAG,CAAC,aAAa,EAAE,CAC7B,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,iBAAC,CACT,CAAC,EACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EACrB;oBACI,4CAA4C;oBAC5C,sCAAsC;oBACtC,sBAAsB;oBACtB,iGAAiG;oBACjG,uCAAuC;oBACvC,0BAA0B;iBAC7B,CAAC,IAAI,CAAC,IAAI,CAAC,CACf,CAAC,CAAC;QACP,CAAC;QAED,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,CAAW,CAAC;QACvD,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAW,CAAC;QAC7D,IAAI,QAAQ,IAAI,WAAW,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;YAC3D,IAAI,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC/C,OAAO,CAAC,IAAI,iBAAC,CACT,CAAC,EACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EACrB;wBACI,kDAAkD;wBAClD,oCAAoC;wBACpC,KAAK,QAAQ,EAAE;wBACf,gEAAgE;wBAChE,MAAM,WAAW,GAAG;qBACvB,CAAC,IAAI,CAAC,IAAI,CAAC,CACf,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;CACJ,CAAC;AAEF,SAAS,aAAa,CAAC,OAAe,EAAE,aAAqB;IACzD,MAAM,SAAS,GAAG,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtD,IAAI,SAAS,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAG,IAAA,iBAAU,EAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAA,WAAI,EAAC,aAAa,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7F,IAAI,CAAC,IAAA,eAAU,EAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QACvC,OAAO,IAAA,iBAAY,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IACD,MAAM,gBAAgB,GAAG,8BAA8B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtE,IAAI,gBAAgB;QAAE,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,gBAAgB,GAAG,8BAA8B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtE,IAAI,gBAAgB;QAAE,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACjD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS;IACvB,MAAM,GAAG,GAAG,GAAG,CAAC;IAChB,OAAO,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;AACvD,CAAC;AAED,kBAAe,eAAe,CAAC","sourcesContent":["import { execSync, spawnSync } from 'child_process';\nimport { readFileSync, existsSync } from 'fs';\nimport { isAbsolute, join } from 'path';\nimport type { BashRule, BashContext, Violation } from '../types';\nimport { Violation as V } from '../types';\n\nconst FIX_HINT: readonly string[] = [\n 'Branch is not up-to-date with origin/main.',\n 'Run the squash-update process to sync with main first:',\n ' pnpm wp-git-update',\n 'Then retry: gh pr create ...',\n '',\n 'Do NOT use \"git merge origin/main\" or \"git rebase\" these break the 3-point fork-point system.',\n 'See docs/git-workflow.md for the full squash-merge update process.',\n];\n\nconst prCreationGuard: BashRule = {\n name: 'pr-creation-guard',\n description: 'Block PR creation when the branch has not been updated from origin/main via the squash-merge process.',\n scope: 'bash',\n files: [],\n defaultOptions: { buildCommand: '', requireTextInPr: '' },\n fixHint: FIX_HINT,\n\n check(ctx: BashContext): readonly Violation[] {\n if (!/gh\\s+pr\\s+create/.test(ctx.command)) return [];\n\n execSync('git fetch origin main --quiet', { cwd: ctx.workspaceRoot, encoding: 'utf8' });\n\n // spawnSync is used here because exit code 1 means \"not an ancestor\" (not an error)\n const result = spawnSync(\n 'git', ['merge-base', '--is-ancestor', 'origin/main', 'HEAD'],\n { cwd: ctx.workspaceRoot },\n );\n\n if (result.status !== 0) {\n return [new V(\n 1,\n truncate(ctx.command),\n [\n 'Branch is not up-to-date with origin/main.',\n 'Run the squash-update process first:',\n ' pnpm wp-git-update',\n 'Do NOT use \"git merge origin/main\" or \"git rebase\" these break the 3-point fork-point system.',\n 'See docs/git-workflow.md for details.',\n 'Then retry: gh pr create',\n ].join('\\n'),\n )];\n }\n\n const buildCmd = ctx.options['buildCommand'] as string;\n const requireText = ctx.options['requireTextInPr'] as string;\n if (buildCmd && requireText) {\n const body = extractPrBody(ctx.command, ctx.workspaceRoot);\n if (body !== null && !body.includes(requireText)) {\n return [new V(\n 1,\n truncate(ctx.command),\n [\n 'PR body is missing the required CI confirmation.',\n 'Before creating a PR you must run:',\n ` ${buildCmd}`,\n 'After it passes, add this exact phrase to your PR description:',\n ` \"${requireText}\"`,\n ].join('\\n'),\n )];\n }\n }\n return [];\n },\n};\n\nfunction extractPrBody(command: string, workspaceRoot: string): string | null {\n const fileMatch = /--body-file\\s+(\\S+)/.exec(command);\n if (fileMatch) {\n const resolved = isAbsolute(fileMatch[1]) ? fileMatch[1] : join(workspaceRoot, fileMatch[1]);\n if (!existsSync(resolved)) return null;\n return readFileSync(resolved, 'utf8');\n }\n const doubleQuoteMatch = /--body\\s+\"((?:[^\"\\\\]|\\\\.)*)\"/.exec(command);\n if (doubleQuoteMatch) return doubleQuoteMatch[1];\n const singleQuoteMatch = /--body\\s+'((?:[^'\\\\]|\\\\.)*)'/.exec(command);\n if (singleQuoteMatch) return singleQuoteMatch[1];\n return null;\n}\n\nfunction truncate(s: string): string {\n const MAX = 120;\n return s.length <= MAX ? s : s.slice(0, MAX) + '…';\n}\n\nexport default prCreationGuard;\n"]}
1
+ {"version":3,"file":"pr-creation-guard.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/pr-creation-guard.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAE1C,MAAM,QAAQ,GAAsB;IAChC,kFAAkF;IAClF,qBAAqB;IACrB,yFAAyF;IACzF,2FAA2F;IAC3F,oEAAoE;CACvE,CAAC;AAEF,sFAAsF;AACtF,sFAAsF;AACtF,0FAA0F;AAC1F,SAAS,kBAAkB,CAAC,GAAW;IACnC,IAAI,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAEzD,MAAM,UAAU,GAAG,6BAA6B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3D,IAAI,UAAU,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC9I,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,+CAA+C,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5E,IAAI,SAAS,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QAC1G,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,MAAM,eAAe,GAAa;IAC9B,IAAI,EAAE,mBAAmB;IACzB,WAAW,EAAE,iGAAiG;IAC9G,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,EAAE;IACT,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE,QAAQ;IAEjB,KAAK,CAAC,GAAgB;QAClB,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,EAAE,CAAC;QAChD,OAAO,CAAC,IAAI,iBAAC,CACT,CAAC,EACD,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EACrB;gBACI,uCAAuC;gBACvC,6EAA6E;gBAC7E,qBAAqB;aACxB,CAAC,IAAI,CAAC,IAAI,CAAC,CACf,CAAC,CAAC;IACP,CAAC;CACJ,CAAC;AAEF,SAAS,QAAQ,CAAC,CAAS;IACvB,MAAM,GAAG,GAAG,GAAG,CAAC;IAChB,OAAO,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;AACvD,CAAC;AAED,kBAAe,eAAe,CAAC","sourcesContent":["import type { BashRule, BashContext, Violation } from '../types';\nimport { Violation as V } from '../types';\n\nconst FIX_HINT: readonly string[] = [\n 'Direct PR creation is blocked. Create or update a PR ONLY via the gated command:',\n ' pnpm wp-upsert-pr',\n 'It updates the branch from main (3-point merge), runs the real build (nx affected), and',\n 'assembles the PR dashboard then creates/updates the PR itself. A failing build = no PR.',\n 'There is nothing to paste or attest to; the command does the work.',\n];\n\n// Detect every way an agent could open/update a PR directly, so the ONLY path left is\n// `pnpm wp-upsert-pr` (whose internal `gh pr create` runs as a child process the hook\n// never sees). Read-only `gh pr list` / `gh api .../pulls` GET are intentionally allowed.\nfunction isDirectPrCreation(cmd: string): boolean {\n if (/\\bgh\\s+pr\\s+(create|edit)\\b/.test(cmd)) return true;\n\n const ghApiPulls = /\\bgh\\s+api\\b[^\\n]*\\/pulls\\b/.test(cmd);\n if (ghApiPulls && (/--method\\s+POST/i.test(cmd) || /-X\\s+POST/i.test(cmd) || /\\s-f\\b/.test(cmd) || /\\s-F\\b/.test(cmd) || /--field\\b/.test(cmd))) {\n return true;\n }\n\n const curlPulls = /\\bcurl\\b[^\\n]*api\\.github\\.com[^\\n]*\\/pulls\\b/.test(cmd);\n if (curlPulls && (/-X\\s*POST/i.test(cmd) || /--request\\s+POST/i.test(cmd) || /(\\s-d\\b|--data\\b)/.test(cmd))) {\n return true;\n }\n return false;\n}\n\nconst prCreationGuard: BashRule = {\n name: 'pr-creation-guard',\n description: 'Block direct PR creation/edit (gh pr / gh api / curl) so PRs go only through pnpm wp-upsert-pr.',\n scope: 'bash',\n files: [],\n defaultOptions: {},\n fixHint: FIX_HINT,\n\n check(ctx: BashContext): readonly Violation[] {\n if (!isDirectPrCreation(ctx.command)) return [];\n return [new V(\n 1,\n truncate(ctx.command),\n [\n 'Direct PR creation/update is blocked.',\n 'Use the gated command instead it runs the build and builds the dashboard:',\n ' pnpm wp-upsert-pr',\n ].join('\\n'),\n )];\n },\n};\n\nfunction truncate(s: string): string {\n const MAX = 120;\n return s.length <= MAX ? s : s.slice(0, MAX) + '…';\n}\n\nexport default prCreationGuard;\n"]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const types_1 = require("../types");
4
+ const rules_config_1 = require("@webpieces/rules-config");
4
5
  // Matches function/method signatures that don't have `: ReturnType` before the `{` body opener.
5
6
  // Pattern: function name(<params>) { — missing `: Type` between `)` and `{`
6
7
  const FUNC_DECL_MISSING = /\bfunction\s+\w+\s*(?:<[^>]*>)?\s*\([^)]*\)\s*\{/;
@@ -29,7 +30,7 @@ const requireReturnTypeRule = {
29
30
  if (!isMissingReturnType(stripped))
30
31
  continue;
31
32
  const lineNum = i + 1;
32
- if (ctx.isLineDisabled(lineNum, 'require-return-type'))
33
+ if (ctx.isLineDisabled(lineNum, rules_config_1.RULE_NAMES.REQUIRE_RETURN_TYPE))
33
34
  continue;
34
35
  violations.push(new types_1.Violation(lineNum, ctx.lines[i].trim(), 'Missing return type annotation.'));
35
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"require-return-type.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/require-return-type.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAE1C,gGAAgG;AAChG,4EAA4E;AAC5E,MAAM,iBAAiB,GAAG,kDAAkD,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,cAAc,GAAG,yDAAyD,CAAC;AAEjF,qFAAqF;AACrF,MAAM,aAAa,GAAG,gEAAgE,CAAC;AAEvF,qEAAqE;AACrE,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC,iEAAiE;AACjE,MAAM,YAAY,GAAG,kFAAkF,CAAC;AAExG,MAAM,qBAAqB,GAAa;IACpC,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,yDAAyD;IACtE,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9B,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE;QACL,yDAAyD;QACzD,sDAAsD;KACzD;IAED,KAAK,CAAC,GAAgB;QAClB,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,qBAAqB,CAAC;gBAAE,SAAS;YACjE,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACnB,iCAAiC,CACpC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAC;AAEF,SAAS,mBAAmB,CAAC,IAAY;IACrC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,UAAU,GACZ,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,kBAAe,qBAAqB,CAAC","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\n\n// Matches function/method signatures that don't have `: ReturnType` before the `{` body opener.\n// Pattern: function name(<params>) { — missing `: Type` between `)` and `{`\nconst FUNC_DECL_MISSING = /\\bfunction\\s+\\w+\\s*(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*\\{/;\n\n// Matches class method signatures: indented, optional async, name(<params>) {\nconst METHOD_MISSING = /^\\s{2,}(?:async\\s+)?\\w+\\s*(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*\\{/;\n\n// Arrow function: const name = (async)? (<params>) => — missing `: Type` before `=>`\nconst ARROW_MISSING = /\\bconst\\s+\\w+\\s*=\\s*(?:async\\s+)?(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*=>/;\n\n// Lines that have ): ReturnType before { or => — these are COMPLIANT\nconst HAS_RETURN_TYPE = /\\)\\s*:\\s*\\S/;\n\n// Skip constructors, getters, setters, and control flow keywords\nconst SKIP_PATTERN = /\\b(?:constructor|get\\s+\\w+|set\\s+\\w+|if|else|while|for|switch|catch|return)\\s*\\(/;\n\nconst requireReturnTypeRule: EditRule = {\n name: 'require-return-type',\n description: 'Every function and method must declare its return type.',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: {},\n fixHint: [\n 'Add return type: function foo(x: T): ReturnType { ... }',\n '// webpieces-disable require-return-type -- <reason>',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n if (!isMissingReturnType(stripped)) continue;\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, 'require-return-type')) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n 'Missing return type annotation.',\n ));\n }\n return violations;\n },\n};\n\nfunction isMissingReturnType(line: string): boolean {\n if (SKIP_PATTERN.test(line)) return false;\n const isFuncLike =\n FUNC_DECL_MISSING.test(line) ||\n METHOD_MISSING.test(line) ||\n ARROW_MISSING.test(line);\n if (!isFuncLike) return false;\n if (HAS_RETURN_TYPE.test(line)) return false;\n return true;\n}\n\nexport default requireReturnTypeRule;\n"]}
1
+ {"version":3,"file":"require-return-type.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/require-return-type.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAC1C,0DAAqD;AAErD,gGAAgG;AAChG,4EAA4E;AAC5E,MAAM,iBAAiB,GAAG,kDAAkD,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,cAAc,GAAG,yDAAyD,CAAC;AAEjF,qFAAqF;AACrF,MAAM,aAAa,GAAG,gEAAgE,CAAC;AAEvF,qEAAqE;AACrE,MAAM,eAAe,GAAG,aAAa,CAAC;AAEtC,iEAAiE;AACjE,MAAM,YAAY,GAAG,kFAAkF,CAAC;AAExG,MAAM,qBAAqB,GAAa;IACpC,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,yDAAyD;IACtE,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9B,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE;QACL,yDAAyD;QACzD,sDAAsD;KACzD;IAED,KAAK,CAAC,GAAgB;QAClB,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAC7C,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,yBAAU,CAAC,mBAAmB,CAAC;gBAAE,SAAS;YAC1E,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACnB,iCAAiC,CACpC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAC;AAEF,SAAS,mBAAmB,CAAC,IAAY;IACrC,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,UAAU,GACZ,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;QACzB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7C,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,kBAAe,qBAAqB,CAAC","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { RULE_NAMES } from '@webpieces/rules-config';\n\n// Matches function/method signatures that don't have `: ReturnType` before the `{` body opener.\n// Pattern: function name(<params>) { — missing `: Type` between `)` and `{`\nconst FUNC_DECL_MISSING = /\\bfunction\\s+\\w+\\s*(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*\\{/;\n\n// Matches class method signatures: indented, optional async, name(<params>) {\nconst METHOD_MISSING = /^\\s{2,}(?:async\\s+)?\\w+\\s*(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*\\{/;\n\n// Arrow function: const name = (async)? (<params>) => — missing `: Type` before `=>`\nconst ARROW_MISSING = /\\bconst\\s+\\w+\\s*=\\s*(?:async\\s+)?(?:<[^>]*>)?\\s*\\([^)]*\\)\\s*=>/;\n\n// Lines that have ): ReturnType before { or => — these are COMPLIANT\nconst HAS_RETURN_TYPE = /\\)\\s*:\\s*\\S/;\n\n// Skip constructors, getters, setters, and control flow keywords\nconst SKIP_PATTERN = /\\b(?:constructor|get\\s+\\w+|set\\s+\\w+|if|else|while|for|switch|catch|return)\\s*\\(/;\n\nconst requireReturnTypeRule: EditRule = {\n name: 'require-return-type',\n description: 'Every function and method must declare its return type.',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: {},\n fixHint: [\n 'Add return type: function foo(x: T): ReturnType { ... }',\n '// webpieces-disable require-return-type -- <reason>',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n for (let i = 0; i < ctx.strippedLines.length; i += 1) {\n const stripped = ctx.strippedLines[i];\n if (!isMissingReturnType(stripped)) continue;\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, RULE_NAMES.REQUIRE_RETURN_TYPE)) continue;\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n 'Missing return type annotation.',\n ));\n }\n return violations;\n },\n};\n\nfunction isMissingReturnType(line: string): boolean {\n if (SKIP_PATTERN.test(line)) return false;\n const isFuncLike =\n FUNC_DECL_MISSING.test(line) ||\n METHOD_MISSING.test(line) ||\n ARROW_MISSING.test(line);\n if (!isFuncLike) return false;\n if (HAS_RETURN_TYPE.test(line)) return false;\n return true;\n}\n\nexport default requireReturnTypeRule;\n"]}
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const types_1 = require("../types");
4
+ const rules_config_1 = require("@webpieces/rules-config");
4
5
  const instruct_ai_writer_1 = require("../instruct-ai-writer");
5
6
  /**
6
7
  * Matches: throw new SomeClass(
@@ -38,7 +39,7 @@ const throwCauseRequiredRule = {
38
39
  if (CAUSE_PATTERN.test(stripped))
39
40
  continue;
40
41
  const lineNum = i + 1;
41
- if (ctx.isLineDisabled(lineNum, 'throw-cause-required'))
42
+ if (ctx.isLineDisabled(lineNum, rules_config_1.RULE_NAMES.THROW_CAUSE_REQUIRED))
42
43
  continue;
43
44
  violations.push(new types_1.Violation(lineNum, ctx.lines[i].trim(), 'Rethrowing with error.message loses the original stack trace. Use { cause: error } to chain it.'));
44
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"throw-cause-required.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/throw-cause-required.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAC1C,8DAA+D;AAE/D;;GAEG;AACH,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAErD;;GAEG;AACH,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAEtD;;GAEG;AACH,MAAM,aAAa,GAAG,0BAA0B,CAAC;AAEjD,MAAM,sBAAsB,GAAa;IACrC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,4GAA4G;IACzH,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9B,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE;QACL,6GAA6G;QAC7G,0HAA0H;QAC1H,0IAA0I;QAC1I,gGAAgG;KACnG;IAED,KAAK,CAAC,GAAgB;QAClB,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC;QAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAChD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACpD,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAE3C,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,sBAAsB,CAAC;gBAAE,SAAS;YAElE,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACnB,iGAAiG,CACpG,CAAC,CAAC;QACP,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,IAAA,2CAAsB,EAAC,GAAG,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC;QAChG,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAC;AAEF,kBAAe,sBAAsB,CAAC","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { writeTemplateIfMissing } from '../instruct-ai-writer';\n\n/**\n * Matches: throw new SomeClass(\n */\nconst THROW_NEW_PATTERN = /\\bthrow\\s+new\\s+\\w+\\s*\\(/;\n\n/**\n * Matches: error.message or error2.message or error3.message\n */\nconst ERROR_MESSAGE_PATTERN = /\\berror\\d*\\.message\\b/;\n\n/**\n * Matches: cause: error or cause: error2 etc. (the good pattern)\n */\nconst CAUSE_PATTERN = /\\bcause\\s*:\\s*error\\d*\\b/;\n\nconst throwCauseRequiredRule: EditRule = {\n name: 'throw-cause-required',\n description: 'When rethrowing with added context, chain the original exception: throw new Error(\"msg\", { cause: error })',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: {},\n fixHint: [\n 'Option 1 — Remove the try-catch entirely. Letting the original exception bubble is usually the best option.',\n 'Option 2 — throw new Error(\"add more info here\", { cause: error }); chains the error and preserves the full stack trace.',\n 'Option 3 — throw new SpecificError(\"add info here\", { cause: error }); e.g. new InformAiError(\"what happened for AI\", { cause: error }).',\n '[Only if disableAllowed:true] Option 4 — // webpieces-disable throw-cause-required -- <reason>',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n const lines = ctx.strippedLines;\n\n for (let i = 0; i < lines.length; i += 1) {\n const stripped = lines[i];\n if (!THROW_NEW_PATTERN.test(stripped)) continue;\n if (!ERROR_MESSAGE_PATTERN.test(stripped)) continue;\n if (CAUSE_PATTERN.test(stripped)) continue;\n\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, 'throw-cause-required')) continue;\n\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n 'Rethrowing with error.message loses the original stack trace. Use { cause: error } to chain it.',\n ));\n }\n\n if (violations.length > 0) writeTemplateIfMissing(ctx.workspaceRoot, 'webpieces.exceptions.md');\n return violations;\n },\n};\n\nexport default throwCauseRequiredRule;\n"]}
1
+ {"version":3,"file":"throw-cause-required.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/rules/throw-cause-required.ts"],"names":[],"mappings":";;AACA,oCAA0C;AAC1C,0DAAqD;AACrD,8DAA+D;AAE/D;;GAEG;AACH,MAAM,iBAAiB,GAAG,0BAA0B,CAAC;AAErD;;GAEG;AACH,MAAM,qBAAqB,GAAG,uBAAuB,CAAC;AAEtD;;GAEG;AACH,MAAM,aAAa,GAAG,0BAA0B,CAAC;AAEjD,MAAM,sBAAsB,GAAa;IACrC,IAAI,EAAE,sBAAsB;IAC5B,WAAW,EAAE,4GAA4G;IACzH,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;IAC9B,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE;QACL,6GAA6G;QAC7G,0HAA0H;QAC1H,0IAA0I;QAC1I,gGAAgG;KACnG;IAED,KAAK,CAAC,GAAgB;QAClB,MAAM,UAAU,GAAQ,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,aAAa,CAAC;QAEhC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1B,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAChD,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACpD,IAAI,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAE3C,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;YACtB,IAAI,GAAG,CAAC,cAAc,CAAC,OAAO,EAAE,yBAAU,CAAC,oBAAoB,CAAC;gBAAE,SAAS;YAE3E,UAAU,CAAC,IAAI,CAAC,IAAI,iBAAC,CACjB,OAAO,EACP,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EACnB,iGAAiG,CACpG,CAAC,CAAC;QACP,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,IAAA,2CAAsB,EAAC,GAAG,CAAC,aAAa,EAAE,yBAAyB,CAAC,CAAC;QAChG,OAAO,UAAU,CAAC;IACtB,CAAC;CACJ,CAAC;AAEF,kBAAe,sBAAsB,CAAC","sourcesContent":["import type { EditRule, EditContext, Violation } from '../types';\nimport { Violation as V } from '../types';\nimport { RULE_NAMES } from '@webpieces/rules-config';\nimport { writeTemplateIfMissing } from '../instruct-ai-writer';\n\n/**\n * Matches: throw new SomeClass(\n */\nconst THROW_NEW_PATTERN = /\\bthrow\\s+new\\s+\\w+\\s*\\(/;\n\n/**\n * Matches: error.message or error2.message or error3.message\n */\nconst ERROR_MESSAGE_PATTERN = /\\berror\\d*\\.message\\b/;\n\n/**\n * Matches: cause: error or cause: error2 etc. (the good pattern)\n */\nconst CAUSE_PATTERN = /\\bcause\\s*:\\s*error\\d*\\b/;\n\nconst throwCauseRequiredRule: EditRule = {\n name: 'throw-cause-required',\n description: 'When rethrowing with added context, chain the original exception: throw new Error(\"msg\", { cause: error })',\n scope: 'edit',\n files: ['**/*.ts', '**/*.tsx'],\n defaultOptions: {},\n fixHint: [\n 'Option 1 — Remove the try-catch entirely. Letting the original exception bubble is usually the best option.',\n 'Option 2 — throw new Error(\"add more info here\", { cause: error }); chains the error and preserves the full stack trace.',\n 'Option 3 — throw new SpecificError(\"add info here\", { cause: error }); e.g. new InformAiError(\"what happened for AI\", { cause: error }).',\n '[Only if disableAllowed:true] Option 4 — // webpieces-disable throw-cause-required -- <reason>',\n ],\n\n check(ctx: EditContext): readonly Violation[] {\n const violations: V[] = [];\n const lines = ctx.strippedLines;\n\n for (let i = 0; i < lines.length; i += 1) {\n const stripped = lines[i];\n if (!THROW_NEW_PATTERN.test(stripped)) continue;\n if (!ERROR_MESSAGE_PATTERN.test(stripped)) continue;\n if (CAUSE_PATTERN.test(stripped)) continue;\n\n const lineNum = i + 1;\n if (ctx.isLineDisabled(lineNum, RULE_NAMES.THROW_CAUSE_REQUIRED)) continue;\n\n violations.push(new V(\n lineNum,\n ctx.lines[i].trim(),\n 'Rethrowing with error.message loses the original stack trace. Use { cause: error } to chain it.',\n ));\n }\n\n if (violations.length > 0) writeTemplateIfMissing(ctx.workspaceRoot, 'webpieces.exceptions.md');\n return violations;\n },\n};\n\nexport default throwCauseRequiredRule;\n"]}
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toError = toError;
4
- // ai-hook-disable-file require-return-type -- toError is a utility copied from dev-config; function return type is on line 6
5
4
  /**
6
5
  * Lightweight duplicate of @webpieces/core-util toError.
7
6
  * ai-hooks is a standalone package and cannot depend on core-util or dev-config.
@@ -1 +1 @@
1
- {"version":3,"file":"to-error.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/to-error.ts"],"names":[],"mappings":";;AAMA,0BA4BC;AAlCD,6HAA6H;AAC7H;;;GAGG;AACH,wHAAwH;AACxH,SAAgB,OAAO,CAAC,GAAY;IAChC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACf,CAAC;IAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7C,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAClD,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YAC5B,CAAC;YACD,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChD,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YAC1B,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,8DAA8D;QAC9D,IAAI,CAAC;YACD,OAAO,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,6BAA6B;YAC7B,KAAK,GAAG,CAAC;YACT,OAAO,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACtE,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["// ai-hook-disable-file require-return-type -- toError is a utility copied from dev-config; function return type is on line 6\n/**\n * Lightweight duplicate of @webpieces/core-util toError.\n * ai-hooks is a standalone package and cannot depend on core-util or dev-config.\n */\n// webpieces-disable no-any-unknown -- toError intentionally accepts unknown to safely convert any thrown value to Error\nexport function toError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n\n if (err && typeof err === 'object') {\n if ('message' in err) {\n const error = new Error(String(err.message));\n if ('stack' in err && typeof err.stack === 'string') {\n error.stack = err.stack;\n }\n if ('name' in err && typeof err.name === 'string') {\n error.name = err.name;\n }\n return error;\n }\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return new Error(`Non-Error object thrown: ${JSON.stringify(err)}`);\n } catch (err: unknown) {\n //const error = toError(err);\n void err;\n return new Error('Non-Error object thrown (unable to stringify)');\n }\n }\n\n const message = err == null ? 'Null or undefined thrown' : String(err);\n return new Error(message);\n}\n"]}
1
+ {"version":3,"file":"to-error.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/to-error.ts"],"names":[],"mappings":";;AAKA,0BA4BC;AAjCD;;;GAGG;AACH,wHAAwH;AACxH,SAAgB,OAAO,CAAC,GAAY;IAChC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC;IACf,CAAC;IAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACnB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;YAC7C,IAAI,OAAO,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAClD,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YAC5B,CAAC;YACD,IAAI,MAAM,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAChD,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;YAC1B,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,8DAA8D;QAC9D,IAAI,CAAC;YACD,OAAO,IAAI,KAAK,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACxE,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,6BAA6B;YAC7B,KAAK,GAAG,CAAC;YACT,OAAO,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;QACtE,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACvE,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["/**\n * Lightweight duplicate of @webpieces/core-util toError.\n * ai-hooks is a standalone package and cannot depend on core-util or dev-config.\n */\n// webpieces-disable no-any-unknown -- toError intentionally accepts unknown to safely convert any thrown value to Error\nexport function toError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n\n if (err && typeof err === 'object') {\n if ('message' in err) {\n const error = new Error(String(err.message));\n if ('stack' in err && typeof err.stack === 'string') {\n error.stack = err.stack;\n }\n if ('name' in err && typeof err.name === 'string') {\n error.name = err.name;\n }\n return error;\n }\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return new Error(`Non-Error object thrown: ${JSON.stringify(err)}`);\n } catch (err: unknown) {\n //const error = toError(err);\n void err;\n return new Error('Non-Error object thrown (unable to stringify)');\n }\n }\n\n const message = err == null ? 'Null or undefined thrown' : String(err);\n return new Error(message);\n}\n"]}
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export declare function main(): Promise<void>;
@@ -1,98 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.main = main;
5
- const tslib_1 = require("tslib");
6
- const child_process_1 = require("child_process");
7
- const fs = tslib_1.__importStar(require("fs"));
8
- const path = tslib_1.__importStar(require("path"));
9
- const git_readAiBranchName_1 = require("./workflow/git-readAiBranchName");
10
- const git_findForkPoint_1 = require("./workflow/git-findForkPoint");
11
- const SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
12
- function validateCleanTree(currentBranch) {
13
- if (currentBranch === 'main') {
14
- process.stderr.write('❌ Error: Already on main branch. No need to update from main.\n');
15
- process.exit(1);
16
- }
17
- process.stderr.write(`Current branch: ${currentBranch}\n`);
18
- const hasDirtyFiles = (0, child_process_1.spawnSync)('git', ['diff-index', '--quiet', 'HEAD', '--']).status !== 0;
19
- if (!hasDirtyFiles)
20
- return;
21
- const changedFiles = (0, child_process_1.execSync)('git diff --name-only HEAD', { encoding: 'utf8' }).trim();
22
- process.stderr.write('\n');
23
- process.stderr.write(SEP);
24
- process.stderr.write('❌ ERROR: You have uncommitted changes\n');
25
- process.stderr.write(SEP);
26
- process.stderr.write('\n');
27
- process.stderr.write('Please commit or stash your changes before updating from main.\n');
28
- process.stderr.write('\n');
29
- process.stderr.write('Files with changes:\n');
30
- process.stderr.write(changedFiles + '\n');
31
- process.stderr.write('\n');
32
- process.stderr.write('\x1b[1;31mTo commit your changes, run:\n');
33
- process.stderr.write(' git add -A && git commit -m "your message"\x1b[0m\n');
34
- process.stderr.write('\n');
35
- process.stderr.write('Or to stash them temporarily:\n');
36
- process.stderr.write(' git stash\n');
37
- process.stderr.write(' pnpm wp-git-update\n');
38
- process.stderr.write(' git stash pop\n');
39
- process.stderr.write('\n');
40
- process.stderr.write(SEP);
41
- process.exit(1);
42
- }
43
- function printHashPoints(hashes, currentBranch, mergeDir) {
44
- process.stderr.write('📍 The 3 Hash Points:\n');
45
- process.stderr.write(` 1. Fork point (A): ${hashes.hashForkPoint}\n`);
46
- process.stderr.write(` (where ${currentBranch} diverged from main)\n`);
47
- process.stderr.write('\n');
48
- process.stderr.write(` 2. Feature HEAD (B): ${hashes.hashFeatureHead}\n`);
49
- process.stderr.write(` (tip of ${currentBranch})\n`);
50
- process.stderr.write('\n');
51
- process.stderr.write(` 3. Main HEAD (C): ${hashes.hashMainHead}\n`);
52
- process.stderr.write(' (current origin/main)\n');
53
- process.stderr.write('\n');
54
- process.stderr.write(`Merge directory: ${mergeDir}\n`);
55
- process.stderr.write('\n');
56
- }
57
- async function main() {
58
- const currentBranch = (0, child_process_1.execSync)('git branch --show-current', { encoding: 'utf8' }).trim();
59
- const featureName = (0, git_readAiBranchName_1.getFeatureName)();
60
- const repoRoot = (0, child_process_1.execSync)('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();
61
- const mergeDir = path.join(repoRoot, 'webpiecesTmp', `merge-${featureName}`);
62
- fs.mkdirSync(mergeDir, { recursive: true });
63
- validateCleanTree(currentBranch);
64
- process.stderr.write('\n');
65
- process.stderr.write(SEP);
66
- process.stderr.write('📍 Gathering Merge Context\n');
67
- process.stderr.write(SEP);
68
- process.stderr.write('\n');
69
- process.stderr.write('Fetching latest changes from origin/main...\n');
70
- (0, child_process_1.spawnSync)('git', ['fetch', 'origin', 'main'], { stdio: 'inherit' });
71
- await (0, git_findForkPoint_1.findForkPoint)('merge');
72
- const hashesFile = path.join(mergeDir, 'updatemain-hashes.json');
73
- const hashes = JSON.parse(fs.readFileSync(hashesFile, 'utf8'));
74
- printHashPoints(hashes, currentBranch, mergeDir);
75
- if (hashes.hashForkPoint === hashes.hashMainHead) {
76
- process.stderr.write(SEP);
77
- process.stderr.write('✅ Already up to date with main!\n');
78
- process.stderr.write(SEP);
79
- process.stderr.write('\n');
80
- process.stderr.write('Your branch has not diverged from main.\n');
81
- process.stderr.write('There are no new changes from main to merge.\n');
82
- process.stderr.write('\n');
83
- process.stderr.write(SEP);
84
- process.exit(0);
85
- }
86
- process.stderr.write('Main has advanced. Merge will be needed.\n');
87
- process.stderr.write('\n');
88
- process.stderr.write(SEP);
89
- process.stderr.write('\n');
90
- }
91
- if (require.main === module) {
92
- main().catch((err) => {
93
- const message = err instanceof Error ? err.message : String(err);
94
- process.stderr.write(message + '\n');
95
- process.exit(1);
96
- });
97
- }
98
- //# sourceMappingURL=git-gatherInfo.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"git-gatherInfo.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/scripts/git-gatherInfo.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { execSync, spawnSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { getFeatureName } from './workflow/git-readAiBranchName';\nimport { findForkPoint } from './workflow/git-findForkPoint';\n\nconst SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n';\n\ninterface HashPoints {\n hashForkPoint: string;\n hashFeatureHead: string;\n hashMainHead: string;\n}\n\nfunction validateCleanTree(currentBranch: string): void {\n if (currentBranch === 'main') {\n process.stderr.write('❌ Error: Already on main branch. No need to update from main.\\n');\n process.exit(1);\n }\n\n process.stderr.write(`Current branch: ${currentBranch}\\n`);\n\n const hasDirtyFiles = spawnSync('git', ['diff-index', '--quiet', 'HEAD', '--']).status !== 0;\n if (!hasDirtyFiles) return;\n\n const changedFiles = execSync('git diff --name-only HEAD', { encoding: 'utf8' }).trim();\n process.stderr.write('\\n');\n process.stderr.write(SEP);\n process.stderr.write('❌ ERROR: You have uncommitted changes\\n');\n process.stderr.write(SEP);\n process.stderr.write('\\n');\n process.stderr.write('Please commit or stash your changes before updating from main.\\n');\n process.stderr.write('\\n');\n process.stderr.write('Files with changes:\\n');\n process.stderr.write(changedFiles + '\\n');\n process.stderr.write('\\n');\n process.stderr.write('\\x1b[1;31mTo commit your changes, run:\\n');\n process.stderr.write(' git add -A && git commit -m \"your message\"\\x1b[0m\\n');\n process.stderr.write('\\n');\n process.stderr.write('Or to stash them temporarily:\\n');\n process.stderr.write(' git stash\\n');\n process.stderr.write(' pnpm wp-git-update\\n');\n process.stderr.write(' git stash pop\\n');\n process.stderr.write('\\n');\n process.stderr.write(SEP);\n process.exit(1);\n}\n\nfunction printHashPoints(hashes: HashPoints, currentBranch: string, mergeDir: string): void {\n process.stderr.write('📍 The 3 Hash Points:\\n');\n process.stderr.write(` 1. Fork point (A): ${hashes.hashForkPoint}\\n`);\n process.stderr.write(` (where ${currentBranch} diverged from main)\\n`);\n process.stderr.write('\\n');\n process.stderr.write(` 2. Feature HEAD (B): ${hashes.hashFeatureHead}\\n`);\n process.stderr.write(` (tip of ${currentBranch})\\n`);\n process.stderr.write('\\n');\n process.stderr.write(` 3. Main HEAD (C): ${hashes.hashMainHead}\\n`);\n process.stderr.write(' (current origin/main)\\n');\n process.stderr.write('\\n');\n process.stderr.write(`Merge directory: ${mergeDir}\\n`);\n process.stderr.write('\\n');\n}\n\nexport async function main(): Promise<void> {\n const currentBranch = execSync('git branch --show-current', { encoding: 'utf8' }).trim();\n const featureName = getFeatureName();\n const repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf8' }).trim();\n const mergeDir = path.join(repoRoot, 'webpiecesTmp', `merge-${featureName}`);\n fs.mkdirSync(mergeDir, { recursive: true });\n\n validateCleanTree(currentBranch);\n\n process.stderr.write('\\n');\n process.stderr.write(SEP);\n process.stderr.write('📍 Gathering Merge Context\\n');\n process.stderr.write(SEP);\n process.stderr.write('\\n');\n process.stderr.write('Fetching latest changes from origin/main...\\n');\n spawnSync('git', ['fetch', 'origin', 'main'], { stdio: 'inherit' });\n\n await findForkPoint('merge');\n\n const hashesFile = path.join(mergeDir, 'updatemain-hashes.json');\n const hashes = JSON.parse(fs.readFileSync(hashesFile, 'utf8')) as HashPoints;\n\n printHashPoints(hashes, currentBranch, mergeDir);\n\n if (hashes.hashForkPoint === hashes.hashMainHead) {\n process.stderr.write(SEP);\n process.stderr.write('✅ Already up to date with main!\\n');\n process.stderr.write(SEP);\n process.stderr.write('\\n');\n process.stderr.write('Your branch has not diverged from main.\\n');\n process.stderr.write('There are no new changes from main to merge.\\n');\n process.stderr.write('\\n');\n process.stderr.write(SEP);\n process.exit(0);\n }\n\n process.stderr.write('Main has advanced. Merge will be needed.\\n');\n process.stderr.write('\\n');\n process.stderr.write(SEP);\n process.stderr.write('\\n');\n}\n\nif (require.main === module) {\n main().catch((err) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(message + '\\n');\n process.exit(1);\n });\n}\n"]}
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export declare function main(): Promise<void>;
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.main = main;
5
- const child_process_1 = require("child_process");
6
- const SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n';
7
- async function main() {
8
- process.stdout.write(SEP);
9
- process.stdout.write('📝 Staging Merge Changes for Review\n');
10
- process.stdout.write(SEP);
11
- process.stdout.write('\n');
12
- const currentBranch = (0, child_process_1.execSync)('git branch --show-current', { encoding: 'utf8' }).trim();
13
- const originMainResult = (0, child_process_1.spawnSync)('git', ['rev-parse', 'origin/main'], { encoding: 'utf8' });
14
- const mainFallbackResult = (0, child_process_1.spawnSync)('git', ['rev-parse', 'main'], { encoding: 'utf8' });
15
- const newForkPoint = (originMainResult.status === 0
16
- ? (originMainResult.stdout ?? '')
17
- : (mainFallbackResult.stdout ?? '')).trim();
18
- const inMergeState = (0, child_process_1.spawnSync)('git', ['rev-parse', '--verify', 'MERGE_HEAD']).status === 0;
19
- let oldForkPoint;
20
- if (inMergeState) {
21
- const mergeHead = (0, child_process_1.execSync)('git rev-parse MERGE_HEAD', { encoding: 'utf8' }).trim();
22
- const result = (0, child_process_1.spawnSync)('git', ['merge-base', mergeHead, 'origin/main'], { encoding: 'utf8' });
23
- oldForkPoint = (result.stdout ?? '').trim();
24
- }
25
- else {
26
- const result = (0, child_process_1.spawnSync)('git', ['merge-base', 'HEAD', 'origin/main'], { encoding: 'utf8' });
27
- oldForkPoint = (result.stdout ?? '').trim();
28
- }
29
- process.stdout.write(`Branch: ${currentBranch}\n`);
30
- process.stdout.write(`Old fork point: ${oldForkPoint.slice(0, 12)}\n`);
31
- process.stdout.write(`New fork point: ${newForkPoint.slice(0, 12)}\n`);
32
- process.stdout.write('\n');
33
- process.stdout.write('Staging all resolved changes...\n');
34
- (0, child_process_1.spawnSync)('git', ['add', '-A'], { stdio: 'inherit' });
35
- process.stdout.write('\n');
36
- process.stdout.write(SEP);
37
- process.stdout.write('✅ All changes staged for review\n');
38
- process.stdout.write(SEP);
39
- process.stdout.write('\n');
40
- process.stdout.write('📋 Review staged changes with:\n');
41
- process.stdout.write(' git diff --cached\n');
42
- process.stdout.write('\n');
43
- process.stdout.write('📋 View list of changed files:\n');
44
- process.stdout.write(' git status\n');
45
- process.stdout.write('\n');
46
- process.stdout.write('⚠️ REVIEW CAREFULLY before committing!\n');
47
- process.stdout.write('\n');
48
- process.stdout.write('When ready to commit, pnpm wp-git-update will continue.\n');
49
- process.stdout.write('\n');
50
- }
51
- if (require.main === module) {
52
- main().catch((err) => {
53
- const message = err instanceof Error ? err.message : String(err);
54
- process.stderr.write(message + '\n');
55
- process.exit(1);
56
- });
57
- }
58
- //# sourceMappingURL=git-mergeComplete.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"git-mergeComplete.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/scripts/git-mergeComplete.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { execSync, spawnSync } from 'child_process';\n\nconst SEP = '━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\n';\n\nexport async function main(): Promise<void> {\n process.stdout.write(SEP);\n process.stdout.write('📝 Staging Merge Changes for Review\\n');\n process.stdout.write(SEP);\n process.stdout.write('\\n');\n\n const currentBranch = execSync('git branch --show-current', { encoding: 'utf8' }).trim();\n\n const originMainResult = spawnSync('git', ['rev-parse', 'origin/main'], { encoding: 'utf8' });\n const mainFallbackResult = spawnSync('git', ['rev-parse', 'main'], { encoding: 'utf8' });\n const newForkPoint = (\n originMainResult.status === 0\n ? (originMainResult.stdout ?? '')\n : (mainFallbackResult.stdout ?? '')\n ).trim();\n\n const inMergeState = spawnSync('git', ['rev-parse', '--verify', 'MERGE_HEAD']).status === 0;\n\n let oldForkPoint: string;\n if (inMergeState) {\n const mergeHead = execSync('git rev-parse MERGE_HEAD', { encoding: 'utf8' }).trim();\n const result = spawnSync('git', ['merge-base', mergeHead, 'origin/main'], { encoding: 'utf8' });\n oldForkPoint = (result.stdout ?? '').trim();\n } else {\n const result = spawnSync('git', ['merge-base', 'HEAD', 'origin/main'], { encoding: 'utf8' });\n oldForkPoint = (result.stdout ?? '').trim();\n }\n\n process.stdout.write(`Branch: ${currentBranch}\\n`);\n process.stdout.write(`Old fork point: ${oldForkPoint.slice(0, 12)}\\n`);\n process.stdout.write(`New fork point: ${newForkPoint.slice(0, 12)}\\n`);\n process.stdout.write('\\n');\n\n process.stdout.write('Staging all resolved changes...\\n');\n spawnSync('git', ['add', '-A'], { stdio: 'inherit' });\n\n process.stdout.write('\\n');\n process.stdout.write(SEP);\n process.stdout.write('✅ All changes staged for review\\n');\n process.stdout.write(SEP);\n process.stdout.write('\\n');\n process.stdout.write('📋 Review staged changes with:\\n');\n process.stdout.write(' git diff --cached\\n');\n process.stdout.write('\\n');\n process.stdout.write('📋 View list of changed files:\\n');\n process.stdout.write(' git status\\n');\n process.stdout.write('\\n');\n process.stdout.write('⚠️ REVIEW CAREFULLY before committing!\\n');\n process.stdout.write('\\n');\n process.stdout.write('When ready to commit, pnpm wp-git-update will continue.\\n');\n process.stdout.write('\\n');\n}\n\nif (require.main === module) {\n main().catch((err) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(message + '\\n');\n process.exit(1);\n });\n}\n"]}
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- export declare function main(): Promise<void>;