@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.
Files changed (66) hide show
  1. package/README.md +174 -0
  2. package/dist/advance.d.ts +30 -0
  3. package/dist/advance.d.ts.map +1 -0
  4. package/dist/advance.js +514 -0
  5. package/dist/advance.js.map +1 -0
  6. package/dist/direct-client.d.ts +57 -0
  7. package/dist/direct-client.d.ts.map +1 -0
  8. package/dist/direct-client.js +92 -0
  9. package/dist/direct-client.js.map +1 -0
  10. package/dist/event-processor.d.ts +17 -0
  11. package/dist/event-processor.d.ts.map +1 -0
  12. package/dist/event-processor.js +360 -0
  13. package/dist/event-processor.js.map +1 -0
  14. package/dist/formulas.d.ts +37 -0
  15. package/dist/formulas.d.ts.map +1 -0
  16. package/dist/formulas.js +245 -0
  17. package/dist/formulas.js.map +1 -0
  18. package/dist/index.d.ts +9 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +42 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/proposals.d.ts +51 -0
  23. package/dist/proposals.d.ts.map +1 -0
  24. package/dist/proposals.js +207 -0
  25. package/dist/proposals.js.map +1 -0
  26. package/dist/run-manager.d.ts +69 -0
  27. package/dist/run-manager.d.ts.map +1 -0
  28. package/dist/run-manager.js +315 -0
  29. package/dist/run-manager.js.map +1 -0
  30. package/dist/scope-policy.d.ts +34 -0
  31. package/dist/scope-policy.d.ts.map +1 -0
  32. package/dist/scope-policy.js +145 -0
  33. package/dist/scope-policy.js.map +1 -0
  34. package/dist/server.d.ts +16 -0
  35. package/dist/server.d.ts.map +1 -0
  36. package/dist/server.js +31 -0
  37. package/dist/server.js.map +1 -0
  38. package/dist/spindle.d.ts +41 -0
  39. package/dist/spindle.d.ts.map +1 -0
  40. package/dist/spindle.js +279 -0
  41. package/dist/spindle.js.map +1 -0
  42. package/dist/state.d.ts +36 -0
  43. package/dist/state.d.ts.map +1 -0
  44. package/dist/state.js +50 -0
  45. package/dist/state.js.map +1 -0
  46. package/dist/tools/execute.d.ts +7 -0
  47. package/dist/tools/execute.d.ts.map +1 -0
  48. package/dist/tools/execute.js +238 -0
  49. package/dist/tools/execute.js.map +1 -0
  50. package/dist/tools/git.d.ts +7 -0
  51. package/dist/tools/git.d.ts.map +1 -0
  52. package/dist/tools/git.js +67 -0
  53. package/dist/tools/git.js.map +1 -0
  54. package/dist/tools/scout.d.ts +7 -0
  55. package/dist/tools/scout.d.ts.map +1 -0
  56. package/dist/tools/scout.js +199 -0
  57. package/dist/tools/scout.js.map +1 -0
  58. package/dist/tools/session.d.ts +7 -0
  59. package/dist/tools/session.d.ts.map +1 -0
  60. package/dist/tools/session.js +296 -0
  61. package/dist/tools/session.js.map +1 -0
  62. package/dist/types.d.ts +116 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +13 -0
  65. package/dist/types.js.map +1 -0
  66. package/package.json +63 -0
@@ -0,0 +1,514 @@
1
+ /**
2
+ * Advance Engine — the deterministic state machine.
3
+ *
4
+ * `advance()` is called by the client on every loop iteration.
5
+ * It returns what to do next (prompt + constraints) or STOP.
6
+ *
7
+ * State machine transitions (from docs/PLUGIN_ROADMAP.md):
8
+ *
9
+ * SCOUT → NEXT_TICKET | DONE | FAILED_BUDGET
10
+ * NEXT_TICKET → PLAN | SCOUT | DONE
11
+ * PLAN → EXECUTE | PLAN | BLOCKED_NEEDS_HUMAN | FAILED_BUDGET
12
+ * EXECUTE → QA | NEXT_TICKET | BLOCKED_NEEDS_HUMAN | FAILED_BUDGET | FAILED_SPINDLE
13
+ * QA → PR | EXECUTE | NEXT_TICKET | FAILED_BUDGET
14
+ * PR → NEXT_TICKET | FAILED_VALIDATION
15
+ */
16
+ import { repos } from '@blockspool/core';
17
+ import { TERMINAL_PHASES } from './types.js';
18
+ import { deriveScopePolicy } from './scope-policy.js';
19
+ import { checkSpindle, getFileEditWarnings } from './spindle.js';
20
+ import { loadFormula } from './formulas.js';
21
+ const MAX_PLAN_REJECTIONS = 3;
22
+ const MAX_QA_RETRIES = 3;
23
+ /**
24
+ * Core advance function. Called once per loop iteration.
25
+ * Returns the next action for the client to perform.
26
+ */
27
+ export async function advance(ctx) {
28
+ const { run, db, project } = ctx;
29
+ const s = run.require();
30
+ // Increment step
31
+ run.incrementStep();
32
+ run.appendEvent('ADVANCE_CALLED', { phase: s.phase, step: s.step_count });
33
+ // -----------------------------------------------------------------------
34
+ // Budget checks (run before any phase logic)
35
+ // -----------------------------------------------------------------------
36
+ const budgetResult = checkBudgets(run);
37
+ if (budgetResult) {
38
+ return budgetResult;
39
+ }
40
+ // -----------------------------------------------------------------------
41
+ // Fire budget warnings at 80%
42
+ // -----------------------------------------------------------------------
43
+ const warnings = run.getBudgetWarnings();
44
+ if (warnings.length > 0) {
45
+ run.appendEvent('BUDGET_WARNING', { warnings });
46
+ }
47
+ // -----------------------------------------------------------------------
48
+ // Spindle check (only in EXECUTE/QA — active work phases)
49
+ // -----------------------------------------------------------------------
50
+ if (s.phase === 'EXECUTE' || s.phase === 'QA') {
51
+ const spindleResult = checkSpindle(s.spindle);
52
+ // File edit frequency warnings
53
+ const fileWarnings = getFileEditWarnings(s.spindle);
54
+ if (fileWarnings.length > 0) {
55
+ run.appendEvent('SPINDLE_WARNING', { file_edit_warnings: fileWarnings });
56
+ }
57
+ if (spindleResult.shouldAbort) {
58
+ run.appendEvent('SPINDLE_ABORT', {
59
+ reason: spindleResult.reason,
60
+ confidence: spindleResult.confidence,
61
+ diagnostics: spindleResult.diagnostics,
62
+ });
63
+ if (s.current_ticket_id) {
64
+ await repos.tickets.updateStatus(db, s.current_ticket_id, 'blocked');
65
+ run.failTicket(`Spindle abort: ${spindleResult.reason}`);
66
+ }
67
+ run.setPhase('FAILED_SPINDLE');
68
+ return stopResponse(run, 'FAILED_SPINDLE', `Spindle loop detected: ${spindleResult.reason} (confidence: ${(spindleResult.confidence * 100).toFixed(0)}%)`);
69
+ }
70
+ if (spindleResult.shouldBlock) {
71
+ run.appendEvent('SPINDLE_WARNING', {
72
+ reason: spindleResult.reason,
73
+ diagnostics: spindleResult.diagnostics,
74
+ action: 'BLOCKED_NEEDS_HUMAN',
75
+ });
76
+ if (s.current_ticket_id) {
77
+ await repos.tickets.updateStatus(db, s.current_ticket_id, 'blocked');
78
+ run.failTicket(`Spindle block: ${spindleResult.reason}`);
79
+ }
80
+ run.setPhase('BLOCKED_NEEDS_HUMAN');
81
+ return stopResponse(run, 'BLOCKED_NEEDS_HUMAN', `Spindle: ${spindleResult.reason}. Needs human intervention.`);
82
+ }
83
+ }
84
+ // -----------------------------------------------------------------------
85
+ // Terminal state check
86
+ // -----------------------------------------------------------------------
87
+ if (TERMINAL_PHASES.has(s.phase)) {
88
+ return stopResponse(run, s.phase, terminalReason(s.phase));
89
+ }
90
+ // -----------------------------------------------------------------------
91
+ // Phase dispatch
92
+ // -----------------------------------------------------------------------
93
+ switch (s.phase) {
94
+ case 'SCOUT':
95
+ return advanceScout(ctx);
96
+ case 'NEXT_TICKET':
97
+ return advanceNextTicket(ctx);
98
+ case 'PLAN':
99
+ return advancePlan(ctx);
100
+ case 'EXECUTE':
101
+ return advanceExecute(ctx);
102
+ case 'QA':
103
+ return advanceQa(ctx);
104
+ case 'PR':
105
+ return advancePr(ctx);
106
+ default:
107
+ return stopResponse(run, 'FAILED_VALIDATION', `Unknown phase: ${s.phase}`);
108
+ }
109
+ }
110
+ // ---------------------------------------------------------------------------
111
+ // Phase handlers
112
+ // ---------------------------------------------------------------------------
113
+ async function advanceScout(ctx) {
114
+ const { run, db } = ctx;
115
+ const s = run.require();
116
+ // Check if we already have ready tickets in backlog
117
+ const readyTickets = await repos.tickets.listByProject(db, s.project_id, { status: 'ready', limit: 1 });
118
+ if (readyTickets.length > 0) {
119
+ // Tickets exist, move to assignment
120
+ run.setPhase('NEXT_TICKET');
121
+ return advance(ctx);
122
+ }
123
+ // No ready tickets — return scout prompt for client to execute
124
+ const recentTickets = await repos.tickets.getRecentlyCompleted(db, s.project_id, 20);
125
+ const dedupContext = recentTickets.map(t => t.title);
126
+ const hints = run.consumeHints();
127
+ // Load formula if specified
128
+ const formula = s.formula ? loadFormula(s.formula, ctx.project.rootPath) : null;
129
+ const prompt = buildScoutPrompt(s.scope, s.categories, s.min_confidence, s.max_proposals_per_scout, dedupContext, formula, hints);
130
+ s.scout_cycles++;
131
+ run.appendEvent('ADVANCE_RETURNED', { phase: 'SCOUT', has_prompt: true });
132
+ return promptResponse(run, 'SCOUT', prompt, 'Scouting for improvements', {
133
+ allowed_paths: [s.scope],
134
+ denied_paths: [],
135
+ denied_patterns: [],
136
+ max_files: 100,
137
+ max_lines: 0,
138
+ required_commands: [],
139
+ plan_required: false,
140
+ });
141
+ }
142
+ async function advanceNextTicket(ctx) {
143
+ const { run, db } = ctx;
144
+ const s = run.require();
145
+ // Check if we've hit PR limit
146
+ if (s.prs_created >= s.max_prs) {
147
+ run.setPhase('DONE');
148
+ return stopResponse(run, 'DONE', `PR limit reached (${s.prs_created}/${s.max_prs})`);
149
+ }
150
+ // Find next ready ticket
151
+ const readyTickets = await repos.tickets.listByProject(db, s.project_id, { status: 'ready', limit: 1 });
152
+ if (readyTickets.length === 0) {
153
+ // No more tickets — scout again if cycles remain, otherwise finish
154
+ if (s.scout_cycles < s.max_cycles) {
155
+ run.setPhase('SCOUT');
156
+ return advance(ctx);
157
+ }
158
+ run.setPhase('DONE');
159
+ return stopResponse(run, 'DONE', 'No more tickets to process');
160
+ }
161
+ const ticket = readyTickets[0];
162
+ // Assign ticket
163
+ await repos.tickets.updateStatus(db, ticket.id, 'in_progress');
164
+ run.assignTicket(ticket.id);
165
+ // Create worker run record
166
+ await repos.runs.create(db, {
167
+ projectId: s.project_id,
168
+ type: 'worker',
169
+ ticketId: ticket.id,
170
+ });
171
+ // Derive scope policy for this ticket
172
+ const policy = deriveScopePolicy({
173
+ allowedPaths: ticket.allowedPaths ?? [],
174
+ category: ticket.category ?? 'refactor',
175
+ maxLinesPerTicket: s.max_lines_per_ticket,
176
+ });
177
+ const constraints = {
178
+ allowed_paths: policy.allowed_paths,
179
+ denied_paths: policy.denied_paths,
180
+ denied_patterns: policy.denied_patterns.map(r => r.source),
181
+ max_files: policy.max_files,
182
+ max_lines: policy.max_lines,
183
+ required_commands: ticket.verificationCommands ?? [],
184
+ plan_required: policy.plan_required,
185
+ };
186
+ // Docs category: skip plan, go straight to execute
187
+ if (!policy.plan_required) {
188
+ s.plan_approved = true;
189
+ run.setPhase('EXECUTE');
190
+ return advanceExecute(ctx);
191
+ }
192
+ // Move to PLAN phase — require commit plan before execution
193
+ run.setPhase('PLAN');
194
+ const prompt = buildPlanPrompt(ticket);
195
+ return promptResponse(run, 'PLAN', prompt, `Planning ticket: ${ticket.title}`, constraints);
196
+ }
197
+ async function advancePlan(ctx) {
198
+ const { run, db } = ctx;
199
+ const s = run.require();
200
+ // If plan is already approved, move to execute
201
+ if (s.plan_approved) {
202
+ run.setPhase('EXECUTE');
203
+ return advanceExecute(ctx);
204
+ }
205
+ // If too many rejections, block the ticket
206
+ if (s.plan_rejections >= MAX_PLAN_REJECTIONS) {
207
+ run.appendEvent('TICKET_FAILED', {
208
+ ticket_id: s.current_ticket_id,
209
+ reason: 'Plan rejected too many times',
210
+ });
211
+ if (s.current_ticket_id) {
212
+ await repos.tickets.updateStatus(db, s.current_ticket_id, 'blocked');
213
+ }
214
+ s.tickets_blocked++;
215
+ s.current_ticket_id = null;
216
+ s.current_ticket_plan = null;
217
+ run.setPhase('BLOCKED_NEEDS_HUMAN');
218
+ return stopResponse(run, 'BLOCKED_NEEDS_HUMAN', `Commit plan rejected ${MAX_PLAN_REJECTIONS} times. Needs human review.`);
219
+ }
220
+ // Request a commit plan from the client
221
+ const ticket = s.current_ticket_id
222
+ ? await repos.tickets.getById(db, s.current_ticket_id)
223
+ : null;
224
+ if (!ticket) {
225
+ run.setPhase('NEXT_TICKET');
226
+ return advance(ctx);
227
+ }
228
+ const policy = deriveScopePolicy({
229
+ allowedPaths: ticket.allowedPaths ?? [],
230
+ category: ticket.category ?? 'refactor',
231
+ maxLinesPerTicket: s.max_lines_per_ticket,
232
+ });
233
+ const prompt = s.plan_rejections > 0
234
+ ? `Your previous commit plan was rejected. Please revise.\n\n${buildPlanPrompt(ticket)}`
235
+ : buildPlanPrompt(ticket);
236
+ return promptResponse(run, 'PLAN', prompt, s.plan_rejections > 0
237
+ ? `Re-planning (attempt ${s.plan_rejections + 1}/${MAX_PLAN_REJECTIONS})`
238
+ : `Awaiting commit plan for: ${ticket.title}`, {
239
+ allowed_paths: policy.allowed_paths,
240
+ denied_paths: policy.denied_paths,
241
+ denied_patterns: policy.denied_patterns.map(r => r.source),
242
+ max_files: policy.max_files,
243
+ max_lines: policy.max_lines,
244
+ required_commands: ticket.verificationCommands ?? [],
245
+ plan_required: policy.plan_required,
246
+ });
247
+ }
248
+ async function advanceExecute(ctx) {
249
+ const { run, db } = ctx;
250
+ const s = run.require();
251
+ // Check ticket step budget
252
+ if (s.ticket_step_count >= s.ticket_step_budget) {
253
+ if (s.current_ticket_id) {
254
+ await repos.tickets.updateStatus(db, s.current_ticket_id, 'blocked');
255
+ run.failTicket('Ticket step budget exhausted');
256
+ }
257
+ run.setPhase('BLOCKED_NEEDS_HUMAN');
258
+ return stopResponse(run, 'BLOCKED_NEEDS_HUMAN', `Ticket step budget exhausted (${s.ticket_step_count}/${s.ticket_step_budget})`);
259
+ }
260
+ const ticket = s.current_ticket_id
261
+ ? await repos.tickets.getById(db, s.current_ticket_id)
262
+ : null;
263
+ if (!ticket) {
264
+ run.setPhase('NEXT_TICKET');
265
+ return advance(ctx);
266
+ }
267
+ const policy = deriveScopePolicy({
268
+ allowedPaths: ticket.allowedPaths ?? [],
269
+ category: ticket.category ?? 'refactor',
270
+ maxLinesPerTicket: s.max_lines_per_ticket,
271
+ });
272
+ const prompt = buildExecutePrompt(ticket, s.current_ticket_plan);
273
+ return promptResponse(run, 'EXECUTE', prompt, `Executing ticket: ${ticket.title}`, {
274
+ allowed_paths: policy.allowed_paths,
275
+ denied_paths: policy.denied_paths,
276
+ denied_patterns: policy.denied_patterns.map(r => r.source),
277
+ max_files: policy.max_files,
278
+ max_lines: policy.max_lines,
279
+ required_commands: ticket.verificationCommands ?? [],
280
+ plan_required: false,
281
+ });
282
+ }
283
+ async function advanceQa(ctx) {
284
+ const { run, db } = ctx;
285
+ const s = run.require();
286
+ // If QA retries exceeded, give up on this ticket
287
+ if (s.qa_retries >= MAX_QA_RETRIES) {
288
+ if (s.current_ticket_id) {
289
+ await repos.tickets.updateStatus(db, s.current_ticket_id, 'blocked');
290
+ run.failTicket(`QA failed ${MAX_QA_RETRIES} times`);
291
+ }
292
+ run.setPhase('NEXT_TICKET');
293
+ return advance(ctx);
294
+ }
295
+ const ticket = s.current_ticket_id
296
+ ? await repos.tickets.getById(db, s.current_ticket_id)
297
+ : null;
298
+ if (!ticket) {
299
+ run.setPhase('NEXT_TICKET');
300
+ return advance(ctx);
301
+ }
302
+ const prompt = buildQaPrompt(ticket);
303
+ return promptResponse(run, 'QA', prompt, `Running QA for: ${ticket.title} (attempt ${s.qa_retries + 1}/${MAX_QA_RETRIES})`, {
304
+ allowed_paths: ticket.allowedPaths ?? [],
305
+ denied_paths: [],
306
+ denied_patterns: [],
307
+ max_files: 0,
308
+ max_lines: 0,
309
+ required_commands: ticket.verificationCommands ?? [],
310
+ plan_required: false,
311
+ });
312
+ }
313
+ async function advancePr(ctx) {
314
+ const { run } = ctx;
315
+ const s = run.require();
316
+ const ticket = s.current_ticket_id
317
+ ? await repos.tickets.getById(ctx.db, s.current_ticket_id)
318
+ : null;
319
+ const prompt = buildPrPrompt(ticket, s.draft_prs);
320
+ return promptResponse(run, 'PR', prompt, 'Creating PR', {
321
+ allowed_paths: [],
322
+ denied_paths: [],
323
+ denied_patterns: [],
324
+ max_files: 0,
325
+ max_lines: 0,
326
+ required_commands: [],
327
+ plan_required: false,
328
+ });
329
+ }
330
+ // ---------------------------------------------------------------------------
331
+ // Budget checks
332
+ // ---------------------------------------------------------------------------
333
+ function checkBudgets(run) {
334
+ const s = run.require();
335
+ if (s.step_count >= s.step_budget) {
336
+ run.appendEvent('BUDGET_EXHAUSTED', { which: 'step_budget', value: s.step_count });
337
+ run.setPhase('FAILED_BUDGET');
338
+ return stopResponse(run, 'FAILED_BUDGET', `Step budget exhausted (${s.step_count}/${s.step_budget})`);
339
+ }
340
+ if (s.expires_at && new Date() >= new Date(s.expires_at)) {
341
+ run.appendEvent('BUDGET_EXHAUSTED', { which: 'time_budget' });
342
+ run.setPhase('FAILED_BUDGET');
343
+ return stopResponse(run, 'FAILED_BUDGET', 'Time budget exhausted');
344
+ }
345
+ return null;
346
+ }
347
+ // ---------------------------------------------------------------------------
348
+ // Response builders
349
+ // ---------------------------------------------------------------------------
350
+ function stopResponse(run, phase, reason) {
351
+ return {
352
+ next_action: 'STOP',
353
+ phase,
354
+ prompt: null,
355
+ reason,
356
+ constraints: emptyConstraints(),
357
+ digest: run.buildDigest(),
358
+ };
359
+ }
360
+ function promptResponse(run, phase, prompt, reason, constraints) {
361
+ return {
362
+ next_action: 'PROMPT',
363
+ phase,
364
+ prompt,
365
+ reason,
366
+ constraints,
367
+ digest: run.buildDigest(),
368
+ };
369
+ }
370
+ function emptyConstraints() {
371
+ return {
372
+ allowed_paths: [],
373
+ denied_paths: [],
374
+ denied_patterns: [],
375
+ max_files: 0,
376
+ max_lines: 0,
377
+ required_commands: [],
378
+ plan_required: false,
379
+ };
380
+ }
381
+ function terminalReason(phase) {
382
+ switch (phase) {
383
+ case 'DONE': return 'Session completed successfully';
384
+ case 'BLOCKED_NEEDS_HUMAN': return 'Ticket blocked, needs human review';
385
+ case 'FAILED_BUDGET': return 'Budget exhausted';
386
+ case 'FAILED_VALIDATION': return 'Validation failed';
387
+ case 'FAILED_SPINDLE': return 'Loop detected by spindle';
388
+ default: return 'Terminal state';
389
+ }
390
+ }
391
+ // ---------------------------------------------------------------------------
392
+ // Prompt builders
393
+ // ---------------------------------------------------------------------------
394
+ function buildScoutPrompt(scope, categories, minConfidence, maxProposals, dedupContext, formula, hints) {
395
+ const parts = [
396
+ '# Scout Phase',
397
+ '',
398
+ 'Scan the codebase and identify improvements. Return proposals in a `<proposals>` XML block containing a JSON array.',
399
+ '',
400
+ `**Scope:** \`${scope}\``,
401
+ `**Categories:** ${categories.join(', ')}`,
402
+ `**Min confidence:** ${minConfidence}`,
403
+ `**Max proposals:** ${maxProposals}`,
404
+ '',
405
+ ];
406
+ if (dedupContext.length > 0) {
407
+ parts.push('**Already completed (do not duplicate):**');
408
+ for (const title of dedupContext) {
409
+ parts.push(`- ${title}`);
410
+ }
411
+ parts.push('');
412
+ }
413
+ if (formula) {
414
+ parts.push(`**Formula:** ${formula.name} — ${formula.description}`);
415
+ if (formula.prompt) {
416
+ parts.push('');
417
+ parts.push('**Formula instructions:**');
418
+ parts.push(formula.prompt);
419
+ }
420
+ if (formula.risk_tolerance) {
421
+ parts.push(`**Risk tolerance:** ${formula.risk_tolerance}`);
422
+ }
423
+ parts.push('');
424
+ }
425
+ if (hints.length > 0) {
426
+ parts.push('**Hints from user:**');
427
+ for (const hint of hints) {
428
+ parts.push(`- ${hint}`);
429
+ }
430
+ parts.push('');
431
+ }
432
+ parts.push('## Required Fields', '', 'Each proposal in the JSON array MUST include ALL of these fields:', '- `category` (string): one of the categories listed above', '- `title` (string): concise, unique title', '- `description` (string): what needs to change and why', '- `acceptance_criteria` (string[]): how to verify the change is correct', '- `verification_commands` (string[]): commands to run (e.g. `npm test`)', '- `allowed_paths` (string[]): file paths/globs this change may touch', '- `files` (string[]): specific files to modify', '- `confidence` (number 0-100): how confident you are this is correct', '- `impact_score` (number 1-10): how much this matters', '- `risk` (string): "low", "medium", or "high"', '- `touched_files_estimate` (number): expected number of files changed', '- `rollback_note` (string): how to revert if something goes wrong', '', '## Scoring', '', 'Proposals are ranked by `impact_score × confidence`. Prefer low-risk proposals.', '', '## Output', '', 'Wrap the JSON array in a `<proposals>` XML block:', '```', '<proposals>', '[{ ... }, { ... }]', '</proposals>', '```', '', 'Then call `blockspool_ingest_event` with type `SCOUT_OUTPUT` and `{ "proposals": [...] }` as payload.');
433
+ return parts.join('\n');
434
+ }
435
+ function buildPlanPrompt(ticket) {
436
+ return [
437
+ '# Commit Plan Required',
438
+ '',
439
+ `**Ticket:** ${ticket.title}`,
440
+ '',
441
+ ticket.description ?? '',
442
+ '',
443
+ 'Before making changes, output a `<commit-plan>` XML block with:',
444
+ '```json',
445
+ '{',
446
+ ` "ticket_id": "<ticket-id>",`,
447
+ ' "files": [{"path": "...", "action": "create|modify|delete", "reason": "..."}],',
448
+ ' "expected_tests": ["npm test -- --grep ..."],',
449
+ ' "estimated_lines": <number>,',
450
+ ' "risk_level": "low|medium|high"',
451
+ '}',
452
+ '```',
453
+ '',
454
+ `**Allowed paths:** ${ticket.allowedPaths.length > 0 ? ticket.allowedPaths.join(', ') : 'any'}`,
455
+ `**Verification commands:** ${ticket.verificationCommands.join(', ') || 'none specified'}`,
456
+ '',
457
+ 'Then call `blockspool_ingest_event` with type `PLAN_SUBMITTED` and the plan as payload.',
458
+ ].join('\n');
459
+ }
460
+ function buildExecutePrompt(ticket, plan) {
461
+ const parts = [
462
+ `# Execute: ${ticket.title}`,
463
+ '',
464
+ ticket.description ?? '',
465
+ '',
466
+ ];
467
+ if (plan) {
468
+ parts.push('## Approved Commit Plan');
469
+ parts.push('```json');
470
+ parts.push(JSON.stringify(plan, null, 2));
471
+ parts.push('```');
472
+ parts.push('');
473
+ parts.push('Follow the plan above. Only touch the files listed.');
474
+ parts.push('');
475
+ }
476
+ parts.push('## Constraints', `- Only modify files in: ${ticket.allowedPaths.length > 0 ? ticket.allowedPaths.join(', ') : 'any'}`, '- Make minimal, focused changes', '', '## When done', 'Output a `<ticket-result>` block with status, changed_files, summary, lines_added, lines_removed.', 'Then call `blockspool_ingest_event` with type `TICKET_RESULT` and the result as payload.');
477
+ return parts.join('\n');
478
+ }
479
+ function buildQaPrompt(ticket) {
480
+ return [
481
+ `# QA: ${ticket.title}`,
482
+ '',
483
+ 'Run the following verification commands and report results:',
484
+ '',
485
+ ...ticket.verificationCommands.map(c => `\`\`\`bash\n${c}\n\`\`\``),
486
+ '',
487
+ 'For each command, call `blockspool_ingest_event` with type `QA_COMMAND_RESULT` and:',
488
+ '`{ "command": "...", "success": true/false, "output": "stdout+stderr" }`',
489
+ '',
490
+ 'After all commands, call `blockspool_ingest_event` with type `QA_PASSED` if all pass, or `QA_FAILED` with failure details.',
491
+ ].join('\n');
492
+ }
493
+ function buildPrPrompt(ticket, draftPr) {
494
+ const title = ticket?.title ?? 'BlockSpool changes';
495
+ return [
496
+ '# Create PR',
497
+ '',
498
+ `Create a ${draftPr ? 'draft ' : ''}pull request for the changes.`,
499
+ '',
500
+ `**Title:** ${title}`,
501
+ ticket?.description ? `**Description:** ${ticket.description.slice(0, 200)}` : '',
502
+ '',
503
+ '## Dry-run first',
504
+ '',
505
+ '1. Stage changes: `git add <files>`',
506
+ '2. Create commit: `git commit -m "..."`',
507
+ '3. Verify the commit looks correct: `git diff HEAD~1 --stat`',
508
+ '4. Push to remote: `git push -u origin <branch>`',
509
+ `5. Create ${draftPr ? 'draft ' : ''}PR: \`gh pr create${draftPr ? ' --draft' : ''}\``,
510
+ '',
511
+ 'Call `blockspool_ingest_event` with type `PR_CREATED` and `{ "url": "<pr-url>", "branch": "<branch-name>" }` as payload.',
512
+ ].join('\n');
513
+ }
514
+ //# sourceMappingURL=advance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advance.js","sourceRoot":"","sources":["../src/advance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Direct Client — programmatic adapter for the BlockSpool canonical loop.
3
+ *
4
+ * Proves the MCP tools work without Claude Code or stdio transport.
5
+ * Any LLM (or test harness) can drive the loop:
6
+ *
7
+ * const client = await DirectClient.create({ projectPath });
8
+ * const session = client.startSession({ scope: 'src/**' });
9
+ * while (true) {
10
+ * const resp = await client.advance();
11
+ * if (resp.next_action === 'STOP') break;
12
+ * // ... call LLM with resp.prompt ...
13
+ * await client.ingestEvent(type, payload);
14
+ * }
15
+ * client.endSession();
16
+ * await client.close();
17
+ */
18
+ import type { DatabaseAdapter, Project } from '@blockspool/core';
19
+ import { RunManager } from './run-manager.js';
20
+ import type { AdvanceResponse, EventType, RunState, SessionConfig } from './types.js';
21
+ export interface DirectClientOptions {
22
+ projectPath: string;
23
+ projectName?: string;
24
+ /** Provide an existing DB adapter (for testing). If omitted, creates SQLite at .blockspool/state.sqlite */
25
+ db?: DatabaseAdapter;
26
+ }
27
+ export declare class DirectClient {
28
+ private run;
29
+ private db;
30
+ private project;
31
+ private ownsDb;
32
+ private constructor();
33
+ /**
34
+ * Create a DirectClient. Initializes SQLite and ensures the project exists.
35
+ */
36
+ static create(options: DirectClientOptions): Promise<DirectClient>;
37
+ /** Start a new session. Returns the initial RunState. */
38
+ startSession(config?: SessionConfig): RunState;
39
+ /** Get the next action. This is the core loop driver. */
40
+ advance(): Promise<AdvanceResponse>;
41
+ /** Report an event back. Triggers state transitions. */
42
+ ingestEvent(type: EventType, payload: Record<string, unknown>): Promise<{
43
+ processed: boolean;
44
+ message: string;
45
+ }>;
46
+ /** Get current run state. */
47
+ getState(): RunState;
48
+ /** End the session. */
49
+ endSession(): RunState;
50
+ /** Clean up resources. */
51
+ close(): Promise<void>;
52
+ /** Expose internals for testing */
53
+ get _run(): RunManager;
54
+ get _db(): DatabaseAdapter;
55
+ get _project(): Project;
56
+ }
57
+ //# sourceMappingURL=direct-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"direct-client.d.ts","sourceRoot":"","sources":["../src/direct-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,KAAK,EACV,eAAe,EACf,SAAS,EACT,QAAQ,EACR,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,mBAAmB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2GAA2G;IAC3G,EAAE,CAAC,EAAE,eAAe,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,EAAE,CAAkB;IAC5B,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAU;IAExB,OAAO;IAYP;;OAEG;WACU,MAAM,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC;IAuBxE,yDAAyD;IACzD,YAAY,CAAC,MAAM,GAAE,aAAkB,GAAG,QAAQ;IAIlD,yDAAyD;IACnD,OAAO,IAAI,OAAO,CAAC,eAAe,CAAC;IAIzC,wDAAwD;IAClD,WAAW,CACf,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAAC;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAOnD,6BAA6B;IAC7B,QAAQ,IAAI,QAAQ;IAIpB,uBAAuB;IACvB,UAAU,IAAI,QAAQ;IAItB,0BAA0B;IACpB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAM5B,mCAAmC;IACnC,IAAI,IAAI,IAAI,UAAU,CAAqB;IAC3C,IAAI,GAAG,IAAI,eAAe,CAAoB;IAC9C,IAAI,QAAQ,IAAI,OAAO,CAAyB;CACjD"}