@magic-ingredients/tiny-brain-local 0.19.1 → 0.20.1
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.map +1 -1
- package/dist/core/mcp-server.js +11 -19
- package/dist/services/analyse-service.d.ts +19 -0
- package/dist/services/analyse-service.d.ts.map +1 -1
- package/dist/services/analyse-service.js +177 -4
- package/dist/services/dashboard-launcher.service.d.ts +1 -0
- package/dist/services/dashboard-launcher.service.d.ts.map +1 -1
- package/dist/services/dashboard-launcher.service.js +4 -0
- package/dist/services/repo-service.d.ts.map +1 -1
- package/dist/services/repo-service.js +3 -1
- package/dist/tools/dashboard/dashboard.tool.d.ts +14 -0
- package/dist/tools/dashboard/dashboard.tool.d.ts.map +1 -0
- package/dist/tools/dashboard/dashboard.tool.js +34 -0
- package/dist/tools/persona/as.tool.js +2 -2
- package/dist/tools/quality/quality.tool.d.ts +1 -0
- package/dist/tools/quality/quality.tool.d.ts.map +1 -1
- package/dist/tools/quality/quality.tool.js +56 -10
- package/dist/tools/tool-registry.d.ts.map +1 -1
- package/dist/tools/tool-registry.js +4 -0
- package/dist/types/local-context.d.ts +2 -0
- package/dist/types/local-context.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -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;AAQ5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAE9E;;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;IAC/F,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,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,iBAAiB,GAAG,IAAI;IAIhD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBjC;;;;;;;OAOG;YACW,sBAAsB;IA+DpC;;OAEG;YACW,iBAAiB;IAW/B;;;OAGG;YACW,oBAAoB;IA6BlC;;OAEG;YACW,oBAAoB;
|
|
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;AAQ5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAE9E;;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;IAC/F,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,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,iBAAiB,GAAG,IAAI;IAIhD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBjC;;;;;;;OAOG;YACW,sBAAsB;IA+DpC;;OAEG;YACW,iBAAiB;IAW/B;;;OAGG;YACW,oBAAoB;IA6BlC;;OAEG;YACW,oBAAoB;IAwGlC;;;;;;OAMG;YACW,yBAAyB;IA+CvC;;OAEG;YACW,kBAAkB;IAsBhC;;OAEG;YACW,wBAAwB;IA8BtC;;OAEG;YACW,mBAAmB;IA8BjC;;OAEG;IACG,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IAK5C;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAiBjB,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
|
@@ -8,7 +8,7 @@ import { existsSync, cpSync, readdirSync, readFileSync, writeFileSync, mkdirSync
|
|
|
8
8
|
import { execSync } from 'child_process';
|
|
9
9
|
import { Server as McpServer } from '@modelcontextprotocol/sdk/server/index.js';
|
|
10
10
|
import { ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, SetLevelRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
11
|
-
import { isDevelopment as checkIsDevelopment } from '@magic-ingredients/tiny-brain-core';
|
|
11
|
+
import { isDevelopment as checkIsDevelopment, detectClaudeCliStatus } from '@magic-ingredients/tiny-brain-core';
|
|
12
12
|
import { AuthTokenService } from '../services/remote/auth-token-service.js';
|
|
13
13
|
import { CredentialStorageService } from '../services/credential-storage.service.js';
|
|
14
14
|
import { SystemPersonaService } from '../services/remote/system-persona-service.js';
|
|
@@ -276,12 +276,11 @@ export class MCPServer {
|
|
|
276
276
|
hasClientSecret: !!this.config.account?.clientSecret,
|
|
277
277
|
configKeys: Object.keys(this.config)
|
|
278
278
|
});
|
|
279
|
-
// Create credential service to check for credentials
|
|
279
|
+
// Create credential service to check for credentials
|
|
280
280
|
const credentialService = new CredentialStorageService();
|
|
281
|
-
// Check
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
const getLlmApiKey = () => credentialService.getLlmApiKey();
|
|
281
|
+
// Check Claude CLI availability (for dashboard to disable/enable skill invocation buttons)
|
|
282
|
+
const cliStatus = await detectClaudeCliStatus(this.logger);
|
|
283
|
+
const hasClaudeCli = cliStatus.authenticated;
|
|
285
284
|
// Check for remote auth credentials
|
|
286
285
|
if (!this.config.account?.clientId || !this.config.account?.clientSecret) {
|
|
287
286
|
this.logger.info('No remote credentials configured in MCP config, checking tiny-brain CLI config...');
|
|
@@ -298,13 +297,11 @@ export class MCPServer {
|
|
|
298
297
|
}
|
|
299
298
|
else {
|
|
300
299
|
this.logger.info('No credentials found in CLI config either, running in local-only mode');
|
|
301
|
-
// Still set libraryAuth with hasLlmApiKey for dashboard
|
|
302
300
|
this.baseContext.libraryAuth = {
|
|
303
301
|
clientId: undefined,
|
|
304
302
|
hasStoredSecret: false,
|
|
305
|
-
|
|
303
|
+
hasClaudeCli,
|
|
306
304
|
token: undefined,
|
|
307
|
-
getLlmApiKey
|
|
308
305
|
};
|
|
309
306
|
return;
|
|
310
307
|
}
|
|
@@ -312,13 +309,11 @@ export class MCPServer {
|
|
|
312
309
|
catch (error) {
|
|
313
310
|
this.logger.warn('Error reading CLI config:', error);
|
|
314
311
|
this.logger.info('Running in local-only mode');
|
|
315
|
-
// Still set libraryAuth with hasLlmApiKey for dashboard
|
|
316
312
|
this.baseContext.libraryAuth = {
|
|
317
313
|
clientId: undefined,
|
|
318
314
|
hasStoredSecret: false,
|
|
319
|
-
|
|
315
|
+
hasClaudeCli,
|
|
320
316
|
token: undefined,
|
|
321
|
-
getLlmApiKey
|
|
322
317
|
};
|
|
323
318
|
return;
|
|
324
319
|
}
|
|
@@ -343,9 +338,8 @@ export class MCPServer {
|
|
|
343
338
|
this.baseContext.libraryAuth = {
|
|
344
339
|
clientId: this.config.account?.clientId,
|
|
345
340
|
hasStoredSecret: true,
|
|
346
|
-
|
|
341
|
+
hasClaudeCli,
|
|
347
342
|
token: token.token,
|
|
348
|
-
getLlmApiKey
|
|
349
343
|
};
|
|
350
344
|
}
|
|
351
345
|
else {
|
|
@@ -356,22 +350,19 @@ export class MCPServer {
|
|
|
356
350
|
this.baseContext.libraryAuth = {
|
|
357
351
|
clientId: this.config.account?.clientId,
|
|
358
352
|
hasStoredSecret: !!this.config.account?.clientSecret,
|
|
359
|
-
|
|
353
|
+
hasClaudeCli,
|
|
360
354
|
token: undefined,
|
|
361
|
-
getLlmApiKey
|
|
362
355
|
};
|
|
363
356
|
}
|
|
364
357
|
}
|
|
365
358
|
catch (error) {
|
|
366
359
|
this.logger.error('Unexpected error during remote authentication', error);
|
|
367
360
|
// Continue in local mode - don't fail the entire initialization
|
|
368
|
-
// Still set libraryAuth with hasLlmApiKey for dashboard
|
|
369
361
|
this.baseContext.libraryAuth = {
|
|
370
362
|
clientId: this.config.account?.clientId,
|
|
371
363
|
hasStoredSecret: !!this.config.account?.clientSecret,
|
|
372
|
-
|
|
364
|
+
hasClaudeCli,
|
|
373
365
|
token: undefined,
|
|
374
|
-
getLlmApiKey
|
|
375
366
|
};
|
|
376
367
|
}
|
|
377
368
|
}
|
|
@@ -558,6 +549,7 @@ export class MCPServer {
|
|
|
558
549
|
activePersona,
|
|
559
550
|
authToken: this.authToken,
|
|
560
551
|
config: this.config,
|
|
552
|
+
dashboardLauncher: this.dashboardLauncher ?? undefined,
|
|
561
553
|
updateActivePersona: (persona) => {
|
|
562
554
|
const newPersonaId = persona?.id;
|
|
563
555
|
this.activePersona = newPersonaId;
|
|
@@ -29,6 +29,7 @@ export interface AnalyseResult {
|
|
|
29
29
|
};
|
|
30
30
|
skillPermissionsAdded?: string[];
|
|
31
31
|
writtenTechContexts?: string[];
|
|
32
|
+
agentsMdStatus?: 'created' | 'updated' | 'up-to-date';
|
|
32
33
|
}
|
|
33
34
|
/**
|
|
34
35
|
* Service for managing repository analysis
|
|
@@ -45,6 +46,20 @@ export declare class AnalyseService {
|
|
|
45
46
|
* Perform repository analysis with unified behavior for initialized/uninitialized repos
|
|
46
47
|
*/
|
|
47
48
|
performAnalysis(options?: AnalyseOptions): Promise<AnalyseResult>;
|
|
49
|
+
/**
|
|
50
|
+
* Generate AGENTS.md file in the repository root
|
|
51
|
+
* For monorepos, also generates per-package AGENTS.md files
|
|
52
|
+
* Uses AgentsMdService from tiny-brain-core
|
|
53
|
+
*/
|
|
54
|
+
private generateAgentsMd;
|
|
55
|
+
/**
|
|
56
|
+
* Read package.json from each workspace directory to collect names and descriptions
|
|
57
|
+
*/
|
|
58
|
+
private collectPackageDescriptions;
|
|
59
|
+
/**
|
|
60
|
+
* Generate AGENTS.md for each workspace package in a monorepo
|
|
61
|
+
*/
|
|
62
|
+
private generatePerPackageAgentsMd;
|
|
48
63
|
/**
|
|
49
64
|
* Register repository in dashboard for visibility
|
|
50
65
|
* Called after successful analysis regardless of invocation method
|
|
@@ -95,6 +110,10 @@ export declare class AnalyseService {
|
|
|
95
110
|
* Format analysis output for display
|
|
96
111
|
*/
|
|
97
112
|
formatAnalysisOutput(result: AnalyseResult): string;
|
|
113
|
+
/**
|
|
114
|
+
* Append rich metadata sections to output lines
|
|
115
|
+
*/
|
|
116
|
+
private appendRichMetadataOutput;
|
|
98
117
|
/**
|
|
99
118
|
* Compare two tech stacks and return differences
|
|
100
119
|
* Handles null previous analysis (first run)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyse-service.d.ts","sourceRoot":"","sources":["../../src/services/analyse-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,aAAa,
|
|
1
|
+
{"version":3,"file":"analyse-service.d.ts","sourceRoot":"","sources":["../../src/services/analyse-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAEL,KAAK,YAAY,EAEjB,KAAK,aAAa,EAQnB,MAAM,oCAAoC,CAAC;AAS5C,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAGD,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,YAAY,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,OAAO,CAAC,EAAE;QACR,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,gBAAgB,EAAE,MAAM,EAAE,CAAC;KAC5B,CAAC;IACF,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,cAAc,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;CACvD;AAGD;;;GAGG;AACH,qBAAa,cAAc;IAMb,OAAO,CAAC,OAAO;IAL3B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,kBAAkB,CAAqB;gBAE3B,OAAO,EAAE,cAAc;IAO3C;;OAEG;IACG,eAAe,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,aAAa,CAAC;IAyK3E;;;;OAIG;YACW,gBAAgB;IAmD9B;;OAEG;YACW,0BAA0B;IAyBxC;;OAEG;YACW,0BAA0B;IA+BxC;;;OAGG;YACW,kBAAkB;IAoBhC;;OAEG;YACW,eAAe;IAc7B;;;OAGG;YACW,sBAAsB;IAwBpC;;;OAGG;YACW,sBAAsB;IAwBpC;;;OAGG;YACW,0BAA0B;IAwBxC;;;OAGG;YACW,wBAAwB;IAwBtC;;;;OAIG;YACW,kBAAkB;IA+EhC;;;;OAIG;YACW,sBAAsB;IAiEpC;;;OAGG;YACW,yBAAyB;IAkCvC;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM;IAgInD;;OAEG;IACH,OAAO,CAAC,wBAAwB;IA2ChC;;;OAGG;IACH,iBAAiB,CAAC,gBAAgB,EAAE,YAAY,GAAG,IAAI,EAAE,eAAe,EAAE,YAAY,GAAG,aAAa;IA8BtG;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;CAWxB"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Handles repository tech stack analysis.
|
|
5
5
|
* Focused solely on analysis - no context file management.
|
|
6
6
|
*/
|
|
7
|
-
import { analyseRepository, formatTechStackChanges, detectTechStackChanges, ConfigService, RepoConfigService, LibraryClient, TechContextService, } from '@magic-ingredients/tiny-brain-core';
|
|
7
|
+
import { analyseRepository, formatTechStackChanges, detectTechStackChanges, ConfigService, RepoConfigService, LibraryClient, TechContextService, AgentsMdService, } from '@magic-ingredients/tiny-brain-core';
|
|
8
8
|
import { RepoService } from './repo-service.js';
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import { dirname, join } from 'path';
|
|
@@ -60,6 +60,13 @@ export class AnalyseService {
|
|
|
60
60
|
primaryLanguage: currentAnalysis.primaryLanguage,
|
|
61
61
|
documentationPattern: currentAnalysis.documentationPattern,
|
|
62
62
|
documentationLocations: currentAnalysis.documentationLocations,
|
|
63
|
+
// Rich metadata
|
|
64
|
+
packageManager: currentAnalysis.packageManager,
|
|
65
|
+
scripts: currentAnalysis.scripts,
|
|
66
|
+
linting: currentAnalysis.linting,
|
|
67
|
+
monorepo: currentAnalysis.monorepo,
|
|
68
|
+
projectName: currentAnalysis.projectName,
|
|
69
|
+
sourceDirectories: currentAnalysis.sourceDirectories,
|
|
63
70
|
};
|
|
64
71
|
const stackChanged = await this.techContextService.hasStackChanged(analysisInput);
|
|
65
72
|
const existingAnalysis = await this.techContextService.readAnalysis();
|
|
@@ -79,6 +86,12 @@ export class AnalyseService {
|
|
|
79
86
|
if (!dryRun) {
|
|
80
87
|
await this.techContextService.syncAgents(enableAgentic);
|
|
81
88
|
}
|
|
89
|
+
// Generate AGENTS.md (if config allows)
|
|
90
|
+
let agentsMdStatus;
|
|
91
|
+
const manageAgentsMd = await this.configService.isManageAgentsMdEnabled();
|
|
92
|
+
if (!dryRun && manageAgentsMd) {
|
|
93
|
+
agentsMdStatus = await this.generateAgentsMd(currentAnalysis);
|
|
94
|
+
}
|
|
82
95
|
// Write workflow sections to CLAUDE.md based on config flags (SDD, TDD)
|
|
83
96
|
if (!dryRun) {
|
|
84
97
|
await this.repoService.writeWorkflowSections({ contextPath });
|
|
@@ -105,7 +118,8 @@ export class AnalyseService {
|
|
|
105
118
|
contextBlockVersion,
|
|
106
119
|
contextBlockUpdated,
|
|
107
120
|
skillPermissionsAdded: skillPermissionsAdded.length > 0 ? skillPermissionsAdded : undefined,
|
|
108
|
-
writtenTechContexts
|
|
121
|
+
writtenTechContexts,
|
|
122
|
+
agentsMdStatus,
|
|
109
123
|
};
|
|
110
124
|
}
|
|
111
125
|
if (!stackChanged) {
|
|
@@ -125,7 +139,8 @@ export class AnalyseService {
|
|
|
125
139
|
contextBlockVersion,
|
|
126
140
|
contextBlockUpdated,
|
|
127
141
|
skillPermissionsAdded: skillPermissionsAdded.length > 0 ? skillPermissionsAdded : undefined,
|
|
128
|
-
writtenTechContexts
|
|
142
|
+
writtenTechContexts,
|
|
143
|
+
agentsMdStatus,
|
|
129
144
|
};
|
|
130
145
|
}
|
|
131
146
|
// Changes detected - compute diff for display purposes
|
|
@@ -163,9 +178,108 @@ export class AnalyseService {
|
|
|
163
178
|
techStackRemoved: techStackDiff.removed
|
|
164
179
|
},
|
|
165
180
|
skillPermissionsAdded: skillPermissionsAdded.length > 0 ? skillPermissionsAdded : undefined,
|
|
166
|
-
writtenTechContexts
|
|
181
|
+
writtenTechContexts,
|
|
182
|
+
agentsMdStatus,
|
|
167
183
|
};
|
|
168
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Generate AGENTS.md file in the repository root
|
|
187
|
+
* For monorepos, also generates per-package AGENTS.md files
|
|
188
|
+
* Uses AgentsMdService from tiny-brain-core
|
|
189
|
+
*/
|
|
190
|
+
async generateAgentsMd(analysis) {
|
|
191
|
+
const repoRoot = process.cwd();
|
|
192
|
+
const agentsMdService = new AgentsMdService(repoRoot);
|
|
193
|
+
const agentsMdPath = join(repoRoot, 'AGENTS.md');
|
|
194
|
+
// Read existing AGENTS.md if present
|
|
195
|
+
let existingContent;
|
|
196
|
+
try {
|
|
197
|
+
existingContent = await readFile(agentsMdPath, 'utf-8');
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// File doesn't exist
|
|
201
|
+
}
|
|
202
|
+
// Extract README excerpt
|
|
203
|
+
const readmeExcerpt = await agentsMdService.extractReadmeExcerpt();
|
|
204
|
+
// Collect package descriptions for monorepo
|
|
205
|
+
let packageDescriptions;
|
|
206
|
+
if (analysis.monorepo?.packages && analysis.monorepo.packages.length > 0) {
|
|
207
|
+
packageDescriptions = await this.collectPackageDescriptions(repoRoot, analysis.monorepo.packages);
|
|
208
|
+
}
|
|
209
|
+
// Generate root content
|
|
210
|
+
const result = await agentsMdService.generateContent({
|
|
211
|
+
analysis,
|
|
212
|
+
readmeExcerpt,
|
|
213
|
+
repoPath: repoRoot,
|
|
214
|
+
existingContent,
|
|
215
|
+
packageDescriptions,
|
|
216
|
+
});
|
|
217
|
+
if (!existingContent) {
|
|
218
|
+
await writeFile(agentsMdPath, result.content, 'utf-8');
|
|
219
|
+
this.context.logger.info('Created AGENTS.md');
|
|
220
|
+
}
|
|
221
|
+
else if (!result.contentChanged) {
|
|
222
|
+
this.context.logger.info('AGENTS.md is up to date');
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
await writeFile(agentsMdPath, result.content, 'utf-8');
|
|
226
|
+
this.context.logger.info('Updated AGENTS.md');
|
|
227
|
+
}
|
|
228
|
+
// Generate per-package AGENTS.md for monorepo
|
|
229
|
+
if (analysis.monorepo?.packages && analysis.monorepo.packages.length > 0) {
|
|
230
|
+
await this.generatePerPackageAgentsMd(repoRoot, analysis, agentsMdService);
|
|
231
|
+
}
|
|
232
|
+
if (!existingContent)
|
|
233
|
+
return 'created';
|
|
234
|
+
if (!result.contentChanged)
|
|
235
|
+
return 'up-to-date';
|
|
236
|
+
return 'updated';
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Read package.json from each workspace directory to collect names and descriptions
|
|
240
|
+
*/
|
|
241
|
+
async collectPackageDescriptions(repoRoot, packages) {
|
|
242
|
+
const descriptions = [];
|
|
243
|
+
for (const pkgPath of packages) {
|
|
244
|
+
const fullPath = join(repoRoot, pkgPath);
|
|
245
|
+
const pkgJsonPath = join(fullPath, 'package.json');
|
|
246
|
+
try {
|
|
247
|
+
const raw = await readFile(pkgJsonPath, 'utf-8');
|
|
248
|
+
const pkgJson = JSON.parse(raw);
|
|
249
|
+
descriptions.push({
|
|
250
|
+
name: pkgJson.name,
|
|
251
|
+
path: pkgPath,
|
|
252
|
+
description: pkgJson.description,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
descriptions.push({ path: pkgPath });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return descriptions;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Generate AGENTS.md for each workspace package in a monorepo
|
|
263
|
+
*/
|
|
264
|
+
async generatePerPackageAgentsMd(repoRoot, analysis, agentsMdService) {
|
|
265
|
+
const packages = analysis.monorepo?.packages ?? [];
|
|
266
|
+
for (const pkgPath of packages) {
|
|
267
|
+
const fullPkgPath = join(repoRoot, pkgPath);
|
|
268
|
+
const pkgAgentsMdPath = join(fullPkgPath, 'AGENTS.md');
|
|
269
|
+
let existingPkgContent;
|
|
270
|
+
try {
|
|
271
|
+
existingPkgContent = await readFile(pkgAgentsMdPath, 'utf-8');
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
// File doesn't exist
|
|
275
|
+
}
|
|
276
|
+
const pkgResult = await agentsMdService.generatePackageContent(fullPkgPath, analysis, existingPkgContent);
|
|
277
|
+
if (!existingPkgContent || pkgResult.contentChanged) {
|
|
278
|
+
await writeFile(pkgAgentsMdPath, pkgResult.content, 'utf-8');
|
|
279
|
+
this.context.logger.debug(`Wrote AGENTS.md for ${pkgPath}`);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
169
283
|
/**
|
|
170
284
|
* Register repository in dashboard for visibility
|
|
171
285
|
* Called after successful analysis regardless of invocation method
|
|
@@ -506,6 +620,9 @@ export class AnalyseService {
|
|
|
506
620
|
lines.push(` Frameworks: ${result.analysis.frameworks.join(', ')}`);
|
|
507
621
|
lines.push(` Build Tools: ${result.analysis.buildTools.join(', ')}`);
|
|
508
622
|
lines.push(` Testing Tools: ${result.analysis.testingTools.join(', ')}`);
|
|
623
|
+
if (result.analysis.packageManager) {
|
|
624
|
+
lines.push(` Package Manager: ${result.analysis.packageManager}`);
|
|
625
|
+
}
|
|
509
626
|
if (result.analysis.documentationPattern) {
|
|
510
627
|
lines.push(`\n📚 Documentation: ${result.analysis.documentationPattern}`);
|
|
511
628
|
if (result.analysis.documentationLocations) {
|
|
@@ -578,8 +695,64 @@ export class AnalyseService {
|
|
|
578
695
|
lines.push(' None');
|
|
579
696
|
}
|
|
580
697
|
}
|
|
698
|
+
// Rich metadata sections (shown in all cases when data exists)
|
|
699
|
+
this.appendRichMetadataOutput(lines, result.analysis);
|
|
700
|
+
// AGENTS.md status (shown in all cases)
|
|
701
|
+
if (result.agentsMdStatus) {
|
|
702
|
+
const statusLabel = result.agentsMdStatus === 'created' ? 'Created'
|
|
703
|
+
: result.agentsMdStatus === 'updated' ? 'Updated'
|
|
704
|
+
: 'Up to date';
|
|
705
|
+
lines.push(`\nAGENTS.md: ${statusLabel}`);
|
|
706
|
+
}
|
|
581
707
|
return lines.join('\n');
|
|
582
708
|
}
|
|
709
|
+
/**
|
|
710
|
+
* Append rich metadata sections to output lines
|
|
711
|
+
*/
|
|
712
|
+
appendRichMetadataOutput(lines, analysis) {
|
|
713
|
+
// Package manager (shown when not already in tech stack section)
|
|
714
|
+
if (analysis.packageManager) {
|
|
715
|
+
lines.push(`\n Package Manager: ${analysis.packageManager}`);
|
|
716
|
+
}
|
|
717
|
+
// Commands section
|
|
718
|
+
const scripts = analysis.scripts;
|
|
719
|
+
if (scripts && (scripts.test?.command || scripts.build?.command || scripts.dev?.command || scripts.lint?.command || scripts.e2e?.command)) {
|
|
720
|
+
lines.push('\n📋 Commands:');
|
|
721
|
+
if (scripts.test?.command)
|
|
722
|
+
lines.push(` Test: ${scripts.test.command}`);
|
|
723
|
+
if (scripts.build?.command)
|
|
724
|
+
lines.push(` Build: ${scripts.build.command}`);
|
|
725
|
+
if (scripts.dev?.command)
|
|
726
|
+
lines.push(` Dev: ${scripts.dev.command}`);
|
|
727
|
+
if (scripts.lint?.command)
|
|
728
|
+
lines.push(` Lint: ${scripts.lint.command}`);
|
|
729
|
+
if (scripts.e2e?.command)
|
|
730
|
+
lines.push(` E2E: ${scripts.e2e.command}`);
|
|
731
|
+
}
|
|
732
|
+
// Linting section
|
|
733
|
+
if (analysis.linting) {
|
|
734
|
+
lines.push('\n🔍 Linting:');
|
|
735
|
+
if (analysis.linting.tool) {
|
|
736
|
+
lines.push(` Tool: ${analysis.linting.tool}`);
|
|
737
|
+
}
|
|
738
|
+
if (analysis.linting.plugins && analysis.linting.plugins.length > 0) {
|
|
739
|
+
lines.push(` Plugins: ${analysis.linting.plugins.join(', ')}`);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
// Monorepo section
|
|
743
|
+
if (analysis.monorepo) {
|
|
744
|
+
lines.push('\n📦 Monorepo:');
|
|
745
|
+
if (analysis.monorepo.tool) {
|
|
746
|
+
lines.push(` Tool: ${analysis.monorepo.tool}`);
|
|
747
|
+
}
|
|
748
|
+
if (analysis.monorepo.packages && analysis.monorepo.packages.length > 0) {
|
|
749
|
+
lines.push(' Packages:');
|
|
750
|
+
for (const pkg of analysis.monorepo.packages) {
|
|
751
|
+
lines.push(` - ${pkg}`);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
583
756
|
/**
|
|
584
757
|
* Compare two tech stacks and return differences
|
|
585
758
|
* Handles null previous analysis (first run)
|
|
@@ -15,6 +15,7 @@ export declare class DashboardLauncher {
|
|
|
15
15
|
private server;
|
|
16
16
|
start(context: RequestContext, options?: DashboardOptions): Promise<DashboardStartResult>;
|
|
17
17
|
stop(): Promise<void>;
|
|
18
|
+
restart(context: RequestContext, options?: DashboardOptions): Promise<DashboardStartResult>;
|
|
18
19
|
isRunning(): boolean;
|
|
19
20
|
}
|
|
20
21
|
//# sourceMappingURL=dashboard-launcher.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo-service.d.ts","sourceRoot":"","sources":["../../src/services/repo-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAIlE,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,WAAW;IAMV,OAAO,CAAC,OAAO;IAL3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAA2B;IACnE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAyB;IAE/D,OAAO,CAAC,aAAa,CAAgB;gBAEjB,OAAO,EAAE,cAAc;IAS3C;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACG,4BAA4B,CAChC,eAAe,GAAE,MAAoB,GACpC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmCzB;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOvD;;OAEG;IACH,cAAc,IAAI,OAAO;IAUzB;;;OAGG;IACG,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC;IAcjD;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAa5B;;;;;;;;OAQG;IACG,qBAAqB,CAAC,OAAO,GAAE,4BAAiC,GAAG,OAAO,CAAC,IAAI,CAAC;IA6FtF;;;OAGG;IACH,OAAO,CAAC,wBAAwB;
|
|
1
|
+
{"version":3,"file":"repo-service.d.ts","sourceRoot":"","sources":["../../src/services/repo-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAIlE,MAAM,WAAW,4BAA4B;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,qBAAa,WAAW;IAMV,OAAO,CAAC,OAAO;IAL3B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAA2B;IACnE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAyB;IAE/D,OAAO,CAAC,aAAa,CAAgB;gBAEjB,OAAO,EAAE,cAAc;IAS3C;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACG,4BAA4B,CAChC,eAAe,GAAE,MAAoB,GACpC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAmCzB;;;;OAIG;IACH,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOvD;;OAEG;IACH,cAAc,IAAI,OAAO;IAUzB;;;OAGG;IACG,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC;IAcjD;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAa5B;;;;;;;;OAQG;IACG,qBAAqB,CAAC,OAAO,GAAE,4BAAiC,GAAG,OAAO,CAAC,IAAI,CAAC;IA6FtF;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IA0BhC;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA6GlC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAoChC;;OAEG;IACH,OAAO,CAAC,6BAA6B;IAwErC;;OAEG;IACH,OAAO,CAAC,gCAAgC;CAyCzC"}
|
|
@@ -229,7 +229,8 @@ export class RepoService {
|
|
|
229
229
|
formatRepoContextSection(enableAgenticCoding) {
|
|
230
230
|
let content = `## Repository Context
|
|
231
231
|
|
|
232
|
-
Before starting work, read
|
|
232
|
+
Before starting work, read \`AGENTS.md\` for comprehensive project context (tech stack, commands, structure).
|
|
233
|
+
Also read \`.tiny-brain/analysis.json\` for detailed detection data and test patterns.
|
|
233
234
|
|
|
234
235
|
`;
|
|
235
236
|
if (enableAgenticCoding) {
|
|
@@ -292,6 +293,7 @@ Description of changes...
|
|
|
292
293
|
| \`fix:\` | Bug fixes | Yes |
|
|
293
294
|
| \`refactor:\` | Code improvement | Yes |
|
|
294
295
|
| \`chore:\` | Maintenance (untracked) | No |
|
|
296
|
+
| \`untracked:\` | Work not related to any PRD or Fix | No |
|
|
295
297
|
|
|
296
298
|
**WARNING:** The commit-msg hook will reject commits missing required headers.
|
|
297
299
|
|
|
@@ -0,0 +1,14 @@
|
|
|
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 - Restart the dashboard server
|
|
6
|
+
*
|
|
7
|
+
* Developer maintenance tool for force-reloading the dashboard,
|
|
8
|
+
* e.g. after rebuilding packages.
|
|
9
|
+
*/
|
|
10
|
+
export declare class DashboardTool {
|
|
11
|
+
static getToolDefinition(): MCPTool;
|
|
12
|
+
static execute(_args: ToolArguments, context: RequestContext): Promise<ToolResult>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=dashboard.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/dashboard/dashboard.tool.ts"],"names":[],"mappings":"AAAA,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;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,MAAM,CAAC,iBAAiB,IAAI,OAAO;WAatB,OAAO,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;CAiBzF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createErrorResult, createSuccessResult } from '../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Dashboard Tool - Restart the dashboard server
|
|
4
|
+
*
|
|
5
|
+
* Developer maintenance tool for force-reloading the dashboard,
|
|
6
|
+
* e.g. after rebuilding packages.
|
|
7
|
+
*/
|
|
8
|
+
export class DashboardTool {
|
|
9
|
+
static getToolDefinition() {
|
|
10
|
+
return {
|
|
11
|
+
name: 'dev_restart_dashboard',
|
|
12
|
+
description: 'Restart the dashboard server. Developer maintenance tool — only needed to force a reload of the dashboard (e.g. after rebuilding packages).',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {},
|
|
16
|
+
required: [],
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
static async execute(_args, context) {
|
|
21
|
+
const localContext = context;
|
|
22
|
+
const launcher = localContext.dashboardLauncher;
|
|
23
|
+
if (!launcher) {
|
|
24
|
+
return createErrorResult('Dashboard launcher is not available. The dashboard may not have been started.');
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const result = await launcher.restart(context, {});
|
|
28
|
+
return createSuccessResult(`Dashboard restarted successfully at ${result.url}`);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
return createErrorResult(`Failed to restart dashboard: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -500,8 +500,8 @@ export class AsTool {
|
|
|
500
500
|
if (libraryAuth?.token) {
|
|
501
501
|
formatted += ` 🔑 Connected to Tiny Brain Remote\n`;
|
|
502
502
|
}
|
|
503
|
-
if (libraryAuth?.
|
|
504
|
-
formatted += `
|
|
503
|
+
if (libraryAuth?.hasClaudeCli) {
|
|
504
|
+
formatted += ` 🤖 Claude CLI authenticated\n`;
|
|
505
505
|
}
|
|
506
506
|
// Only show pre-flight and agent-first workflow if agents are installed
|
|
507
507
|
if (hasAgents) {
|
|
@@ -22,6 +22,7 @@ export declare class QualityTool {
|
|
|
22
22
|
private static handleDetectAnalyzers;
|
|
23
23
|
private static handleRunAnalyzers;
|
|
24
24
|
private static handleAssembleRun;
|
|
25
|
+
private static handleImplementPlan;
|
|
25
26
|
private static handleMergeResults;
|
|
26
27
|
}
|
|
27
28
|
//# sourceMappingURL=quality.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quality.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/quality/quality.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,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;
|
|
1
|
+
{"version":3,"file":"quality.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/quality/quality.tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,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;AA0DrE;;GAEG;AACH,qBAAa,WAAW;IACtB,MAAM,CAAC,iBAAiB,IAAI,OAAO;WAiLtB,OAAO,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,UAAU,CAAC;mBAgDD,UAAU;mBAqCV,aAAa;mBA2Bb,aAAa;mBA2Eb,aAAa;mBAsEb,UAAU;mBA0CV,iBAAiB;mBAgEjB,qBAAqB;mBA6BrB,kBAAkB;mBAgDlB,iBAAiB;mBAmDjB,mBAAmB;IAiDxC,OAAO,CAAC,MAAM,CAAC,kBAAkB;CAoBlC"}
|
|
@@ -15,7 +15,8 @@ import { QualityService, AnalyzerDetectionService, AnalyzerExecutorService, Asse
|
|
|
15
15
|
const QualityArgsSchema = z.object({
|
|
16
16
|
operation: z.enum([
|
|
17
17
|
'save', 'history', 'details', 'compare', 'plan', 'plan-details',
|
|
18
|
-
'detect-
|
|
18
|
+
'detect-analysers', 'run-analysers', 'merge-results', 'assemble-run',
|
|
19
|
+
'implement-plan',
|
|
19
20
|
]),
|
|
20
21
|
// For 'save' operation
|
|
21
22
|
score: z.number().min(0).max(100).optional(),
|
|
@@ -63,10 +64,11 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
|
|
|
63
64
|
• compare: Compare two runs to see new, resolved, and persistent issues
|
|
64
65
|
• plan: Generate a Quality Improvement Plan from a saved run
|
|
65
66
|
• plan-details: Retrieve a saved Quality Improvement Plan by ID
|
|
66
|
-
• detect-
|
|
67
|
-
• run-
|
|
67
|
+
• detect-analysers: Scan repo for configured static analyzers
|
|
68
|
+
• run-analysers: Execute detected analyzers and return normalized issues
|
|
68
69
|
• merge-results: Merge analyzer + LLM issues with deduplication
|
|
69
70
|
• assemble-run: Read all intermediate files, merge, score, and save final report
|
|
71
|
+
• implement-plan: Generate fix documents from a saved Quality Improvement Plan
|
|
70
72
|
|
|
71
73
|
💡 WORKFLOW:
|
|
72
74
|
1. Quality-coordinator agent performs analysis
|
|
@@ -81,7 +83,8 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
|
|
|
81
83
|
type: 'string',
|
|
82
84
|
enum: [
|
|
83
85
|
'save', 'history', 'details', 'compare', 'plan', 'plan-details',
|
|
84
|
-
'detect-
|
|
86
|
+
'detect-analysers', 'run-analysers', 'merge-results', 'assemble-run',
|
|
87
|
+
'implement-plan',
|
|
85
88
|
],
|
|
86
89
|
description: 'The quality operation to perform',
|
|
87
90
|
},
|
|
@@ -164,7 +167,7 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
|
|
|
164
167
|
// For 'details' operation
|
|
165
168
|
runId: {
|
|
166
169
|
type: 'string',
|
|
167
|
-
description: 'Run ID
|
|
170
|
+
description: 'Run ID (required for details, assemble-run; optional for run-analysers to reuse Phase 1 directory)',
|
|
168
171
|
},
|
|
169
172
|
// For 'compare' operation
|
|
170
173
|
baseRunId: {
|
|
@@ -244,14 +247,16 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
|
|
|
244
247
|
return await QualityTool.handlePlan(validatedArgs, service);
|
|
245
248
|
case 'plan-details':
|
|
246
249
|
return await QualityTool.handlePlanDetails(validatedArgs, context.repositoryRoot);
|
|
247
|
-
case 'detect-
|
|
250
|
+
case 'detect-analysers':
|
|
248
251
|
return await QualityTool.handleDetectAnalyzers(context.repositoryRoot);
|
|
249
|
-
case 'run-
|
|
250
|
-
return await QualityTool.handleRunAnalyzers(context.repositoryRoot);
|
|
252
|
+
case 'run-analysers':
|
|
253
|
+
return await QualityTool.handleRunAnalyzers(validatedArgs, context.repositoryRoot);
|
|
251
254
|
case 'merge-results':
|
|
252
255
|
return QualityTool.handleMergeResults(validatedArgs);
|
|
253
256
|
case 'assemble-run':
|
|
254
257
|
return await QualityTool.handleAssembleRun(validatedArgs, context.repositoryRoot);
|
|
258
|
+
case 'implement-plan':
|
|
259
|
+
return await QualityTool.handleImplementPlan(validatedArgs, service);
|
|
255
260
|
default:
|
|
256
261
|
return createErrorResult(`Unknown operation: ${validatedArgs.operation}`);
|
|
257
262
|
}
|
|
@@ -527,8 +532,8 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
|
|
|
527
532
|
lines.push(JSON.stringify(analyzers, null, 2));
|
|
528
533
|
return createSuccessResult(lines.join('\n'));
|
|
529
534
|
}
|
|
530
|
-
static async handleRunAnalyzers(repositoryRoot) {
|
|
531
|
-
const runId = generateRunId();
|
|
535
|
+
static async handleRunAnalyzers(args, repositoryRoot) {
|
|
536
|
+
const runId = args.runId ?? generateRunId();
|
|
532
537
|
const runDir = path.join(repositoryRoot, 'docs', 'quality', 'runs', runIdToPath(runId));
|
|
533
538
|
const outputPath = path.join(runDir, 'analysis.json');
|
|
534
539
|
const outputDir = path.join(runDir, 'analysers');
|
|
@@ -576,6 +581,10 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
|
|
|
576
581
|
`🔍 Issues: ${result.issueCount}`,
|
|
577
582
|
`📁 File: ${result.filePath}`,
|
|
578
583
|
];
|
|
584
|
+
if (result.planId) {
|
|
585
|
+
lines.push(`📋 Plan: ${result.planId}`);
|
|
586
|
+
lines.push(`📁 Plan File: ${result.planFilePath}`);
|
|
587
|
+
}
|
|
579
588
|
if (result.incremental) {
|
|
580
589
|
lines.push('');
|
|
581
590
|
lines.push('### Incremental Analysis');
|
|
@@ -598,6 +607,43 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
|
|
|
598
607
|
}
|
|
599
608
|
return createSuccessResult(lines.join('\n'));
|
|
600
609
|
}
|
|
610
|
+
static async handleImplementPlan(args, service) {
|
|
611
|
+
if (!args.planId) {
|
|
612
|
+
return createErrorResult('planId is required for implement-plan operation');
|
|
613
|
+
}
|
|
614
|
+
const plan = await service.loadImprovementPlan(args.planId);
|
|
615
|
+
if (!plan) {
|
|
616
|
+
return createErrorResult(`Improvement plan not found: ${args.planId}`);
|
|
617
|
+
}
|
|
618
|
+
const run = await service.getRunDetails(plan.sourceRunId);
|
|
619
|
+
if (!run) {
|
|
620
|
+
return createErrorResult(`Source quality run not found: ${plan.sourceRunId}`);
|
|
621
|
+
}
|
|
622
|
+
const fixIds = await service.generateFixesFromPlan(plan, run.issues);
|
|
623
|
+
if (fixIds.length === 0) {
|
|
624
|
+
return createSuccessResult('No initiatives found in plan. No fix documents created.');
|
|
625
|
+
}
|
|
626
|
+
const lines = [
|
|
627
|
+
`Created ${fixIds.length} fix document(s) from Quality Improvement Plan ${args.planId}`,
|
|
628
|
+
'',
|
|
629
|
+
'## Fixes Created',
|
|
630
|
+
'',
|
|
631
|
+
'| Fix ID | File |',
|
|
632
|
+
'|--------|------|',
|
|
633
|
+
];
|
|
634
|
+
for (const fixId of fixIds) {
|
|
635
|
+
lines.push(`| ${fixId} | .tiny-brain/fixes/${fixId}.md |`);
|
|
636
|
+
}
|
|
637
|
+
lines.push('');
|
|
638
|
+
lines.push('## Next Steps');
|
|
639
|
+
lines.push('');
|
|
640
|
+
for (const fixId of fixIds) {
|
|
641
|
+
lines.push(`1. Run \`npx tiny-brain sync-file .tiny-brain/fixes/${fixId}.md\``);
|
|
642
|
+
}
|
|
643
|
+
lines.push('2. Start working on fixes using the /fix workflow');
|
|
644
|
+
lines.push('3. Track progress in the dashboard');
|
|
645
|
+
return createSuccessResult(lines.join('\n'));
|
|
646
|
+
}
|
|
601
647
|
static handleMergeResults(args) {
|
|
602
648
|
const analyzerIssues = args.analyzerIssues ?? [];
|
|
603
649
|
const llmIssues = args.llmIssues ?? [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-registry.d.ts","sourceRoot":"","sources":["../../src/tools/tool-registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
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,6 +15,7 @@ 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';
|
|
18
19
|
export class ToolRegistry {
|
|
19
20
|
/**
|
|
20
21
|
* Get all available tool definitions from all tools
|
|
@@ -36,6 +37,8 @@ export class ToolRegistry {
|
|
|
36
37
|
QualityTool.getToolDefinition(),
|
|
37
38
|
// Config tool - manages preferences with reactive agent sync
|
|
38
39
|
ConfigTool.getToolDefinition(),
|
|
40
|
+
// Dashboard tool - restart dashboard server (dev maintenance)
|
|
41
|
+
DashboardTool.getToolDefinition(),
|
|
39
42
|
// Response tools (disabled for later release)
|
|
40
43
|
// AnalyseRequestTool.getToolDefinition(),
|
|
41
44
|
// ValidateResponseTool.getToolDefinition(),
|
|
@@ -63,6 +66,7 @@ export class ToolRegistry {
|
|
|
63
66
|
update: UpdateTool,
|
|
64
67
|
quality: QualityTool,
|
|
65
68
|
config: ConfigTool,
|
|
69
|
+
dev_restart_dashboard: DashboardTool,
|
|
66
70
|
};
|
|
67
71
|
return toolMap[name];
|
|
68
72
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
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';
|
|
8
9
|
export interface LocalRequestContext extends RequestContext {
|
|
9
10
|
authToken?: AuthToken;
|
|
10
11
|
config?: {
|
|
@@ -13,5 +14,6 @@ export interface LocalRequestContext extends RequestContext {
|
|
|
13
14
|
clientSecret?: string;
|
|
14
15
|
};
|
|
15
16
|
};
|
|
17
|
+
dashboardLauncher?: DashboardLauncher;
|
|
16
18
|
}
|
|
17
19
|
//# 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;
|
|
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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@magic-ingredients/tiny-brain-local",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.1",
|
|
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.
|
|
34
|
+
"@magic-ingredients/tiny-brain-core": "^0.20.1",
|
|
35
35
|
"@magic-ingredients/tiny-brain-dashboard": "file:../tiny-brain-dashboard",
|
|
36
36
|
"@modelcontextprotocol/sdk": "^1.0.6",
|
|
37
37
|
"chalk": "^5.3.0",
|