craftdriver 0.1.0 → 0.2.1

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 (186) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/README.md +157 -45
  3. package/bin/craftdriver.mjs +26 -0
  4. package/dist/cli/client.d.ts +17 -0
  5. package/dist/cli/client.d.ts.map +1 -0
  6. package/dist/cli/client.js +88 -0
  7. package/dist/cli/client.js.map +1 -0
  8. package/dist/cli/daemon.d.ts +15 -0
  9. package/dist/cli/daemon.d.ts.map +1 -0
  10. package/dist/cli/daemon.js +145 -0
  11. package/dist/cli/daemon.js.map +1 -0
  12. package/dist/cli/defaults.d.ts +10 -0
  13. package/dist/cli/defaults.d.ts.map +1 -0
  14. package/dist/cli/defaults.js +42 -0
  15. package/dist/cli/defaults.js.map +1 -0
  16. package/dist/cli/dispatcher.d.ts +28 -0
  17. package/dist/cli/dispatcher.d.ts.map +1 -0
  18. package/dist/cli/dispatcher.js +319 -0
  19. package/dist/cli/dispatcher.js.map +1 -0
  20. package/dist/cli/index.d.ts +2 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +404 -0
  23. package/dist/cli/index.js.map +1 -0
  24. package/dist/cli/init.d.ts +24 -0
  25. package/dist/cli/init.d.ts.map +1 -0
  26. package/dist/cli/init.js +192 -0
  27. package/dist/cli/init.js.map +1 -0
  28. package/dist/cli/mcp/artifacts.d.ts +43 -0
  29. package/dist/cli/mcp/artifacts.d.ts.map +1 -0
  30. package/dist/cli/mcp/artifacts.js +104 -0
  31. package/dist/cli/mcp/artifacts.js.map +1 -0
  32. package/dist/cli/mcp/server.d.ts +34 -0
  33. package/dist/cli/mcp/server.d.ts.map +1 -0
  34. package/dist/cli/mcp/server.js +214 -0
  35. package/dist/cli/mcp/server.js.map +1 -0
  36. package/dist/cli/mcp/tools.d.ts +34 -0
  37. package/dist/cli/mcp/tools.d.ts.map +1 -0
  38. package/dist/cli/mcp/tools.js +236 -0
  39. package/dist/cli/mcp/tools.js.map +1 -0
  40. package/dist/cli/parseArgs.d.ts +37 -0
  41. package/dist/cli/parseArgs.d.ts.map +1 -0
  42. package/dist/cli/parseArgs.js +215 -0
  43. package/dist/cli/parseArgs.js.map +1 -0
  44. package/dist/cli/protocol.d.ts +34 -0
  45. package/dist/cli/protocol.d.ts.map +1 -0
  46. package/dist/cli/protocol.js +2 -0
  47. package/dist/cli/protocol.js.map +1 -0
  48. package/dist/cli/selector.d.ts +29 -0
  49. package/dist/cli/selector.d.ts.map +1 -0
  50. package/dist/cli/selector.js +100 -0
  51. package/dist/cli/selector.js.map +1 -0
  52. package/dist/cli/snapshot.d.ts +48 -0
  53. package/dist/cli/snapshot.d.ts.map +1 -0
  54. package/dist/cli/snapshot.js +179 -0
  55. package/dist/cli/snapshot.js.map +1 -0
  56. package/dist/index.d.ts +14 -2
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +15 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/lib/a11y.d.ts +81 -0
  61. package/dist/lib/a11y.d.ts.map +1 -0
  62. package/dist/lib/a11y.js +171 -0
  63. package/dist/lib/a11y.js.map +1 -0
  64. package/dist/lib/bidi/index.d.ts +26 -1
  65. package/dist/lib/bidi/index.d.ts.map +1 -1
  66. package/dist/lib/bidi/index.js +49 -0
  67. package/dist/lib/bidi/index.js.map +1 -1
  68. package/dist/lib/bidi/logs.d.ts +2 -2
  69. package/dist/lib/bidi/logs.d.ts.map +1 -1
  70. package/dist/lib/bidi/logs.js +2 -2
  71. package/dist/lib/bidi/logs.js.map +1 -1
  72. package/dist/lib/bidi/network.d.ts +74 -1
  73. package/dist/lib/bidi/network.d.ts.map +1 -1
  74. package/dist/lib/bidi/network.js +222 -4
  75. package/dist/lib/bidi/network.js.map +1 -1
  76. package/dist/lib/bidi/storage.d.ts +5 -3
  77. package/dist/lib/bidi/storage.d.ts.map +1 -1
  78. package/dist/lib/bidi/storage.js +14 -7
  79. package/dist/lib/bidi/storage.js.map +1 -1
  80. package/dist/lib/bidi/types.d.ts +27 -6
  81. package/dist/lib/bidi/types.d.ts.map +1 -1
  82. package/dist/lib/browser.d.ts +637 -16
  83. package/dist/lib/browser.d.ts.map +1 -1
  84. package/dist/lib/browser.js +1428 -102
  85. package/dist/lib/browser.js.map +1 -1
  86. package/dist/lib/browserContext.d.ts +486 -0
  87. package/dist/lib/browserContext.d.ts.map +1 -0
  88. package/dist/lib/browserContext.js +937 -0
  89. package/dist/lib/browserContext.js.map +1 -0
  90. package/dist/lib/builder.d.ts +3 -0
  91. package/dist/lib/builder.d.ts.map +1 -1
  92. package/dist/lib/builder.js +31 -4
  93. package/dist/lib/builder.js.map +1 -1
  94. package/dist/lib/by.d.ts +18 -2
  95. package/dist/lib/by.d.ts.map +1 -1
  96. package/dist/lib/by.js +20 -2
  97. package/dist/lib/by.js.map +1 -1
  98. package/dist/lib/chrome.d.ts +13 -1
  99. package/dist/lib/chrome.d.ts.map +1 -1
  100. package/dist/lib/chrome.js +13 -17
  101. package/dist/lib/chrome.js.map +1 -1
  102. package/dist/lib/clock.d.ts +115 -0
  103. package/dist/lib/clock.d.ts.map +1 -0
  104. package/dist/lib/clock.js +407 -0
  105. package/dist/lib/clock.js.map +1 -0
  106. package/dist/lib/driver.d.ts +43 -0
  107. package/dist/lib/driver.d.ts.map +1 -1
  108. package/dist/lib/driver.js +120 -0
  109. package/dist/lib/driver.js.map +1 -1
  110. package/dist/lib/driverManager.d.ts +25 -0
  111. package/dist/lib/driverManager.d.ts.map +1 -0
  112. package/dist/lib/driverManager.js +399 -0
  113. package/dist/lib/driverManager.js.map +1 -0
  114. package/dist/lib/elementHandle.d.ts +67 -3
  115. package/dist/lib/elementHandle.d.ts.map +1 -1
  116. package/dist/lib/elementHandle.js +209 -67
  117. package/dist/lib/elementHandle.js.map +1 -1
  118. package/dist/lib/errors.d.ts +71 -0
  119. package/dist/lib/errors.d.ts.map +1 -0
  120. package/dist/lib/errors.js +73 -0
  121. package/dist/lib/errors.js.map +1 -0
  122. package/dist/lib/expect.d.ts +6 -1
  123. package/dist/lib/expect.d.ts.map +1 -1
  124. package/dist/lib/expect.js +55 -37
  125. package/dist/lib/expect.js.map +1 -1
  126. package/dist/lib/firefox.d.ts +18 -0
  127. package/dist/lib/firefox.d.ts.map +1 -0
  128. package/dist/lib/firefox.js +33 -0
  129. package/dist/lib/firefox.js.map +1 -0
  130. package/dist/lib/frame.d.ts +57 -0
  131. package/dist/lib/frame.d.ts.map +1 -0
  132. package/dist/lib/frame.js +277 -0
  133. package/dist/lib/frame.js.map +1 -0
  134. package/dist/lib/keyboard.d.ts +1 -1
  135. package/dist/lib/keyboard.d.ts.map +1 -1
  136. package/dist/lib/keyboard.js +1 -1
  137. package/dist/lib/keyboard.js.map +1 -1
  138. package/dist/lib/locator.d.ts +71 -2
  139. package/dist/lib/locator.d.ts.map +1 -1
  140. package/dist/lib/locator.js +289 -31
  141. package/dist/lib/locator.js.map +1 -1
  142. package/dist/lib/mouse.d.ts +1 -1
  143. package/dist/lib/mouse.d.ts.map +1 -1
  144. package/dist/lib/mouse.js +1 -1
  145. package/dist/lib/mouse.js.map +1 -1
  146. package/dist/lib/page.d.ts +107 -0
  147. package/dist/lib/page.d.ts.map +1 -0
  148. package/dist/lib/page.js +388 -0
  149. package/dist/lib/page.js.map +1 -0
  150. package/dist/lib/tracing.d.ts +128 -0
  151. package/dist/lib/tracing.d.ts.map +1 -0
  152. package/dist/lib/tracing.js +272 -0
  153. package/dist/lib/tracing.js.map +1 -0
  154. package/dist/lib/wait.d.ts.map +1 -1
  155. package/dist/lib/wait.js +14 -1
  156. package/dist/lib/wait.js.map +1 -1
  157. package/dist/lib/webelement.d.ts +2 -0
  158. package/dist/lib/webelement.d.ts.map +1 -1
  159. package/dist/lib/webelement.js +18 -0
  160. package/dist/lib/webelement.js.map +1 -1
  161. package/docs/accessibility.md +177 -0
  162. package/docs/api-reference.md +71 -0
  163. package/docs/assertions.md +182 -0
  164. package/docs/bidi-features.md +462 -0
  165. package/docs/browser-api.md +673 -0
  166. package/docs/browser-context.md +522 -0
  167. package/docs/cli.md +233 -0
  168. package/docs/clock.md +245 -0
  169. package/docs/dialogs.md +143 -0
  170. package/docs/driver-configuration.md +64 -0
  171. package/docs/element-api.md +219 -0
  172. package/docs/emulation.md +155 -0
  173. package/docs/error-codes.md +67 -0
  174. package/docs/getting-started.md +168 -0
  175. package/docs/keyboard-mouse.md +250 -0
  176. package/docs/mcp.md +250 -0
  177. package/docs/mobile-emulation.md +194 -0
  178. package/docs/screenshots.md +146 -0
  179. package/docs/selectors.md +382 -0
  180. package/docs/session-management.md +229 -0
  181. package/docs/tracing.md +282 -0
  182. package/package.json +26 -8
  183. package/skills/craftdriver/SKILL.md +84 -0
  184. package/skills/craftdriver/cheatsheet.md +194 -0
  185. package/skills/craftdriver/cli.md +104 -0
  186. package/skills/craftdriver/patterns.md +139 -0
@@ -0,0 +1,43 @@
1
+ export interface ArtifactWriteResult {
2
+ path: string;
3
+ bytes: number;
4
+ }
5
+ export declare class ArtifactStore {
6
+ private dir;
7
+ private ready;
8
+ private counter;
9
+ constructor(rootOverride?: string);
10
+ /** Absolute path to the artifact directory (may not exist yet). */
11
+ get directory(): string;
12
+ private ensure;
13
+ /**
14
+ * Write a payload to a numbered file. `nameHint` is used to build a
15
+ * human-readable filename (`0001-<hint>`); pass something like
16
+ * `screenshot.png` or `eval.json`.
17
+ */
18
+ write(nameHint: string, data: Buffer | string): Promise<ArtifactWriteResult>;
19
+ /**
20
+ * Allocate a path for an artifact the caller will write itself (e.g.
21
+ * pass to `browser.screenshot({ path })`). Doesn't touch the disk
22
+ * beyond `mkdir -p` of the directory.
23
+ */
24
+ allocate(nameHint: string): Promise<string>;
25
+ }
26
+ /**
27
+ * Spill threshold in bytes. Content blocks longer than this are
28
+ * written to an artifact and replaced inline with a short preview.
29
+ *
30
+ * Default 2 KB ≈ 500 tokens — enough room for a typical short
31
+ * snapshot diff or a small JSON result, but well below the cost of a
32
+ * full 80-node snapshot or a verbose eval payload.
33
+ */
34
+ export declare const DEFAULT_SPILL_BYTES = 2048;
35
+ export declare function resolveSpillBytes(): number;
36
+ /**
37
+ * Build the short inline replacement shown in place of a spilled
38
+ * payload. Keeps the first ~5 lines (or 240 chars, whichever is
39
+ * shorter) so the agent still sees the head of the data without
40
+ * having to read the file for a quick glance.
41
+ */
42
+ export declare function spillPreview(text: string, written: ArtifactWriteResult): string;
43
+ //# sourceMappingURL=artifacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/artifacts.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,OAAO,CAAK;gBAER,YAAY,CAAC,EAAE,MAAM;IAQjC,mEAAmE;IACnE,IAAI,SAAS,IAAI,MAAM,CAEtB;YAEa,MAAM;IAOpB;;;;OAIG;IACG,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAUlF;;;;OAIG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAMlD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,OAAO,CAAC;AAExC,wBAAgB,iBAAiB,IAAI,MAAM,CAK1C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAI/E"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Per-session artifact store for the MCP server.
3
+ *
4
+ * Why this exists: MCP content blocks count against the model's
5
+ * context window. A 100 KB screenshot or a 4 KB full a11y snapshot
6
+ * costs the agent real tokens on every turn. We'd rather spill the
7
+ * payload to disk and hand back a short preview + absolute path.
8
+ * Hosts that can read files (Claude Code, Cursor, Windsurf, Zed,
9
+ * Goose, Gemini CLI, …) just open it; hosts that can't can still
10
+ * fetch via MCP resources once we expose them.
11
+ *
12
+ * Directory layout:
13
+ * <root>/craftdriver-mcp-<pid>-<ts>/
14
+ * 0001-screenshot.png
15
+ * 0002-snapshot.txt
16
+ * 0003-eval.json
17
+ *
18
+ * Root resolution order:
19
+ * 1. $CRAFTDRIVER_MCP_ARTIFACTS_DIR if set
20
+ * 2. os.tmpdir()
21
+ *
22
+ * Lifetime: the directory is **not** deleted on shutdown. Agents may
23
+ * still be holding paths to past artifacts; OS-level temp cleanup
24
+ * reclaims them eventually. Override the root if you need a custom
25
+ * cleanup policy.
26
+ */
27
+ import { mkdir, writeFile } from 'fs/promises';
28
+ import { join, resolve } from 'path';
29
+ import { tmpdir } from 'os';
30
+ export class ArtifactStore {
31
+ dir;
32
+ ready = null;
33
+ counter = 0;
34
+ constructor(rootOverride) {
35
+ const root = rootOverride
36
+ ?? process.env.CRAFTDRIVER_MCP_ARTIFACTS_DIR
37
+ ?? tmpdir();
38
+ const stamp = `${process.pid}-${Date.now().toString(36)}`;
39
+ this.dir = resolve(root, `craftdriver-mcp-${stamp}`);
40
+ }
41
+ /** Absolute path to the artifact directory (may not exist yet). */
42
+ get directory() {
43
+ return this.dir;
44
+ }
45
+ async ensure() {
46
+ if (!this.ready) {
47
+ this.ready = mkdir(this.dir, { recursive: true }).then(() => undefined);
48
+ }
49
+ await this.ready;
50
+ }
51
+ /**
52
+ * Write a payload to a numbered file. `nameHint` is used to build a
53
+ * human-readable filename (`0001-<hint>`); pass something like
54
+ * `screenshot.png` or `eval.json`.
55
+ */
56
+ async write(nameHint, data) {
57
+ await this.ensure();
58
+ this.counter += 1;
59
+ const seq = this.counter.toString().padStart(4, '0');
60
+ const path = join(this.dir, `${seq}-${nameHint}`);
61
+ const buf = typeof data === 'string' ? Buffer.from(data, 'utf8') : data;
62
+ await writeFile(path, buf);
63
+ return { path, bytes: buf.length };
64
+ }
65
+ /**
66
+ * Allocate a path for an artifact the caller will write itself (e.g.
67
+ * pass to `browser.screenshot({ path })`). Doesn't touch the disk
68
+ * beyond `mkdir -p` of the directory.
69
+ */
70
+ async allocate(nameHint) {
71
+ await this.ensure();
72
+ this.counter += 1;
73
+ const seq = this.counter.toString().padStart(4, '0');
74
+ return join(this.dir, `${seq}-${nameHint}`);
75
+ }
76
+ }
77
+ /**
78
+ * Spill threshold in bytes. Content blocks longer than this are
79
+ * written to an artifact and replaced inline with a short preview.
80
+ *
81
+ * Default 2 KB ≈ 500 tokens — enough room for a typical short
82
+ * snapshot diff or a small JSON result, but well below the cost of a
83
+ * full 80-node snapshot or a verbose eval payload.
84
+ */
85
+ export const DEFAULT_SPILL_BYTES = 2048;
86
+ export function resolveSpillBytes() {
87
+ const env = process.env.CRAFTDRIVER_MCP_SPILL_BYTES;
88
+ if (!env)
89
+ return DEFAULT_SPILL_BYTES;
90
+ const n = Number.parseInt(env, 10);
91
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_SPILL_BYTES;
92
+ }
93
+ /**
94
+ * Build the short inline replacement shown in place of a spilled
95
+ * payload. Keeps the first ~5 lines (or 240 chars, whichever is
96
+ * shorter) so the agent still sees the head of the data without
97
+ * having to read the file for a quick glance.
98
+ */
99
+ export function spillPreview(text, written) {
100
+ const head = text.split('\n').slice(0, 5).join('\n');
101
+ const trimmed = head.length > 240 ? head.slice(0, 237) + '…' : head;
102
+ return `${trimmed}\n…\n(full output: ${written.path}, ${written.bytes} bytes)`;
103
+ }
104
+ //# sourceMappingURL=artifacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../../src/cli/mcp/artifacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * MCP server — JSON-RPC 2.0 over stdio.
3
+ *
4
+ * Hand-rolled because the spec we use (initialize / tools/list /
5
+ * tools/call) is ~6 methods, and pulling `@modelcontextprotocol/sdk`
6
+ * would multiply our runtime-dep footprint. If the spec grows we can
7
+ * swap in the SDK without changing tool definitions in `tools.ts`.
8
+ *
9
+ * Protocol version we advertise: 2024-11-05. If the client offers a
10
+ * newer one we just echo theirs back — the methods we implement are
11
+ * stable across versions to date.
12
+ *
13
+ * Lifecycle:
14
+ * client → initialize → server returns capabilities + info
15
+ * client → notifications/initialized (no response)
16
+ * client ⇆ tools/list, tools/call, ...
17
+ * stdin EOF (or SIGINT/SIGTERM) → close browser, exit 0
18
+ */
19
+ import { type LaunchOptions } from '../../lib/browser.js';
20
+ export interface McpServerOptions {
21
+ launch: LaunchOptions;
22
+ /** Stream for incoming messages; defaults to process.stdin. */
23
+ input?: NodeJS.ReadableStream;
24
+ /** Stream for outgoing messages; defaults to process.stdout. */
25
+ output?: NodeJS.WritableStream;
26
+ /** Disable snapshots for tests that want a deterministic payload. */
27
+ snapshot?: 'auto' | 'none';
28
+ /** Override the artifact directory root (defaults to $CRAFTDRIVER_MCP_ARTIFACTS_DIR or os.tmpdir()). */
29
+ artifactsDir?: string;
30
+ /** Override the spill threshold in bytes (default 2048; env: $CRAFTDRIVER_MCP_SPILL_BYTES). */
31
+ spillBytes?: number;
32
+ }
33
+ export declare function runMcpServer(opts: McpServerOptions): Promise<void>;
34
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAW,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAiDnE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,aAAa,CAAC;IACtB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,wGAAwG;IACxG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+FAA+F;IAC/F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoHxE"}
@@ -0,0 +1,214 @@
1
+ /**
2
+ * MCP server — JSON-RPC 2.0 over stdio.
3
+ *
4
+ * Hand-rolled because the spec we use (initialize / tools/list /
5
+ * tools/call) is ~6 methods, and pulling `@modelcontextprotocol/sdk`
6
+ * would multiply our runtime-dep footprint. If the spec grows we can
7
+ * swap in the SDK without changing tool definitions in `tools.ts`.
8
+ *
9
+ * Protocol version we advertise: 2024-11-05. If the client offers a
10
+ * newer one we just echo theirs back — the methods we implement are
11
+ * stable across versions to date.
12
+ *
13
+ * Lifecycle:
14
+ * client → initialize → server returns capabilities + info
15
+ * client → notifications/initialized (no response)
16
+ * client ⇆ tools/list, tools/call, ...
17
+ * stdin EOF (or SIGINT/SIGTERM) → close browser, exit 0
18
+ */
19
+ import { Browser } from '../../lib/browser.js';
20
+ import { CraftdriverError, ErrorCode } from '../../lib/errors.js';
21
+ import { createBrowserHandle } from '../dispatcher.js';
22
+ import { TOOLS, getTool, runTool } from './tools.js';
23
+ import { renderDelta, renderFull, takeSnapshot } from '../snapshot.js';
24
+ import { ArtifactStore, resolveSpillBytes, spillPreview, } from './artifacts.js';
25
+ const PROTOCOL_VERSION = '2024-11-05';
26
+ const SERVER_NAME = 'craftdriver';
27
+ const SERVER_VERSION = '0.1.0';
28
+ export async function runMcpServer(opts) {
29
+ const input = opts.input ?? process.stdin;
30
+ const output = opts.output ?? process.stdout;
31
+ const handle = createBrowserHandle(() => Browser.launch(opts.launch));
32
+ const ctx = { handle, launchOptions: opts.launch };
33
+ // Snapshot state: one most-recent snapshot per session for diffing.
34
+ let lastSnapshot = null;
35
+ const snapshotsOn = opts.snapshot !== 'none';
36
+ // Artifact store: large content blocks spill here so they don't burn
37
+ // context tokens on every turn.
38
+ const artifacts = new ArtifactStore(opts.artifactsDir);
39
+ const spillBytes = opts.spillBytes ?? resolveSpillBytes();
40
+ function send(msg) {
41
+ output.write(JSON.stringify(msg) + '\n');
42
+ }
43
+ async function handleRequest(req) {
44
+ const id = req.id ?? null;
45
+ try {
46
+ switch (req.method) {
47
+ case 'initialize':
48
+ return ok(id, {
49
+ protocolVersion: req.params?.protocolVersion ?? PROTOCOL_VERSION,
50
+ capabilities: { tools: {} },
51
+ serverInfo: { name: SERVER_NAME, version: SERVER_VERSION },
52
+ instructions: 'craftdriver browser automation. Probe selectors with browser_exists ' +
53
+ 'before acting; errors carry a stable `code` field; the post-action ' +
54
+ 'a11y snapshot diff tells you what changed.',
55
+ });
56
+ case 'notifications/initialized':
57
+ return null; // notification — no response
58
+ case 'ping':
59
+ return ok(id, {});
60
+ case 'tools/list':
61
+ return ok(id, {
62
+ tools: TOOLS.map((t) => ({
63
+ name: t.name,
64
+ description: t.description,
65
+ inputSchema: t.inputSchema,
66
+ })),
67
+ });
68
+ case 'tools/call': {
69
+ const name = req.params?.name;
70
+ const args = req.params?.arguments ?? {};
71
+ if (!name)
72
+ return rpcError(id, -32602, 'tools/call: missing "name"');
73
+ const tool = getTool(name);
74
+ if (!tool) {
75
+ return ok(id, toolError(`unknown tool: ${name}`, ErrorCode.INVALID_ARGUMENT));
76
+ }
77
+ const result = await callTool(ctx, tool, args, {
78
+ snapshotsOn,
79
+ getPrev: () => lastSnapshot,
80
+ setLast: (s) => {
81
+ lastSnapshot = s;
82
+ },
83
+ artifacts,
84
+ spillBytes,
85
+ });
86
+ return ok(id, result);
87
+ }
88
+ case 'resources/list':
89
+ // Resources land with Item 7 (trace summaries). Empty list now
90
+ // keeps clients that probe for resource capability happy.
91
+ return ok(id, { resources: [] });
92
+ default:
93
+ return rpcError(id, -32601, `method not found: ${req.method}`);
94
+ }
95
+ }
96
+ catch (e) {
97
+ return rpcError(id, -32000, e.message ?? String(e));
98
+ }
99
+ }
100
+ // Line-delimited JSON over stdin. Tolerate \r\n and trailing whitespace.
101
+ let buf = '';
102
+ input.setEncoding?.('utf8');
103
+ input.on('data', (chunk) => {
104
+ buf += typeof chunk === 'string' ? chunk : chunk.toString('utf8');
105
+ let nl;
106
+ while ((nl = buf.indexOf('\n')) !== -1) {
107
+ const line = buf.slice(0, nl).trim();
108
+ buf = buf.slice(nl + 1);
109
+ if (!line)
110
+ continue;
111
+ let parsed;
112
+ try {
113
+ parsed = JSON.parse(line);
114
+ }
115
+ catch {
116
+ send({ jsonrpc: '2.0', id: null, error: { code: -32700, message: 'parse error' } });
117
+ continue;
118
+ }
119
+ // Run async; responses may interleave but each carries its own id.
120
+ void handleRequest(parsed).then((resp) => {
121
+ if (resp)
122
+ send(resp);
123
+ });
124
+ }
125
+ });
126
+ await new Promise((resolve) => {
127
+ const done = () => resolve();
128
+ input.once('end', done);
129
+ input.once('close', done);
130
+ process.once('SIGINT', done);
131
+ process.once('SIGTERM', done);
132
+ });
133
+ await handle.close();
134
+ }
135
+ async function callTool(ctx, tool, args, snap) {
136
+ // Screenshot path allocation: if the caller didn't supply a path,
137
+ // give them one inside the artifact directory so the PNG bytes are
138
+ // actually persisted somewhere they can read.
139
+ if (tool.name === 'browser_screenshot' && !args.path) {
140
+ args = { ...args, path: await snap.artifacts.allocate('screenshot.png') };
141
+ }
142
+ let value;
143
+ try {
144
+ value = await runTool(ctx, tool, args);
145
+ }
146
+ catch (e) {
147
+ if (e instanceof CraftdriverError) {
148
+ return toolError(e.message, e.code, e.hint);
149
+ }
150
+ return toolError(e.message ?? String(e), ErrorCode.DRIVER_ERROR);
151
+ }
152
+ const content = [];
153
+ // Render result. The snapshot tool returns a structured shape we
154
+ // know how to print compactly; everything else falls through to
155
+ // the generic summariser. Both paths run through `maybeSpill` so
156
+ // large payloads land on disk instead of in the context window.
157
+ let primaryText;
158
+ if (tool.name === 'browser_snapshot' && value && typeof value === 'object' && 'lines' in value) {
159
+ primaryText = await maybeSpill(renderFull(value), 'snapshot.txt', snap.artifacts, snap.spillBytes);
160
+ }
161
+ else {
162
+ primaryText = await summariseValue(tool.name, value, snap.artifacts, snap.spillBytes);
163
+ }
164
+ content.push({ type: 'text', text: primaryText });
165
+ // Post-action a11y diff, when this tool changed page state.
166
+ if (tool.mutating && snap.snapshotsOn) {
167
+ const next = await takeSnapshot(await ctx.handle.get()).catch(() => null);
168
+ const delta = renderDelta(snap.getPrev(), next);
169
+ if (delta) {
170
+ const block = await maybeSpill(delta, 'snapshot.txt', snap.artifacts, snap.spillBytes);
171
+ content.push({ type: 'text', text: block });
172
+ }
173
+ snap.setLast(next);
174
+ }
175
+ return { content, structuredContent: { result: value } };
176
+ }
177
+ async function summariseValue(toolName, value, artifacts, spillBytes) {
178
+ if (value === null || value === undefined)
179
+ return `${toolName}: ok`;
180
+ const text = typeof value === 'string' ? value : safeJson(value);
181
+ return maybeSpill(text, `${toolName}.txt`, artifacts, spillBytes);
182
+ }
183
+ async function maybeSpill(text, nameHint, artifacts, spillBytes) {
184
+ const size = Buffer.byteLength(text, 'utf8');
185
+ if (size <= spillBytes)
186
+ return text;
187
+ const written = await artifacts.write(nameHint, text);
188
+ return spillPreview(text, written);
189
+ }
190
+ function safeJson(value) {
191
+ try {
192
+ return JSON.stringify(value);
193
+ }
194
+ catch {
195
+ return String(value);
196
+ }
197
+ }
198
+ function toolError(message, code, hint) {
199
+ const lines = [`error: ${message}`, `code: ${code}`];
200
+ if (hint)
201
+ lines.push(`hint: ${hint}`);
202
+ return {
203
+ isError: true,
204
+ content: [{ type: 'text', text: lines.join('\n') }],
205
+ structuredContent: { error: { code, message, hint } },
206
+ };
207
+ }
208
+ function ok(id, result) {
209
+ return { jsonrpc: '2.0', id, result };
210
+ }
211
+ function rpcError(id, code, message) {
212
+ return { jsonrpc: '2.0', id, error: { code, message } };
213
+ }
214
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/cli/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * MCP tool registry.
3
+ *
4
+ * Each tool: a JSON Schema for the model + a thin handler that maps
5
+ * the arguments onto the existing dispatcher. The dispatcher already
6
+ * speaks `{ cmd, args }` and throws `CraftdriverError` with stable
7
+ * codes — we reuse it untouched so library, CLI, and MCP all behave
8
+ * identically when given the same selector.
9
+ *
10
+ * Compact set per §6 of the AI-productivity plan: ~12 tools, one-line
11
+ * descriptions, merged variants behind options. `browser_trace` is
12
+ * intentionally absent in v1 — it ships with Item 7 (trace summaries).
13
+ */
14
+ import type { DispatchContext } from '../dispatcher.js';
15
+ export interface ToolDef {
16
+ name: string;
17
+ description: string;
18
+ /** JSON Schema, restricted to types MCP clients reliably support. */
19
+ inputSchema: Record<string, unknown>;
20
+ /** Map MCP args → dispatcher args. Defaults to identity. */
21
+ toDispatch: (args: Record<string, unknown>) => {
22
+ cmd: string;
23
+ args: Record<string, unknown>;
24
+ };
25
+ /** When true, this action mutates page state — caller should take a snapshot. */
26
+ mutating: boolean;
27
+ /** When true, the result includes binary content (image bytes). */
28
+ returnsImage?: boolean;
29
+ }
30
+ export declare const TOOLS: ToolDef[];
31
+ export declare function getTool(name: string): ToolDef | undefined;
32
+ /** Run a tool against the dispatcher. Throws CraftdriverError on failure. */
33
+ export declare function runTool(ctx: DispatchContext, tool: ToolDef, args: Record<string, unknown>): Promise<unknown>;
34
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/cli/mcp/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,4DAA4D;IAC5D,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;IAC9F,iFAAiF;IACjF,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAUD,eAAO,MAAM,KAAK,EAAE,OAAO,EAkO1B,CAAC;AAIF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAEzD;AAED,6EAA6E;AAC7E,wBAAsB,OAAO,CAC3B,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAGlB"}