claude-autopm 1.31.0 → 2.1.1
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/README.md +57 -5
- package/autopm/.claude/mcp/test-server.md +10 -0
- package/bin/autopm-poc.js +176 -44
- package/bin/autopm.js +97 -179
- package/lib/ai-providers/AbstractAIProvider.js +524 -0
- package/lib/ai-providers/ClaudeProvider.js +359 -48
- package/lib/ai-providers/TemplateProvider.js +432 -0
- package/lib/cli/commands/agent.js +206 -0
- package/lib/cli/commands/config.js +488 -0
- package/lib/cli/commands/prd.js +345 -0
- package/lib/cli/commands/task.js +206 -0
- package/lib/config/ConfigManager.js +531 -0
- package/lib/errors/AIProviderError.js +164 -0
- package/lib/services/AgentService.js +557 -0
- package/lib/services/EpicService.js +609 -0
- package/lib/services/PRDService.js +928 -103
- package/lib/services/TaskService.js +760 -0
- package/lib/services/interfaces.js +753 -0
- package/lib/utils/CircuitBreaker.js +165 -0
- package/lib/utils/Encryption.js +201 -0
- package/lib/utils/RateLimiter.js +241 -0
- package/lib/utils/ServiceFactory.js +165 -0
- package/package.json +6 -5
- package/scripts/config/get.js +108 -0
- package/scripts/config/init.js +100 -0
- package/scripts/config/list-providers.js +93 -0
- package/scripts/config/set-api-key.js +107 -0
- package/scripts/config/set-provider.js +201 -0
- package/scripts/config/set.js +139 -0
- package/scripts/config/show.js +181 -0
- package/autopm/.claude/.env +0 -158
- package/autopm/.claude/settings.local.json +0 -9
|
@@ -0,0 +1,753 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Interfaces for ClaudeAutoPM
|
|
3
|
+
*
|
|
4
|
+
* This module defines TypeScript-style interfaces using JSDoc for all service layers.
|
|
5
|
+
* These interfaces provide:
|
|
6
|
+
* - Type safety through JSDoc annotations
|
|
7
|
+
* - Clear contracts for service implementations
|
|
8
|
+
* - IDE autocomplete and IntelliSense support
|
|
9
|
+
* - Documentation for API consumers
|
|
10
|
+
*
|
|
11
|
+
* @module services/interfaces
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// ============================================================================
|
|
15
|
+
// COMMON TYPES
|
|
16
|
+
// ============================================================================
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @typedef {Object} ConfigManager
|
|
20
|
+
* @property {function(string, *): void} set - Set configuration value
|
|
21
|
+
* @property {function(string): *} get - Get configuration value
|
|
22
|
+
* @property {function(string): void} setMasterPassword - Set master password
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @typedef {Object} AIProvider
|
|
27
|
+
* @property {function(string, Object=): Promise<string>} complete - Complete a prompt
|
|
28
|
+
* @property {function(string, Object=): AsyncGenerator<string>} stream - Stream completion
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @typedef {Object} TaskObject
|
|
33
|
+
* @property {string} id - Task identifier (e.g., "TASK-001")
|
|
34
|
+
* @property {string} title - Task title
|
|
35
|
+
* @property {string} description - Task description
|
|
36
|
+
* @property {string} status - Task status (pending, in_progress, completed, blocked)
|
|
37
|
+
* @property {string} type - Task type (development, testing, documentation, etc.)
|
|
38
|
+
* @property {string} effort - Effort estimate (e.g., "2d", "8h")
|
|
39
|
+
* @property {string[]} [dependencies] - Array of dependent task IDs
|
|
40
|
+
* @property {number} [priority] - Priority level (1=highest)
|
|
41
|
+
* @property {string} [assignee] - Assigned developer
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {Object} MetadataObject
|
|
46
|
+
* @property {string} id - Unique identifier
|
|
47
|
+
* @property {string} title - Document title
|
|
48
|
+
* @property {string} status - Current status
|
|
49
|
+
* @property {string} created - Creation timestamp
|
|
50
|
+
* @property {string} updated - Last update timestamp
|
|
51
|
+
* @property {Object} [additionalFields] - Additional metadata fields
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {Object} ProgressObject
|
|
56
|
+
* @property {string} bar - Visual progress bar (e.g., "████████░░ 80%")
|
|
57
|
+
* @property {number} percent - Completion percentage (0-100)
|
|
58
|
+
* @property {number} filled - Number of filled characters
|
|
59
|
+
* @property {number} empty - Number of empty characters
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* @typedef {Object} PRDSections
|
|
64
|
+
* @property {string} vision - Product vision
|
|
65
|
+
* @property {string} problem - Problem statement
|
|
66
|
+
* @property {string} users - Target users
|
|
67
|
+
* @property {string[]} features - List of features
|
|
68
|
+
* @property {string[]} requirements - List of requirements
|
|
69
|
+
* @property {string} metrics - Success metrics
|
|
70
|
+
* @property {string} technical - Technical approach
|
|
71
|
+
* @property {string} timeline - Project timeline
|
|
72
|
+
* @property {Array<{raw: string}>} [userStories] - Parsed user stories
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @typedef {Object} TaskStatistics
|
|
77
|
+
* @property {number} total - Total number of tasks
|
|
78
|
+
* @property {number} open - Number of open tasks
|
|
79
|
+
* @property {number} closed - Number of closed tasks
|
|
80
|
+
* @property {number} blocked - Number of blocked tasks
|
|
81
|
+
* @property {number} completionPercentage - Overall completion (0-100)
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @typedef {Object} ValidationResult
|
|
86
|
+
* @property {boolean} valid - Whether validation passed
|
|
87
|
+
* @property {string[]} errors - Array of error messages
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
// ============================================================================
|
|
91
|
+
// SERVICE INTERFACES
|
|
92
|
+
// ============================================================================
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* PRD Service Interface
|
|
96
|
+
*
|
|
97
|
+
* Provides methods for parsing, analyzing, and managing Product Requirements Documents.
|
|
98
|
+
* All methods are synchronous and pure (no side effects).
|
|
99
|
+
*
|
|
100
|
+
* @interface IPRDService
|
|
101
|
+
* @example
|
|
102
|
+
* const prdService = new PRDService({ defaultEffortHours: 8 });
|
|
103
|
+
* const frontmatter = prdService.parseFrontmatter(content);
|
|
104
|
+
* const sections = prdService.extractPrdContent(content);
|
|
105
|
+
*/
|
|
106
|
+
class IPRDService {
|
|
107
|
+
/**
|
|
108
|
+
* Create a new PRDService instance
|
|
109
|
+
* @param {Object} [options] - Service options
|
|
110
|
+
* @param {ConfigManager} [options.configManager] - Configuration manager
|
|
111
|
+
* @param {AIProvider} [options.provider] - AI provider for advanced operations
|
|
112
|
+
* @param {number} [options.defaultEffortHours=8] - Default effort in hours
|
|
113
|
+
* @param {number} [options.hoursPerDay=8] - Working hours per day
|
|
114
|
+
* @param {number} [options.hoursPerWeek=40] - Working hours per week
|
|
115
|
+
*/
|
|
116
|
+
constructor(options = {}) {}
|
|
117
|
+
|
|
118
|
+
// ========================================================================
|
|
119
|
+
// TIER 1: Pure Parsing Methods
|
|
120
|
+
// ========================================================================
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Parse YAML frontmatter from markdown content
|
|
124
|
+
* @param {string} content - Markdown content with frontmatter
|
|
125
|
+
* @returns {Object|null} Parsed frontmatter object or null if none found
|
|
126
|
+
* @example
|
|
127
|
+
* const fm = service.parseFrontmatter('---\ntitle: My PRD\n---\nContent');
|
|
128
|
+
* // Returns: { title: 'My PRD' }
|
|
129
|
+
*/
|
|
130
|
+
parseFrontmatter(content) {}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Extract PRD sections from content
|
|
134
|
+
* @param {string} content - PRD markdown content
|
|
135
|
+
* @param {Object} [options] - Extraction options
|
|
136
|
+
* @param {boolean} [options.useAdvancedParser=false] - Use advanced parser
|
|
137
|
+
* @returns {PRDSections} Extracted sections
|
|
138
|
+
* @example
|
|
139
|
+
* const sections = service.extractPrdContent(prdContent);
|
|
140
|
+
* console.log(sections.features); // Array of feature strings
|
|
141
|
+
*/
|
|
142
|
+
extractPrdContent(content, options = {}) {}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Parse user stories from text
|
|
146
|
+
* @param {string} text - Text containing user stories
|
|
147
|
+
* @returns {Array<{raw: string}>} Array of parsed user stories
|
|
148
|
+
* @example
|
|
149
|
+
* const stories = service.parseUserStories('As a user, I want...');
|
|
150
|
+
* // Returns: [{ raw: 'As a user, I want...' }]
|
|
151
|
+
*/
|
|
152
|
+
parseUserStories(text) {}
|
|
153
|
+
|
|
154
|
+
// ========================================================================
|
|
155
|
+
// TIER 3: Utility Methods
|
|
156
|
+
// ========================================================================
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Parse effort string to hours
|
|
160
|
+
* @param {string|number} effort - Effort string (e.g., "2d", "4h", "1w") or hours
|
|
161
|
+
* @returns {number} Total hours
|
|
162
|
+
* @example
|
|
163
|
+
* service.parseEffort('2d'); // Returns: 16 (assuming 8h/day)
|
|
164
|
+
* service.parseEffort('1w'); // Returns: 40 (assuming 40h/week)
|
|
165
|
+
*/
|
|
166
|
+
parseEffort(effort) {}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Format hours to readable effort string
|
|
170
|
+
* @param {number} hours - Hours to format
|
|
171
|
+
* @returns {string} Formatted effort (e.g., "1w 2d 4h")
|
|
172
|
+
* @example
|
|
173
|
+
* service.formatEffort(44); // Returns: "1w 4h"
|
|
174
|
+
*/
|
|
175
|
+
formatEffort(hours) {}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Calculate total effort across all tasks
|
|
179
|
+
* @param {TaskObject[]} tasks - Array of tasks
|
|
180
|
+
* @returns {string} Total effort formatted
|
|
181
|
+
* @example
|
|
182
|
+
* service.calculateTotalEffort([
|
|
183
|
+
* { effort: '2d' },
|
|
184
|
+
* { effort: '8h' }
|
|
185
|
+
* ]); // Returns: "3d"
|
|
186
|
+
*/
|
|
187
|
+
calculateTotalEffort(tasks) {}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Calculate effort for tasks of specific type
|
|
191
|
+
* @param {TaskObject[]} tasks - Array of tasks
|
|
192
|
+
* @param {string} type - Task type to filter by
|
|
193
|
+
* @returns {string} Total effort formatted
|
|
194
|
+
* @example
|
|
195
|
+
* service.calculateEffortByType(tasks, 'development'); // Returns: "5d"
|
|
196
|
+
*/
|
|
197
|
+
calculateEffortByType(tasks, type) {}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Generate epic ID from PRD ID
|
|
201
|
+
* @param {string} prdId - PRD identifier (e.g., "prd-347")
|
|
202
|
+
* @returns {string} Epic ID (e.g., "epic-347")
|
|
203
|
+
* @example
|
|
204
|
+
* service.generateEpicId('prd-347'); // Returns: "epic-347"
|
|
205
|
+
*/
|
|
206
|
+
generateEpicId(prdId) {}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Slugify text for filesystem-safe names
|
|
210
|
+
* @param {string} text - Text to slugify
|
|
211
|
+
* @returns {string} Slugified text
|
|
212
|
+
* @example
|
|
213
|
+
* service.slugify('My Feature Name!'); // Returns: "my-feature-name"
|
|
214
|
+
*/
|
|
215
|
+
slugify(text) {}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Determine if PRD is complex (needs splitting)
|
|
219
|
+
* @param {string} technicalApproach - Technical approach text
|
|
220
|
+
* @param {TaskObject[]} tasks - Array of tasks
|
|
221
|
+
* @returns {boolean} True if complex (3+ components or 10+ tasks)
|
|
222
|
+
* @example
|
|
223
|
+
* const complex = service.isComplexPrd(approach, tasks);
|
|
224
|
+
*/
|
|
225
|
+
isComplexPrd(technicalApproach, tasks) {}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Epic Service Interface
|
|
230
|
+
*
|
|
231
|
+
* Provides methods for managing epics, including status tracking,
|
|
232
|
+
* GitHub integration, and content generation.
|
|
233
|
+
* Requires PRDService for dependency injection.
|
|
234
|
+
*
|
|
235
|
+
* @interface IEpicService
|
|
236
|
+
* @example
|
|
237
|
+
* const epicService = new EpicService({ prdService });
|
|
238
|
+
* const progress = epicService.calculateProgress(tasks);
|
|
239
|
+
*/
|
|
240
|
+
class IEpicService {
|
|
241
|
+
/**
|
|
242
|
+
* Create a new EpicService instance
|
|
243
|
+
* @param {Object} options - Service options (REQUIRED)
|
|
244
|
+
* @param {IPRDService} options.prdService - PRD service instance (REQUIRED)
|
|
245
|
+
* @param {ConfigManager} [options.configManager] - Configuration manager
|
|
246
|
+
* @throws {Error} If prdService is missing or invalid
|
|
247
|
+
*/
|
|
248
|
+
constructor(options) {}
|
|
249
|
+
|
|
250
|
+
// ========================================================================
|
|
251
|
+
// Status & Categorization
|
|
252
|
+
// ========================================================================
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Categorize status into standard buckets
|
|
256
|
+
* @param {string} status - Raw status string
|
|
257
|
+
* @returns {string} Categorized status: 'backlog'|'planning'|'in_progress'|'done'
|
|
258
|
+
* @example
|
|
259
|
+
* service.categorizeStatus('in-progress'); // Returns: "in_progress"
|
|
260
|
+
*/
|
|
261
|
+
categorizeStatus(status) {}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Check if task is closed/completed
|
|
265
|
+
* @param {TaskObject} task - Task to check
|
|
266
|
+
* @returns {boolean} True if task is closed
|
|
267
|
+
* @example
|
|
268
|
+
* service.isTaskClosed({ status: 'completed' }); // Returns: true
|
|
269
|
+
*/
|
|
270
|
+
isTaskClosed(task) {}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Calculate completion percentage
|
|
274
|
+
* @param {TaskObject[]} tasks - Array of tasks
|
|
275
|
+
* @returns {number} Completion percentage (0-100)
|
|
276
|
+
* @example
|
|
277
|
+
* service.calculateProgress([
|
|
278
|
+
* { status: 'completed' },
|
|
279
|
+
* { status: 'pending' }
|
|
280
|
+
* ]); // Returns: 50
|
|
281
|
+
*/
|
|
282
|
+
calculateProgress(tasks) {}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Generate visual progress bar
|
|
286
|
+
* @param {number} percent - Percentage (0-100)
|
|
287
|
+
* @param {number} [totalChars=20] - Total bar width
|
|
288
|
+
* @returns {ProgressObject} Progress bar object
|
|
289
|
+
* @example
|
|
290
|
+
* const bar = service.generateProgressBar(75);
|
|
291
|
+
* console.log(bar.bar); // "███████████████░░░░░ 75%"
|
|
292
|
+
*/
|
|
293
|
+
generateProgressBar(percent, totalChars = 20) {}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Validate dependencies format
|
|
297
|
+
* @param {string[]|string} dependencies - Dependencies to validate
|
|
298
|
+
* @returns {boolean} True if valid
|
|
299
|
+
* @example
|
|
300
|
+
* service.hasValidDependencies(['TASK-001', 'TASK-002']); // Returns: true
|
|
301
|
+
*/
|
|
302
|
+
hasValidDependencies(dependencies) {}
|
|
303
|
+
|
|
304
|
+
// ========================================================================
|
|
305
|
+
// GitHub Integration
|
|
306
|
+
// ========================================================================
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Extract issue number from GitHub URL
|
|
310
|
+
* @param {string} githubUrl - GitHub issue URL
|
|
311
|
+
* @returns {string|null} Issue number or null
|
|
312
|
+
* @example
|
|
313
|
+
* service.extractGitHubIssue('https://github.com/org/repo/issues/42');
|
|
314
|
+
* // Returns: "42"
|
|
315
|
+
*/
|
|
316
|
+
extractGitHubIssue(githubUrl) {}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Format GitHub issue URL
|
|
320
|
+
* @param {string} repoOwner - Repository owner
|
|
321
|
+
* @param {string} repoName - Repository name
|
|
322
|
+
* @param {string|number} issueNumber - Issue number
|
|
323
|
+
* @returns {string} Formatted GitHub URL
|
|
324
|
+
* @throws {Error} If parameters are missing
|
|
325
|
+
* @example
|
|
326
|
+
* service.formatGitHubUrl('owner', 'repo', 42);
|
|
327
|
+
* // Returns: "https://github.com/owner/repo/issues/42"
|
|
328
|
+
*/
|
|
329
|
+
formatGitHubUrl(repoOwner, repoName, issueNumber) {}
|
|
330
|
+
|
|
331
|
+
// ========================================================================
|
|
332
|
+
// Content Analysis & Generation
|
|
333
|
+
// ========================================================================
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Analyze PRD content
|
|
337
|
+
* @param {string} prdContent - PRD markdown content
|
|
338
|
+
* @returns {Object} Analysis result with frontmatter and sections
|
|
339
|
+
* @example
|
|
340
|
+
* const analysis = service.analyzePRD(prdContent);
|
|
341
|
+
* console.log(analysis.sections.features);
|
|
342
|
+
*/
|
|
343
|
+
analyzePRD(prdContent) {}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Determine feature dependencies
|
|
347
|
+
* @param {string[]} features - Array of feature descriptions
|
|
348
|
+
* @returns {Object} Dependency map
|
|
349
|
+
* @example
|
|
350
|
+
* const deps = service.determineDependencies([
|
|
351
|
+
* 'Authentication system',
|
|
352
|
+
* 'User dashboard (requires authentication)'
|
|
353
|
+
* ]);
|
|
354
|
+
*/
|
|
355
|
+
determineDependencies(features) {}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Generate epic metadata/frontmatter
|
|
359
|
+
* @param {string} name - Epic name (REQUIRED)
|
|
360
|
+
* @param {string} prdId - PRD identifier (REQUIRED)
|
|
361
|
+
* @param {Object} [options] - Additional options
|
|
362
|
+
* @returns {MetadataObject} Epic metadata
|
|
363
|
+
* @throws {Error} If name or prdId is missing
|
|
364
|
+
* @example
|
|
365
|
+
* const metadata = service.generateEpicMetadata('auth', 'prd-001');
|
|
366
|
+
*/
|
|
367
|
+
generateEpicMetadata(name, prdId, options = {}) {}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Generate complete epic markdown content
|
|
371
|
+
* @param {MetadataObject} metadata - Epic metadata
|
|
372
|
+
* @param {PRDSections} sections - PRD sections
|
|
373
|
+
* @param {TaskObject[]} tasks - Array of tasks
|
|
374
|
+
* @returns {string} Complete epic markdown
|
|
375
|
+
* @example
|
|
376
|
+
* const markdown = service.generateEpicContent(metadata, sections, tasks);
|
|
377
|
+
*/
|
|
378
|
+
generateEpicContent(metadata, sections, tasks) {}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Build task section as markdown list
|
|
382
|
+
* @param {TaskObject[]} tasks - Array of tasks
|
|
383
|
+
* @returns {string} Markdown formatted task list
|
|
384
|
+
* @example
|
|
385
|
+
* const taskMd = service.buildTaskSection(tasks);
|
|
386
|
+
* // Returns: "- [x] Task 1\n- [ ] Task 2"
|
|
387
|
+
*/
|
|
388
|
+
buildTaskSection(tasks) {}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Task Service Interface
|
|
393
|
+
*
|
|
394
|
+
* Provides comprehensive task management including status tracking,
|
|
395
|
+
* dependency validation, analytics, and task generation.
|
|
396
|
+
* Requires PRDService for dependency injection.
|
|
397
|
+
*
|
|
398
|
+
* @interface ITaskService
|
|
399
|
+
* @example
|
|
400
|
+
* const taskService = new TaskService({ prdService });
|
|
401
|
+
* const stats = taskService.getTaskStatistics(tasks);
|
|
402
|
+
*/
|
|
403
|
+
class ITaskService {
|
|
404
|
+
/**
|
|
405
|
+
* Create a new TaskService instance
|
|
406
|
+
* @param {Object} options - Service options (REQUIRED)
|
|
407
|
+
* @param {IPRDService} options.prdService - PRD service instance (REQUIRED)
|
|
408
|
+
* @param {ConfigManager} [options.configManager] - Configuration manager
|
|
409
|
+
* @param {string} [options.defaultTaskType='development'] - Default task type
|
|
410
|
+
* @param {string} [options.defaultEffort='1d'] - Default effort estimate
|
|
411
|
+
* @throws {Error} If prdService is missing or invalid
|
|
412
|
+
*/
|
|
413
|
+
constructor(options) {}
|
|
414
|
+
|
|
415
|
+
// ========================================================================
|
|
416
|
+
// Status Management
|
|
417
|
+
// ========================================================================
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Normalize task status to standard values
|
|
421
|
+
* @param {string} status - Raw status string
|
|
422
|
+
* @returns {string} Normalized status
|
|
423
|
+
* @example
|
|
424
|
+
* service.normalizeTaskStatus('In Progress'); // Returns: "in_progress"
|
|
425
|
+
*/
|
|
426
|
+
normalizeTaskStatus(status) {}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Check if task is open/active
|
|
430
|
+
* @param {TaskObject} task - Task to check
|
|
431
|
+
* @returns {boolean} True if task is open
|
|
432
|
+
* @example
|
|
433
|
+
* service.isTaskOpen({ status: 'pending' }); // Returns: true
|
|
434
|
+
*/
|
|
435
|
+
isTaskOpen(task) {}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Check if task is closed/completed
|
|
439
|
+
* @param {TaskObject} task - Task to check
|
|
440
|
+
* @returns {boolean} True if task is closed
|
|
441
|
+
* @example
|
|
442
|
+
* service.isTaskClosed({ status: 'completed' }); // Returns: true
|
|
443
|
+
*/
|
|
444
|
+
isTaskClosed(task) {}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Categorize task status into buckets
|
|
448
|
+
* @param {string} status - Task status
|
|
449
|
+
* @returns {string} Category: 'todo'|'in_progress'|'completed'|'blocked'
|
|
450
|
+
* @example
|
|
451
|
+
* service.categorizeTaskStatus('pending'); // Returns: "todo"
|
|
452
|
+
*/
|
|
453
|
+
categorizeTaskStatus(status) {}
|
|
454
|
+
|
|
455
|
+
// ========================================================================
|
|
456
|
+
// Task Parsing & Validation
|
|
457
|
+
// ========================================================================
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Extract task number from ID
|
|
461
|
+
* @param {string} taskId - Task ID (e.g., "TASK-042")
|
|
462
|
+
* @returns {number|null} Task number or null
|
|
463
|
+
* @example
|
|
464
|
+
* service.parseTaskNumber('TASK-042'); // Returns: 42
|
|
465
|
+
*/
|
|
466
|
+
parseTaskNumber(taskId) {}
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* Parse task frontmatter metadata
|
|
470
|
+
* @param {string} content - Task markdown content
|
|
471
|
+
* @returns {MetadataObject|null} Parsed metadata or null
|
|
472
|
+
* @example
|
|
473
|
+
* const metadata = service.parseTaskMetadata(taskContent);
|
|
474
|
+
*/
|
|
475
|
+
parseTaskMetadata(content) {}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Validate task metadata completeness
|
|
479
|
+
* @param {MetadataObject} metadata - Task metadata
|
|
480
|
+
* @returns {ValidationResult} Validation result
|
|
481
|
+
* @example
|
|
482
|
+
* const result = service.validateTaskMetadata(metadata);
|
|
483
|
+
* if (!result.valid) console.log(result.errors);
|
|
484
|
+
*/
|
|
485
|
+
validateTaskMetadata(metadata) {}
|
|
486
|
+
|
|
487
|
+
/**
|
|
488
|
+
* Format task number to ID
|
|
489
|
+
* @param {number} number - Task number
|
|
490
|
+
* @returns {string} Formatted task ID (e.g., "TASK-001")
|
|
491
|
+
* @throws {Error} If number is invalid
|
|
492
|
+
* @example
|
|
493
|
+
* service.formatTaskId(42); // Returns: "TASK-042"
|
|
494
|
+
*/
|
|
495
|
+
formatTaskId(number) {}
|
|
496
|
+
|
|
497
|
+
// ========================================================================
|
|
498
|
+
// Dependencies
|
|
499
|
+
// ========================================================================
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Parse dependency string to array
|
|
503
|
+
* @param {string} dependencyString - Comma-separated dependencies
|
|
504
|
+
* @returns {string[]} Array of task IDs
|
|
505
|
+
* @example
|
|
506
|
+
* service.parseDependencies('TASK-001, TASK-002');
|
|
507
|
+
* // Returns: ['TASK-001', 'TASK-002']
|
|
508
|
+
*/
|
|
509
|
+
parseDependencies(dependencyString) {}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* Check if task has blocking dependencies
|
|
513
|
+
* @param {TaskObject} task - Task to check
|
|
514
|
+
* @param {TaskObject[]} allTasks - All tasks for lookup
|
|
515
|
+
* @returns {boolean} True if blocked by uncompleted dependencies
|
|
516
|
+
* @example
|
|
517
|
+
* const blocked = service.hasBlockingDependencies(task, allTasks);
|
|
518
|
+
*/
|
|
519
|
+
hasBlockingDependencies(task, allTasks) {}
|
|
520
|
+
|
|
521
|
+
/**
|
|
522
|
+
* Validate dependency format
|
|
523
|
+
* @param {string} depString - Dependency string
|
|
524
|
+
* @returns {boolean} True if valid format
|
|
525
|
+
* @example
|
|
526
|
+
* service.validateDependencyFormat('TASK-001'); // Returns: true
|
|
527
|
+
*/
|
|
528
|
+
validateDependencyFormat(depString) {}
|
|
529
|
+
|
|
530
|
+
// ========================================================================
|
|
531
|
+
// Analytics & Statistics
|
|
532
|
+
// ========================================================================
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* Calculate task completion percentage
|
|
536
|
+
* @param {TaskObject[]} tasks - Array of tasks
|
|
537
|
+
* @returns {number} Completion percentage (0-100)
|
|
538
|
+
* @example
|
|
539
|
+
* const completion = service.calculateTaskCompletion(tasks);
|
|
540
|
+
*/
|
|
541
|
+
calculateTaskCompletion(tasks) {}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Get comprehensive task statistics
|
|
545
|
+
* @param {TaskObject[]} tasks - Array of tasks
|
|
546
|
+
* @returns {TaskStatistics} Complete statistics
|
|
547
|
+
* @example
|
|
548
|
+
* const stats = service.getTaskStatistics(tasks);
|
|
549
|
+
* console.log(`${stats.completionPercentage}% complete`);
|
|
550
|
+
*/
|
|
551
|
+
getTaskStatistics(tasks) {}
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* Sort tasks by priority
|
|
555
|
+
* @param {TaskObject[]} tasks - Tasks to sort
|
|
556
|
+
* @returns {TaskObject[]} New sorted array (does not mutate original)
|
|
557
|
+
* @example
|
|
558
|
+
* const sorted = service.sortTasksByPriority(tasks);
|
|
559
|
+
*/
|
|
560
|
+
sortTasksByPriority(tasks) {}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Filter tasks by status
|
|
564
|
+
* @param {TaskObject[]} tasks - Tasks to filter
|
|
565
|
+
* @param {string} status - Status to filter by
|
|
566
|
+
* @returns {TaskObject[]} New filtered array
|
|
567
|
+
* @example
|
|
568
|
+
* const pending = service.filterTasksByStatus(tasks, 'pending');
|
|
569
|
+
*/
|
|
570
|
+
filterTasksByStatus(tasks, status) {}
|
|
571
|
+
|
|
572
|
+
// ========================================================================
|
|
573
|
+
// Task Generation
|
|
574
|
+
// ========================================================================
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Generate task metadata/frontmatter
|
|
578
|
+
* @param {string} title - Task title (REQUIRED)
|
|
579
|
+
* @param {Object} [options] - Additional options
|
|
580
|
+
* @param {string} [options.type] - Task type
|
|
581
|
+
* @param {string} [options.effort] - Effort estimate
|
|
582
|
+
* @param {string} [options.status] - Initial status
|
|
583
|
+
* @param {string[]} [options.dependencies] - Dependent tasks
|
|
584
|
+
* @returns {MetadataObject} Task metadata
|
|
585
|
+
* @throws {Error} If title is missing
|
|
586
|
+
* @example
|
|
587
|
+
* const metadata = service.generateTaskMetadata('Implement auth', {
|
|
588
|
+
* type: 'development',
|
|
589
|
+
* effort: '3d'
|
|
590
|
+
* });
|
|
591
|
+
*/
|
|
592
|
+
generateTaskMetadata(title, options = {}) {}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Generate complete task markdown content
|
|
596
|
+
* @param {MetadataObject} metadata - Task metadata
|
|
597
|
+
* @param {string} [description=''] - Task description
|
|
598
|
+
* @param {string[]} [subtasks=[]] - Array of subtask strings
|
|
599
|
+
* @returns {string} Complete task markdown
|
|
600
|
+
* @example
|
|
601
|
+
* const taskMd = service.generateTaskContent(metadata, 'Description', [
|
|
602
|
+
* 'Subtask 1',
|
|
603
|
+
* 'Subtask 2'
|
|
604
|
+
* ]);
|
|
605
|
+
*/
|
|
606
|
+
generateTaskContent(metadata, description = '', subtasks = []) {}
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/**
|
|
610
|
+
* Agent Service Interface
|
|
611
|
+
*
|
|
612
|
+
* Provides methods for loading, parsing, and invoking AI agents for standalone mode.
|
|
613
|
+
* Agents are defined in markdown files with specialization, Context7 queries, and methodologies.
|
|
614
|
+
*
|
|
615
|
+
* @interface IAgentService
|
|
616
|
+
* @example
|
|
617
|
+
* const agentService = new AgentService(aiProvider);
|
|
618
|
+
* const agents = await agentService.listAgents();
|
|
619
|
+
* const response = await agentService.invoke('aws-cloud-architect', task, context);
|
|
620
|
+
*/
|
|
621
|
+
class IAgentService {
|
|
622
|
+
/**
|
|
623
|
+
* Create a new AgentService instance
|
|
624
|
+
* @param {AIProvider} aiProvider - AI provider instance (REQUIRED)
|
|
625
|
+
* @param {Object} [options] - Service options
|
|
626
|
+
* @param {string} [options.agentsBaseDir] - Base directory for agents
|
|
627
|
+
* @throws {Error} If aiProvider is missing or invalid
|
|
628
|
+
*/
|
|
629
|
+
constructor(aiProvider, options = {}) {}
|
|
630
|
+
|
|
631
|
+
// ========================================================================
|
|
632
|
+
// Agent Loading & Parsing
|
|
633
|
+
// ========================================================================
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Load agent metadata from .md file
|
|
637
|
+
* @param {string} agentName - Agent name (e.g., 'aws-cloud-architect')
|
|
638
|
+
* @returns {Promise<AgentMetadata>} Parsed agent metadata with category
|
|
639
|
+
* @throws {Error} If agent not found or file is malformed
|
|
640
|
+
* @example
|
|
641
|
+
* const agent = await service.loadAgent('aws-cloud-architect');
|
|
642
|
+
* console.log(agent.title, agent.specialization);
|
|
643
|
+
*/
|
|
644
|
+
loadAgent(agentName) {}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Parse agent markdown file content
|
|
648
|
+
* @param {string} markdownContent - Agent .md file content
|
|
649
|
+
* @returns {AgentMetadata} Parsed agent metadata
|
|
650
|
+
* @example
|
|
651
|
+
* const metadata = service.parseAgent(fileContent);
|
|
652
|
+
* console.log(metadata.documentationQueries);
|
|
653
|
+
*/
|
|
654
|
+
parseAgent(markdownContent) {}
|
|
655
|
+
|
|
656
|
+
// ========================================================================
|
|
657
|
+
// Agent Invocation
|
|
658
|
+
// ========================================================================
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Invoke agent with task and context
|
|
662
|
+
* @param {string} agentName - Agent name to invoke
|
|
663
|
+
* @param {string} task - Task description
|
|
664
|
+
* @param {Object} [context={}] - Additional context (tech stack, requirements)
|
|
665
|
+
* @param {Object} [options={}] - Invocation options
|
|
666
|
+
* @param {string} [options.conversationId] - For multi-turn conversations
|
|
667
|
+
* @returns {Promise<string>} Agent response
|
|
668
|
+
* @throws {Error} If agent not found or AI provider fails
|
|
669
|
+
* @example
|
|
670
|
+
* const response = await service.invoke(
|
|
671
|
+
* 'nodejs-backend-engineer',
|
|
672
|
+
* 'Review authentication module',
|
|
673
|
+
* { techStack: 'Node.js, PostgreSQL' }
|
|
674
|
+
* );
|
|
675
|
+
*/
|
|
676
|
+
invoke(agentName, task, context, options) {}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Invoke agent with streaming response
|
|
680
|
+
* @param {string} agentName - Agent name to invoke
|
|
681
|
+
* @param {string} task - Task description
|
|
682
|
+
* @param {Object} [context={}] - Additional context
|
|
683
|
+
* @param {Object} [options={}] - Invocation options
|
|
684
|
+
* @returns {AsyncGenerator<string>} Stream of response chunks
|
|
685
|
+
* @example
|
|
686
|
+
* for await (const chunk of service.invokeStream('test-agent', 'task', {})) {
|
|
687
|
+
* process.stdout.write(chunk);
|
|
688
|
+
* }
|
|
689
|
+
*/
|
|
690
|
+
invokeStream(agentName, task, context, options) {}
|
|
691
|
+
|
|
692
|
+
// ========================================================================
|
|
693
|
+
// Agent Discovery
|
|
694
|
+
// ========================================================================
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* List all available agents
|
|
698
|
+
* @param {Object} [options={}] - List options
|
|
699
|
+
* @param {boolean} [options.grouped=false] - Group by category
|
|
700
|
+
* @returns {Promise<Array<AgentSummary>|Object>} Array of agents or grouped object
|
|
701
|
+
* @example
|
|
702
|
+
* const agents = await service.listAgents();
|
|
703
|
+
* const grouped = await service.listAgents({ grouped: true });
|
|
704
|
+
* console.log(grouped.core, grouped.cloud);
|
|
705
|
+
*/
|
|
706
|
+
listAgents(options) {}
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Search agents by keyword
|
|
710
|
+
* @param {string} query - Search query (case-insensitive)
|
|
711
|
+
* @returns {Promise<Array<AgentSummary>>} Matching agents
|
|
712
|
+
* @example
|
|
713
|
+
* const awsAgents = await service.searchAgents('aws');
|
|
714
|
+
* const dbExperts = await service.searchAgents('database');
|
|
715
|
+
*/
|
|
716
|
+
searchAgents(query) {}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Agent Metadata
|
|
721
|
+
* @typedef {Object} AgentMetadata
|
|
722
|
+
* @property {string} name - Agent name (e.g., 'aws-cloud-architect')
|
|
723
|
+
* @property {string} title - Agent title from markdown
|
|
724
|
+
* @property {string} specialization - Agent specialization description
|
|
725
|
+
* @property {string[]} documentationQueries - Context7 mcp:// queries
|
|
726
|
+
* @property {string[]} methodologies - Methodologies used by agent
|
|
727
|
+
* @property {string[]} tools - Available tools (Read, Write, Bash, etc.)
|
|
728
|
+
* @property {string} category - Agent category (core, cloud, devops, etc.)
|
|
729
|
+
*/
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Agent Summary (for listing)
|
|
733
|
+
* @typedef {Object} AgentSummary
|
|
734
|
+
* @property {string} name - Agent name
|
|
735
|
+
* @property {string} title - Agent title
|
|
736
|
+
* @property {string} specialization - Brief specialization
|
|
737
|
+
* @property {string} category - Agent category
|
|
738
|
+
*/
|
|
739
|
+
|
|
740
|
+
// ============================================================================
|
|
741
|
+
// EXPORTS
|
|
742
|
+
// ============================================================================
|
|
743
|
+
|
|
744
|
+
module.exports = {
|
|
745
|
+
// Interfaces (for documentation)
|
|
746
|
+
IPRDService,
|
|
747
|
+
IEpicService,
|
|
748
|
+
ITaskService,
|
|
749
|
+
IAgentService,
|
|
750
|
+
|
|
751
|
+
// TypeDefs are defined above for JSDoc @type references only.
|
|
752
|
+
// They are NOT exported at runtime and cannot be imported.
|
|
753
|
+
};
|