@unbound-app/debugger-protocol 0.9.0 → 0.11.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.
package/dist/controller.d.mts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { l as EvalResult, o as DeviceInfo, p as PluginPushResult } from "./index-
|
|
2
|
-
import {
|
|
1
|
+
import { l as EvalResult, m as PushedAddonKind, o as DeviceInfo, p as PluginPushResult } from "./index-DdSiZNoR.mjs";
|
|
2
|
+
import { PushedManifest } from "@unbound-app/types";
|
|
3
3
|
type PluginPush = {
|
|
4
4
|
addonId: string;
|
|
5
|
+
kind?: PushedAddonKind;
|
|
5
6
|
bundle: string;
|
|
6
|
-
manifest:
|
|
7
|
+
manifest: PushedManifest;
|
|
7
8
|
bytecode?: Record<string, string>;
|
|
9
|
+
files?: Record<string, string>;
|
|
8
10
|
};
|
|
9
11
|
export declare class ControllerClient {
|
|
10
12
|
private ws;
|
|
@@ -32,7 +34,7 @@ export declare class ControllerClient {
|
|
|
32
34
|
*/
|
|
33
35
|
evaluate(code: string, timeout?: number): Promise<EvalResult>;
|
|
34
36
|
/**
|
|
35
|
-
* @description Pushes a freshly built plugin to the device via the bridge and resolves with the
|
|
37
|
+
* @description Pushes a freshly built plugin or theme to the device via the bridge and resolves with the
|
|
36
38
|
* device's reload outcome. Fails fast if the socket isn't open or the bridge doesn't answer in time.
|
|
37
39
|
* @param push The addon id plus the built bundle and manifest to swap in.
|
|
38
40
|
* @returns The device's {@link PluginPushResult}.
|
package/dist/controller.mjs
CHANGED
|
@@ -106,7 +106,7 @@ var ControllerClient = class {
|
|
|
106
106
|
});
|
|
107
107
|
}
|
|
108
108
|
/**
|
|
109
|
-
* @description Pushes a freshly built plugin to the device via the bridge and resolves with the
|
|
109
|
+
* @description Pushes a freshly built plugin or theme to the device via the bridge and resolves with the
|
|
110
110
|
* device's reload outcome. Fails fast if the socket isn't open or the bridge doesn't answer in time.
|
|
111
111
|
* @param push The addon id plus the built bundle and manifest to swap in.
|
|
112
112
|
* @returns The device's {@link PluginPushResult}.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PushedManifest } from "@unbound-app/types";
|
|
2
2
|
/**
|
|
3
3
|
* The wire protocol shared by the bridge, the device and controllers: every frame is a JSON-encoded
|
|
4
4
|
* {@link BridgeMessage}. Dependency-free at runtime so the React Native client can bundle it.
|
|
@@ -16,40 +16,53 @@ type EvalResult = {
|
|
|
16
16
|
type: 'eval-result';
|
|
17
17
|
/** The `id` of the {@link EvalRequest} this answers. */
|
|
18
18
|
id: string;
|
|
19
|
-
ok: boolean;
|
|
20
|
-
/** Present when `ok`; the inspected return value. */
|
|
21
|
-
value?: string;
|
|
22
|
-
/** Present when `!ok`; the inspected error. */
|
|
23
|
-
error?: string;
|
|
24
19
|
/**
|
|
25
20
|
* Console output captured during this eval, so callers see its side effects too. Populated by
|
|
26
21
|
* the controller that owns the request, not sent by the device.
|
|
27
22
|
*/
|
|
28
23
|
logs?: LogMessage[];
|
|
29
|
-
}
|
|
24
|
+
} & ({
|
|
25
|
+
ok: true;
|
|
26
|
+
/** The inspected return value. */
|
|
27
|
+
value: string;
|
|
28
|
+
} | {
|
|
29
|
+
ok: false;
|
|
30
|
+
/** The inspected error. */
|
|
31
|
+
error: string;
|
|
32
|
+
});
|
|
33
|
+
/** The addon managers a push can reload into. */
|
|
34
|
+
type PushedAddonKind = 'plugin' | 'theme';
|
|
30
35
|
/**
|
|
31
|
-
* A request to hot-reload a plugin on the device, sent controller → bridge → device. Carries
|
|
32
|
-
* freshly built bundle and manifest so the device swaps them in without a re-fetch.
|
|
36
|
+
* A request to hot-reload a plugin or theme on the device, sent controller → bridge → device. Carries
|
|
37
|
+
* the freshly built bundle and manifest so the device swaps them in without a re-fetch.
|
|
33
38
|
*/
|
|
34
39
|
type PluginPushRequest = {
|
|
35
40
|
type: 'plugin-push';
|
|
36
41
|
/** Correlation id echoed back on the matching {@link PluginPushResult}. */
|
|
37
42
|
id: string;
|
|
38
43
|
addonId: string;
|
|
44
|
+
/** Which manager reloads the addon; a plugin when omitted, as pushes from older CLIs are. */
|
|
45
|
+
kind?: PushedAddonKind;
|
|
39
46
|
bundle: string;
|
|
40
|
-
manifest
|
|
47
|
+
/** The manifest as authored; the device validates it before swapping anything in. */
|
|
48
|
+
manifest: PushedManifest;
|
|
41
49
|
/** The bundle compiled to Hermes bytecode, base64-encoded, by bytecode version; its digests are in `manifest.bytecode`. */
|
|
42
50
|
bytecode?: Record<string, string>;
|
|
51
|
+
/** Each extra file the manifest lists beside the bundle, such as an image, base64-encoded, by path. */
|
|
52
|
+
files?: Record<string, string>;
|
|
43
53
|
};
|
|
44
54
|
/** The outcome of a {@link PluginPushRequest}, sent device → bridge → the one waiting controller. */
|
|
45
55
|
type PluginPushResult = {
|
|
46
56
|
type: 'plugin-push-result';
|
|
47
57
|
/** The `id` of the {@link PluginPushRequest} this answers. */
|
|
48
58
|
id: string;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
} & ({
|
|
60
|
+
ok: true;
|
|
61
|
+
} | {
|
|
62
|
+
ok: false;
|
|
63
|
+
/** The reload failure, inspected. */
|
|
64
|
+
error: string;
|
|
65
|
+
});
|
|
53
66
|
/** A `console.*` / `nativeLoggingHook` line, streamed device → bridge → all controllers. */
|
|
54
67
|
type LogMessage = {
|
|
55
68
|
type: 'log';
|
|
@@ -72,10 +85,13 @@ type DeviceHello = {
|
|
|
72
85
|
/** Bridge → controller, once on attach and whenever the device connects, drops or says hello. */
|
|
73
86
|
type DeviceStatus = {
|
|
74
87
|
type: 'device-status';
|
|
75
|
-
|
|
88
|
+
} & ({
|
|
89
|
+
connected: false;
|
|
90
|
+
} | {
|
|
91
|
+
connected: true;
|
|
76
92
|
/** Present once the connected device has said hello. */
|
|
77
93
|
device?: DeviceInfo;
|
|
78
|
-
};
|
|
94
|
+
});
|
|
79
95
|
/** Every framed message on the wire. */
|
|
80
96
|
type BridgeMessage = EvalRequest | EvalResult | PluginPushRequest | PluginPushResult | LogMessage | DeviceHello | DeviceStatus;
|
|
81
97
|
/** The default port the bridge listens on and controllers dial. */
|
|
@@ -105,4 +121,4 @@ declare const _default: {
|
|
|
105
121
|
parseMessage: typeof parseMessage;
|
|
106
122
|
serializeMessage: typeof serializeMessage;
|
|
107
123
|
};
|
|
108
|
-
export { DeviceHello as a, EvalRequest as c, MAX_EVAL_TIMEOUT_MS as d, PluginPushRequest as f,
|
|
124
|
+
export { serializeMessage as _, DeviceHello as a, EvalRequest as c, MAX_EVAL_TIMEOUT_MS as d, PluginPushRequest as f, parseMessage as g, _default as h, DEFAULT_EVAL_TIMEOUT_MS as i, EvalResult as l, PushedAddonKind as m, CONTROLLER_ENDPOINT_MARKER as n, DeviceInfo as o, PluginPushResult as p, DEFAULT_BRIDGE_PORT as r, DeviceStatus as s, BridgeMessage as t, LogMessage as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as DeviceHello, c as EvalRequest, d as MAX_EVAL_TIMEOUT_MS, f as PluginPushRequest, g as
|
|
2
|
-
export { BridgeMessage, CONTROLLER_ENDPOINT_MARKER, DEFAULT_BRIDGE_PORT, DEFAULT_EVAL_TIMEOUT_MS, DeviceHello, DeviceInfo, DeviceStatus, EvalRequest, EvalResult, LogMessage, MAX_EVAL_TIMEOUT_MS, PluginPushRequest, PluginPushResult, _default as default, parseMessage, serializeMessage };
|
|
1
|
+
import { _ as serializeMessage, a as DeviceHello, c as EvalRequest, d as MAX_EVAL_TIMEOUT_MS, f as PluginPushRequest, g as parseMessage, h as _default, i as DEFAULT_EVAL_TIMEOUT_MS, l as EvalResult, m as PushedAddonKind, n as CONTROLLER_ENDPOINT_MARKER, o as DeviceInfo, p as PluginPushResult, r as DEFAULT_BRIDGE_PORT, s as DeviceStatus, t as BridgeMessage, u as LogMessage } from "./index-DdSiZNoR.mjs";
|
|
2
|
+
export { BridgeMessage, CONTROLLER_ENDPOINT_MARKER, DEFAULT_BRIDGE_PORT, DEFAULT_EVAL_TIMEOUT_MS, DeviceHello, DeviceInfo, DeviceStatus, EvalRequest, EvalResult, LogMessage, MAX_EVAL_TIMEOUT_MS, PluginPushRequest, PluginPushResult, PushedAddonKind, _default as default, parseMessage, serializeMessage };
|
package/dist/index.mjs
CHANGED
|
@@ -34,14 +34,17 @@ function hasRequiredFields(frame) {
|
|
|
34
34
|
switch (frame.type) {
|
|
35
35
|
case "log": return "message" in frame && typeof frame.message === "string" && "level" in frame && (frame.level === 1 || frame.level === 2 || frame.level === 3);
|
|
36
36
|
case "eval": return "id" in frame && typeof frame.id === "string" && "code" in frame && typeof frame.code === "string";
|
|
37
|
-
case "eval-result":
|
|
38
|
-
case "plugin-push-result": return "id" in frame && typeof frame.id === "string" && "ok" in frame &&
|
|
39
|
-
case "plugin-push": return "id" in frame && typeof frame.id === "string" && "addonId" in frame && typeof frame.addonId === "string" && "bundle" in frame && typeof frame.bundle === "string" && "manifest" in frame && typeof frame.manifest === "object" && frame.manifest !== null && (!("bytecode" in frame) || frame.bytecode === void 0 || isStringRecord(frame.bytecode));
|
|
37
|
+
case "eval-result": return "id" in frame && typeof frame.id === "string" && "ok" in frame && (frame.ok === true ? "value" in frame && typeof frame.value === "string" : frame.ok === false && hasError(frame));
|
|
38
|
+
case "plugin-push-result": return "id" in frame && typeof frame.id === "string" && "ok" in frame && (frame.ok === true || frame.ok === false && hasError(frame));
|
|
39
|
+
case "plugin-push": return "id" in frame && typeof frame.id === "string" && "addonId" in frame && typeof frame.addonId === "string" && (!("kind" in frame) || frame.kind === void 0 || frame.kind === "plugin" || frame.kind === "theme") && "bundle" in frame && typeof frame.bundle === "string" && "manifest" in frame && typeof frame.manifest === "object" && frame.manifest !== null && (!("bytecode" in frame) || frame.bytecode === void 0 || isStringRecord(frame.bytecode)) && (!("files" in frame) || frame.files === void 0 || isStringRecord(frame.files));
|
|
40
40
|
case "hello": return "device" in frame && isDeviceInfo(frame.device);
|
|
41
|
-
case "device-status": return "connected" in frame &&
|
|
41
|
+
case "device-status": return "connected" in frame && (frame.connected === false || frame.connected === true && (!("device" in frame) || frame.device === void 0 || isDeviceInfo(frame.device)));
|
|
42
42
|
default: return false;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
function hasError(frame) {
|
|
46
|
+
return typeof frame === "object" && frame !== null && "error" in frame && typeof frame.error === "string";
|
|
47
|
+
}
|
|
45
48
|
function isDeviceInfo(value) {
|
|
46
49
|
return typeof value === "object" && value !== null && "platform" in value && typeof value.platform === "string" && "discordVersion" in value && typeof value.discordVersion === "string" && "loaderVersion" in value && typeof value.loaderVersion === "string" && "clientVersion" in value && typeof value.clientVersion === "string";
|
|
47
50
|
}
|
package/dist/registry.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ControllerClient } from "./controller.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { StaticDecode, TObject } from "typebox";
|
|
3
3
|
/**
|
|
4
4
|
* One command definition feeds both surfaces: the CLI builds flags and positionals from its schema,
|
|
5
5
|
* and the MCP server uses the schema as the tool's input schema.
|
|
@@ -26,15 +26,17 @@ export type CommandSurfaces = {
|
|
|
26
26
|
mcp: true;
|
|
27
27
|
};
|
|
28
28
|
/** A command usable from both the CLI and (when opted in) the MCP server. */
|
|
29
|
-
export type CommandDefinition<S extends
|
|
29
|
+
export type CommandDefinition<S extends TObject = TObject> = {
|
|
30
30
|
name: string;
|
|
31
31
|
description: string;
|
|
32
|
+
/** A one-line summary for the CLI's menu, where the description is too long. */
|
|
33
|
+
summary?: string;
|
|
32
34
|
surfaces: CommandSurfaces;
|
|
33
|
-
/** Used directly as the MCP
|
|
35
|
+
/** Used directly as the MCP tool's input schema; the CLI adapter derives flags from its properties. */
|
|
34
36
|
schema: S;
|
|
35
|
-
/** Which schema
|
|
37
|
+
/** Which schema properties the CLI presents as positionals; the rest become flags. */
|
|
36
38
|
cli?: {
|
|
37
|
-
positionals?: (keyof
|
|
39
|
+
positionals?: (keyof StaticDecode<S>)[];
|
|
38
40
|
};
|
|
39
|
-
handler
|
|
41
|
+
handler(input: StaticDecode<S>, context: CommandContext): Promise<CommandOutput>;
|
|
40
42
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unbound-app/debugger-protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "The wire protocol and controller client shared by the debugger bridge, the on-device client, and the CLI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mario P.",
|
|
@@ -32,12 +32,13 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
|
-
"build": "tsdown"
|
|
35
|
+
"build": "tsdown",
|
|
36
|
+
"typecheck": "tsc --noEmit -p ."
|
|
36
37
|
},
|
|
37
38
|
"dependencies": {
|
|
38
|
-
"
|
|
39
|
+
"typebox": "^1.4.4"
|
|
39
40
|
},
|
|
40
41
|
"peerDependencies": {
|
|
41
|
-
"typescript": "^
|
|
42
|
+
"typescript": "^7.0.2"
|
|
42
43
|
}
|
|
43
44
|
}
|