@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.
- package/dist/core/mcp-server.d.ts +3 -5
- package/dist/core/mcp-server.d.ts.map +1 -1
- package/dist/core/mcp-server.js +17 -38
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/prompts/rules/rules.prompt.d.ts.map +1 -1
- package/dist/prompts/rules/rules.prompt.js +1 -7
- package/dist/services/analyse-service.js +1 -1
- package/dist/services/credential-storage.service.d.ts +5 -44
- package/dist/services/credential-storage.service.d.ts.map +1 -1
- package/dist/services/credential-storage.service.js +4 -197
- package/dist/services/remote/auth-token-service.d.ts +10 -47
- package/dist/services/remote/auth-token-service.d.ts.map +1 -1
- package/dist/services/remote/auth-token-service.js +13 -188
- package/dist/services/repo-service.d.ts.map +1 -1
- package/dist/services/repo-service.js +3 -0
- package/dist/tools/config/config.tool.d.ts.map +1 -1
- package/dist/tools/config/config.tool.js +18 -0
- package/dist/tools/persona/as.tool.d.ts +0 -12
- package/dist/tools/persona/as.tool.d.ts.map +1 -1
- package/dist/tools/persona/as.tool.js +13 -199
- package/dist/tools/plan/plan.tool.d.ts.map +1 -1
- package/dist/tools/plan/plan.tool.js +26 -38
- package/dist/tools/quality/quality.tool.js +4 -4
- package/dist/tools/recommendations/recommendations.tool.d.ts.map +1 -1
- package/dist/tools/recommendations/recommendations.tool.js +11 -1
- package/dist/tools/tool-registry.d.ts.map +1 -1
- package/dist/tools/tool-registry.js +0 -4
- package/dist/types/local-context.d.ts +0 -2
- package/dist/types/local-context.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/services/dashboard-launcher.service.d.ts +0 -21
- package/dist/services/dashboard-launcher.service.d.ts.map +0 -1
- package/dist/services/dashboard-launcher.service.js +0 -33
- package/dist/tools/dashboard/dashboard.tool.d.ts +0 -15
- package/dist/tools/dashboard/dashboard.tool.d.ts.map +0 -1
- package/dist/tools/dashboard/dashboard.tool.js +0 -81
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { LogLevel } from '@magic-ingredients/tiny-brain-core';
|
|
7
7
|
import { AuthTokenService } from '../services/remote/auth-token-service.js';
|
|
8
|
-
import { DashboardLauncher } from '../services/dashboard-launcher.service.js';
|
|
9
8
|
/**
|
|
10
9
|
* Configuration for local MCP server
|
|
11
10
|
*/
|
|
@@ -37,7 +36,6 @@ export declare class MCPServer {
|
|
|
37
36
|
private personaChangeListeners;
|
|
38
37
|
private planChangeListeners;
|
|
39
38
|
private instanceId;
|
|
40
|
-
private dashboardLauncher;
|
|
41
39
|
private baseContext;
|
|
42
40
|
private authToken?;
|
|
43
41
|
private authTokenService?;
|
|
@@ -52,9 +50,9 @@ export declare class MCPServer {
|
|
|
52
50
|
*/
|
|
53
51
|
getAuthTokenService(): AuthTokenService | undefined;
|
|
54
52
|
/**
|
|
55
|
-
*
|
|
53
|
+
* @deprecated Dashboard runs as standalone process
|
|
56
54
|
*/
|
|
57
|
-
getDashboardLauncher():
|
|
55
|
+
getDashboardLauncher(): null;
|
|
58
56
|
/**
|
|
59
57
|
* Initialize the server
|
|
60
58
|
*/
|
|
@@ -98,7 +96,7 @@ export declare class MCPServer {
|
|
|
98
96
|
*/
|
|
99
97
|
private initializeRemotePersonas;
|
|
100
98
|
/**
|
|
101
|
-
*
|
|
99
|
+
* Check if standalone dashboard is running
|
|
102
100
|
*/
|
|
103
101
|
private initializeDashboard;
|
|
104
102
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/core/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,OAAO,KAAK,EAA4B,QAAQ,EAAkC,MAAM,oCAAoC,CAAC;AAE7H,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../../src/core/mcp-server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA0BH,OAAO,KAAK,EAA4B,QAAQ,EAAkC,MAAM,oCAAoC,CAAC;AAE7H,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAU5E;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IAEF,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,QAAQ,CAAC;KACrB,CAAC;CACH;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,MAAM,CAAwB;IACtC,OAAO,CAAC,sBAAsB,CAA0D;IACxF,OAAO,CAAC,mBAAmB,CAA2G;IACtI,OAAO,CAAC,UAAU,CAA6E;IAE/F,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAmB;gBAEhC,MAAM,GAAE,SAAc;IAwFlC,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,SAAS,IAAI,SAAS;IAItB;;OAEG;IACH,mBAAmB,IAAI,gBAAgB,GAAG,SAAS;IAInD;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAI5B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBjC;;;;;;;OAOG;YACW,sBAAsB;IA+DpC;;OAEG;YACW,iBAAiB;IAW/B;;;OAGG;YACW,oBAAoB;IAkClC;;OAEG;YACW,oBAAoB;IAwGlC;;;;;;OAMG;YACW,yBAAyB;IA+CvC;;OAEG;YACW,kBAAkB;IAsBhC;;OAEG;YACW,wBAAwB;IA8BtC;;OAEG;YACW,mBAAmB;IAgBjC;;OAEG;IACG,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YASjB,eAAe;YAMf,cAAc;YAgGd,iBAAiB;YAMjB,eAAe;YAqEf,iBAAiB;IAS/B;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAoB7B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAkD7B"}
|
package/dist/core/mcp-server.js
CHANGED
|
@@ -16,7 +16,6 @@ import { LocalFilesystemStorageAdapter } from '../storage/local-filesystem-adapt
|
|
|
16
16
|
import { FileLogger } from './file-logger.js';
|
|
17
17
|
import { ToolRegistry } from '../tools/tool-registry.js';
|
|
18
18
|
import { PromptRegistry } from '../prompts/prompt-registry.js';
|
|
19
|
-
import { DashboardLauncher } from '../services/dashboard-launcher.service.js';
|
|
20
19
|
/**
|
|
21
20
|
* MCP Server for local execution
|
|
22
21
|
*/
|
|
@@ -31,7 +30,7 @@ export class MCPServer {
|
|
|
31
30
|
personaChangeListeners = [];
|
|
32
31
|
planChangeListeners = [];
|
|
33
32
|
instanceId = `mcp-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
|
34
|
-
|
|
33
|
+
// Dashboard runs as standalone process — no in-process launcher
|
|
35
34
|
baseContext;
|
|
36
35
|
authToken;
|
|
37
36
|
authTokenService;
|
|
@@ -132,10 +131,10 @@ export class MCPServer {
|
|
|
132
131
|
return this.authTokenService;
|
|
133
132
|
}
|
|
134
133
|
/**
|
|
135
|
-
*
|
|
134
|
+
* @deprecated Dashboard runs as standalone process
|
|
136
135
|
*/
|
|
137
136
|
getDashboardLauncher() {
|
|
138
|
-
return
|
|
137
|
+
return null;
|
|
139
138
|
}
|
|
140
139
|
/**
|
|
141
140
|
* Initialize the server
|
|
@@ -473,32 +472,21 @@ export class MCPServer {
|
|
|
473
472
|
}
|
|
474
473
|
}
|
|
475
474
|
/**
|
|
476
|
-
*
|
|
475
|
+
* Check if standalone dashboard is running
|
|
477
476
|
*/
|
|
478
477
|
async initializeDashboard() {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
try {
|
|
486
|
-
this.logger.info('Auto-starting dashboard...');
|
|
487
|
-
// Create and start the dashboard
|
|
488
|
-
this.dashboardLauncher = new DashboardLauncher();
|
|
489
|
-
const result = await this.dashboardLauncher.start(this.baseContext, {
|
|
490
|
-
port: this.config.dashboardPort || 8765,
|
|
491
|
-
autoOpen: false, // Don't auto-open browser on server start
|
|
492
|
-
});
|
|
493
|
-
this.logger.info(`Dashboard available at ${result.url}`);
|
|
494
|
-
// Also output to stderr so user can see it
|
|
495
|
-
console.error(`🧠 Dashboard available at: ${result.url}`);
|
|
496
|
-
}
|
|
497
|
-
catch (error) {
|
|
498
|
-
this.logger.warn('Error starting dashboard:', error instanceof Error ? error.message : error);
|
|
499
|
-
// Don't throw - this is optional functionality
|
|
478
|
+
const port = this.config.dashboardPort || 8765;
|
|
479
|
+
try {
|
|
480
|
+
const res = await fetch(`http://localhost:${port}/health`);
|
|
481
|
+
if (res.ok) {
|
|
482
|
+
this.logger.info(`Dashboard running at http://localhost:${port}`);
|
|
483
|
+
console.error(`🧠 Dashboard available at: http://localhost:${port}`);
|
|
500
484
|
}
|
|
501
|
-
}
|
|
485
|
+
}
|
|
486
|
+
catch {
|
|
487
|
+
this.logger.info(`Dashboard not running on port ${port}. Start with: npx tiny-brain dashboard start`);
|
|
488
|
+
console.error(`🧠 Dashboard not running. Start with: npx tiny-brain dashboard start`);
|
|
489
|
+
}
|
|
502
490
|
}
|
|
503
491
|
/**
|
|
504
492
|
* Connect to transport
|
|
@@ -512,16 +500,7 @@ export class MCPServer {
|
|
|
512
500
|
*/
|
|
513
501
|
async shutdown() {
|
|
514
502
|
this.logger.info('Shutting down Local MCP Server');
|
|
515
|
-
//
|
|
516
|
-
if (this.dashboardLauncher) {
|
|
517
|
-
try {
|
|
518
|
-
await this.dashboardLauncher.stop();
|
|
519
|
-
this.logger.info('Dashboard stopped');
|
|
520
|
-
}
|
|
521
|
-
catch (error) {
|
|
522
|
-
this.logger.warn('Error stopping dashboard:', error);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
503
|
+
// Dashboard runs as standalone process — no shutdown needed here
|
|
525
504
|
await this.server.close();
|
|
526
505
|
}
|
|
527
506
|
// Tool handlers
|
|
@@ -552,7 +531,7 @@ export class MCPServer {
|
|
|
552
531
|
activePersona,
|
|
553
532
|
authToken: this.authToken,
|
|
554
533
|
config: this.config,
|
|
555
|
-
|
|
534
|
+
// dashboardLauncher removed — dashboard is standalone
|
|
556
535
|
updateActivePersona: (persona) => {
|
|
557
536
|
const newPersonaId = persona?.id;
|
|
558
537
|
this.activePersona = newPersonaId;
|
package/dist/index.d.ts
CHANGED
|
@@ -21,7 +21,6 @@ export { PlatformConfigAdapter } from './storage/platform-config-adapter.js';
|
|
|
21
21
|
export { PlatformPathBuilder } from './storage/platform-path-builder.js';
|
|
22
22
|
export type { ConfigScope } from './storage/platform-path-builder.js';
|
|
23
23
|
export { CredentialStorageService } from './services/credential-storage.service.js';
|
|
24
|
-
export { DashboardLauncher } from './services/dashboard-launcher.service.js';
|
|
25
24
|
export { AuthTokenService } from './services/remote/auth-token-service.js';
|
|
26
25
|
export type { AuthToken } from './services/remote/auth-token-service.js';
|
|
27
26
|
export { SystemPersonaService } from './services/remote/system-persona-service.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,gBAAgB,EAAE,OAAO,CAAC;CAC/B;AAID,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG9E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjF,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACtE,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,gBAAgB,EAAE,OAAO,CAAC;CAC/B;AAID,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAG9E,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjF,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACtE,YAAY,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AAGtE,OAAO,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,YAAY,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,YAAY,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,YAAY,EACV,wBAAwB,EACxB,MAAM,EACN,QAAQ,EACR,cAAc,EACd,cAAc,EACf,MAAM,oCAAoC,CAAC;AAE5C,eAAO,MAAM,OAAO,WAAW,CAAC;AAiDhC,wBAAsB,IAAI,kBA+FzB"}
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ export { PlatformConfigAdapter } from './storage/platform-config-adapter.js';
|
|
|
24
24
|
export { PlatformPathBuilder } from './storage/platform-path-builder.js';
|
|
25
25
|
// Services
|
|
26
26
|
export { CredentialStorageService } from './services/credential-storage.service.js';
|
|
27
|
-
|
|
27
|
+
// DashboardLauncher removed — dashboard runs as standalone process
|
|
28
28
|
export { AuthTokenService } from './services/remote/auth-token-service.js';
|
|
29
29
|
export { SystemPersonaService } from './services/remote/system-persona-service.js';
|
|
30
30
|
export { AnalyseService } from './services/analyse-service.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.prompt.d.ts","sourceRoot":"","sources":["../../../src/prompts/rules/rules.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"rules.prompt.d.ts","sourceRoot":"","sources":["../../../src/prompts/rules/rules.prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAgBlD,qBAAa,WAAW;IACtB;;OAEG;IACH,MAAM,CAAC,oBAAoB,IAAI,MAAM,EAAE;IAuCvC;;OAEG;WACU,MAAM,CACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC;IAa1B;;OAEG;WACU,aAAa,CACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC;IA8C1B;;OAEG;WACU,eAAe,CAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC;IAiD1B;;OAEG;WACU,gBAAgB,CAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,cAAc,CAAC;CA6C3B"}
|
|
@@ -9,7 +9,6 @@ import { RulesService } from '@magic-ingredients/tiny-brain-core';
|
|
|
9
9
|
// Zod schemas for each prompt handler
|
|
10
10
|
const AddRuleArgsSchema = z.object({
|
|
11
11
|
rule: z.string(),
|
|
12
|
-
category: z.string().optional(),
|
|
13
12
|
});
|
|
14
13
|
const ListRulesArgsSchema = z.object({
|
|
15
14
|
query: z.string().optional(),
|
|
@@ -32,11 +31,6 @@ export class RulesPrompt {
|
|
|
32
31
|
description: 'The rule or directive to add (e.g., "ALWAYS use TDD")',
|
|
33
32
|
required: true,
|
|
34
33
|
},
|
|
35
|
-
{
|
|
36
|
-
name: 'category',
|
|
37
|
-
description: 'Category for this rule (e.g., coding, communication)',
|
|
38
|
-
required: false,
|
|
39
|
-
},
|
|
40
34
|
],
|
|
41
35
|
},
|
|
42
36
|
{
|
|
@@ -100,7 +94,7 @@ export class RulesPrompt {
|
|
|
100
94
|
role: 'user',
|
|
101
95
|
content: {
|
|
102
96
|
type: 'text',
|
|
103
|
-
text: `Add rule: ${validatedArgs.rule}
|
|
97
|
+
text: `Add rule: ${validatedArgs.rule}`,
|
|
104
98
|
},
|
|
105
99
|
},
|
|
106
100
|
{
|
|
@@ -482,7 +482,7 @@ export class AnalyseService {
|
|
|
482
482
|
}
|
|
483
483
|
if (result.qualityInitialized) {
|
|
484
484
|
lines.push('\n📊 Quality Analysis: Initialized');
|
|
485
|
-
lines.push(' Created
|
|
485
|
+
lines.push(' Created .tiny-brain/quality/ directory');
|
|
486
486
|
}
|
|
487
487
|
if (result.fixesInitialized) {
|
|
488
488
|
lines.push('\n🔧 Fixes Tracking: Initialized');
|
|
@@ -1,45 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
export interface DisplayCredentials {
|
|
8
|
-
clientId?: string;
|
|
9
|
-
clientSecret: string | null;
|
|
10
|
-
llmProvider: string | null;
|
|
11
|
-
llmApiKey: string | null;
|
|
12
|
-
}
|
|
13
|
-
export declare class CredentialStorageService {
|
|
14
|
-
private readonly credentialsPath;
|
|
15
|
-
private readonly algorithm;
|
|
16
|
-
private readonly iterations;
|
|
17
|
-
private readonly keyLength;
|
|
18
|
-
constructor();
|
|
19
|
-
setCredential(key: string, value: string): Promise<void>;
|
|
20
|
-
getCredentials(): Promise<Credentials | null>;
|
|
21
|
-
showCredentials(): Promise<DisplayCredentials | null>;
|
|
22
|
-
/**
|
|
23
|
-
* Get the LLM provider name
|
|
24
|
-
* @returns The provider name or null if not configured
|
|
25
|
-
*/
|
|
26
|
-
getLlmProvider(): Promise<string | null>;
|
|
27
|
-
/**
|
|
28
|
-
* Get the LLM API key, with fallback to environment variable
|
|
29
|
-
* @returns The API key or null if not configured
|
|
30
|
-
*/
|
|
31
|
-
getLlmApiKey(): Promise<string | null>;
|
|
32
|
-
/**
|
|
33
|
-
* Check if an LLM API key is available (stored or in env)
|
|
34
|
-
* @returns true if API key is configured
|
|
35
|
-
*/
|
|
36
|
-
hasLlmApiKey(): Promise<boolean>;
|
|
37
|
-
clearCredentials(): Promise<void>;
|
|
38
|
-
validateCredential(key: string, value: string): void;
|
|
39
|
-
private encryptSecret;
|
|
40
|
-
private decryptSecret;
|
|
41
|
-
private deriveKey;
|
|
42
|
-
private loadStoredCredentials;
|
|
43
|
-
private saveStoredCredentials;
|
|
44
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Credential Storage Service (re-exported from core)
|
|
3
|
+
*/
|
|
4
|
+
export { CredentialStorageService } from '@magic-ingredients/tiny-brain-core';
|
|
5
|
+
export type { Credentials, DisplayCredentials } from '@magic-ingredients/tiny-brain-core';
|
|
45
6
|
//# sourceMappingURL=credential-storage.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-storage.service.d.ts","sourceRoot":"","sources":["../../src/services/credential-storage.service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credential-storage.service.d.ts","sourceRoot":"","sources":["../../src/services/credential-storage.service.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC"}
|
|
@@ -1,197 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export class CredentialStorageService {
|
|
6
|
-
credentialsPath;
|
|
7
|
-
algorithm = 'aes-256-gcm';
|
|
8
|
-
iterations = 100000;
|
|
9
|
-
keyLength = 32;
|
|
10
|
-
constructor() {
|
|
11
|
-
const homeDir = os.homedir();
|
|
12
|
-
this.credentialsPath = path.join(homeDir, '.tiny-brain', 'config', 'credentials.json');
|
|
13
|
-
}
|
|
14
|
-
async setCredential(key, value) {
|
|
15
|
-
const validKeys = ['clientId', 'clientSecret', 'llmProvider', 'llmApiKey'];
|
|
16
|
-
if (!validKeys.includes(key)) {
|
|
17
|
-
throw new Error(`Invalid credential key: ${key}`);
|
|
18
|
-
}
|
|
19
|
-
this.validateCredential(key, value);
|
|
20
|
-
// Load existing credentials
|
|
21
|
-
let stored = await this.loadStoredCredentials();
|
|
22
|
-
if (!stored) {
|
|
23
|
-
stored = {
|
|
24
|
-
version: 1,
|
|
25
|
-
updatedAt: new Date().toISOString()
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
// Update the specific credential
|
|
29
|
-
if (key === 'clientId') {
|
|
30
|
-
stored.clientId = value;
|
|
31
|
-
}
|
|
32
|
-
else if (key === 'clientSecret') {
|
|
33
|
-
stored.clientSecret = this.encryptSecret(value);
|
|
34
|
-
}
|
|
35
|
-
else if (key === 'llmProvider') {
|
|
36
|
-
stored.llmProvider = value;
|
|
37
|
-
}
|
|
38
|
-
else if (key === 'llmApiKey') {
|
|
39
|
-
stored.llmApiKey = this.encryptSecret(value);
|
|
40
|
-
}
|
|
41
|
-
stored.updatedAt = new Date().toISOString();
|
|
42
|
-
// Save credentials
|
|
43
|
-
await this.saveStoredCredentials(stored);
|
|
44
|
-
}
|
|
45
|
-
async getCredentials() {
|
|
46
|
-
const stored = await this.loadStoredCredentials();
|
|
47
|
-
if (!stored) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
const result = {};
|
|
51
|
-
if (stored.clientId) {
|
|
52
|
-
result.clientId = stored.clientId;
|
|
53
|
-
}
|
|
54
|
-
if (stored.clientSecret) {
|
|
55
|
-
try {
|
|
56
|
-
result.clientSecret = this.decryptSecret(stored.clientSecret);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
// If decryption fails, return null
|
|
60
|
-
console.error('Failed to decrypt client secret:', error);
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
async showCredentials() {
|
|
67
|
-
const stored = await this.loadStoredCredentials();
|
|
68
|
-
if (!stored) {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
clientId: stored.clientId,
|
|
73
|
-
clientSecret: stored.clientSecret ? '[STORED]' : null,
|
|
74
|
-
llmProvider: stored.llmProvider || null,
|
|
75
|
-
llmApiKey: stored.llmApiKey ? '[STORED]' : null
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Get the LLM provider name
|
|
80
|
-
* @returns The provider name or null if not configured
|
|
81
|
-
*/
|
|
82
|
-
async getLlmProvider() {
|
|
83
|
-
const stored = await this.loadStoredCredentials();
|
|
84
|
-
return stored?.llmProvider || null;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Get the LLM API key, with fallback to environment variable
|
|
88
|
-
* @returns The API key or null if not configured
|
|
89
|
-
*/
|
|
90
|
-
async getLlmApiKey() {
|
|
91
|
-
// First try stored credentials
|
|
92
|
-
const stored = await this.loadStoredCredentials();
|
|
93
|
-
if (stored?.llmApiKey) {
|
|
94
|
-
try {
|
|
95
|
-
return this.decryptSecret(stored.llmApiKey);
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
console.error('Failed to decrypt LLM API key:', error);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
// Fall back to environment variable
|
|
102
|
-
return process.env.LLM_API_KEY || null;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Check if an LLM API key is available (stored or in env)
|
|
106
|
-
* @returns true if API key is configured
|
|
107
|
-
*/
|
|
108
|
-
async hasLlmApiKey() {
|
|
109
|
-
const apiKey = await this.getLlmApiKey();
|
|
110
|
-
return apiKey !== null;
|
|
111
|
-
}
|
|
112
|
-
async clearCredentials() {
|
|
113
|
-
try {
|
|
114
|
-
await fs.unlink(this.credentialsPath);
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
if (error.code !== 'ENOENT') {
|
|
118
|
-
throw error;
|
|
119
|
-
}
|
|
120
|
-
// File doesn't exist, that's fine
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
validateCredential(key, value) {
|
|
124
|
-
const trimmed = value.trim();
|
|
125
|
-
if (!trimmed) {
|
|
126
|
-
const displayNames = {
|
|
127
|
-
clientId: 'Client ID',
|
|
128
|
-
clientSecret: 'Client Secret',
|
|
129
|
-
llmProvider: 'LLM Provider',
|
|
130
|
-
llmApiKey: 'LLM API Key'
|
|
131
|
-
};
|
|
132
|
-
const displayName = displayNames[key] || key;
|
|
133
|
-
throw new Error(`${displayName} cannot be empty`);
|
|
134
|
-
}
|
|
135
|
-
// Could add format validation here if needed
|
|
136
|
-
// For example: if (!trimmed.startsWith('cid_')) for clientId
|
|
137
|
-
}
|
|
138
|
-
encryptSecret(secret) {
|
|
139
|
-
const salt = crypto.randomBytes(32);
|
|
140
|
-
const iv = crypto.randomBytes(16);
|
|
141
|
-
// Derive key from machine-specific data
|
|
142
|
-
const key = this.deriveKey(salt);
|
|
143
|
-
const cipher = crypto.createCipheriv(this.algorithm, key, iv);
|
|
144
|
-
const encrypted = Buffer.concat([
|
|
145
|
-
cipher.update(secret, 'utf8'),
|
|
146
|
-
cipher.final()
|
|
147
|
-
]);
|
|
148
|
-
const tag = cipher.getAuthTag();
|
|
149
|
-
return {
|
|
150
|
-
encrypted: encrypted.toString('base64'),
|
|
151
|
-
salt: salt.toString('base64'),
|
|
152
|
-
iv: iv.toString('base64'),
|
|
153
|
-
tag: tag.toString('base64')
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
decryptSecret(encryptedData) {
|
|
157
|
-
const salt = Buffer.from(encryptedData.salt, 'base64');
|
|
158
|
-
const iv = Buffer.from(encryptedData.iv, 'base64');
|
|
159
|
-
const tag = Buffer.from(encryptedData.tag, 'base64');
|
|
160
|
-
const encrypted = Buffer.from(encryptedData.encrypted, 'base64');
|
|
161
|
-
const key = this.deriveKey(salt);
|
|
162
|
-
const decipher = crypto.createDecipheriv(this.algorithm, key, iv);
|
|
163
|
-
decipher.setAuthTag(tag);
|
|
164
|
-
const decrypted = Buffer.concat([
|
|
165
|
-
decipher.update(encrypted),
|
|
166
|
-
decipher.final()
|
|
167
|
-
]);
|
|
168
|
-
return decrypted.toString('utf8');
|
|
169
|
-
}
|
|
170
|
-
deriveKey(salt) {
|
|
171
|
-
// Use machine-specific data as the passphrase
|
|
172
|
-
// This makes the encryption tied to this specific machine
|
|
173
|
-
const passphrase = os.homedir();
|
|
174
|
-
return crypto.pbkdf2Sync(passphrase, salt, this.iterations, this.keyLength, 'sha256');
|
|
175
|
-
}
|
|
176
|
-
async loadStoredCredentials() {
|
|
177
|
-
try {
|
|
178
|
-
const data = await fs.readFile(this.credentialsPath, 'utf8');
|
|
179
|
-
return JSON.parse(data);
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
if (error.code === 'ENOENT') {
|
|
183
|
-
return null;
|
|
184
|
-
}
|
|
185
|
-
throw error;
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
async saveStoredCredentials(credentials) {
|
|
189
|
-
const dir = path.dirname(this.credentialsPath);
|
|
190
|
-
// Ensure directory exists
|
|
191
|
-
await fs.mkdir(dir, { recursive: true });
|
|
192
|
-
// Write file
|
|
193
|
-
await fs.writeFile(this.credentialsPath, JSON.stringify(credentials, null, 2), 'utf8');
|
|
194
|
-
// Set strict permissions (user read/write only)
|
|
195
|
-
await fs.chmod(this.credentialsPath, 0o600);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Credential Storage Service (re-exported from core)
|
|
3
|
+
*/
|
|
4
|
+
export { CredentialStorageService } from '@magic-ingredients/tiny-brain-core';
|
|
@@ -1,55 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Auth Token Service
|
|
2
|
+
* Auth Token Service (re-exported from core)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* This module re-exports the core AuthTokenService and adapts
|
|
5
|
+
* it for MCP usage with MCPConfig.
|
|
5
6
|
*/
|
|
6
|
-
import {
|
|
7
|
+
import { AuthTokenService as CoreAuthTokenService } from '@magic-ingredients/tiny-brain-core';
|
|
7
8
|
import type { RequestContext } from '@magic-ingredients/tiny-brain-core';
|
|
8
9
|
import type { MCPConfig } from '../../core/mcp-server.js';
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export
|
|
15
|
-
isValid: boolean;
|
|
16
|
-
clientId?: string;
|
|
17
|
-
clientSecret?: string;
|
|
18
|
-
error?: string;
|
|
19
|
-
}
|
|
20
|
-
export declare class AuthTokenService extends BaseService {
|
|
21
|
-
private baseUrl;
|
|
22
|
-
private authToken;
|
|
23
|
-
private config;
|
|
10
|
+
export type { AuthToken, CredentialsValidation, AuthCredentials } from '@magic-ingredients/tiny-brain-core';
|
|
11
|
+
/**
|
|
12
|
+
* MCP-specific AuthTokenService that accepts MCPConfig
|
|
13
|
+
* and extracts credentials from config.account
|
|
14
|
+
*/
|
|
15
|
+
export declare class AuthTokenService extends CoreAuthTokenService {
|
|
24
16
|
constructor(context: RequestContext, config?: MCPConfig);
|
|
25
|
-
/**
|
|
26
|
-
* Validate that credentials are properly configured
|
|
27
|
-
*/
|
|
28
|
-
validateCredentials(): CredentialsValidation;
|
|
29
|
-
/**
|
|
30
|
-
* Connect to the auth service and obtain a token
|
|
31
|
-
* Assumes credentials have been validated
|
|
32
|
-
*/
|
|
33
|
-
connectToAuthService(clientId: string, clientSecret: string): Promise<AuthToken | null>;
|
|
34
|
-
/**
|
|
35
|
-
* Main authentication flow - validate and connect if valid
|
|
36
|
-
*/
|
|
37
|
-
authenticate(): Promise<AuthToken | null>;
|
|
38
|
-
/**
|
|
39
|
-
* Get auth headers for API requests
|
|
40
|
-
*/
|
|
41
|
-
getAuthHeaders(): Record<string, string> | null;
|
|
42
|
-
/**
|
|
43
|
-
* Check if currently authenticated
|
|
44
|
-
*/
|
|
45
|
-
isAuthenticated(): boolean;
|
|
46
|
-
/**
|
|
47
|
-
* Clear authentication
|
|
48
|
-
*/
|
|
49
|
-
clearAuth(): void;
|
|
50
|
-
/**
|
|
51
|
-
* Get current token (for debugging/testing)
|
|
52
|
-
*/
|
|
53
|
-
getToken(): AuthToken | null;
|
|
54
17
|
}
|
|
55
18
|
//# sourceMappingURL=auth-token-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-token-service.d.ts","sourceRoot":"","sources":["../../../src/services/remote/auth-token-service.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"auth-token-service.d.ts","sourceRoot":"","sources":["../../../src/services/remote/auth-token-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,IAAI,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC9F,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,oCAAoC,CAAC;AAC1F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAG1D,YAAY,EAAE,SAAS,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE5G;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,oBAAoB;gBAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,SAAS;CAMxD"}
|