@sma1lboy/kobe 0.5.10 → 0.5.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/README.md +26 -2
- package/dist/bin/kobed.js +21 -9
- package/dist/cli/index.js +2003 -1252
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -68,6 +68,7 @@ Once you're in, the keys you'll use most:
|
|
|
68
68
|
| `ctrl+1` / `2` / `3` / `4` | Jump straight to a pane (sidebar, workspace, files, terminal) |
|
|
69
69
|
| `tab` | Cycle focus to the next pane |
|
|
70
70
|
| `ctrl+q` | Detach back to the sidebar (your task keeps streaming) |
|
|
71
|
+
| `ctrl+o` | Open the active task's worktree in your editor |
|
|
71
72
|
| `?` | Show the full keybinding help dialog |
|
|
72
73
|
| `,` or `ctrl+,` | Open Settings (theme, transparent background, dev reset) |
|
|
73
74
|
| `q` | Quit (with confirm) |
|
|
@@ -87,6 +88,29 @@ Inside the chat composer:
|
|
|
87
88
|
A given task can host **multiple chat tabs** on the same worktree — useful when
|
|
88
89
|
you want a parallel sub-conversation without losing the main thread.
|
|
89
90
|
|
|
91
|
+
## Opening tasks in your editor
|
|
92
|
+
|
|
93
|
+
The top bar shows an `[Open] <editor>` chip when kobe can find an editor for the
|
|
94
|
+
active task. Click it, use `ctrl+o`, or run **Open task in editor** from the
|
|
95
|
+
command palette to open the task's worktree.
|
|
96
|
+
|
|
97
|
+
Detection order is:
|
|
98
|
+
|
|
99
|
+
1. `KOBE_OPEN_EDITOR`
|
|
100
|
+
2. `code` (VS Code)
|
|
101
|
+
3. `cursor`
|
|
102
|
+
4. `windsurf`
|
|
103
|
+
5. `zed`
|
|
104
|
+
6. platform fallback (`open` on macOS, `xdg-open` on Linux)
|
|
105
|
+
|
|
106
|
+
Set `KOBE_OPEN_EDITOR` globally if you want to force a specific tool:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
export KOBE_OPEN_EDITOR=cursor
|
|
110
|
+
export KOBE_OPEN_EDITOR=code
|
|
111
|
+
export KOBE_OPEN_EDITOR=/Applications/Cursor.app/Contents/Resources/app/bin/cursor
|
|
112
|
+
```
|
|
113
|
+
|
|
90
114
|
For the full feature manifest, see [`CHANGELOG.md`](./CHANGELOG.md).
|
|
91
115
|
|
|
92
116
|
## Custom themes
|
|
@@ -152,8 +176,8 @@ If you want to hack on kobe itself rather than just use it:
|
|
|
152
176
|
```bash
|
|
153
177
|
bun install
|
|
154
178
|
bun run dev # boots the 5-pane TUI under KOBE_DEV=1 (no update chip, etc.)
|
|
155
|
-
bun run test #
|
|
156
|
-
bun run test:behavior # PTY
|
|
179
|
+
bun run test # normal suite: fast tests + serial socket tests
|
|
180
|
+
bun run test:behavior # slow PTY suite; only run for user-visible TUI behavior
|
|
157
181
|
bun run typecheck # strict tsc
|
|
158
182
|
bun run build # produces ./dist/index.js for `npm publish`
|
|
159
183
|
```
|
package/dist/bin/kobed.js
CHANGED
|
@@ -1208,18 +1208,29 @@ var init_server = () => {};
|
|
|
1208
1208
|
// src/orchestrator/bridge/index.ts
|
|
1209
1209
|
var exports_bridge = {};
|
|
1210
1210
|
__export(exports_bridge, {
|
|
1211
|
-
startBridge: () => startBridge
|
|
1211
|
+
startBridge: () => startBridge,
|
|
1212
|
+
bridgeSocketPathForHome: () => bridgeSocketPathForHome
|
|
1212
1213
|
});
|
|
1213
|
-
import { writeFile as writeFile2 } from "fs/promises";
|
|
1214
|
-
import { homedir as homedir5 } from "os";
|
|
1214
|
+
import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
|
|
1215
|
+
import { homedir as homedir5, tmpdir as tmpdir2 } from "os";
|
|
1215
1216
|
import { join as join3 } from "path";
|
|
1216
1217
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1218
|
+
function bridgeSocketPathForHome(home, pid = process.pid) {
|
|
1219
|
+
const runDir = join3(home, ".kobe", "run");
|
|
1220
|
+
const preferred = join3(runDir, `bridge-${pid}.sock`);
|
|
1221
|
+
const macTempSocket = process.platform === "darwin" && preferred.startsWith(tmpdir2());
|
|
1222
|
+
if (preferred.length <= UNIX_SOCKET_PATH_LIMIT && !macTempSocket)
|
|
1223
|
+
return preferred;
|
|
1224
|
+
const shortTmp = process.platform === "darwin" ? "/tmp" : tmpdir2();
|
|
1225
|
+
return join3(shortTmp, `kobe-bridge-${pid}.sock`);
|
|
1226
|
+
}
|
|
1217
1227
|
async function startBridge(orch, opts = {}) {
|
|
1218
1228
|
const home = opts.homeDir ?? process.env.KOBE_HOME_DIR ?? homedir5();
|
|
1219
1229
|
const runDir = join3(home, ".kobe", "run");
|
|
1220
|
-
const socketPath =
|
|
1230
|
+
const socketPath = bridgeSocketPathForHome(home);
|
|
1221
1231
|
const mcpConfigPath = join3(runDir, `mcp-${process.pid}.json`);
|
|
1222
1232
|
const server = await startBridgeServer(orch, socketPath);
|
|
1233
|
+
await mkdir3(runDir, { recursive: true });
|
|
1223
1234
|
const moduleExt = import.meta.url.endsWith(".ts") ? ".ts" : ".js";
|
|
1224
1235
|
const entry = fileURLToPath2(new URL(`../../cli/index${moduleExt}`, import.meta.url));
|
|
1225
1236
|
const mcpConfig = {
|
|
@@ -1240,6 +1251,7 @@ async function startBridge(orch, opts = {}) {
|
|
|
1240
1251
|
}
|
|
1241
1252
|
};
|
|
1242
1253
|
}
|
|
1254
|
+
var UNIX_SOCKET_PATH_LIMIT = 103;
|
|
1243
1255
|
var init_bridge = __esm(() => {
|
|
1244
1256
|
init_server();
|
|
1245
1257
|
});
|
|
@@ -3994,7 +4006,7 @@ var init_core = __esm(() => {
|
|
|
3994
4006
|
});
|
|
3995
4007
|
|
|
3996
4008
|
// src/orchestrator/index/store.ts
|
|
3997
|
-
import { mkdir as
|
|
4009
|
+
import { mkdir as mkdir4, open, readFile as readFile3, rename, unlink as unlink3 } from "fs/promises";
|
|
3998
4010
|
import { homedir as homedir8 } from "os";
|
|
3999
4011
|
import { dirname as dirname4, join as join6 } from "path";
|
|
4000
4012
|
|
|
@@ -4068,7 +4080,7 @@ class TaskIndexStore {
|
|
|
4068
4080
|
return next;
|
|
4069
4081
|
}
|
|
4070
4082
|
async doSave() {
|
|
4071
|
-
await
|
|
4083
|
+
await mkdir4(dirname4(this.path), { recursive: true });
|
|
4072
4084
|
const payload = this.snapshot();
|
|
4073
4085
|
const json = `${JSON.stringify(payload, null, 2)}
|
|
4074
4086
|
`;
|
|
@@ -4619,7 +4631,7 @@ init_paths();
|
|
|
4619
4631
|
// src/daemon/server.ts
|
|
4620
4632
|
init_repos();
|
|
4621
4633
|
init_paths();
|
|
4622
|
-
import { mkdir as
|
|
4634
|
+
import { mkdir as mkdir5, readFile as readFile5, unlink as unlink4, writeFile as writeFile4 } from "fs/promises";
|
|
4623
4635
|
import { createServer as createServer2 } from "net";
|
|
4624
4636
|
import { dirname as dirname5 } from "path";
|
|
4625
4637
|
|
|
@@ -4959,8 +4971,8 @@ async function startDaemonServer(orch, options = {}) {
|
|
|
4959
4971
|
const startedAt = options.startedAt ?? new Date;
|
|
4960
4972
|
const clients = new Set;
|
|
4961
4973
|
let nextClientId = 1;
|
|
4962
|
-
await
|
|
4963
|
-
await
|
|
4974
|
+
await mkdir5(dirname5(socketPath), { recursive: true });
|
|
4975
|
+
await mkdir5(dirname5(pidPath), { recursive: true });
|
|
4964
4976
|
await unlink4(socketPath).catch(() => {});
|
|
4965
4977
|
const server = createServer2((socket) => {
|
|
4966
4978
|
const client = {
|