prjct-cli 0.5.1 → 0.7.0
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 +220 -7
- package/CLAUDE.md +476 -55
- package/README.md +48 -55
- package/bin/prjct +170 -225
- package/core/agentic/command-executor.js +113 -0
- package/core/agentic/context-builder.js +85 -0
- package/core/agentic/prompt-builder.js +86 -0
- package/core/agentic/template-loader.js +104 -0
- package/core/agentic/tool-registry.js +117 -0
- package/core/command-registry.js +597 -0
- package/core/commands.js +2046 -2028
- package/core/domain/agent-generator.js +118 -0
- package/core/domain/analyzer.js +211 -0
- package/core/domain/architect-session.js +300 -0
- package/core/{agents → infrastructure/agents}/claude-agent.js +16 -13
- package/core/{author-detector.js → infrastructure/author-detector.js} +3 -1
- package/core/{capability-installer.js → infrastructure/capability-installer.js} +3 -6
- package/core/{command-installer.js → infrastructure/command-installer.js} +4 -2
- package/core/{config-manager.js → infrastructure/config-manager.js} +4 -4
- package/core/{editors-config.js → infrastructure/editors-config.js} +2 -10
- package/core/{migrator.js → infrastructure/migrator.js} +34 -19
- package/core/{path-manager.js → infrastructure/path-manager.js} +20 -44
- package/core/{session-manager.js → infrastructure/session-manager.js} +45 -105
- package/core/{update-checker.js → infrastructure/update-checker.js} +67 -67
- package/core/{animations-simple.js → utils/animations.js} +3 -23
- package/core/utils/date-helper.js +238 -0
- package/core/utils/file-helper.js +327 -0
- package/core/utils/jsonl-helper.js +206 -0
- package/core/{project-capabilities.js → utils/project-capabilities.js} +21 -22
- package/core/utils/session-helper.js +277 -0
- package/core/{version.js → utils/version.js} +1 -1
- package/package.json +5 -12
- package/templates/agents/AGENTS.md +151 -99
- package/templates/analysis/analyze.md +84 -0
- package/templates/commands/analyze.md +37 -233
- package/templates/commands/bug.md +79 -0
- package/templates/commands/build.md +44 -0
- package/templates/commands/cleanup.md +24 -84
- package/templates/commands/design.md +20 -95
- package/templates/commands/done.md +17 -180
- package/templates/commands/feature.md +113 -0
- package/templates/commands/fix.md +58 -66
- package/templates/commands/git.md +35 -57
- package/templates/commands/help.md +18 -52
- package/templates/commands/idea.md +18 -34
- package/templates/commands/init.md +65 -257
- package/templates/commands/next.md +20 -60
- package/templates/commands/now.md +21 -23
- package/templates/commands/progress.md +40 -73
- package/templates/commands/recap.md +52 -75
- package/templates/commands/roadmap.md +30 -85
- package/templates/commands/ship.md +93 -126
- package/templates/commands/status.md +42 -0
- package/templates/commands/sync.md +19 -205
- package/templates/commands/task.md +19 -79
- package/templates/commands/test.md +25 -71
- package/templates/commands/workflow.md +20 -210
- package/core/agent-generator.js +0 -516
- package/core/analyzer.js +0 -600
- package/core/animations.js +0 -277
- package/core/git-integration.js +0 -401
- package/core/workflow-engine.js +0 -213
- package/core/workflow-prompts.js +0 -192
- package/core/workflow-rules.js +0 -147
- package/scripts/post-install.js +0 -121
- package/scripts/preuninstall.js +0 -94
- package/scripts/verify-installation.sh +0 -158
- package/templates/agents/be.template.md +0 -42
- package/templates/agents/data.template.md +0 -41
- package/templates/agents/devops.template.md +0 -41
- package/templates/agents/fe.template.md +0 -42
- package/templates/agents/mobile.template.md +0 -41
- package/templates/agents/pm.template.md +0 -84
- package/templates/agents/qa.template.md +0 -54
- package/templates/agents/scribe.template.md +0 -95
- package/templates/agents/security.template.md +0 -41
- package/templates/agents/ux.template.md +0 -49
- package/templates/commands/context.md +0 -105
- package/templates/commands/stuck.md +0 -48
- package/templates/examples/natural-language-examples.md +0 -532
- /package/core/{agent-detector.js → infrastructure/agent-detector.js} +0 -0
package/core/workflow-engine.js
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow Engine
|
|
3
|
-
* Orchestrates adaptive agent workflows based on project capabilities
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const fs = require('fs').promises
|
|
7
|
-
const path = require('path')
|
|
8
|
-
const capabilities = require('./project-capabilities')
|
|
9
|
-
const rules = require('./workflow-rules')
|
|
10
|
-
|
|
11
|
-
class WorkflowEngine {
|
|
12
|
-
/**
|
|
13
|
-
* Initialize workflow for task
|
|
14
|
-
* @param {string} task - Task description
|
|
15
|
-
* @param {string} type - Workflow type (ui, api, bug, refactor, feature)
|
|
16
|
-
* @param {string} dataPath - Project data path
|
|
17
|
-
* @returns {Promise<Object>} Workflow object
|
|
18
|
-
*/
|
|
19
|
-
async init(task, type, dataPath) {
|
|
20
|
-
// Detect project capabilities
|
|
21
|
-
const projectPath = path.dirname(path.dirname(dataPath))
|
|
22
|
-
const caps = await capabilities.detect(projectPath)
|
|
23
|
-
|
|
24
|
-
// Get base workflow
|
|
25
|
-
const base = rules[type] || rules.ui
|
|
26
|
-
|
|
27
|
-
// Map all steps - mark for prompting if capability missing
|
|
28
|
-
const steps = base.map((s, index) => ({
|
|
29
|
-
...s,
|
|
30
|
-
index,
|
|
31
|
-
status: 'pending',
|
|
32
|
-
skipped: false,
|
|
33
|
-
needsPrompt: !s.required && s.prompt && !caps[s.needs],
|
|
34
|
-
}))
|
|
35
|
-
|
|
36
|
-
// Track which capabilities are missing
|
|
37
|
-
const missingCapabilities = base
|
|
38
|
-
.filter(s => !s.required && s.needs && !caps[s.needs])
|
|
39
|
-
.map(s => s.needs)
|
|
40
|
-
|
|
41
|
-
const workflow = {
|
|
42
|
-
task,
|
|
43
|
-
type,
|
|
44
|
-
caps,
|
|
45
|
-
steps,
|
|
46
|
-
missingCapabilities,
|
|
47
|
-
current: 0,
|
|
48
|
-
active: true,
|
|
49
|
-
createdAt: new Date().toISOString(),
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
await this.save(workflow, dataPath)
|
|
53
|
-
return workflow
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Get current step info
|
|
58
|
-
*/
|
|
59
|
-
async getCurrent(dataPath) {
|
|
60
|
-
const wf = await this.load(dataPath)
|
|
61
|
-
if (!wf || !wf.active) return null
|
|
62
|
-
|
|
63
|
-
return wf.steps[wf.current]
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Advance to next step
|
|
68
|
-
*/
|
|
69
|
-
async next(dataPath) {
|
|
70
|
-
const wf = await this.load(dataPath)
|
|
71
|
-
if (!wf) return null
|
|
72
|
-
|
|
73
|
-
// Mark current step as completed
|
|
74
|
-
wf.steps[wf.current].status = 'completed'
|
|
75
|
-
wf.steps[wf.current].completedAt = new Date().toISOString()
|
|
76
|
-
|
|
77
|
-
// Move to next
|
|
78
|
-
wf.current++
|
|
79
|
-
|
|
80
|
-
// Check if workflow complete
|
|
81
|
-
if (wf.current >= wf.steps.length) {
|
|
82
|
-
wf.active = false
|
|
83
|
-
wf.completedAt = new Date().toISOString()
|
|
84
|
-
await this.save(wf, dataPath)
|
|
85
|
-
return null
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Mark next step as in progress
|
|
89
|
-
wf.steps[wf.current].status = 'in_progress'
|
|
90
|
-
wf.steps[wf.current].startedAt = new Date().toISOString()
|
|
91
|
-
|
|
92
|
-
await this.save(wf, dataPath)
|
|
93
|
-
return wf.steps[wf.current]
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Skip current step
|
|
98
|
-
*/
|
|
99
|
-
async skip(dataPath, reason = 'User skipped') {
|
|
100
|
-
const wf = await this.load(dataPath)
|
|
101
|
-
if (!wf) return null
|
|
102
|
-
|
|
103
|
-
wf.steps[wf.current].skipped = true
|
|
104
|
-
wf.steps[wf.current].status = 'skipped'
|
|
105
|
-
wf.steps[wf.current].skipReason = reason
|
|
106
|
-
wf.steps[wf.current].skippedAt = new Date().toISOString()
|
|
107
|
-
|
|
108
|
-
return await this.next(dataPath)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Insert installation step before current step
|
|
113
|
-
*/
|
|
114
|
-
async insertInstall(dataPath, installTask) {
|
|
115
|
-
const wf = await this.load(dataPath)
|
|
116
|
-
if (!wf) return null
|
|
117
|
-
|
|
118
|
-
const currentIndex = wf.current
|
|
119
|
-
|
|
120
|
-
// Insert install task at current position
|
|
121
|
-
wf.steps.splice(currentIndex, 0, {
|
|
122
|
-
...installTask,
|
|
123
|
-
index: currentIndex,
|
|
124
|
-
status: 'in_progress',
|
|
125
|
-
insertedAt: new Date().toISOString(),
|
|
126
|
-
})
|
|
127
|
-
|
|
128
|
-
// Reindex all subsequent steps
|
|
129
|
-
for (let i = currentIndex + 1; i < wf.steps.length; i++) {
|
|
130
|
-
wf.steps[i].index = i
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
await this.save(wf, dataPath)
|
|
134
|
-
return wf.steps[currentIndex]
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Classify task type from description
|
|
139
|
-
* @param {string} text - Task description
|
|
140
|
-
* @returns {string} Workflow type
|
|
141
|
-
*/
|
|
142
|
-
classify(text) {
|
|
143
|
-
const t = text.toLowerCase()
|
|
144
|
-
|
|
145
|
-
if (/button|form|modal|card|component|menu|nav|input/.test(t)) return 'ui'
|
|
146
|
-
if (/endpoint|api|service|route|controller/.test(t)) return 'api'
|
|
147
|
-
if (/bug|fix|error|issue|broken/.test(t)) return 'bug'
|
|
148
|
-
if (/refactor|improve|optimize|clean/.test(t)) return 'refactor'
|
|
149
|
-
if (/feature|functionality|module/.test(t)) return 'feature'
|
|
150
|
-
|
|
151
|
-
return 'ui' // Default
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Get workflow status
|
|
156
|
-
*/
|
|
157
|
-
async getStatus(dataPath) {
|
|
158
|
-
const wf = await this.load(dataPath)
|
|
159
|
-
if (!wf) return null
|
|
160
|
-
|
|
161
|
-
return {
|
|
162
|
-
task: wf.task,
|
|
163
|
-
type: wf.type,
|
|
164
|
-
active: wf.active,
|
|
165
|
-
current: wf.current,
|
|
166
|
-
total: wf.steps.length,
|
|
167
|
-
steps: wf.steps.map(s => ({
|
|
168
|
-
name: s.name,
|
|
169
|
-
status: s.status,
|
|
170
|
-
agent: s.agent,
|
|
171
|
-
})),
|
|
172
|
-
skipped: wf.skipped,
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Load workflow from file
|
|
178
|
-
*/
|
|
179
|
-
async load(dataPath) {
|
|
180
|
-
try {
|
|
181
|
-
const workflowPath = path.join(dataPath, 'workflow', 'state.json')
|
|
182
|
-
const content = await fs.readFile(workflowPath, 'utf8')
|
|
183
|
-
return JSON.parse(content)
|
|
184
|
-
} catch {
|
|
185
|
-
return null
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Save workflow to file
|
|
191
|
-
*/
|
|
192
|
-
async save(workflow, dataPath) {
|
|
193
|
-
const workflowDir = path.join(dataPath, 'workflow')
|
|
194
|
-
await fs.mkdir(workflowDir, { recursive: true })
|
|
195
|
-
|
|
196
|
-
const workflowPath = path.join(workflowDir, 'state.json')
|
|
197
|
-
await fs.writeFile(workflowPath, JSON.stringify(workflow, null, 2))
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Clear workflow
|
|
202
|
-
*/
|
|
203
|
-
async clear(dataPath) {
|
|
204
|
-
try {
|
|
205
|
-
const workflowPath = path.join(dataPath, 'workflow', 'state.json')
|
|
206
|
-
await fs.unlink(workflowPath)
|
|
207
|
-
} catch {
|
|
208
|
-
// Ignore if doesn't exist
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
module.exports = new WorkflowEngine()
|
package/core/workflow-prompts.js
DELETED
|
@@ -1,192 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interactive workflow prompts for missing capabilities
|
|
3
|
-
* Asks users before skipping or installing tools
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
class WorkflowPrompts {
|
|
7
|
-
/**
|
|
8
|
-
* Get recommendation based on detected stack
|
|
9
|
-
*/
|
|
10
|
-
getRecommendation(stepName, projectInfo = {}) {
|
|
11
|
-
const recommendations = {
|
|
12
|
-
design: {
|
|
13
|
-
tools: ['Figma plugin', 'Storybook', 'Design tokens'],
|
|
14
|
-
install: 'npx storybook@latest init',
|
|
15
|
-
reason: 'Component documentation and design system',
|
|
16
|
-
},
|
|
17
|
-
test: {
|
|
18
|
-
tools: this.getTestRecommendation(projectInfo),
|
|
19
|
-
install: this.getTestInstallCommand(projectInfo),
|
|
20
|
-
reason: 'Quality assurance and regression prevention',
|
|
21
|
-
},
|
|
22
|
-
docs: {
|
|
23
|
-
tools: ['JSDoc', 'TypeDoc', 'Docusaurus'],
|
|
24
|
-
install: 'npm install -D jsdoc',
|
|
25
|
-
reason: 'API documentation and code examples',
|
|
26
|
-
},
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return recommendations[stepName] || null
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Detect test framework based on project stack
|
|
34
|
-
*/
|
|
35
|
-
getTestRecommendation(projectInfo) {
|
|
36
|
-
const { framework, typescript } = projectInfo
|
|
37
|
-
|
|
38
|
-
if (framework === 'react') {
|
|
39
|
-
return typescript
|
|
40
|
-
? ['Vitest + Testing Library', 'Jest + Testing Library']
|
|
41
|
-
: ['Jest + Testing Library', 'Vitest']
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (framework === 'vue') {
|
|
45
|
-
return ['Vitest', '@vue/test-utils']
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (framework === 'angular') {
|
|
49
|
-
return ['Jasmine + Karma', 'Jest']
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Default Node.js
|
|
53
|
-
return typescript
|
|
54
|
-
? ['Vitest', 'Jest with ts-jest']
|
|
55
|
-
: ['Jest', 'Vitest', 'Mocha + Chai']
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Get install command based on stack
|
|
60
|
-
*/
|
|
61
|
-
getTestInstallCommand(projectInfo) {
|
|
62
|
-
const { framework, typescript } = projectInfo
|
|
63
|
-
|
|
64
|
-
if (framework === 'react') {
|
|
65
|
-
return typescript
|
|
66
|
-
? 'npm install -D vitest @testing-library/react @testing-library/jest-dom'
|
|
67
|
-
: 'npm install -D jest @testing-library/react @testing-library/jest-dom'
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (framework === 'vue') {
|
|
71
|
-
return 'npm install -D vitest @vue/test-utils'
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
if (framework === 'angular') {
|
|
75
|
-
return 'npm install -D jest @types/jest ts-jest'
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return typescript
|
|
79
|
-
? 'npm install -D vitest'
|
|
80
|
-
: 'npm install -D jest'
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Detect project stack from package.json
|
|
85
|
-
*/
|
|
86
|
-
async detectStack(projectPath) {
|
|
87
|
-
const fs = require('fs').promises
|
|
88
|
-
const path = require('path')
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
const pkgPath = path.join(projectPath, 'package.json')
|
|
92
|
-
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf8'))
|
|
93
|
-
|
|
94
|
-
const deps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
95
|
-
|
|
96
|
-
return {
|
|
97
|
-
framework: this.detectFramework(deps),
|
|
98
|
-
typescript: 'typescript' in deps,
|
|
99
|
-
bundler: this.detectBundler(deps),
|
|
100
|
-
runtime: this.detectRuntime(deps),
|
|
101
|
-
}
|
|
102
|
-
} catch {
|
|
103
|
-
return { framework: 'node', typescript: false }
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
detectFramework(deps) {
|
|
108
|
-
if ('react' in deps) return 'react'
|
|
109
|
-
if ('vue' in deps) return 'vue'
|
|
110
|
-
if ('@angular/core' in deps) return 'angular'
|
|
111
|
-
if ('next' in deps) return 'next'
|
|
112
|
-
if ('nuxt' in deps) return 'nuxt'
|
|
113
|
-
return 'node'
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
detectBundler(deps) {
|
|
117
|
-
if ('vite' in deps) return 'vite'
|
|
118
|
-
if ('webpack' in deps) return 'webpack'
|
|
119
|
-
if ('esbuild' in deps) return 'esbuild'
|
|
120
|
-
return null
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
detectRuntime(deps) {
|
|
124
|
-
if ('bun' in deps) return 'bun'
|
|
125
|
-
if ('deno' in deps) return 'deno'
|
|
126
|
-
return 'node'
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Build prompt message for missing capability
|
|
131
|
-
*/
|
|
132
|
-
async buildPrompt(step, capabilities, projectPath) {
|
|
133
|
-
const stack = await this.detectStack(projectPath)
|
|
134
|
-
const rec = this.getRecommendation(step.needs, stack)
|
|
135
|
-
|
|
136
|
-
if (!rec) {
|
|
137
|
-
return {
|
|
138
|
-
message: `⚠️ Step "${step.name}" requires ${step.needs} capability\n\nOptions:\n1. Skip this step\n2. Continue without ${step.needs}\n3. Pause workflow`,
|
|
139
|
-
options: ['skip', 'continue', 'pause'],
|
|
140
|
-
recommendation: null,
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
const toolsList = rec.tools.join(', ')
|
|
145
|
-
|
|
146
|
-
return {
|
|
147
|
-
message: `⚠️ Missing ${step.needs} capability for "${step.name}" step\n\n` +
|
|
148
|
-
`📋 Recommended: ${toolsList}\n` +
|
|
149
|
-
`💡 Reason: ${rec.reason}\n\n` +
|
|
150
|
-
'Options:\n' +
|
|
151
|
-
`1. Install recommended (${rec.install})\n` +
|
|
152
|
-
'2. Skip this step\n' +
|
|
153
|
-
`3. Continue without ${step.needs}\n` +
|
|
154
|
-
'4. Pause workflow',
|
|
155
|
-
options: ['install', 'skip', 'continue', 'pause'],
|
|
156
|
-
recommendation: rec,
|
|
157
|
-
stack,
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Parse user choice from response
|
|
163
|
-
*/
|
|
164
|
-
parseChoice(response) {
|
|
165
|
-
const lower = response.toLowerCase().trim()
|
|
166
|
-
|
|
167
|
-
if (lower.match(/^(1|install|yes|y)/)) return 'install'
|
|
168
|
-
if (lower.match(/^(2|skip|s)/)) return 'skip'
|
|
169
|
-
if (lower.match(/^(3|continue|c)/)) return 'continue'
|
|
170
|
-
if (lower.match(/^(4|pause|p)/)) return 'pause'
|
|
171
|
-
|
|
172
|
-
return 'skip' // Default to skip if unclear
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Create installation task for workflow
|
|
177
|
-
*/
|
|
178
|
-
createInstallTask(step, recommendation) {
|
|
179
|
-
return {
|
|
180
|
-
name: `install-${step.needs}`,
|
|
181
|
-
agent: 'devops',
|
|
182
|
-
action: `Install ${step.needs}: ${recommendation.install}`,
|
|
183
|
-
required: true,
|
|
184
|
-
type: 'install',
|
|
185
|
-
install: recommendation.install,
|
|
186
|
-
capability: step.needs,
|
|
187
|
-
reason: recommendation.reason,
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
module.exports = new WorkflowPrompts()
|
package/core/workflow-rules.js
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workflow Rules
|
|
3
|
-
* Defines workflows by task type with capability requirements
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
module.exports = {
|
|
7
|
-
// UI Component workflow
|
|
8
|
-
ui: [
|
|
9
|
-
{
|
|
10
|
-
name: 'design',
|
|
11
|
-
agent: 'frontend',
|
|
12
|
-
action: 'Create component design',
|
|
13
|
-
required: false,
|
|
14
|
-
needs: 'design',
|
|
15
|
-
prompt: true,
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
name: 'dev',
|
|
19
|
-
agent: 'frontend',
|
|
20
|
-
action: 'Implement component',
|
|
21
|
-
required: true,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: 'test',
|
|
25
|
-
agent: 'qa',
|
|
26
|
-
action: 'Create tests',
|
|
27
|
-
required: false,
|
|
28
|
-
needs: 'test',
|
|
29
|
-
retry: 3,
|
|
30
|
-
prompt: true,
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
name: 'docs',
|
|
34
|
-
agent: 'scribe',
|
|
35
|
-
action: 'Document component',
|
|
36
|
-
required: false,
|
|
37
|
-
needs: 'docs',
|
|
38
|
-
prompt: true,
|
|
39
|
-
},
|
|
40
|
-
],
|
|
41
|
-
|
|
42
|
-
// API Endpoint workflow
|
|
43
|
-
api: [
|
|
44
|
-
{
|
|
45
|
-
name: 'dev',
|
|
46
|
-
agent: 'backend',
|
|
47
|
-
action: 'Implement endpoint',
|
|
48
|
-
required: true,
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
name: 'test',
|
|
52
|
-
agent: 'qa',
|
|
53
|
-
action: 'Create API tests',
|
|
54
|
-
required: false,
|
|
55
|
-
needs: 'test',
|
|
56
|
-
retry: 3,
|
|
57
|
-
prompt: true,
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: 'docs',
|
|
61
|
-
agent: 'scribe',
|
|
62
|
-
action: 'Document API',
|
|
63
|
-
required: false,
|
|
64
|
-
needs: 'docs',
|
|
65
|
-
prompt: true,
|
|
66
|
-
},
|
|
67
|
-
],
|
|
68
|
-
|
|
69
|
-
// Bug Fix workflow
|
|
70
|
-
bug: [
|
|
71
|
-
{
|
|
72
|
-
name: 'analyze',
|
|
73
|
-
agent: 'analyzer',
|
|
74
|
-
action: 'Analyze bug',
|
|
75
|
-
required: true,
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
name: 'fix',
|
|
79
|
-
agent: 'auto',
|
|
80
|
-
action: 'Fix bug',
|
|
81
|
-
required: true,
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
name: 'test',
|
|
85
|
-
agent: 'qa',
|
|
86
|
-
action: 'Verify fix',
|
|
87
|
-
required: false,
|
|
88
|
-
needs: 'test',
|
|
89
|
-
retry: 3,
|
|
90
|
-
prompt: true,
|
|
91
|
-
},
|
|
92
|
-
],
|
|
93
|
-
|
|
94
|
-
// Refactor workflow
|
|
95
|
-
refactor: [
|
|
96
|
-
{
|
|
97
|
-
name: 'refactor',
|
|
98
|
-
agent: 'refactorer',
|
|
99
|
-
action: 'Refactor code',
|
|
100
|
-
required: true,
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
name: 'test',
|
|
104
|
-
agent: 'qa',
|
|
105
|
-
action: 'Verify refactor',
|
|
106
|
-
required: false,
|
|
107
|
-
needs: 'test',
|
|
108
|
-
retry: 3,
|
|
109
|
-
prompt: true,
|
|
110
|
-
},
|
|
111
|
-
],
|
|
112
|
-
|
|
113
|
-
// Feature workflow (complete feature)
|
|
114
|
-
feature: [
|
|
115
|
-
{
|
|
116
|
-
name: 'design',
|
|
117
|
-
agent: 'architect',
|
|
118
|
-
action: 'Design feature',
|
|
119
|
-
required: false,
|
|
120
|
-
needs: 'design',
|
|
121
|
-
prompt: true,
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
name: 'dev',
|
|
125
|
-
agent: 'auto',
|
|
126
|
-
action: 'Implement feature',
|
|
127
|
-
required: true,
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'test',
|
|
131
|
-
agent: 'qa',
|
|
132
|
-
action: 'Test feature',
|
|
133
|
-
required: false,
|
|
134
|
-
needs: 'test',
|
|
135
|
-
retry: 3,
|
|
136
|
-
prompt: true,
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: 'docs',
|
|
140
|
-
agent: 'scribe',
|
|
141
|
-
action: 'Document feature',
|
|
142
|
-
required: false,
|
|
143
|
-
needs: 'docs',
|
|
144
|
-
prompt: true,
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
}
|
package/scripts/post-install.js
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Post-Install Script
|
|
5
|
-
*
|
|
6
|
-
* Runs automatically after `npm install -g prjct-cli` or `npm update -g prjct-cli`.
|
|
7
|
-
* Auto-updates slash commands in all previously configured editors.
|
|
8
|
-
*
|
|
9
|
-
* Flow:
|
|
10
|
-
* 1. Check if running as global install
|
|
11
|
-
* 2. Read tracked editors from ~/.prjct-cli/config/installed-editors.json
|
|
12
|
-
* 3. If config exists and version changed, force-update commands in tracked editors
|
|
13
|
-
* 4. Update version in config
|
|
14
|
-
*
|
|
15
|
-
* @version 0.4.4
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
const path = require('path')
|
|
19
|
-
const chalk = require('chalk')
|
|
20
|
-
const { execSync } = require('child_process')
|
|
21
|
-
|
|
22
|
-
async function main() {
|
|
23
|
-
try {
|
|
24
|
-
// Get current package version
|
|
25
|
-
const packageJson = require('../package.json')
|
|
26
|
-
const currentVersion = packageJson.version
|
|
27
|
-
|
|
28
|
-
// Check if this is a global installation
|
|
29
|
-
const isGlobal = await checkIfGlobalInstall()
|
|
30
|
-
|
|
31
|
-
if (!isGlobal) {
|
|
32
|
-
// Skip post-install for local/dev installations
|
|
33
|
-
if (process.env.DEBUG) {
|
|
34
|
-
console.log(chalk.gray('[post-install] Skipping - not a global install'))
|
|
35
|
-
}
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Load editors config
|
|
40
|
-
const editorsConfig = require('../core/editors-config')
|
|
41
|
-
const configExists = await editorsConfig.configExists()
|
|
42
|
-
|
|
43
|
-
if (!configExists) {
|
|
44
|
-
// First-time install - show welcome message
|
|
45
|
-
console.log(chalk.cyan('\n✨ prjct-cli installed successfully!\n'))
|
|
46
|
-
console.log(chalk.gray('Run: ') + chalk.cyan('prjct start') + chalk.gray(' to get started\n'))
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Check if version has changed
|
|
51
|
-
const versionChanged = await editorsConfig.hasVersionChanged(currentVersion)
|
|
52
|
-
|
|
53
|
-
if (!versionChanged) {
|
|
54
|
-
// Same version, no update needed
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Get tracked editors
|
|
59
|
-
const trackedEditors = await editorsConfig.getTrackedEditors()
|
|
60
|
-
|
|
61
|
-
if (trackedEditors.length === 0) {
|
|
62
|
-
// No editors tracked yet
|
|
63
|
-
return
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
console.log(chalk.cyan('\n🔄 Updating prjct commands in configured editors...\n'))
|
|
67
|
-
|
|
68
|
-
// Load command installer
|
|
69
|
-
const commandInstaller = require('../core/command-installer')
|
|
70
|
-
|
|
71
|
-
// Force-update commands in all tracked editors
|
|
72
|
-
const results = await commandInstaller.installToSelected(trackedEditors, true)
|
|
73
|
-
|
|
74
|
-
if (results.success) {
|
|
75
|
-
console.log(chalk.green(`✅ Updated commands in: ${results.editors.join(', ')}`))
|
|
76
|
-
console.log(chalk.gray(` Commands updated: ${results.totalUpdated}`))
|
|
77
|
-
} else {
|
|
78
|
-
console.log(chalk.yellow('⚠️ Some editors could not be updated'))
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Update version in config
|
|
82
|
-
await editorsConfig.updateVersion(currentVersion)
|
|
83
|
-
|
|
84
|
-
console.log(chalk.cyan(`\n✨ prjct-cli ${currentVersion} is ready!\n`))
|
|
85
|
-
|
|
86
|
-
} catch (error) {
|
|
87
|
-
// Silently fail - don't block npm install
|
|
88
|
-
// Only log if explicitly debugging
|
|
89
|
-
if (process.env.DEBUG) {
|
|
90
|
-
console.error(chalk.red('[post-install] Error:'), error.message)
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Check if package is being installed globally
|
|
97
|
-
* @returns {Promise<boolean>} True if global install
|
|
98
|
-
*/
|
|
99
|
-
async function checkIfGlobalInstall() {
|
|
100
|
-
try {
|
|
101
|
-
// Get npm global root directory
|
|
102
|
-
const globalRoot = execSync('npm root -g', { encoding: 'utf-8' }).trim()
|
|
103
|
-
|
|
104
|
-
// Get current package directory
|
|
105
|
-
const currentDir = path.resolve(__dirname, '..')
|
|
106
|
-
|
|
107
|
-
// Check if current directory is under global node_modules
|
|
108
|
-
return currentDir.startsWith(globalRoot)
|
|
109
|
-
} catch {
|
|
110
|
-
return false
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Run main function
|
|
115
|
-
main().catch(error => {
|
|
116
|
-
// Silently fail - don't block npm install
|
|
117
|
-
if (process.env.DEBUG) {
|
|
118
|
-
console.error('[post-install] Fatal error:', error)
|
|
119
|
-
}
|
|
120
|
-
process.exit(0) // Exit with success to not block npm install
|
|
121
|
-
})
|