@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 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 # unit + type tests
156
- bun run test:behavior # PTY-driven; spawns kobe as a real binary
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 = join3(runDir, `bridge-${process.pid}.sock`);
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 mkdir3, open, readFile as readFile3, rename, unlink as unlink3 } from "fs/promises";
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 mkdir3(dirname4(this.path), { recursive: true });
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 mkdir4, readFile as readFile5, unlink as unlink4, writeFile as writeFile4 } from "fs/promises";
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 mkdir4(dirname5(socketPath), { recursive: true });
4963
- await mkdir4(dirname5(pidPath), { recursive: true });
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 = {