@octane-xplat/mcp 0.1.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +342 -1
  3. package/dist/_virtual/_rolldown/runtime.js +27 -0
  4. package/dist/actions/bridge.js +1 -0
  5. package/dist/context.js +0 -0
  6. package/dist/contracts/actions.js +1 -0
  7. package/dist/contracts/boundaries.js +1 -0
  8. package/dist/contracts/capabilities.js +1 -0
  9. package/dist/contracts/code.js +1 -0
  10. package/dist/contracts/errors.js +8 -0
  11. package/dist/contracts/evidence.js +8 -0
  12. package/dist/contracts/identity.js +8 -0
  13. package/dist/contracts/index.js +1 -0
  14. package/dist/contracts/inspection.js +1 -0
  15. package/dist/contracts/policy.js +8 -0
  16. package/dist/contracts/sessions.js +1 -0
  17. package/dist/contracts/status.js +1 -0
  18. package/dist/discovery.js +8 -0
  19. package/dist/docs.js +63 -0
  20. package/dist/inspection/service.js +3 -0
  21. package/dist/inspection/tools.js +43 -0
  22. package/dist/runtime/logs.js +1 -0
  23. package/dist/runtime/process.js +1 -0
  24. package/dist/runtime/service.js +1 -0
  25. package/dist/runtime/targets.js +1 -0
  26. package/dist/runtime/tools.js +119 -0
  27. package/dist/server.js +324 -0
  28. package/dist/status.js +8 -0
  29. package/dist/xplat-mcp.js +68 -0
  30. package/package.json +43 -4
  31. package/src/actions/bridge.ts +2 -0
  32. package/src/context.ts +108 -0
  33. package/src/contracts/actions.ts +3 -0
  34. package/src/contracts/boundaries.ts +3 -0
  35. package/src/contracts/capabilities.ts +3 -0
  36. package/src/contracts/code.ts +3 -0
  37. package/src/contracts/errors.ts +3 -0
  38. package/src/contracts/evidence.ts +3 -0
  39. package/src/contracts/identity.ts +3 -0
  40. package/src/contracts/index.ts +3 -0
  41. package/src/contracts/inspection.ts +3 -0
  42. package/src/contracts/policy.ts +3 -0
  43. package/src/contracts/sessions.ts +3 -0
  44. package/src/contracts/status.ts +3 -0
  45. package/src/discovery.ts +2 -0
  46. package/src/docs.ts +89 -0
  47. package/src/inspection/service.ts +5 -0
  48. package/src/inspection/tools.ts +61 -0
  49. package/src/runtime/logs.ts +2 -0
  50. package/src/runtime/process.ts +2 -0
  51. package/src/runtime/service.ts +2 -0
  52. package/src/runtime/targets.ts +2 -0
  53. package/src/runtime/tools.ts +136 -0
  54. package/src/server.ts +580 -0
  55. package/src/status.ts +2 -0
  56. package/src/xplat-mcp.ts +96 -0
  57. package/types/contracts/actions.d.ts +209 -0
  58. package/types/contracts/boundaries.d.ts +6 -0
  59. package/types/contracts/capabilities.d.ts +106 -0
  60. package/types/contracts/code.d.ts +134 -0
  61. package/types/contracts/errors.d.ts +75 -0
  62. package/types/contracts/evidence.d.ts +115 -0
  63. package/types/contracts/identity.d.ts +127 -0
  64. package/types/contracts/index.d.ts +11 -0
  65. package/types/contracts/inspection.d.ts +45 -0
  66. package/types/contracts/policy.d.ts +86 -0
  67. package/types/contracts/sessions.d.ts +160 -0
  68. package/types/contracts/status.d.ts +40 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 Alec Larson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,344 @@
1
1
  # @octane-xplat/mcp
2
2
 
3
- Bootstrap placeholder for automated publishing. This version has no supported API.
3
+ MCP server for agents working on Octane Xplat consumer apps. One entry point
4
+ gives the agent detected project identity, framework versions, guidance,
5
+ capability discovery, and the shared permission / session / evidence contracts
6
+ that every later subsystem (docs, code search, runtime, inspection,
7
+ development actions) plugs into.
8
+
9
+ Published as a normal lockstep package on npm. The qualified surface today is
10
+ the Chromium consumer lane (status/docs/code/build/launch/inspection/
11
+ interaction/development actions); native-platform inspection and input
12
+ adapters report honest `unavailable` results until they are qualified — see
13
+ [Remaining acceptance](#remaining-acceptance).
14
+
15
+ ## Install and run
16
+
17
+ Add the server to a consumer app and point the agent's MCP client at the
18
+ installed `xplat-mcp` bin:
19
+
20
+ ```sh
21
+ pnpm add -D @octane-xplat/mcp
22
+ ```
23
+
24
+ ```json
25
+ {
26
+ "mcpServers": {
27
+ "octane-xplat": {
28
+ "command": "xplat-mcp",
29
+ "args": ["--workspace", "/path/to/app-workspace"]
30
+ }
31
+ }
32
+ }
33
+ ```
34
+
35
+ A one-off run without a devDependency also works:
36
+
37
+ ```sh
38
+ pnpm dlx @octane-xplat/mcp --workspace /path/to/app-workspace
39
+ ```
40
+
41
+ For development inside this repository — `start` runs the TypeScript source
42
+ directly (Node ≥22.18 strips types); `test` and `prepack` run `vite build` so
43
+ the checked and packed surface is the emitted `dist/`:
44
+
45
+ ```sh
46
+ pnpm --filter @octane-xplat/mcp start -- --workspace <path>
47
+ pnpm --filter @octane-xplat/mcp test
48
+ ```
49
+
50
+ Transport is stdio; stdout is protocol-clean (diagnostics go to stderr).
51
+ Options: `--workspace` / `XPLAT_MCP_WORKSPACE` (default cwd), `--app` /
52
+ `XPLAT_MCP_APP` (pre-select an app id), `--permissions` /
53
+ `XPLAT_MCP_PERMISSIONS` (comma-separated scope grants), `--evidence-dir` /
54
+ `XPLAT_MCP_EVIDENCE_DIR`.
55
+
56
+ ## Tools
57
+
58
+ | Tool | Purpose |
59
+ | --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
60
+ | `xplat_project_status` | Detected apps, selection state, framework version binding, guidance sources, docs/code-index status, declared platforms, runtime prerequisites, capability summary, permissions, boundaries, next steps. |
61
+ | `xplat_select_app` | Explicitly bind an app by id/path/name. Ambiguous or unknown selections fail with the candidate list — the server never picks silently. |
62
+ | `xplat_capability_matrix` | Per-platform capability entries: build, launch, logs, inspection, screenshot, interaction, and the rest are separate rows with status, detail, and alternatives. |
63
+ | `xplat_permissions` | Grant states per scope plus the action-time check result and recovery path. |
64
+ | `xplat_sessions` | Bound sessions: owned vs attached user-owned, state, build identity. |
65
+ | `xplat_targets` | Launchable targets per platform (simulators, devices, host targets) with availability, missing-toolchain reasons, and busy/ownership state. |
66
+ | `xplat_build` | Build the bound app for one platform as a job — same commands `xplat build` runs. `requestKey` dedupes retries. |
67
+ | `xplat_launch` | Owned dev session on one target as a job; completes at confirmed readiness, session owns the processes until `xplat_session_end`. |
68
+ | `xplat_attach` | Bind a compatible already-running dev session (user-owned, preserved). |
69
+ | `xplat_logs` | Bounded ordered logs for a session or build job: cursor, limit, stream filter, truncation/reset indicators, `historical` flag for dead sessions. |
70
+ | `xplat_dev_actions` | The bound app's live development-action registry: instance identity, revision, declarations (contracts, effects, availability). Empty vs disconnected vs no-bridge are distinct states. |
71
+ | `xplat_dev_action_invoke` | Invoke an action against an exact app instance + registry revision. Pre-validates input, availability, grants and queue bounds; returns a job (`requestKey` dedupes retries). |
72
+ | `xplat_dev_action_status` | Invocation status/result — same job data restricted to dev-action jobs, with instance/request identity. |
73
+ | `xplat_job_status` / `xplat_job_cancel` | Bounded job status and cooperative cancellation. |
74
+ | `xplat_session_end` | Ownership-safe cleanup: owned sessions release resources; attached sessions are preserved (our log taps still stop). |
75
+ | `xplat_evidence` | `list` / `retain` / `delete` evidence; retain takes an optional ISO expiration. |
76
+ | `xplat_code_search` | Exact identifier/token search over current source (`mode: 'exact'`), optional local semantic index (`mode: 'semantic'`), or both (`'auto'`). Corpus filters: `app`, `framework`; platform and package filters. |
77
+ | `xplat_code_read` | Bounded read of current source by search ref (`xplat-code://…`) or explicit corpus + path; results carry freshness markers and continuation offsets. |
78
+ | `xplat_docs_search` / `xplat_docs_read` | Installed-version docs search and bounded page reads, with snapshot/version provenance and unavailable/conflict results. |
79
+ | `xplat_guidance` | Tailored guidance for the selected app's installed packages. |
80
+
81
+ ## Retrieve the app's documentation
82
+
83
+ Select your app first. Search defaults to maintained guides for its actual
84
+ installed versions; design notes and recipes require an explicit corpus.
85
+ The provider validates release tags and preserves cached snapshot commits.
86
+ Missing matching docs return an installed-source fallback instead of latest docs.
87
+
88
+ ```json
89
+ {
90
+ "name": "xplat_docs_search",
91
+ "arguments": { "query": "testID", "package": "@octane-xplat/ui", "platform": "web" }
92
+ }
93
+ ```
94
+
95
+ Read a result using its `ref`. A ref from an older installation remains tied
96
+ to that version and is labeled outside the installed binding after an upgrade.
97
+ `xplat_project_status` reports provider readiness; each search reports actual
98
+ snapshot availability, so readiness alone is not a successful retrieval.
99
+
100
+ ```json
101
+ {
102
+ "name": "xplat_docs_read",
103
+ "arguments": {
104
+ "package": "@octane-xplat/ui",
105
+ "path": "docs/verify/test-identifiers.md",
106
+ "limit": 2000
107
+ }
108
+ }
109
+ ```
110
+
111
+ Code search reads the bound application's source plus its installed
112
+ `@octane-xplat/*` package sources — corpora stay labeled and distinguishable.
113
+ The semantic index is local TF-IDF (`local-tfidf`): it builds in the
114
+ background, reports `preparing` / `ready` / `stale` / `unavailable`, and stale
115
+ hits are revalidated against current file content before serving. Nothing
116
+ leaves the machine; there is no remote embedding path. Secrets, private
117
+ configuration, generated output, and paths outside the bound scope are
118
+ excluded and unreadable.
119
+
120
+ Every result is `{ ok: true, data } | { ok: false, error }` where `error` is a
121
+ `ContractError` from the shared vocabulary.
122
+
123
+ The service layer lives in `packages/cli/src/mcp/` — the `xplat` CLI projects
124
+ the same contracts through its agent commands (`xplat catalog --json` is the
125
+ entry point). `packages/mcp/src/` holds the stdio transport adapter: tool
126
+ registration wraps the shared services, and the published `.d.ts` contract
127
+ surface stays here under `types/contracts/`. Sources are TypeScript; `pnpm
128
+ build` emits the runnable ESM to `dist/` (`pnpm test` builds first).
129
+
130
+ ## Contract surface (`@octane-xplat/mcp/contracts/*`)
131
+
132
+ Later work packages integrate against these modules; the `.d.ts` files under
133
+ `types/contracts/` are the documented surface and the compiled `dist/` modules
134
+ carry the runtime values and stores (re-exported from `@octane-xplat/cli`).
135
+
136
+ - `errors` — `ContractErrorCode` vocabulary (`invalid_selection`,
137
+ `ambiguous_selection`, `permission_denied`, `unsupported_capability`,
138
+ `prerequisite_missing`, `target_busy`, `stale_identity`,
139
+ `disconnected_runtime`, `execution_failure`, `not_found`, `cancelled`,
140
+ `timeout`, `unavailable`) with `recovery` (smallest corrective action) and
141
+ `retryable` semantics.
142
+ - `identity` — `Platform`, `AppRef`, `FrameworkBinding` (installed / workspace /
143
+ lockfile / provisional version sources), `GuidanceStatus`,
144
+ `RuntimePrerequisite`, `AppSelection` (`bound` / `ambiguous` / `none`).
145
+ - `capabilities` — `CapabilityId`, `CapabilityStatus`, `CapabilityEntry`,
146
+ `PlatformCapabilityMatrix`, and the `CapabilityProvider` / registry seam
147
+ adapters use to report real support.
148
+ - `policy` — `PermissionScope` grants (`workspace`, `runtime-actions`,
149
+ `visual-capture`, `evidence-retain`, `external-effects`), `PolicyStore` with
150
+ task-authorization baseline, action-time checks, expiry, revocation, and an
151
+ elicitation channel for explicit developer grants. `visual-capture` is never
152
+ baseline-granted.
153
+ - `sessions` — `SessionBinding` (`owned` / `attached`, `starting` / `ready` /
154
+ `disconnected` / `stopped`), `Job` (`queued` → `running` → terminal, with
155
+ `cancelling` / `cancelled`), request-key deduplication, and ownership-safe
156
+ `end` / `shutdown`.
157
+ - `evidence` — `EvidenceRecord` with provenance (app, platform, target,
158
+ session, build identity, time, interaction mechanism), session-scoped
159
+ default retention, `retain` with expiration, ownership-safe deletion, and
160
+ `TRANSCRIPT_LIMITATION_NOTE`. `isOsInputEvidence` is the guard that keeps
161
+ handler-dispatch results from being labeled OS-input verification.
162
+ - `status` — `ProjectStatusReport`, the shape `xplat_project_status` returns.
163
+ - `code` — the `CodeProvider` seam the context's `code` slot consumes, plus
164
+ `CodeHit` / `CodeSearchResult` / provenance and freshness shapes.
165
+ - `boundaries` — `PRODUCT_BOUNDARIES`, the advertised out-of-scope list.
166
+ - `actions` — the app-declared development-action wire contract (package G):
167
+ `DevActionDeclaration` (stable id, title, description, runtime-validatable
168
+ input/result field contracts, disclosed effects, availability, execution
169
+ policy), `DevActionRegistryAnnouncement` (instance identity + revision +
170
+ declarations), invocation request/outcome types, and the field-subset
171
+ validators both sides share. The app announces its registry through a
172
+ dev-bridge (`xplatDevBridge` vite middleware in `@octane-xplat/cli`, included
173
+ in the `xplatNative` preset); the server scans the app's bridge session
174
+ files under `node_modules/.cache/xplat/dev-bridge/` and polls live
175
+ announcements — an empty registry is never confused with a disconnected app.
176
+
177
+ ## Runtime (work item D)
178
+
179
+ The shared `runtime/` service (in `packages/cli/src/mcp/runtime/`, re-exported
180
+ here) implements build/launch/attach/logs/cleanup for consumer apps
181
+ on all six platforms. Adapters (`runtime/adapters/*`) own platform
182
+ mechanics and always spawn the app's own toolchain — `pnpm exec vite`,
183
+ `pnpm exec ns run …`, the app's installed `@octane-xplat/cli` dev entry, or
184
+ its `dev` script — so a session behaves like the app's installed framework
185
+ version. The shared `runtime/service` module owns the contract behavior: explicit
186
+ app+target binding, `target_busy` contention, job dedupe/cooperative
187
+ cancel, ownership-safe cleanup, bounded logs, and capability-matrix entries.
188
+
189
+ | Platform | Launch | Attach | Host gate |
190
+ | -------------- | ----------------------------------------------------------------- | -------------------------------------------------- | ---------- |
191
+ | web / Chromium | `pnpm exec vite` + headless Chromium (devtools endpoint reported) | probe common dev ports — identity heuristic | none |
192
+ | iOS | `ns run ios --device <udid>` | booted sim + app running → `simctl log stream` tap | macOS |
193
+ | Android | `ns run android --device <serial>` | package running → `adb logcat --pid` tap | none (adb) |
194
+ | macOS | `xplat.targets.macos.dev` → CLI dev entry, else `pnpm run dev` | pgrep on app root — no scrollback | macOS |
195
+ | Linux | `pnpm run dev` (app-owned script) | pgrep on app root | Linux |
196
+ | Windows | `ns run windows` | not yet qualified | Windows |
197
+
198
+ Readiness is probe/marker-confirmed (`ready` session state) — HTTP 200 for
199
+ web, the host-start marker for macOS, `Successfully synced application` /
200
+ first `CONSOLE` line for `ns run`. A timeout or pre-ready exit fails the job
201
+ and ends the owned session honestly. Chromium is located via
202
+ `XPLAT_MCP_CHROMIUM`, the Playwright browser cache, or system installs;
203
+ without it the web session still reports the server URL with an explicit
204
+ `browser.launched: false`.
205
+
206
+ Physical iOS devices, Windows attach detection, and non-simulator iOS log
207
+ taps are reported limitations, not silent gaps — the capability matrix
208
+ carries the detail and an alternative.
209
+
210
+ ## Inspect and interact with Chromium
211
+
212
+ This development package adds `xplat_inspect`, `xplat_interact`, and
213
+ `xplat_screenshot` for the Chromium browser started by `xplat_launch`.
214
+ Select a DOM `id` or shared `testID` explicitly; duplicate names fail.
215
+ Inspection returns bounded text/value/geometry, a document identity, and
216
+ session/build provenance. Main-document DOM hosts are the qualified surface;
217
+ shadow roots, frames, component ownership and signals are excluded.
218
+
219
+ ```json
220
+ {
221
+ "name": "xplat_inspect",
222
+ "arguments": {
223
+ "sessionId": "SESSION_FROM_LAUNCH",
224
+ "control": { "kind": "testID", "name": "counter.increment" }
225
+ }
226
+ }
227
+ ```
228
+
229
+ Pass the returned `documentId` when interacting. A `dom-event` interaction
230
+ clicks the control center through CDP. `os-input` sends Space or Enter through
231
+ the macOS event system to the owned headed Chromium process. It requires
232
+ Swift, OS event-posting permission, and a desktop-input reservation. The
233
+ server does not open permission prompts. Inspect the resulting app state
234
+ separately; sending input alone is not an assertion.
235
+
236
+ ```json
237
+ {
238
+ "name": "xplat_interact",
239
+ "arguments": {
240
+ "sessionId": "SESSION_FROM_LAUNCH",
241
+ "documentId": "DOCUMENT_FROM_INSPECTION",
242
+ "control": { "kind": "testID", "name": "counter.increment" },
243
+ "mechanism": "os-input",
244
+ "key": "Space"
245
+ }
246
+ }
247
+ ```
248
+
249
+ Screenshot requests require an explicit current-task `visual-capture` grant
250
+ before connecting or sending a capture command. No grant means no capture.
251
+ Password fields, hidden inputs and hosts marked `data-xplat-private` are
252
+ redacted in nonvisual inspection; this does not guarantee complete redaction
253
+ of arbitrary application data.
254
+
255
+ ```json
256
+ { "name": "xplat_screenshot", "arguments": { "sessionId": "SESSION_FROM_LAUNCH" } }
257
+ ```
258
+
259
+ ## Run the consumer acceptance lane
260
+
261
+ Use a fresh directory outside your existing app. These commands scaffold the
262
+ normal web starter and add one app-owned development action. The in-repo lane
263
+ links framework packages to this checkout; other dependencies
264
+ install normally. The runner checks docs and current code, build/readiness,
265
+ the counter's `0 → 1` transition, action discovery/invocation, screenshot
266
+ denial, logs, and owned browser/server/profile cleanup. It also checks that
267
+ the fixture declaration and handler are absent from production artifacts.
268
+
269
+ ```sh
270
+ node packages/mcp/tests/prepare-consumer.mjs /tmp/new-xplat-mcp-app
271
+ pnpm --dir /tmp/new-xplat-mcp-app install
272
+ node packages/mcp/tests/consumer-workflow.mjs /tmp/new-xplat-mcp-app
273
+ ```
274
+
275
+ The default run supplies browser-event evidence. On macOS, reserve the full
276
+ resource set and add `--os-input` for a headed Chromium OS keyboard journey.
277
+ Only the owned browser receives the events; the helper attempts to restore the
278
+ previously active application and reports when restoration is unconfirmed.
279
+ The runner captures no images.
280
+
281
+ ```sh
282
+ goddard-agent resource run --json '{"resources":{"native_builds":1,"desktop_input":1},"purpose":"MCP consumer OS keyboard acceptance"}' -- node packages/mcp/tests/consumer-workflow.mjs /tmp/new-xplat-mcp-app --os-input
283
+ ```
284
+
285
+ The packed-artifact lane qualifies the same checks against release-evidence
286
+ packaging: `prepare-packed-consumer.mjs` packs the needed packages, scaffolds
287
+ through the packed `create-octane-xplat` bin, installs `file:` tarballs (no
288
+ registry/latest resolution for framework packages), and tags the framework
289
+ HEAD as `v<installed version>` in a local bare release fixture. The runner
290
+ spawns the consumer's own installed `xplat-mcp` bin over stdin/stdout and
291
+ redirects the canonical release-repo URL to the fixture through a per-process
292
+ `url.insteadOf` (never user git config). Snapshot cache and evidence roots are
293
+ isolated under the work dir. OS keyboard input additionally requires an
294
+ unlocked console — the window server refuses activation while the screen is
295
+ locked, and the run reports that block honestly.
296
+
297
+ ```sh
298
+ goddard-agent resource run --json '{"resources":{"native_builds":1,"desktop_input":1},"purpose":"packed MCP stdio consumer acceptance"}' -- bash -c '
299
+ node packages/mcp/tests/prepare-packed-consumer.mjs /tmp/xplat-packed-mcp &&
300
+ node packages/mcp/tests/packed-stdio-consumer.mjs /tmp/xplat-packed-mcp'
301
+ ```
302
+
303
+ For an existing consumer, declare actions behind the development build gate.
304
+ Registration automatically starts the bridge when the dev-server endpoint is
305
+ present. The action's contracts and effects appear in `xplat_dev_actions`;
306
+ no action-specific MCP tool definition is needed.
307
+
308
+ ```ts
309
+ if (import.meta.env.DEV) {
310
+ const { registerDevAction } = await import('@octane-xplat/platform/dev-actions')
311
+ registerDevAction({
312
+ id: 'fixture.describe-counter',
313
+ title: 'Describe the counter',
314
+ description: 'Identify this test fixture without external effects.',
315
+ result: { fields: { label: { type: 'string' } } },
316
+ effects: { summary: 'Read fixture identity.' },
317
+ run: () => ({ label: 'starter-counter' }),
318
+ })
319
+ }
320
+ ```
321
+
322
+ ## Remaining acceptance
323
+
324
+ The Chromium lane is an incremental milestone. All six platforms remain
325
+ required by the original plan. Native inspection/input adapters, attached
326
+ Chromium inspection, approved screenshot qualification, and the complete
327
+ platform-by-capability acceptance matrix remain unfinished. Runtime adapters
328
+ and honest unavailable responses do not establish native behavior.
329
+
330
+ | Target | Inspection/input qualification boundary |
331
+ | --------------- | ------------------------------------------------------------------------------ |
332
+ | Chromium | Owned main-document DOM; browser events plus macOS scoped OS keyboard path |
333
+ | iOS / Android | Native host inspection and OS-input adapters still required |
334
+ | macOS | AppKit host inspection/input still required; Chromium on macOS is web evidence |
335
+ | Linux / Windows | Target-host adapters and independent consumer qualification still required |
336
+
337
+ ## Boundaries
338
+
339
+ This server complements the agent's editing tools. It is not an autonomous
340
+ code editor or deployment system: no arbitrary shell execution, no arbitrary
341
+ runtime expression evaluation, no universal component tree, no hook/signal
342
+ inspection, no profiling API, no cloud indexing by default, no app-store
343
+ operations, no credential management. Screenshots are permission-gated —
344
+ capability existence never implies capture approval.
@@ -0,0 +1,27 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __exportAll = (all, no_symbols) => {
7
+ let target = {};
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ return target;
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
17
+ key = keys[i];
18
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
19
+ get: ((k) => from[k]).bind(null, key),
20
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
21
+ });
22
+ }
23
+ return to;
24
+ };
25
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
26
+ //#endregion
27
+ export { __exportAll, __reExport };
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/actions/bridge";
File without changes
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/contracts/actions";
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/contracts/boundaries";
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/contracts/capabilities";
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/contracts/code";
@@ -0,0 +1,8 @@
1
+ import { __exportAll, __reExport } from "../_virtual/_rolldown/runtime.js";
2
+ export * from "@octane-xplat/cli/mcp/contracts/errors";
3
+ //#region src/contracts/errors.ts
4
+ var errors_exports = /* @__PURE__ */ __exportAll({});
5
+ import * as import__octane_xplat_cli_mcp_contracts_errors from "@octane-xplat/cli/mcp/contracts/errors";
6
+ __reExport(errors_exports, import__octane_xplat_cli_mcp_contracts_errors);
7
+ //#endregion
8
+ export { errors_exports };
@@ -0,0 +1,8 @@
1
+ import { __exportAll, __reExport } from "../_virtual/_rolldown/runtime.js";
2
+ export * from "@octane-xplat/cli/mcp/contracts/evidence";
3
+ //#region src/contracts/evidence.ts
4
+ var evidence_exports = /* @__PURE__ */ __exportAll({});
5
+ import * as import__octane_xplat_cli_mcp_contracts_evidence from "@octane-xplat/cli/mcp/contracts/evidence";
6
+ __reExport(evidence_exports, import__octane_xplat_cli_mcp_contracts_evidence);
7
+ //#endregion
8
+ export { evidence_exports };
@@ -0,0 +1,8 @@
1
+ import { __exportAll, __reExport } from "../_virtual/_rolldown/runtime.js";
2
+ export * from "@octane-xplat/cli/mcp/contracts/identity";
3
+ //#region src/contracts/identity.ts
4
+ var identity_exports = /* @__PURE__ */ __exportAll({});
5
+ import * as import__octane_xplat_cli_mcp_contracts_identity from "@octane-xplat/cli/mcp/contracts/identity";
6
+ __reExport(identity_exports, import__octane_xplat_cli_mcp_contracts_identity);
7
+ //#endregion
8
+ export { identity_exports };
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/contracts/index";
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/contracts/inspection";
@@ -0,0 +1,8 @@
1
+ import { __exportAll, __reExport } from "../_virtual/_rolldown/runtime.js";
2
+ export * from "@octane-xplat/cli/mcp/contracts/policy";
3
+ //#region src/contracts/policy.ts
4
+ var policy_exports = /* @__PURE__ */ __exportAll({});
5
+ import * as import__octane_xplat_cli_mcp_contracts_policy from "@octane-xplat/cli/mcp/contracts/policy";
6
+ __reExport(policy_exports, import__octane_xplat_cli_mcp_contracts_policy);
7
+ //#endregion
8
+ export { policy_exports };
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/contracts/sessions";
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/contracts/status";
@@ -0,0 +1,8 @@
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
2
+ export * from "@octane-xplat/cli/mcp/discovery";
3
+ //#region src/discovery.ts
4
+ var discovery_exports = /* @__PURE__ */ __exportAll({});
5
+ import * as import__octane_xplat_cli_mcp_discovery from "@octane-xplat/cli/mcp/discovery";
6
+ __reExport(discovery_exports, import__octane_xplat_cli_mcp_discovery);
7
+ //#endregion
8
+ export { discovery_exports };
package/dist/docs.js ADDED
@@ -0,0 +1,63 @@
1
+ import { errors_exports } from "./contracts/errors.js";
2
+ import { identity_exports } from "./contracts/identity.js";
3
+ import { status_exports } from "./status.js";
4
+ import { z } from "zod";
5
+ //#region src/docs.ts
6
+ function registerDocsTools(server, context, respond) {
7
+ const run = (method) => async (args) => {
8
+ const permission = context.policy.require("workspace");
9
+ if (!permission.granted) return respond({
10
+ ok: false,
11
+ error: permission.error
12
+ });
13
+ const selection = (0, status_exports.resolveSelection)(context);
14
+ if (selection.state !== "bound") return respond({
15
+ ok: false,
16
+ error: (0, errors_exports.contractError)(selection.state === "ambiguous" ? "ambiguous_selection" : "invalid_selection", "Bind an app with xplat_select_app before retrieving docs.")
17
+ });
18
+ try {
19
+ return respond({
20
+ ok: true,
21
+ data: await context.docs.serviceFor(selection.app)[method](args)
22
+ });
23
+ } catch (error) {
24
+ return respond({
25
+ ok: false,
26
+ error: (0, errors_exports.toContractError)(error)
27
+ });
28
+ }
29
+ };
30
+ server.registerTool("xplat_docs_search", {
31
+ description: "Search the selected app’s installed-version docs. Results include version/snapshot provenance, unavailable packages, conflicts, and separately labeled project guidance.",
32
+ inputSchema: {
33
+ query: z.string().trim().min(1).max(500),
34
+ package: z.string().optional(),
35
+ version: z.string().optional().describe("Explicit comparison version, visibly outside the installed binding."),
36
+ platform: z.enum(identity_exports.PLATFORMS).optional(),
37
+ corpus: z.enum([
38
+ "guide",
39
+ "recipe",
40
+ "design-note",
41
+ "implementation-note"
42
+ ]).optional().default("guide"),
43
+ limit: z.number().int().min(1).max(50).optional()
44
+ }
45
+ }, run("search"));
46
+ server.registerTool("xplat_docs_read", {
47
+ description: "Read a bounded documentation page from a search ref, or package and path, preserving its version binding.",
48
+ inputSchema: {
49
+ ref: z.string().optional(),
50
+ package: z.string().optional(),
51
+ path: z.string().optional(),
52
+ version: z.string().optional(),
53
+ offset: z.number().int().min(0).optional(),
54
+ limit: z.number().int().min(1).max(2e4).optional()
55
+ }
56
+ }, run("read"));
57
+ server.registerTool("xplat_guidance", {
58
+ description: "Retrieve tailored guidance for the selected app’s actual installed package versions.",
59
+ inputSchema: {}
60
+ }, run("guidance"));
61
+ }
62
+ //#endregion
63
+ export { registerDocsTools };
@@ -0,0 +1,3 @@
1
+ import { registerInspectionTools } from "./tools.js";
2
+ import { createInspectionService } from "@octane-xplat/cli/mcp/inspection/service";
3
+ export { createInspectionService, registerInspectionTools };
@@ -0,0 +1,43 @@
1
+ import { z } from "zod";
2
+ //#region src/inspection/tools.ts
3
+ function registerInspectionTools(server, context, respond) {
4
+ const control = z.object({
5
+ kind: z.enum(["id", "testID"]),
6
+ name: z.string().min(1).max(200)
7
+ });
8
+ const run = (method) => async (args) => {
9
+ const data = await context.inspection[method](args);
10
+ return data.error ? respond({
11
+ ok: false,
12
+ error: data.error
13
+ }) : respond({
14
+ ok: true,
15
+ data
16
+ });
17
+ };
18
+ server.registerTool("xplat_inspect", {
19
+ description: "Bounded main-document named DOM hosts in the owned Chromium session. Explicit id/testID selector; duplicates fail. Password/private values are redacted. Includes document/session/build identity and coverage.",
20
+ inputSchema: {
21
+ sessionId: z.string(),
22
+ control: control.optional(),
23
+ offset: z.number().int().min(0).optional(),
24
+ limit: z.number().int().min(1).max(100).optional()
25
+ }
26
+ }, run("inspect"));
27
+ server.registerTool("xplat_interact", {
28
+ description: "Send scoped input to one stable control from an inspected document. dom-event sends a CDP mouse click; os-input sends Space/Enter via the macOS event system to owned headed Chromium. Reserve desktop input for OS actions. Input delivery is not an app assertion.",
29
+ inputSchema: {
30
+ sessionId: z.string(),
31
+ documentId: z.string(),
32
+ control,
33
+ mechanism: z.enum(["dom-event", "os-input"]),
34
+ key: z.enum(["Space", "Enter"]).optional().default("Space")
35
+ }
36
+ }, run("interact"));
37
+ server.registerTool("xplat_screenshot", {
38
+ description: "Capture the owned Chromium viewport only with a current visual-capture grant. Returns a session-scoped artifact and provenance; capability discovery never grants approval.",
39
+ inputSchema: { sessionId: z.string() }
40
+ }, run("screenshot"));
41
+ }
42
+ //#endregion
43
+ export { registerInspectionTools };
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/runtime/logs";
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/runtime/process";
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/runtime/service";
@@ -0,0 +1 @@
1
+ export * from "@octane-xplat/cli/mcp/runtime/targets";