@magic-ingredients/tiny-brain-local 0.20.0 → 0.21.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.map +1 -1
- package/dist/core/mcp-server.js +12 -8
- package/dist/core/repo-registration.d.ts +30 -0
- package/dist/core/repo-registration.d.ts.map +1 -0
- package/dist/core/repo-registration.js +34 -0
- package/dist/prompts/persona/persona.prompt.js +1 -1
- package/dist/prompts/planning/planning.prompt.d.ts +0 -8
- package/dist/prompts/planning/planning.prompt.d.ts.map +1 -1
- package/dist/prompts/planning/planning.prompt.js +0 -193
- package/dist/prompts/prompt-registry.d.ts.map +1 -1
- package/dist/prompts/prompt-registry.js +0 -2
- package/dist/services/analyse-service.d.ts +15 -29
- package/dist/services/analyse-service.d.ts.map +1 -1
- package/dist/services/analyse-service.js +99 -236
- 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 +5 -0
- package/dist/services/repo-service.d.ts.map +1 -1
- package/dist/services/repo-service.js +67 -42
- package/dist/storage/local-filesystem-adapter.d.ts.map +1 -1
- package/dist/storage/local-filesystem-adapter.js +0 -3
- package/dist/tools/dashboard/dashboard.tool.d.ts +15 -0
- package/dist/tools/dashboard/dashboard.tool.d.ts.map +1 -0
- package/dist/tools/dashboard/dashboard.tool.js +81 -0
- package/dist/tools/plan/plan.tool.d.ts +0 -1
- package/dist/tools/plan/plan.tool.d.ts.map +1 -1
- package/dist/tools/plan/plan.tool.js +10 -56
- package/dist/tools/quality/quality.tool.js +1 -1
- package/dist/tools/recommendations/recommendations.tool.d.ts +13 -0
- package/dist/tools/recommendations/recommendations.tool.d.ts.map +1 -0
- package/dist/tools/recommendations/recommendations.tool.js +178 -0
- package/dist/tools/tool-registry.d.ts.map +1 -1
- package/dist/tools/tool-registry.js +8 -0
- package/dist/types/local-context.d.ts +2 -0
- package/dist/types/local-context.d.ts.map +1 -1
- package/package.json +4 -10
|
@@ -155,7 +155,7 @@ export class RepoService {
|
|
|
155
155
|
// Build the workflow sections content
|
|
156
156
|
let workflowContent = '';
|
|
157
157
|
// Repository Context (always when workflow sections are enabled)
|
|
158
|
-
workflowContent += this.formatRepoContextSection(enableAgentic);
|
|
158
|
+
workflowContent += this.formatRepoContextSection(enableAgentic, options.isMonorepo);
|
|
159
159
|
// Commit Message Format (when SDD enabled)
|
|
160
160
|
if (enableSDD) {
|
|
161
161
|
workflowContent += this.formatCommitMessageSection();
|
|
@@ -168,6 +168,10 @@ export class RepoService {
|
|
|
168
168
|
if (enableSDD) {
|
|
169
169
|
workflowContent += this.formatProgressTrackingSection();
|
|
170
170
|
}
|
|
171
|
+
// Worktree Merge Workflow (when SDD enabled)
|
|
172
|
+
if (enableSDD) {
|
|
173
|
+
workflowContent += this.formatWorktreeMergeSection();
|
|
174
|
+
}
|
|
171
175
|
// Operational Tracking Directory (when SDD enabled)
|
|
172
176
|
if (enableSDD) {
|
|
173
177
|
workflowContent += this.formatOperationalTrackingSection();
|
|
@@ -226,13 +230,15 @@ export class RepoService {
|
|
|
226
230
|
* Format the Repository Context section
|
|
227
231
|
* When agentic coding is enabled, includes a mandatory agent delegation section
|
|
228
232
|
*/
|
|
229
|
-
formatRepoContextSection(enableAgenticCoding) {
|
|
230
|
-
let content = `## Repository Context
|
|
231
|
-
|
|
232
|
-
Before starting work, read \`AGENTS.md\` for comprehensive project context (tech stack, commands, structure).
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
`;
|
|
233
|
+
formatRepoContextSection(enableAgenticCoding, isMonorepo) {
|
|
234
|
+
let content = `## Repository Context\n\n`;
|
|
235
|
+
if (isMonorepo) {
|
|
236
|
+
content += `Before starting work, read the root \`AGENTS.md\` for comprehensive project context (tech stack, commands, structure).\nWhen working in a specific package, also read that package's \`AGENTS.md\` for package-specific details.\n`;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
content += `Before starting work, read \`AGENTS.md\` for comprehensive project context (tech stack, commands, structure).\n`;
|
|
240
|
+
}
|
|
241
|
+
content += `Also read \`.tiny-brain/analysis.json\` for detailed detection data and test patterns.\n\n`;
|
|
236
242
|
if (enableAgenticCoding) {
|
|
237
243
|
content += `## Agent Delegation (MANDATORY)
|
|
238
244
|
|
|
@@ -297,19 +303,6 @@ Description of changes...
|
|
|
297
303
|
|
|
298
304
|
**WARNING:** The commit-msg hook will reject commits missing required headers.
|
|
299
305
|
|
|
300
|
-
### Updating Markdown After Commits
|
|
301
|
-
|
|
302
|
-
**For PRD tasks:**
|
|
303
|
-
1. Open the feature file: \`docs/prd/{prd-id}/features/{feature-id}.md\`
|
|
304
|
-
2. Update the task with status and commitSha:
|
|
305
|
-
\`\`\`markdown
|
|
306
|
-
### 1. Task description
|
|
307
|
-
status: completed
|
|
308
|
-
commitSha: abc1234
|
|
309
|
-
\`\`\`
|
|
310
|
-
3. Run: \`npx tiny-brain sync-file docs/prd/{prd-id}/features/{feature-id}.md\`
|
|
311
|
-
4. If ALL tasks in the feature are complete, update the PRD status
|
|
312
|
-
|
|
313
306
|
### Fix Status Workflow
|
|
314
307
|
|
|
315
308
|
Fix documents have three statuses: \`documented\` → \`in_progress\` → \`resolved\`
|
|
@@ -317,7 +310,7 @@ Fix documents have three statuses: \`documented\` → \`in_progress\` → \`reso
|
|
|
317
310
|
**When starting work on a fix:**
|
|
318
311
|
1. Open the fix file: \`.tiny-brain/fixes/{fix-id}.md\`
|
|
319
312
|
2. Update frontmatter: \`status: in_progress\`
|
|
320
|
-
3. Run: \`npx tiny-brain sync-
|
|
313
|
+
3. Run: \`npx tiny-brain sync-progress .tiny-brain/fixes/{fix-id}.md\`
|
|
321
314
|
|
|
322
315
|
**After each commit:**
|
|
323
316
|
1. Update the completed task(s) in the markdown:
|
|
@@ -333,7 +326,7 @@ Fix documents have three statuses: \`documented\` → \`in_progress\` → \`reso
|
|
|
333
326
|
status: superseded
|
|
334
327
|
commitSha: null
|
|
335
328
|
\`\`\`
|
|
336
|
-
4. Run: \`npx tiny-brain sync-
|
|
329
|
+
4. Run: \`npx tiny-brain sync-progress .tiny-brain/fixes/{fix-id}.md\`
|
|
337
330
|
|
|
338
331
|
**When all tasks are complete:**
|
|
339
332
|
1. **ONLY set \`status: resolved\`** when ALL tasks are accounted for:
|
|
@@ -354,9 +347,9 @@ Fix documents have three statuses: \`documented\` → \`in_progress\` → \`reso
|
|
|
354
347
|
- path/to/file1.ts
|
|
355
348
|
- path/to/file2.ts
|
|
356
349
|
\`\`\`
|
|
357
|
-
3. Run: \`npx tiny-brain sync-
|
|
350
|
+
3. Run: \`npx tiny-brain sync-progress .tiny-brain/fixes/{fix-id}.md\`
|
|
358
351
|
|
|
359
|
-
**Note:** The markdown file is the source of truth. The \`sync-
|
|
352
|
+
**Note:** The markdown file is the source of truth. The \`sync-progress\` command updates \`progress.json\` from the markdown.
|
|
360
353
|
|
|
361
354
|
`;
|
|
362
355
|
}
|
|
@@ -371,30 +364,38 @@ IMPORTANT: This repository follows strict Test-Driven Development (TDD) with a 3
|
|
|
371
364
|
**Red → Green → Refactor Cycle:**
|
|
372
365
|
|
|
373
366
|
1. **Red Phase** (\`test:\` or \`test(scope):\` commits):
|
|
367
|
+
- **CRITICAL — you MUST run before writing tests:**
|
|
368
|
+
\`npx tiny-brain update-phase --phase red --event start --task '...' [--fix ID | --prd ID --feature ID]\`
|
|
374
369
|
- Write failing tests first
|
|
375
370
|
- Tests SHOULD fail (that's the point!)
|
|
376
371
|
- Use: \`git commit -m "test: ..."\` or \`git commit -m "test(api): ..."\`
|
|
377
372
|
- Git hook automatically runs typecheck + lint but SKIPS tests
|
|
378
373
|
- Tracked in: \`testCommitSha\` field
|
|
374
|
+
- **After commit:** post-commit hook automatically transitions to \`green:start\`
|
|
379
375
|
|
|
380
376
|
2. **Green Phase** (\`feat:\` or \`feat(scope):\` commits):
|
|
377
|
+
- Phase started automatically by post-commit hook after \`test:\` commit (no manual step needed)
|
|
381
378
|
- Implement minimum code to make tests pass
|
|
382
379
|
- Use: \`git commit -m "feat: ..."\` or \`git commit -m "feat(auth): ..."\`
|
|
383
380
|
- Git hook automatically runs full checks (typecheck + lint + test)
|
|
384
381
|
- Tracked in: \`commitSha\` field
|
|
385
382
|
- **Marks task as COMPLETED**
|
|
383
|
+
- **After commit:** adversarial review hook sets \`adversarial:start\` and outputs review instructions
|
|
386
384
|
|
|
387
385
|
3. **Refactor Phase** (\`refactor:\` or \`refactor(scope):\` commits - optional):
|
|
386
|
+
- Triggered by adversarial review suggestions
|
|
388
387
|
- Improve code quality without changing behavior
|
|
389
388
|
- Use: \`git commit -m "refactor: ..."\` or \`git commit -m "refactor(plan): ..."\`
|
|
390
389
|
- Git hook automatically runs full checks (typecheck + lint + test)
|
|
391
|
-
-
|
|
390
|
+
- **After commit:** post-commit hook automatically transitions \`adversarial-refactor:complete\`
|
|
391
|
+
|
|
392
|
+
4. **Progress Commit** (end of cycle):
|
|
393
|
+
- After the full RED→GREEN→REFACTOR cycle is complete
|
|
394
|
+
- Run: \`npx tiny-brain commit-progress\`
|
|
395
|
+
|
|
396
|
+
**What you must do manually:** Only \`update-phase --phase red --event start\` before writing tests. Everything else is automated by hooks.
|
|
392
397
|
|
|
393
|
-
**
|
|
394
|
-
- Git hooks automatically detect commit type and run appropriate checks
|
|
395
|
-
- Separate commit tracking enables Feature 9 (TDD phase tracking in dashboard)
|
|
396
|
-
- Provides audit trail of development process
|
|
397
|
-
- Only \`feat:\` or \`feat(scope):\` commits mark tasks as completed
|
|
398
|
+
**What you must NOT do:** Do not manually call \`update-phase\` for green:start, adversarial:start, or adversarial-refactor:complete — the hooks handle these.
|
|
398
399
|
|
|
399
400
|
`;
|
|
400
401
|
}
|
|
@@ -410,18 +411,11 @@ By default, tiny-brain uses **manual mode** for progress.json commits. This mean
|
|
|
410
411
|
|
|
411
412
|
When you complete a task with a \`feat:\` or \`test:\` commit:
|
|
412
413
|
1. The post-commit hook updates progress.json automatically
|
|
413
|
-
2. You'll see a friendly message with instructions
|
|
414
|
+
2. You'll see a friendly message with instructions
|
|
415
|
+
3. Commit the progress.json changes by running:
|
|
416
|
+
\`\`\`bash
|
|
417
|
+
npx tiny-brain commit-progress
|
|
414
418
|
\`\`\`
|
|
415
|
-
📝 Progress tracking updated!
|
|
416
|
-
|
|
417
|
-
To commit progress.json changes, run:
|
|
418
|
-
git add .tiny-brain/progress/*.json
|
|
419
|
-
git commit -m "chore: update progress tracking"
|
|
420
|
-
|
|
421
|
-
💡 Tip: Enable auto-commit to skip this step:
|
|
422
|
-
npx tiny-brain config preferences set autoCommitProgress true
|
|
423
|
-
\`\`\`
|
|
424
|
-
3. Commit the progress.json changes when you're ready
|
|
425
419
|
|
|
426
420
|
### Enabling Auto-Commit
|
|
427
421
|
|
|
@@ -470,6 +464,37 @@ Settings follow this precedence (highest to lowest):
|
|
|
470
464
|
|
|
471
465
|
This allows you to set a global preference but override it per repository as needed.
|
|
472
466
|
|
|
467
|
+
`;
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Format the Worktree Merge Workflow section
|
|
471
|
+
*/
|
|
472
|
+
formatWorktreeMergeSection() {
|
|
473
|
+
return `## Worktree Merge Workflow
|
|
474
|
+
|
|
475
|
+
When merging a worktree branch back into the main branch, \`progress.json\` files may conflict because both branches tracked different task completions. The \`post-merge\` git hook handles this automatically.
|
|
476
|
+
|
|
477
|
+
### How It Works
|
|
478
|
+
|
|
479
|
+
1. After a merge, the hook detects if any \`.tiny-brain/progress/*.json\` or \`.tiny-brain/fixes/progress.json\` files changed
|
|
480
|
+
2. If so, it re-runs \`npx tiny-brain sync-progress\` on all markdown sources to regenerate progress.json
|
|
481
|
+
3. The regenerated files are staged and committed as \`chore: re-sync progress after merge\`
|
|
482
|
+
|
|
483
|
+
### Handling Merge Conflicts in progress.json
|
|
484
|
+
|
|
485
|
+
If you encounter a merge conflict in progress.json:
|
|
486
|
+
1. Accept either version (it doesn't matter which)
|
|
487
|
+
2. Complete the merge
|
|
488
|
+
3. The post-merge hook will regenerate progress.json from the markdown sources automatically
|
|
489
|
+
|
|
490
|
+
### Manual Re-sync
|
|
491
|
+
|
|
492
|
+
If the hook doesn't run or you need to re-sync manually:
|
|
493
|
+
\`\`\`bash
|
|
494
|
+
npx tiny-brain sync-progress docs/prd/*/features/*.md
|
|
495
|
+
npx tiny-brain sync-progress .tiny-brain/fixes/*.md
|
|
496
|
+
\`\`\`
|
|
497
|
+
|
|
473
498
|
`;
|
|
474
499
|
}
|
|
475
500
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-filesystem-adapter.d.ts","sourceRoot":"","sources":["../../src/storage/local-filesystem-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAOnF;;GAEG;AACH,qBAAa,6BAA8B,YAAW,wBAAwB;IAC5E,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,UAAU,CAAU;IACrB,WAAW,EAAE,MAAM,CAAC;gBAEf,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE;IAMvD,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYtD,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAYV,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAanB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvF,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqCxE,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAuBjD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAajE,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"local-filesystem-adapter.d.ts","sourceRoot":"","sources":["../../src/storage/local-filesystem-adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAOnF;;GAEG;AACH,qBAAa,6BAA8B,YAAW,wBAAwB;IAC5E,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,UAAU,CAAU;IACrB,WAAW,EAAE,MAAM,CAAC;gBAEf,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAA;KAAE;IAMvD,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYtD,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAYV,cAAc,CAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAanB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYvF,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAqCxE,YAAY,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAuBjD,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAajE,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5E,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY5E,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAalE,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY5D,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAiB/B,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDhG,iBAAiB,IAAI;QACnB,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;QACzB,WAAW,CAAC,EAAE,OAAO,oCAAoC,EAAE,iBAAiB,CAAC;QAC7E,iBAAiB,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB;IAQD;;OAEG;YACW,qBAAqB;IAWnC;;OAEG;IACH,WAAW,IAAI,MAAM;CAGtB"}
|
|
@@ -125,9 +125,6 @@ export class LocalFilesystemStorageAdapter {
|
|
|
125
125
|
const personaDir = this.pathBuilder.buildPersonaDirectoryPath(personaId);
|
|
126
126
|
// Create main persona directory
|
|
127
127
|
await this.ensureDirectoryExists(personaDir);
|
|
128
|
-
// Create plans subdirectory
|
|
129
|
-
const plansDir = join(personaDir, 'plans');
|
|
130
|
-
await this.ensureDirectoryExists(plansDir);
|
|
131
128
|
}
|
|
132
129
|
async storeUserData(key, content, _userId) {
|
|
133
130
|
const filePath = this.pathBuilder.buildUserDataPath(key);
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
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
|
+
}
|
|
@@ -11,7 +11,6 @@ export declare class PlanTool {
|
|
|
11
11
|
private static handleStatus;
|
|
12
12
|
private static handleReport;
|
|
13
13
|
private static handleList;
|
|
14
|
-
private static handleArchive;
|
|
15
14
|
private static handleStartDashboard;
|
|
16
15
|
private static handleStopDashboard;
|
|
17
16
|
private static handleDashboardStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/plan/plan.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;
|
|
1
|
+
{"version":3,"file":"plan.tool.d.ts","sourceRoot":"","sources":["../../../src/tools/plan/plan.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;AAsLrE,qBAAa,QAAQ;IACnB,MAAM,CAAC,iBAAiB,IAAI,OAAO;WAgLtB,OAAO,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,UAAU,CAAC;mBAyED,YAAY;mBA+LZ,aAAa;mBAyCb,eAAe;mBA0Df,YAAY;mBA+CZ,YAAY;mBAsDZ,YAAY;mBAiCZ,UAAU;mBA2DV,oBAAoB;mBA+CpB,mBAAmB;mBAsBnB,qBAAqB;mBAqCrB,SAAS;mBAgGT,eAAe;IAuFpC;;OAEG;mBACkB,UAAU;CA2DhC"}
|
|
@@ -9,7 +9,7 @@ import { exec } from 'child_process';
|
|
|
9
9
|
import { promisify } from 'util';
|
|
10
10
|
const execAsync = promisify(exec);
|
|
11
11
|
const PlanArgsSchema = z.object({
|
|
12
|
-
operation: z.enum(['accept', 'feature', 'implement', 'update', 'status', 'report', 'list', '
|
|
12
|
+
operation: z.enum(['accept', 'feature', 'implement', 'update', 'status', 'report', 'list', 'adr', 'create-adr', 'sync', 'start-dashboard', 'stop-dashboard', 'dashboard-status']),
|
|
13
13
|
// For 'accept' operation
|
|
14
14
|
planName: z.string().optional(),
|
|
15
15
|
planDetails: z.string().optional(),
|
|
@@ -39,12 +39,12 @@ const PlanArgsSchema = z.object({
|
|
|
39
39
|
updateFeature: z
|
|
40
40
|
.object({
|
|
41
41
|
featureNumber: z.number(),
|
|
42
|
-
status: z.enum(['
|
|
42
|
+
status: z.enum(['not_started', 'in_progress', 'completed', 'superseded']).optional(),
|
|
43
43
|
addTask: z.string().optional(),
|
|
44
44
|
addTasks: z.array(z.string()).optional(),
|
|
45
45
|
updateTask: z.object({
|
|
46
46
|
id: z.string(),
|
|
47
|
-
status: z.enum(['
|
|
47
|
+
status: z.enum(['not_started', 'in_progress', 'completed', 'superseded']).optional(),
|
|
48
48
|
testCommitSha: z.string().optional(),
|
|
49
49
|
testCommittedAt: z.string().optional(),
|
|
50
50
|
commitSha: z.string().optional(),
|
|
@@ -58,7 +58,7 @@ const PlanArgsSchema = z.object({
|
|
|
58
58
|
updateFeatures: z
|
|
59
59
|
.array(z.object({
|
|
60
60
|
featureNumber: z.number(),
|
|
61
|
-
status: z.enum(['
|
|
61
|
+
status: z.enum(['not_started', 'in_progress', 'completed', 'superseded']).optional(),
|
|
62
62
|
addTask: z.string().optional(),
|
|
63
63
|
addTasks: z.array(z.string()).optional(),
|
|
64
64
|
}))
|
|
@@ -71,11 +71,6 @@ const PlanArgsSchema = z.object({
|
|
|
71
71
|
saveToFile: z.boolean().optional(),
|
|
72
72
|
// For 'list' operation
|
|
73
73
|
listStatus: z.enum(['active', 'completed', 'archived', 'all']).optional(),
|
|
74
|
-
// For 'archive' operation
|
|
75
|
-
reason: z.string().optional(),
|
|
76
|
-
// For 'switch' operation
|
|
77
|
-
// planId is reused from update operation
|
|
78
|
-
// Note: switchToPlan automatically unarchives if needed
|
|
79
74
|
// For 'watch' operation
|
|
80
75
|
port: z.number().optional().default(8765),
|
|
81
76
|
autoOpen: z.boolean().optional().default(true),
|
|
@@ -190,7 +185,6 @@ export class PlanTool {
|
|
|
190
185
|
• status: Show current plan progress and summary
|
|
191
186
|
• report: Generate and display comprehensive markdown report
|
|
192
187
|
• list: List all plans (active, completed, archived)
|
|
193
|
-
• archive: Archive a completed plan
|
|
194
188
|
• adr: Analyze recent commits for ADR suggestions and prompt for creation
|
|
195
189
|
• create-adr: Create ADR file from suggestion (used after user confirmation)
|
|
196
190
|
• start-dashboard: Manually start the dashboard (usually auto-started)
|
|
@@ -236,7 +230,7 @@ export class PlanTool {
|
|
|
236
230
|
properties: {
|
|
237
231
|
operation: {
|
|
238
232
|
type: 'string',
|
|
239
|
-
enum: ['accept', 'feature', 'implement', 'update', 'status', 'report', 'list', '
|
|
233
|
+
enum: ['accept', 'feature', 'implement', 'update', 'status', 'report', 'list', 'adr', 'create-adr', 'start-dashboard', 'stop-dashboard', 'dashboard-status'],
|
|
240
234
|
description: 'The planning operation to perform',
|
|
241
235
|
},
|
|
242
236
|
// For 'accept' operation
|
|
@@ -294,13 +288,13 @@ export class PlanTool {
|
|
|
294
288
|
type: 'object',
|
|
295
289
|
properties: {
|
|
296
290
|
featureNumber: { type: 'number' },
|
|
297
|
-
status: { type: 'string', enum: ['
|
|
291
|
+
status: { type: 'string', enum: ['not_started', 'in_progress', 'completed', 'superseded'] },
|
|
298
292
|
addTask: { type: 'string' },
|
|
299
293
|
updateTask: {
|
|
300
294
|
type: 'object',
|
|
301
295
|
properties: {
|
|
302
296
|
id: { type: 'string' },
|
|
303
|
-
status: { type: 'string', enum: ['
|
|
297
|
+
status: { type: 'string', enum: ['not_started', 'in_progress', 'completed', 'superseded'] },
|
|
304
298
|
testCommitSha: { type: 'string' },
|
|
305
299
|
testCommittedAt: { type: 'string' },
|
|
306
300
|
commitSha: { type: 'string' },
|
|
@@ -330,17 +324,6 @@ export class PlanTool {
|
|
|
330
324
|
enum: ['active', 'completed', 'archived', 'all'],
|
|
331
325
|
description: 'Filter plans by status',
|
|
332
326
|
},
|
|
333
|
-
// For 'archive' operation
|
|
334
|
-
reason: {
|
|
335
|
-
type: 'string',
|
|
336
|
-
description: 'Reason for archiving',
|
|
337
|
-
},
|
|
338
|
-
// For 'switch' operation
|
|
339
|
-
// planId is reused from update operation
|
|
340
|
-
force: {
|
|
341
|
-
type: 'boolean',
|
|
342
|
-
description: 'Force switch to archived plans (optional)',
|
|
343
|
-
},
|
|
344
327
|
// For 'watch' operation
|
|
345
328
|
port: {
|
|
346
329
|
type: 'number',
|
|
@@ -400,8 +383,6 @@ export class PlanTool {
|
|
|
400
383
|
return await PlanTool.handleReport(validatedArgs, contextWithRepo);
|
|
401
384
|
case 'list':
|
|
402
385
|
return await PlanTool.handleList(validatedArgs, contextWithRepo);
|
|
403
|
-
case 'archive':
|
|
404
|
-
return await PlanTool.handleArchive(validatedArgs, contextWithRepo);
|
|
405
386
|
case 'adr':
|
|
406
387
|
return await PlanTool.handleAdr(validatedArgs, contextWithRepo);
|
|
407
388
|
case 'create-adr':
|
|
@@ -565,7 +546,7 @@ export class PlanTool {
|
|
|
565
546
|
},
|
|
566
547
|
{
|
|
567
548
|
featureNumber: 2,
|
|
568
|
-
status: '
|
|
549
|
+
status: 'in_progress',
|
|
569
550
|
addTasks: ['New task 1', 'New task 2'],
|
|
570
551
|
},
|
|
571
552
|
],
|
|
@@ -640,7 +621,7 @@ export class PlanTool {
|
|
|
640
621
|
...plan.features.map((feature, i) => {
|
|
641
622
|
const taskCount = feature.tasks?.length || 0;
|
|
642
623
|
const completedCount = feature.tasks?.filter(t => t.completedAt).length || 0;
|
|
643
|
-
const statusEmoji = feature.status === 'completed' ? '✅' : feature.status === '
|
|
624
|
+
const statusEmoji = feature.status === 'completed' ? '✅' : feature.status === 'in_progress' ? '🔄' : '📋';
|
|
644
625
|
return `${statusEmoji} **Feature ${i + 1}: ${feature.title}** (${completedCount}/${taskCount} tasks complete)`;
|
|
645
626
|
}),
|
|
646
627
|
``,
|
|
@@ -805,33 +786,6 @@ export class PlanTool {
|
|
|
805
786
|
return createErrorResult(`Failed to list plans: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
806
787
|
}
|
|
807
788
|
}
|
|
808
|
-
static async handleArchive(args, context) {
|
|
809
|
-
try {
|
|
810
|
-
// planId is required for archive operation
|
|
811
|
-
if (!args.planId) {
|
|
812
|
-
return createErrorResult('Plan ID is required for archive operation. Use "plan operation=list" to see available plans.');
|
|
813
|
-
}
|
|
814
|
-
// Create service with RequestContext
|
|
815
|
-
const planningService = new PlanningService(context);
|
|
816
|
-
// Load the specific plan to archive
|
|
817
|
-
const plan = await planningService.loadPlan({ planId: args.planId });
|
|
818
|
-
if (!plan) {
|
|
819
|
-
return createErrorResult(`Plan not found: ${args.planId}. Use "plan operation=list" to see available plans.`);
|
|
820
|
-
}
|
|
821
|
-
// Archive the plan with explicit args
|
|
822
|
-
const archived = await planningService.archivePlan({
|
|
823
|
-
planId: plan.id,
|
|
824
|
-
reason: args.reason
|
|
825
|
-
});
|
|
826
|
-
if (!archived) {
|
|
827
|
-
return createErrorResult('Failed to archive plan.');
|
|
828
|
-
}
|
|
829
|
-
return createSuccessResult(`✅ Archived plan: "${plan.title}"\nReason: ${args.reason || 'Completed'}`);
|
|
830
|
-
}
|
|
831
|
-
catch (error) {
|
|
832
|
-
return createErrorResult(`Failed to archive plan: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
789
|
static async handleStartDashboard(args, context) {
|
|
836
790
|
try {
|
|
837
791
|
// Check if dashboard is already running
|
|
@@ -856,7 +810,7 @@ export class PlanTool {
|
|
|
856
810
|
'',
|
|
857
811
|
'The dashboard provides:',
|
|
858
812
|
'• Real-time plan monitoring',
|
|
859
|
-
'• Plan management (create,
|
|
813
|
+
'• Plan management (create, delete)',
|
|
860
814
|
'• Persona overview',
|
|
861
815
|
'• Auto-refresh on changes',
|
|
862
816
|
'',
|
|
@@ -638,7 +638,7 @@ Persists and retrieves quality analysis results. Analysis is performed by agents
|
|
|
638
638
|
lines.push('## Next Steps');
|
|
639
639
|
lines.push('');
|
|
640
640
|
for (const fixId of fixIds) {
|
|
641
|
-
lines.push(`1. Run \`npx tiny-brain sync-
|
|
641
|
+
lines.push(`1. Run \`npx tiny-brain sync-progress .tiny-brain/fixes/${fixId}.md\``);
|
|
642
642
|
}
|
|
643
643
|
lines.push('2. Start working on fixes using the /fix workflow');
|
|
644
644
|
lines.push('3. Track progress in the dashboard');
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ToolResult } from '../index.js';
|
|
2
|
+
import type { RequestContext } from '../../types/request-context.js';
|
|
3
|
+
import { Tool as MCPTool } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
export declare class RecommendationsTool {
|
|
5
|
+
static getToolDefinition(): MCPTool;
|
|
6
|
+
static execute(args: Record<string, unknown>, context: RequestContext): Promise<ToolResult>;
|
|
7
|
+
private static handleList;
|
|
8
|
+
private static handleAccept;
|
|
9
|
+
private static handleDismiss;
|
|
10
|
+
private static handleRestore;
|
|
11
|
+
private static handleGraduated;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=recommendations.tool.d.ts.map
|
|
@@ -0,0 +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"}
|