codecruise 0.1.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/LICENSE +21 -0
- package/README.md +111 -0
- package/bin/codecruise.js +68 -0
- package/config/CLAUDE.md +107 -0
- package/config/agents/analyst.md +48 -0
- package/config/agents/architect-reviewer.md +161 -0
- package/config/agents/architect.md +119 -0
- package/config/agents/critic.md +63 -0
- package/config/agents/developer.md +96 -0
- package/config/agents/devops.md +81 -0
- package/config/agents/orchestrator.md +91 -0
- package/config/agents/planner.md +139 -0
- package/config/agents/retro.md +52 -0
- package/config/agents/reviewer.md +101 -0
- package/config/agents/security-reviewer.md +57 -0
- package/config/agents/stack/expo/AGENT.md +473 -0
- package/config/agents/stack/expo/rules/critical.md +427 -0
- package/config/agents/stack/expo/rules/native.md +455 -0
- package/config/agents/stack/expo/rules/navigation.md +445 -0
- package/config/agents/stack/expo/rules/performance.md +415 -0
- package/config/agents/stack/fastify/AGENT.md +397 -0
- package/config/agents/stack/fastify/rules/api-design.md +283 -0
- package/config/agents/stack/fastify/rules/critical.md +232 -0
- package/config/agents/stack/fastify/rules/queues.md +303 -0
- package/config/agents/stack/fastify/rules/security.md +384 -0
- package/config/agents/stack/index.yaml +48 -0
- package/config/agents/stack/nextjs/AGENT.md +421 -0
- package/config/agents/stack/nextjs/rules/components.md +413 -0
- package/config/agents/stack/nextjs/rules/critical.md +391 -0
- package/config/agents/stack/nextjs/rules/performance.md +403 -0
- package/config/agents/stack/nextjs/rules/styling.md +334 -0
- package/config/agents/stack/shared-ts/AGENT.md +384 -0
- package/config/agents/stack/shared-ts/rules/critical.md +315 -0
- package/config/agents/stack/shared-ts/rules/patterns.md +384 -0
- package/config/agents/stack/shared-ts/rules/zod.md +427 -0
- package/config/agents/tester.md +79 -0
- package/config/commands/architect-discuss.md +366 -0
- package/config/commands/architect-list.md +160 -0
- package/config/commands/architect-review.md +111 -0
- package/config/commands/architect.md +118 -0
- package/config/commands/compact.md +118 -0
- package/config/commands/companion.md +279 -0
- package/config/commands/dashboard.md +152 -0
- package/config/commands/doctor.md +227 -0
- package/config/commands/dogfood-report.md +101 -0
- package/config/commands/flags/run-autonomous.md +110 -0
- package/config/commands/flags/run-pause.md +80 -0
- package/config/commands/ingest.md +173 -0
- package/config/commands/init.md +128 -0
- package/config/commands/metrics.md +87 -0
- package/config/commands/parallel.md +320 -0
- package/config/commands/pause.md +55 -0
- package/config/commands/plan-review.md +130 -0
- package/config/commands/plan.md +216 -0
- package/config/commands/production-check.md +308 -0
- package/config/commands/refine.md +323 -0
- package/config/commands/resume.md +72 -0
- package/config/commands/retro.md +121 -0
- package/config/commands/retry.md +75 -0
- package/config/commands/role.md +310 -0
- package/config/commands/run.md +417 -0
- package/config/commands/scope.md +85 -0
- package/config/commands/setup-permissions.md +104 -0
- package/config/commands/skip.md +75 -0
- package/config/commands/spec-forge.md +213 -0
- package/config/commands/spec-help.md +194 -0
- package/config/commands/spec-patch.md +342 -0
- package/config/commands/spec-resolve.md +110 -0
- package/config/commands/spec-review.md +153 -0
- package/config/commands/status.md +114 -0
- package/config/commands/sync.md +131 -0
- package/config/commands/task.md +138 -0
- package/config/commands/verify.md +124 -0
- package/config/hooks/README.md +632 -0
- package/config/hooks/activity-log.sh +187 -0
- package/config/hooks/anti-rationalize.sh +52 -0
- package/config/hooks/capture-verification.sh +112 -0
- package/config/hooks/collect-metrics.sh +135 -0
- package/config/hooks/enforce-file-scope.sh +75 -0
- package/config/hooks/enforce-state-machine.sh +161 -0
- package/config/hooks/enforce-tdd.sh +180 -0
- package/config/hooks/format.sh +40 -0
- package/config/hooks/lib/activity-helpers.sh +162 -0
- package/config/hooks/lib/read-settings.sh +71 -0
- package/config/hooks/load-context-skills.sh +95 -0
- package/config/hooks/notify.sh +81 -0
- package/config/hooks/pre-commit.sample +35 -0
- package/config/hooks/protect-files.sh +63 -0
- package/config/hooks/track-agents.sh +41 -0
- package/config/hooks/track-commands.sh +37 -0
- package/config/hooks/track-enforcement.sh +44 -0
- package/config/hooks/track-ooda.sh +77 -0
- package/config/hooks/validate-commit-msg.sh +35 -0
- package/config/hooks/validate-plan.sh +213 -0
- package/config/hooks/verify-criteria.sh +46 -0
- package/config/hooks/verify-todo-completion.sh +140 -0
- package/config/rules/comments.md +25 -0
- package/config/rules/decision-rules.md +308 -0
- package/config/rules/hygiene.md +247 -0
- package/config/rules/pattern-detection.md +372 -0
- package/config/rules/profiles.md +193 -0
- package/config/rules/recovery.md +83 -0
- package/config/rules/scope-detection.md +213 -0
- package/config/rules/standards.md +127 -0
- package/config/rules/workflow.md +121 -0
- package/config/schemas.md +767 -0
- package/config/settings.json +195 -0
- package/config/skills/backend/SKILL.md +734 -0
- package/config/skills/database/SKILL.md +426 -0
- package/config/skills/frontend/SKILL.md +434 -0
- package/config/skills/git/SKILL.md +396 -0
- package/config/skills/index.yaml +36 -0
- package/config/skills/observability/SKILL.md +430 -0
- package/config/skills/package-dev/SKILL.md +498 -0
- package/config/skills/performance/SKILL.md +378 -0
- package/config/skills/resilience/SKILL.md +573 -0
- package/config/skills/testing/SKILL.md +398 -0
- package/config/skills/testing-patterns/SKILL.md +276 -0
- package/config/skills/typescript/SKILL.md +152 -0
- package/config/templates/CLAUDE.md +70 -0
- package/config/templates/README.md +117 -0
- package/config/templates/steering/adr-template.md +102 -0
- package/config/templates/steering/product.md +60 -0
- package/config/templates/steering/rfc-template.md +159 -0
- package/config/templates/steering/structure.md +146 -0
- package/config/templates/steering/tech.md +85 -0
- package/package.json +40 -0
- package/src/install.js +163 -0
- package/src/report.js +310 -0
package/src/report.js
ADDED
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codecruise report - Generate dogfood analysis report
|
|
3
|
+
*
|
|
4
|
+
* Answers Boris & Peter's questions:
|
|
5
|
+
* 1. Which agents are actually used?
|
|
6
|
+
* 2. How many enforcement blocks?
|
|
7
|
+
* 3. Is OODA meaningful?
|
|
8
|
+
* 4. Which commands matter?
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync } from 'fs';
|
|
12
|
+
import { join } from 'path';
|
|
13
|
+
import { homedir } from 'os';
|
|
14
|
+
import { execSync } from 'child_process';
|
|
15
|
+
|
|
16
|
+
function readJsonl(filepath) {
|
|
17
|
+
if (!existsSync(filepath)) return [];
|
|
18
|
+
try {
|
|
19
|
+
return readFileSync(filepath, 'utf-8')
|
|
20
|
+
.split('\n')
|
|
21
|
+
.filter(line => line.trim())
|
|
22
|
+
.map(line => {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(line);
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
.filter(Boolean);
|
|
30
|
+
} catch {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function countByField(records, field) {
|
|
36
|
+
const counts = {};
|
|
37
|
+
for (const record of records) {
|
|
38
|
+
const value = record[field] || 'unknown';
|
|
39
|
+
counts[value] = (counts[value] || 0) + 1;
|
|
40
|
+
}
|
|
41
|
+
return Object.entries(counts)
|
|
42
|
+
.sort((a, b) => b[1] - a[1])
|
|
43
|
+
.map(([key, count]) => ({ key, count }));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function formatTable(data, total) {
|
|
47
|
+
if (data.length === 0) return '*No data recorded yet.*';
|
|
48
|
+
|
|
49
|
+
let result = '| Item | Count | % |\n|------|-------|---|\n';
|
|
50
|
+
for (const { key, count } of data) {
|
|
51
|
+
const pct = total > 0 ? ((count / total) * 100).toFixed(1) : '0';
|
|
52
|
+
result += `| ${key} | ${count} | ${pct}% |\n`;
|
|
53
|
+
}
|
|
54
|
+
return result;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function getDateRange(records) {
|
|
58
|
+
if (records.length === 0) return 'N/A';
|
|
59
|
+
const timestamps = records
|
|
60
|
+
.map(r => r.timestamp)
|
|
61
|
+
.filter(Boolean)
|
|
62
|
+
.sort();
|
|
63
|
+
if (timestamps.length === 0) return 'N/A';
|
|
64
|
+
const first = timestamps[0].split('T')[0];
|
|
65
|
+
const last = timestamps[timestamps.length - 1].split('T')[0];
|
|
66
|
+
return `${first} to ${last}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function getProjects(records) {
|
|
70
|
+
const projects = new Set();
|
|
71
|
+
for (const record of records) {
|
|
72
|
+
if (record.project) projects.add(record.project);
|
|
73
|
+
}
|
|
74
|
+
return Array.from(projects).join(', ') || '(unknown)';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export async function runReport(projectDirs) {
|
|
78
|
+
console.log(`
|
|
79
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
80
|
+
║ codecruise report ║
|
|
81
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
82
|
+
`);
|
|
83
|
+
|
|
84
|
+
// Find metrics directories
|
|
85
|
+
const metricsDirs = [];
|
|
86
|
+
|
|
87
|
+
if (projectDirs.length === 0) {
|
|
88
|
+
// Check current directory
|
|
89
|
+
if (existsSync('.codecruise/metrics')) {
|
|
90
|
+
metricsDirs.push('.codecruise/metrics');
|
|
91
|
+
}
|
|
92
|
+
} else {
|
|
93
|
+
for (const dir of projectDirs) {
|
|
94
|
+
const metricsPath = join(dir, '.codecruise/metrics');
|
|
95
|
+
if (existsSync(metricsPath)) {
|
|
96
|
+
metricsDirs.push(metricsPath);
|
|
97
|
+
} else {
|
|
98
|
+
console.log(`⚠ No metrics found in ${dir}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (metricsDirs.length === 0) {
|
|
104
|
+
console.log(`✗ No metrics found.
|
|
105
|
+
|
|
106
|
+
To collect metrics during dogfooding:
|
|
107
|
+
1. npx codecruise install
|
|
108
|
+
2. cd your-project && claude
|
|
109
|
+
3. /init && /run
|
|
110
|
+
4. Metrics are collected automatically
|
|
111
|
+
|
|
112
|
+
Then run:
|
|
113
|
+
npx codecruise report /path/to/project1 /path/to/project2
|
|
114
|
+
`);
|
|
115
|
+
process.exit(1);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log(`Analyzing metrics from ${metricsDirs.length} project(s)...\n`);
|
|
119
|
+
|
|
120
|
+
// Aggregate all data
|
|
121
|
+
let enforcement = [];
|
|
122
|
+
let agents = [];
|
|
123
|
+
let commands = [];
|
|
124
|
+
let ooda = [];
|
|
125
|
+
let events = [];
|
|
126
|
+
|
|
127
|
+
for (const dir of metricsDirs) {
|
|
128
|
+
enforcement = enforcement.concat(readJsonl(join(dir, 'enforcement.jsonl')));
|
|
129
|
+
agents = agents.concat(readJsonl(join(dir, 'agents.jsonl')));
|
|
130
|
+
commands = commands.concat(readJsonl(join(dir, 'commands.jsonl')));
|
|
131
|
+
ooda = ooda.concat(readJsonl(join(dir, 'ooda.jsonl')));
|
|
132
|
+
events = events.concat(readJsonl(join(dir, 'events.jsonl')));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const allRecords = [...enforcement, ...agents, ...commands, ...ooda, ...events];
|
|
136
|
+
|
|
137
|
+
// Analysis
|
|
138
|
+
const agentBreakdown = countByField(agents, 'agent');
|
|
139
|
+
const commandBreakdown = countByField(commands, 'command');
|
|
140
|
+
const enforcementBreakdown = countByField(enforcement, 'event');
|
|
141
|
+
const oodaPhases = countByField(ooda, 'phase');
|
|
142
|
+
const confidenceLevels = countByField(ooda.filter(r => r.confidence), 'confidence');
|
|
143
|
+
|
|
144
|
+
// Counts
|
|
145
|
+
const tddBlocks = enforcement.filter(r => r.event === 'tdd_block').length;
|
|
146
|
+
const rationalizationCaught = enforcement.filter(r => r.event === 'rationalization_caught').length;
|
|
147
|
+
const qualityBlocks = enforcement.filter(r => r.event === 'quality_block').length;
|
|
148
|
+
const stateBlocks = enforcement.filter(r => r.event === 'state_block').length;
|
|
149
|
+
const totalEnforcement = tddBlocks + rationalizationCaught + qualityBlocks + stateBlocks;
|
|
150
|
+
|
|
151
|
+
const testPasses = events.filter(r => r.event === 'test_pass').length;
|
|
152
|
+
const testFails = events.filter(r => r.event === 'test_fail').length;
|
|
153
|
+
const commits = events.filter(r => r.event === 'commit').length;
|
|
154
|
+
|
|
155
|
+
// Generate report
|
|
156
|
+
const dateRange = getDateRange(allRecords);
|
|
157
|
+
const projects = getProjects(allRecords);
|
|
158
|
+
const timestamp = new Date().toISOString();
|
|
159
|
+
|
|
160
|
+
let verdict = '';
|
|
161
|
+
if (totalEnforcement > 10) {
|
|
162
|
+
verdict = `The enforcement layer is **working**. ${totalEnforcement} violations were blocked, preventing sloppy work from shipping.`;
|
|
163
|
+
} else if (totalEnforcement > 0) {
|
|
164
|
+
verdict = `Enforcement is active (${totalEnforcement} blocks). Need more data to draw strong conclusions.`;
|
|
165
|
+
} else {
|
|
166
|
+
verdict = `**Insufficient data** to draw conclusions. Run more sessions with /run to collect metrics.`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const report = `# Codecruise Dogfood Report
|
|
170
|
+
|
|
171
|
+
**Generated**: ${timestamp}
|
|
172
|
+
**Projects**: ${projects}
|
|
173
|
+
**Period**: ${dateRange}
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Executive Summary
|
|
178
|
+
|
|
179
|
+
${verdict}
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## 1. Agent Usage
|
|
184
|
+
|
|
185
|
+
*Boris Q1: "Are 12 agents actually used? Or do 3-4 do 90% of the work?"*
|
|
186
|
+
|
|
187
|
+
**Total delegations**: ${agents.length}
|
|
188
|
+
|
|
189
|
+
${formatTable(agentBreakdown, agents.length)}
|
|
190
|
+
|
|
191
|
+
**Verdict**: ${agents.length < 10 ? 'Need more data' : agentBreakdown.length <= 4 ? `Only ${agentBreakdown.length} agents used — consider trimming` : 'Multiple agents in use'}
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## 2. Enforcement Effectiveness
|
|
196
|
+
|
|
197
|
+
*Peter Q1: "How many false dones were caught? How many TDD violations blocked?"*
|
|
198
|
+
|
|
199
|
+
| Enforcement Type | Count |
|
|
200
|
+
|-----------------|-------|
|
|
201
|
+
| TDD violations blocked | ${tddBlocks} |
|
|
202
|
+
| Rationalizations caught | ${rationalizationCaught} |
|
|
203
|
+
| Quality gate blocks | ${qualityBlocks} |
|
|
204
|
+
| State machine blocks | ${stateBlocks} |
|
|
205
|
+
| **Total** | **${totalEnforcement}** |
|
|
206
|
+
|
|
207
|
+
**Value**: ${totalEnforcement > 5 ? 'HIGH — These would have been bugs or incomplete work' : totalEnforcement > 0 ? 'MODERATE — Some catches' : 'Unknown — No violations recorded'}
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 3. OODA Reality
|
|
212
|
+
|
|
213
|
+
*Boris Q2, Peter Q2: "Is OODA's ORIENT phase doing meaningful confidence calculation?"*
|
|
214
|
+
|
|
215
|
+
**OODA phases logged**: ${ooda.length}
|
|
216
|
+
|
|
217
|
+
${formatTable(oodaPhases, ooda.length)}
|
|
218
|
+
|
|
219
|
+
**Confidence distribution**:
|
|
220
|
+
${formatTable(confidenceLevels, ooda.filter(r => r.confidence).length)}
|
|
221
|
+
|
|
222
|
+
**Verdict**: ${ooda.length === 0 ? 'No OODA data recorded — may not be emitting phase markers' : confidenceLevels.length > 1 ? 'OODA is calculating varied confidence levels' : 'Need more data to assess OODA value'}
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## 4. Command Usage
|
|
227
|
+
|
|
228
|
+
*Boris Q2: "Which of the 34 commands actually get used?"*
|
|
229
|
+
|
|
230
|
+
**Total invocations**: ${commands.length}
|
|
231
|
+
|
|
232
|
+
${formatTable(commandBreakdown, commands.length)}
|
|
233
|
+
|
|
234
|
+
**Verdict**: ${commands.length < 10 ? 'Need more data' : commandBreakdown.length <= 5 ? `Only ${commandBreakdown.length} commands used — consider trimming` : 'Multiple commands in use'}
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 5. Activity Summary
|
|
239
|
+
|
|
240
|
+
| Metric | Count |
|
|
241
|
+
|--------|-------|
|
|
242
|
+
| Test passes | ${testPasses} |
|
|
243
|
+
| Test failures | ${testFails} |
|
|
244
|
+
| Commits | ${commits} |
|
|
245
|
+
|
|
246
|
+
---
|
|
247
|
+
|
|
248
|
+
## 6. Overall Verdict
|
|
249
|
+
|
|
250
|
+
${totalEnforcement > 10 ? `**Complexity justified**: PARTIALLY
|
|
251
|
+
|
|
252
|
+
**Evidence**:
|
|
253
|
+
- Enforcement layer is clearly valuable (${totalEnforcement} violations blocked)
|
|
254
|
+
- Agent/command usage: ${agentBreakdown.length} agents, ${commandBreakdown.length} commands actively used
|
|
255
|
+
- OODA: ${ooda.length > 0 ? 'Recording data' : 'No data yet'}
|
|
256
|
+
|
|
257
|
+
**Recommendations**:
|
|
258
|
+
1. ${agentBreakdown.length < 5 ? 'Trim unused agents' : 'Keep agents, they are being used'}
|
|
259
|
+
2. ${commandBreakdown.length < 10 ? 'Trim unused commands' : 'Keep commands, they are being used'}
|
|
260
|
+
3. ${ooda.length === 0 ? 'Add OODA phase markers to /run output' : 'Continue monitoring OODA effectiveness'}` : `**Complexity justified**: INSUFFICIENT DATA
|
|
261
|
+
|
|
262
|
+
Run more dogfooding sessions with /run to collect meaningful metrics.
|
|
263
|
+
|
|
264
|
+
**Minimum needed**:
|
|
265
|
+
- 3+ projects
|
|
266
|
+
- 20+ TODOs completed
|
|
267
|
+
- Multiple sessions over several days`}
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
*Report generated by \`npx codecruise report\`*
|
|
272
|
+
`;
|
|
273
|
+
|
|
274
|
+
// Save report to ~/.claude/reports/
|
|
275
|
+
const reportsDir = join(homedir(), '.claude', 'reports');
|
|
276
|
+
mkdirSync(reportsDir, { recursive: true });
|
|
277
|
+
|
|
278
|
+
const reportPath = join(reportsDir, 'DOGFOOD-REPORT.md');
|
|
279
|
+
writeFileSync(reportPath, report);
|
|
280
|
+
|
|
281
|
+
console.log(`✓ Report saved to: ${reportPath}
|
|
282
|
+
|
|
283
|
+
Summary:
|
|
284
|
+
- Enforcement blocks: ${totalEnforcement}
|
|
285
|
+
- Agent delegations: ${agents.length}
|
|
286
|
+
- Command invocations: ${commands.length}
|
|
287
|
+
- OODA phases logged: ${ooda.length}
|
|
288
|
+
|
|
289
|
+
View report:
|
|
290
|
+
cat ${reportPath}
|
|
291
|
+
# or
|
|
292
|
+
npx codecruise report --show
|
|
293
|
+
`);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export async function showReport() {
|
|
297
|
+
const reportPath = join(homedir(), '.claude', 'reports', 'DOGFOOD-REPORT.md');
|
|
298
|
+
|
|
299
|
+
if (!existsSync(reportPath)) {
|
|
300
|
+
console.log(`No report found at ${reportPath}
|
|
301
|
+
|
|
302
|
+
Generate one first:
|
|
303
|
+
npx codecruise report ~/project1 ~/project2
|
|
304
|
+
`);
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const content = readFileSync(reportPath, 'utf-8');
|
|
309
|
+
console.log(content);
|
|
310
|
+
}
|