@blockspool/mcp 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +174 -0
- package/dist/advance.d.ts +30 -0
- package/dist/advance.d.ts.map +1 -0
- package/dist/advance.js +514 -0
- package/dist/advance.js.map +1 -0
- package/dist/direct-client.d.ts +57 -0
- package/dist/direct-client.d.ts.map +1 -0
- package/dist/direct-client.js +92 -0
- package/dist/direct-client.js.map +1 -0
- package/dist/event-processor.d.ts +17 -0
- package/dist/event-processor.d.ts.map +1 -0
- package/dist/event-processor.js +360 -0
- package/dist/event-processor.js.map +1 -0
- package/dist/formulas.d.ts +37 -0
- package/dist/formulas.d.ts.map +1 -0
- package/dist/formulas.js +245 -0
- package/dist/formulas.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/proposals.d.ts +51 -0
- package/dist/proposals.d.ts.map +1 -0
- package/dist/proposals.js +207 -0
- package/dist/proposals.js.map +1 -0
- package/dist/run-manager.d.ts +69 -0
- package/dist/run-manager.d.ts.map +1 -0
- package/dist/run-manager.js +315 -0
- package/dist/run-manager.js.map +1 -0
- package/dist/scope-policy.d.ts +34 -0
- package/dist/scope-policy.d.ts.map +1 -0
- package/dist/scope-policy.js +145 -0
- package/dist/scope-policy.js.map +1 -0
- package/dist/server.d.ts +16 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +31 -0
- package/dist/server.js.map +1 -0
- package/dist/spindle.d.ts +41 -0
- package/dist/spindle.d.ts.map +1 -0
- package/dist/spindle.js +279 -0
- package/dist/spindle.js.map +1 -0
- package/dist/state.d.ts +36 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +50 -0
- package/dist/state.js.map +1 -0
- package/dist/tools/execute.d.ts +7 -0
- package/dist/tools/execute.d.ts.map +1 -0
- package/dist/tools/execute.js +238 -0
- package/dist/tools/execute.js.map +1 -0
- package/dist/tools/git.d.ts +7 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +67 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/scout.d.ts +7 -0
- package/dist/tools/scout.d.ts.map +1 -0
- package/dist/tools/scout.js +199 -0
- package/dist/tools/scout.js.map +1 -0
- package/dist/tools/session.d.ts +7 -0
- package/dist/tools/session.d.ts.map +1 -0
- package/dist/tools/session.js +296 -0
- package/dist/tools/session.js.map +1 -0
- package/dist/types.d.ts +116 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/package.json +63 -0
package/dist/spindle.js
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spindle Loop Detection — MCP server adaptation.
|
|
3
|
+
*
|
|
4
|
+
* Monitors agent execution for unproductive patterns:
|
|
5
|
+
* - Oscillation: diffs flip-flopping (A→B→A)
|
|
6
|
+
* - Repetition: similar outputs repeated
|
|
7
|
+
* - Stalling: no file changes for N iterations
|
|
8
|
+
* - QA ping-pong: alternating test/lint failures
|
|
9
|
+
* - Command signature: same command fails repeatedly
|
|
10
|
+
*
|
|
11
|
+
* Ported from packages/cli/src/lib/spindle.ts, adapted for the
|
|
12
|
+
* event-driven MCP architecture.
|
|
13
|
+
*/
|
|
14
|
+
import { createHash } from 'node:crypto';
|
|
15
|
+
export const DEFAULT_SPINDLE_CONFIG = {
|
|
16
|
+
similarityThreshold: 0.8,
|
|
17
|
+
maxSimilarOutputs: 3,
|
|
18
|
+
maxStallIterations: 5,
|
|
19
|
+
maxCommandFailures: 3,
|
|
20
|
+
maxQaPingPong: 3,
|
|
21
|
+
maxFileEdits: 3,
|
|
22
|
+
};
|
|
23
|
+
const PASS = {
|
|
24
|
+
shouldAbort: false,
|
|
25
|
+
shouldBlock: false,
|
|
26
|
+
confidence: 0,
|
|
27
|
+
diagnostics: {},
|
|
28
|
+
risk: 'none',
|
|
29
|
+
};
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Core check — runs on every advance()
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
export function checkSpindle(spindle, config = DEFAULT_SPINDLE_CONFIG) {
|
|
34
|
+
// 1. Stalling — no file changes
|
|
35
|
+
if (spindle.iterations_since_change >= config.maxStallIterations) {
|
|
36
|
+
return {
|
|
37
|
+
shouldAbort: true,
|
|
38
|
+
shouldBlock: false,
|
|
39
|
+
reason: 'stalling',
|
|
40
|
+
confidence: 0.9,
|
|
41
|
+
diagnostics: {
|
|
42
|
+
iterations_without_change: spindle.iterations_since_change,
|
|
43
|
+
threshold: config.maxStallIterations,
|
|
44
|
+
},
|
|
45
|
+
risk: 'high',
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// 2. Oscillation — diff flip-flops
|
|
49
|
+
if (spindle.diff_hashes.length >= 3) {
|
|
50
|
+
const osc = detectOscillation(spindle.diff_hashes);
|
|
51
|
+
if (osc) {
|
|
52
|
+
return {
|
|
53
|
+
shouldAbort: true,
|
|
54
|
+
shouldBlock: false,
|
|
55
|
+
reason: 'oscillation',
|
|
56
|
+
confidence: 0.95,
|
|
57
|
+
diagnostics: { pattern: osc },
|
|
58
|
+
risk: 'high',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 3. Repetition — similar output hashes
|
|
63
|
+
if (spindle.output_hashes.length >= config.maxSimilarOutputs) {
|
|
64
|
+
const rep = detectRepetition(spindle.output_hashes, config.maxSimilarOutputs);
|
|
65
|
+
if (rep) {
|
|
66
|
+
return {
|
|
67
|
+
shouldAbort: true,
|
|
68
|
+
shouldBlock: false,
|
|
69
|
+
reason: 'repetition',
|
|
70
|
+
confidence: 0.85,
|
|
71
|
+
diagnostics: { repeated_hash: rep, count: config.maxSimilarOutputs },
|
|
72
|
+
risk: 'high',
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// 4. QA ping-pong — alternating failure types
|
|
77
|
+
if (spindle.failing_command_signatures.length >= config.maxQaPingPong * 2) {
|
|
78
|
+
const pp = detectQaPingPong(spindle.failing_command_signatures, config.maxQaPingPong);
|
|
79
|
+
if (pp) {
|
|
80
|
+
return {
|
|
81
|
+
shouldAbort: true,
|
|
82
|
+
shouldBlock: false,
|
|
83
|
+
reason: 'qa_ping_pong',
|
|
84
|
+
confidence: 0.9,
|
|
85
|
+
diagnostics: { pattern: pp },
|
|
86
|
+
risk: 'high',
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// 5. Command signature — same command fails N times
|
|
91
|
+
const cmdFail = detectCommandFailure(spindle.failing_command_signatures, config.maxCommandFailures);
|
|
92
|
+
if (cmdFail) {
|
|
93
|
+
return {
|
|
94
|
+
shouldAbort: false,
|
|
95
|
+
shouldBlock: true, // → BLOCKED_NEEDS_HUMAN
|
|
96
|
+
reason: 'command_failure',
|
|
97
|
+
confidence: 0.8,
|
|
98
|
+
diagnostics: { command: cmdFail, threshold: config.maxCommandFailures },
|
|
99
|
+
risk: 'high',
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
// Compute risk level
|
|
103
|
+
const risk = computeRisk(spindle, config);
|
|
104
|
+
return { ...PASS, risk };
|
|
105
|
+
}
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// State update helpers — called from event processor
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
export function recordOutput(spindle, output) {
|
|
110
|
+
const hash = shortHash(output);
|
|
111
|
+
spindle.output_hashes.push(hash);
|
|
112
|
+
if (spindle.output_hashes.length > 10)
|
|
113
|
+
spindle.output_hashes.shift();
|
|
114
|
+
spindle.total_output_chars += output.length;
|
|
115
|
+
}
|
|
116
|
+
export function recordDiff(spindle, diff) {
|
|
117
|
+
if (!diff || diff.trim() === '') {
|
|
118
|
+
spindle.iterations_since_change++;
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
spindle.iterations_since_change = 0;
|
|
122
|
+
const hash = shortHash(diff);
|
|
123
|
+
spindle.diff_hashes.push(hash);
|
|
124
|
+
if (spindle.diff_hashes.length > 10)
|
|
125
|
+
spindle.diff_hashes.shift();
|
|
126
|
+
spindle.total_change_chars += diff.length;
|
|
127
|
+
// Track per-file edit frequency
|
|
128
|
+
const files = extractFilesFromDiff(diff);
|
|
129
|
+
for (const f of files) {
|
|
130
|
+
const existing = spindle.file_edit_counts?.[f] ?? 0;
|
|
131
|
+
if (!spindle.file_edit_counts)
|
|
132
|
+
spindle.file_edit_counts = {};
|
|
133
|
+
spindle.file_edit_counts[f] = existing + 1;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
export function recordCommandFailure(spindle, command, error) {
|
|
137
|
+
const sig = shortHash(`${command}::${error.slice(0, 200)}`);
|
|
138
|
+
spindle.failing_command_signatures.push(sig);
|
|
139
|
+
if (spindle.failing_command_signatures.length > 20)
|
|
140
|
+
spindle.failing_command_signatures.shift();
|
|
141
|
+
}
|
|
142
|
+
export function recordPlanHash(spindle, plan) {
|
|
143
|
+
const hash = shortHash(JSON.stringify(plan));
|
|
144
|
+
spindle.plan_hashes.push(hash);
|
|
145
|
+
if (spindle.plan_hashes.length > 10)
|
|
146
|
+
spindle.plan_hashes.shift();
|
|
147
|
+
}
|
|
148
|
+
export function recordTicketResult(spindle, changedFiles, diff) {
|
|
149
|
+
recordDiff(spindle, diff);
|
|
150
|
+
}
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// Detection functions
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
/** Detect A→B→A hash oscillation */
|
|
155
|
+
function detectOscillation(hashes) {
|
|
156
|
+
// Check for A→B→A pattern in last 3
|
|
157
|
+
const recent = hashes.slice(-3);
|
|
158
|
+
if (recent.length === 3 && recent[0] === recent[2] && recent[0] !== recent[1]) {
|
|
159
|
+
return `Hash ${recent[0]} appeared at positions -3 and -1 (flip-flop)`;
|
|
160
|
+
}
|
|
161
|
+
// Check for any hash appearing in alternating positions
|
|
162
|
+
for (let i = hashes.length - 1; i >= 2; i--) {
|
|
163
|
+
if (hashes[i] === hashes[i - 2] && hashes[i] !== hashes[i - 1]) {
|
|
164
|
+
return `Hash ${hashes[i]} oscillating at positions ${i - 2}, ${i}`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
/** Detect N consecutive identical output hashes */
|
|
170
|
+
function detectRepetition(hashes, threshold) {
|
|
171
|
+
if (hashes.length < threshold)
|
|
172
|
+
return null;
|
|
173
|
+
const recent = hashes.slice(-threshold);
|
|
174
|
+
const first = recent[0];
|
|
175
|
+
if (recent.every(h => h === first)) {
|
|
176
|
+
return first;
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
/** Detect QA ping-pong: alternating failure signatures */
|
|
181
|
+
function detectQaPingPong(sigs, cycles) {
|
|
182
|
+
if (sigs.length < cycles * 2)
|
|
183
|
+
return null;
|
|
184
|
+
const recent = sigs.slice(-(cycles * 2));
|
|
185
|
+
// Check for A→B→A→B pattern
|
|
186
|
+
const a = recent[0];
|
|
187
|
+
const b = recent[1];
|
|
188
|
+
if (a === b)
|
|
189
|
+
return null; // Not alternating
|
|
190
|
+
let alternating = true;
|
|
191
|
+
for (let i = 0; i < recent.length; i++) {
|
|
192
|
+
const expected = i % 2 === 0 ? a : b;
|
|
193
|
+
if (recent[i] !== expected) {
|
|
194
|
+
alternating = false;
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
if (alternating) {
|
|
199
|
+
return `Alternating failures: ${a} ↔ ${b} (${cycles} cycles)`;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
/** Detect same command failing N times */
|
|
204
|
+
function detectCommandFailure(sigs, threshold) {
|
|
205
|
+
if (sigs.length < threshold)
|
|
206
|
+
return null;
|
|
207
|
+
// Count occurrences of each signature
|
|
208
|
+
const counts = new Map();
|
|
209
|
+
for (const sig of sigs) {
|
|
210
|
+
counts.set(sig, (counts.get(sig) ?? 0) + 1);
|
|
211
|
+
}
|
|
212
|
+
for (const [sig, count] of counts) {
|
|
213
|
+
if (count >= threshold)
|
|
214
|
+
return sig;
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
// Risk computation
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
function computeRisk(spindle, config) {
|
|
222
|
+
let score = 0;
|
|
223
|
+
// Stall proximity
|
|
224
|
+
if (spindle.iterations_since_change >= config.maxStallIterations * 0.6)
|
|
225
|
+
score += 2;
|
|
226
|
+
else if (spindle.iterations_since_change >= 2)
|
|
227
|
+
score += 1;
|
|
228
|
+
// Repeated outputs
|
|
229
|
+
const recentOutputs = spindle.output_hashes.slice(-3);
|
|
230
|
+
if (recentOutputs.length >= 2 && recentOutputs[recentOutputs.length - 1] === recentOutputs[recentOutputs.length - 2]) {
|
|
231
|
+
score += 1;
|
|
232
|
+
}
|
|
233
|
+
// File edit frequency warnings
|
|
234
|
+
if (spindle.file_edit_counts) {
|
|
235
|
+
for (const count of Object.values(spindle.file_edit_counts)) {
|
|
236
|
+
if (count >= config.maxFileEdits)
|
|
237
|
+
score += 2;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
// Command failures
|
|
241
|
+
if (spindle.failing_command_signatures.length >= 2)
|
|
242
|
+
score += 1;
|
|
243
|
+
if (score >= 4)
|
|
244
|
+
return 'high';
|
|
245
|
+
if (score >= 2)
|
|
246
|
+
return 'medium';
|
|
247
|
+
if (score >= 1)
|
|
248
|
+
return 'low';
|
|
249
|
+
return 'none';
|
|
250
|
+
}
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
// Helpers
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
function shortHash(s) {
|
|
255
|
+
return createHash('sha256').update(s).digest('hex').slice(0, 12);
|
|
256
|
+
}
|
|
257
|
+
/** Extract file paths from a unified diff */
|
|
258
|
+
function extractFilesFromDiff(diff) {
|
|
259
|
+
const files = [];
|
|
260
|
+
for (const line of diff.split('\n')) {
|
|
261
|
+
if (line.startsWith('+++ b/')) {
|
|
262
|
+
files.push(line.slice(6));
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return files;
|
|
266
|
+
}
|
|
267
|
+
/** Get file edit frequency warnings */
|
|
268
|
+
export function getFileEditWarnings(spindle, threshold = 3) {
|
|
269
|
+
if (!spindle.file_edit_counts)
|
|
270
|
+
return [];
|
|
271
|
+
const warnings = [];
|
|
272
|
+
for (const [file, count] of Object.entries(spindle.file_edit_counts)) {
|
|
273
|
+
if (count >= threshold) {
|
|
274
|
+
warnings.push(`${file} edited ${count} times`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return warnings;
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=spindle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spindle.js","sourceRoot":"","sources":["../src/spindle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAgBzC,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,mBAAmB,EAAE,GAAG;IACxB,iBAAiB,EAAE,CAAC;IACpB,kBAAkB,EAAE,CAAC;IACrB,kBAAkB,EAAE,CAAC;IACrB,aAAa,EAAE,CAAC;IAChB,YAAY,EAAE,CAAC;CAChB,CAAC;AAsBF,MAAM,IAAI,GAAuB;IAC/B,WAAW,EAAE,KAAK;IAClB,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,EAAE;IACf,IAAI,EAAE,MAAM;CACb,CAAC;AAEF,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAE9E,MAAM,UAAU,YAAY,CAC1B,OAAqB,EACrB,SAAwB,sBAAsB;IAE9C,gCAAgC;IAChC,IAAI,OAAO,CAAC,uBAAuB,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACjE,OAAO;YACL,WAAW,EAAE,IAAI;YACjB,WAAW,EAAE,KAAK;YAClB,MAAM,EAAE,UAAU;YAClB,UAAU,EAAE,GAAG;YACf,WAAW,EAAE;gBACX,yBAAyB,EAAE,OAAO,CAAC,uBAAuB;gBAC1D,SAAS,EAAE,MAAM,CAAC,kBAAkB;aACrC;YACD,IAAI,EAAE,MAAM;SACb,CAAC;IACJ,CAAC;IAED,mCAAmC;IACnC,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,iBAAiB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACnD,IAAI,GAAG,EAAE,CAAC;YACR,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,aAAa;gBACrB,UAAU,EAAE,IAAI;gBAChB,WAAW,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE;gBAC7B,IAAI,EAAE,MAAM;aACb,CAAC;QACJ,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC7D,MAAM,GAAG,GAAG,gBAAgB,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAC9E,IAAI,GAAG,EAAE,CAAC;YACR,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,YAAY;gBACpB,UAAU,EAAE,IAAI;gBAChB,WAAW,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,iBAAiB,EAAE;gBACpE,IAAI,EAAE,MAAM;aACb,CAAC;QACJ,CAAC;IACH,CAAC;IAED,8CAA8C;IAC9C,IAAI,OAAO,CAAC,0BAA0B,CAAC,MAAM,IAAI,MAAM,CAAC,aAAa,GAAG,CAAC,EAAE,CAAC;QAC1E,MAAM,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QACtF,IAAI,EAAE,EAAE,CAAC;YACP,OAAO;gBACL,WAAW,EAAE,IAAI;gBACjB,WAAW,EAAE,KAAK;gBAClB,MAAM,EAAE,cAAc;gBACtB,UAAU,EAAE,GAAG;gBACf,WAAW,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBAC5B,IAAI,EAAE,MAAM;aACb,CAAC;QACJ,CAAC;IACH,CAAC;IAED,oDAAoD;IACpD,MAAM,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,0BAA0B,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACpG,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO;YACL,WAAW,EAAE,KAAK;YAClB,WAAW,EAAE,IAAI,EAAE,wBAAwB;YAC3C,MAAM,EAAE,iBAAiB;YACzB,UAAU,EAAE,GAAG;YACf,WAAW,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,kBAAkB,EAAE;YACvE,IAAI,EAAE,MAAM;SACb,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE1C,OAAO,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,8EAA8E;AAC9E,qDAAqD;AACrD,8EAA8E;AAE9E,MAAM,UAAU,YAAY,CAAC,OAAqB,EAAE,MAAc;IAChE,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,OAAO,CAAC,aAAa,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IACrE,OAAO,CAAC,kBAAkB,IAAI,MAAM,CAAC,MAAM,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAqB,EAAE,IAAmB;IACnE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAChC,OAAO,CAAC,uBAAuB,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,uBAAuB,GAAG,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC7B,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IACjE,OAAO,CAAC,kBAAkB,IAAI,IAAI,CAAC,MAAM,CAAC;IAE1C,gCAAgC;IAChC,MAAM,KAAK,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,gBAAgB;YAAE,OAAO,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC7D,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAqB,EAAE,OAAe,EAAE,KAAa;IACxF,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,OAAO,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5D,OAAO,CAAC,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,OAAO,CAAC,0BAA0B,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,CAAC,0BAA0B,CAAC,KAAK,EAAE,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAqB,EAAE,IAAa;IACjE,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,OAAO,CAAC,WAAW,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAqB,EAAE,YAAsB,EAAE,IAAmB;IACnG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,oCAAoC;AACpC,SAAS,iBAAiB,CAAC,MAAgB;IACzC,oCAAoC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9E,OAAO,QAAQ,MAAM,CAAC,CAAC,CAAC,8CAA8C,CAAC;IACzE,CAAC;IAED,wDAAwD;IACxD,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC/D,OAAO,QAAQ,MAAM,CAAC,CAAC,CAAC,6BAA6B,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACrE,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,mDAAmD;AACnD,SAAS,gBAAgB,CAAC,MAAgB,EAAE,SAAiB;IAC3D,IAAI,MAAM,CAAC,MAAM,GAAG,SAAS;QAAE,OAAO,IAAI,CAAC;IAE3C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0DAA0D;AAC1D,SAAS,gBAAgB,CAAC,IAAc,EAAE,MAAc;IACtD,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IAEzC,4BAA4B;IAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,kBAAkB;IAE5C,IAAI,WAAW,GAAG,IAAI,CAAC;IACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC3B,WAAW,GAAG,KAAK,CAAC;YACpB,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,yBAAyB,CAAC,MAAM,CAAC,KAAK,MAAM,UAAU,CAAC;IAChE,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,0CAA0C;AAC1C,SAAS,oBAAoB,CAAC,IAAc,EAAE,SAAiB;IAC7D,IAAI,IAAI,CAAC,MAAM,GAAG,SAAS;QAAE,OAAO,IAAI,CAAC;IAEzC,sCAAsC;IACtC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QAClC,IAAI,KAAK,IAAI,SAAS;YAAE,OAAO,GAAG,CAAC;IACrC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,SAAS,WAAW,CAClB,OAAqB,EACrB,MAAqB;IAErB,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,kBAAkB;IAClB,IAAI,OAAO,CAAC,uBAAuB,IAAI,MAAM,CAAC,kBAAkB,GAAG,GAAG;QAAE,KAAK,IAAI,CAAC,CAAC;SAC9E,IAAI,OAAO,CAAC,uBAAuB,IAAI,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IAE1D,mBAAmB;IACnB,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,aAAa,CAAC,MAAM,IAAI,CAAC,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QACrH,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IAED,+BAA+B;IAC/B,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAC5D,IAAI,KAAK,IAAI,MAAM,CAAC,YAAY;gBAAE,KAAK,IAAI,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,mBAAmB;IACnB,IAAI,OAAO,CAAC,0BAA0B,CAAC,MAAM,IAAI,CAAC;QAAE,KAAK,IAAI,CAAC,CAAC;IAE/D,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChC,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,SAAS,CAAC,CAAS;IAC1B,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnE,CAAC;AAED,6CAA6C;AAC7C,SAAS,oBAAoB,CAAC,IAAY;IACxC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,mBAAmB,CAAC,OAAqB,EAAE,YAAoB,CAAC;IAC9E,IAAI,CAAC,OAAO,CAAC,gBAAgB;QAAE,OAAO,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QACrE,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,WAAW,KAAK,QAAQ,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session state manager (v2)
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around RunManager + database.
|
|
5
|
+
* Each MCP server instance has at most one active run.
|
|
6
|
+
*/
|
|
7
|
+
import type { DatabaseAdapter } from '@blockspool/core';
|
|
8
|
+
import type { Project } from '@blockspool/core';
|
|
9
|
+
import { RunManager } from './run-manager.js';
|
|
10
|
+
import type { RunState, SessionConfig } from './types.js';
|
|
11
|
+
export declare class SessionManager {
|
|
12
|
+
readonly db: DatabaseAdapter;
|
|
13
|
+
readonly project: Project;
|
|
14
|
+
readonly projectPath: string;
|
|
15
|
+
readonly run: RunManager;
|
|
16
|
+
constructor(db: DatabaseAdapter, project: Project, projectPath: string);
|
|
17
|
+
/** Start a new session/run */
|
|
18
|
+
start(config: SessionConfig): RunState;
|
|
19
|
+
/** Get active run state or throw */
|
|
20
|
+
requireActive(): RunState;
|
|
21
|
+
/** End the session */
|
|
22
|
+
end(): RunState;
|
|
23
|
+
/** Get current status summary */
|
|
24
|
+
getStatus(): {
|
|
25
|
+
sessionId: string;
|
|
26
|
+
runId: string;
|
|
27
|
+
phase: string;
|
|
28
|
+
stepCount: number;
|
|
29
|
+
budgetRemaining: number;
|
|
30
|
+
ticketsCompleted: number;
|
|
31
|
+
ticketsFailed: number;
|
|
32
|
+
currentTicketId: string | null;
|
|
33
|
+
timeRemainingMs: number | null;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE1D,qBAAa,cAAc;IAIvB,QAAQ,CAAC,EAAE,EAAE,eAAe;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM;IAL9B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;gBAGd,EAAE,EAAE,eAAe,EACnB,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,MAAM;IAK9B,8BAA8B;IAC9B,KAAK,CAAC,MAAM,EAAE,aAAa,GAAG,QAAQ;IAItC,oCAAoC;IACpC,aAAa,IAAI,QAAQ;IAIzB,sBAAsB;IACtB,GAAG,IAAI,QAAQ;IAIf,iCAAiC;IACjC,SAAS,IAAI;QACX,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;KAChC;CAkBF"}
|
package/dist/state.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session state manager (v2)
|
|
3
|
+
*
|
|
4
|
+
* Thin wrapper around RunManager + database.
|
|
5
|
+
* Each MCP server instance has at most one active run.
|
|
6
|
+
*/
|
|
7
|
+
import { RunManager } from './run-manager.js';
|
|
8
|
+
export class SessionManager {
|
|
9
|
+
db;
|
|
10
|
+
project;
|
|
11
|
+
projectPath;
|
|
12
|
+
run;
|
|
13
|
+
constructor(db, project, projectPath) {
|
|
14
|
+
this.db = db;
|
|
15
|
+
this.project = project;
|
|
16
|
+
this.projectPath = projectPath;
|
|
17
|
+
this.run = new RunManager(projectPath);
|
|
18
|
+
}
|
|
19
|
+
/** Start a new session/run */
|
|
20
|
+
start(config) {
|
|
21
|
+
return this.run.create(this.project.id, config);
|
|
22
|
+
}
|
|
23
|
+
/** Get active run state or throw */
|
|
24
|
+
requireActive() {
|
|
25
|
+
return this.run.require();
|
|
26
|
+
}
|
|
27
|
+
/** End the session */
|
|
28
|
+
end() {
|
|
29
|
+
return this.run.end();
|
|
30
|
+
}
|
|
31
|
+
/** Get current status summary */
|
|
32
|
+
getStatus() {
|
|
33
|
+
const s = this.run.require();
|
|
34
|
+
const timeRemainingMs = s.expires_at
|
|
35
|
+
? Math.max(0, new Date(s.expires_at).getTime() - Date.now())
|
|
36
|
+
: null;
|
|
37
|
+
return {
|
|
38
|
+
sessionId: s.session_id,
|
|
39
|
+
runId: s.run_id,
|
|
40
|
+
phase: s.phase,
|
|
41
|
+
stepCount: s.step_count,
|
|
42
|
+
budgetRemaining: s.step_budget - s.step_count,
|
|
43
|
+
ticketsCompleted: s.tickets_completed,
|
|
44
|
+
ticketsFailed: s.tickets_failed,
|
|
45
|
+
currentTicketId: s.current_ticket_id,
|
|
46
|
+
timeRemainingMs,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,OAAO,cAAc;IAId;IACA;IACA;IALF,GAAG,CAAa;IAEzB,YACW,EAAmB,EACnB,OAAgB,EAChB,WAAmB;QAFnB,OAAE,GAAF,EAAE,CAAiB;QACnB,YAAO,GAAP,OAAO,CAAS;QAChB,gBAAW,GAAX,WAAW,CAAQ;QAE5B,IAAI,CAAC,GAAG,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAED,8BAA8B;IAC9B,KAAK,CAAC,MAAqB;QACzB,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,oCAAoC;IACpC,aAAa;QACX,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IAED,sBAAsB;IACtB,GAAG;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;IACxB,CAAC;IAED,iCAAiC;IACjC,SAAS;QAWP,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM,eAAe,GAAG,CAAC,CAAC,UAAU;YAClC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC5D,CAAC,CAAC,IAAI,CAAC;QAET,OAAO;YACL,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,KAAK,EAAE,CAAC,CAAC,MAAM;YACf,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,eAAe,EAAE,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,UAAU;YAC7C,gBAAgB,EAAE,CAAC,CAAC,iBAAiB;YACrC,aAAa,EAAE,CAAC,CAAC,cAAc;YAC/B,eAAe,EAAE,CAAC,CAAC,iBAAiB;YACpC,eAAe;SAChB,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,7 @@
|
|
|
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
|
+
export declare function registerExecuteTools(server: McpServer, getState: () => SessionManager): void;
|
|
7
|
+
//# 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;AAElD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,QAsPrF"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execution tools: next_ticket, validate_scope, complete_ticket, fail_ticket
|
|
3
|
+
*/
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { repos } from '@blockspool/core';
|
|
6
|
+
import { execSync } from 'node:child_process';
|
|
7
|
+
export function registerExecuteTools(server, getState) {
|
|
8
|
+
server.tool('blockspool_next_ticket', 'Returns the next ticket to work on: title, description, allowed_paths, and execution instructions.', {}, async () => {
|
|
9
|
+
const state = getState();
|
|
10
|
+
const run = state.requireActive();
|
|
11
|
+
// Find next ready ticket
|
|
12
|
+
const readyTickets = await repos.tickets.listByProject(state.db, run.project_id, { status: 'ready', limit: 1 });
|
|
13
|
+
if (readyTickets.length === 0) {
|
|
14
|
+
return {
|
|
15
|
+
content: [{
|
|
16
|
+
type: 'text',
|
|
17
|
+
text: JSON.stringify({
|
|
18
|
+
message: 'No tickets ready for execution. Run blockspool_scout_files to find more work.',
|
|
19
|
+
tickets_completed: run.tickets_completed,
|
|
20
|
+
tickets_failed: run.tickets_failed,
|
|
21
|
+
}),
|
|
22
|
+
}],
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const ticket = readyTickets[0];
|
|
26
|
+
// Mark as in_progress
|
|
27
|
+
await repos.tickets.updateStatus(state.db, ticket.id, 'in_progress');
|
|
28
|
+
state.run.assignTicket(ticket.id);
|
|
29
|
+
// Create a worker run record
|
|
30
|
+
const dbRun = await repos.runs.create(state.db, {
|
|
31
|
+
projectId: run.project_id,
|
|
32
|
+
type: 'worker',
|
|
33
|
+
ticketId: ticket.id,
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
content: [{
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: JSON.stringify({
|
|
39
|
+
ticketId: ticket.id,
|
|
40
|
+
runId: dbRun.id,
|
|
41
|
+
title: ticket.title,
|
|
42
|
+
description: ticket.description,
|
|
43
|
+
allowedPaths: ticket.allowedPaths,
|
|
44
|
+
verificationCommands: ticket.verificationCommands,
|
|
45
|
+
category: ticket.category,
|
|
46
|
+
instructions: buildExecutionPrompt(ticket),
|
|
47
|
+
}, null, 2),
|
|
48
|
+
}],
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
server.tool('blockspool_validate_scope', 'Before committing, send the list of changed files. BlockSpool checks scope enforcement.', {
|
|
52
|
+
ticketId: z.string().describe('The ticket ID being worked on.'),
|
|
53
|
+
changedFiles: z.array(z.string()).describe('List of file paths that were modified.'),
|
|
54
|
+
}, async (params) => {
|
|
55
|
+
const state = getState();
|
|
56
|
+
state.requireActive();
|
|
57
|
+
const ticket = await repos.tickets.getById(state.db, params.ticketId);
|
|
58
|
+
if (!ticket) {
|
|
59
|
+
return {
|
|
60
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'Ticket not found.' }) }],
|
|
61
|
+
isError: true,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// If no allowed_paths, everything is allowed
|
|
65
|
+
if (ticket.allowedPaths.length === 0) {
|
|
66
|
+
state.run.appendEvent('SCOPE_ALLOWED', { ticket_id: params.ticketId, files: params.changedFiles });
|
|
67
|
+
return {
|
|
68
|
+
content: [{
|
|
69
|
+
type: 'text',
|
|
70
|
+
text: JSON.stringify({ valid: true, message: 'No scope restrictions.' }),
|
|
71
|
+
}],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const violations = [];
|
|
75
|
+
for (const file of params.changedFiles) {
|
|
76
|
+
const allowed = ticket.allowedPaths.some(pattern => {
|
|
77
|
+
if (file === pattern)
|
|
78
|
+
return true;
|
|
79
|
+
if (file.startsWith(pattern.replace(/\*\*$/, '').replace(/\*$/, '')))
|
|
80
|
+
return true;
|
|
81
|
+
if (pattern.endsWith('/**') && file.startsWith(pattern.slice(0, -3)))
|
|
82
|
+
return true;
|
|
83
|
+
return false;
|
|
84
|
+
});
|
|
85
|
+
if (!allowed) {
|
|
86
|
+
violations.push(file);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (violations.length > 0) {
|
|
90
|
+
state.run.appendEvent('SCOPE_BLOCKED', {
|
|
91
|
+
ticket_id: params.ticketId,
|
|
92
|
+
violations,
|
|
93
|
+
allowed_paths: ticket.allowedPaths,
|
|
94
|
+
});
|
|
95
|
+
return {
|
|
96
|
+
content: [{
|
|
97
|
+
type: 'text',
|
|
98
|
+
text: JSON.stringify({
|
|
99
|
+
valid: false,
|
|
100
|
+
violations,
|
|
101
|
+
allowedPaths: ticket.allowedPaths,
|
|
102
|
+
message: 'Some changed files are outside the allowed scope. Revert those changes before completing.',
|
|
103
|
+
}, null, 2),
|
|
104
|
+
}],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
state.run.appendEvent('SCOPE_ALLOWED', { ticket_id: params.ticketId, files: params.changedFiles });
|
|
108
|
+
return {
|
|
109
|
+
content: [{
|
|
110
|
+
type: 'text',
|
|
111
|
+
text: JSON.stringify({ valid: true, message: 'All changes within allowed scope.' }),
|
|
112
|
+
}],
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
server.tool('blockspool_complete_ticket', 'Mark a ticket as done. BlockSpool runs QA commands to verify, then records success.', {
|
|
116
|
+
ticketId: z.string().describe('The ticket ID to complete.'),
|
|
117
|
+
runId: z.string().describe('The run ID from next_ticket.'),
|
|
118
|
+
summary: z.string().optional().describe('Brief summary of changes made.'),
|
|
119
|
+
}, async (params) => {
|
|
120
|
+
const state = getState();
|
|
121
|
+
state.requireActive();
|
|
122
|
+
const ticket = await repos.tickets.getById(state.db, params.ticketId);
|
|
123
|
+
if (!ticket) {
|
|
124
|
+
return {
|
|
125
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'Ticket not found.' }) }],
|
|
126
|
+
isError: true,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
state.run.appendEvent('QA_STARTED', { ticket_id: params.ticketId });
|
|
130
|
+
// Run QA commands
|
|
131
|
+
const qaResults = [];
|
|
132
|
+
for (const cmd of ticket.verificationCommands) {
|
|
133
|
+
try {
|
|
134
|
+
const output = execSync(cmd, {
|
|
135
|
+
cwd: state.project.rootPath,
|
|
136
|
+
timeout: 120_000,
|
|
137
|
+
encoding: 'utf-8',
|
|
138
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
139
|
+
});
|
|
140
|
+
qaResults.push({ command: cmd, success: true, output: output.slice(-2000) });
|
|
141
|
+
state.run.appendEvent('QA_COMMAND_RESULT', { command: cmd, success: true });
|
|
142
|
+
}
|
|
143
|
+
catch (e) {
|
|
144
|
+
const err = e;
|
|
145
|
+
const output = (err.stderr || err.stdout || err.message).slice(-2000);
|
|
146
|
+
qaResults.push({ command: cmd, success: false, output });
|
|
147
|
+
state.run.appendEvent('QA_COMMAND_RESULT', { command: cmd, success: false });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const allPassed = qaResults.every(r => r.success);
|
|
151
|
+
if (allPassed) {
|
|
152
|
+
await repos.tickets.updateStatus(state.db, params.ticketId, 'done');
|
|
153
|
+
await repos.runs.markSuccess(state.db, params.runId, {
|
|
154
|
+
summary: params.summary,
|
|
155
|
+
qaResults,
|
|
156
|
+
});
|
|
157
|
+
state.run.appendEvent('QA_PASSED', { ticket_id: params.ticketId });
|
|
158
|
+
state.run.setPhase('PR');
|
|
159
|
+
// Save QA artifact
|
|
160
|
+
state.run.saveArtifact(`${state.run.require().step_count}-qa-stdout.log`, qaResults.map(r => `$ ${r.command}\n${r.output}`).join('\n\n'));
|
|
161
|
+
return {
|
|
162
|
+
content: [{
|
|
163
|
+
type: 'text',
|
|
164
|
+
text: JSON.stringify({
|
|
165
|
+
success: true,
|
|
166
|
+
ticketId: params.ticketId,
|
|
167
|
+
qaResults: qaResults.map(r => ({ command: r.command, success: r.success })),
|
|
168
|
+
message: 'QA passed. Call blockspool_advance to create a PR for this ticket.',
|
|
169
|
+
}, null, 2),
|
|
170
|
+
}],
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
state.run.appendEvent('QA_FAILED', { ticket_id: params.ticketId, results: qaResults });
|
|
175
|
+
return {
|
|
176
|
+
content: [{
|
|
177
|
+
type: 'text',
|
|
178
|
+
text: JSON.stringify({
|
|
179
|
+
success: false,
|
|
180
|
+
ticketId: params.ticketId,
|
|
181
|
+
qaResults,
|
|
182
|
+
message: 'QA failed. Fix the issues and try again, or call blockspool_fail_ticket.',
|
|
183
|
+
}, null, 2),
|
|
184
|
+
}],
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
server.tool('blockspool_fail_ticket', 'Mark a ticket as failed with a reason.', {
|
|
189
|
+
ticketId: z.string().describe('The ticket ID that failed.'),
|
|
190
|
+
runId: z.string().describe('The run ID from next_ticket.'),
|
|
191
|
+
reason: z.string().describe('Why the ticket failed.'),
|
|
192
|
+
}, async (params) => {
|
|
193
|
+
const state = getState();
|
|
194
|
+
state.requireActive();
|
|
195
|
+
await repos.tickets.updateStatus(state.db, params.ticketId, 'blocked');
|
|
196
|
+
await repos.runs.markFailure(state.db, params.runId, params.reason);
|
|
197
|
+
state.run.failTicket(params.reason);
|
|
198
|
+
return {
|
|
199
|
+
content: [{
|
|
200
|
+
type: 'text',
|
|
201
|
+
text: JSON.stringify({
|
|
202
|
+
ticketId: params.ticketId,
|
|
203
|
+
status: 'blocked',
|
|
204
|
+
reason: params.reason,
|
|
205
|
+
message: 'Ticket marked as failed. Use blockspool_next_ticket for the next one.',
|
|
206
|
+
}, null, 2),
|
|
207
|
+
}],
|
|
208
|
+
};
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
function buildExecutionPrompt(ticket) {
|
|
212
|
+
const parts = [
|
|
213
|
+
`# Task: ${ticket.title}`,
|
|
214
|
+
'',
|
|
215
|
+
ticket.description ?? '',
|
|
216
|
+
'',
|
|
217
|
+
'## Constraints',
|
|
218
|
+
'',
|
|
219
|
+
`- Only modify files in: ${ticket.allowedPaths.length > 0 ? ticket.allowedPaths.join(', ') : 'any files'}`,
|
|
220
|
+
'- Make minimal, focused changes',
|
|
221
|
+
'- Do not introduce new dependencies unless necessary',
|
|
222
|
+
'',
|
|
223
|
+
'## Verification',
|
|
224
|
+
'',
|
|
225
|
+
'After making changes, these commands must pass:',
|
|
226
|
+
...ticket.verificationCommands.map(c => `- \`${c}\``),
|
|
227
|
+
'',
|
|
228
|
+
'## Workflow',
|
|
229
|
+
'',
|
|
230
|
+
'1. Read the relevant files',
|
|
231
|
+
'2. Make the changes described above',
|
|
232
|
+
'3. Call blockspool_validate_scope with the list of changed files',
|
|
233
|
+
'4. If valid, call blockspool_complete_ticket',
|
|
234
|
+
'5. If QA fails, fix and retry or call blockspool_fail_ticket',
|
|
235
|
+
];
|
|
236
|
+
return parts.join('\n');
|
|
237
|
+
}
|
|
238
|
+
//# 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
|