@qredence/fleet 0.6.4 → 0.6.5

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 (46) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/web/client/assets/{chat-command-palette-DdPlRVuL.js → chat-command-palette-AjGusIEp.js} +1 -1
  3. package/dist/web/client/assets/{create-project-dialog-CaXurRpm.js → create-project-dialog-zTSeGUup.js} +1 -1
  4. package/dist/web/client/assets/globals-BiAbxPQ2.css +2 -0
  5. package/dist/web/client/assets/{index-BJIGh8ag.js → index-NhnAdIsR.js} +2 -2
  6. package/dist/web/client/assets/{message-queue-CPYj2iaw.js → message-queue-BoNn57Po.js} +1 -1
  7. package/dist/web/client/assets/prompt-input-BhVQxoyh.js +1 -0
  8. package/dist/web/client/assets/{prompt-suggestions-ULqmPijZ.js → prompt-suggestions-BRFWFm5y.js} +1 -1
  9. package/dist/web/client/assets/right-panel-registry-gwgnEeUz.js +2 -0
  10. package/dist/web/client/assets/routes-umGEy_Ak.js +16 -0
  11. package/dist/web/client/assets/{settings-dialog-BRWheaBZ.js → settings-dialog-C8YN5D1V.js} +1 -1
  12. package/dist/web/client/assets/{subagent-chat-panel-B6d4Z3bV.js → subagent-chat-panel-BIsmzS45.js} +1 -1
  13. package/dist/web/client/assets/{subagent-transcript-CQuPs6N4.js → subagent-transcript-CEUBL9sF.js} +1 -1
  14. package/dist/web/client/assets/{subagents-panel-ajf--C_-.js → subagents-panel-CFxWpUT0.js} +1 -1
  15. package/dist/web/client/assets/{tokens-BcUIpW6Y.js → tokens-CtP2s1Y3.js} +1 -1
  16. package/dist/web/client/assets/types-D5hZ8IyV.js +1 -0
  17. package/dist/web/client/assets/virtualized-turn-list-DkJIWXFJ.js +6 -0
  18. package/dist/web/client/bundle-budget.json +6 -6
  19. package/dist/web/server/{_tanstack-start-manifest_v-BZR0i182-OLTGGEDQ.js → _tanstack-start-manifest_v-B3Gb4p5p-DO2GL5VM.js} +9 -10
  20. package/dist/web/server/{artifacts-panel-BySfu7im-AKBWHYJS.js → artifacts-panel-CGgpyc85-V3KXDVAX.js} +2 -2
  21. package/dist/web/server/{chat-command-palette-BLGKnp-w-OKFIKD3T.js → chat-command-palette-BMR7RsuI-U5S4X44U.js} +2 -2
  22. package/dist/web/server/{chunk-4B2PJSK5.js → chunk-5TXDGMCK.js} +14 -4
  23. package/dist/web/server/{chunk-ONWT54IL.js → chunk-BS4D5LRR.js} +5 -1
  24. package/dist/web/server/{chunk-JLGBOCFM.js → chunk-ELRLMFHT.js} +49 -33
  25. package/dist/web/server/{chunk-JZ2WBCIH.js → chunk-G6NMFFZX.js} +624 -624
  26. package/dist/web/server/{chunk-47TH5VUT.js → chunk-LBUHLBKK.js} +2 -2
  27. package/dist/web/server/{chunk-2GQATGF4.js → chunk-N47UN47Y.js} +3 -3
  28. package/dist/web/server/{chunk-CIE2PLNB.js → chunk-PX7B5BTI.js} +2 -2
  29. package/dist/web/server/{chunk-NHZRY22Z.js → chunk-SOZKLVNI.js} +59 -19
  30. package/dist/web/server/{create-project-dialog-CigfFgAj-QS27NAJH.js → create-project-dialog-xhTWmcx1-UQQU3MAT.js} +2 -2
  31. package/dist/web/server/{message-queue-BsrLcNPX-CUCBSF6U.js → message-queue-Dg2okv2L-SJTUUJS7.js} +4 -4
  32. package/dist/web/server/{openui-renderer-TbIFXEW2-BET2OXM2.js → openui-renderer-CiWvcD3p-N6I66FOC.js} +1 -1
  33. package/dist/web/server/{prompt-suggestions-D6RXFQF4-7WHYRNMN.js → prompt-suggestions-h17Gu7u1-BS5SU2FY.js} +2 -2
  34. package/dist/web/server/{router-RPObiwZR-AFMFSYSZ.js → router-DOPFvRSC-G7G75P7U.js} +84 -28
  35. package/dist/web/server/{routes-Dn-deuPY-MDXEQXRU.js → routes-i2Ai-ZwX-SMSFONDQ.js} +469 -352
  36. package/dist/web/server/server.js +2 -2
  37. package/dist/web/server/{settings-dialog-CzeangBl-YKL7CLPF.js → settings-dialog-C-xwPYy8-TFICZWEM.js} +7 -7
  38. package/dist/web/server/{subagent-chat-panel-Fa31QewE-YDPOKN74.js → subagent-chat-panel-VEVu0QXU-DPWJFCYR.js} +5 -4
  39. package/dist/web/server/{subagents-panel-DjOcQxp4-GZYOZOYC.js → subagents-panel-Cs3cBcsy-HTQBIYAS.js} +4 -3
  40. package/package.json +1 -1
  41. package/dist/web/client/assets/globals-B-fD_O7k.css +0 -2
  42. package/dist/web/client/assets/prompt-input-a7UP_MAw.js +0 -1
  43. package/dist/web/client/assets/right-panel-registry-BqtgZw7Z.js +0 -2
  44. package/dist/web/client/assets/routes-C37r2W1K.js +0 -16
  45. package/dist/web/client/assets/types-Cr5Z97oW.js +0 -1
  46. package/dist/web/client/assets/virtualized-turn-list-Bcq088gZ.js +0 -6
@@ -12,7 +12,7 @@ import {
12
12
  normalizeAssistantToolParts,
13
13
  orderedRlmChildren,
14
14
  rlmStatusIcon
15
- } from "./chunk-JLGBOCFM.js";
15
+ } from "./chunk-ELRLMFHT.js";
16
16
  import {
17
17
  RefreshCw
18
18
  } from "./chunk-NZ5YXXQ5.js";
@@ -47,7 +47,7 @@ import {
47
47
  cn
48
48
  } from "./chunk-JCK6B7ZW.js";
49
49
 
50
- // web/app/dist/server/assets/subagent-transcript-E3nOzjsO.js
50
+ // web/app/dist/server/assets/subagent-transcript-Bb8_b7HL.js
51
51
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
52
52
  import { jsx, jsxs } from "react/jsx-runtime";
53
53
  function SubagentList({ children, tree, className }) {
@@ -24,7 +24,7 @@ import {
24
24
  createLucideIcon
25
25
  } from "./chunk-JVXQQYXB.js";
26
26
 
27
- // web/app/dist/server/assets/right-panel-registry-B34oIBYD.js
27
+ // web/app/dist/server/assets/right-panel-registry-pxvGpyjD.js
28
28
  import { Suspense, lazy } from "react";
29
29
  import { jsx, jsxs } from "react/jsx-runtime";
30
30
  var __iconData$1 = {
@@ -61,11 +61,11 @@ var __iconData = {
61
61
  };
62
62
  __iconData.node;
63
63
  var Library = createLucideIcon(__iconData);
64
- var LazyArtifactsPanel = lazy(() => import("./artifacts-panel-BySfu7im-AKBWHYJS.js").then(({ ArtifactsPanelContent }) => ({ default: ArtifactsPanelContent })));
64
+ var LazyArtifactsPanel = lazy(() => import("./artifacts-panel-CGgpyc85-V3KXDVAX.js").then(({ ArtifactsPanelContent }) => ({ default: ArtifactsPanelContent })));
65
65
  var LazyResourcesPanel = lazy(() => import("./resources-panel-rn64m-sL-7QXEGRNX.js").then(({ ResourcesPanelContent }) => ({ default: ResourcesPanelContent })));
66
66
  var LazySessionInsightsPanel = lazy(() => import("./session-insights-panel-DKkakWj6-ITHKDXF4.js").then(({ SessionInsightsPanel }) => ({ default: SessionInsightsPanel })));
67
67
  var LazyReplPanel = lazy(() => import("./repl-panel-CBwh0VGD-USDEOGGJ.js").then(({ ReplPanelContent }) => ({ default: ReplPanelContent })));
68
- var LazySubagentsPanel = lazy(() => import("./subagents-panel-DjOcQxp4-GZYOZOYC.js").then(({ SubagentsPanelContent }) => ({ default: SubagentsPanelContent })));
68
+ var LazySubagentsPanel = lazy(() => import("./subagents-panel-Cs3cBcsy-HTQBIYAS.js").then(({ SubagentsPanelContent }) => ({ default: SubagentsPanelContent })));
69
69
  var LazyWorkspacePanel = lazy(() => import("./workspace-panel-BU50q4Bu-JHTQPR6R.js").then(({ WorkspacePanelContent }) => ({ default: WorkspacePanelContent })));
70
70
  var LazySessionTreePanel = lazy(() => import("./session-tree-panel-WaHHv775-HRUHFSFO.js").then(({ SessionTreePanel }) => ({ default: SessionTreePanel })));
71
71
  function PanelFallback() {
@@ -2,7 +2,7 @@ import {
2
2
  cva
3
3
  } from "./chunk-UUDBEYKV.js";
4
4
 
5
- // web/app/dist/server/assets/tokens-BWrrps_E.js
5
+ // web/app/dist/server/assets/tokens-D0kuFXb3.js
6
6
  var COMPACT_ACTION_BUTTON_CLASS = "h-8 shrink-0 cursor-pointer rounded-full border-border/45 bg-background/65 px-3 text-caption font-semibold text-foreground/75 shadow-sm transition-[background-color,border-color,box-shadow,opacity,transform] duration-150 hover:bg-foreground/5 active:scale-[0.96] disabled:opacity-50";
7
7
  var HIT_AREA_EXPAND_CLASS = "relative after:absolute after:top-1/2 after:left-1/2 after:size-10 after:-translate-x-1/2 after:-translate-y-1/2";
8
8
  var HIT_AREA_EXPAND_DENSE_CLASS = "relative after:absolute after:inset-x-0 after:-top-1.5 after:-bottom-1.5";
@@ -13,7 +13,7 @@ var CHAT_HEADER_LAYER_CLASS = "relative z-10 overflow-visible";
13
13
  var CHAT_COLUMN_CLASS = "mx-auto w-full max-w-chat px-[var(--density-pad-x)]";
14
14
  var COMPOSER_ADD_BUTTON_CLASS = "size-8 shrink-0 rounded-full border-border/70 bg-background text-foreground/80 shadow-sm hover:bg-muted hover:text-foreground";
15
15
  var SUGGESTION_ITEM_CLASS = "h-auto justify-start rounded-full border border-border/70 bg-background/80 px-3 py-1.5 text-pretty text-sm font-normal text-foreground/65 shadow-sm transition-colors hover:border-border hover:bg-foreground/6 hover:text-foreground";
16
- var PANEL_OVERLAY_CLASS = "h-full min-h-0 w-[min(360px,calc(100vw-1.5rem))] overflow-hidden rounded-lg border border-border/70 bg-background/95 shadow-lg backdrop-blur";
16
+ var PANEL_OVERLAY_CLASS = "min-h-0 w-[min(360px,calc(100vw-1.5rem))] overflow-hidden rounded-lg border border-border/70 bg-background/95 shadow-lg backdrop-blur";
17
17
  var rowSurface = cva("flex min-w-0 rounded-sm border", {
18
18
  variants: {
19
19
  tone: {
@@ -19,8 +19,8 @@ import {
19
19
  cn
20
20
  } from "./chunk-JCK6B7ZW.js";
21
21
 
22
- // web/app/dist/server/assets/prompt-input-D2ekqCWz.js
23
- import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
22
+ // web/app/dist/server/assets/prompt-input-Cki_c9TM.js
23
+ import { useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
24
24
  import { jsx, jsxs } from "react/jsx-runtime";
25
25
  var PROMPT_TEXT_METRICS = "px-2 text-sm leading-6 whitespace-pre-wrap [overflow-wrap:break-word]";
26
26
  var PROMPT_GHOST_PREFIX_CLASS = "text-transparent";
@@ -40,30 +40,45 @@ function resolveInlineCompletion(context) {
40
40
  if (completion.forValue !== value) return null;
41
41
  const text = completion.text;
42
42
  if (text.length === 0 || text.trim().length === 0) return null;
43
- if (value.endsWith(text)) return null;
43
+ if (completion.mode !== "replace" && value.endsWith(text)) return null;
44
44
  if (value.length === 0) return null;
45
45
  if (context.streaming || context.disabled) return null;
46
46
  if (context.triggerOpen) return null;
47
- if (context.intentSuggestion) return null;
48
47
  if (context.dismissed && context.dismissed.forValue === value && context.dismissed.text === text) return null;
49
48
  if (!editing.focused || editing.composing) return null;
50
49
  if (editing.caretStart === null || editing.caretEnd === null) return null;
51
50
  if (editing.caretStart !== editing.caretEnd) return null;
52
51
  if (editing.caretStart !== value.length) return null;
53
- return { text };
52
+ return {
53
+ text,
54
+ mode: completion.mode
55
+ };
56
+ }
57
+ function spliceCompletion(value, text, mode = "append") {
58
+ return mode === "replace" ? text : `${value}${text}`;
54
59
  }
55
- function spliceCompletion(value, text) {
56
- return `${value}${text}`;
60
+ function ghostPaintText(value, completion) {
61
+ if (!completion) return void 0;
62
+ if (completion.mode === "append") return completion.text;
63
+ return /\s$/.test(value) ? completion.text : ` ${completion.text}`;
57
64
  }
58
- function PromptInput({ value, defaultValue = "", onValueChange, onSubmit, loading = false, submitWhileLoading = false, onStop, minRows = 2, maxRows = 8, leadingAction, className, disabled, placeholder = "Ask the agent to do something\u2026", "aria-label": ariaLabel = "Prompt", onKeyDown, onScroll, ghostText, onTextareaRef, ...textareaProps }) {
65
+ function PromptInput({ value, defaultValue = "", onValueChange, onSubmit, loading = false, submitWhileLoading = false, onStop, minRows = 2, maxRows = 8, leadingAction, className, disabled, placeholder = "Ask the agent to do something\u2026", "aria-label": ariaLabel = "Prompt", "aria-describedby": ariaDescribedBy, onKeyDown, onScroll, ghostText, onTextareaRef, ...textareaProps }) {
59
66
  const reduce = useReducedMotion() ?? false;
60
67
  const textareaRef = useRef(null);
61
68
  const measurementRef = useRef(null);
62
69
  const ghostMirrorRef = useRef(null);
70
+ const descriptionId = useId();
71
+ const ghostStatusId = useId();
63
72
  const [mirrorWidth, setMirrorWidth] = useState(void 0);
64
73
  const [internalValue, setInternalValue] = useState(defaultValue);
65
74
  const currentValue = value ?? internalValue;
66
75
  const canSubmit = Boolean(currentValue.trim()) && !disabled && (!loading || submitWhileLoading);
76
+ const sendDisabled = Boolean(disabled) || loading && !submitWhileLoading;
77
+ const describedBy = [
78
+ descriptionId,
79
+ ghostStatusId,
80
+ ariaDescribedBy
81
+ ].filter(Boolean).join(" ");
67
82
  const syncGhostLayer = useCallback(() => {
68
83
  const textarea = textareaRef.current;
69
84
  const mirror = ghostMirrorRef.current;
@@ -132,8 +147,9 @@ function PromptInput({ value, defaultValue = "", onValueChange, onSubmit, loadin
132
147
  submit();
133
148
  };
134
149
  return /* @__PURE__ */ jsxs("form", {
150
+ "aria-label": "Message composer",
135
151
  onSubmit: submit,
136
- className: cn("relative w-full rounded-chat-input border border-border/70 bg-sidebar p-2 text-[color:var(--foreground)] shadow-sm transition-[border-color,box-shadow] focus-within:border-chat-input-focus-outline/45 focus-within:ring-1 focus-within:ring-chat-input-focus-outline/25", disabled && "opacity-60", className),
152
+ className: cn("relative w-full rounded-chat-input border border-border/70 bg-sidebar p-2 text-[color:var(--foreground)] shadow-sm transition-[border-color,box-shadow] focus-within:border-chat-input-focus-outline/45 focus-within:ring-2 focus-within:ring-chat-input-focus-outline/25", disabled && "opacity-60", className),
137
153
  children: [
138
154
  /* @__PURE__ */ jsx("div", {
139
155
  ref: measurementRef,
@@ -142,6 +158,17 @@ function PromptInput({ value, defaultValue = "", onValueChange, onSubmit, loadin
142
158
  className: cn("pointer-events-none invisible absolute inset-x-2 top-0", PROMPT_TEXT_METRICS),
143
159
  children: `${currentValue}\u200B`
144
160
  }),
161
+ /* @__PURE__ */ jsx("p", {
162
+ id: descriptionId,
163
+ className: "sr-only",
164
+ children: "Enter to send. Shift+Enter for a new line. Tab accepts an inline suggestion or menu item. Escape dismisses suggestions."
165
+ }),
166
+ /* @__PURE__ */ jsx("p", {
167
+ id: ghostStatusId,
168
+ className: "sr-only",
169
+ "aria-live": "polite",
170
+ children: ghostText ? "Suggestion available. Press Tab to accept." : ""
171
+ }),
145
172
  /* @__PURE__ */ jsxs("div", {
146
173
  className: "relative",
147
174
  children: [ghostText ? /* @__PURE__ */ jsx("div", {
@@ -165,6 +192,7 @@ function PromptInput({ value, defaultValue = "", onValueChange, onSubmit, loadin
165
192
  disabled,
166
193
  placeholder,
167
194
  "aria-label": ariaLabel,
195
+ "aria-describedby": describedBy,
168
196
  autoComplete: "off",
169
197
  rows: minRows,
170
198
  ...textareaProps,
@@ -174,27 +202,35 @@ function PromptInput({ value, defaultValue = "", onValueChange, onSubmit, loadin
174
202
  onScroll?.(event);
175
203
  syncGhostLayer();
176
204
  },
177
- className: cn("block w-full resize-none overflow-y-auto bg-transparent pt-1.5 text-foreground outline-none placeholder:text-foreground/55", PROMPT_TEXT_METRICS)
205
+ className: cn("block w-full resize-none overflow-y-auto bg-transparent pt-1.5 text-foreground outline-none placeholder:text-foreground/70", PROMPT_TEXT_METRICS)
178
206
  })]
179
207
  }),
180
208
  /* @__PURE__ */ jsxs("div", {
181
- className: "mt-1 flex min-h-8 items-center gap-1",
209
+ className: "mt-1 flex min-h-8 items-center gap-1.5",
182
210
  children: [
183
- leadingAction,
211
+ leadingAction ? /* @__PURE__ */ jsx("div", {
212
+ role: "group",
213
+ "aria-label": "Composer options",
214
+ className: "flex min-w-0 items-center gap-1.5",
215
+ children: leadingAction
216
+ }) : null,
184
217
  loading && onStop ? /* @__PURE__ */ jsx(Button, {
185
218
  type: "button",
186
219
  size: "icon",
187
220
  "aria-label": "Stop generating",
188
221
  onClick: onStop,
189
- className: "ml-auto size-8 rounded-full",
190
- children: /* @__PURE__ */ jsx(Square, { className: "size-3 fill-current" })
222
+ className: "ms-auto size-8 rounded-full",
223
+ children: /* @__PURE__ */ jsx(Square, {
224
+ "aria-hidden": "true",
225
+ className: "size-3 fill-current"
226
+ })
191
227
  }) : null,
192
- !loading || canSubmit ? /* @__PURE__ */ jsx(Button, {
228
+ !loading || canSubmit || submitWhileLoading ? /* @__PURE__ */ jsx(Button, {
193
229
  type: "submit",
194
230
  size: "icon",
195
- disabled: !canSubmit,
196
- "aria-label": loading ? "Steer current run" : "Send prompt",
197
- className: cn("size-8 rounded-full", !loading && "ml-auto", canSubmit && "border-transparent bg-chat-input-accent text-white hover:bg-chat-input-accent/90 focus-visible:border-chat-input-accent focus-visible:ring-chat-input-accent/40"),
231
+ disabled: sendDisabled || !currentValue.trim(),
232
+ "aria-label": loading ? "Send follow-up" : "Send prompt",
233
+ className: cn("size-8 rounded-full", !loading && "ms-auto", canSubmit && "border-transparent bg-chat-input-accent text-white hover:bg-chat-input-accent/90 focus-visible:border-chat-input-accent focus-visible:ring-chat-input-accent/40"),
198
234
  children: /* @__PURE__ */ jsx(AnimatePresence, {
199
235
  initial: false,
200
236
  mode: "popLayout",
@@ -216,7 +252,10 @@ function PromptInput({ value, defaultValue = "", onValueChange, onSubmit, loadin
216
252
  },
217
253
  transition: reduce ? { duration: 0 } : SPRING_SWAP,
218
254
  className: "grid place-items-center",
219
- children: /* @__PURE__ */ jsx(ArrowUp, { className: "size-4" })
255
+ children: /* @__PURE__ */ jsx(ArrowUp, {
256
+ "aria-hidden": "true",
257
+ className: "size-4"
258
+ })
220
259
  }, "send")
221
260
  })
222
261
  }) : null
@@ -231,5 +270,6 @@ export {
231
270
  sameEditingState,
232
271
  resolveInlineCompletion,
233
272
  spliceCompletion,
273
+ ghostPaintText,
234
274
  PromptInput
235
275
  };
@@ -2,7 +2,7 @@ import {
2
2
  FolderPlus,
3
3
  FolderTree,
4
4
  pathEntryLabel
5
- } from "./chunk-ONWT54IL.js";
5
+ } from "./chunk-BS4D5LRR.js";
6
6
  import {
7
7
  Command,
8
8
  CommandEmpty,
@@ -56,7 +56,7 @@ import "./chunk-RPWKCJHL.js";
56
56
  import "./chunk-L547YHC4.js";
57
57
  import "./chunk-MLKGABMK.js";
58
58
 
59
- // web/app/dist/server/assets/create-project-dialog-CigfFgAj.js
59
+ // web/app/dist/server/assets/create-project-dialog-xhTWmcx1.js
60
60
  import { useId } from "react";
61
61
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
62
62
  function SessionSidebarCreateDialog({ createOpen, setCreateOpen, directoryBrowser, setDirectoryBrowser, directoryBrowseLoading, directoryBrowseError, setDirectoryBrowseError, onBrowseDirectories, directoryToken, setDirectoryToken, createName, setCreateName, createPath, setCreatePath, loadDirectories, createSubmitting, createSubmitError, setCreateSubmitError, submitCreate }) {
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  Pencil
3
3
  } from "./chunk-LOFZS555.js";
4
- import {
5
- CHAT_COLUMN_CLASS
6
- } from "./chunk-CIE2PLNB.js";
7
4
  import {
8
5
  notify
9
6
  } from "./chunk-UIUZ4ETR.js";
10
7
  import "./chunk-VHLBXWEN.js";
8
+ import {
9
+ CHAT_COLUMN_CLASS
10
+ } from "./chunk-PX7B5BTI.js";
11
11
  import "./chunk-HFN4TNR3.js";
12
12
  import "./chunk-FOMB2JR7.js";
13
13
  import {
@@ -25,7 +25,7 @@ import "./chunk-RPWKCJHL.js";
25
25
  import "./chunk-L547YHC4.js";
26
26
  import "./chunk-MLKGABMK.js";
27
27
 
28
- // web/app/dist/server/assets/message-queue-BsrLcNPX.js
28
+ // web/app/dist/server/assets/message-queue-Dg2okv2L.js
29
29
  import { useState } from "react";
30
30
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
31
31
  var LANES = [{
@@ -2,7 +2,7 @@ import {
2
2
  GenerativeTextRenderer,
3
3
  OpenUIHtmlArtifactView,
4
4
  openui_renderer_exports
5
- } from "./chunk-JZ2WBCIH.js";
5
+ } from "./chunk-G6NMFFZX.js";
6
6
  import "./chunk-2HOITUWV.js";
7
7
  import "./chunk-FF2M3MLP.js";
8
8
  import "./chunk-3YYNG52U.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  SUGGESTION_ITEM_CLASS
3
- } from "./chunk-CIE2PLNB.js";
3
+ } from "./chunk-PX7B5BTI.js";
4
4
  import "./chunk-UUDBEYKV.js";
5
5
  import {
6
6
  cn
@@ -8,7 +8,7 @@ import {
8
8
  import "./chunk-RPWKCJHL.js";
9
9
  import "./chunk-MLKGABMK.js";
10
10
 
11
- // web/app/dist/server/assets/prompt-suggestions-D6RXFQF4.js
11
+ // web/app/dist/server/assets/prompt-suggestions-h17Gu7u1.js
12
12
  import { jsx } from "react/jsx-runtime";
13
13
  function PromptSuggestions({ suggestions, selectedSuggestion, cycle, onSuggestion, variant = "pills", className, ...props }) {
14
14
  const list = variant === "list";
@@ -20,8 +20,9 @@ import {
20
20
  SessionTreeSnapshotResponseSchema,
21
21
  composerCompletionIgnores,
22
22
  initAnalytics,
23
- isServer
24
- } from "./chunk-4B2PJSK5.js";
23
+ isServer,
24
+ normalizeCompletionDraft
25
+ } from "./chunk-5TXDGMCK.js";
25
26
  import {
26
27
  isModelPatternEnabled
27
28
  } from "./chunk-WTYNN6EV.js";
@@ -195,7 +196,7 @@ import "./chunk-RPWKCJHL.js";
195
196
  import "./chunk-L547YHC4.js";
196
197
  import "./chunk-MLKGABMK.js";
197
198
 
198
- // web/app/dist/server/assets/router-RPObiwZR.js
199
+ // web/app/dist/server/assets/router-DOPFvRSC.js
199
200
  import { Component, Fragment, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
200
201
  import { jsx, jsxs } from "react/jsx-runtime";
201
202
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
@@ -4773,7 +4774,7 @@ function MotionRuntime({ children }) {
4773
4774
  })
4774
4775
  });
4775
4776
  }
4776
- var globals_default = "/assets/globals-B-fD_O7k.css";
4777
+ var globals_default = "/assets/globals-BiAbxPQ2.css";
4777
4778
  function makeQueryClient() {
4778
4779
  return new QueryClient({ defaultOptions: { queries: {
4779
4780
  staleTime: 6e4,
@@ -4855,7 +4856,7 @@ function RootDocument({ children }) {
4855
4856
  ] })]
4856
4857
  });
4857
4858
  }
4858
- var $$splitComponentImporter = () => import("./routes-Dn-deuPY-MDXEQXRU.js");
4859
+ var $$splitComponentImporter = () => import("./routes-i2Ai-ZwX-SMSFONDQ.js");
4859
4860
  var Route$28 = createFileRoute("/")({ component: lazyRouteComponent($$splitComponentImporter, "component") });
4860
4861
  var ManagedAttachmentValidationError = class extends Error {
4861
4862
  status;
@@ -11503,7 +11504,30 @@ function handleChatCommandsGet(request) {
11503
11504
  }, request);
11504
11505
  }
11505
11506
  function normalizeCompletionText(text) {
11506
- return text.trim().replace(/\s+/g, " ");
11507
+ return normalizeCompletionDraft(text);
11508
+ }
11509
+ function longestCommonPrefix(values) {
11510
+ const first = values[0];
11511
+ if (first === void 0) return "";
11512
+ let prefix = first;
11513
+ for (let index = 1; index < values.length; index += 1) {
11514
+ const value = values[index] ?? "";
11515
+ const limit = Math.min(prefix.length, value.length);
11516
+ let shared = 0;
11517
+ while (shared < limit && prefix[shared]?.toLowerCase() === value[shared]?.toLowerCase()) shared += 1;
11518
+ prefix = prefix.slice(0, shared);
11519
+ if (prefix.length === 0) break;
11520
+ }
11521
+ return prefix;
11522
+ }
11523
+ function sessionIdFromFile(sessionFile) {
11524
+ return (sessionFile.split(/[/\\]/).pop() ?? "").replace(/\.jsonl$/i, "");
11525
+ }
11526
+ function isFromSession(candidate, sessionId) {
11527
+ if (!sessionId) return false;
11528
+ if (candidate.sessionId) return candidate.sessionId === sessionId;
11529
+ if (!candidate.sessionFile) return false;
11530
+ return sessionIdFromFile(candidate.sessionFile) === sessionId;
11507
11531
  }
11508
11532
  function findCompletion(draft, candidates, options = {}) {
11509
11533
  const minChars = options.minChars ?? 4;
@@ -11511,19 +11535,39 @@ function findCompletion(draft, candidates, options = {}) {
11511
11535
  const normalizedDraft = normalizeCompletionText(draft);
11512
11536
  if (normalizedDraft.length < minChars) return void 0;
11513
11537
  const needle = normalizedDraft.toLowerCase();
11514
- let best;
11515
- let bestText = "";
11538
+ const matched = [];
11516
11539
  for (const candidate of candidates) {
11517
11540
  const text = normalizeCompletionText(candidate.text);
11518
11541
  if (text.length <= normalizedDraft.length) continue;
11519
11542
  if (text.length > maxChars) continue;
11520
11543
  if (!text.toLowerCase().startsWith(needle)) continue;
11521
- if (!best || candidate.at > best.at || candidate.at === best.at && text.length > bestText.length) {
11522
- best = candidate;
11523
- bestText = text;
11524
- }
11544
+ matched.push({
11545
+ candidate,
11546
+ text
11547
+ });
11525
11548
  }
11526
- return best ? bestText : void 0;
11549
+ if (matched.length === 0) return void 0;
11550
+ const sessionMatches = matched.filter((entry) => isFromSession(entry.candidate, options.sessionId));
11551
+ const tier = sessionMatches.length > 0 ? sessionMatches : matched;
11552
+ const source = sessionMatches.length > 0 ? "session" : "corpus";
11553
+ const ranked = [...tier].sort((a, b) => b.candidate.at - a.candidate.at || b.text.length - a.text.length);
11554
+ const best = ranked[0];
11555
+ if (!best) return void 0;
11556
+ const bestRemainder = best.text.slice(normalizedDraft.length);
11557
+ const remainders = [bestRemainder, ...ranked.filter((entry) => entry !== best).map((entry) => entry.text.slice(normalizedDraft.length))];
11558
+ const agreed = longestCommonPrefix(remainders);
11559
+ if (agreed.length === 0) return void 0;
11560
+ const shortestRemainder = Math.min(...remainders.map((remainder) => remainder.length));
11561
+ const agreement = shortestRemainder === 0 ? 0 : agreed.length / shortestRemainder;
11562
+ const confidence = Math.min(1, agreement);
11563
+ if (confidence < (options.floor ?? 0.5)) return void 0;
11564
+ const extendConfidence = options.extendConfidence ?? 0.8;
11565
+ return {
11566
+ completion: normalizedDraft + (source === "corpus" ? agreed : confidence >= extendConfidence ? bestRemainder : agreed),
11567
+ confidence,
11568
+ source,
11569
+ candidateCount: ranked.length
11570
+ };
11527
11571
  }
11528
11572
  function harvestPromptCandidates(messages, at, maxChars = 200) {
11529
11573
  const out = [];
@@ -11541,11 +11585,16 @@ function harvestPromptCandidates(messages, at, maxChars = 200) {
11541
11585
  }
11542
11586
  var INDEX_READY_TIMEOUT_MS = 250;
11543
11587
  function createComposerCompletionService(options) {
11544
- return { async complete(draft) {
11588
+ return { async complete(draft, sessionId) {
11545
11589
  if (composerCompletionIgnores(draft)) return {};
11546
11590
  await Promise.race([options.index.ready(), new Promise((resolve2) => setTimeout(resolve2, INDEX_READY_TIMEOUT_MS))]);
11547
- const completion = findCompletion(draft, options.index.candidates());
11548
- return completion ? { completion } : {};
11591
+ const suggestion = findCompletion(draft, options.index.candidates(), { sessionId });
11592
+ if (!suggestion) return {};
11593
+ return {
11594
+ completion: suggestion.completion,
11595
+ confidence: suggestion.confidence,
11596
+ source: suggestion.source
11597
+ };
11549
11598
  } };
11550
11599
  }
11551
11600
  function stringValue(value) {
@@ -11617,6 +11666,7 @@ async function loadSessionListPresentation(row, source, livePresentation) {
11617
11666
  if (!path) return livePresentation;
11618
11667
  return await loadManagedPrimePresentation({ sessionPath: path }) ?? livePresentation;
11619
11668
  }
11669
+ var PROMPT_INDEX_MAX_SESSION_ENTRIES = 1e4;
11620
11670
  var PROMPT_INDEX_CANDIDATE_LIMIT = 2e3;
11621
11671
  var PROMPT_INDEX_RETRY_BACKOFF_MS = 6e4;
11622
11672
  var PROMPT_INDEX_FILE = "fleet-prompt-index.json";
@@ -11655,15 +11705,18 @@ async function writePersisted(agentDir, index) {
11655
11705
  `, "utf8");
11656
11706
  await rename(temporary, path);
11657
11707
  }
11658
- function flatten(index, limit) {
11708
+ function flattenPromptIndex(index, limit) {
11659
11709
  const out = [];
11660
11710
  for (const session of index.sessions) {
11661
11711
  const base = Date.parse(session.modified);
11662
11712
  const at = Number.isFinite(base) ? base : 0;
11713
+ const sessionId = sessionIdFromFile(session.sessionFile);
11663
11714
  session.prompts.forEach((text, offset) => {
11664
11715
  out.push({
11665
11716
  text,
11666
- at: at + Math.min(offset, 999) / 1e3
11717
+ at: at + Math.min(offset, 999) / 1e3,
11718
+ sessionFile: session.sessionFile,
11719
+ sessionId
11667
11720
  });
11668
11721
  });
11669
11722
  }
@@ -11671,8 +11724,7 @@ function flatten(index, limit) {
11671
11724
  return out.slice(0, limit);
11672
11725
  }
11673
11726
  function createPromptIndex(options) {
11674
- const limit = options.sessionLimit ?? 400;
11675
- const maxSessionMessages = options.maxSessionMessages ?? 2e3;
11727
+ const limit = options.sessionLimit ?? 2e3;
11676
11728
  const now2 = options.now ?? Date.now;
11677
11729
  const log = options.log ?? (() => {
11678
11730
  });
@@ -11699,7 +11751,7 @@ function createPromptIndex(options) {
11699
11751
  log(`prompt index: session listing failed (${error instanceof Error ? error.name : "unknown"})`);
11700
11752
  return false;
11701
11753
  }
11702
- const scoped = sessions2.filter((session) => !isSubagent(session)).filter((session) => (session.messageCount ?? 0) <= maxSessionMessages).filter((session) => typeof session.sessionFile === "string" && session.sessionFile.length > 0).sort((a, b) => sessionRecency(b) - sessionRecency(a)).slice(0, limit);
11754
+ const scoped = sessions2.filter((session) => !isSubagent(session)).filter((session) => typeof session.sessionFile === "string" && session.sessionFile.length > 0).sort((a, b) => sessionRecency(b) - sessionRecency(a)).slice(0, limit);
11703
11755
  const next = [];
11704
11756
  for (const session of scoped) {
11705
11757
  const modified = session.modified ?? "";
@@ -11710,6 +11762,11 @@ function createPromptIndex(options) {
11710
11762
  }
11711
11763
  try {
11712
11764
  const messages = await options.openSession(session.sessionFile);
11765
+ if (messages.length > 1e4) {
11766
+ if (cached) next.push(cached);
11767
+ else log(`prompt index: skipped ${session.sessionFile} (${messages.length} entries > ${PROMPT_INDEX_MAX_SESSION_ENTRIES})`);
11768
+ continue;
11769
+ }
11713
11770
  next.push({
11714
11771
  sessionFile: session.sessionFile,
11715
11772
  modified,
@@ -11768,7 +11825,7 @@ function createPromptIndex(options) {
11768
11825
  candidates() {
11769
11826
  ensureFresh();
11770
11827
  if (!persisted) return [];
11771
- flattened ??= flatten(persisted, PROMPT_INDEX_CANDIDATE_LIMIT);
11828
+ flattened ??= flattenPromptIndex(persisted, PROMPT_INDEX_CANDIDATE_LIMIT);
11772
11829
  return flattened;
11773
11830
  },
11774
11831
  async refresh() {
@@ -11797,9 +11854,9 @@ function messageText(message) {
11797
11854
  }).map((part) => part.text).join(" ");
11798
11855
  }
11799
11856
  var openSessionWithRuntime = async (sessionFile) => {
11800
- return (await SessionManager.openAsync(sessionFile)).buildSessionContext().messages.map((message) => ({
11801
- role: message.role,
11802
- text: messageText(message)
11857
+ return (await SessionManager.openAsync(sessionFile)).getEntries().filter((entry) => entry.type === "message").map((entry) => ({
11858
+ role: entry.message.role,
11859
+ text: messageText(entry.message)
11803
11860
  }));
11804
11861
  };
11805
11862
  function getPromptIndex() {
@@ -11810,8 +11867,7 @@ function getPromptIndex() {
11810
11867
  return {
11811
11868
  sessionFile: sessionSourcePath(row.source),
11812
11869
  modified: row.updatedAt,
11813
- isSubagent: row.isSubagent,
11814
- messageCount: row.messageCount
11870
+ isSubagent: row.isSubagent
11815
11871
  };
11816
11872
  }),
11817
11873
  openSession: openSessionWithRuntime,
@@ -11824,7 +11880,7 @@ function handleChatCompletionPost(request) {
11824
11880
  return wrapApiHandler(async () => {
11825
11881
  const body = ComposerCompletionRequestSchema.parse(await request.json().catch(() => ({})));
11826
11882
  const service = createComposerCompletionService({ index: getPromptIndex() });
11827
- return Response.json(await service.complete(body.text));
11883
+ return Response.json(await service.complete(body.text, body.sessionId));
11828
11884
  }, request);
11829
11885
  }
11830
11886
  function shouldReplaySseEvent(event, pendingQuestionIds) {