@cad0p/pi-steering 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/LICENSE +29 -0
  3. package/README.md +920 -0
  4. package/dist/__test-helpers__.d.ts +95 -0
  5. package/dist/__test-helpers__.d.ts.map +1 -0
  6. package/dist/__test-helpers__.js +174 -0
  7. package/dist/__test-helpers__.js.map +1 -0
  8. package/dist/bin/pi-steering.d.ts +9 -0
  9. package/dist/bin/pi-steering.d.ts.map +1 -0
  10. package/dist/bin/pi-steering.js +506 -0
  11. package/dist/bin/pi-steering.js.map +1 -0
  12. package/dist/compat.d.ts +50 -0
  13. package/dist/compat.d.ts.map +1 -0
  14. package/dist/compat.js +180 -0
  15. package/dist/compat.js.map +1 -0
  16. package/dist/defaults.d.ts +61 -0
  17. package/dist/defaults.d.ts.map +1 -0
  18. package/dist/defaults.js +106 -0
  19. package/dist/defaults.js.map +1 -0
  20. package/dist/define-config.d.ts +235 -0
  21. package/dist/define-config.d.ts.map +1 -0
  22. package/dist/define-config.js +118 -0
  23. package/dist/define-config.js.map +1 -0
  24. package/dist/define-predicate.d.ts +49 -0
  25. package/dist/define-predicate.d.ts.map +1 -0
  26. package/dist/define-predicate.js +35 -0
  27. package/dist/define-predicate.js.map +1 -0
  28. package/dist/evaluator-internals/context.d.ts +186 -0
  29. package/dist/evaluator-internals/context.d.ts.map +1 -0
  30. package/dist/evaluator-internals/context.js +219 -0
  31. package/dist/evaluator-internals/context.js.map +1 -0
  32. package/dist/evaluator-internals/override.d.ts +19 -0
  33. package/dist/evaluator-internals/override.d.ts.map +1 -0
  34. package/dist/evaluator-internals/override.js +79 -0
  35. package/dist/evaluator-internals/override.js.map +1 -0
  36. package/dist/evaluator-internals/predicates.d.ts +152 -0
  37. package/dist/evaluator-internals/predicates.d.ts.map +1 -0
  38. package/dist/evaluator-internals/predicates.js +849 -0
  39. package/dist/evaluator-internals/predicates.js.map +1 -0
  40. package/dist/evaluator-internals/speculative-synthesis.d.ts +102 -0
  41. package/dist/evaluator-internals/speculative-synthesis.d.ts.map +1 -0
  42. package/dist/evaluator-internals/speculative-synthesis.js +101 -0
  43. package/dist/evaluator-internals/speculative-synthesis.js.map +1 -0
  44. package/dist/evaluator.d.ts +101 -0
  45. package/dist/evaluator.d.ts.map +1 -0
  46. package/dist/evaluator.js +714 -0
  47. package/dist/evaluator.js.map +1 -0
  48. package/dist/helpers/walker-unknown-cwd-reason.d.ts +68 -0
  49. package/dist/helpers/walker-unknown-cwd-reason.d.ts.map +1 -0
  50. package/dist/helpers/walker-unknown-cwd-reason.js +73 -0
  51. package/dist/helpers/walker-unknown-cwd-reason.js.map +1 -0
  52. package/dist/index.d.ts +42 -0
  53. package/dist/index.d.ts.map +1 -0
  54. package/dist/index.js +93 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/internal/drop-unused-observers.d.ts +43 -0
  57. package/dist/internal/drop-unused-observers.d.ts.map +1 -0
  58. package/dist/internal/drop-unused-observers.js +50 -0
  59. package/dist/internal/drop-unused-observers.js.map +1 -0
  60. package/dist/internal/finalize-plugin-state.d.ts +22 -0
  61. package/dist/internal/finalize-plugin-state.d.ts.map +1 -0
  62. package/dist/internal/finalize-plugin-state.js +14 -0
  63. package/dist/internal/finalize-plugin-state.js.map +1 -0
  64. package/dist/internal/merge-observers.d.ts +30 -0
  65. package/dist/internal/merge-observers.d.ts.map +1 -0
  66. package/dist/internal/merge-observers.js +27 -0
  67. package/dist/internal/merge-observers.js.map +1 -0
  68. package/dist/internal/pattern-utils.d.ts +33 -0
  69. package/dist/internal/pattern-utils.d.ts.map +1 -0
  70. package/dist/internal/pattern-utils.js +20 -0
  71. package/dist/internal/pattern-utils.js.map +1 -0
  72. package/dist/internal/ref-text.d.ts +11 -0
  73. package/dist/internal/ref-text.d.ts.map +1 -0
  74. package/dist/internal/ref-text.js +15 -0
  75. package/dist/internal/ref-text.js.map +1 -0
  76. package/dist/internal/session-runtime.d.ts +44 -0
  77. package/dist/internal/session-runtime.d.ts.map +1 -0
  78. package/dist/internal/session-runtime.js +143 -0
  79. package/dist/internal/session-runtime.js.map +1 -0
  80. package/dist/internal/watch-matcher.d.ts +56 -0
  81. package/dist/internal/watch-matcher.d.ts.map +1 -0
  82. package/dist/internal/watch-matcher.js +179 -0
  83. package/dist/internal/watch-matcher.js.map +1 -0
  84. package/dist/loader.d.ts +97 -0
  85. package/dist/loader.d.ts.map +1 -0
  86. package/dist/loader.js +527 -0
  87. package/dist/loader.js.map +1 -0
  88. package/dist/observer-dispatcher.d.ts +69 -0
  89. package/dist/observer-dispatcher.d.ts.map +1 -0
  90. package/dist/observer-dispatcher.js +184 -0
  91. package/dist/observer-dispatcher.js.map +1 -0
  92. package/dist/plugin-merger.d.ts +175 -0
  93. package/dist/plugin-merger.d.ts.map +1 -0
  94. package/dist/plugin-merger.js +450 -0
  95. package/dist/plugin-merger.js.map +1 -0
  96. package/dist/plugins/git/branch-tracker.d.ts +85 -0
  97. package/dist/plugins/git/branch-tracker.d.ts.map +1 -0
  98. package/dist/plugins/git/branch-tracker.js +181 -0
  99. package/dist/plugins/git/branch-tracker.js.map +1 -0
  100. package/dist/plugins/git/cwd-extensions.d.ts +10 -0
  101. package/dist/plugins/git/cwd-extensions.d.ts.map +1 -0
  102. package/dist/plugins/git/cwd-extensions.js +155 -0
  103. package/dist/plugins/git/cwd-extensions.js.map +1 -0
  104. package/dist/plugins/git/git-ops.d.ts +89 -0
  105. package/dist/plugins/git/git-ops.d.ts.map +1 -0
  106. package/dist/plugins/git/git-ops.js +107 -0
  107. package/dist/plugins/git/git-ops.js.map +1 -0
  108. package/dist/plugins/git/index.d.ts +225 -0
  109. package/dist/plugins/git/index.d.ts.map +1 -0
  110. package/dist/plugins/git/index.js +52 -0
  111. package/dist/plugins/git/index.js.map +1 -0
  112. package/dist/plugins/git/predicates.d.ts +312 -0
  113. package/dist/plugins/git/predicates.d.ts.map +1 -0
  114. package/dist/plugins/git/predicates.js +580 -0
  115. package/dist/plugins/git/predicates.js.map +1 -0
  116. package/dist/plugins/git/rules.d.ts +209 -0
  117. package/dist/plugins/git/rules.d.ts.map +1 -0
  118. package/dist/plugins/git/rules.js +267 -0
  119. package/dist/plugins/git/rules.js.map +1 -0
  120. package/dist/schema.d.ts +1799 -0
  121. package/dist/schema.d.ts.map +1 -0
  122. package/dist/schema.js +4 -0
  123. package/dist/schema.js.map +1 -0
  124. package/dist/testing/index.d.ts +621 -0
  125. package/dist/testing/index.d.ts.map +1 -0
  126. package/dist/testing/index.js +747 -0
  127. package/dist/testing/index.js.map +1 -0
  128. package/examples/README.md +83 -0
  129. package/examples/combined-git-discipline/README.md +52 -0
  130. package/examples/combined-git-discipline/node_modules/.bin/pi-steering +43 -0
  131. package/examples/combined-git-discipline/package.json +18 -0
  132. package/examples/combined-git-discipline/steering.json +27 -0
  133. package/examples/combined-git-discipline/steering.test.ts +42 -0
  134. package/examples/combined-git-discipline/steering.ts +64 -0
  135. package/examples/combined-git-discipline/tsconfig.json +7 -0
  136. package/examples/draft-prs-only/README.md +42 -0
  137. package/examples/draft-prs-only/node_modules/.bin/pi-steering +43 -0
  138. package/examples/draft-prs-only/package.json +18 -0
  139. package/examples/draft-prs-only/steering.json +12 -0
  140. package/examples/draft-prs-only/steering.test.ts +48 -0
  141. package/examples/draft-prs-only/steering.ts +36 -0
  142. package/examples/draft-prs-only/tsconfig.json +7 -0
  143. package/examples/dynamic-reason-runtime-cwd/README.md +148 -0
  144. package/examples/dynamic-reason-runtime-cwd/node_modules/.bin/pi-steering +43 -0
  145. package/examples/dynamic-reason-runtime-cwd/package.json +18 -0
  146. package/examples/dynamic-reason-runtime-cwd/steering.test.ts +130 -0
  147. package/examples/dynamic-reason-runtime-cwd/steering.ts +82 -0
  148. package/examples/dynamic-reason-runtime-cwd/tsconfig.json +7 -0
  149. package/examples/force-push-strict/README.md +75 -0
  150. package/examples/force-push-strict/node_modules/.bin/pi-steering +43 -0
  151. package/examples/force-push-strict/package.json +18 -0
  152. package/examples/force-push-strict/steering.json +12 -0
  153. package/examples/force-push-strict/steering.test.ts +51 -0
  154. package/examples/force-push-strict/steering.ts +54 -0
  155. package/examples/force-push-strict/tsconfig.json +7 -0
  156. package/examples/no-amend/README.md +52 -0
  157. package/examples/no-amend/node_modules/.bin/pi-steering +43 -0
  158. package/examples/no-amend/package.json +18 -0
  159. package/examples/no-amend/steering.cwd-scoped.json +12 -0
  160. package/examples/no-amend/steering.json +11 -0
  161. package/examples/no-amend/steering.test.ts +49 -0
  162. package/examples/no-amend/steering.ts +38 -0
  163. package/examples/no-amend/tsconfig.json +7 -0
  164. package/examples/work-item-plugin/README.md +103 -0
  165. package/examples/work-item-plugin/node_modules/.bin/pi-steering +43 -0
  166. package/examples/work-item-plugin/package.json +19 -0
  167. package/examples/work-item-plugin/src/index.test.ts +168 -0
  168. package/examples/work-item-plugin/src/index.ts +122 -0
  169. package/examples/work-item-plugin/src/observers/npm-test-tracker.test.ts +95 -0
  170. package/examples/work-item-plugin/src/observers/npm-test-tracker.ts +88 -0
  171. package/examples/work-item-plugin/src/observers/retest-required-tracker.test.ts +81 -0
  172. package/examples/work-item-plugin/src/observers/retest-required-tracker.ts +81 -0
  173. package/examples/work-item-plugin/src/predicates/work-item-format.test.ts +157 -0
  174. package/examples/work-item-plugin/src/predicates/work-item-format.ts +99 -0
  175. package/examples/work-item-plugin/src/rules/commit-description-check.test.ts +107 -0
  176. package/examples/work-item-plugin/src/rules/commit-description-check.ts +83 -0
  177. package/examples/work-item-plugin/src/rules/commit-requires-work-item.test.ts +79 -0
  178. package/examples/work-item-plugin/src/rules/commit-requires-work-item.ts +56 -0
  179. package/examples/work-item-plugin/src/rules/push-requires-tests.test.ts +245 -0
  180. package/examples/work-item-plugin/src/rules/push-requires-tests.ts +62 -0
  181. package/examples/work-item-plugin/tsconfig.json +8 -0
  182. package/package.json +88 -0
  183. package/skills/steering-authoring/SKILL.md +102 -0
  184. package/src/INVARIANTS.md +116 -0
  185. package/src/__test-helpers__.ts +243 -0
  186. package/src/bin/pi-steering.test.ts +920 -0
  187. package/src/bin/pi-steering.ts +584 -0
  188. package/src/compat.test.ts +431 -0
  189. package/src/compat.ts +282 -0
  190. package/src/defaults.test.ts +585 -0
  191. package/src/defaults.ts +148 -0
  192. package/src/define-config.test.ts +888 -0
  193. package/src/define-config.ts +375 -0
  194. package/src/define-predicate.test.ts +70 -0
  195. package/src/define-predicate.ts +57 -0
  196. package/src/evaluator-internals/context.ts +290 -0
  197. package/src/evaluator-internals/override.test.ts +99 -0
  198. package/src/evaluator-internals/override.ts +83 -0
  199. package/src/evaluator-internals/predicates.ts +1037 -0
  200. package/src/evaluator-internals/speculative-synthesis.test.ts +411 -0
  201. package/src/evaluator-internals/speculative-synthesis.ts +199 -0
  202. package/src/evaluator.test.ts +6296 -0
  203. package/src/evaluator.ts +1106 -0
  204. package/src/factory-time-load.test.ts +630 -0
  205. package/src/helpers/walker-unknown-cwd-reason.test.ts +73 -0
  206. package/src/helpers/walker-unknown-cwd-reason.ts +83 -0
  207. package/src/index.test.ts +836 -0
  208. package/src/index.ts +229 -0
  209. package/src/internal/drop-unused-observers.test.ts +141 -0
  210. package/src/internal/drop-unused-observers.ts +81 -0
  211. package/src/internal/finalize-plugin-state.ts +43 -0
  212. package/src/internal/merge-observers.ts +51 -0
  213. package/src/internal/pattern-utils.test.ts +52 -0
  214. package/src/internal/pattern-utils.ts +38 -0
  215. package/src/internal/ref-text.test.ts +54 -0
  216. package/src/internal/ref-text.ts +17 -0
  217. package/src/internal/session-runtime.test.ts +629 -0
  218. package/src/internal/session-runtime.ts +201 -0
  219. package/src/internal/watch-matcher.test.ts +326 -0
  220. package/src/internal/watch-matcher.ts +200 -0
  221. package/src/jsdoc-propagation.test.ts +277 -0
  222. package/src/loader.test.ts +1098 -0
  223. package/src/loader.ts +581 -0
  224. package/src/not-block-onunknown.test.ts +554 -0
  225. package/src/observer-dispatcher.test.ts +939 -0
  226. package/src/observer-dispatcher.ts +290 -0
  227. package/src/per-predicate-typing.test.ts +361 -0
  228. package/src/plugin-merger.test.ts +790 -0
  229. package/src/plugin-merger.ts +598 -0
  230. package/src/plugins/git/README.md +485 -0
  231. package/src/plugins/git/branch-tracker.test.ts +281 -0
  232. package/src/plugins/git/branch-tracker.ts +187 -0
  233. package/src/plugins/git/cwd-extensions.test.ts +230 -0
  234. package/src/plugins/git/cwd-extensions.ts +160 -0
  235. package/src/plugins/git/git-ops.test.ts +397 -0
  236. package/src/plugins/git/git-ops.ts +173 -0
  237. package/src/plugins/git/index.ts +253 -0
  238. package/src/plugins/git/integration.test.ts +705 -0
  239. package/src/plugins/git/predicates.test.ts +1401 -0
  240. package/src/plugins/git/predicates.ts +693 -0
  241. package/src/plugins/git/rules.test.ts +1001 -0
  242. package/src/plugins/git/rules.ts +307 -0
  243. package/src/schema.test.ts +259 -0
  244. package/src/schema.ts +1963 -0
  245. package/src/testing/index.test.ts +1696 -0
  246. package/src/testing/index.ts +1472 -0
@@ -0,0 +1,79 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Part of pi-steering.
3
+ /**
4
+ * Inline override-comment detection for the v2 evaluator.
5
+ *
6
+ * Ported verbatim from the v1 evaluator's `extractOverride` (see
7
+ * `../../evaluator.ts`). Syntax and behaviour match exactly so the
8
+ * extension runtime can swap from v1 to v2 without users rewriting
9
+ * their override comments. See the v1 evaluator's JSDoc for the full
10
+ * syntax grammar.
11
+ *
12
+ * Exposed as a standalone module so the evaluator and its tests can
13
+ * assert override detection independently of the rest of the pipeline.
14
+ */
15
+ /**
16
+ * Global-flag regex matching every override comment in a text blob.
17
+ *
18
+ * leader: `#`, `//`, `/*`, `<!--`, `--`, `%%`, `;;`
19
+ * key: `steering-override:`
20
+ * name: `[A-Za-z0-9_-]+`
21
+ * sep: `—` (em dash), `–` (en dash), or `-` (hyphen)
22
+ * reason: anything up to `*\u002f`, `-->`, or end of line
23
+ */
24
+ const OVERRIDE_RE = /(?:#|\/\/|\/\*|<!--|--|%%|;;)\s*steering-override:\s*([A-Za-z0-9_-]+)\s*[\u2014\u2013-]\s*(.*?)(?:\*\/|-->|$)/gm;
25
+ /**
26
+ * Shorter marker-only regex used to detect when the lazy reason capture
27
+ * in {@link OVERRIDE_RE} swallowed a subsequent override marker. When the
28
+ * scanner finds one, it trims the reason at the marker and rewinds so
29
+ * the next iteration parses the subsequent override cleanly.
30
+ */
31
+ const OVERRIDE_MARKER_RE = /(?:#|\/\/|\/\*|<!--|--|%%|;;)\s*steering-override:/;
32
+ /**
33
+ * Extract an inline override-comment's reason that targets a specific
34
+ * rule name. Returns the trimmed reason, or null when no override
35
+ * addressed to `ruleName` is present (empty reasons are treated as
36
+ * "no override" — users must supply an explicit justification).
37
+ *
38
+ * Behaviour parity with v1 `extractOverride`:
39
+ *
40
+ * - case-sensitive rule-name match,
41
+ * - supports stacked overrides on one line (e.g.
42
+ * `cmd # steering-override: a — r1 # steering-override: b — r2`),
43
+ * - first-match-wins across the scanned comments,
44
+ * - all leader styles from v1 accepted.
45
+ *
46
+ * The v1 implementation is the authoritative reference for edge cases
47
+ * — see `evaluator.ts` in this package's v1 tree.
48
+ */
49
+ export function extractOverride(text, ruleName) {
50
+ // Reset `lastIndex` — the regex is module-scoped and shared across
51
+ // calls. Without the reset two back-to-back calls with different
52
+ // texts would pick up mid-string from the previous scan.
53
+ OVERRIDE_RE.lastIndex = 0;
54
+ let m = OVERRIDE_RE.exec(text);
55
+ while (m !== null) {
56
+ let reason = m[2] ?? "";
57
+ // Compute where the reason capture started in the source so we
58
+ // can rewind the scanner if we trim a trailing next-override
59
+ // marker out of the lazy capture.
60
+ const reasonStart = (m.index ?? 0) + m[0].length - reason.length;
61
+ const nextIdx = reason.search(OVERRIDE_MARKER_RE);
62
+ if (nextIdx !== -1) {
63
+ reason = reason.slice(0, nextIdx);
64
+ OVERRIDE_RE.lastIndex = reasonStart + nextIdx;
65
+ }
66
+ if (m[1] !== ruleName) {
67
+ m = OVERRIDE_RE.exec(text);
68
+ continue;
69
+ }
70
+ reason = reason.trim();
71
+ if (reason === "") {
72
+ m = OVERRIDE_RE.exec(text);
73
+ continue;
74
+ }
75
+ return reason;
76
+ }
77
+ return null;
78
+ }
79
+ //# sourceMappingURL=override.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"override.js","sourceRoot":"","sources":["../../src/evaluator-internals/override.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,uBAAuB;AAEvB;;;;;;;;;;;GAWG;AAEH;;;;;;;;GAQG;AACH,MAAM,WAAW,GACf,iHAAiH,CAAC;AAEpH;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,oDAAoD,CAAC;AAEhF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,QAAgB;IAC5D,mEAAmE;IACnE,iEAAiE;IACjE,yDAAyD;IACzD,WAAW,CAAC,SAAS,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;QAClB,IAAI,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACxB,+DAA+D;QAC/D,6DAA6D;QAC7D,kCAAkC;QAClC,MAAM,WAAW,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACjE,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAClD,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;YACnB,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YAClC,WAAW,CAAC,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YACtB,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,MAAM,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;QACvB,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;YAClB,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,152 @@
1
+ import type { Pattern, PredicateContext, PredicateFn, PredicateHandler, ReservedPredicateKey, TopLevelWhenClause } from "../schema.ts";
2
+ /**
3
+ * Runtime list of predicate keys that plugins are NOT allowed to
4
+ * register. Mirrors the type-level {@link ReservedPredicateKey} from
5
+ * `schema.ts`. Adding a new modifier to {@link PredicateModifiers} OR a
6
+ * new operator field requires updating both this list and the matching
7
+ * type union; the {@link reservedPredicateKeysCoverReservedTypes}
8
+ * sync-pinning test in `evaluator.test.ts` fails when the two drift.
9
+ *
10
+ * The engine (in the plugin merger) throws at plugin-registration time
11
+ * if a plugin attempts a reserved key, with a concrete error message
12
+ * pointing the plugin author at the collision and suggesting an
13
+ * alternative name.
14
+ */
15
+ export declare const RESERVED_PREDICATE_KEYS: readonly ["not", "onUnknown"];
16
+ /**
17
+ * Whether a string key is reserved (cannot be used as a plugin
18
+ * predicate name). Used by the plugin merger and by
19
+ * {@link validateWhenClauseShape} when computing the leaf-key set of
20
+ * a `not:` block.
21
+ */
22
+ export declare function isReservedPredicateKey(key: string): key is ReservedPredicateKey;
23
+ /**
24
+ * Throws if a `when:` or `not:` block contains no predicate-leaf keys
25
+ * after stripping modifier keys.
26
+ *
27
+ * Catches three foot-guns at config-resolve time so the engine never
28
+ * has to silently skip a malformed clause:
29
+ * - `when: {}` — zero keys.
30
+ * - `not: { onUnknown: "block" }` — one key, but it's a modifier; no
31
+ * leaves means the block has nothing to evaluate.
32
+ * - `when: { not: { not: ... } }` — nested `not:` inside a not-block,
33
+ * authored via JSON load or `as any` escape hatch (the type-level
34
+ * ban via {@link TopLevelWhenClauseNoRecurse} catches authoring-
35
+ * time mistakes; the same recursion catches the JSON / `as any`
36
+ * escape hatch).
37
+ *
38
+ * The `not:` operator field itself counts as a leaf at the outer
39
+ * `when:` level (it produces a verdict via Kleene composition of the
40
+ * inner not-block); only modifier keys are stripped. Built-in
41
+ * non-registry keys (`condition`, `happened`, `cwd`) count as leaves;
42
+ * plugin-registered predicates count as leaves regardless of whether
43
+ * the plugin is currently loaded — the unknown-predicate check fires
44
+ * later via {@link UnknownPredicateError}.
45
+ *
46
+ * Recurses into the `not:` block to enforce the same shape there.
47
+ *
48
+ * `path` describes the call site for error messages, e.g.
49
+ * `'rule "no-main-commit".when'` or `'rule "no-git-worktree".when.not'`.
50
+ */
51
+ export declare function validateWhenClauseShape(block: TopLevelWhenClause<string> | undefined, path: string): void;
52
+ /**
53
+ * Modifier-only subset of {@link RESERVED_PREDICATE_KEYS} — used by
54
+ * {@link validateWhenClauseShape} to strip modifiers when counting
55
+ * leaves. Operator fields (currently `"not"`) are NOT modifiers; they
56
+ * produce verdicts and count as leaves.
57
+ *
58
+ * Type-level coverage assertion (mirrors the
59
+ * {@link _RESERVED_PREDICATE_KEYS_COVERS_TYPE} pattern): the
60
+ * `satisfies readonly (keyof PredicateModifiers)[]` clause pins each
61
+ * entry to a real modifier key, AND the
62
+ * {@link _MODIFIER_KEYS_COVERS_TYPE} constant fails compilation if a
63
+ * future modifier (e.g. a hypothetical v0.2 `priority?: number`) is
64
+ * added to {@link PredicateModifiers} without updating this list.
65
+ * Without the lockstep check, the new modifier would be counted as a
66
+ * leaf by {@link validateWhenClauseShape}, masking empty-clause
67
+ * configs that are now "only modifiers, no real leaves."
68
+ */
69
+ export declare const MODIFIER_KEYS: readonly ["onUnknown"];
70
+ /**
71
+ * Match a string against a {@link Pattern} (string source or RegExp).
72
+ * Patterns are compiled once and cached; RegExps pass through.
73
+ */
74
+ export declare function matchesPattern(pattern: Pattern, target: string): boolean;
75
+ /**
76
+ * Evaluate a rule-level predicate (`pattern`, `requires`, `unless`).
77
+ *
78
+ * Accepts the same union v1's `Rule` supported plus {@link PredicateFn}:
79
+ * - `string` / `RegExp` → pattern match against `target`.
80
+ * - `function` → call with `ctx`, coerce result to boolean.
81
+ */
82
+ export declare function matchesPatternOrFn(value: Pattern | PredicateFn, target: string, ctx: PredicateContext): Promise<boolean>;
83
+ /**
84
+ * Thrown when a {@link TopLevelWhenClause} references a predicate name that no
85
+ * plugin has registered. The error message includes the offending key
86
+ * so the source of the typo / missing plugin is clear at the site of
87
+ * the rule.
88
+ *
89
+ * Schema-level typo detection doesn't cover this because the
90
+ * `TopLevelWhenClause` mapped-type's index signature is deliberately
91
+ * loose (`unknown`) — per
92
+ * the ADR, plugin predicates can accept arbitrary arg shapes. The
93
+ * trade-off is that we surface the error at evaluation time instead of
94
+ * load time; the key-scoped message keeps that tolerable.
95
+ */
96
+ export declare class UnknownPredicateError extends Error {
97
+ readonly key: string;
98
+ constructor(key: string);
99
+ }
100
+ /**
101
+ * Walker state consumed by `when` evaluation. Today just the per-ref
102
+ * cwd; the shape is open for future built-ins (e.g. branch) to pull
103
+ * their own fields from the same snapshot.
104
+ *
105
+ * @internal — not a plugin-author surface. Plugin predicates consume
106
+ * `ctx.walkerState` (the public `Readonly<Record<string, unknown>>`
107
+ * on {@link PredicateContext}) instead.
108
+ */
109
+ interface WhenWalkerState {
110
+ readonly cwd: string;
111
+ }
112
+ /**
113
+ * Evaluate a {@link TopLevelWhenClause}: returns true if every predicate in the
114
+ * clause "matches" for the given context. An empty / undefined clause
115
+ * trivially matches (rule fires regardless of `when`).
116
+ *
117
+ * Dispatch table:
118
+ * - `cwd` — built-in (walker-tied), consumes `state.cwd`. Returns
119
+ * trinary; outer leaf-level `onUnknown:` modifier on
120
+ * the spread form projects to a definite boolean via
121
+ * {@link projectVerdict} (default `"block"` =
122
+ * fail-CLOSED).
123
+ * - `happened` — built-in (session-entry-scoped), consumes
124
+ * `ctx.findEntries` + `ctx.agentLoopIndex`. Boolean.
125
+ * - `not` — nested `not:` block; dispatched to
126
+ * {@link evaluateNotBlock} which composes leaves with
127
+ * Kleene 3-valued AND and applies the block-level
128
+ * `onUnknown:` policy without the not-flip on unknown
129
+ * leaves.
130
+ * - `condition` — {@link PredicateFn}; call with ctx. Throws caught
131
+ * and treated as `"unknown"`. Outer-level
132
+ * `condition:` is bare-`PredicateFn`-typed (no
133
+ * spread shape), so the projection always uses the
134
+ * default `"block"` policy and a throwing condition
135
+ * fires the rule fail-CLOSED. Mirrors the inner
136
+ * not-block exception treatment + the
137
+ * plugin-handler contract in
138
+ * {@link evaluateLeafTrinary}.
139
+ * - anything else — `predicates[key]`; trinary handler with
140
+ * leaf-level `onUnknown:` modifier projection. Throws
141
+ * treated as `"unknown"` per spec.
142
+ *
143
+ * Reserved keys (`onUnknown`, future modifiers) are skipped here too —
144
+ * they're meaningful as siblings to leaves at the outer level (per
145
+ * spread form `{ pattern, onUnknown }` placement) but the engine
146
+ * doesn't iterate them as standalone keys; the leaf adapter consumes
147
+ * them inline. A bare `onUnknown:` at the outer level (without a
148
+ * containing leaf) is type-banned but skipped here defensively.
149
+ */
150
+ export declare function evaluateWhen(when: TopLevelWhenClause<string> | undefined, state: WhenWalkerState, ctx: PredicateContext, predicates: Record<string, PredicateHandler>, ruleName: string, source: string): Promise<boolean>;
151
+ export {};
152
+ //# sourceMappingURL=predicates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"predicates.d.ts","sourceRoot":"","sources":["../../src/evaluator-internals/predicates.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EACV,OAAO,EACP,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAGhB,oBAAoB,EACpB,kBAAkB,EAEnB,MAAM,cAAc,CAAC;AAQtB;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,uBAAuB,+BAKgB,CAAC;AAkBrD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,MAAM,GACV,GAAG,IAAI,oBAAoB,CAE7B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,GAAG,SAAS,EAC7C,IAAI,EAAE,MAAM,GACX,IAAI,CAsDN;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,wBAEgC,CAAC;AA6C3D;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxE;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,OAAO,GAAG,WAAW,EAC5B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,OAAO,CAAC,CAMlB;AAMD;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBACT,GAAG,EAAE,MAAM;CASxB;AA0VD;;;;;;;;GAQG;AACH,UAAU,eAAe;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AA0OD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,GAAG,SAAS,EAC5C,KAAK,EAAE,eAAe,EACtB,GAAG,EAAE,gBAAgB,EACrB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,EAC5C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC,CA+FlB"}