@hopla/claude-setup 1.3.4 → 1.4.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/README.md CHANGED
@@ -72,6 +72,8 @@ This system is built on two core concepts from the Agentic Coding Course:
72
72
  | **Global Rules** | Always-loaded context: language, git flow, tech defaults, autonomy rules | `~/.claude/CLAUDE.md` |
73
73
  | **On-Demand Context** | Task-specific guides loaded when needed (e.g. "how to add an API endpoint") | `.agents/guides/*.md` |
74
74
  | **Commands** | Reusable processes that tell the agent *how* to work | `~/.claude/commands/hopla-*.md` |
75
+ | **Skills** | Auto-activate by semantic matching — no slash command needed | `~/.claude/skills/hopla-*/SKILL.md` |
76
+ | **Hooks** | Run automatically before/after tool use for type checking and protection | `~/.claude/hooks/*.js` |
75
77
 
76
78
  The key insight: **commands inject on-demand context deterministically** — when you run `/hopla-plan-feature`, it automatically reads the relevant guide from `.agents/guides/` before planning.
77
79
 
@@ -112,6 +114,42 @@ After each PIV loop, run `/hopla-execution-report` + `/hopla-system-review` to f
112
114
  | `/hopla-execution-report` | Generate an implementation report for system review |
113
115
  | `/hopla-system-review` | Analyze implementation against plan to find process improvements |
114
116
 
117
+ **`~/.claude/skills/`** — Auto-activate by semantic matching, no slash command needed:
118
+
119
+ | Skill | Auto-activates when you say... |
120
+ |---|---|
121
+ | `hopla-git` | "commit this", "create a PR", "guarda los cambios" |
122
+ | `hopla-prime` | "orient yourself", "ponte al día", "what is this project" |
123
+ | `hopla-code-review` | "review the code", "code review", "analiza los cambios" |
124
+ | `hopla-execution-report` | "generate the report", "genera el reporte", "document what was done" |
125
+
126
+ **`~/.claude/hooks/`** — Run automatically before/after tool use (configured in `~/.claude/settings.json`):
127
+
128
+ | Hook | Type | What it does |
129
+ |---|---|---|
130
+ | `tsc-check.js` | PostToolUse | Runs `tsc --noEmit` after file edits; feeds errors back to Claude |
131
+ | `env-protect.js` | PreToolUse | Blocks reads/greps targeting `.env` files |
132
+ | `session-prime.js` | SessionStart (opt-in) | Loads git context + CLAUDE.md summary at session start |
133
+
134
+ **Installed layout:**
135
+
136
+ ```
137
+ ~/.claude/
138
+ ├── CLAUDE.md ← Global rules
139
+ ├── commands/
140
+ │ └── hopla-*.md ← Slash commands (/hopla-prime, /hopla-execute, etc.)
141
+ ├── skills/
142
+ │ ├── hopla-git/ ← Auto-activates for commit/PR requests
143
+ │ ├── hopla-prime/ ← Auto-activates for orientation requests
144
+ │ ├── hopla-code-review/ ← Auto-activates for review requests
145
+ │ └── hopla-execution-report/ ← Auto-activates for report requests
146
+ ├── hooks/
147
+ │ ├── tsc-check.js ← TypeScript type checking after edits
148
+ │ ├── env-protect.js ← .env file protection
149
+ │ └── session-prime.js ← Session context loader (opt-in)
150
+ └── settings.json ← Permissions + hooks config (auto-updated)
151
+ ```
152
+
115
153
  ---
116
154
 
117
155
  ## Recommended Workflow
@@ -141,6 +179,8 @@ After each PIV loop, run `/hopla-execution-report` + `/hopla-system-review` to f
141
179
  /hopla-system-review → analyze plan vs. actual for process improvements
142
180
  ```
143
181
 
182
+ > **Tip:** `hopla-prime`, `hopla-git-commit`, `hopla-git-pr`, `hopla-code-review`, and `hopla-execution-report` also exist as skills — they auto-activate when you describe what you want in natural language, without typing the slash command.
183
+
144
184
  ---
145
185
 
146
186
  ## Command Chaining
package/cli.js CHANGED
@@ -17,6 +17,8 @@ if (VERSION) {
17
17
  }
18
18
  const CLAUDE_DIR = path.join(os.homedir(), ".claude");
19
19
  const COMMANDS_DIR = path.join(CLAUDE_DIR, "commands");
20
+ const SKILLS_DIR = path.join(CLAUDE_DIR, "skills");
21
+ const HOOKS_DIR = path.join(CLAUDE_DIR, "hooks");
20
22
  const FILES_DIR = path.join(import.meta.dirname, "files");
21
23
 
22
24
  const GREEN = "\x1b[32m";
@@ -226,6 +228,169 @@ async function install() {
226
228
  }
227
229
 
228
230
  await setupPermissions();
231
+ await installSkills();
232
+ await installHooks();
233
+ }
234
+
235
+ // Skills to install in planning mode (subset)
236
+ const PLANNING_SKILLS = ["hopla-prime"];
237
+
238
+ async function installSkills() {
239
+ const skillsSrcDir = path.join(FILES_DIR, "skills");
240
+ if (!fs.existsSync(skillsSrcDir)) return;
241
+
242
+ fs.mkdirSync(SKILLS_DIR, { recursive: true });
243
+
244
+ const skillDirs = fs.readdirSync(skillsSrcDir).filter((entry) => {
245
+ return fs.statSync(path.join(skillsSrcDir, entry)).isDirectory();
246
+ });
247
+
248
+ const skillsToInstall = PLANNING
249
+ ? skillDirs.filter((d) => PLANNING_SKILLS.includes(d))
250
+ : skillDirs;
251
+
252
+ if (skillsToInstall.length === 0) return;
253
+
254
+ log(`\n${CYAN}Installing skills...${RESET}`);
255
+ for (const skillName of skillsToInstall.sort()) {
256
+ const srcDir = path.join(skillsSrcDir, skillName);
257
+ const destDir = path.join(SKILLS_DIR, skillName);
258
+ fs.mkdirSync(destDir, { recursive: true });
259
+ for (const file of fs.readdirSync(srcDir).sort()) {
260
+ await installFile(
261
+ path.join(srcDir, file),
262
+ path.join(destDir, file),
263
+ `~/.claude/skills/${skillName}/${file}`
264
+ );
265
+ }
266
+ }
267
+
268
+ log(`\n${GREEN}${BOLD}Skills installed!${RESET} Auto-activate without a slash command:\n`);
269
+ for (const skillName of skillsToInstall.sort()) {
270
+ log(` ${CYAN}${skillName}${RESET}`);
271
+ }
272
+ }
273
+
274
+ async function installHooks() {
275
+ const hooksSrcDir = path.join(FILES_DIR, "hooks");
276
+ if (!fs.existsSync(hooksSrcDir)) return;
277
+
278
+ const hookFiles = fs.readdirSync(hooksSrcDir).filter((f) => f.endsWith(".js"));
279
+ if (hookFiles.length === 0) return;
280
+
281
+ const settingsPath = path.join(CLAUDE_DIR, "settings.json");
282
+
283
+ // Read existing settings
284
+ let settings = {};
285
+ if (fs.existsSync(settingsPath)) {
286
+ try {
287
+ settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
288
+ } catch {
289
+ // keep defaults
290
+ }
291
+ }
292
+
293
+ const existingHooks = settings.hooks || {};
294
+ const tscHookCmd = `${HOOKS_DIR}/tsc-check.js`;
295
+ const envHookCmd = `${HOOKS_DIR}/env-protect.js`;
296
+ const sessionHookCmd = `${HOOKS_DIR}/session-prime.js`;
297
+
298
+ // Check what's already configured
299
+ const postToolUseHooks = existingHooks.PostToolUse || [];
300
+ const preToolUseHooks = existingHooks.PreToolUse || [];
301
+ const sessionStartHooks = existingHooks.SessionStart || [];
302
+
303
+ const hasTsc = postToolUseHooks.some((h) =>
304
+ h.hooks?.some((hh) => hh.command === tscHookCmd)
305
+ );
306
+ const hasEnv = preToolUseHooks.some((h) =>
307
+ h.hooks?.some((hh) => hh.command === envHookCmd)
308
+ );
309
+ const hasSession = sessionStartHooks.some((h) =>
310
+ h.hooks?.some((hh) => hh.command === sessionHookCmd)
311
+ );
312
+
313
+ const toAdd = [];
314
+ if (!hasTsc) toAdd.push(`PostToolUse(Write|Edit|MultiEdit) → tsc-check.js`);
315
+ if (!hasEnv) toAdd.push(`PreToolUse(Read|Grep) → env-protect.js`);
316
+
317
+ log(`\n${CYAN}Configuring hooks...${RESET}`);
318
+
319
+ if (toAdd.length === 0 && hasSession) {
320
+ log(`${GREEN}✓${RESET} Hooks already configured.\n`);
321
+ return;
322
+ }
323
+
324
+ if (toAdd.length > 0) {
325
+ log(` The following hooks will be added to ~/.claude/settings.json:\n`);
326
+ for (const h of toAdd) {
327
+ log(` ${CYAN}+${RESET} ${h}`);
328
+ }
329
+ }
330
+
331
+ // Ask about session-prime separately (opt-in)
332
+ let installSessionPrime = false;
333
+ if (!hasSession) {
334
+ log(`\n ${YELLOW}Optional:${RESET} session-prime.js auto-loads project context on session start.`);
335
+ installSessionPrime = await confirm(` Enable session-prime hook? (y/N) `);
336
+ }
337
+
338
+ if (toAdd.length === 0 && !installSessionPrime) {
339
+ log(` ${YELLOW}↷${RESET} Skipped hooks — you can configure ~/.claude/settings.json manually\n`);
340
+ return;
341
+ }
342
+
343
+ const ok = toAdd.length > 0
344
+ ? await confirm(`\n Install these hooks? (y/N) `)
345
+ : true;
346
+
347
+ if (!ok) {
348
+ log(` ${YELLOW}↷${RESET} Skipped hooks — you can configure ~/.claude/settings.json manually\n`);
349
+ return;
350
+ }
351
+
352
+ // Copy hook files
353
+ fs.mkdirSync(HOOKS_DIR, { recursive: true });
354
+ for (const file of hookFiles) {
355
+ await installFile(
356
+ path.join(hooksSrcDir, file),
357
+ path.join(HOOKS_DIR, file),
358
+ `~/.claude/hooks/${file}`
359
+ );
360
+ // Make executable
361
+ try {
362
+ fs.chmodSync(path.join(HOOKS_DIR, file), 0o755);
363
+ } catch {
364
+ // Non-critical
365
+ }
366
+ }
367
+
368
+ // Build updated hooks config
369
+ if (!settings.hooks) settings.hooks = {};
370
+
371
+ if (!hasTsc) {
372
+ if (!settings.hooks.PostToolUse) settings.hooks.PostToolUse = [];
373
+ settings.hooks.PostToolUse.push({
374
+ matcher: "Write|Edit|MultiEdit",
375
+ hooks: [{ type: "command", command: tscHookCmd }],
376
+ });
377
+ }
378
+ if (!hasEnv) {
379
+ if (!settings.hooks.PreToolUse) settings.hooks.PreToolUse = [];
380
+ settings.hooks.PreToolUse.push({
381
+ matcher: "Read|Grep",
382
+ hooks: [{ type: "command", command: envHookCmd }],
383
+ });
384
+ }
385
+ if (installSessionPrime && !hasSession) {
386
+ if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];
387
+ settings.hooks.SessionStart.push({
388
+ hooks: [{ type: "command", command: sessionHookCmd }],
389
+ });
390
+ }
391
+
392
+ fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
393
+ log(` ${GREEN}✓${RESET} Hooks configured.\n`);
229
394
  }
230
395
 
231
396
  const HOPLA_PERMISSIONS = [
@@ -139,6 +139,16 @@ Before saving the draft, review the plan against these criteria:
139
139
 
140
140
  ## Phase 7: Save Draft and Enter Review Loop
141
141
 
142
+ **Before saving, identify the target file:**
143
+
144
+ 1. List all files in `.agents/plans/` (both `*.draft.md` and `*.md`)
145
+ 2. Determine the target filename from the feature name derived in Phase 1: `[kebab-case-feature-name].draft.md`
146
+ 3. If a file with that name already exists → **overwrite it**
147
+ 4. If a file with a similar name exists (e.g. same feature, slight variation) → **overwrite it and confirm which file was updated**
148
+ 5. Never create versioned files (e.g. `-v2`, `-updated`, `-new`) — always update in place
149
+
150
+ **Save and notify:**
151
+
142
152
  1. Save the plan to `.agents/plans/[kebab-case-feature-name].draft.md`
143
153
  2. Tell the user:
144
154
  > "Plan draft saved to `.agents/plans/[feature-name].draft.md` — open it in your editor and review it carefully. If you want changes, add comments like `<? change this >` anywhere in the file and tell me 'apply comments'. You can also request changes directly in the chat. When it's ready, say 'done' to create the final file."
@@ -147,10 +157,11 @@ Before saving the draft, review the plan against these criteria:
147
157
  - Any open questions or decisions that require human input before execution
148
158
 
149
159
  **Review loop:** Stay in this loop until the user finalizes:
150
- - If the user says **"apply comments"** → scan the draft for `<? ... >`, apply each one, remove the comment tags, update the file, report what changed
151
- - If the user requests changes in chat → apply directly to the draft, confirm what changed
160
+ - If the user says **"apply comments"** → identify the active draft (the one saved in this session, or ask if unclear), scan it for `<? ... >`, apply each one, remove the comment tags, update the file, report what changed
161
+ - If the user requests changes in chat → apply directly to the active draft, confirm the filename and what changed
162
+ - If the user references a specific plan file (e.g. passes a path) → treat that file as the active draft
152
163
  - If the user says the plan is ready → proceed to finalize
153
164
 
154
165
  **Finalize:**
155
- 1. Rename `.agents/plans/[feature-name].draft.md` → `.agents/plans/[feature-name].md`
166
+ 1. Rename `.agents/plans/[feature-name].draft.md` → `.agents/plans/[feature-name].md` (overwrite if it already exists)
156
167
  2. Confirm: "✅ Plan saved to `.agents/plans/[feature-name].md`. Run `/hopla-git-commit` to commit it, then share with the team to execute with `/hopla-execute .agents/plans/[feature-name].md`."
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ // PreToolUse hook: blocks reads/greps targeting .env files
3
+
4
+ async function main() {
5
+ const chunks = [];
6
+ for await (const chunk of process.stdin) {
7
+ chunks.push(chunk);
8
+ }
9
+
10
+ const toolCall = JSON.parse(Buffer.concat(chunks).toString());
11
+ const filePath = toolCall.tool_input?.file_path || toolCall.tool_input?.path || "";
12
+
13
+ if (filePath.includes(".env")) {
14
+ process.stderr.write(
15
+ `Access denied: Reading .env files is blocked to prevent accidental secret exposure. ` +
16
+ `If you need environment variable names, check the README or ask the user.\n`
17
+ );
18
+ process.exit(2);
19
+ }
20
+
21
+ process.exit(0);
22
+ }
23
+
24
+ main();
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env node
2
+ // SessionStart hook: provides initial project context when a session begins
3
+
4
+ import { execSync } from "child_process";
5
+ import fs from "fs";
6
+ import path from "path";
7
+
8
+ function run(cmd) {
9
+ try {
10
+ return execSync(cmd, { cwd: process.cwd(), stdio: "pipe" }).toString().trim();
11
+ } catch {
12
+ return null;
13
+ }
14
+ }
15
+
16
+ async function main() {
17
+ const lines = [];
18
+
19
+ // Git context
20
+ const branch = run("git branch --show-current");
21
+ const log = run("git log --oneline -5");
22
+ const status = run("git status --short");
23
+
24
+ if (branch) {
25
+ lines.push(`Current branch: ${branch}`);
26
+ }
27
+ if (log) {
28
+ lines.push(`Recent commits:\n${log}`);
29
+ }
30
+ if (status) {
31
+ lines.push(`Uncommitted changes:\n${status}`);
32
+ } else if (branch) {
33
+ lines.push("Working tree is clean.");
34
+ }
35
+
36
+ // CLAUDE.md summary (first 20 lines)
37
+ const claudeMdPath = path.join(process.cwd(), "CLAUDE.md");
38
+ if (fs.existsSync(claudeMdPath)) {
39
+ const content = fs.readFileSync(claudeMdPath, "utf8").split("\n").slice(0, 20).join("\n");
40
+ lines.push(`Project rules (CLAUDE.md excerpt):\n${content}`);
41
+ }
42
+
43
+ if (lines.length > 0) {
44
+ process.stdout.write("=== Session Context ===\n" + lines.join("\n\n") + "\n======================\n");
45
+ }
46
+
47
+ process.exit(0);
48
+ }
49
+
50
+ main();
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ // PostToolUse hook: runs tsc --noEmit after file edits and feeds errors back to Claude
3
+
4
+ import { execSync } from "child_process";
5
+ import fs from "fs";
6
+ import path from "path";
7
+
8
+ async function main() {
9
+ const chunks = [];
10
+ for await (const chunk of process.stdin) {
11
+ chunks.push(chunk);
12
+ }
13
+
14
+ // If no tsconfig.json in cwd, exit silently (non-TS project)
15
+ const tsconfigPath = path.join(process.cwd(), "tsconfig.json");
16
+ if (!fs.existsSync(tsconfigPath)) {
17
+ process.exit(0);
18
+ }
19
+
20
+ let result;
21
+ try {
22
+ execSync("tsc --noEmit", { cwd: process.cwd(), stdio: "pipe" });
23
+ // No errors — exit silently
24
+ process.exit(0);
25
+ } catch (err) {
26
+ const output = (err.stdout || "").toString() + (err.stderr || "").toString();
27
+ if (output.trim()) {
28
+ process.stdout.write("TypeScript errors detected:\n" + output + "\n");
29
+ }
30
+ // Exit 0: PostToolUse hooks cannot block, but stdout is fed back to Claude
31
+ process.exit(0);
32
+ }
33
+ }
34
+
35
+ main();
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: hopla-code-review
3
+ description: Performs a technical code review on recently changed files. Use when the user says "review the code", "revisar el código", "code review", "analiza los cambios", "check my code", "revisa mi código", "look for issues", or asks for feedback on their implementation.
4
+ ---
5
+
6
+ Perform a technical code review focused on finding real bugs and issues.
7
+
8
+ ## Step 1: Load Context
9
+
10
+ Read `CLAUDE.md` or `AGENTS.md` to understand project standards and patterns.
11
+
12
+ 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.
13
+
14
+ ## Step 2: Identify Changed Files
15
+
16
+ ```bash
17
+ git diff --stat HEAD
18
+ git diff HEAD
19
+ git ls-files --others --exclude-standard
20
+ ```
21
+
22
+ Read each changed or new file in its entirety — not just the diff.
23
+
24
+ ## Step 3: Analyze for Issues
25
+
26
+ For each changed file, look for:
27
+
28
+ **1. Logic Errors**
29
+ - Off-by-one errors, incorrect conditionals
30
+ - Missing error handling, unhandled edge cases
31
+ - Race conditions or async issues
32
+
33
+ **2. Security Issues**
34
+ - Exposed secrets or API keys
35
+ - SQL/command injection vulnerabilities
36
+ - Insecure data handling or missing input validation
37
+ - XSS vulnerabilities (frontend)
38
+
39
+ **3. Performance Problems**
40
+ - Unnecessary re-renders (React)
41
+ - N+1 queries or redundant API calls
42
+ - Memory leaks
43
+
44
+ **4. Code Quality**
45
+ - DRY violations
46
+ - Poor naming or overly complex functions
47
+ - Missing TypeScript types or `any` usage
48
+
49
+ **5. Pattern Adherence**
50
+ - Follows project conventions from CLAUDE.md
51
+ - Consistent with existing codebase style
52
+
53
+ ## Step 4: Verify Issues Are Real
54
+
55
+ Before reporting, confirm each issue is legitimate:
56
+ - Run relevant tests if applicable
57
+ - Check if the pattern is intentional based on context
58
+
59
+ ## Step 5: Output Report
60
+
61
+ Save to `.agents/code-reviews/[descriptive-name].md`
62
+
63
+ **Format for each issue:**
64
+ ```
65
+ severity: critical | high | medium | low
66
+ file: path/to/file.ts
67
+ line: 42
68
+ issue: [one-line description]
69
+ detail: [why this is a problem]
70
+ suggestion: [how to fix it]
71
+ ```
72
+
73
+ If no issues found: "Code review passed. No technical issues detected."
74
+
75
+ **Rules:**
76
+ - Be specific — line numbers, not vague complaints
77
+ - Focus on real bugs, not style preferences (linting handles that)
78
+ - Flag security issues as `critical`
79
+ - Suggest fixes, don't just identify problems
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: hopla-execution-report
3
+ description: Generates an implementation report documenting what was built. Use when the user says "generate the report", "genera el reporte", "documenta lo implementado", "execution report", "document what was done", "write the implementation report", or after finishing a feature before committing.
4
+ ---
5
+
6
+ Review and document the implementation you just completed. Run this immediately after finishing a feature — before committing or starting the next task.
7
+
8
+ ## Step 1: Gather Implementation Data
9
+
10
+ ```bash
11
+ git diff HEAD --stat
12
+ git diff HEAD
13
+ git ls-files --others --exclude-standard
14
+ ```
15
+
16
+ ## Step 2: Generate Report
17
+
18
+ Save to: `.agents/execution-reports/[feature-name].md`
19
+
20
+ Use the following structure:
21
+
22
+ ---
23
+
24
+ ### Meta Information
25
+
26
+ - **Plan file:** [path to the plan that guided this implementation]
27
+ - **Files added:** [list with paths]
28
+ - **Files modified:** [list with paths]
29
+ - **Lines changed:** +X -Y
30
+
31
+ ### Validation Results
32
+
33
+ - Syntax & Linting: ✓/✗ [details if failed]
34
+ - Type Checking: ✓/✗ [details if failed]
35
+ - Unit Tests: ✓/✗ [X passed, Y failed]
36
+ - Integration Tests: ✓/✗ [X passed, Y failed]
37
+
38
+ ### What Went Well
39
+
40
+ List specific things that worked smoothly:
41
+ - [concrete examples]
42
+
43
+ ### Challenges Encountered
44
+
45
+ List specific difficulties encountered:
46
+ - [what was difficult and why]
47
+
48
+ ### Divergences from Plan
49
+
50
+ For each divergence from the original plan:
51
+
52
+ **[Divergence Title]**
53
+ - **Planned:** [what the plan specified]
54
+ - **Actual:** [what was implemented instead]
55
+ - **Reason:** [why this divergence occurred]
56
+ - **Type:** Better approach found | Plan assumption wrong | Security concern | Performance issue | Other
57
+
58
+ ### Skipped Items
59
+
60
+ List anything from the plan that was not implemented:
61
+ - [what was skipped] — Reason: [why]
62
+
63
+ ### Recommendations
64
+
65
+ Based on this implementation, what should change for next time?
66
+ - Plan command improvements: [suggestions]
67
+ - Execute command improvements: [suggestions]
68
+ - CLAUDE.md additions: [suggestions]
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: hopla-git
3
+ description: Handles git operations: creating commits, making pull requests, pushing branches. Use when the user asks to commit, create a commit, save changes to git, make a PR, create a pull request, push the branch, or any git workflow action.
4
+ ---
5
+
6
+ Detect the user's intent and execute the appropriate git workflow.
7
+
8
+ ## Intent Detection
9
+
10
+ **If the user wants to commit** (keywords: "commit", "comitea", "guarda los cambios", "save changes", "crear commit", "hacer commit"):
11
+ - Read and follow the instructions in `commit.md` (located in the same directory as this skill)
12
+
13
+ **If the user wants to create a PR or push** (keywords: "PR", "pull request", "crea un PR", "abre un PR", "push", "merge request"):
14
+ - Read and follow the instructions in `pr.md` (located in the same directory as this skill)
15
+
16
+ **If unclear**, ask the user one short question: "¿Commit o Pull Request?" / "Commit or Pull Request?"
17
+
18
+ ## File References
19
+
20
+ The full step-by-step instructions for each workflow are in:
21
+ - `~/.claude/skills/hopla-git/commit.md` — conventional commit with Git Flow awareness
22
+ - `~/.claude/skills/hopla-git/pr.md` — GitHub PR creation with structured description
23
+
24
+ Read the relevant file now and follow its instructions completely.
@@ -0,0 +1,57 @@
1
+ # Hopla Git Commit — Full Workflow
2
+
3
+ Review the current git state and create an appropriate conventional commit.
4
+
5
+ ## Step 1: Gather Context
6
+
7
+ Run these commands to understand what changed:
8
+
9
+ ```bash
10
+ git status
11
+ git diff --staged
12
+ git diff
13
+ git log --oneline -5
14
+ ```
15
+
16
+ ## Step 2: Analyze Changes
17
+
18
+ - Identify what was added, modified, or deleted
19
+ - Determine the appropriate commit type: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `style`
20
+ - Identify the scope if relevant (e.g., `auth`, `api`, `ui`)
21
+ - Check current branch — confirm it follows Git Flow naming (`feature/`, `fix/`, `hotfix/`, `develop`, `dev`)
22
+
23
+ ## Step 3: Stage Files
24
+
25
+ Stage only the relevant files for this commit (avoid `git add -A` unless all changes belong together):
26
+
27
+ ```bash
28
+ git add <specific files>
29
+ ```
30
+
31
+ ## Step 4: Propose Commit
32
+
33
+ Present the proposed commit message to the user **before executing**:
34
+
35
+ > "Proposed commit:
36
+ > `feat(products): add price filter to search endpoint`
37
+ >
38
+ > Files included: [list files]
39
+ > Shall I proceed?"
40
+
41
+ Wait for explicit approval before running `git commit`.
42
+
43
+ ## Step 5: Execute Commit
44
+
45
+ Once approved, create the commit:
46
+
47
+ ```bash
48
+ git commit -m "<type>(<scope>): <description>"
49
+ ```
50
+
51
+ ## Step 6: Push Reminder
52
+
53
+ After committing, remind the user:
54
+
55
+ > "Commit created locally. Do you want to push to `origin/<branch>`?"
56
+
57
+ **Never push automatically** — wait for explicit confirmation.
@@ -0,0 +1,79 @@
1
+ # Hopla Git PR — Full Workflow
2
+
3
+ Create a Pull Request on GitHub for the current branch.
4
+
5
+ ## Step 1: Gather Context
6
+
7
+ ```bash
8
+ git status
9
+ git branch --show-current
10
+ git log --oneline origin/$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null | sed 's|.*/||' || echo 'develop')..HEAD
11
+ git diff --stat origin/$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null | sed 's|.*/||' || echo 'develop')..HEAD
12
+ ```
13
+
14
+ Read the following if they exist:
15
+ - The plan file in `.agents/plans/` related to this feature
16
+ - `CLAUDE.md` — for project context
17
+
18
+ ## Step 2: Determine Base Branch
19
+
20
+ - If the user specified a base branch, use it
21
+ - Otherwise default to `develop` (or `dev` if that's what the project uses)
22
+ - If on `main` or `develop` directly, warn the user: "You're on `[branch]` — PRs should come from feature branches."
23
+
24
+ ## Step 3: Check Push Status
25
+
26
+ ```bash
27
+ git status
28
+ ```
29
+
30
+ If the branch hasn't been pushed yet:
31
+ > "Branch not pushed yet. Push to origin first?"
32
+
33
+ Wait for confirmation before pushing:
34
+ ```bash
35
+ git push -u origin <branch>
36
+ ```
37
+
38
+ ## Step 4: Build PR Description
39
+
40
+ Using the commits and plan context, draft:
41
+
42
+ **Title:** `[type(scope)]: short description` — match the main commit or feature name, max 70 chars
43
+
44
+ **Body:**
45
+ ```markdown
46
+ ## Summary
47
+ - [What was built — 2-3 bullets max]
48
+
49
+ ## Changes
50
+ - [Key files modified and why]
51
+
52
+ ## Test Plan
53
+ - [ ] [How to verify this works]
54
+ - [ ] [Edge cases to check]
55
+
56
+ ## Related
57
+ - Plan: `.agents/plans/[feature-name].md` (if exists)
58
+ ```
59
+
60
+ ## Step 5: Propose and Confirm
61
+
62
+ Show the proposed PR title and body to the user:
63
+ > "Proposed PR:
64
+ > Title: `[title]`
65
+ > Base: `[base branch]`
66
+ > [body preview]
67
+ > Shall I create it?"
68
+
69
+ Wait for explicit approval before creating.
70
+
71
+ ## Step 6: Create PR
72
+
73
+ ```bash
74
+ gh pr create --title "[title]" --body "[body]" --base [base-branch]
75
+ ```
76
+
77
+ After creating, show the PR URL to the user.
78
+
79
+ **Never merge automatically** — the PR is for human review.
@@ -0,0 +1,59 @@
1
+ ---
2
+ name: hopla-prime
3
+ description: Orients Claude in a project at the start of a session. Use when the user says "orient yourself", "get oriented", "prime yourself", "ponte al día", "qué es este proyecto", "what is this project", "load context", or asks Claude to familiarize itself with the codebase before starting work.
4
+ ---
5
+
6
+ Get oriented in this project before doing any work.
7
+
8
+ ## Step 1: Project Structure
9
+
10
+ Use the Glob tool to list project files (up to 60):
11
+ - Pattern: `**/*` with head_limit: 60
12
+
13
+ Use the Glob tool to find key config files:
14
+ - `**/CLAUDE.md`
15
+ - `**/AGENTS.md`
16
+ - `**/README.md`
17
+
18
+ ## Step 2: Read Key Files
19
+
20
+ Read in this order:
21
+ 1. `CLAUDE.md` or `AGENTS.md` at project root (project-specific rules)
22
+ 2. `README.md` (project overview)
23
+ 3. `package.json` or `pyproject.toml` (dependencies and scripts)
24
+
25
+ ## Step 3: Understand Git State
26
+
27
+ ```bash
28
+ git branch --show-current
29
+ git log --oneline -10
30
+ git status
31
+ ```
32
+
33
+ ## Step 4: Check Pending Work
34
+
35
+ Use the Glob tool to check for pending plans:
36
+ - Pattern: `.agents/plans/*.md`
37
+
38
+ If `.agents/plans/` exists, identify:
39
+ - `.draft.md` files — unfinished drafts waiting for review
40
+ - `.md` files (without `.draft`) — finalized plans ready to execute
41
+
42
+ ## Step 5: Summary Report
43
+
44
+ Write a short, conversational message addressed directly to the user. Mention:
45
+ - What the project is and what it does
46
+ - The current branch and what it's for
47
+ - Whether there are uncommitted changes or pending work
48
+ - The command to start the project (if available)
49
+
50
+ If there are pending plans, list them clearly after the prose summary:
51
+ ```
52
+ Pending plans:
53
+ - inventory-page.draft.md ← draft, not finalized yet
54
+ - add-user-authentication.md ← ready to execute with /hopla-execute
55
+ ```
56
+
57
+ End with a sentence like: "Listo para continuar — ¿por dónde empezamos?" or "All caught up — what are we working on today?" depending on the language the user writes in.
58
+
59
+ Do NOT use headers in the prose summary. Write it as natural, friendly prose, then the pending plans list if applicable.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hopla/claude-setup",
3
- "version": "1.3.4",
3
+ "version": "1.4.0",
4
4
  "description": "Hopla team agentic coding system for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {