@hyperdrive.bot/paseo-server 0.3.10 → 0.3.12

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.
Files changed (90) hide show
  1. package/dist/server/server/agent/agent-loading.js +24 -3
  2. package/dist/server/server/agent/agent-manager.d.ts +22 -0
  3. package/dist/server/server/agent/agent-manager.js +36 -0
  4. package/dist/server/server/agent/agent-storage.d.ts +9 -0
  5. package/dist/server/server/agent/blocker-log.d.ts +81 -0
  6. package/dist/server/server/agent/blocker-log.js +113 -0
  7. package/dist/server/server/agent/card-move-log.d.ts +66 -0
  8. package/dist/server/server/agent/card-move-log.js +113 -0
  9. package/dist/server/server/agent/jarvis-judge.d.ts +121 -0
  10. package/dist/server/server/agent/jarvis-judge.js +225 -0
  11. package/dist/server/server/agent/judge-relay-gate.d.ts +70 -0
  12. package/dist/server/server/agent/judge-relay-gate.js +92 -0
  13. package/dist/server/server/agent/mcp-server.js +9 -0
  14. package/dist/server/server/agent/mcp-shared.d.ts +5 -0
  15. package/dist/server/server/agent/providers/claude/transport/pty-query.d.ts +92 -10
  16. package/dist/server/server/agent/providers/claude/transport/pty-query.js +615 -38
  17. package/dist/server/server/agent/session-digest-generator.d.ts +27 -0
  18. package/dist/server/server/agent/session-digest-generator.js +208 -17
  19. package/dist/server/server/agent/tools/paseo-tools.d.ts +12 -0
  20. package/dist/server/server/agent/tools/paseo-tools.js +48 -0
  21. package/dist/server/server/agent/tools/read-only-surface.d.ts +52 -0
  22. package/dist/server/server/agent/tools/read-only-surface.js +68 -0
  23. package/dist/server/server/agent/tools/types.d.ts +5 -0
  24. package/dist/server/server/bootstrap.js +73 -0
  25. package/dist/server/server/relay-transport.js +36 -5
  26. package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-bridge-9f03d060da06e8838a4e0fdd5c067757.js → desktop-attachment-bridge-e6e0f92f1a2959279a7c3b2b50bf1df3.js} +5 -5
  27. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-e6e0f92f1a2959279a7c3b2b50bf1df3.js.br +0 -0
  28. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-e6e0f92f1a2959279a7c3b2b50bf1df3.js.gz +0 -0
  29. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-e6e0f92f1a2959279a7c3b2b50bf1df3.js.map.br +0 -0
  30. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-e6e0f92f1a2959279a7c3b2b50bf1df3.js.map.gz +0 -0
  31. package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-store-d0d9dffa612bf12bf551c5e513c28691.js → desktop-attachment-store-d5c93939344c993e52d655ccf8942928.js} +3 -3
  32. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d5c93939344c993e52d655ccf8942928.js.br +0 -0
  33. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d5c93939344c993e52d655ccf8942928.js.gz +0 -0
  34. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d5c93939344c993e52d655ccf8942928.js.map.br +0 -0
  35. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d5c93939344c993e52d655ccf8942928.js.map.gz +0 -0
  36. package/dist/server/web-ui/_expo/static/js/web/{index-461cf3ab1d54d6debea0e037829768e9.js → index-853ef1a7fc9c9b7a39577b79564e0896.js} +166 -165
  37. package/dist/server/web-ui/_expo/static/js/web/index-853ef1a7fc9c9b7a39577b79564e0896.js.br +0 -0
  38. package/dist/server/web-ui/_expo/static/js/web/index-853ef1a7fc9c9b7a39577b79564e0896.js.gz +0 -0
  39. package/dist/server/web-ui/_expo/static/js/web/index-853ef1a7fc9c9b7a39577b79564e0896.js.map.br +0 -0
  40. package/dist/server/web-ui/_expo/static/js/web/{index-461cf3ab1d54d6debea0e037829768e9.js.map.gz → index-853ef1a7fc9c9b7a39577b79564e0896.js.map.gz} +0 -0
  41. package/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-54584275ea7a32061741c119074ff13f.js → indexeddb-attachment-store-35fb4ddfe925b1fb6b7a6c1953b21621.js} +3 -3
  42. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-35fb4ddfe925b1fb6b7a6c1953b21621.js.br +0 -0
  43. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-35fb4ddfe925b1fb6b7a6c1953b21621.js.gz +0 -0
  44. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-35fb4ddfe925b1fb6b7a6c1953b21621.js.map.br +0 -0
  45. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-35fb4ddfe925b1fb6b7a6c1953b21621.js.map.gz +0 -0
  46. package/dist/server/web-ui/_expo/static/js/web/{native-file-attachment-store-b53f2ba81a9777f6f6d04a98b0a12c33.js → native-file-attachment-store-8602ccac919e2b56f2e9a252dd06483e.js} +5 -5
  47. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-8602ccac919e2b56f2e9a252dd06483e.js.br +0 -0
  48. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-8602ccac919e2b56f2e9a252dd06483e.js.gz +0 -0
  49. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-8602ccac919e2b56f2e9a252dd06483e.js.map.br +0 -0
  50. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-8602ccac919e2b56f2e9a252dd06483e.js.map.gz +0 -0
  51. package/dist/server/web-ui/_expo/static/js/web/{profiler-7b2011c26cedb58cc00c02a7c25fc0a0.js → profiler-b3dd30ba0a88aece50e7e403785f34ba.js} +11 -11
  52. package/dist/server/web-ui/_expo/static/js/web/profiler-b3dd30ba0a88aece50e7e403785f34ba.js.br +0 -0
  53. package/dist/server/web-ui/_expo/static/js/web/profiler-b3dd30ba0a88aece50e7e403785f34ba.js.gz +0 -0
  54. package/dist/server/web-ui/_expo/static/js/web/profiler-b3dd30ba0a88aece50e7e403785f34ba.js.map.br +0 -0
  55. package/dist/server/web-ui/_expo/static/js/web/profiler-b3dd30ba0a88aece50e7e403785f34ba.js.map.gz +0 -0
  56. package/dist/server/web-ui/_expo/static/js/web/{startRecording-1b57837c4c358ef963a1392d9d96354b.js → startRecording-fd9fa11e24a3b8d94e5161aae7f42a5d.js} +60 -60
  57. package/dist/server/web-ui/_expo/static/js/web/startRecording-fd9fa11e24a3b8d94e5161aae7f42a5d.js.br +0 -0
  58. package/dist/server/web-ui/_expo/static/js/web/startRecording-fd9fa11e24a3b8d94e5161aae7f42a5d.js.gz +0 -0
  59. package/dist/server/web-ui/_expo/static/js/web/startRecording-fd9fa11e24a3b8d94e5161aae7f42a5d.js.map.br +0 -0
  60. package/dist/server/web-ui/_expo/static/js/web/{startRecording-1b57837c4c358ef963a1392d9d96354b.js.map.gz → startRecording-fd9fa11e24a3b8d94e5161aae7f42a5d.js.map.gz} +0 -0
  61. package/dist/server/web-ui/index.html +1 -1
  62. package/dist/server/web-ui/index.html.br +0 -0
  63. package/dist/server/web-ui/index.html.gz +0 -0
  64. package/package.json +6 -6
  65. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-9f03d060da06e8838a4e0fdd5c067757.js.br +0 -0
  66. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-9f03d060da06e8838a4e0fdd5c067757.js.gz +0 -0
  67. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-9f03d060da06e8838a4e0fdd5c067757.js.map.br +0 -0
  68. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-9f03d060da06e8838a4e0fdd5c067757.js.map.gz +0 -0
  69. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d0d9dffa612bf12bf551c5e513c28691.js.br +0 -0
  70. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d0d9dffa612bf12bf551c5e513c28691.js.gz +0 -0
  71. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d0d9dffa612bf12bf551c5e513c28691.js.map.br +0 -0
  72. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-d0d9dffa612bf12bf551c5e513c28691.js.map.gz +0 -0
  73. package/dist/server/web-ui/_expo/static/js/web/index-461cf3ab1d54d6debea0e037829768e9.js.br +0 -0
  74. package/dist/server/web-ui/_expo/static/js/web/index-461cf3ab1d54d6debea0e037829768e9.js.gz +0 -0
  75. package/dist/server/web-ui/_expo/static/js/web/index-461cf3ab1d54d6debea0e037829768e9.js.map.br +0 -0
  76. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-54584275ea7a32061741c119074ff13f.js.br +0 -0
  77. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-54584275ea7a32061741c119074ff13f.js.gz +0 -0
  78. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-54584275ea7a32061741c119074ff13f.js.map.br +0 -0
  79. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-54584275ea7a32061741c119074ff13f.js.map.gz +0 -0
  80. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-b53f2ba81a9777f6f6d04a98b0a12c33.js.br +0 -0
  81. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-b53f2ba81a9777f6f6d04a98b0a12c33.js.gz +0 -0
  82. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-b53f2ba81a9777f6f6d04a98b0a12c33.js.map.br +0 -0
  83. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-b53f2ba81a9777f6f6d04a98b0a12c33.js.map.gz +0 -0
  84. package/dist/server/web-ui/_expo/static/js/web/profiler-7b2011c26cedb58cc00c02a7c25fc0a0.js.br +0 -0
  85. package/dist/server/web-ui/_expo/static/js/web/profiler-7b2011c26cedb58cc00c02a7c25fc0a0.js.gz +0 -0
  86. package/dist/server/web-ui/_expo/static/js/web/profiler-7b2011c26cedb58cc00c02a7c25fc0a0.js.map.br +0 -0
  87. package/dist/server/web-ui/_expo/static/js/web/profiler-7b2011c26cedb58cc00c02a7c25fc0a0.js.map.gz +0 -0
  88. package/dist/server/web-ui/_expo/static/js/web/startRecording-1b57837c4c358ef963a1392d9d96354b.js.br +0 -0
  89. package/dist/server/web-ui/_expo/static/js/web/startRecording-1b57837c4c358ef963a1392d9d96354b.js.gz +0 -0
  90. package/dist/server/web-ui/_expo/static/js/web/startRecording-1b57837c4c358ef963a1392d9d96354b.js.map.br +0 -0
@@ -91,6 +91,10 @@ import { getCaptureStreamWs } from "./meetings/capture-stream-ws.js";
91
91
  import { createSpeechService } from "./speech/speech-runtime.js";
92
92
  import { AgentManager } from "./agent/agent-manager.js";
93
93
  import { scheduleSessionDigestRefresh } from "./agent/session-digest-generator.js";
94
+ import { CardMoveLog } from "./agent/card-move-log.js";
95
+ import { BlockerLog } from "./agent/blocker-log.js";
96
+ import { JudgeRelayGate } from "./agent/judge-relay-gate.js";
97
+ import { JarvisJudge } from "./agent/jarvis-judge.js";
94
98
  import { registerAgentRoutes } from "./agent/agent-routes.js";
95
99
  import { AgentStorage } from "./agent/agent-storage.js";
96
100
  import { attachAgentStoragePersistence } from "./persistence-hooks.js";
@@ -560,11 +564,33 @@ export async function createPaseoDaemon(config, rootLogger) {
560
564
  isDev: config.isDev === true,
561
565
  extraClients: config.agentClients,
562
566
  });
567
+ // Jarvis substrate (JARVIS-V1-SPEC §3.2). Append-only kanban move history.
568
+ // Prospective only: nothing before this ships is recoverable, which is why the
569
+ // spec sequences it ahead of every other piece.
570
+ const cardMoveLog = new CardMoveLog({ dir: config.paseoHome, logger });
571
+ // Blocker history. Same prospective-only property as the move log, and it
572
+ // answers a different question: not "how often was this deferred" but "who or
573
+ // what has kept blocking it". mergeDigest overwrites digest.blockers on every
574
+ // derivation, so without this the signal is destroyed on each idle.
575
+ const blockerLog = new BlockerLog({ dir: config.paseoHome, logger });
576
+ // Jarvis judge config (§5, §9.1). Env-driven in v1 to avoid protocol churn
577
+ // while the feature is still being shaped.
578
+ // Gate for the judge's one mutating capability. Enabled only when the judge
579
+ // itself is, so an unconfigured deployment cannot expose relay_to_agent.
580
+ const judgeRelayGate = new JudgeRelayGate({
581
+ enabled: Boolean(process.env.PASEO_JARVIS_AGENT_ID?.trim()),
582
+ });
583
+ const jarvisJudgeConfig = {
584
+ agentId: process.env.PASEO_JARVIS_AGENT_ID?.trim() || null,
585
+ shadow: process.env.PASEO_JARVIS_SHADOW === "1",
586
+ };
563
587
  const initialAgentManagerState = providerSnapshotManager.getAgentManagerProviderState();
564
588
  const agentManager = new AgentManager({
565
589
  clients: initialAgentManagerState.clients,
566
590
  providerDefinitions: initialAgentManagerState.providerDefinitions,
567
591
  registry: agentStorage,
592
+ cardMoveLog,
593
+ blockerLog,
568
594
  appendSystemPrompt: config.appendSystemPrompt,
569
595
  onWorkspaceStateMayHaveChanged: ({ cwd }) => {
570
596
  workspaceGitService.onWorkspaceStateMayHaveChanged(cwd);
@@ -577,14 +603,49 @@ export async function createPaseoDaemon(config, rootLogger) {
577
603
  // and regenerate summary/accomplishments via the borrowed-provider rail (the
578
604
  // same one auto-title uses; the daemon holds no API key of its own). Debounced +
579
605
  // coalesced inside the scheduler; internal agents never broadcast attention.
606
+ // Jarvis judge (JARVIS-V1-SPEC §5.1). Constructed before the attention
607
+ // listener because the listener has to ORDER the two: see below.
608
+ const jarvisJudge = new JarvisJudge({
609
+ agentManager,
610
+ agentStorage,
611
+ cardMoveLog,
612
+ blockerLog,
613
+ relayGate: judgeRelayGate,
614
+ config: jarvisJudgeConfig,
615
+ logger,
616
+ });
617
+ if (jarvisJudge.enabled) {
618
+ logger.info({ judgeAgentId: jarvisJudgeConfig.agentId, shadow: jarvisJudgeConfig.shadow }, "Jarvis judge enabled");
619
+ }
580
620
  agentManager.addAgentAttentionListener((params) => {
621
+ // Never let a judge failure take down attention handling for everyone else.
622
+ const wakeJudge = () => {
623
+ void jarvisJudge.handleAttention({ agentId: params.agentId, reason: params.reason });
624
+ };
625
+ // `error` and `permission` have no derivation step, so nothing to wait for.
581
626
  if (params.reason !== "finished") {
627
+ if (jarvisJudge.enabled) {
628
+ wakeJudge();
629
+ }
582
630
  return;
583
631
  }
584
632
  const agent = agentManager.getAgent(params.agentId);
585
633
  if (!agent || agent.internal) {
586
634
  return;
587
635
  }
636
+ // ORDERING IS LOAD-BEARING, and getting it wrong is invisible.
637
+ //
638
+ // The digest refresh and the judge both hang off this one `finished` event.
639
+ // Fired in parallel, the judge wins the race every time and reads a digest
640
+ // that has not been written yet, so its briefing carries no summary, no
641
+ // blockers and no deadline. It then correctly concludes there is nothing
642
+ // worth saying and answers "quiet" forever. No error is raised anywhere: the
643
+ // feature looks healthy and delivers nothing. Verified live in the docker lab
644
+ // before this chaining existed.
645
+ //
646
+ // So the judge is woken from onSettled, which fires on success, skip AND
647
+ // failure. A judge that only ran on the happy path would go quiet exactly
648
+ // when something broke.
588
649
  scheduleSessionDigestRefresh({
589
650
  agentManager,
590
651
  agentId: params.agentId,
@@ -597,6 +658,7 @@ export async function createPaseoDaemon(config, rootLogger) {
597
658
  thinkingOptionId: agent.runtimeInfo?.thinkingOptionId ?? agent.config.thinkingOptionId ?? null,
598
659
  },
599
660
  logger,
661
+ onSettled: jarvisJudge.enabled ? wakeJudge : undefined,
600
662
  });
601
663
  });
602
664
  // Epic 1, Story 1.2 — first-class workflow entity. WorkflowManager orchestrates
@@ -849,6 +911,17 @@ export async function createPaseoDaemon(config, rootLogger) {
849
911
  callerAgentId: runtime.callerAgentId,
850
912
  enableVoiceTools: runtime.enableVoiceTools,
851
913
  voiceOnly: runtime.voiceOnly,
914
+ // JARVIS-V1-SPEC §6, HARD REQUIREMENT. The judge reads untrusted transcripts,
915
+ // so it must not hold a mutating tool. Keyed on identity rather than on a
916
+ // mode, because a mode is something the agent itself could change.
917
+ readOnly: runtime.readOnly ||
918
+ (jarvisJudgeConfig.agentId !== null && runtime.callerAgentId === jarvisJudgeConfig.agentId),
919
+ // Only the judge's own tool sessions get the relay tool, and even then its
920
+ // handler refuses unless a human turn is driving. Identity-keyed, like the
921
+ // read-only surface, so the agent cannot grant it to itself.
922
+ judgeRelayGate: jarvisJudgeConfig.agentId !== null && runtime.callerAgentId === jarvisJudgeConfig.agentId
923
+ ? judgeRelayGate
924
+ : undefined,
852
925
  resolveSpeakHandler: (agentId) => wsServer?.resolveVoiceSpeakHandler(agentId) ?? null,
853
926
  resolveCallerContext: (agentId) => wsServer?.resolveVoiceCallerContext(agentId) ?? null,
854
927
  logger,
@@ -3,6 +3,20 @@ import { EventEmitter } from "node:events";
3
3
  import { WebSocket } from "ws";
4
4
  import { createDaemonChannel, } from "@hyperdrive.bot/paseo-relay/e2ee";
5
5
  import { buildRelayWebSocketUrl } from "@hyperdrive.bot/paseo-protocol/daemon-endpoints";
6
+ /**
7
+ * Monotonic milliseconds. Every liveness comparison in this file MUST use this, never
8
+ * Date.now().
9
+ *
10
+ * Date.now() can step. On a WSL2 host whose Windows Time service is stopped, this machine's
11
+ * wall clock oscillated +/-48.6s about six times a minute (69 steps in 11.7 minutes, while
12
+ * monotonic time advanced exactly on schedule). A forward step made a 10s-old ping look 58s
13
+ * stale, so healthy control sockets were terminated every few minutes and every phone client
14
+ * was dropped with them. performance.now() is immune: it cannot go backwards and no clock
15
+ * sync moves it.
16
+ */
17
+ function monotonicNowMs() {
18
+ return performance.now();
19
+ }
6
20
  const CONTROL_PING_INTERVAL_MS = 10000;
7
21
  const CONTROL_STALE_TIMEOUT_MS = 30000;
8
22
  const CONTROL_READY_TIMEOUT_MS = 8000;
@@ -138,7 +152,7 @@ export function startRelayTransport({ logger, attachSocket, relayEndpoint, relay
138
152
  socket.on("open", () => {
139
153
  if (controlWs !== socket)
140
154
  return;
141
- controlLastSeenAt = Date.now();
155
+ controlLastSeenAt = monotonicNowMs();
142
156
  if (controlKeepaliveInterval) {
143
157
  clearInterval(controlKeepaliveInterval);
144
158
  controlKeepaliveInterval = null;
@@ -162,14 +176,31 @@ export function startRelayTransport({ logger, attachSocket, relayEndpoint, relay
162
176
  // ignore
163
177
  }
164
178
  }, CONTROL_READY_TIMEOUT_MS);
179
+ let lastTickAt = monotonicNowMs();
165
180
  controlKeepaliveInterval = setInterval(() => {
166
181
  if (stopped)
167
182
  return;
168
- if (controlWs !== socket)
183
+ // Instrumentation for a measured anomaly, see docs/tech-debt.md 2026-08-01.
184
+ // Terminations consistently report staleForMs ~58.3s (57455-58566 across 36 samples)
185
+ // although this ticks every 10s and trips past 30s, which can only produce 30-40s.
186
+ // Two candidates remain: the tick is not running at its configured interval, or an
187
+ // interval belonging to a superseded socket is doing the terminating (21 of the 36
188
+ // trips killed a connection whose replacement was already live, always 45.9-47.1s
189
+ // after it connected). These two lines distinguish them; neither is derivable from
190
+ // the logs we have today.
191
+ const tickNow = monotonicNowMs();
192
+ const sinceLastTickMs = tickNow - lastTickAt;
193
+ lastTickAt = tickNow;
194
+ if (sinceLastTickMs > CONTROL_PING_INTERVAL_MS * 1.5) {
195
+ relayLogger.warn({ connectionId, sinceLastTickMs, expectedMs: CONTROL_PING_INTERVAL_MS }, "relay_control_keepalive_tick_late");
196
+ }
197
+ if (controlWs !== socket) {
198
+ relayLogger.warn({ connectionId, sinceLastTickMs }, "relay_control_keepalive_orphaned");
169
199
  return;
200
+ }
170
201
  if (socket.readyState !== WebSocket.OPEN)
171
202
  return;
172
- const now = Date.now();
203
+ const now = monotonicNowMs();
173
204
  const staleForMs = now - controlLastSeenAt;
174
205
  // If the control socket is half-open or silently dropped, ws may never emit "close".
175
206
  // Use a WebSocket protocol ping to detect staleness and force a reconnect.
@@ -236,13 +267,13 @@ export function startRelayTransport({ logger, attachSocket, relayEndpoint, relay
236
267
  socket.on("pong", () => {
237
268
  if (controlWs !== socket)
238
269
  return;
239
- controlLastSeenAt = Date.now();
270
+ controlLastSeenAt = monotonicNowMs();
240
271
  relayLogger.debug({ connectionId }, "relay_control_pong_received");
241
272
  });
242
273
  socket.on("message", (data) => {
243
274
  if (controlWs !== socket)
244
275
  return;
245
- controlLastSeenAt = Date.now();
276
+ controlLastSeenAt = monotonicNowMs();
246
277
  const msg = tryParseControlMessage(data);
247
278
  if (msg) {
248
279
  markControlReady();
@@ -1,5 +1,5 @@
1
- __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentBridge=function(){const l=(0,s.createDesktopPreviewUrlResolver)({reader:(0,s.createDesktopFileReader)(),objectUrls:(0,s.createBrowserObjectUrlMinter)()});return{copyFile:t.copyDesktopAttachmentFile,writeBase64:t.writeDesktopAttachmentBase64,writeBytes:t.writeDesktopAttachmentBytes,deleteFile:t.deleteDesktopAttachmentFile,garbageCollect:t.garbageCollectDesktopAttachmentFiles,readFileBase64:s.readDesktopFileBase64,resolvePreviewUrl:t=>l.resolve(t),releasePreviewUrl:t=>l.release(t)}};var t=r(d[0]),s=r(d[1])},4779,[4784,4785]);
2
- __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.writeDesktopAttachmentBase64=async function(n){return await(0,t.invokeDesktopCommand)("write_attachment_base64",{attachmentId:n.attachmentId,base64:n.base64,extension:n.extension??null})},e.writeDesktopAttachmentBytes=async function(n){return await(0,t.invokeDesktopCommand)("write_attachment_bytes",{attachmentId:n.attachmentId,bytes:n.bytes,extension:n.extension??null})},e.copyDesktopAttachmentFile=async function(n){return await(0,t.invokeDesktopCommand)("copy_attachment_file",{attachmentId:n.attachmentId,sourcePath:n.sourcePath,extension:n.extension??null})},e.deleteDesktopAttachmentFile=async function(n){return await(0,t.invokeDesktopCommand)("delete_attachment_file",{path:n.path})},e.garbageCollectDesktopAttachmentFiles=async function(n){return await(0,t.invokeDesktopCommand)("garbage_collect_attachment_files",{referencedIds:[...n.referencedIds]})};var t=r(d[0])},4784,[3406]);
3
- __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.readDesktopFileBase64=s,e.createDesktopFileReader=function(){return{readFileBase64:s}},e.createBrowserObjectUrlMinter=function(){return{tryCreate({mimeType:t,base64:n}){if("undefined"==typeof URL||"function"!=typeof URL.createObjectURL)return null;const o=c(n),s=new ArrayBuffer(o.byteLength);new Uint8Array(s).set(o);const u=new Blob([s],{type:t});return URL.createObjectURL(u)},revoke(t){"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL&&URL.revokeObjectURL(t)}}},e.createDesktopPreviewUrlResolver=function(t){const n=new Set;return{async resolve(o){const s=await t.reader.readFileBase64(o.storageKey),c=t.objectUrls.tryCreate({mimeType:o.mimeType,base64:s});return null===c?`data:${o.mimeType};base64,${s}`:(n.add(c),c)},async release({url:o}){n.has(o)&&(n.delete(o),t.objectUrls.revoke(o))}}};var t=r(d[0]),n=r(d[1]),o=r(d[2]);async function s(o){return await(0,n.invokeDesktopCommand)("read_file_base64",{path:(0,t.fileUriToPath)(o)})}function c(t){return new Uint8Array(o.Buffer.from(t,"base64"))}},4785,[4481,3406,52]);
4
- //# sourceMappingURL=/_expo/static/js/web/desktop-attachment-bridge-9f03d060da06e8838a4e0fdd5c067757.js.map
5
- //# debugId=b27b1ca8-1e2a-4a5a-ad3a-bef5fdc1d185
1
+ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentBridge=function(){const l=(0,s.createDesktopPreviewUrlResolver)({reader:(0,s.createDesktopFileReader)(),objectUrls:(0,s.createBrowserObjectUrlMinter)()});return{copyFile:t.copyDesktopAttachmentFile,writeBase64:t.writeDesktopAttachmentBase64,writeBytes:t.writeDesktopAttachmentBytes,deleteFile:t.deleteDesktopAttachmentFile,garbageCollect:t.garbageCollectDesktopAttachmentFiles,readFileBase64:s.readDesktopFileBase64,resolvePreviewUrl:t=>l.resolve(t),releasePreviewUrl:t=>l.release(t)}};var t=r(d[0]),s=r(d[1])},4780,[4785,4786]);
2
+ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.writeDesktopAttachmentBase64=async function(n){return await(0,t.invokeDesktopCommand)("write_attachment_base64",{attachmentId:n.attachmentId,base64:n.base64,extension:n.extension??null})},e.writeDesktopAttachmentBytes=async function(n){return await(0,t.invokeDesktopCommand)("write_attachment_bytes",{attachmentId:n.attachmentId,bytes:n.bytes,extension:n.extension??null})},e.copyDesktopAttachmentFile=async function(n){return await(0,t.invokeDesktopCommand)("copy_attachment_file",{attachmentId:n.attachmentId,sourcePath:n.sourcePath,extension:n.extension??null})},e.deleteDesktopAttachmentFile=async function(n){return await(0,t.invokeDesktopCommand)("delete_attachment_file",{path:n.path})},e.garbageCollectDesktopAttachmentFiles=async function(n){return await(0,t.invokeDesktopCommand)("garbage_collect_attachment_files",{referencedIds:[...n.referencedIds]})};var t=r(d[0])},4785,[3406]);
3
+ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.readDesktopFileBase64=s,e.createDesktopFileReader=function(){return{readFileBase64:s}},e.createBrowserObjectUrlMinter=function(){return{tryCreate({mimeType:t,base64:n}){if("undefined"==typeof URL||"function"!=typeof URL.createObjectURL)return null;const o=c(n),s=new ArrayBuffer(o.byteLength);new Uint8Array(s).set(o);const u=new Blob([s],{type:t});return URL.createObjectURL(u)},revoke(t){"undefined"!=typeof URL&&"function"==typeof URL.revokeObjectURL&&URL.revokeObjectURL(t)}}},e.createDesktopPreviewUrlResolver=function(t){const n=new Set;return{async resolve(o){const s=await t.reader.readFileBase64(o.storageKey),c=t.objectUrls.tryCreate({mimeType:o.mimeType,base64:s});return null===c?`data:${o.mimeType};base64,${s}`:(n.add(c),c)},async release({url:o}){n.has(o)&&(n.delete(o),t.objectUrls.revoke(o))}}};var t=r(d[0]),n=r(d[1]),o=r(d[2]);async function s(o){return await(0,n.invokeDesktopCommand)("read_file_base64",{path:(0,t.fileUriToPath)(o)})}function c(t){return new Uint8Array(o.Buffer.from(t,"base64"))}},4786,[4481,3406,52]);
4
+ //# sourceMappingURL=/_expo/static/js/web/desktop-attachment-bridge-e6e0f92f1a2959279a7c3b2b50bf1df3.js.map
5
+ //# debugId=391ec10e-786a-4bd5-9972-7810ef469b73
@@ -1,3 +1,3 @@
1
- __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentStore=function(n){return{storageType:"desktop-file",async save(s){const o=s.id??(0,t.generateAttachmentId)(),l=s.fileName??null;if("file_uri"===s.source.kind)return await c(n,{id:o,uri:s.source.uri,mimeType:s.mimeType,fileName:l});if("data_url"===s.source.kind){const c=(0,t.parseDataUrl)(s.source.dataUrl),p=(0,t.normalizeMimeType)(s.mimeType??c.mimeType);return await y(n,{id:o,base64:c.base64,mimeType:p,fileName:l})}if("bytes"===s.source.kind){const c=(0,t.normalizeMimeType)(s.mimeType);return await p(n,{id:o,bytes:s.source.bytes,mimeType:c,fileName:l})}const f=(0,t.normalizeMimeType)(s.mimeType??s.source.blob.type),u=await(0,t.blobToBase64)(s.source.blob);return await y(n,{id:o,base64:u,mimeType:f,fileName:l})},encodeBase64:async({attachment:t})=>(f(t),await n.readFileBase64(t.storageKey)),resolvePreviewUrl:async({attachment:t})=>(f(t),await n.resolvePreviewUrl(t)),async releasePreviewUrl({attachment:t,url:s}){f(t),await n.releasePreviewUrl({url:s})},async delete({attachment:t}){f(t),await n.deleteFile({path:t.storageKey})},async garbageCollect({referencedIds:t}){await n.garbageCollect({referencedIds:Array.from(t)})}}};var t=r(d[0]);const n={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/gif":".gif","image/webp":".webp","image/avif":".avif","image/heic":".heic","image/heif":".heif","image/tiff":".tiff","image/bmp":".bmp","image/svg+xml":".svg"};function s(t){const n=t.replace(/\\/g,"/").split("/"),s=n[n.length-1];return s&&s.length>0?s:null}function o(s){const o=(0,t.getFileExtensionFromName)(s.fileName);if(o)return o;const l=(0,t.getFileExtensionFromName)(s.sourcePath);return l||(n[s.mimeType]??".img")}function l(t){return{id:t.id,mimeType:t.mimeType,storageType:"desktop-file",storageKey:t.storagePath,fileName:t.fileName??null,byteSize:t.byteSize,createdAt:Date.now()}}async function c(n,c){const y=(0,t.fileUriToPath)(c.uri),p=c.fileName??s(y),f=(0,t.normalizeMimeType)(c.mimeType),u=o({fileName:p,sourcePath:y,mimeType:f}),T=await n.copyFile({attachmentId:c.id,sourcePath:y,extension:u});return l({id:c.id,mimeType:f,storagePath:T.path,byteSize:T.byteSize,fileName:p})}async function y(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBase64({attachmentId:n.id,base64:n.base64,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}async function p(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBytes({attachmentId:n.id,bytes:n.bytes,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}function f(t){if("desktop-file"!==t.storageType)throw new Error(`Unsupported desktop attachment storage type '${t.storageType}'.`)}},4778,[4481]);
2
- //# sourceMappingURL=/_expo/static/js/web/desktop-attachment-store-d0d9dffa612bf12bf551c5e513c28691.js.map
3
- //# debugId=936c0b02-c88e-4a06-bf9d-785dff42ae12
1
+ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.createDesktopAttachmentStore=function(n){return{storageType:"desktop-file",async save(s){const o=s.id??(0,t.generateAttachmentId)(),l=s.fileName??null;if("file_uri"===s.source.kind)return await c(n,{id:o,uri:s.source.uri,mimeType:s.mimeType,fileName:l});if("data_url"===s.source.kind){const c=(0,t.parseDataUrl)(s.source.dataUrl),p=(0,t.normalizeMimeType)(s.mimeType??c.mimeType);return await y(n,{id:o,base64:c.base64,mimeType:p,fileName:l})}if("bytes"===s.source.kind){const c=(0,t.normalizeMimeType)(s.mimeType);return await p(n,{id:o,bytes:s.source.bytes,mimeType:c,fileName:l})}const f=(0,t.normalizeMimeType)(s.mimeType??s.source.blob.type),u=await(0,t.blobToBase64)(s.source.blob);return await y(n,{id:o,base64:u,mimeType:f,fileName:l})},encodeBase64:async({attachment:t})=>(f(t),await n.readFileBase64(t.storageKey)),resolvePreviewUrl:async({attachment:t})=>(f(t),await n.resolvePreviewUrl(t)),async releasePreviewUrl({attachment:t,url:s}){f(t),await n.releasePreviewUrl({url:s})},async delete({attachment:t}){f(t),await n.deleteFile({path:t.storageKey})},async garbageCollect({referencedIds:t}){await n.garbageCollect({referencedIds:Array.from(t)})}}};var t=r(d[0]);const n={"image/png":".png","image/jpeg":".jpg","image/jpg":".jpg","image/gif":".gif","image/webp":".webp","image/avif":".avif","image/heic":".heic","image/heif":".heif","image/tiff":".tiff","image/bmp":".bmp","image/svg+xml":".svg"};function s(t){const n=t.replace(/\\/g,"/").split("/"),s=n[n.length-1];return s&&s.length>0?s:null}function o(s){const o=(0,t.getFileExtensionFromName)(s.fileName);if(o)return o;const l=(0,t.getFileExtensionFromName)(s.sourcePath);return l||(n[s.mimeType]??".img")}function l(t){return{id:t.id,mimeType:t.mimeType,storageType:"desktop-file",storageKey:t.storagePath,fileName:t.fileName??null,byteSize:t.byteSize,createdAt:Date.now()}}async function c(n,c){const y=(0,t.fileUriToPath)(c.uri),p=c.fileName??s(y),f=(0,t.normalizeMimeType)(c.mimeType),u=o({fileName:p,sourcePath:y,mimeType:f}),T=await n.copyFile({attachmentId:c.id,sourcePath:y,extension:u});return l({id:c.id,mimeType:f,storagePath:T.path,byteSize:T.byteSize,fileName:p})}async function y(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBase64({attachmentId:n.id,base64:n.base64,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}async function p(t,n){const s=o({fileName:n.fileName,mimeType:n.mimeType}),c=await t.writeBytes({attachmentId:n.id,bytes:n.bytes,extension:s});return l({id:n.id,mimeType:n.mimeType,storagePath:c.path,byteSize:c.byteSize,fileName:n.fileName})}function f(t){if("desktop-file"!==t.storageType)throw new Error(`Unsupported desktop attachment storage type '${t.storageType}'.`)}},4779,[4481]);
2
+ //# sourceMappingURL=/_expo/static/js/web/desktop-attachment-store-d5c93939344c993e52d655ccf8942928.js.map
3
+ //# debugId=af1fb756-487c-4cc0-940a-a1a6caef5527