@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,253 @@
1
+ // SPDX-License-Identifier: MIT
2
+ // Part of pi-steering.
3
+
4
+ /**
5
+ * Git plugin for `@cad0p/pi-steering`.
6
+ *
7
+ * Subpath import: `pi-steering/plugins/git`.
8
+ *
9
+ * Registers (in the terms of `Plugin`):
10
+ *
11
+ * - `predicates` - `branch`, `upstream`, `commitsAhead`,
12
+ * `hasStagedChanges`, `isClean`, `remote`.
13
+ * See `./predicates.ts` for the arg
14
+ * shapes each handler accepts.
15
+ * - `rules` - `no-main-commit-github` (github-flavored,
16
+ * first-match-wins) + `no-main-commit`
17
+ * (generic fallback). Both overridable.
18
+ * Users disable via
19
+ * `disabledRules: ["no-main-commit"]` /
20
+ * `["no-main-commit-github"]` or opt out
21
+ * of the whole plugin with
22
+ * `disabledPlugins: ["git"]`.
23
+ * - `trackers.branch` - sequential `git checkout` / `git switch`
24
+ * branch tracker. See `./branch-tracker.ts`.
25
+ * - `trackerExtensions.cwd.git`
26
+ * - per-command `--git-dir=` / `--work-tree=`
27
+ * parser layered on the core cwd tracker.
28
+ * See `./cwd-extensions.ts`.
29
+ *
30
+ * Also re-exported as composable building blocks for downstream
31
+ * plugins (e.g. RDS-style multi-package `cr --all` scans that need
32
+ * to query git state per subpackage directory):
33
+ *
34
+ * - `getBranch(ctx, cwd?)` — current branch or `null`
35
+ * - `getUpstream(ctx, cwd?)` — upstream name or `null`
36
+ * - `getCommitsAhead(ctx, wrt?, cwd?)` — commit count or `null`
37
+ * - `getStagedChanges(ctx, cwd?)` — boolean or `null`
38
+ * - `getWorkingTreeClean(ctx, cwd?)` — boolean or `null`
39
+ * - `getRemoteUrl(ctx, cwd?)` — origin URL or `null`
40
+ * - `walkerString(value)` — walker-sentinel narrowing
41
+ * helper for plugin-author
42
+ * predicates
43
+ * - `NO_CHECKOUT_IN_CHAIN` — branch-tracker fall-through
44
+ * sentinel
45
+ * - `GIT_COMMIT_PATTERN` — shared `git commit` regex
46
+ * source used by both
47
+ * commit-on-main rules
48
+ * - `PROTECTED_BRANCH_PATTERN` — shared protected-branch
49
+ * regex (main / master /
50
+ * mainline / trunk) used by
51
+ * both commit-on-main rules
52
+ *
53
+ * See `./git-ops.ts` for the helper contract (all collapse failure
54
+ * modes to `null`; caller decides what to do with it).
55
+ *
56
+ * Opt-in since the v0.1.x monorepo split: `DEFAULT_PLUGINS` is empty,
57
+ * so this plugin is registered ONLY when the user declares it:
58
+ *
59
+ * ```ts
60
+ * import gitPlugin from "@cad0p/pi-steering/plugins/git";
61
+ * export default defineConfig({ plugins: [gitPlugin] });
62
+ * ```
63
+ *
64
+ * Declaring it explicitly also feeds its rule / predicate names into
65
+ * `defineConfig`'s type unions (typo-checking on `disabledRules` /
66
+ * `disabledPlugins`); relying on a default would silently widen the
67
+ * union and let typos through.
68
+ *
69
+ * Tests build configs via `loadHarness({ includeDefaults: false })`
70
+ * and pass the plugin explicitly.
71
+ *
72
+ * ## Note for plugin authors
73
+ *
74
+ * This is the canonical reference plugin. Third-party plugins are
75
+ * expected to mirror this layout - one file per concern (tracker /
76
+ * extension / predicates / rules), a terse default export assembling
77
+ * them. Copy-adapt liberally.
78
+ */
79
+
80
+ import type { Tracker } from "@cad0p/unbash-walker";
81
+ import type { DEFAULT_PLUGINS } from "../../defaults.ts";
82
+ import type {
83
+ BuiltInWhenLeaves,
84
+ Patterns,
85
+ Plugin,
86
+ PredicateShape,
87
+ } from "../../schema.ts";
88
+ import { branchTracker } from "./branch-tracker.ts";
89
+ import { gitCwdExtensions } from "./cwd-extensions.ts";
90
+ import { predicates } from "./predicates.ts";
91
+ import { rules } from "./rules.ts";
92
+
93
+ declare global {
94
+ /**
95
+ * gitPlugin's typed-predicate registry. Each entry declares the
96
+ * predicate's `bare` value type and (optionally) an explicit
97
+ * `spreadBase` (the spread's object form WITHOUT modifiers).
98
+ * Modifiers (currently `onUnknown:`) are added at use site via
99
+ * `& PredicateModifiers` (outer leaf) or at the not-block top
100
+ * level (inside `not:`).
101
+ *
102
+ * Note: `cwd` is intentionally NOT in this block. It's a built-in
103
+ * non-registry leaf on {@link BuiltInWhenLeaves} (see schema.ts) so
104
+ * authors can write `when: { cwd: /work/ }` against pi-steering core
105
+ * without needing gitPlugin's module augmentation in scope. The
106
+ * runtime handler that wires `when.cwd` to the walker still lives
107
+ * in pi-steering core; gitPlugin layers `git --git-dir=` /
108
+ * `--work-tree=` cwd extensions via {@link gitCwdExtensions} but
109
+ * does not own the predicate's registry shape.
110
+ *
111
+ * @see PredicateShape, DefaultSpreadBase, PredicateModifiers in
112
+ * `schema.ts` for the full registry contract.
113
+ */
114
+ interface PiSteeringPredicates {
115
+ /**
116
+ * `when.branch` — match the current git branch. Pattern leaf,
117
+ * tracker-aware (in-chain `git checkout X` resolves statically;
118
+ * dynamic `git checkout $VAR` surfaces the walker's
119
+ * `"unknown"` sentinel — the engine's `onUnknown:` policy
120
+ * then projects to a definite verdict).
121
+ */
122
+ branch: PredicateShape<Patterns>;
123
+
124
+ /**
125
+ * `when.upstream` — match the current branch's configured
126
+ * upstream (`git rev-parse --abbrev-ref @{upstream}`). Pattern
127
+ * leaf. Inlines a walker-unknown-cwd guard at the handler
128
+ * top — surfaces trinary `"unknown"` instead of querying the
129
+ * wrong repo when the walker can't statically resolve cwd.
130
+ */
131
+ upstream: PredicateShape<Patterns>;
132
+
133
+ /**
134
+ * `when.remote` — match the repo's `origin` remote URL
135
+ * (`git config --get remote.origin.url`). Pattern leaf. Same
136
+ * walker-unknown-cwd guard as `upstream:`.
137
+ */
138
+ remote: PredicateShape<Patterns>;
139
+
140
+ /**
141
+ * `when.isClean` — `true` when the working tree has no
142
+ * unstaged / untracked / staged changes (`git status
143
+ * --porcelain` is empty); `false` otherwise. Boolean leaf;
144
+ * spreadBase auto-detects to `{ value: boolean }`. Inlines
145
+ * the walker-unknown-cwd guard.
146
+ */
147
+ isClean: PredicateShape<boolean>;
148
+
149
+ /**
150
+ * `when.hasStagedChanges` — `true` when there are staged
151
+ * changes (`git diff --cached --quiet` exits non-zero);
152
+ * `false` otherwise. Boolean leaf. Inlines the walker-
153
+ * unknown-cwd guard.
154
+ */
155
+ hasStagedChanges: PredicateShape<boolean>;
156
+
157
+ /**
158
+ * `when.commitsAhead` — match when the count of commits ahead
159
+ * of `wrt:` (default `@{upstream}`) satisfies every supplied
160
+ * comparator. Bare shorthand `commitsAhead: N` is equivalent
161
+ * to `{ eq: N }`. Spread form supports:
162
+ * - `eq?: number` — exact equality (`count === eq`).
163
+ * - `gt?: number` — strict greater-than (`count > gt`).
164
+ * - `lt?: number` — strict less-than (`count < lt`).
165
+ * - `wrt?: string` — git revision to count against (default
166
+ * `"@{upstream}"`).
167
+ * At least one of `eq` / `gt` / `lt` MUST be specified;
168
+ * combined with AND.
169
+ *
170
+ * Mixed-bare predicate: explicit `SpreadBase` since auto-
171
+ * detection from `number` would give `{ value: number }`,
172
+ * which doesn't match the desired comparator-bag shape.
173
+ * Inlines the walker-unknown-cwd guard.
174
+ */
175
+ commitsAhead: PredicateShape<
176
+ number,
177
+ { eq?: number; gt?: number; lt?: number; wrt?: string }
178
+ >;
179
+ }
180
+ }
181
+
182
+ /**
183
+ * The git plugin. Default export so `import gitPlugin from
184
+ * "pi-steering/plugins/git"` gives you the whole thing.
185
+ *
186
+ * `as const satisfies Plugin` (rather than `: Plugin`) preserves the
187
+ * literal `name: "git"` in the inferred type. That literal is the
188
+ * input to any future `AllPluginNames<P>`-style inference in
189
+ * `defineConfig`, which needs `name: "git"`, not `name: string`, to
190
+ * offer string-literal completion for e.g. `disabledPlugins`.
191
+ */
192
+ const gitPlugin = {
193
+ name: "git",
194
+ predicates,
195
+ rules,
196
+ trackers: {
197
+ // `Plugin.trackers` is typed `Record<string, Tracker<unknown>>`
198
+ // because the schema can't commit to a specific T per tracker.
199
+ // Cast is safe - the walker dispatches on `modifiers[basename]`
200
+ // and never narrows T at the tracker-registry layer.
201
+ branch: branchTracker as unknown as Tracker<unknown>,
202
+ },
203
+ trackerExtensions: {
204
+ cwd: {
205
+ git: gitCwdExtensions,
206
+ },
207
+ },
208
+ } as const satisfies Plugin;
209
+
210
+ /**
211
+ * Type-level regression sentinel: if the plugin literal ever loses
212
+ * the `name: "git"` narrowing (for example, someone reintroducing
213
+ * `: Plugin` annotation), the inferred type of `GIT_PLUGIN_NAME`
214
+ * widens to `string` and any downstream literal-name inference
215
+ * breaks. Keep this export in place to fail compilation loudly when
216
+ * that happens.
217
+ */
218
+ export const GIT_PLUGIN_NAME: "git" = gitPlugin.name;
219
+
220
+ export default gitPlugin;
221
+
222
+ // Named re-exports for consumers that want to pick pieces (e.g. a
223
+ // test harness constructing a minimal config that uses only the
224
+ // `branch` predicate without the shipped rule).
225
+ export { branchTracker, NO_CHECKOUT_IN_CHAIN } from "./branch-tracker.ts";
226
+ export { gitCwdExtensions } from "./cwd-extensions.ts";
227
+ export {
228
+ getBranch,
229
+ getCommitsAhead,
230
+ getRemoteUrl,
231
+ getStagedChanges,
232
+ getUpstream,
233
+ getWorkingTreeClean,
234
+ } from "./git-ops.ts";
235
+ export {
236
+ branch,
237
+ type CommitsAheadArgs,
238
+ commitsAhead,
239
+ hasStagedChanges,
240
+ isClean,
241
+ predicates,
242
+ remote,
243
+ upstream,
244
+ type WalkerStringResult,
245
+ walkerString,
246
+ } from "./predicates.ts";
247
+ export {
248
+ GIT_COMMIT_PATTERN,
249
+ noMainCommit,
250
+ noMainCommitGithub,
251
+ PROTECTED_BRANCH_PATTERN,
252
+ rules,
253
+ } from "./rules.ts";