prjct-cli 0.10.10 β 0.10.12
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/CHANGELOG.md +88 -0
- package/core/__tests__/agentic/prompt-builder.test.js +7 -3
- package/core/agentic/agent-router.js +79 -372
- package/core/commands.js +128 -470
- package/core/domain/agent-matcher.js +71 -185
- package/core/domain/architecture-generator.js +51 -519
- package/core/domain/task-analyzer.js +11 -36
- package/package.json +1 -1
- package/templates/agent-assignment.md +72 -0
- package/templates/analysis/bug-severity.md +74 -0
- package/templates/analysis/complexity.md +54 -0
- package/templates/analysis/health.md +66 -0
- package/templates/analysis/intent.md +66 -0
- package/templates/analysis/task-breakdown.md +53 -0
- package/templates/architect/discovery.md +67 -0
- package/templates/architect/phases.md +59 -0
- package/templates/design/api.md +95 -0
- package/templates/design/architecture.md +77 -0
- package/templates/design/component.md +89 -0
- package/templates/design/database.md +78 -0
- package/templates/design/flow.md +94 -0
package/core/commands.js
CHANGED
|
@@ -22,6 +22,7 @@ const commandExecutor = require('./agentic/command-executor')
|
|
|
22
22
|
const contextBuilder = require('./agentic/context-builder')
|
|
23
23
|
const toolRegistry = require('./agentic/tool-registry')
|
|
24
24
|
const memorySystem = require('./agentic/memory-system')
|
|
25
|
+
const AgentRouter = require('./agentic/agent-router')
|
|
25
26
|
const pathManager = require('./infrastructure/path-manager')
|
|
26
27
|
const configManager = require('./infrastructure/config-manager')
|
|
27
28
|
const authorDetector = require('./infrastructure/author-detector')
|
|
@@ -46,6 +47,7 @@ class PrjctCommands {
|
|
|
46
47
|
this.updateChecker = new UpdateChecker()
|
|
47
48
|
this.updateNotificationShown = false
|
|
48
49
|
this.commandExecutor = commandExecutor
|
|
50
|
+
this.agentRouter = new AgentRouter()
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
/**
|
|
@@ -138,17 +140,24 @@ class PrjctCommands {
|
|
|
138
140
|
const context = await contextBuilder.build(projectPath, { task })
|
|
139
141
|
|
|
140
142
|
if (task) {
|
|
141
|
-
//
|
|
142
|
-
const
|
|
143
|
+
// MANDATORY: Assign agent before setting task
|
|
144
|
+
const agentResult = await this._assignAgentForTask(task, projectPath, context)
|
|
145
|
+
const agent = agentResult.agent?.name || 'generalist'
|
|
146
|
+
const confidence = agentResult.routing?.confidence || 0.5
|
|
147
|
+
|
|
148
|
+
// Set task WITH agent
|
|
149
|
+
const nowContent = `# NOW\n\n**${task}**\n\nStarted: ${new Date().toLocaleString()}\nAgent: ${agent} (${Math.round(confidence * 100)}% confidence)\n`
|
|
143
150
|
await toolRegistry.get('Write')(context.paths.now, nowContent)
|
|
144
151
|
|
|
145
|
-
out.done(`${task}
|
|
152
|
+
out.done(`${task} [${agent}]`)
|
|
146
153
|
|
|
147
154
|
await this.logToMemory(projectPath, 'task_started', {
|
|
148
155
|
task,
|
|
156
|
+
agent,
|
|
157
|
+
confidence,
|
|
149
158
|
timestamp: dateHelper.getTimestamp(),
|
|
150
159
|
})
|
|
151
|
-
return { success: true, task }
|
|
160
|
+
return { success: true, task, agent }
|
|
152
161
|
} else {
|
|
153
162
|
// Show current task
|
|
154
163
|
const nowContent = await toolRegistry.get('Read')(context.paths.now)
|
|
@@ -158,10 +167,12 @@ class PrjctCommands {
|
|
|
158
167
|
return { success: true, message: 'No active task' }
|
|
159
168
|
}
|
|
160
169
|
|
|
161
|
-
// Extract task name for minimal output
|
|
170
|
+
// Extract task name and agent for minimal output
|
|
162
171
|
const taskMatch = nowContent.match(/\*\*(.+?)\*\*/)
|
|
172
|
+
const agentMatch = nowContent.match(/Agent: ([^\s(]+)/)
|
|
163
173
|
const currentTask = taskMatch ? taskMatch[1] : 'unknown'
|
|
164
|
-
|
|
174
|
+
const currentAgent = agentMatch ? agentMatch[1] : ''
|
|
175
|
+
out.done(`working on: ${currentTask}${currentAgent ? ` [${currentAgent}]` : ''}`)
|
|
165
176
|
return { success: true, content: nowContent }
|
|
166
177
|
}
|
|
167
178
|
} catch (error) {
|
|
@@ -427,26 +438,42 @@ class PrjctCommands {
|
|
|
427
438
|
// Task breakdown
|
|
428
439
|
const tasks = this._breakdownFeatureTasks(description)
|
|
429
440
|
|
|
430
|
-
//
|
|
441
|
+
// MANDATORY: Assign agent to each task
|
|
442
|
+
const tasksWithAgents = []
|
|
443
|
+
for (const taskDesc of tasks) {
|
|
444
|
+
const agentResult = await this._assignAgentForTask(taskDesc, projectPath, context)
|
|
445
|
+
const agent = agentResult.agent?.name || 'generalist'
|
|
446
|
+
tasksWithAgents.push({ task: taskDesc, agent })
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Write to next.md with agents
|
|
431
450
|
const nextContent =
|
|
432
451
|
(await toolRegistry.get('Read')(context.paths.next)) || '# NEXT\n\n## Priority Queue\n\n'
|
|
433
452
|
const taskSection =
|
|
434
453
|
`\n## Feature: ${description}\n\n` +
|
|
435
|
-
|
|
454
|
+
tasksWithAgents.map((t, i) => `${i + 1}. [${t.agent}] [ ] ${t.task}`).join('\n') +
|
|
436
455
|
`\n\nEstimated: ${tasks.length * 2}h\n`
|
|
437
456
|
|
|
438
457
|
await toolRegistry.get('Write')(context.paths.next, nextContent + taskSection)
|
|
439
458
|
|
|
440
|
-
// Log to memory
|
|
459
|
+
// Log to memory with agent assignments
|
|
441
460
|
await this.logToMemory(projectPath, 'feature_planned', {
|
|
442
461
|
feature: description,
|
|
443
|
-
tasks:
|
|
462
|
+
tasks: tasksWithAgents.length,
|
|
463
|
+
assignments: tasksWithAgents.map(t => ({ task: t.task, agent: t.agent })),
|
|
444
464
|
timestamp: dateHelper.getTimestamp(),
|
|
445
465
|
})
|
|
446
466
|
|
|
447
|
-
|
|
467
|
+
// Show summary with agent distribution
|
|
468
|
+
const agentCounts = tasksWithAgents.reduce((acc, t) => {
|
|
469
|
+
acc[t.agent] = (acc[t.agent] || 0) + 1
|
|
470
|
+
return acc
|
|
471
|
+
}, {})
|
|
472
|
+
const agentSummary = Object.entries(agentCounts).map(([a, c]) => `${a}:${c}`).join(' ')
|
|
473
|
+
|
|
474
|
+
out.done(`${tasks.length} tasks [${agentSummary}]`)
|
|
448
475
|
|
|
449
|
-
return { success: true, feature: description, tasks }
|
|
476
|
+
return { success: true, feature: description, tasks: tasksWithAgents }
|
|
450
477
|
} catch (error) {
|
|
451
478
|
out.fail(error.message)
|
|
452
479
|
return { success: false, error: error.message }
|
|
@@ -459,36 +486,13 @@ class PrjctCommands {
|
|
|
459
486
|
* @private
|
|
460
487
|
*/
|
|
461
488
|
_breakdownFeatureTasks(description) {
|
|
462
|
-
//
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
if (lowerDesc.includes('test')) {
|
|
466
|
-
return [
|
|
467
|
-
'Setup testing framework configuration',
|
|
468
|
-
'Write tests for core utilities',
|
|
469
|
-
'Write tests for components/modules',
|
|
470
|
-
'Add CI/CD test runner',
|
|
471
|
-
'Update docs with testing guide',
|
|
472
|
-
]
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
if (lowerDesc.includes('auth') || lowerDesc.includes('login')) {
|
|
476
|
-
return [
|
|
477
|
-
'Design authentication flow',
|
|
478
|
-
'Implement backend authentication API',
|
|
479
|
-
'Implement frontend login/signup UI',
|
|
480
|
-
'Add session management',
|
|
481
|
-
'Test authentication flow',
|
|
482
|
-
]
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
// Default breakdown
|
|
489
|
+
// AGENTIC: Claude analyzes and creates tasks via templates/analysis/task-breakdown.md
|
|
490
|
+
// This returns a placeholder - real breakdown happens in template execution
|
|
486
491
|
return [
|
|
487
|
-
`
|
|
492
|
+
`Analyze and plan: ${description}`,
|
|
488
493
|
'Implement core functionality',
|
|
489
|
-
'
|
|
490
|
-
'
|
|
491
|
-
'Review and refine',
|
|
494
|
+
'Test and validate',
|
|
495
|
+
'Document changes',
|
|
492
496
|
]
|
|
493
497
|
}
|
|
494
498
|
|
|
@@ -511,10 +515,14 @@ class PrjctCommands {
|
|
|
511
515
|
const context = await contextBuilder.build(projectPath, { description })
|
|
512
516
|
const severity = this._detectBugSeverity(description)
|
|
513
517
|
|
|
514
|
-
//
|
|
518
|
+
// MANDATORY: Assign agent to bug
|
|
519
|
+
const agentResult = await this._assignAgentForTask(`fix bug: ${description}`, projectPath, context)
|
|
520
|
+
const agent = agentResult.agent?.name || 'generalist'
|
|
521
|
+
|
|
522
|
+
// Add to next.md with priority and agent
|
|
515
523
|
const nextContent =
|
|
516
524
|
(await toolRegistry.get('Read')(context.paths.next)) || '# NEXT\n\n## Priority Queue\n\n'
|
|
517
|
-
const bugEntry = `\n## π BUG [${severity.toUpperCase()}]: ${description}\n\nReported: ${new Date().toLocaleString()}\nPriority: ${severity === 'critical' ? 'β οΈ URGENT' : severity === 'high' ? 'π΄ High' : 'π‘ Normal'}\n`
|
|
525
|
+
const bugEntry = `\n## π BUG [${severity.toUpperCase()}] [${agent}]: ${description}\n\nReported: ${new Date().toLocaleString()}\nPriority: ${severity === 'critical' ? 'β οΈ URGENT' : severity === 'high' ? 'π΄ High' : 'π‘ Normal'}\nAssigned: ${agent}\n`
|
|
518
526
|
|
|
519
527
|
// Insert at top if critical/high, at bottom otherwise
|
|
520
528
|
const updatedContent =
|
|
@@ -524,16 +532,17 @@ class PrjctCommands {
|
|
|
524
532
|
|
|
525
533
|
await toolRegistry.get('Write')(context.paths.next, updatedContent)
|
|
526
534
|
|
|
527
|
-
// Log to memory
|
|
535
|
+
// Log to memory with agent
|
|
528
536
|
await this.logToMemory(projectPath, 'bug_reported', {
|
|
529
537
|
bug: description,
|
|
530
538
|
severity,
|
|
539
|
+
agent,
|
|
531
540
|
timestamp: dateHelper.getTimestamp(),
|
|
532
541
|
})
|
|
533
542
|
|
|
534
|
-
out.done(`bug [${severity}]
|
|
543
|
+
out.done(`bug [${severity}] β ${agent}`)
|
|
535
544
|
|
|
536
|
-
return { success: true, bug: description, severity }
|
|
545
|
+
return { success: true, bug: description, severity, agent }
|
|
537
546
|
} catch (error) {
|
|
538
547
|
out.fail(error.message)
|
|
539
548
|
return { success: false, error: error.message }
|
|
@@ -546,20 +555,8 @@ class PrjctCommands {
|
|
|
546
555
|
* @private
|
|
547
556
|
*/
|
|
548
557
|
_detectBugSeverity(description) {
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
if (
|
|
552
|
-
lowerDesc.includes('crash') ||
|
|
553
|
-
lowerDesc.includes('broken') ||
|
|
554
|
-
lowerDesc.includes('not working')
|
|
555
|
-
) {
|
|
556
|
-
return 'critical'
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
if (lowerDesc.includes('error') || lowerDesc.includes('fail') || lowerDesc.includes('bug')) {
|
|
560
|
-
return 'high'
|
|
561
|
-
}
|
|
562
|
-
|
|
558
|
+
// AGENTIC: Claude assesses severity via templates/analysis/bug-severity.md
|
|
559
|
+
// Returns default - real assessment happens in template execution
|
|
563
560
|
return 'medium'
|
|
564
561
|
}
|
|
565
562
|
|
|
@@ -971,68 +968,8 @@ class PrjctCommands {
|
|
|
971
968
|
* @private
|
|
972
969
|
*/
|
|
973
970
|
_generateArchitectureDesign(target, projectPath) {
|
|
974
|
-
|
|
975
|
-
return `# Architecture Design: ${target}
|
|
976
|
-
|
|
977
|
-
**Project**: ${projectName}
|
|
978
|
-
**Created**: ${new Date().toLocaleString()}
|
|
979
|
-
**Type**: System Architecture
|
|
980
|
-
|
|
981
|
-
## Overview
|
|
982
|
-
|
|
983
|
-
High-level architecture design for ${target}.
|
|
984
|
-
|
|
985
|
-
## Components
|
|
986
|
-
|
|
987
|
-
### Core Components
|
|
988
|
-
1. **Component A**
|
|
989
|
-
- Responsibility: [Define responsibility]
|
|
990
|
-
- Dependencies: [List dependencies]
|
|
991
|
-
- Interfaces: [Define interfaces]
|
|
992
|
-
|
|
993
|
-
2. **Component B**
|
|
994
|
-
- Responsibility: [Define responsibility]
|
|
995
|
-
- Dependencies: [List dependencies]
|
|
996
|
-
- Interfaces: [Define interfaces]
|
|
997
|
-
|
|
998
|
-
## Data Flow
|
|
999
|
-
|
|
1000
|
-
\`\`\`
|
|
1001
|
-
[User] β [Frontend] β [API Gateway] β [Backend Services] β [Database]
|
|
1002
|
-
β
|
|
1003
|
-
[Cache Layer]
|
|
1004
|
-
\`\`\`
|
|
1005
|
-
|
|
1006
|
-
## Technology Stack
|
|
1007
|
-
|
|
1008
|
-
- **Frontend**: [Framework/Library]
|
|
1009
|
-
- **Backend**: [Framework/Runtime]
|
|
1010
|
-
- **Database**: [Type/System]
|
|
1011
|
-
- **Deployment**: [Platform/Method]
|
|
1012
|
-
|
|
1013
|
-
## Design Decisions
|
|
1014
|
-
|
|
1015
|
-
### Decision 1: [Title]
|
|
1016
|
-
- **Context**: [Why this decision is needed]
|
|
1017
|
-
- **Options**: [Alternatives considered]
|
|
1018
|
-
- **Choice**: [What was chosen]
|
|
1019
|
-
- **Rationale**: [Why this choice]
|
|
1020
|
-
|
|
1021
|
-
## Implementation Plan
|
|
1022
|
-
|
|
1023
|
-
1. [ ] Setup project structure
|
|
1024
|
-
2. [ ] Implement core components
|
|
1025
|
-
3. [ ] Add integration layer
|
|
1026
|
-
4. [ ] Testing and validation
|
|
1027
|
-
5. [ ] Documentation
|
|
1028
|
-
|
|
1029
|
-
## Notes
|
|
1030
|
-
|
|
1031
|
-
[Additional notes, constraints, assumptions]
|
|
1032
|
-
|
|
1033
|
-
---
|
|
1034
|
-
*This is a living document. Update as design evolves.*
|
|
1035
|
-
`
|
|
971
|
+
// AGENTIC: Claude generates via templates/design/architecture.md
|
|
972
|
+
return `# Architecture Design: ${target}\n\n*Use templates/design/architecture.md for full design*\n`
|
|
1036
973
|
}
|
|
1037
974
|
|
|
1038
975
|
/**
|
|
@@ -1040,79 +977,8 @@ High-level architecture design for ${target}.
|
|
|
1040
977
|
* @private
|
|
1041
978
|
*/
|
|
1042
979
|
_generateApiDesign(target) {
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
**Created**: ${new Date().toLocaleString()}
|
|
1046
|
-
**Type**: API Specification
|
|
1047
|
-
|
|
1048
|
-
## Endpoints
|
|
1049
|
-
|
|
1050
|
-
### GET /api/${target.toLowerCase()}
|
|
1051
|
-
**Description**: Retrieve ${target}
|
|
1052
|
-
|
|
1053
|
-
**Request**:
|
|
1054
|
-
\`\`\`
|
|
1055
|
-
GET /api/${target.toLowerCase()}?limit=10&offset=0
|
|
1056
|
-
\`\`\`
|
|
1057
|
-
|
|
1058
|
-
**Response** (200 OK):
|
|
1059
|
-
\`\`\`json
|
|
1060
|
-
{
|
|
1061
|
-
"data": [],
|
|
1062
|
-
"meta": {
|
|
1063
|
-
"total": 0,
|
|
1064
|
-
"limit": 10,
|
|
1065
|
-
"offset": 0
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
\`\`\`
|
|
1069
|
-
|
|
1070
|
-
### POST /api/${target.toLowerCase()}
|
|
1071
|
-
**Description**: Create new ${target}
|
|
1072
|
-
|
|
1073
|
-
**Request**:
|
|
1074
|
-
\`\`\`json
|
|
1075
|
-
{
|
|
1076
|
-
"name": "string",
|
|
1077
|
-
"description": "string"
|
|
1078
|
-
}
|
|
1079
|
-
\`\`\`
|
|
1080
|
-
|
|
1081
|
-
**Response** (201 Created):
|
|
1082
|
-
\`\`\`json
|
|
1083
|
-
{
|
|
1084
|
-
"id": "string",
|
|
1085
|
-
"name": "string",
|
|
1086
|
-
"description": "string",
|
|
1087
|
-
"createdAt": "ISO8601"
|
|
1088
|
-
}
|
|
1089
|
-
\`\`\`
|
|
1090
|
-
|
|
1091
|
-
## Error Handling
|
|
1092
|
-
|
|
1093
|
-
\`\`\`json
|
|
1094
|
-
{
|
|
1095
|
-
"error": {
|
|
1096
|
-
"code": "ERROR_CODE",
|
|
1097
|
-
"message": "Human-readable message",
|
|
1098
|
-
"details": {}
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
\`\`\`
|
|
1102
|
-
|
|
1103
|
-
## Authentication
|
|
1104
|
-
|
|
1105
|
-
- **Method**: Bearer Token
|
|
1106
|
-
- **Header**: \`Authorization: Bearer <token>\`
|
|
1107
|
-
|
|
1108
|
-
## Rate Limiting
|
|
1109
|
-
|
|
1110
|
-
- **Limit**: 100 requests/minute
|
|
1111
|
-
- **Headers**: \`X-RateLimit-Limit\`, \`X-RateLimit-Remaining\`
|
|
1112
|
-
|
|
1113
|
-
---
|
|
1114
|
-
*Update this specification as API evolves.*
|
|
1115
|
-
`
|
|
980
|
+
// AGENTIC: Claude generates via templates/design/api.md
|
|
981
|
+
return `# API Design: ${target}\n\n*Use templates/design/api.md for full design*\n`
|
|
1116
982
|
}
|
|
1117
983
|
|
|
1118
984
|
/**
|
|
@@ -1120,79 +986,8 @@ GET /api/${target.toLowerCase()}?limit=10&offset=0
|
|
|
1120
986
|
* @private
|
|
1121
987
|
*/
|
|
1122
988
|
_generateComponentDesign(target) {
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
**Created**: ${new Date().toLocaleString()}
|
|
1126
|
-
**Type**: Component Specification
|
|
1127
|
-
|
|
1128
|
-
## Overview
|
|
1129
|
-
|
|
1130
|
-
Component for ${target} functionality.
|
|
1131
|
-
|
|
1132
|
-
## Props/Interface
|
|
1133
|
-
|
|
1134
|
-
\`\`\`typescript
|
|
1135
|
-
interface ${target}Props {
|
|
1136
|
-
// Define props
|
|
1137
|
-
id?: string
|
|
1138
|
-
className?: string
|
|
1139
|
-
onAction?: (data: any) => void
|
|
1140
|
-
}
|
|
1141
|
-
\`\`\`
|
|
1142
|
-
|
|
1143
|
-
## State
|
|
1144
|
-
|
|
1145
|
-
\`\`\`typescript
|
|
1146
|
-
interface ${target}State {
|
|
1147
|
-
// Define internal state
|
|
1148
|
-
loading: boolean
|
|
1149
|
-
data: any[]
|
|
1150
|
-
error: Error | null
|
|
1151
|
-
}
|
|
1152
|
-
\`\`\`
|
|
1153
|
-
|
|
1154
|
-
## Component Structure
|
|
1155
|
-
|
|
1156
|
-
\`\`\`
|
|
1157
|
-
${target}/
|
|
1158
|
-
βββ index.ts # Barrel export
|
|
1159
|
-
βββ ${target}.tsx # Main component
|
|
1160
|
-
βββ ${target}.test.tsx # Tests
|
|
1161
|
-
βββ ${target}.styles.ts # Styles
|
|
1162
|
-
βββ types.ts # Type definitions
|
|
1163
|
-
\`\`\`
|
|
1164
|
-
|
|
1165
|
-
## Usage Example
|
|
1166
|
-
|
|
1167
|
-
\`\`\`tsx
|
|
1168
|
-
import { ${target} } from '@/components/${target}'
|
|
1169
|
-
|
|
1170
|
-
function App() {
|
|
1171
|
-
return (
|
|
1172
|
-
<${target}
|
|
1173
|
-
id="example"
|
|
1174
|
-
onAction={(data) => console.log(data)}
|
|
1175
|
-
/>
|
|
1176
|
-
)
|
|
1177
|
-
}
|
|
1178
|
-
\`\`\`
|
|
1179
|
-
|
|
1180
|
-
## Dependencies
|
|
1181
|
-
|
|
1182
|
-
- React
|
|
1183
|
-
- [Other libraries]
|
|
1184
|
-
|
|
1185
|
-
## Implementation Notes
|
|
1186
|
-
|
|
1187
|
-
1. [ ] Setup component structure
|
|
1188
|
-
2. [ ] Implement core logic
|
|
1189
|
-
3. [ ] Add styling
|
|
1190
|
-
4. [ ] Write tests
|
|
1191
|
-
5. [ ] Document usage
|
|
1192
|
-
|
|
1193
|
-
---
|
|
1194
|
-
*Component design is iterative. Update as needed.*
|
|
1195
|
-
`
|
|
989
|
+
// AGENTIC: Claude generates via templates/design/component.md
|
|
990
|
+
return `# Component Design: ${target}\n\n*Use templates/design/component.md for full design*\n`
|
|
1196
991
|
}
|
|
1197
992
|
|
|
1198
993
|
/**
|
|
@@ -1200,68 +995,8 @@ function App() {
|
|
|
1200
995
|
* @private
|
|
1201
996
|
*/
|
|
1202
997
|
_generateDatabaseDesign(target) {
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
**Created**: ${new Date().toLocaleString()}
|
|
1206
|
-
**Type**: Database Schema
|
|
1207
|
-
|
|
1208
|
-
## Schema
|
|
1209
|
-
|
|
1210
|
-
### Table: ${target.toLowerCase()}
|
|
1211
|
-
|
|
1212
|
-
\`\`\`sql
|
|
1213
|
-
CREATE TABLE ${target.toLowerCase()} (
|
|
1214
|
-
id SERIAL PRIMARY KEY,
|
|
1215
|
-
name VARCHAR(255) NOT NULL,
|
|
1216
|
-
description TEXT,
|
|
1217
|
-
status VARCHAR(50) DEFAULT 'active',
|
|
1218
|
-
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1219
|
-
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
1220
|
-
);
|
|
1221
|
-
\`\`\`
|
|
1222
|
-
|
|
1223
|
-
## Indexes
|
|
1224
|
-
|
|
1225
|
-
\`\`\`sql
|
|
1226
|
-
CREATE INDEX idx_${target.toLowerCase()}_status ON ${target.toLowerCase()}(status);
|
|
1227
|
-
CREATE INDEX idx_${target.toLowerCase()}_created_at ON ${target.toLowerCase()}(created_at);
|
|
1228
|
-
\`\`\`
|
|
1229
|
-
|
|
1230
|
-
## Relationships
|
|
1231
|
-
|
|
1232
|
-
- **Related Tables**: [List related tables]
|
|
1233
|
-
- **Foreign Keys**: [Define foreign keys]
|
|
1234
|
-
|
|
1235
|
-
## Queries
|
|
1236
|
-
|
|
1237
|
-
### Common Queries
|
|
1238
|
-
|
|
1239
|
-
\`\`\`sql
|
|
1240
|
-
-- Get active records
|
|
1241
|
-
SELECT * FROM ${target.toLowerCase()} WHERE status = 'active';
|
|
1242
|
-
|
|
1243
|
-
-- Get recent records
|
|
1244
|
-
SELECT * FROM ${target.toLowerCase()}
|
|
1245
|
-
ORDER BY created_at DESC
|
|
1246
|
-
LIMIT 10;
|
|
1247
|
-
\`\`\`
|
|
1248
|
-
|
|
1249
|
-
## Migrations
|
|
1250
|
-
|
|
1251
|
-
1. [ ] Create initial schema
|
|
1252
|
-
2. [ ] Add indexes
|
|
1253
|
-
3. [ ] Setup relationships
|
|
1254
|
-
4. [ ] Add constraints
|
|
1255
|
-
|
|
1256
|
-
## Notes
|
|
1257
|
-
|
|
1258
|
-
- Consider partitioning for large datasets
|
|
1259
|
-
- Add audit logging if needed
|
|
1260
|
-
- Implement soft deletes
|
|
1261
|
-
|
|
1262
|
-
---
|
|
1263
|
-
*Database design should evolve with requirements.*
|
|
1264
|
-
`
|
|
998
|
+
// AGENTIC: Claude generates via templates/design/database.md
|
|
999
|
+
return `# Database Design: ${target}\n\n*Use templates/design/database.md for full design*\n`
|
|
1265
1000
|
}
|
|
1266
1001
|
|
|
1267
1002
|
/**
|
|
@@ -1269,63 +1004,8 @@ LIMIT 10;
|
|
|
1269
1004
|
* @private
|
|
1270
1005
|
*/
|
|
1271
1006
|
_generateFlowDesign(target) {
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
**Created**: ${new Date().toLocaleString()}
|
|
1275
|
-
**Type**: Process Flow
|
|
1276
|
-
|
|
1277
|
-
## Flow Overview
|
|
1278
|
-
|
|
1279
|
-
Process flow for ${target}.
|
|
1280
|
-
|
|
1281
|
-
## Steps
|
|
1282
|
-
|
|
1283
|
-
\`\`\`
|
|
1284
|
-
1. [User Action/Trigger]
|
|
1285
|
-
β
|
|
1286
|
-
2. [Validation]
|
|
1287
|
-
β
|
|
1288
|
-
3. [Processing]
|
|
1289
|
-
β
|
|
1290
|
-
4. [Side Effects]
|
|
1291
|
-
β
|
|
1292
|
-
5. [Response/Completion]
|
|
1293
|
-
\`\`\`
|
|
1294
|
-
|
|
1295
|
-
## Detailed Flow
|
|
1296
|
-
|
|
1297
|
-
### Step 1: Initial Action
|
|
1298
|
-
- **Input**: [What triggers this]
|
|
1299
|
-
- **Validation**: [What gets checked]
|
|
1300
|
-
- **Output**: [What proceeds]
|
|
1301
|
-
|
|
1302
|
-
### Step 2: Processing
|
|
1303
|
-
- **Actions**: [What happens]
|
|
1304
|
-
- **Dependencies**: [What's needed]
|
|
1305
|
-
- **Side Effects**: [What changes]
|
|
1306
|
-
|
|
1307
|
-
### Step 3: Completion
|
|
1308
|
-
- **Success**: [What happens on success]
|
|
1309
|
-
- **Failure**: [What happens on failure]
|
|
1310
|
-
- **Notifications**: [Who gets notified]
|
|
1311
|
-
|
|
1312
|
-
## Error Handling
|
|
1313
|
-
|
|
1314
|
-
- **Error Type 1**: [Recovery strategy]
|
|
1315
|
-
- **Error Type 2**: [Recovery strategy]
|
|
1316
|
-
|
|
1317
|
-
## Rollback Strategy
|
|
1318
|
-
|
|
1319
|
-
[How to undo if needed]
|
|
1320
|
-
|
|
1321
|
-
## Monitoring
|
|
1322
|
-
|
|
1323
|
-
- **Metrics**: [What to track]
|
|
1324
|
-
- **Alerts**: [When to alert]
|
|
1325
|
-
|
|
1326
|
-
---
|
|
1327
|
-
*Document edge cases and special scenarios.*
|
|
1328
|
-
`
|
|
1007
|
+
// AGENTIC: Claude generates via templates/design/flow.md
|
|
1008
|
+
return `# Flow Design: ${target}\n\n*Use templates/design/flow.md for full design*\n`
|
|
1329
1009
|
}
|
|
1330
1010
|
|
|
1331
1011
|
/**
|
|
@@ -1661,30 +1341,13 @@ Status: βΈοΈ Planned
|
|
|
1661
1341
|
* @private
|
|
1662
1342
|
*/
|
|
1663
1343
|
_calculateHealth(stats) {
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
if (stats.tasksInQueue >= 15) score -= 5 // Too many tasks
|
|
1672
|
-
|
|
1673
|
-
// Shipped features is great
|
|
1674
|
-
score += Math.min(20, stats.featuresShipped * 5)
|
|
1675
|
-
|
|
1676
|
-
// Ideas are good but not critical
|
|
1677
|
-
score += Math.min(10, stats.ideasCaptured * 2)
|
|
1678
|
-
|
|
1679
|
-
score = Math.max(0, Math.min(100, score))
|
|
1680
|
-
|
|
1681
|
-
let message = ''
|
|
1682
|
-
if (score >= 80) message = 'π’ Excellent - Great momentum!'
|
|
1683
|
-
else if (score >= 60) message = 'π‘ Good - Keep shipping!'
|
|
1684
|
-
else if (score >= 40) message = 'π Fair - Need more activity'
|
|
1685
|
-
else message = 'π΄ Low - Time to get started!'
|
|
1686
|
-
|
|
1687
|
-
return { score, message }
|
|
1344
|
+
// AGENTIC: Claude evaluates health via templates/analysis/health.md
|
|
1345
|
+
// Simple calculation - real assessment happens in template execution
|
|
1346
|
+
const hasActivity = stats.activeTask || stats.featuresShipped > 0
|
|
1347
|
+
return {
|
|
1348
|
+
score: hasActivity ? 70 : 50,
|
|
1349
|
+
message: hasActivity ? 'π’ Active' : 'π‘ Ready to start',
|
|
1350
|
+
}
|
|
1688
1351
|
}
|
|
1689
1352
|
|
|
1690
1353
|
/**
|
|
@@ -1747,9 +1410,11 @@ Status: βΈοΈ Planned
|
|
|
1747
1410
|
console.log(` Estimated: ${estimate}h`)
|
|
1748
1411
|
console.log(` Type: ${complexity.type}\n`)
|
|
1749
1412
|
|
|
1750
|
-
//
|
|
1751
|
-
const
|
|
1752
|
-
|
|
1413
|
+
// MANDATORY: Assign agent using router
|
|
1414
|
+
const agentResult = await this._assignAgentForTask(task, projectPath, context)
|
|
1415
|
+
const agent = agentResult.agent?.name || 'generalist'
|
|
1416
|
+
const confidence = agentResult.routing?.confidence || 0.5
|
|
1417
|
+
console.log(`π€ Agent: ${agent} (${Math.round(confidence * 100)}% confidence)\n`)
|
|
1753
1418
|
|
|
1754
1419
|
// Set as current task with metadata
|
|
1755
1420
|
const nowContentNew = `# NOW
|
|
@@ -1759,7 +1424,7 @@ Status: βΈοΈ Planned
|
|
|
1759
1424
|
Started: ${new Date().toLocaleString()}
|
|
1760
1425
|
Estimated: ${estimate}h
|
|
1761
1426
|
Complexity: ${complexity.level}
|
|
1762
|
-
Agent: ${agent}
|
|
1427
|
+
Agent: ${agent} (${Math.round(confidence * 100)}% confidence)
|
|
1763
1428
|
`
|
|
1764
1429
|
await toolRegistry.get('Write')(context.paths.now, nowContentNew)
|
|
1765
1430
|
|
|
@@ -1774,6 +1439,7 @@ Agent: ${agent}
|
|
|
1774
1439
|
complexity: complexity.level,
|
|
1775
1440
|
estimate,
|
|
1776
1441
|
agent,
|
|
1442
|
+
confidence,
|
|
1777
1443
|
timestamp: dateHelper.getTimestamp(),
|
|
1778
1444
|
})
|
|
1779
1445
|
|
|
@@ -1789,72 +1455,64 @@ Agent: ${agent}
|
|
|
1789
1455
|
* @private
|
|
1790
1456
|
*/
|
|
1791
1457
|
_detectComplexity(task) {
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
if (lowerTask.includes('fix') || lowerTask.includes('bug')) type = 'bugfix'
|
|
1797
|
-
else if (lowerTask.includes('test')) type = 'testing'
|
|
1798
|
-
else if (lowerTask.includes('refactor')) type = 'refactoring'
|
|
1799
|
-
else if (lowerTask.includes('implement') || lowerTask.includes('add')) type = 'feature'
|
|
1800
|
-
else if (lowerTask.includes('design')) type = 'design'
|
|
1801
|
-
|
|
1802
|
-
// Complexity indicators
|
|
1803
|
-
const complexityIndicators = {
|
|
1804
|
-
high: ['architecture', 'redesign', 'migration', 'integration', 'authentication', 'database'],
|
|
1805
|
-
medium: ['api', 'component', 'service', 'endpoint', 'feature'],
|
|
1806
|
-
low: ['fix', 'update', 'modify', 'adjust', 'tweak'],
|
|
1807
|
-
}
|
|
1458
|
+
// AGENTIC: Claude analyzes complexity via templates/analysis/complexity.md
|
|
1459
|
+
// Returns default - real analysis happens in template execution
|
|
1460
|
+
return { level: 'medium', hours: 4, type: 'feature' }
|
|
1461
|
+
}
|
|
1808
1462
|
|
|
1809
|
-
|
|
1810
|
-
|
|
1463
|
+
/**
|
|
1464
|
+
* Assign agent for a task
|
|
1465
|
+
* AGENTIC: Claude decides via templates/agent-assignment.md
|
|
1466
|
+
* JS only orchestrates: load agents β build context β delegate to Claude
|
|
1467
|
+
* @private
|
|
1468
|
+
*/
|
|
1469
|
+
async _assignAgentForTask(taskDescription, projectPath, context) {
|
|
1470
|
+
try {
|
|
1471
|
+
const projectId = await configManager.getProjectId(projectPath)
|
|
1811
1472
|
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1473
|
+
// ORCHESTRATION ONLY: Load available agents
|
|
1474
|
+
const agentsPath = pathManager.getPath(projectId, 'agents')
|
|
1475
|
+
const agentFiles = await fileHelper.listFiles(agentsPath, '.md')
|
|
1476
|
+
const agents = agentFiles.map(f => f.replace('.md', ''))
|
|
1477
|
+
|
|
1478
|
+
// ORCHESTRATION ONLY: Build context for Claude
|
|
1479
|
+
const assignmentContext = {
|
|
1480
|
+
task: taskDescription,
|
|
1481
|
+
agents: agents.join(', ') || 'generalist',
|
|
1482
|
+
projectPath,
|
|
1483
|
+
// Claude will use this context + template to decide
|
|
1816
1484
|
}
|
|
1817
|
-
}
|
|
1818
|
-
|
|
1819
|
-
// Estimate hours
|
|
1820
|
-
if (level === 'high') hours = 8
|
|
1821
|
-
else if (level === 'medium') hours = 4
|
|
1822
|
-
else hours = 2
|
|
1823
1485
|
|
|
1824
|
-
|
|
1486
|
+
// AGENTIC: Claude decides agent via template
|
|
1487
|
+
// The template templates/agent-assignment.md guides Claude's decision
|
|
1488
|
+
// For now, return structure that prompt-builder will use with template
|
|
1489
|
+
return {
|
|
1490
|
+
agent: { name: agents[0] || 'generalist', domain: 'auto' },
|
|
1491
|
+
routing: {
|
|
1492
|
+
confidence: 0.8,
|
|
1493
|
+
reason: 'Claude assigns via templates/agent-assignment.md',
|
|
1494
|
+
availableAgents: agents
|
|
1495
|
+
},
|
|
1496
|
+
_agenticNote: 'Use templates/agent-assignment.md for actual assignment'
|
|
1497
|
+
}
|
|
1498
|
+
} catch (error) {
|
|
1499
|
+
// Fallback - still return structure
|
|
1500
|
+
return {
|
|
1501
|
+
agent: { name: 'generalist', domain: 'general' },
|
|
1502
|
+
routing: { confidence: 0.5, reason: 'Fallback - no agents found' }
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1825
1505
|
}
|
|
1826
1506
|
|
|
1827
1507
|
/**
|
|
1828
|
-
* Auto-assign agent based on task
|
|
1508
|
+
* Auto-assign agent based on task (sync wrapper for backward compat)
|
|
1509
|
+
* DEPRECATED: Use _assignAgentForTask instead
|
|
1829
1510
|
* @private
|
|
1830
1511
|
*/
|
|
1831
1512
|
_autoAssignAgent(task) {
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
lowerTask.includes('ui') ||
|
|
1836
|
-
lowerTask.includes('component') ||
|
|
1837
|
-
lowerTask.includes('frontend')
|
|
1838
|
-
) {
|
|
1839
|
-
return 'frontend-specialist'
|
|
1840
|
-
}
|
|
1841
|
-
if (
|
|
1842
|
-
lowerTask.includes('api') ||
|
|
1843
|
-
lowerTask.includes('backend') ||
|
|
1844
|
-
lowerTask.includes('database')
|
|
1845
|
-
) {
|
|
1846
|
-
return 'backend-specialist'
|
|
1847
|
-
}
|
|
1848
|
-
if (lowerTask.includes('test')) {
|
|
1849
|
-
return 'qa-specialist'
|
|
1850
|
-
}
|
|
1851
|
-
if (lowerTask.includes('design') || lowerTask.includes('architecture')) {
|
|
1852
|
-
return 'architect'
|
|
1853
|
-
}
|
|
1854
|
-
if (lowerTask.includes('deploy') || lowerTask.includes('docker')) {
|
|
1855
|
-
return 'devops-specialist'
|
|
1856
|
-
}
|
|
1857
|
-
|
|
1513
|
+
// For backward compatibility, return generalist synchronously
|
|
1514
|
+
// New code should use _assignAgentForTask() which is async
|
|
1515
|
+
console.warn('DEPRECATED: Use _assignAgentForTask() for proper agent routing')
|
|
1858
1516
|
return 'generalist'
|
|
1859
1517
|
}
|
|
1860
1518
|
|