openwork 0.1.4 → 0.2.0

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 CHANGED
@@ -44,7 +44,7 @@ Or configure them in-app via the settings panel.
44
44
  | --------- | -------------------------------------------------------------------------------------- |
45
45
  | Anthropic | Claude Opus 4.5, Claude Sonnet 4.5, Claude Haiku 4.5, Claude Opus 4.1, Claude Sonnet 4 |
46
46
  | OpenAI | GPT-5.2, GPT-5.1, o3, o3 Mini, o4 Mini, o1, GPT-4.1, GPT-4o |
47
- | Google | Gemini 3 Pro Preview, Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash Lite |
47
+ | Google | Gemini 3 Pro Preview, Gemini 3 Flash Preview, Gemini 2.5 Pro, Gemini 2.5 Flash, Gemini 2.5 Flash Lite |
48
48
 
49
49
  ## Contributing
50
50
 
@@ -541,6 +541,11 @@
541
541
  display: inline-flex;
542
542
  }
543
543
 
544
+ .size-1\.5 {
545
+ width: calc(var(--spacing) * 1.5);
546
+ height: calc(var(--spacing) * 1.5);
547
+ }
548
+
544
549
  .size-2 {
545
550
  width: calc(var(--spacing) * 2);
546
551
  height: calc(var(--spacing) * 2);
@@ -760,6 +765,10 @@
760
765
  width: 140px;
761
766
  }
762
767
 
768
+ .w-\[200px\] {
769
+ width: 200px;
770
+ }
771
+
763
772
  .w-\[420px\] {
764
773
  width: 420px;
765
774
  }
@@ -816,6 +825,14 @@
816
825
  min-width: 8rem;
817
826
  }
818
827
 
828
+ .min-w-\[200px\] {
829
+ min-width: 200px;
830
+ }
831
+
832
+ .min-w-max {
833
+ min-width: max-content;
834
+ }
835
+
819
836
  .flex-1 {
820
837
  flex: 1;
821
838
  }
@@ -1043,6 +1060,11 @@
1043
1060
  border-top-width: 1px;
1044
1061
  }
1045
1062
 
1063
+ .border-t-2 {
1064
+ border-top-style: var(--tw-border-style);
1065
+ border-top-width: 2px;
1066
+ }
1067
+
1046
1068
  .border-r {
1047
1069
  border-right-style: var(--tw-border-style);
1048
1070
  border-right-width: 1px;
@@ -1068,6 +1090,21 @@
1068
1090
  border-left-width: 1px;
1069
1091
  }
1070
1092
 
1093
+ .border-dashed {
1094
+ --tw-border-style: dashed;
1095
+ border-style: dashed;
1096
+ }
1097
+
1098
+ .\!border-amber-500\/50 {
1099
+ border-color: #f99c0080 !important;
1100
+ }
1101
+
1102
+ @supports (color: color-mix(in lab, red, red)) {
1103
+ .\!border-amber-500\/50 {
1104
+ border-color: color-mix(in oklab, var(--color-amber-500) 50%, transparent) !important;
1105
+ }
1106
+ }
1107
+
1071
1108
  .border-amber-500\/20 {
1072
1109
  border-color: #f99c0033;
1073
1110
  }
@@ -1166,6 +1203,22 @@
1166
1203
  border-color: #0000;
1167
1204
  }
1168
1205
 
1206
+ .border-t-border {
1207
+ border-top-color: var(--border);
1208
+ }
1209
+
1210
+ .border-t-status-info {
1211
+ border-top-color: var(--status-info);
1212
+ }
1213
+
1214
+ .border-t-status-nominal {
1215
+ border-top-color: var(--status-nominal);
1216
+ }
1217
+
1218
+ .border-t-status-warning {
1219
+ border-top-color: var(--status-warning);
1220
+ }
1221
+
1169
1222
  .border-t-transparent {
1170
1223
  border-top-color: #0000;
1171
1224
  }
@@ -1178,6 +1231,16 @@
1178
1231
  border-left-color: #0000;
1179
1232
  }
1180
1233
 
1234
+ .\!bg-amber-500\/5 {
1235
+ background-color: #f99c000d !important;
1236
+ }
1237
+
1238
+ @supports (color: color-mix(in lab, red, red)) {
1239
+ .\!bg-amber-500\/5 {
1240
+ background-color: color-mix(in oklab, var(--color-amber-500) 5%, transparent) !important;
1241
+ }
1242
+ }
1243
+
1181
1244
  .bg-accent\/10 {
1182
1245
  background-color: var(--accent);
1183
1246
  }
@@ -1284,7 +1347,15 @@
1284
1347
  }
1285
1348
  }
1286
1349
 
1287
- .bg-muted, .bg-muted\/30 {
1350
+ .bg-muted {
1351
+ background-color: var(--muted);
1352
+ }
1353
+
1354
+ .bg-muted-foreground {
1355
+ background-color: var(--muted-foreground);
1356
+ }
1357
+
1358
+ .bg-muted\/30 {
1288
1359
  background-color: var(--muted);
1289
1360
  }
1290
1361
 
@@ -1921,6 +1992,10 @@
1921
1992
  opacity: 1;
1922
1993
  }
1923
1994
 
1995
+ .opacity-\[0\.03\] {
1996
+ opacity: .03;
1997
+ }
1998
+
1924
1999
  .shadow-lg {
1925
2000
  --tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, #0000001a), 0 4px 6px -4px var(--tw-shadow-color, #0000001a);
1926
2001
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -2024,6 +2099,10 @@
2024
2099
  }
2025
2100
 
2026
2101
  @media (hover: hover) {
2102
+ .hover\:border-border-emphasis:hover {
2103
+ border-color: var(--border-emphasis);
2104
+ }
2105
+
2027
2106
  .hover\:bg-accent\/50:hover {
2028
2107
  background-color: var(--accent);
2029
2108
  }
@@ -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" }],
@@ -16704,6 +16710,8 @@ const useAppStore = create$1((set, get) => ({
16704
16710
  rightPanelTab: "todos",
16705
16711
  settingsOpen: false,
16706
16712
  sidebarCollapsed: false,
16713
+ showKanbanView: false,
16714
+ showSubagentsInKanban: true,
16707
16715
  // Thread actions
16708
16716
  loadThreads: async () => {
16709
16717
  const threads = await window.api.threads.list();
@@ -16716,12 +16724,13 @@ const useAppStore = create$1((set, get) => ({
16716
16724
  const thread = await window.api.threads.create(metadata);
16717
16725
  set((state) => ({
16718
16726
  threads: [thread, ...state.threads],
16719
- currentThreadId: thread.thread_id
16727
+ currentThreadId: thread.thread_id,
16728
+ showKanbanView: false
16720
16729
  }));
16721
16730
  return thread;
16722
16731
  },
16723
16732
  selectThread: async (threadId) => {
16724
- set({ currentThreadId: threadId });
16733
+ set({ currentThreadId: threadId, showKanbanView: false });
16725
16734
  },
16726
16735
  deleteThread: async (threadId) => {
16727
16736
  console.log("[Store] Deleting thread:", threadId);
@@ -16796,6 +16805,17 @@ const useAppStore = create$1((set, get) => ({
16796
16805
  },
16797
16806
  setSidebarCollapsed: (collapsed) => {
16798
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 });
16799
16819
  }
16800
16820
  }));
16801
16821
  const CR = "\r".charCodeAt(0);
@@ -17944,6 +17964,13 @@ function convertToV1FromResponses(message) {
17944
17964
  };
17945
17965
  continue;
17946
17966
  } else if (_isContentBlock(toolOutput, "image_generation_call")) {
17967
+ if (_isString(toolOutput.result)) yield {
17968
+ type: "image",
17969
+ mimeType: "image/png",
17970
+ data: toolOutput.result,
17971
+ id: _isString(toolOutput.id) ? toolOutput.id : void 0,
17972
+ metadata: { status: _isString(toolOutput.status) ? toolOutput.status : void 0 }
17973
+ };
17947
17974
  yield {
17948
17975
  type: "non_standard",
17949
17976
  value: toolOutput
@@ -18187,8 +18214,8 @@ const DEFAULT_MERGE_IGNORE_KEYS = [
18187
18214
  ];
18188
18215
  function _mergeDicts(left, right, options) {
18189
18216
  const ignoreKeys = options?.ignoreKeys ?? DEFAULT_MERGE_IGNORE_KEYS;
18190
- if (left === void 0 && right === void 0) return void 0;
18191
- if (left === void 0 || right === void 0) return left ?? right;
18217
+ if (left == null && right == null) return void 0;
18218
+ if (left == null || right == null) return left ?? right;
18192
18219
  const merged = { ...left };
18193
18220
  for (const [key2, value] of Object.entries(right)) if (merged[key2] == null) merged[key2] = value;
18194
18221
  else if (value == null) continue;
@@ -18213,8 +18240,8 @@ function _mergeDicts(left, right, options) {
18213
18240
  return merged;
18214
18241
  }
18215
18242
  function _mergeLists(left, right, options) {
18216
- if (left === void 0 && right === void 0) return void 0;
18217
- else if (left === void 0 || right === void 0) return left || right;
18243
+ if (left == null && right == null) return void 0;
18244
+ else if (left == null || right == null) return left || right;
18218
18245
  else {
18219
18246
  const merged = [...left];
18220
18247
  for (const item of right) if (typeof item === "object" && item !== null && "index" in item && typeof item.index === "number") {
@@ -18233,8 +18260,8 @@ function _mergeLists(left, right, options) {
18233
18260
  }
18234
18261
  }
18235
18262
  function _mergeObj(left, right, options) {
18236
- if (left === void 0 && right === void 0) return void 0;
18237
- if (left === void 0 || right === void 0) return left ?? right;
18263
+ if (left == null && right == null) return void 0;
18264
+ if (left == null || right == null) return left ?? right;
18238
18265
  else if (typeof left !== typeof right) throw new Error(`Cannot merge objects of different types.
18239
18266
  Left ${typeof left}
18240
18267
  Right ${typeof right}`);
@@ -30324,7 +30351,7 @@ var CallbackManager = class CallbackManager2 extends BaseCallbackManager {
30324
30351
  callbackManager = callbackManager.copy(Array.isArray(localHandlers) ? localHandlers.map(ensureHandler) : localHandlers?.handlers, false);
30325
30352
  }
30326
30353
  const verboseEnabled = getEnvironmentVariable$2("LANGCHAIN_VERBOSE") === "true" || options?.verbose;
30327
- const tracingV2Enabled = LangChainTracer.getTraceableRunTree()?.tracingEnabled || isTracingEnabled();
30354
+ const tracingV2Enabled = LangChainTracer.getTraceableRunTree()?.tracingEnabled ?? isTracingEnabled();
30328
30355
  const tracingEnabled = tracingV2Enabled || (getEnvironmentVariable$2("LANGCHAIN_TRACING") ?? false);
30329
30356
  if (verboseEnabled || tracingEnabled) {
30330
30357
  if (!callbackManager) callbackManager = new CallbackManager2();
@@ -31899,7 +31926,9 @@ const defaultFailedAttemptHandler = (error) => {
31899
31926
  if (typeof error !== "object" || error === null) return;
31900
31927
  if ("message" in error && typeof error.message === "string" && (error.message.startsWith("Cancel") || error.message.startsWith("AbortError")) || "name" in error && typeof error.name === "string" && error.name === "AbortError") throw error;
31901
31928
  if ("code" in error && typeof error.code === "string" && error.code === "ECONNABORTED") throw error;
31902
- const status = "response" in error && typeof error.response === "object" && error.response !== null && "status" in error.response && typeof error.response.status === "number" ? error.response.status : void 0;
31929
+ const responseStatus = "response" in error && typeof error.response === "object" && error.response !== null && "status" in error.response && typeof error.response.status === "number" ? error.response.status : void 0;
31930
+ const directStatus = "status" in error && typeof error.status === "number" ? error.status : void 0;
31931
+ const status = responseStatus ?? directStatus;
31903
31932
  if (status && STATUS_NO_RETRY$1.includes(+status)) throw error;
31904
31933
  const code2 = "error" in error && typeof error.error === "object" && error.error !== null && "code" in error.error && typeof error.error.code === "string" ? error.error.code : void 0;
31905
31934
  if (code2 === "insufficient_quota") {
@@ -41300,14 +41329,15 @@ var StreamManager = class {
41300
41329
  };
41301
41330
  getMutateFn = (kind, historyValues) => {
41302
41331
  return (update) => {
41332
+ const stateValues = (this.state.values ?? [null, "stream"])[0];
41303
41333
  const prev = {
41304
41334
  ...historyValues,
41305
- ...(this.state.values ?? [null, "stream"])[0]
41335
+ ...stateValues ?? {}
41306
41336
  };
41307
41337
  const next = typeof update === "function" ? update(prev) : update;
41308
41338
  this.setStreamValues({
41309
41339
  ...prev,
41310
- ...next
41340
+ ...next ?? {}
41311
41341
  }, kind);
41312
41342
  };
41313
41343
  };
@@ -41344,8 +41374,8 @@ var StreamManager = class {
41344
41374
  if (this.matchEventType("checkpoints", event, data)) options.callbacks.onCheckpointEvent?.(data, { namespace });
41345
41375
  if (this.matchEventType("tasks", event, data)) options.callbacks.onTaskEvent?.(data, { namespace });
41346
41376
  if (this.matchEventType("debug", event, data)) options.callbacks.onDebugEvent?.(data, { namespace });
41347
- if (event === "values") if ("__interrupt__" in data) this.setStreamValues((prev) => ({
41348
- ...prev,
41377
+ if (event === "values") if (data != null && typeof data === "object" && "__interrupt__" in data) this.setStreamValues((prev) => ({
41378
+ ...prev ?? {},
41349
41379
  ...data
41350
41380
  }));
41351
41381
  else this.setStreamValues(data);
@@ -41359,7 +41389,7 @@ var StreamManager = class {
41359
41389
  this.setStreamValues((streamValues) => {
41360
41390
  const values$1 = {
41361
41391
  ...options.initialValues,
41362
- ...streamValues
41392
+ ...streamValues ?? {}
41363
41393
  };
41364
41394
  let messages = options.getMessages(values$1).slice();
41365
41395
  const { chunk, index: index2 } = this.messages.get(messageId, messages.length) ?? {};
@@ -42925,7 +42955,7 @@ var BaseClient = class {
42925
42955
  const [url, init] = this.prepareFetchOptions(path2, options);
42926
42956
  let finalInit = init;
42927
42957
  if (this.onRequest) finalInit = await this.onRequest(url, init);
42928
- const response = await this.asyncCaller.fetch(url, finalInit);
42958
+ const response = await this.asyncCaller.fetch(url.toString(), finalInit);
42929
42959
  const body2 = (() => {
42930
42960
  if (response.status === 202 || response.status === 204) return;
42931
42961
  return response.json();
@@ -42955,7 +42985,7 @@ var BaseClient = class {
42955
42985
  json: isReconnect ? void 0 : config2.json
42956
42986
  });
42957
42987
  if (this.onRequest != null) init = await this.onRequest(url, init);
42958
- const response = await this.asyncCaller.fetch(url, init);
42988
+ const response = await this.asyncCaller.fetch(url.toString(), init);
42959
42989
  if (!isReconnect && config2.onInitialResponse) await config2.onInitialResponse(response);
42960
42990
  return {
42961
42991
  response,
@@ -43922,7 +43952,7 @@ var UiClient = class UiClient2 extends BaseClient {
43922
43952
  json: { name: agentName }
43923
43953
  });
43924
43954
  if (this.onRequest != null) init = await this.onRequest(url, init);
43925
- return (await this.asyncCaller.fetch(url, init)).text();
43955
+ return (await this.asyncCaller.fetch(url.toString(), init)).text();
43926
43956
  });
43927
43957
  }
43928
43958
  };
@@ -43987,6 +44017,13 @@ function unique(array) {
43987
44017
  function findLast(array, predicate) {
43988
44018
  for (let i2 = array.length - 1; i2 >= 0; i2 -= 1) if (predicate(array[i2])) return array[i2];
43989
44019
  }
44020
+ async function* filterStream(stream, filter) {
44021
+ while (true) {
44022
+ const { value, done } = await stream.next();
44023
+ if (done) return value;
44024
+ if (filter(value)) yield value;
44025
+ }
44026
+ }
43990
44027
  function getBranchSequence(history) {
43991
44028
  const nodeIds = /* @__PURE__ */ new Set();
43992
44029
  const childrenMap = {};
@@ -44446,11 +44483,12 @@ function useStreamLGP(options) {
44446
44483
  };
44447
44484
  await stream.start(async (signal) => {
44448
44485
  threadIdStreamingRef.current = threadId;
44449
- return client2.runs.joinStream(threadId, runId, {
44486
+ const stream$1 = client2.runs.joinStream(threadId, runId, {
44450
44487
  signal,
44451
44488
  lastEventId,
44452
44489
  streamMode: joinOptions?.streamMode
44453
44490
  });
44491
+ return joinOptions?.filter != null ? filterStream(stream$1, joinOptions.filter) : stream$1;
44454
44492
  }, {
44455
44493
  getMessages,
44456
44494
  setMessages,
@@ -45162,7 +45200,8 @@ const createDefaultThreadState = () => ({
45162
45200
  openFiles: [],
45163
45201
  activeTab: "agent",
45164
45202
  fileContents: {},
45165
- tokenUsage: null
45203
+ tokenUsage: null,
45204
+ draftInput: ""
45166
45205
  });
45167
45206
  const defaultStreamData = {
45168
45207
  messages: [],
@@ -45227,6 +45266,7 @@ function ThreadStreamHolder({
45227
45266
  function ThreadProvider({ children }) {
45228
45267
  const [threadStates, setThreadStates] = reactExports.useState({});
45229
45268
  const [activeThreadIds, setActiveThreadIds] = reactExports.useState(/* @__PURE__ */ new Set());
45269
+ const [loadingStates, setLoadingStates] = reactExports.useState({});
45230
45270
  const initializedThreadsRef = reactExports.useRef(/* @__PURE__ */ new Set());
45231
45271
  const actionsCache = reactExports.useRef({});
45232
45272
  const streamDataRef = reactExports.useRef({});
@@ -45241,6 +45281,10 @@ function ThreadProvider({ children }) {
45241
45281
  (threadId, data) => {
45242
45282
  streamDataRef.current[threadId] = data;
45243
45283
  notifyStreamSubscribers(threadId);
45284
+ setLoadingStates((prev) => {
45285
+ if (prev[threadId] === data.isLoading) return prev;
45286
+ return { ...prev, [threadId]: data.isLoading };
45287
+ });
45244
45288
  },
45245
45289
  [notifyStreamSubscribers]
45246
45290
  );
@@ -45270,6 +45314,16 @@ function ThreadProvider({ children }) {
45270
45314
  },
45271
45315
  [threadStates]
45272
45316
  );
45317
+ const getAllThreadStates = reactExports.useCallback(() => {
45318
+ return threadStates;
45319
+ }, [threadStates]);
45320
+ const getAllStreamLoadingStates = reactExports.useCallback(() => {
45321
+ return loadingStates;
45322
+ }, [loadingStates]);
45323
+ const subscribeToAllStreams = reactExports.useCallback(() => {
45324
+ return () => {
45325
+ };
45326
+ }, []);
45273
45327
  const updateThreadState = reactExports.useCallback(
45274
45328
  (threadId, updater) => {
45275
45329
  setThreadStates((prev) => {
@@ -45469,6 +45523,9 @@ function ThreadProvider({ children }) {
45469
45523
  updateThreadState(threadId, (state) => ({
45470
45524
  fileContents: { ...state.fileContents, [path2]: content2 }
45471
45525
  }));
45526
+ },
45527
+ setDraftInput: (input) => {
45528
+ updateThreadState(threadId, () => ({ draftInput: input }));
45472
45529
  }
45473
45530
  };
45474
45531
  actionsCache.current[threadId] = actions;
@@ -45613,7 +45670,10 @@ function ThreadProvider({ children }) {
45613
45670
  initializeThread,
45614
45671
  cleanupThread,
45615
45672
  subscribeToStream,
45616
- getStreamData
45673
+ getStreamData,
45674
+ getAllThreadStates,
45675
+ getAllStreamLoadingStates,
45676
+ subscribeToAllStreams
45617
45677
  }),
45618
45678
  [
45619
45679
  getThreadState,
@@ -45621,7 +45681,10 @@ function ThreadProvider({ children }) {
45621
45681
  initializeThread,
45622
45682
  cleanupThread,
45623
45683
  subscribeToStream,
45624
- getStreamData
45684
+ getStreamData,
45685
+ getAllThreadStates,
45686
+ getAllStreamLoadingStates,
45687
+ subscribeToAllStreams
45625
45688
  ]
45626
45689
  );
45627
45690
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(ThreadContext.Provider, { value: contextValue, children: [
@@ -45671,6 +45734,14 @@ function useThreadState(threadId) {
45671
45734
  const actions = context.getThreadActions(threadId);
45672
45735
  return { ...state, ...actions };
45673
45736
  }
45737
+ function useAllThreadStates() {
45738
+ const context = useThreadContext();
45739
+ return context.getAllThreadStates();
45740
+ }
45741
+ function useAllStreamLoadingStates() {
45742
+ const context = useThreadContext();
45743
+ return context.getAllStreamLoadingStates();
45744
+ }
45674
45745
  // @__NO_SIDE_EFFECTS__
45675
45746
  function createSlot$3(ownerName) {
45676
45747
  const SlotClone = /* @__PURE__ */ createSlotClone$3(ownerName);
@@ -50772,7 +50843,15 @@ function ThreadListItem({
50772
50843
  ] });
50773
50844
  }
50774
50845
  function ThreadSidebar() {
50775
- const { threads, currentThreadId, createThread, selectThread, deleteThread, updateThread } = useAppStore();
50846
+ const {
50847
+ threads,
50848
+ currentThreadId,
50849
+ createThread,
50850
+ selectThread,
50851
+ deleteThread,
50852
+ updateThread,
50853
+ setShowKanbanView
50854
+ } = useAppStore();
50776
50855
  const [editingThreadId, setEditingThreadId] = reactExports.useState(null);
50777
50856
  const [editingTitle, setEditingTitle] = reactExports.useState("");
50778
50857
  const startEditing = (threadId, currentTitle) => {
@@ -50825,7 +50904,20 @@ function ThreadSidebar() {
50825
50904
  thread.thread_id
50826
50905
  )),
50827
50906
  threads.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-8 text-center text-sm text-muted-foreground", children: "No threads yet" })
50828
- ] }) })
50907
+ ] }) }),
50908
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 border-t border-border", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
50909
+ Button,
50910
+ {
50911
+ variant: "ghost",
50912
+ size: "sm",
50913
+ className: "w-full justify-start gap-2",
50914
+ onClick: () => setShowKanbanView(true),
50915
+ children: [
50916
+ /* @__PURE__ */ jsxRuntimeExports.jsx(LayoutGrid, { className: "size-4" }),
50917
+ "Overview"
50918
+ ]
50919
+ }
50920
+ ) })
50829
50921
  ] });
50830
50922
  }
50831
50923
  function TabBar({
@@ -75453,7 +75545,6 @@ function ContextUsageIndicator({
75453
75545
  ] });
75454
75546
  }
75455
75547
  function ChatContainer({ threadId }) {
75456
- const [input, setInput] = reactExports.useState("");
75457
75548
  const inputRef = reactExports.useRef(null);
75458
75549
  const scrollRef = reactExports.useRef(null);
75459
75550
  const isAtBottomRef = reactExports.useRef(true);
@@ -75466,13 +75557,15 @@ function ChatContainer({ threadId }) {
75466
75557
  workspacePath,
75467
75558
  tokenUsage,
75468
75559
  currentModel,
75560
+ draftInput: input,
75469
75561
  setTodos,
75470
75562
  setWorkspaceFiles,
75471
75563
  setWorkspacePath,
75472
75564
  setPendingApproval,
75473
75565
  appendMessage,
75474
75566
  setError,
75475
- clearError
75567
+ clearError,
75568
+ setDraftInput: setInput
75476
75569
  } = useCurrentThread(threadId);
75477
75570
  const streamData = useThreadStream(threadId);
75478
75571
  const stream = streamData.stream;
@@ -76454,6 +76547,297 @@ function formatSize(bytes) {
76454
76547
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;
76455
76548
  return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
76456
76549
  }
76550
+ const columnConfig = {
76551
+ pending: { badge: "outline", borderColor: "border-t-border" },
76552
+ in_progress: { badge: "info", borderColor: "border-t-status-info" },
76553
+ interrupted: { badge: "warning", borderColor: "border-t-status-warning" },
76554
+ done: { badge: "nominal", borderColor: "border-t-status-nominal" }
76555
+ };
76556
+ function KanbanColumn({
76557
+ title,
76558
+ status,
76559
+ count: count2,
76560
+ children
76561
+ }) {
76562
+ const config2 = columnConfig[status];
76563
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
76564
+ "div",
76565
+ {
76566
+ className: cn(
76567
+ "flex flex-col min-w-[200px] w-[200px] flex-1 bg-muted/30 rounded-sm border border-border border-t-2",
76568
+ config2.borderColor
76569
+ ),
76570
+ children: [
76571
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-b border-border", children: [
76572
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-section-header", children: title }),
76573
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: config2.badge, children: count2 })
76574
+ ] }),
76575
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ScrollArea, { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-2 space-y-2", children }) })
76576
+ ]
76577
+ }
76578
+ );
76579
+ }
76580
+ const Card = reactExports.forwardRef(
76581
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx(
76582
+ "div",
76583
+ {
76584
+ ref,
76585
+ className: cn("rounded-sm border border-border bg-card text-card-foreground", className),
76586
+ ...props
76587
+ }
76588
+ )
76589
+ );
76590
+ Card.displayName = "Card";
76591
+ const CardHeader = reactExports.forwardRef(
76592
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex flex-col space-y-1.5 p-4", className), ...props })
76593
+ );
76594
+ CardHeader.displayName = "CardHeader";
76595
+ const CardTitle = reactExports.forwardRef(
76596
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { ref, className: cn("text-section-header", className), ...props })
76597
+ );
76598
+ CardTitle.displayName = "CardTitle";
76599
+ const CardDescription = reactExports.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
76600
+ CardDescription.displayName = "CardDescription";
76601
+ const CardContent = reactExports.forwardRef(
76602
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("p-4 pt-0", className), ...props })
76603
+ );
76604
+ CardContent.displayName = "CardContent";
76605
+ const CardFooter = reactExports.forwardRef(
76606
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: cn("flex items-center p-4 pt-0", className), ...props })
76607
+ );
76608
+ CardFooter.displayName = "CardFooter";
76609
+ function ThreadStatusIcon({ threadId }) {
76610
+ const { isLoading } = useThreadStream(threadId);
76611
+ if (isLoading) {
76612
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(LoaderCircle, { className: "size-4 shrink-0 text-status-info animate-spin" });
76613
+ }
76614
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-muted-foreground" });
76615
+ }
76616
+ function ThreadKanbanCard({ thread, status, onClick }) {
76617
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
76618
+ Card,
76619
+ {
76620
+ className: cn(
76621
+ "cursor-pointer transition-all hover:border-border-emphasis hover:bg-background-interactive",
76622
+ status === "in_progress" && "border-status-info/50",
76623
+ status === "interrupted" && "!border-amber-500/50 !bg-amber-500/5"
76624
+ ),
76625
+ onClick,
76626
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-3", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2", children: [
76627
+ status === "interrupted" ? /* @__PURE__ */ jsxRuntimeExports.jsx(MessageSquare, { className: "size-4 shrink-0 text-amber-500" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadStatusIcon, { threadId: thread.thread_id }),
76628
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
76629
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
76630
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: thread.title || truncate(thread.thread_id, 20) }),
76631
+ status === "done" && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "nominal", className: "shrink-0 text-[9px]", children: "DONE" })
76632
+ ] }),
76633
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mt-1 text-[10px] text-muted-foreground", children: [
76634
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "size-3" }),
76635
+ formatRelativeTime(thread.updated_at)
76636
+ ] })
76637
+ ] })
76638
+ ] }) })
76639
+ }
76640
+ );
76641
+ }
76642
+ function SubagentKanbanCard({
76643
+ subagent,
76644
+ parentThread,
76645
+ onClick
76646
+ }) {
76647
+ const isDone = subagent.status === "completed" || subagent.status === "failed";
76648
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
76649
+ Card,
76650
+ {
76651
+ className: cn(
76652
+ "cursor-pointer transition-all hover:border-border-emphasis hover:bg-background-interactive border-dashed",
76653
+ subagent.status === "running" && "border-status-info/50"
76654
+ ),
76655
+ onClick,
76656
+ 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: [
76657
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76658
+ Bot,
76659
+ {
76660
+ className: cn(
76661
+ "size-4 shrink-0",
76662
+ subagent.status === "running" ? "text-status-info" : "text-muted-foreground"
76663
+ )
76664
+ }
76665
+ ),
76666
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0 overflow-hidden", children: [
76667
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
76668
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium truncate", children: subagent.name }),
76669
+ isDone && /* @__PURE__ */ jsxRuntimeExports.jsx(
76670
+ Badge,
76671
+ {
76672
+ variant: subagent.status === "failed" ? "critical" : "nominal",
76673
+ className: "shrink-0 text-[9px]",
76674
+ children: subagent.status === "failed" ? "FAILED" : "DONE"
76675
+ }
76676
+ )
76677
+ ] }),
76678
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-muted-foreground line-clamp-2 mt-0.5 break-words", children: subagent.description }),
76679
+ /* @__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: [
76680
+ "↳ ",
76681
+ parentThread.title || truncate(parentThread.thread_id, 15)
76682
+ ] }) })
76683
+ ] })
76684
+ ] }) })
76685
+ }
76686
+ );
76687
+ }
76688
+ function getThreadKanbanStatus(thread, isLoading, hasDraft, hasPendingApproval) {
76689
+ if (hasPendingApproval || thread.status === "interrupted") return "interrupted";
76690
+ if (thread.status === "busy" || isLoading) return "in_progress";
76691
+ if (hasDraft) return "pending";
76692
+ return "done";
76693
+ }
76694
+ function KanbanView() {
76695
+ const { threads, selectThread, showSubagentsInKanban } = useAppStore();
76696
+ const allThreadStates = useAllThreadStates();
76697
+ const loadingStates = useAllStreamLoadingStates();
76698
+ const handleCardClick = (threadId) => {
76699
+ selectThread(threadId);
76700
+ };
76701
+ const categorizedThreads = reactExports.useMemo(() => {
76702
+ const result = {
76703
+ pending: [],
76704
+ in_progress: [],
76705
+ interrupted: [],
76706
+ done: []
76707
+ };
76708
+ for (const thread of threads) {
76709
+ const isLoading = loadingStates[thread.thread_id] ?? false;
76710
+ const threadState = allThreadStates[thread.thread_id];
76711
+ const hasDraft = Boolean(threadState?.draftInput?.trim());
76712
+ const hasPendingApproval = Boolean(threadState?.pendingApproval);
76713
+ const status = getThreadKanbanStatus(thread, isLoading, hasDraft, hasPendingApproval);
76714
+ result[status].push({ thread, status });
76715
+ }
76716
+ return result;
76717
+ }, [threads, loadingStates, allThreadStates]);
76718
+ const categorizedSubagents = reactExports.useMemo(() => {
76719
+ if (!showSubagentsInKanban) {
76720
+ return { pending: [], in_progress: [], interrupted: [], done: [] };
76721
+ }
76722
+ const result = {
76723
+ pending: [],
76724
+ in_progress: [],
76725
+ interrupted: [],
76726
+ done: []
76727
+ };
76728
+ const threadMap = new Map(threads.map((t) => [t.thread_id, t]));
76729
+ for (const [threadId, state] of Object.entries(allThreadStates)) {
76730
+ const parentThread = threadMap.get(threadId);
76731
+ if (!parentThread || !state.subagents) continue;
76732
+ for (const subagent of state.subagents) {
76733
+ let status;
76734
+ switch (subagent.status) {
76735
+ case "pending":
76736
+ status = "pending";
76737
+ break;
76738
+ case "running":
76739
+ status = "in_progress";
76740
+ break;
76741
+ case "completed":
76742
+ status = "done";
76743
+ break;
76744
+ case "failed":
76745
+ status = "done";
76746
+ break;
76747
+ default:
76748
+ status = "pending";
76749
+ }
76750
+ result[status].push({ subagent, parentThread, status });
76751
+ }
76752
+ }
76753
+ return result;
76754
+ }, [threads, allThreadStates, showSubagentsInKanban]);
76755
+ const columnData = [
76756
+ { status: "pending", title: "PENDING" },
76757
+ { status: "in_progress", title: "IN PROGRESS" },
76758
+ { status: "interrupted", title: "BLOCKED" },
76759
+ { status: "done", title: "DONE" }
76760
+ ];
76761
+ 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 }) => {
76762
+ const threadItems = categorizedThreads[status];
76763
+ const subagentItems = categorizedSubagents[status];
76764
+ const totalCount = threadItems.length + subagentItems.length;
76765
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(KanbanColumn, { title, status, count: totalCount, children: [
76766
+ threadItems.map(({ thread, status: threadStatus }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
76767
+ ThreadKanbanCard,
76768
+ {
76769
+ thread,
76770
+ status: threadStatus,
76771
+ onClick: () => handleCardClick(thread.thread_id)
76772
+ },
76773
+ thread.thread_id
76774
+ )),
76775
+ subagentItems.map(({ subagent, parentThread }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
76776
+ SubagentKanbanCard,
76777
+ {
76778
+ subagent,
76779
+ parentThread,
76780
+ onClick: () => handleCardClick(parentThread.thread_id)
76781
+ },
76782
+ subagent.id
76783
+ )),
76784
+ totalCount === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center text-sm text-muted-foreground py-8", children: "No items" })
76785
+ ] }, status);
76786
+ }) }) }) });
76787
+ }
76788
+ function KanbanHeader({ className }) {
76789
+ const { showSubagentsInKanban, setShowSubagentsInKanban, threads } = useAppStore();
76790
+ const activeCount = threads.filter(
76791
+ (t) => t.status === "busy" || t.status === "interrupted"
76792
+ ).length;
76793
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs(
76794
+ "div",
76795
+ {
76796
+ className: cn(
76797
+ "flex items-center justify-between px-3 app-no-drag relative overflow-hidden",
76798
+ className
76799
+ ),
76800
+ children: [
76801
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 pointer-events-none opacity-[0.03]", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
76802
+ "div",
76803
+ {
76804
+ className: "absolute inset-0",
76805
+ style: {
76806
+ backgroundImage: "repeating-linear-gradient(0deg, transparent, transparent 2px, currentColor 2px, currentColor 3px)",
76807
+ backgroundSize: "100% 3px"
76808
+ }
76809
+ }
76810
+ ) }),
76811
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5 text-[10px] font-mono uppercase tracking-wider text-muted-foreground", children: [
76812
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
76813
+ "div",
76814
+ {
76815
+ className: cn(
76816
+ "size-1.5 rounded-full",
76817
+ activeCount > 0 ? "bg-status-nominal animate-tactical-pulse" : "bg-muted-foreground"
76818
+ )
76819
+ }
76820
+ ),
76821
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "tabular-nums", children: activeCount > 0 ? `${activeCount} ACTIVE` : "IDLE" })
76822
+ ] }),
76823
+ /* @__PURE__ */ jsxRuntimeExports.jsxs(
76824
+ Button,
76825
+ {
76826
+ variant: showSubagentsInKanban ? "secondary" : "ghost",
76827
+ size: "sm",
76828
+ onClick: () => setShowSubagentsInKanban(!showSubagentsInKanban),
76829
+ className: "gap-2 h-7 relative",
76830
+ children: [
76831
+ /* @__PURE__ */ jsxRuntimeExports.jsx(Bot, { className: "size-3.5" }),
76832
+ showSubagentsInKanban ? "Hide" : "Show",
76833
+ " Subagents"
76834
+ ]
76835
+ }
76836
+ )
76837
+ ]
76838
+ }
76839
+ );
76840
+ }
76457
76841
  const HANDLE_WIDTH = 6;
76458
76842
  function ResizeHandle({ onDrag }) {
76459
76843
  const startXRef = reactExports.useRef(0);
@@ -76495,7 +76879,7 @@ const RIGHT_MIN = 250;
76495
76879
  const RIGHT_MAX = 450;
76496
76880
  const RIGHT_DEFAULT = 320;
76497
76881
  function App() {
76498
- const { currentThreadId, loadThreads, createThread } = useAppStore();
76882
+ const { currentThreadId, loadThreads, createThread, showKanbanView } = useAppStore();
76499
76883
  const [isLoading, setIsLoading] = reactExports.useState(true);
76500
76884
  const [leftWidth, setLeftWidth] = reactExports.useState(LEFT_DEFAULT);
76501
76885
  const [rightWidth, setRightWidth] = reactExports.useState(RIGHT_DEFAULT);
@@ -76585,24 +76969,29 @@ function App() {
76585
76969
  },
76586
76970
  children: [
76587
76971
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-name", children: "OPENWORK" }),
76588
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.1.4" })
76972
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "app-badge-version", children: "0.2.0" })
76589
76973
  ]
76590
76974
  }
76591
76975
  ),
76592
76976
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col flex-1 min-w-0", children: [
76593
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-9 w-full shrink-0 app-drag-region bg-sidebar", children: [
76594
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0" }),
76977
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-9 w-full shrink-0 app-drag-region", children: [
76978
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0 bg-sidebar" }),
76595
76979
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-[1px] shrink-0" }),
76596
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0", children: currentThreadId && /* @__PURE__ */ jsxRuntimeExports.jsx(TabBar, { className: "h-full border-b-0" }) })
76980
+ /* @__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" }) })
76597
76981
  ] }),
76598
76982
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 overflow-hidden", children: [
76599
76983
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: leftWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ThreadSidebar, {}) }),
76600
76984
  /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleLeftResize }),
76601
- /* @__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" }) })
76985
+ showKanbanView ? (
76986
+ /* Kanban View - replaces center and right panels */
76987
+ /* @__PURE__ */ jsxRuntimeExports.jsx("main", { className: "flex flex-1 flex-col min-w-0 overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx(KanbanView, {}) })
76988
+ ) : /* @__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" }) }) })
76602
76989
  ] })
76603
76990
  ] }),
76604
- /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleRightResize }),
76605
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: rightWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RightPanel, {}) })
76991
+ !showKanbanView && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
76992
+ /* @__PURE__ */ jsxRuntimeExports.jsx(ResizeHandle, { onDrag: handleRightResize }),
76993
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { width: rightWidth }, className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(RightPanel, {}) })
76994
+ ] })
76606
76995
  ] }) });
76607
76996
  }
76608
76997
  ReactDOM$1.createRoot(document.getElementById("root")).render(
@@ -7,8 +7,8 @@
7
7
  http-equiv="Content-Security-Policy"
8
8
  content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:"
9
9
  />
10
- <script type="module" crossorigin src="./assets/index-u31WTlh3.js"></script>
11
- <link rel="stylesheet" crossorigin href="./assets/index-DaPTMBd5.css">
10
+ <script type="module" crossorigin src="./assets/index-D1IgUk4g.js"></script>
11
+ <link rel="stylesheet" crossorigin href="./assets/index-CeMSVFwO.css">
12
12
  </head>
13
13
  <body>
14
14
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openwork",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "A tactical agent interface for deepagentsjs",
5
5
  "main": "./out/main/index.js",
6
6
  "files": [
@@ -46,14 +46,13 @@
46
46
  "build": "npm run typecheck && electron-vite build"
47
47
  },
48
48
  "dependencies": {
49
- "electron": "^39.2.6",
50
- "@langchain/anthropic": "^1.3.10",
51
- "@langchain/core": "1.1.15",
49
+ "@langchain/anthropic": "^1.3.11",
50
+ "@langchain/core": "1.1.16",
51
+ "@langchain/google-genai": "^2.1.12",
52
52
  "@langchain/langgraph": "^1.0.15",
53
53
  "@langchain/langgraph-checkpoint": "^1.0.0",
54
54
  "@langchain/langgraph-sdk": "^1.5.3",
55
- "@langchain/openai": "^1.2.2",
56
- "@langchain/google-genai": "^2.1.10",
55
+ "@langchain/openai": "^1.2.3",
57
56
  "@radix-ui/react-context-menu": "^2.2.16",
58
57
  "@radix-ui/react-dialog": "^1.1.15",
59
58
  "@radix-ui/react-dropdown-menu": "^2.1.16",
@@ -69,8 +68,10 @@
69
68
  "@radix-ui/react-tooltip": "^1.2.8",
70
69
  "class-variance-authority": "^0.7.1",
71
70
  "clsx": "^2.1.1",
72
- "deepagents": "^1.5.0",
71
+ "deepagents": "^1.5.1",
72
+ "electron": "^39.2.6",
73
73
  "electron-store": "^8.2.0",
74
+ "langchain": "^1.2.12",
74
75
  "lucide-react": "^0.469.0",
75
76
  "react-markdown": "^10.1.0",
76
77
  "react-resizable-panels": "^4.4.0",