the-frame-ai 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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +335 -0
  3. package/README.ru.md +333 -0
  4. package/bin/the-frame +5 -0
  5. package/bin/the-frame-ai +5 -0
  6. package/package.json +29 -0
  7. package/src/cli.js +84 -0
  8. package/src/doctor.js +164 -0
  9. package/src/init.js +178 -0
  10. package/src/languages.js +141 -0
  11. package/src/manifest.js +55 -0
  12. package/src/update.js +87 -0
  13. package/src/utils.js +55 -0
  14. package/templates/agents/builder.md +240 -0
  15. package/templates/agents/devils-advocate.md +136 -0
  16. package/templates/agents/planner.md +277 -0
  17. package/templates/agents/researcher.md +195 -0
  18. package/templates/agents/reviewer.md +300 -0
  19. package/templates/commands/frame:add-task.md +57 -0
  20. package/templates/commands/frame:build.md +170 -0
  21. package/templates/commands/frame:check-deps.md +118 -0
  22. package/templates/commands/frame:checkpoint.md +158 -0
  23. package/templates/commands/frame:cleanup-memory.md +80 -0
  24. package/templates/commands/frame:context.md +64 -0
  25. package/templates/commands/frame:daily.md +77 -0
  26. package/templates/commands/frame:debug.md +146 -0
  27. package/templates/commands/frame:doctor.md +170 -0
  28. package/templates/commands/frame:estimate.md +105 -0
  29. package/templates/commands/frame:explain.md +84 -0
  30. package/templates/commands/frame:fast.md +89 -0
  31. package/templates/commands/frame:forensics.md +139 -0
  32. package/templates/commands/frame:headless.md +118 -0
  33. package/templates/commands/frame:health.md +86 -0
  34. package/templates/commands/frame:init.md +231 -0
  35. package/templates/commands/frame:migrate.md +107 -0
  36. package/templates/commands/frame:note.md +32 -0
  37. package/templates/commands/frame:pause.md +145 -0
  38. package/templates/commands/frame:performance.md +228 -0
  39. package/templates/commands/frame:plan.md +198 -0
  40. package/templates/commands/frame:refactor.md +161 -0
  41. package/templates/commands/frame:research.md +131 -0
  42. package/templates/commands/frame:resume.md +137 -0
  43. package/templates/commands/frame:retrospective.md +196 -0
  44. package/templates/commands/frame:review.md +174 -0
  45. package/templates/commands/frame:rollback.md +207 -0
  46. package/templates/commands/frame:ship.md +148 -0
  47. package/templates/commands/frame:sprint-check.md +111 -0
  48. package/templates/commands/frame:status.md +103 -0
  49. package/templates/commands/frame:unstuck.md +102 -0
  50. package/templates/commands/frame:wave.md +312 -0
  51. package/templates/commands/frame:where.md +5 -0
  52. package/templates/commands/frame:why.md +57 -0
  53. package/templates/commands/frame:worktree.md +219 -0
  54. package/templates/hooks/git-safety.sh +33 -0
  55. package/templates/hooks/quality-gate.sh +52 -0
  56. package/templates/hooks/safety-net.sh +13 -0
  57. package/templates/hooks/session-init.sh +81 -0
  58. package/templates/planning/pause-state.json +1 -0
  59. package/templates/project/CLAUDE.md +63 -0
  60. package/templates/project/CONTEXT.md +16 -0
  61. package/templates/project/MAP.md +35 -0
  62. package/templates/project/ROADMAP.md +12 -0
  63. package/templates/project/STATE.md +13 -0
  64. package/templates/project/config.json +74 -0
  65. package/templates/project/memory/anti-patterns.md +14 -0
  66. package/templates/project/memory/context.md +23 -0
  67. package/templates/project/memory/conventions.md +19 -0
  68. package/templates/project/memory/decisions.md +20 -0
  69. package/templates/project/memory/dependencies.md +23 -0
  70. package/templates/project/memory/metrics.md +22 -0
  71. package/templates/project/memory/patterns.md +30 -0
  72. package/templates/project/memory/wins.md +11 -0
  73. package/templates/project/settings.local.json +50 -0
  74. package/templates/project/specs/_template/PRD.md +24 -0
  75. package/templates/project/specs/_template/plan.md +25 -0
  76. package/templates/project/specs/_template/spec.md +27 -0
  77. package/templates/project/specs/_template/subagent-prompt.md +43 -0
@@ -0,0 +1,312 @@
1
+ # /frame:wave -- Parallel Task Execution
2
+
3
+ > Use for 4+ independent tasks (parallel subagents). For 1–3 tasks → `/frame:build`
4
+
5
+ Identifies dependencies, groups into waves, launches subagents in parallel.
6
+
7
+ **Role**: Orchestrator (not Builder). You coordinate and validate — subagents write the code.
8
+
9
+ ## Instructions
10
+
11
+ ### Step 0: Fail-fast validation + STATE.md (IN_PROGRESS)
12
+
13
+ **Before doing anything**, check:
14
+ - `.planning/MAP.md` exists — if missing, STOP: "Run /frame:init first — MAP.md not found."
15
+ - `plan.md` exists: `find docs/specs -name "plan.md" | head -1` — if missing, STOP: "No plan.md found. Run /frame:plan first."
16
+
17
+ Then immediately update `.planning/STATE.md`:
18
+ ```markdown
19
+ ## Current Position
20
+ - Phase: BUILD (wave)
21
+ - Feature: {feature from plan.md}
22
+ - Status: IN_PROGRESS
23
+ - Started: {timestamp}
24
+ ```
25
+
26
+ **Orchestrator heartbeat rules:**
27
+ - After each wave completes: "Wave {N}/{total} done — {passed}/{total_tasks} tasks committed"
28
+ - Before launching a wave: "Launching Wave {N}: {task_names}"
29
+ - No more than 3 tool calls in a row without output
30
+
31
+ ### Step 1: Find plan.md
32
+
33
+ - `find docs/specs -name "plan.md" | head -5`
34
+ - Read plan.md
35
+
36
+ ### Step 2: Determine dependencies
37
+
38
+ For each task, determine:
39
+ - Which files it will change (Files: `path/to/file`)
40
+ - Which other tasks it depends on (Dependencies: Task N)
41
+ - Which wave it belongs to (auto-assigned by dependencies)
42
+
43
+ **Wave algorithm**: no dependencies → Wave 1; depends on Wave N → Wave N+1; depends on multiple waves → max(waves) + 1.
44
+
45
+ If plan.md already has `Wave:` fields — use them. Otherwise compute from dependencies.
46
+
47
+ ### Step 3: Group into waves
48
+
49
+ ```
50
+ Wave 1: Tasks with no dependencies (parallel)
51
+ Wave 2: Tasks that depend on Wave 1
52
+ Wave 3: Tasks that depend on Wave 2
53
+ ...
54
+ ```
55
+
56
+ ### Step 4: Check file conflicts and Risk
57
+
58
+ **File Locking Strategy:**
59
+
60
+ 1. Each subagent declares files in plan.md
61
+ 2. Orchestrator checks for file overlaps between tasks in the same wave
62
+ 3. If overlap exists — move tasks to separate waves or merge (sequential)
63
+ 4. If no overlap — launch in parallel
64
+
65
+ ```
66
+ Subagent 1: Files: [lib/api/client.ts, types/api.ts]
67
+ Subagent 2: Files: [components/chat/message.tsx]
68
+ -> No overlap -> parallel OK
69
+
70
+ Subagent 1: Files: [components/chat/message.tsx]
71
+ Subagent 2: Files: [components/chat/message.tsx]
72
+ -> Overlap -> same wave (sequential) WARNING
73
+ ```
74
+
75
+ **Risk strategy for waves:**
76
+
77
+ Before launching a wave, check task Risk fields:
78
+
79
+ - If the wave contains a `Risk: high` task →
80
+ create a git checkpoint before the wave:
81
+ `git tag frame/pre-wave-{N}-{timestamp}`
82
+
83
+ - If the wave contains more than one `Risk: high` task →
84
+ move them into a separate wave, do not run in parallel
85
+
86
+ ### Step 5: Launch Wave N
87
+
88
+ Before launching, update STATE.md:
89
+ ```markdown
90
+ - Phase: BUILD (wave)
91
+ - Status: IN_PROGRESS
92
+ - Wave: {N}/{total}
93
+ - Wave Status: Running (0/{count} subagents completed)
94
+ - Started: {timestamp}
95
+ ```
96
+
97
+ For each task in the wave, launch a subagent via the Agent tool:
98
+ - Fresh context (200K)
99
+ - Self-contained prompt from `docs/specs/_template/subagent-prompt.md`
100
+ - Fill in all placeholders
101
+
102
+ **Maximum 5 subagents** per wave.
103
+
104
+ If a subagent produces no output for more than 2 minutes →
105
+ consider it hung, log in STATE.md: `Wave Status: AGENT_HUNG ({task_name})`
106
+
107
+ ### Step 6: Wave Validation (D-step)
108
+
109
+ After all subagents in the wave complete:
110
+
111
+ ```bash
112
+ {quality.commands.typecheck}
113
+ {quality.commands.test}
114
+ {quality.commands.lint}
115
+ git log --oneline -5
116
+ ```
117
+
118
+ **Logic:**
119
+ - If **OK** -> proceed to next wave
120
+ - If **FAIL** -> Retry strategy (see below)
121
+ - **Max retries: 2** per wave
122
+
123
+ ### Retry strategy
124
+
125
+ On FAIL of wave N:
126
+ 1. Identify which tasks failed (via git log — no commit present)
127
+ 2. Relaunch ONLY the failed subagents (not the entire wave)
128
+ 3. Tasks with a `[DONE]` commit — do not touch
129
+
130
+ ### Step 7: Repeat for each wave
131
+
132
+ Repeat Steps 5-6 for each wave until all waves are complete.
133
+
134
+ ### Step 8: Final validation
135
+
136
+ ```bash
137
+ {quality.commands.typecheck}
138
+ {quality.commands.test}
139
+ {quality.commands.lint}
140
+ {quality.commands.build}
141
+ git log --oneline -10
142
+ ```
143
+
144
+ Check completeness:
145
+ ```bash
146
+ TOTAL=$(grep -c "^### Task" plan.md)
147
+ DONE=$(grep -c "\[DONE\]" plan.md)
148
+
149
+ if [ "$TOTAL" != "$DONE" ]; then
150
+ echo "⚠️ Unclosed tasks: $((TOTAL - DONE)) of $TOTAL"
151
+ grep "^### Task" plan.md | grep -v "\[DONE\]"
152
+ fi
153
+ ```
154
+
155
+ ### Step 9: Update STATE.md and Memory
156
+
157
+ Update `.planning/STATE.md`:
158
+ ```markdown
159
+ ## Current Position
160
+ - Phase: BUILD
161
+ - Feature: {feature}
162
+ - Task: {completed}/{total}
163
+ - Status: Wave execution complete -- all {N} waves passed
164
+ ```
165
+
166
+ **Memory Updates (if patterns found):**
167
+
168
+ Analyze git log of waves. If recurring solutions are visible → suggest adding to patterns.md:
169
+
170
+ "During the wave, the following patterns were used N times: {pattern}. Add to patterns.md? (y/n)"
171
+
172
+ ## Wave Failure Strategy
173
+
174
+ If wave N failed after 2 retries:
175
+
176
+ ```
177
+ 1. git tag frame/wave-failure-{N}
178
+ 2. Update STATE.md: Status: WAVE_FAILED, Wave: N
179
+ 3. Show the user:
180
+ ✅ What succeeded (committed waves 1..N-1)
181
+ ❌ What did not complete (wave N and its dependents)
182
+ 4. Do NOT auto-rollback previous waves
183
+ ```
184
+
185
+ User decides: manual retry, fix and relaunch, or rollback via `/frame:rollback`.
186
+
187
+ ## Task format in plan.md
188
+
189
+ ```markdown
190
+ ### Task 1: API Client
191
+ - Files: `lib/api/client.ts`
192
+ - Dependencies: NONE
193
+ - Wave: 1
194
+ - Risk: low
195
+
196
+ ### Task 2: Types
197
+ - Files: `types/api.ts`
198
+ - Dependencies: NONE
199
+ - Wave: 1
200
+ - Risk: low
201
+
202
+ ### Task 3: UI Components
203
+ - Files: `components/chat/message.tsx`
204
+ - Dependencies: Task 1 (API Client), Task 2 (Types)
205
+ - Wave: 2
206
+ - Risk: high
207
+
208
+ ### Task 4: Tests for API
209
+ - Files: `lib/api/__tests__/client.test.ts`
210
+ - Dependencies: Task 1
211
+ - Wave: 2
212
+ - Risk: low
213
+
214
+ ### Task 5: Tests for UI
215
+ - Files: `components/chat/__tests__/message.test.tsx`
216
+ - Dependencies: Task 3
217
+ - Wave: 3
218
+ - Risk: low
219
+ ```
220
+
221
+ ## Subagent Prompt Template
222
+
223
+ See `docs/specs/_template/subagent-prompt.md` for the full template with placeholders.
224
+
225
+ Brief version for quick use:
226
+
227
+ ```markdown
228
+ # Task: {task_name}
229
+
230
+ ## Memory (read before writing code)
231
+ - .planning/memory/anti-patterns.md — what to avoid
232
+ - .planning/memory/conventions.md — how to write code
233
+ - .planning/memory/dependencies.md — stack + Avoid list
234
+ - docs/specs/{FEATURE}/research.md → Memory Impact section
235
+
236
+ ## Heartbeat rules
237
+ - After each D-step: "✓ Task {name}: {step} confirmed"
238
+ - Before a long command: "⏳ Running: {command}"
239
+ - No more than 3 tools in a row without output
240
+
241
+ ## Context
242
+ - Project: {project_name}
243
+ - MAP: See .planning/MAP.md
244
+ - Spec: See docs/specs/{FEATURE}/spec.md
245
+ - Task: {task_description}
246
+
247
+ ## Your Role: Builder
248
+ 1. Write TEST first (RED)
249
+ 2. Verify: `{quality.commands.test} {test_file}`
250
+ 3. Write CODE (GREEN)
251
+ 4. Verify: `{quality.commands.test} {test_file}`
252
+ 5. Refactor if needed
253
+ 6. Verify types: `{quality.commands.typecheck}`
254
+ 7. Verify lint: `{quality.commands.lint}`
255
+ 8. Git commit: `{type}({scope}): {description}`
256
+
257
+ ## Key Files
258
+ - {file1} -- {purpose}
259
+ - {file2} -- {purpose}
260
+
261
+ ## Patterns
262
+ - Follow project conventions from CLAUDE.md
263
+ - Errors: use project error reporting (no console.log for errors)
264
+ - Types: no `any` (use `unknown` + type guard)
265
+
266
+ ## DO NOT
267
+ - Do not modify files outside {scope_dir}
268
+ - Do not skip tests
269
+ - Do not use `any` type
270
+ - Do not add dependencies without approval
271
+ - Do not commit without passing quality gates
272
+ ```
273
+
274
+ ## Rules
275
+
276
+ - **Maximum 5 subagents** per wave
277
+ - **File locking** -- check conflicts before launching a wave
278
+ - **Risk strategy** -- isolate high-risk tasks into a separate wave + git tag
279
+ - **STATE.md before launch** -- update IN_PROGRESS before each wave
280
+ - **Subagent heartbeat** -- >2 min without output = hung
281
+ - **Wave validation** -- D-step (tsc + vitest + eslint) between waves
282
+ - **Retry only failed** -- max 2 retries, only tasks without [DONE] commit
283
+ - **Wave Failure Strategy** -- git tag + STATE.md + report to user, do not auto-rollback
284
+ - **Completeness check** -- grep plan.md before final report
285
+ - **Fresh context** -- each subagent gets an isolated 200K context
286
+ - **Waves are sequential** -- waves do not run in parallel, only tasks within a wave do
287
+
288
+ ## Algorithm (summary)
289
+
290
+ 1. Read plan.md
291
+ 2. Determine dependencies
292
+ 3. Group into waves (independent batches)
293
+ 4. Check file conflicts + Risk
294
+ 5. Update STATE.md (IN_PROGRESS)
295
+ 6. Launch subagents in parallel (max 5)
296
+ 7. Wait for all subagents (heartbeat monitoring)
297
+ 8. Run wave validation (tsc + vitest + eslint)
298
+ 9. If OK -> next wave
299
+ 10. If FAIL -> retry only failed tasks (max 2)
300
+ 11. If FAIL after 2 retries -> Wave Failure Strategy
301
+ 12. Repeat until all waves are complete
302
+ 13. Final validation + completeness check
303
+ 14. Update STATE.md + suggest Memory Updates
304
+
305
+ ## Result
306
+
307
+ - Tasks executed in parallel
308
+ - Waves separated by dependencies
309
+ - High-risk tasks isolated + git checkpoint
310
+ - Quality gates passed between waves
311
+ - `.planning/STATE.md` updated
312
+ - Patterns suggested for memory
@@ -0,0 +1,5 @@
1
+ # /frame:where -- Alias for /frame:daily
2
+
3
+ > This is an alias. Use `/frame:daily` instead — it does everything this command does, plus gives you a concrete next action.
4
+
5
+ Run `/frame:daily` to get your current position and next step.
@@ -0,0 +1,57 @@
1
+ # /frame:why -- Search Decision History
2
+
3
+ Find why a decision was made. Searches memory and git history.
4
+
5
+ ## Instructions
6
+
7
+ Search for: **$ARGUMENTS**
8
+
9
+ ### Step 1: Search memory files
10
+
11
+ ```bash
12
+ grep -i "$ARGUMENTS" .planning/memory/decisions.md 2>/dev/null
13
+ grep -i "$ARGUMENTS" .planning/memory/anti-patterns.md 2>/dev/null
14
+ grep -i "$ARGUMENTS" .planning/memory/patterns.md 2>/dev/null
15
+ ```
16
+
17
+ ### Step 2: Search git history
18
+
19
+ ```bash
20
+ git log --oneline --grep="$ARGUMENTS" | head -10
21
+ git log --oneline -S "$ARGUMENTS" | head -10
22
+ ```
23
+
24
+ ### Step 3: Search forensics reports
25
+
26
+ ```bash
27
+ grep -rl "$ARGUMENTS" .planning/forensics/ 2>/dev/null | head -5
28
+ ```
29
+
30
+ ### Step 4: Output results
31
+
32
+ Format findings:
33
+
34
+ ```
35
+ Search: "{keyword}"
36
+
37
+ DECISIONS:
38
+ [DEC-XXX] {title} — {date}
39
+ Context: {why it was needed}
40
+ Decision: {what was decided}
41
+
42
+ ANTI-PATTERNS:
43
+ {pattern name} — {why it's bad}
44
+
45
+ GIT HISTORY:
46
+ {hash} {commit message}
47
+
48
+ FORENSICS:
49
+ {report file} — {issue title}
50
+ ```
51
+
52
+ If nothing found: "No records found for '{keyword}'. Check spelling or try a broader term."
53
+
54
+ ## Rules
55
+
56
+ - Read-only — never modify files
57
+ - If $ARGUMENTS is empty: "Provide a keyword. Example: /frame:why auth"
@@ -0,0 +1,219 @@
1
+ # /frame:worktree -- Git Worktrees
2
+
3
+ Manage isolated git worktrees for parallel work.
4
+
5
+ ## Instructions
6
+
7
+ Command: **$ARGUMENTS**
8
+
9
+ ### Step 0: Fail-fast validation
10
+
11
+ Before routing, run these checks:
12
+
13
+ ```bash
14
+ git rev-parse --git-dir 2>/dev/null || echo "NOT_GIT"
15
+ ```
16
+
17
+ If output is `NOT_GIT` — STOP with error: "Error: not a git repository. Run this command from inside a git project."
18
+
19
+ For `create`: if `$NAME` is empty — STOP with error: "Error: name is required. Usage: /frame:worktree create <name>"
20
+
21
+ ### Routing
22
+
23
+ Determine action from the first argument:
24
+ - `create <name>` -- create a worktree
25
+ - `list` -- show all worktrees
26
+ - `switch <name>` -- switch to a worktree
27
+ - `cleanup <name>` -- remove a worktree
28
+
29
+ ---
30
+
31
+ ## Action: create
32
+
33
+ Create a git worktree with an isolated workspace.
34
+
35
+ Update STATE.md at the start:
36
+ ```markdown
37
+ ## Current Position
38
+ - Phase: WORKTREE
39
+ - Action: create
40
+ - Name: feature/{name}
41
+ - Status: IN_PROGRESS
42
+ - Started: {timestamp}
43
+ ```
44
+
45
+ ### Step 1: Validate Name
46
+
47
+ Name must follow git branch naming conventions:
48
+ ```bash
49
+ echo "$NAME" | grep -E '^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$'
50
+ ```
51
+
52
+ Check if worktree already exists:
53
+ ```bash
54
+ git worktree list | grep "feature/$NAME" && echo "EXISTS"
55
+ ```
56
+
57
+ If EXISTS — STOP with error: "Error: worktree feature/{name} already exists."
58
+
59
+ ### Step 2: Create Worktree
60
+
61
+ ```bash
62
+ git worktree add ../$(basename $(pwd))-$NAME -b feature/$NAME
63
+ ```
64
+
65
+ Say: "Worktree created, copying context..."
66
+
67
+ ### Step 3: Copy Context
68
+
69
+ Copy planning context into the new worktree:
70
+ ```bash
71
+ mkdir -p ../$(basename $(pwd))-$NAME/.planning
72
+ cp .planning/STATE.md ../$(basename $(pwd))-$NAME/.planning/
73
+ cp .planning/CONTEXT.md ../$(basename $(pwd))-$NAME/.planning/ 2>/dev/null || true
74
+ cp .planning/MAP.md ../$(basename $(pwd))-$NAME/.planning/ 2>/dev/null || true
75
+ ```
76
+
77
+ ### Step 4: Show Result
78
+
79
+ Update STATE.md:
80
+ ```markdown
81
+ ## Current Position
82
+ - Phase: WORKTREE
83
+ - Action: create
84
+ - Name: feature/{name}
85
+ - Status: COMPLETE
86
+ - Started: {timestamp}
87
+ ```
88
+
89
+ ```
90
+ +======================================================================+
91
+ | WORKTREE CREATED |
92
+ +======================================================================+
93
+ | Name: feature/{name} |
94
+ | Path: ../{project}-{name} |
95
+ | Branch: feature/{name} |
96
+ | |
97
+ | cd ../{project}-{name} to work in isolation |
98
+ +======================================================================+
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Action: list
104
+
105
+ Show all active worktrees.
106
+
107
+ ```bash
108
+ git worktree list
109
+ ```
110
+
111
+ ### Output
112
+
113
+ ```
114
+ +======================================================================+
115
+ | GIT WORKTREES |
116
+ +======================================================================+
117
+ | {path} [{branch}] |
118
+ | {path} [{branch}] |
119
+ +======================================================================+
120
+ ```
121
+
122
+ ---
123
+
124
+ ## Action: switch
125
+
126
+ Switch to another worktree.
127
+
128
+ Show the path and instructions:
129
+ ```bash
130
+ WORKTREE_PATH="../$(basename $(pwd))-$NAME"
131
+ if git worktree list | grep -q "feature/$NAME"; then
132
+ echo "WORKTREE_PATH=$WORKTREE_PATH"
133
+ else
134
+ echo "ERROR: worktree feature/$NAME not found"
135
+ git worktree list
136
+ fi
137
+ ```
138
+
139
+ Tell the user: "Open a new terminal and run: `cd $WORKTREE_PATH`"
140
+
141
+ Show current status of the worktree:
142
+ ```bash
143
+ git -C "../$(basename $(pwd))-$NAME" status 2>/dev/null
144
+ git -C "../$(basename $(pwd))-$NAME" branch --show-current 2>/dev/null
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Action: cleanup
150
+
151
+ Remove a worktree and branch.
152
+
153
+ Update STATE.md at the start:
154
+ ```markdown
155
+ ## Current Position
156
+ - Phase: WORKTREE
157
+ - Action: cleanup
158
+ - Name: feature/{name}
159
+ - Status: IN_PROGRESS
160
+ - Started: {timestamp}
161
+ ```
162
+
163
+ ### Step 1: Check Status
164
+
165
+ ```bash
166
+ cd ../{project}-{name}
167
+ git status --short
168
+ ```
169
+
170
+ If there are uncommitted changes, warn the user and request confirmation.
171
+
172
+ ### Step 2: Remove Worktree
173
+
174
+ ```bash
175
+ cd {project-root}
176
+ git worktree remove ../{project}-{name}
177
+ ```
178
+
179
+ ### Step 3: Remove Branch (optional)
180
+
181
+ ```bash
182
+ git branch -d feature/{name}
183
+ ```
184
+
185
+ ### Step 4: Show Result
186
+
187
+ Update STATE.md:
188
+ ```markdown
189
+ ## Current Position
190
+ - Phase: WORKTREE
191
+ - Action: cleanup
192
+ - Name: feature/{name}
193
+ - Status: COMPLETE
194
+ - Started: {timestamp}
195
+ ```
196
+
197
+ ```
198
+ +======================================================================+
199
+ | WORKTREE REMOVED |
200
+ +======================================================================+
201
+ | Name: feature/{name} |
202
+ | Path: removed |
203
+ | Branch: {deleted or kept} |
204
+ +======================================================================+
205
+ ```
206
+
207
+ ## Rules
208
+
209
+ - **WorktreeBase**: `../` -- sibling directories
210
+ - **Branch naming**: `feature/{name}`
211
+ - **Context copy**: STATE.md, CONTEXT.md, MAP.md
212
+ - **Cleanup**: check for uncommitted changes before removal
213
+ - **Never force** -- warn about potential work loss
214
+
215
+ ## Result
216
+
217
+ - Git worktree created/removed
218
+ - Branch created/removed
219
+ - Context copied
@@ -0,0 +1,33 @@
1
+ #!/bin/bash
2
+ # git-safety.sh - Blocks dangerous git commands
3
+
4
+ read -r input
5
+
6
+ COMMAND=$(node -e "try{const i=JSON.parse(process.argv[1]);process.stdout.write(i.tool_input?.command??'')}catch{}" -- "$input" 2>/dev/null)
7
+
8
+ deny() {
9
+ node -e "process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'PreToolUse',permissionDecision:'deny',permissionDecisionReason:process.argv[1]}}))" -- "$1"
10
+ exit 0
11
+ }
12
+
13
+ ask() {
14
+ node -e "process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'PreToolUse',permissionDecision:'ask',permissionDecisionReason:process.argv[1]}}))" -- "$1"
15
+ exit 0
16
+ }
17
+
18
+ if echo "$COMMAND" | grep -qiE 'git\s+push.*(--force|-f)' && ! echo "$COMMAND" | grep -q 'force-with-lease'; then
19
+ deny "FRAME Git Safety: Force push blocked. Use regular push. If you must force push, do it manually."
20
+ fi
21
+
22
+ if echo "$COMMAND" | grep -qiE 'git\s+reset\s+--hard'; then
23
+ if [ "${FRAME_INTERNAL}" = "1" ]; then
24
+ exit 0
25
+ fi
26
+ deny "FRAME Git Safety: git reset --hard blocked. Use git restore or git stash instead."
27
+ fi
28
+
29
+ if echo "$COMMAND" | grep -qiE 'git\s+add\s+(-A|\.)'; then
30
+ ask "FRAME Git Safety: FRAME recommends using specific files instead of git add -A. Are you sure you want to add all files?"
31
+ fi
32
+
33
+ exit 0
@@ -0,0 +1,52 @@
1
+ #!/bin/bash
2
+ # quality-gate.sh - Runs typecheck and lint after file changes
3
+
4
+ FILE_PATH=$(node -e "try{const i=JSON.parse(process.env.CLAUDE_TOOL_INPUT||'{}');process.stdout.write(i.file_path||i.path||'')}catch{}" 2>/dev/null)
5
+
6
+ if [ -z "$FILE_PATH" ]; then
7
+ exit 0
8
+ fi
9
+
10
+ # Read quality commands from config if available
11
+ TYPECHECK_CMD=""
12
+ LINT_CMD=""
13
+ if [ -f ".frame/config.json" ] && command -v node &>/dev/null; then
14
+ CONFIG_VALID=$(node -e "try{JSON.parse(require('fs').readFileSync('.frame/config.json','utf8'));process.stdout.write('ok')}catch(e){process.stdout.write('invalid: '+e.message)}" 2>/dev/null)
15
+ if [ "$CONFIG_VALID" != "ok" ]; then
16
+ echo "FRAME Quality Gate: .frame/config.json is malformed — $CONFIG_VALID"
17
+ echo "Fix it or run /frame:doctor to diagnose."
18
+ exit 0
19
+ fi
20
+ TYPECHECK_CMD=$(node -e "try{const c=JSON.parse(require('fs').readFileSync('.frame/config.json','utf8'));process.stdout.write(c.quality?.commands?.typecheck||'')}catch{}" 2>/dev/null)
21
+ LINT_CMD=$(node -e "try{const c=JSON.parse(require('fs').readFileSync('.frame/config.json','utf8'));process.stdout.write(c.quality?.commands?.lint||'')}catch{}" 2>/dev/null)
22
+ fi
23
+
24
+ # Fallback: TypeScript-only detection
25
+ if [ -z "$TYPECHECK_CMD" ] && echo "$FILE_PATH" | grep -qiE '\.(ts|tsx)$'; then
26
+ TYPECHECK_CMD="npx tsc --noEmit"
27
+ LINT_CMD="npx eslint --fix \"$FILE_PATH\""
28
+ fi
29
+
30
+ run_cmd() {
31
+ local cmd="$1"
32
+ # Only allow commands starting with known safe prefixes
33
+ if ! echo "$cmd" | grep -qE '^(npx |npm run |yarn |pnpm |node |tsc |eslint |biome |deno )'; then
34
+ echo "FRAME Quality Gate: command not in allowlist, skipping: $cmd"
35
+ return 0
36
+ fi
37
+ sh -c "$cmd" 2>/dev/null
38
+ }
39
+
40
+ if [ -n "$TYPECHECK_CMD" ]; then
41
+ if ! run_cmd "$TYPECHECK_CMD"; then
42
+ echo "FRAME Quality Gate: typecheck failed for $FILE_PATH"
43
+ fi
44
+ fi
45
+
46
+ if [ -n "$LINT_CMD" ]; then
47
+ if ! run_cmd "$LINT_CMD"; then
48
+ echo "FRAME Quality Gate: lint issues in $FILE_PATH"
49
+ fi
50
+ fi
51
+
52
+ exit 0
@@ -0,0 +1,13 @@
1
+ #!/bin/bash
2
+ # safety-net.sh - Blocks dangerous bash commands
3
+
4
+ read -r input
5
+
6
+ COMMAND=$(node -e "try{const i=JSON.parse(process.argv[1]);process.stdout.write(i.tool_input?.command??'')}catch{}" -- "$input" 2>/dev/null)
7
+
8
+ if echo "$COMMAND" | grep -qiE 'rm\s+-[a-zA-Z]*r[a-zA-Z]*f|rm\s+--recursive.*--force|rm\s+--force.*--recursive|\bDROP\s+(TABLE|DATABASE)\b'; then
9
+ node -e "process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'PreToolUse',permissionDecision:'deny',permissionDecisionReason:'FRAME Safety Net: Destructive command blocked (rm -rf or DROP TABLE/DATABASE). Use specific, safer alternatives.'}}))"
10
+ exit 0
11
+ fi
12
+
13
+ exit 0