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.
Files changed (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/bin/codecruise.js +68 -0
  4. package/config/CLAUDE.md +107 -0
  5. package/config/agents/analyst.md +48 -0
  6. package/config/agents/architect-reviewer.md +161 -0
  7. package/config/agents/architect.md +119 -0
  8. package/config/agents/critic.md +63 -0
  9. package/config/agents/developer.md +96 -0
  10. package/config/agents/devops.md +81 -0
  11. package/config/agents/orchestrator.md +91 -0
  12. package/config/agents/planner.md +139 -0
  13. package/config/agents/retro.md +52 -0
  14. package/config/agents/reviewer.md +101 -0
  15. package/config/agents/security-reviewer.md +57 -0
  16. package/config/agents/stack/expo/AGENT.md +473 -0
  17. package/config/agents/stack/expo/rules/critical.md +427 -0
  18. package/config/agents/stack/expo/rules/native.md +455 -0
  19. package/config/agents/stack/expo/rules/navigation.md +445 -0
  20. package/config/agents/stack/expo/rules/performance.md +415 -0
  21. package/config/agents/stack/fastify/AGENT.md +397 -0
  22. package/config/agents/stack/fastify/rules/api-design.md +283 -0
  23. package/config/agents/stack/fastify/rules/critical.md +232 -0
  24. package/config/agents/stack/fastify/rules/queues.md +303 -0
  25. package/config/agents/stack/fastify/rules/security.md +384 -0
  26. package/config/agents/stack/index.yaml +48 -0
  27. package/config/agents/stack/nextjs/AGENT.md +421 -0
  28. package/config/agents/stack/nextjs/rules/components.md +413 -0
  29. package/config/agents/stack/nextjs/rules/critical.md +391 -0
  30. package/config/agents/stack/nextjs/rules/performance.md +403 -0
  31. package/config/agents/stack/nextjs/rules/styling.md +334 -0
  32. package/config/agents/stack/shared-ts/AGENT.md +384 -0
  33. package/config/agents/stack/shared-ts/rules/critical.md +315 -0
  34. package/config/agents/stack/shared-ts/rules/patterns.md +384 -0
  35. package/config/agents/stack/shared-ts/rules/zod.md +427 -0
  36. package/config/agents/tester.md +79 -0
  37. package/config/commands/architect-discuss.md +366 -0
  38. package/config/commands/architect-list.md +160 -0
  39. package/config/commands/architect-review.md +111 -0
  40. package/config/commands/architect.md +118 -0
  41. package/config/commands/compact.md +118 -0
  42. package/config/commands/companion.md +279 -0
  43. package/config/commands/dashboard.md +152 -0
  44. package/config/commands/doctor.md +227 -0
  45. package/config/commands/dogfood-report.md +101 -0
  46. package/config/commands/flags/run-autonomous.md +110 -0
  47. package/config/commands/flags/run-pause.md +80 -0
  48. package/config/commands/ingest.md +173 -0
  49. package/config/commands/init.md +128 -0
  50. package/config/commands/metrics.md +87 -0
  51. package/config/commands/parallel.md +320 -0
  52. package/config/commands/pause.md +55 -0
  53. package/config/commands/plan-review.md +130 -0
  54. package/config/commands/plan.md +216 -0
  55. package/config/commands/production-check.md +308 -0
  56. package/config/commands/refine.md +323 -0
  57. package/config/commands/resume.md +72 -0
  58. package/config/commands/retro.md +121 -0
  59. package/config/commands/retry.md +75 -0
  60. package/config/commands/role.md +310 -0
  61. package/config/commands/run.md +417 -0
  62. package/config/commands/scope.md +85 -0
  63. package/config/commands/setup-permissions.md +104 -0
  64. package/config/commands/skip.md +75 -0
  65. package/config/commands/spec-forge.md +213 -0
  66. package/config/commands/spec-help.md +194 -0
  67. package/config/commands/spec-patch.md +342 -0
  68. package/config/commands/spec-resolve.md +110 -0
  69. package/config/commands/spec-review.md +153 -0
  70. package/config/commands/status.md +114 -0
  71. package/config/commands/sync.md +131 -0
  72. package/config/commands/task.md +138 -0
  73. package/config/commands/verify.md +124 -0
  74. package/config/hooks/README.md +632 -0
  75. package/config/hooks/activity-log.sh +187 -0
  76. package/config/hooks/anti-rationalize.sh +52 -0
  77. package/config/hooks/capture-verification.sh +112 -0
  78. package/config/hooks/collect-metrics.sh +135 -0
  79. package/config/hooks/enforce-file-scope.sh +75 -0
  80. package/config/hooks/enforce-state-machine.sh +161 -0
  81. package/config/hooks/enforce-tdd.sh +180 -0
  82. package/config/hooks/format.sh +40 -0
  83. package/config/hooks/lib/activity-helpers.sh +162 -0
  84. package/config/hooks/lib/read-settings.sh +71 -0
  85. package/config/hooks/load-context-skills.sh +95 -0
  86. package/config/hooks/notify.sh +81 -0
  87. package/config/hooks/pre-commit.sample +35 -0
  88. package/config/hooks/protect-files.sh +63 -0
  89. package/config/hooks/track-agents.sh +41 -0
  90. package/config/hooks/track-commands.sh +37 -0
  91. package/config/hooks/track-enforcement.sh +44 -0
  92. package/config/hooks/track-ooda.sh +77 -0
  93. package/config/hooks/validate-commit-msg.sh +35 -0
  94. package/config/hooks/validate-plan.sh +213 -0
  95. package/config/hooks/verify-criteria.sh +46 -0
  96. package/config/hooks/verify-todo-completion.sh +140 -0
  97. package/config/rules/comments.md +25 -0
  98. package/config/rules/decision-rules.md +308 -0
  99. package/config/rules/hygiene.md +247 -0
  100. package/config/rules/pattern-detection.md +372 -0
  101. package/config/rules/profiles.md +193 -0
  102. package/config/rules/recovery.md +83 -0
  103. package/config/rules/scope-detection.md +213 -0
  104. package/config/rules/standards.md +127 -0
  105. package/config/rules/workflow.md +121 -0
  106. package/config/schemas.md +767 -0
  107. package/config/settings.json +195 -0
  108. package/config/skills/backend/SKILL.md +734 -0
  109. package/config/skills/database/SKILL.md +426 -0
  110. package/config/skills/frontend/SKILL.md +434 -0
  111. package/config/skills/git/SKILL.md +396 -0
  112. package/config/skills/index.yaml +36 -0
  113. package/config/skills/observability/SKILL.md +430 -0
  114. package/config/skills/package-dev/SKILL.md +498 -0
  115. package/config/skills/performance/SKILL.md +378 -0
  116. package/config/skills/resilience/SKILL.md +573 -0
  117. package/config/skills/testing/SKILL.md +398 -0
  118. package/config/skills/testing-patterns/SKILL.md +276 -0
  119. package/config/skills/typescript/SKILL.md +152 -0
  120. package/config/templates/CLAUDE.md +70 -0
  121. package/config/templates/README.md +117 -0
  122. package/config/templates/steering/adr-template.md +102 -0
  123. package/config/templates/steering/product.md +60 -0
  124. package/config/templates/steering/rfc-template.md +159 -0
  125. package/config/templates/steering/structure.md +146 -0
  126. package/config/templates/steering/tech.md +85 -0
  127. package/package.json +40 -0
  128. package/src/install.js +163 -0
  129. 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
+ }