@magic-ingredients/tiny-brain-local 0.21.3 → 0.22.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.
Files changed (38) hide show
  1. package/dist/core/mcp-server.d.ts +3 -5
  2. package/dist/core/mcp-server.d.ts.map +1 -1
  3. package/dist/core/mcp-server.js +17 -38
  4. package/dist/index.d.ts +0 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -1
  7. package/dist/prompts/rules/rules.prompt.d.ts.map +1 -1
  8. package/dist/prompts/rules/rules.prompt.js +1 -7
  9. package/dist/services/analyse-service.js +1 -1
  10. package/dist/services/credential-storage.service.d.ts +5 -44
  11. package/dist/services/credential-storage.service.d.ts.map +1 -1
  12. package/dist/services/credential-storage.service.js +4 -197
  13. package/dist/services/remote/auth-token-service.d.ts +10 -47
  14. package/dist/services/remote/auth-token-service.d.ts.map +1 -1
  15. package/dist/services/remote/auth-token-service.js +13 -188
  16. package/dist/services/repo-service.d.ts.map +1 -1
  17. package/dist/services/repo-service.js +3 -0
  18. package/dist/tools/config/config.tool.d.ts.map +1 -1
  19. package/dist/tools/config/config.tool.js +18 -0
  20. package/dist/tools/persona/as.tool.d.ts +0 -12
  21. package/dist/tools/persona/as.tool.d.ts.map +1 -1
  22. package/dist/tools/persona/as.tool.js +13 -199
  23. package/dist/tools/plan/plan.tool.d.ts.map +1 -1
  24. package/dist/tools/plan/plan.tool.js +26 -38
  25. package/dist/tools/quality/quality.tool.js +4 -4
  26. package/dist/tools/recommendations/recommendations.tool.d.ts.map +1 -1
  27. package/dist/tools/recommendations/recommendations.tool.js +11 -1
  28. package/dist/tools/tool-registry.d.ts.map +1 -1
  29. package/dist/tools/tool-registry.js +0 -4
  30. package/dist/types/local-context.d.ts +0 -2
  31. package/dist/types/local-context.d.ts.map +1 -1
  32. package/package.json +2 -2
  33. package/dist/services/dashboard-launcher.service.d.ts +0 -21
  34. package/dist/services/dashboard-launcher.service.d.ts.map +0 -1
  35. package/dist/services/dashboard-launcher.service.js +0 -33
  36. package/dist/tools/dashboard/dashboard.tool.d.ts +0 -15
  37. package/dist/tools/dashboard/dashboard.tool.d.ts.map +0 -1
  38. package/dist/tools/dashboard/dashboard.tool.js +0 -81
@@ -2,7 +2,7 @@ import { z } from 'zod';
2
2
  import { createSuccessResult, createErrorResult } from '../index.js';
3
3
  import { PlanningService, RepoConfigService, ADRService } from '@magic-ingredients/tiny-brain-core';
4
4
  import { toKebabCase } from '@magic-ingredients/tiny-brain-core';
5
- import { DashboardLauncher } from '../../services/dashboard-launcher.service.js';
5
+ import { execSync } from 'node:child_process';
6
6
  import { promises as fs } from 'fs';
7
7
  import path from 'path';
8
8
  import { exec } from 'child_process';
@@ -78,7 +78,7 @@ const PlanArgsSchema = z.object({
78
78
  });
79
79
  // Dashboard is now managed by MCP server and auto-started on initialization
80
80
  // We keep a reference for manual control
81
- let dashboardLauncher = null;
81
+ // Dashboard runs as standalone process — managed via CLI
82
82
  /**
83
83
  * Detect the repository root from the current working directory
84
84
  * Uses process.cwd() which reflects Claude Code's working directory
@@ -786,37 +786,18 @@ export class PlanTool {
786
786
  return createErrorResult(`Failed to list plans: ${error instanceof Error ? error.message : 'Unknown error'}`);
787
787
  }
788
788
  }
789
- static async handleStartDashboard(args, context) {
789
+ static async handleStartDashboard(args, _context) {
790
790
  try {
791
- // Check if dashboard is already running
792
- if (dashboardLauncher && dashboardLauncher.isRunning()) {
793
- return createSuccessResult(`📊 Dashboard is already running at http://localhost:${args.port || 8765}\n\nUse "plan operation=stop-dashboard" to stop it.`);
791
+ const port = Number(args.port) || 8765;
792
+ if (!Number.isInteger(port) || port < 1 || port > 65535) {
793
+ return createErrorResult(`Invalid port: ${args.port}`);
794
794
  }
795
- // Create a new launcher if needed
796
- if (!dashboardLauncher) {
797
- dashboardLauncher = new DashboardLauncher();
798
- }
799
- // Start the dashboard with provided options
800
- const result = await dashboardLauncher.start(context, {
801
- port: args.port || 8765,
802
- autoOpen: args.autoOpen,
795
+ execSync(`npx tiny-brain dashboard start --port ${String(port)} --if-not-running`, {
796
+ encoding: 'utf-8',
797
+ stdio: 'pipe',
798
+ timeout: 10_000,
803
799
  });
804
- const response = [
805
- '🚀 Dashboard started successfully!',
806
- '',
807
- `📊 Dashboard URL: ${result.url}`,
808
- `🔌 Port: ${args.port || 8765}`,
809
- args.autoOpen ? '🌐 Browser will open automatically' : '🔗 Open the URL in your browser',
810
- '',
811
- 'The dashboard provides:',
812
- '• Real-time plan monitoring',
813
- '• Plan management (create, delete)',
814
- '• Persona overview',
815
- '• Auto-refresh on changes',
816
- '',
817
- 'Use "plan operation=stop-dashboard" to stop the dashboard.',
818
- ].join('\n');
819
- return createSuccessResult(response);
800
+ return createSuccessResult(`Dashboard started on port ${port}\nUse "plan operation=stop-dashboard" to stop it.`);
820
801
  }
821
802
  catch (error) {
822
803
  return createErrorResult(`Failed to start dashboard: ${error instanceof Error ? error.message : 'Unknown error'}`);
@@ -824,13 +805,12 @@ export class PlanTool {
824
805
  }
825
806
  static async handleStopDashboard(_args, _context) {
826
807
  try {
827
- if (!dashboardLauncher || !dashboardLauncher.isRunning()) {
828
- return createErrorResult('Dashboard is not running');
829
- }
830
- await dashboardLauncher.stop();
831
- // Clear the singleton instance
832
- dashboardLauncher = null;
833
- return createSuccessResult('✅ Dashboard stopped successfully');
808
+ execSync('npx tiny-brain dashboard stop', {
809
+ encoding: 'utf-8',
810
+ stdio: 'pipe',
811
+ timeout: 10_000,
812
+ });
813
+ return createSuccessResult('Dashboard stopped');
834
814
  }
835
815
  catch (error) {
836
816
  return createErrorResult(`Failed to stop dashboard: ${error instanceof Error ? error.message : 'Unknown error'}`);
@@ -838,7 +818,15 @@ export class PlanTool {
838
818
  }
839
819
  static async handleDashboardStatus(_args, _context) {
840
820
  try {
841
- const isRunning = dashboardLauncher && dashboardLauncher.isRunning();
821
+ const port = 8765;
822
+ let isRunning = false;
823
+ try {
824
+ const res = await fetch(`http://localhost:${port}/health`);
825
+ isRunning = res.ok;
826
+ }
827
+ catch {
828
+ // not running
829
+ }
842
830
  if (isRunning) {
843
831
  const response = [
844
832
  '📊 Dashboard Status: RUNNING',
@@ -58,7 +58,7 @@ export class QualityTool {
58
58
  Persists and retrieves quality analysis results. Analysis is performed by agents; this tool handles storage only.
59
59
 
60
60
  ✅ OPERATIONS:
61
- • save: Persist a quality run to docs/quality/runs/
61
+ • save: Persist a quality run to .tiny-brain/quality/runs/
62
62
  • history: List previous quality runs with summary data
63
63
  • details: Get full details for a specific run by ID
64
64
  • compare: Compare two runs to see new, resolved, and persistent issues
@@ -73,7 +73,7 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
73
73
  💡 WORKFLOW:
74
74
  1. Quality-coordinator agent performs analysis
75
75
  2. Agent calls quality save with score, grade, issues, recommendations
76
- 3. Results stored as markdown in docs/quality/runs/YYYY-MM-DD-quality.md
76
+ 3. Results stored as markdown in .tiny-brain/quality/runs/YYYY-MM-DD-quality.md
77
77
  4. Use history/details to retrieve past runs
78
78
  5. Use plan to generate an improvement roadmap from a run`,
79
79
  inputSchema: {
@@ -466,7 +466,7 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
466
466
  return createErrorResult('planId is required for plan-details operation');
467
467
  }
468
468
  try {
469
- const plansDir = path.join(repositoryRoot, 'docs', 'quality', 'plans');
469
+ const plansDir = path.join(repositoryRoot, '.tiny-brain', 'quality', 'plans');
470
470
  const filePath = path.join(plansDir, `${args.planId}.md`);
471
471
  const content = await fs.readFile(filePath, 'utf-8');
472
472
  // Extract JSON from the Raw Data code block
@@ -534,7 +534,7 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
534
534
  }
535
535
  static async handleRunAnalyzers(args, repositoryRoot) {
536
536
  const runId = args.runId ?? generateRunId();
537
- const runDir = path.join(repositoryRoot, 'docs', 'quality', 'runs', runIdToPath(runId));
537
+ const runDir = path.join(repositoryRoot, '.tiny-brain', 'quality', 'runs', runIdToPath(runId));
538
538
  const outputPath = path.join(runDir, 'analysis.json');
539
539
  const outputDir = path.join(runDir, 'analysers');
540
540
  const detectionService = new AnalyzerDetectionService(repositoryRoot);
@@ -1 +1 @@
1
- {"version":3,"file":"recommendations.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/recommendations/recommendations.tool.ts"],"names":[],"mappings":"AACA,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,oCAAoC,CAAC;AASrE,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,iBAAiB,IAAI,OAAO;WA8BtB,OAAO,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,UAAU,CAAC;mBAkCD,UAAU;mBAgCV,YAAY;mBAqCZ,aAAa;mBAgCb,aAAa;mBAwCb,eAAe;CAkBrC"}
1
+ {"version":3,"file":"recommendations.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/recommendations/recommendations.tool.ts"],"names":[],"mappings":"AACA,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,oCAAoC,CAAC;AASrE,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,iBAAiB,IAAI,OAAO;WA8BtB,OAAO,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,UAAU,CAAC;mBAkCD,UAAU;mBAgCV,YAAY;mBAqCZ,aAAa;mBAgCb,aAAa;mBAwCb,eAAe;CA8BrC"}
@@ -71,7 +71,7 @@ Operations:
71
71
  }
72
72
  const grouped = {};
73
73
  for (const rec of pending) {
74
- const typeLabel = rec.type === 'skill' ? 'Skills' : rec.type === 'agent' ? 'Agents' : 'Hooks';
74
+ const typeLabel = rec.type === 'skill' ? 'Skills' : rec.type === 'agent' ? 'Agents' : rec.type === 'capability' ? 'Capabilities' : 'Hooks';
75
75
  if (!grouped[typeLabel]) {
76
76
  grouped[typeLabel] = [];
77
77
  }
@@ -172,6 +172,16 @@ Operations:
172
172
  lines.push(`- **${origin.recommendationName}** (${origin.type})`);
173
173
  lines.push(` Source: ${origin.source}`);
174
174
  lines.push(` Accepted: ${origin.acceptedAt}`);
175
+ if (item.installedVersion) {
176
+ lines.push(` Version: v${item.installedVersion}`);
177
+ }
178
+ if (item.stepResults && item.stepResults.length > 0) {
179
+ lines.push(' Steps:');
180
+ for (const step of item.stepResults) {
181
+ const pathInfo = step.installedPath ? ` → ${step.installedPath}` : '';
182
+ lines.push(` - ${step.description} (${step.status})${pathInfo}`);
183
+ }
184
+ }
175
185
  }
176
186
  return createSuccessResult(lines.join('\n'));
177
187
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/tools/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAgBH,OAAO,KAAK,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,QAAQ,IAAI,OAAO,EAAE;IA0C5B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;CAqB9D;AAGD,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,8BAAqC,CAAC;AAChF,eAAO,MAAM,eAAe,gBAAyD,CAAC"}
1
+ {"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/tools/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,OAAO,KAAK,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,YAAY;IACvB;;OAEG;IACH,MAAM,CAAC,QAAQ,IAAI,OAAO,EAAE;IAuC5B;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;CAoB9D;AAGD,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,8BAAqC,CAAC;AAChF,eAAO,MAAM,eAAe,gBAAyD,CAAC"}
@@ -15,7 +15,6 @@ import { StrategyTool } from './strategy/strategy.tool.js';
15
15
  import { AnalyseTool } from './analyse.tool.js';
16
16
  import { QualityTool } from './quality/quality.tool.js';
17
17
  import { ConfigTool } from './config/config.tool.js';
18
- import { DashboardTool } from './dashboard/dashboard.tool.js';
19
18
  import { RecommendationsTool } from './recommendations/recommendations.tool.js';
20
19
  export class ToolRegistry {
21
20
  /**
@@ -38,8 +37,6 @@ export class ToolRegistry {
38
37
  QualityTool.getToolDefinition(),
39
38
  // Config tool - manages preferences with reactive agent sync
40
39
  ConfigTool.getToolDefinition(),
41
- // Dashboard tool - restart dashboard server (dev maintenance)
42
- DashboardTool.getToolDefinition(),
43
40
  // Recommendations tool - browse, accept, dismiss recommendations
44
41
  RecommendationsTool.getToolDefinition(),
45
42
  // Response tools (disabled for later release)
@@ -69,7 +66,6 @@ export class ToolRegistry {
69
66
  update: UpdateTool,
70
67
  quality: QualityTool,
71
68
  config: ConfigTool,
72
- dev_restart_dashboard: DashboardTool,
73
69
  recommendations: RecommendationsTool,
74
70
  };
75
71
  return toolMap[name];
@@ -5,7 +5,6 @@
5
5
  */
6
6
  import type { RequestContext } from '@magic-ingredients/tiny-brain-core';
7
7
  import type { AuthToken } from '../services/remote/auth-token-service.js';
8
- import type { DashboardLauncher } from '../services/dashboard-launcher.service.js';
9
8
  export interface LocalRequestContext extends RequestContext {
10
9
  authToken?: AuthToken;
11
10
  config?: {
@@ -14,6 +13,5 @@ export interface LocalRequestContext extends RequestContext {
14
13
  clientSecret?: string;
15
14
  };
16
15
  };
17
- dashboardLauncher?: DashboardLauncher;
18
16
  }
19
17
  //# sourceMappingURL=local-context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"local-context.d.ts","sourceRoot":"","sources":["../../src/types/local-context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAC;AAC1E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAEnF,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IAEzD,SAAS,CAAC,EAAE,SAAS,CAAC;IAGtB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE;YACR,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,YAAY,CAAC,EAAE,MAAM,CAAC;SACvB,CAAC;KACH,CAAC;IAGF,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;CACvC"}
1
+ {"version":3,"file":"local-context.d.ts","sourceRoot":"","sources":["../../src/types/local-context.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAC;AAE1E,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IAEzD,SAAS,CAAC,EAAE,SAAS,CAAC;IAGtB,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE;YACR,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,YAAY,CAAC,EAAE,MAAM,CAAC;SACvB,CAAC;KACH,CAAC;CACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magic-ingredients/tiny-brain-local",
3
- "version": "0.21.3",
3
+ "version": "0.22.0",
4
4
  "description": "MCP server for Tiny Brain AI assistant",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "dxt:init": "cd dxt && dxt init"
32
32
  },
33
33
  "dependencies": {
34
- "@magic-ingredients/tiny-brain-core": "^0.21.3",
34
+ "@magic-ingredients/tiny-brain-core": "^0.22.0",
35
35
  "@magic-ingredients/tiny-brain-dashboard": "file:../tiny-brain-dashboard",
36
36
  "@modelcontextprotocol/sdk": "^1.0.6",
37
37
  "chalk": "^5.3.0",
@@ -1,21 +0,0 @@
1
- /**
2
- * Dashboard Launcher Service
3
- *
4
- * Minimal service to launch the dashboard from the separate dashboard package
5
- */
6
- import type { RequestContext } from '../types/request-context.js';
7
- export interface DashboardOptions {
8
- port?: number;
9
- autoOpen?: boolean;
10
- }
11
- export interface DashboardStartResult {
12
- url: string;
13
- }
14
- export declare class DashboardLauncher {
15
- private server;
16
- start(context: RequestContext, options?: DashboardOptions): Promise<DashboardStartResult>;
17
- stop(): Promise<void>;
18
- restart(context: RequestContext, options?: DashboardOptions): Promise<DashboardStartResult>;
19
- isRunning(): boolean;
20
- }
21
- //# sourceMappingURL=dashboard-launcher.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard-launcher.service.d.ts","sourceRoot":"","sources":["../../src/services/dashboard-launcher.service.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAIlE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAa;IAErB,KAAK,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAc7F,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAOrB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAKrG,SAAS,IAAI,OAAO;CAGrB"}
@@ -1,33 +0,0 @@
1
- /**
2
- * Dashboard Launcher Service
3
- *
4
- * Minimal service to launch the dashboard from the separate dashboard package
5
- */
6
- // Static import so esbuild bundles the dashboard server
7
- import { DashboardServer } from '@magic-ingredients/tiny-brain-dashboard/server';
8
- export class DashboardLauncher {
9
- server = null;
10
- async start(context, options = {}) {
11
- if (this.server) {
12
- throw new Error('Dashboard already running');
13
- }
14
- this.server = new DashboardServer(context);
15
- const result = await this.server.start(options.port || 8765);
16
- return {
17
- url: result.url,
18
- };
19
- }
20
- async stop() {
21
- if (this.server) {
22
- await this.server.stop();
23
- this.server = null;
24
- }
25
- }
26
- async restart(context, options = {}) {
27
- await this.stop();
28
- return this.start(context, options);
29
- }
30
- isRunning() {
31
- return this.server !== null;
32
- }
33
- }
@@ -1,15 +0,0 @@
1
- import { type ToolArguments, type ToolResult } from '../index.js';
2
- import type { RequestContext } from '../../types/request-context.js';
3
- import type { Tool as MCPTool } from '@modelcontextprotocol/sdk/types.js';
4
- /**
5
- * Dashboard Tool - Rebuild and restart the dashboard server
6
- *
7
- * Developer maintenance tool that runs `npm run rebuild_all` to rebuild
8
- * all packages and rebundle the plugin, then kills the old dashboard
9
- * process on port 8765 and restarts from the fresh bundle.
10
- */
11
- export declare class DashboardTool {
12
- static getToolDefinition(): MCPTool;
13
- static execute(_args: ToolArguments, context: RequestContext): Promise<ToolResult>;
14
- }
15
- //# sourceMappingURL=dashboard.tool.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"dashboard.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/dashboard/dashboard.tool.ts"],"names":[],"mappings":"AACA,OAAO,EAA0C,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1G,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,KAAK,EAAE,IAAI,IAAI,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAE1E;;;;;;GAMG;AACH,qBAAa,aAAa;IACxB,MAAM,CAAC,iBAAiB,IAAI,OAAO;WAatB,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;CA8DzF"}
@@ -1,81 +0,0 @@
1
- import { execSync } from 'node:child_process';
2
- import { createErrorResult, createSuccessResult } from '../index.js';
3
- /**
4
- * Dashboard Tool - Rebuild and restart the dashboard server
5
- *
6
- * Developer maintenance tool that runs `npm run rebuild_all` to rebuild
7
- * all packages and rebundle the plugin, then kills the old dashboard
8
- * process on port 8765 and restarts from the fresh bundle.
9
- */
10
- export class DashboardTool {
11
- static getToolDefinition() {
12
- return {
13
- name: 'dev_restart_dashboard',
14
- description: 'Restart the dashboard server. Developer maintenance tool — only needed to force a reload of the dashboard (e.g. after rebuilding packages).',
15
- inputSchema: {
16
- type: 'object',
17
- properties: {},
18
- required: [],
19
- },
20
- };
21
- }
22
- static async execute(_args, context) {
23
- const localContext = context;
24
- const launcher = localContext.dashboardLauncher;
25
- if (!launcher) {
26
- return createErrorResult('Dashboard launcher is not available. The dashboard may not have been started.');
27
- }
28
- // Find the repo root (where package.json with rebuild_all lives)
29
- let repoRoot;
30
- try {
31
- repoRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim();
32
- }
33
- catch {
34
- return createErrorResult('Could not determine repository root. Are you in a git repository?');
35
- }
36
- // Step 1: Rebuild all packages
37
- const steps = [];
38
- try {
39
- execSync('npm run rebuild_all', {
40
- cwd: repoRoot,
41
- encoding: 'utf-8',
42
- stdio: 'pipe',
43
- timeout: 120_000,
44
- });
45
- steps.push('Rebuilt all packages (rebuild_all)');
46
- }
47
- catch (error) {
48
- return createErrorResult(`rebuild_all failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
49
- }
50
- // Step 2: Stop the current dashboard and kill the port
51
- try {
52
- await launcher.stop();
53
- steps.push('Stopped dashboard server');
54
- }
55
- catch {
56
- // Ignore stop errors — port kill will clean up
57
- }
58
- try {
59
- execSync('lsof -ti:8765 | xargs kill 2>/dev/null || true', {
60
- encoding: 'utf-8',
61
- stdio: 'pipe',
62
- });
63
- steps.push('Killed process on port 8765');
64
- }
65
- catch {
66
- // No process on port — fine
67
- }
68
- // Step 3: Start fresh from the new bundle
69
- try {
70
- const result = await launcher.restart(context, {});
71
- steps.push(`Dashboard started at ${result.url}`);
72
- return createSuccessResult(steps.join('\n'));
73
- }
74
- catch {
75
- // In-process restart failed (expected — bundle is stale in memory)
76
- // The rebuild is done, user needs to restart the MCP server
77
- steps.push('Note: MCP server must be restarted for code changes to take effect (the running process still has the old bundle in memory)');
78
- return createSuccessResult(steps.join('\n'));
79
- }
80
- }
81
- }