pangolint-mcp 0.7.20 → 0.7.28
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 +6 -6
- package/dist/server.js +225 -216
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,7 +31,7 @@ which pangolint-mcp
|
|
|
31
31
|
Or install the `pangolint-mcp` tarball attached to a GitHub Release:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
npm install -g ./pangolint-mcp-0.7.
|
|
34
|
+
npm install -g ./pangolint-mcp-0.7.28.tgz
|
|
35
35
|
which pangolint-mcp
|
|
36
36
|
```
|
|
37
37
|
|
|
@@ -40,7 +40,7 @@ For local development, build the same tarball from a repository checkout:
|
|
|
40
40
|
```bash
|
|
41
41
|
# from the repository root
|
|
42
42
|
npm run package:mcp
|
|
43
|
-
npm install -g ./mcp/pangolint-mcp-0.7.
|
|
43
|
+
npm install -g ./mcp/pangolint-mcp-0.7.28.tgz
|
|
44
44
|
which pangolint-mcp
|
|
45
45
|
```
|
|
46
46
|
|
|
@@ -124,12 +124,12 @@ calling individual tools.
|
|
|
124
124
|
| `PANGOLINT_MCP_BEYOND_TALK_TRANSPORT` | `auto` | `auto`, `tcp`, or `udp`. Auto tries Talk TCP first and only uses UDP when fallback is explicitly allowed. |
|
|
125
125
|
| `PANGOLINT_MCP_BEYOND_TALK_TCP_HOST` | `127.0.0.1` | BEYOND Talk TCP host. |
|
|
126
126
|
| `PANGOLINT_MCP_BEYOND_TALK_TCP_PORT` | `16063` | BEYOND Talk TCP port. |
|
|
127
|
-
| `PANGOLINT_MCP_BEYOND_TALK_UDP_HOST` |
|
|
128
|
-
| `PANGOLINT_MCP_BEYOND_TALK_UDP_PORT` |
|
|
127
|
+
| `PANGOLINT_MCP_BEYOND_TALK_UDP_HOST` | Talk host alias or `127.0.0.1` | BEYOND Talk UDP host. |
|
|
128
|
+
| `PANGOLINT_MCP_BEYOND_TALK_UDP_PORT` | Talk port alias or `16062` | BEYOND Talk UDP port. |
|
|
129
129
|
| `PANGOLINT_MCP_BEYOND_TALK_UDP_FALLBACK_ALLOWED` | (off) | Set to `enabled` (or `1` / `true`) to allow auto mode to use unauthenticated UDP when TCP is unavailable before authentication or command send begins. |
|
|
130
130
|
| `PANGOLINT_MCP_BEYOND_TALK_TCP_PASSWORD` | (empty) | Optional BEYOND TCP Talk Server password. This value is redacted from runtime output. |
|
|
131
|
-
| `PANGOLINT_MCP_BEYOND_TALK_HOST` | `127.0.0.1` |
|
|
132
|
-
| `PANGOLINT_MCP_BEYOND_TALK_PORT` | `16062` |
|
|
131
|
+
| `PANGOLINT_MCP_BEYOND_TALK_HOST` | `127.0.0.1` | UDP host alias used when `PANGOLINT_MCP_BEYOND_TALK_UDP_HOST` is unset. |
|
|
132
|
+
| `PANGOLINT_MCP_BEYOND_TALK_PORT` | `16062` | UDP port alias used when `PANGOLINT_MCP_BEYOND_TALK_UDP_PORT` is unset. |
|
|
133
133
|
| `PANGOLINT_MCP_BEYOND_OSC_LISTEN_HOST` | `0.0.0.0` | Local interface for OSC callbacks. |
|
|
134
134
|
| `PANGOLINT_MCP_BEYOND_OSC_LISTEN_PORT` | `7000` | Local UDP port for OSC callbacks. |
|
|
135
135
|
| `PANGOLINT_MCP_READBACK_TIMEOUT_MS` | `3000` | Readback timeout (ms). |
|
package/dist/server.js
CHANGED
|
@@ -21909,8 +21909,38 @@ function formatUnsupportedTalkControlFlowError(findings) {
|
|
|
21909
21909
|
return `BEYOND Talk can only send straight-line command batches. This script contains ${first.construct} control flow at line ${first.lineNumber}: ${first.lineText}.${extra} Paste/run it directly in BEYOND's PangoScript editor to test full script control flow.`;
|
|
21910
21910
|
}
|
|
21911
21911
|
|
|
21912
|
-
// ../src/runtime/
|
|
21913
|
-
|
|
21912
|
+
// ../src/runtime/osc/oscPortLock.ts
|
|
21913
|
+
var oscPortLocks = /* @__PURE__ */ new Map();
|
|
21914
|
+
async function acquireOscPortLock(options) {
|
|
21915
|
+
const key = `${options.listenHost}:${options.listenPort}`;
|
|
21916
|
+
const previous = oscPortLocks.get(key) ?? Promise.resolve();
|
|
21917
|
+
let releaseTail;
|
|
21918
|
+
const tail = new Promise((resolve) => {
|
|
21919
|
+
releaseTail = resolve;
|
|
21920
|
+
});
|
|
21921
|
+
const next = previous.catch(() => void 0).then(() => tail);
|
|
21922
|
+
oscPortLocks.set(key, next);
|
|
21923
|
+
await previous.catch(() => void 0);
|
|
21924
|
+
let released = false;
|
|
21925
|
+
return () => {
|
|
21926
|
+
if (released) return;
|
|
21927
|
+
released = true;
|
|
21928
|
+
releaseTail();
|
|
21929
|
+
if (oscPortLocks.get(key) === next) {
|
|
21930
|
+
oscPortLocks.delete(key);
|
|
21931
|
+
}
|
|
21932
|
+
};
|
|
21933
|
+
}
|
|
21934
|
+
async function withOscPortLock(options, operation) {
|
|
21935
|
+
const release = await acquireOscPortLock(options);
|
|
21936
|
+
try {
|
|
21937
|
+
return await operation();
|
|
21938
|
+
} finally {
|
|
21939
|
+
release();
|
|
21940
|
+
}
|
|
21941
|
+
}
|
|
21942
|
+
|
|
21943
|
+
// ../src/runtime/readback/nodeReadbackTransport.ts
|
|
21914
21944
|
import dgram2 from "node:dgram";
|
|
21915
21945
|
|
|
21916
21946
|
// ../src/runtime/osc/osc.ts
|
|
@@ -22003,45 +22033,146 @@ function requireBytes(payload, offset, length, message) {
|
|
|
22003
22033
|
}
|
|
22004
22034
|
}
|
|
22005
22035
|
|
|
22006
|
-
// ../src/runtime/
|
|
22007
|
-
var
|
|
22008
|
-
async
|
|
22009
|
-
|
|
22010
|
-
|
|
22011
|
-
|
|
22012
|
-
|
|
22013
|
-
|
|
22036
|
+
// ../src/runtime/readback/nodeReadbackTransport.ts
|
|
22037
|
+
var nodeReadbackTransport = {
|
|
22038
|
+
async sendTalk(host, port, payload) {
|
|
22039
|
+
await sendTalkUdp(host, port, payload);
|
|
22040
|
+
},
|
|
22041
|
+
async sendTalkTcp(options) {
|
|
22042
|
+
return sendTalkTcpCommands(options);
|
|
22043
|
+
},
|
|
22044
|
+
listenForOsc(host, port, predicate, timeoutMs) {
|
|
22045
|
+
const socket = dgram2.createSocket("udp4");
|
|
22046
|
+
const readyDeferred = createDeferred();
|
|
22047
|
+
let settled = false;
|
|
22048
|
+
let closeListener = () => {
|
|
22049
|
+
};
|
|
22050
|
+
const message = new Promise((resolve, reject) => {
|
|
22051
|
+
const timer = setTimeout(
|
|
22052
|
+
() => {
|
|
22053
|
+
const timeoutError = new Error(`Timed out waiting for OSC callback after ${timeoutMs}ms.`);
|
|
22054
|
+
readyDeferred.reject(timeoutError);
|
|
22055
|
+
finish(() => reject(timeoutError));
|
|
22056
|
+
},
|
|
22057
|
+
Math.max(1, timeoutMs)
|
|
22058
|
+
);
|
|
22059
|
+
const finish = (settle) => {
|
|
22060
|
+
if (settled) {
|
|
22061
|
+
return;
|
|
22062
|
+
}
|
|
22063
|
+
settled = true;
|
|
22064
|
+
clearTimeout(timer);
|
|
22065
|
+
try {
|
|
22066
|
+
socket.close();
|
|
22067
|
+
} catch {
|
|
22068
|
+
}
|
|
22069
|
+
settle();
|
|
22070
|
+
};
|
|
22071
|
+
closeListener = () => {
|
|
22072
|
+
const closeError = new Error("OSC listener closed before callback.");
|
|
22073
|
+
readyDeferred.reject(closeError);
|
|
22074
|
+
finish(() => reject(closeError));
|
|
22075
|
+
};
|
|
22076
|
+
socket.on("error", (error2) => {
|
|
22077
|
+
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
22078
|
+
const bindError = new Error(`OSC listener failed on ${host}:${port}: ${msg}`);
|
|
22079
|
+
readyDeferred.reject(bindError);
|
|
22080
|
+
finish(() => reject(bindError));
|
|
22081
|
+
});
|
|
22082
|
+
socket.on("listening", () => {
|
|
22083
|
+
readyDeferred.resolve();
|
|
22084
|
+
});
|
|
22085
|
+
socket.on("message", (payload, rinfo) => {
|
|
22086
|
+
let decoded;
|
|
22087
|
+
try {
|
|
22088
|
+
decoded = {
|
|
22089
|
+
...decodeOscPacket(payload),
|
|
22090
|
+
sourceAddress: rinfo.address,
|
|
22091
|
+
sourcePort: rinfo.port
|
|
22092
|
+
};
|
|
22093
|
+
} catch {
|
|
22094
|
+
return;
|
|
22095
|
+
}
|
|
22096
|
+
if (predicate(decoded)) {
|
|
22097
|
+
finish(() => resolve(decoded));
|
|
22098
|
+
}
|
|
22099
|
+
});
|
|
22100
|
+
});
|
|
22101
|
+
socket.bind(Number(port), host);
|
|
22102
|
+
return { ready: readyDeferred.promise, message, close: closeListener };
|
|
22103
|
+
}
|
|
22104
|
+
};
|
|
22105
|
+
function createDeferred() {
|
|
22106
|
+
let resolve = () => {
|
|
22107
|
+
};
|
|
22108
|
+
let reject = () => {
|
|
22109
|
+
};
|
|
22110
|
+
const promise = new Promise((res, rej) => {
|
|
22111
|
+
resolve = res;
|
|
22112
|
+
reject = rej;
|
|
22014
22113
|
});
|
|
22015
|
-
|
|
22016
|
-
|
|
22017
|
-
|
|
22018
|
-
|
|
22019
|
-
|
|
22020
|
-
|
|
22021
|
-
|
|
22022
|
-
|
|
22023
|
-
|
|
22024
|
-
|
|
22114
|
+
let settled = false;
|
|
22115
|
+
return {
|
|
22116
|
+
promise,
|
|
22117
|
+
resolve: (value) => {
|
|
22118
|
+
if (settled) return;
|
|
22119
|
+
settled = true;
|
|
22120
|
+
resolve(value);
|
|
22121
|
+
},
|
|
22122
|
+
reject: (error2) => {
|
|
22123
|
+
if (settled) return;
|
|
22124
|
+
settled = true;
|
|
22125
|
+
reject(error2);
|
|
22025
22126
|
}
|
|
22026
22127
|
};
|
|
22027
22128
|
}
|
|
22028
|
-
|
|
22029
|
-
|
|
22030
|
-
|
|
22031
|
-
|
|
22032
|
-
|
|
22033
|
-
|
|
22129
|
+
|
|
22130
|
+
// ../src/runtime/readback/readbackOscCallbacks.ts
|
|
22131
|
+
function expectedReadbackOscSourceHosts(options) {
|
|
22132
|
+
const transport = options.talkTransport ?? "udp";
|
|
22133
|
+
if (transport === "tcp") {
|
|
22134
|
+
return [options.talkTcpHost ?? options.talkHost];
|
|
22034
22135
|
}
|
|
22136
|
+
if (transport === "auto") {
|
|
22137
|
+
const tcpHost = options.talkTcpHost ?? options.talkHost;
|
|
22138
|
+
const udpHost = options.talkUdpHost ?? options.talkHost;
|
|
22139
|
+
return options.talkUdpFallbackAllowed ? uniqueDefinedHosts([tcpHost, udpHost]) : [tcpHost];
|
|
22140
|
+
}
|
|
22141
|
+
return [options.talkUdpHost ?? options.talkHost];
|
|
22142
|
+
}
|
|
22143
|
+
function isExpectedOscCallback(message, expected) {
|
|
22144
|
+
if (message.address !== expected.address) return false;
|
|
22145
|
+
if (message.typeTags !== expected.typeTags) return false;
|
|
22146
|
+
if (!sourceMatchesAnyExpectedHost(message, expected.expectedSourceHosts)) return false;
|
|
22147
|
+
if (expected.expectedArgs) {
|
|
22148
|
+
if (message.args.length !== expected.expectedArgs.length) return false;
|
|
22149
|
+
return expected.expectedArgs.every((arg, index) => message.args[index] === arg);
|
|
22150
|
+
}
|
|
22151
|
+
if (message.args.length !== expected.typeTags.length) return false;
|
|
22152
|
+
return expected.typeTags.split("").every((tag, index) => argMatchesTypeTag(message.args[index], tag));
|
|
22153
|
+
}
|
|
22154
|
+
function assertExpectedOscCallback(message, expected) {
|
|
22155
|
+
if (!isExpectedOscCallback(message, expected)) {
|
|
22156
|
+
throw new Error(`Unexpected OSC callback for ${expected.address}.`);
|
|
22157
|
+
}
|
|
22158
|
+
}
|
|
22159
|
+
function uniqueDefinedHosts(hosts) {
|
|
22160
|
+
return [...new Set(hosts.filter((host) => host.trim().length > 0))];
|
|
22161
|
+
}
|
|
22162
|
+
function sourceMatchesAnyExpectedHost(message, expectedHosts) {
|
|
22163
|
+
return expectedHosts.length === 0 || expectedHosts.some((host) => sourceMatchesExpectedHost(message, host));
|
|
22164
|
+
}
|
|
22165
|
+
function argMatchesTypeTag(arg, tag) {
|
|
22166
|
+
if (tag === "s") return typeof arg === "string";
|
|
22167
|
+
if (tag === "i") return typeof arg === "number" && Number.isInteger(arg);
|
|
22168
|
+
if (tag === "f") return typeof arg === "number" && Number.isFinite(arg);
|
|
22169
|
+
return false;
|
|
22035
22170
|
}
|
|
22036
22171
|
|
|
22037
|
-
// ../src/runtime/readback/
|
|
22172
|
+
// ../src/runtime/readback/readbackPropertyPath.ts
|
|
22038
22173
|
var PROPERTY_ROOT2 = String.raw`(?:FB[34][-_][A-Za-z0-9]+|[A-Za-z_][A-Za-z0-9_]*|#[0-9]+)(?:\[[0-9]+\])*`;
|
|
22039
22174
|
var PROPERTY_SEGMENT = String.raw`(?:[A-Za-z_][A-Za-z0-9_]*|[0-9]+)(?:\[[0-9]+\])*`;
|
|
22040
22175
|
var PROPERTY_PATH_RE = new RegExp(`^${PROPERTY_ROOT2}(?:\\.${PROPERTY_SEGMENT})+$`);
|
|
22041
|
-
var REQUEST_ID_BYTES = 16;
|
|
22042
|
-
function createReadbackRequestId(prefix = "pangolint") {
|
|
22043
|
-
return `${prefix}-${randomBytes(REQUEST_ID_BYTES).toString("hex")}`;
|
|
22044
|
-
}
|
|
22045
22176
|
function validateReadbackPropertyPath(path10) {
|
|
22046
22177
|
const trimmed = path10.trim();
|
|
22047
22178
|
if (path10 !== trimmed || !PROPERTY_PATH_RE.test(trimmed)) {
|
|
@@ -22049,9 +22180,71 @@ function validateReadbackPropertyPath(path10) {
|
|
|
22049
22180
|
}
|
|
22050
22181
|
return void 0;
|
|
22051
22182
|
}
|
|
22183
|
+
|
|
22184
|
+
// ../src/runtime/readback/readbackRequestId.ts
|
|
22185
|
+
import { randomBytes } from "node:crypto";
|
|
22186
|
+
var REQUEST_ID_BYTES = 16;
|
|
22187
|
+
function createReadbackRequestId(prefix = "pangolint") {
|
|
22188
|
+
return `${prefix}-${randomBytes(REQUEST_ID_BYTES).toString("hex")}`;
|
|
22189
|
+
}
|
|
22190
|
+
|
|
22191
|
+
// ../src/runtime/readback/readbackScriptLines.ts
|
|
22192
|
+
function propertyReadbackScriptLines(address, typeTag, propertyPath, options) {
|
|
22193
|
+
if (usesStatusProducingReadbackLine(options)) {
|
|
22194
|
+
return [`OscOutTTS "${address}", "${typeTag}", ${propertyPath}`];
|
|
22195
|
+
}
|
|
22196
|
+
return ["var v", `v = ${propertyPath}`, `OscOutTTS "${address}", "${typeTag}", v`];
|
|
22197
|
+
}
|
|
22198
|
+
function usesStatusProducingReadbackLine(options) {
|
|
22199
|
+
const transport = options.talkTransport ?? "udp";
|
|
22200
|
+
return transport === "tcp" || transport === "auto";
|
|
22201
|
+
}
|
|
22202
|
+
|
|
22203
|
+
// ../src/runtime/readback/readbackTalk.ts
|
|
22204
|
+
async function sendReadbackTalk(commands, options, transport) {
|
|
22205
|
+
return runScript(commands.join("\n"), {
|
|
22206
|
+
talkHost: options.talkHost,
|
|
22207
|
+
talkPort: options.talkPort,
|
|
22208
|
+
talkTransport: options.talkTransport ?? "udp",
|
|
22209
|
+
talkTcpHost: options.talkTcpHost,
|
|
22210
|
+
talkTcpPort: options.talkTcpPort,
|
|
22211
|
+
talkUdpHost: options.talkUdpHost ?? options.talkHost,
|
|
22212
|
+
talkUdpPort: options.talkUdpPort ?? options.talkPort,
|
|
22213
|
+
talkUdpFallbackAllowed: options.talkUdpFallbackAllowed,
|
|
22214
|
+
talkTcpPassword: options.talkTcpPassword,
|
|
22215
|
+
commandTimeoutMs: options.commandTimeoutMs ?? options.timeoutMs,
|
|
22216
|
+
send: transport.sendTalk,
|
|
22217
|
+
sendTcp: transport.sendTalkTcp
|
|
22218
|
+
});
|
|
22219
|
+
}
|
|
22220
|
+
function readbackTalkStatus(result) {
|
|
22221
|
+
return {
|
|
22222
|
+
transport: result.transport,
|
|
22223
|
+
talkStatus: result.talkStatus,
|
|
22224
|
+
talkGreeting: result.talkGreeting,
|
|
22225
|
+
talkReplies: result.talkReplies,
|
|
22226
|
+
beyondError: result.beyondError,
|
|
22227
|
+
linesSent: result.linesSent,
|
|
22228
|
+
payloadsSent: result.payloadsSent,
|
|
22229
|
+
bytesSent: result.bytesSent
|
|
22230
|
+
};
|
|
22231
|
+
}
|
|
22232
|
+
function udpPayloadPreflightError(commands, options) {
|
|
22233
|
+
if (!readbackUdpMayBeUsed(options)) {
|
|
22234
|
+
return void 0;
|
|
22235
|
+
}
|
|
22236
|
+
const payloads = buildTalkPayloads([...commands]);
|
|
22237
|
+
return payloads.length > 1 ? "Script exceeded payload limit." : void 0;
|
|
22238
|
+
}
|
|
22239
|
+
function readbackUdpMayBeUsed(options) {
|
|
22240
|
+
const transport = options.talkTransport ?? "udp";
|
|
22241
|
+
return transport === "udp" || transport === "auto" && options.talkUdpFallbackAllowed === true;
|
|
22242
|
+
}
|
|
22243
|
+
|
|
22244
|
+
// ../src/runtime/readback/beyondReadback.ts
|
|
22052
22245
|
async function readBeyondProperty(options, transport = nodeReadbackTransport) {
|
|
22053
22246
|
const { logger } = options;
|
|
22054
|
-
const requestId = options.requestId ??
|
|
22247
|
+
const requestId = options.requestId ?? createReadbackRequestId();
|
|
22055
22248
|
const typeTag = options.typeTag ?? "f";
|
|
22056
22249
|
const address = `/pangolint/readback/${requestId}`;
|
|
22057
22250
|
const pathError = validateReadbackPropertyPath(options.propertyPath);
|
|
@@ -22144,196 +22337,12 @@ async function readBeyondProperty(options, transport = nodeReadbackTransport) {
|
|
|
22144
22337
|
return { ok: false, requestId, propertyPath: options.propertyPath, script, error: msg };
|
|
22145
22338
|
}
|
|
22146
22339
|
}
|
|
22147
|
-
function propertyReadbackScriptLines(address, typeTag, propertyPath, options) {
|
|
22148
|
-
if (usesStatusProducingReadbackLine(options)) {
|
|
22149
|
-
return [`OscOutTTS "${address}", "${typeTag}", ${propertyPath}`];
|
|
22150
|
-
}
|
|
22151
|
-
return ["var v", `v = ${propertyPath}`, `OscOutTTS "${address}", "${typeTag}", v`];
|
|
22152
|
-
}
|
|
22153
|
-
function usesStatusProducingReadbackLine(options) {
|
|
22154
|
-
const transport = options.talkTransport ?? "udp";
|
|
22155
|
-
return transport === "tcp" || transport === "auto";
|
|
22156
|
-
}
|
|
22157
|
-
async function sendReadbackTalk(commands, options, transport) {
|
|
22158
|
-
return runScript(commands.join("\n"), {
|
|
22159
|
-
talkHost: options.talkHost,
|
|
22160
|
-
talkPort: options.talkPort,
|
|
22161
|
-
talkTransport: options.talkTransport ?? "udp",
|
|
22162
|
-
talkTcpHost: options.talkTcpHost,
|
|
22163
|
-
talkTcpPort: options.talkTcpPort,
|
|
22164
|
-
talkUdpHost: options.talkUdpHost ?? options.talkHost,
|
|
22165
|
-
talkUdpPort: options.talkUdpPort ?? options.talkPort,
|
|
22166
|
-
talkUdpFallbackAllowed: options.talkUdpFallbackAllowed,
|
|
22167
|
-
talkTcpPassword: options.talkTcpPassword,
|
|
22168
|
-
commandTimeoutMs: options.commandTimeoutMs ?? options.timeoutMs,
|
|
22169
|
-
send: transport.sendTalk,
|
|
22170
|
-
sendTcp: transport.sendTalkTcp
|
|
22171
|
-
});
|
|
22172
|
-
}
|
|
22173
|
-
function readbackTalkStatus(result) {
|
|
22174
|
-
return {
|
|
22175
|
-
transport: result.transport,
|
|
22176
|
-
talkStatus: result.talkStatus,
|
|
22177
|
-
talkGreeting: result.talkGreeting,
|
|
22178
|
-
talkReplies: result.talkReplies,
|
|
22179
|
-
beyondError: result.beyondError,
|
|
22180
|
-
linesSent: result.linesSent,
|
|
22181
|
-
payloadsSent: result.payloadsSent,
|
|
22182
|
-
bytesSent: result.bytesSent
|
|
22183
|
-
};
|
|
22184
|
-
}
|
|
22185
|
-
function udpPayloadPreflightError(commands, options) {
|
|
22186
|
-
if (!readbackUdpMayBeUsed(options)) {
|
|
22187
|
-
return void 0;
|
|
22188
|
-
}
|
|
22189
|
-
const payloads = buildTalkPayloads([...commands]);
|
|
22190
|
-
return payloads.length > 1 ? "Script exceeded payload limit." : void 0;
|
|
22191
|
-
}
|
|
22192
|
-
function readbackUdpMayBeUsed(options) {
|
|
22193
|
-
const transport = options.talkTransport ?? "udp";
|
|
22194
|
-
return transport === "udp" || transport === "auto" && options.talkUdpFallbackAllowed === true;
|
|
22195
|
-
}
|
|
22196
|
-
function expectedReadbackOscSourceHosts(options) {
|
|
22197
|
-
const transport = options.talkTransport ?? "udp";
|
|
22198
|
-
if (transport === "tcp") {
|
|
22199
|
-
return [options.talkTcpHost ?? options.talkHost];
|
|
22200
|
-
}
|
|
22201
|
-
if (transport === "auto") {
|
|
22202
|
-
const tcpHost = options.talkTcpHost ?? options.talkHost;
|
|
22203
|
-
const udpHost = options.talkUdpHost ?? options.talkHost;
|
|
22204
|
-
return options.talkUdpFallbackAllowed ? uniqueDefinedHosts([tcpHost, udpHost]) : [tcpHost];
|
|
22205
|
-
}
|
|
22206
|
-
return [options.talkUdpHost ?? options.talkHost];
|
|
22207
|
-
}
|
|
22208
|
-
function uniqueDefinedHosts(hosts) {
|
|
22209
|
-
return [...new Set(hosts.filter((host) => host.trim().length > 0))];
|
|
22210
|
-
}
|
|
22211
22340
|
function closeReadbackOscListener(listener) {
|
|
22212
22341
|
try {
|
|
22213
22342
|
listener.close?.();
|
|
22214
22343
|
} catch {
|
|
22215
22344
|
}
|
|
22216
22345
|
}
|
|
22217
|
-
function isExpectedOscCallback(message, expected) {
|
|
22218
|
-
if (message.address !== expected.address) return false;
|
|
22219
|
-
if (message.typeTags !== expected.typeTags) return false;
|
|
22220
|
-
if (!sourceMatchesAnyExpectedHost(message, expected.expectedSourceHosts)) return false;
|
|
22221
|
-
if (expected.expectedArgs) {
|
|
22222
|
-
if (message.args.length !== expected.expectedArgs.length) return false;
|
|
22223
|
-
return expected.expectedArgs.every((arg, index) => message.args[index] === arg);
|
|
22224
|
-
}
|
|
22225
|
-
if (message.args.length !== expected.typeTags.length) return false;
|
|
22226
|
-
return expected.typeTags.split("").every((tag, index) => argMatchesTypeTag(message.args[index], tag));
|
|
22227
|
-
}
|
|
22228
|
-
function sourceMatchesAnyExpectedHost(message, expectedHosts) {
|
|
22229
|
-
return expectedHosts.length === 0 || expectedHosts.some((host) => sourceMatchesExpectedHost(message, host));
|
|
22230
|
-
}
|
|
22231
|
-
function assertExpectedOscCallback(message, expected) {
|
|
22232
|
-
if (!isExpectedOscCallback(message, expected)) {
|
|
22233
|
-
throw new Error(`Unexpected OSC callback for ${expected.address}.`);
|
|
22234
|
-
}
|
|
22235
|
-
}
|
|
22236
|
-
function argMatchesTypeTag(arg, tag) {
|
|
22237
|
-
if (tag === "s") return typeof arg === "string";
|
|
22238
|
-
if (tag === "i") return typeof arg === "number" && Number.isInteger(arg);
|
|
22239
|
-
if (tag === "f") return typeof arg === "number" && Number.isFinite(arg);
|
|
22240
|
-
return false;
|
|
22241
|
-
}
|
|
22242
|
-
var nodeReadbackTransport = {
|
|
22243
|
-
async sendTalk(host, port, payload) {
|
|
22244
|
-
await sendTalkUdp(host, port, payload);
|
|
22245
|
-
},
|
|
22246
|
-
async sendTalkTcp(options) {
|
|
22247
|
-
return sendTalkTcpCommands(options);
|
|
22248
|
-
},
|
|
22249
|
-
listenForOsc(host, port, predicate, timeoutMs) {
|
|
22250
|
-
const socket = dgram2.createSocket("udp4");
|
|
22251
|
-
const readyDeferred = createDeferred();
|
|
22252
|
-
let settled = false;
|
|
22253
|
-
let closeListener = () => {
|
|
22254
|
-
};
|
|
22255
|
-
const message = new Promise((resolve, reject) => {
|
|
22256
|
-
const timer = setTimeout(
|
|
22257
|
-
() => {
|
|
22258
|
-
const timeoutError = new Error(`Timed out waiting for OSC callback after ${timeoutMs}ms.`);
|
|
22259
|
-
readyDeferred.reject(timeoutError);
|
|
22260
|
-
finish(() => reject(timeoutError));
|
|
22261
|
-
},
|
|
22262
|
-
Math.max(1, timeoutMs)
|
|
22263
|
-
);
|
|
22264
|
-
const finish = (settle) => {
|
|
22265
|
-
if (settled) {
|
|
22266
|
-
return;
|
|
22267
|
-
}
|
|
22268
|
-
settled = true;
|
|
22269
|
-
clearTimeout(timer);
|
|
22270
|
-
try {
|
|
22271
|
-
socket.close();
|
|
22272
|
-
} catch {
|
|
22273
|
-
}
|
|
22274
|
-
settle();
|
|
22275
|
-
};
|
|
22276
|
-
closeListener = () => {
|
|
22277
|
-
const closeError = new Error("OSC listener closed before callback.");
|
|
22278
|
-
readyDeferred.reject(closeError);
|
|
22279
|
-
finish(() => reject(closeError));
|
|
22280
|
-
};
|
|
22281
|
-
socket.on("error", (error2) => {
|
|
22282
|
-
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
22283
|
-
const bindError = new Error(`OSC listener failed on ${host}:${port}: ${msg}`);
|
|
22284
|
-
readyDeferred.reject(bindError);
|
|
22285
|
-
finish(() => reject(bindError));
|
|
22286
|
-
});
|
|
22287
|
-
socket.on("listening", () => {
|
|
22288
|
-
readyDeferred.resolve();
|
|
22289
|
-
});
|
|
22290
|
-
socket.on("message", (payload, rinfo) => {
|
|
22291
|
-
let decoded;
|
|
22292
|
-
try {
|
|
22293
|
-
decoded = {
|
|
22294
|
-
...decodeOscPacket(payload),
|
|
22295
|
-
sourceAddress: rinfo.address,
|
|
22296
|
-
sourcePort: rinfo.port
|
|
22297
|
-
};
|
|
22298
|
-
} catch {
|
|
22299
|
-
return;
|
|
22300
|
-
}
|
|
22301
|
-
if (predicate(decoded)) {
|
|
22302
|
-
finish(() => resolve(decoded));
|
|
22303
|
-
}
|
|
22304
|
-
});
|
|
22305
|
-
});
|
|
22306
|
-
socket.bind(Number(port), host);
|
|
22307
|
-
return { ready: readyDeferred.promise, message, close: closeListener };
|
|
22308
|
-
}
|
|
22309
|
-
};
|
|
22310
|
-
function createRequestId() {
|
|
22311
|
-
return createReadbackRequestId("pangolint");
|
|
22312
|
-
}
|
|
22313
|
-
function createDeferred() {
|
|
22314
|
-
let resolve = () => {
|
|
22315
|
-
};
|
|
22316
|
-
let reject = () => {
|
|
22317
|
-
};
|
|
22318
|
-
const promise = new Promise((res, rej) => {
|
|
22319
|
-
resolve = res;
|
|
22320
|
-
reject = rej;
|
|
22321
|
-
});
|
|
22322
|
-
let settled = false;
|
|
22323
|
-
return {
|
|
22324
|
-
promise,
|
|
22325
|
-
resolve: (value) => {
|
|
22326
|
-
if (settled) return;
|
|
22327
|
-
settled = true;
|
|
22328
|
-
resolve(value);
|
|
22329
|
-
},
|
|
22330
|
-
reject: (error2) => {
|
|
22331
|
-
if (settled) return;
|
|
22332
|
-
settled = true;
|
|
22333
|
-
reject(error2);
|
|
22334
|
-
}
|
|
22335
|
-
};
|
|
22336
|
-
}
|
|
22337
22346
|
|
|
22338
22347
|
// ../src/extensionHost/extensionIds.ts
|
|
22339
22348
|
var EXTENSION_CONFIG_SECTIONS = {
|