@octane-xplat/mcp 0.15.0 → 0.16.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -5
- package/dist/_virtual/_rolldown/runtime.js +27 -0
- package/dist/actions/bridge.js +1 -0
- package/dist/context.js +0 -0
- package/dist/contracts/actions.js +1 -0
- package/dist/contracts/boundaries.js +1 -0
- package/dist/contracts/capabilities.js +1 -0
- package/dist/contracts/code.js +1 -0
- package/dist/contracts/errors.js +8 -0
- package/dist/contracts/evidence.js +8 -0
- package/dist/contracts/identity.js +8 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/inspection.js +1 -0
- package/dist/contracts/policy.js +8 -0
- package/dist/contracts/sessions.js +1 -0
- package/dist/contracts/status.js +1 -0
- package/dist/discovery.js +8 -0
- package/dist/docs.js +63 -0
- package/dist/inspection/service.js +3 -0
- package/dist/inspection/tools.js +43 -0
- package/dist/runtime/logs.js +1 -0
- package/dist/runtime/process.js +1 -0
- package/dist/runtime/service.js +1 -0
- package/dist/runtime/targets.js +1 -0
- package/dist/runtime/tools.js +119 -0
- package/dist/server.js +324 -0
- package/dist/status.js +8 -0
- package/dist/xplat-mcp.js +68 -0
- package/package.json +18 -12
- package/src/context.ts +108 -0
- package/src/{docs.mjs → docs.ts} +31 -26
- package/src/inspection/{service.mjs → service.ts} +1 -1
- package/src/inspection/{tools.mjs → tools.ts} +13 -5
- package/src/runtime/{tools.mjs → tools.ts} +16 -6
- package/src/{server.mjs → server.ts} +48 -33
- package/src/{xplat-mcp.mjs → xplat-mcp.ts} +21 -10
- /package/src/actions/{bridge.mjs → bridge.ts} +0 -0
- /package/src/contracts/{actions.mjs → actions.ts} +0 -0
- /package/src/contracts/{boundaries.mjs → boundaries.ts} +0 -0
- /package/src/contracts/{capabilities.mjs → capabilities.ts} +0 -0
- /package/src/contracts/{code.mjs → code.ts} +0 -0
- /package/src/contracts/{errors.mjs → errors.ts} +0 -0
- /package/src/contracts/{evidence.mjs → evidence.ts} +0 -0
- /package/src/contracts/{identity.mjs → identity.ts} +0 -0
- /package/src/contracts/{index.mjs → index.ts} +0 -0
- /package/src/contracts/{inspection.mjs → inspection.ts} +0 -0
- /package/src/contracts/{policy.mjs → policy.ts} +0 -0
- /package/src/contracts/{sessions.mjs → sessions.ts} +0 -0
- /package/src/contracts/{status.mjs → status.ts} +0 -0
- /package/src/{discovery.mjs → discovery.ts} +0 -0
- /package/src/runtime/{logs.mjs → logs.ts} +0 -0
- /package/src/runtime/{process.mjs → process.ts} +0 -0
- /package/src/runtime/{service.mjs → service.ts} +0 -0
- /package/src/runtime/{targets.mjs → targets.ts} +0 -0
- /package/src/{status.mjs → status.ts} +0 -0
- /package/{src → types}/contracts/actions.d.ts +0 -0
- /package/{src → types}/contracts/boundaries.d.ts +0 -0
- /package/{src → types}/contracts/capabilities.d.ts +0 -0
- /package/{src → types}/contracts/code.d.ts +0 -0
- /package/{src → types}/contracts/errors.d.ts +0 -0
- /package/{src → types}/contracts/evidence.d.ts +0 -0
- /package/{src → types}/contracts/identity.d.ts +0 -0
- /package/{src → types}/contracts/index.d.ts +0 -0
- /package/{src → types}/contracts/inspection.d.ts +0 -0
- /package/{src → types}/contracts/policy.d.ts +0 -0
- /package/{src → types}/contracts/sessions.d.ts +0 -0
- /package/{src → types}/contracts/status.d.ts +0 -0
package/README.md
CHANGED
|
@@ -38,7 +38,9 @@ A one-off run without a devDependency also works:
|
|
|
38
38
|
pnpm dlx @octane-xplat/mcp --workspace /path/to/app-workspace
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
For development inside this repository
|
|
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/`:
|
|
42
44
|
|
|
43
45
|
```sh
|
|
44
46
|
pnpm --filter @octane-xplat/mcp start -- --workspace <path>
|
|
@@ -122,12 +124,14 @@ The service layer lives in `packages/cli/src/mcp/` — the `xplat` CLI projects
|
|
|
122
124
|
the same contracts through its agent commands (`xplat catalog --json` is the
|
|
123
125
|
entry point). `packages/mcp/src/` holds the stdio transport adapter: tool
|
|
124
126
|
registration wraps the shared services, and the published `.d.ts` contract
|
|
125
|
-
surface stays here
|
|
127
|
+
surface stays here under `types/contracts/`. Sources are TypeScript; `pnpm
|
|
128
|
+
build` emits the runnable ESM to `dist/` (`pnpm test` builds first).
|
|
126
129
|
|
|
127
130
|
## Contract surface (`@octane-xplat/mcp/contracts/*`)
|
|
128
131
|
|
|
129
|
-
Later work packages integrate against these modules; the `.d.ts` files
|
|
130
|
-
|
|
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`).
|
|
131
135
|
|
|
132
136
|
- `errors` — `ContractErrorCode` vocabulary (`invalid_selection`,
|
|
133
137
|
`ambiguous_selection`, `permission_denied`, `unsupported_capability`,
|
|
@@ -178,7 +182,7 @@ on all six platforms. Adapters (`runtime/adapters/*`) own platform
|
|
|
178
182
|
mechanics and always spawn the app's own toolchain — `pnpm exec vite`,
|
|
179
183
|
`pnpm exec ns run …`, the app's installed `@octane-xplat/cli` dev entry, or
|
|
180
184
|
its `dev` script — so a session behaves like the app's installed framework
|
|
181
|
-
version. `service
|
|
185
|
+
version. The shared `runtime/service` module owns the contract behavior: explicit
|
|
182
186
|
app+target binding, `target_busy` contention, job dedupe/cooperative
|
|
183
187
|
cancel, ownership-safe cleanup, bounded logs, and capability-matrix entries.
|
|
184
188
|
|
|
@@ -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";
|
package/dist/context.js
ADDED
|
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,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";
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { identity_exports } from "../contracts/identity.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
//#region src/runtime/tools.ts
|
|
4
|
+
function registerRuntimeTools(server, context, respond) {
|
|
5
|
+
const runtime = context.runtime;
|
|
6
|
+
server.registerTool("xplat_targets", {
|
|
7
|
+
description: "Discover launchable targets for the bound app: simulators, emulators, devices and host targets with availability, missing-toolchain reasons, and session busy/ownership state.",
|
|
8
|
+
inputSchema: { platform: z.enum(identity_exports.PLATFORMS).optional().describe("Limit to one platform") }
|
|
9
|
+
}, async ({ platform }) => {
|
|
10
|
+
const result = await runtime.listTargets({ platform });
|
|
11
|
+
return result.error ? respond({
|
|
12
|
+
ok: false,
|
|
13
|
+
error: result.error
|
|
14
|
+
}) : respond({
|
|
15
|
+
ok: true,
|
|
16
|
+
data: result
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
server.registerTool("xplat_build", {
|
|
20
|
+
description: "Build the bound app for one platform as a background job (the same commands `xplat build` runs). Returns a job id — poll xplat_job_status and read output with xplat_logs. Repeating with the same requestKey returns the live job instead of duplicating it.",
|
|
21
|
+
inputSchema: {
|
|
22
|
+
platform: z.enum(identity_exports.PLATFORMS),
|
|
23
|
+
requestKey: z.string().optional().describe("Idempotence key for retries")
|
|
24
|
+
}
|
|
25
|
+
}, async ({ platform, requestKey }) => {
|
|
26
|
+
const result = await runtime.build({
|
|
27
|
+
platform,
|
|
28
|
+
requestKey
|
|
29
|
+
});
|
|
30
|
+
return result.error ? respond({
|
|
31
|
+
ok: false,
|
|
32
|
+
error: result.error
|
|
33
|
+
}) : respond({
|
|
34
|
+
ok: true,
|
|
35
|
+
data: result
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
server.registerTool("xplat_launch", {
|
|
39
|
+
description: "Start an owned development session: bind one app to one target and run the platform dev command as a job. The job completes when readiness is confirmed — a failed launch after a successful build reports accurately, and the session keeps the app alive until xplat_session_end.",
|
|
40
|
+
inputSchema: {
|
|
41
|
+
platform: z.enum(identity_exports.PLATFORMS),
|
|
42
|
+
targetId: z.string().optional().describe("Target from xplat_targets; required when several are available"),
|
|
43
|
+
requestKey: z.string().optional().describe("Idempotence key for retries"),
|
|
44
|
+
browserMode: z.enum(["headless", "headed"]).optional().describe("Web only. Headed mode enables scoped OS keyboard input on qualified hosts; reserve desktop input before using it.")
|
|
45
|
+
}
|
|
46
|
+
}, async ({ platform, targetId, requestKey, browserMode }) => {
|
|
47
|
+
const result = await runtime.launch({
|
|
48
|
+
platform,
|
|
49
|
+
targetId,
|
|
50
|
+
requestKey,
|
|
51
|
+
browserMode
|
|
52
|
+
});
|
|
53
|
+
return result.error ? respond({
|
|
54
|
+
ok: false,
|
|
55
|
+
error: result.error
|
|
56
|
+
}) : respond({
|
|
57
|
+
ok: true,
|
|
58
|
+
data: result
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
server.registerTool("xplat_attach", {
|
|
62
|
+
description: "Attach to a compatible development session that is already running — never restarts or terminates it. Reports candidates per platform; attach binds a preserved user-owned session.",
|
|
63
|
+
inputSchema: {
|
|
64
|
+
platform: z.enum(identity_exports.PLATFORMS),
|
|
65
|
+
targetId: z.string().optional().describe("Candidate target; required when several are attachable")
|
|
66
|
+
}
|
|
67
|
+
}, async ({ platform, targetId }) => {
|
|
68
|
+
const result = await runtime.attach({
|
|
69
|
+
platform,
|
|
70
|
+
targetId
|
|
71
|
+
});
|
|
72
|
+
return result.error ? respond({
|
|
73
|
+
ok: false,
|
|
74
|
+
error: result.error
|
|
75
|
+
}) : respond({
|
|
76
|
+
ok: true,
|
|
77
|
+
data: result
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
server.registerTool("xplat_logs", {
|
|
81
|
+
description: "Bounded, ordered log read for a session or build job. Cursor-paginated: pass the previous nextCursor to continue; truncated/dropped flags reveal gaps and reset marks a restarted capture. A stopped or disconnected session reports its capture as historical.",
|
|
82
|
+
inputSchema: {
|
|
83
|
+
sessionId: z.string().optional(),
|
|
84
|
+
jobId: z.string().optional(),
|
|
85
|
+
cursor: z.number().optional().describe("Continue after this record seq"),
|
|
86
|
+
limit: z.number().int().positive().max(5e3).optional(),
|
|
87
|
+
stream: z.enum([
|
|
88
|
+
"stdout",
|
|
89
|
+
"stderr",
|
|
90
|
+
"lifecycle"
|
|
91
|
+
]).optional()
|
|
92
|
+
}
|
|
93
|
+
}, async ({ sessionId, jobId, cursor, limit, stream }) => {
|
|
94
|
+
if (!sessionId && !jobId) return respond({
|
|
95
|
+
ok: false,
|
|
96
|
+
error: {
|
|
97
|
+
code: "invalid_selection",
|
|
98
|
+
message: "Pass a sessionId or a jobId.",
|
|
99
|
+
recovery: { action: "Use xplat_sessions or a build/launch job id." }
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
const result = runtime.readLogs({
|
|
103
|
+
sessionId,
|
|
104
|
+
jobId,
|
|
105
|
+
cursor,
|
|
106
|
+
limit,
|
|
107
|
+
stream
|
|
108
|
+
});
|
|
109
|
+
return result.error ? respond({
|
|
110
|
+
ok: false,
|
|
111
|
+
error: result.error
|
|
112
|
+
}) : respond({
|
|
113
|
+
ok: true,
|
|
114
|
+
data: result
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { registerRuntimeTools };
|