@axiomatic-labs/claudeflow 2.9.73 → 2.9.75
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/lib/install.js +136 -3
- package/package.json +1 -1
package/lib/install.js
CHANGED
|
@@ -52,11 +52,11 @@ async function run() {
|
|
|
52
52
|
fs.writeFileSync(tmpZip, zipBuffer);
|
|
53
53
|
fs.mkdirSync(tmpExtract, { recursive: true });
|
|
54
54
|
|
|
55
|
+
const cwd = process.cwd();
|
|
56
|
+
|
|
55
57
|
try {
|
|
56
58
|
ui.step('Extracting template files...');
|
|
57
59
|
execSync(`unzip -o "${tmpZip}" -d "${tmpExtract}"`, { stdio: 'pipe' });
|
|
58
|
-
|
|
59
|
-
const cwd = process.cwd();
|
|
60
60
|
const srcClaude = path.join(tmpExtract, '.claude');
|
|
61
61
|
|
|
62
62
|
// Copy settings.json
|
|
@@ -116,8 +116,10 @@ async function run() {
|
|
|
116
116
|
fs.rmSync(tmpExtract, { recursive: true, force: true });
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// Install analysis tools (ast-grep + Serena MCP)
|
|
120
|
+
installAnalysisTools();
|
|
121
|
+
|
|
119
122
|
// Count installed items
|
|
120
|
-
const cwd = process.cwd();
|
|
121
123
|
const skillsDir = path.join(cwd, '.claude', 'skills');
|
|
122
124
|
let skillCount = 0;
|
|
123
125
|
try {
|
|
@@ -216,6 +218,137 @@ function showGettingStarted(cwd) {
|
|
|
216
218
|
console.log('');
|
|
217
219
|
}
|
|
218
220
|
|
|
221
|
+
// Install ast-grep CLI, uv, and Serena MCP for enhanced code analysis.
|
|
222
|
+
// All steps are best-effort — failures warn but never block the install.
|
|
223
|
+
function installAnalysisTools() {
|
|
224
|
+
console.log('');
|
|
225
|
+
ui.step('Setting up analysis tools...');
|
|
226
|
+
|
|
227
|
+
// 1. ast-grep CLI
|
|
228
|
+
const hasAstGrep = commandExists('sg');
|
|
229
|
+
if (hasAstGrep) {
|
|
230
|
+
ui.success('ast-grep CLI already installed');
|
|
231
|
+
} else {
|
|
232
|
+
ui.step('Installing ast-grep CLI...');
|
|
233
|
+
try {
|
|
234
|
+
execSync('npm install -g @ast-grep/cli', { stdio: 'pipe', timeout: 60000 });
|
|
235
|
+
ui.success('ast-grep CLI installed');
|
|
236
|
+
} catch {
|
|
237
|
+
ui.warn('ast-grep install failed — code exploration will use Grep fallback');
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// 2. uv (required by Serena)
|
|
242
|
+
let hasUv = commandExists('uv');
|
|
243
|
+
if (hasUv) {
|
|
244
|
+
ui.success('uv already installed');
|
|
245
|
+
} else {
|
|
246
|
+
ui.step('Installing uv (Python package manager)...');
|
|
247
|
+
try {
|
|
248
|
+
if (process.platform === 'win32') {
|
|
249
|
+
execSync('powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"', {
|
|
250
|
+
stdio: 'pipe',
|
|
251
|
+
timeout: 60000,
|
|
252
|
+
});
|
|
253
|
+
} else {
|
|
254
|
+
execSync('curl -LsSf https://astral.sh/uv/install.sh | sh', {
|
|
255
|
+
stdio: 'pipe',
|
|
256
|
+
timeout: 60000,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
// uv installs to ~/.local/bin or ~/.cargo/bin — check both
|
|
260
|
+
hasUv = commandExists('uv') || commandExists(path.join(homedir(), '.local', 'bin', 'uv'));
|
|
261
|
+
if (hasUv) {
|
|
262
|
+
ui.success('uv installed');
|
|
263
|
+
} else {
|
|
264
|
+
ui.warn('uv installed but not in PATH — restart your terminal before running init/update');
|
|
265
|
+
}
|
|
266
|
+
} catch {
|
|
267
|
+
ui.warn('uv install failed — Serena MCP will not be available');
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// 3. Serena MCP
|
|
272
|
+
if (hasUv) {
|
|
273
|
+
let serenaConfigured = false;
|
|
274
|
+
try {
|
|
275
|
+
const mcpList = execSync('claude mcp list', { stdio: 'pipe', encoding: 'utf8', timeout: 10000 });
|
|
276
|
+
serenaConfigured = mcpList.includes('serena');
|
|
277
|
+
} catch {
|
|
278
|
+
// claude CLI not available or mcp list failed — skip Serena
|
|
279
|
+
ui.warn('Could not check MCP servers — Serena setup skipped');
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (serenaConfigured) {
|
|
284
|
+
ui.success('Serena MCP already configured');
|
|
285
|
+
} else {
|
|
286
|
+
ui.step('Adding Serena MCP for semantic code analysis...');
|
|
287
|
+
try {
|
|
288
|
+
const projectPath = process.cwd();
|
|
289
|
+
const uvBin = resolveUvBin();
|
|
290
|
+
execSync(
|
|
291
|
+
`claude mcp add serena -- ${uvBin} -p 3.13 --from git+https://github.com/oraios/serena serena start-mcp-server --context claude-code --project "${projectPath}"`,
|
|
292
|
+
{ stdio: 'pipe', timeout: 30000 }
|
|
293
|
+
);
|
|
294
|
+
ui.success('Serena MCP configured');
|
|
295
|
+
} catch {
|
|
296
|
+
ui.warn('Serena MCP setup failed — code exploration will use Grep fallback');
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// 4. context7 MCP (library documentation for research)
|
|
302
|
+
let context7Configured = false;
|
|
303
|
+
try {
|
|
304
|
+
const mcpList = execSync('claude mcp list', { stdio: 'pipe', encoding: 'utf8', timeout: 10000 });
|
|
305
|
+
context7Configured = mcpList.includes('context7');
|
|
306
|
+
} catch {}
|
|
307
|
+
|
|
308
|
+
if (context7Configured) {
|
|
309
|
+
ui.success('context7 MCP already configured');
|
|
310
|
+
} else {
|
|
311
|
+
ui.step('Adding context7 MCP for library documentation...');
|
|
312
|
+
try {
|
|
313
|
+
execSync('claude mcp add context7 -- npx -y @upstash/context7-mcp@latest', {
|
|
314
|
+
stdio: 'pipe',
|
|
315
|
+
timeout: 30000,
|
|
316
|
+
});
|
|
317
|
+
ui.success('context7 MCP configured');
|
|
318
|
+
} catch {
|
|
319
|
+
ui.warn('context7 setup failed — research will use WebSearch fallback');
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Check if a command exists in PATH
|
|
325
|
+
function commandExists(cmd) {
|
|
326
|
+
try {
|
|
327
|
+
const check = process.platform === 'win32' ? `where "${cmd}"` : `command -v "${cmd}"`;
|
|
328
|
+
execSync(check, { stdio: 'pipe' });
|
|
329
|
+
return true;
|
|
330
|
+
} catch {
|
|
331
|
+
return false;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Resolve uv binary path — may be in PATH or in common install locations
|
|
336
|
+
function resolveUvBin() {
|
|
337
|
+
if (commandExists('uv')) return 'uv';
|
|
338
|
+
const candidates = [
|
|
339
|
+
path.join(homedir(), '.local', 'bin', 'uv'),
|
|
340
|
+
path.join(homedir(), '.cargo', 'bin', 'uv'),
|
|
341
|
+
];
|
|
342
|
+
for (const p of candidates) {
|
|
343
|
+
if (fs.existsSync(p)) return p;
|
|
344
|
+
}
|
|
345
|
+
return 'uv'; // fallback — let it fail with a clear error
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function homedir() {
|
|
349
|
+
return require('os').homedir();
|
|
350
|
+
}
|
|
351
|
+
|
|
219
352
|
// Recursively copy a directory, creating parents as needed
|
|
220
353
|
function copyDirSync(src, dst) {
|
|
221
354
|
fs.mkdirSync(dst, { recursive: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiomatic-labs/claudeflow",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.75",
|
|
4
4
|
"description": "Claudeflow — AI-powered development toolkit for Claude Code. Skills, agents, hooks, and quality gates that ship production apps.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claudeflow": "./bin/cli.js"
|