@qredence/fleet 0.6.2 → 0.6.3

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 (78) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/web/client/assets/DialogTitle-DiAm7YNe.js +1 -0
  3. package/dist/web/client/assets/alert-dialog-CYE37KMM.js +1 -0
  4. package/dist/web/client/assets/{artifacts-panel-DmQghvw8.js → artifacts-panel-ClDpGWOU.js} +1 -1
  5. package/dist/web/client/assets/{chat-C24kD2SP.js → chat-BVMnC5Qh.js} +1 -1
  6. package/dist/web/client/assets/{chat-command-palette-BIwjhE6s.js → chat-command-palette-YuyaJNbi.js} +1 -1
  7. package/dist/web/client/assets/{citations-BUvM92nt.js → citations-DXqV2NLy.js} +1 -1
  8. package/dist/web/client/assets/command-Cw4X8Bpk.js +1 -0
  9. package/dist/web/client/assets/dialog-BzcIOvFC.js +1 -0
  10. package/dist/web/client/assets/{fork-picker-dialog-CpwEwsxA.js → fork-picker-dialog-BYRr-xTy.js} +1 -1
  11. package/dist/web/client/assets/git-branch-CTq9aACS.js +1 -0
  12. package/dist/web/client/assets/globals-BtCXZXL_.css +2 -0
  13. package/dist/web/client/assets/{index-BGnQeUYE.js → index-B9aXxpOv.js} +2 -2
  14. package/dist/web/client/assets/{model-selector-list-CRZCXeBf.js → model-selector-list-CHD8lMAl.js} +1 -1
  15. package/dist/web/client/assets/{openui-renderer-Bkkx5kmA.js → openui-renderer-C4e9FOVR.js} +8 -8
  16. package/dist/web/client/assets/provider-catalog-ClVvphe0.js +1 -0
  17. package/dist/web/client/assets/provider-label-CwZ-KDxk.js +1 -0
  18. package/dist/web/client/assets/right-panel-registry-BnYCffmM.js +2 -0
  19. package/dist/web/client/assets/routes-DUontXSG.js +16 -0
  20. package/dist/web/client/assets/{session-tool-renderer-3E3cv8D0.js → session-tool-renderer-Bd3dsE2D.js} +3 -3
  21. package/dist/web/client/assets/session-tree-panel-CM4_wwrM.js +1 -0
  22. package/dist/web/client/assets/settings-dialog-DMTD9m6z.js +2 -0
  23. package/dist/web/client/assets/sparkles-BY5MFyk6.js +1 -0
  24. package/dist/web/client/assets/{subagent-chat-panel-C5ukYiUx.js → subagent-chat-panel-BESrXxAR.js} +1 -1
  25. package/dist/web/client/assets/{subagent-transcript-lqNcSVbH.js → subagent-transcript-CAqFJfMj.js} +1 -1
  26. package/dist/web/client/assets/{subagents-panel-SJKhaVTr.js → subagents-panel-8aKOwWLs.js} +1 -1
  27. package/dist/web/client/assets/{virtualized-turn-list-BgUgX6tM.js → virtualized-turn-list-mL3ONUUA.js} +3 -3
  28. package/dist/web/client/bundle-budget.json +6 -6
  29. package/dist/web/server/{_tanstack-start-manifest_v-BDPifIFN-DTSNCHBX.js → _tanstack-start-manifest_v-Cm8xE-Rb-TMLYN3GY.js} +15 -13
  30. package/dist/web/server/{artifacts-panel-BN3DgqfV-N73J6N5Y.js → artifacts-panel-CwLVBqyi-CDORJY75.js} +21 -20
  31. package/dist/web/server/{chat-command-palette-G8awyZRw-2QE7FXGT.js → chat-command-palette-DUha04ia-5OV7WVJZ.js} +11 -9
  32. package/dist/web/server/{chunk-ZOVXMNJM.js → chunk-3Q3QKLHC.js} +5 -96
  33. package/dist/web/server/{chunk-6SOMNRAX.js → chunk-ADYZWC5L.js} +12 -12
  34. package/dist/web/server/{chunk-CW6KZUKT.js → chunk-B2LF64HM.js} +1 -1
  35. package/dist/web/server/{chunk-YMPJMHXZ.js → chunk-DP26GVWH.js} +3 -2
  36. package/dist/web/server/chunk-ETCO5KZK.js +113 -0
  37. package/dist/web/server/{chunk-ENGEUJIH.js → chunk-FMAYMBRS.js} +22 -20
  38. package/dist/web/server/{chunk-WB2LJC3R.js → chunk-FTLJ66KU.js} +4 -4
  39. package/dist/web/server/{chunk-OSMP55KI.js → chunk-H5D5DX3K.js} +1 -20
  40. package/dist/web/server/chunk-HGVJEUV4.js +102 -0
  41. package/dist/web/server/{chunk-FT74GAAH.js → chunk-KZ35W5M7.js} +27 -27
  42. package/dist/web/server/{chunk-CCYLHNZJ.js → chunk-O2IC376F.js} +46 -3
  43. package/dist/web/server/chunk-OMPXUTMX.js +33 -0
  44. package/dist/web/server/{chunk-BUXJSBE3.js → chunk-RJNGEU6C.js} +1 -1
  45. package/dist/web/server/{chunk-O2UYZT3Z.js → chunk-T2UTBHJ4.js} +48 -4
  46. package/dist/web/server/{chunk-NMBH57JT.js → chunk-TU2WNRAL.js} +6 -6
  47. package/dist/web/server/{chunk-JPDRUSUD.js → chunk-UM3RHJNZ.js} +1 -1
  48. package/dist/web/server/{chunk-4OTHKQMG.js → chunk-V5IFFLZQ.js} +4 -4
  49. package/dist/web/server/{chunk-EDAWH2MT.js → chunk-XEG4JTND.js} +2 -2
  50. package/dist/web/server/{chunk-NCK2FJAD.js → chunk-XSOUURPF.js} +2 -2
  51. package/dist/web/server/{chunk-ESM7OCRL.js → chunk-YCCF676T.js} +3 -3
  52. package/dist/web/server/{chunk-JVOW2NWC.js → chunk-YDDDSVNB.js} +7 -100
  53. package/dist/web/server/{fork-picker-dialog-YKlapaxN-DR5L74ST.js → fork-picker-dialog-DeMiLZtS-WTRTTP64.js} +4 -3
  54. package/dist/web/server/{message-queue-Demph1x4-RBJUC3AT.js → message-queue-Demph1x4-GGXJUUKO.js} +4 -4
  55. package/dist/web/server/{model-selector-list-BmzLiCx9-TK6JGGKU.js → model-selector-list-BeGQHwKV-UJYFO4KX.js} +9 -8
  56. package/dist/web/server/{openui-renderer-moJGf0LA-QCU3PI6H.js → openui-renderer-B4z18Brm-HSMKJ47D.js} +13 -12
  57. package/dist/web/server/{router-CPdFlpbe-LAD4MNZB.js → router-DfG45nTQ-3VXEUYG5.js} +278 -56
  58. package/dist/web/server/{routes-hkom6S6L-DUPPQHPY.js → routes-B9F9UfF1-UN2IVBMJ.js} +271 -117
  59. package/dist/web/server/server.js +2 -2
  60. package/dist/web/server/{session-tool-renderer-CglQ2ky7-2JVYNZG2.js → session-tool-renderer-CT65wuet-RQBMXHEZ.js} +11 -10
  61. package/dist/web/server/session-tree-panel-rS0t1wbf-HNA6AJBY.js +229 -0
  62. package/dist/web/server/{settings-dialog-BCEfmgtP-T3WQEZHB.js → settings-dialog-CqkrDSnm-LFEKSS7Y.js} +38 -34
  63. package/dist/web/server/{subagent-chat-panel-BTwI1kdB-LKBWA4GD.js → subagent-chat-panel-Cf7QdDqH-DPPSVLSY.js} +18 -17
  64. package/dist/web/server/{subagents-panel-8Z9_csoV-HYMEEBHB.js → subagents-panel-_JsUw-6t-MZWM5P45.js} +18 -17
  65. package/package.json +1 -1
  66. package/dist/web/client/assets/command-Dv96gATQ.js +0 -1
  67. package/dist/web/client/assets/dialog-BCb4rQh0.js +0 -1
  68. package/dist/web/client/assets/globals-DCtBkCSD.css +0 -2
  69. package/dist/web/client/assets/provider-catalog-C0XBIasJ.js +0 -1
  70. package/dist/web/client/assets/provider-label-Cka0ep0S.js +0 -1
  71. package/dist/web/client/assets/right-panel-registry-BCW7fQTG.js +0 -2
  72. package/dist/web/client/assets/routes-BWe5Iz-2.js +0 -16
  73. package/dist/web/client/assets/settings-dialog-B8lHq2tT.js +0 -2
  74. package/dist/web/client/assets/sparkles-D8XIY8pN.js +0 -1
  75. package/dist/web/server/{chunk-43S5N7SH.js → chunk-5RTGRTPD.js} +3 -3
  76. package/dist/web/server/{chunk-OMEDERPG.js → chunk-S2IBIJIG.js} +3 -3
  77. package/dist/web/server/{chunk-IXGLKAPN.js → chunk-TR2GA5OF.js} +3 -3
  78. package/dist/web/server/{workspace-panel-BHEB9nRM-TS62SYBA.js → workspace-panel-BHEB9nRM-Y6KGIVGP.js} +2 -2
@@ -17,6 +17,9 @@ import {
17
17
  QueryClient,
18
18
  QueryClientProvider,
19
19
  SVGVisualElement,
20
+ SessionTreeNavigateRequestSchema,
21
+ SessionTreeNavigateResponseSchema,
22
+ SessionTreeSnapshotResponseSchema,
20
23
  addValueToWillChange,
21
24
  animateMotionValue,
22
25
  animateSingleValue,
@@ -44,7 +47,7 @@ import {
44
47
  scalePoint,
45
48
  transformBox,
46
49
  translateAxis
47
- } from "./chunk-CCYLHNZJ.js";
50
+ } from "./chunk-O2IC376F.js";
48
51
  import {
49
52
  DEFAULT_UI_PREFERENCES,
50
53
  applyUiPreferencesToDocument,
@@ -52,7 +55,7 @@ import {
52
55
  } from "./chunk-4EBSM4JR.js";
53
56
  import {
54
57
  Toaster
55
- } from "./chunk-IXGLKAPN.js";
58
+ } from "./chunk-TR2GA5OF.js";
56
59
  import {
57
60
  fallbackSessionLabel,
58
61
  meaningfulSessionLabel,
@@ -106,7 +109,7 @@ import {
106
109
  CardHeader,
107
110
  CardTitle,
108
111
  validateAndNormalizeOpenUIHtmlArtifact
109
- } from "./chunk-JPDRUSUD.js";
112
+ } from "./chunk-UM3RHJNZ.js";
110
113
  import {
111
114
  ChatNewRequestSchema,
112
115
  ChatOpenUIArtifactUpsertRequestSchema,
@@ -126,7 +129,7 @@ import {
126
129
  UploadedAttachmentSchema,
127
130
  ZodError,
128
131
  external_exports
129
- } from "./chunk-YMPJMHXZ.js";
132
+ } from "./chunk-DP26GVWH.js";
130
133
  import {
131
134
  KNOWN_PROVIDERS,
132
135
  OPENAI_CHAT_COMPLETIONS_PROVIDER_ID,
@@ -141,9 +144,9 @@ import {
141
144
  toInstanceSlug,
142
145
  toOccInstanceId
143
146
  } from "./chunk-RJOANOT4.js";
147
+ import "./chunk-JBLHIEVG.js";
144
148
  import "./chunk-HQ5TEXHT.js";
145
149
  import "./chunk-TLNZNR7C.js";
146
- import "./chunk-JBLHIEVG.js";
147
150
  import "./chunk-XJ6TGSUB.js";
148
151
  import "./chunk-HFQZLPU2.js";
149
152
  import "./chunk-4ZIEVI5O.js";
@@ -161,7 +164,7 @@ import "./chunk-JDCCC7A7.js";
161
164
  import "./chunk-L547YHC4.js";
162
165
  import "./chunk-MLKGABMK.js";
163
166
 
164
- // web/app/dist/server/assets/router-CPdFlpbe.js
167
+ // web/app/dist/server/assets/router-DfG45nTQ.js
165
168
  import { Component, Fragment, useContext, useEffect, useLayoutEffect, useRef, useState } from "react";
166
169
  import { jsx, jsxs } from "react/jsx-runtime";
167
170
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -3076,7 +3079,7 @@ function MotionRuntime({ children }) {
3076
3079
  })
3077
3080
  });
3078
3081
  }
3079
- var globals_default = "/assets/globals-DCtBkCSD.css";
3082
+ var globals_default = "/assets/globals-BtCXZXL_.css";
3080
3083
  function makeQueryClient() {
3081
3084
  return new QueryClient({ defaultOptions: { queries: {
3082
3085
  staleTime: 6e4,
@@ -3090,7 +3093,7 @@ function getQueryClient() {
3090
3093
  if (!browserQueryClient) browserQueryClient = makeQueryClient();
3091
3094
  return browserQueryClient;
3092
3095
  }
3093
- var Route$26 = createRootRoute({
3096
+ var Route$27 = createRootRoute({
3094
3097
  head: () => ({
3095
3098
  meta: [
3096
3099
  { charSet: "utf-8" },
@@ -3158,8 +3161,8 @@ function RootDocument({ children }) {
3158
3161
  ] })]
3159
3162
  });
3160
3163
  }
3161
- var $$splitComponentImporter = () => import("./routes-hkom6S6L-DUPPQHPY.js");
3162
- var Route$25 = createFileRoute("/")({ component: lazyRouteComponent($$splitComponentImporter, "component") });
3164
+ var $$splitComponentImporter = () => import("./routes-B9F9UfF1-UN2IVBMJ.js");
3165
+ var Route$26 = createFileRoute("/")({ component: lazyRouteComponent($$splitComponentImporter, "component") });
3163
3166
  var ManagedAttachmentValidationError = class extends Error {
3164
3167
  status;
3165
3168
  constructor(message, status) {
@@ -3971,8 +3974,8 @@ var openUIPromptSpec = {
3971
3974
  description: "A button that triggers interactive actions or conversational updates."
3972
3975
  },
3973
3976
  PanelAction: {
3974
- signature: 'PanelAction(label: string, panel: "resources" | "workspace" | "artifacts" | "repl" | "subagents" | "session-insights", relativePath?: any, focus?: boolean)',
3975
- description: "A trusted local action that opens Resources, Workspace, Artifacts, REPL, Subagents, or Session insights. relativePath selects a contained workspace-relative path and is valid only for Workspace and Artifacts panels."
3977
+ signature: 'PanelAction(label: string, panel: "resources" | "workspace" | "artifacts" | "repl" | "subagents" | "session-insights" | "session-tree", relativePath?: any, focus?: boolean)',
3978
+ description: "A trusted local action that opens Resources, Workspace, Artifacts, REPL, Subagents, Session insights, or Session tree. relativePath selects a contained workspace-relative path and is valid only for Workspace and Artifacts panels."
3976
3979
  },
3977
3980
  Input: {
3978
3981
  signature: 'Input(name: string, value: $binding<string>, placeholder?: string, type?: "text" | "email" | "number" | "password" | "search", disabled?: boolean)',
@@ -4296,7 +4299,8 @@ var openUIPromptSpec = {
4296
4299
  "artifacts",
4297
4300
  "repl",
4298
4301
  "subagents",
4299
- "session-insights"
4302
+ "session-insights",
4303
+ "session-tree"
4300
4304
  ]
4301
4305
  },
4302
4306
  relativePath: { type: "string" },
@@ -4311,7 +4315,7 @@ var openUIPromptSpec = {
4311
4315
  "focus"
4312
4316
  ],
4313
4317
  additionalProperties: false,
4314
- description: "A trusted local action that opens Resources, Workspace, Artifacts, REPL, Subagents, or Session insights. relativePath selects a contained workspace-relative path and is valid only for Workspace and Artifacts panels."
4318
+ description: "A trusted local action that opens Resources, Workspace, Artifacts, REPL, Subagents, Session insights, or Session tree. relativePath selects a contained workspace-relative path and is valid only for Workspace and Artifacts panels."
4315
4319
  },
4316
4320
  Input: {
4317
4321
  type: "object",
@@ -7463,6 +7467,123 @@ var RingBuffer = class {
7463
7467
  this.nextSeq = 1;
7464
7468
  }
7465
7469
  };
7470
+ var SessionTreeBusyError = class extends Error {
7471
+ status = 409;
7472
+ constructor() {
7473
+ super("Session is still streaming. Stop the current turn before rewinding.");
7474
+ this.name = "SessionTreeBusyError";
7475
+ }
7476
+ };
7477
+ var SessionTreeConcurrencyError = class extends Error {
7478
+ status = 409;
7479
+ constructor() {
7480
+ super("The session tree changed while you were selecting a rewind target. Refresh and try again.");
7481
+ this.name = "SessionTreeConcurrencyError";
7482
+ }
7483
+ };
7484
+ var SessionTreeCancelledError = class extends Error {
7485
+ status = 409;
7486
+ constructor() {
7487
+ super("Session tree navigation was cancelled. Refresh and try again.");
7488
+ this.name = "SessionTreeCancelledError";
7489
+ }
7490
+ };
7491
+ function messageContentToText(content) {
7492
+ if (typeof content === "string") return content;
7493
+ if (!Array.isArray(content)) return "";
7494
+ return content.filter((part) => typeof part === "object" && part !== null && part.type === "text" && typeof part.text === "string").map((part) => part.text).join(" ");
7495
+ }
7496
+ function entryPreview(node) {
7497
+ const { entry } = node;
7498
+ if (entry.type === "message" && entry.message) {
7499
+ const role = entry.message.role ?? "message";
7500
+ const oneLine = messageContentToText(entry.message.content).replace(/\s+/g, " ").trim();
7501
+ return `${role}: ${oneLine.length > 72 ? `${oneLine.slice(0, 72)}\u2026` : oneLine}`;
7502
+ }
7503
+ return entry.label ?? node.label ?? entry.type;
7504
+ }
7505
+ function entryKind(entry) {
7506
+ if (entry.type === "message") return "message";
7507
+ if (entry.type === "system" || entry.type === "compaction" || entry.type === "model_change") return "system";
7508
+ return "other";
7509
+ }
7510
+ function entryRole(entry) {
7511
+ if (entry.type !== "message" || !entry.message?.role) return void 0;
7512
+ switch (entry.message.role) {
7513
+ case "user":
7514
+ return "user";
7515
+ case "assistant":
7516
+ return "assistant";
7517
+ case "system":
7518
+ return "system";
7519
+ default:
7520
+ return "unknown";
7521
+ }
7522
+ }
7523
+ function findActiveBranchPath(nodes, leafId) {
7524
+ const active = /* @__PURE__ */ new Set();
7525
+ if (!leafId) return active;
7526
+ const walk = (items) => {
7527
+ for (const node of items) {
7528
+ if (node.entry.id === leafId) {
7529
+ active.add(node.entry.id);
7530
+ return true;
7531
+ }
7532
+ if (walk(node.children)) {
7533
+ active.add(node.entry.id);
7534
+ return true;
7535
+ }
7536
+ }
7537
+ return false;
7538
+ };
7539
+ walk(nodes);
7540
+ return active;
7541
+ }
7542
+ function buildMessageIndexByEntryId(nodes, leafId) {
7543
+ const activePath = findActiveBranchPath(nodes, leafId);
7544
+ const messageIndexByEntryId = /* @__PURE__ */ new Map();
7545
+ let messageIndex = 0;
7546
+ const walk = (items) => {
7547
+ for (const node of items) {
7548
+ if (!activePath.has(node.entry.id)) continue;
7549
+ if (node.entry.type === "message") {
7550
+ messageIndexByEntryId.set(node.entry.id, messageIndex);
7551
+ messageIndex += 1;
7552
+ }
7553
+ walk(node.children);
7554
+ return;
7555
+ }
7556
+ };
7557
+ walk(nodes);
7558
+ return messageIndexByEntryId;
7559
+ }
7560
+ function mapNode(node, leafId, activePath, messageIndexByEntryId) {
7561
+ const preview = entryPreview(node);
7562
+ const role = entryRole(node.entry);
7563
+ const messageIndex = messageIndexByEntryId.get(node.entry.id);
7564
+ return {
7565
+ id: node.entry.id,
7566
+ ...node.entry.parentId ? { parentId: node.entry.parentId } : {},
7567
+ kind: entryKind(node.entry),
7568
+ ...role ? { role } : {},
7569
+ label: node.entry.label ?? node.label ?? node.entry.type,
7570
+ preview,
7571
+ isLeaf: node.entry.id === leafId,
7572
+ isOnActiveBranch: activePath.has(node.entry.id),
7573
+ ...messageIndex !== void 0 ? { messageIndex } : {},
7574
+ children: node.children.map((child) => mapNode(child, leafId, activePath, messageIndexByEntryId))
7575
+ };
7576
+ }
7577
+ function mapSessionTreeSnapshot(sessionId, nodes, leafId) {
7578
+ const upstreamNodes = nodes;
7579
+ const activePath = findActiveBranchPath(upstreamNodes, leafId);
7580
+ const messageIndexByEntryId = buildMessageIndexByEntryId(upstreamNodes, leafId);
7581
+ return {
7582
+ sessionId,
7583
+ leafId,
7584
+ nodes: upstreamNodes.map((node) => mapNode(node, leafId, activePath, messageIndexByEntryId))
7585
+ };
7586
+ }
7466
7587
  var WEB_UI_UNSUPPORTED = "Not available in the web UI";
7467
7588
  function unsupportedInWebUi(method) {
7468
7589
  throw new Error(`${method}: ${WEB_UI_UNSUPPORTED}`);
@@ -7774,6 +7895,7 @@ var PrimeBridge = class {
7774
7895
  #childPromptStarter;
7775
7896
  #childPrompts = /* @__PURE__ */ new Map();
7776
7897
  #caches = /* @__PURE__ */ new Map();
7898
+ #sessionTreeNavigationQueues = /* @__PURE__ */ new Map();
7777
7899
  #openUIPromptTransitions = /* @__PURE__ */ new Map();
7778
7900
  #daemonDialogs = /* @__PURE__ */ new Map();
7779
7901
  #auxiliaryWarnings = /* @__PURE__ */ new Set();
@@ -7869,6 +7991,7 @@ var PrimeBridge = class {
7869
7991
  this.#presentationWrites.clear();
7870
7992
  this.#presentationGenerations.clear();
7871
7993
  this.#caches.clear();
7994
+ this.#sessionTreeNavigationQueues.clear();
7872
7995
  this.#openUIPromptTransitions.clear();
7873
7996
  this.#daemonDialogs.clear();
7874
7997
  this.#auxiliaryWarnings.clear();
@@ -8734,8 +8857,12 @@ var PrimeBridge = class {
8734
8857
  /** /tree — session-tree navigation via navigateTree (requires entry id). */
8735
8858
  async navigateTree(sessionId, targetId) {
8736
8859
  const session = this.#requireSession(sessionId);
8737
- await session.connection.navigateTree(targetId, {});
8738
- await deleteManagedPlanPresentationsForSession(sessionId, session.sessionPath);
8860
+ await this.#withSessionTreeNavigationLock(sessionId, async () => {
8861
+ await session.connection.waitForIdle();
8862
+ await session.connection.navigateTree(targetId, {});
8863
+ await this.#refreshSessionTreeCache(sessionId, session.connection);
8864
+ await deleteManagedPlanPresentationsForSession(sessionId, session.sessionPath);
8865
+ });
8739
8866
  }
8740
8867
  /** /tree — the session's entry tree plus the current leaf, for pickers. */
8741
8868
  getSessionTree(sessionId) {
@@ -8747,6 +8874,43 @@ var PrimeBridge = class {
8747
8874
  leafId: null
8748
8875
  };
8749
8876
  }
8877
+ async #refreshSessionTreeCache(sessionId, connection) {
8878
+ const tree = await connection.getSessionTree();
8879
+ const cache = this.#caches.get(sessionId) ?? emptyCache();
8880
+ cache.tree = {
8881
+ tree: tree.tree,
8882
+ leafId: tree.leafId
8883
+ };
8884
+ this.#caches.set(sessionId, cache);
8885
+ }
8886
+ async #withSessionTreeNavigationLock(sessionId, operation) {
8887
+ const current = (this.#sessionTreeNavigationQueues.get(sessionId) ?? Promise.resolve()).catch(() => void 0).then(operation);
8888
+ const tail = current.then(() => void 0, () => void 0);
8889
+ this.#sessionTreeNavigationQueues.set(sessionId, tail);
8890
+ tail.then(() => {
8891
+ if (this.#sessionTreeNavigationQueues.get(sessionId) === tail) this.#sessionTreeNavigationQueues.delete(sessionId);
8892
+ });
8893
+ return current;
8894
+ }
8895
+ /** Reads a browser-safe session tree snapshot from the live connection. */
8896
+ async readSessionTreeSnapshot(sessionId) {
8897
+ const session = this.#requireSession(sessionId);
8898
+ await this.#refreshSessionTreeCache(sessionId, session.connection);
8899
+ const cached = this.getSessionTree(sessionId);
8900
+ return mapSessionTreeSnapshot(sessionId, cached.tree, cached.leafId);
8901
+ }
8902
+ /** Navigates the live session tree and returns the authoritative browser-safe snapshot. */
8903
+ async navigateSessionTree(sessionId, targetEntryId, expectedLeafId) {
8904
+ const session = this.#requireSession(sessionId);
8905
+ return this.#withSessionTreeNavigationLock(sessionId, async () => {
8906
+ await session.connection.waitForIdle();
8907
+ const before = await session.connection.getSessionTree();
8908
+ if (expectedLeafId && before.leafId !== expectedLeafId) throw new SessionTreeConcurrencyError();
8909
+ if ((await session.connection.navigateTree(targetEntryId, {})).cancelled) throw new SessionTreeCancelledError();
8910
+ await deleteManagedPlanPresentationsForSession(sessionId, session.sessionPath);
8911
+ return this.readSessionTreeSnapshot(sessionId);
8912
+ });
8913
+ }
8750
8914
  /**
8751
8915
  * /fork and /clone — branch the session at `entryId` into a NEW live session.
8752
8916
  *
@@ -39560,6 +39724,54 @@ function handleHealthGet(request) {
39560
39724
  });
39561
39725
  }, request);
39562
39726
  }
39727
+ async function requireReadableSession(sessionId) {
39728
+ const bridge = getBridge();
39729
+ const session = bridge.getSession(sessionId) ?? await bridge.resumeSessionById(sessionId);
39730
+ if (!await requireProjectSession(session)) return {
39731
+ ok: false,
39732
+ response: Response.json({ message: `Unknown session: ${sessionId}` }, { status: 404 })
39733
+ };
39734
+ return {
39735
+ ok: true,
39736
+ session
39737
+ };
39738
+ }
39739
+ async function requireWritableSession(sessionId) {
39740
+ const access = await requireReadableSession(sessionId);
39741
+ if (!access.ok) return access;
39742
+ const { session } = access;
39743
+ if (session?.isStreaming) return {
39744
+ ok: false,
39745
+ response: Response.json({ message: new SessionTreeBusyError().message }, { status: 409 })
39746
+ };
39747
+ return access;
39748
+ }
39749
+ function handleChatSessionTreeGet(request) {
39750
+ return wrapApiHandler(async () => {
39751
+ const sessionId = new URL(request.url).searchParams.get("sessionId");
39752
+ if (!sessionId) return Response.json({ message: "GET /api/chat/session-tree requires ?sessionId=" }, { status: 400 });
39753
+ const parsedSessionId = SessionIdSchema.safeParse(sessionId);
39754
+ if (!parsedSessionId.success) return Response.json({ message: "Invalid session id" }, { status: 400 });
39755
+ const access = await requireReadableSession(parsedSessionId.data);
39756
+ if (!access.ok) return access.response;
39757
+ const snapshot2 = await getBridge().readSessionTreeSnapshot(parsedSessionId.data);
39758
+ return Response.json(SessionTreeSnapshotResponseSchema.parse({ snapshot: snapshot2 }));
39759
+ }, request);
39760
+ }
39761
+ function handleChatSessionTreeNavigatePost(request) {
39762
+ return wrapApiHandler(async () => {
39763
+ const body = SessionTreeNavigateRequestSchema.parse(await request.json().catch(() => ({})));
39764
+ const access = await requireWritableSession(body.sessionId);
39765
+ if (!access.ok) return access.response;
39766
+ try {
39767
+ const snapshot2 = await getBridge().navigateSessionTree(body.sessionId, body.targetEntryId, body.expectedLeafId);
39768
+ return Response.json(SessionTreeNavigateResponseSchema.parse({ snapshot: snapshot2 }));
39769
+ } catch (error) {
39770
+ if (error instanceof SessionTreeConcurrencyError || error instanceof SessionTreeCancelledError) return Response.json({ message: error.message }, { status: error.status });
39771
+ throw error;
39772
+ }
39773
+ }, request);
39774
+ }
39563
39775
  function canonicalizePath(path) {
39564
39776
  try {
39565
39777
  return realpathSync(path);
@@ -39761,40 +39973,44 @@ function handleWorkspaceTreeGet(_request) {
39761
39973
  });
39762
39974
  }, _request);
39763
39975
  }
39764
- var Route$24 = createFileRoute("/api/chat")({ server: { handlers: { POST: ({ request }) => handleChatPost(request) } } });
39765
- var Route$23 = createFileRoute("/api/health")({ server: { handlers: { GET: ({ request }) => handleHealthGet(request) } } });
39766
- var Route$22 = createFileRoute("/api/projects")({ server: { handlers: {
39976
+ var Route$25 = createFileRoute("/api/chat")({ server: { handlers: { POST: ({ request }) => handleChatPost(request) } } });
39977
+ var Route$24 = createFileRoute("/api/health")({ server: { handlers: { GET: ({ request }) => handleHealthGet(request) } } });
39978
+ var Route$23 = createFileRoute("/api/projects")({ server: { handlers: {
39767
39979
  DELETE: ({ request }) => handleProjectDelete(request),
39768
39980
  GET: ({ request }) => handleProjectsGet(request),
39769
39981
  PATCH: ({ request }) => handleProjectPatch(request),
39770
39982
  POST: ({ request }) => handleProjectsPost(request)
39771
39983
  } } });
39772
- var Route$21 = createFileRoute("/api/chat/abort")({ server: { handlers: { POST: ({ request }) => handleChatAbortPost(request) } } });
39773
- var Route$20 = createFileRoute("/api/chat/artifacts")({ server: { handlers: { PUT: ({ request }) => handleChatOpenUIArtifactPut(request) } } });
39774
- var Route$19 = createFileRoute("/api/chat/command")({ server: { handlers: { POST: ({ request }) => handleChatCommandPost(request) } } });
39775
- var Route$18 = createFileRoute("/api/chat/commands")({ server: { handlers: { GET: ({ request }) => handleChatCommandsGet(request) } } });
39776
- var Route$17 = createFileRoute("/api/chat/events")({ server: { handlers: { GET: ({ request }) => handleChatEventsGet(request) } } });
39777
- var Route$16 = createFileRoute("/api/chat/mcp")({ server: { handlers: {
39984
+ var Route$22 = createFileRoute("/api/chat/abort")({ server: { handlers: { POST: ({ request }) => handleChatAbortPost(request) } } });
39985
+ var Route$21 = createFileRoute("/api/chat/artifacts")({ server: { handlers: { PUT: ({ request }) => handleChatOpenUIArtifactPut(request) } } });
39986
+ var Route$20 = createFileRoute("/api/chat/command")({ server: { handlers: { POST: ({ request }) => handleChatCommandPost(request) } } });
39987
+ var Route$19 = createFileRoute("/api/chat/commands")({ server: { handlers: { GET: ({ request }) => handleChatCommandsGet(request) } } });
39988
+ var Route$18 = createFileRoute("/api/chat/events")({ server: { handlers: { GET: ({ request }) => handleChatEventsGet(request) } } });
39989
+ var Route$17 = createFileRoute("/api/chat/mcp")({ server: { handlers: {
39778
39990
  GET: ({ request }) => handleChatMcpGet(request),
39779
39991
  POST: ({ request }) => handleChatMcpPost(request),
39780
39992
  DELETE: ({ request }) => handleChatMcpDelete(request)
39781
39993
  } } });
39782
- var Route$15 = createFileRoute("/api/chat/models")({ server: { handlers: { GET: ({ request }) => handleChatModelsGet(request) } } });
39783
- var Route$14 = createFileRoute("/api/chat/new")({ server: { handlers: { POST: ({ request }) => handleChatNewPost(request) } } });
39784
- var Route$13 = createFileRoute("/api/chat/providers")({ server: { handlers: {
39994
+ var Route$16 = createFileRoute("/api/chat/models")({ server: { handlers: { GET: ({ request }) => handleChatModelsGet(request) } } });
39995
+ var Route$15 = createFileRoute("/api/chat/new")({ server: { handlers: { POST: ({ request }) => handleChatNewPost(request) } } });
39996
+ var Route$14 = createFileRoute("/api/chat/providers")({ server: { handlers: {
39785
39997
  GET: ({ request }) => handleChatProvidersGet(request),
39786
39998
  POST: ({ request }) => handleChatProvidersPost(request),
39787
39999
  DELETE: ({ request }) => handleChatProvidersDelete(request)
39788
40000
  } } });
39789
- var Route$12 = createFileRoute("/api/chat/question")({ server: { handlers: { POST: ({ request }) => handleChatQuestionPost(request) } } });
39790
- var Route$11 = createFileRoute("/api/chat/resources")({ server: { handlers: { GET: ({ request }) => handleChatResourcesGet(request) } } });
39791
- var Route$10 = createFileRoute("/api/chat/resume")({ server: { handlers: { POST: ({ request }) => handleChatResumePost(request) } } });
39792
- var Route$9 = createFileRoute("/api/chat/session")({ server: { handlers: {
40001
+ var Route$13 = createFileRoute("/api/chat/question")({ server: { handlers: { POST: ({ request }) => handleChatQuestionPost(request) } } });
40002
+ var Route$12 = createFileRoute("/api/chat/resources")({ server: { handlers: { GET: ({ request }) => handleChatResourcesGet(request) } } });
40003
+ var Route$11 = createFileRoute("/api/chat/resume")({ server: { handlers: { POST: ({ request }) => handleChatResumePost(request) } } });
40004
+ var Route$10 = createFileRoute("/api/chat/session")({ server: { handlers: {
39793
40005
  GET: ({ request }) => new URL(request.url).searchParams.has("attachmentId") ? handleChatAttachmentGet(request) : handleChatSessionGet(request),
39794
40006
  POST: ({ request }) => handleChatAttachmentsPost(request),
39795
40007
  PUT: ({ request }) => handleChatPlanPresentationPut(request),
39796
40008
  PATCH: ({ request }) => handleChatQueueMutationPost(request)
39797
40009
  } } });
40010
+ var Route$9 = createFileRoute("/api/chat/session-tree")({ server: { handlers: {
40011
+ GET: ({ request }) => handleChatSessionTreeGet(request),
40012
+ POST: ({ request }) => handleChatSessionTreeNavigatePost(request)
40013
+ } } });
39798
40014
  var Route$8 = createFileRoute("/api/chat/sessions")({ server: { handlers: {
39799
40015
  DELETE: ({ request }) => handleChatSessionDelete(request),
39800
40016
  GET: ({ request }) => handleChatSessionsGet(request),
@@ -39811,91 +40027,96 @@ var Route$3 = createFileRoute("/api/workspace/tree")({ server: { handlers: { GET
39811
40027
  var Route$2 = createFileRoute("/api/chat/mcp/oauth")({ server: { handlers: { POST: ({ request }) => handleChatMcpOAuthPost(request) } } });
39812
40028
  var Route$1 = createFileRoute("/api/chat/models/discover")({ server: { handlers: { POST: ({ request }) => handleChatModelsDiscoverPost(request) } } });
39813
40029
  var Route = createFileRoute("/api/chat/providers/oauth")({ server: { handlers: { POST: ({ request }) => handleChatProvidersOAuthPost(request) } } });
39814
- var IndexRoute = Route$25.update({
40030
+ var IndexRoute = Route$26.update({
39815
40031
  id: "/",
39816
40032
  path: "/",
39817
- getParentRoute: () => Route$26
40033
+ getParentRoute: () => Route$27
39818
40034
  });
39819
- var ApiChatRoute = Route$24.update({
40035
+ var ApiChatRoute = Route$25.update({
39820
40036
  id: "/api/chat",
39821
40037
  path: "/api/chat",
39822
- getParentRoute: () => Route$26
40038
+ getParentRoute: () => Route$27
39823
40039
  });
39824
- var ApiHealthRoute = Route$23.update({
40040
+ var ApiHealthRoute = Route$24.update({
39825
40041
  id: "/api/health",
39826
40042
  path: "/api/health",
39827
- getParentRoute: () => Route$26
40043
+ getParentRoute: () => Route$27
39828
40044
  });
39829
- var ApiProjectsRoute = Route$22.update({
40045
+ var ApiProjectsRoute = Route$23.update({
39830
40046
  id: "/api/projects",
39831
40047
  path: "/api/projects",
39832
- getParentRoute: () => Route$26
40048
+ getParentRoute: () => Route$27
39833
40049
  });
39834
- var ApiChatAbortRoute = Route$21.update({
40050
+ var ApiChatAbortRoute = Route$22.update({
39835
40051
  id: "/abort",
39836
40052
  path: "/abort",
39837
40053
  getParentRoute: () => ApiChatRoute
39838
40054
  });
39839
- var ApiChatArtifactsRoute = Route$20.update({
40055
+ var ApiChatArtifactsRoute = Route$21.update({
39840
40056
  id: "/artifacts",
39841
40057
  path: "/artifacts",
39842
40058
  getParentRoute: () => ApiChatRoute
39843
40059
  });
39844
- var ApiChatCommandRoute = Route$19.update({
40060
+ var ApiChatCommandRoute = Route$20.update({
39845
40061
  id: "/command",
39846
40062
  path: "/command",
39847
40063
  getParentRoute: () => ApiChatRoute
39848
40064
  });
39849
- var ApiChatCommandsRoute = Route$18.update({
40065
+ var ApiChatCommandsRoute = Route$19.update({
39850
40066
  id: "/commands",
39851
40067
  path: "/commands",
39852
40068
  getParentRoute: () => ApiChatRoute
39853
40069
  });
39854
- var ApiChatEventsRoute = Route$17.update({
40070
+ var ApiChatEventsRoute = Route$18.update({
39855
40071
  id: "/events",
39856
40072
  path: "/events",
39857
40073
  getParentRoute: () => ApiChatRoute
39858
40074
  });
39859
- var ApiChatMcpRoute = Route$16.update({
40075
+ var ApiChatMcpRoute = Route$17.update({
39860
40076
  id: "/mcp",
39861
40077
  path: "/mcp",
39862
40078
  getParentRoute: () => ApiChatRoute
39863
40079
  });
39864
- var ApiChatModelsRoute = Route$15.update({
40080
+ var ApiChatModelsRoute = Route$16.update({
39865
40081
  id: "/models",
39866
40082
  path: "/models",
39867
40083
  getParentRoute: () => ApiChatRoute
39868
40084
  });
39869
- var ApiChatNewRoute = Route$14.update({
40085
+ var ApiChatNewRoute = Route$15.update({
39870
40086
  id: "/new",
39871
40087
  path: "/new",
39872
40088
  getParentRoute: () => ApiChatRoute
39873
40089
  });
39874
- var ApiChatProvidersRoute = Route$13.update({
40090
+ var ApiChatProvidersRoute = Route$14.update({
39875
40091
  id: "/providers",
39876
40092
  path: "/providers",
39877
40093
  getParentRoute: () => ApiChatRoute
39878
40094
  });
39879
- var ApiChatQuestionRoute = Route$12.update({
40095
+ var ApiChatQuestionRoute = Route$13.update({
39880
40096
  id: "/question",
39881
40097
  path: "/question",
39882
40098
  getParentRoute: () => ApiChatRoute
39883
40099
  });
39884
- var ApiChatResourcesRoute = Route$11.update({
40100
+ var ApiChatResourcesRoute = Route$12.update({
39885
40101
  id: "/resources",
39886
40102
  path: "/resources",
39887
40103
  getParentRoute: () => ApiChatRoute
39888
40104
  });
39889
- var ApiChatResumeRoute = Route$10.update({
40105
+ var ApiChatResumeRoute = Route$11.update({
39890
40106
  id: "/resume",
39891
40107
  path: "/resume",
39892
40108
  getParentRoute: () => ApiChatRoute
39893
40109
  });
39894
- var ApiChatSessionRoute = Route$9.update({
40110
+ var ApiChatSessionRoute = Route$10.update({
39895
40111
  id: "/session",
39896
40112
  path: "/session",
39897
40113
  getParentRoute: () => ApiChatRoute
39898
40114
  });
40115
+ var ApiChatSessionTreeRoute = Route$9.update({
40116
+ id: "/session-tree",
40117
+ path: "/session-tree",
40118
+ getParentRoute: () => ApiChatRoute
40119
+ });
39899
40120
  var ApiChatSessionsRoute = Route$8.update({
39900
40121
  id: "/sessions",
39901
40122
  path: "/sessions",
@@ -39919,12 +40140,12 @@ var ApiProjectsForkRoute = Route$5.update({
39919
40140
  var ApiWorkspaceFileRoute = Route$4.update({
39920
40141
  id: "/api/workspace/file",
39921
40142
  path: "/api/workspace/file",
39922
- getParentRoute: () => Route$26
40143
+ getParentRoute: () => Route$27
39923
40144
  });
39924
40145
  var ApiWorkspaceTreeRoute = Route$3.update({
39925
40146
  id: "/api/workspace/tree",
39926
40147
  path: "/api/workspace/tree",
39927
- getParentRoute: () => Route$26
40148
+ getParentRoute: () => Route$27
39928
40149
  });
39929
40150
  var ApiChatMcpOauthRoute = Route$2.update({
39930
40151
  id: "/oauth",
@@ -39960,6 +40181,7 @@ var ApiChatRouteChildren = {
39960
40181
  ApiChatResourcesRoute,
39961
40182
  ApiChatResumeRoute,
39962
40183
  ApiChatSessionRoute,
40184
+ ApiChatSessionTreeRoute,
39963
40185
  ApiChatSessionsRoute,
39964
40186
  ApiChatSettingsRoute
39965
40187
  };
@@ -39976,7 +40198,7 @@ var rootRouteChildren = {
39976
40198
  ApiWorkspaceFileRoute,
39977
40199
  ApiWorkspaceTreeRoute
39978
40200
  };
39979
- var routeTree = Route$26._addFileChildren(rootRouteChildren)._addFileTypes();
40201
+ var routeTree = Route$27._addFileChildren(rootRouteChildren)._addFileTypes();
39980
40202
  function getRouter() {
39981
40203
  return createRouter({
39982
40204
  routeTree,