@infinitedusky/indusk-mcp 1.3.0 → 1.4.0

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.
@@ -6,3 +6,4 @@ export declare function extensionsAdd(projectRoot: string, name: string, from: s
6
6
  export declare function extensionsRemove(projectRoot: string, names: string[]): Promise<void>;
7
7
  export declare function extensionsUpdate(projectRoot: string, names?: string[]): Promise<void>;
8
8
  export declare function extensionsSuggest(projectRoot: string): Promise<void>;
9
+ export declare function autoEnableExtensions(projectRoot: string): Promise<void>;
@@ -323,6 +323,7 @@ export async function extensionsUpdate(projectRoot, names) {
323
323
  }
324
324
  else {
325
325
  console.info(`\n${updated} extension(s) updated.`);
326
+ console.info("\n⚠ Restart Claude Code to load the updated extensions.");
326
327
  }
327
328
  }
328
329
  export async function extensionsSuggest(projectRoot) {
@@ -361,6 +362,20 @@ export async function extensionsSuggest(projectRoot) {
361
362
  }
362
363
  }
363
364
  }
365
+ if (ext.detect.mcp_server) {
366
+ try {
367
+ const mcpPath = join(projectRoot, ".mcp.json");
368
+ if (existsSync(mcpPath)) {
369
+ const mcp = JSON.parse(readFileSync(mcpPath, "utf-8"));
370
+ if (mcp.mcpServers?.[ext.detect.mcp_server]) {
371
+ suggestions.push({ name: ext.name, reason: `${ext.detect.mcp_server} in .mcp.json` });
372
+ }
373
+ }
374
+ }
375
+ catch {
376
+ // ignore
377
+ }
378
+ }
364
379
  }
365
380
  if (suggestions.length === 0) {
366
381
  console.info("No extension suggestions — all detected extensions are already enabled.");
@@ -372,6 +387,68 @@ export async function extensionsSuggest(projectRoot) {
372
387
  }
373
388
  console.info(`\nEnable with: extensions enable ${suggestions.map((s) => s.name).join(" ")}`);
374
389
  }
390
+ export async function autoEnableExtensions(projectRoot) {
391
+ const builtins = getBuiltinExtensions();
392
+ let enabled = 0;
393
+ for (const ext of builtins) {
394
+ if (isEnabled(projectRoot, ext.name))
395
+ continue;
396
+ if (!ext.detect)
397
+ continue;
398
+ let detected = false;
399
+ let reason = "";
400
+ if (ext.detect.file && existsSync(join(projectRoot, ext.detect.file))) {
401
+ detected = true;
402
+ reason = `${ext.detect.file} found`;
403
+ }
404
+ if (!detected && ext.detect.file_pattern) {
405
+ const matches = globSync(ext.detect.file_pattern, { cwd: projectRoot, maxDepth: 3 });
406
+ if (matches.length > 0) {
407
+ detected = true;
408
+ reason = `${ext.detect.file_pattern} found`;
409
+ }
410
+ }
411
+ if (!detected && (ext.detect.dependency || ext.detect.devDependency)) {
412
+ const pkgPath = join(projectRoot, "package.json");
413
+ if (existsSync(pkgPath)) {
414
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
415
+ const deps = pkg.dependencies ?? {};
416
+ const devDeps = pkg.devDependencies ?? {};
417
+ if (ext.detect.dependency && deps[ext.detect.dependency]) {
418
+ detected = true;
419
+ reason = `${ext.detect.dependency} in dependencies`;
420
+ }
421
+ else if (ext.detect.devDependency && devDeps[ext.detect.devDependency]) {
422
+ detected = true;
423
+ reason = `${ext.detect.devDependency} in devDependencies`;
424
+ }
425
+ }
426
+ }
427
+ if (!detected && ext.detect.mcp_server) {
428
+ try {
429
+ const mcpPath = join(projectRoot, ".mcp.json");
430
+ if (existsSync(mcpPath)) {
431
+ const mcp = JSON.parse(readFileSync(mcpPath, "utf-8"));
432
+ if (mcp.mcpServers?.[ext.detect.mcp_server]) {
433
+ detected = true;
434
+ reason = `${ext.detect.mcp_server} in .mcp.json`;
435
+ }
436
+ }
437
+ }
438
+ catch {
439
+ // ignore parse errors
440
+ }
441
+ }
442
+ if (detected) {
443
+ await extensionsEnable(projectRoot, [ext.name]);
444
+ console.info(` (detected: ${reason})`);
445
+ enabled++;
446
+ }
447
+ }
448
+ if (enabled === 0) {
449
+ console.info(" No new extensions detected.");
450
+ }
451
+ }
375
452
  // --- Helpers ---
376
453
  function runHook(projectRoot, name, hook) {
377
454
  const extPath = join(extensionsDir(projectRoot), `${name}.json`);
@@ -294,15 +294,15 @@ export async function init(projectRoot, options = {}) {
294
294
  console.info(" skipped (CGC not available)");
295
295
  }
296
296
  }
297
- // 11. Suggest extensions
297
+ // 11. Auto-enable detected extensions
298
298
  console.info("\n[Extensions]");
299
- const { extensionsSuggest } = await import("./extensions.js");
300
- await extensionsSuggest(projectRoot);
299
+ const { autoEnableExtensions } = await import("./extensions.js");
300
+ await autoEnableExtensions(projectRoot);
301
301
  // Summary
302
302
  console.info("\nDone!");
303
+ console.info("\n⚠ Restart Claude Code to load the updated MCP server and skills.");
303
304
  console.info("\nNext steps:");
304
- console.info(" 1. Edit CLAUDE.md with your project details");
305
- console.info(" 2. Enable extensions: extensions enable falkordb cgc typescript");
306
- console.info(" 3. Start a Claude Code session — MCP tools will be available");
307
- console.info(" 4. Start planning: /plan your-first-feature");
305
+ console.info(" 1. Restart Claude Code");
306
+ console.info(" 2. Edit CLAUDE.md with your project details");
307
+ console.info(" 3. Start planning: /plan your-first-feature");
308
308
  }
@@ -3,6 +3,7 @@ export interface DetectRule {
3
3
  file_pattern?: string;
4
4
  dependency?: string;
5
5
  devDependency?: string;
6
+ mcp_server?: string;
6
7
  }
7
8
  export interface HealthCheck {
8
9
  name: string;
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "dash0",
3
+ "description": "Dash0 observability — query logs, traces, and metrics from your OpenTelemetry data via MCP",
4
+ "provides": {
5
+ "skill": true,
6
+ "health_checks": [
7
+ {
8
+ "name": "dash0-mcp-configured",
9
+ "command": "node -e \"const m=JSON.parse(require('fs').readFileSync('.mcp.json','utf-8'));process.exit(m.mcpServers?.dash0 ? 0 : 1)\""
10
+ }
11
+ ]
12
+ },
13
+ "hooks": {
14
+ "on_init": "echo 'Dash0 extension enabled. Configure the Dash0 MCP server in .mcp.json if not already present.'"
15
+ },
16
+ "detect": {
17
+ "mcp_server": "dash0"
18
+ }
19
+ }
@@ -0,0 +1,70 @@
1
+ # Dash0 Observability
2
+
3
+ Dash0 provides access to your OpenTelemetry data — logs, traces, and metrics — directly from Claude Code via its MCP server.
4
+
5
+ ## When to Use Dash0
6
+
7
+ - **Test failures**: query recent traces to see what happened in the service during the test
8
+ - **Debugging production issues**: search logs for errors, find related traces by trace ID
9
+ - **Performance investigation**: query metrics (PromQL) to check latency, throughput, error rates
10
+ - **Deployment verification**: check traces and error rates after deploying a change
11
+ - **During /work verification**: if a verification step involves checking service health, query Dash0
12
+
13
+ ## Available Tools (from Dash0 MCP server)
14
+
15
+ Dash0's MCP server provides 23 tools. The most useful for development:
16
+
17
+ | Tool | When |
18
+ |------|------|
19
+ | Search logs | Find errors, warnings, or specific log messages |
20
+ | Search traces | Find request traces by service, endpoint, status, or trace ID |
21
+ | Query metrics (PromQL) | Check latency percentiles, error rates, throughput |
22
+ | List services | See what services are sending telemetry |
23
+ | Get trace details | Deep-dive into a specific trace's spans |
24
+
25
+ ## Setup
26
+
27
+ 1. Sign up at [dash0.com](https://www.dash0.com)
28
+ 2. Get your API token from the Dash0 dashboard
29
+ 3. Add the Dash0 MCP server to your `.mcp.json`:
30
+
31
+ ```json
32
+ {
33
+ "mcpServers": {
34
+ "dash0": {
35
+ "command": "npx",
36
+ "args": ["@dash0hq/mcp-server"],
37
+ "env": {
38
+ "DASH0_API_TOKEN": "your-token-here",
39
+ "DASH0_DATASET": "default"
40
+ }
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ 4. Enable the extension: `extensions enable dash0`
47
+
48
+ ## Workflow Integration
49
+
50
+ ### During verification
51
+ When a verification step involves checking that a service is working correctly, don't just check the HTTP status — query Dash0 for:
52
+ - Recent error traces for the service
53
+ - Error rate metrics before and after your change
54
+ - Log entries matching the feature you modified
55
+
56
+ ### During debugging
57
+ When something fails:
58
+ 1. Check logs first — search for errors in the relevant service
59
+ 2. Find the trace — use the trace ID from logs to get the full request flow
60
+ 3. Check metrics — is this a new problem or an existing one? Compare error rates over time.
61
+
62
+ ### During retrospective
63
+ Query Dash0 for metrics that show the impact of the plan:
64
+ - Error rate before vs after
65
+ - Latency changes
66
+ - New services or endpoints that appeared
67
+
68
+ ## Connecting to OpenTelemetry
69
+
70
+ Dash0 ingests standard OpenTelemetry data. If your services already export OTLP telemetry, point the OTLP exporter at Dash0's endpoint. See [Dash0 docs](https://www.dash0.com/documentation/dash0) for setup per language.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infinitedusky/indusk-mcp",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "InDusk development system — skills, MCP tools, and CLI for structured AI-assisted development",
5
5
  "type": "module",
6
6
  "files": [