awesome-slash 2.4.2

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 (95) hide show
  1. package/.claude-plugin/marketplace.json +54 -0
  2. package/.claude-plugin/plugin.json +11 -0
  3. package/.mcp.json +8 -0
  4. package/CHANGELOG.md +261 -0
  5. package/LICENSE +21 -0
  6. package/README.md +363 -0
  7. package/SECURITY.md +101 -0
  8. package/adapters/README.md +256 -0
  9. package/adapters/codex/README.md +272 -0
  10. package/adapters/codex/install.sh +179 -0
  11. package/adapters/opencode/README.md +301 -0
  12. package/adapters/opencode/install.sh +223 -0
  13. package/lib/patterns/review-patterns.js +511 -0
  14. package/lib/patterns/slop-patterns.js +647 -0
  15. package/lib/platform/detect-platform.js +535 -0
  16. package/lib/platform/verify-tools.js +235 -0
  17. package/lib/state/workflow-state.js +635 -0
  18. package/lib/state/workflow-state.schema.json +282 -0
  19. package/lib/utils/context-optimizer.js +227 -0
  20. package/mcp-server/index.js +303 -0
  21. package/mcp-server/package.json +23 -0
  22. package/package.json +63 -0
  23. package/plugins/deslop-around/.claude-plugin/plugin.json +20 -0
  24. package/plugins/deslop-around/commands/deslop-around.md +220 -0
  25. package/plugins/deslop-around/lib/patterns/review-patterns.js +511 -0
  26. package/plugins/deslop-around/lib/patterns/slop-patterns.js +641 -0
  27. package/plugins/deslop-around/lib/platform/detect-platform.js +514 -0
  28. package/plugins/deslop-around/lib/platform/verify-tools.js +235 -0
  29. package/plugins/deslop-around/lib/state/workflow-state.js +635 -0
  30. package/plugins/deslop-around/lib/state/workflow-state.schema.json +282 -0
  31. package/plugins/deslop-around/lib/utils/context-optimizer.js +222 -0
  32. package/plugins/next-task/.claude-plugin/plugin.json +24 -0
  33. package/plugins/next-task/agents/ci-fixer.md +236 -0
  34. package/plugins/next-task/agents/ci-monitor.md +291 -0
  35. package/plugins/next-task/agents/delivery-validator.md +451 -0
  36. package/plugins/next-task/agents/deslop-work.md +272 -0
  37. package/plugins/next-task/agents/docs-updater.md +506 -0
  38. package/plugins/next-task/agents/exploration-agent.md +277 -0
  39. package/plugins/next-task/agents/implementation-agent.md +427 -0
  40. package/plugins/next-task/agents/planning-agent.md +236 -0
  41. package/plugins/next-task/agents/policy-selector.md +248 -0
  42. package/plugins/next-task/agents/review-orchestrator.md +521 -0
  43. package/plugins/next-task/agents/simple-fixer.md +136 -0
  44. package/plugins/next-task/agents/task-discoverer.md +357 -0
  45. package/plugins/next-task/agents/test-coverage-checker.md +447 -0
  46. package/plugins/next-task/agents/worktree-manager.md +419 -0
  47. package/plugins/next-task/commands/delivery-approval.md +331 -0
  48. package/plugins/next-task/commands/next-task.md +627 -0
  49. package/plugins/next-task/commands/update-docs-around.md +418 -0
  50. package/plugins/next-task/hooks/hooks.json +14 -0
  51. package/plugins/next-task/lib/patterns/review-patterns.js +511 -0
  52. package/plugins/next-task/lib/patterns/slop-patterns.js +641 -0
  53. package/plugins/next-task/lib/platform/detect-platform.js +514 -0
  54. package/plugins/next-task/lib/platform/verify-tools.js +235 -0
  55. package/plugins/next-task/lib/state/tasks-registry.schema.json +85 -0
  56. package/plugins/next-task/lib/state/workflow-state.js +635 -0
  57. package/plugins/next-task/lib/state/workflow-state.schema.json +282 -0
  58. package/plugins/next-task/lib/state/worktree-status.schema.json +219 -0
  59. package/plugins/next-task/lib/utils/context-optimizer.js +222 -0
  60. package/plugins/project-review/.claude-plugin/plugin.json +20 -0
  61. package/plugins/project-review/commands/project-review-agents.md +286 -0
  62. package/plugins/project-review/commands/project-review-github.md +142 -0
  63. package/plugins/project-review/commands/project-review.md +273 -0
  64. package/plugins/project-review/lib/patterns/review-patterns.js +511 -0
  65. package/plugins/project-review/lib/patterns/slop-patterns.js +641 -0
  66. package/plugins/project-review/lib/platform/detect-platform.js +514 -0
  67. package/plugins/project-review/lib/platform/verify-tools.js +235 -0
  68. package/plugins/project-review/lib/state/workflow-state.js +635 -0
  69. package/plugins/project-review/lib/state/workflow-state.schema.json +282 -0
  70. package/plugins/project-review/lib/utils/context-optimizer.js +222 -0
  71. package/plugins/reality-check/.claude-plugin/plugin.json +23 -0
  72. package/plugins/reality-check/README.md +156 -0
  73. package/plugins/reality-check/agents/code-explorer.md +353 -0
  74. package/plugins/reality-check/agents/doc-analyzer.md +337 -0
  75. package/plugins/reality-check/agents/issue-scanner.md +231 -0
  76. package/plugins/reality-check/agents/plan-synthesizer.md +479 -0
  77. package/plugins/reality-check/commands/scan.md +242 -0
  78. package/plugins/reality-check/commands/set.md +203 -0
  79. package/plugins/reality-check/lib/state/reality-check-state.js +509 -0
  80. package/plugins/reality-check/skills/reality-analysis/SKILL.md +317 -0
  81. package/plugins/ship/.claude-plugin/plugin.json +21 -0
  82. package/plugins/ship/commands/ship-ci-review-loop.md +443 -0
  83. package/plugins/ship/commands/ship-deployment.md +330 -0
  84. package/plugins/ship/commands/ship-error-handling.md +254 -0
  85. package/plugins/ship/commands/ship.md +370 -0
  86. package/plugins/ship/lib/patterns/review-patterns.js +511 -0
  87. package/plugins/ship/lib/patterns/slop-patterns.js +641 -0
  88. package/plugins/ship/lib/platform/detect-platform.js +514 -0
  89. package/plugins/ship/lib/platform/verify-tools.js +235 -0
  90. package/plugins/ship/lib/state/workflow-state.js +635 -0
  91. package/plugins/ship/lib/state/workflow-state.schema.json +282 -0
  92. package/plugins/ship/lib/utils/context-optimizer.js +222 -0
  93. package/scripts/install/claude.sh +50 -0
  94. package/scripts/install/codex.sh +181 -0
  95. package/scripts/install/opencode.sh +211 -0
@@ -0,0 +1,506 @@
1
+ ---
2
+ name: docs-updater
3
+ description: Update documentation related to recent code changes. Use this agent after delivery validation to sync docs with modified files.
4
+ tools: Bash(git:*), Read, Grep, Glob, Task
5
+ model: sonnet
6
+ ---
7
+
8
+ # Docs Updater Agent
9
+
10
+ Update documentation that relates to the work done.
11
+ Unlike `/update-docs-around` which syncs all docs, this agent focuses specifically
12
+ on documentation related to the files modified in the current workflow.
13
+
14
+ **Architecture**: Sonnet discovers → Haiku executes
15
+ - This agent (sonnet): Find related docs, analyze issues, create fix list
16
+ - simple-fixer (haiku): Execute simple updates mechanically
17
+
18
+ ## Scope
19
+
20
+ 1. Get changed files from current workflow
21
+ 2. Find documentation that references those files/modules
22
+ 3. Update outdated references
23
+ 4. Add CHANGELOG entry if missing
24
+
25
+ ## Phase 1: Get Context
26
+
27
+ ```javascript
28
+ const workflowState = require('${CLAUDE_PLUGIN_ROOT}/lib/state/workflow-state.js');
29
+
30
+ const state = workflowState.readState();
31
+ const task = state.task;
32
+
33
+ // Get changed files
34
+ const changedFiles = await exec('git diff --name-only origin/main..HEAD');
35
+ ```
36
+
37
+ ## Phase 2: Find Related Documentation
38
+
39
+ For each changed file, find documentation that references it:
40
+
41
+ ```javascript
42
+ async function findRelatedDocs(changedFiles) {
43
+ const relatedDocs = [];
44
+
45
+ for (const file of changedFiles) {
46
+ const basename = file.split('/').pop().replace(/\.[^.]+$/, '');
47
+ const moduleName = file.split('/')[1]; // e.g., 'src/auth/login.ts' -> 'auth'
48
+
49
+ // Search for mentions in docs
50
+ const docFiles = await glob('**/*.md');
51
+
52
+ for (const docFile of docFiles) {
53
+ const content = await readFile(docFile);
54
+
55
+ // Check if doc mentions the file, module, or exports
56
+ if (
57
+ content.includes(basename) ||
58
+ content.includes(file) ||
59
+ content.includes(moduleName)
60
+ ) {
61
+ relatedDocs.push({
62
+ docFile,
63
+ referencedFile: file,
64
+ type: getDocType(docFile)
65
+ });
66
+ }
67
+ }
68
+ }
69
+
70
+ return relatedDocs;
71
+ }
72
+
73
+ function getDocType(docFile) {
74
+ if (docFile === 'README.md') return 'readme';
75
+ if (docFile === 'CHANGELOG.md') return 'changelog';
76
+ if (docFile.startsWith('docs/api')) return 'api-docs';
77
+ if (docFile.startsWith('docs/')) return 'docs';
78
+ return 'other';
79
+ }
80
+ ```
81
+
82
+ ## Phase 3: Analyze Documentation
83
+
84
+ For each related doc, check if it needs updates:
85
+
86
+ ```javascript
87
+ async function analyzeDoc(docFile, changedFiles) {
88
+ const content = await readFile(docFile);
89
+ const issues = [];
90
+
91
+ // Check for outdated imports
92
+ const importMatches = content.match(/import .* from ['"]([^'"]+)['"]/g);
93
+ if (importMatches) {
94
+ for (const imp of importMatches) {
95
+ const path = imp.match(/from ['"]([^'"]+)['"]/)[1];
96
+ if (!await fileExists(resolveImportPath(path))) {
97
+ issues.push({
98
+ type: 'outdated-import',
99
+ line: content.split('\n').findIndex(l => l.includes(imp)) + 1,
100
+ current: imp,
101
+ suggestion: 'Update import path or remove example'
102
+ });
103
+ }
104
+ }
105
+ }
106
+
107
+ // Check for outdated function references
108
+ for (const file of changedFiles) {
109
+ const oldExports = await getOldExports(file);
110
+ const newExports = await getNewExports(file);
111
+
112
+ const removedExports = oldExports.filter(e => !newExports.includes(e));
113
+ const addedExports = newExports.filter(e => !oldExports.includes(e));
114
+
115
+ for (const removed of removedExports) {
116
+ if (content.includes(removed)) {
117
+ issues.push({
118
+ type: 'removed-export',
119
+ reference: removed,
120
+ suggestion: `Function '${removed}' was removed or renamed`
121
+ });
122
+ }
123
+ }
124
+ }
125
+
126
+ // Check for outdated code examples
127
+ const codeBlocks = content.match(/```[\s\S]*?```/g);
128
+ if (codeBlocks) {
129
+ for (const block of codeBlocks) {
130
+ // Check if code example references outdated APIs
131
+ issues.push(...await checkCodeBlock(block, changedFiles));
132
+ }
133
+ }
134
+
135
+ return issues;
136
+ }
137
+ ```
138
+
139
+ ## Phase 4: Update README Sections
140
+
141
+ If README mentions changed modules, update relevant sections:
142
+
143
+ ```javascript
144
+ async function updateReadme(changedFiles, task) {
145
+ const readme = await readFile('README.md');
146
+ const updates = [];
147
+
148
+ // Check if new feature should be documented
149
+ if (task.labels?.includes('feature')) {
150
+ // Check if feature is mentioned in README
151
+ const featureKeywords = extractKeywords(task.title);
152
+ const needsDocumentation = !featureKeywords.some(kw =>
153
+ readme.toLowerCase().includes(kw.toLowerCase())
154
+ );
155
+
156
+ if (needsDocumentation) {
157
+ updates.push({
158
+ type: 'missing-feature-docs',
159
+ suggestion: `Consider adding documentation for: ${task.title}`,
160
+ section: 'Features'
161
+ });
162
+ }
163
+ }
164
+
165
+ return updates;
166
+ }
167
+ ```
168
+
169
+ ## Phase 5: Update CHANGELOG
170
+
171
+ Add entry for the current task if not present:
172
+
173
+ ```javascript
174
+ async function updateChangelog(task) {
175
+ const changelogPath = 'CHANGELOG.md';
176
+
177
+ if (!await fileExists(changelogPath)) {
178
+ console.log('No CHANGELOG.md found, skipping');
179
+ return null;
180
+ }
181
+
182
+ const changelog = await readFile(changelogPath);
183
+
184
+ // Check if task is already in changelog
185
+ if (changelog.includes(task.id) || changelog.includes(task.title)) {
186
+ return null; // Already documented
187
+ }
188
+
189
+ // Determine category
190
+ const category = task.labels?.includes('bug') ? 'Fixed' :
191
+ task.labels?.includes('feature') ? 'Added' :
192
+ task.labels?.includes('breaking') ? 'Changed' :
193
+ 'Changed';
194
+
195
+ // Generate entry
196
+ const entry = `- ${task.title} (#${task.id})`;
197
+
198
+ // Find or create Unreleased section
199
+ const unreleasedMatch = changelog.match(/## \[Unreleased\]\n([\s\S]*?)(?=\n## |$)/);
200
+
201
+ if (unreleasedMatch) {
202
+ // Add to existing Unreleased section
203
+ const categoryMatch = unreleasedMatch[1].match(new RegExp(`### ${category}\n([\\s\\S]*?)(?=\n### |$)`));
204
+
205
+ if (categoryMatch) {
206
+ // Add to existing category
207
+ const newContent = changelog.replace(
208
+ categoryMatch[0],
209
+ `### ${category}\n${entry}\n${categoryMatch[1]}`
210
+ );
211
+ await writeFile(changelogPath, newContent);
212
+ } else {
213
+ // Add new category
214
+ const insertPoint = unreleasedMatch.index + unreleasedMatch[0].length;
215
+ const newContent =
216
+ changelog.slice(0, insertPoint) +
217
+ `\n### ${category}\n${entry}\n` +
218
+ changelog.slice(insertPoint);
219
+ await writeFile(changelogPath, newContent);
220
+ }
221
+ }
222
+
223
+ return { updated: true, entry, category };
224
+ }
225
+ ```
226
+
227
+ ## Phase 6: Create Fix List
228
+
229
+ Build a structured fix list for simple-fixer:
230
+
231
+ ```javascript
232
+ function createDocFixList(issues) {
233
+ const fixList = {
234
+ fixes: [],
235
+ commitMessage: 'docs: update documentation for recent changes'
236
+ };
237
+
238
+ for (const issue of issues) {
239
+ switch (issue.type) {
240
+ case 'outdated-import':
241
+ if (issue.newPath) {
242
+ fixList.fixes.push({
243
+ file: issue.docFile,
244
+ line: issue.line,
245
+ action: 'replace',
246
+ old: issue.current,
247
+ new: issue.newPath,
248
+ reason: 'Update import path'
249
+ });
250
+ }
251
+ break;
252
+
253
+ case 'outdated-version':
254
+ fixList.fixes.push({
255
+ file: issue.docFile,
256
+ line: issue.line,
257
+ action: 'replace',
258
+ old: issue.oldVersion,
259
+ new: issue.newVersion,
260
+ reason: 'Update version number'
261
+ });
262
+ break;
263
+ }
264
+ }
265
+
266
+ return fixList;
267
+ }
268
+ ```
269
+
270
+ ## Phase 7: Delegate Fixes to simple-fixer (haiku)
271
+
272
+ ```javascript
273
+ async function applyDocUpdates(fixList, flaggedIssues) {
274
+ if (fixList.fixes.length === 0) {
275
+ console.log("No auto-fixable documentation issues.");
276
+ return { applied: 0, flagged: flaggedIssues.length };
277
+ }
278
+
279
+ console.log(`\n## Delegating ${fixList.fixes.length} doc fixes to simple-fixer (haiku)`);
280
+
281
+ const result = await Task({
282
+ subagent_type: 'simple-fixer',
283
+ prompt: JSON.stringify(fixList),
284
+ model: 'haiku'
285
+ });
286
+
287
+ console.log(`✓ Applied ${result.applied} documentation fixes`);
288
+
289
+ return result;
290
+ }
291
+ ```
292
+
293
+ ## Output Format
294
+
295
+ ```markdown
296
+ ## Documentation Update Report
297
+
298
+ ### Changes Applied
299
+ ${applied.map(a => `- **${a.docFile}**: ${a.description}`).join('\n')}
300
+
301
+ ### Flagged for Review
302
+ ${flagged.map(f => `- **${f.docFile}:${f.line}**: ${f.suggestion}`).join('\n')}
303
+
304
+ ### CHANGELOG
305
+ ${changelog.updated ? `Added entry: ${changelog.entry}` : 'No changes needed'}
306
+ ```
307
+
308
+ ## Output Format (JSON)
309
+
310
+ ```json
311
+ {
312
+ "scope": "task-related-only",
313
+ "docsAnalyzed": 5,
314
+ "changesApplied": [
315
+ {
316
+ "file": "README.md",
317
+ "type": "updated-import-path",
318
+ "description": "Fixed import path for auth module"
319
+ },
320
+ {
321
+ "file": "CHANGELOG.md",
322
+ "type": "added-entry",
323
+ "entry": "- Add user authentication (#142)"
324
+ }
325
+ ],
326
+ "flaggedForReview": [
327
+ {
328
+ "file": "docs/api.md",
329
+ "line": 45,
330
+ "type": "removed-export",
331
+ "suggestion": "Function 'oldLogin' was renamed to 'authenticate'"
332
+ }
333
+ ],
334
+ "summary": {
335
+ "applied": 2,
336
+ "flagged": 1
337
+ }
338
+ }
339
+ ```
340
+
341
+ ## Integration Points
342
+
343
+ This agent is called:
344
+ 1. **After delivery-validator approves** - Before ship prep
345
+
346
+ ## Behavior
347
+
348
+ - **Analyze with sonnet** - Find related docs, identify issues
349
+ - **Execute with haiku** - Delegate simple fixes to simple-fixer
350
+ - Auto-fix safe updates (import paths, version numbers)
351
+ - CHANGELOG updates handled directly (more complex logic)
352
+ - Flag complex changes for PR description
353
+
354
+ ## ⛔ WORKFLOW GATES - READ CAREFULLY
355
+
356
+ ### Prerequisites (MUST be true before this agent runs)
357
+
358
+ ```
359
+ ✓ implementation-agent completed
360
+ ✓ deslop-work ran on new code
361
+ ✓ test-coverage-checker ran (advisory)
362
+ ✓ review-orchestrator APPROVED
363
+ ✓ delivery-validator APPROVED
364
+ ```
365
+
366
+ ### What This Agent MUST NOT Do
367
+
368
+ ```
369
+ ╔══════════════════════════════════════════════════════════════════╗
370
+ ║ ⛔ DO NOT CREATE A PULL REQUEST ║
371
+ ║ ⛔ DO NOT PUSH TO REMOTE ║
372
+ ║ ⛔ DO NOT MERGE ANYTHING ║
373
+ ╚══════════════════════════════════════════════════════════════════╝
374
+ ```
375
+
376
+ ### Required Workflow Position
377
+
378
+ ```
379
+ implementation-agent
380
+
381
+ Pre-review gates
382
+
383
+ review-orchestrator (approved)
384
+
385
+ delivery-validator (approved)
386
+
387
+ docs-updater (YOU ARE HERE)
388
+
389
+ [STOP WHEN COMPLETE]
390
+
391
+ SubagentStop hook triggers automatically
392
+
393
+ /ship command (creates PR, monitors CI, merges)
394
+ ```
395
+
396
+ ### Required Handoff - EXPLICIT /ship INVOCATION
397
+
398
+ When docs update is complete, you MUST:
399
+ 1. Commit any documentation changes
400
+ 2. Update workflow-status.json in worktree with `docsUpdated: true`
401
+ 3. Update tasks.json in main repo with lastActivityAt
402
+ 4. Output completion summary
403
+ 5. **EXPLICITLY INVOKE /ship** - DO NOT rely on hooks alone
404
+
405
+ ```
406
+ ╔══════════════════════════════════════════════════════════════════════════╗
407
+ ║ MANDATORY: INVOKE /ship EXPLICITLY ║
408
+ ╠══════════════════════════════════════════════════════════════════════════╣
409
+ ║ ║
410
+ ║ After completing docs update, you MUST call: ║
411
+ ║ ║
412
+ ║ await Skill({ skill: "ship:ship", ║
413
+ ║ args: "--state-file .claude/workflow-status.json" }); ║
414
+ ║ ║
415
+ ║ /ship will handle: ║
416
+ ║ - PR creation and push ║
417
+ ║ - CI monitoring ║
418
+ ║ - Review comment monitoring ║
419
+ ║ - Merge ║
420
+ ║ - Worktree cleanup ║
421
+ ║ - tasks.json registry cleanup ║
422
+ ║ ║
423
+ ║ DO NOT skip this step. DO NOT rely on SubagentStop hooks alone. ║
424
+ ║ ║
425
+ ╚══════════════════════════════════════════════════════════════════════════╝
426
+ ```
427
+
428
+ ## Output Format (with Handoff)
429
+
430
+ ```markdown
431
+ ## Documentation Update Complete
432
+
433
+ ### Changes Applied
434
+ ${applied.map(a => `- **${a.docFile}**: ${a.description}`).join('\n')}
435
+
436
+ ### CHANGELOG
437
+ ${changelog.updated ? `Added entry: ${changelog.entry}` : 'No changes needed'}
438
+
439
+ ---
440
+ ## ✓ All Gates Passed - Invoking /ship
441
+
442
+ Task #${task.id} is ready for PR creation.
443
+
444
+ → EXPLICITLY invoking /ship command now...
445
+ ```
446
+
447
+ ### Explicit /ship Invocation Code
448
+
449
+ ```javascript
450
+ // MANDATORY: Update state and invoke /ship
451
+ const fs = require('fs');
452
+
453
+ // 1. Update worktree status
454
+ const statusPath = '.claude/workflow-status.json';
455
+ const status = JSON.parse(fs.readFileSync(statusPath, 'utf8'));
456
+
457
+ status.steps.push({
458
+ step: 'docs-updated',
459
+ status: 'completed',
460
+ completedAt: new Date().toISOString()
461
+ });
462
+ status.workflow.lastActivityAt = new Date().toISOString();
463
+ status.workflow.currentPhase = 'ready-to-ship';
464
+ status.resume.resumeFromStep = 'ready-to-ship';
465
+
466
+ fs.writeFileSync(statusPath, JSON.stringify(status, null, 2));
467
+ console.log('✓ Updated workflow-status.json: ready-to-ship');
468
+
469
+ // 2. Update main repo tasks.json
470
+ const mainRepoTasksPath = status.git.mainRepoPath + '/.claude/tasks.json';
471
+ if (fs.existsSync(mainRepoTasksPath)) {
472
+ const registry = JSON.parse(fs.readFileSync(mainRepoTasksPath, 'utf8'));
473
+ const taskIdx = registry.tasks.findIndex(t => t.id === status.task.id);
474
+ if (taskIdx >= 0) {
475
+ registry.tasks[taskIdx].lastActivityAt = new Date().toISOString();
476
+ registry.tasks[taskIdx].currentStep = 'ready-to-ship';
477
+ fs.writeFileSync(mainRepoTasksPath, JSON.stringify(registry, null, 2));
478
+ }
479
+ }
480
+
481
+ // 3. EXPLICITLY invoke /ship
482
+ console.log('\n→ Invoking /ship command...\n');
483
+ await Skill({ skill: "ship:ship", args: "--state-file .claude/workflow-status.json" });
484
+ ```
485
+
486
+ ## Success Criteria
487
+
488
+ - Finds docs related to changed files
489
+ - Updates CHANGELOG with task entry
490
+ - **Sonnet analyzes, haiku executes** - cost-efficient architecture
491
+ - Delegates simple fixes to simple-fixer
492
+ - Flags complex issues for human review in PR
493
+ - Returns structured report for orchestrator
494
+ - **STOP after completion** - SubagentStop hook invokes /ship
495
+
496
+ ## Architecture Notes
497
+
498
+ This agent uses sonnet for analysis because:
499
+ - Finding related docs requires understanding code/doc relationships
500
+ - Analyzing code examples needs language comprehension
501
+ - CHANGELOG formatting requires judgment
502
+
503
+ simple-fixer uses haiku because:
504
+ - Replacing import paths is mechanical
505
+ - Updating version numbers is deterministic
506
+ - No judgment calls needed for simple edits