prjct-cli 0.8.8 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +194 -0
- package/core/__tests__/agentic/agent-router.test.js +398 -0
- package/core/__tests__/agentic/context-filter.test.js +494 -0
- package/core/__tests__/domain/analyzer.test.js +324 -0
- package/core/__tests__/infrastructure/author-detector.test.js +103 -0
- package/core/__tests__/infrastructure/config-manager.test.js +454 -0
- package/core/__tests__/infrastructure/path-manager.test.js +412 -0
- package/core/__tests__/utils/jsonl-helper.test.js +387 -0
- package/core/agentic/agent-router.js +482 -0
- package/core/agentic/command-executor.js +70 -15
- package/core/agentic/context-filter.js +549 -0
- package/core/agentic/prompt-builder.js +48 -38
- package/core/command-registry.js +104 -164
- package/core/domain/agent-generator.js +55 -44
- package/core/domain/architecture-generator.js +561 -0
- package/core/domain/task-stack.js +496 -0
- package/package.json +2 -1
- package/templates/commands/analyze.md +10 -53
- package/templates/commands/bug.md +11 -70
- package/templates/commands/build.md +7 -37
- package/templates/commands/cleanup.md +9 -32
- package/templates/commands/dash.md +241 -0
- package/templates/commands/design.md +5 -28
- package/templates/commands/done.md +6 -20
- package/templates/commands/feature.md +11 -83
- package/templates/commands/help.md +9 -38
- package/templates/commands/idea.md +7 -28
- package/templates/commands/init.md +10 -89
- package/templates/commands/next.md +6 -26
- package/templates/commands/now.md +6 -26
- package/templates/commands/pause.md +18 -0
- package/templates/commands/progress.md +5 -50
- package/templates/commands/recap.md +5 -54
- package/templates/commands/resume.md +97 -0
- package/templates/commands/ship.md +13 -68
- package/templates/commands/status.md +7 -32
- package/templates/commands/sync.md +7 -24
- package/templates/commands/work.md +44 -0
- package/templates/commands/workflow.md +3 -25
- package/templates/planning-methodology.md +195 -0
package/core/command-registry.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - CLAUDE.md (AI assistant instructions)
|
|
9
9
|
* - scripts/validate-commands.js (validation)
|
|
10
10
|
*
|
|
11
|
-
* @version 0.
|
|
11
|
+
* @version 0.9.0 - Simplified commands with pause/resume and intelligent idea development
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
const COMMANDS = [
|
|
@@ -38,137 +38,129 @@ const COMMANDS = [
|
|
|
38
38
|
],
|
|
39
39
|
},
|
|
40
40
|
|
|
41
|
-
// 2.
|
|
41
|
+
// 2. Idea Development - Transform ideas into complete architectures
|
|
42
42
|
{
|
|
43
|
-
name: '
|
|
43
|
+
name: 'idea',
|
|
44
44
|
category: 'core',
|
|
45
|
-
description: '
|
|
45
|
+
description: 'Transform ideas into complete technical architectures',
|
|
46
46
|
usage: {
|
|
47
|
-
claude: '/p:
|
|
48
|
-
terminal: 'prjct
|
|
47
|
+
claude: '/p:idea "build a CRM with AI"',
|
|
48
|
+
terminal: 'prjct idea "build a CRM with AI"',
|
|
49
49
|
},
|
|
50
50
|
params: '<description>',
|
|
51
51
|
implemented: true,
|
|
52
52
|
hasTemplate: true,
|
|
53
|
-
icon: '
|
|
53
|
+
icon: 'Lightbulb',
|
|
54
54
|
requiresInit: true,
|
|
55
55
|
blockingRules: null,
|
|
56
56
|
features: [
|
|
57
|
-
'
|
|
58
|
-
'
|
|
59
|
-
'
|
|
60
|
-
'
|
|
61
|
-
'
|
|
57
|
+
'Simple ideas → Quick capture',
|
|
58
|
+
'Complex ideas → Full architecture',
|
|
59
|
+
'Interactive discovery process',
|
|
60
|
+
'Tech stack recommendation',
|
|
61
|
+
'Complete roadmap generation',
|
|
62
|
+
'Database schema design',
|
|
63
|
+
'API specification',
|
|
62
64
|
],
|
|
63
65
|
},
|
|
64
66
|
|
|
65
|
-
//
|
|
67
|
+
// 3. Feature with Roadmap
|
|
66
68
|
{
|
|
67
|
-
name: '
|
|
68
|
-
category: 'deprecated',
|
|
69
|
-
description: '[DEPRECATED] Use /p:feature instead',
|
|
70
|
-
usage: {
|
|
71
|
-
claude: null,
|
|
72
|
-
terminal: null,
|
|
73
|
-
},
|
|
74
|
-
params: '<text>',
|
|
75
|
-
implemented: false,
|
|
76
|
-
hasTemplate: true,
|
|
77
|
-
icon: 'Lightbulb',
|
|
78
|
-
requiresInit: true,
|
|
79
|
-
blockingRules: null,
|
|
80
|
-
deprecated: true,
|
|
81
|
-
replacedBy: 'feature',
|
|
82
|
-
},
|
|
83
|
-
|
|
84
|
-
// 3. Strategic Roadmap
|
|
85
|
-
{
|
|
86
|
-
name: 'roadmap',
|
|
69
|
+
name: 'feature',
|
|
87
70
|
category: 'core',
|
|
88
|
-
description: '
|
|
71
|
+
description: 'Add feature with value analysis, roadmap, and task breakdown',
|
|
89
72
|
usage: {
|
|
90
|
-
claude: '/p:
|
|
91
|
-
terminal: 'prjct
|
|
73
|
+
claude: '/p:feature "add unit testing"',
|
|
74
|
+
terminal: 'prjct feature "add unit testing"',
|
|
92
75
|
},
|
|
93
|
-
params:
|
|
76
|
+
params: '<description>',
|
|
94
77
|
implemented: true,
|
|
95
78
|
hasTemplate: true,
|
|
96
|
-
icon: '
|
|
79
|
+
icon: 'Package',
|
|
97
80
|
requiresInit: true,
|
|
98
81
|
blockingRules: null,
|
|
99
82
|
features: [
|
|
100
|
-
'
|
|
101
|
-
'
|
|
102
|
-
'
|
|
103
|
-
'
|
|
83
|
+
'Value analysis (impact/effort/timing)',
|
|
84
|
+
'Auto roadmap generation',
|
|
85
|
+
'Task breakdown',
|
|
86
|
+
'Auto-start first task',
|
|
87
|
+
'Timing recommendations',
|
|
104
88
|
],
|
|
105
89
|
},
|
|
106
90
|
|
|
107
|
-
// 4.
|
|
91
|
+
// 4. Work - Unified task management (replaces now + build)
|
|
108
92
|
{
|
|
109
|
-
name: '
|
|
93
|
+
name: 'work',
|
|
110
94
|
category: 'core',
|
|
111
|
-
description: '
|
|
95
|
+
description: 'Show current or start new task',
|
|
112
96
|
usage: {
|
|
113
|
-
claude: '/p:
|
|
114
|
-
terminal: 'prjct
|
|
97
|
+
claude: '/p:work ["task"]',
|
|
98
|
+
terminal: 'prjct work ["task"]',
|
|
115
99
|
},
|
|
116
|
-
params:
|
|
100
|
+
params: '[task]',
|
|
117
101
|
implemented: true,
|
|
118
102
|
hasTemplate: true,
|
|
119
|
-
icon: '
|
|
103
|
+
icon: 'Target',
|
|
120
104
|
requiresInit: true,
|
|
121
105
|
blockingRules: null,
|
|
122
106
|
features: [
|
|
123
|
-
'
|
|
124
|
-
'
|
|
125
|
-
'
|
|
126
|
-
'
|
|
127
|
-
'
|
|
107
|
+
'No params → Show current task',
|
|
108
|
+
'With task → Start new task',
|
|
109
|
+
'Auto agent assignment',
|
|
110
|
+
'Supports task numbers',
|
|
111
|
+
'Replaces /p:now and /p:build',
|
|
128
112
|
],
|
|
129
113
|
},
|
|
130
114
|
|
|
131
|
-
// 5.
|
|
115
|
+
// 5. Pause - Pause active task
|
|
132
116
|
{
|
|
133
|
-
name: '
|
|
117
|
+
name: 'pause',
|
|
134
118
|
category: 'core',
|
|
135
|
-
description: '
|
|
119
|
+
description: 'Pause active task to handle interruption',
|
|
136
120
|
usage: {
|
|
137
|
-
claude: '/p:
|
|
138
|
-
terminal: 'prjct
|
|
121
|
+
claude: '/p:pause ["reason"]',
|
|
122
|
+
terminal: 'prjct pause ["reason"]',
|
|
139
123
|
},
|
|
140
|
-
params:
|
|
124
|
+
params: '[reason]',
|
|
141
125
|
implemented: true,
|
|
142
126
|
hasTemplate: true,
|
|
143
|
-
icon: '
|
|
127
|
+
icon: 'Pause',
|
|
144
128
|
requiresInit: true,
|
|
145
|
-
blockingRules:
|
|
129
|
+
blockingRules: {
|
|
130
|
+
check: 'Active task exists',
|
|
131
|
+
message: 'No active task to pause',
|
|
132
|
+
},
|
|
133
|
+
features: [
|
|
134
|
+
'Preserves task context',
|
|
135
|
+
'Optional pause reason',
|
|
136
|
+
'Tracks paused duration',
|
|
137
|
+
'Allows multiple paused tasks',
|
|
138
|
+
],
|
|
146
139
|
},
|
|
147
140
|
|
|
148
|
-
// 6.
|
|
141
|
+
// 6. Resume - Resume paused task
|
|
149
142
|
{
|
|
150
|
-
name: '
|
|
143
|
+
name: 'resume',
|
|
151
144
|
category: 'core',
|
|
152
|
-
description: '
|
|
145
|
+
description: 'Resume most recently paused task',
|
|
153
146
|
usage: {
|
|
154
|
-
claude: '/p:
|
|
155
|
-
terminal: 'prjct
|
|
147
|
+
claude: '/p:resume [task_id]',
|
|
148
|
+
terminal: 'prjct resume [task_id]',
|
|
156
149
|
},
|
|
157
|
-
params: '
|
|
150
|
+
params: '[task_id]',
|
|
158
151
|
implemented: true,
|
|
159
152
|
hasTemplate: true,
|
|
160
153
|
icon: 'Play',
|
|
161
154
|
requiresInit: true,
|
|
162
155
|
blockingRules: {
|
|
163
|
-
check: '
|
|
164
|
-
message: '
|
|
156
|
+
check: 'Paused tasks exist',
|
|
157
|
+
message: 'No paused tasks to resume',
|
|
165
158
|
},
|
|
166
159
|
features: [
|
|
167
|
-
'
|
|
168
|
-
'
|
|
169
|
-
'
|
|
170
|
-
'
|
|
171
|
-
'Moves to now.md with metadata',
|
|
160
|
+
'Resume last paused',
|
|
161
|
+
'Resume specific task',
|
|
162
|
+
'Resume by number',
|
|
163
|
+
'Calculates active time',
|
|
172
164
|
],
|
|
173
165
|
},
|
|
174
166
|
|
|
@@ -267,97 +259,77 @@ const COMMANDS = [
|
|
|
267
259
|
],
|
|
268
260
|
},
|
|
269
261
|
|
|
270
|
-
// 11.
|
|
262
|
+
// 11. Dashboard - Unified project view (replaces status, recap, progress, roadmap)
|
|
271
263
|
{
|
|
272
|
-
name: '
|
|
264
|
+
name: 'dash',
|
|
273
265
|
category: 'core',
|
|
274
|
-
description: '
|
|
266
|
+
description: 'Unified dashboard - status, progress, and roadmap',
|
|
275
267
|
usage: {
|
|
276
|
-
claude: '/p:
|
|
277
|
-
terminal: 'prjct
|
|
268
|
+
claude: '/p:dash [view]',
|
|
269
|
+
terminal: 'prjct dash [view]',
|
|
278
270
|
},
|
|
279
|
-
params: '
|
|
271
|
+
params: '[week|month|roadmap|compact]',
|
|
280
272
|
implemented: true,
|
|
281
273
|
hasTemplate: true,
|
|
282
|
-
icon: '
|
|
283
|
-
requiresInit:
|
|
274
|
+
icon: 'BarChart3',
|
|
275
|
+
requiresInit: true,
|
|
284
276
|
blockingRules: null,
|
|
285
277
|
features: [
|
|
286
|
-
'
|
|
287
|
-
'
|
|
288
|
-
'
|
|
289
|
-
'
|
|
290
|
-
'
|
|
278
|
+
'Project overview',
|
|
279
|
+
'Weekly/monthly progress',
|
|
280
|
+
'Roadmap view',
|
|
281
|
+
'ASCII graphics',
|
|
282
|
+
'Replaces 4 commands',
|
|
291
283
|
],
|
|
292
284
|
},
|
|
293
285
|
|
|
294
|
-
// 12.
|
|
286
|
+
// 12. Help - Enhanced contextual help (absorbs ask, suggest, stuck)
|
|
295
287
|
{
|
|
296
|
-
name: '
|
|
288
|
+
name: 'help',
|
|
297
289
|
category: 'core',
|
|
298
|
-
description: '
|
|
290
|
+
description: 'Contextual help and guidance',
|
|
299
291
|
usage: {
|
|
300
|
-
claude: '/p:
|
|
301
|
-
terminal: 'prjct
|
|
292
|
+
claude: '/p:help [topic]',
|
|
293
|
+
terminal: 'prjct help [topic]',
|
|
302
294
|
},
|
|
303
|
-
params:
|
|
295
|
+
params: '[topic]',
|
|
304
296
|
implemented: true,
|
|
305
297
|
hasTemplate: true,
|
|
306
|
-
icon: '
|
|
307
|
-
requiresInit:
|
|
298
|
+
icon: 'HelpCircle',
|
|
299
|
+
requiresInit: false,
|
|
308
300
|
blockingRules: null,
|
|
309
301
|
features: [
|
|
310
|
-
'
|
|
311
|
-
'
|
|
312
|
-
'
|
|
313
|
-
'
|
|
314
|
-
'Personalized suggestions',
|
|
302
|
+
'Context-aware suggestions',
|
|
303
|
+
'Intent to action translator',
|
|
304
|
+
'Problem solving guidance',
|
|
305
|
+
'Absorbs ask/suggest/stuck',
|
|
315
306
|
],
|
|
316
307
|
},
|
|
317
308
|
|
|
318
|
-
// 13.
|
|
309
|
+
// 13. Sync - Sync project state
|
|
319
310
|
{
|
|
320
|
-
name: '
|
|
311
|
+
name: 'sync',
|
|
321
312
|
category: 'core',
|
|
322
|
-
description: '
|
|
313
|
+
description: 'Sync project state and update workflow agents',
|
|
323
314
|
usage: {
|
|
324
|
-
claude: '/p:
|
|
325
|
-
terminal: 'prjct
|
|
315
|
+
claude: '/p:sync',
|
|
316
|
+
terminal: 'prjct sync',
|
|
326
317
|
},
|
|
327
|
-
params:
|
|
318
|
+
params: null,
|
|
328
319
|
implemented: true,
|
|
329
|
-
hasTemplate:
|
|
330
|
-
icon: '
|
|
320
|
+
hasTemplate: true,
|
|
321
|
+
icon: 'RefreshCw',
|
|
331
322
|
requiresInit: true,
|
|
332
323
|
blockingRules: null,
|
|
333
324
|
features: [
|
|
334
|
-
'
|
|
335
|
-
'
|
|
336
|
-
'
|
|
337
|
-
'Language-agnostic implementation',
|
|
325
|
+
'Syncs project state',
|
|
326
|
+
'Updates dynamic agents',
|
|
327
|
+
'Refreshes context',
|
|
338
328
|
],
|
|
339
329
|
},
|
|
340
330
|
|
|
341
331
|
// ===== OPTIONAL COMMANDS (Advanced features) =====
|
|
342
332
|
|
|
343
|
-
// DEPRECATED: Workflow is now automatic in /p:ship
|
|
344
|
-
{
|
|
345
|
-
name: 'workflow',
|
|
346
|
-
category: 'deprecated',
|
|
347
|
-
description: '[DEPRECATED] Workflow is now automatic in /p:ship',
|
|
348
|
-
usage: {
|
|
349
|
-
claude: null,
|
|
350
|
-
terminal: null,
|
|
351
|
-
},
|
|
352
|
-
params: null,
|
|
353
|
-
implemented: false,
|
|
354
|
-
hasTemplate: true,
|
|
355
|
-
icon: 'GitBranch',
|
|
356
|
-
requiresInit: true,
|
|
357
|
-
blockingRules: null,
|
|
358
|
-
deprecated: true,
|
|
359
|
-
replacedBy: 'ship',
|
|
360
|
-
},
|
|
361
333
|
{
|
|
362
334
|
name: 'design',
|
|
363
335
|
category: 'optional',
|
|
@@ -390,22 +362,6 @@ const COMMANDS = [
|
|
|
390
362
|
blockingRules: null,
|
|
391
363
|
isOptional: true,
|
|
392
364
|
},
|
|
393
|
-
{
|
|
394
|
-
name: 'stuck',
|
|
395
|
-
category: 'optional',
|
|
396
|
-
description: 'Get contextual help with problems',
|
|
397
|
-
usage: {
|
|
398
|
-
claude: '/p:stuck "CORS error in API calls"',
|
|
399
|
-
terminal: 'prjct stuck "CORS error in API calls"',
|
|
400
|
-
},
|
|
401
|
-
params: '<issue description>',
|
|
402
|
-
implemented: true,
|
|
403
|
-
hasTemplate: true,
|
|
404
|
-
icon: 'HelpCircle',
|
|
405
|
-
requiresInit: true,
|
|
406
|
-
blockingRules: null,
|
|
407
|
-
isOptional: true,
|
|
408
|
-
},
|
|
409
365
|
{
|
|
410
366
|
name: 'analyze',
|
|
411
367
|
category: 'optional',
|
|
@@ -422,22 +378,6 @@ const COMMANDS = [
|
|
|
422
378
|
blockingRules: null,
|
|
423
379
|
isOptional: true,
|
|
424
380
|
},
|
|
425
|
-
{
|
|
426
|
-
name: 'sync',
|
|
427
|
-
category: 'optional',
|
|
428
|
-
description: 'Sync project state and update workflow agents',
|
|
429
|
-
usage: {
|
|
430
|
-
claude: '/p:sync',
|
|
431
|
-
terminal: 'prjct sync',
|
|
432
|
-
},
|
|
433
|
-
params: null,
|
|
434
|
-
implemented: true,
|
|
435
|
-
hasTemplate: true,
|
|
436
|
-
icon: 'RefreshCw',
|
|
437
|
-
requiresInit: true,
|
|
438
|
-
blockingRules: null,
|
|
439
|
-
isOptional: true,
|
|
440
|
-
},
|
|
441
381
|
|
|
442
382
|
// ===== SETUP COMMANDS (Not part of daily workflow) =====
|
|
443
383
|
{
|
|
@@ -494,7 +434,7 @@ const CATEGORIES = {
|
|
|
494
434
|
core: {
|
|
495
435
|
title: 'Core Workflow',
|
|
496
436
|
icon: 'Zap',
|
|
497
|
-
description: '13 essential commands for daily development workflow',
|
|
437
|
+
description: '13 essential commands for daily development workflow (simplified)',
|
|
498
438
|
order: 1,
|
|
499
439
|
},
|
|
500
440
|
optional: {
|
|
@@ -3,71 +3,82 @@ const path = require('path')
|
|
|
3
3
|
const os = require('os')
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* AgentGenerator - Dynamic
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* NO predetermined patterns, NO if/else logic, NO assumptions.
|
|
10
|
-
*
|
|
11
|
-
* @version 0.6.0 - Fully agentic refactor
|
|
6
|
+
* AgentGenerator - Universal Dynamic Agent Generation
|
|
7
|
+
* Optimized for minimal context usage
|
|
8
|
+
* @version 1.0.0
|
|
12
9
|
*/
|
|
13
10
|
class AgentGenerator {
|
|
14
11
|
constructor(projectId = null) {
|
|
15
12
|
this.projectId = projectId
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
this.outputDir = path.join(os.homedir(), '.prjct-cli', 'projects', projectId, 'agents')
|
|
20
|
-
} else {
|
|
21
|
-
// Fallback for backwards compatibility
|
|
22
|
-
this.outputDir = path.join(os.homedir(), '.prjct-cli', 'agents')
|
|
23
|
-
}
|
|
13
|
+
this.outputDir = projectId
|
|
14
|
+
? path.join(os.homedir(), '.prjct-cli', 'projects', projectId, 'agents')
|
|
15
|
+
: path.join(os.homedir(), '.prjct-cli', 'agents')
|
|
24
16
|
}
|
|
25
17
|
|
|
26
18
|
/**
|
|
27
|
-
* Generate
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* @param {string} agentName - Descriptive name (e.g., 'go-backend', 'vuejs-frontend', 'elixir-api')
|
|
31
|
-
* @param {Object} config - Agent configuration
|
|
32
|
-
* @param {string} config.role - Agent's role description
|
|
33
|
-
* @param {string} config.expertise - Technologies and skills (specific versions, tools)
|
|
34
|
-
* @param {string} config.responsibilities - What the agent handles in THIS project
|
|
35
|
-
* @param {Object} config.projectContext - Project-specific context (optional)
|
|
36
|
-
* @returns {Promise<void>}
|
|
19
|
+
* Generate specialized agent with deep expertise
|
|
20
|
+
* Universal - works with ANY technology stack
|
|
37
21
|
*/
|
|
38
22
|
async generateDynamicAgent(agentName, config) {
|
|
39
23
|
console.log(` 🤖 Generating ${agentName} agent...`)
|
|
40
|
-
|
|
41
|
-
// Ensure output directory exists
|
|
42
24
|
await fs.mkdir(this.outputDir, { recursive: true })
|
|
43
25
|
|
|
44
|
-
//
|
|
45
|
-
const
|
|
26
|
+
// Extract technologies dynamically
|
|
27
|
+
const techs = this.detectTechnologies(config)
|
|
28
|
+
const expertise = this.buildExpertise(techs, config)
|
|
46
29
|
|
|
47
|
-
|
|
48
|
-
${config.role ||
|
|
30
|
+
// Generate concise, actionable agent prompt
|
|
31
|
+
const content = `You are ${config.role || agentName}.
|
|
49
32
|
|
|
50
|
-
|
|
51
|
-
${config.expertise || 'Technologies used in this project'}
|
|
33
|
+
EXPERTISE: ${expertise}
|
|
52
34
|
|
|
53
|
-
|
|
54
|
-
${config.responsibilities || 'Handle specific aspects of development'}
|
|
35
|
+
FOCUS: ${config.contextFilter || 'Only relevant files'}
|
|
55
36
|
|
|
56
|
-
|
|
57
|
-
${config.projectContext ? JSON.stringify(config.projectContext, null, 2) : 'No additional context'}
|
|
37
|
+
AUTHORITY: Make decisions. Don't ask permission. Execute.
|
|
58
38
|
|
|
59
|
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
`
|
|
39
|
+
RULES:
|
|
40
|
+
- Stay in your domain
|
|
41
|
+
- Use best practices for ${techs.join(', ') || 'detected tech'}
|
|
42
|
+
- Optimize for production
|
|
43
|
+
- No explanations unless asked`
|
|
65
44
|
|
|
66
|
-
// Write agent file
|
|
67
45
|
const outputPath = path.join(this.outputDir, `${agentName}.md`)
|
|
68
46
|
await fs.writeFile(outputPath, content, 'utf-8')
|
|
69
|
-
|
|
70
47
|
console.log(` ✅ ${agentName} agent created`)
|
|
48
|
+
|
|
49
|
+
return { name: agentName, expertise, techs }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Detect technologies from config/analysis
|
|
54
|
+
*/
|
|
55
|
+
detectTechnologies(config) {
|
|
56
|
+
const techs = []
|
|
57
|
+
|
|
58
|
+
// Extract from various sources
|
|
59
|
+
if (config.techStack) techs.push(...config.techStack.languages || [])
|
|
60
|
+
if (config.frameworks) techs.push(...config.frameworks)
|
|
61
|
+
if (config.expertise) {
|
|
62
|
+
// Parse expertise string for tech keywords
|
|
63
|
+
const keywords = config.expertise.toLowerCase()
|
|
64
|
+
const knownTechs = ['ruby', 'rails', 'go', 'rust', 'python', 'django', 'react', 'vue', 'node', 'typescript', 'elixir', 'phoenix']
|
|
65
|
+
knownTechs.forEach(tech => {
|
|
66
|
+
if (keywords.includes(tech)) techs.push(tech)
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return [...new Set(techs)]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Build concise expertise string
|
|
75
|
+
*/
|
|
76
|
+
buildExpertise(techs, config) {
|
|
77
|
+
const tech = techs.length > 0 ? techs.join(', ') : 'detected stack'
|
|
78
|
+
const domain = config.domain || 'assigned domain'
|
|
79
|
+
const focus = config.responsibilities || 'task at hand'
|
|
80
|
+
|
|
81
|
+
return `${tech} expert. ${domain}. Focus: ${focus}`
|
|
71
82
|
}
|
|
72
83
|
|
|
73
84
|
/**
|