portholejs 0.1.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/client-dist/assets/index-C_qSS_Gy.js +49 -0
- package/client-dist/index.html +12 -0
- package/dist/adb-actions.d.ts +4 -0
- package/dist/adb-actions.d.ts.map +1 -0
- package/dist/adb-actions.js +40 -0
- package/dist/adb-actions.js.map +1 -0
- package/dist/cli-errors.d.ts +5 -0
- package/dist/cli-errors.d.ts.map +1 -0
- package/dist/cli-errors.js +19 -0
- package/dist/cli-errors.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +542 -0
- package/dist/cli.js.map +1 -0
- package/dist/control-client.d.ts +22 -0
- package/dist/control-client.d.ts.map +1 -0
- package/dist/control-client.js +100 -0
- package/dist/control-client.js.map +1 -0
- package/dist/crashes.d.ts +8 -0
- package/dist/crashes.d.ts.map +1 -0
- package/dist/crashes.js +38 -0
- package/dist/crashes.js.map +1 -0
- package/dist/device-manager.d.ts +29 -0
- package/dist/device-manager.d.ts.map +1 -0
- package/dist/device-manager.js +213 -0
- package/dist/device-manager.js.map +1 -0
- package/dist/doctor.d.ts +8 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +115 -0
- package/dist/doctor.js.map +1 -0
- package/dist/engine/scrcpy-engine.d.ts +38 -0
- package/dist/engine/scrcpy-engine.d.ts.map +1 -0
- package/dist/engine/scrcpy-engine.js +216 -0
- package/dist/engine/scrcpy-engine.js.map +1 -0
- package/dist/engine/types.d.ts +26 -0
- package/dist/engine/types.d.ts.map +1 -0
- package/dist/engine/types.js +2 -0
- package/dist/engine/types.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/input-validation.d.ts +5 -0
- package/dist/input-validation.d.ts.map +1 -0
- package/dist/input-validation.js +62 -0
- package/dist/input-validation.js.map +1 -0
- package/dist/input.d.ts +22 -0
- package/dist/input.d.ts.map +1 -0
- package/dist/input.js +2 -0
- package/dist/input.js.map +1 -0
- package/dist/keycodes.d.ts +19 -0
- package/dist/keycodes.d.ts.map +1 -0
- package/dist/keycodes.js +32 -0
- package/dist/keycodes.js.map +1 -0
- package/dist/log.d.ts +3 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +10 -0
- package/dist/log.js.map +1 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +401 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/middleware.d.ts +13 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +31 -0
- package/dist/middleware.js.map +1 -0
- package/dist/paths.d.ts +5 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +27 -0
- package/dist/paths.js.map +1 -0
- package/dist/port-check.d.ts +5 -0
- package/dist/port-check.d.ts.map +1 -0
- package/dist/port-check.js +27 -0
- package/dist/port-check.js.map +1 -0
- package/dist/profiles.d.ts +4 -0
- package/dist/profiles.d.ts.map +1 -0
- package/dist/profiles.js +25 -0
- package/dist/profiles.js.map +1 -0
- package/dist/protocol.d.ts +10 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +27 -0
- package/dist/protocol.js.map +1 -0
- package/dist/server/frame-convert.d.ts +6 -0
- package/dist/server/frame-convert.d.ts.map +1 -0
- package/dist/server/frame-convert.js +33 -0
- package/dist/server/frame-convert.js.map +1 -0
- package/dist/server/http.d.ts +20 -0
- package/dist/server/http.d.ts.map +1 -0
- package/dist/server/http.js +509 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/mjpeg.d.ts +21 -0
- package/dist/server/mjpeg.d.ts.map +1 -0
- package/dist/server/mjpeg.js +92 -0
- package/dist/server/mjpeg.js.map +1 -0
- package/dist/server/ws.d.ts +15 -0
- package/dist/server/ws.d.ts.map +1 -0
- package/dist/server/ws.js +102 -0
- package/dist/server/ws.js.map +1 -0
- package/dist/session.d.ts +45 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +188 -0
- package/dist/session.js.map +1 -0
- package/dist/state.d.ts +27 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +70 -0
- package/dist/state.js.map +1 -0
- package/dist/target-resolution.d.ts +14 -0
- package/dist/target-resolution.d.ts.map +1 -0
- package/dist/target-resolution.js +37 -0
- package/dist/target-resolution.js.map +1 -0
- package/dist/ui-tree.d.ts +47 -0
- package/dist/ui-tree.d.ts.map +1 -0
- package/dist/ui-tree.js +179 -0
- package/dist/ui-tree.js.map +1 -0
- package/package.json +63 -0
- package/scripts/download-scrcpy-server.mjs +67 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { InputEvent } from "../input.js";
|
|
2
|
+
import type { Engine, EngineMetadata, VideoChunk } from "./types.js";
|
|
3
|
+
export interface ScrcpyEngineOptions {
|
|
4
|
+
serial: string;
|
|
5
|
+
maxSize?: number;
|
|
6
|
+
maxFps?: number;
|
|
7
|
+
bitrate?: number;
|
|
8
|
+
serverPath?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class ScrcpyEngine implements Engine {
|
|
11
|
+
private readonly serial;
|
|
12
|
+
private readonly maxSize;
|
|
13
|
+
private readonly maxFps;
|
|
14
|
+
private readonly bitrate?;
|
|
15
|
+
private readonly serverPath;
|
|
16
|
+
private videoCallbacks;
|
|
17
|
+
private closeCallbacks;
|
|
18
|
+
private client;
|
|
19
|
+
private controller;
|
|
20
|
+
private adb;
|
|
21
|
+
private _metadata;
|
|
22
|
+
private lastFrame;
|
|
23
|
+
get metadata(): EngineMetadata | null;
|
|
24
|
+
constructor(opts: ScrcpyEngineOptions);
|
|
25
|
+
start(): Promise<void>;
|
|
26
|
+
private consumeVideoStream;
|
|
27
|
+
onVideoChunk(cb: (chunk: VideoChunk) => void): void;
|
|
28
|
+
onClose(cb: (error?: Error) => void): void;
|
|
29
|
+
sendInput(event: InputEvent): Promise<void>;
|
|
30
|
+
screenshot(): Promise<Uint8Array>;
|
|
31
|
+
captureFrame(): Promise<{
|
|
32
|
+
data: Uint8Array;
|
|
33
|
+
mime: string;
|
|
34
|
+
}>;
|
|
35
|
+
stop(): Promise<void>;
|
|
36
|
+
private emitClose;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=scrcpy-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrcpy-engine.d.ts","sourceRoot":"","sources":["../../src/engine/scrcpy-engine.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIrE,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,YAAa,YAAW,MAAM;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,cAAc,CAA0C;IAChE,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,MAAM,CAA2D;IACzE,OAAO,CAAC,UAAU,CAA2C;IAC7D,OAAO,CAAC,GAAG,CAAoB;IAC/B,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,SAAS,CAA2B;IAE5C,IAAI,QAAQ,IAAI,cAAc,GAAG,IAAI,CAEpC;gBAEW,IAAI,EAAE,mBAAmB;IAS/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA0D5B,OAAO,CAAC,kBAAkB;IAiC1B,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI;IAInD,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAIpC,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA0D3C,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;IASjC,YAAY,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAI3D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,OAAO,CAAC,SAAS;CAKlB"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { AdbServerClient } from "@yume-chan/adb";
|
|
6
|
+
import { AdbScrcpyClient, AdbScrcpyOptions3_1 } from "@yume-chan/adb-scrcpy";
|
|
7
|
+
import { AdbServerNodeTcpConnector } from "@yume-chan/adb-server-node-tcp";
|
|
8
|
+
import { AndroidKeyEventAction, AndroidMotionEventAction } from "@yume-chan/scrcpy";
|
|
9
|
+
import { ReadableStream } from "@yume-chan/stream-extra";
|
|
10
|
+
import { REMOTE_BUTTON_TO_KEYCODE } from "../keycodes.js";
|
|
11
|
+
import { debugLog } from "../log.js";
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
export class ScrcpyEngine {
|
|
14
|
+
serial;
|
|
15
|
+
maxSize;
|
|
16
|
+
maxFps;
|
|
17
|
+
bitrate;
|
|
18
|
+
serverPath;
|
|
19
|
+
videoCallbacks = [];
|
|
20
|
+
closeCallbacks = [];
|
|
21
|
+
client = null;
|
|
22
|
+
controller = null;
|
|
23
|
+
adb = null;
|
|
24
|
+
_metadata = null;
|
|
25
|
+
lastFrame = null;
|
|
26
|
+
get metadata() {
|
|
27
|
+
return this._metadata;
|
|
28
|
+
}
|
|
29
|
+
constructor(opts) {
|
|
30
|
+
this.serial = opts.serial;
|
|
31
|
+
this.maxSize = opts.maxSize ?? 1280;
|
|
32
|
+
this.maxFps = opts.maxFps ?? 30;
|
|
33
|
+
this.bitrate = opts.bitrate;
|
|
34
|
+
this.serverPath =
|
|
35
|
+
opts.serverPath ?? join(import.meta.dirname, "../../assets/scrcpy-server");
|
|
36
|
+
}
|
|
37
|
+
async start() {
|
|
38
|
+
debugLog("engine", `starting scrcpy for ${this.serial}`);
|
|
39
|
+
const connector = new AdbServerNodeTcpConnector({ port: 5037 });
|
|
40
|
+
const serverClient = new AdbServerClient(connector);
|
|
41
|
+
this.adb = await serverClient.createAdb({ serial: this.serial });
|
|
42
|
+
const serverBuf = await readFile(this.serverPath);
|
|
43
|
+
const serverStream = new ReadableStream({
|
|
44
|
+
start(controller) {
|
|
45
|
+
controller.enqueue(new Uint8Array(serverBuf));
|
|
46
|
+
controller.close();
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
await AdbScrcpyClient.pushServer(this.adb, serverStream);
|
|
50
|
+
const options = new AdbScrcpyOptions3_1({
|
|
51
|
+
video: true,
|
|
52
|
+
audio: false,
|
|
53
|
+
control: true,
|
|
54
|
+
maxSize: this.maxSize,
|
|
55
|
+
maxFps: this.maxFps,
|
|
56
|
+
videoBitRate: this.bitrate,
|
|
57
|
+
videoCodec: "h264",
|
|
58
|
+
tunnelForward: false,
|
|
59
|
+
sendFrameMeta: true,
|
|
60
|
+
sendCodecMeta: true,
|
|
61
|
+
sendDeviceMeta: true,
|
|
62
|
+
sendDummyByte: true,
|
|
63
|
+
});
|
|
64
|
+
this.client = await AdbScrcpyClient.start(this.adb, "/data/local/tmp/scrcpy-server.jar", options);
|
|
65
|
+
this.controller = this.client.controller ?? null;
|
|
66
|
+
const videoStream = await this.client.videoStream;
|
|
67
|
+
if (!videoStream) {
|
|
68
|
+
throw new Error("Video stream not available");
|
|
69
|
+
}
|
|
70
|
+
this._metadata = {
|
|
71
|
+
codec: "h264",
|
|
72
|
+
width: videoStream.width,
|
|
73
|
+
height: videoStream.height,
|
|
74
|
+
};
|
|
75
|
+
videoStream.sizeChanged(({ width, height }) => {
|
|
76
|
+
if (this._metadata) {
|
|
77
|
+
this._metadata = { ...this._metadata, width, height };
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
this.consumeVideoStream(videoStream.stream);
|
|
81
|
+
}
|
|
82
|
+
consumeVideoStream(stream) {
|
|
83
|
+
const reader = stream.getReader();
|
|
84
|
+
const read = async () => {
|
|
85
|
+
try {
|
|
86
|
+
while (true) {
|
|
87
|
+
const { done, value } = await reader.read();
|
|
88
|
+
if (done)
|
|
89
|
+
break;
|
|
90
|
+
const chunk = {
|
|
91
|
+
type: value.type === "configuration" ? "config" : "frame",
|
|
92
|
+
data: value.data,
|
|
93
|
+
timestamp: value.type === "data" && value.pts != null ? Number(value.pts) : undefined,
|
|
94
|
+
keyframe: value.type === "data" ? hasIdrNal(value.data) : undefined,
|
|
95
|
+
};
|
|
96
|
+
if (chunk.type === "frame") {
|
|
97
|
+
this.lastFrame = chunk.data;
|
|
98
|
+
}
|
|
99
|
+
for (const cb of this.videoCallbacks) {
|
|
100
|
+
cb(chunk);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
this.emitClose(new Error("scrcpy video stream closed"));
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
this.emitClose();
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
void read();
|
|
112
|
+
}
|
|
113
|
+
onVideoChunk(cb) {
|
|
114
|
+
this.videoCallbacks.push(cb);
|
|
115
|
+
}
|
|
116
|
+
onClose(cb) {
|
|
117
|
+
this.closeCallbacks.push(cb);
|
|
118
|
+
}
|
|
119
|
+
async sendInput(event) {
|
|
120
|
+
if (!this.controller || !this._metadata)
|
|
121
|
+
return;
|
|
122
|
+
switch (event.kind) {
|
|
123
|
+
case "touch": {
|
|
124
|
+
const action = event.phase === "down"
|
|
125
|
+
? AndroidMotionEventAction.Down
|
|
126
|
+
: event.phase === "up"
|
|
127
|
+
? AndroidMotionEventAction.Up
|
|
128
|
+
: AndroidMotionEventAction.Move;
|
|
129
|
+
await this.controller.injectTouch({
|
|
130
|
+
action,
|
|
131
|
+
pointerId: -1n,
|
|
132
|
+
pointerX: Math.round(event.x * this._metadata.width),
|
|
133
|
+
pointerY: Math.round(event.y * this._metadata.height),
|
|
134
|
+
videoWidth: this._metadata.width,
|
|
135
|
+
videoHeight: this._metadata.height,
|
|
136
|
+
pressure: event.phase === "up" ? 0 : 1,
|
|
137
|
+
actionButton: 0,
|
|
138
|
+
buttons: 0,
|
|
139
|
+
});
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
case "key": {
|
|
143
|
+
const action = event.phase === "down" ? AndroidKeyEventAction.Down : AndroidKeyEventAction.Up;
|
|
144
|
+
await this.controller.injectKeyCode({
|
|
145
|
+
action,
|
|
146
|
+
keyCode: event.keycode,
|
|
147
|
+
repeat: 0,
|
|
148
|
+
metaState: 0,
|
|
149
|
+
});
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
case "text": {
|
|
153
|
+
await this.controller.injectText(event.text);
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
case "remote": {
|
|
157
|
+
const keycode = REMOTE_BUTTON_TO_KEYCODE[event.button];
|
|
158
|
+
await this.controller.injectKeyCode({
|
|
159
|
+
action: AndroidKeyEventAction.Down,
|
|
160
|
+
keyCode: keycode,
|
|
161
|
+
repeat: 0,
|
|
162
|
+
metaState: 0,
|
|
163
|
+
});
|
|
164
|
+
await this.controller.injectKeyCode({
|
|
165
|
+
action: AndroidKeyEventAction.Up,
|
|
166
|
+
keyCode: keycode,
|
|
167
|
+
repeat: 0,
|
|
168
|
+
metaState: 0,
|
|
169
|
+
});
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
async screenshot() {
|
|
175
|
+
const { stdout } = await execFileAsync("adb", ["-s", this.serial, "exec-out", "screencap", "-p"], { encoding: "buffer", maxBuffer: 20 * 1024 * 1024 });
|
|
176
|
+
return new Uint8Array(stdout);
|
|
177
|
+
}
|
|
178
|
+
async captureFrame() {
|
|
179
|
+
return { data: await this.screenshot(), mime: "image/png" };
|
|
180
|
+
}
|
|
181
|
+
async stop() {
|
|
182
|
+
debugLog("engine", `stopping scrcpy for ${this.serial}`);
|
|
183
|
+
if (this.client) {
|
|
184
|
+
await this.client.close();
|
|
185
|
+
this.client = null;
|
|
186
|
+
}
|
|
187
|
+
this.controller = null;
|
|
188
|
+
this.adb = null;
|
|
189
|
+
this._metadata = null;
|
|
190
|
+
this.lastFrame = null;
|
|
191
|
+
this.videoCallbacks = [];
|
|
192
|
+
this.closeCallbacks = [];
|
|
193
|
+
}
|
|
194
|
+
emitClose(error) {
|
|
195
|
+
const callbacks = [...this.closeCallbacks];
|
|
196
|
+
this.closeCallbacks = [];
|
|
197
|
+
for (const cb of callbacks)
|
|
198
|
+
cb(error);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function hasIdrNal(data) {
|
|
202
|
+
for (let i = 0; i < data.length - 4; i++) {
|
|
203
|
+
if (data[i] === 0 && data[i + 1] === 0) {
|
|
204
|
+
let offset = i + 2;
|
|
205
|
+
if (data[offset] === 0)
|
|
206
|
+
offset++;
|
|
207
|
+
if (data[offset] === 1) {
|
|
208
|
+
const nalByte = data[offset + 1];
|
|
209
|
+
if (nalByte !== undefined && (nalByte & 0x1f) === 5)
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=scrcpy-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scrcpy-engine.js","sourceRoot":"","sources":["../../src/engine/scrcpy-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { InputEvent } from "../input.js";
|
|
2
|
+
export interface VideoChunk {
|
|
3
|
+
type: "config" | "frame";
|
|
4
|
+
data: Uint8Array;
|
|
5
|
+
timestamp?: number;
|
|
6
|
+
keyframe?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface EngineMetadata {
|
|
9
|
+
codec: "h264";
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
}
|
|
13
|
+
export interface Engine {
|
|
14
|
+
start(): Promise<void>;
|
|
15
|
+
stop(): Promise<void>;
|
|
16
|
+
onVideoChunk(cb: (chunk: VideoChunk) => void): void;
|
|
17
|
+
onClose?(cb: (error?: Error) => void): void;
|
|
18
|
+
sendInput(event: InputEvent): Promise<void>;
|
|
19
|
+
screenshot(): Promise<Uint8Array>;
|
|
20
|
+
captureFrame?(): Promise<{
|
|
21
|
+
data: Uint8Array;
|
|
22
|
+
mime: string;
|
|
23
|
+
}>;
|
|
24
|
+
readonly metadata: EngineMetadata | null;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC;IACzB,IAAI,EAAE,UAAU,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,YAAY,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;IACpD,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IAC5C,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;IAClC,YAAY,CAAC,IAAI,OAAO,CAAC;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;CAC1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const VERSION = "0.0.1";
|
|
2
|
+
export { listDevices, findAndroidSdk, bootDevice, shutdownDevice, } from "./device-manager.js";
|
|
3
|
+
export { detectProfileFromConfig, detectProfile } from "./profiles.js";
|
|
4
|
+
export { ScrcpyEngine } from "./engine/scrcpy-engine.js";
|
|
5
|
+
export { Session } from "./session.js";
|
|
6
|
+
export { startMcpServer } from "./mcp/server.js";
|
|
7
|
+
export { createPortholeMiddleware, attachPortholeWs } from "./middleware.js";
|
|
8
|
+
export type { DeviceInfo } from "./device-manager.js";
|
|
9
|
+
export type { DeviceProfile } from "./profiles.js";
|
|
10
|
+
export type { InputEvent, TouchEvent, KeyEvent, TextEvent, RemoteEvent, } from "./input.js";
|
|
11
|
+
export type { Engine, EngineMetadata, VideoChunk } from "./engine/types.js";
|
|
12
|
+
export { AndroidKeycode, REMOTE_BUTTON_TO_KEYCODE } from "./keycodes.js";
|
|
13
|
+
export type { RemoteButton } from "./keycodes.js";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,OAAO,EACL,WAAW,EACX,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC7E,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,YAAY,EACV,UAAU,EACV,UAAU,EACV,QAAQ,EACR,SAAS,EACT,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACzE,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const VERSION = "0.0.1";
|
|
2
|
+
export { listDevices, findAndroidSdk, bootDevice, shutdownDevice, } from "./device-manager.js";
|
|
3
|
+
export { detectProfileFromConfig, detectProfile } from "./profiles.js";
|
|
4
|
+
export { ScrcpyEngine } from "./engine/scrcpy-engine.js";
|
|
5
|
+
export { Session } from "./session.js";
|
|
6
|
+
export { startMcpServer } from "./mcp/server.js";
|
|
7
|
+
export { createPortholeMiddleware, attachPortholeWs } from "./middleware.js";
|
|
8
|
+
export { AndroidKeycode, REMOTE_BUTTON_TO_KEYCODE } from "./keycodes.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,OAAO,EACL,WAAW,EACX,cAAc,EACd,UAAU,EACV,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAW7E,OAAO,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { InputEvent } from "./input.js";
|
|
2
|
+
import type { DeviceProfile } from "./profiles.js";
|
|
3
|
+
export declare function parseInputEvent(value: unknown): InputEvent;
|
|
4
|
+
export declare function assertInputAllowed(profile: DeviceProfile, event: InputEvent): void;
|
|
5
|
+
//# sourceMappingURL=input-validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-validation.d.ts","sourceRoot":"","sources":["../src/input-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAKnD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAqD1D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAIlF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { REMOTE_BUTTON_TO_KEYCODE } from "./keycodes.js";
|
|
2
|
+
const TOUCH_PHASES = new Set(["down", "move", "up"]);
|
|
3
|
+
const KEY_PHASES = new Set(["down", "up"]);
|
|
4
|
+
export function parseInputEvent(value) {
|
|
5
|
+
if (!value || typeof value !== "object") {
|
|
6
|
+
throw new Error("Input event must be an object.");
|
|
7
|
+
}
|
|
8
|
+
const event = value;
|
|
9
|
+
if (event.kind === "touch") {
|
|
10
|
+
if (!TOUCH_PHASES.has(String(event.phase))) {
|
|
11
|
+
throw new Error("Touch phase must be down, move, or up.");
|
|
12
|
+
}
|
|
13
|
+
if (!isNormalized(event.x) || !isNormalized(event.y)) {
|
|
14
|
+
throw new Error("Touch coordinates must be numbers in 0..1.");
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
kind: "touch",
|
|
18
|
+
phase: event.phase,
|
|
19
|
+
x: event.x,
|
|
20
|
+
y: event.y,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (event.kind === "key") {
|
|
24
|
+
if (!KEY_PHASES.has(String(event.phase))) {
|
|
25
|
+
throw new Error("Key phase must be down or up.");
|
|
26
|
+
}
|
|
27
|
+
if (!Number.isInteger(event.keycode)) {
|
|
28
|
+
throw new Error("Keycode must be an integer.");
|
|
29
|
+
}
|
|
30
|
+
const keycode = event.keycode;
|
|
31
|
+
return {
|
|
32
|
+
kind: "key",
|
|
33
|
+
phase: event.phase,
|
|
34
|
+
keycode,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (event.kind === "text") {
|
|
38
|
+
if (typeof event.text !== "string") {
|
|
39
|
+
throw new Error("Text input must include a string text field.");
|
|
40
|
+
}
|
|
41
|
+
return { kind: "text", text: event.text };
|
|
42
|
+
}
|
|
43
|
+
if (event.kind === "remote") {
|
|
44
|
+
if (typeof event.button !== "string" || !isRemoteButton(event.button)) {
|
|
45
|
+
throw new Error(`Remote button must be one of ${Object.keys(REMOTE_BUTTON_TO_KEYCODE).join(", ")}.`);
|
|
46
|
+
}
|
|
47
|
+
return { kind: "remote", button: event.button };
|
|
48
|
+
}
|
|
49
|
+
throw new Error("Unknown input event kind.");
|
|
50
|
+
}
|
|
51
|
+
export function assertInputAllowed(profile, event) {
|
|
52
|
+
if (profile === "tv" && event.kind === "touch") {
|
|
53
|
+
throw new Error("Touch input is not available for TV profile sessions.");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function isNormalized(value) {
|
|
57
|
+
return typeof value === "number" && value >= 0 && value <= 1;
|
|
58
|
+
}
|
|
59
|
+
function isRemoteButton(value) {
|
|
60
|
+
return Object.prototype.hasOwnProperty.call(REMOTE_BUTTON_TO_KEYCODE, value);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=input-validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-validation.js","sourceRoot":"","sources":["../src/input-validation.ts"],"names":[],"mappings":"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"}
|
package/dist/input.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { RemoteButton } from "./keycodes.js";
|
|
2
|
+
export interface TouchEvent {
|
|
3
|
+
kind: "touch";
|
|
4
|
+
phase: "down" | "move" | "up";
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
}
|
|
8
|
+
export interface KeyEvent {
|
|
9
|
+
kind: "key";
|
|
10
|
+
phase: "down" | "up";
|
|
11
|
+
keycode: number;
|
|
12
|
+
}
|
|
13
|
+
export interface TextEvent {
|
|
14
|
+
kind: "text";
|
|
15
|
+
text: string;
|
|
16
|
+
}
|
|
17
|
+
export interface RemoteEvent {
|
|
18
|
+
kind: "remote";
|
|
19
|
+
button: RemoteButton;
|
|
20
|
+
}
|
|
21
|
+
export type InputEvent = TouchEvent | KeyEvent | TextEvent | RemoteEvent;
|
|
22
|
+
//# sourceMappingURL=input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC"}
|
package/dist/input.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input.js","sourceRoot":"","sources":["../src/input.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const AndroidKeycode: {
|
|
2
|
+
readonly KEYCODE_DPAD_UP: 19;
|
|
3
|
+
readonly KEYCODE_DPAD_DOWN: 20;
|
|
4
|
+
readonly KEYCODE_DPAD_LEFT: 21;
|
|
5
|
+
readonly KEYCODE_DPAD_RIGHT: 22;
|
|
6
|
+
readonly KEYCODE_DPAD_CENTER: 23;
|
|
7
|
+
readonly KEYCODE_BACK: 4;
|
|
8
|
+
readonly KEYCODE_HOME: 3;
|
|
9
|
+
readonly KEYCODE_MENU: 82;
|
|
10
|
+
readonly KEYCODE_MEDIA_PLAY_PAUSE: 85;
|
|
11
|
+
readonly KEYCODE_MEDIA_REWIND: 89;
|
|
12
|
+
readonly KEYCODE_MEDIA_FAST_FORWARD: 90;
|
|
13
|
+
readonly KEYCODE_VOLUME_UP: 24;
|
|
14
|
+
readonly KEYCODE_VOLUME_DOWN: 25;
|
|
15
|
+
readonly KEYCODE_WAKEUP: 224;
|
|
16
|
+
};
|
|
17
|
+
export type RemoteButton = "dpad_up" | "dpad_down" | "dpad_left" | "dpad_right" | "select" | "back" | "home" | "menu" | "play_pause" | "rewind" | "fast_forward" | "volume_up" | "volume_down";
|
|
18
|
+
export declare const REMOTE_BUTTON_TO_KEYCODE: Record<RemoteButton, number>;
|
|
19
|
+
//# sourceMappingURL=keycodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keycodes.d.ts","sourceRoot":"","sources":["../src/keycodes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;CAejB,CAAC;AAEX,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,WAAW,GACX,WAAW,GACX,YAAY,GACZ,QAAQ,GACR,MAAM,GACN,MAAM,GACN,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,cAAc,GACd,WAAW,GACX,aAAa,CAAC;AAElB,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAcjE,CAAC"}
|
package/dist/keycodes.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const AndroidKeycode = {
|
|
2
|
+
KEYCODE_DPAD_UP: 19,
|
|
3
|
+
KEYCODE_DPAD_DOWN: 20,
|
|
4
|
+
KEYCODE_DPAD_LEFT: 21,
|
|
5
|
+
KEYCODE_DPAD_RIGHT: 22,
|
|
6
|
+
KEYCODE_DPAD_CENTER: 23,
|
|
7
|
+
KEYCODE_BACK: 4,
|
|
8
|
+
KEYCODE_HOME: 3,
|
|
9
|
+
KEYCODE_MENU: 82,
|
|
10
|
+
KEYCODE_MEDIA_PLAY_PAUSE: 85,
|
|
11
|
+
KEYCODE_MEDIA_REWIND: 89,
|
|
12
|
+
KEYCODE_MEDIA_FAST_FORWARD: 90,
|
|
13
|
+
KEYCODE_VOLUME_UP: 24,
|
|
14
|
+
KEYCODE_VOLUME_DOWN: 25,
|
|
15
|
+
KEYCODE_WAKEUP: 224,
|
|
16
|
+
};
|
|
17
|
+
export const REMOTE_BUTTON_TO_KEYCODE = {
|
|
18
|
+
dpad_up: AndroidKeycode.KEYCODE_DPAD_UP,
|
|
19
|
+
dpad_down: AndroidKeycode.KEYCODE_DPAD_DOWN,
|
|
20
|
+
dpad_left: AndroidKeycode.KEYCODE_DPAD_LEFT,
|
|
21
|
+
dpad_right: AndroidKeycode.KEYCODE_DPAD_RIGHT,
|
|
22
|
+
select: AndroidKeycode.KEYCODE_DPAD_CENTER,
|
|
23
|
+
back: AndroidKeycode.KEYCODE_BACK,
|
|
24
|
+
home: AndroidKeycode.KEYCODE_HOME,
|
|
25
|
+
menu: AndroidKeycode.KEYCODE_MENU,
|
|
26
|
+
play_pause: AndroidKeycode.KEYCODE_MEDIA_PLAY_PAUSE,
|
|
27
|
+
rewind: AndroidKeycode.KEYCODE_MEDIA_REWIND,
|
|
28
|
+
fast_forward: AndroidKeycode.KEYCODE_MEDIA_FAST_FORWARD,
|
|
29
|
+
volume_up: AndroidKeycode.KEYCODE_VOLUME_UP,
|
|
30
|
+
volume_down: AndroidKeycode.KEYCODE_VOLUME_DOWN,
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=keycodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"keycodes.js","sourceRoot":"","sources":["../src/keycodes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,eAAe,EAAE,EAAE;IACnB,iBAAiB,EAAE,EAAE;IACrB,iBAAiB,EAAE,EAAE;IACrB,kBAAkB,EAAE,EAAE;IACtB,mBAAmB,EAAE,EAAE;IACvB,YAAY,EAAE,CAAC;IACf,YAAY,EAAE,CAAC;IACf,YAAY,EAAE,EAAE;IAChB,wBAAwB,EAAE,EAAE;IAC5B,oBAAoB,EAAE,EAAE;IACxB,0BAA0B,EAAE,EAAE;IAC9B,iBAAiB,EAAE,EAAE;IACrB,mBAAmB,EAAE,EAAE;IACvB,cAAc,EAAE,GAAG;CACX,CAAC;AAiBX,MAAM,CAAC,MAAM,wBAAwB,GAAiC;IACpE,OAAO,EAAE,cAAc,CAAC,eAAe;IACvC,SAAS,EAAE,cAAc,CAAC,iBAAiB;IAC3C,SAAS,EAAE,cAAc,CAAC,iBAAiB;IAC3C,UAAU,EAAE,cAAc,CAAC,kBAAkB;IAC7C,MAAM,EAAE,cAAc,CAAC,mBAAmB;IAC1C,IAAI,EAAE,cAAc,CAAC,YAAY;IACjC,IAAI,EAAE,cAAc,CAAC,YAAY;IACjC,IAAI,EAAE,cAAc,CAAC,YAAY;IACjC,UAAU,EAAE,cAAc,CAAC,wBAAwB;IACnD,MAAM,EAAE,cAAc,CAAC,oBAAoB;IAC3C,YAAY,EAAE,cAAc,CAAC,0BAA0B;IACvD,SAAS,EAAE,cAAc,CAAC,iBAAiB;IAC3C,WAAW,EAAE,cAAc,CAAC,mBAAmB;CAChD,CAAC"}
|
package/dist/log.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,IAAI,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEvE,wBAAgB,QAAQ,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMvE"}
|
package/dist/log.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function debugLog(namespace, message) {
|
|
2
|
+
const enabled = process.env["PORTHOLE_DEBUG"];
|
|
3
|
+
if (!enabled)
|
|
4
|
+
return;
|
|
5
|
+
const namespaces = new Set(enabled.split(",").map((value) => value.trim()));
|
|
6
|
+
if (!namespaces.has("*") && !namespaces.has(namespace))
|
|
7
|
+
return;
|
|
8
|
+
process.stderr.write(`[porthole:${namespace}] ${message}\n`);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=log.js.map
|
package/dist/log.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../src/log.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,QAAQ,CAAC,SAAuB,EAAE,OAAe;IAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9C,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC5E,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO;IAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,SAAS,KAAK,OAAO,IAAI,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAgBA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA6dpD"}
|