claude-autopm 1.13.0 ā 1.13.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/README.md +37 -19
- package/bin/autopm.js +26 -1
- package/bin/commands/mcp.js +17 -13
- package/install/install.js +14 -8
- package/install/post-install-check.js +384 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,25 +43,43 @@ ClaudeAutoPM uses a **hybrid approach** combining deterministic operations with
|
|
|
43
43
|
|
|
44
44
|
## šŗ Visual Walkthrough
|
|
45
45
|
|
|
46
|
-
See ClaudeAutoPM in action - from installation to deployment
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
46
|
+
See ClaudeAutoPM in action - from installation to deployment. **Click to expand each video:**
|
|
47
|
+
|
|
48
|
+
<details>
|
|
49
|
+
<summary><b>1ļøā£ Install AutoPM</b> - Complete installation process</summary>
|
|
50
|
+
<br>
|
|
51
|
+
<img src="docs/assets/video-1.gif" width="100%" alt="Install AutoPM">
|
|
52
|
+
</details>
|
|
53
|
+
|
|
54
|
+
<details>
|
|
55
|
+
<summary><b>2ļøā£ First Claude Execution</b> - Setting up and running Claude Code</summary>
|
|
56
|
+
<br>
|
|
57
|
+
<img src="docs/assets/video-2.gif" width="100%" alt="First Claude Execution">
|
|
58
|
+
</details>
|
|
59
|
+
|
|
60
|
+
<details>
|
|
61
|
+
<summary><b>3ļøā£ Creation of PRD</b> - Product Requirements Document workflow</summary>
|
|
62
|
+
<br>
|
|
63
|
+
<img src="docs/assets/video-3.gif" width="100%" alt="Create PRD">
|
|
64
|
+
</details>
|
|
65
|
+
|
|
66
|
+
<details>
|
|
67
|
+
<summary><b>4ļøā£ GitHub Sync and Start Working</b> - Synchronizing with GitHub and beginning tasks</summary>
|
|
68
|
+
<br>
|
|
69
|
+
<img src="docs/assets/video-4.gif" width="100%" alt="GitHub Sync">
|
|
70
|
+
</details>
|
|
71
|
+
|
|
72
|
+
<details>
|
|
73
|
+
<summary><b>5ļøā£ Issues Finished</b> - Completing and closing tasks</summary>
|
|
74
|
+
<br>
|
|
75
|
+
<img src="docs/assets/video-5.gif" width="100%" alt="Issues Complete">
|
|
76
|
+
</details>
|
|
77
|
+
|
|
78
|
+
<details>
|
|
79
|
+
<summary><b>6ļøā£ Checking the Work Done</b> - Running Web App + FastAPI demo</summary>
|
|
80
|
+
<br>
|
|
81
|
+
<img src="docs/assets/video-6.gif" width="100%" alt="Web App and FastAPI">
|
|
82
|
+
</details>
|
|
65
83
|
|
|
66
84
|
## š Get Started in 5 Minutes
|
|
67
85
|
|
package/bin/autopm.js
CHANGED
|
@@ -180,6 +180,29 @@ function main() {
|
|
|
180
180
|
.command(require('./commands/config'))
|
|
181
181
|
// MCP management command
|
|
182
182
|
.command(require('./commands/mcp'))
|
|
183
|
+
// Validation command
|
|
184
|
+
.command('validate', 'Validate ClaudeAutoPM configuration and setup',
|
|
185
|
+
(yargs) => {
|
|
186
|
+
return yargs
|
|
187
|
+
.example('autopm validate', 'Check all configuration requirements')
|
|
188
|
+
.example('autopm validate --verbose', 'Show detailed validation info');
|
|
189
|
+
},
|
|
190
|
+
async (argv) => {
|
|
191
|
+
const PostInstallChecker = require('../install/post-install-check.js');
|
|
192
|
+
const checker = new PostInstallChecker();
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
await checker.runAllChecks();
|
|
196
|
+
process.exit(0);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error(`ā Validation error: ${error.message}`);
|
|
199
|
+
if (argv.debug) {
|
|
200
|
+
console.error(error.stack);
|
|
201
|
+
}
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
)
|
|
183
206
|
// Global options
|
|
184
207
|
.option('verbose', {
|
|
185
208
|
type: 'boolean',
|
|
@@ -203,6 +226,7 @@ function main() {
|
|
|
203
226
|
.epilogue(`
|
|
204
227
|
š Quick Start:
|
|
205
228
|
autopm install # Install ClaudeAutoPM in current directory
|
|
229
|
+
autopm validate # Check configuration status
|
|
206
230
|
autopm update # Update to latest framework version
|
|
207
231
|
autopm team load frontend # Load React/UI development agents
|
|
208
232
|
claude --dangerously-skip-permissions . # Open Claude Code
|
|
@@ -392,7 +416,8 @@ function main() {
|
|
|
392
416
|
ā Updates epic progress tracking
|
|
393
417
|
|
|
394
418
|
š ļø Troubleshooting:
|
|
395
|
-
# Check installation
|
|
419
|
+
# Check installation and configuration
|
|
420
|
+
autopm validate # Comprehensive status check
|
|
396
421
|
ls -la .claude/ # Should show: agents/, commands/, config.json
|
|
397
422
|
|
|
398
423
|
# Verify configuration
|
package/bin/commands/mcp.js
CHANGED
|
@@ -7,7 +7,7 @@ const path = require('path');
|
|
|
7
7
|
const MCPHandler = require('../../scripts/mcp-handler.js');
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
|
-
command: 'mcp <action> [
|
|
10
|
+
command: 'mcp <action> [name]',
|
|
11
11
|
describe: 'Manage MCP (Model Context Protocol) servers and configuration',
|
|
12
12
|
|
|
13
13
|
builder: (yargs) => {
|
|
@@ -20,6 +20,10 @@ module.exports = {
|
|
|
20
20
|
'agents', 'agent', 'usage', 'setup', 'check', 'diagnose', 'test', 'tree', 'status'
|
|
21
21
|
]
|
|
22
22
|
})
|
|
23
|
+
.positional('name', {
|
|
24
|
+
describe: 'Server or agent name (for actions that require it)',
|
|
25
|
+
type: 'string'
|
|
26
|
+
})
|
|
23
27
|
.option('server', {
|
|
24
28
|
alias: 's',
|
|
25
29
|
describe: 'Server name',
|
|
@@ -64,27 +68,27 @@ module.exports = {
|
|
|
64
68
|
break;
|
|
65
69
|
|
|
66
70
|
case 'remove':
|
|
67
|
-
if (!argv.
|
|
71
|
+
if (!argv.name && !argv.server) {
|
|
68
72
|
console.error('ā Please specify a server name: autopm mcp remove <server-name>');
|
|
69
73
|
process.exit(1);
|
|
70
74
|
}
|
|
71
|
-
handler.remove(argv.
|
|
75
|
+
handler.remove(argv.name || argv.server);
|
|
72
76
|
break;
|
|
73
77
|
|
|
74
78
|
case 'enable':
|
|
75
|
-
if (!argv.
|
|
79
|
+
if (!argv.name && !argv.server) {
|
|
76
80
|
console.error('ā Please specify a server name: autopm mcp enable <server-name>');
|
|
77
81
|
process.exit(1);
|
|
78
82
|
}
|
|
79
|
-
handler.enable(argv.
|
|
83
|
+
handler.enable(argv.name || argv.server);
|
|
80
84
|
break;
|
|
81
85
|
|
|
82
86
|
case 'disable':
|
|
83
|
-
if (!argv.
|
|
87
|
+
if (!argv.name && !argv.server) {
|
|
84
88
|
console.error('ā Please specify a server name: autopm mcp disable <server-name>');
|
|
85
89
|
process.exit(1);
|
|
86
90
|
}
|
|
87
|
-
handler.disable(argv.
|
|
91
|
+
handler.disable(argv.name || argv.server);
|
|
88
92
|
break;
|
|
89
93
|
|
|
90
94
|
case 'sync':
|
|
@@ -96,11 +100,11 @@ module.exports = {
|
|
|
96
100
|
break;
|
|
97
101
|
|
|
98
102
|
case 'info':
|
|
99
|
-
if (!argv.
|
|
103
|
+
if (!argv.name && !argv.server) {
|
|
100
104
|
console.error('ā Please specify a server name: autopm mcp info <server-name>');
|
|
101
105
|
process.exit(1);
|
|
102
106
|
}
|
|
103
|
-
handler.info(argv.
|
|
107
|
+
handler.info(argv.name || argv.server);
|
|
104
108
|
break;
|
|
105
109
|
|
|
106
110
|
// Agent analysis commands
|
|
@@ -109,11 +113,11 @@ module.exports = {
|
|
|
109
113
|
break;
|
|
110
114
|
|
|
111
115
|
case 'agent':
|
|
112
|
-
if (!argv.
|
|
116
|
+
if (!argv.name && !argv.agent) {
|
|
113
117
|
console.error('ā Please specify an agent name: autopm mcp agent <agent-name>');
|
|
114
118
|
process.exit(1);
|
|
115
119
|
}
|
|
116
|
-
handler.mcpAgent(argv.
|
|
120
|
+
handler.mcpAgent(argv.name || argv.agent);
|
|
117
121
|
break;
|
|
118
122
|
|
|
119
123
|
case 'usage':
|
|
@@ -134,11 +138,11 @@ module.exports = {
|
|
|
134
138
|
break;
|
|
135
139
|
|
|
136
140
|
case 'test':
|
|
137
|
-
if (!argv.
|
|
141
|
+
if (!argv.name && !argv.server) {
|
|
138
142
|
console.error('ā Please specify a server name: autopm mcp test <server-name>');
|
|
139
143
|
process.exit(1);
|
|
140
144
|
}
|
|
141
|
-
const result = await handler.testServer(argv.
|
|
145
|
+
const result = await handler.testServer(argv.name || argv.server);
|
|
142
146
|
if (result.success) {
|
|
143
147
|
console.log(`ā
${result.message}`);
|
|
144
148
|
} else {
|
package/install/install.js
CHANGED
|
@@ -797,6 +797,18 @@ See: https://github.com/rafeekpro/ClaudeAutoPM
|
|
|
797
797
|
}
|
|
798
798
|
}
|
|
799
799
|
|
|
800
|
+
async runPostInstallCheck() {
|
|
801
|
+
const PostInstallChecker = require('./post-install-check.js');
|
|
802
|
+
const checker = new PostInstallChecker();
|
|
803
|
+
|
|
804
|
+
try {
|
|
805
|
+
await checker.runAllChecks();
|
|
806
|
+
} catch (error) {
|
|
807
|
+
this.printWarning(`Configuration check failed: ${error.message}`);
|
|
808
|
+
console.log('You can run the check later with: autopm config validate\n');
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
800
812
|
async run() {
|
|
801
813
|
// Handle help and version
|
|
802
814
|
if (this.options.help) {
|
|
@@ -852,14 +864,8 @@ See: https://github.com/rafeekpro/ClaudeAutoPM
|
|
|
852
864
|
this.printMsg('GREEN', 'āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
853
865
|
console.log('');
|
|
854
866
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
this.printStep('Next steps:');
|
|
858
|
-
console.log(' 1. Review CLAUDE.md for project configuration');
|
|
859
|
-
console.log(' 2. Run: ./scripts/setup-hooks.sh to setup git hooks');
|
|
860
|
-
console.log(' 3. Open Claude Code in this directory');
|
|
861
|
-
console.log(' 4. In Claude, run: /pm:validate');
|
|
862
|
-
console.log('');
|
|
867
|
+
// Run post-installation configuration check
|
|
868
|
+
await this.runPostInstallCheck();
|
|
863
869
|
|
|
864
870
|
process.exit(0);
|
|
865
871
|
}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post-Installation Configuration Checker
|
|
5
|
+
* Validates that all required components are properly configured
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { execSync } = require('child_process');
|
|
11
|
+
|
|
12
|
+
class PostInstallChecker {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.projectRoot = process.cwd();
|
|
15
|
+
this.results = {
|
|
16
|
+
essential: [],
|
|
17
|
+
optional: [],
|
|
18
|
+
nextSteps: []
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Run all configuration checks
|
|
24
|
+
*/
|
|
25
|
+
async runAllChecks() {
|
|
26
|
+
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
27
|
+
console.log('ā š ClaudeAutoPM Configuration Status ā');
|
|
28
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
29
|
+
|
|
30
|
+
// Essential checks
|
|
31
|
+
this.checkClaudeDirectory();
|
|
32
|
+
this.checkConfigFile();
|
|
33
|
+
this.checkProvider();
|
|
34
|
+
this.checkGitRepository();
|
|
35
|
+
|
|
36
|
+
// Optional but recommended
|
|
37
|
+
this.checkMCPConfiguration();
|
|
38
|
+
this.checkGitHooks();
|
|
39
|
+
this.checkNodeVersion();
|
|
40
|
+
|
|
41
|
+
// Display results
|
|
42
|
+
this.displayResults();
|
|
43
|
+
this.displayNextSteps();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check if .claude directory exists
|
|
48
|
+
*/
|
|
49
|
+
checkClaudeDirectory() {
|
|
50
|
+
const claudeDir = path.join(this.projectRoot, '.claude');
|
|
51
|
+
const exists = fs.existsSync(claudeDir);
|
|
52
|
+
|
|
53
|
+
this.results.essential.push({
|
|
54
|
+
name: '.claude directory',
|
|
55
|
+
status: exists,
|
|
56
|
+
message: exists
|
|
57
|
+
? 'Framework installed'
|
|
58
|
+
: 'Not found - run: autopm install'
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
if (exists) {
|
|
62
|
+
// Check subdirectories
|
|
63
|
+
const subdirs = ['agents', 'commands', 'rules', 'scripts'];
|
|
64
|
+
subdirs.forEach(dir => {
|
|
65
|
+
const dirPath = path.join(claudeDir, dir);
|
|
66
|
+
const dirExists = fs.existsSync(dirPath);
|
|
67
|
+
this.results.optional.push({
|
|
68
|
+
name: ` āā ${dir}/`,
|
|
69
|
+
status: dirExists,
|
|
70
|
+
message: dirExists ? 'Present' : 'Missing'
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check configuration file
|
|
78
|
+
*/
|
|
79
|
+
checkConfigFile() {
|
|
80
|
+
const configPath = path.join(this.projectRoot, '.claude', 'config.json');
|
|
81
|
+
let config = null;
|
|
82
|
+
|
|
83
|
+
if (fs.existsSync(configPath)) {
|
|
84
|
+
try {
|
|
85
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
86
|
+
this.results.essential.push({
|
|
87
|
+
name: 'Configuration file',
|
|
88
|
+
status: true,
|
|
89
|
+
message: `Provider: ${config.provider || 'not set'}`
|
|
90
|
+
});
|
|
91
|
+
this.config = config;
|
|
92
|
+
} catch (error) {
|
|
93
|
+
this.results.essential.push({
|
|
94
|
+
name: 'Configuration file',
|
|
95
|
+
status: false,
|
|
96
|
+
message: 'Invalid JSON format'
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
this.results.essential.push({
|
|
101
|
+
name: 'Configuration file',
|
|
102
|
+
status: false,
|
|
103
|
+
message: 'Not found'
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Check provider configuration (GitHub or Azure DevOps)
|
|
110
|
+
*/
|
|
111
|
+
checkProvider() {
|
|
112
|
+
if (!this.config) {
|
|
113
|
+
this.results.essential.push({
|
|
114
|
+
name: 'Provider setup',
|
|
115
|
+
status: false,
|
|
116
|
+
message: 'No configuration file'
|
|
117
|
+
});
|
|
118
|
+
this.results.nextSteps.push('Run: autopm config set provider github|azure');
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const provider = this.config.provider;
|
|
123
|
+
|
|
124
|
+
if (!provider) {
|
|
125
|
+
this.results.essential.push({
|
|
126
|
+
name: 'Provider setup',
|
|
127
|
+
status: false,
|
|
128
|
+
message: 'Provider not configured'
|
|
129
|
+
});
|
|
130
|
+
this.results.nextSteps.push('Run: autopm config set provider github|azure');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Check GitHub configuration
|
|
135
|
+
if (provider === 'github') {
|
|
136
|
+
const hasToken = !!process.env.GITHUB_TOKEN;
|
|
137
|
+
const hasOwner = !!this.config.github?.owner;
|
|
138
|
+
const hasRepo = !!this.config.github?.repo;
|
|
139
|
+
|
|
140
|
+
this.results.essential.push({
|
|
141
|
+
name: 'GitHub Provider',
|
|
142
|
+
status: hasToken && hasOwner && hasRepo,
|
|
143
|
+
message: this.getGitHubStatus(hasToken, hasOwner, hasRepo)
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
if (!hasToken) {
|
|
147
|
+
this.results.nextSteps.push('Set GITHUB_TOKEN environment variable');
|
|
148
|
+
}
|
|
149
|
+
if (!hasOwner || !hasRepo) {
|
|
150
|
+
this.results.nextSteps.push('Run: autopm config set github.owner <username>');
|
|
151
|
+
this.results.nextSteps.push('Run: autopm config set github.repo <repository>');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Check Azure DevOps configuration
|
|
156
|
+
if (provider === 'azure') {
|
|
157
|
+
const hasToken = !!process.env.AZURE_DEVOPS_PAT;
|
|
158
|
+
const hasOrg = !!this.config.azure?.organization;
|
|
159
|
+
const hasProject = !!this.config.azure?.project;
|
|
160
|
+
|
|
161
|
+
this.results.essential.push({
|
|
162
|
+
name: 'Azure DevOps Provider',
|
|
163
|
+
status: hasToken && hasOrg && hasProject,
|
|
164
|
+
message: this.getAzureStatus(hasToken, hasOrg, hasProject)
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
if (!hasToken) {
|
|
168
|
+
this.results.nextSteps.push('Set AZURE_DEVOPS_PAT environment variable');
|
|
169
|
+
}
|
|
170
|
+
if (!hasOrg || !hasProject) {
|
|
171
|
+
this.results.nextSteps.push('Run: autopm config set azure.organization <org>');
|
|
172
|
+
this.results.nextSteps.push('Run: autopm config set azure.project <project>');
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Get GitHub configuration status message
|
|
179
|
+
*/
|
|
180
|
+
getGitHubStatus(hasToken, hasOwner, hasRepo) {
|
|
181
|
+
if (hasToken && hasOwner && hasRepo) {
|
|
182
|
+
return `Configured: ${this.config.github.owner}/${this.config.github.repo}`;
|
|
183
|
+
}
|
|
184
|
+
const missing = [];
|
|
185
|
+
if (!hasToken) missing.push('token');
|
|
186
|
+
if (!hasOwner) missing.push('owner');
|
|
187
|
+
if (!hasRepo) missing.push('repo');
|
|
188
|
+
return `Missing: ${missing.join(', ')}`;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get Azure DevOps configuration status message
|
|
193
|
+
*/
|
|
194
|
+
getAzureStatus(hasToken, hasOrg, hasProject) {
|
|
195
|
+
if (hasToken && hasOrg && hasProject) {
|
|
196
|
+
return `Configured: ${this.config.azure.organization}/${this.config.azure.project}`;
|
|
197
|
+
}
|
|
198
|
+
const missing = [];
|
|
199
|
+
if (!hasToken) missing.push('PAT');
|
|
200
|
+
if (!hasOrg) missing.push('organization');
|
|
201
|
+
if (!hasProject) missing.push('project');
|
|
202
|
+
return `Missing: ${missing.join(', ')}`;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Check MCP server configuration
|
|
207
|
+
*/
|
|
208
|
+
checkMCPConfiguration() {
|
|
209
|
+
const mcpServersPath = path.join(this.projectRoot, '.claude', 'mcp-servers.json');
|
|
210
|
+
const envPath = path.join(this.projectRoot, '.claude', '.env');
|
|
211
|
+
|
|
212
|
+
let mcpConfigured = false;
|
|
213
|
+
let message = 'Not configured';
|
|
214
|
+
|
|
215
|
+
if (fs.existsSync(mcpServersPath)) {
|
|
216
|
+
try {
|
|
217
|
+
const mcpConfig = JSON.parse(fs.readFileSync(mcpServersPath, 'utf8'));
|
|
218
|
+
const serverCount = Object.keys(mcpConfig.mcpServers || {}).length;
|
|
219
|
+
|
|
220
|
+
if (serverCount > 0) {
|
|
221
|
+
mcpConfigured = true;
|
|
222
|
+
message = `${serverCount} server(s) configured`;
|
|
223
|
+
} else {
|
|
224
|
+
message = 'No servers enabled';
|
|
225
|
+
}
|
|
226
|
+
} catch (error) {
|
|
227
|
+
message = 'Invalid configuration';
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
this.results.optional.push({
|
|
232
|
+
name: 'MCP Servers',
|
|
233
|
+
status: mcpConfigured,
|
|
234
|
+
message: message
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const hasEnv = fs.existsSync(envPath);
|
|
238
|
+
this.results.optional.push({
|
|
239
|
+
name: 'MCP Environment',
|
|
240
|
+
status: hasEnv,
|
|
241
|
+
message: hasEnv ? 'Environment file exists' : 'No .env file'
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
if (!mcpConfigured) {
|
|
245
|
+
this.results.nextSteps.push('Run: autopm mcp check (to see MCP requirements)');
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Check Git repository
|
|
251
|
+
*/
|
|
252
|
+
checkGitRepository() {
|
|
253
|
+
try {
|
|
254
|
+
execSync('git rev-parse --is-inside-work-tree', {
|
|
255
|
+
stdio: 'pipe',
|
|
256
|
+
cwd: this.projectRoot
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
this.results.essential.push({
|
|
260
|
+
name: 'Git repository',
|
|
261
|
+
status: true,
|
|
262
|
+
message: 'Initialized'
|
|
263
|
+
});
|
|
264
|
+
} catch (error) {
|
|
265
|
+
this.results.essential.push({
|
|
266
|
+
name: 'Git repository',
|
|
267
|
+
status: false,
|
|
268
|
+
message: 'Not initialized'
|
|
269
|
+
});
|
|
270
|
+
this.results.nextSteps.push('Run: git init');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Check Git hooks installation
|
|
276
|
+
*/
|
|
277
|
+
checkGitHooks() {
|
|
278
|
+
const hooksDir = path.join(this.projectRoot, '.git', 'hooks');
|
|
279
|
+
const preCommit = path.join(hooksDir, 'pre-commit');
|
|
280
|
+
const prePush = path.join(hooksDir, 'pre-push');
|
|
281
|
+
|
|
282
|
+
const hasPreCommit = fs.existsSync(preCommit);
|
|
283
|
+
const hasPrePush = fs.existsSync(prePush);
|
|
284
|
+
|
|
285
|
+
this.results.optional.push({
|
|
286
|
+
name: 'Git hooks',
|
|
287
|
+
status: hasPreCommit || hasPrePush,
|
|
288
|
+
message: hasPreCommit && hasPrePush
|
|
289
|
+
? 'Installed'
|
|
290
|
+
: hasPreCommit || hasPrePush
|
|
291
|
+
? 'Partially installed'
|
|
292
|
+
: 'Not installed'
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Check Node.js version
|
|
298
|
+
*/
|
|
299
|
+
checkNodeVersion() {
|
|
300
|
+
const version = process.version;
|
|
301
|
+
const major = parseInt(version.split('.')[0].substring(1));
|
|
302
|
+
const isSupported = major >= 18;
|
|
303
|
+
|
|
304
|
+
this.results.optional.push({
|
|
305
|
+
name: 'Node.js version',
|
|
306
|
+
status: isSupported,
|
|
307
|
+
message: isSupported
|
|
308
|
+
? `${version} (supported)`
|
|
309
|
+
: `${version} (upgrade recommended)`
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
if (!isSupported) {
|
|
313
|
+
this.results.nextSteps.push('Upgrade Node.js to v18 or higher');
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Display check results
|
|
319
|
+
*/
|
|
320
|
+
displayResults() {
|
|
321
|
+
console.log('š Essential Components:\n');
|
|
322
|
+
|
|
323
|
+
this.results.essential.forEach(check => {
|
|
324
|
+
const icon = check.status ? 'ā
' : 'ā';
|
|
325
|
+
const status = check.status ? 'OK' : 'MISSING';
|
|
326
|
+
console.log(`${icon} ${check.name.padEnd(25)} ${status.padEnd(10)} ${check.message}`);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
if (this.results.optional.length > 0) {
|
|
330
|
+
console.log('\nš§ Optional Components:\n');
|
|
331
|
+
|
|
332
|
+
this.results.optional.forEach(check => {
|
|
333
|
+
const icon = check.status ? 'ā
' : 'āŖ';
|
|
334
|
+
console.log(`${icon} ${check.name.padEnd(25)} ${check.message}`);
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
console.log('\n' + 'ā'.repeat(70) + '\n');
|
|
339
|
+
|
|
340
|
+
// Overall status
|
|
341
|
+
const essentialPassed = this.results.essential.every(c => c.status);
|
|
342
|
+
|
|
343
|
+
if (essentialPassed) {
|
|
344
|
+
console.log('ā
All essential components are configured!\n');
|
|
345
|
+
} else {
|
|
346
|
+
console.log('ā ļø Some essential components need configuration\n');
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Display next steps
|
|
352
|
+
*/
|
|
353
|
+
displayNextSteps() {
|
|
354
|
+
if (this.results.nextSteps.length === 0) {
|
|
355
|
+
console.log('š Ready to start! Try:\n');
|
|
356
|
+
console.log(' claude --dangerously-skip-permissions .');
|
|
357
|
+
console.log(' /pm:validate\n');
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
console.log('š Next Steps:\n');
|
|
362
|
+
|
|
363
|
+
this.results.nextSteps.forEach((step, index) => {
|
|
364
|
+
console.log(` ${index + 1}. ${step}`);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
console.log('\nš” Quick Setup:\n');
|
|
368
|
+
console.log(' autopm config show # View current configuration');
|
|
369
|
+
console.log(' autopm config validate # Validate settings');
|
|
370
|
+
console.log(' autopm mcp check # Check MCP requirements');
|
|
371
|
+
console.log(' autopm --help # See all commands\n');
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Run if executed directly
|
|
376
|
+
if (require.main === module) {
|
|
377
|
+
const checker = new PostInstallChecker();
|
|
378
|
+
checker.runAllChecks().catch(error => {
|
|
379
|
+
console.error('Error during configuration check:', error.message);
|
|
380
|
+
process.exit(1);
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
module.exports = PostInstallChecker;
|