@uniqueli/openwork 0.2.0 → 0.2.2
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.
- package/README.md +18 -6
- package/bin/cli.js +15 -14
- package/out/main/index.js +232 -269
- package/out/preload/index.js +12 -9
- package/out/renderer/assets/{index-wQN5U7g5.js → index-BayYTupF.js} +1001 -608
- package/out/renderer/assets/{index-BtAM3QNQ.css → index-iDdc8OMS.css} +86 -17
- package/out/renderer/index.html +2 -2
- package/package.json +8 -7
- package/resources/README.md +0 -16
|
@@ -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" }],
|
|
@@ -15579,14 +15585,7 @@ const buttonVariants = cva(
|
|
|
15579
15585
|
const Button = reactExports.forwardRef(
|
|
15580
15586
|
({ className, variant, size: size2, asChild = false, ...props }, ref) => {
|
|
15581
15587
|
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
|
-
);
|
|
15588
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(Comp, { className: cn(buttonVariants({ variant, size: size2, className })), ref, ...props });
|
|
15590
15589
|
}
|
|
15591
15590
|
);
|
|
15592
15591
|
Button.displayName = "Button";
|
|
@@ -16711,6 +16710,8 @@ const useAppStore = create$1((set, get) => ({
|
|
|
16711
16710
|
rightPanelTab: "todos",
|
|
16712
16711
|
settingsOpen: false,
|
|
16713
16712
|
sidebarCollapsed: false,
|
|
16713
|
+
showKanbanView: false,
|
|
16714
|
+
showSubagentsInKanban: true,
|
|
16714
16715
|
// Thread actions
|
|
16715
16716
|
loadThreads: async () => {
|
|
16716
16717
|
const threads = await window.api.threads.list();
|
|
@@ -16723,12 +16724,13 @@ const useAppStore = create$1((set, get) => ({
|
|
|
16723
16724
|
const thread = await window.api.threads.create(metadata);
|
|
16724
16725
|
set((state) => ({
|
|
16725
16726
|
threads: [thread, ...state.threads],
|
|
16726
|
-
currentThreadId: thread.thread_id
|
|
16727
|
+
currentThreadId: thread.thread_id,
|
|
16728
|
+
showKanbanView: false
|
|
16727
16729
|
}));
|
|
16728
16730
|
return thread;
|
|
16729
16731
|
},
|
|
16730
16732
|
selectThread: async (threadId) => {
|
|
16731
|
-
set({ currentThreadId: threadId });
|
|
16733
|
+
set({ currentThreadId: threadId, showKanbanView: false });
|
|
16732
16734
|
},
|
|
16733
16735
|
deleteThread: async (threadId) => {
|
|
16734
16736
|
console.log("[Store] Deleting thread:", threadId);
|
|
@@ -16803,6 +16805,17 @@ const useAppStore = create$1((set, get) => ({
|
|
|
16803
16805
|
},
|
|
16804
16806
|
setSidebarCollapsed: (collapsed) => {
|
|
16805
16807
|
set({ sidebarCollapsed: collapsed });
|
|
16808
|
+
},
|
|
16809
|
+
// Kanban actions
|
|
16810
|
+
setShowKanbanView: (show) => {
|
|
16811
|
+
if (show) {
|
|
16812
|
+
set({ showKanbanView: true, currentThreadId: null });
|
|
16813
|
+
} else {
|
|
16814
|
+
set({ showKanbanView: false });
|
|
16815
|
+
}
|
|
16816
|
+
},
|
|
16817
|
+
setShowSubagentsInKanban: (show) => {
|
|
16818
|
+
set({ showSubagentsInKanban: show });
|
|
16806
16819
|
}
|
|
16807
16820
|
}));
|
|
16808
16821
|
const CR = "\r".charCodeAt(0);
|
|
@@ -44595,6 +44608,7 @@ class ElectronIPCTransport {
|
|
|
44595
44608
|
this.accumulatedToolCalls.clear();
|
|
44596
44609
|
this.completedToolCallsByName.clear();
|
|
44597
44610
|
const threadId = payload.config?.configurable?.thread_id;
|
|
44611
|
+
const modelId = payload.config?.configurable?.model_id;
|
|
44598
44612
|
if (!threadId) {
|
|
44599
44613
|
return this.createErrorGenerator("MISSING_THREAD_ID", "Thread ID is required");
|
|
44600
44614
|
}
|
|
@@ -44606,7 +44620,13 @@ class ElectronIPCTransport {
|
|
|
44606
44620
|
if (!messageContent && !hasResumeCommand) {
|
|
44607
44621
|
return this.createErrorGenerator("MISSING_MESSAGE", "Message content is required");
|
|
44608
44622
|
}
|
|
44609
|
-
return this.createStreamGenerator(
|
|
44623
|
+
return this.createStreamGenerator(
|
|
44624
|
+
threadId,
|
|
44625
|
+
messageContent,
|
|
44626
|
+
payload.command,
|
|
44627
|
+
payload.signal,
|
|
44628
|
+
modelId
|
|
44629
|
+
);
|
|
44610
44630
|
}
|
|
44611
44631
|
async *createErrorGenerator(code2, message) {
|
|
44612
44632
|
yield {
|
|
@@ -44614,7 +44634,7 @@ class ElectronIPCTransport {
|
|
|
44614
44634
|
data: { error: code2, message }
|
|
44615
44635
|
};
|
|
44616
44636
|
}
|
|
44617
|
-
async *createStreamGenerator(threadId, message, command, signal) {
|
|
44637
|
+
async *createStreamGenerator(threadId, message, command, signal, modelId) {
|
|
44618
44638
|
const eventQueue = [];
|
|
44619
44639
|
let resolveNext = null;
|
|
44620
44640
|
let isDone = false;
|
|
@@ -44627,22 +44647,28 @@ class ElectronIPCTransport {
|
|
|
44627
44647
|
thread_id: threadId
|
|
44628
44648
|
}
|
|
44629
44649
|
};
|
|
44630
|
-
const cleanup = window.api.agent.streamAgent(
|
|
44631
|
-
|
|
44632
|
-
|
|
44633
|
-
|
|
44634
|
-
|
|
44635
|
-
|
|
44636
|
-
|
|
44637
|
-
|
|
44638
|
-
|
|
44639
|
-
|
|
44640
|
-
|
|
44641
|
-
|
|
44642
|
-
|
|
44650
|
+
const cleanup = window.api.agent.streamAgent(
|
|
44651
|
+
threadId,
|
|
44652
|
+
message,
|
|
44653
|
+
command,
|
|
44654
|
+
(ipcEvent) => {
|
|
44655
|
+
const sdkEvents = this.convertToSDKEvents(ipcEvent, threadId);
|
|
44656
|
+
for (const sdkEvent of sdkEvents) {
|
|
44657
|
+
if (sdkEvent.event === "done" || sdkEvent.event === "error") {
|
|
44658
|
+
isDone = true;
|
|
44659
|
+
hasError = sdkEvent.event === "error";
|
|
44660
|
+
}
|
|
44661
|
+
if (resolveNext) {
|
|
44662
|
+
const resolve = resolveNext;
|
|
44663
|
+
resolveNext = null;
|
|
44664
|
+
resolve(sdkEvent);
|
|
44665
|
+
} else {
|
|
44666
|
+
eventQueue.push(sdkEvent);
|
|
44667
|
+
}
|
|
44643
44668
|
}
|
|
44644
|
-
}
|
|
44645
|
-
|
|
44669
|
+
},
|
|
44670
|
+
modelId
|
|
44671
|
+
);
|
|
44646
44672
|
if (signal) {
|
|
44647
44673
|
signal.addEventListener("abort", () => {
|
|
44648
44674
|
cleanup();
|
|
@@ -45156,7 +45182,8 @@ const createDefaultThreadState = () => ({
|
|
|
45156
45182
|
openFiles: [],
|
|
45157
45183
|
activeTab: "agent",
|
|
45158
45184
|
fileContents: {},
|
|
45159
|
-
tokenUsage: null
|
|
45185
|
+
tokenUsage: null,
|
|
45186
|
+
draftInput: ""
|
|
45160
45187
|
});
|
|
45161
45188
|
const defaultStreamData = {
|
|
45162
45189
|
messages: [],
|
|
@@ -45221,6 +45248,7 @@ function ThreadStreamHolder({
|
|
|
45221
45248
|
function ThreadProvider({ children }) {
|
|
45222
45249
|
const [threadStates, setThreadStates] = reactExports.useState({});
|
|
45223
45250
|
const [activeThreadIds, setActiveThreadIds] = reactExports.useState(/* @__PURE__ */ new Set());
|
|
45251
|
+
const [loadingStates, setLoadingStates] = reactExports.useState({});
|
|
45224
45252
|
const initializedThreadsRef = reactExports.useRef(/* @__PURE__ */ new Set());
|
|
45225
45253
|
const actionsCache = reactExports.useRef({});
|
|
45226
45254
|
const streamDataRef = reactExports.useRef({});
|
|
@@ -45235,6 +45263,10 @@ function ThreadProvider({ children }) {
|
|
|
45235
45263
|
(threadId, data) => {
|
|
45236
45264
|
streamDataRef.current[threadId] = data;
|
|
45237
45265
|
notifyStreamSubscribers(threadId);
|
|
45266
|
+
setLoadingStates((prev) => {
|
|
45267
|
+
if (prev[threadId] === data.isLoading) return prev;
|
|
45268
|
+
return { ...prev, [threadId]: data.isLoading };
|
|
45269
|
+
});
|
|
45238
45270
|
},
|
|
45239
45271
|
[notifyStreamSubscribers]
|
|
45240
45272
|
);
|
|
@@ -45254,12 +45286,26 @@ function ThreadProvider({ children }) {
|
|
|
45254
45286
|
(threadId) => {
|
|
45255
45287
|
const state = threadStates[threadId] || createDefaultThreadState();
|
|
45256
45288
|
if (state.pendingApproval) {
|
|
45257
|
-
console.log(
|
|
45289
|
+
console.log(
|
|
45290
|
+
"[ThreadContext] getThreadState returning pendingApproval for:",
|
|
45291
|
+
threadId,
|
|
45292
|
+
state.pendingApproval
|
|
45293
|
+
);
|
|
45258
45294
|
}
|
|
45259
45295
|
return state;
|
|
45260
45296
|
},
|
|
45261
45297
|
[threadStates]
|
|
45262
45298
|
);
|
|
45299
|
+
const getAllThreadStates = reactExports.useCallback(() => {
|
|
45300
|
+
return threadStates;
|
|
45301
|
+
}, [threadStates]);
|
|
45302
|
+
const getAllStreamLoadingStates = reactExports.useCallback(() => {
|
|
45303
|
+
return loadingStates;
|
|
45304
|
+
}, [loadingStates]);
|
|
45305
|
+
const subscribeToAllStreams = reactExports.useCallback(() => {
|
|
45306
|
+
return () => {
|
|
45307
|
+
};
|
|
45308
|
+
}, []);
|
|
45263
45309
|
const updateThreadState = reactExports.useCallback(
|
|
45264
45310
|
(threadId, updater) => {
|
|
45265
45311
|
setThreadStates((prev) => {
|
|
@@ -45275,7 +45321,9 @@ function ThreadProvider({ children }) {
|
|
|
45275
45321
|
);
|
|
45276
45322
|
const parseErrorMessage = reactExports.useCallback((error) => {
|
|
45277
45323
|
const errorMessage = typeof error === "string" ? error : error.message;
|
|
45278
|
-
const contextWindowMatch = errorMessage.match(
|
|
45324
|
+
const contextWindowMatch = errorMessage.match(
|
|
45325
|
+
/prompt is too long: (\d+) tokens > (\d+) maximum/i
|
|
45326
|
+
);
|
|
45279
45327
|
if (contextWindowMatch) {
|
|
45280
45328
|
const [, usedTokens, maxTokens] = contextWindowMatch;
|
|
45281
45329
|
const usedK = Math.round(parseInt(usedTokens) / 1e3);
|
|
@@ -45304,7 +45352,11 @@ function ThreadProvider({ children }) {
|
|
|
45304
45352
|
switch (data.type) {
|
|
45305
45353
|
case "interrupt":
|
|
45306
45354
|
if (data.request) {
|
|
45307
|
-
console.log(
|
|
45355
|
+
console.log(
|
|
45356
|
+
"[ThreadContext] Setting pendingApproval for thread:",
|
|
45357
|
+
threadId,
|
|
45358
|
+
data.request
|
|
45359
|
+
);
|
|
45308
45360
|
updateThreadState(threadId, () => ({ pendingApproval: data.request }));
|
|
45309
45361
|
}
|
|
45310
45362
|
break;
|
|
@@ -45431,7 +45483,8 @@ function ThreadProvider({ children }) {
|
|
|
45431
45483
|
closeFile: (path2) => {
|
|
45432
45484
|
updateThreadState(threadId, (state) => {
|
|
45433
45485
|
const newOpenFiles = state.openFiles.filter((f2) => f2.path !== path2);
|
|
45434
|
-
const
|
|
45486
|
+
const newFileContents = { ...state.fileContents };
|
|
45487
|
+
delete newFileContents[path2];
|
|
45435
45488
|
let newActiveTab = state.activeTab;
|
|
45436
45489
|
if (state.activeTab === path2) {
|
|
45437
45490
|
const closedIndex = state.openFiles.findIndex((f2) => f2.path === path2);
|
|
@@ -45439,7 +45492,11 @@ function ThreadProvider({ children }) {
|
|
|
45439
45492
|
else if (closedIndex > 0) newActiveTab = newOpenFiles[closedIndex - 1].path;
|
|
45440
45493
|
else newActiveTab = newOpenFiles[0].path;
|
|
45441
45494
|
}
|
|
45442
|
-
return {
|
|
45495
|
+
return {
|
|
45496
|
+
openFiles: newOpenFiles,
|
|
45497
|
+
activeTab: newActiveTab,
|
|
45498
|
+
fileContents: newFileContents
|
|
45499
|
+
};
|
|
45443
45500
|
});
|
|
45444
45501
|
},
|
|
45445
45502
|
setActiveTab: (tab2) => {
|
|
@@ -45449,6 +45506,9 @@ function ThreadProvider({ children }) {
|
|
|
45449
45506
|
updateThreadState(threadId, (state) => ({
|
|
45450
45507
|
fileContents: { ...state.fileContents, [path2]: content2 }
|
|
45451
45508
|
}));
|
|
45509
|
+
},
|
|
45510
|
+
setDraftInput: (input) => {
|
|
45511
|
+
updateThreadState(threadId, () => ({ draftInput: input }));
|
|
45452
45512
|
}
|
|
45453
45513
|
};
|
|
45454
45514
|
actionsCache.current[threadId] = actions;
|
|
@@ -45466,21 +45526,16 @@ function ThreadProvider({ children }) {
|
|
|
45466
45526
|
if (metadata.currentModel) {
|
|
45467
45527
|
actions.setCurrentModel(metadata.currentModel);
|
|
45468
45528
|
}
|
|
45469
|
-
|
|
45470
|
-
|
|
45471
|
-
|
|
45472
|
-
|
|
45473
|
-
|
|
45474
|
-
|
|
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);
|
|
45529
|
+
if (metadata.workspacePath) {
|
|
45530
|
+
actions.setWorkspacePath(metadata.workspacePath);
|
|
45531
|
+
const diskResult = await window.api.workspace.loadFromDisk(threadId);
|
|
45532
|
+
if (diskResult.success) {
|
|
45533
|
+
actions.setWorkspaceFiles(diskResult.files);
|
|
45534
|
+
}
|
|
45480
45535
|
}
|
|
45481
45536
|
}
|
|
45482
45537
|
} catch (error) {
|
|
45483
|
-
console.error("[ThreadContext] Failed to load
|
|
45538
|
+
console.error("[ThreadContext] Failed to load thread metadata:", error);
|
|
45484
45539
|
}
|
|
45485
45540
|
try {
|
|
45486
45541
|
const history = await window.api.threads.getHistory(threadId);
|
|
@@ -45561,7 +45616,7 @@ function ThreadProvider({ children }) {
|
|
|
45561
45616
|
console.error("[ThreadContext] Failed to load thread history:", error);
|
|
45562
45617
|
}
|
|
45563
45618
|
},
|
|
45564
|
-
[getThreadActions]
|
|
45619
|
+
[getThreadActions, updateThreadState]
|
|
45565
45620
|
);
|
|
45566
45621
|
const initializeThread = reactExports.useCallback(
|
|
45567
45622
|
(threadId) => {
|
|
@@ -45587,7 +45642,7 @@ function ThreadProvider({ children }) {
|
|
|
45587
45642
|
return next;
|
|
45588
45643
|
});
|
|
45589
45644
|
setThreadStates((prev) => {
|
|
45590
|
-
const { [threadId]:
|
|
45645
|
+
const { [threadId]: _removed, ...rest } = prev;
|
|
45591
45646
|
return rest;
|
|
45592
45647
|
});
|
|
45593
45648
|
}, []);
|
|
@@ -45598,9 +45653,22 @@ function ThreadProvider({ children }) {
|
|
|
45598
45653
|
initializeThread,
|
|
45599
45654
|
cleanupThread,
|
|
45600
45655
|
subscribeToStream,
|
|
45601
|
-
getStreamData
|
|
45656
|
+
getStreamData,
|
|
45657
|
+
getAllThreadStates,
|
|
45658
|
+
getAllStreamLoadingStates,
|
|
45659
|
+
subscribeToAllStreams
|
|
45602
45660
|
}),
|
|
45603
|
-
[
|
|
45661
|
+
[
|
|
45662
|
+
getThreadState,
|
|
45663
|
+
getThreadActions,
|
|
45664
|
+
initializeThread,
|
|
45665
|
+
cleanupThread,
|
|
45666
|
+
subscribeToStream,
|
|
45667
|
+
getStreamData,
|
|
45668
|
+
getAllThreadStates,
|
|
45669
|
+
getAllStreamLoadingStates,
|
|
45670
|
+
subscribeToAllStreams
|
|
45671
|
+
]
|
|
45604
45672
|
);
|
|
45605
45673
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(ThreadContext.Provider, { value: contextValue, children: [
|
|
45606
45674
|
Array.from(activeThreadIds).map((threadId) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -45649,6 +45717,14 @@ function useThreadState(threadId) {
|
|
|
45649
45717
|
const actions = context.getThreadActions(threadId);
|
|
45650
45718
|
return { ...state, ...actions };
|
|
45651
45719
|
}
|
|
45720
|
+
function useAllThreadStates() {
|
|
45721
|
+
const context = useThreadContext();
|
|
45722
|
+
return context.getAllThreadStates();
|
|
45723
|
+
}
|
|
45724
|
+
function useAllStreamLoadingStates() {
|
|
45725
|
+
const context = useThreadContext();
|
|
45726
|
+
return context.getAllStreamLoadingStates();
|
|
45727
|
+
}
|
|
45652
45728
|
// @__NO_SIDE_EFFECTS__
|
|
45653
45729
|
function createSlot$3(ownerName) {
|
|
45654
45730
|
const SlotClone = /* @__PURE__ */ createSlotClone$3(ownerName);
|
|
@@ -50610,9 +50686,7 @@ var Portal2 = ContextMenuPortal;
|
|
|
50610
50686
|
var Content2$1 = ContextMenuContent$1;
|
|
50611
50687
|
var Item2 = ContextMenuItem$1;
|
|
50612
50688
|
var Separator2 = ContextMenuSeparator$1;
|
|
50613
|
-
function ContextMenu({
|
|
50614
|
-
...props
|
|
50615
|
-
}) {
|
|
50689
|
+
function ContextMenu({ ...props }) {
|
|
50616
50690
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2$1, { "data-slot": "context-menu", ...props });
|
|
50617
50691
|
}
|
|
50618
50692
|
function ContextMenuTrigger({
|
|
@@ -50669,11 +50743,15 @@ function ContextMenuSeparator({
|
|
|
50669
50743
|
}
|
|
50670
50744
|
);
|
|
50671
50745
|
}
|
|
50672
|
-
function
|
|
50746
|
+
function ThreadStatusIcon$1({ threadId }) {
|
|
50673
50747
|
const { isLoading } = useThreadStream(threadId);
|
|
50748
|
+
const { pendingApproval } = useCurrentThread(threadId);
|
|
50674
50749
|
if (isLoading) {
|
|
50675
50750
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 text-status-info animate-spin" });
|
|
50676
50751
|
}
|
|
50752
|
+
if (pendingApproval) {
|
|
50753
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(CircleAlert, { className: "size-4 shrink-0 text-status-warning" });
|
|
50754
|
+
}
|
|
50677
50755
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-muted-foreground" });
|
|
50678
50756
|
}
|
|
50679
50757
|
function ThreadListItem({
|
|
@@ -50702,7 +50780,7 @@ function ThreadListItem({
|
|
|
50702
50780
|
}
|
|
50703
50781
|
},
|
|
50704
50782
|
children: [
|
|
50705
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50783
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ThreadStatusIcon$1, { threadId: thread.thread_id }),
|
|
50706
50784
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0 overflow-hidden", children: isEditing ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50707
50785
|
"input",
|
|
50708
50786
|
{
|
|
@@ -50744,17 +50822,10 @@ function ThreadListItem({
|
|
|
50744
50822
|
"Rename"
|
|
50745
50823
|
] }),
|
|
50746
50824
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenuSeparator, {}),
|
|
50747
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
50748
|
-
|
|
50749
|
-
|
|
50750
|
-
|
|
50751
|
-
onClick: onDelete,
|
|
50752
|
-
children: [
|
|
50753
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4 mr-2" }),
|
|
50754
|
-
"Delete"
|
|
50755
|
-
]
|
|
50756
|
-
}
|
|
50757
|
-
)
|
|
50825
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(ContextMenuItem, { variant: "destructive", onClick: onDelete, children: [
|
|
50826
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4 mr-2" }),
|
|
50827
|
+
"Delete"
|
|
50828
|
+
] })
|
|
50758
50829
|
] })
|
|
50759
50830
|
] });
|
|
50760
50831
|
}
|
|
@@ -50765,7 +50836,8 @@ function ThreadSidebar() {
|
|
|
50765
50836
|
createThread,
|
|
50766
50837
|
selectThread,
|
|
50767
50838
|
deleteThread,
|
|
50768
|
-
updateThread
|
|
50839
|
+
updateThread,
|
|
50840
|
+
setShowKanbanView
|
|
50769
50841
|
} = useAppStore();
|
|
50770
50842
|
const [editingThreadId, setEditingThreadId] = reactExports.useState(null);
|
|
50771
50843
|
const [editingTitle, setEditingTitle] = reactExports.useState("");
|
|
@@ -50788,10 +50860,19 @@ function ThreadSidebar() {
|
|
|
50788
50860
|
await createThread({ title: `Thread ${(/* @__PURE__ */ new Date()).toLocaleDateString()}` });
|
|
50789
50861
|
};
|
|
50790
50862
|
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(
|
|
50792
|
-
|
|
50793
|
-
|
|
50794
|
-
|
|
50863
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2", style: { paddingTop: "calc(8px + var(--sidebar-safe-padding, 0px))" }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
50864
|
+
Button,
|
|
50865
|
+
{
|
|
50866
|
+
variant: "ghost",
|
|
50867
|
+
size: "sm",
|
|
50868
|
+
className: "w-full justify-start gap-2",
|
|
50869
|
+
onClick: handleNewThread,
|
|
50870
|
+
children: [
|
|
50871
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "size-4" }),
|
|
50872
|
+
"New Thread"
|
|
50873
|
+
]
|
|
50874
|
+
}
|
|
50875
|
+
) }),
|
|
50795
50876
|
/* @__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
50877
|
threads.map((thread) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50797
50878
|
ThreadListItem,
|
|
@@ -50810,10 +50891,26 @@ function ThreadSidebar() {
|
|
|
50810
50891
|
thread.thread_id
|
|
50811
50892
|
)),
|
|
50812
50893
|
threads.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-8 text-center text-sm text-muted-foreground", children: "No threads yet" })
|
|
50813
|
-
] }) })
|
|
50894
|
+
] }) }),
|
|
50895
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 border-t border-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
50896
|
+
Button,
|
|
50897
|
+
{
|
|
50898
|
+
variant: "ghost",
|
|
50899
|
+
size: "sm",
|
|
50900
|
+
className: "w-full justify-start gap-2",
|
|
50901
|
+
onClick: () => setShowKanbanView(true),
|
|
50902
|
+
children: [
|
|
50903
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LayoutGrid, { className: "size-4" }),
|
|
50904
|
+
"Overview"
|
|
50905
|
+
]
|
|
50906
|
+
}
|
|
50907
|
+
) })
|
|
50814
50908
|
] });
|
|
50815
50909
|
}
|
|
50816
|
-
function TabBar({
|
|
50910
|
+
function TabBar({
|
|
50911
|
+
className,
|
|
50912
|
+
threadId: propThreadId
|
|
50913
|
+
}) {
|
|
50817
50914
|
const { currentThreadId } = useAppStore();
|
|
50818
50915
|
const threadId = propThreadId ?? currentThreadId;
|
|
50819
50916
|
const threadState = useThreadState(threadId);
|
|
@@ -50821,36 +50918,42 @@ function TabBar({ className, threadId: propThreadId }) {
|
|
|
50821
50918
|
return null;
|
|
50822
50919
|
}
|
|
50823
50920
|
const { openFiles, activeTab, setActiveTab, closeFile } = threadState;
|
|
50824
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
50825
|
-
"
|
|
50826
|
-
|
|
50827
|
-
|
|
50828
|
-
|
|
50829
|
-
|
|
50830
|
-
|
|
50831
|
-
|
|
50832
|
-
|
|
50833
|
-
"
|
|
50834
|
-
|
|
50921
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
50922
|
+
"div",
|
|
50923
|
+
{
|
|
50924
|
+
className: cn(
|
|
50925
|
+
"flex items-center h-9 border-b border-border bg-sidebar overflow-x-auto scrollbar-hide",
|
|
50926
|
+
className
|
|
50927
|
+
),
|
|
50928
|
+
children: [
|
|
50929
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
50930
|
+
"button",
|
|
50931
|
+
{
|
|
50932
|
+
onClick: () => setActiveTab("agent"),
|
|
50933
|
+
className: cn(
|
|
50934
|
+
"flex items-center gap-2 px-4 h-full text-sm font-medium transition-colors shrink-0 border-r border-border",
|
|
50935
|
+
activeTab === "agent" ? "bg-primary/15 text-primary border-b-2 border-b-primary" : "text-muted-foreground hover:text-foreground hover:bg-background-interactive"
|
|
50936
|
+
),
|
|
50937
|
+
children: [
|
|
50938
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "size-4" }),
|
|
50939
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Agent" })
|
|
50940
|
+
]
|
|
50941
|
+
}
|
|
50835
50942
|
),
|
|
50836
|
-
|
|
50837
|
-
|
|
50838
|
-
|
|
50839
|
-
|
|
50840
|
-
|
|
50841
|
-
|
|
50842
|
-
|
|
50843
|
-
|
|
50844
|
-
|
|
50845
|
-
|
|
50846
|
-
|
|
50847
|
-
|
|
50848
|
-
|
|
50849
|
-
|
|
50850
|
-
file.path
|
|
50851
|
-
)),
|
|
50852
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0" })
|
|
50853
|
-
] });
|
|
50943
|
+
openFiles.map((file) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
50944
|
+
FileTab,
|
|
50945
|
+
{
|
|
50946
|
+
file,
|
|
50947
|
+
isActive: activeTab === file.path,
|
|
50948
|
+
onSelect: () => setActiveTab(file.path),
|
|
50949
|
+
onClose: () => closeFile(file.path)
|
|
50950
|
+
},
|
|
50951
|
+
file.path
|
|
50952
|
+
)),
|
|
50953
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0" })
|
|
50954
|
+
]
|
|
50955
|
+
}
|
|
50956
|
+
);
|
|
50854
50957
|
}
|
|
50855
50958
|
function FileTab({ file, isActive, onSelect, onClose }) {
|
|
50856
50959
|
const handleClose = (e) => {
|
|
@@ -50925,27 +51028,8 @@ const IMAGE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
|
50925
51028
|
"tiff",
|
|
50926
51029
|
"tif"
|
|
50927
51030
|
]);
|
|
50928
|
-
const VIDEO_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
50929
|
-
|
|
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
|
-
]);
|
|
51031
|
+
const VIDEO_EXTENSIONS = /* @__PURE__ */ new Set(["mp4", "webm", "ogg", "ogv", "mov", "avi", "wmv", "flv", "mkv"]);
|
|
51032
|
+
const AUDIO_EXTENSIONS = /* @__PURE__ */ new Set(["mp3", "wav", "ogg", "oga", "m4a", "flac", "aac", "weba"]);
|
|
50949
51033
|
const PDF_EXTENSIONS = /* @__PURE__ */ new Set(["pdf"]);
|
|
50950
51034
|
const CODE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
50951
51035
|
"ts",
|
|
@@ -51057,36 +51141,36 @@ function getFileType(fileName) {
|
|
|
51057
51141
|
function getMimeType(ext) {
|
|
51058
51142
|
const mimeTypes = {
|
|
51059
51143
|
// Images
|
|
51060
|
-
|
|
51061
|
-
|
|
51062
|
-
|
|
51063
|
-
|
|
51064
|
-
|
|
51065
|
-
|
|
51066
|
-
|
|
51067
|
-
|
|
51068
|
-
|
|
51069
|
-
|
|
51144
|
+
png: "image/png",
|
|
51145
|
+
jpg: "image/jpeg",
|
|
51146
|
+
jpeg: "image/jpeg",
|
|
51147
|
+
gif: "image/gif",
|
|
51148
|
+
svg: "image/svg+xml",
|
|
51149
|
+
webp: "image/webp",
|
|
51150
|
+
bmp: "image/bmp",
|
|
51151
|
+
ico: "image/x-icon",
|
|
51152
|
+
tiff: "image/tiff",
|
|
51153
|
+
tif: "image/tiff",
|
|
51070
51154
|
// Video
|
|
51071
|
-
|
|
51072
|
-
|
|
51073
|
-
|
|
51074
|
-
|
|
51075
|
-
|
|
51076
|
-
|
|
51077
|
-
|
|
51078
|
-
|
|
51079
|
-
|
|
51155
|
+
mp4: "video/mp4",
|
|
51156
|
+
webm: "video/webm",
|
|
51157
|
+
ogg: "video/ogg",
|
|
51158
|
+
ogv: "video/ogg",
|
|
51159
|
+
mov: "video/quicktime",
|
|
51160
|
+
avi: "video/x-msvideo",
|
|
51161
|
+
wmv: "video/x-ms-wmv",
|
|
51162
|
+
flv: "video/x-flv",
|
|
51163
|
+
mkv: "video/x-matroska",
|
|
51080
51164
|
// Audio
|
|
51081
|
-
|
|
51082
|
-
|
|
51083
|
-
|
|
51084
|
-
|
|
51085
|
-
|
|
51086
|
-
|
|
51087
|
-
|
|
51165
|
+
mp3: "audio/mpeg",
|
|
51166
|
+
wav: "audio/wav",
|
|
51167
|
+
oga: "audio/ogg",
|
|
51168
|
+
m4a: "audio/mp4",
|
|
51169
|
+
flac: "audio/flac",
|
|
51170
|
+
aac: "audio/aac",
|
|
51171
|
+
weba: "audio/webm",
|
|
51088
51172
|
// PDF
|
|
51089
|
-
|
|
51173
|
+
pdf: "application/pdf"
|
|
51090
51174
|
};
|
|
51091
51175
|
return mimeTypes[ext] || "application/octet-stream";
|
|
51092
51176
|
}
|
|
@@ -61610,25 +61694,25 @@ const SUPPORTED_LANGS = /* @__PURE__ */ new Set([
|
|
|
61610
61694
|
]);
|
|
61611
61695
|
function getLanguage(ext) {
|
|
61612
61696
|
const langMap = {
|
|
61613
|
-
|
|
61614
|
-
|
|
61615
|
-
|
|
61616
|
-
|
|
61617
|
-
|
|
61618
|
-
|
|
61619
|
-
|
|
61620
|
-
|
|
61621
|
-
|
|
61622
|
-
|
|
61623
|
-
|
|
61624
|
-
|
|
61625
|
-
|
|
61626
|
-
|
|
61627
|
-
|
|
61628
|
-
|
|
61629
|
-
|
|
61630
|
-
|
|
61631
|
-
|
|
61697
|
+
ts: "typescript",
|
|
61698
|
+
tsx: "tsx",
|
|
61699
|
+
js: "javascript",
|
|
61700
|
+
jsx: "jsx",
|
|
61701
|
+
mjs: "javascript",
|
|
61702
|
+
cjs: "javascript",
|
|
61703
|
+
py: "python",
|
|
61704
|
+
json: "json",
|
|
61705
|
+
css: "css",
|
|
61706
|
+
html: "html",
|
|
61707
|
+
htm: "html",
|
|
61708
|
+
md: "markdown",
|
|
61709
|
+
mdx: "markdown",
|
|
61710
|
+
yaml: "yaml",
|
|
61711
|
+
yml: "yaml",
|
|
61712
|
+
sh: "bash",
|
|
61713
|
+
bash: "bash",
|
|
61714
|
+
zsh: "bash",
|
|
61715
|
+
sql: "sql"
|
|
61632
61716
|
};
|
|
61633
61717
|
const lang2 = ext ? langMap[ext] : null;
|
|
61634
61718
|
return lang2 && SUPPORTED_LANGS.has(lang2) ? lang2 : null;
|
|
@@ -61678,19 +61762,17 @@ function CodeViewer({ filePath, content: content2 }) {
|
|
|
61678
61762
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/50", children: "•" }),
|
|
61679
61763
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/70", children: language || "plain text" })
|
|
61680
61764
|
] }),
|
|
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
|
-
) : (
|
|
61765
|
+
/* @__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
61766
|
// Fallback plain text rendering
|
|
61689
61767
|
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "p-4 text-sm font-mono leading-relaxed whitespace-pre-wrap break-all", children: content2 })
|
|
61690
61768
|
) }) })
|
|
61691
61769
|
] });
|
|
61692
61770
|
}
|
|
61693
|
-
function ImageViewer({
|
|
61771
|
+
function ImageViewer({
|
|
61772
|
+
filePath,
|
|
61773
|
+
base64Content,
|
|
61774
|
+
mimeType
|
|
61775
|
+
}) {
|
|
61694
61776
|
const [zoom, setZoom] = reactExports.useState(100);
|
|
61695
61777
|
const [rotation, setRotation] = reactExports.useState(0);
|
|
61696
61778
|
const [isPanning, setIsPanning] = reactExports.useState(false);
|
|
@@ -61700,10 +61782,18 @@ function ImageViewer({ filePath, base64Content, mimeType }) {
|
|
|
61700
61782
|
const fileName = filePath.split("/").pop() || filePath;
|
|
61701
61783
|
const imageUrl = `data:${mimeType};base64,${base64Content}`;
|
|
61702
61784
|
const handleZoomIn = () => {
|
|
61703
|
-
|
|
61785
|
+
const newZoom = Math.min(zoom + 25, 400);
|
|
61786
|
+
setZoom(newZoom);
|
|
61787
|
+
if (newZoom <= 100) {
|
|
61788
|
+
setPanOffset({ x: 0, y: 0 });
|
|
61789
|
+
}
|
|
61704
61790
|
};
|
|
61705
61791
|
const handleZoomOut = () => {
|
|
61706
|
-
|
|
61792
|
+
const newZoom = Math.max(zoom - 25, 25);
|
|
61793
|
+
setZoom(newZoom);
|
|
61794
|
+
if (newZoom <= 100) {
|
|
61795
|
+
setPanOffset({ x: 0, y: 0 });
|
|
61796
|
+
}
|
|
61707
61797
|
};
|
|
61708
61798
|
const handleResetZoom = () => {
|
|
61709
61799
|
setZoom(100);
|
|
@@ -61734,11 +61824,6 @@ function ImageViewer({ filePath, base64Content, mimeType }) {
|
|
|
61734
61824
|
const handleMouseLeave = () => {
|
|
61735
61825
|
setIsPanning(false);
|
|
61736
61826
|
};
|
|
61737
|
-
reactExports.useEffect(() => {
|
|
61738
|
-
if (zoom <= 100) {
|
|
61739
|
-
setPanOffset({ x: 0, y: 0 });
|
|
61740
|
-
}
|
|
61741
|
-
}, [zoom]);
|
|
61742
61827
|
const canPan = zoom > 100;
|
|
61743
61828
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col min-h-0 overflow-hidden", children: [
|
|
61744
61829
|
/* @__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 +61866,8 @@ function ImageViewer({ filePath, base64Content, mimeType }) {
|
|
|
61781
61866
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomIn, { className: "size-4" })
|
|
61782
61867
|
}
|
|
61783
61868
|
),
|
|
61784
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
61785
|
-
|
|
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
|
-
)
|
|
61869
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: handleRotate, className: "h-7 px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RotateCw, { className: "size-4" }) }),
|
|
61870
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "ghost", size: "sm", onClick: handleResetZoom, className: "h-7 px-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Maximize2, { className: "size-4" }) })
|
|
61804
61871
|
] })
|
|
61805
61872
|
] }),
|
|
61806
61873
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -61833,7 +61900,12 @@ function ImageViewer({ filePath, base64Content, mimeType }) {
|
|
|
61833
61900
|
) })
|
|
61834
61901
|
] });
|
|
61835
61902
|
}
|
|
61836
|
-
function MediaViewer({
|
|
61903
|
+
function MediaViewer({
|
|
61904
|
+
filePath,
|
|
61905
|
+
base64Content,
|
|
61906
|
+
mimeType,
|
|
61907
|
+
mediaType
|
|
61908
|
+
}) {
|
|
61837
61909
|
const fileName = filePath.split("/").pop() || filePath;
|
|
61838
61910
|
const mediaUrl = `data:${mimeType};base64,${base64Content}`;
|
|
61839
61911
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 flex-col min-h-0 overflow-hidden", children: [
|
|
@@ -61864,18 +61936,10 @@ function MediaViewer({ filePath, base64Content, mimeType, mediaType }) {
|
|
|
61864
61936
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground", children: "Audio File" })
|
|
61865
61937
|
] })
|
|
61866
61938
|
] }),
|
|
61867
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
61868
|
-
"
|
|
61869
|
-
|
|
61870
|
-
|
|
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
|
-
)
|
|
61939
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("audio", { controls: true, className: "w-full max-w-md", preload: "metadata", children: [
|
|
61940
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("source", { src: mediaUrl, type: mimeType }),
|
|
61941
|
+
"Your browser does not support the audio tag."
|
|
61942
|
+
] })
|
|
61879
61943
|
] }) }) })
|
|
61880
61944
|
] });
|
|
61881
61945
|
}
|
|
@@ -61895,39 +61959,22 @@ function PDFViewer({ filePath, base64Content }) {
|
|
|
61895
61959
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-muted-foreground/50", children: "•" }),
|
|
61896
61960
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "PDF Document" })
|
|
61897
61961
|
] }),
|
|
61898
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
61899
|
-
|
|
61900
|
-
{
|
|
61901
|
-
|
|
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
|
-
)
|
|
61962
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "ghost", size: "sm", onClick: handleOpenExternal, className: "h-7 px-2 gap-1", children: [
|
|
61963
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-3" }),
|
|
61964
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs", children: "Download" })
|
|
61965
|
+
] })
|
|
61911
61966
|
] }),
|
|
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
|
-
"
|
|
61914
|
-
{
|
|
61915
|
-
|
|
61916
|
-
|
|
61917
|
-
|
|
61918
|
-
|
|
61919
|
-
|
|
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
|
-
] })
|
|
61967
|
+
/* @__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: [
|
|
61968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "size-16 text-muted-foreground/50" }),
|
|
61969
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center", children: [
|
|
61970
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium text-foreground mb-2", children: fileName }),
|
|
61971
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-muted-foreground mb-4", children: "PDF preview not available in this browser" }),
|
|
61972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: handleOpenExternal, variant: "outline", children: [
|
|
61973
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "size-4 mr-2" }),
|
|
61974
|
+
"Download PDF"
|
|
61928
61975
|
] })
|
|
61929
|
-
}
|
|
61930
|
-
) }) })
|
|
61976
|
+
] })
|
|
61977
|
+
] }) }) }) })
|
|
61931
61978
|
] });
|
|
61932
61979
|
}
|
|
61933
61980
|
function BinaryFileViewer({ filePath, size: size2 }) {
|
|
@@ -62142,16 +62189,23 @@ function TodosDisplay({ todos }) {
|
|
|
62142
62189
|
const config2 = statusConfig[todo.status] || defaultConfig;
|
|
62143
62190
|
const Icon2 = config2.icon;
|
|
62144
62191
|
const isDone = todo.status === "completed" || todo.status === "cancelled";
|
|
62145
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
62146
|
-
"
|
|
62147
|
-
|
|
62148
|
-
|
|
62149
|
-
|
|
62150
|
-
|
|
62151
|
-
|
|
62192
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
62193
|
+
"div",
|
|
62194
|
+
{
|
|
62195
|
+
className: cn("flex items-start gap-2 text-xs", isDone && "opacity-50"),
|
|
62196
|
+
children: [
|
|
62197
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: cn("size-3.5 mt-0.5 shrink-0", config2.color) }),
|
|
62198
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: cn(isDone && "line-through"), children: todo.content })
|
|
62199
|
+
]
|
|
62200
|
+
},
|
|
62201
|
+
todo.id || i2
|
|
62202
|
+
);
|
|
62152
62203
|
}) });
|
|
62153
62204
|
}
|
|
62154
|
-
function FileListDisplay({
|
|
62205
|
+
function FileListDisplay({
|
|
62206
|
+
files,
|
|
62207
|
+
isGlob
|
|
62208
|
+
}) {
|
|
62155
62209
|
const items = files.slice(0, 15);
|
|
62156
62210
|
const hasMore = files.length > 15;
|
|
62157
62211
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-0.5", children: [
|
|
@@ -62170,12 +62224,17 @@ function FileListDisplay({ files, isGlob }) {
|
|
|
62170
62224
|
] })
|
|
62171
62225
|
] });
|
|
62172
62226
|
}
|
|
62173
|
-
function GrepResultsDisplay({
|
|
62174
|
-
|
|
62175
|
-
|
|
62176
|
-
|
|
62177
|
-
|
|
62178
|
-
|
|
62227
|
+
function GrepResultsDisplay({
|
|
62228
|
+
matches: matches2
|
|
62229
|
+
}) {
|
|
62230
|
+
const grouped = matches2.reduce(
|
|
62231
|
+
(acc, match) => {
|
|
62232
|
+
if (!acc[match.path]) acc[match.path] = [];
|
|
62233
|
+
acc[match.path].push(match);
|
|
62234
|
+
return acc;
|
|
62235
|
+
},
|
|
62236
|
+
{}
|
|
62237
|
+
);
|
|
62179
62238
|
const files = Object.keys(grouped).slice(0, 5);
|
|
62180
62239
|
const hasMore = Object.keys(grouped).length > 5;
|
|
62181
62240
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
@@ -62252,7 +62311,10 @@ function FileEditSummary({ args }) {
|
|
|
62252
62311
|
}
|
|
62253
62312
|
return null;
|
|
62254
62313
|
}
|
|
62255
|
-
function CommandDisplay({
|
|
62314
|
+
function CommandDisplay({
|
|
62315
|
+
command,
|
|
62316
|
+
output
|
|
62317
|
+
}) {
|
|
62256
62318
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs space-y-2 w-full overflow-hidden", children: [
|
|
62257
62319
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-mono bg-background rounded-sm p-2 flex items-center gap-2 min-w-0", children: [
|
|
62258
62320
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-status-info shrink-0", children: "$" }),
|
|
@@ -62264,7 +62326,10 @@ function CommandDisplay({ command, output }) {
|
|
|
62264
62326
|
] })
|
|
62265
62327
|
] });
|
|
62266
62328
|
}
|
|
62267
|
-
function TaskDisplay({
|
|
62329
|
+
function TaskDisplay({
|
|
62330
|
+
args,
|
|
62331
|
+
isExpanded
|
|
62332
|
+
}) {
|
|
62268
62333
|
const name2 = args.name;
|
|
62269
62334
|
const description = args.description;
|
|
62270
62335
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs space-y-1", children: [
|
|
@@ -62272,13 +62337,16 @@ function TaskDisplay({ args, isExpanded }) {
|
|
|
62272
62337
|
/* @__PURE__ */ jsxRuntimeExports.jsx(GitBranch, { className: "size-3 text-status-info" }),
|
|
62273
62338
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium truncate", children: name2 })
|
|
62274
62339
|
] }),
|
|
62275
|
-
description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: cn(
|
|
62276
|
-
"text-muted-foreground pl-5",
|
|
62277
|
-
!isExpanded && "line-clamp-2"
|
|
62278
|
-
), children: description })
|
|
62340
|
+
description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: cn("text-muted-foreground pl-5", !isExpanded && "line-clamp-2"), children: description })
|
|
62279
62341
|
] });
|
|
62280
62342
|
}
|
|
62281
|
-
function ToolCallRenderer({
|
|
62343
|
+
function ToolCallRenderer({
|
|
62344
|
+
toolCall,
|
|
62345
|
+
result,
|
|
62346
|
+
isError: isError2,
|
|
62347
|
+
needsApproval,
|
|
62348
|
+
onApprovalDecision
|
|
62349
|
+
}) {
|
|
62282
62350
|
const args = toolCall?.args || {};
|
|
62283
62351
|
const [isExpanded, setIsExpanded] = reactExports.useState(false);
|
|
62284
62352
|
if (!toolCall) {
|
|
@@ -62358,7 +62426,9 @@ function ToolCallRenderer({ toolCall, result, isError: isError2, needsApproval,
|
|
|
62358
62426
|
}
|
|
62359
62427
|
case "ls": {
|
|
62360
62428
|
if (Array.isArray(result)) {
|
|
62361
|
-
const dirs = result.filter(
|
|
62429
|
+
const dirs = result.filter(
|
|
62430
|
+
(f2) => typeof f2 === "object" && f2.is_dir
|
|
62431
|
+
).length;
|
|
62362
62432
|
const files = result.length - dirs;
|
|
62363
62433
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
|
|
62364
62434
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-status-nominal flex items-center gap-1.5", children: [
|
|
@@ -62491,72 +62561,89 @@ function ToolCallRenderer({ toolCall, result, isError: isError2, needsApproval,
|
|
|
62491
62561
|
const formattedContent = renderFormattedContent();
|
|
62492
62562
|
const formattedResult = renderFormattedResult();
|
|
62493
62563
|
const hasFormattedDisplay = formattedContent || formattedResult;
|
|
62494
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
62495
|
-
"
|
|
62496
|
-
|
|
62497
|
-
|
|
62498
|
-
|
|
62499
|
-
|
|
62500
|
-
|
|
62501
|
-
|
|
62502
|
-
|
|
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(
|
|
62564
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
62565
|
+
"div",
|
|
62566
|
+
{
|
|
62567
|
+
className: cn(
|
|
62568
|
+
"rounded-sm border overflow-hidden",
|
|
62569
|
+
needsApproval ? "border-amber-500/50 bg-amber-500/5" : "border-border bg-background-elevated"
|
|
62570
|
+
),
|
|
62571
|
+
children: [
|
|
62572
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
62523
62573
|
"button",
|
|
62524
62574
|
{
|
|
62525
|
-
|
|
62526
|
-
|
|
62527
|
-
children:
|
|
62575
|
+
onClick: () => setIsExpanded(!isExpanded),
|
|
62576
|
+
className: "flex w-full items-center gap-2 px-3 py-2 hover:bg-background-interactive transition-colors",
|
|
62577
|
+
children: [
|
|
62578
|
+
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" }),
|
|
62579
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
62580
|
+
Icon2,
|
|
62581
|
+
{
|
|
62582
|
+
className: cn("size-4 shrink-0", needsApproval ? "text-amber-500" : "text-status-info")
|
|
62583
|
+
}
|
|
62584
|
+
),
|
|
62585
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium shrink-0", children: label }),
|
|
62586
|
+
displayArg && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 truncate text-left text-xs text-muted-foreground font-mono", children: displayArg }),
|
|
62587
|
+
needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "warning", className: "ml-auto shrink-0", children: "APPROVAL" }),
|
|
62588
|
+
!needsApproval && result === void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "ml-auto shrink-0 animate-pulse", children: "RUNNING" }),
|
|
62589
|
+
result !== void 0 && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: isError2 ? "critical" : "nominal", className: "ml-auto shrink-0", children: isError2 ? "ERROR" : "OK" }),
|
|
62590
|
+
isPanelSynced && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "shrink-0 text-[9px]", children: "SYNCED" })
|
|
62591
|
+
]
|
|
62528
62592
|
}
|
|
62529
62593
|
),
|
|
62530
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
62531
|
-
|
|
62532
|
-
{
|
|
62533
|
-
className: "
|
|
62534
|
-
|
|
62535
|
-
|
|
62536
|
-
|
|
62537
|
-
|
|
62538
|
-
|
|
62539
|
-
|
|
62540
|
-
|
|
62541
|
-
|
|
62542
|
-
|
|
62543
|
-
|
|
62544
|
-
|
|
62545
|
-
|
|
62546
|
-
|
|
62547
|
-
|
|
62548
|
-
|
|
62549
|
-
|
|
62550
|
-
|
|
62551
|
-
|
|
62552
|
-
|
|
62553
|
-
|
|
62554
|
-
|
|
62555
|
-
|
|
62556
|
-
|
|
62557
|
-
|
|
62558
|
-
|
|
62559
|
-
|
|
62594
|
+
needsApproval ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-amber-500/20 px-3 py-3 space-y-3", children: [
|
|
62595
|
+
formattedContent,
|
|
62596
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
62597
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header text-[10px] mb-1", children: "ARGUMENTS" }),
|
|
62598
|
+
/* @__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) })
|
|
62599
|
+
] }),
|
|
62600
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-2", children: [
|
|
62601
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
62602
|
+
"button",
|
|
62603
|
+
{
|
|
62604
|
+
className: "px-3 py-1.5 text-xs border border-border rounded-sm hover:bg-background-interactive transition-colors",
|
|
62605
|
+
onClick: handleReject,
|
|
62606
|
+
children: "Reject"
|
|
62607
|
+
}
|
|
62608
|
+
),
|
|
62609
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
62610
|
+
"button",
|
|
62611
|
+
{
|
|
62612
|
+
className: "px-3 py-1.5 text-xs bg-status-nominal text-background rounded-sm hover:bg-status-nominal/90 transition-colors",
|
|
62613
|
+
onClick: handleApprove,
|
|
62614
|
+
children: "Approve & Run"
|
|
62615
|
+
}
|
|
62616
|
+
)
|
|
62617
|
+
] })
|
|
62618
|
+
] }) : null,
|
|
62619
|
+
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: [
|
|
62620
|
+
formattedContent,
|
|
62621
|
+
formattedResult
|
|
62622
|
+
] }),
|
|
62623
|
+
isExpanded && !needsApproval && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-border px-3 py-2 space-y-2 overflow-hidden", children: [
|
|
62624
|
+
formattedContent,
|
|
62625
|
+
formattedResult,
|
|
62626
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden w-full", children: [
|
|
62627
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header mb-1", children: "RAW ARGUMENTS" }),
|
|
62628
|
+
/* @__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) })
|
|
62629
|
+
] }),
|
|
62630
|
+
result !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "overflow-hidden w-full", children: [
|
|
62631
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-section-header mb-1", children: "RAW RESULT" }),
|
|
62632
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
62633
|
+
"pre",
|
|
62634
|
+
{
|
|
62635
|
+
className: cn(
|
|
62636
|
+
"text-xs font-mono p-2 rounded-sm overflow-auto max-h-48 w-full whitespace-pre-wrap break-all",
|
|
62637
|
+
isError2 ? "bg-status-critical/10 text-status-critical" : "bg-background"
|
|
62638
|
+
),
|
|
62639
|
+
children: typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
62640
|
+
}
|
|
62641
|
+
)
|
|
62642
|
+
] })
|
|
62643
|
+
] })
|
|
62644
|
+
]
|
|
62645
|
+
}
|
|
62646
|
+
);
|
|
62560
62647
|
}
|
|
62561
62648
|
function ok$1() {
|
|
62562
62649
|
}
|
|
@@ -73902,7 +73989,13 @@ const StreamingMarkdown = reactExports.memo(function StreamingMarkdown2({
|
|
|
73902
73989
|
isStreaming && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "inline-block w-2 h-4 ml-0.5 bg-foreground/70 animate-pulse" })
|
|
73903
73990
|
] });
|
|
73904
73991
|
});
|
|
73905
|
-
function MessageBubble({
|
|
73992
|
+
function MessageBubble({
|
|
73993
|
+
message,
|
|
73994
|
+
isStreaming,
|
|
73995
|
+
toolResults,
|
|
73996
|
+
pendingApproval,
|
|
73997
|
+
onApprovalDecision
|
|
73998
|
+
}) {
|
|
73906
73999
|
const isUser = message.role === "user";
|
|
73907
74000
|
const isTool = message.role === "tool";
|
|
73908
74001
|
if (isTool) {
|
|
@@ -73945,14 +74038,14 @@ function MessageBubble({ message, isStreaming, toolResults, pendingApproval, onA
|
|
|
73945
74038
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-3 overflow-hidden", children: [
|
|
73946
74039
|
/* @__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
74040
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 space-y-2 overflow-hidden", children: [
|
|
73948
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn(
|
|
73949
|
-
|
|
73950
|
-
|
|
73951
|
-
|
|
73952
|
-
|
|
73953
|
-
|
|
73954
|
-
|
|
73955
|
-
),
|
|
74041
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: cn("text-section-header", isUser && "text-right"), children: getLabel() }),
|
|
74042
|
+
content2 && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74043
|
+
"div",
|
|
74044
|
+
{
|
|
74045
|
+
className: cn("rounded-sm p-3 overflow-hidden", isUser ? "bg-primary/10" : "bg-card"),
|
|
74046
|
+
children: content2
|
|
74047
|
+
}
|
|
74048
|
+
),
|
|
73956
74049
|
hasToolCalls && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 overflow-hidden", children: message.tool_calls.map((toolCall, index2) => {
|
|
73957
74050
|
const result = toolResults?.get(toolCall.id);
|
|
73958
74051
|
const pendingId = pendingApproval?.tool_call?.id;
|
|
@@ -74333,14 +74426,10 @@ var Root2 = Popover$1;
|
|
|
74333
74426
|
var Trigger = PopoverTrigger$1;
|
|
74334
74427
|
var Portal$1 = PopoverPortal;
|
|
74335
74428
|
var Content2 = PopoverContent$1;
|
|
74336
|
-
function Popover({
|
|
74337
|
-
...props
|
|
74338
|
-
}) {
|
|
74429
|
+
function Popover({ ...props }) {
|
|
74339
74430
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Root2, { "data-slot": "popover", ...props });
|
|
74340
74431
|
}
|
|
74341
|
-
function PopoverTrigger({
|
|
74342
|
-
...props
|
|
74343
|
-
}) {
|
|
74432
|
+
function PopoverTrigger({ ...props }) {
|
|
74344
74433
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(Trigger, { "data-slot": "popover-trigger", ...props });
|
|
74345
74434
|
}
|
|
74346
74435
|
function PopoverContent({
|
|
@@ -74782,16 +74871,7 @@ const DialogContent = reactExports.forwardRef(({ className, children, ...props }
|
|
|
74782
74871
|
)
|
|
74783
74872
|
] }));
|
|
74784
74873
|
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
|
-
);
|
|
74874
|
+
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
74875
|
DialogHeader.displayName = "DialogHeader";
|
|
74796
74876
|
const DialogTitle = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74797
74877
|
Title,
|
|
@@ -74831,10 +74911,13 @@ Input.displayName = "Input";
|
|
|
74831
74911
|
const PROVIDER_INFO = {
|
|
74832
74912
|
anthropic: { placeholder: "sk-ant-...", envVar: "ANTHROPIC_API_KEY" },
|
|
74833
74913
|
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" }
|
|
74914
|
+
google: { placeholder: "AIza...", envVar: "GOOGLE_API_KEY" }
|
|
74836
74915
|
};
|
|
74837
|
-
function ApiKeyDialog({
|
|
74916
|
+
function ApiKeyDialog({
|
|
74917
|
+
open,
|
|
74918
|
+
onOpenChange,
|
|
74919
|
+
provider
|
|
74920
|
+
}) {
|
|
74838
74921
|
const [apiKey, setApiKey] = reactExports.useState("");
|
|
74839
74922
|
const [showKey, setShowKey] = reactExports.useState(false);
|
|
74840
74923
|
const [saving, setSaving] = reactExports.useState(false);
|
|
@@ -74965,14 +75048,14 @@ function ApiKeyDialog({ open, onOpenChange, provider }) {
|
|
|
74965
75048
|
] })
|
|
74966
75049
|
] }),
|
|
74967
75050
|
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 (
|
|
75051
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-xs text-muted-foreground", children: "Model Name (optional)" }),
|
|
74969
75052
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
74970
75053
|
Input,
|
|
74971
75054
|
{
|
|
74972
75055
|
type: "text",
|
|
74973
75056
|
value: modelName,
|
|
74974
75057
|
onChange: (e) => setModelName(e.target.value),
|
|
74975
|
-
placeholder: "gpt-4
|
|
75058
|
+
placeholder: "e.g., gpt-4"
|
|
74976
75059
|
}
|
|
74977
75060
|
),
|
|
74978
75061
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
@@ -74981,32 +75064,29 @@ function ApiKeyDialog({ open, onOpenChange, provider }) {
|
|
|
74981
75064
|
] })
|
|
74982
75065
|
] })
|
|
74983
75066
|
] }),
|
|
74984
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between", children: [
|
|
74985
|
-
hasExistingKey ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
74986
|
-
|
|
74987
|
-
|
|
74988
|
-
|
|
74989
|
-
|
|
74990
|
-
|
|
74991
|
-
|
|
74992
|
-
|
|
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" }),
|
|
75067
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between gap-2", children: [
|
|
75068
|
+
hasExistingKey && /* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "destructive", size: "sm", onClick: handleDelete2, disabled: deleting, children: deleting ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
75069
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin" }),
|
|
75070
|
+
"Removing..."
|
|
75071
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
75072
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "size-4" }),
|
|
75073
|
+
"Remove"
|
|
75074
|
+
] }) }),
|
|
75075
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 ml-auto", children: [
|
|
75001
75076
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
75002
75077
|
Button,
|
|
75003
75078
|
{
|
|
75004
|
-
|
|
75005
|
-
|
|
75006
|
-
|
|
75007
|
-
|
|
75079
|
+
variant: "outline",
|
|
75080
|
+
size: "sm",
|
|
75081
|
+
onClick: () => onOpenChange(false),
|
|
75082
|
+
disabled: saving,
|
|
75083
|
+
children: "Cancel"
|
|
75008
75084
|
}
|
|
75009
|
-
)
|
|
75085
|
+
),
|
|
75086
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", onClick: handleSave, disabled: saving || !apiKey.trim(), children: saving ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
75087
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin" }),
|
|
75088
|
+
"Saving..."
|
|
75089
|
+
] }) : "Save" })
|
|
75010
75090
|
] })
|
|
75011
75091
|
] })
|
|
75012
75092
|
] }) });
|
|
@@ -75158,26 +75238,11 @@ function AddProviderDialog({ open, onOpenChange, onSuccess }) {
|
|
|
75158
75238
|
] })
|
|
75159
75239
|
] }),
|
|
75160
75240
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
75161
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
75162
|
-
|
|
75163
|
-
{
|
|
75164
|
-
|
|
75165
|
-
|
|
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
|
-
)
|
|
75241
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: handleCancel, disabled: saving, children: "取消" }),
|
|
75242
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { onClick: handleSave, disabled: saving || !id || !name2 || !baseUrl || !apiKey, children: saving ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
75243
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 animate-spin mr-2" }),
|
|
75244
|
+
"保存中..."
|
|
75245
|
+
] }) : "保存" })
|
|
75181
75246
|
] })
|
|
75182
75247
|
] }) });
|
|
75183
75248
|
}
|
|
@@ -75191,11 +75256,21 @@ function GoogleIcon({ className }) {
|
|
|
75191
75256
|
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
75257
|
}
|
|
75193
75258
|
function CustomIcon({ className }) {
|
|
75194
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
75195
|
-
|
|
75196
|
-
|
|
75197
|
-
|
|
75198
|
-
|
|
75259
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
75260
|
+
"svg",
|
|
75261
|
+
{
|
|
75262
|
+
className,
|
|
75263
|
+
viewBox: "0 0 24 24",
|
|
75264
|
+
fill: "none",
|
|
75265
|
+
stroke: "currentColor",
|
|
75266
|
+
strokeWidth: "2",
|
|
75267
|
+
children: [
|
|
75268
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 2L2 7l10 5 10-5-10-5z" }),
|
|
75269
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2 17l10 5 10-5" }),
|
|
75270
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M2 12l10 5 10-5" })
|
|
75271
|
+
]
|
|
75272
|
+
}
|
|
75273
|
+
);
|
|
75199
75274
|
}
|
|
75200
75275
|
const PROVIDER_ICONS = {
|
|
75201
75276
|
anthropic: AnthropicIcon,
|
|
@@ -75211,8 +75286,7 @@ function getProviderIcon(providerId) {
|
|
|
75211
75286
|
const FALLBACK_PROVIDERS = [
|
|
75212
75287
|
{ id: "anthropic", name: "Anthropic", hasApiKey: false },
|
|
75213
75288
|
{ id: "openai", name: "OpenAI", hasApiKey: false },
|
|
75214
|
-
{ id: "google", name: "Google", hasApiKey: false }
|
|
75215
|
-
{ id: "custom", name: "Custom API", hasApiKey: false }
|
|
75289
|
+
{ id: "google", name: "Google", hasApiKey: false }
|
|
75216
75290
|
];
|
|
75217
75291
|
function ModelSwitcher({ threadId }) {
|
|
75218
75292
|
const [open, setOpen] = reactExports.useState(false);
|
|
@@ -75227,20 +75301,10 @@ function ModelSwitcher({ threadId }) {
|
|
|
75227
75301
|
loadProviders();
|
|
75228
75302
|
}, [loadModels, loadProviders]);
|
|
75229
75303
|
const displayProviders = providers.length > 0 ? providers : FALLBACK_PROVIDERS;
|
|
75230
|
-
|
|
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]);
|
|
75304
|
+
const effectiveProviderId = selectedProviderId || (currentModel ? models.find((m2) => m2.id === currentModel)?.provider : null) || (displayProviders.length > 0 ? displayProviders[0].id : null);
|
|
75241
75305
|
const selectedModel = models.find((m2) => m2.id === currentModel);
|
|
75242
|
-
const filteredModels =
|
|
75243
|
-
const selectedProvider = displayProviders.find((p2) => p2.id ===
|
|
75306
|
+
const filteredModels = effectiveProviderId ? models.filter((m2) => m2.provider === effectiveProviderId) : [];
|
|
75307
|
+
const selectedProvider = displayProviders.find((p2) => p2.id === effectiveProviderId);
|
|
75244
75308
|
function handleProviderClick(provider) {
|
|
75245
75309
|
setSelectedProviderId(provider.id);
|
|
75246
75310
|
}
|
|
@@ -75301,7 +75365,7 @@ function ModelSwitcher({ threadId }) {
|
|
|
75301
75365
|
onClick: () => handleProviderClick(provider),
|
|
75302
75366
|
className: cn(
|
|
75303
75367
|
"w-full flex items-center gap-1.5 px-2 py-1 rounded-sm text-xs transition-colors text-left",
|
|
75304
|
-
|
|
75368
|
+
effectiveProviderId === provider.id ? "bg-muted text-foreground" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"
|
|
75305
75369
|
),
|
|
75306
75370
|
children: [
|
|
75307
75371
|
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon2, { className: "size-3.5 shrink-0" }),
|
|
@@ -75321,10 +75385,20 @@ function ModelSwitcher({ threadId }) {
|
|
|
75321
75385
|
},
|
|
75322
75386
|
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
75387
|
children: [
|
|
75324
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
75325
|
-
|
|
75326
|
-
|
|
75327
|
-
|
|
75388
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
75389
|
+
"svg",
|
|
75390
|
+
{
|
|
75391
|
+
className: "size-4",
|
|
75392
|
+
viewBox: "0 0 24 24",
|
|
75393
|
+
fill: "none",
|
|
75394
|
+
stroke: "currentColor",
|
|
75395
|
+
strokeWidth: "2",
|
|
75396
|
+
children: [
|
|
75397
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
|
|
75398
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
|
|
75399
|
+
]
|
|
75400
|
+
}
|
|
75401
|
+
),
|
|
75328
75402
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "添加Provider" })
|
|
75329
75403
|
]
|
|
75330
75404
|
}
|
|
@@ -75341,14 +75415,7 @@ function ModelSwitcher({ threadId }) {
|
|
|
75341
75415
|
"API key required for ",
|
|
75342
75416
|
selectedProvider.name
|
|
75343
75417
|
] }),
|
|
75344
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
75345
|
-
Button,
|
|
75346
|
-
{
|
|
75347
|
-
size: "sm",
|
|
75348
|
-
onClick: () => handleConfigureApiKey(selectedProvider),
|
|
75349
|
-
children: "Configure API Key"
|
|
75350
|
-
}
|
|
75351
|
-
)
|
|
75418
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { size: "sm", onClick: () => handleConfigureApiKey(selectedProvider), children: "Configure API Key" })
|
|
75352
75419
|
] })
|
|
75353
75420
|
) : (
|
|
75354
75421
|
// Show models list with scrollable area
|
|
@@ -75577,11 +75644,16 @@ const MODEL_CONTEXT_LIMITS = {
|
|
|
75577
75644
|
"gpt-4o-mini": 128e3,
|
|
75578
75645
|
"gpt-4-turbo": 128e3,
|
|
75579
75646
|
"gpt-4": 8192,
|
|
75580
|
-
|
|
75647
|
+
o1: 2e5,
|
|
75581
75648
|
"o1-mini": 128e3,
|
|
75582
|
-
|
|
75649
|
+
o3: 2e5,
|
|
75583
75650
|
"o3-mini": 2e5,
|
|
75584
75651
|
// Google models
|
|
75652
|
+
"gemini-3-pro-preview": 2e6,
|
|
75653
|
+
"gemini-3-flash-preview": 1e6,
|
|
75654
|
+
"gemini-2.5-pro": 2e6,
|
|
75655
|
+
"gemini-2.5-flash": 1e6,
|
|
75656
|
+
"gemini-2.5-flash-lite": 1e6,
|
|
75585
75657
|
"gemini-2.0-flash": 1e6,
|
|
75586
75658
|
"gemini-1.5-pro": 2e6,
|
|
75587
75659
|
"gemini-1.5-flash": 1e6
|
|
@@ -75624,9 +75696,9 @@ function ContextUsageIndicator({
|
|
|
75624
75696
|
const contextLimit = getContextLimit(modelId);
|
|
75625
75697
|
const usedTokens = tokenUsage.inputTokens;
|
|
75626
75698
|
const usagePercent = Math.min(usedTokens / contextLimit * 100, 100);
|
|
75627
|
-
let colorClass = "text-
|
|
75628
|
-
let bgColorClass = "bg-
|
|
75629
|
-
let barColorClass = "bg-
|
|
75699
|
+
let colorClass = "text-blue-500";
|
|
75700
|
+
let bgColorClass = "bg-blue-500/20";
|
|
75701
|
+
let barColorClass = "bg-blue-500";
|
|
75630
75702
|
let statusText = "Normal";
|
|
75631
75703
|
if (usagePercent >= 90) {
|
|
75632
75704
|
colorClass = "text-red-500";
|
|
@@ -75670,96 +75742,97 @@ function ContextUsageIndicator({
|
|
|
75670
75742
|
]
|
|
75671
75743
|
}
|
|
75672
75744
|
) }),
|
|
75673
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
75674
|
-
|
|
75675
|
-
|
|
75676
|
-
|
|
75677
|
-
|
|
75678
|
-
|
|
75679
|
-
|
|
75680
|
-
|
|
75681
|
-
|
|
75682
|
-
|
|
75683
|
-
|
|
75684
|
-
|
|
75685
|
-
|
|
75686
|
-
|
|
75687
|
-
|
|
75688
|
-
|
|
75689
|
-
|
|
75690
|
-
|
|
75691
|
-
|
|
75692
|
-
|
|
75693
|
-
|
|
75694
|
-
|
|
75695
|
-
|
|
75696
|
-
|
|
75697
|
-
|
|
75698
|
-
|
|
75699
|
-
|
|
75700
|
-
] })
|
|
75701
|
-
] })
|
|
75745
|
+
/* @__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: [
|
|
75746
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
75747
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-medium text-foreground", children: "Context Window" }),
|
|
75748
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
75749
|
+
"span",
|
|
75750
|
+
{
|
|
75751
|
+
className: cn(
|
|
75752
|
+
"text-[10px] font-medium px-1.5 py-0.5 rounded",
|
|
75753
|
+
bgColorClass,
|
|
75754
|
+
colorClass
|
|
75755
|
+
),
|
|
75756
|
+
children: statusText
|
|
75757
|
+
}
|
|
75758
|
+
)
|
|
75759
|
+
] }),
|
|
75760
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
|
|
75761
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-2 bg-muted rounded-full overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
75762
|
+
"div",
|
|
75763
|
+
{
|
|
75764
|
+
className: cn("h-full rounded-full transition-all", barColorClass),
|
|
75765
|
+
style: { width: `${usagePercent}%` }
|
|
75766
|
+
}
|
|
75767
|
+
) }),
|
|
75768
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-between text-[10px] text-muted-foreground", children: [
|
|
75769
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
75770
|
+
formatTokenCountFull(usedTokens),
|
|
75771
|
+
" tokens"
|
|
75702
75772
|
] }),
|
|
75703
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
75704
|
-
|
|
75705
|
-
|
|
75706
|
-
|
|
75707
|
-
|
|
75708
|
-
|
|
75709
|
-
|
|
75710
|
-
|
|
75711
|
-
|
|
75712
|
-
|
|
75713
|
-
|
|
75714
|
-
|
|
75715
|
-
|
|
75716
|
-
|
|
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
|
-
] })
|
|
75773
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [
|
|
75774
|
+
formatTokenCountFull(contextLimit),
|
|
75775
|
+
" max"
|
|
75776
|
+
] })
|
|
75777
|
+
] })
|
|
75778
|
+
] }),
|
|
75779
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5 pt-2 border-t border-border", children: [
|
|
75780
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wider", children: "Token Breakdown" }),
|
|
75781
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
|
|
75782
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
75783
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
|
|
75784
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ArrowUp, { className: "size-3" }),
|
|
75785
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Input" })
|
|
75786
|
+
] }),
|
|
75787
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.inputTokens) })
|
|
75728
75788
|
] }),
|
|
75729
|
-
|
|
75730
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
75731
|
-
|
|
75732
|
-
|
|
75733
|
-
|
|
75734
|
-
|
|
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
|
-
] })
|
|
75789
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
75790
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
|
|
75791
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ArrowDown, { className: "size-3" }),
|
|
75792
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Output" })
|
|
75793
|
+
] }),
|
|
75794
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.outputTokens) })
|
|
75747
75795
|
] }),
|
|
75748
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
75749
|
-
"
|
|
75750
|
-
|
|
75751
|
-
|
|
75796
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs pt-1 border-t border-border/50", children: [
|
|
75797
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-muted-foreground", children: [
|
|
75798
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "size-3" }),
|
|
75799
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Total" })
|
|
75800
|
+
] }),
|
|
75801
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: formatTokenCountFull(tokenUsage.totalTokens) })
|
|
75802
|
+
] })
|
|
75752
75803
|
] })
|
|
75753
|
-
}
|
|
75754
|
-
|
|
75804
|
+
] }),
|
|
75805
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1.5 pt-2 border-t border-border", children: [
|
|
75806
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] font-medium text-muted-foreground uppercase tracking-wider", children: "Cache" }),
|
|
75807
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: hasCacheData ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
75808
|
+
tokenUsage.cacheReadTokens !== void 0 && tokenUsage.cacheReadTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
75809
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-green-500", children: [
|
|
75810
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Database, { className: "size-3" }),
|
|
75811
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Cache hits" })
|
|
75812
|
+
] }),
|
|
75813
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-green-500", children: formatTokenCountFull(tokenUsage.cacheReadTokens) })
|
|
75814
|
+
] }),
|
|
75815
|
+
tokenUsage.cacheCreationTokens !== void 0 && tokenUsage.cacheCreationTokens > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
75816
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-blue-500", children: [
|
|
75817
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Database, { className: "size-3" }),
|
|
75818
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Cache created" })
|
|
75819
|
+
] }),
|
|
75820
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-blue-500", children: formatTokenCountFull(tokenUsage.cacheCreationTokens) })
|
|
75821
|
+
] })
|
|
75822
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-muted-foreground", children: "No cached tokens" }) })
|
|
75823
|
+
] }),
|
|
75824
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "pt-2 border-t border-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] text-muted-foreground", children: [
|
|
75825
|
+
"Last updated: ",
|
|
75826
|
+
tokenUsage.lastUpdated.toLocaleTimeString()
|
|
75827
|
+
] }) })
|
|
75828
|
+
] }) })
|
|
75755
75829
|
] });
|
|
75756
75830
|
}
|
|
75757
75831
|
function ChatContainer({ threadId }) {
|
|
75758
|
-
const [input, setInput] = reactExports.useState("");
|
|
75759
75832
|
const inputRef = reactExports.useRef(null);
|
|
75760
75833
|
const scrollRef = reactExports.useRef(null);
|
|
75761
75834
|
const isAtBottomRef = reactExports.useRef(true);
|
|
75762
|
-
const { loadThreads, generateTitleForFirstMessage } = useAppStore();
|
|
75835
|
+
const { threads, loadThreads, generateTitleForFirstMessage } = useAppStore();
|
|
75763
75836
|
const {
|
|
75764
75837
|
messages: threadMessages,
|
|
75765
75838
|
pendingApproval,
|
|
@@ -75768,13 +75841,15 @@ function ChatContainer({ threadId }) {
|
|
|
75768
75841
|
workspacePath,
|
|
75769
75842
|
tokenUsage,
|
|
75770
75843
|
currentModel,
|
|
75844
|
+
draftInput: input,
|
|
75771
75845
|
setTodos,
|
|
75772
75846
|
setWorkspaceFiles,
|
|
75773
75847
|
setWorkspacePath,
|
|
75774
75848
|
setPendingApproval,
|
|
75775
75849
|
appendMessage,
|
|
75776
75850
|
setError,
|
|
75777
|
-
clearError
|
|
75851
|
+
clearError,
|
|
75852
|
+
setDraftInput: setInput
|
|
75778
75853
|
} = useCurrentThread(threadId);
|
|
75779
75854
|
const streamData = useThreadStream(threadId);
|
|
75780
75855
|
const stream = streamData.stream;
|
|
@@ -75784,12 +75859,15 @@ function ChatContainer({ threadId }) {
|
|
|
75784
75859
|
if (!pendingApproval || !stream) return;
|
|
75785
75860
|
setPendingApproval(null);
|
|
75786
75861
|
try {
|
|
75787
|
-
await stream.submit(null, {
|
|
75862
|
+
await stream.submit(null, {
|
|
75863
|
+
command: { resume: { decision } },
|
|
75864
|
+
config: { configurable: { thread_id: threadId, model_id: currentModel } }
|
|
75865
|
+
});
|
|
75788
75866
|
} catch (err) {
|
|
75789
75867
|
console.error("[ChatContainer] Resume command failed:", err);
|
|
75790
75868
|
}
|
|
75791
75869
|
},
|
|
75792
|
-
[pendingApproval, setPendingApproval, stream]
|
|
75870
|
+
[pendingApproval, setPendingApproval, stream, threadId, currentModel]
|
|
75793
75871
|
);
|
|
75794
75872
|
const agentValues = stream?.values;
|
|
75795
75873
|
const streamTodos = agentValues?.todos;
|
|
@@ -75924,7 +76002,11 @@ function ChatContainer({ threadId }) {
|
|
|
75924
76002
|
};
|
|
75925
76003
|
appendMessage(userMessage);
|
|
75926
76004
|
if (isFirstMessage) {
|
|
75927
|
-
|
|
76005
|
+
const currentThread = threads.find((t) => t.thread_id === threadId);
|
|
76006
|
+
const hasDefaultTitle = currentThread?.title?.startsWith("Thread ");
|
|
76007
|
+
if (hasDefaultTitle) {
|
|
76008
|
+
generateTitleForFirstMessage(threadId, message);
|
|
76009
|
+
}
|
|
75928
76010
|
}
|
|
75929
76011
|
await stream.submit(
|
|
75930
76012
|
{
|
|
@@ -75932,7 +76014,7 @@ function ChatContainer({ threadId }) {
|
|
|
75932
76014
|
},
|
|
75933
76015
|
{
|
|
75934
76016
|
config: {
|
|
75935
|
-
configurable: { thread_id: threadId }
|
|
76017
|
+
configurable: { thread_id: threadId, model_id: currentModel }
|
|
75936
76018
|
}
|
|
75937
76019
|
}
|
|
75938
76020
|
);
|
|
@@ -76034,7 +76116,17 @@ function ChatContainer({ threadId }) {
|
|
|
76034
76116
|
style: { minHeight: "48px", maxHeight: "200px" }
|
|
76035
76117
|
}
|
|
76036
76118
|
),
|
|
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(
|
|
76119
|
+
/* @__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(
|
|
76120
|
+
Button,
|
|
76121
|
+
{
|
|
76122
|
+
type: "submit",
|
|
76123
|
+
variant: "default",
|
|
76124
|
+
size: "icon",
|
|
76125
|
+
disabled: !input.trim(),
|
|
76126
|
+
className: "rounded-md",
|
|
76127
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Send, { className: "size-4" })
|
|
76128
|
+
}
|
|
76129
|
+
) })
|
|
76038
76130
|
] }),
|
|
76039
76131
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
76040
76132
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
@@ -76585,14 +76677,11 @@ function buildFileTree(files) {
|
|
|
76585
76677
|
return root2;
|
|
76586
76678
|
}
|
|
76587
76679
|
function FileTree({ files }) {
|
|
76680
|
+
const { currentThreadId } = useAppStore();
|
|
76681
|
+
const threadState = useThreadState(currentThreadId);
|
|
76682
|
+
const openFile = threadState?.openFile;
|
|
76588
76683
|
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
|
-
});
|
|
76684
|
+
const [expanded, setExpanded] = reactExports.useState(/* @__PURE__ */ new Set());
|
|
76596
76685
|
const toggleExpand = reactExports.useCallback((path2) => {
|
|
76597
76686
|
setExpanded((prev) => {
|
|
76598
76687
|
const next = new Set(prev);
|
|
@@ -76610,59 +76699,64 @@ function FileTree({ files }) {
|
|
|
76610
76699
|
node: node2,
|
|
76611
76700
|
depth: 0,
|
|
76612
76701
|
expanded,
|
|
76613
|
-
onToggle: toggleExpand
|
|
76702
|
+
onToggle: toggleExpand,
|
|
76703
|
+
openFile
|
|
76614
76704
|
},
|
|
76615
76705
|
node2.path
|
|
76616
76706
|
)) });
|
|
76617
76707
|
}
|
|
76618
|
-
|
|
76619
|
-
|
|
76620
|
-
|
|
76621
|
-
|
|
76622
|
-
|
|
76623
|
-
|
|
76624
|
-
|
|
76625
|
-
|
|
76626
|
-
|
|
76627
|
-
|
|
76628
|
-
|
|
76629
|
-
|
|
76630
|
-
|
|
76631
|
-
|
|
76632
|
-
|
|
76633
|
-
|
|
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
|
-
]
|
|
76708
|
+
const FileTreeNode = reactExports.memo(
|
|
76709
|
+
function FileTreeNode2({
|
|
76710
|
+
node: node2,
|
|
76711
|
+
depth,
|
|
76712
|
+
expanded,
|
|
76713
|
+
onToggle,
|
|
76714
|
+
openFile
|
|
76715
|
+
}) {
|
|
76716
|
+
const isExpanded = expanded.has(node2.path);
|
|
76717
|
+
const hasChildren = node2.children.length > 0;
|
|
76718
|
+
const paddingLeft = 8 + depth * 16;
|
|
76719
|
+
const handleClick = () => {
|
|
76720
|
+
if (node2.is_dir) {
|
|
76721
|
+
onToggle(node2.path);
|
|
76722
|
+
} else if (openFile) {
|
|
76723
|
+
openFile(node2.path, node2.name);
|
|
76652
76724
|
}
|
|
76653
|
-
|
|
76654
|
-
|
|
76655
|
-
|
|
76656
|
-
|
|
76657
|
-
|
|
76658
|
-
|
|
76659
|
-
|
|
76660
|
-
|
|
76661
|
-
|
|
76662
|
-
|
|
76663
|
-
|
|
76664
|
-
|
|
76665
|
-
}
|
|
76725
|
+
};
|
|
76726
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
76727
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
76728
|
+
"div",
|
|
76729
|
+
{
|
|
76730
|
+
onClick: handleClick,
|
|
76731
|
+
className: cn(
|
|
76732
|
+
"flex items-center gap-1.5 py-1 pr-3 text-xs hover:bg-background-interactive cursor-pointer"
|
|
76733
|
+
),
|
|
76734
|
+
style: { paddingLeft },
|
|
76735
|
+
children: [
|
|
76736
|
+
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" }),
|
|
76737
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(FileIcon, { name: node2.name, isDir: node2.is_dir, isOpen: isExpanded }),
|
|
76738
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "truncate flex-1", children: node2.name }),
|
|
76739
|
+
!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) })
|
|
76740
|
+
]
|
|
76741
|
+
}
|
|
76742
|
+
),
|
|
76743
|
+
node2.is_dir && isExpanded && node2.children.map((child) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76744
|
+
FileTreeNode2,
|
|
76745
|
+
{
|
|
76746
|
+
node: child,
|
|
76747
|
+
depth: depth + 1,
|
|
76748
|
+
expanded,
|
|
76749
|
+
onToggle,
|
|
76750
|
+
openFile
|
|
76751
|
+
},
|
|
76752
|
+
child.path
|
|
76753
|
+
))
|
|
76754
|
+
] });
|
|
76755
|
+
},
|
|
76756
|
+
(prevProps, nextProps) => {
|
|
76757
|
+
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;
|
|
76758
|
+
}
|
|
76759
|
+
);
|
|
76666
76760
|
function FileIcon({
|
|
76667
76761
|
name: name2,
|
|
76668
76762
|
isDir,
|
|
@@ -76743,27 +76837,321 @@ function formatSize(bytes) {
|
|
|
76743
76837
|
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
|
|
76744
76838
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
76745
76839
|
}
|
|
76840
|
+
const columnConfig = {
|
|
76841
|
+
pending: { badge: "outline", borderColor: "border-t-border" },
|
|
76842
|
+
in_progress: { badge: "info", borderColor: "border-t-status-info" },
|
|
76843
|
+
interrupted: { badge: "warning", borderColor: "border-t-status-warning" },
|
|
76844
|
+
done: { badge: "nominal", borderColor: "border-t-status-nominal" }
|
|
76845
|
+
};
|
|
76846
|
+
function KanbanColumn({
|
|
76847
|
+
title,
|
|
76848
|
+
status,
|
|
76849
|
+
count: count2,
|
|
76850
|
+
children
|
|
76851
|
+
}) {
|
|
76852
|
+
const config2 = columnConfig[status];
|
|
76853
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
76854
|
+
"div",
|
|
76855
|
+
{
|
|
76856
|
+
className: cn(
|
|
76857
|
+
"flex flex-col min-w-[200px] w-[200px] flex-1 bg-muted/30 rounded-sm border border-border border-t-2",
|
|
76858
|
+
config2.borderColor
|
|
76859
|
+
),
|
|
76860
|
+
children: [
|
|
76861
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-b border-border", children: [
|
|
76862
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-section-header", children: title }),
|
|
76863
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: config2.badge, children: count2 })
|
|
76864
|
+
] }),
|
|
76865
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 space-y-2", children }) })
|
|
76866
|
+
]
|
|
76867
|
+
}
|
|
76868
|
+
);
|
|
76869
|
+
}
|
|
76870
|
+
const Card = reactExports.forwardRef(
|
|
76871
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76872
|
+
"div",
|
|
76873
|
+
{
|
|
76874
|
+
ref,
|
|
76875
|
+
className: cn("rounded-sm border border-border bg-card text-card-foreground", className),
|
|
76876
|
+
...props
|
|
76877
|
+
}
|
|
76878
|
+
)
|
|
76879
|
+
);
|
|
76880
|
+
Card.displayName = "Card";
|
|
76881
|
+
const CardHeader = reactExports.forwardRef(
|
|
76882
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-4", className), ...props })
|
|
76883
|
+
);
|
|
76884
|
+
CardHeader.displayName = "CardHeader";
|
|
76885
|
+
const CardTitle = reactExports.forwardRef(
|
|
76886
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { ref, className: cn("text-section-header", className), ...props })
|
|
76887
|
+
);
|
|
76888
|
+
CardTitle.displayName = "CardTitle";
|
|
76889
|
+
const CardDescription = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
|
|
76890
|
+
CardDescription.displayName = "CardDescription";
|
|
76891
|
+
const CardContent = reactExports.forwardRef(
|
|
76892
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("p-4 pt-0", className), ...props })
|
|
76893
|
+
);
|
|
76894
|
+
CardContent.displayName = "CardContent";
|
|
76895
|
+
const CardFooter = reactExports.forwardRef(
|
|
76896
|
+
({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex items-center p-4 pt-0", className), ...props })
|
|
76897
|
+
);
|
|
76898
|
+
CardFooter.displayName = "CardFooter";
|
|
76899
|
+
function ThreadStatusIcon({ threadId }) {
|
|
76900
|
+
const { isLoading } = useThreadStream(threadId);
|
|
76901
|
+
if (isLoading) {
|
|
76902
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 text-status-info animate-spin" });
|
|
76903
|
+
}
|
|
76904
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-muted-foreground" });
|
|
76905
|
+
}
|
|
76906
|
+
function ThreadKanbanCard({ thread, status, onClick }) {
|
|
76907
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76908
|
+
Card,
|
|
76909
|
+
{
|
|
76910
|
+
className: cn(
|
|
76911
|
+
"cursor-pointer transition-all hover:border-border-emphasis hover:bg-background-interactive",
|
|
76912
|
+
status === "in_progress" && "border-status-info/50",
|
|
76913
|
+
status === "interrupted" && "!border-amber-500/50 !bg-amber-500/5"
|
|
76914
|
+
),
|
|
76915
|
+
onClick,
|
|
76916
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2", children: [
|
|
76917
|
+
status === "interrupted" ? /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-amber-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadStatusIcon, { threadId: thread.thread_id }),
|
|
76918
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
76919
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
76920
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: thread.title || truncate(thread.thread_id, 20) }),
|
|
76921
|
+
status === "done" && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "nominal", className: "shrink-0 text-[9px]", children: "DONE" })
|
|
76922
|
+
] }),
|
|
76923
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mt-1 text-[10px] text-muted-foreground", children: [
|
|
76924
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
|
|
76925
|
+
formatRelativeTime(thread.updated_at)
|
|
76926
|
+
] })
|
|
76927
|
+
] })
|
|
76928
|
+
] }) })
|
|
76929
|
+
}
|
|
76930
|
+
);
|
|
76931
|
+
}
|
|
76932
|
+
function SubagentKanbanCard({
|
|
76933
|
+
subagent,
|
|
76934
|
+
parentThread,
|
|
76935
|
+
onClick
|
|
76936
|
+
}) {
|
|
76937
|
+
const isDone = subagent.status === "completed" || subagent.status === "failed";
|
|
76938
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76939
|
+
Card,
|
|
76940
|
+
{
|
|
76941
|
+
className: cn(
|
|
76942
|
+
"cursor-pointer transition-all hover:border-border-emphasis hover:bg-background-interactive border-dashed",
|
|
76943
|
+
subagent.status === "running" && "border-status-info/50"
|
|
76944
|
+
),
|
|
76945
|
+
onClick,
|
|
76946
|
+
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: [
|
|
76947
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76948
|
+
Bot,
|
|
76949
|
+
{
|
|
76950
|
+
className: cn(
|
|
76951
|
+
"size-4 shrink-0",
|
|
76952
|
+
subagent.status === "running" ? "text-status-info" : "text-muted-foreground"
|
|
76953
|
+
)
|
|
76954
|
+
}
|
|
76955
|
+
),
|
|
76956
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
|
|
76957
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
76958
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: subagent.name }),
|
|
76959
|
+
isDone && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76960
|
+
Badge,
|
|
76961
|
+
{
|
|
76962
|
+
variant: subagent.status === "failed" ? "critical" : "nominal",
|
|
76963
|
+
className: "shrink-0 text-[9px]",
|
|
76964
|
+
children: subagent.status === "failed" ? "FAILED" : "DONE"
|
|
76965
|
+
}
|
|
76966
|
+
)
|
|
76967
|
+
] }),
|
|
76968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-muted-foreground line-clamp-2 mt-0.5 break-words", children: subagent.description }),
|
|
76969
|
+
/* @__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: [
|
|
76970
|
+
"↳ ",
|
|
76971
|
+
parentThread.title || truncate(parentThread.thread_id, 15)
|
|
76972
|
+
] }) })
|
|
76973
|
+
] })
|
|
76974
|
+
] }) })
|
|
76975
|
+
}
|
|
76976
|
+
);
|
|
76977
|
+
}
|
|
76978
|
+
function getThreadKanbanStatus(thread, isLoading, hasDraft, hasPendingApproval) {
|
|
76979
|
+
if (hasPendingApproval || thread.status === "interrupted") return "interrupted";
|
|
76980
|
+
if (thread.status === "busy" || isLoading) return "in_progress";
|
|
76981
|
+
if (hasDraft) return "pending";
|
|
76982
|
+
return "done";
|
|
76983
|
+
}
|
|
76984
|
+
function KanbanView() {
|
|
76985
|
+
const { threads, selectThread, showSubagentsInKanban } = useAppStore();
|
|
76986
|
+
const allThreadStates = useAllThreadStates();
|
|
76987
|
+
const loadingStates = useAllStreamLoadingStates();
|
|
76988
|
+
const handleCardClick = (threadId) => {
|
|
76989
|
+
selectThread(threadId);
|
|
76990
|
+
};
|
|
76991
|
+
const categorizedThreads = reactExports.useMemo(() => {
|
|
76992
|
+
const result = {
|
|
76993
|
+
pending: [],
|
|
76994
|
+
in_progress: [],
|
|
76995
|
+
interrupted: [],
|
|
76996
|
+
done: []
|
|
76997
|
+
};
|
|
76998
|
+
for (const thread of threads) {
|
|
76999
|
+
const isLoading = loadingStates[thread.thread_id] ?? false;
|
|
77000
|
+
const threadState = allThreadStates[thread.thread_id];
|
|
77001
|
+
const hasDraft = Boolean(threadState?.draftInput?.trim());
|
|
77002
|
+
const hasPendingApproval = Boolean(threadState?.pendingApproval);
|
|
77003
|
+
const status = getThreadKanbanStatus(thread, isLoading, hasDraft, hasPendingApproval);
|
|
77004
|
+
result[status].push({ thread, status });
|
|
77005
|
+
}
|
|
77006
|
+
return result;
|
|
77007
|
+
}, [threads, loadingStates, allThreadStates]);
|
|
77008
|
+
const categorizedSubagents = reactExports.useMemo(() => {
|
|
77009
|
+
if (!showSubagentsInKanban) {
|
|
77010
|
+
return { pending: [], in_progress: [], interrupted: [], done: [] };
|
|
77011
|
+
}
|
|
77012
|
+
const result = {
|
|
77013
|
+
pending: [],
|
|
77014
|
+
in_progress: [],
|
|
77015
|
+
interrupted: [],
|
|
77016
|
+
done: []
|
|
77017
|
+
};
|
|
77018
|
+
const threadMap = new Map(threads.map((t) => [t.thread_id, t]));
|
|
77019
|
+
for (const [threadId, state] of Object.entries(allThreadStates)) {
|
|
77020
|
+
const parentThread = threadMap.get(threadId);
|
|
77021
|
+
if (!parentThread || !state.subagents) continue;
|
|
77022
|
+
for (const subagent of state.subagents) {
|
|
77023
|
+
let status;
|
|
77024
|
+
switch (subagent.status) {
|
|
77025
|
+
case "pending":
|
|
77026
|
+
status = "pending";
|
|
77027
|
+
break;
|
|
77028
|
+
case "running":
|
|
77029
|
+
status = "in_progress";
|
|
77030
|
+
break;
|
|
77031
|
+
case "completed":
|
|
77032
|
+
status = "done";
|
|
77033
|
+
break;
|
|
77034
|
+
case "failed":
|
|
77035
|
+
status = "done";
|
|
77036
|
+
break;
|
|
77037
|
+
default:
|
|
77038
|
+
status = "pending";
|
|
77039
|
+
}
|
|
77040
|
+
result[status].push({ subagent, parentThread, status });
|
|
77041
|
+
}
|
|
77042
|
+
}
|
|
77043
|
+
return result;
|
|
77044
|
+
}, [threads, allThreadStates, showSubagentsInKanban]);
|
|
77045
|
+
const columnData = [
|
|
77046
|
+
{ status: "pending", title: "PENDING" },
|
|
77047
|
+
{ status: "in_progress", title: "IN PROGRESS" },
|
|
77048
|
+
{ status: "interrupted", title: "BLOCKED" },
|
|
77049
|
+
{ status: "done", title: "DONE" }
|
|
77050
|
+
];
|
|
77051
|
+
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 }) => {
|
|
77052
|
+
const threadItems = categorizedThreads[status];
|
|
77053
|
+
const subagentItems = categorizedSubagents[status];
|
|
77054
|
+
const totalCount = threadItems.length + subagentItems.length;
|
|
77055
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(KanbanColumn, { title, status, count: totalCount, children: [
|
|
77056
|
+
threadItems.map(({ thread, status: threadStatus }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
77057
|
+
ThreadKanbanCard,
|
|
77058
|
+
{
|
|
77059
|
+
thread,
|
|
77060
|
+
status: threadStatus,
|
|
77061
|
+
onClick: () => handleCardClick(thread.thread_id)
|
|
77062
|
+
},
|
|
77063
|
+
thread.thread_id
|
|
77064
|
+
)),
|
|
77065
|
+
subagentItems.map(({ subagent, parentThread }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
77066
|
+
SubagentKanbanCard,
|
|
77067
|
+
{
|
|
77068
|
+
subagent,
|
|
77069
|
+
parentThread,
|
|
77070
|
+
onClick: () => handleCardClick(parentThread.thread_id)
|
|
77071
|
+
},
|
|
77072
|
+
subagent.id
|
|
77073
|
+
)),
|
|
77074
|
+
totalCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center text-sm text-muted-foreground py-8", children: "No items" })
|
|
77075
|
+
] }, status);
|
|
77076
|
+
}) }) }) });
|
|
77077
|
+
}
|
|
77078
|
+
function KanbanHeader({ className }) {
|
|
77079
|
+
const { showSubagentsInKanban, setShowSubagentsInKanban, threads } = useAppStore();
|
|
77080
|
+
const activeCount = threads.filter(
|
|
77081
|
+
(t) => t.status === "busy" || t.status === "interrupted"
|
|
77082
|
+
).length;
|
|
77083
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
77084
|
+
"div",
|
|
77085
|
+
{
|
|
77086
|
+
className: cn(
|
|
77087
|
+
"flex items-center justify-between px-3 app-no-drag relative overflow-hidden",
|
|
77088
|
+
className
|
|
77089
|
+
),
|
|
77090
|
+
children: [
|
|
77091
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 pointer-events-none opacity-[0.03]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
77092
|
+
"div",
|
|
77093
|
+
{
|
|
77094
|
+
className: "absolute inset-0",
|
|
77095
|
+
style: {
|
|
77096
|
+
backgroundImage: "repeating-linear-gradient(0deg, transparent, transparent 2px, currentColor 2px, currentColor 3px)",
|
|
77097
|
+
backgroundSize: "100% 3px"
|
|
77098
|
+
}
|
|
77099
|
+
}
|
|
77100
|
+
) }),
|
|
77101
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-mono uppercase tracking-wider text-muted-foreground", children: [
|
|
77102
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
77103
|
+
"div",
|
|
77104
|
+
{
|
|
77105
|
+
className: cn(
|
|
77106
|
+
"size-1.5 rounded-full",
|
|
77107
|
+
activeCount > 0 ? "bg-status-nominal animate-tactical-pulse" : "bg-muted-foreground"
|
|
77108
|
+
)
|
|
77109
|
+
}
|
|
77110
|
+
),
|
|
77111
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "tabular-nums", children: activeCount > 0 ? `${activeCount} ACTIVE` : "IDLE" })
|
|
77112
|
+
] }),
|
|
77113
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
77114
|
+
Button,
|
|
77115
|
+
{
|
|
77116
|
+
variant: showSubagentsInKanban ? "secondary" : "ghost",
|
|
77117
|
+
size: "sm",
|
|
77118
|
+
onClick: () => setShowSubagentsInKanban(!showSubagentsInKanban),
|
|
77119
|
+
className: "gap-2 h-7 relative",
|
|
77120
|
+
children: [
|
|
77121
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "size-3.5" }),
|
|
77122
|
+
showSubagentsInKanban ? "Hide" : "Show",
|
|
77123
|
+
" Subagents"
|
|
77124
|
+
]
|
|
77125
|
+
}
|
|
77126
|
+
)
|
|
77127
|
+
]
|
|
77128
|
+
}
|
|
77129
|
+
);
|
|
77130
|
+
}
|
|
76746
77131
|
const HANDLE_WIDTH = 6;
|
|
76747
77132
|
function ResizeHandle({ onDrag }) {
|
|
76748
77133
|
const startXRef = reactExports.useRef(0);
|
|
76749
|
-
const handleMouseDown = reactExports.useCallback(
|
|
76750
|
-
e
|
|
76751
|
-
|
|
76752
|
-
|
|
76753
|
-
const
|
|
76754
|
-
|
|
76755
|
-
|
|
76756
|
-
|
|
76757
|
-
|
|
76758
|
-
|
|
76759
|
-
|
|
76760
|
-
|
|
76761
|
-
|
|
76762
|
-
|
|
76763
|
-
|
|
76764
|
-
|
|
76765
|
-
|
|
76766
|
-
|
|
77134
|
+
const handleMouseDown = reactExports.useCallback(
|
|
77135
|
+
(e) => {
|
|
77136
|
+
e.preventDefault();
|
|
77137
|
+
startXRef.current = e.clientX;
|
|
77138
|
+
const handleMouseMove = (e2) => {
|
|
77139
|
+
const totalDelta = e2.clientX - startXRef.current;
|
|
77140
|
+
onDrag(totalDelta);
|
|
77141
|
+
};
|
|
77142
|
+
const handleMouseUp = () => {
|
|
77143
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
77144
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
77145
|
+
document.body.style.cursor = "";
|
|
77146
|
+
document.body.style.userSelect = "";
|
|
77147
|
+
};
|
|
77148
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
77149
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
77150
|
+
document.body.style.cursor = "col-resize";
|
|
77151
|
+
document.body.style.userSelect = "none";
|
|
77152
|
+
},
|
|
77153
|
+
[onDrag]
|
|
77154
|
+
);
|
|
76767
77155
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
76768
77156
|
"div",
|
|
76769
77157
|
{
|
|
@@ -76781,7 +77169,7 @@ const RIGHT_MIN = 250;
|
|
|
76781
77169
|
const RIGHT_MAX = 450;
|
|
76782
77170
|
const RIGHT_DEFAULT = 320;
|
|
76783
77171
|
function App() {
|
|
76784
|
-
const { currentThreadId, loadThreads, createThread } = useAppStore();
|
|
77172
|
+
const { currentThreadId, loadThreads, createThread, showKanbanView } = useAppStore();
|
|
76785
77173
|
const [isLoading, setIsLoading] = reactExports.useState(true);
|
|
76786
77174
|
const [leftWidth, setLeftWidth] = reactExports.useState(LEFT_DEFAULT);
|
|
76787
77175
|
const [rightWidth, setRightWidth] = reactExports.useState(RIGHT_DEFAULT);
|
|
@@ -76871,24 +77259,29 @@ function App() {
|
|
|
76871
77259
|
},
|
|
76872
77260
|
children: [
|
|
76873
77261
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-name", children: "OPENWORK" }),
|
|
76874
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.
|
|
77262
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.2" })
|
|
76875
77263
|
]
|
|
76876
77264
|
}
|
|
76877
77265
|
),
|
|
76878
77266
|
/* @__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
|
|
76880
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0" }),
|
|
77267
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-9 w-full shrink-0 app-drag-region", children: [
|
|
77268
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0 bg-sidebar" }),
|
|
76881
77269
|
/* @__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" }) })
|
|
77270
|
+
/* @__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
77271
|
] }),
|
|
76884
77272
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 overflow-hidden", children: [
|
|
76885
77273
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadSidebar, {}) }),
|
|
76886
77274
|
/* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleLeftResize }),
|
|
76887
|
-
|
|
77275
|
+
showKanbanView ? (
|
|
77276
|
+
/* Kanban View - replaces center and right panels */
|
|
77277
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "flex flex-1 flex-col min-w-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(KanbanView, {}) })
|
|
77278
|
+
) : /* @__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
77279
|
] })
|
|
76889
77280
|
] }),
|
|
76890
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
76891
|
-
|
|
77281
|
+
!showKanbanView && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
77282
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleRightResize }),
|
|
77283
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: rightWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RightPanel, {}) })
|
|
77284
|
+
] })
|
|
76892
77285
|
] }) });
|
|
76893
77286
|
}
|
|
76894
77287
|
ReactDOM$1.createRoot(document.getElementById("root")).render(
|