@syntesseraai/opencode-feature-factory 0.6.8 → 0.6.9

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 (96) hide show
  1. package/README.md +6 -4
  2. package/agents/building.md +28 -541
  3. package/agents/documenting.md +39 -0
  4. package/agents/ff-research.md +18 -410
  5. package/agents/pipeline.md +20 -71
  6. package/agents/planning.md +28 -350
  7. package/agents/reviewing.md +27 -475
  8. package/commands/pipeline/building/breakdown.md +4 -3
  9. package/commands/pipeline/building/implement-batch.md +4 -3
  10. package/commands/pipeline/building/run.md +8 -8
  11. package/commands/pipeline/building/validate-batch.md +4 -3
  12. package/commands/pipeline/complete.md +1 -1
  13. package/commands/pipeline/documentation/{run-codex.md → document.md} +3 -4
  14. package/commands/pipeline/documentation/gate.md +3 -3
  15. package/commands/pipeline/documentation/{run-gemini.md → review.md} +4 -3
  16. package/commands/pipeline/documentation/run.md +6 -7
  17. package/commands/pipeline/planning/gate.md +8 -6
  18. package/commands/pipeline/planning/plan.md +25 -0
  19. package/commands/pipeline/planning/run.md +7 -7
  20. package/commands/pipeline/planning/synthesize.md +7 -3
  21. package/commands/pipeline/reviewing/gate.md +3 -3
  22. package/commands/pipeline/reviewing/review.md +20 -0
  23. package/commands/pipeline/reviewing/run.md +6 -6
  24. package/commands/pipeline/reviewing/synthesize.md +3 -3
  25. package/commands/pipeline/reviewing/triage.md +2 -2
  26. package/commands/pipeline/start.md +5 -5
  27. package/dist/index.d.ts +1 -2
  28. package/dist/index.js +3 -52
  29. package/package.json +1 -1
  30. package/skills/ff-reviewing-architecture/SKILL.md +34 -0
  31. package/skills/ff-reviewing-code-quality/SKILL.md +34 -0
  32. package/skills/ff-reviewing-documentation/SKILL.md +34 -0
  33. package/skills/ff-reviewing-security/SKILL.md +34 -0
  34. package/agents/ff-acceptance.md +0 -285
  35. package/agents/ff-building-codex.md +0 -305
  36. package/agents/ff-building-gemini.md +0 -305
  37. package/agents/ff-building-opus.md +0 -305
  38. package/agents/ff-planning-codex.md +0 -335
  39. package/agents/ff-planning-gemini.md +0 -335
  40. package/agents/ff-planning-opus.md +0 -335
  41. package/agents/ff-review.md +0 -288
  42. package/agents/ff-reviewing-codex.md +0 -259
  43. package/agents/ff-reviewing-gemini.md +0 -259
  44. package/agents/ff-reviewing-opus.md +0 -259
  45. package/agents/ff-security.md +0 -322
  46. package/agents/ff-validate.md +0 -316
  47. package/agents/ff-well-architected.md +0 -284
  48. package/commands/pipeline/planning/run-codex.md +0 -22
  49. package/commands/pipeline/planning/run-gemini.md +0 -21
  50. package/commands/pipeline/planning/run-opus.md +0 -21
  51. package/commands/pipeline/reviewing/run-codex.md +0 -12
  52. package/commands/pipeline/reviewing/run-gemini.md +0 -11
  53. package/commands/pipeline/reviewing/run-opus.md +0 -11
  54. package/dist/agent-context.d.ts +0 -57
  55. package/dist/agent-context.js +0 -282
  56. package/dist/plugins/ff-agent-context-create-plugin.d.ts +0 -2
  57. package/dist/plugins/ff-agent-context-create-plugin.js +0 -82
  58. package/dist/plugins/ff-agent-context-update-plugin.d.ts +0 -2
  59. package/dist/plugins/ff-agent-context-update-plugin.js +0 -78
  60. package/dist/plugins/ff-agents-clear-plugin.d.ts +0 -2
  61. package/dist/plugins/ff-agents-clear-plugin.js +0 -40
  62. package/dist/plugins/ff-agents-current-plugin.d.ts +0 -2
  63. package/dist/plugins/ff-agents-current-plugin.js +0 -45
  64. package/dist/plugins/ff-agents-delete-plugin.d.ts +0 -2
  65. package/dist/plugins/ff-agents-delete-plugin.js +0 -32
  66. package/dist/plugins/ff-agents-get-plugin.d.ts +0 -2
  67. package/dist/plugins/ff-agents-get-plugin.js +0 -32
  68. package/dist/plugins/ff-agents-list-plugin.d.ts +0 -2
  69. package/dist/plugins/ff-agents-list-plugin.js +0 -42
  70. package/dist/plugins/ff-agents-show-plugin.d.ts +0 -2
  71. package/dist/plugins/ff-agents-show-plugin.js +0 -22
  72. package/dist/plugins/ff-agents-update-plugin.d.ts +0 -2
  73. package/dist/plugins/ff-agents-update-plugin.js +0 -32
  74. package/dist/plugins/ff-plan-create-plugin.d.ts +0 -2
  75. package/dist/plugins/ff-plan-create-plugin.js +0 -61
  76. package/dist/plugins/ff-plan-update-plugin.d.ts +0 -2
  77. package/dist/plugins/ff-plan-update-plugin.js +0 -142
  78. package/dist/plugins/ff-plans-delete-plugin.d.ts +0 -2
  79. package/dist/plugins/ff-plans-delete-plugin.js +0 -32
  80. package/dist/plugins/ff-plans-get-plugin.d.ts +0 -2
  81. package/dist/plugins/ff-plans-get-plugin.js +0 -32
  82. package/dist/plugins/ff-plans-list-plugin.d.ts +0 -2
  83. package/dist/plugins/ff-plans-list-plugin.js +0 -42
  84. package/dist/plugins/ff-plans-update-plugin.d.ts +0 -2
  85. package/dist/plugins/ff-plans-update-plugin.js +0 -32
  86. package/dist/plugins/ff-review-create-plugin.d.ts +0 -2
  87. package/dist/plugins/ff-review-create-plugin.js +0 -256
  88. package/dist/plugins/ff-reviews-get-plugin.d.ts +0 -2
  89. package/dist/plugins/ff-reviews-get-plugin.js +0 -32
  90. package/dist/plugins/ff-reviews-list-plugin.d.ts +0 -2
  91. package/dist/plugins/ff-reviews-list-plugin.js +0 -42
  92. package/dist/plugins/ff-reviews-update-plugin.d.ts +0 -2
  93. package/dist/plugins/ff-reviews-update-plugin.js +0 -32
  94. package/skills/ff-context-tracking/SKILL.md +0 -573
  95. package/skills/ff-delegation/SKILL.md +0 -457
  96. package/skills/ff-swarm/SKILL.md +0 -209
@@ -1,256 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- import { writeFile, mkdir } from 'fs/promises';
3
- import { dirname } from 'path';
4
- export function createFFReviewCreateTool() {
5
- return tool({
6
- description: 'Create a new review report file in .feature-factory/reviews/. Use this to document review findings, validation results, or audit reports.',
7
- args: {
8
- title: tool.schema.string().describe('Title of the review'),
9
- description: tool.schema.string().describe('Brief description of what was reviewed'),
10
- reviewType: tool.schema
11
- .enum([
12
- 'code-review',
13
- 'security-audit',
14
- 'acceptance-validation',
15
- 'architecture-review',
16
- 'comprehensive-validation',
17
- ])
18
- .describe('Type of review performed'),
19
- target: tool.schema.string().describe('What was reviewed (e.g., PR #123, feature X, file Y)'),
20
- verdict: tool.schema
21
- .enum(['approved', 'changes-requested', 'rejected'])
22
- .describe('Overall review verdict'),
23
- confidence: tool.schema.number().min(0).max(100).describe('Confidence score (0-100)'),
24
- findings: tool.schema
25
- .array(tool.schema.object({
26
- severity: tool.schema
27
- .enum(['critical', 'high', 'medium', 'low'])
28
- .describe('Severity level'),
29
- category: tool.schema
30
- .string()
31
- .describe('Category (e.g., security, quality, performance)'),
32
- file: tool.schema.string().optional().describe('Affected file path'),
33
- line: tool.schema.number().optional().describe('Line number'),
34
- description: tool.schema.string().describe('Description of the finding'),
35
- recommendation: tool.schema.string().describe('Recommended fix or improvement'),
36
- }))
37
- .optional()
38
- .describe('List of findings/issues discovered'),
39
- positives: tool.schema
40
- .array(tool.schema.string())
41
- .optional()
42
- .describe('List of positive observations'),
43
- metrics: tool.schema
44
- .object({
45
- testsPassed: tool.schema.string().optional(),
46
- coverage: tool.schema.string().optional(),
47
- securityScore: tool.schema.number().optional(),
48
- qualityScore: tool.schema.number().optional(),
49
- })
50
- .optional()
51
- .describe('Review metrics and scores'),
52
- actionItems: tool.schema
53
- .array(tool.schema.object({
54
- priority: tool.schema
55
- .enum(['critical', 'high', 'medium', 'low'])
56
- .describe('Priority level'),
57
- description: tool.schema.string().describe('Action item description'),
58
- assignee: tool.schema.string().optional().describe('Who should address this'),
59
- }))
60
- .optional()
61
- .describe('Action items to address findings'),
62
- relatedPlan: tool.schema.string().optional().describe('ID of related implementation plan'),
63
- relatedAgent: tool.schema
64
- .string()
65
- .optional()
66
- .describe('UUID of agent that performed the review'),
67
- notes: tool.schema.string().optional().describe('Additional notes or context'),
68
- },
69
- async execute(args, toolCtx) {
70
- try {
71
- const timestamp = new Date().toISOString();
72
- const reviewId = `${timestamp.replace(/[:.]/g, '-').slice(0, 19)}-${args.reviewType}`;
73
- const filePath = `${toolCtx.directory}/.feature-factory/reviews/${reviewId}.md`;
74
- // Generate frontmatter
75
- const frontmatter = `---
76
- id: "${reviewId}"
77
- title: "${args.title}"
78
- description: "${args.description}"
79
- created: "${timestamp}"
80
- review_type: "${args.reviewType}"
81
- target: "${args.target}"
82
- verdict: "${args.verdict}"
83
- confidence: ${args.confidence}
84
- ${args.relatedPlan ? `related_plan: "${args.relatedPlan}"` : ''}
85
- ${args.relatedAgent ? `related_agent: "${args.relatedAgent}"` : ''}
86
- ---`;
87
- // Generate review content
88
- let content = `# ${args.title}
89
-
90
- **Review Type:** ${args.reviewType}
91
- **Target:** ${args.target}
92
- **Verdict:** ${args.verdict === 'approved' ? '✅ Approved' : args.verdict === 'changes-requested' ? '⚠️ Changes Requested' : '❌ Rejected'}
93
- **Confidence:** ${args.confidence}%
94
- **Date:** ${timestamp}
95
-
96
- ## Summary
97
-
98
- ${args.description}
99
-
100
- `;
101
- // Add metrics if provided
102
- if (args.metrics && Object.keys(args.metrics).length > 0) {
103
- content += `## Metrics
104
-
105
- `;
106
- if (args.metrics.testsPassed) {
107
- content += `- **Tests Passed:** ${args.metrics.testsPassed}\n`;
108
- }
109
- if (args.metrics.coverage) {
110
- content += `- **Coverage:** ${args.metrics.coverage}\n`;
111
- }
112
- if (args.metrics.securityScore !== undefined) {
113
- content += `- **Security Score:** ${args.metrics.securityScore}/100\n`;
114
- }
115
- if (args.metrics.qualityScore !== undefined) {
116
- content += `- **Quality Score:** ${args.metrics.qualityScore}/100\n`;
117
- }
118
- content += `\n`;
119
- }
120
- // Add findings
121
- if (args.findings && args.findings.length > 0) {
122
- const critical = args.findings.filter((f) => f.severity === 'critical');
123
- const high = args.findings.filter((f) => f.severity === 'high');
124
- const medium = args.findings.filter((f) => f.severity === 'medium');
125
- const low = args.findings.filter((f) => f.severity === 'low');
126
- if (critical.length > 0) {
127
- content += `## 🚨 Critical Issues (${critical.length})
128
-
129
- `;
130
- critical.forEach((finding, idx) => {
131
- content += `### ${idx + 1}. ${finding.category}: ${finding.description.substring(0, 50)}${finding.description.length > 50 ? '...' : ''}\n\n`;
132
- content += `- **Severity:** Critical\n`;
133
- if (finding.file) {
134
- content += `- **Location:** \`${finding.file}${finding.line ? `:${finding.line}` : ''}\`\n`;
135
- }
136
- content += `- **Description:** ${finding.description}\n`;
137
- content += `- **Recommendation:** ${finding.recommendation}\n\n`;
138
- });
139
- }
140
- if (high.length > 0) {
141
- content += `## ⚠️ High Priority Issues (${high.length})
142
-
143
- `;
144
- high.forEach((finding, idx) => {
145
- content += `### ${idx + 1}. ${finding.category}: ${finding.description.substring(0, 50)}${finding.description.length > 50 ? '...' : ''}\n\n`;
146
- content += `- **Severity:** High\n`;
147
- if (finding.file) {
148
- content += `- **Location:** \`${finding.file}${finding.line ? `:${finding.line}` : ''}\`\n`;
149
- }
150
- content += `- **Description:** ${finding.description}\n`;
151
- content += `- **Recommendation:** ${finding.recommendation}\n\n`;
152
- });
153
- }
154
- if (medium.length > 0) {
155
- content += `## 🟡 Medium Priority Issues (${medium.length})
156
-
157
- `;
158
- medium.forEach((finding, idx) => {
159
- content += `${idx + 1}. **${finding.category}:** ${finding.description}\n`;
160
- if (finding.recommendation) {
161
- content += ` - *Recommendation:* ${finding.recommendation}\n`;
162
- }
163
- });
164
- content += `\n`;
165
- }
166
- if (low.length > 0) {
167
- content += `## 🟢 Low Priority / Suggestions (${low.length})
168
-
169
- `;
170
- low.forEach((finding, idx) => {
171
- content += `${idx + 1}. **${finding.category}:** ${finding.description}\n`;
172
- if (finding.recommendation) {
173
- content += ` - *Suggestion:* ${finding.recommendation}\n`;
174
- }
175
- });
176
- content += `\n`;
177
- }
178
- }
179
- // Add positives
180
- if (args.positives && args.positives.length > 0) {
181
- content += `## ✅ Positives
182
-
183
- `;
184
- args.positives.forEach((positive) => {
185
- content += `- ${positive}\n`;
186
- });
187
- content += `\n`;
188
- }
189
- // Add action items
190
- if (args.actionItems && args.actionItems.length > 0) {
191
- content += `## 📋 Action Items
192
-
193
- `;
194
- const critical = args.actionItems.filter((a) => a.priority === 'critical');
195
- const high = args.actionItems.filter((a) => a.priority === 'high');
196
- const medium = args.actionItems.filter((a) => a.priority === 'medium');
197
- const low = args.actionItems.filter((a) => a.priority === 'low');
198
- if (critical.length > 0) {
199
- content += `### 🔴 Critical (Must Fix)\n\n`;
200
- critical.forEach((item, idx) => {
201
- content += `${idx + 1}. ${item.description}${item.assignee ? ` (@${item.assignee})` : ''}\n`;
202
- });
203
- content += `\n`;
204
- }
205
- if (high.length > 0) {
206
- content += `### 🟠 High Priority (Should Fix)\n\n`;
207
- high.forEach((item, idx) => {
208
- content += `${idx + 1}. ${item.description}${item.assignee ? ` (@${item.assignee})` : ''}\n`;
209
- });
210
- content += `\n`;
211
- }
212
- if (medium.length > 0) {
213
- content += `### 🟡 Medium Priority (Fix if Time)\n\n`;
214
- medium.forEach((item, idx) => {
215
- content += `${idx + 1}. ${item.description}${item.assignee ? ` (@${item.assignee})` : ''}\n`;
216
- });
217
- content += `\n`;
218
- }
219
- if (low.length > 0) {
220
- content += `### 🟢 Low Priority (Optional)\n\n`;
221
- low.forEach((item, idx) => {
222
- content += `${idx + 1}. ${item.description}${item.assignee ? ` (@${item.assignee})` : ''}\n`;
223
- });
224
- content += `\n`;
225
- }
226
- }
227
- // Add notes
228
- if (args.notes) {
229
- content += `## 📝 Notes
230
-
231
- ${args.notes}\n\n`;
232
- }
233
- const fullContent = `${frontmatter}\n\n${content}`;
234
- // Ensure directory exists
235
- await mkdir(dirname(filePath), { recursive: true });
236
- // Write file
237
- await writeFile(filePath, fullContent, 'utf-8');
238
- return JSON.stringify({
239
- success: true,
240
- reviewId,
241
- filePath: `.feature-factory/reviews/${reviewId}.md`,
242
- message: `Review created successfully at .feature-factory/reviews/${reviewId}.md`,
243
- verdict: args.verdict,
244
- confidence: args.confidence,
245
- findingsCount: args.findings?.length || 0,
246
- }, null, 2);
247
- }
248
- catch (error) {
249
- return JSON.stringify({
250
- success: false,
251
- error: `Failed to create review: ${error}`,
252
- }, null, 2);
253
- }
254
- },
255
- });
256
- }
@@ -1,2 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- export declare function createFFReviewsGetTool(): ReturnType<typeof tool>;
@@ -1,32 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- import { validateSafePath, resolveSafePath, getFeatureFactoryDir } from '../utils/file-utils.js';
3
- import { readFile } from 'fs/promises';
4
- export function createFFReviewsGetTool() {
5
- return tool({
6
- description: 'Read a review file by name from .feature-factory/reviews',
7
- args: {
8
- fileName: tool.schema
9
- .string()
10
- .describe('Name of the review file (e.g., "security-audit-abc123.md")'),
11
- },
12
- async execute(args, toolCtx) {
13
- try {
14
- const reviewsDir = getFeatureFactoryDir(toolCtx.directory, 'reviews');
15
- // Validate the file path
16
- if (!validateSafePath(reviewsDir, args.fileName)) {
17
- return `Error: Invalid or unsafe file name "${args.fileName}". Only .md files with alphanumeric names are allowed.`;
18
- }
19
- const filePath = resolveSafePath(reviewsDir, args.fileName);
20
- // Read file content
21
- const content = await readFile(filePath, 'utf-8');
22
- return content;
23
- }
24
- catch (error) {
25
- if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
26
- return `Error: File "${args.fileName}" not found in .feature-factory/reviews`;
27
- }
28
- return `Error reading review file: ${error}`;
29
- }
30
- },
31
- });
32
- }
@@ -1,2 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- export declare function createFFReviewsListTool(): ReturnType<typeof tool>;
@@ -1,42 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- import { validateSafePattern, ensureDirectoryExists, getFeatureFactoryDir, } from '../utils/file-utils.js';
3
- import { readdir } from 'fs/promises';
4
- export function createFFReviewsListTool() {
5
- return tool({
6
- description: 'List all review files in .feature-factory/reviews',
7
- args: {
8
- pattern: tool.schema
9
- .string()
10
- .optional()
11
- .describe('Optional filter pattern (e.g., "security-*.md")'),
12
- },
13
- async execute(args, toolCtx) {
14
- try {
15
- const reviewsDir = getFeatureFactoryDir(toolCtx.directory, 'reviews');
16
- // Ensure the reviews directory exists
17
- await ensureDirectoryExists(reviewsDir);
18
- // List files
19
- const entries = await readdir(reviewsDir, { withFileTypes: true });
20
- let files = entries
21
- .filter((entry) => entry.isFile() && entry.name.endsWith('.md'))
22
- .map((entry) => entry.name);
23
- // Apply pattern filter if provided
24
- if (args.pattern) {
25
- if (!validateSafePattern(args.pattern)) {
26
- return `Error: Invalid pattern "${args.pattern}". Only safe pattern characters are allowed.`;
27
- }
28
- // Simple glob-like matching
29
- const regex = new RegExp('^' + args.pattern.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
30
- files = files.filter((f) => regex.test(f));
31
- }
32
- if (files.length === 0) {
33
- return 'No review files found in .feature-factory/reviews';
34
- }
35
- return JSON.stringify(files, null, 2);
36
- }
37
- catch (error) {
38
- return `Error listing review files: ${error}`;
39
- }
40
- },
41
- });
42
- }
@@ -1,2 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- export declare function createFFReviewsUpdateTool(): ReturnType<typeof tool>;
@@ -1,32 +0,0 @@
1
- import { tool } from '@opencode-ai/plugin/tool';
2
- import { validateSafePath, resolveSafePath, ensureDirectoryExists, getFeatureFactoryDir, } from '../utils/file-utils.js';
3
- import { writeFile } from 'fs/promises';
4
- export function createFFReviewsUpdateTool() {
5
- return tool({
6
- description: 'Create or update a review file in .feature-factory/reviews',
7
- args: {
8
- fileName: tool.schema
9
- .string()
10
- .describe('Name of the review file (e.g., "security-audit-abc123.md")'),
11
- content: tool.schema.string().describe('Content to write to the file'),
12
- },
13
- async execute(args, toolCtx) {
14
- try {
15
- const reviewsDir = getFeatureFactoryDir(toolCtx.directory, 'reviews');
16
- // Validate the file path
17
- if (!validateSafePath(reviewsDir, args.fileName)) {
18
- return `Error: Invalid or unsafe file name "${args.fileName}". Only .md files with alphanumeric names are allowed.`;
19
- }
20
- // Ensure the reviews directory exists
21
- await ensureDirectoryExists(reviewsDir);
22
- const filePath = resolveSafePath(reviewsDir, args.fileName);
23
- // Write file content
24
- await writeFile(filePath, args.content, 'utf-8');
25
- return `Successfully updated review file: ${args.fileName}`;
26
- }
27
- catch (error) {
28
- return `Error updating review file: ${error}`;
29
- }
30
- },
31
- });
32
- }