cskit-cli 1.0.3 → 1.0.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cskit-cli",
3
- "version": "1.0.3",
3
+ "version": "1.0.6",
4
4
  "description": "Content Suite Kit CLI - Download and manage CSK skills from private repository",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -66,30 +66,57 @@ 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
- spinner.succeed('Python environment ready');
92
- return { success: true };
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 };
@@ -97,42 +124,25 @@ async function setupPythonEnv(projectDir, spinner) {
97
124
  }
98
125
 
99
126
  /**
100
- * Setup CSK in Claude Code directories
127
+ * Remap source paths to .claude/ destinations
128
+ * Downloads directly to Claude Code directories
101
129
  */
102
- async function setupCommands(projectDir, spinner) {
103
- spinner.start('Setting up CSK for Claude Code...');
104
-
105
- try {
106
- const claudeDir = path.join(projectDir, '.claude');
107
- ensureDir(claudeDir);
108
-
109
- // Map: source → destination
110
- const mappings = [
111
- { src: 'src/commands', dest: '.claude/commands' },
112
- { src: 'core', dest: '.claude/skills/csk/core' },
113
- { src: 'domains', dest: '.claude/skills/csk/domains' },
114
- { src: 'industries', dest: '.claude/skills/csk/industries' },
115
- { src: 'lib', dest: '.claude/skills/csk/lib' }
116
- ];
117
-
118
- let copied = 0;
119
- for (const { src, dest } of mappings) {
120
- const srcPath = path.join(projectDir, src);
121
- const destPath = path.join(projectDir, dest);
122
-
123
- if (fs.existsSync(srcPath)) {
124
- ensureDir(destPath);
125
- copyDirRecursive(srcPath, destPath);
126
- copied++;
127
- }
130
+ function remapPath(filePath) {
131
+ const mappings = [
132
+ { from: 'src/commands/', to: '.claude/commands/' },
133
+ { from: 'core/', to: '.claude/skills/csk/core/' },
134
+ { from: 'domains/', to: '.claude/skills/csk/domains/' },
135
+ { from: 'industries/', to: '.claude/skills/csk/industries/' }
136
+ ];
137
+
138
+ for (const { from, to } of mappings) {
139
+ if (filePath.startsWith(from)) {
140
+ return filePath.replace(from, to);
128
141
  }
129
-
130
- spinner.succeed(`CSK installed to .claude/ (${copied} modules)`);
131
- return { success: true };
132
- } catch (error) {
133
- spinner.warn(`CSK setup failed: ${error.message}`);
134
- return { success: false, error: error.message };
135
142
  }
143
+
144
+ // Keep other files as-is (lib/, cli/, config/, etc.)
145
+ return filePath;
136
146
  }
137
147
 
138
148
  /**
@@ -250,8 +260,8 @@ async function initCommand(options) {
250
260
 
251
261
  for (let i = 0; i < files.length; i++) {
252
262
  const file = files[i];
253
- const targetPath = path.join(projectDir, file.path);
254
- const relativePath = file.path;
263
+ const relativePath = remapPath(file.path);
264
+ const targetPath = path.join(projectDir, relativePath);
255
265
 
256
266
  // Update progress bar
257
267
  process.stdout.write(`\r ${progressBar(i + 1, files.length)} ${chalk.dim(`(${i + 1}/${files.length})`)}`);
@@ -312,8 +322,8 @@ async function initCommand(options) {
312
322
  console.log('');
313
323
  const pythonResult = await setupPythonEnv(projectDir, spinner);
314
324
 
315
- // Copy commands to .claude/commands/
316
- await setupCommands(projectDir, spinner);
325
+ // CSK files already downloaded to .claude/ (no copy needed)
326
+ spinner.succeed('CSK installed to .claude/');
317
327
 
318
328
  // Success message
319
329
  const ver = selectedVersion.replace(/^v/, '');