@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,911 @@
1
+ # Computer Linker Product Spec
2
+
3
+ ## Status
4
+
5
+ This is the product boundary for Computer Linker.
6
+ When implementation details conflict with this document, the product should be
7
+ changed back toward this spec instead of expanding around accidental features.
8
+
9
+ ## Product Goal
10
+
11
+ Computer Linker is a local MCP service installed on a user's computer.
12
+ It gives an AI client a controlled way to inspect and operate that computer.
13
+
14
+ The core product is not a ChatGPT dashboard, a web app, a tunnel manager, or a
15
+ workspace document system. Human setup and management should be CLI-first; MCP
16
+ and the JSON API are client protocol surfaces. The primary runtime is:
17
+
18
+ ```text
19
+ AI client
20
+ -> MCP
21
+ -> Computer Linker running on this computer
22
+ -> files, commands, Codex, screenshots, computer facts
23
+ ```
24
+
25
+ ## Core Jobs
26
+
27
+ Computer Linker must make these jobs reliable and easy:
28
+
29
+ 1. Let a client ask what this computer can do.
30
+ 2. Let a client read, write, list, and search files within configured bounds.
31
+ 3. Let a client run commands under a clear local execution policy.
32
+ 4. Let a client operate the local Codex CLI as a first-class workflow.
33
+ 5. Let a client capture screenshots of the screen, a display, a window, or a
34
+ process when the platform supports it.
35
+ 6. Record what happened so the user can inspect and debug actions later.
36
+
37
+ ## Non-Goals
38
+
39
+ These are not the core product:
40
+
41
+ - A dashboard or browser-first management app.
42
+ - A ChatGPT-specific product with many special endpoints.
43
+ - A general remote desktop replacement.
44
+ - A full OS sandbox. Computer Linker enforces its own policy, but shell,
45
+ Codex, and screenshot operations still rely on local OS behavior.
46
+ - A cloud service. The service runs on the user's computer; tunnels only expose
47
+ it when the user chooses to.
48
+
49
+ ## Client Positioning
50
+
51
+ ChatGPT is a client, not the product axis.
52
+
53
+ Computer Linker should expose a generic MCP contract that works for ChatGPT,
54
+ Claude, Codex, a custom web UI, or any other MCP-capable client. ChatGPT setup
55
+ documentation may exist, but it must not drive the core architecture.
56
+
57
+ Correct framing:
58
+
59
+ - Product: local computer MCP service.
60
+ - Client: ChatGPT or any other MCP host.
61
+ - Setup helper: CLI/API URL, auth token, tunnel status, and smoke test.
62
+ - Not core: ChatGPT-specific manifests, model guides, or profile formats unless
63
+ they are thin exports over the generic MCP contract.
64
+
65
+ ## Product Model
66
+
67
+ One computer runs one Computer Linker service.
68
+ Each computer has:
69
+
70
+ - `machineId`: stable identifier.
71
+ - `machineName`: human-readable name.
72
+ - `capabilities`: OS, runtime, available tools, screenshot support, command
73
+ policy, Codex availability, and configured file scopes.
74
+ - `policy`: what the client is allowed to do.
75
+ - `history`: audit log of operations and outcomes.
76
+
77
+ The product should support Windows, macOS, and Linux. Platform differences are
78
+ reported through capabilities instead of hidden behind failed calls.
79
+
80
+ ## Terminology
81
+
82
+ - **Computer**: the physical or virtual machine running Computer Linker.
83
+ - **Client**: any MCP host or automation tool connected to Computer Linker.
84
+ - **Scope**: a named permission boundary. A scope can point at a folder, a
85
+ project, a command policy, screenshot permission, or a broader computer
86
+ profile. Existing `workspace` language maps to a folder-backed scope.
87
+ - **Operation**: one requested action inside a scope.
88
+ - **Provider**: platform-specific implementation for files, commands, Codex,
89
+ screenshots, process lookup, or system facts.
90
+ - **Managed process**: a command or Codex session started by Computer Linker
91
+ and tracked for later read/stop/list operations.
92
+
93
+ Use `scope` in the product contract. Keep `workspace` only as a compatibility
94
+ term for existing folder-backed integrations.
95
+
96
+ ## System Architecture
97
+
98
+ Computer Linker has these runtime components:
99
+
100
+ 1. **Transport adapters**
101
+ - stdio MCP server.
102
+ - HTTP MCP server.
103
+ - optional local JSON API for non-MCP clients.
104
+ 2. **Tool router**
105
+ - exposes the small public MCP tool surface.
106
+ - validates the outer request shape.
107
+ - forwards operations to the dispatcher.
108
+ 3. **Policy engine**
109
+ - loads configured scopes.
110
+ - resolves capabilities.
111
+ - denies operations before provider execution.
112
+ - enforces file roots for file operations.
113
+ - applies command/Codex/screenshot policy.
114
+ 4. **Operation dispatcher**
115
+ - normalizes `{ scope, op, target, input, options }`.
116
+ - selects the provider.
117
+ - applies operation limits.
118
+ - returns the standard result envelope.
119
+ 5. **Providers**
120
+ - file provider.
121
+ - search provider, preferring `ripgrep`.
122
+ - command/process provider.
123
+ - Codex provider.
124
+ - screenshot provider.
125
+ - computer-info provider.
126
+ 6. **Audit store**
127
+ - records every operation.
128
+ - supports recent history, session timeline, and debug bundle export.
129
+ 7. **Management UI and CLI**
130
+ - configure scopes and policy.
131
+ - show status.
132
+ - start/stop service helpers.
133
+ - do not define the product API.
134
+
135
+ ## Configuration Model
136
+
137
+ The durable config should describe one computer and its scopes:
138
+
139
+ ```json
140
+ {
141
+ "machineId": "stable-machine-id",
142
+ "machineName": "desktop-pc",
143
+ "host": "127.0.0.1",
144
+ "port": 3939,
145
+ "ownerToken": "secret-or-null",
146
+ "scopes": [
147
+ {
148
+ "id": "app",
149
+ "name": "Main app",
150
+ "type": "folder",
151
+ "roots": ["/Users/me/work/app"],
152
+ "capabilities": [
153
+ "fs:read",
154
+ "fs:write",
155
+ "command:run",
156
+ "process:manage",
157
+ "codex:run"
158
+ ],
159
+ "policy": {
160
+ "maxRuntimeSeconds": 1800,
161
+ "maxOutputBytes": 200000,
162
+ "allowedCommands": ["npm *", "pnpm *", "yarn *", "bun *", "node *", "npx *", "git *", "codex *"],
163
+ "deniedCommands": ["rm -rf *", "del /s *", "rmdir /s *", "format *", "shutdown *"]
164
+ }
165
+ },
166
+ {
167
+ "id": "screen",
168
+ "name": "Screen capture",
169
+ "type": "computer",
170
+ "capabilities": ["screen:capture"],
171
+ "policy": {
172
+ "allowDisplays": true,
173
+ "allowWindows": true,
174
+ "allowProcesses": true
175
+ }
176
+ }
177
+ ]
178
+ }
179
+ ```
180
+
181
+ Rules:
182
+
183
+ - `machineId` must be created once and stay stable.
184
+ - `scope.id` is the stable target clients use.
185
+ - `roots` are required for folder scopes.
186
+ - no operation may silently fall back to unrestricted global access.
187
+ - compatibility config may still store `workspaces`, but runtime should expose
188
+ them as folder-backed scopes.
189
+
190
+ ## Public MCP Surface
191
+
192
+ Keep the MCP tool surface small. Prefer a stable operation envelope over many
193
+ specialized tools.
194
+
195
+ Recommended v1 MCP tools:
196
+
197
+ - `get_computer_info`: return identity, OS/runtime, capabilities, policy, and
198
+ current readiness.
199
+ - `computer_operation`: run file, command, Codex, screenshot, or history
200
+ operations through one stable envelope.
201
+ - `get_operation_history`: retrieve recent audit/session history.
202
+
203
+ Compatibility tools can exist while migrating, but they must be opt-in and new
204
+ clients should not need more than the small surface above.
205
+
206
+ ### `get_computer_info`
207
+
208
+ Input:
209
+
210
+ ```json
211
+ {
212
+ "include": ["identity", "platform", "tools", "scopes", "policy", "status"]
213
+ }
214
+ ```
215
+
216
+ Output:
217
+
218
+ ```json
219
+ {
220
+ "machineId": "stable-machine-id",
221
+ "machineName": "desktop-pc",
222
+ "platform": {
223
+ "os": "darwin",
224
+ "arch": "arm64",
225
+ "release": "26.0",
226
+ "shell": "/bin/zsh"
227
+ },
228
+ "service": {
229
+ "version": "0.1.0",
230
+ "transports": ["stdio", "http"],
231
+ "localUrl": "http://127.0.0.1:3939/mcp",
232
+ "publicUrl": null
233
+ },
234
+ "tools": {
235
+ "rg": { "available": true, "path": "/opt/homebrew/bin/rg" },
236
+ "git": { "available": true },
237
+ "codex": { "available": true },
238
+ "screenshot": { "available": true, "modes": ["display", "window"] }
239
+ },
240
+ "scopes": [
241
+ {
242
+ "id": "app",
243
+ "name": "Main app",
244
+ "type": "folder",
245
+ "capabilities": ["fs:read", "fs:write", "command:run"]
246
+ }
247
+ ],
248
+ "status": {
249
+ "ready": true,
250
+ "blockingReasons": [],
251
+ "warnings": []
252
+ }
253
+ }
254
+ ```
255
+
256
+ ### `computer_operation`
257
+
258
+ Input is the operation envelope defined below.
259
+ Output is the standard operation result envelope.
260
+
261
+ ### `get_operation_history`
262
+
263
+ Input:
264
+
265
+ ```json
266
+ {
267
+ "scope": "app",
268
+ "view": "last",
269
+ "limit": 50,
270
+ "query": "npm test"
271
+ }
272
+ ```
273
+
274
+ Supported views:
275
+
276
+ - `last`
277
+ - `timeline`
278
+ - `sessions`
279
+ - `connections`
280
+ - `failed_replay`
281
+ - `debug_bundle`
282
+
283
+ Output must not include secrets, full file contents, screenshot pixels, or raw
284
+ command output unless explicitly requested and permitted.
285
+
286
+ ## Operation Envelope
287
+
288
+ All operations should fit this shape:
289
+
290
+ ```json
291
+ {
292
+ "scope": "default",
293
+ "op": "file.read",
294
+ "target": "src/index.ts",
295
+ "input": {},
296
+ "options": {}
297
+ }
298
+ ```
299
+
300
+ Field rules:
301
+
302
+ - `scope`: named policy scope. It can map to a folder, a project, or broader
303
+ computer permission. It must be explicit; no hidden global access.
304
+ - `op`: stable operation name.
305
+ - `target`: the primary path, command working directory, process id, display id,
306
+ window id, or Codex session id.
307
+ - `input`: operation-specific data.
308
+ - `options`: limits, filters, output format, timeout, and safety controls.
309
+
310
+ The outer envelope should stay stable even when individual operations evolve.
311
+
312
+ ## Operation Result Envelope
313
+
314
+ Every operation returns the same outer shape:
315
+
316
+ ```json
317
+ {
318
+ "ok": true,
319
+ "operationId": "01J...",
320
+ "scope": "app",
321
+ "op": "file.read",
322
+ "startedAt": "2026-06-23T00:00:00.000Z",
323
+ "durationMs": 12,
324
+ "data": {},
325
+ "warnings": []
326
+ }
327
+ ```
328
+
329
+ Failures return:
330
+
331
+ ```json
332
+ {
333
+ "ok": false,
334
+ "operationId": "01J...",
335
+ "scope": "app",
336
+ "op": "command.run",
337
+ "error": {
338
+ "code": "permission_denied",
339
+ "message": "Scope app does not allow command:run.",
340
+ "retryable": false,
341
+ "details": {}
342
+ }
343
+ }
344
+ ```
345
+
346
+ Required error codes:
347
+
348
+ - `invalid_request`
349
+ - `unknown_scope`
350
+ - `unknown_operation`
351
+ - `permission_denied`
352
+ - `path_out_of_scope`
353
+ - `unsupported_platform`
354
+ - `provider_unavailable`
355
+ - `timeout`
356
+ - `process_not_found`
357
+ - `os_permission_required`
358
+ - `execution_failed`
359
+
360
+ Non-zero command or Codex exit codes are `ok: true` when the operation executed
361
+ successfully and the diagnostic output is returned. Use `data.exitCode` to
362
+ represent the command result.
363
+
364
+ ## Core Operations
365
+
366
+ ### Computer Info
367
+
368
+ Required:
369
+
370
+ - machine identity.
371
+ - OS, architecture, shell, current user context where safe.
372
+ - Node/runtime version.
373
+ - available tools: `rg`, `git`, package managers, `codex`.
374
+ - configured scopes.
375
+ - command policy summary.
376
+ - screenshot capability summary.
377
+ - current service URLs and exposure state when available.
378
+
379
+ ### File Operations
380
+
381
+ Required:
382
+
383
+ - `file.stat`
384
+ - `file.list`
385
+ - `file.tree`
386
+ - `file.read`
387
+ - `file.read_many`
388
+ - `file.write`
389
+ - `file.create`
390
+ - `file.patch`
391
+ - `file.move`
392
+ - `file.delete`
393
+ - `file.find`
394
+ - `file.search`
395
+
396
+ File operations must enforce configured bounds before touching the filesystem.
397
+ Fast search should use `ripgrep` when available, with a safe fallback.
398
+
399
+ Contract details:
400
+
401
+ - `target` is always scope-relative for folder scopes.
402
+ - `options.maxBytes` limits returned content.
403
+ - `options.encoding` defaults to `utf8`; binary reads return base64 only when
404
+ requested.
405
+ - `file.write` creates parent directories only when `options.createParents` is
406
+ true.
407
+ - `file.create` creates a new file only and must fail without overwriting when
408
+ the target already exists.
409
+ - `file.patch` accepts unified diff or structured replacement input.
410
+ - `file.delete` requires `options.recursive` for directories.
411
+ - `file.find` supports `input.pattern` and `options.maxResults`.
412
+ - `file.search` supports `input.query`, `options.glob`, `options.maxResults`,
413
+ and `options.ignoreCase`.
414
+
415
+ Representative result shapes:
416
+
417
+ ```json
418
+ {
419
+ "path": "src/index.ts",
420
+ "content": "...",
421
+ "sha256": "hex",
422
+ "truncated": false
423
+ }
424
+ ```
425
+
426
+ ```json
427
+ {
428
+ "matches": [
429
+ {
430
+ "path": "src/index.ts",
431
+ "line": 12,
432
+ "column": 4,
433
+ "preview": "const value = ..."
434
+ }
435
+ ],
436
+ "engine": "rg"
437
+ }
438
+ ```
439
+
440
+ ### Coding And Repository Operations
441
+
442
+ Computer Linker also exposes coding-oriented dotted ops over the same stable
443
+ `computer_operation` envelope:
444
+
445
+ - `code.context`: bounded project orientation for coding tasks.
446
+ - `code.search_symbols`: symbol discovery for common source languages.
447
+ - `git.status`: repository status and optional bounded diff.
448
+ - `git.changes`: structured changed-file entries.
449
+ - `git.diff`: bounded staged or unstaged diff.
450
+ - `git.log`: recent commits.
451
+ - `git.show`: bounded commit or object view.
452
+ - `git.stage` / `git.unstage`: mutate the index for scoped paths.
453
+ - `git.commit`: commit already staged scoped files.
454
+ - `package.run`: run an existing `package.json` script.
455
+ - `package.start`: start an existing `package.json` script as a managed
456
+ process.
457
+
458
+ These are product-level generic names. Compatibility workspace operation names
459
+ such as `coding_context`, `repo_status`, `git_diff`, and `package_run` remain
460
+ accepted while older clients migrate.
461
+
462
+ ### Command Operations
463
+
464
+ Required:
465
+
466
+ - `command.run`: run and wait for completion.
467
+ - `command.start`: start a managed long-running process.
468
+ - `command.read`: read process output.
469
+ - `command.stop`: stop a managed process.
470
+ - `command.list`: list managed processes.
471
+ - `process.start`: domain alias for starting managed processes.
472
+ - `process.read`: domain alias for reading managed process output.
473
+ - `process.stop`: domain alias for stopping managed processes.
474
+ - `process.list`: domain alias for listing managed processes.
475
+
476
+ Command execution is dangerous and should be policy-driven:
477
+
478
+ - allowed scopes and working directories.
479
+ - timeout and max output.
480
+ - environment filtering.
481
+ - optional allowlist/denylist.
482
+ - explicit indication that commands are not filesystem-sandboxed unless an
483
+ external sandbox is configured.
484
+
485
+ Contract details:
486
+
487
+ - `target` is the working directory, relative to a folder-backed scope unless
488
+ the scope explicitly allows broader command execution.
489
+ - `input.command` is the command string or argv array.
490
+ - `options.timeoutSeconds` must default to a finite value.
491
+ - `options.maxOutputBytes` must default to a finite value.
492
+ - stdout/stderr are captured separately.
493
+ - managed processes get a stable `processId`.
494
+ - process output is retained in a bounded ring buffer.
495
+
496
+ `command.run` result:
497
+
498
+ ```json
499
+ {
500
+ "exitCode": 0,
501
+ "signal": null,
502
+ "timedOut": false,
503
+ "stdout": "...",
504
+ "stderr": "...",
505
+ "durationMs": 1200
506
+ }
507
+ ```
508
+
509
+ `command.start` result:
510
+
511
+ ```json
512
+ {
513
+ "processId": "proc_...",
514
+ "status": "running",
515
+ "commandPreview": "npm run dev",
516
+ "startedAt": "2026-06-23T00:00:00.000Z"
517
+ }
518
+ ```
519
+
520
+ ### Codex Operations
521
+
522
+ Required:
523
+
524
+ - `codex.run`: run a prompt in a scope.
525
+ - `codex.start`: start a managed Codex process/session.
526
+ - `codex.read`: read session output/status.
527
+ - `codex.stop`: stop a session.
528
+ - `codex.list`: list recent sessions.
529
+
530
+ Higher-level workflows such as plan, review, fix, and test are allowed, but
531
+ they should remain wrappers around the core Codex operations rather than
532
+ expanding the public surface.
533
+
534
+ Contract details:
535
+
536
+ - `target` is the working directory or existing Codex session id, depending on
537
+ the operation.
538
+ - `input.prompt` is required for `codex.run` and `codex.start`.
539
+ - Codex runs inherit command policy plus `codex:run`.
540
+ - Codex must run with the configured current working directory.
541
+ - all Codex stdout/stderr and final status are stored in history.
542
+ - writes made by Codex are not separately trusted; clients should inspect diffs
543
+ after Codex runs.
544
+
545
+ `codex.run` result:
546
+
547
+ ```json
548
+ {
549
+ "sessionId": "codex_...",
550
+ "exitCode": 0,
551
+ "stdout": "...",
552
+ "stderr": "...",
553
+ "diffSummary": {
554
+ "changedFiles": 2,
555
+ "insertions": 20,
556
+ "deletions": 4
557
+ }
558
+ }
559
+ ```
560
+
561
+ ### Screenshot Operations
562
+
563
+ Required:
564
+
565
+ - `screen.capture`: capture full screen or selected display.
566
+ - `screen.list`: list displays and capturable windows/processes when available.
567
+ - `screen.capture_window`: capture a specific window when supported.
568
+ - `screen.capture_process`: capture the visible window for a process when
569
+ supported.
570
+
571
+ Screenshot results should return metadata and either image bytes or a temporary
572
+ file reference, depending on transport limits.
573
+
574
+ Safety requirements:
575
+
576
+ - report platform permission state.
577
+ - fail clearly when the OS blocks screen recording.
578
+ - allow future redaction/masking before returning images.
579
+ - audit every screenshot request.
580
+
581
+ Contract details:
582
+
583
+ - `screen.list` returns displays, windows, and process/window mappings when
584
+ available.
585
+ - `screen.capture` uses `target` as display id or `primary`.
586
+ - `screen.capture_window` uses `target` as window id.
587
+ - `screen.capture_process` uses `target` as process id or process name and
588
+ captures that process's active visible window when possible.
589
+ - `options.format` supports `png` first. `jpeg` is optional.
590
+ - `options.maxWidth` and `options.maxHeight` can downscale before returning.
591
+ - `options.return` is `bytes`, `base64`, or `fileRef`.
592
+
593
+ `screen.list` result:
594
+
595
+ ```json
596
+ {
597
+ "permission": {
598
+ "status": "granted",
599
+ "detail": null
600
+ },
601
+ "displays": [
602
+ { "id": "display-1", "primary": true, "width": 3024, "height": 1964 }
603
+ ],
604
+ "windows": [
605
+ {
606
+ "id": "window-1",
607
+ "title": "Terminal",
608
+ "processId": 123,
609
+ "processName": "Terminal"
610
+ }
611
+ ]
612
+ }
613
+ ```
614
+
615
+ `screen.capture` result:
616
+
617
+ ```json
618
+ {
619
+ "format": "png",
620
+ "width": 1512,
621
+ "height": 982,
622
+ "bytesBase64": "...",
623
+ "source": {
624
+ "type": "display",
625
+ "id": "display-1"
626
+ }
627
+ }
628
+ ```
629
+
630
+ Platform expectations:
631
+
632
+ - macOS: use Screen Recording permission; report `os_permission_required` when
633
+ not granted.
634
+ - Windows: use a Windows capture provider for display/window capture; process
635
+ capture resolves to the best matching visible window.
636
+ - Linux: support depends on desktop/session. Wayland may require portal
637
+ permission; X11 support may be broader but less secure.
638
+
639
+ ## Policy Model
640
+
641
+ Policy should be capability-based, not only booleans.
642
+
643
+ Examples:
644
+
645
+ - `fs:read`
646
+ - `fs:write`
647
+ - `command:run`
648
+ - `process:manage`
649
+ - `codex:run`
650
+ - `screen:capture`
651
+ - `network:false`
652
+ - `maxRuntimeSeconds`
653
+ - `maxOutputBytes`
654
+ - `allowedRoots`
655
+ - `allowedCommands`
656
+ - `deniedCommands`
657
+
658
+ Default policy should be conservative:
659
+
660
+ - loopback-only service.
661
+ - no public exposure without owner token.
662
+ - file access limited to configured scopes.
663
+ - command, Codex, and screenshot disabled unless explicitly enabled.
664
+ - first-run product setup with an explicit folder should remove the bootstrap
665
+ `current` scope and expose only the requested folder.
666
+ - when product setup enables command or Codex execution, attach a default
667
+ command policy with allowlisted project commands plus runtime and output caps.
668
+
669
+ Policy evaluation order:
670
+
671
+ 1. Resolve `scope`.
672
+ 2. Check operation exists.
673
+ 3. Check required capability.
674
+ 4. Check scope type supports the operation.
675
+ 5. Check path, command, process, Codex, or screenshot-specific policy.
676
+ 6. Apply runtime limits.
677
+ 7. Execute provider.
678
+ 8. Audit result.
679
+
680
+ Capability requirements:
681
+
682
+ - `file.stat`, `file.list`, `file.tree`, `file.read`, `file.read_many`,
683
+ `file.find`, `file.search`, `code.context`, `code.search_symbols`,
684
+ `git.status`, `git.changes`, `git.diff`, `git.log`, and `git.show` require
685
+ read-oriented capabilities such as `fs:read`, `search:read`, `history:read`,
686
+ or `git:read`.
687
+ - `file.write`, `file.create`, `file.patch`, `file.move`, `file.delete`
688
+ require `fs:write`.
689
+ - `git.stage`, `git.unstage`, and `git.commit` require `git:write`.
690
+ - `package.run`, `package.start`, `command.run`, and `process.start` require
691
+ `command:run` or `package:run` according to scope policy.
692
+ - `command.start` requires `command:run` and `process:manage`.
693
+ - `command.read`, `command.stop`, `command.list`, `process.read`,
694
+ `process.stop`, and `process.list` require `process:manage`.
695
+ - `codex.run`, `codex.start` require `codex:run`.
696
+ - `codex.read`, `codex.stop`, `codex.list` require `codex:run`.
697
+ - `screen.list`, `screen.capture`, `screen.capture_window`,
698
+ `screen.capture_process` require `screen:capture`.
699
+ - `history.*` requires `history:read`.
700
+
701
+ Path checks are mandatory for file operations. Command and Codex operations are
702
+ working-directory scoped, not filesystem sandboxed, unless an external sandbox
703
+ provider is explicitly configured and reported in capabilities.
704
+
705
+ ## History And Audit
706
+
707
+ Every operation should write an audit event:
708
+
709
+ - timestamp.
710
+ - machine id.
711
+ - scope.
712
+ - operation.
713
+ - target preview.
714
+ - permission/capability used.
715
+ - success/failure.
716
+ - duration.
717
+ - output summary.
718
+ - redacted error details.
719
+
720
+ History must support:
721
+
722
+ - last operation.
723
+ - session timeline.
724
+ - managed process/Codex session history.
725
+ - failed operation replay templates when safe.
726
+ - debug bundle export without secrets or file contents by default.
727
+
728
+ History views:
729
+
730
+ - `last`: most recent operation plus suggested next actions.
731
+ - `timeline`: chronological event list.
732
+ - `sessions`: grouped by client session, scope, command process, or Codex
733
+ session.
734
+ - `connections`: grouped tunnel and MCP connection summaries with session and
735
+ request IDs where the tunnel provider exposes them.
736
+ - `failed_replay`: failed operations that can be retried with missing sensitive
737
+ input supplied by the caller.
738
+ - `debug_bundle`: redacted support bundle.
739
+
740
+ Redaction rules:
741
+
742
+ - never store owner tokens.
743
+ - never store full file write payloads by default.
744
+ - never store screenshot image bytes by default.
745
+ - command/Codex output is bounded and may be redacted in debug bundles.
746
+ - screenshot capture replay templates must not be directly replayable because a
747
+ replay would capture the current screen, not the historical pixels.
748
+ - replay templates must omit sensitive fields such as file content, command
749
+ secrets, and Codex prompts when marked sensitive.
750
+
751
+ ## Transports And Exposure
752
+
753
+ Required transports:
754
+
755
+ - stdio MCP for local clients.
756
+ - HTTP MCP for remote/tunnel clients.
757
+
758
+ Exposure helpers are allowed but secondary:
759
+
760
+ - Cloudflare Tunnel.
761
+ - Tailscale Funnel.
762
+ - manual reverse proxy.
763
+
764
+ The product should always make clear which URL a client should use, whether it
765
+ is local or public, and what auth is required.
766
+ Public URL providers and OpenAI Secure MCP Tunnel are different exposure
767
+ models: OpenAI tunnel setup uses a `tunnel_...` id and should not require or
768
+ warn about `publicBaseUrl` in daily status unless another public URL provider is
769
+ being used.
770
+
771
+ Auth rules:
772
+
773
+ - stdio transport relies on local process/user trust.
774
+ - HTTP loopback may run without owner token only when bound to loopback.
775
+ - any non-loopback HTTP exposure requires owner token or stronger auth.
776
+ - bearer token is acceptable for v1.
777
+ - OAuth metadata can exist as compatibility, but must wrap the same generic MCP
778
+ contract and must not add ChatGPT-specific semantics.
779
+
780
+ Smoke tests:
781
+
782
+ - installed CLI self-test using a temporary config and workspace.
783
+ - local MCP initialize, tools/list, `get_computer_info`, and read-only
784
+ `computer_operation` through the MCP SDK.
785
+ - HTTP `/healthz`.
786
+ - authenticated `get_computer_info`.
787
+ - one read-only operation in a configured scope.
788
+ - screenshot capability probe without capturing pixels unless explicitly
789
+ requested.
790
+
791
+ ## Management Surface
792
+
793
+ The human management surface is CLI-first:
794
+
795
+ - service status.
796
+ - policy/scopes.
797
+ - tool readiness.
798
+ - tunnel/exposure status.
799
+ - history.
800
+ - active processes.
801
+ - screenshot permission diagnostics.
802
+
803
+ The product should not rely on a local browser dashboard for setup or
804
+ operations. The JSON API remains a protocol surface for MCP clients,
805
+ automation, and smoke checks rather than a human-facing management UI.
806
+ The default CLI help should stay short and focused on first-run start, tunnel
807
+ selection, client setup, status, and quickstart preview. Self-test, smoke,
808
+ repair, service/config/API, history, and compatibility commands remain available
809
+ through advanced or focused help topics rather than the first-run surface.
810
+
811
+ Required management actions:
812
+
813
+ - initialize machine identity.
814
+ - create/edit/remove scopes.
815
+ - enable/disable capabilities per scope.
816
+ - show exact MCP URLs.
817
+ - generate/rotate owner token.
818
+ - run local smoke tests.
819
+ - display screenshot permission status.
820
+ - list/stop managed command and Codex processes.
821
+ - inspect/export redacted history.
822
+
823
+ ## Platform Requirements
824
+
825
+ ### Windows
826
+
827
+ Required:
828
+
829
+ - file operations.
830
+ - command/process management.
831
+ - Codex invocation when installed.
832
+ - computer info.
833
+ - display screenshot capability probe.
834
+ - primary-display screenshot capture in an interactive desktop session.
835
+
836
+ Target:
837
+
838
+ - active-window screenshot.
839
+ - process-to-window screenshot when a visible window can be resolved.
840
+
841
+ ### macOS
842
+
843
+ Required:
844
+
845
+ - file operations.
846
+ - command/process management.
847
+ - Codex invocation when installed.
848
+ - computer info.
849
+ - screenshot permission probe.
850
+
851
+ Target:
852
+
853
+ - display screenshot.
854
+ - window screenshot.
855
+ - process-to-window screenshot through visible window metadata.
856
+
857
+ ### Linux
858
+
859
+ Required:
860
+
861
+ - file operations.
862
+ - command/process management.
863
+ - Codex invocation when installed.
864
+ - computer info.
865
+ - screenshot capability probe.
866
+
867
+ Target:
868
+
869
+ - screenshot through the active desktop/session provider where available.
870
+ - clear unsupported/permission errors under Wayland or headless environments.
871
+
872
+ ## Implementation Priority
873
+
874
+ Implement in this order:
875
+
876
+ 1. Normalize product language around computer, scope, operation, and policy.
877
+ 2. Expose the small MCP surface while keeping existing tools as compatibility.
878
+ 3. Implement `get_computer_info` from current capabilities.
879
+ 4. Implement `computer_operation` as the generic dispatcher.
880
+ 5. Map existing file/search/command/Codex operations into dotted operation
881
+ names.
882
+ 6. Add screenshot capability probe and full-screen capture.
883
+ 7. Add window/process screenshot support by platform.
884
+ 8. Tighten history/debug bundle around the new operation envelope.
885
+ 9. Trim ChatGPT-specific code paths to thin setup exports over the generic MCP
886
+ contract.
887
+
888
+ ## First Product Milestone
889
+
890
+ The first productized milestone is complete only when these are true:
891
+
892
+ 1. A user can install/run one local MCP service on Windows/macOS/Linux.
893
+ 2. A client can call a small MCP surface and discover computer capabilities.
894
+ 3. File read/write/list/search works inside configured scopes.
895
+ 4. Commands can run under policy with timeout/output limits.
896
+ 5. Codex can be run and inspected as a managed workflow.
897
+ 6. Full-screen screenshot works on at least one platform and reports capability
898
+ status on the others.
899
+ 7. History shows every operation and can export a redacted debug bundle.
900
+ 8. Local and HTTP transports are documented and smoke-testable.
901
+ 9. `status` exposes short daily readiness for humans and scripts, while
902
+ `status --details` keeps diagnostic rows out of the default view. `doctor`
903
+ exposes release readiness, config diagnostics, and security diagnostics that
904
+ can block an alpha release before packaging or exposure, and `doctor --fix`
905
+ can apply deterministic local config repairs.
906
+ 10. The default CI gate is manual and cost-capped: it runs the product gate on
907
+ Windows with the primary supported Node line. Broader OS or Node coverage is
908
+ a wider-release check, not the routine push gate.
909
+
910
+ Anything outside this list should be treated as supporting work, not the center
911
+ of the product.