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.
- package/.claude-plugin/marketplace.json +54 -0
- package/.claude-plugin/plugin.json +11 -0
- package/.mcp.json +8 -0
- package/CHANGELOG.md +261 -0
- package/LICENSE +21 -0
- package/README.md +363 -0
- package/SECURITY.md +101 -0
- package/adapters/README.md +256 -0
- package/adapters/codex/README.md +272 -0
- package/adapters/codex/install.sh +179 -0
- package/adapters/opencode/README.md +301 -0
- package/adapters/opencode/install.sh +223 -0
- package/lib/patterns/review-patterns.js +511 -0
- package/lib/patterns/slop-patterns.js +647 -0
- package/lib/platform/detect-platform.js +535 -0
- package/lib/platform/verify-tools.js +235 -0
- package/lib/state/workflow-state.js +635 -0
- package/lib/state/workflow-state.schema.json +282 -0
- package/lib/utils/context-optimizer.js +227 -0
- package/mcp-server/index.js +303 -0
- package/mcp-server/package.json +23 -0
- package/package.json +63 -0
- package/plugins/deslop-around/.claude-plugin/plugin.json +20 -0
- package/plugins/deslop-around/commands/deslop-around.md +220 -0
- package/plugins/deslop-around/lib/patterns/review-patterns.js +511 -0
- package/plugins/deslop-around/lib/patterns/slop-patterns.js +641 -0
- package/plugins/deslop-around/lib/platform/detect-platform.js +514 -0
- package/plugins/deslop-around/lib/platform/verify-tools.js +235 -0
- package/plugins/deslop-around/lib/state/workflow-state.js +635 -0
- package/plugins/deslop-around/lib/state/workflow-state.schema.json +282 -0
- package/plugins/deslop-around/lib/utils/context-optimizer.js +222 -0
- package/plugins/next-task/.claude-plugin/plugin.json +24 -0
- package/plugins/next-task/agents/ci-fixer.md +236 -0
- package/plugins/next-task/agents/ci-monitor.md +291 -0
- package/plugins/next-task/agents/delivery-validator.md +451 -0
- package/plugins/next-task/agents/deslop-work.md +272 -0
- package/plugins/next-task/agents/docs-updater.md +506 -0
- package/plugins/next-task/agents/exploration-agent.md +277 -0
- package/plugins/next-task/agents/implementation-agent.md +427 -0
- package/plugins/next-task/agents/planning-agent.md +236 -0
- package/plugins/next-task/agents/policy-selector.md +248 -0
- package/plugins/next-task/agents/review-orchestrator.md +521 -0
- package/plugins/next-task/agents/simple-fixer.md +136 -0
- package/plugins/next-task/agents/task-discoverer.md +357 -0
- package/plugins/next-task/agents/test-coverage-checker.md +447 -0
- package/plugins/next-task/agents/worktree-manager.md +419 -0
- package/plugins/next-task/commands/delivery-approval.md +331 -0
- package/plugins/next-task/commands/next-task.md +627 -0
- package/plugins/next-task/commands/update-docs-around.md +418 -0
- package/plugins/next-task/hooks/hooks.json +14 -0
- package/plugins/next-task/lib/patterns/review-patterns.js +511 -0
- package/plugins/next-task/lib/patterns/slop-patterns.js +641 -0
- package/plugins/next-task/lib/platform/detect-platform.js +514 -0
- package/plugins/next-task/lib/platform/verify-tools.js +235 -0
- package/plugins/next-task/lib/state/tasks-registry.schema.json +85 -0
- package/plugins/next-task/lib/state/workflow-state.js +635 -0
- package/plugins/next-task/lib/state/workflow-state.schema.json +282 -0
- package/plugins/next-task/lib/state/worktree-status.schema.json +219 -0
- package/plugins/next-task/lib/utils/context-optimizer.js +222 -0
- package/plugins/project-review/.claude-plugin/plugin.json +20 -0
- package/plugins/project-review/commands/project-review-agents.md +286 -0
- package/plugins/project-review/commands/project-review-github.md +142 -0
- package/plugins/project-review/commands/project-review.md +273 -0
- package/plugins/project-review/lib/patterns/review-patterns.js +511 -0
- package/plugins/project-review/lib/patterns/slop-patterns.js +641 -0
- package/plugins/project-review/lib/platform/detect-platform.js +514 -0
- package/plugins/project-review/lib/platform/verify-tools.js +235 -0
- package/plugins/project-review/lib/state/workflow-state.js +635 -0
- package/plugins/project-review/lib/state/workflow-state.schema.json +282 -0
- package/plugins/project-review/lib/utils/context-optimizer.js +222 -0
- package/plugins/reality-check/.claude-plugin/plugin.json +23 -0
- package/plugins/reality-check/README.md +156 -0
- package/plugins/reality-check/agents/code-explorer.md +353 -0
- package/plugins/reality-check/agents/doc-analyzer.md +337 -0
- package/plugins/reality-check/agents/issue-scanner.md +231 -0
- package/plugins/reality-check/agents/plan-synthesizer.md +479 -0
- package/plugins/reality-check/commands/scan.md +242 -0
- package/plugins/reality-check/commands/set.md +203 -0
- package/plugins/reality-check/lib/state/reality-check-state.js +509 -0
- package/plugins/reality-check/skills/reality-analysis/SKILL.md +317 -0
- package/plugins/ship/.claude-plugin/plugin.json +21 -0
- package/plugins/ship/commands/ship-ci-review-loop.md +443 -0
- package/plugins/ship/commands/ship-deployment.md +330 -0
- package/plugins/ship/commands/ship-error-handling.md +254 -0
- package/plugins/ship/commands/ship.md +370 -0
- package/plugins/ship/lib/patterns/review-patterns.js +511 -0
- package/plugins/ship/lib/patterns/slop-patterns.js +641 -0
- package/plugins/ship/lib/platform/detect-platform.js +514 -0
- package/plugins/ship/lib/platform/verify-tools.js +235 -0
- package/plugins/ship/lib/state/workflow-state.js +635 -0
- package/plugins/ship/lib/state/workflow-state.schema.json +282 -0
- package/plugins/ship/lib/utils/context-optimizer.js +222 -0
- package/scripts/install/claude.sh +50 -0
- package/scripts/install/codex.sh +181 -0
- 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
|