@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.
- package/dist/cli/index.js +1808 -686
- 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$
|
|
6151
|
+
var _el$ = createElement("box"), _el$2 = createElement("box"), _el$7 = createElement("scrollbox");
|
|
6152
6152
|
insertNode(_el$, _el$2);
|
|
6153
|
-
insertNode(_el$, _el$
|
|
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$
|
|
6171
|
-
setProp(_el$
|
|
6172
|
-
setProp(_el$
|
|
6173
|
-
insert(_el$
|
|
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$
|
|
6177
|
-
_v$4 !== _p$.t && (_p$.t = setProp(_el$
|
|
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$
|
|
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$
|
|
6199
|
-
insertNode(_el$
|
|
6200
|
-
setProp(_el$
|
|
6201
|
-
setProp(_el$
|
|
6202
|
-
setProp(_el$
|
|
6203
|
-
insertNode(_el$
|
|
6204
|
-
setProp(_el$
|
|
6205
|
-
effect((_$p) => setProp(_el$
|
|
6206
|
-
return _el$
|
|
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$
|
|
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$
|
|
6215
|
-
setProp(_el$
|
|
6216
|
-
setProp(_el$
|
|
6217
|
-
setProp(_el$
|
|
6218
|
-
return _el$
|
|
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$
|
|
6213
|
+
}), _el$7);
|
|
6221
6214
|
use((r) => {
|
|
6222
6215
|
scrollRef = r;
|
|
6223
|
-
}, _el$
|
|
6224
|
-
setProp(_el$
|
|
6225
|
-
setProp(_el$
|
|
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$
|
|
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$
|
|
6236
|
-
insertNode(_el$
|
|
6237
|
-
setProp(_el$
|
|
6238
|
-
setProp(_el$
|
|
6239
|
-
insertNode(_el$
|
|
6240
|
-
effect((_$p) => setProp(_el$
|
|
6241
|
-
return _el$
|
|
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$
|
|
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$
|
|
6250
|
-
insertNode(_el$
|
|
6251
|
-
insertNode(_el$
|
|
6252
|
-
setProp(_el$
|
|
6253
|
-
setProp(_el$
|
|
6254
|
-
setProp(_el$
|
|
6255
|
-
setProp(_el$
|
|
6256
|
-
setProp(_el$
|
|
6257
|
-
insert(_el$
|
|
6258
|
-
insertNode(_el$
|
|
6259
|
-
setProp(_el$
|
|
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$
|
|
6263
|
-
_v$2 !== _p$.t && (_p$.t = setProp(_el$
|
|
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$
|
|
6262
|
+
return _el$1;
|
|
6270
6263
|
}
|
|
6271
6264
|
}), null);
|
|
6272
|
-
insert(_el$
|
|
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$
|
|
6278
|
-
insertNode(_el$
|
|
6279
|
-
setProp(_el$
|
|
6280
|
-
setProp(_el$
|
|
6281
|
-
insert(_el$
|
|
6282
|
-
effect((_$p) => setProp(_el$
|
|
6283
|
-
return _el$
|
|
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$
|
|
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$
|
|
6292
|
-
setProp(_el$
|
|
6293
|
-
setProp(_el$
|
|
6294
|
-
setProp(_el$
|
|
6295
|
-
insert(_el$
|
|
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$
|
|
6306
|
-
insertNode(_el$
|
|
6307
|
-
setProp(_el$
|
|
6308
|
-
setProp(_el$
|
|
6309
|
-
setProp(_el$
|
|
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$
|
|
6321
|
-
insert(_el$
|
|
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$
|
|
6325
|
-
_v$6 !== _p$.t && (_p$.t = setProp(_el$
|
|
6326
|
-
_v$7 !== _p$.a && (_p$.a = setProp(_el$
|
|
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$
|
|
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$
|
|
6340
|
-
insertNode(_el$
|
|
6341
|
-
setProp(_el$
|
|
6342
|
-
setProp(_el$
|
|
6343
|
-
setProp(_el$
|
|
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$
|
|
6348
|
-
insert(_el$
|
|
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$
|
|
6352
|
-
_v$9 !== _p$.t && (_p$.t = setProp(_el$
|
|
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$
|
|
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$
|
|
6381
|
-
insertNode(_el$
|
|
6382
|
-
insertNode(_el$
|
|
6383
|
-
setProp(_el$
|
|
6384
|
-
setProp(_el$
|
|
6385
|
-
setProp(_el$
|
|
6386
|
-
setProp(_el$
|
|
6387
|
-
setProp(_el$
|
|
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$
|
|
6392
|
-
insert(_el$
|
|
6393
|
-
setProp(_el$
|
|
6394
|
-
setProp(_el$
|
|
6395
|
-
insert(_el$
|
|
6396
|
-
insert(_el$
|
|
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$
|
|
6402
|
-
setProp(_el$
|
|
6403
|
-
insert(_el$
|
|
6404
|
-
effect((_$p) => setProp(_el$
|
|
6405
|
-
return _el$
|
|
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$
|
|
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$
|
|
6414
|
-
setProp(_el$
|
|
6415
|
-
insert(_el$
|
|
6416
|
-
effect((_$p) => setProp(_el$
|
|
6417
|
-
return _el$
|
|
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$
|
|
6423
|
-
_v$1 !== _p$.t && (_p$.t = setProp(_el$
|
|
6424
|
-
_v$10 !== _p$.a && (_p$.a = setProp(_el$
|
|
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$
|
|
6424
|
+
return _el$21;
|
|
6432
6425
|
})();
|
|
6433
6426
|
}
|
|
6434
6427
|
}));
|
|
6435
|
-
return _el$
|
|
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
|
|
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
|
|
16963
|
+
var init_settings4 = () => {};
|
|
16885
16964
|
|
|
16886
16965
|
// src/engine/gemini-local/capabilities.ts
|
|
16887
16966
|
var geminiCapabilities, geminiIdentity;
|
|
16888
|
-
var
|
|
16889
|
-
|
|
16890
|
-
|
|
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.
|
|
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/
|
|
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
|
|
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(
|
|
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(
|
|
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,
|
|
21845
|
-
var
|
|
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
|
-
|
|
22738
|
+
defaultDeps9 = {
|
|
21855
22739
|
fileExists(p2) {
|
|
21856
22740
|
try {
|
|
21857
|
-
return
|
|
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
|
|
22750
|
+
return homedir19();
|
|
21867
22751
|
},
|
|
21868
22752
|
which(name) {
|
|
21869
22753
|
const cmd = process.platform === "win32" ? "where" : "which";
|
|
21870
|
-
const out =
|
|
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 &&
|
|
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
|
|
21888
|
-
import { homedir as
|
|
21889
|
-
import
|
|
21890
|
-
async function listChatFiles(deps =
|
|
21891
|
-
const roots = [
|
|
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 =
|
|
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(
|
|
22782
|
+
out.push(path15.join(chatsDir, f2));
|
|
21899
22783
|
}
|
|
21900
22784
|
}
|
|
21901
22785
|
return out;
|
|
21902
22786
|
}
|
|
21903
|
-
async function
|
|
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
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
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 (
|
|
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 (!
|
|
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 (!
|
|
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 (!
|
|
22951
|
+
if (!isObject12(tokens))
|
|
22068
22952
|
return;
|
|
22069
22953
|
return {
|
|
22070
|
-
input_tokens:
|
|
22071
|
-
output_tokens:
|
|
22072
|
-
cache_read_input_tokens:
|
|
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 (
|
|
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 (!
|
|
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
|
|
23000
|
+
function numberOr4(v2, fallback) {
|
|
22117
23001
|
return typeof v2 === "number" && Number.isFinite(v2) ? v2 : fallback;
|
|
22118
23002
|
}
|
|
22119
|
-
function
|
|
23003
|
+
function isObject12(v2) {
|
|
22120
23004
|
return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
|
|
22121
23005
|
}
|
|
22122
|
-
var
|
|
22123
|
-
var
|
|
22124
|
-
|
|
23006
|
+
var defaultDeps10;
|
|
23007
|
+
var init_history4 = __esm(() => {
|
|
23008
|
+
defaultDeps10 = {
|
|
22125
23009
|
geminiDir() {
|
|
22126
|
-
return
|
|
23010
|
+
return path15.join(homedir20(), ".gemini");
|
|
22127
23011
|
},
|
|
22128
23012
|
async readdir(p2) {
|
|
22129
23013
|
try {
|
|
22130
|
-
return await
|
|
23014
|
+
return await readdir7(p2);
|
|
22131
23015
|
} catch {
|
|
22132
23016
|
return [];
|
|
22133
23017
|
}
|
|
22134
23018
|
},
|
|
22135
23019
|
async readFile(p2) {
|
|
22136
|
-
return await
|
|
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
|
|
22144
|
-
import { homedir as
|
|
22145
|
-
import
|
|
22146
|
-
async function
|
|
22147
|
-
const actualDeps = deps ??
|
|
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 =
|
|
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
|
|
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,
|
|
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 =
|
|
23060
|
+
const normalized = path16.resolve(cwd);
|
|
22177
23061
|
const ids = new Set;
|
|
22178
|
-
const projectsRaw = await deps.readFile(
|
|
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 (
|
|
23066
|
+
if (isObject13(parsed) && isObject13(parsed.projects)) {
|
|
22183
23067
|
for (const [projectPath, id] of Object.entries(parsed.projects)) {
|
|
22184
|
-
if (typeof id === "string" &&
|
|
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 [
|
|
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(
|
|
22193
|
-
if (marker &&
|
|
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
|
|
22200
|
-
const ar =
|
|
22201
|
-
const br =
|
|
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
|
|
23090
|
+
function isObject13(v2) {
|
|
22207
23091
|
return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
|
|
22208
23092
|
}
|
|
22209
|
-
var
|
|
22210
|
-
var
|
|
22211
|
-
|
|
22212
|
-
|
|
23093
|
+
var PREVIEW_CHAR_CAP3 = 200, defaultDeps11;
|
|
23094
|
+
var init_sessions4 = __esm(() => {
|
|
23095
|
+
init_history4();
|
|
23096
|
+
defaultDeps11 = {
|
|
22213
23097
|
geminiDir() {
|
|
22214
|
-
return
|
|
23098
|
+
return path16.join(homedir21(), ".gemini");
|
|
22215
23099
|
},
|
|
22216
23100
|
async readdir(p2) {
|
|
22217
23101
|
try {
|
|
22218
|
-
return await
|
|
23102
|
+
return await readdir8(p2);
|
|
22219
23103
|
} catch {
|
|
22220
23104
|
return [];
|
|
22221
23105
|
}
|
|
22222
23106
|
},
|
|
22223
23107
|
async readFile(p2) {
|
|
22224
|
-
return await
|
|
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
|
|
23115
|
+
import { spawn as spawn13 } from "child_process";
|
|
22232
23116
|
function spawnGeminiProcess(opts) {
|
|
22233
|
-
const args =
|
|
22234
|
-
const proc =
|
|
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
|
|
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
|
|
23140
|
+
var init_spawn4 = () => {};
|
|
22257
23141
|
|
|
22258
23142
|
// src/engine/gemini-local/usage.ts
|
|
22259
23143
|
function geminiStatsToSnapshot(stats) {
|
|
22260
|
-
if (!
|
|
23144
|
+
if (!isObject14(stats))
|
|
22261
23145
|
return;
|
|
22262
|
-
const inputTokens =
|
|
22263
|
-
const outputTokens =
|
|
22264
|
-
const cached3 =
|
|
22265
|
-
const total =
|
|
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 &&
|
|
23153
|
+
if (input === 0 && output === 0 && isObject14(stats.models)) {
|
|
22270
23154
|
for (const modelStats of Object.values(stats.models)) {
|
|
22271
|
-
if (!
|
|
23155
|
+
if (!isObject14(modelStats))
|
|
22272
23156
|
continue;
|
|
22273
|
-
input +=
|
|
22274
|
-
output +=
|
|
22275
|
-
cacheRead +=
|
|
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
|
|
23171
|
+
function numberOr5(v2, fallback) {
|
|
22288
23172
|
return typeof v2 === "number" && Number.isFinite(v2) ? v2 : fallback;
|
|
22289
23173
|
}
|
|
22290
|
-
function
|
|
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: ${
|
|
23189
|
+
yield { type: "error", message: `gemini stream-json parse failed: ${stringifyErr5(err)}` };
|
|
22306
23190
|
continue;
|
|
22307
23191
|
}
|
|
22308
|
-
if (!
|
|
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:
|
|
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 ?? (
|
|
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*
|
|
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
|
|
23264
|
+
function isObject15(v2) {
|
|
22381
23265
|
return typeof v2 === "object" && v2 !== null && !Array.isArray(v2);
|
|
22382
23266
|
}
|
|
22383
|
-
function
|
|
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
|
|
23322
|
+
return readHistoryWithMetrics3(sessionId);
|
|
22439
23323
|
}
|
|
22440
23324
|
async deleteHistory(sessionId) {
|
|
22441
|
-
return
|
|
23325
|
+
return deleteHistory4(sessionId);
|
|
22442
23326
|
}
|
|
22443
23327
|
async listSessions(cwd) {
|
|
22444
|
-
return
|
|
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
|
-
|
|
22482
|
-
stderrTail = (stderrTail + chunk).slice(-
|
|
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(
|
|
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(
|
|
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,
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
23475
|
+
var STDERR_TAIL_CAP3, PROCESS_EXIT_GRACE_MS2 = 500;
|
|
22592
23476
|
var init_gemini_local = __esm(() => {
|
|
22593
|
-
|
|
22594
|
-
|
|
22595
|
-
|
|
22596
|
-
|
|
22597
|
-
|
|
23477
|
+
init_binary4();
|
|
23478
|
+
init_capabilities4();
|
|
23479
|
+
init_history4();
|
|
23480
|
+
init_sessions4();
|
|
23481
|
+
init_spawn4();
|
|
22598
23482
|
init_stream2();
|
|
22599
|
-
|
|
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
|
|
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 ??
|
|
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
|
|
23998
|
+
import { spawnSync as spawnSync8 } from "child_process";
|
|
23113
23999
|
function git(cwd, args) {
|
|
23114
24000
|
try {
|
|
23115
|
-
const out =
|
|
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
|
|
24356
|
+
import { spawnSync as spawnSync9 } from "child_process";
|
|
23471
24357
|
function git2(cwd, args) {
|
|
23472
24358
|
try {
|
|
23473
|
-
const out =
|
|
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
|
|
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 =
|
|
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
|
|
24468
|
+
import { spawnSync as spawnSync10 } from "child_process";
|
|
23583
24469
|
function run(cwd, command, args, timeout) {
|
|
23584
24470
|
try {
|
|
23585
|
-
const out =
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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 =
|
|
25492
|
-
const callerPath =
|
|
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 =
|
|
25554
|
-
const base =
|
|
25555
|
-
return base === ".git" ?
|
|
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 || !
|
|
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
|
|
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
|
|
26498
|
+
import { homedir as homedir23 } from "os";
|
|
25613
26499
|
async function createKobeCore(options = {}) {
|
|
25614
|
-
const homeDir2 = options.homeDir ?? process.env.KOBE_HOME_DIR ??
|
|
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
|
|
25680
|
-
import { homedir as
|
|
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(
|
|
25712
|
-
const
|
|
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
|
|
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
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
|
27236
|
-
import { homedir as
|
|
27237
|
-
import
|
|
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
|
|
27242
|
-
return
|
|
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 ??
|
|
27247
|
-
return
|
|
28132
|
+
const dir = override ?? path19.join(home, ".codex");
|
|
28133
|
+
return path19.join(dir, "auth.json");
|
|
27248
28134
|
}
|
|
27249
28135
|
function geminiOauthCredsPath(home) {
|
|
27250
|
-
return
|
|
28136
|
+
return path19.join(home, ".gemini", "oauth_creds.json");
|
|
27251
28137
|
}
|
|
27252
28138
|
function geminiSettingsPath(home) {
|
|
27253
|
-
return
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
28409
|
+
init_binary4();
|
|
28410
|
+
defaultDeps12 = {
|
|
27464
28411
|
readFile(p2) {
|
|
27465
28412
|
try {
|
|
27466
|
-
|
|
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
|
|
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$
|
|
27900
|
-
insertNode(_el$
|
|
27901
|
-
setProp(_el$
|
|
27902
|
-
setProp(_el$
|
|
27903
|
-
setProp(_el$
|
|
27904
|
-
insert(_el$
|
|
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$
|
|
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$
|
|
27914
|
-
setProp(_el$
|
|
27915
|
-
insert(_el$
|
|
27916
|
-
effect((_$p) => setProp(_el$
|
|
27917
|
-
return _el$
|
|
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$
|
|
27922
|
-
insertNode(_el$
|
|
27923
|
-
effect((_$p) => setProp(_el$
|
|
27924
|
-
return _el$
|
|
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$
|
|
28878
|
+
insert(_el$60, createComponent2(Show, {
|
|
27928
28879
|
get when() {
|
|
27929
28880
|
return s2().accountError;
|
|
27930
28881
|
},
|
|
27931
28882
|
children: (err) => (() => {
|
|
27932
|
-
var _el$
|
|
27933
|
-
setProp(_el$
|
|
27934
|
-
insert(_el$
|
|
27935
|
-
effect((_$p) => setProp(_el$
|
|
27936
|
-
return _el$
|
|
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$
|
|
27940
|
-
return _el$
|
|
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$
|
|
27964
|
-
insertNode(_el$
|
|
27965
|
-
setProp(_el$
|
|
27966
|
-
setProp(_el$
|
|
27967
|
-
setProp(_el$
|
|
27968
|
-
insert(_el$
|
|
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$
|
|
28923
|
+
insert(_el$66, () => {
|
|
27973
28924
|
const a2 = s2().account;
|
|
27974
28925
|
if (a2.kind === "chatgpt") {
|
|
27975
28926
|
return (() => {
|
|
27976
|
-
var _el$
|
|
27977
|
-
setProp(_el$
|
|
27978
|
-
insert(_el$
|
|
27979
|
-
effect((_$p) => setProp(_el$
|
|
27980
|
-
return _el$
|
|
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$
|
|
27986
|
-
insertNode(_el$
|
|
27987
|
-
effect((_$p) => setProp(_el$
|
|
27988
|
-
return _el$
|
|
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$
|
|
27992
|
-
insertNode(_el$
|
|
27993
|
-
effect((_$p) => setProp(_el$
|
|
27994
|
-
return _el$
|
|
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$
|
|
28948
|
+
insert(_el$66, createComponent2(Show, {
|
|
27998
28949
|
get when() {
|
|
27999
28950
|
return s2().accountError;
|
|
28000
28951
|
},
|
|
28001
28952
|
children: (err) => (() => {
|
|
28002
|
-
var _el$
|
|
28003
|
-
setProp(_el$
|
|
28004
|
-
insert(_el$
|
|
28005
|
-
effect((_$p) => setProp(_el$
|
|
28006
|
-
return _el$
|
|
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$
|
|
28010
|
-
return _el$
|
|
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(`
|
|
28967
|
+
insertNode(_el$51, createTextNode(`copilot`));
|
|
28017
28968
|
insert(_el$50, createComponent2(Show, {
|
|
28018
28969
|
get when() {
|
|
28019
|
-
return props.
|
|
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.
|
|
28981
|
+
return props.copilotStatus();
|
|
28031
28982
|
},
|
|
28032
28983
|
children: (s2) => (() => {
|
|
28033
|
-
var _el$
|
|
28034
|
-
insertNode(_el$
|
|
28035
|
-
setProp(_el$
|
|
28036
|
-
setProp(_el$
|
|
28037
|
-
setProp(_el$
|
|
28038
|
-
insert(_el$
|
|
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$
|
|
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$
|
|
28048
|
-
setProp(_el$
|
|
28049
|
-
insert(_el$
|
|
28050
|
-
effect((_$p) => setProp(_el$
|
|
28051
|
-
return _el$
|
|
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$
|
|
28057
|
-
insertNode(_el$
|
|
28058
|
-
effect((_$p) => setProp(_el$
|
|
28059
|
-
return _el$
|
|
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$
|
|
28065
|
-
setProp(_el$
|
|
28066
|
-
insert(_el$
|
|
28067
|
-
effect((_$p) => setProp(_el$
|
|
28068
|
-
return _el$
|
|
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$
|
|
28073
|
-
insertNode(_el$
|
|
28074
|
-
effect((_$p) => setProp(_el$
|
|
28075
|
-
return _el$
|
|
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$
|
|
29097
|
+
insert(_el$82, createComponent2(Show, {
|
|
28079
29098
|
get when() {
|
|
28080
29099
|
return s2().accountError;
|
|
28081
29100
|
},
|
|
28082
29101
|
children: (err) => (() => {
|
|
28083
|
-
var _el$
|
|
28084
|
-
setProp(_el$
|
|
28085
|
-
insert(_el$
|
|
28086
|
-
effect((_$p) => setProp(_el$
|
|
28087
|
-
return _el$
|
|
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$
|
|
28091
|
-
return _el$
|
|
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$
|
|
28126
|
-
insertNode(_el$
|
|
28127
|
-
insertNode(_el$
|
|
28128
|
-
insertNode(_el$
|
|
28129
|
-
insertNode(_el$
|
|
28130
|
-
setProp(_el$
|
|
28131
|
-
setProp(_el$
|
|
28132
|
-
insertNode(_el$
|
|
28133
|
-
insertNode(_el$
|
|
28134
|
-
setProp(_el$
|
|
28135
|
-
insert(_el$
|
|
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$
|
|
28141
|
-
setProp(_el$
|
|
28142
|
-
insert(_el$
|
|
28143
|
-
effect((_$p) => setProp(_el$
|
|
28144
|
-
return _el$
|
|
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$
|
|
28147
|
-
insertNode(_el$
|
|
28148
|
-
setProp(_el$
|
|
28149
|
-
setProp(_el$
|
|
28150
|
-
setProp(_el$
|
|
28151
|
-
insert(_el$
|
|
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$
|
|
28158
|
-
insertNode(_el$
|
|
28159
|
-
insertNode(_el$
|
|
28160
|
-
setProp(_el$
|
|
28161
|
-
setProp(_el$
|
|
28162
|
-
setProp(_el$
|
|
28163
|
-
setProp(_el$
|
|
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$
|
|
28169
|
-
insert(_el$
|
|
28170
|
-
insert(_el$
|
|
28171
|
-
setProp(_el$
|
|
28172
|
-
insert(_el$
|
|
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$
|
|
28175
|
-
_v$
|
|
28176
|
-
_v$
|
|
28177
|
-
_v$
|
|
28178
|
-
_v$
|
|
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$
|
|
29209
|
+
return _el$100;
|
|
28187
29210
|
})();
|
|
28188
29211
|
}
|
|
28189
29212
|
}));
|
|
28190
29213
|
effect((_p$) => {
|
|
28191
|
-
var _v$
|
|
28192
|
-
_v$
|
|
28193
|
-
_v$
|
|
28194
|
-
_v$
|
|
28195
|
-
_v$
|
|
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$
|
|
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$
|
|
28214
|
-
insertNode(_el$
|
|
28215
|
-
insertNode(_el$
|
|
28216
|
-
insertNode(_el$
|
|
28217
|
-
setProp(_el$
|
|
28218
|
-
setProp(_el$
|
|
28219
|
-
insertNode(_el$
|
|
28220
|
-
insertNode(_el$
|
|
28221
|
-
setProp(_el$
|
|
28222
|
-
insertNode(_el$
|
|
28223
|
-
setProp(_el$
|
|
28224
|
-
setProp(_el$
|
|
28225
|
-
setProp(_el$
|
|
28226
|
-
setProp(_el$
|
|
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$
|
|
28232
|
-
insert(_el$
|
|
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$
|
|
28238
|
-
insertNode(_el$
|
|
28239
|
-
insertNode(_el$
|
|
28240
|
-
insertNode(_el$
|
|
28241
|
-
setProp(_el$
|
|
28242
|
-
setProp(_el$
|
|
28243
|
-
setProp(_el$
|
|
28244
|
-
insertNode(_el$
|
|
28245
|
-
insertNode(_el$
|
|
28246
|
-
setProp(_el$
|
|
28247
|
-
insertNode(_el$
|
|
28248
|
-
setProp(_el$
|
|
28249
|
-
setProp(_el$
|
|
28250
|
-
setProp(_el$
|
|
28251
|
-
setProp(_el$
|
|
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$
|
|
29279
|
+
insertNode(_el$117, createTextNode(`[enter] Restart`));
|
|
28257
29280
|
effect((_p$) => {
|
|
28258
|
-
var _v$
|
|
28259
|
-
_v$
|
|
28260
|
-
_v$
|
|
28261
|
-
_v$
|
|
28262
|
-
_v$
|
|
28263
|
-
_v$
|
|
28264
|
-
_v$
|
|
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$
|
|
29297
|
+
return _el$111;
|
|
28275
29298
|
}
|
|
28276
29299
|
}), null);
|
|
28277
29300
|
effect((_p$) => {
|
|
28278
|
-
var _v$
|
|
28279
|
-
_v$
|
|
28280
|
-
_v$
|
|
28281
|
-
_v$
|
|
28282
|
-
_v$
|
|
28283
|
-
_v$
|
|
28284
|
-
_v$
|
|
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$
|
|
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
|
|
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
|
|
28772
|
-
const segments =
|
|
28773
|
-
cachedPlayer = PLAYERS.find((p2) => segments.some((dir) =>
|
|
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((
|
|
29829
|
+
ensureAsset().then((path20) => {
|
|
28793
29830
|
try {
|
|
28794
|
-
const proc = Bun.spawn(args(player,
|
|
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
|
|
30463
|
-
import { existsSync as
|
|
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 ??
|
|
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((
|
|
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 ??
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
33725
|
+
let stat10;
|
|
32689
33726
|
try {
|
|
32690
|
-
|
|
33727
|
+
stat10 = fs5.statSync(trimmed);
|
|
32691
33728
|
} catch {
|
|
32692
33729
|
return `path does not exist: ${trimmed}`;
|
|
32693
33730
|
}
|
|
32694
|
-
if (!
|
|
33731
|
+
if (!stat10.isDirectory())
|
|
32695
33732
|
return `not a directory: ${trimmed}`;
|
|
32696
33733
|
try {
|
|
32697
|
-
const { spawnSync:
|
|
32698
|
-
const out =
|
|
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:
|
|
32716
|
-
const out =
|
|
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:
|
|
32737
|
-
const out =
|
|
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 =
|
|
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
|
|
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
|
|
32875
|
-
if (!
|
|
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(
|
|
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(
|
|
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 =
|
|
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((
|
|
35020
|
-
for (const
|
|
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(
|
|
36079
|
+
const index = text.indexOf(path21, from);
|
|
35024
36080
|
if (index < 0)
|
|
35025
36081
|
break;
|
|
35026
|
-
const end = index +
|
|
36082
|
+
const end = index + path21.length;
|
|
35027
36083
|
if (hasStartBoundary(text, index) && hasEndBoundary(text, end)) {
|
|
35028
|
-
if (!seen.has(
|
|
35029
|
-
seen.add(
|
|
35030
|
-
matches.push({ path:
|
|
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(
|
|
36096
|
+
function formatPreviewPathLabel(path21, maxCells) {
|
|
35041
36097
|
if (maxCells <= 3)
|
|
35042
|
-
return
|
|
35043
|
-
if (
|
|
35044
|
-
return
|
|
35045
|
-
const slash =
|
|
35046
|
-
const filename = slash >= 0 ?
|
|
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 `${
|
|
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 `${
|
|
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
|
|
35900
|
-
import { statSync as
|
|
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 =
|
|
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 =
|
|
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
|
|
35984
|
-
import { appendFile as appendFile2, mkdir as mkdir6, readFile as
|
|
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(
|
|
35990
|
-
if (!
|
|
37045
|
+
function loadFromDisk(path21 = defaultHistoryPath()) {
|
|
37046
|
+
if (!existsSync13(path21))
|
|
35991
37047
|
return [];
|
|
35992
37048
|
let text;
|
|
35993
37049
|
try {
|
|
35994
|
-
text = readFileSync10(
|
|
37050
|
+
text = readFileSync10(path21, "utf8");
|
|
35995
37051
|
} catch (err) {
|
|
35996
|
-
console.warn(`[kobe] could not read composer history at ${
|
|
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 ${
|
|
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,
|
|
37084
|
+
function appendToDisk(entry, path21 = defaultHistoryPath()) {
|
|
36029
37085
|
const next = writeQueue.then(async () => {
|
|
36030
37086
|
try {
|
|
36031
|
-
const dir = dirname8(
|
|
37087
|
+
const dir = dirname8(path21);
|
|
36032
37088
|
await mkdir6(dir, { recursive: true });
|
|
36033
37089
|
const line = `${JSON.stringify(entry)}
|
|
36034
37090
|
`;
|
|
36035
|
-
await appendFile2(
|
|
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(
|
|
37099
|
+
async function pruneToCap(path21 = defaultHistoryPath(), cap = DISK_HISTORY_CAP) {
|
|
36044
37100
|
try {
|
|
36045
|
-
if (!
|
|
37101
|
+
if (!existsSync13(path21))
|
|
36046
37102
|
return;
|
|
36047
|
-
const text = await
|
|
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 = `${
|
|
37109
|
+
const tmp = `${path21}.tmp`;
|
|
36054
37110
|
await writeFile5(tmp, `${keep.join(`
|
|
36055
37111
|
`)}
|
|
36056
37112
|
`, { encoding: "utf8", mode: 384 });
|
|
36057
|
-
await rename2(tmp,
|
|
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
|
|
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
|
-
|
|
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
|
|
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(), `${
|
|
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(
|
|
36647
|
-
if (
|
|
36648
|
-
return
|
|
36649
|
-
return
|
|
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((
|
|
36657
|
-
path:
|
|
36658
|
-
displayPath: formatDisplayPath(
|
|
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
|
|
36664
|
-
const lower =
|
|
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 -=
|
|
36679
|
-
matches.push({ path:
|
|
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(
|
|
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(`@${
|
|
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
|
-
|
|
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
|
|
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} ${
|
|
38226
|
-
return `${verb} ${
|
|
39281
|
+
return `${verb} ${path21}`;
|
|
39282
|
+
return `${verb} ${path21} \xB7 ${parts.join(", ")}`;
|
|
38227
39283
|
}
|
|
38228
39284
|
function makeMultiEditHeader(filePath, count, adds, removes) {
|
|
38229
|
-
const
|
|
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 ${
|
|
38246
|
-
return `Edited ${
|
|
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
|
|
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
|
|
41068
|
-
|
|
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 =
|
|
41078
|
-
const [cursor, setCursor] = createSignal(
|
|
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
|
|
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 :
|
|
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) =>
|
|
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 :
|
|
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) =>
|
|
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 :
|
|
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) =>
|
|
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 :
|
|
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) =>
|
|
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
|
|
42361
|
+
return rows();
|
|
41285
42362
|
},
|
|
41286
|
-
children: (
|
|
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")
|
|
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(() =>
|
|
41322
|
-
return () => _c$3() ? (() => {
|
|
41323
|
-
var _el$
|
|
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, () =>
|
|
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$
|
|
41330
|
-
insertNode(_el$
|
|
41331
|
-
setProp(_el$
|
|
41332
|
-
effect((_$p) => setProp(_el$
|
|
41333
|
-
return _el$
|
|
41334
|
-
})() : null
|
|
41335
|
-
|
|
41336
|
-
|
|
41337
|
-
|
|
41338
|
-
|
|
41339
|
-
|
|
41340
|
-
|
|
41341
|
-
|
|
41342
|
-
|
|
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
|
|
41386
|
-
|
|
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 %
|
|
41389
|
-
for (let offset = 0;offset <
|
|
41390
|
-
const idx = ((normalized + offset * step) %
|
|
41391
|
-
|
|
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
|
|
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 =
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
44344
|
-
return
|
|
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 ??
|
|
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
|
-
|
|
46082
|
+
init_history5();
|
|
44961
46083
|
init_filetree();
|
|
44962
46084
|
init_preview();
|
|
44963
46085
|
init_Sidebar();
|