slavedriver 0.1.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 (240) hide show
  1. package/README.md +165 -0
  2. package/agents/executor.md +26 -0
  3. package/agents/planner.md +41 -0
  4. package/agents/researcher.md +28 -0
  5. package/agents/verifier.md +25 -0
  6. package/dist/agents/backends/claude-code.d.ts +2 -0
  7. package/dist/agents/backends/claude-code.js +215 -0
  8. package/dist/agents/backends/claude-code.js.map +1 -0
  9. package/dist/agents/backends/mock.d.ts +9 -0
  10. package/dist/agents/backends/mock.js +31 -0
  11. package/dist/agents/backends/mock.js.map +1 -0
  12. package/dist/agents/context-builder.d.ts +10 -0
  13. package/dist/agents/context-builder.js +61 -0
  14. package/dist/agents/context-builder.js.map +1 -0
  15. package/dist/agents/prompt-compiler.d.ts +27 -0
  16. package/dist/agents/prompt-compiler.js +549 -0
  17. package/dist/agents/prompt-compiler.js.map +1 -0
  18. package/dist/agents/runtime.d.ts +40 -0
  19. package/dist/agents/runtime.js +2 -0
  20. package/dist/agents/runtime.js.map +1 -0
  21. package/dist/cli/arg-parser.d.ts +6 -0
  22. package/dist/cli/arg-parser.js +59 -0
  23. package/dist/cli/arg-parser.js.map +1 -0
  24. package/dist/cli/commands/config.d.ts +9 -0
  25. package/dist/cli/commands/config.js +120 -0
  26. package/dist/cli/commands/config.js.map +1 -0
  27. package/dist/cli/commands/dashboard.d.ts +1 -0
  28. package/dist/cli/commands/dashboard.js +54 -0
  29. package/dist/cli/commands/dashboard.js.map +1 -0
  30. package/dist/cli/commands/find-root.d.ts +14 -0
  31. package/dist/cli/commands/find-root.js +55 -0
  32. package/dist/cli/commands/find-root.js.map +1 -0
  33. package/dist/cli/commands/init.d.ts +1 -0
  34. package/dist/cli/commands/init.js +65 -0
  35. package/dist/cli/commands/init.js.map +1 -0
  36. package/dist/cli/commands/next.d.ts +1 -0
  37. package/dist/cli/commands/next.js +61 -0
  38. package/dist/cli/commands/next.js.map +1 -0
  39. package/dist/cli/commands/plan.d.ts +2 -0
  40. package/dist/cli/commands/plan.js +53 -0
  41. package/dist/cli/commands/plan.js.map +1 -0
  42. package/dist/cli/commands/replan.d.ts +1 -0
  43. package/dist/cli/commands/replan.js +54 -0
  44. package/dist/cli/commands/replan.js.map +1 -0
  45. package/dist/cli/commands/run-pipeline.d.ts +2 -0
  46. package/dist/cli/commands/run-pipeline.js +74 -0
  47. package/dist/cli/commands/run-pipeline.js.map +1 -0
  48. package/dist/cli/commands/run.d.ts +2 -0
  49. package/dist/cli/commands/run.js +106 -0
  50. package/dist/cli/commands/run.js.map +1 -0
  51. package/dist/cli/commands/status.d.ts +1 -0
  52. package/dist/cli/commands/status.js +51 -0
  53. package/dist/cli/commands/status.js.map +1 -0
  54. package/dist/cli/commands/verify.d.ts +1 -0
  55. package/dist/cli/commands/verify.js +63 -0
  56. package/dist/cli/commands/verify.js.map +1 -0
  57. package/dist/cli/commands/wizard.d.ts +8 -0
  58. package/dist/cli/commands/wizard.js +39 -0
  59. package/dist/cli/commands/wizard.js.map +1 -0
  60. package/dist/cli/index.d.ts +2 -0
  61. package/dist/cli/index.js +82 -0
  62. package/dist/cli/index.js.map +1 -0
  63. package/dist/cli/wizard/index.d.ts +11 -0
  64. package/dist/cli/wizard/index.js +40 -0
  65. package/dist/cli/wizard/index.js.map +1 -0
  66. package/dist/cli/wizard/interview.d.ts +26 -0
  67. package/dist/cli/wizard/interview.js +284 -0
  68. package/dist/cli/wizard/interview.js.map +1 -0
  69. package/dist/cli/wizard/prompt.d.ts +18 -0
  70. package/dist/cli/wizard/prompt.js +72 -0
  71. package/dist/cli/wizard/prompt.js.map +1 -0
  72. package/dist/cli/wizard/template-generator.d.ts +8 -0
  73. package/dist/cli/wizard/template-generator.js +133 -0
  74. package/dist/cli/wizard/template-generator.js.map +1 -0
  75. package/dist/mcp/index.d.ts +2 -0
  76. package/dist/mcp/index.js +68 -0
  77. package/dist/mcp/index.js.map +1 -0
  78. package/dist/mcp/protocol.d.ts +33 -0
  79. package/dist/mcp/protocol.js +82 -0
  80. package/dist/mcp/protocol.js.map +1 -0
  81. package/dist/mcp/resources.d.ts +20 -0
  82. package/dist/mcp/resources.js +101 -0
  83. package/dist/mcp/resources.js.map +1 -0
  84. package/dist/mcp/run-manager.d.ts +36 -0
  85. package/dist/mcp/run-manager.js +179 -0
  86. package/dist/mcp/run-manager.js.map +1 -0
  87. package/dist/mcp/server.d.ts +13 -0
  88. package/dist/mcp/server.js +99 -0
  89. package/dist/mcp/server.js.map +1 -0
  90. package/dist/mcp/tools.d.ts +32 -0
  91. package/dist/mcp/tools.js +259 -0
  92. package/dist/mcp/tools.js.map +1 -0
  93. package/dist/orchestrator/alert-types.d.ts +16 -0
  94. package/dist/orchestrator/alert-types.js +2 -0
  95. package/dist/orchestrator/alert-types.js.map +1 -0
  96. package/dist/orchestrator/alerts.d.ts +20 -0
  97. package/dist/orchestrator/alerts.js +76 -0
  98. package/dist/orchestrator/alerts.js.map +1 -0
  99. package/dist/orchestrator/checkpoints.d.ts +8 -0
  100. package/dist/orchestrator/checkpoints.js +24 -0
  101. package/dist/orchestrator/checkpoints.js.map +1 -0
  102. package/dist/orchestrator/engine.d.ts +71 -0
  103. package/dist/orchestrator/engine.js +420 -0
  104. package/dist/orchestrator/engine.js.map +1 -0
  105. package/dist/orchestrator/phase-gates.d.ts +6 -0
  106. package/dist/orchestrator/phase-gates.js +127 -0
  107. package/dist/orchestrator/phase-gates.js.map +1 -0
  108. package/dist/orchestrator/plan-approval.d.ts +10 -0
  109. package/dist/orchestrator/plan-approval.js +51 -0
  110. package/dist/orchestrator/plan-approval.js.map +1 -0
  111. package/dist/orchestrator/safety.d.ts +22 -0
  112. package/dist/orchestrator/safety.js +126 -0
  113. package/dist/orchestrator/safety.js.map +1 -0
  114. package/dist/orchestrator/task-graph.d.ts +17 -0
  115. package/dist/orchestrator/task-graph.js +156 -0
  116. package/dist/orchestrator/task-graph.js.map +1 -0
  117. package/dist/orchestrator/wave-executor.d.ts +37 -0
  118. package/dist/orchestrator/wave-executor.js +237 -0
  119. package/dist/orchestrator/wave-executor.js.map +1 -0
  120. package/dist/session/in-process.d.ts +2 -0
  121. package/dist/session/in-process.js +149 -0
  122. package/dist/session/in-process.js.map +1 -0
  123. package/dist/session/log-capture.d.ts +7 -0
  124. package/dist/session/log-capture.js +56 -0
  125. package/dist/session/log-capture.js.map +1 -0
  126. package/dist/session/manager.d.ts +20 -0
  127. package/dist/session/manager.js +2 -0
  128. package/dist/session/manager.js.map +1 -0
  129. package/dist/state/file-store.d.ts +3 -0
  130. package/dist/state/file-store.js +124 -0
  131. package/dist/state/file-store.js.map +1 -0
  132. package/dist/state/lock.d.ts +6 -0
  133. package/dist/state/lock.js +71 -0
  134. package/dist/state/lock.js.map +1 -0
  135. package/dist/state/plan-parser.d.ts +6 -0
  136. package/dist/state/plan-parser.js +54 -0
  137. package/dist/state/plan-parser.js.map +1 -0
  138. package/dist/state/store.d.ts +27 -0
  139. package/dist/state/store.js +2 -0
  140. package/dist/state/store.js.map +1 -0
  141. package/dist/steps/events.d.ts +49 -0
  142. package/dist/steps/events.js +2 -0
  143. package/dist/steps/events.js.map +1 -0
  144. package/dist/steps/pipeline.d.ts +14 -0
  145. package/dist/steps/pipeline.js +284 -0
  146. package/dist/steps/pipeline.js.map +1 -0
  147. package/dist/steps/plan-parser.d.ts +35 -0
  148. package/dist/steps/plan-parser.js +147 -0
  149. package/dist/steps/plan-parser.js.map +1 -0
  150. package/dist/steps/runner.d.ts +13 -0
  151. package/dist/steps/runner.js +155 -0
  152. package/dist/steps/runner.js.map +1 -0
  153. package/dist/steps/store.d.ts +26 -0
  154. package/dist/steps/store.js +164 -0
  155. package/dist/steps/store.js.map +1 -0
  156. package/dist/steps/types.d.ts +36 -0
  157. package/dist/steps/types.js +2 -0
  158. package/dist/steps/types.js.map +1 -0
  159. package/dist/tui/app.d.ts +15 -0
  160. package/dist/tui/app.js +297 -0
  161. package/dist/tui/app.js.map +1 -0
  162. package/dist/tui/banner.d.ts +1 -0
  163. package/dist/tui/banner.js +11 -0
  164. package/dist/tui/banner.js.map +1 -0
  165. package/dist/tui/colors.d.ts +22 -0
  166. package/dist/tui/colors.js +30 -0
  167. package/dist/tui/colors.js.map +1 -0
  168. package/dist/tui/components/agent-panel.d.ts +8 -0
  169. package/dist/tui/components/agent-panel.js +80 -0
  170. package/dist/tui/components/agent-panel.js.map +1 -0
  171. package/dist/tui/components/header.d.ts +15 -0
  172. package/dist/tui/components/header.js +69 -0
  173. package/dist/tui/components/header.js.map +1 -0
  174. package/dist/tui/components/status-bar.d.ts +2 -0
  175. package/dist/tui/components/status-bar.js +8 -0
  176. package/dist/tui/components/status-bar.js.map +1 -0
  177. package/dist/tui/components/task-board.d.ts +3 -0
  178. package/dist/tui/components/task-board.js +96 -0
  179. package/dist/tui/components/task-board.js.map +1 -0
  180. package/dist/tui/display.d.ts +23 -0
  181. package/dist/tui/display.js +125 -0
  182. package/dist/tui/display.js.map +1 -0
  183. package/dist/tui/input.d.ts +2 -0
  184. package/dist/tui/input.js +44 -0
  185. package/dist/tui/input.js.map +1 -0
  186. package/dist/tui/layout-master.d.ts +7 -0
  187. package/dist/tui/layout-master.js +31 -0
  188. package/dist/tui/layout-master.js.map +1 -0
  189. package/dist/tui/layout.d.ts +13 -0
  190. package/dist/tui/layout.js +37 -0
  191. package/dist/tui/layout.js.map +1 -0
  192. package/dist/tui/pane-formatter.d.ts +27 -0
  193. package/dist/tui/pane-formatter.js +153 -0
  194. package/dist/tui/pane-formatter.js.map +1 -0
  195. package/dist/tui/renderer.d.ts +8 -0
  196. package/dist/tui/renderer.js +30 -0
  197. package/dist/tui/renderer.js.map +1 -0
  198. package/dist/tui/screen.d.ts +12 -0
  199. package/dist/tui/screen.js +32 -0
  200. package/dist/tui/screen.js.map +1 -0
  201. package/dist/tui/structured-display.d.ts +5 -0
  202. package/dist/tui/structured-display.js +74 -0
  203. package/dist/tui/structured-display.js.map +1 -0
  204. package/dist/tui/tmux-display.d.ts +6 -0
  205. package/dist/tui/tmux-display.js +187 -0
  206. package/dist/tui/tmux-display.js.map +1 -0
  207. package/dist/tui/tmux.d.ts +26 -0
  208. package/dist/tui/tmux.js +265 -0
  209. package/dist/tui/tmux.js.map +1 -0
  210. package/dist/types.d.ts +15 -0
  211. package/dist/types.js +2 -0
  212. package/dist/types.js.map +1 -0
  213. package/dist/utils/git.d.ts +6 -0
  214. package/dist/utils/git.js +35 -0
  215. package/dist/utils/git.js.map +1 -0
  216. package/dist/utils/hello.d.ts +1 -0
  217. package/dist/utils/hello.js +4 -0
  218. package/dist/utils/hello.js.map +1 -0
  219. package/dist/utils/id.d.ts +1 -0
  220. package/dist/utils/id.js +5 -0
  221. package/dist/utils/id.js.map +1 -0
  222. package/dist/utils/jsonl.d.ts +2 -0
  223. package/dist/utils/jsonl.js +18 -0
  224. package/dist/utils/jsonl.js.map +1 -0
  225. package/dist/utils/logger.d.ts +20 -0
  226. package/dist/utils/logger.js +40 -0
  227. package/dist/utils/logger.js.map +1 -0
  228. package/dist/utils/pricing.d.ts +3 -0
  229. package/dist/utils/pricing.js +26 -0
  230. package/dist/utils/pricing.js.map +1 -0
  231. package/dist/utils/xml.d.ts +13 -0
  232. package/dist/utils/xml.js +67 -0
  233. package/dist/utils/xml.js.map +1 -0
  234. package/dist/utils/yaml.d.ts +5 -0
  235. package/dist/utils/yaml.js +126 -0
  236. package/dist/utils/yaml.js.map +1 -0
  237. package/package.json +45 -0
  238. package/templates/CONSTITUTION.md +10 -0
  239. package/templates/STATE.md +3 -0
  240. package/templates/config.json +11 -0
@@ -0,0 +1,82 @@
1
+ // ── Constants ────────────────────────────────────────────────────────────────
2
+ export const MAX_MESSAGE_SIZE = 1_048_576; // 1 MB
3
+ // JSON-RPC 2.0 error codes
4
+ export const PARSE_ERROR = -32700;
5
+ export const INVALID_REQUEST = -32600;
6
+ export const METHOD_NOT_FOUND = -32601;
7
+ export const INVALID_PARAMS = -32602;
8
+ export const INTERNAL_ERROR = -32603;
9
+ // ── Reader ───────────────────────────────────────────────────────────────────
10
+ /**
11
+ * Create an async iterable that yields validated `JsonRpcRequest` objects
12
+ * from a newline-delimited JSON stream (MCP stdio transport).
13
+ */
14
+ export async function* createMessageReader(input) {
15
+ let buffer = Buffer.alloc(0);
16
+ const chunks = input;
17
+ for await (const chunk of chunks) {
18
+ buffer = Buffer.concat([
19
+ buffer,
20
+ typeof chunk === 'string' ? Buffer.from(chunk, 'utf-8') : chunk,
21
+ ]);
22
+ // Process as many complete lines as possible.
23
+ let newlineIdx;
24
+ while ((newlineIdx = buffer.indexOf(0x0a)) !== -1) {
25
+ let line = buffer.subarray(0, newlineIdx).toString('utf-8');
26
+ buffer = buffer.subarray(newlineIdx + 1);
27
+ // Strip trailing \r for Windows compat.
28
+ if (line.endsWith('\r')) {
29
+ line = line.slice(0, -1);
30
+ }
31
+ // Skip blank lines.
32
+ if (line.length === 0)
33
+ continue;
34
+ // Reject oversized messages.
35
+ if (Buffer.byteLength(line, 'utf-8') > MAX_MESSAGE_SIZE) {
36
+ process.stderr.write(`JSON-RPC: message too large (${Buffer.byteLength(line, 'utf-8')} bytes), skipping\n`);
37
+ continue;
38
+ }
39
+ // Parse JSON.
40
+ let parsed;
41
+ try {
42
+ parsed = JSON.parse(line);
43
+ }
44
+ catch {
45
+ process.stderr.write('JSON-RPC: failed to parse JSON, skipping\n');
46
+ continue;
47
+ }
48
+ // Validate JSON-RPC 2.0 envelope.
49
+ if (typeof parsed !== 'object' ||
50
+ parsed === null ||
51
+ parsed['jsonrpc'] !== '2.0') {
52
+ process.stderr.write('JSON-RPC: missing or invalid jsonrpc field, skipping\n');
53
+ continue;
54
+ }
55
+ if (typeof parsed['method'] !== 'string') {
56
+ process.stderr.write('JSON-RPC: missing or invalid method field, skipping\n');
57
+ continue;
58
+ }
59
+ yield parsed;
60
+ }
61
+ }
62
+ }
63
+ // ── Writer ───────────────────────────────────────────────────────────────────
64
+ export function createMessageWriter(output) {
65
+ return {
66
+ write(msg) {
67
+ output.write(JSON.stringify(msg) + '\n');
68
+ },
69
+ };
70
+ }
71
+ // ── Response helpers ─────────────────────────────────────────────────────────
72
+ export function createSuccessResponse(id, result) {
73
+ return { jsonrpc: '2.0', id, result };
74
+ }
75
+ export function createErrorResponse(id, code, message, data) {
76
+ const error = { code, message };
77
+ if (data !== undefined) {
78
+ error.data = data;
79
+ }
80
+ return { jsonrpc: '2.0', id, error };
81
+ }
82
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/mcp/protocol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { StepStore } from '../steps/store.js';
2
+ export interface McpResource {
3
+ uri: string;
4
+ name: string;
5
+ description: string;
6
+ mimeType: string;
7
+ }
8
+ export interface ResourceRegistry {
9
+ list(): McpResource[];
10
+ read(uri: string): Promise<{
11
+ uri: string;
12
+ mimeType: string;
13
+ text: string;
14
+ } | undefined>;
15
+ }
16
+ export interface ResourceRegistryParams {
17
+ readonly store: StepStore;
18
+ readonly sdRoot: string;
19
+ }
20
+ export declare function createResourceRegistry(params: ResourceRegistryParams): ResourceRegistry;
@@ -0,0 +1,101 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ // ── Credential redaction ─────────────────────────────────────────────────────
4
+ const SENSITIVE_PATTERNS = /token|secret|key|password|credential/i;
5
+ function redactSensitiveFields(obj) {
6
+ const result = {};
7
+ for (const [k, v] of Object.entries(obj)) {
8
+ if (SENSITIVE_PATTERNS.test(k)) {
9
+ result[k] = '[REDACTED]';
10
+ }
11
+ else {
12
+ result[k] = v;
13
+ }
14
+ }
15
+ return result;
16
+ }
17
+ // ── Helpers ──────────────────────────────────────────────────────────────────
18
+ async function readFileOrEmpty(filePath) {
19
+ try {
20
+ return await readFile(filePath, 'utf-8');
21
+ }
22
+ catch {
23
+ return '';
24
+ }
25
+ }
26
+ // ── Resource definitions ─────────────────────────────────────────────────────
27
+ const RESOURCE_DEFS = [
28
+ {
29
+ uri: 'slavedriver://constitution',
30
+ name: 'Constitution',
31
+ description: 'Project rules and constraints',
32
+ mimeType: 'text/markdown',
33
+ },
34
+ {
35
+ uri: 'slavedriver://config',
36
+ name: 'Configuration',
37
+ description: 'Project configuration',
38
+ mimeType: 'application/json',
39
+ },
40
+ {
41
+ uri: 'slavedriver://steps',
42
+ name: 'Steps',
43
+ description: 'All pipeline steps and their status',
44
+ mimeType: 'application/json',
45
+ },
46
+ ];
47
+ const RESOURCE_URI_SET = new Set(RESOURCE_DEFS.map((r) => r.uri));
48
+ export function createResourceRegistry(params) {
49
+ const { store, sdRoot } = params;
50
+ const readers = {
51
+ 'slavedriver://constitution': async () => {
52
+ const text = await readFileOrEmpty(join(sdRoot, 'CONSTITUTION.md'));
53
+ return { mimeType: 'text/markdown', text };
54
+ },
55
+ 'slavedriver://config': async () => {
56
+ try {
57
+ const text = await readFile(join(sdRoot, 'config.json'), 'utf-8');
58
+ const config = JSON.parse(text);
59
+ const redacted = redactSensitiveFields(config);
60
+ return { mimeType: 'application/json', text: JSON.stringify(redacted) };
61
+ }
62
+ catch {
63
+ return { mimeType: 'application/json', text: '{}' };
64
+ }
65
+ },
66
+ 'slavedriver://steps': async () => {
67
+ try {
68
+ const steps = await store.listSteps();
69
+ const data = steps.map((s) => ({
70
+ number: s.number,
71
+ name: s.meta.name,
72
+ status: s.meta.status,
73
+ agent: s.meta.agent,
74
+ reads: s.meta.reads,
75
+ inputTokens: s.meta.inputTokens,
76
+ outputTokens: s.meta.outputTokens,
77
+ error: s.meta.error,
78
+ }));
79
+ return { mimeType: 'application/json', text: JSON.stringify(data) };
80
+ }
81
+ catch {
82
+ return { mimeType: 'application/json', text: '[]' };
83
+ }
84
+ },
85
+ };
86
+ return {
87
+ list() {
88
+ return [...RESOURCE_DEFS];
89
+ },
90
+ async read(uri) {
91
+ if (!RESOURCE_URI_SET.has(uri))
92
+ return undefined;
93
+ const reader = readers[uri];
94
+ if (!reader)
95
+ return undefined;
96
+ const { mimeType, text } = await reader();
97
+ return { uri, mimeType, text };
98
+ },
99
+ };
100
+ }
101
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/mcp/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { AgentRuntime } from '../agents/runtime.js';
2
+ import type { ProjectConfig } from '../types.js';
3
+ import type { StepStore } from '../steps/store.js';
4
+ import type { StepEvent } from '../steps/events.js';
5
+ export interface RunState {
6
+ readonly runId: string;
7
+ readonly goal: string;
8
+ readonly startedAt: string;
9
+ readonly totalSteps: number;
10
+ readonly completedSteps: number;
11
+ readonly failedSteps: number;
12
+ readonly totalInputTokens: number;
13
+ readonly totalOutputTokens: number;
14
+ readonly error?: string;
15
+ readonly isRunning: boolean;
16
+ readonly dashboardSession?: string;
17
+ }
18
+ export interface RunManagerParams {
19
+ readonly runtime: AgentRuntime;
20
+ readonly store: StepStore;
21
+ readonly config: ProjectConfig;
22
+ readonly sdRoot: string;
23
+ readonly workingDirectory: string;
24
+ readonly noDisplay?: boolean;
25
+ }
26
+ export interface RunManager {
27
+ start(goal: string, options?: {
28
+ dryRun?: boolean;
29
+ }): string;
30
+ waitForCompletion(): Promise<RunState | null>;
31
+ getState(): RunState | null;
32
+ getRecentEvents(limit?: number): StepEvent[];
33
+ abort(): boolean;
34
+ isRunning(): boolean;
35
+ }
36
+ export declare function createRunManager(params: RunManagerParams): RunManager;
@@ -0,0 +1,179 @@
1
+ import { runPipeline } from '../steps/pipeline.js';
2
+ import { createDisplay } from '../tui/display.js';
3
+ import { generateId } from '../utils/id.js';
4
+ // ── Constants ────────────────────────────────────────────────────────────────
5
+ const MAX_EVENT_BUFFER = 200;
6
+ export function createRunManager(params) {
7
+ const { runtime, store, config, sdRoot, workingDirectory } = params;
8
+ let activeRun = null;
9
+ const eventBuffer = [];
10
+ let totalSteps = 0;
11
+ let completedSteps = 0;
12
+ let failedSteps = 0;
13
+ let totalInputTokens = 0;
14
+ let totalOutputTokens = 0;
15
+ function resetCounters() {
16
+ totalSteps = 0;
17
+ completedSteps = 0;
18
+ failedSteps = 0;
19
+ totalInputTokens = 0;
20
+ totalOutputTokens = 0;
21
+ }
22
+ function pushEvent(event) {
23
+ if (eventBuffer.length >= MAX_EVENT_BUFFER) {
24
+ eventBuffer.shift();
25
+ }
26
+ eventBuffer.push(event);
27
+ // Forward to display
28
+ if (activeRun?.display) {
29
+ activeRun.display.handleEvent(event);
30
+ }
31
+ // Track counts
32
+ switch (event.type) {
33
+ case 'step_created':
34
+ totalSteps++;
35
+ break;
36
+ case 'step_completed':
37
+ completedSteps++;
38
+ totalInputTokens += event.inputTokens;
39
+ totalOutputTokens += event.outputTokens;
40
+ break;
41
+ case 'step_failed':
42
+ failedSteps++;
43
+ break;
44
+ case 'pipeline_complete':
45
+ totalSteps = event.totalSteps;
46
+ completedSteps = event.completedSteps;
47
+ totalInputTokens = event.totalInputTokens;
48
+ totalOutputTokens = event.totalOutputTokens;
49
+ break;
50
+ case 'phase_started':
51
+ case 'phase_completed':
52
+ case 'pipeline_started':
53
+ case 'pipeline_error':
54
+ case 'agent_event':
55
+ // Tracked in event buffer only
56
+ break;
57
+ }
58
+ }
59
+ function isActiveAndRunning() {
60
+ if (!activeRun)
61
+ return false;
62
+ return !activeRun.error && !activeRun.aborted;
63
+ }
64
+ return {
65
+ start(goal, options) {
66
+ if (activeRun && isActiveAndRunning()) {
67
+ throw new Error(`A run is already active (runId=${activeRun.runId})`);
68
+ }
69
+ // Clear previous state
70
+ eventBuffer.length = 0;
71
+ resetCounters();
72
+ const runId = generateId();
73
+ const startedAt = new Date().toISOString();
74
+ // Create tmux display — always detached so we don't split the parent session
75
+ const projectName = workingDirectory.split('/').pop() ?? 'project';
76
+ let display = null;
77
+ if (!params.noDisplay) {
78
+ try {
79
+ display = createDisplay({
80
+ version: '0.2.0',
81
+ projectName,
82
+ noTui: false,
83
+ forceDetached: true,
84
+ });
85
+ display.start();
86
+ const session = display.getSessionName?.();
87
+ if (session) {
88
+ process.stderr.write(`[run-manager] Dashboard: tmux attach-session -t ${session}\n`);
89
+ }
90
+ }
91
+ catch (err) {
92
+ process.stderr.write(`[run-manager] Display creation failed, running headless: ${err instanceof Error ? err.message : String(err)}\n`);
93
+ display = null;
94
+ }
95
+ }
96
+ const abortController = new AbortController();
97
+ activeRun = {
98
+ runId,
99
+ goal,
100
+ startedAt,
101
+ display,
102
+ abortController,
103
+ promise: Promise.resolve(),
104
+ aborted: false,
105
+ };
106
+ // Run pipeline in background
107
+ activeRun.promise = (async () => {
108
+ try {
109
+ for await (const event of runPipeline(goal, {
110
+ runtime,
111
+ store,
112
+ config,
113
+ sdRoot,
114
+ workingDirectory,
115
+ dryRun: options?.dryRun,
116
+ abortSignal: abortController.signal,
117
+ })) {
118
+ pushEvent(event);
119
+ }
120
+ }
121
+ catch (err) {
122
+ if (activeRun) {
123
+ activeRun.error = err instanceof Error ? err.message : String(err);
124
+ }
125
+ }
126
+ finally {
127
+ if (activeRun?.display) {
128
+ activeRun.display.stop();
129
+ }
130
+ }
131
+ })();
132
+ return runId;
133
+ },
134
+ async waitForCompletion() {
135
+ if (!activeRun)
136
+ return null;
137
+ await activeRun.promise;
138
+ return this.getState();
139
+ },
140
+ getState() {
141
+ if (!activeRun)
142
+ return null;
143
+ const dashboardSession = activeRun.display?.getSessionName?.() ?? undefined;
144
+ return {
145
+ runId: activeRun.runId,
146
+ goal: activeRun.goal,
147
+ startedAt: activeRun.startedAt,
148
+ totalSteps,
149
+ completedSteps,
150
+ failedSteps,
151
+ totalInputTokens,
152
+ totalOutputTokens,
153
+ isRunning: isActiveAndRunning(),
154
+ ...(activeRun.error ? { error: activeRun.error } : {}),
155
+ ...(dashboardSession ? { dashboardSession } : {}),
156
+ };
157
+ },
158
+ getRecentEvents(limit = 50) {
159
+ const start = Math.max(0, eventBuffer.length - limit);
160
+ return eventBuffer.slice(start);
161
+ },
162
+ abort() {
163
+ if (!activeRun)
164
+ return false;
165
+ if (!isActiveAndRunning())
166
+ return false;
167
+ activeRun.aborted = true;
168
+ activeRun.abortController.abort();
169
+ if (activeRun.display) {
170
+ activeRun.display.stop();
171
+ }
172
+ return true;
173
+ },
174
+ isRunning() {
175
+ return isActiveAndRunning();
176
+ },
177
+ };
178
+ }
179
+ //# sourceMappingURL=run-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-manager.js","sourceRoot":"","sources":["../../src/mcp/run-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Readable, Writable } from 'node:stream';
2
+ import type { ToolRegistry } from './tools.js';
3
+ import type { ResourceRegistry } from './resources.js';
4
+ export interface McpServerParams {
5
+ readonly input: Readable;
6
+ readonly output: Writable;
7
+ readonly tools: ToolRegistry;
8
+ readonly resources: ResourceRegistry;
9
+ }
10
+ export interface McpServer {
11
+ start(): Promise<void>;
12
+ }
13
+ export declare function createMcpServer(params: McpServerParams): McpServer;
@@ -0,0 +1,99 @@
1
+ import { createMessageReader, createMessageWriter, createSuccessResponse, createErrorResponse, METHOD_NOT_FOUND, INVALID_PARAMS, INTERNAL_ERROR, } from './protocol.js';
2
+ // ── Constants ────────────────────────────────────────────────────────────────
3
+ const PROTOCOL_VERSION = '2024-11-05';
4
+ const SERVER_NAME = 'slavedriver';
5
+ const SERVER_VERSION = '0.1.0';
6
+ // ── Factory ─────────────────────────────────────────────────────────────────
7
+ export function createMcpServer(params) {
8
+ const { input, output, tools, resources } = params;
9
+ const writer = createMessageWriter(output);
10
+ async function handleRequest(req) {
11
+ // Notifications (no id) don't get responses
12
+ if (req.id === undefined || req.id === null) {
13
+ // Handle notification methods silently
14
+ return;
15
+ }
16
+ try {
17
+ switch (req.method) {
18
+ case 'initialize': {
19
+ writer.write(createSuccessResponse(req.id, {
20
+ protocolVersion: PROTOCOL_VERSION,
21
+ capabilities: {
22
+ tools: {},
23
+ resources: {},
24
+ },
25
+ serverInfo: {
26
+ name: SERVER_NAME,
27
+ version: SERVER_VERSION,
28
+ },
29
+ }));
30
+ return;
31
+ }
32
+ case 'tools/list': {
33
+ const toolList = tools.list();
34
+ writer.write(createSuccessResponse(req.id, {
35
+ tools: toolList,
36
+ }));
37
+ return;
38
+ }
39
+ case 'tools/call': {
40
+ const p = req.params;
41
+ const name = p?.['name'];
42
+ if (typeof name !== 'string') {
43
+ writer.write(createErrorResponse(req.id, INVALID_PARAMS, 'Missing tool name'));
44
+ return;
45
+ }
46
+ const toolArgs = (p?.['arguments'] ?? {});
47
+ const result = await tools.call(name, toolArgs);
48
+ writer.write(createSuccessResponse(req.id, result));
49
+ return;
50
+ }
51
+ case 'resources/list': {
52
+ const resourceList = resources.list();
53
+ writer.write(createSuccessResponse(req.id, {
54
+ resources: resourceList,
55
+ }));
56
+ return;
57
+ }
58
+ case 'resources/read': {
59
+ const p = req.params;
60
+ const uri = p?.['uri'];
61
+ if (typeof uri !== 'string') {
62
+ writer.write(createErrorResponse(req.id, INVALID_PARAMS, 'Missing resource URI'));
63
+ return;
64
+ }
65
+ const content = await resources.read(uri);
66
+ if (!content) {
67
+ writer.write(createErrorResponse(req.id, INVALID_PARAMS, `Unknown resource: ${uri}`));
68
+ return;
69
+ }
70
+ writer.write(createSuccessResponse(req.id, {
71
+ contents: [content],
72
+ }));
73
+ return;
74
+ }
75
+ default: {
76
+ writer.write(createErrorResponse(req.id, METHOD_NOT_FOUND, `Unknown method: ${req.method}`));
77
+ return;
78
+ }
79
+ }
80
+ }
81
+ catch (err) {
82
+ process.stderr.write(`MCP server error handling ${req.method}: ${err instanceof Error ? err.message : String(err)}\n`);
83
+ writer.write(createErrorResponse(req.id, INTERNAL_ERROR, err instanceof Error ? err.message : 'Internal error'));
84
+ }
85
+ }
86
+ return {
87
+ async start() {
88
+ const reader = createMessageReader(input);
89
+ for await (const request of reader) {
90
+ // Fire-and-forget: don't await so long-running handlers
91
+ // (e.g. slavedriver_start with wait=true) don't block other requests.
92
+ handleRequest(request).catch((err) => {
93
+ process.stderr.write(`MCP server unhandled error: ${err instanceof Error ? err.message : String(err)}\n`);
94
+ });
95
+ }
96
+ },
97
+ };
98
+ }
99
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { RunManager } from './run-manager.js';
2
+ import type { StepStore } from '../steps/store.js';
3
+ import type { AgentRuntime } from '../agents/runtime.js';
4
+ export interface McpToolDef {
5
+ name: string;
6
+ description: string;
7
+ inputSchema: {
8
+ type: 'object';
9
+ properties: Record<string, unknown>;
10
+ required?: string[];
11
+ };
12
+ }
13
+ export interface ToolResult {
14
+ content: Array<{
15
+ type: 'text';
16
+ text: string;
17
+ }>;
18
+ isError?: boolean;
19
+ }
20
+ export interface ToolRegistry {
21
+ list(): McpToolDef[];
22
+ call(name: string, params: unknown): Promise<ToolResult>;
23
+ }
24
+ export interface ToolRegistryParams {
25
+ readonly runManager: RunManager;
26
+ readonly store: StepStore;
27
+ readonly runtime: AgentRuntime;
28
+ readonly sdRoot: string;
29
+ readonly workingDirectory: string;
30
+ readonly configPath: string;
31
+ }
32
+ export declare function createToolRegistry(params: ToolRegistryParams): ToolRegistry;