@easonwumac/computer-linker 0.1.2

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 (82) hide show
  1. package/CHANGELOG.md +230 -0
  2. package/LICENSE +21 -0
  3. package/README.md +539 -0
  4. package/SECURITY.md +48 -0
  5. package/dist/api.d.ts +2 -0
  6. package/dist/api.js +360 -0
  7. package/dist/audit.d.ts +70 -0
  8. package/dist/audit.js +102 -0
  9. package/dist/capabilities.d.ts +98 -0
  10. package/dist/capabilities.js +718 -0
  11. package/dist/capability-policy.d.ts +22 -0
  12. package/dist/capability-policy.js +103 -0
  13. package/dist/chatgpt.d.ts +167 -0
  14. package/dist/chatgpt.js +561 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +4621 -0
  17. package/dist/client-smoke.d.ts +44 -0
  18. package/dist/client-smoke.js +639 -0
  19. package/dist/client.d.ts +217 -0
  20. package/dist/client.js +357 -0
  21. package/dist/codex-runs.d.ts +35 -0
  22. package/dist/codex-runs.js +66 -0
  23. package/dist/computer-contract.d.ts +33 -0
  24. package/dist/computer-contract.js +384 -0
  25. package/dist/computer-operation-registry.d.ts +45 -0
  26. package/dist/computer-operation-registry.js +179 -0
  27. package/dist/config-diagnostics.d.ts +11 -0
  28. package/dist/config-diagnostics.js +185 -0
  29. package/dist/config.d.ts +10 -0
  30. package/dist/config.js +69 -0
  31. package/dist/history-insights.d.ts +132 -0
  32. package/dist/history-insights.js +457 -0
  33. package/dist/http-auth.d.ts +3 -0
  34. package/dist/http-auth.js +15 -0
  35. package/dist/mcp-surface.d.ts +5 -0
  36. package/dist/mcp-surface.js +25 -0
  37. package/dist/oauth-provider.d.ts +52 -0
  38. package/dist/oauth-provider.js +325 -0
  39. package/dist/package-metadata.d.ts +7 -0
  40. package/dist/package-metadata.js +24 -0
  41. package/dist/permissions.d.ts +43 -0
  42. package/dist/permissions.js +150 -0
  43. package/dist/platform-shell.d.ts +28 -0
  44. package/dist/platform-shell.js +124 -0
  45. package/dist/processes.d.ts +50 -0
  46. package/dist/processes.js +178 -0
  47. package/dist/profile.d.ts +159 -0
  48. package/dist/profile.js +416 -0
  49. package/dist/screenshot.d.ts +47 -0
  50. package/dist/screenshot.js +302 -0
  51. package/dist/search.d.ts +34 -0
  52. package/dist/search.js +340 -0
  53. package/dist/security.d.ts +10 -0
  54. package/dist/security.js +108 -0
  55. package/dist/sensitive-files.d.ts +4 -0
  56. package/dist/sensitive-files.js +96 -0
  57. package/dist/server.d.ts +9 -0
  58. package/dist/server.js +713 -0
  59. package/dist/service.d.ts +125 -0
  60. package/dist/service.js +486 -0
  61. package/dist/sessions.d.ts +26 -0
  62. package/dist/sessions.js +34 -0
  63. package/dist/tunnels.d.ts +161 -0
  64. package/dist/tunnels.js +1243 -0
  65. package/dist/workspace-operations.d.ts +170 -0
  66. package/dist/workspace-operations.js +3219 -0
  67. package/dist/workspaces.d.ts +61 -0
  68. package/dist/workspaces.js +353 -0
  69. package/docs/agent-instructions.md +65 -0
  70. package/docs/alpha-evidence.example.json +54 -0
  71. package/docs/api-compatibility.md +56 -0
  72. package/docs/architecture.md +561 -0
  73. package/docs/chatgpt-setup.md +397 -0
  74. package/docs/client-recipes.md +98 -0
  75. package/docs/client-sdk.md +163 -0
  76. package/docs/computer-operation-v1.schema.json +143 -0
  77. package/docs/manual-test-plan.md +322 -0
  78. package/docs/product-spec.md +911 -0
  79. package/docs/release-checklist.md +285 -0
  80. package/docs/service-mode.md +99 -0
  81. package/examples/minimal-mcp-client.mjs +114 -0
  82. package/package.json +87 -0
@@ -0,0 +1,397 @@
1
+ # ChatGPT Setup
2
+
3
+ Computer Linker can be tested from ChatGPT as a remote MCP server when the
4
+ ChatGPT workspace supports custom MCP apps / developer mode.
5
+
6
+ ChatGPT cannot reach a server that only listens on `localhost` from your
7
+ computer. For cloud-hosted ChatGPT clients, expose Computer Linker through an
8
+ HTTPS URL. Cloudflare custom hostnames should be saved as `publicBaseUrl`
9
+ before OAuth client setup; Tailscale Funnel URLs are detected and saved by
10
+ `start C:\Projects\my-app --tunnel tailscale`.
11
+
12
+ ## 1. Install
13
+
14
+ Commands below use the installed CLI:
15
+
16
+ ```powershell
17
+ npm install -g @easonwumac/computer-linker
18
+ ```
19
+
20
+ From this checkout, run `npm install` once and replace `computer-linker` with
21
+ `npm run dev --`.
22
+
23
+ ## 2. Choose A Workspace
24
+
25
+ Pass the folder to `start`. Computer Linker creates the config, owner token,
26
+ and workspace entry automatically before the server starts:
27
+
28
+ ```powershell
29
+ computer-linker start C:\Projects\my-app
30
+ ```
31
+
32
+ If you want to configure without starting the server yet, use `setup`:
33
+
34
+ ```powershell
35
+ computer-linker setup C:\Projects\my-app --show-token
36
+ ```
37
+
38
+ Permission meaning:
39
+
40
+ - `read`: list, read, search, inspect project/git metadata
41
+ - `write`: write, edit, patch, move, delete, stage, commit
42
+ - `shell`: run package scripts, commands, and managed shell processes
43
+ - `codex`: invoke the local `codex` CLI in this workspace
44
+
45
+ `start <folder>` and `setup <folder>` default to normal development access:
46
+ file edits plus approved project commands. Use `--read-only` when ChatGPT
47
+ should inspect without editing or running project commands. Add `--write`,
48
+ `--shell`, or `--codex` separately only when you need finer control.
49
+
50
+ When `start` or `setup` enables `--shell` or `--codex`, Computer Linker adds a
51
+ default execution policy. The default policy allows common project commands
52
+ such as `npm *`, `pnpm *`, `yarn *`, `bun *`, `node *`, `npx *`, and `git *`;
53
+ `codex *` is added only for Codex-enabled scopes. Runtime and output are capped.
54
+
55
+ Use `computer-linker status` for a quick check and `computer-linker doctor`
56
+ before exposing any workspace with `shell` or `codex`; those operations start
57
+ in the workspace but are not OS-level filesystem sandboxes.
58
+
59
+ ## 3. Choose A Tunnel
60
+
61
+ Cloudflare Quick Tunnel:
62
+
63
+ ```powershell
64
+ computer-linker start C:\Projects\my-app --tunnel cloudflare
65
+ ```
66
+
67
+ Tailscale Funnel:
68
+
69
+ ```powershell
70
+ computer-linker start C:\Projects\my-app --tunnel tailscale
71
+ ```
72
+
73
+ You do not need to know `https://<machine>.<tailnet>.ts.net` before setup.
74
+ Computer Linker detects that URL from `tailscale funnel` output or Tailscale
75
+ status, prints the public MCP URL, and saves the detected origin as
76
+ `publicBaseUrl`.
77
+ The `*.ts.net` hostname is public only when Tailscale reports Funnel as enabled;
78
+ plain Tailscale DNS or Serve remains tailnet-only.
79
+
80
+ OpenAI Secure MCP Tunnel:
81
+
82
+ ```powershell
83
+ $env:CONTROL_PLANE_API_KEY = "sk-..."
84
+ computer-linker start C:\Projects\my-app --tunnel openai --tunnel-id tunnel_...
85
+ ```
86
+
87
+ This mode does not create a public MCP URL and does not need `publicBaseUrl`.
88
+ In ChatGPT connector settings, choose **Tunnel** and select or paste the
89
+ `tunnel_...` id. Do not paste the Computer Linker bearer token into ChatGPT
90
+ Tunnel mode; the local `tunnel-client` forwards the owner token to the private
91
+ local MCP server. Computer Linker downloads the official OpenAI
92
+ `tunnel-client` release into its config directory on first use, verifies the
93
+ asset with `SHA256SUMS.txt`, and then reuses that managed binary. It does not
94
+ search the Desktop for `tunnel-client.exe`; pass `--tunnel-client` or set
95
+ `COMPUTER_LINKER_OPENAI_TUNNEL_CLIENT` only when you intentionally want a
96
+ pinned executable.
97
+
98
+ If ChatGPT or the tunnel control plane returns `401 Access denied: this tunnel
99
+ requires an active organization context`, the local Computer Linker server is
100
+ usually not the failing component. Check that the API key belongs to the
101
+ Platform organization that owns or can use the tunnel, that the organization
102
+ has Tunnels Read + Use permission, and that the tunnel is associated with the
103
+ target ChatGPT workspace when testing from ChatGPT. If you are using an API
104
+ surface that supports explicit organization selection, send the matching
105
+ OpenAI organization context for the tunnel owner.
106
+
107
+ If you run the HTTP server and tunnel separately:
108
+
109
+ ```powershell
110
+ computer-linker start C:\Projects\my-app --url https://your-public-origin.example.com
111
+ ```
112
+
113
+ When a running tunnel reports a public URL, persist that HTTPS origin with:
114
+
115
+ ```powershell
116
+ computer-linker config set-public-url https://your-public-origin.example.com
117
+ ```
118
+
119
+ You can still use `COMPUTER_LINKER_PUBLIC_BASE_URL` as a temporary override,
120
+ but `config set-public-url` is easier for repeated ChatGPT testing.
121
+
122
+ For Cloudflare, Tailscale Funnel, or a custom HTTPS reverse proxy, the public
123
+ MCP endpoint is:
124
+
125
+ ```text
126
+ https://your-public-origin.example.com/mcp
127
+ ```
128
+
129
+ ## 4. Verify Readiness
130
+
131
+ ```bash
132
+ computer-linker status
133
+ computer-linker status --details
134
+ computer-linker status --json
135
+ computer-linker doctor
136
+ computer-linker doctor --json
137
+ computer-linker doctor --fix
138
+ computer-linker client chatgpt url
139
+ computer-linker client chatgpt smoke
140
+ computer-linker client chatgpt verify --mode coding
141
+ computer-linker client chatgpt verify --mode coding --json
142
+ computer-linker client chatgpt profile --mode coding
143
+ ```
144
+
145
+ The capabilities endpoint should report:
146
+
147
+ - `name: computer-linker`
148
+ - `exposure.readyForTunnel: true`
149
+ - no critical security findings
150
+ - `connectionProfile.http.publicMcpUrl` equal to your HTTPS `/mcp` URL
151
+
152
+ The CLI `status` command prints the short daily readiness view: connection mode,
153
+ local MCP URL, workspace/tunnel summary, readiness, and the next few actions.
154
+ Use `status --details` when you need the full workspace list, warnings, running
155
+ tunnel rows, and all next actions. `doctor` prints the full diagnostic view, including
156
+ `publicMcpUrl`, JSON API URLs, security findings, startup readiness, local tool
157
+ paths, missing
158
+ required/recommended tools, and suggested next actions.
159
+ Use `doctor --json` when a script or another model needs to verify readiness
160
+ without parsing terminal text. The `toolReadiness` block gives ChatGPT a compact
161
+ way to explain whether `rg`, `git`, `codex`, Node package managers, or shell
162
+ tools are available and how to install the missing required/recommended ones on
163
+ the current platform. The `startup` block lists CLI-first foreground HTTP,
164
+ stdio, and OS service startup modes plus service profile and install dry-run
165
+ commands.
166
+ Use `tunnel status --json` when the setup flow only needs tunnel provider
167
+ contracts, available commands, and the currently configured or detected public
168
+ URL.
169
+
170
+ `client chatgpt verify` is the ChatGPT-specific readiness gate. It checks the HTTPS
171
+ public base URL, `/mcp` URL, owner-token auth, the minimal four-tool surface,
172
+ workspace availability, security findings, tunnel hints, and whether workspace
173
+ permissions match the intended mode:
174
+
175
+ - `safe`: read/search/history/git-read style access only
176
+ - `coding`: write access is acceptable; shell/Codex access is reported as a
177
+ warning that must be reviewed
178
+ - `full`: write/shell/Codex are allowed but still called out as warnings
179
+
180
+ Use `client chatgpt verify --json` for automated setup checks or when another agent
181
+ needs a structured report before attempting connection.
182
+
183
+ `client chatgpt url` is the shortest path when you only need the fields to paste into
184
+ ChatGPT. It prints the MCP server URL, the bearer Authorization header shape,
185
+ the effective public URL source (`configured` or `running-tunnel`), warnings,
186
+ and the next action if no public HTTPS URL is configured. Use
187
+ `client chatgpt url --show-token` only on a trusted setup screen.
188
+
189
+ `client chatgpt smoke` performs a live connection check against the configured
190
+ `publicBaseUrl` or a URL passed with `--url`. For public HTTPS URLs it validates
191
+ MCP `/mcp` initialize, tools/list, `get_computer_info`, and one read-only
192
+ `computer_operation` using the owner token, which matches the default MCP-only
193
+ public exposure. For local loopback testing with `--allow-http`, it also
194
+ validates `/healthz`, authenticated `/api/v1/capabilities`,
195
+ `get_computer_info`, and one read-only `computer_operation` `file.list`. Use
196
+ `client chatgpt smoke --json` for scripts. Use `--allow-http` only for local
197
+ loopback testing:
198
+
199
+ ```bash
200
+ computer-linker client chatgpt smoke --url http://127.0.0.1:3939/mcp --allow-http
201
+ ```
202
+
203
+ Use `status`, `doctor`, `tunnel status`, `history`, and `client chatgpt smoke`
204
+ for local readiness checks. Use `client chatgpt profile`, `manifest`,
205
+ `connector`, or `files` to export the exact fields to paste into ChatGPT: app
206
+ name, server URL, connection type, auth type, bearer-token guidance, OAuth
207
+ metadata URLs, model instructions, and workflow recipes.
208
+
209
+ `client chatgpt profile` prints a stable JSON setup profile for ChatGPT or
210
+ another hosted MCP client. It includes the MCP server URL, auth options,
211
+ recommended tool flow, operation envelope example, `modelGuide`,
212
+ `workflowRecipes`, model instructions, and warnings when the current config is
213
+ not reachable from ChatGPT.
214
+
215
+ Raw JSON clients should use the generic setup action before selecting client-
216
+ specific exports:
217
+
218
+ ```json
219
+ {
220
+ "action": "client_setup"
221
+ }
222
+ ```
223
+
224
+ The ChatGPT profile export includes `connectProfile`, a redacted ready-to-paste
225
+ setup block with `appName`, `serverUrl`, auth guidance, smoke commands, export
226
+ commands, and the first prompt. It also includes `wizard.overallStatus`, `wizard.currentStepId`,
227
+ `wizard.effectiveMcpServerUrl`, `wizard.detectedPublicUrl`, and ordered setup
228
+ steps so a UI or hosted model can show the next required action without
229
+ reimplementing readiness checks. `wizard.detectedPublicUrl` is populated from
230
+ currently running Computer Linker tunnel processes, even before that URL is
231
+ saved as `publicBaseUrl`. A detected HTTPS tunnel URL can make bearer-token
232
+ ChatGPT setup ready immediately; OAuth discovery remains disabled until the
233
+ same origin is saved as `publicBaseUrl`.
234
+
235
+ Use the same mode in `client chatgpt verify` and `client chatgpt profile`:
236
+
237
+ - `safe`: generated instructions stay read-only, even if a workspace exposes
238
+ elevated operations
239
+ - `coding`: generated instructions allow file edits and coding workflows, while
240
+ treating shell/Codex as higher-risk operations
241
+ - `full`: generated instructions allow write/shell/process/package/git/Codex
242
+ workflows when `allowedOperations` permits them, with warnings for destructive
243
+ or external actions
244
+
245
+ Local JSON API check:
246
+
247
+ ```bash
248
+ curl http://127.0.0.1:3939/api/v1/capabilities \
249
+ -H "Authorization: Bearer <ownerToken>"
250
+ ```
251
+
252
+ ## 6. Add To ChatGPT
253
+
254
+ Generate the connector profile:
255
+
256
+ ```bash
257
+ computer-linker client chatgpt url
258
+ computer-linker client chatgpt profile --mode coding
259
+ computer-linker client chatgpt profile --mode coding --url https://your-public-origin.example.com
260
+ computer-linker client chatgpt manifest --mode coding
261
+ computer-linker client chatgpt connector --mode coding
262
+ computer-linker client chatgpt files ./chatgpt-config --mode coding
263
+ ```
264
+
265
+ The output directory contains `chatgpt-profile.json`,
266
+ `chatgpt-app-manifest.json`, `chatgpt-connector-config.json`,
267
+ `operation-registry.json`, and `chatgpt-index.json`. Give GPT-style clients the
268
+ operation registry when they need exact operation names, permissions, payload
269
+ fields, and safety boundaries instead of guessing function shapes.
270
+
271
+ Use `--url https://...` when `tunnel status` detected a running tunnel URL but
272
+ you do not want to write it to config yet. This changes the exported MCP URL
273
+ only; save the same origin as `publicBaseUrl` before relying on OAuth discovery
274
+ metadata. When a Computer Linker-managed tunnel is running, the CLI exports use
275
+ the detected tunnel origin for the exported MCP URL and include a warning if the
276
+ origin is not saved.
277
+
278
+ Use these fields in ChatGPT developer mode / custom MCP app setup:
279
+
280
+ - App name: `appManifest.appName`, or `appName` from `--format manifest`
281
+ - MCP server URL: `mcpServerUrl`
282
+ - Auth: OAuth when the client supports MCP OAuth discovery, or bearer token
283
+ from `auth.bearer.header` / `auth.bearerHeader` when the client allows custom
284
+ headers
285
+ - Model instructions: use `modelGuide` for the entrypoint and operation-choice
286
+ rules, and `workflowRecipes` for common coding flows
287
+
288
+ For bearer-token clients:
289
+
290
+ ```text
291
+ Authorization: Bearer <ownerToken>
292
+ ```
293
+
294
+ or:
295
+
296
+ ```text
297
+ x-computer-linker-token: <ownerToken>
298
+ ```
299
+
300
+ The default output redacts the owner token. For a trusted local setup screen,
301
+ print the full token explicitly:
302
+
303
+ ```bash
304
+ computer-linker client chatgpt profile --mode coding --show-token
305
+ computer-linker client chatgpt connector --mode coding --show-token
306
+ ```
307
+
308
+ ## First Prompt To Test
309
+
310
+ Ask ChatGPT:
311
+
312
+ ```text
313
+ Call get_computer_info, choose the app scope if present, run computer_operation op=code.context, then call get_operation_history with view=last.
314
+ ```
315
+
316
+ Expected flow:
317
+
318
+ 1. `get_computer_info`
319
+ 2. `computer_operation` with `scope: "app"` and `op: "code.context"`
320
+ 3. `get_operation_history` with `view: "last"`
321
+
322
+ The default MCP surface intentionally exposes only `get_computer_info`,
323
+ `computer_operation`, and `get_operation_history`. Older clients can opt in to
324
+ the legacy workspace tools with
325
+ `COMPUTER_LINKER_MCP_TOOL_SURFACE=compatibility`; that mode exposes
326
+ `get_capabilities`, `list_workspaces`, `open_workspace`,
327
+ `workspace_operation`, `read`, `ls`, `grep`, `glob`, and `create_file`.
328
+
329
+ The generated profile also includes:
330
+
331
+ - `modelGuide.mcpEntrypoint`: the MCP tool name, currently
332
+ `computer_operation`
333
+ - `modelGuide.jsonApiEntrypoint`: the local/trusted-private JSON API fallback,
334
+ `POST /api/v1/control` with `action: "computer_operation"`; default public
335
+ tunnel exposure is MCP-only, so public tunnel URLs block this route unless
336
+ the operator deliberately exposes the JSON API through a private route
337
+ - `operation_registry`: optional JSON API discovery action for a smaller,
338
+ filterable generic `computer_operation` contract when a client does not want
339
+ to parse all capabilities. Use `workspace_operation_registry` or
340
+ `operation_registry` with `contract: "workspace"` only for compatibility
341
+ clients that still call `workspace_operation`
342
+ - `modelGuide.operationSelection`: short intent-to-op guidance for GPT clients
343
+ - `workflowRecipes`: ready-made flows such as `connect_and_orient`,
344
+ `search_and_read`, `implement_and_verify`, and `codex_assisted_change`
345
+
346
+ For a coding task, ChatGPT can then use `computer_operation` with ops such as
347
+ `code.context`, `code.search_symbols`, `file.search`, `file.read`,
348
+ `file.patch`, `git.diff`, `package.run`, `command.run`, and, only when enabled
349
+ for that workspace, `codex.run` or `codex.start`. When a run fails or the
350
+ conversation loses context, ask it to call
351
+ `get_operation_history` with `view: "last"` first, then `view: "timeline"`,
352
+ `view: "connections"` for tunnel/session/request correlation,
353
+ `view: "failed_replay"`, `view: "sessions"` for compact session grouping, or
354
+ `view: "debug_bundle"` before retrying. In `failed_replay`, ChatGPT can submit
355
+ `replayable: true` request templates directly; when `requiresInput` is present,
356
+ it must ask for or reconstruct the missing command or Codex prompt before
357
+ retrying. After using `codex.run` or `codex.start`, ChatGPT can call
358
+ `codex.read` with the returned workflow id to inspect the stored run summary
359
+ later.
360
+
361
+ If the connector is not reachable yet, use the same history insight locally:
362
+
363
+ ```bash
364
+ computer-linker history --view last
365
+ computer-linker history --view debug_bundle --workspace app --json --output ./computer-linker-debug-bundle.json
366
+ ```
367
+
368
+ Tell GPT-style clients to prefer this generic operation envelope:
369
+
370
+ ```json
371
+ {
372
+ "scope": "app",
373
+ "op": "file.search",
374
+ "target": ".",
375
+ "input": { "query": "TODO", "glob": "*.ts" },
376
+ "options": { "maxResults": 20 }
377
+ }
378
+ ```
379
+
380
+ ## Troubleshooting
381
+
382
+ - If ChatGPT cannot connect, confirm the `/mcp` URL is HTTPS and reachable from
383
+ outside your machine.
384
+ - If ChatGPT shows the connector but never calls tools, try a different
385
+ ChatGPT model/lane and check `computer-linker history --view last` or tunnel
386
+ metrics before changing tunnel settings. Some ChatGPT accounts or model lanes
387
+ can show the app while not routing actions to MCP tools.
388
+ - If OAuth metadata is wrong, restart HTTP mode after changing `publicBaseUrl`
389
+ or owner-token state.
390
+ - If operations are missing, call `get_computer_info`; each scope includes
391
+ `allowedOperations` and the generic `operationRegistry`.
392
+ - If a write, shell, or Codex action is blocked, inspect
393
+ `get_computer_info.scopes[].allowedOperations` and
394
+ `get_computer_info.operationRegistry` before retrying.
395
+ - If ChatGPT refuses broad writes, shell commands, or remote Git operations,
396
+ treat it as a host safety decision. Prefer `file.create`, `file.patch`, and
397
+ local terminal follow-up for publishing or remote service changes.
@@ -0,0 +1,98 @@
1
+ # MCP Client Recipes
2
+
3
+ Use `computer-linker client setup` as the source of truth for the current
4
+ connection details. Use `--show-token` only on a trusted local screen.
5
+
6
+ ## Local MCP Clients
7
+
8
+ Start Computer Linker:
9
+
10
+ ```powershell
11
+ computer-linker start C:\Projects\my-app
12
+ ```
13
+
14
+ Configure the client:
15
+
16
+ - URL: `http://127.0.0.1:3939/mcp`
17
+ - Auth: `Authorization: Bearer <ownerToken>`
18
+ - Agent instructions: [agent-instructions.md](agent-instructions.md)
19
+
20
+ Verify:
21
+
22
+ ```powershell
23
+ computer-linker diagnose client --local
24
+ computer-linker client smoke --allow-http --url http://127.0.0.1:3939/mcp
25
+ ```
26
+
27
+ ## OpenAI Secure MCP Tunnel
28
+
29
+ Create the tunnel in OpenAI Platform, then start Computer Linker:
30
+
31
+ ```powershell
32
+ $env:CONTROL_PLANE_API_KEY = "sk-..."
33
+ computer-linker start C:\Projects\my-app --tunnel openai --tunnel-id tunnel_...
34
+ ```
35
+
36
+ In the client, choose Tunnel mode and select or paste the `tunnel_...` id. Do
37
+ not paste the Computer Linker bearer token into OpenAI Tunnel mode; the local
38
+ tunnel client forwards it to the local MCP server.
39
+
40
+ Verify:
41
+
42
+ ```powershell
43
+ computer-linker diagnose client
44
+ computer-linker history --view connections
45
+ ```
46
+
47
+ ## Tailscale Funnel
48
+
49
+ ```powershell
50
+ computer-linker start C:\Projects\my-app --tunnel tailscale
51
+ ```
52
+
53
+ Computer Linker detects the Funnel HTTPS origin and saves it as
54
+ `publicBaseUrl`. Configure the client with the printed HTTPS URL plus `/mcp`
55
+ and the bearer header from:
56
+
57
+ ```powershell
58
+ computer-linker client setup --show-token
59
+ ```
60
+
61
+ ## Cloudflare
62
+
63
+ Quick tunnel:
64
+
65
+ ```powershell
66
+ computer-linker start C:\Projects\my-app --tunnel cloudflare
67
+ ```
68
+
69
+ Owned hostname:
70
+
71
+ ```powershell
72
+ computer-linker start C:\Projects\my-app --url https://mcp.your-domain.com --tunnel cloudflare
73
+ ```
74
+
75
+ Configure the client with `https://mcp.your-domain.com/mcp` and the bearer
76
+ header from `computer-linker client setup --show-token`.
77
+
78
+ ## Minimal SDK Client
79
+
80
+ With Computer Linker already running:
81
+
82
+ ```powershell
83
+ $env:COMPUTER_LINKER_MCP_URL = "http://127.0.0.1:3939/mcp"
84
+ $env:COMPUTER_LINKER_TOKEN = "<ownerToken>"
85
+ node examples/minimal-mcp-client.mjs
86
+ ```
87
+
88
+ The example initializes MCP, lists tools, calls `get_computer_info`, and runs a
89
+ read-only `computer_operation`.
90
+
91
+ ## Agent Prompt
92
+
93
+ Use [agent-instructions.md](agent-instructions.md) when the client accepts a
94
+ system or instruction prompt. The short version:
95
+
96
+ ```text
97
+ First call get_computer_info. Use computer_operation with {scope, op, target, input, options}. Stay inside configured scopes. Prefer read-only context/search/diff before write or command operations.
98
+ ```
@@ -0,0 +1,163 @@
1
+ # Client SDK Contract
2
+
3
+ Computer Linker exposes a small TypeScript client for MCP hosts, local
4
+ automation, and compatibility connectors. Prefer the generic
5
+ computer contract for new integrations:
6
+
7
+ ```ts
8
+ import { ComputerLinkerClient } from "@easonwumac/computer-linker";
9
+
10
+ const client = new ComputerLinkerClient({
11
+ baseUrl: "http://127.0.0.1:3939/api/v1",
12
+ ownerToken: process.env.COMPUTER_LINKER_TOKEN,
13
+ });
14
+
15
+ await client.getComputerInfo();
16
+ await client.clientSetup();
17
+ await client.smoke();
18
+ const result = await client.computerOperation<{ ok: boolean; data?: unknown }>({
19
+ scope: "app",
20
+ op: "file.search",
21
+ target: "src",
22
+ input: { query: "TODO" },
23
+ options: { maxResults: 20 },
24
+ });
25
+ if (result.ok) console.log(result.data);
26
+ ```
27
+
28
+ The SDK talks to the JSON API under `/api/v1`. Treat that API as a local or
29
+ trusted-private automation surface. Public tunnels created by `computer-linker
30
+ start --tunnel ...` and `computer-linker expose ...` default to MCP-only, so
31
+ public hosts expose `/mcp` but return 404 for `/api` and `/healthz`.
32
+ Use the SDK against `connectionProfile.http.localApiUrl`, or against a
33
+ deliberately private reverse proxy where you have chosen to expose the JSON API.
34
+
35
+ The outer shape stays stable:
36
+
37
+ ```ts
38
+ {
39
+ scope: "app",
40
+ op: "code.context" | "file.read" | "file.search" | "git.diff" | "package.run" | "command.run" | "codex.run" | "screen.list",
41
+ target: "src/index.ts",
42
+ input: {},
43
+ options: {}
44
+ }
45
+ ```
46
+
47
+ For raw JSON clients using the single control endpoint, use the same envelope at
48
+ the top level with `action: "computer_operation"`:
49
+
50
+ ```json
51
+ {
52
+ "action": "computer_operation",
53
+ "scope": "app",
54
+ "op": "file.read",
55
+ "target": "README.md",
56
+ "input": {},
57
+ "options": { "maxBytes": 65536 }
58
+ }
59
+ ```
60
+
61
+ Use `input` for operation data and `options` for limits, filters, and runtime
62
+ controls. The response is always a standard operation result envelope with
63
+ `ok`, `operationId`, `scope`, `op`, `startedAt`, `durationMs`, `data` on
64
+ success, and `error` on failure. Computer Linker still enforces the configured
65
+ workspace boundary on the server side.
66
+ Use `getComputerInfo()` to discover `computerOperationRegistry`; new clients
67
+ should prefer its dotted op names such as `code.context`, `file.read`,
68
+ `file.search`, `git.diff`, `package.run`, `command.run`, `process.start`,
69
+ `codex.run`, `screen.capture`, and `history.last`.
70
+ The registry is current-machine aware for screen capture: it only advertises
71
+ display, window, or process capture operations that the local provider reports
72
+ as supported.
73
+ The stable request/result bundle is also published as JSON Schema at
74
+ `docs/computer-operation-v1.schema.json` for clients that validate contracts
75
+ outside TypeScript.
76
+
77
+ Common helpers are wrappers around the same envelope:
78
+
79
+ ```ts
80
+ await client.getComputerInfo();
81
+ await client.clientSetup();
82
+ await client.smoke();
83
+ await client.computerOperation({ scope: "app", op: "file.read", target: "README.md" });
84
+ await client.getOperationHistory({ scope: "app", view: "last", limit: 20 });
85
+ await client.listWorkspaces();
86
+ await client.connectReadiness({ registry: { category: "search" } });
87
+ await client.chatGptSetup("coding");
88
+ await client.read("app", "README.md", { maxBytes: 65536 });
89
+ await client.search("app", "runWorkspaceOperation", { glob: "src/**/*.ts" });
90
+ await client.write("app", "notes/todo.md", "- ship\n");
91
+ await client.command("app", "npm test", { timeoutSeconds: 120 });
92
+ await client.screenList("app");
93
+ await client.screenCapture("app", "primary", { returnMode: "fileRef" });
94
+ await client.git("app", "git_diff", { paths: ["src/client.ts"] });
95
+ await client.codex("app", "Fix the failing tests");
96
+ await client.operationRegistry({ category: "search", query: "ripgrep" });
97
+ await client.workspaceOperationRegistry({ category: "search", query: "ripgrep" });
98
+ await client.historyLast({ workspaceId: "app", limit: 20 });
99
+ await client.workspaceHistoryInsight("app", { view: "timeline", maxResults: 20 });
100
+ await client.historySessions({ workspaceId: "app", limit: 20 });
101
+ ```
102
+
103
+ `workspaceOperation()` is kept for older integrations that already send the MCP
104
+ style nested envelope. `operation()` is kept for older JSON clients using
105
+ workspace operation names. New JSON clients should use `computerOperation()` or
106
+ `action: "computer_operation"`.
107
+
108
+ For generic MCP/client integrations, the recommended flow is:
109
+
110
+ 1. `getComputerInfo()`
111
+ 2. `clientSetup()` when URL/auth setup details are needed
112
+ 3. `smoke()` when validating that the local or trusted-private HTTP API and MCP
113
+ endpoint are reachable from the SDK process
114
+ 4. `computerOperation({ scope, op, target, input, options })`
115
+ 5. `getOperationHistory({ scope, view })` when auditing actions
116
+ 6. compatibility only: `getCapabilities()`, `workspaceOperationRegistry()`,
117
+ `operation()`, or `workspaceOperation()`
118
+
119
+ This keeps clients from learning many endpoints while still covering file
120
+ operations, search, git, commands, Codex workflows, and audit history.
121
+ `connectReadiness()` is a client-side aggregate over generic MCP client setup,
122
+ workspace list, and operation registry contracts. It
123
+ returns `ready`, `status`, `blockingReasons`, `warnings`, `nextActions`,
124
+ `recommendedWorkspace`, and the source payloads so GPT clients can decide
125
+ whether to connect, show setup steps, or continue with coding operations.
126
+ `smoke()` is the SDK equivalent of `computer-linker client smoke` for local or
127
+ trusted-private integrations. It checks `/healthz`, `/api/v1/capabilities`,
128
+ authenticated `get_computer_info`, one read-only `computer_operation`
129
+ `file.list` in a readable scope, and an MCP SDK flow on `/mcp`: initialize,
130
+ tools/list, `get_computer_info`, and one read-only `computer_operation`.
131
+ It then returns a `computer-linker-client-smoke` report with `ready`, `checks`,
132
+ `blockingReasons`, `warnings`, and `nextActions`. Public tunnel smoke remains
133
+ MCP-only by default because public hosts expose `/mcp` and intentionally block
134
+ the JSON API, but the MCP tool flow still runs. The CLI and SDK use the same
135
+ generic smoke contract;
136
+ ChatGPT-specific smoke helpers remain compatibility commands layered beside it.
137
+ `clientSetup()` separates local and remote readiness: `localReady`/`ready` cover
138
+ stdio or loopback MCP usage, while `remoteReady` and `remoteBlockingReasons`
139
+ describe what remains before a cloud or tunnel client can connect. It also
140
+ returns `firstPrompt` and `agentInstructions`, which are the same generic
141
+ copy-pasteable MCP agent guidance printed by
142
+ `computer-linker client setup --details`.
143
+ `operationRegistry()` returns the stable `computer_operation` contract,
144
+ filtered dotted operation metadata, required capabilities, permissions,
145
+ boundaries, schemas, and examples. `workspaceOperationRegistry()` returns the
146
+ older workspace-operation registry for clients that still call
147
+ `workspace_operation` or the JSON `operation` compatibility action.
148
+ `chatGptSetup()` is a compatibility helper for ChatGPT-specific setup screens.
149
+ It returns the same redacted client-specific setup status used by CLI/API clients,
150
+ including `connectProfile.serverUrl`, redacted auth guidance, first prompt,
151
+ profile commands, smoke commands, `wizard.currentStepId`, and ordered setup
152
+ steps for product UIs.
153
+
154
+ ChatGPT connector profiles add two higher-level guidance fields on top of the
155
+ same envelope:
156
+
157
+ - `modelGuide`: explains that MCP clients call `computer_operation`, while
158
+ local or trusted-private raw JSON clients call `POST /api/v1/control` with
159
+ `action: "computer_operation"`; default public tunnel exposure is MCP-only
160
+ and blocks JSON API routes. Legacy JSON clients can still use
161
+ `action: "operation"` or `workspace_operation`
162
+ - `workflowRecipes`: gives ready-made flows for orientation, search/read,
163
+ implementation, verification, history, and Codex-assisted coding