@hopla/claude-setup 1.14.1 → 1.16.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.
@@ -0,0 +1,41 @@
1
+ {
2
+ "_comment": "Copy this file to your project root as .mcp.json and uncomment the servers you want Claude Code to use. Each server is standalone — enable only what you need. Set the required env vars in your shell or .envrc (NOT committed). Restart Claude Code after editing.",
3
+
4
+ "mcpServers": {
5
+ "_playwright_example": {
6
+ "_note": "Browser automation for E2E testing and UI inspection. No credentials needed.",
7
+ "command": "npx",
8
+ "args": ["-y", "@playwright/mcp"]
9
+ },
10
+
11
+ "_github_example": {
12
+ "_note": "GitHub API access for reading repos, issues, PRs. Requires a token with the scopes you need.",
13
+ "command": "npx",
14
+ "args": ["-y", "@modelcontextprotocol/server-github"],
15
+ "env": {
16
+ "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_PERSONAL_ACCESS_TOKEN}"
17
+ }
18
+ },
19
+
20
+ "_linear_example": {
21
+ "_note": "Linear workspace access (issues, projects, cycles). Get an API key at linear.app/settings/api.",
22
+ "command": "npx",
23
+ "args": ["-y", "@tacticlaunch/mcp-linear"],
24
+ "env": {
25
+ "LINEAR_API_KEY": "${LINEAR_API_KEY}"
26
+ }
27
+ },
28
+
29
+ "_postgres_example": {
30
+ "_note": "Read-only Postgres access for database introspection and ad-hoc queries.",
31
+ "command": "npx",
32
+ "args": ["-y", "@modelcontextprotocol/server-postgres", "${DATABASE_URL}"]
33
+ },
34
+
35
+ "_filesystem_example": {
36
+ "_note": "Constrained filesystem access outside the current workspace (e.g. to inspect ~/Documents/specs).",
37
+ "command": "npx",
38
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/ABSOLUTE/PATH/TO/ALLOWED/DIR"]
39
+ }
40
+ }
41
+ }
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "hopla",
11
11
  "description": "Agentic coding system: PIV loop, TDD, debugging, brainstorming, subagent execution, and team workflows",
12
- "version": "1.14.1",
12
+ "version": "1.16.0",
13
13
  "source": "./",
14
14
  "author": {
15
15
  "name": "Hopla Tools",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hopla",
3
3
  "description": "Agentic coding system for Claude Code: PIV loop (Plan → Implement → Validate), TDD, debugging, brainstorming, subagent execution, and team workflows",
4
- "version": "1.14.1",
4
+ "version": "1.16.0",
5
5
  "author": {
6
6
  "name": "Hopla Tools",
7
7
  "email": "julio@hopla.tools"
package/README.md CHANGED
@@ -101,10 +101,32 @@ Removes `~/.claude/CLAUDE.md` plus legacy `hopla-*` files from older installs.
101
101
  | `claude-setup --force` | Install without prompts |
102
102
  | `claude-setup --migrate` | Remove legacy CLI-installed duplicates only |
103
103
  | `claude-setup --uninstall` | Remove global rules + legacy files |
104
+ | `claude-setup --dry-run` | Preview changes without touching disk (composes with other flags) |
104
105
  | `claude-setup --version` | Print package version |
105
106
 
106
107
  ---
107
108
 
109
+ ## Optional: Hopla statusline
110
+
111
+ The plugin ships a statusline script that shows your branch, worktree indicator, uncommitted count, and active plan file (`📋 plan-name`) in Claude Code's status bar.
112
+
113
+ Enable it by adding to `~/.claude/settings.json`:
114
+
115
+ ```json
116
+ {
117
+ "statusLine": {
118
+ "type": "command",
119
+ "command": "node ~/.claude/plugins/marketplaces/hopla-marketplace/hooks/statusline.js"
120
+ }
121
+ }
122
+ ```
123
+
124
+ Then run `/reload-plugins` or restart Claude Code.
125
+
126
+ Sample output: ` feature/auth · 3M · 📋 add-authentication`
127
+
128
+ ---
129
+
108
130
  ## Naming Convention
109
131
 
110
132
  Skills and commands use short names in source (e.g., `prime`, `execute`, `git`). The plugin namespaces them automatically:
package/cli.js CHANGED
@@ -87,6 +87,21 @@ function logRemoved(label) {
87
87
  log(` ${RED}✕${RESET} ${verb}: ${label}`);
88
88
  }
89
89
 
90
+ // Safe parser for settings.json-style files. Returns null when the file is
91
+ // missing. Warns (and returns null) when the file exists but is not valid JSON
92
+ // — previously these failures were silently swallowed, causing cleanup and
93
+ // permission updates to skip with no signal to the user.
94
+ function parseSettingsFile(settingsPath) {
95
+ if (!fs.existsSync(settingsPath)) return null;
96
+ try {
97
+ return JSON.parse(fs.readFileSync(settingsPath, "utf8"));
98
+ } catch (err) {
99
+ log(` ${YELLOW}⚠${RESET} Could not parse ${settingsPath}: ${err.message}`);
100
+ log(` Skipping this file. Fix the JSON and re-run to apply changes.`);
101
+ return null;
102
+ }
103
+ }
104
+
90
105
  function logInstalled(label, exists) {
91
106
  const verb = DRY_RUN
92
107
  ? (exists ? "Would update" : "Would install")
@@ -220,35 +235,34 @@ function removeLegacyFiles() {
220
235
 
221
236
  // hopla hook entries from settings.json AND settings.local.json
222
237
  for (const settingsPath of SETTINGS_FILES) {
223
- if (!fs.existsSync(settingsPath)) continue;
224
- try {
225
- const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
226
- let changed = false;
227
-
228
- if (settings.hooks) {
229
- for (const [event, matchers] of Object.entries(settings.hooks)) {
230
- if (!Array.isArray(matchers)) continue;
231
- const filtered = matchers.filter((m) => {
232
- if (!m.hooks || !Array.isArray(m.hooks)) return true;
233
- const isHopla = m.hooks.every((h) =>
234
- LEGACY_HOOK_COMMANDS.some((cmd) => h.command && h.command.includes(cmd))
235
- );
236
- return !isHopla;
237
- });
238
- if (filtered.length !== matchers.length) {
239
- settings.hooks[event] = filtered;
240
- if (filtered.length === 0) delete settings.hooks[event];
241
- changed = true;
242
- }
238
+ const settings = parseSettingsFile(settingsPath);
239
+ if (!settings) continue;
240
+
241
+ let changed = false;
242
+
243
+ if (settings.hooks) {
244
+ for (const [event, matchers] of Object.entries(settings.hooks)) {
245
+ if (!Array.isArray(matchers)) continue;
246
+ const filtered = matchers.filter((m) => {
247
+ if (!m.hooks || !Array.isArray(m.hooks)) return true;
248
+ const isHopla = m.hooks.every((h) =>
249
+ LEGACY_HOOK_COMMANDS.some((cmd) => h.command && h.command.includes(cmd))
250
+ );
251
+ return !isHopla;
252
+ });
253
+ if (filtered.length !== matchers.length) {
254
+ settings.hooks[event] = filtered;
255
+ if (filtered.length === 0) delete settings.hooks[event];
256
+ changed = true;
243
257
  }
244
- if (Object.keys(settings.hooks).length === 0) delete settings.hooks;
245
258
  }
259
+ if (Object.keys(settings.hooks).length === 0) delete settings.hooks;
260
+ }
246
261
 
247
- if (changed) {
248
- safeWrite(settingsPath, JSON.stringify(settings, null, 2) + "\n");
249
- removed.push(`hooks from ${path.basename(settingsPath)}`);
250
- }
251
- } catch { /* ignore parse errors */ }
262
+ if (changed) {
263
+ safeWrite(settingsPath, JSON.stringify(settings, null, 2) + "\n");
264
+ removed.push(`hooks from ${path.basename(settingsPath)}`);
265
+ }
252
266
  }
253
267
 
254
268
  return removed;
@@ -257,31 +271,27 @@ function removeLegacyFiles() {
257
271
  function removeHoplaPermissions() {
258
272
  const removed = [];
259
273
  for (const settingsPath of SETTINGS_FILES) {
260
- if (!fs.existsSync(settingsPath)) continue;
261
- try {
262
- const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
263
- if (!settings.permissions || !Array.isArray(settings.permissions.allow)) continue;
264
- const before = settings.permissions.allow.length;
265
- settings.permissions.allow = settings.permissions.allow.filter(
266
- (p) => !ALL_HOPLA_PERMISSIONS.has(p)
267
- );
268
- if (settings.permissions.allow.length !== before) {
269
- safeWrite(settingsPath, JSON.stringify(settings, null, 2) + "\n");
270
- removed.push(`permissions from ${path.basename(settingsPath)}`);
271
- }
272
- } catch { /* ignore */ }
274
+ const settings = parseSettingsFile(settingsPath);
275
+ if (!settings) continue;
276
+ if (!settings.permissions || !Array.isArray(settings.permissions.allow)) continue;
277
+ const before = settings.permissions.allow.length;
278
+ settings.permissions.allow = settings.permissions.allow.filter(
279
+ (p) => !ALL_HOPLA_PERMISSIONS.has(p)
280
+ );
281
+ if (settings.permissions.allow.length !== before) {
282
+ safeWrite(settingsPath, JSON.stringify(settings, null, 2) + "\n");
283
+ removed.push(`permissions from ${path.basename(settingsPath)}`);
284
+ }
273
285
  }
274
286
  return removed;
275
287
  }
276
288
 
277
289
  function detectPlugin() {
278
290
  for (const settingsPath of SETTINGS_FILES) {
279
- if (!fs.existsSync(settingsPath)) continue;
280
- try {
281
- const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
282
- const plugins = settings.enabledPlugins || {};
283
- if (Object.keys(plugins).some((key) => key.startsWith("hopla@"))) return true;
284
- } catch { /* ignore */ }
291
+ const settings = parseSettingsFile(settingsPath);
292
+ if (!settings) continue;
293
+ const plugins = settings.enabledPlugins || {};
294
+ if (Object.keys(plugins).some((key) => key.startsWith("hopla@"))) return true;
285
295
  }
286
296
  return false;
287
297
  }
@@ -373,11 +383,16 @@ async function uninstall() {
373
383
  async function setupPermissions() {
374
384
  const settingsPath = path.join(CLAUDE_DIR, "settings.json");
375
385
 
376
- let settings = { permissions: { allow: [] } };
377
- if (fs.existsSync(settingsPath)) {
378
- try {
379
- settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
380
- } catch { /* keep defaults */ }
386
+ // Use parseSettingsFile so malformed JSON is reported instead of silently
387
+ // overwritten. When the file is missing we start from defaults.
388
+ let settings = parseSettingsFile(settingsPath);
389
+ if (!settings) {
390
+ if (fs.existsSync(settingsPath)) {
391
+ // Malformed JSON — do NOT overwrite (user needs to fix first)
392
+ log(` ${YELLOW}↷${RESET} Skipped permissions setup — settings.json is not valid JSON.`);
393
+ return;
394
+ }
395
+ settings = { permissions: { allow: [] } };
381
396
  }
382
397
  if (!settings.permissions) settings.permissions = {};
383
398
  if (!settings.permissions.allow) settings.permissions.allow = [];
@@ -98,7 +98,7 @@ Work through each task in the plan sequentially. For each task:
98
98
 
99
99
  1. **Announce** the task you are starting (e.g., "Starting Task 2: Create the filter component")
100
100
  2. **Follow the pattern** referenced in the plan — do not invent new patterns
101
- 3. **Check for existing implementations** — before creating new functions, constants, or utility modules, search the codebase for existing implementations that serve the same purpose. Reuse or extend rather than duplicate. DRY violations were the #1 code quality issue across 28 implementations.
101
+ 3. **Check for existing implementations** — before creating new functions, constants, or utility modules, search the codebase for existing implementations that serve the same purpose. Reuse or extend rather than duplicate.
102
102
  4. **Implement** only what the task specifies — nothing more
103
103
  5. **Validate** the task using the method specified in the plan's validate field
104
104
  6. **Report completion** with a brief status: what was done, what was skipped, any decision made
@@ -137,54 +137,15 @@ If the user requests changes that are NOT in the plan during execution:
137
137
  - Suggest committing the current planned work first
138
138
  - Then create a new branch or add it to the backlog
139
139
  - Say: "This looks like a separate feature. I recommend we commit the current work first, then handle this in a new branch. Should I add it to `.agents/plans/backlog/` instead?"
140
- 5. **Never** silently add significant unplanned work — scope creep caused the lowest alignment score (6/10) in past implementations
140
+ 5. **Never** silently add significant unplanned work — it mixes unreviewed changes into an otherwise reviewed plan and breaks the audit trail
141
141
 
142
142
  ## Step 5: Run Full Validation Pyramid
143
143
 
144
- After all tasks are complete, run the full validation sequence in order.
145
- **Do not skip levels. Do not proceed if a level fails.**
144
+ After all tasks are complete, run **Levels 1–7** from `commands/guides/validation-pyramid.md` (same repo). Do not skip levels. Do not proceed if a level fails.
146
145
 
147
- Use the exact commands from the plan's **Validation Checklist**. If not specified, read `CLAUDE.md` section "Development Commands" to find the correct commands.
146
+ Use the exact commands from the plan's **Validation Checklist**. If not specified, read `CLAUDE.md` "Development Commands" to find the correct commands.
148
147
 
149
- ### Level 1 Lint & Format
150
- Run the project's lint and format check (e.g. `npm run lint`, `uv run ruff check .`).
151
- Fix any issues before continuing.
152
-
153
- ### Level 2 — Type Check
154
- Run the project's type checker (e.g. `npm run type-check`, `uv run mypy .`).
155
- Fix all type errors before continuing.
156
-
157
- ### Level 3 — Unit Tests
158
- Run the project's unit test suite (e.g. `npm run test`, `uv run pytest`).
159
- If tests fail:
160
- - Investigate the root cause
161
- - Fix the code (not the tests)
162
- - Re-run until all pass
163
-
164
- ### Level 4 — Integration Tests
165
- Run integration tests or manual verification as specified in the plan (e.g. `npm run test:e2e`, manual curl).
166
- Verify the feature works end-to-end.
167
-
168
- ### Level 5 — Code Review
169
- Run a code review on all changed files following the the `code-review` skill process. This catches bugs that linting, types, and tests miss (security issues, logic errors, pattern violations).
170
-
171
- If the review finds critical or high severity issues, **fix them before proceeding**.
172
-
173
- ### Level 6 — File Drift Check
174
- Compare the files actually changed against the plan's task list:
175
-
176
- ```bash
177
- git diff --name-only
178
- git ls-files --others --exclude-standard
179
- ```
180
-
181
- Flag any files that were changed but are **not listed in any task**. These are potential scope leaks — unplanned additions that didn't get the same scrutiny as planned tasks. Report them in the completion summary so the user can review.
182
-
183
- ### Level 7 — Human Review (flag for user)
184
- List what the user should manually verify:
185
- - Specific behaviors to test in the browser or CLI
186
- - Edge cases to check
187
- - Any decisions made during implementation that the user should review
148
+ Level 5 triggers the `code-review` skill (not a slash command). Level 6 is the file-drift check specific to plan execution. Level 7 surfaces items for human verification.
188
149
 
189
150
  ## Step 6: Completion Report
190
151
 
@@ -0,0 +1,74 @@
1
+ # Validation Pyramid
2
+
3
+ Shared reference for the full validation sequence. Callers (`commands/execute.md`, `commands/validate.md`, `skills/verify/SKILL.md`, plus plans' `Validation Checklist`) pick the levels that apply to their scope.
4
+
5
+ Run levels **in order**. Do not skip a level. Do not proceed if a level fails — fix it first.
6
+
7
+ Commands below are generic examples; use the exact commands from the project's `CLAUDE.md` "Development Commands" section or the plan's checklist.
8
+
9
+ ## Level 1 — Lint & Format
10
+
11
+ Run the project's lint and format commands (e.g. `npm run lint`, `uv run ruff check .`).
12
+
13
+ If issues are found:
14
+
15
+ - Fix them automatically where the tool supports it (e.g. `--fix`)
16
+ - Re-run to confirm clean
17
+
18
+ ## Level 2 — Type Check
19
+
20
+ Run the project's type checker (e.g. `npm run typecheck`, `tsc --noEmit`, `uv run mypy .`).
21
+
22
+ Fix all type errors before continuing.
23
+
24
+ ## Level 3 — Unit Tests
25
+
26
+ Run the project's unit test suite (e.g. `npm run test`, `uv run pytest`).
27
+
28
+ If tests fail:
29
+
30
+ - Investigate the root cause
31
+ - Fix the code (not the tests, unless the test is wrong)
32
+ - Re-run until all pass
33
+
34
+ ## Level 4 — Integration Tests
35
+
36
+ Run integration tests if the project has them (e.g. `npm run test:e2e`, manual curl).
37
+
38
+ If not available, skip and note it in the report.
39
+
40
+ ## Level 5 — Code Review
41
+
42
+ Trigger the `code-review` skill on the changed files. This catches bugs that lint, types, and tests miss (security issues, logic errors, pattern violations).
43
+
44
+ If the review finds `critical` or `high` severity issues, **fix them before proceeding**.
45
+
46
+ ## Level 6 — File Drift Check (post-execution only)
47
+
48
+ Compare the files actually changed against the plan's task list:
49
+
50
+ ```bash
51
+ git diff --name-only
52
+ git ls-files --others --exclude-standard
53
+ ```
54
+
55
+ Flag any files that were changed but are **not listed in any task**. These are potential scope leaks — report them in the completion summary so the user can review.
56
+
57
+ Skip this level when validating outside of a plan (`/hopla:validate` or the `verify` skill without a plan).
58
+
59
+ ## Level 7 — Human Review
60
+
61
+ Flag for the user what they should verify manually:
62
+
63
+ - Specific behaviors to test in the browser or CLI
64
+ - Edge cases to check
65
+ - Any decisions made during implementation that the user should review
66
+
67
+ ## Which levels apply when
68
+
69
+ | Caller | Levels |
70
+ |---|---|
71
+ | `/hopla:validate` | 1–4 |
72
+ | `verify` skill | 1–4 + 7 |
73
+ | `/hopla:execute` | 1–7 |
74
+ | Plan's `Validation Checklist` | as specified by the plan, typically 1–5 or 1–7 |
@@ -47,7 +47,7 @@ Investigate the areas of the codebase relevant to this feature:
47
47
  - Locate similar features already implemented to use as reference
48
48
  - Find the entry points that will need to be modified or extended
49
49
  - Identify potential conflicts or dependencies
50
- - **DRY check:** Before specifying new utility functions, constants, or helpers in the plan, search for existing implementations that can be reused or extended. DRY violations were the #1 code review finding across 28 implementations.
50
+ - **DRY check:** Before specifying new utility functions, constants, or helpers in the plan, search for existing implementations that can be reused or extended.
51
51
 
52
52
  Use the Grep tool to find relevant files (pattern: relevant keyword, case-insensitive).
53
53
 
@@ -60,7 +60,7 @@ For each existing table, API endpoint, or component the plan will modify, verify
60
60
  - **API endpoints:** Read the actual route handler. Confirm the request/response shape matches your assumptions.
61
61
  - **Components:** Read the component file. Confirm props, state, and data flow match your assumptions.
62
62
 
63
- Document verified assumptions in the plan's **Context References** with the exact file and line number. This prevents the #1 cause of mid-implementation redesigns: plans that assumed a field name, type, or constraint that didn't match reality.
63
+ Document verified assumptions in the plan's **Context References** with the exact file and line number. This prevents mid-implementation redesigns caused by plans that assumed a field name, type, or constraint that did not match reality.
64
64
 
65
65
  ### Data audit (required for features that consume existing data)
66
66
 
@@ -79,17 +79,17 @@ Based on research, define:
79
79
  - Any risks, edge cases, or gotchas to flag
80
80
  - What tests are needed
81
81
  - **Derived/computed values:** If any value is calculated from other fields, specify the exact formula including how stored values are interpreted (sign, units, semantics), AND how derived values propagate when inputs change (event system, reactivity, polling, etc.)
82
- - **Interaction states & edge cases:** For features involving interactive UI (forms, grids, keyboard navigation, wizards, CLI interactions), define a matrix of user interactions and their expected behavior. Cover: all keyboard shortcuts (both directions — e.g., Tab AND Shift+Tab), state transitions (empty → editing → saved → error), and boundary conditions (first item, last item, empty list, maximum items). This prevents iterative fix rounds that consumed up to 40% of session time in past implementations.
83
- - **API input validation:** For every API endpoint being created or modified, specify: required fields, field format constraints (e.g., "IMEI must be exactly 15 digits"), payload size limits, and what the user sees on validation failure. This was the #2 most common gap in past plans — validation was only added after code review in 4 of 7 implementations.
84
- - **Bidirectional data interactions:** If feature A updates data that feature B displays, does B need to react? If adding an item triggers validation, does editing trigger re-validation? Map all data mutation → side effect chains, not just keyboard navigation. Missed bidirectional interactions were a recurring planning blind spot.
82
+ - **Interaction states & edge cases:** For features involving interactive UI (forms, grids, keyboard navigation, wizards, CLI interactions), define a matrix of user interactions and their expected behavior. Cover: all keyboard shortcuts (both directions — e.g., Tab AND Shift+Tab), state transitions (empty → editing → saved → error), and boundary conditions (first item, last item, empty list, maximum items).
83
+ - **API input validation:** For every API endpoint being created or modified, specify: required fields, field format constraints (e.g., "IMEI must be exactly 15 digits"), payload size limits, and what the user sees on validation failure.
84
+ - **Bidirectional data interactions:** If feature A updates data that feature B displays, does B need to react? If adding an item triggers validation, does editing trigger re-validation? Map all data mutation → side effect chains, not just keyboard navigation.
85
85
  - **AI/LLM prompt tasks:** If the plan involves creating or modifying AI prompts (system prompts, prompt templates, LLM-based features), add an explicit task for testing against real data with 2-3 iteration cycles budgeted. AI prompt engineering rarely works on the first attempt.
86
- - **User preferences check:** Before specifying UI architecture (modal vs. inline, page vs. panel, dialog vs. drawer), verify against MEMORY.md and conversation history for established preferences. In past implementations, plans that specified modals were rejected because the user preferred inline panels — this caused rework. When no preference exists, note it as a decision point for the user to confirm.
87
- - **Reuse context analysis:** When a new view reuses an existing component in a different context (e.g., a list component in a "history" view vs. an "active" view), the plan MUST list what's different about the new context's requirements: different columns, different data filters, different interactions, different toolbar layout. Missed context differences caused 40%+ of unplanned work in past implementations.
86
+ - **User preferences check:** Before specifying UI architecture (modal vs. inline, page vs. panel, dialog vs. drawer), verify against `MEMORY.md` and conversation history for established preferences. When no preference exists, note it as a decision point for the user to confirm.
87
+ - **Reuse context analysis:** When a new view reuses an existing component in a different context (e.g., a list component in a "history" view vs. an "active" view), the plan MUST list what's different about the new context's requirements: different columns, different data filters, different interactions, different toolbar layout.
88
88
  - **Multi-phase plan guidance:** For features requiring 3+ phases, create an architectural plan (`backlog/NN-feature.md`) with schema, phase boundaries, and target architecture. When executing each phase, create a standalone plan (`phase-NX-description.md`) with full task-level detail following this template. The architectural plan is the spec; phase plans are the execution instructions. Each phase should have its own feature branch and PR.
89
- - **API surface enumeration (security/access control plans):** When the plan modifies access control, authorization, or data visibility, enumerate ALL API surfaces that serve the same data — REST endpoints, WebSocket handlers, Durable Object methods, and any other data paths. Each surface must be updated consistently. In past implementations, updating only the WebSocket path while missing the parallel REST endpoint caused a security gap that was only caught by code review. Add a task for each surface, not just the primary one.
90
- - **Role access matrix:** For features involving multiple user roles or multi-tenant access (admin, member, viewer, buyer, external user), define a matrix: what data does each role see? What endpoints does each role call? What filters apply per role? In past implementations, plans that didn't specify role-level access had authorization bugs discovered only during code review.
91
- - **External integration buffer:** If the feature integrates an external API or third-party service, budget 2x the estimated time. Document: do we have working test credentials? Is the SDK tested in our runtime (Workers, Node, edge, etc.)? Are there known deprecations or version constraints? External integrations consistently took 2-3x longer than planned in past implementations.
92
- - **UI iteration budget:** For features with significant UI (new pages, complex forms, interactive grids), note that UI specifications are provisional — expect 30-50% additional work for visual refinement based on user feedback. Specify what "good enough for v1" looks like vs. future polish. This prevents scope creep from being classified as plan failure.
89
+ - **API surface enumeration (security/access control plans):** When the plan modifies access control, authorization, or data visibility, enumerate ALL API surfaces that serve the same data — REST endpoints, WebSocket handlers, Durable Object methods, and any other data paths. Each surface must be updated consistently. Add a task for each surface, not just the primary one.
90
+ - **Role access matrix:** For features involving multiple user roles or multi-tenant access (admin, member, viewer, buyer, external user), define a matrix: what data does each role see? What endpoints does each role call? What filters apply per role?
91
+ - **External integration buffer:** If the feature integrates an external API or third-party service, budget 2x the estimated time. Document: do we have working test credentials? Is the SDK tested in our runtime (Workers, Node, edge, etc.)? Are there known deprecations or version constraints?
92
+ - **UI iteration budget:** For features with significant UI (new pages, complex forms, interactive grids), note that UI specifications are provisional — visual polish typically needs iteration on user feedback. Specify what "good enough for v1" looks like vs. future polish so scope creep is not classified as plan failure.
93
93
 
94
94
  ## Phase 5: Generate the Plan
95
95
 
@@ -112,7 +112,7 @@ Use this structure:
112
112
  - [Anything explicitly excluded]
113
113
 
114
114
  ## Likely Follow-ups
115
- [Features or changes naturally adjacent to this work that the user may request during or after execution. Historical data: 71% of sessions had scope expansion. Listing these upfront helps the executing agent handle them via the Scope Guard rather than improvising.]
115
+ [Features or changes naturally adjacent to this work that the user may request during or after execution. Listing these upfront helps the executing agent handle scope expansion via the Scope Guard rather than improvising.]
116
116
  - [Follow-up 1]
117
117
  - [Follow-up 2]
118
118
 
@@ -195,7 +195,7 @@ Scoring guide:
195
195
  ## Notes for Executing Agent
196
196
  [Any important context, warnings, or decisions made during planning that the executing agent needs to know]
197
197
 
198
- > **UI Styling Note:** UI styling specifications (colors, sizes, variants, labels, spacing) are `[provisional]` proposals. Historical data shows these change in 50%+ of implementations based on user feedback. Implement as specified but do not over-invest in pixel-perfect adherence expect iteration.
198
+ > **UI Styling Note:** UI styling specifications (colors, sizes, variants, labels, spacing) are `[provisional]` proposals expect them to change once the user sees the implementation. Implement as specified but do not over-invest in pixel-perfect adherence; plan for iteration.
199
199
  ```
200
200
 
201
201
  ---
@@ -206,7 +206,7 @@ After generating the plan, count the implementation tasks (excluding test tasks)
206
206
 
207
207
  - **3–7 tasks:** Optimal size. Proceed as-is.
208
208
  - **8–11 tasks:** Consider grouping tasks into logical phases with intermediate commit points. Add a `## Phase Boundaries` section to the plan listing where commits should happen.
209
- - **12+ tasks:** The plan should be split into multiple plans or phased with mandatory intermediate commits. Historical data: plans with 12+ tasks scored 6/10 alignment vs 10/10 for 3–7 task plans. Add phase boundaries and consider whether independent task groups can be separate plans.
209
+ - **12+ tasks:** The plan should be split into multiple plans or phased with mandatory intermediate commits. Large plans tend to drift during execution; phase boundaries give reviewers and the executing agent natural checkpoints. Consider whether independent task groups can be separate plans.
210
210
 
211
211
  ---
212
212
 
@@ -231,7 +231,7 @@ Before saving the draft, review the plan against these criteria:
231
231
  - [ ] **Plan size checked:** If >8 tasks, phase boundaries are defined with intermediate commit points. If >12 tasks, split justification is provided or phases are created.
232
232
  - [ ] **Likely follow-ups listed:** If the Out of Scope section has items, the Likely Follow-ups section is populated with naturally adjacent work the user may request
233
233
  - [ ] **API surface enumeration (if security/access plan):** All parallel API surfaces (REST, WebSocket, DO) that serve the same data are listed with a task for each
234
- - [ ] **N+1 query check:** For every task that writes database queries or API calls, verify: is any call inside a loop? Could it be batched? Are there duplicate existence checks before mutations? N+1 queries were found in 5 of 13 recent implementations.
234
+ - [ ] **N+1 query check:** For every task that writes database queries or API calls, verify: is any call inside a loop? Could it be batched? Are there duplicate existence checks before mutations?
235
235
 
236
236
  ## Phase 7: Save Draft and Enter Review Loop
237
237
 
@@ -14,36 +14,9 @@ If a `.claude/commands/validate.md` exists at the project root, use the commands
14
14
 
15
15
  ## Step 2: Run the Validation Pyramid
16
16
 
17
- Execute each level in order. **Do not skip levels. Do not proceed if a level fails — fix it first.**
17
+ Execute levels **1–4** from `commands/guides/validation-pyramid.md` (same repo). Do not skip levels. Do not proceed if a level fails — fix it first.
18
18
 
19
- ### Level 1 Lint & Format
20
-
21
- Run the project's lint and format commands (e.g. `npm run lint`, `uv run ruff check .`).
22
-
23
- If issues are found:
24
- - Fix them automatically if the tool supports it (e.g. `--fix`)
25
- - Re-run to confirm clean
26
-
27
- ### Level 2 — Type Check
28
-
29
- Run the project's type checker (e.g. `npm run typecheck`, `uv run mypy .`).
30
-
31
- Fix all type errors before continuing.
32
-
33
- ### Level 3 — Unit Tests
34
-
35
- Run the project's test suite (e.g. `npm run test`, `uv run pytest`).
36
-
37
- If tests fail:
38
- - Investigate the root cause
39
- - Fix the code (not the tests, unless the test is wrong)
40
- - Re-run until all pass
41
-
42
- ### Level 4 — Integration Tests
43
-
44
- Run integration tests if the project has them (e.g. `npm run test:e2e`).
45
-
46
- If not available, skip and note it in the report.
19
+ Use the exact commands from the project's `CLAUDE.md` "Development Commands" section. If a `.claude/commands/validate.md` exists at the project root, use the commands defined there instead.
47
20
 
48
21
  ## Step 3: Summary Report
49
22
 
@@ -72,4 +45,4 @@ If anything failed and could not be fixed, list the remaining issues and suggest
72
45
  ## Next Step
73
46
 
74
47
  After validation passes, suggest:
75
- > "All validation levels passed. Consider running the `code-review` skill for a deeper analysis — code review catches bugs in 79% of implementations that pass automated validation (stale closures, missing input validation, route shadowing, unhandled promise rejections). Run the `code-review` skill to check, or the `git` skill (say "commit") to commit directly."
48
+ > "All validation levels passed. Consider triggering the `code-review` skill for a deeper analysis — it catches classes of bugs that lint/types/tests miss (stale closures, missing input validation, route shadowing, unhandled promise rejections). Say 'review the code' to trigger it, or say 'commit' to use the `git` skill directly."
package/global-rules.md CHANGED
@@ -85,11 +85,21 @@ When suggesting a commit, explain in plain language why it's a good moment, adap
85
85
  ---
86
86
 
87
87
  ## 🔌 MCP Servers
88
- <!-- List your configured MCP servers here so the agent knows what tools are available -->
89
- <!-- Example: -->
90
- <!-- - Playwright: Browser automation for E2E testing -->
91
- <!-- - Supabase: Database management -->
92
- <!-- When planning features, explicitly include MCP integration points in the plan -->
88
+
89
+ Declare MCP servers in your project's `.mcp.json` so Claude Code picks them up automatically. Copy the starter template from the plugin:
90
+
91
+ ```bash
92
+ # Inside your project root
93
+ cp ~/.claude/plugins/marketplaces/hopla-marketplace/.claude-plugin/.mcp.json.example .mcp.json
94
+ # Then edit — uncomment the servers you need, set env vars in your shell
95
+ ```
96
+
97
+ List the servers you actually enabled here so the agent knows what tools are available, e.g.:
98
+ - Playwright — browser automation for E2E testing and UI inspection
99
+ - GitHub — PR/issue access (read and write depending on token scope)
100
+ - Linear — workspace tickets, cycles, projects
101
+
102
+ When planning features, explicitly include MCP integration points in the plan.
93
103
 
94
104
  ---
95
105
 
package/hooks/hooks.json CHANGED
@@ -35,6 +35,28 @@
35
35
  }
36
36
  ]
37
37
  }
38
+ ],
39
+ "UserPromptSubmit": [
40
+ {
41
+ "hooks": [
42
+ {
43
+ "type": "command",
44
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/prompt-route.js\"",
45
+ "async": false
46
+ }
47
+ ]
48
+ }
49
+ ],
50
+ "PreCompact": [
51
+ {
52
+ "hooks": [
53
+ {
54
+ "type": "command",
55
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/precompact-snapshot.js\"",
56
+ "async": false
57
+ }
58
+ ]
59
+ }
38
60
  ]
39
61
  }
40
62
  }