@ulpi/cli 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/LICENSE +21 -0
- package/README.md +200 -0
- package/dist/auth-PN7TMQHV-2W4ICG64.js +15 -0
- package/dist/chunk-247GVVKK.js +2259 -0
- package/dist/chunk-2CLNOKPA.js +793 -0
- package/dist/chunk-2HEE5OKX.js +79 -0
- package/dist/chunk-2MZER6ND.js +415 -0
- package/dist/chunk-3SBPZRB5.js +772 -0
- package/dist/chunk-4VNS5WPM.js +42 -0
- package/dist/chunk-6JCMYYBT.js +1546 -0
- package/dist/chunk-6OCEY7JY.js +422 -0
- package/dist/chunk-74WVVWJ4.js +375 -0
- package/dist/chunk-7AL4DOEJ.js +131 -0
- package/dist/chunk-7LXY5UVC.js +330 -0
- package/dist/chunk-DBMUNBNB.js +3048 -0
- package/dist/chunk-JWUUVXIV.js +13694 -0
- package/dist/chunk-KIKPIH6N.js +4048 -0
- package/dist/chunk-KLEASXUR.js +70 -0
- package/dist/chunk-MIAQVCFW.js +39 -0
- package/dist/chunk-NNUWU6CV.js +1610 -0
- package/dist/chunk-PKD4ASEM.js +115 -0
- package/dist/chunk-Q4HIY43N.js +4230 -0
- package/dist/chunk-QJ5GSMEC.js +146 -0
- package/dist/chunk-SIAQVRKG.js +2163 -0
- package/dist/chunk-SPOI23SB.js +197 -0
- package/dist/chunk-YM2HV4IA.js +505 -0
- package/dist/codemap-RRJIDBQ5.js +636 -0
- package/dist/config-EGAXXCGL.js +127 -0
- package/dist/dist-6G7JC2RA.js +90 -0
- package/dist/dist-7LHZ65GC.js +418 -0
- package/dist/dist-LZKZFPVX.js +140 -0
- package/dist/dist-R5F4MX3I.js +107 -0
- package/dist/dist-R5ZJ4LX5.js +56 -0
- package/dist/dist-RJGCUS3L.js +87 -0
- package/dist/dist-RKOGLK7R.js +151 -0
- package/dist/dist-W7K4WPAF.js +597 -0
- package/dist/export-import-4A5MWLIA.js +53 -0
- package/dist/history-ATTUKOHO.js +934 -0
- package/dist/index.js +2120 -0
- package/dist/init-AY5C2ZAS.js +393 -0
- package/dist/launchd-LF2QMSKZ.js +148 -0
- package/dist/log-TVTUXAYD.js +75 -0
- package/dist/mcp-installer-NQCGKQ23.js +124 -0
- package/dist/memory-J3G24QHS.js +406 -0
- package/dist/ollama-3XCUZMZT-FYKHW4TZ.js +7 -0
- package/dist/openai-E7G2YAHU-UYY4ZWON.js +8 -0
- package/dist/projects-ATHDD3D6.js +271 -0
- package/dist/review-ADUPV3PN.js +152 -0
- package/dist/rules-E427DKYJ.js +134 -0
- package/dist/server-MOYPE4SM-N7SE2AN7.js +18 -0
- package/dist/server-X5P6WH2M-7K2RY34N.js +11 -0
- package/dist/skills/ulpi-generate-guardian/SKILL.md +511 -0
- package/dist/skills/ulpi-generate-guardian/references/framework-rules.md +692 -0
- package/dist/skills/ulpi-generate-guardian/references/language-rules.md +596 -0
- package/dist/skills-CX73O3IV.js +76 -0
- package/dist/status-4DFHDJMN.js +66 -0
- package/dist/templates/biome.yml +24 -0
- package/dist/templates/conventional-commits.yml +18 -0
- package/dist/templates/django.yml +30 -0
- package/dist/templates/docker.yml +30 -0
- package/dist/templates/eslint.yml +13 -0
- package/dist/templates/express.yml +20 -0
- package/dist/templates/fastapi.yml +23 -0
- package/dist/templates/git-flow.yml +26 -0
- package/dist/templates/github-flow.yml +27 -0
- package/dist/templates/go.yml +33 -0
- package/dist/templates/jest.yml +24 -0
- package/dist/templates/laravel.yml +30 -0
- package/dist/templates/monorepo.yml +26 -0
- package/dist/templates/nestjs.yml +21 -0
- package/dist/templates/nextjs.yml +31 -0
- package/dist/templates/nodejs.yml +33 -0
- package/dist/templates/npm.yml +15 -0
- package/dist/templates/php.yml +25 -0
- package/dist/templates/pnpm.yml +15 -0
- package/dist/templates/prettier.yml +23 -0
- package/dist/templates/prisma.yml +21 -0
- package/dist/templates/python.yml +33 -0
- package/dist/templates/quality-of-life.yml +111 -0
- package/dist/templates/ruby.yml +25 -0
- package/dist/templates/rust.yml +34 -0
- package/dist/templates/typescript.yml +14 -0
- package/dist/templates/vitest.yml +24 -0
- package/dist/templates/yarn.yml +15 -0
- package/dist/templates-U7T6MARD.js +156 -0
- package/dist/ui-L7UAWXDY.js +167 -0
- package/dist/ui.html +698 -0
- package/dist/ulpi-RMMCUAGP-JCJ273T6.js +161 -0
- package/dist/uninstall-6SW35IK4.js +25 -0
- package/dist/update-M2B4RLGH.js +61 -0
- package/dist/version-checker-ANCS3IHR.js +10 -0
- package/package.json +92 -0
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ulpi-generate-guards
|
|
3
|
+
description: Use when the user asks to generate ULPI configuration for a project. Detects language, framework, package manager, and tooling to create optimized guards.yml with preconditions, permissions, postconditions, and pipelines. Invoke via /ulpi-generate-guards or when user says "generate guards", "create guards.yml", "setup ulpi", "configure guardian".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<EXTREMELY-IMPORTANT>
|
|
7
|
+
Before generating ANY guards.yml configuration, you **ABSOLUTELY MUST**:
|
|
8
|
+
|
|
9
|
+
1. Verify the target directory exists
|
|
10
|
+
2. Check for existing `.ulpi/guards.yml` (ask before overwriting)
|
|
11
|
+
3. Detect at least one technology signal (language, framework, or package manager)
|
|
12
|
+
|
|
13
|
+
**Generating without verification = wrong rules, overwritten configs, broken guards**
|
|
14
|
+
|
|
15
|
+
This is not optional. Every generation requires disciplined verification.
|
|
16
|
+
</EXTREMELY-IMPORTANT>
|
|
17
|
+
|
|
18
|
+
# Generate ULPI Configuration
|
|
19
|
+
|
|
20
|
+
## MANDATORY FIRST RESPONSE PROTOCOL
|
|
21
|
+
|
|
22
|
+
Before generating ANY configuration, you **MUST** complete this checklist:
|
|
23
|
+
|
|
24
|
+
1. ☐ Verify target directory exists
|
|
25
|
+
2. ☐ Check for existing guards.yml
|
|
26
|
+
3. ☐ Detect language (tsconfig.json, pyproject.toml, go.mod, etc.)
|
|
27
|
+
4. ☐ Detect framework (next.config.*, artisan, manage.py, etc.)
|
|
28
|
+
5. ☐ Detect package manager (pnpm-lock.yaml, yarn.lock, etc.)
|
|
29
|
+
6. ☐ Announce: "Generating ULPI configuration for [language]/[framework]/[package_manager]"
|
|
30
|
+
|
|
31
|
+
Do NOT ask "Proceed?" — the user invoked this skill explicitly. Show the detected stack as an informational summary, then generate immediately.
|
|
32
|
+
|
|
33
|
+
**Generating WITHOUT completing this checklist = wrong or harmful rules.**
|
|
34
|
+
|
|
35
|
+
## Purpose
|
|
36
|
+
|
|
37
|
+
This skill generates configuration for **ULPI**, a tool that:
|
|
38
|
+
- Auto-approves safe operations (reads, package manager commands)
|
|
39
|
+
- Blocks dangerous commands (force push, database wipes, env file edits)
|
|
40
|
+
- Enforces best practices (read-before-write)
|
|
41
|
+
- Runs postconditions (lint, test, generate) after file changes
|
|
42
|
+
|
|
43
|
+
**Output:** `.ulpi/guards.yml` configuration file
|
|
44
|
+
|
|
45
|
+
**Does NOT:** Install ULPI, run the generated rules, or modify existing configurations without confirmation.
|
|
46
|
+
|
|
47
|
+
## Overview
|
|
48
|
+
|
|
49
|
+
Analyze a project directory, detect the technology stack, and generate a complete `guards.yml` configuration for ULPI. Creates rules that auto-approve safe operations, block dangerous commands, and enforce best practices.
|
|
50
|
+
|
|
51
|
+
## When to Use
|
|
52
|
+
|
|
53
|
+
- User says "generate guards", "create guards.yml", "/ulpi-generate-guards"
|
|
54
|
+
- User says "setup ulpi", "configure guardian for this project"
|
|
55
|
+
- $ARGUMENTS contains a path (e.g., `/ulpi-generate-guards /path/to/project`)
|
|
56
|
+
|
|
57
|
+
**Never generate unprompted.** Only when explicitly requested.
|
|
58
|
+
|
|
59
|
+
## Step 1: Determine Target Directory
|
|
60
|
+
|
|
61
|
+
**Gate: Valid directory confirmed before proceeding to Step 2.**
|
|
62
|
+
|
|
63
|
+
If $ARGUMENTS has a path, use it. Otherwise use current working directory.
|
|
64
|
+
|
|
65
|
+
Verify the directory exists before proceeding. If not found, stop and inform the user.
|
|
66
|
+
|
|
67
|
+
Check for existing `.ulpi/guards.yml`:
|
|
68
|
+
- If found, ask user: merge, overwrite, or abort?
|
|
69
|
+
- Never overwrite without explicit confirmation
|
|
70
|
+
|
|
71
|
+
## Step 2: Detect Technology Stack
|
|
72
|
+
|
|
73
|
+
**Gate: Stack detected before proceeding to Step 3.**
|
|
74
|
+
|
|
75
|
+
Scan for indicator files in priority order:
|
|
76
|
+
|
|
77
|
+
### Language Detection
|
|
78
|
+
|
|
79
|
+
| Signal | Language |
|
|
80
|
+
|--------|----------|
|
|
81
|
+
| `tsconfig.json` | TypeScript |
|
|
82
|
+
| `package.json` (no tsconfig) | JavaScript |
|
|
83
|
+
| `pyproject.toml`, `requirements.txt` | Python |
|
|
84
|
+
| `go.mod` | Go |
|
|
85
|
+
| `Cargo.toml` | Rust |
|
|
86
|
+
| `composer.json` | PHP |
|
|
87
|
+
| `Gemfile` | Ruby |
|
|
88
|
+
| `pom.xml`, `build.gradle` | Java |
|
|
89
|
+
| `*.csproj`, `*.sln` | C# |
|
|
90
|
+
| `mix.exs` | Elixir |
|
|
91
|
+
|
|
92
|
+
### Framework Detection
|
|
93
|
+
|
|
94
|
+
| Signal | Framework |
|
|
95
|
+
|--------|-----------|
|
|
96
|
+
| `next.config.*` | Next.js |
|
|
97
|
+
| `nuxt.config.*` | Nuxt |
|
|
98
|
+
| `angular.json` | Angular |
|
|
99
|
+
| `svelte.config.*` | SvelteKit |
|
|
100
|
+
| `nest-cli.json` | NestJS |
|
|
101
|
+
| `artisan` | Laravel |
|
|
102
|
+
| `manage.py` + django | Django |
|
|
103
|
+
| `fastapi` in deps | FastAPI |
|
|
104
|
+
| `actix-web` in Cargo.toml | Actix |
|
|
105
|
+
| `gin` in go.mod | Gin |
|
|
106
|
+
|
|
107
|
+
### Package Manager Detection
|
|
108
|
+
|
|
109
|
+
| Signal | Package Manager |
|
|
110
|
+
|--------|-----------------|
|
|
111
|
+
| `pnpm-lock.yaml` | pnpm |
|
|
112
|
+
| `yarn.lock` | yarn |
|
|
113
|
+
| `package-lock.json` | npm |
|
|
114
|
+
| `bun.lockb` | bun |
|
|
115
|
+
| `poetry.lock` | poetry |
|
|
116
|
+
| `uv.lock` | uv |
|
|
117
|
+
| `Cargo.lock` | cargo |
|
|
118
|
+
| `composer.lock` | composer |
|
|
119
|
+
| `Gemfile.lock` | bundler |
|
|
120
|
+
|
|
121
|
+
### Tooling Detection
|
|
122
|
+
|
|
123
|
+
| Signal | Tool | Type |
|
|
124
|
+
|--------|------|------|
|
|
125
|
+
| `vitest.config.*` | Vitest | test |
|
|
126
|
+
| `jest.config.*` | Jest | test |
|
|
127
|
+
| `pytest.ini` | pytest | test |
|
|
128
|
+
| `.eslintrc*` | ESLint | lint |
|
|
129
|
+
| `.prettierrc*` | Prettier | format |
|
|
130
|
+
| `biome.json` | Biome | lint+format |
|
|
131
|
+
| `prisma/schema.prisma` | Prisma | ORM |
|
|
132
|
+
| `drizzle.config.*` | Drizzle | ORM |
|
|
133
|
+
|
|
134
|
+
### Monorepo Detection
|
|
135
|
+
|
|
136
|
+
| Signal | Structure |
|
|
137
|
+
|--------|-----------|
|
|
138
|
+
| `turbo.json` | Turborepo |
|
|
139
|
+
| `lerna.json` | Lerna |
|
|
140
|
+
| `pnpm-workspace.yaml` | pnpm workspaces |
|
|
141
|
+
| `"workspaces"` in package.json | Yarn/npm workspaces |
|
|
142
|
+
|
|
143
|
+
For monorepos: Generate root-level rules that apply to all packages.
|
|
144
|
+
|
|
145
|
+
## Step 3: Extract Commands from Config
|
|
146
|
+
|
|
147
|
+
**Gate: Commands extracted before proceeding to Step 4.**
|
|
148
|
+
|
|
149
|
+
For Node.js projects, read package.json scripts to identify:
|
|
150
|
+
- `test_command` (from "test" script)
|
|
151
|
+
- `build_command` (from "build" script)
|
|
152
|
+
- `lint_command` (from "lint" script)
|
|
153
|
+
- `format_command` (from "format" script)
|
|
154
|
+
|
|
155
|
+
For Python projects, check pyproject.toml for tool configurations.
|
|
156
|
+
|
|
157
|
+
For Rust projects, use standard cargo commands.
|
|
158
|
+
|
|
159
|
+
## Step 4: Generate guards.yml
|
|
160
|
+
|
|
161
|
+
**Gate: Complete rules generated before proceeding to Step 5.**
|
|
162
|
+
|
|
163
|
+
Create `.ulpi/guards.yml` with these sections:
|
|
164
|
+
|
|
165
|
+
### Header
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
# ULPI — Generated Configuration
|
|
169
|
+
# Stack: {language} / {framework} / {package_manager}
|
|
170
|
+
# Generated: {timestamp}
|
|
171
|
+
|
|
172
|
+
project:
|
|
173
|
+
name: "{project_name}"
|
|
174
|
+
runtime: "{runtime}"
|
|
175
|
+
package_manager: "{package_manager}"
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Universal Preconditions (Always Include)
|
|
179
|
+
|
|
180
|
+
```yaml
|
|
181
|
+
preconditions:
|
|
182
|
+
read-before-write:
|
|
183
|
+
enabled: true
|
|
184
|
+
trigger: PreToolUse
|
|
185
|
+
matcher: "Write|Edit|MultiEdit"
|
|
186
|
+
requires_read: true
|
|
187
|
+
message: "Read {file_path} before editing it."
|
|
188
|
+
locked: true
|
|
189
|
+
priority: 10
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Universal Permissions (Always Include)
|
|
193
|
+
|
|
194
|
+
```yaml
|
|
195
|
+
permissions:
|
|
196
|
+
auto-approve-reads:
|
|
197
|
+
enabled: true
|
|
198
|
+
trigger: PermissionRequest
|
|
199
|
+
matcher: "Read|LS|Glob|Grep"
|
|
200
|
+
decision: allow
|
|
201
|
+
priority: 100
|
|
202
|
+
|
|
203
|
+
no-force-push:
|
|
204
|
+
enabled: true
|
|
205
|
+
trigger: PreToolUse
|
|
206
|
+
matcher: Bash
|
|
207
|
+
command_pattern: "git push --force"
|
|
208
|
+
decision: deny
|
|
209
|
+
message: "Force push blocked. Use --force-with-lease."
|
|
210
|
+
locked: true
|
|
211
|
+
priority: 1
|
|
212
|
+
|
|
213
|
+
block-env-files:
|
|
214
|
+
enabled: true
|
|
215
|
+
trigger: PreToolUse
|
|
216
|
+
matcher: "Write|Edit"
|
|
217
|
+
file_pattern: ".env*"
|
|
218
|
+
decision: deny
|
|
219
|
+
message: "Cannot edit .env files directly."
|
|
220
|
+
priority: 50
|
|
221
|
+
|
|
222
|
+
block-node-modules:
|
|
223
|
+
enabled: true
|
|
224
|
+
trigger: PreToolUse
|
|
225
|
+
matcher: "Write|Edit"
|
|
226
|
+
file_pattern: "node_modules/**"
|
|
227
|
+
decision: deny
|
|
228
|
+
locked: true
|
|
229
|
+
priority: 1
|
|
230
|
+
|
|
231
|
+
block-dist:
|
|
232
|
+
enabled: true
|
|
233
|
+
trigger: PreToolUse
|
|
234
|
+
matcher: "Write|Edit"
|
|
235
|
+
file_pattern: "**/dist/**"
|
|
236
|
+
decision: deny
|
|
237
|
+
locked: true
|
|
238
|
+
priority: 1
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Language-Specific Rules
|
|
242
|
+
|
|
243
|
+
Add based on detected language. See `references/language-rules.md`.
|
|
244
|
+
|
|
245
|
+
### Framework-Specific Rules
|
|
246
|
+
|
|
247
|
+
Add based on detected framework. See `references/framework-rules.md`.
|
|
248
|
+
|
|
249
|
+
## Step 5: Write Configuration
|
|
250
|
+
|
|
251
|
+
**Gate: File written before proceeding to Step 6.**
|
|
252
|
+
|
|
253
|
+
Create the `.ulpi/` directory if it doesn't exist.
|
|
254
|
+
|
|
255
|
+
Write the generated YAML to `guards.yml`.
|
|
256
|
+
|
|
257
|
+
Verify the file was written successfully.
|
|
258
|
+
|
|
259
|
+
## Step 6: Report Results
|
|
260
|
+
|
|
261
|
+
**Gate: Results reported before marking complete.**
|
|
262
|
+
|
|
263
|
+
Report to the user:
|
|
264
|
+
- Stack detected
|
|
265
|
+
- Rules created (counts)
|
|
266
|
+
- File location
|
|
267
|
+
- Suggested next steps
|
|
268
|
+
|
|
269
|
+
## Pre-Generation Checklist
|
|
270
|
+
|
|
271
|
+
Before generating, verify:
|
|
272
|
+
- [ ] Target directory exists and is accessible
|
|
273
|
+
- [ ] No existing guards.yml OR user approved overwrite
|
|
274
|
+
- [ ] At least one technology detected
|
|
275
|
+
|
|
276
|
+
## Error Handling
|
|
277
|
+
|
|
278
|
+
| Situation | Action |
|
|
279
|
+
|-----------|--------|
|
|
280
|
+
| Directory not found | Stop and inform user |
|
|
281
|
+
| No tech stack detected | Generate minimal universal rules only |
|
|
282
|
+
| Multiple frameworks | Ask user which is primary |
|
|
283
|
+
| Existing guards.yml | Ask: merge, overwrite, or abort |
|
|
284
|
+
| Conflicting signals | Prefer more specific (framework > language) |
|
|
285
|
+
|
|
286
|
+
## About Postconditions
|
|
287
|
+
|
|
288
|
+
Postconditions are **disabled by default** because they run automatically after file changes and may:
|
|
289
|
+
- Slow down workflows
|
|
290
|
+
- Produce unexpected side effects
|
|
291
|
+
- Conflict with user's preferred workflow
|
|
292
|
+
|
|
293
|
+
**To enable:** User should manually set `enabled: true` for desired postconditions after reviewing them.
|
|
294
|
+
|
|
295
|
+
## Safety Rules
|
|
296
|
+
|
|
297
|
+
| Rule | Reason |
|
|
298
|
+
|------|--------|
|
|
299
|
+
| Always include read-before-write | Prevents editing files without reading first |
|
|
300
|
+
| Always block force push | Prevents history destruction |
|
|
301
|
+
| Always block .env edits | Protects secrets |
|
|
302
|
+
| Always block node_modules/dist | Build artifacts should not be edited |
|
|
303
|
+
| Auto-approve reads | Safe operations should not prompt |
|
|
304
|
+
| Auto-approve detected package manager | Reduces friction |
|
|
305
|
+
| Never overwrite without asking | Preserves existing configuration |
|
|
306
|
+
| Always verify directory exists | Prevents errors |
|
|
307
|
+
|
|
308
|
+
## Quick Reference: Command Detection
|
|
309
|
+
|
|
310
|
+
```
|
|
311
|
+
package.json scripts:
|
|
312
|
+
"test" → test_command
|
|
313
|
+
"build" → build_command
|
|
314
|
+
"lint" → lint_command
|
|
315
|
+
"format" → format_command
|
|
316
|
+
"dev" → auto-approve permission
|
|
317
|
+
|
|
318
|
+
pyproject.toml:
|
|
319
|
+
[tool.pytest] → pytest
|
|
320
|
+
[tool.ruff] → ruff
|
|
321
|
+
[tool.black] → black
|
|
322
|
+
|
|
323
|
+
Cargo.toml:
|
|
324
|
+
cargo test → test_command
|
|
325
|
+
cargo build → build_command
|
|
326
|
+
cargo clippy → lint_command
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Quality Checklist (Must Score 8/10)
|
|
332
|
+
|
|
333
|
+
Score yourself honestly before marking generation complete:
|
|
334
|
+
|
|
335
|
+
### Detection Accuracy (0-2 points)
|
|
336
|
+
- **0 points:** Guessed technology without file verification
|
|
337
|
+
- **1 point:** Detected some signals but missed others
|
|
338
|
+
- **2 points:** Verified all signals, detection matches reality
|
|
339
|
+
|
|
340
|
+
### Stack Announcement (0-2 points)
|
|
341
|
+
- **0 points:** Generated without showing detected stack
|
|
342
|
+
- **1 point:** Showed partial detection
|
|
343
|
+
- **2 points:** Full detection shown before generation
|
|
344
|
+
|
|
345
|
+
### Rule Coverage (0-2 points)
|
|
346
|
+
- **0 points:** Missing universal rules (read-before-write, block-env)
|
|
347
|
+
- **1 point:** Universal rules present but missing language/framework rules
|
|
348
|
+
- **2 points:** Complete coverage: universal + language + framework + tooling
|
|
349
|
+
|
|
350
|
+
### Safety Rules (0-2 points)
|
|
351
|
+
- **0 points:** Missing critical blocks (force-push, env files)
|
|
352
|
+
- **1 point:** Some safety rules but incomplete
|
|
353
|
+
- **2 points:** All dangerous operations blocked
|
|
354
|
+
|
|
355
|
+
### Output Quality (0-2 points)
|
|
356
|
+
- **0 points:** Invalid YAML or missing required fields
|
|
357
|
+
- **1 point:** Valid but poorly organized
|
|
358
|
+
- **2 points:** Clean, well-commented, properly structured YAML
|
|
359
|
+
|
|
360
|
+
**Minimum passing score: 8/10**
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Common Rationalizations (All Wrong)
|
|
365
|
+
|
|
366
|
+
These are excuses. Don't fall for them:
|
|
367
|
+
|
|
368
|
+
- **"The directory is obvious"** → STILL verify it exists
|
|
369
|
+
- **"I know this is a Node.js project"** → STILL detect from config files
|
|
370
|
+
- **"There's no existing guards.yml"** → STILL check before generating
|
|
371
|
+
- **"The user wants it fast"** → STILL show detected stack first
|
|
372
|
+
- **"These are standard rules"** → STILL customize for detected stack
|
|
373
|
+
- **"Postconditions are disabled anyway"** → STILL generate them correctly
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Failure Modes
|
|
378
|
+
|
|
379
|
+
### Failure Mode 1: Wrong Technology Detection
|
|
380
|
+
|
|
381
|
+
**Symptom:** Generated Python rules for a TypeScript project
|
|
382
|
+
**Fix:** Always verify with config files, not assumptions
|
|
383
|
+
|
|
384
|
+
### Failure Mode 2: Overwritten Existing Config
|
|
385
|
+
|
|
386
|
+
**Symptom:** User's custom guards.yml was replaced without warning
|
|
387
|
+
**Fix:** Always check for existing file, ask before overwriting
|
|
388
|
+
|
|
389
|
+
### Failure Mode 3: Missing Critical Safety Rules
|
|
390
|
+
|
|
391
|
+
**Symptom:** Agent force-pushed after generation (rule wasn't blocked)
|
|
392
|
+
**Fix:** Always include universal safety rules regardless of stack
|
|
393
|
+
|
|
394
|
+
### Failure Mode 4: Invalid YAML Generated
|
|
395
|
+
|
|
396
|
+
**Symptom:** ULPI fails to parse guards.yml
|
|
397
|
+
**Fix:** Validate YAML structure before writing
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Quick Workflow Summary
|
|
402
|
+
|
|
403
|
+
```
|
|
404
|
+
STEP 1: DETERMINE TARGET
|
|
405
|
+
├── Parse $ARGUMENTS for path
|
|
406
|
+
├── Default to current directory
|
|
407
|
+
├── Verify directory exists
|
|
408
|
+
├── Check for existing guards.yml
|
|
409
|
+
└── Gate: Valid directory confirmed
|
|
410
|
+
|
|
411
|
+
STEP 2: DETECT TECHNOLOGY
|
|
412
|
+
├── Scan for language signals
|
|
413
|
+
├── Scan for framework signals
|
|
414
|
+
├── Scan for package manager signals
|
|
415
|
+
├── Scan for tooling (test, lint, ORM)
|
|
416
|
+
├── Check for monorepo structure
|
|
417
|
+
├── Announce detected stack (informational, no question)
|
|
418
|
+
└── Gate: Stack detected
|
|
419
|
+
|
|
420
|
+
STEP 3: EXTRACT COMMANDS
|
|
421
|
+
├── Read package.json scripts
|
|
422
|
+
├── Read pyproject.toml tools
|
|
423
|
+
├── Identify test/build/lint commands
|
|
424
|
+
└── Gate: Commands extracted
|
|
425
|
+
|
|
426
|
+
STEP 4: GENERATE RULES
|
|
427
|
+
├── Start with universal rules
|
|
428
|
+
├── Add language-specific rules
|
|
429
|
+
├── Add framework-specific rules
|
|
430
|
+
├── Add tooling rules
|
|
431
|
+
└── Gate: Complete rules generated
|
|
432
|
+
|
|
433
|
+
STEP 5: WRITE CONFIGURATION
|
|
434
|
+
├── Create .ulpi/ directory
|
|
435
|
+
├── Write guards.yml
|
|
436
|
+
├── Verify file written
|
|
437
|
+
└── Gate: File written
|
|
438
|
+
|
|
439
|
+
STEP 6: REPORT RESULTS
|
|
440
|
+
├── Show stack summary
|
|
441
|
+
├── Show rule counts
|
|
442
|
+
├── Show file location
|
|
443
|
+
├── Suggest next steps
|
|
444
|
+
└── Gate: Complete
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
## Completion Announcement
|
|
450
|
+
|
|
451
|
+
When generation is complete, announce:
|
|
452
|
+
|
|
453
|
+
```
|
|
454
|
+
ULPI configuration generated.
|
|
455
|
+
|
|
456
|
+
**Quality Score: X/10**
|
|
457
|
+
- Detection Accuracy: X/2
|
|
458
|
+
- Stack Announcement: X/2
|
|
459
|
+
- Rule Coverage: X/2
|
|
460
|
+
- Safety Rules: X/2
|
|
461
|
+
- Output Quality: X/2
|
|
462
|
+
|
|
463
|
+
**Stack Detected:**
|
|
464
|
+
- Language: [language]
|
|
465
|
+
- Framework: [framework]
|
|
466
|
+
- Package Manager: [package_manager]
|
|
467
|
+
- Test Runner: [test_runner]
|
|
468
|
+
- Linter: [linter]
|
|
469
|
+
|
|
470
|
+
**Rules Generated:**
|
|
471
|
+
- Preconditions: [count]
|
|
472
|
+
- Permissions: [count]
|
|
473
|
+
- Postconditions: [count]
|
|
474
|
+
|
|
475
|
+
**Output:** .ulpi/guards.yml
|
|
476
|
+
|
|
477
|
+
**Next steps:**
|
|
478
|
+
Run `ulpi rules validate` to verify configuration.
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## Integration with Other Skills
|
|
484
|
+
|
|
485
|
+
The `ulpi-generate-guards` skill integrates with:
|
|
486
|
+
|
|
487
|
+
- **`start`** — Detects ULPI configuration needs during project setup
|
|
488
|
+
- **`commit`** — Generated rules can auto-approve git operations
|
|
489
|
+
- **`create-pr`** — Generated rules can auto-approve PR creation commands
|
|
490
|
+
|
|
491
|
+
**Workflow Chain:**
|
|
492
|
+
|
|
493
|
+
```
|
|
494
|
+
New project or directory
|
|
495
|
+
│
|
|
496
|
+
▼
|
|
497
|
+
ulpi-generate-guards skill (this skill)
|
|
498
|
+
│
|
|
499
|
+
▼
|
|
500
|
+
guards.yml created
|
|
501
|
+
│
|
|
502
|
+
▼
|
|
503
|
+
ULPI uses rules during development
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## Resources
|
|
509
|
+
|
|
510
|
+
See `references/language-rules.md` for language-specific rule templates.
|
|
511
|
+
See `references/framework-rules.md` for framework-specific rule templates.
|