prjct-cli 0.7.0 ā 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/prjct +4 -0
- package/core/command-registry.js +3 -3
- package/core/commands.js +257 -36
- package/core/infrastructure/command-installer.js +1 -1
- package/package.json +1 -1
package/bin/prjct
CHANGED
|
@@ -72,6 +72,10 @@ async function main() {
|
|
|
72
72
|
result = await commands.analyze(options)
|
|
73
73
|
} else if (commandName === 'cleanup') {
|
|
74
74
|
result = await commands.cleanup(options)
|
|
75
|
+
} else if (commandName === 'setup') {
|
|
76
|
+
result = await commands.setup(options)
|
|
77
|
+
} else if (commandName === 'migrate-all') {
|
|
78
|
+
result = await commands.migrateAll(options)
|
|
75
79
|
} else if (commandName === 'progress') {
|
|
76
80
|
const period = parsedArgs[0] || 'week'
|
|
77
81
|
result = await commands.progress(period)
|
package/core/command-registry.js
CHANGED
|
@@ -91,7 +91,7 @@ const COMMANDS = [
|
|
|
91
91
|
terminal: 'prjct roadmap',
|
|
92
92
|
},
|
|
93
93
|
params: null,
|
|
94
|
-
implemented:
|
|
94
|
+
implemented: true,
|
|
95
95
|
hasTemplate: true,
|
|
96
96
|
icon: 'Map',
|
|
97
97
|
requiresInit: true,
|
|
@@ -114,7 +114,7 @@ const COMMANDS = [
|
|
|
114
114
|
terminal: 'prjct status',
|
|
115
115
|
},
|
|
116
116
|
params: null,
|
|
117
|
-
implemented:
|
|
117
|
+
implemented: true,
|
|
118
118
|
hasTemplate: true,
|
|
119
119
|
icon: 'BarChart3',
|
|
120
120
|
requiresInit: true,
|
|
@@ -155,7 +155,7 @@ const COMMANDS = [
|
|
|
155
155
|
terminal: 'prjct build "implement auth"',
|
|
156
156
|
},
|
|
157
157
|
params: '<task> | [1-5]',
|
|
158
|
-
implemented:
|
|
158
|
+
implemented: true,
|
|
159
159
|
hasTemplate: true,
|
|
160
160
|
icon: 'Play',
|
|
161
161
|
requiresInit: true,
|
package/core/commands.js
CHANGED
|
@@ -2511,51 +2511,272 @@ Agent: ${agent}
|
|
|
2511
2511
|
return agents
|
|
2512
2512
|
}
|
|
2513
2513
|
|
|
2514
|
+
/**
|
|
2515
|
+
* First-time setup - Install commands to editors
|
|
2516
|
+
*/
|
|
2514
2517
|
async start() {
|
|
2515
|
-
|
|
2516
|
-
}
|
|
2518
|
+
const commandInstaller = require('./infrastructure/command-installer')
|
|
2517
2519
|
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2520
|
+
console.log('š Setting up prjct for Claude...\n')
|
|
2521
|
+
|
|
2522
|
+
// Check if Claude is installed
|
|
2523
|
+
const status = await commandInstaller.checkInstallation()
|
|
2524
|
+
|
|
2525
|
+
if (!status.claudeDetected) {
|
|
2526
|
+
return {
|
|
2527
|
+
success: false,
|
|
2528
|
+
message:
|
|
2529
|
+
'ā Claude not detected.\n\nPlease install Claude Code or Claude Desktop first:\n' +
|
|
2530
|
+
' - Claude Code: https://claude.com/code\n' +
|
|
2531
|
+
' - Claude Desktop: https://claude.com/desktop',
|
|
2532
|
+
}
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
// Install commands
|
|
2536
|
+
console.log('š¦ Installing /p:* commands...')
|
|
2537
|
+
const result = await commandInstaller.installCommands()
|
|
2538
|
+
|
|
2539
|
+
if (!result.success) {
|
|
2540
|
+
return {
|
|
2541
|
+
success: false,
|
|
2542
|
+
message: `ā Installation failed: ${result.error}`,
|
|
2543
|
+
}
|
|
2544
|
+
}
|
|
2521
2545
|
|
|
2522
|
-
|
|
2523
|
-
|
|
2546
|
+
console.log(`\nā
Installed ${result.installed.length} commands to:\n ${result.path}`)
|
|
2547
|
+
|
|
2548
|
+
if (result.errors.length > 0) {
|
|
2549
|
+
console.log(`\nā ļø ${result.errors.length} errors:`)
|
|
2550
|
+
result.errors.forEach((e) => console.log(` - ${e.file}: ${e.error}`))
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
console.log('\nš Setup complete!')
|
|
2554
|
+
console.log('\nNext steps:')
|
|
2555
|
+
console.log(' 1. Open Claude Code or Claude Desktop')
|
|
2556
|
+
console.log(' 2. Navigate to your project')
|
|
2557
|
+
console.log(' 3. Run: /p:init')
|
|
2558
|
+
|
|
2559
|
+
return {
|
|
2560
|
+
success: true,
|
|
2561
|
+
message: '',
|
|
2562
|
+
}
|
|
2524
2563
|
}
|
|
2525
2564
|
|
|
2526
|
-
|
|
2527
|
-
|
|
2565
|
+
/**
|
|
2566
|
+
* Reconfigure editor installations
|
|
2567
|
+
*/
|
|
2568
|
+
async setup(options = {}) {
|
|
2569
|
+
const commandInstaller = require('./infrastructure/command-installer')
|
|
2570
|
+
|
|
2571
|
+
console.log('š§ Reconfiguring prjct...\n')
|
|
2572
|
+
|
|
2573
|
+
if (options.force) {
|
|
2574
|
+
console.log('šļø Removing existing installation...')
|
|
2575
|
+
await commandInstaller.uninstallCommands()
|
|
2576
|
+
}
|
|
2577
|
+
|
|
2578
|
+
// Reinstall commands
|
|
2579
|
+
console.log('š¦ Installing /p:* commands...')
|
|
2580
|
+
const result = await commandInstaller.updateCommands()
|
|
2581
|
+
|
|
2582
|
+
if (!result.success) {
|
|
2583
|
+
return {
|
|
2584
|
+
success: false,
|
|
2585
|
+
message: `ā Setup failed: ${result.error}`,
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2589
|
+
console.log(`\nā
Installed ${result.installed.length} commands`)
|
|
2590
|
+
|
|
2591
|
+
if (result.errors.length > 0) {
|
|
2592
|
+
console.log(`\nā ļø ${result.errors.length} errors:`)
|
|
2593
|
+
result.errors.forEach((e) => console.log(` - ${e.file}: ${e.error}`))
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2596
|
+
console.log('\nš Setup complete!')
|
|
2597
|
+
|
|
2598
|
+
return {
|
|
2599
|
+
success: true,
|
|
2600
|
+
message: '',
|
|
2601
|
+
}
|
|
2528
2602
|
}
|
|
2529
2603
|
|
|
2530
|
-
|
|
2531
|
-
|
|
2604
|
+
/**
|
|
2605
|
+
* Migrate all legacy projects
|
|
2606
|
+
*/
|
|
2607
|
+
async migrateAll(options = {}) {
|
|
2608
|
+
const fs = require('fs').promises
|
|
2609
|
+
const path = require('path')
|
|
2610
|
+
|
|
2611
|
+
console.log('š Scanning for legacy prjct projects...\n')
|
|
2612
|
+
|
|
2613
|
+
const homeDir = require('os').homedir()
|
|
2614
|
+
const globalRoot = path.join(homeDir, '.prjct-cli', 'projects')
|
|
2615
|
+
|
|
2616
|
+
// Get all project IDs
|
|
2617
|
+
let projectIds = []
|
|
2618
|
+
try {
|
|
2619
|
+
const dirs = await fs.readdir(globalRoot)
|
|
2620
|
+
projectIds = dirs.filter((d) => !d.startsWith('.'))
|
|
2621
|
+
} catch (error) {
|
|
2622
|
+
return {
|
|
2623
|
+
success: false,
|
|
2624
|
+
message: 'ā No prjct projects found',
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
|
|
2628
|
+
console.log(`š Found ${projectIds.length} projects in global storage\n`)
|
|
2629
|
+
|
|
2630
|
+
const migrated = []
|
|
2631
|
+
const failed = []
|
|
2632
|
+
const skipped = []
|
|
2633
|
+
|
|
2634
|
+
for (const projectId of projectIds) {
|
|
2635
|
+
const globalProjectPath = path.join(globalRoot, projectId)
|
|
2636
|
+
|
|
2637
|
+
// Read global config to get project path
|
|
2638
|
+
const globalConfig = await configManager.readGlobalConfig(projectId)
|
|
2639
|
+
if (!globalConfig || !globalConfig.projectPath) {
|
|
2640
|
+
skipped.push({ projectId, reason: 'No project path in config' })
|
|
2641
|
+
continue
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2644
|
+
const projectPath = globalConfig.projectPath
|
|
2645
|
+
|
|
2646
|
+
// Check if needs migration
|
|
2647
|
+
if (!(await migrator.needsMigration(projectPath))) {
|
|
2648
|
+
skipped.push({ projectId, reason: 'Already migrated' })
|
|
2649
|
+
continue
|
|
2650
|
+
}
|
|
2651
|
+
|
|
2652
|
+
console.log(`š Migrating: ${projectPath}`)
|
|
2653
|
+
|
|
2654
|
+
try {
|
|
2655
|
+
const result = await migrator.migrate(projectPath, options)
|
|
2656
|
+
|
|
2657
|
+
if (result.success) {
|
|
2658
|
+
migrated.push({ projectId, path: projectPath })
|
|
2659
|
+
console.log(` ā
${result.message}`)
|
|
2660
|
+
} else {
|
|
2661
|
+
failed.push({ projectId, path: projectPath, error: result.message })
|
|
2662
|
+
console.log(` ā ${result.message}`)
|
|
2663
|
+
}
|
|
2664
|
+
} catch (error) {
|
|
2665
|
+
failed.push({ projectId, path: projectPath, error: error.message })
|
|
2666
|
+
console.log(` ā ${error.message}`)
|
|
2667
|
+
}
|
|
2668
|
+
|
|
2669
|
+
console.log('')
|
|
2670
|
+
}
|
|
2671
|
+
|
|
2672
|
+
// Summary
|
|
2673
|
+
console.log('\nš Migration Summary:')
|
|
2674
|
+
console.log(` ā
Migrated: ${migrated.length}`)
|
|
2675
|
+
console.log(` āļø Skipped: ${skipped.length}`)
|
|
2676
|
+
console.log(` ā Failed: ${failed.length}`)
|
|
2677
|
+
|
|
2678
|
+
if (failed.length > 0) {
|
|
2679
|
+
console.log('\nā Failed migrations:')
|
|
2680
|
+
failed.forEach((f) => console.log(` - ${f.path}: ${f.error}`))
|
|
2681
|
+
}
|
|
2682
|
+
|
|
2683
|
+
return {
|
|
2684
|
+
success: failed.length === 0,
|
|
2685
|
+
message: '',
|
|
2686
|
+
}
|
|
2532
2687
|
}
|
|
2533
2688
|
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2689
|
+
/**
|
|
2690
|
+
* Execute architect plan and generate code
|
|
2691
|
+
*/
|
|
2692
|
+
async architect(action = 'execute', projectPath = process.cwd()) {
|
|
2693
|
+
if (action !== 'execute') {
|
|
2694
|
+
return {
|
|
2695
|
+
success: false,
|
|
2696
|
+
message: 'ā Invalid action. Use: /p:architect execute',
|
|
2697
|
+
}
|
|
2698
|
+
}
|
|
2699
|
+
|
|
2700
|
+
try {
|
|
2701
|
+
const initResult = await this.ensureProjectInit(projectPath)
|
|
2702
|
+
if (!initResult.success) return initResult
|
|
2703
|
+
|
|
2704
|
+
console.log('šļø Architect Mode - Code Generation\n')
|
|
2705
|
+
|
|
2706
|
+
const globalPath = await this.getGlobalProjectPath(projectPath)
|
|
2707
|
+
const architectSession = require('./domain/architect-session')
|
|
2708
|
+
|
|
2709
|
+
// Check if there's a completed plan
|
|
2710
|
+
const planPath = path.join(globalPath, 'planning', 'architect-session.md')
|
|
2711
|
+
|
|
2712
|
+
let planContent
|
|
2713
|
+
try {
|
|
2714
|
+
planContent = await fileHelper.readFile(planPath)
|
|
2715
|
+
} catch (error) {
|
|
2716
|
+
return {
|
|
2717
|
+
success: false,
|
|
2718
|
+
message:
|
|
2719
|
+
'ā No architect plan found.\n\n' +
|
|
2720
|
+
'Create a plan first:\n' +
|
|
2721
|
+
' 1. Run /p:init in an empty directory\n' +
|
|
2722
|
+
' 2. Answer the discovery questions\n' +
|
|
2723
|
+
' 3. Plan will be auto-generated\n' +
|
|
2724
|
+
' 4. Then run /p:architect execute',
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
if (!planContent || planContent.trim() === '') {
|
|
2729
|
+
return {
|
|
2730
|
+
success: false,
|
|
2731
|
+
message: 'ā Architect plan is empty',
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
console.log('š Reading architect plan...\n')
|
|
2736
|
+
|
|
2737
|
+
// Extract key information from plan
|
|
2738
|
+
const ideaMatch = planContent.match(/## Project Idea\n(.+)/s)
|
|
2739
|
+
const stackMatch = planContent.match(/\*\*Stack:\*\*\n([\s\S]+?)\n\n/)
|
|
2740
|
+
const stepsMatch = planContent.match(/\*\*Implementation Steps:\*\*\n([\s\S]+?)\n\n/)
|
|
2741
|
+
|
|
2742
|
+
const idea = ideaMatch ? ideaMatch[1].split('\n')[0].trim() : 'Unknown project'
|
|
2743
|
+
const stack = stackMatch ? stackMatch[1] : 'Not specified'
|
|
2744
|
+
const steps = stepsMatch ? stepsMatch[1] : 'Not specified'
|
|
2745
|
+
|
|
2746
|
+
console.log(`š Project: ${idea}`)
|
|
2747
|
+
console.log(`\nš§ Stack:\n${stack}`)
|
|
2748
|
+
console.log(`\nš Implementation Steps:\n${steps}`)
|
|
2749
|
+
|
|
2750
|
+
console.log('\n' + '='.repeat(60))
|
|
2751
|
+
console.log('š¤ READY TO GENERATE CODE')
|
|
2752
|
+
console.log('='.repeat(60))
|
|
2753
|
+
|
|
2754
|
+
console.log(
|
|
2755
|
+
'\nThe architect plan is ready. Claude will now:\n' +
|
|
2756
|
+
' 1. Read the architectural plan\n' +
|
|
2757
|
+
' 2. Use Context7 for official documentation\n' +
|
|
2758
|
+
' 3. Generate project structure\n' +
|
|
2759
|
+
' 4. Create starter files with boilerplate\n'
|
|
2760
|
+
)
|
|
2761
|
+
|
|
2762
|
+
console.log('\nš” This command shows the plan.')
|
|
2763
|
+
console.log(' For code generation, Claude Code will read this plan')
|
|
2764
|
+
console.log(' and generate the structure automatically.\n')
|
|
2765
|
+
|
|
2766
|
+
await this.logToMemory(projectPath, 'architect_executed', {
|
|
2767
|
+
timestamp: dateHelper.getTimestamp(),
|
|
2768
|
+
idea,
|
|
2769
|
+
})
|
|
2770
|
+
|
|
2771
|
+
return {
|
|
2772
|
+
success: true,
|
|
2773
|
+
plan: planContent,
|
|
2774
|
+
idea,
|
|
2775
|
+
}
|
|
2776
|
+
} catch (error) {
|
|
2777
|
+
console.error('ā Error:', error.message)
|
|
2778
|
+
return { success: false, error: error.message }
|
|
2779
|
+
}
|
|
2559
2780
|
}
|
|
2560
2781
|
}
|
|
2561
2782
|
|
|
@@ -16,7 +16,7 @@ class CommandInstaller {
|
|
|
16
16
|
this.homeDir = os.homedir()
|
|
17
17
|
this.claudeCommandsPath = path.join(this.homeDir, '.claude', 'commands', 'p')
|
|
18
18
|
this.claudeConfigPath = path.join(this.homeDir, '.claude')
|
|
19
|
-
this.templatesDir = path.join(__dirname, '..', 'templates', 'commands')
|
|
19
|
+
this.templatesDir = path.join(__dirname, '..', '..', 'templates', 'commands')
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
/**
|