@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,561 @@
1
+ # Computer Linker Architecture
2
+
3
+ The product boundary is defined in [product-spec.md](product-spec.md). This
4
+ architecture should serve that spec: a local computer MCP service for controlled
5
+ file access, commands, Codex, screenshots, computer info, and audit history.
6
+ ChatGPT-specific setup is a client helper, not the product axis.
7
+
8
+ ## Product Name
9
+
10
+ The product is named **Computer Linker**. It intentionally does not reuse DevSpace.
11
+
12
+ ## Mental Model
13
+
14
+ One computer runs one Computer Linker MCP server.
15
+ The runtime target is Node.js on macOS, Linux, and Windows. The default GitHub
16
+ Actions product gate is manual and runs on `windows-latest` with Node 22 to
17
+ keep routine Actions usage bounded. Broader OS or Node coverage should be run
18
+ manually before a wider release. The local and CI release gate is
19
+ `npm run product:check`, which runs release metadata validation, typecheck,
20
+ the progress-reporting test runner, build, and package smoke.
21
+ The package smoke uses `npm pack --dry-run` to verify packed files, CLI bins,
22
+ SDK exports, release docs, security policy, and the published
23
+ `computer_operation` schema, then creates a real `.tgz`, installs it into a
24
+ temporary consumer project, runs the installed `computer-linker` bin, verifies
25
+ installed `self-test`, `setup`, and `status` against isolated config
26
+ directories, and imports the installed SDK entrypoint. The package build uses
27
+ `tsconfig.build.json` so tests are typechecked but are not emitted into the
28
+ runtime package.
29
+
30
+ ```text
31
+ ChatGPT / Claude / MCP host
32
+ -> Computer Linker: desktop-pc
33
+ workspaces: ~/work/app-a, ~/open-source/lib-b
34
+ -> Computer Linker: laptop-pc
35
+ workspaces: ~/client-a/site, ~/notes/dev
36
+ ```
37
+
38
+ The user chooses the target connector by machine name. Each connector also has
39
+ a stable `machineId` so clients can distinguish two computers even if the
40
+ display name changes. Inside that connector, the model calls
41
+ `get_computer_info`, chooses one reported scope, and then sends stable
42
+ `computer_operation` envelopes.
43
+
44
+ When no config file exists, Computer Linker writes a loopback-only default config on
45
+ first load so the `machineId` is durable even before explicit initialization.
46
+ `computer-linker init` adds an owner token to that existing config when needed.
47
+ `computer-linker config token rotate` replaces the owner token for routine
48
+ credential rotation; `--show-token` is required before the raw token is printed.
49
+
50
+ `computer-linker client setup` exports MCP setup guidance with redacted auth by
51
+ default; `client setup --show-token` includes the owner token only for trusted
52
+ local setup screens. `computer-linker profile` exports a lower-level
53
+ per-computer connection profile with machine ID, machine name, stdio command,
54
+ local/public MCP URLs, local/public JSON API URLs, and the same redaction
55
+ default. Capabilities also expose the redacted profile so clients can identify
56
+ which computer they are connected to.
57
+
58
+ The previous prototype name was LocalPort. New installs expose only the
59
+ `computer-linker` CLI. `LOCALPORT_*` and `x-localport-token` remain config and
60
+ HTTP auth compatibility aliases while the product moves to `COMPUTER_LINKER_*`
61
+ and `x-computer-linker-token`.
62
+
63
+ `get_computer_info` is the public MCP introspection entrypoint. The local
64
+ `/api/v1/capabilities` endpoint and compatibility `get_capabilities` tool
65
+ expose the fuller implementation diagnostics for local tools, config, security,
66
+ release readiness, and tunnel state. Together they expose OS/runtime facts,
67
+ coding capability flags, local tool availability, executable paths, versions,
68
+ install hints, workspace permissions, operation catalog, config diagnostics,
69
+ security findings, release readiness, tunnel diagnostics, and the redacted
70
+ connection profile. This lets a client choose whether to use fast search,
71
+ shell, Codex, package scripts, or tunnel setup without probing many separate
72
+ endpoints. The `toolReadiness` block separates required, recommended, and
73
+ optional local tools so GPT-style clients can explain missing `rg`, `git`,
74
+ `codex`, or package tooling without guessing platform-specific installation
75
+ steps.
76
+
77
+ `releaseReadiness` is the productization summary for CLI, API, smoke checks, and
78
+ CI handoff. It combines Node runtime support, config diagnostics, security
79
+ diagnostics, tool readiness, startup readiness, workspace scope presence, and
80
+ command policy coverage. A release is blocked when
81
+ `releaseReadiness.status === "blocked"`; `needs_attention` keeps the local
82
+ service usable but should be reviewed before tagging an alpha release.
83
+ `computer-linker config validate` exposes this release-focused subset for
84
+ local release scripts, while the manual GitHub Actions `Release Package`
85
+ workflow runs the product gate and uploads the packed npm artifact.
86
+ The local `alpha:evidence` release tool captures one manually verified external
87
+ MCP client/tunnel pass in a gitignored JSON file, with `record` commands for
88
+ marking individual checks as passed without hand-editing JSON. `init` and
89
+ `record` reject common secret-shaped values before writing evidence. `alpha:check
90
+ --require-evidence` validates that evidence against the current package version,
91
+ Git HEAD, age, concrete client/exposure/tunnel target, `/mcp` path, required
92
+ generic MCP tool flow, MCP-only public surface, history review, and common
93
+ secret-shaped values before a public alpha announcement.
94
+ `computer-linker status` is the short daily readiness command for humans and
95
+ scripts. Its text output uses user-facing readiness labels; release-focused
96
+ `releaseReadiness` details stay in `doctor`, `config validate`, and JSON
97
+ outputs, while verbose status rows stay behind `status --details`.
98
+ `computer-linker doctor --fix` applies local, deterministic config
99
+ repairs only: bootstrap scope cleanup, exact duplicate folder-scope cleanup,
100
+ and missing execution policy defaults. It does not guess tunnel URLs or mutate
101
+ external services.
102
+ Config diagnostics warn when multiple scopes point at the same folder, but this
103
+ is auto-fixed only when the duplicate scopes have identical permissions and
104
+ policy. Differently permissioned duplicates may be intentional and remain a
105
+ manual cleanup decision.
106
+
107
+ ## Scope And Permission Model
108
+
109
+ The product spec uses **scope** as the public term. A current workspace is a
110
+ folder-backed scope kept for compatibility while the implementation moves toward
111
+ the generic computer-control contract.
112
+
113
+ Permissions live on predefined scopes, not on individual tool calls. The
114
+ current compatibility flags are:
115
+
116
+ - `read`: read files, list directories, search files
117
+ - `write`: write, edit, create, move, and delete paths
118
+ - `shell`: run local shell commands in a workspace
119
+ - `codex`: invoke the local `codex` CLI in a workspace
120
+ - `screen`: capture screen pixels through the platform screenshot provider
121
+
122
+ The default MCP surface is the spec-defined `get_computer_info`,
123
+ `computer_operation`, and `get_operation_history`. Compatibility tools
124
+ `get_capabilities`, `list_workspaces`, `open_workspace`,
125
+ `workspace_operation`, `read`, `ls`, `grep`, `glob`, and `create_file` are
126
+ hidden unless `COMPUTER_LINKER_MCP_TOOL_SURFACE=compatibility` is set for an
127
+ older client. Those tools call the same workspace operation dispatcher.
128
+ Operations inherit the scope's policy, and file path resolution cannot leave
129
+ configured roots.
130
+ Capability, workspace-list, and open-workspace responses include
131
+ `allowedOperations` and a derived `capabilityPolicy` for each workspace so
132
+ clients can pick valid operations without reimplementing permission rules.
133
+ `allowedOperations` is the concrete call allowlist; `capabilityPolicy` is the
134
+ more semantic contract for clients, with capabilities such as `git:read`,
135
+ `git:write`, `package:run`, `process:manage`, `codex:readOnly`,
136
+ `codex:write`, `screen:capture`, `network:false`, and `maxRuntimeSeconds`.
137
+ Clients can also call `explain_operation` inside an opened workspace to
138
+ preflight one operation and receive its required permission, missing permission
139
+ when blocked, required capabilities, missing capabilities, catalog entry, and
140
+ safety boundary metadata. `allowedOperations` is the intersection of the legacy
141
+ workspace permission flag and the derived capability policy.
142
+ Workspace ids are unique. When exposed paths overlap, direct path matching uses
143
+ the deepest matching configured path; explicit workspace opens by id, name, or
144
+ exact configured path remain exact.
145
+ Capability discovery includes `computerOperationContract` and
146
+ `computerOperationRegistry` so new clients can use the generic
147
+ `computer_operation` envelope without hardcoding operation names. It also
148
+ includes an `exposure` summary that tells clients whether this machine is
149
+ loopback-only, which tunnel tools are available, whether the server is ready for
150
+ tunnel exposure, and which blocking reasons or warnings remain.
151
+ `computer_operation` returns the product-level result envelope with `ok`,
152
+ `operationId`, `scope`, `op`, timing fields, `data` on success, and `error` on
153
+ failure. Compatibility `workspace_operation` continues to return the legacy
154
+ operation data shape directly.
155
+ `operation_registry` now defaults to the generic `computer_operation` registry
156
+ so raw JSON clients can discover dotted ops such as `file.read`,
157
+ `code.context`, `git.diff`, `package.run`, `command.run`, and `history.last`
158
+ without parsing the full capabilities payload. Compatibility clients can still
159
+ request the old workspace-operation
160
+ registry with `workspace_operation_registry` or
161
+ `operation_registry` plus `contract: "workspace"`; that legacy registry is
162
+ built through `registerOperation(...)` and combines operation category,
163
+ permission, schema, run/audit metadata, examples, boundary metadata, required
164
+ capabilities, and runtime limits in one list. Internally,
165
+ `runWorkspaceOperation` resolves the registry entry first and calls its
166
+ registered runner, so the registry is part of the execution path rather than
167
+ only documentation. Older operation groups still share the legacy dispatcher,
168
+ while file/search operations use `runFileSearchOperation`, metadata and history
169
+ operations use `runMetadataOperation`, Codex operations use `runCodexOperation`,
170
+ and screen operations use `runScreenOperation`; future provider groups should
171
+ follow that pattern instead of adding more switch cases. The registry builder
172
+ validates that every known operation is registered exactly once and rejects
173
+ unknown or duplicate operation names, so catalog, capability, audit, and
174
+ execution metadata cannot silently drift apart.
175
+
176
+ Capabilities also include `operationSafety`. This machine-readable list marks
177
+ each operation as `workspace-path-enforced`, `workspace-scoped-metadata`,
178
+ `workspace-cwd-only`, or `mixed`. File, search, patch, and direct Git operations
179
+ validate workspace paths before running. Shell, long-running process, and Codex
180
+ operations start in the workspace but are cwd-bound local execution rather than
181
+ an OS filesystem sandbox. Clients that need hard boundaries should prefer the
182
+ path-enforced operations and require explicit user trust before using cwd-only
183
+ execution.
184
+
185
+ ## Why Separate `shell` And `codex`
186
+
187
+ Shell access is broad local execution. Codex access is also broad, but it is a
188
+ specific workflow with its own user expectations. Keeping it separate lets a
189
+ user allow normal tests, package scripts, and long-running dev processes while
190
+ blocking local agent loops, or allow Codex only for selected repos.
191
+
192
+ `command`, raw `codex`, and Codex workflow operations return structured process
193
+ results, including non-zero `exitCode`, `stdout`, `stderr`, signal, and timeout
194
+ status. A failed test command is still a successful Computer Linker operation
195
+ because the diagnostic output is the useful result. `process_start`,
196
+ `codex_start`, `process_list`, `process_read`, and `process_stop` provide
197
+ workspace-scoped in-memory management for dev servers, watch tests,
198
+ long-running shell tasks, and long-running Codex jobs. Managed processes are
199
+ tagged as `shell` or `codex`;
200
+ workspaces can only read or stop process kinds allowed by their current
201
+ permissions. On Unix-like systems, managed processes are started in a process
202
+ group so stop and timeout can terminate child processes started by commands
203
+ such as `npm run dev` or `codex exec`. HTTP server shutdown also stops all
204
+ managed processes to avoid leaving detached tasks behind. If a managed process
205
+ does not exit after the requested stop signal, Computer Linker follows up with
206
+ `SIGKILL`.
207
+
208
+ Workspace config can add an optional `policy` block per scope. Command,
209
+ package, managed process, and Codex execution check `allowedCommands` and
210
+ `deniedCommands` wildcard patterns before launch, cap runtime with
211
+ `maxRuntimeSeconds`, and bound command stdout/stderr with `maxOutputBytes`.
212
+ `computer-linker start <folder>` and `computer-linker setup <folder>` attach
213
+ a default execution policy when `--shell` or `--codex` is enabled. Manual
214
+ `workspace add/update` flows keep policy management explicit. Absent policy
215
+ keeps the existing permission-flag behavior.
216
+ Config diagnostics and security diagnostics warn when shell or Codex execution
217
+ is enabled without an `allowedCommands` policy, because those operations remain
218
+ cwd-bound local execution rather than a filesystem sandbox.
219
+
220
+ These operations are intentionally flagged by security diagnostics. Computer Linker
221
+ sets the working directory to the workspace, but a normal OS shell or Codex
222
+ process is not a filesystem sandbox. Read/write/search operations enforce path
223
+ boundaries directly; shell/codex should only be enabled for workspaces where
224
+ that broader local execution is acceptable.
225
+
226
+ ## HTTP Mode
227
+
228
+ Computer Linker supports stdio, a Streamable HTTP MCP endpoint, and a small JSON API
229
+ for non-MCP clients. Tunnel commands start the HTTP server and then shell out to
230
+ the provider CLI:
231
+
232
+ - Cloudflare Quick Tunnel: `cloudflared tunnel --url http://127.0.0.1:<port>`
233
+ - Tailscale Funnel: `tailscale funnel --yes <port>`
234
+ - OpenAI Secure MCP Tunnel: `tunnel-client run --control-plane.tunnel-id tunnel_... --mcp.server-url url=http://127.0.0.1:<port>/mcp`
235
+
236
+ Tailscale Serve is intentionally not part of the short-term public ChatGPT
237
+ flow because it is tailnet-scoped; Funnel is the public Tailscale path.
238
+ OpenAI Secure MCP Tunnel is different from the public URL providers: ChatGPT
239
+ uses the OpenAI tunnel id, and the local server remains private behind outbound
240
+ HTTPS from `tunnel-client`.
241
+
242
+ HTTP mode exposes OAuth metadata, dynamic client registration, owner-token
243
+ approval, access tokens, and refresh tokens. It also accepts the owner token as
244
+ a direct bearer token for simpler clients that support custom headers.
245
+
246
+ OAuth registered clients, access tokens, and refresh tokens are persisted in
247
+ `~/.computer-linker/oauth-state.json` with `0600` permissions. Short-lived
248
+ authorization codes stay in memory and expire quickly; they are not persisted
249
+ across restarts.
250
+
251
+ When running behind a tunnel, `publicBaseUrl` or `COMPUTER_LINKER_PUBLIC_BASE_URL`
252
+ must match the reachable origin so OAuth issuer and resource metadata are
253
+ correct. OpenAI Secure MCP Tunnel does not use `publicBaseUrl`; connector setup
254
+ uses the `tunnel_...` id instead. Daily status output should treat a running
255
+ OpenAI tunnel as active exposure without a public URL, not as a missing
256
+ `publicBaseUrl` problem.
257
+
258
+ ## JSON API
259
+
260
+ The JSON API lives under `/api/v1` and mirrors the core MCP model with a small
261
+ surface. The preferred shape for simple clients is `POST /api/v1/control` with
262
+ an `action` value: `get_computer_info`, `client_setup`,
263
+ `computer_operation`, or `get_operation_history`. Compatibility actions include
264
+ `get_capabilities`, `doctor`, `list_workspaces`, `history`, `history_insight`,
265
+ `operation_registry`, `workspace_operation`, and the shorter `operation` alias.
266
+ For new clients, `computer_operation` accepts the flat envelope
267
+ `{ action, scope, op, target, input, options }`. Its `op` value should come from
268
+ `computerOperationRegistry`, for example `file.read`, `file.search`,
269
+ `code.context`, `git.diff`, `package.run`, `command.run`, `codex.run`,
270
+ `screen.capture`, or `history.last`.
271
+ The older workspace/action shape and direct legacy operation names remain
272
+ supported during migration.
273
+ The JSON API is a local or trusted-private automation surface. Public tunnel
274
+ commands default to MCP-only exposure, so public hosts expose `/mcp` and block
275
+ `/api/v1` unless the operator deliberately places the JSON API behind a private
276
+ route.
277
+ This gives non-MCP clients one universal command-style endpoint while keeping
278
+ dedicated compatibility endpoints for normal REST usage. `doctor` is a compact
279
+ readiness summary for clients that need to decide whether tunnel exposure is
280
+ safe without parsing the full capabilities payload.
281
+
282
+ The workspace operation path covers single and multi-file read,
283
+ compare-and-write, write/edit, directory listing, bounded recursive tree
284
+ listing, path metadata, directory creation, path move/delete, project
285
+ instruction loading, workspace-scoped audit history, coding-oriented project
286
+ overview, read-only git status/diff inspection, workspace-bounded Git index and
287
+ commit updates, bounded Git worktree creation for parallel coding sessions,
288
+ workspace-validated unified diff patching, fast file/text search, ordered batch
289
+ execution, command execution, long-running process management, and Codex
290
+ execution, including background Codex jobs. It is intended for scripts and
291
+ simple local integrations that do not speak MCP. Screen operations report
292
+ provider readiness, list known capture targets, and advertise only the capture
293
+ target types the current platform provider can run.
294
+ The current screenshot providers are macOS `screencapture` for display/window
295
+ capture and Windows PowerShell for primary-display capture in an interactive
296
+ desktop session. Linux reports capability status until a desktop/session
297
+ provider is added. Window and process capture remain provider-specific; generic
298
+ clients should follow `computerOperationRegistry`, while legacy direct calls
299
+ return clear unsupported errors when the platform cannot supply that target.
300
+
301
+ Workspace operations support both the original direct-field payload and a
302
+ generic envelope for clients that want a stable outer shape:
303
+
304
+ ```json
305
+ {
306
+ "workspace": "app",
307
+ "op": "read",
308
+ "target": "README.md",
309
+ "input": {},
310
+ "options": { "maxBytes": 65536 }
311
+ }
312
+ ```
313
+
314
+ `op` is a registered operation name. `target` maps to the natural target for
315
+ that operation, while `input` carries required data and `options` carries
316
+ limits or modifiers. The server normalizes both shapes before permission checks,
317
+ execution, and audit logging.
318
+
319
+ API calls use configured workspace references instead of MCP session
320
+ `workspaceId` values. Each request resolves the configured workspace, checks the
321
+ same permissions, resolves paths inside the same boundary, and writes the same
322
+ audit log events. This keeps the API simpler without creating a second security
323
+ model or a long list of public endpoints.
324
+
325
+ ## Search
326
+
327
+ Search is a first-class coding API:
328
+
329
+ - `tree`: bounded recursive workspace structure listing
330
+ - `explain_operation`: explain whether one operation is allowed in the current
331
+ workspace, including required permission and safety boundary metadata
332
+ - `instructions`: load `AGENTS.md` and `CLAUDE.md` files from the workspace
333
+ root to a target path
334
+ - `agent_skills`: discover workspace-scoped agent skills from `.codex/skills`,
335
+ `.claude/skills`, and `skills` without reading global user skill folders
336
+ - `coding_context`: return the normal session-start context in one call:
337
+ overview, instructions, skills, tree, and change summary
338
+ - `project_overview`: summarize package scripts, package managers, config
339
+ files, language hints, instruction files, git presence, and suggested next
340
+ operations for coding work
341
+ - `history`: return recent audit events for the opened workspace
342
+ - `history_insight`: return an agent-friendly last-operation view, history
343
+ summary, chronological timeline, session/connection summaries, failed replay
344
+ templates, or redacted debug bundle for the opened workspace
345
+ - `change_summary`: return branch, changed-file counts, entries, and diff
346
+ stats in one read-only call
347
+ - `repo_status`: read git status and optional diff without shell permission
348
+ - `git_changes`: return structured changed-file entries and counts for staged,
349
+ unstaged, untracked, ignored, and renamed files
350
+ - `git_diff`: return bounded staged or unstaged diffs for the whole repository
351
+ or selected workspace-validated pathspecs without shell permission
352
+ - `git_log`: return recent commits for the repository or selected
353
+ workspace-validated pathspecs without shell permission
354
+ - `git_show`: return a bounded commit or object view for the repository or
355
+ selected workspace-validated pathspecs without shell permission
356
+ - `git_stage` / `git_unstage`: update the Git index for selected
357
+ workspace-validated paths without shell permission; these require `write`
358
+ permission because they mutate repository state
359
+ - `git_commit`: create a Git commit from currently staged files after
360
+ verifying every staged path is inside the workspace
361
+ - `git_worktree_list`: list Git worktrees for a repository path inside the
362
+ workspace
363
+ - `git_worktree_create`: create an isolated Git worktree at a target path that
364
+ must stay inside the workspace; this requires `write` permission and runs
365
+ `git` directly rather than through the shell
366
+ - `read`: read a UTF-8 file with optional `startLine`, `lineCount`, and
367
+ `maxBytes` bounds for large-file inspection; returns a full-file `sha256`.
368
+ Common sensitive files are blocked by default.
369
+ - `read_many`: read several files in one bounded workspace-scoped call; each
370
+ file includes a full-file `sha256`
371
+ - `create_file`: create a new UTF-8 file and fail if the target path already
372
+ exists; intended for first-run probes and new files where overwriting would
373
+ be unsafe
374
+ - `write_if_unchanged`: overwrite a file only when its current `sha256` still
375
+ matches a value returned by a prior read
376
+ - `patch`: apply a unified diff after validating all touched paths stay inside
377
+ the workspace
378
+ - `find_files`: fast file discovery
379
+ - `search_text`: line-based text search with glob, case, fixed-string, and
380
+ before/after context options; common sensitive files are excluded from search
381
+ by default
382
+ - `search_symbols`: structured symbol discovery for common programming
383
+ languages, including functions, classes, interfaces, types, and enums
384
+ - `batch`: run up to 25 operations in order and return per-operation results
385
+ without bypassing the permissions of each item
386
+ - `package_run`: run an existing `package.json` script through the detected
387
+ package manager; this requires `shell` permission because package scripts can
388
+ execute arbitrary local commands
389
+ - `package_start`: start an existing `package.json` script as a managed process
390
+ for dev servers and watch tasks
391
+ - `process_start` / `process_list` / `process_read` / `process_stop`: manage
392
+ long-running workspace shell processes such as dev servers and watch tasks
393
+ - `codex_start`: start a long-running managed Codex job that can be inspected
394
+ or stopped with the same process operations
395
+ - `codex_plan` / `codex_review` / `codex_fix` / `codex_test` /
396
+ `codex_continue`: higher-level Codex workflows that wrap `codex exec -` with
397
+ stable prompts, workflow metadata, history/change context, and structured
398
+ stdout/stderr results
399
+ - `codex_runs`: list persisted Codex workflow records for the workspace, or
400
+ inspect one workflow id with bounded stdout/stderr previews, exit metadata,
401
+ pre/post change summaries, and continuation history references
402
+
403
+ File, text, and symbol search prefer `rg` for fast candidate discovery and fall
404
+ back to built-in scanners if `rg` is missing. Future versions can back
405
+ `search_symbols` with language servers, ctags, or project indexes without
406
+ changing the workspace permission boundary.
407
+
408
+ ## CLI/API Management
409
+
410
+ Computer Linker is CLI-first. The CLI and JSON API are the administrative
411
+ surface for the same config file used by the MCP server:
412
+
413
+ - `computer-linker status` shows the short daily readiness view: connection
414
+ mode, local MCP URL, auth summary, workspace/tunnel summary, user-facing
415
+ readiness, and the next few actions. `status --details` prints the full
416
+ workspace rows, warnings, running tunnel rows, and all next actions.
417
+ - `computer-linker self-test` creates an isolated temporary config/workspace,
418
+ starts the loopback HTTP MCP server, runs the generic MCP SDK smoke flow, and
419
+ exits non-zero when the installed CLI/server/tool flow is not working.
420
+ - `computer-linker doctor` shows full runtime diagnostics, startup readiness,
421
+ local MCP/API URLs, security findings, tool availability, release readiness,
422
+ and next actions.
423
+ - `computer-linker doctor --fix` applies deterministic local config repairs.
424
+ - `computer-linker setup` and `computer-linker start <folder>` initialize
425
+ machine identity, owner token, workspace scopes, permissions, and default
426
+ command policy.
427
+ - `computer-linker config ...` shows and edits config values such as
428
+ `publicBaseUrl` and per-workspace execution policy.
429
+ - `computer-linker process list/read/stop` talks to the running local HTTP
430
+ server and manages background command/Codex processes started through MCP.
431
+ - `computer-linker screen status` reports screenshot provider readiness,
432
+ permission status, supported modes, and screen-enabled workspaces without
433
+ capturing pixels.
434
+ - `computer-linker tunnel status` shows provider status, public URL detection,
435
+ and managed tunnel process state.
436
+ - `computer-linker history ...` reads recent events, sessions, failed replay
437
+ templates, connection summaries, and redacted debug bundles.
438
+ - `computer-linker client setup` prints a short generic MCP connection summary
439
+ without using ChatGPT-specific profile formats. `client setup --details`
440
+ prints tool names, first-prompt guidance, and copy-pasteable agent
441
+ instructions. `--show-token` prints bearer headers only when explicitly
442
+ requested on a trusted local setup screen. OpenAI Secure MCP Tunnel is treated
443
+ as remote-ready without a public URL because the local tunnel client forwards
444
+ the owner token to the private loopback MCP server.
445
+ - `computer-linker client smoke` runs a generic HTTP/MCP reachability check.
446
+ Local loopback smoke validates `/healthz`, authenticated JSON API
447
+ capabilities, `get_computer_info`, one read-only `computer_operation`
448
+ `file.list`, and an MCP SDK flow over `/mcp`: initialize, tools/list,
449
+ `get_computer_info`, and one read-only `computer_operation`. Public HTTPS
450
+ smoke skips JSON API checks but still runs the MCP SDK tool flow, matching
451
+ the default MCP-only tunnel exposure.
452
+ - `computer-linker diagnose client` is the product troubleshooting wrapper:
453
+ it combines generic setup readiness, the same MCP SDK smoke flow, and
454
+ redacted connection history into one local or remote diagnosis payload.
455
+ - `computer-linker client chatgpt ...` exports profile/manifest/connector
456
+ setup data; its smoke command is a thin compatibility wrapper over the same
457
+ generic client smoke core.
458
+ - `/api/v1/control` exposes the same management/introspection contracts for
459
+ local automation and compatibility connectors.
460
+
461
+ The management surface does not grant new capabilities by itself. It only
462
+ writes config or reports state; MCP tools still enforce workspace paths and
463
+ permissions at runtime.
464
+
465
+ Active sessions are tracked in memory and shown with auth type, client/user
466
+ agent, remote address, last seen time, and request count. A revoked session is
467
+ closed at the HTTP transport layer and removed from the active list. Audit
468
+ events remain the durable history.
469
+
470
+ ## Tunnel Diagnostics
471
+
472
+ Computer Linker treats tunnel providers as local CLIs rather than hidden services.
473
+ Each provider implements `detect`, `status`, `expose`, `getPublicUrl`, and
474
+ `stop`. The product-mode CLI entrypoint is `computer-linker start`, which starts
475
+ local HTTP mode by default and starts a tunnel only when `--tunnel` is explicit.
476
+ When a tunnel is selected, `computer-linker start --tunnel ...` and
477
+ `computer-linker expose ...` enable `publicMcpOnly` before the HTTP server
478
+ listens so public-host requests expose `/mcp` only; local `/api/v1` and
479
+ `/healthz` remain available for CLI smoke checks.
480
+ Tailscale product-mode startup uses Funnel by default once selected;
481
+ `computer-linker expose <provider>` remains as a lower-level compatibility
482
+ entrypoint:
483
+
484
+ - Cloudflare Quick Tunnel uses `cloudflared tunnel --url http://127.0.0.1:<port>`.
485
+ - Tailscale Funnel uses `tailscale funnel --yes <port>`.
486
+ - OpenAI Secure MCP Tunnel uses OpenAI's official `tunnel-client` with
487
+ `--mcp.server-url url=http://127.0.0.1:<port>/mcp`.
488
+ - Tailscale Serve still exists at the provider layer for compatibility, but is
489
+ not part of the default public ChatGPT flow.
490
+
491
+ `computer-linker tunnel status --json`, `doctor`, capabilities, and ChatGPT
492
+ setup helpers all use this provider layer. Diagnostics include a serializable
493
+ `providerContracts` list with each provider's modes, commands, lifecycle
494
+ capabilities, and public URL sources, plus live provider status and managed
495
+ process output. Managed tunnel snapshots are persisted to `tunnels.json` under
496
+ the Computer Linker config directory, which lets a separate CLI process show a
497
+ detected public URL in `tunnel status`, `doctor`, `capabilities`, and `client
498
+ chatgpt url`. Cloudflare custom hostnames are still configured explicitly as
499
+ `publicBaseUrl`. Tailscale Funnel startup can detect the `https://*.ts.net`
500
+ origin from the managed tunnel output and save it as `publicBaseUrl` for future
501
+ OAuth metadata. OpenAI Secure MCP Tunnel has no public URL source; on first CLI
502
+ startup Computer Linker downloads the official `openai/tunnel-client` release
503
+ into its config directory, verifies the selected asset against
504
+ `SHA256SUMS.txt`, and runs that managed binary. It never scans user directories
505
+ such as Desktop for executables unless a path is explicitly provided with
506
+ `--tunnel-client` or `COMPUTER_LINKER_OPENAI_TUNNEL_CLIENT`.
507
+
508
+ `computer-linker start` and `computer-linker expose` require an owner token
509
+ before starting a tunnel. Loopback
510
+ HTTP mode can run without a token for local-only development, and `init`,
511
+ `setup`, `start <folder>`, or `config token rotate` can generate the token
512
+ before exposure. Tunnel mode must not publish a loopback-only unauthenticated
513
+ server to the network. The direct bearer owner-token compatibility path reads
514
+ current config on each `/mcp` request, so token changes take effect immediately
515
+ for clients that send `Authorization: Bearer ...`. OAuth discovery and provider
516
+ state are created when HTTP mode starts; restart the server after token-state
517
+ changes for full OAuth client setup.
518
+
519
+ ## Audit Log
520
+
521
+ Computer Linker writes local JSONL audit events to `~/.computer-linker/audit.jsonl`.
522
+ Events cover MCP sessions, workspace opens, tool calls, auth failures, admin
523
+ actions, success/failure, timing, workspace identifiers, operation names,
524
+ targets, paths, request paths, remote addresses, and command previews. File
525
+ contents, write payloads, screenshot image bytes, and tokens are not logged.
526
+ CLI/API history readers use this file directly, so history survives restarts and
527
+ can be exported or filtered without changing the permission boundary.
528
+ The generic `computer_operation` and compatibility `workspace_operation`
529
+ surfaces write into the same audit/history stream. Generic events keep the
530
+ dotted op name, resolved scope id/root, target, and mapped path so
531
+ `get_operation_history` and debug bundles work even when a client never calls
532
+ the older workspace tools.
533
+
534
+ Compatibility `batch` writes one outer `workspace_operation` event plus one
535
+ `workspace_operation.batch_item` event for each child operation. This preserves
536
+ the convenience of a single request while keeping the durable history detailed
537
+ enough to inspect which read, write, search, command, or Codex step succeeded
538
+ or failed.
539
+
540
+ Compatibility clients can also call `workspace_operation` with
541
+ `operation=history` to see recent events for the opened workspace.
542
+ Use `operation=history_insight` when an agent needs a compact last-operation
543
+ summary, a chronological workspace timeline, grouped session summaries, a
544
+ grouped tunnel/MCP connection summary, a failed-operation replay template, or a
545
+ redacted debug bundle to attach to a follow-up coding request. Replay
546
+ templates are stored as stable `workspace_operation` envelopes. Safe operations
547
+ such as package scripts can be retried directly; screenshot captures are marked
548
+ non-replayable because they can expose current screen pixels; raw shell commands
549
+ and Codex prompts are represented as templates with `requiresInput` because
550
+ full sensitive text is not written to the audit log.
551
+ For local support/debug workflows, the same redacted views are available through
552
+ `computer-linker history --view last` and
553
+ `computer-linker history --view debug_bundle --json --output <file>`.
554
+
555
+ Reachability is verified through CLI smoke checks. `computer-linker doctor`
556
+ reports local readiness, `computer-linker diagnose client` summarizes client
557
+ setup, MCP SDK smoke, and recent connection history, `computer-linker client
558
+ smoke` verifies the configured local or public MCP origin,
559
+ local/trusted-private smoke also proves the authenticated `get_computer_info`
560
+ and read-only `computer_operation` contract, and `/api/v1/control` exposes
561
+ machine-readable readiness for automation.