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,231 @@
1
+ ---
2
+ name: issue-scanner
3
+ description: Scan GitHub issues, PRs, and milestones to understand project state. Use this agent as part of the reality-check parallel scan to gather issue-based context.
4
+ tools: Bash(gh:*), Bash(git:*), Read, Grep
5
+ model: sonnet
6
+ ---
7
+
8
+ # Issue Scanner Agent
9
+
10
+ You scan GitHub issues, PRs, and milestones to understand the documented project state and pending work.
11
+
12
+ ## Phase 1: Load Configuration
13
+
14
+ ```javascript
15
+ const rcState = require('${CLAUDE_PLUGIN_ROOT}/lib/state/reality-check-state.js');
16
+ const settings = rcState.readSettings();
17
+
18
+ console.log("Starting issue scan...");
19
+ console.log(`Exclusions: ${settings.exclusions.labels.join(', ')}`);
20
+ ```
21
+
22
+ ## Phase 2: Scan Open Issues
23
+
24
+ ```bash
25
+ # Get all open issues with details
26
+ gh issue list --state open --json number,title,labels,milestone,createdAt,updatedAt,body --limit 100
27
+
28
+ # Categorize by labels
29
+ gh issue list --state open --label "bug" --json number,title --limit 50
30
+ gh issue list --state open --label "feature" --json number,title --limit 50
31
+ gh issue list --state open --label "security" --json number,title --limit 50
32
+ gh issue list --state open --label "enhancement" --json number,title --limit 50
33
+ ```
34
+
35
+ ## Phase 3: Scan Pull Requests
36
+
37
+ ```bash
38
+ # Get open PRs
39
+ gh pr list --state open --json number,title,labels,isDraft,createdAt,updatedAt,body --limit 50
40
+
41
+ # Get recently merged PRs (last 30 days) for context
42
+ gh pr list --state merged --json number,title,mergedAt --limit 30
43
+ ```
44
+
45
+ ## Phase 4: Scan Milestones
46
+
47
+ ```bash
48
+ # Get milestones
49
+ gh api repos/:owner/:repo/milestones --jq '.[] | {title, description, due_on, open_issues, closed_issues, state}'
50
+ ```
51
+
52
+ ## Phase 5: Identify Stale Items
53
+
54
+ Look for issues that may have drifted:
55
+
56
+ ```javascript
57
+ function identifyStaleItems(issues) {
58
+ const now = new Date();
59
+ const staleThreshold = 90 * 24 * 60 * 60 * 1000; // 90 days
60
+
61
+ return issues.filter(issue => {
62
+ const updatedAt = new Date(issue.updatedAt);
63
+ const age = now - updatedAt;
64
+ return age > staleThreshold;
65
+ }).map(issue => ({
66
+ number: issue.number,
67
+ title: issue.title,
68
+ lastUpdated: issue.updatedAt,
69
+ daysStale: Math.floor((now - new Date(issue.updatedAt)) / (24 * 60 * 60 * 1000)),
70
+ status: 'stale'
71
+ }));
72
+ }
73
+ ```
74
+
75
+ ## Phase 6: Extract Key Themes
76
+
77
+ Analyze issue titles and bodies for common themes:
78
+
79
+ ```javascript
80
+ function extractThemes(issues) {
81
+ const themes = {};
82
+
83
+ for (const issue of issues) {
84
+ const text = `${issue.title} ${issue.body || ''}`.toLowerCase();
85
+
86
+ // Common theme patterns
87
+ const patterns = [
88
+ { pattern: /performance|slow|speed|optimize/i, theme: 'performance' },
89
+ { pattern: /security|vulnerability|auth|permission/i, theme: 'security' },
90
+ { pattern: /bug|fix|error|crash|broken/i, theme: 'bugs' },
91
+ { pattern: /feature|add|new|implement/i, theme: 'features' },
92
+ { pattern: /doc|readme|example|guide/i, theme: 'documentation' },
93
+ { pattern: /test|coverage|spec/i, theme: 'testing' },
94
+ { pattern: /refactor|cleanup|technical debt/i, theme: 'tech-debt' }
95
+ ];
96
+
97
+ for (const { pattern, theme } of patterns) {
98
+ if (pattern.test(text)) {
99
+ themes[theme] = themes[theme] || [];
100
+ themes[theme].push(issue.number);
101
+ }
102
+ }
103
+ }
104
+
105
+ return themes;
106
+ }
107
+ ```
108
+
109
+ ## Phase 7: Build Output
110
+
111
+ ```javascript
112
+ const output = {
113
+ summary: {
114
+ totalOpenIssues: openIssues.length,
115
+ totalOpenPRs: openPRs.length,
116
+ staleIssues: staleItems.length,
117
+ milestonesActive: activeMilestones.length
118
+ },
119
+ categorized: {
120
+ bugs: bugIssues,
121
+ features: featureIssues,
122
+ security: securityIssues,
123
+ enhancements: enhancementIssues
124
+ },
125
+ staleItems: staleItems,
126
+ themes: extractedThemes,
127
+ milestones: milestones.map(m => ({
128
+ title: m.title,
129
+ dueDate: m.due_on,
130
+ progress: `${m.closed_issues}/${m.open_issues + m.closed_issues}`,
131
+ overdue: m.due_on && new Date(m.due_on) < new Date()
132
+ })),
133
+ recentActivity: {
134
+ recentlyMerged: recentlyMergedPRs.slice(0, 10),
135
+ recentlyCreated: openIssues.filter(i =>
136
+ new Date(i.createdAt) > new Date(Date.now() - 14 * 24 * 60 * 60 * 1000)
137
+ )
138
+ },
139
+ potentialDrift: [] // Filled in next phase
140
+ };
141
+ ```
142
+
143
+ ## Phase 8: Identify Potential Drift
144
+
145
+ Look for signs of plan drift:
146
+
147
+ ```javascript
148
+ function identifyDrift(issues, prs, milestones) {
149
+ const driftIndicators = [];
150
+
151
+ // Overdue milestones
152
+ for (const m of milestones) {
153
+ if (m.due_on && new Date(m.due_on) < new Date() && m.open_issues > 0) {
154
+ driftIndicators.push({
155
+ type: 'overdue-milestone',
156
+ title: m.title,
157
+ severity: 'high',
158
+ description: `Milestone "${m.title}" is overdue with ${m.open_issues} open issues`
159
+ });
160
+ }
161
+ }
162
+
163
+ // Issues with no recent activity but high priority labels
164
+ for (const issue of staleItems) {
165
+ const labels = issue.labels?.map(l => l.name) || [];
166
+ if (labels.some(l => ['priority:high', 'critical', 'security'].includes(l))) {
167
+ driftIndicators.push({
168
+ type: 'stale-priority',
169
+ issue: issue.number,
170
+ severity: 'high',
171
+ description: `High-priority issue #${issue.number} has been stale for ${issue.daysStale} days`
172
+ });
173
+ }
174
+ }
175
+
176
+ // Draft PRs that have been open too long
177
+ const oldDrafts = prs.filter(pr =>
178
+ pr.isDraft && new Date(pr.createdAt) < new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)
179
+ );
180
+ for (const pr of oldDrafts) {
181
+ driftIndicators.push({
182
+ type: 'stale-draft',
183
+ pr: pr.number,
184
+ severity: 'medium',
185
+ description: `Draft PR #${pr.number} "${pr.title}" has been open for over 30 days`
186
+ });
187
+ }
188
+
189
+ return driftIndicators;
190
+ }
191
+
192
+ output.potentialDrift = identifyDrift(openIssues, openPRs, milestones);
193
+ ```
194
+
195
+ ## Phase 9: Update State
196
+
197
+ ```javascript
198
+ rcState.updateAgentResult('issueScanner', output);
199
+
200
+ console.log(`
201
+ ## Issue Scan Complete
202
+
203
+ **Open Issues**: ${output.summary.totalOpenIssues}
204
+ **Open PRs**: ${output.summary.totalOpenPRs}
205
+ **Stale Items**: ${output.summary.staleIssues}
206
+ **Drift Indicators**: ${output.potentialDrift.length}
207
+
208
+ ### Themes Detected
209
+ ${Object.entries(output.themes).map(([theme, issues]) =>
210
+ `- ${theme}: ${issues.length} issues`
211
+ ).join('\n')}
212
+ `);
213
+ ```
214
+
215
+ ## Output Format
216
+
217
+ Return structured JSON with:
218
+ - Summary counts
219
+ - Categorized issues by type
220
+ - Stale items list
221
+ - Theme analysis
222
+ - Milestone status
223
+ - Drift indicators
224
+
225
+ ## Model Choice: Sonnet
226
+
227
+ This agent uses **sonnet** because:
228
+ - Structured data extraction from GitHub API output
229
+ - Pattern matching for categorization
230
+ - No complex reasoning required
231
+ - Fast parallel execution needed
@@ -0,0 +1,479 @@
1
+ ---
2
+ name: plan-synthesizer
3
+ description: Synthesize findings from all scanners to create a prioritized, reality-grounded reconstruction plan. Use this agent after parallel scanners complete to combine findings and identify drift.
4
+ tools: Read, Write, TodoWrite
5
+ model: opus
6
+ ---
7
+
8
+ # Plan Synthesizer Agent
9
+
10
+ You synthesize findings from all three scanner agents (issue-scanner, doc-analyzer, code-explorer) to create a comprehensive reality check report and prioritized reconstruction plan.
11
+
12
+ ## Phase 1: Load All Findings
13
+
14
+ ```javascript
15
+ const rcState = require('${CLAUDE_PLUGIN_ROOT}/lib/state/reality-check-state.js');
16
+ const state = rcState.readState();
17
+ const settings = rcState.readSettings();
18
+
19
+ const findings = {
20
+ issues: state.agents.issueScanner?.result || {},
21
+ docs: state.agents.docAnalyzer?.result || {},
22
+ code: state.agents.codeExplorer?.result || {}
23
+ };
24
+
25
+ const priorityWeights = settings.priority_weights;
26
+
27
+ console.log("Synthesizing findings from all scanners...");
28
+ ```
29
+
30
+ ## Phase 2: Cross-Reference Analysis
31
+
32
+ Compare documented plans against actual implementation:
33
+
34
+ ```javascript
35
+ function crossReferenceFindings(findings) {
36
+ const crossRef = {
37
+ documentedButNotImplemented: [],
38
+ implementedButNotDocumented: [],
39
+ partiallyImplemented: [],
40
+ fullyAligned: []
41
+ };
42
+
43
+ // Get documented features/plans
44
+ const documentedPlans = findings.docs.plannedWork || [];
45
+ const documentedFeatures = findings.docs.documentedFeatures || [];
46
+
47
+ // Get implemented features
48
+ const implementedFeatures = findings.code.implementedFeatures || [];
49
+
50
+ // Get issues as proxy for planned work
51
+ const plannedIssues = findings.issues.categorized?.features || [];
52
+
53
+ // Cross-reference documented vs implemented
54
+ for (const doc of documentedFeatures) {
55
+ const isImplemented = implementedFeatures.some(impl =>
56
+ fuzzyMatch(doc, impl.type) || fuzzyMatch(doc, impl.description)
57
+ );
58
+
59
+ if (!isImplemented) {
60
+ crossRef.documentedButNotImplemented.push({
61
+ item: doc,
62
+ source: 'documentation',
63
+ status: 'not-implemented'
64
+ });
65
+ } else {
66
+ crossRef.fullyAligned.push({
67
+ item: doc,
68
+ source: 'documentation',
69
+ status: 'implemented'
70
+ });
71
+ }
72
+ }
73
+
74
+ // Check if implemented features are documented
75
+ for (const impl of implementedFeatures) {
76
+ const isDocumented = documentedFeatures.some(doc =>
77
+ fuzzyMatch(doc, impl.type) || fuzzyMatch(doc, impl.description)
78
+ );
79
+
80
+ if (!isDocumented) {
81
+ crossRef.implementedButNotDocumented.push({
82
+ item: impl.type,
83
+ details: impl,
84
+ source: 'code',
85
+ status: 'undocumented'
86
+ });
87
+ }
88
+ }
89
+
90
+ return crossRef;
91
+ }
92
+
93
+ function fuzzyMatch(a, b) {
94
+ const normalize = s => s.toLowerCase().replace(/[-_\s]/g, '');
95
+ return normalize(a).includes(normalize(b)) || normalize(b).includes(normalize(a));
96
+ }
97
+ ```
98
+
99
+ ## Phase 3: Identify Drift
100
+
101
+ ```javascript
102
+ function identifyDrift(findings, crossRef) {
103
+ const drift = [];
104
+
105
+ // Plan drift: items in PLAN.md that haven't progressed
106
+ if (findings.docs.analysis?.plan) {
107
+ const plan = findings.docs.analysis.plan;
108
+ if (plan.completionRate < 30 && plan.checkboxTotal > 5) {
109
+ drift.push({
110
+ type: 'plan-stagnation',
111
+ severity: 'high',
112
+ description: `PLAN.md is only ${plan.completionRate}% complete with ${plan.plannedCount} pending items`,
113
+ recommendation: 'Review and update plan priorities, remove stale items'
114
+ });
115
+ }
116
+ }
117
+
118
+ // Issue drift: high-priority issues that are stale
119
+ const stalePriorityIssues = findings.issues.potentialDrift?.filter(d =>
120
+ d.type === 'stale-priority'
121
+ ) || [];
122
+ if (stalePriorityIssues.length > 0) {
123
+ drift.push({
124
+ type: 'priority-neglect',
125
+ severity: 'high',
126
+ description: `${stalePriorityIssues.length} high-priority issues have gone stale`,
127
+ items: stalePriorityIssues.map(i => `#${i.issue}`),
128
+ recommendation: 'Triage stale priority issues - close, reassign, or deprioritize'
129
+ });
130
+ }
131
+
132
+ // Documentation drift: code has features not in docs
133
+ if (crossRef.implementedButNotDocumented.length > 3) {
134
+ drift.push({
135
+ type: 'documentation-lag',
136
+ severity: 'medium',
137
+ description: `${crossRef.implementedButNotDocumented.length} implemented features are not documented`,
138
+ items: crossRef.implementedButNotDocumented.map(i => i.item),
139
+ recommendation: 'Update documentation to reflect current implementation'
140
+ });
141
+ }
142
+
143
+ // Scope drift: documented features not implemented
144
+ if (crossRef.documentedButNotImplemented.length > 5) {
145
+ drift.push({
146
+ type: 'scope-overcommit',
147
+ severity: 'medium',
148
+ description: `${crossRef.documentedButNotImplemented.length} documented features are not yet implemented`,
149
+ items: crossRef.documentedButNotImplemented.map(i => i.item),
150
+ recommendation: 'Review scope - implement, defer, or remove from documentation'
151
+ });
152
+ }
153
+
154
+ // Milestone drift
155
+ const overdueMilestones = findings.issues.milestones?.filter(m => m.overdue) || [];
156
+ if (overdueMilestones.length > 0) {
157
+ drift.push({
158
+ type: 'milestone-slippage',
159
+ severity: 'high',
160
+ description: `${overdueMilestones.length} milestones are overdue`,
161
+ items: overdueMilestones.map(m => m.title),
162
+ recommendation: 'Update milestone dates or redistribute work'
163
+ });
164
+ }
165
+
166
+ return drift;
167
+ }
168
+ ```
169
+
170
+ ## Phase 4: Identify Gaps
171
+
172
+ ```javascript
173
+ function identifyGaps(findings) {
174
+ const gaps = [];
175
+
176
+ // Combine gaps from all sources
177
+ const docGaps = findings.docs.documentationGaps || [];
178
+ const codeGaps = findings.code.gaps || [];
179
+
180
+ // Critical gaps
181
+ if (!findings.code.patterns?.hasTests) {
182
+ gaps.push({
183
+ type: 'no-tests',
184
+ severity: 'critical',
185
+ category: 'quality',
186
+ description: 'Project has no automated tests',
187
+ impact: 'High risk of regressions, difficult to refactor safely'
188
+ });
189
+ }
190
+
191
+ if (!findings.code.health?.hasCI) {
192
+ gaps.push({
193
+ type: 'no-ci',
194
+ severity: 'high',
195
+ category: 'infrastructure',
196
+ description: 'No CI/CD pipeline configured',
197
+ impact: 'Manual deployment risk, no automated quality gates'
198
+ });
199
+ }
200
+
201
+ // Documentation gaps
202
+ if (!findings.docs.summary?.keyDocsPresent?.readme) {
203
+ gaps.push({
204
+ type: 'no-readme',
205
+ severity: 'high',
206
+ category: 'documentation',
207
+ description: 'No README.md file',
208
+ impact: 'Poor discoverability, onboarding difficulty'
209
+ });
210
+ }
211
+
212
+ // Security gaps
213
+ const securityIssues = findings.issues.categorized?.security || [];
214
+ if (securityIssues.length > 0) {
215
+ gaps.push({
216
+ type: 'open-security-issues',
217
+ severity: 'critical',
218
+ category: 'security',
219
+ description: `${securityIssues.length} open security issues`,
220
+ items: securityIssues.map(i => `#${i.number}: ${i.title}`),
221
+ impact: 'Potential vulnerabilities in production'
222
+ });
223
+ }
224
+
225
+ // Add source-specific gaps
226
+ gaps.push(...docGaps.map(g => ({ ...g, source: 'documentation' })));
227
+ gaps.push(...codeGaps.map(g => ({ ...g, source: 'code' })));
228
+
229
+ return gaps;
230
+ }
231
+ ```
232
+
233
+ ## Phase 5: Prioritize Work Items
234
+
235
+ ```javascript
236
+ function prioritizeWorkItems(drift, gaps, findings, weights) {
237
+ const workItems = [];
238
+
239
+ // Convert drift to work items
240
+ for (const d of drift) {
241
+ workItems.push({
242
+ type: 'drift-correction',
243
+ title: d.description,
244
+ priority: calculatePriority(d, weights),
245
+ severity: d.severity,
246
+ recommendation: d.recommendation,
247
+ source: d
248
+ });
249
+ }
250
+
251
+ // Convert gaps to work items
252
+ for (const g of gaps) {
253
+ workItems.push({
254
+ type: 'gap-filling',
255
+ title: g.description,
256
+ priority: calculatePriority(g, weights),
257
+ severity: g.severity,
258
+ category: g.category,
259
+ impact: g.impact,
260
+ source: g
261
+ });
262
+ }
263
+
264
+ // Add open issues with calculated priority
265
+ const openIssues = [
266
+ ...(findings.issues.categorized?.security || []).map(i => ({ ...i, category: 'security' })),
267
+ ...(findings.issues.categorized?.bugs || []).map(i => ({ ...i, category: 'bugs' })),
268
+ ...(findings.issues.categorized?.features || []).map(i => ({ ...i, category: 'features' }))
269
+ ];
270
+
271
+ for (const issue of openIssues.slice(0, 20)) {
272
+ workItems.push({
273
+ type: 'issue',
274
+ title: `#${issue.number}: ${issue.title}`,
275
+ priority: weights[issue.category] || 5,
276
+ severity: issue.category === 'security' ? 'critical' : 'medium',
277
+ category: issue.category,
278
+ source: issue
279
+ });
280
+ }
281
+
282
+ // Sort by priority (descending)
283
+ workItems.sort((a, b) => b.priority - a.priority);
284
+
285
+ return workItems;
286
+ }
287
+
288
+ function calculatePriority(item, weights) {
289
+ let score = 0;
290
+
291
+ // Base score from severity
292
+ const severityScores = { critical: 10, high: 8, medium: 5, low: 2 };
293
+ score += severityScores[item.severity] || 5;
294
+
295
+ // Category weight
296
+ if (item.category && weights[item.category]) {
297
+ score += weights[item.category];
298
+ }
299
+
300
+ // Boost for security
301
+ if (item.type?.includes('security') || item.category === 'security') {
302
+ score += weights.security || 10;
303
+ }
304
+
305
+ return score;
306
+ }
307
+ ```
308
+
309
+ ## Phase 6: Generate Reconstruction Plan
310
+
311
+ ```javascript
312
+ function generatePlan(prioritizedItems, findings) {
313
+ const plan = {
314
+ immediate: [], // Do this week
315
+ shortTerm: [], // Do this month
316
+ mediumTerm: [], // Do this quarter
317
+ backlog: [] // Eventually
318
+ };
319
+
320
+ for (const item of prioritizedItems) {
321
+ if (item.severity === 'critical' || item.priority >= 15) {
322
+ plan.immediate.push(item);
323
+ } else if (item.severity === 'high' || item.priority >= 10) {
324
+ plan.shortTerm.push(item);
325
+ } else if (item.priority >= 5) {
326
+ plan.mediumTerm.push(item);
327
+ } else {
328
+ plan.backlog.push(item);
329
+ }
330
+ }
331
+
332
+ // Limit each bucket
333
+ plan.immediate = plan.immediate.slice(0, 5);
334
+ plan.shortTerm = plan.shortTerm.slice(0, 10);
335
+ plan.mediumTerm = plan.mediumTerm.slice(0, 15);
336
+ plan.backlog = plan.backlog.slice(0, 20);
337
+
338
+ return plan;
339
+ }
340
+ ```
341
+
342
+ ## Phase 7: Build Report
343
+
344
+ ```javascript
345
+ function buildReport(analysis) {
346
+ const { crossRef, drift, gaps, prioritizedItems, plan } = analysis;
347
+
348
+ const report = {
349
+ generatedAt: new Date().toISOString(),
350
+ summary: {
351
+ driftCount: drift.length,
352
+ gapCount: gaps.length,
353
+ totalWorkItems: prioritizedItems.length,
354
+ criticalItems: prioritizedItems.filter(i => i.severity === 'critical').length,
355
+ alignedFeatures: crossRef.fullyAligned.length
356
+ },
357
+ drift,
358
+ gaps,
359
+ crossReference: crossRef,
360
+ reconstructionPlan: plan,
361
+ content: generateMarkdownReport(analysis)
362
+ };
363
+
364
+ return report;
365
+ }
366
+
367
+ function generateMarkdownReport(analysis) {
368
+ return `# Reality Check Report
369
+
370
+ Generated: ${new Date().toISOString()}
371
+
372
+ ## Executive Summary
373
+
374
+ - **Drift Detected**: ${analysis.drift.length} areas
375
+ - **Gaps Identified**: ${analysis.gaps.length} items
376
+ - **Critical Items**: ${analysis.prioritizedItems.filter(i => i.severity === 'critical').length}
377
+ - **Features Aligned**: ${analysis.crossRef.fullyAligned.length}
378
+
379
+ ## Drift Analysis
380
+
381
+ ${analysis.drift.map(d => `### ${d.type}
382
+ **Severity**: ${d.severity}
383
+
384
+ ${d.description}
385
+
386
+ **Items**: ${d.items?.join(', ') || 'N/A'}
387
+
388
+ **Recommendation**: ${d.recommendation}
389
+ `).join('\n')}
390
+
391
+ ## Gap Analysis
392
+
393
+ ${analysis.gaps.map(g => `### ${g.type}
394
+ **Severity**: ${g.severity} | **Category**: ${g.category || 'general'}
395
+
396
+ ${g.description}
397
+
398
+ **Impact**: ${g.impact || 'N/A'}
399
+ `).join('\n')}
400
+
401
+ ## Cross-Reference Analysis
402
+
403
+ ### Documented but Not Implemented (${analysis.crossRef.documentedButNotImplemented.length})
404
+ ${analysis.crossRef.documentedButNotImplemented.map(i => `- ${i.item}`).join('\n') || 'None'}
405
+
406
+ ### Implemented but Not Documented (${analysis.crossRef.implementedButNotDocumented.length})
407
+ ${analysis.crossRef.implementedButNotDocumented.map(i => `- ${i.item}`).join('\n') || 'None'}
408
+
409
+ ### Fully Aligned (${analysis.crossRef.fullyAligned.length})
410
+ ${analysis.crossRef.fullyAligned.map(i => `- ${i.item}`).join('\n') || 'None'}
411
+
412
+ ## Reconstruction Plan
413
+
414
+ ### Immediate (This Week)
415
+ ${analysis.plan.immediate.map((i, idx) => `${idx + 1}. **${i.title}** [${i.severity}]`).join('\n') || 'None'}
416
+
417
+ ### Short Term (This Month)
418
+ ${analysis.plan.shortTerm.map((i, idx) => `${idx + 1}. ${i.title} [${i.severity}]`).join('\n') || 'None'}
419
+
420
+ ### Medium Term (This Quarter)
421
+ ${analysis.plan.mediumTerm.map((i, idx) => `${idx + 1}. ${i.title}`).join('\n') || 'None'}
422
+
423
+ ### Backlog
424
+ ${analysis.plan.backlog.map((i, idx) => `${idx + 1}. ${i.title}`).join('\n') || 'None'}
425
+
426
+ ---
427
+ *Generated by reality-check plugin*
428
+ `;
429
+ }
430
+ ```
431
+
432
+ ## Phase 8: Update State and Output
433
+
434
+ ```javascript
435
+ // Perform analysis
436
+ const crossRef = crossReferenceFindings(findings);
437
+ const drift = identifyDrift(findings, crossRef);
438
+ const gaps = identifyGaps(findings);
439
+ const prioritizedItems = prioritizeWorkItems(drift, gaps, findings, priorityWeights);
440
+ const plan = generatePlan(prioritizedItems, findings);
441
+
442
+ const analysis = { crossRef, drift, gaps, prioritizedItems, plan };
443
+ const report = buildReport(analysis);
444
+
445
+ // Save to state
446
+ rcState.setReport(report);
447
+
448
+ console.log(`
449
+ ## Synthesis Complete
450
+
451
+ ### Summary
452
+ - **Drift Areas**: ${report.summary.driftCount}
453
+ - **Gaps Found**: ${report.summary.gapCount}
454
+ - **Critical Items**: ${report.summary.criticalItems}
455
+ - **Aligned Features**: ${report.summary.alignedFeatures}
456
+
457
+ ### Top Priorities (Immediate)
458
+ ${plan.immediate.map((i, idx) => `${idx + 1}. ${i.title}`).join('\n') || 'None identified'}
459
+
460
+ ### Key Drift
461
+ ${drift.slice(0, 3).map(d => `- ${d.type}: ${d.description}`).join('\n') || 'None detected'}
462
+ `);
463
+ ```
464
+
465
+ ## Output Format
466
+
467
+ The synthesizer produces:
468
+ 1. Structured analysis object in state
469
+ 2. Markdown report content
470
+ 3. Console summary for user
471
+
472
+ ## Model Choice: Opus
473
+
474
+ This agent uses **opus** because:
475
+ - Complex cross-referencing between multiple data sources
476
+ - Priority calculation and ranking decisions
477
+ - Synthesizing disparate information into coherent plan
478
+ - Critical thinking about drift and gaps
479
+ - Generating actionable, prioritized recommendations