@openscout/scout 0.2.60 → 0.2.62
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 +29 -0
- package/dist/client/assets/{arc.es-DgeMPL-I.js → arc.es-nBIiEfYv.js} +1 -1
- package/dist/client/assets/index-BdwfgbIm.js +140 -0
- package/dist/client/assets/index-tcdw22Rl.css +1 -0
- package/dist/client/index.html +3 -2
- package/dist/main.mjs +2793 -5467
- package/dist/pair-supervisor.mjs +719 -2636
- package/dist/scout-control-plane-web.mjs +16597 -17857
- package/package.json +2 -2
- package/dist/client/assets/index-25TJx0iN.js +0 -140
- package/dist/client/assets/index-B1kglsyi.css +0 -1
package/dist/pair-supervisor.mjs
CHANGED
|
@@ -56,6 +56,9 @@ function resolvedPairingConfig() {
|
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
// ../../apps/desktop/src/core/pairing/supervisor.ts
|
|
60
|
+
import { spawn as spawn4 } from "child_process";
|
|
61
|
+
|
|
59
62
|
// ../../node_modules/.bun/uqr@0.1.3/node_modules/uqr/dist/index.mjs
|
|
60
63
|
var QrCodeDataType = /* @__PURE__ */ ((QrCodeDataType2) => {
|
|
61
64
|
QrCodeDataType2[QrCodeDataType2["Border"] = -1] = "Border";
|
|
@@ -685,7 +688,7 @@ function renderQRCode(payload) {
|
|
|
685
688
|
// ../../apps/desktop/src/core/pairing/runtime/relay-runtime.ts
|
|
686
689
|
import { execSync } from "child_process";
|
|
687
690
|
import { existsSync as existsSync2, mkdirSync as mkdirSync3, readdirSync } from "fs";
|
|
688
|
-
import { homedir as homedir2 } from "os";
|
|
691
|
+
import { homedir as homedir2, networkInterfaces } from "os";
|
|
689
692
|
import { join } from "path";
|
|
690
693
|
|
|
691
694
|
// ../../apps/desktop/src/core/pairing/runtime/log.ts
|
|
@@ -716,6 +719,7 @@ function startRelay(port, options = {}) {
|
|
|
716
719
|
const roomByBridgeKey = new Map;
|
|
717
720
|
const server = Bun.serve({
|
|
718
721
|
port,
|
|
722
|
+
hostname: "0.0.0.0",
|
|
719
723
|
...options.tls ? {
|
|
720
724
|
tls: {
|
|
721
725
|
cert: Bun.file(options.tls.cert),
|
|
@@ -974,24 +978,42 @@ function readTailscaleStatus() {
|
|
|
974
978
|
return null;
|
|
975
979
|
}
|
|
976
980
|
}
|
|
977
|
-
function resolveRelayEndpointForTailscaleStatus(port, tailscale) {
|
|
981
|
+
function resolveRelayEndpointForTailscaleStatus(port, tailscale, options = {}) {
|
|
978
982
|
const backendState = tailscale?.backendState?.trim().toLowerCase() ?? "";
|
|
979
983
|
const hostname = tailscale?.dnsName ?? null;
|
|
980
984
|
const tailscaleRunning = backendState === "running" && tailscale?.online !== false && Boolean(hostname);
|
|
981
|
-
const tls =
|
|
982
|
-
|
|
985
|
+
const tls = tailscaleRunning ? options.tls !== undefined ? options.tls : resolveTls(hostname) : null;
|
|
986
|
+
const scheme = tls ? "wss" : "ws";
|
|
987
|
+
const connectUrl = `${scheme}://127.0.0.1:${port}`;
|
|
988
|
+
const localAddress = options.localAddress !== undefined ? normalizedOptionalAddress(options.localAddress) : findLocalNetworkAddress();
|
|
989
|
+
const localRelayUrl = localAddress ? `${scheme}://${localAddress}:${port}` : null;
|
|
990
|
+
const tailnetRelayUrl = tailscaleRunning && hostname ? `${scheme}://${hostname}:${port}` : null;
|
|
991
|
+
const fallbackRelayUrls = tailnetRelayUrl && localRelayUrl ? [tailnetRelayUrl] : [];
|
|
992
|
+
if (localRelayUrl) {
|
|
983
993
|
return {
|
|
984
|
-
relayUrl:
|
|
994
|
+
relayUrl: localRelayUrl,
|
|
995
|
+
connectUrl,
|
|
996
|
+
fallbackRelayUrls,
|
|
997
|
+
options: tls ? { tls } : {}
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
if (tailnetRelayUrl && tls) {
|
|
1001
|
+
return {
|
|
1002
|
+
relayUrl: tailnetRelayUrl,
|
|
1003
|
+
connectUrl,
|
|
1004
|
+
fallbackRelayUrls: [],
|
|
985
1005
|
options: { tls }
|
|
986
1006
|
};
|
|
987
1007
|
}
|
|
988
|
-
if (
|
|
1008
|
+
if (tailnetRelayUrl) {
|
|
989
1009
|
pairingLog.warn("relay", "tailscale is running without TLS; falling back to insecure websocket relay", {
|
|
990
1010
|
hostname,
|
|
991
1011
|
port
|
|
992
1012
|
});
|
|
993
1013
|
return {
|
|
994
|
-
relayUrl:
|
|
1014
|
+
relayUrl: tailnetRelayUrl,
|
|
1015
|
+
connectUrl,
|
|
1016
|
+
fallbackRelayUrls: [],
|
|
995
1017
|
options: {}
|
|
996
1018
|
};
|
|
997
1019
|
}
|
|
@@ -1004,7 +1026,9 @@ function resolveRelayEndpointForTailscaleStatus(port, tailscale) {
|
|
|
1004
1026
|
});
|
|
1005
1027
|
}
|
|
1006
1028
|
return {
|
|
1007
|
-
relayUrl:
|
|
1029
|
+
relayUrl: connectUrl,
|
|
1030
|
+
connectUrl,
|
|
1031
|
+
fallbackRelayUrls: [],
|
|
1008
1032
|
options: {}
|
|
1009
1033
|
};
|
|
1010
1034
|
}
|
|
@@ -1057,16 +1081,87 @@ function resolveRelayEndpoint(port) {
|
|
|
1057
1081
|
}
|
|
1058
1082
|
function startManagedRelay(port = 7889) {
|
|
1059
1083
|
const endpoint = resolveRelayEndpoint(port);
|
|
1060
|
-
pairingLog.info("relay", "starting managed relay", {
|
|
1084
|
+
pairingLog.info("relay", "starting managed relay", {
|
|
1085
|
+
relay: endpoint.relayUrl,
|
|
1086
|
+
connectUrl: endpoint.connectUrl,
|
|
1087
|
+
fallbackRelayUrls: endpoint.fallbackRelayUrls,
|
|
1088
|
+
port
|
|
1089
|
+
});
|
|
1061
1090
|
const relay = startRelay(port, endpoint.options);
|
|
1062
1091
|
return {
|
|
1063
1092
|
relayUrl: endpoint.relayUrl,
|
|
1093
|
+
connectUrl: endpoint.connectUrl,
|
|
1094
|
+
fallbackRelayUrls: endpoint.fallbackRelayUrls,
|
|
1064
1095
|
stop() {
|
|
1065
1096
|
pairingLog.info("relay", "stopping managed relay", { relay: endpoint.relayUrl, port });
|
|
1066
1097
|
relay.stop();
|
|
1067
1098
|
}
|
|
1068
1099
|
};
|
|
1069
1100
|
}
|
|
1101
|
+
function normalizedOptionalAddress(address) {
|
|
1102
|
+
const trimmed = address?.trim();
|
|
1103
|
+
return trimmed ? trimmed : null;
|
|
1104
|
+
}
|
|
1105
|
+
function findLocalNetworkAddress() {
|
|
1106
|
+
const candidates = [];
|
|
1107
|
+
const interfaces = networkInterfaces();
|
|
1108
|
+
for (const [name, entries] of Object.entries(interfaces)) {
|
|
1109
|
+
for (const entry of entries ?? []) {
|
|
1110
|
+
if (entry.internal || entry.family !== "IPv4") {
|
|
1111
|
+
continue;
|
|
1112
|
+
}
|
|
1113
|
+
if (!isPrivateIPv4(entry.address) || isLinkLocalIPv4(entry.address) || isTailscaleIPv4(entry.address)) {
|
|
1114
|
+
continue;
|
|
1115
|
+
}
|
|
1116
|
+
candidates.push({ name, address: entry.address });
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
candidates.sort((left, right) => {
|
|
1120
|
+
const leftScore = localInterfaceScore(left.name);
|
|
1121
|
+
const rightScore = localInterfaceScore(right.name);
|
|
1122
|
+
if (leftScore !== rightScore) {
|
|
1123
|
+
return leftScore - rightScore;
|
|
1124
|
+
}
|
|
1125
|
+
return left.address.localeCompare(right.address);
|
|
1126
|
+
});
|
|
1127
|
+
return candidates[0]?.address ?? null;
|
|
1128
|
+
}
|
|
1129
|
+
function localInterfaceScore(name) {
|
|
1130
|
+
if (/^en\d+$/i.test(name)) {
|
|
1131
|
+
return 0;
|
|
1132
|
+
}
|
|
1133
|
+
if (/^bridge\d*$/i.test(name)) {
|
|
1134
|
+
return 2;
|
|
1135
|
+
}
|
|
1136
|
+
return 1;
|
|
1137
|
+
}
|
|
1138
|
+
function isPrivateIPv4(address) {
|
|
1139
|
+
const octets = parseIPv4(address);
|
|
1140
|
+
if (!octets) {
|
|
1141
|
+
return false;
|
|
1142
|
+
}
|
|
1143
|
+
const [first, second] = octets;
|
|
1144
|
+
return first === 10 || first === 172 && second >= 16 && second <= 31 || first === 192 && second === 168;
|
|
1145
|
+
}
|
|
1146
|
+
function isLinkLocalIPv4(address) {
|
|
1147
|
+
const octets = parseIPv4(address);
|
|
1148
|
+
return Boolean(octets && octets[0] === 169 && octets[1] === 254);
|
|
1149
|
+
}
|
|
1150
|
+
function isTailscaleIPv4(address) {
|
|
1151
|
+
const octets = parseIPv4(address);
|
|
1152
|
+
return Boolean(octets && octets[0] === 100 && octets[1] >= 64 && octets[1] <= 127);
|
|
1153
|
+
}
|
|
1154
|
+
function parseIPv4(address) {
|
|
1155
|
+
const octets = address.split(".");
|
|
1156
|
+
if (octets.length !== 4) {
|
|
1157
|
+
return null;
|
|
1158
|
+
}
|
|
1159
|
+
const numbers = octets.map((octet) => Number(octet));
|
|
1160
|
+
if (numbers.some((value) => !Number.isInteger(value) || value < 0 || value > 255)) {
|
|
1161
|
+
return null;
|
|
1162
|
+
}
|
|
1163
|
+
return numbers;
|
|
1164
|
+
}
|
|
1070
1165
|
|
|
1071
1166
|
// ../../apps/desktop/src/core/pairing/runtime/runtime-state.ts
|
|
1072
1167
|
import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync3, renameSync, unlinkSync, writeFileSync as writeFileSync3 } from "fs";
|
|
@@ -3152,15 +3247,30 @@ function isTrustedPeer(publicKeyHex) {
|
|
|
3152
3247
|
}
|
|
3153
3248
|
var QR_VERSION = 1;
|
|
3154
3249
|
var QR_EXPIRY_MS = 5 * 60 * 1000;
|
|
3155
|
-
function createQRPayload(bridgePublicKey, relayUrl) {
|
|
3250
|
+
function createQRPayload(bridgePublicKey, relayUrl, fallbackRelayUrls = []) {
|
|
3251
|
+
const fallbackRelays = normalizedRelayUrls(fallbackRelayUrls, relayUrl);
|
|
3156
3252
|
return {
|
|
3157
3253
|
v: QR_VERSION,
|
|
3158
3254
|
relay: relayUrl,
|
|
3255
|
+
...fallbackRelays.length > 0 ? { fallbackRelays } : {},
|
|
3159
3256
|
room: crypto.randomUUID(),
|
|
3160
3257
|
publicKey: bytesToHex2(bridgePublicKey),
|
|
3161
3258
|
expiresAt: Date.now() + QR_EXPIRY_MS
|
|
3162
3259
|
};
|
|
3163
3260
|
}
|
|
3261
|
+
function normalizedRelayUrls(urls, primaryRelayUrl) {
|
|
3262
|
+
const seen = new Set([primaryRelayUrl.trim()]);
|
|
3263
|
+
const normalized = [];
|
|
3264
|
+
for (const url of urls) {
|
|
3265
|
+
const trimmed = url.trim();
|
|
3266
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
3267
|
+
continue;
|
|
3268
|
+
}
|
|
3269
|
+
seen.add(trimmed);
|
|
3270
|
+
normalized.push(trimmed);
|
|
3271
|
+
}
|
|
3272
|
+
return normalized;
|
|
3273
|
+
}
|
|
3164
3274
|
function bytesToHex2(bytes) {
|
|
3165
3275
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
3166
3276
|
}
|
|
@@ -3394,7 +3504,7 @@ function writeJsonAtomically(filePath, value) {
|
|
|
3394
3504
|
}
|
|
3395
3505
|
|
|
3396
3506
|
// ../../apps/desktop/src/core/pairing/runtime/runtime.ts
|
|
3397
|
-
import { homedir as
|
|
3507
|
+
import { homedir as homedir19 } from "os";
|
|
3398
3508
|
// ../agent-sessions/src/protocol/adapter.ts
|
|
3399
3509
|
class BaseAdapter {
|
|
3400
3510
|
config;
|
|
@@ -4026,6 +4136,15 @@ function stringifyUnknown(value) {
|
|
|
4026
4136
|
return String(value);
|
|
4027
4137
|
}
|
|
4028
4138
|
}
|
|
4139
|
+
function isRecord(value) {
|
|
4140
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
4141
|
+
}
|
|
4142
|
+
function maybeString(value) {
|
|
4143
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
4144
|
+
}
|
|
4145
|
+
function maybeNumber(value) {
|
|
4146
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
4147
|
+
}
|
|
4029
4148
|
function renderToolResultContent(content) {
|
|
4030
4149
|
if (typeof content === "string") {
|
|
4031
4150
|
return content;
|
|
@@ -4081,6 +4200,7 @@ class ClaudeCodeHistoryParser {
|
|
|
4081
4200
|
blockById = new Map;
|
|
4082
4201
|
activeStreamBlocks = new Map;
|
|
4083
4202
|
sawStreamTextThisTurn = false;
|
|
4203
|
+
assistantUsageByMessageId = new Map;
|
|
4084
4204
|
constructor(session, baseTimestampMs) {
|
|
4085
4205
|
this.session = session;
|
|
4086
4206
|
this.baseTimestampMs = baseTimestampMs;
|
|
@@ -4090,6 +4210,7 @@ class ClaudeCodeHistoryParser {
|
|
|
4090
4210
|
let parsedLineCount = 0;
|
|
4091
4211
|
let skippedLineCount = 0;
|
|
4092
4212
|
let lineCount = 0;
|
|
4213
|
+
let lastCapturedAt = this.baseTimestampMs;
|
|
4093
4214
|
for (let index = 0;index < lines.length; index += 1) {
|
|
4094
4215
|
const rawLine = lines[index];
|
|
4095
4216
|
const trimmed = rawLine.trim();
|
|
@@ -4110,12 +4231,19 @@ class ClaudeCodeHistoryParser {
|
|
|
4110
4231
|
continue;
|
|
4111
4232
|
}
|
|
4112
4233
|
const capturedAt = extractRecordTimestamp(record) ?? this.baseTimestampMs + index;
|
|
4234
|
+
lastCapturedAt = capturedAt;
|
|
4113
4235
|
if (this.handleRecord(record, capturedAt)) {
|
|
4114
4236
|
parsedLineCount += 1;
|
|
4115
4237
|
} else {
|
|
4116
4238
|
skippedLineCount += 1;
|
|
4117
4239
|
}
|
|
4118
4240
|
}
|
|
4241
|
+
if (this.persistObserveUsageMetadata()) {
|
|
4242
|
+
this.emitEvent(lastCapturedAt, {
|
|
4243
|
+
event: "session:update",
|
|
4244
|
+
session: { ...this.session }
|
|
4245
|
+
});
|
|
4246
|
+
}
|
|
4119
4247
|
return {
|
|
4120
4248
|
events: this.events,
|
|
4121
4249
|
lineCount,
|
|
@@ -4124,6 +4252,7 @@ class ClaudeCodeHistoryParser {
|
|
|
4124
4252
|
};
|
|
4125
4253
|
}
|
|
4126
4254
|
handleRecord(record, capturedAt) {
|
|
4255
|
+
this.captureRecordMetadata(record);
|
|
4127
4256
|
const type = typeof record.type === "string" ? record.type : null;
|
|
4128
4257
|
if (!type) {
|
|
4129
4258
|
return false;
|
|
@@ -4133,7 +4262,7 @@ class ClaudeCodeHistoryParser {
|
|
|
4133
4262
|
this.handleSystem(record, capturedAt);
|
|
4134
4263
|
return true;
|
|
4135
4264
|
case "user":
|
|
4136
|
-
this.
|
|
4265
|
+
this.handleUser(record, capturedAt);
|
|
4137
4266
|
return true;
|
|
4138
4267
|
case "assistant":
|
|
4139
4268
|
this.handleAssistant(record, capturedAt);
|
|
@@ -4157,6 +4286,130 @@ class ClaudeCodeHistoryParser {
|
|
|
4157
4286
|
return false;
|
|
4158
4287
|
}
|
|
4159
4288
|
}
|
|
4289
|
+
captureRecordMetadata(record) {
|
|
4290
|
+
const runtime = this.ensureObserveMetaRecord("observeRuntime");
|
|
4291
|
+
this.assignObserveString(runtime, "entrypoint", record.entrypoint);
|
|
4292
|
+
this.assignObserveString(runtime, "cliVersion", record.version);
|
|
4293
|
+
this.assignObserveString(runtime, "gitBranch", record.gitBranch);
|
|
4294
|
+
this.assignObserveString(runtime, "permissionMode", record.permissionMode);
|
|
4295
|
+
this.assignObserveString(runtime, "userType", record.userType);
|
|
4296
|
+
const recordCwd = maybeString(record.cwd);
|
|
4297
|
+
if (recordCwd && !this.session.cwd) {
|
|
4298
|
+
this.session.cwd = recordCwd;
|
|
4299
|
+
}
|
|
4300
|
+
const message = isRecord(record.message) ? record.message : null;
|
|
4301
|
+
const model = maybeString(message?.model);
|
|
4302
|
+
if (model && !this.session.model) {
|
|
4303
|
+
this.session.model = model;
|
|
4304
|
+
}
|
|
4305
|
+
const usage = this.readClaudeUsageEntry(record);
|
|
4306
|
+
if (!usage) {
|
|
4307
|
+
return;
|
|
4308
|
+
}
|
|
4309
|
+
const messageId = maybeString(message?.id) ?? maybeString(record.requestId) ?? maybeString(record.uuid);
|
|
4310
|
+
if (!messageId) {
|
|
4311
|
+
return;
|
|
4312
|
+
}
|
|
4313
|
+
this.assistantUsageByMessageId.set(messageId, usage);
|
|
4314
|
+
}
|
|
4315
|
+
readClaudeUsageEntry(record) {
|
|
4316
|
+
const type = maybeString(record.type);
|
|
4317
|
+
const message = isRecord(record.message) ? record.message : null;
|
|
4318
|
+
const role = maybeString(message?.role);
|
|
4319
|
+
if (type !== "assistant" && role !== "assistant") {
|
|
4320
|
+
return null;
|
|
4321
|
+
}
|
|
4322
|
+
const usage = isRecord(message?.usage) ? message.usage : null;
|
|
4323
|
+
const serverToolUse = isRecord(usage?.server_tool_use) ? usage.server_tool_use : null;
|
|
4324
|
+
const entry = {
|
|
4325
|
+
inputTokens: maybeNumber(usage?.input_tokens) ?? 0,
|
|
4326
|
+
outputTokens: maybeNumber(usage?.output_tokens) ?? 0,
|
|
4327
|
+
cacheReadInputTokens: maybeNumber(usage?.cache_read_input_tokens) ?? 0,
|
|
4328
|
+
cacheCreationInputTokens: maybeNumber(usage?.cache_creation_input_tokens) ?? 0,
|
|
4329
|
+
webSearchRequests: maybeNumber(serverToolUse?.web_search_requests) ?? 0,
|
|
4330
|
+
webFetchRequests: maybeNumber(serverToolUse?.web_fetch_requests) ?? 0,
|
|
4331
|
+
...maybeString(message?.service_tier) ? { serviceTier: maybeString(message?.service_tier) } : {},
|
|
4332
|
+
...maybeString(message?.speed) ? { speed: maybeString(message?.speed) } : {}
|
|
4333
|
+
};
|
|
4334
|
+
const hasUsage = entry.inputTokens > 0 || entry.outputTokens > 0 || entry.cacheReadInputTokens > 0 || entry.cacheCreationInputTokens > 0 || entry.webSearchRequests > 0 || entry.webFetchRequests > 0 || Boolean(entry.serviceTier) || Boolean(entry.speed);
|
|
4335
|
+
return hasUsage ? entry : null;
|
|
4336
|
+
}
|
|
4337
|
+
persistObserveUsageMetadata() {
|
|
4338
|
+
if (this.assistantUsageByMessageId.size === 0) {
|
|
4339
|
+
return false;
|
|
4340
|
+
}
|
|
4341
|
+
const usage = this.ensureObserveMetaRecord("observeUsage");
|
|
4342
|
+
let inputTokens = 0;
|
|
4343
|
+
let outputTokens = 0;
|
|
4344
|
+
let cacheReadInputTokens = 0;
|
|
4345
|
+
let cacheCreationInputTokens = 0;
|
|
4346
|
+
let webSearchRequests = 0;
|
|
4347
|
+
let webFetchRequests = 0;
|
|
4348
|
+
let serviceTier;
|
|
4349
|
+
let speed;
|
|
4350
|
+
for (const entry of this.assistantUsageByMessageId.values()) {
|
|
4351
|
+
inputTokens += entry.inputTokens;
|
|
4352
|
+
outputTokens += entry.outputTokens;
|
|
4353
|
+
cacheReadInputTokens += entry.cacheReadInputTokens;
|
|
4354
|
+
cacheCreationInputTokens += entry.cacheCreationInputTokens;
|
|
4355
|
+
webSearchRequests += entry.webSearchRequests;
|
|
4356
|
+
webFetchRequests += entry.webFetchRequests;
|
|
4357
|
+
if (entry.serviceTier) {
|
|
4358
|
+
serviceTier = entry.serviceTier;
|
|
4359
|
+
}
|
|
4360
|
+
if (entry.speed) {
|
|
4361
|
+
speed = entry.speed;
|
|
4362
|
+
}
|
|
4363
|
+
}
|
|
4364
|
+
let changed = false;
|
|
4365
|
+
const assignNumber = (key, value) => {
|
|
4366
|
+
if (usage[key] !== value) {
|
|
4367
|
+
usage[key] = value;
|
|
4368
|
+
changed = true;
|
|
4369
|
+
}
|
|
4370
|
+
};
|
|
4371
|
+
const assignString = (key, value) => {
|
|
4372
|
+
if (usage[key] !== value) {
|
|
4373
|
+
usage[key] = value;
|
|
4374
|
+
changed = true;
|
|
4375
|
+
}
|
|
4376
|
+
};
|
|
4377
|
+
assignNumber("assistantMessages", this.assistantUsageByMessageId.size);
|
|
4378
|
+
if (inputTokens > 0)
|
|
4379
|
+
assignNumber("inputTokens", inputTokens);
|
|
4380
|
+
if (outputTokens > 0)
|
|
4381
|
+
assignNumber("outputTokens", outputTokens);
|
|
4382
|
+
if (cacheReadInputTokens > 0)
|
|
4383
|
+
assignNumber("cacheReadInputTokens", cacheReadInputTokens);
|
|
4384
|
+
if (cacheCreationInputTokens > 0)
|
|
4385
|
+
assignNumber("cacheCreationInputTokens", cacheCreationInputTokens);
|
|
4386
|
+
if (webSearchRequests > 0)
|
|
4387
|
+
assignNumber("webSearchRequests", webSearchRequests);
|
|
4388
|
+
if (webFetchRequests > 0)
|
|
4389
|
+
assignNumber("webFetchRequests", webFetchRequests);
|
|
4390
|
+
if (serviceTier)
|
|
4391
|
+
assignString("serviceTier", serviceTier);
|
|
4392
|
+
if (speed)
|
|
4393
|
+
assignString("speed", speed);
|
|
4394
|
+
return changed;
|
|
4395
|
+
}
|
|
4396
|
+
ensureObserveMetaRecord(key) {
|
|
4397
|
+
const providerMeta = isRecord(this.session.providerMeta) ? this.session.providerMeta : {};
|
|
4398
|
+
this.session.providerMeta = providerMeta;
|
|
4399
|
+
const existing = providerMeta[key];
|
|
4400
|
+
if (isRecord(existing)) {
|
|
4401
|
+
return existing;
|
|
4402
|
+
}
|
|
4403
|
+
const next = {};
|
|
4404
|
+
providerMeta[key] = next;
|
|
4405
|
+
return next;
|
|
4406
|
+
}
|
|
4407
|
+
assignObserveString(target, key, value) {
|
|
4408
|
+
const next = maybeString(value);
|
|
4409
|
+
if (next) {
|
|
4410
|
+
target[key] = next;
|
|
4411
|
+
}
|
|
4412
|
+
}
|
|
4160
4413
|
handleSystem(record, capturedAt) {
|
|
4161
4414
|
if (record.subtype !== "init") {
|
|
4162
4415
|
return;
|
|
@@ -4186,19 +4439,41 @@ class ClaudeCodeHistoryParser {
|
|
|
4186
4439
|
});
|
|
4187
4440
|
}
|
|
4188
4441
|
}
|
|
4442
|
+
handleUser(record, capturedAt) {
|
|
4443
|
+
const message = record.message && typeof record.message === "object" ? record.message : null;
|
|
4444
|
+
const content = message?.content;
|
|
4445
|
+
if (Array.isArray(content) && content.length > 0) {
|
|
4446
|
+
const toolResults = content.filter((entry) => {
|
|
4447
|
+
return !!entry && typeof entry === "object" && !Array.isArray(entry) && entry.type === "tool_result";
|
|
4448
|
+
});
|
|
4449
|
+
if (toolResults.length === content.length) {
|
|
4450
|
+
for (const toolResult of toolResults) {
|
|
4451
|
+
this.handleToolResult({
|
|
4452
|
+
...toolResult,
|
|
4453
|
+
tool_use_id: typeof toolResult.tool_use_id === "string" ? toolResult.tool_use_id : toolResult.id,
|
|
4454
|
+
is_error: toolResult.is_error === true
|
|
4455
|
+
}, capturedAt);
|
|
4456
|
+
}
|
|
4457
|
+
return;
|
|
4458
|
+
}
|
|
4459
|
+
}
|
|
4460
|
+
this.startTurn(capturedAt);
|
|
4461
|
+
}
|
|
4189
4462
|
handleAssistant(record, capturedAt) {
|
|
4190
4463
|
const turn = this.ensureTurn(capturedAt);
|
|
4191
|
-
if (this.sawStreamTextThisTurn) {
|
|
4192
|
-
return;
|
|
4193
|
-
}
|
|
4194
4464
|
const content = record.message && typeof record.message === "object" ? record.message.content : record.content;
|
|
4195
4465
|
if (!Array.isArray(content)) {
|
|
4466
|
+
this.maybeEndTurnFromAssistant(record, capturedAt);
|
|
4196
4467
|
return;
|
|
4197
4468
|
}
|
|
4469
|
+
const skipTextBlocks = this.sawStreamTextThisTurn;
|
|
4198
4470
|
for (const part of content) {
|
|
4199
4471
|
const contentPart = part;
|
|
4200
4472
|
const contentType = typeof contentPart.type === "string" ? contentPart.type : "";
|
|
4201
4473
|
if (contentType === "thinking" || contentType === "reasoning") {
|
|
4474
|
+
if (skipTextBlocks) {
|
|
4475
|
+
continue;
|
|
4476
|
+
}
|
|
4202
4477
|
const block = this.startBlock(turn, capturedAt, {
|
|
4203
4478
|
type: "reasoning",
|
|
4204
4479
|
text: typeof contentPart.thinking === "string" ? contentPart.thinking : typeof contentPart.text === "string" ? contentPart.text : "",
|
|
@@ -4206,14 +4481,20 @@ class ClaudeCodeHistoryParser {
|
|
|
4206
4481
|
});
|
|
4207
4482
|
this.emitBlockEnd(capturedAt, turn, block, "completed");
|
|
4208
4483
|
} else if (contentType === "text") {
|
|
4484
|
+
if (skipTextBlocks) {
|
|
4485
|
+
continue;
|
|
4486
|
+
}
|
|
4209
4487
|
const block = this.startBlock(turn, capturedAt, {
|
|
4210
4488
|
type: "text",
|
|
4211
4489
|
text: typeof contentPart.text === "string" ? contentPart.text : "",
|
|
4212
4490
|
status: "completed"
|
|
4213
4491
|
});
|
|
4214
4492
|
this.emitBlockEnd(capturedAt, turn, block, "completed");
|
|
4493
|
+
} else if (contentType === "tool_use") {
|
|
4494
|
+
this.handleToolUse(contentPart, capturedAt);
|
|
4215
4495
|
}
|
|
4216
4496
|
}
|
|
4497
|
+
this.maybeEndTurnFromAssistant(record, capturedAt);
|
|
4217
4498
|
}
|
|
4218
4499
|
handleStreamEvent(record, capturedAt) {
|
|
4219
4500
|
const turn = this.ensureTurn(capturedAt);
|
|
@@ -4435,6 +4716,12 @@ class ClaudeCodeHistoryParser {
|
|
|
4435
4716
|
this.emitError(turn, capturedAt, message);
|
|
4436
4717
|
this.endTurn("failed", capturedAt);
|
|
4437
4718
|
}
|
|
4719
|
+
maybeEndTurnFromAssistant(record, capturedAt) {
|
|
4720
|
+
const stopReason = record.message && typeof record.message === "object" ? record.message.stop_reason : record.stop_reason;
|
|
4721
|
+
if (stopReason === "end_turn") {
|
|
4722
|
+
this.endTurn("completed", capturedAt);
|
|
4723
|
+
}
|
|
4724
|
+
}
|
|
4438
4725
|
startTurn(capturedAt) {
|
|
4439
4726
|
if (this.currentTurn) {
|
|
4440
4727
|
this.endTurn("stopped", capturedAt);
|
|
@@ -8539,11 +8826,11 @@ function formatTimestamp(value) {
|
|
|
8539
8826
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/server.ts
|
|
8540
8827
|
import { readdirSync as readdirSync3, readFileSync as readFileSync9, realpathSync, statSync as statSync3 } from "fs";
|
|
8541
8828
|
import { execSync as execSync3 } from "child_process";
|
|
8542
|
-
import { basename as
|
|
8543
|
-
import { homedir as
|
|
8829
|
+
import { basename as basename7, isAbsolute as isAbsolute3, join as join18, relative as relative2 } from "path";
|
|
8830
|
+
import { homedir as homedir16 } from "os";
|
|
8544
8831
|
|
|
8545
8832
|
// ../../apps/desktop/src/core/mobile/service.ts
|
|
8546
|
-
import { basename as
|
|
8833
|
+
import { basename as basename6, resolve as resolve7 } from "path";
|
|
8547
8834
|
|
|
8548
8835
|
// ../runtime/src/harness-catalog.ts
|
|
8549
8836
|
import { execFileSync } from "child_process";
|
|
@@ -10154,149 +10441,6 @@ function diagnoseAgentIdentity(identity, candidates) {
|
|
|
10154
10441
|
var parseAgentSelector = parseAgentIdentity;
|
|
10155
10442
|
var formatAgentSelector = formatAgentIdentity;
|
|
10156
10443
|
var resolveAgentSelector = resolveAgentIdentity;
|
|
10157
|
-
// ../protocol/dist/scout-agent-card.js
|
|
10158
|
-
function buildScoutReturnAddress(input) {
|
|
10159
|
-
const next = {
|
|
10160
|
-
actorId: input.actorId,
|
|
10161
|
-
handle: input.handle.trim()
|
|
10162
|
-
};
|
|
10163
|
-
if (input.displayName?.trim()) {
|
|
10164
|
-
next.displayName = input.displayName.trim();
|
|
10165
|
-
}
|
|
10166
|
-
if (input.selector?.trim()) {
|
|
10167
|
-
next.selector = input.selector.trim();
|
|
10168
|
-
}
|
|
10169
|
-
if (input.defaultSelector?.trim()) {
|
|
10170
|
-
next.defaultSelector = input.defaultSelector.trim();
|
|
10171
|
-
}
|
|
10172
|
-
if (input.conversationId?.trim()) {
|
|
10173
|
-
next.conversationId = input.conversationId.trim();
|
|
10174
|
-
}
|
|
10175
|
-
if (input.replyToMessageId?.trim()) {
|
|
10176
|
-
next.replyToMessageId = input.replyToMessageId.trim();
|
|
10177
|
-
}
|
|
10178
|
-
if (input.nodeId?.trim()) {
|
|
10179
|
-
next.nodeId = input.nodeId.trim();
|
|
10180
|
-
}
|
|
10181
|
-
if (input.projectRoot?.trim()) {
|
|
10182
|
-
next.projectRoot = input.projectRoot.trim();
|
|
10183
|
-
}
|
|
10184
|
-
if (input.sessionId?.trim()) {
|
|
10185
|
-
next.sessionId = input.sessionId.trim();
|
|
10186
|
-
}
|
|
10187
|
-
if (input.metadata && Object.keys(input.metadata).length > 0) {
|
|
10188
|
-
next.metadata = input.metadata;
|
|
10189
|
-
}
|
|
10190
|
-
return next;
|
|
10191
|
-
}
|
|
10192
|
-
// ../protocol/dist/collaboration.js
|
|
10193
|
-
function isQuestionTerminalState(state) {
|
|
10194
|
-
return state === "closed" || state === "declined";
|
|
10195
|
-
}
|
|
10196
|
-
function isWorkItemTerminalState(state) {
|
|
10197
|
-
return state === "done" || state === "cancelled";
|
|
10198
|
-
}
|
|
10199
|
-
function collaborationRequiresNextMoveOwner(record) {
|
|
10200
|
-
if (record.kind === "question") {
|
|
10201
|
-
return !isQuestionTerminalState(record.state);
|
|
10202
|
-
}
|
|
10203
|
-
return !isWorkItemTerminalState(record.state);
|
|
10204
|
-
}
|
|
10205
|
-
function collaborationRequiresOwner(record) {
|
|
10206
|
-
return record.kind === "work_item" && !isWorkItemTerminalState(record.state);
|
|
10207
|
-
}
|
|
10208
|
-
function collaborationRequiresWaitingOn(record) {
|
|
10209
|
-
return record.kind === "work_item" && record.state === "waiting";
|
|
10210
|
-
}
|
|
10211
|
-
function collaborationRequiresAcceptance(record) {
|
|
10212
|
-
if (record.acceptanceState === "none") {
|
|
10213
|
-
return false;
|
|
10214
|
-
}
|
|
10215
|
-
if (record.kind === "question") {
|
|
10216
|
-
return Boolean(record.askedById && record.askedOfId);
|
|
10217
|
-
}
|
|
10218
|
-
return Boolean(record.requestedById);
|
|
10219
|
-
}
|
|
10220
|
-
function validateCollaborationRecord(record) {
|
|
10221
|
-
const errors = [];
|
|
10222
|
-
if (!record.id.trim()) {
|
|
10223
|
-
errors.push("collaboration record id is required");
|
|
10224
|
-
}
|
|
10225
|
-
if (!record.title.trim()) {
|
|
10226
|
-
errors.push("collaboration title is required");
|
|
10227
|
-
}
|
|
10228
|
-
if (!record.createdById.trim()) {
|
|
10229
|
-
errors.push("createdById is required");
|
|
10230
|
-
}
|
|
10231
|
-
if (record.parentId && record.parentId === record.id) {
|
|
10232
|
-
errors.push("parentId cannot reference the record itself");
|
|
10233
|
-
}
|
|
10234
|
-
if (record.createdAt > record.updatedAt) {
|
|
10235
|
-
errors.push("updatedAt must be greater than or equal to createdAt");
|
|
10236
|
-
}
|
|
10237
|
-
if (collaborationRequiresOwner(record) && !record.ownerId) {
|
|
10238
|
-
errors.push("non-terminal work items require ownerId");
|
|
10239
|
-
}
|
|
10240
|
-
if (collaborationRequiresNextMoveOwner(record) && !record.nextMoveOwnerId) {
|
|
10241
|
-
errors.push("non-terminal collaboration records require nextMoveOwnerId");
|
|
10242
|
-
}
|
|
10243
|
-
if (record.kind === "work_item" && collaborationRequiresWaitingOn(record) && !record.waitingOn) {
|
|
10244
|
-
errors.push("waiting work items require waitingOn");
|
|
10245
|
-
}
|
|
10246
|
-
if (record.kind === "question") {
|
|
10247
|
-
if (record.spawnedWorkItemId && record.spawnedWorkItemId === record.id) {
|
|
10248
|
-
errors.push("question spawnedWorkItemId cannot reference the question itself");
|
|
10249
|
-
}
|
|
10250
|
-
} else if (record.waitingOn?.targetId && record.waitingOn.targetId === record.id) {
|
|
10251
|
-
errors.push("waitingOn.targetId cannot reference the work item itself");
|
|
10252
|
-
}
|
|
10253
|
-
if (record.acceptanceState !== "none" && !collaborationRequiresAcceptance(record)) {
|
|
10254
|
-
errors.push("acceptanceState requires the corresponding requester and reviewer identities");
|
|
10255
|
-
}
|
|
10256
|
-
return errors;
|
|
10257
|
-
}
|
|
10258
|
-
function assertValidCollaborationRecord(record) {
|
|
10259
|
-
const errors = validateCollaborationRecord(record);
|
|
10260
|
-
if (errors.length > 0) {
|
|
10261
|
-
throw new Error(errors.join("; "));
|
|
10262
|
-
}
|
|
10263
|
-
}
|
|
10264
|
-
function validateCollaborationEvent(event, record) {
|
|
10265
|
-
const errors = [];
|
|
10266
|
-
if (!event.id.trim()) {
|
|
10267
|
-
errors.push("collaboration event id is required");
|
|
10268
|
-
}
|
|
10269
|
-
if (!event.recordId.trim()) {
|
|
10270
|
-
errors.push("collaboration event recordId is required");
|
|
10271
|
-
}
|
|
10272
|
-
if (!event.actorId.trim()) {
|
|
10273
|
-
errors.push("collaboration event actorId is required");
|
|
10274
|
-
}
|
|
10275
|
-
if (record) {
|
|
10276
|
-
if (record.id !== event.recordId) {
|
|
10277
|
-
errors.push("collaboration event recordId does not match the target record");
|
|
10278
|
-
}
|
|
10279
|
-
if (record.kind !== event.recordKind) {
|
|
10280
|
-
errors.push("collaboration event recordKind does not match the target record");
|
|
10281
|
-
}
|
|
10282
|
-
}
|
|
10283
|
-
if (event.kind === "answered" && event.recordKind !== "question") {
|
|
10284
|
-
errors.push("answered events only apply to questions");
|
|
10285
|
-
}
|
|
10286
|
-
if (event.kind === "declined" && event.recordKind !== "question") {
|
|
10287
|
-
errors.push("declined events only apply to questions");
|
|
10288
|
-
}
|
|
10289
|
-
if ((event.kind === "waiting" || event.kind === "progressed" || event.kind === "review_requested" || event.kind === "done" || event.kind === "cancelled") && event.recordKind !== "work_item") {
|
|
10290
|
-
errors.push(`${event.kind} events only apply to work items`);
|
|
10291
|
-
}
|
|
10292
|
-
return errors;
|
|
10293
|
-
}
|
|
10294
|
-
function assertValidCollaborationEvent(event, record) {
|
|
10295
|
-
const errors = validateCollaborationEvent(event, record);
|
|
10296
|
-
if (errors.length > 0) {
|
|
10297
|
-
throw new Error(errors.join("; "));
|
|
10298
|
-
}
|
|
10299
|
-
}
|
|
10300
10444
|
// ../runtime/src/user-project-hints.ts
|
|
10301
10445
|
import { readdir, readFile as readFile3, stat } from "fs/promises";
|
|
10302
10446
|
import { homedir as homedir11 } from "os";
|
|
@@ -12347,9 +12491,9 @@ async function ensureRelayAgentConfigured(value, options = {}) {
|
|
|
12347
12491
|
|
|
12348
12492
|
// ../runtime/src/local-agents.ts
|
|
12349
12493
|
import { execFileSync as execFileSync3, execSync as execSync2 } from "child_process";
|
|
12350
|
-
import { existsSync as
|
|
12494
|
+
import { existsSync as existsSync14, readFileSync as readFileSync8 } from "fs";
|
|
12351
12495
|
import { mkdir as mkdir6, rm as rm5, stat as stat3, writeFile as writeFile6 } from "fs/promises";
|
|
12352
|
-
import { basename as
|
|
12496
|
+
import { basename as basename5, dirname as dirname7, join as join16, resolve as resolve6 } from "path";
|
|
12353
12497
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
12354
12498
|
|
|
12355
12499
|
// ../runtime/src/claude-stream-json.ts
|
|
@@ -13693,10 +13837,116 @@ function buildCollaborationContractPrompt(agentId) {
|
|
|
13693
13837
|
|
|
13694
13838
|
// ../runtime/src/broker-service.ts
|
|
13695
13839
|
import { spawnSync } from "child_process";
|
|
13696
|
-
import { existsSync as
|
|
13840
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync7, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
|
|
13841
|
+
import { homedir as homedir14 } from "os";
|
|
13842
|
+
import { dirname as dirname6, join as join15, resolve as resolve5 } from "path";
|
|
13843
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
13844
|
+
|
|
13845
|
+
// ../runtime/src/tool-resolution.ts
|
|
13846
|
+
import { accessSync as accessSync2, constants as constants4, existsSync as existsSync12 } from "fs";
|
|
13697
13847
|
import { homedir as homedir13 } from "os";
|
|
13698
13848
|
import { basename as basename3, dirname as dirname5, join as join14, resolve as resolve4 } from "path";
|
|
13699
|
-
|
|
13849
|
+
var DEFAULT_COMMON_EXECUTABLE_DIRECTORIES = [
|
|
13850
|
+
join14(homedir13(), ".bun", "bin"),
|
|
13851
|
+
"/opt/homebrew/bin",
|
|
13852
|
+
"/usr/local/bin"
|
|
13853
|
+
];
|
|
13854
|
+
function expandHomePath3(value, env = process.env) {
|
|
13855
|
+
const home = env.HOME ?? homedir13();
|
|
13856
|
+
if (value === "~") {
|
|
13857
|
+
return home;
|
|
13858
|
+
}
|
|
13859
|
+
if (value.startsWith("~/")) {
|
|
13860
|
+
return join14(home, value.slice(2));
|
|
13861
|
+
}
|
|
13862
|
+
return value;
|
|
13863
|
+
}
|
|
13864
|
+
function isExecutablePath(candidate) {
|
|
13865
|
+
if (!candidate) {
|
|
13866
|
+
return false;
|
|
13867
|
+
}
|
|
13868
|
+
try {
|
|
13869
|
+
accessSync2(candidate, constants4.X_OK);
|
|
13870
|
+
return true;
|
|
13871
|
+
} catch {
|
|
13872
|
+
return false;
|
|
13873
|
+
}
|
|
13874
|
+
}
|
|
13875
|
+
function splitPathEntries(env = process.env) {
|
|
13876
|
+
const separator = process.platform === "win32" ? ";" : ":";
|
|
13877
|
+
return (env.PATH ?? "").split(separator).filter(Boolean);
|
|
13878
|
+
}
|
|
13879
|
+
function dedupeDirectories(values, env) {
|
|
13880
|
+
const seen = new Set;
|
|
13881
|
+
const resolvedEntries = [];
|
|
13882
|
+
for (const value of values) {
|
|
13883
|
+
const normalized = resolve4(expandHomePath3(value, env));
|
|
13884
|
+
if (seen.has(normalized)) {
|
|
13885
|
+
continue;
|
|
13886
|
+
}
|
|
13887
|
+
seen.add(normalized);
|
|
13888
|
+
resolvedEntries.push(normalized);
|
|
13889
|
+
}
|
|
13890
|
+
return resolvedEntries;
|
|
13891
|
+
}
|
|
13892
|
+
function resolveExecutableFromSearch(options) {
|
|
13893
|
+
const env = options.env ?? process.env;
|
|
13894
|
+
const envKeys = options.envKeys ?? [];
|
|
13895
|
+
for (const envKey of envKeys) {
|
|
13896
|
+
const explicit = env[envKey]?.trim();
|
|
13897
|
+
if (!explicit) {
|
|
13898
|
+
continue;
|
|
13899
|
+
}
|
|
13900
|
+
const expanded = expandHomePath3(explicit, env);
|
|
13901
|
+
if (isExecutablePath(expanded)) {
|
|
13902
|
+
return { path: resolve4(expanded), source: "env" };
|
|
13903
|
+
}
|
|
13904
|
+
const foundOnPath = findExecutableOnSearchPath(explicit, env);
|
|
13905
|
+
if (foundOnPath) {
|
|
13906
|
+
return { path: foundOnPath.path, source: "env" };
|
|
13907
|
+
}
|
|
13908
|
+
}
|
|
13909
|
+
const commonDirectories = dedupeDirectories([...options.commonDirectories ?? DEFAULT_COMMON_EXECUTABLE_DIRECTORIES], env);
|
|
13910
|
+
const searchDirectories = dedupeDirectories([
|
|
13911
|
+
...splitPathEntries(env),
|
|
13912
|
+
...options.extraDirectories ?? [],
|
|
13913
|
+
...commonDirectories
|
|
13914
|
+
], env);
|
|
13915
|
+
for (const directory of searchDirectories) {
|
|
13916
|
+
for (const name of options.names) {
|
|
13917
|
+
const candidate = join14(directory, name);
|
|
13918
|
+
if (isExecutablePath(candidate)) {
|
|
13919
|
+
return {
|
|
13920
|
+
path: candidate,
|
|
13921
|
+
source: commonDirectories.includes(directory) ? "common-path" : "path"
|
|
13922
|
+
};
|
|
13923
|
+
}
|
|
13924
|
+
}
|
|
13925
|
+
}
|
|
13926
|
+
return null;
|
|
13927
|
+
}
|
|
13928
|
+
function resolveBunExecutable2(env = process.env) {
|
|
13929
|
+
return resolveExecutableFromSearch({
|
|
13930
|
+
env,
|
|
13931
|
+
envKeys: ["OPENSCOUT_BUN_BIN", "SCOUT_BUN_BIN", "BUN_BIN"],
|
|
13932
|
+
names: ["bun"]
|
|
13933
|
+
});
|
|
13934
|
+
}
|
|
13935
|
+
function findExecutableOnSearchPath(name, env) {
|
|
13936
|
+
const searchDirectories = dedupeDirectories([
|
|
13937
|
+
...splitPathEntries(env),
|
|
13938
|
+
...DEFAULT_COMMON_EXECUTABLE_DIRECTORIES
|
|
13939
|
+
], env);
|
|
13940
|
+
for (const directory of searchDirectories) {
|
|
13941
|
+
const candidate = join14(directory, name);
|
|
13942
|
+
if (isExecutablePath(candidate)) {
|
|
13943
|
+
return { path: candidate, source: "path" };
|
|
13944
|
+
}
|
|
13945
|
+
}
|
|
13946
|
+
return null;
|
|
13947
|
+
}
|
|
13948
|
+
|
|
13949
|
+
// ../runtime/src/broker-service.ts
|
|
13700
13950
|
function isTmpPath(p) {
|
|
13701
13951
|
return /^\/(?:private\/)?tmp\//.test(p);
|
|
13702
13952
|
}
|
|
@@ -13735,17 +13985,17 @@ function runtimePackageDir() {
|
|
|
13735
13985
|
const fromCwd = findWorkspaceRuntimeDir(process.cwd());
|
|
13736
13986
|
if (fromCwd)
|
|
13737
13987
|
return fromCwd;
|
|
13738
|
-
const moduleDir =
|
|
13739
|
-
return
|
|
13988
|
+
const moduleDir = dirname6(fileURLToPath4(import.meta.url));
|
|
13989
|
+
return resolve5(moduleDir, "..");
|
|
13740
13990
|
}
|
|
13741
13991
|
function isInstalledRuntimePackageDir(candidate) {
|
|
13742
|
-
return
|
|
13992
|
+
return existsSync13(join15(candidate, "package.json")) && existsSync13(join15(candidate, "bin", "openscout-runtime.mjs"));
|
|
13743
13993
|
}
|
|
13744
13994
|
function findGlobalRuntimeDir() {
|
|
13745
13995
|
const candidates = [
|
|
13746
|
-
|
|
13747
|
-
|
|
13748
|
-
|
|
13996
|
+
join15(homedir14(), ".bun", "node_modules", "@openscout", "runtime"),
|
|
13997
|
+
join15(homedir14(), ".bun", "install", "global", "node_modules", "@openscout", "runtime"),
|
|
13998
|
+
join15(homedir14(), ".bun", "install", "global", "node_modules", "@openscout", "scout", "node_modules", "@openscout", "runtime")
|
|
13749
13999
|
];
|
|
13750
14000
|
for (const c of candidates) {
|
|
13751
14001
|
if (isInstalledRuntimePackageDir(c))
|
|
@@ -13755,11 +14005,11 @@ function findGlobalRuntimeDir() {
|
|
|
13755
14005
|
const result = spawnSync("which", ["scout"], { encoding: "utf8", timeout: 3000 });
|
|
13756
14006
|
const scoutBin = result.stdout?.trim();
|
|
13757
14007
|
if (scoutBin) {
|
|
13758
|
-
const scoutPkg =
|
|
13759
|
-
const nested =
|
|
14008
|
+
const scoutPkg = resolve5(scoutBin, "..", "..");
|
|
14009
|
+
const nested = join15(scoutPkg, "node_modules", "@openscout", "runtime");
|
|
13760
14010
|
if (isInstalledRuntimePackageDir(nested))
|
|
13761
14011
|
return nested;
|
|
13762
|
-
const sibling =
|
|
14012
|
+
const sibling = resolve5(scoutPkg, "..", "runtime");
|
|
13763
14013
|
if (isInstalledRuntimePackageDir(sibling))
|
|
13764
14014
|
return sibling;
|
|
13765
14015
|
}
|
|
@@ -13767,38 +14017,24 @@ function findGlobalRuntimeDir() {
|
|
|
13767
14017
|
return null;
|
|
13768
14018
|
}
|
|
13769
14019
|
function findWorkspaceRuntimeDir(startDir) {
|
|
13770
|
-
let current =
|
|
14020
|
+
let current = resolve5(startDir);
|
|
13771
14021
|
while (true) {
|
|
13772
|
-
const candidate =
|
|
13773
|
-
if (
|
|
14022
|
+
const candidate = join15(current, "packages", "runtime");
|
|
14023
|
+
if (existsSync13(join15(candidate, "package.json")) && existsSync13(join15(candidate, "src"))) {
|
|
13774
14024
|
return candidate;
|
|
13775
14025
|
}
|
|
13776
|
-
const parent =
|
|
14026
|
+
const parent = dirname6(current);
|
|
13777
14027
|
if (parent === current)
|
|
13778
14028
|
return null;
|
|
13779
14029
|
current = parent;
|
|
13780
14030
|
}
|
|
13781
14031
|
}
|
|
13782
|
-
function
|
|
13783
|
-
const
|
|
13784
|
-
if (
|
|
13785
|
-
return
|
|
13786
|
-
}
|
|
13787
|
-
if (basename3(process.execPath).startsWith("bun") && existsSync12(process.execPath)) {
|
|
13788
|
-
return process.execPath;
|
|
13789
|
-
}
|
|
13790
|
-
const pathEntries = (process.env.PATH ?? "").split(":").filter(Boolean);
|
|
13791
|
-
for (const entry of pathEntries) {
|
|
13792
|
-
const candidate = join14(entry, "bun");
|
|
13793
|
-
if (existsSync12(candidate)) {
|
|
13794
|
-
return candidate;
|
|
13795
|
-
}
|
|
13796
|
-
}
|
|
13797
|
-
const homeBun = join14(homedir13(), ".bun", "bin", "bun");
|
|
13798
|
-
if (existsSync12(homeBun)) {
|
|
13799
|
-
return homeBun;
|
|
14032
|
+
function resolveBunExecutable3() {
|
|
14033
|
+
const bun = resolveBunExecutable2(process.env);
|
|
14034
|
+
if (bun) {
|
|
14035
|
+
return bun.path;
|
|
13800
14036
|
}
|
|
13801
|
-
|
|
14037
|
+
throw new Error("Unable to locate Bun for broker service management. Install Bun or set OPENSCOUT_BUN_BIN.");
|
|
13802
14038
|
}
|
|
13803
14039
|
function resolveBrokerServiceMode() {
|
|
13804
14040
|
const explicit = (process.env.OPENSCOUT_BROKER_SERVICE_MODE ?? "").trim().toLowerCase();
|
|
@@ -13837,15 +14073,15 @@ function resolveBrokerServiceConfig() {
|
|
|
13837
14073
|
const label = resolveBrokerServiceLabel(mode);
|
|
13838
14074
|
const uid = typeof process.getuid === "function" ? process.getuid() : Number.parseInt(process.env.UID ?? "0", 10);
|
|
13839
14075
|
const supportPaths = resolveOpenScoutSupportPaths();
|
|
13840
|
-
const defaultSupportDir =
|
|
14076
|
+
const defaultSupportDir = join15(homedir14(), "Library", "Application Support", "OpenScout");
|
|
13841
14077
|
const supportDirectory = isTmpPath(supportPaths.supportDirectory) ? defaultSupportDir : supportPaths.supportDirectory;
|
|
13842
|
-
const logsDirectory =
|
|
13843
|
-
const controlHome = isTmpPath(supportPaths.controlHome) ?
|
|
14078
|
+
const logsDirectory = join15(supportDirectory, "logs", "broker");
|
|
14079
|
+
const controlHome = isTmpPath(supportPaths.controlHome) ? join15(homedir14(), ".openscout", "control-plane") : supportPaths.controlHome;
|
|
13844
14080
|
const advertiseScope = resolveAdvertiseScope();
|
|
13845
14081
|
const brokerHost = resolveBrokerHost(advertiseScope);
|
|
13846
14082
|
const brokerPort = Number.parseInt(process.env.OPENSCOUT_BROKER_PORT ?? String(DEFAULT_BROKER_PORT), 10);
|
|
13847
14083
|
const brokerUrl = process.env.OPENSCOUT_BROKER_URL ?? buildDefaultBrokerUrl(brokerHost, brokerPort);
|
|
13848
|
-
const launchAgentPath =
|
|
14084
|
+
const launchAgentPath = join15(homedir14(), "Library", "LaunchAgents", `${label}.plist`);
|
|
13849
14085
|
return {
|
|
13850
14086
|
label,
|
|
13851
14087
|
mode,
|
|
@@ -13855,11 +14091,11 @@ function resolveBrokerServiceConfig() {
|
|
|
13855
14091
|
launchAgentPath,
|
|
13856
14092
|
supportDirectory,
|
|
13857
14093
|
logsDirectory,
|
|
13858
|
-
stdoutLogPath:
|
|
13859
|
-
stderrLogPath:
|
|
14094
|
+
stdoutLogPath: join15(logsDirectory, "stdout.log"),
|
|
14095
|
+
stderrLogPath: join15(logsDirectory, "stderr.log"),
|
|
13860
14096
|
controlHome,
|
|
13861
14097
|
runtimePackageDir: runtimePackageDir(),
|
|
13862
|
-
bunExecutable:
|
|
14098
|
+
bunExecutable: resolveBunExecutable3(),
|
|
13863
14099
|
brokerHost,
|
|
13864
14100
|
brokerPort,
|
|
13865
14101
|
brokerUrl,
|
|
@@ -13876,7 +14112,7 @@ function renderLaunchAgentPlist(config) {
|
|
|
13876
14112
|
OPENSCOUT_BROKER_SERVICE_MODE: config.mode,
|
|
13877
14113
|
OPENSCOUT_BROKER_SERVICE_LABEL: config.label,
|
|
13878
14114
|
OPENSCOUT_ADVERTISE_SCOPE: config.advertiseScope,
|
|
13879
|
-
HOME:
|
|
14115
|
+
HOME: homedir14(),
|
|
13880
14116
|
PATH: launchPath,
|
|
13881
14117
|
...collectOptionalEnvVars([
|
|
13882
14118
|
"OPENSCOUT_MESH_ID",
|
|
@@ -13902,7 +14138,7 @@ function renderLaunchAgentPlist(config) {
|
|
|
13902
14138
|
<key>ProgramArguments</key>
|
|
13903
14139
|
<array>
|
|
13904
14140
|
<string>${xmlEscape(config.bunExecutable)}</string>
|
|
13905
|
-
<string>${xmlEscape(
|
|
14141
|
+
<string>${xmlEscape(join15(config.runtimePackageDir, "bin", "openscout-runtime.mjs"))}</string>
|
|
13906
14142
|
<string>broker</string>
|
|
13907
14143
|
</array>
|
|
13908
14144
|
<key>WorkingDirectory</key>
|
|
@@ -13937,7 +14173,7 @@ function collectOptionalEnvVars(keys) {
|
|
|
13937
14173
|
}
|
|
13938
14174
|
function resolveLaunchAgentPATH() {
|
|
13939
14175
|
const entries = [
|
|
13940
|
-
|
|
14176
|
+
join15(homedir14(), ".bun", "bin"),
|
|
13941
14177
|
...(process.env.PATH ?? "").split(":").filter(Boolean),
|
|
13942
14178
|
"/opt/homebrew/bin",
|
|
13943
14179
|
"/usr/local/bin",
|
|
@@ -13952,7 +14188,7 @@ function xmlEscape(value) {
|
|
|
13952
14188
|
return value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
13953
14189
|
}
|
|
13954
14190
|
function ensureParentDirectory(filePath) {
|
|
13955
|
-
mkdirSync8(
|
|
14191
|
+
mkdirSync8(dirname6(filePath), { recursive: true });
|
|
13956
14192
|
}
|
|
13957
14193
|
function ensureServiceDirectories(config) {
|
|
13958
14194
|
ensureOpenScoutCleanSlateSync();
|
|
@@ -13985,7 +14221,7 @@ function launchctlPath() {
|
|
|
13985
14221
|
return "/bin/launchctl";
|
|
13986
14222
|
}
|
|
13987
14223
|
function readLogLines(path2) {
|
|
13988
|
-
if (!
|
|
14224
|
+
if (!existsSync13(path2)) {
|
|
13989
14225
|
return [];
|
|
13990
14226
|
}
|
|
13991
14227
|
return readFileSync7(path2, "utf8").split(`
|
|
@@ -14085,7 +14321,7 @@ async function brokerServiceStatus(config = resolveBrokerServiceConfig()) {
|
|
|
14085
14321
|
ensureServiceDirectories(config);
|
|
14086
14322
|
const launchctl = inspectLaunchctl(config);
|
|
14087
14323
|
const health = await fetchHealthSnapshot(config);
|
|
14088
|
-
const installed =
|
|
14324
|
+
const installed = existsSync13(config.launchAgentPath);
|
|
14089
14325
|
const lastLogLine = health.reachable ? readLastLogLine([config.stdoutLogPath, config.stderrLogPath]) : readLastLogLine([config.stderrLogPath, config.stdoutLogPath]);
|
|
14090
14326
|
return {
|
|
14091
14327
|
label: config.label,
|
|
@@ -14128,7 +14364,7 @@ async function startBrokerService(config = resolveBrokerServiceConfig()) {
|
|
|
14128
14364
|
throw new Error(status.lastLogLine ?? status.health.error ?? "Broker service did not become healthy.");
|
|
14129
14365
|
}
|
|
14130
14366
|
function sleep(ms) {
|
|
14131
|
-
return new Promise((
|
|
14367
|
+
return new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
14132
14368
|
}
|
|
14133
14369
|
async function stopBrokerService(config = resolveBrokerServiceConfig()) {
|
|
14134
14370
|
runCommand(launchctlPath(), ["bootout", config.serviceTarget], { allowFailure: true });
|
|
@@ -14147,7 +14383,7 @@ async function restartBrokerService(config = resolveBrokerServiceConfig()) {
|
|
|
14147
14383
|
}
|
|
14148
14384
|
async function uninstallBrokerService(config = resolveBrokerServiceConfig()) {
|
|
14149
14385
|
await stopBrokerService(config);
|
|
14150
|
-
if (
|
|
14386
|
+
if (existsSync13(config.launchAgentPath)) {
|
|
14151
14387
|
rmSync2(config.launchAgentPath, { force: true });
|
|
14152
14388
|
}
|
|
14153
14389
|
return brokerServiceStatus(config);
|
|
@@ -14217,8 +14453,8 @@ var LOCAL_AGENT_SYSTEM_PROMPT_TEMPLATE_HINT = [
|
|
|
14217
14453
|
].join("");
|
|
14218
14454
|
|
|
14219
14455
|
// ../runtime/src/local-agents.ts
|
|
14220
|
-
var MODULE_DIRECTORY =
|
|
14221
|
-
var OPENSCOUT_REPO_ROOT =
|
|
14456
|
+
var MODULE_DIRECTORY = dirname7(fileURLToPath5(import.meta.url));
|
|
14457
|
+
var OPENSCOUT_REPO_ROOT = resolve6(MODULE_DIRECTORY, "..", "..", "..");
|
|
14222
14458
|
var DEFAULT_LOCAL_AGENT_CAPABILITIES = ["chat", "invoke", "deliver"];
|
|
14223
14459
|
var DEFAULT_LOCAL_AGENT_HARNESS = "claude";
|
|
14224
14460
|
function resolveRelayHub() {
|
|
@@ -14226,18 +14462,18 @@ function resolveRelayHub() {
|
|
|
14226
14462
|
}
|
|
14227
14463
|
function resolveProjectsRoot(projectPath) {
|
|
14228
14464
|
if (process.env.OPENSCOUT_PROJECTS_ROOT?.trim()) {
|
|
14229
|
-
return
|
|
14465
|
+
return resolve6(process.env.OPENSCOUT_PROJECTS_ROOT.trim());
|
|
14230
14466
|
}
|
|
14231
14467
|
try {
|
|
14232
14468
|
const supportPaths = resolveOpenScoutSupportPaths();
|
|
14233
|
-
if (!
|
|
14234
|
-
return
|
|
14469
|
+
if (!existsSync14(supportPaths.settingsPath)) {
|
|
14470
|
+
return dirname7(projectPath);
|
|
14235
14471
|
}
|
|
14236
14472
|
const raw = JSON.parse(readFileSync8(supportPaths.settingsPath, "utf8"));
|
|
14237
14473
|
const workspaceRoot = raw.discovery?.workspaceRoots?.find((entry) => typeof entry === "string" && entry.trim().length > 0);
|
|
14238
|
-
return workspaceRoot ?
|
|
14474
|
+
return workspaceRoot ? resolve6(workspaceRoot) : dirname7(projectPath);
|
|
14239
14475
|
} catch {
|
|
14240
|
-
return
|
|
14476
|
+
return dirname7(projectPath);
|
|
14241
14477
|
}
|
|
14242
14478
|
}
|
|
14243
14479
|
function resolveBrokerUrl() {
|
|
@@ -14247,7 +14483,7 @@ function nowSeconds2() {
|
|
|
14247
14483
|
return Math.floor(Date.now() / 1000);
|
|
14248
14484
|
}
|
|
14249
14485
|
function scoutCliPath() {
|
|
14250
|
-
return
|
|
14486
|
+
return join16(OPENSCOUT_REPO_ROOT, "packages", "cli", "bin", "scout.mjs");
|
|
14251
14487
|
}
|
|
14252
14488
|
function legacyNodeBrokerRelayCommand() {
|
|
14253
14489
|
return `node ${JSON.stringify(scoutCliPath())}`;
|
|
@@ -14260,13 +14496,13 @@ function titleCaseLocalAgentName(value) {
|
|
|
14260
14496
|
}
|
|
14261
14497
|
function resolveScoutSkillPath() {
|
|
14262
14498
|
const candidatePaths = [
|
|
14263
|
-
|
|
14264
|
-
|
|
14265
|
-
|
|
14266
|
-
|
|
14499
|
+
join16(OPENSCOUT_REPO_ROOT, ".agents", "skills", "scout", "SKILL.md"),
|
|
14500
|
+
join16(process.env.HOME ?? "", ".agents", "skills", "scout", "SKILL.md"),
|
|
14501
|
+
join16(OPENSCOUT_REPO_ROOT, ".agents", "skills", "relay-agent-comms", "SKILL.md"),
|
|
14502
|
+
join16(process.env.HOME ?? "", ".agents", "skills", "relay-agent-comms", "SKILL.md")
|
|
14267
14503
|
];
|
|
14268
14504
|
for (const path2 of candidatePaths) {
|
|
14269
|
-
if (
|
|
14505
|
+
if (existsSync14(path2)) {
|
|
14270
14506
|
return path2;
|
|
14271
14507
|
}
|
|
14272
14508
|
}
|
|
@@ -14317,7 +14553,7 @@ function buildLocalAgentCollaborationPrompt(context) {
|
|
|
14317
14553
|
function buildLocalAgentTmuxProtocolPrompt(context) {
|
|
14318
14554
|
return [
|
|
14319
14555
|
"Relay protocol:",
|
|
14320
|
-
` - Read recent context with: ${context.relayCommand}
|
|
14556
|
+
` - Read recent context when needed with: ${context.relayCommand} latest --agent ${context.agentId} --limit 20`,
|
|
14321
14557
|
` - Tell one agent with: ${context.relayCommand} send --as ${context.agentId} "@<agent> your message"`,
|
|
14322
14558
|
` - Ask one agent and stay attached with: ${context.relayCommand} ask --to <agent> --as ${context.agentId} "your request"`,
|
|
14323
14559
|
"",
|
|
@@ -14329,9 +14565,10 @@ function buildLocalAgentTmuxProtocolPrompt(context) {
|
|
|
14329
14565
|
" - If you need multiple agents, use separate DMs or an explicit channel; do not guess a venue from multiple mentions",
|
|
14330
14566
|
" - Do not use channel.shared for ordinary delegation or follow-up; reserve it for explicit group updates or broadcasts",
|
|
14331
14567
|
" - If a short @handle may be ambiguous, resolve the exact target before sending; do not guess and do not fall back to shared",
|
|
14568
|
+
" - Treat known offline / on-demand agents as wakeable: use send or ask first and let the broker wake them; only surface ambiguity or unknown-target failures to the operator",
|
|
14332
14569
|
" - Use send for tells and status; use ask when the meaning is 'do this and get back to me'",
|
|
14333
14570
|
" - When replying to an [ask:<id>] request, include the same [ask:<id>] tag in your reply",
|
|
14334
|
-
" - Use the broker-backed
|
|
14571
|
+
" - Use the broker-backed latest command above only when recent context is needed before responding",
|
|
14335
14572
|
` - Follow the scout skill at ${context.scoutSkill} for agent-to-agent communication`
|
|
14336
14573
|
].join(`
|
|
14337
14574
|
`);
|
|
@@ -14342,7 +14579,7 @@ function buildLocalAgentDirectProtocolPrompt(context) {
|
|
|
14342
14579
|
" - You are invoked directly by the OpenScout broker",
|
|
14343
14580
|
" - Return your final answer in the assistant message for the current turn",
|
|
14344
14581
|
" - Do not shell out to send the final answer through relay yourself",
|
|
14345
|
-
` - If you need recent
|
|
14582
|
+
` - If you need recent broker context, inspect it with: ${context.relayCommand} latest --agent ${context.agentId} --limit 20`,
|
|
14346
14583
|
` - If you need to tell one agent something, use: ${context.relayCommand} send --as ${context.agentId} "@<agent> your message"`,
|
|
14347
14584
|
` - If you need another agent to do work, use: ${context.relayCommand} ask --to <agent> --as ${context.agentId} "your request"`,
|
|
14348
14585
|
" - Default Scout loop: resolve identity, resolve one target, choose DM vs explicit channel, keep follow-up in that same venue",
|
|
@@ -14350,6 +14587,7 @@ function buildLocalAgentDirectProtocolPrompt(context) {
|
|
|
14350
14587
|
" - If you need multiple agents, use separate DMs or an explicit channel; do not guess a venue from multiple mentions",
|
|
14351
14588
|
" - Do not use channel.shared for ordinary delegation or follow-up; reserve it for explicit group updates or broadcasts",
|
|
14352
14589
|
" - If a short @handle may be ambiguous, resolve the exact target before sending; do not guess and do not fall back to shared",
|
|
14590
|
+
" - Treat known offline / on-demand agents as wakeable: use send or ask first and let the broker wake them; only surface ambiguity or unknown-target failures to the operator",
|
|
14353
14591
|
" - Use send for tells and status; use ask when the meaning is 'do this and get back to me'",
|
|
14354
14592
|
` - Follow the scout skill at ${context.scoutSkill} for agent-to-agent communication`
|
|
14355
14593
|
].join(`
|
|
@@ -14412,7 +14650,7 @@ function buildLegacySimpleRelayPrompt(agentId, projectName, projectPath, relayCo
|
|
|
14412
14650
|
"A primary agent may call into you for context, execution, follow-through, and handoff.",
|
|
14413
14651
|
"",
|
|
14414
14652
|
`You have full access to the codebase at ${projectPath}.`,
|
|
14415
|
-
`There is a structured relay event stream at ${
|
|
14653
|
+
`There is a structured relay event stream at ${join16(relayHub, "channel.jsonl")} shared by all agents.`,
|
|
14416
14654
|
"",
|
|
14417
14655
|
"Your job:",
|
|
14418
14656
|
` - Respond to @${agentId} mentions from other agents`,
|
|
@@ -14516,17 +14754,17 @@ async function writeLocalAgentRegistry(registry) {
|
|
|
14516
14754
|
}
|
|
14517
14755
|
await writeRelayAgentOverrides(nextOverrides);
|
|
14518
14756
|
}
|
|
14519
|
-
function
|
|
14757
|
+
function expandHomePath4(value) {
|
|
14520
14758
|
if (value === "~") {
|
|
14521
14759
|
return process.env.HOME ?? process.cwd();
|
|
14522
14760
|
}
|
|
14523
14761
|
if (value.startsWith("~/")) {
|
|
14524
|
-
return
|
|
14762
|
+
return join16(process.env.HOME ?? process.cwd(), value.slice(2));
|
|
14525
14763
|
}
|
|
14526
14764
|
return value;
|
|
14527
14765
|
}
|
|
14528
14766
|
function normalizeProjectPath(value) {
|
|
14529
|
-
return
|
|
14767
|
+
return resolve6(expandHomePath4(value.trim() || "."));
|
|
14530
14768
|
}
|
|
14531
14769
|
function normalizeTmuxSessionName2(value, agentId) {
|
|
14532
14770
|
const fallback = `relay-${agentId}`;
|
|
@@ -14789,7 +15027,7 @@ function recordForHarness(record, harnessOverride) {
|
|
|
14789
15027
|
function normalizeLocalAgentRecord(agentId, record) {
|
|
14790
15028
|
const cwd = normalizeProjectPath(record.cwd || process.cwd());
|
|
14791
15029
|
const projectRoot = normalizeProjectPath(record.projectRoot || cwd);
|
|
14792
|
-
const project = record.project?.trim() ||
|
|
15030
|
+
const project = record.project?.trim() || basename5(projectRoot);
|
|
14793
15031
|
const definitionId = record.definitionId?.trim() || agentId;
|
|
14794
15032
|
const defaultHarness = activeLocalHarness(record);
|
|
14795
15033
|
const harnessProfiles = normalizeLocalHarnessProfiles(agentId, {
|
|
@@ -14854,7 +15092,7 @@ function localAgentRecordFromResolvedConfig(config) {
|
|
|
14854
15092
|
function localAgentRecordFromRelayAgentOverride(agentId, override) {
|
|
14855
15093
|
return normalizeLocalAgentRecord(agentId, {
|
|
14856
15094
|
definitionId: override.definitionId ?? agentId,
|
|
14857
|
-
project: override.projectName ??
|
|
15095
|
+
project: override.projectName ?? basename5(override.projectRoot || override.runtime?.cwd || agentId),
|
|
14858
15096
|
projectRoot: override.projectRoot ?? override.runtime?.cwd,
|
|
14859
15097
|
tmuxSession: override.runtime?.sessionId ?? `relay-${agentId}`,
|
|
14860
15098
|
cwd: override.runtime?.cwd ?? override.projectRoot,
|
|
@@ -14950,7 +15188,7 @@ function buildLocalAgentBootstrapPrompt(_harness, _systemPrompt, initialMessage)
|
|
|
14950
15188
|
function buildLocalAgentLaunchCommand(agentName, record, projectPath, promptFile, workerScript) {
|
|
14951
15189
|
const extraArgs = shellQuoteArguments(normalizeLaunchArgsForHarness(normalizeLocalAgentHarness(record.harness), record.launchArgs));
|
|
14952
15190
|
if (normalizeLocalAgentHarness(record.harness) === "codex") {
|
|
14953
|
-
return `exec bash ${JSON.stringify(workerScript ??
|
|
15191
|
+
return `exec bash ${JSON.stringify(workerScript ?? join16(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
|
|
14954
15192
|
}
|
|
14955
15193
|
return [
|
|
14956
15194
|
"claude",
|
|
@@ -14996,7 +15234,7 @@ async function ensureLocalAgentOnline(agentName, record) {
|
|
|
14996
15234
|
return normalizedRecord;
|
|
14997
15235
|
}
|
|
14998
15236
|
const projectPath = normalizedRecord.cwd;
|
|
14999
|
-
const projectName = normalizedRecord.project ||
|
|
15237
|
+
const projectName = normalizedRecord.project || basename5(projectPath);
|
|
15000
15238
|
const systemPromptTemplate = normalizedRecord.systemPrompt || buildLocalAgentSystemPromptTemplate();
|
|
15001
15239
|
const systemPrompt = renderLocalAgentSystemPromptTemplate(systemPromptTemplate, buildLocalAgentTemplateContext(agentName, projectName, projectPath), { transport: normalizedRecord.transport });
|
|
15002
15240
|
const agentRuntimeDir = relayAgentRuntimeDirectory(agentName);
|
|
@@ -15004,7 +15242,7 @@ async function ensureLocalAgentOnline(agentName, record) {
|
|
|
15004
15242
|
await mkdir6(agentRuntimeDir, { recursive: true });
|
|
15005
15243
|
await mkdir6(logsDir, { recursive: true });
|
|
15006
15244
|
if (normalizedRecord.transport === "codex_app_server") {
|
|
15007
|
-
await writeFile6(
|
|
15245
|
+
await writeFile6(join16(agentRuntimeDir, "prompt.txt"), systemPrompt);
|
|
15008
15246
|
await ensureCodexAppServerAgentOnline(buildCodexAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
|
|
15009
15247
|
const registry2 = await readLocalAgentRegistry();
|
|
15010
15248
|
registry2[agentName] = {
|
|
@@ -15016,7 +15254,7 @@ async function ensureLocalAgentOnline(agentName, record) {
|
|
|
15016
15254
|
return registry2[agentName];
|
|
15017
15255
|
}
|
|
15018
15256
|
if (normalizedRecord.transport === "claude_stream_json") {
|
|
15019
|
-
await writeFile6(
|
|
15257
|
+
await writeFile6(join16(agentRuntimeDir, "prompt.txt"), systemPrompt);
|
|
15020
15258
|
await ensureClaudeStreamJsonAgentOnline(buildClaudeAgentSessionOptions(agentName, normalizedRecord, systemPrompt));
|
|
15021
15259
|
const registry2 = await readLocalAgentRegistry();
|
|
15022
15260
|
registry2[agentName] = {
|
|
@@ -15029,17 +15267,17 @@ async function ensureLocalAgentOnline(agentName, record) {
|
|
|
15029
15267
|
}
|
|
15030
15268
|
const initialMessage = buildLocalAgentInitialMessage(projectName, agentName);
|
|
15031
15269
|
const bootstrapPrompt = buildLocalAgentBootstrapPrompt(normalizeLocalAgentHarness(normalizedRecord.harness), systemPrompt, initialMessage);
|
|
15032
|
-
const queueDirectory =
|
|
15033
|
-
const processingDirectory =
|
|
15034
|
-
const processedDirectory =
|
|
15035
|
-
const promptFile =
|
|
15036
|
-
const initialFile =
|
|
15037
|
-
const launchScript =
|
|
15038
|
-
const workerScript =
|
|
15039
|
-
const codexSessionIdFile =
|
|
15040
|
-
const stateFile =
|
|
15041
|
-
const stdoutLogFile =
|
|
15042
|
-
const stderrLogFile =
|
|
15270
|
+
const queueDirectory = join16(agentRuntimeDir, "queue");
|
|
15271
|
+
const processingDirectory = join16(queueDirectory, "processing");
|
|
15272
|
+
const processedDirectory = join16(queueDirectory, "processed");
|
|
15273
|
+
const promptFile = join16(agentRuntimeDir, "prompt.txt");
|
|
15274
|
+
const initialFile = join16(agentRuntimeDir, "initial.txt");
|
|
15275
|
+
const launchScript = join16(agentRuntimeDir, "launch.sh");
|
|
15276
|
+
const workerScript = join16(agentRuntimeDir, "codex-worker.sh");
|
|
15277
|
+
const codexSessionIdFile = join16(agentRuntimeDir, "codex-session-id.txt");
|
|
15278
|
+
const stateFile = join16(agentRuntimeDir, "state.json");
|
|
15279
|
+
const stdoutLogFile = join16(logsDir, "stdout.log");
|
|
15280
|
+
const stderrLogFile = join16(logsDir, "stderr.log");
|
|
15043
15281
|
await writeFile6(promptFile, systemPrompt);
|
|
15044
15282
|
await writeFile6(initialFile, bootstrapPrompt);
|
|
15045
15283
|
await writeFile6(stderrLogFile, "");
|
|
@@ -15101,10 +15339,10 @@ async function ensureLocalAgentOnline(agentName, record) {
|
|
|
15101
15339
|
if (isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
|
|
15102
15340
|
break;
|
|
15103
15341
|
}
|
|
15104
|
-
await new Promise((
|
|
15342
|
+
await new Promise((resolve7) => setTimeout(resolve7, 100));
|
|
15105
15343
|
}
|
|
15106
15344
|
if (!isLocalAgentSessionAlive(normalizedRecord.tmuxSession)) {
|
|
15107
|
-
const stderrTail =
|
|
15345
|
+
const stderrTail = existsSync14(stderrLogFile) ? readFileSync8(stderrLogFile, "utf8").trim().split(/\r?\n/).slice(-10).join(`
|
|
15108
15346
|
`).trim() : "";
|
|
15109
15347
|
throw new Error(stderrTail ? `Relay agent ${agentName} failed to stay online:
|
|
15110
15348
|
${stderrTail}` : `Relay agent ${agentName} failed to stay online.`);
|
|
@@ -15159,6 +15397,7 @@ async function startLocalAgent(input) {
|
|
|
15159
15397
|
const preferredHarness = input.harness ? normalizeLocalAgentHarness(input.harness) : undefined;
|
|
15160
15398
|
const currentDirectory = input.currentDirectory ?? projectPath;
|
|
15161
15399
|
const effectiveCwd = input.cwdOverride ? normalizeProjectPath(input.cwdOverride) : undefined;
|
|
15400
|
+
const shouldEnsureOnline = input.ensureOnline !== false;
|
|
15162
15401
|
const requestedDefinitionId = input.agentName?.trim() ? normalizeAgentSelectorSegment(input.agentName.trim()) : "";
|
|
15163
15402
|
if (input.agentName?.trim() && !requestedDefinitionId) {
|
|
15164
15403
|
throw new Error(`Invalid agent name "${input.agentName}".`);
|
|
@@ -15206,7 +15445,7 @@ async function startLocalAgent(input) {
|
|
|
15206
15445
|
}
|
|
15207
15446
|
if (!matchingOverride) {
|
|
15208
15447
|
const configDefinitionId = coldProjectConfig?.agent?.id?.trim() ? normalizeAgentSelectorSegment(coldProjectConfig.agent.id.trim()) : "";
|
|
15209
|
-
const definitionId = requestedDefinitionId || configDefinitionId || normalizeAgentSelectorSegment(
|
|
15448
|
+
const definitionId = requestedDefinitionId || configDefinitionId || normalizeAgentSelectorSegment(basename5(projectRoot)) || "agent";
|
|
15210
15449
|
const configDisplayName = coldProjectConfig?.agent?.displayName?.trim() || "";
|
|
15211
15450
|
const effectiveDisplayName = input.displayName || configDisplayName || titleCaseLocalAgentName(definitionId);
|
|
15212
15451
|
const instance = buildRelayAgentInstance(definitionId, projectRoot);
|
|
@@ -15223,7 +15462,7 @@ async function startLocalAgent(input) {
|
|
|
15223
15462
|
agentId: instance.id,
|
|
15224
15463
|
definitionId,
|
|
15225
15464
|
displayName: effectiveDisplayName,
|
|
15226
|
-
projectName:
|
|
15465
|
+
projectName: basename5(projectRoot),
|
|
15227
15466
|
projectRoot,
|
|
15228
15467
|
projectConfigPath: coldProjectConfigPath,
|
|
15229
15468
|
source: "manual",
|
|
@@ -15263,7 +15502,7 @@ async function startLocalAgent(input) {
|
|
|
15263
15502
|
agentId: instance.id,
|
|
15264
15503
|
definitionId: requestedDefinitionId,
|
|
15265
15504
|
displayName: input.displayName || titleCaseLocalAgentName(requestedDefinitionId),
|
|
15266
|
-
projectName: matchingOverride.projectName ??
|
|
15505
|
+
projectName: matchingOverride.projectName ?? basename5(matchingProjectRoot),
|
|
15267
15506
|
projectRoot: matchingProjectRoot,
|
|
15268
15507
|
projectConfigPath: matchingOverride.projectConfigPath ?? null,
|
|
15269
15508
|
source: "manual",
|
|
@@ -15308,12 +15547,14 @@ async function startLocalAgent(input) {
|
|
|
15308
15547
|
}
|
|
15309
15548
|
targetAgentId = matchingAgentId;
|
|
15310
15549
|
}
|
|
15311
|
-
|
|
15312
|
-
|
|
15313
|
-
|
|
15314
|
-
|
|
15315
|
-
|
|
15316
|
-
|
|
15550
|
+
if (shouldEnsureOnline) {
|
|
15551
|
+
await ensureLocalAgentBindingOnline(targetAgentId, process.env.OPENSCOUT_NODE_ID ?? "local", {
|
|
15552
|
+
includeDiscovered: false,
|
|
15553
|
+
currentDirectory,
|
|
15554
|
+
ensureCurrentProjectConfig: false,
|
|
15555
|
+
harness: preferredHarness
|
|
15556
|
+
});
|
|
15557
|
+
}
|
|
15317
15558
|
const finalOverrides = await readRelayAgentOverrides();
|
|
15318
15559
|
const finalOverride = finalOverrides[targetAgentId];
|
|
15319
15560
|
if (!finalOverride) {
|
|
@@ -15379,8 +15620,8 @@ async function interruptLocalAgent(agentId) {
|
|
|
15379
15620
|
function readPersistedClaudeSessionId(agentName) {
|
|
15380
15621
|
try {
|
|
15381
15622
|
const runtimeDir = relayAgentRuntimeDirectory(agentName);
|
|
15382
|
-
const catalogPath =
|
|
15383
|
-
if (
|
|
15623
|
+
const catalogPath = join16(runtimeDir, "session-catalog.json");
|
|
15624
|
+
if (existsSync14(catalogPath)) {
|
|
15384
15625
|
const raw = readFileSync8(catalogPath, "utf8").trim();
|
|
15385
15626
|
if (raw) {
|
|
15386
15627
|
const catalog = JSON.parse(raw);
|
|
@@ -15389,8 +15630,8 @@ function readPersistedClaudeSessionId(agentName) {
|
|
|
15389
15630
|
}
|
|
15390
15631
|
}
|
|
15391
15632
|
}
|
|
15392
|
-
const legacyPath =
|
|
15393
|
-
if (
|
|
15633
|
+
const legacyPath = join16(runtimeDir, "claude-session-id.txt");
|
|
15634
|
+
if (existsSync14(legacyPath)) {
|
|
15394
15635
|
const value = readFileSync8(legacyPath, "utf8").trim();
|
|
15395
15636
|
return value || null;
|
|
15396
15637
|
}
|
|
@@ -15584,6 +15825,7 @@ var scoutBrokerPaths = {
|
|
|
15584
15825
|
endpoints: "/v1/endpoints",
|
|
15585
15826
|
conversations: "/v1/conversations",
|
|
15586
15827
|
invocations: "/v1/invocations",
|
|
15828
|
+
deliver: "/v1/deliver",
|
|
15587
15829
|
activity: "/v1/activity",
|
|
15588
15830
|
collaborationRecords: "/v1/collaboration/records",
|
|
15589
15831
|
collaborationEvents: "/v1/collaboration/events"
|
|
@@ -15613,29 +15855,6 @@ function titleCaseName(value) {
|
|
|
15613
15855
|
function displayNameForBrokerActor(snapshot, actorId) {
|
|
15614
15856
|
return snapshot.agents[actorId]?.displayName ?? snapshot.actors[actorId]?.displayName ?? titleCaseName(metadataString2(snapshot.agents[actorId]?.metadata, "definitionId") || actorId);
|
|
15615
15857
|
}
|
|
15616
|
-
function firstEndpointForActor(snapshot, actorId) {
|
|
15617
|
-
return Object.values(snapshot.endpoints).filter((endpoint) => endpoint.agentId === actorId).sort((lhs, rhs) => lhs.id.localeCompare(rhs.id))[0];
|
|
15618
|
-
}
|
|
15619
|
-
function buildScoutReturnAddress2(snapshot, actorId, options = {}) {
|
|
15620
|
-
const agent = snapshot.agents[actorId];
|
|
15621
|
-
const actor = snapshot.actors[actorId];
|
|
15622
|
-
const endpoint = firstEndpointForActor(snapshot, actorId);
|
|
15623
|
-
const selector = agent?.selector?.trim() || metadataString2(agent?.metadata, "selector") || metadataString2(actor?.metadata, "selector");
|
|
15624
|
-
const defaultSelector = agent?.defaultSelector?.trim() || metadataString2(agent?.metadata, "defaultSelector") || metadataString2(actor?.metadata, "defaultSelector");
|
|
15625
|
-
const projectRoot = endpoint?.projectRoot ?? endpoint?.cwd ?? metadataString2(agent?.metadata, "projectRoot") ?? metadataString2(actor?.metadata, "projectRoot");
|
|
15626
|
-
return buildScoutReturnAddress({
|
|
15627
|
-
actorId,
|
|
15628
|
-
handle: agent?.handle?.trim() || actor?.handle?.trim() || actorId,
|
|
15629
|
-
displayName: agent?.displayName || actor?.displayName,
|
|
15630
|
-
selector,
|
|
15631
|
-
defaultSelector,
|
|
15632
|
-
conversationId: options.conversationId,
|
|
15633
|
-
replyToMessageId: options.replyToMessageId,
|
|
15634
|
-
nodeId: endpoint?.nodeId || agent?.authorityNodeId || agent?.homeNodeId,
|
|
15635
|
-
projectRoot,
|
|
15636
|
-
sessionId: endpoint?.sessionId
|
|
15637
|
-
});
|
|
15638
|
-
}
|
|
15639
15858
|
function metadataString2(metadata, key) {
|
|
15640
15859
|
const value = metadata?.[key];
|
|
15641
15860
|
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
@@ -15938,74 +16157,42 @@ async function openScoutPeerSession(input) {
|
|
|
15938
16157
|
};
|
|
15939
16158
|
}
|
|
15940
16159
|
async function sendScoutDirectMessage(input) {
|
|
15941
|
-
const currentDirectory = input.currentDirectory ?? process.cwd();
|
|
15942
|
-
const directSession = await openScoutPeerSession({
|
|
15943
|
-
sourceId: OPERATOR_ID,
|
|
15944
|
-
targetId: input.agentId,
|
|
15945
|
-
currentDirectory
|
|
15946
|
-
});
|
|
15947
16160
|
const broker = await requireScoutBrokerContext();
|
|
15948
16161
|
const createdAt = Date.now();
|
|
15949
|
-
const messageId = `msg-${createdAt.toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
15950
16162
|
const source = input.source?.trim() || "scout-mobile";
|
|
15951
|
-
const
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
replyToMessageId: messageId
|
|
15957
|
-
});
|
|
15958
|
-
await brokerPostJson(broker.baseUrl, scoutBrokerPaths.v1.messages, {
|
|
15959
|
-
id: messageId,
|
|
15960
|
-
conversationId: directSession.conversation.id,
|
|
15961
|
-
replyToMessageId: input.replyToMessageId ?? undefined,
|
|
15962
|
-
actorId: OPERATOR_ID,
|
|
15963
|
-
originNodeId: broker.node.id,
|
|
15964
|
-
class: "agent",
|
|
16163
|
+
const delivery = await brokerPostJson(broker.baseUrl, scoutBrokerPaths.v1.deliver, {
|
|
16164
|
+
id: `deliver-${createdAt.toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
|
|
16165
|
+
requesterId: OPERATOR_ID,
|
|
16166
|
+
requesterNodeId: broker.node.id,
|
|
16167
|
+
targetAgentId: input.agentId,
|
|
15965
16168
|
body: input.body.trim(),
|
|
15966
|
-
|
|
15967
|
-
|
|
15968
|
-
|
|
15969
|
-
|
|
15970
|
-
},
|
|
15971
|
-
visibility: "private",
|
|
15972
|
-
policy: "durable",
|
|
16169
|
+
intent: "consult",
|
|
16170
|
+
replyToMessageId: input.replyToMessageId ?? undefined,
|
|
16171
|
+
execution: input.executionHarness ? { harness: input.executionHarness } : undefined,
|
|
16172
|
+
ensureAwake: true,
|
|
15973
16173
|
createdAt,
|
|
15974
|
-
|
|
16174
|
+
messageMetadata: {
|
|
15975
16175
|
source,
|
|
15976
16176
|
destinationKind: "direct",
|
|
15977
|
-
destinationId:
|
|
16177
|
+
destinationId: input.agentId,
|
|
15978
16178
|
referenceMessageIds: input.referenceMessageIds ?? [],
|
|
15979
16179
|
clientMessageId: input.clientMessageId ?? null,
|
|
15980
|
-
returnAddress,
|
|
15981
16180
|
...input.deviceId ? { deviceId: input.deviceId } : {}
|
|
15982
|
-
}
|
|
15983
|
-
|
|
15984
|
-
const invocationResponse = await brokerPostJson(broker.baseUrl, scoutBrokerPaths.v1.invocations, {
|
|
15985
|
-
id: `inv-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,
|
|
15986
|
-
requesterId: OPERATOR_ID,
|
|
15987
|
-
requesterNodeId: broker.node.id,
|
|
15988
|
-
targetAgentId,
|
|
15989
|
-
action: "consult",
|
|
15990
|
-
task: input.body.trim(),
|
|
15991
|
-
conversationId: directSession.conversation.id,
|
|
15992
|
-
messageId,
|
|
15993
|
-
execution: input.executionHarness ? { harness: input.executionHarness } : undefined,
|
|
15994
|
-
ensureAwake: true,
|
|
15995
|
-
stream: false,
|
|
15996
|
-
createdAt,
|
|
15997
|
-
metadata: {
|
|
16181
|
+
},
|
|
16182
|
+
invocationMetadata: {
|
|
15998
16183
|
source,
|
|
15999
16184
|
destinationKind: "direct",
|
|
16000
|
-
destinationId:
|
|
16001
|
-
returnAddress,
|
|
16185
|
+
destinationId: input.agentId,
|
|
16002
16186
|
...input.deviceId ? { deviceId: input.deviceId } : {}
|
|
16003
16187
|
}
|
|
16004
16188
|
});
|
|
16189
|
+
if (delivery.kind !== "delivery") {
|
|
16190
|
+
throw new Error(delivery.kind === "question" ? delivery.question.detail : delivery.rejection.detail);
|
|
16191
|
+
}
|
|
16005
16192
|
return {
|
|
16006
|
-
conversationId:
|
|
16007
|
-
messageId,
|
|
16008
|
-
flight:
|
|
16193
|
+
conversationId: delivery.conversation.id,
|
|
16194
|
+
messageId: delivery.message.id,
|
|
16195
|
+
flight: delivery.flight
|
|
16009
16196
|
};
|
|
16010
16197
|
}
|
|
16011
16198
|
async function loadScoutActivityItems(options = {}) {
|
|
@@ -16032,11 +16219,11 @@ async function upScoutAgent(input) {
|
|
|
16032
16219
|
|
|
16033
16220
|
// ../../apps/desktop/src/server/db-queries.ts
|
|
16034
16221
|
import { Database } from "bun:sqlite";
|
|
16035
|
-
import { homedir as
|
|
16036
|
-
import { join as
|
|
16222
|
+
import { homedir as homedir15 } from "os";
|
|
16223
|
+
import { join as join17 } from "path";
|
|
16037
16224
|
function resolveDbPath() {
|
|
16038
|
-
const controlHome = process.env.OPENSCOUT_CONTROL_HOME ??
|
|
16039
|
-
return
|
|
16225
|
+
const controlHome = process.env.OPENSCOUT_CONTROL_HOME ?? join17(homedir15(), ".openscout", "control-plane");
|
|
16226
|
+
return join17(controlHome, "control-plane.sqlite");
|
|
16040
16227
|
}
|
|
16041
16228
|
var _db = null;
|
|
16042
16229
|
function db() {
|
|
@@ -16047,7 +16234,7 @@ function db() {
|
|
|
16047
16234
|
}
|
|
16048
16235
|
return _db;
|
|
16049
16236
|
}
|
|
16050
|
-
var HOME =
|
|
16237
|
+
var HOME = homedir15();
|
|
16051
16238
|
function compact(p) {
|
|
16052
16239
|
if (!p)
|
|
16053
16240
|
return null;
|
|
@@ -16703,8 +16890,8 @@ async function createScoutSession(input, currentDirectory, deviceId) {
|
|
|
16703
16890
|
if (!rawWorkspaceId) {
|
|
16704
16891
|
throw new Error(`Invalid workspaceId.`);
|
|
16705
16892
|
}
|
|
16706
|
-
const workspaceRoot =
|
|
16707
|
-
const projectName =
|
|
16893
|
+
const workspaceRoot = resolve7(rawWorkspaceId);
|
|
16894
|
+
const projectName = basename6(workspaceRoot) || workspaceRoot;
|
|
16708
16895
|
const workspace = {
|
|
16709
16896
|
id: workspaceRoot,
|
|
16710
16897
|
title: projectName,
|
|
@@ -16813,17 +17000,17 @@ async function deriveNewAgentName(projectName, branch, harness) {
|
|
|
16813
17000
|
}
|
|
16814
17001
|
async function createGitWorktree(projectRoot, agentName) {
|
|
16815
17002
|
const { execSync: execSync3 } = await import("child_process");
|
|
16816
|
-
const { join:
|
|
16817
|
-
const { mkdirSync: mkdirSync9, existsSync:
|
|
17003
|
+
const { join: join18 } = await import("path");
|
|
17004
|
+
const { mkdirSync: mkdirSync9, existsSync: existsSync15 } = await import("fs");
|
|
16818
17005
|
try {
|
|
16819
17006
|
execSync3("git rev-parse --git-dir", { cwd: projectRoot, stdio: "pipe" });
|
|
16820
17007
|
} catch {
|
|
16821
17008
|
return null;
|
|
16822
17009
|
}
|
|
16823
17010
|
const branchName = `scout/${agentName}`;
|
|
16824
|
-
const worktreeDir =
|
|
16825
|
-
const worktreePath =
|
|
16826
|
-
if (
|
|
17011
|
+
const worktreeDir = join18(projectRoot, ".scout-worktrees");
|
|
17012
|
+
const worktreePath = join18(worktreeDir, agentName);
|
|
17013
|
+
if (existsSync15(worktreePath)) {
|
|
16827
17014
|
return { path: worktreePath, branch: branchName };
|
|
16828
17015
|
}
|
|
16829
17016
|
mkdirSync9(worktreeDir, { recursive: true });
|
|
@@ -17027,9 +17214,9 @@ async function handleRPCInner(bridge, req, deviceId) {
|
|
|
17027
17214
|
}
|
|
17028
17215
|
case "session/resume": {
|
|
17029
17216
|
const p = req.params;
|
|
17030
|
-
const sessionFilename =
|
|
17217
|
+
const sessionFilename = basename7(p.sessionPath, ".jsonl");
|
|
17031
17218
|
const parentDir = p.sessionPath.substring(0, p.sessionPath.lastIndexOf("/"));
|
|
17032
|
-
const dirName =
|
|
17219
|
+
const dirName = basename7(parentDir);
|
|
17033
17220
|
let cwd;
|
|
17034
17221
|
if (dirName.startsWith("-")) {
|
|
17035
17222
|
const candidate = "/" + dirName.slice(1).replace(/-/g, "/");
|
|
@@ -17096,7 +17283,7 @@ async function handleRPCInner(bridge, req, deviceId) {
|
|
|
17096
17283
|
return { id: req.id, error: { code: -32000, message: "Workspace target is not a directory" } };
|
|
17097
17284
|
}
|
|
17098
17285
|
const adapterType = p.adapter ?? "claude-code";
|
|
17099
|
-
const name = p.name ??
|
|
17286
|
+
const name = p.name ?? basename7(projectPath);
|
|
17100
17287
|
const session = await bridge.createSession(adapterType, {
|
|
17101
17288
|
name,
|
|
17102
17289
|
cwd: projectPath
|
|
@@ -17336,13 +17523,13 @@ function resolveMobileCurrentDirectory() {
|
|
|
17336
17523
|
}
|
|
17337
17524
|
}
|
|
17338
17525
|
function resolveWorkspaceRoot(root) {
|
|
17339
|
-
const expandedRoot = root.replace(/^~/,
|
|
17526
|
+
const expandedRoot = root.replace(/^~/, homedir16());
|
|
17340
17527
|
return realpathSync(expandedRoot);
|
|
17341
17528
|
}
|
|
17342
17529
|
function resolveWorkspacePath(root, requestedPath) {
|
|
17343
17530
|
const normalizedRoot = resolveWorkspaceRoot(root);
|
|
17344
|
-
const expandedPath = requestedPath?.replace(/^~/,
|
|
17345
|
-
const candidate = expandedPath ? isAbsolute3(expandedPath) ? expandedPath :
|
|
17531
|
+
const expandedPath = requestedPath?.replace(/^~/, homedir16());
|
|
17532
|
+
const candidate = expandedPath ? isAbsolute3(expandedPath) ? expandedPath : join18(normalizedRoot, expandedPath) : normalizedRoot;
|
|
17346
17533
|
const resolvedCandidate = realpathSync(candidate);
|
|
17347
17534
|
const rel = relative2(normalizedRoot, resolvedCandidate);
|
|
17348
17535
|
if (rel === "" || !rel.startsWith("..") && !isAbsolute3(rel)) {
|
|
@@ -17372,7 +17559,7 @@ function listDirectories(dirPath) {
|
|
|
17372
17559
|
continue;
|
|
17373
17560
|
if (name === "node_modules" || name === ".build" || name === "target")
|
|
17374
17561
|
continue;
|
|
17375
|
-
const fullPath =
|
|
17562
|
+
const fullPath = join18(dirPath, name);
|
|
17376
17563
|
try {
|
|
17377
17564
|
const stat4 = statSync3(fullPath);
|
|
17378
17565
|
if (!stat4.isDirectory())
|
|
@@ -17395,7 +17582,7 @@ function listDirectories(dirPath) {
|
|
|
17395
17582
|
return entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
17396
17583
|
}
|
|
17397
17584
|
async function discoverSessionFiles(maxAgeDays, limit) {
|
|
17398
|
-
const home =
|
|
17585
|
+
const home = homedir16();
|
|
17399
17586
|
const results = [];
|
|
17400
17587
|
const searchPaths = [
|
|
17401
17588
|
{ pattern: `${home}/.claude/projects`, agent: "claude-code" },
|
|
@@ -31932,2189 +32119,12 @@ function date4(params) {
|
|
|
31932
32119
|
|
|
31933
32120
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
31934
32121
|
config(en_default());
|
|
31935
|
-
// ../runtime/src/registry.ts
|
|
31936
|
-
function createRuntimeRegistrySnapshot(value = {}) {
|
|
31937
|
-
return {
|
|
31938
|
-
nodes: value.nodes ?? {},
|
|
31939
|
-
actors: value.actors ?? {},
|
|
31940
|
-
agents: value.agents ?? {},
|
|
31941
|
-
endpoints: value.endpoints ?? {},
|
|
31942
|
-
conversations: value.conversations ?? {},
|
|
31943
|
-
bindings: value.bindings ?? {},
|
|
31944
|
-
messages: value.messages ?? {},
|
|
31945
|
-
flights: value.flights ?? {},
|
|
31946
|
-
collaborationRecords: value.collaborationRecords ?? {}
|
|
31947
|
-
};
|
|
31948
|
-
}
|
|
31949
|
-
// ../runtime/src/planner.ts
|
|
31950
|
-
function createDeliveryId(messageId, targetId, reason, transport) {
|
|
31951
|
-
return `del-${messageId}-${targetId}-${reason}-${transport}`;
|
|
31952
|
-
}
|
|
31953
|
-
function unique(values) {
|
|
31954
|
-
return [...new Set(values)];
|
|
31955
|
-
}
|
|
31956
|
-
function resolveVisibilityAudience(message, conversation) {
|
|
31957
|
-
if (message.audience?.visibleTo?.length) {
|
|
31958
|
-
return unique(message.audience.visibleTo);
|
|
31959
|
-
}
|
|
31960
|
-
return unique(conversation.participantIds.filter((participantId) => participantId !== message.actorId));
|
|
31961
|
-
}
|
|
31962
|
-
function resolveNotifyAudience(message) {
|
|
31963
|
-
const fromMentions = (message.mentions ?? []).map((mention) => mention.actorId);
|
|
31964
|
-
const explicit = message.audience?.notify ?? [];
|
|
31965
|
-
return unique([...fromMentions, ...explicit].filter((actorId) => actorId !== message.actorId));
|
|
31966
|
-
}
|
|
31967
|
-
function resolveInvocationAudience(message) {
|
|
31968
|
-
return unique((message.audience?.invoke ?? []).filter((actorId) => actorId !== message.actorId));
|
|
31969
|
-
}
|
|
31970
|
-
function planTargetDelivery(message, route2, reason, policy) {
|
|
31971
|
-
return {
|
|
31972
|
-
id: createDeliveryId(message.id, route2.targetId, reason, route2.transport),
|
|
31973
|
-
messageId: message.id,
|
|
31974
|
-
targetId: route2.targetId,
|
|
31975
|
-
targetNodeId: route2.nodeId,
|
|
31976
|
-
targetKind: route2.targetKind,
|
|
31977
|
-
transport: route2.transport,
|
|
31978
|
-
reason,
|
|
31979
|
-
policy,
|
|
31980
|
-
status: "pending",
|
|
31981
|
-
bindingId: route2.bindingId
|
|
31982
|
-
};
|
|
31983
|
-
}
|
|
31984
|
-
function planMessageDeliveries(input) {
|
|
31985
|
-
const visibilityIds = new Set(resolveVisibilityAudience(input.message, input.conversation));
|
|
31986
|
-
const notifyIds = new Set(resolveNotifyAudience(input.message));
|
|
31987
|
-
const invokeIds = new Set(resolveInvocationAudience(input.message));
|
|
31988
|
-
const deliveries2 = new Map;
|
|
31989
|
-
for (const route2 of input.participantRoutes) {
|
|
31990
|
-
if (visibilityIds.has(route2.targetId)) {
|
|
31991
|
-
const intent = planTargetDelivery(input.message, {
|
|
31992
|
-
...route2,
|
|
31993
|
-
transport: route2.nodeId && input.localNodeId && route2.nodeId !== input.localNodeId ? "peer_broker" : route2.transport
|
|
31994
|
-
}, input.conversation.kind === "direct" || input.conversation.kind === "group_direct" ? "direct_message" : "conversation_visibility", "durable");
|
|
31995
|
-
deliveries2.set(intent.id, intent);
|
|
31996
|
-
}
|
|
31997
|
-
if (notifyIds.has(route2.targetId)) {
|
|
31998
|
-
const intent = planTargetDelivery(input.message, {
|
|
31999
|
-
...route2,
|
|
32000
|
-
transport: route2.nodeId && input.localNodeId && route2.nodeId !== input.localNodeId ? "peer_broker" : route2.transport
|
|
32001
|
-
}, "mention", "must_ack");
|
|
32002
|
-
deliveries2.set(intent.id, intent);
|
|
32003
|
-
}
|
|
32004
|
-
if (invokeIds.has(route2.targetId)) {
|
|
32005
|
-
const intent = planTargetDelivery(input.message, {
|
|
32006
|
-
...route2,
|
|
32007
|
-
transport: route2.nodeId && input.localNodeId && route2.nodeId !== input.localNodeId ? "peer_broker" : route2.transport
|
|
32008
|
-
}, "invocation", "must_ack");
|
|
32009
|
-
deliveries2.set(intent.id, intent);
|
|
32010
|
-
}
|
|
32011
|
-
if (input.message.speech?.text && route2.speechEnabled) {
|
|
32012
|
-
const speechIntent = planTargetDelivery(input.message, {
|
|
32013
|
-
...route2,
|
|
32014
|
-
transport: route2.transport === "local_socket" ? "native_voice" : "tts",
|
|
32015
|
-
targetKind: route2.targetKind === "device" ? "voice_session" : route2.targetKind
|
|
32016
|
-
}, "speech", "best_effort");
|
|
32017
|
-
deliveries2.set(speechIntent.id, speechIntent);
|
|
32018
|
-
}
|
|
32019
|
-
}
|
|
32020
|
-
for (const route2 of input.bindingRoutes ?? []) {
|
|
32021
|
-
const intent = planTargetDelivery(input.message, route2, "bridge_outbound", "durable");
|
|
32022
|
-
deliveries2.set(intent.id, intent);
|
|
32023
|
-
}
|
|
32024
|
-
return [...deliveries2.values()];
|
|
32025
|
-
}
|
|
32026
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/entity.js
|
|
32027
|
-
var entityKind = Symbol.for("drizzle:entityKind");
|
|
32028
|
-
var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
|
|
32029
|
-
function is(value, type) {
|
|
32030
|
-
if (!value || typeof value !== "object") {
|
|
32031
|
-
return false;
|
|
32032
|
-
}
|
|
32033
|
-
if (value instanceof type) {
|
|
32034
|
-
return true;
|
|
32035
|
-
}
|
|
32036
|
-
if (!Object.prototype.hasOwnProperty.call(type, entityKind)) {
|
|
32037
|
-
throw new Error(`Class "${type.name ?? "<unknown>"}" doesn't look like a Drizzle entity. If this is incorrect and the class is provided by Drizzle, please report this as a bug.`);
|
|
32038
|
-
}
|
|
32039
|
-
let cls = Object.getPrototypeOf(value).constructor;
|
|
32040
|
-
if (cls) {
|
|
32041
|
-
while (cls) {
|
|
32042
|
-
if (entityKind in cls && cls[entityKind] === type[entityKind]) {
|
|
32043
|
-
return true;
|
|
32044
|
-
}
|
|
32045
|
-
cls = Object.getPrototypeOf(cls);
|
|
32046
|
-
}
|
|
32047
|
-
}
|
|
32048
|
-
return false;
|
|
32049
|
-
}
|
|
32050
|
-
|
|
32051
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/column.js
|
|
32052
|
-
class Column {
|
|
32053
|
-
constructor(table, config2) {
|
|
32054
|
-
this.table = table;
|
|
32055
|
-
this.config = config2;
|
|
32056
|
-
this.name = config2.name;
|
|
32057
|
-
this.keyAsName = config2.keyAsName;
|
|
32058
|
-
this.notNull = config2.notNull;
|
|
32059
|
-
this.default = config2.default;
|
|
32060
|
-
this.defaultFn = config2.defaultFn;
|
|
32061
|
-
this.onUpdateFn = config2.onUpdateFn;
|
|
32062
|
-
this.hasDefault = config2.hasDefault;
|
|
32063
|
-
this.primary = config2.primaryKey;
|
|
32064
|
-
this.isUnique = config2.isUnique;
|
|
32065
|
-
this.uniqueName = config2.uniqueName;
|
|
32066
|
-
this.uniqueType = config2.uniqueType;
|
|
32067
|
-
this.dataType = config2.dataType;
|
|
32068
|
-
this.columnType = config2.columnType;
|
|
32069
|
-
this.generated = config2.generated;
|
|
32070
|
-
this.generatedIdentity = config2.generatedIdentity;
|
|
32071
|
-
}
|
|
32072
|
-
static [entityKind] = "Column";
|
|
32073
|
-
name;
|
|
32074
|
-
keyAsName;
|
|
32075
|
-
primary;
|
|
32076
|
-
notNull;
|
|
32077
|
-
default;
|
|
32078
|
-
defaultFn;
|
|
32079
|
-
onUpdateFn;
|
|
32080
|
-
hasDefault;
|
|
32081
|
-
isUnique;
|
|
32082
|
-
uniqueName;
|
|
32083
|
-
uniqueType;
|
|
32084
|
-
dataType;
|
|
32085
|
-
columnType;
|
|
32086
|
-
enumValues = undefined;
|
|
32087
|
-
generated = undefined;
|
|
32088
|
-
generatedIdentity = undefined;
|
|
32089
|
-
config;
|
|
32090
|
-
mapFromDriverValue(value) {
|
|
32091
|
-
return value;
|
|
32092
|
-
}
|
|
32093
|
-
mapToDriverValue(value) {
|
|
32094
|
-
return value;
|
|
32095
|
-
}
|
|
32096
|
-
shouldDisableInsert() {
|
|
32097
|
-
return this.config.generated !== undefined && this.config.generated.type !== "byDefault";
|
|
32098
|
-
}
|
|
32099
|
-
}
|
|
32100
|
-
|
|
32101
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/column-builder.js
|
|
32102
|
-
class ColumnBuilder {
|
|
32103
|
-
static [entityKind] = "ColumnBuilder";
|
|
32104
|
-
config;
|
|
32105
|
-
constructor(name, dataType, columnType) {
|
|
32106
|
-
this.config = {
|
|
32107
|
-
name,
|
|
32108
|
-
keyAsName: name === "",
|
|
32109
|
-
notNull: false,
|
|
32110
|
-
default: undefined,
|
|
32111
|
-
hasDefault: false,
|
|
32112
|
-
primaryKey: false,
|
|
32113
|
-
isUnique: false,
|
|
32114
|
-
uniqueName: undefined,
|
|
32115
|
-
uniqueType: undefined,
|
|
32116
|
-
dataType,
|
|
32117
|
-
columnType,
|
|
32118
|
-
generated: undefined
|
|
32119
|
-
};
|
|
32120
|
-
}
|
|
32121
|
-
$type() {
|
|
32122
|
-
return this;
|
|
32123
|
-
}
|
|
32124
|
-
notNull() {
|
|
32125
|
-
this.config.notNull = true;
|
|
32126
|
-
return this;
|
|
32127
|
-
}
|
|
32128
|
-
default(value) {
|
|
32129
|
-
this.config.default = value;
|
|
32130
|
-
this.config.hasDefault = true;
|
|
32131
|
-
return this;
|
|
32132
|
-
}
|
|
32133
|
-
$defaultFn(fn) {
|
|
32134
|
-
this.config.defaultFn = fn;
|
|
32135
|
-
this.config.hasDefault = true;
|
|
32136
|
-
return this;
|
|
32137
|
-
}
|
|
32138
|
-
$default = this.$defaultFn;
|
|
32139
|
-
$onUpdateFn(fn) {
|
|
32140
|
-
this.config.onUpdateFn = fn;
|
|
32141
|
-
this.config.hasDefault = true;
|
|
32142
|
-
return this;
|
|
32143
|
-
}
|
|
32144
|
-
$onUpdate = this.$onUpdateFn;
|
|
32145
|
-
primaryKey() {
|
|
32146
|
-
this.config.primaryKey = true;
|
|
32147
|
-
this.config.notNull = true;
|
|
32148
|
-
return this;
|
|
32149
|
-
}
|
|
32150
|
-
setName(name) {
|
|
32151
|
-
if (this.config.name !== "")
|
|
32152
|
-
return;
|
|
32153
|
-
this.config.name = name;
|
|
32154
|
-
}
|
|
32155
|
-
}
|
|
32156
|
-
|
|
32157
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/table.utils.js
|
|
32158
|
-
var TableName = Symbol.for("drizzle:Name");
|
|
32159
|
-
|
|
32160
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/tracing-utils.js
|
|
32161
|
-
function iife(fn, ...args) {
|
|
32162
|
-
return fn(...args);
|
|
32163
|
-
}
|
|
32164
|
-
|
|
32165
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/pg-core/unique-constraint.js
|
|
32166
|
-
function uniqueKeyName(table, columns) {
|
|
32167
|
-
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
32168
|
-
}
|
|
32169
|
-
|
|
32170
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/pg-core/columns/common.js
|
|
32171
|
-
class PgColumn extends Column {
|
|
32172
|
-
constructor(table, config2) {
|
|
32173
|
-
if (!config2.uniqueName) {
|
|
32174
|
-
config2.uniqueName = uniqueKeyName(table, [config2.name]);
|
|
32175
|
-
}
|
|
32176
|
-
super(table, config2);
|
|
32177
|
-
this.table = table;
|
|
32178
|
-
}
|
|
32179
|
-
static [entityKind] = "PgColumn";
|
|
32180
|
-
}
|
|
32181
|
-
|
|
32182
|
-
class ExtraConfigColumn extends PgColumn {
|
|
32183
|
-
static [entityKind] = "ExtraConfigColumn";
|
|
32184
|
-
getSQLType() {
|
|
32185
|
-
return this.getSQLType();
|
|
32186
|
-
}
|
|
32187
|
-
indexConfig = {
|
|
32188
|
-
order: this.config.order ?? "asc",
|
|
32189
|
-
nulls: this.config.nulls ?? "last",
|
|
32190
|
-
opClass: this.config.opClass
|
|
32191
|
-
};
|
|
32192
|
-
defaultConfig = {
|
|
32193
|
-
order: "asc",
|
|
32194
|
-
nulls: "last",
|
|
32195
|
-
opClass: undefined
|
|
32196
|
-
};
|
|
32197
|
-
asc() {
|
|
32198
|
-
this.indexConfig.order = "asc";
|
|
32199
|
-
return this;
|
|
32200
|
-
}
|
|
32201
|
-
desc() {
|
|
32202
|
-
this.indexConfig.order = "desc";
|
|
32203
|
-
return this;
|
|
32204
|
-
}
|
|
32205
|
-
nullsFirst() {
|
|
32206
|
-
this.indexConfig.nulls = "first";
|
|
32207
|
-
return this;
|
|
32208
|
-
}
|
|
32209
|
-
nullsLast() {
|
|
32210
|
-
this.indexConfig.nulls = "last";
|
|
32211
|
-
return this;
|
|
32212
|
-
}
|
|
32213
|
-
op(opClass) {
|
|
32214
|
-
this.indexConfig.opClass = opClass;
|
|
32215
|
-
return this;
|
|
32216
|
-
}
|
|
32217
|
-
}
|
|
32218
|
-
|
|
32219
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/pg-core/columns/enum.js
|
|
32220
|
-
class PgEnumObjectColumn extends PgColumn {
|
|
32221
|
-
static [entityKind] = "PgEnumObjectColumn";
|
|
32222
|
-
enum;
|
|
32223
|
-
enumValues = this.config.enum.enumValues;
|
|
32224
|
-
constructor(table, config2) {
|
|
32225
|
-
super(table, config2);
|
|
32226
|
-
this.enum = config2.enum;
|
|
32227
|
-
}
|
|
32228
|
-
getSQLType() {
|
|
32229
|
-
return this.enum.enumName;
|
|
32230
|
-
}
|
|
32231
|
-
}
|
|
32232
|
-
var isPgEnumSym = Symbol.for("drizzle:isPgEnum");
|
|
32233
|
-
function isPgEnum(obj) {
|
|
32234
|
-
return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
|
|
32235
|
-
}
|
|
32236
|
-
class PgEnumColumn extends PgColumn {
|
|
32237
|
-
static [entityKind] = "PgEnumColumn";
|
|
32238
|
-
enum = this.config.enum;
|
|
32239
|
-
enumValues = this.config.enum.enumValues;
|
|
32240
|
-
constructor(table, config2) {
|
|
32241
|
-
super(table, config2);
|
|
32242
|
-
this.enum = config2.enum;
|
|
32243
|
-
}
|
|
32244
|
-
getSQLType() {
|
|
32245
|
-
return this.enum.enumName;
|
|
32246
|
-
}
|
|
32247
|
-
}
|
|
32248
|
-
|
|
32249
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/subquery.js
|
|
32250
|
-
class Subquery {
|
|
32251
|
-
static [entityKind] = "Subquery";
|
|
32252
|
-
constructor(sql, fields, alias, isWith = false, usedTables = []) {
|
|
32253
|
-
this._ = {
|
|
32254
|
-
brand: "Subquery",
|
|
32255
|
-
sql,
|
|
32256
|
-
selectedFields: fields,
|
|
32257
|
-
alias,
|
|
32258
|
-
isWith,
|
|
32259
|
-
usedTables
|
|
32260
|
-
};
|
|
32261
|
-
}
|
|
32262
|
-
}
|
|
32263
|
-
|
|
32264
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/version.js
|
|
32265
|
-
var version2 = "0.45.2";
|
|
32266
|
-
|
|
32267
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/tracing.js
|
|
32268
|
-
var otel;
|
|
32269
|
-
var rawTracer;
|
|
32270
|
-
var tracer = {
|
|
32271
|
-
startActiveSpan(name, fn) {
|
|
32272
|
-
if (!otel) {
|
|
32273
|
-
return fn();
|
|
32274
|
-
}
|
|
32275
|
-
if (!rawTracer) {
|
|
32276
|
-
rawTracer = otel.trace.getTracer("drizzle-orm", version2);
|
|
32277
|
-
}
|
|
32278
|
-
return iife((otel2, rawTracer2) => rawTracer2.startActiveSpan(name, (span) => {
|
|
32279
|
-
try {
|
|
32280
|
-
return fn(span);
|
|
32281
|
-
} catch (e) {
|
|
32282
|
-
span.setStatus({
|
|
32283
|
-
code: otel2.SpanStatusCode.ERROR,
|
|
32284
|
-
message: e instanceof Error ? e.message : "Unknown error"
|
|
32285
|
-
});
|
|
32286
|
-
throw e;
|
|
32287
|
-
} finally {
|
|
32288
|
-
span.end();
|
|
32289
|
-
}
|
|
32290
|
-
}), otel, rawTracer);
|
|
32291
|
-
}
|
|
32292
|
-
};
|
|
32293
|
-
|
|
32294
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/view-common.js
|
|
32295
|
-
var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
|
|
32296
|
-
|
|
32297
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/table.js
|
|
32298
|
-
var Schema = Symbol.for("drizzle:Schema");
|
|
32299
|
-
var Columns = Symbol.for("drizzle:Columns");
|
|
32300
|
-
var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
|
|
32301
|
-
var OriginalName = Symbol.for("drizzle:OriginalName");
|
|
32302
|
-
var BaseName = Symbol.for("drizzle:BaseName");
|
|
32303
|
-
var IsAlias = Symbol.for("drizzle:IsAlias");
|
|
32304
|
-
var ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
|
|
32305
|
-
var IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
|
|
32306
|
-
|
|
32307
|
-
class Table {
|
|
32308
|
-
static [entityKind] = "Table";
|
|
32309
|
-
static Symbol = {
|
|
32310
|
-
Name: TableName,
|
|
32311
|
-
Schema,
|
|
32312
|
-
OriginalName,
|
|
32313
|
-
Columns,
|
|
32314
|
-
ExtraConfigColumns,
|
|
32315
|
-
BaseName,
|
|
32316
|
-
IsAlias,
|
|
32317
|
-
ExtraConfigBuilder
|
|
32318
|
-
};
|
|
32319
|
-
[TableName];
|
|
32320
|
-
[OriginalName];
|
|
32321
|
-
[Schema];
|
|
32322
|
-
[Columns];
|
|
32323
|
-
[ExtraConfigColumns];
|
|
32324
|
-
[BaseName];
|
|
32325
|
-
[IsAlias] = false;
|
|
32326
|
-
[IsDrizzleTable] = true;
|
|
32327
|
-
[ExtraConfigBuilder] = undefined;
|
|
32328
|
-
constructor(name, schema, baseName) {
|
|
32329
|
-
this[TableName] = this[OriginalName] = name;
|
|
32330
|
-
this[Schema] = schema;
|
|
32331
|
-
this[BaseName] = baseName;
|
|
32332
|
-
}
|
|
32333
|
-
}
|
|
32334
|
-
|
|
32335
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sql/sql.js
|
|
32336
|
-
function isSQLWrapper(value) {
|
|
32337
|
-
return value !== null && value !== undefined && typeof value.getSQL === "function";
|
|
32338
|
-
}
|
|
32339
|
-
function mergeQueries(queries) {
|
|
32340
|
-
const result = { sql: "", params: [] };
|
|
32341
|
-
for (const query of queries) {
|
|
32342
|
-
result.sql += query.sql;
|
|
32343
|
-
result.params.push(...query.params);
|
|
32344
|
-
if (query.typings?.length) {
|
|
32345
|
-
if (!result.typings) {
|
|
32346
|
-
result.typings = [];
|
|
32347
|
-
}
|
|
32348
|
-
result.typings.push(...query.typings);
|
|
32349
|
-
}
|
|
32350
|
-
}
|
|
32351
|
-
return result;
|
|
32352
|
-
}
|
|
32353
|
-
|
|
32354
|
-
class StringChunk {
|
|
32355
|
-
static [entityKind] = "StringChunk";
|
|
32356
|
-
value;
|
|
32357
|
-
constructor(value) {
|
|
32358
|
-
this.value = Array.isArray(value) ? value : [value];
|
|
32359
|
-
}
|
|
32360
|
-
getSQL() {
|
|
32361
|
-
return new SQL([this]);
|
|
32362
|
-
}
|
|
32363
|
-
}
|
|
32364
|
-
|
|
32365
|
-
class SQL {
|
|
32366
|
-
constructor(queryChunks) {
|
|
32367
|
-
this.queryChunks = queryChunks;
|
|
32368
|
-
for (const chunk of queryChunks) {
|
|
32369
|
-
if (is(chunk, Table)) {
|
|
32370
|
-
const schemaName = chunk[Table.Symbol.Schema];
|
|
32371
|
-
this.usedTables.push(schemaName === undefined ? chunk[Table.Symbol.Name] : schemaName + "." + chunk[Table.Symbol.Name]);
|
|
32372
|
-
}
|
|
32373
|
-
}
|
|
32374
|
-
}
|
|
32375
|
-
static [entityKind] = "SQL";
|
|
32376
|
-
decoder = noopDecoder;
|
|
32377
|
-
shouldInlineParams = false;
|
|
32378
|
-
usedTables = [];
|
|
32379
|
-
append(query) {
|
|
32380
|
-
this.queryChunks.push(...query.queryChunks);
|
|
32381
|
-
return this;
|
|
32382
|
-
}
|
|
32383
|
-
toQuery(config2) {
|
|
32384
|
-
return tracer.startActiveSpan("drizzle.buildSQL", (span) => {
|
|
32385
|
-
const query = this.buildQueryFromSourceParams(this.queryChunks, config2);
|
|
32386
|
-
span?.setAttributes({
|
|
32387
|
-
"drizzle.query.text": query.sql,
|
|
32388
|
-
"drizzle.query.params": JSON.stringify(query.params)
|
|
32389
|
-
});
|
|
32390
|
-
return query;
|
|
32391
|
-
});
|
|
32392
|
-
}
|
|
32393
|
-
buildQueryFromSourceParams(chunks, _config) {
|
|
32394
|
-
const config2 = Object.assign({}, _config, {
|
|
32395
|
-
inlineParams: _config.inlineParams || this.shouldInlineParams,
|
|
32396
|
-
paramStartIndex: _config.paramStartIndex || { value: 0 }
|
|
32397
|
-
});
|
|
32398
|
-
const {
|
|
32399
|
-
casing,
|
|
32400
|
-
escapeName,
|
|
32401
|
-
escapeParam,
|
|
32402
|
-
prepareTyping,
|
|
32403
|
-
inlineParams,
|
|
32404
|
-
paramStartIndex
|
|
32405
|
-
} = config2;
|
|
32406
|
-
return mergeQueries(chunks.map((chunk) => {
|
|
32407
|
-
if (is(chunk, StringChunk)) {
|
|
32408
|
-
return { sql: chunk.value.join(""), params: [] };
|
|
32409
|
-
}
|
|
32410
|
-
if (is(chunk, Name)) {
|
|
32411
|
-
return { sql: escapeName(chunk.value), params: [] };
|
|
32412
|
-
}
|
|
32413
|
-
if (chunk === undefined) {
|
|
32414
|
-
return { sql: "", params: [] };
|
|
32415
|
-
}
|
|
32416
|
-
if (Array.isArray(chunk)) {
|
|
32417
|
-
const result = [new StringChunk("(")];
|
|
32418
|
-
for (const [i, p] of chunk.entries()) {
|
|
32419
|
-
result.push(p);
|
|
32420
|
-
if (i < chunk.length - 1) {
|
|
32421
|
-
result.push(new StringChunk(", "));
|
|
32422
|
-
}
|
|
32423
|
-
}
|
|
32424
|
-
result.push(new StringChunk(")"));
|
|
32425
|
-
return this.buildQueryFromSourceParams(result, config2);
|
|
32426
|
-
}
|
|
32427
|
-
if (is(chunk, SQL)) {
|
|
32428
|
-
return this.buildQueryFromSourceParams(chunk.queryChunks, {
|
|
32429
|
-
...config2,
|
|
32430
|
-
inlineParams: inlineParams || chunk.shouldInlineParams
|
|
32431
|
-
});
|
|
32432
|
-
}
|
|
32433
|
-
if (is(chunk, Table)) {
|
|
32434
|
-
const schemaName = chunk[Table.Symbol.Schema];
|
|
32435
|
-
const tableName = chunk[Table.Symbol.Name];
|
|
32436
|
-
return {
|
|
32437
|
-
sql: schemaName === undefined || chunk[IsAlias] ? escapeName(tableName) : escapeName(schemaName) + "." + escapeName(tableName),
|
|
32438
|
-
params: []
|
|
32439
|
-
};
|
|
32440
|
-
}
|
|
32441
|
-
if (is(chunk, Column)) {
|
|
32442
|
-
const columnName = casing.getColumnCasing(chunk);
|
|
32443
|
-
if (_config.invokeSource === "indexes") {
|
|
32444
|
-
return { sql: escapeName(columnName), params: [] };
|
|
32445
|
-
}
|
|
32446
|
-
const schemaName = chunk.table[Table.Symbol.Schema];
|
|
32447
|
-
return {
|
|
32448
|
-
sql: chunk.table[IsAlias] || schemaName === undefined ? escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName) : escapeName(schemaName) + "." + escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName),
|
|
32449
|
-
params: []
|
|
32450
|
-
};
|
|
32451
|
-
}
|
|
32452
|
-
if (is(chunk, View)) {
|
|
32453
|
-
const schemaName = chunk[ViewBaseConfig].schema;
|
|
32454
|
-
const viewName = chunk[ViewBaseConfig].name;
|
|
32455
|
-
return {
|
|
32456
|
-
sql: schemaName === undefined || chunk[ViewBaseConfig].isAlias ? escapeName(viewName) : escapeName(schemaName) + "." + escapeName(viewName),
|
|
32457
|
-
params: []
|
|
32458
|
-
};
|
|
32459
|
-
}
|
|
32460
|
-
if (is(chunk, Param)) {
|
|
32461
|
-
if (is(chunk.value, Placeholder)) {
|
|
32462
|
-
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
32463
|
-
}
|
|
32464
|
-
const mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);
|
|
32465
|
-
if (is(mappedValue, SQL)) {
|
|
32466
|
-
return this.buildQueryFromSourceParams([mappedValue], config2);
|
|
32467
|
-
}
|
|
32468
|
-
if (inlineParams) {
|
|
32469
|
-
return { sql: this.mapInlineParam(mappedValue, config2), params: [] };
|
|
32470
|
-
}
|
|
32471
|
-
let typings = ["none"];
|
|
32472
|
-
if (prepareTyping) {
|
|
32473
|
-
typings = [prepareTyping(chunk.encoder)];
|
|
32474
|
-
}
|
|
32475
|
-
return { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };
|
|
32476
|
-
}
|
|
32477
|
-
if (is(chunk, Placeholder)) {
|
|
32478
|
-
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
32479
|
-
}
|
|
32480
|
-
if (is(chunk, SQL.Aliased) && chunk.fieldAlias !== undefined) {
|
|
32481
|
-
return { sql: escapeName(chunk.fieldAlias), params: [] };
|
|
32482
|
-
}
|
|
32483
|
-
if (is(chunk, Subquery)) {
|
|
32484
|
-
if (chunk._.isWith) {
|
|
32485
|
-
return { sql: escapeName(chunk._.alias), params: [] };
|
|
32486
|
-
}
|
|
32487
|
-
return this.buildQueryFromSourceParams([
|
|
32488
|
-
new StringChunk("("),
|
|
32489
|
-
chunk._.sql,
|
|
32490
|
-
new StringChunk(") "),
|
|
32491
|
-
new Name(chunk._.alias)
|
|
32492
|
-
], config2);
|
|
32493
|
-
}
|
|
32494
|
-
if (isPgEnum(chunk)) {
|
|
32495
|
-
if (chunk.schema) {
|
|
32496
|
-
return { sql: escapeName(chunk.schema) + "." + escapeName(chunk.enumName), params: [] };
|
|
32497
|
-
}
|
|
32498
|
-
return { sql: escapeName(chunk.enumName), params: [] };
|
|
32499
|
-
}
|
|
32500
|
-
if (isSQLWrapper(chunk)) {
|
|
32501
|
-
if (chunk.shouldOmitSQLParens?.()) {
|
|
32502
|
-
return this.buildQueryFromSourceParams([chunk.getSQL()], config2);
|
|
32503
|
-
}
|
|
32504
|
-
return this.buildQueryFromSourceParams([
|
|
32505
|
-
new StringChunk("("),
|
|
32506
|
-
chunk.getSQL(),
|
|
32507
|
-
new StringChunk(")")
|
|
32508
|
-
], config2);
|
|
32509
|
-
}
|
|
32510
|
-
if (inlineParams) {
|
|
32511
|
-
return { sql: this.mapInlineParam(chunk, config2), params: [] };
|
|
32512
|
-
}
|
|
32513
|
-
return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
|
|
32514
|
-
}));
|
|
32515
|
-
}
|
|
32516
|
-
mapInlineParam(chunk, { escapeString }) {
|
|
32517
|
-
if (chunk === null) {
|
|
32518
|
-
return "null";
|
|
32519
|
-
}
|
|
32520
|
-
if (typeof chunk === "number" || typeof chunk === "boolean") {
|
|
32521
|
-
return chunk.toString();
|
|
32522
|
-
}
|
|
32523
|
-
if (typeof chunk === "string") {
|
|
32524
|
-
return escapeString(chunk);
|
|
32525
|
-
}
|
|
32526
|
-
if (typeof chunk === "object") {
|
|
32527
|
-
const mappedValueAsString = chunk.toString();
|
|
32528
|
-
if (mappedValueAsString === "[object Object]") {
|
|
32529
|
-
return escapeString(JSON.stringify(chunk));
|
|
32530
|
-
}
|
|
32531
|
-
return escapeString(mappedValueAsString);
|
|
32532
|
-
}
|
|
32533
|
-
throw new Error("Unexpected param value: " + chunk);
|
|
32534
|
-
}
|
|
32535
|
-
getSQL() {
|
|
32536
|
-
return this;
|
|
32537
|
-
}
|
|
32538
|
-
as(alias) {
|
|
32539
|
-
if (alias === undefined) {
|
|
32540
|
-
return this;
|
|
32541
|
-
}
|
|
32542
|
-
return new SQL.Aliased(this, alias);
|
|
32543
|
-
}
|
|
32544
|
-
mapWith(decoder) {
|
|
32545
|
-
this.decoder = typeof decoder === "function" ? { mapFromDriverValue: decoder } : decoder;
|
|
32546
|
-
return this;
|
|
32547
|
-
}
|
|
32548
|
-
inlineParams() {
|
|
32549
|
-
this.shouldInlineParams = true;
|
|
32550
|
-
return this;
|
|
32551
|
-
}
|
|
32552
|
-
if(condition) {
|
|
32553
|
-
return condition ? this : undefined;
|
|
32554
|
-
}
|
|
32555
|
-
}
|
|
32556
|
-
|
|
32557
|
-
class Name {
|
|
32558
|
-
constructor(value) {
|
|
32559
|
-
this.value = value;
|
|
32560
|
-
}
|
|
32561
|
-
static [entityKind] = "Name";
|
|
32562
|
-
brand;
|
|
32563
|
-
getSQL() {
|
|
32564
|
-
return new SQL([this]);
|
|
32565
|
-
}
|
|
32566
|
-
}
|
|
32567
|
-
var noopDecoder = {
|
|
32568
|
-
mapFromDriverValue: (value) => value
|
|
32569
|
-
};
|
|
32570
|
-
var noopEncoder = {
|
|
32571
|
-
mapToDriverValue: (value) => value
|
|
32572
|
-
};
|
|
32573
|
-
var noopMapper = {
|
|
32574
|
-
...noopDecoder,
|
|
32575
|
-
...noopEncoder
|
|
32576
|
-
};
|
|
32577
|
-
|
|
32578
|
-
class Param {
|
|
32579
|
-
constructor(value, encoder = noopEncoder) {
|
|
32580
|
-
this.value = value;
|
|
32581
|
-
this.encoder = encoder;
|
|
32582
|
-
}
|
|
32583
|
-
static [entityKind] = "Param";
|
|
32584
|
-
brand;
|
|
32585
|
-
getSQL() {
|
|
32586
|
-
return new SQL([this]);
|
|
32587
|
-
}
|
|
32588
|
-
}
|
|
32589
|
-
function sql(strings, ...params) {
|
|
32590
|
-
const queryChunks = [];
|
|
32591
|
-
if (params.length > 0 || strings.length > 0 && strings[0] !== "") {
|
|
32592
|
-
queryChunks.push(new StringChunk(strings[0]));
|
|
32593
|
-
}
|
|
32594
|
-
for (const [paramIndex, param2] of params.entries()) {
|
|
32595
|
-
queryChunks.push(param2, new StringChunk(strings[paramIndex + 1]));
|
|
32596
|
-
}
|
|
32597
|
-
return new SQL(queryChunks);
|
|
32598
|
-
}
|
|
32599
|
-
((sql2) => {
|
|
32600
|
-
function empty() {
|
|
32601
|
-
return new SQL([]);
|
|
32602
|
-
}
|
|
32603
|
-
sql2.empty = empty;
|
|
32604
|
-
function fromList(list) {
|
|
32605
|
-
return new SQL(list);
|
|
32606
|
-
}
|
|
32607
|
-
sql2.fromList = fromList;
|
|
32608
|
-
function raw(str) {
|
|
32609
|
-
return new SQL([new StringChunk(str)]);
|
|
32610
|
-
}
|
|
32611
|
-
sql2.raw = raw;
|
|
32612
|
-
function join18(chunks, separator) {
|
|
32613
|
-
const result = [];
|
|
32614
|
-
for (const [i, chunk] of chunks.entries()) {
|
|
32615
|
-
if (i > 0 && separator !== undefined) {
|
|
32616
|
-
result.push(separator);
|
|
32617
|
-
}
|
|
32618
|
-
result.push(chunk);
|
|
32619
|
-
}
|
|
32620
|
-
return new SQL(result);
|
|
32621
|
-
}
|
|
32622
|
-
sql2.join = join18;
|
|
32623
|
-
function identifier(value) {
|
|
32624
|
-
return new Name(value);
|
|
32625
|
-
}
|
|
32626
|
-
sql2.identifier = identifier;
|
|
32627
|
-
function placeholder2(name2) {
|
|
32628
|
-
return new Placeholder(name2);
|
|
32629
|
-
}
|
|
32630
|
-
sql2.placeholder = placeholder2;
|
|
32631
|
-
function param2(value, encoder) {
|
|
32632
|
-
return new Param(value, encoder);
|
|
32633
|
-
}
|
|
32634
|
-
sql2.param = param2;
|
|
32635
|
-
})(sql || (sql = {}));
|
|
32636
|
-
((SQL2) => {
|
|
32637
|
-
|
|
32638
|
-
class Aliased {
|
|
32639
|
-
constructor(sql2, fieldAlias) {
|
|
32640
|
-
this.sql = sql2;
|
|
32641
|
-
this.fieldAlias = fieldAlias;
|
|
32642
|
-
}
|
|
32643
|
-
static [entityKind] = "SQL.Aliased";
|
|
32644
|
-
isSelectionField = false;
|
|
32645
|
-
getSQL() {
|
|
32646
|
-
return this.sql;
|
|
32647
|
-
}
|
|
32648
|
-
clone() {
|
|
32649
|
-
return new Aliased(this.sql, this.fieldAlias);
|
|
32650
|
-
}
|
|
32651
|
-
}
|
|
32652
|
-
SQL2.Aliased = Aliased;
|
|
32653
|
-
})(SQL || (SQL = {}));
|
|
32654
|
-
|
|
32655
|
-
class Placeholder {
|
|
32656
|
-
constructor(name2) {
|
|
32657
|
-
this.name = name2;
|
|
32658
|
-
}
|
|
32659
|
-
static [entityKind] = "Placeholder";
|
|
32660
|
-
getSQL() {
|
|
32661
|
-
return new SQL([this]);
|
|
32662
|
-
}
|
|
32663
|
-
}
|
|
32664
|
-
var IsDrizzleView = Symbol.for("drizzle:IsDrizzleView");
|
|
32665
|
-
|
|
32666
|
-
class View {
|
|
32667
|
-
static [entityKind] = "View";
|
|
32668
|
-
[ViewBaseConfig];
|
|
32669
|
-
[IsDrizzleView] = true;
|
|
32670
|
-
constructor({ name: name2, schema, selectedFields, query }) {
|
|
32671
|
-
this[ViewBaseConfig] = {
|
|
32672
|
-
name: name2,
|
|
32673
|
-
originalName: name2,
|
|
32674
|
-
schema,
|
|
32675
|
-
selectedFields,
|
|
32676
|
-
query,
|
|
32677
|
-
isExisting: !query,
|
|
32678
|
-
isAlias: false
|
|
32679
|
-
};
|
|
32680
|
-
}
|
|
32681
|
-
getSQL() {
|
|
32682
|
-
return new SQL([this]);
|
|
32683
|
-
}
|
|
32684
|
-
}
|
|
32685
|
-
Column.prototype.getSQL = function() {
|
|
32686
|
-
return new SQL([this]);
|
|
32687
|
-
};
|
|
32688
|
-
Table.prototype.getSQL = function() {
|
|
32689
|
-
return new SQL([this]);
|
|
32690
|
-
};
|
|
32691
|
-
Subquery.prototype.getSQL = function() {
|
|
32692
|
-
return new SQL([this]);
|
|
32693
|
-
};
|
|
32694
|
-
|
|
32695
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/utils.js
|
|
32696
|
-
function getColumnNameAndConfig(a, b) {
|
|
32697
|
-
return {
|
|
32698
|
-
name: typeof a === "string" && a.length > 0 ? a : "",
|
|
32699
|
-
config: typeof a === "object" ? a : b
|
|
32700
|
-
};
|
|
32701
|
-
}
|
|
32702
|
-
var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
|
|
32703
|
-
|
|
32704
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
|
|
32705
|
-
class ForeignKeyBuilder {
|
|
32706
|
-
static [entityKind] = "SQLiteForeignKeyBuilder";
|
|
32707
|
-
reference;
|
|
32708
|
-
_onUpdate;
|
|
32709
|
-
_onDelete;
|
|
32710
|
-
constructor(config2, actions) {
|
|
32711
|
-
this.reference = () => {
|
|
32712
|
-
const { name, columns, foreignColumns } = config2();
|
|
32713
|
-
return { name, columns, foreignTable: foreignColumns[0].table, foreignColumns };
|
|
32714
|
-
};
|
|
32715
|
-
if (actions) {
|
|
32716
|
-
this._onUpdate = actions.onUpdate;
|
|
32717
|
-
this._onDelete = actions.onDelete;
|
|
32718
|
-
}
|
|
32719
|
-
}
|
|
32720
|
-
onUpdate(action) {
|
|
32721
|
-
this._onUpdate = action;
|
|
32722
|
-
return this;
|
|
32723
|
-
}
|
|
32724
|
-
onDelete(action) {
|
|
32725
|
-
this._onDelete = action;
|
|
32726
|
-
return this;
|
|
32727
|
-
}
|
|
32728
|
-
build(table) {
|
|
32729
|
-
return new ForeignKey(table, this);
|
|
32730
|
-
}
|
|
32731
|
-
}
|
|
32732
|
-
|
|
32733
|
-
class ForeignKey {
|
|
32734
|
-
constructor(table, builder) {
|
|
32735
|
-
this.table = table;
|
|
32736
|
-
this.reference = builder.reference;
|
|
32737
|
-
this.onUpdate = builder._onUpdate;
|
|
32738
|
-
this.onDelete = builder._onDelete;
|
|
32739
|
-
}
|
|
32740
|
-
static [entityKind] = "SQLiteForeignKey";
|
|
32741
|
-
reference;
|
|
32742
|
-
onUpdate;
|
|
32743
|
-
onDelete;
|
|
32744
|
-
getName() {
|
|
32745
|
-
const { name, columns, foreignColumns } = this.reference();
|
|
32746
|
-
const columnNames = columns.map((column) => column.name);
|
|
32747
|
-
const foreignColumnNames = foreignColumns.map((column) => column.name);
|
|
32748
|
-
const chunks = [
|
|
32749
|
-
this.table[TableName],
|
|
32750
|
-
...columnNames,
|
|
32751
|
-
foreignColumns[0].table[TableName],
|
|
32752
|
-
...foreignColumnNames
|
|
32753
|
-
];
|
|
32754
|
-
return name ?? `${chunks.join("_")}_fk`;
|
|
32755
|
-
}
|
|
32756
|
-
}
|
|
32757
|
-
|
|
32758
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
|
|
32759
|
-
function uniqueKeyName2(table, columns) {
|
|
32760
|
-
return `${table[TableName]}_${columns.join("_")}_unique`;
|
|
32761
|
-
}
|
|
32762
|
-
|
|
32763
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/common.js
|
|
32764
|
-
class SQLiteColumnBuilder extends ColumnBuilder {
|
|
32765
|
-
static [entityKind] = "SQLiteColumnBuilder";
|
|
32766
|
-
foreignKeyConfigs = [];
|
|
32767
|
-
references(ref, actions = {}) {
|
|
32768
|
-
this.foreignKeyConfigs.push({ ref, actions });
|
|
32769
|
-
return this;
|
|
32770
|
-
}
|
|
32771
|
-
unique(name) {
|
|
32772
|
-
this.config.isUnique = true;
|
|
32773
|
-
this.config.uniqueName = name;
|
|
32774
|
-
return this;
|
|
32775
|
-
}
|
|
32776
|
-
generatedAlwaysAs(as, config2) {
|
|
32777
|
-
this.config.generated = {
|
|
32778
|
-
as,
|
|
32779
|
-
type: "always",
|
|
32780
|
-
mode: config2?.mode ?? "virtual"
|
|
32781
|
-
};
|
|
32782
|
-
return this;
|
|
32783
|
-
}
|
|
32784
|
-
buildForeignKeys(column, table) {
|
|
32785
|
-
return this.foreignKeyConfigs.map(({ ref, actions }) => {
|
|
32786
|
-
return ((ref2, actions2) => {
|
|
32787
|
-
const builder = new ForeignKeyBuilder(() => {
|
|
32788
|
-
const foreignColumn = ref2();
|
|
32789
|
-
return { columns: [column], foreignColumns: [foreignColumn] };
|
|
32790
|
-
});
|
|
32791
|
-
if (actions2.onUpdate) {
|
|
32792
|
-
builder.onUpdate(actions2.onUpdate);
|
|
32793
|
-
}
|
|
32794
|
-
if (actions2.onDelete) {
|
|
32795
|
-
builder.onDelete(actions2.onDelete);
|
|
32796
|
-
}
|
|
32797
|
-
return builder.build(table);
|
|
32798
|
-
})(ref, actions);
|
|
32799
|
-
});
|
|
32800
|
-
}
|
|
32801
|
-
}
|
|
32802
|
-
|
|
32803
|
-
class SQLiteColumn extends Column {
|
|
32804
|
-
constructor(table, config2) {
|
|
32805
|
-
if (!config2.uniqueName) {
|
|
32806
|
-
config2.uniqueName = uniqueKeyName2(table, [config2.name]);
|
|
32807
|
-
}
|
|
32808
|
-
super(table, config2);
|
|
32809
|
-
this.table = table;
|
|
32810
|
-
}
|
|
32811
|
-
static [entityKind] = "SQLiteColumn";
|
|
32812
|
-
}
|
|
32813
|
-
|
|
32814
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/blob.js
|
|
32815
|
-
class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
|
|
32816
|
-
static [entityKind] = "SQLiteBigIntBuilder";
|
|
32817
|
-
constructor(name) {
|
|
32818
|
-
super(name, "bigint", "SQLiteBigInt");
|
|
32819
|
-
}
|
|
32820
|
-
build(table) {
|
|
32821
|
-
return new SQLiteBigInt(table, this.config);
|
|
32822
|
-
}
|
|
32823
|
-
}
|
|
32824
|
-
|
|
32825
|
-
class SQLiteBigInt extends SQLiteColumn {
|
|
32826
|
-
static [entityKind] = "SQLiteBigInt";
|
|
32827
|
-
getSQLType() {
|
|
32828
|
-
return "blob";
|
|
32829
|
-
}
|
|
32830
|
-
mapFromDriverValue(value) {
|
|
32831
|
-
if (typeof Buffer !== "undefined" && Buffer.from) {
|
|
32832
|
-
const buf = Buffer.isBuffer(value) ? value : value instanceof ArrayBuffer ? Buffer.from(value) : value.buffer ? Buffer.from(value.buffer, value.byteOffset, value.byteLength) : Buffer.from(value);
|
|
32833
|
-
return BigInt(buf.toString("utf8"));
|
|
32834
|
-
}
|
|
32835
|
-
return BigInt(textDecoder.decode(value));
|
|
32836
|
-
}
|
|
32837
|
-
mapToDriverValue(value) {
|
|
32838
|
-
return Buffer.from(value.toString());
|
|
32839
|
-
}
|
|
32840
|
-
}
|
|
32841
|
-
|
|
32842
|
-
class SQLiteBlobJsonBuilder extends SQLiteColumnBuilder {
|
|
32843
|
-
static [entityKind] = "SQLiteBlobJsonBuilder";
|
|
32844
|
-
constructor(name) {
|
|
32845
|
-
super(name, "json", "SQLiteBlobJson");
|
|
32846
|
-
}
|
|
32847
|
-
build(table) {
|
|
32848
|
-
return new SQLiteBlobJson(table, this.config);
|
|
32849
|
-
}
|
|
32850
|
-
}
|
|
32851
|
-
|
|
32852
|
-
class SQLiteBlobJson extends SQLiteColumn {
|
|
32853
|
-
static [entityKind] = "SQLiteBlobJson";
|
|
32854
|
-
getSQLType() {
|
|
32855
|
-
return "blob";
|
|
32856
|
-
}
|
|
32857
|
-
mapFromDriverValue(value) {
|
|
32858
|
-
if (typeof Buffer !== "undefined" && Buffer.from) {
|
|
32859
|
-
const buf = Buffer.isBuffer(value) ? value : value instanceof ArrayBuffer ? Buffer.from(value) : value.buffer ? Buffer.from(value.buffer, value.byteOffset, value.byteLength) : Buffer.from(value);
|
|
32860
|
-
return JSON.parse(buf.toString("utf8"));
|
|
32861
|
-
}
|
|
32862
|
-
return JSON.parse(textDecoder.decode(value));
|
|
32863
|
-
}
|
|
32864
|
-
mapToDriverValue(value) {
|
|
32865
|
-
return Buffer.from(JSON.stringify(value));
|
|
32866
|
-
}
|
|
32867
|
-
}
|
|
32868
|
-
|
|
32869
|
-
class SQLiteBlobBufferBuilder extends SQLiteColumnBuilder {
|
|
32870
|
-
static [entityKind] = "SQLiteBlobBufferBuilder";
|
|
32871
|
-
constructor(name) {
|
|
32872
|
-
super(name, "buffer", "SQLiteBlobBuffer");
|
|
32873
|
-
}
|
|
32874
|
-
build(table) {
|
|
32875
|
-
return new SQLiteBlobBuffer(table, this.config);
|
|
32876
|
-
}
|
|
32877
|
-
}
|
|
32878
|
-
|
|
32879
|
-
class SQLiteBlobBuffer extends SQLiteColumn {
|
|
32880
|
-
static [entityKind] = "SQLiteBlobBuffer";
|
|
32881
|
-
mapFromDriverValue(value) {
|
|
32882
|
-
if (Buffer.isBuffer(value)) {
|
|
32883
|
-
return value;
|
|
32884
|
-
}
|
|
32885
|
-
return Buffer.from(value);
|
|
32886
|
-
}
|
|
32887
|
-
getSQLType() {
|
|
32888
|
-
return "blob";
|
|
32889
|
-
}
|
|
32890
|
-
}
|
|
32891
|
-
function blob(a, b) {
|
|
32892
|
-
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
32893
|
-
if (config2?.mode === "json") {
|
|
32894
|
-
return new SQLiteBlobJsonBuilder(name);
|
|
32895
|
-
}
|
|
32896
|
-
if (config2?.mode === "bigint") {
|
|
32897
|
-
return new SQLiteBigIntBuilder(name);
|
|
32898
|
-
}
|
|
32899
|
-
return new SQLiteBlobBufferBuilder(name);
|
|
32900
|
-
}
|
|
32901
|
-
|
|
32902
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/custom.js
|
|
32903
|
-
class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
|
|
32904
|
-
static [entityKind] = "SQLiteCustomColumnBuilder";
|
|
32905
|
-
constructor(name, fieldConfig, customTypeParams) {
|
|
32906
|
-
super(name, "custom", "SQLiteCustomColumn");
|
|
32907
|
-
this.config.fieldConfig = fieldConfig;
|
|
32908
|
-
this.config.customTypeParams = customTypeParams;
|
|
32909
|
-
}
|
|
32910
|
-
build(table) {
|
|
32911
|
-
return new SQLiteCustomColumn(table, this.config);
|
|
32912
|
-
}
|
|
32913
|
-
}
|
|
32914
|
-
|
|
32915
|
-
class SQLiteCustomColumn extends SQLiteColumn {
|
|
32916
|
-
static [entityKind] = "SQLiteCustomColumn";
|
|
32917
|
-
sqlName;
|
|
32918
|
-
mapTo;
|
|
32919
|
-
mapFrom;
|
|
32920
|
-
constructor(table, config2) {
|
|
32921
|
-
super(table, config2);
|
|
32922
|
-
this.sqlName = config2.customTypeParams.dataType(config2.fieldConfig);
|
|
32923
|
-
this.mapTo = config2.customTypeParams.toDriver;
|
|
32924
|
-
this.mapFrom = config2.customTypeParams.fromDriver;
|
|
32925
|
-
}
|
|
32926
|
-
getSQLType() {
|
|
32927
|
-
return this.sqlName;
|
|
32928
|
-
}
|
|
32929
|
-
mapFromDriverValue(value) {
|
|
32930
|
-
return typeof this.mapFrom === "function" ? this.mapFrom(value) : value;
|
|
32931
|
-
}
|
|
32932
|
-
mapToDriverValue(value) {
|
|
32933
|
-
return typeof this.mapTo === "function" ? this.mapTo(value) : value;
|
|
32934
|
-
}
|
|
32935
|
-
}
|
|
32936
|
-
function customType(customTypeParams) {
|
|
32937
|
-
return (a, b) => {
|
|
32938
|
-
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
32939
|
-
return new SQLiteCustomColumnBuilder(name, config2, customTypeParams);
|
|
32940
|
-
};
|
|
32941
|
-
}
|
|
32942
|
-
|
|
32943
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/integer.js
|
|
32944
|
-
class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
|
|
32945
|
-
static [entityKind] = "SQLiteBaseIntegerBuilder";
|
|
32946
|
-
constructor(name, dataType, columnType) {
|
|
32947
|
-
super(name, dataType, columnType);
|
|
32948
|
-
this.config.autoIncrement = false;
|
|
32949
|
-
}
|
|
32950
|
-
primaryKey(config2) {
|
|
32951
|
-
if (config2?.autoIncrement) {
|
|
32952
|
-
this.config.autoIncrement = true;
|
|
32953
|
-
}
|
|
32954
|
-
this.config.hasDefault = true;
|
|
32955
|
-
return super.primaryKey();
|
|
32956
|
-
}
|
|
32957
|
-
}
|
|
32958
|
-
|
|
32959
|
-
class SQLiteBaseInteger extends SQLiteColumn {
|
|
32960
|
-
static [entityKind] = "SQLiteBaseInteger";
|
|
32961
|
-
autoIncrement = this.config.autoIncrement;
|
|
32962
|
-
getSQLType() {
|
|
32963
|
-
return "integer";
|
|
32964
|
-
}
|
|
32965
|
-
}
|
|
32966
|
-
|
|
32967
|
-
class SQLiteIntegerBuilder extends SQLiteBaseIntegerBuilder {
|
|
32968
|
-
static [entityKind] = "SQLiteIntegerBuilder";
|
|
32969
|
-
constructor(name) {
|
|
32970
|
-
super(name, "number", "SQLiteInteger");
|
|
32971
|
-
}
|
|
32972
|
-
build(table) {
|
|
32973
|
-
return new SQLiteInteger(table, this.config);
|
|
32974
|
-
}
|
|
32975
|
-
}
|
|
32976
|
-
|
|
32977
|
-
class SQLiteInteger extends SQLiteBaseInteger {
|
|
32978
|
-
static [entityKind] = "SQLiteInteger";
|
|
32979
|
-
}
|
|
32980
|
-
|
|
32981
|
-
class SQLiteTimestampBuilder extends SQLiteBaseIntegerBuilder {
|
|
32982
|
-
static [entityKind] = "SQLiteTimestampBuilder";
|
|
32983
|
-
constructor(name, mode) {
|
|
32984
|
-
super(name, "date", "SQLiteTimestamp");
|
|
32985
|
-
this.config.mode = mode;
|
|
32986
|
-
}
|
|
32987
|
-
defaultNow() {
|
|
32988
|
-
return this.default(sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`);
|
|
32989
|
-
}
|
|
32990
|
-
build(table) {
|
|
32991
|
-
return new SQLiteTimestamp(table, this.config);
|
|
32992
|
-
}
|
|
32993
|
-
}
|
|
32994
|
-
|
|
32995
|
-
class SQLiteTimestamp extends SQLiteBaseInteger {
|
|
32996
|
-
static [entityKind] = "SQLiteTimestamp";
|
|
32997
|
-
mode = this.config.mode;
|
|
32998
|
-
mapFromDriverValue(value) {
|
|
32999
|
-
if (this.config.mode === "timestamp") {
|
|
33000
|
-
return new Date(value * 1000);
|
|
33001
|
-
}
|
|
33002
|
-
return new Date(value);
|
|
33003
|
-
}
|
|
33004
|
-
mapToDriverValue(value) {
|
|
33005
|
-
const unix = value.getTime();
|
|
33006
|
-
if (this.config.mode === "timestamp") {
|
|
33007
|
-
return Math.floor(unix / 1000);
|
|
33008
|
-
}
|
|
33009
|
-
return unix;
|
|
33010
|
-
}
|
|
33011
|
-
}
|
|
33012
|
-
|
|
33013
|
-
class SQLiteBooleanBuilder extends SQLiteBaseIntegerBuilder {
|
|
33014
|
-
static [entityKind] = "SQLiteBooleanBuilder";
|
|
33015
|
-
constructor(name, mode) {
|
|
33016
|
-
super(name, "boolean", "SQLiteBoolean");
|
|
33017
|
-
this.config.mode = mode;
|
|
33018
|
-
}
|
|
33019
|
-
build(table) {
|
|
33020
|
-
return new SQLiteBoolean(table, this.config);
|
|
33021
|
-
}
|
|
33022
|
-
}
|
|
33023
|
-
|
|
33024
|
-
class SQLiteBoolean extends SQLiteBaseInteger {
|
|
33025
|
-
static [entityKind] = "SQLiteBoolean";
|
|
33026
|
-
mode = this.config.mode;
|
|
33027
|
-
mapFromDriverValue(value) {
|
|
33028
|
-
return Number(value) === 1;
|
|
33029
|
-
}
|
|
33030
|
-
mapToDriverValue(value) {
|
|
33031
|
-
return value ? 1 : 0;
|
|
33032
|
-
}
|
|
33033
|
-
}
|
|
33034
|
-
function integer2(a, b) {
|
|
33035
|
-
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
33036
|
-
if (config2?.mode === "timestamp" || config2?.mode === "timestamp_ms") {
|
|
33037
|
-
return new SQLiteTimestampBuilder(name, config2.mode);
|
|
33038
|
-
}
|
|
33039
|
-
if (config2?.mode === "boolean") {
|
|
33040
|
-
return new SQLiteBooleanBuilder(name, config2.mode);
|
|
33041
|
-
}
|
|
33042
|
-
return new SQLiteIntegerBuilder(name);
|
|
33043
|
-
}
|
|
33044
|
-
|
|
33045
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
|
|
33046
|
-
class SQLiteNumericBuilder extends SQLiteColumnBuilder {
|
|
33047
|
-
static [entityKind] = "SQLiteNumericBuilder";
|
|
33048
|
-
constructor(name) {
|
|
33049
|
-
super(name, "string", "SQLiteNumeric");
|
|
33050
|
-
}
|
|
33051
|
-
build(table) {
|
|
33052
|
-
return new SQLiteNumeric(table, this.config);
|
|
33053
|
-
}
|
|
33054
|
-
}
|
|
33055
|
-
|
|
33056
|
-
class SQLiteNumeric extends SQLiteColumn {
|
|
33057
|
-
static [entityKind] = "SQLiteNumeric";
|
|
33058
|
-
mapFromDriverValue(value) {
|
|
33059
|
-
if (typeof value === "string")
|
|
33060
|
-
return value;
|
|
33061
|
-
return String(value);
|
|
33062
|
-
}
|
|
33063
|
-
getSQLType() {
|
|
33064
|
-
return "numeric";
|
|
33065
|
-
}
|
|
33066
|
-
}
|
|
33067
|
-
|
|
33068
|
-
class SQLiteNumericNumberBuilder extends SQLiteColumnBuilder {
|
|
33069
|
-
static [entityKind] = "SQLiteNumericNumberBuilder";
|
|
33070
|
-
constructor(name) {
|
|
33071
|
-
super(name, "number", "SQLiteNumericNumber");
|
|
33072
|
-
}
|
|
33073
|
-
build(table) {
|
|
33074
|
-
return new SQLiteNumericNumber(table, this.config);
|
|
33075
|
-
}
|
|
33076
|
-
}
|
|
33077
|
-
|
|
33078
|
-
class SQLiteNumericNumber extends SQLiteColumn {
|
|
33079
|
-
static [entityKind] = "SQLiteNumericNumber";
|
|
33080
|
-
mapFromDriverValue(value) {
|
|
33081
|
-
if (typeof value === "number")
|
|
33082
|
-
return value;
|
|
33083
|
-
return Number(value);
|
|
33084
|
-
}
|
|
33085
|
-
mapToDriverValue = String;
|
|
33086
|
-
getSQLType() {
|
|
33087
|
-
return "numeric";
|
|
33088
|
-
}
|
|
33089
|
-
}
|
|
33090
|
-
|
|
33091
|
-
class SQLiteNumericBigIntBuilder extends SQLiteColumnBuilder {
|
|
33092
|
-
static [entityKind] = "SQLiteNumericBigIntBuilder";
|
|
33093
|
-
constructor(name) {
|
|
33094
|
-
super(name, "bigint", "SQLiteNumericBigInt");
|
|
33095
|
-
}
|
|
33096
|
-
build(table) {
|
|
33097
|
-
return new SQLiteNumericBigInt(table, this.config);
|
|
33098
|
-
}
|
|
33099
|
-
}
|
|
33100
|
-
|
|
33101
|
-
class SQLiteNumericBigInt extends SQLiteColumn {
|
|
33102
|
-
static [entityKind] = "SQLiteNumericBigInt";
|
|
33103
|
-
mapFromDriverValue = BigInt;
|
|
33104
|
-
mapToDriverValue = String;
|
|
33105
|
-
getSQLType() {
|
|
33106
|
-
return "numeric";
|
|
33107
|
-
}
|
|
33108
|
-
}
|
|
33109
|
-
function numeric(a, b) {
|
|
33110
|
-
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
33111
|
-
const mode = config2?.mode;
|
|
33112
|
-
return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
|
|
33113
|
-
}
|
|
33114
|
-
|
|
33115
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/real.js
|
|
33116
|
-
class SQLiteRealBuilder extends SQLiteColumnBuilder {
|
|
33117
|
-
static [entityKind] = "SQLiteRealBuilder";
|
|
33118
|
-
constructor(name) {
|
|
33119
|
-
super(name, "number", "SQLiteReal");
|
|
33120
|
-
}
|
|
33121
|
-
build(table) {
|
|
33122
|
-
return new SQLiteReal(table, this.config);
|
|
33123
|
-
}
|
|
33124
|
-
}
|
|
33125
|
-
|
|
33126
|
-
class SQLiteReal extends SQLiteColumn {
|
|
33127
|
-
static [entityKind] = "SQLiteReal";
|
|
33128
|
-
getSQLType() {
|
|
33129
|
-
return "real";
|
|
33130
|
-
}
|
|
33131
|
-
}
|
|
33132
|
-
function real(name) {
|
|
33133
|
-
return new SQLiteRealBuilder(name ?? "");
|
|
33134
|
-
}
|
|
33135
|
-
|
|
33136
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/text.js
|
|
33137
|
-
class SQLiteTextBuilder extends SQLiteColumnBuilder {
|
|
33138
|
-
static [entityKind] = "SQLiteTextBuilder";
|
|
33139
|
-
constructor(name, config2) {
|
|
33140
|
-
super(name, "string", "SQLiteText");
|
|
33141
|
-
this.config.enumValues = config2.enum;
|
|
33142
|
-
this.config.length = config2.length;
|
|
33143
|
-
}
|
|
33144
|
-
build(table) {
|
|
33145
|
-
return new SQLiteText(table, this.config);
|
|
33146
|
-
}
|
|
33147
|
-
}
|
|
33148
|
-
|
|
33149
|
-
class SQLiteText extends SQLiteColumn {
|
|
33150
|
-
static [entityKind] = "SQLiteText";
|
|
33151
|
-
enumValues = this.config.enumValues;
|
|
33152
|
-
length = this.config.length;
|
|
33153
|
-
constructor(table, config2) {
|
|
33154
|
-
super(table, config2);
|
|
33155
|
-
}
|
|
33156
|
-
getSQLType() {
|
|
33157
|
-
return `text${this.config.length ? `(${this.config.length})` : ""}`;
|
|
33158
|
-
}
|
|
33159
|
-
}
|
|
33160
|
-
|
|
33161
|
-
class SQLiteTextJsonBuilder extends SQLiteColumnBuilder {
|
|
33162
|
-
static [entityKind] = "SQLiteTextJsonBuilder";
|
|
33163
|
-
constructor(name) {
|
|
33164
|
-
super(name, "json", "SQLiteTextJson");
|
|
33165
|
-
}
|
|
33166
|
-
build(table) {
|
|
33167
|
-
return new SQLiteTextJson(table, this.config);
|
|
33168
|
-
}
|
|
33169
|
-
}
|
|
33170
|
-
|
|
33171
|
-
class SQLiteTextJson extends SQLiteColumn {
|
|
33172
|
-
static [entityKind] = "SQLiteTextJson";
|
|
33173
|
-
getSQLType() {
|
|
33174
|
-
return "text";
|
|
33175
|
-
}
|
|
33176
|
-
mapFromDriverValue(value) {
|
|
33177
|
-
return JSON.parse(value);
|
|
33178
|
-
}
|
|
33179
|
-
mapToDriverValue(value) {
|
|
33180
|
-
return JSON.stringify(value);
|
|
33181
|
-
}
|
|
33182
|
-
}
|
|
33183
|
-
function text(a, b = {}) {
|
|
33184
|
-
const { name, config: config2 } = getColumnNameAndConfig(a, b);
|
|
33185
|
-
if (config2.mode === "json") {
|
|
33186
|
-
return new SQLiteTextJsonBuilder(name);
|
|
33187
|
-
}
|
|
33188
|
-
return new SQLiteTextBuilder(name, config2);
|
|
33189
|
-
}
|
|
33190
|
-
|
|
33191
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/all.js
|
|
33192
|
-
function getSQLiteColumnBuilders() {
|
|
33193
|
-
return {
|
|
33194
|
-
blob,
|
|
33195
|
-
customType,
|
|
33196
|
-
integer: integer2,
|
|
33197
|
-
numeric,
|
|
33198
|
-
real,
|
|
33199
|
-
text
|
|
33200
|
-
};
|
|
33201
|
-
}
|
|
33202
|
-
|
|
33203
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/table.js
|
|
33204
|
-
var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
|
|
33205
|
-
|
|
33206
|
-
class SQLiteTable extends Table {
|
|
33207
|
-
static [entityKind] = "SQLiteTable";
|
|
33208
|
-
static Symbol = Object.assign({}, Table.Symbol, {
|
|
33209
|
-
InlineForeignKeys
|
|
33210
|
-
});
|
|
33211
|
-
[Table.Symbol.Columns];
|
|
33212
|
-
[InlineForeignKeys] = [];
|
|
33213
|
-
[Table.Symbol.ExtraConfigBuilder] = undefined;
|
|
33214
|
-
}
|
|
33215
|
-
function sqliteTableBase(name, columns, extraConfig, schema, baseName = name) {
|
|
33216
|
-
const rawTable = new SQLiteTable(name, schema, baseName);
|
|
33217
|
-
const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
|
|
33218
|
-
const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name2, colBuilderBase]) => {
|
|
33219
|
-
const colBuilder = colBuilderBase;
|
|
33220
|
-
colBuilder.setName(name2);
|
|
33221
|
-
const column = colBuilder.build(rawTable);
|
|
33222
|
-
rawTable[InlineForeignKeys].push(...colBuilder.buildForeignKeys(column, rawTable));
|
|
33223
|
-
return [name2, column];
|
|
33224
|
-
}));
|
|
33225
|
-
const table = Object.assign(rawTable, builtColumns);
|
|
33226
|
-
table[Table.Symbol.Columns] = builtColumns;
|
|
33227
|
-
table[Table.Symbol.ExtraConfigColumns] = builtColumns;
|
|
33228
|
-
if (extraConfig) {
|
|
33229
|
-
table[SQLiteTable.Symbol.ExtraConfigBuilder] = extraConfig;
|
|
33230
|
-
}
|
|
33231
|
-
return table;
|
|
33232
|
-
}
|
|
33233
|
-
var sqliteTable = (name, columns, extraConfig) => {
|
|
33234
|
-
return sqliteTableBase(name, columns, extraConfig);
|
|
33235
|
-
};
|
|
33236
|
-
|
|
33237
|
-
// ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/indexes.js
|
|
33238
|
-
class IndexBuilderOn {
|
|
33239
|
-
constructor(name, unique2) {
|
|
33240
|
-
this.name = name;
|
|
33241
|
-
this.unique = unique2;
|
|
33242
|
-
}
|
|
33243
|
-
static [entityKind] = "SQLiteIndexBuilderOn";
|
|
33244
|
-
on(...columns) {
|
|
33245
|
-
return new IndexBuilder(this.name, columns, this.unique);
|
|
33246
|
-
}
|
|
33247
|
-
}
|
|
33248
|
-
|
|
33249
|
-
class IndexBuilder {
|
|
33250
|
-
static [entityKind] = "SQLiteIndexBuilder";
|
|
33251
|
-
config;
|
|
33252
|
-
constructor(name, columns, unique2) {
|
|
33253
|
-
this.config = {
|
|
33254
|
-
name,
|
|
33255
|
-
columns,
|
|
33256
|
-
unique: unique2,
|
|
33257
|
-
where: undefined
|
|
33258
|
-
};
|
|
33259
|
-
}
|
|
33260
|
-
where(condition) {
|
|
33261
|
-
this.config.where = condition;
|
|
33262
|
-
return this;
|
|
33263
|
-
}
|
|
33264
|
-
build(table) {
|
|
33265
|
-
return new Index(this.config, table);
|
|
33266
|
-
}
|
|
33267
|
-
}
|
|
33268
|
-
|
|
33269
|
-
class Index {
|
|
33270
|
-
static [entityKind] = "SQLiteIndex";
|
|
33271
|
-
config;
|
|
33272
|
-
constructor(config2, table) {
|
|
33273
|
-
this.config = { ...config2, table };
|
|
33274
|
-
}
|
|
33275
|
-
}
|
|
33276
|
-
function index(name) {
|
|
33277
|
-
return new IndexBuilderOn(name, false);
|
|
33278
|
-
}
|
|
33279
|
-
|
|
33280
|
-
// ../runtime/src/drizzle-schema.ts
|
|
33281
|
-
var deliveriesTable = sqliteTable("deliveries", {
|
|
33282
|
-
id: text("id").primaryKey(),
|
|
33283
|
-
messageId: text("message_id"),
|
|
33284
|
-
invocationId: text("invocation_id"),
|
|
33285
|
-
targetId: text("target_id").notNull(),
|
|
33286
|
-
targetNodeId: text("target_node_id"),
|
|
33287
|
-
targetKind: text("target_kind").$type().notNull(),
|
|
33288
|
-
transport: text("transport").$type().notNull(),
|
|
33289
|
-
reason: text("reason").$type().notNull(),
|
|
33290
|
-
policy: text("policy").$type().notNull(),
|
|
33291
|
-
status: text("status").$type().notNull(),
|
|
33292
|
-
bindingId: text("binding_id"),
|
|
33293
|
-
leaseOwner: text("lease_owner"),
|
|
33294
|
-
leaseExpiresAt: integer2("lease_expires_at"),
|
|
33295
|
-
metadataJson: text("metadata_json"),
|
|
33296
|
-
createdAt: integer2("created_at").notNull().default(sql`(unixepoch())`)
|
|
33297
|
-
}, (table) => [
|
|
33298
|
-
index("idx_deliveries_status_transport").on(table.status, table.transport)
|
|
33299
|
-
]);
|
|
33300
|
-
var deliveryAttemptsTable = sqliteTable("delivery_attempts", {
|
|
33301
|
-
id: text("id").primaryKey(),
|
|
33302
|
-
deliveryId: text("delivery_id").notNull(),
|
|
33303
|
-
attempt: integer2("attempt").notNull(),
|
|
33304
|
-
status: text("status").$type().notNull(),
|
|
33305
|
-
error: text("error"),
|
|
33306
|
-
externalRef: text("external_ref"),
|
|
33307
|
-
metadataJson: text("metadata_json"),
|
|
33308
|
-
createdAt: integer2("created_at").notNull()
|
|
33309
|
-
});
|
|
33310
|
-
// ../runtime/src/broker.ts
|
|
33311
|
-
function createRuntimeId(prefix) {
|
|
33312
|
-
return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
33313
|
-
}
|
|
33314
|
-
function toTargetKind(actor) {
|
|
33315
|
-
if (!actor)
|
|
33316
|
-
return "participant";
|
|
33317
|
-
if (actor.kind === "agent")
|
|
33318
|
-
return "agent";
|
|
33319
|
-
if (actor.kind === "device")
|
|
33320
|
-
return "device";
|
|
33321
|
-
if (actor.kind === "bridge")
|
|
33322
|
-
return "bridge";
|
|
33323
|
-
return "participant";
|
|
33324
|
-
}
|
|
33325
|
-
function defaultTransportForActor(actor) {
|
|
33326
|
-
if (!actor)
|
|
33327
|
-
return "local_socket";
|
|
33328
|
-
switch (actor.kind) {
|
|
33329
|
-
case "bridge":
|
|
33330
|
-
return "webhook";
|
|
33331
|
-
case "device":
|
|
33332
|
-
return "local_socket";
|
|
33333
|
-
case "agent":
|
|
33334
|
-
return "local_socket";
|
|
33335
|
-
default:
|
|
33336
|
-
return "local_socket";
|
|
33337
|
-
}
|
|
33338
|
-
}
|
|
33339
|
-
function endpointTransportRank(transport) {
|
|
33340
|
-
switch (transport) {
|
|
33341
|
-
case "codex_app_server":
|
|
33342
|
-
return 0;
|
|
33343
|
-
case "claude_stream_json":
|
|
33344
|
-
return 1;
|
|
33345
|
-
case "tmux":
|
|
33346
|
-
return 2;
|
|
33347
|
-
case "local_socket":
|
|
33348
|
-
return 3;
|
|
33349
|
-
default:
|
|
33350
|
-
return 4;
|
|
33351
|
-
}
|
|
33352
|
-
}
|
|
33353
|
-
function shouldBridgeMessageToBinding(binding, message) {
|
|
33354
|
-
if (binding.platform !== "telegram") {
|
|
33355
|
-
return true;
|
|
33356
|
-
}
|
|
33357
|
-
const source = typeof message.metadata?.source === "string" ? String(message.metadata.source) : "";
|
|
33358
|
-
if (source === "telegram") {
|
|
33359
|
-
return false;
|
|
33360
|
-
}
|
|
33361
|
-
const outboundMode = typeof binding.metadata?.outboundMode === "string" ? String(binding.metadata.outboundMode) : "operator_only";
|
|
33362
|
-
const operatorId = typeof binding.metadata?.operatorId === "string" ? String(binding.metadata.operatorId) : "operator";
|
|
33363
|
-
const allowedActorIds = Array.isArray(binding.metadata?.allowedActorIds) ? binding.metadata.allowedActorIds.map((entry) => String(entry).trim()).filter(Boolean) : [];
|
|
33364
|
-
if (outboundMode === "all") {
|
|
33365
|
-
return true;
|
|
33366
|
-
}
|
|
33367
|
-
if (outboundMode === "allowlist") {
|
|
33368
|
-
return allowedActorIds.includes(message.actorId);
|
|
33369
|
-
}
|
|
33370
|
-
return message.actorId === operatorId;
|
|
33371
|
-
}
|
|
33372
|
-
function resolveBindingRoutes(bindings, message) {
|
|
33373
|
-
return bindings.filter((binding) => shouldBridgeMessageToBinding(binding, message)).map((binding) => ({
|
|
33374
|
-
targetId: binding.id,
|
|
33375
|
-
targetKind: "bridge",
|
|
33376
|
-
transport: binding.platform === "telegram" ? "telegram" : binding.platform === "discord" ? "discord" : "webhook",
|
|
33377
|
-
bindingId: binding.id
|
|
33378
|
-
}));
|
|
33379
|
-
}
|
|
33380
|
-
function preferredEndpoint(endpoints) {
|
|
33381
|
-
let preferred;
|
|
33382
|
-
let preferredRank = Number.POSITIVE_INFINITY;
|
|
33383
|
-
for (const endpoint of endpoints) {
|
|
33384
|
-
const rank = endpointTransportRank(endpoint.transport);
|
|
33385
|
-
if (!preferred || rank < preferredRank) {
|
|
33386
|
-
preferred = endpoint;
|
|
33387
|
-
preferredRank = rank;
|
|
33388
|
-
}
|
|
33389
|
-
}
|
|
33390
|
-
return preferred;
|
|
33391
|
-
}
|
|
33392
|
-
|
|
33393
|
-
class InMemoryControlRuntime {
|
|
33394
|
-
registry;
|
|
33395
|
-
listeners = new Set;
|
|
33396
|
-
eventBuffer = [];
|
|
33397
|
-
localNodeId;
|
|
33398
|
-
endpointIdsByAgentId = new Map;
|
|
33399
|
-
bindingIdsByConversationId = new Map;
|
|
33400
|
-
flightIdByInvocationId = new Map;
|
|
33401
|
-
constructor(initial = {}, options = {}) {
|
|
33402
|
-
this.registry = createRuntimeRegistrySnapshot(initial);
|
|
33403
|
-
this.localNodeId = options.localNodeId;
|
|
33404
|
-
this.rebuildIndexes();
|
|
33405
|
-
}
|
|
33406
|
-
snapshot() {
|
|
33407
|
-
return createRuntimeRegistrySnapshot({
|
|
33408
|
-
nodes: { ...this.registry.nodes },
|
|
33409
|
-
actors: { ...this.registry.actors },
|
|
33410
|
-
agents: { ...this.registry.agents },
|
|
33411
|
-
endpoints: { ...this.registry.endpoints },
|
|
33412
|
-
conversations: { ...this.registry.conversations },
|
|
33413
|
-
bindings: { ...this.registry.bindings },
|
|
33414
|
-
messages: { ...this.registry.messages },
|
|
33415
|
-
flights: { ...this.registry.flights },
|
|
33416
|
-
collaborationRecords: { ...this.registry.collaborationRecords }
|
|
33417
|
-
});
|
|
33418
|
-
}
|
|
33419
|
-
peek() {
|
|
33420
|
-
return this.registry;
|
|
33421
|
-
}
|
|
33422
|
-
node(nodeId) {
|
|
33423
|
-
return this.registry.nodes[nodeId];
|
|
33424
|
-
}
|
|
33425
|
-
agent(agentId) {
|
|
33426
|
-
return this.registry.agents[agentId];
|
|
33427
|
-
}
|
|
33428
|
-
conversation(conversationId) {
|
|
33429
|
-
return this.registry.conversations[conversationId];
|
|
33430
|
-
}
|
|
33431
|
-
message(messageId) {
|
|
33432
|
-
return this.registry.messages[messageId];
|
|
33433
|
-
}
|
|
33434
|
-
collaborationRecord(recordId) {
|
|
33435
|
-
return this.registry.collaborationRecords[recordId];
|
|
33436
|
-
}
|
|
33437
|
-
flightForInvocation(invocationId) {
|
|
33438
|
-
const flightId = this.flightIdByInvocationId.get(invocationId);
|
|
33439
|
-
return flightId ? this.registry.flights[flightId] : undefined;
|
|
33440
|
-
}
|
|
33441
|
-
bindingsForConversation(conversationId) {
|
|
33442
|
-
const bindingIds = this.bindingIdsByConversationId.get(conversationId);
|
|
33443
|
-
if (!bindingIds) {
|
|
33444
|
-
return [];
|
|
33445
|
-
}
|
|
33446
|
-
const bindings = [];
|
|
33447
|
-
for (const bindingId of bindingIds) {
|
|
33448
|
-
const binding = this.registry.bindings[bindingId];
|
|
33449
|
-
if (binding) {
|
|
33450
|
-
bindings.push(binding);
|
|
33451
|
-
}
|
|
33452
|
-
}
|
|
33453
|
-
return bindings;
|
|
33454
|
-
}
|
|
33455
|
-
endpointsForAgent(agentId, options = {}) {
|
|
33456
|
-
const endpointIds = this.endpointIdsByAgentId.get(agentId);
|
|
33457
|
-
if (!endpointIds) {
|
|
33458
|
-
return [];
|
|
33459
|
-
}
|
|
33460
|
-
const endpoints = [];
|
|
33461
|
-
for (const endpointId of endpointIds) {
|
|
33462
|
-
const endpoint = this.registry.endpoints[endpointId];
|
|
33463
|
-
if (!endpoint)
|
|
33464
|
-
continue;
|
|
33465
|
-
if (!options.includeOffline && endpoint.state === "offline")
|
|
33466
|
-
continue;
|
|
33467
|
-
if (options.nodeId && endpoint.nodeId !== options.nodeId)
|
|
33468
|
-
continue;
|
|
33469
|
-
if (options.harness && endpoint.harness !== options.harness)
|
|
33470
|
-
continue;
|
|
33471
|
-
endpoints.push(endpoint);
|
|
33472
|
-
}
|
|
33473
|
-
return endpoints;
|
|
33474
|
-
}
|
|
33475
|
-
recentEvents(limit = 100) {
|
|
33476
|
-
return this.eventBuffer.slice(-limit);
|
|
33477
|
-
}
|
|
33478
|
-
subscribe(listener) {
|
|
33479
|
-
this.listeners.add(listener);
|
|
33480
|
-
return () => {
|
|
33481
|
-
this.listeners.delete(listener);
|
|
33482
|
-
};
|
|
33483
|
-
}
|
|
33484
|
-
async dispatch(command) {
|
|
33485
|
-
switch (command.kind) {
|
|
33486
|
-
case "node.upsert":
|
|
33487
|
-
await this.upsertNode(command.node);
|
|
33488
|
-
return;
|
|
33489
|
-
case "actor.upsert":
|
|
33490
|
-
await this.upsertActor(command.actor);
|
|
33491
|
-
return;
|
|
33492
|
-
case "agent.upsert":
|
|
33493
|
-
await this.upsertAgent(command.agent);
|
|
33494
|
-
return;
|
|
33495
|
-
case "agent.endpoint.upsert":
|
|
33496
|
-
await this.upsertEndpoint(command.endpoint);
|
|
33497
|
-
return;
|
|
33498
|
-
case "conversation.upsert":
|
|
33499
|
-
await this.upsertConversation(command.conversation);
|
|
33500
|
-
return;
|
|
33501
|
-
case "binding.upsert":
|
|
33502
|
-
await this.upsertBinding(command.binding);
|
|
33503
|
-
return;
|
|
33504
|
-
case "collaboration.upsert":
|
|
33505
|
-
await this.upsertCollaboration(command.record);
|
|
33506
|
-
return;
|
|
33507
|
-
case "collaboration.event.append":
|
|
33508
|
-
await this.appendCollaborationEvent(command.event);
|
|
33509
|
-
return;
|
|
33510
|
-
case "conversation.post":
|
|
33511
|
-
await this.postMessage(command.message);
|
|
33512
|
-
return;
|
|
33513
|
-
case "agent.invoke":
|
|
33514
|
-
await this.invokeAgent(command.invocation);
|
|
33515
|
-
return;
|
|
33516
|
-
case "agent.ensure_awake":
|
|
33517
|
-
this.emit({
|
|
33518
|
-
id: createRuntimeId("evt"),
|
|
33519
|
-
kind: "flight.updated",
|
|
33520
|
-
ts: Date.now(),
|
|
33521
|
-
actorId: command.requesterId,
|
|
33522
|
-
nodeId: this.localNodeId,
|
|
33523
|
-
payload: {
|
|
33524
|
-
flight: {
|
|
33525
|
-
id: createRuntimeId("flt"),
|
|
33526
|
-
invocationId: command.agentId,
|
|
33527
|
-
requesterId: command.requesterId,
|
|
33528
|
-
targetAgentId: command.agentId,
|
|
33529
|
-
state: "waking",
|
|
33530
|
-
summary: command.reason
|
|
33531
|
-
}
|
|
33532
|
-
}
|
|
33533
|
-
});
|
|
33534
|
-
return;
|
|
33535
|
-
case "stream.subscribe":
|
|
33536
|
-
return;
|
|
33537
|
-
default: {
|
|
33538
|
-
const exhaustive = command;
|
|
33539
|
-
return exhaustive;
|
|
33540
|
-
}
|
|
33541
|
-
}
|
|
33542
|
-
}
|
|
33543
|
-
async upsertNode(node) {
|
|
33544
|
-
this.registry.nodes[node.id] = node;
|
|
33545
|
-
this.emit({
|
|
33546
|
-
id: createRuntimeId("evt"),
|
|
33547
|
-
kind: "node.upserted",
|
|
33548
|
-
ts: Date.now(),
|
|
33549
|
-
actorId: node.id,
|
|
33550
|
-
nodeId: node.id,
|
|
33551
|
-
payload: { node }
|
|
33552
|
-
});
|
|
33553
|
-
}
|
|
33554
|
-
async upsertActor(actor) {
|
|
33555
|
-
this.registry.actors[actor.id] = {
|
|
33556
|
-
id: actor.id,
|
|
33557
|
-
kind: actor.kind,
|
|
33558
|
-
displayName: actor.displayName,
|
|
33559
|
-
handle: actor.handle,
|
|
33560
|
-
labels: actor.labels,
|
|
33561
|
-
metadata: actor.metadata
|
|
33562
|
-
};
|
|
33563
|
-
this.emit({
|
|
33564
|
-
id: createRuntimeId("evt"),
|
|
33565
|
-
kind: "actor.registered",
|
|
33566
|
-
ts: Date.now(),
|
|
33567
|
-
actorId: actor.id,
|
|
33568
|
-
nodeId: this.localNodeId,
|
|
33569
|
-
payload: { actor }
|
|
33570
|
-
});
|
|
33571
|
-
}
|
|
33572
|
-
async upsertAgent(agent) {
|
|
33573
|
-
if (!this.registry.actors[agent.id]) {
|
|
33574
|
-
this.registry.actors[agent.id] = {
|
|
33575
|
-
id: agent.id,
|
|
33576
|
-
kind: agent.kind,
|
|
33577
|
-
displayName: agent.displayName,
|
|
33578
|
-
handle: agent.handle,
|
|
33579
|
-
labels: agent.labels,
|
|
33580
|
-
metadata: agent.metadata
|
|
33581
|
-
};
|
|
33582
|
-
}
|
|
33583
|
-
this.registry.agents[agent.id] = agent;
|
|
33584
|
-
this.emit({
|
|
33585
|
-
id: createRuntimeId("evt"),
|
|
33586
|
-
kind: "agent.registered",
|
|
33587
|
-
ts: Date.now(),
|
|
33588
|
-
actorId: agent.id,
|
|
33589
|
-
nodeId: agent.authorityNodeId,
|
|
33590
|
-
payload: { agent }
|
|
33591
|
-
});
|
|
33592
|
-
}
|
|
33593
|
-
async upsertEndpoint(endpoint) {
|
|
33594
|
-
const previous = this.registry.endpoints[endpoint.id];
|
|
33595
|
-
if (previous) {
|
|
33596
|
-
this.unindexEndpoint(previous);
|
|
33597
|
-
}
|
|
33598
|
-
this.registry.endpoints[endpoint.id] = endpoint;
|
|
33599
|
-
this.indexEndpoint(endpoint);
|
|
33600
|
-
this.emit({
|
|
33601
|
-
id: createRuntimeId("evt"),
|
|
33602
|
-
kind: "agent.endpoint.upserted",
|
|
33603
|
-
ts: Date.now(),
|
|
33604
|
-
actorId: endpoint.agentId,
|
|
33605
|
-
nodeId: endpoint.nodeId,
|
|
33606
|
-
payload: { endpoint }
|
|
33607
|
-
});
|
|
33608
|
-
}
|
|
33609
|
-
async upsertConversation(conversation) {
|
|
33610
|
-
this.registry.conversations[conversation.id] = conversation;
|
|
33611
|
-
this.emit({
|
|
33612
|
-
id: createRuntimeId("evt"),
|
|
33613
|
-
kind: "conversation.upserted",
|
|
33614
|
-
ts: Date.now(),
|
|
33615
|
-
actorId: "system",
|
|
33616
|
-
nodeId: conversation.authorityNodeId,
|
|
33617
|
-
payload: { conversation }
|
|
33618
|
-
});
|
|
33619
|
-
}
|
|
33620
|
-
async upsertBinding(binding) {
|
|
33621
|
-
const previous = this.registry.bindings[binding.id];
|
|
33622
|
-
if (previous) {
|
|
33623
|
-
this.unindexBinding(previous);
|
|
33624
|
-
}
|
|
33625
|
-
this.registry.bindings[binding.id] = binding;
|
|
33626
|
-
this.indexBinding(binding);
|
|
33627
|
-
this.emit({
|
|
33628
|
-
id: createRuntimeId("evt"),
|
|
33629
|
-
kind: "binding.upserted",
|
|
33630
|
-
ts: Date.now(),
|
|
33631
|
-
actorId: "system",
|
|
33632
|
-
nodeId: this.localNodeId,
|
|
33633
|
-
payload: { binding }
|
|
33634
|
-
});
|
|
33635
|
-
}
|
|
33636
|
-
async upsertCollaboration(record2) {
|
|
33637
|
-
assertValidCollaborationRecord(record2);
|
|
33638
|
-
this.registry.collaborationRecords[record2.id] = record2;
|
|
33639
|
-
this.emit({
|
|
33640
|
-
id: createRuntimeId("evt"),
|
|
33641
|
-
kind: "collaboration.upserted",
|
|
33642
|
-
ts: Date.now(),
|
|
33643
|
-
actorId: record2.createdById,
|
|
33644
|
-
nodeId: this.localNodeId,
|
|
33645
|
-
payload: { record: record2 }
|
|
33646
|
-
});
|
|
33647
|
-
}
|
|
33648
|
-
async appendCollaborationEvent(event) {
|
|
33649
|
-
const record2 = this.registry.collaborationRecords[event.recordId];
|
|
33650
|
-
if (!record2) {
|
|
33651
|
-
throw new Error(`unknown collaboration record: ${event.recordId}`);
|
|
33652
|
-
}
|
|
33653
|
-
assertValidCollaborationEvent(event, record2);
|
|
33654
|
-
this.emit({
|
|
33655
|
-
id: createRuntimeId("evt"),
|
|
33656
|
-
kind: "collaboration.event.appended",
|
|
33657
|
-
ts: Date.now(),
|
|
33658
|
-
actorId: event.actorId,
|
|
33659
|
-
nodeId: this.localNodeId,
|
|
33660
|
-
payload: { event }
|
|
33661
|
-
});
|
|
33662
|
-
}
|
|
33663
|
-
async upsertFlight(flight) {
|
|
33664
|
-
const previous = this.registry.flights[flight.id];
|
|
33665
|
-
if (previous && this.flightIdByInvocationId.get(previous.invocationId) === previous.id) {
|
|
33666
|
-
this.flightIdByInvocationId.delete(previous.invocationId);
|
|
33667
|
-
}
|
|
33668
|
-
this.registry.flights[flight.id] = flight;
|
|
33669
|
-
this.flightIdByInvocationId.set(flight.invocationId, flight.id);
|
|
33670
|
-
this.emit({
|
|
33671
|
-
id: createRuntimeId("evt"),
|
|
33672
|
-
kind: "flight.updated",
|
|
33673
|
-
ts: Date.now(),
|
|
33674
|
-
actorId: flight.requesterId,
|
|
33675
|
-
nodeId: this.localNodeId,
|
|
33676
|
-
payload: { flight }
|
|
33677
|
-
});
|
|
33678
|
-
}
|
|
33679
|
-
async postMessage(message, options = {}) {
|
|
33680
|
-
const deliveries2 = this.planMessage(message, options);
|
|
33681
|
-
await this.commitMessage(message, deliveries2);
|
|
33682
|
-
return deliveries2;
|
|
33683
|
-
}
|
|
33684
|
-
planMessage(message, options = {}) {
|
|
33685
|
-
const conversation = this.registry.conversations[message.conversationId];
|
|
33686
|
-
if (!conversation) {
|
|
33687
|
-
throw new Error(`unknown conversation: ${message.conversationId}`);
|
|
33688
|
-
}
|
|
33689
|
-
const bindingRoutes = resolveBindingRoutes(this.bindingsForConversation(conversation.id), message);
|
|
33690
|
-
const plannedParticipantRoutes = this.resolveParticipantRoutes(conversation.participantIds);
|
|
33691
|
-
const participantRoutes = options.localOnly ? plannedParticipantRoutes.filter((route2) => !route2.nodeId || route2.nodeId === this.localNodeId) : plannedParticipantRoutes;
|
|
33692
|
-
const deliveries2 = planMessageDeliveries({
|
|
33693
|
-
localNodeId: this.localNodeId,
|
|
33694
|
-
message,
|
|
33695
|
-
conversation,
|
|
33696
|
-
participantRoutes,
|
|
33697
|
-
bindingRoutes: options.localOnly ? [] : bindingRoutes
|
|
33698
|
-
});
|
|
33699
|
-
return deliveries2;
|
|
33700
|
-
}
|
|
33701
|
-
async commitMessage(message, deliveries2) {
|
|
33702
|
-
this.registry.messages[message.id] = message;
|
|
33703
|
-
this.emit({
|
|
33704
|
-
id: createRuntimeId("evt"),
|
|
33705
|
-
kind: "message.posted",
|
|
33706
|
-
ts: Date.now(),
|
|
33707
|
-
actorId: message.actorId,
|
|
33708
|
-
nodeId: message.originNodeId,
|
|
33709
|
-
payload: { message }
|
|
33710
|
-
});
|
|
33711
|
-
for (const delivery of deliveries2) {
|
|
33712
|
-
this.emit({
|
|
33713
|
-
id: createRuntimeId("evt"),
|
|
33714
|
-
kind: "delivery.planned",
|
|
33715
|
-
ts: Date.now(),
|
|
33716
|
-
actorId: message.actorId,
|
|
33717
|
-
nodeId: message.originNodeId,
|
|
33718
|
-
payload: { delivery }
|
|
33719
|
-
});
|
|
33720
|
-
}
|
|
33721
|
-
}
|
|
33722
|
-
async invokeAgent(invocation) {
|
|
33723
|
-
const flight = this.planInvocation(invocation);
|
|
33724
|
-
await this.commitInvocation(invocation, flight);
|
|
33725
|
-
return flight;
|
|
33726
|
-
}
|
|
33727
|
-
planInvocation(invocation) {
|
|
33728
|
-
const targetAgent = this.registry.agents[invocation.targetAgentId];
|
|
33729
|
-
if (!targetAgent) {
|
|
33730
|
-
throw new Error(`unknown agent: ${invocation.targetAgentId}`);
|
|
33731
|
-
}
|
|
33732
|
-
const targetEndpoints = this.endpointsForAgent(invocation.targetAgentId, {
|
|
33733
|
-
nodeId: targetAgent.authorityNodeId,
|
|
33734
|
-
harness: invocation.execution?.harness
|
|
33735
|
-
});
|
|
33736
|
-
const isLocalAuthority = !this.localNodeId || targetAgent.authorityNodeId === this.localNodeId;
|
|
33737
|
-
const startedAt = Date.now();
|
|
33738
|
-
let state = invocation.ensureAwake ? "waking" : "queued";
|
|
33739
|
-
let summary;
|
|
33740
|
-
let error48;
|
|
33741
|
-
let completedAt;
|
|
33742
|
-
if (isLocalAuthority) {
|
|
33743
|
-
if (targetEndpoints.length == 0) {
|
|
33744
|
-
state = invocation.ensureAwake ? "waking" : "queued";
|
|
33745
|
-
summary = invocation.ensureAwake ? invocation.execution?.harness ? `${targetAgent.displayName} waking on ${invocation.execution.harness}.` : `${targetAgent.displayName} waking.` : `Message stored for ${targetAgent.displayName}. Will deliver when online.`;
|
|
33746
|
-
} else {
|
|
33747
|
-
state = "queued";
|
|
33748
|
-
summary = `${targetAgent.displayName} queued for local execution.`;
|
|
33749
|
-
}
|
|
33750
|
-
}
|
|
33751
|
-
const flight = {
|
|
33752
|
-
id: createRuntimeId("flt"),
|
|
33753
|
-
invocationId: invocation.id,
|
|
33754
|
-
requesterId: invocation.requesterId,
|
|
33755
|
-
targetAgentId: invocation.targetAgentId,
|
|
33756
|
-
state,
|
|
33757
|
-
summary,
|
|
33758
|
-
error: error48,
|
|
33759
|
-
startedAt,
|
|
33760
|
-
completedAt,
|
|
33761
|
-
metadata: invocation.metadata
|
|
33762
|
-
};
|
|
33763
|
-
return flight;
|
|
33764
|
-
}
|
|
33765
|
-
async commitInvocation(invocation, flight) {
|
|
33766
|
-
const previous = this.registry.flights[flight.id];
|
|
33767
|
-
if (previous && this.flightIdByInvocationId.get(previous.invocationId) === previous.id) {
|
|
33768
|
-
this.flightIdByInvocationId.delete(previous.invocationId);
|
|
33769
|
-
}
|
|
33770
|
-
this.registry.flights[flight.id] = flight;
|
|
33771
|
-
this.flightIdByInvocationId.set(flight.invocationId, flight.id);
|
|
33772
|
-
const targetAgent = this.registry.agents[invocation.targetAgentId];
|
|
33773
|
-
this.emit({
|
|
33774
|
-
id: createRuntimeId("evt"),
|
|
33775
|
-
kind: "invocation.requested",
|
|
33776
|
-
ts: Date.now(),
|
|
33777
|
-
actorId: invocation.requesterId,
|
|
33778
|
-
nodeId: invocation.requesterNodeId,
|
|
33779
|
-
payload: { invocation }
|
|
33780
|
-
});
|
|
33781
|
-
this.emit({
|
|
33782
|
-
id: createRuntimeId("evt"),
|
|
33783
|
-
kind: "flight.updated",
|
|
33784
|
-
ts: Date.now(),
|
|
33785
|
-
actorId: invocation.requesterId,
|
|
33786
|
-
nodeId: targetAgent?.authorityNodeId,
|
|
33787
|
-
payload: { flight }
|
|
33788
|
-
});
|
|
33789
|
-
}
|
|
33790
|
-
rebuildIndexes() {
|
|
33791
|
-
for (const endpoint of Object.values(this.registry.endpoints)) {
|
|
33792
|
-
this.indexEndpoint(endpoint);
|
|
33793
|
-
}
|
|
33794
|
-
for (const binding of Object.values(this.registry.bindings)) {
|
|
33795
|
-
this.indexBinding(binding);
|
|
33796
|
-
}
|
|
33797
|
-
for (const flight of Object.values(this.registry.flights)) {
|
|
33798
|
-
this.flightIdByInvocationId.set(flight.invocationId, flight.id);
|
|
33799
|
-
}
|
|
33800
|
-
}
|
|
33801
|
-
indexEndpoint(endpoint) {
|
|
33802
|
-
this.addIndexedId(this.endpointIdsByAgentId, endpoint.agentId, endpoint.id);
|
|
33803
|
-
}
|
|
33804
|
-
unindexEndpoint(endpoint) {
|
|
33805
|
-
this.removeIndexedId(this.endpointIdsByAgentId, endpoint.agentId, endpoint.id);
|
|
33806
|
-
}
|
|
33807
|
-
indexBinding(binding) {
|
|
33808
|
-
this.addIndexedId(this.bindingIdsByConversationId, binding.conversationId, binding.id);
|
|
33809
|
-
}
|
|
33810
|
-
unindexBinding(binding) {
|
|
33811
|
-
this.removeIndexedId(this.bindingIdsByConversationId, binding.conversationId, binding.id);
|
|
33812
|
-
}
|
|
33813
|
-
addIndexedId(index2, key, value) {
|
|
33814
|
-
const ids = index2.get(key) ?? new Set;
|
|
33815
|
-
ids.add(value);
|
|
33816
|
-
index2.set(key, ids);
|
|
33817
|
-
}
|
|
33818
|
-
removeIndexedId(index2, key, value) {
|
|
33819
|
-
const ids = index2.get(key);
|
|
33820
|
-
if (!ids) {
|
|
33821
|
-
return;
|
|
33822
|
-
}
|
|
33823
|
-
ids.delete(value);
|
|
33824
|
-
if (ids.size === 0) {
|
|
33825
|
-
index2.delete(key);
|
|
33826
|
-
}
|
|
33827
|
-
}
|
|
33828
|
-
resolveParticipantRoutes(participantIds) {
|
|
33829
|
-
const routes = [];
|
|
33830
|
-
for (const participantId of participantIds) {
|
|
33831
|
-
const actor = this.registry.actors[participantId];
|
|
33832
|
-
const agent = this.registry.agents[participantId];
|
|
33833
|
-
const targetIdentity = actor ?? agent;
|
|
33834
|
-
const endpoints = this.endpointsForAgent(participantId);
|
|
33835
|
-
const endpoint = preferredEndpoint(endpoints);
|
|
33836
|
-
if (!endpoint) {
|
|
33837
|
-
if (agent?.authorityNodeId && agent.authorityNodeId !== this.localNodeId) {
|
|
33838
|
-
routes.push({
|
|
33839
|
-
targetId: participantId,
|
|
33840
|
-
nodeId: agent.authorityNodeId,
|
|
33841
|
-
targetKind: toTargetKind(targetIdentity),
|
|
33842
|
-
transport: defaultTransportForActor(targetIdentity),
|
|
33843
|
-
speechEnabled: false
|
|
33844
|
-
});
|
|
33845
|
-
} else if (agent) {
|
|
33846
|
-
routes.push({
|
|
33847
|
-
targetId: participantId,
|
|
33848
|
-
nodeId: agent.authorityNodeId ?? this.localNodeId,
|
|
33849
|
-
targetKind: toTargetKind(targetIdentity),
|
|
33850
|
-
transport: defaultTransportForActor(targetIdentity),
|
|
33851
|
-
speechEnabled: false
|
|
33852
|
-
});
|
|
33853
|
-
}
|
|
33854
|
-
continue;
|
|
33855
|
-
}
|
|
33856
|
-
routes.push({
|
|
33857
|
-
targetId: participantId,
|
|
33858
|
-
nodeId: endpoint.nodeId ?? agent?.authorityNodeId,
|
|
33859
|
-
targetKind: toTargetKind(targetIdentity),
|
|
33860
|
-
transport: endpoint.transport ?? defaultTransportForActor(targetIdentity),
|
|
33861
|
-
speechEnabled: Boolean(actor?.kind === "device" || endpoints.some((candidate) => candidate.transport === "local_socket" || candidate.transport === "websocket"))
|
|
33862
|
-
});
|
|
33863
|
-
}
|
|
33864
|
-
return routes;
|
|
33865
|
-
}
|
|
33866
|
-
emit(event) {
|
|
33867
|
-
this.eventBuffer.push(event);
|
|
33868
|
-
if (this.eventBuffer.length > 500) {
|
|
33869
|
-
this.eventBuffer.shift();
|
|
33870
|
-
}
|
|
33871
|
-
for (const listener of this.listeners) {
|
|
33872
|
-
listener(event);
|
|
33873
|
-
}
|
|
33874
|
-
}
|
|
33875
|
-
}
|
|
33876
|
-
// ../runtime/src/tailscale.ts
|
|
33877
|
-
import { execFile } from "child_process";
|
|
33878
|
-
import { promisify } from "util";
|
|
33879
|
-
var execFileAsync = promisify(execFile);
|
|
33880
|
-
// ../runtime/src/thread-events.ts
|
|
33881
|
-
class ThreadWatchProtocolError extends Error {
|
|
33882
|
-
status;
|
|
33883
|
-
body;
|
|
33884
|
-
constructor(status, body) {
|
|
33885
|
-
super(body.message);
|
|
33886
|
-
this.status = status;
|
|
33887
|
-
this.body = body;
|
|
33888
|
-
}
|
|
33889
|
-
}
|
|
33890
|
-
function watchKey(conversationId, watcherNodeId, watcherId) {
|
|
33891
|
-
return `${conversationId}:${watcherNodeId}:${watcherId}`;
|
|
33892
|
-
}
|
|
33893
|
-
function writeSse(response, eventName, payload) {
|
|
33894
|
-
response.write(`event: ${eventName}
|
|
33895
|
-
data: ${JSON.stringify(payload)}
|
|
33896
|
-
|
|
33897
|
-
`);
|
|
33898
|
-
}
|
|
33899
|
-
|
|
33900
|
-
class ThreadEventPlane {
|
|
33901
|
-
options;
|
|
33902
|
-
watches = new Map;
|
|
33903
|
-
watchIdsByKey = new Map;
|
|
33904
|
-
watchIdsByConversation = new Map;
|
|
33905
|
-
constructor(options) {
|
|
33906
|
-
this.options = options;
|
|
33907
|
-
}
|
|
33908
|
-
async openWatch(request) {
|
|
33909
|
-
const conversation = this.requireConversationAuthority(request.conversationId);
|
|
33910
|
-
this.requireRemoteWatchAllowed(conversation);
|
|
33911
|
-
const afterSeq = Math.max(0, request.afterSeq ?? 0);
|
|
33912
|
-
const oldestSeq = await this.options.projection.oldestThreadSeq(conversation.id);
|
|
33913
|
-
const latestSeq = await this.options.projection.latestThreadSeq(conversation.id);
|
|
33914
|
-
if (latestSeq > 0 && oldestSeq > 0 && afterSeq < oldestSeq - 1) {
|
|
33915
|
-
throw new ThreadWatchProtocolError(409, {
|
|
33916
|
-
code: "cursor_out_of_range",
|
|
33917
|
-
message: `thread cursor ${afterSeq} is older than retained seq ${oldestSeq}`
|
|
33918
|
-
});
|
|
33919
|
-
}
|
|
33920
|
-
const key = watchKey(conversation.id, request.watcherNodeId, request.watcherId);
|
|
33921
|
-
const existingWatchId = this.watchIdsByKey.get(key);
|
|
33922
|
-
if (existingWatchId) {
|
|
33923
|
-
this.closeWatchInternal(existingWatchId);
|
|
33924
|
-
}
|
|
33925
|
-
const watchId = `thread-watch:${conversation.id}:${request.watcherNodeId}:${request.watcherId}`;
|
|
33926
|
-
const leaseExpiresAt = Date.now() + this.normalizeLeaseMs(request.leaseMs);
|
|
33927
|
-
const watch = {
|
|
33928
|
-
watchId,
|
|
33929
|
-
conversationId: conversation.id,
|
|
33930
|
-
watcherNodeId: request.watcherNodeId,
|
|
33931
|
-
watcherId: request.watcherId,
|
|
33932
|
-
acceptedAfterSeq: afterSeq,
|
|
33933
|
-
leaseExpiresAt,
|
|
33934
|
-
mode: conversation.shareMode === "summary" ? "summary" : "shared",
|
|
33935
|
-
clients: new Set
|
|
33936
|
-
};
|
|
33937
|
-
this.watches.set(watchId, watch);
|
|
33938
|
-
this.watchIdsByKey.set(key, watchId);
|
|
33939
|
-
this.indexWatch(watch);
|
|
33940
|
-
return {
|
|
33941
|
-
watchId,
|
|
33942
|
-
conversationId: conversation.id,
|
|
33943
|
-
authorityNodeId: conversation.authorityNodeId,
|
|
33944
|
-
acceptedAfterSeq: afterSeq,
|
|
33945
|
-
latestSeq,
|
|
33946
|
-
leaseExpiresAt,
|
|
33947
|
-
mode: watch.mode
|
|
33948
|
-
};
|
|
33949
|
-
}
|
|
33950
|
-
async renewWatch(request) {
|
|
33951
|
-
const watch = this.requireLiveWatch(request.watchId);
|
|
33952
|
-
watch.leaseExpiresAt = Date.now() + this.normalizeLeaseMs(request.leaseMs);
|
|
33953
|
-
return {
|
|
33954
|
-
watchId: watch.watchId,
|
|
33955
|
-
leaseExpiresAt: watch.leaseExpiresAt
|
|
33956
|
-
};
|
|
33957
|
-
}
|
|
33958
|
-
async closeWatch(request) {
|
|
33959
|
-
this.closeWatchInternal(request.watchId);
|
|
33960
|
-
}
|
|
33961
|
-
async replay(options) {
|
|
33962
|
-
const conversation = this.requireConversationAuthority(options.conversationId);
|
|
33963
|
-
this.requireRemoteWatchAllowed(conversation);
|
|
33964
|
-
const oldestSeq = await this.options.projection.oldestThreadSeq(conversation.id);
|
|
33965
|
-
const latestSeq = await this.options.projection.latestThreadSeq(conversation.id);
|
|
33966
|
-
if (latestSeq > 0 && oldestSeq > 0 && options.afterSeq < oldestSeq - 1) {
|
|
33967
|
-
throw new ThreadWatchProtocolError(409, {
|
|
33968
|
-
code: "cursor_out_of_range",
|
|
33969
|
-
message: `thread cursor ${options.afterSeq} is older than retained seq ${oldestSeq}`
|
|
33970
|
-
});
|
|
33971
|
-
}
|
|
33972
|
-
return this.options.projection.listThreadEvents({
|
|
33973
|
-
conversationId: conversation.id,
|
|
33974
|
-
afterSeq: options.afterSeq,
|
|
33975
|
-
limit: Math.min(options.limit ?? 500, this.options.maxReplayLimit ?? 2000)
|
|
33976
|
-
});
|
|
33977
|
-
}
|
|
33978
|
-
async snapshot(conversationId) {
|
|
33979
|
-
const conversation = this.requireConversationAuthority(conversationId);
|
|
33980
|
-
this.requireRemoteWatchAllowed(conversation);
|
|
33981
|
-
const snapshot = await this.options.projection.getThreadSnapshot(conversation.id);
|
|
33982
|
-
if (!snapshot) {
|
|
33983
|
-
throw new ThreadWatchProtocolError(404, {
|
|
33984
|
-
code: "unknown_conversation",
|
|
33985
|
-
message: `unknown conversation ${conversation.id}`
|
|
33986
|
-
});
|
|
33987
|
-
}
|
|
33988
|
-
return snapshot;
|
|
33989
|
-
}
|
|
33990
|
-
async streamWatch(watchId, request, response) {
|
|
33991
|
-
const watch = this.requireLiveWatch(watchId);
|
|
33992
|
-
const backlog = await this.options.projection.listThreadEvents({
|
|
33993
|
-
conversationId: watch.conversationId,
|
|
33994
|
-
afterSeq: watch.acceptedAfterSeq,
|
|
33995
|
-
limit: this.options.maxReplayLimit ?? 2000
|
|
33996
|
-
});
|
|
33997
|
-
response.writeHead(200, {
|
|
33998
|
-
"content-type": "text/event-stream",
|
|
33999
|
-
"cache-control": "no-cache, no-transform",
|
|
34000
|
-
connection: "keep-alive"
|
|
34001
|
-
});
|
|
34002
|
-
writeSse(response, "hello", {
|
|
34003
|
-
watchId: watch.watchId,
|
|
34004
|
-
conversationId: watch.conversationId,
|
|
34005
|
-
leaseExpiresAt: watch.leaseExpiresAt
|
|
34006
|
-
});
|
|
34007
|
-
for (const event of backlog) {
|
|
34008
|
-
writeSse(response, "thread.event", event);
|
|
34009
|
-
}
|
|
34010
|
-
watch.clients.add(response);
|
|
34011
|
-
request.on("close", () => {
|
|
34012
|
-
watch.clients.delete(response);
|
|
34013
|
-
response.end();
|
|
34014
|
-
});
|
|
34015
|
-
}
|
|
34016
|
-
publish(events2) {
|
|
34017
|
-
for (const event of events2) {
|
|
34018
|
-
const watchIds = this.watchIdsByConversation.get(event.conversationId);
|
|
34019
|
-
if (!watchIds || watchIds.size === 0) {
|
|
34020
|
-
continue;
|
|
34021
|
-
}
|
|
34022
|
-
for (const watchId of [...watchIds]) {
|
|
34023
|
-
const watch = this.watches.get(watchId);
|
|
34024
|
-
if (!watch) {
|
|
34025
|
-
watchIds.delete(watchId);
|
|
34026
|
-
continue;
|
|
34027
|
-
}
|
|
34028
|
-
if (watch.leaseExpiresAt <= Date.now()) {
|
|
34029
|
-
this.closeWatchInternal(watchId);
|
|
34030
|
-
continue;
|
|
34031
|
-
}
|
|
34032
|
-
for (const client of watch.clients) {
|
|
34033
|
-
writeSse(client, "thread.event", event);
|
|
34034
|
-
}
|
|
34035
|
-
}
|
|
34036
|
-
}
|
|
34037
|
-
}
|
|
34038
|
-
normalizeLeaseMs(requestedLeaseMs) {
|
|
34039
|
-
const defaultLeaseMs = this.options.defaultLeaseMs ?? 30000;
|
|
34040
|
-
const maxLeaseMs = this.options.maxLeaseMs ?? 300000;
|
|
34041
|
-
if (!requestedLeaseMs || !Number.isFinite(requestedLeaseMs) || requestedLeaseMs <= 0) {
|
|
34042
|
-
return defaultLeaseMs;
|
|
34043
|
-
}
|
|
34044
|
-
return Math.min(Math.max(requestedLeaseMs, 5000), maxLeaseMs);
|
|
34045
|
-
}
|
|
34046
|
-
requireConversationAuthority(conversationId) {
|
|
34047
|
-
const conversation = this.options.runtime.conversation(conversationId);
|
|
34048
|
-
if (!conversation) {
|
|
34049
|
-
throw new ThreadWatchProtocolError(404, {
|
|
34050
|
-
code: "unknown_conversation",
|
|
34051
|
-
message: `unknown conversation ${conversationId}`
|
|
34052
|
-
});
|
|
34053
|
-
}
|
|
34054
|
-
if (conversation.authorityNodeId !== this.options.nodeId) {
|
|
34055
|
-
throw new ThreadWatchProtocolError(409, {
|
|
34056
|
-
code: "no_responder",
|
|
34057
|
-
message: `conversation ${conversationId} is owned by ${conversation.authorityNodeId}`
|
|
34058
|
-
});
|
|
34059
|
-
}
|
|
34060
|
-
return conversation;
|
|
34061
|
-
}
|
|
34062
|
-
requireRemoteWatchAllowed(conversation) {
|
|
34063
|
-
if (conversation.shareMode === "local") {
|
|
34064
|
-
throw new ThreadWatchProtocolError(403, {
|
|
34065
|
-
code: "forbidden",
|
|
34066
|
-
message: `conversation ${conversation.id} does not allow remote watches`
|
|
34067
|
-
});
|
|
34068
|
-
}
|
|
34069
|
-
}
|
|
34070
|
-
requireLiveWatch(watchId) {
|
|
34071
|
-
const watch = this.watches.get(watchId);
|
|
34072
|
-
if (!watch) {
|
|
34073
|
-
throw new ThreadWatchProtocolError(404, {
|
|
34074
|
-
code: "invalid_request",
|
|
34075
|
-
message: `unknown watch ${watchId}`
|
|
34076
|
-
});
|
|
34077
|
-
}
|
|
34078
|
-
if (watch.leaseExpiresAt <= Date.now()) {
|
|
34079
|
-
this.closeWatchInternal(watchId);
|
|
34080
|
-
throw new ThreadWatchProtocolError(410, {
|
|
34081
|
-
code: "lease_expired",
|
|
34082
|
-
message: `watch ${watchId} lease expired`
|
|
34083
|
-
});
|
|
34084
|
-
}
|
|
34085
|
-
return watch;
|
|
34086
|
-
}
|
|
34087
|
-
indexWatch(watch) {
|
|
34088
|
-
const ids = this.watchIdsByConversation.get(watch.conversationId) ?? new Set;
|
|
34089
|
-
ids.add(watch.watchId);
|
|
34090
|
-
this.watchIdsByConversation.set(watch.conversationId, ids);
|
|
34091
|
-
}
|
|
34092
|
-
closeWatchInternal(watchId) {
|
|
34093
|
-
const watch = this.watches.get(watchId);
|
|
34094
|
-
if (!watch) {
|
|
34095
|
-
return;
|
|
34096
|
-
}
|
|
34097
|
-
this.watches.delete(watchId);
|
|
34098
|
-
this.watchIdsByKey.delete(watchKey(watch.conversationId, watch.watcherNodeId, watch.watcherId));
|
|
34099
|
-
const ids = this.watchIdsByConversation.get(watch.conversationId);
|
|
34100
|
-
if (ids) {
|
|
34101
|
-
ids.delete(watchId);
|
|
34102
|
-
if (ids.size === 0) {
|
|
34103
|
-
this.watchIdsByConversation.delete(watch.conversationId);
|
|
34104
|
-
}
|
|
34105
|
-
}
|
|
34106
|
-
for (const client of watch.clients) {
|
|
34107
|
-
client.end();
|
|
34108
|
-
}
|
|
34109
|
-
watch.clients.clear();
|
|
34110
|
-
}
|
|
34111
|
-
}
|
|
34112
32122
|
// ../runtime/src/mobile-push.ts
|
|
34113
32123
|
import { Database as Database2 } from "bun:sqlite";
|
|
34114
32124
|
import { mkdirSync as mkdirSync9, readFileSync as readFileSync10 } from "fs";
|
|
34115
32125
|
import { connect as connectHttp2 } from "http2";
|
|
34116
32126
|
import { createPrivateKey, sign as signWithKey } from "crypto";
|
|
34117
|
-
import { dirname as
|
|
32127
|
+
import { dirname as dirname8, join as join19 } from "path";
|
|
34118
32128
|
var MOBILE_PUSH_SCHEMA = `
|
|
34119
32129
|
CREATE TABLE IF NOT EXISTS mobile_push_registrations (
|
|
34120
32130
|
id TEXT PRIMARY KEY,
|
|
@@ -34142,7 +32152,7 @@ var dbHandle = null;
|
|
|
34142
32152
|
var dbPath = null;
|
|
34143
32153
|
var cachedApnsJwt = null;
|
|
34144
32154
|
function resolveControlPlaneDbPath() {
|
|
34145
|
-
return
|
|
32155
|
+
return join19(resolveOpenScoutSupportPaths().controlHome, "control-plane.sqlite");
|
|
34146
32156
|
}
|
|
34147
32157
|
function ensureMobilePushSchema(database) {
|
|
34148
32158
|
database.exec("PRAGMA busy_timeout = 5000;");
|
|
@@ -34156,7 +32166,7 @@ function writeDb() {
|
|
|
34156
32166
|
dbHandle = null;
|
|
34157
32167
|
}
|
|
34158
32168
|
if (!dbHandle) {
|
|
34159
|
-
mkdirSync9(
|
|
32169
|
+
mkdirSync9(dirname8(nextPath), { recursive: true });
|
|
34160
32170
|
dbHandle = new Database2(nextPath, { create: true });
|
|
34161
32171
|
dbPath = nextPath;
|
|
34162
32172
|
ensureMobilePushSchema(dbHandle);
|
|
@@ -34372,7 +32382,7 @@ async function sendApnsAlertToRegistration(registration, alert) {
|
|
|
34372
32382
|
},
|
|
34373
32383
|
...alert.payload ? { scout: alert.payload } : {}
|
|
34374
32384
|
});
|
|
34375
|
-
return new Promise((
|
|
32385
|
+
return new Promise((resolve8, reject) => {
|
|
34376
32386
|
const client = connectHttp2(authority);
|
|
34377
32387
|
client.once("error", reject);
|
|
34378
32388
|
const request = client.request({
|
|
@@ -34410,7 +32420,7 @@ async function sendApnsAlertToRegistration(registration, alert) {
|
|
|
34410
32420
|
}
|
|
34411
32421
|
}
|
|
34412
32422
|
if (status === 200) {
|
|
34413
|
-
|
|
32423
|
+
resolve8({
|
|
34414
32424
|
delivered: true,
|
|
34415
32425
|
skipped: false,
|
|
34416
32426
|
status,
|
|
@@ -34422,7 +32432,7 @@ async function sendApnsAlertToRegistration(registration, alert) {
|
|
|
34422
32432
|
if (reason === "BadDeviceToken" || reason === "Unregistered") {
|
|
34423
32433
|
deleteMobilePushRegistrationByToken(registration.pushToken);
|
|
34424
32434
|
}
|
|
34425
|
-
|
|
32435
|
+
resolve8({
|
|
34426
32436
|
delivered: false,
|
|
34427
32437
|
skipped: false,
|
|
34428
32438
|
status,
|
|
@@ -34481,11 +32491,12 @@ async function broadcastApnsAlertToActiveMobileDevices(alert) {
|
|
|
34481
32491
|
failures
|
|
34482
32492
|
};
|
|
34483
32493
|
}
|
|
32494
|
+
|
|
34484
32495
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/router.ts
|
|
34485
32496
|
import { readFileSync as readFileSync11, readdirSync as readdirSync4, realpathSync as realpathSync2, statSync as statSync4 } from "fs";
|
|
34486
32497
|
import { execSync as execSync4 } from "child_process";
|
|
34487
|
-
import { basename as
|
|
34488
|
-
import { homedir as
|
|
32498
|
+
import { basename as basename8, isAbsolute as isAbsolute4, join as join20, relative as relative3 } from "path";
|
|
32499
|
+
import { homedir as homedir17 } from "os";
|
|
34489
32500
|
var t = initTRPC.context().create();
|
|
34490
32501
|
var logged = t.middleware(async ({ path: path2, type, next }) => {
|
|
34491
32502
|
const start = Date.now();
|
|
@@ -34512,13 +32523,13 @@ function resolveMobileCurrentDirectory2() {
|
|
|
34512
32523
|
}
|
|
34513
32524
|
}
|
|
34514
32525
|
function resolveWorkspaceRoot2(root) {
|
|
34515
|
-
const expandedRoot = root.replace(/^~/,
|
|
32526
|
+
const expandedRoot = root.replace(/^~/, homedir17());
|
|
34516
32527
|
return realpathSync2(expandedRoot);
|
|
34517
32528
|
}
|
|
34518
32529
|
function resolveWorkspacePath2(root, requestedPath) {
|
|
34519
32530
|
const normalizedRoot = resolveWorkspaceRoot2(root);
|
|
34520
|
-
const expandedPath = requestedPath?.replace(/^~/,
|
|
34521
|
-
const candidate = expandedPath ? isAbsolute4(expandedPath) ? expandedPath :
|
|
32531
|
+
const expandedPath = requestedPath?.replace(/^~/, homedir17());
|
|
32532
|
+
const candidate = expandedPath ? isAbsolute4(expandedPath) ? expandedPath : join20(normalizedRoot, expandedPath) : normalizedRoot;
|
|
34522
32533
|
const resolvedCandidate = realpathSync2(candidate);
|
|
34523
32534
|
const rel = relative3(normalizedRoot, resolvedCandidate);
|
|
34524
32535
|
if (rel === "" || !rel.startsWith("..") && !isAbsolute4(rel)) {
|
|
@@ -34548,7 +32559,7 @@ function listDirectories2(dirPath) {
|
|
|
34548
32559
|
continue;
|
|
34549
32560
|
if (name === "node_modules" || name === ".build" || name === "target")
|
|
34550
32561
|
continue;
|
|
34551
|
-
const fullPath =
|
|
32562
|
+
const fullPath = join20(dirPath, name);
|
|
34552
32563
|
try {
|
|
34553
32564
|
const stat4 = statSync4(fullPath);
|
|
34554
32565
|
if (!stat4.isDirectory())
|
|
@@ -34587,7 +32598,7 @@ function detectAgent2(filePath) {
|
|
|
34587
32598
|
return "unknown";
|
|
34588
32599
|
}
|
|
34589
32600
|
async function discoverSessionFiles2(maxAgeDays, limit) {
|
|
34590
|
-
const home =
|
|
32601
|
+
const home = homedir17();
|
|
34591
32602
|
const results = [];
|
|
34592
32603
|
const searchPaths = [
|
|
34593
32604
|
{ pattern: `${home}/.claude/projects`, agent: "claude-code" },
|
|
@@ -34669,23 +32680,23 @@ function bridgeEventIterable(bridge, signal) {
|
|
|
34669
32680
|
return {
|
|
34670
32681
|
[Symbol.asyncIterator]() {
|
|
34671
32682
|
const buffer = [];
|
|
34672
|
-
let
|
|
32683
|
+
let resolve8 = null;
|
|
34673
32684
|
let done = false;
|
|
34674
32685
|
const unsub = bridge.onEvent((event) => {
|
|
34675
32686
|
if (done)
|
|
34676
32687
|
return;
|
|
34677
32688
|
buffer.push(event);
|
|
34678
|
-
if (
|
|
34679
|
-
|
|
34680
|
-
|
|
32689
|
+
if (resolve8) {
|
|
32690
|
+
resolve8();
|
|
32691
|
+
resolve8 = null;
|
|
34681
32692
|
}
|
|
34682
32693
|
});
|
|
34683
32694
|
const cleanup = () => {
|
|
34684
32695
|
done = true;
|
|
34685
32696
|
unsub();
|
|
34686
|
-
if (
|
|
34687
|
-
|
|
34688
|
-
|
|
32697
|
+
if (resolve8) {
|
|
32698
|
+
resolve8();
|
|
32699
|
+
resolve8 = null;
|
|
34689
32700
|
}
|
|
34690
32701
|
};
|
|
34691
32702
|
signal?.addEventListener("abort", cleanup, { once: true });
|
|
@@ -34698,7 +32709,7 @@ function bridgeEventIterable(bridge, signal) {
|
|
|
34698
32709
|
return { done: false, value: buffer.shift() };
|
|
34699
32710
|
}
|
|
34700
32711
|
await new Promise((r) => {
|
|
34701
|
-
|
|
32712
|
+
resolve8 = r;
|
|
34702
32713
|
});
|
|
34703
32714
|
}
|
|
34704
32715
|
},
|
|
@@ -34717,8 +32728,8 @@ function getEventSessionId(event) {
|
|
|
34717
32728
|
function trackedSequencedEventId(event) {
|
|
34718
32729
|
return `${getEventSessionId(event) ?? "unknown"}:${event.seq}`;
|
|
34719
32730
|
}
|
|
34720
|
-
function approvalInboxItemId(sessionId, turnId, blockId,
|
|
34721
|
-
return `approval:${sessionId}:${turnId}:${blockId}:v${
|
|
32731
|
+
function approvalInboxItemId(sessionId, turnId, blockId, version2) {
|
|
32732
|
+
return `approval:${sessionId}:${turnId}:${blockId}:v${version2}`;
|
|
34722
32733
|
}
|
|
34723
32734
|
function projectApprovalInboxItem(snapshot, turn, block) {
|
|
34724
32735
|
const normalized = normalizeApprovalRequest(snapshot.session, turn.id, block);
|
|
@@ -34827,9 +32838,9 @@ var sessionRouter = t.router({
|
|
|
34827
32838
|
adapterType: exports_external.string().optional(),
|
|
34828
32839
|
name: exports_external.string().optional()
|
|
34829
32840
|
})).mutation(async ({ input, ctx }) => {
|
|
34830
|
-
const sessionFilename =
|
|
32841
|
+
const sessionFilename = basename8(input.sessionPath, ".jsonl");
|
|
34831
32842
|
const parentDir = input.sessionPath.substring(0, input.sessionPath.lastIndexOf("/"));
|
|
34832
|
-
const dirName =
|
|
32843
|
+
const dirName = basename8(parentDir);
|
|
34833
32844
|
let cwd;
|
|
34834
32845
|
if (dirName.startsWith("-")) {
|
|
34835
32846
|
const candidate = "/" + dirName.slice(1).replace(/-/g, "/");
|
|
@@ -35129,7 +33140,7 @@ var workspaceRouter = t.router({
|
|
|
35129
33140
|
});
|
|
35130
33141
|
}
|
|
35131
33142
|
const adapterType = input.adapter ?? "claude-code";
|
|
35132
|
-
const name = input.name ??
|
|
33143
|
+
const name = input.name ?? basename8(projectPath);
|
|
35133
33144
|
return ctx.bridge.createSession(adapterType, {
|
|
35134
33145
|
name,
|
|
35135
33146
|
cwd: projectPath
|
|
@@ -35376,7 +33387,8 @@ var BACKOFF_MULTIPLIER = 2;
|
|
|
35376
33387
|
var LEGACY_CLIENT_ID = "__legacy__";
|
|
35377
33388
|
function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
35378
33389
|
const { secure = true, events: events2 } = options;
|
|
35379
|
-
const
|
|
33390
|
+
const publicRelayUrl = options.publicRelayUrl?.trim() || relayUrl;
|
|
33391
|
+
const qrPayload = createQRPayload(identity2.publicKey, publicRelayUrl, options.fallbackRelayUrls);
|
|
35380
33392
|
let ws = null;
|
|
35381
33393
|
let eventUnsub = null;
|
|
35382
33394
|
let stopped = false;
|
|
@@ -35390,12 +33402,12 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
35390
33402
|
const bridgeKeyHex = bytesToHex2(identity2.publicKey);
|
|
35391
33403
|
const url2 = buildRelayUrl(relayUrl, qrPayload.room, bridgeKeyHex);
|
|
35392
33404
|
console.log(`[relay-client] connecting to relay (room: ${qrPayload.room})`);
|
|
35393
|
-
events2?.onConnecting?.({ relayUrl, room: qrPayload.room });
|
|
33405
|
+
events2?.onConnecting?.({ relayUrl: publicRelayUrl, room: qrPayload.room });
|
|
35394
33406
|
ws = new WebSocket(url2, relayWebSocketOptions(relayUrl));
|
|
35395
33407
|
ws.addEventListener("open", () => {
|
|
35396
33408
|
console.log(`[relay-client] connected to relay (room: ${qrPayload.room})`);
|
|
35397
33409
|
backoff = INITIAL_BACKOFF_MS;
|
|
35398
|
-
events2?.onConnected?.({ relayUrl, room: qrPayload.room });
|
|
33410
|
+
events2?.onConnected?.({ relayUrl: publicRelayUrl, room: qrPayload.room });
|
|
35399
33411
|
});
|
|
35400
33412
|
ws.addEventListener("message", (event) => {
|
|
35401
33413
|
handleRelaySocketMessage(event.data);
|
|
@@ -35403,7 +33415,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
35403
33415
|
ws.addEventListener("close", (event) => {
|
|
35404
33416
|
console.log(`[relay-client] disconnected (code: ${event.code}, reason: ${event.reason})`);
|
|
35405
33417
|
events2?.onClosed?.({
|
|
35406
|
-
relayUrl,
|
|
33418
|
+
relayUrl: publicRelayUrl,
|
|
35407
33419
|
room: qrPayload.room,
|
|
35408
33420
|
code: event.code,
|
|
35409
33421
|
reason: event.reason
|
|
@@ -35414,7 +33426,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
35414
33426
|
ws.addEventListener("error", () => {
|
|
35415
33427
|
const error48 = new Error("Relay websocket error");
|
|
35416
33428
|
console.error("[relay-client] connection error");
|
|
35417
|
-
events2?.onError?.({ relayUrl, room: qrPayload.room, error: error48 });
|
|
33429
|
+
events2?.onError?.({ relayUrl: publicRelayUrl, room: qrPayload.room, error: error48 });
|
|
35418
33430
|
});
|
|
35419
33431
|
}
|
|
35420
33432
|
function handleRelaySocketMessage(raw) {
|
|
@@ -35468,7 +33480,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
35468
33480
|
replaceOlderPeerForSameDevice(peer);
|
|
35469
33481
|
ensureBridgeEventSubscription();
|
|
35470
33482
|
console.log(`[relay-client] secure handshake complete (peer: ${pubHex.slice(0, 12)}..., device: ${peer.deviceId}, client: ${clientId})`);
|
|
35471
|
-
events2?.onPaired?.({ relayUrl, room: qrPayload.room, remotePublicKey });
|
|
33483
|
+
events2?.onPaired?.({ relayUrl: publicRelayUrl, room: qrPayload.room, remotePublicKey });
|
|
35472
33484
|
sendExistingSessions((json2) => {
|
|
35473
33485
|
if (peer.transport.isReady()) {
|
|
35474
33486
|
peer.transport.send(json2);
|
|
@@ -35481,7 +33493,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
35481
33493
|
onError: (err) => {
|
|
35482
33494
|
console.error("[relay-client] secure transport error:", err.message);
|
|
35483
33495
|
log.error("trns:cry", `decrypt failed for ${clientId} \u2014 resetting handshake: ${err.message}`);
|
|
35484
|
-
events2?.onError?.({ relayUrl, room: qrPayload.room, error: err });
|
|
33496
|
+
events2?.onError?.({ relayUrl: publicRelayUrl, room: qrPayload.room, error: err });
|
|
35485
33497
|
sendRelayClose(clientId, 4002, "Transport reset");
|
|
35486
33498
|
teardownSecurePeer(clientId);
|
|
35487
33499
|
},
|
|
@@ -35680,7 +33692,7 @@ function connectToRelay(relayUrl, identity2, bridge, options = {}) {
|
|
|
35680
33692
|
if (stopped)
|
|
35681
33693
|
return;
|
|
35682
33694
|
console.log(`[relay-client] reconnecting in ${backoff}ms...`);
|
|
35683
|
-
events2?.onReconnectScheduled?.({ relayUrl, room: qrPayload.room, delayMs: backoff });
|
|
33695
|
+
events2?.onReconnectScheduled?.({ relayUrl: publicRelayUrl, room: qrPayload.room, delayMs: backoff });
|
|
35684
33696
|
reconnectTimer = setTimeout(() => {
|
|
35685
33697
|
reconnectTimer = null;
|
|
35686
33698
|
connect();
|
|
@@ -35772,13 +33784,13 @@ function asStringPayload(raw) {
|
|
|
35772
33784
|
// ../../node_modules/.bun/hono@4.12.10/node_modules/hono/dist/compose.js
|
|
35773
33785
|
var compose = (middleware, onError, onNotFound) => {
|
|
35774
33786
|
return (context, next) => {
|
|
35775
|
-
let
|
|
33787
|
+
let index = -1;
|
|
35776
33788
|
return dispatch(0);
|
|
35777
33789
|
async function dispatch(i) {
|
|
35778
|
-
if (i <=
|
|
33790
|
+
if (i <= index) {
|
|
35779
33791
|
throw new Error("next() called multiple times");
|
|
35780
33792
|
}
|
|
35781
|
-
|
|
33793
|
+
index = i;
|
|
35782
33794
|
let res;
|
|
35783
33795
|
let isError = false;
|
|
35784
33796
|
let handler;
|
|
@@ -35875,8 +33887,8 @@ var handleParsingNestedValues = (form, key, value) => {
|
|
|
35875
33887
|
}
|
|
35876
33888
|
let nestedForm = form;
|
|
35877
33889
|
const keys = key.split(".");
|
|
35878
|
-
keys.forEach((key2,
|
|
35879
|
-
if (
|
|
33890
|
+
keys.forEach((key2, index) => {
|
|
33891
|
+
if (index === keys.length - 1) {
|
|
35880
33892
|
nestedForm[key2] = value;
|
|
35881
33893
|
} else {
|
|
35882
33894
|
if (!nestedForm[key2] || typeof nestedForm[key2] !== "object" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) {
|
|
@@ -35902,8 +33914,8 @@ var splitRoutingPath = (routePath) => {
|
|
|
35902
33914
|
};
|
|
35903
33915
|
var extractGroupsFromPath = (path2) => {
|
|
35904
33916
|
const groups = [];
|
|
35905
|
-
path2 = path2.replace(/\{[^}]+\}/g, (match,
|
|
35906
|
-
const mark = `@${
|
|
33917
|
+
path2 = path2.replace(/\{[^}]+\}/g, (match, index) => {
|
|
33918
|
+
const mark = `@${index}`;
|
|
35907
33919
|
groups.push([mark, match]);
|
|
35908
33920
|
return mark;
|
|
35909
33921
|
});
|
|
@@ -36161,7 +34173,7 @@ var HonoRequest = class {
|
|
|
36161
34173
|
return bodyCache[key] = raw[key]();
|
|
36162
34174
|
};
|
|
36163
34175
|
json() {
|
|
36164
|
-
return this.#cachedBody("text").then((
|
|
34176
|
+
return this.#cachedBody("text").then((text) => JSON.parse(text));
|
|
36165
34177
|
}
|
|
36166
34178
|
text() {
|
|
36167
34179
|
return this.#cachedBody("text");
|
|
@@ -36382,8 +34394,8 @@ var Context = class {
|
|
|
36382
34394
|
}
|
|
36383
34395
|
newResponse = (...args) => this.#newResponse(...args);
|
|
36384
34396
|
body = (data, arg, headers) => this.#newResponse(data, arg, headers);
|
|
36385
|
-
text = (
|
|
36386
|
-
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(
|
|
34397
|
+
text = (text, arg, headers) => {
|
|
34398
|
+
return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(text, arg, setDefaultContentType(TEXT_PLAIN, headers));
|
|
36387
34399
|
};
|
|
36388
34400
|
json = (object2, arg, headers) => {
|
|
36389
34401
|
return this.#newResponse(JSON.stringify(object2), arg, setDefaultContentType("application/json", headers));
|
|
@@ -36647,8 +34659,8 @@ function match(method, path2) {
|
|
|
36647
34659
|
if (!match3) {
|
|
36648
34660
|
return [[], emptyParam];
|
|
36649
34661
|
}
|
|
36650
|
-
const
|
|
36651
|
-
return [matcher[1][
|
|
34662
|
+
const index = match3.indexOf("", 1);
|
|
34663
|
+
return [matcher[1][index], match3];
|
|
36652
34664
|
};
|
|
36653
34665
|
this.match = match2;
|
|
36654
34666
|
return match2(method, path2);
|
|
@@ -36683,7 +34695,7 @@ var Node = class _Node {
|
|
|
36683
34695
|
#index;
|
|
36684
34696
|
#varIndex;
|
|
36685
34697
|
#children = /* @__PURE__ */ Object.create(null);
|
|
36686
|
-
insert(tokens,
|
|
34698
|
+
insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
|
|
36687
34699
|
if (tokens.length === 0) {
|
|
36688
34700
|
if (this.#index !== undefined) {
|
|
36689
34701
|
throw PATH_ERROR;
|
|
@@ -36691,7 +34703,7 @@ var Node = class _Node {
|
|
|
36691
34703
|
if (pathErrorCheckOnly) {
|
|
36692
34704
|
return;
|
|
36693
34705
|
}
|
|
36694
|
-
this.#index =
|
|
34706
|
+
this.#index = index;
|
|
36695
34707
|
return;
|
|
36696
34708
|
}
|
|
36697
34709
|
const [token, ...restTokens] = tokens;
|
|
@@ -36737,7 +34749,7 @@ var Node = class _Node {
|
|
|
36737
34749
|
node = this.#children[token] = new _Node;
|
|
36738
34750
|
}
|
|
36739
34751
|
}
|
|
36740
|
-
node.insert(restTokens,
|
|
34752
|
+
node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
|
|
36741
34753
|
}
|
|
36742
34754
|
buildRegExpStr() {
|
|
36743
34755
|
const childKeys = Object.keys(this.#children).sort(compareKey);
|
|
@@ -36762,7 +34774,7 @@ var Node = class _Node {
|
|
|
36762
34774
|
var Trie = class {
|
|
36763
34775
|
#context = { varIndex: 0 };
|
|
36764
34776
|
#root = new Node;
|
|
36765
|
-
insert(path2,
|
|
34777
|
+
insert(path2, index, pathErrorCheckOnly) {
|
|
36766
34778
|
const paramAssoc = [];
|
|
36767
34779
|
const groups = [];
|
|
36768
34780
|
for (let i = 0;; ) {
|
|
@@ -36788,7 +34800,7 @@ var Trie = class {
|
|
|
36788
34800
|
}
|
|
36789
34801
|
}
|
|
36790
34802
|
}
|
|
36791
|
-
this.#root.insert(tokens,
|
|
34803
|
+
this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);
|
|
36792
34804
|
return paramAssoc;
|
|
36793
34805
|
}
|
|
36794
34806
|
buildRegExp() {
|
|
@@ -36998,11 +35010,11 @@ var PreparedRegExpRouter = class {
|
|
|
36998
35010
|
if (!map2) {
|
|
36999
35011
|
matcher[2][path2][0].push([handler, {}]);
|
|
37000
35012
|
} else {
|
|
37001
|
-
indexes.forEach((
|
|
37002
|
-
if (typeof
|
|
37003
|
-
matcher[1][
|
|
35013
|
+
indexes.forEach((index) => {
|
|
35014
|
+
if (typeof index === "number") {
|
|
35015
|
+
matcher[1][index].push([handler, map2]);
|
|
37004
35016
|
} else {
|
|
37005
|
-
matcher[2][
|
|
35017
|
+
matcher[2][index || path2][0].push([handler, map2]);
|
|
37006
35018
|
}
|
|
37007
35019
|
});
|
|
37008
35020
|
}
|
|
@@ -37481,22 +35493,22 @@ var jsonContentTypeHandler = {
|
|
|
37481
35493
|
message: '"input" needs to be an object when doing a batch call'
|
|
37482
35494
|
});
|
|
37483
35495
|
const acc = emptyObject();
|
|
37484
|
-
for (const
|
|
37485
|
-
const input = inputs[
|
|
35496
|
+
for (const index of paths.keys()) {
|
|
35497
|
+
const input = inputs[index];
|
|
37486
35498
|
if (input !== undefined)
|
|
37487
|
-
acc[
|
|
35499
|
+
acc[index] = opts.router._def._config.transformer.input.deserialize(input);
|
|
37488
35500
|
}
|
|
37489
35501
|
return acc;
|
|
37490
35502
|
});
|
|
37491
|
-
const calls = await Promise.all(paths.map(async (path2,
|
|
35503
|
+
const calls = await Promise.all(paths.map(async (path2, index) => {
|
|
37492
35504
|
const procedure2 = await getProcedureAtPath(opts.router, path2);
|
|
37493
35505
|
return {
|
|
37494
|
-
batchIndex:
|
|
35506
|
+
batchIndex: index,
|
|
37495
35507
|
path: path2,
|
|
37496
35508
|
procedure: procedure2,
|
|
37497
35509
|
getRawInput: async () => {
|
|
37498
35510
|
const inputs = await getInputs.read();
|
|
37499
|
-
let input = inputs[
|
|
35511
|
+
let input = inputs[index];
|
|
37500
35512
|
if ((procedure2 === null || procedure2 === undefined ? undefined : procedure2._def.type) === "subscription") {
|
|
37501
35513
|
var _ref2, _opts$headers$get;
|
|
37502
35514
|
const lastEventId = (_ref2 = (_opts$headers$get = opts.headers.get("last-event-id")) !== null && _opts$headers$get !== undefined ? _opts$headers$get : opts.searchParams.get("lastEventId")) !== null && _ref2 !== undefined ? _ref2 : opts.searchParams.get("Last-Event-Id");
|
|
@@ -37512,7 +35524,7 @@ var jsonContentTypeHandler = {
|
|
|
37512
35524
|
},
|
|
37513
35525
|
result: () => {
|
|
37514
35526
|
var _getInputs$result;
|
|
37515
|
-
return (_getInputs$result = getInputs.result()) === null || _getInputs$result === undefined ? undefined : _getInputs$result[
|
|
35527
|
+
return (_getInputs$result = getInputs.result()) === null || _getInputs$result === undefined ? undefined : _getInputs$result[index];
|
|
37516
35528
|
}
|
|
37517
35529
|
};
|
|
37518
35530
|
}));
|
|
@@ -37676,8 +35688,8 @@ var Unpromise = class Unpromise2 {
|
|
|
37676
35688
|
status: "fulfilled",
|
|
37677
35689
|
value
|
|
37678
35690
|
};
|
|
37679
|
-
subscribers === null || subscribers === undefined || subscribers.forEach(({ resolve:
|
|
37680
|
-
|
|
35691
|
+
subscribers === null || subscribers === undefined || subscribers.forEach(({ resolve: resolve8 }) => {
|
|
35692
|
+
resolve8(value);
|
|
37681
35693
|
});
|
|
37682
35694
|
});
|
|
37683
35695
|
if ("catch" in thenReturn)
|
|
@@ -37785,28 +35797,28 @@ function resolveSelfTuple(promise2) {
|
|
|
37785
35797
|
return Unpromise.proxy(promise2).then(() => [promise2]);
|
|
37786
35798
|
}
|
|
37787
35799
|
function withResolvers() {
|
|
37788
|
-
let
|
|
35800
|
+
let resolve8;
|
|
37789
35801
|
let reject;
|
|
37790
35802
|
const promise2 = new Promise((_resolve, _reject) => {
|
|
37791
|
-
|
|
35803
|
+
resolve8 = _resolve;
|
|
37792
35804
|
reject = _reject;
|
|
37793
35805
|
});
|
|
37794
35806
|
return {
|
|
37795
35807
|
promise: promise2,
|
|
37796
|
-
resolve:
|
|
35808
|
+
resolve: resolve8,
|
|
37797
35809
|
reject
|
|
37798
35810
|
};
|
|
37799
35811
|
}
|
|
37800
35812
|
function listWithMember(arr, member) {
|
|
37801
35813
|
return [...arr, member];
|
|
37802
35814
|
}
|
|
37803
|
-
function listWithoutIndex(arr,
|
|
37804
|
-
return [...arr.slice(0,
|
|
35815
|
+
function listWithoutIndex(arr, index) {
|
|
35816
|
+
return [...arr.slice(0, index), ...arr.slice(index + 1)];
|
|
37805
35817
|
}
|
|
37806
35818
|
function listWithoutMember(arr, member) {
|
|
37807
|
-
const
|
|
37808
|
-
if (
|
|
37809
|
-
return listWithoutIndex(arr,
|
|
35819
|
+
const index = arr.indexOf(member);
|
|
35820
|
+
if (index !== -1)
|
|
35821
|
+
return listWithoutIndex(arr, index);
|
|
37810
35822
|
return arr;
|
|
37811
35823
|
}
|
|
37812
35824
|
var _Symbol;
|
|
@@ -37839,8 +35851,8 @@ function timerResource(ms) {
|
|
|
37839
35851
|
return makeResource({ start() {
|
|
37840
35852
|
if (timer)
|
|
37841
35853
|
throw new Error("Timer already started");
|
|
37842
|
-
const promise2 = new Promise((
|
|
37843
|
-
timer = setTimeout(() =>
|
|
35854
|
+
const promise2 = new Promise((resolve8) => {
|
|
35855
|
+
timer = setTimeout(() => resolve8(disposablePromiseTimerResult), ms);
|
|
37844
35856
|
});
|
|
37845
35857
|
return promise2;
|
|
37846
35858
|
} }, () => {
|
|
@@ -38043,15 +36055,15 @@ function _takeWithGrace() {
|
|
|
38043
36055
|
return _takeWithGrace.apply(this, arguments);
|
|
38044
36056
|
}
|
|
38045
36057
|
function createDeferred() {
|
|
38046
|
-
let
|
|
36058
|
+
let resolve8;
|
|
38047
36059
|
let reject;
|
|
38048
36060
|
const promise2 = new Promise((res, rej) => {
|
|
38049
|
-
|
|
36061
|
+
resolve8 = res;
|
|
38050
36062
|
reject = rej;
|
|
38051
36063
|
});
|
|
38052
36064
|
return {
|
|
38053
36065
|
promise: promise2,
|
|
38054
|
-
resolve:
|
|
36066
|
+
resolve: resolve8,
|
|
38055
36067
|
reject
|
|
38056
36068
|
};
|
|
38057
36069
|
}
|
|
@@ -39019,9 +37031,9 @@ async function resolveResponse(opts) {
|
|
|
39019
37031
|
});
|
|
39020
37032
|
const stream = jsonlStreamProducer((0, import_objectSpread24.default)((0, import_objectSpread24.default)({}, config2.jsonl), {}, {
|
|
39021
37033
|
maxDepth: Infinity,
|
|
39022
|
-
data: rpcCalls.map(async (res,
|
|
37034
|
+
data: rpcCalls.map(async (res, index) => {
|
|
39023
37035
|
const [error48, result] = await res;
|
|
39024
|
-
const call = info.calls[
|
|
37036
|
+
const call = info.calls[index];
|
|
39025
37037
|
if (error48) {
|
|
39026
37038
|
var _procedure$_def$type, _procedure;
|
|
39027
37039
|
return { error: getErrorShape({
|
|
@@ -39083,8 +37095,8 @@ async function resolveResponse(opts) {
|
|
|
39083
37095
|
}), undefined];
|
|
39084
37096
|
return res;
|
|
39085
37097
|
});
|
|
39086
|
-
const resultAsRPCResponse = results.map(([error48, result],
|
|
39087
|
-
const call = info.calls[
|
|
37098
|
+
const resultAsRPCResponse = results.map(([error48, result], index) => {
|
|
37099
|
+
const call = info.calls[index];
|
|
39088
37100
|
if (error48) {
|
|
39089
37101
|
var _call$procedure$_def$4, _call$procedure5;
|
|
39090
37102
|
return { error: getErrorShape({
|
|
@@ -39189,7 +37201,7 @@ async function fetchRequestHandler(opts) {
|
|
|
39189
37201
|
|
|
39190
37202
|
// ../../node_modules/.bun/hono@4.12.10/node_modules/hono/dist/helper/route/index.js
|
|
39191
37203
|
var matchedRoutes = (c) => c.req[GET_MATCH_RESULT][0].map(([[, route2]]) => route2);
|
|
39192
|
-
var routePath = (c,
|
|
37204
|
+
var routePath = (c, index) => matchedRoutes(c).at(index ?? c.req.routeIndex)?.path ?? "";
|
|
39193
37205
|
|
|
39194
37206
|
// ../../node_modules/.bun/@hono+trpc-server@0.4.2+2b2485a92adeb0d0/node_modules/@hono/trpc-server/dist/index.js
|
|
39195
37207
|
var trpcServer = ({ endpoint, createContext, ...rest }) => {
|
|
@@ -39282,14 +37294,14 @@ function parseTRPCMessage(obj, transformer) {
|
|
|
39282
37294
|
}
|
|
39283
37295
|
// ../../apps/desktop/src/core/pairing/runtime/bridge/server-trpc.ts
|
|
39284
37296
|
import { realpathSync as realpathSync3 } from "fs";
|
|
39285
|
-
import { homedir as
|
|
37297
|
+
import { homedir as homedir18 } from "os";
|
|
39286
37298
|
function resolveCurrentDirectory() {
|
|
39287
37299
|
try {
|
|
39288
37300
|
const config2 = resolveConfig();
|
|
39289
37301
|
const configuredRoot = config2.workspace?.root;
|
|
39290
37302
|
if (!configuredRoot)
|
|
39291
37303
|
return process.cwd();
|
|
39292
|
-
const expanded = configuredRoot.replace(/^~/,
|
|
37304
|
+
const expanded = configuredRoot.replace(/^~/, homedir18());
|
|
39293
37305
|
return realpathSync3(expanded);
|
|
39294
37306
|
} catch {
|
|
39295
37307
|
return process.cwd();
|
|
@@ -39352,14 +37364,14 @@ function startBridgeServerTRPC(options) {
|
|
|
39352
37364
|
}
|
|
39353
37365
|
};
|
|
39354
37366
|
}
|
|
39355
|
-
async function handleTRPCMessage(ws, state,
|
|
37367
|
+
async function handleTRPCMessage(ws, state, text) {
|
|
39356
37368
|
const send = createSender(ws, state);
|
|
39357
37369
|
if (!bridgeRouter) {
|
|
39358
|
-
await handleLegacyFallback(ws, state,
|
|
37370
|
+
await handleLegacyFallback(ws, state, text);
|
|
39359
37371
|
return;
|
|
39360
37372
|
}
|
|
39361
37373
|
try {
|
|
39362
|
-
const msgJSON = JSON.parse(
|
|
37374
|
+
const msgJSON = JSON.parse(text);
|
|
39363
37375
|
const msgs = Array.isArray(msgJSON) ? msgJSON : [msgJSON];
|
|
39364
37376
|
for (const raw2 of msgs) {
|
|
39365
37377
|
log.info("rpc:req", `\u2192 ${raw2.params?.path ?? raw2.method ?? "?"}`);
|
|
@@ -39436,8 +37448,8 @@ function startBridgeServerTRPC(options) {
|
|
|
39436
37448
|
}
|
|
39437
37449
|
const iterable = isObservable(result) ? observableToAsyncIterable(result, abortController.signal) : result;
|
|
39438
37450
|
const iterator = iterable[Symbol.asyncIterator]();
|
|
39439
|
-
const abortPromise = new Promise((
|
|
39440
|
-
abortController.signal.addEventListener("abort", () =>
|
|
37451
|
+
const abortPromise = new Promise((resolve8) => {
|
|
37452
|
+
abortController.signal.addEventListener("abort", () => resolve8("abort"), {
|
|
39441
37453
|
once: true
|
|
39442
37454
|
});
|
|
39443
37455
|
});
|
|
@@ -39548,7 +37560,7 @@ function startBridgeServerTRPC(options) {
|
|
|
39548
37560
|
});
|
|
39549
37561
|
}
|
|
39550
37562
|
}
|
|
39551
|
-
async function handleLegacyFallback(ws, state,
|
|
37563
|
+
async function handleLegacyFallback(ws, state, text) {
|
|
39552
37564
|
const sendRaw = (json2) => {
|
|
39553
37565
|
if (state.transport) {
|
|
39554
37566
|
state.transport.send(json2);
|
|
@@ -39558,7 +37570,7 @@ function startBridgeServerTRPC(options) {
|
|
|
39558
37570
|
};
|
|
39559
37571
|
let req;
|
|
39560
37572
|
try {
|
|
39561
|
-
req = JSON.parse(
|
|
37573
|
+
req = JSON.parse(text);
|
|
39562
37574
|
} catch {
|
|
39563
37575
|
sendRaw(JSON.stringify({ id: null, error: { code: -32700, message: "Parse error" } }));
|
|
39564
37576
|
return;
|
|
@@ -39672,8 +37684,8 @@ function startBridgeServerTRPC(options) {
|
|
|
39672
37684
|
const data = typeof raw2 === "string" ? raw2 : new Uint8Array(raw2);
|
|
39673
37685
|
state.transport.receive(data);
|
|
39674
37686
|
} else {
|
|
39675
|
-
const
|
|
39676
|
-
handleTRPCMessage(ws, state,
|
|
37687
|
+
const text = typeof raw2 === "string" ? raw2 : new TextDecoder().decode(raw2);
|
|
37688
|
+
handleTRPCMessage(ws, state, text);
|
|
39677
37689
|
}
|
|
39678
37690
|
},
|
|
39679
37691
|
close(ws) {
|
|
@@ -39782,6 +37794,8 @@ async function startPairingRuntime(options) {
|
|
|
39782
37794
|
}
|
|
39783
37795
|
const relayConnection = connectToRelay(relayUrl, identity2, bridge, {
|
|
39784
37796
|
secure: true,
|
|
37797
|
+
publicRelayUrl: options?.advertisedRelayUrl ?? undefined,
|
|
37798
|
+
fallbackRelayUrls: options?.fallbackRelayUrls,
|
|
39785
37799
|
events: options?.relayEvents
|
|
39786
37800
|
});
|
|
39787
37801
|
await autoStartConfiguredSessions(bridge, config2.sessions);
|
|
@@ -39809,7 +37823,7 @@ async function autoStartConfiguredSessions(bridge, sessions3) {
|
|
|
39809
37823
|
try {
|
|
39810
37824
|
const session = await bridge.createSession(entry.adapter, {
|
|
39811
37825
|
name: entry.name,
|
|
39812
|
-
cwd: entry.cwd?.replace(/^~/,
|
|
37826
|
+
cwd: entry.cwd?.replace(/^~/, homedir19()),
|
|
39813
37827
|
options: entry.options
|
|
39814
37828
|
});
|
|
39815
37829
|
console.log(`[bridge] session started: ${session.name} (${entry.adapter})`);
|
|
@@ -39823,6 +37837,7 @@ async function autoStartConfiguredSessions(bridge, sessions3) {
|
|
|
39823
37837
|
// ../../apps/desktop/src/core/pairing/supervisor.ts
|
|
39824
37838
|
var SCOUT_PAIR_REFRESH_LEEWAY_MS = 30000;
|
|
39825
37839
|
var SCOUT_PAIR_RESTART_DELAY_MS = 2000;
|
|
37840
|
+
var BONJOUR_SERVICE_TYPE = "_scout-pair._tcp";
|
|
39826
37841
|
async function runScoutPairingSupervisor() {
|
|
39827
37842
|
clearStalePairingRuntimeFiles();
|
|
39828
37843
|
const existingPid = readPairingRuntimePid();
|
|
@@ -39844,7 +37859,8 @@ async function runScoutPairingSupervisor() {
|
|
|
39844
37859
|
refreshTimer: null,
|
|
39845
37860
|
intentionalStop: false,
|
|
39846
37861
|
runtime: null,
|
|
39847
|
-
relay: null
|
|
37862
|
+
relay: null,
|
|
37863
|
+
bonjour: null
|
|
39848
37864
|
};
|
|
39849
37865
|
const shutdown = async () => {
|
|
39850
37866
|
state.intentionalStop = true;
|
|
@@ -39872,6 +37888,8 @@ async function startSupervisorRuntime(state) {
|
|
|
39872
37888
|
const config2 = resolvedPairingConfig();
|
|
39873
37889
|
const relayPort = config2.port + 1;
|
|
39874
37890
|
const resolvedRelayUrl = config2.relay?.trim() || null;
|
|
37891
|
+
const identity2 = loadOrCreateIdentity();
|
|
37892
|
+
const publicKeyHex = bytesToHex2(identity2.publicKey);
|
|
39875
37893
|
writeCurrent(state, {
|
|
39876
37894
|
status: "starting",
|
|
39877
37895
|
statusLabel: "Starting",
|
|
@@ -39883,12 +37901,24 @@ async function startSupervisorRuntime(state) {
|
|
|
39883
37901
|
});
|
|
39884
37902
|
const emitStatus = createStatusWriter(state);
|
|
39885
37903
|
try {
|
|
39886
|
-
const
|
|
37904
|
+
const managedRelay = resolvedRelayUrl ? null : (() => {
|
|
39887
37905
|
state.relay = startManagedRelay(relayPort);
|
|
39888
|
-
return state.relay
|
|
37906
|
+
return state.relay;
|
|
39889
37907
|
})();
|
|
39890
|
-
|
|
37908
|
+
const activeRelayUrl = resolvedRelayUrl ?? managedRelay?.relayUrl;
|
|
37909
|
+
const connectRelayUrl = resolvedRelayUrl ?? managedRelay?.connectUrl ?? managedRelay?.relayUrl;
|
|
37910
|
+
if (!activeRelayUrl || !connectRelayUrl) {
|
|
37911
|
+
throw new Error("Scout pairing relay URL is not configured.");
|
|
37912
|
+
}
|
|
37913
|
+
state.bonjour = managedRelay ? startBonjourRelayAdvertisement({
|
|
37914
|
+
port: relayPort,
|
|
39891
37915
|
relayUrl: activeRelayUrl,
|
|
37916
|
+
publicKeyHex
|
|
37917
|
+
}) : null;
|
|
37918
|
+
state.runtime = await startPairingRuntime({
|
|
37919
|
+
relayUrl: connectRelayUrl,
|
|
37920
|
+
advertisedRelayUrl: activeRelayUrl,
|
|
37921
|
+
fallbackRelayUrls: managedRelay?.fallbackRelayUrls,
|
|
39892
37922
|
relayEvents: {
|
|
39893
37923
|
onConnecting() {
|
|
39894
37924
|
emitStatus("connecting", `Connecting to ${activeRelayUrl}`);
|
|
@@ -39911,7 +37941,6 @@ async function startSupervisorRuntime(state) {
|
|
|
39911
37941
|
if (!payload) {
|
|
39912
37942
|
throw new Error("Scout pairing runtime did not produce a QR payload.");
|
|
39913
37943
|
}
|
|
39914
|
-
const identity2 = loadOrCreateIdentity();
|
|
39915
37944
|
writeCurrent(state, {
|
|
39916
37945
|
status: "connecting",
|
|
39917
37946
|
statusLabel: "Pairing Ready",
|
|
@@ -39928,7 +37957,7 @@ async function startSupervisorRuntime(state) {
|
|
|
39928
37957
|
},
|
|
39929
37958
|
childPid: null
|
|
39930
37959
|
}, {
|
|
39931
|
-
identityFingerprint:
|
|
37960
|
+
identityFingerprint: publicKeyHex.slice(0, 16),
|
|
39932
37961
|
trustedPeerCount: trustedPeerCount()
|
|
39933
37962
|
});
|
|
39934
37963
|
schedulePairingRefresh(state, payload);
|
|
@@ -40002,6 +38031,9 @@ function clearRefreshTimer(state) {
|
|
|
40002
38031
|
}
|
|
40003
38032
|
}
|
|
40004
38033
|
async function stopSupervisorRuntime(state) {
|
|
38034
|
+
try {
|
|
38035
|
+
state.bonjour?.stop();
|
|
38036
|
+
} catch {}
|
|
40005
38037
|
try {
|
|
40006
38038
|
await state.runtime?.stop();
|
|
40007
38039
|
} catch {}
|
|
@@ -40010,6 +38042,57 @@ async function stopSupervisorRuntime(state) {
|
|
|
40010
38042
|
} catch {}
|
|
40011
38043
|
state.runtime = null;
|
|
40012
38044
|
state.relay = null;
|
|
38045
|
+
state.bonjour = null;
|
|
38046
|
+
}
|
|
38047
|
+
function startBonjourRelayAdvertisement(input) {
|
|
38048
|
+
if (process.platform !== "darwin") {
|
|
38049
|
+
return null;
|
|
38050
|
+
}
|
|
38051
|
+
const scheme = relayScheme(input.relayUrl);
|
|
38052
|
+
const fingerprint = input.publicKeyHex.slice(0, 16);
|
|
38053
|
+
const serviceName = `OpenScout ${fingerprint}`;
|
|
38054
|
+
const args = [
|
|
38055
|
+
"-R",
|
|
38056
|
+
serviceName,
|
|
38057
|
+
BONJOUR_SERVICE_TYPE,
|
|
38058
|
+
"local.",
|
|
38059
|
+
String(input.port),
|
|
38060
|
+
"v=1",
|
|
38061
|
+
`pk=${input.publicKeyHex}`,
|
|
38062
|
+
`fp=${fingerprint}`,
|
|
38063
|
+
`scheme=${scheme}`
|
|
38064
|
+
];
|
|
38065
|
+
let processRef = null;
|
|
38066
|
+
try {
|
|
38067
|
+
processRef = spawn4("/usr/bin/dns-sd", args, { stdio: "ignore" });
|
|
38068
|
+
processRef.on("error", (error48) => {
|
|
38069
|
+
console.warn(`[pairing] bonjour advertisement failed: ${error48.message}`);
|
|
38070
|
+
});
|
|
38071
|
+
processRef.on("exit", (code, signal) => {
|
|
38072
|
+
if (code !== 0 && signal !== "SIGTERM") {
|
|
38073
|
+
console.warn(`[pairing] bonjour advertisement exited (code=${code ?? "null"}, signal=${signal ?? "null"})`);
|
|
38074
|
+
}
|
|
38075
|
+
});
|
|
38076
|
+
console.log(`[pairing] bonjour advertising ${serviceName} on ${BONJOUR_SERVICE_TYPE} port ${input.port}`);
|
|
38077
|
+
} catch (error48) {
|
|
38078
|
+
const detail = error48 instanceof Error ? error48.message : String(error48);
|
|
38079
|
+
console.warn(`[pairing] bonjour advertisement unavailable: ${detail}`);
|
|
38080
|
+
return null;
|
|
38081
|
+
}
|
|
38082
|
+
return {
|
|
38083
|
+
stop() {
|
|
38084
|
+
processRef?.kill("SIGTERM");
|
|
38085
|
+
processRef = null;
|
|
38086
|
+
}
|
|
38087
|
+
};
|
|
38088
|
+
}
|
|
38089
|
+
function relayScheme(relayUrl) {
|
|
38090
|
+
try {
|
|
38091
|
+
const protocol = new URL(relayUrl).protocol;
|
|
38092
|
+
return protocol === "wss:" ? "wss" : "ws";
|
|
38093
|
+
} catch {
|
|
38094
|
+
return relayUrl.startsWith("wss://") ? "wss" : "ws";
|
|
38095
|
+
}
|
|
40013
38096
|
}
|
|
40014
38097
|
function writeCurrent(state, patch, overrides = {}) {
|
|
40015
38098
|
state.current = writePairingRuntimeSnapshot({
|