@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,65 @@
1
+ #!/usr/bin/env node
2
+ // PreCompact hook: snapshot the session's work state so it survives /compact.
3
+ // The SessionStart hook (session-prime.js) re-injects this when it exists and is recent.
4
+
5
+ import { execSync } from "child_process";
6
+ import fs from "fs";
7
+ import path from "path";
8
+
9
+ function run(cmd) {
10
+ try {
11
+ return execSync(cmd, { cwd: process.cwd(), stdio: "pipe" }).toString().trim();
12
+ } catch {
13
+ return null;
14
+ }
15
+ }
16
+
17
+ function findActivePlan() {
18
+ const plansDir = path.join(process.cwd(), ".agents", "plans");
19
+ if (!fs.existsSync(plansDir)) return null;
20
+ try {
21
+ const files = fs
22
+ .readdirSync(plansDir)
23
+ .filter((f) => f.endsWith(".md") && !f.startsWith("."))
24
+ .map((f) => ({ name: f, mtime: fs.statSync(path.join(plansDir, f)).mtimeMs }))
25
+ .sort((a, b) => b.mtime - a.mtime);
26
+ return files[0]?.name || null;
27
+ } catch {
28
+ return null;
29
+ }
30
+ }
31
+
32
+ function detectWorktree() {
33
+ const gitDir = run("git rev-parse --git-dir");
34
+ const commonDir = run("git rev-parse --git-common-dir");
35
+ if (!gitDir || !commonDir) return false;
36
+ return path.resolve(gitDir) !== path.resolve(commonDir);
37
+ }
38
+
39
+ async function main() {
40
+ // Drain stdin (hook contract)
41
+ const chunks = [];
42
+ for await (const chunk of process.stdin) chunks.push(chunk);
43
+
44
+ const snapshot = {
45
+ timestamp: new Date().toISOString(),
46
+ branch: run("git branch --show-current"),
47
+ uncommitted: run("git status --short"),
48
+ activePlan: findActivePlan(),
49
+ inWorktree: detectWorktree(),
50
+ };
51
+
52
+ const targetDir = path.join(process.cwd(), ".claude");
53
+ try {
54
+ fs.mkdirSync(targetDir, { recursive: true });
55
+ fs.writeFileSync(
56
+ path.join(targetDir, "compact-snapshot.json"),
57
+ JSON.stringify(snapshot, null, 2) + "\n"
58
+ );
59
+ } catch {
60
+ // Best-effort — never block /compact
61
+ }
62
+ process.exit(0);
63
+ }
64
+
65
+ main();
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env node
2
+ // UserPromptSubmit hook: scan the user's prompt for skill keywords and inject
3
+ // a short routing hint. Keeps skill suggestions visible mid-session even after
4
+ // compaction or long conversations where the initial skill list gets buried.
5
+
6
+ const SKILL_TRIGGERS = [
7
+ {
8
+ skill: "git",
9
+ patterns: [
10
+ /\bcommit\b/i,
11
+ /save (my |the )?changes/i,
12
+ /\bcreate (a )?pr\b/i,
13
+ /pull request/i,
14
+ /\bpush\b/i,
15
+ /merge request/i,
16
+ ],
17
+ },
18
+ {
19
+ skill: "worktree",
20
+ patterns: [
21
+ /\bworktree\b/i,
22
+ /isolated branch/i,
23
+ /parallel (feature|development)/i,
24
+ ],
25
+ },
26
+ {
27
+ skill: "prime",
28
+ patterns: [
29
+ /\borient(\b| yourself)/i,
30
+ /catch me up/i,
31
+ /get context/i,
32
+ /load project/i,
33
+ /what is this project/i,
34
+ ],
35
+ },
36
+ {
37
+ skill: "brainstorm",
38
+ patterns: [
39
+ /\bbrainstorm\b/i,
40
+ /explore (options|approaches)/i,
41
+ /how should we/i,
42
+ /trade[- ]offs?/i,
43
+ ],
44
+ },
45
+ {
46
+ skill: "debug",
47
+ patterns: [
48
+ /\bbug\b/i,
49
+ /\berror\b/i,
50
+ /\bdebug\b/i,
51
+ /not working/i,
52
+ /\bfailing\b/i,
53
+ /\bbroken\b/i,
54
+ /\bno funciona\b/i,
55
+ ],
56
+ },
57
+ {
58
+ skill: "verify",
59
+ patterns: [
60
+ /\bverify\b/i,
61
+ /all tests? pass/i,
62
+ /\blisto\b/i,
63
+ /\bterminé\b/i,
64
+ /\bya está\b/i,
65
+ ],
66
+ },
67
+ {
68
+ skill: "code-review",
69
+ patterns: [
70
+ /review (the |my )?code/i,
71
+ /code review/i,
72
+ /audit (the |my )?code/i,
73
+ ],
74
+ },
75
+ {
76
+ skill: "execution-report",
77
+ patterns: [
78
+ /generate (the |a )?report/i,
79
+ /document what was done/i,
80
+ /execution report/i,
81
+ ],
82
+ },
83
+ {
84
+ skill: "tdd",
85
+ patterns: [
86
+ /\btdd\b/i,
87
+ /test[- ]first/i,
88
+ /red[- ]green[- ]refactor/i,
89
+ ],
90
+ },
91
+ ];
92
+
93
+ async function main() {
94
+ const chunks = [];
95
+ for await (const chunk of process.stdin) chunks.push(chunk);
96
+
97
+ let input;
98
+ try {
99
+ input = JSON.parse(Buffer.concat(chunks).toString());
100
+ } catch {
101
+ // Malformed payload — skip silently so we never block legitimate prompts
102
+ process.exit(0);
103
+ }
104
+
105
+ // Cap prompt length so regex matching stays cheap on large paste-ins
106
+ const prompt = (input.prompt || "").slice(0, 4000);
107
+ if (!prompt) process.exit(0);
108
+
109
+ const matched = [];
110
+ for (const { skill, patterns } of SKILL_TRIGGERS) {
111
+ if (patterns.some((p) => p.test(prompt))) matched.push(skill);
112
+ }
113
+
114
+ if (matched.length === 0) process.exit(0);
115
+
116
+ const list = matched.map((s) => `\`${s}\``).join(", ");
117
+ const plural = matched.length > 1;
118
+ process.stdout.write(
119
+ `📦 HOPLA routing hint: this prompt matches skill${plural ? "s" : ""} ${list}. ` +
120
+ `Use ${plural ? "them" : "it"} if applicable to the current task.`
121
+ );
122
+ process.exit(0);
123
+ }
124
+
125
+ main();
@@ -13,6 +13,18 @@ function run(cmd) {
13
13
  }
14
14
  }
15
15
 
16
+ function excerptClaudeMd(content) {
17
+ const lines = content.split("\n");
18
+ // Prefer the first `---` separator after the opening heading and first section
19
+ for (let i = 5; i < Math.min(lines.length, 120); i++) {
20
+ if (lines[i].trim() === "---") {
21
+ return lines.slice(0, i).join("\n").trimEnd();
22
+ }
23
+ }
24
+ // No separator within a reasonable window — cap at 60 lines
25
+ return lines.slice(0, Math.min(lines.length, 60)).join("\n").trimEnd();
26
+ }
27
+
16
28
  function discoverSkills() {
17
29
  // Try plugin context first: ../skills/ relative to this script
18
30
  const hookDir = import.meta.dirname;
@@ -65,11 +77,31 @@ async function main() {
65
77
  lines.push("Working tree is clean.");
66
78
  }
67
79
 
68
- // CLAUDE.md summary (first 20 lines)
80
+ // Re-inject pre-compact snapshot if recent (< 2 hours old)
81
+ const snapshotPath = path.join(process.cwd(), ".claude", "compact-snapshot.json");
82
+ if (fs.existsSync(snapshotPath)) {
83
+ try {
84
+ const snap = JSON.parse(fs.readFileSync(snapshotPath, "utf8"));
85
+ const ageMs = Date.now() - Date.parse(snap.timestamp);
86
+ if (Number.isFinite(ageMs) && ageMs < 2 * 60 * 60 * 1000) {
87
+ const parts = [
88
+ `Resuming from pre-compact snapshot (${Math.round(ageMs / 60000)} min ago):`,
89
+ ];
90
+ if (snap.branch) parts.push(`- branch: ${snap.branch}${snap.inWorktree ? " (worktree)" : ""}`);
91
+ if (snap.activePlan) parts.push(`- active plan: .agents/plans/${snap.activePlan}`);
92
+ if (snap.uncommitted) parts.push(`- uncommitted at snapshot:\n${snap.uncommitted}`);
93
+ lines.push(parts.join("\n"));
94
+ }
95
+ } catch {
96
+ // Ignore malformed snapshot
97
+ }
98
+ }
99
+
100
+ // CLAUDE.md excerpt — cut at a natural boundary, not a fixed line count
69
101
  const claudeMdPath = path.join(process.cwd(), "CLAUDE.md");
70
102
  if (fs.existsSync(claudeMdPath)) {
71
- const content = fs.readFileSync(claudeMdPath, "utf8").split("\n").slice(0, 20).join("\n");
72
- lines.push(`Project rules (CLAUDE.md excerpt):\n${content}`);
103
+ const excerpt = excerptClaudeMd(fs.readFileSync(claudeMdPath, "utf8"));
104
+ lines.push(`Project rules (CLAUDE.md excerpt):\n${excerpt}`);
73
105
  }
74
106
 
75
107
  // Auto-discover available skills
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env node
2
+ // Hopla statusline: branch · worktree indicator · uncommitted count · active plan.
3
+ // Wire it up by adding to ~/.claude/settings.json:
4
+ // "statusLine": {
5
+ // "type": "command",
6
+ // "command": "node ~/.claude/plugins/marketplaces/hopla-marketplace/hooks/statusline.js"
7
+ // }
8
+
9
+ import { execSync } from "child_process";
10
+ import fs from "fs";
11
+ import path from "path";
12
+
13
+ const CYAN = "\x1b[36m";
14
+ const YELLOW = "\x1b[33m";
15
+ const MAGENTA = "\x1b[35m";
16
+ const DIM = "\x1b[2m";
17
+ const RESET = "\x1b[0m";
18
+
19
+ function run(cmd, cwd) {
20
+ try {
21
+ return execSync(cmd, { cwd, stdio: "pipe" }).toString().trim();
22
+ } catch {
23
+ return null;
24
+ }
25
+ }
26
+
27
+ function findActivePlan(cwd) {
28
+ const plansDir = path.join(cwd, ".agents", "plans");
29
+ if (!fs.existsSync(plansDir)) return null;
30
+ try {
31
+ const files = fs
32
+ .readdirSync(plansDir)
33
+ .filter((f) => f.endsWith(".md") && !f.startsWith("."))
34
+ .map((f) => ({ name: f, mtime: fs.statSync(path.join(plansDir, f)).mtimeMs }))
35
+ .sort((a, b) => b.mtime - a.mtime);
36
+ return files[0]?.name.replace(/\.md$/, "") || null;
37
+ } catch {
38
+ return null;
39
+ }
40
+ }
41
+
42
+ async function main() {
43
+ const chunks = [];
44
+ for await (const chunk of process.stdin) chunks.push(chunk);
45
+
46
+ let input = {};
47
+ try {
48
+ input = JSON.parse(Buffer.concat(chunks).toString());
49
+ } catch {
50
+ // Malformed payload — render nothing
51
+ process.exit(0);
52
+ }
53
+
54
+ const cwd = input.workspace?.current_dir || input.cwd || process.cwd();
55
+ const parts = [];
56
+
57
+ const branch = run("git branch --show-current", cwd);
58
+ if (branch) {
59
+ const gitDir = run("git rev-parse --git-dir", cwd);
60
+ const commonDir = run("git rev-parse --git-common-dir", cwd);
61
+ const isWorktree =
62
+ gitDir && commonDir && path.resolve(cwd, gitDir) !== path.resolve(cwd, commonDir);
63
+ parts.push(`${CYAN}${isWorktree ? "⎇ " : " "}${branch}${RESET}`);
64
+ }
65
+
66
+ const status = run("git status --short", cwd);
67
+ if (status) {
68
+ const count = status.split("\n").length;
69
+ parts.push(`${YELLOW}${count}M${RESET}`);
70
+ }
71
+
72
+ const plan = findActivePlan(cwd);
73
+ if (plan) {
74
+ parts.push(`${MAGENTA}📋 ${plan}${RESET}`);
75
+ }
76
+
77
+ if (parts.length === 0) process.exit(0);
78
+
79
+ process.stdout.write(parts.join(` ${DIM}·${RESET} `));
80
+ process.exit(0);
81
+ }
82
+
83
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hopla/claude-setup",
3
- "version": "1.14.1",
3
+ "version": "1.16.0",
4
4
  "description": "Hopla team agentic coding system for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,6 +16,10 @@
16
16
  "hooks/",
17
17
  ".claude-plugin/"
18
18
  ],
19
+ "scripts": {
20
+ "prepublishOnly": "node scripts/check-versions.js",
21
+ "check-versions": "node scripts/check-versions.js"
22
+ },
19
23
  "engines": {
20
24
  "node": ">=18"
21
25
  },
@@ -14,7 +14,7 @@ Read `CLAUDE.md` or `AGENTS.md` to understand project standards and patterns.
14
14
 
15
15
  If `.agents/guides/` exists, read any guides relevant to the files being reviewed (e.g. `@.agents/guides/api-guide.md` when reviewing API changes). These guides define the expected patterns for specific task types.
16
16
 
17
- If `.agents/guides/review-checklist.md` exists, read it and apply the project-specific checks it defines in addition to the standard checks below. Project-specific checklists cover framework gotchas and domain anti-patterns unique to the project (e.g., AG Grid stale closures, Hono route ordering).
17
+ If `.agents/guides/review-checklist.md` exists, read it and apply the project-specific checks it defines in addition to the standard checks. Project-specific checklists cover framework gotchas and domain anti-patterns unique to the project (e.g., grid stale closures, route ordering).
18
18
 
19
19
  ## Step 2: Identify Changed Files
20
20
 
@@ -28,42 +28,16 @@ Read each changed or new file in its entirety — not just the diff.
28
28
 
29
29
  ## Step 3: Analyze for Issues
30
30
 
31
- For each changed file, look for:
32
-
33
- **1. Logic Errors**
34
- - Off-by-one errors, incorrect conditionals
35
- - Missing error handling, unhandled edge cases
36
- - Race conditions or async issues
37
- - Stale closures — callbacks passed to imperative APIs (grids, charts, maps) that capture stale state instead of using refs or stable references
38
- - Unhandled promise rejections — `.then()` without `.catch()`, async calls without `try/catch` in non-void contexts
39
- - Side effects inside JSX render — mutations of arrays/objects inside `.map()` in JSX (breaks React strict mode, causes double-execution bugs)
40
- - Stale dependency arrays — for every new `useState`/`useRef` variable introduced in the diff, verify it appears in the dependency arrays of `useEffect`, `useCallback`, or `useMemo` that reference it. Missing deps cause stale closures — this was the #1 React bug category across 28 implementations
41
-
42
- **2. Security Issues**
43
- - Exposed secrets or API keys
44
- - SQL/command injection vulnerabilities
45
- - Missing input validation on API endpoints — required fields, format constraints (regex, length), payload size limits
46
- - Insecure data handling — raw user input in queries, responses exposing internal data or stack traces
47
- - XSS vulnerabilities (frontend)
48
- - Multi-user authorization context — for multi-tenant apps, verify each endpoint filters by the correct context (e.g., active org vs personal org, admin vs viewer). Check that middleware/auth guards match the intended audience for each route
49
-
50
- **3. Performance Problems**
51
- - Unnecessary re-renders (React)
52
- - N+1 queries — database queries or API calls inside loops (`for`, `.map`, `.forEach`), duplicate existence checks before mutations, sequential operations that could use `Promise.all()` or batch SQL. This was found in 5 of 13 recent implementations
53
- - Memory leaks
54
-
55
- **4. Code Quality**
56
- - DRY violations — before flagging, search for similar functions/constants elsewhere in the codebase; suggest extraction to a shared module if the same logic exists in multiple places
57
- - Poor naming or overly complex functions
58
- - Missing TypeScript types or `any` usage
59
-
60
- **5. Pattern Adherence**
61
- - Follows project conventions from CLAUDE.md
62
- - Consistent with existing codebase style
63
-
64
- **6. Route & Middleware Ordering**
65
- - Static routes defined AFTER parameterized routes (e.g., `/users/all` after `/users/:id`) causing shadowing — the parameterized route captures requests meant for the static one
66
- - Middleware applied in incorrect order (e.g., auth after route handler, CORS after response sent)
31
+ Apply the full checklist in `checklist.md` (same directory). It covers:
32
+
33
+ 1. Logic errors (stale closures, unhandled rejections, missing deps)
34
+ 2. Security (secrets, injection, input validation, multi-tenant auth)
35
+ 3. Performance (N+1, re-renders, memory leaks)
36
+ 4. Code quality (DRY, naming, types)
37
+ 5. Pattern adherence (project conventions)
38
+ 6. Route & middleware ordering
39
+
40
+ Read `checklist.md` before reviewing so you apply every category.
67
41
 
68
42
  ## Step 4: Verify Issues Are Real
69
43
 
@@ -73,9 +47,10 @@ Before reporting, confirm each issue is legitimate:
73
47
 
74
48
  ## Step 5: Output Report
75
49
 
76
- Save to `.agents/code-reviews/[descriptive-name].md`
50
+ Save to `.agents/code-reviews/[descriptive-name].md`.
77
51
 
78
52
  **Format for each issue:**
53
+
79
54
  ```
80
55
  severity: critical | high | medium | low
81
56
  file: path/to/file.ts
@@ -88,6 +63,7 @@ suggestion: [how to fix it]
88
63
  If no issues found: "Code review passed. No technical issues detected."
89
64
 
90
65
  **Rules:**
66
+
91
67
  - Be specific — line numbers, not vague complaints
92
68
  - Focus on real bugs, not style preferences (linting handles that)
93
69
  - Flag security issues as `critical`
@@ -96,4 +72,5 @@ If no issues found: "Code review passed. No technical issues detected."
96
72
  ## Next Step
97
73
 
98
74
  After the review, suggest:
75
+
99
76
  > "Code review saved to `.agents/code-reviews/[name].md`. If issues were found, run `/hopla:code-review-fix .agents/code-reviews/[name].md` to fix them. If the review passed clean, proceed to the `execution-report` skill."
@@ -0,0 +1,44 @@
1
+ # Code Review Checklist
2
+
3
+ Apply every category to every changed file. Severity guidance is in the parent `SKILL.md`.
4
+
5
+ ## 1. Logic Errors
6
+
7
+ - Off-by-one errors, incorrect conditionals
8
+ - Missing error handling, unhandled edge cases
9
+ - Race conditions or async issues
10
+ - Stale closures — callbacks passed to imperative APIs (grids, charts, maps) that capture stale state instead of using refs or stable references
11
+ - Unhandled promise rejections — `.then()` without `.catch()`, async calls without `try/catch` in non-void contexts
12
+ - Side effects inside JSX render — mutations of arrays/objects inside `.map()` in JSX (breaks React strict mode, causes double-execution bugs)
13
+ - Stale dependency arrays — for every new `useState`/`useRef` variable introduced in the diff, verify it appears in the dependency arrays of `useEffect`, `useCallback`, or `useMemo` that reference it. Missing deps cause stale closures and are a recurring source of React bugs.
14
+
15
+ ## 2. Security Issues
16
+
17
+ - Exposed secrets or API keys
18
+ - SQL/command injection vulnerabilities
19
+ - Missing input validation on API endpoints — required fields, format constraints (regex, length), payload size limits
20
+ - Insecure data handling — raw user input in queries, responses exposing internal data or stack traces
21
+ - XSS vulnerabilities (frontend)
22
+ - Multi-user authorization context — for multi-tenant apps, verify each endpoint filters by the correct context (e.g., active org vs personal org, admin vs viewer). Check that middleware/auth guards match the intended audience for each route.
23
+
24
+ ## 3. Performance Problems
25
+
26
+ - Unnecessary re-renders (React)
27
+ - N+1 queries — database queries or API calls inside loops (`for`, `.map`, `.forEach`), duplicate existence checks before mutations, sequential operations that could use `Promise.all()` or batch SQL
28
+ - Memory leaks (event listeners not detached, timers not cleared, closures holding large objects)
29
+
30
+ ## 4. Code Quality
31
+
32
+ - DRY violations — before flagging, search for similar functions/constants elsewhere in the codebase; suggest extraction to a shared module if the same logic exists in multiple places
33
+ - Poor naming or overly complex functions
34
+ - Missing TypeScript types or `any` usage
35
+
36
+ ## 5. Pattern Adherence
37
+
38
+ - Follows project conventions from `CLAUDE.md`
39
+ - Consistent with existing codebase style
40
+
41
+ ## 6. Route & Middleware Ordering
42
+
43
+ - Static routes defined AFTER parameterized routes (e.g., `/users/all` after `/users/:id`) causing shadowing — the parameterized route captures requests meant for the static one
44
+ - Middleware applied in incorrect order (e.g., auth after route handler, CORS after response sent)
@@ -22,97 +22,30 @@ Also check for recent code reviews:
22
22
  ls -t .agents/code-reviews/ 2>/dev/null | head -5
23
23
  ```
24
24
 
25
- If a code review exists for this feature, note its path for the Code Review Findings section below.
25
+ If a code review exists for this feature, note its path for the Code Review Findings section.
26
26
 
27
- ## Step 2: Generate Report
27
+ ## Step 2: Generate the Report
28
28
 
29
- Save to: `.agents/execution-reports/[feature-name].md`
29
+ Save to: `.agents/execution-reports/[feature-name].md`.
30
30
 
31
- Use the following structure:
31
+ Use the full structure documented in `report-structure.md` (same directory). It covers:
32
32
 
33
- ---
34
-
35
- ### Meta Information
36
-
37
- - **Plan file:** [path to the plan that guided this implementation]
38
- - **Files added:** [list with paths]
39
- - **Files modified:** [list with paths]
40
- - **Lines changed:** +X -Y
41
-
42
- ### Validation Results
43
-
44
- - Syntax & Linting: ✓/✗ [details if failed]
45
- - Type Checking: ✓/✗ [details if failed]
46
- - Unit Tests: ✓/✗ [X passed, Y failed]
47
- - Integration Tests: ✓/✗ [X passed, Y failed]
48
-
49
- ### Code Review Findings
50
-
51
- - **Code review file:** [path to `.agents/code-reviews/[name].md`, or "Not run"]
52
- - **Issues found:** [count by severity: X critical, Y high, Z medium, W low]
53
- - **Issues fixed before this report:** [count]
54
- - **Key findings:** [1-2 sentence summary of the most significant issues found]
55
-
56
- ### What Went Well
57
-
58
- List specific things that worked smoothly:
59
- - [concrete examples]
60
-
61
- ### Challenges Encountered
62
-
63
- List specific difficulties encountered:
64
- - [what was difficult and why]
65
-
66
- ### Bugs Encountered
67
-
68
- Categorize each bug found during implementation:
69
-
70
- | Bug | Category | Found By | Severity |
71
- |-----|----------|----------|----------|
72
- | [description] | stale closure / validation / race condition / styling / scope mismatch / type error / route ordering / other | lint / types / tests / code review / manual testing | critical / high / medium / low |
33
+ - Meta information (plan file, files added/modified, lines changed)
34
+ - Validation results
35
+ - Code review findings
36
+ - What went well
37
+ - Challenges encountered
38
+ - Bugs encountered (with categorization table)
39
+ - Divergences from plan
40
+ - Scope assessment
41
+ - Skipped items
42
+ - Technical patterns discovered (with ready-to-paste CLAUDE.md entry)
43
+ - Recommendations
73
44
 
74
- If no bugs were encountered, write "No bugs encountered during implementation."
75
-
76
- ### Divergences from Plan
77
-
78
- For each divergence from the original plan:
79
-
80
- **[Divergence Title]**
81
- - **Planned:** [what the plan specified]
82
- - **Actual:** [what was implemented instead]
83
- - **Reason:** [why this divergence occurred]
84
- - **Type:** Better approach found | Plan assumption wrong | Security concern | Performance issue | Other
85
-
86
- ### Scope Assessment
87
-
88
- - **Planned tasks:** [number of tasks in the original plan]
89
- - **Executed tasks:** [number of tasks actually completed]
90
- - **Unplanned additions:** [count and brief description of work not in the original plan]
91
- - **Scope accuracy:** On target | Under-scoped (took more work than planned) | Over-scoped (simpler than expected)
92
-
93
- ### Skipped Items
94
-
95
- List anything from the plan that was not implemented:
96
- - [what was skipped] — Reason: [why]
97
-
98
- ### Technical Patterns Discovered
99
-
100
- New gotchas, patterns, or conventions learned during this implementation that should be documented:
101
-
102
- - **Pattern/Gotcha:** [description]
103
- - **Where it applies:** [what type of feature or context triggers this]
104
- - **Ready-to-paste CLAUDE.md entry:** [Write the EXACT text that should be added to the project's CLAUDE.md to prevent this gotcha in future features. Format it as a bullet point under the appropriate section. If it belongs in a guide instead, write the exact text for the guide. Do not write vague suggestions like "document this" — write the actual content so the system reviewer can apply it directly.]
105
-
106
- If nothing new was discovered, write "No new patterns discovered."
107
-
108
- ### Recommendations
109
-
110
- Based on this implementation, what should change for next time?
111
- - Plan command improvements: [suggestions]
112
- - Execute command improvements: [suggestions]
113
- - CLAUDE.md additions: [suggestions]
45
+ Read `report-structure.md` before writing so every section is filled correctly.
114
46
 
115
47
  ## Next Step
116
48
 
117
49
  After the report is saved, suggest:
118
- > "Execution report saved to `.agents/execution-reports/[name].md`. Run the `git` skill (say "commit") to commit your changes."
50
+
51
+ > "Execution report saved to `.agents/execution-reports/[name].md`. Use the `git` skill (say 'commit') to save your changes."