@uniqueli/openwork 0.2.1 → 0.2.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.
@@ -12755,6 +12755,12 @@ const Key = createLucideIcon("Key", [
12755
12755
  ["path", { d: "m21 2-9.6 9.6", key: "1j0ho8" }],
12756
12756
  ["circle", { cx: "7.5", cy: "15.5", r: "5.5", key: "yqb3hr" }]
12757
12757
  ]);
12758
+ const LayoutGrid = createLucideIcon("LayoutGrid", [
12759
+ ["rect", { width: "7", height: "7", x: "3", y: "3", rx: "1", key: "1g98yp" }],
12760
+ ["rect", { width: "7", height: "7", x: "14", y: "3", rx: "1", key: "6d4xhi" }],
12761
+ ["rect", { width: "7", height: "7", x: "14", y: "14", rx: "1", key: "nxv5o0" }],
12762
+ ["rect", { width: "7", height: "7", x: "3", y: "14", rx: "1", key: "1bb6yr" }]
12763
+ ]);
12758
12764
  const ListTodo = createLucideIcon("ListTodo", [
12759
12765
  ["rect", { x: "3", y: "5", width: "6", height: "6", rx: "1", key: "1defrl" }],
12760
12766
  ["path", { d: "m3 17 2 2 4-4", key: "1jhpwq" }],
@@ -12811,6 +12817,19 @@ const Send = createLucideIcon("Send", [
12811
12817
  ],
12812
12818
  ["path", { d: "m21.854 2.147-10.94 10.939", key: "12cjpa" }]
12813
12819
  ]);
12820
+ const Sparkles = createLucideIcon("Sparkles", [
12821
+ [
12822
+ "path",
12823
+ {
12824
+ d: "M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z",
12825
+ key: "4pj2yx"
12826
+ }
12827
+ ],
12828
+ ["path", { d: "M20 3v4", key: "1olli1" }],
12829
+ ["path", { d: "M22 5h-4", key: "1gvqau" }],
12830
+ ["path", { d: "M4 17v2", key: "vumght" }],
12831
+ ["path", { d: "M5 18H3", key: "zchphs" }]
12832
+ ]);
12814
12833
  const SquarePen = createLucideIcon("SquarePen", [
12815
12834
  ["path", { d: "M12 3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7", key: "1m0v6g" }],
12816
12835
  [
@@ -15579,14 +15598,7 @@ const buttonVariants = cva(
15579
15598
  const Button = reactExports.forwardRef(
15580
15599
  ({ className, variant, size: size2, asChild = false, ...props }, ref) => {
15581
15600
  const Comp = asChild ? Slot$3 : "button";
15582
- return /* @__PURE__ */ jsxRuntimeExports.jsx(
15583
- Comp,
15584
- {
15585
- className: cn(buttonVariants({ variant, size: size2, className })),
15586
- ref,
15587
- ...props
15588
- }
15589
- );
15601
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(Comp, { className: cn(buttonVariants({ variant, size: size2, className })), ref, ...props });
15590
15602
  }
15591
15603
  );
15592
15604
  Button.displayName = "Button";
@@ -16711,6 +16723,8 @@ const useAppStore = create$1((set, get) => ({
16711
16723
  rightPanelTab: "todos",
16712
16724
  settingsOpen: false,
16713
16725
  sidebarCollapsed: false,
16726
+ showKanbanView: false,
16727
+ showSubagentsInKanban: true,
16714
16728
  // Thread actions
16715
16729
  loadThreads: async () => {
16716
16730
  const threads = await window.api.threads.list();
@@ -16723,12 +16737,13 @@ const useAppStore = create$1((set, get) => ({
16723
16737
  const thread = await window.api.threads.create(metadata);
16724
16738
  set((state) => ({
16725
16739
  threads: [thread, ...state.threads],
16726
- currentThreadId: thread.thread_id
16740
+ currentThreadId: thread.thread_id,
16741
+ showKanbanView: false
16727
16742
  }));
16728
16743
  return thread;
16729
16744
  },
16730
16745
  selectThread: async (threadId) => {
16731
- set({ currentThreadId: threadId });
16746
+ set({ currentThreadId: threadId, showKanbanView: false });
16732
16747
  },
16733
16748
  deleteThread: async (threadId) => {
16734
16749
  console.log("[Store] Deleting thread:", threadId);
@@ -16803,6 +16818,17 @@ const useAppStore = create$1((set, get) => ({
16803
16818
  },
16804
16819
  setSidebarCollapsed: (collapsed) => {
16805
16820
  set({ sidebarCollapsed: collapsed });
16821
+ },
16822
+ // Kanban actions
16823
+ setShowKanbanView: (show) => {
16824
+ if (show) {
16825
+ set({ showKanbanView: true, currentThreadId: null });
16826
+ } else {
16827
+ set({ showKanbanView: false });
16828
+ }
16829
+ },
16830
+ setShowSubagentsInKanban: (show) => {
16831
+ set({ showSubagentsInKanban: show });
16806
16832
  }
16807
16833
  }));
16808
16834
  const CR = "\r".charCodeAt(0);
@@ -44595,6 +44621,7 @@ class ElectronIPCTransport {
44595
44621
  this.accumulatedToolCalls.clear();
44596
44622
  this.completedToolCallsByName.clear();
44597
44623
  const threadId = payload.config?.configurable?.thread_id;
44624
+ const modelId = payload.config?.configurable?.model_id;
44598
44625
  if (!threadId) {
44599
44626
  return this.createErrorGenerator("MISSING_THREAD_ID", "Thread ID is required");
44600
44627
  }
@@ -44606,7 +44633,13 @@ class ElectronIPCTransport {
44606
44633
  if (!messageContent && !hasResumeCommand) {
44607
44634
  return this.createErrorGenerator("MISSING_MESSAGE", "Message content is required");
44608
44635
  }
44609
- return this.createStreamGenerator(threadId, messageContent, payload.command, payload.signal);
44636
+ return this.createStreamGenerator(
44637
+ threadId,
44638
+ messageContent,
44639
+ payload.command,
44640
+ payload.signal,
44641
+ modelId
44642
+ );
44610
44643
  }
44611
44644
  async *createErrorGenerator(code2, message) {
44612
44645
  yield {
@@ -44614,7 +44647,7 @@ class ElectronIPCTransport {
44614
44647
  data: { error: code2, message }
44615
44648
  };
44616
44649
  }
44617
- async *createStreamGenerator(threadId, message, command, signal) {
44650
+ async *createStreamGenerator(threadId, message, command, signal, modelId) {
44618
44651
  const eventQueue = [];
44619
44652
  let resolveNext = null;
44620
44653
  let isDone = false;
@@ -44627,22 +44660,28 @@ class ElectronIPCTransport {
44627
44660
  thread_id: threadId
44628
44661
  }
44629
44662
  };
44630
- const cleanup = window.api.agent.streamAgent(threadId, message, command, (ipcEvent) => {
44631
- const sdkEvents = this.convertToSDKEvents(ipcEvent, threadId);
44632
- for (const sdkEvent of sdkEvents) {
44633
- if (sdkEvent.event === "done" || sdkEvent.event === "error") {
44634
- isDone = true;
44635
- hasError = sdkEvent.event === "error";
44636
- }
44637
- if (resolveNext) {
44638
- const resolve = resolveNext;
44639
- resolveNext = null;
44640
- resolve(sdkEvent);
44641
- } else {
44642
- eventQueue.push(sdkEvent);
44663
+ const cleanup = window.api.agent.streamAgent(
44664
+ threadId,
44665
+ message,
44666
+ command,
44667
+ (ipcEvent) => {
44668
+ const sdkEvents = this.convertToSDKEvents(ipcEvent, threadId);
44669
+ for (const sdkEvent of sdkEvents) {
44670
+ if (sdkEvent.event === "done" || sdkEvent.event === "error") {
44671
+ isDone = true;
44672
+ hasError = sdkEvent.event === "error";
44673
+ }
44674
+ if (resolveNext) {
44675
+ const resolve = resolveNext;
44676
+ resolveNext = null;
44677
+ resolve(sdkEvent);
44678
+ } else {
44679
+ eventQueue.push(sdkEvent);
44680
+ }
44643
44681
  }
44644
- }
44645
- });
44682
+ },
44683
+ modelId
44684
+ );
44646
44685
  if (signal) {
44647
44686
  signal.addEventListener("abort", () => {
44648
44687
  cleanup();
@@ -45156,7 +45195,8 @@ const createDefaultThreadState = () => ({
45156
45195
  openFiles: [],
45157
45196
  activeTab: "agent",
45158
45197
  fileContents: {},
45159
- tokenUsage: null
45198
+ tokenUsage: null,
45199
+ draftInput: ""
45160
45200
  });
45161
45201
  const defaultStreamData = {
45162
45202
  messages: [],
@@ -45221,6 +45261,7 @@ function ThreadStreamHolder({
45221
45261
  function ThreadProvider({ children }) {
45222
45262
  const [threadStates, setThreadStates] = reactExports.useState({});
45223
45263
  const [activeThreadIds, setActiveThreadIds] = reactExports.useState(/* @__PURE__ */ new Set());
45264
+ const [loadingStates, setLoadingStates] = reactExports.useState({});
45224
45265
  const initializedThreadsRef = reactExports.useRef(/* @__PURE__ */ new Set());
45225
45266
  const actionsCache = reactExports.useRef({});
45226
45267
  const streamDataRef = reactExports.useRef({});
@@ -45235,6 +45276,10 @@ function ThreadProvider({ children }) {
45235
45276
  (threadId, data) => {
45236
45277
  streamDataRef.current[threadId] = data;
45237
45278
  notifyStreamSubscribers(threadId);
45279
+ setLoadingStates((prev) => {
45280
+ if (prev[threadId] === data.isLoading) return prev;
45281
+ return { ...prev, [threadId]: data.isLoading };
45282
+ });
45238
45283
  },
45239
45284
  [notifyStreamSubscribers]
45240
45285
  );
@@ -45254,12 +45299,26 @@ function ThreadProvider({ children }) {
45254
45299
  (threadId) => {
45255
45300
  const state = threadStates[threadId] || createDefaultThreadState();
45256
45301
  if (state.pendingApproval) {
45257
- console.log("[ThreadContext] getThreadState returning pendingApproval for:", threadId, state.pendingApproval);
45302
+ console.log(
45303
+ "[ThreadContext] getThreadState returning pendingApproval for:",
45304
+ threadId,
45305
+ state.pendingApproval
45306
+ );
45258
45307
  }
45259
45308
  return state;
45260
45309
  },
45261
45310
  [threadStates]
45262
45311
  );
45312
+ const getAllThreadStates = reactExports.useCallback(() => {
45313
+ return threadStates;
45314
+ }, [threadStates]);
45315
+ const getAllStreamLoadingStates = reactExports.useCallback(() => {
45316
+ return loadingStates;
45317
+ }, [loadingStates]);
45318
+ const subscribeToAllStreams = reactExports.useCallback(() => {
45319
+ return () => {
45320
+ };
45321
+ }, []);
45263
45322
  const updateThreadState = reactExports.useCallback(
45264
45323
  (threadId, updater) => {
45265
45324
  setThreadStates((prev) => {
@@ -45275,7 +45334,9 @@ function ThreadProvider({ children }) {
45275
45334
  );
45276
45335
  const parseErrorMessage = reactExports.useCallback((error) => {
45277
45336
  const errorMessage = typeof error === "string" ? error : error.message;
45278
- const contextWindowMatch = errorMessage.match(/prompt is too long: (\d+) tokens > (\d+) maximum/i);
45337
+ const contextWindowMatch = errorMessage.match(
45338
+ /prompt is too long: (\d+) tokens > (\d+) maximum/i
45339
+ );
45279
45340
  if (contextWindowMatch) {
45280
45341
  const [, usedTokens, maxTokens] = contextWindowMatch;
45281
45342
  const usedK = Math.round(parseInt(usedTokens) / 1e3);
@@ -45304,7 +45365,11 @@ function ThreadProvider({ children }) {
45304
45365
  switch (data.type) {
45305
45366
  case "interrupt":
45306
45367
  if (data.request) {
45307
- console.log("[ThreadContext] Setting pendingApproval for thread:", threadId, data.request);
45368
+ console.log(
45369
+ "[ThreadContext] Setting pendingApproval for thread:",
45370
+ threadId,
45371
+ data.request
45372
+ );
45308
45373
  updateThreadState(threadId, () => ({ pendingApproval: data.request }));
45309
45374
  }
45310
45375
  break;
@@ -45431,7 +45496,8 @@ function ThreadProvider({ children }) {
45431
45496
  closeFile: (path2) => {
45432
45497
  updateThreadState(threadId, (state) => {
45433
45498
  const newOpenFiles = state.openFiles.filter((f2) => f2.path !== path2);
45434
- const { [path2]: _2, ...newFileContents } = state.fileContents;
45499
+ const newFileContents = { ...state.fileContents };
45500
+ delete newFileContents[path2];
45435
45501
  let newActiveTab = state.activeTab;
45436
45502
  if (state.activeTab === path2) {
45437
45503
  const closedIndex = state.openFiles.findIndex((f2) => f2.path === path2);
@@ -45439,7 +45505,11 @@ function ThreadProvider({ children }) {
45439
45505
  else if (closedIndex > 0) newActiveTab = newOpenFiles[closedIndex - 1].path;
45440
45506
  else newActiveTab = newOpenFiles[0].path;
45441
45507
  }
45442
- return { openFiles: newOpenFiles, activeTab: newActiveTab, fileContents: newFileContents };
45508
+ return {
45509
+ openFiles: newOpenFiles,
45510
+ activeTab: newActiveTab,
45511
+ fileContents: newFileContents
45512
+ };
45443
45513
  });
45444
45514
  },
45445
45515
  setActiveTab: (tab2) => {
@@ -45449,6 +45519,9 @@ function ThreadProvider({ children }) {
45449
45519
  updateThreadState(threadId, (state) => ({
45450
45520
  fileContents: { ...state.fileContents, [path2]: content2 }
45451
45521
  }));
45522
+ },
45523
+ setDraftInput: (input) => {
45524
+ updateThreadState(threadId, () => ({ draftInput: input }));
45452
45525
  }
45453
45526
  };
45454
45527
  actionsCache.current[threadId] = actions;
@@ -45466,21 +45539,16 @@ function ThreadProvider({ children }) {
45466
45539
  if (metadata.currentModel) {
45467
45540
  actions.setCurrentModel(metadata.currentModel);
45468
45541
  }
45469
- }
45470
- } catch (error) {
45471
- console.error("[ThreadContext] Failed to load thread metadata:", error);
45472
- }
45473
- try {
45474
- const path2 = await window.api.workspace.get(threadId);
45475
- if (path2) {
45476
- actions.setWorkspacePath(path2);
45477
- const diskResult = await window.api.workspace.loadFromDisk(threadId);
45478
- if (diskResult.success) {
45479
- actions.setWorkspaceFiles(diskResult.files);
45542
+ if (metadata.workspacePath) {
45543
+ actions.setWorkspacePath(metadata.workspacePath);
45544
+ const diskResult = await window.api.workspace.loadFromDisk(threadId);
45545
+ if (diskResult.success) {
45546
+ actions.setWorkspaceFiles(diskResult.files);
45547
+ }
45480
45548
  }
45481
45549
  }
45482
45550
  } catch (error) {
45483
- console.error("[ThreadContext] Failed to load workspace path:", error);
45551
+ console.error("[ThreadContext] Failed to load thread metadata:", error);
45484
45552
  }
45485
45553
  try {
45486
45554
  const history = await window.api.threads.getHistory(threadId);
@@ -45561,7 +45629,7 @@ function ThreadProvider({ children }) {
45561
45629
  console.error("[ThreadContext] Failed to load thread history:", error);
45562
45630
  }
45563
45631
  },
45564
- [getThreadActions]
45632
+ [getThreadActions, updateThreadState]
45565
45633
  );
45566
45634
  const initializeThread = reactExports.useCallback(
45567
45635
  (threadId) => {
@@ -45587,7 +45655,7 @@ function ThreadProvider({ children }) {
45587
45655
  return next;
45588
45656
  });
45589
45657
  setThreadStates((prev) => {
45590
- const { [threadId]: _2, ...rest } = prev;
45658
+ const { [threadId]: _removed, ...rest } = prev;
45591
45659
  return rest;
45592
45660
  });
45593
45661
  }, []);
@@ -45598,9 +45666,22 @@ function ThreadProvider({ children }) {
45598
45666
  initializeThread,
45599
45667
  cleanupThread,
45600
45668
  subscribeToStream,
45601
- getStreamData
45669
+ getStreamData,
45670
+ getAllThreadStates,
45671
+ getAllStreamLoadingStates,
45672
+ subscribeToAllStreams
45602
45673
  }),
45603
- [getThreadState, getThreadActions, initializeThread, cleanupThread, subscribeToStream, getStreamData]
45674
+ [
45675
+ getThreadState,
45676
+ getThreadActions,
45677
+ initializeThread,
45678
+ cleanupThread,
45679
+ subscribeToStream,
45680
+ getStreamData,
45681
+ getAllThreadStates,
45682
+ getAllStreamLoadingStates,
45683
+ subscribeToAllStreams
45684
+ ]
45604
45685
  );
45605
45686
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(ThreadContext.Provider, { value: contextValue, children: [
45606
45687
  Array.from(activeThreadIds).map((threadId) => /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -45649,6 +45730,14 @@ function useThreadState(threadId) {
45649
45730
  const actions = context.getThreadActions(threadId);
45650
45731
  return { ...state, ...actions };
45651
45732
  }
45733
+ function useAllThreadStates() {
45734
+ const context = useThreadContext();
45735
+ return context.getAllThreadStates();
45736
+ }
45737
+ function useAllStreamLoadingStates() {
45738
+ const context = useThreadContext();
45739
+ return context.getAllStreamLoadingStates();
45740
+ }
45652
45741
  // @__NO_SIDE_EFFECTS__
45653
45742
  function createSlot$3(ownerName) {
45654
45743
  const SlotClone = /* @__PURE__ */ createSlotClone$3(ownerName);
@@ -50610,9 +50699,7 @@ var Portal2 = ContextMenuPortal;
50610
50699
  var Content2$1 = ContextMenuContent$1;
50611
50700
  var Item2 = ContextMenuItem$1;
50612
50701
  var Separator2 = ContextMenuSeparator$1;
50613
- function ContextMenu({
50614
- ...props
50615
- }) {
50702
+ function ContextMenu({ ...props }) {
50616
50703
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$1, { "data-slot": "context-menu", ...props });
50617
50704
  }
50618
50705
  function ContextMenuTrigger({
@@ -50669,11 +50756,15 @@ function ContextMenuSeparator({
50669
50756
  }
50670
50757
  );
50671
50758
  }
50672
- function ThreadLoadingIcon({ threadId }) {
50759
+ function ThreadStatusIcon$1({ threadId }) {
50673
50760
  const { isLoading } = useThreadStream(threadId);
50761
+ const { pendingApproval } = useCurrentThread(threadId);
50674
50762
  if (isLoading) {
50675
50763
  return /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 text-status-info animate-spin" });
50676
50764
  }
50765
+ if (pendingApproval) {
50766
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "size-4 shrink-0 text-status-warning" });
50767
+ }
50677
50768
  return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-muted-foreground" });
50678
50769
  }
50679
50770
  function ThreadListItem({
@@ -50702,7 +50793,7 @@ function ThreadListItem({
50702
50793
  }
50703
50794
  },
50704
50795
  children: [
50705
- /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadLoadingIcon, { threadId: thread.thread_id }),
50796
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadStatusIcon$1, { threadId: thread.thread_id }),
50706
50797
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0 overflow-hidden", children: isEditing ? /* @__PURE__ */ jsxRuntimeExports.jsx(
50707
50798
  "input",
50708
50799
  {
@@ -50744,17 +50835,10 @@ function ThreadListItem({
50744
50835
  "Rename"
50745
50836
  ] }),
50746
50837
  /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
50747
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
50748
- ContextMenuItem,
50749
- {
50750
- variant: "destructive",
50751
- onClick: onDelete,
50752
- children: [
50753
- /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4 mr-2" }),
50754
- "Delete"
50755
- ]
50756
- }
50757
- )
50838
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { variant: "destructive", onClick: onDelete, children: [
50839
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4 mr-2" }),
50840
+ "Delete"
50841
+ ] })
50758
50842
  ] })
50759
50843
  ] });
50760
50844
  }
@@ -50765,7 +50849,8 @@ function ThreadSidebar() {
50765
50849
  createThread,
50766
50850
  selectThread,
50767
50851
  deleteThread,
50768
- updateThread
50852
+ updateThread,
50853
+ setShowKanbanView
50769
50854
  } = useAppStore();
50770
50855
  const [editingThreadId, setEditingThreadId] = reactExports.useState(null);
50771
50856
  const [editingTitle, setEditingTitle] = reactExports.useState("");
@@ -50788,10 +50873,19 @@ function ThreadSidebar() {
50788
50873
  await createThread({ title: `Thread ${(/* @__PURE__ */ new Date()).toLocaleDateString()}` });
50789
50874
  };
50790
50875
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("aside", { className: "flex h-full w-full flex-col border-r border-border bg-sidebar overflow-hidden", children: [
50791
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2", style: { paddingTop: "calc(8px + var(--sidebar-safe-padding, 0px))" }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "ghost", size: "sm", className: "w-full justify-start gap-2", onClick: handleNewThread, children: [
50792
- /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
50793
- "New Thread"
50794
- ] }) }),
50876
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2", style: { paddingTop: "calc(8px + var(--sidebar-safe-padding, 0px))" }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
50877
+ Button,
50878
+ {
50879
+ variant: "ghost",
50880
+ size: "sm",
50881
+ className: "w-full justify-start gap-2",
50882
+ onClick: handleNewThread,
50883
+ children: [
50884
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
50885
+ "New Thread"
50886
+ ]
50887
+ }
50888
+ ) }),
50795
50889
  /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-2 space-y-1 overflow-hidden", children: [
50796
50890
  threads.map((thread) => /* @__PURE__ */ jsxRuntimeExports.jsx(
50797
50891
  ThreadListItem,
@@ -50810,10 +50904,26 @@ function ThreadSidebar() {
50810
50904
  thread.thread_id
50811
50905
  )),
50812
50906
  threads.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-8 text-center text-sm text-muted-foreground", children: "No threads yet" })
50813
- ] }) })
50907
+ ] }) }),
50908
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 border-t border-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
50909
+ Button,
50910
+ {
50911
+ variant: "ghost",
50912
+ size: "sm",
50913
+ className: "w-full justify-start gap-2",
50914
+ onClick: () => setShowKanbanView(true),
50915
+ children: [
50916
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LayoutGrid, { className: "size-4" }),
50917
+ "Overview"
50918
+ ]
50919
+ }
50920
+ ) })
50814
50921
  ] });
50815
50922
  }
50816
- function TabBar({ className, threadId: propThreadId }) {
50923
+ function TabBar({
50924
+ className,
50925
+ threadId: propThreadId
50926
+ }) {
50817
50927
  const { currentThreadId } = useAppStore();
50818
50928
  const threadId = propThreadId ?? currentThreadId;
50819
50929
  const threadState = useThreadState(threadId);
@@ -50821,36 +50931,42 @@ function TabBar({ className, threadId: propThreadId }) {
50821
50931
  return null;
50822
50932
  }
50823
50933
  const { openFiles, activeTab, setActiveTab, closeFile } = threadState;
50824
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn(
50825
- "flex items-center h-9 border-b border-border bg-sidebar overflow-x-auto scrollbar-hide",
50826
- className
50827
- ), children: [
50828
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
50829
- "button",
50830
- {
50831
- onClick: () => setActiveTab("agent"),
50832
- className: cn(
50833
- "flex items-center gap-2 px-4 h-full text-sm font-medium transition-colors shrink-0 border-r border-border",
50834
- activeTab === "agent" ? "bg-primary/15 text-primary border-b-2 border-b-primary" : "text-muted-foreground hover:text-foreground hover:bg-background-interactive"
50934
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
50935
+ "div",
50936
+ {
50937
+ className: cn(
50938
+ "flex items-center h-9 border-b border-border bg-sidebar overflow-x-auto scrollbar-hide",
50939
+ className
50940
+ ),
50941
+ children: [
50942
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
50943
+ "button",
50944
+ {
50945
+ onClick: () => setActiveTab("agent"),
50946
+ className: cn(
50947
+ "flex items-center gap-2 px-4 h-full text-sm font-medium transition-colors shrink-0 border-r border-border",
50948
+ activeTab === "agent" ? "bg-primary/15 text-primary border-b-2 border-b-primary" : "text-muted-foreground hover:text-foreground hover:bg-background-interactive"
50949
+ ),
50950
+ children: [
50951
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "size-4" }),
50952
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Agent" })
50953
+ ]
50954
+ }
50835
50955
  ),
50836
- children: [
50837
- /* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "size-4" }),
50838
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Agent" })
50839
- ]
50840
- }
50841
- ),
50842
- openFiles.map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
50843
- FileTab,
50844
- {
50845
- file,
50846
- isActive: activeTab === file.path,
50847
- onSelect: () => setActiveTab(file.path),
50848
- onClose: () => closeFile(file.path)
50849
- },
50850
- file.path
50851
- )),
50852
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0" })
50853
- ] });
50956
+ openFiles.map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
50957
+ FileTab,
50958
+ {
50959
+ file,
50960
+ isActive: activeTab === file.path,
50961
+ onSelect: () => setActiveTab(file.path),
50962
+ onClose: () => closeFile(file.path)
50963
+ },
50964
+ file.path
50965
+ )),
50966
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0" })
50967
+ ]
50968
+ }
50969
+ );
50854
50970
  }
50855
50971
  function FileTab({ file, isActive, onSelect, onClose }) {
50856
50972
  const handleClose = (e) => {
@@ -50925,27 +51041,8 @@ const IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
50925
51041
  "tiff",
50926
51042
  "tif"
50927
51043
  ]);
50928
- const VIDEO_EXTENSIONS = /* @__PURE__ */ new Set([
50929
- "mp4",
50930
- "webm",
50931
- "ogg",
50932
- "ogv",
50933
- "mov",
50934
- "avi",
50935
- "wmv",
50936
- "flv",
50937
- "mkv"
50938
- ]);
50939
- const AUDIO_EXTENSIONS = /* @__PURE__ */ new Set([
50940
- "mp3",
50941
- "wav",
50942
- "ogg",
50943
- "oga",
50944
- "m4a",
50945
- "flac",
50946
- "aac",
50947
- "weba"
50948
- ]);
51044
+ const VIDEO_EXTENSIONS = /* @__PURE__ */ new Set(["mp4", "webm", "ogg", "ogv", "mov", "avi", "wmv", "flv", "mkv"]);
51045
+ const AUDIO_EXTENSIONS = /* @__PURE__ */ new Set(["mp3", "wav", "ogg", "oga", "m4a", "flac", "aac", "weba"]);
50949
51046
  const PDF_EXTENSIONS = /* @__PURE__ */ new Set(["pdf"]);
50950
51047
  const CODE_EXTENSIONS = /* @__PURE__ */ new Set([
50951
51048
  "ts",
@@ -51057,36 +51154,36 @@ function getFileType(fileName) {
51057
51154
  function getMimeType(ext) {
51058
51155
  const mimeTypes = {
51059
51156
  // Images
51060
- "png": "image/png",
51061
- "jpg": "image/jpeg",
51062
- "jpeg": "image/jpeg",
51063
- "gif": "image/gif",
51064
- "svg": "image/svg+xml",
51065
- "webp": "image/webp",
51066
- "bmp": "image/bmp",
51067
- "ico": "image/x-icon",
51068
- "tiff": "image/tiff",
51069
- "tif": "image/tiff",
51157
+ png: "image/png",
51158
+ jpg: "image/jpeg",
51159
+ jpeg: "image/jpeg",
51160
+ gif: "image/gif",
51161
+ svg: "image/svg+xml",
51162
+ webp: "image/webp",
51163
+ bmp: "image/bmp",
51164
+ ico: "image/x-icon",
51165
+ tiff: "image/tiff",
51166
+ tif: "image/tiff",
51070
51167
  // Video
51071
- "mp4": "video/mp4",
51072
- "webm": "video/webm",
51073
- "ogg": "video/ogg",
51074
- "ogv": "video/ogg",
51075
- "mov": "video/quicktime",
51076
- "avi": "video/x-msvideo",
51077
- "wmv": "video/x-ms-wmv",
51078
- "flv": "video/x-flv",
51079
- "mkv": "video/x-matroska",
51168
+ mp4: "video/mp4",
51169
+ webm: "video/webm",
51170
+ ogg: "video/ogg",
51171
+ ogv: "video/ogg",
51172
+ mov: "video/quicktime",
51173
+ avi: "video/x-msvideo",
51174
+ wmv: "video/x-ms-wmv",
51175
+ flv: "video/x-flv",
51176
+ mkv: "video/x-matroska",
51080
51177
  // Audio
51081
- "mp3": "audio/mpeg",
51082
- "wav": "audio/wav",
51083
- "oga": "audio/ogg",
51084
- "m4a": "audio/mp4",
51085
- "flac": "audio/flac",
51086
- "aac": "audio/aac",
51087
- "weba": "audio/webm",
51178
+ mp3: "audio/mpeg",
51179
+ wav: "audio/wav",
51180
+ oga: "audio/ogg",
51181
+ m4a: "audio/mp4",
51182
+ flac: "audio/flac",
51183
+ aac: "audio/aac",
51184
+ weba: "audio/webm",
51088
51185
  // PDF
51089
- "pdf": "application/pdf"
51186
+ pdf: "application/pdf"
51090
51187
  };
51091
51188
  return mimeTypes[ext] || "application/octet-stream";
51092
51189
  }
@@ -61610,25 +61707,25 @@ const SUPPORTED_LANGS = /* @__PURE__ */ new Set([
61610
61707
  ]);
61611
61708
  function getLanguage(ext) {
61612
61709
  const langMap = {
61613
- "ts": "typescript",
61614
- "tsx": "tsx",
61615
- "js": "javascript",
61616
- "jsx": "jsx",
61617
- "mjs": "javascript",
61618
- "cjs": "javascript",
61619
- "py": "python",
61620
- "json": "json",
61621
- "css": "css",
61622
- "html": "html",
61623
- "htm": "html",
61624
- "md": "markdown",
61625
- "mdx": "markdown",
61626
- "yaml": "yaml",
61627
- "yml": "yaml",
61628
- "sh": "bash",
61629
- "bash": "bash",
61630
- "zsh": "bash",
61631
- "sql": "sql"
61710
+ ts: "typescript",
61711
+ tsx: "tsx",
61712
+ js: "javascript",
61713
+ jsx: "jsx",
61714
+ mjs: "javascript",
61715
+ cjs: "javascript",
61716
+ py: "python",
61717
+ json: "json",
61718
+ css: "css",
61719
+ html: "html",
61720
+ htm: "html",
61721
+ md: "markdown",
61722
+ mdx: "markdown",
61723
+ yaml: "yaml",
61724
+ yml: "yaml",
61725
+ sh: "bash",
61726
+ bash: "bash",
61727
+ zsh: "bash",
61728
+ sql: "sql"
61632
61729
  };
61633
61730
  const lang2 = ext ? langMap[ext] : null;
61634
61731
  return lang2 && SUPPORTED_LANGS.has(lang2) ? lang2 : null;
@@ -61678,19 +61775,17 @@ function CodeViewer({ filePath, content: content2 }) {
61678
61775
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/50", children: "•" }),
61679
61776
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/70", children: language || "plain text" })
61680
61777
  ] }),
61681
- /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shiki-wrapper", children: highlightedHtml ? /* @__PURE__ */ jsxRuntimeExports.jsx(
61682
- "div",
61683
- {
61684
- className: "shiki-content",
61685
- dangerouslySetInnerHTML: { __html: highlightedHtml }
61686
- }
61687
- ) : (
61778
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shiki-wrapper", children: highlightedHtml ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shiki-content", dangerouslySetInnerHTML: { __html: highlightedHtml } }) : (
61688
61779
  // Fallback plain text rendering
61689
61780
  /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "p-4 text-sm font-mono leading-relaxed whitespace-pre-wrap break-all", children: content2 })
61690
61781
  ) }) })
61691
61782
  ] });
61692
61783
  }
61693
- function ImageViewer({ filePath, base64Content, mimeType }) {
61784
+ function ImageViewer({
61785
+ filePath,
61786
+ base64Content,
61787
+ mimeType
61788
+ }) {
61694
61789
  const [zoom, setZoom] = reactExports.useState(100);
61695
61790
  const [rotation, setRotation] = reactExports.useState(0);
61696
61791
  const [isPanning, setIsPanning] = reactExports.useState(false);
@@ -61700,10 +61795,18 @@ function ImageViewer({ filePath, base64Content, mimeType }) {
61700
61795
  const fileName = filePath.split("/").pop() || filePath;
61701
61796
  const imageUrl = `data:${mimeType};base64,${base64Content}`;
61702
61797
  const handleZoomIn = () => {
61703
- setZoom((prev) => Math.min(prev + 25, 400));
61798
+ const newZoom = Math.min(zoom + 25, 400);
61799
+ setZoom(newZoom);
61800
+ if (newZoom <= 100) {
61801
+ setPanOffset({ x: 0, y: 0 });
61802
+ }
61704
61803
  };
61705
61804
  const handleZoomOut = () => {
61706
- setZoom((prev) => Math.max(prev - 25, 25));
61805
+ const newZoom = Math.max(zoom - 25, 25);
61806
+ setZoom(newZoom);
61807
+ if (newZoom <= 100) {
61808
+ setPanOffset({ x: 0, y: 0 });
61809
+ }
61707
61810
  };
61708
61811
  const handleResetZoom = () => {
61709
61812
  setZoom(100);
@@ -61734,11 +61837,6 @@ function ImageViewer({ filePath, base64Content, mimeType }) {
61734
61837
  const handleMouseLeave = () => {
61735
61838
  setIsPanning(false);
61736
61839
  };
61737
- reactExports.useEffect(() => {
61738
- if (zoom <= 100) {
61739
- setPanOffset({ x: 0, y: 0 });
61740
- }
61741
- }, [zoom]);
61742
61840
  const canPan = zoom > 100;
61743
61841
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col min-h-0 overflow-hidden", children: [
61744
61842
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2 px-4 py-2 border-b border-border bg-background/50 shrink-0", children: [
@@ -61781,26 +61879,8 @@ function ImageViewer({ filePath, base64Content, mimeType }) {
61781
61879
  children: /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomIn, { className: "size-4" })
61782
61880
  }
61783
61881
  ),
61784
- /* @__PURE__ */ jsxRuntimeExports.jsx(
61785
- Button,
61786
- {
61787
- variant: "ghost",
61788
- size: "sm",
61789
- onClick: handleRotate,
61790
- className: "h-7 px-2",
61791
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: "size-4" })
61792
- }
61793
- ),
61794
- /* @__PURE__ */ jsxRuntimeExports.jsx(
61795
- Button,
61796
- {
61797
- variant: "ghost",
61798
- size: "sm",
61799
- onClick: handleResetZoom,
61800
- className: "h-7 px-2",
61801
- children: /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "size-4" })
61802
- }
61803
- )
61882
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: handleRotate, className: "h-7 px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: "size-4" }) }),
61883
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: handleResetZoom, className: "h-7 px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "size-4" }) })
61804
61884
  ] })
61805
61885
  ] }),
61806
61886
  /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -61833,7 +61913,12 @@ function ImageViewer({ filePath, base64Content, mimeType }) {
61833
61913
  ) })
61834
61914
  ] });
61835
61915
  }
61836
- function MediaViewer({ filePath, base64Content, mimeType, mediaType }) {
61916
+ function MediaViewer({
61917
+ filePath,
61918
+ base64Content,
61919
+ mimeType,
61920
+ mediaType
61921
+ }) {
61837
61922
  const fileName = filePath.split("/").pop() || filePath;
61838
61923
  const mediaUrl = `data:${mimeType};base64,${base64Content}`;
61839
61924
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col min-h-0 overflow-hidden", children: [
@@ -61864,18 +61949,10 @@ function MediaViewer({ filePath, base64Content, mimeType, mediaType }) {
61864
61949
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground", children: "Audio File" })
61865
61950
  ] })
61866
61951
  ] }),
61867
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
61868
- "audio",
61869
- {
61870
- controls: true,
61871
- className: "w-full max-w-md",
61872
- preload: "metadata",
61873
- children: [
61874
- /* @__PURE__ */ jsxRuntimeExports.jsx("source", { src: mediaUrl, type: mimeType }),
61875
- "Your browser does not support the audio tag."
61876
- ]
61877
- }
61878
- )
61952
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("audio", { controls: true, className: "w-full max-w-md", preload: "metadata", children: [
61953
+ /* @__PURE__ */ jsxRuntimeExports.jsx("source", { src: mediaUrl, type: mimeType }),
61954
+ "Your browser does not support the audio tag."
61955
+ ] })
61879
61956
  ] }) }) })
61880
61957
  ] });
61881
61958
  }
@@ -61895,39 +61972,22 @@ function PDFViewer({ filePath, base64Content }) {
61895
61972
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/50", children: "•" }),
61896
61973
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "PDF Document" })
61897
61974
  ] }),
61898
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
61899
- Button,
61900
- {
61901
- variant: "ghost",
61902
- size: "sm",
61903
- onClick: handleOpenExternal,
61904
- className: "h-7 px-2 gap-1",
61905
- children: [
61906
- /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3" }),
61907
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs", children: "Download" })
61908
- ]
61909
- }
61910
- )
61975
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "ghost", size: "sm", onClick: handleOpenExternal, className: "h-7 px-2 gap-1", children: [
61976
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3" }),
61977
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs", children: "Download" })
61978
+ ] })
61911
61979
  ] }),
61912
- /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col items-center min-h-full bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
61913
- "object",
61914
- {
61915
- data: pdfUrl,
61916
- type: "application/pdf",
61917
- className: "w-full h-full min-h-[600px]",
61918
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center min-h-[600px] gap-4 p-8", children: [
61919
- /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "size-16 text-muted-foreground/50" }),
61920
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [
61921
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium text-foreground mb-2", children: fileName }),
61922
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground mb-4", children: "PDF preview not available in this browser" }),
61923
- /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: handleOpenExternal, variant: "outline", children: [
61924
- /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-4 mr-2" }),
61925
- "Download PDF"
61926
- ] })
61927
- ] })
61980
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col items-center min-h-full bg-muted/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx("object", { data: pdfUrl, type: "application/pdf", className: "w-full h-full min-h-[600px]", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center min-h-[600px] gap-4 p-8", children: [
61981
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "size-16 text-muted-foreground/50" }),
61982
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [
61983
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium text-foreground mb-2", children: fileName }),
61984
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground mb-4", children: "PDF preview not available in this browser" }),
61985
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: handleOpenExternal, variant: "outline", children: [
61986
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-4 mr-2" }),
61987
+ "Download PDF"
61928
61988
  ] })
61929
- }
61930
- ) }) })
61989
+ ] })
61990
+ ] }) }) }) })
61931
61991
  ] });
61932
61992
  }
61933
61993
  function BinaryFileViewer({ filePath, size: size2 }) {
@@ -62142,16 +62202,23 @@ function TodosDisplay({ todos }) {
62142
62202
  const config2 = statusConfig[todo.status] || defaultConfig;
62143
62203
  const Icon2 = config2.icon;
62144
62204
  const isDone = todo.status === "completed" || todo.status === "cancelled";
62145
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn(
62146
- "flex items-start gap-2 text-xs",
62147
- isDone && "opacity-50"
62148
- ), children: [
62149
- /* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: cn("size-3.5 mt-0.5 shrink-0", config2.color) }),
62150
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn(isDone && "line-through"), children: todo.content })
62151
- ] }, todo.id || i2);
62205
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
62206
+ "div",
62207
+ {
62208
+ className: cn("flex items-start gap-2 text-xs", isDone && "opacity-50"),
62209
+ children: [
62210
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: cn("size-3.5 mt-0.5 shrink-0", config2.color) }),
62211
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn(isDone && "line-through"), children: todo.content })
62212
+ ]
62213
+ },
62214
+ todo.id || i2
62215
+ );
62152
62216
  }) });
62153
62217
  }
62154
- function FileListDisplay({ files, isGlob }) {
62218
+ function FileListDisplay({
62219
+ files,
62220
+ isGlob
62221
+ }) {
62155
62222
  const items = files.slice(0, 15);
62156
62223
  const hasMore = files.length > 15;
62157
62224
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-0.5", children: [
@@ -62170,12 +62237,17 @@ function FileListDisplay({ files, isGlob }) {
62170
62237
  ] })
62171
62238
  ] });
62172
62239
  }
62173
- function GrepResultsDisplay({ matches: matches2 }) {
62174
- const grouped = matches2.reduce((acc, match) => {
62175
- if (!acc[match.path]) acc[match.path] = [];
62176
- acc[match.path].push(match);
62177
- return acc;
62178
- }, {});
62240
+ function GrepResultsDisplay({
62241
+ matches: matches2
62242
+ }) {
62243
+ const grouped = matches2.reduce(
62244
+ (acc, match) => {
62245
+ if (!acc[match.path]) acc[match.path] = [];
62246
+ acc[match.path].push(match);
62247
+ return acc;
62248
+ },
62249
+ {}
62250
+ );
62179
62251
  const files = Object.keys(grouped).slice(0, 5);
62180
62252
  const hasMore = Object.keys(grouped).length > 5;
62181
62253
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
@@ -62252,7 +62324,10 @@ function FileEditSummary({ args }) {
62252
62324
  }
62253
62325
  return null;
62254
62326
  }
62255
- function CommandDisplay({ command, output }) {
62327
+ function CommandDisplay({
62328
+ command,
62329
+ output
62330
+ }) {
62256
62331
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs space-y-2 w-full overflow-hidden", children: [
62257
62332
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono bg-background rounded-sm p-2 flex items-center gap-2 min-w-0", children: [
62258
62333
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-status-info shrink-0", children: "$" }),
@@ -62264,7 +62339,10 @@ function CommandDisplay({ command, output }) {
62264
62339
  ] })
62265
62340
  ] });
62266
62341
  }
62267
- function TaskDisplay({ args, isExpanded }) {
62342
+ function TaskDisplay({
62343
+ args,
62344
+ isExpanded
62345
+ }) {
62268
62346
  const name2 = args.name;
62269
62347
  const description = args.description;
62270
62348
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs space-y-1", children: [
@@ -62272,13 +62350,16 @@ function TaskDisplay({ args, isExpanded }) {
62272
62350
  /* @__PURE__ */ jsxRuntimeExports.jsx(GitBranch, { className: "size-3 text-status-info" }),
62273
62351
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium truncate", children: name2 })
62274
62352
  ] }),
62275
- description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: cn(
62276
- "text-muted-foreground pl-5",
62277
- !isExpanded && "line-clamp-2"
62278
- ), children: description })
62353
+ description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: cn("text-muted-foreground pl-5", !isExpanded && "line-clamp-2"), children: description })
62279
62354
  ] });
62280
62355
  }
62281
- function ToolCallRenderer({ toolCall, result, isError: isError2, needsApproval, onApprovalDecision }) {
62356
+ function ToolCallRenderer({
62357
+ toolCall,
62358
+ result,
62359
+ isError: isError2,
62360
+ needsApproval,
62361
+ onApprovalDecision
62362
+ }) {
62282
62363
  const args = toolCall?.args || {};
62283
62364
  const [isExpanded, setIsExpanded] = reactExports.useState(false);
62284
62365
  if (!toolCall) {
@@ -62358,7 +62439,9 @@ function ToolCallRenderer({ toolCall, result, isError: isError2, needsApproval,
62358
62439
  }
62359
62440
  case "ls": {
62360
62441
  if (Array.isArray(result)) {
62361
- const dirs = result.filter((f2) => typeof f2 === "object" && f2.is_dir).length;
62442
+ const dirs = result.filter(
62443
+ (f2) => typeof f2 === "object" && f2.is_dir
62444
+ ).length;
62362
62445
  const files = result.length - dirs;
62363
62446
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
62364
62447
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-status-nominal flex items-center gap-1.5", children: [
@@ -62491,72 +62574,89 @@ function ToolCallRenderer({ toolCall, result, isError: isError2, needsApproval,
62491
62574
  const formattedContent = renderFormattedContent();
62492
62575
  const formattedResult = renderFormattedResult();
62493
62576
  const hasFormattedDisplay = formattedContent || formattedResult;
62494
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cn(
62495
- "rounded-sm border overflow-hidden",
62496
- needsApproval ? "border-amber-500/50 bg-amber-500/5" : "border-border bg-background-elevated"
62497
- ), children: [
62498
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
62499
- "button",
62500
- {
62501
- onClick: () => setIsExpanded(!isExpanded),
62502
- className: "flex w-full items-center gap-2 px-3 py-2 hover:bg-background-interactive transition-colors",
62503
- children: [
62504
- isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 text-muted-foreground shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" }),
62505
- /* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: cn("size-4 shrink-0", needsApproval ? "text-amber-500" : "text-status-info") }),
62506
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium shrink-0", children: label }),
62507
- displayArg && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 truncate text-left text-xs text-muted-foreground font-mono", children: displayArg }),
62508
- needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "warning", className: "ml-auto shrink-0", children: "APPROVAL" }),
62509
- !needsApproval && result === void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "ml-auto shrink-0 animate-pulse", children: "RUNNING" }),
62510
- result !== void 0 && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: isError2 ? "critical" : "nominal", className: "ml-auto shrink-0", children: isError2 ? "ERROR" : "OK" }),
62511
- isPanelSynced && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "shrink-0 text-[9px]", children: "SYNCED" })
62512
- ]
62513
- }
62514
- ),
62515
- needsApproval ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-amber-500/20 px-3 py-3 space-y-3", children: [
62516
- formattedContent,
62517
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
62518
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header text-[10px] mb-1", children: "ARGUMENTS" }),
62519
- /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs font-mono bg-background p-2 rounded-sm overflow-auto max-h-24", children: JSON.stringify(args, null, 2) })
62520
- ] }),
62521
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-2", children: [
62522
- /* @__PURE__ */ jsxRuntimeExports.jsx(
62577
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
62578
+ "div",
62579
+ {
62580
+ className: cn(
62581
+ "rounded-sm border overflow-hidden",
62582
+ needsApproval ? "border-amber-500/50 bg-amber-500/5" : "border-border bg-background-elevated"
62583
+ ),
62584
+ children: [
62585
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
62523
62586
  "button",
62524
62587
  {
62525
- className: "px-3 py-1.5 text-xs border border-border rounded-sm hover:bg-background-interactive transition-colors",
62526
- onClick: handleReject,
62527
- children: "Reject"
62588
+ onClick: () => setIsExpanded(!isExpanded),
62589
+ className: "flex w-full items-center gap-2 px-3 py-2 hover:bg-background-interactive transition-colors",
62590
+ children: [
62591
+ isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-4 text-muted-foreground shrink-0" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-4 text-muted-foreground shrink-0" }),
62592
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
62593
+ Icon2,
62594
+ {
62595
+ className: cn("size-4 shrink-0", needsApproval ? "text-amber-500" : "text-status-info")
62596
+ }
62597
+ ),
62598
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium shrink-0", children: label }),
62599
+ displayArg && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 truncate text-left text-xs text-muted-foreground font-mono", children: displayArg }),
62600
+ needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "warning", className: "ml-auto shrink-0", children: "APPROVAL" }),
62601
+ !needsApproval && result === void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "ml-auto shrink-0 animate-pulse", children: "RUNNING" }),
62602
+ result !== void 0 && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: isError2 ? "critical" : "nominal", className: "ml-auto shrink-0", children: isError2 ? "ERROR" : "OK" }),
62603
+ isPanelSynced && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "shrink-0 text-[9px]", children: "SYNCED" })
62604
+ ]
62528
62605
  }
62529
62606
  ),
62530
- /* @__PURE__ */ jsxRuntimeExports.jsx(
62531
- "button",
62532
- {
62533
- className: "px-3 py-1.5 text-xs bg-status-nominal text-background rounded-sm hover:bg-status-nominal/90 transition-colors",
62534
- onClick: handleApprove,
62535
- children: "Approve & Run"
62536
- }
62537
- )
62538
- ] })
62539
- ] }) : null,
62540
- hasFormattedDisplay && !isExpanded && !needsApproval && result !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border px-3 py-2 space-y-2 overflow-hidden", children: [
62541
- formattedContent,
62542
- formattedResult
62543
- ] }),
62544
- isExpanded && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border px-3 py-2 space-y-2 overflow-hidden", children: [
62545
- formattedContent,
62546
- formattedResult,
62547
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden w-full", children: [
62548
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header mb-1", children: "RAW ARGUMENTS" }),
62549
- /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs font-mono bg-background p-2 rounded-sm overflow-auto max-h-48 w-full whitespace-pre-wrap break-all", children: JSON.stringify(args, null, 2) })
62550
- ] }),
62551
- result !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden w-full", children: [
62552
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header mb-1", children: "RAW RESULT" }),
62553
- /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: cn(
62554
- "text-xs font-mono p-2 rounded-sm overflow-auto max-h-48 w-full whitespace-pre-wrap break-all",
62555
- isError2 ? "bg-status-critical/10 text-status-critical" : "bg-background"
62556
- ), children: typeof result === "string" ? result : JSON.stringify(result, null, 2) })
62557
- ] })
62558
- ] })
62559
- ] });
62607
+ needsApproval ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-amber-500/20 px-3 py-3 space-y-3", children: [
62608
+ formattedContent,
62609
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
62610
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header text-[10px] mb-1", children: "ARGUMENTS" }),
62611
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs font-mono bg-background p-2 rounded-sm overflow-auto max-h-24", children: JSON.stringify(args, null, 2) })
62612
+ ] }),
62613
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-2", children: [
62614
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
62615
+ "button",
62616
+ {
62617
+ className: "px-3 py-1.5 text-xs border border-border rounded-sm hover:bg-background-interactive transition-colors",
62618
+ onClick: handleReject,
62619
+ children: "Reject"
62620
+ }
62621
+ ),
62622
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
62623
+ "button",
62624
+ {
62625
+ className: "px-3 py-1.5 text-xs bg-status-nominal text-background rounded-sm hover:bg-status-nominal/90 transition-colors",
62626
+ onClick: handleApprove,
62627
+ children: "Approve & Run"
62628
+ }
62629
+ )
62630
+ ] })
62631
+ ] }) : null,
62632
+ hasFormattedDisplay && !isExpanded && !needsApproval && result !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border px-3 py-2 space-y-2 overflow-hidden", children: [
62633
+ formattedContent,
62634
+ formattedResult
62635
+ ] }),
62636
+ isExpanded && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border px-3 py-2 space-y-2 overflow-hidden", children: [
62637
+ formattedContent,
62638
+ formattedResult,
62639
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden w-full", children: [
62640
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header mb-1", children: "RAW ARGUMENTS" }),
62641
+ /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-xs font-mono bg-background p-2 rounded-sm overflow-auto max-h-48 w-full whitespace-pre-wrap break-all", children: JSON.stringify(args, null, 2) })
62642
+ ] }),
62643
+ result !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden w-full", children: [
62644
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header mb-1", children: "RAW RESULT" }),
62645
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
62646
+ "pre",
62647
+ {
62648
+ className: cn(
62649
+ "text-xs font-mono p-2 rounded-sm overflow-auto max-h-48 w-full whitespace-pre-wrap break-all",
62650
+ isError2 ? "bg-status-critical/10 text-status-critical" : "bg-background"
62651
+ ),
62652
+ children: typeof result === "string" ? result : JSON.stringify(result, null, 2)
62653
+ }
62654
+ )
62655
+ ] })
62656
+ ] })
62657
+ ]
62658
+ }
62659
+ );
62560
62660
  }
62561
62661
  function ok$1() {
62562
62662
  }
@@ -73902,7 +74002,13 @@ const StreamingMarkdown = reactExports.memo(function StreamingMarkdown2({
73902
74002
  isStreaming && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-block w-2 h-4 ml-0.5 bg-foreground/70 animate-pulse" })
73903
74003
  ] });
73904
74004
  });
73905
- function MessageBubble({ message, isStreaming, toolResults, pendingApproval, onApprovalDecision }) {
74005
+ function MessageBubble({
74006
+ message,
74007
+ isStreaming,
74008
+ toolResults,
74009
+ pendingApproval,
74010
+ onApprovalDecision
74011
+ }) {
73906
74012
  const isUser = message.role === "user";
73907
74013
  const isTool = message.role === "tool";
73908
74014
  if (isTool) {
@@ -73945,14 +74051,14 @@ function MessageBubble({ message, isStreaming, toolResults, pendingApproval, onA
73945
74051
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-3 overflow-hidden", children: [
73946
74052
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-8 shrink-0", children: !isUser && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex size-8 items-center justify-center rounded-sm bg-status-info/10 text-status-info", children: getIcon() }) }),
73947
74053
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 space-y-2 overflow-hidden", children: [
73948
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn(
73949
- "text-section-header",
73950
- isUser && "text-right"
73951
- ), children: getLabel() }),
73952
- content2 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn(
73953
- "rounded-sm p-3 overflow-hidden",
73954
- isUser ? "bg-primary/10" : "bg-card"
73955
- ), children: content2 }),
74054
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("text-section-header", isUser && "text-right"), children: getLabel() }),
74055
+ content2 && /* @__PURE__ */ jsxRuntimeExports.jsx(
74056
+ "div",
74057
+ {
74058
+ className: cn("rounded-sm p-3 overflow-hidden", isUser ? "bg-primary/10" : "bg-card"),
74059
+ children: content2
74060
+ }
74061
+ ),
73956
74062
  hasToolCalls && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 overflow-hidden", children: message.tool_calls.map((toolCall, index2) => {
73957
74063
  const result = toolResults?.get(toolCall.id);
73958
74064
  const pendingId = pendingApproval?.tool_call?.id;
@@ -74333,14 +74439,10 @@ var Root2 = Popover$1;
74333
74439
  var Trigger = PopoverTrigger$1;
74334
74440
  var Portal$1 = PopoverPortal;
74335
74441
  var Content2 = PopoverContent$1;
74336
- function Popover({
74337
- ...props
74338
- }) {
74442
+ function Popover({ ...props }) {
74339
74443
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2, { "data-slot": "popover", ...props });
74340
74444
  }
74341
- function PopoverTrigger({
74342
- ...props
74343
- }) {
74445
+ function PopoverTrigger({ ...props }) {
74344
74446
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger, { "data-slot": "popover-trigger", ...props });
74345
74447
  }
74346
74448
  function PopoverContent({
@@ -74782,16 +74884,7 @@ const DialogContent = reactExports.forwardRef(({ className, children, ...props }
74782
74884
  )
74783
74885
  ] }));
74784
74886
  DialogContent.displayName = Content.displayName;
74785
- const DialogHeader = ({
74786
- className,
74787
- ...props
74788
- }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
74789
- "div",
74790
- {
74791
- className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className),
74792
- ...props
74793
- }
74794
- );
74887
+ const DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props });
74795
74888
  DialogHeader.displayName = "DialogHeader";
74796
74889
  const DialogTitle = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
74797
74890
  Title,
@@ -74831,10 +74924,13 @@ Input.displayName = "Input";
74831
74924
  const PROVIDER_INFO = {
74832
74925
  anthropic: { placeholder: "sk-ant-...", envVar: "ANTHROPIC_API_KEY" },
74833
74926
  openai: { placeholder: "sk-...", envVar: "OPENAI_API_KEY" },
74834
- google: { placeholder: "AIza...", envVar: "GOOGLE_API_KEY" },
74835
- custom: { placeholder: "your-api-key", envVar: "CUSTOM_API_KEY" }
74927
+ google: { placeholder: "AIza...", envVar: "GOOGLE_API_KEY" }
74836
74928
  };
74837
- function ApiKeyDialog({ open, onOpenChange, provider }) {
74929
+ function ApiKeyDialog({
74930
+ open,
74931
+ onOpenChange,
74932
+ provider
74933
+ }) {
74838
74934
  const [apiKey, setApiKey] = reactExports.useState("");
74839
74935
  const [showKey, setShowKey] = reactExports.useState(false);
74840
74936
  const [saving, setSaving] = reactExports.useState(false);
@@ -74965,14 +75061,14 @@ function ApiKeyDialog({ open, onOpenChange, provider }) {
74965
75061
  ] })
74966
75062
  ] }),
74967
75063
  provider.id === "custom" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
74968
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs text-muted-foreground", children: "Model Name (Optional)" }),
75064
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs text-muted-foreground", children: "Model Name (optional)" }),
74969
75065
  /* @__PURE__ */ jsxRuntimeExports.jsx(
74970
75066
  Input,
74971
75067
  {
74972
75068
  type: "text",
74973
75069
  value: modelName,
74974
75070
  onChange: (e) => setModelName(e.target.value),
74975
- placeholder: "gpt-4, claude-3-opus, etc."
75071
+ placeholder: "e.g., gpt-4"
74976
75072
  }
74977
75073
  ),
74978
75074
  /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground", children: [
@@ -74981,32 +75077,29 @@ function ApiKeyDialog({ open, onOpenChange, provider }) {
74981
75077
  ] })
74982
75078
  ] })
74983
75079
  ] }),
74984
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [
74985
- hasExistingKey ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
74986
- Button,
74987
- {
74988
- type: "button",
74989
- variant: "destructive",
74990
- size: "sm",
74991
- onClick: handleDelete2,
74992
- disabled: deleting || saving,
74993
- children: [
74994
- deleting ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin mr-2" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4 mr-2" }),
74995
- "Remove Key"
74996
- ]
74997
- }
74998
- ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", {}),
74999
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
75000
- /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "outline", onClick: () => onOpenChange(false), children: "Cancel" }),
75080
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between gap-2", children: [
75081
+ hasExistingKey && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "destructive", size: "sm", onClick: handleDelete2, disabled: deleting, children: deleting ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
75082
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin" }),
75083
+ "Removing..."
75084
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
75085
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4" }),
75086
+ "Remove"
75087
+ ] }) }),
75088
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 ml-auto", children: [
75001
75089
  /* @__PURE__ */ jsxRuntimeExports.jsx(
75002
75090
  Button,
75003
75091
  {
75004
- type: "button",
75005
- onClick: handleSave,
75006
- disabled: !apiKey.trim() || saving || provider.id === "custom" && !baseUrl.trim(),
75007
- children: saving ? /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin" }) : "Save"
75092
+ variant: "outline",
75093
+ size: "sm",
75094
+ onClick: () => onOpenChange(false),
75095
+ disabled: saving,
75096
+ children: "Cancel"
75008
75097
  }
75009
- )
75098
+ ),
75099
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", onClick: handleSave, disabled: saving || !apiKey.trim(), children: saving ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
75100
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin" }),
75101
+ "Saving..."
75102
+ ] }) : "Save" })
75010
75103
  ] })
75011
75104
  ] })
75012
75105
  ] }) });
@@ -75158,26 +75251,11 @@ function AddProviderDialog({ open, onOpenChange, onSuccess }) {
75158
75251
  ] })
75159
75252
  ] }),
75160
75253
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-end gap-2", children: [
75161
- /* @__PURE__ */ jsxRuntimeExports.jsx(
75162
- Button,
75163
- {
75164
- variant: "outline",
75165
- onClick: handleCancel,
75166
- disabled: saving,
75167
- children: "取消"
75168
- }
75169
- ),
75170
- /* @__PURE__ */ jsxRuntimeExports.jsx(
75171
- Button,
75172
- {
75173
- onClick: handleSave,
75174
- disabled: saving || !id || !name2 || !baseUrl || !apiKey,
75175
- children: saving ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
75176
- /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin mr-2" }),
75177
- "保存中..."
75178
- ] }) : "保存"
75179
- }
75180
- )
75254
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: handleCancel, disabled: saving, children: "取消" }),
75255
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: handleSave, disabled: saving || !id || !name2 || !baseUrl || !apiKey, children: saving ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
75256
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin mr-2" }),
75257
+ "保存中..."
75258
+ ] }) : "保存" })
75181
75259
  ] })
75182
75260
  ] }) });
75183
75261
  }
@@ -75191,11 +75269,21 @@ function GoogleIcon({ className }) {
75191
75269
  return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className, viewBox: "0 0 24 24", fill: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z" }) });
75192
75270
  }
75193
75271
  function CustomIcon({ className }) {
75194
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { className, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
75195
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
75196
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2 17l10 5 10-5" }),
75197
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2 12l10 5 10-5" })
75198
- ] });
75272
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
75273
+ "svg",
75274
+ {
75275
+ className,
75276
+ viewBox: "0 0 24 24",
75277
+ fill: "none",
75278
+ stroke: "currentColor",
75279
+ strokeWidth: "2",
75280
+ children: [
75281
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
75282
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2 17l10 5 10-5" }),
75283
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2 12l10 5 10-5" })
75284
+ ]
75285
+ }
75286
+ );
75199
75287
  }
75200
75288
  const PROVIDER_ICONS = {
75201
75289
  anthropic: AnthropicIcon,
@@ -75211,8 +75299,7 @@ function getProviderIcon(providerId) {
75211
75299
  const FALLBACK_PROVIDERS = [
75212
75300
  { id: "anthropic", name: "Anthropic", hasApiKey: false },
75213
75301
  { id: "openai", name: "OpenAI", hasApiKey: false },
75214
- { id: "google", name: "Google", hasApiKey: false },
75215
- { id: "custom", name: "Custom API", hasApiKey: false }
75302
+ { id: "google", name: "Google", hasApiKey: false }
75216
75303
  ];
75217
75304
  function ModelSwitcher({ threadId }) {
75218
75305
  const [open, setOpen] = reactExports.useState(false);
@@ -75227,20 +75314,10 @@ function ModelSwitcher({ threadId }) {
75227
75314
  loadProviders();
75228
75315
  }, [loadModels, loadProviders]);
75229
75316
  const displayProviders = providers.length > 0 ? providers : FALLBACK_PROVIDERS;
75230
- reactExports.useEffect(() => {
75231
- if (!selectedProviderId && currentModel) {
75232
- const model = models.find((m2) => m2.id === currentModel);
75233
- if (model) {
75234
- setSelectedProviderId(model.provider);
75235
- }
75236
- }
75237
- if (!selectedProviderId && displayProviders.length > 0) {
75238
- setSelectedProviderId(displayProviders[0].id);
75239
- }
75240
- }, [currentModel, models, selectedProviderId, displayProviders]);
75317
+ const effectiveProviderId = selectedProviderId || (currentModel ? models.find((m2) => m2.id === currentModel)?.provider : null) || (displayProviders.length > 0 ? displayProviders[0].id : null);
75241
75318
  const selectedModel = models.find((m2) => m2.id === currentModel);
75242
- const filteredModels = selectedProviderId ? models.filter((m2) => m2.provider === selectedProviderId) : [];
75243
- const selectedProvider = displayProviders.find((p2) => p2.id === selectedProviderId);
75319
+ const filteredModels = effectiveProviderId ? models.filter((m2) => m2.provider === effectiveProviderId) : [];
75320
+ const selectedProvider = displayProviders.find((p2) => p2.id === effectiveProviderId);
75244
75321
  function handleProviderClick(provider) {
75245
75322
  setSelectedProviderId(provider.id);
75246
75323
  }
@@ -75301,7 +75378,7 @@ function ModelSwitcher({ threadId }) {
75301
75378
  onClick: () => handleProviderClick(provider),
75302
75379
  className: cn(
75303
75380
  "w-full flex items-center gap-1.5 px-2 py-1 rounded-sm text-xs transition-colors text-left",
75304
- selectedProviderId === provider.id ? "bg-muted text-foreground" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
75381
+ effectiveProviderId === provider.id ? "bg-muted text-foreground" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
75305
75382
  ),
75306
75383
  children: [
75307
75384
  /* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: "size-3.5 shrink-0" }),
@@ -75321,10 +75398,20 @@ function ModelSwitcher({ threadId }) {
75321
75398
  },
75322
75399
  className: "w-full flex items-center justify-center gap-1.5 px-2 py-2 rounded-sm text-xs transition-colors text-muted-foreground hover:text-foreground hover:bg-muted/50 border-t border-border mt-1 pt-2",
75323
75400
  children: [
75324
- /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { className: "size-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
75325
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
75326
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
75327
- ] }),
75401
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
75402
+ "svg",
75403
+ {
75404
+ className: "size-4",
75405
+ viewBox: "0 0 24 24",
75406
+ fill: "none",
75407
+ stroke: "currentColor",
75408
+ strokeWidth: "2",
75409
+ children: [
75410
+ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
75411
+ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
75412
+ ]
75413
+ }
75414
+ ),
75328
75415
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "添加Provider" })
75329
75416
  ]
75330
75417
  }
@@ -75341,14 +75428,7 @@ function ModelSwitcher({ threadId }) {
75341
75428
  "API key required for ",
75342
75429
  selectedProvider.name
75343
75430
  ] }),
75344
- /* @__PURE__ */ jsxRuntimeExports.jsx(
75345
- Button,
75346
- {
75347
- size: "sm",
75348
- onClick: () => handleConfigureApiKey(selectedProvider),
75349
- children: "Configure API Key"
75350
- }
75351
- )
75431
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", onClick: () => handleConfigureApiKey(selectedProvider), children: "Configure API Key" })
75352
75432
  ] })
75353
75433
  ) : (
75354
75434
  // Show models list with scrollable area
@@ -75577,11 +75657,16 @@ const MODEL_CONTEXT_LIMITS = {
75577
75657
  "gpt-4o-mini": 128e3,
75578
75658
  "gpt-4-turbo": 128e3,
75579
75659
  "gpt-4": 8192,
75580
- "o1": 2e5,
75660
+ o1: 2e5,
75581
75661
  "o1-mini": 128e3,
75582
- "o3": 2e5,
75662
+ o3: 2e5,
75583
75663
  "o3-mini": 2e5,
75584
75664
  // Google models
75665
+ "gemini-3-pro-preview": 2e6,
75666
+ "gemini-3-flash-preview": 1e6,
75667
+ "gemini-2.5-pro": 2e6,
75668
+ "gemini-2.5-flash": 1e6,
75669
+ "gemini-2.5-flash-lite": 1e6,
75585
75670
  "gemini-2.0-flash": 1e6,
75586
75671
  "gemini-1.5-pro": 2e6,
75587
75672
  "gemini-1.5-flash": 1e6
@@ -75624,9 +75709,9 @@ function ContextUsageIndicator({
75624
75709
  const contextLimit = getContextLimit(modelId);
75625
75710
  const usedTokens = tokenUsage.inputTokens;
75626
75711
  const usagePercent = Math.min(usedTokens / contextLimit * 100, 100);
75627
- let colorClass = "text-muted-foreground";
75628
- let bgColorClass = "bg-muted-foreground/20";
75629
- let barColorClass = "bg-muted-foreground";
75712
+ let colorClass = "text-blue-500";
75713
+ let bgColorClass = "bg-blue-500/20";
75714
+ let barColorClass = "bg-blue-500";
75630
75715
  let statusText = "Normal";
75631
75716
  if (usagePercent >= 90) {
75632
75717
  colorClass = "text-red-500";
@@ -75670,96 +75755,97 @@ function ContextUsageIndicator({
75670
75755
  ]
75671
75756
  }
75672
75757
  ) }),
75673
- /* @__PURE__ */ jsxRuntimeExports.jsx(
75674
- PopoverContent,
75675
- {
75676
- className: "w-72 p-0 bg-background border-border",
75677
- align: "end",
75678
- sideOffset: 8,
75679
- children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-3 space-y-3", children: [
75680
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
75681
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-foreground", children: "Context Window" }),
75682
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn("text-[10px] font-medium px-1.5 py-0.5 rounded", bgColorClass, colorClass), children: statusText })
75683
- ] }),
75684
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
75685
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-2 bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
75686
- "div",
75687
- {
75688
- className: cn("h-full rounded-full transition-all", barColorClass),
75689
- style: { width: `${usagePercent}%` }
75690
- }
75691
- ) }),
75692
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-[10px] text-muted-foreground", children: [
75693
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
75694
- formatTokenCountFull(usedTokens),
75695
- " tokens"
75696
- ] }),
75697
- /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
75698
- formatTokenCountFull(contextLimit),
75699
- " max"
75700
- ] })
75701
- ] })
75758
+ /* @__PURE__ */ jsxRuntimeExports.jsx(PopoverContent, { className: "w-72 p-0 bg-background border-border", align: "end", sideOffset: 8, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-3 space-y-3", children: [
75759
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
75760
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-foreground", children: "Context Window" }),
75761
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
75762
+ "span",
75763
+ {
75764
+ className: cn(
75765
+ "text-[10px] font-medium px-1.5 py-0.5 rounded",
75766
+ bgColorClass,
75767
+ colorClass
75768
+ ),
75769
+ children: statusText
75770
+ }
75771
+ )
75772
+ ] }),
75773
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
75774
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-2 bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
75775
+ "div",
75776
+ {
75777
+ className: cn("h-full rounded-full transition-all", barColorClass),
75778
+ style: { width: `${usagePercent}%` }
75779
+ }
75780
+ ) }),
75781
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-[10px] text-muted-foreground", children: [
75782
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
75783
+ formatTokenCountFull(usedTokens),
75784
+ " tokens"
75702
75785
  ] }),
75703
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5 pt-2 border-t border-border", children: [
75704
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wider", children: "Token Breakdown" }),
75705
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
75706
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
75707
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
75708
- /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowUp, { className: "size-3" }),
75709
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Input" })
75710
- ] }),
75711
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.inputTokens) })
75712
- ] }),
75713
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
75714
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
75715
- /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowDown, { className: "size-3" }),
75716
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Output" })
75717
- ] }),
75718
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.outputTokens) })
75719
- ] }),
75720
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs pt-1 border-t border-border/50", children: [
75721
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
75722
- /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3" }),
75723
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Total" })
75724
- ] }),
75725
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.totalTokens) })
75726
- ] })
75727
- ] })
75786
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
75787
+ formatTokenCountFull(contextLimit),
75788
+ " max"
75789
+ ] })
75790
+ ] })
75791
+ ] }),
75792
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5 pt-2 border-t border-border", children: [
75793
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wider", children: "Token Breakdown" }),
75794
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
75795
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
75796
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
75797
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowUp, { className: "size-3" }),
75798
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Input" })
75799
+ ] }),
75800
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.inputTokens) })
75728
75801
  ] }),
75729
- hasCacheData && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5 pt-2 border-t border-border", children: [
75730
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wider", children: "Cache" }),
75731
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
75732
- tokenUsage.cacheReadTokens !== void 0 && tokenUsage.cacheReadTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
75733
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-green-500", children: [
75734
- /* @__PURE__ */ jsxRuntimeExports.jsx(Database, { className: "size-3" }),
75735
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Cache hits" })
75736
- ] }),
75737
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-green-500", children: formatTokenCountFull(tokenUsage.cacheReadTokens) })
75738
- ] }),
75739
- tokenUsage.cacheCreationTokens !== void 0 && tokenUsage.cacheCreationTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
75740
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-blue-500", children: [
75741
- /* @__PURE__ */ jsxRuntimeExports.jsx(Database, { className: "size-3" }),
75742
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Cache created" })
75743
- ] }),
75744
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-blue-500", children: formatTokenCountFull(tokenUsage.cacheCreationTokens) })
75745
- ] })
75746
- ] })
75802
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
75803
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
75804
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowDown, { className: "size-3" }),
75805
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Output" })
75806
+ ] }),
75807
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.outputTokens) })
75747
75808
  ] }),
75748
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-2 border-t border-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] text-muted-foreground", children: [
75749
- "Last updated: ",
75750
- tokenUsage.lastUpdated.toLocaleTimeString()
75751
- ] }) })
75809
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs pt-1 border-t border-border/50", children: [
75810
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
75811
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3" }),
75812
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Total" })
75813
+ ] }),
75814
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.totalTokens) })
75815
+ ] })
75752
75816
  ] })
75753
- }
75754
- )
75817
+ ] }),
75818
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5 pt-2 border-t border-border", children: [
75819
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wider", children: "Cache" }),
75820
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: hasCacheData ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
75821
+ tokenUsage.cacheReadTokens !== void 0 && tokenUsage.cacheReadTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
75822
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-green-500", children: [
75823
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Database, { className: "size-3" }),
75824
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Cache hits" })
75825
+ ] }),
75826
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-green-500", children: formatTokenCountFull(tokenUsage.cacheReadTokens) })
75827
+ ] }),
75828
+ tokenUsage.cacheCreationTokens !== void 0 && tokenUsage.cacheCreationTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
75829
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-blue-500", children: [
75830
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Database, { className: "size-3" }),
75831
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Cache created" })
75832
+ ] }),
75833
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-blue-500", children: formatTokenCountFull(tokenUsage.cacheCreationTokens) })
75834
+ ] })
75835
+ ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: "No cached tokens" }) })
75836
+ ] }),
75837
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-2 border-t border-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] text-muted-foreground", children: [
75838
+ "Last updated: ",
75839
+ tokenUsage.lastUpdated.toLocaleTimeString()
75840
+ ] }) })
75841
+ ] }) })
75755
75842
  ] });
75756
75843
  }
75757
75844
  function ChatContainer({ threadId }) {
75758
- const [input, setInput] = reactExports.useState("");
75759
75845
  const inputRef = reactExports.useRef(null);
75760
75846
  const scrollRef = reactExports.useRef(null);
75761
75847
  const isAtBottomRef = reactExports.useRef(true);
75762
- const { loadThreads, generateTitleForFirstMessage } = useAppStore();
75848
+ const { threads, loadThreads, generateTitleForFirstMessage } = useAppStore();
75763
75849
  const {
75764
75850
  messages: threadMessages,
75765
75851
  pendingApproval,
@@ -75768,13 +75854,15 @@ function ChatContainer({ threadId }) {
75768
75854
  workspacePath,
75769
75855
  tokenUsage,
75770
75856
  currentModel,
75857
+ draftInput: input,
75771
75858
  setTodos,
75772
75859
  setWorkspaceFiles,
75773
75860
  setWorkspacePath,
75774
75861
  setPendingApproval,
75775
75862
  appendMessage,
75776
75863
  setError,
75777
- clearError
75864
+ clearError,
75865
+ setDraftInput: setInput
75778
75866
  } = useCurrentThread(threadId);
75779
75867
  const streamData = useThreadStream(threadId);
75780
75868
  const stream = streamData.stream;
@@ -75784,12 +75872,15 @@ function ChatContainer({ threadId }) {
75784
75872
  if (!pendingApproval || !stream) return;
75785
75873
  setPendingApproval(null);
75786
75874
  try {
75787
- await stream.submit(null, { command: { resume: { decision } } });
75875
+ await stream.submit(null, {
75876
+ command: { resume: { decision } },
75877
+ config: { configurable: { thread_id: threadId, model_id: currentModel } }
75878
+ });
75788
75879
  } catch (err) {
75789
75880
  console.error("[ChatContainer] Resume command failed:", err);
75790
75881
  }
75791
75882
  },
75792
- [pendingApproval, setPendingApproval, stream]
75883
+ [pendingApproval, setPendingApproval, stream, threadId, currentModel]
75793
75884
  );
75794
75885
  const agentValues = stream?.values;
75795
75886
  const streamTodos = agentValues?.todos;
@@ -75924,7 +76015,11 @@ function ChatContainer({ threadId }) {
75924
76015
  };
75925
76016
  appendMessage(userMessage);
75926
76017
  if (isFirstMessage) {
75927
- generateTitleForFirstMessage(threadId, message);
76018
+ const currentThread = threads.find((t) => t.thread_id === threadId);
76019
+ const hasDefaultTitle = currentThread?.title?.startsWith("Thread ");
76020
+ if (hasDefaultTitle) {
76021
+ generateTitleForFirstMessage(threadId, message);
76022
+ }
75928
76023
  }
75929
76024
  await stream.submit(
75930
76025
  {
@@ -75932,7 +76027,7 @@ function ChatContainer({ threadId }) {
75932
76027
  },
75933
76028
  {
75934
76029
  config: {
75935
- configurable: { thread_id: threadId }
76030
+ configurable: { thread_id: threadId, model_id: currentModel }
75936
76031
  }
75937
76032
  }
75938
76033
  );
@@ -76034,7 +76129,17 @@ function ChatContainer({ threadId }) {
76034
76129
  style: { minHeight: "48px", maxHeight: "200px" }
76035
76130
  }
76036
76131
  ),
76037
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center shrink-0 h-12", children: isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: handleCancel, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Square, { className: "size-4" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "submit", variant: "default", size: "icon", disabled: !input.trim(), className: "rounded-md", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Send, { className: "size-4" }) }) })
76132
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center shrink-0 h-12", children: isLoading ? /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: handleCancel, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Square, { className: "size-4" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(
76133
+ Button,
76134
+ {
76135
+ type: "submit",
76136
+ variant: "default",
76137
+ size: "icon",
76138
+ disabled: !input.trim(),
76139
+ className: "rounded-md",
76140
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(Send, { className: "size-4" })
76141
+ }
76142
+ ) })
76038
76143
  ] }),
76039
76144
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
76040
76145
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
@@ -76063,6 +76168,781 @@ function TabbedPanel({ threadId, showTabBar = true }) {
76063
76168
  ) })
76064
76169
  ] });
76065
76170
  }
76171
+ function Switch({ checked = false, onCheckedChange, disabled = false, className, onClick, ...props }) {
76172
+ const handleClick = (e) => {
76173
+ onClick?.(e);
76174
+ if (!disabled) {
76175
+ onCheckedChange?.(!checked);
76176
+ }
76177
+ };
76178
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
76179
+ "button",
76180
+ {
76181
+ type: "button",
76182
+ role: "switch",
76183
+ "aria-checked": checked,
76184
+ disabled,
76185
+ onClick: handleClick,
76186
+ className: cn(
76187
+ "relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-white/20 focus:ring-offset-2 focus:ring-offset-[#0D0D0F] disabled:cursor-not-allowed disabled:opacity-50",
76188
+ checked ? "bg-blue-500" : "bg-white/10",
76189
+ className
76190
+ ),
76191
+ ...props,
76192
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
76193
+ "span",
76194
+ {
76195
+ className: cn(
76196
+ "pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out",
76197
+ checked ? "translate-x-4" : "translate-x-0"
76198
+ )
76199
+ }
76200
+ )
76201
+ }
76202
+ );
76203
+ }
76204
+ const SKILL_TEMPLATES = [
76205
+ {
76206
+ id: "custom-code-language",
76207
+ name: "Programming Language Expert",
76208
+ description: "Create a skill for a specific programming language",
76209
+ category: "coding",
76210
+ prompt: `You are an expert in {{LANGUAGE}} programming. Your expertise includes:
76211
+
76212
+ ## Core {{LANGUAGE}} Knowledge
76213
+ - Language syntax and best practices
76214
+ - Standard library and common frameworks
76215
+ - Idiomatic {{LANGUAGE}} code patterns
76216
+ - Performance considerations specific to {{LANGUAGE}}
76217
+
76218
+ ## Code Style
76219
+ - Follow {{LANGUAGE}} community conventions
76220
+ - Write clear, readable code
76221
+ - Use meaningful variable and function names
76222
+ - Add comments only when necessary
76223
+
76224
+ ## Common Patterns
76225
+ {{COMMON_PATTERNS}}
76226
+
76227
+ ## Best Practices
76228
+ {{BEST_PRACTICES}}
76229
+
76230
+ ## Testing
76231
+ - Testing frameworks for {{LANGUAGE}}
76232
+ - Writing testable code
76233
+ - Test organization and structure
76234
+
76235
+ When helping with {{LANGUAGE}}:
76236
+ 1. Follow modern {{LANGUAGE}} conventions
76237
+ 2. Use appropriate libraries and frameworks
76238
+ 3. Write idiomatic, clean code
76239
+ 4. Explain {{LANGUAGE}}-specific concepts`,
76240
+ variables: [
76241
+ {
76242
+ name: "LANGUAGE",
76243
+ label: "Programming Language",
76244
+ placeholder: "e.g., Rust, Go, Ruby, PHP",
76245
+ required: true
76246
+ },
76247
+ {
76248
+ name: "COMMON_PATTERNS",
76249
+ label: "Common Patterns",
76250
+ placeholder: "Describe common patterns in this language...",
76251
+ required: false
76252
+ },
76253
+ {
76254
+ name: "BEST_PRACTICES",
76255
+ label: "Best Practices",
76256
+ placeholder: "Describe best practices for this language...",
76257
+ required: false
76258
+ }
76259
+ ]
76260
+ },
76261
+ {
76262
+ id: "custom-framework",
76263
+ name: "Framework Expert",
76264
+ description: "Create a skill for a specific framework (React, Vue, Django, etc.)",
76265
+ category: "coding",
76266
+ prompt: `You are an expert in {{FRAMEWORK}} development. Your expertise includes:
76267
+
76268
+ ## {{FRAMEWORK}} Fundamentals
76269
+ - Framework architecture and design patterns
76270
+ - Component/model/view/controller structure
76271
+ - State management approaches
76272
+ - Routing and navigation
76273
+
76274
+ ## Best Practices
76275
+ - {{FRAMEWORK}} conventions and patterns
76276
+ - Performance optimization
76277
+ - Code organization and structure
76278
+ - Testing strategies
76279
+
76280
+ ## Common Tasks
76281
+ {{COMMON_TASKS}}
76282
+
76283
+ ## Ecosystem
76284
+ - Popular libraries and tools
76285
+ - Development workflow
76286
+ - Build and deployment
76287
+
76288
+ When working with {{FRAMEWORK}}:
76289
+ 1. Follow framework conventions
76290
+ 2. Use recommended patterns
76291
+ 3. Consider performance implications
76292
+ 4. Write maintainable code`,
76293
+ variables: [
76294
+ {
76295
+ name: "FRAMEWORK",
76296
+ label: "Framework Name",
76297
+ placeholder: "e.g., Laravel, Spring Boot, Express.js",
76298
+ required: true
76299
+ },
76300
+ {
76301
+ name: "COMMON_TASKS",
76302
+ label: "Common Tasks",
76303
+ placeholder: "List common tasks for this framework...",
76304
+ required: false
76305
+ }
76306
+ ]
76307
+ },
76308
+ {
76309
+ id: "custom-domain",
76310
+ name: "Domain Expert",
76311
+ description: "Create a skill for a specific domain (finance, healthcare, education, etc.)",
76312
+ category: "custom",
76313
+ prompt: `You are an expert in {{DOMAIN}}. Your expertise includes:
76314
+
76315
+ ## Domain Knowledge
76316
+ - {{DOMAIN}} terminology and concepts
76317
+ - Industry standards and regulations
76318
+ - Best practices and workflows
76319
+ - Common tools and technologies
76320
+
76321
+ ## Problem Solving
76322
+ - Typical {{DOMAIN}} challenges
76323
+ - Analytical approaches
76324
+ - Solution strategies
76325
+ - Decision-making frameworks
76326
+
76327
+ ## Communication
76328
+ - Explain {{DOMAIN}} concepts clearly
76329
+ - Use appropriate terminology
76330
+ - Provide context for technical decisions
76331
+ - Consider stakeholder needs
76332
+
76333
+ When helping with {{DOMAIN}}:
76334
+ 1. Understand the specific context
76335
+ 2. Apply domain-relevant knowledge
76336
+ 3. Consider industry standards
76337
+ 4. Explain domain-specific concepts`,
76338
+ variables: [
76339
+ {
76340
+ name: "DOMAIN",
76341
+ label: "Domain Name",
76342
+ placeholder: "e.g., Finance, Healthcare, E-commerce",
76343
+ required: true
76344
+ }
76345
+ ]
76346
+ },
76347
+ {
76348
+ id: "custom-tool",
76349
+ name: "Tool/CLI Expert",
76350
+ description: "Create a skill for a specific command-line tool or software",
76351
+ category: "system",
76352
+ prompt: `You are an expert in {{TOOL_NAME}}. Your expertise includes:
76353
+
76354
+ ## {{TOOL_NAME}} Overview
76355
+ - Tool purpose and use cases
76356
+ - Installation and setup
76357
+ - Basic commands and operations
76358
+ - Advanced features
76359
+
76360
+ ## Common Commands
76361
+ {{COMMON_COMMANDS}}
76362
+
76363
+ ## Best Practices
76364
+ - Efficient workflows
76365
+ - Common pitfalls and how to avoid them
76366
+ - Performance considerations
76367
+ - Integration with other tools
76368
+
76369
+ ## Troubleshooting
76370
+ - Common issues and solutions
76371
+ - Debugging techniques
76372
+ - Error interpretation
76373
+
76374
+ When helping with {{TOOL_NAME}}:
76375
+ 1. Provide clear command examples
76376
+ 2. Explain flags and options
76377
+ 3. Show expected output
76378
+ 4. Include troubleshooting tips`,
76379
+ variables: [
76380
+ {
76381
+ name: "TOOL_NAME",
76382
+ label: "Tool Name",
76383
+ placeholder: "e.g., Docker, Kubernetes, Git",
76384
+ required: true
76385
+ },
76386
+ {
76387
+ name: "COMMON_COMMANDS",
76388
+ label: "Common Commands",
76389
+ placeholder: "List common commands with examples...",
76390
+ required: false
76391
+ }
76392
+ ]
76393
+ },
76394
+ {
76395
+ id: "custom-language-learning",
76396
+ name: "Language Learning Assistant",
76397
+ description: "Create a skill for learning a human language",
76398
+ category: "creative",
76399
+ prompt: `You are a {{LANGUAGE}} language learning assistant. Your expertise includes:
76400
+
76401
+ ## Language Skills
76402
+ - {{LANGUAGE}} grammar and syntax
76403
+ - Vocabulary and expressions
76404
+ - Pronunciation guidance
76405
+ - Cultural context and nuances
76406
+
76407
+ ## Teaching Approach
76408
+ - Explain concepts clearly
76409
+ - Provide examples and practice
76410
+ - Correct mistakes gently
76411
+ - Encourage conversation practice
76412
+
76413
+ ## Learning Resources
76414
+ - Common learning materials
76415
+ - Practice exercises
76416
+ - Real-world usage examples
76417
+ - Tips for effective learning
76418
+
76419
+ When helping with {{LANGUAGE}}:
76420
+ 1. Assess current skill level
76421
+ 2. Provide appropriate level instruction
76422
+ 3. Use natural examples
76423
+ 4. Encourage practice and immersion`,
76424
+ variables: [
76425
+ {
76426
+ name: "LANGUAGE",
76427
+ label: "Language",
76428
+ placeholder: "e.g., Spanish, Japanese, German",
76429
+ required: true
76430
+ }
76431
+ ]
76432
+ }
76433
+ ];
76434
+ function renderTemplate(template, values) {
76435
+ let rendered = template.prompt;
76436
+ for (const variable of template.variables || []) {
76437
+ const value = values[variable.name] || "";
76438
+ const placeholder = `{{${variable.name}}}`;
76439
+ rendered = rendered.replace(new RegExp(placeholder, "g"), value);
76440
+ }
76441
+ return rendered;
76442
+ }
76443
+ const categories = [
76444
+ { value: "coding", label: "Coding", description: "Programming and development tasks" },
76445
+ { value: "analysis", label: "Analysis", description: "Data analysis and research" },
76446
+ { value: "creative", label: "Creative", description: "Writing and creative work" },
76447
+ { value: "data", label: "Data", description: "Database and data management" },
76448
+ { value: "system", label: "System", description: "System operations and debugging" },
76449
+ { value: "custom", label: "Custom", description: "Other specialized skills" }
76450
+ ];
76451
+ function CreateSkillDialog({ open, onClose, onCreate }) {
76452
+ const [mode, setMode] = reactExports.useState("custom");
76453
+ const [selectedTemplate, setSelectedTemplate] = reactExports.useState(null);
76454
+ const [templateValues, setTemplateValues] = reactExports.useState({});
76455
+ const [name2, setName] = reactExports.useState("");
76456
+ const [description, setDescription] = reactExports.useState("");
76457
+ const [category, setCategory] = reactExports.useState("custom");
76458
+ const [prompt, setPrompt] = reactExports.useState("");
76459
+ reactExports.useEffect(() => {
76460
+ if (!open) {
76461
+ setMode("custom");
76462
+ setSelectedTemplate(null);
76463
+ setTemplateValues({});
76464
+ setName("");
76465
+ setDescription("");
76466
+ setCategory("custom");
76467
+ setPrompt("");
76468
+ }
76469
+ }, [open]);
76470
+ reactExports.useEffect(() => {
76471
+ if (mode === "template" && selectedTemplate) {
76472
+ const template = SKILL_TEMPLATES.find((t) => t.id === selectedTemplate);
76473
+ if (template) {
76474
+ setCategory(template.category);
76475
+ setName(template.name.replace(/{{.*?}}/g, "Custom"));
76476
+ setDescription(template.description);
76477
+ setPrompt(template.prompt);
76478
+ }
76479
+ }
76480
+ }, [selectedTemplate, mode]);
76481
+ const handleSubmit = (e) => {
76482
+ e.preventDefault();
76483
+ const finalPrompt = mode === "template" && selectedTemplate ? renderTemplate(SKILL_TEMPLATES.find((t) => t.id === selectedTemplate), templateValues) : prompt;
76484
+ if (!name2.trim() || !description.trim() || !finalPrompt.trim()) {
76485
+ return;
76486
+ }
76487
+ onCreate({
76488
+ name: name2.trim(),
76489
+ description: description.trim(),
76490
+ category,
76491
+ prompt: finalPrompt.trim()
76492
+ });
76493
+ setMode("custom");
76494
+ setSelectedTemplate(null);
76495
+ setTemplateValues({});
76496
+ setName("");
76497
+ setDescription("");
76498
+ setCategory("custom");
76499
+ setPrompt("");
76500
+ onClose();
76501
+ };
76502
+ const currentTemplate = SKILL_TEMPLATES.find((t) => t.id === selectedTemplate);
76503
+ if (!open) return null;
76504
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full max-w-3xl mx-4 bg-[#1A1A1D] rounded-lg shadow-xl border border-white/10", children: [
76505
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-white/5", children: [
76506
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-white", children: "Create Custom Skill" }),
76507
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76508
+ "button",
76509
+ {
76510
+ onClick: onClose,
76511
+ className: "text-gray-400 hover:text-white transition-colors",
76512
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
76513
+ }
76514
+ )
76515
+ ] }),
76516
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-6 py-3 border-b border-white/5", children: [
76517
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76518
+ "button",
76519
+ {
76520
+ type: "button",
76521
+ onClick: () => setMode("custom"),
76522
+ className: `px-4 py-2 text-sm font-medium rounded-md transition-colors ${mode === "custom" ? "bg-blue-500 text-white" : "bg-white/5 text-gray-400 hover:bg-white/10"}`,
76523
+ children: "Custom"
76524
+ }
76525
+ ),
76526
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76527
+ "button",
76528
+ {
76529
+ type: "button",
76530
+ onClick: () => setMode("template"),
76531
+ className: `px-4 py-2 text-sm font-medium rounded-md transition-colors ${mode === "template" ? "bg-blue-500 text-white" : "bg-white/5 text-gray-400 hover:bg-white/10"}`,
76532
+ children: "From Template"
76533
+ }
76534
+ )
76535
+ ] }),
76536
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, className: "p-6 space-y-4", children: [
76537
+ mode === "template" && /* Template Selection */
76538
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76539
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-300 mb-2", children: "Choose Template" }),
76540
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-2 max-h-48 overflow-y-auto", children: SKILL_TEMPLATES.map((template) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
76541
+ "button",
76542
+ {
76543
+ type: "button",
76544
+ onClick: () => setSelectedTemplate(template.id),
76545
+ className: `px-3 py-2 text-left text-sm rounded-md transition-colors ${selectedTemplate === template.id ? "bg-blue-500/20 text-blue-400 border border-blue-500/50" : "bg-white/5 text-gray-400 border border-white/10 hover:bg-white/10"}`,
76546
+ children: [
76547
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: template.name }),
76548
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs opacity-75", children: template.description })
76549
+ ]
76550
+ },
76551
+ template.id
76552
+ )) })
76553
+ ] }),
76554
+ mode === "template" && currentTemplate && currentTemplate.variables && currentTemplate.variables.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3 p-4 bg-white/5 rounded-lg border border-white/10", children: [
76555
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-white", children: "Customize Template" }),
76556
+ currentTemplate.variables.map((variable) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76557
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm text-gray-300 mb-1", children: [
76558
+ variable.label,
76559
+ variable.required && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: " *" })
76560
+ ] }),
76561
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76562
+ "input",
76563
+ {
76564
+ type: "text",
76565
+ value: templateValues[variable.name] || "",
76566
+ onChange: (e) => setTemplateValues({ ...templateValues, [variable.name]: e.target.value }),
76567
+ placeholder: variable.placeholder,
76568
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-blue-500",
76569
+ required: variable.required
76570
+ }
76571
+ )
76572
+ ] }, variable.name))
76573
+ ] }),
76574
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76575
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-300 mb-1", children: [
76576
+ "Skill Name ",
76577
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
76578
+ ] }),
76579
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76580
+ "input",
76581
+ {
76582
+ type: "text",
76583
+ value: name2,
76584
+ onChange: (e) => setName(e.target.value),
76585
+ placeholder: "e.g., React Expert, Python Specialist",
76586
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-blue-500",
76587
+ required: true
76588
+ }
76589
+ )
76590
+ ] }),
76591
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76592
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-300 mb-1", children: [
76593
+ "Description ",
76594
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
76595
+ ] }),
76596
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76597
+ "input",
76598
+ {
76599
+ type: "text",
76600
+ value: description,
76601
+ onChange: (e) => setDescription(e.target.value),
76602
+ placeholder: "Brief description of what this skill does",
76603
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-blue-500",
76604
+ required: true
76605
+ }
76606
+ )
76607
+ ] }),
76608
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76609
+ /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-300 mb-2", children: "Category" }),
76610
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-3 gap-2", children: categories.map((cat) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
76611
+ "button",
76612
+ {
76613
+ type: "button",
76614
+ onClick: () => setCategory(cat.value),
76615
+ className: `px-3 py-2 text-left text-sm rounded-md transition-colors ${category === cat.value ? "bg-blue-500/20 text-blue-400 border border-blue-500/50" : "bg-white/5 text-gray-400 border border-white/10 hover:bg-white/10"}`,
76616
+ children: [
76617
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: cat.label }),
76618
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs opacity-75", children: cat.description })
76619
+ ]
76620
+ },
76621
+ cat.value
76622
+ )) })
76623
+ ] }),
76624
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76625
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-300 mb-1", children: [
76626
+ "Specialized Prompt ",
76627
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
76628
+ ] }),
76629
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76630
+ "textarea",
76631
+ {
76632
+ value: prompt,
76633
+ onChange: (e) => setPrompt(e.target.value),
76634
+ placeholder: "Enter the specialized instructions and expertise for this skill...",
76635
+ rows: 8,
76636
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-blue-500 resize-none",
76637
+ required: true
76638
+ }
76639
+ ),
76640
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500", children: "This prompt will be loaded when the agent activates this skill, providing specialized knowledge and instructions." })
76641
+ ] }),
76642
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-3 pt-4 border-t border-white/5", children: [
76643
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76644
+ "button",
76645
+ {
76646
+ type: "button",
76647
+ onClick: onClose,
76648
+ className: "px-4 py-2 text-sm text-gray-400 hover:text-white transition-colors",
76649
+ children: "Cancel"
76650
+ }
76651
+ ),
76652
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76653
+ "button",
76654
+ {
76655
+ type: "submit",
76656
+ disabled: !name2.trim() || !description.trim() || !prompt.trim(),
76657
+ className: "px-4 py-2 text-sm text-white bg-blue-500 hover:bg-blue-600 disabled:bg-gray-600 disabled:cursor-not-allowed rounded-md transition-colors",
76658
+ children: "Create Skill"
76659
+ }
76660
+ )
76661
+ ] })
76662
+ ] })
76663
+ ] }) });
76664
+ }
76665
+ const categoryColors = {
76666
+ coding: "bg-blue-500/10 text-blue-500 border-blue-500/20",
76667
+ analysis: "bg-purple-500/10 text-purple-500 border-purple-500/20",
76668
+ creative: "bg-pink-500/10 text-pink-500 border-pink-500/20",
76669
+ data: "bg-green-500/10 text-green-500 border-green-500/20",
76670
+ system: "bg-orange-500/10 text-orange-500 border-orange-500/20",
76671
+ custom: "bg-cyan-500/10 text-cyan-500 border-cyan-500/20"
76672
+ };
76673
+ function SkillDetailDialog({ skill, open, onClose, onToggle, onDelete }) {
76674
+ if (!open) return null;
76675
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-full max-w-3xl mx-4 max-h-[80vh] bg-[#1A1A1D] rounded-lg shadow-xl border border-white/10 flex flex-col", children: [
76676
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between px-6 py-4 border-b border-white/5", children: [
76677
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
76678
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
76679
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold text-white", children: skill.name }),
76680
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76681
+ "span",
76682
+ {
76683
+ className: `px-2 py-0.5 text-xs font-medium rounded border ${categoryColors[skill.category] || categoryColors.custom}`,
76684
+ children: skill.category
76685
+ }
76686
+ ),
76687
+ skill.isBuiltin && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "px-2 py-0.5 text-xs font-medium rounded bg-white/5 text-gray-400 border border-white/10", children: "Built-in" })
76688
+ ] }),
76689
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-400", children: skill.description })
76690
+ ] }),
76691
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76692
+ "button",
76693
+ {
76694
+ onClick: onClose,
76695
+ className: "ml-4 text-gray-400 hover:text-white transition-colors",
76696
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
76697
+ }
76698
+ )
76699
+ ] }),
76700
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: [
76701
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-4 mb-6", children: [
76702
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white/5 rounded-lg p-3 border border-white/5", children: [
76703
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 mb-1", children: "Status" }),
76704
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium text-white", children: skill.enabled ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-green-400", children: "Enabled" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-400", children: "Disabled" }) })
76705
+ ] }),
76706
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white/5 rounded-lg p-3 border border-white/5", children: [
76707
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 mb-1", children: "Type" }),
76708
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-medium text-white", children: skill.isBuiltin ? "Built-in Skill" : "Custom Skill" })
76709
+ ] })
76710
+ ] }),
76711
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
76712
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-gray-300 mb-2", children: "Specialized Prompt" }),
76713
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-white/5 rounded-lg p-4 border border-white/5", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "text-sm text-gray-300 whitespace-pre-wrap font-mono", children: skill.prompt }) })
76714
+ ] }),
76715
+ skill.subSkills && skill.subSkills.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76716
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-gray-300 mb-2", children: "Sub Skills" }),
76717
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-2", children: skill.subSkills.map((subSkill) => /* @__PURE__ */ jsxRuntimeExports.jsx(
76718
+ "span",
76719
+ {
76720
+ className: "px-3 py-1 text-sm bg-white/5 text-gray-300 rounded-md border border-white/10",
76721
+ children: subSkill
76722
+ },
76723
+ subSkill
76724
+ )) })
76725
+ ] })
76726
+ ] }),
76727
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-t border-white/5", children: [
76728
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-gray-500", children: [
76729
+ "Created: ",
76730
+ new Date(skill.createdAt).toLocaleDateString(),
76731
+ " • Updated:",
76732
+ " ",
76733
+ new Date(skill.updatedAt).toLocaleDateString()
76734
+ ] }),
76735
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
76736
+ !skill.isBuiltin && onDelete && /* @__PURE__ */ jsxRuntimeExports.jsx(
76737
+ "button",
76738
+ {
76739
+ onClick: () => {
76740
+ if (confirm(`Are you sure you want to delete "${skill.name}"?`)) {
76741
+ onDelete(skill.id);
76742
+ onClose();
76743
+ }
76744
+ },
76745
+ className: "px-4 py-2 text-sm text-red-400 hover:text-red-300 hover:bg-red-500/10 rounded-md transition-colors",
76746
+ children: "Delete"
76747
+ }
76748
+ ),
76749
+ onToggle && /* @__PURE__ */ jsxRuntimeExports.jsx(
76750
+ "button",
76751
+ {
76752
+ onClick: () => onToggle(skill.id, !skill.enabled),
76753
+ className: `px-4 py-2 text-sm rounded-md transition-colors ${skill.enabled ? "bg-white/10 text-gray-300 hover:bg-white/15" : "bg-blue-500 text-white hover:bg-blue-600"}`,
76754
+ children: skill.enabled ? "Disable" : "Enable"
76755
+ }
76756
+ ),
76757
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76758
+ "button",
76759
+ {
76760
+ onClick: onClose,
76761
+ className: "px-4 py-2 text-sm text-white bg-white/10 hover:bg-white/15 rounded-md transition-colors",
76762
+ children: "Close"
76763
+ }
76764
+ )
76765
+ ] })
76766
+ ] })
76767
+ ] }) });
76768
+ }
76769
+ function SkillsPanel(_props) {
76770
+ const [skills, setSkills] = reactExports.useState([]);
76771
+ const [loading, setLoading] = reactExports.useState(true);
76772
+ const [filter, setFilter] = reactExports.useState("all");
76773
+ const [searchQuery, setSearchQuery] = reactExports.useState("");
76774
+ const [showCreateDialog, setShowCreateDialog] = reactExports.useState(false);
76775
+ const [selectedSkill, setSelectedSkill] = reactExports.useState(null);
76776
+ reactExports.useEffect(() => {
76777
+ loadSkills();
76778
+ }, []);
76779
+ const loadSkills = async () => {
76780
+ setLoading(true);
76781
+ try {
76782
+ const result = await window.api.skills.list();
76783
+ if (result.success && result.skills) {
76784
+ setSkills(result.skills);
76785
+ }
76786
+ } catch (error) {
76787
+ console.error("Failed to load skills:", error);
76788
+ } finally {
76789
+ setLoading(false);
76790
+ }
76791
+ };
76792
+ const toggleSkill = async (skillId, enabled) => {
76793
+ const result = await window.api.skills.toggle(skillId, enabled);
76794
+ if (result.success) {
76795
+ setSkills(
76796
+ (prev) => prev.map((s2) => s2.id === skillId ? { ...s2, enabled: result.enabled ?? false } : s2)
76797
+ );
76798
+ }
76799
+ };
76800
+ const handleCreateSkill = async (skill) => {
76801
+ const result = await window.api.skills.create(skill);
76802
+ if (result.success) {
76803
+ loadSkills();
76804
+ }
76805
+ };
76806
+ const handleDeleteSkill = async (skillId) => {
76807
+ const result = await window.api.skills.delete(skillId);
76808
+ if (result.success) {
76809
+ loadSkills();
76810
+ }
76811
+ };
76812
+ const filteredSkills = skills.filter((skill) => {
76813
+ if (searchQuery) {
76814
+ const query = searchQuery.toLowerCase();
76815
+ if (!skill.name.toLowerCase().includes(query) && !skill.description.toLowerCase().includes(query)) {
76816
+ return false;
76817
+ }
76818
+ }
76819
+ if (filter === "enabled") return skill.enabled;
76820
+ if (filter === "builtin") return skill.isBuiltin;
76821
+ if (filter === "user") return !skill.isBuiltin;
76822
+ return true;
76823
+ });
76824
+ const groupedSkills = filteredSkills.reduce(
76825
+ (acc, skill) => {
76826
+ if (!acc[skill.category]) {
76827
+ acc[skill.category] = [];
76828
+ }
76829
+ acc[skill.category].push(skill);
76830
+ return acc;
76831
+ },
76832
+ {}
76833
+ );
76834
+ const categoryColors2 = {
76835
+ coding: "bg-blue-500/10 text-blue-500",
76836
+ analysis: "bg-purple-500/10 text-purple-500",
76837
+ creative: "bg-pink-500/10 text-pink-500",
76838
+ data: "bg-green-500/10 text-green-500",
76839
+ system: "bg-orange-500/10 text-orange-500",
76840
+ custom: "bg-cyan-500/10 text-cyan-500"
76841
+ };
76842
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
76843
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col h-full bg-[#0D0D0F]", children: [
76844
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-white/5", children: [
76845
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-white", children: "Skills" }),
76846
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
76847
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76848
+ "button",
76849
+ {
76850
+ onClick: () => setShowCreateDialog(true),
76851
+ className: "px-3 py-1 text-xs font-medium text-white bg-blue-500 hover:bg-blue-600 rounded-md transition-colors",
76852
+ children: "+ New Skill"
76853
+ }
76854
+ ),
76855
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm text-gray-400", children: [
76856
+ skills.filter((s2) => s2.enabled).length,
76857
+ " / ",
76858
+ skills.length,
76859
+ " enabled"
76860
+ ] })
76861
+ ] })
76862
+ ] }),
76863
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 px-4 py-3 border-b border-white/5", children: [
76864
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76865
+ "input",
76866
+ {
76867
+ type: "text",
76868
+ placeholder: "Search skills...",
76869
+ value: searchQuery,
76870
+ onChange: (e) => setSearchQuery(e.target.value),
76871
+ className: "w-full px-3 py-2 text-sm text-white placeholder-gray-500 bg-white/5 border border-white/10 rounded-md focus:outline-none focus:border-white/20"
76872
+ }
76873
+ ),
76874
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2", children: ["all", "enabled", "builtin", "user"].map((f2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
76875
+ "button",
76876
+ {
76877
+ onClick: () => setFilter(f2),
76878
+ className: `px-3 py-1 text-xs rounded-md transition-colors ${filter === f2 ? "bg-white/10 text-white" : "text-gray-400 hover:text-white hover:bg-white/5"}`,
76879
+ children: f2.charAt(0).toUpperCase() + f2.slice(1)
76880
+ },
76881
+ f2
76882
+ )) })
76883
+ ] }),
76884
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4", children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-32", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-400", children: "Loading skills..." }) }) : filteredSkills.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col items-center justify-center h-32 text-gray-400", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm", children: "No skills found" }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: Object.entries(groupedSkills).map(([category, categorySkills]) => {
76885
+ const skillsList = categorySkills;
76886
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
76887
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-medium text-gray-300 mb-2 capitalize", children: category }),
76888
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: skillsList.map((skill) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
76889
+ "div",
76890
+ {
76891
+ onClick: () => setSelectedSkill(skill),
76892
+ className: "flex items-start justify-between p-3 rounded-lg bg-white/5 hover:bg-white/10 transition-colors cursor-pointer",
76893
+ children: [
76894
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
76895
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
76896
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-white", children: skill.name }),
76897
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76898
+ Badge,
76899
+ {
76900
+ className: categoryColors2[skill.category] || categoryColors2.custom,
76901
+ children: skill.category
76902
+ }
76903
+ ),
76904
+ skill.isBuiltin && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { className: "bg-white/5 text-gray-400 text-xs", children: "Built-in" })
76905
+ ] }),
76906
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 line-clamp-2", children: skill.description })
76907
+ ] }),
76908
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76909
+ Switch,
76910
+ {
76911
+ checked: skill.enabled,
76912
+ onCheckedChange: (checked) => {
76913
+ toggleSkill(skill.id, checked);
76914
+ },
76915
+ onClick: (e) => e.stopPropagation(),
76916
+ className: "ml-3 flex-shrink-0"
76917
+ }
76918
+ )
76919
+ ]
76920
+ },
76921
+ skill.id
76922
+ )) })
76923
+ ] }, category);
76924
+ }) }) }) })
76925
+ ] }),
76926
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76927
+ CreateSkillDialog,
76928
+ {
76929
+ open: showCreateDialog,
76930
+ onClose: () => setShowCreateDialog(false),
76931
+ onCreate: handleCreateSkill
76932
+ }
76933
+ ),
76934
+ selectedSkill && /* @__PURE__ */ jsxRuntimeExports.jsx(
76935
+ SkillDetailDialog,
76936
+ {
76937
+ skill: selectedSkill,
76938
+ open: !!selectedSkill,
76939
+ onClose: () => setSelectedSkill(null),
76940
+ onToggle: toggleSkill,
76941
+ onDelete: handleDeleteSkill
76942
+ }
76943
+ )
76944
+ ] });
76945
+ }
76066
76946
  const HEADER_HEIGHT = 40;
76067
76947
  const HANDLE_HEIGHT = 6;
76068
76948
  const MIN_CONTENT_HEIGHT = 60;
@@ -76140,38 +77020,43 @@ function RightPanel() {
76140
77020
  const [tasksOpen, setTasksOpen] = reactExports.useState(true);
76141
77021
  const [filesOpen, setFilesOpen] = reactExports.useState(true);
76142
77022
  const [agentsOpen, setAgentsOpen] = reactExports.useState(true);
77023
+ const [skillsOpen, setSkillsOpen] = reactExports.useState(false);
76143
77024
  const [tasksHeight, setTasksHeight] = reactExports.useState(null);
76144
77025
  const [filesHeight, setFilesHeight] = reactExports.useState(null);
76145
77026
  const [agentsHeight, setAgentsHeight] = reactExports.useState(null);
77027
+ const [skillsHeight, setSkillsHeight] = reactExports.useState(null);
76146
77028
  const dragStartHeights = reactExports.useRef(null);
76147
77029
  const getAvailableContentHeight = reactExports.useCallback(() => {
76148
77030
  if (!containerRef.current) return 0;
76149
77031
  const totalHeight = containerRef.current.clientHeight;
76150
- let used = HEADER_HEIGHT * 3;
76151
- if (tasksOpen && (filesOpen || agentsOpen)) used += HANDLE_HEIGHT;
76152
- if (filesOpen && agentsOpen) used += HANDLE_HEIGHT;
77032
+ let used = HEADER_HEIGHT * 4;
77033
+ const openPanels = [tasksOpen, filesOpen, agentsOpen, skillsOpen].filter(Boolean).length;
77034
+ used += HANDLE_HEIGHT * (openPanels - 1);
76153
77035
  return Math.max(0, totalHeight - used);
76154
- }, [tasksOpen, filesOpen, agentsOpen]);
77036
+ }, [tasksOpen, filesOpen, agentsOpen, skillsOpen]);
76155
77037
  const getContentHeights = reactExports.useCallback(() => {
76156
77038
  const available = getAvailableContentHeight();
76157
- const openCount = [tasksOpen, filesOpen, agentsOpen].filter(Boolean).length;
77039
+ const openCount = [tasksOpen, filesOpen, agentsOpen, skillsOpen].filter(Boolean).length;
76158
77040
  if (openCount === 0) {
76159
- return { tasks: 0, files: 0, agents: 0 };
77041
+ return { tasks: 0, files: 0, agents: 0, skills: 0 };
76160
77042
  }
76161
77043
  const defaultHeight = available / openCount;
76162
77044
  return {
76163
77045
  tasks: tasksOpen ? tasksHeight ?? defaultHeight : 0,
76164
77046
  files: filesOpen ? filesHeight ?? defaultHeight : 0,
76165
- agents: agentsOpen ? agentsHeight ?? defaultHeight : 0
77047
+ agents: agentsOpen ? agentsHeight ?? defaultHeight : 0,
77048
+ skills: skillsOpen ? skillsHeight ?? defaultHeight : 0
76166
77049
  };
76167
77050
  }, [
76168
77051
  getAvailableContentHeight,
76169
77052
  tasksOpen,
76170
77053
  filesOpen,
76171
77054
  agentsOpen,
77055
+ skillsOpen,
76172
77056
  tasksHeight,
76173
77057
  filesHeight,
76174
- agentsHeight
77058
+ agentsHeight,
77059
+ skillsHeight
76175
77060
  ]);
76176
77061
  const handleTasksResize = reactExports.useCallback(
76177
77062
  (totalDelta) => {
@@ -76181,7 +77066,12 @@ function RightPanel() {
76181
77066
  }
76182
77067
  const start = dragStartHeights.current;
76183
77068
  const available = getAvailableContentHeight();
76184
- const otherStart = filesOpen ? start.files : start.agents;
77069
+ let nextPanel = null;
77070
+ if (filesOpen) nextPanel = "files";
77071
+ else if (agentsOpen) nextPanel = "agents";
77072
+ else if (skillsOpen) nextPanel = "skills";
77073
+ if (!nextPanel) return;
77074
+ const otherStart = start[nextPanel];
76185
77075
  let newTasksHeight = start.tasks + totalDelta;
76186
77076
  let newOtherHeight = otherStart - totalDelta;
76187
77077
  if (newTasksHeight < MIN_CONTENT_HEIGHT) {
@@ -76192,8 +77082,8 @@ function RightPanel() {
76192
77082
  newOtherHeight = MIN_CONTENT_HEIGHT;
76193
77083
  newTasksHeight = start.tasks + (otherStart - MIN_CONTENT_HEIGHT);
76194
77084
  }
76195
- const thirdPanelHeight = filesOpen && agentsOpen ? agentsHeight ?? available / 3 : 0;
76196
- const maxForTwo = available - thirdPanelHeight;
77085
+ const belowHeight = nextPanel === "files" && (agentsOpen || skillsOpen) ? (agentsOpen ? agentsHeight ?? available / 4 : 0) + (skillsOpen ? skillsHeight ?? available / 4 : 0) : nextPanel === "agents" && skillsOpen ? skillsHeight ?? available / 4 : 0;
77086
+ const maxForTwo = available - belowHeight;
76197
77087
  if (newTasksHeight + newOtherHeight > maxForTwo) {
76198
77088
  const excess = newTasksHeight + newOtherHeight - maxForTwo;
76199
77089
  if (totalDelta > 0) {
@@ -76203,20 +77093,19 @@ function RightPanel() {
76203
77093
  }
76204
77094
  }
76205
77095
  setTasksHeight(newTasksHeight);
76206
- if (filesOpen) {
76207
- setFilesHeight(newOtherHeight);
76208
- } else if (agentsOpen) {
76209
- setAgentsHeight(newOtherHeight);
76210
- }
77096
+ if (nextPanel === "files") setFilesHeight(newOtherHeight);
77097
+ else if (nextPanel === "agents") setAgentsHeight(newOtherHeight);
77098
+ else if (nextPanel === "skills") setSkillsHeight(newOtherHeight);
76211
77099
  if (newTasksHeight < COLLAPSE_THRESHOLD) {
76212
77100
  setTasksOpen(false);
76213
77101
  }
76214
77102
  if (newOtherHeight < COLLAPSE_THRESHOLD) {
76215
- if (filesOpen) setFilesOpen(false);
76216
- else if (agentsOpen) setAgentsOpen(false);
77103
+ if (nextPanel === "files") setFilesOpen(false);
77104
+ else if (nextPanel === "agents") setAgentsOpen(false);
77105
+ else if (nextPanel === "skills") setSkillsOpen(false);
76217
77106
  }
76218
77107
  },
76219
- [getContentHeights, getAvailableContentHeight, filesOpen, agentsOpen, agentsHeight]
77108
+ [getContentHeights, getAvailableContentHeight, filesOpen, agentsOpen, skillsOpen, agentsHeight, skillsHeight]
76220
77109
  );
76221
77110
  const handleFilesResize = reactExports.useCallback(
76222
77111
  (totalDelta) => {
@@ -76226,36 +77115,83 @@ function RightPanel() {
76226
77115
  }
76227
77116
  const start = dragStartHeights.current;
76228
77117
  const available = getAvailableContentHeight();
76229
- const tasksH = tasksOpen ? tasksHeight ?? available / 3 : 0;
76230
- const maxForFilesAndAgents = available - tasksH;
77118
+ const tasksH = tasksOpen ? tasksHeight ?? available / 4 : 0;
77119
+ let nextPanel = null;
77120
+ if (agentsOpen) nextPanel = "agents";
77121
+ else if (skillsOpen) nextPanel = "skills";
77122
+ if (!nextPanel) return;
77123
+ const maxForFilesAndNext = available - tasksH;
76231
77124
  let newFilesHeight = start.files + totalDelta;
76232
- let newAgentsHeight = start.agents - totalDelta;
77125
+ let newNextHeight = start[nextPanel] - totalDelta;
76233
77126
  if (newFilesHeight < MIN_CONTENT_HEIGHT) {
76234
77127
  newFilesHeight = MIN_CONTENT_HEIGHT;
76235
- newAgentsHeight = start.agents + (start.files - MIN_CONTENT_HEIGHT);
77128
+ newNextHeight = start[nextPanel] + (start.files - MIN_CONTENT_HEIGHT);
76236
77129
  }
76237
- if (newAgentsHeight < MIN_CONTENT_HEIGHT) {
76238
- newAgentsHeight = MIN_CONTENT_HEIGHT;
76239
- newFilesHeight = start.files + (start.agents - MIN_CONTENT_HEIGHT);
77130
+ if (newNextHeight < MIN_CONTENT_HEIGHT) {
77131
+ newNextHeight = MIN_CONTENT_HEIGHT;
77132
+ newFilesHeight = start.files + (start[nextPanel] - MIN_CONTENT_HEIGHT);
76240
77133
  }
76241
- if (newFilesHeight + newAgentsHeight > maxForFilesAndAgents) {
76242
- const excess = newFilesHeight + newAgentsHeight - maxForFilesAndAgents;
77134
+ if (newFilesHeight + newNextHeight > maxForFilesAndNext) {
77135
+ const excess = newFilesHeight + newNextHeight - maxForFilesAndNext;
76243
77136
  if (totalDelta > 0) {
76244
- newAgentsHeight = Math.max(MIN_CONTENT_HEIGHT, newAgentsHeight - excess);
77137
+ newNextHeight = Math.max(MIN_CONTENT_HEIGHT, newNextHeight - excess);
76245
77138
  } else {
76246
77139
  newFilesHeight = Math.max(MIN_CONTENT_HEIGHT, newFilesHeight - excess);
76247
77140
  }
76248
77141
  }
76249
77142
  setFilesHeight(newFilesHeight);
76250
- setAgentsHeight(newAgentsHeight);
77143
+ if (nextPanel === "agents") setAgentsHeight(newNextHeight);
77144
+ else if (nextPanel === "skills") setSkillsHeight(newNextHeight);
76251
77145
  if (newFilesHeight < COLLAPSE_THRESHOLD) {
76252
77146
  setFilesOpen(false);
76253
77147
  }
77148
+ if (newNextHeight < COLLAPSE_THRESHOLD) {
77149
+ if (nextPanel === "agents") setAgentsOpen(false);
77150
+ else if (nextPanel === "skills") setSkillsOpen(false);
77151
+ }
77152
+ },
77153
+ [getContentHeights, getAvailableContentHeight, tasksOpen, tasksHeight, agentsOpen, skillsOpen]
77154
+ );
77155
+ const handleAgentsResize = reactExports.useCallback(
77156
+ (totalDelta) => {
77157
+ if (!dragStartHeights.current) {
77158
+ const heights2 = getContentHeights();
77159
+ dragStartHeights.current = { ...heights2 };
77160
+ }
77161
+ const start = dragStartHeights.current;
77162
+ const available = getAvailableContentHeight();
77163
+ const tasksH = tasksOpen ? tasksHeight ?? available / 4 : 0;
77164
+ const filesH = filesOpen ? filesHeight ?? available / 4 : 0;
77165
+ const aboveHeight = tasksH + filesH;
77166
+ const maxForAgentsAndSkills = available - aboveHeight;
77167
+ let newAgentsHeight = start.agents + totalDelta;
77168
+ let newSkillsHeight = start.skills - totalDelta;
77169
+ if (newAgentsHeight < MIN_CONTENT_HEIGHT) {
77170
+ newAgentsHeight = MIN_CONTENT_HEIGHT;
77171
+ newSkillsHeight = start.skills + (start.agents - MIN_CONTENT_HEIGHT);
77172
+ }
77173
+ if (newSkillsHeight < MIN_CONTENT_HEIGHT) {
77174
+ newSkillsHeight = MIN_CONTENT_HEIGHT;
77175
+ newAgentsHeight = start.agents + (start.skills - MIN_CONTENT_HEIGHT);
77176
+ }
77177
+ if (newAgentsHeight + newSkillsHeight > maxForAgentsAndSkills) {
77178
+ const excess = newAgentsHeight + newSkillsHeight - maxForAgentsAndSkills;
77179
+ if (totalDelta > 0) {
77180
+ newSkillsHeight = Math.max(MIN_CONTENT_HEIGHT, newSkillsHeight - excess);
77181
+ } else {
77182
+ newAgentsHeight = Math.max(MIN_CONTENT_HEIGHT, newAgentsHeight - excess);
77183
+ }
77184
+ }
77185
+ setAgentsHeight(newAgentsHeight);
77186
+ setSkillsHeight(newSkillsHeight);
76254
77187
  if (newAgentsHeight < COLLAPSE_THRESHOLD) {
76255
77188
  setAgentsOpen(false);
76256
77189
  }
77190
+ if (newSkillsHeight < COLLAPSE_THRESHOLD) {
77191
+ setSkillsOpen(false);
77192
+ }
76257
77193
  },
76258
- [getContentHeights, getAvailableContentHeight, tasksOpen, tasksHeight]
77194
+ [getContentHeights, getAvailableContentHeight, tasksOpen, filesOpen, tasksHeight, filesHeight]
76259
77195
  );
76260
77196
  reactExports.useEffect(() => {
76261
77197
  const handleMouseUp = () => {
@@ -76268,8 +77204,9 @@ function RightPanel() {
76268
77204
  setTasksHeight(null);
76269
77205
  setFilesHeight(null);
76270
77206
  setAgentsHeight(null);
76271
- }, [tasksOpen, filesOpen, agentsOpen]);
76272
- const [heights, setHeights] = reactExports.useState({ tasks: 0, files: 0, agents: 0 });
77207
+ setSkillsHeight(null);
77208
+ }, [tasksOpen, filesOpen, agentsOpen, skillsOpen]);
77209
+ const [heights, setHeights] = reactExports.useState({ tasks: 0, files: 0, agents: 0, skills: 0 });
76273
77210
  reactExports.useEffect(() => {
76274
77211
  setHeights(getContentHeights());
76275
77212
  }, [getContentHeights]);
@@ -76292,7 +77229,7 @@ function RightPanel() {
76292
77229
  ),
76293
77230
  tasksOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: { height: heights.tasks }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(TasksContent, {}) })
76294
77231
  ] }),
76295
- tasksOpen && (filesOpen || agentsOpen) && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleTasksResize }),
77232
+ tasksOpen && (filesOpen || agentsOpen || skillsOpen) && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleTasksResize }),
76296
77233
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col shrink-0 border-b border-border", children: [
76297
77234
  /* @__PURE__ */ jsxRuntimeExports.jsx(
76298
77235
  SectionHeader,
@@ -76306,8 +77243,8 @@ function RightPanel() {
76306
77243
  ),
76307
77244
  filesOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: { height: heights.files }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(FilesContent, {}) })
76308
77245
  ] }),
76309
- filesOpen && agentsOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleFilesResize }),
76310
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col shrink-0", children: [
77246
+ filesOpen && (agentsOpen || skillsOpen) && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleFilesResize }),
77247
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col shrink-0 border-b border-border", children: [
76311
77248
  /* @__PURE__ */ jsxRuntimeExports.jsx(
76312
77249
  SectionHeader,
76313
77250
  {
@@ -76319,6 +77256,19 @@ function RightPanel() {
76319
77256
  }
76320
77257
  ),
76321
77258
  agentsOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: { height: heights.agents }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(AgentsContent, {}) })
77259
+ ] }),
77260
+ agentsOpen && skillsOpen && /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle$1, { onDrag: handleAgentsResize }),
77261
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col shrink-0", children: [
77262
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
77263
+ SectionHeader,
77264
+ {
77265
+ title: "SKILLS",
77266
+ icon: Sparkles,
77267
+ isOpen: skillsOpen,
77268
+ onToggle: () => setSkillsOpen((prev) => !prev)
77269
+ }
77270
+ ),
77271
+ skillsOpen && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-auto", style: { height: heights.skills }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(SkillsContent, {}) })
76322
77272
  ] })
76323
77273
  ]
76324
77274
  }
@@ -76585,14 +77535,11 @@ function buildFileTree(files) {
76585
77535
  return root2;
76586
77536
  }
76587
77537
  function FileTree({ files }) {
77538
+ const { currentThreadId } = useAppStore();
77539
+ const threadState = useThreadState(currentThreadId);
77540
+ const openFile = threadState?.openFile;
76588
77541
  const tree = reactExports.useMemo(() => buildFileTree(files), [files]);
76589
- const [expanded, setExpanded] = reactExports.useState(() => {
76590
- const dirs = /* @__PURE__ */ new Set();
76591
- files.forEach((f2) => {
76592
- if (f2.is_dir ?? false) dirs.add(f2.path);
76593
- });
76594
- return dirs;
76595
- });
77542
+ const [expanded, setExpanded] = reactExports.useState(/* @__PURE__ */ new Set());
76596
77543
  const toggleExpand = reactExports.useCallback((path2) => {
76597
77544
  setExpanded((prev) => {
76598
77545
  const next = new Set(prev);
@@ -76610,59 +77557,64 @@ function FileTree({ files }) {
76610
77557
  node: node2,
76611
77558
  depth: 0,
76612
77559
  expanded,
76613
- onToggle: toggleExpand
77560
+ onToggle: toggleExpand,
77561
+ openFile
76614
77562
  },
76615
77563
  node2.path
76616
77564
  )) });
76617
77565
  }
76618
- function FileTreeNode({
76619
- node: node2,
76620
- depth,
76621
- expanded,
76622
- onToggle
76623
- }) {
76624
- const { currentThreadId } = useAppStore();
76625
- const threadState = useThreadState(currentThreadId);
76626
- const openFile = threadState?.openFile;
76627
- const isExpanded = expanded.has(node2.path);
76628
- const hasChildren = node2.children.length > 0;
76629
- const paddingLeft = 8 + depth * 16;
76630
- const handleClick = () => {
76631
- if (node2.is_dir) {
76632
- onToggle(node2.path);
76633
- } else if (openFile) {
76634
- openFile(node2.path, node2.name);
76635
- }
76636
- };
76637
- return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
76638
- /* @__PURE__ */ jsxRuntimeExports.jsxs(
76639
- "div",
76640
- {
76641
- onClick: handleClick,
76642
- className: cn(
76643
- "flex items-center gap-1.5 py-1 pr-3 text-xs hover:bg-background-interactive cursor-pointer"
76644
- ),
76645
- style: { paddingLeft },
76646
- children: [
76647
- node2.is_dir ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-3.5 flex items-center justify-center shrink-0", children: hasChildren && (isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" })) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-3.5 shrink-0" }),
76648
- /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { name: node2.name, isDir: node2.is_dir, isOpen: isExpanded }),
76649
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate flex-1", children: node2.name }),
76650
- !node2.is_dir && node2.size !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground tabular-nums shrink-0", children: formatSize(node2.size) })
76651
- ]
77566
+ const FileTreeNode = reactExports.memo(
77567
+ function FileTreeNode2({
77568
+ node: node2,
77569
+ depth,
77570
+ expanded,
77571
+ onToggle,
77572
+ openFile
77573
+ }) {
77574
+ const isExpanded = expanded.has(node2.path);
77575
+ const hasChildren = node2.children.length > 0;
77576
+ const paddingLeft = 8 + depth * 16;
77577
+ const handleClick = () => {
77578
+ if (node2.is_dir) {
77579
+ onToggle(node2.path);
77580
+ } else if (openFile) {
77581
+ openFile(node2.path, node2.name);
76652
77582
  }
76653
- ),
76654
- node2.is_dir && isExpanded && node2.children.map((child) => /* @__PURE__ */ jsxRuntimeExports.jsx(
76655
- FileTreeNode,
76656
- {
76657
- node: child,
76658
- depth: depth + 1,
76659
- expanded,
76660
- onToggle
76661
- },
76662
- child.path
76663
- ))
76664
- ] });
76665
- }
77583
+ };
77584
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
77585
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
77586
+ "div",
77587
+ {
77588
+ onClick: handleClick,
77589
+ className: cn(
77590
+ "flex items-center gap-1.5 py-1 pr-3 text-xs hover:bg-background-interactive cursor-pointer"
77591
+ ),
77592
+ style: { paddingLeft },
77593
+ children: [
77594
+ node2.is_dir ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-3.5 flex items-center justify-center shrink-0", children: hasChildren && (isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "size-3 text-muted-foreground" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "size-3 text-muted-foreground" })) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-3.5 shrink-0" }),
77595
+ /* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { name: node2.name, isDir: node2.is_dir, isOpen: isExpanded }),
77596
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate flex-1", children: node2.name }),
77597
+ !node2.is_dir && node2.size !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] text-muted-foreground tabular-nums shrink-0", children: formatSize(node2.size) })
77598
+ ]
77599
+ }
77600
+ ),
77601
+ node2.is_dir && isExpanded && node2.children.map((child) => /* @__PURE__ */ jsxRuntimeExports.jsx(
77602
+ FileTreeNode2,
77603
+ {
77604
+ node: child,
77605
+ depth: depth + 1,
77606
+ expanded,
77607
+ onToggle,
77608
+ openFile
77609
+ },
77610
+ child.path
77611
+ ))
77612
+ ] });
77613
+ },
77614
+ (prevProps, nextProps) => {
77615
+ return prevProps.node === nextProps.node && prevProps.expanded.has(prevProps.node.path) === nextProps.expanded.has(nextProps.node.path) && prevProps.openFile === nextProps.openFile && prevProps.onToggle === nextProps.onToggle && prevProps.depth === nextProps.depth;
77616
+ }
77617
+ );
76666
77618
  function FileIcon({
76667
77619
  name: name2,
76668
77620
  isDir,
@@ -76738,32 +77690,329 @@ function AgentsContent() {
76738
77690
  agent.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: agent.description })
76739
77691
  ] }, agent.id)) });
76740
77692
  }
77693
+ function SkillsContent() {
77694
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(SkillsPanel, {});
77695
+ }
76741
77696
  function formatSize(bytes) {
76742
77697
  if (bytes < 1024) return `${bytes}B`;
76743
77698
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
76744
77699
  return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
76745
77700
  }
77701
+ const columnConfig = {
77702
+ pending: { badge: "outline", borderColor: "border-t-border" },
77703
+ in_progress: { badge: "info", borderColor: "border-t-status-info" },
77704
+ interrupted: { badge: "warning", borderColor: "border-t-status-warning" },
77705
+ done: { badge: "nominal", borderColor: "border-t-status-nominal" }
77706
+ };
77707
+ function KanbanColumn({
77708
+ title,
77709
+ status,
77710
+ count: count2,
77711
+ children
77712
+ }) {
77713
+ const config2 = columnConfig[status];
77714
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
77715
+ "div",
77716
+ {
77717
+ className: cn(
77718
+ "flex flex-col min-w-[200px] w-[200px] flex-1 bg-muted/30 rounded-sm border border-border border-t-2",
77719
+ config2.borderColor
77720
+ ),
77721
+ children: [
77722
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-b border-border", children: [
77723
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-section-header", children: title }),
77724
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: config2.badge, children: count2 })
77725
+ ] }),
77726
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 space-y-2", children }) })
77727
+ ]
77728
+ }
77729
+ );
77730
+ }
77731
+ const Card = reactExports.forwardRef(
77732
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
77733
+ "div",
77734
+ {
77735
+ ref,
77736
+ className: cn("rounded-sm border border-border bg-card text-card-foreground", className),
77737
+ ...props
77738
+ }
77739
+ )
77740
+ );
77741
+ Card.displayName = "Card";
77742
+ const CardHeader = reactExports.forwardRef(
77743
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-4", className), ...props })
77744
+ );
77745
+ CardHeader.displayName = "CardHeader";
77746
+ const CardTitle = reactExports.forwardRef(
77747
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { ref, className: cn("text-section-header", className), ...props })
77748
+ );
77749
+ CardTitle.displayName = "CardTitle";
77750
+ const CardDescription = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
77751
+ CardDescription.displayName = "CardDescription";
77752
+ const CardContent = reactExports.forwardRef(
77753
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("p-4 pt-0", className), ...props })
77754
+ );
77755
+ CardContent.displayName = "CardContent";
77756
+ const CardFooter = reactExports.forwardRef(
77757
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex items-center p-4 pt-0", className), ...props })
77758
+ );
77759
+ CardFooter.displayName = "CardFooter";
77760
+ function ThreadStatusIcon({ threadId }) {
77761
+ const { isLoading } = useThreadStream(threadId);
77762
+ if (isLoading) {
77763
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 text-status-info animate-spin" });
77764
+ }
77765
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-muted-foreground" });
77766
+ }
77767
+ function ThreadKanbanCard({ thread, status, onClick }) {
77768
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
77769
+ Card,
77770
+ {
77771
+ className: cn(
77772
+ "cursor-pointer transition-all hover:border-border-emphasis hover:bg-background-interactive",
77773
+ status === "in_progress" && "border-status-info/50",
77774
+ status === "interrupted" && "!border-amber-500/50 !bg-amber-500/5"
77775
+ ),
77776
+ onClick,
77777
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2", children: [
77778
+ status === "interrupted" ? /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-amber-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadStatusIcon, { threadId: thread.thread_id }),
77779
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
77780
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
77781
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: thread.title || truncate(thread.thread_id, 20) }),
77782
+ status === "done" && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "nominal", className: "shrink-0 text-[9px]", children: "DONE" })
77783
+ ] }),
77784
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mt-1 text-[10px] text-muted-foreground", children: [
77785
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
77786
+ formatRelativeTime(thread.updated_at)
77787
+ ] })
77788
+ ] })
77789
+ ] }) })
77790
+ }
77791
+ );
77792
+ }
77793
+ function SubagentKanbanCard({
77794
+ subagent,
77795
+ parentThread,
77796
+ onClick
77797
+ }) {
77798
+ const isDone = subagent.status === "completed" || subagent.status === "failed";
77799
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
77800
+ Card,
77801
+ {
77802
+ className: cn(
77803
+ "cursor-pointer transition-all hover:border-border-emphasis hover:bg-background-interactive border-dashed",
77804
+ subagent.status === "running" && "border-status-info/50"
77805
+ ),
77806
+ onClick,
77807
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-3 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 min-w-0", children: [
77808
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
77809
+ Bot,
77810
+ {
77811
+ className: cn(
77812
+ "size-4 shrink-0",
77813
+ subagent.status === "running" ? "text-status-info" : "text-muted-foreground"
77814
+ )
77815
+ }
77816
+ ),
77817
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
77818
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
77819
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: subagent.name }),
77820
+ isDone && /* @__PURE__ */ jsxRuntimeExports.jsx(
77821
+ Badge,
77822
+ {
77823
+ variant: subagent.status === "failed" ? "critical" : "nominal",
77824
+ className: "shrink-0 text-[9px]",
77825
+ children: subagent.status === "failed" ? "FAILED" : "DONE"
77826
+ }
77827
+ )
77828
+ ] }),
77829
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-muted-foreground line-clamp-2 mt-0.5 break-words", children: subagent.description }),
77830
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-1 mt-1 text-[10px] text-muted-foreground", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "truncate", children: [
77831
+ "↳ ",
77832
+ parentThread.title || truncate(parentThread.thread_id, 15)
77833
+ ] }) })
77834
+ ] })
77835
+ ] }) })
77836
+ }
77837
+ );
77838
+ }
77839
+ function getThreadKanbanStatus(thread, isLoading, hasDraft, hasPendingApproval) {
77840
+ if (hasPendingApproval || thread.status === "interrupted") return "interrupted";
77841
+ if (thread.status === "busy" || isLoading) return "in_progress";
77842
+ if (hasDraft) return "pending";
77843
+ return "done";
77844
+ }
77845
+ function KanbanView() {
77846
+ const { threads, selectThread, showSubagentsInKanban } = useAppStore();
77847
+ const allThreadStates = useAllThreadStates();
77848
+ const loadingStates = useAllStreamLoadingStates();
77849
+ const handleCardClick = (threadId) => {
77850
+ selectThread(threadId);
77851
+ };
77852
+ const categorizedThreads = reactExports.useMemo(() => {
77853
+ const result = {
77854
+ pending: [],
77855
+ in_progress: [],
77856
+ interrupted: [],
77857
+ done: []
77858
+ };
77859
+ for (const thread of threads) {
77860
+ const isLoading = loadingStates[thread.thread_id] ?? false;
77861
+ const threadState = allThreadStates[thread.thread_id];
77862
+ const hasDraft = Boolean(threadState?.draftInput?.trim());
77863
+ const hasPendingApproval = Boolean(threadState?.pendingApproval);
77864
+ const status = getThreadKanbanStatus(thread, isLoading, hasDraft, hasPendingApproval);
77865
+ result[status].push({ thread, status });
77866
+ }
77867
+ return result;
77868
+ }, [threads, loadingStates, allThreadStates]);
77869
+ const categorizedSubagents = reactExports.useMemo(() => {
77870
+ if (!showSubagentsInKanban) {
77871
+ return { pending: [], in_progress: [], interrupted: [], done: [] };
77872
+ }
77873
+ const result = {
77874
+ pending: [],
77875
+ in_progress: [],
77876
+ interrupted: [],
77877
+ done: []
77878
+ };
77879
+ const threadMap = new Map(threads.map((t) => [t.thread_id, t]));
77880
+ for (const [threadId, state] of Object.entries(allThreadStates)) {
77881
+ const parentThread = threadMap.get(threadId);
77882
+ if (!parentThread || !state.subagents) continue;
77883
+ for (const subagent of state.subagents) {
77884
+ let status;
77885
+ switch (subagent.status) {
77886
+ case "pending":
77887
+ status = "pending";
77888
+ break;
77889
+ case "running":
77890
+ status = "in_progress";
77891
+ break;
77892
+ case "completed":
77893
+ status = "done";
77894
+ break;
77895
+ case "failed":
77896
+ status = "done";
77897
+ break;
77898
+ default:
77899
+ status = "pending";
77900
+ }
77901
+ result[status].push({ subagent, parentThread, status });
77902
+ }
77903
+ }
77904
+ return result;
77905
+ }, [threads, allThreadStates, showSubagentsInKanban]);
77906
+ const columnData = [
77907
+ { status: "pending", title: "PENDING" },
77908
+ { status: "in_progress", title: "IN PROGRESS" },
77909
+ { status: "interrupted", title: "BLOCKED" },
77910
+ { status: "done", title: "DONE" }
77911
+ ];
77912
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col h-full bg-background", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-x-auto p-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full min-w-max gap-2", children: columnData.map(({ status, title }) => {
77913
+ const threadItems = categorizedThreads[status];
77914
+ const subagentItems = categorizedSubagents[status];
77915
+ const totalCount = threadItems.length + subagentItems.length;
77916
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(KanbanColumn, { title, status, count: totalCount, children: [
77917
+ threadItems.map(({ thread, status: threadStatus }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
77918
+ ThreadKanbanCard,
77919
+ {
77920
+ thread,
77921
+ status: threadStatus,
77922
+ onClick: () => handleCardClick(thread.thread_id)
77923
+ },
77924
+ thread.thread_id
77925
+ )),
77926
+ subagentItems.map(({ subagent, parentThread }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
77927
+ SubagentKanbanCard,
77928
+ {
77929
+ subagent,
77930
+ parentThread,
77931
+ onClick: () => handleCardClick(parentThread.thread_id)
77932
+ },
77933
+ subagent.id
77934
+ )),
77935
+ totalCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center text-sm text-muted-foreground py-8", children: "No items" })
77936
+ ] }, status);
77937
+ }) }) }) });
77938
+ }
77939
+ function KanbanHeader({ className }) {
77940
+ const { showSubagentsInKanban, setShowSubagentsInKanban, threads } = useAppStore();
77941
+ const activeCount = threads.filter(
77942
+ (t) => t.status === "busy" || t.status === "interrupted"
77943
+ ).length;
77944
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
77945
+ "div",
77946
+ {
77947
+ className: cn(
77948
+ "flex items-center justify-between px-3 app-no-drag relative overflow-hidden",
77949
+ className
77950
+ ),
77951
+ children: [
77952
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 pointer-events-none opacity-[0.03]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
77953
+ "div",
77954
+ {
77955
+ className: "absolute inset-0",
77956
+ style: {
77957
+ backgroundImage: "repeating-linear-gradient(0deg, transparent, transparent 2px, currentColor 2px, currentColor 3px)",
77958
+ backgroundSize: "100% 3px"
77959
+ }
77960
+ }
77961
+ ) }),
77962
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-mono uppercase tracking-wider text-muted-foreground", children: [
77963
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
77964
+ "div",
77965
+ {
77966
+ className: cn(
77967
+ "size-1.5 rounded-full",
77968
+ activeCount > 0 ? "bg-status-nominal animate-tactical-pulse" : "bg-muted-foreground"
77969
+ )
77970
+ }
77971
+ ),
77972
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "tabular-nums", children: activeCount > 0 ? `${activeCount} ACTIVE` : "IDLE" })
77973
+ ] }),
77974
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
77975
+ Button,
77976
+ {
77977
+ variant: showSubagentsInKanban ? "secondary" : "ghost",
77978
+ size: "sm",
77979
+ onClick: () => setShowSubagentsInKanban(!showSubagentsInKanban),
77980
+ className: "gap-2 h-7 relative",
77981
+ children: [
77982
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "size-3.5" }),
77983
+ showSubagentsInKanban ? "Hide" : "Show",
77984
+ " Subagents"
77985
+ ]
77986
+ }
77987
+ )
77988
+ ]
77989
+ }
77990
+ );
77991
+ }
76746
77992
  const HANDLE_WIDTH = 6;
76747
77993
  function ResizeHandle({ onDrag }) {
76748
77994
  const startXRef = reactExports.useRef(0);
76749
- const handleMouseDown = reactExports.useCallback((e) => {
76750
- e.preventDefault();
76751
- startXRef.current = e.clientX;
76752
- const handleMouseMove = (e2) => {
76753
- const totalDelta = e2.clientX - startXRef.current;
76754
- onDrag(totalDelta);
76755
- };
76756
- const handleMouseUp = () => {
76757
- document.removeEventListener("mousemove", handleMouseMove);
76758
- document.removeEventListener("mouseup", handleMouseUp);
76759
- document.body.style.cursor = "";
76760
- document.body.style.userSelect = "";
76761
- };
76762
- document.addEventListener("mousemove", handleMouseMove);
76763
- document.addEventListener("mouseup", handleMouseUp);
76764
- document.body.style.cursor = "col-resize";
76765
- document.body.style.userSelect = "none";
76766
- }, [onDrag]);
77995
+ const handleMouseDown = reactExports.useCallback(
77996
+ (e) => {
77997
+ e.preventDefault();
77998
+ startXRef.current = e.clientX;
77999
+ const handleMouseMove = (e2) => {
78000
+ const totalDelta = e2.clientX - startXRef.current;
78001
+ onDrag(totalDelta);
78002
+ };
78003
+ const handleMouseUp = () => {
78004
+ document.removeEventListener("mousemove", handleMouseMove);
78005
+ document.removeEventListener("mouseup", handleMouseUp);
78006
+ document.body.style.cursor = "";
78007
+ document.body.style.userSelect = "";
78008
+ };
78009
+ document.addEventListener("mousemove", handleMouseMove);
78010
+ document.addEventListener("mouseup", handleMouseUp);
78011
+ document.body.style.cursor = "col-resize";
78012
+ document.body.style.userSelect = "none";
78013
+ },
78014
+ [onDrag]
78015
+ );
76767
78016
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
76768
78017
  "div",
76769
78018
  {
@@ -76781,7 +78030,7 @@ const RIGHT_MIN = 250;
76781
78030
  const RIGHT_MAX = 450;
76782
78031
  const RIGHT_DEFAULT = 320;
76783
78032
  function App() {
76784
- const { currentThreadId, loadThreads, createThread } = useAppStore();
78033
+ const { currentThreadId, loadThreads, createThread, showKanbanView } = useAppStore();
76785
78034
  const [isLoading, setIsLoading] = reactExports.useState(true);
76786
78035
  const [leftWidth, setLeftWidth] = reactExports.useState(LEFT_DEFAULT);
76787
78036
  const [rightWidth, setRightWidth] = reactExports.useState(RIGHT_DEFAULT);
@@ -76871,24 +78120,29 @@ function App() {
76871
78120
  },
76872
78121
  children: [
76873
78122
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-name", children: "OPENWORK" }),
76874
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.1" })
78123
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.3" })
76875
78124
  ]
76876
78125
  }
76877
78126
  ),
76878
78127
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col flex-1 min-w-0", children: [
76879
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-9 w-full shrink-0 app-drag-region bg-sidebar", children: [
76880
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0" }),
78128
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-9 w-full shrink-0 app-drag-region", children: [
78129
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0 bg-sidebar" }),
76881
78130
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-[1px] shrink-0" }),
76882
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0", children: currentThreadId && /* @__PURE__ */ jsxRuntimeExports.jsx(TabBar, { className: "h-full border-b-0" }) })
78131
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0 bg-background border-b border-border", children: showKanbanView ? /* @__PURE__ */ jsxRuntimeExports.jsx(KanbanHeader, { className: "h-full" }) : currentThreadId && /* @__PURE__ */ jsxRuntimeExports.jsx(TabBar, { className: "h-full border-b-0" }) })
76883
78132
  ] }),
76884
78133
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 overflow-hidden", children: [
76885
78134
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadSidebar, {}) }),
76886
78135
  /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleLeftResize }),
76887
- /* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "flex flex-1 flex-col min-w-0 overflow-hidden", children: currentThreadId ? /* @__PURE__ */ jsxRuntimeExports.jsx(TabbedPanel, { threadId: currentThreadId, showTabBar: false }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1 items-center justify-center text-muted-foreground", children: "Select or create a thread to begin" }) })
78136
+ showKanbanView ? (
78137
+ /* Kanban View - replaces center and right panels */
78138
+ /* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "flex flex-1 flex-col min-w-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(KanbanView, {}) })
78139
+ ) : /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "flex flex-1 flex-col min-w-0 overflow-hidden", children: currentThreadId ? /* @__PURE__ */ jsxRuntimeExports.jsx(TabbedPanel, { threadId: currentThreadId, showTabBar: false }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1 items-center justify-center text-muted-foreground", children: "Select or create a thread to begin" }) }) })
76888
78140
  ] })
76889
78141
  ] }),
76890
- /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleRightResize }),
76891
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: rightWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RightPanel, {}) })
78142
+ !showKanbanView && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
78143
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleRightResize }),
78144
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: rightWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RightPanel, {}) })
78145
+ ] })
76892
78146
  ] }) });
76893
78147
  }
76894
78148
  ReactDOM$1.createRoot(document.getElementById("root")).render(