@alivault/pico 0.10.0 → 0.10.1

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.
@@ -1,8 +1,8 @@
1
1
  import { i as __toESM } from "../_runtime.mjs";
2
2
  import { $ as require_react, Q as require_jsx_runtime } from "../_libs/@base-ui/react+[...].mjs";
3
3
  import { a as createRouter, c as createRootRoute, n as Scripts, r as HeadContent, s as createFileRoute } from "../_libs/@tanstack/react-router+[...].mjs";
4
- import { F as CircleCheck, S as Info, _ as OctagonX, a as TriangleAlert } from "../_libs/lucide-react.mjs";
5
- import { A as TooltipProvider, B as extractMessageImages, F as buildItemsFromSync, G as mergeAssistantBlocksForStreaming, H as extractToolText, L as createCompactionSummaryItem, P as assistantBlocksFromMessage, S as Spinner, V as extractMessageText$1, n as APPLIED_THEME_STORAGE_KEY, t as APPLIED_THEME_CLASSES, v as Route$54, xt as toolCategoryFromTool } from "./routes-D6yf6dMU.mjs";
4
+ import { I as CircleCheck, S as Info, _ as OctagonX, a as TriangleAlert } from "../_libs/lucide-react.mjs";
5
+ import { A as TooltipProvider, B as extractMessageImages, F as buildItemsFromSync, G as mergeAssistantBlocksForStreaming, H as extractToolText, L as createCompactionSummaryItem, P as assistantBlocksFromMessage, S as Spinner, St as toolCategoryFromTool, V as extractMessageText$1, n as APPLIED_THEME_STORAGE_KEY, t as APPLIED_THEME_CLASSES, v as Route$54 } from "./routes-DbGwM-bj.mjs";
6
6
  import { t as QueryClient } from "../_libs/tanstack__query-core.mjs";
7
7
  import { t as setupRouterSsrQueryIntegration } from "../_libs/@tanstack/react-router-ssr-query+[...].mjs";
8
8
  import { n as HotkeysProvider } from "../_libs/tanstack__react-hotkeys.mjs";
@@ -20,7 +20,7 @@ import os, { homedir } from "node:os";
20
20
  import { performance } from "node:perf_hooks";
21
21
  import { isMainThread } from "node:worker_threads";
22
22
  import { execSync, spawn } from "node:child_process";
23
- //#region node_modules/.nitro/vite/services/ssr/assets/router-BfWi4RfZ.js
23
+ //#region node_modules/.nitro/vite/services/ssr/assets/router-DhVJ7gcL.js
24
24
  var import_react = /* @__PURE__ */ __toESM(require_react());
25
25
  var import_jsx_runtime = require_jsx_runtime();
26
26
  var Toaster$1 = ({ ...props }) => {
@@ -71,7 +71,7 @@ function AppProviders({ children }) {
71
71
  })
72
72
  });
73
73
  }
74
- var styles_default = "/assets/styles-DgbW000h.css";
74
+ var styles_default = "/assets/styles-oRWMaOB0.css";
75
75
  var TANSTACK_DEVTOOLS_SETTINGS_KEY = "tanstack_devtools_settings";
76
76
  var TANSTACK_DEVTOOLS_DEFAULTS_STORAGE_KEY = "pico-tanstack-devtools-defaults-v1";
77
77
  var TANSTACK_DEVTOOLS_CONFIG = {
@@ -529,15 +529,15 @@ async function resolveRequestedEntry(options) {
529
529
  const requestedEntry = getSessionEntryByKey(requestedSessionKey);
530
530
  if (requestedEntry) return await activateRequestedEntry(requestedEntry);
531
531
  }
532
- if (preferActiveDraft && context.draftKey) {
533
- const draftEntry = getSessionEntryByKey(context.draftKey);
534
- if (draftEntry && isDraftEntry(draftEntry)) return await activateRequestedEntry(draftEntry);
535
- }
536
532
  const requestedSessionId = url.searchParams.get("session");
537
533
  if (requestedSessionId) {
538
534
  const requestedEntry = await ensureSessionEntryById(requestedSessionId);
539
535
  if (requestedEntry) return await activateRequestedEntry(requestedEntry);
540
536
  }
537
+ if (preferActiveDraft && context.draftKey) {
538
+ const draftEntry = getSessionEntryByKey(context.draftKey);
539
+ if (draftEntry && isDraftEntry(draftEntry)) return await activateRequestedEntry(draftEntry);
540
+ }
541
541
  const activeEntry = getActiveEntry(context);
542
542
  if (activeEntry) return await activateRequestedEntry(activeEntry);
543
543
  return await getOrCreateDraftEntry(context);
@@ -1113,40 +1113,85 @@ function countFullTurnUserAndAssistantMessages(messages) {
1113
1113
  finishTurn(false);
1114
1114
  return count;
1115
1115
  }
1116
- async function readSessionListMetrics(sessionPath) {
1117
- try {
1118
- const content = await readFile(sessionPath, "utf8");
1119
- let lastTimestamp = 0;
1120
- let lastValue;
1121
- const messages = [];
1122
- for (const line of content.split("\n")) {
1123
- if (!line.trim()) continue;
1124
- let entry;
1125
- try {
1126
- entry = JSON.parse(line);
1127
- } catch {
1128
- continue;
1129
- }
1130
- if (!isRecord(entry) || entry.type !== "message") continue;
1131
- const message = isRecord(entry.message) ? entry.message : void 0;
1132
- if (!message) continue;
1133
- const messageWithTimestamp = {
1134
- ...message,
1135
- timestamp: message.timestamp ?? entry.timestamp
1136
- };
1137
- if (messageWithTimestamp.role === "user") {
1138
- const normalized = normalizeModifiedTimestamp(messageWithTimestamp.timestamp);
1139
- const timestamp = modifiedTimestampValue(normalized);
1140
- if (timestamp && timestamp >= lastTimestamp) {
1141
- lastTimestamp = timestamp;
1142
- lastValue = normalized;
1143
- }
1116
+ function readSessionListMetricEntries(content) {
1117
+ const entries = [];
1118
+ for (const line of content.split("\n")) {
1119
+ if (!line.trim()) continue;
1120
+ let entry;
1121
+ try {
1122
+ entry = JSON.parse(line);
1123
+ } catch {
1124
+ continue;
1125
+ }
1126
+ if (!isRecord(entry) || entry.type === "session") continue;
1127
+ entries.push(entry);
1128
+ }
1129
+ return entries;
1130
+ }
1131
+ function sessionListMetricEntryId(entry) {
1132
+ return typeof entry.id === "string" && entry.id ? entry.id : "";
1133
+ }
1134
+ function sessionListMetricEntryParentId(entry) {
1135
+ return typeof entry.parentId === "string" && entry.parentId ? entry.parentId : "";
1136
+ }
1137
+ function sessionListMetricBranchEntries(entries, leafId) {
1138
+ if (leafId === void 0) return entries;
1139
+ if (leafId === null) return [];
1140
+ const byId = new Map(entries.flatMap((entry) => {
1141
+ const id = sessionListMetricEntryId(entry);
1142
+ return id ? [[id, entry]] : [];
1143
+ }));
1144
+ const leaf = byId.get(leafId);
1145
+ if (!leaf) return entries;
1146
+ const branch = [];
1147
+ let current = leaf;
1148
+ const visited = /* @__PURE__ */ new Set();
1149
+ while (current) {
1150
+ const id = sessionListMetricEntryId(current);
1151
+ if (id) {
1152
+ if (visited.has(id)) break;
1153
+ visited.add(id);
1154
+ }
1155
+ branch.unshift(current);
1156
+ const parentId = sessionListMetricEntryParentId(current);
1157
+ current = parentId ? byId.get(parentId) : void 0;
1158
+ }
1159
+ return branch;
1160
+ }
1161
+ function collectSessionListMetricMessages(entries) {
1162
+ let lastTimestamp = 0;
1163
+ let lastValue;
1164
+ const messages = [];
1165
+ for (const entry of entries) {
1166
+ if (entry.type !== "message") continue;
1167
+ const message = isRecord(entry.message) ? entry.message : void 0;
1168
+ if (!message) continue;
1169
+ const messageWithTimestamp = {
1170
+ ...message,
1171
+ timestamp: message.timestamp ?? entry.timestamp
1172
+ };
1173
+ if (messageWithTimestamp.role === "user") {
1174
+ const normalized = normalizeModifiedTimestamp(messageWithTimestamp.timestamp);
1175
+ const timestamp = modifiedTimestampValue(normalized);
1176
+ if (timestamp && timestamp >= lastTimestamp) {
1177
+ lastTimestamp = timestamp;
1178
+ lastValue = normalized;
1144
1179
  }
1145
- if (messageWithTimestamp.role === "user" || messageWithTimestamp.role === "assistant") messages.push(messageWithTimestamp);
1146
1180
  }
1181
+ if (messageWithTimestamp.role === "user" || messageWithTimestamp.role === "assistant") messages.push(messageWithTimestamp);
1182
+ }
1183
+ return {
1184
+ lastUserMessageAt: lastValue,
1185
+ messages
1186
+ };
1187
+ }
1188
+ async function readSessionListMetrics(sessionPath, options) {
1189
+ try {
1190
+ const entries = readSessionListMetricEntries(await readFile(sessionPath, "utf8"));
1191
+ const { lastUserMessageAt, messages } = collectSessionListMetricMessages(Object.prototype.hasOwnProperty.call(options ?? {}, "leafId") ? sessionListMetricBranchEntries(entries, options?.leafId) : entries);
1147
1192
  const lastMessage = getSessionLastCompleteMessageInfo(messages);
1148
1193
  return {
1149
- lastUserMessageAt: lastValue,
1194
+ lastUserMessageAt,
1150
1195
  lastMessageAt: lastMessage.timestamp,
1151
1196
  lastMessagePreview: lastMessage.preview,
1152
1197
  messageCount: countFullTurnUserAndAssistantMessages(messages)
@@ -3688,6 +3733,7 @@ var PicoRuntime = class {
3688
3733
  encoder = new TextEncoder();
3689
3734
  contexts = /* @__PURE__ */ new Map();
3690
3735
  sessionEntries = /* @__PURE__ */ new Map();
3736
+ sessionTreeLeafOverrides = /* @__PURE__ */ new Map();
3691
3737
  servicesByCwd = /* @__PURE__ */ new Map();
3692
3738
  pendingUiRequests = /* @__PURE__ */ new Map();
3693
3739
  activeOAuthLogins = /* @__PURE__ */ new Map();
@@ -3866,6 +3912,7 @@ var PicoRuntime = class {
3866
3912
  id,
3867
3913
  clients: /* @__PURE__ */ new Set(),
3868
3914
  activeRevision: 0,
3915
+ selectionNonce: 0,
3869
3916
  activeKey: void 0,
3870
3917
  draftKey: void 0,
3871
3918
  sessionScope: process.cwd(),
@@ -3878,6 +3925,31 @@ var PicoRuntime = class {
3878
3925
  getSessionPath(entry) {
3879
3926
  return entry.session.sessionFile ?? entry.key;
3880
3927
  }
3928
+ getSessionTreeLeafOverrideKey(entry) {
3929
+ return entry.session.sessionFile || "";
3930
+ }
3931
+ rememberSessionTreeLeaf(entry, onlyExisting = false) {
3932
+ const key = this.getSessionTreeLeafOverrideKey(entry);
3933
+ if (!key) return;
3934
+ if (onlyExisting && !this.sessionTreeLeafOverrides.has(key)) return;
3935
+ const leafId = entry.session.sessionManager.getLeafId?.() ?? null;
3936
+ if (this.sessionTreeLeafOverrides.get(key) === leafId) return;
3937
+ this.sessionTreeLeafOverrides.set(key, leafId);
3938
+ this.invalidateSessionIndexCache();
3939
+ }
3940
+ restoreSessionTreeLeafOverride(manager, sessionPath) {
3941
+ if (!this.sessionTreeLeafOverrides.has(sessionPath)) return;
3942
+ const leafId = this.sessionTreeLeafOverrides.get(sessionPath) ?? null;
3943
+ if (leafId === null) {
3944
+ manager.resetLeaf?.();
3945
+ return;
3946
+ }
3947
+ if (!manager.getEntry?.(leafId)) {
3948
+ this.sessionTreeLeafOverrides.delete(sessionPath);
3949
+ return;
3950
+ }
3951
+ manager.branch?.(leafId);
3952
+ }
3881
3953
  getActiveEntry(context) {
3882
3954
  return context.activeKey ? this.sessionEntries.get(context.activeKey) : void 0;
3883
3955
  }
@@ -4023,13 +4095,17 @@ var PicoRuntime = class {
4023
4095
  const sessions = allSessions.filter((entry) => (entry.messageCount ?? 0) > 0);
4024
4096
  const metricsStartedAt = performance.now();
4025
4097
  const withMetrics = await Promise.all(sessions.map(async (entry) => {
4026
- const metrics = entry.path ? await readSessionListMetrics(entry.path) : void 0;
4098
+ let metrics;
4099
+ if (entry.path) {
4100
+ const hasLeafOverride = this.sessionTreeLeafOverrides.has(entry.path);
4101
+ metrics = await readSessionListMetrics(entry.path, hasLeafOverride ? { leafId: this.sessionTreeLeafOverrides.get(entry.path) ?? null } : void 0);
4102
+ }
4027
4103
  return {
4028
4104
  ...entry,
4029
- lastUserMessageAt: metrics?.lastUserMessageAt ?? entry.lastUserMessageAt,
4030
- lastMessageAt: metrics?.lastMessageAt ?? entry.lastMessageAt,
4031
- lastMessagePreview: metrics?.lastMessagePreview ?? entry.lastMessagePreview,
4032
- messageCount: metrics?.messageCount ?? entry.messageCount
4105
+ lastUserMessageAt: metrics ? metrics.lastUserMessageAt : entry.lastUserMessageAt,
4106
+ lastMessageAt: metrics ? metrics.lastMessageAt : entry.lastMessageAt,
4107
+ lastMessagePreview: metrics ? metrics.lastMessagePreview : entry.lastMessagePreview,
4108
+ messageCount: metrics ? metrics.messageCount : entry.messageCount
4033
4109
  };
4034
4110
  }));
4035
4111
  this.logSessionLoadDebug("session_index:metrics", {
@@ -4370,6 +4446,16 @@ var PicoRuntime = class {
4370
4446
  await this.bindSessionEntry(entry);
4371
4447
  await Promise.all([this.broadcastEntryState(entry), this.broadcastSessionsAll()]);
4372
4448
  }
4449
+ scheduleTreeNavigationSessionListChange(entry, previousLeafId, result) {
4450
+ if (result.cancelled || result.aborted) return;
4451
+ const nextLeafId = entry.session.sessionManager.getLeafId?.() ?? null;
4452
+ if (!result.summaryEntry && previousLeafId === nextLeafId) return;
4453
+ this.rememberSessionTreeLeaf(entry);
4454
+ this.touchSessionEntry(entry);
4455
+ this.broadcastSessionsAll().catch((error) => {
4456
+ console.error("[pico] failed to broadcast tree navigation sessions:", error);
4457
+ });
4458
+ }
4373
4459
  syncGitWatchDirectories() {
4374
4460
  const cwds = /* @__PURE__ */ new Set();
4375
4461
  for (const context of this.contexts.values()) {
@@ -4793,6 +4879,7 @@ var PicoRuntime = class {
4793
4879
  const sdk = await this.getSdk();
4794
4880
  const openStartedAt = performance.now();
4795
4881
  const sessionManager = sdk.SessionManager.open(sessionPath);
4882
+ this.restoreSessionTreeLeafOverride(sessionManager, sessionPath);
4796
4883
  this.logSessionLoadDebug("session_manager:open", {
4797
4884
  sessionPath,
4798
4885
  cwd: sessionManager.getCwd(),
@@ -4809,7 +4896,9 @@ var PicoRuntime = class {
4809
4896
  if (currentManager.isPersisted?.()) {
4810
4897
  const currentSessionFile = entry.session.sessionFile;
4811
4898
  if (!currentSessionFile) throw new Error("Persisted session is missing a session file");
4812
- return (await this.getSdk()).SessionManager.open(currentSessionFile, currentManager.getSessionDir?.(), entry.cwd);
4899
+ const sessionManager = (await this.getSdk()).SessionManager.open(currentSessionFile, currentManager.getSessionDir?.(), entry.cwd);
4900
+ this.restoreSessionTreeLeafOverride(sessionManager, currentSessionFile);
4901
+ return sessionManager;
4813
4902
  }
4814
4903
  return await this.createForkedInMemorySessionManager(currentManager, currentManager.getLeafId?.(), entry.session.sessionFile);
4815
4904
  }
@@ -5192,14 +5281,12 @@ var PicoRuntime = class {
5192
5281
  };
5193
5282
  },
5194
5283
  navigateTree: async (targetId, navigateOptions) => {
5284
+ const previousLeafId = session.sessionManager.getLeafId?.() ?? null;
5195
5285
  const result = await session.navigateTree(targetId, navigateOptions);
5196
5286
  this.refreshRetainedConversationItems(entry);
5197
5287
  if (result.editorText != null) entry.uiState.editorText = result.editorText;
5198
5288
  await this.broadcastEntryState(entry);
5199
- if (result.summaryEntry) {
5200
- this.touchSessionEntry(entry);
5201
- await this.broadcastSessionsAll();
5202
- }
5289
+ this.scheduleTreeNavigationSessionListChange(entry, previousLeafId, result);
5203
5290
  return {
5204
5291
  cancelled: Boolean(result.cancelled),
5205
5292
  aborted: Boolean(result.aborted)
@@ -5326,6 +5413,7 @@ var PicoRuntime = class {
5326
5413
  statusChanged = true;
5327
5414
  }
5328
5415
  if (statusChanged) this.broadcastSessionStatusAll(entry);
5416
+ this.rememberSessionTreeLeaf(entry, true);
5329
5417
  await this.broadcastEntryState(entry);
5330
5418
  if (type === "agent_start" || type === "agent_end" || type === "message_end" || type === "compaction_end" || type === "queue_update") await this.broadcastSessionsAll();
5331
5419
  if (type === "agent_end" || type === "compaction_end") await this.cleanupInactiveContexts();
@@ -5383,12 +5471,13 @@ var PicoRuntime = class {
5383
5471
  const bootstrapStartedAt = performance.now();
5384
5472
  try {
5385
5473
  const stateStartedAt = performance.now();
5386
- this.sendStatePayloadToClient(context, client, this.currentStatePayload(activeEntry, context), { forceFull: true });
5474
+ const bootstrapEntry = this.getActiveEntry(context) ?? activeEntry;
5475
+ this.sendStatePayloadToClient(context, client, this.currentStatePayload(bootstrapEntry, context), { forceFull: true });
5387
5476
  this.logSessionLoadDebug("events_response:bootstrap_state", {
5388
5477
  contextId: context.id,
5389
5478
  clientId: client.id,
5390
5479
  durationMs: roundedDurationMs(stateStartedAt),
5391
- ...this.sessionDebugDetails(activeEntry)
5480
+ ...this.sessionDebugDetails(bootstrapEntry)
5392
5481
  });
5393
5482
  if (client.closed || request.signal.aborted) return;
5394
5483
  const sessionsStartedAt = performance.now();
@@ -5620,11 +5709,16 @@ var PicoRuntime = class {
5620
5709
  const url = new URL(request.url);
5621
5710
  const requestedSessionId = url.searchParams.get("session")?.trim() || "";
5622
5711
  const requestedSessionPath = url.searchParams.get("sessionPath")?.trim() || "";
5712
+ const rawSelectionNonce = Number(url.searchParams.get("selectionNonce"));
5713
+ const selectionNonce = Number.isSafeInteger(rawSelectionNonce) && rawSelectionNonce > 0 ? rawSelectionNonce : 0;
5623
5714
  const context = this.ensureContext(url.searchParams.get("context") || "default");
5624
5715
  context.sessionScope = normalizeSessionScope(url.searchParams.get("scope"), process.cwd());
5716
+ if (selectionNonce > context.selectionNonce) context.selectionNonce = selectionNonce;
5625
5717
  this.logSessionLoadDebug("select_session:start", {
5626
5718
  requestedSessionId,
5627
5719
  requestedSessionPath,
5720
+ selectionNonce,
5721
+ latestSelectionNonce: context.selectionNonce,
5628
5722
  contextId: context.id
5629
5723
  });
5630
5724
  try {
@@ -5640,6 +5734,26 @@ var PicoRuntime = class {
5640
5734
  ...this.sessionDebugDetails(nextEntry)
5641
5735
  });
5642
5736
  if (!nextEntry) throw new Error(`Unknown session: ${requestedSessionId}`);
5737
+ if (request.signal.aborted) {
5738
+ this.logSessionLoadDebug("select_session:skip_aborted", {
5739
+ requestedSessionId,
5740
+ requestedSessionPath,
5741
+ selectionNonce,
5742
+ latestSelectionNonce: context.selectionNonce,
5743
+ ...this.sessionDebugDetails(nextEntry)
5744
+ });
5745
+ return { ok: true };
5746
+ }
5747
+ if (selectionNonce > 0 && selectionNonce < context.selectionNonce) {
5748
+ this.logSessionLoadDebug("select_session:skip_stale", {
5749
+ requestedSessionId,
5750
+ requestedSessionPath,
5751
+ selectionNonce,
5752
+ latestSelectionNonce: context.selectionNonce,
5753
+ ...this.sessionDebugDetails(nextEntry)
5754
+ });
5755
+ return { ok: true };
5756
+ }
5643
5757
  const activateStartedAt = performance.now();
5644
5758
  await this.activateContextSession(context, nextEntry);
5645
5759
  this.logSessionLoadDebug("select_session:activate", {
@@ -5763,6 +5877,7 @@ var PicoRuntime = class {
5763
5877
  const targetId = typeof body.targetId === "string" ? body.targetId.trim() : "";
5764
5878
  if (!targetId) throw new Error("targetId is required");
5765
5879
  if (this.getEntryStreamingState(activeEntry) || activeEntry.session.isStreaming) throw new Error("Abort the current response before navigating the tree.");
5880
+ const previousLeafId = activeEntry.session.sessionManager.getLeafId?.() ?? null;
5766
5881
  const result = await activeEntry.session.navigateTree(targetId, {
5767
5882
  summarize: Boolean(body.summarize),
5768
5883
  customInstructions: typeof body.customInstructions === "string" ? body.customInstructions : void 0,
@@ -5771,11 +5886,8 @@ var PicoRuntime = class {
5771
5886
  });
5772
5887
  this.refreshRetainedConversationItems(activeEntry);
5773
5888
  if (result.editorText != null) activeEntry.uiState.editorText = result.editorText;
5774
- if (result.summaryEntry) {
5775
- this.touchSessionEntry(activeEntry);
5776
- await this.broadcastSessionsAll();
5777
- }
5778
5889
  await this.broadcastEntryState(activeEntry);
5890
+ this.scheduleTreeNavigationSessionListChange(activeEntry, previousLeafId, result);
5779
5891
  return {
5780
5892
  ok: true,
5781
5893
  cancelled: Boolean(result.cancelled),
@@ -3,9 +3,9 @@ import { $ as require_react, G as TooltipPositioner, J as TooltipRoot, K as Tool
3
3
  import { o as lazyRouteComponent, s as createFileRoute } from "../_libs/@tanstack/react-router+[...].mjs";
4
4
  import { n as clsx } from "../_libs/class-variance-authority+clsx.mjs";
5
5
  import { t as twMerge } from "../_libs/tailwind-merge.mjs";
6
- import { G as ArrowRight, H as ArrowUp, J as ArrowBigUp, K as ArrowLeft, P as Command, R as ChevronUp, g as Option, q as ArrowDown } from "../_libs/lucide-react.mjs";
6
+ import { F as Command, J as ArrowDown, K as ArrowRight, U as ArrowUp, Y as ArrowBigUp, g as Option, q as ArrowLeft, z as ChevronUp } from "../_libs/lucide-react.mjs";
7
7
  import { n as string, t as object } from "../_libs/zod.mjs";
8
- //#region node_modules/.nitro/vite/services/ssr/assets/routes-D6yf6dMU.js
8
+ //#region node_modules/.nitro/vite/services/ssr/assets/routes-DbGwM-bj.js
9
9
  var import_react = /* @__PURE__ */ __toESM(require_react());
10
10
  var import_jsx_runtime = require_jsx_runtime();
11
11
  function cn(...inputs) {
@@ -335,6 +335,11 @@ function promptDraftKey(target = {}) {
335
335
  if (target.sessionFile) return `file:${target.sessionFile}`;
336
336
  return `draft:${target.cwd?.trim() || "default"}`;
337
337
  }
338
+ function promptDraftKeyMatchesOwner(draftKey, ownerKey) {
339
+ if (!ownerKey) return false;
340
+ if (draftKey === ownerKey) return true;
341
+ return ownerKey === promptDraftKey() && draftKey.startsWith("draft:");
342
+ }
338
343
  function loadStoredPromptDrafts() {
339
344
  try {
340
345
  const raw = safeSessionStorageGetItem(PROMPT_DRAFTS_STORAGE_KEY);
@@ -1317,11 +1322,11 @@ function getSessionTitle(summary) {
1317
1322
  if (summary?.name?.trim()) return summary.name.trim();
1318
1323
  return "New session";
1319
1324
  }
1320
- var $$splitComponentImporter = () => import("./routes-CSvcOSyF.mjs");
1325
+ var $$splitComponentImporter = () => import("./routes-NB2wmfpS.mjs");
1321
1326
  var indexSearchSchema = object({ session: string().optional() });
1322
1327
  var Route = createFileRoute("/")({
1323
1328
  validateSearch: indexSearchSchema,
1324
1329
  component: lazyRouteComponent($$splitComponentImporter, "component")
1325
1330
  });
1326
1331
  //#endregion
1327
- export { readStoredAutoScrollEnabled as $, TooltipProvider as A, extractMessageImages as B, THEME_COLOR_MODES as C, TitleTooltip as D, THEME_STORAGE_KEY as E, buildItemsFromSync as F, mergeAssistantBlocksForStreaming as G, extractToolText as H, cn as I, normalizeStoredDirectoryList as J, normalizePromptImage as K, createCompactionSummaryItem as L, VIEWER_CONTEXT_STORAGE_KEY as M, appliedThemeClass as N, Tooltip$1 as O, assistantBlocksFromMessage as P, promptDraftKey as Q, createContextId as R, Spinner as S, THEME_FAMILIES as T, flattenTree as U, extractMessageText as V, getSessionTitle as W, normalizeThemeFamily as X, normalizeThemeColorMode as Y, previewUrlForImage as Z, RIGHT_SIDEBAR_WIDTHS_STORAGE_KEY as _, sessionListEntryKey as _t, COLLAPSED_DIRECTORIES_STORAGE_KEY as a, readStoredPromptDraft as at, SESSION_DONE_SOUND_ENABLED_STORAGE_KEY as b, thinkingSummaryText as bt, Kbd as c, readStoredSessionDoneDesktopNotificationsEnabled as ct, RECENT_DIRECTORIES_STORAGE_KEY as d, readStoredTheme as dt, readStoredCenterMessages as et, RIGHT_SIDEBAR_ACTIVE_TAB_STORAGE_KEY as f, readStoredThemeColorMode as ft, RIGHT_SIDEBAR_OPEN_STORAGE_KEY as g, sameContextUsage as gt, RIGHT_SIDEBAR_HISTORY_TAB_STORAGE_KEY as h, safeLocalStorageSetItem as ht, CENTER_MESSAGES_STORAGE_KEY as i, readStoredPinnedSessionKeys as it, TooltipTrigger as j, TooltipContent as k, KeyboardShortcutContent as l, readStoredSessionDoneSoundEnabled as lt, RIGHT_SIDEBAR_HISTORY_HEIGHT_STORAGE_KEY as m, safeLocalStorageGetItem as mt, APPLIED_THEME_STORAGE_KEY as n, readStoredDraftDirectory as nt, DRAFT_DIRECTORY_STORAGE_KEY as o, readStoredRecentDirectories as ot, RIGHT_SIDEBAR_FILE_TREE_WIDTH_STORAGE_KEY as p, rememberStoredPromptDraft as pt, normalizeSessionSelectionKeys as q, AUTO_SCROLL_ENABLED_STORAGE_KEY as r, readStoredHideToolBlocks as rt, HIDE_TOOL_BLOCKS_STORAGE_KEY as s, readStoredRightSidebarOpen as st, APPLIED_THEME_CLASSES as t, readStoredCollapsedDirectories as tt, PINNED_SESSIONS_STORAGE_KEY as u, readStoredSidebarDirectories as ut, Route as v, themeColorModeLabel as vt, THEME_COLOR_MODE_STORAGE_KEY as w, SIDEBAR_DIRECTORIES_STORAGE_KEY as x, toolCategoryFromTool as xt, SESSION_DONE_DESKTOP_NOTIFICATIONS_ENABLED_STORAGE_KEY as y, themeFamilyLabel as yt, createInitialSessionState as z };
1332
+ export { promptDraftKeyMatchesOwner as $, TooltipProvider as A, extractMessageImages as B, THEME_COLOR_MODES as C, TitleTooltip as D, THEME_STORAGE_KEY as E, buildItemsFromSync as F, mergeAssistantBlocksForStreaming as G, extractToolText as H, cn as I, normalizeStoredDirectoryList as J, normalizePromptImage as K, createCompactionSummaryItem as L, VIEWER_CONTEXT_STORAGE_KEY as M, appliedThemeClass as N, Tooltip$1 as O, assistantBlocksFromMessage as P, promptDraftKey as Q, createContextId as R, Spinner as S, toolCategoryFromTool as St, THEME_FAMILIES as T, flattenTree as U, extractMessageText as V, getSessionTitle as W, normalizeThemeFamily as X, normalizeThemeColorMode as Y, previewUrlForImage as Z, RIGHT_SIDEBAR_WIDTHS_STORAGE_KEY as _, sameContextUsage as _t, COLLAPSED_DIRECTORIES_STORAGE_KEY as a, readStoredPinnedSessionKeys as at, SESSION_DONE_SOUND_ENABLED_STORAGE_KEY as b, themeFamilyLabel as bt, Kbd as c, readStoredRightSidebarOpen as ct, RECENT_DIRECTORIES_STORAGE_KEY as d, readStoredSidebarDirectories as dt, readStoredAutoScrollEnabled as et, RIGHT_SIDEBAR_ACTIVE_TAB_STORAGE_KEY as f, readStoredTheme as ft, RIGHT_SIDEBAR_OPEN_STORAGE_KEY as g, safeLocalStorageSetItem as gt, RIGHT_SIDEBAR_HISTORY_TAB_STORAGE_KEY as h, safeLocalStorageGetItem as ht, CENTER_MESSAGES_STORAGE_KEY as i, readStoredHideToolBlocks as it, TooltipTrigger as j, TooltipContent as k, KeyboardShortcutContent as l, readStoredSessionDoneDesktopNotificationsEnabled as lt, RIGHT_SIDEBAR_HISTORY_HEIGHT_STORAGE_KEY as m, rememberStoredPromptDraft as mt, APPLIED_THEME_STORAGE_KEY as n, readStoredCollapsedDirectories as nt, DRAFT_DIRECTORY_STORAGE_KEY as o, readStoredPromptDraft as ot, RIGHT_SIDEBAR_FILE_TREE_WIDTH_STORAGE_KEY as p, readStoredThemeColorMode as pt, normalizeSessionSelectionKeys as q, AUTO_SCROLL_ENABLED_STORAGE_KEY as r, readStoredDraftDirectory as rt, HIDE_TOOL_BLOCKS_STORAGE_KEY as s, readStoredRecentDirectories as st, APPLIED_THEME_CLASSES as t, readStoredCenterMessages as tt, PINNED_SESSIONS_STORAGE_KEY as u, readStoredSessionDoneSoundEnabled as ut, Route as v, sessionListEntryKey as vt, THEME_COLOR_MODE_STORAGE_KEY as w, SIDEBAR_DIRECTORIES_STORAGE_KEY as x, thinkingSummaryText as xt, SESSION_DONE_DESKTOP_NOTIFICATIONS_ENABLED_STORAGE_KEY as y, themeColorModeLabel as yt, createInitialSessionState as z };