@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.
- package/CHANGELOG.md +36 -0
- package/LICENSE +29 -0
- package/README.md +920 -0
- package/dist/__test-helpers__.d.ts +95 -0
- package/dist/__test-helpers__.d.ts.map +1 -0
- package/dist/__test-helpers__.js +174 -0
- package/dist/__test-helpers__.js.map +1 -0
- package/dist/bin/pi-steering.d.ts +9 -0
- package/dist/bin/pi-steering.d.ts.map +1 -0
- package/dist/bin/pi-steering.js +506 -0
- package/dist/bin/pi-steering.js.map +1 -0
- package/dist/compat.d.ts +50 -0
- package/dist/compat.d.ts.map +1 -0
- package/dist/compat.js +180 -0
- package/dist/compat.js.map +1 -0
- package/dist/defaults.d.ts +61 -0
- package/dist/defaults.d.ts.map +1 -0
- package/dist/defaults.js +106 -0
- package/dist/defaults.js.map +1 -0
- package/dist/define-config.d.ts +235 -0
- package/dist/define-config.d.ts.map +1 -0
- package/dist/define-config.js +118 -0
- package/dist/define-config.js.map +1 -0
- package/dist/define-predicate.d.ts +49 -0
- package/dist/define-predicate.d.ts.map +1 -0
- package/dist/define-predicate.js +35 -0
- package/dist/define-predicate.js.map +1 -0
- package/dist/evaluator-internals/context.d.ts +186 -0
- package/dist/evaluator-internals/context.d.ts.map +1 -0
- package/dist/evaluator-internals/context.js +219 -0
- package/dist/evaluator-internals/context.js.map +1 -0
- package/dist/evaluator-internals/override.d.ts +19 -0
- package/dist/evaluator-internals/override.d.ts.map +1 -0
- package/dist/evaluator-internals/override.js +79 -0
- package/dist/evaluator-internals/override.js.map +1 -0
- package/dist/evaluator-internals/predicates.d.ts +152 -0
- package/dist/evaluator-internals/predicates.d.ts.map +1 -0
- package/dist/evaluator-internals/predicates.js +849 -0
- package/dist/evaluator-internals/predicates.js.map +1 -0
- package/dist/evaluator-internals/speculative-synthesis.d.ts +102 -0
- package/dist/evaluator-internals/speculative-synthesis.d.ts.map +1 -0
- package/dist/evaluator-internals/speculative-synthesis.js +101 -0
- package/dist/evaluator-internals/speculative-synthesis.js.map +1 -0
- package/dist/evaluator.d.ts +101 -0
- package/dist/evaluator.d.ts.map +1 -0
- package/dist/evaluator.js +714 -0
- package/dist/evaluator.js.map +1 -0
- package/dist/helpers/walker-unknown-cwd-reason.d.ts +68 -0
- package/dist/helpers/walker-unknown-cwd-reason.d.ts.map +1 -0
- package/dist/helpers/walker-unknown-cwd-reason.js +73 -0
- package/dist/helpers/walker-unknown-cwd-reason.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/drop-unused-observers.d.ts +43 -0
- package/dist/internal/drop-unused-observers.d.ts.map +1 -0
- package/dist/internal/drop-unused-observers.js +50 -0
- package/dist/internal/drop-unused-observers.js.map +1 -0
- package/dist/internal/finalize-plugin-state.d.ts +22 -0
- package/dist/internal/finalize-plugin-state.d.ts.map +1 -0
- package/dist/internal/finalize-plugin-state.js +14 -0
- package/dist/internal/finalize-plugin-state.js.map +1 -0
- package/dist/internal/merge-observers.d.ts +30 -0
- package/dist/internal/merge-observers.d.ts.map +1 -0
- package/dist/internal/merge-observers.js +27 -0
- package/dist/internal/merge-observers.js.map +1 -0
- package/dist/internal/pattern-utils.d.ts +33 -0
- package/dist/internal/pattern-utils.d.ts.map +1 -0
- package/dist/internal/pattern-utils.js +20 -0
- package/dist/internal/pattern-utils.js.map +1 -0
- package/dist/internal/ref-text.d.ts +11 -0
- package/dist/internal/ref-text.d.ts.map +1 -0
- package/dist/internal/ref-text.js +15 -0
- package/dist/internal/ref-text.js.map +1 -0
- package/dist/internal/session-runtime.d.ts +44 -0
- package/dist/internal/session-runtime.d.ts.map +1 -0
- package/dist/internal/session-runtime.js +143 -0
- package/dist/internal/session-runtime.js.map +1 -0
- package/dist/internal/watch-matcher.d.ts +56 -0
- package/dist/internal/watch-matcher.d.ts.map +1 -0
- package/dist/internal/watch-matcher.js +179 -0
- package/dist/internal/watch-matcher.js.map +1 -0
- package/dist/loader.d.ts +97 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +527 -0
- package/dist/loader.js.map +1 -0
- package/dist/observer-dispatcher.d.ts +69 -0
- package/dist/observer-dispatcher.d.ts.map +1 -0
- package/dist/observer-dispatcher.js +184 -0
- package/dist/observer-dispatcher.js.map +1 -0
- package/dist/plugin-merger.d.ts +175 -0
- package/dist/plugin-merger.d.ts.map +1 -0
- package/dist/plugin-merger.js +450 -0
- package/dist/plugin-merger.js.map +1 -0
- package/dist/plugins/git/branch-tracker.d.ts +85 -0
- package/dist/plugins/git/branch-tracker.d.ts.map +1 -0
- package/dist/plugins/git/branch-tracker.js +181 -0
- package/dist/plugins/git/branch-tracker.js.map +1 -0
- package/dist/plugins/git/cwd-extensions.d.ts +10 -0
- package/dist/plugins/git/cwd-extensions.d.ts.map +1 -0
- package/dist/plugins/git/cwd-extensions.js +155 -0
- package/dist/plugins/git/cwd-extensions.js.map +1 -0
- package/dist/plugins/git/git-ops.d.ts +89 -0
- package/dist/plugins/git/git-ops.d.ts.map +1 -0
- package/dist/plugins/git/git-ops.js +107 -0
- package/dist/plugins/git/git-ops.js.map +1 -0
- package/dist/plugins/git/index.d.ts +225 -0
- package/dist/plugins/git/index.d.ts.map +1 -0
- package/dist/plugins/git/index.js +52 -0
- package/dist/plugins/git/index.js.map +1 -0
- package/dist/plugins/git/predicates.d.ts +312 -0
- package/dist/plugins/git/predicates.d.ts.map +1 -0
- package/dist/plugins/git/predicates.js +580 -0
- package/dist/plugins/git/predicates.js.map +1 -0
- package/dist/plugins/git/rules.d.ts +209 -0
- package/dist/plugins/git/rules.d.ts.map +1 -0
- package/dist/plugins/git/rules.js +267 -0
- package/dist/plugins/git/rules.js.map +1 -0
- package/dist/schema.d.ts +1799 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +4 -0
- package/dist/schema.js.map +1 -0
- package/dist/testing/index.d.ts +621 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +747 -0
- package/dist/testing/index.js.map +1 -0
- package/examples/README.md +83 -0
- package/examples/combined-git-discipline/README.md +52 -0
- package/examples/combined-git-discipline/node_modules/.bin/pi-steering +43 -0
- package/examples/combined-git-discipline/package.json +18 -0
- package/examples/combined-git-discipline/steering.json +27 -0
- package/examples/combined-git-discipline/steering.test.ts +42 -0
- package/examples/combined-git-discipline/steering.ts +64 -0
- package/examples/combined-git-discipline/tsconfig.json +7 -0
- package/examples/draft-prs-only/README.md +42 -0
- package/examples/draft-prs-only/node_modules/.bin/pi-steering +43 -0
- package/examples/draft-prs-only/package.json +18 -0
- package/examples/draft-prs-only/steering.json +12 -0
- package/examples/draft-prs-only/steering.test.ts +48 -0
- package/examples/draft-prs-only/steering.ts +36 -0
- package/examples/draft-prs-only/tsconfig.json +7 -0
- package/examples/dynamic-reason-runtime-cwd/README.md +148 -0
- package/examples/dynamic-reason-runtime-cwd/node_modules/.bin/pi-steering +43 -0
- package/examples/dynamic-reason-runtime-cwd/package.json +18 -0
- package/examples/dynamic-reason-runtime-cwd/steering.test.ts +130 -0
- package/examples/dynamic-reason-runtime-cwd/steering.ts +82 -0
- package/examples/dynamic-reason-runtime-cwd/tsconfig.json +7 -0
- package/examples/force-push-strict/README.md +75 -0
- package/examples/force-push-strict/node_modules/.bin/pi-steering +43 -0
- package/examples/force-push-strict/package.json +18 -0
- package/examples/force-push-strict/steering.json +12 -0
- package/examples/force-push-strict/steering.test.ts +51 -0
- package/examples/force-push-strict/steering.ts +54 -0
- package/examples/force-push-strict/tsconfig.json +7 -0
- package/examples/no-amend/README.md +52 -0
- package/examples/no-amend/node_modules/.bin/pi-steering +43 -0
- package/examples/no-amend/package.json +18 -0
- package/examples/no-amend/steering.cwd-scoped.json +12 -0
- package/examples/no-amend/steering.json +11 -0
- package/examples/no-amend/steering.test.ts +49 -0
- package/examples/no-amend/steering.ts +38 -0
- package/examples/no-amend/tsconfig.json +7 -0
- package/examples/work-item-plugin/README.md +103 -0
- package/examples/work-item-plugin/node_modules/.bin/pi-steering +43 -0
- package/examples/work-item-plugin/package.json +19 -0
- package/examples/work-item-plugin/src/index.test.ts +168 -0
- package/examples/work-item-plugin/src/index.ts +122 -0
- package/examples/work-item-plugin/src/observers/npm-test-tracker.test.ts +95 -0
- package/examples/work-item-plugin/src/observers/npm-test-tracker.ts +88 -0
- package/examples/work-item-plugin/src/observers/retest-required-tracker.test.ts +81 -0
- package/examples/work-item-plugin/src/observers/retest-required-tracker.ts +81 -0
- package/examples/work-item-plugin/src/predicates/work-item-format.test.ts +157 -0
- package/examples/work-item-plugin/src/predicates/work-item-format.ts +99 -0
- package/examples/work-item-plugin/src/rules/commit-description-check.test.ts +107 -0
- package/examples/work-item-plugin/src/rules/commit-description-check.ts +83 -0
- package/examples/work-item-plugin/src/rules/commit-requires-work-item.test.ts +79 -0
- package/examples/work-item-plugin/src/rules/commit-requires-work-item.ts +56 -0
- package/examples/work-item-plugin/src/rules/push-requires-tests.test.ts +245 -0
- package/examples/work-item-plugin/src/rules/push-requires-tests.ts +62 -0
- package/examples/work-item-plugin/tsconfig.json +8 -0
- package/package.json +88 -0
- package/skills/steering-authoring/SKILL.md +102 -0
- package/src/INVARIANTS.md +116 -0
- package/src/__test-helpers__.ts +243 -0
- package/src/bin/pi-steering.test.ts +920 -0
- package/src/bin/pi-steering.ts +584 -0
- package/src/compat.test.ts +431 -0
- package/src/compat.ts +282 -0
- package/src/defaults.test.ts +585 -0
- package/src/defaults.ts +148 -0
- package/src/define-config.test.ts +888 -0
- package/src/define-config.ts +375 -0
- package/src/define-predicate.test.ts +70 -0
- package/src/define-predicate.ts +57 -0
- package/src/evaluator-internals/context.ts +290 -0
- package/src/evaluator-internals/override.test.ts +99 -0
- package/src/evaluator-internals/override.ts +83 -0
- package/src/evaluator-internals/predicates.ts +1037 -0
- package/src/evaluator-internals/speculative-synthesis.test.ts +411 -0
- package/src/evaluator-internals/speculative-synthesis.ts +199 -0
- package/src/evaluator.test.ts +6296 -0
- package/src/evaluator.ts +1106 -0
- package/src/factory-time-load.test.ts +630 -0
- package/src/helpers/walker-unknown-cwd-reason.test.ts +73 -0
- package/src/helpers/walker-unknown-cwd-reason.ts +83 -0
- package/src/index.test.ts +836 -0
- package/src/index.ts +229 -0
- package/src/internal/drop-unused-observers.test.ts +141 -0
- package/src/internal/drop-unused-observers.ts +81 -0
- package/src/internal/finalize-plugin-state.ts +43 -0
- package/src/internal/merge-observers.ts +51 -0
- package/src/internal/pattern-utils.test.ts +52 -0
- package/src/internal/pattern-utils.ts +38 -0
- package/src/internal/ref-text.test.ts +54 -0
- package/src/internal/ref-text.ts +17 -0
- package/src/internal/session-runtime.test.ts +629 -0
- package/src/internal/session-runtime.ts +201 -0
- package/src/internal/watch-matcher.test.ts +326 -0
- package/src/internal/watch-matcher.ts +200 -0
- package/src/jsdoc-propagation.test.ts +277 -0
- package/src/loader.test.ts +1098 -0
- package/src/loader.ts +581 -0
- package/src/not-block-onunknown.test.ts +554 -0
- package/src/observer-dispatcher.test.ts +939 -0
- package/src/observer-dispatcher.ts +290 -0
- package/src/per-predicate-typing.test.ts +361 -0
- package/src/plugin-merger.test.ts +790 -0
- package/src/plugin-merger.ts +598 -0
- package/src/plugins/git/README.md +485 -0
- package/src/plugins/git/branch-tracker.test.ts +281 -0
- package/src/plugins/git/branch-tracker.ts +187 -0
- package/src/plugins/git/cwd-extensions.test.ts +230 -0
- package/src/plugins/git/cwd-extensions.ts +160 -0
- package/src/plugins/git/git-ops.test.ts +397 -0
- package/src/plugins/git/git-ops.ts +173 -0
- package/src/plugins/git/index.ts +253 -0
- package/src/plugins/git/integration.test.ts +705 -0
- package/src/plugins/git/predicates.test.ts +1401 -0
- package/src/plugins/git/predicates.ts +693 -0
- package/src/plugins/git/rules.test.ts +1001 -0
- package/src/plugins/git/rules.ts +307 -0
- package/src/schema.test.ts +259 -0
- package/src/schema.ts +1963 -0
- package/src/testing/index.test.ts +1696 -0
- 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"}
|