@sma1lboy/kobe 0.2.0 → 0.2.1
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/index.js +78 -25
- 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.
|
|
8283
|
+
version: "0.2.1",
|
|
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:
|
|
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:
|
|
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
|
|
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(
|
|
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,
|
|
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
|
|
12196
|
-
import { homedir as
|
|
12197
|
-
import { dirname as dirname4, join as
|
|
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 =
|
|
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 =
|
|
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 ??
|
|
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-
|
|
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
|
|
14938
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
15107
|
+
const sub = join10(dir, entry);
|
|
15055
15108
|
if (!await isDir(sub))
|
|
15056
15109
|
continue;
|
|
15057
|
-
const skillMd =
|
|
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(
|
|
15068
|
-
scanCommandsDir(
|
|
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(
|
|
15079
|
-
const globalScan = scanBasePath(
|
|
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)
|
|
@@ -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
|
|
16723
|
-
import { basename as basename3, join as
|
|
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 ??
|
|
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