@sma1lboy/kobe 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +79 -26
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8280,7 +8280,7 @@ var init_package = __esm(() => {
8280
8280
  package_default = {
8281
8281
  $schema: "https://json.schemastore.org/package.json",
8282
8282
  name: "@sma1lboy/kobe",
8283
- version: "0.2.0",
8283
+ version: "0.2.2",
8284
8284
  description: "TUI orchestrator for Claude Code (codename)",
8285
8285
  type: "module",
8286
8286
  packageManager: "bun@1.3.13",
@@ -9581,6 +9581,40 @@ var init_claude_code_local = __esm(() => {
9581
9581
  init_spawn();
9582
9582
  });
9583
9583
 
9584
+ // src/tui/panes/chat/composer/claude-settings.ts
9585
+ import { homedir as homedir6 } from "os";
9586
+ import { readFileSync as readFileSync4 } from "fs";
9587
+ import { join as join7 } from "path";
9588
+ function readClaudeSettings() {
9589
+ if (cached !== undefined)
9590
+ return cached;
9591
+ try {
9592
+ const raw = readFileSync4(SETTINGS_PATH, "utf8");
9593
+ const parsed = JSON.parse(raw);
9594
+ if (!parsed || typeof parsed !== "object") {
9595
+ cached = null;
9596
+ return null;
9597
+ }
9598
+ const obj = parsed;
9599
+ const model = typeof obj.model === "string" && obj.model.length > 0 ? obj.model : undefined;
9600
+ cached = { model };
9601
+ return cached;
9602
+ } catch {
9603
+ cached = null;
9604
+ return null;
9605
+ }
9606
+ }
9607
+ function resolveDefaultModelId() {
9608
+ const settings = readClaudeSettings();
9609
+ if (settings?.model && settings.model.length > 0)
9610
+ return settings.model;
9611
+ return FALLBACK_DEFAULT_MODEL_ID;
9612
+ }
9613
+ var SETTINGS_PATH, cached, FALLBACK_DEFAULT_MODEL_ID = "claude-opus-4-7[1m]";
9614
+ var init_claude_settings = __esm(() => {
9615
+ SETTINGS_PATH = join7(homedir6(), ".claude", "settings.json");
9616
+ });
9617
+
9584
9618
  // src/orchestrator/branch-suggestion.ts
9585
9619
  import { spawn as spawn3 } from "child_process";
9586
9620
  async function suggestBranchSlug(prompt) {
@@ -9968,17 +10002,18 @@ class Orchestrator {
9968
10002
  }
9969
10003
  }
9970
10004
  const promptToSend = prompt && prompt.length > 0 ? prompt : " ";
10005
+ const modelToUse = task.model ?? resolveDefaultModelId();
9971
10006
  let handle;
9972
10007
  if (targetTab.sessionId) {
9973
10008
  handle = await this.engine.resume(targetTab.sessionId, promptToSend, {
9974
10009
  env: { KOBE_RESUME_CWD: task.worktreePath },
9975
10010
  permissionMode: task.permissionMode,
9976
- model: task.model
10011
+ model: modelToUse
9977
10012
  });
9978
10013
  } else {
9979
10014
  handle = await this.engine.spawn(task.worktreePath, promptToSend, {
9980
10015
  permissionMode: task.permissionMode,
9981
- model: task.model
10016
+ model: modelToUse
9982
10017
  });
9983
10018
  await this.updateTab(task.id, targetTab.id, { sessionId: handle.sessionId });
9984
10019
  if (task.title === PLACEHOLDER_TASK_TITLE && prompt && prompt.trim().length > 0) {
@@ -10404,6 +10439,7 @@ function deriveTitleFromPrompt(prompt) {
10404
10439
  var CONCURRENCY_CAP = 4, PLACEHOLDER_TASK_TITLE = "(new task)", IllegalTransitionError, ConcurrencyCapError, PRPreconditionError, TaskNotFoundError, TITLE_CHAR_CAP = 40;
10405
10440
  var init_core = __esm(() => {
10406
10441
  init_dev();
10442
+ init_claude_settings();
10407
10443
  init_branch_suggestion();
10408
10444
  init_ulid();
10409
10445
  init_pr();
@@ -11202,7 +11238,7 @@ var init_dialog_confirm = __esm(() => {
11202
11238
  // src/tui/component/settings-dialog.tsx
11203
11239
  import { TextAttributes as TextAttributes10 } from "@opentui/core";
11204
11240
  import { unlinkSync as unlinkSync2 } from "fs";
11205
- import { join as join7 } from "path";
11241
+ import { join as join8 } from "path";
11206
11242
  function SettingsDialog(props) {
11207
11243
  const dialog = useDialog();
11208
11244
  const themeCtx = useTheme();
@@ -11265,7 +11301,7 @@ function SettingsDialog(props) {
11265
11301
  return;
11266
11302
  props.kv.clear();
11267
11303
  try {
11268
- unlinkSync2(join7(homeDir(), ".kobe", "tasks.json"));
11304
+ unlinkSync2(join8(homeDir(), ".kobe", "tasks.json"));
11269
11305
  } catch (err) {
11270
11306
  if (err.code !== "ENOENT") {
11271
11307
  console.error("kobe: failed to delete tasks.json during reset:", err);
@@ -12148,7 +12184,19 @@ var init_update_dialog = __esm(() => {
12148
12184
 
12149
12185
  // src/tui/context/focus.tsx
12150
12186
  function FocusProvider(props) {
12151
- const [focused, setFocused] = createSignal(props.initial ?? "sidebar");
12187
+ const [focused, setFocusedSignal] = createSignal(props.initial ?? "sidebar");
12188
+ const renderer = useRenderer();
12189
+ function setFocused(pane) {
12190
+ if (focused() === pane)
12191
+ return;
12192
+ const current = renderer?.currentFocusedRenderable;
12193
+ if (current && !current.isDestroyed) {
12194
+ try {
12195
+ current.blur();
12196
+ } catch {}
12197
+ }
12198
+ setFocusedSignal(pane);
12199
+ }
12152
12200
  function cycle(delta) {
12153
12201
  const idx = PANE_ORDER.indexOf(focused());
12154
12202
  const next = (idx + delta + PANE_ORDER.length) % PANE_ORDER.length;
@@ -12185,6 +12233,7 @@ function useFocus() {
12185
12233
  }
12186
12234
  var PANE_ORDER, FocusContext;
12187
12235
  var init_focus = __esm(() => {
12236
+ init_solid();
12188
12237
  init_solid();
12189
12238
  init_dev();
12190
12239
  PANE_ORDER = ["sidebar", "workspace", "files", "terminal"];
@@ -12192,12 +12241,12 @@ var init_focus = __esm(() => {
12192
12241
  });
12193
12242
 
12194
12243
  // src/tui/context/kv.tsx
12195
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "fs";
12196
- import { homedir as homedir6 } from "os";
12197
- import { dirname as dirname4, join as join8 } from "path";
12244
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync5, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "fs";
12245
+ import { homedir as homedir7 } from "os";
12246
+ import { dirname as dirname4, join as join9 } from "path";
12198
12247
  function loadInitial() {
12199
12248
  try {
12200
- const text = readFileSync4(STATE_PATH, "utf8");
12249
+ const text = readFileSync5(STATE_PATH, "utf8");
12201
12250
  const parsed = JSON.parse(text);
12202
12251
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
12203
12252
  return parsed;
@@ -12209,7 +12258,7 @@ var STATE_PATH, WRITE_DEBOUNCE_MS = 250, useKV, KVProvider;
12209
12258
  var init_kv = __esm(() => {
12210
12259
  init_dev2();
12211
12260
  init_helper();
12212
- STATE_PATH = join8(homedir6(), ".config", "kobe", "state.json");
12261
+ STATE_PATH = join9(homedir7(), ".config", "kobe", "state.json");
12213
12262
  ({
12214
12263
  use: useKV,
12215
12264
  provider: KVProvider
@@ -14780,14 +14829,18 @@ var init_MessageList = __esm(() => {
14780
14829
 
14781
14830
  // src/tui/panes/chat/composer/models.ts
14782
14831
  function modelLabelFor(id) {
14783
- const resolved = id ?? DEFAULT_MODEL_ID;
14832
+ const resolved = id ?? resolveDefaultModelId();
14784
14833
  const match = MODEL_CHOICES.find((m) => m.id === resolved);
14785
14834
  return match?.label ?? resolved;
14786
14835
  }
14787
- var DEFAULT_MODEL_ID = "claude-sonnet-4-6", MODEL_CHOICES;
14836
+ var DEFAULT_MODEL_ID = "claude-opus-4-7[1m]", MODEL_CHOICES;
14788
14837
  var init_models = __esm(() => {
14838
+ init_claude_settings();
14839
+ init_claude_settings();
14789
14840
  MODEL_CHOICES = [
14841
+ { id: "claude-opus-4-7[1m]", label: "opus 4.7 (1M)", hint: "long context, default" },
14790
14842
  { id: "claude-opus-4-7", label: "opus 4.7", hint: "most capable, slowest" },
14843
+ { id: "claude-sonnet-4-6[1m]", label: "sonnet 4.6 (1M)", hint: "long context" },
14791
14844
  { id: "claude-sonnet-4-6", label: "sonnet 4.6" },
14792
14845
  { id: "claude-haiku-4-5-20251001", label: "haiku 4.5", hint: "fastest, cheapest" }
14793
14846
  ];
@@ -14934,8 +14987,8 @@ var init_ModelPicker = __esm(() => {
14934
14987
 
14935
14988
  // src/tui/panes/chat/composer/user-slashes.ts
14936
14989
  import { readFile as readFile5, readdir as readdir2, stat as stat2 } from "fs/promises";
14937
- import { homedir as homedir7 } from "os";
14938
- import { join as join9 } from "path";
14990
+ import { homedir as homedir8 } from "os";
14991
+ import { join as join10 } from "path";
14939
14992
  async function safeReaddir(path7) {
14940
14993
  try {
14941
14994
  return await readdir2(path7);
@@ -15038,7 +15091,7 @@ async function scanCommandsDir(dir) {
15038
15091
  for (const entry of entries) {
15039
15092
  if (!entry.endsWith(".md"))
15040
15093
  continue;
15041
- const full = join9(dir, entry);
15094
+ const full = join10(dir, entry);
15042
15095
  if (!await isFile(full))
15043
15096
  continue;
15044
15097
  const name = entry.slice(0, -3);
@@ -15051,10 +15104,10 @@ async function scanSkillsDir(dir) {
15051
15104
  const entries = await safeReaddir(dir);
15052
15105
  const out = [];
15053
15106
  for (const entry of entries) {
15054
- const sub = join9(dir, entry);
15107
+ const sub = join10(dir, entry);
15055
15108
  if (!await isDir(sub))
15056
15109
  continue;
15057
- const skillMd = join9(sub, "SKILL.md");
15110
+ const skillMd = join10(sub, "SKILL.md");
15058
15111
  if (!await isFile(skillMd))
15059
15112
  continue;
15060
15113
  const description = await tryReadDescription(skillMd) ?? "";
@@ -15064,8 +15117,8 @@ async function scanSkillsDir(dir) {
15064
15117
  }
15065
15118
  async function scanBasePath(claudeDir) {
15066
15119
  const [skills, commands] = await Promise.all([
15067
- scanSkillsDir(join9(claudeDir, "skills")),
15068
- scanCommandsDir(join9(claudeDir, "commands"))
15120
+ scanSkillsDir(join10(claudeDir, "skills")),
15121
+ scanCommandsDir(join10(claudeDir, "commands"))
15069
15122
  ]);
15070
15123
  const map = new Map;
15071
15124
  for (const e of skills)
@@ -15075,8 +15128,8 @@ async function scanBasePath(claudeDir) {
15075
15128
  return [...map.values()];
15076
15129
  }
15077
15130
  async function loadUserSlashes(worktreePath) {
15078
- const projectScan = worktreePath ? scanBasePath(join9(worktreePath, ".claude")) : Promise.resolve([]);
15079
- const globalScan = scanBasePath(join9(homedir7(), ".claude"));
15131
+ const projectScan = worktreePath ? scanBasePath(join10(worktreePath, ".claude")) : Promise.resolve([]);
15132
+ const globalScan = scanBasePath(join10(homedir8(), ".claude"));
15080
15133
  const [project, global] = await Promise.all([projectScan, globalScan]);
15081
15134
  const map = new Map;
15082
15135
  for (const e of global)
@@ -15564,7 +15617,7 @@ function Chat(props) {
15564
15617
  if (!id)
15565
15618
  return;
15566
15619
  const current = permissionMode() ?? "default";
15567
- const next = current === "default" ? "acceptEdits" : current === "acceptEdits" ? "plan" : "default";
15620
+ const next = current === "default" ? "acceptEdits" : current === "acceptEdits" ? "plan" : current === "plan" ? "bypassPermissions" : "default";
15568
15621
  props.orchestrator.setPermissionMode(id, next).catch((err) => {
15569
15622
  console.error("[kobe] setPermissionMode failed:", err);
15570
15623
  });
@@ -16719,8 +16772,8 @@ class FakeAIEngine {
16719
16772
 
16720
16773
  // src/tui/app.tsx
16721
16774
  import * as fs5 from "fs";
16722
- import { homedir as homedir8 } from "os";
16723
- import { basename as basename3, join as join10 } from "path";
16775
+ import { homedir as homedir9 } from "os";
16776
+ import { basename as basename3, join as join11 } from "path";
16724
16777
  import { TextAttributes as TextAttributes19 } from "@opentui/core";
16725
16778
  async function buildEngine() {
16726
16779
  if (process.env.KOBE_TEST_ENGINE === "fake") {
@@ -18456,7 +18509,7 @@ async function startApp() {
18456
18509
  addTheme(name, theme);
18457
18510
  }
18458
18511
  const engine3 = await buildEngine();
18459
- const homeDir2 = process.env.KOBE_HOME_DIR ?? homedir8();
18512
+ const homeDir2 = process.env.KOBE_HOME_DIR ?? homedir9();
18460
18513
  const store2 = new TaskIndexStore({
18461
18514
  homeDir: homeDir2
18462
18515
  });
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.2.0",
4
+ "version": "0.2.2",
5
5
  "description": "TUI orchestrator for Claude Code (codename)",
6
6
  "type": "module",
7
7
  "packageManager": "bun@1.3.13",