cc-dev-template 0.1.27 → 0.1.29

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/bin/install.js CHANGED
@@ -96,11 +96,21 @@ if (fs.existsSync(skillsDir)) {
96
96
  console.log('\nHooks:');
97
97
  const hooksDir = path.join(SRC_DIR, 'hooks');
98
98
  if (fs.existsSync(hooksDir)) {
99
- const hookScripts = fs.readdirSync(hooksDir).filter(f => f.endsWith('.sh'));
99
+ const hookShellScripts = fs.readdirSync(hooksDir).filter(f => f.endsWith('.sh'));
100
+ const hookJsScripts = fs.readdirSync(hooksDir).filter(f => f.endsWith('.js'));
100
101
  const hookConfigs = fs.readdirSync(hooksDir).filter(f => f.endsWith('.json'));
101
102
 
102
103
  // Copy shell scripts and make executable
103
- hookScripts.forEach(file => {
104
+ hookShellScripts.forEach(file => {
105
+ const src = path.join(hooksDir, file);
106
+ const dest = path.join(CLAUDE_DIR, 'hooks', file);
107
+ fs.copyFileSync(src, dest);
108
+ fs.chmodSync(dest, 0o755); // Make executable
109
+ console.log(` ${file}`);
110
+ });
111
+
112
+ // Copy JS scripts and make executable
113
+ hookJsScripts.forEach(file => {
104
114
  const src = path.join(hooksDir, file);
105
115
  const dest = path.join(CLAUDE_DIR, 'hooks', file);
106
116
  fs.copyFileSync(src, dest);
@@ -115,7 +125,8 @@ if (fs.existsSync(hooksDir)) {
115
125
  fs.copyFileSync(src, dest);
116
126
  });
117
127
 
118
- console.log(`✓ ${hookScripts.length} hooks installed`);
128
+ const totalHooks = hookShellScripts.length + hookJsScripts.length;
129
+ console.log(`✓ ${totalHooks} hooks installed`);
119
130
  } else {
120
131
  console.log(' No hooks to install');
121
132
  }
@@ -229,7 +240,8 @@ if (fs.existsSync(mergeSettingsPath)) {
229
240
  { file: 'statusline-config.json', name: 'Custom status line' },
230
241
  { file: 'orchestration-hook.json', name: 'Orchestration guidance hook' },
231
242
  { file: 'bash-overflow-hook.json', name: 'Bash overflow guard hook' },
232
- { file: 'bash-precheck-hook.json', name: 'Bash precheck hook' }
243
+ { file: 'bash-precheck-hook.json', name: 'Bash precheck hook' },
244
+ { file: 'plan-agent-hook.json', name: 'Plan agent context injection hook' }
233
245
  ];
234
246
 
235
247
  configs.forEach(({ file, name }) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-dev-template",
3
- "version": "0.1.27",
3
+ "version": "0.1.29",
4
4
  "description": "Structured AI-assisted development framework for Claude Code",
5
5
  "bin": {
6
6
  "cc-dev-template": "./bin/install.js"
@@ -9,14 +9,28 @@ cat << 'EOF'
9
9
  <orchestration-guidance>
10
10
  You are an ORCHESTRATOR, not an implementer. Your main thread is for coordination only.
11
11
 
12
- DELEGATE AGGRESSIVELY:
13
- - Use Task with model: haiku for read-only exploration: file search, code understanding, research
14
- - Use Task with model: opus for ALL reasoning, code changes, implementation, refactors
15
- - Default to opus when uncertain—it handles complexity better
12
+ ## THE WORKFLOW: Explore → Plan → Execute
13
+
14
+ Never make code changes without a plan. Follow this sequence:
15
+
16
+ 1. **EXPLORE** - Use Task sub-agents to understand current state: file search, code patterns, dependencies
17
+ 2. **PLAN** - Use Task with subagent_type: "Plan" to design the change based on current state
18
+ 3. **EXECUTE** - Use Task sub-agents to implement the approved plan
19
+
20
+ ## DELEGATE AGGRESSIVELY
21
+
22
+ - Use Task sub-agents for ALL exploration and implementation work
23
+ - Use Task with subagent_type: "Plan" before any non-trivial changes
16
24
  - Launch multiple agents in parallel when tasks are independent
17
25
  - The only tools you use directly: Task, TodoWrite, AskUserQuestion
18
26
 
19
- DISPATCH WITH CLARITY - Every sub-agent prompt must include:
27
+ ## SPECIALIZED AGENTS
28
+
29
+ **execution-agent is ONLY for the /prime orchestration skill workflow.** It expects plan.yaml context and specific execution semantics. For general task delegation, use generic Task sub-agents without subagent_type.
30
+
31
+ ## DISPATCH WITH CLARITY
32
+
33
+ Every sub-agent prompt must include:
20
34
  1. Concrete objective: What specific outcome is needed
21
35
  2. Acceptance criteria: How to verify the task is complete
22
36
  3. Assumptions: Context the agent should validate before proceeding
@@ -24,13 +38,16 @@ DISPATCH WITH CLARITY - Every sub-agent prompt must include:
24
38
 
25
39
  This ensures smooth feedback: sub-agents surface blockers early rather than going down wrong paths.
26
40
 
27
- YOUR ROLE:
41
+ ## YOUR ROLE
42
+
28
43
  1. Decompose problems into discrete tasks
29
44
  2. Dispatch sub-agents with clear objectives and acceptance criteria
30
45
  3. Verify results meet requirements
31
46
  4. Synthesize findings for the user
32
47
 
33
- SUCCESS LOOKS LIKE: Your main thread has almost no Read, Grep, Glob, Edit, or Write calls. Sub-agents do the work; you orchestrate and verify.
48
+ ## SUCCESS LOOKS LIKE
49
+
50
+ Your main thread has almost no Read, Grep, Glob, Edit, or Write calls. Sub-agents do the work; you orchestrate and verify.
34
51
 
35
52
  ONLY handle directly: Single-command bash (git status, npm test), trivial typo fixes where you already know the exact line.
36
53
  </orchestration-guidance>
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * plan-agent-context.js - PreToolUse hook for Task sub-agents
4
+ *
5
+ * Intercepts ALL Task calls and:
6
+ * 1. Forces model: "opus" on every Task call
7
+ * 2. For Plan agents (subagent_type: "Plan"), also injects ADRs and planning guidance
8
+ */
9
+
10
+ const fs = require('fs');
11
+ const path = require('path');
12
+ const yaml = require('js-yaml');
13
+
14
+ // Read hook input from stdin
15
+ let input = '';
16
+ process.stdin.setEncoding('utf8');
17
+ process.stdin.on('data', chunk => input += chunk);
18
+ process.stdin.on('end', () => {
19
+ try {
20
+ const hookInput = JSON.parse(input);
21
+ const result = processHook(hookInput);
22
+ console.log(JSON.stringify(result));
23
+ } catch (err) {
24
+ // On error, allow the tool call to proceed unchanged
25
+ console.log(JSON.stringify({ decision: "allow" }));
26
+ }
27
+ });
28
+
29
+ function processHook(hookInput) {
30
+ const toolInput = hookInput.tool_input || {};
31
+
32
+ // Base override: force opus model on ALL Task calls
33
+ const updatedInput = {
34
+ ...toolInput,
35
+ model: "opus"
36
+ };
37
+
38
+ // For Plan agent calls, also inject ADRs and planning guidance
39
+ if (toolInput.subagent_type === 'Plan') {
40
+ const adrs = collectADRs();
41
+ const planningGuidance = buildPlanningGuidance(adrs);
42
+ const originalPrompt = toolInput.prompt || '';
43
+ updatedInput.prompt = `${planningGuidance}\n\n---\n\nORIGINAL TASK:\n${originalPrompt}`;
44
+ }
45
+
46
+ return {
47
+ decision: "allow",
48
+ updatedInput
49
+ };
50
+ }
51
+
52
+ function collectADRs() {
53
+ const adrDir = path.join(process.cwd(), '.claude', 'adrs');
54
+ const adrs = [];
55
+
56
+ if (!fs.existsSync(adrDir)) {
57
+ return adrs;
58
+ }
59
+
60
+ const files = fs.readdirSync(adrDir).filter(f => f.endsWith('.yaml'));
61
+
62
+ for (const file of files) {
63
+ try {
64
+ const content = fs.readFileSync(path.join(adrDir, file), 'utf8');
65
+ const adr = yaml.load(content);
66
+ if (adr && adr.status !== 'Superseded') {
67
+ adrs.push({
68
+ id: adr.id,
69
+ title: adr.title,
70
+ description: adr.description,
71
+ constraints: adr.constraints,
72
+ decision: adr.decision
73
+ });
74
+ }
75
+ } catch (err) {
76
+ // Skip malformed ADRs
77
+ }
78
+ }
79
+
80
+ return adrs;
81
+ }
82
+
83
+ function buildPlanningGuidance(adrs) {
84
+ let guidance = `<plan-agent-context>
85
+ ## Planning Guidelines
86
+
87
+ You are creating an implementation plan. Follow these principles:
88
+
89
+ ### Research Before Planning
90
+ - If the plan involves third-party libraries, APIs, or features not yet in the codebase, use WebSearch or WebFetch to get current documentation
91
+ - Do not assume library APIs - verify them with up-to-date sources
92
+ - Check compatibility with the project's infrastructure and existing patterns
93
+
94
+ ### Remove Ambiguity
95
+ - Each step in your plan should be concrete and actionable
96
+ - If requirements are unclear, surface the ambiguity rather than making assumptions
97
+ - Identify decision points that need user input before execution
98
+
99
+ ### ADR Compliance
100
+ The plan must respect these architectural decisions:
101
+
102
+ `;
103
+
104
+ if (adrs.length === 0) {
105
+ guidance += `(No ADRs found in this project)\n`;
106
+ } else {
107
+ for (const adr of adrs) {
108
+ guidance += `### ${adr.id}: ${adr.title}\n`;
109
+ if (adr.description) {
110
+ guidance += `${adr.description.trim()}\n`;
111
+ }
112
+ if (adr.constraints) {
113
+ if (adr.constraints.must && adr.constraints.must.length > 0) {
114
+ guidance += `**MUST:**\n`;
115
+ for (const c of adr.constraints.must) {
116
+ guidance += `- ${c}\n`;
117
+ }
118
+ }
119
+ if (adr.constraints.must_not && adr.constraints.must_not.length > 0) {
120
+ guidance += `**MUST NOT:**\n`;
121
+ for (const c of adr.constraints.must_not) {
122
+ guidance += `- ${c}\n`;
123
+ }
124
+ }
125
+ }
126
+ if (adr.decision) {
127
+ guidance += `**Decision:** ${adr.decision.trim()}\n`;
128
+ }
129
+ guidance += `\n`;
130
+ }
131
+ }
132
+
133
+ guidance += `</plan-agent-context>`;
134
+
135
+ return guidance;
136
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "Task",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "node $HOME/.claude/hooks/plan-agent-context.js"
10
+ }
11
+ ]
12
+ }
13
+ ]
14
+ }
15
+ }