@ulpi/cli 0.1.1 → 0.1.3
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/dist/auth-KQCJ43U2.js +118 -0
- package/dist/{chunk-Q4HIY43N.js → chunk-2VYFVYJL.js} +67 -24
- package/dist/{chunk-DBMUNBNB.js → chunk-5J6NLQUN.js} +149 -19
- package/dist/{chunk-4KRVDKGB.js → chunk-F7OXF7Z3.js} +1 -1
- package/dist/chunk-G6SVZ4Q5.js +122 -0
- package/dist/{chunk-NNUWU6CV.js → chunk-JGBXM5NC.js} +42 -0
- package/dist/{chunk-6JCMYYBT.js → chunk-PDR55ZNW.js} +247 -112
- package/dist/{chunk-247GVVKK.js → chunk-ZLYRPD7I.js} +18 -16
- package/dist/ci-QM57ZCBW.js +367 -0
- package/dist/{codemap-RRJIDBQ5.js → codemap-RKSD4MIE.js} +49 -17
- package/dist/{dist-LZKZFPVX.js → dist-CB5D5LMO.js} +6 -3
- package/dist/{dist-7LHZ65GC.js → dist-CS2VKNYS.js} +5 -4
- package/dist/{dist-R5F4MX3I.js → dist-GJYT2OQV.js} +11 -4
- package/dist/{dist-RJGCUS3L.js → dist-QAU3LGJN.js} +3 -1
- package/dist/{dist-W7K4WPAF.js → dist-UKMCJBB2.js} +42 -14
- package/dist/{dist-R5ZJ4LX5.js → dist-YA2BWZB2.js} +1 -1
- package/dist/{history-Q2LDADFW.js → history-NFNA4HE5.js} +13 -7
- package/dist/index.js +50 -21
- package/dist/{init-AY5C2ZAS.js → init-6CH4HV5T.js} +2 -2
- package/dist/{memory-J3G24QHS.js → memory-Y6OZTXJ2.js} +231 -22
- package/dist/{server-MOYPE4SM-N7SE2AN7.js → server-USLHY6GH-AEOJC5ST.js} +2 -2
- package/dist/skills/ulpi-generate-guardian/SKILL.md +246 -7
- package/dist/skills/ulpi-generate-guardian/references/framework-rules.md +161 -4
- package/dist/skills/ulpi-generate-guardian/references/language-rules.md +13 -18
- package/dist/{ui-L7UAWXDY.js → ui-OWXZ3YSR.js} +3 -3
- package/dist/ui.html +112 -112
- package/dist/{update-DJ227LL3.js → update-WUITQX4Z.js} +1 -1
- package/dist/{version-checker-M37KI7DY.js → version-checker-SMAYSN7Y.js} +1 -1
- package/package.json +31 -28
- package/LICENSE +0 -21
|
@@ -140,7 +140,43 @@ Scan for indicator files in priority order:
|
|
|
140
140
|
| `pnpm-workspace.yaml` | pnpm workspaces |
|
|
141
141
|
| `"workspaces"` in package.json | Yarn/npm workspaces |
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
**If a monorepo is detected, you MUST proceed to Step 2b (Map Monorepo Topology) before continuing.**
|
|
144
|
+
|
|
145
|
+
## Step 2b: Map Monorepo Topology (Monorepos Only)
|
|
146
|
+
|
|
147
|
+
**Gate: Full workspace topology mapped before proceeding to Step 3.**
|
|
148
|
+
|
|
149
|
+
When a monorepo is detected, do NOT treat it as a flat project. You must:
|
|
150
|
+
|
|
151
|
+
1. **Read the workspace config** — `pnpm-workspace.yaml`, `lerna.json`, or `package.json` workspaces field to find all workspace globs
|
|
152
|
+
2. **List all packages** — Resolve workspace globs to actual directories (e.g., `apps/*`, `packages/*`)
|
|
153
|
+
3. **Read each package's `package.json`** — Identify name, dependencies, devDependencies, scripts
|
|
154
|
+
4. **Map the dependency graph** — Which packages depend on which? Identify the direction of dependency flow
|
|
155
|
+
5. **Read the task runner config** — `turbo.json` task definitions, dependency chains (`^` prefix = depends on upstream)
|
|
156
|
+
6. **Identify build characteristics** — Does the package have a build step? Is it consumed as source? Does it have its own tsconfig?
|
|
157
|
+
|
|
158
|
+
### Topology Output Format
|
|
159
|
+
|
|
160
|
+
Record the topology as a YAML comment in the header:
|
|
161
|
+
|
|
162
|
+
```yaml
|
|
163
|
+
# Workspace Topology:
|
|
164
|
+
# {package-a} → {package-b} (one-way dependency)
|
|
165
|
+
# {package-c} (standalone)
|
|
166
|
+
#
|
|
167
|
+
# Task Graph (turbo.json):
|
|
168
|
+
# build: depends on ^build
|
|
169
|
+
# type-check: depends on ^type-check
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### What Monorepo Topology Enables
|
|
173
|
+
|
|
174
|
+
- **Package boundary enforcement** — Prevent imports in the wrong direction
|
|
175
|
+
- **Per-package postconditions** — Type-check only the affected package using `turbo --filter=`
|
|
176
|
+
- **Turbo-first commands** — Use `turbo run` instead of direct package manager for tasks defined in turbo.json
|
|
177
|
+
- **Critical file cautions** — Barrel exports, shared configs, workspace manifests
|
|
178
|
+
|
|
179
|
+
See `references/framework-rules.md` → Turborepo section for complete rule templates.
|
|
144
180
|
|
|
145
181
|
## Step 3: Extract Commands from Config
|
|
146
182
|
|
|
@@ -152,6 +188,11 @@ For Node.js projects, read package.json scripts to identify:
|
|
|
152
188
|
- `lint_command` (from "lint" script)
|
|
153
189
|
- `format_command` (from "format" script)
|
|
154
190
|
|
|
191
|
+
**For monorepos:** Read BOTH the root `package.json` AND `turbo.json`:
|
|
192
|
+
- If root scripts delegate to turbo (e.g., `"build": "turbo run build"`), the real commands are turbo tasks
|
|
193
|
+
- Read each workspace's `package.json` scripts to understand what turbo invokes per-package
|
|
194
|
+
- Postconditions and pipelines should use `turbo run <task> --filter=<package>`, NOT direct `pnpm <script>`
|
|
195
|
+
|
|
155
196
|
For Python projects, check pyproject.toml for tool configurations.
|
|
156
197
|
|
|
157
198
|
For Rust projects, use standard cargo commands.
|
|
@@ -193,6 +234,7 @@ preconditions:
|
|
|
193
234
|
|
|
194
235
|
```yaml
|
|
195
236
|
permissions:
|
|
237
|
+
# --- Auto-approvals ---
|
|
196
238
|
auto-approve-reads:
|
|
197
239
|
enabled: true
|
|
198
240
|
trigger: PermissionRequest
|
|
@@ -200,16 +242,120 @@ permissions:
|
|
|
200
242
|
decision: allow
|
|
201
243
|
priority: 100
|
|
202
244
|
|
|
245
|
+
auto-approve-git-readonly:
|
|
246
|
+
enabled: true
|
|
247
|
+
trigger: PermissionRequest
|
|
248
|
+
matcher: Bash
|
|
249
|
+
command_pattern: "git (status|log|diff|branch|show|stash list|remote -v|rev-parse)"
|
|
250
|
+
decision: allow
|
|
251
|
+
priority: 90
|
|
252
|
+
|
|
253
|
+
auto-approve-gh-cli:
|
|
254
|
+
enabled: true
|
|
255
|
+
trigger: PermissionRequest
|
|
256
|
+
matcher: Bash
|
|
257
|
+
command_pattern: "gh"
|
|
258
|
+
decision: allow
|
|
259
|
+
priority: 80
|
|
260
|
+
|
|
261
|
+
auto-approve-prettier:
|
|
262
|
+
enabled: true
|
|
263
|
+
trigger: PermissionRequest
|
|
264
|
+
matcher: Bash
|
|
265
|
+
command_pattern: "prettier"
|
|
266
|
+
decision: allow
|
|
267
|
+
priority: 80
|
|
268
|
+
|
|
269
|
+
auto-approve-shell-inspection:
|
|
270
|
+
enabled: true
|
|
271
|
+
trigger: PermissionRequest
|
|
272
|
+
matcher: Bash
|
|
273
|
+
command_pattern: "(ls|cat|head|tail|wc|file|which|echo|pwd|whoami)"
|
|
274
|
+
decision: allow
|
|
275
|
+
priority: 80
|
|
276
|
+
|
|
277
|
+
# --- Git destructive blocks (comprehensive) ---
|
|
203
278
|
no-force-push:
|
|
204
279
|
enabled: true
|
|
205
280
|
trigger: PreToolUse
|
|
206
281
|
matcher: Bash
|
|
207
|
-
command_pattern: "git push
|
|
282
|
+
command_pattern: "git push.*(--force|-f)"
|
|
208
283
|
decision: deny
|
|
209
284
|
message: "Force push blocked. Use --force-with-lease."
|
|
210
285
|
locked: true
|
|
211
286
|
priority: 1
|
|
212
287
|
|
|
288
|
+
no-git-checkout-dot:
|
|
289
|
+
enabled: true
|
|
290
|
+
trigger: PreToolUse
|
|
291
|
+
matcher: Bash
|
|
292
|
+
command_pattern: "git checkout \\."
|
|
293
|
+
decision: deny
|
|
294
|
+
message: "git checkout . discards all unstaged changes."
|
|
295
|
+
locked: true
|
|
296
|
+
priority: 1
|
|
297
|
+
|
|
298
|
+
no-git-restore-dot:
|
|
299
|
+
enabled: true
|
|
300
|
+
trigger: PreToolUse
|
|
301
|
+
matcher: Bash
|
|
302
|
+
command_pattern: "git restore \\."
|
|
303
|
+
decision: deny
|
|
304
|
+
message: "git restore . discards all unstaged changes."
|
|
305
|
+
locked: true
|
|
306
|
+
priority: 1
|
|
307
|
+
|
|
308
|
+
no-git-reset-hard:
|
|
309
|
+
enabled: true
|
|
310
|
+
trigger: PreToolUse
|
|
311
|
+
matcher: Bash
|
|
312
|
+
command_pattern: "git reset --hard"
|
|
313
|
+
decision: deny
|
|
314
|
+
message: "git reset --hard destroys uncommitted work."
|
|
315
|
+
locked: true
|
|
316
|
+
priority: 1
|
|
317
|
+
|
|
318
|
+
no-git-clean-force:
|
|
319
|
+
enabled: true
|
|
320
|
+
trigger: PreToolUse
|
|
321
|
+
matcher: Bash
|
|
322
|
+
command_pattern: "git clean.* -f"
|
|
323
|
+
decision: deny
|
|
324
|
+
message: "git clean -f permanently deletes untracked files."
|
|
325
|
+
locked: true
|
|
326
|
+
priority: 1
|
|
327
|
+
|
|
328
|
+
no-git-branch-delete-force:
|
|
329
|
+
enabled: true
|
|
330
|
+
trigger: PreToolUse
|
|
331
|
+
matcher: Bash
|
|
332
|
+
command_pattern: "git branch -D"
|
|
333
|
+
decision: deny
|
|
334
|
+
message: "git branch -D force-deletes branches. Use -d for safe delete."
|
|
335
|
+
locked: true
|
|
336
|
+
priority: 1
|
|
337
|
+
|
|
338
|
+
no-skip-hooks:
|
|
339
|
+
enabled: true
|
|
340
|
+
trigger: PreToolUse
|
|
341
|
+
matcher: Bash
|
|
342
|
+
command_pattern: "--no-verify"
|
|
343
|
+
decision: deny
|
|
344
|
+
message: "Do not skip git hooks."
|
|
345
|
+
locked: true
|
|
346
|
+
priority: 1
|
|
347
|
+
|
|
348
|
+
no-rm-rf:
|
|
349
|
+
enabled: true
|
|
350
|
+
trigger: PreToolUse
|
|
351
|
+
matcher: Bash
|
|
352
|
+
command_pattern: "rm -rf"
|
|
353
|
+
decision: deny
|
|
354
|
+
message: "rm -rf is destructive. Remove specific files instead."
|
|
355
|
+
locked: true
|
|
356
|
+
priority: 1
|
|
357
|
+
|
|
358
|
+
# --- File protection ---
|
|
213
359
|
block-env-files:
|
|
214
360
|
enabled: true
|
|
215
361
|
trigger: PreToolUse
|
|
@@ -238,6 +384,8 @@ permissions:
|
|
|
238
384
|
priority: 1
|
|
239
385
|
```
|
|
240
386
|
|
|
387
|
+
**Important:** `git push` is intentionally NOT auto-approved. Pushes affect shared state and should always require confirmation.
|
|
388
|
+
|
|
241
389
|
### Language-Specific Rules
|
|
242
390
|
|
|
243
391
|
Add based on detected language. See `references/language-rules.md`.
|
|
@@ -246,6 +394,32 @@ Add based on detected language. See `references/language-rules.md`.
|
|
|
246
394
|
|
|
247
395
|
Add based on detected framework. See `references/framework-rules.md`.
|
|
248
396
|
|
|
397
|
+
### Pipelines (Required Fields)
|
|
398
|
+
|
|
399
|
+
Every pipeline MUST include `on_failure`. It is a **required field** — omitting it causes a validation error.
|
|
400
|
+
|
|
401
|
+
```yaml
|
|
402
|
+
pipelines:
|
|
403
|
+
pre-commit-checks:
|
|
404
|
+
enabled: true
|
|
405
|
+
trigger: "PreToolUse"
|
|
406
|
+
matcher: "Bash"
|
|
407
|
+
command_pattern: "git commit"
|
|
408
|
+
steps:
|
|
409
|
+
- name: "type-check"
|
|
410
|
+
run: "{type_check_command}"
|
|
411
|
+
timeout: 60000
|
|
412
|
+
- name: "lint"
|
|
413
|
+
run: "{lint_command}"
|
|
414
|
+
timeout: 60000
|
|
415
|
+
on_failure: "block" # REQUIRED — "block" or "warn"
|
|
416
|
+
message: "Pre-commit checks failed."
|
|
417
|
+
locked: true
|
|
418
|
+
priority: 5
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
Valid `on_failure` values: `"block"` (prevent the action) or `"warn"` (show warning but allow).
|
|
422
|
+
|
|
249
423
|
## Step 5: Write Configuration
|
|
250
424
|
|
|
251
425
|
**Gate: File written before proceeding to Step 6.**
|
|
@@ -292,16 +466,48 @@ Postconditions are **disabled by default** because they run automatically after
|
|
|
292
466
|
|
|
293
467
|
**To enable:** User should manually set `enabled: true` for desired postconditions after reviewing them.
|
|
294
468
|
|
|
469
|
+
## About Pipelines
|
|
470
|
+
|
|
471
|
+
Pipelines define multi-step checks (e.g., pre-commit). Every pipeline **MUST** include the `on_failure` field — it is required. Valid values: `"block"` (stop the action) or `"warn"` (show warning but proceed).
|
|
472
|
+
|
|
473
|
+
```yaml
|
|
474
|
+
pipelines:
|
|
475
|
+
pre-commit-checks:
|
|
476
|
+
enabled: true
|
|
477
|
+
trigger: "PreToolUse"
|
|
478
|
+
matcher: "Bash"
|
|
479
|
+
command_pattern: "git commit"
|
|
480
|
+
steps:
|
|
481
|
+
- name: "type-check"
|
|
482
|
+
run: "{type_check_command}"
|
|
483
|
+
timeout: 60000
|
|
484
|
+
- name: "lint"
|
|
485
|
+
run: "{lint_command}"
|
|
486
|
+
timeout: 60000
|
|
487
|
+
on_failure: "block" # REQUIRED — omitting this causes validation error
|
|
488
|
+
message: "Pre-commit checks."
|
|
489
|
+
locked: true
|
|
490
|
+
priority: 5
|
|
491
|
+
```
|
|
492
|
+
|
|
295
493
|
## Safety Rules
|
|
296
494
|
|
|
297
495
|
| Rule | Reason |
|
|
298
496
|
|------|--------|
|
|
299
497
|
| Always include read-before-write | Prevents editing files without reading first |
|
|
300
|
-
| Always block force push | Prevents history destruction |
|
|
498
|
+
| Always block force push (--force AND -f) | Prevents history destruction |
|
|
499
|
+
| Always block all git destructive ops | checkout ., restore ., reset --hard, clean -f, branch -D |
|
|
500
|
+
| Always block --no-verify | Never skip git hooks |
|
|
501
|
+
| Always block rm -rf | Prevents catastrophic deletions |
|
|
301
502
|
| Always block .env edits | Protects secrets |
|
|
302
503
|
| Always block node_modules/dist | Build artifacts should not be edited |
|
|
303
504
|
| Auto-approve reads | Safe operations should not prompt |
|
|
304
|
-
| Auto-approve detected package manager |
|
|
505
|
+
| Auto-approve ONLY the detected package manager | Do not auto-approve all package managers |
|
|
506
|
+
| Never auto-approve git push | Pushes affect shared state, always confirm |
|
|
507
|
+
| Never generate state-tracking rules | ULPI has no state; rules like "track last N" are non-functional |
|
|
508
|
+
| Never generate redundant rules | If a rule duplicates another, remove the weaker one |
|
|
509
|
+
| Always include `on_failure` in pipelines | Required field — omitting causes validation error |
|
|
510
|
+
| Always map monorepo topology when detected | Flat treatment of monorepos produces wrong rules |
|
|
305
511
|
| Never overwrite without asking | Preserves existing configuration |
|
|
306
512
|
| Always verify directory exists | Prevents errors |
|
|
307
513
|
|
|
@@ -371,6 +577,10 @@ These are excuses. Don't fall for them:
|
|
|
371
577
|
- **"The user wants it fast"** → STILL show detected stack first
|
|
372
578
|
- **"These are standard rules"** → STILL customize for detected stack
|
|
373
579
|
- **"Postconditions are disabled anyway"** → STILL generate them correctly
|
|
580
|
+
- **"It's a monorepo but I'll just use global commands"** → Map the topology and use per-package `--filter`
|
|
581
|
+
- **"git push is just like other git commands"** → Push affects shared state, NEVER auto-approve it
|
|
582
|
+
- **"I'll add a rule to track recent actions"** → ULPI has no state between invocations, this won't work
|
|
583
|
+
- **"All Node.js package managers should be auto-approved"** → Only approve the DETECTED one
|
|
374
584
|
|
|
375
585
|
---
|
|
376
586
|
|
|
@@ -396,6 +606,21 @@ These are excuses. Don't fall for them:
|
|
|
396
606
|
**Symptom:** ULPI fails to parse guards.yml
|
|
397
607
|
**Fix:** Validate YAML structure before writing
|
|
398
608
|
|
|
609
|
+
### Failure Mode 5: Flat Treatment of Monorepo
|
|
610
|
+
|
|
611
|
+
**Symptom:** Postconditions run `tsc --noEmit` globally instead of `turbo --filter=<pkg>`, package boundaries not enforced, no topology in header
|
|
612
|
+
**Fix:** Always run Step 2b when monorepo is detected. Map the full workspace dependency graph. Generate per-package postconditions with `--filter`.
|
|
613
|
+
|
|
614
|
+
### Failure Mode 6: Non-Functional State-Tracking Rules
|
|
615
|
+
|
|
616
|
+
**Symptom:** Rules reference "last N actions" or "track recent commands" — ULPI has no state between invocations
|
|
617
|
+
**Fix:** Only generate rules that use ULPI's actual capabilities: matchers, patterns, triggers. No stateful tracking.
|
|
618
|
+
|
|
619
|
+
### Failure Mode 7: Redundant Rules
|
|
620
|
+
|
|
621
|
+
**Symptom:** Multiple rules block the same thing (e.g., separate `block-dist` and `block-build-output` when only one output dir exists)
|
|
622
|
+
**Fix:** Audit generated rules for overlap. Each rule should block a distinct concern.
|
|
623
|
+
|
|
399
624
|
---
|
|
400
625
|
|
|
401
626
|
## Quick Workflow Summary
|
|
@@ -417,17 +642,31 @@ STEP 2: DETECT TECHNOLOGY
|
|
|
417
642
|
├── Announce detected stack (informational, no question)
|
|
418
643
|
└── Gate: Stack detected
|
|
419
644
|
|
|
645
|
+
STEP 2b: MAP MONOREPO TOPOLOGY (if monorepo detected)
|
|
646
|
+
├── Read workspace config (pnpm-workspace.yaml, etc.)
|
|
647
|
+
├── List all packages in workspace
|
|
648
|
+
├── Read each package's package.json
|
|
649
|
+
├── Map dependency graph (who depends on whom)
|
|
650
|
+
├── Read turbo.json / lerna.json task definitions
|
|
651
|
+
├── Identify build characteristics per package
|
|
652
|
+
└── Gate: Full topology mapped
|
|
653
|
+
|
|
420
654
|
STEP 3: EXTRACT COMMANDS
|
|
421
|
-
├── Read package.json scripts
|
|
655
|
+
├── Read package.json scripts (root + per-package for monorepos)
|
|
656
|
+
├── Read turbo.json tasks (monorepos)
|
|
422
657
|
├── Read pyproject.toml tools
|
|
423
658
|
├── Identify test/build/lint commands
|
|
659
|
+
├── For monorepos: note turbo --filter commands per package
|
|
424
660
|
└── Gate: Commands extracted
|
|
425
661
|
|
|
426
662
|
STEP 4: GENERATE RULES
|
|
427
|
-
├── Start with universal rules
|
|
428
|
-
├── Add language-specific rules
|
|
663
|
+
├── Start with universal rules (comprehensive git blocks, no push auto-approve)
|
|
664
|
+
├── Add language-specific rules (only detected pkg manager)
|
|
429
665
|
├── Add framework-specific rules
|
|
666
|
+
├── Add monorepo rules (boundaries, per-pkg postconditions, prefer-turbo)
|
|
667
|
+
├── Add project-specific critical file cautions
|
|
430
668
|
├── Add tooling rules
|
|
669
|
+
├── Audit for redundancy (no duplicate rules)
|
|
431
670
|
└── Gate: Complete rules generated
|
|
432
671
|
|
|
433
672
|
STEP 5: WRITE CONFIGURATION
|
|
@@ -663,7 +663,26 @@ preconditions:
|
|
|
663
663
|
priority: 60
|
|
664
664
|
```
|
|
665
665
|
|
|
666
|
-
## Turborepo
|
|
666
|
+
## Turborepo (Monorepo)
|
|
667
|
+
|
|
668
|
+
When Turborepo is detected, the skill MUST map the full workspace topology (Step 2b in SKILL.md) and generate monorepo-aware rules. The rules below are templates — replace placeholders with actual package names and paths from the detected topology.
|
|
669
|
+
|
|
670
|
+
### Header — Workspace Topology Comment
|
|
671
|
+
|
|
672
|
+
Always include a topology diagram in the YAML header:
|
|
673
|
+
|
|
674
|
+
```yaml
|
|
675
|
+
# Workspace Topology:
|
|
676
|
+
# {app-package} → {lib-package} (one-way dependency)
|
|
677
|
+
# {standalone-package} (no internal deps)
|
|
678
|
+
#
|
|
679
|
+
# Task Graph (from turbo.json):
|
|
680
|
+
# build: depends on ^build
|
|
681
|
+
# type-check: depends on ^type-check
|
|
682
|
+
# lint: depends on ^lint
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
### Permissions
|
|
667
686
|
|
|
668
687
|
```yaml
|
|
669
688
|
permissions:
|
|
@@ -681,12 +700,150 @@ permissions:
|
|
|
681
700
|
decision: deny
|
|
682
701
|
message: "Do not edit .turbo/ cache. Run `turbo` to regenerate."
|
|
683
702
|
locked: true
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
### Preconditions — Package Boundary Enforcement
|
|
684
706
|
|
|
707
|
+
Generate one rule per dependency boundary. The `file_pattern` and `import_pattern` should reflect the actual package names.
|
|
708
|
+
|
|
709
|
+
```yaml
|
|
685
710
|
preconditions:
|
|
686
|
-
|
|
711
|
+
# Package boundary: {lib-package} must NOT import from {app-package}
|
|
712
|
+
# Generate one rule per forbidden import direction
|
|
713
|
+
no-{lib-short}-imports-{app-short}:
|
|
714
|
+
enabled: true
|
|
715
|
+
trigger: PreToolUse
|
|
716
|
+
matcher: "Write|Edit"
|
|
717
|
+
file_pattern: "{lib-package-path}/**"
|
|
718
|
+
message: "{lib-package} must not import from {app-package}. Dependency flows {app} → {lib}, never reverse."
|
|
719
|
+
priority: 80
|
|
720
|
+
|
|
721
|
+
# Prefer turbo over direct package manager for tasks defined in turbo.json
|
|
722
|
+
prefer-turbo-over-direct:
|
|
723
|
+
enabled: true
|
|
724
|
+
trigger: PreToolUse
|
|
725
|
+
matcher: Bash
|
|
726
|
+
command_pattern: "{package_manager} (build|lint|type-check|test)"
|
|
727
|
+
message: "Use `turbo run <task>` or `turbo run <task> --filter=<package>` instead of running {package_manager} directly for tasks defined in turbo.json."
|
|
728
|
+
priority: 70
|
|
729
|
+
|
|
730
|
+
# Critical config cautions
|
|
731
|
+
caution-turbo-config:
|
|
732
|
+
enabled: true
|
|
687
733
|
trigger: PreToolUse
|
|
688
734
|
matcher: "Write|Edit"
|
|
689
735
|
file_pattern: "turbo.json"
|
|
690
|
-
message: "
|
|
691
|
-
priority:
|
|
736
|
+
message: "turbo.json defines the task graph and caching for ALL packages. Changes affect the entire monorepo build pipeline."
|
|
737
|
+
priority: 90
|
|
738
|
+
|
|
739
|
+
caution-root-package-json:
|
|
740
|
+
enabled: true
|
|
741
|
+
trigger: PreToolUse
|
|
742
|
+
matcher: "Write|Edit"
|
|
743
|
+
file_pattern: "package.json"
|
|
744
|
+
message: "Root package.json defines workspace scripts and shared devDependencies. Changes affect all packages."
|
|
745
|
+
priority: 80
|
|
746
|
+
|
|
747
|
+
caution-workspace-config:
|
|
748
|
+
enabled: true
|
|
749
|
+
trigger: PreToolUse
|
|
750
|
+
matcher: "Write|Edit"
|
|
751
|
+
file_pattern: "pnpm-workspace.yaml" # or package.json workspaces field
|
|
752
|
+
message: "Workspace config defines which directories are packages. Changes affect monorepo structure."
|
|
753
|
+
priority: 90
|
|
692
754
|
```
|
|
755
|
+
|
|
756
|
+
### Preconditions — Project-Specific Critical Files
|
|
757
|
+
|
|
758
|
+
Generate caution rules for files identified as architecturally critical during topology mapping. Examples:
|
|
759
|
+
|
|
760
|
+
```yaml
|
|
761
|
+
# Barrel exports (index.ts files that re-export from a package)
|
|
762
|
+
caution-barrel-exports:
|
|
763
|
+
enabled: true
|
|
764
|
+
trigger: PreToolUse
|
|
765
|
+
matcher: "Write|Edit"
|
|
766
|
+
file_pattern: "{lib-package-path}/src/index.ts"
|
|
767
|
+
message: "Barrel export for {lib-package}. Adding/removing exports affects all consumers."
|
|
768
|
+
priority: 80
|
|
769
|
+
|
|
770
|
+
# Framework middleware, adapters, or other high-impact files
|
|
771
|
+
# Customize based on what you find during topology mapping
|
|
772
|
+
caution-{critical-file}:
|
|
773
|
+
enabled: true
|
|
774
|
+
trigger: PreToolUse
|
|
775
|
+
matcher: "Write|Edit"
|
|
776
|
+
file_pattern: "{path-to-critical-file}"
|
|
777
|
+
message: "{Explanation of why this file is critical}"
|
|
778
|
+
priority: 80
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
### Postconditions — Per-Package Type Checking
|
|
782
|
+
|
|
783
|
+
Generate one postcondition per package. Use `turbo run --filter=` to scope to the affected package.
|
|
784
|
+
|
|
785
|
+
```yaml
|
|
786
|
+
postconditions:
|
|
787
|
+
# Per-package type checking — one rule per workspace package
|
|
788
|
+
type-check-{package-short}-on-change:
|
|
789
|
+
enabled: false # postconditions disabled by default
|
|
790
|
+
trigger: PostToolUse
|
|
791
|
+
matcher: "Write|Edit"
|
|
792
|
+
file_pattern: "{package-path}/**/*.{ts,tsx}"
|
|
793
|
+
run: "turbo run type-check --filter={package-name}"
|
|
794
|
+
timeout: 30000
|
|
795
|
+
block_on_failure: true
|
|
796
|
+
|
|
797
|
+
# Example for a package with no build step (consumed as source):
|
|
798
|
+
# type-check-ui-on-change:
|
|
799
|
+
# file_pattern: "packages/ui/**/*.{ts,tsx}"
|
|
800
|
+
# run: "turbo run type-check --filter=@maya/ui"
|
|
801
|
+
|
|
802
|
+
# Example for an app package:
|
|
803
|
+
# type-check-web-on-change:
|
|
804
|
+
# file_pattern: "apps/web/**/*.{ts,tsx}"
|
|
805
|
+
# run: "turbo run type-check --filter=@maya/web"
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
### Pipelines — Use Turbo Directly
|
|
809
|
+
|
|
810
|
+
**IMPORTANT:** Every pipeline MUST include `on_failure`. It is a required field. Omitting it causes a validation error.
|
|
811
|
+
|
|
812
|
+
```yaml
|
|
813
|
+
pipelines:
|
|
814
|
+
pre-commit-checks:
|
|
815
|
+
enabled: true
|
|
816
|
+
trigger: "PreToolUse"
|
|
817
|
+
matcher: "Bash"
|
|
818
|
+
command_pattern: "git commit"
|
|
819
|
+
steps:
|
|
820
|
+
- name: "type-check"
|
|
821
|
+
run: "turbo run type-check"
|
|
822
|
+
timeout: 60000
|
|
823
|
+
- name: "lint"
|
|
824
|
+
run: "turbo run lint"
|
|
825
|
+
timeout: 60000
|
|
826
|
+
on_failure: "block" # REQUIRED — "block" or "warn"
|
|
827
|
+
message: "Pre-commit checks via turbo."
|
|
828
|
+
locked: true
|
|
829
|
+
priority: 5
|
|
830
|
+
|
|
831
|
+
full-check:
|
|
832
|
+
enabled: false
|
|
833
|
+
steps:
|
|
834
|
+
- run: "turbo run type-check"
|
|
835
|
+
label: "Type-check all packages"
|
|
836
|
+
timeout: 60000
|
|
837
|
+
- run: "turbo run lint"
|
|
838
|
+
label: "Lint all packages"
|
|
839
|
+
timeout: 60000
|
|
840
|
+
on_failure: "warn" # REQUIRED — "block" or "warn"
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
### What NOT to Generate for Turborepo
|
|
844
|
+
|
|
845
|
+
- **Do NOT use `pnpm build` / `pnpm lint` in postconditions** — use `turbo run <task> --filter=<pkg>` instead
|
|
846
|
+
- **Do NOT generate global `tsc --noEmit` postconditions** — each package has its own tsconfig; use turbo to respect the task graph
|
|
847
|
+
- **Do NOT omit the topology comment** — it documents the workspace structure for humans
|
|
848
|
+
- **Do NOT skip package boundary rules** — they prevent the most common monorepo mistake (reverse imports)
|
|
849
|
+
- **Do NOT auto-approve git push** — even in monorepos, pushes affect shared state
|
|
@@ -2,31 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
## Node.js / TypeScript
|
|
4
4
|
|
|
5
|
+
**IMPORTANT:** Only auto-approve the DETECTED package manager, not all of them. If the project uses pnpm, only include the pnpm rule. Do not include npm/yarn/bun rules for a pnpm project.
|
|
6
|
+
|
|
5
7
|
```yaml
|
|
6
8
|
permissions:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
matcher: Bash
|
|
10
|
-
command_pattern: "npm"
|
|
11
|
-
decision: allow
|
|
12
|
-
|
|
9
|
+
# Include ONLY the detected package manager — pick ONE of these:
|
|
10
|
+
# If pnpm detected (pnpm-lock.yaml):
|
|
13
11
|
auto-approve-pnpm:
|
|
14
12
|
trigger: PermissionRequest
|
|
15
13
|
matcher: Bash
|
|
16
14
|
command_pattern: "pnpm"
|
|
17
15
|
decision: allow
|
|
18
|
-
|
|
19
|
-
auto-approve-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
auto-approve-bun:
|
|
26
|
-
|
|
27
|
-
matcher: Bash
|
|
28
|
-
command_pattern: "bun"
|
|
29
|
-
decision: allow
|
|
16
|
+
# If npm detected (package-lock.json):
|
|
17
|
+
# auto-approve-npm:
|
|
18
|
+
# command_pattern: "npm"
|
|
19
|
+
# If yarn detected (yarn.lock):
|
|
20
|
+
# auto-approve-yarn:
|
|
21
|
+
# command_pattern: "yarn"
|
|
22
|
+
# If bun detected (bun.lockb):
|
|
23
|
+
# auto-approve-bun:
|
|
24
|
+
# command_pattern: "bun"
|
|
30
25
|
|
|
31
26
|
auto-approve-node:
|
|
32
27
|
trigger: PermissionRequest
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createApiServer,
|
|
3
3
|
setUiServerPort
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2VYFVYJL.js";
|
|
5
5
|
import {
|
|
6
6
|
attachWebSocket
|
|
7
7
|
} from "./chunk-7AL4DOEJ.js";
|
|
@@ -15,7 +15,7 @@ import "./chunk-2CLNOKPA.js";
|
|
|
15
15
|
import "./chunk-SPOI23SB.js";
|
|
16
16
|
import "./chunk-6OCEY7JY.js";
|
|
17
17
|
import "./chunk-SIAQVRKG.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-JGBXM5NC.js";
|
|
19
19
|
import "./chunk-YM2HV4IA.js";
|
|
20
20
|
import "./chunk-KIKPIH6N.js";
|
|
21
21
|
import {
|
|
@@ -55,7 +55,7 @@ async function main() {
|
|
|
55
55
|
const projectDir = process.argv[2] || process.cwd();
|
|
56
56
|
const secret = generateApiSecret2();
|
|
57
57
|
setApiSecret2(secret);
|
|
58
|
-
const { createApiServer: createApiServer2 } = await import("./server-
|
|
58
|
+
const { createApiServer: createApiServer2 } = await import("./server-USLHY6GH-AEOJC5ST.js");
|
|
59
59
|
const { attachWebSocket: attachWebSocket2 } = await import("./server-X5P6WH2M-7K2RY34N.js");
|
|
60
60
|
const server = createApiServer2(projectDir);
|
|
61
61
|
const wss = attachWebSocket2(server, projectDir);
|