start-vibing 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/package.json +1 -1
  2. package/template/.claude/CLAUDE.md +129 -168
  3. package/template/.claude/agents/analyzer.md +0 -14
  4. package/template/.claude/agents/commit-manager.md +0 -19
  5. package/template/.claude/agents/documenter.md +0 -10
  6. package/template/.claude/agents/domain-updater.md +194 -200
  7. package/template/.claude/agents/final-validator.md +0 -18
  8. package/template/.claude/agents/orchestrator.md +36 -34
  9. package/template/.claude/agents/quality-checker.md +0 -24
  10. package/template/.claude/agents/research.md +299 -262
  11. package/template/.claude/agents/security-auditor.md +1 -14
  12. package/template/.claude/agents/tester.md +0 -8
  13. package/template/.claude/agents/ui-ux-reviewer.md +80 -18
  14. package/template/.claude/commands/feature.md +48 -102
  15. package/template/.claude/config/README.md +30 -30
  16. package/template/.claude/config/project-config.json +53 -53
  17. package/template/.claude/config/quality-gates.json +46 -46
  18. package/template/.claude/config/security-rules.json +45 -45
  19. package/template/.claude/config/testing-config.json +168 -168
  20. package/template/.claude/hooks/SETUP.md +52 -181
  21. package/template/.claude/hooks/user-prompt-submit.py +184 -46
  22. package/template/.claude/settings.json +0 -39
  23. package/template/.claude/skills/codebase-knowledge/SKILL.md +145 -145
  24. package/template/.claude/skills/codebase-knowledge/domains/claude-system.md +260 -321
  25. package/template/.claude/skills/docs-tracker/SKILL.md +239 -239
  26. package/template/.claude/skills/final-check/SKILL.md +284 -284
  27. package/template/.claude/skills/quality-gate/SKILL.md +278 -278
  28. package/template/.claude/skills/research-cache/SKILL.md +207 -207
  29. package/template/.claude/skills/security-scan/SKILL.md +206 -206
  30. package/template/.claude/skills/test-coverage/SKILL.md +441 -441
  31. package/template/.claude/skills/ui-ux-audit/SKILL.md +254 -254
  32. package/template/.claude/config/domain-mapping.json +0 -26
  33. package/template/.claude/hooks/post-tool-use.py +0 -155
  34. package/template/.claude/hooks/pre-tool-use.py +0 -159
  35. package/template/.claude/hooks/stop-validation.py +0 -155
  36. package/template/.claude/hooks/validate-commit.py +0 -200
  37. package/template/.claude/hooks/workflow-manager.py +0 -350
  38. package/template/.claude/workflow-state.schema.json +0 -200
@@ -1,159 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- PreToolUse Hook - File Modification Enforcement
4
-
5
- This hook blocks file modifications unless:
6
- 1. The analyzer agent has approved the file
7
- 2. The file is in the approvedFiles list in workflow-state.json
8
-
9
- Exit codes:
10
- - 0: Allow the operation
11
- - 2: Block the operation (shows stderr to Claude)
12
- """
13
-
14
- import json
15
- import sys
16
- import os
17
- from datetime import datetime
18
- from pathlib import Path
19
-
20
- # Get project directory
21
- PROJECT_DIR = os.environ.get('CLAUDE_PROJECT_DIR', os.getcwd())
22
- WORKFLOW_STATE_PATH = Path(PROJECT_DIR) / '.claude' / 'workflow-state.json'
23
-
24
- # Tools that modify files
25
- FILE_MODIFY_TOOLS = {'Edit', 'Write', 'NotebookEdit'}
26
-
27
- # Files always allowed (config, etc)
28
- ALWAYS_ALLOWED = {
29
- '.claude/workflow-state.json',
30
- '.claude/hooks/',
31
- 'package-lock.json',
32
- 'node_modules/',
33
- }
34
-
35
- # Files always blocked
36
- ALWAYS_BLOCKED = {
37
- '.env',
38
- '.env.local',
39
- '.env.production',
40
- 'credentials.json',
41
- 'secrets/',
42
- }
43
-
44
-
45
- def load_workflow_state():
46
- """Load current workflow state"""
47
- if not WORKFLOW_STATE_PATH.exists():
48
- return None
49
- try:
50
- with open(WORKFLOW_STATE_PATH) as f:
51
- return json.load(f)
52
- except (json.JSONDecodeError, IOError):
53
- return None
54
-
55
-
56
- def is_file_approved(file_path: str, state: dict) -> tuple[bool, str]:
57
- """Check if file is approved for modification"""
58
-
59
- # Normalize path
60
- file_path = file_path.replace('\\', '/')
61
-
62
- # Always blocked files
63
- for blocked in ALWAYS_BLOCKED:
64
- if blocked in file_path:
65
- return False, f"BLOCKED: {file_path} is in the always-blocked list (sensitive file)"
66
-
67
- # Always allowed files
68
- for allowed in ALWAYS_ALLOWED:
69
- if allowed in file_path:
70
- return True, "Allowed (system file)"
71
-
72
- # No active task - block all modifications
73
- if not state or not state.get('currentTask'):
74
- return False, f"""BLOCKED: No active task in workflow-state.json
75
-
76
- To modify files, you must first:
77
- 1. Start a task via orchestrator agent
78
- 2. Run analyzer agent to approve files for modification
79
- 3. The file '{file_path}' must be in the approvedFiles list
80
-
81
- Current state: No task active. Start with orchestrator first."""
82
-
83
- task = state['currentTask']
84
- approved_files = task.get('approvedFiles', [])
85
-
86
- # Check if analyzer has run
87
- agents = task.get('agents', {})
88
- analyzer = agents.get('analyzer', {})
89
-
90
- if not analyzer.get('executed'):
91
- return False, f"""BLOCKED: Analyzer agent has not executed yet
92
-
93
- To modify '{file_path}', you must:
94
- 1. Run the analyzer agent first
95
- 2. Analyzer will determine which files can be modified
96
- 3. Add approved files to workflow-state.json
97
-
98
- Current task: {task.get('description', 'Unknown')}
99
- Analyzer status: Not executed"""
100
-
101
- # Check if file is in approved list
102
- for approved in approved_files:
103
- # Support glob patterns
104
- if approved.endswith('*'):
105
- if file_path.startswith(approved[:-1]):
106
- return True, f"Approved (matches pattern: {approved})"
107
- elif approved == file_path or file_path.endswith(approved):
108
- return True, f"Approved by analyzer"
109
-
110
- return False, f"""BLOCKED: File not in approved list
111
-
112
- File: {file_path}
113
- Task: {task.get('description', 'Unknown')}
114
-
115
- Approved files for this task:
116
- {chr(10).join(f' - {f}' for f in approved_files) if approved_files else ' (none)'}
117
-
118
- To modify this file, run analyzer again and add it to approvedFiles."""
119
-
120
-
121
- def main():
122
- # Read hook input from stdin
123
- try:
124
- hook_input = json.load(sys.stdin)
125
- except json.JSONDecodeError:
126
- # Can't parse input, allow by default
127
- sys.exit(0)
128
-
129
- tool_name = hook_input.get('tool_name', '')
130
- tool_input = hook_input.get('tool_input', {})
131
-
132
- # Only check file modification tools
133
- if tool_name not in FILE_MODIFY_TOOLS:
134
- sys.exit(0)
135
-
136
- # Get file path from tool input
137
- file_path = tool_input.get('file_path', tool_input.get('notebook_path', ''))
138
-
139
- if not file_path:
140
- sys.exit(0)
141
-
142
- # Load workflow state
143
- state = load_workflow_state()
144
-
145
- # Check if file is approved
146
- approved, message = is_file_approved(file_path, state)
147
-
148
- if approved:
149
- # Log the approval (optional verbose output)
150
- # print(f"✓ {message}", file=sys.stderr)
151
- sys.exit(0)
152
- else:
153
- # Block with error message
154
- print(message, file=sys.stderr)
155
- sys.exit(2)
156
-
157
-
158
- if __name__ == '__main__':
159
- main()
@@ -1,155 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Stop Hook - Workflow Validation Before Stopping
4
-
5
- This hook validates that the workflow was properly executed before
6
- allowing Claude to stop. If validation fails, Claude is forced to continue.
7
-
8
- Exit codes:
9
- - 0: Allow stop (or output JSON to block)
10
- """
11
-
12
- import json
13
- import sys
14
- import os
15
- from pathlib import Path
16
-
17
- PROJECT_DIR = os.environ.get('CLAUDE_PROJECT_DIR', os.getcwd())
18
- WORKFLOW_STATE_PATH = Path(PROJECT_DIR) / '.claude' / 'workflow-state.json'
19
-
20
-
21
- def load_workflow_state():
22
- """Load current workflow state"""
23
- if not WORKFLOW_STATE_PATH.exists():
24
- return None
25
- try:
26
- with open(WORKFLOW_STATE_PATH) as f:
27
- return json.load(f)
28
- except (json.JSONDecodeError, IOError):
29
- return None
30
-
31
-
32
- def validate_workflow(state: dict) -> tuple[bool, list[str]]:
33
- """Validate workflow completion"""
34
- issues = []
35
-
36
- if not state or not state.get('currentTask'):
37
- # No task, allow stop
38
- return True, []
39
-
40
- task = state['currentTask']
41
- task_type = task.get('type', 'feature')
42
- agents = task.get('agents', {})
43
- modified_files = task.get('modifiedFiles', [])
44
-
45
- # Skip validation for research/config tasks
46
- if task_type in ['research', 'config']:
47
- return True, []
48
-
49
- # Check required agents executed
50
- required_agents = {
51
- 'feature': ['orchestrator', 'analyzer', 'research', 'tester', 'securityAuditor', 'qualityChecker', 'finalValidator', 'domainUpdater'],
52
- 'fix': ['analyzer', 'research', 'tester', 'securityAuditor', 'qualityChecker', 'finalValidator', 'domainUpdater'],
53
- 'refactor': ['analyzer', 'tester', 'qualityChecker', 'finalValidator', 'domainUpdater'],
54
- }
55
-
56
- for agent in required_agents.get(task_type, []):
57
- agent_status = agents.get(agent, {})
58
- if not agent_status.get('executed'):
59
- issues.append(f"Agent '{agent}' has not executed")
60
- elif agent_status.get('result') == 'vetoed':
61
- issues.append(f"Agent '{agent}' VETOED - must resolve before stopping")
62
-
63
- # Check if files were modified without tests
64
- if modified_files and task_type in ['feature', 'fix']:
65
- tests_created = task.get('testsCreated', [])
66
- # Exclude: tests, specs, docs, markdown, and .claude config files
67
- source_files = [m for m in modified_files if not any(
68
- p in m['path'].lower() for p in ['test', 'spec', '.md', 'docs/', '.claude/']
69
- )]
70
-
71
- if source_files and not tests_created:
72
- issues.append(f"Modified {len(source_files)} source file(s) but no tests created")
73
-
74
- # Check documentation (skip for .claude config files)
75
- if modified_files and task_type == 'feature':
76
- non_config_files = [m for m in modified_files if '.claude/' not in m['path']]
77
- if non_config_files:
78
- docs_updated = task.get('docsUpdated', [])
79
- if not docs_updated:
80
- issues.append("No documentation updated for feature")
81
-
82
- # Check quality gates
83
- quality = task.get('qualityGates', {})
84
- for gate in ['typecheck', 'lint', 'build']:
85
- gate_result = quality.get(gate, {})
86
- if gate_result and not gate_result.get('passed'):
87
- issues.append(f"Quality gate '{gate}' failed")
88
-
89
- # Check security audit
90
- security = task.get('securityAudit', {})
91
- if security.get('result') == 'vetoed':
92
- issues.append("Security audit VETOED - must resolve vulnerabilities")
93
-
94
- # Check final validation
95
- final = task.get('finalValidation', {})
96
- if final.get('executed') and not final.get('readyToCommit'):
97
- issues.append("Final validation not approved for commit")
98
-
99
- # Check domain-updater (critical for knowledge retention)
100
- domain_updater = agents.get('domainUpdater', {})
101
- if modified_files and not domain_updater.get('executed'):
102
- issues.append("Domain updater has not run - domains must be updated with session learnings")
103
-
104
- # Check commit-manager (critical for persisting changes - FINAL step)
105
- commit_manager = agents.get('commitManager', {})
106
- if domain_updater.get('executed') and not commit_manager.get('executed'):
107
- issues.append("Commit-manager has not run - changes must be committed before session ends")
108
-
109
- return len(issues) == 0, issues
110
-
111
-
112
- def main():
113
- # Read hook input
114
- try:
115
- hook_input = json.load(sys.stdin)
116
- except json.JSONDecodeError:
117
- sys.exit(0)
118
-
119
- # Load state
120
- state = load_workflow_state()
121
-
122
- # Validate
123
- is_valid, issues = validate_workflow(state)
124
-
125
- if is_valid:
126
- # Allow stop
127
- sys.exit(0)
128
- else:
129
- # Block stop and force continuation
130
- output = {
131
- "decision": "block",
132
- "reason": f"""WORKFLOW INCOMPLETE - Cannot stop yet.
133
-
134
- Issues found:
135
- {chr(10).join(f' ❌ {issue}' for issue in issues)}
136
-
137
- You must complete these steps before stopping:
138
- 1. Execute all required agents
139
- 2. Resolve any VETOs
140
- 3. Create tests for modified files
141
- 4. Update documentation
142
- 5. Pass all quality gates
143
- 6. Get final validation approval
144
- 7. Run domain-updater to update domains with session learnings
145
- 8. Run commit-manager to commit changes (FINAL step)
146
-
147
- Resume the workflow to address these issues."""
148
- }
149
-
150
- print(json.dumps(output))
151
- sys.exit(0)
152
-
153
-
154
- if __name__ == '__main__':
155
- main()
@@ -1,200 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Husky Pre-Commit Hook - Workflow Validation
4
-
5
- This script is called by Husky before allowing a commit.
6
- It validates that:
7
- 1. The workflow was properly executed
8
- 2. All modified files were approved
9
- 3. Tests were created for source files
10
- 4. Documentation was updated
11
- 5. Quality gates passed
12
- 6. Final validation approved
13
-
14
- Exit codes:
15
- - 0: Allow commit
16
- - 1: Block commit with error message
17
- """
18
-
19
- import json
20
- import sys
21
- import os
22
- import subprocess
23
- from pathlib import Path
24
-
25
- PROJECT_DIR = os.environ.get('CLAUDE_PROJECT_DIR', os.getcwd())
26
- WORKFLOW_STATE_PATH = Path(PROJECT_DIR) / '.claude' / 'workflow-state.json'
27
-
28
-
29
- def get_staged_files():
30
- """Get list of staged files"""
31
- try:
32
- result = subprocess.run(
33
- ['git', 'diff', '--cached', '--name-only'],
34
- capture_output=True,
35
- text=True,
36
- check=True
37
- )
38
- return [f.strip() for f in result.stdout.strip().split('\n') if f.strip()]
39
- except subprocess.CalledProcessError:
40
- return []
41
-
42
-
43
- def load_workflow_state():
44
- """Load current workflow state"""
45
- if not WORKFLOW_STATE_PATH.exists():
46
- return None
47
- try:
48
- with open(WORKFLOW_STATE_PATH) as f:
49
- return json.load(f)
50
- except (json.JSONDecodeError, IOError):
51
- return None
52
-
53
-
54
- def validate_commit(state: dict, staged_files: list) -> tuple[bool, list[str]]:
55
- """Validate that commit is allowed"""
56
- errors = []
57
-
58
- # Skip validation if no staged files
59
- if not staged_files:
60
- return True, []
61
-
62
- # Skip if only workflow state files
63
- non_workflow_files = [f for f in staged_files if '.claude/' not in f]
64
- if not non_workflow_files:
65
- return True, []
66
-
67
- # Check workflow state exists
68
- if not state:
69
- errors.append("No workflow-state.json found - did you use the agent workflow?")
70
- errors.append("Run the orchestrator agent to start a task before committing.")
71
- return False, errors
72
-
73
- task = state.get('currentTask')
74
- if not task:
75
- errors.append("No active task in workflow state")
76
- errors.append("The agent workflow was not properly started")
77
- return False, errors
78
-
79
- # Check all staged files were in workflow
80
- modified_in_workflow = [m['path'] for m in task.get('modifiedFiles', [])]
81
- approved_files = task.get('approvedFiles', [])
82
-
83
- for staged in staged_files:
84
- # Skip workflow files
85
- if '.claude/' in staged or staged.endswith('.md'):
86
- continue
87
-
88
- # Check if file was tracked
89
- if staged not in modified_in_workflow:
90
- # Check if matches approved pattern
91
- matched = False
92
- for approved in approved_files:
93
- if approved.endswith('*') and staged.startswith(approved[:-1]):
94
- matched = True
95
- break
96
- if staged.endswith(approved) or staged == approved:
97
- matched = True
98
- break
99
-
100
- if not matched:
101
- errors.append(f"File '{staged}' was not tracked in workflow")
102
- errors.append(" This file was modified outside the agent workflow")
103
-
104
- # Check agents executed
105
- agents = task.get('agents', {})
106
- task_type = task.get('type', 'feature')
107
-
108
- # Required agents by task type
109
- required = {
110
- 'feature': ['analyzer', 'tester', 'securityAuditor', 'qualityChecker', 'finalValidator'],
111
- 'fix': ['analyzer', 'tester', 'qualityChecker', 'finalValidator'],
112
- 'refactor': ['analyzer', 'qualityChecker', 'finalValidator'],
113
- 'config': ['qualityChecker'],
114
- }
115
-
116
- for agent in required.get(task_type, []):
117
- agent_status = agents.get(agent, {})
118
- if not agent_status.get('executed'):
119
- errors.append(f"Required agent '{agent}' was not executed")
120
- elif agent_status.get('result') == 'vetoed':
121
- errors.append(f"Agent '{agent}' VETOED this task - resolve before committing")
122
-
123
- # Check tests
124
- if task_type in ['feature', 'fix']:
125
- source_files = [f for f in staged_files if not any(
126
- p in f.lower() for p in ['test', 'spec', '.md', 'docs/', '.json']
127
- )]
128
- tests_created = task.get('testsCreated', [])
129
-
130
- if source_files and not tests_created:
131
- errors.append(f"Modified {len(source_files)} source file(s) but no tests were created")
132
- errors.append(" Run the tester agent to create tests")
133
-
134
- # Check quality gates
135
- quality = task.get('qualityGates', {})
136
- for gate in ['typecheck', 'lint']:
137
- gate_result = quality.get(gate, {})
138
- if gate_result.get('passed') is False:
139
- errors.append(f"Quality gate '{gate}' failed")
140
-
141
- # Check security audit
142
- security = task.get('securityAudit', {})
143
- if security.get('result') == 'vetoed':
144
- errors.append("Security audit VETOED - vulnerabilities must be fixed")
145
-
146
- # Check final validation
147
- final = task.get('finalValidation', {})
148
- if not final.get('readyToCommit'):
149
- if not final.get('executed'):
150
- errors.append("Final validation was not executed")
151
- errors.append(" Run the final-validator agent before committing")
152
- else:
153
- errors.append("Final validation did not approve commit")
154
- violations = final.get('violations', [])
155
- for v in violations[:5]: # Show first 5
156
- errors.append(f" - {v}")
157
-
158
- return len(errors) == 0, errors
159
-
160
-
161
- def main():
162
- print("🔍 Validating workflow compliance...\n")
163
-
164
- # Get staged files
165
- staged_files = get_staged_files()
166
-
167
- if not staged_files:
168
- print("✅ No files staged for commit")
169
- sys.exit(0)
170
-
171
- # Load state
172
- state = load_workflow_state()
173
-
174
- # Validate
175
- is_valid, errors = validate_commit(state, staged_files)
176
-
177
- if is_valid:
178
- print("✅ Workflow validation passed")
179
- print(f" {len(staged_files)} file(s) ready to commit")
180
- sys.exit(0)
181
- else:
182
- print("❌ COMMIT BLOCKED - Workflow validation failed\n")
183
- print("Errors found:")
184
- for error in errors:
185
- print(f" {error}")
186
-
187
- print("\n" + "=" * 50)
188
- print("How to fix:")
189
- print("1. Run the complete agent workflow (orchestrator → ... → final-validator)")
190
- print("2. Ensure all agents executed and approved")
191
- print("3. Create tests for new/modified code")
192
- print("4. Pass all quality gates")
193
- print("5. Get final validation approval")
194
- print("=" * 50)
195
-
196
- sys.exit(1)
197
-
198
-
199
- if __name__ == '__main__':
200
- main()