@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
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
/** @jsxImportSource @opentui/solid */
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
createSignal,
|
|
4
|
+
createEffect,
|
|
5
|
+
createMemo,
|
|
6
|
+
onCleanup,
|
|
7
|
+
Show,
|
|
8
|
+
} from "solid-js";
|
|
3
9
|
import { useKeyboard } from "@opentui/solid";
|
|
4
10
|
import type { ToolSessionEntry } from "../../../../config/index.js";
|
|
5
11
|
import type { CodingAgentId, InferenceLevel } from "../../types.js";
|
|
@@ -13,6 +19,7 @@ import {
|
|
|
13
19
|
AgentSelectStep,
|
|
14
20
|
VersionSelectStep,
|
|
15
21
|
ModelSelectStep,
|
|
22
|
+
ModelInputStep,
|
|
16
23
|
ReasoningLevelStep,
|
|
17
24
|
ExecutionModeStep,
|
|
18
25
|
SkipPermissionsStep,
|
|
@@ -53,6 +60,7 @@ type WizardStep =
|
|
|
53
60
|
| "agent-select"
|
|
54
61
|
| "version-select"
|
|
55
62
|
| "model-select"
|
|
63
|
+
| "model-input"
|
|
56
64
|
| "reasoning-level"
|
|
57
65
|
| "execution-mode"
|
|
58
66
|
| "skip-permissions";
|
|
@@ -87,9 +95,11 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
87
95
|
>(undefined);
|
|
88
96
|
const [executionMode, setExecutionMode] =
|
|
89
97
|
createSignal<ExecutionMode>("normal");
|
|
98
|
+
const [versionSelectionReady, setVersionSelectionReady] = createSignal(false);
|
|
90
99
|
|
|
91
|
-
// キー伝播防止:
|
|
92
|
-
const [
|
|
100
|
+
// キー伝播防止: ステップ遷移直後は focused を無効にする
|
|
101
|
+
const [isTransitioning, setIsTransitioning] = createSignal(true);
|
|
102
|
+
let versionSelectionTimer: ReturnType<typeof setTimeout> | null = null;
|
|
93
103
|
|
|
94
104
|
// Reset state when wizard becomes visible
|
|
95
105
|
function getInitialStep(): WizardStep {
|
|
@@ -115,6 +125,13 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
115
125
|
setExecutionMode("normal");
|
|
116
126
|
};
|
|
117
127
|
|
|
128
|
+
// ステップ遷移時にキー伝搬防止を有効化するヘルパー
|
|
129
|
+
const startTransition = () => {
|
|
130
|
+
setIsTransitioning(true);
|
|
131
|
+
// 50ms後にフォーカスを有効化(キー伝搬を防止しつつ、応答性を維持)
|
|
132
|
+
setTimeout(() => setIsTransitioning(false), 50);
|
|
133
|
+
};
|
|
134
|
+
|
|
118
135
|
// Reset wizard when it becomes visible
|
|
119
136
|
let prevVisible = false;
|
|
120
137
|
createEffect(() => {
|
|
@@ -123,19 +140,17 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
123
140
|
resetWizard();
|
|
124
141
|
// キー伝播防止: 最初の数フレームでは focused を無効にする
|
|
125
142
|
// Enter キーが複数フレームにわたって伝播する可能性があるため、長めに設定
|
|
126
|
-
|
|
127
|
-
// 十分な時間を置いて focused を有効化 (150ms)
|
|
128
|
-
setTimeout(() => setIsInitialFrame(false), 150);
|
|
143
|
+
startTransition();
|
|
129
144
|
}
|
|
130
145
|
prevVisible = visible;
|
|
131
146
|
});
|
|
132
147
|
|
|
133
148
|
// Handle keyboard events for step navigation
|
|
134
|
-
// T412:
|
|
149
|
+
// T412: ステップ遷移直後は Enter キーをブロックして伝播を防ぐ
|
|
135
150
|
useKeyboard((key) => {
|
|
136
151
|
if (!props.visible) return;
|
|
137
|
-
//
|
|
138
|
-
if (
|
|
152
|
+
// ステップ遷移直後は Enter キーを無視(ステップ間のキー伝播防止)
|
|
153
|
+
if (isTransitioning() && key.name === "return") {
|
|
139
154
|
return;
|
|
140
155
|
}
|
|
141
156
|
if (key.name === "escape") {
|
|
@@ -146,6 +161,8 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
146
161
|
const goToStep = (nextStep: WizardStep) => {
|
|
147
162
|
setStepHistory((prev) => [...prev, step()]);
|
|
148
163
|
setStep(nextStep);
|
|
164
|
+
// ステップ遷移時にキー伝搬防止を有効化
|
|
165
|
+
startTransition();
|
|
149
166
|
};
|
|
150
167
|
|
|
151
168
|
const goBack = () => {
|
|
@@ -157,8 +174,32 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
157
174
|
const previousStep = history[history.length - 1] ?? "agent-select";
|
|
158
175
|
setStepHistory(history.slice(0, -1));
|
|
159
176
|
setStep(previousStep);
|
|
177
|
+
// ステップ遷移時にキー伝搬防止を有効化
|
|
178
|
+
startTransition();
|
|
160
179
|
};
|
|
161
180
|
|
|
181
|
+
createEffect(() => {
|
|
182
|
+
const currentStep = step();
|
|
183
|
+
if (versionSelectionTimer) {
|
|
184
|
+
clearTimeout(versionSelectionTimer);
|
|
185
|
+
versionSelectionTimer = null;
|
|
186
|
+
}
|
|
187
|
+
if (currentStep === "version-select") {
|
|
188
|
+
setVersionSelectionReady(false);
|
|
189
|
+
versionSelectionTimer = setTimeout(() => {
|
|
190
|
+
setVersionSelectionReady(true);
|
|
191
|
+
}, 50);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
setVersionSelectionReady(false);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
onCleanup(() => {
|
|
198
|
+
if (versionSelectionTimer) {
|
|
199
|
+
clearTimeout(versionSelectionTimer);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
162
203
|
// Determine if reasoning level step is needed
|
|
163
204
|
const needsReasoningLevel = createMemo(() => {
|
|
164
205
|
return selectedAgent() === "codex-cli";
|
|
@@ -204,12 +245,20 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
204
245
|
};
|
|
205
246
|
|
|
206
247
|
const handleVersionSelect = (version: string) => {
|
|
207
|
-
|
|
208
|
-
|
|
248
|
+
if (!versionSelectionReady() || step() !== "version-select") {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
// "installed" を明示的に保存し、未指定時は後方互換で "latest" にフォールバックできるようにする
|
|
252
|
+
setSelectedVersion(version);
|
|
209
253
|
goToStep("model-select");
|
|
210
254
|
};
|
|
211
255
|
|
|
212
256
|
const handleModelSelect = (model: string) => {
|
|
257
|
+
const agent = selectedAgent();
|
|
258
|
+
if (agent === "opencode" && model === "__custom__") {
|
|
259
|
+
goToStep("model-input");
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
213
262
|
setSelectedModel(model);
|
|
214
263
|
if (needsReasoningLevel()) {
|
|
215
264
|
goToStep("reasoning-level");
|
|
@@ -218,6 +267,19 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
218
267
|
}
|
|
219
268
|
};
|
|
220
269
|
|
|
270
|
+
const handleModelInputSubmit = (value: string) => {
|
|
271
|
+
const trimmed = value.trim();
|
|
272
|
+
if (!trimmed) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
setSelectedModel(trimmed);
|
|
276
|
+
if (needsReasoningLevel()) {
|
|
277
|
+
goToStep("reasoning-level");
|
|
278
|
+
} else {
|
|
279
|
+
goToStep("execution-mode");
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
|
|
221
283
|
const handleReasoningLevelSelect = (level: string) => {
|
|
222
284
|
setReasoningLevel(level as InferenceLevel);
|
|
223
285
|
goToStep("execution-mode");
|
|
@@ -258,7 +320,7 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
258
320
|
|
|
259
321
|
const renderStep = () => {
|
|
260
322
|
const currentStep = step();
|
|
261
|
-
const focused = !
|
|
323
|
+
const focused = !isTransitioning();
|
|
262
324
|
|
|
263
325
|
if (currentStep === "action-select") {
|
|
264
326
|
return (
|
|
@@ -337,6 +399,17 @@ export function WizardController(props: WizardControllerProps) {
|
|
|
337
399
|
);
|
|
338
400
|
}
|
|
339
401
|
|
|
402
|
+
if (currentStep === "model-input") {
|
|
403
|
+
return (
|
|
404
|
+
<ModelInputStep
|
|
405
|
+
agentId={selectedAgent() ?? "claude-code"}
|
|
406
|
+
onSubmit={handleModelInputSubmit}
|
|
407
|
+
onBack={goBack}
|
|
408
|
+
focused={focused}
|
|
409
|
+
/>
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
340
413
|
if (currentStep === "reasoning-level") {
|
|
341
414
|
return (
|
|
342
415
|
<ReasoningLevelStep
|
|
@@ -2,19 +2,20 @@
|
|
|
2
2
|
import { TextAttributes } from "@opentui/core";
|
|
3
3
|
import type { SelectRenderable } from "@opentui/core";
|
|
4
4
|
import { useKeyboard } from "@opentui/solid";
|
|
5
|
-
import { createEffect,
|
|
5
|
+
import { createEffect, createSignal } from "solid-js";
|
|
6
6
|
import { SelectInput, type SelectInputItem } from "./SelectInput.js";
|
|
7
7
|
import { TextInput } from "./TextInput.js";
|
|
8
8
|
import { getModelOptions } from "../../utils/modelOptions.js";
|
|
9
9
|
import type { CodingAgentId } from "../../types.js";
|
|
10
10
|
import { useWizardScroll } from "./WizardPopup.js";
|
|
11
11
|
import { getAgentTerminalColor } from "../../../../utils/coding-agent-colors.js";
|
|
12
|
+
import { getVersionCache } from "../../utils/versionCache.js";
|
|
13
|
+
import { selectionStyle } from "../../core/theme.js";
|
|
12
14
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from "
|
|
16
|
-
import {
|
|
17
|
-
import { findCommand } from "../../../../utils/command.js";
|
|
15
|
+
versionInfoToSelectItem,
|
|
16
|
+
createInstalledOption,
|
|
17
|
+
} from "../../utils/versionFetcher.js";
|
|
18
|
+
import { getInstalledVersionCache } from "../../utils/installedVersionCache.js";
|
|
18
19
|
|
|
19
20
|
/**
|
|
20
21
|
* WizardSteps - ウィザードの各ステップコンポーネント
|
|
@@ -346,7 +347,7 @@ export function AgentSelectStep(props: AgentSelectStepProps) {
|
|
|
346
347
|
const isSelected = () => selectedIndex() === index;
|
|
347
348
|
const agentColor = getAgentTerminalColor(agent.value);
|
|
348
349
|
return isSelected() ? (
|
|
349
|
-
<text bg=
|
|
350
|
+
<text bg={selectionStyle.bg} fg={selectionStyle.fg}>
|
|
350
351
|
{"> "}
|
|
351
352
|
{agent.label}
|
|
352
353
|
</text>
|
|
@@ -440,6 +441,54 @@ export function ModelSelectStep(props: ModelSelectStepProps) {
|
|
|
440
441
|
);
|
|
441
442
|
}
|
|
442
443
|
|
|
444
|
+
// T408b: カスタムモデル入力ステップ
|
|
445
|
+
export interface ModelInputStepProps extends StepProps {
|
|
446
|
+
agentId: CodingAgentId;
|
|
447
|
+
onSubmit: (value: string) => void;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
export function ModelInputStep(props: ModelInputStepProps) {
|
|
451
|
+
const [value, setValue] = createSignal("");
|
|
452
|
+
const scroll = useWizardScroll();
|
|
453
|
+
const placeholder = props.agentId === "opencode" ? "provider/model" : "model";
|
|
454
|
+
|
|
455
|
+
createEffect(() => {
|
|
456
|
+
if (props.focused === false) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (!scroll) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
scroll.ensureLineVisible(2);
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
const handleSubmit = (next: string) => {
|
|
466
|
+
const trimmed = next.trim();
|
|
467
|
+
if (!trimmed) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
props.onSubmit(trimmed);
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
return (
|
|
474
|
+
<box flexDirection="column">
|
|
475
|
+
<text fg="cyan" attributes={TextAttributes.BOLD}>
|
|
476
|
+
Enter custom model:
|
|
477
|
+
</text>
|
|
478
|
+
<text> </text>
|
|
479
|
+
<TextInput
|
|
480
|
+
value={value()}
|
|
481
|
+
onChange={setValue}
|
|
482
|
+
onSubmit={handleSubmit}
|
|
483
|
+
placeholder={placeholder}
|
|
484
|
+
focused={props.focused ?? true}
|
|
485
|
+
/>
|
|
486
|
+
<text> </text>
|
|
487
|
+
<text attributes={TextAttributes.DIM}>[Enter] Submit [Esc] Back</text>
|
|
488
|
+
</box>
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
|
|
443
492
|
// T409: 推論レベル選択ステップ(Codexのみ)
|
|
444
493
|
export interface ReasoningLevelStepProps extends StepProps {
|
|
445
494
|
onSelect: (level: string) => void;
|
|
@@ -626,89 +675,28 @@ const LATEST_OPTION: SelectInputItem = {
|
|
|
626
675
|
description: "Always fetch latest version",
|
|
627
676
|
};
|
|
628
677
|
|
|
629
|
-
// エージェントIDからパッケージ名を取得
|
|
630
|
-
function getPackageNameForAgent(agentId: string): string | null {
|
|
631
|
-
const agent = BUILTIN_CODING_AGENTS.find((a) => a.id === agentId);
|
|
632
|
-
if (!agent || agent.type !== "bunx") {
|
|
633
|
-
return null;
|
|
634
|
-
}
|
|
635
|
-
const { packageName } = parsePackageCommand(agent.command);
|
|
636
|
-
return packageName;
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
// バージョン一覧を取得
|
|
640
|
-
async function fetchVersionOptions(
|
|
641
|
-
agentId: string,
|
|
642
|
-
): Promise<SelectInputItem[]> {
|
|
643
|
-
const packageName = getPackageNameForAgent(agentId);
|
|
644
|
-
if (!packageName) {
|
|
645
|
-
return [];
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
const versions = await fetchPackageVersions(packageName);
|
|
649
|
-
return versions.map((v) => {
|
|
650
|
-
const item: SelectInputItem = {
|
|
651
|
-
label: v.isPrerelease ? `${v.version} (pre)` : v.version,
|
|
652
|
-
value: v.version,
|
|
653
|
-
};
|
|
654
|
-
if (v.publishedAt) {
|
|
655
|
-
item.description = new Date(v.publishedAt).toLocaleDateString();
|
|
656
|
-
}
|
|
657
|
-
return item;
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
// エージェントIDからコマンド名へのマッピング
|
|
662
|
-
const AGENT_COMMAND_MAP: Record<string, string> = {
|
|
663
|
-
"claude-code": "claude",
|
|
664
|
-
"codex-cli": "codex",
|
|
665
|
-
"gemini-cli": "gemini",
|
|
666
|
-
opencode: "opencode",
|
|
667
|
-
};
|
|
668
|
-
|
|
669
|
-
// インストール済みコマンド情報を取得(findCommandと統一)
|
|
670
|
-
async function fetchInstalledOption(
|
|
671
|
-
agentId: string,
|
|
672
|
-
): Promise<SelectInputItem | null> {
|
|
673
|
-
const commandName = AGENT_COMMAND_MAP[agentId];
|
|
674
|
-
if (!commandName) {
|
|
675
|
-
return null;
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
const result = await findCommand(commandName);
|
|
679
|
-
if (result.source !== "installed" || !result.path) {
|
|
680
|
-
return null;
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
// バージョン表示(v1.0.3 → 1.0.3 形式に)
|
|
684
|
-
const version = result.version?.replace(/^v/, "") ?? "unknown";
|
|
685
|
-
|
|
686
|
-
return {
|
|
687
|
-
label: `installed@${version}`,
|
|
688
|
-
value: "installed",
|
|
689
|
-
description: result.path,
|
|
690
|
-
};
|
|
691
|
-
}
|
|
692
|
-
|
|
693
678
|
export function VersionSelectStep(props: VersionSelectStepProps) {
|
|
694
679
|
const [selectedIndex, setSelectedIndex] = createSignal(0);
|
|
695
680
|
const [selectRef, setSelectRef] = createSignal<SelectRenderable | undefined>(
|
|
696
681
|
undefined,
|
|
697
682
|
);
|
|
698
683
|
|
|
699
|
-
// npm
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
684
|
+
// FR-029: Use cached versions from startup prefetch (no npm registry re-access)
|
|
685
|
+
const cachedVersions = () => {
|
|
686
|
+
const cached = getVersionCache(props.agentId);
|
|
687
|
+
if (!cached) {
|
|
688
|
+
return []; // FR-031: Fallback to empty, UI will show "latest" only
|
|
689
|
+
}
|
|
690
|
+
return cached.map(versionInfoToSelectItem);
|
|
691
|
+
};
|
|
704
692
|
|
|
705
|
-
//
|
|
706
|
-
const
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
693
|
+
// インストール済み情報は起動時にキャッシュ済み(FR-017)
|
|
694
|
+
const installedOption = () => {
|
|
695
|
+
const installed = getInstalledVersionCache(props.agentId);
|
|
696
|
+
return installed ? createInstalledOption(installed) : null;
|
|
697
|
+
};
|
|
710
698
|
|
|
711
|
-
// 全オプション(installed + latest +
|
|
699
|
+
// 全オプション(installed + latest + cached versions)
|
|
712
700
|
const allOptions = (): SelectInputItem[] => {
|
|
713
701
|
const options: SelectInputItem[] = [];
|
|
714
702
|
|
|
@@ -721,9 +709,9 @@ export function VersionSelectStep(props: VersionSelectStepProps) {
|
|
|
721
709
|
// latestオプション(常に表示)
|
|
722
710
|
options.push(LATEST_OPTION);
|
|
723
711
|
|
|
724
|
-
// npm
|
|
725
|
-
const
|
|
726
|
-
options.push(...
|
|
712
|
+
// FR-029: Use cached versions (no npm registry re-access)
|
|
713
|
+
const cached = cachedVersions();
|
|
714
|
+
options.push(...cached);
|
|
727
715
|
|
|
728
716
|
return options;
|
|
729
717
|
};
|
|
@@ -761,11 +749,11 @@ export function VersionSelectStep(props: VersionSelectStepProps) {
|
|
|
761
749
|
};
|
|
762
750
|
|
|
763
751
|
const statusText = () => {
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
if (
|
|
768
|
-
return "
|
|
752
|
+
// FR-029: No loading state since we use cached versions from startup
|
|
753
|
+
// FR-031: Show message if cache is empty (failed to fetch at startup)
|
|
754
|
+
const cached = cachedVersions();
|
|
755
|
+
if (cached.length === 0) {
|
|
756
|
+
return "Version list unavailable (using latest)";
|
|
769
757
|
}
|
|
770
758
|
return null;
|
|
771
759
|
};
|
package/src/cli/ui/core/theme.ts
CHANGED
|
@@ -33,6 +33,8 @@ export const colors = {
|
|
|
33
33
|
selected: "cyan",
|
|
34
34
|
highlighted: "cyan",
|
|
35
35
|
disabled: "gray",
|
|
36
|
+
selectionBackground: "cyan",
|
|
37
|
+
selectionText: "black",
|
|
36
38
|
|
|
37
39
|
// Branch type colors
|
|
38
40
|
branchFeature: "green",
|
|
@@ -64,6 +66,36 @@ export const colors = {
|
|
|
64
66
|
export type ColorName = keyof typeof colors;
|
|
65
67
|
export type ColorValue = (typeof colors)[ColorName];
|
|
66
68
|
|
|
69
|
+
export type LogLevelLabel =
|
|
70
|
+
| "TRACE"
|
|
71
|
+
| "DEBUG"
|
|
72
|
+
| "INFO"
|
|
73
|
+
| "WARN"
|
|
74
|
+
| "ERROR"
|
|
75
|
+
| "FATAL";
|
|
76
|
+
|
|
77
|
+
export const logLevelColors: Record<LogLevelLabel, ColorValue> = {
|
|
78
|
+
TRACE: colors.textDim,
|
|
79
|
+
DEBUG: colors.info,
|
|
80
|
+
INFO: colors.success,
|
|
81
|
+
WARN: colors.warning,
|
|
82
|
+
ERROR: colors.error,
|
|
83
|
+
FATAL: colors.error,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const selectionStyle = {
|
|
87
|
+
fg: colors.selectionText,
|
|
88
|
+
bg: colors.selectionBackground,
|
|
89
|
+
} as const;
|
|
90
|
+
|
|
91
|
+
export const getLogLevelColor = (label?: string | null): ColorValue => {
|
|
92
|
+
if (!label) {
|
|
93
|
+
return colors.text;
|
|
94
|
+
}
|
|
95
|
+
const normalized = label.toUpperCase() as LogLevelLabel;
|
|
96
|
+
return logLevelColors[normalized] ?? colors.text;
|
|
97
|
+
};
|
|
98
|
+
|
|
67
99
|
// ========================================
|
|
68
100
|
// Icon Definitions
|
|
69
101
|
// ========================================
|
|
@@ -32,12 +32,14 @@ export function useAsyncOperation<T, Args extends unknown[]>(
|
|
|
32
32
|
);
|
|
33
33
|
|
|
34
34
|
const isLoading = createMemo(() => state().status === "loading");
|
|
35
|
-
const error = createMemo(() =>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
const error = createMemo(() => {
|
|
36
|
+
const current = state();
|
|
37
|
+
return current.status === "error" ? current.error : null;
|
|
38
|
+
});
|
|
39
|
+
const data = createMemo(() => {
|
|
40
|
+
const current = state();
|
|
41
|
+
return current.status === "success" ? current.data : null;
|
|
42
|
+
});
|
|
41
43
|
|
|
42
44
|
const setState = (next: AsyncState<T>) => {
|
|
43
45
|
setStateInternal(next);
|
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
createWorktree,
|
|
6
6
|
generateWorktreePath,
|
|
7
7
|
removeWorktree,
|
|
8
|
-
} from "
|
|
9
|
-
import { deleteBranch, getRepositoryRoot } from "
|
|
8
|
+
} from "../../../../worktree.js";
|
|
9
|
+
import { deleteBranch, getRepositoryRoot } from "../../../../git.js";
|
|
10
10
|
|
|
11
11
|
export interface UseGitOperationsResult {
|
|
12
12
|
state: Accessor<AsyncState<unknown>>;
|
|
@@ -36,9 +36,10 @@ export function useGitOperations(): UseGitOperationsResult {
|
|
|
36
36
|
});
|
|
37
37
|
|
|
38
38
|
const isLoading = createMemo(() => state().status === "loading");
|
|
39
|
-
const error = createMemo(() =>
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
const error = createMemo(() => {
|
|
40
|
+
const current = state();
|
|
41
|
+
return current.status === "error" ? current.error : null;
|
|
42
|
+
});
|
|
42
43
|
|
|
43
44
|
const run = async <T>(operation: () => Promise<T>): Promise<T> => {
|
|
44
45
|
setState({ status: "loading" });
|