prjct-cli 0.35.3 → 0.35.4
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/core/commands/analysis.ts +58 -32
- package/core/commands/command-data.ts +11 -50
- package/core/commands/commands.ts +18 -21
- package/core/commands/context.ts +238 -0
- package/core/commands/register.ts +7 -5
- package/core/commands/setup.ts +1 -17
- package/core/index.ts +2 -4
- package/core/services/index.ts +2 -0
- package/core/services/sync-service.ts +1080 -0
- package/core/types/commands.ts +0 -12
- package/core/types/index.ts +0 -1
- package/dist/bin/prjct.mjs +1215 -307
- package/package.json +2 -8
- package/templates/agentic/agent-routing.md +22 -88
- package/templates/agentic/agents/uxui.md +42 -197
- package/templates/agentic/context-filtering.md +14 -56
- package/templates/agentic/orchestrator.md +26 -302
- package/templates/agentic/skill-integration.md +37 -289
- package/templates/agentic/subagent-generation.md +31 -104
- package/templates/agentic/task-fragmentation.md +39 -273
- package/templates/agents/AGENTS.md +32 -188
- package/templates/commands/bug.md +22 -520
- package/templates/commands/dash.md +26 -161
- package/templates/commands/done.md +19 -250
- package/templates/commands/enrich.md +21 -732
- package/templates/commands/idea.md +18 -160
- package/templates/commands/init.md +20 -209
- package/templates/commands/merge.md +21 -185
- package/templates/commands/next.md +21 -103
- package/templates/commands/pause.md +21 -272
- package/templates/commands/resume.md +18 -411
- package/templates/commands/setup.md +0 -1
- package/templates/commands/ship.md +30 -627
- package/templates/commands/sync.md +11 -1448
- package/templates/commands/task.md +17 -439
- package/templates/commands/test.md +30 -259
- package/CLAUDE.md +0 -211
- package/packages/shared/package.json +0 -29
- package/packages/shared/src/index.ts +0 -10
- package/packages/shared/src/schemas.ts +0 -124
- package/packages/shared/src/types.ts +0 -187
- package/packages/shared/src/unified.ts +0 -174
- package/packages/shared/src/utils.ts +0 -148
- package/packages/shared/tsconfig.json +0 -18
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
import analyzer from '../domain/analyzer'
|
|
17
17
|
import { generateContext } from '../context/generator'
|
|
18
18
|
import commandInstaller from '../infrastructure/command-installer'
|
|
19
|
+
import { syncService } from '../services'
|
|
19
20
|
|
|
20
21
|
export class AnalysisCommands extends PrjctCommandsBase {
|
|
21
22
|
/**
|
|
@@ -189,58 +190,83 @@ export class AnalysisCommands extends PrjctCommandsBase {
|
|
|
189
190
|
}
|
|
190
191
|
|
|
191
192
|
/**
|
|
192
|
-
* /p:sync -
|
|
193
|
+
* /p:sync - Comprehensive project sync
|
|
193
194
|
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
195
|
+
* Uses syncService to do ALL operations in one TypeScript execution:
|
|
196
|
+
* - Git analysis
|
|
197
|
+
* - Project stats
|
|
198
|
+
* - Agent generation
|
|
199
|
+
* - Context file generation
|
|
200
|
+
* - Skill configuration
|
|
201
|
+
* - State updates
|
|
202
|
+
*
|
|
203
|
+
* This eliminates the need for Claude to make 50+ individual tool calls.
|
|
197
204
|
*/
|
|
198
205
|
async sync(projectPath: string = process.cwd()): Promise<CommandResult> {
|
|
199
206
|
try {
|
|
200
207
|
const initResult = await this.ensureProjectInit(projectPath)
|
|
201
208
|
if (!initResult.success) return initResult
|
|
202
209
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
console.log('🔄 Syncing project state...\n')
|
|
210
|
+
console.log('🔄 Syncing project...\n')
|
|
206
211
|
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
const analysisResult = await this.analyze({}, projectPath)
|
|
212
|
+
// Use syncService to do EVERYTHING in one call
|
|
213
|
+
const result = await syncService.sync(projectPath)
|
|
210
214
|
|
|
211
|
-
if (!
|
|
212
|
-
console.error('❌
|
|
213
|
-
return
|
|
215
|
+
if (!result.success) {
|
|
216
|
+
console.error('❌ Sync failed:', result.error)
|
|
217
|
+
return { success: false, error: result.error }
|
|
214
218
|
}
|
|
215
219
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// 2. Generate CLAUDE.md with RAW DATA (no processing)
|
|
219
|
-
// Claude will read this and decide what to do
|
|
220
|
-
await generateContext(projectId!, projectPath)
|
|
221
|
-
|
|
222
|
-
// 3. Update global config
|
|
220
|
+
// Update global config
|
|
223
221
|
const globalConfigResult = await commandInstaller.installGlobalConfig()
|
|
224
222
|
if (globalConfigResult.success) {
|
|
225
223
|
console.log('📝 Updated ~/.claude/CLAUDE.md')
|
|
226
224
|
}
|
|
227
225
|
|
|
228
|
-
//
|
|
229
|
-
|
|
230
|
-
timestamp: dateHelper.getTimestamp(),
|
|
231
|
-
projectId,
|
|
232
|
-
})
|
|
226
|
+
// Format output
|
|
227
|
+
console.log(`🔄 Project synced to prjct v${result.cliVersion}\n`)
|
|
233
228
|
|
|
234
|
-
console.log('
|
|
235
|
-
console.log(
|
|
236
|
-
console.log(
|
|
237
|
-
console.log(
|
|
238
|
-
console.log(
|
|
239
|
-
|
|
240
|
-
console.log('
|
|
229
|
+
console.log('📊 Project Stats')
|
|
230
|
+
console.log(`├── Files: ~${result.stats.fileCount}`)
|
|
231
|
+
console.log(`├── Commits: ${result.git.commits}`)
|
|
232
|
+
console.log(`├── Version: ${result.stats.version}`)
|
|
233
|
+
console.log(`└── Stack: ${result.stats.ecosystem}\n`)
|
|
234
|
+
|
|
235
|
+
console.log('🌿 Git Status')
|
|
236
|
+
console.log(`├── Branch: ${result.git.branch}`)
|
|
237
|
+
console.log(`├── Uncommitted: ${result.git.hasChanges ? 'Yes' : 'Clean'}`)
|
|
238
|
+
console.log(`└── Recent: ${result.git.weeklyCommits} commits this week\n`)
|
|
239
|
+
|
|
240
|
+
console.log('📁 Context Updated')
|
|
241
|
+
for (const file of result.contextFiles) {
|
|
242
|
+
console.log(`├── ${file}`)
|
|
243
|
+
}
|
|
244
|
+
console.log('')
|
|
245
|
+
|
|
246
|
+
const workflowAgents = result.agents.filter(a => a.type === 'workflow').map(a => a.name)
|
|
247
|
+
const domainAgents = result.agents.filter(a => a.type === 'domain').map(a => a.name)
|
|
248
|
+
|
|
249
|
+
console.log(`🤖 Agents Regenerated (${result.agents.length})`)
|
|
250
|
+
console.log(`├── Workflow: ${workflowAgents.join(', ')}`)
|
|
251
|
+
console.log(`└── Domain: ${domainAgents.join(', ') || 'none'}\n`)
|
|
252
|
+
|
|
253
|
+
if (result.skills.length > 0) {
|
|
254
|
+
console.log('📦 Skills Configured')
|
|
255
|
+
for (const skill of result.skills) {
|
|
256
|
+
console.log(`├── ${skill.agent}.md → ${skill.skill}`)
|
|
257
|
+
}
|
|
258
|
+
console.log('')
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (result.git.hasChanges) {
|
|
262
|
+
console.log('⚠️ You have uncommitted changes\n')
|
|
263
|
+
} else {
|
|
264
|
+
console.log('✨ Repository is clean!\n')
|
|
265
|
+
}
|
|
241
266
|
|
|
242
267
|
return {
|
|
243
268
|
success: true,
|
|
269
|
+
data: result,
|
|
244
270
|
}
|
|
245
271
|
} catch (error) {
|
|
246
272
|
console.error('❌ Error:', (error as Error).message)
|
|
@@ -62,17 +62,6 @@ export const COMMANDS: CommandMeta[] = [
|
|
|
62
62
|
requiresProject: true,
|
|
63
63
|
features: ['Agentic type classification', '7-phase workflow', 'Git branch management', 'Task breakdown'],
|
|
64
64
|
},
|
|
65
|
-
{
|
|
66
|
-
name: 'feature',
|
|
67
|
-
group: 'core',
|
|
68
|
-
description: 'DEPRECATED - Use /p:task instead',
|
|
69
|
-
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
70
|
-
params: '<description>',
|
|
71
|
-
implemented: true,
|
|
72
|
-
hasTemplate: true,
|
|
73
|
-
requiresProject: true,
|
|
74
|
-
deprecated: true,
|
|
75
|
-
},
|
|
76
65
|
{
|
|
77
66
|
name: 'spec',
|
|
78
67
|
group: 'core',
|
|
@@ -83,28 +72,6 @@ export const COMMANDS: CommandMeta[] = [
|
|
|
83
72
|
hasTemplate: true,
|
|
84
73
|
requiresProject: true,
|
|
85
74
|
},
|
|
86
|
-
{
|
|
87
|
-
name: 'now',
|
|
88
|
-
group: 'core',
|
|
89
|
-
description: 'DEPRECATED - Use /p:task instead',
|
|
90
|
-
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
91
|
-
params: '[task]',
|
|
92
|
-
implemented: true,
|
|
93
|
-
hasTemplate: true,
|
|
94
|
-
requiresProject: true,
|
|
95
|
-
deprecated: true,
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
name: 'work',
|
|
99
|
-
group: 'core',
|
|
100
|
-
description: 'DEPRECATED - Use /p:task instead',
|
|
101
|
-
usage: { claude: '/p:task "<description>"', terminal: 'prjct task "<description>"' },
|
|
102
|
-
params: '[task]',
|
|
103
|
-
implemented: true,
|
|
104
|
-
hasTemplate: true,
|
|
105
|
-
requiresProject: true,
|
|
106
|
-
deprecated: true,
|
|
107
|
-
},
|
|
108
75
|
{
|
|
109
76
|
name: 'pause',
|
|
110
77
|
group: 'core',
|
|
@@ -328,16 +295,6 @@ export const COMMANDS: CommandMeta[] = [
|
|
|
328
295
|
hasTemplate: true,
|
|
329
296
|
requiresProject: true,
|
|
330
297
|
},
|
|
331
|
-
{
|
|
332
|
-
name: 'migrate-all',
|
|
333
|
-
group: 'setup',
|
|
334
|
-
description: 'Migrate all legacy projects to UUID format',
|
|
335
|
-
usage: { claude: '/p:migrate-all', terminal: 'prjct migrate-all' },
|
|
336
|
-
params: '[--deep-scan] [--dry-run]',
|
|
337
|
-
implemented: true,
|
|
338
|
-
hasTemplate: true,
|
|
339
|
-
requiresProject: false,
|
|
340
|
-
},
|
|
341
298
|
{
|
|
342
299
|
name: 'auth',
|
|
343
300
|
group: 'setup',
|
|
@@ -348,12 +305,16 @@ export const COMMANDS: CommandMeta[] = [
|
|
|
348
305
|
hasTemplate: true,
|
|
349
306
|
requiresProject: false,
|
|
350
307
|
},
|
|
308
|
+
{
|
|
309
|
+
name: 'context',
|
|
310
|
+
group: 'setup',
|
|
311
|
+
description: 'Get project context as JSON for Claude templates',
|
|
312
|
+
usage: { claude: null, terminal: 'prjct context <command> [args]' },
|
|
313
|
+
params: '<command> [args]',
|
|
314
|
+
implemented: true,
|
|
315
|
+
hasTemplate: false,
|
|
316
|
+
requiresProject: true,
|
|
317
|
+
features: ['Returns JSON with project context', 'Runs orchestrator', 'Loads agents and skills'],
|
|
318
|
+
},
|
|
351
319
|
]
|
|
352
320
|
|
|
353
|
-
// Legacy compatibility - category field mapping
|
|
354
|
-
export function getCommandsWithCategory(): Array<CommandMeta & { category: string }> {
|
|
355
|
-
return COMMANDS.map(cmd => ({
|
|
356
|
-
...cmd,
|
|
357
|
-
category: cmd.group, // Map group to category for backward compat
|
|
358
|
-
}))
|
|
359
|
-
}
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* MD-First Architecture - All state in Markdown files.
|
|
5
5
|
*
|
|
6
|
-
* COMMANDS
|
|
7
|
-
* - Workflow
|
|
8
|
-
* - Planning
|
|
9
|
-
* - Shipping
|
|
10
|
-
* - Analytics
|
|
11
|
-
* - Maintenance
|
|
12
|
-
* - Analysis
|
|
13
|
-
* - Setup
|
|
6
|
+
* COMMANDS:
|
|
7
|
+
* - Workflow: done, next, pause, resume
|
|
8
|
+
* - Planning: init, bug, idea, spec
|
|
9
|
+
* - Shipping: ship
|
|
10
|
+
* - Analytics: dash, help
|
|
11
|
+
* - Maintenance: cleanup, design, recover, undo, redo, history
|
|
12
|
+
* - Analysis: analyze, sync
|
|
13
|
+
* - Setup: start, setup
|
|
14
|
+
* - Context: context
|
|
14
15
|
*/
|
|
15
16
|
|
|
16
17
|
import { WorkflowCommands } from './workflow'
|
|
@@ -20,6 +21,7 @@ import { AnalyticsCommands } from './analytics'
|
|
|
20
21
|
import { MaintenanceCommands } from './maintenance'
|
|
21
22
|
import { AnalysisCommands } from './analysis'
|
|
22
23
|
import { SetupCommands } from './setup'
|
|
24
|
+
import { ContextCommands } from './context'
|
|
23
25
|
|
|
24
26
|
import type {
|
|
25
27
|
CommandResult,
|
|
@@ -28,7 +30,6 @@ import type {
|
|
|
28
30
|
DesignOptions,
|
|
29
31
|
CleanupOptions,
|
|
30
32
|
SetupOptions,
|
|
31
|
-
MigrateOptions,
|
|
32
33
|
AnalyzeOptions
|
|
33
34
|
} from '../types'
|
|
34
35
|
|
|
@@ -45,6 +46,7 @@ class PrjctCommands {
|
|
|
45
46
|
private maintenance: MaintenanceCommands
|
|
46
47
|
private analysis: AnalysisCommands
|
|
47
48
|
private setupCmds: SetupCommands
|
|
49
|
+
private contextCmds: ContextCommands
|
|
48
50
|
|
|
49
51
|
// Shared state
|
|
50
52
|
agent: unknown
|
|
@@ -60,6 +62,7 @@ class PrjctCommands {
|
|
|
60
62
|
this.maintenance = new MaintenanceCommands()
|
|
61
63
|
this.analysis = new AnalysisCommands()
|
|
62
64
|
this.setupCmds = new SetupCommands()
|
|
65
|
+
this.contextCmds = new ContextCommands()
|
|
63
66
|
|
|
64
67
|
this.agent = null
|
|
65
68
|
this.agentInfo = null
|
|
@@ -69,10 +72,6 @@ class PrjctCommands {
|
|
|
69
72
|
|
|
70
73
|
// ========== Workflow Commands ==========
|
|
71
74
|
|
|
72
|
-
async work(task: string | null = null, projectPath: string = process.cwd()): Promise<CommandResult> {
|
|
73
|
-
return this.workflow.now(task, projectPath)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
75
|
async done(projectPath: string = process.cwd()): Promise<CommandResult> {
|
|
77
76
|
return this.workflow.done(projectPath)
|
|
78
77
|
}
|
|
@@ -95,10 +94,6 @@ class PrjctCommands {
|
|
|
95
94
|
return this.planning.init(idea, projectPath)
|
|
96
95
|
}
|
|
97
96
|
|
|
98
|
-
async feature(description: string, projectPath: string = process.cwd()): Promise<CommandResult> {
|
|
99
|
-
return this.planning.feature(description, projectPath)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
97
|
async bug(description: string, projectPath: string = process.cwd()): Promise<CommandResult> {
|
|
103
98
|
return this.planning.bug(description, projectPath)
|
|
104
99
|
}
|
|
@@ -163,6 +158,12 @@ class PrjctCommands {
|
|
|
163
158
|
return this.analysis.sync(projectPath)
|
|
164
159
|
}
|
|
165
160
|
|
|
161
|
+
// ========== Context Commands ==========
|
|
162
|
+
|
|
163
|
+
async context(input: string | null = null, projectPath: string = process.cwd()): Promise<CommandResult> {
|
|
164
|
+
return this.contextCmds.context(input, projectPath)
|
|
165
|
+
}
|
|
166
|
+
|
|
166
167
|
// ========== Setup Commands ==========
|
|
167
168
|
|
|
168
169
|
async start(): Promise<CommandResult> {
|
|
@@ -173,10 +174,6 @@ class PrjctCommands {
|
|
|
173
174
|
return this.setupCmds.setup(options)
|
|
174
175
|
}
|
|
175
176
|
|
|
176
|
-
async migrateAll(options: MigrateOptions = {}): Promise<CommandResult> {
|
|
177
|
-
return this.setupCmds.migrateAll(options)
|
|
178
|
-
}
|
|
179
|
-
|
|
180
177
|
async installStatusLine(): Promise<{ success: boolean; error?: string }> {
|
|
181
178
|
return this.setupCmds.installStatusLine()
|
|
182
179
|
}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Commands - Exposes orchestrator context to Claude
|
|
3
|
+
*
|
|
4
|
+
* The `context` command runs the orchestrator and returns JSON with everything
|
|
5
|
+
* Claude needs to execute workflows:
|
|
6
|
+
* - projectId and globalPath for file operations
|
|
7
|
+
* - detected domains from task description
|
|
8
|
+
* - loaded agents with file paths and previews
|
|
9
|
+
* - current task state (if any)
|
|
10
|
+
* - repo analysis data
|
|
11
|
+
*
|
|
12
|
+
* This bridges the gap between TypeScript orchestration and Claude Code templates.
|
|
13
|
+
*
|
|
14
|
+
* @module commands/context
|
|
15
|
+
* @version 1.0.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import fs from 'fs/promises'
|
|
19
|
+
import path from 'path'
|
|
20
|
+
import configManager from '../infrastructure/config-manager'
|
|
21
|
+
import pathManager from '../infrastructure/path-manager'
|
|
22
|
+
import { stateStorage } from '../storage'
|
|
23
|
+
import orchestratorExecutor from '../agentic/orchestrator-executor'
|
|
24
|
+
import { isNotFoundError } from '../types/fs'
|
|
25
|
+
import type { CommandResult } from '../types'
|
|
26
|
+
|
|
27
|
+
// =============================================================================
|
|
28
|
+
// Types
|
|
29
|
+
// =============================================================================
|
|
30
|
+
|
|
31
|
+
export interface ContextOutput {
|
|
32
|
+
projectId: string
|
|
33
|
+
globalPath: string
|
|
34
|
+
currentTask: {
|
|
35
|
+
id: string
|
|
36
|
+
description: string
|
|
37
|
+
startedAt: string
|
|
38
|
+
subtasks?: Array<{
|
|
39
|
+
id: string
|
|
40
|
+
description: string
|
|
41
|
+
status: string
|
|
42
|
+
domain: string
|
|
43
|
+
}>
|
|
44
|
+
currentSubtaskIndex?: number
|
|
45
|
+
} | null
|
|
46
|
+
domains: string[]
|
|
47
|
+
primaryDomain: string | null
|
|
48
|
+
agents: Array<{
|
|
49
|
+
name: string
|
|
50
|
+
domain: string
|
|
51
|
+
filePath: string
|
|
52
|
+
skills: string[]
|
|
53
|
+
preview: string
|
|
54
|
+
}>
|
|
55
|
+
subtasks: Array<{
|
|
56
|
+
id: string
|
|
57
|
+
description: string
|
|
58
|
+
domain: string
|
|
59
|
+
agent: string
|
|
60
|
+
status: string
|
|
61
|
+
order: number
|
|
62
|
+
}> | null
|
|
63
|
+
repoAnalysis: {
|
|
64
|
+
ecosystem: string
|
|
65
|
+
frameworks: string[]
|
|
66
|
+
hasTests: boolean
|
|
67
|
+
technologies: string[]
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// =============================================================================
|
|
72
|
+
// Context Commands Class
|
|
73
|
+
// =============================================================================
|
|
74
|
+
|
|
75
|
+
export class ContextCommands {
|
|
76
|
+
/**
|
|
77
|
+
* Get full project context for Claude
|
|
78
|
+
*
|
|
79
|
+
* Usage:
|
|
80
|
+
* prjct context task "add user auth"
|
|
81
|
+
* prjct context done
|
|
82
|
+
* prjct context ship
|
|
83
|
+
*
|
|
84
|
+
* Returns JSON with all orchestrator data.
|
|
85
|
+
*/
|
|
86
|
+
async context(
|
|
87
|
+
input: string | null = null,
|
|
88
|
+
projectPath: string = process.cwd()
|
|
89
|
+
): Promise<CommandResult> {
|
|
90
|
+
try {
|
|
91
|
+
// Parse input: first word is command, rest is arguments
|
|
92
|
+
const parts = (input || '').trim().split(/\s+/)
|
|
93
|
+
const command = parts[0] || 'task'
|
|
94
|
+
const taskDescription = parts.slice(1).join(' ')
|
|
95
|
+
|
|
96
|
+
// Get project info
|
|
97
|
+
const config = await configManager.readConfig(projectPath)
|
|
98
|
+
if (!config || !config.projectId) {
|
|
99
|
+
const output: Partial<ContextOutput> = {
|
|
100
|
+
projectId: '',
|
|
101
|
+
globalPath: '',
|
|
102
|
+
currentTask: null,
|
|
103
|
+
domains: [],
|
|
104
|
+
primaryDomain: null,
|
|
105
|
+
agents: [],
|
|
106
|
+
subtasks: null,
|
|
107
|
+
repoAnalysis: {
|
|
108
|
+
ecosystem: 'unknown',
|
|
109
|
+
frameworks: [],
|
|
110
|
+
hasTests: false,
|
|
111
|
+
technologies: [],
|
|
112
|
+
},
|
|
113
|
+
}
|
|
114
|
+
console.log(JSON.stringify(output, null, 2))
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
message: 'No prjct project. Run `p. init` first.',
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const projectId = config.projectId
|
|
122
|
+
const globalPath = pathManager.getGlobalProjectPath(projectId)
|
|
123
|
+
|
|
124
|
+
// Get current task state
|
|
125
|
+
const state = await stateStorage.read(projectId)
|
|
126
|
+
const currentTask = state?.currentTask
|
|
127
|
+
? {
|
|
128
|
+
id: state.currentTask.id,
|
|
129
|
+
description: state.currentTask.description,
|
|
130
|
+
startedAt: state.currentTask.startedAt,
|
|
131
|
+
subtasks: state.currentTask.subtasks?.map((st) => ({
|
|
132
|
+
id: st.id,
|
|
133
|
+
description: st.description,
|
|
134
|
+
status: st.status,
|
|
135
|
+
domain: st.domain,
|
|
136
|
+
})),
|
|
137
|
+
currentSubtaskIndex: state.currentTask.currentSubtaskIndex,
|
|
138
|
+
}
|
|
139
|
+
: null
|
|
140
|
+
|
|
141
|
+
// Run orchestrator if we have a task description
|
|
142
|
+
let orchestratorContext = null
|
|
143
|
+
if (taskDescription) {
|
|
144
|
+
try {
|
|
145
|
+
orchestratorContext = await orchestratorExecutor.execute(
|
|
146
|
+
command,
|
|
147
|
+
taskDescription,
|
|
148
|
+
projectPath
|
|
149
|
+
)
|
|
150
|
+
} catch (error) {
|
|
151
|
+
// Orchestration failed - continue without it
|
|
152
|
+
console.error(`Warning: Orchestrator failed: ${(error as Error).message}`)
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Load repo analysis
|
|
157
|
+
const repoAnalysis = await this.loadRepoAnalysis(globalPath)
|
|
158
|
+
|
|
159
|
+
// Build output
|
|
160
|
+
const output: ContextOutput = {
|
|
161
|
+
projectId,
|
|
162
|
+
globalPath,
|
|
163
|
+
currentTask,
|
|
164
|
+
domains: orchestratorContext?.detectedDomains || [],
|
|
165
|
+
primaryDomain: orchestratorContext?.primaryDomain || null,
|
|
166
|
+
agents:
|
|
167
|
+
orchestratorContext?.agents.map((a) => ({
|
|
168
|
+
name: a.name,
|
|
169
|
+
domain: a.domain,
|
|
170
|
+
filePath: a.filePath,
|
|
171
|
+
skills: a.skills,
|
|
172
|
+
preview: a.content.substring(0, 500),
|
|
173
|
+
})) || [],
|
|
174
|
+
subtasks:
|
|
175
|
+
orchestratorContext?.subtasks?.map((st) => ({
|
|
176
|
+
id: st.id,
|
|
177
|
+
description: st.description,
|
|
178
|
+
domain: st.domain,
|
|
179
|
+
agent: st.agent,
|
|
180
|
+
status: st.status,
|
|
181
|
+
order: st.order,
|
|
182
|
+
})) || null,
|
|
183
|
+
repoAnalysis: {
|
|
184
|
+
ecosystem: repoAnalysis?.ecosystem || 'unknown',
|
|
185
|
+
frameworks: repoAnalysis?.frameworks || [],
|
|
186
|
+
hasTests: repoAnalysis?.hasTests || false,
|
|
187
|
+
technologies: repoAnalysis?.technologies || [],
|
|
188
|
+
},
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Output JSON to stdout
|
|
192
|
+
console.log(JSON.stringify(output, null, 2))
|
|
193
|
+
|
|
194
|
+
return {
|
|
195
|
+
success: true,
|
|
196
|
+
message: '', // Empty message - JSON output is the result
|
|
197
|
+
}
|
|
198
|
+
} catch (error) {
|
|
199
|
+
return {
|
|
200
|
+
success: false,
|
|
201
|
+
message: `Context error: ${(error as Error).message}`,
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Load repo analysis from analysis/repo-analysis.json
|
|
208
|
+
*/
|
|
209
|
+
private async loadRepoAnalysis(globalPath: string): Promise<{
|
|
210
|
+
ecosystem: string
|
|
211
|
+
frameworks: string[]
|
|
212
|
+
hasTests: boolean
|
|
213
|
+
technologies: string[]
|
|
214
|
+
} | null> {
|
|
215
|
+
try {
|
|
216
|
+
const analysisPath = path.join(globalPath, 'analysis', 'repo-analysis.json')
|
|
217
|
+
const content = await fs.readFile(analysisPath, 'utf-8')
|
|
218
|
+
const data = JSON.parse(content)
|
|
219
|
+
return {
|
|
220
|
+
ecosystem: data.ecosystem || 'unknown',
|
|
221
|
+
frameworks: data.frameworks || [],
|
|
222
|
+
hasTests: data.hasTests ?? false,
|
|
223
|
+
technologies: data.technologies || [],
|
|
224
|
+
}
|
|
225
|
+
} catch (error) {
|
|
226
|
+
if (isNotFoundError(error)) return null
|
|
227
|
+
return null
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// =============================================================================
|
|
233
|
+
// Exports
|
|
234
|
+
// =============================================================================
|
|
235
|
+
|
|
236
|
+
const contextCommands = new ContextCommands()
|
|
237
|
+
export default contextCommands
|
|
238
|
+
export { contextCommands }
|
|
@@ -17,6 +17,7 @@ import { AnalyticsCommands } from './analytics'
|
|
|
17
17
|
import { MaintenanceCommands } from './maintenance'
|
|
18
18
|
import { AnalysisCommands } from './analysis'
|
|
19
19
|
import { SetupCommands } from './setup'
|
|
20
|
+
import { ContextCommands } from './context'
|
|
20
21
|
|
|
21
22
|
// Singleton instances of command groups
|
|
22
23
|
const workflow = new WorkflowCommands()
|
|
@@ -26,6 +27,7 @@ const analytics = new AnalyticsCommands()
|
|
|
26
27
|
const maintenance = new MaintenanceCommands()
|
|
27
28
|
const analysis = new AnalysisCommands()
|
|
28
29
|
const setup = new SetupCommands()
|
|
30
|
+
const context = new ContextCommands()
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* Register categories
|
|
@@ -50,8 +52,6 @@ export function registerAllCommands(): void {
|
|
|
50
52
|
const getMeta = (name: string) => COMMANDS.find(c => c.name === name)
|
|
51
53
|
|
|
52
54
|
// Workflow commands
|
|
53
|
-
commandRegistry.registerMethod('work', workflow, 'now', getMeta('work'))
|
|
54
|
-
commandRegistry.registerMethod('now', workflow, 'now', getMeta('now'))
|
|
55
55
|
commandRegistry.registerMethod('done', workflow, 'done', getMeta('done'))
|
|
56
56
|
commandRegistry.registerMethod('next', workflow, 'next', getMeta('next'))
|
|
57
57
|
commandRegistry.registerMethod('pause', workflow, 'pause', getMeta('pause'))
|
|
@@ -59,7 +59,6 @@ export function registerAllCommands(): void {
|
|
|
59
59
|
|
|
60
60
|
// Planning commands
|
|
61
61
|
commandRegistry.registerMethod('init', planning, 'init', getMeta('init'))
|
|
62
|
-
commandRegistry.registerMethod('feature', planning, 'feature', getMeta('feature'))
|
|
63
62
|
commandRegistry.registerMethod('bug', planning, 'bug', getMeta('bug'))
|
|
64
63
|
commandRegistry.registerMethod('idea', planning, 'idea', getMeta('idea'))
|
|
65
64
|
commandRegistry.registerMethod('spec', planning, 'spec', getMeta('spec'))
|
|
@@ -86,7 +85,9 @@ export function registerAllCommands(): void {
|
|
|
86
85
|
// Setup commands
|
|
87
86
|
commandRegistry.registerMethod('start', setup, 'start', getMeta('start'))
|
|
88
87
|
commandRegistry.registerMethod('setup', setup, 'setup', getMeta('setup'))
|
|
89
|
-
|
|
88
|
+
|
|
89
|
+
// Context command (for Claude templates)
|
|
90
|
+
commandRegistry.registerMethod('context', context, 'context', getMeta('context'))
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
// Auto-register on import
|
|
@@ -100,5 +101,6 @@ export {
|
|
|
100
101
|
analytics,
|
|
101
102
|
maintenance,
|
|
102
103
|
analysis,
|
|
103
|
-
setup
|
|
104
|
+
setup,
|
|
105
|
+
context
|
|
104
106
|
}
|
package/core/commands/setup.ts
CHANGED
|
@@ -8,7 +8,7 @@ import chalk from 'chalk'
|
|
|
8
8
|
|
|
9
9
|
import commandInstaller from '../infrastructure/command-installer'
|
|
10
10
|
import pathManager from '../infrastructure/path-manager'
|
|
11
|
-
import type { CommandResult, SetupOptions
|
|
11
|
+
import type { CommandResult, SetupOptions } from '../types'
|
|
12
12
|
import { PrjctCommandsBase } from './base'
|
|
13
13
|
import { VERSION } from '../utils/version'
|
|
14
14
|
|
|
@@ -254,20 +254,4 @@ echo "⚡ prjct"
|
|
|
254
254
|
console.log('')
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
/**
|
|
258
|
-
* Migrate all projects to UUID format
|
|
259
|
-
*/
|
|
260
|
-
async migrateAll(_options: MigrateOptions = {}): Promise<CommandResult> {
|
|
261
|
-
console.log('🔄 Migrating all projects to UUID format...\n')
|
|
262
|
-
|
|
263
|
-
// TODO: Implement full migration logic
|
|
264
|
-
// For now, return success as this is a stub
|
|
265
|
-
console.log('✅ Migration complete (no projects needed migration)\n')
|
|
266
|
-
|
|
267
|
-
return {
|
|
268
|
-
success: true,
|
|
269
|
-
message: 'Migration complete',
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
257
|
}
|
package/core/index.ts
CHANGED
|
@@ -90,21 +90,17 @@ async function main(): Promise<void> {
|
|
|
90
90
|
result = await commands.cleanup(options)
|
|
91
91
|
} else if (commandName === 'setup') {
|
|
92
92
|
result = await commands.setup(options)
|
|
93
|
-
} else if (commandName === 'migrate-all') {
|
|
94
|
-
result = await commands.migrateAll(options)
|
|
95
93
|
} else {
|
|
96
94
|
// Standard commands - type-safe invocation
|
|
97
95
|
const param = parsedArgs.join(' ') || null
|
|
98
96
|
const standardCommands: Record<string, (p: string | null) => Promise<CommandResult>> = {
|
|
99
97
|
// Core workflow
|
|
100
|
-
work: (p) => commands.work(p),
|
|
101
98
|
done: () => commands.done(),
|
|
102
99
|
next: () => commands.next(),
|
|
103
100
|
pause: (p) => commands.pause(p || ''),
|
|
104
101
|
resume: (p) => commands.resume(p),
|
|
105
102
|
// Planning
|
|
106
103
|
init: (p) => commands.init(p),
|
|
107
|
-
feature: (p) => commands.feature(p || ''),
|
|
108
104
|
bug: (p) => commands.bug(p || ''),
|
|
109
105
|
idea: (p) => commands.idea(p || ''),
|
|
110
106
|
spec: (p) => commands.spec(p),
|
|
@@ -120,6 +116,8 @@ async function main(): Promise<void> {
|
|
|
120
116
|
// Setup
|
|
121
117
|
sync: () => commands.sync(),
|
|
122
118
|
start: () => commands.start(),
|
|
119
|
+
// Context (for Claude templates)
|
|
120
|
+
context: (p) => commands.context(p),
|
|
123
121
|
}
|
|
124
122
|
|
|
125
123
|
const handler = standardCommands[commandName]
|
package/core/services/index.ts
CHANGED
|
@@ -9,6 +9,8 @@ export { agentService, AgentService } from './agent-service'
|
|
|
9
9
|
export { projectService, ProjectService } from './project-service'
|
|
10
10
|
export { memoryService, MemoryService } from './memory-service'
|
|
11
11
|
export { breakdownService, BreakdownService } from './breakdown-service'
|
|
12
|
+
export { syncService, SyncService } from './sync-service'
|
|
13
|
+
export type { SyncResult } from './sync-service'
|
|
12
14
|
|
|
13
15
|
// Re-export types from canonical source
|
|
14
16
|
export type {
|