claude-threads 0.44.0 → 0.45.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/CHANGELOG.md +14 -0
- package/dist/index.js +405 -70
- package/dist/mcp/permission-server.js +13 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.45.0] - 2026-01-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Update modal in CLI UI** - Press `u` to open a modal showing update status, changelog, and options to apply or defer updates
|
|
14
|
+
- **Worktree path shortening** - Tool output shows shortened worktree paths as `[branch]/path` instead of full paths for readability
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- **Duplicate task list posts in Slack** - Fixed race condition that caused double task list messages
|
|
18
|
+
- **Worktree prompt cleanup** - Remove ❌ reaction from worktree prompts after user responds
|
|
19
|
+
- **Streaming message failures** - Handle `updatePost` failures gracefully with automatic recovery
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
- **`.claude-threads-meta.json` added to .gitignore** - Session metadata files are no longer tracked
|
|
23
|
+
|
|
10
24
|
## [0.44.0] - 2026-01-07
|
|
11
25
|
|
|
12
26
|
### Added
|
package/dist/index.js
CHANGED
|
@@ -45274,12 +45274,11 @@ async function flush(session, registerPost) {
|
|
|
45274
45274
|
if (breakInfo && breakInfo.position < content.length) {
|
|
45275
45275
|
breakPoint = breakInfo.position;
|
|
45276
45276
|
} else {
|
|
45277
|
-
|
|
45278
|
-
|
|
45279
|
-
|
|
45277
|
+
try {
|
|
45278
|
+
await session.platform.updatePost(session.currentPostId, content);
|
|
45279
|
+
} catch {
|
|
45280
|
+
sessionLog(session).debug("Update failed (no breakpoint), will create new post on next flush");
|
|
45280
45281
|
session.currentPostId = null;
|
|
45281
|
-
session.currentPostContent = "";
|
|
45282
|
-
return flush(session, registerPost);
|
|
45283
45282
|
}
|
|
45284
45283
|
return;
|
|
45285
45284
|
}
|
|
@@ -45295,20 +45294,18 @@ async function flush(session, registerPost) {
|
|
|
45295
45294
|
const firstPartWithMarker = remainder ? firstPart + `
|
|
45296
45295
|
|
|
45297
45296
|
` + formatter2.formatItalic("... (continued below)") : firstPart;
|
|
45298
|
-
|
|
45299
|
-
|
|
45300
|
-
|
|
45301
|
-
session.
|
|
45302
|
-
} else {
|
|
45303
|
-
session.pendingContent = remainder;
|
|
45297
|
+
try {
|
|
45298
|
+
await session.platform.updatePost(session.currentPostId, firstPartWithMarker);
|
|
45299
|
+
} catch {
|
|
45300
|
+
sessionLog(session).debug("Update failed during split, continuing with new post");
|
|
45304
45301
|
}
|
|
45305
45302
|
session.currentPostId = null;
|
|
45306
|
-
|
|
45307
|
-
if (
|
|
45308
|
-
const continuationMarker =
|
|
45303
|
+
session.pendingContent = remainder;
|
|
45304
|
+
if (remainder) {
|
|
45305
|
+
const continuationMarker = formatter2.formatItalic("(continued)");
|
|
45306
|
+
const continuationContent = continuationMarker + `
|
|
45309
45307
|
|
|
45310
|
-
`
|
|
45311
|
-
const continuationContent = continuationMarker + contentToPost;
|
|
45308
|
+
` + remainder;
|
|
45312
45309
|
const hasActiveTasks = session.tasksPostId && session.lastTasksContent && !session.tasksCompleted;
|
|
45313
45310
|
if (hasActiveTasks) {
|
|
45314
45311
|
const postId = await bumpTasksToBottomWithContent(session, continuationContent, registerPost);
|
|
@@ -45332,12 +45329,11 @@ async function flush(session, registerPost) {
|
|
|
45332
45329
|
` + formatter2.formatItalic("... (truncated)");
|
|
45333
45330
|
}
|
|
45334
45331
|
if (session.currentPostId) {
|
|
45335
|
-
|
|
45336
|
-
|
|
45337
|
-
|
|
45332
|
+
try {
|
|
45333
|
+
await session.platform.updatePost(session.currentPostId, content);
|
|
45334
|
+
} catch {
|
|
45335
|
+
sessionLog(session).debug("Update failed, will create new post on next flush");
|
|
45338
45336
|
session.currentPostId = null;
|
|
45339
|
-
session.currentPostContent = "";
|
|
45340
|
-
return flush(session, registerPost);
|
|
45341
45337
|
}
|
|
45342
45338
|
} else {
|
|
45343
45339
|
const hasActiveTasks = session.tasksPostId && session.lastTasksContent && !session.tasksCompleted;
|
|
@@ -45981,15 +45977,22 @@ class ArrayDiff extends Diff {
|
|
|
45981
45977
|
var arrayDiff = new ArrayDiff;
|
|
45982
45978
|
|
|
45983
45979
|
// src/utils/tool-formatter.ts
|
|
45984
|
-
var
|
|
45985
|
-
|
|
45986
|
-
|
|
45987
|
-
|
|
45988
|
-
maxPreviewLines: 20
|
|
45989
|
-
};
|
|
45990
|
-
function shortenPath(path2, homeDir) {
|
|
45980
|
+
var DEFAULT_DETAILED = false;
|
|
45981
|
+
var DEFAULT_MAX_COMMAND_LENGTH = 50;
|
|
45982
|
+
var DEFAULT_MAX_PREVIEW_LINES = 20;
|
|
45983
|
+
function shortenPath(path2, homeDir, worktreeInfo) {
|
|
45991
45984
|
if (!path2)
|
|
45992
45985
|
return "";
|
|
45986
|
+
if (worktreeInfo?.path && worktreeInfo?.branch) {
|
|
45987
|
+
const worktreePath = worktreeInfo.path.endsWith("/") ? worktreeInfo.path : worktreeInfo.path + "/";
|
|
45988
|
+
if (path2.startsWith(worktreePath)) {
|
|
45989
|
+
const relativePath = path2.slice(worktreePath.length);
|
|
45990
|
+
return `[${worktreeInfo.branch}]/${relativePath}`;
|
|
45991
|
+
}
|
|
45992
|
+
if (path2 === worktreeInfo.path) {
|
|
45993
|
+
return `[${worktreeInfo.branch}]/`;
|
|
45994
|
+
}
|
|
45995
|
+
}
|
|
45993
45996
|
const home = homeDir ?? process.env.HOME ?? "";
|
|
45994
45997
|
if (home && path2.startsWith(home)) {
|
|
45995
45998
|
return "~" + path2.slice(home.length);
|
|
@@ -46008,8 +46011,10 @@ function parseMcpToolName(toolName) {
|
|
|
46008
46011
|
};
|
|
46009
46012
|
}
|
|
46010
46013
|
function formatToolUse(toolName, input, formatter, options = {}) {
|
|
46011
|
-
const
|
|
46012
|
-
const
|
|
46014
|
+
const detailed = options.detailed ?? DEFAULT_DETAILED;
|
|
46015
|
+
const maxCommandLength = options.maxCommandLength ?? DEFAULT_MAX_COMMAND_LENGTH;
|
|
46016
|
+
const maxPreviewLines = options.maxPreviewLines ?? DEFAULT_MAX_PREVIEW_LINES;
|
|
46017
|
+
const short = (p) => shortenPath(p, undefined, options.worktreeInfo);
|
|
46013
46018
|
switch (toolName) {
|
|
46014
46019
|
case "Read":
|
|
46015
46020
|
return `\uD83D\uDCC4 ${formatter.formatBold("Read")} ${formatter.formatCode(short(input.file_path))}`;
|
|
@@ -46017,9 +46022,9 @@ function formatToolUse(toolName, input, formatter, options = {}) {
|
|
|
46017
46022
|
const filePath = short(input.file_path);
|
|
46018
46023
|
const oldStr = input.old_string || "";
|
|
46019
46024
|
const newStr = input.new_string || "";
|
|
46020
|
-
if (
|
|
46025
|
+
if (detailed && (oldStr || newStr)) {
|
|
46021
46026
|
const changes = diffLines(oldStr, newStr);
|
|
46022
|
-
const maxLines =
|
|
46027
|
+
const maxLines = maxPreviewLines;
|
|
46023
46028
|
let lineCount = 0;
|
|
46024
46029
|
const diffLines2 = [];
|
|
46025
46030
|
for (const change of changes) {
|
|
@@ -46064,7 +46069,7 @@ ${formatter.formatCodeBlock(diffLines2.join(`
|
|
|
46064
46069
|
const lines = content.split(`
|
|
46065
46070
|
`);
|
|
46066
46071
|
const lineCount = lines.length;
|
|
46067
|
-
if (
|
|
46072
|
+
if (detailed && content && lineCount > 0) {
|
|
46068
46073
|
const maxLines = 6;
|
|
46069
46074
|
const previewLines = lines.slice(0, maxLines);
|
|
46070
46075
|
let preview = `\uD83D\uDCDD ${formatter.formatBold("Write")} ${formatter.formatCode(filePath)} ${formatter.formatItalic(`(${lineCount} lines)`)}
|
|
@@ -46082,8 +46087,8 @@ ${formatter.formatCodeBlock(diffLines2.join(`
|
|
|
46082
46087
|
return `\uD83D\uDCDD ${formatter.formatBold("Write")} ${formatter.formatCode(filePath)}`;
|
|
46083
46088
|
}
|
|
46084
46089
|
case "Bash": {
|
|
46085
|
-
const cmd = (input.command || "").substring(0,
|
|
46086
|
-
const truncated = cmd.length >=
|
|
46090
|
+
const cmd = (input.command || "").substring(0, maxCommandLength);
|
|
46091
|
+
const truncated = cmd.length >= maxCommandLength;
|
|
46087
46092
|
return `\uD83D\uDCBB ${formatter.formatBold("Bash")} ${formatter.formatCode(cmd + (truncated ? "..." : ""))}`;
|
|
46088
46093
|
}
|
|
46089
46094
|
case "Glob":
|
|
@@ -46373,7 +46378,8 @@ function formatEvent(session, e, ctx) {
|
|
|
46373
46378
|
if (text)
|
|
46374
46379
|
parts.push(text);
|
|
46375
46380
|
} else if (block.type === "tool_use" && block.name) {
|
|
46376
|
-
const
|
|
46381
|
+
const worktreeInfo = session.worktreeInfo ? { path: session.worktreeInfo.worktreePath, branch: session.worktreeInfo.branch } : undefined;
|
|
46382
|
+
const formatted = formatToolUse(block.name, block.input || {}, session.platform.getFormatter(), { detailed: true, worktreeInfo });
|
|
46377
46383
|
if (formatted)
|
|
46378
46384
|
parts.push(formatted);
|
|
46379
46385
|
} else if (block.type === "thinking" && block.thinking) {
|
|
@@ -46401,7 +46407,8 @@ function formatEvent(session, e, ctx) {
|
|
|
46401
46407
|
if (tool.id) {
|
|
46402
46408
|
session.activeToolStarts.set(tool.id, Date.now());
|
|
46403
46409
|
}
|
|
46404
|
-
|
|
46410
|
+
const worktreeInfo = session.worktreeInfo ? { path: session.worktreeInfo.worktreePath, branch: session.worktreeInfo.branch } : undefined;
|
|
46411
|
+
return formatToolUse(tool.name, tool.input || {}, session.platform.getFormatter(), { detailed: true, worktreeInfo }) || null;
|
|
46405
46412
|
}
|
|
46406
46413
|
case "tool_result": {
|
|
46407
46414
|
const result = e.tool_result;
|
|
@@ -46477,6 +46484,9 @@ async function handleExitPlanMode(session, toolUseId, ctx) {
|
|
|
46477
46484
|
ctx.ops.stopTyping(session);
|
|
46478
46485
|
}
|
|
46479
46486
|
async function handleTodoWrite(session, input, ctx) {
|
|
46487
|
+
if (session.taskListCreationPromise) {
|
|
46488
|
+
await session.taskListCreationPromise;
|
|
46489
|
+
}
|
|
46480
46490
|
const todos = input.todos;
|
|
46481
46491
|
if (!todos || todos.length === 0) {
|
|
46482
46492
|
session.tasksCompleted = true;
|
|
@@ -46558,12 +46568,21 @@ async function handleTodoWrite(session, input, ctx) {
|
|
|
46558
46568
|
if (existingTasksPostId) {
|
|
46559
46569
|
await withErrorHandling(() => session.platform.updatePost(existingTasksPostId, displayMessage), { action: "Update tasks", session });
|
|
46560
46570
|
} else {
|
|
46561
|
-
|
|
46562
|
-
|
|
46563
|
-
|
|
46564
|
-
|
|
46565
|
-
|
|
46566
|
-
await session.platform.
|
|
46571
|
+
let resolveCreation;
|
|
46572
|
+
session.taskListCreationPromise = new Promise((resolve2) => {
|
|
46573
|
+
resolveCreation = resolve2;
|
|
46574
|
+
});
|
|
46575
|
+
try {
|
|
46576
|
+
const post = await withErrorHandling(() => session.platform.createInteractivePost(displayMessage, [TASK_TOGGLE_EMOJIS[0]], session.threadId), { action: "Create tasks post", session });
|
|
46577
|
+
if (post) {
|
|
46578
|
+
session.tasksPostId = post.id;
|
|
46579
|
+
ctx.ops.registerPost(post.id, session.threadId);
|
|
46580
|
+
updateLastMessage(session, post);
|
|
46581
|
+
await session.platform.pinPost(post.id).catch(() => {});
|
|
46582
|
+
}
|
|
46583
|
+
} finally {
|
|
46584
|
+
resolveCreation();
|
|
46585
|
+
session.taskListCreationPromise = undefined;
|
|
46567
46586
|
}
|
|
46568
46587
|
}
|
|
46569
46588
|
ctx.ops.updateStickyMessage().catch(() => {});
|
|
@@ -52250,6 +52269,7 @@ async function handleWorktreeSkip(session, username, persistSession, offerContex
|
|
|
52250
52269
|
const promptPostId = session.worktreePromptPostId;
|
|
52251
52270
|
if (promptPostId) {
|
|
52252
52271
|
await withErrorHandling(() => session.platform.updatePost(promptPostId, `\u2705 Continuing in main repo (skipped by @${username})`), { action: "Update worktree prompt", session });
|
|
52272
|
+
await withErrorHandling(() => session.platform.removeReaction(promptPostId, "x"), { action: "Remove x reaction from worktree prompt", session });
|
|
52253
52273
|
}
|
|
52254
52274
|
session.pendingWorktreePrompt = false;
|
|
52255
52275
|
session.worktreePromptPostId = undefined;
|
|
@@ -52284,6 +52304,7 @@ async function createAndSwitchToWorktree(session, branch, username, options) {
|
|
|
52284
52304
|
const worktreePromptId = session.worktreePromptPostId;
|
|
52285
52305
|
if (worktreePromptId) {
|
|
52286
52306
|
await withErrorHandling(() => session.platform.updatePost(worktreePromptId, `\u2705 Joining existing worktree for ${fmt.formatCode(branch)}`), { action: "Update worktree prompt", session });
|
|
52307
|
+
await withErrorHandling(() => session.platform.removeReaction(worktreePromptId, "x"), { action: "Remove x reaction from worktree prompt", session });
|
|
52287
52308
|
}
|
|
52288
52309
|
const queuedPrompt = session.queuedPrompt;
|
|
52289
52310
|
const queuedFiles = session.queuedFiles;
|
|
@@ -52365,6 +52386,7 @@ ${fmt.formatItalic("Claude Code restarted in the worktree")}`);
|
|
|
52365
52386
|
const worktreePromptId = session.worktreePromptPostId;
|
|
52366
52387
|
if (worktreePromptId) {
|
|
52367
52388
|
await withErrorHandling(() => session.platform.updatePost(worktreePromptId, `\u2705 Created worktree for \`${branch}\``), { action: "Update worktree prompt", session });
|
|
52389
|
+
await withErrorHandling(() => session.platform.removeReaction(worktreePromptId, "x"), { action: "Remove x reaction from worktree prompt", session });
|
|
52368
52390
|
}
|
|
52369
52391
|
const wasPending = session.pendingWorktreePrompt;
|
|
52370
52392
|
session.pendingWorktreePrompt = false;
|
|
@@ -52431,6 +52453,7 @@ ${fmt.formatItalic("Claude Code restarted in the new worktree")}`);
|
|
|
52431
52453
|
const worktreePromptId = session.worktreePromptPostId;
|
|
52432
52454
|
if (worktreePromptId) {
|
|
52433
52455
|
await withErrorHandling(() => session.platform.updatePost(worktreePromptId, `\u274C Failed to create worktree for ${fmt.formatCode(branch)} - continuing in main repo`), { action: "Update worktree prompt after failure", session });
|
|
52456
|
+
await withErrorHandling(() => session.platform.removeReaction(worktreePromptId, "x"), { action: "Remove x reaction from worktree prompt", session });
|
|
52434
52457
|
}
|
|
52435
52458
|
const wasPending = session.pendingWorktreePrompt;
|
|
52436
52459
|
session.pendingWorktreePrompt = false;
|
|
@@ -59517,6 +59540,8 @@ var use_input_default = useInput;
|
|
|
59517
59540
|
var import_react20 = __toESM(require_react(), 1);
|
|
59518
59541
|
// node_modules/ink/build/hooks/use-stdout.js
|
|
59519
59542
|
var import_react21 = __toESM(require_react(), 1);
|
|
59543
|
+
var useStdout = () => import_react21.useContext(StdoutContext_default);
|
|
59544
|
+
var use_stdout_default = useStdout;
|
|
59520
59545
|
// node_modules/ink/build/hooks/use-stderr.js
|
|
59521
59546
|
var import_react22 = __toESM(require_react(), 1);
|
|
59522
59547
|
// node_modules/ink/build/hooks/use-focus.js
|
|
@@ -62860,7 +62885,8 @@ function CollapsibleSession(props) {
|
|
|
62860
62885
|
}
|
|
62861
62886
|
// src/ui/components/StatusLine.tsx
|
|
62862
62887
|
var jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
|
|
62863
|
-
function ToggleKey({ keyChar, label, enabled }) {
|
|
62888
|
+
function ToggleKey({ keyChar, label, enabled, color }) {
|
|
62889
|
+
const displayColor = color ?? (enabled ? "green" : "gray");
|
|
62864
62890
|
return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
|
|
62865
62891
|
gap: 0,
|
|
62866
62892
|
children: [
|
|
@@ -62869,7 +62895,7 @@ function ToggleKey({ keyChar, label, enabled }) {
|
|
|
62869
62895
|
children: "["
|
|
62870
62896
|
}, undefined, false, undefined, this),
|
|
62871
62897
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
|
|
62872
|
-
color:
|
|
62898
|
+
color: displayColor,
|
|
62873
62899
|
bold: true,
|
|
62874
62900
|
children: keyChar
|
|
62875
62901
|
}, undefined, false, undefined, this),
|
|
@@ -62878,12 +62904,44 @@ function ToggleKey({ keyChar, label, enabled }) {
|
|
|
62878
62904
|
children: "]"
|
|
62879
62905
|
}, undefined, false, undefined, this),
|
|
62880
62906
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
|
|
62881
|
-
color:
|
|
62907
|
+
color: displayColor,
|
|
62882
62908
|
children: label
|
|
62883
62909
|
}, undefined, false, undefined, this)
|
|
62884
62910
|
]
|
|
62885
62911
|
}, undefined, true, undefined, this);
|
|
62886
62912
|
}
|
|
62913
|
+
function getUpdateColor(state) {
|
|
62914
|
+
if (!state)
|
|
62915
|
+
return "gray";
|
|
62916
|
+
switch (state.status) {
|
|
62917
|
+
case "available":
|
|
62918
|
+
return "green";
|
|
62919
|
+
case "scheduled":
|
|
62920
|
+
case "installing":
|
|
62921
|
+
case "pending_restart":
|
|
62922
|
+
return "yellow";
|
|
62923
|
+
case "failed":
|
|
62924
|
+
return "red";
|
|
62925
|
+
case "deferred":
|
|
62926
|
+
case "idle":
|
|
62927
|
+
default:
|
|
62928
|
+
return "gray";
|
|
62929
|
+
}
|
|
62930
|
+
}
|
|
62931
|
+
function getUpdateIndicator(state) {
|
|
62932
|
+
if (!state)
|
|
62933
|
+
return "";
|
|
62934
|
+
switch (state.status) {
|
|
62935
|
+
case "available":
|
|
62936
|
+
return " \uD83C\uDD95";
|
|
62937
|
+
case "installing":
|
|
62938
|
+
return " \uD83D\uDCE6";
|
|
62939
|
+
case "failed":
|
|
62940
|
+
return " \u274C";
|
|
62941
|
+
default:
|
|
62942
|
+
return "";
|
|
62943
|
+
}
|
|
62944
|
+
}
|
|
62887
62945
|
function PlatformToggle({
|
|
62888
62946
|
index,
|
|
62889
62947
|
platform: platform2
|
|
@@ -62927,9 +62985,12 @@ function StatusLine({
|
|
|
62927
62985
|
shuttingDown,
|
|
62928
62986
|
sessionCount,
|
|
62929
62987
|
toggles,
|
|
62930
|
-
platforms
|
|
62988
|
+
platforms,
|
|
62989
|
+
updateState
|
|
62931
62990
|
}) {
|
|
62932
62991
|
const platformList = Array.from(platforms.values());
|
|
62992
|
+
const updateColor = getUpdateColor(updateState);
|
|
62993
|
+
const updateIndicator = getUpdateIndicator(updateState);
|
|
62933
62994
|
return /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
|
|
62934
62995
|
flexDirection: "column",
|
|
62935
62996
|
marginTop: 1,
|
|
@@ -63002,6 +63063,20 @@ function StatusLine({
|
|
|
63002
63063
|
label: "eep-alive",
|
|
63003
63064
|
enabled: toggles.keepAliveEnabled
|
|
63004
63065
|
}, undefined, false, undefined, this),
|
|
63066
|
+
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Box_default, {
|
|
63067
|
+
gap: 0,
|
|
63068
|
+
children: [
|
|
63069
|
+
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(ToggleKey, {
|
|
63070
|
+
keyChar: "u",
|
|
63071
|
+
label: "pdate",
|
|
63072
|
+
enabled: updateState?.status === "available",
|
|
63073
|
+
color: updateColor
|
|
63074
|
+
}, undefined, false, undefined, this),
|
|
63075
|
+
updateIndicator && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
|
|
63076
|
+
children: updateIndicator
|
|
63077
|
+
}, undefined, false, undefined, this)
|
|
63078
|
+
]
|
|
63079
|
+
}, undefined, true, undefined, this),
|
|
63005
63080
|
platformList.length > 0 && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(jsx_dev_runtime7.Fragment, {
|
|
63006
63081
|
children: [
|
|
63007
63082
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(Text, {
|
|
@@ -63093,6 +63168,187 @@ function LogPanel({ logs, maxLines = 10 }) {
|
|
|
63093
63168
|
}, log19.id, true, undefined, this))
|
|
63094
63169
|
}, undefined, false, undefined, this);
|
|
63095
63170
|
}
|
|
63171
|
+
// src/ui/components/Modal.tsx
|
|
63172
|
+
var jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
|
|
63173
|
+
function Modal({ title, children, hint }) {
|
|
63174
|
+
const { stdout } = use_stdout_default();
|
|
63175
|
+
const terminalWidth = stdout?.columns ?? 80;
|
|
63176
|
+
const modalWidth = Math.min(50, terminalWidth - 4);
|
|
63177
|
+
return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
63178
|
+
flexDirection: "column",
|
|
63179
|
+
borderStyle: "round",
|
|
63180
|
+
borderColor: "cyan",
|
|
63181
|
+
paddingX: 1,
|
|
63182
|
+
paddingY: 0,
|
|
63183
|
+
width: modalWidth,
|
|
63184
|
+
children: [
|
|
63185
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
63186
|
+
justifyContent: "center",
|
|
63187
|
+
marginBottom: 1,
|
|
63188
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
63189
|
+
color: "cyan",
|
|
63190
|
+
bold: true,
|
|
63191
|
+
children: title
|
|
63192
|
+
}, undefined, false, undefined, this)
|
|
63193
|
+
}, undefined, false, undefined, this),
|
|
63194
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
63195
|
+
flexDirection: "column",
|
|
63196
|
+
children
|
|
63197
|
+
}, undefined, false, undefined, this),
|
|
63198
|
+
hint && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
63199
|
+
justifyContent: "center",
|
|
63200
|
+
marginTop: 1,
|
|
63201
|
+
children: /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
63202
|
+
dimColor: true,
|
|
63203
|
+
children: hint
|
|
63204
|
+
}, undefined, false, undefined, this)
|
|
63205
|
+
}, undefined, false, undefined, this)
|
|
63206
|
+
]
|
|
63207
|
+
}, undefined, true, undefined, this);
|
|
63208
|
+
}
|
|
63209
|
+
// src/ui/components/UpdateModal.tsx
|
|
63210
|
+
var jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
|
|
63211
|
+
function formatTime(date) {
|
|
63212
|
+
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
|
|
63213
|
+
}
|
|
63214
|
+
function getStatusDisplay(state) {
|
|
63215
|
+
switch (state.status) {
|
|
63216
|
+
case "idle":
|
|
63217
|
+
return { icon: "\u2713", label: "Up to date", color: "green" };
|
|
63218
|
+
case "available":
|
|
63219
|
+
return { icon: "\uD83C\uDD95", label: "Update available", color: "green" };
|
|
63220
|
+
case "scheduled":
|
|
63221
|
+
return { icon: "\u23F0", label: "Restart scheduled", color: "yellow" };
|
|
63222
|
+
case "installing":
|
|
63223
|
+
return { icon: "\uD83D\uDCE6", label: "Installing...", color: "cyan" };
|
|
63224
|
+
case "pending_restart":
|
|
63225
|
+
return { icon: "\uD83D\uDD04", label: "Restarting...", color: "yellow" };
|
|
63226
|
+
case "failed":
|
|
63227
|
+
return { icon: "\u274C", label: "Update failed", color: "red" };
|
|
63228
|
+
case "deferred":
|
|
63229
|
+
return { icon: "\u23F8\uFE0F", label: "Update deferred", color: "gray" };
|
|
63230
|
+
default:
|
|
63231
|
+
return { icon: "?", label: "Unknown", color: "gray" };
|
|
63232
|
+
}
|
|
63233
|
+
}
|
|
63234
|
+
function getHint(state) {
|
|
63235
|
+
const canUpdate = state.status === "available" || state.status === "deferred";
|
|
63236
|
+
if (canUpdate) {
|
|
63237
|
+
return "Press [Shift+U] to update now | [u] or [Esc] to close";
|
|
63238
|
+
}
|
|
63239
|
+
return "Press [u] or [Esc] to close";
|
|
63240
|
+
}
|
|
63241
|
+
function UpdateModal({ state }) {
|
|
63242
|
+
const statusDisplay = getStatusDisplay(state);
|
|
63243
|
+
const hint = getHint(state);
|
|
63244
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Modal, {
|
|
63245
|
+
title: "Update Status",
|
|
63246
|
+
hint,
|
|
63247
|
+
children: [
|
|
63248
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63249
|
+
flexDirection: "column",
|
|
63250
|
+
gap: 0,
|
|
63251
|
+
children: [
|
|
63252
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63253
|
+
children: [
|
|
63254
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63255
|
+
dimColor: true,
|
|
63256
|
+
children: "Current version: "
|
|
63257
|
+
}, undefined, false, undefined, this),
|
|
63258
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63259
|
+
bold: true,
|
|
63260
|
+
children: [
|
|
63261
|
+
"v",
|
|
63262
|
+
state.currentVersion
|
|
63263
|
+
]
|
|
63264
|
+
}, undefined, true, undefined, this)
|
|
63265
|
+
]
|
|
63266
|
+
}, undefined, true, undefined, this),
|
|
63267
|
+
state.latestVersion && state.latestVersion !== state.currentVersion && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63268
|
+
children: [
|
|
63269
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63270
|
+
dimColor: true,
|
|
63271
|
+
children: "Latest version: "
|
|
63272
|
+
}, undefined, false, undefined, this),
|
|
63273
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63274
|
+
bold: true,
|
|
63275
|
+
color: "green",
|
|
63276
|
+
children: [
|
|
63277
|
+
"v",
|
|
63278
|
+
state.latestVersion
|
|
63279
|
+
]
|
|
63280
|
+
}, undefined, true, undefined, this)
|
|
63281
|
+
]
|
|
63282
|
+
}, undefined, true, undefined, this)
|
|
63283
|
+
]
|
|
63284
|
+
}, undefined, true, undefined, this),
|
|
63285
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63286
|
+
marginTop: 1,
|
|
63287
|
+
children: state.status === "installing" ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63288
|
+
gap: 1,
|
|
63289
|
+
children: [
|
|
63290
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Spinner2, {
|
|
63291
|
+
type: "dots"
|
|
63292
|
+
}, undefined, false, undefined, this),
|
|
63293
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63294
|
+
color: statusDisplay.color,
|
|
63295
|
+
children: statusDisplay.label
|
|
63296
|
+
}, undefined, false, undefined, this)
|
|
63297
|
+
]
|
|
63298
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63299
|
+
gap: 1,
|
|
63300
|
+
children: [
|
|
63301
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63302
|
+
children: statusDisplay.icon
|
|
63303
|
+
}, undefined, false, undefined, this),
|
|
63304
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63305
|
+
color: statusDisplay.color,
|
|
63306
|
+
children: statusDisplay.label
|
|
63307
|
+
}, undefined, false, undefined, this)
|
|
63308
|
+
]
|
|
63309
|
+
}, undefined, true, undefined, this)
|
|
63310
|
+
}, undefined, false, undefined, this),
|
|
63311
|
+
state.status === "scheduled" && state.scheduledRestartAt && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63312
|
+
marginTop: 1,
|
|
63313
|
+
children: [
|
|
63314
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63315
|
+
dimColor: true,
|
|
63316
|
+
children: "Restart at: "
|
|
63317
|
+
}, undefined, false, undefined, this),
|
|
63318
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63319
|
+
children: formatTime(state.scheduledRestartAt)
|
|
63320
|
+
}, undefined, false, undefined, this)
|
|
63321
|
+
]
|
|
63322
|
+
}, undefined, true, undefined, this),
|
|
63323
|
+
state.status === "deferred" && state.deferredUntil && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63324
|
+
marginTop: 1,
|
|
63325
|
+
children: [
|
|
63326
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63327
|
+
dimColor: true,
|
|
63328
|
+
children: "Deferred until: "
|
|
63329
|
+
}, undefined, false, undefined, this),
|
|
63330
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63331
|
+
children: formatTime(state.deferredUntil)
|
|
63332
|
+
}, undefined, false, undefined, this)
|
|
63333
|
+
]
|
|
63334
|
+
}, undefined, true, undefined, this),
|
|
63335
|
+
state.status === "failed" && state.errorMessage && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
63336
|
+
marginTop: 1,
|
|
63337
|
+
flexDirection: "column",
|
|
63338
|
+
children: [
|
|
63339
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63340
|
+
color: "red",
|
|
63341
|
+
children: "Error:"
|
|
63342
|
+
}, undefined, false, undefined, this),
|
|
63343
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
63344
|
+
dimColor: true,
|
|
63345
|
+
children: state.errorMessage
|
|
63346
|
+
}, undefined, false, undefined, this)
|
|
63347
|
+
]
|
|
63348
|
+
}, undefined, true, undefined, this)
|
|
63349
|
+
]
|
|
63350
|
+
}, undefined, true, undefined, this);
|
|
63351
|
+
}
|
|
63096
63352
|
// src/ui/hooks/useAppState.ts
|
|
63097
63353
|
var import_react57 = __toESM(require_react(), 1);
|
|
63098
63354
|
var logIdCounter = 0;
|
|
@@ -63237,15 +63493,26 @@ function useKeyboard({
|
|
|
63237
63493
|
onDebugToggle,
|
|
63238
63494
|
onPermissionsToggle,
|
|
63239
63495
|
onChromeToggle,
|
|
63240
|
-
onKeepAliveToggle
|
|
63496
|
+
onKeepAliveToggle,
|
|
63497
|
+
onUpdateModalToggle,
|
|
63498
|
+
onForceUpdate,
|
|
63499
|
+
updateModalVisible
|
|
63241
63500
|
}) {
|
|
63242
63501
|
use_input_default((input, key) => {
|
|
63502
|
+
if (key.escape && updateModalVisible) {
|
|
63503
|
+
onUpdateModalToggle?.();
|
|
63504
|
+
return;
|
|
63505
|
+
}
|
|
63243
63506
|
if (input === "\x03" || input === "c" && key.ctrl) {
|
|
63244
63507
|
if (onQuit) {
|
|
63245
63508
|
onQuit();
|
|
63246
63509
|
}
|
|
63247
63510
|
return;
|
|
63248
63511
|
}
|
|
63512
|
+
if (input === "U") {
|
|
63513
|
+
onForceUpdate?.();
|
|
63514
|
+
return;
|
|
63515
|
+
}
|
|
63249
63516
|
const platformIndex = SHIFT_NUMBER_MAP[input];
|
|
63250
63517
|
if (platformIndex !== undefined && onPlatformToggle) {
|
|
63251
63518
|
const platformId = platformIds[platformIndex];
|
|
@@ -63274,6 +63541,9 @@ function useKeyboard({
|
|
|
63274
63541
|
case "k":
|
|
63275
63542
|
onKeepAliveToggle?.();
|
|
63276
63543
|
break;
|
|
63544
|
+
case "u":
|
|
63545
|
+
onUpdateModalToggle?.();
|
|
63546
|
+
break;
|
|
63277
63547
|
case "q":
|
|
63278
63548
|
onQuit?.();
|
|
63279
63549
|
break;
|
|
@@ -63282,7 +63552,7 @@ function useKeyboard({
|
|
|
63282
63552
|
}
|
|
63283
63553
|
|
|
63284
63554
|
// src/ui/App.tsx
|
|
63285
|
-
var
|
|
63555
|
+
var jsx_dev_runtime11 = __toESM(require_jsx_dev_runtime(), 1);
|
|
63286
63556
|
function App2({ config, onStateReady, onResizeReady, onQuit, toggleCallbacks }) {
|
|
63287
63557
|
const {
|
|
63288
63558
|
state,
|
|
@@ -63303,7 +63573,12 @@ function App2({ config, onStateReady, onResizeReady, onQuit, toggleCallbacks })
|
|
|
63303
63573
|
debugMode: process.env.DEBUG === "1",
|
|
63304
63574
|
skipPermissions: config.skipPermissions,
|
|
63305
63575
|
chromeEnabled: config.chromeEnabled,
|
|
63306
|
-
keepAliveEnabled: config.keepAliveEnabled
|
|
63576
|
+
keepAliveEnabled: config.keepAliveEnabled,
|
|
63577
|
+
updateModalVisible: false
|
|
63578
|
+
});
|
|
63579
|
+
const [updateState, setUpdateState] = import_react58.default.useState({
|
|
63580
|
+
status: "idle",
|
|
63581
|
+
currentVersion: config.version
|
|
63307
63582
|
});
|
|
63308
63583
|
const handleDebugToggle = import_react58.default.useCallback(() => {
|
|
63309
63584
|
setToggles((prev) => {
|
|
@@ -63334,6 +63609,9 @@ function App2({ config, onStateReady, onResizeReady, onQuit, toggleCallbacks })
|
|
|
63334
63609
|
return { ...prev, keepAliveEnabled: newValue };
|
|
63335
63610
|
});
|
|
63336
63611
|
}, [toggleCallbacks]);
|
|
63612
|
+
const handleUpdateModalToggle = import_react58.default.useCallback(() => {
|
|
63613
|
+
setToggles((prev) => ({ ...prev, updateModalVisible: !prev.updateModalVisible }));
|
|
63614
|
+
}, []);
|
|
63337
63615
|
const handlePlatformToggle = import_react58.default.useCallback((platformId) => {
|
|
63338
63616
|
const newEnabled = togglePlatformEnabled(platformId);
|
|
63339
63617
|
toggleCallbacks?.onPlatformToggle?.(platformId, newEnabled);
|
|
@@ -63348,9 +63626,10 @@ function App2({ config, onStateReady, onResizeReady, onQuit, toggleCallbacks })
|
|
|
63348
63626
|
removeSession,
|
|
63349
63627
|
addLog,
|
|
63350
63628
|
setPlatformStatus,
|
|
63629
|
+
setUpdateState,
|
|
63351
63630
|
getToggles
|
|
63352
63631
|
});
|
|
63353
|
-
}, [onStateReady, setReady, setShuttingDown2, addSession, updateSession, removeSession, addLog, setPlatformStatus, getToggles]);
|
|
63632
|
+
}, [onStateReady, setReady, setShuttingDown2, addSession, updateSession, removeSession, addLog, setPlatformStatus, setUpdateState, getToggles]);
|
|
63354
63633
|
import_react58.default.useEffect(() => {
|
|
63355
63634
|
if (onResizeReady) {
|
|
63356
63635
|
onResizeReady(() => setResizeCount((c) => c + 1));
|
|
@@ -63367,58 +63646,61 @@ function App2({ config, onStateReady, onResizeReady, onQuit, toggleCallbacks })
|
|
|
63367
63646
|
onDebugToggle: handleDebugToggle,
|
|
63368
63647
|
onPermissionsToggle: handlePermissionsToggle,
|
|
63369
63648
|
onChromeToggle: handleChromeToggle,
|
|
63370
|
-
onKeepAliveToggle: handleKeepAliveToggle
|
|
63649
|
+
onKeepAliveToggle: handleKeepAliveToggle,
|
|
63650
|
+
onUpdateModalToggle: handleUpdateModalToggle,
|
|
63651
|
+
onForceUpdate: toggleCallbacks?.onForceUpdate,
|
|
63652
|
+
updateModalVisible: toggles.updateModalVisible
|
|
63371
63653
|
});
|
|
63372
63654
|
const staticContent = import_react58.default.useMemo(() => [
|
|
63373
|
-
{ id: `header-${resizeCount}`, element: /* @__PURE__ */
|
|
63655
|
+
{ id: `header-${resizeCount}`, element: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Header, {
|
|
63374
63656
|
version: config.version
|
|
63375
63657
|
}, undefined, false, undefined, this) },
|
|
63376
|
-
{ id: `config-${resizeCount}`, element: /* @__PURE__ */
|
|
63658
|
+
{ id: `config-${resizeCount}`, element: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(ConfigSummary, {
|
|
63377
63659
|
config
|
|
63378
63660
|
}, undefined, false, undefined, this) }
|
|
63379
63661
|
], [config, resizeCount]);
|
|
63380
63662
|
const globalLogs = getGlobalLogs();
|
|
63381
63663
|
const hasLogs = globalLogs.length > 0;
|
|
63382
63664
|
const hasSessions = state.sessions.size > 0;
|
|
63383
|
-
return /* @__PURE__ */
|
|
63665
|
+
return /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
63384
63666
|
flexDirection: "column",
|
|
63385
63667
|
children: [
|
|
63386
|
-
/* @__PURE__ */
|
|
63668
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Static, {
|
|
63387
63669
|
items: staticContent,
|
|
63388
|
-
children: (item) => /* @__PURE__ */
|
|
63670
|
+
children: (item) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
63389
63671
|
children: item.element
|
|
63390
63672
|
}, item.id, false, undefined, this)
|
|
63391
63673
|
}, undefined, false, undefined, this),
|
|
63392
|
-
/* @__PURE__ */
|
|
63674
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Platforms, {
|
|
63393
63675
|
platforms: state.platforms
|
|
63394
63676
|
}, undefined, false, undefined, this),
|
|
63395
|
-
hasLogs && /* @__PURE__ */
|
|
63677
|
+
hasLogs && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(jsx_dev_runtime11.Fragment, {
|
|
63396
63678
|
children: [
|
|
63397
|
-
/* @__PURE__ */
|
|
63679
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
63398
63680
|
marginTop: 1,
|
|
63399
|
-
children: /* @__PURE__ */
|
|
63681
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
63400
63682
|
dimColor: true,
|
|
63401
63683
|
children: "\u2500".repeat(50)
|
|
63402
63684
|
}, undefined, false, undefined, this)
|
|
63403
63685
|
}, undefined, false, undefined, this),
|
|
63404
|
-
/* @__PURE__ */
|
|
63686
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(LogPanel, {
|
|
63405
63687
|
logs: globalLogs,
|
|
63406
63688
|
maxLines: 10
|
|
63407
63689
|
}, undefined, false, undefined, this)
|
|
63408
63690
|
]
|
|
63409
63691
|
}, undefined, true, undefined, this),
|
|
63410
|
-
hasSessions && /* @__PURE__ */
|
|
63692
|
+
hasSessions && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(jsx_dev_runtime11.Fragment, {
|
|
63411
63693
|
children: [
|
|
63412
|
-
/* @__PURE__ */
|
|
63694
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
63413
63695
|
marginTop: 1,
|
|
63414
|
-
children: /* @__PURE__ */
|
|
63696
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
63415
63697
|
dimColor: true,
|
|
63416
63698
|
children: "\u2500".repeat(50)
|
|
63417
63699
|
}, undefined, false, undefined, this)
|
|
63418
63700
|
}, undefined, false, undefined, this),
|
|
63419
|
-
/* @__PURE__ */
|
|
63701
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
63420
63702
|
marginTop: 0,
|
|
63421
|
-
children: /* @__PURE__ */
|
|
63703
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
63422
63704
|
dimColor: true,
|
|
63423
63705
|
children: [
|
|
63424
63706
|
"Sessions (",
|
|
@@ -63427,7 +63709,7 @@ function App2({ config, onStateReady, onResizeReady, onQuit, toggleCallbacks })
|
|
|
63427
63709
|
]
|
|
63428
63710
|
}, undefined, true, undefined, this)
|
|
63429
63711
|
}, undefined, false, undefined, this),
|
|
63430
|
-
Array.from(state.sessions.entries()).map(([id, session], index) => /* @__PURE__ */
|
|
63712
|
+
Array.from(state.sessions.entries()).map(([id, session], index) => /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(CollapsibleSession, {
|
|
63431
63713
|
session,
|
|
63432
63714
|
logs: getLogsForSession(id),
|
|
63433
63715
|
expanded: state.expandedSessions.has(id),
|
|
@@ -63435,12 +63717,20 @@ function App2({ config, onStateReady, onResizeReady, onQuit, toggleCallbacks })
|
|
|
63435
63717
|
}, id, false, undefined, this))
|
|
63436
63718
|
]
|
|
63437
63719
|
}, undefined, true, undefined, this),
|
|
63438
|
-
/* @__PURE__ */
|
|
63720
|
+
/* @__PURE__ */ jsx_dev_runtime11.jsxDEV(StatusLine, {
|
|
63439
63721
|
ready: state.ready,
|
|
63440
63722
|
shuttingDown: state.shuttingDown,
|
|
63441
63723
|
sessionCount: state.sessions.size,
|
|
63442
63724
|
toggles,
|
|
63443
|
-
platforms: state.platforms
|
|
63725
|
+
platforms: state.platforms,
|
|
63726
|
+
updateState
|
|
63727
|
+
}, undefined, false, undefined, this),
|
|
63728
|
+
toggles.updateModalVisible && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Box_default, {
|
|
63729
|
+
marginTop: 1,
|
|
63730
|
+
justifyContent: "center",
|
|
63731
|
+
children: /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(UpdateModal, {
|
|
63732
|
+
state: updateState
|
|
63733
|
+
}, undefined, false, undefined, this)
|
|
63444
63734
|
}, undefined, false, undefined, this)
|
|
63445
63735
|
]
|
|
63446
63736
|
}, undefined, true, undefined, this);
|
|
@@ -63487,6 +63777,7 @@ async function startUI(options) {
|
|
|
63487
63777
|
removeSession: handlers.removeSession,
|
|
63488
63778
|
addLog: handlers.addLog,
|
|
63489
63779
|
setPlatformStatus: handlers.setPlatformStatus,
|
|
63780
|
+
setUpdateState: handlers.setUpdateState,
|
|
63490
63781
|
waitUntilExit,
|
|
63491
63782
|
getToggles: handlers.getToggles
|
|
63492
63783
|
};
|
|
@@ -64613,6 +64904,16 @@ async function main() {
|
|
|
64613
64904
|
ui.setPlatformStatus(platformId, { connected: false });
|
|
64614
64905
|
ui.addLog({ level: "info", component: "toggle", message: `\u2713 Platform ${platformId} disabled` });
|
|
64615
64906
|
}
|
|
64907
|
+
},
|
|
64908
|
+
onForceUpdate: () => {
|
|
64909
|
+
if (autoUpdateManager?.hasUpdate()) {
|
|
64910
|
+
ui.addLog({ level: "info", component: "update", message: "\uD83D\uDE80 Force updating via Shift+U..." });
|
|
64911
|
+
autoUpdateManager.forceUpdate().catch((err) => {
|
|
64912
|
+
ui.addLog({ level: "error", component: "update", message: `Force update failed: ${err}` });
|
|
64913
|
+
});
|
|
64914
|
+
} else {
|
|
64915
|
+
ui.addLog({ level: "info", component: "update", message: "No update available to install" });
|
|
64916
|
+
}
|
|
64616
64917
|
}
|
|
64617
64918
|
}
|
|
64618
64919
|
});
|
|
@@ -64677,19 +64978,53 @@ async function main() {
|
|
|
64677
64978
|
session.setAutoUpdateManager(autoUpdateManager);
|
|
64678
64979
|
autoUpdateManager.on("update:available", (info) => {
|
|
64679
64980
|
ui.addLog({ level: "info", component: "update", message: `\uD83C\uDD95 Update available: v${info.currentVersion} \u2192 v${info.latestVersion}` });
|
|
64981
|
+
ui.setUpdateState({
|
|
64982
|
+
status: "available",
|
|
64983
|
+
currentVersion: info.currentVersion,
|
|
64984
|
+
latestVersion: info.latestVersion
|
|
64985
|
+
});
|
|
64680
64986
|
});
|
|
64681
64987
|
autoUpdateManager.on("update:countdown", (seconds) => {
|
|
64682
64988
|
if (seconds === 60 || seconds === 30 || seconds === 10 || seconds <= 5) {
|
|
64683
64989
|
ui.addLog({ level: "info", component: "update", message: `\uD83D\uDD04 Restarting in ${seconds} seconds...` });
|
|
64684
64990
|
}
|
|
64991
|
+
const restartAt = autoUpdateManager?.getScheduledRestartAt();
|
|
64992
|
+
const updateInfo = autoUpdateManager?.getUpdateInfo();
|
|
64993
|
+
if (restartAt) {
|
|
64994
|
+
ui.setUpdateState({
|
|
64995
|
+
status: "scheduled",
|
|
64996
|
+
currentVersion: VERSION,
|
|
64997
|
+
latestVersion: updateInfo?.latestVersion,
|
|
64998
|
+
scheduledRestartAt: restartAt
|
|
64999
|
+
});
|
|
65000
|
+
}
|
|
64685
65001
|
});
|
|
64686
65002
|
autoUpdateManager.on("update:status", (status, message) => {
|
|
64687
65003
|
if (message) {
|
|
64688
65004
|
ui.addLog({ level: "info", component: "update", message: `\uD83D\uDD04 ${status}: ${message}` });
|
|
64689
65005
|
}
|
|
65006
|
+
const updateInfo = autoUpdateManager?.getUpdateInfo();
|
|
65007
|
+
const state = autoUpdateManager?.getState();
|
|
65008
|
+
ui.setUpdateState({
|
|
65009
|
+
status,
|
|
65010
|
+
currentVersion: VERSION,
|
|
65011
|
+
latestVersion: updateInfo?.latestVersion,
|
|
65012
|
+
scheduledRestartAt: autoUpdateManager?.getScheduledRestartAt() ?? undefined,
|
|
65013
|
+
errorMessage: state?.errorMessage
|
|
65014
|
+
});
|
|
64690
65015
|
});
|
|
64691
65016
|
autoUpdateManager.on("update:failed", (error) => {
|
|
64692
65017
|
ui.addLog({ level: "error", component: "update", message: `\u274C Update failed: ${error}` });
|
|
65018
|
+
ui.setUpdateState({
|
|
65019
|
+
status: "failed",
|
|
65020
|
+
currentVersion: VERSION,
|
|
65021
|
+
latestVersion: autoUpdateManager?.getUpdateInfo()?.latestVersion,
|
|
65022
|
+
errorMessage: error
|
|
65023
|
+
});
|
|
65024
|
+
});
|
|
65025
|
+
ui.setUpdateState({
|
|
65026
|
+
status: "idle",
|
|
65027
|
+
currentVersion: VERSION
|
|
64693
65028
|
});
|
|
64694
65029
|
autoUpdateManager.start();
|
|
64695
65030
|
ui.setReady();
|
|
@@ -33641,9 +33641,19 @@ function isAllowAllEmoji(emoji3) {
|
|
|
33641
33641
|
}
|
|
33642
33642
|
|
|
33643
33643
|
// src/utils/tool-formatter.ts
|
|
33644
|
-
function shortenPath(path, homeDir) {
|
|
33644
|
+
function shortenPath(path, homeDir, worktreeInfo) {
|
|
33645
33645
|
if (!path)
|
|
33646
33646
|
return "";
|
|
33647
|
+
if (worktreeInfo?.path && worktreeInfo?.branch) {
|
|
33648
|
+
const worktreePath = worktreeInfo.path.endsWith("/") ? worktreeInfo.path : worktreeInfo.path + "/";
|
|
33649
|
+
if (path.startsWith(worktreePath)) {
|
|
33650
|
+
const relativePath = path.slice(worktreePath.length);
|
|
33651
|
+
return `[${worktreeInfo.branch}]/${relativePath}`;
|
|
33652
|
+
}
|
|
33653
|
+
if (path === worktreeInfo.path) {
|
|
33654
|
+
return `[${worktreeInfo.branch}]/`;
|
|
33655
|
+
}
|
|
33656
|
+
}
|
|
33647
33657
|
const home = homeDir ?? process.env.HOME ?? "";
|
|
33648
33658
|
if (home && path.startsWith(home)) {
|
|
33649
33659
|
return "~" + path.slice(home.length);
|
|
@@ -33661,8 +33671,8 @@ function parseMcpToolName(toolName) {
|
|
|
33661
33671
|
tool: parts.slice(2).join("__")
|
|
33662
33672
|
};
|
|
33663
33673
|
}
|
|
33664
|
-
function formatToolForPermission(toolName, input, formatter) {
|
|
33665
|
-
const short = (p) => shortenPath(p);
|
|
33674
|
+
function formatToolForPermission(toolName, input, formatter, options = {}) {
|
|
33675
|
+
const short = (p) => shortenPath(p, undefined, options.worktreeInfo);
|
|
33666
33676
|
switch (toolName) {
|
|
33667
33677
|
case "Read":
|
|
33668
33678
|
return `\uD83D\uDCC4 ${formatter.formatBold("Read")} ${formatter.formatCode(short(input.file_path))}`;
|