@akiojin/gwt 4.11.6 → 4.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/gwt.js +36 -10
- package/dist/claude.d.ts +1 -0
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +81 -24
- package/dist/claude.js.map +1 -1
- package/dist/cli/ui/App.solid.d.ts.map +1 -1
- package/dist/cli/ui/App.solid.js +280 -50
- package/dist/cli/ui/App.solid.js.map +1 -1
- package/dist/cli/ui/components/solid/QuickStartStep.d.ts.map +1 -1
- package/dist/cli/ui/components/solid/QuickStartStep.js +35 -22
- package/dist/cli/ui/components/solid/QuickStartStep.js.map +1 -1
- package/dist/cli/ui/components/solid/SelectInput.d.ts.map +1 -1
- package/dist/cli/ui/components/solid/SelectInput.js +2 -1
- package/dist/cli/ui/components/solid/SelectInput.js.map +1 -1
- package/dist/cli/ui/components/solid/WizardController.d.ts.map +1 -1
- package/dist/cli/ui/components/solid/WizardController.js +67 -13
- package/dist/cli/ui/components/solid/WizardController.js.map +1 -1
- package/dist/cli/ui/components/solid/WizardSteps.d.ts +5 -0
- package/dist/cli/ui/components/solid/WizardSteps.d.ts.map +1 -1
- package/dist/cli/ui/components/solid/WizardSteps.js +50 -70
- package/dist/cli/ui/components/solid/WizardSteps.js.map +1 -1
- package/dist/cli/ui/core/theme.d.ts +9 -0
- package/dist/cli/ui/core/theme.d.ts.map +1 -1
- package/dist/cli/ui/core/theme.js +21 -0
- package/dist/cli/ui/core/theme.js.map +1 -1
- package/dist/cli/ui/screens/solid/BranchListScreen.d.ts +9 -2
- package/dist/cli/ui/screens/solid/BranchListScreen.d.ts.map +1 -1
- package/dist/cli/ui/screens/solid/BranchListScreen.js +101 -28
- package/dist/cli/ui/screens/solid/BranchListScreen.js.map +1 -1
- package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts +2 -1
- package/dist/cli/ui/screens/solid/ConfirmScreen.d.ts.map +1 -1
- package/dist/cli/ui/screens/solid/ConfirmScreen.js +11 -3
- package/dist/cli/ui/screens/solid/ConfirmScreen.js.map +1 -1
- package/dist/cli/ui/screens/solid/EnvironmentScreen.d.ts.map +1 -1
- package/dist/cli/ui/screens/solid/EnvironmentScreen.js +9 -10
- package/dist/cli/ui/screens/solid/EnvironmentScreen.js.map +1 -1
- package/dist/cli/ui/screens/solid/LogScreen.d.ts +7 -1
- package/dist/cli/ui/screens/solid/LogScreen.d.ts.map +1 -1
- package/dist/cli/ui/screens/solid/LogScreen.js +254 -16
- package/dist/cli/ui/screens/solid/LogScreen.js.map +1 -1
- package/dist/cli/ui/screens/solid/ProfileEnvScreen.d.ts.map +1 -1
- package/dist/cli/ui/screens/solid/ProfileEnvScreen.js +8 -5
- package/dist/cli/ui/screens/solid/ProfileEnvScreen.js.map +1 -1
- package/dist/cli/ui/screens/solid/SelectorScreen.d.ts.map +1 -1
- package/dist/cli/ui/screens/solid/SelectorScreen.js +12 -4
- package/dist/cli/ui/screens/solid/SelectorScreen.js.map +1 -1
- package/dist/cli/ui/types.d.ts +1 -0
- package/dist/cli/ui/types.d.ts.map +1 -1
- package/dist/cli/ui/utils/branchFormatter.d.ts +1 -0
- package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
- package/dist/cli/ui/utils/branchFormatter.js +29 -7
- package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
- package/dist/cli/ui/utils/continueSession.d.ts +14 -0
- package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
- package/dist/cli/ui/utils/continueSession.js +61 -3
- package/dist/cli/ui/utils/continueSession.js.map +1 -1
- package/dist/cli/ui/utils/installedVersionCache.d.ts +33 -0
- package/dist/cli/ui/utils/installedVersionCache.d.ts.map +1 -0
- package/dist/cli/ui/utils/installedVersionCache.js +59 -0
- package/dist/cli/ui/utils/installedVersionCache.js.map +1 -0
- package/dist/cli/ui/utils/modelOptions.d.ts.map +1 -1
- package/dist/cli/ui/utils/modelOptions.js +16 -0
- package/dist/cli/ui/utils/modelOptions.js.map +1 -1
- package/dist/cli/ui/utils/versionCache.d.ts +37 -0
- package/dist/cli/ui/utils/versionCache.d.ts.map +1 -0
- package/dist/cli/ui/utils/versionCache.js +70 -0
- package/dist/cli/ui/utils/versionCache.js.map +1 -0
- package/dist/cli/ui/utils/versionFetcher.d.ts +41 -0
- package/dist/cli/ui/utils/versionFetcher.d.ts.map +1 -0
- package/dist/cli/ui/utils/versionFetcher.js +89 -0
- package/dist/cli/ui/utils/versionFetcher.js.map +1 -0
- package/dist/codex.d.ts +1 -0
- package/dist/codex.d.ts.map +1 -1
- package/dist/codex.js +95 -25
- package/dist/codex.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +10 -1
- package/dist/config/index.js.map +1 -1
- package/dist/gemini.d.ts +1 -0
- package/dist/gemini.d.ts.map +1 -1
- package/dist/gemini.js +36 -3
- package/dist/gemini.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -2
- package/dist/index.js.map +1 -1
- package/dist/launcher.d.ts.map +1 -1
- package/dist/launcher.js +43 -8
- package/dist/launcher.js.map +1 -1
- package/dist/logging/agentOutput.d.ts +21 -0
- package/dist/logging/agentOutput.d.ts.map +1 -0
- package/dist/logging/agentOutput.js +164 -0
- package/dist/logging/agentOutput.js.map +1 -0
- package/dist/logging/formatter.d.ts.map +1 -1
- package/dist/logging/formatter.js +18 -4
- package/dist/logging/formatter.js.map +1 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +2 -0
- package/dist/logging/logger.js.map +1 -1
- package/dist/logging/reader.d.ts +22 -0
- package/dist/logging/reader.d.ts.map +1 -1
- package/dist/logging/reader.js +116 -1
- package/dist/logging/reader.js.map +1 -1
- package/dist/opentui/index.solid.js +2575 -888
- package/dist/services/codingAgentResolver.d.ts.map +1 -1
- package/dist/services/codingAgentResolver.js +8 -6
- package/dist/services/codingAgentResolver.js.map +1 -1
- package/dist/services/dependency-installer.js +2 -2
- package/dist/services/dependency-installer.js.map +1 -1
- package/dist/shared/codingAgentConstants.d.ts +3 -0
- package/dist/shared/codingAgentConstants.d.ts.map +1 -1
- package/dist/shared/codingAgentConstants.js +66 -0
- package/dist/shared/codingAgentConstants.js.map +1 -1
- package/dist/utils/bun-runtime.d.ts +12 -0
- package/dist/utils/bun-runtime.d.ts.map +1 -0
- package/dist/utils/bun-runtime.js +13 -0
- package/dist/utils/bun-runtime.js.map +1 -0
- package/dist/utils/session/common.d.ts +8 -0
- package/dist/utils/session/common.d.ts.map +1 -1
- package/dist/utils/session/common.js +22 -0
- package/dist/utils/session/common.js.map +1 -1
- package/dist/utils/session/parsers/claude.d.ts +10 -4
- package/dist/utils/session/parsers/claude.d.ts.map +1 -1
- package/dist/utils/session/parsers/claude.js +64 -18
- package/dist/utils/session/parsers/claude.js.map +1 -1
- package/dist/utils/session/parsers/codex.d.ts.map +1 -1
- package/dist/utils/session/parsers/codex.js +47 -28
- package/dist/utils/session/parsers/codex.js.map +1 -1
- package/dist/utils/session/parsers/gemini.d.ts.map +1 -1
- package/dist/utils/session/parsers/gemini.js +43 -6
- package/dist/utils/session/parsers/gemini.js.map +1 -1
- package/dist/utils/session/parsers/opencode.d.ts.map +1 -1
- package/dist/utils/session/parsers/opencode.js +43 -6
- package/dist/utils/session/parsers/opencode.js.map +1 -1
- package/dist/utils/session/types.d.ts +7 -0
- package/dist/utils/session/types.d.ts.map +1 -1
- package/dist/web/client/src/components/ui/alert.d.ts +1 -1
- package/dist/worktree.d.ts +4 -1
- package/dist/worktree.d.ts.map +1 -1
- package/dist/worktree.js +21 -15
- package/dist/worktree.js.map +1 -1
- package/package.json +2 -1
- package/src/claude.ts +99 -28
- package/src/cli/ui/App.solid.tsx +373 -51
- package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +921 -1
- package/src/cli/ui/__tests__/solid/BranchListScreen.test.tsx +105 -5
- package/src/cli/ui/__tests__/solid/ConfirmScreen.test.tsx +77 -0
- package/src/cli/ui/__tests__/solid/LogScreen.test.tsx +351 -0
- package/src/cli/ui/__tests__/solid/components/QuickStartStep.test.tsx +73 -2
- package/src/cli/ui/__tests__/solid/components/WizardController.test.tsx +71 -0
- package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +95 -2
- package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +72 -45
- package/src/cli/ui/components/solid/QuickStartStep.tsx +35 -23
- package/src/cli/ui/components/solid/SearchInput.tsx +1 -1
- package/src/cli/ui/components/solid/SelectInput.tsx +4 -0
- package/src/cli/ui/components/solid/WizardController.tsx +85 -12
- package/src/cli/ui/components/solid/WizardSteps.tsx +78 -90
- package/src/cli/ui/core/theme.ts +32 -0
- package/src/cli/ui/hooks/solid/useAsyncOperation.ts +8 -6
- package/src/cli/ui/hooks/solid/useGitOperations.ts +6 -5
- package/src/cli/ui/screens/solid/BranchListScreen.tsx +135 -32
- package/src/cli/ui/screens/solid/ConfirmScreen.tsx +20 -8
- package/src/cli/ui/screens/solid/EnvironmentScreen.tsx +22 -20
- package/src/cli/ui/screens/solid/LogScreen.tsx +364 -35
- package/src/cli/ui/screens/solid/ProfileEnvScreen.tsx +19 -15
- package/src/cli/ui/screens/solid/SelectorScreen.tsx +25 -14
- package/src/cli/ui/screens/solid/SettingsScreen.tsx +5 -3
- package/src/cli/ui/types.ts +1 -0
- package/src/cli/ui/utils/__tests__/branchFormatter.test.ts +53 -6
- package/src/cli/ui/utils/__tests__/installedVersionCache.test.ts +46 -0
- package/src/cli/ui/utils/branchFormatter.ts +35 -7
- package/src/cli/ui/utils/continueSession.ts +90 -3
- package/src/cli/ui/utils/installedVersionCache.ts +84 -0
- package/src/cli/ui/utils/modelOptions.test.ts +6 -0
- package/src/cli/ui/utils/modelOptions.ts +16 -0
- package/src/cli/ui/utils/versionCache.ts +93 -0
- package/src/cli/ui/utils/versionFetcher.ts +120 -0
- package/src/codex.ts +124 -26
- package/src/config/__tests__/saveSession.test.ts +2 -2
- package/src/config/index.ts +11 -1
- package/src/gemini.ts +50 -4
- package/src/index.test.ts +16 -10
- package/src/index.ts +41 -1
- package/src/launcher.ts +49 -8
- package/src/logging/agentOutput.ts +216 -0
- package/src/logging/formatter.ts +23 -4
- package/src/logging/logger.ts +2 -0
- package/src/logging/reader.ts +165 -1
- package/src/services/__tests__/BatchMergeService.test.ts +34 -14
- package/src/services/codingAgentResolver.ts +12 -5
- package/src/services/dependency-installer.ts +2 -2
- package/src/shared/codingAgentConstants.ts +73 -0
- package/src/utils/bun-runtime.ts +29 -0
- package/src/utils/session/common.ts +28 -0
- package/src/utils/session/parsers/claude.ts +79 -29
- package/src/utils/session/parsers/codex.ts +49 -26
- package/src/utils/session/parsers/gemini.ts +46 -5
- package/src/utils/session/parsers/opencode.ts +46 -5
- package/src/utils/session/types.ts +4 -0
- package/src/worktree.ts +28 -15
|
@@ -28,6 +28,164 @@ var __export = (target, all) => {
|
|
|
28
28
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
29
29
|
var __require = import.meta.require;
|
|
30
30
|
|
|
31
|
+
// src/utils/npmRegistry.ts
|
|
32
|
+
function isPrerelease(version) {
|
|
33
|
+
return /-(alpha|beta|rc|canary|next|dev|pre)\b/i.test(version);
|
|
34
|
+
}
|
|
35
|
+
async function fetchPackageVersions(packageName, limit = DEFAULT_LIMIT, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
36
|
+
try {
|
|
37
|
+
const controller = new AbortController;
|
|
38
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
39
|
+
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`, {
|
|
40
|
+
signal: controller.signal,
|
|
41
|
+
headers: {
|
|
42
|
+
Accept: "application/json"
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
clearTimeout(timeoutId);
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
const data = await response.json();
|
|
50
|
+
if (!data.versions || !data.time) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
const versionsWithTime = [];
|
|
54
|
+
for (const version of Object.keys(data.versions)) {
|
|
55
|
+
const publishedAt = data.time[version];
|
|
56
|
+
if (publishedAt) {
|
|
57
|
+
versionsWithTime.push({ version, publishedAt });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
versionsWithTime.sort((a, b) => {
|
|
61
|
+
const dateA = new Date(a.publishedAt).getTime();
|
|
62
|
+
const dateB = new Date(b.publishedAt).getTime();
|
|
63
|
+
return dateB - dateA;
|
|
64
|
+
});
|
|
65
|
+
const topVersions = versionsWithTime.slice(0, limit);
|
|
66
|
+
return topVersions.map((v) => ({
|
|
67
|
+
version: v.version,
|
|
68
|
+
isPrerelease: isPrerelease(v.version),
|
|
69
|
+
publishedAt: v.publishedAt
|
|
70
|
+
}));
|
|
71
|
+
} catch {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function parsePackageCommand(command) {
|
|
76
|
+
if (command.startsWith("@")) {
|
|
77
|
+
const firstSlash = command.indexOf("/");
|
|
78
|
+
if (firstSlash === -1) {
|
|
79
|
+
return { packageName: command, version: null };
|
|
80
|
+
}
|
|
81
|
+
const afterScope = command.substring(firstSlash + 1);
|
|
82
|
+
const atIndex2 = afterScope.indexOf("@");
|
|
83
|
+
if (atIndex2 === -1) {
|
|
84
|
+
return { packageName: command, version: null };
|
|
85
|
+
}
|
|
86
|
+
const packageName2 = command.substring(0, firstSlash + 1 + atIndex2);
|
|
87
|
+
const version2 = afterScope.substring(atIndex2 + 1);
|
|
88
|
+
return { packageName: packageName2, version: version2 };
|
|
89
|
+
}
|
|
90
|
+
const atIndex = command.indexOf("@");
|
|
91
|
+
if (atIndex === -1) {
|
|
92
|
+
return { packageName: command, version: null };
|
|
93
|
+
}
|
|
94
|
+
const packageName = command.substring(0, atIndex);
|
|
95
|
+
const version = command.substring(atIndex + 1);
|
|
96
|
+
return { packageName, version };
|
|
97
|
+
}
|
|
98
|
+
var DEFAULT_TIMEOUT_MS = 3000, DEFAULT_LIMIT = 10;
|
|
99
|
+
|
|
100
|
+
// src/shared/codingAgentConstants.ts
|
|
101
|
+
var CLAUDE_PERMISSION_SKIP_ARGS, CODEX_DEFAULT_ARGS;
|
|
102
|
+
var init_codingAgentConstants = __esm(() => {
|
|
103
|
+
CLAUDE_PERMISSION_SKIP_ARGS = [
|
|
104
|
+
"--dangerously-skip-permissions"
|
|
105
|
+
];
|
|
106
|
+
CODEX_DEFAULT_ARGS = [
|
|
107
|
+
"--enable",
|
|
108
|
+
"web_search_request",
|
|
109
|
+
"--model=gpt-5.2-codex",
|
|
110
|
+
"--sandbox",
|
|
111
|
+
"workspace-write",
|
|
112
|
+
"-c",
|
|
113
|
+
"model_reasoning_effort=high",
|
|
114
|
+
"-c",
|
|
115
|
+
"model_reasoning_summaries=detailed",
|
|
116
|
+
"-c",
|
|
117
|
+
"sandbox_workspace_write.network_access=true",
|
|
118
|
+
"-c",
|
|
119
|
+
"shell_environment_policy.inherit=all",
|
|
120
|
+
"-c",
|
|
121
|
+
"shell_environment_policy.ignore_default_excludes=true",
|
|
122
|
+
"-c",
|
|
123
|
+
"shell_environment_policy.experimental_use_profile=true"
|
|
124
|
+
];
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// src/config/builtin-coding-agents.ts
|
|
128
|
+
var CLAUDE_CODE_TOOL, CODEX_CLI_TOOL, GEMINI_CLI_TOOL, OPENCODE_TOOL, BUILTIN_CODING_AGENTS;
|
|
129
|
+
var init_builtin_coding_agents = __esm(() => {
|
|
130
|
+
init_codingAgentConstants();
|
|
131
|
+
CLAUDE_CODE_TOOL = {
|
|
132
|
+
id: "claude-code",
|
|
133
|
+
displayName: "Claude Code",
|
|
134
|
+
type: "bunx",
|
|
135
|
+
command: "@anthropic-ai/claude-code",
|
|
136
|
+
modeArgs: {
|
|
137
|
+
normal: [],
|
|
138
|
+
continue: ["-c"],
|
|
139
|
+
resume: ["-r"]
|
|
140
|
+
},
|
|
141
|
+
permissionSkipArgs: Array.from(CLAUDE_PERMISSION_SKIP_ARGS),
|
|
142
|
+
env: {
|
|
143
|
+
ENABLE_LSP_TOOL: "true"
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
CODEX_CLI_TOOL = {
|
|
147
|
+
id: "codex-cli",
|
|
148
|
+
displayName: "Codex",
|
|
149
|
+
type: "bunx",
|
|
150
|
+
command: "@openai/codex",
|
|
151
|
+
defaultArgs: Array.from(CODEX_DEFAULT_ARGS),
|
|
152
|
+
modeArgs: {
|
|
153
|
+
normal: [],
|
|
154
|
+
continue: ["resume", "--last"],
|
|
155
|
+
resume: ["resume"]
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
GEMINI_CLI_TOOL = {
|
|
159
|
+
id: "gemini-cli",
|
|
160
|
+
displayName: "Gemini",
|
|
161
|
+
type: "bunx",
|
|
162
|
+
command: "@google/gemini-cli",
|
|
163
|
+
modeArgs: {
|
|
164
|
+
normal: [],
|
|
165
|
+
continue: ["-r", "latest"],
|
|
166
|
+
resume: ["-r", "latest"]
|
|
167
|
+
},
|
|
168
|
+
permissionSkipArgs: ["-y"]
|
|
169
|
+
};
|
|
170
|
+
OPENCODE_TOOL = {
|
|
171
|
+
id: "opencode",
|
|
172
|
+
displayName: "OpenCode",
|
|
173
|
+
type: "bunx",
|
|
174
|
+
command: "opencode-ai",
|
|
175
|
+
modeArgs: {
|
|
176
|
+
normal: [],
|
|
177
|
+
continue: ["-c"],
|
|
178
|
+
resume: ["-s"]
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
BUILTIN_CODING_AGENTS = [
|
|
182
|
+
CLAUDE_CODE_TOOL,
|
|
183
|
+
CODEX_CLI_TOOL,
|
|
184
|
+
GEMINI_CLI_TOOL,
|
|
185
|
+
OPENCODE_TOOL
|
|
186
|
+
];
|
|
187
|
+
});
|
|
188
|
+
|
|
31
189
|
// node_modules/is-plain-obj/index.js
|
|
32
190
|
function isPlainObject(value) {
|
|
33
191
|
if (typeof value !== "object" || value === null) {
|
|
@@ -3129,12 +3287,12 @@ var init_exports = __esm(() => {
|
|
|
3129
3287
|
});
|
|
3130
3288
|
|
|
3131
3289
|
// node_modules/get-stream/source/index.js
|
|
3132
|
-
import { on } from "events";
|
|
3290
|
+
import { on as on2 } from "events";
|
|
3133
3291
|
import { finished } from "stream/promises";
|
|
3134
3292
|
var init_source = __esm(() => {
|
|
3135
3293
|
init_stream();
|
|
3136
3294
|
init_exports();
|
|
3137
|
-
Object.assign(nodeImports, { on, finished });
|
|
3295
|
+
Object.assign(nodeImports, { on: on2, finished });
|
|
3138
3296
|
});
|
|
3139
3297
|
|
|
3140
3298
|
// node_modules/execa/lib/io/max-buffer.js
|
|
@@ -5044,7 +5202,7 @@ var init_main_sync = __esm(() => {
|
|
|
5044
5202
|
});
|
|
5045
5203
|
|
|
5046
5204
|
// node_modules/execa/lib/ipc/get-one.js
|
|
5047
|
-
import { once as once5, on as
|
|
5205
|
+
import { once as once5, on as on3 } from "events";
|
|
5048
5206
|
var getOneMessage = ({ anyProcess, channel, isSubprocess, ipc }, { reference = true, filter } = {}) => {
|
|
5049
5207
|
validateIpcMethod({
|
|
5050
5208
|
methodName: "getOneMessage",
|
|
@@ -5081,7 +5239,7 @@ var getOneMessage = ({ anyProcess, channel, isSubprocess, ipc }, { reference = t
|
|
|
5081
5239
|
const [message] = await once5(ipcEmitter, "message", { signal });
|
|
5082
5240
|
return message;
|
|
5083
5241
|
}
|
|
5084
|
-
for await (const [message] of
|
|
5242
|
+
for await (const [message] of on3(ipcEmitter, "message", { signal })) {
|
|
5085
5243
|
if (filter(message)) {
|
|
5086
5244
|
return message;
|
|
5087
5245
|
}
|
|
@@ -5099,7 +5257,7 @@ var init_get_one = __esm(() => {
|
|
|
5099
5257
|
});
|
|
5100
5258
|
|
|
5101
5259
|
// node_modules/execa/lib/ipc/get-each.js
|
|
5102
|
-
import { once as once6, on as
|
|
5260
|
+
import { once as once6, on as on4 } from "events";
|
|
5103
5261
|
var getEachMessage = ({ anyProcess, channel, isSubprocess, ipc }, { reference = true } = {}) => loopOnMessages({
|
|
5104
5262
|
anyProcess,
|
|
5105
5263
|
channel,
|
|
@@ -5148,7 +5306,7 @@ var getEachMessage = ({ anyProcess, channel, isSubprocess, ipc }, { reference =
|
|
|
5148
5306
|
} catch {}
|
|
5149
5307
|
}, iterateOnMessages = async function* ({ anyProcess, channel, ipcEmitter, isSubprocess, shouldAwait, controller, state, reference }) {
|
|
5150
5308
|
try {
|
|
5151
|
-
for await (const [message] of
|
|
5309
|
+
for await (const [message] of on4(ipcEmitter, "message", { signal: controller.signal })) {
|
|
5152
5310
|
throwIfStrictError(state);
|
|
5153
5311
|
yield message;
|
|
5154
5312
|
}
|
|
@@ -5316,7 +5474,7 @@ var init_handle_async = __esm(() => {
|
|
|
5316
5474
|
});
|
|
5317
5475
|
|
|
5318
5476
|
// node_modules/@sindresorhus/merge-streams/index.js
|
|
5319
|
-
import { on as
|
|
5477
|
+
import { on as on5, once as once7 } from "events";
|
|
5320
5478
|
import { PassThrough as PassThroughStream, getDefaultHighWaterMark as getDefaultHighWaterMark2 } from "stream";
|
|
5321
5479
|
import { finished as finished2 } from "stream/promises";
|
|
5322
5480
|
function mergeStreams(streams) {
|
|
@@ -5364,7 +5522,7 @@ var getHighWaterMark = (streams, objectMode) => {
|
|
|
5364
5522
|
throw error;
|
|
5365
5523
|
}
|
|
5366
5524
|
}, onInputStreamsUnpipe = async (passThroughStream, streams, unpipeEvent, { signal }) => {
|
|
5367
|
-
for await (const [unpipedStream] of
|
|
5525
|
+
for await (const [unpipedStream] of on5(passThroughStream, "unpipe", { signal })) {
|
|
5368
5526
|
if (streams.has(unpipedStream)) {
|
|
5369
5527
|
unpipedStream.emit(unpipeEvent);
|
|
5370
5528
|
}
|
|
@@ -6087,7 +6245,7 @@ var init_setup = __esm(() => {
|
|
|
6087
6245
|
});
|
|
6088
6246
|
|
|
6089
6247
|
// node_modules/execa/lib/io/iterate.js
|
|
6090
|
-
import { on as
|
|
6248
|
+
import { on as on6 } from "events";
|
|
6091
6249
|
import { getDefaultHighWaterMark as getDefaultHighWaterMark3 } from "stream";
|
|
6092
6250
|
var iterateOnSubprocessStream = ({ subprocessStdout, subprocess, binary, shouldEncode, encoding, preserveNewlines }) => {
|
|
6093
6251
|
const controller = new AbortController;
|
|
@@ -6129,7 +6287,7 @@ var iterateOnSubprocessStream = ({ subprocessStdout, subprocess, binary, shouldE
|
|
|
6129
6287
|
controller.abort();
|
|
6130
6288
|
}
|
|
6131
6289
|
}, iterateOnStream = ({ stream, controller, binary, shouldEncode, encoding, shouldSplit, preserveNewlines }) => {
|
|
6132
|
-
const onStdoutChunk =
|
|
6290
|
+
const onStdoutChunk = on6(stream, "data", {
|
|
6133
6291
|
signal: controller.signal,
|
|
6134
6292
|
highWaterMark: HIGH_WATER_MARK,
|
|
6135
6293
|
highWatermark: HIGH_WATER_MARK
|
|
@@ -7209,6 +7367,182 @@ var init_execa = __esm(() => {
|
|
|
7209
7367
|
} = getIpcExport());
|
|
7210
7368
|
});
|
|
7211
7369
|
|
|
7370
|
+
// src/utils/command.ts
|
|
7371
|
+
import { existsSync as existsSync3 } from "fs";
|
|
7372
|
+
import { homedir } from "os";
|
|
7373
|
+
import { join as join2 } from "path";
|
|
7374
|
+
async function getCommandVersion(commandPath) {
|
|
7375
|
+
try {
|
|
7376
|
+
const result = await execa(commandPath, ["--version"], {
|
|
7377
|
+
timeout: 3000,
|
|
7378
|
+
stdin: "ignore",
|
|
7379
|
+
stdout: "pipe",
|
|
7380
|
+
stderr: "ignore"
|
|
7381
|
+
});
|
|
7382
|
+
const match = result.stdout.match(/(\d+\.\d+(?:\.\d+)?(?:-[\w.]+)?)/);
|
|
7383
|
+
return match ? `v${match[1]}` : null;
|
|
7384
|
+
} catch {
|
|
7385
|
+
return null;
|
|
7386
|
+
}
|
|
7387
|
+
}
|
|
7388
|
+
async function findCommand(commandName) {
|
|
7389
|
+
const cached = commandLookupCache.get(commandName);
|
|
7390
|
+
if (cached) {
|
|
7391
|
+
return cached;
|
|
7392
|
+
}
|
|
7393
|
+
let lookupResult = null;
|
|
7394
|
+
try {
|
|
7395
|
+
const lookupCommand = process.platform === "win32" ? "where" : "which";
|
|
7396
|
+
const execResult = await execa(lookupCommand, [commandName], {
|
|
7397
|
+
shell: true,
|
|
7398
|
+
stdin: "ignore",
|
|
7399
|
+
stdout: "pipe",
|
|
7400
|
+
stderr: "ignore"
|
|
7401
|
+
});
|
|
7402
|
+
const foundPath = execResult.stdout.trim().split(`
|
|
7403
|
+
`)[0];
|
|
7404
|
+
if (foundPath) {
|
|
7405
|
+
lookupResult = { available: true, path: foundPath, source: "installed" };
|
|
7406
|
+
}
|
|
7407
|
+
} catch {}
|
|
7408
|
+
if (!lookupResult) {
|
|
7409
|
+
const knownPaths = KNOWN_INSTALL_PATHS[commandName];
|
|
7410
|
+
if (knownPaths) {
|
|
7411
|
+
const pathsToCheck = process.platform === "win32" ? knownPaths.win32 : knownPaths.unix;
|
|
7412
|
+
for (const p of pathsToCheck) {
|
|
7413
|
+
if (p && existsSync3(p)) {
|
|
7414
|
+
lookupResult = { available: true, path: p, source: "installed" };
|
|
7415
|
+
break;
|
|
7416
|
+
}
|
|
7417
|
+
}
|
|
7418
|
+
}
|
|
7419
|
+
}
|
|
7420
|
+
if (!lookupResult) {
|
|
7421
|
+
lookupResult = { available: true, path: null, source: "bunx" };
|
|
7422
|
+
}
|
|
7423
|
+
if (lookupResult.source === "installed" && lookupResult.path) {
|
|
7424
|
+
lookupResult.version = await getCommandVersion(lookupResult.path);
|
|
7425
|
+
} else {
|
|
7426
|
+
lookupResult.version = null;
|
|
7427
|
+
}
|
|
7428
|
+
commandLookupCache.set(commandName, lookupResult);
|
|
7429
|
+
return lookupResult;
|
|
7430
|
+
}
|
|
7431
|
+
var KNOWN_INSTALL_PATHS, commandLookupCache;
|
|
7432
|
+
var init_command3 = __esm(() => {
|
|
7433
|
+
init_execa();
|
|
7434
|
+
KNOWN_INSTALL_PATHS = {
|
|
7435
|
+
claude: {
|
|
7436
|
+
unix: [
|
|
7437
|
+
join2(homedir(), ".bun", "bin", "claude"),
|
|
7438
|
+
join2(homedir(), ".local", "bin", "claude"),
|
|
7439
|
+
"/usr/local/bin/claude"
|
|
7440
|
+
],
|
|
7441
|
+
win32: [
|
|
7442
|
+
join2(process.env.LOCALAPPDATA ?? "", "Programs", "claude", "claude.exe"),
|
|
7443
|
+
join2(homedir(), ".bun", "bin", "claude.exe")
|
|
7444
|
+
]
|
|
7445
|
+
},
|
|
7446
|
+
codex: {
|
|
7447
|
+
unix: [
|
|
7448
|
+
join2(homedir(), ".bun", "bin", "codex"),
|
|
7449
|
+
join2(homedir(), ".local", "bin", "codex"),
|
|
7450
|
+
"/usr/local/bin/codex"
|
|
7451
|
+
],
|
|
7452
|
+
win32: [join2(homedir(), ".bun", "bin", "codex.exe")]
|
|
7453
|
+
},
|
|
7454
|
+
gemini: {
|
|
7455
|
+
unix: [
|
|
7456
|
+
join2(homedir(), ".bun", "bin", "gemini"),
|
|
7457
|
+
join2(homedir(), ".local", "bin", "gemini"),
|
|
7458
|
+
"/usr/local/bin/gemini"
|
|
7459
|
+
],
|
|
7460
|
+
win32: [join2(homedir(), ".bun", "bin", "gemini.exe")]
|
|
7461
|
+
},
|
|
7462
|
+
opencode: {
|
|
7463
|
+
unix: [
|
|
7464
|
+
join2(homedir(), ".bun", "bin", "opencode"),
|
|
7465
|
+
join2(homedir(), ".local", "bin", "opencode"),
|
|
7466
|
+
"/usr/local/bin/opencode"
|
|
7467
|
+
],
|
|
7468
|
+
win32: [join2(homedir(), ".bun", "bin", "opencode.exe")]
|
|
7469
|
+
}
|
|
7470
|
+
};
|
|
7471
|
+
commandLookupCache = new Map;
|
|
7472
|
+
});
|
|
7473
|
+
|
|
7474
|
+
// src/cli/ui/utils/versionFetcher.ts
|
|
7475
|
+
var exports_versionFetcher = {};
|
|
7476
|
+
__export(exports_versionFetcher, {
|
|
7477
|
+
versionInfoToSelectItem: () => versionInfoToSelectItem,
|
|
7478
|
+
getPackageNameForAgent: () => getPackageNameForAgent,
|
|
7479
|
+
getBunxAgentIds: () => getBunxAgentIds,
|
|
7480
|
+
fetchVersionOptionsForAgent: () => fetchVersionOptionsForAgent,
|
|
7481
|
+
fetchInstalledVersionForAgent: () => fetchInstalledVersionForAgent,
|
|
7482
|
+
createInstalledOption: () => createInstalledOption
|
|
7483
|
+
});
|
|
7484
|
+
function getPackageNameForAgent(agentId) {
|
|
7485
|
+
const agent = BUILTIN_CODING_AGENTS.find((a2) => a2.id === agentId);
|
|
7486
|
+
if (!agent || agent.type !== "bunx") {
|
|
7487
|
+
return null;
|
|
7488
|
+
}
|
|
7489
|
+
const { packageName } = parsePackageCommand(agent.command);
|
|
7490
|
+
return packageName;
|
|
7491
|
+
}
|
|
7492
|
+
async function fetchVersionOptionsForAgent(agentId) {
|
|
7493
|
+
const packageName = getPackageNameForAgent(agentId);
|
|
7494
|
+
if (!packageName) {
|
|
7495
|
+
return [];
|
|
7496
|
+
}
|
|
7497
|
+
return fetchPackageVersions(packageName);
|
|
7498
|
+
}
|
|
7499
|
+
async function fetchInstalledVersionForAgent(agentId) {
|
|
7500
|
+
const commandName = AGENT_COMMAND_MAP[agentId];
|
|
7501
|
+
if (!commandName) {
|
|
7502
|
+
return null;
|
|
7503
|
+
}
|
|
7504
|
+
const result = await findCommand(commandName);
|
|
7505
|
+
if (result.source !== "installed" || !result.path) {
|
|
7506
|
+
return null;
|
|
7507
|
+
}
|
|
7508
|
+
const version = result.version?.replace(/^v/, "") ?? "unknown";
|
|
7509
|
+
return {
|
|
7510
|
+
version,
|
|
7511
|
+
path: result.path
|
|
7512
|
+
};
|
|
7513
|
+
}
|
|
7514
|
+
function versionInfoToSelectItem(v) {
|
|
7515
|
+
const item = {
|
|
7516
|
+
label: v.isPrerelease ? `${v.version} (pre)` : v.version,
|
|
7517
|
+
value: v.version
|
|
7518
|
+
};
|
|
7519
|
+
if (v.publishedAt) {
|
|
7520
|
+
item.description = new Date(v.publishedAt).toLocaleDateString();
|
|
7521
|
+
}
|
|
7522
|
+
return item;
|
|
7523
|
+
}
|
|
7524
|
+
function createInstalledOption(installed) {
|
|
7525
|
+
return {
|
|
7526
|
+
label: `installed@${installed.version}`,
|
|
7527
|
+
value: "installed",
|
|
7528
|
+
description: installed.path
|
|
7529
|
+
};
|
|
7530
|
+
}
|
|
7531
|
+
function getBunxAgentIds() {
|
|
7532
|
+
return BUILTIN_CODING_AGENTS.filter((a2) => a2.type === "bunx").map((a2) => a2.id);
|
|
7533
|
+
}
|
|
7534
|
+
var AGENT_COMMAND_MAP;
|
|
7535
|
+
var init_versionFetcher = __esm(() => {
|
|
7536
|
+
init_builtin_coding_agents();
|
|
7537
|
+
init_command3();
|
|
7538
|
+
AGENT_COMMAND_MAP = {
|
|
7539
|
+
"claude-code": "claude",
|
|
7540
|
+
"codex-cli": "codex",
|
|
7541
|
+
"gemini-cli": "gemini",
|
|
7542
|
+
opencode: "opencode"
|
|
7543
|
+
};
|
|
7544
|
+
});
|
|
7545
|
+
|
|
7212
7546
|
// node_modules/pino-std-serializers/lib/err-helpers.js
|
|
7213
7547
|
var require_err_helpers = __commonJS((exports, module2) => {
|
|
7214
7548
|
var isErrorLike = (err) => {
|
|
@@ -42550,7 +42884,6 @@ var UNOWNED = {
|
|
|
42550
42884
|
context: null,
|
|
42551
42885
|
owner: null
|
|
42552
42886
|
};
|
|
42553
|
-
var NO_INIT = {};
|
|
42554
42887
|
var Owner = null;
|
|
42555
42888
|
var Transition = null;
|
|
42556
42889
|
var Scheduler = null;
|
|
@@ -42594,13 +42927,6 @@ function createSignal(value, options) {
|
|
|
42594
42927
|
};
|
|
42595
42928
|
return [readSignal.bind(s), setter];
|
|
42596
42929
|
}
|
|
42597
|
-
function createComputed(fn, value, options) {
|
|
42598
|
-
const c = createComputation(fn, value, true, STALE);
|
|
42599
|
-
if (Scheduler && Transition && Transition.running)
|
|
42600
|
-
Updates.push(c);
|
|
42601
|
-
else
|
|
42602
|
-
updateComputation(c);
|
|
42603
|
-
}
|
|
42604
42930
|
function createRenderEffect(fn, value, options) {
|
|
42605
42931
|
const c = createComputation(fn, value, false, STALE);
|
|
42606
42932
|
if (Scheduler && Transition && Transition.running)
|
|
@@ -42630,163 +42956,8 @@ function createMemo(fn, value, options) {
|
|
|
42630
42956
|
updateComputation(c);
|
|
42631
42957
|
return readSignal.bind(c);
|
|
42632
42958
|
}
|
|
42633
|
-
function
|
|
42634
|
-
return
|
|
42635
|
-
}
|
|
42636
|
-
function createResource(pSource, pFetcher, pOptions) {
|
|
42637
|
-
let source;
|
|
42638
|
-
let fetcher;
|
|
42639
|
-
let options;
|
|
42640
|
-
if (typeof pFetcher === "function") {
|
|
42641
|
-
source = pSource;
|
|
42642
|
-
fetcher = pFetcher;
|
|
42643
|
-
options = pOptions || {};
|
|
42644
|
-
} else {
|
|
42645
|
-
source = true;
|
|
42646
|
-
fetcher = pSource;
|
|
42647
|
-
options = pFetcher || {};
|
|
42648
|
-
}
|
|
42649
|
-
let pr = null, initP = NO_INIT, id = null, loadedUnderTransition = false, scheduled = false, resolved = "initialValue" in options, dynamic = typeof source === "function" && createMemo(source);
|
|
42650
|
-
const contexts = new Set, [value, setValue] = (options.storage || createSignal)(options.initialValue), [error, setError] = createSignal(undefined), [track, trigger] = createSignal(undefined, {
|
|
42651
|
-
equals: false
|
|
42652
|
-
}), [state, setState] = createSignal(resolved ? "ready" : "unresolved");
|
|
42653
|
-
if (sharedConfig.context) {
|
|
42654
|
-
id = sharedConfig.getNextContextId();
|
|
42655
|
-
if (options.ssrLoadFrom === "initial")
|
|
42656
|
-
initP = options.initialValue;
|
|
42657
|
-
else if (sharedConfig.load && sharedConfig.has(id))
|
|
42658
|
-
initP = sharedConfig.load(id);
|
|
42659
|
-
}
|
|
42660
|
-
function loadEnd(p, v, error2, key) {
|
|
42661
|
-
if (pr === p) {
|
|
42662
|
-
pr = null;
|
|
42663
|
-
key !== undefined && (resolved = true);
|
|
42664
|
-
if ((p === initP || v === initP) && options.onHydrated)
|
|
42665
|
-
queueMicrotask(() => options.onHydrated(key, {
|
|
42666
|
-
value: v
|
|
42667
|
-
}));
|
|
42668
|
-
initP = NO_INIT;
|
|
42669
|
-
if (Transition && p && loadedUnderTransition) {
|
|
42670
|
-
Transition.promises.delete(p);
|
|
42671
|
-
loadedUnderTransition = false;
|
|
42672
|
-
runUpdates(() => {
|
|
42673
|
-
Transition.running = true;
|
|
42674
|
-
completeLoad(v, error2);
|
|
42675
|
-
}, false);
|
|
42676
|
-
} else
|
|
42677
|
-
completeLoad(v, error2);
|
|
42678
|
-
}
|
|
42679
|
-
return v;
|
|
42680
|
-
}
|
|
42681
|
-
function completeLoad(v, err) {
|
|
42682
|
-
runUpdates(() => {
|
|
42683
|
-
if (err === undefined)
|
|
42684
|
-
setValue(() => v);
|
|
42685
|
-
setState(err !== undefined ? "errored" : resolved ? "ready" : "unresolved");
|
|
42686
|
-
setError(err);
|
|
42687
|
-
for (const c of contexts.keys())
|
|
42688
|
-
c.decrement();
|
|
42689
|
-
contexts.clear();
|
|
42690
|
-
}, false);
|
|
42691
|
-
}
|
|
42692
|
-
function read() {
|
|
42693
|
-
const c = SuspenseContext && useContext(SuspenseContext), v = value(), err = error();
|
|
42694
|
-
if (err !== undefined && !pr)
|
|
42695
|
-
throw err;
|
|
42696
|
-
if (Listener && !Listener.user && c) {
|
|
42697
|
-
createComputed(() => {
|
|
42698
|
-
track();
|
|
42699
|
-
if (pr) {
|
|
42700
|
-
if (c.resolved && Transition && loadedUnderTransition)
|
|
42701
|
-
Transition.promises.add(pr);
|
|
42702
|
-
else if (!contexts.has(c)) {
|
|
42703
|
-
c.increment();
|
|
42704
|
-
contexts.add(c);
|
|
42705
|
-
}
|
|
42706
|
-
}
|
|
42707
|
-
});
|
|
42708
|
-
}
|
|
42709
|
-
return v;
|
|
42710
|
-
}
|
|
42711
|
-
function load(refetching = true) {
|
|
42712
|
-
if (refetching !== false && scheduled)
|
|
42713
|
-
return;
|
|
42714
|
-
scheduled = false;
|
|
42715
|
-
const lookup = dynamic ? dynamic() : source;
|
|
42716
|
-
loadedUnderTransition = Transition && Transition.running;
|
|
42717
|
-
if (lookup == null || lookup === false) {
|
|
42718
|
-
loadEnd(pr, untrack(value));
|
|
42719
|
-
return;
|
|
42720
|
-
}
|
|
42721
|
-
if (Transition && pr)
|
|
42722
|
-
Transition.promises.delete(pr);
|
|
42723
|
-
let error2;
|
|
42724
|
-
const p = initP !== NO_INIT ? initP : untrack(() => {
|
|
42725
|
-
try {
|
|
42726
|
-
return fetcher(lookup, {
|
|
42727
|
-
value: value(),
|
|
42728
|
-
refetching
|
|
42729
|
-
});
|
|
42730
|
-
} catch (fetcherError) {
|
|
42731
|
-
error2 = fetcherError;
|
|
42732
|
-
}
|
|
42733
|
-
});
|
|
42734
|
-
if (error2 !== undefined) {
|
|
42735
|
-
loadEnd(pr, undefined, castError(error2), lookup);
|
|
42736
|
-
return;
|
|
42737
|
-
} else if (!isPromise(p)) {
|
|
42738
|
-
loadEnd(pr, p, undefined, lookup);
|
|
42739
|
-
return p;
|
|
42740
|
-
}
|
|
42741
|
-
pr = p;
|
|
42742
|
-
if ("v" in p) {
|
|
42743
|
-
if (p.s === 1)
|
|
42744
|
-
loadEnd(pr, p.v, undefined, lookup);
|
|
42745
|
-
else
|
|
42746
|
-
loadEnd(pr, undefined, castError(p.v), lookup);
|
|
42747
|
-
return p;
|
|
42748
|
-
}
|
|
42749
|
-
scheduled = true;
|
|
42750
|
-
queueMicrotask(() => scheduled = false);
|
|
42751
|
-
runUpdates(() => {
|
|
42752
|
-
setState(resolved ? "refreshing" : "pending");
|
|
42753
|
-
trigger();
|
|
42754
|
-
}, false);
|
|
42755
|
-
return p.then((v) => loadEnd(p, v, undefined, lookup), (e) => loadEnd(p, undefined, castError(e), lookup));
|
|
42756
|
-
}
|
|
42757
|
-
Object.defineProperties(read, {
|
|
42758
|
-
state: {
|
|
42759
|
-
get: () => state()
|
|
42760
|
-
},
|
|
42761
|
-
error: {
|
|
42762
|
-
get: () => error()
|
|
42763
|
-
},
|
|
42764
|
-
loading: {
|
|
42765
|
-
get() {
|
|
42766
|
-
const s = state();
|
|
42767
|
-
return s === "pending" || s === "refreshing";
|
|
42768
|
-
}
|
|
42769
|
-
},
|
|
42770
|
-
latest: {
|
|
42771
|
-
get() {
|
|
42772
|
-
if (!resolved)
|
|
42773
|
-
return read();
|
|
42774
|
-
const err = error();
|
|
42775
|
-
if (err && !pr)
|
|
42776
|
-
throw err;
|
|
42777
|
-
return value();
|
|
42778
|
-
}
|
|
42779
|
-
}
|
|
42780
|
-
});
|
|
42781
|
-
let owner = Owner;
|
|
42782
|
-
if (dynamic)
|
|
42783
|
-
createComputed(() => (owner = Owner, load(false)));
|
|
42784
|
-
else
|
|
42785
|
-
load(false);
|
|
42786
|
-
return [read, {
|
|
42787
|
-
refetch: (info) => runWithOwner(owner, () => load(info)),
|
|
42788
|
-
mutate: setValue
|
|
42789
|
-
}];
|
|
42959
|
+
function batch(fn) {
|
|
42960
|
+
return runUpdates(fn, false);
|
|
42790
42961
|
}
|
|
42791
42962
|
function untrack(fn) {
|
|
42792
42963
|
if (!ExternalSourceConfig && Listener === null)
|
|
@@ -42801,6 +42972,27 @@ function untrack(fn) {
|
|
|
42801
42972
|
Listener = listener;
|
|
42802
42973
|
}
|
|
42803
42974
|
}
|
|
42975
|
+
function on(deps, fn, options) {
|
|
42976
|
+
const isArray = Array.isArray(deps);
|
|
42977
|
+
let prevInput;
|
|
42978
|
+
let defer = options && options.defer;
|
|
42979
|
+
return (prevValue) => {
|
|
42980
|
+
let input;
|
|
42981
|
+
if (isArray) {
|
|
42982
|
+
input = Array(deps.length);
|
|
42983
|
+
for (let i = 0;i < deps.length; i++)
|
|
42984
|
+
input[i] = deps[i]();
|
|
42985
|
+
} else
|
|
42986
|
+
input = deps();
|
|
42987
|
+
if (defer) {
|
|
42988
|
+
defer = false;
|
|
42989
|
+
return prevValue;
|
|
42990
|
+
}
|
|
42991
|
+
const result = untrack(() => fn(input, prevInput, prevValue));
|
|
42992
|
+
prevInput = input;
|
|
42993
|
+
return result;
|
|
42994
|
+
};
|
|
42995
|
+
}
|
|
42804
42996
|
function onMount(fn) {
|
|
42805
42997
|
createEffect(() => untrack(fn));
|
|
42806
42998
|
}
|
|
@@ -42813,20 +43005,6 @@ function onCleanup(fn) {
|
|
|
42813
43005
|
Owner.cleanups.push(fn);
|
|
42814
43006
|
return fn;
|
|
42815
43007
|
}
|
|
42816
|
-
function runWithOwner(o, fn) {
|
|
42817
|
-
const prev = Owner;
|
|
42818
|
-
const prevListener = Listener;
|
|
42819
|
-
Owner = o;
|
|
42820
|
-
Listener = null;
|
|
42821
|
-
try {
|
|
42822
|
-
return runUpdates(fn, true);
|
|
42823
|
-
} catch (err) {
|
|
42824
|
-
handleError(err);
|
|
42825
|
-
} finally {
|
|
42826
|
-
Owner = prev;
|
|
42827
|
-
Listener = prevListener;
|
|
42828
|
-
}
|
|
42829
|
-
}
|
|
42830
43008
|
function startTransition(fn) {
|
|
42831
43009
|
if (Transition && Transition.running) {
|
|
42832
43010
|
fn();
|
|
@@ -44312,14 +44490,36 @@ function mapToolLabel(toolId, toolLabel) {
|
|
|
44312
44490
|
return toolLabel;
|
|
44313
44491
|
return "Custom";
|
|
44314
44492
|
}
|
|
44493
|
+
var LOCAL_DATE_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
|
|
44494
|
+
year: "numeric",
|
|
44495
|
+
month: "2-digit",
|
|
44496
|
+
day: "2-digit",
|
|
44497
|
+
hour: "2-digit",
|
|
44498
|
+
minute: "2-digit",
|
|
44499
|
+
hour12: false
|
|
44500
|
+
});
|
|
44501
|
+
var formatLocalDateTimeParts = (date) => {
|
|
44502
|
+
const parts = LOCAL_DATE_TIME_FORMATTER.formatToParts(date);
|
|
44503
|
+
const get = (type) => parts.find((part) => part.type === type)?.value;
|
|
44504
|
+
const year = get("year");
|
|
44505
|
+
const month = get("month");
|
|
44506
|
+
const day = get("day");
|
|
44507
|
+
const hour = get("hour");
|
|
44508
|
+
const minute = get("minute");
|
|
44509
|
+
if (!year || !month || !day || !hour || !minute) {
|
|
44510
|
+
return LOCAL_DATE_TIME_FORMATTER.format(date);
|
|
44511
|
+
}
|
|
44512
|
+
return `${year}-${month}-${day} ${hour}:${minute}`;
|
|
44513
|
+
};
|
|
44514
|
+
function formatLocalDateTime(timestampMs) {
|
|
44515
|
+
const date = new Date(timestampMs);
|
|
44516
|
+
if (Number.isNaN(date.getTime())) {
|
|
44517
|
+
return "";
|
|
44518
|
+
}
|
|
44519
|
+
return formatLocalDateTimeParts(date);
|
|
44520
|
+
}
|
|
44315
44521
|
function formatTimestamp(ts) {
|
|
44316
|
-
|
|
44317
|
-
const year = date.getFullYear();
|
|
44318
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
44319
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
44320
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
44321
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
44322
|
-
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
44522
|
+
return formatLocalDateTime(ts);
|
|
44323
44523
|
}
|
|
44324
44524
|
function buildLastToolUsageLabel(usage) {
|
|
44325
44525
|
if (!usage)
|
|
@@ -44616,6 +44816,98 @@ function Header({
|
|
|
44616
44816
|
})();
|
|
44617
44817
|
}
|
|
44618
44818
|
|
|
44819
|
+
// src/cli/ui/core/theme.ts
|
|
44820
|
+
var colors = {
|
|
44821
|
+
primary: "cyan",
|
|
44822
|
+
secondary: "gray",
|
|
44823
|
+
success: "green",
|
|
44824
|
+
warning: "yellow",
|
|
44825
|
+
error: "red",
|
|
44826
|
+
info: "blue",
|
|
44827
|
+
text: "white",
|
|
44828
|
+
textDim: "gray",
|
|
44829
|
+
textMuted: "gray",
|
|
44830
|
+
selected: "cyan",
|
|
44831
|
+
highlighted: "cyan",
|
|
44832
|
+
disabled: "gray",
|
|
44833
|
+
selectionBackground: "cyan",
|
|
44834
|
+
selectionText: "black",
|
|
44835
|
+
branchFeature: "green",
|
|
44836
|
+
branchBugfix: "yellow",
|
|
44837
|
+
branchHotfix: "red",
|
|
44838
|
+
branchRelease: "magenta",
|
|
44839
|
+
branchMain: "cyan",
|
|
44840
|
+
branchDevelop: "blue",
|
|
44841
|
+
branchOther: "gray",
|
|
44842
|
+
syncUpToDate: "green",
|
|
44843
|
+
syncAhead: "cyan",
|
|
44844
|
+
syncBehind: "yellow",
|
|
44845
|
+
syncDiverged: "red",
|
|
44846
|
+
syncNoUpstream: "gray",
|
|
44847
|
+
worktreeActive: "green",
|
|
44848
|
+
worktreeInaccessible: "red",
|
|
44849
|
+
progressFilled: "green",
|
|
44850
|
+
progressEmpty: "gray",
|
|
44851
|
+
progressPhase: "yellow",
|
|
44852
|
+
progressTime: "magenta"
|
|
44853
|
+
};
|
|
44854
|
+
var logLevelColors = {
|
|
44855
|
+
TRACE: colors.textDim,
|
|
44856
|
+
DEBUG: colors.info,
|
|
44857
|
+
INFO: colors.success,
|
|
44858
|
+
WARN: colors.warning,
|
|
44859
|
+
ERROR: colors.error,
|
|
44860
|
+
FATAL: colors.error
|
|
44861
|
+
};
|
|
44862
|
+
var selectionStyle = {
|
|
44863
|
+
fg: colors.selectionText,
|
|
44864
|
+
bg: colors.selectionBackground
|
|
44865
|
+
};
|
|
44866
|
+
var getLogLevelColor = (label) => {
|
|
44867
|
+
if (!label) {
|
|
44868
|
+
return colors.text;
|
|
44869
|
+
}
|
|
44870
|
+
const normalized = label.toUpperCase();
|
|
44871
|
+
return logLevelColors[normalized] ?? colors.text;
|
|
44872
|
+
};
|
|
44873
|
+
var icons = {
|
|
44874
|
+
pointer: ">",
|
|
44875
|
+
pointerBold: ">",
|
|
44876
|
+
arrowUp: "^",
|
|
44877
|
+
arrowDown: "v",
|
|
44878
|
+
arrowLeft: "<",
|
|
44879
|
+
arrowRight: ">",
|
|
44880
|
+
success: "OK",
|
|
44881
|
+
error: "X",
|
|
44882
|
+
warning: "!",
|
|
44883
|
+
info: "i",
|
|
44884
|
+
skipped: "-",
|
|
44885
|
+
worktree: "W",
|
|
44886
|
+
worktreeActive: "A",
|
|
44887
|
+
worktreeInaccessible: "X",
|
|
44888
|
+
changes: "C",
|
|
44889
|
+
unpushed: "U",
|
|
44890
|
+
current: "*",
|
|
44891
|
+
pr: "PR",
|
|
44892
|
+
merged: "M",
|
|
44893
|
+
syncUpToDate: "=",
|
|
44894
|
+
syncAhead: ">",
|
|
44895
|
+
syncBehind: "<",
|
|
44896
|
+
syncDiverged: "!",
|
|
44897
|
+
spinnerFrames: ["|", "/", "-", "\\"],
|
|
44898
|
+
bullet: "*",
|
|
44899
|
+
divider: "-",
|
|
44900
|
+
verticalLine: "|",
|
|
44901
|
+
corner: "+",
|
|
44902
|
+
branch: "+"
|
|
44903
|
+
};
|
|
44904
|
+
var statsItemsConfig = {
|
|
44905
|
+
local: { label: "Local", icon: "L", color: colors.primary },
|
|
44906
|
+
remote: { label: "Remote", icon: "R", color: colors.info },
|
|
44907
|
+
worktree: { label: "Worktrees", icon: icons.worktree, color: colors.success },
|
|
44908
|
+
changes: { label: "Changes", icon: icons.changes, color: colors.warning }
|
|
44909
|
+
};
|
|
44910
|
+
|
|
44619
44911
|
// src/cli/ui/screens/solid/BranchListScreen.tsx
|
|
44620
44912
|
var VIEW_MODES = ["all", "local", "remote"];
|
|
44621
44913
|
var getCharWidth = (char) => stringWidth(char);
|
|
@@ -44724,8 +45016,8 @@ var fitSegmentsToWidth = (segments, width) => {
|
|
|
44724
45016
|
};
|
|
44725
45017
|
var applySelectionStyle = (segments) => segments.map((segment) => ({
|
|
44726
45018
|
text: segment.text,
|
|
44727
|
-
fg:
|
|
44728
|
-
bg:
|
|
45019
|
+
fg: selectionStyle.fg,
|
|
45020
|
+
bg: selectionStyle.bg
|
|
44729
45021
|
}));
|
|
44730
45022
|
var CLEANUP_SPINNER_FRAMES = ["-", "\\", "|", "/"];
|
|
44731
45023
|
var CURSOR_FRAMES = ["|", " "];
|
|
@@ -44805,7 +45097,13 @@ function BranchListScreen(props) {
|
|
|
44805
45097
|
const [filterQuery, setFilterQuery] = createSignal("");
|
|
44806
45098
|
const [filterMode, setFilterMode] = createSignal(false);
|
|
44807
45099
|
const [viewMode, setViewMode] = createSignal("all");
|
|
44808
|
-
const [
|
|
45100
|
+
const [internalSelectedIndex, setInternalSelectedIndex] = createSignal(props.cursorPosition ?? 0);
|
|
45101
|
+
const selectedIndex = () => props.cursorPosition ?? internalSelectedIndex();
|
|
45102
|
+
const setSelectedIndex = (value) => {
|
|
45103
|
+
const newValue = typeof value === "function" ? value(selectedIndex()) : value;
|
|
45104
|
+
setInternalSelectedIndex(newValue);
|
|
45105
|
+
props.onCursorPositionChange?.(newValue);
|
|
45106
|
+
};
|
|
44809
45107
|
const [scrollOffset, setScrollOffset] = createSignal(0);
|
|
44810
45108
|
const [cleanupSpinnerIndex, setCleanupSpinnerIndex] = createSignal(0);
|
|
44811
45109
|
const [cursorIndex, setCursorIndex] = createSignal(0);
|
|
@@ -44833,7 +45131,14 @@ function BranchListScreen(props) {
|
|
|
44833
45131
|
return Object.values(props.cleanupUI.indicators).some((indicator) => indicator.isSpinning);
|
|
44834
45132
|
});
|
|
44835
45133
|
const hasSpinningFooter = createMemo(() => props.cleanupUI?.footerMessage?.isSpinning ?? false);
|
|
44836
|
-
const
|
|
45134
|
+
const safetyPendingActive = createMemo(() => {
|
|
45135
|
+
const pending = props.cleanupUI?.safetyPendingBranches;
|
|
45136
|
+
if (pending) {
|
|
45137
|
+
return pending.size > 0;
|
|
45138
|
+
}
|
|
45139
|
+
return props.cleanupUI?.safetyLoading === true;
|
|
45140
|
+
});
|
|
45141
|
+
const cleanupSpinnerActive = createMemo(() => hasSpinningIndicator() || hasSpinningFooter() || safetyPendingActive());
|
|
44837
45142
|
createEffect(() => {
|
|
44838
45143
|
let intervalTimer;
|
|
44839
45144
|
if (cleanupSpinnerActive()) {
|
|
@@ -44884,12 +45189,12 @@ function BranchListScreen(props) {
|
|
|
44884
45189
|
}
|
|
44885
45190
|
return maxWidth;
|
|
44886
45191
|
});
|
|
44887
|
-
createEffect(() => {
|
|
44888
|
-
filterQuery();
|
|
44889
|
-
viewMode();
|
|
45192
|
+
createEffect(on(() => [filterQuery(), viewMode()], () => {
|
|
44890
45193
|
setSelectedIndex(0);
|
|
44891
45194
|
setScrollOffset(0);
|
|
44892
|
-
}
|
|
45195
|
+
}, {
|
|
45196
|
+
defer: true
|
|
45197
|
+
}));
|
|
44893
45198
|
createEffect(() => {
|
|
44894
45199
|
const total = filteredBranches().length;
|
|
44895
45200
|
if (total === 0) {
|
|
@@ -44937,18 +45242,16 @@ function BranchListScreen(props) {
|
|
|
44937
45242
|
if (!timestamp || Number.isNaN(timestamp)) {
|
|
44938
45243
|
return "---";
|
|
44939
45244
|
}
|
|
44940
|
-
const
|
|
44941
|
-
|
|
44942
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
44943
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
44944
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
44945
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
44946
|
-
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
|
45245
|
+
const formatted = formatLocalDateTime(timestamp * 1000);
|
|
45246
|
+
return formatted || "---";
|
|
44947
45247
|
};
|
|
44948
45248
|
useKeyboard((key) => {
|
|
44949
45249
|
if (props.wizardVisible) {
|
|
44950
45250
|
return;
|
|
44951
45251
|
}
|
|
45252
|
+
if (props.confirmVisible) {
|
|
45253
|
+
return;
|
|
45254
|
+
}
|
|
44952
45255
|
if (props.helpVisible) {
|
|
44953
45256
|
return;
|
|
44954
45257
|
}
|
|
@@ -45054,7 +45357,8 @@ function BranchListScreen(props) {
|
|
|
45054
45357
|
} else if (key.name === "p" || key.sequence === "p") {
|
|
45055
45358
|
props.onOpenProfiles?.();
|
|
45056
45359
|
} else if (key.name === "l" || key.sequence === "l") {
|
|
45057
|
-
|
|
45360
|
+
const selected = filteredBranches()[selectedIndex()] ?? null;
|
|
45361
|
+
props.onOpenLogs?.(selected);
|
|
45058
45362
|
}
|
|
45059
45363
|
});
|
|
45060
45364
|
const visibleBranches = createMemo(() => {
|
|
@@ -45082,19 +45386,24 @@ function BranchListScreen(props) {
|
|
|
45082
45386
|
let worktreeColor = "gray";
|
|
45083
45387
|
if (branch.worktreeStatus === "active") {
|
|
45084
45388
|
worktreeIcon = "w";
|
|
45085
|
-
worktreeColor = "
|
|
45389
|
+
worktreeColor = "brightGreen";
|
|
45086
45390
|
} else if (branch.worktreeStatus === "inaccessible") {
|
|
45087
45391
|
worktreeIcon = "x";
|
|
45088
45392
|
worktreeColor = "red";
|
|
45089
45393
|
}
|
|
45090
45394
|
const isRemoteBranch = branch.type === "remote";
|
|
45091
45395
|
const safetyLoading = props.cleanupUI?.safetyLoading === true;
|
|
45396
|
+
const safetyPendingBranches = props.cleanupUI?.safetyPendingBranches;
|
|
45397
|
+
const isSafetyPending = safetyPendingBranches ? safetyPendingBranches.has(branch.name) : safetyLoading;
|
|
45092
45398
|
const spinnerFrame = cleanupSpinnerFrame();
|
|
45093
45399
|
let safeIcon = " ";
|
|
45094
45400
|
let safeColor;
|
|
45095
45401
|
if (isRemoteBranch) {
|
|
45096
45402
|
safeIcon = " ";
|
|
45097
45403
|
safeColor = undefined;
|
|
45404
|
+
} else if (isSafetyPending) {
|
|
45405
|
+
safeIcon = spinnerFrame ?? "-";
|
|
45406
|
+
safeColor = undefined;
|
|
45098
45407
|
} else if (hasUncommitted) {
|
|
45099
45408
|
safeIcon = "!";
|
|
45100
45409
|
safeColor = "red";
|
|
@@ -45104,12 +45413,9 @@ function BranchListScreen(props) {
|
|
|
45104
45413
|
} else if (branch.isUnmerged) {
|
|
45105
45414
|
safeIcon = "*";
|
|
45106
45415
|
safeColor = "yellow";
|
|
45107
|
-
} else if (safetyLoading) {
|
|
45108
|
-
safeIcon = spinnerFrame ?? "-";
|
|
45109
|
-
safeColor = undefined;
|
|
45110
45416
|
} else if (branch.safeToCleanup === true) {
|
|
45111
|
-
safeIcon = "
|
|
45112
|
-
safeColor =
|
|
45417
|
+
safeIcon = "o";
|
|
45418
|
+
safeColor = "brightGreen";
|
|
45113
45419
|
} else {
|
|
45114
45420
|
safeIcon = "!";
|
|
45115
45421
|
safeColor = "red";
|
|
@@ -45316,6 +45622,63 @@ function BranchListScreen(props) {
|
|
|
45316
45622
|
}
|
|
45317
45623
|
return fitSegmentsToWidth(segments, layoutWidth());
|
|
45318
45624
|
});
|
|
45625
|
+
const statusLegendSegments = createMemo(() => {
|
|
45626
|
+
const segments = [];
|
|
45627
|
+
const separator = " ";
|
|
45628
|
+
appendSegment(segments, {
|
|
45629
|
+
text: "Legend: ",
|
|
45630
|
+
attributes: TextAttributes.DIM
|
|
45631
|
+
});
|
|
45632
|
+
appendSegment(segments, {
|
|
45633
|
+
text: "o",
|
|
45634
|
+
fg: "brightGreen",
|
|
45635
|
+
attributes: TextAttributes.BOLD
|
|
45636
|
+
});
|
|
45637
|
+
appendSegment(segments, {
|
|
45638
|
+
text: " Safe",
|
|
45639
|
+
fg: "brightGreen"
|
|
45640
|
+
});
|
|
45641
|
+
appendSegment(segments, {
|
|
45642
|
+
text: separator,
|
|
45643
|
+
attributes: TextAttributes.DIM
|
|
45644
|
+
});
|
|
45645
|
+
appendSegment(segments, {
|
|
45646
|
+
text: "!",
|
|
45647
|
+
fg: "red",
|
|
45648
|
+
attributes: TextAttributes.BOLD
|
|
45649
|
+
});
|
|
45650
|
+
appendSegment(segments, {
|
|
45651
|
+
text: " Uncommitted",
|
|
45652
|
+
fg: "red"
|
|
45653
|
+
});
|
|
45654
|
+
appendSegment(segments, {
|
|
45655
|
+
text: separator,
|
|
45656
|
+
attributes: TextAttributes.DIM
|
|
45657
|
+
});
|
|
45658
|
+
appendSegment(segments, {
|
|
45659
|
+
text: "!",
|
|
45660
|
+
fg: "yellow",
|
|
45661
|
+
attributes: TextAttributes.BOLD
|
|
45662
|
+
});
|
|
45663
|
+
appendSegment(segments, {
|
|
45664
|
+
text: " Unpushed",
|
|
45665
|
+
fg: "yellow"
|
|
45666
|
+
});
|
|
45667
|
+
appendSegment(segments, {
|
|
45668
|
+
text: separator,
|
|
45669
|
+
attributes: TextAttributes.DIM
|
|
45670
|
+
});
|
|
45671
|
+
appendSegment(segments, {
|
|
45672
|
+
text: "*",
|
|
45673
|
+
fg: "yellow",
|
|
45674
|
+
attributes: TextAttributes.BOLD
|
|
45675
|
+
});
|
|
45676
|
+
appendSegment(segments, {
|
|
45677
|
+
text: " Unmerged",
|
|
45678
|
+
fg: "yellow"
|
|
45679
|
+
});
|
|
45680
|
+
return fitSegmentsToWidth(segments, layoutWidth());
|
|
45681
|
+
});
|
|
45319
45682
|
const footerSegments = createMemo(() => {
|
|
45320
45683
|
const segments = [];
|
|
45321
45684
|
const separator = " ";
|
|
@@ -45411,50 +45774,46 @@ function BranchListScreen(props) {
|
|
|
45411
45774
|
}
|
|
45412
45775
|
}, () => props.loadingIndicatorDelay !== undefined ? {
|
|
45413
45776
|
delay: props.loadingIndicatorDelay
|
|
45414
|
-
} : {})) : (()
|
|
45415
|
-
var _el$7 = createElement("text");
|
|
45416
|
-
insert(_el$7, () => padLine("", layoutWidth()));
|
|
45417
|
-
return _el$7;
|
|
45418
|
-
})();
|
|
45777
|
+
} : {})) : renderSegmentLine(statusLegendSegments());
|
|
45419
45778
|
})(), null);
|
|
45420
45779
|
insert(_el$5, (() => {
|
|
45421
45780
|
var _c$2 = memo2(() => !!props.error);
|
|
45422
45781
|
return () => _c$2() && [(() => {
|
|
45782
|
+
var _el$7 = createElement("text");
|
|
45783
|
+
setProp(_el$7, "fg", "red");
|
|
45784
|
+
insert(_el$7, () => padLine(`Error: ${props.error.message}`, layoutWidth()));
|
|
45785
|
+
effect((_$p) => setProp(_el$7, "attributes", TextAttributes.BOLD, _$p));
|
|
45786
|
+
return _el$7;
|
|
45787
|
+
})(), memo2(() => memo2(() => !!(process.env.DEBUG && props.error.stack))() && [(() => {
|
|
45423
45788
|
var _el$8 = createElement("text");
|
|
45424
|
-
|
|
45425
|
-
|
|
45426
|
-
effect((_$p) => setProp(_el$8, "attributes", TextAttributes.BOLD, _$p));
|
|
45789
|
+
insert(_el$8, () => padLine("", layoutWidth()));
|
|
45790
|
+
effect((_$p) => setProp(_el$8, "attributes", TextAttributes.DIM, _$p));
|
|
45427
45791
|
return _el$8;
|
|
45428
|
-
})(), memo2(() =>
|
|
45792
|
+
})(), memo2(() => props.error.stack.split(`
|
|
45793
|
+
`).map((line) => (() => {
|
|
45429
45794
|
var _el$9 = createElement("text");
|
|
45430
|
-
|
|
45795
|
+
setProp(_el$9, "fg", "gray");
|
|
45796
|
+
insert(_el$9, () => padLine(line, layoutWidth()));
|
|
45431
45797
|
effect((_$p) => setProp(_el$9, "attributes", TextAttributes.DIM, _$p));
|
|
45432
45798
|
return _el$9;
|
|
45433
|
-
})(), memo2(() => props.error.stack.split(`
|
|
45434
|
-
`).map((line) => (() => {
|
|
45435
|
-
var _el$0 = createElement("text");
|
|
45436
|
-
setProp(_el$0, "fg", "gray");
|
|
45437
|
-
insert(_el$0, () => padLine(line, layoutWidth()));
|
|
45438
|
-
effect((_$p) => setProp(_el$0, "attributes", TextAttributes.DIM, _$p));
|
|
45439
|
-
return _el$0;
|
|
45440
45799
|
})()))])];
|
|
45441
45800
|
})(), null);
|
|
45442
45801
|
insert(_el$5, (() => {
|
|
45443
45802
|
var _c$3 = memo2(() => !!(!props.loading && !props.error && props.branches.length === 0));
|
|
45444
45803
|
return () => _c$3() && (() => {
|
|
45445
|
-
var _el$
|
|
45446
|
-
insert(_el$
|
|
45447
|
-
effect((_$p) => setProp(_el$
|
|
45448
|
-
return _el$
|
|
45804
|
+
var _el$0 = createElement("text");
|
|
45805
|
+
insert(_el$0, () => padLine("No branches found", layoutWidth()));
|
|
45806
|
+
effect((_$p) => setProp(_el$0, "attributes", TextAttributes.DIM, _$p));
|
|
45807
|
+
return _el$0;
|
|
45449
45808
|
})();
|
|
45450
45809
|
})(), null);
|
|
45451
45810
|
insert(_el$5, (() => {
|
|
45452
45811
|
var _c$4 = memo2(() => !!(!props.loading && !props.error && props.branches.length > 0 && filteredBranches().length === 0 && filterQuery()));
|
|
45453
45812
|
return () => _c$4() && (() => {
|
|
45454
|
-
var _el$
|
|
45455
|
-
insert(_el$
|
|
45456
|
-
effect((_$p) => setProp(_el$
|
|
45457
|
-
return _el$
|
|
45813
|
+
var _el$1 = createElement("text");
|
|
45814
|
+
insert(_el$1, () => padLine("No branches match your filter", layoutWidth()));
|
|
45815
|
+
effect((_$p) => setProp(_el$1, "attributes", TextAttributes.DIM, _$p));
|
|
45816
|
+
return _el$1;
|
|
45458
45817
|
})();
|
|
45459
45818
|
})(), null);
|
|
45460
45819
|
insert(_el$5, (() => {
|
|
@@ -45465,20 +45824,20 @@ function BranchListScreen(props) {
|
|
|
45465
45824
|
})), memo2(() => Array.from({
|
|
45466
45825
|
length: Math.max(0, contentHeight() - visibleBranches().length)
|
|
45467
45826
|
}).map(() => (() => {
|
|
45468
|
-
var _el$
|
|
45469
|
-
insert(_el$
|
|
45470
|
-
return _el$
|
|
45827
|
+
var _el$10 = createElement("text");
|
|
45828
|
+
insert(_el$10, () => padLine("", listWidth()));
|
|
45829
|
+
return _el$10;
|
|
45471
45830
|
})()))];
|
|
45472
45831
|
})(), null);
|
|
45473
45832
|
insert(_el$4, (() => {
|
|
45474
45833
|
var _c$6 = memo2(() => !!props.cleanupUI?.footerMessage);
|
|
45475
45834
|
return () => _c$6() && (() => {
|
|
45476
|
-
var _el$
|
|
45477
|
-
spread(_el$
|
|
45835
|
+
var _el$11 = createElement("text");
|
|
45836
|
+
spread(_el$11, mergeProps3(() => props.cleanupUI.footerMessage.color ? {
|
|
45478
45837
|
fg: props.cleanupUI.footerMessage.color
|
|
45479
45838
|
} : {}), true);
|
|
45480
|
-
insert(_el$
|
|
45481
|
-
return _el$
|
|
45839
|
+
insert(_el$11, () => padLine(props.cleanupUI.footerMessage.isSpinning && cleanupSpinnerFrame() ? `${cleanupSpinnerFrame()} ${props.cleanupUI.footerMessage.text}` : props.cleanupUI.footerMessage.text, layoutWidth()));
|
|
45840
|
+
return _el$11;
|
|
45482
45841
|
})();
|
|
45483
45842
|
})(), _el$6);
|
|
45484
45843
|
insert(_el$6, () => padLine(`Worktree: ${selectedWorktreeLabel()}`, layoutWidth()));
|
|
@@ -46009,6 +46368,15 @@ function SelectInput(props) {
|
|
|
46009
46368
|
},
|
|
46010
46369
|
get height() {
|
|
46011
46370
|
return computedHeight();
|
|
46371
|
+
},
|
|
46372
|
+
get selectedBackgroundColor() {
|
|
46373
|
+
return selectionStyle.bg;
|
|
46374
|
+
},
|
|
46375
|
+
get selectedTextColor() {
|
|
46376
|
+
return selectionStyle.fg;
|
|
46377
|
+
},
|
|
46378
|
+
get selectedDescriptionColor() {
|
|
46379
|
+
return selectionStyle.fg;
|
|
46012
46380
|
}
|
|
46013
46381
|
}, () => props.selectedIndex !== undefined && {
|
|
46014
46382
|
selectedIndex: props.selectedIndex
|
|
@@ -46040,30 +46408,46 @@ function QuickStartStep(props) {
|
|
|
46040
46408
|
props.onChooseDifferent();
|
|
46041
46409
|
}
|
|
46042
46410
|
});
|
|
46043
|
-
const
|
|
46411
|
+
const buildSettingsDescription = (entry) => {
|
|
46412
|
+
const parts = [];
|
|
46413
|
+
if (entry.toolLabel) {
|
|
46414
|
+
parts.push(entry.toolLabel);
|
|
46415
|
+
} else if (entry.toolId) {
|
|
46416
|
+
parts.push(entry.toolId);
|
|
46417
|
+
}
|
|
46418
|
+
if (entry.model) {
|
|
46419
|
+
parts.push(entry.model);
|
|
46420
|
+
}
|
|
46421
|
+
if (entry.toolId === "codex-cli" && entry.reasoningLevel) {
|
|
46422
|
+
parts.push(entry.reasoningLevel);
|
|
46423
|
+
}
|
|
46424
|
+
return parts.join(", ");
|
|
46425
|
+
};
|
|
46044
46426
|
const items = createMemo(() => {
|
|
46045
46427
|
const result = [];
|
|
46046
|
-
|
|
46047
|
-
|
|
46048
|
-
|
|
46049
|
-
const
|
|
46050
|
-
const
|
|
46051
|
-
const
|
|
46052
|
-
|
|
46053
|
-
|
|
46054
|
-
|
|
46055
|
-
|
|
46056
|
-
|
|
46057
|
-
|
|
46058
|
-
|
|
46428
|
+
props.history.forEach((entry, index) => {
|
|
46429
|
+
if (!entry)
|
|
46430
|
+
return;
|
|
46431
|
+
const settingsDesc = buildSettingsDescription(entry);
|
|
46432
|
+
const sessionId = entry.sessionId && entry.sessionId.trim().length > 0 ? entry.sessionId.trim() : null;
|
|
46433
|
+
const suffix = `${entry.toolId ?? "tool"}-${index}`;
|
|
46434
|
+
if (sessionId) {
|
|
46435
|
+
result.push({
|
|
46436
|
+
label: "Resume session (previous settings)",
|
|
46437
|
+
value: `resume-${suffix}`,
|
|
46438
|
+
description: `${settingsDesc} | Session: ${sessionId}`,
|
|
46439
|
+
action: "resume",
|
|
46440
|
+
entry
|
|
46441
|
+
});
|
|
46442
|
+
}
|
|
46059
46443
|
result.push({
|
|
46060
46444
|
label: "Start new (previous settings)",
|
|
46061
|
-
value: `start-new-${
|
|
46445
|
+
value: `start-new-${suffix}`,
|
|
46062
46446
|
description: settingsDesc,
|
|
46063
46447
|
action: "start-new",
|
|
46064
46448
|
entry
|
|
46065
46449
|
});
|
|
46066
|
-
}
|
|
46450
|
+
});
|
|
46067
46451
|
result.push({
|
|
46068
46452
|
label: "Choose different settings...",
|
|
46069
46453
|
value: "choose-different",
|
|
@@ -46327,6 +46711,19 @@ var MODEL_OPTIONS = {
|
|
|
46327
46711
|
label: "Flash-Lite (gemini-2.5-flash-lite)",
|
|
46328
46712
|
description: "Fastest for simple tasks"
|
|
46329
46713
|
}
|
|
46714
|
+
],
|
|
46715
|
+
opencode: [
|
|
46716
|
+
{
|
|
46717
|
+
id: "",
|
|
46718
|
+
label: "Default (Auto)",
|
|
46719
|
+
description: "Use OpenCode default model",
|
|
46720
|
+
isDefault: true
|
|
46721
|
+
},
|
|
46722
|
+
{
|
|
46723
|
+
id: "__custom__",
|
|
46724
|
+
label: "Custom (provider/model)",
|
|
46725
|
+
description: "Enter a provider/model identifier"
|
|
46726
|
+
}
|
|
46330
46727
|
]
|
|
46331
46728
|
};
|
|
46332
46729
|
function getModelOptions(tool) {
|
|
@@ -46356,6 +46753,9 @@ function normalizeModelId(tool, model) {
|
|
|
46356
46753
|
const trimmed = model.trim();
|
|
46357
46754
|
if (!trimmed)
|
|
46358
46755
|
return null;
|
|
46756
|
+
if (tool === "opencode" && trimmed === "__custom__") {
|
|
46757
|
+
return null;
|
|
46758
|
+
}
|
|
46359
46759
|
if (tool === "claude-code") {
|
|
46360
46760
|
const lower = trimmed.toLowerCase();
|
|
46361
46761
|
if (lower === "opuss")
|
|
@@ -46366,257 +46766,55 @@ function normalizeModelId(tool, model) {
|
|
|
46366
46766
|
return trimmed;
|
|
46367
46767
|
}
|
|
46368
46768
|
|
|
46369
|
-
// src/utils/
|
|
46370
|
-
var
|
|
46371
|
-
|
|
46372
|
-
|
|
46373
|
-
return
|
|
46374
|
-
}
|
|
46375
|
-
async function fetchPackageVersions(packageName, limit = DEFAULT_LIMIT, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
46376
|
-
try {
|
|
46377
|
-
const controller = new AbortController;
|
|
46378
|
-
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
46379
|
-
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`, {
|
|
46380
|
-
signal: controller.signal,
|
|
46381
|
-
headers: {
|
|
46382
|
-
Accept: "application/json"
|
|
46383
|
-
}
|
|
46384
|
-
});
|
|
46385
|
-
clearTimeout(timeoutId);
|
|
46386
|
-
if (!response.ok) {
|
|
46387
|
-
return [];
|
|
46388
|
-
}
|
|
46389
|
-
const data = await response.json();
|
|
46390
|
-
if (!data.versions || !data.time) {
|
|
46391
|
-
return [];
|
|
46392
|
-
}
|
|
46393
|
-
const versionsWithTime = [];
|
|
46394
|
-
for (const version of Object.keys(data.versions)) {
|
|
46395
|
-
const publishedAt = data.time[version];
|
|
46396
|
-
if (publishedAt) {
|
|
46397
|
-
versionsWithTime.push({ version, publishedAt });
|
|
46398
|
-
}
|
|
46399
|
-
}
|
|
46400
|
-
versionsWithTime.sort((a, b) => {
|
|
46401
|
-
const dateA = new Date(a.publishedAt).getTime();
|
|
46402
|
-
const dateB = new Date(b.publishedAt).getTime();
|
|
46403
|
-
return dateB - dateA;
|
|
46404
|
-
});
|
|
46405
|
-
const topVersions = versionsWithTime.slice(0, limit);
|
|
46406
|
-
return topVersions.map((v) => ({
|
|
46407
|
-
version: v.version,
|
|
46408
|
-
isPrerelease: isPrerelease(v.version),
|
|
46409
|
-
publishedAt: v.publishedAt
|
|
46410
|
-
}));
|
|
46411
|
-
} catch {
|
|
46412
|
-
return [];
|
|
46413
|
-
}
|
|
46769
|
+
// src/cli/ui/utils/versionCache.ts
|
|
46770
|
+
var versionCache = new Map;
|
|
46771
|
+
function getVersionCache(agentId) {
|
|
46772
|
+
const cached = versionCache.get(agentId);
|
|
46773
|
+
return cached !== undefined ? cached : null;
|
|
46414
46774
|
}
|
|
46415
|
-
function
|
|
46416
|
-
|
|
46417
|
-
const
|
|
46418
|
-
|
|
46419
|
-
|
|
46420
|
-
|
|
46421
|
-
|
|
46422
|
-
|
|
46423
|
-
|
|
46424
|
-
|
|
46425
|
-
|
|
46426
|
-
|
|
46427
|
-
const
|
|
46428
|
-
|
|
46429
|
-
}
|
|
46430
|
-
const atIndex = command.indexOf("@");
|
|
46431
|
-
if (atIndex === -1) {
|
|
46432
|
-
return { packageName: command, version: null };
|
|
46775
|
+
async function prefetchAgentVersions(agentIds, fetchFn) {
|
|
46776
|
+
const fetcher = fetchFn ?? (async (agentId) => {
|
|
46777
|
+
const { fetchVersionOptionsForAgent: fetchVersionOptionsForAgent2 } = await Promise.resolve().then(() => (init_versionFetcher(), exports_versionFetcher));
|
|
46778
|
+
return fetchVersionOptionsForAgent2(agentId);
|
|
46779
|
+
});
|
|
46780
|
+
const results = await Promise.allSettled(agentIds.map(async (agentId) => {
|
|
46781
|
+
try {
|
|
46782
|
+
const versions = await fetcher(agentId);
|
|
46783
|
+
versionCache.set(agentId, versions);
|
|
46784
|
+
} catch {}
|
|
46785
|
+
}));
|
|
46786
|
+
for (let i2 = 0;i2 < results.length; i2++) {
|
|
46787
|
+
const result = results[i2];
|
|
46788
|
+
if (result && result.status === "rejected") {}
|
|
46433
46789
|
}
|
|
46434
|
-
const packageName = command.substring(0, atIndex);
|
|
46435
|
-
const version = command.substring(atIndex + 1);
|
|
46436
|
-
return { packageName, version };
|
|
46437
46790
|
}
|
|
46438
46791
|
|
|
46439
|
-
// src/
|
|
46440
|
-
|
|
46441
|
-
"--dangerously-skip-permissions"
|
|
46442
|
-
];
|
|
46443
|
-
var CODEX_DEFAULT_ARGS = [
|
|
46444
|
-
"--enable",
|
|
46445
|
-
"web_search_request",
|
|
46446
|
-
"--model=gpt-5.2-codex",
|
|
46447
|
-
"--sandbox",
|
|
46448
|
-
"workspace-write",
|
|
46449
|
-
"-c",
|
|
46450
|
-
"model_reasoning_effort=high",
|
|
46451
|
-
"-c",
|
|
46452
|
-
"model_reasoning_summaries=detailed",
|
|
46453
|
-
"-c",
|
|
46454
|
-
"sandbox_workspace_write.network_access=true",
|
|
46455
|
-
"-c",
|
|
46456
|
-
"shell_environment_policy.inherit=all",
|
|
46457
|
-
"-c",
|
|
46458
|
-
"shell_environment_policy.ignore_default_excludes=true",
|
|
46459
|
-
"-c",
|
|
46460
|
-
"shell_environment_policy.experimental_use_profile=true"
|
|
46461
|
-
];
|
|
46462
|
-
|
|
46463
|
-
// src/config/builtin-coding-agents.ts
|
|
46464
|
-
var CLAUDE_CODE_TOOL = {
|
|
46465
|
-
id: "claude-code",
|
|
46466
|
-
displayName: "Claude Code",
|
|
46467
|
-
type: "bunx",
|
|
46468
|
-
command: "@anthropic-ai/claude-code",
|
|
46469
|
-
modeArgs: {
|
|
46470
|
-
normal: [],
|
|
46471
|
-
continue: ["-c"],
|
|
46472
|
-
resume: ["-r"]
|
|
46473
|
-
},
|
|
46474
|
-
permissionSkipArgs: Array.from(CLAUDE_PERMISSION_SKIP_ARGS),
|
|
46475
|
-
env: {
|
|
46476
|
-
ENABLE_LSP_TOOL: "true"
|
|
46477
|
-
}
|
|
46478
|
-
};
|
|
46479
|
-
var CODEX_CLI_TOOL = {
|
|
46480
|
-
id: "codex-cli",
|
|
46481
|
-
displayName: "Codex",
|
|
46482
|
-
type: "bunx",
|
|
46483
|
-
command: "@openai/codex",
|
|
46484
|
-
defaultArgs: Array.from(CODEX_DEFAULT_ARGS),
|
|
46485
|
-
modeArgs: {
|
|
46486
|
-
normal: [],
|
|
46487
|
-
continue: ["resume", "--last"],
|
|
46488
|
-
resume: ["resume"]
|
|
46489
|
-
}
|
|
46490
|
-
};
|
|
46491
|
-
var GEMINI_CLI_TOOL = {
|
|
46492
|
-
id: "gemini-cli",
|
|
46493
|
-
displayName: "Gemini",
|
|
46494
|
-
type: "bunx",
|
|
46495
|
-
command: "@google/gemini-cli",
|
|
46496
|
-
modeArgs: {
|
|
46497
|
-
normal: [],
|
|
46498
|
-
continue: ["-r", "latest"],
|
|
46499
|
-
resume: ["-r", "latest"]
|
|
46500
|
-
},
|
|
46501
|
-
permissionSkipArgs: ["-y"]
|
|
46502
|
-
};
|
|
46503
|
-
var OPENCODE_TOOL = {
|
|
46504
|
-
id: "opencode",
|
|
46505
|
-
displayName: "OpenCode",
|
|
46506
|
-
type: "bunx",
|
|
46507
|
-
command: "opencode-ai",
|
|
46508
|
-
modeArgs: {
|
|
46509
|
-
normal: [],
|
|
46510
|
-
continue: ["-c"],
|
|
46511
|
-
resume: ["-s"]
|
|
46512
|
-
}
|
|
46513
|
-
};
|
|
46514
|
-
var BUILTIN_CODING_AGENTS = [
|
|
46515
|
-
CLAUDE_CODE_TOOL,
|
|
46516
|
-
CODEX_CLI_TOOL,
|
|
46517
|
-
GEMINI_CLI_TOOL,
|
|
46518
|
-
OPENCODE_TOOL
|
|
46519
|
-
];
|
|
46792
|
+
// src/cli/ui/components/solid/WizardSteps.tsx
|
|
46793
|
+
init_versionFetcher();
|
|
46520
46794
|
|
|
46521
|
-
// src/utils/
|
|
46522
|
-
|
|
46523
|
-
|
|
46524
|
-
|
|
46525
|
-
|
|
46526
|
-
|
|
46527
|
-
claude: {
|
|
46528
|
-
unix: [
|
|
46529
|
-
join2(homedir(), ".bun", "bin", "claude"),
|
|
46530
|
-
join2(homedir(), ".local", "bin", "claude"),
|
|
46531
|
-
"/usr/local/bin/claude"
|
|
46532
|
-
],
|
|
46533
|
-
win32: [
|
|
46534
|
-
join2(process.env.LOCALAPPDATA ?? "", "Programs", "claude", "claude.exe"),
|
|
46535
|
-
join2(homedir(), ".bun", "bin", "claude.exe")
|
|
46536
|
-
]
|
|
46537
|
-
},
|
|
46538
|
-
codex: {
|
|
46539
|
-
unix: [
|
|
46540
|
-
join2(homedir(), ".bun", "bin", "codex"),
|
|
46541
|
-
join2(homedir(), ".local", "bin", "codex"),
|
|
46542
|
-
"/usr/local/bin/codex"
|
|
46543
|
-
],
|
|
46544
|
-
win32: [join2(homedir(), ".bun", "bin", "codex.exe")]
|
|
46545
|
-
},
|
|
46546
|
-
gemini: {
|
|
46547
|
-
unix: [
|
|
46548
|
-
join2(homedir(), ".bun", "bin", "gemini"),
|
|
46549
|
-
join2(homedir(), ".local", "bin", "gemini"),
|
|
46550
|
-
"/usr/local/bin/gemini"
|
|
46551
|
-
],
|
|
46552
|
-
win32: [join2(homedir(), ".bun", "bin", "gemini.exe")]
|
|
46553
|
-
},
|
|
46554
|
-
opencode: {
|
|
46555
|
-
unix: [
|
|
46556
|
-
join2(homedir(), ".bun", "bin", "opencode"),
|
|
46557
|
-
join2(homedir(), ".local", "bin", "opencode"),
|
|
46558
|
-
"/usr/local/bin/opencode"
|
|
46559
|
-
],
|
|
46560
|
-
win32: [join2(homedir(), ".bun", "bin", "opencode.exe")]
|
|
46561
|
-
}
|
|
46562
|
-
};
|
|
46563
|
-
var commandLookupCache = new Map;
|
|
46564
|
-
async function getCommandVersion(commandPath) {
|
|
46565
|
-
try {
|
|
46566
|
-
const result = await execa(commandPath, ["--version"], {
|
|
46567
|
-
timeout: 3000,
|
|
46568
|
-
stdin: "ignore",
|
|
46569
|
-
stdout: "pipe",
|
|
46570
|
-
stderr: "ignore"
|
|
46571
|
-
});
|
|
46572
|
-
const match = result.stdout.match(/(\d+\.\d+(?:\.\d+)?(?:-[\w.]+)?)/);
|
|
46573
|
-
return match ? `v${match[1]}` : null;
|
|
46574
|
-
} catch {
|
|
46575
|
-
return null;
|
|
46576
|
-
}
|
|
46795
|
+
// src/cli/ui/utils/installedVersionCache.ts
|
|
46796
|
+
init_versionFetcher();
|
|
46797
|
+
var installedVersionCache = new Map;
|
|
46798
|
+
function getInstalledVersionCache(agentId) {
|
|
46799
|
+
const cached = installedVersionCache.get(agentId);
|
|
46800
|
+
return cached ?? null;
|
|
46577
46801
|
}
|
|
46578
|
-
|
|
46579
|
-
|
|
46580
|
-
|
|
46581
|
-
|
|
46582
|
-
|
|
46583
|
-
|
|
46584
|
-
|
|
46585
|
-
|
|
46586
|
-
|
|
46587
|
-
|
|
46588
|
-
|
|
46589
|
-
stdout: "pipe",
|
|
46590
|
-
stderr: "ignore"
|
|
46591
|
-
});
|
|
46592
|
-
const foundPath = execResult.stdout.trim().split(`
|
|
46593
|
-
`)[0];
|
|
46594
|
-
if (foundPath) {
|
|
46595
|
-
lookupResult = { available: true, path: foundPath, source: "installed" };
|
|
46596
|
-
}
|
|
46597
|
-
} catch {}
|
|
46598
|
-
if (!lookupResult) {
|
|
46599
|
-
const knownPaths = KNOWN_INSTALL_PATHS[commandName];
|
|
46600
|
-
if (knownPaths) {
|
|
46601
|
-
const pathsToCheck = process.platform === "win32" ? knownPaths.win32 : knownPaths.unix;
|
|
46602
|
-
for (const p of pathsToCheck) {
|
|
46603
|
-
if (p && existsSync3(p)) {
|
|
46604
|
-
lookupResult = { available: true, path: p, source: "installed" };
|
|
46605
|
-
break;
|
|
46606
|
-
}
|
|
46607
|
-
}
|
|
46802
|
+
function setInstalledVersionCache(agentId, installed) {
|
|
46803
|
+
installedVersionCache.set(agentId, installed);
|
|
46804
|
+
}
|
|
46805
|
+
async function prefetchInstalledVersions(agentIds, fetchFn) {
|
|
46806
|
+
const fetcher = fetchFn ?? (async (agentId) => fetchInstalledVersionForAgent(agentId));
|
|
46807
|
+
const results = await Promise.allSettled(agentIds.map(async (agentId) => {
|
|
46808
|
+
try {
|
|
46809
|
+
const installed = await fetcher(agentId);
|
|
46810
|
+
setInstalledVersionCache(agentId, installed);
|
|
46811
|
+
} catch {
|
|
46812
|
+
setInstalledVersionCache(agentId, null);
|
|
46608
46813
|
}
|
|
46814
|
+
}));
|
|
46815
|
+
for (const result of results) {
|
|
46816
|
+
if (result.status === "rejected") {}
|
|
46609
46817
|
}
|
|
46610
|
-
if (!lookupResult) {
|
|
46611
|
-
lookupResult = { available: true, path: null, source: "bunx" };
|
|
46612
|
-
}
|
|
46613
|
-
if (lookupResult.source === "installed" && lookupResult.path) {
|
|
46614
|
-
lookupResult.version = await getCommandVersion(lookupResult.path);
|
|
46615
|
-
} else {
|
|
46616
|
-
lookupResult.version = null;
|
|
46617
|
-
}
|
|
46618
|
-
commandLookupCache.set(commandName, lookupResult);
|
|
46619
|
-
return lookupResult;
|
|
46620
46818
|
}
|
|
46621
46819
|
|
|
46622
46820
|
// src/cli/ui/components/solid/WizardSteps.tsx
|
|
@@ -46929,9 +47127,16 @@ function AgentSelectStep(props) {
|
|
|
46929
47127
|
return isSelected() ? (() => {
|
|
46930
47128
|
var _el$39 = createElement("text"), _el$40 = createTextNode(`> `);
|
|
46931
47129
|
insertNode(_el$39, _el$40);
|
|
46932
|
-
setProp(_el$39, "bg", "cyan");
|
|
46933
|
-
setProp(_el$39, "fg", "black");
|
|
46934
47130
|
insert(_el$39, () => agent.label, null);
|
|
47131
|
+
effect((_p$) => {
|
|
47132
|
+
var _v$9 = selectionStyle.bg, _v$0 = selectionStyle.fg;
|
|
47133
|
+
_v$9 !== _p$.e && (_p$.e = setProp(_el$39, "bg", _v$9, _p$.e));
|
|
47134
|
+
_v$0 !== _p$.t && (_p$.t = setProp(_el$39, "fg", _v$0, _p$.t));
|
|
47135
|
+
return _p$;
|
|
47136
|
+
}, {
|
|
47137
|
+
e: undefined,
|
|
47138
|
+
t: undefined
|
|
47139
|
+
});
|
|
46935
47140
|
return _el$39;
|
|
46936
47141
|
})() : (() => {
|
|
46937
47142
|
var _el$41 = createElement("text"), _el$42 = createTextNode(` `);
|
|
@@ -47023,9 +47228,9 @@ function ModelSelectStep(props) {
|
|
|
47023
47228
|
insertNode(_el$48, createTextNode(` `));
|
|
47024
47229
|
insertNode(_el$50, createTextNode(`[Enter] Select [Esc] Back`));
|
|
47025
47230
|
effect((_p$) => {
|
|
47026
|
-
var _v$
|
|
47027
|
-
_v$
|
|
47028
|
-
_v$
|
|
47231
|
+
var _v$1 = TextAttributes.BOLD, _v$10 = TextAttributes.DIM;
|
|
47232
|
+
_v$1 !== _p$.e && (_p$.e = setProp(_el$44, "attributes", _v$1, _p$.e));
|
|
47233
|
+
_v$10 !== _p$.t && (_p$.t = setProp(_el$50, "attributes", _v$10, _p$.t));
|
|
47029
47234
|
return _p$;
|
|
47030
47235
|
}, {
|
|
47031
47236
|
e: undefined,
|
|
@@ -47034,6 +47239,61 @@ function ModelSelectStep(props) {
|
|
|
47034
47239
|
return _el$43;
|
|
47035
47240
|
})();
|
|
47036
47241
|
}
|
|
47242
|
+
function ModelInputStep(props) {
|
|
47243
|
+
const [value, setValue] = createSignal("");
|
|
47244
|
+
const scroll = useWizardScroll();
|
|
47245
|
+
const placeholder = props.agentId === "opencode" ? "provider/model" : "model";
|
|
47246
|
+
createEffect(() => {
|
|
47247
|
+
if (props.focused === false) {
|
|
47248
|
+
return;
|
|
47249
|
+
}
|
|
47250
|
+
if (!scroll) {
|
|
47251
|
+
return;
|
|
47252
|
+
}
|
|
47253
|
+
scroll.ensureLineVisible(2);
|
|
47254
|
+
});
|
|
47255
|
+
const handleSubmit = (next) => {
|
|
47256
|
+
const trimmed = next.trim();
|
|
47257
|
+
if (!trimmed) {
|
|
47258
|
+
return;
|
|
47259
|
+
}
|
|
47260
|
+
props.onSubmit(trimmed);
|
|
47261
|
+
};
|
|
47262
|
+
return (() => {
|
|
47263
|
+
var _el$52 = createElement("box"), _el$53 = createElement("text"), _el$55 = createElement("text"), _el$57 = createElement("text"), _el$59 = createElement("text");
|
|
47264
|
+
insertNode(_el$52, _el$53);
|
|
47265
|
+
insertNode(_el$52, _el$55);
|
|
47266
|
+
insertNode(_el$52, _el$57);
|
|
47267
|
+
insertNode(_el$52, _el$59);
|
|
47268
|
+
setProp(_el$52, "flexDirection", "column");
|
|
47269
|
+
insertNode(_el$53, createTextNode(`Enter custom model:`));
|
|
47270
|
+
setProp(_el$53, "fg", "cyan");
|
|
47271
|
+
insertNode(_el$55, createTextNode(` `));
|
|
47272
|
+
insert(_el$52, createComponent2(TextInput, {
|
|
47273
|
+
get value() {
|
|
47274
|
+
return value();
|
|
47275
|
+
},
|
|
47276
|
+
onChange: setValue,
|
|
47277
|
+
onSubmit: handleSubmit,
|
|
47278
|
+
placeholder,
|
|
47279
|
+
get focused() {
|
|
47280
|
+
return props.focused ?? true;
|
|
47281
|
+
}
|
|
47282
|
+
}), _el$57);
|
|
47283
|
+
insertNode(_el$57, createTextNode(` `));
|
|
47284
|
+
insertNode(_el$59, createTextNode(`[Enter] Submit [Esc] Back`));
|
|
47285
|
+
effect((_p$) => {
|
|
47286
|
+
var _v$11 = TextAttributes.BOLD, _v$12 = TextAttributes.DIM;
|
|
47287
|
+
_v$11 !== _p$.e && (_p$.e = setProp(_el$53, "attributes", _v$11, _p$.e));
|
|
47288
|
+
_v$12 !== _p$.t && (_p$.t = setProp(_el$59, "attributes", _v$12, _p$.t));
|
|
47289
|
+
return _p$;
|
|
47290
|
+
}, {
|
|
47291
|
+
e: undefined,
|
|
47292
|
+
t: undefined
|
|
47293
|
+
});
|
|
47294
|
+
return _el$52;
|
|
47295
|
+
})();
|
|
47296
|
+
}
|
|
47037
47297
|
var REASONING_LEVELS = [{
|
|
47038
47298
|
label: "low",
|
|
47039
47299
|
value: "low",
|
|
@@ -47071,16 +47331,16 @@ function ReasoningLevelStep(props) {
|
|
|
47071
47331
|
}
|
|
47072
47332
|
};
|
|
47073
47333
|
return (() => {
|
|
47074
|
-
var _el$
|
|
47075
|
-
insertNode(_el$
|
|
47076
|
-
insertNode(_el$
|
|
47077
|
-
insertNode(_el$
|
|
47078
|
-
insertNode(_el$
|
|
47079
|
-
setProp(_el$
|
|
47080
|
-
insertNode(_el$
|
|
47081
|
-
setProp(_el$
|
|
47082
|
-
insertNode(_el$
|
|
47083
|
-
insert(_el$
|
|
47334
|
+
var _el$61 = createElement("box"), _el$62 = createElement("text"), _el$64 = createElement("text"), _el$66 = createElement("text"), _el$68 = createElement("text");
|
|
47335
|
+
insertNode(_el$61, _el$62);
|
|
47336
|
+
insertNode(_el$61, _el$64);
|
|
47337
|
+
insertNode(_el$61, _el$66);
|
|
47338
|
+
insertNode(_el$61, _el$68);
|
|
47339
|
+
setProp(_el$61, "flexDirection", "column");
|
|
47340
|
+
insertNode(_el$62, createTextNode(`Select reasoning level:`));
|
|
47341
|
+
setProp(_el$62, "fg", "cyan");
|
|
47342
|
+
insertNode(_el$64, createTextNode(` `));
|
|
47343
|
+
insert(_el$61, createComponent2(SelectInput, {
|
|
47084
47344
|
items: REASONING_LEVELS,
|
|
47085
47345
|
onSelect: (item) => props.onSelect(item.value),
|
|
47086
47346
|
onChange: handleChange,
|
|
@@ -47088,19 +47348,19 @@ function ReasoningLevelStep(props) {
|
|
|
47088
47348
|
return props.focused ?? true;
|
|
47089
47349
|
},
|
|
47090
47350
|
selectRef: setSelectRef
|
|
47091
|
-
}), _el$
|
|
47092
|
-
insertNode(_el$
|
|
47093
|
-
insertNode(_el$
|
|
47351
|
+
}), _el$66);
|
|
47352
|
+
insertNode(_el$66, createTextNode(` `));
|
|
47353
|
+
insertNode(_el$68, createTextNode(`[Enter] Select [Esc] Back`));
|
|
47094
47354
|
effect((_p$) => {
|
|
47095
|
-
var _v$
|
|
47096
|
-
_v$
|
|
47097
|
-
_v$
|
|
47355
|
+
var _v$13 = TextAttributes.BOLD, _v$14 = TextAttributes.DIM;
|
|
47356
|
+
_v$13 !== _p$.e && (_p$.e = setProp(_el$62, "attributes", _v$13, _p$.e));
|
|
47357
|
+
_v$14 !== _p$.t && (_p$.t = setProp(_el$68, "attributes", _v$14, _p$.t));
|
|
47098
47358
|
return _p$;
|
|
47099
47359
|
}, {
|
|
47100
47360
|
e: undefined,
|
|
47101
47361
|
t: undefined
|
|
47102
47362
|
});
|
|
47103
|
-
return _el$
|
|
47363
|
+
return _el$61;
|
|
47104
47364
|
})();
|
|
47105
47365
|
}
|
|
47106
47366
|
var EXECUTION_MODES = [{
|
|
@@ -47136,16 +47396,16 @@ function ExecutionModeStep(props) {
|
|
|
47136
47396
|
}
|
|
47137
47397
|
};
|
|
47138
47398
|
return (() => {
|
|
47139
|
-
var _el$
|
|
47140
|
-
insertNode(_el$
|
|
47141
|
-
insertNode(_el$
|
|
47142
|
-
insertNode(_el$
|
|
47143
|
-
insertNode(_el$
|
|
47144
|
-
setProp(_el$
|
|
47145
|
-
insertNode(_el$
|
|
47146
|
-
setProp(_el$
|
|
47147
|
-
insertNode(_el$
|
|
47148
|
-
insert(_el$
|
|
47399
|
+
var _el$70 = createElement("box"), _el$71 = createElement("text"), _el$73 = createElement("text"), _el$75 = createElement("text"), _el$77 = createElement("text");
|
|
47400
|
+
insertNode(_el$70, _el$71);
|
|
47401
|
+
insertNode(_el$70, _el$73);
|
|
47402
|
+
insertNode(_el$70, _el$75);
|
|
47403
|
+
insertNode(_el$70, _el$77);
|
|
47404
|
+
setProp(_el$70, "flexDirection", "column");
|
|
47405
|
+
insertNode(_el$71, createTextNode(`Select execution mode:`));
|
|
47406
|
+
setProp(_el$71, "fg", "cyan");
|
|
47407
|
+
insertNode(_el$73, createTextNode(` `));
|
|
47408
|
+
insert(_el$70, createComponent2(SelectInput, {
|
|
47149
47409
|
items: EXECUTION_MODES,
|
|
47150
47410
|
onSelect: (item) => props.onSelect(item.value),
|
|
47151
47411
|
onChange: handleChange,
|
|
@@ -47153,19 +47413,19 @@ function ExecutionModeStep(props) {
|
|
|
47153
47413
|
return props.focused ?? true;
|
|
47154
47414
|
},
|
|
47155
47415
|
selectRef: setSelectRef
|
|
47156
|
-
}), _el$
|
|
47157
|
-
insertNode(_el$
|
|
47158
|
-
insertNode(_el$
|
|
47416
|
+
}), _el$75);
|
|
47417
|
+
insertNode(_el$75, createTextNode(` `));
|
|
47418
|
+
insertNode(_el$77, createTextNode(`[Enter] Select [Esc] Back`));
|
|
47159
47419
|
effect((_p$) => {
|
|
47160
|
-
var _v$
|
|
47161
|
-
_v$
|
|
47162
|
-
_v$
|
|
47420
|
+
var _v$15 = TextAttributes.BOLD, _v$16 = TextAttributes.DIM;
|
|
47421
|
+
_v$15 !== _p$.e && (_p$.e = setProp(_el$71, "attributes", _v$15, _p$.e));
|
|
47422
|
+
_v$16 !== _p$.t && (_p$.t = setProp(_el$77, "attributes", _v$16, _p$.t));
|
|
47163
47423
|
return _p$;
|
|
47164
47424
|
}, {
|
|
47165
47425
|
e: undefined,
|
|
47166
47426
|
t: undefined
|
|
47167
47427
|
});
|
|
47168
|
-
return _el$
|
|
47428
|
+
return _el$70;
|
|
47169
47429
|
})();
|
|
47170
47430
|
}
|
|
47171
47431
|
var SKIP_OPTIONS = [{
|
|
@@ -47197,16 +47457,16 @@ function SkipPermissionsStep(props) {
|
|
|
47197
47457
|
}
|
|
47198
47458
|
};
|
|
47199
47459
|
return (() => {
|
|
47200
|
-
var _el$
|
|
47201
|
-
insertNode(_el$
|
|
47202
|
-
insertNode(_el$
|
|
47203
|
-
insertNode(_el$
|
|
47204
|
-
insertNode(_el$
|
|
47205
|
-
setProp(_el$
|
|
47206
|
-
insertNode(_el$
|
|
47207
|
-
setProp(_el$
|
|
47208
|
-
insertNode(_el$
|
|
47209
|
-
insert(_el$
|
|
47460
|
+
var _el$79 = createElement("box"), _el$80 = createElement("text"), _el$82 = createElement("text"), _el$84 = createElement("text"), _el$86 = createElement("text");
|
|
47461
|
+
insertNode(_el$79, _el$80);
|
|
47462
|
+
insertNode(_el$79, _el$82);
|
|
47463
|
+
insertNode(_el$79, _el$84);
|
|
47464
|
+
insertNode(_el$79, _el$86);
|
|
47465
|
+
setProp(_el$79, "flexDirection", "column");
|
|
47466
|
+
insertNode(_el$80, createTextNode(`Skip permission prompts?`));
|
|
47467
|
+
setProp(_el$80, "fg", "cyan");
|
|
47468
|
+
insertNode(_el$82, createTextNode(` `));
|
|
47469
|
+
insert(_el$79, createComponent2(SelectInput, {
|
|
47210
47470
|
items: SKIP_OPTIONS,
|
|
47211
47471
|
onSelect: (item) => props.onSelect(item.value === "true"),
|
|
47212
47472
|
onChange: handleChange,
|
|
@@ -47214,19 +47474,19 @@ function SkipPermissionsStep(props) {
|
|
|
47214
47474
|
return props.focused ?? true;
|
|
47215
47475
|
},
|
|
47216
47476
|
selectRef: setSelectRef
|
|
47217
|
-
}), _el$
|
|
47218
|
-
insertNode(_el$
|
|
47219
|
-
insertNode(_el$
|
|
47477
|
+
}), _el$84);
|
|
47478
|
+
insertNode(_el$84, createTextNode(` `));
|
|
47479
|
+
insertNode(_el$86, createTextNode(`[Enter] Select [Esc] Back`));
|
|
47220
47480
|
effect((_p$) => {
|
|
47221
|
-
var _v$
|
|
47222
|
-
_v$
|
|
47223
|
-
_v$
|
|
47481
|
+
var _v$17 = TextAttributes.BOLD, _v$18 = TextAttributes.DIM;
|
|
47482
|
+
_v$17 !== _p$.e && (_p$.e = setProp(_el$80, "attributes", _v$17, _p$.e));
|
|
47483
|
+
_v$18 !== _p$.t && (_p$.t = setProp(_el$86, "attributes", _v$18, _p$.t));
|
|
47224
47484
|
return _p$;
|
|
47225
47485
|
}, {
|
|
47226
47486
|
e: undefined,
|
|
47227
47487
|
t: undefined
|
|
47228
47488
|
});
|
|
47229
|
-
return _el$
|
|
47489
|
+
return _el$79;
|
|
47230
47490
|
})();
|
|
47231
47491
|
}
|
|
47232
47492
|
var LATEST_OPTION = {
|
|
@@ -47234,60 +47494,20 @@ var LATEST_OPTION = {
|
|
|
47234
47494
|
value: "latest",
|
|
47235
47495
|
description: "Always fetch latest version"
|
|
47236
47496
|
};
|
|
47237
|
-
function getPackageNameForAgent(agentId) {
|
|
47238
|
-
const agent = BUILTIN_CODING_AGENTS.find((a2) => a2.id === agentId);
|
|
47239
|
-
if (!agent || agent.type !== "bunx") {
|
|
47240
|
-
return null;
|
|
47241
|
-
}
|
|
47242
|
-
const {
|
|
47243
|
-
packageName
|
|
47244
|
-
} = parsePackageCommand(agent.command);
|
|
47245
|
-
return packageName;
|
|
47246
|
-
}
|
|
47247
|
-
async function fetchVersionOptions(agentId) {
|
|
47248
|
-
const packageName = getPackageNameForAgent(agentId);
|
|
47249
|
-
if (!packageName) {
|
|
47250
|
-
return [];
|
|
47251
|
-
}
|
|
47252
|
-
const versions = await fetchPackageVersions(packageName);
|
|
47253
|
-
return versions.map((v) => {
|
|
47254
|
-
const item = {
|
|
47255
|
-
label: v.isPrerelease ? `${v.version} (pre)` : v.version,
|
|
47256
|
-
value: v.version
|
|
47257
|
-
};
|
|
47258
|
-
if (v.publishedAt) {
|
|
47259
|
-
item.description = new Date(v.publishedAt).toLocaleDateString();
|
|
47260
|
-
}
|
|
47261
|
-
return item;
|
|
47262
|
-
});
|
|
47263
|
-
}
|
|
47264
|
-
var AGENT_COMMAND_MAP = {
|
|
47265
|
-
"claude-code": "claude",
|
|
47266
|
-
"codex-cli": "codex",
|
|
47267
|
-
"gemini-cli": "gemini",
|
|
47268
|
-
opencode: "opencode"
|
|
47269
|
-
};
|
|
47270
|
-
async function fetchInstalledOption(agentId) {
|
|
47271
|
-
const commandName = AGENT_COMMAND_MAP[agentId];
|
|
47272
|
-
if (!commandName) {
|
|
47273
|
-
return null;
|
|
47274
|
-
}
|
|
47275
|
-
const result = await findCommand(commandName);
|
|
47276
|
-
if (result.source !== "installed" || !result.path) {
|
|
47277
|
-
return null;
|
|
47278
|
-
}
|
|
47279
|
-
const version = result.version?.replace(/^v/, "") ?? "unknown";
|
|
47280
|
-
return {
|
|
47281
|
-
label: `installed@${version}`,
|
|
47282
|
-
value: "installed",
|
|
47283
|
-
description: result.path
|
|
47284
|
-
};
|
|
47285
|
-
}
|
|
47286
47497
|
function VersionSelectStep(props) {
|
|
47287
47498
|
const [selectedIndex, setSelectedIndex] = createSignal(0);
|
|
47288
47499
|
const [selectRef, setSelectRef] = createSignal(undefined);
|
|
47289
|
-
const
|
|
47290
|
-
|
|
47500
|
+
const cachedVersions = () => {
|
|
47501
|
+
const cached = getVersionCache(props.agentId);
|
|
47502
|
+
if (!cached) {
|
|
47503
|
+
return [];
|
|
47504
|
+
}
|
|
47505
|
+
return cached.map(versionInfoToSelectItem);
|
|
47506
|
+
};
|
|
47507
|
+
const installedOption = () => {
|
|
47508
|
+
const installed = getInstalledVersionCache(props.agentId);
|
|
47509
|
+
return installed ? createInstalledOption(installed) : null;
|
|
47510
|
+
};
|
|
47291
47511
|
const allOptions = () => {
|
|
47292
47512
|
const options = [];
|
|
47293
47513
|
const installed = installedOption();
|
|
@@ -47295,8 +47515,8 @@ function VersionSelectStep(props) {
|
|
|
47295
47515
|
options.push(installed);
|
|
47296
47516
|
}
|
|
47297
47517
|
options.push(LATEST_OPTION);
|
|
47298
|
-
const
|
|
47299
|
-
options.push(...
|
|
47518
|
+
const cached = cachedVersions();
|
|
47519
|
+
options.push(...cached);
|
|
47300
47520
|
return options;
|
|
47301
47521
|
};
|
|
47302
47522
|
useEnsureSelectionVisible({
|
|
@@ -47327,34 +47547,32 @@ function VersionSelectStep(props) {
|
|
|
47327
47547
|
}
|
|
47328
47548
|
};
|
|
47329
47549
|
const statusText = () => {
|
|
47330
|
-
|
|
47331
|
-
|
|
47332
|
-
|
|
47333
|
-
if (versionOptions.error) {
|
|
47334
|
-
return "Could not fetch versions";
|
|
47550
|
+
const cached = cachedVersions();
|
|
47551
|
+
if (cached.length === 0) {
|
|
47552
|
+
return "Version list unavailable (using latest)";
|
|
47335
47553
|
}
|
|
47336
47554
|
return null;
|
|
47337
47555
|
};
|
|
47338
47556
|
return (() => {
|
|
47339
|
-
var _el$
|
|
47340
|
-
insertNode(_el$
|
|
47341
|
-
insertNode(_el$
|
|
47342
|
-
insertNode(_el$
|
|
47343
|
-
insertNode(_el$
|
|
47344
|
-
setProp(_el$
|
|
47345
|
-
insertNode(_el$
|
|
47346
|
-
setProp(_el$
|
|
47347
|
-
insert(_el$
|
|
47557
|
+
var _el$88 = createElement("box"), _el$89 = createElement("text"), _el$91 = createElement("text"), _el$93 = createElement("text"), _el$95 = createElement("text");
|
|
47558
|
+
insertNode(_el$88, _el$89);
|
|
47559
|
+
insertNode(_el$88, _el$91);
|
|
47560
|
+
insertNode(_el$88, _el$93);
|
|
47561
|
+
insertNode(_el$88, _el$95);
|
|
47562
|
+
setProp(_el$88, "flexDirection", "column");
|
|
47563
|
+
insertNode(_el$89, createTextNode(`Select version:`));
|
|
47564
|
+
setProp(_el$89, "fg", "cyan");
|
|
47565
|
+
insert(_el$88, (() => {
|
|
47348
47566
|
var _c$ = memo2(() => !!statusText());
|
|
47349
47567
|
return () => _c$() && (() => {
|
|
47350
|
-
var _el$
|
|
47351
|
-
insert(_el$
|
|
47352
|
-
effect((_$p) => setProp(_el$
|
|
47353
|
-
return _el$
|
|
47568
|
+
var _el$97 = createElement("text");
|
|
47569
|
+
insert(_el$97, statusText);
|
|
47570
|
+
effect((_$p) => setProp(_el$97, "attributes", TextAttributes.DIM, _$p));
|
|
47571
|
+
return _el$97;
|
|
47354
47572
|
})();
|
|
47355
|
-
})(), _el$
|
|
47356
|
-
insertNode(_el$
|
|
47357
|
-
insert(_el$
|
|
47573
|
+
})(), _el$91);
|
|
47574
|
+
insertNode(_el$91, createTextNode(` `));
|
|
47575
|
+
insert(_el$88, createComponent2(SelectInput, {
|
|
47358
47576
|
get items() {
|
|
47359
47577
|
return allOptions();
|
|
47360
47578
|
},
|
|
@@ -47364,19 +47582,19 @@ function VersionSelectStep(props) {
|
|
|
47364
47582
|
return props.focused ?? true;
|
|
47365
47583
|
},
|
|
47366
47584
|
selectRef: setSelectRef
|
|
47367
|
-
}), _el$
|
|
47368
|
-
insertNode(_el$
|
|
47369
|
-
insertNode(_el$
|
|
47585
|
+
}), _el$93);
|
|
47586
|
+
insertNode(_el$93, createTextNode(` `));
|
|
47587
|
+
insertNode(_el$95, createTextNode(`[Enter] Select [Esc] Back`));
|
|
47370
47588
|
effect((_p$) => {
|
|
47371
|
-
var _v$
|
|
47372
|
-
_v$
|
|
47373
|
-
_v$
|
|
47589
|
+
var _v$19 = TextAttributes.BOLD, _v$20 = TextAttributes.DIM;
|
|
47590
|
+
_v$19 !== _p$.e && (_p$.e = setProp(_el$89, "attributes", _v$19, _p$.e));
|
|
47591
|
+
_v$20 !== _p$.t && (_p$.t = setProp(_el$95, "attributes", _v$20, _p$.t));
|
|
47374
47592
|
return _p$;
|
|
47375
47593
|
}, {
|
|
47376
47594
|
e: undefined,
|
|
47377
47595
|
t: undefined
|
|
47378
47596
|
});
|
|
47379
|
-
return _el$
|
|
47597
|
+
return _el$88;
|
|
47380
47598
|
})();
|
|
47381
47599
|
}
|
|
47382
47600
|
|
|
@@ -47392,7 +47610,9 @@ function WizardController(props) {
|
|
|
47392
47610
|
const [selectedModel, setSelectedModel] = createSignal("");
|
|
47393
47611
|
const [reasoningLevel, setReasoningLevel] = createSignal(undefined);
|
|
47394
47612
|
const [executionMode, setExecutionMode] = createSignal("normal");
|
|
47395
|
-
const [
|
|
47613
|
+
const [versionSelectionReady, setVersionSelectionReady] = createSignal(false);
|
|
47614
|
+
const [isTransitioning, setIsTransitioning] = createSignal(true);
|
|
47615
|
+
let versionSelectionTimer = null;
|
|
47396
47616
|
function getInitialStep() {
|
|
47397
47617
|
if (props.history.length > 0) {
|
|
47398
47618
|
return "quick-start";
|
|
@@ -47411,20 +47631,23 @@ function WizardController(props) {
|
|
|
47411
47631
|
setReasoningLevel(undefined);
|
|
47412
47632
|
setExecutionMode("normal");
|
|
47413
47633
|
};
|
|
47634
|
+
const startTransition2 = () => {
|
|
47635
|
+
setIsTransitioning(true);
|
|
47636
|
+
setTimeout(() => setIsTransitioning(false), 50);
|
|
47637
|
+
};
|
|
47414
47638
|
let prevVisible = false;
|
|
47415
47639
|
createEffect(() => {
|
|
47416
47640
|
const visible = props.visible;
|
|
47417
47641
|
if (visible && !prevVisible) {
|
|
47418
47642
|
resetWizard();
|
|
47419
|
-
|
|
47420
|
-
setTimeout(() => setIsInitialFrame(false), 150);
|
|
47643
|
+
startTransition2();
|
|
47421
47644
|
}
|
|
47422
47645
|
prevVisible = visible;
|
|
47423
47646
|
});
|
|
47424
47647
|
useKeyboard((key) => {
|
|
47425
47648
|
if (!props.visible)
|
|
47426
47649
|
return;
|
|
47427
|
-
if (
|
|
47650
|
+
if (isTransitioning() && key.name === "return") {
|
|
47428
47651
|
return;
|
|
47429
47652
|
}
|
|
47430
47653
|
if (key.name === "escape") {
|
|
@@ -47434,6 +47657,7 @@ function WizardController(props) {
|
|
|
47434
47657
|
const goToStep = (nextStep) => {
|
|
47435
47658
|
setStepHistory((prev) => [...prev, step()]);
|
|
47436
47659
|
setStep(nextStep);
|
|
47660
|
+
startTransition2();
|
|
47437
47661
|
};
|
|
47438
47662
|
const goBack = () => {
|
|
47439
47663
|
const history = stepHistory();
|
|
@@ -47444,7 +47668,28 @@ function WizardController(props) {
|
|
|
47444
47668
|
const previousStep = history[history.length - 1] ?? "agent-select";
|
|
47445
47669
|
setStepHistory(history.slice(0, -1));
|
|
47446
47670
|
setStep(previousStep);
|
|
47671
|
+
startTransition2();
|
|
47447
47672
|
};
|
|
47673
|
+
createEffect(() => {
|
|
47674
|
+
const currentStep = step();
|
|
47675
|
+
if (versionSelectionTimer) {
|
|
47676
|
+
clearTimeout(versionSelectionTimer);
|
|
47677
|
+
versionSelectionTimer = null;
|
|
47678
|
+
}
|
|
47679
|
+
if (currentStep === "version-select") {
|
|
47680
|
+
setVersionSelectionReady(false);
|
|
47681
|
+
versionSelectionTimer = setTimeout(() => {
|
|
47682
|
+
setVersionSelectionReady(true);
|
|
47683
|
+
}, 50);
|
|
47684
|
+
return;
|
|
47685
|
+
}
|
|
47686
|
+
setVersionSelectionReady(false);
|
|
47687
|
+
});
|
|
47688
|
+
onCleanup(() => {
|
|
47689
|
+
if (versionSelectionTimer) {
|
|
47690
|
+
clearTimeout(versionSelectionTimer);
|
|
47691
|
+
}
|
|
47692
|
+
});
|
|
47448
47693
|
const needsReasoningLevel = createMemo(() => {
|
|
47449
47694
|
return selectedAgent() === "codex-cli";
|
|
47450
47695
|
});
|
|
@@ -47479,10 +47724,18 @@ function WizardController(props) {
|
|
|
47479
47724
|
goToStep("version-select");
|
|
47480
47725
|
};
|
|
47481
47726
|
const handleVersionSelect = (version) => {
|
|
47482
|
-
|
|
47727
|
+
if (!versionSelectionReady() || step() !== "version-select") {
|
|
47728
|
+
return;
|
|
47729
|
+
}
|
|
47730
|
+
setSelectedVersion(version);
|
|
47483
47731
|
goToStep("model-select");
|
|
47484
47732
|
};
|
|
47485
47733
|
const handleModelSelect = (model) => {
|
|
47734
|
+
const agent = selectedAgent();
|
|
47735
|
+
if (agent === "opencode" && model === "__custom__") {
|
|
47736
|
+
goToStep("model-input");
|
|
47737
|
+
return;
|
|
47738
|
+
}
|
|
47486
47739
|
setSelectedModel(model);
|
|
47487
47740
|
if (needsReasoningLevel()) {
|
|
47488
47741
|
goToStep("reasoning-level");
|
|
@@ -47490,6 +47743,18 @@ function WizardController(props) {
|
|
|
47490
47743
|
goToStep("execution-mode");
|
|
47491
47744
|
}
|
|
47492
47745
|
};
|
|
47746
|
+
const handleModelInputSubmit = (value) => {
|
|
47747
|
+
const trimmed = value.trim();
|
|
47748
|
+
if (!trimmed) {
|
|
47749
|
+
return;
|
|
47750
|
+
}
|
|
47751
|
+
setSelectedModel(trimmed);
|
|
47752
|
+
if (needsReasoningLevel()) {
|
|
47753
|
+
goToStep("reasoning-level");
|
|
47754
|
+
} else {
|
|
47755
|
+
goToStep("execution-mode");
|
|
47756
|
+
}
|
|
47757
|
+
};
|
|
47493
47758
|
const handleReasoningLevelSelect = (level) => {
|
|
47494
47759
|
setReasoningLevel(level);
|
|
47495
47760
|
goToStep("execution-mode");
|
|
@@ -47526,7 +47791,7 @@ function WizardController(props) {
|
|
|
47526
47791
|
};
|
|
47527
47792
|
const renderStep = () => {
|
|
47528
47793
|
const currentStep = step();
|
|
47529
|
-
const focused = !
|
|
47794
|
+
const focused = !isTransitioning();
|
|
47530
47795
|
if (currentStep === "action-select") {
|
|
47531
47796
|
return createComponent2(ActionSelectStep, {
|
|
47532
47797
|
get branchName() {
|
|
@@ -47593,6 +47858,16 @@ function WizardController(props) {
|
|
|
47593
47858
|
focused
|
|
47594
47859
|
});
|
|
47595
47860
|
}
|
|
47861
|
+
if (currentStep === "model-input") {
|
|
47862
|
+
return createComponent2(ModelInputStep, {
|
|
47863
|
+
get agentId() {
|
|
47864
|
+
return selectedAgent() ?? "claude-code";
|
|
47865
|
+
},
|
|
47866
|
+
onSubmit: handleModelInputSubmit,
|
|
47867
|
+
onBack: goBack,
|
|
47868
|
+
focused
|
|
47869
|
+
});
|
|
47870
|
+
}
|
|
47596
47871
|
if (currentStep === "reasoning-level") {
|
|
47597
47872
|
return createComponent2(ReasoningLevelStep, {
|
|
47598
47873
|
onSelect: handleReasoningLevelSelect,
|
|
@@ -47780,6 +48055,10 @@ function useScrollableList(options) {
|
|
|
47780
48055
|
|
|
47781
48056
|
// src/cli/ui/screens/solid/SelectorScreen.tsx
|
|
47782
48057
|
var clamp2 = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
48058
|
+
var padLine2 = (value, width) => {
|
|
48059
|
+
const padding = Math.max(0, width - stringWidth(value));
|
|
48060
|
+
return padding > 0 ? `${value}${" ".repeat(padding)}` : value;
|
|
48061
|
+
};
|
|
47783
48062
|
function SelectorScreen({
|
|
47784
48063
|
title,
|
|
47785
48064
|
description,
|
|
@@ -47898,30 +48177,34 @@ function SelectorScreen({
|
|
|
47898
48177
|
insert(_el$5, () => list.visibleItems().map((item, index) => {
|
|
47899
48178
|
const absoluteIndex = list.scrollOffset() + index;
|
|
47900
48179
|
const isSelected = absoluteIndex === selectedIndex();
|
|
48180
|
+
const descriptionText = showDescription && item.description ? ` - ${item.description}` : "";
|
|
48181
|
+
const fullLine = `${item.label}${descriptionText}`;
|
|
47901
48182
|
return (() => {
|
|
47902
|
-
var _el$6 = createElement("box")
|
|
47903
|
-
insertNode(_el$6, _el$7);
|
|
48183
|
+
var _el$6 = createElement("box");
|
|
47904
48184
|
setProp(_el$6, "flexDirection", "row");
|
|
47905
|
-
|
|
47906
|
-
|
|
47907
|
-
|
|
47908
|
-
|
|
47909
|
-
|
|
47910
|
-
|
|
47911
|
-
|
|
47912
|
-
|
|
47913
|
-
|
|
47914
|
-
|
|
47915
|
-
|
|
47916
|
-
|
|
47917
|
-
|
|
47918
|
-
|
|
47919
|
-
|
|
47920
|
-
|
|
47921
|
-
|
|
47922
|
-
|
|
47923
|
-
|
|
47924
|
-
|
|
48185
|
+
insert(_el$6, isSelected ? (() => {
|
|
48186
|
+
var _el$7 = createElement("text");
|
|
48187
|
+
insert(_el$7, () => padLine2(fullLine, terminal().columns));
|
|
48188
|
+
effect((_p$) => {
|
|
48189
|
+
var _v$ = selectionStyle.fg, _v$2 = selectionStyle.bg;
|
|
48190
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$7, "fg", _v$, _p$.e));
|
|
48191
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$7, "bg", _v$2, _p$.t));
|
|
48192
|
+
return _p$;
|
|
48193
|
+
}, {
|
|
48194
|
+
e: undefined,
|
|
48195
|
+
t: undefined
|
|
48196
|
+
});
|
|
48197
|
+
return _el$7;
|
|
48198
|
+
})() : [(() => {
|
|
48199
|
+
var _el$8 = createElement("text");
|
|
48200
|
+
insert(_el$8, () => item.label);
|
|
48201
|
+
return _el$8;
|
|
48202
|
+
})(), memo2(() => memo2(() => !!(showDescription && item.description))() ? (() => {
|
|
48203
|
+
var _el$9 = createElement("text");
|
|
48204
|
+
insert(_el$9, () => ` - ${item.description}`);
|
|
48205
|
+
effect((_$p) => setProp(_el$9, "attributes", TextAttributes.DIM, _$p));
|
|
48206
|
+
return _el$9;
|
|
48207
|
+
})() : null)]);
|
|
47925
48208
|
return _el$6;
|
|
47926
48209
|
})();
|
|
47927
48210
|
}));
|
|
@@ -47939,53 +48222,237 @@ function SelectorScreen({
|
|
|
47939
48222
|
}
|
|
47940
48223
|
|
|
47941
48224
|
// src/cli/ui/screens/solid/LogScreen.tsx
|
|
47942
|
-
|
|
47943
|
-
|
|
47944
|
-
|
|
47945
|
-
|
|
47946
|
-
|
|
47947
|
-
|
|
47948
|
-
|
|
47949
|
-
|
|
47950
|
-
|
|
47951
|
-
|
|
47952
|
-
|
|
47953
|
-
|
|
47954
|
-
|
|
48225
|
+
var LEVEL_ORDER = ["ALL", "INFO+", "WARN+", "ERROR+"];
|
|
48226
|
+
var LEVEL_THRESHOLDS = {
|
|
48227
|
+
ALL: 0,
|
|
48228
|
+
"INFO+": 30,
|
|
48229
|
+
"WARN+": 40,
|
|
48230
|
+
"ERROR+": 50
|
|
48231
|
+
};
|
|
48232
|
+
var LEVEL_LABEL_VALUES = {
|
|
48233
|
+
TRACE: 10,
|
|
48234
|
+
DEBUG: 20,
|
|
48235
|
+
INFO: 30,
|
|
48236
|
+
WARN: 40,
|
|
48237
|
+
ERROR: 50,
|
|
48238
|
+
FATAL: 60
|
|
48239
|
+
};
|
|
48240
|
+
var measureWidth2 = (value) => stringWidth(value);
|
|
48241
|
+
var truncateToWidth3 = (value, maxWidth) => {
|
|
48242
|
+
if (maxWidth <= 0) {
|
|
48243
|
+
return "";
|
|
48244
|
+
}
|
|
48245
|
+
if (measureWidth2(value) <= maxWidth) {
|
|
48246
|
+
return value;
|
|
48247
|
+
}
|
|
48248
|
+
const ellipsis = "...";
|
|
48249
|
+
const ellipsisWidth = measureWidth2(ellipsis);
|
|
48250
|
+
if (ellipsisWidth >= maxWidth) {
|
|
48251
|
+
return ellipsis.slice(0, maxWidth);
|
|
48252
|
+
}
|
|
48253
|
+
let currentWidth = 0;
|
|
48254
|
+
let result = "";
|
|
48255
|
+
for (const char of Array.from(value)) {
|
|
48256
|
+
const charWidth = measureWidth2(char);
|
|
48257
|
+
if (currentWidth + charWidth + ellipsisWidth > maxWidth) {
|
|
48258
|
+
break;
|
|
48259
|
+
}
|
|
48260
|
+
result += char;
|
|
48261
|
+
currentWidth += charWidth;
|
|
48262
|
+
}
|
|
48263
|
+
return `${result}${ellipsis}`;
|
|
48264
|
+
};
|
|
48265
|
+
var padToWidth = (value, width) => {
|
|
48266
|
+
if (width <= 0) {
|
|
48267
|
+
return "";
|
|
48268
|
+
}
|
|
48269
|
+
const truncated = truncateToWidth3(value, width);
|
|
48270
|
+
const padding = Math.max(0, width - measureWidth2(truncated));
|
|
48271
|
+
return `${truncated}${" ".repeat(padding)}`;
|
|
48272
|
+
};
|
|
48273
|
+
var appendSegment2 = (segments, segment) => {
|
|
48274
|
+
if (!segment.text) {
|
|
48275
|
+
return;
|
|
48276
|
+
}
|
|
48277
|
+
segments.push(segment);
|
|
48278
|
+
};
|
|
48279
|
+
var measureSegmentsWidth2 = (segments) => segments.reduce((total, segment) => total + measureWidth2(segment.text), 0);
|
|
48280
|
+
var truncateSegmentsToWidth2 = (segments, maxWidth) => {
|
|
48281
|
+
if (maxWidth <= 0) {
|
|
48282
|
+
return [];
|
|
48283
|
+
}
|
|
48284
|
+
const result = [];
|
|
48285
|
+
let currentWidth = 0;
|
|
48286
|
+
for (const segment of segments) {
|
|
48287
|
+
if (currentWidth >= maxWidth) {
|
|
48288
|
+
break;
|
|
48289
|
+
}
|
|
48290
|
+
const segmentWidth = measureWidth2(segment.text);
|
|
48291
|
+
if (currentWidth + segmentWidth <= maxWidth) {
|
|
48292
|
+
result.push(segment);
|
|
48293
|
+
currentWidth += segmentWidth;
|
|
48294
|
+
continue;
|
|
48295
|
+
}
|
|
48296
|
+
const remaining = maxWidth - currentWidth;
|
|
48297
|
+
const truncated = truncateToWidth3(segment.text, remaining);
|
|
48298
|
+
if (truncated) {
|
|
48299
|
+
result.push({
|
|
48300
|
+
...segment,
|
|
48301
|
+
text: truncated
|
|
48302
|
+
});
|
|
48303
|
+
currentWidth += measureWidth2(truncated);
|
|
48304
|
+
}
|
|
48305
|
+
break;
|
|
48306
|
+
}
|
|
48307
|
+
return result;
|
|
48308
|
+
};
|
|
48309
|
+
var segmentsToText = (segments) => segments.map((segment) => segment.text).join("");
|
|
48310
|
+
var padLine3 = (value, width) => {
|
|
48311
|
+
const padding = Math.max(0, width - measureWidth2(value));
|
|
48312
|
+
return padding > 0 ? `${value}${" ".repeat(padding)}` : value;
|
|
48313
|
+
};
|
|
48314
|
+
var resolveEntryLevel = (entry) => {
|
|
48315
|
+
const rawLevel = entry.raw?.level;
|
|
48316
|
+
if (typeof rawLevel === "number") {
|
|
48317
|
+
return rawLevel;
|
|
48318
|
+
}
|
|
48319
|
+
const label = entry.levelLabel?.toUpperCase() ?? "";
|
|
48320
|
+
return LEVEL_LABEL_VALUES[label] ?? 0;
|
|
48321
|
+
};
|
|
48322
|
+
function LogScreen(props) {
|
|
48323
|
+
const merged = mergeProps({
|
|
48324
|
+
loading: false,
|
|
48325
|
+
error: null,
|
|
48326
|
+
branchLabel: null,
|
|
48327
|
+
sourceLabel: null,
|
|
48328
|
+
tailing: false,
|
|
48329
|
+
helpVisible: false
|
|
48330
|
+
}, props);
|
|
47955
48331
|
const terminal = useTerminalSize();
|
|
48332
|
+
const [filterQuery, setFilterQuery] = createSignal("");
|
|
48333
|
+
const [filterMode, setFilterMode] = createSignal(false);
|
|
48334
|
+
const [levelMode, setLevelMode] = createSignal("ALL");
|
|
48335
|
+
const filteredEntries = createMemo(() => {
|
|
48336
|
+
let result = merged.entries;
|
|
48337
|
+
const threshold = LEVEL_THRESHOLDS[levelMode()];
|
|
48338
|
+
if (threshold > 0) {
|
|
48339
|
+
result = result.filter((entry) => resolveEntryLevel(entry) >= threshold);
|
|
48340
|
+
}
|
|
48341
|
+
const query = filterQuery().trim().toLowerCase();
|
|
48342
|
+
if (!query) {
|
|
48343
|
+
return result;
|
|
48344
|
+
}
|
|
48345
|
+
return result.filter((entry) => {
|
|
48346
|
+
const target = `${entry.category} ${entry.levelLabel} ${entry.message}`.toLowerCase();
|
|
48347
|
+
return target.includes(query);
|
|
48348
|
+
});
|
|
48349
|
+
});
|
|
48350
|
+
const totalCount = createMemo(() => merged.entries.length);
|
|
48351
|
+
const filteredCount = createMemo(() => filteredEntries().length);
|
|
48352
|
+
const showFilterCount = createMemo(() => filterMode() || filterQuery().trim().length > 0);
|
|
48353
|
+
const levelWidth = createMemo(() => {
|
|
48354
|
+
const MIN = 5;
|
|
48355
|
+
return Math.max(MIN, ...filteredEntries().map((entry) => measureWidth2(entry.levelLabel)));
|
|
48356
|
+
});
|
|
48357
|
+
const categoryWidth = createMemo(() => {
|
|
48358
|
+
const MIN = 4;
|
|
48359
|
+
const MAX = 20;
|
|
48360
|
+
const maxWidth = Math.max(MIN, ...filteredEntries().map((entry) => measureWidth2(entry.category)));
|
|
48361
|
+
return Math.min(MAX, maxWidth);
|
|
48362
|
+
});
|
|
47956
48363
|
const listHeight = createMemo(() => {
|
|
47957
48364
|
const headerRows = 2;
|
|
47958
|
-
const infoRows =
|
|
48365
|
+
const infoRows = 3;
|
|
47959
48366
|
const footerRows = 1;
|
|
47960
|
-
const notificationRows = notification ? 1 : 0;
|
|
48367
|
+
const notificationRows = merged.notification ? 1 : 0;
|
|
47961
48368
|
const reserved = headerRows + infoRows + footerRows + notificationRows;
|
|
47962
48369
|
return Math.max(1, terminal().rows - reserved);
|
|
47963
48370
|
});
|
|
47964
48371
|
const list = useScrollableList({
|
|
47965
|
-
items:
|
|
48372
|
+
items: filteredEntries,
|
|
47966
48373
|
visibleCount: listHeight
|
|
47967
48374
|
});
|
|
47968
|
-
const currentEntry = createMemo(() =>
|
|
48375
|
+
const currentEntry = createMemo(() => filteredEntries()[list.selectedIndex()]);
|
|
48376
|
+
createEffect(() => {
|
|
48377
|
+
filterQuery();
|
|
48378
|
+
levelMode();
|
|
48379
|
+
list.setSelectedIndex(0);
|
|
48380
|
+
list.setScrollOffset(0);
|
|
48381
|
+
});
|
|
47969
48382
|
const updateSelectedIndex = (value) => {
|
|
47970
48383
|
list.setSelectedIndex(value);
|
|
47971
48384
|
};
|
|
47972
48385
|
useKeyboard((key) => {
|
|
47973
|
-
if (helpVisible) {
|
|
48386
|
+
if (merged.helpVisible) {
|
|
48387
|
+
return;
|
|
48388
|
+
}
|
|
48389
|
+
if (filterMode()) {
|
|
48390
|
+
if (key.name === "down") {
|
|
48391
|
+
updateSelectedIndex((prev) => prev + 1);
|
|
48392
|
+
return;
|
|
48393
|
+
}
|
|
48394
|
+
if (key.name === "up") {
|
|
48395
|
+
updateSelectedIndex((prev) => prev - 1);
|
|
48396
|
+
return;
|
|
48397
|
+
}
|
|
48398
|
+
if (key.name === "escape") {
|
|
48399
|
+
if (filterQuery()) {
|
|
48400
|
+
setFilterQuery("");
|
|
48401
|
+
} else {
|
|
48402
|
+
setFilterMode(false);
|
|
48403
|
+
}
|
|
48404
|
+
return;
|
|
48405
|
+
}
|
|
48406
|
+
if (key.name === "backspace") {
|
|
48407
|
+
setFilterQuery((prev) => prev.slice(0, -1));
|
|
48408
|
+
return;
|
|
48409
|
+
}
|
|
48410
|
+
if (key.name === "return" || key.name === "linefeed") {
|
|
48411
|
+
setFilterMode(false);
|
|
48412
|
+
return;
|
|
48413
|
+
}
|
|
48414
|
+
if (key.sequence && key.sequence.length === 1 && !key.ctrl && !key.meta && !key.super && !key.hyper) {
|
|
48415
|
+
setFilterQuery((prev) => prev + key.sequence);
|
|
48416
|
+
}
|
|
47974
48417
|
return;
|
|
47975
48418
|
}
|
|
47976
48419
|
if (key.name === "escape" || key.name === "q") {
|
|
47977
|
-
onBack();
|
|
48420
|
+
merged.onBack();
|
|
47978
48421
|
return;
|
|
47979
48422
|
}
|
|
47980
48423
|
if (key.name === "c") {
|
|
47981
48424
|
const entry = currentEntry();
|
|
47982
48425
|
if (entry) {
|
|
47983
|
-
onCopy(entry);
|
|
48426
|
+
merged.onCopy(entry);
|
|
47984
48427
|
}
|
|
47985
48428
|
return;
|
|
47986
48429
|
}
|
|
47987
48430
|
if (key.name === "d") {
|
|
47988
|
-
onPickDate?.();
|
|
48431
|
+
merged.onPickDate?.();
|
|
48432
|
+
return;
|
|
48433
|
+
}
|
|
48434
|
+
if (key.name === "f") {
|
|
48435
|
+
setFilterMode(true);
|
|
48436
|
+
return;
|
|
48437
|
+
}
|
|
48438
|
+
if (key.name === "v") {
|
|
48439
|
+
setLevelMode((prev) => {
|
|
48440
|
+
const index = LEVEL_ORDER.indexOf(prev);
|
|
48441
|
+
const nextIndex = (index + 1) % LEVEL_ORDER.length;
|
|
48442
|
+
return LEVEL_ORDER[nextIndex] ?? "ALL";
|
|
48443
|
+
});
|
|
48444
|
+
return;
|
|
48445
|
+
}
|
|
48446
|
+
if (key.name === "r") {
|
|
48447
|
+
merged.onReload?.();
|
|
48448
|
+
return;
|
|
48449
|
+
}
|
|
48450
|
+
if (key.name === "t") {
|
|
48451
|
+
merged.onToggleTail?.();
|
|
48452
|
+
return;
|
|
48453
|
+
}
|
|
48454
|
+
if (key.name === "x") {
|
|
48455
|
+
merged.onReset?.();
|
|
47989
48456
|
return;
|
|
47990
48457
|
}
|
|
47991
48458
|
if (key.name === "down") {
|
|
@@ -48009,13 +48476,13 @@ function LogScreen({
|
|
|
48009
48476
|
return;
|
|
48010
48477
|
}
|
|
48011
48478
|
if (key.name === "end") {
|
|
48012
|
-
updateSelectedIndex(
|
|
48479
|
+
updateSelectedIndex(filteredEntries().length - 1);
|
|
48013
48480
|
return;
|
|
48014
48481
|
}
|
|
48015
48482
|
if (key.name === "return" || key.name === "linefeed") {
|
|
48016
48483
|
const entry = currentEntry();
|
|
48017
48484
|
if (entry) {
|
|
48018
|
-
onSelect(entry);
|
|
48485
|
+
merged.onSelect(entry);
|
|
48019
48486
|
}
|
|
48020
48487
|
}
|
|
48021
48488
|
});
|
|
@@ -48029,92 +48496,227 @@ function LogScreen({
|
|
|
48029
48496
|
}, {
|
|
48030
48497
|
key: "d",
|
|
48031
48498
|
description: "Date"
|
|
48499
|
+
}, {
|
|
48500
|
+
key: "f",
|
|
48501
|
+
description: "Filter"
|
|
48502
|
+
}, {
|
|
48503
|
+
key: "v",
|
|
48504
|
+
description: "Level"
|
|
48505
|
+
}, {
|
|
48506
|
+
key: "r",
|
|
48507
|
+
description: "Reload"
|
|
48508
|
+
}, {
|
|
48509
|
+
key: "t",
|
|
48510
|
+
description: "Tail"
|
|
48511
|
+
}, {
|
|
48512
|
+
key: "x",
|
|
48513
|
+
description: "Reset"
|
|
48032
48514
|
}, {
|
|
48033
48515
|
key: "esc",
|
|
48034
48516
|
description: "Back"
|
|
48035
48517
|
}];
|
|
48036
48518
|
return actions;
|
|
48037
48519
|
});
|
|
48520
|
+
const formatEntrySegments = (entry) => {
|
|
48521
|
+
const levelText = padToWidth(entry.levelLabel, levelWidth());
|
|
48522
|
+
const categoryText = padToWidth(entry.category, categoryWidth());
|
|
48523
|
+
const segments = [];
|
|
48524
|
+
appendSegment2(segments, {
|
|
48525
|
+
text: `[${entry.timeLabel}] `
|
|
48526
|
+
});
|
|
48527
|
+
appendSegment2(segments, {
|
|
48528
|
+
text: "["
|
|
48529
|
+
});
|
|
48530
|
+
appendSegment2(segments, {
|
|
48531
|
+
text: levelText,
|
|
48532
|
+
fg: getLogLevelColor(entry.levelLabel)
|
|
48533
|
+
});
|
|
48534
|
+
appendSegment2(segments, {
|
|
48535
|
+
text: "] "
|
|
48536
|
+
});
|
|
48537
|
+
appendSegment2(segments, {
|
|
48538
|
+
text: "["
|
|
48539
|
+
});
|
|
48540
|
+
appendSegment2(segments, {
|
|
48541
|
+
text: categoryText
|
|
48542
|
+
});
|
|
48543
|
+
appendSegment2(segments, {
|
|
48544
|
+
text: "] "
|
|
48545
|
+
});
|
|
48546
|
+
appendSegment2(segments, {
|
|
48547
|
+
text: entry.message
|
|
48548
|
+
});
|
|
48549
|
+
const maxWidth = terminal().columns;
|
|
48550
|
+
if (measureSegmentsWidth2(segments) <= maxWidth) {
|
|
48551
|
+
return segments;
|
|
48552
|
+
}
|
|
48553
|
+
return truncateSegmentsToWidth2(segments, maxWidth);
|
|
48554
|
+
};
|
|
48555
|
+
const filterLabel = createMemo(() => {
|
|
48556
|
+
if (filterQuery()) {
|
|
48557
|
+
return filterQuery();
|
|
48558
|
+
}
|
|
48559
|
+
return filterMode() ? "(type to filter)" : "(press f to filter)";
|
|
48560
|
+
});
|
|
48038
48561
|
return (() => {
|
|
48039
|
-
var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$5 = createElement("text"), _el$6 = createElement("text"), _el$8 = createElement("text"), _el$9 = createElement("box");
|
|
48562
|
+
var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$5 = createElement("text"), _el$6 = createElement("text"), _el$8 = createElement("text"), _el$9 = createElement("box"), _el$0 = createElement("text"), _el$10 = createElement("text"), _el$11 = createElement("text"), _el$13 = createElement("text"), _el$14 = createElement("text"), _el$16 = createElement("text"), _el$17 = createElement("text"), _el$19 = createElement("text"), _el$20 = createElement("box"), _el$21 = createElement("text"), _el$23 = createElement("text"), _el$24 = createElement("box");
|
|
48040
48563
|
insertNode(_el$, _el$2);
|
|
48041
48564
|
insertNode(_el$, _el$9);
|
|
48565
|
+
insertNode(_el$, _el$20);
|
|
48566
|
+
insertNode(_el$, _el$24);
|
|
48042
48567
|
setProp(_el$, "flexDirection", "column");
|
|
48043
48568
|
insert(_el$, createComponent2(Header, {
|
|
48044
48569
|
title: "gwt - Log Viewer",
|
|
48045
48570
|
titleColor: "cyan",
|
|
48046
|
-
version
|
|
48571
|
+
get version() {
|
|
48572
|
+
return merged.version;
|
|
48573
|
+
}
|
|
48047
48574
|
}), _el$2);
|
|
48048
|
-
insert(_el$,
|
|
48049
|
-
var
|
|
48050
|
-
|
|
48051
|
-
|
|
48052
|
-
|
|
48053
|
-
|
|
48575
|
+
insert(_el$, (() => {
|
|
48576
|
+
var _c$ = memo2(() => !!merged.notification);
|
|
48577
|
+
return () => _c$() ? (() => {
|
|
48578
|
+
var _el$25 = createElement("text");
|
|
48579
|
+
insert(_el$25, () => merged.notification.message);
|
|
48580
|
+
effect((_$p) => setProp(_el$25, "fg", merged.notification.tone === "error" ? "red" : "green", _$p));
|
|
48581
|
+
return _el$25;
|
|
48582
|
+
})() : null;
|
|
48583
|
+
})(), _el$2);
|
|
48054
48584
|
insertNode(_el$2, _el$3);
|
|
48055
48585
|
insertNode(_el$2, _el$5);
|
|
48056
48586
|
insertNode(_el$2, _el$6);
|
|
48057
48587
|
insertNode(_el$2, _el$8);
|
|
48058
48588
|
setProp(_el$2, "flexDirection", "row");
|
|
48059
|
-
insertNode(_el$3, createTextNode(`
|
|
48060
|
-
insert(_el$5,
|
|
48061
|
-
insertNode(_el$6, createTextNode(`
|
|
48062
|
-
insert(_el$8, () =>
|
|
48063
|
-
|
|
48064
|
-
|
|
48065
|
-
|
|
48066
|
-
|
|
48067
|
-
|
|
48068
|
-
|
|
48069
|
-
|
|
48070
|
-
|
|
48071
|
-
|
|
48072
|
-
|
|
48073
|
-
|
|
48074
|
-
|
|
48075
|
-
|
|
48076
|
-
|
|
48077
|
-
|
|
48078
|
-
|
|
48079
|
-
|
|
48080
|
-
|
|
48081
|
-
|
|
48082
|
-
|
|
48083
|
-
|
|
48084
|
-
|
|
48085
|
-
|
|
48086
|
-
|
|
48087
|
-
|
|
48088
|
-
|
|
48089
|
-
|
|
48090
|
-
|
|
48091
|
-
|
|
48589
|
+
insertNode(_el$3, createTextNode(`Branch: `));
|
|
48590
|
+
insert(_el$5, () => merged.branchLabel ?? "(none)");
|
|
48591
|
+
insertNode(_el$6, createTextNode(` Source: `));
|
|
48592
|
+
insert(_el$8, () => merged.sourceLabel ?? "(none)");
|
|
48593
|
+
insertNode(_el$9, _el$0);
|
|
48594
|
+
insertNode(_el$9, _el$10);
|
|
48595
|
+
insertNode(_el$9, _el$11);
|
|
48596
|
+
insertNode(_el$9, _el$13);
|
|
48597
|
+
insertNode(_el$9, _el$14);
|
|
48598
|
+
insertNode(_el$9, _el$16);
|
|
48599
|
+
insertNode(_el$9, _el$17);
|
|
48600
|
+
insertNode(_el$9, _el$19);
|
|
48601
|
+
setProp(_el$9, "flexDirection", "row");
|
|
48602
|
+
insertNode(_el$0, createTextNode(`Date: `));
|
|
48603
|
+
insert(_el$10, () => merged.selectedDate ?? "---");
|
|
48604
|
+
insertNode(_el$11, createTextNode(` Total: `));
|
|
48605
|
+
insert(_el$13, totalCount);
|
|
48606
|
+
insertNode(_el$14, createTextNode(` Level: `));
|
|
48607
|
+
insert(_el$16, levelMode);
|
|
48608
|
+
insertNode(_el$17, createTextNode(` Tail: `));
|
|
48609
|
+
insert(_el$19, () => merged.tailing ? "ON" : "OFF");
|
|
48610
|
+
insertNode(_el$20, _el$21);
|
|
48611
|
+
insertNode(_el$20, _el$23);
|
|
48612
|
+
setProp(_el$20, "flexDirection", "row");
|
|
48613
|
+
insertNode(_el$21, createTextNode(`Filter: `));
|
|
48614
|
+
insert(_el$23, filterLabel);
|
|
48615
|
+
insert(_el$20, (() => {
|
|
48616
|
+
var _c$2 = memo2(() => !!showFilterCount());
|
|
48617
|
+
return () => _c$2() ? (() => {
|
|
48618
|
+
var _el$26 = createElement("text");
|
|
48619
|
+
insert(_el$26, () => ` (Showing ${filteredCount()} of ${totalCount()})`);
|
|
48620
|
+
effect((_$p) => setProp(_el$26, "attributes", TextAttributes.DIM, _$p));
|
|
48621
|
+
return _el$26;
|
|
48622
|
+
})() : null;
|
|
48623
|
+
})(), null);
|
|
48624
|
+
setProp(_el$24, "flexDirection", "column");
|
|
48625
|
+
setProp(_el$24, "flexGrow", 1);
|
|
48626
|
+
insert(_el$24, (() => {
|
|
48627
|
+
var _c$3 = memo2(() => !!merged.loading);
|
|
48628
|
+
return () => _c$3() ? (() => {
|
|
48629
|
+
var _el$27 = createElement("text");
|
|
48630
|
+
insertNode(_el$27, createTextNode(`Loading logs...`));
|
|
48631
|
+
setProp(_el$27, "fg", "gray");
|
|
48632
|
+
return _el$27;
|
|
48633
|
+
})() : memo2(() => filteredEntries().length === 0)() ? (() => {
|
|
48634
|
+
var _el$29 = createElement("text");
|
|
48635
|
+
insertNode(_el$29, createTextNode(`No logs available.`));
|
|
48636
|
+
setProp(_el$29, "fg", "gray");
|
|
48637
|
+
return _el$29;
|
|
48638
|
+
})() : (() => {
|
|
48639
|
+
var _el$31 = createElement("box");
|
|
48640
|
+
setProp(_el$31, "flexDirection", "column");
|
|
48641
|
+
insert(_el$31, () => list.visibleItems().map((entry, index) => {
|
|
48642
|
+
const absoluteIndex = list.scrollOffset() + index;
|
|
48643
|
+
const isSelected = absoluteIndex === list.selectedIndex();
|
|
48644
|
+
const segments = formatEntrySegments(entry);
|
|
48645
|
+
const lineText = segmentsToText(segments);
|
|
48646
|
+
const selectedContent = padLine3(lineText, terminal().columns);
|
|
48647
|
+
return (() => {
|
|
48648
|
+
var _el$32 = createElement("text");
|
|
48649
|
+
spread(_el$32, mergeProps3(() => isSelected ? {
|
|
48650
|
+
fg: selectionStyle.fg,
|
|
48651
|
+
bg: selectionStyle.bg
|
|
48652
|
+
} : {}, {
|
|
48653
|
+
wrapMode: "none",
|
|
48654
|
+
get width() {
|
|
48655
|
+
return terminal().columns;
|
|
48656
|
+
}
|
|
48657
|
+
}), true);
|
|
48658
|
+
insert(_el$32, () => isSelected ? selectedContent : segments.map((segment) => segment.fg ? (() => {
|
|
48659
|
+
var _el$33 = createElement("span");
|
|
48660
|
+
insert(_el$33, () => segment.text);
|
|
48661
|
+
effect((_$p) => setProp(_el$33, "style", {
|
|
48662
|
+
fg: segment.fg
|
|
48663
|
+
}, _$p));
|
|
48664
|
+
return _el$33;
|
|
48665
|
+
})() : segment.text));
|
|
48666
|
+
return _el$32;
|
|
48667
|
+
})();
|
|
48668
|
+
}));
|
|
48669
|
+
return _el$31;
|
|
48670
|
+
})();
|
|
48671
|
+
})(), null);
|
|
48672
|
+
insert(_el$24, (() => {
|
|
48673
|
+
var _c$4 = memo2(() => !!merged.error);
|
|
48674
|
+
return () => _c$4() ? (() => {
|
|
48675
|
+
var _el$34 = createElement("text");
|
|
48676
|
+
setProp(_el$34, "fg", "red");
|
|
48677
|
+
insert(_el$34, () => merged.error);
|
|
48678
|
+
return _el$34;
|
|
48679
|
+
})() : null;
|
|
48092
48680
|
})(), null);
|
|
48093
|
-
insert(_el$9, error ? (() => {
|
|
48094
|
-
var _el$15 = createElement("text");
|
|
48095
|
-
setProp(_el$15, "fg", "red");
|
|
48096
|
-
insert(_el$15, error);
|
|
48097
|
-
return _el$15;
|
|
48098
|
-
})() : null, null);
|
|
48099
48681
|
insert(_el$, createComponent2(Footer, {
|
|
48100
48682
|
get actions() {
|
|
48101
48683
|
return footerActions();
|
|
48102
48684
|
}
|
|
48103
48685
|
}), null);
|
|
48104
48686
|
effect((_p$) => {
|
|
48105
|
-
var _v$ = terminal().rows, _v$2 = TextAttributes.DIM, _v$3 = TextAttributes.BOLD, _v$4 = TextAttributes.DIM, _v$5 = TextAttributes.BOLD;
|
|
48687
|
+
var _v$ = terminal().rows, _v$2 = TextAttributes.DIM, _v$3 = TextAttributes.BOLD, _v$4 = TextAttributes.DIM, _v$5 = TextAttributes.BOLD, _v$6 = TextAttributes.DIM, _v$7 = TextAttributes.BOLD, _v$8 = TextAttributes.DIM, _v$9 = TextAttributes.BOLD, _v$0 = TextAttributes.DIM, _v$1 = TextAttributes.BOLD, _v$10 = TextAttributes.DIM, _v$11 = TextAttributes.BOLD, _v$12 = TextAttributes.DIM, _v$13 = TextAttributes.BOLD;
|
|
48106
48688
|
_v$ !== _p$.e && (_p$.e = setProp(_el$, "height", _v$, _p$.e));
|
|
48107
48689
|
_v$2 !== _p$.t && (_p$.t = setProp(_el$3, "attributes", _v$2, _p$.t));
|
|
48108
48690
|
_v$3 !== _p$.a && (_p$.a = setProp(_el$5, "attributes", _v$3, _p$.a));
|
|
48109
48691
|
_v$4 !== _p$.o && (_p$.o = setProp(_el$6, "attributes", _v$4, _p$.o));
|
|
48110
48692
|
_v$5 !== _p$.i && (_p$.i = setProp(_el$8, "attributes", _v$5, _p$.i));
|
|
48693
|
+
_v$6 !== _p$.n && (_p$.n = setProp(_el$0, "attributes", _v$6, _p$.n));
|
|
48694
|
+
_v$7 !== _p$.s && (_p$.s = setProp(_el$10, "attributes", _v$7, _p$.s));
|
|
48695
|
+
_v$8 !== _p$.h && (_p$.h = setProp(_el$11, "attributes", _v$8, _p$.h));
|
|
48696
|
+
_v$9 !== _p$.r && (_p$.r = setProp(_el$13, "attributes", _v$9, _p$.r));
|
|
48697
|
+
_v$0 !== _p$.d && (_p$.d = setProp(_el$14, "attributes", _v$0, _p$.d));
|
|
48698
|
+
_v$1 !== _p$.l && (_p$.l = setProp(_el$16, "attributes", _v$1, _p$.l));
|
|
48699
|
+
_v$10 !== _p$.u && (_p$.u = setProp(_el$17, "attributes", _v$10, _p$.u));
|
|
48700
|
+
_v$11 !== _p$.c && (_p$.c = setProp(_el$19, "attributes", _v$11, _p$.c));
|
|
48701
|
+
_v$12 !== _p$.w && (_p$.w = setProp(_el$21, "attributes", _v$12, _p$.w));
|
|
48702
|
+
_v$13 !== _p$.m && (_p$.m = setProp(_el$23, "attributes", _v$13, _p$.m));
|
|
48111
48703
|
return _p$;
|
|
48112
48704
|
}, {
|
|
48113
48705
|
e: undefined,
|
|
48114
48706
|
t: undefined,
|
|
48115
48707
|
a: undefined,
|
|
48116
48708
|
o: undefined,
|
|
48117
|
-
i: undefined
|
|
48709
|
+
i: undefined,
|
|
48710
|
+
n: undefined,
|
|
48711
|
+
s: undefined,
|
|
48712
|
+
h: undefined,
|
|
48713
|
+
r: undefined,
|
|
48714
|
+
d: undefined,
|
|
48715
|
+
l: undefined,
|
|
48716
|
+
u: undefined,
|
|
48717
|
+
c: undefined,
|
|
48718
|
+
w: undefined,
|
|
48719
|
+
m: undefined
|
|
48118
48720
|
});
|
|
48119
48721
|
return _el$;
|
|
48120
48722
|
})();
|
|
@@ -48473,9 +49075,16 @@ function ConfirmScreen({
|
|
|
48473
49075
|
yesLabel = "Yes",
|
|
48474
49076
|
noLabel = "No",
|
|
48475
49077
|
defaultNo = false,
|
|
48476
|
-
helpVisible = false
|
|
49078
|
+
helpVisible = false,
|
|
49079
|
+
width
|
|
48477
49080
|
}) {
|
|
48478
49081
|
const [selectedIndex, setSelectedIndex] = createSignal(defaultNo ? 1 : 0);
|
|
49082
|
+
const terminal = useTerminalSize();
|
|
49083
|
+
const contentWidth = () => Math.max(0, width ?? terminal().columns);
|
|
49084
|
+
const padLine4 = (value, width2) => {
|
|
49085
|
+
const padding = Math.max(0, width2 - stringWidth(value));
|
|
49086
|
+
return padding > 0 ? `${value}${" ".repeat(padding)}` : value;
|
|
49087
|
+
};
|
|
48479
49088
|
const confirm = (confirmed) => {
|
|
48480
49089
|
onConfirm(confirmed);
|
|
48481
49090
|
};
|
|
@@ -48502,25 +49111,34 @@ function ConfirmScreen({
|
|
|
48502
49111
|
confirm(selectedIndex() === 0);
|
|
48503
49112
|
}
|
|
48504
49113
|
});
|
|
48505
|
-
const renderOption = (label, isSelected) => (() => {
|
|
49114
|
+
const renderOption = (label, isSelected) => isSelected ? (() => {
|
|
48506
49115
|
var _el$ = createElement("text");
|
|
48507
|
-
|
|
48508
|
-
|
|
48509
|
-
|
|
48510
|
-
|
|
48511
|
-
|
|
49116
|
+
insert(_el$, () => padLine4(label, contentWidth()));
|
|
49117
|
+
effect((_p$) => {
|
|
49118
|
+
var _v$ = selectionStyle.fg, _v$2 = selectionStyle.bg;
|
|
49119
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$, "fg", _v$, _p$.e));
|
|
49120
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$, "bg", _v$2, _p$.t));
|
|
49121
|
+
return _p$;
|
|
49122
|
+
}, {
|
|
49123
|
+
e: undefined,
|
|
49124
|
+
t: undefined
|
|
49125
|
+
});
|
|
48512
49126
|
return _el$;
|
|
49127
|
+
})() : (() => {
|
|
49128
|
+
var _el$2 = createElement("text");
|
|
49129
|
+
insert(_el$2, label);
|
|
49130
|
+
return _el$2;
|
|
48513
49131
|
})();
|
|
48514
49132
|
return (() => {
|
|
48515
|
-
var _el$
|
|
48516
|
-
insertNode(_el$
|
|
48517
|
-
insertNode(_el$
|
|
48518
|
-
setProp(_el$
|
|
48519
|
-
insert(_el$
|
|
48520
|
-
setProp(_el$
|
|
48521
|
-
insert(_el$
|
|
48522
|
-
insert(_el$
|
|
48523
|
-
return _el$
|
|
49133
|
+
var _el$3 = createElement("box"), _el$4 = createElement("text"), _el$5 = createElement("box");
|
|
49134
|
+
insertNode(_el$3, _el$4);
|
|
49135
|
+
insertNode(_el$3, _el$5);
|
|
49136
|
+
setProp(_el$3, "flexDirection", "column");
|
|
49137
|
+
insert(_el$4, message);
|
|
49138
|
+
setProp(_el$5, "flexDirection", "column");
|
|
49139
|
+
insert(_el$5, () => renderOption(yesLabel, selectedIndex() === 0), null);
|
|
49140
|
+
insert(_el$5, () => renderOption(noLabel, selectedIndex() === 1), null);
|
|
49141
|
+
return _el$3;
|
|
48524
49142
|
})();
|
|
48525
49143
|
}
|
|
48526
49144
|
|
|
@@ -48535,6 +49153,10 @@ function EnvironmentScreen({
|
|
|
48535
49153
|
helpVisible = false
|
|
48536
49154
|
}) {
|
|
48537
49155
|
const terminal = useTerminalSize();
|
|
49156
|
+
const padLine4 = (value, width) => {
|
|
49157
|
+
const padding = Math.max(0, width - stringWidth(value));
|
|
49158
|
+
return padding > 0 ? `${value}${" ".repeat(padding)}` : value;
|
|
49159
|
+
};
|
|
48538
49160
|
const listHeight = createMemo(() => {
|
|
48539
49161
|
const headerRows = 2;
|
|
48540
49162
|
const footerRows = 1;
|
|
@@ -48630,27 +49252,36 @@ function EnvironmentScreen({
|
|
|
48630
49252
|
const absoluteIndex = list.scrollOffset() + index;
|
|
48631
49253
|
const isSelected = absoluteIndex === list.selectedIndex();
|
|
48632
49254
|
const isHighlighted = highlightSet().has(variable.key);
|
|
48633
|
-
const
|
|
48634
|
-
const keyColor = isSelected ? "cyan" : isHighlighted ? "yellow" : undefined;
|
|
48635
|
-
const valueColor = isSelected ? "cyan" : undefined;
|
|
49255
|
+
const keyColor = isHighlighted ? "yellow" : undefined;
|
|
48636
49256
|
return (() => {
|
|
48637
|
-
var _el$6 = createElement("box")
|
|
48638
|
-
insertNode(_el$6, _el$7);
|
|
48639
|
-
insertNode(_el$6, _el$8);
|
|
49257
|
+
var _el$6 = createElement("box");
|
|
48640
49258
|
setProp(_el$6, "flexDirection", "row");
|
|
48641
|
-
|
|
48642
|
-
|
|
48643
|
-
|
|
48644
|
-
|
|
48645
|
-
|
|
48646
|
-
|
|
48647
|
-
|
|
48648
|
-
|
|
48649
|
-
|
|
48650
|
-
|
|
48651
|
-
|
|
48652
|
-
|
|
48653
|
-
|
|
49259
|
+
insert(_el$6, isSelected ? (() => {
|
|
49260
|
+
var _el$7 = createElement("text");
|
|
49261
|
+
insert(_el$7, () => padLine4(`${variable.key}=${variable.value}`, terminal().columns));
|
|
49262
|
+
effect((_p$) => {
|
|
49263
|
+
var _v$ = selectionStyle.fg, _v$2 = selectionStyle.bg;
|
|
49264
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$7, "fg", _v$, _p$.e));
|
|
49265
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$7, "bg", _v$2, _p$.t));
|
|
49266
|
+
return _p$;
|
|
49267
|
+
}, {
|
|
49268
|
+
e: undefined,
|
|
49269
|
+
t: undefined
|
|
49270
|
+
});
|
|
49271
|
+
return _el$7;
|
|
49272
|
+
})() : [(() => {
|
|
49273
|
+
var _el$8 = createElement("text");
|
|
49274
|
+
spread(_el$8, keyColor ? {
|
|
49275
|
+
fg: keyColor
|
|
49276
|
+
} : {}, true);
|
|
49277
|
+
insert(_el$8, () => variable.key);
|
|
49278
|
+
return _el$8;
|
|
49279
|
+
})(), (() => {
|
|
49280
|
+
var _el$9 = createElement("text"), _el$0 = createTextNode(`=`);
|
|
49281
|
+
insertNode(_el$9, _el$0);
|
|
49282
|
+
insert(_el$9, () => variable.value, null);
|
|
49283
|
+
return _el$9;
|
|
49284
|
+
})()]);
|
|
48654
49285
|
return _el$6;
|
|
48655
49286
|
})();
|
|
48656
49287
|
}));
|
|
@@ -48752,6 +49383,10 @@ function ProfileEnvScreen({
|
|
|
48752
49383
|
helpVisible = false
|
|
48753
49384
|
}) {
|
|
48754
49385
|
const terminal = useTerminalSize();
|
|
49386
|
+
const padLine4 = (value, width) => {
|
|
49387
|
+
const padding = Math.max(0, width - stringWidth(value));
|
|
49388
|
+
return padding > 0 ? `${value}${" ".repeat(padding)}` : value;
|
|
49389
|
+
};
|
|
48755
49390
|
const listHeight = createMemo(() => {
|
|
48756
49391
|
const headerRows = 2;
|
|
48757
49392
|
const footerRows = 1;
|
|
@@ -48882,26 +49517,32 @@ function ProfileEnvScreen({
|
|
|
48882
49517
|
insert(_el$5, () => list.visibleItems().map((variable, index) => {
|
|
48883
49518
|
const absoluteIndex = list.scrollOffset() + index;
|
|
48884
49519
|
const isSelected = absoluteIndex === list.selectedIndex();
|
|
48885
|
-
const attributes = isSelected ? TextAttributes.BOLD : undefined;
|
|
48886
|
-
const color = isSelected ? "cyan" : undefined;
|
|
48887
49520
|
return (() => {
|
|
48888
|
-
var _el$6 = createElement("box")
|
|
48889
|
-
insertNode(_el$6, _el$7);
|
|
48890
|
-
insertNode(_el$6, _el$8);
|
|
49521
|
+
var _el$6 = createElement("box");
|
|
48891
49522
|
setProp(_el$6, "flexDirection", "row");
|
|
48892
|
-
|
|
48893
|
-
|
|
48894
|
-
|
|
48895
|
-
|
|
48896
|
-
|
|
48897
|
-
|
|
48898
|
-
|
|
48899
|
-
|
|
48900
|
-
|
|
48901
|
-
|
|
48902
|
-
|
|
48903
|
-
|
|
48904
|
-
|
|
49523
|
+
insert(_el$6, isSelected ? (() => {
|
|
49524
|
+
var _el$7 = createElement("text");
|
|
49525
|
+
insert(_el$7, () => padLine4(`${variable.key}=${variable.value}`, terminal().columns));
|
|
49526
|
+
effect((_p$) => {
|
|
49527
|
+
var _v$ = selectionStyle.fg, _v$2 = selectionStyle.bg;
|
|
49528
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$7, "fg", _v$, _p$.e));
|
|
49529
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$7, "bg", _v$2, _p$.t));
|
|
49530
|
+
return _p$;
|
|
49531
|
+
}, {
|
|
49532
|
+
e: undefined,
|
|
49533
|
+
t: undefined
|
|
49534
|
+
});
|
|
49535
|
+
return _el$7;
|
|
49536
|
+
})() : [(() => {
|
|
49537
|
+
var _el$8 = createElement("text");
|
|
49538
|
+
insert(_el$8, () => variable.key);
|
|
49539
|
+
return _el$8;
|
|
49540
|
+
})(), (() => {
|
|
49541
|
+
var _el$9 = createElement("text"), _el$0 = createTextNode(`=`);
|
|
49542
|
+
insertNode(_el$9, _el$0);
|
|
49543
|
+
insert(_el$9, () => variable.value, null);
|
|
49544
|
+
return _el$9;
|
|
49545
|
+
})()]);
|
|
48905
49546
|
return _el$6;
|
|
48906
49547
|
})();
|
|
48907
49548
|
}));
|
|
@@ -49000,7 +49641,8 @@ function createLogger(config = {}) {
|
|
|
49000
49641
|
if (config.sync) {
|
|
49001
49642
|
const destinationStream2 = import_pino.default.destination({
|
|
49002
49643
|
dest: destination,
|
|
49003
|
-
sync: true
|
|
49644
|
+
sync: true,
|
|
49645
|
+
append: true
|
|
49004
49646
|
});
|
|
49005
49647
|
return import_pino.default(options, destinationStream2);
|
|
49006
49648
|
}
|
|
@@ -49024,7 +49666,8 @@ function createLogger(config = {}) {
|
|
|
49024
49666
|
}
|
|
49025
49667
|
const destinationStream = import_pino.default.destination({
|
|
49026
49668
|
dest: destination,
|
|
49027
|
-
sync: false
|
|
49669
|
+
sync: false,
|
|
49670
|
+
append: true
|
|
49028
49671
|
});
|
|
49029
49672
|
return import_pino.default(options, destinationStream);
|
|
49030
49673
|
}
|
|
@@ -49819,6 +50462,9 @@ async function listWorktrees() {
|
|
|
49819
50462
|
throw new WorktreeError("Failed to list worktrees", error);
|
|
49820
50463
|
}
|
|
49821
50464
|
}
|
|
50465
|
+
async function listAllWorktrees() {
|
|
50466
|
+
return listWorktrees();
|
|
50467
|
+
}
|
|
49822
50468
|
async function listAdditionalWorktrees() {
|
|
49823
50469
|
try {
|
|
49824
50470
|
const [allWorktrees, repoRoot] = await Promise.all([
|
|
@@ -49962,7 +50608,8 @@ async function getWorktreesWithPRStatus() {
|
|
|
49962
50608
|
}
|
|
49963
50609
|
async function getOrphanedLocalBranchStatuses({
|
|
49964
50610
|
baseBranch,
|
|
49965
|
-
repoRoot
|
|
50611
|
+
repoRoot,
|
|
50612
|
+
onProgress
|
|
49966
50613
|
}) {
|
|
49967
50614
|
try {
|
|
49968
50615
|
const [localBranches, worktrees] = await Promise.all([
|
|
@@ -49991,8 +50638,7 @@ async function getOrphanedLocalBranchStatuses({
|
|
|
49991
50638
|
hasUnpushed = true;
|
|
49992
50639
|
}
|
|
49993
50640
|
const { upstream, hasUpstream } = await resolveUpstreamStatus(localBranch.name, repoRoot);
|
|
49994
|
-
const
|
|
49995
|
-
const hasUniqueCommits = await branchHasUniqueCommitsComparedToBase(localBranch.name, comparisonBase, repoRoot);
|
|
50641
|
+
const hasUniqueCommits = await branchHasUniqueCommitsComparedToBase(localBranch.name, baseBranch, repoRoot);
|
|
49996
50642
|
const reasons = buildCleanupReasons({
|
|
49997
50643
|
hasUniqueCommits,
|
|
49998
50644
|
hasUncommitted: false,
|
|
@@ -50002,7 +50648,7 @@ async function getOrphanedLocalBranchStatuses({
|
|
|
50002
50648
|
if (process.env.DEBUG_CLEANUP) {
|
|
50003
50649
|
console.log(source_default.gray(`Debug: Checking orphaned branch ${localBranch.name} -> reasons: ${reasons.join(", ")}`));
|
|
50004
50650
|
}
|
|
50005
|
-
|
|
50651
|
+
const status = {
|
|
50006
50652
|
worktreePath: null,
|
|
50007
50653
|
branch: localBranch.name,
|
|
50008
50654
|
hasUncommittedChanges: false,
|
|
@@ -50013,7 +50659,9 @@ async function getOrphanedLocalBranchStatuses({
|
|
|
50013
50659
|
hasUpstream,
|
|
50014
50660
|
upstream,
|
|
50015
50661
|
reasons
|
|
50016
|
-
}
|
|
50662
|
+
};
|
|
50663
|
+
statuses.push(status);
|
|
50664
|
+
onProgress?.(status);
|
|
50017
50665
|
}
|
|
50018
50666
|
}
|
|
50019
50667
|
if (process.env.DEBUG_CLEANUP) {
|
|
@@ -50028,7 +50676,9 @@ async function getOrphanedLocalBranchStatuses({
|
|
|
50028
50676
|
return [];
|
|
50029
50677
|
}
|
|
50030
50678
|
}
|
|
50031
|
-
async function getCleanupStatus(
|
|
50679
|
+
async function getCleanupStatus({
|
|
50680
|
+
onProgress
|
|
50681
|
+
} = {}) {
|
|
50032
50682
|
const [config, repoRoot, worktreesWithPR] = await Promise.all([
|
|
50033
50683
|
getConfig(),
|
|
50034
50684
|
getRepositoryRoot(),
|
|
@@ -50037,7 +50687,8 @@ async function getCleanupStatus() {
|
|
|
50037
50687
|
const baseBranch = config.defaultBaseBranch || GIT_CONFIG.DEFAULT_BASE_BRANCH;
|
|
50038
50688
|
const orphanedStatuses = await getOrphanedLocalBranchStatuses({
|
|
50039
50689
|
baseBranch,
|
|
50040
|
-
repoRoot
|
|
50690
|
+
repoRoot,
|
|
50691
|
+
...onProgress ? { onProgress } : {}
|
|
50041
50692
|
});
|
|
50042
50693
|
const statuses = [];
|
|
50043
50694
|
if (process.env.DEBUG_CLEANUP) {
|
|
@@ -50066,8 +50717,7 @@ async function getCleanupStatus() {
|
|
|
50066
50717
|
}
|
|
50067
50718
|
}
|
|
50068
50719
|
const { upstream, hasUpstream } = await resolveUpstreamStatus(worktree.branch, repoRoot);
|
|
50069
|
-
const
|
|
50070
|
-
const hasUniqueCommits = await branchHasUniqueCommitsComparedToBase(worktree.branch, comparisonBase, repoRoot);
|
|
50720
|
+
const hasUniqueCommits = await branchHasUniqueCommitsComparedToBase(worktree.branch, baseBranch, repoRoot);
|
|
50071
50721
|
const reasons = buildCleanupReasons({
|
|
50072
50722
|
hasUniqueCommits,
|
|
50073
50723
|
hasUncommitted,
|
|
@@ -50077,7 +50727,7 @@ async function getCleanupStatus() {
|
|
|
50077
50727
|
if (process.env.DEBUG_CLEANUP) {
|
|
50078
50728
|
console.log(source_default.gray(`Debug: Cleanup reasons for ${worktree.branch}: ${reasons.length > 0 ? reasons.join(", ") : "none"}`));
|
|
50079
50729
|
}
|
|
50080
|
-
|
|
50730
|
+
const status = {
|
|
50081
50731
|
worktreePath: worktree.worktreePath,
|
|
50082
50732
|
branch: worktree.branch,
|
|
50083
50733
|
hasUncommittedChanges: hasUncommitted,
|
|
@@ -50090,7 +50740,9 @@ async function getCleanupStatus() {
|
|
|
50090
50740
|
isAccessible,
|
|
50091
50741
|
reasons,
|
|
50092
50742
|
...isAccessible ? {} : { invalidReason: "Path not accessible in current environment" }
|
|
50093
|
-
}
|
|
50743
|
+
};
|
|
50744
|
+
statuses.push(status);
|
|
50745
|
+
onProgress?.(status);
|
|
50094
50746
|
}
|
|
50095
50747
|
statuses.push(...orphanedStatuses);
|
|
50096
50748
|
if (process.env.DEBUG_CLEANUP) {
|
|
@@ -50101,22 +50753,643 @@ async function getCleanupStatus() {
|
|
|
50101
50753
|
return statuses;
|
|
50102
50754
|
}
|
|
50103
50755
|
|
|
50104
|
-
// src/
|
|
50105
|
-
import
|
|
50756
|
+
// src/utils/session/common.ts
|
|
50757
|
+
import path14 from "path";
|
|
50758
|
+
import { readdir, readFile as readFile2, stat } from "fs/promises";
|
|
50759
|
+
var UUID_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
|
|
50760
|
+
function isValidUuidSessionId(id) {
|
|
50761
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
|
|
50762
|
+
}
|
|
50763
|
+
function pickSessionIdFromObject(obj) {
|
|
50764
|
+
if (!obj || typeof obj !== "object")
|
|
50765
|
+
return null;
|
|
50766
|
+
const candidate = obj;
|
|
50767
|
+
const keys = ["sessionId", "session_id", "id", "conversation_id"];
|
|
50768
|
+
for (const key of keys) {
|
|
50769
|
+
const value = candidate[key];
|
|
50770
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
50771
|
+
const trimmed = value.trim();
|
|
50772
|
+
if (isValidUuidSessionId(trimmed)) {
|
|
50773
|
+
return trimmed;
|
|
50774
|
+
}
|
|
50775
|
+
}
|
|
50776
|
+
}
|
|
50777
|
+
return null;
|
|
50778
|
+
}
|
|
50779
|
+
function pickCwdFromObject(obj) {
|
|
50780
|
+
if (!obj || typeof obj !== "object")
|
|
50781
|
+
return null;
|
|
50782
|
+
const candidate = obj;
|
|
50783
|
+
const keys = [
|
|
50784
|
+
"cwd",
|
|
50785
|
+
"workingDirectory",
|
|
50786
|
+
"workdir",
|
|
50787
|
+
"directory",
|
|
50788
|
+
"projectPath"
|
|
50789
|
+
];
|
|
50790
|
+
for (const key of keys) {
|
|
50791
|
+
const value = candidate[key];
|
|
50792
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
50793
|
+
return value;
|
|
50794
|
+
}
|
|
50795
|
+
}
|
|
50796
|
+
const payload = candidate["payload"];
|
|
50797
|
+
if (payload && typeof payload === "object") {
|
|
50798
|
+
const nested = pickCwdFromObject(payload);
|
|
50799
|
+
if (nested)
|
|
50800
|
+
return nested;
|
|
50801
|
+
}
|
|
50802
|
+
return null;
|
|
50803
|
+
}
|
|
50804
|
+
function pickSessionIdFromText(content) {
|
|
50805
|
+
try {
|
|
50806
|
+
const parsed = JSON.parse(content);
|
|
50807
|
+
const fromObject = pickSessionIdFromObject(parsed);
|
|
50808
|
+
if (fromObject)
|
|
50809
|
+
return fromObject;
|
|
50810
|
+
} catch {}
|
|
50811
|
+
const lines = content.split(/\r?\n/);
|
|
50812
|
+
for (const line of lines) {
|
|
50813
|
+
const trimmed = line.trim();
|
|
50814
|
+
if (!trimmed)
|
|
50815
|
+
continue;
|
|
50816
|
+
try {
|
|
50817
|
+
const parsedLine = JSON.parse(trimmed);
|
|
50818
|
+
const fromLine = pickSessionIdFromObject(parsedLine);
|
|
50819
|
+
if (fromLine)
|
|
50820
|
+
return fromLine;
|
|
50821
|
+
} catch {}
|
|
50822
|
+
const match2 = trimmed.match(UUID_REGEX);
|
|
50823
|
+
if (match2)
|
|
50824
|
+
return match2[0];
|
|
50825
|
+
}
|
|
50826
|
+
const match = content.match(UUID_REGEX);
|
|
50827
|
+
return match ? match[0] : null;
|
|
50828
|
+
}
|
|
50829
|
+
async function collectFilesIterative(dir, filter) {
|
|
50830
|
+
const results = [];
|
|
50831
|
+
const queue = [dir];
|
|
50832
|
+
while (queue.length > 0) {
|
|
50833
|
+
const currentDir = queue.shift();
|
|
50834
|
+
if (!currentDir)
|
|
50835
|
+
break;
|
|
50836
|
+
try {
|
|
50837
|
+
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
50838
|
+
for (const entry of entries) {
|
|
50839
|
+
const fullPath = path14.join(currentDir, entry.name);
|
|
50840
|
+
if (entry.isDirectory()) {
|
|
50841
|
+
queue.push(fullPath);
|
|
50842
|
+
} else if (entry.isFile() && filter(entry.name)) {
|
|
50843
|
+
try {
|
|
50844
|
+
const info = await stat(fullPath);
|
|
50845
|
+
results.push({ fullPath, mtime: info.mtimeMs });
|
|
50846
|
+
} catch {}
|
|
50847
|
+
}
|
|
50848
|
+
}
|
|
50849
|
+
} catch {}
|
|
50850
|
+
}
|
|
50851
|
+
return results;
|
|
50852
|
+
}
|
|
50853
|
+
async function readSessionIdFromFile(filePath) {
|
|
50854
|
+
try {
|
|
50855
|
+
const basename2 = path14.basename(filePath);
|
|
50856
|
+
const filenameWithoutExt = basename2.replace(/\.(json|jsonl)$/i, "");
|
|
50857
|
+
if (isValidUuidSessionId(filenameWithoutExt)) {
|
|
50858
|
+
return filenameWithoutExt;
|
|
50859
|
+
}
|
|
50860
|
+
const content = await readFile2(filePath, "utf-8");
|
|
50861
|
+
const fromContent = pickSessionIdFromText(content);
|
|
50862
|
+
if (fromContent)
|
|
50863
|
+
return fromContent;
|
|
50864
|
+
const filenameMatch = basename2.match(UUID_REGEX);
|
|
50865
|
+
return filenameMatch ? filenameMatch[0] : null;
|
|
50866
|
+
} catch {
|
|
50867
|
+
return null;
|
|
50868
|
+
}
|
|
50869
|
+
}
|
|
50870
|
+
async function readSessionInfoFromFile(filePath) {
|
|
50871
|
+
try {
|
|
50872
|
+
const content = await readFile2(filePath, "utf-8");
|
|
50873
|
+
try {
|
|
50874
|
+
const parsed = JSON.parse(content);
|
|
50875
|
+
const id = pickSessionIdFromObject(parsed);
|
|
50876
|
+
const cwd = pickCwdFromObject(parsed);
|
|
50877
|
+
if (id || cwd)
|
|
50878
|
+
return { id, cwd };
|
|
50879
|
+
} catch {}
|
|
50880
|
+
const lines = content.split(/\r?\n/);
|
|
50881
|
+
for (const line of lines) {
|
|
50882
|
+
const trimmed = line.trim();
|
|
50883
|
+
if (!trimmed)
|
|
50884
|
+
continue;
|
|
50885
|
+
try {
|
|
50886
|
+
const parsedLine = JSON.parse(trimmed);
|
|
50887
|
+
const id = pickSessionIdFromObject(parsedLine);
|
|
50888
|
+
const cwd = pickCwdFromObject(parsedLine);
|
|
50889
|
+
if (id || cwd)
|
|
50890
|
+
return { id, cwd };
|
|
50891
|
+
} catch {}
|
|
50892
|
+
}
|
|
50893
|
+
const filenameMatch = path14.basename(filePath).match(UUID_REGEX);
|
|
50894
|
+
if (filenameMatch)
|
|
50895
|
+
return { id: filenameMatch[0], cwd: null };
|
|
50896
|
+
} catch {}
|
|
50897
|
+
return { id: null, cwd: null };
|
|
50898
|
+
}
|
|
50899
|
+
async function findNewestSessionIdFromDir(dir, recursive, options = {}) {
|
|
50900
|
+
try {
|
|
50901
|
+
const files = [];
|
|
50902
|
+
const queue = [dir];
|
|
50903
|
+
while (queue.length > 0) {
|
|
50904
|
+
const currentDir = queue.shift();
|
|
50905
|
+
if (!currentDir)
|
|
50906
|
+
break;
|
|
50907
|
+
try {
|
|
50908
|
+
const entries = await readdir(currentDir, { withFileTypes: true });
|
|
50909
|
+
for (const entry of entries) {
|
|
50910
|
+
const fullPath = path14.join(currentDir, entry.name);
|
|
50911
|
+
if (entry.isDirectory()) {
|
|
50912
|
+
if (recursive) {
|
|
50913
|
+
queue.push(fullPath);
|
|
50914
|
+
}
|
|
50915
|
+
continue;
|
|
50916
|
+
}
|
|
50917
|
+
if (!entry.isFile())
|
|
50918
|
+
continue;
|
|
50919
|
+
if (!entry.name.endsWith(".json") && !entry.name.endsWith(".jsonl"))
|
|
50920
|
+
continue;
|
|
50921
|
+
try {
|
|
50922
|
+
const info = await stat(fullPath);
|
|
50923
|
+
files.push({ fullPath, mtime: info.mtimeMs });
|
|
50924
|
+
} catch {}
|
|
50925
|
+
}
|
|
50926
|
+
} catch {}
|
|
50927
|
+
}
|
|
50928
|
+
const filtered = files.filter((f) => {
|
|
50929
|
+
if (options.since !== undefined && f.mtime < options.since)
|
|
50930
|
+
return false;
|
|
50931
|
+
if (options.until !== undefined && f.mtime > options.until)
|
|
50932
|
+
return false;
|
|
50933
|
+
return true;
|
|
50934
|
+
});
|
|
50935
|
+
if (!filtered.length)
|
|
50936
|
+
return null;
|
|
50937
|
+
let pool = filtered.sort((a2, b) => b.mtime - a2.mtime);
|
|
50938
|
+
const ref = options.preferClosestTo;
|
|
50939
|
+
if (typeof ref === "number") {
|
|
50940
|
+
const window = options.windowMs ?? 30 * 60 * 1000;
|
|
50941
|
+
const withinWindow = pool.filter((f) => Math.abs(f.mtime - ref) <= window);
|
|
50942
|
+
if (withinWindow.length) {
|
|
50943
|
+
pool = withinWindow.sort((a2, b) => b.mtime - a2.mtime);
|
|
50944
|
+
}
|
|
50945
|
+
}
|
|
50946
|
+
for (const file of pool) {
|
|
50947
|
+
const id = await readSessionIdFromFile(file.fullPath);
|
|
50948
|
+
if (id)
|
|
50949
|
+
return { id, mtime: file.mtime };
|
|
50950
|
+
}
|
|
50951
|
+
} catch {}
|
|
50952
|
+
return null;
|
|
50953
|
+
}
|
|
50954
|
+
async function readFileContent(filePath) {
|
|
50955
|
+
return readFile2(filePath, "utf-8");
|
|
50956
|
+
}
|
|
50957
|
+
async function checkFileStat(filePath) {
|
|
50958
|
+
try {
|
|
50959
|
+
const info = await stat(filePath);
|
|
50960
|
+
return { mtimeMs: info.mtimeMs };
|
|
50961
|
+
} catch {
|
|
50962
|
+
return null;
|
|
50963
|
+
}
|
|
50964
|
+
}
|
|
50965
|
+
function normalizePath(p) {
|
|
50966
|
+
return path14.normalize(p).replace(/\\/g, "/");
|
|
50967
|
+
}
|
|
50968
|
+
function isPathPrefix(prefix, full) {
|
|
50969
|
+
if (!full.startsWith(prefix))
|
|
50970
|
+
return false;
|
|
50971
|
+
if (full.length === prefix.length)
|
|
50972
|
+
return true;
|
|
50973
|
+
return full[prefix.length] === "/";
|
|
50974
|
+
}
|
|
50975
|
+
function matchesCwd(sessionCwd, targetCwd) {
|
|
50976
|
+
if (!sessionCwd)
|
|
50977
|
+
return false;
|
|
50978
|
+
const normalizedSession = normalizePath(sessionCwd);
|
|
50979
|
+
const normalizedTarget = normalizePath(targetCwd);
|
|
50980
|
+
return normalizedSession === normalizedTarget || isPathPrefix(normalizedTarget, normalizedSession) || isPathPrefix(normalizedSession, normalizedTarget);
|
|
50981
|
+
}
|
|
50982
|
+
function resolveBranchFromCwd(sessionCwd, worktrees) {
|
|
50983
|
+
if (!sessionCwd)
|
|
50984
|
+
return null;
|
|
50985
|
+
const normalizedSession = normalizePath(sessionCwd);
|
|
50986
|
+
let bestMatch = null;
|
|
50987
|
+
for (const worktree of worktrees) {
|
|
50988
|
+
if (!worktree?.path || !worktree.branch)
|
|
50989
|
+
continue;
|
|
50990
|
+
const normalizedPath = normalizePath(worktree.path);
|
|
50991
|
+
if (normalizedSession === normalizedPath || isPathPrefix(normalizedPath, normalizedSession)) {
|
|
50992
|
+
if (!bestMatch || normalizedPath.length > bestMatch.path.length) {
|
|
50993
|
+
bestMatch = { branch: worktree.branch, path: normalizedPath };
|
|
50994
|
+
}
|
|
50995
|
+
}
|
|
50996
|
+
}
|
|
50997
|
+
return bestMatch?.branch ?? null;
|
|
50998
|
+
}
|
|
50999
|
+
// src/utils/session/parsers/claude.ts
|
|
50106
51000
|
import path15 from "path";
|
|
50107
|
-
import {
|
|
51001
|
+
import { homedir as homedir3 } from "os";
|
|
51002
|
+
function encodeClaudeProjectPath(cwd) {
|
|
51003
|
+
const normalized = cwd.replace(/\\/g, "/").replace(/:/g, "");
|
|
51004
|
+
return normalized.replace(/_/g, "-").replace(/\//g, "-");
|
|
51005
|
+
}
|
|
51006
|
+
function generateClaudeProjectPathCandidates(cwd) {
|
|
51007
|
+
const base2 = encodeClaudeProjectPath(cwd);
|
|
51008
|
+
const dotToDash = cwd.replace(/\\/g, "/").replace(/:/g, "").replace(/\./g, "-").replace(/_/g, "-").replace(/\//g, "-");
|
|
51009
|
+
const collapsed = dotToDash.replace(/-+/g, "-");
|
|
51010
|
+
const candidates = [base2, dotToDash, collapsed];
|
|
51011
|
+
return Array.from(new Set(candidates));
|
|
51012
|
+
}
|
|
51013
|
+
function getClaudeRootCandidates() {
|
|
51014
|
+
const roots = [];
|
|
51015
|
+
if (process.env.CLAUDE_CONFIG_DIR) {
|
|
51016
|
+
roots.push(process.env.CLAUDE_CONFIG_DIR);
|
|
51017
|
+
}
|
|
51018
|
+
roots.push(path15.join(homedir3(), ".claude"), path15.join(homedir3(), ".config", "claude"));
|
|
51019
|
+
return roots;
|
|
51020
|
+
}
|
|
51021
|
+
async function findLatestClaudeSession(cwd, options = {}) {
|
|
51022
|
+
const rootCandidates = getClaudeRootCandidates();
|
|
51023
|
+
const branchFilter = typeof options.branch === "string" && options.branch.trim().length > 0 ? options.branch.trim() : null;
|
|
51024
|
+
let cwdCandidates = [];
|
|
51025
|
+
if (branchFilter) {
|
|
51026
|
+
let worktrees = [];
|
|
51027
|
+
if (Array.isArray(options.worktrees) && options.worktrees.length > 0) {
|
|
51028
|
+
worktrees = options.worktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51029
|
+
} else {
|
|
51030
|
+
try {
|
|
51031
|
+
const allWorktrees = await listAllWorktrees();
|
|
51032
|
+
worktrees = allWorktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51033
|
+
} catch {
|
|
51034
|
+
worktrees = [];
|
|
51035
|
+
}
|
|
51036
|
+
}
|
|
51037
|
+
const matches = worktrees.filter((entry) => entry.branch === branchFilter).map((entry) => entry.path);
|
|
51038
|
+
if (!matches.length)
|
|
51039
|
+
return null;
|
|
51040
|
+
cwdCandidates = matches;
|
|
51041
|
+
} else {
|
|
51042
|
+
const baseCwd = options.cwd ?? cwd;
|
|
51043
|
+
if (!baseCwd)
|
|
51044
|
+
return null;
|
|
51045
|
+
cwdCandidates = [baseCwd];
|
|
51046
|
+
}
|
|
51047
|
+
const uniqueCwds = Array.from(new Set(cwdCandidates));
|
|
51048
|
+
for (const candidateCwd of uniqueCwds) {
|
|
51049
|
+
const encodedPaths = generateClaudeProjectPathCandidates(candidateCwd);
|
|
51050
|
+
for (const claudeRoot of rootCandidates) {
|
|
51051
|
+
for (const encoded of encodedPaths) {
|
|
51052
|
+
const projectDir = path15.join(claudeRoot, "projects", encoded);
|
|
51053
|
+
const sessionsDir = path15.join(projectDir, "sessions");
|
|
51054
|
+
const session = await findNewestSessionIdFromDir(sessionsDir, false, options);
|
|
51055
|
+
if (session)
|
|
51056
|
+
return session;
|
|
51057
|
+
const rootSession = await findNewestSessionIdFromDir(projectDir, true, options);
|
|
51058
|
+
if (rootSession)
|
|
51059
|
+
return rootSession;
|
|
51060
|
+
}
|
|
51061
|
+
}
|
|
51062
|
+
}
|
|
51063
|
+
try {
|
|
51064
|
+
const historyPath = path15.join(homedir3(), ".claude", "history.jsonl");
|
|
51065
|
+
const historyStat = await checkFileStat(historyPath);
|
|
51066
|
+
if (!historyStat)
|
|
51067
|
+
return null;
|
|
51068
|
+
const content = await readFileContent(historyPath);
|
|
51069
|
+
const lines = content.split(/\r?\n/).filter(Boolean);
|
|
51070
|
+
for (let i2 = lines.length - 1;i2 >= 0; i2 -= 1) {
|
|
51071
|
+
try {
|
|
51072
|
+
const line = lines[i2] ?? "";
|
|
51073
|
+
const parsed = JSON.parse(line);
|
|
51074
|
+
const project = typeof parsed.project === "string" ? parsed.project : null;
|
|
51075
|
+
const sessionId = typeof parsed.sessionId === "string" ? parsed.sessionId : null;
|
|
51076
|
+
const matchesProject = uniqueCwds.some((candidate) => matchesCwd(project, candidate));
|
|
51077
|
+
if (project && sessionId && matchesProject) {
|
|
51078
|
+
return { id: sessionId, mtime: historyStat.mtimeMs };
|
|
51079
|
+
}
|
|
51080
|
+
} catch {}
|
|
51081
|
+
}
|
|
51082
|
+
} catch {}
|
|
51083
|
+
return null;
|
|
51084
|
+
}
|
|
51085
|
+
// src/utils/session/parsers/codex.ts
|
|
51086
|
+
import path16 from "path";
|
|
51087
|
+
import { homedir as homedir4 } from "os";
|
|
51088
|
+
async function findLatestCodexSession(options = {}) {
|
|
51089
|
+
const codexHome = process.env.CODEX_HOME ?? path16.join(homedir4(), ".codex");
|
|
51090
|
+
const baseDir = path16.join(codexHome, "sessions");
|
|
51091
|
+
const candidates = await collectFilesIterative(baseDir, (name) => name.endsWith(".json") || name.endsWith(".jsonl"));
|
|
51092
|
+
if (!candidates.length)
|
|
51093
|
+
return null;
|
|
51094
|
+
let pool = candidates;
|
|
51095
|
+
const sinceVal = options.since;
|
|
51096
|
+
const untilVal = options.until;
|
|
51097
|
+
if (sinceVal !== undefined) {
|
|
51098
|
+
pool = pool.filter((c3) => c3.mtime >= sinceVal);
|
|
51099
|
+
}
|
|
51100
|
+
if (untilVal !== undefined) {
|
|
51101
|
+
pool = pool.filter((c3) => c3.mtime <= untilVal);
|
|
51102
|
+
}
|
|
51103
|
+
if (!pool.length)
|
|
51104
|
+
return null;
|
|
51105
|
+
const ref = options.preferClosestTo;
|
|
51106
|
+
const window = options.windowMs ?? 30 * 60 * 1000;
|
|
51107
|
+
const ordered = [...pool].sort((a2, b) => {
|
|
51108
|
+
if (typeof ref === "number") {
|
|
51109
|
+
const da = Math.abs(a2.mtime - ref);
|
|
51110
|
+
const db = Math.abs(b.mtime - ref);
|
|
51111
|
+
if (da === db)
|
|
51112
|
+
return b.mtime - a2.mtime;
|
|
51113
|
+
if (da <= window || db <= window)
|
|
51114
|
+
return da - db;
|
|
51115
|
+
}
|
|
51116
|
+
return b.mtime - a2.mtime;
|
|
51117
|
+
});
|
|
51118
|
+
const branchFilter = typeof options.branch === "string" && options.branch.trim().length > 0 ? options.branch.trim() : null;
|
|
51119
|
+
const shouldCheckBranch = Boolean(branchFilter);
|
|
51120
|
+
const shouldCheckCwd = Boolean(options.cwd) && !shouldCheckBranch;
|
|
51121
|
+
let worktrees = [];
|
|
51122
|
+
if (shouldCheckBranch) {
|
|
51123
|
+
if (Array.isArray(options.worktrees) && options.worktrees.length > 0) {
|
|
51124
|
+
worktrees = options.worktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51125
|
+
} else {
|
|
51126
|
+
try {
|
|
51127
|
+
const allWorktrees = await listAllWorktrees();
|
|
51128
|
+
worktrees = allWorktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51129
|
+
} catch {
|
|
51130
|
+
worktrees = [];
|
|
51131
|
+
}
|
|
51132
|
+
}
|
|
51133
|
+
if (!worktrees.length)
|
|
51134
|
+
return null;
|
|
51135
|
+
}
|
|
51136
|
+
for (const file of ordered) {
|
|
51137
|
+
const filenameMatch = path16.basename(file.fullPath).match(UUID_REGEX);
|
|
51138
|
+
const idFromName = filenameMatch?.[0] ?? null;
|
|
51139
|
+
const needsInfo = shouldCheckBranch || shouldCheckCwd || !idFromName;
|
|
51140
|
+
const info = needsInfo ? await readSessionInfoFromFile(file.fullPath) : null;
|
|
51141
|
+
const sessionCwd = info?.cwd ?? null;
|
|
51142
|
+
if (shouldCheckBranch) {
|
|
51143
|
+
const resolvedBranch = resolveBranchFromCwd(sessionCwd, worktrees);
|
|
51144
|
+
if (resolvedBranch !== branchFilter) {
|
|
51145
|
+
continue;
|
|
51146
|
+
}
|
|
51147
|
+
}
|
|
51148
|
+
if (shouldCheckCwd && options.cwd) {
|
|
51149
|
+
if (!matchesCwd(sessionCwd, options.cwd)) {
|
|
51150
|
+
continue;
|
|
51151
|
+
}
|
|
51152
|
+
}
|
|
51153
|
+
const sessionId = idFromName ?? info?.id ?? null;
|
|
51154
|
+
if (sessionId) {
|
|
51155
|
+
return { id: sessionId, mtime: file.mtime };
|
|
51156
|
+
}
|
|
51157
|
+
}
|
|
51158
|
+
return null;
|
|
51159
|
+
}
|
|
51160
|
+
// src/utils/session/parsers/gemini.ts
|
|
51161
|
+
import path17 from "path";
|
|
51162
|
+
import { homedir as homedir5 } from "os";
|
|
51163
|
+
async function findLatestGeminiSession(options = {}) {
|
|
51164
|
+
const baseDir = path17.join(homedir5(), ".gemini", "tmp");
|
|
51165
|
+
const files = await collectFilesIterative(baseDir, (name) => name.endsWith(".json") || name.endsWith(".jsonl"));
|
|
51166
|
+
if (!files.length)
|
|
51167
|
+
return null;
|
|
51168
|
+
let pool = files;
|
|
51169
|
+
const sinceVal = options.since;
|
|
51170
|
+
if (sinceVal !== undefined) {
|
|
51171
|
+
pool = pool.filter((f) => f.mtime >= sinceVal);
|
|
51172
|
+
}
|
|
51173
|
+
const untilVal = options.until;
|
|
51174
|
+
if (untilVal !== undefined) {
|
|
51175
|
+
pool = pool.filter((f) => f.mtime <= untilVal);
|
|
51176
|
+
}
|
|
51177
|
+
if (!pool.length)
|
|
51178
|
+
return null;
|
|
51179
|
+
const ref = options.preferClosestTo;
|
|
51180
|
+
const window = options.windowMs ?? 30 * 60 * 1000;
|
|
51181
|
+
pool = pool.slice().sort((a2, b) => {
|
|
51182
|
+
if (typeof ref === "number") {
|
|
51183
|
+
const da = Math.abs(a2.mtime - ref);
|
|
51184
|
+
const db = Math.abs(b.mtime - ref);
|
|
51185
|
+
if (da === db)
|
|
51186
|
+
return b.mtime - a2.mtime;
|
|
51187
|
+
if (da <= window || db <= window)
|
|
51188
|
+
return da - db;
|
|
51189
|
+
}
|
|
51190
|
+
return b.mtime - a2.mtime;
|
|
51191
|
+
});
|
|
51192
|
+
const branchFilter = typeof options.branch === "string" && options.branch.trim().length > 0 ? options.branch.trim() : null;
|
|
51193
|
+
const shouldCheckBranch = Boolean(branchFilter);
|
|
51194
|
+
const shouldCheckCwd = Boolean(options.cwd) && !shouldCheckBranch;
|
|
51195
|
+
let worktrees = [];
|
|
51196
|
+
if (shouldCheckBranch) {
|
|
51197
|
+
if (Array.isArray(options.worktrees) && options.worktrees.length > 0) {
|
|
51198
|
+
worktrees = options.worktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51199
|
+
} else {
|
|
51200
|
+
try {
|
|
51201
|
+
const allWorktrees = await listAllWorktrees();
|
|
51202
|
+
worktrees = allWorktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51203
|
+
} catch {
|
|
51204
|
+
worktrees = [];
|
|
51205
|
+
}
|
|
51206
|
+
}
|
|
51207
|
+
if (!worktrees.length)
|
|
51208
|
+
return null;
|
|
51209
|
+
}
|
|
51210
|
+
for (const file of pool) {
|
|
51211
|
+
const info = await readSessionInfoFromFile(file.fullPath);
|
|
51212
|
+
if (!info.id)
|
|
51213
|
+
continue;
|
|
51214
|
+
const sessionCwd = info.cwd ?? null;
|
|
51215
|
+
if (shouldCheckBranch) {
|
|
51216
|
+
const resolvedBranch = resolveBranchFromCwd(sessionCwd, worktrees);
|
|
51217
|
+
if (resolvedBranch !== branchFilter) {
|
|
51218
|
+
continue;
|
|
51219
|
+
}
|
|
51220
|
+
}
|
|
51221
|
+
if (shouldCheckCwd && options.cwd) {
|
|
51222
|
+
if (!matchesCwd(sessionCwd, options.cwd)) {
|
|
51223
|
+
continue;
|
|
51224
|
+
}
|
|
51225
|
+
}
|
|
51226
|
+
return { id: info.id, mtime: file.mtime };
|
|
51227
|
+
}
|
|
51228
|
+
return null;
|
|
51229
|
+
}
|
|
51230
|
+
// src/utils/session/parsers/opencode.ts
|
|
51231
|
+
import path18 from "path";
|
|
51232
|
+
import { homedir as homedir6 } from "os";
|
|
51233
|
+
function getOpenCodeSessionDir() {
|
|
51234
|
+
return path18.join(homedir6(), ".local", "share", "opencode", "storage", "session");
|
|
51235
|
+
}
|
|
51236
|
+
async function findLatestOpenCodeSession(options = {}) {
|
|
51237
|
+
const baseDir = getOpenCodeSessionDir();
|
|
51238
|
+
const files = await collectFilesIterative(baseDir, (name) => name.endsWith(".json") || name.endsWith(".jsonl"));
|
|
51239
|
+
if (!files.length)
|
|
51240
|
+
return null;
|
|
51241
|
+
let pool = files;
|
|
51242
|
+
const sinceVal = options.since;
|
|
51243
|
+
if (sinceVal !== undefined) {
|
|
51244
|
+
pool = pool.filter((f) => f.mtime >= sinceVal);
|
|
51245
|
+
}
|
|
51246
|
+
const untilVal = options.until;
|
|
51247
|
+
if (untilVal !== undefined) {
|
|
51248
|
+
pool = pool.filter((f) => f.mtime <= untilVal);
|
|
51249
|
+
}
|
|
51250
|
+
if (!pool.length)
|
|
51251
|
+
return null;
|
|
51252
|
+
const ref = options.preferClosestTo;
|
|
51253
|
+
const window = options.windowMs ?? 30 * 60 * 1000;
|
|
51254
|
+
pool = pool.slice().sort((a2, b) => {
|
|
51255
|
+
if (typeof ref === "number") {
|
|
51256
|
+
const da = Math.abs(a2.mtime - ref);
|
|
51257
|
+
const db = Math.abs(b.mtime - ref);
|
|
51258
|
+
if (da === db)
|
|
51259
|
+
return b.mtime - a2.mtime;
|
|
51260
|
+
if (da <= window || db <= window)
|
|
51261
|
+
return da - db;
|
|
51262
|
+
}
|
|
51263
|
+
return b.mtime - a2.mtime;
|
|
51264
|
+
});
|
|
51265
|
+
const branchFilter = typeof options.branch === "string" && options.branch.trim().length > 0 ? options.branch.trim() : null;
|
|
51266
|
+
const shouldCheckBranch = Boolean(branchFilter);
|
|
51267
|
+
const shouldCheckCwd = Boolean(options.cwd) && !shouldCheckBranch;
|
|
51268
|
+
let worktrees = [];
|
|
51269
|
+
if (shouldCheckBranch) {
|
|
51270
|
+
if (Array.isArray(options.worktrees) && options.worktrees.length > 0) {
|
|
51271
|
+
worktrees = options.worktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51272
|
+
} else {
|
|
51273
|
+
try {
|
|
51274
|
+
const allWorktrees = await listAllWorktrees();
|
|
51275
|
+
worktrees = allWorktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51276
|
+
} catch {
|
|
51277
|
+
worktrees = [];
|
|
51278
|
+
}
|
|
51279
|
+
}
|
|
51280
|
+
if (!worktrees.length)
|
|
51281
|
+
return null;
|
|
51282
|
+
}
|
|
51283
|
+
for (const file of pool) {
|
|
51284
|
+
const info = await readSessionInfoFromFile(file.fullPath);
|
|
51285
|
+
if (!info.id)
|
|
51286
|
+
continue;
|
|
51287
|
+
const sessionCwd = info.cwd ?? null;
|
|
51288
|
+
if (shouldCheckBranch) {
|
|
51289
|
+
const resolvedBranch = resolveBranchFromCwd(sessionCwd, worktrees);
|
|
51290
|
+
if (resolvedBranch !== branchFilter) {
|
|
51291
|
+
continue;
|
|
51292
|
+
}
|
|
51293
|
+
}
|
|
51294
|
+
if (shouldCheckCwd && options.cwd) {
|
|
51295
|
+
if (!matchesCwd(sessionCwd, options.cwd)) {
|
|
51296
|
+
continue;
|
|
51297
|
+
}
|
|
51298
|
+
}
|
|
51299
|
+
return { id: info.id, mtime: file.mtime };
|
|
51300
|
+
}
|
|
51301
|
+
return null;
|
|
51302
|
+
}
|
|
51303
|
+
// src/cli/ui/utils/continueSession.ts
|
|
51304
|
+
function findLatestBranchSessionsByTool(history, branch, worktreePath) {
|
|
51305
|
+
const byBranch = history.filter((entry) => entry && entry.branch === branch);
|
|
51306
|
+
if (!byBranch.length)
|
|
51307
|
+
return [];
|
|
51308
|
+
const source = worktreePath ? byBranch.filter((entry) => entry.worktreePath === worktreePath) : byBranch;
|
|
51309
|
+
if (!source.length)
|
|
51310
|
+
return [];
|
|
51311
|
+
const latestByTool = new Map;
|
|
51312
|
+
for (const entry of source) {
|
|
51313
|
+
if (!entry.toolId)
|
|
51314
|
+
continue;
|
|
51315
|
+
const current = latestByTool.get(entry.toolId);
|
|
51316
|
+
const currentTs = current?.timestamp ?? 0;
|
|
51317
|
+
const entryTs = entry.timestamp ?? 0;
|
|
51318
|
+
if (!current || entryTs >= currentTs) {
|
|
51319
|
+
latestByTool.set(entry.toolId, entry);
|
|
51320
|
+
}
|
|
51321
|
+
}
|
|
51322
|
+
return Array.from(latestByTool.values()).sort((a2, b) => (b.timestamp ?? 0) - (a2.timestamp ?? 0));
|
|
51323
|
+
}
|
|
51324
|
+
async function refreshQuickStartEntries(entries, context, lookups = {}) {
|
|
51325
|
+
if (!entries.length)
|
|
51326
|
+
return entries;
|
|
51327
|
+
const worktreePath = context.worktreePath ?? null;
|
|
51328
|
+
if (!worktreePath)
|
|
51329
|
+
return entries;
|
|
51330
|
+
const lookupWorktrees = lookups.listAllWorktrees ?? listAllWorktrees;
|
|
51331
|
+
let resolvedWorktrees = null;
|
|
51332
|
+
try {
|
|
51333
|
+
const allWorktrees = await lookupWorktrees();
|
|
51334
|
+
resolvedWorktrees = allWorktrees.filter((entry) => entry?.path && entry?.branch).map((entry) => ({ path: entry.path, branch: entry.branch }));
|
|
51335
|
+
} catch {
|
|
51336
|
+
resolvedWorktrees = null;
|
|
51337
|
+
}
|
|
51338
|
+
const searchOptions = {
|
|
51339
|
+
branch: context.branch,
|
|
51340
|
+
...resolvedWorktrees && resolvedWorktrees.length > 0 ? { worktrees: resolvedWorktrees } : {}
|
|
51341
|
+
};
|
|
51342
|
+
const lookupCodex = lookups.findLatestCodexSession ?? findLatestCodexSession;
|
|
51343
|
+
const lookupClaude = lookups.findLatestClaudeSession ?? findLatestClaudeSession;
|
|
51344
|
+
const lookupGemini = lookups.findLatestGeminiSession ?? findLatestGeminiSession;
|
|
51345
|
+
const lookupOpenCode = lookups.findLatestOpenCodeSession ?? findLatestOpenCodeSession;
|
|
51346
|
+
const updated = await Promise.all(entries.map(async (entry) => {
|
|
51347
|
+
let latest = null;
|
|
51348
|
+
switch (entry.toolId) {
|
|
51349
|
+
case "codex-cli":
|
|
51350
|
+
latest = await lookupCodex(searchOptions);
|
|
51351
|
+
break;
|
|
51352
|
+
case "claude-code":
|
|
51353
|
+
latest = await lookupClaude(worktreePath, searchOptions);
|
|
51354
|
+
break;
|
|
51355
|
+
case "gemini-cli":
|
|
51356
|
+
latest = await lookupGemini(searchOptions);
|
|
51357
|
+
break;
|
|
51358
|
+
case "opencode":
|
|
51359
|
+
latest = await lookupOpenCode(searchOptions);
|
|
51360
|
+
break;
|
|
51361
|
+
default:
|
|
51362
|
+
return entry;
|
|
51363
|
+
}
|
|
51364
|
+
if (!latest?.id)
|
|
51365
|
+
return entry;
|
|
51366
|
+
const updatedTimestamp = Math.max(entry.timestamp ?? 0, latest.mtime);
|
|
51367
|
+
return {
|
|
51368
|
+
...entry,
|
|
51369
|
+
sessionId: latest.id,
|
|
51370
|
+
timestamp: updatedTimestamp
|
|
51371
|
+
};
|
|
51372
|
+
}));
|
|
51373
|
+
return updated.sort((a2, b) => (b.timestamp ?? 0) - (a2.timestamp ?? 0));
|
|
51374
|
+
}
|
|
51375
|
+
|
|
51376
|
+
// src/config/tools.ts
|
|
51377
|
+
init_builtin_coding_agents();
|
|
51378
|
+
import { homedir as homedir8 } from "os";
|
|
51379
|
+
import path20 from "path";
|
|
51380
|
+
import { readFile as readFile4, writeFile as writeFile3, mkdir as mkdir3, rename as rename2 } from "fs/promises";
|
|
50108
51381
|
|
|
50109
51382
|
// src/config/profiles.ts
|
|
50110
51383
|
import {
|
|
50111
51384
|
mkdir as mkdir2,
|
|
50112
51385
|
open,
|
|
50113
|
-
readFile as
|
|
51386
|
+
readFile as readFile3,
|
|
50114
51387
|
rename,
|
|
50115
|
-
stat,
|
|
51388
|
+
stat as stat2,
|
|
50116
51389
|
unlink,
|
|
50117
51390
|
writeFile as writeFile2
|
|
50118
51391
|
} from "fs/promises";
|
|
50119
|
-
import
|
|
51392
|
+
import path19 from "path";
|
|
50120
51393
|
|
|
50121
51394
|
// node_modules/yaml/dist/index.js
|
|
50122
51395
|
var composer = require_composer();
|
|
@@ -50165,7 +51438,7 @@ var $visit = visit.visit;
|
|
|
50165
51438
|
var $visitAsync = visit.visitAsync;
|
|
50166
51439
|
|
|
50167
51440
|
// src/config/profiles.ts
|
|
50168
|
-
import { homedir as
|
|
51441
|
+
import { homedir as homedir7 } from "os";
|
|
50169
51442
|
|
|
50170
51443
|
// src/types/profiles.ts
|
|
50171
51444
|
var DEFAULT_PROFILES_CONFIG = Object.freeze({
|
|
@@ -50180,11 +51453,11 @@ function isValidProfileName(name) {
|
|
|
50180
51453
|
|
|
50181
51454
|
// src/config/profiles.ts
|
|
50182
51455
|
function getConfigDir() {
|
|
50183
|
-
const worktreeHome = process.env.GWT_HOME && process.env.GWT_HOME.trim().length > 0 ? process.env.GWT_HOME :
|
|
50184
|
-
return
|
|
51456
|
+
const worktreeHome = process.env.GWT_HOME && process.env.GWT_HOME.trim().length > 0 ? process.env.GWT_HOME : homedir7();
|
|
51457
|
+
return path19.join(worktreeHome, ".gwt");
|
|
50185
51458
|
}
|
|
50186
51459
|
function getProfilesConfigPath() {
|
|
50187
|
-
return
|
|
51460
|
+
return path19.join(getConfigDir(), "profiles.yaml");
|
|
50188
51461
|
}
|
|
50189
51462
|
var LOCK_RETRY_INTERVAL_MS = 50;
|
|
50190
51463
|
var LOCK_TIMEOUT_MS = 3000;
|
|
@@ -50194,7 +51467,7 @@ function getProfilesLockPath() {
|
|
|
50194
51467
|
}
|
|
50195
51468
|
async function withProfilesLock(fn) {
|
|
50196
51469
|
const lockPath = getProfilesLockPath();
|
|
50197
|
-
await mkdir2(
|
|
51470
|
+
await mkdir2(path19.dirname(lockPath), { recursive: true });
|
|
50198
51471
|
const startedAt = Date.now();
|
|
50199
51472
|
while (true) {
|
|
50200
51473
|
try {
|
|
@@ -50213,7 +51486,7 @@ async function withProfilesLock(fn) {
|
|
|
50213
51486
|
throw error;
|
|
50214
51487
|
}
|
|
50215
51488
|
try {
|
|
50216
|
-
const lockStat = await
|
|
51489
|
+
const lockStat = await stat2(lockPath);
|
|
50217
51490
|
const isStale = Date.now() - lockStat.mtimeMs > LOCK_STALE_MS;
|
|
50218
51491
|
if (isStale) {
|
|
50219
51492
|
await unlink(lockPath).catch(() => {});
|
|
@@ -50243,7 +51516,7 @@ var PROFILES_CONFIG_PATH = getProfilesConfigPath();
|
|
|
50243
51516
|
async function loadProfiles() {
|
|
50244
51517
|
try {
|
|
50245
51518
|
const configPath = getProfilesConfigPath();
|
|
50246
|
-
const content = await
|
|
51519
|
+
const content = await readFile3(configPath, "utf-8");
|
|
50247
51520
|
const config = $parse(content);
|
|
50248
51521
|
if (!config.version || typeof config.version !== "string") {
|
|
50249
51522
|
throw new Error("version field is required and must be a string");
|
|
@@ -50328,9 +51601,9 @@ async function deleteProfile(name) {
|
|
|
50328
51601
|
|
|
50329
51602
|
// src/config/tools.ts
|
|
50330
51603
|
var logger3 = createLogger({ category: "config" });
|
|
50331
|
-
var WORKTREE_HOME = process.env.GWT_HOME && process.env.GWT_HOME.trim().length > 0 ? process.env.GWT_HOME :
|
|
50332
|
-
var CONFIG_DIR =
|
|
50333
|
-
var TOOLS_CONFIG_PATH =
|
|
51604
|
+
var WORKTREE_HOME = process.env.GWT_HOME && process.env.GWT_HOME.trim().length > 0 ? process.env.GWT_HOME : homedir8();
|
|
51605
|
+
var CONFIG_DIR = path20.join(WORKTREE_HOME, ".gwt");
|
|
51606
|
+
var TOOLS_CONFIG_PATH = path20.join(CONFIG_DIR, "tools.json");
|
|
50334
51607
|
var TEMP_CONFIG_PATH = `${TOOLS_CONFIG_PATH}.tmp`;
|
|
50335
51608
|
var DEFAULT_CONFIG2 = {
|
|
50336
51609
|
version: "1.0.0",
|
|
@@ -50339,7 +51612,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
50339
51612
|
};
|
|
50340
51613
|
async function loadCodingAgentsConfig() {
|
|
50341
51614
|
try {
|
|
50342
|
-
const content = await
|
|
51615
|
+
const content = await readFile4(TOOLS_CONFIG_PATH, "utf-8");
|
|
50343
51616
|
const config = JSON.parse(content);
|
|
50344
51617
|
const legacyConfig = config;
|
|
50345
51618
|
if (!config.customCodingAgents && legacyConfig.customTools) {
|
|
@@ -50423,7 +51696,7 @@ function validateCodingAgent(agent) {
|
|
|
50423
51696
|
throw new Error(`Invalid type: "${a2.type}"
|
|
50424
51697
|
` + `Type must be one of: ${validTypes.join(", ")}`);
|
|
50425
51698
|
}
|
|
50426
|
-
if (a2.type === "path" && !
|
|
51699
|
+
if (a2.type === "path" && !path20.isAbsolute(a2.command)) {
|
|
50427
51700
|
throw new Error(`For type="path", command must be an absolute path: "${a2.command}"`);
|
|
50428
51701
|
}
|
|
50429
51702
|
if (!a2.modeArgs.normal && !a2.modeArgs.continue && !a2.modeArgs.resume) {
|
|
@@ -50450,14 +51723,45 @@ async function getAllCodingAgents() {
|
|
|
50450
51723
|
|
|
50451
51724
|
// src/logging/reader.ts
|
|
50452
51725
|
import fs4 from "fs/promises";
|
|
50453
|
-
import
|
|
51726
|
+
import path21 from "path";
|
|
50454
51727
|
import os4 from "os";
|
|
51728
|
+
var LOG_FILENAME_PATTERN = /^\d{4}-\d{2}-\d{2}\.jsonl$/;
|
|
50455
51729
|
function resolveLogDir(cwd = process.cwd()) {
|
|
50456
|
-
const cwdBase =
|
|
50457
|
-
return
|
|
51730
|
+
const cwdBase = path21.basename(cwd) || "workspace";
|
|
51731
|
+
return path21.join(os4.homedir(), ".gwt", "logs", cwdBase);
|
|
50458
51732
|
}
|
|
50459
|
-
function
|
|
50460
|
-
|
|
51733
|
+
function resolveLogTarget(branch, workingDirectory = process.cwd()) {
|
|
51734
|
+
if (!branch) {
|
|
51735
|
+
return {
|
|
51736
|
+
logDir: resolveLogDir(workingDirectory),
|
|
51737
|
+
sourcePath: workingDirectory,
|
|
51738
|
+
reason: "working-directory"
|
|
51739
|
+
};
|
|
51740
|
+
}
|
|
51741
|
+
const worktreePath = branch.worktree?.path;
|
|
51742
|
+
if (worktreePath) {
|
|
51743
|
+
const accessible = branch.worktree?.isAccessible !== false;
|
|
51744
|
+
if (accessible) {
|
|
51745
|
+
return {
|
|
51746
|
+
logDir: resolveLogDir(worktreePath),
|
|
51747
|
+
sourcePath: worktreePath,
|
|
51748
|
+
reason: "worktree"
|
|
51749
|
+
};
|
|
51750
|
+
}
|
|
51751
|
+
return {
|
|
51752
|
+
logDir: null,
|
|
51753
|
+
sourcePath: worktreePath,
|
|
51754
|
+
reason: "worktree-inaccessible"
|
|
51755
|
+
};
|
|
51756
|
+
}
|
|
51757
|
+
if (branch.isCurrent) {
|
|
51758
|
+
return {
|
|
51759
|
+
logDir: resolveLogDir(workingDirectory),
|
|
51760
|
+
sourcePath: workingDirectory,
|
|
51761
|
+
reason: "current-working-directory"
|
|
51762
|
+
};
|
|
51763
|
+
}
|
|
51764
|
+
return { logDir: null, sourcePath: null, reason: "no-worktree" };
|
|
50461
51765
|
}
|
|
50462
51766
|
function getTodayLogDate() {
|
|
50463
51767
|
return formatDate(new Date);
|
|
@@ -50475,6 +51779,111 @@ async function readLogFileLines(filePath) {
|
|
|
50475
51779
|
throw error;
|
|
50476
51780
|
}
|
|
50477
51781
|
}
|
|
51782
|
+
async function listLogFiles(logDir) {
|
|
51783
|
+
try {
|
|
51784
|
+
const entries = await fs4.readdir(logDir, { withFileTypes: true });
|
|
51785
|
+
const files = [];
|
|
51786
|
+
for (const entry of entries) {
|
|
51787
|
+
if (!entry.isFile())
|
|
51788
|
+
continue;
|
|
51789
|
+
if (!LOG_FILENAME_PATTERN.test(entry.name))
|
|
51790
|
+
continue;
|
|
51791
|
+
const date = entry.name.replace(/\.jsonl$/, "");
|
|
51792
|
+
const fullPath = path21.join(logDir, entry.name);
|
|
51793
|
+
try {
|
|
51794
|
+
const stat3 = await fs4.stat(fullPath);
|
|
51795
|
+
files.push({ date, path: fullPath, mtimeMs: stat3.mtimeMs });
|
|
51796
|
+
} catch {}
|
|
51797
|
+
}
|
|
51798
|
+
return files.sort((a2, b) => b.mtimeMs - a2.mtimeMs);
|
|
51799
|
+
} catch (error) {
|
|
51800
|
+
const err = error;
|
|
51801
|
+
if (err.code === "ENOENT") {
|
|
51802
|
+
return [];
|
|
51803
|
+
}
|
|
51804
|
+
throw error;
|
|
51805
|
+
}
|
|
51806
|
+
}
|
|
51807
|
+
var getLatestLogMtimeWithContent = async (logDir) => {
|
|
51808
|
+
const files = await listLogFiles(logDir);
|
|
51809
|
+
for (const file of files) {
|
|
51810
|
+
const lines = await readLogFileLines(file.path);
|
|
51811
|
+
if (lines.length > 0) {
|
|
51812
|
+
return file.mtimeMs;
|
|
51813
|
+
}
|
|
51814
|
+
}
|
|
51815
|
+
return null;
|
|
51816
|
+
};
|
|
51817
|
+
async function selectLogTargetByRecency(primary, fallback) {
|
|
51818
|
+
if (!primary.logDir || !primary.sourcePath) {
|
|
51819
|
+
return primary;
|
|
51820
|
+
}
|
|
51821
|
+
if (!fallback.logDir || !fallback.sourcePath) {
|
|
51822
|
+
return primary;
|
|
51823
|
+
}
|
|
51824
|
+
if (primary.logDir === fallback.logDir) {
|
|
51825
|
+
return primary;
|
|
51826
|
+
}
|
|
51827
|
+
if (primary.reason !== "worktree") {
|
|
51828
|
+
return primary;
|
|
51829
|
+
}
|
|
51830
|
+
const [primaryMtime, fallbackMtime] = await Promise.all([
|
|
51831
|
+
getLatestLogMtimeWithContent(primary.logDir),
|
|
51832
|
+
getLatestLogMtimeWithContent(fallback.logDir)
|
|
51833
|
+
]);
|
|
51834
|
+
if (fallbackMtime !== null && (primaryMtime === null || fallbackMtime > primaryMtime)) {
|
|
51835
|
+
return {
|
|
51836
|
+
...fallback,
|
|
51837
|
+
reason: "working-directory-fallback"
|
|
51838
|
+
};
|
|
51839
|
+
}
|
|
51840
|
+
return primary;
|
|
51841
|
+
}
|
|
51842
|
+
async function clearLogFiles(logDir) {
|
|
51843
|
+
const files = await listLogFiles(logDir);
|
|
51844
|
+
let cleared = 0;
|
|
51845
|
+
for (const file of files) {
|
|
51846
|
+
try {
|
|
51847
|
+
await fs4.truncate(file.path, 0);
|
|
51848
|
+
cleared += 1;
|
|
51849
|
+
} catch (error) {
|
|
51850
|
+
const err = error;
|
|
51851
|
+
if (err.code !== "ENOENT") {
|
|
51852
|
+
throw error;
|
|
51853
|
+
}
|
|
51854
|
+
}
|
|
51855
|
+
}
|
|
51856
|
+
return cleared;
|
|
51857
|
+
}
|
|
51858
|
+
async function readLogLinesForDate(logDir, preferredDate) {
|
|
51859
|
+
const files = await listLogFiles(logDir);
|
|
51860
|
+
if (files.length === 0) {
|
|
51861
|
+
return null;
|
|
51862
|
+
}
|
|
51863
|
+
const ordered = [];
|
|
51864
|
+
const preferred = files.find((file) => file.date === preferredDate);
|
|
51865
|
+
if (preferred) {
|
|
51866
|
+
ordered.push(preferred);
|
|
51867
|
+
}
|
|
51868
|
+
for (const file of files) {
|
|
51869
|
+
if (preferred && file.date === preferred.date) {
|
|
51870
|
+
continue;
|
|
51871
|
+
}
|
|
51872
|
+
ordered.push(file);
|
|
51873
|
+
}
|
|
51874
|
+
for (const file of ordered) {
|
|
51875
|
+
const lines = await readLogFileLines(file.path);
|
|
51876
|
+
if (lines.length > 0) {
|
|
51877
|
+
return { date: file.date, lines };
|
|
51878
|
+
}
|
|
51879
|
+
}
|
|
51880
|
+
const fallback = files[0];
|
|
51881
|
+
if (!fallback) {
|
|
51882
|
+
return { date: preferredDate, lines: [] };
|
|
51883
|
+
}
|
|
51884
|
+
const fallbackDate = preferred?.date ?? fallback.date;
|
|
51885
|
+
return { date: fallbackDate, lines: [] };
|
|
51886
|
+
}
|
|
50478
51887
|
|
|
50479
51888
|
// src/logging/formatter.ts
|
|
50480
51889
|
var LEVEL_LABELS = {
|
|
@@ -50485,15 +51894,29 @@ var LEVEL_LABELS = {
|
|
|
50485
51894
|
50: "ERROR",
|
|
50486
51895
|
60: "FATAL"
|
|
50487
51896
|
};
|
|
51897
|
+
var LOCAL_TIME_FORMATTER = new Intl.DateTimeFormat(undefined, {
|
|
51898
|
+
hour: "2-digit",
|
|
51899
|
+
minute: "2-digit",
|
|
51900
|
+
second: "2-digit",
|
|
51901
|
+
hour12: false
|
|
51902
|
+
});
|
|
51903
|
+
var formatLocalTimeParts = (date) => {
|
|
51904
|
+
const parts = LOCAL_TIME_FORMATTER.formatToParts(date);
|
|
51905
|
+
const get = (type) => parts.find((part) => part.type === type)?.value;
|
|
51906
|
+
const hour = get("hour");
|
|
51907
|
+
const minute = get("minute");
|
|
51908
|
+
const second = get("second");
|
|
51909
|
+
if (!hour || !minute || !second) {
|
|
51910
|
+
return LOCAL_TIME_FORMATTER.format(date);
|
|
51911
|
+
}
|
|
51912
|
+
return `${hour}:${minute}:${second}`;
|
|
51913
|
+
};
|
|
50488
51914
|
var formatTimeLabel = (value) => {
|
|
50489
51915
|
if (typeof value === "string" || typeof value === "number") {
|
|
50490
51916
|
const date = new Date(value);
|
|
50491
51917
|
if (!Number.isNaN(date.getTime())) {
|
|
50492
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
50493
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
50494
|
-
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
50495
51918
|
return {
|
|
50496
|
-
label:
|
|
51919
|
+
label: formatLocalTimeParts(date),
|
|
50497
51920
|
timestamp: date.getTime()
|
|
50498
51921
|
};
|
|
50499
51922
|
}
|
|
@@ -50577,17 +52000,17 @@ async function copyToClipboard(text, options = {}) {
|
|
|
50577
52000
|
}
|
|
50578
52001
|
|
|
50579
52002
|
// src/utils.ts
|
|
50580
|
-
import
|
|
52003
|
+
import path22 from "path";
|
|
50581
52004
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
50582
|
-
import { readFile as
|
|
52005
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
50583
52006
|
function getCurrentDirname() {
|
|
50584
|
-
return
|
|
52007
|
+
return path22.dirname(fileURLToPath4(import.meta.url));
|
|
50585
52008
|
}
|
|
50586
52009
|
async function getPackageVersion() {
|
|
50587
52010
|
try {
|
|
50588
52011
|
const currentDir = getCurrentDirname();
|
|
50589
|
-
const packageJsonPath =
|
|
50590
|
-
const packageJsonContent = await
|
|
52012
|
+
const packageJsonPath = path22.resolve(currentDir, "..", "package.json");
|
|
52013
|
+
const packageJsonContent = await readFile5(packageJsonPath, "utf-8");
|
|
50591
52014
|
const packageJson = JSON.parse(packageJsonContent);
|
|
50592
52015
|
return packageJson.version || null;
|
|
50593
52016
|
} catch {
|
|
@@ -50597,9 +52020,12 @@ async function getPackageVersion() {
|
|
|
50597
52020
|
|
|
50598
52021
|
// src/cli/ui/App.solid.tsx
|
|
50599
52022
|
init_constants();
|
|
52023
|
+
init_versionFetcher();
|
|
50600
52024
|
var logger4 = createLogger({
|
|
50601
52025
|
category: "app"
|
|
50602
52026
|
});
|
|
52027
|
+
var UNSAFE_SELECTION_MESSAGE = "Unsafe branch selected. Select anyway?";
|
|
52028
|
+
var SAFETY_PENDING_MESSAGE = "Safety check in progress. Select anyway?";
|
|
50603
52029
|
var DEFAULT_SCREEN = "branch-list";
|
|
50604
52030
|
var buildStats = (branches) => calculateStatistics(branches);
|
|
50605
52031
|
var applyCleanupStatus = (items, statusByBranch) => items.map((branch) => {
|
|
@@ -50630,6 +52056,23 @@ var applyCleanupStatus = (items, statusByBranch) => items.map((branch) => {
|
|
|
50630
52056
|
worktree
|
|
50631
52057
|
} : base2;
|
|
50632
52058
|
});
|
|
52059
|
+
var buildCleanupSafetyPending = (items) => {
|
|
52060
|
+
const pending = new Set;
|
|
52061
|
+
for (const branch of items) {
|
|
52062
|
+
if (branch.type === "remote") {
|
|
52063
|
+
continue;
|
|
52064
|
+
}
|
|
52065
|
+
if (branch.worktree) {
|
|
52066
|
+
pending.add(branch.name);
|
|
52067
|
+
continue;
|
|
52068
|
+
}
|
|
52069
|
+
if (isProtectedBranchName(branch.name)) {
|
|
52070
|
+
continue;
|
|
52071
|
+
}
|
|
52072
|
+
pending.add(branch.name);
|
|
52073
|
+
}
|
|
52074
|
+
return pending;
|
|
52075
|
+
};
|
|
50633
52076
|
var toLocalBranchName = (name) => {
|
|
50634
52077
|
const segments = name.split("/");
|
|
50635
52078
|
if (segments.length <= 1) {
|
|
@@ -50645,6 +52088,7 @@ var toSelectedBranchState = (branch) => {
|
|
|
50645
52088
|
displayName: branch.name,
|
|
50646
52089
|
branchType: branch.type,
|
|
50647
52090
|
branchCategory: branch.branchType,
|
|
52091
|
+
worktreePath: branch.worktree?.path ?? null,
|
|
50648
52092
|
...isRemote ? {
|
|
50649
52093
|
remoteBranch: branch.name
|
|
50650
52094
|
} : {}
|
|
@@ -50652,6 +52096,7 @@ var toSelectedBranchState = (branch) => {
|
|
|
50652
52096
|
};
|
|
50653
52097
|
function AppSolid(props) {
|
|
50654
52098
|
const renderer = useRenderer();
|
|
52099
|
+
const terminal = useTerminalSize();
|
|
50655
52100
|
let hasExited = false;
|
|
50656
52101
|
const exitApp = (result) => {
|
|
50657
52102
|
if (hasExited)
|
|
@@ -50668,6 +52113,7 @@ function AppSolid(props) {
|
|
|
50668
52113
|
const [stats, setStats] = createSignal(props.stats ?? buildStats(props.branches ?? []));
|
|
50669
52114
|
const [loading, setLoading] = createSignal(!props.branches);
|
|
50670
52115
|
const [error, setError] = createSignal(null);
|
|
52116
|
+
const [branchCursorPosition, setBranchCursorPosition] = createSignal(0);
|
|
50671
52117
|
const [toolItems, setToolItems] = createSignal([]);
|
|
50672
52118
|
const [toolError, setToolError] = createSignal(null);
|
|
50673
52119
|
const [version, setVersion] = createSignal(props.version ?? null);
|
|
@@ -50676,11 +52122,16 @@ function AppSolid(props) {
|
|
|
50676
52122
|
const [selectedTool, setSelectedTool] = createSignal(null);
|
|
50677
52123
|
const [selectedMode, setSelectedMode] = createSignal("normal");
|
|
50678
52124
|
const [selectedBranches, setSelectedBranches] = createSignal([]);
|
|
52125
|
+
const [unsafeSelectionConfirmVisible, setUnsafeSelectionConfirmVisible] = createSignal(false);
|
|
52126
|
+
const [unsafeConfirmInputLocked, setUnsafeConfirmInputLocked] = createSignal(false);
|
|
52127
|
+
const [unsafeSelectionTarget, setUnsafeSelectionTarget] = createSignal(null);
|
|
52128
|
+
const [unsafeSelectionMessage, setUnsafeSelectionMessage] = createSignal(UNSAFE_SELECTION_MESSAGE);
|
|
50679
52129
|
const [branchFooterMessage, setBranchFooterMessage] = createSignal(null);
|
|
50680
52130
|
const [branchInputLocked, setBranchInputLocked] = createSignal(false);
|
|
50681
52131
|
const [cleanupIndicators, setCleanupIndicators] = createSignal({});
|
|
50682
52132
|
const [cleanupStatusByBranch, setCleanupStatusByBranch] = createSignal(new Map);
|
|
50683
52133
|
const [cleanupSafetyLoading, setCleanupSafetyLoading] = createSignal(false);
|
|
52134
|
+
const [cleanupSafetyPending, setCleanupSafetyPending] = createSignal(new Set);
|
|
50684
52135
|
const [isNewBranch, setIsNewBranch] = createSignal(false);
|
|
50685
52136
|
const [newBranchBaseRef, setNewBranchBaseRef] = createSignal(null);
|
|
50686
52137
|
const [creationSource, setCreationSource] = createSignal(null);
|
|
@@ -50689,20 +52140,59 @@ function AppSolid(props) {
|
|
|
50689
52140
|
});
|
|
50690
52141
|
const [suppressCreateKey, setSuppressCreateKey] = createSignal(null);
|
|
50691
52142
|
const [defaultBaseBranch, setDefaultBaseBranch] = createSignal("main");
|
|
52143
|
+
const suppressBranchInputOnce = () => {
|
|
52144
|
+
setUnsafeConfirmInputLocked(true);
|
|
52145
|
+
queueMicrotask(() => {
|
|
52146
|
+
setUnsafeConfirmInputLocked(false);
|
|
52147
|
+
});
|
|
52148
|
+
};
|
|
52149
|
+
const unsafeConfirmBoxWidth = createMemo(() => {
|
|
52150
|
+
const columns = terminal().columns || 80;
|
|
52151
|
+
return Math.max(1, Math.floor(columns * 0.6));
|
|
52152
|
+
});
|
|
52153
|
+
const unsafeConfirmContentWidth = createMemo(() => Math.max(0, unsafeConfirmBoxWidth() - 4));
|
|
50692
52154
|
const [sessionHistory, setSessionHistory] = createSignal([]);
|
|
52155
|
+
const [quickStartHistory, setQuickStartHistory] = createSignal([]);
|
|
50693
52156
|
const historyForBranch = createMemo(() => {
|
|
50694
52157
|
const history = sessionHistory();
|
|
50695
52158
|
const branch = selectedBranch();
|
|
50696
52159
|
if (!branch)
|
|
50697
52160
|
return [];
|
|
50698
|
-
return history
|
|
52161
|
+
return findLatestBranchSessionsByTool(history, branch.name, branch.worktreePath ?? null);
|
|
52162
|
+
});
|
|
52163
|
+
createEffect(() => {
|
|
52164
|
+
setQuickStartHistory(historyForBranch());
|
|
52165
|
+
});
|
|
52166
|
+
createEffect(() => {
|
|
52167
|
+
const branch = selectedBranch();
|
|
52168
|
+
const baseHistory = historyForBranch();
|
|
52169
|
+
if (!wizardVisible() || !branch || baseHistory.length === 0) {
|
|
52170
|
+
return;
|
|
52171
|
+
}
|
|
52172
|
+
const worktreePath = branch.worktreePath ?? null;
|
|
52173
|
+
if (!worktreePath) {
|
|
52174
|
+
return;
|
|
52175
|
+
}
|
|
52176
|
+
const branchName = branch.name;
|
|
52177
|
+
(async () => {
|
|
52178
|
+
const refreshed = await refreshQuickStartEntries(baseHistory, {
|
|
52179
|
+
branch: branchName,
|
|
52180
|
+
worktreePath
|
|
52181
|
+
});
|
|
52182
|
+
if (selectedBranch()?.name !== branchName) {
|
|
52183
|
+
return;
|
|
52184
|
+
}
|
|
52185
|
+
setQuickStartHistory(refreshed);
|
|
52186
|
+
})();
|
|
50699
52187
|
});
|
|
50700
52188
|
const [logEntries, setLogEntries] = createSignal([]);
|
|
50701
52189
|
const [logLoading, setLogLoading] = createSignal(false);
|
|
50702
52190
|
const [logError2, setLogError] = createSignal(null);
|
|
50703
52191
|
const [logSelectedEntry, setLogSelectedEntry] = createSignal(null);
|
|
50704
|
-
const [logSelectedDate,
|
|
52192
|
+
const [logSelectedDate, setLogSelectedDate] = createSignal(getTodayLogDate());
|
|
50705
52193
|
const [logNotification, setLogNotification] = createSignal(null);
|
|
52194
|
+
const [logTailEnabled, setLogTailEnabled] = createSignal(false);
|
|
52195
|
+
const [logTargetBranch, setLogTargetBranch] = createSignal(null);
|
|
50706
52196
|
const [profileItems, setProfileItems] = createSignal([]);
|
|
50707
52197
|
const [activeProfile, setActiveProfileName] = createSignal(null);
|
|
50708
52198
|
const [profileError, setProfileError] = createSignal(null);
|
|
@@ -50717,7 +52207,31 @@ function AppSolid(props) {
|
|
|
50717
52207
|
const [profileInputSuppressKey, setProfileInputSuppressKey] = createSignal(null);
|
|
50718
52208
|
const [profileEnvKey, setProfileEnvKey] = createSignal(null);
|
|
50719
52209
|
const [profileConfirmMode, setProfileConfirmMode] = createSignal("delete-profile");
|
|
50720
|
-
const
|
|
52210
|
+
const [logEffectiveTarget, setLogEffectiveTarget] = createSignal(null);
|
|
52211
|
+
const logPrimaryTarget = createMemo(() => resolveLogTarget(logTargetBranch(), workingDirectory()));
|
|
52212
|
+
const logFallbackTarget = createMemo(() => resolveLogTarget(null, workingDirectory()));
|
|
52213
|
+
const logActiveTarget = createMemo(() => logEffectiveTarget() ?? logPrimaryTarget());
|
|
52214
|
+
const logBranchLabel = createMemo(() => logTargetBranch()?.label ?? null);
|
|
52215
|
+
const logSourceLabel = createMemo(() => {
|
|
52216
|
+
const target = logActiveTarget();
|
|
52217
|
+
if (!target.sourcePath) {
|
|
52218
|
+
return "(none)";
|
|
52219
|
+
}
|
|
52220
|
+
if (target.reason === "current-working-directory" || target.reason === "working-directory") {
|
|
52221
|
+
return `${target.sourcePath} (cwd)`;
|
|
52222
|
+
}
|
|
52223
|
+
if (target.reason === "working-directory-fallback") {
|
|
52224
|
+
return `${target.sourcePath} (cwd fallback)`;
|
|
52225
|
+
}
|
|
52226
|
+
if (target.reason === "worktree-inaccessible") {
|
|
52227
|
+
return `${target.sourcePath} (inaccessible)`;
|
|
52228
|
+
}
|
|
52229
|
+
return target.sourcePath;
|
|
52230
|
+
});
|
|
52231
|
+
createEffect(() => {
|
|
52232
|
+
logPrimaryTarget();
|
|
52233
|
+
setLogEffectiveTarget(null);
|
|
52234
|
+
});
|
|
50721
52235
|
const selectedProfileConfig = createMemo(() => {
|
|
50722
52236
|
const name = selectedProfileName();
|
|
50723
52237
|
const config = profilesConfig();
|
|
@@ -50746,15 +52260,42 @@ function AppSolid(props) {
|
|
|
50746
52260
|
let cleanupSafetyRequestId = 0;
|
|
50747
52261
|
const refreshCleanupSafety = async () => {
|
|
50748
52262
|
const requestId = ++cleanupSafetyRequestId;
|
|
50749
|
-
|
|
52263
|
+
const pendingBranches = buildCleanupSafetyPending(branchItems());
|
|
52264
|
+
setCleanupSafetyPending(pendingBranches);
|
|
52265
|
+
setCleanupSafetyLoading(pendingBranches.size > 0);
|
|
52266
|
+
const statusByBranch = new Map;
|
|
52267
|
+
const applyProgress = (status) => {
|
|
52268
|
+
if (requestId !== cleanupSafetyRequestId) {
|
|
52269
|
+
return;
|
|
52270
|
+
}
|
|
52271
|
+
statusByBranch.set(status.branch, status);
|
|
52272
|
+
batch(() => {
|
|
52273
|
+
setCleanupStatusByBranch(new Map(statusByBranch));
|
|
52274
|
+
setBranchItems((items) => applyCleanupStatus(items, statusByBranch));
|
|
52275
|
+
setCleanupSafetyPending((prev) => {
|
|
52276
|
+
if (!prev.has(status.branch)) {
|
|
52277
|
+
return prev;
|
|
52278
|
+
}
|
|
52279
|
+
const next = new Set(prev);
|
|
52280
|
+
next.delete(status.branch);
|
|
52281
|
+
return next;
|
|
52282
|
+
});
|
|
52283
|
+
});
|
|
52284
|
+
};
|
|
50750
52285
|
try {
|
|
50751
|
-
const cleanupStatuses = await getCleanupStatus(
|
|
52286
|
+
const cleanupStatuses = await getCleanupStatus({
|
|
52287
|
+
onProgress: applyProgress
|
|
52288
|
+
});
|
|
50752
52289
|
if (requestId !== cleanupSafetyRequestId) {
|
|
50753
52290
|
return;
|
|
50754
52291
|
}
|
|
50755
|
-
|
|
50756
|
-
|
|
50757
|
-
|
|
52292
|
+
if (cleanupStatuses.length > statusByBranch.size) {
|
|
52293
|
+
cleanupStatuses.forEach((status) => {
|
|
52294
|
+
if (!statusByBranch.has(status.branch)) {
|
|
52295
|
+
applyProgress(status);
|
|
52296
|
+
}
|
|
52297
|
+
});
|
|
52298
|
+
}
|
|
50758
52299
|
} catch (err) {
|
|
50759
52300
|
if (requestId !== cleanupSafetyRequestId) {
|
|
50760
52301
|
return;
|
|
@@ -50763,15 +52304,19 @@ function AppSolid(props) {
|
|
|
50763
52304
|
err
|
|
50764
52305
|
}, "Failed to refresh cleanup safety indicators");
|
|
50765
52306
|
const empty = new Map;
|
|
50766
|
-
|
|
50767
|
-
|
|
52307
|
+
batch(() => {
|
|
52308
|
+
setCleanupStatusByBranch(empty);
|
|
52309
|
+
setBranchItems((items) => applyCleanupStatus(items, empty));
|
|
52310
|
+
});
|
|
50768
52311
|
} finally {
|
|
50769
52312
|
if (requestId === cleanupSafetyRequestId) {
|
|
50770
52313
|
setCleanupSafetyLoading(false);
|
|
52314
|
+
setCleanupSafetyPending(new Set);
|
|
50771
52315
|
}
|
|
50772
52316
|
}
|
|
50773
52317
|
};
|
|
50774
52318
|
let logNotificationTimer = null;
|
|
52319
|
+
let logTailTimer = null;
|
|
50775
52320
|
let branchFooterTimer = null;
|
|
50776
52321
|
const BRANCH_LOAD_TIMEOUT_MS = 3000;
|
|
50777
52322
|
const BRANCH_FULL_LOAD_TIMEOUT_MS = 8000;
|
|
@@ -50838,9 +52383,23 @@ function AppSolid(props) {
|
|
|
50838
52383
|
setLogLoading(true);
|
|
50839
52384
|
setLogError(null);
|
|
50840
52385
|
try {
|
|
50841
|
-
const
|
|
50842
|
-
const
|
|
50843
|
-
const
|
|
52386
|
+
const primaryTarget = logPrimaryTarget();
|
|
52387
|
+
const fallbackTarget = logFallbackTarget();
|
|
52388
|
+
const target = await selectLogTargetByRecency(primaryTarget, fallbackTarget);
|
|
52389
|
+
setLogEffectiveTarget(target);
|
|
52390
|
+
if (!target.logDir) {
|
|
52391
|
+
setLogEntries([]);
|
|
52392
|
+
setLogSelectedDate(targetDate);
|
|
52393
|
+
return;
|
|
52394
|
+
}
|
|
52395
|
+
const result = await readLogLinesForDate(target.logDir, targetDate);
|
|
52396
|
+
if (!result) {
|
|
52397
|
+
setLogEntries([]);
|
|
52398
|
+
setLogSelectedDate(targetDate);
|
|
52399
|
+
return;
|
|
52400
|
+
}
|
|
52401
|
+
setLogSelectedDate(result.date);
|
|
52402
|
+
const parsed = parseLogLines(result.lines, {
|
|
50844
52403
|
limit: 100
|
|
50845
52404
|
});
|
|
50846
52405
|
setLogEntries(parsed);
|
|
@@ -50851,10 +52410,39 @@ function AppSolid(props) {
|
|
|
50851
52410
|
setLogLoading(false);
|
|
50852
52411
|
}
|
|
50853
52412
|
};
|
|
52413
|
+
const clearLogTailTimer = () => {
|
|
52414
|
+
if (logTailTimer) {
|
|
52415
|
+
clearInterval(logTailTimer);
|
|
52416
|
+
logTailTimer = null;
|
|
52417
|
+
}
|
|
52418
|
+
};
|
|
52419
|
+
const toggleLogTail = () => {
|
|
52420
|
+
setLogTailEnabled((prev) => !prev);
|
|
52421
|
+
};
|
|
52422
|
+
const resetLogFiles = async () => {
|
|
52423
|
+
const target = logActiveTarget();
|
|
52424
|
+
if (!target.logDir) {
|
|
52425
|
+
showLogNotification("No logs available.", "error");
|
|
52426
|
+
return;
|
|
52427
|
+
}
|
|
52428
|
+
try {
|
|
52429
|
+
const cleared = await clearLogFiles(target.logDir);
|
|
52430
|
+
if (cleared === 0) {
|
|
52431
|
+
showLogNotification("No logs to reset.", "error");
|
|
52432
|
+
} else {
|
|
52433
|
+
showLogNotification("Logs cleared.", "success");
|
|
52434
|
+
}
|
|
52435
|
+
await loadLogEntries(logSelectedDate());
|
|
52436
|
+
} catch (err) {
|
|
52437
|
+
logger4.warn({
|
|
52438
|
+
err
|
|
52439
|
+
}, "Failed to clear log files");
|
|
52440
|
+
showLogNotification("Failed to reset logs.", "error");
|
|
52441
|
+
}
|
|
52442
|
+
};
|
|
50854
52443
|
const refreshBranches = async () => {
|
|
50855
52444
|
setLoading(true);
|
|
50856
52445
|
setError(null);
|
|
50857
|
-
refreshCleanupSafety();
|
|
50858
52446
|
try {
|
|
50859
52447
|
const repoRoot = await getRepositoryRoot();
|
|
50860
52448
|
const worktreesPromise = listAdditionalWorktrees();
|
|
@@ -50873,7 +52461,11 @@ function AppSolid(props) {
|
|
|
50873
52461
|
const initialItems = applyCleanupStatus(initial.items, cleanupStatusByBranch());
|
|
50874
52462
|
setBranchItems(initialItems);
|
|
50875
52463
|
setStats(buildStats(initialItems));
|
|
52464
|
+
refreshCleanupSafety();
|
|
50876
52465
|
(async () => {
|
|
52466
|
+
await withTimeout(fetchAllRemotes({
|
|
52467
|
+
cwd: repoRoot
|
|
52468
|
+
}), BRANCH_FULL_LOAD_TIMEOUT_MS).catch(() => {});
|
|
50877
52469
|
const [branches, latestWorktrees] = await Promise.all([withTimeout(getAllBranches(repoRoot), BRANCH_FULL_LOAD_TIMEOUT_MS).catch(() => localBranches), withTimeout(listAdditionalWorktrees(), BRANCH_FULL_LOAD_TIMEOUT_MS).catch(() => worktrees)]);
|
|
50878
52470
|
const full = buildBranchList(branches, latestWorktrees, lastToolUsageMap);
|
|
50879
52471
|
const fullItems = applyCleanupStatus(full.items, cleanupStatusByBranch());
|
|
@@ -50954,15 +52546,32 @@ function AppSolid(props) {
|
|
|
50954
52546
|
setToolError(err instanceof Error ? err : new Error(String(err)));
|
|
50955
52547
|
});
|
|
50956
52548
|
});
|
|
52549
|
+
onMount(() => {
|
|
52550
|
+
const bunxAgentIds = getBunxAgentIds();
|
|
52551
|
+
prefetchAgentVersions(bunxAgentIds).catch(() => {});
|
|
52552
|
+
prefetchInstalledVersions(bunxAgentIds).catch(() => {});
|
|
52553
|
+
});
|
|
50957
52554
|
createEffect(() => {
|
|
50958
52555
|
if (currentScreen() === "log-list") {
|
|
52556
|
+
logPrimaryTarget();
|
|
50959
52557
|
loadLogEntries(logSelectedDate());
|
|
50960
52558
|
}
|
|
50961
52559
|
});
|
|
52560
|
+
createEffect(() => {
|
|
52561
|
+
if (currentScreen() !== "log-list" || !logTailEnabled()) {
|
|
52562
|
+
clearLogTailTimer();
|
|
52563
|
+
return;
|
|
52564
|
+
}
|
|
52565
|
+
clearLogTailTimer();
|
|
52566
|
+
logTailTimer = setInterval(() => {
|
|
52567
|
+
loadLogEntries(logSelectedDate());
|
|
52568
|
+
}, 1500);
|
|
52569
|
+
});
|
|
50962
52570
|
onCleanup(() => {
|
|
50963
52571
|
if (logNotificationTimer) {
|
|
50964
52572
|
clearTimeout(logNotificationTimer);
|
|
50965
52573
|
}
|
|
52574
|
+
clearLogTailTimer();
|
|
50966
52575
|
if (branchFooterTimer) {
|
|
50967
52576
|
clearTimeout(branchFooterTimer);
|
|
50968
52577
|
}
|
|
@@ -51058,6 +52667,10 @@ function AppSolid(props) {
|
|
|
51058
52667
|
});
|
|
51059
52668
|
};
|
|
51060
52669
|
const handleWizardResume = (entry) => {
|
|
52670
|
+
if (!entry.sessionId) {
|
|
52671
|
+
handleWizardStartNew(entry);
|
|
52672
|
+
return;
|
|
52673
|
+
}
|
|
51061
52674
|
setWizardVisible(false);
|
|
51062
52675
|
const branch = selectedBranch();
|
|
51063
52676
|
if (!branch) {
|
|
@@ -51166,24 +52779,10 @@ function AppSolid(props) {
|
|
|
51166
52779
|
skipCounts.remote += 1;
|
|
51167
52780
|
continue;
|
|
51168
52781
|
}
|
|
51169
|
-
if (isProtectedBranchName(branch.name)) {
|
|
51170
|
-
skipCounts.protected += 1;
|
|
51171
|
-
continue;
|
|
51172
|
-
}
|
|
51173
52782
|
if (branch.isCurrent) {
|
|
51174
52783
|
skipCounts.current += 1;
|
|
51175
52784
|
continue;
|
|
51176
52785
|
}
|
|
51177
|
-
const hasUncommitted = branch.worktree?.hasUncommittedChanges === true;
|
|
51178
|
-
const hasUnpushed = branch.hasUnpushedCommits === true;
|
|
51179
|
-
if (hasUncommitted || hasUnpushed) {
|
|
51180
|
-
skipCounts.unsafe += 1;
|
|
51181
|
-
continue;
|
|
51182
|
-
}
|
|
51183
|
-
if (branch.safeToCleanup !== true) {
|
|
51184
|
-
skipCounts.unsafe += 1;
|
|
51185
|
-
continue;
|
|
51186
|
-
}
|
|
51187
52786
|
const worktreePath = branch.worktree?.path ?? null;
|
|
51188
52787
|
const cleanupType = worktreePath ? "worktree-and-branch" : "branch-only";
|
|
51189
52788
|
const baseTask = {
|
|
@@ -51274,7 +52873,7 @@ function AppSolid(props) {
|
|
|
51274
52873
|
return;
|
|
51275
52874
|
}
|
|
51276
52875
|
const selectionSet = new Set(selection);
|
|
51277
|
-
const targets = branchItems().filter((branch) => selectionSet.has(branch.name) && branch.
|
|
52876
|
+
const targets = branchItems().filter((branch) => selectionSet.has(branch.name) && branch.type !== "remote" && branch.worktreeStatus !== undefined).map((branch) => branch.name);
|
|
51278
52877
|
if (targets.length === 0) {
|
|
51279
52878
|
showBranchFooterMessage("No worktrees to repair.", "yellow");
|
|
51280
52879
|
return;
|
|
@@ -51485,15 +53084,49 @@ function AppSolid(props) {
|
|
|
51485
53084
|
}
|
|
51486
53085
|
};
|
|
51487
53086
|
const toggleSelectedBranch = (branchName) => {
|
|
51488
|
-
|
|
51489
|
-
|
|
51490
|
-
|
|
51491
|
-
|
|
51492
|
-
|
|
51493
|
-
|
|
51494
|
-
|
|
51495
|
-
return
|
|
51496
|
-
}
|
|
53087
|
+
if (unsafeSelectionConfirmVisible()) {
|
|
53088
|
+
return;
|
|
53089
|
+
}
|
|
53090
|
+
const currentSelection = new Set(selectedBranches());
|
|
53091
|
+
if (currentSelection.has(branchName)) {
|
|
53092
|
+
currentSelection.delete(branchName);
|
|
53093
|
+
setSelectedBranches(Array.from(currentSelection));
|
|
53094
|
+
return;
|
|
53095
|
+
}
|
|
53096
|
+
const branch = branchItems().find((item) => item.name === branchName);
|
|
53097
|
+
const pending = cleanupSafetyPending();
|
|
53098
|
+
const hasSafetyPending = pending.has(branchName);
|
|
53099
|
+
const hasUncommitted = branch?.worktree?.hasUncommittedChanges === true;
|
|
53100
|
+
const hasUnpushed = branch?.hasUnpushedCommits === true;
|
|
53101
|
+
const isUnmerged = branch?.isUnmerged === true;
|
|
53102
|
+
const safeToCleanup = branch?.safeToCleanup === true;
|
|
53103
|
+
const isRemoteBranch = branch?.type === "remote";
|
|
53104
|
+
const isUnsafe = Boolean(branch) && !isRemoteBranch && !hasSafetyPending && (hasUncommitted || hasUnpushed || isUnmerged || !safeToCleanup);
|
|
53105
|
+
if (branch && hasSafetyPending) {
|
|
53106
|
+
setUnsafeSelectionTarget(branch.name);
|
|
53107
|
+
setUnsafeSelectionMessage(SAFETY_PENDING_MESSAGE);
|
|
53108
|
+
setUnsafeSelectionConfirmVisible(true);
|
|
53109
|
+
return;
|
|
53110
|
+
}
|
|
53111
|
+
if (branch && isUnsafe) {
|
|
53112
|
+
setUnsafeSelectionTarget(branch.name);
|
|
53113
|
+
setUnsafeSelectionMessage(UNSAFE_SELECTION_MESSAGE);
|
|
53114
|
+
setUnsafeSelectionConfirmVisible(true);
|
|
53115
|
+
return;
|
|
53116
|
+
}
|
|
53117
|
+
currentSelection.add(branchName);
|
|
53118
|
+
setSelectedBranches(Array.from(currentSelection));
|
|
53119
|
+
};
|
|
53120
|
+
const confirmUnsafeSelection = (confirmed) => {
|
|
53121
|
+
suppressBranchInputOnce();
|
|
53122
|
+
const target = unsafeSelectionTarget();
|
|
53123
|
+
setUnsafeSelectionConfirmVisible(false);
|
|
53124
|
+
setUnsafeSelectionTarget(null);
|
|
53125
|
+
setUnsafeSelectionMessage(UNSAFE_SELECTION_MESSAGE);
|
|
53126
|
+
if (!confirmed || !target) {
|
|
53127
|
+
return;
|
|
53128
|
+
}
|
|
53129
|
+
setSelectedBranches((prev) => prev.includes(target) ? prev : [...prev, target]);
|
|
51497
53130
|
};
|
|
51498
53131
|
const handleToolSelect = (item) => {
|
|
51499
53132
|
setSelectedTool(item.value);
|
|
@@ -51544,8 +53177,9 @@ function AppSolid(props) {
|
|
|
51544
53177
|
const cleanupUI = {
|
|
51545
53178
|
indicators: cleanupIndicators(),
|
|
51546
53179
|
footerMessage: branchFooterMessage(),
|
|
51547
|
-
inputLocked: branchInputLocked(),
|
|
51548
|
-
safetyLoading: cleanupSafetyLoading()
|
|
53180
|
+
inputLocked: branchInputLocked() || unsafeConfirmInputLocked(),
|
|
53181
|
+
safetyLoading: cleanupSafetyLoading(),
|
|
53182
|
+
safetyPendingBranches: cleanupSafetyPending()
|
|
51549
53183
|
};
|
|
51550
53184
|
return createComponent2(BranchListScreen, {
|
|
51551
53185
|
get branches() {
|
|
@@ -51580,7 +53214,13 @@ function AppSolid(props) {
|
|
|
51580
53214
|
get activeProfile() {
|
|
51581
53215
|
return activeProfile();
|
|
51582
53216
|
},
|
|
51583
|
-
onOpenLogs: () =>
|
|
53217
|
+
onOpenLogs: (branch) => {
|
|
53218
|
+
setLogTargetBranch(branch);
|
|
53219
|
+
setLogSelectedEntry(null);
|
|
53220
|
+
setLogSelectedDate(getTodayLogDate());
|
|
53221
|
+
setLogTailEnabled(false);
|
|
53222
|
+
navigateTo("log-list");
|
|
53223
|
+
},
|
|
51584
53224
|
onOpenProfiles: () => navigateTo("profile"),
|
|
51585
53225
|
get selectedBranches() {
|
|
51586
53226
|
return selectedBranches();
|
|
@@ -51593,7 +53233,14 @@ function AppSolid(props) {
|
|
|
51593
53233
|
},
|
|
51594
53234
|
get wizardVisible() {
|
|
51595
53235
|
return wizardVisible();
|
|
51596
|
-
}
|
|
53236
|
+
},
|
|
53237
|
+
get confirmVisible() {
|
|
53238
|
+
return unsafeSelectionConfirmVisible();
|
|
53239
|
+
},
|
|
53240
|
+
get cursorPosition() {
|
|
53241
|
+
return branchCursorPosition();
|
|
53242
|
+
},
|
|
53243
|
+
onCursorPositionChange: setBranchCursorPosition
|
|
51597
53244
|
});
|
|
51598
53245
|
}
|
|
51599
53246
|
if (screen === "tool-select") {
|
|
@@ -51679,6 +53326,9 @@ function AppSolid(props) {
|
|
|
51679
53326
|
showLogNotification("Failed to copy to clipboard.", "error");
|
|
51680
53327
|
}
|
|
51681
53328
|
},
|
|
53329
|
+
onReload: () => void loadLogEntries(logSelectedDate()),
|
|
53330
|
+
onToggleTail: toggleLogTail,
|
|
53331
|
+
onReset: () => void resetLogFiles(),
|
|
51682
53332
|
get notification() {
|
|
51683
53333
|
return logNotification();
|
|
51684
53334
|
},
|
|
@@ -51688,6 +53338,15 @@ function AppSolid(props) {
|
|
|
51688
53338
|
get selectedDate() {
|
|
51689
53339
|
return logSelectedDate();
|
|
51690
53340
|
},
|
|
53341
|
+
get branchLabel() {
|
|
53342
|
+
return logBranchLabel();
|
|
53343
|
+
},
|
|
53344
|
+
get sourceLabel() {
|
|
53345
|
+
return logSourceLabel();
|
|
53346
|
+
},
|
|
53347
|
+
get tailing() {
|
|
53348
|
+
return logTailEnabled();
|
|
53349
|
+
},
|
|
51691
53350
|
get helpVisible() {
|
|
51692
53351
|
return helpVisible();
|
|
51693
53352
|
}
|
|
@@ -51932,7 +53591,35 @@ function AppSolid(props) {
|
|
|
51932
53591
|
}
|
|
51933
53592
|
});
|
|
51934
53593
|
};
|
|
51935
|
-
return [memo2(renderCurrentScreen),
|
|
53594
|
+
return [memo2(renderCurrentScreen), memo2(() => memo2(() => !!unsafeSelectionConfirmVisible())() && (() => {
|
|
53595
|
+
var _el$ = createElement("box");
|
|
53596
|
+
setProp(_el$, "position", "absolute");
|
|
53597
|
+
setProp(_el$, "top", "30%");
|
|
53598
|
+
setProp(_el$, "left", "20%");
|
|
53599
|
+
setProp(_el$, "zIndex", 110);
|
|
53600
|
+
setProp(_el$, "border", true);
|
|
53601
|
+
setProp(_el$, "borderStyle", "single");
|
|
53602
|
+
setProp(_el$, "borderColor", "yellow");
|
|
53603
|
+
setProp(_el$, "backgroundColor", "black");
|
|
53604
|
+
setProp(_el$, "padding", 1);
|
|
53605
|
+
insert(_el$, createComponent2(ConfirmScreen, {
|
|
53606
|
+
get message() {
|
|
53607
|
+
return unsafeSelectionMessage();
|
|
53608
|
+
},
|
|
53609
|
+
onConfirm: confirmUnsafeSelection,
|
|
53610
|
+
yesLabel: "OK",
|
|
53611
|
+
noLabel: "Cancel",
|
|
53612
|
+
defaultNo: true,
|
|
53613
|
+
get helpVisible() {
|
|
53614
|
+
return helpVisible();
|
|
53615
|
+
},
|
|
53616
|
+
get width() {
|
|
53617
|
+
return unsafeConfirmContentWidth();
|
|
53618
|
+
}
|
|
53619
|
+
}));
|
|
53620
|
+
effect((_$p) => setProp(_el$, "width", unsafeConfirmBoxWidth(), _$p));
|
|
53621
|
+
return _el$;
|
|
53622
|
+
})()), createComponent2(HelpOverlay, {
|
|
51936
53623
|
get visible() {
|
|
51937
53624
|
return helpVisible();
|
|
51938
53625
|
},
|
|
@@ -51947,7 +53634,7 @@ function AppSolid(props) {
|
|
|
51947
53634
|
return selectedBranch()?.name ?? "";
|
|
51948
53635
|
},
|
|
51949
53636
|
get history() {
|
|
51950
|
-
return
|
|
53637
|
+
return quickStartHistory();
|
|
51951
53638
|
},
|
|
51952
53639
|
onClose: handleWizardClose,
|
|
51953
53640
|
onComplete: handleWizardComplete,
|