@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.
Files changed (37) hide show
  1. package/dist/core/mcp-server.d.ts.map +1 -1
  2. package/dist/core/mcp-server.js +12 -8
  3. package/dist/core/repo-registration.d.ts +30 -0
  4. package/dist/core/repo-registration.d.ts.map +1 -0
  5. package/dist/core/repo-registration.js +34 -0
  6. package/dist/prompts/persona/persona.prompt.js +1 -1
  7. package/dist/prompts/planning/planning.prompt.d.ts +0 -8
  8. package/dist/prompts/planning/planning.prompt.d.ts.map +1 -1
  9. package/dist/prompts/planning/planning.prompt.js +0 -193
  10. package/dist/prompts/prompt-registry.d.ts.map +1 -1
  11. package/dist/prompts/prompt-registry.js +0 -2
  12. package/dist/services/analyse-service.d.ts +15 -29
  13. package/dist/services/analyse-service.d.ts.map +1 -1
  14. package/dist/services/analyse-service.js +99 -236
  15. package/dist/services/dashboard-launcher.service.d.ts +1 -0
  16. package/dist/services/dashboard-launcher.service.d.ts.map +1 -1
  17. package/dist/services/dashboard-launcher.service.js +4 -0
  18. package/dist/services/repo-service.d.ts +5 -0
  19. package/dist/services/repo-service.d.ts.map +1 -1
  20. package/dist/services/repo-service.js +67 -42
  21. package/dist/storage/local-filesystem-adapter.d.ts.map +1 -1
  22. package/dist/storage/local-filesystem-adapter.js +0 -3
  23. package/dist/tools/dashboard/dashboard.tool.d.ts +15 -0
  24. package/dist/tools/dashboard/dashboard.tool.d.ts.map +1 -0
  25. package/dist/tools/dashboard/dashboard.tool.js +81 -0
  26. package/dist/tools/plan/plan.tool.d.ts +0 -1
  27. package/dist/tools/plan/plan.tool.d.ts.map +1 -1
  28. package/dist/tools/plan/plan.tool.js +10 -56
  29. package/dist/tools/quality/quality.tool.js +1 -1
  30. package/dist/tools/recommendations/recommendations.tool.d.ts +13 -0
  31. package/dist/tools/recommendations/recommendations.tool.d.ts.map +1 -0
  32. package/dist/tools/recommendations/recommendations.tool.js +178 -0
  33. package/dist/tools/tool-registry.d.ts.map +1 -1
  34. package/dist/tools/tool-registry.js +8 -0
  35. package/dist/types/local-context.d.ts +2 -0
  36. package/dist/types/local-context.d.ts.map +1 -1
  37. 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
- Also read \`.tiny-brain/analysis.json\` for detailed detection data and test patterns.
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-file .tiny-brain/fixes/{fix-id}.md\`
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-file .tiny-brain/fixes/{fix-id}.md\`
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-file .tiny-brain/fixes/{fix-id}.md\`
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-file\` command updates \`progress.json\` from the markdown.
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
- - Tracked in: \`refactorCommitSha\` field
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
- **Why This Matters:**
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;IAe5E,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"}
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;AA2LrE,qBAAa,QAAQ;IACnB,MAAM,CAAC,iBAAiB,IAAI,OAAO;WA4LtB,OAAO,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,UAAU,CAAC;mBA2ED,YAAY;mBA+LZ,aAAa;mBAyCb,eAAe;mBA0Df,YAAY;mBA+CZ,YAAY;mBAsDZ,YAAY;mBAiCZ,UAAU;mBA2DV,aAAa;mBA2Cb,oBAAoB;mBA+CpB,mBAAmB;mBAsBnB,qBAAqB;mBAqCrB,SAAS;mBAgGT,eAAe;IAuFpC;;OAEG;mBACkB,UAAU;CA2DhC"}
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', 'archive', 'adr', 'create-adr', 'sync', 'start-dashboard', 'stop-dashboard', 'dashboard-status']),
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(['defined', 'tested', 'completed']).optional(),
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(['defined', 'tested', 'completed']).optional(),
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(['defined', 'tested', 'completed']).optional(),
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', 'archive', 'adr', 'create-adr', 'start-dashboard', 'stop-dashboard', 'dashboard-status'],
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: ['defined', 'tested', 'completed'] },
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: ['defined', 'tested', 'completed'] },
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: 'tested',
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 === 'tested' ? '🔄' : '📋';
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, archive, delete)',
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-file .tiny-brain/fixes/${fixId}.md\``);
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"}