@sma1lboy/kobe 0.6.10 → 0.7.0
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 +1770 -1149
- package/package.json +1 -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.
|
|
73
|
+
version: "0.7.0",
|
|
74
74
|
description: "TUI orchestrator for Claude Code (codename)",
|
|
75
75
|
type: "module",
|
|
76
76
|
packageManager: "bun@1.3.13",
|
|
@@ -214,6 +214,10 @@ function isNewerSemver(latest, current) {
|
|
|
214
214
|
return false;
|
|
215
215
|
}
|
|
216
216
|
async function checkLatestVersion(opts = {}) {
|
|
217
|
+
const fake = process.env.KOBE_FAKE_UPDATE;
|
|
218
|
+
if (fake) {
|
|
219
|
+
return { current: CURRENT_VERSION, latest: fake, hasUpdate: isNewerSemver(fake, CURRENT_VERSION) };
|
|
220
|
+
}
|
|
217
221
|
if (isDev() && !opts.force)
|
|
218
222
|
return null;
|
|
219
223
|
const latest = await fetchLatestFromRegistry(PACKAGE_NAME);
|
|
@@ -3045,6 +3049,21 @@ class Orchestrator {
|
|
|
3045
3049
|
if (task.title === trimmed)
|
|
3046
3050
|
return;
|
|
3047
3051
|
await this.store.update(task.id, { title: trimmed });
|
|
3052
|
+
await this.followBranchToTitle(task, trimmed);
|
|
3053
|
+
}
|
|
3054
|
+
async followBranchToTitle(taskBefore, newTitle) {
|
|
3055
|
+
if (taskBefore.kind === "main" || !taskBefore.worktreePath)
|
|
3056
|
+
return;
|
|
3057
|
+
if (taskBefore.branch !== autoBranch(PLACEHOLDER_TASK_TITLE, taskBefore.id))
|
|
3058
|
+
return;
|
|
3059
|
+
const nextBranch = autoBranch(newTitle, taskBefore.id);
|
|
3060
|
+
if (nextBranch === taskBefore.branch)
|
|
3061
|
+
return;
|
|
3062
|
+
try {
|
|
3063
|
+
await this.setBranch(taskBefore.id, nextBranch);
|
|
3064
|
+
} catch (err) {
|
|
3065
|
+
console.error(`[kobe] follow-branch-to-title failed for ${taskBefore.id}:`, err);
|
|
3066
|
+
}
|
|
3048
3067
|
}
|
|
3049
3068
|
async setBranch(id, branch) {
|
|
3050
3069
|
const trimmed = branch.trim();
|
|
@@ -4217,6 +4236,13 @@ var init_history3 = __esm(() => {
|
|
|
4217
4236
|
});
|
|
4218
4237
|
|
|
4219
4238
|
// src/monitor/auto-title.ts
|
|
4239
|
+
function readerFor(vendor) {
|
|
4240
|
+
if (vendor === "codex")
|
|
4241
|
+
return readHistory2;
|
|
4242
|
+
if (vendor === "copilot")
|
|
4243
|
+
return readHistory3;
|
|
4244
|
+
return readHistory;
|
|
4245
|
+
}
|
|
4220
4246
|
async function originSessions(worktree, vendor) {
|
|
4221
4247
|
if (vendor === "codex") {
|
|
4222
4248
|
return { ids: await listSessionIdsForWorktree(worktree), read: readHistory2 };
|
|
@@ -4228,22 +4254,33 @@ async function originSessions(worktree, vendor) {
|
|
|
4228
4254
|
const ids = [...files].sort((a, b) => a.mtimeMs - b.mtimeMs).map((f) => f.sessionId);
|
|
4229
4255
|
return { ids, read: readHistory };
|
|
4230
4256
|
}
|
|
4257
|
+
function titleFromMessages(messages) {
|
|
4258
|
+
const firstUser = messages.find((m) => m.role === "user");
|
|
4259
|
+
if (!firstUser)
|
|
4260
|
+
return "";
|
|
4261
|
+
const text = firstUser.blocks.filter((b) => b.type === "text").map((b) => b.text).join(" ");
|
|
4262
|
+
return deriveTitleFromPrompt(text);
|
|
4263
|
+
}
|
|
4231
4264
|
async function deriveTitleFromSession(worktree, vendor = DEFAULT_TASK_VENDOR) {
|
|
4232
4265
|
if (!worktree)
|
|
4233
4266
|
return "";
|
|
4234
4267
|
const { ids, read } = await originSessions(worktree, vendor);
|
|
4235
4268
|
for (const sessionId of ids.slice(0, MAX_SESSIONS_SCANNED)) {
|
|
4236
|
-
const
|
|
4237
|
-
const firstUser = messages.find((m) => m.role === "user");
|
|
4238
|
-
if (!firstUser)
|
|
4239
|
-
continue;
|
|
4240
|
-
const text = firstUser.blocks.filter((b) => b.type === "text").map((b) => b.text).join(" ");
|
|
4241
|
-
const title = deriveTitleFromPrompt(text);
|
|
4269
|
+
const title = titleFromMessages(await read(sessionId));
|
|
4242
4270
|
if (title)
|
|
4243
4271
|
return title;
|
|
4244
4272
|
}
|
|
4245
4273
|
return "";
|
|
4246
4274
|
}
|
|
4275
|
+
async function deriveTitleFromSessionId(vendor, sessionId) {
|
|
4276
|
+
if (!sessionId)
|
|
4277
|
+
return "";
|
|
4278
|
+
try {
|
|
4279
|
+
return titleFromMessages(await readerFor(vendor)(sessionId));
|
|
4280
|
+
} catch {
|
|
4281
|
+
return "";
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4247
4284
|
var MAX_SESSIONS_SCANNED = 8;
|
|
4248
4285
|
var init_auto_title = __esm(() => {
|
|
4249
4286
|
init_history();
|
|
@@ -4251,168 +4288,483 @@ var init_auto_title = __esm(() => {
|
|
|
4251
4288
|
init_history3();
|
|
4252
4289
|
});
|
|
4253
4290
|
|
|
4254
|
-
// src/
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4291
|
+
// src/tmux/client.ts
|
|
4292
|
+
var exports_client = {};
|
|
4293
|
+
__export(exports_client, {
|
|
4294
|
+
windowCount: () => windowCount,
|
|
4295
|
+
tmuxSessionName: () => tmuxSessionName,
|
|
4296
|
+
tmuxCommandSequence: () => tmuxCommandSequence,
|
|
4297
|
+
tmuxAvailable: () => tmuxAvailable,
|
|
4298
|
+
tmuxArgs: () => tmuxArgs,
|
|
4299
|
+
tagPaneRole: () => tagPaneRole,
|
|
4300
|
+
tagClaudePane: () => tagClaudePane,
|
|
4301
|
+
switchClientBeforeKill: () => switchClientBeforeKill,
|
|
4302
|
+
setWindowOption: () => setWindowOption,
|
|
4303
|
+
setSessionOption: () => setSessionOption,
|
|
4304
|
+
sessionExists: () => sessionExists,
|
|
4305
|
+
sendKeys: () => sendKeys,
|
|
4306
|
+
sendKeyName: () => sendKeyName,
|
|
4307
|
+
runTmuxSequenceCapturing: () => runTmuxSequenceCapturing,
|
|
4308
|
+
runTmuxSequence: () => runTmuxSequence,
|
|
4309
|
+
runTmuxCapturing: () => runTmuxCapturing,
|
|
4310
|
+
runTmux: () => runTmux,
|
|
4311
|
+
paneIdByRole: () => paneIdByRole,
|
|
4312
|
+
newWindow: () => newWindow,
|
|
4313
|
+
killSession: () => killSession,
|
|
4314
|
+
getSessionOptions: () => getSessionOptions,
|
|
4315
|
+
getSessionOption: () => getSessionOption,
|
|
4316
|
+
ensureFallbackSession: () => ensureFallbackSession,
|
|
4317
|
+
currentSessionName: () => currentSessionName,
|
|
4318
|
+
claudePaneIdStrict: () => claudePaneIdStrict,
|
|
4319
|
+
claudePaneId: () => claudePaneId,
|
|
4320
|
+
capturePaneById: () => capturePaneById,
|
|
4321
|
+
attachArgv: () => attachArgv,
|
|
4322
|
+
PANE_ROLE_OPTION: () => PANE_ROLE_OPTION,
|
|
4323
|
+
KOBE_TMUX_SOCKET: () => KOBE_TMUX_SOCKET,
|
|
4324
|
+
KOBE_HOME_SESSION: () => KOBE_HOME_SESSION,
|
|
4325
|
+
CLAUDE_ROLE_OPTION: () => CLAUDE_ROLE_OPTION,
|
|
4326
|
+
CHAT_TAB_SESSION_ID_OPTION: () => CHAT_TAB_SESSION_ID_OPTION
|
|
4327
|
+
});
|
|
4328
|
+
function tmuxArgs(...args) {
|
|
4329
|
+
return ["tmux", "-L", KOBE_TMUX_SOCKET, ...args];
|
|
4330
|
+
}
|
|
4331
|
+
function tmuxSessionName(taskId) {
|
|
4332
|
+
return `kobe-${taskId.replace(/[^A-Za-z0-9_-]/g, "")}`;
|
|
4333
|
+
}
|
|
4334
|
+
function attachArgv(name) {
|
|
4335
|
+
return tmuxArgs("attach-session", "-t", `=${name}`);
|
|
4336
|
+
}
|
|
4337
|
+
async function drainText(stream) {
|
|
4338
|
+
if (!stream)
|
|
4339
|
+
return "";
|
|
4259
4340
|
try {
|
|
4260
|
-
|
|
4341
|
+
return await new Response(stream).text();
|
|
4261
4342
|
} catch {
|
|
4262
|
-
|
|
4343
|
+
return "";
|
|
4263
4344
|
}
|
|
4264
|
-
return new Error(text);
|
|
4265
|
-
}
|
|
4266
|
-
function formatCrashEntry(kind, err, now = new Date) {
|
|
4267
|
-
const e = toError(err);
|
|
4268
|
-
return `[${now.toISOString()}] daemon ${kind}: ${e.stack ?? `${e.name}: ${e.message}`}
|
|
4269
|
-
`;
|
|
4270
|
-
}
|
|
4271
|
-
function formatDaemonError(subsystem, err, now = new Date) {
|
|
4272
|
-
const e = toError(err);
|
|
4273
|
-
return `[${now.toISOString()}] daemon error [${subsystem}]: ${e.stack ?? `${e.name}: ${e.message}`}
|
|
4274
|
-
`;
|
|
4275
4345
|
}
|
|
4276
|
-
function
|
|
4277
|
-
|
|
4346
|
+
async function runTmux(args) {
|
|
4347
|
+
const proc = Bun.spawn(tmuxArgs(...args), { stdin: "ignore", stdout: "ignore", stderr: "pipe" });
|
|
4348
|
+
const [errText, code] = await Promise.all([drainText(proc.stderr), proc.exited]);
|
|
4349
|
+
if (code !== 0 && errText.trim().length > 0) {
|
|
4350
|
+
console.error(`[kobe tmux] ${args.join(" ")} (${code}): ${errText.trim()}`);
|
|
4351
|
+
}
|
|
4352
|
+
return code;
|
|
4278
4353
|
}
|
|
4279
|
-
function
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
onRejection = (reason) => log(formatCrashEntry("unhandledRejection", reason));
|
|
4283
|
-
onException = (err) => log(formatCrashEntry("uncaughtException", err));
|
|
4284
|
-
process.on("unhandledRejection", onRejection);
|
|
4285
|
-
process.on("uncaughtException", onException);
|
|
4354
|
+
async function runTmuxQuiet(args) {
|
|
4355
|
+
const proc = Bun.spawn(tmuxArgs(...args), { stdin: "ignore", stdout: "ignore", stderr: "ignore" });
|
|
4356
|
+
return proc.exited;
|
|
4286
4357
|
}
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
let renamed = 0;
|
|
4292
|
-
for (const task of orch.listTasks()) {
|
|
4293
|
-
if (task.title !== PLACEHOLDER_TASK_TITLE || !task.worktreePath)
|
|
4358
|
+
function tmuxCommandSequence(commands) {
|
|
4359
|
+
const out = [];
|
|
4360
|
+
for (const cmd of commands) {
|
|
4361
|
+
if (cmd.length === 0)
|
|
4294
4362
|
continue;
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
continue;
|
|
4299
|
-
const current = orch.getTask(task.id);
|
|
4300
|
-
if (!current || current.title !== PLACEHOLDER_TASK_TITLE)
|
|
4301
|
-
continue;
|
|
4302
|
-
await orch.setTitle(task.id, title);
|
|
4303
|
-
renamed++;
|
|
4304
|
-
} catch (err) {
|
|
4305
|
-
logDaemonError("auto-title-poller", err);
|
|
4306
|
-
}
|
|
4363
|
+
if (out.length > 0)
|
|
4364
|
+
out.push(";");
|
|
4365
|
+
out.push(...cmd);
|
|
4307
4366
|
}
|
|
4308
|
-
return
|
|
4367
|
+
return out;
|
|
4309
4368
|
}
|
|
4310
|
-
function
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
let running = false;
|
|
4314
|
-
const tick = () => {
|
|
4315
|
-
if (running)
|
|
4316
|
-
return;
|
|
4317
|
-
running = true;
|
|
4318
|
-
runAutoTitlePass(orch).catch((err) => logDaemonError("auto-title-poller", err)).finally(() => {
|
|
4319
|
-
running = false;
|
|
4320
|
-
});
|
|
4321
|
-
};
|
|
4322
|
-
const timer = setInterval(tick, intervalMs);
|
|
4323
|
-
timer.unref?.();
|
|
4324
|
-
return () => clearInterval(timer);
|
|
4369
|
+
async function runTmuxSequence(commands) {
|
|
4370
|
+
const args = tmuxCommandSequence(commands);
|
|
4371
|
+
return args.length === 0 ? 0 : runTmux(args);
|
|
4325
4372
|
}
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
});
|
|
4331
|
-
|
|
4332
|
-
// src/daemon/event-bus.ts
|
|
4333
|
-
class DaemonEventBus {
|
|
4334
|
-
last = new Map;
|
|
4335
|
-
sinks = new Set;
|
|
4336
|
-
publish(channel, payload) {
|
|
4337
|
-
this.last.set(channel, payload);
|
|
4338
|
-
const event = { channel, payload };
|
|
4339
|
-
for (const sink of this.sinks)
|
|
4340
|
-
sink(event);
|
|
4341
|
-
}
|
|
4342
|
-
snapshot() {
|
|
4343
|
-
return [...this.last].map(([channel, payload]) => ({ channel, payload }));
|
|
4344
|
-
}
|
|
4345
|
-
onPublish(sink) {
|
|
4346
|
-
this.sinks.add(sink);
|
|
4347
|
-
return () => {
|
|
4348
|
-
this.sinks.delete(sink);
|
|
4349
|
-
};
|
|
4373
|
+
async function runTmuxCapturing(args) {
|
|
4374
|
+
const proc = Bun.spawn(tmuxArgs(...args), { stdin: "ignore", stdout: "pipe", stderr: "pipe" });
|
|
4375
|
+
const [stdout, errText, code] = await Promise.all([drainText(proc.stdout), drainText(proc.stderr), proc.exited]);
|
|
4376
|
+
if (code !== 0 && errText.trim().length > 0) {
|
|
4377
|
+
console.error(`[kobe tmux] ${args.join(" ")} (${code}): ${errText.trim()}`);
|
|
4350
4378
|
}
|
|
4379
|
+
return { code, stdout };
|
|
4351
4380
|
}
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
import { homedir as homedir6, tmpdir } from "os";
|
|
4356
|
-
import { join as join3 } from "path";
|
|
4357
|
-
function shortHomeTag(homeDir2) {
|
|
4358
|
-
return createHash2("sha1").update(homeDir2).digest("hex").slice(0, 8);
|
|
4359
|
-
}
|
|
4360
|
-
function fitSocketPath(naturalPath, homeDir2, role, pidTag) {
|
|
4361
|
-
if (Buffer.byteLength(naturalPath, "utf8") <= SOCKET_PATH_SAFETY_LIMIT)
|
|
4362
|
-
return naturalPath;
|
|
4363
|
-
const tag = shortHomeTag(homeDir2);
|
|
4364
|
-
const suffix = pidTag === undefined ? "" : `-${pidTag}`;
|
|
4365
|
-
const fallback = join3(tmpdir(), `kobe-${tag}-${role}${suffix}.sock`);
|
|
4366
|
-
if (Buffer.byteLength(fallback, "utf8") <= SOCKET_PATH_SAFETY_LIMIT)
|
|
4367
|
-
return fallback;
|
|
4368
|
-
throw new Error(`kobe socket path exceeds ${SOCKET_PATH_SAFETY_LIMIT} bytes even after fallback: ${fallback}`);
|
|
4381
|
+
async function runTmuxSequenceCapturing(commands) {
|
|
4382
|
+
const args = tmuxCommandSequence(commands);
|
|
4383
|
+
return args.length === 0 ? { code: 0, stdout: "" } : runTmuxCapturing(args);
|
|
4369
4384
|
}
|
|
4370
|
-
function
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
return
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
return fitSocketPath(join3(explicit, ".kobe", "daemon.sock"), explicit, "daemon");
|
|
4377
|
-
}
|
|
4378
|
-
const runtimeDir = process.env.XDG_RUNTIME_DIR;
|
|
4379
|
-
if (runtimeDir && runtimeDir.length > 0) {
|
|
4380
|
-
return fitSocketPath(join3(runtimeDir, "kobe.sock"), runtimeDir, "daemon");
|
|
4385
|
+
async function tmuxAvailable() {
|
|
4386
|
+
try {
|
|
4387
|
+
const proc = Bun.spawn(["tmux", "-V"], { stdin: "ignore", stdout: "ignore", stderr: "ignore" });
|
|
4388
|
+
return await proc.exited === 0;
|
|
4389
|
+
} catch {
|
|
4390
|
+
return false;
|
|
4381
4391
|
}
|
|
4382
|
-
const home = homedir6();
|
|
4383
|
-
return fitSocketPath(join3(home, ".kobe", "daemon.sock"), home, "daemon");
|
|
4384
4392
|
}
|
|
4385
|
-
function
|
|
4386
|
-
|
|
4387
|
-
if (override && override.length > 0)
|
|
4388
|
-
return override;
|
|
4389
|
-
return join3(homeDir2, ".kobe", "daemon.pid");
|
|
4393
|
+
async function sessionExists(name) {
|
|
4394
|
+
return await runTmuxQuiet(["has-session", "-t", `=${name}`]) === 0;
|
|
4390
4395
|
}
|
|
4391
|
-
function
|
|
4392
|
-
|
|
4396
|
+
async function windowCount(sessionName) {
|
|
4397
|
+
const { code, stdout } = await runTmuxCapturing(["list-windows", "-t", `=${sessionName}`, "-F", "#{window_id}"]);
|
|
4398
|
+
if (code !== 0)
|
|
4399
|
+
return 0;
|
|
4400
|
+
return stdout.split(`
|
|
4401
|
+
`).filter((l) => l.trim().length > 0).length;
|
|
4393
4402
|
}
|
|
4394
|
-
|
|
4395
|
-
|
|
4396
|
-
|
|
4397
|
-
// src/daemon/server.ts
|
|
4398
|
-
import { mkdir as mkdir3, readFile as readFile5, unlink as unlink4, writeFile as writeFile3 } from "fs/promises";
|
|
4399
|
-
import { createServer } from "net";
|
|
4400
|
-
import { dirname as dirname3 } from "path";
|
|
4401
|
-
function resolveIdleGraceMs() {
|
|
4402
|
-
const raw = process.env.KOBE_DAEMON_IDLE_GRACE_MS;
|
|
4403
|
-
if (raw === undefined)
|
|
4404
|
-
return DEFAULT_IDLE_GRACE_MS;
|
|
4405
|
-
const n = Number(raw);
|
|
4406
|
-
return Number.isFinite(n) && n >= 0 ? n : DEFAULT_IDLE_GRACE_MS;
|
|
4403
|
+
async function setSessionOption(session, option, value) {
|
|
4404
|
+
await runTmux(["set-option", "-t", session, option, value]);
|
|
4407
4405
|
}
|
|
4408
|
-
async function
|
|
4409
|
-
const
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
const
|
|
4415
|
-
|
|
4406
|
+
async function getSessionOption(session, option) {
|
|
4407
|
+
const { code, stdout } = await runTmuxCapturing(["show-options", "-v", "-t", session, option]);
|
|
4408
|
+
return code === 0 ? stdout.trim() : "";
|
|
4409
|
+
}
|
|
4410
|
+
async function getSessionOptions(session, options) {
|
|
4411
|
+
const values = Object.fromEntries(options.map((option) => [option, undefined]));
|
|
4412
|
+
const { code, stdout } = await runTmuxSequenceCapturing(options.map((option) => ["show-options", "-q", "-t", session, option]));
|
|
4413
|
+
if (code !== 0)
|
|
4414
|
+
return values;
|
|
4415
|
+
for (const line of stdout.split(`
|
|
4416
|
+
`)) {
|
|
4417
|
+
const idx = line.indexOf(" ");
|
|
4418
|
+
if (idx <= 0)
|
|
4419
|
+
continue;
|
|
4420
|
+
const option = line.slice(0, idx);
|
|
4421
|
+
if (option in values)
|
|
4422
|
+
values[option] = line.slice(idx + 1).trim();
|
|
4423
|
+
}
|
|
4424
|
+
return values;
|
|
4425
|
+
}
|
|
4426
|
+
async function tagPaneRole(paneId, role) {
|
|
4427
|
+
await runTmux(["set-option", "-p", "-t", paneId, PANE_ROLE_OPTION, role]);
|
|
4428
|
+
}
|
|
4429
|
+
async function setWindowOption(target, option, value) {
|
|
4430
|
+
await runTmux(["set-window-option", "-t", target, option, value]);
|
|
4431
|
+
}
|
|
4432
|
+
async function tagClaudePane(paneId) {
|
|
4433
|
+
await tagPaneRole(paneId, CLAUDE_ROLE_VALUE);
|
|
4434
|
+
}
|
|
4435
|
+
async function paneIdByRole(sessionName, role, fallbackFirst = false) {
|
|
4436
|
+
const { code, stdout } = await runTmuxCapturing([
|
|
4437
|
+
"list-panes",
|
|
4438
|
+
"-t",
|
|
4439
|
+
`=${sessionName}`,
|
|
4440
|
+
"-F",
|
|
4441
|
+
`#{pane_id} #{${PANE_ROLE_OPTION}}`
|
|
4442
|
+
]);
|
|
4443
|
+
if (code !== 0)
|
|
4444
|
+
return "";
|
|
4445
|
+
let firstId = "";
|
|
4446
|
+
for (const line of stdout.split(`
|
|
4447
|
+
`)) {
|
|
4448
|
+
const [id, paneRole] = line.split("\t");
|
|
4449
|
+
if (!id)
|
|
4450
|
+
continue;
|
|
4451
|
+
if (!firstId)
|
|
4452
|
+
firstId = id.trim();
|
|
4453
|
+
if (paneRole?.trim() === role)
|
|
4454
|
+
return id.trim();
|
|
4455
|
+
}
|
|
4456
|
+
return fallbackFirst ? firstId : "";
|
|
4457
|
+
}
|
|
4458
|
+
async function claudePaneId(sessionName) {
|
|
4459
|
+
return paneIdByRole(sessionName, CLAUDE_ROLE_VALUE, true);
|
|
4460
|
+
}
|
|
4461
|
+
async function claudePaneIdStrict(sessionName) {
|
|
4462
|
+
return paneIdByRole(sessionName, CLAUDE_ROLE_VALUE, false);
|
|
4463
|
+
}
|
|
4464
|
+
async function capturePaneById(paneId, lines) {
|
|
4465
|
+
if (!paneId)
|
|
4466
|
+
return "";
|
|
4467
|
+
const args = ["capture-pane", "-t", paneId, "-p"];
|
|
4468
|
+
if (typeof lines === "number" && lines > 0)
|
|
4469
|
+
args.push("-S", String(-lines));
|
|
4470
|
+
const { code, stdout } = await runTmuxCapturing(args);
|
|
4471
|
+
return code === 0 ? stdout : "";
|
|
4472
|
+
}
|
|
4473
|
+
async function sendKeys(target, text) {
|
|
4474
|
+
await runTmux(["send-keys", "-t", target, "-l", "--", text]);
|
|
4475
|
+
}
|
|
4476
|
+
async function sendKeyName(target, key) {
|
|
4477
|
+
await runTmux(["send-keys", "-t", target, key]);
|
|
4478
|
+
}
|
|
4479
|
+
async function newWindow(session, opts) {
|
|
4480
|
+
const args = ["new-window", "-t", `=${session}`, "-c", opts.cwd];
|
|
4481
|
+
if (opts.name)
|
|
4482
|
+
args.push("-n", opts.name);
|
|
4483
|
+
args.push(opts.command);
|
|
4484
|
+
await runTmux(args);
|
|
4485
|
+
}
|
|
4486
|
+
async function currentSessionName() {
|
|
4487
|
+
const args = ["display-message", "-p"];
|
|
4488
|
+
const target = process.env.TMUX_PANE;
|
|
4489
|
+
if (target && target.length > 0)
|
|
4490
|
+
args.push("-t", target);
|
|
4491
|
+
args.push("#{session_name}");
|
|
4492
|
+
const { code, stdout } = await runTmuxCapturing(args);
|
|
4493
|
+
const name = stdout.trim();
|
|
4494
|
+
return code === 0 && name.length > 0 ? name : null;
|
|
4495
|
+
}
|
|
4496
|
+
async function killSession(name) {
|
|
4497
|
+
if (await sessionExists(name))
|
|
4498
|
+
await runTmux(["kill-session", "-t", `=${name}`]);
|
|
4499
|
+
}
|
|
4500
|
+
async function ensureFallbackSession() {
|
|
4501
|
+
const name = KOBE_HOME_SESSION;
|
|
4502
|
+
if (!await sessionExists(name)) {
|
|
4503
|
+
await runTmux([
|
|
4504
|
+
"new-session",
|
|
4505
|
+
"-d",
|
|
4506
|
+
"-s",
|
|
4507
|
+
name,
|
|
4508
|
+
"-x",
|
|
4509
|
+
"220",
|
|
4510
|
+
"-y",
|
|
4511
|
+
"50",
|
|
4512
|
+
"sh",
|
|
4513
|
+
"-c",
|
|
4514
|
+
'clear; printf "\\n No active task\\n\\n Select a task from the sidebar to continue.\\n\\n"; exec ${SHELL:-sh}'
|
|
4515
|
+
]);
|
|
4516
|
+
}
|
|
4517
|
+
return name;
|
|
4518
|
+
}
|
|
4519
|
+
async function switchClientBeforeKill(killedName, nextSessionName) {
|
|
4520
|
+
const current = await currentSessionName();
|
|
4521
|
+
if (current !== killedName)
|
|
4522
|
+
return;
|
|
4523
|
+
if (nextSessionName && nextSessionName !== killedName && await sessionExists(nextSessionName)) {
|
|
4524
|
+
await runTmux(["switch-client", "-t", `=${nextSessionName}`]);
|
|
4525
|
+
return;
|
|
4526
|
+
}
|
|
4527
|
+
const fallback = await ensureFallbackSession();
|
|
4528
|
+
await runTmux(["switch-client", "-t", `=${fallback}`]);
|
|
4529
|
+
}
|
|
4530
|
+
var KOBE_TMUX_SOCKET, PANE_ROLE_OPTION = "@kobe_role", CLAUDE_ROLE_OPTION, CLAUDE_ROLE_VALUE = "claude", CHAT_TAB_SESSION_ID_OPTION = "@kobe_session_id", KOBE_HOME_SESSION = "kobe-home";
|
|
4531
|
+
var init_client2 = __esm(() => {
|
|
4532
|
+
KOBE_TMUX_SOCKET = process.env.KOBE_TMUX_SOCKET?.trim() || "kobe";
|
|
4533
|
+
CLAUDE_ROLE_OPTION = PANE_ROLE_OPTION;
|
|
4534
|
+
});
|
|
4535
|
+
|
|
4536
|
+
// src/tmux/chat-tab-naming.ts
|
|
4537
|
+
async function listChatTabWindows(session, runner = realRunner) {
|
|
4538
|
+
const { code, stdout } = await runner.capture([
|
|
4539
|
+
"list-windows",
|
|
4540
|
+
"-t",
|
|
4541
|
+
`=${session}`,
|
|
4542
|
+
"-F",
|
|
4543
|
+
`#{window_index} #{${CHAT_TAB_SESSION_ID_OPTION}}`
|
|
4544
|
+
]);
|
|
4545
|
+
if (code !== 0)
|
|
4546
|
+
return [];
|
|
4547
|
+
const out = [];
|
|
4548
|
+
for (const line of stdout.split(`
|
|
4549
|
+
`)) {
|
|
4550
|
+
const tab = line.indexOf("\t");
|
|
4551
|
+
const index = Number.parseInt((tab >= 0 ? line.slice(0, tab) : line).trim(), 10);
|
|
4552
|
+
if (!Number.isInteger(index))
|
|
4553
|
+
continue;
|
|
4554
|
+
out.push({ index, sessionId: tab >= 0 ? line.slice(tab + 1).trim() : "" });
|
|
4555
|
+
}
|
|
4556
|
+
return out;
|
|
4557
|
+
}
|
|
4558
|
+
async function windowNamedManually(session, index, runner) {
|
|
4559
|
+
const { code, stdout } = await runner.capture([
|
|
4560
|
+
"show-window-options",
|
|
4561
|
+
"-t",
|
|
4562
|
+
`=${session}:${index}`,
|
|
4563
|
+
"automatic-rename"
|
|
4564
|
+
]);
|
|
4565
|
+
return code === 0 && /\boff\b/.test(stdout);
|
|
4566
|
+
}
|
|
4567
|
+
async function renameWindow(session, index, title, runner) {
|
|
4568
|
+
return await runner.run(["rename-window", "-t", `=${session}:${index}`, "--", title]) === 0;
|
|
4569
|
+
}
|
|
4570
|
+
async function runChatTabNamingPass(orch, deps = realDeps) {
|
|
4571
|
+
let renamed = 0;
|
|
4572
|
+
for (const task of orch.listTasks()) {
|
|
4573
|
+
if (task.kind === "main" || !task.worktreePath)
|
|
4574
|
+
continue;
|
|
4575
|
+
const session = tmuxSessionName(task.id);
|
|
4576
|
+
const windows = await listChatTabWindows(session, deps.runner);
|
|
4577
|
+
if (windows.length === 0)
|
|
4578
|
+
continue;
|
|
4579
|
+
const originIndex = windows.reduce((min, w) => Math.min(min, w.index), Number.POSITIVE_INFINITY);
|
|
4580
|
+
const vendor = task.vendor ?? DEFAULT_TASK_VENDOR;
|
|
4581
|
+
for (const w of windows) {
|
|
4582
|
+
try {
|
|
4583
|
+
if (await windowNamedManually(session, w.index, deps.runner))
|
|
4584
|
+
continue;
|
|
4585
|
+
const title = w.sessionId ? await deps.titleFromSessionId(vendor, w.sessionId) : w.index === originIndex ? await deps.titleFromWorktree(task.worktreePath, vendor) : "";
|
|
4586
|
+
if (title && await renameWindow(session, w.index, title, deps.runner))
|
|
4587
|
+
renamed++;
|
|
4588
|
+
} catch {}
|
|
4589
|
+
}
|
|
4590
|
+
}
|
|
4591
|
+
return renamed;
|
|
4592
|
+
}
|
|
4593
|
+
var realRunner, realDeps;
|
|
4594
|
+
var init_chat_tab_naming = __esm(() => {
|
|
4595
|
+
init_auto_title();
|
|
4596
|
+
init_client2();
|
|
4597
|
+
realRunner = { capture: runTmuxCapturing, run: runTmux };
|
|
4598
|
+
realDeps = {
|
|
4599
|
+
runner: realRunner,
|
|
4600
|
+
titleFromSessionId: deriveTitleFromSessionId,
|
|
4601
|
+
titleFromWorktree: deriveTitleFromSession
|
|
4602
|
+
};
|
|
4603
|
+
});
|
|
4604
|
+
|
|
4605
|
+
// src/daemon/crash-log.ts
|
|
4606
|
+
function toError(err) {
|
|
4607
|
+
if (err instanceof Error)
|
|
4608
|
+
return err;
|
|
4609
|
+
let text;
|
|
4610
|
+
try {
|
|
4611
|
+
text = typeof err === "string" ? err : JSON.stringify(err);
|
|
4612
|
+
} catch {
|
|
4613
|
+
text = String(err);
|
|
4614
|
+
}
|
|
4615
|
+
return new Error(text);
|
|
4616
|
+
}
|
|
4617
|
+
function formatCrashEntry(kind, err, now = new Date) {
|
|
4618
|
+
const e = toError(err);
|
|
4619
|
+
return `[${now.toISOString()}] daemon ${kind}: ${e.stack ?? `${e.name}: ${e.message}`}
|
|
4620
|
+
`;
|
|
4621
|
+
}
|
|
4622
|
+
function formatDaemonError(subsystem, err, now = new Date) {
|
|
4623
|
+
const e = toError(err);
|
|
4624
|
+
return `[${now.toISOString()}] daemon error [${subsystem}]: ${e.stack ?? `${e.name}: ${e.message}`}
|
|
4625
|
+
`;
|
|
4626
|
+
}
|
|
4627
|
+
function logDaemonError(subsystem, err) {
|
|
4628
|
+
process.stderr.write(formatDaemonError(subsystem, err));
|
|
4629
|
+
}
|
|
4630
|
+
function installDaemonCrashHandlers(log = (l) => process.stderr.write(l)) {
|
|
4631
|
+
if (onRejection || onException)
|
|
4632
|
+
return;
|
|
4633
|
+
onRejection = (reason) => log(formatCrashEntry("unhandledRejection", reason));
|
|
4634
|
+
onException = (err) => log(formatCrashEntry("uncaughtException", err));
|
|
4635
|
+
process.on("unhandledRejection", onRejection);
|
|
4636
|
+
process.on("uncaughtException", onException);
|
|
4637
|
+
}
|
|
4638
|
+
var onRejection, onException;
|
|
4639
|
+
|
|
4640
|
+
// src/daemon/auto-title-poller.ts
|
|
4641
|
+
async function runAutoTitlePass(orch, derive = deriveTitleFromSession) {
|
|
4642
|
+
const renamed = [];
|
|
4643
|
+
for (const task of orch.listTasks()) {
|
|
4644
|
+
if (task.title !== PLACEHOLDER_TASK_TITLE || !task.worktreePath)
|
|
4645
|
+
continue;
|
|
4646
|
+
try {
|
|
4647
|
+
const title = await derive(task.worktreePath, task.vendor ?? DEFAULT_TASK_VENDOR);
|
|
4648
|
+
if (!title)
|
|
4649
|
+
continue;
|
|
4650
|
+
const current = orch.getTask(task.id);
|
|
4651
|
+
if (!current || current.title !== PLACEHOLDER_TASK_TITLE)
|
|
4652
|
+
continue;
|
|
4653
|
+
await orch.setTitle(task.id, title);
|
|
4654
|
+
renamed.push({ id: task.id, title });
|
|
4655
|
+
} catch (err) {
|
|
4656
|
+
logDaemonError("auto-title-poller", err);
|
|
4657
|
+
}
|
|
4658
|
+
}
|
|
4659
|
+
return renamed;
|
|
4660
|
+
}
|
|
4661
|
+
function startAutoTitlePoller(orch, intervalMs = DEFAULT_AUTO_TITLE_POLL_MS) {
|
|
4662
|
+
if (intervalMs <= 0)
|
|
4663
|
+
return () => {};
|
|
4664
|
+
let running = false;
|
|
4665
|
+
const tick = () => {
|
|
4666
|
+
if (running)
|
|
4667
|
+
return;
|
|
4668
|
+
running = true;
|
|
4669
|
+
runAutoTitlePass(orch).then(() => runChatTabNamingPass(orch)).catch((err) => logDaemonError("auto-title-poller", err)).finally(() => {
|
|
4670
|
+
running = false;
|
|
4671
|
+
});
|
|
4672
|
+
};
|
|
4673
|
+
const timer = setInterval(tick, intervalMs);
|
|
4674
|
+
timer.unref?.();
|
|
4675
|
+
return () => clearInterval(timer);
|
|
4676
|
+
}
|
|
4677
|
+
var DEFAULT_AUTO_TITLE_POLL_MS = 4000;
|
|
4678
|
+
var init_auto_title_poller = __esm(() => {
|
|
4679
|
+
init_auto_title();
|
|
4680
|
+
init_core();
|
|
4681
|
+
init_chat_tab_naming();
|
|
4682
|
+
});
|
|
4683
|
+
|
|
4684
|
+
// src/daemon/event-bus.ts
|
|
4685
|
+
class DaemonEventBus {
|
|
4686
|
+
last = new Map;
|
|
4687
|
+
sinks = new Set;
|
|
4688
|
+
publish(channel, payload) {
|
|
4689
|
+
this.last.set(channel, payload);
|
|
4690
|
+
const event = { channel, payload };
|
|
4691
|
+
for (const sink of this.sinks)
|
|
4692
|
+
sink(event);
|
|
4693
|
+
}
|
|
4694
|
+
snapshot() {
|
|
4695
|
+
return [...this.last].map(([channel, payload]) => ({ channel, payload }));
|
|
4696
|
+
}
|
|
4697
|
+
onPublish(sink) {
|
|
4698
|
+
this.sinks.add(sink);
|
|
4699
|
+
return () => {
|
|
4700
|
+
this.sinks.delete(sink);
|
|
4701
|
+
};
|
|
4702
|
+
}
|
|
4703
|
+
}
|
|
4704
|
+
|
|
4705
|
+
// src/daemon/paths.ts
|
|
4706
|
+
import { createHash as createHash2 } from "crypto";
|
|
4707
|
+
import { homedir as homedir6, tmpdir } from "os";
|
|
4708
|
+
import { join as join3 } from "path";
|
|
4709
|
+
function shortHomeTag(homeDir2) {
|
|
4710
|
+
return createHash2("sha1").update(homeDir2).digest("hex").slice(0, 8);
|
|
4711
|
+
}
|
|
4712
|
+
function fitSocketPath(naturalPath, homeDir2, role, pidTag) {
|
|
4713
|
+
if (Buffer.byteLength(naturalPath, "utf8") <= SOCKET_PATH_SAFETY_LIMIT)
|
|
4714
|
+
return naturalPath;
|
|
4715
|
+
const tag = shortHomeTag(homeDir2);
|
|
4716
|
+
const suffix = pidTag === undefined ? "" : `-${pidTag}`;
|
|
4717
|
+
const fallback = join3(tmpdir(), `kobe-${tag}-${role}${suffix}.sock`);
|
|
4718
|
+
if (Buffer.byteLength(fallback, "utf8") <= SOCKET_PATH_SAFETY_LIMIT)
|
|
4719
|
+
return fallback;
|
|
4720
|
+
throw new Error(`kobe socket path exceeds ${SOCKET_PATH_SAFETY_LIMIT} bytes even after fallback: ${fallback}`);
|
|
4721
|
+
}
|
|
4722
|
+
function defaultDaemonSocketPath(homeDir2) {
|
|
4723
|
+
const override = process.env.KOBE_DAEMON_SOCKET_PATH;
|
|
4724
|
+
if (override && override.length > 0)
|
|
4725
|
+
return override;
|
|
4726
|
+
const explicit = homeDir2 ?? process.env.KOBE_HOME_DIR;
|
|
4727
|
+
if (explicit && explicit.length > 0) {
|
|
4728
|
+
return fitSocketPath(join3(explicit, ".kobe", "daemon.sock"), explicit, "daemon");
|
|
4729
|
+
}
|
|
4730
|
+
const runtimeDir = process.env.XDG_RUNTIME_DIR;
|
|
4731
|
+
if (runtimeDir && runtimeDir.length > 0) {
|
|
4732
|
+
return fitSocketPath(join3(runtimeDir, "kobe.sock"), runtimeDir, "daemon");
|
|
4733
|
+
}
|
|
4734
|
+
const home = homedir6();
|
|
4735
|
+
return fitSocketPath(join3(home, ".kobe", "daemon.sock"), home, "daemon");
|
|
4736
|
+
}
|
|
4737
|
+
function defaultDaemonPidPath(homeDir2 = process.env.KOBE_HOME_DIR ?? homedir6()) {
|
|
4738
|
+
const override = process.env.KOBE_DAEMON_PID_PATH;
|
|
4739
|
+
if (override && override.length > 0)
|
|
4740
|
+
return override;
|
|
4741
|
+
return join3(homeDir2, ".kobe", "daemon.pid");
|
|
4742
|
+
}
|
|
4743
|
+
function defaultDaemonLogPath(homeDir2 = process.env.KOBE_HOME_DIR ?? homedir6()) {
|
|
4744
|
+
return join3(homeDir2, ".kobe", "daemon.log");
|
|
4745
|
+
}
|
|
4746
|
+
var SOCKET_PATH_SAFETY_LIMIT = 100;
|
|
4747
|
+
var init_paths2 = () => {};
|
|
4748
|
+
|
|
4749
|
+
// src/daemon/server.ts
|
|
4750
|
+
import { mkdir as mkdir3, readFile as readFile5, unlink as unlink4, writeFile as writeFile3 } from "fs/promises";
|
|
4751
|
+
import { createServer } from "net";
|
|
4752
|
+
import { dirname as dirname3 } from "path";
|
|
4753
|
+
function resolveIdleGraceMs() {
|
|
4754
|
+
const raw = process.env.KOBE_DAEMON_IDLE_GRACE_MS;
|
|
4755
|
+
if (raw === undefined)
|
|
4756
|
+
return DEFAULT_IDLE_GRACE_MS;
|
|
4757
|
+
const n = Number(raw);
|
|
4758
|
+
return Number.isFinite(n) && n >= 0 ? n : DEFAULT_IDLE_GRACE_MS;
|
|
4759
|
+
}
|
|
4760
|
+
async function startDaemonServer(orch, options = {}) {
|
|
4761
|
+
const socketPath = options.socketPath ?? defaultDaemonSocketPath(options.homeDir);
|
|
4762
|
+
const pidPath = options.pidPath ?? defaultDaemonPidPath(options.homeDir);
|
|
4763
|
+
const startedAt = options.startedAt ?? new Date;
|
|
4764
|
+
const clients = new Set;
|
|
4765
|
+
let nextClientId = 1;
|
|
4766
|
+
const idleGraceMs = resolveIdleGraceMs();
|
|
4767
|
+
let idleTimer = null;
|
|
4416
4768
|
let stopping = false;
|
|
4417
4769
|
function guiCount() {
|
|
4418
4770
|
let n = 0;
|
|
@@ -5075,289 +5427,55 @@ var init_repo_cmd = __esm(() => {
|
|
|
5075
5427
|
].join(`
|
|
5076
5428
|
`);
|
|
5077
5429
|
});
|
|
5078
|
-
|
|
5079
|
-
// src/engine/interactive-command.ts
|
|
5080
|
-
|
|
5081
|
-
|
|
5082
|
-
}
|
|
5083
|
-
function defaultEngineCommand(vendor) {
|
|
5084
|
-
return DEFAULT_COMMANDS[vendor ?? "claude"] ?? DEFAULT_COMMANDS.claude;
|
|
5085
|
-
}
|
|
5086
|
-
function parseEngineCommand(command) {
|
|
5087
|
-
const out = [];
|
|
5088
|
-
const re = /"([^"]*)"|'([^']*)'|(\S+)/g;
|
|
5089
|
-
for (let m = re.exec(command);m !== null; m = re.exec(command)) {
|
|
5090
|
-
out.push(m[1] ?? m[2] ?? m[3] ?? "");
|
|
5091
|
-
}
|
|
5092
|
-
return out;
|
|
5093
|
-
}
|
|
5094
|
-
function interactiveEngineCommand(vendor) {
|
|
5095
|
-
const v = vendor ?? "claude";
|
|
5096
|
-
const override = getPersistedString(engineCommandKey(v))?.trim();
|
|
5097
|
-
if (override) {
|
|
5098
|
-
const argv = parseEngineCommand(override);
|
|
5099
|
-
if (argv.length > 0)
|
|
5100
|
-
return argv;
|
|
5101
|
-
}
|
|
5102
|
-
return defaultEngineCommand(v);
|
|
5103
|
-
}
|
|
5104
|
-
var DEFAULT_COMMANDS, VENDOR_LABEL;
|
|
5105
|
-
var init_interactive_command = __esm(() => {
|
|
5106
|
-
init_repos();
|
|
5107
|
-
DEFAULT_COMMANDS = {
|
|
5108
|
-
claude: ["claude"],
|
|
5109
|
-
codex: ["codex"],
|
|
5110
|
-
copilot: ["copilot"]
|
|
5111
|
-
};
|
|
5112
|
-
VENDOR_LABEL = {
|
|
5113
|
-
claude: "Claude",
|
|
5114
|
-
codex: "Codex",
|
|
5115
|
-
copilot: "Copilot"
|
|
5116
|
-
};
|
|
5117
|
-
});
|
|
5118
|
-
|
|
5119
|
-
// src/tmux/client.ts
|
|
5120
|
-
var exports_client = {};
|
|
5121
|
-
__export(exports_client, {
|
|
5122
|
-
windowCount: () => windowCount,
|
|
5123
|
-
tmuxSessionName: () => tmuxSessionName,
|
|
5124
|
-
tmuxCommandSequence: () => tmuxCommandSequence,
|
|
5125
|
-
tmuxAvailable: () => tmuxAvailable,
|
|
5126
|
-
tmuxArgs: () => tmuxArgs,
|
|
5127
|
-
tagPaneRole: () => tagPaneRole,
|
|
5128
|
-
tagClaudePane: () => tagClaudePane,
|
|
5129
|
-
switchClientBeforeKill: () => switchClientBeforeKill,
|
|
5130
|
-
setWindowOption: () => setWindowOption,
|
|
5131
|
-
setSessionOption: () => setSessionOption,
|
|
5132
|
-
sessionExists: () => sessionExists,
|
|
5133
|
-
sendKeys: () => sendKeys,
|
|
5134
|
-
sendKeyName: () => sendKeyName,
|
|
5135
|
-
runTmuxSequenceCapturing: () => runTmuxSequenceCapturing,
|
|
5136
|
-
runTmuxSequence: () => runTmuxSequence,
|
|
5137
|
-
runTmuxCapturing: () => runTmuxCapturing,
|
|
5138
|
-
runTmux: () => runTmux,
|
|
5139
|
-
paneIdByRole: () => paneIdByRole,
|
|
5140
|
-
newWindow: () => newWindow,
|
|
5141
|
-
killSession: () => killSession,
|
|
5142
|
-
getSessionOptions: () => getSessionOptions,
|
|
5143
|
-
getSessionOption: () => getSessionOption,
|
|
5144
|
-
ensureFallbackSession: () => ensureFallbackSession,
|
|
5145
|
-
currentSessionName: () => currentSessionName,
|
|
5146
|
-
claudePaneIdStrict: () => claudePaneIdStrict,
|
|
5147
|
-
claudePaneId: () => claudePaneId,
|
|
5148
|
-
capturePaneById: () => capturePaneById,
|
|
5149
|
-
attachArgv: () => attachArgv,
|
|
5150
|
-
PANE_ROLE_OPTION: () => PANE_ROLE_OPTION,
|
|
5151
|
-
KOBE_TMUX_SOCKET: () => KOBE_TMUX_SOCKET,
|
|
5152
|
-
KOBE_HOME_SESSION: () => KOBE_HOME_SESSION,
|
|
5153
|
-
CLAUDE_ROLE_OPTION: () => CLAUDE_ROLE_OPTION
|
|
5154
|
-
});
|
|
5155
|
-
function tmuxArgs(...args) {
|
|
5156
|
-
return ["tmux", "-L", KOBE_TMUX_SOCKET, ...args];
|
|
5157
|
-
}
|
|
5158
|
-
function tmuxSessionName(taskId) {
|
|
5159
|
-
return `kobe-${taskId.replace(/[^A-Za-z0-9_-]/g, "")}`;
|
|
5160
|
-
}
|
|
5161
|
-
function attachArgv(name) {
|
|
5162
|
-
return tmuxArgs("attach-session", "-t", `=${name}`);
|
|
5163
|
-
}
|
|
5164
|
-
async function drainText(stream) {
|
|
5165
|
-
if (!stream)
|
|
5166
|
-
return "";
|
|
5167
|
-
try {
|
|
5168
|
-
return await new Response(stream).text();
|
|
5169
|
-
} catch {
|
|
5170
|
-
return "";
|
|
5171
|
-
}
|
|
5172
|
-
}
|
|
5173
|
-
async function runTmux(args) {
|
|
5174
|
-
const proc = Bun.spawn(tmuxArgs(...args), { stdin: "ignore", stdout: "ignore", stderr: "pipe" });
|
|
5175
|
-
const [errText, code] = await Promise.all([drainText(proc.stderr), proc.exited]);
|
|
5176
|
-
if (code !== 0 && errText.trim().length > 0) {
|
|
5177
|
-
console.error(`[kobe tmux] ${args.join(" ")} (${code}): ${errText.trim()}`);
|
|
5178
|
-
}
|
|
5179
|
-
return code;
|
|
5180
|
-
}
|
|
5181
|
-
async function runTmuxQuiet(args) {
|
|
5182
|
-
const proc = Bun.spawn(tmuxArgs(...args), { stdin: "ignore", stdout: "ignore", stderr: "ignore" });
|
|
5183
|
-
return proc.exited;
|
|
5184
|
-
}
|
|
5185
|
-
function tmuxCommandSequence(commands) {
|
|
5186
|
-
const out = [];
|
|
5187
|
-
for (const cmd of commands) {
|
|
5188
|
-
if (cmd.length === 0)
|
|
5189
|
-
continue;
|
|
5190
|
-
if (out.length > 0)
|
|
5191
|
-
out.push(";");
|
|
5192
|
-
out.push(...cmd);
|
|
5193
|
-
}
|
|
5194
|
-
return out;
|
|
5195
|
-
}
|
|
5196
|
-
async function runTmuxSequence(commands) {
|
|
5197
|
-
const args = tmuxCommandSequence(commands);
|
|
5198
|
-
return args.length === 0 ? 0 : runTmux(args);
|
|
5199
|
-
}
|
|
5200
|
-
async function runTmuxCapturing(args) {
|
|
5201
|
-
const proc = Bun.spawn(tmuxArgs(...args), { stdin: "ignore", stdout: "pipe", stderr: "pipe" });
|
|
5202
|
-
const [stdout, errText, code] = await Promise.all([drainText(proc.stdout), drainText(proc.stderr), proc.exited]);
|
|
5203
|
-
if (code !== 0 && errText.trim().length > 0) {
|
|
5204
|
-
console.error(`[kobe tmux] ${args.join(" ")} (${code}): ${errText.trim()}`);
|
|
5205
|
-
}
|
|
5206
|
-
return { code, stdout };
|
|
5207
|
-
}
|
|
5208
|
-
async function runTmuxSequenceCapturing(commands) {
|
|
5209
|
-
const args = tmuxCommandSequence(commands);
|
|
5210
|
-
return args.length === 0 ? { code: 0, stdout: "" } : runTmuxCapturing(args);
|
|
5211
|
-
}
|
|
5212
|
-
async function tmuxAvailable() {
|
|
5213
|
-
try {
|
|
5214
|
-
const proc = Bun.spawn(["tmux", "-V"], { stdin: "ignore", stdout: "ignore", stderr: "ignore" });
|
|
5215
|
-
return await proc.exited === 0;
|
|
5216
|
-
} catch {
|
|
5217
|
-
return false;
|
|
5218
|
-
}
|
|
5219
|
-
}
|
|
5220
|
-
async function sessionExists(name) {
|
|
5221
|
-
return await runTmuxQuiet(["has-session", "-t", `=${name}`]) === 0;
|
|
5222
|
-
}
|
|
5223
|
-
async function windowCount(sessionName) {
|
|
5224
|
-
const { code, stdout } = await runTmuxCapturing(["list-windows", "-t", `=${sessionName}`, "-F", "#{window_id}"]);
|
|
5225
|
-
if (code !== 0)
|
|
5226
|
-
return 0;
|
|
5227
|
-
return stdout.split(`
|
|
5228
|
-
`).filter((l) => l.trim().length > 0).length;
|
|
5229
|
-
}
|
|
5230
|
-
async function setSessionOption(session, option, value) {
|
|
5231
|
-
await runTmux(["set-option", "-t", session, option, value]);
|
|
5232
|
-
}
|
|
5233
|
-
async function getSessionOption(session, option) {
|
|
5234
|
-
const { code, stdout } = await runTmuxCapturing(["show-options", "-v", "-t", session, option]);
|
|
5235
|
-
return code === 0 ? stdout.trim() : "";
|
|
5236
|
-
}
|
|
5237
|
-
async function getSessionOptions(session, options) {
|
|
5238
|
-
const values = Object.fromEntries(options.map((option) => [option, undefined]));
|
|
5239
|
-
const { code, stdout } = await runTmuxSequenceCapturing(options.map((option) => ["show-options", "-q", "-t", session, option]));
|
|
5240
|
-
if (code !== 0)
|
|
5241
|
-
return values;
|
|
5242
|
-
for (const line of stdout.split(`
|
|
5243
|
-
`)) {
|
|
5244
|
-
const idx = line.indexOf(" ");
|
|
5245
|
-
if (idx <= 0)
|
|
5246
|
-
continue;
|
|
5247
|
-
const option = line.slice(0, idx);
|
|
5248
|
-
if (option in values)
|
|
5249
|
-
values[option] = line.slice(idx + 1).trim();
|
|
5250
|
-
}
|
|
5251
|
-
return values;
|
|
5252
|
-
}
|
|
5253
|
-
async function tagPaneRole(paneId, role) {
|
|
5254
|
-
await runTmux(["set-option", "-p", "-t", paneId, PANE_ROLE_OPTION, role]);
|
|
5255
|
-
}
|
|
5256
|
-
async function setWindowOption(target, option, value) {
|
|
5257
|
-
await runTmux(["set-window-option", "-t", target, option, value]);
|
|
5258
|
-
}
|
|
5259
|
-
async function tagClaudePane(paneId) {
|
|
5260
|
-
await tagPaneRole(paneId, CLAUDE_ROLE_VALUE);
|
|
5261
|
-
}
|
|
5262
|
-
async function paneIdByRole(sessionName, role, fallbackFirst = false) {
|
|
5263
|
-
const { code, stdout } = await runTmuxCapturing([
|
|
5264
|
-
"list-panes",
|
|
5265
|
-
"-t",
|
|
5266
|
-
`=${sessionName}`,
|
|
5267
|
-
"-F",
|
|
5268
|
-
`#{pane_id} #{${PANE_ROLE_OPTION}}`
|
|
5269
|
-
]);
|
|
5270
|
-
if (code !== 0)
|
|
5271
|
-
return "";
|
|
5272
|
-
let firstId = "";
|
|
5273
|
-
for (const line of stdout.split(`
|
|
5274
|
-
`)) {
|
|
5275
|
-
const [id, paneRole] = line.split("\t");
|
|
5276
|
-
if (!id)
|
|
5277
|
-
continue;
|
|
5278
|
-
if (!firstId)
|
|
5279
|
-
firstId = id.trim();
|
|
5280
|
-
if (paneRole?.trim() === role)
|
|
5281
|
-
return id.trim();
|
|
5282
|
-
}
|
|
5283
|
-
return fallbackFirst ? firstId : "";
|
|
5284
|
-
}
|
|
5285
|
-
async function claudePaneId(sessionName) {
|
|
5286
|
-
return paneIdByRole(sessionName, CLAUDE_ROLE_VALUE, true);
|
|
5287
|
-
}
|
|
5288
|
-
async function claudePaneIdStrict(sessionName) {
|
|
5289
|
-
return paneIdByRole(sessionName, CLAUDE_ROLE_VALUE, false);
|
|
5290
|
-
}
|
|
5291
|
-
async function capturePaneById(paneId, lines) {
|
|
5292
|
-
if (!paneId)
|
|
5293
|
-
return "";
|
|
5294
|
-
const args = ["capture-pane", "-t", paneId, "-p"];
|
|
5295
|
-
if (typeof lines === "number" && lines > 0)
|
|
5296
|
-
args.push("-S", String(-lines));
|
|
5297
|
-
const { code, stdout } = await runTmuxCapturing(args);
|
|
5298
|
-
return code === 0 ? stdout : "";
|
|
5299
|
-
}
|
|
5300
|
-
async function sendKeys(target, text) {
|
|
5301
|
-
await runTmux(["send-keys", "-t", target, "-l", "--", text]);
|
|
5302
|
-
}
|
|
5303
|
-
async function sendKeyName(target, key) {
|
|
5304
|
-
await runTmux(["send-keys", "-t", target, key]);
|
|
5305
|
-
}
|
|
5306
|
-
async function newWindow(session, opts) {
|
|
5307
|
-
const args = ["new-window", "-t", `=${session}`, "-c", opts.cwd];
|
|
5308
|
-
if (opts.name)
|
|
5309
|
-
args.push("-n", opts.name);
|
|
5310
|
-
args.push(opts.command);
|
|
5311
|
-
await runTmux(args);
|
|
5312
|
-
}
|
|
5313
|
-
async function currentSessionName() {
|
|
5314
|
-
const args = ["display-message", "-p"];
|
|
5315
|
-
const target = process.env.TMUX_PANE;
|
|
5316
|
-
if (target && target.length > 0)
|
|
5317
|
-
args.push("-t", target);
|
|
5318
|
-
args.push("#{session_name}");
|
|
5319
|
-
const { code, stdout } = await runTmuxCapturing(args);
|
|
5320
|
-
const name = stdout.trim();
|
|
5321
|
-
return code === 0 && name.length > 0 ? name : null;
|
|
5430
|
+
|
|
5431
|
+
// src/engine/interactive-command.ts
|
|
5432
|
+
import { randomUUID } from "crypto";
|
|
5433
|
+
function engineCommandKey(vendor) {
|
|
5434
|
+
return `engineCommand.${vendor}`;
|
|
5322
5435
|
}
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
await runTmux(["kill-session", "-t", `=${name}`]);
|
|
5436
|
+
function defaultEngineCommand(vendor) {
|
|
5437
|
+
return DEFAULT_COMMANDS[vendor ?? "claude"] ?? DEFAULT_COMMANDS.claude;
|
|
5326
5438
|
}
|
|
5327
|
-
|
|
5328
|
-
const
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
"-d",
|
|
5333
|
-
"-s",
|
|
5334
|
-
name,
|
|
5335
|
-
"-x",
|
|
5336
|
-
"220",
|
|
5337
|
-
"-y",
|
|
5338
|
-
"50",
|
|
5339
|
-
"sh",
|
|
5340
|
-
"-c",
|
|
5341
|
-
'clear; printf "\\n No active task\\n\\n Select a task from the sidebar to continue.\\n\\n"; exec ${SHELL:-sh}'
|
|
5342
|
-
]);
|
|
5439
|
+
function parseEngineCommand(command) {
|
|
5440
|
+
const out = [];
|
|
5441
|
+
const re = /"([^"]*)"|'([^']*)'|(\S+)/g;
|
|
5442
|
+
for (let m = re.exec(command);m !== null; m = re.exec(command)) {
|
|
5443
|
+
out.push(m[1] ?? m[2] ?? m[3] ?? "");
|
|
5343
5444
|
}
|
|
5344
|
-
return
|
|
5445
|
+
return out;
|
|
5345
5446
|
}
|
|
5346
|
-
|
|
5347
|
-
const
|
|
5348
|
-
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5447
|
+
function interactiveEngineCommand(vendor) {
|
|
5448
|
+
const v = vendor ?? "claude";
|
|
5449
|
+
const override = getPersistedString(engineCommandKey(v))?.trim();
|
|
5450
|
+
if (override) {
|
|
5451
|
+
const argv = parseEngineCommand(override);
|
|
5452
|
+
if (argv.length > 0)
|
|
5453
|
+
return argv;
|
|
5353
5454
|
}
|
|
5354
|
-
|
|
5355
|
-
await runTmux(["switch-client", "-t", `=${fallback}`]);
|
|
5455
|
+
return defaultEngineCommand(v);
|
|
5356
5456
|
}
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5457
|
+
function withClaudeSessionId(argv, vendor) {
|
|
5458
|
+
if ((vendor ?? "claude") !== "claude")
|
|
5459
|
+
return { argv, sessionId: null };
|
|
5460
|
+
if (argv.some((a) => CLAUDE_SESSION_CONTROL_FLAGS.has(a)))
|
|
5461
|
+
return { argv, sessionId: null };
|
|
5462
|
+
const sessionId = randomUUID();
|
|
5463
|
+
return { argv: [...argv, "--session-id", sessionId], sessionId };
|
|
5464
|
+
}
|
|
5465
|
+
var DEFAULT_COMMANDS, VENDOR_LABEL, CLAUDE_SESSION_CONTROL_FLAGS;
|
|
5466
|
+
var init_interactive_command = __esm(() => {
|
|
5467
|
+
init_repos();
|
|
5468
|
+
DEFAULT_COMMANDS = {
|
|
5469
|
+
claude: ["claude"],
|
|
5470
|
+
codex: ["codex"],
|
|
5471
|
+
copilot: ["copilot"]
|
|
5472
|
+
};
|
|
5473
|
+
VENDOR_LABEL = {
|
|
5474
|
+
claude: "Claude",
|
|
5475
|
+
codex: "Codex",
|
|
5476
|
+
copilot: "Copilot"
|
|
5477
|
+
};
|
|
5478
|
+
CLAUDE_SESSION_CONTROL_FLAGS = new Set(["--session-id", "--resume", "-r", "--continue", "-c", "--from-pr"]);
|
|
5361
5479
|
});
|
|
5362
5480
|
|
|
5363
5481
|
// src/tmux/prompt-delivery.ts
|
|
@@ -5480,6 +5598,7 @@ __export(exports_tmux, {
|
|
|
5480
5598
|
tmuxAvailable: () => tmuxAvailable,
|
|
5481
5599
|
switchClientBeforeKill: () => switchClientBeforeKill,
|
|
5482
5600
|
sessionExists: () => sessionExists,
|
|
5601
|
+
refreshKobeWorkspacePanes: () => refreshKobeWorkspacePanes,
|
|
5483
5602
|
quickCreate: () => quickCreate,
|
|
5484
5603
|
openUpdateTab: () => openUpdateTab,
|
|
5485
5604
|
openSettingsTab: () => openSettingsTab,
|
|
@@ -5487,6 +5606,7 @@ __export(exports_tmux, {
|
|
|
5487
5606
|
newChatTab: () => newChatTab,
|
|
5488
5607
|
killSession: () => killSession,
|
|
5489
5608
|
ensureSession: () => ensureSession,
|
|
5609
|
+
currentSessionName: () => currentSessionName,
|
|
5490
5610
|
attachArgv: () => attachArgv,
|
|
5491
5611
|
PANE_VERSION_OPTION: () => PANE_VERSION_OPTION,
|
|
5492
5612
|
CHAT_TAB_SWITCH_BINDINGS: () => CHAT_TAB_SWITCH_BINDINGS,
|
|
@@ -5549,6 +5669,7 @@ async function ensureSessionImpl(opts) {
|
|
|
5549
5669
|
await runTmux(["kill-session", "-t", `=${opts.name}`]);
|
|
5550
5670
|
}
|
|
5551
5671
|
const inv = kobeCliInvocation();
|
|
5672
|
+
const launch = withClaudeSessionId(opts.command, opts.vendor);
|
|
5552
5673
|
const r0 = await runTmuxCapturing([
|
|
5553
5674
|
"new-session",
|
|
5554
5675
|
"-d",
|
|
@@ -5560,7 +5681,7 @@ async function ensureSessionImpl(opts) {
|
|
|
5560
5681
|
"-P",
|
|
5561
5682
|
"-F",
|
|
5562
5683
|
"#{pane_id}",
|
|
5563
|
-
engineLaunchLine(shellQuoteArgv(
|
|
5684
|
+
engineLaunchLine(shellQuoteArgv(launch.argv), {
|
|
5564
5685
|
initScript: opts.initScript,
|
|
5565
5686
|
markerPath: opts.initScript ? worktreeInitMarkerPath(opts.cwd) : undefined
|
|
5566
5687
|
})
|
|
@@ -5570,6 +5691,8 @@ async function ensureSessionImpl(opts) {
|
|
|
5570
5691
|
console.error("[kobe tmux] new-session returned no pane id; session creation failed");
|
|
5571
5692
|
return false;
|
|
5572
5693
|
}
|
|
5694
|
+
if (launch.sessionId)
|
|
5695
|
+
await setWindowOption(pane0, CHAT_TAB_SESSION_ID_OPTION, launch.sessionId);
|
|
5573
5696
|
await runTmuxSequence([
|
|
5574
5697
|
...opts.taskId ? [["set-option", "-t", opts.name, "@kobe_task", opts.taskId]] : [],
|
|
5575
5698
|
["set-option", "-t", opts.name, "@kobe_worktree", opts.cwd],
|
|
@@ -5711,6 +5834,58 @@ async function healKobePaneVersions(session, cwd, taskId, vendor) {
|
|
|
5711
5834
|
if (commands.length > 0)
|
|
5712
5835
|
await runTmuxSequence(commands);
|
|
5713
5836
|
}
|
|
5837
|
+
async function refreshKobeWorkspacePanes(session) {
|
|
5838
|
+
const sessionOptions = await getSessionOptions(session, ["@kobe_worktree", "@kobe_task", "@kobe_vendor"]);
|
|
5839
|
+
const cwd = sessionOptions["@kobe_worktree"] || process.cwd();
|
|
5840
|
+
const taskId = sessionOptions["@kobe_task"] || undefined;
|
|
5841
|
+
const vendor = sessionOptions["@kobe_vendor"] || undefined;
|
|
5842
|
+
const inv = kobeCliInvocation();
|
|
5843
|
+
const envPrefix = inheritedEnvPrefix();
|
|
5844
|
+
const { code, stdout } = await runTmuxCapturing([
|
|
5845
|
+
"list-panes",
|
|
5846
|
+
"-s",
|
|
5847
|
+
"-t",
|
|
5848
|
+
`=${session}`,
|
|
5849
|
+
"-F",
|
|
5850
|
+
`#{window_id} #{pane_id} #{@kobe_role} #{${PANE_VERSION_OPTION}}`
|
|
5851
|
+
]);
|
|
5852
|
+
if (code !== 0)
|
|
5853
|
+
return;
|
|
5854
|
+
const byWindow = new Map;
|
|
5855
|
+
for (const row of parseKobePaneRows(stdout)) {
|
|
5856
|
+
const panes = byWindow.get(row.windowId) ?? [];
|
|
5857
|
+
panes.push(row);
|
|
5858
|
+
byWindow.set(row.windowId, panes);
|
|
5859
|
+
}
|
|
5860
|
+
const commands = [];
|
|
5861
|
+
for (const panes of byWindow.values()) {
|
|
5862
|
+
const claudePane = panes.find((pane) => pane.role === "claude")?.paneId;
|
|
5863
|
+
const tasksPane = panes.find((pane) => pane.role === "tasks");
|
|
5864
|
+
const opsPane = panes.find((pane) => pane.role === "ops");
|
|
5865
|
+
if (tasksPane) {
|
|
5866
|
+
commands.push(["respawn-pane", "-k", "-t", tasksPane.paneId, "-c", cwd, keepAlive(envPrefix + tasksPaneCommand(inv))], ["set-option", "-p", "-t", tasksPane.paneId, "@kobe_role", "tasks"], ["set-option", "-p", "-t", tasksPane.paneId, PANE_VERSION_OPTION, CURRENT_VERSION]);
|
|
5867
|
+
}
|
|
5868
|
+
if (opsPane && claudePane) {
|
|
5869
|
+
commands.push([
|
|
5870
|
+
"respawn-pane",
|
|
5871
|
+
"-k",
|
|
5872
|
+
"-t",
|
|
5873
|
+
opsPane.paneId,
|
|
5874
|
+
"-c",
|
|
5875
|
+
cwd,
|
|
5876
|
+
keepAlive(envPrefix + opsPaneCommand({
|
|
5877
|
+
cwd,
|
|
5878
|
+
taskId,
|
|
5879
|
+
claudePaneId: claudePane,
|
|
5880
|
+
cliInvocation: inv,
|
|
5881
|
+
vendor
|
|
5882
|
+
}))
|
|
5883
|
+
], ["set-option", "-p", "-t", opsPane.paneId, "@kobe_role", "ops"], ["set-option", "-p", "-t", opsPane.paneId, PANE_VERSION_OPTION, CURRENT_VERSION]);
|
|
5884
|
+
}
|
|
5885
|
+
}
|
|
5886
|
+
if (commands.length > 0)
|
|
5887
|
+
await runTmuxSequence(commands);
|
|
5888
|
+
}
|
|
5714
5889
|
function inheritedEnvPrefix() {
|
|
5715
5890
|
const parts = [];
|
|
5716
5891
|
for (const key of ["KOBE_HOME_DIR", "KOBE_DAEMON_SOCKET_PATH", "KOBE_TMUX_SOCKET"]) {
|
|
@@ -5783,6 +5958,7 @@ async function newChatTab(session, vendorOverride) {
|
|
|
5783
5958
|
if (vendorOverride)
|
|
5784
5959
|
await rememberSessionVendor(session, taskId, vendorOverride);
|
|
5785
5960
|
const command = interactiveEngineCommand(vendor);
|
|
5961
|
+
const launch = withClaudeSessionId(command, vendor);
|
|
5786
5962
|
const inv = kobeCliInvocation();
|
|
5787
5963
|
const r = await runTmuxCapturing([
|
|
5788
5964
|
"new-window",
|
|
@@ -5793,11 +5969,13 @@ async function newChatTab(session, vendorOverride) {
|
|
|
5793
5969
|
"-P",
|
|
5794
5970
|
"-F",
|
|
5795
5971
|
"#{pane_id}",
|
|
5796
|
-
keepAlive(shellQuoteArgv(
|
|
5972
|
+
keepAlive(shellQuoteArgv(launch.argv))
|
|
5797
5973
|
]);
|
|
5798
5974
|
const claudePane = r.stdout.trim();
|
|
5799
5975
|
if (!claudePane)
|
|
5800
5976
|
return;
|
|
5977
|
+
if (launch.sessionId)
|
|
5978
|
+
await setWindowOption(claudePane, CHAT_TAB_SESSION_ID_OPTION, launch.sessionId);
|
|
5801
5979
|
await buildPanesAround(claudePane, { cwd, taskId, inv, vendor });
|
|
5802
5980
|
}
|
|
5803
5981
|
async function openSettingsTab(session) {
|
|
@@ -5949,7 +6127,8 @@ function readWorktreeChanges(worktreePath) {
|
|
|
5949
6127
|
const out = spawnSync3("git", ["status", "--porcelain=v1"], {
|
|
5950
6128
|
cwd: worktreePath,
|
|
5951
6129
|
encoding: "utf8",
|
|
5952
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
6130
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
6131
|
+
env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" }
|
|
5953
6132
|
});
|
|
5954
6133
|
if (out.status !== 0 || !out.stdout)
|
|
5955
6134
|
return ZERO;
|
|
@@ -12827,6 +13006,15 @@ var init_account_detect = __esm(() => {
|
|
|
12827
13006
|
};
|
|
12828
13007
|
});
|
|
12829
13008
|
|
|
13009
|
+
// src/tui/lib/editor-prefs.ts
|
|
13010
|
+
function normalizeEditorKind(value) {
|
|
13011
|
+
return value === "nano" || value === "custom" || value === "vim" ? value : DEFAULT_EDITOR_KIND;
|
|
13012
|
+
}
|
|
13013
|
+
var EDITOR_KINDS, EDITOR_KIND_KEY = "editor.kind", EDITOR_CUSTOM_KEY = "editor.customCommand", DEFAULT_EDITOR_KIND = "vim";
|
|
13014
|
+
var init_editor_prefs = __esm(() => {
|
|
13015
|
+
EDITOR_KINDS = ["vim", "nano", "custom"];
|
|
13016
|
+
});
|
|
13017
|
+
|
|
12830
13018
|
// src/tui/lib/settings-surface.ts
|
|
12831
13019
|
function normalizeSettingsSurface(value) {
|
|
12832
13020
|
return value === "taskpanel" ? "taskpanel" : "chattab";
|
|
@@ -13015,7 +13203,7 @@ function devRowCount(hasDaemon) {
|
|
|
13015
13203
|
return hasDaemon ? 2 : 1;
|
|
13016
13204
|
}
|
|
13017
13205
|
function generalRowCount(themeCount, focusAccentCount) {
|
|
13018
|
-
return themeCount + 1 + focusAccentCount +
|
|
13206
|
+
return themeCount + 1 + focusAccentCount + 6;
|
|
13019
13207
|
}
|
|
13020
13208
|
function bodyRowCount(section, themeCount, focusAccentCount, hasDaemon) {
|
|
13021
13209
|
if (section === "general")
|
|
@@ -13050,6 +13238,12 @@ function surfaceChattabRowIndex(themeCount, focusAccentCount) {
|
|
|
13050
13238
|
function surfaceTaskpanelRowIndex(themeCount, focusAccentCount) {
|
|
13051
13239
|
return surfaceChattabRowIndex(themeCount, focusAccentCount) + 1;
|
|
13052
13240
|
}
|
|
13241
|
+
function editorKindRowIndex(themeCount, focusAccentCount) {
|
|
13242
|
+
return surfaceTaskpanelRowIndex(themeCount, focusAccentCount) + 1;
|
|
13243
|
+
}
|
|
13244
|
+
function editorCustomRowIndex(themeCount, focusAccentCount) {
|
|
13245
|
+
return editorKindRowIndex(themeCount, focusAccentCount) + 1;
|
|
13246
|
+
}
|
|
13053
13247
|
var SECTIONS, FOCUS_ACCENT_LABEL;
|
|
13054
13248
|
var init_model = __esm(() => {
|
|
13055
13249
|
init_vendor();
|
|
@@ -13118,13 +13312,17 @@ function GeneralSettingsSection(props) {
|
|
|
13118
13312
|
const soundRow = () => soundRowIndex(props.themeNames().length, FOCUS_ACCENT_SLOTS.length);
|
|
13119
13313
|
const surfaceChattabRow = () => surfaceChattabRowIndex(props.themeNames().length, FOCUS_ACCENT_SLOTS.length);
|
|
13120
13314
|
const surfaceTaskpanelRow = () => surfaceTaskpanelRowIndex(props.themeNames().length, FOCUS_ACCENT_SLOTS.length);
|
|
13315
|
+
const editorKindRow = () => editorKindRowIndex(props.themeNames().length, FOCUS_ACCENT_SLOTS.length);
|
|
13316
|
+
const editorCustomRow = () => editorCustomRowIndex(props.themeNames().length, FOCUS_ACCENT_SLOTS.length);
|
|
13121
13317
|
const isTransparentRow = () => props.bodyRow() === transparentRowIndex(props.themeNames().length);
|
|
13122
13318
|
const isToastRow = () => props.bodyRow() === toastRow();
|
|
13123
13319
|
const isSoundRow = () => props.bodyRow() === soundRow();
|
|
13124
13320
|
const isSurfaceChattabRow = () => props.bodyRow() === surfaceChattabRow();
|
|
13125
13321
|
const isSurfaceTaskpanelRow = () => props.bodyRow() === surfaceTaskpanelRow();
|
|
13322
|
+
const isEditorKindRow = () => props.bodyRow() === editorKindRow();
|
|
13323
|
+
const isEditorCustomRow = () => props.bodyRow() === editorCustomRow();
|
|
13126
13324
|
return (() => {
|
|
13127
|
-
var _el$4 = createElement("box"), _el$5 = createElement("text"), _el$7 = createElement("text"), _el$9 = createElement("box"), _el$0 = createElement("box"), _el$1 = createElement("text"), _el$11 = createElement("text"), _el$13 = createElement("box"), _el$14 = createElement("text"), _el$15 = createElement("box"), _el$16 = createElement("text"), _el$18 = createElement("text"), _el$20 = createElement("box"), _el$21 = createElement("text"), _el$23 = createElement("text"), _el$25 = createElement("box"), _el$26 = createElement("text"), _el$27 = createTextNode(` Toast`), _el$28 = createElement("box"), _el$29 = createElement("text"), _el$30 = createTextNode(` Sound`), _el$31 = createElement("box"), _el$32 = createElement("text"), _el$34 = createElement("text"), _el$36 = createElement("box"), _el$37 = createElement("text"), _el$38 = createTextNode(` ChatTab (separate page)`), _el$39 = createElement("box"), _el$40 = createElement("text"), _el$41 = createTextNode(` Task panel (in-pane overlay)`);
|
|
13325
|
+
var _el$4 = createElement("box"), _el$5 = createElement("text"), _el$7 = createElement("text"), _el$9 = createElement("box"), _el$0 = createElement("box"), _el$1 = createElement("text"), _el$11 = createElement("text"), _el$13 = createElement("box"), _el$14 = createElement("text"), _el$15 = createElement("box"), _el$16 = createElement("text"), _el$18 = createElement("text"), _el$20 = createElement("box"), _el$21 = createElement("text"), _el$23 = createElement("text"), _el$25 = createElement("box"), _el$26 = createElement("text"), _el$27 = createTextNode(` Toast`), _el$28 = createElement("box"), _el$29 = createElement("text"), _el$30 = createTextNode(` Sound`), _el$31 = createElement("box"), _el$32 = createElement("text"), _el$34 = createElement("text"), _el$36 = createElement("box"), _el$37 = createElement("text"), _el$38 = createTextNode(` ChatTab (separate page)`), _el$39 = createElement("box"), _el$40 = createElement("text"), _el$41 = createTextNode(` Task panel (in-pane overlay)`), _el$42 = createElement("box"), _el$43 = createElement("text"), _el$45 = createElement("text"), _el$47 = createElement("box"), _el$48 = createElement("text"), _el$49 = createElement("box"), _el$50 = createElement("text");
|
|
13128
13326
|
insertNode(_el$4, _el$5);
|
|
13129
13327
|
insertNode(_el$4, _el$7);
|
|
13130
13328
|
insertNode(_el$4, _el$9);
|
|
@@ -13132,6 +13330,7 @@ function GeneralSettingsSection(props) {
|
|
|
13132
13330
|
insertNode(_el$4, _el$15);
|
|
13133
13331
|
insertNode(_el$4, _el$20);
|
|
13134
13332
|
insertNode(_el$4, _el$31);
|
|
13333
|
+
insertNode(_el$4, _el$42);
|
|
13135
13334
|
setProp(_el$4, "flexDirection", "column");
|
|
13136
13335
|
setProp(_el$4, "gap", 1);
|
|
13137
13336
|
insertNode(_el$5, createTextNode(`Theme`));
|
|
@@ -13146,33 +13345,33 @@ function GeneralSettingsSection(props) {
|
|
|
13146
13345
|
const isCursor = () => props.level() === "body" && props.bodyRow() === i();
|
|
13147
13346
|
const isSelected = () => name === themeCtx.selected;
|
|
13148
13347
|
return (() => {
|
|
13149
|
-
var _el$
|
|
13150
|
-
insertNode(_el$
|
|
13151
|
-
setProp(_el$
|
|
13152
|
-
setProp(_el$
|
|
13153
|
-
setProp(_el$
|
|
13154
|
-
setProp(_el$
|
|
13155
|
-
setProp(_el$
|
|
13348
|
+
var _el$51 = createElement("box"), _el$52 = createElement("text");
|
|
13349
|
+
insertNode(_el$51, _el$52);
|
|
13350
|
+
setProp(_el$51, "flexDirection", "row");
|
|
13351
|
+
setProp(_el$51, "gap", 1);
|
|
13352
|
+
setProp(_el$51, "paddingLeft", 1);
|
|
13353
|
+
setProp(_el$51, "paddingRight", 1);
|
|
13354
|
+
setProp(_el$51, "onMouseUp", () => {
|
|
13156
13355
|
props.setLevel("body");
|
|
13157
13356
|
props.setBodyRow(i());
|
|
13158
13357
|
props.setThemeCursor(i());
|
|
13159
|
-
|
|
13358
|
+
props.selectTheme(name);
|
|
13160
13359
|
});
|
|
13161
|
-
setProp(_el$
|
|
13162
|
-
insert(_el$
|
|
13163
|
-
insert(_el$
|
|
13360
|
+
setProp(_el$52, "wrapMode", "none");
|
|
13361
|
+
insert(_el$52, () => isSelected() ? "\u25CF " : " ", null);
|
|
13362
|
+
insert(_el$52, name, null);
|
|
13164
13363
|
effect((_p$) => {
|
|
13165
|
-
var _v$
|
|
13166
|
-
_v$
|
|
13167
|
-
_v$
|
|
13168
|
-
_v$
|
|
13364
|
+
var _v$40 = isCursor() ? theme.primary : undefined, _v$41 = isCursor() ? theme.selectedListItemText : isSelected() ? theme.accent : theme.text, _v$42 = isCursor() || isSelected() ? TextAttributes5.BOLD : undefined;
|
|
13365
|
+
_v$40 !== _p$.e && (_p$.e = setProp(_el$51, "backgroundColor", _v$40, _p$.e));
|
|
13366
|
+
_v$41 !== _p$.t && (_p$.t = setProp(_el$52, "fg", _v$41, _p$.t));
|
|
13367
|
+
_v$42 !== _p$.a && (_p$.a = setProp(_el$52, "attributes", _v$42, _p$.a));
|
|
13169
13368
|
return _p$;
|
|
13170
13369
|
}, {
|
|
13171
13370
|
e: undefined,
|
|
13172
13371
|
t: undefined,
|
|
13173
13372
|
a: undefined
|
|
13174
13373
|
});
|
|
13175
|
-
return _el$
|
|
13374
|
+
return _el$51;
|
|
13176
13375
|
})();
|
|
13177
13376
|
}
|
|
13178
13377
|
}));
|
|
@@ -13192,7 +13391,7 @@ function GeneralSettingsSection(props) {
|
|
|
13192
13391
|
setProp(_el$13, "onMouseUp", () => {
|
|
13193
13392
|
props.setLevel("body");
|
|
13194
13393
|
props.setBodyRow(transparentRowIndex(props.themeNames().length));
|
|
13195
|
-
|
|
13394
|
+
props.toggleTransparent();
|
|
13196
13395
|
});
|
|
13197
13396
|
setProp(_el$14, "wrapMode", "none");
|
|
13198
13397
|
insert(_el$14, () => themeCtx.transparentBackground ? "[x] on" : "[ ] off");
|
|
@@ -13211,32 +13410,32 @@ function GeneralSettingsSection(props) {
|
|
|
13211
13410
|
const isCursor = () => props.level() === "body" && props.bodyRow() === rowIndex();
|
|
13212
13411
|
const isSelected = () => themeCtx.focusAccent === slot;
|
|
13213
13412
|
return (() => {
|
|
13214
|
-
var _el$
|
|
13215
|
-
insertNode(_el$
|
|
13216
|
-
setProp(_el$
|
|
13217
|
-
setProp(_el$
|
|
13218
|
-
setProp(_el$
|
|
13219
|
-
setProp(_el$
|
|
13220
|
-
setProp(_el$
|
|
13413
|
+
var _el$53 = createElement("box"), _el$54 = createElement("text");
|
|
13414
|
+
insertNode(_el$53, _el$54);
|
|
13415
|
+
setProp(_el$53, "flexDirection", "row");
|
|
13416
|
+
setProp(_el$53, "gap", 1);
|
|
13417
|
+
setProp(_el$53, "paddingLeft", 1);
|
|
13418
|
+
setProp(_el$53, "paddingRight", 1);
|
|
13419
|
+
setProp(_el$53, "onMouseUp", () => {
|
|
13221
13420
|
props.setLevel("body");
|
|
13222
13421
|
props.setBodyRow(rowIndex());
|
|
13223
|
-
|
|
13422
|
+
props.selectFocusAccent(slot);
|
|
13224
13423
|
});
|
|
13225
|
-
setProp(_el$
|
|
13226
|
-
insert(_el$
|
|
13227
|
-
insert(_el$
|
|
13424
|
+
setProp(_el$54, "wrapMode", "none");
|
|
13425
|
+
insert(_el$54, () => isSelected() ? "\u25CF " : " ", null);
|
|
13426
|
+
insert(_el$54, () => FOCUS_ACCENT_LABEL[slot], null);
|
|
13228
13427
|
effect((_p$) => {
|
|
13229
|
-
var _v$
|
|
13230
|
-
_v$
|
|
13231
|
-
_v$
|
|
13232
|
-
_v$
|
|
13428
|
+
var _v$43 = isCursor() ? theme.primary : undefined, _v$44 = isCursor() ? theme.selectedListItemText : isSelected() ? theme.focusAccent : theme.text, _v$45 = isCursor() || isSelected() ? TextAttributes5.BOLD : undefined;
|
|
13429
|
+
_v$43 !== _p$.e && (_p$.e = setProp(_el$53, "backgroundColor", _v$43, _p$.e));
|
|
13430
|
+
_v$44 !== _p$.t && (_p$.t = setProp(_el$54, "fg", _v$44, _p$.t));
|
|
13431
|
+
_v$45 !== _p$.a && (_p$.a = setProp(_el$54, "attributes", _v$45, _p$.a));
|
|
13233
13432
|
return _p$;
|
|
13234
13433
|
}, {
|
|
13235
13434
|
e: undefined,
|
|
13236
13435
|
t: undefined,
|
|
13237
13436
|
a: undefined
|
|
13238
13437
|
});
|
|
13239
|
-
return _el$
|
|
13438
|
+
return _el$53;
|
|
13240
13439
|
})();
|
|
13241
13440
|
}
|
|
13242
13441
|
}), null);
|
|
@@ -13312,8 +13511,42 @@ function GeneralSettingsSection(props) {
|
|
|
13312
13511
|
insertNode(_el$40, _el$41);
|
|
13313
13512
|
setProp(_el$40, "wrapMode", "none");
|
|
13314
13513
|
insert(_el$40, () => props.settingsSurface() === "taskpanel" ? "[x]" : "[ ]", _el$41);
|
|
13514
|
+
insertNode(_el$42, _el$43);
|
|
13515
|
+
insertNode(_el$42, _el$45);
|
|
13516
|
+
insertNode(_el$42, _el$47);
|
|
13517
|
+
insertNode(_el$42, _el$49);
|
|
13518
|
+
setProp(_el$42, "flexDirection", "column");
|
|
13519
|
+
setProp(_el$42, "gap", 0);
|
|
13520
|
+
setProp(_el$42, "paddingTop", 1);
|
|
13521
|
+
insertNode(_el$43, createTextNode(`Editor`));
|
|
13522
|
+
insertNode(_el$45, createTextNode(`What \`e\` opens a file with in the file tree (enter stays the read-only preview). enter on the row below cycles vim / nano / custom; if the editor isn't installed it falls back to the preview.`));
|
|
13523
|
+
setProp(_el$45, "wrapMode", "word");
|
|
13524
|
+
insertNode(_el$47, _el$48);
|
|
13525
|
+
setProp(_el$47, "flexDirection", "row");
|
|
13526
|
+
setProp(_el$47, "gap", 1);
|
|
13527
|
+
setProp(_el$47, "paddingLeft", 1);
|
|
13528
|
+
setProp(_el$47, "paddingRight", 1);
|
|
13529
|
+
setProp(_el$47, "onMouseUp", () => {
|
|
13530
|
+
props.setLevel("body");
|
|
13531
|
+
props.setBodyRow(editorKindRow());
|
|
13532
|
+
props.cycleEditorKind();
|
|
13533
|
+
});
|
|
13534
|
+
setProp(_el$48, "wrapMode", "none");
|
|
13535
|
+
insert(_el$48, () => `editor: < ${props.editorKind()} > (enter to change)`);
|
|
13536
|
+
insertNode(_el$49, _el$50);
|
|
13537
|
+
setProp(_el$49, "flexDirection", "row");
|
|
13538
|
+
setProp(_el$49, "gap", 1);
|
|
13539
|
+
setProp(_el$49, "paddingLeft", 1);
|
|
13540
|
+
setProp(_el$49, "paddingRight", 1);
|
|
13541
|
+
setProp(_el$49, "onMouseUp", () => {
|
|
13542
|
+
props.setLevel("body");
|
|
13543
|
+
props.setBodyRow(editorCustomRow());
|
|
13544
|
+
props.editEditorCustom();
|
|
13545
|
+
});
|
|
13546
|
+
setProp(_el$50, "wrapMode", "none");
|
|
13547
|
+
insert(_el$50, () => `custom: ${props.editorCustomCommand().trim() || "(unset \u2014 enter to edit)"}`);
|
|
13315
13548
|
effect((_p$) => {
|
|
13316
|
-
var _v$4 = theme.text, _v$5 = TextAttributes5.BOLD, _v$6 = theme.textMuted, _v$7 = theme.text, _v$8 = TextAttributes5.BOLD, _v$9 = theme.textMuted, _v$0 = isTransparentRow() ? theme.primary : undefined, _v$1 = isTransparentRow() ? theme.selectedListItemText : themeCtx.transparentBackground ? theme.accent : theme.textMuted, _v$10 = TextAttributes5.BOLD, _v$11 = theme.text, _v$12 = TextAttributes5.BOLD, _v$13 = theme.textMuted, _v$14 = theme.text, _v$15 = TextAttributes5.BOLD, _v$16 = theme.textMuted, _v$17 = isToastRow() ? theme.primary : undefined, _v$18 = isToastRow() ? theme.selectedListItemText : props.toastEnabled() ? theme.accent : theme.textMuted, _v$19 = TextAttributes5.BOLD, _v$20 = isSoundRow() ? theme.primary : undefined, _v$21 = isSoundRow() ? theme.selectedListItemText : props.soundEnabled() ? theme.accent : theme.textMuted, _v$22 = TextAttributes5.BOLD, _v$23 = theme.text, _v$24 = TextAttributes5.BOLD, _v$25 = theme.textMuted, _v$26 = isSurfaceChattabRow() ? theme.primary : undefined, _v$27 = isSurfaceChattabRow() ? theme.selectedListItemText : props.settingsSurface() === "chattab" ? theme.accent : theme.textMuted, _v$28 = TextAttributes5.BOLD, _v$29 = isSurfaceTaskpanelRow() ? theme.primary : undefined, _v$30 = isSurfaceTaskpanelRow() ? theme.selectedListItemText : props.settingsSurface() === "taskpanel" ? theme.accent : theme.textMuted, _v$31 = TextAttributes5.BOLD;
|
|
13549
|
+
var _v$4 = theme.text, _v$5 = TextAttributes5.BOLD, _v$6 = theme.textMuted, _v$7 = theme.text, _v$8 = TextAttributes5.BOLD, _v$9 = theme.textMuted, _v$0 = isTransparentRow() ? theme.primary : undefined, _v$1 = isTransparentRow() ? theme.selectedListItemText : themeCtx.transparentBackground ? theme.accent : theme.textMuted, _v$10 = TextAttributes5.BOLD, _v$11 = theme.text, _v$12 = TextAttributes5.BOLD, _v$13 = theme.textMuted, _v$14 = theme.text, _v$15 = TextAttributes5.BOLD, _v$16 = theme.textMuted, _v$17 = isToastRow() ? theme.primary : undefined, _v$18 = isToastRow() ? theme.selectedListItemText : props.toastEnabled() ? theme.accent : theme.textMuted, _v$19 = TextAttributes5.BOLD, _v$20 = isSoundRow() ? theme.primary : undefined, _v$21 = isSoundRow() ? theme.selectedListItemText : props.soundEnabled() ? theme.accent : theme.textMuted, _v$22 = TextAttributes5.BOLD, _v$23 = theme.text, _v$24 = TextAttributes5.BOLD, _v$25 = theme.textMuted, _v$26 = isSurfaceChattabRow() ? theme.primary : undefined, _v$27 = isSurfaceChattabRow() ? theme.selectedListItemText : props.settingsSurface() === "chattab" ? theme.accent : theme.textMuted, _v$28 = TextAttributes5.BOLD, _v$29 = isSurfaceTaskpanelRow() ? theme.primary : undefined, _v$30 = isSurfaceTaskpanelRow() ? theme.selectedListItemText : props.settingsSurface() === "taskpanel" ? theme.accent : theme.textMuted, _v$31 = TextAttributes5.BOLD, _v$32 = theme.text, _v$33 = TextAttributes5.BOLD, _v$34 = theme.textMuted, _v$35 = isEditorKindRow() ? theme.primary : undefined, _v$36 = isEditorKindRow() ? theme.selectedListItemText : theme.accent, _v$37 = TextAttributes5.BOLD, _v$38 = isEditorCustomRow() ? theme.primary : undefined, _v$39 = isEditorCustomRow() ? theme.selectedListItemText : props.editorKind() === "custom" ? theme.text : theme.textMuted;
|
|
13317
13550
|
_v$4 !== _p$.e && (_p$.e = setProp(_el$5, "fg", _v$4, _p$.e));
|
|
13318
13551
|
_v$5 !== _p$.t && (_p$.t = setProp(_el$5, "attributes", _v$5, _p$.t));
|
|
13319
13552
|
_v$6 !== _p$.a && (_p$.a = setProp(_el$7, "fg", _v$6, _p$.a));
|
|
@@ -13344,6 +13577,14 @@ function GeneralSettingsSection(props) {
|
|
|
13344
13577
|
_v$29 !== _p$.B && (_p$.B = setProp(_el$39, "backgroundColor", _v$29, _p$.B));
|
|
13345
13578
|
_v$30 !== _p$.v && (_p$.v = setProp(_el$40, "fg", _v$30, _p$.v));
|
|
13346
13579
|
_v$31 !== _p$.k && (_p$.k = setProp(_el$40, "attributes", _v$31, _p$.k));
|
|
13580
|
+
_v$32 !== _p$.x && (_p$.x = setProp(_el$43, "fg", _v$32, _p$.x));
|
|
13581
|
+
_v$33 !== _p$.j && (_p$.j = setProp(_el$43, "attributes", _v$33, _p$.j));
|
|
13582
|
+
_v$34 !== _p$.q && (_p$.q = setProp(_el$45, "fg", _v$34, _p$.q));
|
|
13583
|
+
_v$35 !== _p$.z && (_p$.z = setProp(_el$47, "backgroundColor", _v$35, _p$.z));
|
|
13584
|
+
_v$36 !== _p$.P && (_p$.P = setProp(_el$48, "fg", _v$36, _p$.P));
|
|
13585
|
+
_v$37 !== _p$.H && (_p$.H = setProp(_el$48, "attributes", _v$37, _p$.H));
|
|
13586
|
+
_v$38 !== _p$.F && (_p$.F = setProp(_el$49, "backgroundColor", _v$38, _p$.F));
|
|
13587
|
+
_v$39 !== _p$.M && (_p$.M = setProp(_el$50, "fg", _v$39, _p$.M));
|
|
13347
13588
|
return _p$;
|
|
13348
13589
|
}, {
|
|
13349
13590
|
e: undefined,
|
|
@@ -13375,7 +13616,15 @@ function GeneralSettingsSection(props) {
|
|
|
13375
13616
|
C: undefined,
|
|
13376
13617
|
B: undefined,
|
|
13377
13618
|
v: undefined,
|
|
13378
|
-
k: undefined
|
|
13619
|
+
k: undefined,
|
|
13620
|
+
x: undefined,
|
|
13621
|
+
j: undefined,
|
|
13622
|
+
q: undefined,
|
|
13623
|
+
z: undefined,
|
|
13624
|
+
P: undefined,
|
|
13625
|
+
H: undefined,
|
|
13626
|
+
F: undefined,
|
|
13627
|
+
M: undefined
|
|
13379
13628
|
});
|
|
13380
13629
|
return _el$4;
|
|
13381
13630
|
})();
|
|
@@ -13385,47 +13634,47 @@ function EngineSettingsSection(props) {
|
|
|
13385
13634
|
theme
|
|
13386
13635
|
} = useTheme();
|
|
13387
13636
|
return (() => {
|
|
13388
|
-
var _el$
|
|
13389
|
-
insertNode(_el$
|
|
13390
|
-
insertNode(_el$
|
|
13391
|
-
insertNode(_el$
|
|
13392
|
-
setProp(_el$
|
|
13393
|
-
setProp(_el$
|
|
13394
|
-
insertNode(_el$
|
|
13395
|
-
insertNode(_el$
|
|
13396
|
-
setProp(_el$
|
|
13397
|
-
setProp(_el$
|
|
13398
|
-
setProp(_el$
|
|
13399
|
-
insert(_el$
|
|
13637
|
+
var _el$55 = createElement("box"), _el$56 = createElement("text"), _el$58 = createElement("text"), _el$60 = createElement("box");
|
|
13638
|
+
insertNode(_el$55, _el$56);
|
|
13639
|
+
insertNode(_el$55, _el$58);
|
|
13640
|
+
insertNode(_el$55, _el$60);
|
|
13641
|
+
setProp(_el$55, "flexDirection", "column");
|
|
13642
|
+
setProp(_el$55, "gap", 1);
|
|
13643
|
+
insertNode(_el$56, createTextNode(`Launch command`));
|
|
13644
|
+
insertNode(_el$58, createTextNode(`The command each engine's task pane runs. Override it when your binary isn't on PATH as \`claude\` / \`codex\` (e.g. it's \`cl\`) or to pass default flags. enter to edit \xB7 takes effect on the next task enter.`));
|
|
13645
|
+
setProp(_el$58, "wrapMode", "word");
|
|
13646
|
+
setProp(_el$60, "flexDirection", "column");
|
|
13647
|
+
setProp(_el$60, "gap", 0);
|
|
13648
|
+
insert(_el$60, createComponent2(For, {
|
|
13400
13649
|
get each() {
|
|
13401
13650
|
return props.vendors;
|
|
13402
13651
|
},
|
|
13403
13652
|
children: (vendor, i) => {
|
|
13404
13653
|
const isCursor = () => props.level() === "body" && props.bodyRow() === i();
|
|
13405
13654
|
return (() => {
|
|
13406
|
-
var _el$
|
|
13407
|
-
insertNode(_el$
|
|
13408
|
-
insertNode(_el$
|
|
13409
|
-
setProp(_el$
|
|
13410
|
-
setProp(_el$
|
|
13411
|
-
setProp(_el$
|
|
13412
|
-
setProp(_el$
|
|
13413
|
-
setProp(_el$
|
|
13655
|
+
var _el$61 = createElement("box"), _el$62 = createElement("text"), _el$63 = createElement("text");
|
|
13656
|
+
insertNode(_el$61, _el$62);
|
|
13657
|
+
insertNode(_el$61, _el$63);
|
|
13658
|
+
setProp(_el$61, "flexDirection", "row");
|
|
13659
|
+
setProp(_el$61, "gap", 1);
|
|
13660
|
+
setProp(_el$61, "paddingLeft", 1);
|
|
13661
|
+
setProp(_el$61, "paddingRight", 1);
|
|
13662
|
+
setProp(_el$61, "onMouseUp", () => {
|
|
13414
13663
|
props.setLevel("body");
|
|
13415
13664
|
props.setBodyRow(i());
|
|
13416
13665
|
props.editEngine(vendor);
|
|
13417
13666
|
});
|
|
13418
|
-
setProp(_el$
|
|
13419
|
-
insert(_el$
|
|
13420
|
-
setProp(_el$
|
|
13421
|
-
insert(_el$
|
|
13422
|
-
insert(_el$
|
|
13667
|
+
setProp(_el$62, "wrapMode", "none");
|
|
13668
|
+
insert(_el$62, () => VENDOR_LABEL[vendor]);
|
|
13669
|
+
setProp(_el$63, "wrapMode", "none");
|
|
13670
|
+
insert(_el$63, () => props.commandText(vendor), null);
|
|
13671
|
+
insert(_el$63, () => props.isDefault(vendor) ? " (default)" : "", null);
|
|
13423
13672
|
effect((_p$) => {
|
|
13424
|
-
var _v$
|
|
13425
|
-
_v$
|
|
13426
|
-
_v$
|
|
13427
|
-
_v$
|
|
13428
|
-
_v$
|
|
13673
|
+
var _v$49 = isCursor() ? theme.primary : undefined, _v$50 = isCursor() ? theme.selectedListItemText : theme.text, _v$51 = TextAttributes5.BOLD, _v$52 = isCursor() ? theme.selectedListItemText : props.isDefault(vendor) ? theme.textMuted : theme.accent;
|
|
13674
|
+
_v$49 !== _p$.e && (_p$.e = setProp(_el$61, "backgroundColor", _v$49, _p$.e));
|
|
13675
|
+
_v$50 !== _p$.t && (_p$.t = setProp(_el$62, "fg", _v$50, _p$.t));
|
|
13676
|
+
_v$51 !== _p$.a && (_p$.a = setProp(_el$62, "attributes", _v$51, _p$.a));
|
|
13677
|
+
_v$52 !== _p$.o && (_p$.o = setProp(_el$63, "fg", _v$52, _p$.o));
|
|
13429
13678
|
return _p$;
|
|
13430
13679
|
}, {
|
|
13431
13680
|
e: undefined,
|
|
@@ -13433,22 +13682,22 @@ function EngineSettingsSection(props) {
|
|
|
13433
13682
|
a: undefined,
|
|
13434
13683
|
o: undefined
|
|
13435
13684
|
});
|
|
13436
|
-
return _el$
|
|
13685
|
+
return _el$61;
|
|
13437
13686
|
})();
|
|
13438
13687
|
}
|
|
13439
13688
|
}));
|
|
13440
13689
|
effect((_p$) => {
|
|
13441
|
-
var _v$
|
|
13442
|
-
_v$
|
|
13443
|
-
_v$
|
|
13444
|
-
_v$
|
|
13690
|
+
var _v$46 = theme.text, _v$47 = TextAttributes5.BOLD, _v$48 = theme.textMuted;
|
|
13691
|
+
_v$46 !== _p$.e && (_p$.e = setProp(_el$56, "fg", _v$46, _p$.e));
|
|
13692
|
+
_v$47 !== _p$.t && (_p$.t = setProp(_el$56, "attributes", _v$47, _p$.t));
|
|
13693
|
+
_v$48 !== _p$.a && (_p$.a = setProp(_el$58, "fg", _v$48, _p$.a));
|
|
13445
13694
|
return _p$;
|
|
13446
13695
|
}, {
|
|
13447
13696
|
e: undefined,
|
|
13448
13697
|
t: undefined,
|
|
13449
13698
|
a: undefined
|
|
13450
13699
|
});
|
|
13451
|
-
return _el$
|
|
13700
|
+
return _el$55;
|
|
13452
13701
|
})();
|
|
13453
13702
|
}
|
|
13454
13703
|
function AccountsSettingsSection(props) {
|
|
@@ -13457,221 +13706,221 @@ function AccountsSettingsSection(props) {
|
|
|
13457
13706
|
} = useTheme();
|
|
13458
13707
|
const binaryLine = (s) => s.binary.found ? `Binary: ${s.binary.path}` : `Binary: ${s.binary.error}`;
|
|
13459
13708
|
return (() => {
|
|
13460
|
-
var _el$
|
|
13461
|
-
insertNode(_el$
|
|
13462
|
-
insertNode(_el$
|
|
13463
|
-
insertNode(_el$
|
|
13464
|
-
insertNode(_el$
|
|
13465
|
-
insertNode(_el$
|
|
13466
|
-
setProp(_el$
|
|
13467
|
-
setProp(_el$
|
|
13468
|
-
insertNode(_el$
|
|
13469
|
-
insertNode(_el$
|
|
13470
|
-
setProp(_el$
|
|
13471
|
-
insertNode(_el$
|
|
13472
|
-
setProp(_el$
|
|
13473
|
-
setProp(_el$
|
|
13474
|
-
insertNode(_el$
|
|
13475
|
-
insert(_el$
|
|
13709
|
+
var _el$64 = createElement("box"), _el$65 = createElement("text"), _el$67 = createElement("text"), _el$69 = createElement("box"), _el$70 = createElement("text"), _el$74 = createElement("box"), _el$75 = createElement("text"), _el$79 = createElement("box"), _el$80 = createElement("text");
|
|
13710
|
+
insertNode(_el$64, _el$65);
|
|
13711
|
+
insertNode(_el$64, _el$67);
|
|
13712
|
+
insertNode(_el$64, _el$69);
|
|
13713
|
+
insertNode(_el$64, _el$74);
|
|
13714
|
+
insertNode(_el$64, _el$79);
|
|
13715
|
+
setProp(_el$64, "flexDirection", "column");
|
|
13716
|
+
setProp(_el$64, "gap", 1);
|
|
13717
|
+
insertNode(_el$65, createTextNode(`Accounts`));
|
|
13718
|
+
insertNode(_el$67, createTextNode(`Read-only view of locally-detected engine accounts. Login flows land here later.`));
|
|
13719
|
+
setProp(_el$67, "wrapMode", "word");
|
|
13720
|
+
insertNode(_el$69, _el$70);
|
|
13721
|
+
setProp(_el$69, "flexDirection", "column");
|
|
13722
|
+
setProp(_el$69, "gap", 0);
|
|
13723
|
+
insertNode(_el$70, createTextNode(`claude-code`));
|
|
13724
|
+
insert(_el$69, createComponent2(Show, {
|
|
13476
13725
|
get when() {
|
|
13477
13726
|
return props.claudeStatus() === null;
|
|
13478
13727
|
},
|
|
13479
13728
|
get children() {
|
|
13480
|
-
var _el$
|
|
13481
|
-
insertNode(_el$
|
|
13482
|
-
effect((_$p) => setProp(_el$
|
|
13483
|
-
return _el$
|
|
13729
|
+
var _el$72 = createElement("text");
|
|
13730
|
+
insertNode(_el$72, createTextNode(`Checking\u2026`));
|
|
13731
|
+
effect((_$p) => setProp(_el$72, "fg", theme.textMuted, _$p));
|
|
13732
|
+
return _el$72;
|
|
13484
13733
|
}
|
|
13485
13734
|
}), null);
|
|
13486
|
-
insert(_el$
|
|
13735
|
+
insert(_el$69, createComponent2(Show, {
|
|
13487
13736
|
get when() {
|
|
13488
13737
|
return props.claudeStatus();
|
|
13489
13738
|
},
|
|
13490
13739
|
children: (s) => (() => {
|
|
13491
|
-
var _el$
|
|
13492
|
-
insertNode(_el$
|
|
13493
|
-
setProp(_el$
|
|
13494
|
-
setProp(_el$
|
|
13495
|
-
setProp(_el$
|
|
13496
|
-
insert(_el$
|
|
13497
|
-
insert(_el$
|
|
13740
|
+
var _el$84 = createElement("box"), _el$85 = createElement("text");
|
|
13741
|
+
insertNode(_el$84, _el$85);
|
|
13742
|
+
setProp(_el$84, "flexDirection", "column");
|
|
13743
|
+
setProp(_el$84, "gap", 0);
|
|
13744
|
+
setProp(_el$85, "wrapMode", "word");
|
|
13745
|
+
insert(_el$85, () => binaryLine(s()));
|
|
13746
|
+
insert(_el$84, () => {
|
|
13498
13747
|
const a = s().account;
|
|
13499
13748
|
if (a.kind === "oauth") {
|
|
13500
13749
|
const tail = [a.organization, a.billingType].filter((x) => !!x).join(" \xB7 ");
|
|
13501
13750
|
return (() => {
|
|
13502
|
-
var _el$
|
|
13503
|
-
setProp(_el$
|
|
13504
|
-
insert(_el$
|
|
13505
|
-
effect((_$p) => setProp(_el$
|
|
13506
|
-
return _el$
|
|
13751
|
+
var _el$86 = createElement("text");
|
|
13752
|
+
setProp(_el$86, "wrapMode", "word");
|
|
13753
|
+
insert(_el$86, () => `\u25CF Logged in: ${a.email}${tail ? ` (${tail})` : ""}`);
|
|
13754
|
+
effect((_$p) => setProp(_el$86, "fg", theme.success, _$p));
|
|
13755
|
+
return _el$86;
|
|
13507
13756
|
})();
|
|
13508
13757
|
}
|
|
13509
13758
|
return (() => {
|
|
13510
|
-
var _el$
|
|
13511
|
-
insertNode(_el$
|
|
13512
|
-
effect((_$p) => setProp(_el$
|
|
13513
|
-
return _el$
|
|
13759
|
+
var _el$87 = createElement("text");
|
|
13760
|
+
insertNode(_el$87, createTextNode(`\u25CB Not logged in`));
|
|
13761
|
+
effect((_$p) => setProp(_el$87, "fg", theme.textMuted, _$p));
|
|
13762
|
+
return _el$87;
|
|
13514
13763
|
})();
|
|
13515
13764
|
}, null);
|
|
13516
|
-
insert(_el$
|
|
13765
|
+
insert(_el$84, createComponent2(Show, {
|
|
13517
13766
|
get when() {
|
|
13518
13767
|
return s().accountError;
|
|
13519
13768
|
},
|
|
13520
13769
|
children: (err) => (() => {
|
|
13521
|
-
var _el$
|
|
13522
|
-
setProp(_el$
|
|
13523
|
-
insert(_el$
|
|
13524
|
-
effect((_$p) => setProp(_el$
|
|
13525
|
-
return _el$
|
|
13770
|
+
var _el$89 = createElement("text");
|
|
13771
|
+
setProp(_el$89, "wrapMode", "word");
|
|
13772
|
+
insert(_el$89, () => `! ${err()}`);
|
|
13773
|
+
effect((_$p) => setProp(_el$89, "fg", theme.warning, _$p));
|
|
13774
|
+
return _el$89;
|
|
13526
13775
|
})()
|
|
13527
13776
|
}), null);
|
|
13528
|
-
effect((_$p) => setProp(_el$
|
|
13529
|
-
return _el$
|
|
13777
|
+
effect((_$p) => setProp(_el$85, "fg", s().binary.found ? theme.textMuted : theme.warning, _$p));
|
|
13778
|
+
return _el$84;
|
|
13530
13779
|
})()
|
|
13531
13780
|
}), null);
|
|
13532
|
-
insertNode(_el$
|
|
13533
|
-
setProp(_el$
|
|
13534
|
-
setProp(_el$
|
|
13535
|
-
insertNode(_el$
|
|
13536
|
-
insert(_el$
|
|
13781
|
+
insertNode(_el$74, _el$75);
|
|
13782
|
+
setProp(_el$74, "flexDirection", "column");
|
|
13783
|
+
setProp(_el$74, "gap", 0);
|
|
13784
|
+
insertNode(_el$75, createTextNode(`codex`));
|
|
13785
|
+
insert(_el$74, createComponent2(Show, {
|
|
13537
13786
|
get when() {
|
|
13538
13787
|
return props.codexStatus() === null;
|
|
13539
13788
|
},
|
|
13540
13789
|
get children() {
|
|
13541
|
-
var _el$
|
|
13542
|
-
insertNode(_el$
|
|
13543
|
-
effect((_$p) => setProp(_el$
|
|
13544
|
-
return _el$
|
|
13790
|
+
var _el$77 = createElement("text");
|
|
13791
|
+
insertNode(_el$77, createTextNode(`Checking\u2026`));
|
|
13792
|
+
effect((_$p) => setProp(_el$77, "fg", theme.textMuted, _$p));
|
|
13793
|
+
return _el$77;
|
|
13545
13794
|
}
|
|
13546
13795
|
}), null);
|
|
13547
|
-
insert(_el$
|
|
13796
|
+
insert(_el$74, createComponent2(Show, {
|
|
13548
13797
|
get when() {
|
|
13549
13798
|
return props.codexStatus();
|
|
13550
13799
|
},
|
|
13551
13800
|
children: (s) => (() => {
|
|
13552
|
-
var _el$
|
|
13553
|
-
insertNode(_el$
|
|
13554
|
-
setProp(_el$
|
|
13555
|
-
setProp(_el$
|
|
13556
|
-
setProp(_el$
|
|
13557
|
-
insert(_el$
|
|
13558
|
-
insert(_el$
|
|
13801
|
+
var _el$90 = createElement("box"), _el$91 = createElement("text");
|
|
13802
|
+
insertNode(_el$90, _el$91);
|
|
13803
|
+
setProp(_el$90, "flexDirection", "column");
|
|
13804
|
+
setProp(_el$90, "gap", 0);
|
|
13805
|
+
setProp(_el$91, "wrapMode", "word");
|
|
13806
|
+
insert(_el$91, () => binaryLine(s()));
|
|
13807
|
+
insert(_el$90, () => {
|
|
13559
13808
|
const a = s().account;
|
|
13560
13809
|
if (a.kind === "chatgpt") {
|
|
13561
13810
|
return (() => {
|
|
13562
|
-
var _el$
|
|
13563
|
-
setProp(_el$
|
|
13564
|
-
insert(_el$
|
|
13565
|
-
effect((_$p) => setProp(_el$
|
|
13566
|
-
return _el$
|
|
13811
|
+
var _el$92 = createElement("text");
|
|
13812
|
+
setProp(_el$92, "wrapMode", "word");
|
|
13813
|
+
insert(_el$92, () => `\u25CF ChatGPT login: ${a.email}${a.plan ? ` (${a.plan})` : ""}`);
|
|
13814
|
+
effect((_$p) => setProp(_el$92, "fg", theme.success, _$p));
|
|
13815
|
+
return _el$92;
|
|
13567
13816
|
})();
|
|
13568
13817
|
}
|
|
13569
13818
|
if (a.kind === "apikey")
|
|
13570
13819
|
return (() => {
|
|
13571
|
-
var _el$
|
|
13572
|
-
insertNode(_el$
|
|
13573
|
-
effect((_$p) => setProp(_el$
|
|
13574
|
-
return _el$
|
|
13820
|
+
var _el$93 = createElement("text");
|
|
13821
|
+
insertNode(_el$93, createTextNode(`\u25CF API key configured`));
|
|
13822
|
+
effect((_$p) => setProp(_el$93, "fg", theme.success, _$p));
|
|
13823
|
+
return _el$93;
|
|
13575
13824
|
})();
|
|
13576
13825
|
return (() => {
|
|
13577
|
-
var _el$
|
|
13578
|
-
insertNode(_el$
|
|
13579
|
-
effect((_$p) => setProp(_el$
|
|
13580
|
-
return _el$
|
|
13826
|
+
var _el$95 = createElement("text");
|
|
13827
|
+
insertNode(_el$95, createTextNode(`\u25CB Not logged in`));
|
|
13828
|
+
effect((_$p) => setProp(_el$95, "fg", theme.textMuted, _$p));
|
|
13829
|
+
return _el$95;
|
|
13581
13830
|
})();
|
|
13582
13831
|
}, null);
|
|
13583
|
-
insert(_el$
|
|
13832
|
+
insert(_el$90, createComponent2(Show, {
|
|
13584
13833
|
get when() {
|
|
13585
13834
|
return s().accountError;
|
|
13586
13835
|
},
|
|
13587
13836
|
children: (err) => (() => {
|
|
13588
|
-
var _el$
|
|
13589
|
-
setProp(_el$
|
|
13590
|
-
insert(_el$
|
|
13591
|
-
effect((_$p) => setProp(_el$
|
|
13592
|
-
return _el$
|
|
13837
|
+
var _el$97 = createElement("text");
|
|
13838
|
+
setProp(_el$97, "wrapMode", "word");
|
|
13839
|
+
insert(_el$97, () => `! ${err()}`);
|
|
13840
|
+
effect((_$p) => setProp(_el$97, "fg", theme.warning, _$p));
|
|
13841
|
+
return _el$97;
|
|
13593
13842
|
})()
|
|
13594
13843
|
}), null);
|
|
13595
|
-
effect((_$p) => setProp(_el$
|
|
13596
|
-
return _el$
|
|
13844
|
+
effect((_$p) => setProp(_el$91, "fg", s().binary.found ? theme.textMuted : theme.warning, _$p));
|
|
13845
|
+
return _el$90;
|
|
13597
13846
|
})()
|
|
13598
13847
|
}), null);
|
|
13599
|
-
insertNode(_el$
|
|
13600
|
-
setProp(_el$
|
|
13601
|
-
setProp(_el$
|
|
13602
|
-
insertNode(_el$
|
|
13603
|
-
insert(_el$
|
|
13848
|
+
insertNode(_el$79, _el$80);
|
|
13849
|
+
setProp(_el$79, "flexDirection", "column");
|
|
13850
|
+
setProp(_el$79, "gap", 0);
|
|
13851
|
+
insertNode(_el$80, createTextNode(`copilot`));
|
|
13852
|
+
insert(_el$79, createComponent2(Show, {
|
|
13604
13853
|
get when() {
|
|
13605
13854
|
return props.copilotStatus() === null;
|
|
13606
13855
|
},
|
|
13607
13856
|
get children() {
|
|
13608
|
-
var _el$
|
|
13609
|
-
insertNode(_el$
|
|
13610
|
-
effect((_$p) => setProp(_el$
|
|
13611
|
-
return _el$
|
|
13857
|
+
var _el$82 = createElement("text");
|
|
13858
|
+
insertNode(_el$82, createTextNode(`Checking\u2026`));
|
|
13859
|
+
effect((_$p) => setProp(_el$82, "fg", theme.textMuted, _$p));
|
|
13860
|
+
return _el$82;
|
|
13612
13861
|
}
|
|
13613
13862
|
}), null);
|
|
13614
|
-
insert(_el$
|
|
13863
|
+
insert(_el$79, createComponent2(Show, {
|
|
13615
13864
|
get when() {
|
|
13616
13865
|
return props.copilotStatus();
|
|
13617
13866
|
},
|
|
13618
13867
|
children: (s) => (() => {
|
|
13619
|
-
var _el$
|
|
13620
|
-
insertNode(_el$
|
|
13621
|
-
setProp(_el$
|
|
13622
|
-
setProp(_el$
|
|
13623
|
-
setProp(_el$
|
|
13624
|
-
insert(_el$
|
|
13625
|
-
insert(_el$
|
|
13868
|
+
var _el$98 = createElement("box"), _el$99 = createElement("text");
|
|
13869
|
+
insertNode(_el$98, _el$99);
|
|
13870
|
+
setProp(_el$98, "flexDirection", "column");
|
|
13871
|
+
setProp(_el$98, "gap", 0);
|
|
13872
|
+
setProp(_el$99, "wrapMode", "word");
|
|
13873
|
+
insert(_el$99, () => binaryLine(s()));
|
|
13874
|
+
insert(_el$98, () => {
|
|
13626
13875
|
const a = s().account;
|
|
13627
13876
|
if (a.kind === "token")
|
|
13628
13877
|
return (() => {
|
|
13629
|
-
var _el$
|
|
13630
|
-
insert(_el$
|
|
13631
|
-
effect((_$p) => setProp(_el$
|
|
13632
|
-
return _el$
|
|
13878
|
+
var _el$100 = createElement("text");
|
|
13879
|
+
insert(_el$100, () => `\u25CF Token configured (${a.source})`);
|
|
13880
|
+
effect((_$p) => setProp(_el$100, "fg", theme.success, _$p));
|
|
13881
|
+
return _el$100;
|
|
13633
13882
|
})();
|
|
13634
13883
|
if (a.kind === "oauth")
|
|
13635
13884
|
return (() => {
|
|
13636
|
-
var _el$
|
|
13637
|
-
insertNode(_el$
|
|
13638
|
-
effect((_$p) => setProp(_el$
|
|
13639
|
-
return _el$
|
|
13885
|
+
var _el$101 = createElement("text");
|
|
13886
|
+
insertNode(_el$101, createTextNode(`\u25CF Copilot login detected`));
|
|
13887
|
+
effect((_$p) => setProp(_el$101, "fg", theme.success, _$p));
|
|
13888
|
+
return _el$101;
|
|
13640
13889
|
})();
|
|
13641
13890
|
return (() => {
|
|
13642
|
-
var _el$
|
|
13643
|
-
insertNode(_el$
|
|
13644
|
-
effect((_$p) => setProp(_el$
|
|
13645
|
-
return _el$
|
|
13891
|
+
var _el$103 = createElement("text");
|
|
13892
|
+
insertNode(_el$103, createTextNode(`\u25CB Not logged in`));
|
|
13893
|
+
effect((_$p) => setProp(_el$103, "fg", theme.textMuted, _$p));
|
|
13894
|
+
return _el$103;
|
|
13646
13895
|
})();
|
|
13647
13896
|
}, null);
|
|
13648
|
-
insert(_el$
|
|
13897
|
+
insert(_el$98, createComponent2(Show, {
|
|
13649
13898
|
get when() {
|
|
13650
13899
|
return s().accountError;
|
|
13651
13900
|
},
|
|
13652
13901
|
children: (err) => (() => {
|
|
13653
|
-
var _el$
|
|
13654
|
-
setProp(_el$
|
|
13655
|
-
insert(_el$
|
|
13656
|
-
effect((_$p) => setProp(_el$
|
|
13657
|
-
return _el$
|
|
13902
|
+
var _el$105 = createElement("text");
|
|
13903
|
+
setProp(_el$105, "wrapMode", "word");
|
|
13904
|
+
insert(_el$105, () => `! ${err()}`);
|
|
13905
|
+
effect((_$p) => setProp(_el$105, "fg", theme.warning, _$p));
|
|
13906
|
+
return _el$105;
|
|
13658
13907
|
})()
|
|
13659
13908
|
}), null);
|
|
13660
|
-
effect((_$p) => setProp(_el$
|
|
13661
|
-
return _el$
|
|
13909
|
+
effect((_$p) => setProp(_el$99, "fg", s().binary.found ? theme.textMuted : theme.warning, _$p));
|
|
13910
|
+
return _el$98;
|
|
13662
13911
|
})()
|
|
13663
13912
|
}), null);
|
|
13664
13913
|
effect((_p$) => {
|
|
13665
|
-
var _v$
|
|
13666
|
-
_v$
|
|
13667
|
-
_v$
|
|
13668
|
-
_v$
|
|
13669
|
-
_v$
|
|
13670
|
-
_v$
|
|
13671
|
-
_v$
|
|
13672
|
-
_v$
|
|
13673
|
-
_v$
|
|
13674
|
-
_v$
|
|
13914
|
+
var _v$53 = theme.text, _v$54 = TextAttributes5.BOLD, _v$55 = theme.textMuted, _v$56 = theme.text, _v$57 = TextAttributes5.BOLD, _v$58 = theme.text, _v$59 = TextAttributes5.BOLD, _v$60 = theme.text, _v$61 = TextAttributes5.BOLD;
|
|
13915
|
+
_v$53 !== _p$.e && (_p$.e = setProp(_el$65, "fg", _v$53, _p$.e));
|
|
13916
|
+
_v$54 !== _p$.t && (_p$.t = setProp(_el$65, "attributes", _v$54, _p$.t));
|
|
13917
|
+
_v$55 !== _p$.a && (_p$.a = setProp(_el$67, "fg", _v$55, _p$.a));
|
|
13918
|
+
_v$56 !== _p$.o && (_p$.o = setProp(_el$70, "fg", _v$56, _p$.o));
|
|
13919
|
+
_v$57 !== _p$.i && (_p$.i = setProp(_el$70, "attributes", _v$57, _p$.i));
|
|
13920
|
+
_v$58 !== _p$.n && (_p$.n = setProp(_el$75, "fg", _v$58, _p$.n));
|
|
13921
|
+
_v$59 !== _p$.s && (_p$.s = setProp(_el$75, "attributes", _v$59, _p$.s));
|
|
13922
|
+
_v$60 !== _p$.h && (_p$.h = setProp(_el$80, "fg", _v$60, _p$.h));
|
|
13923
|
+
_v$61 !== _p$.r && (_p$.r = setProp(_el$80, "attributes", _v$61, _p$.r));
|
|
13675
13924
|
return _p$;
|
|
13676
13925
|
}, {
|
|
13677
13926
|
e: undefined,
|
|
@@ -13684,7 +13933,7 @@ function AccountsSettingsSection(props) {
|
|
|
13684
13933
|
h: undefined,
|
|
13685
13934
|
r: undefined
|
|
13686
13935
|
});
|
|
13687
|
-
return _el$
|
|
13936
|
+
return _el$64;
|
|
13688
13937
|
})();
|
|
13689
13938
|
}
|
|
13690
13939
|
function DevSettingsSection(props) {
|
|
@@ -13694,58 +13943,58 @@ function DevSettingsSection(props) {
|
|
|
13694
13943
|
const resetIsCursor = () => props.level() === "body" && props.bodyRow() === 0;
|
|
13695
13944
|
const restartIsCursor = () => props.level() === "body" && props.bodyRow() === 1;
|
|
13696
13945
|
return (() => {
|
|
13697
|
-
var _el$
|
|
13698
|
-
insertNode(_el$
|
|
13699
|
-
insertNode(_el$
|
|
13700
|
-
insertNode(_el$
|
|
13701
|
-
setProp(_el$
|
|
13702
|
-
setProp(_el$
|
|
13703
|
-
insertNode(_el$
|
|
13704
|
-
insertNode(_el$
|
|
13705
|
-
setProp(_el$
|
|
13706
|
-
insertNode(_el$
|
|
13707
|
-
setProp(_el$
|
|
13708
|
-
setProp(_el$
|
|
13709
|
-
setProp(_el$
|
|
13710
|
-
setProp(_el$
|
|
13946
|
+
var _el$106 = createElement("box"), _el$107 = createElement("text"), _el$109 = createElement("text"), _el$111 = createElement("box"), _el$112 = createElement("text");
|
|
13947
|
+
insertNode(_el$106, _el$107);
|
|
13948
|
+
insertNode(_el$106, _el$109);
|
|
13949
|
+
insertNode(_el$106, _el$111);
|
|
13950
|
+
setProp(_el$106, "flexDirection", "column");
|
|
13951
|
+
setProp(_el$106, "gap", 1);
|
|
13952
|
+
insertNode(_el$107, createTextNode(`Reset UI state`));
|
|
13953
|
+
insertNode(_el$109, createTextNode(`Clears ~/.config/kobe/state.json and ~/.kobe/tasks.json, then quits kobe \u2014 relaunch to start fresh. Working session / Archive lists, pane sizes, theme, model picks all reset. Worktrees on disk and Claude Code session history are not touched.`));
|
|
13954
|
+
setProp(_el$109, "wrapMode", "word");
|
|
13955
|
+
insertNode(_el$111, _el$112);
|
|
13956
|
+
setProp(_el$111, "flexDirection", "row");
|
|
13957
|
+
setProp(_el$111, "paddingLeft", 1);
|
|
13958
|
+
setProp(_el$111, "paddingRight", 1);
|
|
13959
|
+
setProp(_el$111, "onMouseUp", () => {
|
|
13711
13960
|
props.setLevel("body");
|
|
13712
13961
|
props.setBodyRow(0);
|
|
13713
13962
|
props.confirmReset();
|
|
13714
13963
|
});
|
|
13715
|
-
insertNode(_el$
|
|
13716
|
-
insert(_el$
|
|
13964
|
+
insertNode(_el$112, createTextNode(`[enter] Reset`));
|
|
13965
|
+
insert(_el$106, createComponent2(Show, {
|
|
13717
13966
|
get when() {
|
|
13718
13967
|
return props.hasDaemon;
|
|
13719
13968
|
},
|
|
13720
13969
|
get children() {
|
|
13721
|
-
var _el$
|
|
13722
|
-
insertNode(_el$
|
|
13723
|
-
insertNode(_el$
|
|
13724
|
-
insertNode(_el$
|
|
13725
|
-
setProp(_el$
|
|
13726
|
-
setProp(_el$
|
|
13727
|
-
setProp(_el$
|
|
13728
|
-
insertNode(_el$
|
|
13729
|
-
insertNode(_el$
|
|
13730
|
-
setProp(_el$
|
|
13731
|
-
insertNode(_el$
|
|
13732
|
-
setProp(_el$
|
|
13733
|
-
setProp(_el$
|
|
13734
|
-
setProp(_el$
|
|
13735
|
-
setProp(_el$
|
|
13970
|
+
var _el$114 = createElement("box"), _el$115 = createElement("text"), _el$117 = createElement("text"), _el$119 = createElement("box"), _el$120 = createElement("text");
|
|
13971
|
+
insertNode(_el$114, _el$115);
|
|
13972
|
+
insertNode(_el$114, _el$117);
|
|
13973
|
+
insertNode(_el$114, _el$119);
|
|
13974
|
+
setProp(_el$114, "flexDirection", "column");
|
|
13975
|
+
setProp(_el$114, "gap", 0);
|
|
13976
|
+
setProp(_el$114, "paddingTop", 1);
|
|
13977
|
+
insertNode(_el$115, createTextNode(`Restart backend`));
|
|
13978
|
+
insertNode(_el$117, createTextNode(`Stops the kobe daemon and quits this kobe window so the next launch spawns a fresh daemon \u2014 picks up daemon / orchestrator / engine edits without a process kill. Other attached kobe windows will lose their connection too.`));
|
|
13979
|
+
setProp(_el$117, "wrapMode", "word");
|
|
13980
|
+
insertNode(_el$119, _el$120);
|
|
13981
|
+
setProp(_el$119, "flexDirection", "row");
|
|
13982
|
+
setProp(_el$119, "paddingLeft", 1);
|
|
13983
|
+
setProp(_el$119, "paddingRight", 1);
|
|
13984
|
+
setProp(_el$119, "onMouseUp", () => {
|
|
13736
13985
|
props.setLevel("body");
|
|
13737
13986
|
props.setBodyRow(1);
|
|
13738
13987
|
props.confirmRestartDaemon();
|
|
13739
13988
|
});
|
|
13740
|
-
insertNode(_el$
|
|
13989
|
+
insertNode(_el$120, createTextNode(`[enter] Restart`));
|
|
13741
13990
|
effect((_p$) => {
|
|
13742
|
-
var _v$
|
|
13743
|
-
_v$
|
|
13744
|
-
_v$
|
|
13745
|
-
_v$
|
|
13746
|
-
_v$
|
|
13747
|
-
_v$
|
|
13748
|
-
_v$
|
|
13991
|
+
var _v$62 = theme.text, _v$63 = TextAttributes5.BOLD, _v$64 = theme.textMuted, _v$65 = restartIsCursor() ? theme.primary : theme.backgroundElement, _v$66 = restartIsCursor() ? theme.selectedListItemText : theme.accent, _v$67 = TextAttributes5.BOLD;
|
|
13992
|
+
_v$62 !== _p$.e && (_p$.e = setProp(_el$115, "fg", _v$62, _p$.e));
|
|
13993
|
+
_v$63 !== _p$.t && (_p$.t = setProp(_el$115, "attributes", _v$63, _p$.t));
|
|
13994
|
+
_v$64 !== _p$.a && (_p$.a = setProp(_el$117, "fg", _v$64, _p$.a));
|
|
13995
|
+
_v$65 !== _p$.o && (_p$.o = setProp(_el$119, "backgroundColor", _v$65, _p$.o));
|
|
13996
|
+
_v$66 !== _p$.i && (_p$.i = setProp(_el$120, "fg", _v$66, _p$.i));
|
|
13997
|
+
_v$67 !== _p$.n && (_p$.n = setProp(_el$120, "attributes", _v$67, _p$.n));
|
|
13749
13998
|
return _p$;
|
|
13750
13999
|
}, {
|
|
13751
14000
|
e: undefined,
|
|
@@ -13755,17 +14004,17 @@ function DevSettingsSection(props) {
|
|
|
13755
14004
|
i: undefined,
|
|
13756
14005
|
n: undefined
|
|
13757
14006
|
});
|
|
13758
|
-
return _el$
|
|
14007
|
+
return _el$114;
|
|
13759
14008
|
}
|
|
13760
14009
|
}), null);
|
|
13761
14010
|
effect((_p$) => {
|
|
13762
|
-
var _v$
|
|
13763
|
-
_v$
|
|
13764
|
-
_v$
|
|
13765
|
-
_v$
|
|
13766
|
-
_v$
|
|
13767
|
-
_v$
|
|
13768
|
-
_v$
|
|
14011
|
+
var _v$68 = theme.text, _v$69 = TextAttributes5.BOLD, _v$70 = theme.textMuted, _v$71 = resetIsCursor() ? theme.primary : theme.backgroundElement, _v$72 = resetIsCursor() ? theme.selectedListItemText : theme.warning, _v$73 = TextAttributes5.BOLD;
|
|
14012
|
+
_v$68 !== _p$.e && (_p$.e = setProp(_el$107, "fg", _v$68, _p$.e));
|
|
14013
|
+
_v$69 !== _p$.t && (_p$.t = setProp(_el$107, "attributes", _v$69, _p$.t));
|
|
14014
|
+
_v$70 !== _p$.a && (_p$.a = setProp(_el$109, "fg", _v$70, _p$.a));
|
|
14015
|
+
_v$71 !== _p$.o && (_p$.o = setProp(_el$111, "backgroundColor", _v$71, _p$.o));
|
|
14016
|
+
_v$72 !== _p$.i && (_p$.i = setProp(_el$112, "fg", _v$72, _p$.i));
|
|
14017
|
+
_v$73 !== _p$.n && (_p$.n = setProp(_el$112, "attributes", _v$73, _p$.n));
|
|
13769
14018
|
return _p$;
|
|
13770
14019
|
}, {
|
|
13771
14020
|
e: undefined,
|
|
@@ -13775,7 +14024,7 @@ function DevSettingsSection(props) {
|
|
|
13775
14024
|
i: undefined,
|
|
13776
14025
|
n: undefined
|
|
13777
14026
|
});
|
|
13778
|
-
return _el$
|
|
14027
|
+
return _el$106;
|
|
13779
14028
|
})();
|
|
13780
14029
|
}
|
|
13781
14030
|
var init_sections = __esm(() => {
|
|
@@ -13844,9 +14093,40 @@ function SettingsDialog(props) {
|
|
|
13844
14093
|
function isSurfaceTaskpanelRow() {
|
|
13845
14094
|
return section() === "general" && bodyRow() === surfaceTaskpanelRowIndex(themeNames().length, FOCUS_ACCENT_SLOTS.length);
|
|
13846
14095
|
}
|
|
14096
|
+
function isEditorKindRow() {
|
|
14097
|
+
return section() === "general" && bodyRow() === editorKindRowIndex(themeNames().length, FOCUS_ACCENT_SLOTS.length);
|
|
14098
|
+
}
|
|
14099
|
+
function isEditorCustomRow() {
|
|
14100
|
+
return section() === "general" && bodyRow() === editorCustomRowIndex(themeNames().length, FOCUS_ACCENT_SLOTS.length);
|
|
14101
|
+
}
|
|
13847
14102
|
function settingsSurface() {
|
|
13848
14103
|
return normalizeSettingsSurface(props.kv.get(SETTINGS_SURFACE_KEY, DEFAULT_SETTINGS_SURFACE));
|
|
13849
14104
|
}
|
|
14105
|
+
function selectTheme(name) {
|
|
14106
|
+
if (themeCtx.selected === name)
|
|
14107
|
+
return;
|
|
14108
|
+
if (!themeCtx.set(name))
|
|
14109
|
+
return;
|
|
14110
|
+
props.kv.set("activeTheme", name);
|
|
14111
|
+
props.onVisualPrefsChange?.();
|
|
14112
|
+
}
|
|
14113
|
+
function setTransparentBackground(next) {
|
|
14114
|
+
if (themeCtx.transparentBackground === next)
|
|
14115
|
+
return;
|
|
14116
|
+
themeCtx.setTransparentBackground(next);
|
|
14117
|
+
props.kv.set("transparentBackground", next);
|
|
14118
|
+
props.onVisualPrefsChange?.();
|
|
14119
|
+
}
|
|
14120
|
+
function toggleTransparent() {
|
|
14121
|
+
setTransparentBackground(!themeCtx.transparentBackground);
|
|
14122
|
+
}
|
|
14123
|
+
function selectFocusAccent(slot) {
|
|
14124
|
+
if (themeCtx.focusAccent === slot)
|
|
14125
|
+
return;
|
|
14126
|
+
themeCtx.setFocusAccent(slot);
|
|
14127
|
+
props.kv.set("focusAccent", slot);
|
|
14128
|
+
props.onVisualPrefsChange?.();
|
|
14129
|
+
}
|
|
13850
14130
|
function selectSurface(surface) {
|
|
13851
14131
|
props.kv.set(SETTINGS_SURFACE_KEY, surface);
|
|
13852
14132
|
}
|
|
@@ -13880,6 +14160,30 @@ function SettingsDialog(props) {
|
|
|
13880
14160
|
return;
|
|
13881
14161
|
props.kv.set(engineCommandKey(vendor), next.trim());
|
|
13882
14162
|
}
|
|
14163
|
+
function editorKind() {
|
|
14164
|
+
return normalizeEditorKind(props.kv.get(EDITOR_KIND_KEY, DEFAULT_EDITOR_KIND));
|
|
14165
|
+
}
|
|
14166
|
+
function cycleEditorKind() {
|
|
14167
|
+
const i = EDITOR_KINDS.indexOf(editorKind());
|
|
14168
|
+
const next = EDITOR_KINDS[(i + 1) % EDITOR_KINDS.length];
|
|
14169
|
+
if (next)
|
|
14170
|
+
props.kv.set(EDITOR_KIND_KEY, next);
|
|
14171
|
+
}
|
|
14172
|
+
function editorCustomCommand() {
|
|
14173
|
+
const v = props.kv.get(EDITOR_CUSTOM_KEY, "");
|
|
14174
|
+
return typeof v === "string" ? v : "";
|
|
14175
|
+
}
|
|
14176
|
+
async function editEditorCustom() {
|
|
14177
|
+
const next = await RenameTaskDialog.show(dialog, editorCustomCommand(), {
|
|
14178
|
+
dialogTitle: "Custom editor command (use {file} for the path)"
|
|
14179
|
+
});
|
|
14180
|
+
if (next === undefined)
|
|
14181
|
+
return;
|
|
14182
|
+
const cmd = next.trim();
|
|
14183
|
+
props.kv.set(EDITOR_CUSTOM_KEY, cmd);
|
|
14184
|
+
if (cmd)
|
|
14185
|
+
props.kv.set(EDITOR_KIND_KEY, "custom");
|
|
14186
|
+
}
|
|
13883
14187
|
function enterBody() {
|
|
13884
14188
|
if (level() !== "sidebar" || bodyRowCount2() === 0)
|
|
13885
14189
|
return;
|
|
@@ -13916,14 +14220,14 @@ function SettingsDialog(props) {
|
|
|
13916
14220
|
function activateBodyRow() {
|
|
13917
14221
|
if (section() === "general") {
|
|
13918
14222
|
if (isTransparentRow()) {
|
|
13919
|
-
|
|
14223
|
+
toggleTransparent();
|
|
13920
14224
|
return;
|
|
13921
14225
|
}
|
|
13922
14226
|
const focusIdx = currentFocusAccentRow();
|
|
13923
14227
|
if (focusIdx !== null) {
|
|
13924
14228
|
const slot = FOCUS_ACCENT_SLOTS[focusIdx];
|
|
13925
14229
|
if (slot)
|
|
13926
|
-
|
|
14230
|
+
selectFocusAccent(slot);
|
|
13927
14231
|
return;
|
|
13928
14232
|
}
|
|
13929
14233
|
if (isToastRow()) {
|
|
@@ -13942,9 +14246,17 @@ function SettingsDialog(props) {
|
|
|
13942
14246
|
selectSurface("taskpanel");
|
|
13943
14247
|
return;
|
|
13944
14248
|
}
|
|
14249
|
+
if (isEditorKindRow()) {
|
|
14250
|
+
cycleEditorKind();
|
|
14251
|
+
return;
|
|
14252
|
+
}
|
|
14253
|
+
if (isEditorCustomRow()) {
|
|
14254
|
+
editEditorCustom();
|
|
14255
|
+
return;
|
|
14256
|
+
}
|
|
13945
14257
|
const name = themeNames()[bodyRow()];
|
|
13946
14258
|
if (name)
|
|
13947
|
-
|
|
14259
|
+
selectTheme(name);
|
|
13948
14260
|
return;
|
|
13949
14261
|
}
|
|
13950
14262
|
if (section() === "engines") {
|
|
@@ -13961,6 +14273,7 @@ function SettingsDialog(props) {
|
|
|
13961
14273
|
}
|
|
13962
14274
|
}
|
|
13963
14275
|
useBindings(() => ({
|
|
14276
|
+
enabled: !props.standalone || dialog.stack.length === 0,
|
|
13964
14277
|
bindings: [{
|
|
13965
14278
|
key: "down",
|
|
13966
14279
|
cmd: () => moveCursor(1)
|
|
@@ -13999,7 +14312,7 @@ function SettingsDialog(props) {
|
|
|
13999
14312
|
}
|
|
14000
14313
|
}, {
|
|
14001
14314
|
key: "t",
|
|
14002
|
-
cmd:
|
|
14315
|
+
cmd: toggleTransparent
|
|
14003
14316
|
}]
|
|
14004
14317
|
}));
|
|
14005
14318
|
return (() => {
|
|
@@ -14042,12 +14355,19 @@ function SettingsDialog(props) {
|
|
|
14042
14355
|
setBodyRow,
|
|
14043
14356
|
themeNames,
|
|
14044
14357
|
setThemeCursor,
|
|
14358
|
+
selectTheme,
|
|
14359
|
+
toggleTransparent,
|
|
14360
|
+
selectFocusAccent,
|
|
14045
14361
|
toastEnabled,
|
|
14046
14362
|
soundEnabled,
|
|
14047
14363
|
toggleToast,
|
|
14048
14364
|
toggleSound,
|
|
14049
14365
|
settingsSurface,
|
|
14050
|
-
selectSurface
|
|
14366
|
+
selectSurface,
|
|
14367
|
+
editorKind,
|
|
14368
|
+
cycleEditorKind,
|
|
14369
|
+
editorCustomCommand,
|
|
14370
|
+
editEditorCustom: () => void editEditorCustom()
|
|
14051
14371
|
});
|
|
14052
14372
|
}
|
|
14053
14373
|
}), null);
|
|
@@ -14129,6 +14449,7 @@ var init_settings_dialog = __esm(() => {
|
|
|
14129
14449
|
init_interactive_command();
|
|
14130
14450
|
init_vendor();
|
|
14131
14451
|
init_theme2();
|
|
14452
|
+
init_editor_prefs();
|
|
14132
14453
|
init_keymap();
|
|
14133
14454
|
init_dialog();
|
|
14134
14455
|
init_rename_task_dialog();
|
|
@@ -14136,12 +14457,20 @@ var init_settings_dialog = __esm(() => {
|
|
|
14136
14457
|
init_model();
|
|
14137
14458
|
init_sections();
|
|
14138
14459
|
SettingsDialog.show = (dialog, kv, orchestrator) => {
|
|
14460
|
+
let visualPrefsChanged = false;
|
|
14139
14461
|
return new Promise((resolve6) => {
|
|
14140
14462
|
dialog.replace(() => createComponent2(SettingsDialog, {
|
|
14141
14463
|
kv,
|
|
14142
14464
|
orchestrator,
|
|
14143
|
-
|
|
14144
|
-
|
|
14465
|
+
onVisualPrefsChange: () => {
|
|
14466
|
+
visualPrefsChanged = true;
|
|
14467
|
+
},
|
|
14468
|
+
onClose: () => resolve6({
|
|
14469
|
+
visualPrefsChanged
|
|
14470
|
+
})
|
|
14471
|
+
}), () => resolve6({
|
|
14472
|
+
visualPrefsChanged
|
|
14473
|
+
}));
|
|
14145
14474
|
});
|
|
14146
14475
|
};
|
|
14147
14476
|
});
|
|
@@ -14234,22 +14563,27 @@ var init_kv = __esm(() => {
|
|
|
14234
14563
|
init: () => {
|
|
14235
14564
|
const [store2, setStore2] = createStore(loadInitial());
|
|
14236
14565
|
let writeTimer = null;
|
|
14566
|
+
function writeNow(label) {
|
|
14567
|
+
const statePath2 = kvStatePath();
|
|
14568
|
+
try {
|
|
14569
|
+
mkdirSync4(dirname5(statePath2), {
|
|
14570
|
+
recursive: true
|
|
14571
|
+
});
|
|
14572
|
+
const tmp = `${statePath2}.tmp`;
|
|
14573
|
+
writeFileSync3(tmp, JSON.stringify(store2, null, 2), "utf8");
|
|
14574
|
+
renameSync2(tmp, statePath2);
|
|
14575
|
+
return true;
|
|
14576
|
+
} catch (err) {
|
|
14577
|
+
console.error(`[kobe] kv ${label} failed:`, err);
|
|
14578
|
+
return false;
|
|
14579
|
+
}
|
|
14580
|
+
}
|
|
14237
14581
|
function scheduleWrite() {
|
|
14238
14582
|
if (writeTimer)
|
|
14239
14583
|
clearTimeout(writeTimer);
|
|
14240
14584
|
writeTimer = setTimeout(() => {
|
|
14241
14585
|
writeTimer = null;
|
|
14242
|
-
|
|
14243
|
-
try {
|
|
14244
|
-
mkdirSync4(dirname5(statePath2), {
|
|
14245
|
-
recursive: true
|
|
14246
|
-
});
|
|
14247
|
-
const tmp = `${statePath2}.tmp`;
|
|
14248
|
-
writeFileSync3(tmp, JSON.stringify(store2, null, 2), "utf8");
|
|
14249
|
-
renameSync2(tmp, statePath2);
|
|
14250
|
-
} catch (err) {
|
|
14251
|
-
console.error("[kobe] kv write failed:", err);
|
|
14252
|
-
}
|
|
14586
|
+
writeNow("write");
|
|
14253
14587
|
}, WRITE_DEBOUNCE_MS);
|
|
14254
14588
|
}
|
|
14255
14589
|
const result = {
|
|
@@ -14271,6 +14605,13 @@ var init_kv = __esm(() => {
|
|
|
14271
14605
|
setStore2(key, value);
|
|
14272
14606
|
scheduleWrite();
|
|
14273
14607
|
},
|
|
14608
|
+
flush() {
|
|
14609
|
+
if (writeTimer) {
|
|
14610
|
+
clearTimeout(writeTimer);
|
|
14611
|
+
writeTimer = null;
|
|
14612
|
+
}
|
|
14613
|
+
return writeNow("flush");
|
|
14614
|
+
},
|
|
14274
14615
|
clear() {
|
|
14275
14616
|
for (const k of Object.keys(store2))
|
|
14276
14617
|
setStore2(k, undefined);
|
|
@@ -14422,36 +14763,6 @@ var init_worktree_opener = __esm(() => {
|
|
|
14422
14763
|
];
|
|
14423
14764
|
});
|
|
14424
14765
|
|
|
14425
|
-
// src/tui/panes/sidebar/git-head.ts
|
|
14426
|
-
import { spawnSync as spawnSync8 } from "child_process";
|
|
14427
|
-
function readCurrentBranch(repo) {
|
|
14428
|
-
if (!repo)
|
|
14429
|
-
return "";
|
|
14430
|
-
try {
|
|
14431
|
-
const out = spawnSync8("git", ["symbolic-ref", "--short", "HEAD"], {
|
|
14432
|
-
cwd: repo,
|
|
14433
|
-
encoding: "utf8",
|
|
14434
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
14435
|
-
});
|
|
14436
|
-
if (out.status === 0 && out.stdout) {
|
|
14437
|
-
const name = out.stdout.trim();
|
|
14438
|
-
if (name && name !== "HEAD")
|
|
14439
|
-
return name;
|
|
14440
|
-
}
|
|
14441
|
-
const head = spawnSync8("git", ["rev-parse", "--verify", "HEAD"], {
|
|
14442
|
-
cwd: repo,
|
|
14443
|
-
encoding: "utf8",
|
|
14444
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
14445
|
-
});
|
|
14446
|
-
if (head.status === 0)
|
|
14447
|
-
return "(detached)";
|
|
14448
|
-
return "";
|
|
14449
|
-
} catch {
|
|
14450
|
-
return "";
|
|
14451
|
-
}
|
|
14452
|
-
}
|
|
14453
|
-
var init_git_head = () => {};
|
|
14454
|
-
|
|
14455
14766
|
// src/tui/panes/sidebar/fuzzy.ts
|
|
14456
14767
|
function fuzzyMatch(query, haystack) {
|
|
14457
14768
|
if (!query)
|
|
@@ -15079,8 +15390,16 @@ var init_keybindings = __esm(() => {
|
|
|
15079
15390
|
scope: "files",
|
|
15080
15391
|
keys: ["return"],
|
|
15081
15392
|
category: "Files",
|
|
15082
|
-
description: "Open file",
|
|
15083
|
-
hint: { keys: "enter", label: "
|
|
15393
|
+
description: "Open file read-only preview",
|
|
15394
|
+
hint: { keys: "enter", label: "preview" }
|
|
15395
|
+
},
|
|
15396
|
+
{
|
|
15397
|
+
id: "files.edit",
|
|
15398
|
+
scope: "files",
|
|
15399
|
+
keys: ["e"],
|
|
15400
|
+
category: "Files",
|
|
15401
|
+
description: "Open file in the configured editor (vim / nano / custom)",
|
|
15402
|
+
hint: { keys: "e", label: "edit" }
|
|
15084
15403
|
},
|
|
15085
15404
|
{
|
|
15086
15405
|
id: "files.tab",
|
|
@@ -15362,6 +15681,13 @@ function truncatePathTail(path11, max) {
|
|
|
15362
15681
|
return path11;
|
|
15363
15682
|
return `\u2026${path11.slice(path11.length - Math.max(0, max - 1))}`;
|
|
15364
15683
|
}
|
|
15684
|
+
function abbrevHome(path11) {
|
|
15685
|
+
const home = process.env.HOME;
|
|
15686
|
+
if (home && (path11 === home || path11.startsWith(`${home}/`))) {
|
|
15687
|
+
return `~${path11.slice(home.length)}`;
|
|
15688
|
+
}
|
|
15689
|
+
return path11;
|
|
15690
|
+
}
|
|
15365
15691
|
function Sidebar(props) {
|
|
15366
15692
|
const {
|
|
15367
15693
|
theme
|
|
@@ -15415,14 +15741,15 @@ function Sidebar(props) {
|
|
|
15415
15741
|
onCleanup(() => clearInterval(spinnerInterval));
|
|
15416
15742
|
const rows = createMemo(() => buildRows(props.tasks(), view(), searchMode() ? searchQuery() : ""));
|
|
15417
15743
|
const flatIds = createMemo(() => flattenIds(rows()));
|
|
15744
|
+
const firstTaskFlatIndex = createMemo(() => {
|
|
15745
|
+
const r = rows();
|
|
15746
|
+
const idx = r.findIndex((row) => row.task.kind !== "main");
|
|
15747
|
+
return idx < 0 ? -1 : r[idx].flatIndex;
|
|
15748
|
+
});
|
|
15418
15749
|
const totalRows = createMemo(() => flattenIds(buildRows(props.tasks(), view(), "")).length);
|
|
15419
15750
|
const effectiveWidth = () => props.width ? props.width() : SIDEBAR_WIDTH;
|
|
15420
|
-
const
|
|
15421
|
-
const
|
|
15422
|
-
const titleBudget = createMemo(() => {
|
|
15423
|
-
const reserved = 9 + (showChangesCol() ? CHANGES_COLUMN_WIDTH + 1 : 0) + (showBranchCol() ? BRANCH_LABEL_MAX + 2 : 0);
|
|
15424
|
-
return Math.max(4, effectiveWidth() - reserved);
|
|
15425
|
-
});
|
|
15751
|
+
const titleBudget = createMemo(() => Math.max(6, effectiveWidth() - 9));
|
|
15752
|
+
const subtitleBudget = createMemo(() => Math.max(6, effectiveWidth() - 16));
|
|
15426
15753
|
const dims = useTerminalDimensions();
|
|
15427
15754
|
const [hover, setHover] = createSignal(null);
|
|
15428
15755
|
const [cursorIndex, setCursorIndex] = createSignal(-1);
|
|
@@ -15480,80 +15807,127 @@ function Sidebar(props) {
|
|
|
15480
15807
|
onSearchEnter: () => enterSearch(),
|
|
15481
15808
|
onSearchExit: (select) => exitSearch(select)
|
|
15482
15809
|
});
|
|
15483
|
-
|
|
15484
|
-
var _el$ = createElement("box"), _el$2 = createElement("
|
|
15810
|
+
const SectionHeader = (p) => (() => {
|
|
15811
|
+
var _el$ = createElement("box"), _el$2 = createElement("text"), _el$3 = createElement("text");
|
|
15485
15812
|
insertNode(_el$, _el$2);
|
|
15486
|
-
insertNode(_el$, _el$
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
setProp(_el$, "
|
|
15490
|
-
setProp(_el$, "
|
|
15491
|
-
setProp(_el
|
|
15492
|
-
|
|
15493
|
-
setProp(_el$, "paddingLeft", 2);
|
|
15494
|
-
setProp(_el$, "paddingRight", 2);
|
|
15495
|
-
insertNode(_el$2, _el$3);
|
|
15496
|
-
insertNode(_el$2, _el$5);
|
|
15497
|
-
setProp(_el$2, "flexDirection", "row");
|
|
15498
|
-
setProp(_el$2, "gap", 1);
|
|
15499
|
-
setProp(_el$2, "paddingBottom", 1);
|
|
15500
|
-
setProp(_el$2, "paddingLeft", 1);
|
|
15501
|
-
insertNode(_el$3, createTextNode(`h`));
|
|
15813
|
+
insertNode(_el$, _el$3);
|
|
15814
|
+
setProp(_el$, "flexDirection", "row");
|
|
15815
|
+
setProp(_el$, "gap", 1);
|
|
15816
|
+
setProp(_el$, "paddingLeft", 1);
|
|
15817
|
+
setProp(_el$, "paddingRight", 1);
|
|
15818
|
+
setProp(_el$2, "wrapMode", "none");
|
|
15819
|
+
insert(_el$2, () => p.label);
|
|
15502
15820
|
setProp(_el$3, "wrapMode", "none");
|
|
15503
|
-
|
|
15504
|
-
|
|
15505
|
-
|
|
15821
|
+
insert(_el$3, () => "\u2500".repeat(Math.max(2, effectiveWidth() - 9 - p.label.length)));
|
|
15822
|
+
effect((_p$) => {
|
|
15823
|
+
var _v$ = p.topPad ? 1 : 0, _v$2 = theme.textMuted, _v$3 = TextAttributes8.BOLD, _v$4 = theme.border;
|
|
15824
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$, "paddingTop", _v$, _p$.e));
|
|
15825
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$2, "fg", _v$2, _p$.t));
|
|
15826
|
+
_v$3 !== _p$.a && (_p$.a = setProp(_el$2, "attributes", _v$3, _p$.a));
|
|
15827
|
+
_v$4 !== _p$.o && (_p$.o = setProp(_el$3, "fg", _v$4, _p$.o));
|
|
15828
|
+
return _p$;
|
|
15829
|
+
}, {
|
|
15830
|
+
e: undefined,
|
|
15831
|
+
t: undefined,
|
|
15832
|
+
a: undefined,
|
|
15833
|
+
o: undefined
|
|
15834
|
+
});
|
|
15835
|
+
return _el$;
|
|
15836
|
+
})();
|
|
15837
|
+
return (() => {
|
|
15838
|
+
var _el$4 = createElement("box"), _el$5 = createElement("box"), _el$6 = createElement("text"), _el$18 = createElement("box"), _el$19 = createElement("scrollbox"), _el$20 = createElement("box"), _el$23 = createElement("box"), _el$24 = createElement("text");
|
|
15839
|
+
insertNode(_el$4, _el$5);
|
|
15840
|
+
insertNode(_el$4, _el$18);
|
|
15841
|
+
insertNode(_el$4, _el$19);
|
|
15842
|
+
insertNode(_el$4, _el$23);
|
|
15843
|
+
setProp(_el$4, "flexShrink", 0);
|
|
15844
|
+
setProp(_el$4, "flexDirection", "column");
|
|
15845
|
+
setProp(_el$4, "paddingTop", 1);
|
|
15846
|
+
setProp(_el$4, "paddingBottom", 1);
|
|
15847
|
+
setProp(_el$4, "paddingLeft", 0);
|
|
15848
|
+
setProp(_el$4, "paddingRight", 0);
|
|
15849
|
+
insertNode(_el$5, _el$6);
|
|
15850
|
+
setProp(_el$5, "flexDirection", "row");
|
|
15851
|
+
setProp(_el$5, "justifyContent", "space-between");
|
|
15852
|
+
setProp(_el$5, "gap", 1);
|
|
15853
|
+
setProp(_el$5, "paddingBottom", 1);
|
|
15854
|
+
setProp(_el$5, "paddingLeft", 1);
|
|
15855
|
+
setProp(_el$5, "paddingRight", 1);
|
|
15856
|
+
insertNode(_el$6, createTextNode(`KOBE`));
|
|
15857
|
+
setProp(_el$6, "wrapMode", "none");
|
|
15858
|
+
insert(_el$5, createComponent2(Show, {
|
|
15859
|
+
get when() {
|
|
15860
|
+
return props.headerStatus?.();
|
|
15861
|
+
},
|
|
15862
|
+
children: (status) => (() => {
|
|
15863
|
+
var _el$26 = createElement("text");
|
|
15864
|
+
setProp(_el$26, "wrapMode", "none");
|
|
15865
|
+
setProp(_el$26, "onMouseUp", () => props.onHeaderStatusClick?.());
|
|
15866
|
+
insert(_el$26, () => status().label);
|
|
15867
|
+
effect((_p$) => {
|
|
15868
|
+
var _v$11 = status().emphasize ? theme.warning : theme.textMuted, _v$12 = status().emphasize ? TextAttributes8.BOLD : TextAttributes8.DIM;
|
|
15869
|
+
_v$11 !== _p$.e && (_p$.e = setProp(_el$26, "fg", _v$11, _p$.e));
|
|
15870
|
+
_v$12 !== _p$.t && (_p$.t = setProp(_el$26, "attributes", _v$12, _p$.t));
|
|
15871
|
+
return _p$;
|
|
15872
|
+
}, {
|
|
15873
|
+
e: undefined,
|
|
15874
|
+
t: undefined
|
|
15875
|
+
});
|
|
15876
|
+
return _el$26;
|
|
15877
|
+
})()
|
|
15878
|
+
}), null);
|
|
15879
|
+
insert(_el$4, createComponent2(Show, {
|
|
15506
15880
|
get when() {
|
|
15507
15881
|
return searchMode();
|
|
15508
15882
|
},
|
|
15509
15883
|
get children() {
|
|
15510
|
-
var _el$
|
|
15511
|
-
insertNode(_el$
|
|
15512
|
-
insertNode(_el$
|
|
15513
|
-
insertNode(_el$
|
|
15514
|
-
setProp(_el$
|
|
15515
|
-
setProp(_el$
|
|
15516
|
-
setProp(_el$
|
|
15517
|
-
setProp(_el$
|
|
15518
|
-
insertNode(_el$
|
|
15519
|
-
setProp(_el$
|
|
15520
|
-
setProp(_el$0, "wrapMode", "none");
|
|
15521
|
-
insert(_el$0, searchQuery);
|
|
15522
|
-
insertNode(_el$1, createTextNode(`\u2588`));
|
|
15884
|
+
var _el$8 = createElement("box"), _el$9 = createElement("text"), _el$1 = createElement("text"), _el$10 = createElement("text");
|
|
15885
|
+
insertNode(_el$8, _el$9);
|
|
15886
|
+
insertNode(_el$8, _el$1);
|
|
15887
|
+
insertNode(_el$8, _el$10);
|
|
15888
|
+
setProp(_el$8, "flexDirection", "row");
|
|
15889
|
+
setProp(_el$8, "gap", 0);
|
|
15890
|
+
setProp(_el$8, "paddingBottom", 1);
|
|
15891
|
+
setProp(_el$8, "paddingLeft", 1);
|
|
15892
|
+
insertNode(_el$9, createTextNode(`/`));
|
|
15893
|
+
setProp(_el$9, "wrapMode", "none");
|
|
15523
15894
|
setProp(_el$1, "wrapMode", "none");
|
|
15524
|
-
insert(_el$
|
|
15895
|
+
insert(_el$1, searchQuery);
|
|
15896
|
+
insertNode(_el$10, createTextNode(`\u2588`));
|
|
15897
|
+
setProp(_el$10, "wrapMode", "none");
|
|
15898
|
+
insert(_el$8, createComponent2(Show, {
|
|
15525
15899
|
get when() {
|
|
15526
15900
|
return searchQuery().length === 0;
|
|
15527
15901
|
},
|
|
15528
15902
|
get children() {
|
|
15529
|
-
var _el$
|
|
15530
|
-
insertNode(_el$
|
|
15531
|
-
setProp(_el$
|
|
15532
|
-
effect((_$p) => setProp(_el$
|
|
15533
|
-
return _el$
|
|
15903
|
+
var _el$12 = createElement("text"), _el$13 = createTextNode(` fuzzy filter`);
|
|
15904
|
+
insertNode(_el$12, _el$13);
|
|
15905
|
+
setProp(_el$12, "wrapMode", "none");
|
|
15906
|
+
effect((_$p) => setProp(_el$12, "fg", theme.textMuted, _$p));
|
|
15907
|
+
return _el$12;
|
|
15534
15908
|
}
|
|
15535
15909
|
}), null);
|
|
15536
|
-
insert(_el$
|
|
15910
|
+
insert(_el$8, createComponent2(Show, {
|
|
15537
15911
|
get when() {
|
|
15538
15912
|
return searchQuery().length > 0;
|
|
15539
15913
|
},
|
|
15540
15914
|
get children() {
|
|
15541
|
-
var _el$
|
|
15542
|
-
insertNode(_el$
|
|
15543
|
-
insertNode(_el$
|
|
15544
|
-
setProp(_el$
|
|
15545
|
-
insert(_el$
|
|
15546
|
-
insert(_el$
|
|
15547
|
-
effect((_$p) => setProp(_el$
|
|
15548
|
-
return _el$
|
|
15915
|
+
var _el$15 = createElement("text"), _el$16 = createTextNode(` `), _el$17 = createTextNode(`/`);
|
|
15916
|
+
insertNode(_el$15, _el$16);
|
|
15917
|
+
insertNode(_el$15, _el$17);
|
|
15918
|
+
setProp(_el$15, "wrapMode", "none");
|
|
15919
|
+
insert(_el$15, () => flatIds().length, _el$17);
|
|
15920
|
+
insert(_el$15, totalRows, null);
|
|
15921
|
+
effect((_$p) => setProp(_el$15, "fg", theme.textMuted, _$p));
|
|
15922
|
+
return _el$15;
|
|
15549
15923
|
}
|
|
15550
15924
|
}), null);
|
|
15551
15925
|
effect((_p$) => {
|
|
15552
|
-
var { info: _v
|
|
15553
|
-
_v$ !== _p$.e && (_p$.e = setProp(_el$
|
|
15554
|
-
_v$
|
|
15555
|
-
_v$
|
|
15556
|
-
_v$
|
|
15926
|
+
var { info: _v$5, text: _v$6, info: _v$7 } = theme, _v$8 = TextAttributes8.BLINK;
|
|
15927
|
+
_v$5 !== _p$.e && (_p$.e = setProp(_el$9, "fg", _v$5, _p$.e));
|
|
15928
|
+
_v$6 !== _p$.t && (_p$.t = setProp(_el$1, "fg", _v$6, _p$.t));
|
|
15929
|
+
_v$7 !== _p$.a && (_p$.a = setProp(_el$10, "fg", _v$7, _p$.a));
|
|
15930
|
+
_v$8 !== _p$.o && (_p$.o = setProp(_el$10, "attributes", _v$8, _p$.o));
|
|
15557
15931
|
return _p$;
|
|
15558
15932
|
}, {
|
|
15559
15933
|
e: undefined,
|
|
@@ -15561,46 +15935,46 @@ function Sidebar(props) {
|
|
|
15561
15935
|
a: undefined,
|
|
15562
15936
|
o: undefined
|
|
15563
15937
|
});
|
|
15564
|
-
return _el$
|
|
15938
|
+
return _el$8;
|
|
15565
15939
|
}
|
|
15566
|
-
}), _el$
|
|
15567
|
-
setProp(_el$
|
|
15568
|
-
setProp(_el$
|
|
15569
|
-
setProp(_el$
|
|
15570
|
-
setProp(_el$
|
|
15571
|
-
insert(_el$
|
|
15940
|
+
}), _el$18);
|
|
15941
|
+
setProp(_el$18, "flexDirection", "row");
|
|
15942
|
+
setProp(_el$18, "gap", 2);
|
|
15943
|
+
setProp(_el$18, "paddingBottom", 1);
|
|
15944
|
+
setProp(_el$18, "paddingLeft", 1);
|
|
15945
|
+
insert(_el$18, createComponent2(For, {
|
|
15572
15946
|
each: VIEW_TABS,
|
|
15573
15947
|
children: (tab) => {
|
|
15574
15948
|
const active = () => view() === tab.view;
|
|
15575
15949
|
return (() => {
|
|
15576
|
-
var _el$
|
|
15577
|
-
setProp(_el$
|
|
15578
|
-
setProp(_el$
|
|
15579
|
-
insert(_el$
|
|
15950
|
+
var _el$27 = createElement("text");
|
|
15951
|
+
setProp(_el$27, "wrapMode", "none");
|
|
15952
|
+
setProp(_el$27, "onMouseUp", () => setView(tab.view));
|
|
15953
|
+
insert(_el$27, () => tab.label);
|
|
15580
15954
|
effect((_p$) => {
|
|
15581
|
-
var _v$
|
|
15582
|
-
_v$
|
|
15583
|
-
_v$
|
|
15955
|
+
var _v$13 = active() ? theme.primary : theme.textMuted, _v$14 = active() ? TextAttributes8.BOLD : undefined;
|
|
15956
|
+
_v$13 !== _p$.e && (_p$.e = setProp(_el$27, "fg", _v$13, _p$.e));
|
|
15957
|
+
_v$14 !== _p$.t && (_p$.t = setProp(_el$27, "attributes", _v$14, _p$.t));
|
|
15584
15958
|
return _p$;
|
|
15585
15959
|
}, {
|
|
15586
15960
|
e: undefined,
|
|
15587
15961
|
t: undefined
|
|
15588
15962
|
});
|
|
15589
|
-
return _el$
|
|
15963
|
+
return _el$27;
|
|
15590
15964
|
})();
|
|
15591
15965
|
}
|
|
15592
15966
|
}));
|
|
15593
|
-
insertNode(_el$
|
|
15594
|
-
setProp(_el$
|
|
15595
|
-
setProp(_el$
|
|
15967
|
+
insertNode(_el$19, _el$20);
|
|
15968
|
+
setProp(_el$19, "flexGrow", 1);
|
|
15969
|
+
setProp(_el$19, "verticalScrollbarOptions", {
|
|
15596
15970
|
trackOptions: {
|
|
15597
15971
|
foregroundColor: "transparent"
|
|
15598
15972
|
}
|
|
15599
15973
|
});
|
|
15600
|
-
setProp(_el$
|
|
15601
|
-
setProp(_el$
|
|
15602
|
-
setProp(_el$
|
|
15603
|
-
insert(_el$
|
|
15974
|
+
setProp(_el$20, "flexShrink", 0);
|
|
15975
|
+
setProp(_el$20, "gap", 0);
|
|
15976
|
+
setProp(_el$20, "paddingRight", 1);
|
|
15977
|
+
insert(_el$20, createComponent2(For, {
|
|
15604
15978
|
get each() {
|
|
15605
15979
|
return rows();
|
|
15606
15980
|
},
|
|
@@ -15640,175 +16014,290 @@ function Sidebar(props) {
|
|
|
15640
16014
|
return theme.textMuted;
|
|
15641
16015
|
}
|
|
15642
16016
|
};
|
|
15643
|
-
const branchLabel = createMemo(() => {
|
|
15644
|
-
if (!isMain)
|
|
15645
|
-
return "";
|
|
15646
|
-
branchTick();
|
|
15647
|
-
return readCurrentBranch(task.repo);
|
|
15648
|
-
});
|
|
15649
16017
|
const changes = createMemo(() => {
|
|
15650
16018
|
branchTick();
|
|
15651
16019
|
return readWorktreeChanges(task.worktreePath);
|
|
15652
16020
|
});
|
|
15653
16021
|
const titleText = isMain ? repoBasename(task.repo) : task.title;
|
|
16022
|
+
const loading = () => isLive() || task.status === "in_progress";
|
|
16023
|
+
const subtitleText = createMemo(() => {
|
|
16024
|
+
if (task.branch.length > 0)
|
|
16025
|
+
return truncateBranchLabel(task.branch, subtitleBudget());
|
|
16026
|
+
return STATUS_LABEL[task.status];
|
|
16027
|
+
});
|
|
16028
|
+
const barColor = () => isCursor() ? theme.focusAccent : isSelected() ? theme.primary : undefined;
|
|
16029
|
+
const barGlyph = () => isCursor() || isSelected() ? "\u258C" : " ";
|
|
16030
|
+
const showProjectsHeader = () => isMain && flatIndex === 0;
|
|
16031
|
+
const showTasksHeader = () => !isMain && flatIndex === firstTaskFlatIndex();
|
|
15654
16032
|
return (() => {
|
|
15655
|
-
var _el$
|
|
15656
|
-
insertNode(_el$
|
|
15657
|
-
|
|
15658
|
-
setProp(_el$
|
|
15659
|
-
setProp(_el$
|
|
15660
|
-
|
|
15661
|
-
|
|
15662
|
-
|
|
16033
|
+
var _el$28 = createElement("box"), _el$29 = createElement("box");
|
|
16034
|
+
insertNode(_el$28, _el$29);
|
|
16035
|
+
setProp(_el$28, "flexDirection", "column");
|
|
16036
|
+
setProp(_el$28, "gap", 0);
|
|
16037
|
+
setProp(_el$28, "paddingBottom", isMain ? 0 : 1);
|
|
16038
|
+
insert(_el$28, createComponent2(Show, {
|
|
16039
|
+
get when() {
|
|
16040
|
+
return showProjectsHeader();
|
|
16041
|
+
},
|
|
16042
|
+
get children() {
|
|
16043
|
+
return createComponent2(SectionHeader, {
|
|
16044
|
+
label: "PROJECTS"
|
|
16045
|
+
});
|
|
16046
|
+
}
|
|
16047
|
+
}), _el$29);
|
|
16048
|
+
insert(_el$28, createComponent2(Show, {
|
|
16049
|
+
get when() {
|
|
16050
|
+
return showTasksHeader();
|
|
16051
|
+
},
|
|
16052
|
+
get children() {
|
|
16053
|
+
return createComponent2(SectionHeader, {
|
|
16054
|
+
label: "TASKS",
|
|
16055
|
+
get topPad() {
|
|
16056
|
+
return firstTaskFlatIndex() > 0;
|
|
16057
|
+
}
|
|
16058
|
+
});
|
|
16059
|
+
}
|
|
16060
|
+
}), _el$29);
|
|
16061
|
+
setProp(_el$29, "flexDirection", "column");
|
|
16062
|
+
setProp(_el$29, "gap", 0);
|
|
16063
|
+
setProp(_el$29, "onMouseUp", () => {
|
|
15663
16064
|
props.onSelect(task.id);
|
|
15664
16065
|
if (props.activateOnClick)
|
|
15665
16066
|
props.onActivate?.(task.id);
|
|
15666
16067
|
});
|
|
15667
|
-
setProp(_el$
|
|
16068
|
+
setProp(_el$29, "onMouseOver", (e) => setHover({
|
|
15668
16069
|
task,
|
|
15669
16070
|
x: e.x,
|
|
15670
16071
|
y: e.y
|
|
15671
16072
|
}));
|
|
15672
|
-
setProp(_el$
|
|
15673
|
-
|
|
15674
|
-
|
|
15675
|
-
setProp(_el$28, "wrapMode", "none");
|
|
15676
|
-
setProp(_el$28, "flexGrow", 1);
|
|
15677
|
-
insert(_el$28, () => truncateTitle(titleText, titleBudget()));
|
|
15678
|
-
insert(_el$26, createComponent2(Show, {
|
|
15679
|
-
get when() {
|
|
15680
|
-
return showChangesCol();
|
|
15681
|
-
},
|
|
15682
|
-
get children() {
|
|
15683
|
-
var _el$29 = createElement("box");
|
|
15684
|
-
setProp(_el$29, "width", 5);
|
|
15685
|
-
setProp(_el$29, "flexShrink", 0);
|
|
15686
|
-
setProp(_el$29, "flexDirection", "row");
|
|
15687
|
-
setProp(_el$29, "justifyContent", "flex-end");
|
|
15688
|
-
setProp(_el$29, "gap", 1);
|
|
15689
|
-
insert(_el$29, createComponent2(Show, {
|
|
15690
|
-
get when() {
|
|
15691
|
-
return changes().added > 0;
|
|
15692
|
-
},
|
|
15693
|
-
get children() {
|
|
15694
|
-
var _el$30 = createElement("text"), _el$31 = createTextNode(`+`);
|
|
15695
|
-
insertNode(_el$30, _el$31);
|
|
15696
|
-
setProp(_el$30, "wrapMode", "none");
|
|
15697
|
-
insert(_el$30, () => changes().added, null);
|
|
15698
|
-
effect((_$p) => setProp(_el$30, "fg", isCursor() ? theme.selectedListItemText : theme.success, _$p));
|
|
15699
|
-
return _el$30;
|
|
15700
|
-
}
|
|
15701
|
-
}), null);
|
|
15702
|
-
insert(_el$29, createComponent2(Show, {
|
|
15703
|
-
get when() {
|
|
15704
|
-
return changes().deleted > 0;
|
|
15705
|
-
},
|
|
15706
|
-
get children() {
|
|
15707
|
-
var _el$32 = createElement("text"), _el$33 = createTextNode(`\u2212`);
|
|
15708
|
-
insertNode(_el$32, _el$33);
|
|
15709
|
-
setProp(_el$32, "wrapMode", "none");
|
|
15710
|
-
insert(_el$32, () => changes().deleted, null);
|
|
15711
|
-
effect((_$p) => setProp(_el$32, "fg", isCursor() ? theme.selectedListItemText : theme.error, _$p));
|
|
15712
|
-
return _el$32;
|
|
15713
|
-
}
|
|
15714
|
-
}), null);
|
|
15715
|
-
return _el$29;
|
|
15716
|
-
}
|
|
15717
|
-
}), null);
|
|
15718
|
-
insert(_el$26, createComponent2(Show, {
|
|
15719
|
-
get when() {
|
|
15720
|
-
return memo2(() => !!showBranchCol())() && (isMain && branchLabel().length > 0 || !isMain && (task.branch.length > 0 || task.pinned === true));
|
|
15721
|
-
},
|
|
16073
|
+
setProp(_el$29, "onMouseOut", () => setHover((h) => h?.task.id === task.id ? null : h));
|
|
16074
|
+
insert(_el$29, createComponent2(Show, {
|
|
16075
|
+
when: isMain,
|
|
15722
16076
|
get children() {
|
|
15723
|
-
var _el$
|
|
15724
|
-
|
|
15725
|
-
|
|
15726
|
-
setProp(_el$
|
|
15727
|
-
setProp(_el$
|
|
15728
|
-
setProp(_el$
|
|
15729
|
-
insert(_el$
|
|
16077
|
+
var _el$30 = createElement("box"), _el$31 = createElement("text"), _el$32 = createElement("box"), _el$33 = createElement("text"), _el$34 = createElement("text");
|
|
16078
|
+
insertNode(_el$30, _el$31);
|
|
16079
|
+
insertNode(_el$30, _el$32);
|
|
16080
|
+
setProp(_el$30, "flexDirection", "row");
|
|
16081
|
+
setProp(_el$30, "gap", 0);
|
|
16082
|
+
setProp(_el$31, "wrapMode", "none");
|
|
16083
|
+
insert(_el$31, barGlyph);
|
|
16084
|
+
insertNode(_el$32, _el$33);
|
|
16085
|
+
insertNode(_el$32, _el$34);
|
|
16086
|
+
setProp(_el$32, "flexDirection", "row");
|
|
16087
|
+
setProp(_el$32, "flexGrow", 1);
|
|
16088
|
+
setProp(_el$32, "paddingRight", 1);
|
|
16089
|
+
setProp(_el$32, "gap", 1);
|
|
16090
|
+
setProp(_el$33, "wrapMode", "none");
|
|
16091
|
+
insert(_el$33, (() => {
|
|
16092
|
+
var _c$2 = memo2(() => !!loading());
|
|
16093
|
+
return () => _c$2() ? IN_PROGRESS_SPINNER[spinnerFrame()] ?? IN_PROGRESS_SPINNER[0] : "\u2605";
|
|
16094
|
+
})());
|
|
16095
|
+
setProp(_el$34, "wrapMode", "none");
|
|
16096
|
+
setProp(_el$34, "flexGrow", 1);
|
|
16097
|
+
insert(_el$34, () => truncateTitle(titleText, titleBudget()));
|
|
16098
|
+
insert(_el$32, createComponent2(Show, {
|
|
15730
16099
|
get when() {
|
|
15731
|
-
return
|
|
16100
|
+
return loading();
|
|
15732
16101
|
},
|
|
15733
16102
|
get children() {
|
|
15734
16103
|
var _el$35 = createElement("text");
|
|
16104
|
+
insertNode(_el$35, createTextNode(`working`));
|
|
15735
16105
|
setProp(_el$35, "wrapMode", "none");
|
|
15736
|
-
|
|
15737
|
-
effect((_$p) => setProp(_el$35, "fg", isCursor() ? theme.selectedListItemText : theme.textMuted, _$p));
|
|
16106
|
+
effect((_$p) => setProp(_el$35, "fg", theme.primary, _$p));
|
|
15738
16107
|
return _el$35;
|
|
15739
16108
|
}
|
|
15740
16109
|
}), null);
|
|
15741
|
-
insert(_el$
|
|
15742
|
-
get when() {
|
|
15743
|
-
return !isMain && task.branch.length > 0;
|
|
15744
|
-
},
|
|
15745
|
-
get children() {
|
|
15746
|
-
var _el$36 = createElement("text");
|
|
15747
|
-
setProp(_el$36, "wrapMode", "none");
|
|
15748
|
-
insert(_el$36, () => truncateBranchLabel(task.branch));
|
|
15749
|
-
effect((_$p) => setProp(_el$36, "fg", isCursor() ? theme.selectedListItemText : theme.textMuted, _$p));
|
|
15750
|
-
return _el$36;
|
|
15751
|
-
}
|
|
15752
|
-
}), null);
|
|
15753
|
-
insert(_el$34, createComponent2(Show, {
|
|
16110
|
+
insert(_el$32, createComponent2(Show, {
|
|
15754
16111
|
get when() {
|
|
15755
|
-
return !
|
|
16112
|
+
return !loading();
|
|
15756
16113
|
},
|
|
15757
16114
|
get children() {
|
|
15758
16115
|
var _el$37 = createElement("text");
|
|
15759
|
-
insertNode(_el$37, createTextNode(`\u25B4`));
|
|
15760
16116
|
setProp(_el$37, "wrapMode", "none");
|
|
15761
|
-
|
|
16117
|
+
insert(_el$37, () => truncatePathTail(abbrevHome(task.repo), subtitleBudget()));
|
|
16118
|
+
effect((_p$) => {
|
|
16119
|
+
var _v$15 = theme.textMuted, _v$16 = TextAttributes8.DIM;
|
|
16120
|
+
_v$15 !== _p$.e && (_p$.e = setProp(_el$37, "fg", _v$15, _p$.e));
|
|
16121
|
+
_v$16 !== _p$.t && (_p$.t = setProp(_el$37, "attributes", _v$16, _p$.t));
|
|
16122
|
+
return _p$;
|
|
16123
|
+
}, {
|
|
16124
|
+
e: undefined,
|
|
16125
|
+
t: undefined
|
|
16126
|
+
});
|
|
15762
16127
|
return _el$37;
|
|
15763
16128
|
}
|
|
15764
16129
|
}), null);
|
|
15765
|
-
|
|
16130
|
+
effect((_p$) => {
|
|
16131
|
+
var _v$17 = barColor(), _v$18 = theme.primary, _v$19 = TextAttributes8.BOLD, _v$20 = theme.text, _v$21 = TextAttributes8.BOLD;
|
|
16132
|
+
_v$17 !== _p$.e && (_p$.e = setProp(_el$31, "fg", _v$17, _p$.e));
|
|
16133
|
+
_v$18 !== _p$.t && (_p$.t = setProp(_el$33, "fg", _v$18, _p$.t));
|
|
16134
|
+
_v$19 !== _p$.a && (_p$.a = setProp(_el$33, "attributes", _v$19, _p$.a));
|
|
16135
|
+
_v$20 !== _p$.o && (_p$.o = setProp(_el$34, "fg", _v$20, _p$.o));
|
|
16136
|
+
_v$21 !== _p$.i && (_p$.i = setProp(_el$34, "attributes", _v$21, _p$.i));
|
|
16137
|
+
return _p$;
|
|
16138
|
+
}, {
|
|
16139
|
+
e: undefined,
|
|
16140
|
+
t: undefined,
|
|
16141
|
+
a: undefined,
|
|
16142
|
+
o: undefined,
|
|
16143
|
+
i: undefined
|
|
16144
|
+
});
|
|
16145
|
+
return _el$30;
|
|
15766
16146
|
}
|
|
15767
16147
|
}), null);
|
|
15768
|
-
|
|
15769
|
-
|
|
15770
|
-
|
|
15771
|
-
|
|
15772
|
-
|
|
15773
|
-
|
|
15774
|
-
|
|
15775
|
-
|
|
15776
|
-
|
|
15777
|
-
|
|
15778
|
-
|
|
15779
|
-
|
|
15780
|
-
|
|
15781
|
-
|
|
15782
|
-
|
|
15783
|
-
|
|
16148
|
+
insert(_el$29, createComponent2(Show, {
|
|
16149
|
+
when: !isMain,
|
|
16150
|
+
get children() {
|
|
16151
|
+
return [(() => {
|
|
16152
|
+
var _el$38 = createElement("box"), _el$39 = createElement("text"), _el$40 = createElement("box"), _el$41 = createElement("text"), _el$42 = createElement("text");
|
|
16153
|
+
insertNode(_el$38, _el$39);
|
|
16154
|
+
insertNode(_el$38, _el$40);
|
|
16155
|
+
setProp(_el$38, "flexDirection", "row");
|
|
16156
|
+
setProp(_el$38, "gap", 0);
|
|
16157
|
+
setProp(_el$39, "wrapMode", "none");
|
|
16158
|
+
insert(_el$39, barGlyph);
|
|
16159
|
+
insertNode(_el$40, _el$41);
|
|
16160
|
+
insertNode(_el$40, _el$42);
|
|
16161
|
+
setProp(_el$40, "flexDirection", "row");
|
|
16162
|
+
setProp(_el$40, "flexGrow", 1);
|
|
16163
|
+
setProp(_el$40, "paddingRight", 1);
|
|
16164
|
+
setProp(_el$40, "gap", 1);
|
|
16165
|
+
setProp(_el$41, "wrapMode", "none");
|
|
16166
|
+
insert(_el$41, (() => {
|
|
16167
|
+
var _c$3 = memo2(() => !!loading());
|
|
16168
|
+
return () => _c$3() ? IN_PROGRESS_SPINNER[spinnerFrame()] ?? IN_PROGRESS_SPINNER[0] : badge.glyph;
|
|
16169
|
+
})());
|
|
16170
|
+
setProp(_el$42, "wrapMode", "none");
|
|
16171
|
+
setProp(_el$42, "flexGrow", 1);
|
|
16172
|
+
insert(_el$42, () => truncateTitle(titleText, titleBudget()));
|
|
16173
|
+
insert(_el$40, createComponent2(Show, {
|
|
16174
|
+
get when() {
|
|
16175
|
+
return loading();
|
|
16176
|
+
},
|
|
16177
|
+
get children() {
|
|
16178
|
+
var _el$43 = createElement("text");
|
|
16179
|
+
insertNode(_el$43, createTextNode(`working`));
|
|
16180
|
+
setProp(_el$43, "wrapMode", "none");
|
|
16181
|
+
effect((_$p) => setProp(_el$43, "fg", theme.primary, _$p));
|
|
16182
|
+
return _el$43;
|
|
16183
|
+
}
|
|
16184
|
+
}), null);
|
|
16185
|
+
effect((_p$) => {
|
|
16186
|
+
var _v$22 = barColor(), _v$23 = badgeColor(), _v$24 = TextAttributes8.BOLD, _v$25 = theme.text, _v$26 = isSelected() || isCursor() ? TextAttributes8.BOLD : undefined;
|
|
16187
|
+
_v$22 !== _p$.e && (_p$.e = setProp(_el$39, "fg", _v$22, _p$.e));
|
|
16188
|
+
_v$23 !== _p$.t && (_p$.t = setProp(_el$41, "fg", _v$23, _p$.t));
|
|
16189
|
+
_v$24 !== _p$.a && (_p$.a = setProp(_el$41, "attributes", _v$24, _p$.a));
|
|
16190
|
+
_v$25 !== _p$.o && (_p$.o = setProp(_el$42, "fg", _v$25, _p$.o));
|
|
16191
|
+
_v$26 !== _p$.i && (_p$.i = setProp(_el$42, "attributes", _v$26, _p$.i));
|
|
16192
|
+
return _p$;
|
|
16193
|
+
}, {
|
|
16194
|
+
e: undefined,
|
|
16195
|
+
t: undefined,
|
|
16196
|
+
a: undefined,
|
|
16197
|
+
o: undefined,
|
|
16198
|
+
i: undefined
|
|
16199
|
+
});
|
|
16200
|
+
return _el$38;
|
|
16201
|
+
})(), (() => {
|
|
16202
|
+
var _el$45 = createElement("box"), _el$46 = createElement("text"), _el$47 = createElement("box"), _el$48 = createElement("text");
|
|
16203
|
+
insertNode(_el$45, _el$46);
|
|
16204
|
+
insertNode(_el$45, _el$47);
|
|
16205
|
+
setProp(_el$45, "flexDirection", "row");
|
|
16206
|
+
setProp(_el$45, "gap", 0);
|
|
16207
|
+
setProp(_el$46, "wrapMode", "none");
|
|
16208
|
+
insert(_el$46, barGlyph);
|
|
16209
|
+
insertNode(_el$47, _el$48);
|
|
16210
|
+
setProp(_el$47, "flexDirection", "row");
|
|
16211
|
+
setProp(_el$47, "flexGrow", 1);
|
|
16212
|
+
setProp(_el$47, "paddingLeft", 2);
|
|
16213
|
+
setProp(_el$47, "paddingRight", 1);
|
|
16214
|
+
setProp(_el$47, "gap", 1);
|
|
16215
|
+
setProp(_el$48, "wrapMode", "none");
|
|
16216
|
+
setProp(_el$48, "flexGrow", 1);
|
|
16217
|
+
insert(_el$48, subtitleText);
|
|
16218
|
+
insert(_el$47, createComponent2(Show, {
|
|
16219
|
+
get when() {
|
|
16220
|
+
return task.pinned === true;
|
|
16221
|
+
},
|
|
16222
|
+
get children() {
|
|
16223
|
+
var _el$49 = createElement("text");
|
|
16224
|
+
insertNode(_el$49, createTextNode(`\u25B4`));
|
|
16225
|
+
setProp(_el$49, "wrapMode", "none");
|
|
16226
|
+
effect((_$p) => setProp(_el$49, "fg", theme.warning, _$p));
|
|
16227
|
+
return _el$49;
|
|
16228
|
+
}
|
|
16229
|
+
}), null);
|
|
16230
|
+
insert(_el$47, createComponent2(Show, {
|
|
16231
|
+
get when() {
|
|
16232
|
+
return changes().added > 0;
|
|
16233
|
+
},
|
|
16234
|
+
get children() {
|
|
16235
|
+
var _el$51 = createElement("text"), _el$52 = createTextNode(`+`);
|
|
16236
|
+
insertNode(_el$51, _el$52);
|
|
16237
|
+
setProp(_el$51, "wrapMode", "none");
|
|
16238
|
+
insert(_el$51, () => changes().added, null);
|
|
16239
|
+
effect((_$p) => setProp(_el$51, "fg", theme.success, _$p));
|
|
16240
|
+
return _el$51;
|
|
16241
|
+
}
|
|
16242
|
+
}), null);
|
|
16243
|
+
insert(_el$47, createComponent2(Show, {
|
|
16244
|
+
get when() {
|
|
16245
|
+
return changes().deleted > 0;
|
|
16246
|
+
},
|
|
16247
|
+
get children() {
|
|
16248
|
+
var _el$53 = createElement("text"), _el$54 = createTextNode(`\u2212`);
|
|
16249
|
+
insertNode(_el$53, _el$54);
|
|
16250
|
+
setProp(_el$53, "wrapMode", "none");
|
|
16251
|
+
insert(_el$53, () => changes().deleted, null);
|
|
16252
|
+
effect((_$p) => setProp(_el$53, "fg", theme.error, _$p));
|
|
16253
|
+
return _el$53;
|
|
16254
|
+
}
|
|
16255
|
+
}), null);
|
|
16256
|
+
effect((_p$) => {
|
|
16257
|
+
var _v$27 = barColor(), _v$28 = theme.textMuted, _v$29 = TextAttributes8.DIM;
|
|
16258
|
+
_v$27 !== _p$.e && (_p$.e = setProp(_el$46, "fg", _v$27, _p$.e));
|
|
16259
|
+
_v$28 !== _p$.t && (_p$.t = setProp(_el$48, "fg", _v$28, _p$.t));
|
|
16260
|
+
_v$29 !== _p$.a && (_p$.a = setProp(_el$48, "attributes", _v$29, _p$.a));
|
|
16261
|
+
return _p$;
|
|
16262
|
+
}, {
|
|
16263
|
+
e: undefined,
|
|
16264
|
+
t: undefined,
|
|
16265
|
+
a: undefined
|
|
16266
|
+
});
|
|
16267
|
+
return _el$45;
|
|
16268
|
+
})()];
|
|
16269
|
+
}
|
|
16270
|
+
}), null);
|
|
16271
|
+
effect((_$p) => setProp(_el$29, "backgroundColor", isCursor() ? theme.backgroundElement : undefined, _$p));
|
|
16272
|
+
return _el$28;
|
|
15784
16273
|
})();
|
|
15785
16274
|
}
|
|
15786
16275
|
}), null);
|
|
15787
|
-
insert(_el$
|
|
16276
|
+
insert(_el$20, createComponent2(Show, {
|
|
15788
16277
|
get when() {
|
|
15789
16278
|
return flatIds().length === 0;
|
|
15790
16279
|
},
|
|
15791
16280
|
get children() {
|
|
15792
|
-
var _el$
|
|
15793
|
-
insertNode(_el$
|
|
15794
|
-
setProp(_el$
|
|
15795
|
-
setProp(_el$
|
|
15796
|
-
insert(_el$
|
|
16281
|
+
var _el$21 = createElement("box"), _el$22 = createElement("text");
|
|
16282
|
+
insertNode(_el$21, _el$22);
|
|
16283
|
+
setProp(_el$21, "paddingTop", 1);
|
|
16284
|
+
setProp(_el$21, "paddingLeft", 1);
|
|
16285
|
+
insert(_el$22, (() => {
|
|
15797
16286
|
var _c$ = memo2(() => !!(searchMode() && searchQuery().trim().length > 0));
|
|
15798
16287
|
return () => _c$() ? "No matching tasks \u2014 esc to clear." : view() === "active" ? "No active tasks." : "No archived tasks.";
|
|
15799
16288
|
})());
|
|
15800
|
-
effect((_$p) => setProp(_el$
|
|
15801
|
-
return _el$
|
|
16289
|
+
effect((_$p) => setProp(_el$22, "fg", theme.textMuted, _$p));
|
|
16290
|
+
return _el$21;
|
|
15802
16291
|
}
|
|
15803
16292
|
}), null);
|
|
15804
|
-
insertNode(_el$
|
|
15805
|
-
setProp(_el$
|
|
15806
|
-
setProp(_el$
|
|
15807
|
-
setProp(_el$
|
|
15808
|
-
insertNode(_el$
|
|
15809
|
-
setProp(_el$
|
|
15810
|
-
setProp(_el$
|
|
15811
|
-
insert(_el
|
|
16293
|
+
insertNode(_el$23, _el$24);
|
|
16294
|
+
setProp(_el$23, "flexShrink", 0);
|
|
16295
|
+
setProp(_el$23, "paddingTop", 1);
|
|
16296
|
+
setProp(_el$23, "paddingLeft", 1);
|
|
16297
|
+
insertNode(_el$24, createTextNode(`+ New task`));
|
|
16298
|
+
setProp(_el$24, "wrapMode", "none");
|
|
16299
|
+
setProp(_el$24, "onMouseUp", () => props.onAddTask?.());
|
|
16300
|
+
insert(_el$4, createComponent2(Show, {
|
|
15812
16301
|
get when() {
|
|
15813
16302
|
return hover();
|
|
15814
16303
|
},
|
|
@@ -15838,43 +16327,43 @@ function Sidebar(props) {
|
|
|
15838
16327
|
const left = createMemo(() => Math.max(0, Math.min(h().x + 2, dims().width - boxW() - 1)));
|
|
15839
16328
|
const top = createMemo(() => Math.max(0, Math.min(h().y + 1, dims().height - boxH() - 1)));
|
|
15840
16329
|
return (() => {
|
|
15841
|
-
var _el$
|
|
15842
|
-
setProp(_el$
|
|
15843
|
-
setProp(_el$
|
|
15844
|
-
setProp(_el$
|
|
15845
|
-
setProp(_el$
|
|
15846
|
-
setProp(_el$
|
|
15847
|
-
setProp(_el$
|
|
15848
|
-
insert(_el$
|
|
16330
|
+
var _el$55 = createElement("box");
|
|
16331
|
+
setProp(_el$55, "position", "absolute");
|
|
16332
|
+
setProp(_el$55, "zIndex", 2600);
|
|
16333
|
+
setProp(_el$55, "flexDirection", "column");
|
|
16334
|
+
setProp(_el$55, "border", true);
|
|
16335
|
+
setProp(_el$55, "paddingLeft", 1);
|
|
16336
|
+
setProp(_el$55, "paddingRight", 1);
|
|
16337
|
+
insert(_el$55, createComponent2(For, {
|
|
15849
16338
|
get each() {
|
|
15850
16339
|
return lines();
|
|
15851
16340
|
},
|
|
15852
16341
|
children: (l) => (() => {
|
|
15853
|
-
var _el$
|
|
15854
|
-
setProp(_el$
|
|
15855
|
-
insert(_el$
|
|
15856
|
-
var _c$
|
|
15857
|
-
return () => _c$
|
|
16342
|
+
var _el$56 = createElement("text");
|
|
16343
|
+
setProp(_el$56, "wrapMode", "none");
|
|
16344
|
+
insert(_el$56, (() => {
|
|
16345
|
+
var _c$4 = memo2(() => !!l.dim);
|
|
16346
|
+
return () => _c$4() ? truncatePathTail(l.text, innerW()) : truncateTitle(l.text, innerW());
|
|
15858
16347
|
})());
|
|
15859
16348
|
effect((_p$) => {
|
|
15860
|
-
var _v$
|
|
15861
|
-
_v$
|
|
15862
|
-
_v$
|
|
16349
|
+
var _v$35 = l.dim ? theme.textMuted : theme.text, _v$36 = l.bold ? TextAttributes8.BOLD : l.dim ? TextAttributes8.DIM : undefined;
|
|
16350
|
+
_v$35 !== _p$.e && (_p$.e = setProp(_el$56, "fg", _v$35, _p$.e));
|
|
16351
|
+
_v$36 !== _p$.t && (_p$.t = setProp(_el$56, "attributes", _v$36, _p$.t));
|
|
15863
16352
|
return _p$;
|
|
15864
16353
|
}, {
|
|
15865
16354
|
e: undefined,
|
|
15866
16355
|
t: undefined
|
|
15867
16356
|
});
|
|
15868
|
-
return _el$
|
|
16357
|
+
return _el$56;
|
|
15869
16358
|
})()
|
|
15870
16359
|
}));
|
|
15871
16360
|
effect((_p$) => {
|
|
15872
|
-
var _v$
|
|
15873
|
-
_v$
|
|
15874
|
-
_v$
|
|
15875
|
-
_v$
|
|
15876
|
-
_v$
|
|
15877
|
-
_v$
|
|
16361
|
+
var _v$30 = left(), _v$31 = top(), _v$32 = boxW(), _v$33 = theme.focusAccent, _v$34 = theme.backgroundElement;
|
|
16362
|
+
_v$30 !== _p$.e && (_p$.e = setProp(_el$55, "left", _v$30, _p$.e));
|
|
16363
|
+
_v$31 !== _p$.t && (_p$.t = setProp(_el$55, "top", _v$31, _p$.t));
|
|
16364
|
+
_v$32 !== _p$.a && (_p$.a = setProp(_el$55, "width", _v$32, _p$.a));
|
|
16365
|
+
_v$33 !== _p$.o && (_p$.o = setProp(_el$55, "borderColor", _v$33, _p$.o));
|
|
16366
|
+
_v$34 !== _p$.i && (_p$.i = setProp(_el$55, "backgroundColor", _v$34, _p$.i));
|
|
15878
16367
|
return _p$;
|
|
15879
16368
|
}, {
|
|
15880
16369
|
e: undefined,
|
|
@@ -15883,31 +16372,27 @@ function Sidebar(props) {
|
|
|
15883
16372
|
o: undefined,
|
|
15884
16373
|
i: undefined
|
|
15885
16374
|
});
|
|
15886
|
-
return _el$
|
|
16375
|
+
return _el$55;
|
|
15887
16376
|
})();
|
|
15888
16377
|
}
|
|
15889
16378
|
}), null);
|
|
15890
16379
|
effect((_p$) => {
|
|
15891
|
-
var _v$
|
|
15892
|
-
_v$
|
|
15893
|
-
_v$
|
|
15894
|
-
_v$
|
|
15895
|
-
_v$
|
|
15896
|
-
_v$9 !== _p$.i && (_p$.i = setProp(_el$5, "attributes", _v$9, _p$.i));
|
|
15897
|
-
_v$0 !== _p$.n && (_p$.n = setProp(_el$23, "fg", _v$0, _p$.n));
|
|
16380
|
+
var _v$9 = props.width ? props.width() : SIDEBAR_WIDTH, _v$0 = focusedAccessor() ? theme.focusAccent : theme.textMuted, _v$1 = TextAttributes8.BOLD, _v$10 = theme.textMuted;
|
|
16381
|
+
_v$9 !== _p$.e && (_p$.e = setProp(_el$4, "width", _v$9, _p$.e));
|
|
16382
|
+
_v$0 !== _p$.t && (_p$.t = setProp(_el$6, "fg", _v$0, _p$.t));
|
|
16383
|
+
_v$1 !== _p$.a && (_p$.a = setProp(_el$6, "attributes", _v$1, _p$.a));
|
|
16384
|
+
_v$10 !== _p$.o && (_p$.o = setProp(_el$24, "fg", _v$10, _p$.o));
|
|
15898
16385
|
return _p$;
|
|
15899
16386
|
}, {
|
|
15900
16387
|
e: undefined,
|
|
15901
16388
|
t: undefined,
|
|
15902
16389
|
a: undefined,
|
|
15903
|
-
o: undefined
|
|
15904
|
-
i: undefined,
|
|
15905
|
-
n: undefined
|
|
16390
|
+
o: undefined
|
|
15906
16391
|
});
|
|
15907
|
-
return _el
|
|
16392
|
+
return _el$4;
|
|
15908
16393
|
})();
|
|
15909
16394
|
}
|
|
15910
|
-
var SIDEBAR_WIDTH = 32, STATUS_BADGE, IN_PROGRESS_SPINNER, SPINNER_FRAME_MS = 100, VIEW_TABS, MAIN_BRANCH_POLL_MS = 2000,
|
|
16395
|
+
var SIDEBAR_WIDTH = 32, STATUS_BADGE, STATUS_LABEL, IN_PROGRESS_SPINNER, SPINNER_FRAME_MS = 100, VIEW_TABS, MAIN_BRANCH_POLL_MS = 2000, BRANCH_LABEL_MAX = 16;
|
|
15911
16396
|
var init_Sidebar = __esm(() => {
|
|
15912
16397
|
init_solid();
|
|
15913
16398
|
init_solid();
|
|
@@ -15921,7 +16406,6 @@ var init_Sidebar = __esm(() => {
|
|
|
15921
16406
|
init_dev();
|
|
15922
16407
|
init_theme2();
|
|
15923
16408
|
init_theme2();
|
|
15924
|
-
init_git_head();
|
|
15925
16409
|
init_groups();
|
|
15926
16410
|
init_keys();
|
|
15927
16411
|
init_worktree_changes();
|
|
@@ -15951,6 +16435,14 @@ var init_Sidebar = __esm(() => {
|
|
|
15951
16435
|
tone: "error"
|
|
15952
16436
|
}
|
|
15953
16437
|
};
|
|
16438
|
+
STATUS_LABEL = {
|
|
16439
|
+
done: "done",
|
|
16440
|
+
in_review: "in review",
|
|
16441
|
+
in_progress: "working",
|
|
16442
|
+
backlog: "backlog",
|
|
16443
|
+
canceled: "canceled",
|
|
16444
|
+
error: "error"
|
|
16445
|
+
};
|
|
15954
16446
|
IN_PROGRESS_SPINNER = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
15955
16447
|
VIEW_TABS = [{
|
|
15956
16448
|
view: "active",
|
|
@@ -16056,7 +16548,18 @@ function TasksShell(props) {
|
|
|
16056
16548
|
return;
|
|
16057
16549
|
}
|
|
16058
16550
|
}
|
|
16059
|
-
SettingsDialog.show(dialog, kv, props.orch ?? undefined);
|
|
16551
|
+
const result = await SettingsDialog.show(dialog, kv, props.orch ?? undefined);
|
|
16552
|
+
if (!result.visualPrefsChanged)
|
|
16553
|
+
return;
|
|
16554
|
+
if (!kv.flush())
|
|
16555
|
+
return;
|
|
16556
|
+
try {
|
|
16557
|
+
const session = await currentSessionName();
|
|
16558
|
+
if (session)
|
|
16559
|
+
await refreshKobeWorkspacePanes(session);
|
|
16560
|
+
} catch (err) {
|
|
16561
|
+
console.error("[kobe tasks] failed to refresh workspace panes:", err);
|
|
16562
|
+
}
|
|
16060
16563
|
}
|
|
16061
16564
|
async function openUpdate() {
|
|
16062
16565
|
const info = updateInfo();
|
|
@@ -16291,6 +16794,18 @@ function TasksShell(props) {
|
|
|
16291
16794
|
await runTmux(["switch-client", "-t", `=${name}`]);
|
|
16292
16795
|
props.orch?.setActiveTask(id).catch(() => {});
|
|
16293
16796
|
}
|
|
16797
|
+
const headerStatus = createMemo(() => {
|
|
16798
|
+
const info = updateInfo();
|
|
16799
|
+
if (info?.hasUpdate)
|
|
16800
|
+
return {
|
|
16801
|
+
label: `v${info.latest} \u2191`,
|
|
16802
|
+
emphasize: true
|
|
16803
|
+
};
|
|
16804
|
+
return {
|
|
16805
|
+
label: `v${CURRENT_VERSION}`,
|
|
16806
|
+
emphasize: false
|
|
16807
|
+
};
|
|
16808
|
+
});
|
|
16294
16809
|
return (() => {
|
|
16295
16810
|
var _el$ = createElement("box"), _el$2 = createElement("box");
|
|
16296
16811
|
insertNode(_el$, _el$2);
|
|
@@ -16306,6 +16821,8 @@ function TasksShell(props) {
|
|
|
16306
16821
|
onSelect: setSelectedId,
|
|
16307
16822
|
onActivate: (id) => void switchTo(id),
|
|
16308
16823
|
activateOnClick: true,
|
|
16824
|
+
headerStatus,
|
|
16825
|
+
onHeaderStatusClick: () => void openUpdate(),
|
|
16309
16826
|
width: () => dimensions().width,
|
|
16310
16827
|
onAddTask: () => void createTask(),
|
|
16311
16828
|
onRenameRequest: (id) => void renameTask(id),
|
|
@@ -16313,24 +16830,15 @@ function TasksShell(props) {
|
|
|
16313
16830
|
onArchiveRequest: (id) => void archiveTask(id),
|
|
16314
16831
|
focused: () => dialog.stack.length === 0
|
|
16315
16832
|
}));
|
|
16316
|
-
insert(_el$, createComponent2(ShortcutHints, {
|
|
16317
|
-
updateInfo,
|
|
16318
|
-
onOpenUpdate: () => void openUpdate()
|
|
16319
|
-
}), null);
|
|
16833
|
+
insert(_el$, createComponent2(ShortcutHints, {}), null);
|
|
16320
16834
|
effect((_$p) => setProp(_el$, "backgroundColor", theme.background, _$p));
|
|
16321
16835
|
return _el$;
|
|
16322
16836
|
})();
|
|
16323
16837
|
}
|
|
16324
|
-
function ShortcutHints(
|
|
16838
|
+
function ShortcutHints() {
|
|
16325
16839
|
const {
|
|
16326
16840
|
theme
|
|
16327
16841
|
} = useTheme();
|
|
16328
|
-
const updateLabel = createMemo(() => {
|
|
16329
|
-
const info = props.updateInfo();
|
|
16330
|
-
if (!info)
|
|
16331
|
-
return `v${CURRENT_VERSION}`;
|
|
16332
|
-
return info.hasUpdate ? `v${info.latest} available` : `v${CURRENT_VERSION} latest`;
|
|
16333
|
-
});
|
|
16334
16842
|
const HINTS = [{
|
|
16335
16843
|
k: "\u23CE",
|
|
16336
16844
|
label: "open"
|
|
@@ -16380,111 +16888,63 @@ function ShortcutHints(props) {
|
|
|
16380
16888
|
k: "\u2303Q",
|
|
16381
16889
|
label: "detach"
|
|
16382
16890
|
}];
|
|
16891
|
+
const LABEL_COL_MAX = 18;
|
|
16892
|
+
const labelColWidth = Math.min(LABEL_COL_MAX, Math.max(...HINTS.map((h) => h.label.length)));
|
|
16893
|
+
const clipLabel = (s) => s.length <= labelColWidth ? s : `${s.slice(0, Math.max(0, labelColWidth - 1))}\u2026`;
|
|
16383
16894
|
return (() => {
|
|
16384
|
-
var _el$3 = createElement("box"), _el$4 = createElement("text")
|
|
16895
|
+
var _el$3 = createElement("box"), _el$4 = createElement("text");
|
|
16385
16896
|
insertNode(_el$3, _el$4);
|
|
16386
|
-
insertNode(_el$3, _el$6);
|
|
16387
|
-
insertNode(_el$3, _el$12);
|
|
16388
16897
|
setProp(_el$3, "flexShrink", 0);
|
|
16389
16898
|
setProp(_el$3, "flexDirection", "column");
|
|
16390
16899
|
setProp(_el$3, "paddingLeft", 1);
|
|
16391
16900
|
setProp(_el$3, "paddingRight", 1);
|
|
16392
16901
|
setProp(_el$3, "paddingTop", 1);
|
|
16393
16902
|
setProp(_el$3, "gap", 0);
|
|
16394
|
-
insertNode(_el$4, createTextNode(`\u2500\u2500
|
|
16903
|
+
insertNode(_el$4, createTextNode(`\u2500\u2500 keys \u2500\u2500`));
|
|
16395
16904
|
setProp(_el$4, "wrapMode", "none");
|
|
16396
|
-
insertNode(_el$6, _el$7);
|
|
16397
|
-
setProp(_el$6, "flexDirection", "row");
|
|
16398
|
-
setProp(_el$6, "gap", 1);
|
|
16399
|
-
setProp(_el$7, "wrapMode", "none");
|
|
16400
|
-
setProp(_el$7, "onMouseUp", () => {
|
|
16401
|
-
if (props.updateInfo()?.hasUpdate)
|
|
16402
|
-
props.onOpenUpdate();
|
|
16403
|
-
});
|
|
16404
|
-
insert(_el$7, updateLabel);
|
|
16405
|
-
insert(_el$3, createComponent2(Show, {
|
|
16406
|
-
get when() {
|
|
16407
|
-
return props.updateInfo()?.hasUpdate;
|
|
16408
|
-
},
|
|
16409
|
-
get children() {
|
|
16410
|
-
var _el$8 = createElement("box"), _el$9 = createElement("box"), _el$0 = createElement("text"), _el$10 = createElement("text");
|
|
16411
|
-
insertNode(_el$8, _el$9);
|
|
16412
|
-
insertNode(_el$8, _el$10);
|
|
16413
|
-
setProp(_el$8, "flexDirection", "row");
|
|
16414
|
-
setProp(_el$8, "gap", 1);
|
|
16415
|
-
setProp(_el$8, "onMouseUp", () => props.onOpenUpdate());
|
|
16416
|
-
insertNode(_el$9, _el$0);
|
|
16417
|
-
setProp(_el$9, "width", 10);
|
|
16418
|
-
setProp(_el$9, "flexShrink", 0);
|
|
16419
|
-
insertNode(_el$0, createTextNode(`[U]`));
|
|
16420
|
-
setProp(_el$0, "wrapMode", "none");
|
|
16421
|
-
insertNode(_el$10, createTextNode(`update page`));
|
|
16422
|
-
setProp(_el$10, "wrapMode", "none");
|
|
16423
|
-
effect((_p$) => {
|
|
16424
|
-
var _v$ = theme.accent, _v$2 = TextAttributes9.BOLD, _v$3 = theme.accent, _v$4 = TextAttributes9.DIM;
|
|
16425
|
-
_v$ !== _p$.e && (_p$.e = setProp(_el$0, "fg", _v$, _p$.e));
|
|
16426
|
-
_v$2 !== _p$.t && (_p$.t = setProp(_el$0, "attributes", _v$2, _p$.t));
|
|
16427
|
-
_v$3 !== _p$.a && (_p$.a = setProp(_el$10, "fg", _v$3, _p$.a));
|
|
16428
|
-
_v$4 !== _p$.o && (_p$.o = setProp(_el$10, "attributes", _v$4, _p$.o));
|
|
16429
|
-
return _p$;
|
|
16430
|
-
}, {
|
|
16431
|
-
e: undefined,
|
|
16432
|
-
t: undefined,
|
|
16433
|
-
a: undefined,
|
|
16434
|
-
o: undefined
|
|
16435
|
-
});
|
|
16436
|
-
return _el$8;
|
|
16437
|
-
}
|
|
16438
|
-
}), _el$12);
|
|
16439
|
-
insertNode(_el$12, createTextNode(`\u2500\u2500 keys \u2500\u2500`));
|
|
16440
|
-
setProp(_el$12, "wrapMode", "none");
|
|
16441
16905
|
insert(_el$3, createComponent2(For, {
|
|
16442
16906
|
each: HINTS,
|
|
16443
16907
|
children: (h) => (() => {
|
|
16444
|
-
var _el$
|
|
16445
|
-
insertNode(_el$
|
|
16446
|
-
insertNode(_el$
|
|
16447
|
-
setProp(_el$
|
|
16448
|
-
setProp(_el$
|
|
16449
|
-
|
|
16450
|
-
|
|
16451
|
-
setProp(_el$
|
|
16452
|
-
|
|
16453
|
-
insertNode(_el$
|
|
16454
|
-
|
|
16455
|
-
|
|
16456
|
-
|
|
16457
|
-
|
|
16908
|
+
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");
|
|
16909
|
+
insertNode(_el$6, _el$7);
|
|
16910
|
+
insertNode(_el$6, _el$1);
|
|
16911
|
+
setProp(_el$6, "flexDirection", "row");
|
|
16912
|
+
setProp(_el$6, "gap", 1);
|
|
16913
|
+
setProp(_el$6, "justifyContent", "space-between");
|
|
16914
|
+
insertNode(_el$7, _el$8);
|
|
16915
|
+
setProp(_el$7, "width", 10);
|
|
16916
|
+
setProp(_el$7, "flexShrink", 0);
|
|
16917
|
+
insertNode(_el$8, _el$9);
|
|
16918
|
+
insertNode(_el$8, _el$0);
|
|
16919
|
+
setProp(_el$8, "wrapMode", "none");
|
|
16920
|
+
insert(_el$8, () => h.k, _el$0);
|
|
16921
|
+
insertNode(_el$1, _el$10);
|
|
16922
|
+
setProp(_el$1, "width", labelColWidth);
|
|
16923
|
+
setProp(_el$1, "flexShrink", 0);
|
|
16924
|
+
setProp(_el$10, "wrapMode", "none");
|
|
16925
|
+
insert(_el$10, () => clipLabel(h.label));
|
|
16458
16926
|
effect((_p$) => {
|
|
16459
|
-
var _v$
|
|
16460
|
-
_v$
|
|
16461
|
-
_v$
|
|
16462
|
-
_v$
|
|
16927
|
+
var _v$3 = theme.accent, _v$4 = TextAttributes9.BOLD, _v$5 = theme.textMuted;
|
|
16928
|
+
_v$3 !== _p$.e && (_p$.e = setProp(_el$8, "fg", _v$3, _p$.e));
|
|
16929
|
+
_v$4 !== _p$.t && (_p$.t = setProp(_el$8, "attributes", _v$4, _p$.t));
|
|
16930
|
+
_v$5 !== _p$.a && (_p$.a = setProp(_el$10, "fg", _v$5, _p$.a));
|
|
16463
16931
|
return _p$;
|
|
16464
16932
|
}, {
|
|
16465
16933
|
e: undefined,
|
|
16466
16934
|
t: undefined,
|
|
16467
16935
|
a: undefined
|
|
16468
16936
|
});
|
|
16469
|
-
return _el$
|
|
16937
|
+
return _el$6;
|
|
16470
16938
|
})()
|
|
16471
16939
|
}), null);
|
|
16472
16940
|
effect((_p$) => {
|
|
16473
|
-
var _v$
|
|
16474
|
-
_v$
|
|
16475
|
-
_v$
|
|
16476
|
-
_v$7 !== _p$.a && (_p$.a = setProp(_el$7, "fg", _v$7, _p$.a));
|
|
16477
|
-
_v$8 !== _p$.o && (_p$.o = setProp(_el$7, "attributes", _v$8, _p$.o));
|
|
16478
|
-
_v$9 !== _p$.i && (_p$.i = setProp(_el$12, "fg", _v$9, _p$.i));
|
|
16479
|
-
_v$0 !== _p$.n && (_p$.n = setProp(_el$12, "attributes", _v$0, _p$.n));
|
|
16941
|
+
var _v$ = theme.textMuted, _v$2 = TextAttributes9.DIM;
|
|
16942
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$4, "fg", _v$, _p$.e));
|
|
16943
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$4, "attributes", _v$2, _p$.t));
|
|
16480
16944
|
return _p$;
|
|
16481
16945
|
}, {
|
|
16482
16946
|
e: undefined,
|
|
16483
|
-
t: undefined
|
|
16484
|
-
a: undefined,
|
|
16485
|
-
o: undefined,
|
|
16486
|
-
i: undefined,
|
|
16487
|
-
n: undefined
|
|
16947
|
+
t: undefined
|
|
16488
16948
|
});
|
|
16489
16949
|
return _el$3;
|
|
16490
16950
|
})();
|
|
@@ -16613,13 +17073,29 @@ function SettingsPage(props) {
|
|
|
16613
17073
|
const {
|
|
16614
17074
|
theme
|
|
16615
17075
|
} = themeCtx;
|
|
17076
|
+
let visualPrefsChanged = false;
|
|
17077
|
+
let exiting = false;
|
|
16616
17078
|
onMount(() => {
|
|
16617
17079
|
themeCtx.setTransparentBackground(props.transparent);
|
|
16618
17080
|
if (props.focusAccent)
|
|
16619
17081
|
themeCtx.setFocusAccent(props.focusAccent);
|
|
16620
17082
|
});
|
|
16621
|
-
function exit() {
|
|
16622
|
-
|
|
17083
|
+
async function exit() {
|
|
17084
|
+
if (exiting)
|
|
17085
|
+
return;
|
|
17086
|
+
exiting = true;
|
|
17087
|
+
try {
|
|
17088
|
+
const flushed = kv.flush();
|
|
17089
|
+
if (flushed && visualPrefsChanged) {
|
|
17090
|
+
const session = await currentSessionName();
|
|
17091
|
+
if (session)
|
|
17092
|
+
await refreshKobeWorkspacePanes(session);
|
|
17093
|
+
}
|
|
17094
|
+
} catch (err) {
|
|
17095
|
+
console.error("[kobe settings] failed to refresh workspace panes:", err);
|
|
17096
|
+
} finally {
|
|
17097
|
+
process.exit(0);
|
|
17098
|
+
}
|
|
16623
17099
|
}
|
|
16624
17100
|
useBindings(() => ({
|
|
16625
17101
|
enabled: dialog.stack.length === 0,
|
|
@@ -16635,15 +17111,23 @@ function SettingsPage(props) {
|
|
|
16635
17111
|
}]
|
|
16636
17112
|
}));
|
|
16637
17113
|
return (() => {
|
|
16638
|
-
var _el$ = createElement("
|
|
16639
|
-
setProp(_el$, "flexDirection", "column");
|
|
17114
|
+
var _el$ = createElement("scrollbox");
|
|
16640
17115
|
setProp(_el$, "flexGrow", 1);
|
|
16641
17116
|
setProp(_el$, "paddingTop", 1);
|
|
17117
|
+
setProp(_el$, "verticalScrollbarOptions", {
|
|
17118
|
+
trackOptions: {
|
|
17119
|
+
foregroundColor: "transparent"
|
|
17120
|
+
}
|
|
17121
|
+
});
|
|
16642
17122
|
insert(_el$, createComponent2(SettingsDialog, {
|
|
16643
17123
|
kv,
|
|
16644
17124
|
get orchestrator() {
|
|
16645
17125
|
return props.orchestrator ?? undefined;
|
|
16646
17126
|
},
|
|
17127
|
+
standalone: true,
|
|
17128
|
+
onVisualPrefsChange: () => {
|
|
17129
|
+
visualPrefsChanged = true;
|
|
17130
|
+
},
|
|
16647
17131
|
onClose: exit
|
|
16648
17132
|
}));
|
|
16649
17133
|
effect((_$p) => setProp(_el$, "backgroundColor", theme.background, _$p));
|
|
@@ -16726,6 +17210,7 @@ var init_host2 = __esm(() => {
|
|
|
16726
17210
|
init_loader();
|
|
16727
17211
|
init_keymap();
|
|
16728
17212
|
init_persisted_ui_prefs();
|
|
17213
|
+
init_tmux();
|
|
16729
17214
|
init_dialog();
|
|
16730
17215
|
});
|
|
16731
17216
|
|
|
@@ -16870,7 +17355,7 @@ var exports_host4 = {};
|
|
|
16870
17355
|
__export(exports_host4, {
|
|
16871
17356
|
startUpdateHost: () => startUpdateHost
|
|
16872
17357
|
});
|
|
16873
|
-
import { spawn as spawn4, spawnSync as
|
|
17358
|
+
import { spawn as spawn4, spawnSync as spawnSync8 } from "child_process";
|
|
16874
17359
|
import { TextAttributes as TextAttributes10 } from "@opentui/core";
|
|
16875
17360
|
function openExternalUrl(url) {
|
|
16876
17361
|
if (!url)
|
|
@@ -16976,7 +17461,7 @@ kobe ${CURRENT_VERSION} -> latest
|
|
|
16976
17461
|
process.stdout.write(`running: ${UPDATE_COMMAND}
|
|
16977
17462
|
|
|
16978
17463
|
`);
|
|
16979
|
-
const result =
|
|
17464
|
+
const result = spawnSync8("sh", ["-c", UPDATE_COMMAND], {
|
|
16980
17465
|
stdio: "inherit"
|
|
16981
17466
|
});
|
|
16982
17467
|
const code = result.status ?? (result.error ? 1 : 0);
|
|
@@ -17423,6 +17908,63 @@ var init_activity = __esm(() => {
|
|
|
17423
17908
|
init_history3();
|
|
17424
17909
|
});
|
|
17425
17910
|
|
|
17911
|
+
// src/tmux/editor-launch.ts
|
|
17912
|
+
function firstToken(cmd) {
|
|
17913
|
+
return cmd.trim().split(/\s+/)[0] ?? "";
|
|
17914
|
+
}
|
|
17915
|
+
function buildEditorCommand(kind, customCommand, absPath, envEditor) {
|
|
17916
|
+
const file = shellQuote(absPath);
|
|
17917
|
+
if (kind === "vim")
|
|
17918
|
+
return { bin: "vim", command: `vim ${file}` };
|
|
17919
|
+
if (kind === "nano")
|
|
17920
|
+
return { bin: "nano", command: `nano ${file}` };
|
|
17921
|
+
const tmpl = (customCommand.trim() || (envEditor ?? "").trim()).trim();
|
|
17922
|
+
if (!tmpl)
|
|
17923
|
+
return null;
|
|
17924
|
+
const bin = firstToken(tmpl);
|
|
17925
|
+
if (!bin)
|
|
17926
|
+
return null;
|
|
17927
|
+
const command = tmpl.includes(FILE_PLACEHOLDER) ? tmpl.split(FILE_PLACEHOLDER).join(file) : `${tmpl} ${file}`;
|
|
17928
|
+
return { bin, command };
|
|
17929
|
+
}
|
|
17930
|
+
function resolveEditorCommand(absPath) {
|
|
17931
|
+
const kind = normalizeEditorKind(getPersistedString(EDITOR_KIND_KEY));
|
|
17932
|
+
const custom = getPersistedString(EDITOR_CUSTOM_KEY) ?? "";
|
|
17933
|
+
const env = process.env.VISUAL ?? process.env.EDITOR ?? "";
|
|
17934
|
+
return buildEditorCommand(kind, custom, absPath, env);
|
|
17935
|
+
}
|
|
17936
|
+
async function binaryAvailable(bin) {
|
|
17937
|
+
try {
|
|
17938
|
+
const proc = Bun.spawn(["sh", "-c", `command -v ${shellQuote(bin)} >/dev/null 2>&1`], {
|
|
17939
|
+
stdin: "ignore",
|
|
17940
|
+
stdout: "ignore",
|
|
17941
|
+
stderr: "ignore"
|
|
17942
|
+
});
|
|
17943
|
+
return await proc.exited === 0;
|
|
17944
|
+
} catch {
|
|
17945
|
+
return false;
|
|
17946
|
+
}
|
|
17947
|
+
}
|
|
17948
|
+
async function openInEditor(session, worktree, absPath) {
|
|
17949
|
+
const resolved = resolveEditorCommand(absPath);
|
|
17950
|
+
if (!resolved)
|
|
17951
|
+
return false;
|
|
17952
|
+
if (!await binaryAvailable(resolved.bin))
|
|
17953
|
+
return false;
|
|
17954
|
+
await newWindow(session, { cwd: worktree, command: resolved.command, name: editorWindowLabel(absPath) });
|
|
17955
|
+
return true;
|
|
17956
|
+
}
|
|
17957
|
+
function editorWindowLabel(absPath) {
|
|
17958
|
+
const base = absPath.slice(absPath.lastIndexOf("/") + 1).trim();
|
|
17959
|
+
return base.length > 0 ? base : "edit";
|
|
17960
|
+
}
|
|
17961
|
+
var FILE_PLACEHOLDER = "{file}";
|
|
17962
|
+
var init_editor_launch = __esm(() => {
|
|
17963
|
+
init_repos();
|
|
17964
|
+
init_editor_prefs();
|
|
17965
|
+
init_client2();
|
|
17966
|
+
});
|
|
17967
|
+
|
|
17426
17968
|
// src/tui/panes/filetree/git.ts
|
|
17427
17969
|
import { spawn as nodeSpawn } from "child_process";
|
|
17428
17970
|
async function runGit(args, cwd) {
|
|
@@ -17577,7 +18119,8 @@ var init_git2 = __esm(() => {
|
|
|
17577
18119
|
const child = nodeSpawn("git", [...args], {
|
|
17578
18120
|
cwd,
|
|
17579
18121
|
shell: false,
|
|
17580
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
18122
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
18123
|
+
env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" }
|
|
17581
18124
|
});
|
|
17582
18125
|
let stdout = "";
|
|
17583
18126
|
let stderr = "";
|
|
@@ -17628,6 +18171,7 @@ function useFileTreeBindings(opts) {
|
|
|
17628
18171
|
opts.setTab(next);
|
|
17629
18172
|
},
|
|
17630
18173
|
"files.open": () => opts.openCurrent(),
|
|
18174
|
+
"files.edit": () => opts.editCurrent?.(),
|
|
17631
18175
|
"files.mention": () => opts.mentionCurrent?.(),
|
|
17632
18176
|
"files.createPR": () => opts.createPR?.(),
|
|
17633
18177
|
"files.openExternal": () => opts.openExternal(),
|
|
@@ -17722,10 +18266,16 @@ function summarizeGitError(raw) {
|
|
|
17722
18266
|
return raw.slice(colon + 2).trim() || "git command failed";
|
|
17723
18267
|
return raw.trim() || "git command failed";
|
|
17724
18268
|
}
|
|
18269
|
+
function truncatePathTail2(path11, max) {
|
|
18270
|
+
if (max <= 0 || path11.length <= max)
|
|
18271
|
+
return path11;
|
|
18272
|
+
return `\u2026${path11.slice(path11.length - Math.max(0, max - 1))}`;
|
|
18273
|
+
}
|
|
17725
18274
|
function FileTree(props) {
|
|
17726
18275
|
const {
|
|
17727
18276
|
theme
|
|
17728
18277
|
} = useTheme();
|
|
18278
|
+
const dims = useTerminalDimensions();
|
|
17729
18279
|
const focusedAccessor = () => props.focused ? props.focused() : true;
|
|
17730
18280
|
const [tab, setTab] = createSignal("all");
|
|
17731
18281
|
const [cursorIndex, setCursorIndex] = createSignal(0);
|
|
@@ -17890,6 +18440,11 @@ function FileTree(props) {
|
|
|
17890
18440
|
deleted
|
|
17891
18441
|
};
|
|
17892
18442
|
});
|
|
18443
|
+
const pathBudget = createMemo(() => {
|
|
18444
|
+
const w = statWidths();
|
|
18445
|
+
const stats = (w.added > 0 ? w.added + 1 : 0) + (w.deleted > 0 ? w.deleted + 1 : 0);
|
|
18446
|
+
return Math.max(8, dims().width - 6 - stats);
|
|
18447
|
+
});
|
|
17893
18448
|
function moveDown() {
|
|
17894
18449
|
const r = rows();
|
|
17895
18450
|
if (r.length === 0)
|
|
@@ -17982,6 +18537,16 @@ function FileTree(props) {
|
|
|
17982
18537
|
return;
|
|
17983
18538
|
props.onMention?.(row.path);
|
|
17984
18539
|
}
|
|
18540
|
+
function editCurrent() {
|
|
18541
|
+
const r = rows();
|
|
18542
|
+
const i = cursorIndex();
|
|
18543
|
+
if (i < 0 || i >= r.length)
|
|
18544
|
+
return;
|
|
18545
|
+
const row = r[i];
|
|
18546
|
+
if (!row || row.kind === "dir")
|
|
18547
|
+
return;
|
|
18548
|
+
props.onEditFile?.(row.path);
|
|
18549
|
+
}
|
|
17985
18550
|
function refresh() {
|
|
17986
18551
|
setRefreshTick((n) => n + 1);
|
|
17987
18552
|
props.onRefresh?.();
|
|
@@ -18008,6 +18573,7 @@ function FileTree(props) {
|
|
|
18008
18573
|
currentTab: tab,
|
|
18009
18574
|
openCurrent,
|
|
18010
18575
|
mentionCurrent,
|
|
18576
|
+
editCurrent,
|
|
18011
18577
|
createPR: props.onCreatePR,
|
|
18012
18578
|
openExternal,
|
|
18013
18579
|
refresh,
|
|
@@ -18044,8 +18610,8 @@ function FileTree(props) {
|
|
|
18044
18610
|
setProp(_el$, "flexGrow", 1);
|
|
18045
18611
|
setProp(_el$, "paddingTop", 1);
|
|
18046
18612
|
setProp(_el$, "paddingBottom", 1);
|
|
18047
|
-
setProp(_el$, "paddingLeft",
|
|
18048
|
-
setProp(_el$, "paddingRight",
|
|
18613
|
+
setProp(_el$, "paddingLeft", 0);
|
|
18614
|
+
setProp(_el$, "paddingRight", 0);
|
|
18049
18615
|
insert(_el$, createComponent2(Show, {
|
|
18050
18616
|
get when() {
|
|
18051
18617
|
return props.onCreatePR;
|
|
@@ -18092,20 +18658,20 @@ function FileTree(props) {
|
|
|
18092
18658
|
children: (t) => {
|
|
18093
18659
|
const isActive = () => tab() === t;
|
|
18094
18660
|
return (() => {
|
|
18095
|
-
var _el$
|
|
18096
|
-
setProp(_el$
|
|
18097
|
-
setProp(_el$
|
|
18098
|
-
insert(_el$
|
|
18661
|
+
var _el$26 = createElement("text");
|
|
18662
|
+
setProp(_el$26, "wrapMode", "none");
|
|
18663
|
+
setProp(_el$26, "onMouseUp", () => setTab(t));
|
|
18664
|
+
insert(_el$26, () => TAB_LABEL[t]);
|
|
18099
18665
|
effect((_p$) => {
|
|
18100
18666
|
var _v$6 = isActive() ? theme.primary : theme.textMuted, _v$7 = isActive() ? TextAttributes11.BOLD : undefined;
|
|
18101
|
-
_v$6 !== _p$.e && (_p$.e = setProp(_el$
|
|
18102
|
-
_v$7 !== _p$.t && (_p$.t = setProp(_el$
|
|
18667
|
+
_v$6 !== _p$.e && (_p$.e = setProp(_el$26, "fg", _v$6, _p$.e));
|
|
18668
|
+
_v$7 !== _p$.t && (_p$.t = setProp(_el$26, "attributes", _v$7, _p$.t));
|
|
18103
18669
|
return _p$;
|
|
18104
18670
|
}, {
|
|
18105
18671
|
e: undefined,
|
|
18106
18672
|
t: undefined
|
|
18107
18673
|
});
|
|
18108
|
-
return _el$
|
|
18674
|
+
return _el$26;
|
|
18109
18675
|
})();
|
|
18110
18676
|
}
|
|
18111
18677
|
}));
|
|
@@ -18114,19 +18680,19 @@ function FileTree(props) {
|
|
|
18114
18680
|
return props.cornerBadge?.();
|
|
18115
18681
|
},
|
|
18116
18682
|
children: (badge) => (() => {
|
|
18117
|
-
var _el$
|
|
18118
|
-
setProp(_el$
|
|
18119
|
-
insert(_el$
|
|
18683
|
+
var _el$27 = createElement("text");
|
|
18684
|
+
setProp(_el$27, "wrapMode", "none");
|
|
18685
|
+
insert(_el$27, () => badge().text);
|
|
18120
18686
|
effect((_p$) => {
|
|
18121
18687
|
var _v$8 = badge().active ? theme.accent : theme.textMuted, _v$9 = badge().active ? TextAttributes11.BOLD : undefined;
|
|
18122
|
-
_v$8 !== _p$.e && (_p$.e = setProp(_el$
|
|
18123
|
-
_v$9 !== _p$.t && (_p$.t = setProp(_el$
|
|
18688
|
+
_v$8 !== _p$.e && (_p$.e = setProp(_el$27, "fg", _v$8, _p$.e));
|
|
18689
|
+
_v$9 !== _p$.t && (_p$.t = setProp(_el$27, "attributes", _v$9, _p$.t));
|
|
18124
18690
|
return _p$;
|
|
18125
18691
|
}, {
|
|
18126
18692
|
e: undefined,
|
|
18127
18693
|
t: undefined
|
|
18128
18694
|
});
|
|
18129
|
-
return _el$
|
|
18695
|
+
return _el$27;
|
|
18130
18696
|
})()
|
|
18131
18697
|
}), null);
|
|
18132
18698
|
insert(_el$, createComponent2(Show, {
|
|
@@ -18238,15 +18804,23 @@ function FileTree(props) {
|
|
|
18238
18804
|
},
|
|
18239
18805
|
children: (row, index) => {
|
|
18240
18806
|
const isCursor = () => index() === cursorIndex();
|
|
18807
|
+
const bar = (() => {
|
|
18808
|
+
var _el$28 = createElement("text");
|
|
18809
|
+
setProp(_el$28, "wrapMode", "none");
|
|
18810
|
+
insert(_el$28, () => isCursor() ? "\u258C" : " ");
|
|
18811
|
+
effect((_$p) => setProp(_el$28, "fg", isCursor() ? theme.focusAccent : undefined, _$p));
|
|
18812
|
+
return _el$28;
|
|
18813
|
+
})();
|
|
18814
|
+
const rowBg = () => isCursor() ? theme.backgroundElement : undefined;
|
|
18241
18815
|
if (row.kind === "dir") {
|
|
18242
18816
|
const indent = " ".repeat(row.depth);
|
|
18243
18817
|
const marker = row.expanded ? "\u25BE" : "\u25B8";
|
|
18244
18818
|
return (() => {
|
|
18245
|
-
var _el$
|
|
18246
|
-
insertNode(_el$
|
|
18247
|
-
setProp(_el$
|
|
18248
|
-
setProp(_el$
|
|
18249
|
-
setProp(_el$
|
|
18819
|
+
var _el$29 = createElement("box"), _el$30 = createElement("box"), _el$31 = createElement("text");
|
|
18820
|
+
insertNode(_el$29, _el$30);
|
|
18821
|
+
setProp(_el$29, "flexDirection", "row");
|
|
18822
|
+
setProp(_el$29, "gap", 0);
|
|
18823
|
+
setProp(_el$29, "onMouseUp", () => {
|
|
18250
18824
|
setCursorIndex(index());
|
|
18251
18825
|
setExpandedDirs((prev) => {
|
|
18252
18826
|
const next = new Set(prev);
|
|
@@ -18257,45 +18831,53 @@ function FileTree(props) {
|
|
|
18257
18831
|
return next;
|
|
18258
18832
|
});
|
|
18259
18833
|
});
|
|
18260
|
-
|
|
18261
|
-
|
|
18834
|
+
insert(_el$29, bar, _el$30);
|
|
18835
|
+
insertNode(_el$30, _el$31);
|
|
18836
|
+
setProp(_el$30, "flexGrow", 1);
|
|
18837
|
+
setProp(_el$30, "paddingRight", 1);
|
|
18838
|
+
setProp(_el$31, "wrapMode", "none");
|
|
18839
|
+
insert(_el$31, () => `${indent}${marker} ${row.name}/`);
|
|
18262
18840
|
effect((_p$) => {
|
|
18263
|
-
var _v$0 =
|
|
18264
|
-
_v$0 !== _p$.e && (_p$.e = setProp(_el$
|
|
18265
|
-
_v$1 !== _p$.t && (_p$.t = setProp(_el$
|
|
18266
|
-
_v$10 !== _p$.a && (_p$.a = setProp(_el$
|
|
18841
|
+
var _v$0 = rowBg(), _v$1 = theme.textMuted, _v$10 = TextAttributes11.BOLD;
|
|
18842
|
+
_v$0 !== _p$.e && (_p$.e = setProp(_el$29, "backgroundColor", _v$0, _p$.e));
|
|
18843
|
+
_v$1 !== _p$.t && (_p$.t = setProp(_el$31, "fg", _v$1, _p$.t));
|
|
18844
|
+
_v$10 !== _p$.a && (_p$.a = setProp(_el$31, "attributes", _v$10, _p$.a));
|
|
18267
18845
|
return _p$;
|
|
18268
18846
|
}, {
|
|
18269
18847
|
e: undefined,
|
|
18270
18848
|
t: undefined,
|
|
18271
18849
|
a: undefined
|
|
18272
18850
|
});
|
|
18273
|
-
return _el$
|
|
18851
|
+
return _el$29;
|
|
18274
18852
|
})();
|
|
18275
18853
|
}
|
|
18276
18854
|
if (row.kind === "file") {
|
|
18277
18855
|
const indent = " ".repeat(row.depth);
|
|
18278
18856
|
return (() => {
|
|
18279
|
-
var _el$
|
|
18280
|
-
insertNode(_el$
|
|
18281
|
-
setProp(_el$
|
|
18282
|
-
setProp(_el$
|
|
18283
|
-
setProp(_el$
|
|
18857
|
+
var _el$32 = createElement("box"), _el$33 = createElement("box"), _el$34 = createElement("text");
|
|
18858
|
+
insertNode(_el$32, _el$33);
|
|
18859
|
+
setProp(_el$32, "flexDirection", "row");
|
|
18860
|
+
setProp(_el$32, "gap", 0);
|
|
18861
|
+
setProp(_el$32, "onMouseUp", () => {
|
|
18284
18862
|
setCursorIndex(index());
|
|
18285
18863
|
props.onOpenFile(row.path);
|
|
18286
18864
|
});
|
|
18287
|
-
|
|
18288
|
-
|
|
18865
|
+
insert(_el$32, bar, _el$33);
|
|
18866
|
+
insertNode(_el$33, _el$34);
|
|
18867
|
+
setProp(_el$33, "flexGrow", 1);
|
|
18868
|
+
setProp(_el$33, "paddingRight", 1);
|
|
18869
|
+
setProp(_el$34, "wrapMode", "none");
|
|
18870
|
+
insert(_el$34, () => `${indent} ${row.name}`);
|
|
18289
18871
|
effect((_p$) => {
|
|
18290
|
-
var _v$11 =
|
|
18291
|
-
_v$11 !== _p$.e && (_p$.e = setProp(_el$
|
|
18292
|
-
_v$12 !== _p$.t && (_p$.t = setProp(_el$
|
|
18872
|
+
var _v$11 = rowBg(), _v$12 = theme.text;
|
|
18873
|
+
_v$11 !== _p$.e && (_p$.e = setProp(_el$32, "backgroundColor", _v$11, _p$.e));
|
|
18874
|
+
_v$12 !== _p$.t && (_p$.t = setProp(_el$34, "fg", _v$12, _p$.t));
|
|
18293
18875
|
return _p$;
|
|
18294
18876
|
}, {
|
|
18295
18877
|
e: undefined,
|
|
18296
18878
|
t: undefined
|
|
18297
18879
|
});
|
|
18298
|
-
return _el$
|
|
18880
|
+
return _el$32;
|
|
18299
18881
|
})();
|
|
18300
18882
|
}
|
|
18301
18883
|
const tone = statusToken(row.status);
|
|
@@ -18317,64 +18899,84 @@ function FileTree(props) {
|
|
|
18317
18899
|
const addedText = row.added == null ? " ".repeat(w.added) : `+${row.added}`.padStart(w.added);
|
|
18318
18900
|
const deletedText = row.deleted == null ? " ".repeat(w.deleted) : `-${row.deleted}`.padStart(w.deleted);
|
|
18319
18901
|
return (() => {
|
|
18320
|
-
var _el$
|
|
18321
|
-
insertNode(_el$
|
|
18322
|
-
|
|
18323
|
-
setProp(_el$
|
|
18324
|
-
setProp(_el$
|
|
18325
|
-
setProp(_el$29, "paddingLeft", 1);
|
|
18326
|
-
setProp(_el$29, "paddingRight", 1);
|
|
18327
|
-
setProp(_el$29, "onMouseUp", () => {
|
|
18902
|
+
var _el$35 = createElement("box"), _el$36 = createElement("box"), _el$37 = createElement("text"), _el$38 = createElement("text");
|
|
18903
|
+
insertNode(_el$35, _el$36);
|
|
18904
|
+
setProp(_el$35, "flexDirection", "row");
|
|
18905
|
+
setProp(_el$35, "gap", 0);
|
|
18906
|
+
setProp(_el$35, "onMouseUp", () => {
|
|
18328
18907
|
setCursorIndex(index());
|
|
18329
18908
|
props.onOpenFile(row.path);
|
|
18330
18909
|
});
|
|
18331
|
-
|
|
18332
|
-
|
|
18333
|
-
|
|
18334
|
-
setProp(_el$
|
|
18335
|
-
|
|
18336
|
-
|
|
18910
|
+
insert(_el$35, bar, _el$36);
|
|
18911
|
+
insertNode(_el$36, _el$37);
|
|
18912
|
+
insertNode(_el$36, _el$38);
|
|
18913
|
+
setProp(_el$36, "flexDirection", "row");
|
|
18914
|
+
setProp(_el$36, "flexGrow", 1);
|
|
18915
|
+
setProp(_el$36, "gap", 1);
|
|
18916
|
+
setProp(_el$36, "paddingRight", 1);
|
|
18917
|
+
setProp(_el$37, "wrapMode", "none");
|
|
18918
|
+
insert(_el$37, () => row.status);
|
|
18919
|
+
setProp(_el$38, "wrapMode", "none");
|
|
18920
|
+
setProp(_el$38, "flexGrow", 1);
|
|
18921
|
+
insert(_el$38, () => truncatePathTail2(row.path, pathBudget()));
|
|
18922
|
+
insert(_el$36, createComponent2(Show, {
|
|
18337
18923
|
get when() {
|
|
18338
18924
|
return w.added > 0;
|
|
18339
18925
|
},
|
|
18340
18926
|
get children() {
|
|
18341
|
-
var _el$
|
|
18342
|
-
setProp(_el$
|
|
18343
|
-
insert(_el$
|
|
18344
|
-
effect((_$p) => setProp(_el$
|
|
18345
|
-
return _el$
|
|
18927
|
+
var _el$39 = createElement("text");
|
|
18928
|
+
setProp(_el$39, "wrapMode", "none");
|
|
18929
|
+
insert(_el$39, addedText);
|
|
18930
|
+
effect((_$p) => setProp(_el$39, "fg", theme.success, _$p));
|
|
18931
|
+
return _el$39;
|
|
18346
18932
|
}
|
|
18347
18933
|
}), null);
|
|
18348
|
-
insert(_el$
|
|
18934
|
+
insert(_el$36, createComponent2(Show, {
|
|
18349
18935
|
get when() {
|
|
18350
18936
|
return w.deleted > 0;
|
|
18351
18937
|
},
|
|
18352
18938
|
get children() {
|
|
18353
|
-
var _el$
|
|
18354
|
-
setProp(_el$
|
|
18355
|
-
insert(_el$
|
|
18356
|
-
effect((_$p) => setProp(_el$
|
|
18357
|
-
return _el$
|
|
18939
|
+
var _el$40 = createElement("text");
|
|
18940
|
+
setProp(_el$40, "wrapMode", "none");
|
|
18941
|
+
insert(_el$40, deletedText);
|
|
18942
|
+
effect((_$p) => setProp(_el$40, "fg", theme.error, _$p));
|
|
18943
|
+
return _el$40;
|
|
18358
18944
|
}
|
|
18359
18945
|
}), null);
|
|
18360
18946
|
effect((_p$) => {
|
|
18361
|
-
var _v$13 =
|
|
18362
|
-
_v$13 !== _p$.e && (_p$.e = setProp(_el$
|
|
18363
|
-
_v$14 !== _p$.t && (_p$.t = setProp(_el$
|
|
18364
|
-
_v$15 !== _p$.a && (_p$.a = setProp(_el$
|
|
18947
|
+
var _v$13 = rowBg(), _v$14 = statusColor(), _v$15 = theme.text;
|
|
18948
|
+
_v$13 !== _p$.e && (_p$.e = setProp(_el$35, "backgroundColor", _v$13, _p$.e));
|
|
18949
|
+
_v$14 !== _p$.t && (_p$.t = setProp(_el$37, "fg", _v$14, _p$.t));
|
|
18950
|
+
_v$15 !== _p$.a && (_p$.a = setProp(_el$38, "fg", _v$15, _p$.a));
|
|
18365
18951
|
return _p$;
|
|
18366
18952
|
}, {
|
|
18367
18953
|
e: undefined,
|
|
18368
18954
|
t: undefined,
|
|
18369
18955
|
a: undefined
|
|
18370
18956
|
});
|
|
18371
|
-
return _el$
|
|
18957
|
+
return _el$35;
|
|
18372
18958
|
})();
|
|
18373
18959
|
}
|
|
18374
18960
|
}));
|
|
18375
18961
|
return _el$22;
|
|
18376
18962
|
}
|
|
18377
18963
|
}), null);
|
|
18964
|
+
insert(_el$, createComponent2(Show, {
|
|
18965
|
+
get when() {
|
|
18966
|
+
return props.worktreePath() != null;
|
|
18967
|
+
},
|
|
18968
|
+
get children() {
|
|
18969
|
+
var _el$23 = createElement("box"), _el$24 = createElement("text");
|
|
18970
|
+
insertNode(_el$23, _el$24);
|
|
18971
|
+
setProp(_el$23, "flexDirection", "row");
|
|
18972
|
+
setProp(_el$23, "paddingTop", 1);
|
|
18973
|
+
setProp(_el$23, "flexShrink", 0);
|
|
18974
|
+
insertNode(_el$24, createTextNode(`\u21B5 preview \xB7 e edit`));
|
|
18975
|
+
setProp(_el$24, "wrapMode", "none");
|
|
18976
|
+
effect((_$p) => setProp(_el$24, "fg", theme.textMuted, _$p));
|
|
18977
|
+
return _el$23;
|
|
18978
|
+
}
|
|
18979
|
+
}), null);
|
|
18378
18980
|
return _el$;
|
|
18379
18981
|
})();
|
|
18380
18982
|
}
|
|
@@ -18389,6 +18991,7 @@ var init_FileTree = __esm(() => {
|
|
|
18389
18991
|
init_solid();
|
|
18390
18992
|
init_solid();
|
|
18391
18993
|
init_solid();
|
|
18994
|
+
init_solid();
|
|
18392
18995
|
init_dev();
|
|
18393
18996
|
init_theme2();
|
|
18394
18997
|
init_git2();
|
|
@@ -18409,15 +19012,16 @@ var init_filetree = __esm(() => {
|
|
|
18409
19012
|
});
|
|
18410
19013
|
|
|
18411
19014
|
// src/tui/ops/pr-prompt.ts
|
|
18412
|
-
import { spawnSync as
|
|
19015
|
+
import { spawnSync as spawnSync9 } from "child_process";
|
|
18413
19016
|
import { promises as fs4 } from "fs";
|
|
18414
19017
|
import path11 from "path";
|
|
18415
19018
|
function git2(cwd, args) {
|
|
18416
19019
|
try {
|
|
18417
|
-
const out =
|
|
19020
|
+
const out = spawnSync9("git", args.slice(), {
|
|
18418
19021
|
cwd,
|
|
18419
19022
|
encoding: "utf8",
|
|
18420
|
-
timeout: GIT_TIMEOUT_MS
|
|
19023
|
+
timeout: GIT_TIMEOUT_MS,
|
|
19024
|
+
env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" }
|
|
18421
19025
|
});
|
|
18422
19026
|
if (out.error)
|
|
18423
19027
|
return null;
|
|
@@ -18618,6 +19222,17 @@ function OpsShell(props) {
|
|
|
18618
19222
|
name: basename5(rel)
|
|
18619
19223
|
});
|
|
18620
19224
|
}
|
|
19225
|
+
function openEditor(rel) {
|
|
19226
|
+
if (!props.taskId) {
|
|
19227
|
+
openPreview(rel);
|
|
19228
|
+
return;
|
|
19229
|
+
}
|
|
19230
|
+
const abs = `${props.worktree}/${rel}`;
|
|
19231
|
+
openInEditor(tmuxSessionName(props.taskId), props.worktree, abs).then((launched) => {
|
|
19232
|
+
if (!launched)
|
|
19233
|
+
openPreview(rel);
|
|
19234
|
+
});
|
|
19235
|
+
}
|
|
18621
19236
|
function injectMention(rel) {
|
|
18622
19237
|
if (!props.targetPane)
|
|
18623
19238
|
return;
|
|
@@ -18638,6 +19253,7 @@ function OpsShell(props) {
|
|
|
18638
19253
|
worktreePath: () => props.worktree,
|
|
18639
19254
|
focused: () => true,
|
|
18640
19255
|
onOpenFile: openPreview,
|
|
19256
|
+
onEditFile: openEditor,
|
|
18641
19257
|
onMention: injectMention,
|
|
18642
19258
|
onCreatePR: () => void createPR(),
|
|
18643
19259
|
cornerBadge,
|
|
@@ -18713,7 +19329,11 @@ async function gitDiff(worktree, relPath) {
|
|
|
18713
19329
|
cwd: worktree,
|
|
18714
19330
|
stdin: "ignore",
|
|
18715
19331
|
stdout: "pipe",
|
|
18716
|
-
stderr: "ignore"
|
|
19332
|
+
stderr: "ignore",
|
|
19333
|
+
env: {
|
|
19334
|
+
...process.env,
|
|
19335
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
19336
|
+
}
|
|
18717
19337
|
});
|
|
18718
19338
|
const text = await new Response(proc.stdout).text();
|
|
18719
19339
|
await proc.exited;
|
|
@@ -18940,6 +19560,7 @@ var init_host5 = __esm(() => {
|
|
|
18940
19560
|
init_turn_detector();
|
|
18941
19561
|
init_activity();
|
|
18942
19562
|
init_client2();
|
|
19563
|
+
init_editor_launch();
|
|
18943
19564
|
init_solid();
|
|
18944
19565
|
init_dev();
|
|
18945
19566
|
init_theme2();
|
|
@@ -19855,7 +20476,7 @@ function repoBasename2(repo) {
|
|
|
19855
20476
|
}
|
|
19856
20477
|
|
|
19857
20478
|
// src/tui/component/top-bar.tsx
|
|
19858
|
-
import { spawnSync as
|
|
20479
|
+
import { spawnSync as spawnSync10 } from "child_process";
|
|
19859
20480
|
import { TextAttributes as TextAttributes16 } from "@opentui/core";
|
|
19860
20481
|
function TopBar(props) {
|
|
19861
20482
|
const {
|
|
@@ -19884,7 +20505,7 @@ function TopBar(props) {
|
|
|
19884
20505
|
`);
|
|
19885
20506
|
process.stderr.write(`running: ${UPDATE_COMMAND}
|
|
19886
20507
|
`);
|
|
19887
|
-
const result =
|
|
20508
|
+
const result = spawnSync10("sh", ["-c", UPDATE_COMMAND], {
|
|
19888
20509
|
stdio: "inherit"
|
|
19889
20510
|
});
|
|
19890
20511
|
if (result.error) {
|