@sma1lboy/kobe 0.7.11 → 0.7.12
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 +266 -163
- package/package.json +2 -1
package/dist/cli/index.js
CHANGED
|
@@ -70,7 +70,7 @@ var init_package = __esm(() => {
|
|
|
70
70
|
package_default = {
|
|
71
71
|
$schema: "https://json.schemastore.org/package.json",
|
|
72
72
|
name: "@sma1lboy/kobe",
|
|
73
|
-
version: "0.7.
|
|
73
|
+
version: "0.7.12",
|
|
74
74
|
description: "TUI orchestrator for Claude Code (codename)",
|
|
75
75
|
type: "module",
|
|
76
76
|
packageManager: "bun@1.3.13",
|
|
@@ -118,6 +118,7 @@ var init_package = __esm(() => {
|
|
|
118
118
|
"@biomejs/biome": "1.9.4",
|
|
119
119
|
"@tsconfig/bun": "1.0.9",
|
|
120
120
|
"@types/bun": "1.3.12",
|
|
121
|
+
"@types/node": "25.6.2",
|
|
121
122
|
knip: "^6.14.2",
|
|
122
123
|
"node-pty": "^1.1.0",
|
|
123
124
|
typescript: "5.8.2",
|
|
@@ -663,6 +664,33 @@ class TaskIndexStore {
|
|
|
663
664
|
this.notifyListeners();
|
|
664
665
|
return next;
|
|
665
666
|
}
|
|
667
|
+
async move(id, delta, withinIds) {
|
|
668
|
+
this.assertLoaded();
|
|
669
|
+
const task = this.cache.tasks.find((t) => t.id === id);
|
|
670
|
+
if (!task)
|
|
671
|
+
throw new Error(`task not found: ${id}`);
|
|
672
|
+
const ids = withinIds?.length ? withinIds : this.cache.tasks.map((t) => t.id);
|
|
673
|
+
const pos = ids.indexOf(String(id));
|
|
674
|
+
if (pos < 0)
|
|
675
|
+
throw new Error(`task not movable in current group: ${id}`);
|
|
676
|
+
const targetId = ids[pos + delta];
|
|
677
|
+
if (!targetId)
|
|
678
|
+
return task;
|
|
679
|
+
const fromIdx = this.cache.tasks.findIndex((t) => t.id === id);
|
|
680
|
+
const toIdx = this.cache.tasks.findIndex((t) => t.id === targetId);
|
|
681
|
+
if (fromIdx < 0 || toIdx < 0 || fromIdx === toIdx)
|
|
682
|
+
return task;
|
|
683
|
+
const [moved] = this.cache.tasks.splice(fromIdx, 1);
|
|
684
|
+
if (!moved)
|
|
685
|
+
return task;
|
|
686
|
+
const adjustedToIdx = fromIdx < toIdx ? toIdx - 1 : toIdx;
|
|
687
|
+
const insertAt = delta > 0 ? adjustedToIdx + 1 : adjustedToIdx;
|
|
688
|
+
const next = { ...moved, updatedAt: new Date().toISOString() };
|
|
689
|
+
this.cache.tasks.splice(insertAt, 0, next);
|
|
690
|
+
await this.save();
|
|
691
|
+
this.notifyListeners();
|
|
692
|
+
return next;
|
|
693
|
+
}
|
|
666
694
|
async archive(id, status = "done") {
|
|
667
695
|
return this.update(id, { status });
|
|
668
696
|
}
|
|
@@ -3096,6 +3124,13 @@ class Orchestrator {
|
|
|
3096
3124
|
return;
|
|
3097
3125
|
await this.store.update(task.id, { pinned: next });
|
|
3098
3126
|
}
|
|
3127
|
+
async moveTask(id, delta) {
|
|
3128
|
+
const task = this.requireTask(id);
|
|
3129
|
+
if (task.kind === "main")
|
|
3130
|
+
return;
|
|
3131
|
+
const groupIds = this.store.list().filter((t) => (t.kind ?? "task") !== "main" && t.archived === task.archived && (t.pinned ?? false) === (task.pinned ?? false)).map((t) => String(t.id));
|
|
3132
|
+
await this.store.move(task.id, delta, groupIds);
|
|
3133
|
+
}
|
|
3099
3134
|
async setArchived(id, archived) {
|
|
3100
3135
|
const task = this.requireTask(id);
|
|
3101
3136
|
const next = archived ?? !task.archived;
|
|
@@ -5344,6 +5379,14 @@ async function startDaemonServer(orch, options = {}) {
|
|
|
5344
5379
|
await orch.setPinned(taskId, optionalBoolean(payload, "pinned"));
|
|
5345
5380
|
return {};
|
|
5346
5381
|
}
|
|
5382
|
+
case "task.move": {
|
|
5383
|
+
const taskId = requireString(payload, "taskId");
|
|
5384
|
+
const direction = requireString(payload, "direction");
|
|
5385
|
+
if (direction !== "up" && direction !== "down")
|
|
5386
|
+
throw new Error("direction must be up or down");
|
|
5387
|
+
await orch.moveTask(taskId, direction === "up" ? -1 : 1);
|
|
5388
|
+
return {};
|
|
5389
|
+
}
|
|
5347
5390
|
case "task.status": {
|
|
5348
5391
|
const taskId = requireString(payload, "taskId");
|
|
5349
5392
|
const status = requireString(payload, "status");
|
|
@@ -10187,6 +10230,9 @@ class RemoteOrchestrator {
|
|
|
10187
10230
|
async setPinned(id, pinned) {
|
|
10188
10231
|
await this.client.request("task.pin", { taskId: String(id), pinned });
|
|
10189
10232
|
}
|
|
10233
|
+
async moveTask(id, delta) {
|
|
10234
|
+
await this.client.request("task.move", { taskId: String(id), direction: delta < 0 ? "up" : "down" });
|
|
10235
|
+
}
|
|
10190
10236
|
async setArchived(id, archived) {
|
|
10191
10237
|
await this.client.request("task.archive", { taskId: String(id), archived });
|
|
10192
10238
|
}
|
|
@@ -17106,28 +17152,51 @@ function useSidebarBindings(opts) {
|
|
|
17106
17152
|
return ids[idx];
|
|
17107
17153
|
};
|
|
17108
17154
|
const searchModeAccessor = () => opts.searchMode?.() ?? false;
|
|
17155
|
+
const moveModeAccessor = () => opts.moveMode?.() ?? false;
|
|
17109
17156
|
useBindings(() => ({
|
|
17110
17157
|
enabled: opts.focused() && !searchModeAccessor(),
|
|
17111
17158
|
bindings: bindByIds({
|
|
17112
17159
|
"sidebar.nav": (evt) => {
|
|
17160
|
+
if (moveModeAccessor()) {
|
|
17161
|
+
const id = cursorTaskId();
|
|
17162
|
+
if (id === undefined)
|
|
17163
|
+
return;
|
|
17164
|
+
if (evt.name === "j" || evt.name === "down")
|
|
17165
|
+
opts.onMoveRequest?.(id, 1);
|
|
17166
|
+
else if (evt.name === "k" || evt.name === "up")
|
|
17167
|
+
opts.onMoveRequest?.(id, -1);
|
|
17168
|
+
return;
|
|
17169
|
+
}
|
|
17113
17170
|
if (evt.name === "j" || evt.name === "down")
|
|
17114
17171
|
ctrl.moveDown();
|
|
17115
17172
|
else if (evt.name === "k" || evt.name === "up")
|
|
17116
17173
|
ctrl.moveUp();
|
|
17117
17174
|
},
|
|
17118
|
-
"sidebar.select": () =>
|
|
17175
|
+
"sidebar.select": () => {
|
|
17176
|
+
if (moveModeAccessor()) {
|
|
17177
|
+
opts.onMoveModeExit?.();
|
|
17178
|
+
return;
|
|
17179
|
+
}
|
|
17180
|
+
ctrl.selectCurrent();
|
|
17181
|
+
},
|
|
17119
17182
|
"sidebar.goto": (evt) => {
|
|
17183
|
+
if (moveModeAccessor())
|
|
17184
|
+
return;
|
|
17120
17185
|
if (evt.shift)
|
|
17121
17186
|
ctrl.pressShiftG();
|
|
17122
17187
|
else
|
|
17123
17188
|
ctrl.pressG();
|
|
17124
17189
|
},
|
|
17125
17190
|
"sidebar.delete": () => {
|
|
17191
|
+
if (moveModeAccessor())
|
|
17192
|
+
return;
|
|
17126
17193
|
const id = cursorTaskId();
|
|
17127
17194
|
if (id !== undefined)
|
|
17128
17195
|
opts.onDeleteRequest?.(id);
|
|
17129
17196
|
},
|
|
17130
17197
|
"sidebar.archive": () => {
|
|
17198
|
+
if (moveModeAccessor())
|
|
17199
|
+
return;
|
|
17131
17200
|
const id = cursorTaskId();
|
|
17132
17201
|
if (id !== undefined)
|
|
17133
17202
|
opts.onArchiveRequest?.(id);
|
|
@@ -17140,20 +17209,32 @@ function useSidebarBindings(opts) {
|
|
|
17140
17209
|
opts.onLocalMergeRequest?.(id);
|
|
17141
17210
|
},
|
|
17142
17211
|
"sidebar.rename": () => {
|
|
17212
|
+
if (moveModeAccessor())
|
|
17213
|
+
return;
|
|
17143
17214
|
const id = cursorTaskId();
|
|
17144
17215
|
if (id !== undefined)
|
|
17145
17216
|
opts.onRenameRequest?.(id);
|
|
17146
17217
|
},
|
|
17147
17218
|
"sidebar.pin": (evt) => {
|
|
17219
|
+
if (moveModeAccessor())
|
|
17220
|
+
return;
|
|
17148
17221
|
if (!evt.shift)
|
|
17149
17222
|
return;
|
|
17150
17223
|
const id = cursorTaskId();
|
|
17151
17224
|
if (id !== undefined)
|
|
17152
17225
|
opts.onPinRequest?.(id);
|
|
17153
17226
|
},
|
|
17154
|
-
"sidebar.search.enter": () =>
|
|
17227
|
+
"sidebar.search.enter": () => {
|
|
17228
|
+
if (moveModeAccessor())
|
|
17229
|
+
return;
|
|
17230
|
+
opts.onSearchEnter?.();
|
|
17231
|
+
}
|
|
17155
17232
|
})
|
|
17156
17233
|
}));
|
|
17234
|
+
useBindings(() => ({
|
|
17235
|
+
enabled: opts.focused() && moveModeAccessor(),
|
|
17236
|
+
bindings: [{ key: "escape", cmd: () => opts.onMoveModeExit?.() }]
|
|
17237
|
+
}));
|
|
17157
17238
|
useBindings(() => ({
|
|
17158
17239
|
enabled: opts.focused(),
|
|
17159
17240
|
bindings: bindByIds({
|
|
@@ -17338,6 +17419,9 @@ function Sidebar(props) {
|
|
|
17338
17419
|
onDeleteRequest: (id) => props.onDeleteRequest?.(id),
|
|
17339
17420
|
onArchiveRequest: (id) => props.onArchiveRequest?.(id),
|
|
17340
17421
|
onLocalMergeRequest: (id) => props.onLocalMergeRequest?.(id),
|
|
17422
|
+
moveMode: props.moveMode,
|
|
17423
|
+
onMoveRequest: (id, delta) => props.onMoveRequest?.(id, delta),
|
|
17424
|
+
onMoveModeExit: () => props.onMoveModeExit?.(),
|
|
17341
17425
|
onRenameRequest: (id) => props.onRenameRequest?.(id),
|
|
17342
17426
|
onPinRequest: (id) => props.onPinRequest?.(id),
|
|
17343
17427
|
onViewSwitch: (delta) => cycleView(delta),
|
|
@@ -17558,33 +17642,55 @@ function Sidebar(props) {
|
|
|
17558
17642
|
});
|
|
17559
17643
|
const titleText = isMain ? repoBasename(task.repo) : task.title;
|
|
17560
17644
|
const activity = () => props.engineState?.().get(task.id)?.state;
|
|
17561
|
-
const
|
|
17562
|
-
const
|
|
17645
|
+
const hasActivity = () => activity() !== undefined;
|
|
17646
|
+
const loading = () => activity() === "running" || isLive() || !hasActivity() && !isMain && task.status === "in_progress";
|
|
17647
|
+
const activityBadge = () => {
|
|
17563
17648
|
switch (activity()) {
|
|
17564
17649
|
case "rate_limited":
|
|
17565
17650
|
return {
|
|
17566
|
-
|
|
17651
|
+
glyph: "\u25F7",
|
|
17567
17652
|
tone: "warning"
|
|
17568
17653
|
};
|
|
17569
17654
|
case "permission_needed":
|
|
17570
17655
|
return {
|
|
17571
|
-
|
|
17656
|
+
glyph: "?",
|
|
17572
17657
|
tone: "warning"
|
|
17573
17658
|
};
|
|
17574
17659
|
case "error":
|
|
17575
17660
|
return {
|
|
17576
|
-
|
|
17661
|
+
glyph: "\u2715",
|
|
17577
17662
|
tone: "error"
|
|
17578
17663
|
};
|
|
17579
17664
|
case "turn_complete":
|
|
17580
17665
|
return {
|
|
17581
|
-
|
|
17666
|
+
glyph: "\u2713",
|
|
17582
17667
|
tone: "primary"
|
|
17583
17668
|
};
|
|
17584
17669
|
default:
|
|
17585
17670
|
return null;
|
|
17586
17671
|
}
|
|
17587
17672
|
};
|
|
17673
|
+
const stateGlyph = () => {
|
|
17674
|
+
if (loading())
|
|
17675
|
+
return IN_PROGRESS_SPINNER[spinnerFrame()] ?? IN_PROGRESS_SPINNER[0];
|
|
17676
|
+
return activityBadge()?.glyph ?? badge.glyph;
|
|
17677
|
+
};
|
|
17678
|
+
const projectGlyph = () => {
|
|
17679
|
+
if (loading())
|
|
17680
|
+
return IN_PROGRESS_SPINNER[spinnerFrame()] ?? IN_PROGRESS_SPINNER[0];
|
|
17681
|
+
return activityBadge()?.glyph ?? "\u2605";
|
|
17682
|
+
};
|
|
17683
|
+
const stateColor = () => {
|
|
17684
|
+
const active = activityBadge();
|
|
17685
|
+
if (!loading() && active) {
|
|
17686
|
+
if (active.tone === "error")
|
|
17687
|
+
return theme.error;
|
|
17688
|
+
if (active.tone === "warning")
|
|
17689
|
+
return theme.warning;
|
|
17690
|
+
return theme.primary;
|
|
17691
|
+
}
|
|
17692
|
+
return badgeColor();
|
|
17693
|
+
};
|
|
17588
17694
|
const subtitleText = createMemo(() => {
|
|
17589
17695
|
if (task.branch.length > 0)
|
|
17590
17696
|
return truncateBranchLabel(task.branch, subtitleBudget());
|
|
@@ -17639,7 +17745,7 @@ function Sidebar(props) {
|
|
|
17639
17745
|
insert(_el$29, createComponent2(Show, {
|
|
17640
17746
|
when: isMain,
|
|
17641
17747
|
get children() {
|
|
17642
|
-
var _el$30 = createElement("box"), _el$31 = createElement("text"), _el$32 = createElement("box"), _el$33 = createElement("text"), _el$34 = createElement("text");
|
|
17748
|
+
var _el$30 = createElement("box"), _el$31 = createElement("text"), _el$32 = createElement("box"), _el$33 = createElement("text"), _el$34 = createElement("text"), _el$35 = createElement("text");
|
|
17643
17749
|
insertNode(_el$30, _el$31);
|
|
17644
17750
|
insertNode(_el$30, _el$32);
|
|
17645
17751
|
setProp(_el$30, "flexDirection", "row");
|
|
@@ -17648,64 +17754,36 @@ function Sidebar(props) {
|
|
|
17648
17754
|
insert(_el$31, barGlyph);
|
|
17649
17755
|
insertNode(_el$32, _el$33);
|
|
17650
17756
|
insertNode(_el$32, _el$34);
|
|
17757
|
+
insertNode(_el$32, _el$35);
|
|
17651
17758
|
setProp(_el$32, "flexDirection", "row");
|
|
17652
17759
|
setProp(_el$32, "flexGrow", 1);
|
|
17653
17760
|
setProp(_el$32, "paddingRight", 1);
|
|
17654
17761
|
setProp(_el$32, "gap", 0);
|
|
17655
17762
|
setProp(_el$33, "wrapMode", "none");
|
|
17656
|
-
insert(_el$33,
|
|
17657
|
-
var _c$2 = memo2(() => !!loading());
|
|
17658
|
-
return () => _c$2() ? IN_PROGRESS_SPINNER[spinnerFrame()] ?? IN_PROGRESS_SPINNER[0] : "\u2605";
|
|
17659
|
-
})());
|
|
17763
|
+
insert(_el$33, projectGlyph);
|
|
17660
17764
|
setProp(_el$34, "wrapMode", "none");
|
|
17661
17765
|
setProp(_el$34, "flexGrow", 1);
|
|
17662
17766
|
insert(_el$34, () => spacedTitle(titleText, titleBudget()));
|
|
17663
|
-
|
|
17664
|
-
|
|
17665
|
-
return loading();
|
|
17666
|
-
},
|
|
17667
|
-
get children() {
|
|
17668
|
-
var _el$35 = createElement("text");
|
|
17669
|
-
insertNode(_el$35, createTextNode(` working`));
|
|
17670
|
-
setProp(_el$35, "wrapMode", "none");
|
|
17671
|
-
effect((_$p) => setProp(_el$35, "fg", theme.primary, _$p));
|
|
17672
|
-
return _el$35;
|
|
17673
|
-
}
|
|
17674
|
-
}), null);
|
|
17675
|
-
insert(_el$32, createComponent2(Show, {
|
|
17676
|
-
get when() {
|
|
17677
|
-
return !loading();
|
|
17678
|
-
},
|
|
17679
|
-
get children() {
|
|
17680
|
-
var _el$37 = createElement("text");
|
|
17681
|
-
setProp(_el$37, "wrapMode", "none");
|
|
17682
|
-
insert(_el$37, () => ` ${truncatePathTail(abbrevHome(task.repo), subtitleBudget())}`);
|
|
17683
|
-
effect((_p$) => {
|
|
17684
|
-
var _v$15 = theme.textMuted, _v$16 = TextAttributes9.DIM;
|
|
17685
|
-
_v$15 !== _p$.e && (_p$.e = setProp(_el$37, "fg", _v$15, _p$.e));
|
|
17686
|
-
_v$16 !== _p$.t && (_p$.t = setProp(_el$37, "attributes", _v$16, _p$.t));
|
|
17687
|
-
return _p$;
|
|
17688
|
-
}, {
|
|
17689
|
-
e: undefined,
|
|
17690
|
-
t: undefined
|
|
17691
|
-
});
|
|
17692
|
-
return _el$37;
|
|
17693
|
-
}
|
|
17694
|
-
}), null);
|
|
17767
|
+
setProp(_el$35, "wrapMode", "none");
|
|
17768
|
+
insert(_el$35, () => ` ${truncatePathTail(abbrevHome(task.repo), subtitleBudget())}`);
|
|
17695
17769
|
effect((_p$) => {
|
|
17696
|
-
var _v$
|
|
17697
|
-
_v$
|
|
17698
|
-
_v$
|
|
17699
|
-
_v$
|
|
17700
|
-
_v$
|
|
17701
|
-
_v$
|
|
17770
|
+
var _v$15 = barColor(), _v$16 = stateColor(), _v$17 = TextAttributes9.BOLD, _v$18 = theme.text, _v$19 = TextAttributes9.BOLD, _v$20 = theme.textMuted, _v$21 = TextAttributes9.DIM;
|
|
17771
|
+
_v$15 !== _p$.e && (_p$.e = setProp(_el$31, "fg", _v$15, _p$.e));
|
|
17772
|
+
_v$16 !== _p$.t && (_p$.t = setProp(_el$33, "fg", _v$16, _p$.t));
|
|
17773
|
+
_v$17 !== _p$.a && (_p$.a = setProp(_el$33, "attributes", _v$17, _p$.a));
|
|
17774
|
+
_v$18 !== _p$.o && (_p$.o = setProp(_el$34, "fg", _v$18, _p$.o));
|
|
17775
|
+
_v$19 !== _p$.i && (_p$.i = setProp(_el$34, "attributes", _v$19, _p$.i));
|
|
17776
|
+
_v$20 !== _p$.n && (_p$.n = setProp(_el$35, "fg", _v$20, _p$.n));
|
|
17777
|
+
_v$21 !== _p$.s && (_p$.s = setProp(_el$35, "attributes", _v$21, _p$.s));
|
|
17702
17778
|
return _p$;
|
|
17703
17779
|
}, {
|
|
17704
17780
|
e: undefined,
|
|
17705
17781
|
t: undefined,
|
|
17706
17782
|
a: undefined,
|
|
17707
17783
|
o: undefined,
|
|
17708
|
-
i: undefined
|
|
17784
|
+
i: undefined,
|
|
17785
|
+
n: undefined,
|
|
17786
|
+
s: undefined
|
|
17709
17787
|
});
|
|
17710
17788
|
return _el$30;
|
|
17711
17789
|
}
|
|
@@ -17714,58 +17792,43 @@ function Sidebar(props) {
|
|
|
17714
17792
|
when: !isMain,
|
|
17715
17793
|
get children() {
|
|
17716
17794
|
return [(() => {
|
|
17717
|
-
var _el$
|
|
17795
|
+
var _el$36 = createElement("box"), _el$37 = createElement("text"), _el$38 = createElement("box"), _el$39 = createElement("text"), _el$40 = createElement("text");
|
|
17796
|
+
insertNode(_el$36, _el$37);
|
|
17797
|
+
insertNode(_el$36, _el$38);
|
|
17798
|
+
setProp(_el$36, "flexDirection", "row");
|
|
17799
|
+
setProp(_el$36, "gap", 0);
|
|
17800
|
+
setProp(_el$37, "wrapMode", "none");
|
|
17801
|
+
insert(_el$37, barGlyph);
|
|
17718
17802
|
insertNode(_el$38, _el$39);
|
|
17719
17803
|
insertNode(_el$38, _el$40);
|
|
17720
17804
|
setProp(_el$38, "flexDirection", "row");
|
|
17805
|
+
setProp(_el$38, "flexGrow", 1);
|
|
17806
|
+
setProp(_el$38, "paddingRight", 1);
|
|
17721
17807
|
setProp(_el$38, "gap", 0);
|
|
17722
17808
|
setProp(_el$39, "wrapMode", "none");
|
|
17723
|
-
insert(_el$39,
|
|
17724
|
-
|
|
17725
|
-
insertNode(_el$40, _el$42);
|
|
17726
|
-
setProp(_el$40, "flexDirection", "row");
|
|
17809
|
+
insert(_el$39, stateGlyph);
|
|
17810
|
+
setProp(_el$40, "wrapMode", "none");
|
|
17727
17811
|
setProp(_el$40, "flexGrow", 1);
|
|
17728
|
-
|
|
17729
|
-
|
|
17730
|
-
setProp(_el$41, "wrapMode", "none");
|
|
17731
|
-
insert(_el$41, (() => {
|
|
17732
|
-
var _c$3 = memo2(() => !!loading());
|
|
17733
|
-
return () => _c$3() ? IN_PROGRESS_SPINNER[spinnerFrame()] ?? IN_PROGRESS_SPINNER[0] : badge.glyph;
|
|
17734
|
-
})());
|
|
17735
|
-
setProp(_el$42, "wrapMode", "none");
|
|
17736
|
-
setProp(_el$42, "flexGrow", 1);
|
|
17737
|
-
insert(_el$42, () => spacedTitle(titleText, titleBudget()));
|
|
17738
|
-
insert(_el$40, createComponent2(Show, {
|
|
17812
|
+
insert(_el$40, () => spacedTitle(titleText, titleBudget()));
|
|
17813
|
+
insert(_el$38, createComponent2(Show, {
|
|
17739
17814
|
get when() {
|
|
17740
|
-
return
|
|
17815
|
+
return memo2(() => !!props.moveMode?.())() && isCursor();
|
|
17741
17816
|
},
|
|
17742
17817
|
get children() {
|
|
17743
|
-
var _el$
|
|
17744
|
-
insertNode(_el$
|
|
17745
|
-
setProp(_el$
|
|
17746
|
-
effect((_$p) => setProp(_el$
|
|
17747
|
-
return _el$
|
|
17818
|
+
var _el$41 = createElement("text");
|
|
17819
|
+
insertNode(_el$41, createTextNode(` move`));
|
|
17820
|
+
setProp(_el$41, "wrapMode", "none");
|
|
17821
|
+
effect((_$p) => setProp(_el$41, "fg", theme.warning, _$p));
|
|
17822
|
+
return _el$41;
|
|
17748
17823
|
}
|
|
17749
17824
|
}), null);
|
|
17750
|
-
insert(_el$40, createComponent2(Show, {
|
|
17751
|
-
get when() {
|
|
17752
|
-
return memo2(() => !!!loading())() && activityChip();
|
|
17753
|
-
},
|
|
17754
|
-
children: (chip) => (() => {
|
|
17755
|
-
var _el$55 = createElement("text");
|
|
17756
|
-
setProp(_el$55, "wrapMode", "none");
|
|
17757
|
-
insert(_el$55, () => ` ${chip().text}`);
|
|
17758
|
-
effect((_$p) => setProp(_el$55, "fg", chip().tone === "error" ? theme.error : chip().tone === "warning" ? theme.warning : theme.primary, _$p));
|
|
17759
|
-
return _el$55;
|
|
17760
|
-
})()
|
|
17761
|
-
}), null);
|
|
17762
17825
|
effect((_p$) => {
|
|
17763
|
-
var _v$22 = barColor(), _v$23 =
|
|
17764
|
-
_v$22 !== _p$.e && (_p$.e = setProp(_el$
|
|
17765
|
-
_v$23 !== _p$.t && (_p$.t = setProp(_el$
|
|
17766
|
-
_v$24 !== _p$.a && (_p$.a = setProp(_el$
|
|
17767
|
-
_v$25 !== _p$.o && (_p$.o = setProp(_el$
|
|
17768
|
-
_v$26 !== _p$.i && (_p$.i = setProp(_el$
|
|
17826
|
+
var _v$22 = barColor(), _v$23 = stateColor(), _v$24 = TextAttributes9.BOLD, _v$25 = theme.text, _v$26 = isSelected() || isCursor() ? TextAttributes9.BOLD : undefined;
|
|
17827
|
+
_v$22 !== _p$.e && (_p$.e = setProp(_el$37, "fg", _v$22, _p$.e));
|
|
17828
|
+
_v$23 !== _p$.t && (_p$.t = setProp(_el$39, "fg", _v$23, _p$.t));
|
|
17829
|
+
_v$24 !== _p$.a && (_p$.a = setProp(_el$39, "attributes", _v$24, _p$.a));
|
|
17830
|
+
_v$25 !== _p$.o && (_p$.o = setProp(_el$40, "fg", _v$25, _p$.o));
|
|
17831
|
+
_v$26 !== _p$.i && (_p$.i = setProp(_el$40, "attributes", _v$26, _p$.i));
|
|
17769
17832
|
return _p$;
|
|
17770
17833
|
}, {
|
|
17771
17834
|
e: undefined,
|
|
@@ -17774,74 +17837,74 @@ function Sidebar(props) {
|
|
|
17774
17837
|
o: undefined,
|
|
17775
17838
|
i: undefined
|
|
17776
17839
|
});
|
|
17777
|
-
return _el$
|
|
17840
|
+
return _el$36;
|
|
17778
17841
|
})(), (() => {
|
|
17779
|
-
var _el$
|
|
17842
|
+
var _el$43 = createElement("box"), _el$44 = createElement("text"), _el$45 = createElement("box"), _el$46 = createElement("text");
|
|
17843
|
+
insertNode(_el$43, _el$44);
|
|
17844
|
+
insertNode(_el$43, _el$45);
|
|
17845
|
+
setProp(_el$43, "flexDirection", "row");
|
|
17846
|
+
setProp(_el$43, "gap", 0);
|
|
17847
|
+
setProp(_el$44, "wrapMode", "none");
|
|
17848
|
+
insert(_el$44, barGlyph);
|
|
17780
17849
|
insertNode(_el$45, _el$46);
|
|
17781
|
-
insertNode(_el$45, _el$47);
|
|
17782
17850
|
setProp(_el$45, "flexDirection", "row");
|
|
17783
|
-
setProp(_el$45, "
|
|
17851
|
+
setProp(_el$45, "flexGrow", 1);
|
|
17852
|
+
setProp(_el$45, "paddingLeft", 2);
|
|
17853
|
+
setProp(_el$45, "paddingRight", 1);
|
|
17854
|
+
setProp(_el$45, "gap", 1);
|
|
17784
17855
|
setProp(_el$46, "wrapMode", "none");
|
|
17785
|
-
|
|
17786
|
-
|
|
17787
|
-
|
|
17788
|
-
setProp(_el$47, "flexGrow", 1);
|
|
17789
|
-
setProp(_el$47, "paddingLeft", 2);
|
|
17790
|
-
setProp(_el$47, "paddingRight", 1);
|
|
17791
|
-
setProp(_el$47, "gap", 1);
|
|
17792
|
-
setProp(_el$48, "wrapMode", "none");
|
|
17793
|
-
setProp(_el$48, "flexGrow", 1);
|
|
17794
|
-
insert(_el$48, subtitleText);
|
|
17795
|
-
insert(_el$47, createComponent2(Show, {
|
|
17856
|
+
setProp(_el$46, "flexGrow", 1);
|
|
17857
|
+
insert(_el$46, subtitleText);
|
|
17858
|
+
insert(_el$45, createComponent2(Show, {
|
|
17796
17859
|
get when() {
|
|
17797
17860
|
return task.pinned === true;
|
|
17798
17861
|
},
|
|
17799
17862
|
get children() {
|
|
17800
|
-
var _el$
|
|
17801
|
-
insertNode(_el$
|
|
17802
|
-
setProp(_el$
|
|
17803
|
-
effect((_$p) => setProp(_el$
|
|
17804
|
-
return _el$
|
|
17863
|
+
var _el$47 = createElement("text");
|
|
17864
|
+
insertNode(_el$47, createTextNode(`\u25B4`));
|
|
17865
|
+
setProp(_el$47, "wrapMode", "none");
|
|
17866
|
+
effect((_$p) => setProp(_el$47, "fg", theme.warning, _$p));
|
|
17867
|
+
return _el$47;
|
|
17805
17868
|
}
|
|
17806
17869
|
}), null);
|
|
17807
|
-
insert(_el$
|
|
17870
|
+
insert(_el$45, createComponent2(Show, {
|
|
17808
17871
|
get when() {
|
|
17809
17872
|
return changes().added > 0;
|
|
17810
17873
|
},
|
|
17811
17874
|
get children() {
|
|
17812
|
-
var _el$
|
|
17813
|
-
insertNode(_el$
|
|
17814
|
-
setProp(_el$
|
|
17815
|
-
insert(_el$
|
|
17816
|
-
effect((_$p) => setProp(_el$
|
|
17817
|
-
return _el$
|
|
17875
|
+
var _el$49 = createElement("text"), _el$50 = createTextNode(`+`);
|
|
17876
|
+
insertNode(_el$49, _el$50);
|
|
17877
|
+
setProp(_el$49, "wrapMode", "none");
|
|
17878
|
+
insert(_el$49, () => changes().added, null);
|
|
17879
|
+
effect((_$p) => setProp(_el$49, "fg", theme.success, _$p));
|
|
17880
|
+
return _el$49;
|
|
17818
17881
|
}
|
|
17819
17882
|
}), null);
|
|
17820
|
-
insert(_el$
|
|
17883
|
+
insert(_el$45, createComponent2(Show, {
|
|
17821
17884
|
get when() {
|
|
17822
17885
|
return changes().deleted > 0;
|
|
17823
17886
|
},
|
|
17824
17887
|
get children() {
|
|
17825
|
-
var _el$
|
|
17826
|
-
insertNode(_el$
|
|
17827
|
-
setProp(_el$
|
|
17828
|
-
insert(_el$
|
|
17829
|
-
effect((_$p) => setProp(_el$
|
|
17830
|
-
return _el$
|
|
17888
|
+
var _el$51 = createElement("text"), _el$52 = createTextNode(`\u2212`);
|
|
17889
|
+
insertNode(_el$51, _el$52);
|
|
17890
|
+
setProp(_el$51, "wrapMode", "none");
|
|
17891
|
+
insert(_el$51, () => changes().deleted, null);
|
|
17892
|
+
effect((_$p) => setProp(_el$51, "fg", theme.error, _$p));
|
|
17893
|
+
return _el$51;
|
|
17831
17894
|
}
|
|
17832
17895
|
}), null);
|
|
17833
17896
|
effect((_p$) => {
|
|
17834
17897
|
var _v$27 = barColor(), _v$28 = theme.textMuted, _v$29 = TextAttributes9.DIM;
|
|
17835
|
-
_v$27 !== _p$.e && (_p$.e = setProp(_el$
|
|
17836
|
-
_v$28 !== _p$.t && (_p$.t = setProp(_el$
|
|
17837
|
-
_v$29 !== _p$.a && (_p$.a = setProp(_el$
|
|
17898
|
+
_v$27 !== _p$.e && (_p$.e = setProp(_el$44, "fg", _v$27, _p$.e));
|
|
17899
|
+
_v$28 !== _p$.t && (_p$.t = setProp(_el$46, "fg", _v$28, _p$.t));
|
|
17900
|
+
_v$29 !== _p$.a && (_p$.a = setProp(_el$46, "attributes", _v$29, _p$.a));
|
|
17838
17901
|
return _p$;
|
|
17839
17902
|
}, {
|
|
17840
17903
|
e: undefined,
|
|
17841
17904
|
t: undefined,
|
|
17842
17905
|
a: undefined
|
|
17843
17906
|
});
|
|
17844
|
-
return _el$
|
|
17907
|
+
return _el$43;
|
|
17845
17908
|
})()];
|
|
17846
17909
|
}
|
|
17847
17910
|
}), null);
|
|
@@ -17904,43 +17967,43 @@ function Sidebar(props) {
|
|
|
17904
17967
|
const left = createMemo(() => Math.max(0, Math.min(h().x + 2, dims().width - boxW() - 1)));
|
|
17905
17968
|
const top = createMemo(() => Math.max(0, Math.min(h().y + 1, dims().height - boxH() - 1)));
|
|
17906
17969
|
return (() => {
|
|
17907
|
-
var _el$
|
|
17908
|
-
setProp(_el$
|
|
17909
|
-
setProp(_el$
|
|
17910
|
-
setProp(_el$
|
|
17911
|
-
setProp(_el$
|
|
17912
|
-
setProp(_el$
|
|
17913
|
-
setProp(_el$
|
|
17914
|
-
insert(_el$
|
|
17970
|
+
var _el$53 = createElement("box");
|
|
17971
|
+
setProp(_el$53, "position", "absolute");
|
|
17972
|
+
setProp(_el$53, "zIndex", 2600);
|
|
17973
|
+
setProp(_el$53, "flexDirection", "column");
|
|
17974
|
+
setProp(_el$53, "border", true);
|
|
17975
|
+
setProp(_el$53, "paddingLeft", 1);
|
|
17976
|
+
setProp(_el$53, "paddingRight", 1);
|
|
17977
|
+
insert(_el$53, createComponent2(For, {
|
|
17915
17978
|
get each() {
|
|
17916
17979
|
return lines();
|
|
17917
17980
|
},
|
|
17918
17981
|
children: (l) => (() => {
|
|
17919
|
-
var _el$
|
|
17920
|
-
setProp(_el$
|
|
17921
|
-
insert(_el$
|
|
17922
|
-
var _c$
|
|
17923
|
-
return () => _c$
|
|
17982
|
+
var _el$54 = createElement("text");
|
|
17983
|
+
setProp(_el$54, "wrapMode", "none");
|
|
17984
|
+
insert(_el$54, (() => {
|
|
17985
|
+
var _c$2 = memo2(() => !!l.dim);
|
|
17986
|
+
return () => _c$2() ? truncatePathTail(l.text, innerW()) : truncateTitle(l.text, innerW());
|
|
17924
17987
|
})());
|
|
17925
17988
|
effect((_p$) => {
|
|
17926
17989
|
var _v$35 = l.dim ? theme.textMuted : theme.text, _v$36 = l.bold ? TextAttributes9.BOLD : l.dim ? TextAttributes9.DIM : undefined;
|
|
17927
|
-
_v$35 !== _p$.e && (_p$.e = setProp(_el$
|
|
17928
|
-
_v$36 !== _p$.t && (_p$.t = setProp(_el$
|
|
17990
|
+
_v$35 !== _p$.e && (_p$.e = setProp(_el$54, "fg", _v$35, _p$.e));
|
|
17991
|
+
_v$36 !== _p$.t && (_p$.t = setProp(_el$54, "attributes", _v$36, _p$.t));
|
|
17929
17992
|
return _p$;
|
|
17930
17993
|
}, {
|
|
17931
17994
|
e: undefined,
|
|
17932
17995
|
t: undefined
|
|
17933
17996
|
});
|
|
17934
|
-
return _el$
|
|
17997
|
+
return _el$54;
|
|
17935
17998
|
})()
|
|
17936
17999
|
}));
|
|
17937
18000
|
effect((_p$) => {
|
|
17938
18001
|
var _v$30 = left(), _v$31 = top(), _v$32 = boxW(), _v$33 = theme.focusAccent, _v$34 = theme.backgroundElement;
|
|
17939
|
-
_v$30 !== _p$.e && (_p$.e = setProp(_el$
|
|
17940
|
-
_v$31 !== _p$.t && (_p$.t = setProp(_el$
|
|
17941
|
-
_v$32 !== _p$.a && (_p$.a = setProp(_el$
|
|
17942
|
-
_v$33 !== _p$.o && (_p$.o = setProp(_el$
|
|
17943
|
-
_v$34 !== _p$.i && (_p$.i = setProp(_el$
|
|
18002
|
+
_v$30 !== _p$.e && (_p$.e = setProp(_el$53, "left", _v$30, _p$.e));
|
|
18003
|
+
_v$31 !== _p$.t && (_p$.t = setProp(_el$53, "top", _v$31, _p$.t));
|
|
18004
|
+
_v$32 !== _p$.a && (_p$.a = setProp(_el$53, "width", _v$32, _p$.a));
|
|
18005
|
+
_v$33 !== _p$.o && (_p$.o = setProp(_el$53, "borderColor", _v$33, _p$.o));
|
|
18006
|
+
_v$34 !== _p$.i && (_p$.i = setProp(_el$53, "backgroundColor", _v$34, _p$.i));
|
|
17944
18007
|
return _p$;
|
|
17945
18008
|
}, {
|
|
17946
18009
|
e: undefined,
|
|
@@ -17949,7 +18012,7 @@ function Sidebar(props) {
|
|
|
17949
18012
|
o: undefined,
|
|
17950
18013
|
i: undefined
|
|
17951
18014
|
});
|
|
17952
|
-
return _el$
|
|
18015
|
+
return _el$53;
|
|
17953
18016
|
})();
|
|
17954
18017
|
}
|
|
17955
18018
|
}), null);
|
|
@@ -18045,6 +18108,7 @@ function TasksShell(props) {
|
|
|
18045
18108
|
const dialog = useDialog();
|
|
18046
18109
|
const kv = useKV();
|
|
18047
18110
|
const [selectedId, setSelectedId] = createSignal(props.tasks().some((t) => t.id === props.initialTaskId) ? props.initialTaskId : props.tasks()[0]?.id ?? null);
|
|
18111
|
+
const [moveMode, setMoveMode] = createSignal(false);
|
|
18048
18112
|
const [updateInfo, setUpdateInfo] = createSignal(null);
|
|
18049
18113
|
const dimensions = useTerminalDimensions();
|
|
18050
18114
|
let activeConfirmed = !props.initialTaskId;
|
|
@@ -18294,6 +18358,19 @@ function TasksShell(props) {
|
|
|
18294
18358
|
console.error(`[kobe tasks] failed to open worktree with ${opener.label}`);
|
|
18295
18359
|
}
|
|
18296
18360
|
}
|
|
18361
|
+
async function moveTask(id, delta) {
|
|
18362
|
+
const task = props.tasks().find((t) => t.id === id);
|
|
18363
|
+
if (!task || task.kind === "main" || !props.orch)
|
|
18364
|
+
return;
|
|
18365
|
+
try {
|
|
18366
|
+
await props.orch.moveTask(id, delta);
|
|
18367
|
+
} catch (err) {
|
|
18368
|
+
console.error("[kobe tasks] task.move failed:", err);
|
|
18369
|
+
return;
|
|
18370
|
+
}
|
|
18371
|
+
setSelectedId(id);
|
|
18372
|
+
await props.reload();
|
|
18373
|
+
}
|
|
18297
18374
|
useBindings(() => ({
|
|
18298
18375
|
enabled: dialog.stack.length === 0,
|
|
18299
18376
|
bindings: [{
|
|
@@ -18425,18 +18502,30 @@ function TasksShell(props) {
|
|
|
18425
18502
|
onRenameRequest: (id) => void renameTask(id),
|
|
18426
18503
|
onDeleteRequest: (id) => void deleteTask(id),
|
|
18427
18504
|
onArchiveRequest: (id) => void archiveTask(id),
|
|
18505
|
+
onLocalMergeRequest: (id) => {
|
|
18506
|
+
const task = props.tasks().find((t) => t.id === id);
|
|
18507
|
+
if (!task || task.kind === "main")
|
|
18508
|
+
return;
|
|
18509
|
+
setSelectedId(id);
|
|
18510
|
+
setMoveMode((cur) => !cur);
|
|
18511
|
+
},
|
|
18512
|
+
moveMode,
|
|
18513
|
+
onMoveRequest: (id, delta) => void moveTask(id, delta),
|
|
18514
|
+
onMoveModeExit: () => setMoveMode(false),
|
|
18428
18515
|
focused: () => dialog.stack.length === 0
|
|
18429
18516
|
}));
|
|
18430
|
-
insert(_el$, createComponent2(ShortcutHints, {
|
|
18517
|
+
insert(_el$, createComponent2(ShortcutHints, {
|
|
18518
|
+
moveMode
|
|
18519
|
+
}), null);
|
|
18431
18520
|
effect((_$p) => setProp(_el$, "backgroundColor", theme.background, _$p));
|
|
18432
18521
|
return _el$;
|
|
18433
18522
|
})();
|
|
18434
18523
|
}
|
|
18435
|
-
function ShortcutHints() {
|
|
18524
|
+
function ShortcutHints(props) {
|
|
18436
18525
|
const {
|
|
18437
18526
|
theme
|
|
18438
18527
|
} = useTheme();
|
|
18439
|
-
const
|
|
18528
|
+
const DEFAULT_HINTS = [{
|
|
18440
18529
|
k: "\u23CE",
|
|
18441
18530
|
label: "open"
|
|
18442
18531
|
}, {
|
|
@@ -18451,6 +18540,9 @@ function ShortcutHints() {
|
|
|
18451
18540
|
}, {
|
|
18452
18541
|
k: "[/]",
|
|
18453
18542
|
label: "views"
|
|
18543
|
+
}, {
|
|
18544
|
+
k: "M",
|
|
18545
|
+
label: "move task"
|
|
18454
18546
|
}, {
|
|
18455
18547
|
k: "A/D",
|
|
18456
18548
|
label: "archive/delete"
|
|
@@ -18485,9 +18577,17 @@ function ShortcutHints() {
|
|
|
18485
18577
|
k: "\u2303Q",
|
|
18486
18578
|
label: "detach"
|
|
18487
18579
|
}];
|
|
18580
|
+
const MOVE_HINTS = [{
|
|
18581
|
+
k: "J/K",
|
|
18582
|
+
label: "reorder"
|
|
18583
|
+
}, {
|
|
18584
|
+
k: "\u23CE/Esc",
|
|
18585
|
+
label: "done"
|
|
18586
|
+
}];
|
|
18587
|
+
const hints = () => props.moveMode?.() ? MOVE_HINTS : DEFAULT_HINTS;
|
|
18488
18588
|
const LABEL_COL_MAX = 18;
|
|
18489
|
-
const labelColWidth = Math.min(LABEL_COL_MAX, Math.max(...
|
|
18490
|
-
const clipLabel = (s) => s.length <= labelColWidth ? s : `${s.slice(0, Math.max(0, labelColWidth - 1))}\u2026`;
|
|
18589
|
+
const labelColWidth = () => Math.min(LABEL_COL_MAX, Math.max(...hints().map((h) => h.label.length)));
|
|
18590
|
+
const clipLabel = (s) => s.length <= labelColWidth() ? s : `${s.slice(0, Math.max(0, labelColWidth() - 1))}\u2026`;
|
|
18491
18591
|
return (() => {
|
|
18492
18592
|
var _el$3 = createElement("box"), _el$4 = createElement("text");
|
|
18493
18593
|
insertNode(_el$3, _el$4);
|
|
@@ -18500,7 +18600,9 @@ function ShortcutHints() {
|
|
|
18500
18600
|
insertNode(_el$4, createTextNode(`\u2500\u2500 keys \u2500\u2500`));
|
|
18501
18601
|
setProp(_el$4, "wrapMode", "none");
|
|
18502
18602
|
insert(_el$3, createComponent2(For, {
|
|
18503
|
-
each
|
|
18603
|
+
get each() {
|
|
18604
|
+
return hints();
|
|
18605
|
+
},
|
|
18504
18606
|
children: (h) => (() => {
|
|
18505
18607
|
var _el$6 = createElement("box"), _el$7 = createElement("box"), _el$8 = createElement("text"), _el$9 = createTextNode(`[`), _el$0 = createTextNode(`]`), _el$1 = createElement("box"), _el$10 = createElement("text");
|
|
18506
18608
|
insertNode(_el$6, _el$7);
|
|
@@ -18516,20 +18618,21 @@ function ShortcutHints() {
|
|
|
18516
18618
|
setProp(_el$8, "wrapMode", "none");
|
|
18517
18619
|
insert(_el$8, () => h.k, _el$0);
|
|
18518
18620
|
insertNode(_el$1, _el$10);
|
|
18519
|
-
setProp(_el$1, "width", labelColWidth);
|
|
18520
18621
|
setProp(_el$1, "flexShrink", 0);
|
|
18521
18622
|
setProp(_el$10, "wrapMode", "none");
|
|
18522
18623
|
insert(_el$10, () => clipLabel(h.label));
|
|
18523
18624
|
effect((_p$) => {
|
|
18524
|
-
var _v$3 = theme.accent, _v$4 = TextAttributes10.BOLD, _v$5 = theme.textMuted;
|
|
18625
|
+
var _v$3 = theme.accent, _v$4 = TextAttributes10.BOLD, _v$5 = labelColWidth(), _v$6 = theme.textMuted;
|
|
18525
18626
|
_v$3 !== _p$.e && (_p$.e = setProp(_el$8, "fg", _v$3, _p$.e));
|
|
18526
18627
|
_v$4 !== _p$.t && (_p$.t = setProp(_el$8, "attributes", _v$4, _p$.t));
|
|
18527
|
-
_v$5 !== _p$.a && (_p$.a = setProp(_el$
|
|
18628
|
+
_v$5 !== _p$.a && (_p$.a = setProp(_el$1, "width", _v$5, _p$.a));
|
|
18629
|
+
_v$6 !== _p$.o && (_p$.o = setProp(_el$10, "fg", _v$6, _p$.o));
|
|
18528
18630
|
return _p$;
|
|
18529
18631
|
}, {
|
|
18530
18632
|
e: undefined,
|
|
18531
18633
|
t: undefined,
|
|
18532
|
-
a: undefined
|
|
18634
|
+
a: undefined,
|
|
18635
|
+
o: undefined
|
|
18533
18636
|
});
|
|
18534
18637
|
return _el$6;
|
|
18535
18638
|
})()
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@sma1lboy/kobe",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.12",
|
|
5
5
|
"description": "TUI orchestrator for Claude Code (codename)",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"packageManager": "bun@1.3.13",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"@biomejs/biome": "1.9.4",
|
|
50
50
|
"@tsconfig/bun": "1.0.9",
|
|
51
51
|
"@types/bun": "1.3.12",
|
|
52
|
+
"@types/node": "25.6.2",
|
|
52
53
|
"knip": "^6.14.2",
|
|
53
54
|
"node-pty": "^1.1.0",
|
|
54
55
|
"typescript": "5.8.2",
|