@openscout/scout 0.2.58 → 0.2.61

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.
@@ -956,19 +956,58 @@ function findStoredCerts() {
956
956
  return null;
957
957
  }
958
958
  }
959
- function getTailscaleHostname() {
959
+ function readTailscaleStatus() {
960
960
  try {
961
961
  const output = execSync("tailscale status --self=true --peers=false --json", {
962
962
  stdio: ["pipe", "pipe", "pipe"],
963
963
  timeout: 5000
964
964
  }).toString();
965
965
  const data = JSON.parse(output);
966
- const dnsName = data?.Self?.DNSName ?? "";
967
- return dnsName.replace(/\.$/, "") || null;
966
+ const dnsName = typeof data.Self?.DNSName === "string" ? data.Self.DNSName.replace(/\.$/, "") : "";
967
+ return {
968
+ backendState: typeof data.BackendState === "string" ? data.BackendState : null,
969
+ dnsName: dnsName || null,
970
+ online: data.Self?.Online !== false,
971
+ health: Array.isArray(data.Health) ? data.Health.filter((entry) => typeof entry === "string") : []
972
+ };
968
973
  } catch {
969
974
  return null;
970
975
  }
971
976
  }
977
+ function resolveRelayEndpointForTailscaleStatus(port, tailscale) {
978
+ const backendState = tailscale?.backendState?.trim().toLowerCase() ?? "";
979
+ const hostname = tailscale?.dnsName ?? null;
980
+ const tailscaleRunning = backendState === "running" && tailscale?.online !== false && Boolean(hostname);
981
+ const tls = resolveTls(tailscaleRunning ? hostname : null);
982
+ if (tailscaleRunning && hostname && tls) {
983
+ return {
984
+ relayUrl: `wss://${hostname}:${port}`,
985
+ options: { tls }
986
+ };
987
+ }
988
+ if (tailscaleRunning && hostname) {
989
+ pairingLog.warn("relay", "tailscale is running without TLS; falling back to insecure websocket relay", {
990
+ hostname,
991
+ port
992
+ });
993
+ return {
994
+ relayUrl: `ws://${hostname}:${port}`,
995
+ options: {}
996
+ };
997
+ }
998
+ if (hostname && backendState && backendState !== "running") {
999
+ pairingLog.warn("relay", "tailscale hostname detected but tailscale is not running; using local-only relay endpoint", {
1000
+ hostname,
1001
+ backendState,
1002
+ health: tailscale?.health ?? [],
1003
+ port
1004
+ });
1005
+ }
1006
+ return {
1007
+ relayUrl: `ws://127.0.0.1:${port}`,
1008
+ options: {}
1009
+ };
1010
+ }
972
1011
  function generateTailscaleCerts(hostname) {
973
1012
  mkdirSync3(PAIRING_DIR, { recursive: true });
974
1013
  const certPath = join(PAIRING_DIR, `${hostname}.crt`);
@@ -1014,28 +1053,7 @@ function resolveTls(hostname) {
1014
1053
  return generateTailscaleCerts(hostname);
1015
1054
  }
1016
1055
  function resolveRelayEndpoint(port) {
1017
- const hostname = getTailscaleHostname();
1018
- const tls = resolveTls(hostname);
1019
- if (hostname && tls) {
1020
- return {
1021
- relayUrl: `wss://${hostname}:${port}`,
1022
- options: { tls }
1023
- };
1024
- }
1025
- if (hostname) {
1026
- pairingLog.warn("relay", "tailscale hostname detected without TLS; falling back to insecure websocket relay", {
1027
- hostname,
1028
- port
1029
- });
1030
- return {
1031
- relayUrl: `ws://${hostname}:${port}`,
1032
- options: {}
1033
- };
1034
- }
1035
- return {
1036
- relayUrl: `ws://127.0.0.1:${port}`,
1037
- options: {}
1038
- };
1056
+ return resolveRelayEndpointForTailscaleStatus(port, readTailscaleStatus());
1039
1057
  }
1040
1058
  function startManagedRelay(port = 7889) {
1041
1059
  const endpoint = resolveRelayEndpoint(port);
@@ -7869,7 +7887,73 @@ function resolveConfig() {
7869
7887
  // ../../apps/desktop/src/core/pairing/runtime/bridge/fileserver.ts
7870
7888
  import { isAbsolute } from "path";
7871
7889
  import { homedir as homedir9 } from "os";
7890
+
7891
+ // ../../apps/desktop/src/core/pairing/runtime/bridge/web-handoff.ts
7892
+ import { randomBytes as randomBytes2 } from "crypto";
7893
+ var SCOUT_WEB_HANDOFF_COOKIE = "scout_handoff";
7894
+ var WEB_HANDOFF_TTL_MS = 5 * 60 * 1000;
7895
+ var activeWebHandoffs = new Map;
7896
+ function pruneExpiredWebHandoffs(now = Date.now()) {
7897
+ for (const [token, record] of activeWebHandoffs) {
7898
+ if (record.expiresAt <= now) {
7899
+ activeWebHandoffs.delete(token);
7900
+ }
7901
+ }
7902
+ }
7903
+ function scopesMatch(left, right) {
7904
+ if (left.kind !== right.kind) {
7905
+ return false;
7906
+ }
7907
+ if (left.sessionId !== right.sessionId) {
7908
+ return false;
7909
+ }
7910
+ if (left.kind === "session") {
7911
+ return true;
7912
+ }
7913
+ return left.turnId === right.turnId && left.blockId === right.blockId;
7914
+ }
7915
+ function pathForWebHandoffScope(scope) {
7916
+ switch (scope.kind) {
7917
+ case "session":
7918
+ return `/handoff/session/${encodeURIComponent(scope.sessionId)}`;
7919
+ case "file_change":
7920
+ return `/handoff/file-change/${encodeURIComponent(scope.sessionId)}/${encodeURIComponent(scope.turnId)}/${encodeURIComponent(scope.blockId)}`;
7921
+ }
7922
+ }
7923
+ function issueWebHandoff(scope, deviceId) {
7924
+ pruneExpiredWebHandoffs();
7925
+ const token = randomBytes2(24).toString("base64url");
7926
+ const expiresAt = Date.now() + WEB_HANDOFF_TTL_MS;
7927
+ activeWebHandoffs.set(token, {
7928
+ token,
7929
+ deviceId: deviceId?.trim() || null,
7930
+ expiresAt,
7931
+ scope
7932
+ });
7933
+ return { token, expiresAt, scope };
7934
+ }
7935
+ function readAuthorizedWebHandoff(token, scope) {
7936
+ pruneExpiredWebHandoffs();
7937
+ if (!token) {
7938
+ return null;
7939
+ }
7940
+ const record = activeWebHandoffs.get(token);
7941
+ if (!record) {
7942
+ return null;
7943
+ }
7944
+ if (!scopesMatch(record.scope, scope)) {
7945
+ return null;
7946
+ }
7947
+ return record;
7948
+ }
7949
+
7950
+ // ../../apps/desktop/src/core/pairing/runtime/bridge/fileserver.ts
7872
7951
  var ALLOWED_ROOTS = [homedir9(), "/tmp"];
7952
+ var LOOPBACK_IPV4_HOST_PATTERN = /^127(?:\.\d{1,3}){3}$/;
7953
+ function isTrustedLoopbackHostname(hostname) {
7954
+ const normalized = hostname.trim().toLowerCase();
7955
+ return normalized === "localhost" || normalized.endsWith(".localhost") || normalized === "::1" || LOOPBACK_IPV4_HOST_PATTERN.test(normalized);
7956
+ }
7873
7957
  function isAllowedPath(filePath) {
7874
7958
  if (!isAbsolute(filePath))
7875
7959
  return false;
@@ -7880,7 +7964,7 @@ function isAllowedPath(filePath) {
7880
7964
  return ALLOWED_ROOTS.some((root) => filePath.startsWith(root));
7881
7965
  }
7882
7966
  function startFileServer(options) {
7883
- const { port } = options;
7967
+ const { port, bridge } = options;
7884
7968
  let server = null;
7885
7969
  function start() {
7886
7970
  try {
@@ -7888,7 +7972,7 @@ function startFileServer(options) {
7888
7972
  port,
7889
7973
  fetch(req) {
7890
7974
  try {
7891
- return route(new URL(req.url));
7975
+ return route(req, new URL(req.url), bridge);
7892
7976
  } catch (err) {
7893
7977
  console.error(`[fileserver] ${req.url} \u2192`, err.message);
7894
7978
  return new Response("Internal error", { status: 500 });
@@ -7911,12 +7995,19 @@ function startFileServer(options) {
7911
7995
  start();
7912
7996
  return { port, stop, restart };
7913
7997
  }
7914
- function route(url) {
7998
+ function route(req, url, bridge) {
7915
7999
  const path2 = url.pathname;
7916
- if (path2 === "/file")
8000
+ if (path2 === "/file") {
8001
+ if (!isTrustedLoopbackHostname(url.hostname)) {
8002
+ return new Response("Forbidden", { status: 403 });
8003
+ }
7917
8004
  return serveFile(url);
8005
+ }
7918
8006
  if (path2 === "/health")
7919
8007
  return Response.json({ ok: true });
8008
+ if (path2.startsWith("/handoff/")) {
8009
+ return serveHandoffPage(req, url, bridge);
8010
+ }
7920
8011
  return new Response("Pairing file server", { status: 200 });
7921
8012
  }
7922
8013
  function serveFile(url) {
@@ -7930,6 +8021,520 @@ function serveFile(url) {
7930
8021
  return new Response("Not found", { status: 404 });
7931
8022
  return new Response(file);
7932
8023
  }
8024
+ function serveHandoffPage(req, url, bridge) {
8025
+ if (!bridge) {
8026
+ return new Response("Secure handoff unavailable", { status: 503 });
8027
+ }
8028
+ const scope = parseHandoffScope(url);
8029
+ if (!scope) {
8030
+ return new Response("Not found", { status: 404 });
8031
+ }
8032
+ const token = readHandoffToken(req);
8033
+ const authorized = readAuthorizedWebHandoff(token, scope);
8034
+ if (!authorized) {
8035
+ return unauthorizedHandoffResponse();
8036
+ }
8037
+ let html;
8038
+ switch (scope.kind) {
8039
+ case "session": {
8040
+ const snapshot = bridge.getSessionSnapshot(scope.sessionId);
8041
+ if (!snapshot) {
8042
+ return new Response("Session handoff expired", { status: 404 });
8043
+ }
8044
+ html = renderSessionHandoffPage(snapshot);
8045
+ break;
8046
+ }
8047
+ case "file_change": {
8048
+ const snapshot = bridge.getSessionSnapshot(scope.sessionId);
8049
+ if (!snapshot) {
8050
+ return new Response("Session handoff expired", { status: 404 });
8051
+ }
8052
+ const target = findFileChangeBlock(snapshot, scope.turnId, scope.blockId);
8053
+ if (!target) {
8054
+ return new Response("File change handoff expired", { status: 404 });
8055
+ }
8056
+ html = renderFileChangeHandoffPage(snapshot, target.turn, target.block);
8057
+ break;
8058
+ }
8059
+ }
8060
+ const headers = new Headers({
8061
+ "content-type": "text/html; charset=utf-8",
8062
+ "cache-control": "no-store",
8063
+ "x-content-type-options": "nosniff"
8064
+ });
8065
+ headers.set("set-cookie", `${SCOUT_WEB_HANDOFF_COOKIE}=${authorized.token}; Max-Age=300; Path=/handoff; HttpOnly; SameSite=Strict`);
8066
+ return new Response(html, { status: 200, headers });
8067
+ }
8068
+ function unauthorizedHandoffResponse() {
8069
+ return new Response("Secure handoff required", {
8070
+ status: 401,
8071
+ headers: {
8072
+ "cache-control": "no-store",
8073
+ "set-cookie": `${SCOUT_WEB_HANDOFF_COOKIE}=; Max-Age=0; Path=/handoff; HttpOnly; SameSite=Strict`
8074
+ }
8075
+ });
8076
+ }
8077
+ function parseHandoffScope(url) {
8078
+ const parts = url.pathname.split("/").filter(Boolean).map((part) => decodeURIComponent(part));
8079
+ if (parts[0] !== "handoff") {
8080
+ return null;
8081
+ }
8082
+ if (parts[1] === "session" && parts[2]) {
8083
+ return { kind: "session", sessionId: parts[2] };
8084
+ }
8085
+ if (parts[1] === "file-change" && parts[2] && parts[3] && parts[4]) {
8086
+ return {
8087
+ kind: "file_change",
8088
+ sessionId: parts[2],
8089
+ turnId: parts[3],
8090
+ blockId: parts[4]
8091
+ };
8092
+ }
8093
+ return null;
8094
+ }
8095
+ function readHandoffToken(req) {
8096
+ const headerToken = req.headers.get("x-scout-handoff-token")?.trim();
8097
+ if (headerToken) {
8098
+ return headerToken;
8099
+ }
8100
+ const cookieHeader = req.headers.get("cookie");
8101
+ if (!cookieHeader) {
8102
+ return null;
8103
+ }
8104
+ for (const part of cookieHeader.split(";")) {
8105
+ const [name, ...rest] = part.trim().split("=");
8106
+ if (name === SCOUT_WEB_HANDOFF_COOKIE) {
8107
+ const value = rest.join("=").trim();
8108
+ return value || null;
8109
+ }
8110
+ }
8111
+ return null;
8112
+ }
8113
+ function findFileChangeBlock(snapshot, turnId, blockId) {
8114
+ const turn = snapshot.turns.find((candidate) => candidate.id === turnId);
8115
+ if (!turn) {
8116
+ return null;
8117
+ }
8118
+ const blockState = turn.blocks.find((candidate) => candidate.block.id === blockId);
8119
+ const block = blockState?.block;
8120
+ if (!block || block.type !== "action" || block.action.kind !== "file_change") {
8121
+ return null;
8122
+ }
8123
+ return { turn, block };
8124
+ }
8125
+ function renderPage(title, body) {
8126
+ return `<!doctype html>
8127
+ <html lang="en">
8128
+ <head>
8129
+ <meta charset="utf-8" />
8130
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
8131
+ <title>${escapeHtml(title)}</title>
8132
+ <style>
8133
+ :root {
8134
+ color-scheme: dark;
8135
+ --bg: #0b0f14;
8136
+ --panel: rgba(19, 27, 39, 0.92);
8137
+ --panel-strong: rgba(12, 18, 28, 0.96);
8138
+ --line: rgba(148, 163, 184, 0.16);
8139
+ --line-strong: rgba(148, 163, 184, 0.24);
8140
+ --text: #e5ecf5;
8141
+ --muted: #90a0b4;
8142
+ --accent: #63d0ff;
8143
+ --green: #54d38a;
8144
+ --amber: #f8c36a;
8145
+ --red: #ff7b72;
8146
+ --surface-add: rgba(84, 211, 138, 0.08);
8147
+ --surface-del: rgba(255, 123, 114, 0.08);
8148
+ }
8149
+ * { box-sizing: border-box; }
8150
+ body {
8151
+ margin: 0;
8152
+ background:
8153
+ radial-gradient(circle at top left, rgba(99, 208, 255, 0.12), transparent 32%),
8154
+ linear-gradient(180deg, #090d12 0%, #0b0f14 55%, #111723 100%);
8155
+ color: var(--text);
8156
+ font: 14px/1.5 ui-sans-serif, -apple-system, BlinkMacSystemFont, "SF Pro Text", sans-serif;
8157
+ }
8158
+ .wrap {
8159
+ width: min(980px, calc(100vw - 24px));
8160
+ margin: 0 auto;
8161
+ padding: 20px 0 40px;
8162
+ }
8163
+ .hero, .panel {
8164
+ background: var(--panel);
8165
+ border: 1px solid var(--line);
8166
+ border-radius: 18px;
8167
+ backdrop-filter: blur(18px);
8168
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);
8169
+ }
8170
+ .hero {
8171
+ padding: 18px 18px 16px;
8172
+ margin-bottom: 14px;
8173
+ }
8174
+ .eyebrow {
8175
+ display: inline-flex;
8176
+ align-items: center;
8177
+ gap: 8px;
8178
+ color: var(--muted);
8179
+ font-size: 11px;
8180
+ letter-spacing: 0.14em;
8181
+ text-transform: uppercase;
8182
+ }
8183
+ .dot {
8184
+ width: 8px;
8185
+ height: 8px;
8186
+ border-radius: 999px;
8187
+ background: var(--accent);
8188
+ box-shadow: 0 0 14px rgba(99, 208, 255, 0.65);
8189
+ }
8190
+ h1 {
8191
+ margin: 12px 0 10px;
8192
+ font-size: 24px;
8193
+ line-height: 1.15;
8194
+ }
8195
+ .meta, .stack {
8196
+ display: flex;
8197
+ flex-wrap: wrap;
8198
+ gap: 8px;
8199
+ }
8200
+ .pill {
8201
+ display: inline-flex;
8202
+ align-items: center;
8203
+ gap: 6px;
8204
+ padding: 5px 10px;
8205
+ border-radius: 999px;
8206
+ border: 1px solid var(--line-strong);
8207
+ background: rgba(255, 255, 255, 0.03);
8208
+ color: var(--muted);
8209
+ font-size: 12px;
8210
+ }
8211
+ .pill strong {
8212
+ color: var(--text);
8213
+ font-weight: 600;
8214
+ }
8215
+ .stack { flex-direction: column; }
8216
+ .panel {
8217
+ margin-top: 12px;
8218
+ overflow: hidden;
8219
+ }
8220
+ .panel-inner {
8221
+ padding: 16px;
8222
+ }
8223
+ .turn {
8224
+ border-top: 1px solid var(--line);
8225
+ }
8226
+ .turn:first-child {
8227
+ border-top: none;
8228
+ }
8229
+ .turn-head {
8230
+ padding: 14px 16px;
8231
+ display: flex;
8232
+ justify-content: space-between;
8233
+ gap: 12px;
8234
+ align-items: center;
8235
+ background: rgba(255, 255, 255, 0.02);
8236
+ }
8237
+ .turn-title {
8238
+ font-size: 13px;
8239
+ font-weight: 600;
8240
+ letter-spacing: 0.02em;
8241
+ }
8242
+ .turn-subtitle {
8243
+ color: var(--muted);
8244
+ font-size: 12px;
8245
+ margin-top: 2px;
8246
+ }
8247
+ .blocks {
8248
+ padding: 8px;
8249
+ }
8250
+ .block {
8251
+ padding: 12px;
8252
+ border-radius: 14px;
8253
+ border: 1px solid var(--line);
8254
+ background: var(--panel-strong);
8255
+ margin: 8px;
8256
+ }
8257
+ .block-head {
8258
+ display: flex;
8259
+ justify-content: space-between;
8260
+ align-items: center;
8261
+ gap: 12px;
8262
+ margin-bottom: 10px;
8263
+ }
8264
+ .block-type {
8265
+ color: var(--muted);
8266
+ text-transform: uppercase;
8267
+ letter-spacing: 0.12em;
8268
+ font-size: 11px;
8269
+ }
8270
+ .label {
8271
+ color: var(--muted);
8272
+ font-size: 12px;
8273
+ }
8274
+ .label strong {
8275
+ color: var(--text);
8276
+ }
8277
+ pre {
8278
+ margin: 0;
8279
+ white-space: pre-wrap;
8280
+ word-break: break-word;
8281
+ overflow-wrap: anywhere;
8282
+ font: 12.5px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
8283
+ }
8284
+ .code {
8285
+ padding: 12px;
8286
+ border-radius: 12px;
8287
+ border: 1px solid var(--line);
8288
+ background: rgba(255, 255, 255, 0.02);
8289
+ }
8290
+ .diff-line-add { background: var(--surface-add); color: #8ef3b7; }
8291
+ .diff-line-del { background: var(--surface-del); color: #ff9d96; }
8292
+ .details {
8293
+ margin-top: 10px;
8294
+ border: 1px solid var(--line);
8295
+ border-radius: 12px;
8296
+ overflow: hidden;
8297
+ }
8298
+ details > summary {
8299
+ list-style: none;
8300
+ cursor: pointer;
8301
+ padding: 10px 12px;
8302
+ background: rgba(255, 255, 255, 0.03);
8303
+ color: var(--muted);
8304
+ font-size: 12px;
8305
+ text-transform: uppercase;
8306
+ letter-spacing: 0.1em;
8307
+ }
8308
+ details[open] > summary {
8309
+ border-bottom: 1px solid var(--line);
8310
+ }
8311
+ .empty {
8312
+ padding: 28px 18px;
8313
+ color: var(--muted);
8314
+ }
8315
+ .grid {
8316
+ display: grid;
8317
+ gap: 10px;
8318
+ }
8319
+ .grid.two {
8320
+ grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
8321
+ }
8322
+ a.inline {
8323
+ color: var(--accent);
8324
+ text-decoration: none;
8325
+ }
8326
+ .status-streaming { color: var(--amber); }
8327
+ .status-completed { color: var(--green); }
8328
+ .status-failed, .status-error { color: var(--red); }
8329
+ </style>
8330
+ </head>
8331
+ <body>
8332
+ <main class="wrap">
8333
+ ${body}
8334
+ </main>
8335
+ </body>
8336
+ </html>`;
8337
+ }
8338
+ function renderSessionHandoffPage(snapshot) {
8339
+ const title = snapshot.session.name || snapshot.session.id;
8340
+ const hero = `
8341
+ <section class="hero">
8342
+ <div class="eyebrow"><span class="dot"></span> Secure Proxy Session Handoff</div>
8343
+ <h1>${escapeHtml(title)}</h1>
8344
+ <div class="meta">
8345
+ <span class="pill"><strong>ID</strong> ${escapeHtml(snapshot.session.id)}</span>
8346
+ <span class="pill"><strong>Adapter</strong> ${escapeHtml(snapshot.session.adapterType)}</span>
8347
+ <span class="pill"><strong>Status</strong> ${escapeHtml(snapshot.session.status)}</span>
8348
+ ${snapshot.session.model ? `<span class="pill"><strong>Model</strong> ${escapeHtml(snapshot.session.model)}</span>` : ""}
8349
+ ${snapshot.session.cwd ? `<span class="pill"><strong>Workspace</strong> ${escapeHtml(snapshot.session.cwd)}</span>` : ""}
8350
+ </div>
8351
+ </section>
8352
+ `;
8353
+ const turns = snapshot.turns.length > 0 ? snapshot.turns.map((turn) => {
8354
+ const turnBody = turn.blocks.length > 0 ? turn.blocks.map(({ block }) => renderBlock(block)).join("") : `<div class="empty">No blocks were captured for this turn.</div>`;
8355
+ return `
8356
+ <section class="turn">
8357
+ <div class="turn-head">
8358
+ <div>
8359
+ <div class="turn-title">${escapeHtml(turn.id)}</div>
8360
+ <div class="turn-subtitle">${formatTimestamp(turn.startedAt)}${turn.endedAt ? ` to ${formatTimestamp(turn.endedAt)}` : ""}</div>
8361
+ </div>
8362
+ <span class="pill"><strong>Turn</strong> <span class="status-${escapeHtml(turn.status)}">${escapeHtml(turn.status)}</span></span>
8363
+ </div>
8364
+ <div class="blocks">${turnBody}</div>
8365
+ </section>
8366
+ `;
8367
+ }).join("") : `<div class="empty">This session has not produced any turns yet.</div>`;
8368
+ return renderPage(title, `${hero}<section class="panel">${turns}</section>`);
8369
+ }
8370
+ function renderFileChangeHandoffPage(snapshot, turn, block) {
8371
+ const action = block.action;
8372
+ const title = action.path || snapshot.session.name || snapshot.session.id;
8373
+ const hero = `
8374
+ <section class="hero">
8375
+ <div class="eyebrow"><span class="dot"></span> Secure Proxy File Change</div>
8376
+ <h1>${escapeHtml(title)}</h1>
8377
+ <div class="meta">
8378
+ <span class="pill"><strong>Session</strong> ${escapeHtml(snapshot.session.name || snapshot.session.id)}</span>
8379
+ <span class="pill"><strong>Turn</strong> ${escapeHtml(turn.id)}</span>
8380
+ <span class="pill"><strong>Status</strong> ${escapeHtml(action.status)}</span>
8381
+ </div>
8382
+ </section>
8383
+ `;
8384
+ const body = `
8385
+ <section class="panel">
8386
+ <div class="panel-inner stack">
8387
+ <div class="grid two">
8388
+ <div class="pill"><strong>Path</strong> ${escapeHtml(action.path)}</div>
8389
+ <div class="pill"><strong>Block</strong> ${escapeHtml(block.id)}</div>
8390
+ </div>
8391
+ ${action.diff ? renderDetailsSection("Diff", renderDiff(action.diff), true) : `<div class="empty">No diff was recorded for this action.</div>`}
8392
+ ${action.output ? renderDetailsSection("Output", `<div class="code"><pre>${escapeHtml(action.output)}</pre></div>`) : ""}
8393
+ </div>
8394
+ </section>
8395
+ `;
8396
+ return renderPage(title, `${hero}${body}`);
8397
+ }
8398
+ function renderBlock(block) {
8399
+ switch (block.type) {
8400
+ case "text":
8401
+ return renderTextLikeBlock("Text", block.text);
8402
+ case "reasoning":
8403
+ return renderTextLikeBlock("Reasoning", block.text);
8404
+ case "error":
8405
+ return `
8406
+ <article class="block">
8407
+ <div class="block-head">
8408
+ <div class="block-type">Error</div>
8409
+ <span class="pill status-error">${escapeHtml(block.status)}</span>
8410
+ </div>
8411
+ <div class="code"><pre>${escapeHtml(block.message)}</pre></div>
8412
+ </article>
8413
+ `;
8414
+ case "file":
8415
+ return `
8416
+ <article class="block">
8417
+ <div class="block-head">
8418
+ <div class="block-type">File</div>
8419
+ <span class="pill">${escapeHtml(block.status)}</span>
8420
+ </div>
8421
+ <div class="grid">
8422
+ ${block.name ? `<div class="label"><strong>Name</strong> ${escapeHtml(block.name)}</div>` : ""}
8423
+ <div class="label"><strong>MIME</strong> ${escapeHtml(block.mimeType)}</div>
8424
+ </div>
8425
+ </article>
8426
+ `;
8427
+ case "question":
8428
+ return renderQuestionBlock(block);
8429
+ case "action":
8430
+ return renderActionBlock(block);
8431
+ }
8432
+ }
8433
+ function renderTextLikeBlock(label, text) {
8434
+ return `
8435
+ <article class="block">
8436
+ <div class="block-head">
8437
+ <div class="block-type">${escapeHtml(label)}</div>
8438
+ </div>
8439
+ <div class="code"><pre>${escapeHtml(text)}</pre></div>
8440
+ </article>
8441
+ `;
8442
+ }
8443
+ function renderQuestionBlock(block) {
8444
+ const answer = block.answer?.length ? block.answer.join(", ") : "Awaiting answer";
8445
+ const options = block.options?.length ? `<div class="label"><strong>Options</strong> ${escapeHtml(block.options.map((option) => option.label).join(", "))}</div>` : "";
8446
+ return `
8447
+ <article class="block">
8448
+ <div class="block-head">
8449
+ <div class="block-type">Question</div>
8450
+ <span class="pill">${escapeHtml(block.questionStatus)}</span>
8451
+ </div>
8452
+ ${block.header ? `<div class="label"><strong>${escapeHtml(block.header)}</strong></div>` : ""}
8453
+ <div class="code"><pre>${escapeHtml(block.question)}</pre></div>
8454
+ <div class="stack" style="margin-top: 10px;">
8455
+ ${options}
8456
+ <div class="label"><strong>Answer</strong> ${escapeHtml(answer)}</div>
8457
+ </div>
8458
+ </article>
8459
+ `;
8460
+ }
8461
+ function renderActionBlock(block) {
8462
+ const action = block.action;
8463
+ const parts = [];
8464
+ switch (action.kind) {
8465
+ case "file_change":
8466
+ parts.push(`<div class="label"><strong>Path</strong> ${escapeHtml(action.path)}</div>`);
8467
+ if (action.diff) {
8468
+ parts.push(renderDetailsSection("Diff", renderDiff(action.diff)));
8469
+ }
8470
+ break;
8471
+ case "command":
8472
+ parts.push(`<div class="label"><strong>Command</strong></div><div class="code"><pre>${escapeHtml(action.command)}</pre></div>`);
8473
+ if (typeof action.exitCode === "number") {
8474
+ parts.push(`<div class="label"><strong>Exit Code</strong> ${escapeHtml(String(action.exitCode))}</div>`);
8475
+ }
8476
+ break;
8477
+ case "tool_call":
8478
+ parts.push(`<div class="label"><strong>Tool</strong> ${escapeHtml(action.toolName)}</div>`);
8479
+ if (action.toolCallId) {
8480
+ parts.push(`<div class="label"><strong>Call ID</strong> ${escapeHtml(action.toolCallId)}</div>`);
8481
+ }
8482
+ break;
8483
+ case "subagent":
8484
+ parts.push(`<div class="label"><strong>Agent</strong> ${escapeHtml(action.agentName || action.agentId)}</div>`);
8485
+ if (action.prompt) {
8486
+ parts.push(`<div class="code"><pre>${escapeHtml(action.prompt)}</pre></div>`);
8487
+ }
8488
+ break;
8489
+ }
8490
+ if (action.approval) {
8491
+ parts.push(`<div class="label"><strong>Approval</strong> ${escapeHtml(action.approval.risk || "medium")} risk${action.approval.description ? ` - ${escapeHtml(action.approval.description)}` : ""}</div>`);
8492
+ }
8493
+ if (action.output) {
8494
+ parts.push(renderDetailsSection("Output", `<div class="code"><pre>${escapeHtml(action.output)}</pre></div>`));
8495
+ }
8496
+ return `
8497
+ <article class="block">
8498
+ <div class="block-head">
8499
+ <div class="block-type">${escapeHtml(action.kind.replace("_", " "))}</div>
8500
+ <span class="pill">${escapeHtml(action.status)}</span>
8501
+ </div>
8502
+ <div class="stack">${parts.join("")}</div>
8503
+ </article>
8504
+ `;
8505
+ }
8506
+ function renderDetailsSection(title, innerHtml, open = false) {
8507
+ return `
8508
+ <details class="details"${open ? " open" : ""}>
8509
+ <summary>${escapeHtml(title)}</summary>
8510
+ <div class="panel-inner">${innerHtml}</div>
8511
+ </details>
8512
+ `;
8513
+ }
8514
+ function renderDiff(diff) {
8515
+ const lines = diff.split(`
8516
+ `).map((line) => {
8517
+ const className = line.startsWith("+") ? "diff-line-add" : line.startsWith("-") ? "diff-line-del" : "";
8518
+ return `<div class="${className}"><pre>${escapeHtml(line || " ")}</pre></div>`;
8519
+ }).join("");
8520
+ return `<div class="code">${lines}</div>`;
8521
+ }
8522
+ function escapeHtml(value) {
8523
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
8524
+ }
8525
+ function formatTimestamp(value) {
8526
+ if (typeof value !== "number" || !Number.isFinite(value)) {
8527
+ return "Unknown time";
8528
+ }
8529
+ try {
8530
+ return new Intl.DateTimeFormat("en-US", {
8531
+ dateStyle: "medium",
8532
+ timeStyle: "short"
8533
+ }).format(value);
8534
+ } catch {
8535
+ return new Date(value).toISOString();
8536
+ }
8537
+ }
7933
8538
 
7934
8539
  // ../../apps/desktop/src/core/pairing/runtime/bridge/server.ts
7935
8540
  import { readdirSync as readdirSync3, readFileSync as readFileSync9, realpathSync, statSync as statSync3 } from "fs";
@@ -9584,114 +10189,6 @@ function buildScoutReturnAddress(input) {
9584
10189
  }
9585
10190
  return next;
9586
10191
  }
9587
- // ../protocol/dist/collaboration.js
9588
- function isQuestionTerminalState(state) {
9589
- return state === "closed" || state === "declined";
9590
- }
9591
- function isWorkItemTerminalState(state) {
9592
- return state === "done" || state === "cancelled";
9593
- }
9594
- function collaborationRequiresNextMoveOwner(record) {
9595
- if (record.kind === "question") {
9596
- return !isQuestionTerminalState(record.state);
9597
- }
9598
- return !isWorkItemTerminalState(record.state);
9599
- }
9600
- function collaborationRequiresOwner(record) {
9601
- return record.kind === "work_item" && !isWorkItemTerminalState(record.state);
9602
- }
9603
- function collaborationRequiresWaitingOn(record) {
9604
- return record.kind === "work_item" && record.state === "waiting";
9605
- }
9606
- function collaborationRequiresAcceptance(record) {
9607
- if (record.acceptanceState === "none") {
9608
- return false;
9609
- }
9610
- if (record.kind === "question") {
9611
- return Boolean(record.askedById && record.askedOfId);
9612
- }
9613
- return Boolean(record.requestedById);
9614
- }
9615
- function validateCollaborationRecord(record) {
9616
- const errors = [];
9617
- if (!record.id.trim()) {
9618
- errors.push("collaboration record id is required");
9619
- }
9620
- if (!record.title.trim()) {
9621
- errors.push("collaboration title is required");
9622
- }
9623
- if (!record.createdById.trim()) {
9624
- errors.push("createdById is required");
9625
- }
9626
- if (record.parentId && record.parentId === record.id) {
9627
- errors.push("parentId cannot reference the record itself");
9628
- }
9629
- if (record.createdAt > record.updatedAt) {
9630
- errors.push("updatedAt must be greater than or equal to createdAt");
9631
- }
9632
- if (collaborationRequiresOwner(record) && !record.ownerId) {
9633
- errors.push("non-terminal work items require ownerId");
9634
- }
9635
- if (collaborationRequiresNextMoveOwner(record) && !record.nextMoveOwnerId) {
9636
- errors.push("non-terminal collaboration records require nextMoveOwnerId");
9637
- }
9638
- if (record.kind === "work_item" && collaborationRequiresWaitingOn(record) && !record.waitingOn) {
9639
- errors.push("waiting work items require waitingOn");
9640
- }
9641
- if (record.kind === "question") {
9642
- if (record.spawnedWorkItemId && record.spawnedWorkItemId === record.id) {
9643
- errors.push("question spawnedWorkItemId cannot reference the question itself");
9644
- }
9645
- } else if (record.waitingOn?.targetId && record.waitingOn.targetId === record.id) {
9646
- errors.push("waitingOn.targetId cannot reference the work item itself");
9647
- }
9648
- if (record.acceptanceState !== "none" && !collaborationRequiresAcceptance(record)) {
9649
- errors.push("acceptanceState requires the corresponding requester and reviewer identities");
9650
- }
9651
- return errors;
9652
- }
9653
- function assertValidCollaborationRecord(record) {
9654
- const errors = validateCollaborationRecord(record);
9655
- if (errors.length > 0) {
9656
- throw new Error(errors.join("; "));
9657
- }
9658
- }
9659
- function validateCollaborationEvent(event, record) {
9660
- const errors = [];
9661
- if (!event.id.trim()) {
9662
- errors.push("collaboration event id is required");
9663
- }
9664
- if (!event.recordId.trim()) {
9665
- errors.push("collaboration event recordId is required");
9666
- }
9667
- if (!event.actorId.trim()) {
9668
- errors.push("collaboration event actorId is required");
9669
- }
9670
- if (record) {
9671
- if (record.id !== event.recordId) {
9672
- errors.push("collaboration event recordId does not match the target record");
9673
- }
9674
- if (record.kind !== event.recordKind) {
9675
- errors.push("collaboration event recordKind does not match the target record");
9676
- }
9677
- }
9678
- if (event.kind === "answered" && event.recordKind !== "question") {
9679
- errors.push("answered events only apply to questions");
9680
- }
9681
- if (event.kind === "declined" && event.recordKind !== "question") {
9682
- errors.push("declined events only apply to questions");
9683
- }
9684
- if ((event.kind === "waiting" || event.kind === "progressed" || event.kind === "review_requested" || event.kind === "done" || event.kind === "cancelled") && event.recordKind !== "work_item") {
9685
- errors.push(`${event.kind} events only apply to work items`);
9686
- }
9687
- return errors;
9688
- }
9689
- function assertValidCollaborationEvent(event, record) {
9690
- const errors = validateCollaborationEvent(event, record);
9691
- if (errors.length > 0) {
9692
- throw new Error(errors.join("; "));
9693
- }
9694
- }
9695
10192
  // ../runtime/src/user-project-hints.ts
9696
10193
  import { readdir, readFile as readFile3, stat } from "fs/promises";
9697
10194
  import { homedir as homedir11 } from "os";
@@ -12151,8 +12648,107 @@ async function shutdownClaudeStreamJsonAgent(options, shutdownOptions = {}) {
12151
12648
 
12152
12649
  // ../runtime/src/codex-app-server.ts
12153
12650
  import { spawn as spawn3 } from "child_process";
12154
- import { access as access3, appendFile as appendFile3, constants as constants3, mkdir as mkdir5, readFile as readFile6, rm as rm4, writeFile as writeFile5 } from "fs/promises";
12651
+ import { constants as constants3 } from "fs";
12652
+ import { access as access3, appendFile as appendFile3, mkdir as mkdir5, readFile as readFile6, rm as rm4, writeFile as writeFile5 } from "fs/promises";
12155
12653
  import { delimiter as delimiter3, join as join13 } from "path";
12654
+ function normalizeCodexModelValue(value) {
12655
+ const trimmed = value?.trim();
12656
+ return trimmed ? trimmed : null;
12657
+ }
12658
+ function encodeCodexModelConfig(model) {
12659
+ return `model=${JSON.stringify(model)}`;
12660
+ }
12661
+ function parseCodexModelConfig(value) {
12662
+ const trimmed = value?.trim();
12663
+ if (!trimmed) {
12664
+ return null;
12665
+ }
12666
+ const separatorIndex = trimmed.indexOf("=");
12667
+ if (separatorIndex <= 0) {
12668
+ return null;
12669
+ }
12670
+ const key = trimmed.slice(0, separatorIndex).trim();
12671
+ if (key !== "model") {
12672
+ return null;
12673
+ }
12674
+ const rawValue = trimmed.slice(separatorIndex + 1).trim();
12675
+ if (!rawValue) {
12676
+ return null;
12677
+ }
12678
+ if (rawValue.startsWith('"') && rawValue.endsWith('"') || rawValue.startsWith("'") && rawValue.endsWith("'")) {
12679
+ return rawValue.slice(1, -1) || null;
12680
+ }
12681
+ return rawValue;
12682
+ }
12683
+ function normalizeCodexAppServerLaunchArgs(launchArgs) {
12684
+ const args = Array.isArray(launchArgs) ? launchArgs.map((entry) => String(entry).trim()).filter(Boolean) : [];
12685
+ const normalized = [];
12686
+ for (let index = 0;index < args.length; index += 1) {
12687
+ const current = args[index] ?? "";
12688
+ if (current === "--model" || current === "-m") {
12689
+ const model = normalizeCodexModelValue(args[index + 1]);
12690
+ if (model) {
12691
+ normalized.push("-c", encodeCodexModelConfig(model));
12692
+ index += 1;
12693
+ continue;
12694
+ }
12695
+ normalized.push(current);
12696
+ continue;
12697
+ }
12698
+ if (current.startsWith("--model=")) {
12699
+ const model = normalizeCodexModelValue(current.slice("--model=".length));
12700
+ if (model) {
12701
+ normalized.push("-c", encodeCodexModelConfig(model));
12702
+ continue;
12703
+ }
12704
+ }
12705
+ if (current.startsWith("-m=")) {
12706
+ const model = normalizeCodexModelValue(current.slice(3));
12707
+ if (model) {
12708
+ normalized.push("-c", encodeCodexModelConfig(model));
12709
+ continue;
12710
+ }
12711
+ }
12712
+ if (current === "-c" || current === "--config") {
12713
+ const next = args[index + 1];
12714
+ if (typeof next === "string") {
12715
+ const model = parseCodexModelConfig(next);
12716
+ normalized.push(current === "--config" ? "--config" : "-c", model ? encodeCodexModelConfig(model) : next);
12717
+ index += 1;
12718
+ continue;
12719
+ }
12720
+ }
12721
+ if (current.startsWith("--config=")) {
12722
+ const value = current.slice("--config=".length);
12723
+ const model = parseCodexModelConfig(value);
12724
+ normalized.push(model ? `--config=${encodeCodexModelConfig(model)}` : current);
12725
+ continue;
12726
+ }
12727
+ normalized.push(current);
12728
+ }
12729
+ return normalized;
12730
+ }
12731
+ function readCodexAppServerModelFromLaunchArgs(launchArgs) {
12732
+ const normalized = normalizeCodexAppServerLaunchArgs(launchArgs);
12733
+ for (let index = 0;index < normalized.length; index += 1) {
12734
+ const current = normalized[index] ?? "";
12735
+ if (current === "-c" || current === "--config") {
12736
+ const model = parseCodexModelConfig(normalized[index + 1]);
12737
+ if (model) {
12738
+ return model;
12739
+ }
12740
+ index += 1;
12741
+ continue;
12742
+ }
12743
+ if (current.startsWith("--config=")) {
12744
+ const model = parseCodexModelConfig(current.slice("--config=".length));
12745
+ if (model) {
12746
+ return model;
12747
+ }
12748
+ }
12749
+ }
12750
+ return null;
12751
+ }
12156
12752
  function sessionKey2(options) {
12157
12753
  return `${options.agentName}:${options.sessionId}`;
12158
12754
  }
@@ -12261,6 +12857,13 @@ function isMissingCodexRolloutError2(error) {
12261
12857
  const message = errorMessage3(error).toLowerCase();
12262
12858
  return message.includes("no rollout found for thread id");
12263
12859
  }
12860
+ function resolveCodexCompletionGraceMs() {
12861
+ const parsed = Number.parseInt(process.env.OPENSCOUT_CODEX_COMPLETION_GRACE_MS ?? "", 10);
12862
+ if (Number.isFinite(parsed) && parsed >= 0) {
12863
+ return parsed;
12864
+ }
12865
+ return 60000;
12866
+ }
12264
12867
 
12265
12868
  class CodexAppServerSession {
12266
12869
  options;
@@ -12450,7 +13053,7 @@ class CodexAppServerSession {
12450
13053
  systemPrompt: options.systemPrompt,
12451
13054
  threadId: options.threadId ?? null,
12452
13055
  requireExistingThread: options.requireExistingThread === true,
12453
- launchArgs: Array.isArray(options.launchArgs) ? options.launchArgs : []
13056
+ launchArgs: normalizeCodexAppServerLaunchArgs(options.launchArgs)
12454
13057
  });
12455
13058
  }
12456
13059
  async ensureStarted() {
@@ -12472,6 +13075,7 @@ class CodexAppServerSession {
12472
13075
  await mkdir5(this.options.logsDirectory, { recursive: true });
12473
13076
  await writeFile5(join13(this.options.runtimeDirectory, "prompt.txt"), this.options.systemPrompt);
12474
13077
  const codexExecutable = await resolveCodexExecutable2();
13078
+ const launchArgs = normalizeCodexAppServerLaunchArgs(this.options.launchArgs);
12475
13079
  const env = buildManagedAgentEnvironment({
12476
13080
  agentName: this.options.agentName,
12477
13081
  currentDirectory: this.options.cwd,
@@ -12482,7 +13086,8 @@ class CodexAppServerSession {
12482
13086
  ...buildScoutMcpCodexLaunchArgs({
12483
13087
  currentDirectory: this.options.cwd,
12484
13088
  env
12485
- })
13089
+ }),
13090
+ ...launchArgs
12486
13091
  ], {
12487
13092
  cwd: this.options.cwd,
12488
13093
  env,
@@ -12580,6 +13185,8 @@ class CodexAppServerSession {
12580
13185
  turnId: "",
12581
13186
  startedAt: Date.now(),
12582
13187
  timer: null,
13188
+ graceTimer: null,
13189
+ timedOutAt: null,
12583
13190
  messageOrder: [],
12584
13191
  messageByItemId: new Map,
12585
13192
  resolve: resolve4,
@@ -12587,20 +13194,43 @@ class CodexAppServerSession {
12587
13194
  watchers: []
12588
13195
  };
12589
13196
  turn.timer = setTimeout(() => {
12590
- this.interrupt().catch(() => {
12591
- return;
12592
- });
12593
- if (this.activeTurn === turn) {
12594
- this.activeTurn = null;
12595
- }
12596
- for (const watcher of this.drainTurnWatchers(turn)) {
12597
- watcher.reject(new Error(`Timed out after ${timeoutMs}ms waiting for ${this.options.agentName}.`));
12598
- }
12599
- reject(new Error(`Timed out after ${timeoutMs}ms waiting for ${this.options.agentName}.`));
13197
+ this.scheduleTurnTimeout(turn, timeoutMs);
12600
13198
  }, timeoutMs);
12601
13199
  this.activeTurn = turn;
12602
13200
  return turn;
12603
13201
  }
13202
+ buildTurnTimeoutError(timeoutMs) {
13203
+ return new Error(`Timed out after ${timeoutMs}ms waiting for ${this.options.agentName}.`);
13204
+ }
13205
+ scheduleTurnTimeout(turn, timeoutMs) {
13206
+ if (turn.timedOutAt !== null) {
13207
+ return;
13208
+ }
13209
+ turn.timedOutAt = Date.now();
13210
+ this.interrupt().catch(() => {
13211
+ return;
13212
+ });
13213
+ const graceMs = resolveCodexCompletionGraceMs();
13214
+ if (graceMs <= 0) {
13215
+ this.rejectTimedOutTurn(turn, timeoutMs);
13216
+ return;
13217
+ }
13218
+ turn.graceTimer = setTimeout(() => {
13219
+ this.rejectTimedOutTurn(turn, timeoutMs);
13220
+ }, graceMs);
13221
+ }
13222
+ rejectTimedOutTurn(turn, timeoutMs) {
13223
+ if (this.activeTurn !== turn) {
13224
+ this.clearActiveTurn(turn);
13225
+ return;
13226
+ }
13227
+ this.clearActiveTurn(turn);
13228
+ const error = this.buildTurnTimeoutError(timeoutMs);
13229
+ for (const watcher of this.drainTurnWatchers(turn)) {
13230
+ watcher.reject(error);
13231
+ }
13232
+ turn.reject(error);
13233
+ }
12604
13234
  addTurnWatcher(turn, resolve4, reject, timeoutMs) {
12605
13235
  const watcher = {
12606
13236
  resolve: resolve4,
@@ -12634,6 +13264,9 @@ class CodexAppServerSession {
12634
13264
  if (turn.timer) {
12635
13265
  clearTimeout(turn.timer);
12636
13266
  }
13267
+ if (turn.graceTimer) {
13268
+ clearTimeout(turn.graceTimer);
13269
+ }
12637
13270
  if (this.activeTurn === turn) {
12638
13271
  this.activeTurn = null;
12639
13272
  }
@@ -13833,6 +14466,128 @@ function normalizeLocalAgentCapabilities(value) {
13833
14466
  function normalizeLocalAgentLaunchArgs(value) {
13834
14467
  return Array.isArray(value) ? value.map((entry) => String(entry).trim()).filter(Boolean) : [];
13835
14468
  }
14469
+ function normalizeRequestedModel(value) {
14470
+ const trimmed = value?.trim();
14471
+ return trimmed ? trimmed : undefined;
14472
+ }
14473
+ function readClaudeLaunchModel(launchArgs) {
14474
+ for (let index = 0;index < launchArgs.length; index += 1) {
14475
+ const current = launchArgs[index] ?? "";
14476
+ if (current === "--model") {
14477
+ const next = launchArgs[index + 1]?.trim();
14478
+ return next || undefined;
14479
+ }
14480
+ if (current.startsWith("--model=")) {
14481
+ const next = current.slice("--model=".length).trim();
14482
+ return next || undefined;
14483
+ }
14484
+ }
14485
+ return;
14486
+ }
14487
+ function normalizeLaunchArgsForHarness(harness, value) {
14488
+ const normalized = normalizeLocalAgentLaunchArgs(value);
14489
+ if (harness === "codex") {
14490
+ return normalizeCodexAppServerLaunchArgs(normalized);
14491
+ }
14492
+ return normalized;
14493
+ }
14494
+ function readLaunchModelForHarness(harness, launchArgs) {
14495
+ if (harness === "codex") {
14496
+ return readCodexAppServerModelFromLaunchArgs(launchArgs) ?? undefined;
14497
+ }
14498
+ if (harness === "claude") {
14499
+ return readClaudeLaunchModel(launchArgs ?? []);
14500
+ }
14501
+ return;
14502
+ }
14503
+ function stripLaunchModelForHarness(harness, launchArgs) {
14504
+ if (harness === "codex") {
14505
+ const next = [];
14506
+ const normalized = normalizeCodexAppServerLaunchArgs(launchArgs);
14507
+ for (let index = 0;index < normalized.length; index += 1) {
14508
+ const current = normalized[index] ?? "";
14509
+ if (current === "-c" || current === "--config") {
14510
+ const value = normalized[index + 1];
14511
+ if (readCodexAppServerModelFromLaunchArgs(value ? [current, value] : [current])) {
14512
+ index += 1;
14513
+ continue;
14514
+ }
14515
+ next.push(current);
14516
+ if (value) {
14517
+ next.push(value);
14518
+ index += 1;
14519
+ }
14520
+ continue;
14521
+ }
14522
+ if (current.startsWith("--config=")) {
14523
+ if (readCodexAppServerModelFromLaunchArgs([current])) {
14524
+ continue;
14525
+ }
14526
+ }
14527
+ next.push(current);
14528
+ }
14529
+ return next;
14530
+ }
14531
+ if (harness === "claude") {
14532
+ const next = [];
14533
+ const normalized = normalizeLocalAgentLaunchArgs(launchArgs);
14534
+ for (let index = 0;index < normalized.length; index += 1) {
14535
+ const current = normalized[index] ?? "";
14536
+ if (current === "--model") {
14537
+ index += 1;
14538
+ continue;
14539
+ }
14540
+ if (current.startsWith("--model=")) {
14541
+ continue;
14542
+ }
14543
+ next.push(current);
14544
+ }
14545
+ return next;
14546
+ }
14547
+ return normalizeLocalAgentLaunchArgs(launchArgs);
14548
+ }
14549
+ function buildLaunchArgsForRequestedModel(harness, model) {
14550
+ if (harness === "codex") {
14551
+ return normalizeCodexAppServerLaunchArgs(["--model", model]);
14552
+ }
14553
+ if (harness === "claude") {
14554
+ return ["--model", model];
14555
+ }
14556
+ return [];
14557
+ }
14558
+ function applyRequestedModelToLaunchArgs(harness, launchArgs, model) {
14559
+ const normalized = normalizeLaunchArgsForHarness(harness, launchArgs);
14560
+ const requestedModel = normalizeRequestedModel(model);
14561
+ if (!requestedModel) {
14562
+ return normalized;
14563
+ }
14564
+ return [
14565
+ ...stripLaunchModelForHarness(harness, normalized),
14566
+ ...buildLaunchArgsForRequestedModel(harness, requestedModel)
14567
+ ];
14568
+ }
14569
+ function defaultHarnessForOverride(override, fallback = "claude") {
14570
+ return normalizeManagedHarness2(override.defaultHarness ?? override.runtime?.harness, fallback);
14571
+ }
14572
+ function launchArgsForOverrideHarness(override, harness) {
14573
+ const profileLaunchArgs = override.harnessProfiles?.[harness]?.launchArgs;
14574
+ if (profileLaunchArgs) {
14575
+ return normalizeLaunchArgsForHarness(harness, profileLaunchArgs);
14576
+ }
14577
+ if (harness === defaultHarnessForOverride(override, harness)) {
14578
+ return normalizeLaunchArgsForHarness(harness, override.launchArgs);
14579
+ }
14580
+ return [];
14581
+ }
14582
+ function overrideHarnessProfile(override, harness) {
14583
+ const profile = override.harnessProfiles?.[harness];
14584
+ return {
14585
+ cwd: normalizeProjectPath(profile?.cwd || override.runtime?.cwd || override.projectRoot || process.cwd()),
14586
+ transport: normalizeLocalAgentTransport(profile?.transport ?? override.runtime?.transport, harness),
14587
+ sessionId: normalizeTmuxSessionName2(profile?.sessionId, `${override.agentId}-${harness}`),
14588
+ launchArgs: launchArgsForOverrideHarness(override, harness)
14589
+ };
14590
+ }
13836
14591
  function normalizeManagedHarness2(value, fallback) {
13837
14592
  return value === "codex" ? "codex" : value === "claude" ? "claude" : fallback;
13838
14593
  }
@@ -13848,7 +14603,7 @@ function normalizeLocalHarnessProfiles(agentId, record) {
13848
14603
  cwd: normalizeProjectPath(profile.cwd || record.cwd || process.cwd()),
13849
14604
  transport: normalizeLocalAgentTransport(profile.transport, harness),
13850
14605
  sessionId: normalizeTmuxSessionName2(profile.sessionId, `${agentId}-${harness}`),
13851
- launchArgs: normalizeLocalAgentLaunchArgs(profile.launchArgs)
14606
+ launchArgs: normalizeLaunchArgsForHarness(harness, profile.launchArgs)
13852
14607
  };
13853
14608
  }
13854
14609
  const runtimeHarness = normalizeManagedHarness2(record.harness, defaultHarness);
@@ -13857,7 +14612,7 @@ function normalizeLocalHarnessProfiles(agentId, record) {
13857
14612
  cwd: normalizeProjectPath(record.cwd || process.cwd()),
13858
14613
  transport: normalizeLocalAgentTransport(record.transport, runtimeHarness),
13859
14614
  sessionId: normalizeTmuxSessionName2(record.tmuxSession, `${agentId}-${runtimeHarness}`),
13860
- launchArgs: normalizeLocalAgentLaunchArgs(record.launchArgs)
14615
+ launchArgs: normalizeLaunchArgsForHarness(runtimeHarness, record.launchArgs)
13861
14616
  };
13862
14617
  }
13863
14618
  if (!nextProfiles[defaultHarness]) {
@@ -13865,7 +14620,7 @@ function normalizeLocalHarnessProfiles(agentId, record) {
13865
14620
  cwd: normalizeProjectPath(record.cwd || process.cwd()),
13866
14621
  transport: normalizeLocalAgentTransport(record.transport, defaultHarness),
13867
14622
  sessionId: normalizeTmuxSessionName2(record.tmuxSession, `${agentId}-${defaultHarness}`),
13868
- launchArgs: normalizeLocalAgentLaunchArgs(record.launchArgs)
14623
+ launchArgs: normalizeLaunchArgsForHarness(defaultHarness, record.launchArgs)
13869
14624
  };
13870
14625
  }
13871
14626
  for (const harness of ["claude", "codex"]) {
@@ -13877,7 +14632,7 @@ function normalizeLocalHarnessProfiles(agentId, record) {
13877
14632
  cwd: normalizeProjectPath(profile.cwd || record.cwd || process.cwd()),
13878
14633
  transport: normalizeLocalAgentTransport(profile.transport, harness),
13879
14634
  sessionId: normalizeTmuxSessionName2(profile.sessionId, `${agentId}-${harness}`),
13880
- launchArgs: normalizeLocalAgentLaunchArgs(profile.launchArgs)
14635
+ launchArgs: normalizeLaunchArgsForHarness(harness, profile.launchArgs)
13881
14636
  };
13882
14637
  }
13883
14638
  return nextProfiles;
@@ -13901,14 +14656,14 @@ function recordForHarness(record, harnessOverride) {
13901
14656
  tmuxSession: fallbackSessionId,
13902
14657
  cwd: fallbackCwd,
13903
14658
  transport: fallbackTransport,
13904
- launchArgs: normalizeLocalAgentLaunchArgs(normalized.launchArgs),
14659
+ launchArgs: normalizeLaunchArgsForHarness(selectedHarness, normalized.launchArgs),
13905
14660
  harnessProfiles: {
13906
14661
  ...normalized.harnessProfiles,
13907
14662
  [selectedHarness]: {
13908
14663
  cwd: fallbackCwd,
13909
14664
  transport: fallbackTransport,
13910
14665
  sessionId: fallbackSessionId,
13911
- launchArgs: normalizeLocalAgentLaunchArgs(normalized.launchArgs)
14666
+ launchArgs: normalizeLaunchArgsForHarness(selectedHarness, normalized.launchArgs)
13912
14667
  }
13913
14668
  }
13914
14669
  };
@@ -13950,7 +14705,7 @@ function normalizeLocalAgentRecord(agentId, record) {
13950
14705
  harnessProfiles,
13951
14706
  transport: activeProfile?.transport ?? normalizeLocalAgentTransport(record.transport, harness),
13952
14707
  capabilities: normalizeLocalAgentCapabilities(record.capabilities),
13953
- launchArgs: activeProfile?.launchArgs ?? normalizeLocalAgentLaunchArgs(record.launchArgs)
14708
+ launchArgs: activeProfile?.launchArgs ?? normalizeLaunchArgsForHarness(harness, record.launchArgs)
13954
14709
  };
13955
14710
  }
13956
14711
  function localAgentStatusFromRecord(agentId, record, source) {
@@ -14019,7 +14774,7 @@ function relayAgentOverrideFromLocalAgentRecord(agentId, record, existing) {
14019
14774
  source: existing?.source && existing.source !== "inferred" ? existing.source : "manual",
14020
14775
  startedAt: normalizedRecord.startedAt,
14021
14776
  systemPrompt: normalizedRecord.systemPrompt,
14022
- launchArgs: normalizeLocalAgentLaunchArgs(normalizedRecord.launchArgs),
14777
+ launchArgs: normalizeLaunchArgsForHarness(normalizeLocalAgentHarness(normalizedRecord.harness), normalizedRecord.launchArgs),
14023
14778
  capabilities: normalizeLocalAgentCapabilities(normalizedRecord.capabilities),
14024
14779
  defaultHarness: normalizeManagedHarness2(normalizedRecord.defaultHarness, "claude"),
14025
14780
  harnessProfiles: normalizedRecord.harnessProfiles,
@@ -14040,7 +14795,7 @@ function buildCodexAgentSessionOptions(agentName, record, systemPrompt) {
14040
14795
  systemPrompt: systemPrompt ?? buildLocalAgentSystemPrompt(agentName, record.project, record.cwd, { transport: "codex_app_server" }),
14041
14796
  runtimeDirectory: relayAgentRuntimeDirectory(agentName),
14042
14797
  logsDirectory: relayAgentLogsDirectory(agentName),
14043
- launchArgs: normalizeLocalAgentLaunchArgs(record.launchArgs)
14798
+ launchArgs: normalizeLaunchArgsForHarness("codex", record.launchArgs)
14044
14799
  };
14045
14800
  }
14046
14801
  function buildClaudeAgentSessionOptions(agentName, record, systemPrompt) {
@@ -14051,7 +14806,7 @@ function buildClaudeAgentSessionOptions(agentName, record, systemPrompt) {
14051
14806
  systemPrompt: systemPrompt ?? buildLocalAgentSystemPrompt(agentName, record.project, record.cwd, { transport: "claude_stream_json" }),
14052
14807
  runtimeDirectory: relayAgentRuntimeDirectory(agentName),
14053
14808
  logsDirectory: relayAgentLogsDirectory(agentName),
14054
- launchArgs: normalizeLocalAgentLaunchArgs(record.launchArgs)
14809
+ launchArgs: normalizeLaunchArgsForHarness("claude", record.launchArgs)
14055
14810
  };
14056
14811
  }
14057
14812
  function isLocalAgentRecordOnline(agentName, record) {
@@ -14085,7 +14840,7 @@ function buildLocalAgentBootstrapPrompt(_harness, _systemPrompt, initialMessage)
14085
14840
  return initialMessage;
14086
14841
  }
14087
14842
  function buildLocalAgentLaunchCommand(agentName, record, projectPath, promptFile, workerScript) {
14088
- const extraArgs = shellQuoteArguments(normalizeLocalAgentLaunchArgs(record.launchArgs));
14843
+ const extraArgs = shellQuoteArguments(normalizeLaunchArgsForHarness(normalizeLocalAgentHarness(record.harness), record.launchArgs));
14089
14844
  if (normalizeLocalAgentHarness(record.harness) === "codex") {
14090
14845
  return `exec bash ${JSON.stringify(workerScript ?? join15(relayAgentRuntimeDirectory(agentName), "codex-worker.sh"))}`;
14091
14846
  }
@@ -14351,6 +15106,7 @@ async function startLocalAgent(input) {
14351
15106
  const effectiveHarness = normalizeManagedHarness2(preferredHarness ?? configDefaultHarness, "claude");
14352
15107
  const transport = normalizeLocalAgentTransport(undefined, effectiveHarness);
14353
15108
  const sessionId = normalizeTmuxSessionName2(undefined, `${instance.id}-${effectiveHarness}`);
15109
+ const launchArgs = applyRequestedModelToLaunchArgs(effectiveHarness, [], input.model);
14354
15110
  const existingForInstance = overrides[instance.id];
14355
15111
  if (existingForInstance && normalizeProjectPath(existingForInstance.projectRoot) !== projectRoot) {
14356
15112
  throw new Error(`Another agent is already registered as ${instance.id} at ${existingForInstance.projectRoot}. ` + `Two clones of the same project on the same branch cannot both register here; ` + `rename one of the checkouts or switch its branch before running scout up.`);
@@ -14364,13 +15120,14 @@ async function startLocalAgent(input) {
14364
15120
  projectConfigPath: coldProjectConfigPath,
14365
15121
  source: "manual",
14366
15122
  startedAt: nowSeconds2(),
15123
+ launchArgs,
14367
15124
  defaultHarness: effectiveHarness,
14368
15125
  harnessProfiles: {
14369
15126
  [effectiveHarness]: {
14370
15127
  cwd: effectiveCwd ?? projectRoot,
14371
15128
  transport,
14372
15129
  sessionId,
14373
- launchArgs: []
15130
+ launchArgs
14374
15131
  }
14375
15132
  },
14376
15133
  runtime: {
@@ -14391,6 +15148,9 @@ async function startLocalAgent(input) {
14391
15148
  throw new Error(`Another agent is already registered as ${instance.id} at ${existingForInstance.projectRoot}. ` + `Two clones of the same project on the same branch cannot both register here; ` + `rename one of the checkouts or switch its branch before running scout up.`);
14392
15149
  }
14393
15150
  const resolvedHarness = preferredHarness ?? matchingOverride.runtime?.harness;
15151
+ const nextHarness = normalizeManagedHarness2(resolvedHarness, "claude");
15152
+ const nextDefaultHarness = preferredHarness ? normalizeManagedHarness2(preferredHarness, "claude") : defaultHarnessForOverride(matchingOverride, "claude");
15153
+ const nextLaunchArgs = applyRequestedModelToLaunchArgs(nextHarness, launchArgsForOverrideHarness(matchingOverride, nextHarness), input.model);
14394
15154
  overrides[instance.id] = {
14395
15155
  agentId: instance.id,
14396
15156
  definitionId: requestedDefinitionId,
@@ -14401,10 +15161,16 @@ async function startLocalAgent(input) {
14401
15161
  source: "manual",
14402
15162
  startedAt: matchingOverride.startedAt ?? nowSeconds2(),
14403
15163
  systemPrompt: matchingOverride.systemPrompt,
14404
- launchArgs: matchingOverride.launchArgs,
15164
+ launchArgs: nextHarness === nextDefaultHarness ? nextLaunchArgs : matchingOverride.launchArgs,
14405
15165
  capabilities: matchingOverride.capabilities,
14406
- defaultHarness: normalizeManagedHarness2(preferredHarness ?? matchingOverride.defaultHarness, "claude"),
14407
- harnessProfiles: matchingOverride.harnessProfiles,
15166
+ defaultHarness: nextDefaultHarness,
15167
+ harnessProfiles: {
15168
+ ...matchingOverride.harnessProfiles ?? {},
15169
+ [nextHarness]: {
15170
+ ...overrideHarnessProfile(matchingOverride, nextHarness),
15171
+ launchArgs: nextLaunchArgs
15172
+ }
15173
+ },
14408
15174
  runtime: {
14409
15175
  cwd: effectiveCwd ?? matchingOverride.runtime?.cwd ?? matchingProjectRoot,
14410
15176
  harness: resolvedHarness,
@@ -14416,6 +15182,22 @@ async function startLocalAgent(input) {
14416
15182
  await writeRelayAgentOverrides(overrides);
14417
15183
  targetAgentId = instance.id;
14418
15184
  } else {
15185
+ if (input.model) {
15186
+ const existingHarness = normalizeManagedHarness2(preferredHarness ?? matchingOverride.defaultHarness ?? matchingOverride.runtime?.harness, "claude");
15187
+ const nextLaunchArgs = applyRequestedModelToLaunchArgs(existingHarness, launchArgsForOverrideHarness(matchingOverride, existingHarness), input.model);
15188
+ overrides[matchingAgentId] = {
15189
+ ...matchingOverride,
15190
+ launchArgs: existingHarness === defaultHarnessForOverride(matchingOverride, existingHarness) ? nextLaunchArgs : matchingOverride.launchArgs,
15191
+ harnessProfiles: {
15192
+ ...matchingOverride.harnessProfiles ?? {},
15193
+ [existingHarness]: {
15194
+ ...overrideHarnessProfile(matchingOverride, existingHarness),
15195
+ launchArgs: nextLaunchArgs
15196
+ }
15197
+ }
15198
+ };
15199
+ await writeRelayAgentOverrides(overrides);
15200
+ }
14419
15201
  targetAgentId = matchingAgentId;
14420
15202
  }
14421
15203
  await ensureLocalAgentBindingOnline(targetAgentId, process.env.OPENSCOUT_NODE_ID ?? "local", {
@@ -14511,6 +15293,7 @@ function readPersistedClaudeSessionId(agentName) {
14511
15293
  }
14512
15294
  function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
14513
15295
  const normalizedRecord = normalizeLocalAgentRecord(agentId, record);
15296
+ const configuredModel = readLaunchModelForHarness(normalizeLocalAgentHarness(normalizedRecord.harness), normalizedRecord.launchArgs);
14514
15297
  const definitionId = normalizedRecord.definitionId ?? agentId;
14515
15298
  const displayName = titleCaseLocalAgentName(definitionId);
14516
15299
  const projectRoot = normalizedRecord.projectRoot ?? normalizedRecord.cwd;
@@ -14535,7 +15318,8 @@ function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
14535
15318
  defaultSelector: instance.defaultSelector,
14536
15319
  nodeQualifier: instance.nodeQualifier,
14537
15320
  workspaceQualifier: instance.workspaceQualifier,
14538
- branch: instance.branch
15321
+ branch: instance.branch,
15322
+ ...configuredModel ? { model: configuredModel } : {}
14539
15323
  }
14540
15324
  },
14541
15325
  agent: {
@@ -14562,7 +15346,8 @@ function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
14562
15346
  defaultSelector: instance.defaultSelector,
14563
15347
  nodeQualifier: instance.nodeQualifier,
14564
15348
  workspaceQualifier: instance.workspaceQualifier,
14565
- branch: instance.branch
15349
+ branch: instance.branch,
15350
+ ...configuredModel ? { model: configuredModel } : {}
14566
15351
  },
14567
15352
  agentClass: "general",
14568
15353
  capabilities: normalizeLocalAgentCapabilities(normalizedRecord.capabilities),
@@ -14595,6 +15380,7 @@ function buildLocalAgentBinding(agentId, record, alive, nodeId, source) {
14595
15380
  nodeQualifier: instance.nodeQualifier,
14596
15381
  workspaceQualifier: instance.workspaceQualifier,
14597
15382
  branch: instance.branch,
15383
+ ...configuredModel ? { model: configuredModel } : {},
14598
15384
  ...externalSessionId ? { externalSessionId } : {}
14599
15385
  }
14600
15386
  }
@@ -15971,6 +16757,20 @@ function readSyncStatus(bridge, sessionId) {
15971
16757
  oldestBufferedSeq: bridge.oldestBufferedSeq(sessionId)
15972
16758
  };
15973
16759
  }
16760
+ function resolveSyncSessionId(bridge, preferredSessionId) {
16761
+ if (preferredSessionId) {
16762
+ return preferredSessionId;
16763
+ }
16764
+ let latestSessionId = null;
16765
+ let latestActivityAt = Number.NEGATIVE_INFINITY;
16766
+ for (const session of bridge.getSessionSummaries()) {
16767
+ if (session.lastActivityAt > latestActivityAt) {
16768
+ latestActivityAt = session.lastActivityAt;
16769
+ latestSessionId = session.sessionId;
16770
+ }
16771
+ }
16772
+ return latestSessionId;
16773
+ }
15974
16774
  function sessionRegistryErrorResponse(reqId, error) {
15975
16775
  if (!isSessionRegistryError(error)) {
15976
16776
  return null;
@@ -16040,23 +16840,36 @@ async function handleRPCInner(bridge, req, deviceId) {
16040
16840
  return { id: req.id, result: { ok: true } };
16041
16841
  }
16042
16842
  case "sync/replay": {
16043
- const p = req.params;
16044
- if (!p.sessionId) {
16045
- return { id: req.id, error: { code: -32602, message: "sessionId is required" } };
16843
+ const p = req.params ?? {};
16844
+ if (typeof p.lastSeq !== "number") {
16845
+ return { id: req.id, error: { code: -32602, message: "lastSeq is required" } };
16046
16846
  }
16047
- const events2 = replaySyncEvents(bridge, p.sessionId, p.lastSeq);
16847
+ const sessionId = resolveSyncSessionId(bridge, p.sessionId);
16848
+ if (!sessionId) {
16849
+ return { id: req.id, result: { events: [] } };
16850
+ }
16851
+ const events2 = replaySyncEvents(bridge, sessionId, p.lastSeq);
16048
16852
  return { id: req.id, result: { events: events2 } };
16049
16853
  }
16050
16854
  case "sync/status": {
16051
16855
  const p = req.params ?? {};
16052
- if (!p.sessionId) {
16053
- return { id: req.id, error: { code: -32602, message: "sessionId is required" } };
16856
+ const sessionCount = bridge.listSessions().length;
16857
+ const sessionId = resolveSyncSessionId(bridge, p.sessionId);
16858
+ if (!sessionId) {
16859
+ return {
16860
+ id: req.id,
16861
+ result: {
16862
+ currentSeq: 0,
16863
+ oldestBufferedSeq: 0,
16864
+ sessionCount
16865
+ }
16866
+ };
16054
16867
  }
16055
16868
  return {
16056
16869
  id: req.id,
16057
16870
  result: {
16058
- ...readSyncStatus(bridge, p.sessionId),
16059
- sessionCount: bridge.listSessions().length
16871
+ ...readSyncStatus(bridge, sessionId),
16872
+ sessionCount
16060
16873
  }
16061
16874
  };
16062
16875
  }
@@ -31011,2183 +31824,6 @@ function date4(params) {
31011
31824
 
31012
31825
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
31013
31826
  config(en_default());
31014
- // ../runtime/src/registry.ts
31015
- function createRuntimeRegistrySnapshot(value = {}) {
31016
- return {
31017
- nodes: value.nodes ?? {},
31018
- actors: value.actors ?? {},
31019
- agents: value.agents ?? {},
31020
- endpoints: value.endpoints ?? {},
31021
- conversations: value.conversations ?? {},
31022
- bindings: value.bindings ?? {},
31023
- messages: value.messages ?? {},
31024
- flights: value.flights ?? {},
31025
- collaborationRecords: value.collaborationRecords ?? {}
31026
- };
31027
- }
31028
- // ../runtime/src/planner.ts
31029
- function createDeliveryId(messageId, targetId, reason, transport) {
31030
- return `del-${messageId}-${targetId}-${reason}-${transport}`;
31031
- }
31032
- function unique(values) {
31033
- return [...new Set(values)];
31034
- }
31035
- function resolveVisibilityAudience(message, conversation) {
31036
- if (message.audience?.visibleTo?.length) {
31037
- return unique(message.audience.visibleTo);
31038
- }
31039
- return unique(conversation.participantIds.filter((participantId) => participantId !== message.actorId));
31040
- }
31041
- function resolveNotifyAudience(message) {
31042
- const fromMentions = (message.mentions ?? []).map((mention) => mention.actorId);
31043
- const explicit = message.audience?.notify ?? [];
31044
- return unique([...fromMentions, ...explicit].filter((actorId) => actorId !== message.actorId));
31045
- }
31046
- function resolveInvocationAudience(message) {
31047
- return unique((message.audience?.invoke ?? []).filter((actorId) => actorId !== message.actorId));
31048
- }
31049
- function planTargetDelivery(message, route2, reason, policy) {
31050
- return {
31051
- id: createDeliveryId(message.id, route2.targetId, reason, route2.transport),
31052
- messageId: message.id,
31053
- targetId: route2.targetId,
31054
- targetNodeId: route2.nodeId,
31055
- targetKind: route2.targetKind,
31056
- transport: route2.transport,
31057
- reason,
31058
- policy,
31059
- status: "pending",
31060
- bindingId: route2.bindingId
31061
- };
31062
- }
31063
- function planMessageDeliveries(input) {
31064
- const visibilityIds = new Set(resolveVisibilityAudience(input.message, input.conversation));
31065
- const notifyIds = new Set(resolveNotifyAudience(input.message));
31066
- const invokeIds = new Set(resolveInvocationAudience(input.message));
31067
- const deliveries2 = new Map;
31068
- for (const route2 of input.participantRoutes) {
31069
- if (visibilityIds.has(route2.targetId)) {
31070
- const intent = planTargetDelivery(input.message, {
31071
- ...route2,
31072
- transport: route2.nodeId && input.localNodeId && route2.nodeId !== input.localNodeId ? "peer_broker" : route2.transport
31073
- }, input.conversation.kind === "direct" || input.conversation.kind === "group_direct" ? "direct_message" : "conversation_visibility", "durable");
31074
- deliveries2.set(intent.id, intent);
31075
- }
31076
- if (notifyIds.has(route2.targetId)) {
31077
- const intent = planTargetDelivery(input.message, {
31078
- ...route2,
31079
- transport: route2.nodeId && input.localNodeId && route2.nodeId !== input.localNodeId ? "peer_broker" : route2.transport
31080
- }, "mention", "must_ack");
31081
- deliveries2.set(intent.id, intent);
31082
- }
31083
- if (invokeIds.has(route2.targetId)) {
31084
- const intent = planTargetDelivery(input.message, {
31085
- ...route2,
31086
- transport: route2.nodeId && input.localNodeId && route2.nodeId !== input.localNodeId ? "peer_broker" : route2.transport
31087
- }, "invocation", "must_ack");
31088
- deliveries2.set(intent.id, intent);
31089
- }
31090
- if (input.message.speech?.text && route2.speechEnabled) {
31091
- const speechIntent = planTargetDelivery(input.message, {
31092
- ...route2,
31093
- transport: route2.transport === "local_socket" ? "native_voice" : "tts",
31094
- targetKind: route2.targetKind === "device" ? "voice_session" : route2.targetKind
31095
- }, "speech", "best_effort");
31096
- deliveries2.set(speechIntent.id, speechIntent);
31097
- }
31098
- }
31099
- for (const route2 of input.bindingRoutes ?? []) {
31100
- const intent = planTargetDelivery(input.message, route2, "bridge_outbound", "durable");
31101
- deliveries2.set(intent.id, intent);
31102
- }
31103
- return [...deliveries2.values()];
31104
- }
31105
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/entity.js
31106
- var entityKind = Symbol.for("drizzle:entityKind");
31107
- var hasOwnEntityKind = Symbol.for("drizzle:hasOwnEntityKind");
31108
- function is(value, type) {
31109
- if (!value || typeof value !== "object") {
31110
- return false;
31111
- }
31112
- if (value instanceof type) {
31113
- return true;
31114
- }
31115
- if (!Object.prototype.hasOwnProperty.call(type, entityKind)) {
31116
- 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.`);
31117
- }
31118
- let cls = Object.getPrototypeOf(value).constructor;
31119
- if (cls) {
31120
- while (cls) {
31121
- if (entityKind in cls && cls[entityKind] === type[entityKind]) {
31122
- return true;
31123
- }
31124
- cls = Object.getPrototypeOf(cls);
31125
- }
31126
- }
31127
- return false;
31128
- }
31129
-
31130
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/column.js
31131
- class Column {
31132
- constructor(table, config2) {
31133
- this.table = table;
31134
- this.config = config2;
31135
- this.name = config2.name;
31136
- this.keyAsName = config2.keyAsName;
31137
- this.notNull = config2.notNull;
31138
- this.default = config2.default;
31139
- this.defaultFn = config2.defaultFn;
31140
- this.onUpdateFn = config2.onUpdateFn;
31141
- this.hasDefault = config2.hasDefault;
31142
- this.primary = config2.primaryKey;
31143
- this.isUnique = config2.isUnique;
31144
- this.uniqueName = config2.uniqueName;
31145
- this.uniqueType = config2.uniqueType;
31146
- this.dataType = config2.dataType;
31147
- this.columnType = config2.columnType;
31148
- this.generated = config2.generated;
31149
- this.generatedIdentity = config2.generatedIdentity;
31150
- }
31151
- static [entityKind] = "Column";
31152
- name;
31153
- keyAsName;
31154
- primary;
31155
- notNull;
31156
- default;
31157
- defaultFn;
31158
- onUpdateFn;
31159
- hasDefault;
31160
- isUnique;
31161
- uniqueName;
31162
- uniqueType;
31163
- dataType;
31164
- columnType;
31165
- enumValues = undefined;
31166
- generated = undefined;
31167
- generatedIdentity = undefined;
31168
- config;
31169
- mapFromDriverValue(value) {
31170
- return value;
31171
- }
31172
- mapToDriverValue(value) {
31173
- return value;
31174
- }
31175
- shouldDisableInsert() {
31176
- return this.config.generated !== undefined && this.config.generated.type !== "byDefault";
31177
- }
31178
- }
31179
-
31180
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/column-builder.js
31181
- class ColumnBuilder {
31182
- static [entityKind] = "ColumnBuilder";
31183
- config;
31184
- constructor(name, dataType, columnType) {
31185
- this.config = {
31186
- name,
31187
- keyAsName: name === "",
31188
- notNull: false,
31189
- default: undefined,
31190
- hasDefault: false,
31191
- primaryKey: false,
31192
- isUnique: false,
31193
- uniqueName: undefined,
31194
- uniqueType: undefined,
31195
- dataType,
31196
- columnType,
31197
- generated: undefined
31198
- };
31199
- }
31200
- $type() {
31201
- return this;
31202
- }
31203
- notNull() {
31204
- this.config.notNull = true;
31205
- return this;
31206
- }
31207
- default(value) {
31208
- this.config.default = value;
31209
- this.config.hasDefault = true;
31210
- return this;
31211
- }
31212
- $defaultFn(fn) {
31213
- this.config.defaultFn = fn;
31214
- this.config.hasDefault = true;
31215
- return this;
31216
- }
31217
- $default = this.$defaultFn;
31218
- $onUpdateFn(fn) {
31219
- this.config.onUpdateFn = fn;
31220
- this.config.hasDefault = true;
31221
- return this;
31222
- }
31223
- $onUpdate = this.$onUpdateFn;
31224
- primaryKey() {
31225
- this.config.primaryKey = true;
31226
- this.config.notNull = true;
31227
- return this;
31228
- }
31229
- setName(name) {
31230
- if (this.config.name !== "")
31231
- return;
31232
- this.config.name = name;
31233
- }
31234
- }
31235
-
31236
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/table.utils.js
31237
- var TableName = Symbol.for("drizzle:Name");
31238
-
31239
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/tracing-utils.js
31240
- function iife(fn, ...args) {
31241
- return fn(...args);
31242
- }
31243
-
31244
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/pg-core/unique-constraint.js
31245
- function uniqueKeyName(table, columns) {
31246
- return `${table[TableName]}_${columns.join("_")}_unique`;
31247
- }
31248
-
31249
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/pg-core/columns/common.js
31250
- class PgColumn extends Column {
31251
- constructor(table, config2) {
31252
- if (!config2.uniqueName) {
31253
- config2.uniqueName = uniqueKeyName(table, [config2.name]);
31254
- }
31255
- super(table, config2);
31256
- this.table = table;
31257
- }
31258
- static [entityKind] = "PgColumn";
31259
- }
31260
-
31261
- class ExtraConfigColumn extends PgColumn {
31262
- static [entityKind] = "ExtraConfigColumn";
31263
- getSQLType() {
31264
- return this.getSQLType();
31265
- }
31266
- indexConfig = {
31267
- order: this.config.order ?? "asc",
31268
- nulls: this.config.nulls ?? "last",
31269
- opClass: this.config.opClass
31270
- };
31271
- defaultConfig = {
31272
- order: "asc",
31273
- nulls: "last",
31274
- opClass: undefined
31275
- };
31276
- asc() {
31277
- this.indexConfig.order = "asc";
31278
- return this;
31279
- }
31280
- desc() {
31281
- this.indexConfig.order = "desc";
31282
- return this;
31283
- }
31284
- nullsFirst() {
31285
- this.indexConfig.nulls = "first";
31286
- return this;
31287
- }
31288
- nullsLast() {
31289
- this.indexConfig.nulls = "last";
31290
- return this;
31291
- }
31292
- op(opClass) {
31293
- this.indexConfig.opClass = opClass;
31294
- return this;
31295
- }
31296
- }
31297
-
31298
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/pg-core/columns/enum.js
31299
- class PgEnumObjectColumn extends PgColumn {
31300
- static [entityKind] = "PgEnumObjectColumn";
31301
- enum;
31302
- enumValues = this.config.enum.enumValues;
31303
- constructor(table, config2) {
31304
- super(table, config2);
31305
- this.enum = config2.enum;
31306
- }
31307
- getSQLType() {
31308
- return this.enum.enumName;
31309
- }
31310
- }
31311
- var isPgEnumSym = Symbol.for("drizzle:isPgEnum");
31312
- function isPgEnum(obj) {
31313
- return !!obj && typeof obj === "function" && isPgEnumSym in obj && obj[isPgEnumSym] === true;
31314
- }
31315
- class PgEnumColumn extends PgColumn {
31316
- static [entityKind] = "PgEnumColumn";
31317
- enum = this.config.enum;
31318
- enumValues = this.config.enum.enumValues;
31319
- constructor(table, config2) {
31320
- super(table, config2);
31321
- this.enum = config2.enum;
31322
- }
31323
- getSQLType() {
31324
- return this.enum.enumName;
31325
- }
31326
- }
31327
-
31328
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/subquery.js
31329
- class Subquery {
31330
- static [entityKind] = "Subquery";
31331
- constructor(sql, fields, alias, isWith = false, usedTables = []) {
31332
- this._ = {
31333
- brand: "Subquery",
31334
- sql,
31335
- selectedFields: fields,
31336
- alias,
31337
- isWith,
31338
- usedTables
31339
- };
31340
- }
31341
- }
31342
-
31343
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/version.js
31344
- var version2 = "0.45.2";
31345
-
31346
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/tracing.js
31347
- var otel;
31348
- var rawTracer;
31349
- var tracer = {
31350
- startActiveSpan(name, fn) {
31351
- if (!otel) {
31352
- return fn();
31353
- }
31354
- if (!rawTracer) {
31355
- rawTracer = otel.trace.getTracer("drizzle-orm", version2);
31356
- }
31357
- return iife((otel2, rawTracer2) => rawTracer2.startActiveSpan(name, (span) => {
31358
- try {
31359
- return fn(span);
31360
- } catch (e) {
31361
- span.setStatus({
31362
- code: otel2.SpanStatusCode.ERROR,
31363
- message: e instanceof Error ? e.message : "Unknown error"
31364
- });
31365
- throw e;
31366
- } finally {
31367
- span.end();
31368
- }
31369
- }), otel, rawTracer);
31370
- }
31371
- };
31372
-
31373
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/view-common.js
31374
- var ViewBaseConfig = Symbol.for("drizzle:ViewBaseConfig");
31375
-
31376
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/table.js
31377
- var Schema = Symbol.for("drizzle:Schema");
31378
- var Columns = Symbol.for("drizzle:Columns");
31379
- var ExtraConfigColumns = Symbol.for("drizzle:ExtraConfigColumns");
31380
- var OriginalName = Symbol.for("drizzle:OriginalName");
31381
- var BaseName = Symbol.for("drizzle:BaseName");
31382
- var IsAlias = Symbol.for("drizzle:IsAlias");
31383
- var ExtraConfigBuilder = Symbol.for("drizzle:ExtraConfigBuilder");
31384
- var IsDrizzleTable = Symbol.for("drizzle:IsDrizzleTable");
31385
-
31386
- class Table {
31387
- static [entityKind] = "Table";
31388
- static Symbol = {
31389
- Name: TableName,
31390
- Schema,
31391
- OriginalName,
31392
- Columns,
31393
- ExtraConfigColumns,
31394
- BaseName,
31395
- IsAlias,
31396
- ExtraConfigBuilder
31397
- };
31398
- [TableName];
31399
- [OriginalName];
31400
- [Schema];
31401
- [Columns];
31402
- [ExtraConfigColumns];
31403
- [BaseName];
31404
- [IsAlias] = false;
31405
- [IsDrizzleTable] = true;
31406
- [ExtraConfigBuilder] = undefined;
31407
- constructor(name, schema, baseName) {
31408
- this[TableName] = this[OriginalName] = name;
31409
- this[Schema] = schema;
31410
- this[BaseName] = baseName;
31411
- }
31412
- }
31413
-
31414
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sql/sql.js
31415
- function isSQLWrapper(value) {
31416
- return value !== null && value !== undefined && typeof value.getSQL === "function";
31417
- }
31418
- function mergeQueries(queries) {
31419
- const result = { sql: "", params: [] };
31420
- for (const query of queries) {
31421
- result.sql += query.sql;
31422
- result.params.push(...query.params);
31423
- if (query.typings?.length) {
31424
- if (!result.typings) {
31425
- result.typings = [];
31426
- }
31427
- result.typings.push(...query.typings);
31428
- }
31429
- }
31430
- return result;
31431
- }
31432
-
31433
- class StringChunk {
31434
- static [entityKind] = "StringChunk";
31435
- value;
31436
- constructor(value) {
31437
- this.value = Array.isArray(value) ? value : [value];
31438
- }
31439
- getSQL() {
31440
- return new SQL([this]);
31441
- }
31442
- }
31443
-
31444
- class SQL {
31445
- constructor(queryChunks) {
31446
- this.queryChunks = queryChunks;
31447
- for (const chunk of queryChunks) {
31448
- if (is(chunk, Table)) {
31449
- const schemaName = chunk[Table.Symbol.Schema];
31450
- this.usedTables.push(schemaName === undefined ? chunk[Table.Symbol.Name] : schemaName + "." + chunk[Table.Symbol.Name]);
31451
- }
31452
- }
31453
- }
31454
- static [entityKind] = "SQL";
31455
- decoder = noopDecoder;
31456
- shouldInlineParams = false;
31457
- usedTables = [];
31458
- append(query) {
31459
- this.queryChunks.push(...query.queryChunks);
31460
- return this;
31461
- }
31462
- toQuery(config2) {
31463
- return tracer.startActiveSpan("drizzle.buildSQL", (span) => {
31464
- const query = this.buildQueryFromSourceParams(this.queryChunks, config2);
31465
- span?.setAttributes({
31466
- "drizzle.query.text": query.sql,
31467
- "drizzle.query.params": JSON.stringify(query.params)
31468
- });
31469
- return query;
31470
- });
31471
- }
31472
- buildQueryFromSourceParams(chunks, _config) {
31473
- const config2 = Object.assign({}, _config, {
31474
- inlineParams: _config.inlineParams || this.shouldInlineParams,
31475
- paramStartIndex: _config.paramStartIndex || { value: 0 }
31476
- });
31477
- const {
31478
- casing,
31479
- escapeName,
31480
- escapeParam,
31481
- prepareTyping,
31482
- inlineParams,
31483
- paramStartIndex
31484
- } = config2;
31485
- return mergeQueries(chunks.map((chunk) => {
31486
- if (is(chunk, StringChunk)) {
31487
- return { sql: chunk.value.join(""), params: [] };
31488
- }
31489
- if (is(chunk, Name)) {
31490
- return { sql: escapeName(chunk.value), params: [] };
31491
- }
31492
- if (chunk === undefined) {
31493
- return { sql: "", params: [] };
31494
- }
31495
- if (Array.isArray(chunk)) {
31496
- const result = [new StringChunk("(")];
31497
- for (const [i, p] of chunk.entries()) {
31498
- result.push(p);
31499
- if (i < chunk.length - 1) {
31500
- result.push(new StringChunk(", "));
31501
- }
31502
- }
31503
- result.push(new StringChunk(")"));
31504
- return this.buildQueryFromSourceParams(result, config2);
31505
- }
31506
- if (is(chunk, SQL)) {
31507
- return this.buildQueryFromSourceParams(chunk.queryChunks, {
31508
- ...config2,
31509
- inlineParams: inlineParams || chunk.shouldInlineParams
31510
- });
31511
- }
31512
- if (is(chunk, Table)) {
31513
- const schemaName = chunk[Table.Symbol.Schema];
31514
- const tableName = chunk[Table.Symbol.Name];
31515
- return {
31516
- sql: schemaName === undefined || chunk[IsAlias] ? escapeName(tableName) : escapeName(schemaName) + "." + escapeName(tableName),
31517
- params: []
31518
- };
31519
- }
31520
- if (is(chunk, Column)) {
31521
- const columnName = casing.getColumnCasing(chunk);
31522
- if (_config.invokeSource === "indexes") {
31523
- return { sql: escapeName(columnName), params: [] };
31524
- }
31525
- const schemaName = chunk.table[Table.Symbol.Schema];
31526
- return {
31527
- sql: chunk.table[IsAlias] || schemaName === undefined ? escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName) : escapeName(schemaName) + "." + escapeName(chunk.table[Table.Symbol.Name]) + "." + escapeName(columnName),
31528
- params: []
31529
- };
31530
- }
31531
- if (is(chunk, View)) {
31532
- const schemaName = chunk[ViewBaseConfig].schema;
31533
- const viewName = chunk[ViewBaseConfig].name;
31534
- return {
31535
- sql: schemaName === undefined || chunk[ViewBaseConfig].isAlias ? escapeName(viewName) : escapeName(schemaName) + "." + escapeName(viewName),
31536
- params: []
31537
- };
31538
- }
31539
- if (is(chunk, Param)) {
31540
- if (is(chunk.value, Placeholder)) {
31541
- return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
31542
- }
31543
- const mappedValue = chunk.value === null ? null : chunk.encoder.mapToDriverValue(chunk.value);
31544
- if (is(mappedValue, SQL)) {
31545
- return this.buildQueryFromSourceParams([mappedValue], config2);
31546
- }
31547
- if (inlineParams) {
31548
- return { sql: this.mapInlineParam(mappedValue, config2), params: [] };
31549
- }
31550
- let typings = ["none"];
31551
- if (prepareTyping) {
31552
- typings = [prepareTyping(chunk.encoder)];
31553
- }
31554
- return { sql: escapeParam(paramStartIndex.value++, mappedValue), params: [mappedValue], typings };
31555
- }
31556
- if (is(chunk, Placeholder)) {
31557
- return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
31558
- }
31559
- if (is(chunk, SQL.Aliased) && chunk.fieldAlias !== undefined) {
31560
- return { sql: escapeName(chunk.fieldAlias), params: [] };
31561
- }
31562
- if (is(chunk, Subquery)) {
31563
- if (chunk._.isWith) {
31564
- return { sql: escapeName(chunk._.alias), params: [] };
31565
- }
31566
- return this.buildQueryFromSourceParams([
31567
- new StringChunk("("),
31568
- chunk._.sql,
31569
- new StringChunk(") "),
31570
- new Name(chunk._.alias)
31571
- ], config2);
31572
- }
31573
- if (isPgEnum(chunk)) {
31574
- if (chunk.schema) {
31575
- return { sql: escapeName(chunk.schema) + "." + escapeName(chunk.enumName), params: [] };
31576
- }
31577
- return { sql: escapeName(chunk.enumName), params: [] };
31578
- }
31579
- if (isSQLWrapper(chunk)) {
31580
- if (chunk.shouldOmitSQLParens?.()) {
31581
- return this.buildQueryFromSourceParams([chunk.getSQL()], config2);
31582
- }
31583
- return this.buildQueryFromSourceParams([
31584
- new StringChunk("("),
31585
- chunk.getSQL(),
31586
- new StringChunk(")")
31587
- ], config2);
31588
- }
31589
- if (inlineParams) {
31590
- return { sql: this.mapInlineParam(chunk, config2), params: [] };
31591
- }
31592
- return { sql: escapeParam(paramStartIndex.value++, chunk), params: [chunk], typings: ["none"] };
31593
- }));
31594
- }
31595
- mapInlineParam(chunk, { escapeString }) {
31596
- if (chunk === null) {
31597
- return "null";
31598
- }
31599
- if (typeof chunk === "number" || typeof chunk === "boolean") {
31600
- return chunk.toString();
31601
- }
31602
- if (typeof chunk === "string") {
31603
- return escapeString(chunk);
31604
- }
31605
- if (typeof chunk === "object") {
31606
- const mappedValueAsString = chunk.toString();
31607
- if (mappedValueAsString === "[object Object]") {
31608
- return escapeString(JSON.stringify(chunk));
31609
- }
31610
- return escapeString(mappedValueAsString);
31611
- }
31612
- throw new Error("Unexpected param value: " + chunk);
31613
- }
31614
- getSQL() {
31615
- return this;
31616
- }
31617
- as(alias) {
31618
- if (alias === undefined) {
31619
- return this;
31620
- }
31621
- return new SQL.Aliased(this, alias);
31622
- }
31623
- mapWith(decoder) {
31624
- this.decoder = typeof decoder === "function" ? { mapFromDriverValue: decoder } : decoder;
31625
- return this;
31626
- }
31627
- inlineParams() {
31628
- this.shouldInlineParams = true;
31629
- return this;
31630
- }
31631
- if(condition) {
31632
- return condition ? this : undefined;
31633
- }
31634
- }
31635
-
31636
- class Name {
31637
- constructor(value) {
31638
- this.value = value;
31639
- }
31640
- static [entityKind] = "Name";
31641
- brand;
31642
- getSQL() {
31643
- return new SQL([this]);
31644
- }
31645
- }
31646
- var noopDecoder = {
31647
- mapFromDriverValue: (value) => value
31648
- };
31649
- var noopEncoder = {
31650
- mapToDriverValue: (value) => value
31651
- };
31652
- var noopMapper = {
31653
- ...noopDecoder,
31654
- ...noopEncoder
31655
- };
31656
-
31657
- class Param {
31658
- constructor(value, encoder = noopEncoder) {
31659
- this.value = value;
31660
- this.encoder = encoder;
31661
- }
31662
- static [entityKind] = "Param";
31663
- brand;
31664
- getSQL() {
31665
- return new SQL([this]);
31666
- }
31667
- }
31668
- function sql(strings, ...params) {
31669
- const queryChunks = [];
31670
- if (params.length > 0 || strings.length > 0 && strings[0] !== "") {
31671
- queryChunks.push(new StringChunk(strings[0]));
31672
- }
31673
- for (const [paramIndex, param2] of params.entries()) {
31674
- queryChunks.push(param2, new StringChunk(strings[paramIndex + 1]));
31675
- }
31676
- return new SQL(queryChunks);
31677
- }
31678
- ((sql2) => {
31679
- function empty() {
31680
- return new SQL([]);
31681
- }
31682
- sql2.empty = empty;
31683
- function fromList(list) {
31684
- return new SQL(list);
31685
- }
31686
- sql2.fromList = fromList;
31687
- function raw(str) {
31688
- return new SQL([new StringChunk(str)]);
31689
- }
31690
- sql2.raw = raw;
31691
- function join18(chunks, separator) {
31692
- const result = [];
31693
- for (const [i, chunk] of chunks.entries()) {
31694
- if (i > 0 && separator !== undefined) {
31695
- result.push(separator);
31696
- }
31697
- result.push(chunk);
31698
- }
31699
- return new SQL(result);
31700
- }
31701
- sql2.join = join18;
31702
- function identifier(value) {
31703
- return new Name(value);
31704
- }
31705
- sql2.identifier = identifier;
31706
- function placeholder2(name2) {
31707
- return new Placeholder(name2);
31708
- }
31709
- sql2.placeholder = placeholder2;
31710
- function param2(value, encoder) {
31711
- return new Param(value, encoder);
31712
- }
31713
- sql2.param = param2;
31714
- })(sql || (sql = {}));
31715
- ((SQL2) => {
31716
-
31717
- class Aliased {
31718
- constructor(sql2, fieldAlias) {
31719
- this.sql = sql2;
31720
- this.fieldAlias = fieldAlias;
31721
- }
31722
- static [entityKind] = "SQL.Aliased";
31723
- isSelectionField = false;
31724
- getSQL() {
31725
- return this.sql;
31726
- }
31727
- clone() {
31728
- return new Aliased(this.sql, this.fieldAlias);
31729
- }
31730
- }
31731
- SQL2.Aliased = Aliased;
31732
- })(SQL || (SQL = {}));
31733
-
31734
- class Placeholder {
31735
- constructor(name2) {
31736
- this.name = name2;
31737
- }
31738
- static [entityKind] = "Placeholder";
31739
- getSQL() {
31740
- return new SQL([this]);
31741
- }
31742
- }
31743
- var IsDrizzleView = Symbol.for("drizzle:IsDrizzleView");
31744
-
31745
- class View {
31746
- static [entityKind] = "View";
31747
- [ViewBaseConfig];
31748
- [IsDrizzleView] = true;
31749
- constructor({ name: name2, schema, selectedFields, query }) {
31750
- this[ViewBaseConfig] = {
31751
- name: name2,
31752
- originalName: name2,
31753
- schema,
31754
- selectedFields,
31755
- query,
31756
- isExisting: !query,
31757
- isAlias: false
31758
- };
31759
- }
31760
- getSQL() {
31761
- return new SQL([this]);
31762
- }
31763
- }
31764
- Column.prototype.getSQL = function() {
31765
- return new SQL([this]);
31766
- };
31767
- Table.prototype.getSQL = function() {
31768
- return new SQL([this]);
31769
- };
31770
- Subquery.prototype.getSQL = function() {
31771
- return new SQL([this]);
31772
- };
31773
-
31774
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/utils.js
31775
- function getColumnNameAndConfig(a, b) {
31776
- return {
31777
- name: typeof a === "string" && a.length > 0 ? a : "",
31778
- config: typeof a === "object" ? a : b
31779
- };
31780
- }
31781
- var textDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder;
31782
-
31783
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/foreign-keys.js
31784
- class ForeignKeyBuilder {
31785
- static [entityKind] = "SQLiteForeignKeyBuilder";
31786
- reference;
31787
- _onUpdate;
31788
- _onDelete;
31789
- constructor(config2, actions) {
31790
- this.reference = () => {
31791
- const { name, columns, foreignColumns } = config2();
31792
- return { name, columns, foreignTable: foreignColumns[0].table, foreignColumns };
31793
- };
31794
- if (actions) {
31795
- this._onUpdate = actions.onUpdate;
31796
- this._onDelete = actions.onDelete;
31797
- }
31798
- }
31799
- onUpdate(action) {
31800
- this._onUpdate = action;
31801
- return this;
31802
- }
31803
- onDelete(action) {
31804
- this._onDelete = action;
31805
- return this;
31806
- }
31807
- build(table) {
31808
- return new ForeignKey(table, this);
31809
- }
31810
- }
31811
-
31812
- class ForeignKey {
31813
- constructor(table, builder) {
31814
- this.table = table;
31815
- this.reference = builder.reference;
31816
- this.onUpdate = builder._onUpdate;
31817
- this.onDelete = builder._onDelete;
31818
- }
31819
- static [entityKind] = "SQLiteForeignKey";
31820
- reference;
31821
- onUpdate;
31822
- onDelete;
31823
- getName() {
31824
- const { name, columns, foreignColumns } = this.reference();
31825
- const columnNames = columns.map((column) => column.name);
31826
- const foreignColumnNames = foreignColumns.map((column) => column.name);
31827
- const chunks = [
31828
- this.table[TableName],
31829
- ...columnNames,
31830
- foreignColumns[0].table[TableName],
31831
- ...foreignColumnNames
31832
- ];
31833
- return name ?? `${chunks.join("_")}_fk`;
31834
- }
31835
- }
31836
-
31837
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/unique-constraint.js
31838
- function uniqueKeyName2(table, columns) {
31839
- return `${table[TableName]}_${columns.join("_")}_unique`;
31840
- }
31841
-
31842
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/common.js
31843
- class SQLiteColumnBuilder extends ColumnBuilder {
31844
- static [entityKind] = "SQLiteColumnBuilder";
31845
- foreignKeyConfigs = [];
31846
- references(ref, actions = {}) {
31847
- this.foreignKeyConfigs.push({ ref, actions });
31848
- return this;
31849
- }
31850
- unique(name) {
31851
- this.config.isUnique = true;
31852
- this.config.uniqueName = name;
31853
- return this;
31854
- }
31855
- generatedAlwaysAs(as, config2) {
31856
- this.config.generated = {
31857
- as,
31858
- type: "always",
31859
- mode: config2?.mode ?? "virtual"
31860
- };
31861
- return this;
31862
- }
31863
- buildForeignKeys(column, table) {
31864
- return this.foreignKeyConfigs.map(({ ref, actions }) => {
31865
- return ((ref2, actions2) => {
31866
- const builder = new ForeignKeyBuilder(() => {
31867
- const foreignColumn = ref2();
31868
- return { columns: [column], foreignColumns: [foreignColumn] };
31869
- });
31870
- if (actions2.onUpdate) {
31871
- builder.onUpdate(actions2.onUpdate);
31872
- }
31873
- if (actions2.onDelete) {
31874
- builder.onDelete(actions2.onDelete);
31875
- }
31876
- return builder.build(table);
31877
- })(ref, actions);
31878
- });
31879
- }
31880
- }
31881
-
31882
- class SQLiteColumn extends Column {
31883
- constructor(table, config2) {
31884
- if (!config2.uniqueName) {
31885
- config2.uniqueName = uniqueKeyName2(table, [config2.name]);
31886
- }
31887
- super(table, config2);
31888
- this.table = table;
31889
- }
31890
- static [entityKind] = "SQLiteColumn";
31891
- }
31892
-
31893
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/blob.js
31894
- class SQLiteBigIntBuilder extends SQLiteColumnBuilder {
31895
- static [entityKind] = "SQLiteBigIntBuilder";
31896
- constructor(name) {
31897
- super(name, "bigint", "SQLiteBigInt");
31898
- }
31899
- build(table) {
31900
- return new SQLiteBigInt(table, this.config);
31901
- }
31902
- }
31903
-
31904
- class SQLiteBigInt extends SQLiteColumn {
31905
- static [entityKind] = "SQLiteBigInt";
31906
- getSQLType() {
31907
- return "blob";
31908
- }
31909
- mapFromDriverValue(value) {
31910
- if (typeof Buffer !== "undefined" && Buffer.from) {
31911
- 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);
31912
- return BigInt(buf.toString("utf8"));
31913
- }
31914
- return BigInt(textDecoder.decode(value));
31915
- }
31916
- mapToDriverValue(value) {
31917
- return Buffer.from(value.toString());
31918
- }
31919
- }
31920
-
31921
- class SQLiteBlobJsonBuilder extends SQLiteColumnBuilder {
31922
- static [entityKind] = "SQLiteBlobJsonBuilder";
31923
- constructor(name) {
31924
- super(name, "json", "SQLiteBlobJson");
31925
- }
31926
- build(table) {
31927
- return new SQLiteBlobJson(table, this.config);
31928
- }
31929
- }
31930
-
31931
- class SQLiteBlobJson extends SQLiteColumn {
31932
- static [entityKind] = "SQLiteBlobJson";
31933
- getSQLType() {
31934
- return "blob";
31935
- }
31936
- mapFromDriverValue(value) {
31937
- if (typeof Buffer !== "undefined" && Buffer.from) {
31938
- 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);
31939
- return JSON.parse(buf.toString("utf8"));
31940
- }
31941
- return JSON.parse(textDecoder.decode(value));
31942
- }
31943
- mapToDriverValue(value) {
31944
- return Buffer.from(JSON.stringify(value));
31945
- }
31946
- }
31947
-
31948
- class SQLiteBlobBufferBuilder extends SQLiteColumnBuilder {
31949
- static [entityKind] = "SQLiteBlobBufferBuilder";
31950
- constructor(name) {
31951
- super(name, "buffer", "SQLiteBlobBuffer");
31952
- }
31953
- build(table) {
31954
- return new SQLiteBlobBuffer(table, this.config);
31955
- }
31956
- }
31957
-
31958
- class SQLiteBlobBuffer extends SQLiteColumn {
31959
- static [entityKind] = "SQLiteBlobBuffer";
31960
- mapFromDriverValue(value) {
31961
- if (Buffer.isBuffer(value)) {
31962
- return value;
31963
- }
31964
- return Buffer.from(value);
31965
- }
31966
- getSQLType() {
31967
- return "blob";
31968
- }
31969
- }
31970
- function blob(a, b) {
31971
- const { name, config: config2 } = getColumnNameAndConfig(a, b);
31972
- if (config2?.mode === "json") {
31973
- return new SQLiteBlobJsonBuilder(name);
31974
- }
31975
- if (config2?.mode === "bigint") {
31976
- return new SQLiteBigIntBuilder(name);
31977
- }
31978
- return new SQLiteBlobBufferBuilder(name);
31979
- }
31980
-
31981
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/custom.js
31982
- class SQLiteCustomColumnBuilder extends SQLiteColumnBuilder {
31983
- static [entityKind] = "SQLiteCustomColumnBuilder";
31984
- constructor(name, fieldConfig, customTypeParams) {
31985
- super(name, "custom", "SQLiteCustomColumn");
31986
- this.config.fieldConfig = fieldConfig;
31987
- this.config.customTypeParams = customTypeParams;
31988
- }
31989
- build(table) {
31990
- return new SQLiteCustomColumn(table, this.config);
31991
- }
31992
- }
31993
-
31994
- class SQLiteCustomColumn extends SQLiteColumn {
31995
- static [entityKind] = "SQLiteCustomColumn";
31996
- sqlName;
31997
- mapTo;
31998
- mapFrom;
31999
- constructor(table, config2) {
32000
- super(table, config2);
32001
- this.sqlName = config2.customTypeParams.dataType(config2.fieldConfig);
32002
- this.mapTo = config2.customTypeParams.toDriver;
32003
- this.mapFrom = config2.customTypeParams.fromDriver;
32004
- }
32005
- getSQLType() {
32006
- return this.sqlName;
32007
- }
32008
- mapFromDriverValue(value) {
32009
- return typeof this.mapFrom === "function" ? this.mapFrom(value) : value;
32010
- }
32011
- mapToDriverValue(value) {
32012
- return typeof this.mapTo === "function" ? this.mapTo(value) : value;
32013
- }
32014
- }
32015
- function customType(customTypeParams) {
32016
- return (a, b) => {
32017
- const { name, config: config2 } = getColumnNameAndConfig(a, b);
32018
- return new SQLiteCustomColumnBuilder(name, config2, customTypeParams);
32019
- };
32020
- }
32021
-
32022
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/integer.js
32023
- class SQLiteBaseIntegerBuilder extends SQLiteColumnBuilder {
32024
- static [entityKind] = "SQLiteBaseIntegerBuilder";
32025
- constructor(name, dataType, columnType) {
32026
- super(name, dataType, columnType);
32027
- this.config.autoIncrement = false;
32028
- }
32029
- primaryKey(config2) {
32030
- if (config2?.autoIncrement) {
32031
- this.config.autoIncrement = true;
32032
- }
32033
- this.config.hasDefault = true;
32034
- return super.primaryKey();
32035
- }
32036
- }
32037
-
32038
- class SQLiteBaseInteger extends SQLiteColumn {
32039
- static [entityKind] = "SQLiteBaseInteger";
32040
- autoIncrement = this.config.autoIncrement;
32041
- getSQLType() {
32042
- return "integer";
32043
- }
32044
- }
32045
-
32046
- class SQLiteIntegerBuilder extends SQLiteBaseIntegerBuilder {
32047
- static [entityKind] = "SQLiteIntegerBuilder";
32048
- constructor(name) {
32049
- super(name, "number", "SQLiteInteger");
32050
- }
32051
- build(table) {
32052
- return new SQLiteInteger(table, this.config);
32053
- }
32054
- }
32055
-
32056
- class SQLiteInteger extends SQLiteBaseInteger {
32057
- static [entityKind] = "SQLiteInteger";
32058
- }
32059
-
32060
- class SQLiteTimestampBuilder extends SQLiteBaseIntegerBuilder {
32061
- static [entityKind] = "SQLiteTimestampBuilder";
32062
- constructor(name, mode) {
32063
- super(name, "date", "SQLiteTimestamp");
32064
- this.config.mode = mode;
32065
- }
32066
- defaultNow() {
32067
- return this.default(sql`(cast((julianday('now') - 2440587.5)*86400000 as integer))`);
32068
- }
32069
- build(table) {
32070
- return new SQLiteTimestamp(table, this.config);
32071
- }
32072
- }
32073
-
32074
- class SQLiteTimestamp extends SQLiteBaseInteger {
32075
- static [entityKind] = "SQLiteTimestamp";
32076
- mode = this.config.mode;
32077
- mapFromDriverValue(value) {
32078
- if (this.config.mode === "timestamp") {
32079
- return new Date(value * 1000);
32080
- }
32081
- return new Date(value);
32082
- }
32083
- mapToDriverValue(value) {
32084
- const unix = value.getTime();
32085
- if (this.config.mode === "timestamp") {
32086
- return Math.floor(unix / 1000);
32087
- }
32088
- return unix;
32089
- }
32090
- }
32091
-
32092
- class SQLiteBooleanBuilder extends SQLiteBaseIntegerBuilder {
32093
- static [entityKind] = "SQLiteBooleanBuilder";
32094
- constructor(name, mode) {
32095
- super(name, "boolean", "SQLiteBoolean");
32096
- this.config.mode = mode;
32097
- }
32098
- build(table) {
32099
- return new SQLiteBoolean(table, this.config);
32100
- }
32101
- }
32102
-
32103
- class SQLiteBoolean extends SQLiteBaseInteger {
32104
- static [entityKind] = "SQLiteBoolean";
32105
- mode = this.config.mode;
32106
- mapFromDriverValue(value) {
32107
- return Number(value) === 1;
32108
- }
32109
- mapToDriverValue(value) {
32110
- return value ? 1 : 0;
32111
- }
32112
- }
32113
- function integer2(a, b) {
32114
- const { name, config: config2 } = getColumnNameAndConfig(a, b);
32115
- if (config2?.mode === "timestamp" || config2?.mode === "timestamp_ms") {
32116
- return new SQLiteTimestampBuilder(name, config2.mode);
32117
- }
32118
- if (config2?.mode === "boolean") {
32119
- return new SQLiteBooleanBuilder(name, config2.mode);
32120
- }
32121
- return new SQLiteIntegerBuilder(name);
32122
- }
32123
-
32124
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/numeric.js
32125
- class SQLiteNumericBuilder extends SQLiteColumnBuilder {
32126
- static [entityKind] = "SQLiteNumericBuilder";
32127
- constructor(name) {
32128
- super(name, "string", "SQLiteNumeric");
32129
- }
32130
- build(table) {
32131
- return new SQLiteNumeric(table, this.config);
32132
- }
32133
- }
32134
-
32135
- class SQLiteNumeric extends SQLiteColumn {
32136
- static [entityKind] = "SQLiteNumeric";
32137
- mapFromDriverValue(value) {
32138
- if (typeof value === "string")
32139
- return value;
32140
- return String(value);
32141
- }
32142
- getSQLType() {
32143
- return "numeric";
32144
- }
32145
- }
32146
-
32147
- class SQLiteNumericNumberBuilder extends SQLiteColumnBuilder {
32148
- static [entityKind] = "SQLiteNumericNumberBuilder";
32149
- constructor(name) {
32150
- super(name, "number", "SQLiteNumericNumber");
32151
- }
32152
- build(table) {
32153
- return new SQLiteNumericNumber(table, this.config);
32154
- }
32155
- }
32156
-
32157
- class SQLiteNumericNumber extends SQLiteColumn {
32158
- static [entityKind] = "SQLiteNumericNumber";
32159
- mapFromDriverValue(value) {
32160
- if (typeof value === "number")
32161
- return value;
32162
- return Number(value);
32163
- }
32164
- mapToDriverValue = String;
32165
- getSQLType() {
32166
- return "numeric";
32167
- }
32168
- }
32169
-
32170
- class SQLiteNumericBigIntBuilder extends SQLiteColumnBuilder {
32171
- static [entityKind] = "SQLiteNumericBigIntBuilder";
32172
- constructor(name) {
32173
- super(name, "bigint", "SQLiteNumericBigInt");
32174
- }
32175
- build(table) {
32176
- return new SQLiteNumericBigInt(table, this.config);
32177
- }
32178
- }
32179
-
32180
- class SQLiteNumericBigInt extends SQLiteColumn {
32181
- static [entityKind] = "SQLiteNumericBigInt";
32182
- mapFromDriverValue = BigInt;
32183
- mapToDriverValue = String;
32184
- getSQLType() {
32185
- return "numeric";
32186
- }
32187
- }
32188
- function numeric(a, b) {
32189
- const { name, config: config2 } = getColumnNameAndConfig(a, b);
32190
- const mode = config2?.mode;
32191
- return mode === "number" ? new SQLiteNumericNumberBuilder(name) : mode === "bigint" ? new SQLiteNumericBigIntBuilder(name) : new SQLiteNumericBuilder(name);
32192
- }
32193
-
32194
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/real.js
32195
- class SQLiteRealBuilder extends SQLiteColumnBuilder {
32196
- static [entityKind] = "SQLiteRealBuilder";
32197
- constructor(name) {
32198
- super(name, "number", "SQLiteReal");
32199
- }
32200
- build(table) {
32201
- return new SQLiteReal(table, this.config);
32202
- }
32203
- }
32204
-
32205
- class SQLiteReal extends SQLiteColumn {
32206
- static [entityKind] = "SQLiteReal";
32207
- getSQLType() {
32208
- return "real";
32209
- }
32210
- }
32211
- function real(name) {
32212
- return new SQLiteRealBuilder(name ?? "");
32213
- }
32214
-
32215
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/text.js
32216
- class SQLiteTextBuilder extends SQLiteColumnBuilder {
32217
- static [entityKind] = "SQLiteTextBuilder";
32218
- constructor(name, config2) {
32219
- super(name, "string", "SQLiteText");
32220
- this.config.enumValues = config2.enum;
32221
- this.config.length = config2.length;
32222
- }
32223
- build(table) {
32224
- return new SQLiteText(table, this.config);
32225
- }
32226
- }
32227
-
32228
- class SQLiteText extends SQLiteColumn {
32229
- static [entityKind] = "SQLiteText";
32230
- enumValues = this.config.enumValues;
32231
- length = this.config.length;
32232
- constructor(table, config2) {
32233
- super(table, config2);
32234
- }
32235
- getSQLType() {
32236
- return `text${this.config.length ? `(${this.config.length})` : ""}`;
32237
- }
32238
- }
32239
-
32240
- class SQLiteTextJsonBuilder extends SQLiteColumnBuilder {
32241
- static [entityKind] = "SQLiteTextJsonBuilder";
32242
- constructor(name) {
32243
- super(name, "json", "SQLiteTextJson");
32244
- }
32245
- build(table) {
32246
- return new SQLiteTextJson(table, this.config);
32247
- }
32248
- }
32249
-
32250
- class SQLiteTextJson extends SQLiteColumn {
32251
- static [entityKind] = "SQLiteTextJson";
32252
- getSQLType() {
32253
- return "text";
32254
- }
32255
- mapFromDriverValue(value) {
32256
- return JSON.parse(value);
32257
- }
32258
- mapToDriverValue(value) {
32259
- return JSON.stringify(value);
32260
- }
32261
- }
32262
- function text(a, b = {}) {
32263
- const { name, config: config2 } = getColumnNameAndConfig(a, b);
32264
- if (config2.mode === "json") {
32265
- return new SQLiteTextJsonBuilder(name);
32266
- }
32267
- return new SQLiteTextBuilder(name, config2);
32268
- }
32269
-
32270
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/columns/all.js
32271
- function getSQLiteColumnBuilders() {
32272
- return {
32273
- blob,
32274
- customType,
32275
- integer: integer2,
32276
- numeric,
32277
- real,
32278
- text
32279
- };
32280
- }
32281
-
32282
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/table.js
32283
- var InlineForeignKeys = Symbol.for("drizzle:SQLiteInlineForeignKeys");
32284
-
32285
- class SQLiteTable extends Table {
32286
- static [entityKind] = "SQLiteTable";
32287
- static Symbol = Object.assign({}, Table.Symbol, {
32288
- InlineForeignKeys
32289
- });
32290
- [Table.Symbol.Columns];
32291
- [InlineForeignKeys] = [];
32292
- [Table.Symbol.ExtraConfigBuilder] = undefined;
32293
- }
32294
- function sqliteTableBase(name, columns, extraConfig, schema, baseName = name) {
32295
- const rawTable = new SQLiteTable(name, schema, baseName);
32296
- const parsedColumns = typeof columns === "function" ? columns(getSQLiteColumnBuilders()) : columns;
32297
- const builtColumns = Object.fromEntries(Object.entries(parsedColumns).map(([name2, colBuilderBase]) => {
32298
- const colBuilder = colBuilderBase;
32299
- colBuilder.setName(name2);
32300
- const column = colBuilder.build(rawTable);
32301
- rawTable[InlineForeignKeys].push(...colBuilder.buildForeignKeys(column, rawTable));
32302
- return [name2, column];
32303
- }));
32304
- const table = Object.assign(rawTable, builtColumns);
32305
- table[Table.Symbol.Columns] = builtColumns;
32306
- table[Table.Symbol.ExtraConfigColumns] = builtColumns;
32307
- if (extraConfig) {
32308
- table[SQLiteTable.Symbol.ExtraConfigBuilder] = extraConfig;
32309
- }
32310
- return table;
32311
- }
32312
- var sqliteTable = (name, columns, extraConfig) => {
32313
- return sqliteTableBase(name, columns, extraConfig);
32314
- };
32315
-
32316
- // ../../node_modules/.bun/drizzle-orm@0.45.2+29ab9a45addfc34e/node_modules/drizzle-orm/sqlite-core/indexes.js
32317
- class IndexBuilderOn {
32318
- constructor(name, unique2) {
32319
- this.name = name;
32320
- this.unique = unique2;
32321
- }
32322
- static [entityKind] = "SQLiteIndexBuilderOn";
32323
- on(...columns) {
32324
- return new IndexBuilder(this.name, columns, this.unique);
32325
- }
32326
- }
32327
-
32328
- class IndexBuilder {
32329
- static [entityKind] = "SQLiteIndexBuilder";
32330
- config;
32331
- constructor(name, columns, unique2) {
32332
- this.config = {
32333
- name,
32334
- columns,
32335
- unique: unique2,
32336
- where: undefined
32337
- };
32338
- }
32339
- where(condition) {
32340
- this.config.where = condition;
32341
- return this;
32342
- }
32343
- build(table) {
32344
- return new Index(this.config, table);
32345
- }
32346
- }
32347
-
32348
- class Index {
32349
- static [entityKind] = "SQLiteIndex";
32350
- config;
32351
- constructor(config2, table) {
32352
- this.config = { ...config2, table };
32353
- }
32354
- }
32355
- function index(name) {
32356
- return new IndexBuilderOn(name, false);
32357
- }
32358
-
32359
- // ../runtime/src/drizzle-schema.ts
32360
- var deliveriesTable = sqliteTable("deliveries", {
32361
- id: text("id").primaryKey(),
32362
- messageId: text("message_id"),
32363
- invocationId: text("invocation_id"),
32364
- targetId: text("target_id").notNull(),
32365
- targetNodeId: text("target_node_id"),
32366
- targetKind: text("target_kind").$type().notNull(),
32367
- transport: text("transport").$type().notNull(),
32368
- reason: text("reason").$type().notNull(),
32369
- policy: text("policy").$type().notNull(),
32370
- status: text("status").$type().notNull(),
32371
- bindingId: text("binding_id"),
32372
- leaseOwner: text("lease_owner"),
32373
- leaseExpiresAt: integer2("lease_expires_at"),
32374
- metadataJson: text("metadata_json"),
32375
- createdAt: integer2("created_at").notNull().default(sql`(unixepoch())`)
32376
- }, (table) => [
32377
- index("idx_deliveries_status_transport").on(table.status, table.transport)
32378
- ]);
32379
- var deliveryAttemptsTable = sqliteTable("delivery_attempts", {
32380
- id: text("id").primaryKey(),
32381
- deliveryId: text("delivery_id").notNull(),
32382
- attempt: integer2("attempt").notNull(),
32383
- status: text("status").$type().notNull(),
32384
- error: text("error"),
32385
- externalRef: text("external_ref"),
32386
- metadataJson: text("metadata_json"),
32387
- createdAt: integer2("created_at").notNull()
32388
- });
32389
- // ../runtime/src/broker.ts
32390
- function createRuntimeId(prefix) {
32391
- return `${prefix}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
32392
- }
32393
- function toTargetKind(actor) {
32394
- if (!actor)
32395
- return "participant";
32396
- if (actor.kind === "agent")
32397
- return "agent";
32398
- if (actor.kind === "device")
32399
- return "device";
32400
- if (actor.kind === "bridge")
32401
- return "bridge";
32402
- return "participant";
32403
- }
32404
- function defaultTransportForActor(actor) {
32405
- if (!actor)
32406
- return "local_socket";
32407
- switch (actor.kind) {
32408
- case "bridge":
32409
- return "webhook";
32410
- case "device":
32411
- return "local_socket";
32412
- case "agent":
32413
- return "local_socket";
32414
- default:
32415
- return "local_socket";
32416
- }
32417
- }
32418
- function endpointTransportRank(transport) {
32419
- switch (transport) {
32420
- case "codex_app_server":
32421
- return 0;
32422
- case "claude_stream_json":
32423
- return 1;
32424
- case "tmux":
32425
- return 2;
32426
- case "local_socket":
32427
- return 3;
32428
- default:
32429
- return 4;
32430
- }
32431
- }
32432
- function shouldBridgeMessageToBinding(binding, message) {
32433
- if (binding.platform !== "telegram") {
32434
- return true;
32435
- }
32436
- const source = typeof message.metadata?.source === "string" ? String(message.metadata.source) : "";
32437
- if (source === "telegram") {
32438
- return false;
32439
- }
32440
- const outboundMode = typeof binding.metadata?.outboundMode === "string" ? String(binding.metadata.outboundMode) : "operator_only";
32441
- const operatorId = typeof binding.metadata?.operatorId === "string" ? String(binding.metadata.operatorId) : "operator";
32442
- const allowedActorIds = Array.isArray(binding.metadata?.allowedActorIds) ? binding.metadata.allowedActorIds.map((entry) => String(entry).trim()).filter(Boolean) : [];
32443
- if (outboundMode === "all") {
32444
- return true;
32445
- }
32446
- if (outboundMode === "allowlist") {
32447
- return allowedActorIds.includes(message.actorId);
32448
- }
32449
- return message.actorId === operatorId;
32450
- }
32451
- function resolveBindingRoutes(bindings, message) {
32452
- return bindings.filter((binding) => shouldBridgeMessageToBinding(binding, message)).map((binding) => ({
32453
- targetId: binding.id,
32454
- targetKind: "bridge",
32455
- transport: binding.platform === "telegram" ? "telegram" : binding.platform === "discord" ? "discord" : "webhook",
32456
- bindingId: binding.id
32457
- }));
32458
- }
32459
- function preferredEndpoint(endpoints) {
32460
- let preferred;
32461
- let preferredRank = Number.POSITIVE_INFINITY;
32462
- for (const endpoint of endpoints) {
32463
- const rank = endpointTransportRank(endpoint.transport);
32464
- if (!preferred || rank < preferredRank) {
32465
- preferred = endpoint;
32466
- preferredRank = rank;
32467
- }
32468
- }
32469
- return preferred;
32470
- }
32471
-
32472
- class InMemoryControlRuntime {
32473
- registry;
32474
- listeners = new Set;
32475
- eventBuffer = [];
32476
- localNodeId;
32477
- endpointIdsByAgentId = new Map;
32478
- bindingIdsByConversationId = new Map;
32479
- flightIdByInvocationId = new Map;
32480
- constructor(initial = {}, options = {}) {
32481
- this.registry = createRuntimeRegistrySnapshot(initial);
32482
- this.localNodeId = options.localNodeId;
32483
- this.rebuildIndexes();
32484
- }
32485
- snapshot() {
32486
- return createRuntimeRegistrySnapshot({
32487
- nodes: { ...this.registry.nodes },
32488
- actors: { ...this.registry.actors },
32489
- agents: { ...this.registry.agents },
32490
- endpoints: { ...this.registry.endpoints },
32491
- conversations: { ...this.registry.conversations },
32492
- bindings: { ...this.registry.bindings },
32493
- messages: { ...this.registry.messages },
32494
- flights: { ...this.registry.flights },
32495
- collaborationRecords: { ...this.registry.collaborationRecords }
32496
- });
32497
- }
32498
- peek() {
32499
- return this.registry;
32500
- }
32501
- node(nodeId) {
32502
- return this.registry.nodes[nodeId];
32503
- }
32504
- agent(agentId) {
32505
- return this.registry.agents[agentId];
32506
- }
32507
- conversation(conversationId) {
32508
- return this.registry.conversations[conversationId];
32509
- }
32510
- message(messageId) {
32511
- return this.registry.messages[messageId];
32512
- }
32513
- collaborationRecord(recordId) {
32514
- return this.registry.collaborationRecords[recordId];
32515
- }
32516
- flightForInvocation(invocationId) {
32517
- const flightId = this.flightIdByInvocationId.get(invocationId);
32518
- return flightId ? this.registry.flights[flightId] : undefined;
32519
- }
32520
- bindingsForConversation(conversationId) {
32521
- const bindingIds = this.bindingIdsByConversationId.get(conversationId);
32522
- if (!bindingIds) {
32523
- return [];
32524
- }
32525
- const bindings = [];
32526
- for (const bindingId of bindingIds) {
32527
- const binding = this.registry.bindings[bindingId];
32528
- if (binding) {
32529
- bindings.push(binding);
32530
- }
32531
- }
32532
- return bindings;
32533
- }
32534
- endpointsForAgent(agentId, options = {}) {
32535
- const endpointIds = this.endpointIdsByAgentId.get(agentId);
32536
- if (!endpointIds) {
32537
- return [];
32538
- }
32539
- const endpoints = [];
32540
- for (const endpointId of endpointIds) {
32541
- const endpoint = this.registry.endpoints[endpointId];
32542
- if (!endpoint)
32543
- continue;
32544
- if (!options.includeOffline && endpoint.state === "offline")
32545
- continue;
32546
- if (options.nodeId && endpoint.nodeId !== options.nodeId)
32547
- continue;
32548
- if (options.harness && endpoint.harness !== options.harness)
32549
- continue;
32550
- endpoints.push(endpoint);
32551
- }
32552
- return endpoints;
32553
- }
32554
- recentEvents(limit = 100) {
32555
- return this.eventBuffer.slice(-limit);
32556
- }
32557
- subscribe(listener) {
32558
- this.listeners.add(listener);
32559
- return () => {
32560
- this.listeners.delete(listener);
32561
- };
32562
- }
32563
- async dispatch(command) {
32564
- switch (command.kind) {
32565
- case "node.upsert":
32566
- await this.upsertNode(command.node);
32567
- return;
32568
- case "actor.upsert":
32569
- await this.upsertActor(command.actor);
32570
- return;
32571
- case "agent.upsert":
32572
- await this.upsertAgent(command.agent);
32573
- return;
32574
- case "agent.endpoint.upsert":
32575
- await this.upsertEndpoint(command.endpoint);
32576
- return;
32577
- case "conversation.upsert":
32578
- await this.upsertConversation(command.conversation);
32579
- return;
32580
- case "binding.upsert":
32581
- await this.upsertBinding(command.binding);
32582
- return;
32583
- case "collaboration.upsert":
32584
- await this.upsertCollaboration(command.record);
32585
- return;
32586
- case "collaboration.event.append":
32587
- await this.appendCollaborationEvent(command.event);
32588
- return;
32589
- case "conversation.post":
32590
- await this.postMessage(command.message);
32591
- return;
32592
- case "agent.invoke":
32593
- await this.invokeAgent(command.invocation);
32594
- return;
32595
- case "agent.ensure_awake":
32596
- this.emit({
32597
- id: createRuntimeId("evt"),
32598
- kind: "flight.updated",
32599
- ts: Date.now(),
32600
- actorId: command.requesterId,
32601
- nodeId: this.localNodeId,
32602
- payload: {
32603
- flight: {
32604
- id: createRuntimeId("flt"),
32605
- invocationId: command.agentId,
32606
- requesterId: command.requesterId,
32607
- targetAgentId: command.agentId,
32608
- state: "waking",
32609
- summary: command.reason
32610
- }
32611
- }
32612
- });
32613
- return;
32614
- case "stream.subscribe":
32615
- return;
32616
- default: {
32617
- const exhaustive = command;
32618
- return exhaustive;
32619
- }
32620
- }
32621
- }
32622
- async upsertNode(node) {
32623
- this.registry.nodes[node.id] = node;
32624
- this.emit({
32625
- id: createRuntimeId("evt"),
32626
- kind: "node.upserted",
32627
- ts: Date.now(),
32628
- actorId: node.id,
32629
- nodeId: node.id,
32630
- payload: { node }
32631
- });
32632
- }
32633
- async upsertActor(actor) {
32634
- this.registry.actors[actor.id] = {
32635
- id: actor.id,
32636
- kind: actor.kind,
32637
- displayName: actor.displayName,
32638
- handle: actor.handle,
32639
- labels: actor.labels,
32640
- metadata: actor.metadata
32641
- };
32642
- this.emit({
32643
- id: createRuntimeId("evt"),
32644
- kind: "actor.registered",
32645
- ts: Date.now(),
32646
- actorId: actor.id,
32647
- nodeId: this.localNodeId,
32648
- payload: { actor }
32649
- });
32650
- }
32651
- async upsertAgent(agent) {
32652
- if (!this.registry.actors[agent.id]) {
32653
- this.registry.actors[agent.id] = {
32654
- id: agent.id,
32655
- kind: agent.kind,
32656
- displayName: agent.displayName,
32657
- handle: agent.handle,
32658
- labels: agent.labels,
32659
- metadata: agent.metadata
32660
- };
32661
- }
32662
- this.registry.agents[agent.id] = agent;
32663
- this.emit({
32664
- id: createRuntimeId("evt"),
32665
- kind: "agent.registered",
32666
- ts: Date.now(),
32667
- actorId: agent.id,
32668
- nodeId: agent.authorityNodeId,
32669
- payload: { agent }
32670
- });
32671
- }
32672
- async upsertEndpoint(endpoint) {
32673
- const previous = this.registry.endpoints[endpoint.id];
32674
- if (previous) {
32675
- this.unindexEndpoint(previous);
32676
- }
32677
- this.registry.endpoints[endpoint.id] = endpoint;
32678
- this.indexEndpoint(endpoint);
32679
- this.emit({
32680
- id: createRuntimeId("evt"),
32681
- kind: "agent.endpoint.upserted",
32682
- ts: Date.now(),
32683
- actorId: endpoint.agentId,
32684
- nodeId: endpoint.nodeId,
32685
- payload: { endpoint }
32686
- });
32687
- }
32688
- async upsertConversation(conversation) {
32689
- this.registry.conversations[conversation.id] = conversation;
32690
- this.emit({
32691
- id: createRuntimeId("evt"),
32692
- kind: "conversation.upserted",
32693
- ts: Date.now(),
32694
- actorId: "system",
32695
- nodeId: conversation.authorityNodeId,
32696
- payload: { conversation }
32697
- });
32698
- }
32699
- async upsertBinding(binding) {
32700
- const previous = this.registry.bindings[binding.id];
32701
- if (previous) {
32702
- this.unindexBinding(previous);
32703
- }
32704
- this.registry.bindings[binding.id] = binding;
32705
- this.indexBinding(binding);
32706
- this.emit({
32707
- id: createRuntimeId("evt"),
32708
- kind: "binding.upserted",
32709
- ts: Date.now(),
32710
- actorId: "system",
32711
- nodeId: this.localNodeId,
32712
- payload: { binding }
32713
- });
32714
- }
32715
- async upsertCollaboration(record2) {
32716
- assertValidCollaborationRecord(record2);
32717
- this.registry.collaborationRecords[record2.id] = record2;
32718
- this.emit({
32719
- id: createRuntimeId("evt"),
32720
- kind: "collaboration.upserted",
32721
- ts: Date.now(),
32722
- actorId: record2.createdById,
32723
- nodeId: this.localNodeId,
32724
- payload: { record: record2 }
32725
- });
32726
- }
32727
- async appendCollaborationEvent(event) {
32728
- const record2 = this.registry.collaborationRecords[event.recordId];
32729
- if (!record2) {
32730
- throw new Error(`unknown collaboration record: ${event.recordId}`);
32731
- }
32732
- assertValidCollaborationEvent(event, record2);
32733
- this.emit({
32734
- id: createRuntimeId("evt"),
32735
- kind: "collaboration.event.appended",
32736
- ts: Date.now(),
32737
- actorId: event.actorId,
32738
- nodeId: this.localNodeId,
32739
- payload: { event }
32740
- });
32741
- }
32742
- async upsertFlight(flight) {
32743
- const previous = this.registry.flights[flight.id];
32744
- if (previous && this.flightIdByInvocationId.get(previous.invocationId) === previous.id) {
32745
- this.flightIdByInvocationId.delete(previous.invocationId);
32746
- }
32747
- this.registry.flights[flight.id] = flight;
32748
- this.flightIdByInvocationId.set(flight.invocationId, flight.id);
32749
- this.emit({
32750
- id: createRuntimeId("evt"),
32751
- kind: "flight.updated",
32752
- ts: Date.now(),
32753
- actorId: flight.requesterId,
32754
- nodeId: this.localNodeId,
32755
- payload: { flight }
32756
- });
32757
- }
32758
- async postMessage(message, options = {}) {
32759
- const deliveries2 = this.planMessage(message, options);
32760
- await this.commitMessage(message, deliveries2);
32761
- return deliveries2;
32762
- }
32763
- planMessage(message, options = {}) {
32764
- const conversation = this.registry.conversations[message.conversationId];
32765
- if (!conversation) {
32766
- throw new Error(`unknown conversation: ${message.conversationId}`);
32767
- }
32768
- const bindingRoutes = resolveBindingRoutes(this.bindingsForConversation(conversation.id), message);
32769
- const plannedParticipantRoutes = this.resolveParticipantRoutes(conversation.participantIds);
32770
- const participantRoutes = options.localOnly ? plannedParticipantRoutes.filter((route2) => !route2.nodeId || route2.nodeId === this.localNodeId) : plannedParticipantRoutes;
32771
- const deliveries2 = planMessageDeliveries({
32772
- localNodeId: this.localNodeId,
32773
- message,
32774
- conversation,
32775
- participantRoutes,
32776
- bindingRoutes: options.localOnly ? [] : bindingRoutes
32777
- });
32778
- return deliveries2;
32779
- }
32780
- async commitMessage(message, deliveries2) {
32781
- this.registry.messages[message.id] = message;
32782
- this.emit({
32783
- id: createRuntimeId("evt"),
32784
- kind: "message.posted",
32785
- ts: Date.now(),
32786
- actorId: message.actorId,
32787
- nodeId: message.originNodeId,
32788
- payload: { message }
32789
- });
32790
- for (const delivery of deliveries2) {
32791
- this.emit({
32792
- id: createRuntimeId("evt"),
32793
- kind: "delivery.planned",
32794
- ts: Date.now(),
32795
- actorId: message.actorId,
32796
- nodeId: message.originNodeId,
32797
- payload: { delivery }
32798
- });
32799
- }
32800
- }
32801
- async invokeAgent(invocation) {
32802
- const flight = this.planInvocation(invocation);
32803
- await this.commitInvocation(invocation, flight);
32804
- return flight;
32805
- }
32806
- planInvocation(invocation) {
32807
- const targetAgent = this.registry.agents[invocation.targetAgentId];
32808
- if (!targetAgent) {
32809
- throw new Error(`unknown agent: ${invocation.targetAgentId}`);
32810
- }
32811
- const targetEndpoints = this.endpointsForAgent(invocation.targetAgentId, {
32812
- nodeId: targetAgent.authorityNodeId,
32813
- harness: invocation.execution?.harness
32814
- });
32815
- const isLocalAuthority = !this.localNodeId || targetAgent.authorityNodeId === this.localNodeId;
32816
- const startedAt = Date.now();
32817
- let state = invocation.ensureAwake ? "waking" : "queued";
32818
- let summary;
32819
- let error48;
32820
- let completedAt;
32821
- if (isLocalAuthority) {
32822
- if (targetEndpoints.length == 0) {
32823
- state = invocation.ensureAwake ? "waking" : "queued";
32824
- 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.`;
32825
- } else {
32826
- state = "queued";
32827
- summary = `${targetAgent.displayName} queued for local execution.`;
32828
- }
32829
- }
32830
- const flight = {
32831
- id: createRuntimeId("flt"),
32832
- invocationId: invocation.id,
32833
- requesterId: invocation.requesterId,
32834
- targetAgentId: invocation.targetAgentId,
32835
- state,
32836
- summary,
32837
- error: error48,
32838
- startedAt,
32839
- completedAt,
32840
- metadata: invocation.metadata
32841
- };
32842
- return flight;
32843
- }
32844
- async commitInvocation(invocation, flight) {
32845
- const previous = this.registry.flights[flight.id];
32846
- if (previous && this.flightIdByInvocationId.get(previous.invocationId) === previous.id) {
32847
- this.flightIdByInvocationId.delete(previous.invocationId);
32848
- }
32849
- this.registry.flights[flight.id] = flight;
32850
- this.flightIdByInvocationId.set(flight.invocationId, flight.id);
32851
- const targetAgent = this.registry.agents[invocation.targetAgentId];
32852
- this.emit({
32853
- id: createRuntimeId("evt"),
32854
- kind: "invocation.requested",
32855
- ts: Date.now(),
32856
- actorId: invocation.requesterId,
32857
- nodeId: invocation.requesterNodeId,
32858
- payload: { invocation }
32859
- });
32860
- this.emit({
32861
- id: createRuntimeId("evt"),
32862
- kind: "flight.updated",
32863
- ts: Date.now(),
32864
- actorId: invocation.requesterId,
32865
- nodeId: targetAgent?.authorityNodeId,
32866
- payload: { flight }
32867
- });
32868
- }
32869
- rebuildIndexes() {
32870
- for (const endpoint of Object.values(this.registry.endpoints)) {
32871
- this.indexEndpoint(endpoint);
32872
- }
32873
- for (const binding of Object.values(this.registry.bindings)) {
32874
- this.indexBinding(binding);
32875
- }
32876
- for (const flight of Object.values(this.registry.flights)) {
32877
- this.flightIdByInvocationId.set(flight.invocationId, flight.id);
32878
- }
32879
- }
32880
- indexEndpoint(endpoint) {
32881
- this.addIndexedId(this.endpointIdsByAgentId, endpoint.agentId, endpoint.id);
32882
- }
32883
- unindexEndpoint(endpoint) {
32884
- this.removeIndexedId(this.endpointIdsByAgentId, endpoint.agentId, endpoint.id);
32885
- }
32886
- indexBinding(binding) {
32887
- this.addIndexedId(this.bindingIdsByConversationId, binding.conversationId, binding.id);
32888
- }
32889
- unindexBinding(binding) {
32890
- this.removeIndexedId(this.bindingIdsByConversationId, binding.conversationId, binding.id);
32891
- }
32892
- addIndexedId(index2, key, value) {
32893
- const ids = index2.get(key) ?? new Set;
32894
- ids.add(value);
32895
- index2.set(key, ids);
32896
- }
32897
- removeIndexedId(index2, key, value) {
32898
- const ids = index2.get(key);
32899
- if (!ids) {
32900
- return;
32901
- }
32902
- ids.delete(value);
32903
- if (ids.size === 0) {
32904
- index2.delete(key);
32905
- }
32906
- }
32907
- resolveParticipantRoutes(participantIds) {
32908
- const routes = [];
32909
- for (const participantId of participantIds) {
32910
- const actor = this.registry.actors[participantId];
32911
- const agent = this.registry.agents[participantId];
32912
- const targetIdentity = actor ?? agent;
32913
- const endpoints = this.endpointsForAgent(participantId);
32914
- const endpoint = preferredEndpoint(endpoints);
32915
- if (!endpoint) {
32916
- if (agent?.authorityNodeId && agent.authorityNodeId !== this.localNodeId) {
32917
- routes.push({
32918
- targetId: participantId,
32919
- nodeId: agent.authorityNodeId,
32920
- targetKind: toTargetKind(targetIdentity),
32921
- transport: defaultTransportForActor(targetIdentity),
32922
- speechEnabled: false
32923
- });
32924
- } else if (agent) {
32925
- routes.push({
32926
- targetId: participantId,
32927
- nodeId: agent.authorityNodeId ?? this.localNodeId,
32928
- targetKind: toTargetKind(targetIdentity),
32929
- transport: defaultTransportForActor(targetIdentity),
32930
- speechEnabled: false
32931
- });
32932
- }
32933
- continue;
32934
- }
32935
- routes.push({
32936
- targetId: participantId,
32937
- nodeId: endpoint.nodeId ?? agent?.authorityNodeId,
32938
- targetKind: toTargetKind(targetIdentity),
32939
- transport: endpoint.transport ?? defaultTransportForActor(targetIdentity),
32940
- speechEnabled: Boolean(actor?.kind === "device" || endpoints.some((candidate) => candidate.transport === "local_socket" || candidate.transport === "websocket"))
32941
- });
32942
- }
32943
- return routes;
32944
- }
32945
- emit(event) {
32946
- this.eventBuffer.push(event);
32947
- if (this.eventBuffer.length > 500) {
32948
- this.eventBuffer.shift();
32949
- }
32950
- for (const listener of this.listeners) {
32951
- listener(event);
32952
- }
32953
- }
32954
- }
32955
- // ../runtime/src/tailscale.ts
32956
- import { execFile } from "child_process";
32957
- import { promisify } from "util";
32958
- var execFileAsync = promisify(execFile);
32959
- // ../runtime/src/thread-events.ts
32960
- class ThreadWatchProtocolError extends Error {
32961
- status;
32962
- body;
32963
- constructor(status, body) {
32964
- super(body.message);
32965
- this.status = status;
32966
- this.body = body;
32967
- }
32968
- }
32969
- function watchKey(conversationId, watcherNodeId, watcherId) {
32970
- return `${conversationId}:${watcherNodeId}:${watcherId}`;
32971
- }
32972
- function writeSse(response, eventName, payload) {
32973
- response.write(`event: ${eventName}
32974
- data: ${JSON.stringify(payload)}
32975
-
32976
- `);
32977
- }
32978
-
32979
- class ThreadEventPlane {
32980
- options;
32981
- watches = new Map;
32982
- watchIdsByKey = new Map;
32983
- watchIdsByConversation = new Map;
32984
- constructor(options) {
32985
- this.options = options;
32986
- }
32987
- async openWatch(request) {
32988
- const conversation = this.requireConversationAuthority(request.conversationId);
32989
- this.requireRemoteWatchAllowed(conversation);
32990
- const afterSeq = Math.max(0, request.afterSeq ?? 0);
32991
- const oldestSeq = await this.options.projection.oldestThreadSeq(conversation.id);
32992
- const latestSeq = await this.options.projection.latestThreadSeq(conversation.id);
32993
- if (latestSeq > 0 && oldestSeq > 0 && afterSeq < oldestSeq - 1) {
32994
- throw new ThreadWatchProtocolError(409, {
32995
- code: "cursor_out_of_range",
32996
- message: `thread cursor ${afterSeq} is older than retained seq ${oldestSeq}`
32997
- });
32998
- }
32999
- const key = watchKey(conversation.id, request.watcherNodeId, request.watcherId);
33000
- const existingWatchId = this.watchIdsByKey.get(key);
33001
- if (existingWatchId) {
33002
- this.closeWatchInternal(existingWatchId);
33003
- }
33004
- const watchId = `thread-watch:${conversation.id}:${request.watcherNodeId}:${request.watcherId}`;
33005
- const leaseExpiresAt = Date.now() + this.normalizeLeaseMs(request.leaseMs);
33006
- const watch = {
33007
- watchId,
33008
- conversationId: conversation.id,
33009
- watcherNodeId: request.watcherNodeId,
33010
- watcherId: request.watcherId,
33011
- acceptedAfterSeq: afterSeq,
33012
- leaseExpiresAt,
33013
- mode: conversation.shareMode === "summary" ? "summary" : "shared",
33014
- clients: new Set
33015
- };
33016
- this.watches.set(watchId, watch);
33017
- this.watchIdsByKey.set(key, watchId);
33018
- this.indexWatch(watch);
33019
- return {
33020
- watchId,
33021
- conversationId: conversation.id,
33022
- authorityNodeId: conversation.authorityNodeId,
33023
- acceptedAfterSeq: afterSeq,
33024
- latestSeq,
33025
- leaseExpiresAt,
33026
- mode: watch.mode
33027
- };
33028
- }
33029
- async renewWatch(request) {
33030
- const watch = this.requireLiveWatch(request.watchId);
33031
- watch.leaseExpiresAt = Date.now() + this.normalizeLeaseMs(request.leaseMs);
33032
- return {
33033
- watchId: watch.watchId,
33034
- leaseExpiresAt: watch.leaseExpiresAt
33035
- };
33036
- }
33037
- async closeWatch(request) {
33038
- this.closeWatchInternal(request.watchId);
33039
- }
33040
- async replay(options) {
33041
- const conversation = this.requireConversationAuthority(options.conversationId);
33042
- this.requireRemoteWatchAllowed(conversation);
33043
- const oldestSeq = await this.options.projection.oldestThreadSeq(conversation.id);
33044
- const latestSeq = await this.options.projection.latestThreadSeq(conversation.id);
33045
- if (latestSeq > 0 && oldestSeq > 0 && options.afterSeq < oldestSeq - 1) {
33046
- throw new ThreadWatchProtocolError(409, {
33047
- code: "cursor_out_of_range",
33048
- message: `thread cursor ${options.afterSeq} is older than retained seq ${oldestSeq}`
33049
- });
33050
- }
33051
- return this.options.projection.listThreadEvents({
33052
- conversationId: conversation.id,
33053
- afterSeq: options.afterSeq,
33054
- limit: Math.min(options.limit ?? 500, this.options.maxReplayLimit ?? 2000)
33055
- });
33056
- }
33057
- async snapshot(conversationId) {
33058
- const conversation = this.requireConversationAuthority(conversationId);
33059
- this.requireRemoteWatchAllowed(conversation);
33060
- const snapshot = await this.options.projection.getThreadSnapshot(conversation.id);
33061
- if (!snapshot) {
33062
- throw new ThreadWatchProtocolError(404, {
33063
- code: "unknown_conversation",
33064
- message: `unknown conversation ${conversation.id}`
33065
- });
33066
- }
33067
- return snapshot;
33068
- }
33069
- async streamWatch(watchId, request, response) {
33070
- const watch = this.requireLiveWatch(watchId);
33071
- const backlog = await this.options.projection.listThreadEvents({
33072
- conversationId: watch.conversationId,
33073
- afterSeq: watch.acceptedAfterSeq,
33074
- limit: this.options.maxReplayLimit ?? 2000
33075
- });
33076
- response.writeHead(200, {
33077
- "content-type": "text/event-stream",
33078
- "cache-control": "no-cache, no-transform",
33079
- connection: "keep-alive"
33080
- });
33081
- writeSse(response, "hello", {
33082
- watchId: watch.watchId,
33083
- conversationId: watch.conversationId,
33084
- leaseExpiresAt: watch.leaseExpiresAt
33085
- });
33086
- for (const event of backlog) {
33087
- writeSse(response, "thread.event", event);
33088
- }
33089
- watch.clients.add(response);
33090
- request.on("close", () => {
33091
- watch.clients.delete(response);
33092
- response.end();
33093
- });
33094
- }
33095
- publish(events2) {
33096
- for (const event of events2) {
33097
- const watchIds = this.watchIdsByConversation.get(event.conversationId);
33098
- if (!watchIds || watchIds.size === 0) {
33099
- continue;
33100
- }
33101
- for (const watchId of [...watchIds]) {
33102
- const watch = this.watches.get(watchId);
33103
- if (!watch) {
33104
- watchIds.delete(watchId);
33105
- continue;
33106
- }
33107
- if (watch.leaseExpiresAt <= Date.now()) {
33108
- this.closeWatchInternal(watchId);
33109
- continue;
33110
- }
33111
- for (const client of watch.clients) {
33112
- writeSse(client, "thread.event", event);
33113
- }
33114
- }
33115
- }
33116
- }
33117
- normalizeLeaseMs(requestedLeaseMs) {
33118
- const defaultLeaseMs = this.options.defaultLeaseMs ?? 30000;
33119
- const maxLeaseMs = this.options.maxLeaseMs ?? 300000;
33120
- if (!requestedLeaseMs || !Number.isFinite(requestedLeaseMs) || requestedLeaseMs <= 0) {
33121
- return defaultLeaseMs;
33122
- }
33123
- return Math.min(Math.max(requestedLeaseMs, 5000), maxLeaseMs);
33124
- }
33125
- requireConversationAuthority(conversationId) {
33126
- const conversation = this.options.runtime.conversation(conversationId);
33127
- if (!conversation) {
33128
- throw new ThreadWatchProtocolError(404, {
33129
- code: "unknown_conversation",
33130
- message: `unknown conversation ${conversationId}`
33131
- });
33132
- }
33133
- if (conversation.authorityNodeId !== this.options.nodeId) {
33134
- throw new ThreadWatchProtocolError(409, {
33135
- code: "no_responder",
33136
- message: `conversation ${conversationId} is owned by ${conversation.authorityNodeId}`
33137
- });
33138
- }
33139
- return conversation;
33140
- }
33141
- requireRemoteWatchAllowed(conversation) {
33142
- if (conversation.shareMode === "local") {
33143
- throw new ThreadWatchProtocolError(403, {
33144
- code: "forbidden",
33145
- message: `conversation ${conversation.id} does not allow remote watches`
33146
- });
33147
- }
33148
- }
33149
- requireLiveWatch(watchId) {
33150
- const watch = this.watches.get(watchId);
33151
- if (!watch) {
33152
- throw new ThreadWatchProtocolError(404, {
33153
- code: "invalid_request",
33154
- message: `unknown watch ${watchId}`
33155
- });
33156
- }
33157
- if (watch.leaseExpiresAt <= Date.now()) {
33158
- this.closeWatchInternal(watchId);
33159
- throw new ThreadWatchProtocolError(410, {
33160
- code: "lease_expired",
33161
- message: `watch ${watchId} lease expired`
33162
- });
33163
- }
33164
- return watch;
33165
- }
33166
- indexWatch(watch) {
33167
- const ids = this.watchIdsByConversation.get(watch.conversationId) ?? new Set;
33168
- ids.add(watch.watchId);
33169
- this.watchIdsByConversation.set(watch.conversationId, ids);
33170
- }
33171
- closeWatchInternal(watchId) {
33172
- const watch = this.watches.get(watchId);
33173
- if (!watch) {
33174
- return;
33175
- }
33176
- this.watches.delete(watchId);
33177
- this.watchIdsByKey.delete(watchKey(watch.conversationId, watch.watcherNodeId, watch.watcherId));
33178
- const ids = this.watchIdsByConversation.get(watch.conversationId);
33179
- if (ids) {
33180
- ids.delete(watchId);
33181
- if (ids.size === 0) {
33182
- this.watchIdsByConversation.delete(watch.conversationId);
33183
- }
33184
- }
33185
- for (const client of watch.clients) {
33186
- client.end();
33187
- }
33188
- watch.clients.clear();
33189
- }
33190
- }
33191
31827
  // ../runtime/src/mobile-push.ts
33192
31828
  import { Database as Database2 } from "bun:sqlite";
33193
31829
  import { mkdirSync as mkdirSync9, readFileSync as readFileSync10 } from "fs";
@@ -33560,6 +32196,7 @@ async function broadcastApnsAlertToActiveMobileDevices(alert) {
33560
32196
  failures
33561
32197
  };
33562
32198
  }
32199
+
33563
32200
  // ../../apps/desktop/src/core/pairing/runtime/bridge/router.ts
33564
32201
  import { readFileSync as readFileSync11, readdirSync as readdirSync4, realpathSync as realpathSync2, statSync as statSync4 } from "fs";
33565
32202
  import { execSync as execSync4 } from "child_process";
@@ -33796,8 +32433,8 @@ function getEventSessionId(event) {
33796
32433
  function trackedSequencedEventId(event) {
33797
32434
  return `${getEventSessionId(event) ?? "unknown"}:${event.seq}`;
33798
32435
  }
33799
- function approvalInboxItemId(sessionId, turnId, blockId, version3) {
33800
- return `approval:${sessionId}:${turnId}:${blockId}:v${version3}`;
32436
+ function approvalInboxItemId(sessionId, turnId, blockId, version2) {
32437
+ return `approval:${sessionId}:${turnId}:${blockId}:v${version2}`;
33801
32438
  }
33802
32439
  function projectApprovalInboxItem(snapshot, turn, block) {
33803
32440
  const normalized = normalizeApprovalRequest(snapshot.session, turn.id, block);
@@ -34044,6 +32681,64 @@ var mobileRouter = t.router({
34044
32681
  limit: typeof input.limit === "number" ? input.limit : null
34045
32682
  }, resolveMobileCurrentDirectory2());
34046
32683
  }),
32684
+ webHandoff: procedure.input(exports_external.object({
32685
+ kind: exports_external.enum(["session", "file_change"]),
32686
+ sessionId: exports_external.string(),
32687
+ turnId: exports_external.string().optional(),
32688
+ blockId: exports_external.string().optional()
32689
+ })).mutation(({ input, ctx }) => {
32690
+ if (!ctx.deviceId) {
32691
+ throw new TRPCError({
32692
+ code: "UNAUTHORIZED",
32693
+ message: "Secure web handoff requires a paired mobile device"
32694
+ });
32695
+ }
32696
+ const snapshot = ctx.bridge.getSessionSnapshot(input.sessionId);
32697
+ if (!snapshot) {
32698
+ throw new TRPCError({
32699
+ code: "NOT_FOUND",
32700
+ message: `No session: ${input.sessionId}`
32701
+ });
32702
+ }
32703
+ let scope;
32704
+ let title = snapshot.session.name || snapshot.session.id;
32705
+ if (input.kind === "file_change") {
32706
+ if (!input.turnId || !input.blockId) {
32707
+ throw new TRPCError({
32708
+ code: "BAD_REQUEST",
32709
+ message: "turnId and blockId are required for file_change handoffs"
32710
+ });
32711
+ }
32712
+ const turn = snapshot.turns.find((candidate) => candidate.id === input.turnId);
32713
+ const block = turn?.blocks.find((candidate) => candidate.block.id === input.blockId)?.block;
32714
+ if (!turn || !block || block.type !== "action" || block.action.kind !== "file_change") {
32715
+ throw new TRPCError({
32716
+ code: "NOT_FOUND",
32717
+ message: "File change block not found"
32718
+ });
32719
+ }
32720
+ scope = {
32721
+ kind: "file_change",
32722
+ sessionId: input.sessionId,
32723
+ turnId: input.turnId,
32724
+ blockId: input.blockId
32725
+ };
32726
+ title = block.action.path || title;
32727
+ } else {
32728
+ scope = {
32729
+ kind: "session",
32730
+ sessionId: input.sessionId
32731
+ };
32732
+ }
32733
+ const issued = issueWebHandoff(scope, ctx.deviceId);
32734
+ return {
32735
+ kind: input.kind,
32736
+ path: pathForWebHandoffScope(scope),
32737
+ token: issued.token,
32738
+ expiresAt: issued.expiresAt,
32739
+ title
32740
+ };
32741
+ }),
34047
32742
  createSession: procedure.input(exports_external.object({
34048
32743
  workspaceId: exports_external.string(),
34049
32744
  harness: exports_external.string().optional(),
@@ -34257,15 +32952,42 @@ function readSyncStatus2(bridge, sessionId) {
34257
32952
  oldestBufferedSeq: bridge.oldestBufferedSeq(sessionId)
34258
32953
  };
34259
32954
  }
32955
+ function resolveSyncSessionId2(bridge, preferredSessionId) {
32956
+ if (preferredSessionId) {
32957
+ return preferredSessionId;
32958
+ }
32959
+ let latestSessionId = null;
32960
+ let latestActivityAt = Number.NEGATIVE_INFINITY;
32961
+ for (const session of bridge.getSessionSummaries()) {
32962
+ if (session.lastActivityAt > latestActivityAt) {
32963
+ latestActivityAt = session.lastActivityAt;
32964
+ latestSessionId = session.sessionId;
32965
+ }
32966
+ }
32967
+ return latestSessionId;
32968
+ }
34260
32969
  var syncRouter = t.router({
34261
- replay: procedure.input(exports_external.object({ lastSeq: exports_external.number(), sessionId: exports_external.string() })).query(({ input, ctx }) => {
34262
- const events2 = replaySyncEvents2(ctx.bridge, input.sessionId, input.lastSeq);
32970
+ replay: procedure.input(exports_external.object({ lastSeq: exports_external.number(), sessionId: exports_external.string().optional() })).query(({ input, ctx }) => {
32971
+ const sessionId = resolveSyncSessionId2(ctx.bridge, input.sessionId);
32972
+ if (!sessionId) {
32973
+ return { events: [] };
32974
+ }
32975
+ const events2 = replaySyncEvents2(ctx.bridge, sessionId, input.lastSeq);
34263
32976
  return { events: events2 };
34264
32977
  }),
34265
- status: procedure.input(exports_external.object({ sessionId: exports_external.string() })).query(({ input, ctx }) => {
32978
+ status: procedure.input(exports_external.object({ sessionId: exports_external.string().optional() }).optional()).query(({ input, ctx }) => {
32979
+ const sessionCount = ctx.bridge.listSessions().length;
32980
+ const sessionId = resolveSyncSessionId2(ctx.bridge, input?.sessionId);
32981
+ if (!sessionId) {
32982
+ return {
32983
+ currentSeq: 0,
32984
+ oldestBufferedSeq: 0,
32985
+ sessionCount
32986
+ };
32987
+ }
34266
32988
  return {
34267
- ...readSyncStatus2(ctx.bridge, input.sessionId),
34268
- sessionCount: ctx.bridge.listSessions().length
32989
+ ...readSyncStatus2(ctx.bridge, sessionId),
32990
+ sessionCount
34269
32991
  };
34270
32992
  })
34271
32993
  });
@@ -34766,13 +33488,13 @@ function asStringPayload(raw) {
34766
33488
  // ../../node_modules/.bun/hono@4.12.10/node_modules/hono/dist/compose.js
34767
33489
  var compose = (middleware, onError, onNotFound) => {
34768
33490
  return (context, next) => {
34769
- let index2 = -1;
33491
+ let index = -1;
34770
33492
  return dispatch(0);
34771
33493
  async function dispatch(i) {
34772
- if (i <= index2) {
33494
+ if (i <= index) {
34773
33495
  throw new Error("next() called multiple times");
34774
33496
  }
34775
- index2 = i;
33497
+ index = i;
34776
33498
  let res;
34777
33499
  let isError = false;
34778
33500
  let handler;
@@ -34869,8 +33591,8 @@ var handleParsingNestedValues = (form, key, value) => {
34869
33591
  }
34870
33592
  let nestedForm = form;
34871
33593
  const keys = key.split(".");
34872
- keys.forEach((key2, index2) => {
34873
- if (index2 === keys.length - 1) {
33594
+ keys.forEach((key2, index) => {
33595
+ if (index === keys.length - 1) {
34874
33596
  nestedForm[key2] = value;
34875
33597
  } else {
34876
33598
  if (!nestedForm[key2] || typeof nestedForm[key2] !== "object" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) {
@@ -34896,8 +33618,8 @@ var splitRoutingPath = (routePath) => {
34896
33618
  };
34897
33619
  var extractGroupsFromPath = (path2) => {
34898
33620
  const groups = [];
34899
- path2 = path2.replace(/\{[^}]+\}/g, (match, index2) => {
34900
- const mark = `@${index2}`;
33621
+ path2 = path2.replace(/\{[^}]+\}/g, (match, index) => {
33622
+ const mark = `@${index}`;
34901
33623
  groups.push([mark, match]);
34902
33624
  return mark;
34903
33625
  });
@@ -35155,7 +33877,7 @@ var HonoRequest = class {
35155
33877
  return bodyCache[key] = raw[key]();
35156
33878
  };
35157
33879
  json() {
35158
- return this.#cachedBody("text").then((text2) => JSON.parse(text2));
33880
+ return this.#cachedBody("text").then((text) => JSON.parse(text));
35159
33881
  }
35160
33882
  text() {
35161
33883
  return this.#cachedBody("text");
@@ -35376,8 +34098,8 @@ var Context = class {
35376
34098
  }
35377
34099
  newResponse = (...args) => this.#newResponse(...args);
35378
34100
  body = (data, arg, headers) => this.#newResponse(data, arg, headers);
35379
- text = (text2, arg, headers) => {
35380
- return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text2) : this.#newResponse(text2, arg, setDefaultContentType(TEXT_PLAIN, headers));
34101
+ text = (text, arg, headers) => {
34102
+ return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(text, arg, setDefaultContentType(TEXT_PLAIN, headers));
35381
34103
  };
35382
34104
  json = (object2, arg, headers) => {
35383
34105
  return this.#newResponse(JSON.stringify(object2), arg, setDefaultContentType("application/json", headers));
@@ -35641,8 +34363,8 @@ function match(method, path2) {
35641
34363
  if (!match3) {
35642
34364
  return [[], emptyParam];
35643
34365
  }
35644
- const index2 = match3.indexOf("", 1);
35645
- return [matcher[1][index2], match3];
34366
+ const index = match3.indexOf("", 1);
34367
+ return [matcher[1][index], match3];
35646
34368
  };
35647
34369
  this.match = match2;
35648
34370
  return match2(method, path2);
@@ -35677,7 +34399,7 @@ var Node = class _Node {
35677
34399
  #index;
35678
34400
  #varIndex;
35679
34401
  #children = /* @__PURE__ */ Object.create(null);
35680
- insert(tokens, index2, paramMap, context, pathErrorCheckOnly) {
34402
+ insert(tokens, index, paramMap, context, pathErrorCheckOnly) {
35681
34403
  if (tokens.length === 0) {
35682
34404
  if (this.#index !== undefined) {
35683
34405
  throw PATH_ERROR;
@@ -35685,7 +34407,7 @@ var Node = class _Node {
35685
34407
  if (pathErrorCheckOnly) {
35686
34408
  return;
35687
34409
  }
35688
- this.#index = index2;
34410
+ this.#index = index;
35689
34411
  return;
35690
34412
  }
35691
34413
  const [token, ...restTokens] = tokens;
@@ -35731,7 +34453,7 @@ var Node = class _Node {
35731
34453
  node = this.#children[token] = new _Node;
35732
34454
  }
35733
34455
  }
35734
- node.insert(restTokens, index2, paramMap, context, pathErrorCheckOnly);
34456
+ node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);
35735
34457
  }
35736
34458
  buildRegExpStr() {
35737
34459
  const childKeys = Object.keys(this.#children).sort(compareKey);
@@ -35756,7 +34478,7 @@ var Node = class _Node {
35756
34478
  var Trie = class {
35757
34479
  #context = { varIndex: 0 };
35758
34480
  #root = new Node;
35759
- insert(path2, index2, pathErrorCheckOnly) {
34481
+ insert(path2, index, pathErrorCheckOnly) {
35760
34482
  const paramAssoc = [];
35761
34483
  const groups = [];
35762
34484
  for (let i = 0;; ) {
@@ -35782,7 +34504,7 @@ var Trie = class {
35782
34504
  }
35783
34505
  }
35784
34506
  }
35785
- this.#root.insert(tokens, index2, paramAssoc, this.#context, pathErrorCheckOnly);
34507
+ this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);
35786
34508
  return paramAssoc;
35787
34509
  }
35788
34510
  buildRegExp() {
@@ -35992,11 +34714,11 @@ var PreparedRegExpRouter = class {
35992
34714
  if (!map2) {
35993
34715
  matcher[2][path2][0].push([handler, {}]);
35994
34716
  } else {
35995
- indexes.forEach((index2) => {
35996
- if (typeof index2 === "number") {
35997
- matcher[1][index2].push([handler, map2]);
34717
+ indexes.forEach((index) => {
34718
+ if (typeof index === "number") {
34719
+ matcher[1][index].push([handler, map2]);
35998
34720
  } else {
35999
- matcher[2][index2 || path2][0].push([handler, map2]);
34721
+ matcher[2][index || path2][0].push([handler, map2]);
36000
34722
  }
36001
34723
  });
36002
34724
  }
@@ -36475,22 +35197,22 @@ var jsonContentTypeHandler = {
36475
35197
  message: '"input" needs to be an object when doing a batch call'
36476
35198
  });
36477
35199
  const acc = emptyObject();
36478
- for (const index2 of paths.keys()) {
36479
- const input = inputs[index2];
35200
+ for (const index of paths.keys()) {
35201
+ const input = inputs[index];
36480
35202
  if (input !== undefined)
36481
- acc[index2] = opts.router._def._config.transformer.input.deserialize(input);
35203
+ acc[index] = opts.router._def._config.transformer.input.deserialize(input);
36482
35204
  }
36483
35205
  return acc;
36484
35206
  });
36485
- const calls = await Promise.all(paths.map(async (path2, index2) => {
35207
+ const calls = await Promise.all(paths.map(async (path2, index) => {
36486
35208
  const procedure2 = await getProcedureAtPath(opts.router, path2);
36487
35209
  return {
36488
- batchIndex: index2,
35210
+ batchIndex: index,
36489
35211
  path: path2,
36490
35212
  procedure: procedure2,
36491
35213
  getRawInput: async () => {
36492
35214
  const inputs = await getInputs.read();
36493
- let input = inputs[index2];
35215
+ let input = inputs[index];
36494
35216
  if ((procedure2 === null || procedure2 === undefined ? undefined : procedure2._def.type) === "subscription") {
36495
35217
  var _ref2, _opts$headers$get;
36496
35218
  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");
@@ -36506,7 +35228,7 @@ var jsonContentTypeHandler = {
36506
35228
  },
36507
35229
  result: () => {
36508
35230
  var _getInputs$result;
36509
- return (_getInputs$result = getInputs.result()) === null || _getInputs$result === undefined ? undefined : _getInputs$result[index2];
35231
+ return (_getInputs$result = getInputs.result()) === null || _getInputs$result === undefined ? undefined : _getInputs$result[index];
36510
35232
  }
36511
35233
  };
36512
35234
  }));
@@ -36794,13 +35516,13 @@ function withResolvers() {
36794
35516
  function listWithMember(arr, member) {
36795
35517
  return [...arr, member];
36796
35518
  }
36797
- function listWithoutIndex(arr, index2) {
36798
- return [...arr.slice(0, index2), ...arr.slice(index2 + 1)];
35519
+ function listWithoutIndex(arr, index) {
35520
+ return [...arr.slice(0, index), ...arr.slice(index + 1)];
36799
35521
  }
36800
35522
  function listWithoutMember(arr, member) {
36801
- const index2 = arr.indexOf(member);
36802
- if (index2 !== -1)
36803
- return listWithoutIndex(arr, index2);
35523
+ const index = arr.indexOf(member);
35524
+ if (index !== -1)
35525
+ return listWithoutIndex(arr, index);
36804
35526
  return arr;
36805
35527
  }
36806
35528
  var _Symbol;
@@ -38013,9 +36735,9 @@ async function resolveResponse(opts) {
38013
36735
  });
38014
36736
  const stream = jsonlStreamProducer((0, import_objectSpread24.default)((0, import_objectSpread24.default)({}, config2.jsonl), {}, {
38015
36737
  maxDepth: Infinity,
38016
- data: rpcCalls.map(async (res, index2) => {
36738
+ data: rpcCalls.map(async (res, index) => {
38017
36739
  const [error48, result] = await res;
38018
- const call = info.calls[index2];
36740
+ const call = info.calls[index];
38019
36741
  if (error48) {
38020
36742
  var _procedure$_def$type, _procedure;
38021
36743
  return { error: getErrorShape({
@@ -38077,8 +36799,8 @@ async function resolveResponse(opts) {
38077
36799
  }), undefined];
38078
36800
  return res;
38079
36801
  });
38080
- const resultAsRPCResponse = results.map(([error48, result], index2) => {
38081
- const call = info.calls[index2];
36802
+ const resultAsRPCResponse = results.map(([error48, result], index) => {
36803
+ const call = info.calls[index];
38082
36804
  if (error48) {
38083
36805
  var _call$procedure$_def$4, _call$procedure5;
38084
36806
  return { error: getErrorShape({
@@ -38183,7 +36905,7 @@ async function fetchRequestHandler(opts) {
38183
36905
 
38184
36906
  // ../../node_modules/.bun/hono@4.12.10/node_modules/hono/dist/helper/route/index.js
38185
36907
  var matchedRoutes = (c) => c.req[GET_MATCH_RESULT][0].map(([[, route2]]) => route2);
38186
- var routePath = (c, index2) => matchedRoutes(c).at(index2 ?? c.req.routeIndex)?.path ?? "";
36908
+ var routePath = (c, index) => matchedRoutes(c).at(index ?? c.req.routeIndex)?.path ?? "";
38187
36909
 
38188
36910
  // ../../node_modules/.bun/@hono+trpc-server@0.4.2+2b2485a92adeb0d0/node_modules/@hono/trpc-server/dist/index.js
38189
36911
  var trpcServer = ({ endpoint, createContext, ...rest }) => {
@@ -38346,14 +37068,14 @@ function startBridgeServerTRPC(options) {
38346
37068
  }
38347
37069
  };
38348
37070
  }
38349
- async function handleTRPCMessage(ws, state, text2) {
37071
+ async function handleTRPCMessage(ws, state, text) {
38350
37072
  const send = createSender(ws, state);
38351
37073
  if (!bridgeRouter) {
38352
- await handleLegacyFallback(ws, state, text2);
37074
+ await handleLegacyFallback(ws, state, text);
38353
37075
  return;
38354
37076
  }
38355
37077
  try {
38356
- const msgJSON = JSON.parse(text2);
37078
+ const msgJSON = JSON.parse(text);
38357
37079
  const msgs = Array.isArray(msgJSON) ? msgJSON : [msgJSON];
38358
37080
  for (const raw2 of msgs) {
38359
37081
  log.info("rpc:req", `\u2192 ${raw2.params?.path ?? raw2.method ?? "?"}`);
@@ -38542,7 +37264,7 @@ function startBridgeServerTRPC(options) {
38542
37264
  });
38543
37265
  }
38544
37266
  }
38545
- async function handleLegacyFallback(ws, state, text2) {
37267
+ async function handleLegacyFallback(ws, state, text) {
38546
37268
  const sendRaw = (json2) => {
38547
37269
  if (state.transport) {
38548
37270
  state.transport.send(json2);
@@ -38552,7 +37274,7 @@ function startBridgeServerTRPC(options) {
38552
37274
  };
38553
37275
  let req;
38554
37276
  try {
38555
- req = JSON.parse(text2);
37277
+ req = JSON.parse(text);
38556
37278
  } catch {
38557
37279
  sendRaw(JSON.stringify({ id: null, error: { code: -32700, message: "Parse error" } }));
38558
37280
  return;
@@ -38666,8 +37388,8 @@ function startBridgeServerTRPC(options) {
38666
37388
  const data = typeof raw2 === "string" ? raw2 : new Uint8Array(raw2);
38667
37389
  state.transport.receive(data);
38668
37390
  } else {
38669
- const text2 = typeof raw2 === "string" ? raw2 : new TextDecoder().decode(raw2);
38670
- handleTRPCMessage(ws, state, text2);
37391
+ const text = typeof raw2 === "string" ? raw2 : new TextDecoder().decode(raw2);
37392
+ handleTRPCMessage(ws, state, text);
38671
37393
  }
38672
37394
  },
38673
37395
  close(ws) {
@@ -38767,7 +37489,7 @@ async function startPairingRuntime(options) {
38767
37489
  secure: config2.secure,
38768
37490
  identity: config2.secure ? identity2 : undefined
38769
37491
  });
38770
- const fileServer = startFileServer({ port: config2.port + 2 });
37492
+ const fileServer = startFileServer({ port: config2.port + 2, bridge });
38771
37493
  const relayUrl = options?.relayUrl?.trim() || config2.relay || null;
38772
37494
  if (!relayUrl) {
38773
37495
  fileServer.stop();