@promptwheel/mcp 0.6.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 (134) hide show
  1. package/README.md +178 -0
  2. package/dist/advance-helpers.d.ts +27 -0
  3. package/dist/advance-helpers.d.ts.map +1 -0
  4. package/dist/advance-helpers.js +127 -0
  5. package/dist/advance-helpers.js.map +1 -0
  6. package/dist/advance-prompts.d.ts +48 -0
  7. package/dist/advance-prompts.d.ts.map +1 -0
  8. package/dist/advance-prompts.js +420 -0
  9. package/dist/advance-prompts.js.map +1 -0
  10. package/dist/advance.d.ts +30 -0
  11. package/dist/advance.d.ts.map +1 -0
  12. package/dist/advance.js +752 -0
  13. package/dist/advance.js.map +1 -0
  14. package/dist/codebase-index.d.ts +5 -0
  15. package/dist/codebase-index.d.ts.map +1 -0
  16. package/dist/codebase-index.js +5 -0
  17. package/dist/codebase-index.js.map +1 -0
  18. package/dist/dedup-memory.d.ts +30 -0
  19. package/dist/dedup-memory.d.ts.map +1 -0
  20. package/dist/dedup-memory.js +76 -0
  21. package/dist/dedup-memory.js.map +1 -0
  22. package/dist/direct-client.d.ts +57 -0
  23. package/dist/direct-client.d.ts.map +1 -0
  24. package/dist/direct-client.js +92 -0
  25. package/dist/direct-client.js.map +1 -0
  26. package/dist/event-handlers-qa.d.ts +5 -0
  27. package/dist/event-handlers-qa.d.ts.map +1 -0
  28. package/dist/event-handlers-qa.js +186 -0
  29. package/dist/event-handlers-qa.js.map +1 -0
  30. package/dist/event-handlers-scout.d.ts +5 -0
  31. package/dist/event-handlers-scout.d.ts.map +1 -0
  32. package/dist/event-handlers-scout.js +270 -0
  33. package/dist/event-handlers-scout.js.map +1 -0
  34. package/dist/event-handlers-ticket.d.ts +5 -0
  35. package/dist/event-handlers-ticket.d.ts.map +1 -0
  36. package/dist/event-handlers-ticket.js +232 -0
  37. package/dist/event-handlers-ticket.js.map +1 -0
  38. package/dist/event-helpers.d.ts +46 -0
  39. package/dist/event-helpers.d.ts.map +1 -0
  40. package/dist/event-helpers.js +125 -0
  41. package/dist/event-helpers.js.map +1 -0
  42. package/dist/event-processor.d.ts +15 -0
  43. package/dist/event-processor.d.ts.map +1 -0
  44. package/dist/event-processor.js +111 -0
  45. package/dist/event-processor.js.map +1 -0
  46. package/dist/formulas.d.ts +27 -0
  47. package/dist/formulas.d.ts.map +1 -0
  48. package/dist/formulas.js +109 -0
  49. package/dist/formulas.js.map +1 -0
  50. package/dist/guidelines.d.ts +16 -0
  51. package/dist/guidelines.d.ts.map +1 -0
  52. package/dist/guidelines.js +44 -0
  53. package/dist/guidelines.js.map +1 -0
  54. package/dist/index.d.ts +9 -0
  55. package/dist/index.d.ts.map +1 -0
  56. package/dist/index.js +42 -0
  57. package/dist/index.js.map +1 -0
  58. package/dist/learnings.d.ts +42 -0
  59. package/dist/learnings.d.ts.map +1 -0
  60. package/dist/learnings.js +117 -0
  61. package/dist/learnings.js.map +1 -0
  62. package/dist/project-metadata.d.ts +34 -0
  63. package/dist/project-metadata.d.ts.map +1 -0
  64. package/dist/project-metadata.js +617 -0
  65. package/dist/project-metadata.js.map +1 -0
  66. package/dist/proposals.d.ts +23 -0
  67. package/dist/proposals.d.ts.map +1 -0
  68. package/dist/proposals.js +201 -0
  69. package/dist/proposals.js.map +1 -0
  70. package/dist/qa-stats.d.ts +51 -0
  71. package/dist/qa-stats.d.ts.map +1 -0
  72. package/dist/qa-stats.js +121 -0
  73. package/dist/qa-stats.js.map +1 -0
  74. package/dist/run-manager.d.ts +97 -0
  75. package/dist/run-manager.d.ts.map +1 -0
  76. package/dist/run-manager.js +583 -0
  77. package/dist/run-manager.js.map +1 -0
  78. package/dist/run-state-bridge.d.ts +13 -0
  79. package/dist/run-state-bridge.d.ts.map +1 -0
  80. package/dist/run-state-bridge.js +101 -0
  81. package/dist/run-state-bridge.js.map +1 -0
  82. package/dist/scope-policy.d.ts +83 -0
  83. package/dist/scope-policy.d.ts.map +1 -0
  84. package/dist/scope-policy.js +278 -0
  85. package/dist/scope-policy.js.map +1 -0
  86. package/dist/server.d.ts +18 -0
  87. package/dist/server.d.ts.map +1 -0
  88. package/dist/server.js +35 -0
  89. package/dist/server.js.map +1 -0
  90. package/dist/spindle.d.ts +41 -0
  91. package/dist/spindle.d.ts.map +1 -0
  92. package/dist/spindle.js +230 -0
  93. package/dist/spindle.js.map +1 -0
  94. package/dist/state.d.ts +36 -0
  95. package/dist/state.d.ts.map +1 -0
  96. package/dist/state.js +50 -0
  97. package/dist/state.js.map +1 -0
  98. package/dist/ticket-worker.d.ts +37 -0
  99. package/dist/ticket-worker.d.ts.map +1 -0
  100. package/dist/ticket-worker.js +527 -0
  101. package/dist/ticket-worker.js.map +1 -0
  102. package/dist/tool-registry.d.ts +35 -0
  103. package/dist/tool-registry.d.ts.map +1 -0
  104. package/dist/tool-registry.js +129 -0
  105. package/dist/tool-registry.js.map +1 -0
  106. package/dist/tools/execute.d.ts +17 -0
  107. package/dist/tools/execute.d.ts.map +1 -0
  108. package/dist/tools/execute.js +418 -0
  109. package/dist/tools/execute.js.map +1 -0
  110. package/dist/tools/git.d.ts +7 -0
  111. package/dist/tools/git.d.ts.map +1 -0
  112. package/dist/tools/git.js +98 -0
  113. package/dist/tools/git.js.map +1 -0
  114. package/dist/tools/intelligence.d.ts +10 -0
  115. package/dist/tools/intelligence.d.ts.map +1 -0
  116. package/dist/tools/intelligence.js +432 -0
  117. package/dist/tools/intelligence.js.map +1 -0
  118. package/dist/tools/session.d.ts +7 -0
  119. package/dist/tools/session.d.ts.map +1 -0
  120. package/dist/tools/session.js +533 -0
  121. package/dist/tools/session.js.map +1 -0
  122. package/dist/tools/trajectory.d.ts +10 -0
  123. package/dist/tools/trajectory.d.ts.map +1 -0
  124. package/dist/tools/trajectory.js +374 -0
  125. package/dist/tools/trajectory.js.map +1 -0
  126. package/dist/trajectory-io.d.ts +21 -0
  127. package/dist/trajectory-io.d.ts.map +1 -0
  128. package/dist/trajectory-io.js +105 -0
  129. package/dist/trajectory-io.js.map +1 -0
  130. package/dist/types.d.ts +229 -0
  131. package/dist/types.d.ts.map +1 -0
  132. package/dist/types.js +13 -0
  133. package/dist/types.js.map +1 -0
  134. package/package.json +63 -0
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Tool Registry — queryable registry of tool specs for phase/category/trust filtering.
3
+ *
4
+ * Replaces hardcoded auto-approve arrays and CATEGORY_TOOL_POLICIES
5
+ * with a single registry that loads built-in specs + custom user tools.
6
+ *
7
+ * Custom tools are loaded from `.promptwheel/tools/*.json`.
8
+ */
9
+ import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
11
+ import { BUILTIN_TOOL_SPECS, filterToolSpecs, collectApprovePatterns, collectConstraintNotes, } from '@promptwheel/core/tools/shared';
12
+ // ---------------------------------------------------------------------------
13
+ // Module-level cache for the registry
14
+ // ---------------------------------------------------------------------------
15
+ let cachedRegistry = null;
16
+ let cachedProjectPath = null;
17
+ /**
18
+ * Get a cached ToolRegistry instance for the given project path.
19
+ * Creates a new one if the project path changed.
20
+ */
21
+ export function getRegistry(projectPath) {
22
+ if (cachedRegistry && cachedProjectPath === (projectPath ?? null)) {
23
+ return cachedRegistry;
24
+ }
25
+ cachedRegistry = new ToolRegistry(projectPath);
26
+ cachedProjectPath = projectPath ?? null;
27
+ return cachedRegistry;
28
+ }
29
+ // ---------------------------------------------------------------------------
30
+ // ToolRegistry
31
+ // ---------------------------------------------------------------------------
32
+ export class ToolRegistry {
33
+ specs;
34
+ constructor(projectPath) {
35
+ this.specs = [...BUILTIN_TOOL_SPECS];
36
+ // Load custom tools from .promptwheel/tools/*.json
37
+ if (projectPath) {
38
+ const toolsDir = path.join(projectPath, '.promptwheel', 'tools');
39
+ if (fs.existsSync(toolsDir)) {
40
+ try {
41
+ const files = fs.readdirSync(toolsDir).filter(f => f.endsWith('.json'));
42
+ for (const file of files) {
43
+ try {
44
+ const raw = JSON.parse(fs.readFileSync(path.join(toolsDir, file), 'utf-8'));
45
+ const spec = validateCustomTool(raw);
46
+ if (spec) {
47
+ this.specs.push(spec);
48
+ }
49
+ }
50
+ catch (err) {
51
+ console.warn(`[promptwheel] failed to load custom tool file ${file}: ${err instanceof Error ? err.message : String(err)}`);
52
+ }
53
+ }
54
+ }
55
+ catch (err) {
56
+ if (err instanceof Error && !('code' in err && err.code === 'ENOENT')) {
57
+ console.warn(`[promptwheel] failed to read tools directory: ${err.message}`);
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ /** Get all tool specs matching the given context. */
64
+ getToolsForContext(ctx) {
65
+ return filterToolSpecs(this.specs, ctx.phase, ctx.category, ctx.trustLevel ?? 'default');
66
+ }
67
+ /** Get auto-approve patterns for the given context. */
68
+ getAutoApprovePatterns(ctx) {
69
+ const filtered = this.getToolsForContext(ctx);
70
+ return collectApprovePatterns(filtered);
71
+ }
72
+ /** Get constraint note for the given context (if any). */
73
+ getConstraintNote(ctx) {
74
+ const filtered = this.getToolsForContext(ctx);
75
+ return collectConstraintNotes(filtered);
76
+ }
77
+ /** Serialize tools for a subagent prompt (markdown block). */
78
+ serializeForSubagent(ctx) {
79
+ const filtered = this.getToolsForContext(ctx);
80
+ if (filtered.length === 0)
81
+ return '';
82
+ const lines = ['## Available Tools', ''];
83
+ for (const spec of filtered) {
84
+ lines.push(`- **${spec.name}**: ${spec.description}`);
85
+ if (spec.constraint_note) {
86
+ lines.push(` ⚠️ ${spec.constraint_note}`);
87
+ }
88
+ }
89
+ return lines.join('\n');
90
+ }
91
+ /** Get all specs (for testing). */
92
+ getAllSpecs() {
93
+ return [...this.specs];
94
+ }
95
+ }
96
+ // ---------------------------------------------------------------------------
97
+ // Custom tool validation
98
+ // ---------------------------------------------------------------------------
99
+ function validateCustomTool(raw) {
100
+ if (!raw || typeof raw !== 'object')
101
+ return null;
102
+ const obj = raw;
103
+ // Required fields
104
+ if (typeof obj.name !== 'string' || !obj.name)
105
+ return null;
106
+ if (!Array.isArray(obj.approve_patterns))
107
+ return null;
108
+ if (!Array.isArray(obj.phase_access))
109
+ return null;
110
+ const validPhases = new Set(['SCOUT', 'PLAN', 'EXECUTE', 'QA', 'PR']);
111
+ const validTrust = new Set(['safe', 'default', 'full']);
112
+ const phaseAccess = obj.phase_access.filter(p => validPhases.has(p));
113
+ if (phaseAccess.length === 0)
114
+ return null;
115
+ const trustLevels = Array.isArray(obj.trust_levels)
116
+ ? obj.trust_levels.filter(t => validTrust.has(t))
117
+ : ['safe', 'default', 'full'];
118
+ return {
119
+ name: obj.name,
120
+ description: typeof obj.description === 'string' ? obj.description : '',
121
+ approve_patterns: obj.approve_patterns.filter(p => typeof p === 'string'),
122
+ phase_access: phaseAccess,
123
+ trust_levels: trustLevels,
124
+ category_access: Array.isArray(obj.category_access) ? obj.category_access : null,
125
+ constraint_note: typeof obj.constraint_note === 'string' ? obj.constraint_note : undefined,
126
+ custom: true,
127
+ };
128
+ }
129
+ //# sourceMappingURL=tool-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../src/tool-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Execution tools: next_ticket, validate_scope, complete_ticket, fail_ticket
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { SessionManager } from '../state.js';
6
+ /**
7
+ * Validates a verification command against the allowlist.
8
+ * Returns { valid: true } if the command is allowed, or { valid: false, reason: string } if not.
9
+ */
10
+ export declare function validateVerificationCommand(command: string): {
11
+ valid: true;
12
+ } | {
13
+ valid: false;
14
+ reason: string;
15
+ };
16
+ export declare function registerExecuteTools(server: McpServer, getState: () => SessionManager): void;
17
+ //# sourceMappingURL=execute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.d.ts","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA+ElD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAoC/G;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,QAkUrF"}
@@ -0,0 +1,418 @@
1
+ /**
2
+ * Execution tools: next_ticket, validate_scope, complete_ticket, fail_ticket
3
+ */
4
+ import { z } from 'zod';
5
+ import { repos } from '@promptwheel/core';
6
+ import { execSync } from 'node:child_process';
7
+ import { deriveScopePolicy, isFileAllowed, isCategoryFileAllowed } from '../scope-policy.js';
8
+ /**
9
+ * Allowlist of safe command prefixes for verification commands.
10
+ * Defense in depth: prevents arbitrary command execution if the trust boundary is compromised.
11
+ */
12
+ const ALLOWED_COMMAND_PREFIXES = [
13
+ // Node.js / JavaScript
14
+ 'npm test',
15
+ 'npm run',
16
+ 'npx vitest',
17
+ 'npx jest',
18
+ 'npx mocha',
19
+ 'npx playwright',
20
+ 'npx cypress',
21
+ 'npx eslint',
22
+ 'npx tsc',
23
+ 'npx tsx',
24
+ 'yarn test',
25
+ 'yarn run',
26
+ 'pnpm test',
27
+ 'pnpm run',
28
+ 'bun test',
29
+ 'bun run',
30
+ 'vitest',
31
+ 'jest',
32
+ 'mocha',
33
+ // Python
34
+ 'pytest',
35
+ 'python -m pytest',
36
+ 'python3 -m pytest',
37
+ 'python -m unittest',
38
+ 'python3 -m unittest',
39
+ 'mypy',
40
+ 'ruff',
41
+ 'flake8',
42
+ 'pylint',
43
+ // Go
44
+ 'go test',
45
+ 'go vet',
46
+ 'go build',
47
+ 'golangci-lint',
48
+ // Rust
49
+ 'cargo test',
50
+ 'cargo check',
51
+ 'cargo clippy',
52
+ 'cargo build',
53
+ // Ruby
54
+ 'bundle exec rspec',
55
+ 'bundle exec rake',
56
+ 'rspec',
57
+ 'rake test',
58
+ 'rails test',
59
+ // Java / JVM
60
+ 'mvn test',
61
+ 'mvn verify',
62
+ 'gradle test',
63
+ './gradlew test',
64
+ // C# / .NET
65
+ 'dotnet test',
66
+ 'dotnet build',
67
+ // PHP
68
+ 'phpunit',
69
+ 'vendor/bin/phpunit',
70
+ './vendor/bin/phpunit',
71
+ 'composer test',
72
+ // Elixir
73
+ 'mix test',
74
+ 'mix compile',
75
+ // Swift
76
+ 'swift test',
77
+ 'swift build',
78
+ // Make (common wrapper)
79
+ 'make test',
80
+ 'make check',
81
+ 'make build',
82
+ ];
83
+ /**
84
+ * Validates a verification command against the allowlist.
85
+ * Returns { valid: true } if the command is allowed, or { valid: false, reason: string } if not.
86
+ */
87
+ export function validateVerificationCommand(command) {
88
+ const trimmedCommand = command.trim();
89
+ // Empty commands are not allowed
90
+ if (!trimmedCommand) {
91
+ return { valid: false, reason: 'Empty command is not allowed' };
92
+ }
93
+ // Check for shell injection patterns
94
+ const dangerousPatterns = [
95
+ /[;&|`$]/, // Shell operators and command substitution
96
+ /\$\(/, // Command substitution
97
+ /\$\{/, // Variable expansion
98
+ />|>>|</, // Redirection
99
+ /\n/, // Newlines (could inject commands)
100
+ ];
101
+ for (const pattern of dangerousPatterns) {
102
+ if (pattern.test(trimmedCommand)) {
103
+ return { valid: false, reason: `Command contains potentially dangerous pattern: ${pattern.source}` };
104
+ }
105
+ }
106
+ // Check if command starts with an allowed prefix
107
+ const isAllowed = ALLOWED_COMMAND_PREFIXES.some(prefix => trimmedCommand === prefix || trimmedCommand.startsWith(prefix + ' '));
108
+ if (!isAllowed) {
109
+ return {
110
+ valid: false,
111
+ reason: `Command "${trimmedCommand.slice(0, 50)}${trimmedCommand.length > 50 ? '...' : ''}" does not match any allowed command prefix. Allowed prefixes: npm test, npm run, vitest, jest, pytest, go test, cargo test, etc.`
112
+ };
113
+ }
114
+ return { valid: true };
115
+ }
116
+ export function registerExecuteTools(server, getState) {
117
+ server.tool('promptwheel_next_ticket', 'Returns the next ticket to work on: title, description, allowed_paths, and execution instructions.', {}, async () => {
118
+ const state = getState();
119
+ const run = state.requireActive();
120
+ // Find next ready ticket
121
+ const readyTickets = await repos.tickets.listByProject(state.db, run.project_id, { status: 'ready', limit: 1 });
122
+ if (readyTickets.length === 0) {
123
+ return {
124
+ content: [{
125
+ type: 'text',
126
+ text: JSON.stringify({
127
+ message: 'No tickets ready for execution. Call promptwheel_advance to scout for more work.',
128
+ tickets_completed: run.tickets_completed,
129
+ tickets_failed: run.tickets_failed,
130
+ }),
131
+ }],
132
+ };
133
+ }
134
+ const ticket = readyTickets[0];
135
+ // Mark as in_progress
136
+ await repos.tickets.updateStatus(state.db, ticket.id, 'in_progress');
137
+ state.run.assignTicket(ticket.id);
138
+ // Create a worker run record
139
+ const dbRun = await repos.runs.create(state.db, {
140
+ projectId: run.project_id,
141
+ type: 'worker',
142
+ ticketId: ticket.id,
143
+ });
144
+ return {
145
+ content: [{
146
+ type: 'text',
147
+ text: JSON.stringify({
148
+ ticketId: ticket.id,
149
+ runId: dbRun.id,
150
+ title: ticket.title,
151
+ description: ticket.description,
152
+ allowedPaths: ticket.allowedPaths,
153
+ verificationCommands: ticket.verificationCommands,
154
+ category: ticket.category,
155
+ instructions: buildExecutionPrompt(ticket),
156
+ }, null, 2),
157
+ }],
158
+ };
159
+ });
160
+ server.tool('promptwheel_validate_scope', 'Before committing, send the list of changed files. PromptWheel checks scope enforcement.', {
161
+ ticketId: z.string().optional().describe('The ticket ID being worked on.'),
162
+ ticket_id: z.string().optional().describe('Alias for ticketId.'),
163
+ changedFiles: z.array(z.string()).optional().describe('List of file paths that were modified.'),
164
+ changed_files: z.array(z.string()).optional().describe('Alias for changedFiles.'),
165
+ }, async (raw) => {
166
+ const ticketId = raw.ticketId ?? raw.ticket_id;
167
+ const changedFiles = raw.changedFiles ?? raw.changed_files;
168
+ if (!ticketId || !changedFiles) {
169
+ return {
170
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Missing required parameters: ticketId (or ticket_id) and changedFiles (or changed_files).' }) }],
171
+ isError: true,
172
+ };
173
+ }
174
+ const params = { ticketId, changedFiles };
175
+ const state = getState();
176
+ state.requireActive();
177
+ const ticket = await repos.tickets.getById(state.db, params.ticketId);
178
+ if (!ticket) {
179
+ return {
180
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Ticket not found.' }) }],
181
+ isError: true,
182
+ };
183
+ }
184
+ // If no allowed_paths, everything is allowed
185
+ if (ticket.allowedPaths.length === 0) {
186
+ state.run.appendEvent('SCOPE_ALLOWED', { ticket_id: params.ticketId, files: params.changedFiles });
187
+ return {
188
+ content: [{
189
+ type: 'text',
190
+ text: JSON.stringify({ valid: true, message: 'No scope restrictions.' }),
191
+ }],
192
+ };
193
+ }
194
+ // Use proper scope policy with minimatch-based validation
195
+ const s = state.run.require();
196
+ const worktreeRoot = s.direct ? undefined : `.promptwheel/worktrees/${params.ticketId}`;
197
+ const policy = deriveScopePolicy({
198
+ allowedPaths: ticket.allowedPaths,
199
+ category: ticket.category ?? 'fix',
200
+ maxLinesPerTicket: 500,
201
+ worktreeRoot,
202
+ });
203
+ const violations = [];
204
+ const categoryViolations = [];
205
+ for (const file of params.changedFiles) {
206
+ if (!isFileAllowed(file, policy)) {
207
+ violations.push(file);
208
+ }
209
+ else if (!isCategoryFileAllowed(file, ticket.category ?? null)) {
210
+ categoryViolations.push(file);
211
+ }
212
+ }
213
+ if (violations.length > 0 || categoryViolations.length > 0) {
214
+ const allViolations = [...violations, ...categoryViolations];
215
+ state.run.appendEvent('SCOPE_BLOCKED', {
216
+ ticket_id: params.ticketId,
217
+ violations: allViolations,
218
+ category_violations: categoryViolations.length > 0 ? categoryViolations : undefined,
219
+ allowed_paths: ticket.allowedPaths,
220
+ });
221
+ const message = categoryViolations.length > 0
222
+ ? `Category "${ticket.category}" restricts file types. These files violate the restriction: ${categoryViolations.join(', ')}`
223
+ : 'Some changed files are outside the allowed scope. Revert those changes before completing.';
224
+ return {
225
+ content: [{
226
+ type: 'text',
227
+ text: JSON.stringify({
228
+ valid: false,
229
+ violations: allViolations,
230
+ categoryViolations: categoryViolations.length > 0 ? categoryViolations : undefined,
231
+ allowedPaths: ticket.allowedPaths,
232
+ message,
233
+ }, null, 2),
234
+ }],
235
+ };
236
+ }
237
+ state.run.appendEvent('SCOPE_ALLOWED', { ticket_id: params.ticketId, files: params.changedFiles });
238
+ return {
239
+ content: [{
240
+ type: 'text',
241
+ text: JSON.stringify({ valid: true, message: 'All changes within allowed scope.' }),
242
+ }],
243
+ };
244
+ });
245
+ server.tool('promptwheel_complete_ticket', 'Mark a ticket as done. PromptWheel runs QA commands to verify, then records success.', {
246
+ ticketId: z.string().optional().describe('The ticket ID to complete.'),
247
+ ticket_id: z.string().optional().describe('Alias for ticketId.'),
248
+ runId: z.string().optional().describe('The run ID from next_ticket.'),
249
+ run_id: z.string().optional().describe('Alias for runId.'),
250
+ summary: z.string().optional().describe('Brief summary of changes made.'),
251
+ }, async (raw) => {
252
+ const ticketId = raw.ticketId ?? raw.ticket_id;
253
+ const runId = raw.runId ?? raw.run_id;
254
+ if (!ticketId || !runId) {
255
+ return {
256
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Missing required parameters: ticketId (or ticket_id) and runId (or run_id).' }) }],
257
+ isError: true,
258
+ };
259
+ }
260
+ const params = { ticketId, runId, summary: raw.summary };
261
+ const state = getState();
262
+ state.requireActive();
263
+ const ticket = await repos.tickets.getById(state.db, params.ticketId);
264
+ if (!ticket) {
265
+ return {
266
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Ticket not found.' }) }],
267
+ isError: true,
268
+ };
269
+ }
270
+ state.run.appendEvent('QA_STARTED', { ticket_id: params.ticketId });
271
+ // Validate all verification commands before executing any
272
+ const invalidCommands = [];
273
+ for (const cmd of ticket.verificationCommands) {
274
+ const validation = validateVerificationCommand(cmd);
275
+ if (!validation.valid) {
276
+ invalidCommands.push({ command: cmd, reason: validation.reason });
277
+ }
278
+ }
279
+ if (invalidCommands.length > 0) {
280
+ state.run.appendEvent('QA_FAILED', {
281
+ ticket_id: params.ticketId,
282
+ reason: 'Verification command validation failed',
283
+ invalid_commands: invalidCommands,
284
+ });
285
+ return {
286
+ content: [{
287
+ type: 'text',
288
+ text: JSON.stringify({
289
+ success: false,
290
+ ticketId: params.ticketId,
291
+ error: 'Verification command validation failed',
292
+ invalidCommands,
293
+ message: 'One or more verification commands were rejected for security reasons. Only standard test runners are allowed (npm test, vitest, jest, pytest, go test, cargo test, etc.).',
294
+ }, null, 2),
295
+ }],
296
+ isError: true,
297
+ };
298
+ }
299
+ // Run QA commands
300
+ const qaResults = [];
301
+ for (const cmd of ticket.verificationCommands) {
302
+ try {
303
+ const output = execSync(cmd, {
304
+ cwd: state.project.rootPath,
305
+ timeout: 120_000,
306
+ encoding: 'utf-8',
307
+ stdio: ['pipe', 'pipe', 'pipe'],
308
+ });
309
+ qaResults.push({ command: cmd, success: true, output: output.slice(-2000) });
310
+ state.run.appendEvent('QA_COMMAND_RESULT', { command: cmd, success: true });
311
+ }
312
+ catch (e) {
313
+ const err = e;
314
+ const output = (err.stderr || err.stdout || err.message).slice(-2000);
315
+ qaResults.push({ command: cmd, success: false, output });
316
+ state.run.appendEvent('QA_COMMAND_RESULT', { command: cmd, success: false });
317
+ }
318
+ }
319
+ const allPassed = qaResults.every(r => r.success);
320
+ if (allPassed) {
321
+ await repos.tickets.updateStatus(state.db, params.ticketId, 'done');
322
+ await repos.runs.markSuccess(state.db, params.runId, {
323
+ summary: params.summary,
324
+ qaResults,
325
+ });
326
+ state.run.appendEvent('QA_PASSED', { ticket_id: params.ticketId });
327
+ state.run.setPhase('PR');
328
+ // Save QA artifact
329
+ state.run.saveArtifact(`${state.run.require().step_count}-qa-stdout.log`, qaResults.map(r => `$ ${r.command}\n${r.output}`).join('\n\n'));
330
+ return {
331
+ content: [{
332
+ type: 'text',
333
+ text: JSON.stringify({
334
+ success: true,
335
+ ticketId: params.ticketId,
336
+ qaResults: qaResults.map(r => ({ command: r.command, success: r.success })),
337
+ message: 'QA passed. Call promptwheel_advance to create a PR for this ticket.',
338
+ }, null, 2),
339
+ }],
340
+ };
341
+ }
342
+ else {
343
+ state.run.appendEvent('QA_FAILED', { ticket_id: params.ticketId, results: qaResults });
344
+ return {
345
+ content: [{
346
+ type: 'text',
347
+ text: JSON.stringify({
348
+ success: false,
349
+ ticketId: params.ticketId,
350
+ qaResults,
351
+ message: 'QA failed. Fix the issues and try again, or call promptwheel_fail_ticket.',
352
+ }, null, 2),
353
+ }],
354
+ };
355
+ }
356
+ });
357
+ server.tool('promptwheel_fail_ticket', 'Mark a ticket as failed with a reason.', {
358
+ ticketId: z.string().optional().describe('The ticket ID that failed.'),
359
+ ticket_id: z.string().optional().describe('Alias for ticketId.'),
360
+ runId: z.string().optional().describe('The run ID from next_ticket.'),
361
+ run_id: z.string().optional().describe('Alias for runId.'),
362
+ reason: z.string().optional().describe('Why the ticket failed.'),
363
+ }, async (raw) => {
364
+ const ticketId = raw.ticketId ?? raw.ticket_id;
365
+ const runId = raw.runId ?? raw.run_id;
366
+ if (!ticketId || !runId) {
367
+ return {
368
+ content: [{ type: 'text', text: JSON.stringify({ error: 'Missing required parameters: ticketId (or ticket_id) and runId (or run_id).' }) }],
369
+ isError: true,
370
+ };
371
+ }
372
+ const params = { ticketId, runId, reason: raw.reason ?? 'Unknown failure' };
373
+ const state = getState();
374
+ state.requireActive();
375
+ await repos.tickets.updateStatus(state.db, params.ticketId, 'blocked');
376
+ await repos.runs.markFailure(state.db, params.runId, params.reason);
377
+ state.run.failTicket(params.reason);
378
+ return {
379
+ content: [{
380
+ type: 'text',
381
+ text: JSON.stringify({
382
+ ticketId: params.ticketId,
383
+ status: 'blocked',
384
+ reason: params.reason,
385
+ message: 'Ticket marked as failed. Use promptwheel_next_ticket for the next one.',
386
+ }, null, 2),
387
+ }],
388
+ };
389
+ });
390
+ }
391
+ function buildExecutionPrompt(ticket) {
392
+ const parts = [
393
+ `# Task: ${ticket.title}`,
394
+ '',
395
+ ticket.description ?? '',
396
+ '',
397
+ '## Constraints',
398
+ '',
399
+ `- Only modify files in: ${ticket.allowedPaths.length > 0 ? ticket.allowedPaths.join(', ') : 'any files'}`,
400
+ '- Make minimal, focused changes',
401
+ '- Do not introduce new dependencies unless necessary',
402
+ '',
403
+ '## Verification',
404
+ '',
405
+ 'After making changes, these commands must pass:',
406
+ ...ticket.verificationCommands.map(c => `- \`${c}\``),
407
+ '',
408
+ '## Workflow',
409
+ '',
410
+ '1. Read the relevant files',
411
+ '2. Make the changes described above',
412
+ '3. Call promptwheel_validate_scope with the list of changed files',
413
+ '4. If valid, call promptwheel_complete_ticket',
414
+ '5. If QA fails, fix and retry or call promptwheel_fail_ticket',
415
+ ];
416
+ return parts.join('\n');
417
+ }
418
+ //# sourceMappingURL=execute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute.js","sourceRoot":"","sources":["../../src/tools/execute.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Git operations tool: git_setup
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { SessionManager } from '../state.js';
6
+ export declare function registerGitTools(server: McpServer, getState: () => SessionManager): void;
7
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/tools/git.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAgBlD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,QAuFjF"}