@sma1lboy/kobe 0.5.28 → 0.5.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli/index.js +1808 -686
  2. package/package.json +1 -1
package/dist/cli/index.js CHANGED
@@ -5346,7 +5346,7 @@ var init_keybindings = __esm(() => {
5346
5346
  keys: ["s"],
5347
5347
  category: "Sidebar",
5348
5348
  description: "Open settings",
5349
- hint: { keys: "s", label: "settings" }
5349
+ hint: { keys: "s", label: "settings", status: false }
5350
5350
  },
5351
5351
  {
5352
5352
  id: "app.quit",
@@ -5354,7 +5354,7 @@ var init_keybindings = __esm(() => {
5354
5354
  keys: ["q"],
5355
5355
  category: "Sidebar",
5356
5356
  description: "Quit (with confirm)",
5357
- hint: { keys: "q", label: "quit" }
5357
+ hint: { keys: "q", label: "quit", status: false }
5358
5358
  },
5359
5359
  {
5360
5360
  id: "focus.sidebar",
@@ -5370,7 +5370,7 @@ var init_keybindings = __esm(() => {
5370
5370
  keys: ["tab"],
5371
5371
  category: "Navigation",
5372
5372
  description: "Focus next pane (Wave 3)",
5373
- hint: { keys: "tab", label: "cycle", pin: "right" }
5373
+ hint: { keys: "tab", label: "cycle", pin: "right", status: false }
5374
5374
  },
5375
5375
  {
5376
5376
  id: "focus.prev",
@@ -5385,7 +5385,7 @@ var init_keybindings = __esm(() => {
5385
5385
  keys: ["ctrl+h", "ctrl+j", "ctrl+k", "ctrl+l"],
5386
5386
  category: "Navigation",
5387
5387
  description: "Jump to pane (h=sidebar, j=workspace, k=files, l=terminal)",
5388
- hint: { keys: "ctrl+hjkl", label: "focus", pin: "right" }
5388
+ hint: { keys: "ctrl+hjkl", label: "focus", pin: "right", status: false }
5389
5389
  },
5390
5390
  {
5391
5391
  id: "app.copy_or_quit",
@@ -5444,7 +5444,7 @@ var init_keybindings = __esm(() => {
5444
5444
  keys: ["r"],
5445
5445
  category: "Sidebar",
5446
5446
  description: "Rename task",
5447
- hint: { keys: "r", label: "rename" }
5447
+ hint: { keys: "r", label: "rename", status: false }
5448
5448
  },
5449
5449
  {
5450
5450
  id: "sidebar.archive",
@@ -5452,7 +5452,7 @@ var init_keybindings = __esm(() => {
5452
5452
  keys: ["a"],
5453
5453
  category: "Sidebar",
5454
5454
  description: "Toggle archive",
5455
- hint: { keys: "a", label: "archive" }
5455
+ hint: { keys: "a", label: "archive", status: false }
5456
5456
  },
5457
5457
  {
5458
5458
  id: "sidebar.localMerge",
@@ -5460,7 +5460,7 @@ var init_keybindings = __esm(() => {
5460
5460
  keys: ["m"],
5461
5461
  category: "Sidebar",
5462
5462
  description: "Local merge task into parent repo (Shift+M)",
5463
- hint: { keys: "M", label: "merge" }
5463
+ hint: { keys: "M", label: "merge", status: false }
5464
5464
  },
5465
5465
  {
5466
5466
  id: "sidebar.pin",
@@ -5468,7 +5468,7 @@ var init_keybindings = __esm(() => {
5468
5468
  keys: ["p"],
5469
5469
  category: "Sidebar",
5470
5470
  description: "Pin / unpin task at top (Shift+P)",
5471
- hint: { keys: "P", label: "pin" }
5471
+ hint: { keys: "P", label: "pin", status: false }
5472
5472
  },
5473
5473
  {
5474
5474
  id: "sidebar.view",
@@ -5476,7 +5476,7 @@ var init_keybindings = __esm(() => {
5476
5476
  keys: ["[", "]"],
5477
5477
  category: "Sidebar",
5478
5478
  description: "Switch view (Working session \u2194 Archives)",
5479
- hint: { keys: "[/]", label: "view" }
5479
+ hint: { keys: "[/]", label: "view", status: false }
5480
5480
  },
5481
5481
  {
5482
5482
  id: "sidebar.delete",
@@ -5484,7 +5484,7 @@ var init_keybindings = __esm(() => {
5484
5484
  keys: ["d"],
5485
5485
  category: "Sidebar",
5486
5486
  description: "Delete task (with confirm)",
5487
- hint: { keys: "d", label: "delete" }
5487
+ hint: { keys: "d", label: "delete", status: false }
5488
5488
  },
5489
5489
  {
5490
5490
  id: "sidebar.search.enter",
@@ -5545,7 +5545,7 @@ var init_keybindings = __esm(() => {
5545
5545
  keys: [],
5546
5546
  category: "Workspace",
5547
5547
  description: "Steer (interrupt + send) \u2014 mid-stream only",
5548
- hint: { keys: "ctrl+enter", label: "steer" }
5548
+ hint: { keys: "ctrl+enter", label: "steer", status: false }
5549
5549
  },
5550
5550
  {
5551
5551
  id: "chat.tab.new",
@@ -5569,7 +5569,7 @@ var init_keybindings = __esm(() => {
5569
5569
  keys: ["ctrl+y"],
5570
5570
  category: "Workspace",
5571
5571
  description: "Resume a prior session in this task's worktree",
5572
- hint: { keys: "ctrl+y", label: "resume" }
5572
+ hint: { keys: "ctrl+y", label: "resume", status: false }
5573
5573
  },
5574
5574
  {
5575
5575
  id: "chat.tab.close",
@@ -5577,7 +5577,7 @@ var init_keybindings = __esm(() => {
5577
5577
  keys: ["ctrl+w"],
5578
5578
  category: "Workspace",
5579
5579
  description: "Close chat tab",
5580
- hint: { keys: "ctrl+w", label: "close tab" }
5580
+ hint: { keys: "ctrl+w", label: "close tab", status: false }
5581
5581
  },
5582
5582
  {
5583
5583
  id: "chat.tab.rename",
@@ -5585,7 +5585,7 @@ var init_keybindings = __esm(() => {
5585
5585
  keys: ["f2"],
5586
5586
  category: "Workspace",
5587
5587
  description: "Rename active chat tab",
5588
- hint: { keys: "f2", label: "rename tab" }
5588
+ hint: { keys: "f2", label: "rename tab", status: false }
5589
5589
  },
5590
5590
  {
5591
5591
  id: "chat.tab.cycle-next",
@@ -5593,7 +5593,7 @@ var init_keybindings = __esm(() => {
5593
5593
  keys: ["ctrl+]"],
5594
5594
  category: "Workspace",
5595
5595
  description: "Next chat tab",
5596
- hint: { keys: "ctrl+]", label: "next tab" }
5596
+ hint: { keys: "ctrl+]", label: "next tab", status: false }
5597
5597
  },
5598
5598
  {
5599
5599
  id: "chat.tab.cycle-prev",
@@ -5601,7 +5601,7 @@ var init_keybindings = __esm(() => {
5601
5601
  keys: ["ctrl+["],
5602
5602
  category: "Workspace",
5603
5603
  description: "Previous chat tab",
5604
- hint: { keys: "ctrl+[", label: "prev tab" }
5604
+ hint: { keys: "ctrl+[", label: "prev tab", status: false }
5605
5605
  },
5606
5606
  {
5607
5607
  id: "chat.question.nav",
@@ -5609,7 +5609,7 @@ var init_keybindings = __esm(() => {
5609
5609
  keys: ["j", "k", "down", "up"],
5610
5610
  category: "Workspace",
5611
5611
  description: "Move highlight in question picker",
5612
- hint: { keys: "j/k", label: "pick" }
5612
+ hint: { keys: "j/k", label: "pick", status: false }
5613
5613
  },
5614
5614
  {
5615
5615
  id: "chat.question.toggle",
@@ -5617,7 +5617,7 @@ var init_keybindings = __esm(() => {
5617
5617
  keys: ["space"],
5618
5618
  category: "Workspace",
5619
5619
  description: "Toggle highlighted option in question picker",
5620
- hint: { keys: "space", label: "toggle" }
5620
+ hint: { keys: "space", label: "toggle", status: false }
5621
5621
  },
5622
5622
  {
5623
5623
  id: "chat.question.submit",
@@ -5625,7 +5625,7 @@ var init_keybindings = __esm(() => {
5625
5625
  keys: ["return"],
5626
5626
  category: "Workspace",
5627
5627
  description: "Advance / submit question picker",
5628
- hint: { keys: "enter", label: "submit" }
5628
+ hint: { keys: "enter", label: "submit", status: false }
5629
5629
  },
5630
5630
  {
5631
5631
  id: "chat.question.pick-number",
@@ -5633,7 +5633,7 @@ var init_keybindings = __esm(() => {
5633
5633
  keys: ["1", "2", "3", "4", "5", "6", "7", "8", "9"],
5634
5634
  category: "Workspace",
5635
5635
  description: "Pick option by number in question picker",
5636
- hint: { keys: "1-9", label: "pick" }
5636
+ hint: { keys: "1-9", label: "pick", status: false }
5637
5637
  },
5638
5638
  {
5639
5639
  id: "files.nav",
@@ -5665,7 +5665,7 @@ var init_keybindings = __esm(() => {
5665
5665
  keys: ["[", "]"],
5666
5666
  category: "Files",
5667
5667
  description: "Switch tab (cycle All / Changes)",
5668
- hint: { keys: "[/]", label: "tab" }
5668
+ hint: { keys: "[/]", label: "tab", status: false }
5669
5669
  },
5670
5670
  {
5671
5671
  id: "files.refresh",
@@ -5673,7 +5673,7 @@ var init_keybindings = __esm(() => {
5673
5673
  keys: ["r"],
5674
5674
  category: "Files",
5675
5675
  description: "Refresh",
5676
- hint: { keys: "r", label: "refresh" }
5676
+ hint: { keys: "r", label: "refresh", status: false }
5677
5677
  },
5678
5678
  {
5679
5679
  id: "files.openExternal",
@@ -5681,7 +5681,7 @@ var init_keybindings = __esm(() => {
5681
5681
  keys: ["o"],
5682
5682
  category: "Files",
5683
5683
  description: "Open file in system default app (audio / video / pdf preview)",
5684
- hint: { keys: "o", label: "open external" }
5684
+ hint: { keys: "o", label: "open external", status: false }
5685
5685
  },
5686
5686
  {
5687
5687
  id: "terminal.scroll-up",
@@ -5689,7 +5689,7 @@ var init_keybindings = __esm(() => {
5689
5689
  keys: ["ctrl+pageup"],
5690
5690
  category: "Terminal",
5691
5691
  description: "Scroll scrollback up",
5692
- hint: { keys: "ctrl+pgup", label: "scroll" }
5692
+ hint: { keys: "ctrl+pgup", label: "scroll", status: false }
5693
5693
  },
5694
5694
  {
5695
5695
  id: "terminal.scroll-down",
@@ -6148,10 +6148,9 @@ function FileTree(props) {
6148
6148
  }
6149
6149
  }));
6150
6150
  return (() => {
6151
- var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("box"), _el$4 = createElement("text"), _el$0 = createElement("scrollbox");
6151
+ var _el$ = createElement("box"), _el$2 = createElement("box"), _el$7 = createElement("scrollbox");
6152
6152
  insertNode(_el$, _el$2);
6153
- insertNode(_el$, _el$3);
6154
- insertNode(_el$, _el$0);
6153
+ insertNode(_el$, _el$7);
6155
6154
  setProp(_el$, "flexDirection", "column");
6156
6155
  setProp(_el$, "flexGrow", 1);
6157
6156
  setProp(_el$, "paddingTop", 1);
@@ -6167,132 +6166,126 @@ function FileTree(props) {
6167
6166
  children: (t) => {
6168
6167
  const isActive = () => tab() === t;
6169
6168
  return (() => {
6170
- var _el$19 = createElement("text");
6171
- setProp(_el$19, "wrapMode", "none");
6172
- setProp(_el$19, "onMouseUp", () => setTab(t));
6173
- insert(_el$19, () => TAB_LABEL[t]);
6169
+ var _el$16 = createElement("text");
6170
+ setProp(_el$16, "wrapMode", "none");
6171
+ setProp(_el$16, "onMouseUp", () => setTab(t));
6172
+ insert(_el$16, () => TAB_LABEL[t]);
6174
6173
  effect((_p$) => {
6175
6174
  var _v$3 = isActive() ? theme.primary : theme.textMuted, _v$4 = isActive() ? TextAttributes3.BOLD : undefined;
6176
- _v$3 !== _p$.e && (_p$.e = setProp(_el$19, "fg", _v$3, _p$.e));
6177
- _v$4 !== _p$.t && (_p$.t = setProp(_el$19, "attributes", _v$4, _p$.t));
6175
+ _v$3 !== _p$.e && (_p$.e = setProp(_el$16, "fg", _v$3, _p$.e));
6176
+ _v$4 !== _p$.t && (_p$.t = setProp(_el$16, "attributes", _v$4, _p$.t));
6178
6177
  return _p$;
6179
6178
  }, {
6180
6179
  e: undefined,
6181
6180
  t: undefined
6182
6181
  });
6183
- return _el$19;
6182
+ return _el$16;
6184
6183
  })();
6185
6184
  }
6186
6185
  }));
6187
- insertNode(_el$3, _el$4);
6188
- setProp(_el$3, "flexDirection", "row");
6189
- setProp(_el$3, "paddingBottom", 0);
6190
- setProp(_el$3, "flexShrink", 0);
6191
- insertNode(_el$4, createTextNode(`enter open \xB7 o open externally \xB7 r refresh`));
6192
- setProp(_el$4, "wrapMode", "none");
6193
6186
  insert(_el$, createComponent2(Show, {
6194
6187
  get when() {
6195
6188
  return tab() === "changes";
6196
6189
  },
6197
6190
  get children() {
6198
- var _el$6 = createElement("box"), _el$7 = createElement("text");
6199
- insertNode(_el$6, _el$7);
6200
- setProp(_el$6, "flexDirection", "row");
6201
- setProp(_el$6, "paddingBottom", 1);
6202
- setProp(_el$6, "flexShrink", 0);
6203
- insertNode(_el$7, createTextNode(`M modified \xB7 A added \xB7 D deleted \xB7 ? untracked`));
6204
- setProp(_el$7, "wrapMode", "none");
6205
- effect((_$p) => setProp(_el$7, "fg", theme.textMuted, _$p));
6206
- return _el$6;
6191
+ var _el$3 = createElement("box"), _el$4 = createElement("text");
6192
+ insertNode(_el$3, _el$4);
6193
+ setProp(_el$3, "flexDirection", "row");
6194
+ setProp(_el$3, "paddingBottom", 1);
6195
+ setProp(_el$3, "flexShrink", 0);
6196
+ insertNode(_el$4, createTextNode(`M modified \xB7 A added \xB7 D deleted \xB7 ? untracked`));
6197
+ setProp(_el$4, "wrapMode", "none");
6198
+ effect((_$p) => setProp(_el$4, "fg", theme.textMuted, _$p));
6199
+ return _el$3;
6207
6200
  }
6208
- }), _el$0);
6201
+ }), _el$7);
6209
6202
  insert(_el$, createComponent2(Show, {
6210
6203
  get when() {
6211
6204
  return tab() !== "changes";
6212
6205
  },
6213
6206
  get children() {
6214
- var _el$9 = createElement("box");
6215
- setProp(_el$9, "flexDirection", "row");
6216
- setProp(_el$9, "paddingBottom", 1);
6217
- setProp(_el$9, "flexShrink", 0);
6218
- return _el$9;
6207
+ var _el$6 = createElement("box");
6208
+ setProp(_el$6, "flexDirection", "row");
6209
+ setProp(_el$6, "paddingBottom", 1);
6210
+ setProp(_el$6, "flexShrink", 0);
6211
+ return _el$6;
6219
6212
  }
6220
- }), _el$0);
6213
+ }), _el$7);
6221
6214
  use((r) => {
6222
6215
  scrollRef = r;
6223
- }, _el$0);
6224
- setProp(_el$0, "flexGrow", 1);
6225
- setProp(_el$0, "verticalScrollbarOptions", {
6216
+ }, _el$7);
6217
+ setProp(_el$7, "flexGrow", 1);
6218
+ setProp(_el$7, "verticalScrollbarOptions", {
6226
6219
  trackOptions: {
6227
6220
  foregroundColor: "transparent"
6228
6221
  }
6229
6222
  });
6230
- insert(_el$0, createComponent2(Show, {
6223
+ insert(_el$7, createComponent2(Show, {
6231
6224
  get when() {
6232
6225
  return props.worktreePath() == null;
6233
6226
  },
6234
6227
  get children() {
6235
- var _el$1 = createElement("box"), _el$10 = createElement("text");
6236
- insertNode(_el$1, _el$10);
6237
- setProp(_el$1, "paddingTop", 1);
6238
- setProp(_el$1, "paddingLeft", 1);
6239
- insertNode(_el$10, createTextNode(`(no task \u2014 press n to create)`));
6240
- effect((_$p) => setProp(_el$10, "fg", theme.textMuted, _$p));
6241
- return _el$1;
6228
+ var _el$8 = createElement("box"), _el$9 = createElement("text");
6229
+ insertNode(_el$8, _el$9);
6230
+ setProp(_el$8, "paddingTop", 1);
6231
+ setProp(_el$8, "paddingLeft", 1);
6232
+ insertNode(_el$9, createTextNode(`(no task \u2014 press n to create)`));
6233
+ effect((_$p) => setProp(_el$9, "fg", theme.textMuted, _$p));
6234
+ return _el$8;
6242
6235
  }
6243
6236
  }), null);
6244
- insert(_el$0, createComponent2(Show, {
6237
+ insert(_el$7, createComponent2(Show, {
6245
6238
  get when() {
6246
6239
  return memo2(() => props.worktreePath() != null)() && error() != null;
6247
6240
  },
6248
6241
  get children() {
6249
- var _el$12 = createElement("box"), _el$13 = createElement("text"), _el$14 = createElement("text");
6250
- insertNode(_el$12, _el$13);
6251
- insertNode(_el$12, _el$14);
6252
- setProp(_el$12, "paddingTop", 1);
6253
- setProp(_el$12, "paddingLeft", 1);
6254
- setProp(_el$12, "flexDirection", "column");
6255
- setProp(_el$12, "gap", 0);
6256
- setProp(_el$13, "wrapMode", "word");
6257
- insert(_el$13, () => summarizeGitError(error() ?? ""));
6258
- insertNode(_el$14, createTextNode(`press r to retry`));
6259
- setProp(_el$14, "wrapMode", "word");
6242
+ var _el$1 = createElement("box"), _el$10 = createElement("text"), _el$11 = createElement("text");
6243
+ insertNode(_el$1, _el$10);
6244
+ insertNode(_el$1, _el$11);
6245
+ setProp(_el$1, "paddingTop", 1);
6246
+ setProp(_el$1, "paddingLeft", 1);
6247
+ setProp(_el$1, "flexDirection", "column");
6248
+ setProp(_el$1, "gap", 0);
6249
+ setProp(_el$10, "wrapMode", "word");
6250
+ insert(_el$10, () => summarizeGitError(error() ?? ""));
6251
+ insertNode(_el$11, createTextNode(`press r to retry`));
6252
+ setProp(_el$11, "wrapMode", "word");
6260
6253
  effect((_p$) => {
6261
6254
  var { error: _v$, textMuted: _v$2 } = theme;
6262
- _v$ !== _p$.e && (_p$.e = setProp(_el$13, "fg", _v$, _p$.e));
6263
- _v$2 !== _p$.t && (_p$.t = setProp(_el$14, "fg", _v$2, _p$.t));
6255
+ _v$ !== _p$.e && (_p$.e = setProp(_el$10, "fg", _v$, _p$.e));
6256
+ _v$2 !== _p$.t && (_p$.t = setProp(_el$11, "fg", _v$2, _p$.t));
6264
6257
  return _p$;
6265
6258
  }, {
6266
6259
  e: undefined,
6267
6260
  t: undefined
6268
6261
  });
6269
- return _el$12;
6262
+ return _el$1;
6270
6263
  }
6271
6264
  }), null);
6272
- insert(_el$0, createComponent2(Show, {
6265
+ insert(_el$7, createComponent2(Show, {
6273
6266
  get when() {
6274
6267
  return memo2(() => !!(props.worktreePath() != null && error() == null && rows().length === 0))() && (tab() === "all" && allFiles() != null || tab() === "changes" && changes() != null);
6275
6268
  },
6276
6269
  get children() {
6277
- var _el$16 = createElement("box"), _el$17 = createElement("text");
6278
- insertNode(_el$16, _el$17);
6279
- setProp(_el$16, "paddingTop", 1);
6280
- setProp(_el$16, "paddingLeft", 1);
6281
- insert(_el$17, () => tab() === "all" ? "(empty worktree)" : "(no changes \u2014 clean worktree)");
6282
- effect((_$p) => setProp(_el$17, "fg", theme.textMuted, _$p));
6283
- return _el$16;
6270
+ var _el$13 = createElement("box"), _el$14 = createElement("text");
6271
+ insertNode(_el$13, _el$14);
6272
+ setProp(_el$13, "paddingTop", 1);
6273
+ setProp(_el$13, "paddingLeft", 1);
6274
+ insert(_el$14, () => tab() === "all" ? "(empty worktree)" : "(no changes \u2014 clean worktree)");
6275
+ effect((_$p) => setProp(_el$14, "fg", theme.textMuted, _$p));
6276
+ return _el$13;
6284
6277
  }
6285
6278
  }), null);
6286
- insert(_el$0, createComponent2(Show, {
6279
+ insert(_el$7, createComponent2(Show, {
6287
6280
  get when() {
6288
6281
  return memo2(() => !!(props.worktreePath() != null && error() == null))() && rows().length > 0;
6289
6282
  },
6290
6283
  get children() {
6291
- var _el$18 = createElement("box");
6292
- setProp(_el$18, "flexShrink", 0);
6293
- setProp(_el$18, "gap", 0);
6294
- setProp(_el$18, "paddingRight", 1);
6295
- insert(_el$18, createComponent2(For, {
6284
+ var _el$15 = createElement("box");
6285
+ setProp(_el$15, "flexShrink", 0);
6286
+ setProp(_el$15, "gap", 0);
6287
+ setProp(_el$15, "paddingRight", 1);
6288
+ insert(_el$15, createComponent2(For, {
6296
6289
  get each() {
6297
6290
  return rows();
6298
6291
  },
@@ -6302,11 +6295,11 @@ function FileTree(props) {
6302
6295
  const indent = " ".repeat(row.depth);
6303
6296
  const marker = row.expanded ? "\u25BE" : "\u25B8";
6304
6297
  return (() => {
6305
- var _el$20 = createElement("box"), _el$21 = createElement("text");
6306
- insertNode(_el$20, _el$21);
6307
- setProp(_el$20, "paddingLeft", 1);
6308
- setProp(_el$20, "paddingRight", 1);
6309
- setProp(_el$20, "onMouseUp", () => {
6298
+ var _el$17 = createElement("box"), _el$18 = createElement("text");
6299
+ insertNode(_el$17, _el$18);
6300
+ setProp(_el$17, "paddingLeft", 1);
6301
+ setProp(_el$17, "paddingRight", 1);
6302
+ setProp(_el$17, "onMouseUp", () => {
6310
6303
  setCursorIndex(index());
6311
6304
  setExpandedDirs((prev) => {
6312
6305
  const next = new Set(prev);
@@ -6317,45 +6310,45 @@ function FileTree(props) {
6317
6310
  return next;
6318
6311
  });
6319
6312
  });
6320
- setProp(_el$21, "wrapMode", "none");
6321
- insert(_el$21, () => `${indent}${marker} ${row.name}/`);
6313
+ setProp(_el$18, "wrapMode", "none");
6314
+ insert(_el$18, () => `${indent}${marker} ${row.name}/`);
6322
6315
  effect((_p$) => {
6323
6316
  var _v$5 = isCursor() ? theme.primary : undefined, _v$6 = isCursor() ? theme.selectedListItemText : theme.textMuted, _v$7 = TextAttributes3.BOLD;
6324
- _v$5 !== _p$.e && (_p$.e = setProp(_el$20, "backgroundColor", _v$5, _p$.e));
6325
- _v$6 !== _p$.t && (_p$.t = setProp(_el$21, "fg", _v$6, _p$.t));
6326
- _v$7 !== _p$.a && (_p$.a = setProp(_el$21, "attributes", _v$7, _p$.a));
6317
+ _v$5 !== _p$.e && (_p$.e = setProp(_el$17, "backgroundColor", _v$5, _p$.e));
6318
+ _v$6 !== _p$.t && (_p$.t = setProp(_el$18, "fg", _v$6, _p$.t));
6319
+ _v$7 !== _p$.a && (_p$.a = setProp(_el$18, "attributes", _v$7, _p$.a));
6327
6320
  return _p$;
6328
6321
  }, {
6329
6322
  e: undefined,
6330
6323
  t: undefined,
6331
6324
  a: undefined
6332
6325
  });
6333
- return _el$20;
6326
+ return _el$17;
6334
6327
  })();
6335
6328
  }
6336
6329
  if (row.kind === "file") {
6337
6330
  const indent = " ".repeat(row.depth);
6338
6331
  return (() => {
6339
- var _el$22 = createElement("box"), _el$23 = createElement("text");
6340
- insertNode(_el$22, _el$23);
6341
- setProp(_el$22, "paddingLeft", 1);
6342
- setProp(_el$22, "paddingRight", 1);
6343
- setProp(_el$22, "onMouseUp", () => {
6332
+ var _el$19 = createElement("box"), _el$20 = createElement("text");
6333
+ insertNode(_el$19, _el$20);
6334
+ setProp(_el$19, "paddingLeft", 1);
6335
+ setProp(_el$19, "paddingRight", 1);
6336
+ setProp(_el$19, "onMouseUp", () => {
6344
6337
  setCursorIndex(index());
6345
6338
  props.onOpenFile(row.path);
6346
6339
  });
6347
- setProp(_el$23, "wrapMode", "none");
6348
- insert(_el$23, () => `${indent} ${row.name}`);
6340
+ setProp(_el$20, "wrapMode", "none");
6341
+ insert(_el$20, () => `${indent} ${row.name}`);
6349
6342
  effect((_p$) => {
6350
6343
  var _v$8 = isCursor() ? theme.primary : undefined, _v$9 = isCursor() ? theme.selectedListItemText : theme.text;
6351
- _v$8 !== _p$.e && (_p$.e = setProp(_el$22, "backgroundColor", _v$8, _p$.e));
6352
- _v$9 !== _p$.t && (_p$.t = setProp(_el$23, "fg", _v$9, _p$.t));
6344
+ _v$8 !== _p$.e && (_p$.e = setProp(_el$19, "backgroundColor", _v$8, _p$.e));
6345
+ _v$9 !== _p$.t && (_p$.t = setProp(_el$20, "fg", _v$9, _p$.t));
6353
6346
  return _p$;
6354
6347
  }, {
6355
6348
  e: undefined,
6356
6349
  t: undefined
6357
6350
  });
6358
- return _el$22;
6351
+ return _el$19;
6359
6352
  })();
6360
6353
  }
6361
6354
  const tone = statusToken(row.status);
@@ -6377,65 +6370,64 @@ function FileTree(props) {
6377
6370
  const addedText = row.added == null ? " ".repeat(w.added) : `+${row.added}`.padStart(w.added);
6378
6371
  const deletedText = row.deleted == null ? " ".repeat(w.deleted) : `-${row.deleted}`.padStart(w.deleted);
6379
6372
  return (() => {
6380
- var _el$24 = createElement("box"), _el$25 = createElement("text"), _el$26 = createElement("text");
6381
- insertNode(_el$24, _el$25);
6382
- insertNode(_el$24, _el$26);
6383
- setProp(_el$24, "flexDirection", "row");
6384
- setProp(_el$24, "gap", 1);
6385
- setProp(_el$24, "paddingLeft", 1);
6386
- setProp(_el$24, "paddingRight", 1);
6387
- setProp(_el$24, "onMouseUp", () => {
6373
+ var _el$21 = createElement("box"), _el$22 = createElement("text"), _el$23 = createElement("text");
6374
+ insertNode(_el$21, _el$22);
6375
+ insertNode(_el$21, _el$23);
6376
+ setProp(_el$21, "flexDirection", "row");
6377
+ setProp(_el$21, "gap", 1);
6378
+ setProp(_el$21, "paddingLeft", 1);
6379
+ setProp(_el$21, "paddingRight", 1);
6380
+ setProp(_el$21, "onMouseUp", () => {
6388
6381
  setCursorIndex(index());
6389
6382
  props.onOpenFile(row.path);
6390
6383
  });
6391
- setProp(_el$25, "wrapMode", "none");
6392
- insert(_el$25, () => row.status);
6393
- setProp(_el$26, "wrapMode", "none");
6394
- setProp(_el$26, "flexGrow", 1);
6395
- insert(_el$26, () => row.path);
6396
- insert(_el$24, createComponent2(Show, {
6384
+ setProp(_el$22, "wrapMode", "none");
6385
+ insert(_el$22, () => row.status);
6386
+ setProp(_el$23, "wrapMode", "none");
6387
+ setProp(_el$23, "flexGrow", 1);
6388
+ insert(_el$23, () => row.path);
6389
+ insert(_el$21, createComponent2(Show, {
6397
6390
  get when() {
6398
6391
  return w.added > 0;
6399
6392
  },
6400
6393
  get children() {
6401
- var _el$27 = createElement("text");
6402
- setProp(_el$27, "wrapMode", "none");
6403
- insert(_el$27, addedText);
6404
- effect((_$p) => setProp(_el$27, "fg", isCursor() ? theme.selectedListItemText : theme.success, _$p));
6405
- return _el$27;
6394
+ var _el$24 = createElement("text");
6395
+ setProp(_el$24, "wrapMode", "none");
6396
+ insert(_el$24, addedText);
6397
+ effect((_$p) => setProp(_el$24, "fg", isCursor() ? theme.selectedListItemText : theme.success, _$p));
6398
+ return _el$24;
6406
6399
  }
6407
6400
  }), null);
6408
- insert(_el$24, createComponent2(Show, {
6401
+ insert(_el$21, createComponent2(Show, {
6409
6402
  get when() {
6410
6403
  return w.deleted > 0;
6411
6404
  },
6412
6405
  get children() {
6413
- var _el$28 = createElement("text");
6414
- setProp(_el$28, "wrapMode", "none");
6415
- insert(_el$28, deletedText);
6416
- effect((_$p) => setProp(_el$28, "fg", isCursor() ? theme.selectedListItemText : theme.error, _$p));
6417
- return _el$28;
6406
+ var _el$25 = createElement("text");
6407
+ setProp(_el$25, "wrapMode", "none");
6408
+ insert(_el$25, deletedText);
6409
+ effect((_$p) => setProp(_el$25, "fg", isCursor() ? theme.selectedListItemText : theme.error, _$p));
6410
+ return _el$25;
6418
6411
  }
6419
6412
  }), null);
6420
6413
  effect((_p$) => {
6421
6414
  var _v$0 = isCursor() ? theme.primary : undefined, _v$1 = isCursor() ? theme.selectedListItemText : statusColor(), _v$10 = isCursor() ? theme.selectedListItemText : theme.text;
6422
- _v$0 !== _p$.e && (_p$.e = setProp(_el$24, "backgroundColor", _v$0, _p$.e));
6423
- _v$1 !== _p$.t && (_p$.t = setProp(_el$25, "fg", _v$1, _p$.t));
6424
- _v$10 !== _p$.a && (_p$.a = setProp(_el$26, "fg", _v$10, _p$.a));
6415
+ _v$0 !== _p$.e && (_p$.e = setProp(_el$21, "backgroundColor", _v$0, _p$.e));
6416
+ _v$1 !== _p$.t && (_p$.t = setProp(_el$22, "fg", _v$1, _p$.t));
6417
+ _v$10 !== _p$.a && (_p$.a = setProp(_el$23, "fg", _v$10, _p$.a));
6425
6418
  return _p$;
6426
6419
  }, {
6427
6420
  e: undefined,
6428
6421
  t: undefined,
6429
6422
  a: undefined
6430
6423
  });
6431
- return _el$24;
6424
+ return _el$21;
6432
6425
  })();
6433
6426
  }
6434
6427
  }));
6435
- return _el$18;
6428
+ return _el$15;
6436
6429
  }
6437
6430
  }), null);
6438
- effect((_$p) => setProp(_el$4, "fg", theme.textMuted, _$p));
6439
6431
  return _el$;
6440
6432
  })();
6441
6433
  }
@@ -16825,6 +16817,93 @@ var init_capabilities2 = __esm(() => {
16825
16817
  };
16826
16818
  });
16827
16819
 
16820
+ // src/engine/copilot-local/models.ts
16821
+ function normalizeCopilotCliModel(modelId) {
16822
+ const trimmed = modelId?.trim();
16823
+ if (!trimmed || trimmed === "auto")
16824
+ return;
16825
+ return COPILOT_SELECTABLE_MODEL_IDS.has(trimmed) ? trimmed : undefined;
16826
+ }
16827
+ function normalizeCopilotCliEffort(modelId, effort) {
16828
+ if (!effort)
16829
+ return;
16830
+ const model = normalizeCopilotCliModel(modelId);
16831
+ if (!model)
16832
+ return;
16833
+ return COPILOT_MODELS.some((m2) => m2.id === model && m2.effort === effort) ? effort : undefined;
16834
+ }
16835
+ function copilotContextWindowFor(_modelId) {
16836
+ return 0;
16837
+ }
16838
+ var COPILOT_MODELS, COPILOT_SELECTABLE_MODEL_IDS;
16839
+ var init_models3 = __esm(() => {
16840
+ COPILOT_MODELS = [
16841
+ {
16842
+ vendor: "copilot",
16843
+ id: "auto",
16844
+ label: "Copilot auto",
16845
+ hint: "let Copilot choose"
16846
+ },
16847
+ {
16848
+ vendor: "copilot",
16849
+ id: "gpt-5.5",
16850
+ label: "GPT-5.5",
16851
+ hint: "latest coding"
16852
+ },
16853
+ {
16854
+ vendor: "copilot",
16855
+ id: "gpt-5.2",
16856
+ label: "GPT-5.2",
16857
+ hint: "general coding"
16858
+ },
16859
+ {
16860
+ vendor: "copilot",
16861
+ id: "claude-opus-4.7",
16862
+ label: "Claude Opus 4.7",
16863
+ hint: "Copilot-hosted"
16864
+ },
16865
+ {
16866
+ vendor: "copilot",
16867
+ id: "claude-sonnet-4.5",
16868
+ label: "Claude Sonnet 4.5",
16869
+ hint: "Copilot-hosted"
16870
+ }
16871
+ ];
16872
+ COPILOT_SELECTABLE_MODEL_IDS = new Set(COPILOT_MODELS.map((m2) => m2.id));
16873
+ });
16874
+
16875
+ // src/engine/copilot-local/settings.ts
16876
+ function resolveCopilotDefaultModelId(env = process.env) {
16877
+ return COPILOT_FALLBACK_DEFAULT_MODEL_ID;
16878
+ }
16879
+ var COPILOT_FALLBACK_DEFAULT_MODEL_ID = "auto";
16880
+ var init_settings3 = () => {};
16881
+
16882
+ // src/engine/copilot-local/capabilities.ts
16883
+ var copilotCapabilities, copilotIdentity;
16884
+ var init_capabilities3 = __esm(() => {
16885
+ init_models3();
16886
+ init_settings3();
16887
+ copilotCapabilities = {
16888
+ vendorId: "copilot",
16889
+ label: "GitHub Copilot",
16890
+ models: COPILOT_MODELS,
16891
+ permissionModes: [
16892
+ { id: "default", label: "full access" },
16893
+ { id: "plan", label: "plan mode" }
16894
+ ],
16895
+ defaultModelId: resolveCopilotDefaultModelId,
16896
+ contextWindowFor: copilotContextWindowFor
16897
+ };
16898
+ copilotIdentity = {
16899
+ vendorId: "copilot",
16900
+ productName: "GitHub Copilot CLI",
16901
+ shortName: "Copilot",
16902
+ assistantName: "Copilot",
16903
+ inputPlaceholder: "Ask Copilot\u2026"
16904
+ };
16905
+ });
16906
+
16828
16907
  // src/engine/gemini-local/models.ts
16829
16908
  function geminiContextWindowFor(modelId) {
16830
16909
  if (modelId.includes("pro") || modelId.includes("flash")) {
@@ -16833,7 +16912,7 @@ function geminiContextWindowFor(modelId) {
16833
16912
  return 0;
16834
16913
  }
16835
16914
  var GEMINI_MODELS;
16836
- var init_models3 = __esm(() => {
16915
+ var init_models4 = __esm(() => {
16837
16916
  GEMINI_MODELS = [
16838
16917
  {
16839
16918
  vendor: "gemini",
@@ -16881,13 +16960,13 @@ function isObject(v2) {
16881
16960
  return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
16882
16961
  }
16883
16962
  var GEMINI_FALLBACK_DEFAULT_MODEL_ID = "gemini-3.1-pro-preview";
16884
- var init_settings3 = () => {};
16963
+ var init_settings4 = () => {};
16885
16964
 
16886
16965
  // src/engine/gemini-local/capabilities.ts
16887
16966
  var geminiCapabilities, geminiIdentity;
16888
- var init_capabilities3 = __esm(() => {
16889
- init_models3();
16890
- init_settings3();
16967
+ var init_capabilities4 = __esm(() => {
16968
+ init_models4();
16969
+ init_settings4();
16891
16970
  geminiCapabilities = {
16892
16971
  vendorId: "gemini",
16893
16972
  label: "Gemini CLI",
@@ -16961,15 +17040,18 @@ var init_registry2 = __esm(() => {
16961
17040
  init_capabilities();
16962
17041
  init_capabilities2();
16963
17042
  init_capabilities3();
17043
+ init_capabilities4();
16964
17044
  ENGINE_REGISTRY = {
16965
17045
  claude: claudeCapabilities,
16966
17046
  codex: codexCapabilities,
16967
- gemini: geminiCapabilities
17047
+ gemini: geminiCapabilities,
17048
+ copilot: copilotCapabilities
16968
17049
  };
16969
17050
  ENGINE_IDENTITIES = {
16970
17051
  claude: claudeIdentity,
16971
17052
  codex: codexIdentity,
16972
- gemini: geminiIdentity
17053
+ gemini: geminiIdentity,
17054
+ copilot: copilotIdentity
16973
17055
  };
16974
17056
  defaultCapabilities = claudeCapabilities;
16975
17057
  defaultIdentity = claudeIdentity;
@@ -17481,7 +17563,7 @@ var init_package = __esm(() => {
17481
17563
  package_default = {
17482
17564
  $schema: "https://json.schemastore.org/package.json",
17483
17565
  name: "@sma1lboy/kobe",
17484
- version: "0.5.28",
17566
+ version: "0.5.29",
17485
17567
  description: "TUI orchestrator for Claude Code (codename)",
17486
17568
  type: "module",
17487
17569
  packageManager: "bun@1.3.13",
@@ -21803,12 +21885,814 @@ var init_codex_local = __esm(() => {
21803
21885
  STDERR_TAIL_CAP = 4 * 1024;
21804
21886
  });
21805
21887
 
21806
- // src/engine/gemini-local/binary.ts
21888
+ // src/engine/copilot-local/binary.ts
21807
21889
  import { spawnSync as spawnSync6 } from "child_process";
21808
21890
  import { existsSync as existsSync8, statSync as statSync4 } from "fs";
21809
21891
  import { homedir as homedir16 } from "os";
21810
21892
  import path11 from "path";
21811
- async function findGeminiBinary(deps = defaultDeps6) {
21893
+ async function findCopilotBinary(deps = defaultDeps6) {
21894
+ const checked = [];
21895
+ const tryPath = (p2) => {
21896
+ if (!p2)
21897
+ return;
21898
+ checked.push(p2);
21899
+ return deps.fileExists(p2) ? p2 : undefined;
21900
+ };
21901
+ const whichResult = deps.which("copilot");
21902
+ if (whichResult) {
21903
+ checked.push(`which:${whichResult}`);
21904
+ if (deps.fileExists(whichResult))
21905
+ return whichResult;
21906
+ }
21907
+ const names = deps.platform() === "win32" ? ["copilot.exe", "copilot.cmd", "copilot"] : ["copilot"];
21908
+ const tryDir = (dir) => {
21909
+ if (!dir)
21910
+ return;
21911
+ for (const name of names) {
21912
+ const candidate = tryPath(path11.join(dir, name));
21913
+ if (candidate)
21914
+ return candidate;
21915
+ }
21916
+ return;
21917
+ };
21918
+ for (const dir of ["/opt/homebrew/bin", "/usr/local/bin", "/usr/bin", "/bin"]) {
21919
+ const candidate = tryDir(dir);
21920
+ if (candidate)
21921
+ return candidate;
21922
+ }
21923
+ const nvmBin = deps.env("NVM_BIN");
21924
+ const nvmCandidate = tryDir(nvmBin);
21925
+ if (nvmCandidate)
21926
+ return nvmCandidate;
21927
+ const home = deps.home();
21928
+ const homeDirs = [
21929
+ path11.join(home, ".npm-global/bin"),
21930
+ path11.join(home, ".local/bin"),
21931
+ path11.join(home, ".bun/bin"),
21932
+ path11.join(home, "bin")
21933
+ ];
21934
+ if (deps.platform() === "win32") {
21935
+ const appData = deps.env("APPDATA");
21936
+ const localAppData = deps.env("LOCALAPPDATA");
21937
+ homeDirs.unshift(path11.join(home, "AppData/Roaming/npm"));
21938
+ if (appData)
21939
+ homeDirs.unshift(path11.join(appData, "npm"));
21940
+ if (localAppData)
21941
+ homeDirs.unshift(path11.join(localAppData, "npm"));
21942
+ }
21943
+ for (const dir of homeDirs) {
21944
+ const candidate = tryDir(dir);
21945
+ if (candidate)
21946
+ return candidate;
21947
+ }
21948
+ throw new CopilotBinaryNotFoundError(checked);
21949
+ }
21950
+ var CopilotBinaryNotFoundError, defaultDeps6;
21951
+ var init_binary3 = __esm(() => {
21952
+ CopilotBinaryNotFoundError = class CopilotBinaryNotFoundError extends Error {
21953
+ checkedPaths;
21954
+ constructor(checkedPaths) {
21955
+ super(`GitHub Copilot CLI binary not found. Checked: ${checkedPaths.join(", ")}. Ensure 'copilot' is on PATH (for example \`npm install -g @github/copilot\` or \`brew install copilot-cli\`).`);
21956
+ this.name = "CopilotBinaryNotFoundError";
21957
+ this.checkedPaths = checkedPaths;
21958
+ }
21959
+ };
21960
+ defaultDeps6 = {
21961
+ fileExists(p2) {
21962
+ try {
21963
+ return statSync4(p2).isFile();
21964
+ } catch {
21965
+ return false;
21966
+ }
21967
+ },
21968
+ env(name) {
21969
+ return process.env[name];
21970
+ },
21971
+ home() {
21972
+ return homedir16();
21973
+ },
21974
+ which(name) {
21975
+ const cmd = process.platform === "win32" ? "where" : "which";
21976
+ const out = spawnSync6(cmd, [name], { encoding: "utf8" });
21977
+ if (out.status !== 0)
21978
+ return;
21979
+ const first = out.stdout.split(`
21980
+ `).map((l2) => l2.trim()).filter(Boolean)[0];
21981
+ if (!first)
21982
+ return;
21983
+ if (first.startsWith("copilot:") && first.includes("aliased to")) {
21984
+ const aliasTarget = first.split("aliased to")[1]?.trim();
21985
+ return aliasTarget && existsSync8(aliasTarget) ? aliasTarget : undefined;
21986
+ }
21987
+ return first;
21988
+ },
21989
+ platform() {
21990
+ return process.platform;
21991
+ }
21992
+ };
21993
+ });
21994
+
21995
+ // src/engine/copilot-local/stream.ts
21996
+ async function* parseCopilotJson(lines, opts = {}) {
21997
+ const completedMessages = new Set;
21998
+ const toolNameById = new Map;
21999
+ let sawAssistantDelta = false;
22000
+ for await (const rawLine of lines) {
22001
+ const line = rawLine.trim();
22002
+ if (!line)
22003
+ continue;
22004
+ let msg;
22005
+ try {
22006
+ msg = JSON.parse(line);
22007
+ } catch (err) {
22008
+ yield { type: "error", message: `copilot JSON parse failed: ${stringifyErr4(err)}` };
22009
+ continue;
22010
+ }
22011
+ if (!isObject10(msg) || typeof msg.type !== "string")
22012
+ continue;
22013
+ switch (msg.type) {
22014
+ case "session.start": {
22015
+ const data = objectData(msg);
22016
+ const sid = typeof data?.sessionId === "string" ? data.sessionId : undefined;
22017
+ if (sid)
22018
+ opts.onSessionId?.(sid);
22019
+ break;
22020
+ }
22021
+ case "assistant.message_delta": {
22022
+ const data = objectData(msg);
22023
+ const text = typeof data?.deltaContent === "string" ? data.deltaContent : "";
22024
+ if (text) {
22025
+ sawAssistantDelta = true;
22026
+ yield { type: "assistant.delta", text };
22027
+ }
22028
+ break;
22029
+ }
22030
+ case "assistant.message": {
22031
+ const data = objectData(msg);
22032
+ const messageId = typeof data?.messageId === "string" ? data.messageId : undefined;
22033
+ const content = typeof data?.content === "string" ? data.content : "";
22034
+ if (messageId) {
22035
+ if (completedMessages.has(messageId))
22036
+ break;
22037
+ completedMessages.add(messageId);
22038
+ }
22039
+ if (sawAssistantDelta)
22040
+ break;
22041
+ if (content)
22042
+ yield { type: "assistant.delta", text: content };
22043
+ break;
22044
+ }
22045
+ case "assistant.reasoning": {
22046
+ const data = objectData(msg);
22047
+ const text = typeof data?.content === "string" ? data.content : "";
22048
+ if (text)
22049
+ yield { type: "reasoning.delta", text };
22050
+ break;
22051
+ }
22052
+ case "tool.execution_start": {
22053
+ const data = objectData(msg);
22054
+ const id = typeof data?.toolCallId === "string" ? data.toolCallId : undefined;
22055
+ const name = typeof data?.toolName === "string" ? data.toolName : "tool";
22056
+ if (id)
22057
+ toolNameById.set(id, name);
22058
+ yield { type: "tool.start", name, input: data?.arguments ?? {}, ...id ? { id } : {} };
22059
+ break;
22060
+ }
22061
+ case "tool.execution_complete": {
22062
+ const data = objectData(msg);
22063
+ const id = typeof data?.toolCallId === "string" ? data.toolCallId : undefined;
22064
+ const name = (id ? toolNameById.get(id) : undefined) ?? (typeof data?.toolName === "string" ? data.toolName : "tool");
22065
+ const output = data?.result ?? (data?.success === false ? { success: false } : undefined);
22066
+ yield { type: "tool.result", name, output };
22067
+ break;
22068
+ }
22069
+ case "result": {
22070
+ const data = objectData(msg);
22071
+ const sid = typeof data?.sessionId === "string" ? data.sessionId : undefined;
22072
+ if (sid)
22073
+ opts.onSessionId?.(sid);
22074
+ const usage = copilotUsageToSnapshot(data?.usage);
22075
+ if (usage)
22076
+ yield { type: "usage", ...usage };
22077
+ const exitCode = data?.exitCode;
22078
+ if (typeof exitCode === "number" && exitCode !== 0) {
22079
+ yield { type: "error", message: `copilot exited with code ${exitCode}` };
22080
+ return;
22081
+ }
22082
+ yield { type: "done" };
22083
+ return;
22084
+ }
22085
+ case "error": {
22086
+ const data = objectData(msg);
22087
+ const message = typeof data?.message === "string" && data.message || typeof msg.message === "string" && msg.message || "copilot emitted an error";
22088
+ yield { type: "error", message };
22089
+ return;
22090
+ }
22091
+ }
22092
+ }
22093
+ }
22094
+ async function* readLines3(stream) {
22095
+ let buf = "";
22096
+ for await (const chunk of stream) {
22097
+ const text = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
22098
+ buf += text;
22099
+ let nl = buf.indexOf(`
22100
+ `);
22101
+ while (nl !== -1) {
22102
+ yield buf.slice(0, nl);
22103
+ buf = buf.slice(nl + 1);
22104
+ nl = buf.indexOf(`
22105
+ `);
22106
+ }
22107
+ }
22108
+ if (buf.length > 0)
22109
+ yield buf;
22110
+ }
22111
+ function copilotUsageToSnapshot(value) {
22112
+ if (!isObject10(value))
22113
+ return;
22114
+ const modelMetrics = isObject10(value.modelMetrics) ? value.modelMetrics : undefined;
22115
+ if (!modelMetrics)
22116
+ return;
22117
+ let input = 0;
22118
+ let output = 0;
22119
+ let cached3 = 0;
22120
+ for (const metrics of Object.values(modelMetrics)) {
22121
+ if (!isObject10(metrics) || !isObject10(metrics.usage))
22122
+ continue;
22123
+ input += numberOr3(metrics.usage.inputTokens, 0);
22124
+ output += numberOr3(metrics.usage.outputTokens, 0);
22125
+ cached3 += numberOr3(metrics.usage.cacheReadTokens, 0);
22126
+ }
22127
+ const context = numberOr3(value.currentTokens, 0);
22128
+ if (input === 0 && output === 0 && cached3 === 0 && context === 0)
22129
+ return;
22130
+ return {
22131
+ input_tokens: input,
22132
+ output_tokens: output,
22133
+ ...cached3 > 0 ? { cache_read_input_tokens: cached3 } : {},
22134
+ ...context > 0 ? { context_tokens: context } : {}
22135
+ };
22136
+ }
22137
+ function objectData(msg) {
22138
+ return isObject10(msg.data) ? msg.data : msg;
22139
+ }
22140
+ function isObject10(v2) {
22141
+ return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
22142
+ }
22143
+ function numberOr3(value, fallback) {
22144
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
22145
+ }
22146
+ function stringifyErr4(err) {
22147
+ if (err instanceof Error)
22148
+ return err.message;
22149
+ try {
22150
+ return JSON.stringify(err);
22151
+ } catch {
22152
+ return String(err);
22153
+ }
22154
+ }
22155
+
22156
+ // src/engine/copilot-local/history.ts
22157
+ import { readFile as readFile8, readdir as readdir6, rm as rm3, stat as stat8 } from "fs/promises";
22158
+ import { homedir as homedir17 } from "os";
22159
+ import path12 from "path";
22160
+ async function listSessionDirs(deps = defaultDeps7) {
22161
+ const root = path12.join(deps.copilotDir(), "session-state");
22162
+ const names = await deps.readdir(root);
22163
+ return names.map((name) => path12.join(root, name));
22164
+ }
22165
+ async function readHistoryWithMetrics2(sessionId, deps = defaultDeps7) {
22166
+ const dir = await findSessionDir(sessionId, deps);
22167
+ if (!dir)
22168
+ return { messages: [] };
22169
+ const raw = await deps.readFile(path12.join(dir, "events.jsonl")).catch(() => "");
22170
+ const parsed = parseEvents(raw, sessionId);
22171
+ return { messages: parsed.messages, ...parsed.usageMetrics ? { usageMetrics: parsed.usageMetrics } : {} };
22172
+ }
22173
+ async function deleteHistory3(sessionId, deps = defaultDeps7) {
22174
+ const dir = await findSessionDir(sessionId, deps);
22175
+ if (!dir)
22176
+ return;
22177
+ await deps.rm(dir);
22178
+ }
22179
+ async function findSessionDir(sessionId, deps = defaultDeps7) {
22180
+ for (const dir of await listSessionDirs(deps)) {
22181
+ if (path12.basename(dir) === sessionId)
22182
+ return dir;
22183
+ const workspace = await readWorkspace(dir, deps);
22184
+ if (workspace.id === sessionId || workspace.name?.toLowerCase() === sessionId.toLowerCase())
22185
+ return dir;
22186
+ }
22187
+ return;
22188
+ }
22189
+ async function readWorkspace(dir, deps = defaultDeps7) {
22190
+ const raw = await deps.readFile(path12.join(dir, "workspace.yaml")).catch(() => "");
22191
+ return parseWorkspaceYaml(raw);
22192
+ }
22193
+ function parseWorkspaceYaml(raw) {
22194
+ const out = {};
22195
+ for (const line of raw.split(`
22196
+ `)) {
22197
+ const match = line.match(/^([A-Za-z_]+):\s*(.*)$/);
22198
+ if (!match)
22199
+ continue;
22200
+ const key = match[1];
22201
+ let value = match[2] ?? "";
22202
+ if (value.startsWith('"') && value.endsWith('"'))
22203
+ value = value.slice(1, -1).replace(/\\"/g, '"');
22204
+ out[key] = value;
22205
+ }
22206
+ return {
22207
+ id: out.id,
22208
+ cwd: out.cwd,
22209
+ name: out.name,
22210
+ updatedAt: out.updated_at,
22211
+ createdAt: out.created_at
22212
+ };
22213
+ }
22214
+ function parseEvents(raw, fallbackSessionId) {
22215
+ const messages = [];
22216
+ const toolNameById = new Map;
22217
+ let sessionId = fallbackSessionId;
22218
+ let usageMetrics;
22219
+ let firstUserMessage = null;
22220
+ for (const line of raw.split(`
22221
+ `)) {
22222
+ const trimmed = line.trim();
22223
+ if (!trimmed)
22224
+ continue;
22225
+ let record;
22226
+ try {
22227
+ record = JSON.parse(trimmed);
22228
+ } catch {
22229
+ continue;
22230
+ }
22231
+ if (!isObject11(record) || typeof record.type !== "string")
22232
+ continue;
22233
+ const timestamp = typeof record.timestamp === "string" ? record.timestamp : new Date().toISOString();
22234
+ const data = isObject11(record.data) ? record.data : {};
22235
+ if (record.type === "session.start") {
22236
+ const sid = typeof data.sessionId === "string" ? data.sessionId : undefined;
22237
+ if (sid)
22238
+ sessionId = sid;
22239
+ continue;
22240
+ }
22241
+ if (record.type === "user.message") {
22242
+ const text = typeof data.content === "string" ? data.content : "";
22243
+ if (!text)
22244
+ continue;
22245
+ if (!firstUserMessage)
22246
+ firstUserMessage = text.slice(0, PREVIEW_CHAR_CAP2);
22247
+ messages.push({ role: "user", blocks: [{ type: "text", text }], timestamp, sessionId });
22248
+ continue;
22249
+ }
22250
+ if (record.type === "assistant.message") {
22251
+ const blocks = [];
22252
+ const text = typeof data.content === "string" ? data.content : "";
22253
+ if (text)
22254
+ blocks.push({ type: "text", text });
22255
+ const toolRequests = Array.isArray(data.toolRequests) ? data.toolRequests : [];
22256
+ for (const req of toolRequests) {
22257
+ if (!isObject11(req))
22258
+ continue;
22259
+ const callId = typeof req.id === "string" ? req.id : typeof req.toolCallId === "string" ? req.toolCallId : "tool";
22260
+ const name = typeof req.name === "string" ? req.name : typeof req.toolName === "string" ? req.toolName : "tool";
22261
+ blocks.push({ type: "tool_call", callId, name, input: req.arguments ?? {} });
22262
+ }
22263
+ if (blocks.length > 0)
22264
+ messages.push({ role: "assistant", blocks, timestamp, sessionId });
22265
+ continue;
22266
+ }
22267
+ if (record.type === "tool.execution_start") {
22268
+ const callId = typeof data.toolCallId === "string" ? data.toolCallId : undefined;
22269
+ const name = typeof data.toolName === "string" ? data.toolName : "tool";
22270
+ if (callId)
22271
+ toolNameById.set(callId, name);
22272
+ continue;
22273
+ }
22274
+ if (record.type === "tool.execution_complete") {
22275
+ const callId = typeof data.toolCallId === "string" ? data.toolCallId : undefined;
22276
+ if (!callId)
22277
+ continue;
22278
+ const name = toolNameById.get(callId) ?? (typeof data.toolName === "string" ? data.toolName : "tool");
22279
+ const output = data.result ?? (data.success === false ? { success: false } : undefined);
22280
+ messages.push({
22281
+ role: "assistant",
22282
+ blocks: [{ type: "tool_result", callId, output, isError: data.success === false }],
22283
+ timestamp,
22284
+ sessionId
22285
+ });
22286
+ continue;
22287
+ }
22288
+ if (record.type === "session.shutdown") {
22289
+ usageMetrics = copilotUsageToSnapshot(data);
22290
+ }
22291
+ }
22292
+ return { messages, usageMetrics, firstUserMessage };
22293
+ }
22294
+ function isObject11(v2) {
22295
+ return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
22296
+ }
22297
+ var defaultDeps7, PREVIEW_CHAR_CAP2 = 200;
22298
+ var init_history3 = __esm(() => {
22299
+ defaultDeps7 = {
22300
+ copilotDir() {
22301
+ const override = process.env.COPILOT_HOME?.trim();
22302
+ if (override)
22303
+ return override;
22304
+ return path12.join(homedir17(), ".copilot");
22305
+ },
22306
+ async readdir(p2) {
22307
+ try {
22308
+ return await readdir6(p2);
22309
+ } catch {
22310
+ return [];
22311
+ }
22312
+ },
22313
+ async readFile(p2) {
22314
+ return await readFile8(p2, "utf8");
22315
+ },
22316
+ stat: stat8,
22317
+ async rm(p2) {
22318
+ await rm3(p2, { recursive: true, force: true });
22319
+ }
22320
+ };
22321
+ });
22322
+
22323
+ // src/engine/copilot-local/sessions.ts
22324
+ import { homedir as homedir18 } from "os";
22325
+ import path13 from "path";
22326
+ async function listSessionsForCwd3(cwd, deps) {
22327
+ const actualDeps = deps ?? defaultDeps8;
22328
+ const normalized = path13.resolve(cwd);
22329
+ const out = [];
22330
+ for (const dir of await listSessionDirs(actualDeps)) {
22331
+ const workspace = await readWorkspace(dir, actualDeps);
22332
+ if (!workspace.id)
22333
+ continue;
22334
+ if (!workspace.cwd || !samePath(workspace.cwd, normalized))
22335
+ continue;
22336
+ const raw = await actualDeps.readFile(path13.join(dir, "events.jsonl")).catch(() => "");
22337
+ const parsed = parseEvents(raw, workspace.id);
22338
+ const st = await actualDeps.stat(path13.join(dir, "events.jsonl")).catch(() => null);
22339
+ out.push({
22340
+ sessionId: workspace.id,
22341
+ mtimeMs: st?.mtimeMs ?? Date.parse(workspace.updatedAt ?? workspace.createdAt ?? "0"),
22342
+ firstUserMessage: parsed.firstUserMessage ?? workspace.name ?? null,
22343
+ messageCount: parsed.messages.length
22344
+ });
22345
+ }
22346
+ out.sort((a2, b2) => b2.mtimeMs - a2.mtimeMs);
22347
+ return out;
22348
+ }
22349
+ function samePath(a2, b2) {
22350
+ const ar = path13.resolve(a2);
22351
+ const br = path13.resolve(b2);
22352
+ if (process.platform === "win32" || process.platform === "darwin")
22353
+ return ar.toLowerCase() === br.toLowerCase();
22354
+ return ar === br;
22355
+ }
22356
+ var defaultDeps8;
22357
+ var init_sessions3 = __esm(() => {
22358
+ init_history3();
22359
+ defaultDeps8 = {
22360
+ copilotDir() {
22361
+ const override = process.env.COPILOT_HOME?.trim();
22362
+ if (override)
22363
+ return override;
22364
+ return path13.join(homedir18(), ".copilot");
22365
+ },
22366
+ async readdir(p2) {
22367
+ const fs3 = await import("fs/promises");
22368
+ try {
22369
+ return await fs3.readdir(p2);
22370
+ } catch {
22371
+ return [];
22372
+ }
22373
+ },
22374
+ async readFile(p2) {
22375
+ const fs3 = await import("fs/promises");
22376
+ return await fs3.readFile(p2, "utf8");
22377
+ },
22378
+ async stat(p2) {
22379
+ const fs3 = await import("fs/promises");
22380
+ return await fs3.stat(p2);
22381
+ },
22382
+ async rm(p2) {
22383
+ const fs3 = await import("fs/promises");
22384
+ await fs3.rm(p2, { recursive: true, force: true });
22385
+ }
22386
+ };
22387
+ });
22388
+
22389
+ // src/engine/copilot-local/spawn.ts
22390
+ import { spawn as spawn12 } from "child_process";
22391
+ function spawnCopilotProcess(opts) {
22392
+ const args = buildArgs3(opts);
22393
+ const command = buildSpawnCommand(opts.binaryPath, args);
22394
+ const proc = spawn12(command.file, command.args, {
22395
+ cwd: opts.cwd,
22396
+ env: { ...process.env, ...opts.env ?? {} },
22397
+ stdio: ["pipe", "pipe", "pipe"],
22398
+ detached: true,
22399
+ ...command.options
22400
+ });
22401
+ try {
22402
+ proc.stdin.end();
22403
+ } catch {}
22404
+ return { proc, stdout: proc.stdout, stderr: proc.stderr, args };
22405
+ }
22406
+ function buildSpawnCommand(binaryPath, args, platform2 = process.platform) {
22407
+ if (platform2 === "win32" && /\.(?:cmd|bat)$/i.test(binaryPath)) {
22408
+ return {
22409
+ file: "cmd.exe",
22410
+ args: ["/d", "/s", "/c", [binaryPath, ...args].map(quoteForCmd).join(" ")]
22411
+ };
22412
+ }
22413
+ return { file: binaryPath, args };
22414
+ }
22415
+ function buildArgs3(opts) {
22416
+ const args = [
22417
+ "-C",
22418
+ opts.cwd,
22419
+ "--output-format",
22420
+ "json",
22421
+ "--stream",
22422
+ "on",
22423
+ "--no-color",
22424
+ "--no-remote",
22425
+ "--no-ask-user"
22426
+ ];
22427
+ if (opts.sessionId)
22428
+ args.push(sessionFlagFor(opts.sessionId));
22429
+ const model = normalizeCopilotCliModel(opts.model);
22430
+ if (model)
22431
+ args.push("--model", model);
22432
+ const effort = normalizeCopilotCliEffort(opts.model, opts.modelEffort);
22433
+ if (effort)
22434
+ args.push("--effort", effort);
22435
+ if (opts.permissionMode === "plan")
22436
+ args.push("--mode", "plan");
22437
+ else
22438
+ args.push("--allow-all");
22439
+ if (opts.extraArgs?.length)
22440
+ args.push(...opts.extraArgs);
22441
+ args.push("--prompt", opts.prompt);
22442
+ return args;
22443
+ }
22444
+ function quoteForCmd(value) {
22445
+ return `"${value.replace(/"/g, '""').replace(/%/g, "%%")}"`;
22446
+ }
22447
+ function sessionFlagFor(sessionId) {
22448
+ return isUuid(sessionId) ? `--session-id=${sessionId}` : `--resume=${sessionId}`;
22449
+ }
22450
+ function isUuid(value) {
22451
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
22452
+ }
22453
+ var init_spawn3 = __esm(() => {
22454
+ init_models3();
22455
+ });
22456
+
22457
+ // src/engine/copilot-local/index.ts
22458
+ import { randomUUID as randomUUID2 } from "crypto";
22459
+
22460
+ class CopilotLocal {
22461
+ identity = copilotIdentity;
22462
+ capabilities = copilotCapabilities;
22463
+ registry = new SessionRegistry;
22464
+ running = new Map;
22465
+ binaryPathResolver;
22466
+ stopGraceMs;
22467
+ constructor(opts = {}) {
22468
+ this.binaryPathResolver = opts.binaryPathResolver ?? findCopilotBinary;
22469
+ this.stopGraceMs = opts.stopGraceMs ?? 5000;
22470
+ }
22471
+ async spawn(cwd, prompt, opts) {
22472
+ return this.start({ cwd, prompt, opts });
22473
+ }
22474
+ async resume(sessionId, prompt, opts) {
22475
+ const cwd = opts?.cwd ?? opts?.env?.KOBE_RESUME_CWD ?? process.cwd();
22476
+ return this.start({ cwd, prompt, opts, resumeSessionId: sessionId });
22477
+ }
22478
+ stream(handle) {
22479
+ const sid = handle.sessionId;
22480
+ const self = this;
22481
+ return {
22482
+ async* [Symbol.asyncIterator]() {
22483
+ const session = self.running.get(sid);
22484
+ if (!session)
22485
+ return;
22486
+ let idx = 0;
22487
+ while (true) {
22488
+ if (idx < session.queue.length) {
22489
+ const ev = session.queue[idx++];
22490
+ yield ev;
22491
+ if (ev.type === "done" || ev.type === "error")
22492
+ return;
22493
+ continue;
22494
+ }
22495
+ if (session.closed)
22496
+ return;
22497
+ await new Promise((resolve3) => session.waiters.push(resolve3));
22498
+ }
22499
+ }
22500
+ };
22501
+ }
22502
+ async readHistory(sessionId) {
22503
+ return readHistoryWithMetrics2(sessionId);
22504
+ }
22505
+ async deleteHistory(sessionId) {
22506
+ return deleteHistory3(sessionId);
22507
+ }
22508
+ async listSessions(cwd) {
22509
+ return listSessionsForCwd3(cwd);
22510
+ }
22511
+ async listCommands(_opts) {
22512
+ return [];
22513
+ }
22514
+ async stop(handle) {
22515
+ const sid = handle.sessionId;
22516
+ await this.registry.kill(sid, this.stopGraceMs);
22517
+ const session = this.running.get(sid);
22518
+ if (session) {
22519
+ session.closed = true;
22520
+ this.notify(session);
22521
+ this.running.delete(sid);
22522
+ }
22523
+ }
22524
+ async start(args) {
22525
+ const binaryPath = await this.binaryPathResolver();
22526
+ const sessionId = args.resumeSessionId ?? randomUUID2();
22527
+ const spawned = spawnCopilotProcess({
22528
+ binaryPath,
22529
+ cwd: args.cwd,
22530
+ prompt: args.prompt,
22531
+ model: args.opts?.model,
22532
+ modelEffort: args.opts?.modelEffort,
22533
+ permissionMode: args.opts?.permissionMode,
22534
+ env: args.opts?.env,
22535
+ sessionId
22536
+ });
22537
+ let resolveHandle = () => {};
22538
+ let rejectHandle = () => {};
22539
+ const handlePromise = new Promise((res, rej) => {
22540
+ resolveHandle = res;
22541
+ rejectHandle = rej;
22542
+ });
22543
+ const queue = [];
22544
+ let session;
22545
+ let bound = false;
22546
+ let stderrTail = "";
22547
+ let terminalSeen = false;
22548
+ const failFromProcessError = (err) => {
22549
+ const ev = { type: "error", message: `copilot process error: ${err.message}` };
22550
+ terminalSeen = true;
22551
+ if (!bound) {
22552
+ rejectHandle(err);
22553
+ return;
22554
+ }
22555
+ queue.push(ev);
22556
+ if (!session)
22557
+ return;
22558
+ session.closed = true;
22559
+ this.notify(session);
22560
+ this.registry.unregister(session.sessionId, spawned.proc);
22561
+ if (this.running.get(session.sessionId) === session)
22562
+ this.running.delete(session.sessionId);
22563
+ };
22564
+ captureStderrTail2(spawned.stderr, (chunk) => {
22565
+ stderrTail = (stderrTail + chunk).slice(-STDERR_TAIL_CAP2);
22566
+ });
22567
+ spawned.proc.once("error", failFromProcessError);
22568
+ const bind = (sessionId2) => {
22569
+ if (bound)
22570
+ return;
22571
+ bound = true;
22572
+ session = {
22573
+ sessionId: sessionId2,
22574
+ cwd: args.cwd,
22575
+ spawned,
22576
+ queue,
22577
+ waiters: [],
22578
+ closed: false
22579
+ };
22580
+ this.running.set(sessionId2, session);
22581
+ this.registry.register({
22582
+ sessionId: sessionId2,
22583
+ cwd: args.cwd,
22584
+ proc: spawned.proc,
22585
+ startedAt: Date.now(),
22586
+ prompt: args.prompt
22587
+ });
22588
+ resolveHandle({ sessionId: sessionId2, cwd: args.cwd });
22589
+ };
22590
+ try {
22591
+ bind(sessionId);
22592
+ } catch (err) {
22593
+ try {
22594
+ spawned.proc.kill("SIGKILL");
22595
+ } catch {}
22596
+ rejectHandle(err);
22597
+ throw err;
22598
+ }
22599
+ const exitInfo = {
22600
+ code: null,
22601
+ signal: null,
22602
+ seen: false
22603
+ };
22604
+ const exitObserved = new Promise((resolve3) => {
22605
+ spawned.proc.once("exit", (code, signal) => {
22606
+ exitInfo.code = code;
22607
+ exitInfo.signal = signal;
22608
+ exitInfo.seen = true;
22609
+ if (!bound)
22610
+ rejectHandle(new Error(formatExitMsg2("copilot exited before session id was captured", code, signal, stderrTail)));
22611
+ resolve3();
22612
+ });
22613
+ });
22614
+ (async () => {
22615
+ try {
22616
+ for await (const ev of parseCopilotJson(readLines3(spawned.stdout), { onSessionId: bind })) {
22617
+ if (ev.type === "done" || ev.type === "error")
22618
+ terminalSeen = true;
22619
+ queue.push(ev);
22620
+ if (session)
22621
+ this.notify(session);
22622
+ if ((ev.type === "done" || ev.type === "error") && session) {
22623
+ this.registry.unregister(session.sessionId, spawned.proc);
22624
+ }
22625
+ }
22626
+ } catch (err) {
22627
+ queue.push({
22628
+ type: "error",
22629
+ message: `copilot parser failure: ${err instanceof Error ? err.message : String(err)}`
22630
+ });
22631
+ if (session)
22632
+ this.notify(session);
22633
+ } finally {
22634
+ await Promise.race([exitObserved, new Promise((r2) => setTimeout(r2, PROCESS_EXIT_GRACE_MS))]);
22635
+ if (session) {
22636
+ const lastEv = queue[queue.length - 1];
22637
+ if (exitInfo.seen && typeof exitInfo.code === "number" && exitInfo.code !== 0 && !terminalSeen && lastEv?.type !== "error") {
22638
+ queue.push({
22639
+ type: "error",
22640
+ message: formatExitMsg2("copilot exited", exitInfo.code, exitInfo.signal, stderrTail)
22641
+ });
22642
+ }
22643
+ session.closed = true;
22644
+ this.notify(session);
22645
+ this.registry.unregister(session.sessionId, spawned.proc);
22646
+ if (this.running.get(session.sessionId) === session)
22647
+ this.running.delete(session.sessionId);
22648
+ }
22649
+ if (!bound)
22650
+ rejectHandle(new Error("copilot exited without emitting a session id"));
22651
+ }
22652
+ })();
22653
+ return handlePromise;
22654
+ }
22655
+ notify(session) {
22656
+ const waiters = session.waiters;
22657
+ session.waiters = [];
22658
+ for (const w2 of waiters)
22659
+ w2();
22660
+ }
22661
+ }
22662
+ function captureStderrTail2(stream, onChunk) {
22663
+ const s2 = stream;
22664
+ s2.on("data", (chunk) => {
22665
+ onChunk(typeof chunk === "string" ? chunk : chunk.toString("utf8"));
22666
+ });
22667
+ s2.on("error", () => {});
22668
+ }
22669
+ function formatExitMsg2(prefix, code, signal, stderrTail) {
22670
+ const parts = [prefix];
22671
+ if (typeof code === "number")
22672
+ parts.push(`(code=${code}${signal ? `, signal=${signal}` : ""})`);
22673
+ else if (signal)
22674
+ parts.push(`(signal=${signal})`);
22675
+ const detail = stderrTail.trim().split(/\r?\n/).filter(Boolean).slice(-3).join(" | ");
22676
+ if (detail)
22677
+ parts.push(`: ${detail}`);
22678
+ return parts.join(" ").replace(/ : /, ": ");
22679
+ }
22680
+ var STDERR_TAIL_CAP2, PROCESS_EXIT_GRACE_MS = 500;
22681
+ var init_copilot_local = __esm(() => {
22682
+ init_binary3();
22683
+ init_capabilities3();
22684
+ init_history3();
22685
+ init_sessions3();
22686
+ init_spawn3();
22687
+ STDERR_TAIL_CAP2 = 4 * 1024;
22688
+ });
22689
+
22690
+ // src/engine/gemini-local/binary.ts
22691
+ import { spawnSync as spawnSync7 } from "child_process";
22692
+ import { existsSync as existsSync9, statSync as statSync5 } from "fs";
22693
+ import { homedir as homedir19 } from "os";
22694
+ import path14 from "path";
22695
+ async function findGeminiBinary(deps = defaultDeps9) {
21812
22696
  const checked = [];
21813
22697
  const tryPath = (p2) => {
21814
22698
  if (!p2)
@@ -21829,20 +22713,20 @@ async function findGeminiBinary(deps = defaultDeps6) {
21829
22713
  }
21830
22714
  const nvmBin = deps.env("NVM_BIN");
21831
22715
  if (nvmBin) {
21832
- const candidate = tryPath(path11.join(nvmBin, "gemini"));
22716
+ const candidate = tryPath(path14.join(nvmBin, "gemini"));
21833
22717
  if (candidate)
21834
22718
  return candidate;
21835
22719
  }
21836
22720
  const home = deps.home();
21837
22721
  for (const rel of [".local/bin/gemini", ".bun/bin/gemini", "bin/gemini"]) {
21838
- const candidate = tryPath(path11.join(home, rel));
22722
+ const candidate = tryPath(path14.join(home, rel));
21839
22723
  if (candidate)
21840
22724
  return candidate;
21841
22725
  }
21842
22726
  throw new GeminiBinaryNotFoundError(checked);
21843
22727
  }
21844
- var GeminiBinaryNotFoundError, defaultDeps6;
21845
- var init_binary3 = __esm(() => {
22728
+ var GeminiBinaryNotFoundError, defaultDeps9;
22729
+ var init_binary4 = __esm(() => {
21846
22730
  GeminiBinaryNotFoundError = class GeminiBinaryNotFoundError extends Error {
21847
22731
  checkedPaths;
21848
22732
  constructor(checkedPaths) {
@@ -21851,10 +22735,10 @@ var init_binary3 = __esm(() => {
21851
22735
  this.checkedPaths = checkedPaths;
21852
22736
  }
21853
22737
  };
21854
- defaultDeps6 = {
22738
+ defaultDeps9 = {
21855
22739
  fileExists(p2) {
21856
22740
  try {
21857
- return statSync4(p2).isFile();
22741
+ return statSync5(p2).isFile();
21858
22742
  } catch {
21859
22743
  return false;
21860
22744
  }
@@ -21863,11 +22747,11 @@ var init_binary3 = __esm(() => {
21863
22747
  return process.env[name];
21864
22748
  },
21865
22749
  home() {
21866
- return homedir16();
22750
+ return homedir19();
21867
22751
  },
21868
22752
  which(name) {
21869
22753
  const cmd = process.platform === "win32" ? "where" : "which";
21870
- const out = spawnSync6(cmd, [name], { encoding: "utf8" });
22754
+ const out = spawnSync7(cmd, [name], { encoding: "utf8" });
21871
22755
  if (out.status !== 0)
21872
22756
  return;
21873
22757
  const first = out.stdout.split(`
@@ -21876,7 +22760,7 @@ var init_binary3 = __esm(() => {
21876
22760
  return;
21877
22761
  if (first.startsWith("gemini:") && first.includes("aliased to")) {
21878
22762
  const aliasTarget = first.split("aliased to")[1]?.trim();
21879
- return aliasTarget && existsSync8(aliasTarget) ? aliasTarget : undefined;
22763
+ return aliasTarget && existsSync9(aliasTarget) ? aliasTarget : undefined;
21880
22764
  }
21881
22765
  return first;
21882
22766
  }
@@ -21884,23 +22768,23 @@ var init_binary3 = __esm(() => {
21884
22768
  });
21885
22769
 
21886
22770
  // src/engine/gemini-local/history.ts
21887
- import { readFile as readFile8, readdir as readdir6, unlink as unlink6 } from "fs/promises";
21888
- import { homedir as homedir17 } from "os";
21889
- import path12 from "path";
21890
- async function listChatFiles(deps = defaultDeps7) {
21891
- const roots = [path12.join(deps.geminiDir(), "tmp"), path12.join(deps.geminiDir(), "history")];
22771
+ import { readFile as readFile9, readdir as readdir7, unlink as unlink6 } from "fs/promises";
22772
+ import { homedir as homedir20 } from "os";
22773
+ import path15 from "path";
22774
+ async function listChatFiles(deps = defaultDeps10) {
22775
+ const roots = [path15.join(deps.geminiDir(), "tmp"), path15.join(deps.geminiDir(), "history")];
21892
22776
  const out = [];
21893
22777
  for (const root of roots) {
21894
22778
  for (const projectId of await deps.readdir(root)) {
21895
- const chatsDir = path12.join(root, projectId, "chats");
22779
+ const chatsDir = path15.join(root, projectId, "chats");
21896
22780
  const files = (await deps.readdir(chatsDir)).filter((f2) => f2.startsWith("session-") && (f2.endsWith(".jsonl") || f2.endsWith(".json")));
21897
22781
  for (const f2 of files)
21898
- out.push(path12.join(chatsDir, f2));
22782
+ out.push(path15.join(chatsDir, f2));
21899
22783
  }
21900
22784
  }
21901
22785
  return out;
21902
22786
  }
21903
- async function readHistoryWithMetrics2(sessionId, deps = defaultDeps7) {
22787
+ async function readHistoryWithMetrics3(sessionId, deps = defaultDeps10) {
21904
22788
  const file = await findChatFile(sessionId, deps);
21905
22789
  if (!file)
21906
22790
  return { messages: [] };
@@ -21917,10 +22801,10 @@ async function readHistoryWithMetrics2(sessionId, deps = defaultDeps7) {
21917
22801
  const usageMetrics = deriveUsage(messages);
21918
22802
  return { messages, ...usageMetrics ? { usageMetrics } : {} };
21919
22803
  }
21920
- async function deleteHistory3(sessionId, deps = defaultDeps7) {
22804
+ async function deleteHistory4(sessionId, deps = defaultDeps10) {
21921
22805
  const short = sessionId.slice(0, 8);
21922
22806
  for (const file of await listChatFiles(deps)) {
21923
- if (!path12.basename(file).includes(short))
22807
+ if (!path15.basename(file).includes(short))
21924
22808
  continue;
21925
22809
  const raw = await deps.readFile(file).catch(() => "");
21926
22810
  const conversation = parseConversation(raw);
@@ -21935,7 +22819,7 @@ async function deleteHistory3(sessionId, deps = defaultDeps7) {
21935
22819
  async function findChatFile(sessionId, deps) {
21936
22820
  const short = sessionId.slice(0, 8);
21937
22821
  for (const file of await listChatFiles(deps)) {
21938
- if (!path12.basename(file).includes(short))
22822
+ if (!path15.basename(file).includes(short))
21939
22823
  continue;
21940
22824
  const raw = await deps.readFile(file).catch(() => "");
21941
22825
  const conversation = parseConversation(raw, { metadataOnly: true });
@@ -21969,7 +22853,7 @@ function parseConversation(raw, opts = {}) {
21969
22853
  } catch {
21970
22854
  continue;
21971
22855
  }
21972
- if (!isObject10(record))
22856
+ if (!isObject12(record))
21973
22857
  continue;
21974
22858
  if (typeof record.$rewindTo === "string") {
21975
22859
  const idx = messageOrder.indexOf(record.$rewindTo);
@@ -21978,7 +22862,7 @@ function parseConversation(raw, opts = {}) {
21978
22862
  messagesById.delete(id);
21979
22863
  continue;
21980
22864
  }
21981
- if (isObject10(record.$set)) {
22865
+ if (isObject12(record.$set)) {
21982
22866
  metadata = { ...metadata, ...record.$set };
21983
22867
  continue;
21984
22868
  }
@@ -22011,7 +22895,7 @@ function parseConversation(raw, opts = {}) {
22011
22895
  };
22012
22896
  }
22013
22897
  function normalizeLegacyConversation(v2) {
22014
- if (!isObject10(v2) || typeof v2.sessionId !== "string")
22898
+ if (!isObject12(v2) || typeof v2.sessionId !== "string")
22015
22899
  return null;
22016
22900
  return {
22017
22901
  sessionId: v2.sessionId,
@@ -22044,7 +22928,7 @@ function normalizeGeminiMessage(msg, sessionId) {
22044
22928
  if (text)
22045
22929
  blocks.push({ type: "text", text });
22046
22930
  for (const tool of msg.toolCalls ?? []) {
22047
- if (!isObject10(tool))
22931
+ if (!isObject12(tool))
22048
22932
  continue;
22049
22933
  const callId = typeof tool.id === "string" ? tool.id : typeof tool.callId === "string" ? tool.callId : "gemini-tool";
22050
22934
  const name = typeof tool.name === "string" ? tool.name : typeof tool.displayName === "string" ? tool.displayName : "tool";
@@ -22064,12 +22948,12 @@ function normalizeGeminiMessage(msg, sessionId) {
22064
22948
  return out;
22065
22949
  }
22066
22950
  function usageFromTokens(tokens) {
22067
- if (!isObject10(tokens))
22951
+ if (!isObject12(tokens))
22068
22952
  return;
22069
22953
  return {
22070
- input_tokens: numberOr3(tokens.input, 0),
22071
- output_tokens: numberOr3(tokens.output, 0),
22072
- cache_read_input_tokens: numberOr3(tokens.cached, 0)
22954
+ input_tokens: numberOr4(tokens.input, 0),
22955
+ output_tokens: numberOr4(tokens.output, 0),
22956
+ cache_read_input_tokens: numberOr4(tokens.cached, 0)
22073
22957
  };
22074
22958
  }
22075
22959
  function deriveUsage(messages) {
@@ -22096,14 +22980,14 @@ function textFromParts(value) {
22096
22980
  for (const part of value) {
22097
22981
  if (typeof part === "string") {
22098
22982
  parts.push(part);
22099
- } else if (isObject10(part) && typeof part.text === "string") {
22983
+ } else if (isObject12(part) && typeof part.text === "string") {
22100
22984
  parts.push(part.text);
22101
22985
  }
22102
22986
  }
22103
22987
  return parts.join("");
22104
22988
  }
22105
22989
  function thoughtText(value) {
22106
- if (!isObject10(value))
22990
+ if (!isObject12(value))
22107
22991
  return "";
22108
22992
  const subject = typeof value.subject === "string" ? value.subject : "";
22109
22993
  const description = typeof value.description === "string" ? value.description : "";
@@ -22113,55 +22997,55 @@ function thoughtText(value) {
22113
22997
  function stringOrUndefined(v2) {
22114
22998
  return typeof v2 === "string" ? v2 : undefined;
22115
22999
  }
22116
- function numberOr3(v2, fallback) {
23000
+ function numberOr4(v2, fallback) {
22117
23001
  return typeof v2 === "number" && Number.isFinite(v2) ? v2 : fallback;
22118
23002
  }
22119
- function isObject10(v2) {
23003
+ function isObject12(v2) {
22120
23004
  return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
22121
23005
  }
22122
- var defaultDeps7;
22123
- var init_history3 = __esm(() => {
22124
- defaultDeps7 = {
23006
+ var defaultDeps10;
23007
+ var init_history4 = __esm(() => {
23008
+ defaultDeps10 = {
22125
23009
  geminiDir() {
22126
- return path12.join(homedir17(), ".gemini");
23010
+ return path15.join(homedir20(), ".gemini");
22127
23011
  },
22128
23012
  async readdir(p2) {
22129
23013
  try {
22130
- return await readdir6(p2);
23014
+ return await readdir7(p2);
22131
23015
  } catch {
22132
23016
  return [];
22133
23017
  }
22134
23018
  },
22135
23019
  async readFile(p2) {
22136
- return await readFile8(p2, "utf8");
23020
+ return await readFile9(p2, "utf8");
22137
23021
  },
22138
23022
  unlink: unlink6
22139
23023
  };
22140
23024
  });
22141
23025
 
22142
23026
  // src/engine/gemini-local/sessions.ts
22143
- import { readFile as readFile9, readdir as readdir7, stat as stat8 } from "fs/promises";
22144
- import { homedir as homedir18 } from "os";
22145
- import path13 from "path";
22146
- async function listSessionsForCwd3(cwd, deps) {
22147
- const actualDeps = deps ?? defaultDeps8;
23027
+ import { readFile as readFile10, readdir as readdir8, stat as stat9 } from "fs/promises";
23028
+ import { homedir as homedir21 } from "os";
23029
+ import path16 from "path";
23030
+ async function listSessionsForCwd4(cwd, deps) {
23031
+ const actualDeps = deps ?? defaultDeps11;
22148
23032
  const projectIds = await projectIdentifiersForCwd(cwd, actualDeps);
22149
23033
  if (projectIds.size === 0)
22150
23034
  return [];
22151
23035
  const bySessionId = new Map;
22152
23036
  for (const file of await listChatFiles(actualDeps)) {
22153
- const projectId = path13.basename(path13.dirname(path13.dirname(file)));
23037
+ const projectId = path16.basename(path16.dirname(path16.dirname(file)));
22154
23038
  if (!projectIds.has(projectId))
22155
23039
  continue;
22156
23040
  const raw = await actualDeps.readFile(file).catch(() => "");
22157
23041
  const conversation = parseConversation(raw);
22158
23042
  if (!conversation || conversation.kind === "subagent")
22159
23043
  continue;
22160
- const st = await stat8(file).catch(() => null);
23044
+ const st = await stat9(file).catch(() => null);
22161
23045
  const next = {
22162
23046
  sessionId: conversation.sessionId,
22163
23047
  mtimeMs: st?.mtimeMs ?? Date.parse(conversation.lastUpdated),
22164
- firstUserMessage: (conversation.firstUserMessage ?? null)?.slice(0, PREVIEW_CHAR_CAP2) ?? null,
23048
+ firstUserMessage: (conversation.firstUserMessage ?? null)?.slice(0, PREVIEW_CHAR_CAP3) ?? null,
22165
23049
  messageCount: conversation.messages.length
22166
23050
  };
22167
23051
  const prev = bySessionId.get(next.sessionId);
@@ -22173,65 +23057,65 @@ async function listSessionsForCwd3(cwd, deps) {
22173
23057
  return out;
22174
23058
  }
22175
23059
  async function projectIdentifiersForCwd(cwd, deps) {
22176
- const normalized = path13.resolve(cwd);
23060
+ const normalized = path16.resolve(cwd);
22177
23061
  const ids = new Set;
22178
- const projectsRaw = await deps.readFile(path13.join(deps.geminiDir(), "projects.json")).catch(() => "");
23062
+ const projectsRaw = await deps.readFile(path16.join(deps.geminiDir(), "projects.json")).catch(() => "");
22179
23063
  if (projectsRaw) {
22180
23064
  try {
22181
23065
  const parsed = JSON.parse(projectsRaw);
22182
- if (isObject11(parsed) && isObject11(parsed.projects)) {
23066
+ if (isObject13(parsed) && isObject13(parsed.projects)) {
22183
23067
  for (const [projectPath, id] of Object.entries(parsed.projects)) {
22184
- if (typeof id === "string" && samePath(projectPath, normalized))
23068
+ if (typeof id === "string" && samePath2(projectPath, normalized))
22185
23069
  ids.add(id);
22186
23070
  }
22187
23071
  }
22188
23072
  } catch {}
22189
23073
  }
22190
- for (const base of [path13.join(deps.geminiDir(), "tmp"), path13.join(deps.geminiDir(), "history")]) {
23074
+ for (const base of [path16.join(deps.geminiDir(), "tmp"), path16.join(deps.geminiDir(), "history")]) {
22191
23075
  for (const id of await deps.readdir(base)) {
22192
- const marker = await deps.readFile(path13.join(base, id, ".project_root")).catch(() => "");
22193
- if (marker && samePath(marker.trim(), normalized))
23076
+ const marker = await deps.readFile(path16.join(base, id, ".project_root")).catch(() => "");
23077
+ if (marker && samePath2(marker.trim(), normalized))
22194
23078
  ids.add(id);
22195
23079
  }
22196
23080
  }
22197
23081
  return ids;
22198
23082
  }
22199
- function samePath(a2, b2) {
22200
- const ar = path13.resolve(a2);
22201
- const br = path13.resolve(b2);
23083
+ function samePath2(a2, b2) {
23084
+ const ar = path16.resolve(a2);
23085
+ const br = path16.resolve(b2);
22202
23086
  if (process.platform === "win32" || process.platform === "darwin")
22203
23087
  return ar.toLowerCase() === br.toLowerCase();
22204
23088
  return ar === br;
22205
23089
  }
22206
- function isObject11(v2) {
23090
+ function isObject13(v2) {
22207
23091
  return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
22208
23092
  }
22209
- var PREVIEW_CHAR_CAP2 = 200, defaultDeps8;
22210
- var init_sessions3 = __esm(() => {
22211
- init_history3();
22212
- defaultDeps8 = {
23093
+ var PREVIEW_CHAR_CAP3 = 200, defaultDeps11;
23094
+ var init_sessions4 = __esm(() => {
23095
+ init_history4();
23096
+ defaultDeps11 = {
22213
23097
  geminiDir() {
22214
- return path13.join(homedir18(), ".gemini");
23098
+ return path16.join(homedir21(), ".gemini");
22215
23099
  },
22216
23100
  async readdir(p2) {
22217
23101
  try {
22218
- return await readdir7(p2);
23102
+ return await readdir8(p2);
22219
23103
  } catch {
22220
23104
  return [];
22221
23105
  }
22222
23106
  },
22223
23107
  async readFile(p2) {
22224
- return await readFile9(p2, "utf8");
23108
+ return await readFile10(p2, "utf8");
22225
23109
  },
22226
23110
  async unlink() {}
22227
23111
  };
22228
23112
  });
22229
23113
 
22230
23114
  // src/engine/gemini-local/spawn.ts
22231
- import { spawn as spawn12 } from "child_process";
23115
+ import { spawn as spawn13 } from "child_process";
22232
23116
  function spawnGeminiProcess(opts) {
22233
- const args = buildArgs3(opts);
22234
- const proc = spawn12(opts.binaryPath, args, {
23117
+ const args = buildArgs4(opts);
23118
+ const proc = spawn13(opts.binaryPath, args, {
22235
23119
  cwd: opts.cwd,
22236
23120
  env: { ...process.env, ...opts.env ?? {} },
22237
23121
  stdio: ["pipe", "pipe", "pipe"]
@@ -22241,7 +23125,7 @@ function spawnGeminiProcess(opts) {
22241
23125
  } catch {}
22242
23126
  return { proc, stdout: proc.stdout, stderr: proc.stderr, args };
22243
23127
  }
22244
- function buildArgs3(opts) {
23128
+ function buildArgs4(opts) {
22245
23129
  const args = ["--output-format", "stream-json", "--skip-trust"];
22246
23130
  if (opts.resumeSessionId)
22247
23131
  args.push("--resume", opts.resumeSessionId);
@@ -22253,26 +23137,26 @@ function buildArgs3(opts) {
22253
23137
  args.push("--prompt", opts.prompt);
22254
23138
  return args;
22255
23139
  }
22256
- var init_spawn3 = () => {};
23140
+ var init_spawn4 = () => {};
22257
23141
 
22258
23142
  // src/engine/gemini-local/usage.ts
22259
23143
  function geminiStatsToSnapshot(stats) {
22260
- if (!isObject12(stats))
23144
+ if (!isObject14(stats))
22261
23145
  return;
22262
- const inputTokens = numberOr4(stats.input_tokens, numberOr4(stats.inputTokens, 0));
22263
- const outputTokens = numberOr4(stats.output_tokens, numberOr4(stats.outputTokens, 0));
22264
- const cached3 = numberOr4(stats.cached, 0);
22265
- const total = numberOr4(stats.total_tokens, numberOr4(stats.totalTokens, 0));
23146
+ const inputTokens = numberOr5(stats.input_tokens, numberOr5(stats.inputTokens, 0));
23147
+ const outputTokens = numberOr5(stats.output_tokens, numberOr5(stats.outputTokens, 0));
23148
+ const cached3 = numberOr5(stats.cached, 0);
23149
+ const total = numberOr5(stats.total_tokens, numberOr5(stats.totalTokens, 0));
22266
23150
  let input = inputTokens;
22267
23151
  let output = outputTokens;
22268
23152
  let cacheRead = cached3;
22269
- if (input === 0 && output === 0 && isObject12(stats.models)) {
23153
+ if (input === 0 && output === 0 && isObject14(stats.models)) {
22270
23154
  for (const modelStats of Object.values(stats.models)) {
22271
- if (!isObject12(modelStats))
23155
+ if (!isObject14(modelStats))
22272
23156
  continue;
22273
- input += numberOr4(modelStats.input_tokens, numberOr4(modelStats.inputTokens, 0));
22274
- output += numberOr4(modelStats.output_tokens, numberOr4(modelStats.outputTokens, 0));
22275
- cacheRead += numberOr4(modelStats.cached, 0);
23157
+ input += numberOr5(modelStats.input_tokens, numberOr5(modelStats.inputTokens, 0));
23158
+ output += numberOr5(modelStats.output_tokens, numberOr5(modelStats.outputTokens, 0));
23159
+ cacheRead += numberOr5(modelStats.cached, 0);
22276
23160
  }
22277
23161
  }
22278
23162
  if (input === 0 && output === 0 && total === 0 && cacheRead === 0)
@@ -22284,10 +23168,10 @@ function geminiStatsToSnapshot(stats) {
22284
23168
  ...total > 0 ? { context_tokens: total, context_tokens_approximate: false } : {}
22285
23169
  };
22286
23170
  }
22287
- function numberOr4(v2, fallback) {
23171
+ function numberOr5(v2, fallback) {
22288
23172
  return typeof v2 === "number" && Number.isFinite(v2) ? v2 : fallback;
22289
23173
  }
22290
- function isObject12(v2) {
23174
+ function isObject14(v2) {
22291
23175
  return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
22292
23176
  }
22293
23177
 
@@ -22302,10 +23186,10 @@ async function* parseStreamJson3(lines, opts = {}) {
22302
23186
  try {
22303
23187
  msg = JSON.parse(line);
22304
23188
  } catch (err) {
22305
- yield { type: "error", message: `gemini stream-json parse failed: ${stringifyErr4(err)}` };
23189
+ yield { type: "error", message: `gemini stream-json parse failed: ${stringifyErr5(err)}` };
22306
23190
  continue;
22307
23191
  }
22308
- if (!isObject13(msg) || typeof msg.type !== "string")
23192
+ if (!isObject15(msg) || typeof msg.type !== "string")
22309
23193
  continue;
22310
23194
  switch (msg.type) {
22311
23195
  case "init": {
@@ -22325,13 +23209,13 @@ async function* parseStreamJson3(lines, opts = {}) {
22325
23209
  const name = typeof msg.tool_name === "string" ? msg.tool_name : "tool";
22326
23210
  if (id)
22327
23211
  toolNameById.set(id, name);
22328
- yield { type: "tool.start", name, input: isObject13(msg.parameters) ? msg.parameters : {} };
23212
+ yield { type: "tool.start", name, input: isObject15(msg.parameters) ? msg.parameters : {} };
22329
23213
  break;
22330
23214
  }
22331
23215
  case "tool_result": {
22332
23216
  const id = typeof msg.tool_id === "string" ? msg.tool_id : undefined;
22333
23217
  const name = (id ? toolNameById.get(id) : undefined) ?? "tool";
22334
- const output = msg.output ?? (isObject13(msg.error) ? msg.error : undefined);
23218
+ const output = msg.output ?? (isObject15(msg.error) ? msg.error : undefined);
22335
23219
  yield { type: "tool.result", name, output };
22336
23220
  break;
22337
23221
  }
@@ -22360,7 +23244,7 @@ async function* parseStreamJson3(lines, opts = {}) {
22360
23244
  }
22361
23245
  }
22362
23246
  }
22363
- async function* readLines3(stream) {
23247
+ async function* readLines4(stream) {
22364
23248
  let buf = "";
22365
23249
  for await (const chunk of stream) {
22366
23250
  const text = typeof chunk === "string" ? chunk : Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk);
@@ -22377,10 +23261,10 @@ async function* readLines3(stream) {
22377
23261
  if (buf.length > 0)
22378
23262
  yield buf;
22379
23263
  }
22380
- function isObject13(v2) {
23264
+ function isObject15(v2) {
22381
23265
  return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
22382
23266
  }
22383
- function stringifyErr4(err) {
23267
+ function stringifyErr5(err) {
22384
23268
  if (err instanceof Error)
22385
23269
  return err.message;
22386
23270
  try {
@@ -22435,13 +23319,13 @@ class GeminiLocal {
22435
23319
  };
22436
23320
  }
22437
23321
  async readHistory(sessionId) {
22438
- return readHistoryWithMetrics2(sessionId);
23322
+ return readHistoryWithMetrics3(sessionId);
22439
23323
  }
22440
23324
  async deleteHistory(sessionId) {
22441
- return deleteHistory3(sessionId);
23325
+ return deleteHistory4(sessionId);
22442
23326
  }
22443
23327
  async listSessions(cwd) {
22444
- return listSessionsForCwd3(cwd);
23328
+ return listSessionsForCwd4(cwd);
22445
23329
  }
22446
23330
  async listCommands(_opts) {
22447
23331
  return [];
@@ -22478,8 +23362,8 @@ class GeminiLocal {
22478
23362
  let bound = false;
22479
23363
  let stderrTail = "";
22480
23364
  let terminalSeen = false;
22481
- captureStderrTail2(spawned.stderr, (chunk) => {
22482
- stderrTail = (stderrTail + chunk).slice(-STDERR_TAIL_CAP2);
23365
+ captureStderrTail3(spawned.stderr, (chunk) => {
23366
+ stderrTail = (stderrTail + chunk).slice(-STDERR_TAIL_CAP3);
22483
23367
  });
22484
23368
  const bind = (sessionId) => {
22485
23369
  if (bound)
@@ -22514,13 +23398,13 @@ class GeminiLocal {
22514
23398
  exitInfo.signal = signal;
22515
23399
  exitInfo.seen = true;
22516
23400
  if (!bound)
22517
- rejectHandle(new Error(formatExitMsg2("gemini exited before session id was captured", code, signal, stderrTail)));
23401
+ rejectHandle(new Error(formatExitMsg3("gemini exited before session id was captured", code, signal, stderrTail)));
22518
23402
  resolve3();
22519
23403
  });
22520
23404
  });
22521
23405
  (async () => {
22522
23406
  try {
22523
- for await (const ev of parseStreamJson3(readLines3(spawned.stdout), { onSessionId: bind })) {
23407
+ for await (const ev of parseStreamJson3(readLines4(spawned.stdout), { onSessionId: bind })) {
22524
23408
  if (ev.type === "done" || ev.type === "error")
22525
23409
  terminalSeen = true;
22526
23410
  queue.push(ev);
@@ -22538,13 +23422,13 @@ class GeminiLocal {
22538
23422
  if (session)
22539
23423
  this.notify(session);
22540
23424
  } finally {
22541
- await Promise.race([exitObserved, new Promise((r2) => setTimeout(r2, PROCESS_EXIT_GRACE_MS))]);
23425
+ await Promise.race([exitObserved, new Promise((r2) => setTimeout(r2, PROCESS_EXIT_GRACE_MS2))]);
22542
23426
  if (session) {
22543
23427
  const lastEv = queue[queue.length - 1];
22544
23428
  if (exitInfo.seen && typeof exitInfo.code === "number" && exitInfo.code !== 0 && !terminalSeen && lastEv?.type !== "error") {
22545
23429
  queue.push({
22546
23430
  type: "error",
22547
- message: formatExitMsg2("gemini exited", exitInfo.code, exitInfo.signal, stderrTail)
23431
+ message: formatExitMsg3("gemini exited", exitInfo.code, exitInfo.signal, stderrTail)
22548
23432
  });
22549
23433
  }
22550
23434
  session.closed = true;
@@ -22570,14 +23454,14 @@ class GeminiLocal {
22570
23454
  w2();
22571
23455
  }
22572
23456
  }
22573
- function captureStderrTail2(stream, onChunk) {
23457
+ function captureStderrTail3(stream, onChunk) {
22574
23458
  const s2 = stream;
22575
23459
  s2.on("data", (chunk) => {
22576
23460
  onChunk(typeof chunk === "string" ? chunk : chunk.toString("utf8"));
22577
23461
  });
22578
23462
  s2.on("error", () => {});
22579
23463
  }
22580
- function formatExitMsg2(prefix, code, signal, stderrTail) {
23464
+ function formatExitMsg3(prefix, code, signal, stderrTail) {
22581
23465
  const parts = [prefix];
22582
23466
  if (typeof code === "number")
22583
23467
  parts.push(`(code=${code}${signal ? `, signal=${signal}` : ""})`);
@@ -22588,15 +23472,15 @@ function formatExitMsg2(prefix, code, signal, stderrTail) {
22588
23472
  parts.push(`: ${detail}`);
22589
23473
  return parts.join(" ").replace(/ : /, ": ");
22590
23474
  }
22591
- var STDERR_TAIL_CAP2, PROCESS_EXIT_GRACE_MS = 500;
23475
+ var STDERR_TAIL_CAP3, PROCESS_EXIT_GRACE_MS2 = 500;
22592
23476
  var init_gemini_local = __esm(() => {
22593
- init_binary3();
22594
- init_capabilities3();
22595
- init_history3();
22596
- init_sessions3();
22597
- init_spawn3();
23477
+ init_binary4();
23478
+ init_capabilities4();
23479
+ init_history4();
23480
+ init_sessions4();
23481
+ init_spawn4();
22598
23482
  init_stream2();
22599
- STDERR_TAIL_CAP2 = 4 * 1024;
23483
+ STDERR_TAIL_CAP3 = 4 * 1024;
22600
23484
  });
22601
23485
 
22602
23486
  // src/engine/default-engines.ts
@@ -22604,12 +23488,14 @@ function buildDefaultEngines() {
22604
23488
  return {
22605
23489
  claude: new ClaudeCodeLocal,
22606
23490
  codex: new CodexLocal,
22607
- gemini: new GeminiLocal
23491
+ gemini: new GeminiLocal,
23492
+ copilot: new CopilotLocal
22608
23493
  };
22609
23494
  }
22610
23495
  var init_default_engines = __esm(() => {
22611
23496
  init_claude_code_local();
22612
23497
  init_codex_local();
23498
+ init_copilot_local();
22613
23499
  init_gemini_local();
22614
23500
  });
22615
23501
 
@@ -22753,7 +23639,7 @@ __export(exports_bridge, {
22753
23639
  bridgeSocketPathForHome: () => bridgeSocketPathForHome
22754
23640
  });
22755
23641
  import { mkdir as mkdir4, unlink as unlink8, writeFile as writeFile3 } from "fs/promises";
22756
- import { homedir as homedir19 } from "os";
23642
+ import { homedir as homedir22 } from "os";
22757
23643
  import { join as join16 } from "path";
22758
23644
  import { fileURLToPath as fileURLToPath2 } from "url";
22759
23645
  function bridgeSocketPathForHome(home, pid = process.pid) {
@@ -22761,7 +23647,7 @@ function bridgeSocketPathForHome(home, pid = process.pid) {
22761
23647
  return fitSocketPath(join16(runDir, `bridge-${pid}.sock`), home, "bridge", pid);
22762
23648
  }
22763
23649
  async function startBridge(orch, opts = {}) {
22764
- const home = opts.homeDir ?? process.env.KOBE_HOME_DIR ?? homedir19();
23650
+ const home = opts.homeDir ?? process.env.KOBE_HOME_DIR ?? homedir22();
22765
23651
  const runDir = join16(home, ".kobe", "run");
22766
23652
  const socketPath = bridgeSocketPathForHome(home);
22767
23653
  const mcpConfigPath = join16(runDir, `mcp-${process.pid}.json`);
@@ -23109,10 +23995,10 @@ var init_errors = __esm(() => {
23109
23995
  });
23110
23996
 
23111
23997
  // src/orchestrator/local-merge/build.ts
23112
- import { spawnSync as spawnSync7 } from "child_process";
23998
+ import { spawnSync as spawnSync8 } from "child_process";
23113
23999
  function git(cwd, args) {
23114
24000
  try {
23115
- const out = spawnSync7("git", args.slice(), {
24001
+ const out = spawnSync8("git", args.slice(), {
23116
24002
  cwd,
23117
24003
  encoding: "utf8",
23118
24004
  timeout: GIT_TIMEOUT_MS
@@ -23467,10 +24353,10 @@ class InMemoryPendingInputBroker {
23467
24353
  }
23468
24354
 
23469
24355
  // src/orchestrator/pr/build.ts
23470
- import { spawnSync as spawnSync8 } from "child_process";
24356
+ import { spawnSync as spawnSync9 } from "child_process";
23471
24357
  function git2(cwd, args) {
23472
24358
  try {
23473
- const out = spawnSync8("git", args.slice(), {
24359
+ const out = spawnSync9("git", args.slice(), {
23474
24360
  cwd,
23475
24361
  encoding: "utf8",
23476
24362
  timeout: GIT_TIMEOUT_MS2
@@ -23520,7 +24406,7 @@ var init_build2 = () => {};
23520
24406
 
23521
24407
  // src/orchestrator/pr/instructions.ts
23522
24408
  import { promises as fs3 } from "fs";
23523
- import path14 from "path";
24409
+ import path17 from "path";
23524
24410
  function dirtyCountSentence(n2) {
23525
24411
  if (n2 <= 0)
23526
24412
  return "There are no uncommitted changes.";
@@ -23548,7 +24434,7 @@ function renderPRInstructions(template, state) {
23548
24434
  async function loadPRInstructionsTemplate(worktreePath) {
23549
24435
  if (!worktreePath)
23550
24436
  return DEFAULT_PR_INSTRUCTIONS_TEMPLATE;
23551
- const file = path14.join(worktreePath, ".kobe", "pr-instructions.md");
24437
+ const file = path17.join(worktreePath, ".kobe", "pr-instructions.md");
23552
24438
  try {
23553
24439
  const text = await fs3.readFile(file, "utf8");
23554
24440
  if (text.length === 0)
@@ -23579,10 +24465,10 @@ If any of these steps fail, ask the user for help.`;
23579
24465
  var init_instructions = () => {};
23580
24466
 
23581
24467
  // src/orchestrator/pr/status.ts
23582
- import { spawnSync as spawnSync9 } from "child_process";
24468
+ import { spawnSync as spawnSync10 } from "child_process";
23583
24469
  function run(cwd, command, args, timeout) {
23584
24470
  try {
23585
- const out = spawnSync9(command, args.slice(), { cwd, encoding: "utf8", timeout });
24471
+ const out = spawnSync10(command, args.slice(), { cwd, encoding: "utf8", timeout });
23586
24472
  if (out.error)
23587
24473
  return null;
23588
24474
  if (out.status !== 0)
@@ -25372,12 +26258,12 @@ var init_core = __esm(() => {
25372
26258
  });
25373
26259
 
25374
26260
  // src/orchestrator/worktree/git.ts
25375
- import { spawnSync as spawnSync10 } from "child_process";
26261
+ import { spawnSync as spawnSync11 } from "child_process";
25376
26262
  function git3(args, opts) {
25377
26263
  if (!opts.cwd) {
25378
26264
  throw new Error("git(): cwd is required; refusing to inherit from process.cwd()");
25379
26265
  }
25380
- const proc = spawnSync10("git", [...args], {
26266
+ const proc = spawnSync11("git", [...args], {
25381
26267
  cwd: opts.cwd,
25382
26268
  env: opts.env ? { ...process.env, ...opts.env } : process.env,
25383
26269
  encoding: "utf8",
@@ -25415,7 +26301,7 @@ var init_git2 = __esm(() => {
25415
26301
 
25416
26302
  // src/orchestrator/worktree/manager.ts
25417
26303
  import fs4 from "fs";
25418
- import path15 from "path";
26304
+ import path18 from "path";
25419
26305
 
25420
26306
  class GitWorktreeManager {
25421
26307
  async create(repo, branch, worktreePath, baseRef) {
@@ -25433,7 +26319,7 @@ class GitWorktreeManager {
25433
26319
  }
25434
26320
  throw new Error(`create(): ${worktreePath} exists but is not a registered git worktree`);
25435
26321
  }
25436
- fs4.mkdirSync(path15.dirname(worktreePath), { recursive: true });
26322
+ fs4.mkdirSync(path18.dirname(worktreePath), { recursive: true });
25437
26323
  const branchExists = this.branchExists(repo, branch);
25438
26324
  const args = branchExists ? ["worktree", "add", worktreePath, branch] : baseRef ? ["worktree", "add", "-b", branch, worktreePath, baseRef] : ["worktree", "add", "-b", branch, worktreePath];
25439
26325
  git3(args, { cwd: repo });
@@ -25488,8 +26374,8 @@ class GitWorktreeManager {
25488
26374
  if (!entry.branch || entry.detached)
25489
26375
  continue;
25490
26376
  const canonEntry = canonicalize2(entry.path);
25491
- const rel = path15.relative(canonRoot, canonEntry);
25492
- const callerPath = path15.join(callerRoot, rel);
26377
+ const rel = path18.relative(canonRoot, canonEntry);
26378
+ const callerPath = path18.join(callerRoot, rel);
25493
26379
  const dirty = await this.isDirty(entry.path);
25494
26380
  infos.push({
25495
26381
  path: callerPath,
@@ -25550,9 +26436,9 @@ class GitWorktreeManager {
25550
26436
  const gitDir = out.stdout.trim();
25551
26437
  if (!gitDir)
25552
26438
  return null;
25553
- const absolute = path15.isAbsolute(gitDir) ? gitDir : path15.resolve(worktreePath, gitDir);
25554
- const base = path15.basename(absolute);
25555
- return base === ".git" ? path15.dirname(absolute) : absolute;
26439
+ const absolute = path18.isAbsolute(gitDir) ? gitDir : path18.resolve(worktreePath, gitDir);
26440
+ const base = path18.basename(absolute);
26441
+ return base === ".git" ? path18.dirname(absolute) : absolute;
25556
26442
  } catch (err) {
25557
26443
  if (err instanceof GitCommandError)
25558
26444
  return null;
@@ -25592,7 +26478,7 @@ function parsePorcelain2(out) {
25592
26478
  return records;
25593
26479
  }
25594
26480
  function requireAbsolute(name, value) {
25595
- if (!value || !path15.isAbsolute(value)) {
26481
+ if (!value || !path18.isAbsolute(value)) {
25596
26482
  throw new Error(`${name} must be an absolute path, got: ${JSON.stringify(value)}`);
25597
26483
  }
25598
26484
  }
@@ -25600,7 +26486,7 @@ function canonicalize2(p2) {
25600
26486
  try {
25601
26487
  return fs4.realpathSync(p2);
25602
26488
  } catch {
25603
- return path15.resolve(p2);
26489
+ return path18.resolve(p2);
25604
26490
  }
25605
26491
  }
25606
26492
  var init_manager = __esm(() => {
@@ -25609,9 +26495,9 @@ var init_manager = __esm(() => {
25609
26495
  });
25610
26496
 
25611
26497
  // src/core/index.ts
25612
- import { homedir as homedir20 } from "os";
26498
+ import { homedir as homedir23 } from "os";
25613
26499
  async function createKobeCore(options = {}) {
25614
- const homeDir2 = options.homeDir ?? process.env.KOBE_HOME_DIR ?? homedir20();
26500
+ const homeDir2 = options.homeDir ?? process.env.KOBE_HOME_DIR ?? homedir23();
25615
26501
  const store2 = new TaskIndexStore({ homeDir: homeDir2 });
25616
26502
  await store2.load();
25617
26503
  const worktrees = new GitWorktreeManager;
@@ -25676,8 +26562,8 @@ var onRejection, onException;
25676
26562
  // src/engine/claude-code-local/plan-usage.ts
25677
26563
  import { execFile } from "child_process";
25678
26564
  import { createHash as createHash2 } from "crypto";
25679
- import { readFile as readFile10 } from "fs/promises";
25680
- import { homedir as homedir21, userInfo } from "os";
26565
+ import { readFile as readFile11 } from "fs/promises";
26566
+ import { homedir as homedir24, userInfo } from "os";
25681
26567
  import { join as join17 } from "path";
25682
26568
  import { promisify } from "util";
25683
26569
  function keychainServiceName() {
@@ -25708,10 +26594,10 @@ async function readKeychainToken() {
25708
26594
  }
25709
26595
  }
25710
26596
  async function readPlainTextToken() {
25711
- const configDir = process.env.CLAUDE_CONFIG_DIR ?? join17(homedir21(), ".claude");
25712
- const path16 = join17(configDir, ".credentials.json");
26597
+ const configDir = process.env.CLAUDE_CONFIG_DIR ?? join17(homedir24(), ".claude");
26598
+ const path19 = join17(configDir, ".credentials.json");
25713
26599
  try {
25714
- const raw = await readFile10(path16, "utf8");
26600
+ const raw = await readFile11(path19, "utf8");
25715
26601
  return parseStoredOAuth(raw);
25716
26602
  } catch {
25717
26603
  return null;
@@ -25833,12 +26719,12 @@ var init_plan_usage_poller = __esm(() => {
25833
26719
  });
25834
26720
 
25835
26721
  // src/daemon/rc-bridge.ts
25836
- import { spawn as spawn13 } from "child_process";
26722
+ import { spawn as spawn14 } from "child_process";
25837
26723
  function createRcBridge(options = {}) {
25838
26724
  const stopGraceMs = options.stopGraceMs ?? 5000;
25839
26725
  const readyTimeoutMs = options.readyTimeoutMs ?? 30000;
25840
26726
  const binaryPathResolver = options.binaryPathResolver ?? findClaudeBinary;
25841
- const spawner = options.spawner ?? ((cmd, args, cwd) => spawn13(cmd, [...args], {
26727
+ const spawner = options.spawner ?? ((cmd, args, cwd) => spawn14(cmd, [...args], {
25842
26728
  cwd,
25843
26729
  stdio: ["ignore", "pipe", "pipe"],
25844
26730
  env: { ...process.env }
@@ -26011,7 +26897,7 @@ var init_rc_bridge = __esm(() => {
26011
26897
  });
26012
26898
 
26013
26899
  // src/daemon/server.ts
26014
- import { mkdir as mkdir5, readFile as readFile11, unlink as unlink9, writeFile as writeFile4 } from "fs/promises";
26900
+ import { mkdir as mkdir5, readFile as readFile12, unlink as unlink9, writeFile as writeFile4 } from "fs/promises";
26015
26901
  import { createServer as createServer2 } from "net";
26016
26902
  import { dirname as dirname6 } from "path";
26017
26903
  async function startDaemonServer(orch, options = {}) {
@@ -26444,7 +27330,7 @@ async function startDaemonServer(orch, options = {}) {
26444
27330
  }
26445
27331
  async function readPidFile(pidPath) {
26446
27332
  try {
26447
- const raw = await readFile11(pidPath, "utf8");
27333
+ const raw = await readFile12(pidPath, "utf8");
26448
27334
  const pid = Number(raw.trim());
26449
27335
  return Number.isFinite(pid) ? pid : null;
26450
27336
  } catch {
@@ -26527,8 +27413,8 @@ function optionalModelEffort(payload, key) {
26527
27413
  }
26528
27414
  function optionalVendor(payload, key) {
26529
27415
  const value = optionalString2(payload, key);
26530
- if (value !== undefined && value !== "claude" && value !== "codex" && value !== "gemini") {
26531
- throw new Error(`${key} '${value}' is not a supported vendor (expected: claude, codex, gemini)`);
27416
+ if (value !== undefined && value !== "claude" && value !== "codex" && value !== "gemini" && value !== "copilot") {
27417
+ throw new Error(`${key} '${value}' is not a supported vendor (expected: claude, codex, gemini, copilot)`);
26532
27418
  }
26533
27419
  return value;
26534
27420
  }
@@ -27232,25 +28118,30 @@ function resolveDaemonMode(flagMode, env = process.env) {
27232
28118
  }
27233
28119
 
27234
28120
  // src/engine/account-detect.ts
27235
- import { readFileSync as readFileSync8, statSync as statSync5 } from "fs";
27236
- import { homedir as homedir22 } from "os";
27237
- import path16 from "path";
28121
+ import { readFileSync as readFileSync8, statSync as statSync6 } from "fs";
28122
+ import { homedir as homedir25 } from "os";
28123
+ import path19 from "path";
27238
28124
  function claudeGlobalConfigPath(env, home) {
27239
28125
  const override = env("CLAUDE_CONFIG_DIR")?.trim();
27240
28126
  if (override)
27241
- return path16.join(override, ".claude.json");
27242
- return path16.join(home, ".claude.json");
28127
+ return path19.join(override, ".claude.json");
28128
+ return path19.join(home, ".claude.json");
27243
28129
  }
27244
28130
  function codexAuthPath(env, home) {
27245
28131
  const override = env("CODEX_HOME")?.trim();
27246
- const dir = override ?? path16.join(home, ".codex");
27247
- return path16.join(dir, "auth.json");
28132
+ const dir = override ?? path19.join(home, ".codex");
28133
+ return path19.join(dir, "auth.json");
27248
28134
  }
27249
28135
  function geminiOauthCredsPath(home) {
27250
- return path16.join(home, ".gemini", "oauth_creds.json");
28136
+ return path19.join(home, ".gemini", "oauth_creds.json");
27251
28137
  }
27252
28138
  function geminiSettingsPath(home) {
27253
- return path16.join(home, ".gemini", "settings.json");
28139
+ return path19.join(home, ".gemini", "settings.json");
28140
+ }
28141
+ function copilotConfigPath(env, home) {
28142
+ const override = env("COPILOT_HOME")?.trim();
28143
+ const dir = override ?? path19.join(home, ".copilot");
28144
+ return path19.join(dir, "config.json");
27254
28145
  }
27255
28146
  function decodeJwtPayload(jwt) {
27256
28147
  const parts = jwt.split(".");
@@ -27274,13 +28165,13 @@ async function probeBinary(probe) {
27274
28165
  const p2 = await probe();
27275
28166
  return { found: true, path: p2 };
27276
28167
  } catch (err) {
27277
- if (err instanceof ClaudeBinaryNotFoundError || err instanceof CodexBinaryNotFoundError || err instanceof GeminiBinaryNotFoundError) {
28168
+ if (err instanceof ClaudeBinaryNotFoundError || err instanceof CodexBinaryNotFoundError || err instanceof GeminiBinaryNotFoundError || err instanceof CopilotBinaryNotFoundError) {
27278
28169
  return { found: false, error: "not found on PATH" };
27279
28170
  }
27280
28171
  return { found: false, error: err instanceof Error ? err.message : String(err) };
27281
28172
  }
27282
28173
  }
27283
- async function detectClaudeAccount(deps = defaultDeps9) {
28174
+ async function detectClaudeAccount(deps = defaultDeps12) {
27284
28175
  const binary = await probeBinary(() => deps.findClaudeBinary());
27285
28176
  const configPath = claudeGlobalConfigPath(deps.env, deps.home());
27286
28177
  let raw;
@@ -27323,7 +28214,7 @@ async function detectClaudeAccount(deps = defaultDeps9) {
27323
28214
  }
27324
28215
  };
27325
28216
  }
27326
- async function detectCodexAccount(deps = defaultDeps9) {
28217
+ async function detectCodexAccount(deps = defaultDeps12) {
27327
28218
  const binary = await probeBinary(() => deps.findCodexBinary());
27328
28219
  const authPath = codexAuthPath(deps.env, deps.home());
27329
28220
  let raw;
@@ -27374,7 +28265,7 @@ async function detectCodexAccount(deps = defaultDeps9) {
27374
28265
  }
27375
28266
  return { binary, account: { kind: "none" } };
27376
28267
  }
27377
- async function detectGeminiAccount(deps = defaultDeps9) {
28268
+ async function detectGeminiAccount(deps = defaultDeps12) {
27378
28269
  const binary = await probeBinary(() => deps.findGeminiBinary());
27379
28270
  const apiKey = deps.env("GEMINI_API_KEY")?.trim();
27380
28271
  if (apiKey)
@@ -27452,18 +28343,74 @@ async function detectGeminiAccount(deps = defaultDeps9) {
27452
28343
  return { binary, account: { kind: "google", authType } };
27453
28344
  return { binary, account: { kind: "none" } };
27454
28345
  }
28346
+ async function detectCopilotAccount(deps = defaultDeps12) {
28347
+ const binary = await probeBinary(() => deps.findCopilotBinary());
28348
+ for (const source of ["COPILOT_GITHUB_TOKEN", "GH_TOKEN", "GITHUB_TOKEN"]) {
28349
+ if (deps.env(source)?.trim())
28350
+ return { binary, account: { kind: "token", source } };
28351
+ }
28352
+ const configPath = copilotConfigPath(deps.env, deps.home());
28353
+ let raw;
28354
+ try {
28355
+ raw = deps.readFile(configPath);
28356
+ } catch (err) {
28357
+ return {
28358
+ binary,
28359
+ account: { kind: "none" },
28360
+ accountError: `read ${configPath}: ${err instanceof Error ? err.message : String(err)}`
28361
+ };
28362
+ }
28363
+ if (raw === null)
28364
+ return { binary, account: { kind: "none" } };
28365
+ let parsed;
28366
+ try {
28367
+ parsed = JSON.parse(raw);
28368
+ } catch (err) {
28369
+ return {
28370
+ binary,
28371
+ account: { kind: "none" },
28372
+ accountError: `parse ${configPath}: ${err instanceof Error ? err.message : String(err)}`
28373
+ };
28374
+ }
28375
+ if (!isRecord(parsed))
28376
+ return { binary, account: { kind: "none" } };
28377
+ if (hasStringDeep(parsed, [
28378
+ "github_token",
28379
+ "oauth_token",
28380
+ "access_token",
28381
+ "token",
28382
+ "selectedUser",
28383
+ "currentUser",
28384
+ "user"
28385
+ ])) {
28386
+ return { binary, account: { kind: "oauth" } };
28387
+ }
28388
+ return { binary, account: { kind: "none" } };
28389
+ }
27455
28390
  function isRecord(v2) {
27456
28391
  return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
27457
28392
  }
27458
- var defaultDeps9;
28393
+ function hasStringDeep(value, interestingKeys, depth = 0) {
28394
+ if (depth > 4 || !isRecord(value))
28395
+ return false;
28396
+ for (const [key, entry] of Object.entries(value)) {
28397
+ if (interestingKeys.includes(key) && typeof entry === "string" && entry.length > 0)
28398
+ return true;
28399
+ if (isRecord(entry) && hasStringDeep(entry, interestingKeys, depth + 1))
28400
+ return true;
28401
+ }
28402
+ return false;
28403
+ }
28404
+ var defaultDeps12;
27459
28405
  var init_account_detect = __esm(() => {
27460
28406
  init_binary();
27461
28407
  init_binary2();
27462
28408
  init_binary3();
27463
- defaultDeps9 = {
28409
+ init_binary4();
28410
+ defaultDeps12 = {
27464
28411
  readFile(p2) {
27465
28412
  try {
27466
- statSync5(p2);
28413
+ statSync6(p2);
27467
28414
  } catch (err) {
27468
28415
  if (err.code === "ENOENT")
27469
28416
  return null;
@@ -27475,7 +28422,7 @@ var init_account_detect = __esm(() => {
27475
28422
  return process.env[name];
27476
28423
  },
27477
28424
  home() {
27478
- return homedir22();
28425
+ return homedir25();
27479
28426
  },
27480
28427
  findClaudeBinary() {
27481
28428
  return findClaudeBinary();
@@ -27485,6 +28432,9 @@ var init_account_detect = __esm(() => {
27485
28432
  },
27486
28433
  findGeminiBinary() {
27487
28434
  return findGeminiBinary();
28435
+ },
28436
+ findCopilotBinary() {
28437
+ return findCopilotBinary();
27488
28438
  }
27489
28439
  };
27490
28440
  });
@@ -27865,12 +28815,13 @@ function AccountsSettingsSection(props) {
27865
28815
  theme
27866
28816
  } = useTheme();
27867
28817
  return (() => {
27868
- var _el$35 = createElement("box"), _el$36 = createElement("text"), _el$38 = createElement("text"), _el$40 = createElement("box"), _el$41 = createElement("text"), _el$45 = createElement("box"), _el$46 = createElement("text"), _el$50 = createElement("box"), _el$51 = createElement("text");
28818
+ var _el$35 = createElement("box"), _el$36 = createElement("text"), _el$38 = createElement("text"), _el$40 = createElement("box"), _el$41 = createElement("text"), _el$45 = createElement("box"), _el$46 = createElement("text"), _el$50 = createElement("box"), _el$51 = createElement("text"), _el$55 = createElement("box"), _el$56 = createElement("text");
27869
28819
  insertNode(_el$35, _el$36);
27870
28820
  insertNode(_el$35, _el$38);
27871
28821
  insertNode(_el$35, _el$40);
27872
28822
  insertNode(_el$35, _el$45);
27873
28823
  insertNode(_el$35, _el$50);
28824
+ insertNode(_el$35, _el$55);
27874
28825
  setProp(_el$35, "flexDirection", "column");
27875
28826
  setProp(_el$35, "gap", 1);
27876
28827
  insertNode(_el$36, createTextNode(`Accounts`));
@@ -27896,48 +28847,48 @@ function AccountsSettingsSection(props) {
27896
28847
  return props.claudeStatus();
27897
28848
  },
27898
28849
  children: (s2) => (() => {
27899
- var _el$55 = createElement("box"), _el$56 = createElement("text");
27900
- insertNode(_el$55, _el$56);
27901
- setProp(_el$55, "flexDirection", "column");
27902
- setProp(_el$55, "gap", 0);
27903
- setProp(_el$56, "wrapMode", "word");
27904
- insert(_el$56, (() => {
28850
+ var _el$60 = createElement("box"), _el$61 = createElement("text");
28851
+ insertNode(_el$60, _el$61);
28852
+ setProp(_el$60, "flexDirection", "column");
28853
+ setProp(_el$60, "gap", 0);
28854
+ setProp(_el$61, "wrapMode", "word");
28855
+ insert(_el$61, (() => {
27905
28856
  var _c$ = memo2(() => !!s2().binary.found);
27906
28857
  return () => _c$() ? `Binary: ${s2().binary.path}` : `Binary: ${s2().binary.error}`;
27907
28858
  })());
27908
- insert(_el$55, () => {
28859
+ insert(_el$60, () => {
27909
28860
  const a2 = s2().account;
27910
28861
  if (a2.kind === "oauth") {
27911
28862
  const tail = [a2.organization, a2.billingType].filter((x2) => !!x2).join(" \xB7 ");
27912
28863
  return (() => {
27913
- var _el$57 = createElement("text");
27914
- setProp(_el$57, "wrapMode", "word");
27915
- insert(_el$57, () => `\u25CF Logged in: ${a2.email}${tail ? ` (${tail})` : ""}`);
27916
- effect((_$p) => setProp(_el$57, "fg", theme.success, _$p));
27917
- return _el$57;
28864
+ var _el$62 = createElement("text");
28865
+ setProp(_el$62, "wrapMode", "word");
28866
+ insert(_el$62, () => `\u25CF Logged in: ${a2.email}${tail ? ` (${tail})` : ""}`);
28867
+ effect((_$p) => setProp(_el$62, "fg", theme.success, _$p));
28868
+ return _el$62;
27918
28869
  })();
27919
28870
  }
27920
28871
  return (() => {
27921
- var _el$58 = createElement("text");
27922
- insertNode(_el$58, createTextNode(`\u25CB Not logged in`));
27923
- effect((_$p) => setProp(_el$58, "fg", theme.textMuted, _$p));
27924
- return _el$58;
28872
+ var _el$63 = createElement("text");
28873
+ insertNode(_el$63, createTextNode(`\u25CB Not logged in`));
28874
+ effect((_$p) => setProp(_el$63, "fg", theme.textMuted, _$p));
28875
+ return _el$63;
27925
28876
  })();
27926
28877
  }, null);
27927
- insert(_el$55, createComponent2(Show, {
28878
+ insert(_el$60, createComponent2(Show, {
27928
28879
  get when() {
27929
28880
  return s2().accountError;
27930
28881
  },
27931
28882
  children: (err) => (() => {
27932
- var _el$60 = createElement("text");
27933
- setProp(_el$60, "wrapMode", "word");
27934
- insert(_el$60, () => `! ${err()}`);
27935
- effect((_$p) => setProp(_el$60, "fg", theme.warning, _$p));
27936
- return _el$60;
28883
+ var _el$65 = createElement("text");
28884
+ setProp(_el$65, "wrapMode", "word");
28885
+ insert(_el$65, () => `! ${err()}`);
28886
+ effect((_$p) => setProp(_el$65, "fg", theme.warning, _$p));
28887
+ return _el$65;
27937
28888
  })()
27938
28889
  }), null);
27939
- effect((_$p) => setProp(_el$56, "fg", s2().binary.found ? theme.textMuted : theme.warning, _$p));
27940
- return _el$55;
28890
+ effect((_$p) => setProp(_el$61, "fg", s2().binary.found ? theme.textMuted : theme.warning, _$p));
28891
+ return _el$60;
27941
28892
  })()
27942
28893
  }), null);
27943
28894
  insertNode(_el$45, _el$46);
@@ -27960,63 +28911,63 @@ function AccountsSettingsSection(props) {
27960
28911
  return props.codexStatus();
27961
28912
  },
27962
28913
  children: (s2) => (() => {
27963
- var _el$61 = createElement("box"), _el$62 = createElement("text");
27964
- insertNode(_el$61, _el$62);
27965
- setProp(_el$61, "flexDirection", "column");
27966
- setProp(_el$61, "gap", 0);
27967
- setProp(_el$62, "wrapMode", "word");
27968
- insert(_el$62, (() => {
28914
+ var _el$66 = createElement("box"), _el$67 = createElement("text");
28915
+ insertNode(_el$66, _el$67);
28916
+ setProp(_el$66, "flexDirection", "column");
28917
+ setProp(_el$66, "gap", 0);
28918
+ setProp(_el$67, "wrapMode", "word");
28919
+ insert(_el$67, (() => {
27969
28920
  var _c$2 = memo2(() => !!s2().binary.found);
27970
28921
  return () => _c$2() ? `Binary: ${s2().binary.path}` : `Binary: ${s2().binary.error}`;
27971
28922
  })());
27972
- insert(_el$61, () => {
28923
+ insert(_el$66, () => {
27973
28924
  const a2 = s2().account;
27974
28925
  if (a2.kind === "chatgpt") {
27975
28926
  return (() => {
27976
- var _el$63 = createElement("text");
27977
- setProp(_el$63, "wrapMode", "word");
27978
- insert(_el$63, () => `\u25CF ChatGPT login: ${a2.email}${a2.plan ? ` (${a2.plan})` : ""}`);
27979
- effect((_$p) => setProp(_el$63, "fg", theme.success, _$p));
27980
- return _el$63;
28927
+ var _el$68 = createElement("text");
28928
+ setProp(_el$68, "wrapMode", "word");
28929
+ insert(_el$68, () => `\u25CF ChatGPT login: ${a2.email}${a2.plan ? ` (${a2.plan})` : ""}`);
28930
+ effect((_$p) => setProp(_el$68, "fg", theme.success, _$p));
28931
+ return _el$68;
27981
28932
  })();
27982
28933
  }
27983
28934
  if (a2.kind === "apikey")
27984
28935
  return (() => {
27985
- var _el$64 = createElement("text");
27986
- insertNode(_el$64, createTextNode(`\u25CF API key configured`));
27987
- effect((_$p) => setProp(_el$64, "fg", theme.success, _$p));
27988
- return _el$64;
28936
+ var _el$69 = createElement("text");
28937
+ insertNode(_el$69, createTextNode(`\u25CF API key configured`));
28938
+ effect((_$p) => setProp(_el$69, "fg", theme.success, _$p));
28939
+ return _el$69;
27989
28940
  })();
27990
28941
  return (() => {
27991
- var _el$66 = createElement("text");
27992
- insertNode(_el$66, createTextNode(`\u25CB Not logged in`));
27993
- effect((_$p) => setProp(_el$66, "fg", theme.textMuted, _$p));
27994
- return _el$66;
28942
+ var _el$71 = createElement("text");
28943
+ insertNode(_el$71, createTextNode(`\u25CB Not logged in`));
28944
+ effect((_$p) => setProp(_el$71, "fg", theme.textMuted, _$p));
28945
+ return _el$71;
27995
28946
  })();
27996
28947
  }, null);
27997
- insert(_el$61, createComponent2(Show, {
28948
+ insert(_el$66, createComponent2(Show, {
27998
28949
  get when() {
27999
28950
  return s2().accountError;
28000
28951
  },
28001
28952
  children: (err) => (() => {
28002
- var _el$68 = createElement("text");
28003
- setProp(_el$68, "wrapMode", "word");
28004
- insert(_el$68, () => `! ${err()}`);
28005
- effect((_$p) => setProp(_el$68, "fg", theme.warning, _$p));
28006
- return _el$68;
28953
+ var _el$73 = createElement("text");
28954
+ setProp(_el$73, "wrapMode", "word");
28955
+ insert(_el$73, () => `! ${err()}`);
28956
+ effect((_$p) => setProp(_el$73, "fg", theme.warning, _$p));
28957
+ return _el$73;
28007
28958
  })()
28008
28959
  }), null);
28009
- effect((_$p) => setProp(_el$62, "fg", s2().binary.found ? theme.textMuted : theme.warning, _$p));
28010
- return _el$61;
28960
+ effect((_$p) => setProp(_el$67, "fg", s2().binary.found ? theme.textMuted : theme.warning, _$p));
28961
+ return _el$66;
28011
28962
  })()
28012
28963
  }), null);
28013
28964
  insertNode(_el$50, _el$51);
28014
28965
  setProp(_el$50, "flexDirection", "column");
28015
28966
  setProp(_el$50, "gap", 0);
28016
- insertNode(_el$51, createTextNode(`gemini`));
28967
+ insertNode(_el$51, createTextNode(`copilot`));
28017
28968
  insert(_el$50, createComponent2(Show, {
28018
28969
  get when() {
28019
- return props.geminiStatus() === null;
28970
+ return props.copilotStatus() === null;
28020
28971
  },
28021
28972
  get children() {
28022
28973
  var _el$53 = createElement("text");
@@ -28027,72 +28978,140 @@ function AccountsSettingsSection(props) {
28027
28978
  }), null);
28028
28979
  insert(_el$50, createComponent2(Show, {
28029
28980
  get when() {
28030
- return props.geminiStatus();
28981
+ return props.copilotStatus();
28031
28982
  },
28032
28983
  children: (s2) => (() => {
28033
- var _el$69 = createElement("box"), _el$70 = createElement("text");
28034
- insertNode(_el$69, _el$70);
28035
- setProp(_el$69, "flexDirection", "column");
28036
- setProp(_el$69, "gap", 0);
28037
- setProp(_el$70, "wrapMode", "word");
28038
- insert(_el$70, (() => {
28984
+ var _el$74 = createElement("box"), _el$75 = createElement("text");
28985
+ insertNode(_el$74, _el$75);
28986
+ setProp(_el$74, "flexDirection", "column");
28987
+ setProp(_el$74, "gap", 0);
28988
+ setProp(_el$75, "wrapMode", "word");
28989
+ insert(_el$75, (() => {
28039
28990
  var _c$3 = memo2(() => !!s2().binary.found);
28040
28991
  return () => _c$3() ? `Binary: ${s2().binary.path}` : `Binary: ${s2().binary.error}`;
28041
28992
  })());
28042
- insert(_el$69, () => {
28993
+ insert(_el$74, () => {
28994
+ const a2 = s2().account;
28995
+ if (a2.kind === "token")
28996
+ return (() => {
28997
+ var _el$76 = createElement("text");
28998
+ insert(_el$76, () => `\u25CF Token configured (${a2.source})`);
28999
+ effect((_$p) => setProp(_el$76, "fg", theme.success, _$p));
29000
+ return _el$76;
29001
+ })();
29002
+ if (a2.kind === "oauth")
29003
+ return (() => {
29004
+ var _el$77 = createElement("text");
29005
+ insertNode(_el$77, createTextNode(`\u25CF Copilot login detected`));
29006
+ effect((_$p) => setProp(_el$77, "fg", theme.success, _$p));
29007
+ return _el$77;
29008
+ })();
29009
+ return (() => {
29010
+ var _el$79 = createElement("text");
29011
+ insertNode(_el$79, createTextNode(`\u25CB Not logged in`));
29012
+ effect((_$p) => setProp(_el$79, "fg", theme.textMuted, _$p));
29013
+ return _el$79;
29014
+ })();
29015
+ }, null);
29016
+ insert(_el$74, createComponent2(Show, {
29017
+ get when() {
29018
+ return s2().accountError;
29019
+ },
29020
+ children: (err) => (() => {
29021
+ var _el$81 = createElement("text");
29022
+ setProp(_el$81, "wrapMode", "word");
29023
+ insert(_el$81, () => `! ${err()}`);
29024
+ effect((_$p) => setProp(_el$81, "fg", theme.warning, _$p));
29025
+ return _el$81;
29026
+ })()
29027
+ }), null);
29028
+ effect((_$p) => setProp(_el$75, "fg", s2().binary.found ? theme.textMuted : theme.warning, _$p));
29029
+ return _el$74;
29030
+ })()
29031
+ }), null);
29032
+ insertNode(_el$55, _el$56);
29033
+ setProp(_el$55, "flexDirection", "column");
29034
+ setProp(_el$55, "gap", 0);
29035
+ insertNode(_el$56, createTextNode(`gemini`));
29036
+ insert(_el$55, createComponent2(Show, {
29037
+ get when() {
29038
+ return props.geminiStatus() === null;
29039
+ },
29040
+ get children() {
29041
+ var _el$58 = createElement("text");
29042
+ insertNode(_el$58, createTextNode(`Checking\u2026`));
29043
+ effect((_$p) => setProp(_el$58, "fg", theme.textMuted, _$p));
29044
+ return _el$58;
29045
+ }
29046
+ }), null);
29047
+ insert(_el$55, createComponent2(Show, {
29048
+ get when() {
29049
+ return props.geminiStatus();
29050
+ },
29051
+ children: (s2) => (() => {
29052
+ var _el$82 = createElement("box"), _el$83 = createElement("text");
29053
+ insertNode(_el$82, _el$83);
29054
+ setProp(_el$82, "flexDirection", "column");
29055
+ setProp(_el$82, "gap", 0);
29056
+ setProp(_el$83, "wrapMode", "word");
29057
+ insert(_el$83, (() => {
29058
+ var _c$4 = memo2(() => !!s2().binary.found);
29059
+ return () => _c$4() ? `Binary: ${s2().binary.path}` : `Binary: ${s2().binary.error}`;
29060
+ })());
29061
+ insert(_el$82, () => {
28043
29062
  const a2 = s2().account;
28044
29063
  if (a2.kind === "google") {
28045
29064
  const tail = a2.authType ? ` (${a2.authType})` : "";
28046
29065
  return (() => {
28047
- var _el$71 = createElement("text");
28048
- setProp(_el$71, "wrapMode", "word");
28049
- insert(_el$71, () => `\u25CF Google login${a2.email ? `: ${a2.email}` : ""}${tail}`);
28050
- effect((_$p) => setProp(_el$71, "fg", theme.success, _$p));
28051
- return _el$71;
29066
+ var _el$84 = createElement("text");
29067
+ setProp(_el$84, "wrapMode", "word");
29068
+ insert(_el$84, () => `\u25CF Google login${a2.email ? `: ${a2.email}` : ""}${tail}`);
29069
+ effect((_$p) => setProp(_el$84, "fg", theme.success, _$p));
29070
+ return _el$84;
28052
29071
  })();
28053
29072
  }
28054
29073
  if (a2.kind === "apikey")
28055
29074
  return (() => {
28056
- var _el$72 = createElement("text");
28057
- insertNode(_el$72, createTextNode(`\u25CF Gemini API key configured`));
28058
- effect((_$p) => setProp(_el$72, "fg", theme.success, _$p));
28059
- return _el$72;
29075
+ var _el$85 = createElement("text");
29076
+ insertNode(_el$85, createTextNode(`\u25CF Gemini API key configured`));
29077
+ effect((_$p) => setProp(_el$85, "fg", theme.success, _$p));
29078
+ return _el$85;
28060
29079
  })();
28061
29080
  if (a2.kind === "vertex") {
28062
29081
  const tail = [a2.project, a2.location].filter((x2) => !!x2).join(" \xB7 ");
28063
29082
  return (() => {
28064
- var _el$74 = createElement("text");
28065
- setProp(_el$74, "wrapMode", "word");
28066
- insert(_el$74, `\u25CF Vertex AI configured${tail ? ` (${tail})` : ""}`);
28067
- effect((_$p) => setProp(_el$74, "fg", theme.success, _$p));
28068
- return _el$74;
29083
+ var _el$87 = createElement("text");
29084
+ setProp(_el$87, "wrapMode", "word");
29085
+ insert(_el$87, `\u25CF Vertex AI configured${tail ? ` (${tail})` : ""}`);
29086
+ effect((_$p) => setProp(_el$87, "fg", theme.success, _$p));
29087
+ return _el$87;
28069
29088
  })();
28070
29089
  }
28071
29090
  return (() => {
28072
- var _el$75 = createElement("text");
28073
- insertNode(_el$75, createTextNode(`\u25CB Not logged in`));
28074
- effect((_$p) => setProp(_el$75, "fg", theme.textMuted, _$p));
28075
- return _el$75;
29091
+ var _el$88 = createElement("text");
29092
+ insertNode(_el$88, createTextNode(`\u25CB Not logged in`));
29093
+ effect((_$p) => setProp(_el$88, "fg", theme.textMuted, _$p));
29094
+ return _el$88;
28076
29095
  })();
28077
29096
  }, null);
28078
- insert(_el$69, createComponent2(Show, {
29097
+ insert(_el$82, createComponent2(Show, {
28079
29098
  get when() {
28080
29099
  return s2().accountError;
28081
29100
  },
28082
29101
  children: (err) => (() => {
28083
- var _el$77 = createElement("text");
28084
- setProp(_el$77, "wrapMode", "word");
28085
- insert(_el$77, () => `! ${err()}`);
28086
- effect((_$p) => setProp(_el$77, "fg", theme.warning, _$p));
28087
- return _el$77;
29102
+ var _el$90 = createElement("text");
29103
+ setProp(_el$90, "wrapMode", "word");
29104
+ insert(_el$90, () => `! ${err()}`);
29105
+ effect((_$p) => setProp(_el$90, "fg", theme.warning, _$p));
29106
+ return _el$90;
28088
29107
  })()
28089
29108
  }), null);
28090
- effect((_$p) => setProp(_el$70, "fg", s2().binary.found ? theme.textMuted : theme.warning, _$p));
28091
- return _el$69;
29109
+ effect((_$p) => setProp(_el$83, "fg", s2().binary.found ? theme.textMuted : theme.warning, _$p));
29110
+ return _el$82;
28092
29111
  })()
28093
29112
  }), null);
28094
29113
  effect((_p$) => {
28095
- var _v$29 = theme.text, _v$30 = TextAttributes9.BOLD, _v$31 = theme.textMuted, _v$32 = theme.text, _v$33 = TextAttributes9.BOLD, _v$34 = theme.text, _v$35 = TextAttributes9.BOLD, _v$36 = theme.text, _v$37 = TextAttributes9.BOLD;
29114
+ var _v$29 = theme.text, _v$30 = TextAttributes9.BOLD, _v$31 = theme.textMuted, _v$32 = theme.text, _v$33 = TextAttributes9.BOLD, _v$34 = theme.text, _v$35 = TextAttributes9.BOLD, _v$36 = theme.text, _v$37 = TextAttributes9.BOLD, _v$38 = theme.text, _v$39 = TextAttributes9.BOLD;
28096
29115
  _v$29 !== _p$.e && (_p$.e = setProp(_el$36, "fg", _v$29, _p$.e));
28097
29116
  _v$30 !== _p$.t && (_p$.t = setProp(_el$36, "attributes", _v$30, _p$.t));
28098
29117
  _v$31 !== _p$.a && (_p$.a = setProp(_el$38, "fg", _v$31, _p$.a));
@@ -28102,6 +29121,8 @@ function AccountsSettingsSection(props) {
28102
29121
  _v$35 !== _p$.s && (_p$.s = setProp(_el$46, "attributes", _v$35, _p$.s));
28103
29122
  _v$36 !== _p$.h && (_p$.h = setProp(_el$51, "fg", _v$36, _p$.h));
28104
29123
  _v$37 !== _p$.r && (_p$.r = setProp(_el$51, "attributes", _v$37, _p$.r));
29124
+ _v$38 !== _p$.d && (_p$.d = setProp(_el$56, "fg", _v$38, _p$.d));
29125
+ _v$39 !== _p$.l && (_p$.l = setProp(_el$56, "attributes", _v$39, _p$.l));
28105
29126
  return _p$;
28106
29127
  }, {
28107
29128
  e: undefined,
@@ -28112,7 +29133,9 @@ function AccountsSettingsSection(props) {
28112
29133
  n: undefined,
28113
29134
  s: undefined,
28114
29135
  h: undefined,
28115
- r: undefined
29136
+ r: undefined,
29137
+ d: undefined,
29138
+ l: undefined
28116
29139
  });
28117
29140
  return _el$35;
28118
29141
  })();
@@ -28122,60 +29145,60 @@ function CodexSettingsSection(props) {
28122
29145
  theme
28123
29146
  } = useTheme();
28124
29147
  return (() => {
28125
- var _el$78 = createElement("box"), _el$79 = createElement("text"), _el$81 = createElement("text"), _el$83 = createElement("text"), _el$85 = createElement("box");
28126
- insertNode(_el$78, _el$79);
28127
- insertNode(_el$78, _el$81);
28128
- insertNode(_el$78, _el$83);
28129
- insertNode(_el$78, _el$85);
28130
- setProp(_el$78, "flexDirection", "column");
28131
- setProp(_el$78, "gap", 1);
28132
- insertNode(_el$79, createTextNode(`Codex backend`));
28133
- insertNode(_el$81, createTextNode(`App server is the default path: kobe talks to \`codex app-server\` over JSON-RPC, so sessions and token usage come from Codex directly. \`exec --json\` starts one Codex process per turn and resumes the saved session id; keep it as a fallback.`));
28134
- setProp(_el$81, "wrapMode", "word");
28135
- insert(_el$78, createComponent2(Show, {
29148
+ var _el$91 = createElement("box"), _el$92 = createElement("text"), _el$94 = createElement("text"), _el$96 = createElement("text"), _el$98 = createElement("box");
29149
+ insertNode(_el$91, _el$92);
29150
+ insertNode(_el$91, _el$94);
29151
+ insertNode(_el$91, _el$96);
29152
+ insertNode(_el$91, _el$98);
29153
+ setProp(_el$91, "flexDirection", "column");
29154
+ setProp(_el$91, "gap", 1);
29155
+ insertNode(_el$92, createTextNode(`Codex backend`));
29156
+ insertNode(_el$94, createTextNode(`App server is the default path: kobe talks to \`codex app-server\` over JSON-RPC, so sessions and token usage come from Codex directly. \`exec --json\` starts one Codex process per turn and resumes the saved session id; keep it as a fallback.`));
29157
+ setProp(_el$94, "wrapMode", "word");
29158
+ insert(_el$91, createComponent2(Show, {
28136
29159
  get when() {
28137
29160
  return codexEnvOverride();
28138
29161
  },
28139
29162
  children: (override) => (() => {
28140
- var _el$86 = createElement("text");
28141
- setProp(_el$86, "wrapMode", "word");
28142
- insert(_el$86, () => `Environment override is active: ${override()}. Unset KOBE_CODEX_BACKEND / KOBE_CODEX_APP_SERVER before the saved setting is used.`);
28143
- effect((_$p) => setProp(_el$86, "fg", theme.warning, _$p));
28144
- return _el$86;
29163
+ var _el$99 = createElement("text");
29164
+ setProp(_el$99, "wrapMode", "word");
29165
+ insert(_el$99, () => `Environment override is active: ${override()}. Unset KOBE_CODEX_BACKEND / KOBE_CODEX_APP_SERVER before the saved setting is used.`);
29166
+ effect((_$p) => setProp(_el$99, "fg", theme.warning, _$p));
29167
+ return _el$99;
28145
29168
  })()
28146
- }), _el$83);
28147
- insertNode(_el$83, createTextNode(`Changing this setting applies after Restart backend or the next kobe launch.`));
28148
- setProp(_el$83, "wrapMode", "word");
28149
- setProp(_el$85, "flexDirection", "column");
28150
- setProp(_el$85, "gap", 0);
28151
- insert(_el$85, createComponent2(For, {
29169
+ }), _el$96);
29170
+ insertNode(_el$96, createTextNode(`Changing this setting applies after Restart backend or the next kobe launch.`));
29171
+ setProp(_el$96, "wrapMode", "word");
29172
+ setProp(_el$98, "flexDirection", "column");
29173
+ setProp(_el$98, "gap", 0);
29174
+ insert(_el$98, createComponent2(For, {
28152
29175
  each: CODEX_BACKENDS,
28153
29176
  children: (backend, i2) => {
28154
29177
  const isCursor = () => props.level() === "body" && props.bodyRow() === i2();
28155
29178
  const isSelected = () => props.codexBackend() === backend;
28156
29179
  return (() => {
28157
- var _el$87 = createElement("box"), _el$88 = createElement("text"), _el$89 = createElement("text");
28158
- insertNode(_el$87, _el$88);
28159
- insertNode(_el$87, _el$89);
28160
- setProp(_el$87, "flexDirection", "column");
28161
- setProp(_el$87, "paddingLeft", 1);
28162
- setProp(_el$87, "paddingRight", 1);
28163
- setProp(_el$87, "onMouseUp", () => {
29180
+ var _el$100 = createElement("box"), _el$101 = createElement("text"), _el$102 = createElement("text");
29181
+ insertNode(_el$100, _el$101);
29182
+ insertNode(_el$100, _el$102);
29183
+ setProp(_el$100, "flexDirection", "column");
29184
+ setProp(_el$100, "paddingLeft", 1);
29185
+ setProp(_el$100, "paddingRight", 1);
29186
+ setProp(_el$100, "onMouseUp", () => {
28164
29187
  props.setLevel("body");
28165
29188
  props.setBodyRow(i2());
28166
29189
  props.setCodexBackend(backend);
28167
29190
  });
28168
- setProp(_el$88, "wrapMode", "none");
28169
- insert(_el$88, () => isSelected() ? "\u25CF " : " ", null);
28170
- insert(_el$88, () => CODEX_BACKEND_LABEL[backend], null);
28171
- setProp(_el$89, "wrapMode", "word");
28172
- insert(_el$89, () => CODEX_BACKEND_DESCRIPTION[backend]);
29191
+ setProp(_el$101, "wrapMode", "none");
29192
+ insert(_el$101, () => isSelected() ? "\u25CF " : " ", null);
29193
+ insert(_el$101, () => CODEX_BACKEND_LABEL[backend], null);
29194
+ setProp(_el$102, "wrapMode", "word");
29195
+ insert(_el$102, () => CODEX_BACKEND_DESCRIPTION[backend]);
28173
29196
  effect((_p$) => {
28174
- var _v$42 = isCursor() ? theme.primary : undefined, _v$43 = isCursor() ? theme.selectedListItemText : isSelected() ? theme.accent : theme.text, _v$44 = isCursor() || isSelected() ? TextAttributes9.BOLD : undefined, _v$45 = isCursor() ? theme.selectedListItemText : theme.textMuted;
28175
- _v$42 !== _p$.e && (_p$.e = setProp(_el$87, "backgroundColor", _v$42, _p$.e));
28176
- _v$43 !== _p$.t && (_p$.t = setProp(_el$88, "fg", _v$43, _p$.t));
28177
- _v$44 !== _p$.a && (_p$.a = setProp(_el$88, "attributes", _v$44, _p$.a));
28178
- _v$45 !== _p$.o && (_p$.o = setProp(_el$89, "fg", _v$45, _p$.o));
29197
+ var _v$44 = isCursor() ? theme.primary : undefined, _v$45 = isCursor() ? theme.selectedListItemText : isSelected() ? theme.accent : theme.text, _v$46 = isCursor() || isSelected() ? TextAttributes9.BOLD : undefined, _v$47 = isCursor() ? theme.selectedListItemText : theme.textMuted;
29198
+ _v$44 !== _p$.e && (_p$.e = setProp(_el$100, "backgroundColor", _v$44, _p$.e));
29199
+ _v$45 !== _p$.t && (_p$.t = setProp(_el$101, "fg", _v$45, _p$.t));
29200
+ _v$46 !== _p$.a && (_p$.a = setProp(_el$101, "attributes", _v$46, _p$.a));
29201
+ _v$47 !== _p$.o && (_p$.o = setProp(_el$102, "fg", _v$47, _p$.o));
28179
29202
  return _p$;
28180
29203
  }, {
28181
29204
  e: undefined,
@@ -28183,16 +29206,16 @@ function CodexSettingsSection(props) {
28183
29206
  a: undefined,
28184
29207
  o: undefined
28185
29208
  });
28186
- return _el$87;
29209
+ return _el$100;
28187
29210
  })();
28188
29211
  }
28189
29212
  }));
28190
29213
  effect((_p$) => {
28191
- var _v$38 = theme.text, _v$39 = TextAttributes9.BOLD, _v$40 = theme.textMuted, _v$41 = theme.textMuted;
28192
- _v$38 !== _p$.e && (_p$.e = setProp(_el$79, "fg", _v$38, _p$.e));
28193
- _v$39 !== _p$.t && (_p$.t = setProp(_el$79, "attributes", _v$39, _p$.t));
28194
- _v$40 !== _p$.a && (_p$.a = setProp(_el$81, "fg", _v$40, _p$.a));
28195
- _v$41 !== _p$.o && (_p$.o = setProp(_el$83, "fg", _v$41, _p$.o));
29214
+ var _v$40 = theme.text, _v$41 = TextAttributes9.BOLD, _v$42 = theme.textMuted, _v$43 = theme.textMuted;
29215
+ _v$40 !== _p$.e && (_p$.e = setProp(_el$92, "fg", _v$40, _p$.e));
29216
+ _v$41 !== _p$.t && (_p$.t = setProp(_el$92, "attributes", _v$41, _p$.t));
29217
+ _v$42 !== _p$.a && (_p$.a = setProp(_el$94, "fg", _v$42, _p$.a));
29218
+ _v$43 !== _p$.o && (_p$.o = setProp(_el$96, "fg", _v$43, _p$.o));
28196
29219
  return _p$;
28197
29220
  }, {
28198
29221
  e: undefined,
@@ -28200,7 +29223,7 @@ function CodexSettingsSection(props) {
28200
29223
  a: undefined,
28201
29224
  o: undefined
28202
29225
  });
28203
- return _el$78;
29226
+ return _el$91;
28204
29227
  })();
28205
29228
  }
28206
29229
  function DevSettingsSection(props) {
@@ -28210,58 +29233,58 @@ function DevSettingsSection(props) {
28210
29233
  const resetIsCursor = () => props.level() === "body" && props.bodyRow() === 0;
28211
29234
  const restartIsCursor = () => props.level() === "body" && props.bodyRow() === 1;
28212
29235
  return (() => {
28213
- var _el$90 = createElement("box"), _el$91 = createElement("text"), _el$93 = createElement("text"), _el$95 = createElement("box"), _el$96 = createElement("text");
28214
- insertNode(_el$90, _el$91);
28215
- insertNode(_el$90, _el$93);
28216
- insertNode(_el$90, _el$95);
28217
- setProp(_el$90, "flexDirection", "column");
28218
- setProp(_el$90, "gap", 1);
28219
- insertNode(_el$91, createTextNode(`Reset UI state`));
28220
- insertNode(_el$93, createTextNode(`Clears ~/.config/kobe/state.json and ~/.kobe/tasks.json, then quits kobe \u2014 relaunch to start fresh. Working session / Archive lists, pane sizes, theme, model picks all reset. Worktrees on disk and Claude Code session history are not touched.`));
28221
- setProp(_el$93, "wrapMode", "word");
28222
- insertNode(_el$95, _el$96);
28223
- setProp(_el$95, "flexDirection", "row");
28224
- setProp(_el$95, "paddingLeft", 1);
28225
- setProp(_el$95, "paddingRight", 1);
28226
- setProp(_el$95, "onMouseUp", () => {
29236
+ var _el$103 = createElement("box"), _el$104 = createElement("text"), _el$106 = createElement("text"), _el$108 = createElement("box"), _el$109 = createElement("text");
29237
+ insertNode(_el$103, _el$104);
29238
+ insertNode(_el$103, _el$106);
29239
+ insertNode(_el$103, _el$108);
29240
+ setProp(_el$103, "flexDirection", "column");
29241
+ setProp(_el$103, "gap", 1);
29242
+ insertNode(_el$104, createTextNode(`Reset UI state`));
29243
+ insertNode(_el$106, createTextNode(`Clears ~/.config/kobe/state.json and ~/.kobe/tasks.json, then quits kobe \u2014 relaunch to start fresh. Working session / Archive lists, pane sizes, theme, model picks all reset. Worktrees on disk and Claude Code session history are not touched.`));
29244
+ setProp(_el$106, "wrapMode", "word");
29245
+ insertNode(_el$108, _el$109);
29246
+ setProp(_el$108, "flexDirection", "row");
29247
+ setProp(_el$108, "paddingLeft", 1);
29248
+ setProp(_el$108, "paddingRight", 1);
29249
+ setProp(_el$108, "onMouseUp", () => {
28227
29250
  props.setLevel("body");
28228
29251
  props.setBodyRow(0);
28229
29252
  props.confirmReset();
28230
29253
  });
28231
- insertNode(_el$96, createTextNode(`[enter] Reset`));
28232
- insert(_el$90, createComponent2(Show, {
29254
+ insertNode(_el$109, createTextNode(`[enter] Reset`));
29255
+ insert(_el$103, createComponent2(Show, {
28233
29256
  get when() {
28234
29257
  return props.hasDaemon;
28235
29258
  },
28236
29259
  get children() {
28237
- var _el$98 = createElement("box"), _el$99 = createElement("text"), _el$101 = createElement("text"), _el$103 = createElement("box"), _el$104 = createElement("text");
28238
- insertNode(_el$98, _el$99);
28239
- insertNode(_el$98, _el$101);
28240
- insertNode(_el$98, _el$103);
28241
- setProp(_el$98, "flexDirection", "column");
28242
- setProp(_el$98, "gap", 0);
28243
- setProp(_el$98, "paddingTop", 1);
28244
- insertNode(_el$99, createTextNode(`Restart backend`));
28245
- insertNode(_el$101, createTextNode(`Stops the kobe daemon and quits this kobe window so the next launch spawns a fresh daemon \u2014 picks up daemon / orchestrator / engine edits without a process kill. Other attached kobe windows will lose their connection too.`));
28246
- setProp(_el$101, "wrapMode", "word");
28247
- insertNode(_el$103, _el$104);
28248
- setProp(_el$103, "flexDirection", "row");
28249
- setProp(_el$103, "paddingLeft", 1);
28250
- setProp(_el$103, "paddingRight", 1);
28251
- setProp(_el$103, "onMouseUp", () => {
29260
+ var _el$111 = createElement("box"), _el$112 = createElement("text"), _el$114 = createElement("text"), _el$116 = createElement("box"), _el$117 = createElement("text");
29261
+ insertNode(_el$111, _el$112);
29262
+ insertNode(_el$111, _el$114);
29263
+ insertNode(_el$111, _el$116);
29264
+ setProp(_el$111, "flexDirection", "column");
29265
+ setProp(_el$111, "gap", 0);
29266
+ setProp(_el$111, "paddingTop", 1);
29267
+ insertNode(_el$112, createTextNode(`Restart backend`));
29268
+ insertNode(_el$114, createTextNode(`Stops the kobe daemon and quits this kobe window so the next launch spawns a fresh daemon \u2014 picks up daemon / orchestrator / engine edits without a process kill. Other attached kobe windows will lose their connection too.`));
29269
+ setProp(_el$114, "wrapMode", "word");
29270
+ insertNode(_el$116, _el$117);
29271
+ setProp(_el$116, "flexDirection", "row");
29272
+ setProp(_el$116, "paddingLeft", 1);
29273
+ setProp(_el$116, "paddingRight", 1);
29274
+ setProp(_el$116, "onMouseUp", () => {
28252
29275
  props.setLevel("body");
28253
29276
  props.setBodyRow(1);
28254
29277
  props.confirmRestartDaemon();
28255
29278
  });
28256
- insertNode(_el$104, createTextNode(`[enter] Restart`));
29279
+ insertNode(_el$117, createTextNode(`[enter] Restart`));
28257
29280
  effect((_p$) => {
28258
- var _v$46 = theme.text, _v$47 = TextAttributes9.BOLD, _v$48 = theme.textMuted, _v$49 = restartIsCursor() ? theme.primary : theme.backgroundElement, _v$50 = restartIsCursor() ? theme.selectedListItemText : theme.accent, _v$51 = TextAttributes9.BOLD;
28259
- _v$46 !== _p$.e && (_p$.e = setProp(_el$99, "fg", _v$46, _p$.e));
28260
- _v$47 !== _p$.t && (_p$.t = setProp(_el$99, "attributes", _v$47, _p$.t));
28261
- _v$48 !== _p$.a && (_p$.a = setProp(_el$101, "fg", _v$48, _p$.a));
28262
- _v$49 !== _p$.o && (_p$.o = setProp(_el$103, "backgroundColor", _v$49, _p$.o));
28263
- _v$50 !== _p$.i && (_p$.i = setProp(_el$104, "fg", _v$50, _p$.i));
28264
- _v$51 !== _p$.n && (_p$.n = setProp(_el$104, "attributes", _v$51, _p$.n));
29281
+ var _v$48 = theme.text, _v$49 = TextAttributes9.BOLD, _v$50 = theme.textMuted, _v$51 = restartIsCursor() ? theme.primary : theme.backgroundElement, _v$52 = restartIsCursor() ? theme.selectedListItemText : theme.accent, _v$53 = TextAttributes9.BOLD;
29282
+ _v$48 !== _p$.e && (_p$.e = setProp(_el$112, "fg", _v$48, _p$.e));
29283
+ _v$49 !== _p$.t && (_p$.t = setProp(_el$112, "attributes", _v$49, _p$.t));
29284
+ _v$50 !== _p$.a && (_p$.a = setProp(_el$114, "fg", _v$50, _p$.a));
29285
+ _v$51 !== _p$.o && (_p$.o = setProp(_el$116, "backgroundColor", _v$51, _p$.o));
29286
+ _v$52 !== _p$.i && (_p$.i = setProp(_el$117, "fg", _v$52, _p$.i));
29287
+ _v$53 !== _p$.n && (_p$.n = setProp(_el$117, "attributes", _v$53, _p$.n));
28265
29288
  return _p$;
28266
29289
  }, {
28267
29290
  e: undefined,
@@ -28271,17 +29294,17 @@ function DevSettingsSection(props) {
28271
29294
  i: undefined,
28272
29295
  n: undefined
28273
29296
  });
28274
- return _el$98;
29297
+ return _el$111;
28275
29298
  }
28276
29299
  }), null);
28277
29300
  effect((_p$) => {
28278
- var _v$52 = theme.text, _v$53 = TextAttributes9.BOLD, _v$54 = theme.textMuted, _v$55 = resetIsCursor() ? theme.primary : theme.backgroundElement, _v$56 = resetIsCursor() ? theme.selectedListItemText : theme.warning, _v$57 = TextAttributes9.BOLD;
28279
- _v$52 !== _p$.e && (_p$.e = setProp(_el$91, "fg", _v$52, _p$.e));
28280
- _v$53 !== _p$.t && (_p$.t = setProp(_el$91, "attributes", _v$53, _p$.t));
28281
- _v$54 !== _p$.a && (_p$.a = setProp(_el$93, "fg", _v$54, _p$.a));
28282
- _v$55 !== _p$.o && (_p$.o = setProp(_el$95, "backgroundColor", _v$55, _p$.o));
28283
- _v$56 !== _p$.i && (_p$.i = setProp(_el$96, "fg", _v$56, _p$.i));
28284
- _v$57 !== _p$.n && (_p$.n = setProp(_el$96, "attributes", _v$57, _p$.n));
29301
+ var _v$54 = theme.text, _v$55 = TextAttributes9.BOLD, _v$56 = theme.textMuted, _v$57 = resetIsCursor() ? theme.primary : theme.backgroundElement, _v$58 = resetIsCursor() ? theme.selectedListItemText : theme.warning, _v$59 = TextAttributes9.BOLD;
29302
+ _v$54 !== _p$.e && (_p$.e = setProp(_el$104, "fg", _v$54, _p$.e));
29303
+ _v$55 !== _p$.t && (_p$.t = setProp(_el$104, "attributes", _v$55, _p$.t));
29304
+ _v$56 !== _p$.a && (_p$.a = setProp(_el$106, "fg", _v$56, _p$.a));
29305
+ _v$57 !== _p$.o && (_p$.o = setProp(_el$108, "backgroundColor", _v$57, _p$.o));
29306
+ _v$58 !== _p$.i && (_p$.i = setProp(_el$109, "fg", _v$58, _p$.i));
29307
+ _v$59 !== _p$.n && (_p$.n = setProp(_el$109, "attributes", _v$59, _p$.n));
28285
29308
  return _p$;
28286
29309
  }, {
28287
29310
  e: undefined,
@@ -28291,7 +29314,7 @@ function DevSettingsSection(props) {
28291
29314
  i: undefined,
28292
29315
  n: undefined
28293
29316
  });
28294
- return _el$90;
29317
+ return _el$103;
28295
29318
  })();
28296
29319
  }
28297
29320
  var init_sections = __esm(() => {
@@ -28327,6 +29350,7 @@ function SettingsDialog(props) {
28327
29350
  const [claudeStatus, setClaudeStatus] = createSignal(null);
28328
29351
  const [codexStatus, setCodexStatus] = createSignal(null);
28329
29352
  const [geminiStatus, setGeminiStatus] = createSignal(null);
29353
+ const [copilotStatus, setCopilotStatus] = createSignal(null);
28330
29354
  onMount(() => {
28331
29355
  detectClaudeAccount().then(setClaudeStatus).catch((err) => {
28332
29356
  console.error("kobe: detectClaudeAccount threw:", err);
@@ -28364,6 +29388,18 @@ function SettingsDialog(props) {
28364
29388
  }
28365
29389
  });
28366
29390
  });
29391
+ detectCopilotAccount().then(setCopilotStatus).catch((err) => {
29392
+ console.error("kobe: detectCopilotAccount threw:", err);
29393
+ setCopilotStatus({
29394
+ binary: {
29395
+ found: false,
29396
+ error: String(err)
29397
+ },
29398
+ account: {
29399
+ kind: "none"
29400
+ }
29401
+ });
29402
+ });
28367
29403
  });
28368
29404
  function bodyRowCount2() {
28369
29405
  return bodyRowCount(section(), themeNames().length, FOCUS_ACCENT_SLOTS.length, hasDaemon);
@@ -28570,7 +29606,8 @@ function SettingsDialog(props) {
28570
29606
  return createComponent2(AccountsSettingsSection, {
28571
29607
  claudeStatus,
28572
29608
  codexStatus,
28573
- geminiStatus
29609
+ geminiStatus,
29610
+ copilotStatus
28574
29611
  });
28575
29612
  }
28576
29613
  }), null);
@@ -28745,7 +29782,7 @@ var pulse_default = "../pulse-n3cq1btw.wav";
28745
29782
  var init_pulse = () => {};
28746
29783
 
28747
29784
  // src/tui/lib/sound.ts
28748
- import { existsSync as existsSync9, mkdirSync as mkdirSync4 } from "fs";
29785
+ import { existsSync as existsSync10, mkdirSync as mkdirSync4 } from "fs";
28749
29786
  import { tmpdir as tmpdir4 } from "os";
28750
29787
  import { basename as basename2, isAbsolute, join as join19, resolve as resolve3 } from "path";
28751
29788
  function args(player, file, volume) {
@@ -28768,9 +29805,9 @@ function args(player, file, volume) {
28768
29805
  function pickPlayer() {
28769
29806
  if (cachedPlayer !== undefined)
28770
29807
  return cachedPlayer;
28771
- const path17 = process.env.PATH ?? "";
28772
- const segments = path17.split(":").filter(Boolean);
28773
- cachedPlayer = PLAYERS.find((p2) => segments.some((dir) => existsSync9(join19(dir, p2)))) ?? null;
29808
+ const path20 = process.env.PATH ?? "";
29809
+ const segments = path20.split(":").filter(Boolean);
29810
+ cachedPlayer = PLAYERS.find((p2) => segments.some((dir) => existsSync10(join19(dir, p2)))) ?? null;
28774
29811
  return cachedPlayer;
28775
29812
  }
28776
29813
  async function ensureAsset() {
@@ -28789,9 +29826,9 @@ function pulse(volume = 0.4) {
28789
29826
  const player = pickPlayer();
28790
29827
  if (!player)
28791
29828
  return;
28792
- ensureAsset().then((path17) => {
29829
+ ensureAsset().then((path20) => {
28793
29830
  try {
28794
- const proc = Bun.spawn(args(player, path17, volume), {
29831
+ const proc = Bun.spawn(args(player, path20, volume), {
28795
29832
  stdin: "ignore",
28796
29833
  stdout: "ignore",
28797
29834
  stderr: "ignore"
@@ -30153,11 +31190,11 @@ function StatusBar() {
30153
31190
  }
30154
31191
  };
30155
31192
  const leftHints = () => KobeKeymap.filter((b2) => {
30156
- if (!b2.hint || b2.hint.pin)
31193
+ if (!b2.hint || b2.hint.pin || b2.hint.status === false)
30157
31194
  return false;
30158
31195
  return b2.scope === focus.focused();
30159
31196
  });
30160
- const rightHints = KobeKeymap.filter((b2) => b2.hint?.pin === "right");
31197
+ const rightHints = KobeKeymap.filter((b2) => b2.hint?.pin === "right" && b2.hint.status !== false);
30161
31198
  return (() => {
30162
31199
  var _el$6 = createElement("box"), _el$7 = createElement("box"), _el$8 = createElement("text"), _el$9 = createElement("box");
30163
31200
  insertNode(_el$6, _el$7);
@@ -30459,8 +31496,8 @@ var init_create_pr_button = __esm(() => {
30459
31496
  });
30460
31497
 
30461
31498
  // src/tui/lib/worktree-opener.ts
30462
- import { spawn as spawn14 } from "child_process";
30463
- import { existsSync as existsSync10 } from "fs";
31499
+ import { spawn as spawn15 } from "child_process";
31500
+ import { existsSync as existsSync11 } from "fs";
30464
31501
  import { basename as basename4, delimiter, isAbsolute as isAbsolute2, join as join20 } from "path";
30465
31502
  function executableOnPath(command, env, exists) {
30466
31503
  if (isAbsolute2(command))
@@ -30489,7 +31526,7 @@ function labelForOverride(command) {
30489
31526
  function detectWorktreeOpener(deps = {}) {
30490
31527
  const env = deps.env ?? process.env;
30491
31528
  const platform2 = deps.platform ?? process.platform;
30492
- const exists = deps.exists ?? existsSync10;
31529
+ const exists = deps.exists ?? existsSync11;
30493
31530
  const override = env.KOBE_OPEN_EDITOR?.trim();
30494
31531
  if (override) {
30495
31532
  return { id: "env", label: labelForOverride(override), command: override, args: [] };
@@ -30501,7 +31538,7 @@ function detectWorktreeOpener(deps = {}) {
30501
31538
  }
30502
31539
  if (platform2 === "darwin" && executableOnPath("open", env, exists)) {
30503
31540
  for (const app of MAC_APP_CANDIDATES) {
30504
- if (app.paths.some((path17) => exists(path17))) {
31541
+ if (app.paths.some((path20) => exists(path20))) {
30505
31542
  return { id: app.id, label: app.label, command: "open", args: ["-a", app.appName] };
30506
31543
  }
30507
31544
  }
@@ -30518,7 +31555,7 @@ function buildOpenWorktreeCommand(worktreePath, opener) {
30518
31555
  function openWorktree(worktreePath, opener, deps = {}) {
30519
31556
  if (!worktreePath)
30520
31557
  return false;
30521
- const spawnFn = deps.spawn ?? spawn14;
31558
+ const spawnFn = deps.spawn ?? spawn15;
30522
31559
  const [command, args2] = buildOpenWorktreeCommand(worktreePath, opener);
30523
31560
  try {
30524
31561
  const child = spawnFn(command, args2, { detached: true, stdio: "ignore" });
@@ -31699,7 +32736,7 @@ var init_update_dialog = __esm(() => {
31699
32736
  });
31700
32737
 
31701
32738
  // src/tui/component/top-bar.tsx
31702
- import { spawnSync as spawnSync11 } from "child_process";
32739
+ import { spawnSync as spawnSync12 } from "child_process";
31703
32740
  import { TextAttributes as TextAttributes21 } from "@opentui/core";
31704
32741
  function TopBar(props) {
31705
32742
  const {
@@ -31741,7 +32778,7 @@ function TopBar(props) {
31741
32778
  `);
31742
32779
  process.stderr.write(`running: ${UPDATE_COMMAND}
31743
32780
  `);
31744
- const result = spawnSync11("sh", ["-c", UPDATE_COMMAND], {
32781
+ const result = spawnSync12("sh", ["-c", UPDATE_COMMAND], {
31745
32782
  stdio: "inherit"
31746
32783
  });
31747
32784
  if (result.error) {
@@ -32601,10 +33638,10 @@ var init_use_pane_sizes = __esm(() => {
32601
33638
  });
32602
33639
 
32603
33640
  // src/tui/component/new-task-dialog/state.ts
32604
- import { spawn as spawn15 } from "child_process";
33641
+ import { spawn as spawn16 } from "child_process";
32605
33642
  import * as fs5 from "fs";
32606
33643
  import * as os from "os";
32607
- import * as path17 from "path";
33644
+ import * as path20 from "path";
32608
33645
  function nextDialogTab(tab) {
32609
33646
  return tab === "existing" ? "clone" : "existing";
32610
33647
  }
@@ -32685,17 +33722,17 @@ function validateRepoPath(repo) {
32685
33722
  const trimmed = repo.trim();
32686
33723
  if (!trimmed)
32687
33724
  return "repo path is required";
32688
- let stat9;
33725
+ let stat10;
32689
33726
  try {
32690
- stat9 = fs5.statSync(trimmed);
33727
+ stat10 = fs5.statSync(trimmed);
32691
33728
  } catch {
32692
33729
  return `path does not exist: ${trimmed}`;
32693
33730
  }
32694
- if (!stat9.isDirectory())
33731
+ if (!stat10.isDirectory())
32695
33732
  return `not a directory: ${trimmed}`;
32696
33733
  try {
32697
- const { spawnSync: spawnSync12 } = __require("child_process");
32698
- const out = spawnSync12("git", ["rev-parse", "--git-dir"], {
33734
+ const { spawnSync: spawnSync13 } = __require("child_process");
33735
+ const out = spawnSync13("git", ["rev-parse", "--git-dir"], {
32699
33736
  cwd: trimmed,
32700
33737
  encoding: "utf-8",
32701
33738
  timeout: 2000,
@@ -32712,8 +33749,8 @@ function getCurrentBranch(repo) {
32712
33749
  if (!repo)
32713
33750
  return null;
32714
33751
  try {
32715
- const { spawnSync: spawnSync12 } = __require("child_process");
32716
- const out = spawnSync12("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
33752
+ const { spawnSync: spawnSync13 } = __require("child_process");
33753
+ const out = spawnSync13("git", ["rev-parse", "--abbrev-ref", "HEAD"], {
32717
33754
  cwd: repo,
32718
33755
  encoding: "utf-8",
32719
33756
  timeout: 2000,
@@ -32733,8 +33770,8 @@ function listLocalBranches(repo) {
32733
33770
  if (!repo)
32734
33771
  return [];
32735
33772
  try {
32736
- const { spawnSync: spawnSync12 } = __require("child_process");
32737
- const out = spawnSync12("git", ["for-each-ref", "--format=%(refname:short)", "refs/heads/"], {
33773
+ const { spawnSync: spawnSync13 } = __require("child_process");
33774
+ const out = spawnSync13("git", ["for-each-ref", "--format=%(refname:short)", "refs/heads/"], {
32738
33775
  cwd: repo,
32739
33776
  encoding: "utf-8",
32740
33777
  timeout: 2000
@@ -32855,13 +33892,13 @@ function validateCloneTarget(parentDir, folder) {
32855
33892
  }
32856
33893
  if (!parentStat.isDirectory())
32857
33894
  return `not a directory: ${parentExpanded}`;
32858
- const target = path17.join(parentExpanded, folderTrimmed);
33895
+ const target = path20.join(parentExpanded, folderTrimmed);
32859
33896
  if (fs5.existsSync(target))
32860
33897
  return `target already exists: ${target}`;
32861
33898
  return null;
32862
33899
  }
32863
33900
  function resolveCloneTarget(parentDir, folder) {
32864
- return path17.join(expandHome(parentDir.trim()), folder.trim());
33901
+ return path20.join(expandHome(parentDir.trim()), folder.trim());
32865
33902
  }
32866
33903
  function findAvailableFolderName(parentDir, base) {
32867
33904
  const trimmed = base.trim();
@@ -32871,17 +33908,17 @@ function findAvailableFolderName(parentDir, base) {
32871
33908
  if (!parentExpanded)
32872
33909
  return base;
32873
33910
  try {
32874
- const stat9 = fs5.statSync(parentExpanded);
32875
- if (!stat9.isDirectory())
33911
+ const stat10 = fs5.statSync(parentExpanded);
33912
+ if (!stat10.isDirectory())
32876
33913
  return base;
32877
33914
  } catch {
32878
33915
  return base;
32879
33916
  }
32880
- if (!fs5.existsSync(path17.join(parentExpanded, trimmed)))
33917
+ if (!fs5.existsSync(path20.join(parentExpanded, trimmed)))
32881
33918
  return trimmed;
32882
33919
  for (let n2 = 2;n2 < 1000; n2++) {
32883
33920
  const candidate = `${trimmed}-${n2}`;
32884
- if (!fs5.existsSync(path17.join(parentExpanded, candidate)))
33921
+ if (!fs5.existsSync(path20.join(parentExpanded, candidate)))
32885
33922
  return candidate;
32886
33923
  }
32887
33924
  return trimmed;
@@ -32890,7 +33927,7 @@ function cloneRepo(url, target, onProgress) {
32890
33927
  return new Promise((resolve4) => {
32891
33928
  let stderrBuf = "";
32892
33929
  try {
32893
- const child = spawn15("git", ["clone", "--progress", url, target], {
33930
+ const child = spawn16("git", ["clone", "--progress", url, target], {
32894
33931
  stdio: ["ignore", "ignore", "pipe"]
32895
33932
  });
32896
33933
  child.stderr?.setEncoding("utf-8");
@@ -33758,6 +34795,25 @@ function modelPickerModelOptions(choices, opts = {}) {
33758
34795
  };
33759
34796
  });
33760
34797
  }
34798
+ function modelPickerProviderGroups(choices, opts = {}) {
34799
+ const models = modelPickerModelOptions(choices, { lockedVendor: opts.lockedVendor });
34800
+ const byVendor = new Map;
34801
+ for (const model of models) {
34802
+ const bucket = byVendor.get(model.vendor);
34803
+ if (bucket)
34804
+ bucket.push(model);
34805
+ else
34806
+ byVendor.set(model.vendor, [model]);
34807
+ }
34808
+ return [...byVendor.entries()].map(([vendor, vendorModels]) => ({
34809
+ vendor,
34810
+ label: opts.providerLabelFor?.(vendor) ?? opts.providerLabels?.[vendor] ?? vendor,
34811
+ models: vendorModels
34812
+ }));
34813
+ }
34814
+ function modelPickerDefaultExpandedVendors(currentVendor, lockedVendor) {
34815
+ return new Set([currentVendor ?? lockedVendor ?? "claude"]);
34816
+ }
33761
34817
  function modelPickerEffortOptions(model) {
33762
34818
  return model.choices.map((choice) => ({
33763
34819
  id: choice.id,
@@ -34609,7 +35665,7 @@ function hasModelConfig(config) {
34609
35665
  return config.model !== undefined || config.modelEffort !== undefined || config.vendor !== undefined;
34610
35666
  }
34611
35667
  function isVendor(value) {
34612
- return value === "claude" || value === "codex" || value === "gemini";
35668
+ return value === "claude" || value === "codex" || value === "gemini" || value === "copilot";
34613
35669
  }
34614
35670
  function isModelEffort(value) {
34615
35671
  return value === "none" || value === "minimal" || value === "low" || value === "medium" || value === "high" || value === "xhigh" || value === "max";
@@ -35016,18 +36072,18 @@ function findPreviewablePathRefs(text, files, limit = DEFAULT_LIMIT) {
35016
36072
  return [];
35017
36073
  const matches = [];
35018
36074
  const seen = new Set;
35019
- const sorted = [...files].filter((path18) => path18.length > 0).sort((a2, b2) => b2.length - a2.length);
35020
- for (const path18 of sorted) {
36075
+ const sorted = [...files].filter((path21) => path21.length > 0).sort((a2, b2) => b2.length - a2.length);
36076
+ for (const path21 of sorted) {
35021
36077
  let from = 0;
35022
36078
  while (from < text.length) {
35023
- const index = text.indexOf(path18, from);
36079
+ const index = text.indexOf(path21, from);
35024
36080
  if (index < 0)
35025
36081
  break;
35026
- const end = index + path18.length;
36082
+ const end = index + path21.length;
35027
36083
  if (hasStartBoundary(text, index) && hasEndBoundary(text, end)) {
35028
- if (!seen.has(path18)) {
35029
- seen.add(path18);
35030
- matches.push({ path: path18, index });
36084
+ if (!seen.has(path21)) {
36085
+ seen.add(path21);
36086
+ matches.push({ path: path21, index });
35031
36087
  }
35032
36088
  break;
35033
36089
  }
@@ -35037,20 +36093,20 @@ function findPreviewablePathRefs(text, files, limit = DEFAULT_LIMIT) {
35037
36093
  matches.sort((a2, b2) => a2.index - b2.index || a2.path.localeCompare(b2.path));
35038
36094
  return matches.slice(0, limit);
35039
36095
  }
35040
- function formatPreviewPathLabel(path18, maxCells) {
36096
+ function formatPreviewPathLabel(path21, maxCells) {
35041
36097
  if (maxCells <= 3)
35042
- return path18.slice(0, Math.max(0, maxCells));
35043
- if (path18.length <= maxCells)
35044
- return path18;
35045
- const slash = path18.lastIndexOf("/");
35046
- const filename = slash >= 0 ? path18.slice(slash + 1) : path18;
36098
+ return path21.slice(0, Math.max(0, maxCells));
36099
+ if (path21.length <= maxCells)
36100
+ return path21;
36101
+ const slash = path21.lastIndexOf("/");
36102
+ const filename = slash >= 0 ? path21.slice(slash + 1) : path21;
35047
36103
  if (filename.length + 4 <= maxCells) {
35048
36104
  const prefixCells = maxCells - filename.length - 4;
35049
- return `${path18.slice(0, prefixCells)}.../${filename}`;
36105
+ return `${path21.slice(0, prefixCells)}.../${filename}`;
35050
36106
  }
35051
36107
  const headCells = Math.max(1, Math.floor((maxCells - 3) / 2));
35052
36108
  const tailCells = Math.max(1, maxCells - 3 - headCells);
35053
- return `${path18.slice(0, headCells)}...${path18.slice(path18.length - tailCells)}`;
36109
+ return `${path21.slice(0, headCells)}...${path21.slice(path21.length - tailCells)}`;
35054
36110
  }
35055
36111
  var DEFAULT_LIMIT = 5, BEFORE_BOUNDARY, AFTER_BOUNDARY;
35056
36112
  var init_path_preview = __esm(() => {
@@ -35896,8 +36952,8 @@ var init_ComposerView = __esm(() => {
35896
36952
  });
35897
36953
 
35898
36954
  // src/tui/panes/chat/composer/clipboard-image.ts
35899
- import { spawnSync as spawnSync12 } from "child_process";
35900
- import { statSync as statSync7 } from "fs";
36955
+ import { spawnSync as spawnSync13 } from "child_process";
36956
+ import { statSync as statSync8 } from "fs";
35901
36957
  function clipboardImageSupported() {
35902
36958
  return process.platform === "darwin";
35903
36959
  }
@@ -35921,14 +36977,14 @@ function readClipboardImageMacOS(destPath) {
35921
36977
  "end try"
35922
36978
  ].join(`
35923
36979
  `);
35924
- const result = spawnSync12("osascript", ["-e", script], {
36980
+ const result = spawnSync13("osascript", ["-e", script], {
35925
36981
  timeout: 5000,
35926
36982
  stdio: ["ignore", "ignore", "ignore"]
35927
36983
  });
35928
36984
  if (result.status !== 0)
35929
36985
  return null;
35930
36986
  try {
35931
- const st = statSync7(destPath);
36987
+ const st = statSync8(destPath);
35932
36988
  if (st.size === 0)
35933
36989
  return null;
35934
36990
  } catch {
@@ -35980,20 +37036,20 @@ function makeDropdownWindow(items, cursor, maxVisible) {
35980
37036
  }
35981
37037
 
35982
37038
  // src/tui/panes/chat/composer/history-store.ts
35983
- import { existsSync as existsSync12, readFileSync as readFileSync10 } from "fs";
35984
- import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile12, rename as rename2, writeFile as writeFile5 } from "fs/promises";
37039
+ import { existsSync as existsSync13, readFileSync as readFileSync10 } from "fs";
37040
+ import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile13, rename as rename2, writeFile as writeFile5 } from "fs/promises";
35985
37041
  import { dirname as dirname8, join as join22 } from "path";
35986
37042
  function defaultHistoryPath() {
35987
37043
  return join22(kobeStateDir(), "composer-history.jsonl");
35988
37044
  }
35989
- function loadFromDisk(path18 = defaultHistoryPath()) {
35990
- if (!existsSync12(path18))
37045
+ function loadFromDisk(path21 = defaultHistoryPath()) {
37046
+ if (!existsSync13(path21))
35991
37047
  return [];
35992
37048
  let text;
35993
37049
  try {
35994
- text = readFileSync10(path18, "utf8");
37050
+ text = readFileSync10(path21, "utf8");
35995
37051
  } catch (err) {
35996
- console.warn(`[kobe] could not read composer history at ${path18}: ${err instanceof Error ? err.message : err}`);
37052
+ console.warn(`[kobe] could not read composer history at ${path21}: ${err instanceof Error ? err.message : err}`);
35997
37053
  return [];
35998
37054
  }
35999
37055
  const lines = text.split(`
@@ -36020,19 +37076,19 @@ function loadFromDisk(path18 = defaultHistoryPath()) {
36020
37076
  }
36021
37077
  }
36022
37078
  if (malformed > 0) {
36023
- console.warn(`[kobe] composer history: skipped ${malformed} malformed line(s) in ${path18}`);
37079
+ console.warn(`[kobe] composer history: skipped ${malformed} malformed line(s) in ${path21}`);
36024
37080
  }
36025
37081
  out.sort((a2, b2) => a2.timestamp - b2.timestamp);
36026
37082
  return out;
36027
37083
  }
36028
- function appendToDisk(entry, path18 = defaultHistoryPath()) {
37084
+ function appendToDisk(entry, path21 = defaultHistoryPath()) {
36029
37085
  const next = writeQueue.then(async () => {
36030
37086
  try {
36031
- const dir = dirname8(path18);
37087
+ const dir = dirname8(path21);
36032
37088
  await mkdir6(dir, { recursive: true });
36033
37089
  const line = `${JSON.stringify(entry)}
36034
37090
  `;
36035
- await appendFile2(path18, line, { encoding: "utf8", mode: 384 });
37091
+ await appendFile2(path21, line, { encoding: "utf8", mode: 384 });
36036
37092
  } catch (err) {
36037
37093
  console.warn(`[kobe] composer history append failed: ${err instanceof Error ? err.message : err}`);
36038
37094
  }
@@ -36040,21 +37096,21 @@ function appendToDisk(entry, path18 = defaultHistoryPath()) {
36040
37096
  writeQueue = next;
36041
37097
  return next;
36042
37098
  }
36043
- async function pruneToCap(path18 = defaultHistoryPath(), cap = DISK_HISTORY_CAP) {
37099
+ async function pruneToCap(path21 = defaultHistoryPath(), cap = DISK_HISTORY_CAP) {
36044
37100
  try {
36045
- if (!existsSync12(path18))
37101
+ if (!existsSync13(path21))
36046
37102
  return;
36047
- const text = await readFile12(path18, "utf8");
37103
+ const text = await readFile13(path21, "utf8");
36048
37104
  const lines = text.split(`
36049
37105
  `).filter((l2) => l2.length > 0);
36050
37106
  if (lines.length <= cap)
36051
37107
  return;
36052
37108
  const keep = lines.slice(lines.length - cap);
36053
- const tmp = `${path18}.tmp`;
37109
+ const tmp = `${path21}.tmp`;
36054
37110
  await writeFile5(tmp, `${keep.join(`
36055
37111
  `)}
36056
37112
  `, { encoding: "utf8", mode: 384 });
36057
- await rename2(tmp, path18);
37113
+ await rename2(tmp, path21);
36058
37114
  } catch (err) {
36059
37115
  console.warn(`[kobe] composer history prune failed: ${err instanceof Error ? err.message : err}`);
36060
37116
  }
@@ -36132,7 +37188,7 @@ function getAllHistoryEntries() {
36132
37188
  return out;
36133
37189
  }
36134
37190
  var HISTORY_LIMIT = 200, STORE, SEQ = 0, DISK_PRUNE_INTERVAL = 50, appendsSincePrune = 0;
36135
- var init_history4 = __esm(() => {
37191
+ var init_history5 = __esm(() => {
36136
37192
  init_history_store();
36137
37193
  STORE = new Map;
36138
37194
  });
@@ -36441,7 +37497,7 @@ var init_HistoryPalette = __esm(() => {
36441
37497
  init_theme();
36442
37498
  init_keymap();
36443
37499
  init_dialog();
36444
- init_history4();
37500
+ init_history5();
36445
37501
  });
36446
37502
 
36447
37503
  // src/tui/panes/chat/composer/history-palette.tsx
@@ -36469,7 +37525,7 @@ var init_history_palette = __esm(() => {
36469
37525
  });
36470
37526
 
36471
37527
  // src/tui/panes/chat/composer/image-paste.ts
36472
- import { randomUUID as randomUUID2 } from "crypto";
37528
+ import { randomUUID as randomUUID3 } from "crypto";
36473
37529
  import { mkdirSync as mkdirSync6, writeFileSync as writeFileSync4 } from "fs";
36474
37530
  import { join as join23 } from "path";
36475
37531
  function pastedImagesDir() {
@@ -36553,7 +37609,7 @@ function mimeTypeToExt(mimeType) {
36553
37609
  return ".png";
36554
37610
  }
36555
37611
  function mintPath(ext) {
36556
- return join23(pastedImagesDir(), `${randomUUID2()}${ext}`);
37612
+ return join23(pastedImagesDir(), `${randomUUID3()}${ext}`);
36557
37613
  }
36558
37614
  var IMAGE_TOKEN_RE;
36559
37615
  var init_image_paste = __esm(() => {
@@ -36643,25 +37699,25 @@ function findMentionContext(text, cursor) {
36643
37699
  }
36644
37700
  return { atPos, query: text.slice(atPos + 1, cursor) };
36645
37701
  }
36646
- function formatDisplayPath(path18) {
36647
- if (path18.startsWith("packages/"))
36648
- return path18.slice("packages/".length);
36649
- return path18;
37702
+ function formatDisplayPath(path21) {
37703
+ if (path21.startsWith("packages/"))
37704
+ return path21.slice("packages/".length);
37705
+ return path21;
36650
37706
  }
36651
37707
  function filterMentionMatches(files, query, limit) {
36652
37708
  if (files.length === 0 || limit <= 0)
36653
37709
  return [];
36654
37710
  const q2 = query.toLowerCase();
36655
37711
  if (q2.length === 0) {
36656
- return files.slice(0, limit).map((path18) => ({
36657
- path: path18,
36658
- displayPath: formatDisplayPath(path18),
37712
+ return files.slice(0, limit).map((path21) => ({
37713
+ path: path21,
37714
+ displayPath: formatDisplayPath(path21),
36659
37715
  score: 0
36660
37716
  }));
36661
37717
  }
36662
37718
  const matches = [];
36663
- for (const path18 of files) {
36664
- const lower = path18.toLowerCase();
37719
+ for (const path21 of files) {
37720
+ const lower = path21.toLowerCase();
36665
37721
  const slash = lower.lastIndexOf("/");
36666
37722
  const filename = slash >= 0 ? lower.slice(slash + 1) : lower;
36667
37723
  let score = 0;
@@ -36675,8 +37731,8 @@ function filterMentionMatches(files, query, limit) {
36675
37731
  score = 40;
36676
37732
  else
36677
37733
  continue;
36678
- score -= path18.length * 0.5;
36679
- matches.push({ path: path18, displayPath: formatDisplayPath(path18), score });
37734
+ score -= path21.length * 0.5;
37735
+ matches.push({ path: path21, displayPath: formatDisplayPath(path21), score });
36680
37736
  }
36681
37737
  matches.sort((a2, b2) => b2.score - a2.score);
36682
37738
  return matches.slice(0, limit);
@@ -36727,7 +37783,7 @@ function createMentionController(args2) {
36727
37783
  });
36728
37784
  const window2 = createMemo(() => makeDropdownWindow(matches(), cursor(), MENTION_MAX_VISIBLE));
36729
37785
  const pathRefs = createMemo(() => findPreviewablePathRefs(args2.liveBuffer(), files()));
36730
- function insertSelection(path18) {
37786
+ function insertSelection(path21) {
36731
37787
  const ref = args2.textarea();
36732
37788
  const ctx4 = context();
36733
37789
  if (!ref || !ctx4)
@@ -36735,7 +37791,7 @@ function createMentionController(args2) {
36735
37791
  const currentCursor = ref.cursorOffset;
36736
37792
  ref.setSelection(ctx4.atPos, currentCursor);
36737
37793
  ref.deleteSelection();
36738
- ref.insertText(`@${path18} `);
37794
+ ref.insertText(`@${path21} `);
36739
37795
  setDismissedAt(null);
36740
37796
  setCursor(0);
36741
37797
  }
@@ -37243,7 +38299,7 @@ var init_Composer = __esm(() => {
37243
38299
  init_dialog();
37244
38300
  init_ComposerView();
37245
38301
  init_clipboard_image();
37246
- init_history4();
38302
+ init_history5();
37247
38303
  init_history_palette();
37248
38304
  init_image_paste();
37249
38305
  init_mention_controller();
@@ -38212,7 +39268,7 @@ function readWriteInput(input) {
38212
39268
  };
38213
39269
  }
38214
39270
  function makeHeader(filePath, verb, adds, removes) {
38215
- const path18 = filePath || "(unknown file)";
39271
+ const path21 = filePath || "(unknown file)";
38216
39272
  const parts = [];
38217
39273
  if (adds > 0) {
38218
39274
  parts.push(`Added ${adds} ${adds === 1 ? "line" : "lines"}`);
@@ -38222,11 +39278,11 @@ function makeHeader(filePath, verb, adds, removes) {
38222
39278
  parts.push(`${word} ${removes} ${removes === 1 ? "line" : "lines"}`);
38223
39279
  }
38224
39280
  if (parts.length === 0)
38225
- return `${verb} ${path18}`;
38226
- return `${verb} ${path18} \xB7 ${parts.join(", ")}`;
39281
+ return `${verb} ${path21}`;
39282
+ return `${verb} ${path21} \xB7 ${parts.join(", ")}`;
38227
39283
  }
38228
39284
  function makeMultiEditHeader(filePath, count, adds, removes) {
38229
- const path18 = filePath || "(unknown file)";
39285
+ const path21 = filePath || "(unknown file)";
38230
39286
  const segments = [];
38231
39287
  if (count > 0) {
38232
39288
  segments.push(`${count} ${count === 1 ? "edit" : "edits"}`);
@@ -38242,8 +39298,8 @@ function makeMultiEditHeader(filePath, count, adds, removes) {
38242
39298
  if (lineParts.length > 0)
38243
39299
  segments.push(lineParts.join(", "));
38244
39300
  if (segments.length === 0)
38245
- return `Edited ${path18}`;
38246
- return `Edited ${path18} \xB7 ${segments.join(" \xB7 ")}`;
39301
+ return `Edited ${path21}`;
39302
+ return `Edited ${path21} \xB7 ${segments.join(" \xB7 ")}`;
38247
39303
  }
38248
39304
  var COLLAPSED_LINE_CAP = 10;
38249
39305
 
@@ -38608,7 +39664,8 @@ var init_tool_registry = __esm(() => {
38608
39664
  registries = {
38609
39665
  claude: claudeRegistry,
38610
39666
  codex: {},
38611
- gemini: {}
39667
+ gemini: {},
39668
+ copilot: {}
38612
39669
  };
38613
39670
  });
38614
39671
 
@@ -41047,7 +42104,7 @@ function stringifyForTokenEstimate(value) {
41047
42104
  return String(value);
41048
42105
  }
41049
42106
  }
41050
- function stringifyErr5(err) {
42107
+ function stringifyErr6(err) {
41051
42108
  if (err instanceof Error)
41052
42109
  return err.message;
41053
42110
  try {
@@ -41064,18 +42121,21 @@ function ModelPicker(props) {
41064
42121
  const {
41065
42122
  theme
41066
42123
  } = useTheme();
41067
- const models = createMemo(() => modelPickerModelOptions(allModels(), {
41068
- lockedVendor: props.lockedVendor
42124
+ const seedVendor = props.currentVendor ?? props.lockedVendor ?? "claude";
42125
+ const groups = createMemo(() => modelPickerProviderGroups(allModels(), {
42126
+ lockedVendor: props.lockedVendor,
42127
+ providerLabelFor: (vendor) => getCapabilities(vendor).label
41069
42128
  }));
42129
+ const [expandedVendors, setExpandedVendors] = createSignal(modelPickerDefaultExpandedVendors(props.currentVendor, props.lockedVendor));
42130
+ const rows = createMemo(() => visibleRows(groups(), expandedVendors()));
41070
42131
  const [selectedModel, setSelectedModel] = createSignal();
41071
42132
  const effortChoices = createMemo(() => {
41072
42133
  const model = selectedModel();
41073
42134
  return model ? modelPickerEffortOptions(model) : [];
41074
42135
  });
41075
- const seedVendor = props.currentVendor ?? props.lockedVendor ?? "claude";
41076
42136
  const seed = props.current ?? getCapabilities(seedVendor).defaultModelId();
41077
- const initial = models().findIndex((m2) => m2.id === seed);
41078
- const [cursor, setCursor] = createSignal(nextEnabledIndex(models(), initial >= 0 ? initial : 0, 1));
42137
+ const initial = rows().findIndex((row) => row.type === "model" && row.model.id === seed);
42138
+ const [cursor, setCursor] = createSignal(nextEnabledRowIndex(rows(), initial >= 0 ? initial : 0, 1));
41079
42139
  const [effortCursor, setEffortCursor] = createSignal(0);
41080
42140
  const inEffortStep = () => selectedModel() !== undefined;
41081
42141
  function setInitialEffortCursor(model) {
@@ -41088,7 +42148,14 @@ function ModelPicker(props) {
41088
42148
  commitEffort();
41089
42149
  return;
41090
42150
  }
41091
- const model = models()[cursor()];
42151
+ const row = rows()[cursor()];
42152
+ if (!row)
42153
+ return;
42154
+ if (row.type === "provider") {
42155
+ toggleProvider(row.vendor);
42156
+ return;
42157
+ }
42158
+ const model = row.model;
41092
42159
  if (!model)
41093
42160
  return;
41094
42161
  if (model.disabled)
@@ -41123,50 +42190,60 @@ function ModelPicker(props) {
41123
42190
  function backToModels() {
41124
42191
  setSelectedModel(undefined);
41125
42192
  }
42193
+ function toggleProvider(vendor) {
42194
+ setExpandedVendors((previous) => {
42195
+ const next = new Set(previous);
42196
+ if (next.has(vendor))
42197
+ next.delete(vendor);
42198
+ else
42199
+ next.add(vendor);
42200
+ return next;
42201
+ });
42202
+ }
41126
42203
  useBindings(() => ({
41127
42204
  bindings: [{
41128
42205
  key: "up",
41129
42206
  cmd: () => {
41130
- const n2 = inEffortStep() ? effortChoices().length : models().length;
42207
+ const n2 = inEffortStep() ? effortChoices().length : rows().length;
41131
42208
  if (n2 === 0)
41132
42209
  return;
41133
42210
  if (inEffortStep())
41134
42211
  setEffortCursor((c2) => (c2 - 1 + n2) % n2);
41135
42212
  else
41136
- setCursor((c2) => nextEnabledIndex(models(), c2 - 1, -1));
42213
+ setCursor((c2) => nextEnabledRowIndex(rows(), c2 - 1, -1));
41137
42214
  }
41138
42215
  }, {
41139
42216
  key: "down",
41140
42217
  cmd: () => {
41141
- const n2 = inEffortStep() ? effortChoices().length : models().length;
42218
+ const n2 = inEffortStep() ? effortChoices().length : rows().length;
41142
42219
  if (n2 === 0)
41143
42220
  return;
41144
42221
  if (inEffortStep())
41145
42222
  setEffortCursor((c2) => (c2 + 1) % n2);
41146
42223
  else
41147
- setCursor((c2) => nextEnabledIndex(models(), c2 + 1, 1));
42224
+ setCursor((c2) => nextEnabledRowIndex(rows(), c2 + 1, 1));
41148
42225
  }
41149
42226
  }, {
41150
42227
  key: "k",
41151
42228
  cmd: () => {
41152
- const n2 = inEffortStep() ? effortChoices().length : models().length;
42229
+ const n2 = inEffortStep() ? effortChoices().length : rows().length;
41153
42230
  if (n2 === 0)
41154
42231
  return;
41155
42232
  if (inEffortStep())
41156
42233
  setEffortCursor((c2) => (c2 - 1 + n2) % n2);
41157
42234
  else
41158
- setCursor((c2) => nextEnabledIndex(models(), c2 - 1, -1));
42235
+ setCursor((c2) => nextEnabledRowIndex(rows(), c2 - 1, -1));
41159
42236
  }
41160
42237
  }, {
41161
42238
  key: "j",
41162
42239
  cmd: () => {
41163
- const n2 = inEffortStep() ? effortChoices().length : models().length;
42240
+ const n2 = inEffortStep() ? effortChoices().length : rows().length;
41164
42241
  if (n2 === 0)
41165
42242
  return;
41166
42243
  if (inEffortStep())
41167
42244
  setEffortCursor((c2) => (c2 + 1) % n2);
41168
42245
  else
41169
- setCursor((c2) => nextEnabledIndex(models(), c2 + 1, 1));
42246
+ setCursor((c2) => nextEnabledRowIndex(rows(), c2 + 1, 1));
41170
42247
  }
41171
42248
  }, {
41172
42249
  key: "left",
@@ -41281,23 +42358,27 @@ function ModelPicker(props) {
41281
42358
  setProp(_el$14, "paddingBottom", 1);
41282
42359
  insert(_el$14, createComponent2(For, {
41283
42360
  get each() {
41284
- return models();
42361
+ return rows();
41285
42362
  },
41286
- children: (model, i2) => {
42363
+ children: (row, i2) => {
41287
42364
  const active = () => i2() === cursor();
41288
- const disabled = () => model.disabled === true;
41289
- const hasEfforts = () => modelPickerEffortOptions(model).some((choice) => choice.effort !== undefined);
42365
+ const disabled = () => row.type === "model" && row.model.disabled === true;
42366
+ const hasEfforts = () => row.type === "model" && modelPickerEffortOptions(row.model).some((choice) => choice.effort !== undefined);
41290
42367
  return (() => {
41291
- var _el$15 = createElement("box"), _el$16 = createElement("text"), _el$17 = createElement("text");
41292
- insertNode(_el$15, _el$16);
41293
- insertNode(_el$15, _el$17);
42368
+ var _el$15 = createElement("box");
41294
42369
  setProp(_el$15, "flexDirection", "row");
41295
42370
  setProp(_el$15, "gap", 2);
41296
42371
  setProp(_el$15, "paddingLeft", 1);
41297
42372
  setProp(_el$15, "paddingRight", 1);
41298
42373
  setProp(_el$15, "onMouseUp", () => {
42374
+ if (row.type === "provider") {
42375
+ setCursor(i2());
42376
+ toggleProvider(row.vendor);
42377
+ return;
42378
+ }
41299
42379
  if (disabled())
41300
42380
  return;
42381
+ const model = row.model;
41301
42382
  const efforts = modelPickerEffortOptions(model);
41302
42383
  if (efforts.length <= 1 && efforts[0]?.effort === undefined) {
41303
42384
  props.onPick({
@@ -41312,50 +42393,69 @@ function ModelPicker(props) {
41312
42393
  setSelectedModel(model);
41313
42394
  setInitialEffortCursor(model);
41314
42395
  });
41315
- setProp(_el$16, "wrapMode", "none");
41316
- insert(_el$16, () => active() ? "\u25B8 " : " ", null);
41317
- insert(_el$16, () => model.label, null);
41318
- setProp(_el$17, "wrapMode", "none");
41319
- insert(_el$17, () => model.vendor);
41320
42396
  insert(_el$15, (() => {
41321
- var _c$3 = memo2(() => !!(disabled() && model.disabledReason));
41322
- return () => _c$3() ? (() => {
41323
- var _el$18 = createElement("text");
42397
+ var _c$3 = memo2(() => row.type === "provider");
42398
+ return () => _c$3() ? [(() => {
42399
+ var _el$16 = createElement("text"), _el$17 = createTextNode(` `);
42400
+ insertNode(_el$16, _el$17);
42401
+ setProp(_el$16, "wrapMode", "none");
42402
+ insert(_el$16, () => active() ? "\u25B8 " : " ", _el$17);
42403
+ insert(_el$16, () => row.expanded ? "\u25BE" : "\u25B8", _el$17);
42404
+ insert(_el$16, () => row.label, null);
42405
+ effect((_p$) => {
42406
+ var _v$1 = active() ? theme.selectedListItemText : theme.text, _v$10 = TextAttributes35.BOLD;
42407
+ _v$1 !== _p$.e && (_p$.e = setProp(_el$16, "fg", _v$1, _p$.e));
42408
+ _v$10 !== _p$.t && (_p$.t = setProp(_el$16, "attributes", _v$10, _p$.t));
42409
+ return _p$;
42410
+ }, {
42411
+ e: undefined,
42412
+ t: undefined
42413
+ });
42414
+ return _el$16;
42415
+ })(), (() => {
42416
+ var _el$18 = createElement("text"), _el$19 = createTextNode(` models`);
42417
+ insertNode(_el$18, _el$19);
41324
42418
  setProp(_el$18, "wrapMode", "none");
41325
- insert(_el$18, () => model.disabledReason);
41326
- effect((_$p) => setProp(_el$18, "fg", theme.textMuted, _$p));
42419
+ insert(_el$18, () => row.count, _el$19);
42420
+ effect((_$p) => setProp(_el$18, "fg", active() ? theme.selectedListItemText : theme.textMuted, _$p));
41327
42421
  return _el$18;
42422
+ })()] : [(() => {
42423
+ var _el$20 = createElement("text"), _el$21 = createTextNode(` `);
42424
+ insertNode(_el$20, _el$21);
42425
+ setProp(_el$20, "wrapMode", "none");
42426
+ insert(_el$20, () => active() ? "\u25B8 " : " ", _el$21);
42427
+ insert(_el$20, () => row.model.label, null);
42428
+ effect((_p$) => {
42429
+ var _v$11 = active() && !disabled() ? theme.selectedListItemText : disabled() ? theme.textMuted : theme.text, _v$12 = active() && !disabled() ? TextAttributes35.BOLD : undefined;
42430
+ _v$11 !== _p$.e && (_p$.e = setProp(_el$20, "fg", _v$11, _p$.e));
42431
+ _v$12 !== _p$.t && (_p$.t = setProp(_el$20, "attributes", _v$12, _p$.t));
42432
+ return _p$;
42433
+ }, {
42434
+ e: undefined,
42435
+ t: undefined
42436
+ });
42437
+ return _el$20;
42438
+ })(), memo2(() => memo2(() => !!(disabled() && row.model.disabledReason))() ? (() => {
42439
+ var _el$22 = createElement("text");
42440
+ setProp(_el$22, "wrapMode", "none");
42441
+ insert(_el$22, () => row.model.disabledReason);
42442
+ effect((_$p) => setProp(_el$22, "fg", theme.textMuted, _$p));
42443
+ return _el$22;
41328
42444
  })() : memo2(() => !!hasEfforts())() ? (() => {
41329
- var _el$19 = createElement("text");
41330
- insertNode(_el$19, createTextNode(`effort\u2026`));
41331
- setProp(_el$19, "wrapMode", "none");
41332
- effect((_$p) => setProp(_el$19, "fg", active() ? theme.selectedListItemText : theme.textMuted, _$p));
41333
- return _el$19;
41334
- })() : null;
41335
- })(), null);
41336
- insert(_el$15, (() => {
41337
- var _c$4 = memo2(() => !!model.hint);
41338
- return () => _c$4() ? (() => {
41339
- var _el$21 = createElement("text");
41340
- setProp(_el$21, "wrapMode", "none");
41341
- insert(_el$21, () => model.hint);
41342
- effect((_$p) => setProp(_el$21, "fg", active() && !disabled() ? theme.selectedListItemText : theme.textMuted, _$p));
41343
- return _el$21;
41344
- })() : null;
41345
- })(), null);
41346
- effect((_p$) => {
41347
- var _v$1 = active() && !disabled() ? theme.primary : undefined, _v$10 = active() && !disabled() ? theme.selectedListItemText : disabled() ? theme.textMuted : theme.text, _v$11 = active() && !disabled() ? TextAttributes35.BOLD : undefined, _v$12 = active() && !disabled() ? theme.selectedListItemText : theme.textMuted;
41348
- _v$1 !== _p$.e && (_p$.e = setProp(_el$15, "backgroundColor", _v$1, _p$.e));
41349
- _v$10 !== _p$.t && (_p$.t = setProp(_el$16, "fg", _v$10, _p$.t));
41350
- _v$11 !== _p$.a && (_p$.a = setProp(_el$16, "attributes", _v$11, _p$.a));
41351
- _v$12 !== _p$.o && (_p$.o = setProp(_el$17, "fg", _v$12, _p$.o));
41352
- return _p$;
41353
- }, {
41354
- e: undefined,
41355
- t: undefined,
41356
- a: undefined,
41357
- o: undefined
41358
- });
42445
+ var _el$23 = createElement("text");
42446
+ insertNode(_el$23, createTextNode(`effort\u2026`));
42447
+ setProp(_el$23, "wrapMode", "none");
42448
+ effect((_$p) => setProp(_el$23, "fg", active() ? theme.selectedListItemText : theme.textMuted, _$p));
42449
+ return _el$23;
42450
+ })() : null), memo2(() => memo2(() => !!row.model.hint)() ? (() => {
42451
+ var _el$25 = createElement("text");
42452
+ setProp(_el$25, "wrapMode", "none");
42453
+ insert(_el$25, () => row.model.hint);
42454
+ effect((_$p) => setProp(_el$25, "fg", active() && !disabled() ? theme.selectedListItemText : theme.textMuted, _$p));
42455
+ return _el$25;
42456
+ })() : null)];
42457
+ })());
42458
+ effect((_$p) => setProp(_el$15, "backgroundColor", active() && !disabled() ? theme.primary : undefined, _$p));
41359
42459
  return _el$15;
41360
42460
  })();
41361
42461
  }
@@ -41365,7 +42465,7 @@ function ModelPicker(props) {
41365
42465
  })(), _el$6);
41366
42466
  insertNode(_el$6, _el$7);
41367
42467
  setProp(_el$6, "paddingBottom", 1);
41368
- insert(_el$7, () => inEffortStep() ? "\u2191\u2193 pick \xB7 enter select \xB7 h back \xB7 esc cancel" : "\u2191\u2193 pick \xB7 enter select \xB7 esc cancel");
42468
+ insert(_el$7, () => inEffortStep() ? "\u2191\u2193 pick \xB7 enter select \xB7 h back \xB7 esc cancel" : "\u2191\u2193 pick \xB7 enter select/toggle \xB7 esc cancel");
41369
42469
  effect((_p$) => {
41370
42470
  var _v$ = TextAttributes35.BOLD, _v$2 = theme.text, _v$3 = theme.textMuted, _v$4 = theme.textMuted;
41371
42471
  _v$ !== _p$.e && (_p$.e = setProp(_el$3, "attributes", _v$, _p$.e));
@@ -41382,13 +42482,35 @@ function ModelPicker(props) {
41382
42482
  return _el$;
41383
42483
  })();
41384
42484
  }
41385
- function nextEnabledIndex(models, start, step) {
41386
- if (models.length === 0)
42485
+ function visibleRows(groups, expandedVendors) {
42486
+ const rows = [];
42487
+ for (const group of groups) {
42488
+ const expanded = expandedVendors.has(group.vendor);
42489
+ rows.push({
42490
+ type: "provider",
42491
+ vendor: group.vendor,
42492
+ label: group.label,
42493
+ expanded,
42494
+ count: group.models.length
42495
+ });
42496
+ if (expanded) {
42497
+ for (const model of group.models)
42498
+ rows.push({
42499
+ type: "model",
42500
+ model
42501
+ });
42502
+ }
42503
+ }
42504
+ return rows;
42505
+ }
42506
+ function nextEnabledRowIndex(rows, start, step) {
42507
+ if (rows.length === 0)
41387
42508
  return 0;
41388
- const normalized = (start % models.length + models.length) % models.length;
41389
- for (let offset = 0;offset < models.length; offset++) {
41390
- const idx = ((normalized + offset * step) % models.length + models.length) % models.length;
41391
- if (!models[idx]?.disabled)
42509
+ const normalized = (start % rows.length + rows.length) % rows.length;
42510
+ for (let offset = 0;offset < rows.length; offset++) {
42511
+ const idx = ((normalized + offset * step) % rows.length + rows.length) % rows.length;
42512
+ const row = rows[idx];
42513
+ if (row?.type === "provider" || !row?.model.disabled)
41392
42514
  return idx;
41393
42515
  }
41394
42516
  return normalized;
@@ -42015,13 +43137,13 @@ var init_store2 = __esm(() => {
42015
43137
  });
42016
43138
 
42017
43139
  // src/tui/panes/chat/bash-mode.ts
42018
- import { spawn as spawn16 } from "child_process";
43140
+ import { spawn as spawn17 } from "child_process";
42019
43141
  async function runBashCommand(opts) {
42020
43142
  const shell = resolveShell();
42021
43143
  return await new Promise((resolve4, reject) => {
42022
43144
  let child;
42023
43145
  try {
42024
- child = spawn16(shell, ["-c", opts.command], {
43146
+ child = spawn17(shell, ["-c", opts.command], {
42025
43147
  cwd: opts.cwd,
42026
43148
  stdio: ["ignore", "pipe", "pipe"],
42027
43149
  env: process.env,
@@ -42178,7 +43300,7 @@ function useBashMode(opts) {
42178
43300
  }
42179
43301
  } catch (err) {
42180
43302
  opts.patchStateForTab(tabId, (s2) => patchBashRow(s2, id, { done: true, exitCode: -1, signal: null }));
42181
- opts.patchStateForTab(tabId, (s2) => pushSystemError(s2, `bash failed: ${stringifyErr5(err)}`));
43303
+ opts.patchStateForTab(tabId, (s2) => pushSystemError(s2, `bash failed: ${stringifyErr6(err)}`));
42182
43304
  } finally {
42183
43305
  if (bashAbortsByTab.get(tabId) === ac)
42184
43306
  bashAbortsByTab.delete(tabId);
@@ -42697,7 +43819,7 @@ function useChatTabs(opts) {
42697
43819
  resetExpansion();
42698
43820
  opts.orchestrator.setActiveTab(taskId, tab.id);
42699
43821
  } catch (err) {
42700
- opts.patchActiveState((s2) => pushSystemError(s2, `createTab failed: ${stringifyErr5(err)}`));
43822
+ opts.patchActiveState((s2) => pushSystemError(s2, `createTab failed: ${stringifyErr6(err)}`));
42701
43823
  }
42702
43824
  }
42703
43825
  async function closeActiveTab() {
@@ -42715,7 +43837,7 @@ function useChatTabs(opts) {
42715
43837
  resetExpansion();
42716
43838
  }
42717
43839
  } catch (err) {
42718
- opts.patchActiveState((s2) => pushSystemError(s2, `closeTab failed: ${stringifyErr5(err)}`));
43840
+ opts.patchActiveState((s2) => pushSystemError(s2, `closeTab failed: ${stringifyErr6(err)}`));
42719
43841
  }
42720
43842
  }
42721
43843
  function selectTabByIndex(idx) {
@@ -43097,7 +44219,7 @@ function Chat(props) {
43097
44219
  try {
43098
44220
  await props.orchestrator.runTask(taskId, finalText, tabId);
43099
44221
  } catch (err) {
43100
- patchActiveState((s2) => pushSystemError(s2, `queued runTask failed: ${stringifyErr5(err)}`));
44222
+ patchActiveState((s2) => pushSystemError(s2, `queued runTask failed: ${stringifyErr6(err)}`));
43101
44223
  }
43102
44224
  } finally {
43103
44225
  setDispatching(false);
@@ -43119,7 +44241,7 @@ function Chat(props) {
43119
44241
  try {
43120
44242
  await props.orchestrator.clearTab(taskId, tabId);
43121
44243
  } catch (err) {
43122
- patchActiveState((s2) => pushSystemError(s2, `/clear failed: ${stringifyErr5(err)}`));
44244
+ patchActiveState((s2) => pushSystemError(s2, `/clear failed: ${stringifyErr6(err)}`));
43123
44245
  return;
43124
44246
  }
43125
44247
  return;
@@ -43129,7 +44251,7 @@ function Chat(props) {
43129
44251
  try {
43130
44252
  await props.orchestrator.generateRecap(taskId, tabId);
43131
44253
  } catch (err) {
43132
- patchActiveState((s2) => pushSystemError(s2, `/recap failed: ${stringifyErr5(err)}`));
44254
+ patchActiveState((s2) => pushSystemError(s2, `/recap failed: ${stringifyErr6(err)}`));
43133
44255
  }
43134
44256
  return;
43135
44257
  }
@@ -43146,7 +44268,7 @@ function Chat(props) {
43146
44268
  try {
43147
44269
  await props.orchestrator.steerTask(taskId, dispatched, tabId);
43148
44270
  } catch (err) {
43149
- patchActiveState((s2) => pushSystemError(s2, `steer failed: ${stringifyErr5(err)}`));
44271
+ patchActiveState((s2) => pushSystemError(s2, `steer failed: ${stringifyErr6(err)}`));
43150
44272
  }
43151
44273
  } finally {
43152
44274
  setDispatching(false);
@@ -43166,7 +44288,7 @@ function Chat(props) {
43166
44288
  try {
43167
44289
  await props.orchestrator.runTask(taskId, dispatched, tabId);
43168
44290
  } catch (err) {
43169
- patchActiveState((s2) => pushSystemError(s2, `runTask failed: ${stringifyErr5(err)}`));
44291
+ patchActiveState((s2) => pushSystemError(s2, `runTask failed: ${stringifyErr6(err)}`));
43170
44292
  }
43171
44293
  }
43172
44294
  function cancelQueued(id) {
@@ -43222,7 +44344,7 @@ function Chat(props) {
43222
44344
  try {
43223
44345
  await props.orchestrator.interruptTask(taskId, tabId);
43224
44346
  } catch (err) {
43225
- patchActiveState((s2) => pushSystemError(s2, `interrupt failed: ${stringifyErr5(err)}`));
44347
+ patchActiveState((s2) => pushSystemError(s2, `interrupt failed: ${stringifyErr6(err)}`));
43226
44348
  }
43227
44349
  }
43228
44350
  useBindings(() => ({
@@ -43236,7 +44358,7 @@ function Chat(props) {
43236
44358
  setAwaitingResumeTurn(true);
43237
44359
  props.orchestrator.respondToInput(taskId, requestId, response).catch((err) => {
43238
44360
  setAwaitingResumeTurn(false);
43239
- patchActiveState((s2) => pushSystemError(s2, `respondToInput failed: ${stringifyErr5(err)}`));
44361
+ patchActiveState((s2) => pushSystemError(s2, `respondToInput failed: ${stringifyErr6(err)}`));
43240
44362
  });
43241
44363
  }
43242
44364
  const showThinking = createMemo(() => activeState().isStreaming);
@@ -43576,12 +44698,12 @@ var init_sidebar = __esm(() => {
43576
44698
  });
43577
44699
 
43578
44700
  // src/tui/panes/sidebar/git-head.ts
43579
- import { spawnSync as spawnSync13 } from "child_process";
44701
+ import { spawnSync as spawnSync14 } from "child_process";
43580
44702
  function readCurrentBranch(repo) {
43581
44703
  if (!repo)
43582
44704
  return "";
43583
44705
  try {
43584
- const out = spawnSync13("git", ["symbolic-ref", "--short", "HEAD"], {
44706
+ const out = spawnSync14("git", ["symbolic-ref", "--short", "HEAD"], {
43585
44707
  cwd: repo,
43586
44708
  encoding: "utf8",
43587
44709
  stdio: ["ignore", "pipe", "pipe"]
@@ -43591,7 +44713,7 @@ function readCurrentBranch(repo) {
43591
44713
  if (name && name !== "HEAD")
43592
44714
  return name;
43593
44715
  }
43594
- const head = spawnSync13("git", ["rev-parse", "--verify", "HEAD"], {
44716
+ const head = spawnSync14("git", ["rev-parse", "--verify", "HEAD"], {
43595
44717
  cwd: repo,
43596
44718
  encoding: "utf8",
43597
44719
  stdio: ["ignore", "pipe", "pipe"]
@@ -43763,12 +44885,12 @@ var init_keys4 = __esm(() => {
43763
44885
  });
43764
44886
 
43765
44887
  // src/tui/panes/sidebar/worktree-changes.ts
43766
- import { spawnSync as spawnSync14 } from "child_process";
44888
+ import { spawnSync as spawnSync15 } from "child_process";
43767
44889
  function readWorktreeChanges(worktreePath) {
43768
44890
  if (!worktreePath)
43769
44891
  return ZERO;
43770
44892
  try {
43771
- const out = spawnSync14("git", ["status", "--porcelain=v1"], {
44893
+ const out = spawnSync15("git", ["status", "--porcelain=v1"], {
43772
44894
  cwd: worktreePath,
43773
44895
  encoding: "utf8",
43774
44896
  stdio: ["ignore", "pipe", "pipe"]
@@ -44283,7 +45405,7 @@ var init_Sidebar = __esm(() => {
44283
45405
  });
44284
45406
 
44285
45407
  // src/tui/app.tsx
44286
- import { homedir as homedir24 } from "os";
45408
+ import { homedir as homedir27 } from "os";
44287
45409
  import { join as join24 } from "path";
44288
45410
  function Shell(props) {
44289
45411
  const themeCtx = useTheme();
@@ -44340,8 +45462,8 @@ function Shell(props) {
44340
45462
  return pp.prompt;
44341
45463
  });
44342
45464
  const worktreePathAcc = createMemo(() => {
44343
- const path18 = activeTask()?.worktreePath;
44344
- return path18 ? path18 : null;
45465
+ const path21 = activeTask()?.worktreePath;
45466
+ return path21 ? path21 : null;
44345
45467
  });
44346
45468
  const taskIdNullAcc = createMemo(() => selectedId());
44347
45469
  const diffBaseAcc = createMemo(() => worktreePathAcc() ? "HEAD" : null);
@@ -44840,7 +45962,7 @@ async function startApp(options = {}) {
44840
45962
  } of loadUserThemes()) {
44841
45963
  addTheme(name, theme);
44842
45964
  }
44843
- const homeDir2 = process.env.KOBE_HOME_DIR ?? homedir24();
45965
+ const homeDir2 = process.env.KOBE_HOME_DIR ?? homedir27();
44844
45966
  let orchestrator;
44845
45967
  let stopOwnedDaemon;
44846
45968
  let ownedDaemonStopped = false;
@@ -44957,7 +46079,7 @@ var init_app = __esm(() => {
44957
46079
  init_use_workspace_tabs();
44958
46080
  init_worktree_opener();
44959
46081
  init_Chat();
44960
- init_history4();
46082
+ init_history5();
44961
46083
  init_filetree();
44962
46084
  init_preview();
44963
46085
  init_Sidebar();