cskit-cli 1.0.2 → 1.0.5
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/package.json +1 -1
- package/src/commands/init.js +97 -9
package/package.json
CHANGED
package/src/commands/init.js
CHANGED
|
@@ -66,36 +66,121 @@ async function setupPythonEnv(projectDir, spinner) {
|
|
|
66
66
|
const venvPath = path.join(libPythonDir, '.venv');
|
|
67
67
|
|
|
68
68
|
try {
|
|
69
|
-
// Check if Python 3 is available
|
|
69
|
+
// Check if Python 3 is available and get version
|
|
70
|
+
let pythonVersion;
|
|
70
71
|
try {
|
|
71
|
-
execSync('python3 --version', { stdio: 'pipe' });
|
|
72
|
+
pythonVersion = execSync('python3 --version', { stdio: 'pipe' }).toString().trim();
|
|
73
|
+
spinner.text = `Found ${pythonVersion}`;
|
|
72
74
|
} catch {
|
|
73
75
|
spinner.warn('Python 3 not found, skipping venv setup');
|
|
74
76
|
return { success: true, skipped: true, reason: 'python3 not found' };
|
|
75
77
|
}
|
|
76
78
|
|
|
79
|
+
// Check minimum version (3.9+)
|
|
80
|
+
const versionMatch = pythonVersion.match(/Python (\d+)\.(\d+)/);
|
|
81
|
+
if (versionMatch) {
|
|
82
|
+
const [, major, minor] = versionMatch.map(Number);
|
|
83
|
+
if (major < 3 || (major === 3 && minor < 9)) {
|
|
84
|
+
spinner.warn(`Python ${major}.${minor} found, requires 3.9+`);
|
|
85
|
+
return { success: true, skipped: true, reason: `Python ${major}.${minor} requires 3.9+` };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
77
89
|
// Create venv if not exists
|
|
78
90
|
if (!fs.existsSync(venvPath)) {
|
|
79
91
|
spinner.text = 'Creating virtual environment...';
|
|
80
92
|
execSync(`python3 -m venv "${venvPath}"`, { stdio: 'pipe', cwd: libPythonDir });
|
|
81
93
|
}
|
|
82
94
|
|
|
83
|
-
// Install requirements
|
|
95
|
+
// Install requirements with error handling
|
|
84
96
|
spinner.text = 'Installing Python packages...';
|
|
85
97
|
const pipPath = path.join(venvPath, 'bin', 'pip');
|
|
86
|
-
execSync(`"${pipPath}" install -r requirements.txt -q`, {
|
|
87
|
-
stdio: 'pipe',
|
|
88
|
-
cwd: libPythonDir
|
|
89
|
-
});
|
|
90
98
|
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
try {
|
|
100
|
+
execSync(`"${pipPath}" install -r requirements.txt -q`, {
|
|
101
|
+
stdio: 'pipe',
|
|
102
|
+
cwd: libPythonDir
|
|
103
|
+
});
|
|
104
|
+
spinner.succeed(`Python environment ready (${pythonVersion})`);
|
|
105
|
+
return { success: true, version: pythonVersion };
|
|
106
|
+
} catch (pipError) {
|
|
107
|
+
// Try installing without optional packages
|
|
108
|
+
spinner.text = 'Retrying with core packages...';
|
|
109
|
+
try {
|
|
110
|
+
execSync(`"${pipPath}" install numpy pandas scipy pydantic rich click -q`, {
|
|
111
|
+
stdio: 'pipe',
|
|
112
|
+
cwd: libPythonDir
|
|
113
|
+
});
|
|
114
|
+
spinner.warn('Partial install - some optional packages failed');
|
|
115
|
+
return { success: true, partial: true, version: pythonVersion };
|
|
116
|
+
} catch {
|
|
117
|
+
throw pipError;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
93
120
|
} catch (error) {
|
|
94
121
|
spinner.warn(`Python setup failed: ${error.message}`);
|
|
95
122
|
return { success: false, error: error.message };
|
|
96
123
|
}
|
|
97
124
|
}
|
|
98
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Setup CSK in Claude Code directories
|
|
128
|
+
*/
|
|
129
|
+
async function setupCommands(projectDir, spinner) {
|
|
130
|
+
spinner.start('Setting up CSK for Claude Code...');
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
const claudeDir = path.join(projectDir, '.claude');
|
|
134
|
+
ensureDir(claudeDir);
|
|
135
|
+
|
|
136
|
+
// Map: source → destination
|
|
137
|
+
const mappings = [
|
|
138
|
+
{ src: 'src/commands', dest: '.claude/commands' },
|
|
139
|
+
{ src: 'core', dest: '.claude/skills/csk/core' },
|
|
140
|
+
{ src: 'domains', dest: '.claude/skills/csk/domains' },
|
|
141
|
+
{ src: 'industries', dest: '.claude/skills/csk/industries' },
|
|
142
|
+
{ src: 'lib', dest: '.claude/skills/csk/lib' }
|
|
143
|
+
];
|
|
144
|
+
|
|
145
|
+
let copied = 0;
|
|
146
|
+
for (const { src, dest } of mappings) {
|
|
147
|
+
const srcPath = path.join(projectDir, src);
|
|
148
|
+
const destPath = path.join(projectDir, dest);
|
|
149
|
+
|
|
150
|
+
if (fs.existsSync(srcPath)) {
|
|
151
|
+
ensureDir(destPath);
|
|
152
|
+
copyDirRecursive(srcPath, destPath);
|
|
153
|
+
copied++;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
spinner.succeed(`CSK installed to .claude/ (${copied} modules)`);
|
|
158
|
+
return { success: true };
|
|
159
|
+
} catch (error) {
|
|
160
|
+
spinner.warn(`CSK setup failed: ${error.message}`);
|
|
161
|
+
return { success: false, error: error.message };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Recursively copy directory
|
|
167
|
+
*/
|
|
168
|
+
function copyDirRecursive(src, dest) {
|
|
169
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
170
|
+
|
|
171
|
+
for (const entry of entries) {
|
|
172
|
+
const srcPath = path.join(src, entry.name);
|
|
173
|
+
const destPath = path.join(dest, entry.name);
|
|
174
|
+
|
|
175
|
+
if (entry.isDirectory()) {
|
|
176
|
+
ensureDir(destPath);
|
|
177
|
+
copyDirRecursive(srcPath, destPath);
|
|
178
|
+
} else {
|
|
179
|
+
fs.copyFileSync(srcPath, destPath);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
99
184
|
/**
|
|
100
185
|
* Main init command handler
|
|
101
186
|
*/
|
|
@@ -254,6 +339,9 @@ async function initCommand(options) {
|
|
|
254
339
|
console.log('');
|
|
255
340
|
const pythonResult = await setupPythonEnv(projectDir, spinner);
|
|
256
341
|
|
|
342
|
+
// Copy commands to .claude/commands/
|
|
343
|
+
await setupCommands(projectDir, spinner);
|
|
344
|
+
|
|
257
345
|
// Success message
|
|
258
346
|
const ver = selectedVersion.replace(/^v/, '');
|
|
259
347
|
console.log(chalk.green(`\n ✓ CSK v${ver} ${isUpdate ? 'updated' : 'installed'} successfully!\n`));
|