@planu/cli 1.12.0 → 1.13.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 (128) hide show
  1. package/dist/config/ai-tool-registry.json +71 -0
  2. package/dist/config/autopilot-config.json +21 -0
  3. package/dist/config/competitive-catalog.json +83 -0
  4. package/dist/config/license-plans.json +17 -1
  5. package/dist/engine/agent-registry/lifecycle-manager.d.ts +8 -0
  6. package/dist/engine/agent-registry/lifecycle-manager.d.ts.map +1 -0
  7. package/dist/engine/agent-registry/lifecycle-manager.js +81 -0
  8. package/dist/engine/agent-registry/lifecycle-manager.js.map +1 -0
  9. package/dist/engine/agent-registry/role-catalog.d.ts +17 -0
  10. package/dist/engine/agent-registry/role-catalog.d.ts.map +1 -0
  11. package/dist/engine/agent-registry/role-catalog.js +55 -0
  12. package/dist/engine/agent-registry/role-catalog.js.map +1 -0
  13. package/dist/engine/autopilot/action-executor.d.ts +18 -0
  14. package/dist/engine/autopilot/action-executor.d.ts.map +1 -0
  15. package/dist/engine/autopilot/action-executor.js +91 -0
  16. package/dist/engine/autopilot/action-executor.js.map +1 -0
  17. package/dist/engine/autopilot/event-bus.d.ts +8 -0
  18. package/dist/engine/autopilot/event-bus.d.ts.map +1 -0
  19. package/dist/engine/autopilot/event-bus.js +28 -0
  20. package/dist/engine/autopilot/event-bus.js.map +1 -0
  21. package/dist/engine/autopilot/trigger-rules.d.ts +3 -0
  22. package/dist/engine/autopilot/trigger-rules.d.ts.map +1 -0
  23. package/dist/engine/autopilot/trigger-rules.js +125 -0
  24. package/dist/engine/autopilot/trigger-rules.js.map +1 -0
  25. package/dist/engine/competitive/gap-analyzer.d.ts +12 -0
  26. package/dist/engine/competitive/gap-analyzer.d.ts.map +1 -0
  27. package/dist/engine/competitive/gap-analyzer.js +214 -0
  28. package/dist/engine/competitive/gap-analyzer.js.map +1 -0
  29. package/dist/engine/hook-generator/ai-hook-templates.d.ts +8 -0
  30. package/dist/engine/hook-generator/ai-hook-templates.d.ts.map +1 -0
  31. package/dist/engine/hook-generator/ai-hook-templates.js +43 -0
  32. package/dist/engine/hook-generator/ai-hook-templates.js.map +1 -0
  33. package/dist/engine/hook-generator/hook-merger.d.ts +13 -0
  34. package/dist/engine/hook-generator/hook-merger.d.ts.map +1 -0
  35. package/dist/engine/hook-generator/hook-merger.js +148 -0
  36. package/dist/engine/hook-generator/hook-merger.js.map +1 -0
  37. package/dist/engine/hook-generator/stack-hook-templates.d.ts +10 -0
  38. package/dist/engine/hook-generator/stack-hook-templates.d.ts.map +1 -0
  39. package/dist/engine/hook-generator/stack-hook-templates.js +105 -0
  40. package/dist/engine/hook-generator/stack-hook-templates.js.map +1 -0
  41. package/dist/engine/project-dna/ai-tool-detector.d.ts +12 -0
  42. package/dist/engine/project-dna/ai-tool-detector.d.ts.map +1 -0
  43. package/dist/engine/project-dna/ai-tool-detector.js +103 -0
  44. package/dist/engine/project-dna/ai-tool-detector.js.map +1 -0
  45. package/dist/engine/project-dna/rules-generator.d.ts +18 -0
  46. package/dist/engine/project-dna/rules-generator.d.ts.map +1 -0
  47. package/dist/engine/project-dna/rules-generator.js +193 -0
  48. package/dist/engine/project-dna/rules-generator.js.map +1 -0
  49. package/dist/engine/project-dna/stack-detector.d.ts +24 -0
  50. package/dist/engine/project-dna/stack-detector.d.ts.map +1 -0
  51. package/dist/engine/project-dna/stack-detector.js +309 -0
  52. package/dist/engine/project-dna/stack-detector.js.map +1 -0
  53. package/dist/index.js +10 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/storage/agent-registry-store.d.ts +11 -0
  56. package/dist/storage/agent-registry-store.d.ts.map +1 -0
  57. package/dist/storage/agent-registry-store.js +45 -0
  58. package/dist/storage/agent-registry-store.js.map +1 -0
  59. package/dist/tools/competitive-handlers.d.ts +30 -0
  60. package/dist/tools/competitive-handlers.d.ts.map +1 -0
  61. package/dist/tools/competitive-handlers.js +155 -0
  62. package/dist/tools/competitive-handlers.js.map +1 -0
  63. package/dist/tools/create-spec/post-creation.d.ts +1 -1
  64. package/dist/tools/create-spec/post-creation.d.ts.map +1 -1
  65. package/dist/tools/create-spec/post-creation.js +13 -1
  66. package/dist/tools/create-spec/post-creation.js.map +1 -1
  67. package/dist/tools/create-spec.js +1 -1
  68. package/dist/tools/create-spec.js.map +1 -1
  69. package/dist/tools/hook-generator-handler.d.ts +8 -0
  70. package/dist/tools/hook-generator-handler.d.ts.map +1 -0
  71. package/dist/tools/hook-generator-handler.js +154 -0
  72. package/dist/tools/hook-generator-handler.js.map +1 -0
  73. package/dist/tools/project-dna-handler.d.ts +34 -0
  74. package/dist/tools/project-dna-handler.d.ts.map +1 -0
  75. package/dist/tools/project-dna-handler.js +261 -0
  76. package/dist/tools/project-dna-handler.js.map +1 -0
  77. package/dist/tools/register-agent-registry.d.ts +5 -0
  78. package/dist/tools/register-agent-registry.d.ts.map +1 -0
  79. package/dist/tools/register-agent-registry.js +254 -0
  80. package/dist/tools/register-agent-registry.js.map +1 -0
  81. package/dist/tools/register-autopilot.d.ts +3 -0
  82. package/dist/tools/register-autopilot.d.ts.map +1 -0
  83. package/dist/tools/register-autopilot.js +78 -0
  84. package/dist/tools/register-autopilot.js.map +1 -0
  85. package/dist/tools/register-competitive.d.ts +3 -0
  86. package/dist/tools/register-competitive.d.ts.map +1 -0
  87. package/dist/tools/register-competitive.js +88 -0
  88. package/dist/tools/register-competitive.js.map +1 -0
  89. package/dist/tools/register-hook-generator.d.ts +3 -0
  90. package/dist/tools/register-hook-generator.d.ts.map +1 -0
  91. package/dist/tools/register-hook-generator.js +96 -0
  92. package/dist/tools/register-hook-generator.js.map +1 -0
  93. package/dist/tools/register-project-dna.d.ts +3 -0
  94. package/dist/tools/register-project-dna.d.ts.map +1 -0
  95. package/dist/tools/register-project-dna.js +43 -0
  96. package/dist/tools/register-project-dna.js.map +1 -0
  97. package/dist/tools/update-status/side-effects.d.ts.map +1 -1
  98. package/dist/tools/update-status/side-effects.js +32 -0
  99. package/dist/tools/update-status/side-effects.js.map +1 -1
  100. package/dist/types/agent-registry.d.ts +53 -0
  101. package/dist/types/agent-registry.d.ts.map +1 -0
  102. package/dist/types/agent-registry.js +2 -0
  103. package/dist/types/agent-registry.js.map +1 -0
  104. package/dist/types/autopilot.d.ts +36 -0
  105. package/dist/types/autopilot.d.ts.map +1 -0
  106. package/dist/types/autopilot.js +3 -0
  107. package/dist/types/autopilot.js.map +1 -0
  108. package/dist/types/competitive.d.ts +41 -0
  109. package/dist/types/competitive.d.ts.map +1 -0
  110. package/dist/types/competitive.js +3 -0
  111. package/dist/types/competitive.js.map +1 -0
  112. package/dist/types/hook-generator.d.ts +49 -0
  113. package/dist/types/hook-generator.d.ts.map +1 -0
  114. package/dist/types/hook-generator.js +3 -0
  115. package/dist/types/hook-generator.js.map +1 -0
  116. package/dist/types/index.d.ts +5 -0
  117. package/dist/types/index.d.ts.map +1 -1
  118. package/dist/types/index.js +5 -0
  119. package/dist/types/index.js.map +1 -1
  120. package/dist/types/project-dna.d.ts +46 -0
  121. package/dist/types/project-dna.d.ts.map +1 -0
  122. package/dist/types/project-dna.js +4 -0
  123. package/dist/types/project-dna.js.map +1 -0
  124. package/package.json +1 -1
  125. package/src/config/ai-tool-registry.json +71 -0
  126. package/src/config/autopilot-config.json +21 -0
  127. package/src/config/competitive-catalog.json +83 -0
  128. package/src/config/license-plans.json +17 -1
@@ -0,0 +1,261 @@
1
+ // Planu — project-dna-handler.ts
2
+ // Handlers for detect_project_dna, bootstrap_project_intelligence, update_project_dna.
3
+ import { z } from 'zod';
4
+ import { writeFile, mkdir, readFile } from 'node:fs/promises';
5
+ import { join, dirname } from 'node:path';
6
+ import { detectStack, detectPackageManager, detectTestingFramework, detectLinter, detectFormatter, } from '../engine/project-dna/stack-detector.js';
7
+ import { detectAITool, loadAIToolProfile } from '../engine/project-dna/ai-tool-detector.js';
8
+ import { generateRulesForStack, getSupportedStackTokens, } from '../engine/project-dna/rules-generator.js';
9
+ // ---------------------------------------------------------------------------
10
+ // Input schemas
11
+ // ---------------------------------------------------------------------------
12
+ export const DetectProjectDNAInputSchema = {
13
+ projectPath: z.string().max(4096).describe('Absolute path to the project root to scan'),
14
+ };
15
+ export const BootstrapProjectIntelligenceInputSchema = {
16
+ projectPath: z
17
+ .string()
18
+ .max(4096)
19
+ .describe('Absolute path to the project root where rules and skills will be installed'),
20
+ dryRun: z
21
+ .boolean()
22
+ .optional()
23
+ .default(false)
24
+ .describe('If true, report what would be created without writing files. Default: false'),
25
+ skipSkills: z
26
+ .boolean()
27
+ .optional()
28
+ .default(false)
29
+ .describe('If true, skip skill installation. Default: false'),
30
+ skipRules: z
31
+ .boolean()
32
+ .optional()
33
+ .default(false)
34
+ .describe('If true, skip rules generation. Default: false'),
35
+ };
36
+ export const UpdateDNAInputSchema = {
37
+ projectPath: z.string().max(4096).describe('Absolute path to the project root to re-scan'),
38
+ force: z
39
+ .boolean()
40
+ .optional()
41
+ .default(false)
42
+ .describe('If true, regenerate rules even if they already exist. Default: false'),
43
+ };
44
+ // ---------------------------------------------------------------------------
45
+ // Shared DNA detection
46
+ // ---------------------------------------------------------------------------
47
+ async function buildProjectDNA(projectPath) {
48
+ const [stack, packageManager, aiTool] = await Promise.all([
49
+ detectStack(projectPath),
50
+ detectPackageManager(projectPath),
51
+ detectAITool(projectPath),
52
+ ]);
53
+ const [aiToolProfile, testingFramework, linter, formatter] = await Promise.all([
54
+ loadAIToolProfile(aiTool),
55
+ detectTestingFramework(projectPath, stack),
56
+ detectLinter(projectPath, stack),
57
+ detectFormatter(projectPath, stack),
58
+ ]);
59
+ const conventions = [];
60
+ if (stack.includes('typescript-strict')) {
61
+ conventions.push('typescript-strict');
62
+ }
63
+ if (stack.includes('github-actions')) {
64
+ conventions.push('github-actions');
65
+ }
66
+ if (packageManager === 'pnpm') {
67
+ conventions.push('pnpm-workspace');
68
+ }
69
+ return {
70
+ projectPath,
71
+ detectedAt: new Date().toISOString(),
72
+ stack,
73
+ aiTool,
74
+ aiToolProfile,
75
+ packageManager,
76
+ testingFramework,
77
+ linter,
78
+ formatter,
79
+ cicd: stack.includes('github-actions')
80
+ ? 'github-actions'
81
+ : stack.includes('gitlab-ci')
82
+ ? 'gitlab-ci'
83
+ : undefined,
84
+ conventions,
85
+ };
86
+ }
87
+ // ---------------------------------------------------------------------------
88
+ // Handler: detect_project_dna
89
+ // ---------------------------------------------------------------------------
90
+ export async function handleDetectProjectDNA(args) {
91
+ const dna = await buildProjectDNA(args.projectPath);
92
+ const lines = [
93
+ `Project DNA detected for: ${dna.projectPath}`,
94
+ ``,
95
+ `AI Tool: ${dna.aiToolProfile.name} (${dna.aiTool})`,
96
+ `Package Manager: ${dna.packageManager}`,
97
+ `Stack: ${dna.stack.length > 0 ? dna.stack.join(', ') : '(none detected)'}`,
98
+ `Testing: ${dna.testingFramework ?? '(none detected)'}`,
99
+ `Linter: ${dna.linter ?? '(none detected)'}`,
100
+ `Formatter: ${dna.formatter ?? '(none detected)'}`,
101
+ `CI/CD: ${dna.cicd ?? '(none detected)'}`,
102
+ `Conventions: ${dna.conventions.length > 0 ? dna.conventions.join(', ') : '(none)'}`,
103
+ ``,
104
+ `Rules format: ${dna.aiToolProfile.rulesFormat}`,
105
+ ];
106
+ if (dna.aiToolProfile.rulesDir !== undefined) {
107
+ lines.push(`Rules directory: ${dna.aiToolProfile.rulesDir}`);
108
+ }
109
+ if (dna.aiToolProfile.rulesFile !== undefined) {
110
+ lines.push(`Rules file: ${dna.aiToolProfile.rulesFile}`);
111
+ }
112
+ const supportedTokens = getSupportedStackTokens();
113
+ const matchedTokens = dna.stack.filter((t) => supportedTokens.includes(t));
114
+ lines.push(``, `Rules available for: ${matchedTokens.length > 0 ? matchedTokens.join(', ') : '(none)'}`);
115
+ lines.push(`Run bootstrap_project_intelligence to install rules and skills.`);
116
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // Handler: bootstrap_project_intelligence
120
+ // ---------------------------------------------------------------------------
121
+ export async function handleBootstrapProjectIntelligence(args) {
122
+ const { projectPath, dryRun = false, skipSkills = false, skipRules = false } = args;
123
+ const dna = await buildProjectDNA(projectPath);
124
+ const result = {
125
+ filesCreated: [],
126
+ skillsInstalled: [],
127
+ rulesGenerated: [],
128
+ warnings: [],
129
+ summary: '',
130
+ };
131
+ if (!skipRules) {
132
+ await generateRules(dna, projectPath, dryRun, result);
133
+ }
134
+ if (!skipSkills) {
135
+ recordSkillSuggestions(dna, result);
136
+ }
137
+ result.summary = buildBootstrapSummary(result, dryRun);
138
+ const lines = [result.summary];
139
+ if (result.filesCreated.length > 0) {
140
+ lines.push(``, `Files created:`);
141
+ result.filesCreated.forEach((f) => lines.push(` - ${f}`));
142
+ }
143
+ if (result.rulesGenerated.length > 0) {
144
+ lines.push(``, `Rules generated for:`);
145
+ result.rulesGenerated.forEach((r) => lines.push(` - ${r}`));
146
+ }
147
+ if (result.skillsInstalled.length > 0) {
148
+ lines.push(``, `Suggested skills:`);
149
+ result.skillsInstalled.forEach((s) => lines.push(` - ${s}`));
150
+ }
151
+ if (result.warnings.length > 0) {
152
+ lines.push(``, `Warnings:`);
153
+ result.warnings.forEach((w) => lines.push(` - ${w}`));
154
+ }
155
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
156
+ }
157
+ async function generateRules(dna, projectPath, dryRun, result) {
158
+ const supportedTokens = getSupportedStackTokens();
159
+ const matchedTokens = dna.stack.filter((t) => supportedTokens.includes(t));
160
+ // For markdown-append and yaml formats, collect all content into one file
161
+ const appendFileMap = new Map();
162
+ for (const token of matchedTokens) {
163
+ const generated = await generateRulesForStack(dna, token);
164
+ if (generated === null) {
165
+ continue;
166
+ }
167
+ const { filePath, content } = generated;
168
+ const absPath = join(projectPath, filePath);
169
+ if (dna.aiToolProfile.rulesFormat === 'markdown-append' ||
170
+ dna.aiToolProfile.rulesFormat === 'yaml') {
171
+ const existing = appendFileMap.get(absPath) ?? [];
172
+ existing.push(content);
173
+ appendFileMap.set(absPath, existing);
174
+ }
175
+ else {
176
+ if (!dryRun) {
177
+ await mkdir(dirname(absPath), { recursive: true });
178
+ await writeFile(absPath, content, 'utf-8');
179
+ result.filesCreated.push(absPath);
180
+ }
181
+ else {
182
+ result.filesCreated.push(`[dry-run] ${absPath}`);
183
+ }
184
+ result.rulesGenerated.push(token);
185
+ }
186
+ }
187
+ for (const [absPath, contents] of appendFileMap) {
188
+ const combined = contents.join('\n');
189
+ if (!dryRun) {
190
+ await mkdir(dirname(absPath), { recursive: true });
191
+ let existing = '';
192
+ try {
193
+ existing = await readFile(absPath, 'utf-8');
194
+ }
195
+ catch {
196
+ // file does not exist yet
197
+ }
198
+ await writeFile(absPath, existing + combined, 'utf-8');
199
+ result.filesCreated.push(absPath);
200
+ }
201
+ else {
202
+ result.filesCreated.push(`[dry-run] ${absPath}`);
203
+ }
204
+ // Record which tokens were written to this file
205
+ const tokenChecks = await Promise.all(matchedTokens.map(async (t) => {
206
+ const gen = await generateRulesForStack(dna, t);
207
+ return gen !== null && join(projectPath, gen.filePath) === absPath ? t : null;
208
+ }));
209
+ const tokensForFile = tokenChecks.filter((t) => t !== null);
210
+ result.rulesGenerated.push(...tokensForFile.map((t) => `${t} -> ${absPath}`));
211
+ }
212
+ }
213
+ function recordSkillSuggestions(dna, result) {
214
+ const skillMap = {
215
+ supabase: 'supabase-patterns',
216
+ nextjs: 'nextjs-patterns',
217
+ typescript: 'typescript-strict',
218
+ vitest: 'vitest-testing',
219
+ stripe: 'stripe-payments',
220
+ prisma: 'prisma-orm',
221
+ zod: 'zod-validation',
222
+ fastapi: 'fastapi-patterns',
223
+ django: 'django-patterns',
224
+ };
225
+ for (const token of dna.stack) {
226
+ const skill = skillMap[token];
227
+ if (skill !== undefined) {
228
+ result.skillsInstalled.push(skill);
229
+ }
230
+ }
231
+ }
232
+ function buildBootstrapSummary(result, dryRun) {
233
+ const prefix = dryRun ? '[DRY RUN] ' : '';
234
+ const fileCount = result.filesCreated.length;
235
+ const ruleCount = result.rulesGenerated.length;
236
+ const skillCount = result.skillsInstalled.length;
237
+ return (`${prefix}Bootstrap complete. ` +
238
+ `${fileCount} file(s) ${dryRun ? 'would be' : 'were'} created, ` +
239
+ `${ruleCount} rule(s) generated, ` +
240
+ `${skillCount} skill(s) suggested.`);
241
+ }
242
+ // ---------------------------------------------------------------------------
243
+ // Handler: update_project_dna
244
+ // ---------------------------------------------------------------------------
245
+ export async function handleUpdateProjectDNA(args) {
246
+ const { projectPath, force = false } = args;
247
+ const dna = await buildProjectDNA(projectPath);
248
+ const forceNote = force ? ' (force mode: existing rules will be overwritten)' : '';
249
+ const lines = [
250
+ `Project DNA updated for: ${projectPath}${forceNote}`,
251
+ ``,
252
+ `Detected at: ${dna.detectedAt}`,
253
+ `AI Tool: ${dna.aiToolProfile.name} (${dna.aiTool})`,
254
+ `Stack: ${dna.stack.length > 0 ? dna.stack.join(', ') : '(none detected)'}`,
255
+ `Package Manager: ${dna.packageManager}`,
256
+ ``,
257
+ `Run bootstrap_project_intelligence to apply the updated configuration.`,
258
+ ];
259
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
260
+ }
261
+ //# sourceMappingURL=project-dna-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-dna-handler.js","sourceRoot":"","sources":["../../src/tools/project-dna-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { ROLE_CATALOG } from '../engine/agent-registry/role-catalog.js';
3
+ export declare function registerAgentRegistryTools(server: McpServer): void;
4
+ export { ROLE_CATALOG };
5
+ //# sourceMappingURL=register-agent-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-agent-registry.d.ts","sourceRoot":"","sources":["../../src/tools/register-agent-registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAYzE,OAAO,EAAc,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAgBpF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0TlE;AAGD,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,254 @@
1
+ // register-agent-registry.ts — Persistent Agent Registry tools (SPEC-415)
2
+ import { z } from 'zod';
3
+ import { safeLicensed, safeTracked } from './safe-handler.js';
4
+ import { registerAgent, stopAgent, restartAgent, unregisterAgent, getAgentHealth, listAllAgents, } from '../engine/agent-registry/lifecycle-manager.js';
5
+ import { getRoleDef, ROLE_CATALOG } from '../engine/agent-registry/role-catalog.js';
6
+ const ROLE_VALUES = [
7
+ 'spec-guardian',
8
+ 'pr-reviewer',
9
+ 'metrics-analyst',
10
+ 'criteria-auditor',
11
+ 'changelog-keeper',
12
+ 'dependency-watcher',
13
+ ];
14
+ const ROLE_DESCRIBE = 'Agent role. Values: spec-guardian — monitors drift, pr-reviewer — reviews PRs, ' +
15
+ 'metrics-analyst — weekly reports, criteria-auditor — validates EARS quality, ' +
16
+ 'changelog-keeper — keeps CHANGELOG updated, dependency-watcher — alerts on vulnerabilities';
17
+ export function registerAgentRegistryTools(server) {
18
+ // ---------------------------------------------------------------------------
19
+ // Tool 1: register_agent
20
+ // ---------------------------------------------------------------------------
21
+ server.registerTool('register_agent', {
22
+ description: 'Register a persistent AI agent with a predefined role for this project. ' +
23
+ 'Agents survive across sessions and run automatically based on their trigger. ' +
24
+ 'Re-registering an existing role updates its trigger and config while preserving run history.',
25
+ inputSchema: {
26
+ projectPath: z
27
+ .string()
28
+ .min(1)
29
+ .max(4096)
30
+ .describe('Absolute path to the project root directory'),
31
+ role: z.enum(ROLE_VALUES).describe(ROLE_DESCRIBE),
32
+ trigger: z.object({
33
+ type: z
34
+ .enum(['cron', 'event', 'webhook', 'manual'])
35
+ .describe('Trigger type. Values: cron — scheduled, event — autopilot event, ' +
36
+ 'webhook — external webhook, manual — on demand only'),
37
+ schedule: z
38
+ .string()
39
+ .max(100)
40
+ .optional()
41
+ .describe('Cron expression (for type=cron). Example: "0 9 * * 1" for Mondays at 9am'),
42
+ event: z
43
+ .string()
44
+ .max(500)
45
+ .optional()
46
+ .describe('Autopilot event name (for type=event). Example: "spec:done"'),
47
+ webhook: z
48
+ .string()
49
+ .max(500)
50
+ .optional()
51
+ .describe('Webhook pattern (for type=webhook). Example: "github:pull_request.opened"'),
52
+ }),
53
+ config: z
54
+ .record(z.string(), z.unknown())
55
+ .optional()
56
+ .describe('Role-specific configuration. Uses role defaults if omitted.'),
57
+ },
58
+ annotations: { title: 'Register Persistent Agent' },
59
+ }, safeLicensed('register_agent', async (args) => {
60
+ const { projectPath, role, trigger, config } = args;
61
+ const roleDef = getRoleDef(role);
62
+ const mergedConfig = { ...(roleDef?.defaultConfig ?? {}), ...(config ?? {}) };
63
+ const agent = await registerAgent(projectPath, role, trigger, mergedConfig);
64
+ const lines = [
65
+ `Agent registered: ${role}`,
66
+ `Status: ${agent.status}`,
67
+ `Trigger: ${agent.trigger.type}` +
68
+ (agent.trigger.schedule !== undefined ? ` (${agent.trigger.schedule})` : '') +
69
+ (agent.trigger.event !== undefined ? ` (${agent.trigger.event})` : '') +
70
+ (agent.trigger.webhook !== undefined ? ` (${agent.trigger.webhook})` : ''),
71
+ `Registered at: ${agent.registeredAt}`,
72
+ ];
73
+ if (roleDef !== undefined) {
74
+ lines.push(`Required tools: ${roleDef.requiredTools.join(', ')}`);
75
+ }
76
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
77
+ }));
78
+ // ---------------------------------------------------------------------------
79
+ // Tool 2: list_agents
80
+ // ---------------------------------------------------------------------------
81
+ server.registerTool('list_agents', {
82
+ description: 'List all registered persistent agents in this project. ' +
83
+ 'Shows role, status, trigger type, run count, and last run time for each agent.',
84
+ inputSchema: {
85
+ projectPath: z
86
+ .string()
87
+ .min(1)
88
+ .max(4096)
89
+ .describe('Absolute path to the project root directory'),
90
+ },
91
+ annotations: { title: 'List Registered Agents', readOnlyHint: true },
92
+ }, safeTracked('list_agents', async (args) => {
93
+ const { projectPath } = args;
94
+ const agents = await listAllAgents(projectPath);
95
+ if (agents.length === 0) {
96
+ return {
97
+ content: [
98
+ {
99
+ type: 'text',
100
+ text: 'No agents registered in this project.\nUse register_agent to add one.',
101
+ },
102
+ ],
103
+ };
104
+ }
105
+ const lines = [`Registered agents (${agents.length}):`, ''];
106
+ for (const agent of agents) {
107
+ const roleDef = getRoleDef(agent.role);
108
+ lines.push(`[${agent.status.toUpperCase()}] ${agent.role}`);
109
+ if (roleDef !== undefined) {
110
+ lines.push(` Description: ${roleDef.description}`);
111
+ }
112
+ lines.push(` Trigger: ${agent.trigger.type}` +
113
+ (agent.trigger.schedule !== undefined ? ` (${agent.trigger.schedule})` : '') +
114
+ (agent.trigger.event !== undefined ? ` (${agent.trigger.event})` : '') +
115
+ (agent.trigger.webhook !== undefined ? ` (${agent.trigger.webhook})` : ''));
116
+ lines.push(` Runs: ${agent.runCount} total, ${agent.successCount} successful`);
117
+ if (agent.lastRunAt !== undefined) {
118
+ lines.push(` Last run: ${agent.lastRunAt}`);
119
+ }
120
+ lines.push('');
121
+ }
122
+ return { content: [{ type: 'text', text: lines.join('\n').trimEnd() }] };
123
+ }));
124
+ // ---------------------------------------------------------------------------
125
+ // Tool 3: stop_agent
126
+ // ---------------------------------------------------------------------------
127
+ server.registerTool('stop_agent', {
128
+ description: 'Pause a registered agent. The agent remains registered but will not run until restarted.',
129
+ inputSchema: {
130
+ projectPath: z
131
+ .string()
132
+ .min(1)
133
+ .max(4096)
134
+ .describe('Absolute path to the project root directory'),
135
+ role: z.enum(ROLE_VALUES).describe(ROLE_DESCRIBE),
136
+ },
137
+ annotations: { title: 'Stop Agent' },
138
+ }, safeLicensed('stop_agent', async (args) => {
139
+ const { projectPath, role } = args;
140
+ await stopAgent(projectPath, role);
141
+ return {
142
+ content: [
143
+ {
144
+ type: 'text',
145
+ text: `Agent '${role}' paused. Use restart_agent to resume it.`,
146
+ },
147
+ ],
148
+ };
149
+ }));
150
+ // ---------------------------------------------------------------------------
151
+ // Tool 4: restart_agent
152
+ // ---------------------------------------------------------------------------
153
+ server.registerTool('restart_agent', {
154
+ description: 'Resume a paused agent or reset an agent in error state back to active.',
155
+ inputSchema: {
156
+ projectPath: z
157
+ .string()
158
+ .min(1)
159
+ .max(4096)
160
+ .describe('Absolute path to the project root directory'),
161
+ role: z.enum(ROLE_VALUES).describe(ROLE_DESCRIBE),
162
+ },
163
+ annotations: { title: 'Restart Agent' },
164
+ }, safeLicensed('restart_agent', async (args) => {
165
+ const { projectPath, role } = args;
166
+ const agent = await restartAgent(projectPath, role);
167
+ return {
168
+ content: [
169
+ {
170
+ type: 'text',
171
+ text: [
172
+ `Agent '${role}' is now active.`,
173
+ `Trigger: ${agent.trigger.type}` +
174
+ (agent.trigger.schedule !== undefined ? ` (${agent.trigger.schedule})` : '') +
175
+ (agent.trigger.event !== undefined ? ` (${agent.trigger.event})` : '') +
176
+ (agent.trigger.webhook !== undefined ? ` (${agent.trigger.webhook})` : ''),
177
+ ].join('\n'),
178
+ },
179
+ ],
180
+ };
181
+ }));
182
+ // ---------------------------------------------------------------------------
183
+ // Tool 5: agent_health
184
+ // ---------------------------------------------------------------------------
185
+ server.registerTool('agent_health', {
186
+ description: 'Get health metrics for a registered agent: status, success rate, average duration, and last error.',
187
+ inputSchema: {
188
+ projectPath: z
189
+ .string()
190
+ .min(1)
191
+ .max(4096)
192
+ .describe('Absolute path to the project root directory'),
193
+ role: z.enum(ROLE_VALUES).describe(ROLE_DESCRIBE),
194
+ },
195
+ annotations: { title: 'Agent Health', readOnlyHint: true },
196
+ }, safeTracked('agent_health', async (args) => {
197
+ const { projectPath, role } = args;
198
+ const health = await getAgentHealth(projectPath, role);
199
+ if (health.status === 'unregistered') {
200
+ return {
201
+ content: [
202
+ {
203
+ type: 'text',
204
+ text: `Agent '${role}' is not registered in this project.\nUse register_agent to add it.`,
205
+ },
206
+ ],
207
+ };
208
+ }
209
+ const lines = [
210
+ `Health report: ${role}`,
211
+ `Status: ${health.status}`,
212
+ `Success rate: ${(health.successRate * 100).toFixed(1)}%`,
213
+ ];
214
+ if (health.avgDurationMs !== undefined) {
215
+ lines.push(`Avg duration: ${health.avgDurationMs.toFixed(0)}ms`);
216
+ }
217
+ if (health.lastRunAt !== undefined) {
218
+ lines.push(`Last run: ${health.lastRunAt}`);
219
+ }
220
+ if (health.lastError !== undefined) {
221
+ lines.push(`Last error: ${health.lastError}`);
222
+ }
223
+ return { content: [{ type: 'text', text: lines.join('\n') }] };
224
+ }));
225
+ // ---------------------------------------------------------------------------
226
+ // Tool 6: unregister_agent (bonus — needed for full lifecycle)
227
+ // ---------------------------------------------------------------------------
228
+ server.registerTool('unregister_agent', {
229
+ description: 'Permanently remove an agent from this project registry. All run history will be lost.',
230
+ inputSchema: {
231
+ projectPath: z
232
+ .string()
233
+ .min(1)
234
+ .max(4096)
235
+ .describe('Absolute path to the project root directory'),
236
+ role: z.enum(ROLE_VALUES).describe(ROLE_DESCRIBE),
237
+ },
238
+ annotations: { title: 'Unregister Agent', destructiveHint: true },
239
+ }, safeLicensed('unregister_agent', async (args) => {
240
+ const { projectPath, role } = args;
241
+ await unregisterAgent(projectPath, role);
242
+ return {
243
+ content: [
244
+ {
245
+ type: 'text',
246
+ text: `Agent '${role}' has been unregistered and removed from the project registry.`,
247
+ },
248
+ ],
249
+ };
250
+ }));
251
+ }
252
+ // Re-export catalog for tests
253
+ export { ROLE_CATALOG };
254
+ //# sourceMappingURL=register-agent-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-agent-registry.js","sourceRoot":"","sources":["../../src/tools/register-agent-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerAutopilotTools(server: McpServer): void;
3
+ //# sourceMappingURL=register-autopilot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-autopilot.d.ts","sourceRoot":"","sources":["../../src/tools/register-autopilot.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASzE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAgG9D"}
@@ -0,0 +1,78 @@
1
+ // tools/register-autopilot.ts — SPEC-413: Registers configure_autopilot MCP tool
2
+ import { z } from 'zod';
3
+ import { safeLicensed } from './safe-handler.js';
4
+ import { loadAutopilotConfig, saveAutopilotConfig, getAutopilotStatus, } from '../engine/autopilot/action-executor.js';
5
+ export function registerAutopilotTools(server) {
6
+ server.registerTool('configure_autopilot', {
7
+ description: 'Enable/disable individual autopilot triggers, set thresholds, or view current autopilot status. Autopilot auto-triggers tools like validate_criteria_quality, tdd_scaffold, and resolve_drift_violations at the right moments in the spec lifecycle.',
8
+ inputSchema: {
9
+ projectPath: z.string().min(1).max(4096).describe('Absolute path to the project root.'),
10
+ action: z
11
+ .enum(['enable', 'disable', 'status', 'set-threshold'])
12
+ .describe('Action to perform. Values: enable — activate a trigger rule, disable — deactivate a trigger rule, status — show all rules and their state, set-threshold — update numeric threshold for a conditional rule.'),
13
+ triggerId: z
14
+ .string()
15
+ .max(200)
16
+ .optional()
17
+ .describe('ID of the trigger rule to enable/disable/configure. Example: "post-create:validate_criteria_quality". Required for enable/disable/set-threshold.'),
18
+ threshold: z
19
+ .number()
20
+ .optional()
21
+ .describe('Threshold value for set-threshold action. For hour-based triggers: minimum estimated hours. For drift triggers: minimum drift score (0-1).'),
22
+ },
23
+ annotations: { readOnlyHint: false },
24
+ }, safeLicensed('configure_autopilot', async (args) => {
25
+ if (args.action === 'status') {
26
+ const status = await getAutopilotStatus(args.projectPath);
27
+ const lines = status.rules.map((r) => `${r.enabled ? '✅' : '⬜'} \`${r.id}\` — ${r.description}`);
28
+ return {
29
+ content: [
30
+ {
31
+ type: 'text',
32
+ text: `## Autopilot Status\n\n**${status.enabledRules}/${status.totalRules} rules enabled**\n\n${lines.join('\n')}`,
33
+ },
34
+ ],
35
+ };
36
+ }
37
+ if (!args.triggerId) {
38
+ return {
39
+ isError: true,
40
+ content: [
41
+ {
42
+ type: 'text',
43
+ text: 'triggerId is required for enable/disable/set-threshold actions.',
44
+ },
45
+ ],
46
+ };
47
+ }
48
+ const config = await loadAutopilotConfig(args.projectPath);
49
+ if (args.action === 'enable') {
50
+ config.rules[args.triggerId] = {
51
+ ...(config.rules[args.triggerId] ?? {}),
52
+ enabled: true,
53
+ };
54
+ }
55
+ else if (args.action === 'disable') {
56
+ config.rules[args.triggerId] = {
57
+ ...(config.rules[args.triggerId] ?? {}),
58
+ enabled: false,
59
+ };
60
+ }
61
+ else if (args.action === 'set-threshold' && args.threshold !== undefined) {
62
+ config.rules[args.triggerId] = {
63
+ ...(config.rules[args.triggerId] ?? { enabled: true }),
64
+ threshold: args.threshold,
65
+ };
66
+ }
67
+ await saveAutopilotConfig(args.projectPath, config);
68
+ return {
69
+ content: [
70
+ {
71
+ type: 'text',
72
+ text: `✅ Autopilot rule \`${args.triggerId}\` updated (action: ${args.action}).`,
73
+ },
74
+ ],
75
+ };
76
+ }));
77
+ }
78
+ //# sourceMappingURL=register-autopilot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-autopilot.js","sourceRoot":"","sources":["../../src/tools/register-autopilot.ts"],"names":[],"mappings":"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"}