@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
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # @blockspool/mcp — MCP Server
2
+
3
+ Stateful MCP server that powers BlockSpool's improvement loop. Exposes tools for session management, scouting, execution, and git operations.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # As stdio MCP server (for Claude Code plugin)
9
+ npx @blockspool/mcp
10
+
11
+ # Or via the DirectClient API (for any LLM)
12
+ import { DirectClient } from '@blockspool/mcp/direct-client';
13
+
14
+ const client = await DirectClient.create({ projectPath: '.' });
15
+ client.startSession({ scope: 'src/**', formula: 'security-audit' });
16
+
17
+ while (true) {
18
+ const resp = await client.advance();
19
+ if (resp.next_action === 'STOP') break;
20
+ // ... call your LLM with resp.prompt ...
21
+ await client.ingestEvent('SCOUT_OUTPUT', { proposals: [...] });
22
+ }
23
+
24
+ client.endSession();
25
+ await client.close();
26
+ ```
27
+
28
+ ## MCP Tool Reference
29
+
30
+ ### Session Management
31
+
32
+ | Tool | Description | Parameters |
33
+ |------|-------------|------------|
34
+ | `blockspool_start_session` | Initialize a session | `hours?`, `formula?`, `deep?`, `scope?`, `categories?`, `min_confidence?`, `max_prs?`, `step_budget?`, `ticket_step_budget?`, `draft_prs?` |
35
+ | `blockspool_advance` | Get next action (main loop driver) | — |
36
+ | `blockspool_ingest_event` | Report event, trigger state transitions | `type`, `payload` |
37
+ | `blockspool_session_status` | Current session state | — |
38
+ | `blockspool_end_session` | Finalize session | — |
39
+ | `blockspool_nudge` | Add hint for next scout cycle | `hint` |
40
+ | `blockspool_list_formulas` | List available formulas | — |
41
+ | `blockspool_get_scope_policy` | Get scope policy for current ticket | `file_path?` |
42
+
43
+ ### Scouting
44
+
45
+ | Tool | Description | Parameters |
46
+ |------|-------------|------------|
47
+ | `blockspool_scout_files` | Get scout prompt + file batch | `batchIndex?` |
48
+ | `blockspool_submit_proposals` | Submit proposals from scouting | `proposals[]` |
49
+
50
+ ### Execution
51
+
52
+ | Tool | Description | Parameters |
53
+ |------|-------------|------------|
54
+ | `blockspool_next_ticket` | Get next ticket to work on | — |
55
+ | `blockspool_validate_scope` | Check changed files against scope | `ticketId`, `changedFiles[]` |
56
+ | `blockspool_complete_ticket` | Mark ticket done, run QA | `ticketId`, `runId`, `summary?` |
57
+ | `blockspool_fail_ticket` | Mark ticket failed | `ticketId`, `runId`, `reason` |
58
+
59
+ ### Git
60
+
61
+ | Tool | Description | Parameters |
62
+ |------|-------------|------------|
63
+ | `blockspool_git_setup` | Create/checkout branch for ticket | `ticketId`, `baseBranch?` |
64
+
65
+ ## Canonical Loop Protocol
66
+
67
+ The core protocol is adapter-agnostic. Any client repeats:
68
+
69
+ ```
70
+ advance() → get prompt + constraints
71
+ → execute prompt (any LLM)
72
+ → ingest_event(type, payload)
73
+ → repeat until STOP
74
+ ```
75
+
76
+ ### Event Types
77
+
78
+ | Event | When | Payload |
79
+ |-------|------|---------|
80
+ | `SCOUT_OUTPUT` | After scouting | `{ proposals: [...] }` |
81
+ | `PLAN_SUBMITTED` | After planning | `{ ticket_id, files_to_touch, estimated_lines, risk_level }` |
82
+ | `TICKET_RESULT` | After execution | `{ status, changed_files, lines_added, lines_removed }` |
83
+ | `QA_COMMAND_RESULT` | Per QA command | `{ command, success, output }` |
84
+ | `QA_PASSED` | All QA passes | `{ summary }` |
85
+ | `QA_FAILED` | QA fails | `{ error }` |
86
+ | `PR_CREATED` | PR created | `{ url, branch }` |
87
+ | `USER_OVERRIDE` | Hint or cancel | `{ hint }` or `{ cancel: true }` |
88
+
89
+ ### Phase State Machine
90
+
91
+ ```
92
+ SCOUT → NEXT_TICKET → PLAN → EXECUTE → QA → PR → NEXT_TICKET → DONE
93
+
94
+ Terminal states: DONE, BLOCKED_NEEDS_HUMAN, FAILED_BUDGET, FAILED_VALIDATION, FAILED_SPINDLE
95
+ ```
96
+
97
+ ## Formulas
98
+
99
+ Built-in formulas customize scout behavior:
100
+
101
+ | Formula | Description | Categories | Confidence |
102
+ |---------|-------------|------------|------------|
103
+ | `security-audit` | OWASP vulnerabilities | security | 80 |
104
+ | `test-coverage` | Missing unit tests | test | 70 |
105
+ | `type-safety` | Remove any/unknown | types | 75 |
106
+ | `cleanup` | Dead code, unused imports | refactor | 85 |
107
+ | `deep` | Architecture review | refactor, perf, security | 60 |
108
+ | `docs` | Missing JSDoc | docs | 70 |
109
+
110
+ ### Custom Formulas
111
+
112
+ Create `.blockspool/formulas/<name>.yaml`:
113
+
114
+ ```yaml
115
+ description: Find and fix error handling issues
116
+ categories: [refactor, security]
117
+ min_confidence: 75
118
+ risk_tolerance: medium
119
+ prompt: |
120
+ Find functions with missing error handling.
121
+ Look for uncaught promises, empty catch blocks,
122
+ and functions that silently swallow errors.
123
+ tags: [quality]
124
+ ```
125
+
126
+ ## Run Folder Anatomy
127
+
128
+ Each session creates a run folder at `.blockspool/runs/<run_id>/`:
129
+
130
+ ```
131
+ .blockspool/runs/run_abc123/
132
+ ├── state.json # Current RunState (overwritten each step)
133
+ ├── events.ndjson # Append-only event log (one JSON per line)
134
+ ├── diffs/ # Patch files per step
135
+ │ └── 5-tkt_xyz.patch
136
+ └── artifacts/ # QA logs, scout proposals, etc.
137
+ ├── 1-scout-proposals.json
138
+ ├── 3-ticket-result.json
139
+ ├── 4-qa-npm-test-pass.log
140
+ └── 5-pr-created.json
141
+ ```
142
+
143
+ ### Debugging a Failed Run
144
+
145
+ 1. **Check phase**: `cat .blockspool/runs/<id>/state.json | jq .phase`
146
+ 2. **Read events**: `cat .blockspool/runs/<id>/events.ndjson | jq .`
147
+ 3. **Find the failure**: `grep FAILED .blockspool/runs/<id>/events.ndjson`
148
+ 4. **Check spindle**: `cat .blockspool/runs/<id>/state.json | jq .spindle`
149
+ 5. **Read QA logs**: `cat .blockspool/runs/<id>/artifacts/*qa*`
150
+
151
+ ### state.json Fields
152
+
153
+ | Field | Description |
154
+ |-------|-------------|
155
+ | `phase` | Current state machine phase |
156
+ | `step_count` / `step_budget` | Progress tracking |
157
+ | `tickets_completed` / `tickets_failed` | Work summary |
158
+ | `spindle` | Loop detection state (output_hashes, diff_hashes, iterations_since_change) |
159
+ | `current_ticket_id` | Active ticket being worked on |
160
+ | `plan_approved` | Whether commit plan was approved |
161
+ | `hints` | Pending hints from nudge |
162
+
163
+ ## Architecture
164
+
165
+ ```
166
+ Claude Code / Any LLM
167
+ └─ MCP: @blockspool/mcp (stdio)
168
+ ├─ advance() — deterministic state machine
169
+ ├─ processEvent() — event-driven transitions
170
+ ├─ checkSpindle() — loop detection
171
+ ├─ deriveScopePolicy()— scope enforcement
172
+ ├─ loadFormula() — formula system
173
+ └─ SQLite state — tickets, runs, proposals
174
+ ```
@@ -0,0 +1,30 @@
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 type { DatabaseAdapter } from '@blockspool/core';
17
+ import type { Project } from '@blockspool/core';
18
+ import { RunManager } from './run-manager.js';
19
+ import type { AdvanceResponse } from './types.js';
20
+ export interface AdvanceContext {
21
+ run: RunManager;
22
+ db: DatabaseAdapter;
23
+ project: Project;
24
+ }
25
+ /**
26
+ * Core advance function. Called once per loop iteration.
27
+ * Returns the next action for the client to perform.
28
+ */
29
+ export declare function advance(ctx: AdvanceContext): Promise<AdvanceResponse>;
30
+ //# sourceMappingURL=advance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advance.d.ts","sourceRoot":"","sources":["../src/advance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,YAAY,CAAC;AAUpB,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,UAAU,CAAC;IAChB,EAAE,EAAE,eAAe,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CA6F3E"}