@akiojin/gwt 2.13.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +41 -0
- package/README.md +38 -0
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +17 -11
- package/dist/claude.js.map +1 -1
- package/dist/cli/ui/components/App.d.ts +0 -6
- package/dist/cli/ui/components/App.d.ts.map +1 -1
- package/dist/cli/ui/components/App.js +27 -88
- package/dist/cli/ui/components/App.js.map +1 -1
- package/dist/cli/ui/components/common/Select.js +2 -2
- package/dist/cli/ui/components/common/Select.js.map +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -1
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +3 -3
- package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +1 -1
- package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
- package/dist/cli/ui/utils/continueSession.js +1 -1
- package/dist/cli/ui/utils/continueSession.js.map +1 -1
- package/dist/client/assets/index-DsDNCy5f.css +1 -0
- package/dist/client/assets/index-f5D2XwDh.js +72 -0
- package/dist/client/index.html +2 -2
- package/dist/codex.d.ts.map +1 -1
- package/dist/codex.js +21 -11
- package/dist/codex.js.map +1 -1
- package/dist/config/builtin-tools.d.ts.map +1 -1
- package/dist/config/builtin-tools.js +3 -2
- package/dist/config/builtin-tools.js.map +1 -1
- package/dist/config/shared-env.d.ts +41 -0
- package/dist/config/shared-env.d.ts.map +1 -0
- package/dist/config/shared-env.js +114 -0
- package/dist/config/shared-env.js.map +1 -0
- package/dist/gemini.d.ts.map +1 -1
- package/dist/gemini.js +20 -17
- package/dist/gemini.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -8
- package/dist/index.js.map +1 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +4 -1
- package/dist/logging/logger.js.map +1 -1
- package/dist/qwen.d.ts.map +1 -1
- package/dist/qwen.js +15 -11
- package/dist/qwen.js.map +1 -1
- package/dist/services/aiToolResolver.d.ts +41 -0
- package/dist/services/aiToolResolver.d.ts.map +1 -0
- package/dist/services/aiToolResolver.js +194 -0
- package/dist/services/aiToolResolver.js.map +1 -0
- package/dist/services/customToolResolver.d.ts +10 -0
- package/dist/services/customToolResolver.d.ts.map +1 -0
- package/dist/services/customToolResolver.js +71 -0
- package/dist/services/customToolResolver.js.map +1 -0
- package/dist/shared/aiToolConstants.d.ts +9 -0
- package/dist/shared/aiToolConstants.d.ts.map +1 -0
- package/dist/shared/aiToolConstants.js +29 -0
- package/dist/shared/aiToolConstants.js.map +1 -0
- package/dist/types/tools.d.ts +12 -0
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/prompt.d.ts.map +1 -1
- package/dist/utils/prompt.js.map +1 -1
- package/dist/utils/session.d.ts.map +1 -1
- package/dist/utils/session.js +15 -6
- package/dist/utils/session.js.map +1 -1
- package/dist/utils/terminal.d.ts +12 -3
- package/dist/utils/terminal.d.ts.map +1 -1
- package/dist/utils/terminal.js +5 -34
- package/dist/utils/terminal.js.map +1 -1
- package/dist/utils/webui.d.ts +8 -0
- package/dist/utils/webui.d.ts.map +1 -0
- package/dist/utils/webui.js +35 -0
- package/dist/utils/webui.js.map +1 -0
- package/dist/web/client/src/components/AIToolLaunchModal.d.ts +9 -0
- package/dist/web/client/src/components/AIToolLaunchModal.d.ts.map +1 -0
- package/dist/web/client/src/components/AIToolLaunchModal.js +363 -0
- package/dist/web/client/src/components/AIToolLaunchModal.js.map +1 -0
- package/dist/web/client/src/components/BranchGraph.d.ts.map +1 -1
- package/dist/web/client/src/components/BranchGraph.js +46 -49
- package/dist/web/client/src/components/BranchGraph.js.map +1 -1
- package/dist/web/client/src/components/CustomToolForm.d.ts +23 -0
- package/dist/web/client/src/components/CustomToolForm.d.ts.map +1 -0
- package/dist/web/client/src/components/CustomToolForm.js +209 -0
- package/dist/web/client/src/components/CustomToolForm.js.map +1 -0
- package/dist/web/client/src/components/CustomToolList.d.ts +10 -0
- package/dist/web/client/src/components/CustomToolList.d.ts.map +1 -0
- package/dist/web/client/src/components/CustomToolList.js +57 -0
- package/dist/web/client/src/components/CustomToolList.js.map +1 -0
- package/dist/web/client/src/components/EnvEditor.d.ts.map +1 -1
- package/dist/web/client/src/components/EnvEditor.js +33 -26
- package/dist/web/client/src/components/EnvEditor.js.map +1 -1
- package/dist/web/client/src/components/EnvironmentEditor.d.ts +17 -0
- package/dist/web/client/src/components/EnvironmentEditor.d.ts.map +1 -0
- package/dist/web/client/src/components/EnvironmentEditor.js +22 -0
- package/dist/web/client/src/components/EnvironmentEditor.js.map +1 -0
- package/dist/web/client/src/components/Terminal.d.ts.map +1 -1
- package/dist/web/client/src/components/Terminal.js +10 -3
- package/dist/web/client/src/components/Terminal.js.map +1 -1
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts +10 -0
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +104 -0
- package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -0
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts +22 -0
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +79 -0
- package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -0
- package/dist/web/client/src/components/branch-detail/TerminalPanel.d.ts +11 -0
- package/dist/web/client/src/components/branch-detail/TerminalPanel.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/TerminalPanel.js +32 -0
- package/dist/web/client/src/components/branch-detail/TerminalPanel.js.map +1 -0
- package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +40 -0
- package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/ToolLauncher.js +147 -0
- package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -0
- package/dist/web/client/src/components/branch-detail/index.d.ts +5 -0
- package/dist/web/client/src/components/branch-detail/index.d.ts.map +1 -0
- package/dist/web/client/src/components/branch-detail/index.js +5 -0
- package/dist/web/client/src/components/branch-detail/index.js.map +1 -0
- package/dist/web/client/src/components/common/BranchCard.d.ts +17 -0
- package/dist/web/client/src/components/common/BranchCard.d.ts.map +1 -0
- package/dist/web/client/src/components/common/BranchCard.js +36 -0
- package/dist/web/client/src/components/common/BranchCard.js.map +1 -0
- package/dist/web/client/src/components/common/MetricCard.d.ts +10 -0
- package/dist/web/client/src/components/common/MetricCard.d.ts.map +1 -0
- package/dist/web/client/src/components/common/MetricCard.js +10 -0
- package/dist/web/client/src/components/common/MetricCard.js.map +1 -0
- package/dist/web/client/src/components/common/PageHeader.d.ts +12 -0
- package/dist/web/client/src/components/common/PageHeader.d.ts.map +1 -0
- package/dist/web/client/src/components/common/PageHeader.js +14 -0
- package/dist/web/client/src/components/common/PageHeader.js.map +1 -0
- package/dist/web/client/src/components/common/SearchInput.d.ts +14 -0
- package/dist/web/client/src/components/common/SearchInput.d.ts.map +1 -0
- package/dist/web/client/src/components/common/SearchInput.js +15 -0
- package/dist/web/client/src/components/common/SearchInput.js.map +1 -0
- package/dist/web/client/src/components/common/StatusBadge.d.ts +10 -0
- package/dist/web/client/src/components/common/StatusBadge.d.ts.map +1 -0
- package/dist/web/client/src/components/common/StatusBadge.js +15 -0
- package/dist/web/client/src/components/common/StatusBadge.js.map +1 -0
- package/dist/web/client/src/components/common/index.d.ts +6 -0
- package/dist/web/client/src/components/common/index.d.ts.map +1 -0
- package/dist/web/client/src/components/common/index.js +6 -0
- package/dist/web/client/src/components/common/index.js.map +1 -0
- package/dist/web/client/src/components/ui/alert.d.ts +9 -0
- package/dist/web/client/src/components/ui/alert.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/alert.js +25 -0
- package/dist/web/client/src/components/ui/alert.js.map +1 -0
- package/dist/web/client/src/components/ui/badge.d.ts +10 -0
- package/dist/web/client/src/components/ui/badge.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/badge.js +25 -0
- package/dist/web/client/src/components/ui/badge.js.map +1 -0
- package/dist/web/client/src/components/ui/button.d.ts +12 -0
- package/dist/web/client/src/components/ui/button.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/button.js +33 -0
- package/dist/web/client/src/components/ui/button.js.map +1 -0
- package/dist/web/client/src/components/ui/card.d.ts +9 -0
- package/dist/web/client/src/components/ui/card.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/card.js +16 -0
- package/dist/web/client/src/components/ui/card.js.map +1 -0
- package/dist/web/client/src/components/ui/index.d.ts +8 -0
- package/dist/web/client/src/components/ui/index.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/index.js +8 -0
- package/dist/web/client/src/components/ui/index.js.map +1 -0
- package/dist/web/client/src/components/ui/input.d.ts +4 -0
- package/dist/web/client/src/components/ui/input.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/input.js +8 -0
- package/dist/web/client/src/components/ui/input.js.map +1 -0
- package/dist/web/client/src/components/ui/select.d.ts +14 -0
- package/dist/web/client/src/components/ui/select.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/select.js +39 -0
- package/dist/web/client/src/components/ui/select.js.map +1 -0
- package/dist/web/client/src/components/ui/table.d.ts +11 -0
- package/dist/web/client/src/components/ui/table.d.ts.map +1 -0
- package/dist/web/client/src/components/ui/table.js +21 -0
- package/dist/web/client/src/components/ui/table.js.map +1 -0
- package/dist/web/client/src/hooks/useSessions.d.ts.map +1 -1
- package/dist/web/client/src/hooks/useSessions.js +6 -1
- package/dist/web/client/src/hooks/useSessions.js.map +1 -1
- package/dist/web/client/src/lib/utils.d.ts +7 -0
- package/dist/web/client/src/lib/utils.d.ts.map +1 -0
- package/dist/web/client/src/lib/utils.js +10 -0
- package/dist/web/client/src/lib/utils.js.map +1 -0
- package/dist/web/client/src/lib/websocket.d.ts +7 -0
- package/dist/web/client/src/lib/websocket.d.ts.map +1 -1
- package/dist/web/client/src/lib/websocket.js +44 -0
- package/dist/web/client/src/lib/websocket.js.map +1 -1
- package/dist/web/client/src/pages/BranchDetailPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/BranchDetailPage.js +125 -376
- package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
- package/dist/web/client/src/pages/BranchListPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/BranchListPage.js +89 -127
- package/dist/web/client/src/pages/BranchListPage.js.map +1 -1
- package/dist/web/client/src/pages/ConfigManagementPage.d.ts.map +1 -1
- package/dist/web/client/src/pages/ConfigManagementPage.js +46 -41
- package/dist/web/client/src/pages/ConfigManagementPage.js.map +1 -1
- package/dist/web/client/src/pages/ConfigPage.d.ts +3 -0
- package/dist/web/client/src/pages/ConfigPage.d.ts.map +1 -0
- package/dist/web/client/src/pages/ConfigPage.js +216 -0
- package/dist/web/client/src/pages/ConfigPage.js.map +1 -0
- package/dist/web/client/vite.config.d.ts.map +1 -1
- package/dist/web/client/vite.config.js +8 -1
- package/dist/web/client/vite.config.js.map +1 -1
- package/dist/web/server/index.d.ts +24 -2
- package/dist/web/server/index.d.ts.map +1 -1
- package/dist/web/server/index.js +46 -15
- package/dist/web/server/index.js.map +1 -1
- package/dist/web/server/pty/manager.d.ts +12 -10
- package/dist/web/server/pty/manager.d.ts.map +1 -1
- package/dist/web/server/pty/manager.js +76 -43
- package/dist/web/server/pty/manager.js.map +1 -1
- package/dist/web/server/routes/sessions.d.ts.map +1 -1
- package/dist/web/server/routes/sessions.js +35 -2
- package/dist/web/server/routes/sessions.js.map +1 -1
- package/dist/web/server/routes/worktrees.js +2 -2
- package/dist/web/server/routes/worktrees.js.map +1 -1
- package/dist/web/server/services/worktrees.d.ts.map +1 -1
- package/dist/web/server/services/worktrees.js +7 -1
- package/dist/web/server/services/worktrees.js.map +1 -1
- package/dist/web/server/tray.d.ts +25 -0
- package/dist/web/server/tray.d.ts.map +1 -0
- package/dist/web/server/tray.js +98 -0
- package/dist/web/server/tray.js.map +1 -0
- package/dist/web/server/websocket/handler.d.ts +18 -2
- package/dist/web/server/websocket/handler.d.ts.map +1 -1
- package/dist/web/server/websocket/handler.js +82 -9
- package/dist/web/server/websocket/handler.js.map +1 -1
- package/package.json +15 -2
- package/src/claude.ts +26 -15
- package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +1 -1
- package/src/cli/ui/__tests__/components/common/Select.test.tsx +11 -0
- package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +3 -1
- package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +4 -4
- package/src/cli/ui/components/App.tsx +33 -133
- package/src/cli/ui/components/common/Select.tsx +2 -2
- package/src/cli/ui/components/screens/BranchListScreen.tsx +28 -21
- package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +41 -46
- package/src/cli/ui/utils/continueSession.ts +1 -7
- package/src/codex.ts +31 -22
- package/src/config/builtin-tools.ts +6 -2
- package/src/config/shared-env.ts +139 -0
- package/src/gemini.ts +35 -22
- package/src/index.ts +13 -8
- package/src/logging/logger.ts +5 -2
- package/src/qwen.ts +28 -19
- package/src/services/aiToolResolver.ts +276 -0
- package/src/services/customToolResolver.ts +98 -0
- package/src/shared/aiToolConstants.ts +30 -0
- package/src/trayicon.d.ts +30 -0
- package/src/types/tools.ts +15 -0
- package/src/utils/prompt.ts +15 -9
- package/src/utils/session.ts +80 -26
- package/src/utils/terminal.ts +11 -41
- package/src/utils/webui.ts +43 -0
- package/src/web/client/components.json +21 -0
- package/src/web/client/src/components/AIToolLaunchModal.tsx +575 -0
- package/src/web/client/src/components/BranchGraph.tsx +95 -75
- package/src/web/client/src/components/CustomToolForm.tsx +386 -0
- package/src/web/client/src/components/CustomToolList.tsx +119 -0
- package/src/web/client/src/components/EnvEditor.tsx +91 -81
- package/src/web/client/src/components/EnvironmentEditor.tsx +97 -0
- package/src/web/client/src/components/Terminal.tsx +11 -3
- package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +179 -0
- package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +181 -0
- package/src/web/client/src/components/branch-detail/TerminalPanel.tsx +92 -0
- package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +327 -0
- package/src/web/client/src/components/branch-detail/index.ts +4 -0
- package/src/web/client/src/components/common/BranchCard.tsx +117 -0
- package/src/web/client/src/components/common/MetricCard.tsx +22 -0
- package/src/web/client/src/components/common/PageHeader.tsx +44 -0
- package/src/web/client/src/components/common/SearchInput.tsx +40 -0
- package/src/web/client/src/components/common/StatusBadge.tsx +37 -0
- package/src/web/client/src/components/common/index.ts +5 -0
- package/src/web/client/src/components/ui/alert.tsx +63 -0
- package/src/web/client/src/components/ui/badge.tsx +44 -0
- package/src/web/client/src/components/ui/button.tsx +57 -0
- package/src/web/client/src/components/ui/card.tsx +82 -0
- package/src/web/client/src/components/ui/index.ts +32 -0
- package/src/web/client/src/components/ui/input.tsx +21 -0
- package/src/web/client/src/components/ui/select.tsx +156 -0
- package/src/web/client/src/components/ui/table.tsx +119 -0
- package/src/web/client/src/hooks/useSessions.ts +10 -1
- package/src/web/client/src/index.css +46 -816
- package/src/web/client/src/lib/utils.ts +10 -0
- package/src/web/client/src/lib/websocket.ts +48 -1
- package/src/web/client/src/pages/BranchDetailPage.tsx +247 -723
- package/src/web/client/src/pages/BranchListPage.tsx +190 -236
- package/src/web/client/src/pages/ConfigManagementPage.tsx +94 -76
- package/src/web/client/src/pages/ConfigPage.tsx +362 -0
- package/src/web/client/vite.config.ts +8 -1
- package/src/web/server/index.ts +72 -15
- package/src/web/server/pty/manager.ts +128 -55
- package/src/web/server/routes/sessions.ts +59 -7
- package/src/web/server/routes/worktrees.ts +3 -3
- package/src/web/server/services/worktrees.ts +12 -4
- package/src/web/server/tray.ts +120 -0
- package/src/web/server/websocket/handler.ts +119 -13
- package/dist/client/assets/index-DeNwPosA.css +0 -1
- package/dist/client/assets/index-Dl798X5w.js +0 -32
package/src/claude.ts
CHANGED
|
@@ -51,6 +51,9 @@ export async function launchClaudeCode(
|
|
|
51
51
|
options.sessionId && options.sessionId.trim().length > 0
|
|
52
52
|
? options.sessionId.trim()
|
|
53
53
|
: null;
|
|
54
|
+
const usedExplicitSessionId =
|
|
55
|
+
Boolean(resumeSessionId) &&
|
|
56
|
+
(options.mode === "continue" || options.mode === "resume");
|
|
54
57
|
|
|
55
58
|
// Handle execution mode
|
|
56
59
|
switch (options.mode) {
|
|
@@ -173,14 +176,16 @@ export async function launchClaudeCode(
|
|
|
173
176
|
|
|
174
177
|
terminal.exitRawMode();
|
|
175
178
|
|
|
176
|
-
const baseEnv = {
|
|
177
|
-
|
|
178
|
-
...(options.envOverrides ?? {}),
|
|
179
|
-
};
|
|
180
|
-
const launchEnv =
|
|
179
|
+
const baseEnv = { ...process.env, ...(options.envOverrides ?? {}) };
|
|
180
|
+
const launchEnvSource =
|
|
181
181
|
options.skipPermissions && !baseEnv.IS_SANDBOX
|
|
182
182
|
? { ...baseEnv, IS_SANDBOX: "1" }
|
|
183
183
|
: baseEnv;
|
|
184
|
+
const launchEnv = Object.fromEntries(
|
|
185
|
+
Object.entries(launchEnvSource).filter(
|
|
186
|
+
(entry): entry is [string, string] => typeof entry[1] === "string",
|
|
187
|
+
),
|
|
188
|
+
);
|
|
184
189
|
|
|
185
190
|
const childStdio = createChildStdio();
|
|
186
191
|
|
|
@@ -199,7 +204,7 @@ export async function launchClaudeCode(
|
|
|
199
204
|
stdout: childStdio.stdout,
|
|
200
205
|
stderr: childStdio.stderr,
|
|
201
206
|
env: launchEnv,
|
|
202
|
-
}
|
|
207
|
+
});
|
|
203
208
|
} else {
|
|
204
209
|
console.log(
|
|
205
210
|
chalk.cyan(
|
|
@@ -233,7 +238,7 @@ export async function launchClaudeCode(
|
|
|
233
238
|
stdout: childStdio.stdout,
|
|
234
239
|
stderr: childStdio.stderr,
|
|
235
240
|
env: launchEnv,
|
|
236
|
-
}
|
|
241
|
+
});
|
|
237
242
|
}
|
|
238
243
|
} finally {
|
|
239
244
|
childStdio.cleanup();
|
|
@@ -250,10 +255,13 @@ export async function launchClaudeCode(
|
|
|
250
255
|
preferClosestTo: finishedAt,
|
|
251
256
|
windowMs: 10 * 60 * 1000,
|
|
252
257
|
});
|
|
253
|
-
|
|
254
|
-
|
|
258
|
+
const detectedSessionId = latest?.id ?? null;
|
|
259
|
+
// When we explicitly resumed a specific session, keep that ID as the source of truth.
|
|
260
|
+
capturedSessionId = usedExplicitSessionId
|
|
261
|
+
? resumeSessionId
|
|
262
|
+
: detectedSessionId;
|
|
255
263
|
} catch {
|
|
256
|
-
capturedSessionId = resumeSessionId
|
|
264
|
+
capturedSessionId = usedExplicitSessionId ? resumeSessionId : null;
|
|
257
265
|
}
|
|
258
266
|
|
|
259
267
|
if (capturedSessionId) {
|
|
@@ -270,11 +278,12 @@ export async function launchClaudeCode(
|
|
|
270
278
|
}
|
|
271
279
|
|
|
272
280
|
return capturedSessionId ? { sessionId: capturedSessionId } : {};
|
|
273
|
-
} catch (error:
|
|
281
|
+
} catch (error: unknown) {
|
|
274
282
|
const hasLocalClaude = await isClaudeCommandAvailable();
|
|
275
283
|
let errorMessage: string;
|
|
284
|
+
const err = error as NodeJS.ErrnoException;
|
|
276
285
|
|
|
277
|
-
if (
|
|
286
|
+
if (err.code === "ENOENT") {
|
|
278
287
|
if (hasLocalClaude) {
|
|
279
288
|
errorMessage =
|
|
280
289
|
"claude command not found. Please ensure Claude Code is properly installed.";
|
|
@@ -283,7 +292,8 @@ export async function launchClaudeCode(
|
|
|
283
292
|
"bunx command not found. Please ensure Bun is installed so Claude Code can run via bunx.";
|
|
284
293
|
}
|
|
285
294
|
} else {
|
|
286
|
-
|
|
295
|
+
const details = error instanceof Error ? error.message : String(error);
|
|
296
|
+
errorMessage = `Failed to launch Claude Code: ${details || "Unknown error"}`;
|
|
287
297
|
}
|
|
288
298
|
|
|
289
299
|
if (process.platform === "win32") {
|
|
@@ -344,8 +354,9 @@ export async function isClaudeCodeAvailable(): Promise<boolean> {
|
|
|
344
354
|
try {
|
|
345
355
|
await execa("bunx", [CLAUDE_CLI_PACKAGE, "--version"], { shell: true });
|
|
346
356
|
return true;
|
|
347
|
-
} catch (error:
|
|
348
|
-
|
|
357
|
+
} catch (error: unknown) {
|
|
358
|
+
const err = error as NodeJS.ErrnoException;
|
|
359
|
+
if (err.code === "ENOENT") {
|
|
349
360
|
console.error(chalk.yellow("\n⚠️ bunx command not found"));
|
|
350
361
|
console.error(
|
|
351
362
|
chalk.gray(
|
|
@@ -203,7 +203,7 @@ describe("App protected branch handling", () => {
|
|
|
203
203
|
remoteRef: null,
|
|
204
204
|
});
|
|
205
205
|
|
|
206
|
-
expect(navigateToMock).toHaveBeenCalledWith("branch-
|
|
206
|
+
expect(navigateToMock).toHaveBeenCalledWith("branch-action-selector");
|
|
207
207
|
expect(branchQuickStartProps).not.toHaveLength(0);
|
|
208
208
|
});
|
|
209
209
|
});
|
|
@@ -183,6 +183,17 @@ describe("Select", () => {
|
|
|
183
183
|
expect(onSelect).toHaveBeenCalled();
|
|
184
184
|
});
|
|
185
185
|
|
|
186
|
+
it("should call onSelect when linefeed is pressed (cooked mode Enter)", () => {
|
|
187
|
+
const onSelect = vi.fn();
|
|
188
|
+
const { stdin } = render(
|
|
189
|
+
<Select items={mockItems} onSelect={onSelect} />,
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
stdin.write("\n"); // Linefeed key
|
|
193
|
+
|
|
194
|
+
expect(onSelect).toHaveBeenCalled();
|
|
195
|
+
});
|
|
196
|
+
|
|
186
197
|
it("should pass selected item to onSelect callback", () => {
|
|
187
198
|
const onSelect = vi.fn();
|
|
188
199
|
render(<Select items={mockItems} onSelect={onSelect} initialIndex={2} />);
|
|
@@ -431,7 +431,9 @@ describe("BranchListScreen", () => {
|
|
|
431
431
|
stdin.write(" ");
|
|
432
432
|
});
|
|
433
433
|
|
|
434
|
-
const frame = stripControlSequences(
|
|
434
|
+
const frame = stripControlSequences(
|
|
435
|
+
stripAnsi(renderResult.lastFrame() ?? ""),
|
|
436
|
+
);
|
|
435
437
|
expect(frame).toContain("[*] 🟢 🛡");
|
|
436
438
|
expect(frame).toContain("feature/login");
|
|
437
439
|
});
|
|
@@ -66,9 +66,7 @@ describe("BranchQuickStartScreen", () => {
|
|
|
66
66
|
/>,
|
|
67
67
|
);
|
|
68
68
|
|
|
69
|
-
expect(
|
|
70
|
-
getByText(/Model: opus \/ Skip: No \/ ID: abc-123/),
|
|
71
|
-
).toBeDefined();
|
|
69
|
+
expect(getByText(/Model: opus \/ Skip: No \/ ID: abc-123/)).toBeDefined();
|
|
72
70
|
});
|
|
73
71
|
|
|
74
72
|
it("disables previous options when no history", () => {
|
|
@@ -132,7 +130,9 @@ describe("BranchQuickStartScreen", () => {
|
|
|
132
130
|
|
|
133
131
|
expect(getAllByText(/\[Codex\]/i)).toHaveLength(2);
|
|
134
132
|
expect(
|
|
135
|
-
getByText(
|
|
133
|
+
getByText(
|
|
134
|
+
/Model: gpt-5.1-codex \/ Reasoning: High \/ Skip: Yes \/ ID: codex-123/,
|
|
135
|
+
),
|
|
136
136
|
).toBeDefined();
|
|
137
137
|
expect(getAllByText(/\[Claude\]/i)).toHaveLength(2);
|
|
138
138
|
expect(
|
|
@@ -11,7 +11,6 @@ import { BranchListScreen } from "./screens/BranchListScreen.js";
|
|
|
11
11
|
import { BranchCreatorScreen } from "./screens/BranchCreatorScreen.js";
|
|
12
12
|
import { BranchActionSelectorScreen } from "../screens/BranchActionSelectorScreen.js";
|
|
13
13
|
import { AIToolSelectorScreen } from "./screens/AIToolSelectorScreen.js";
|
|
14
|
-
import { SessionSelectorScreen } from "./screens/SessionSelectorScreen.js";
|
|
15
14
|
import { ExecutionModeSelectorScreen } from "./screens/ExecutionModeSelectorScreen.js";
|
|
16
15
|
import type { ExecutionMode } from "./screens/ExecutionModeSelectorScreen.js";
|
|
17
16
|
import { BranchQuickStartScreen } from "./screens/BranchQuickStartScreen.js";
|
|
@@ -93,13 +92,6 @@ export interface AppProps {
|
|
|
93
92
|
loadingIndicatorDelay?: number;
|
|
94
93
|
}
|
|
95
94
|
|
|
96
|
-
export interface SessionOption {
|
|
97
|
-
sessionId: string;
|
|
98
|
-
toolLabel: string;
|
|
99
|
-
branch: string;
|
|
100
|
-
timestamp: number;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
95
|
/**
|
|
104
96
|
* App - Top-level component for Ink.js UI
|
|
105
97
|
* Integrates ErrorBoundary, data fetching, screen navigation, and all screens
|
|
@@ -119,13 +111,6 @@ export function App({ onExit, loadingIndicatorDelay = 300 }: AppProps) {
|
|
|
119
111
|
// Version state
|
|
120
112
|
const [version, setVersion] = useState<string | null>(null);
|
|
121
113
|
const [repoRoot, setRepoRoot] = useState<string | null>(null);
|
|
122
|
-
const [sessionOptions, setSessionOptions] = useState<SessionOption[]>([]);
|
|
123
|
-
const [sessionLoading, setSessionLoading] = useState(false);
|
|
124
|
-
const [sessionError, setSessionError] = useState<string | null>(null);
|
|
125
|
-
const [pendingExecution, setPendingExecution] = useState<{
|
|
126
|
-
mode: ExecutionMode;
|
|
127
|
-
skipPermissions: boolean;
|
|
128
|
-
} | null>(null);
|
|
129
114
|
const [continueSessionId, setContinueSessionId] = useState<string | null>(
|
|
130
115
|
null,
|
|
131
116
|
);
|
|
@@ -140,8 +125,7 @@ export function App({ onExit, loadingIndicatorDelay = 300 }: AppProps) {
|
|
|
140
125
|
timestamp?: number | null;
|
|
141
126
|
}[]
|
|
142
127
|
>([]);
|
|
143
|
-
const [branchQuickStartLoading, setBranchQuickStartLoading] =
|
|
144
|
-
useState(false);
|
|
128
|
+
const [branchQuickStartLoading, setBranchQuickStartLoading] = useState(false);
|
|
145
129
|
|
|
146
130
|
// Selection state (for branch → tool → mode flow)
|
|
147
131
|
const [selectedBranch, setSelectedBranch] =
|
|
@@ -274,9 +258,7 @@ export function App({ onExit, loadingIndicatorDelay = 300 }: AppProps) {
|
|
|
274
258
|
if (cancelled) return;
|
|
275
259
|
const safe = new Set(
|
|
276
260
|
targets
|
|
277
|
-
.filter(
|
|
278
|
-
(t) => !t.hasUncommittedChanges && !t.hasUnpushedCommits,
|
|
279
|
-
)
|
|
261
|
+
.filter((t) => !t.hasUncommittedChanges && !t.hasUnpushedCommits)
|
|
280
262
|
.map((t) => t.branch),
|
|
281
263
|
);
|
|
282
264
|
setSafeBranches(safe);
|
|
@@ -290,53 +272,6 @@ export function App({ onExit, loadingIndicatorDelay = 300 }: AppProps) {
|
|
|
290
272
|
};
|
|
291
273
|
}, [branches, worktrees]);
|
|
292
274
|
|
|
293
|
-
// Load available sessions when entering session selector
|
|
294
|
-
useEffect(() => {
|
|
295
|
-
if (currentScreen !== "session-selector") {
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
if (!selectedTool || !selectedBranch) {
|
|
299
|
-
setSessionOptions([]);
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
setSessionLoading(true);
|
|
304
|
-
setSessionError(null);
|
|
305
|
-
|
|
306
|
-
(async () => {
|
|
307
|
-
try {
|
|
308
|
-
const root = repoRoot ?? (await getRepositoryRoot());
|
|
309
|
-
if (!repoRoot && root) {
|
|
310
|
-
setRepoRoot(root);
|
|
311
|
-
}
|
|
312
|
-
const sessionData = root ? await loadSession(root) : null;
|
|
313
|
-
const history = sessionData?.history ?? [];
|
|
314
|
-
|
|
315
|
-
const filtered = history
|
|
316
|
-
.filter(
|
|
317
|
-
(entry) =>
|
|
318
|
-
entry.sessionId &&
|
|
319
|
-
entry.toolId === selectedTool &&
|
|
320
|
-
entry.branch === selectedBranch.name,
|
|
321
|
-
)
|
|
322
|
-
.sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0))
|
|
323
|
-
.map((entry) => ({
|
|
324
|
-
sessionId: entry.sessionId as string,
|
|
325
|
-
toolLabel: entry.toolLabel,
|
|
326
|
-
branch: entry.branch,
|
|
327
|
-
timestamp: entry.timestamp,
|
|
328
|
-
}));
|
|
329
|
-
|
|
330
|
-
setSessionOptions(filtered);
|
|
331
|
-
} catch (_err) {
|
|
332
|
-
setSessionOptions([]);
|
|
333
|
-
setSessionError("セッション一覧の取得に失敗しました");
|
|
334
|
-
} finally {
|
|
335
|
-
setSessionLoading(false);
|
|
336
|
-
}
|
|
337
|
-
})();
|
|
338
|
-
}, [currentScreen, selectedTool, selectedBranch, repoRoot]);
|
|
339
|
-
|
|
340
275
|
// Load quick start options for selected branch (latest per tool)
|
|
341
276
|
useEffect(() => {
|
|
342
277
|
if (!selectedBranch) {
|
|
@@ -387,60 +322,55 @@ export function App({ onExit, loadingIndicatorDelay = 300 }: AppProps) {
|
|
|
387
322
|
const mapped = await Promise.all(
|
|
388
323
|
latestPerTool.map(async (entry) => {
|
|
389
324
|
let sessionId = entry.sessionId ?? null;
|
|
325
|
+
const worktree = selectedWorktreePath ?? workingDirectory;
|
|
390
326
|
|
|
391
327
|
// For Codex, prefer a newer filesystem session over stale history
|
|
392
|
-
if (entry.toolId === "codex-cli") {
|
|
328
|
+
if (!sessionId && entry.toolId === "codex-cli") {
|
|
393
329
|
try {
|
|
394
|
-
const
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
330
|
+
const historyTs = entry.timestamp ?? null;
|
|
331
|
+
const latestCodex = await findLatestCodexSession({
|
|
332
|
+
...(historyTs
|
|
333
|
+
? {
|
|
334
|
+
since: historyTs - 60_000,
|
|
335
|
+
preferClosestTo: historyTs,
|
|
336
|
+
windowMs: 60 * 60 * 1000,
|
|
337
|
+
}
|
|
338
|
+
: {}),
|
|
339
|
+
cwd: worktree,
|
|
340
|
+
});
|
|
341
|
+
sessionId =
|
|
342
|
+
latestCodex?.id ??
|
|
343
|
+
(await findLatestCodexSessionId({ cwd: worktree })) ??
|
|
344
|
+
null;
|
|
407
345
|
} catch {
|
|
408
346
|
// ignore lookup failure
|
|
409
347
|
}
|
|
410
348
|
}
|
|
411
349
|
|
|
412
350
|
// For Claude Code, prefer the newest session file in the worktree even if history is stale.
|
|
413
|
-
if (entry.toolId === "claude-code") {
|
|
351
|
+
if (!sessionId && entry.toolId === "claude-code") {
|
|
414
352
|
try {
|
|
415
|
-
const worktree =
|
|
416
|
-
selectedWorktreePath ??
|
|
417
|
-
selectedBranch?.displayName ??
|
|
418
|
-
workingDirectory;
|
|
419
|
-
|
|
420
353
|
// Always resolve freshest on-disk session for this worktree (no window restriction)
|
|
421
354
|
const latestAny = await findLatestClaudeSession(worktree);
|
|
422
|
-
sessionId = latestAny?.id ??
|
|
423
|
-
|
|
355
|
+
sessionId = latestAny?.id ?? null;
|
|
424
356
|
} catch {
|
|
425
357
|
// ignore lookup failure
|
|
426
358
|
}
|
|
427
359
|
}
|
|
428
360
|
|
|
429
361
|
// For Gemini, prefer newest session file (Gemini keeps per-project chats)
|
|
430
|
-
if (entry.toolId === "gemini-cli") {
|
|
362
|
+
if (!sessionId && entry.toolId === "gemini-cli") {
|
|
431
363
|
try {
|
|
432
|
-
const gemSession = await findLatestGeminiSession(
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
);
|
|
443
|
-
if (gemSession?.id) sessionId = gemSession.id;
|
|
364
|
+
const gemSession = await findLatestGeminiSession(worktree, {
|
|
365
|
+
...(entry.timestamp !== null && entry.timestamp !== undefined
|
|
366
|
+
? {
|
|
367
|
+
since: entry.timestamp - 60_000,
|
|
368
|
+
preferClosestTo: entry.timestamp,
|
|
369
|
+
}
|
|
370
|
+
: {}),
|
|
371
|
+
windowMs: 60 * 60 * 1000,
|
|
372
|
+
});
|
|
373
|
+
sessionId = gemSession?.id ?? null;
|
|
444
374
|
} catch {
|
|
445
375
|
// ignore
|
|
446
376
|
}
|
|
@@ -1165,18 +1095,6 @@ export function App({ onExit, loadingIndicatorDelay = 300 }: AppProps) {
|
|
|
1165
1095
|
],
|
|
1166
1096
|
);
|
|
1167
1097
|
|
|
1168
|
-
// Handle session selection
|
|
1169
|
-
const handleSessionSelect = useCallback(
|
|
1170
|
-
(session: string) => {
|
|
1171
|
-
const execution = pendingExecution ?? {
|
|
1172
|
-
mode: "resume" as ExecutionMode,
|
|
1173
|
-
skipPermissions: false,
|
|
1174
|
-
};
|
|
1175
|
-
completeSelection(execution.mode, execution.skipPermissions, session);
|
|
1176
|
-
},
|
|
1177
|
-
[pendingExecution, completeSelection],
|
|
1178
|
-
);
|
|
1179
|
-
|
|
1180
1098
|
const handleQuickStartSelect = useCallback(
|
|
1181
1099
|
(action: QuickStartAction, toolId?: AITool | null) => {
|
|
1182
1100
|
if (action === "manual" || !branchQuickStart.length) {
|
|
@@ -1228,14 +1146,9 @@ export function App({ onExit, loadingIndicatorDelay = 300 }: AppProps) {
|
|
|
1228
1146
|
// Handle execution mode and skipPermissions selection
|
|
1229
1147
|
const handleModeSelect = useCallback(
|
|
1230
1148
|
(result: { mode: ExecutionMode; skipPermissions: boolean }) => {
|
|
1231
|
-
if (result.mode === "resume") {
|
|
1232
|
-
setPendingExecution(result);
|
|
1233
|
-
navigateTo("session-selector");
|
|
1234
|
-
return;
|
|
1235
|
-
}
|
|
1236
1149
|
completeSelection(result.mode, result.skipPermissions, null);
|
|
1237
1150
|
},
|
|
1238
|
-
[completeSelection
|
|
1151
|
+
[completeSelection],
|
|
1239
1152
|
);
|
|
1240
1153
|
|
|
1241
1154
|
// Render screen based on currentScreen
|
|
@@ -1345,19 +1258,6 @@ export function App({ onExit, loadingIndicatorDelay = 300 }: AppProps) {
|
|
|
1345
1258
|
/>
|
|
1346
1259
|
);
|
|
1347
1260
|
|
|
1348
|
-
case "session-selector":
|
|
1349
|
-
// TODO: Implement session data fetching
|
|
1350
|
-
return (
|
|
1351
|
-
<SessionSelectorScreen
|
|
1352
|
-
sessions={sessionOptions}
|
|
1353
|
-
loading={sessionLoading}
|
|
1354
|
-
errorMessage={sessionError}
|
|
1355
|
-
onBack={goBack}
|
|
1356
|
-
onSelect={handleSessionSelect}
|
|
1357
|
-
version={version}
|
|
1358
|
-
/>
|
|
1359
|
-
);
|
|
1360
|
-
|
|
1361
1261
|
case "execution-mode-selector":
|
|
1362
1262
|
return (
|
|
1363
1263
|
<ExecutionModeSelectorScreen
|
|
@@ -164,8 +164,8 @@ const SelectComponent = <T extends SelectItem = SelectItem>({
|
|
|
164
164
|
|
|
165
165
|
return newIndex;
|
|
166
166
|
});
|
|
167
|
-
} else if (key.return) {
|
|
168
|
-
// Select current item
|
|
167
|
+
} else if (key.return || input === "\n") {
|
|
168
|
+
// Select current item (handle both CR in raw mode and LF in cooked mode)
|
|
169
169
|
const selectedItem = items[selectedIndex];
|
|
170
170
|
if (selectedItem && !disabled) {
|
|
171
171
|
onSelect(selectedItem);
|
|
@@ -125,9 +125,11 @@ export function BranchListScreen({
|
|
|
125
125
|
onToggleSelect,
|
|
126
126
|
}: BranchListScreenProps) {
|
|
127
127
|
const { rows } = useTerminalSize();
|
|
128
|
-
const headerText =
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
const headerText = " Legend: [ ]/[ * ] select 🟢/⚪ worktree 🛡/⚠ safe";
|
|
129
|
+
const selectedSet = useMemo(
|
|
130
|
+
() => new Set(selectedBranches),
|
|
131
|
+
[selectedBranches],
|
|
132
|
+
);
|
|
131
133
|
|
|
132
134
|
// Filter state - allow test control via props
|
|
133
135
|
const [internalFilterQuery, setInternalFilterQuery] = useState("");
|
|
@@ -308,25 +310,28 @@ export function BranchListScreen({
|
|
|
308
310
|
return result + ellipsis;
|
|
309
311
|
}, []);
|
|
310
312
|
|
|
311
|
-
const colorToolLabel = useCallback(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
313
|
+
const colorToolLabel = useCallback(
|
|
314
|
+
(label: string, toolId?: string | null) => {
|
|
315
|
+
switch (toolId) {
|
|
316
|
+
case "claude-code":
|
|
317
|
+
return chalk.hex("#ffaf00")(label); // orange-ish
|
|
318
|
+
case "codex-cli":
|
|
319
|
+
return chalk.cyan(label);
|
|
320
|
+
case "gemini-cli":
|
|
321
|
+
return chalk.magenta(label);
|
|
322
|
+
case "qwen-cli":
|
|
323
|
+
return chalk.green(label);
|
|
324
|
+
default: {
|
|
325
|
+
const trimmed = label.trim().toLowerCase();
|
|
326
|
+
if (!toolId || trimmed === "unknown") {
|
|
327
|
+
return chalk.gray(label);
|
|
328
|
+
}
|
|
329
|
+
return chalk.white(label);
|
|
325
330
|
}
|
|
326
|
-
return chalk.white(label);
|
|
327
331
|
}
|
|
328
|
-
}
|
|
329
|
-
|
|
332
|
+
},
|
|
333
|
+
[],
|
|
334
|
+
);
|
|
330
335
|
|
|
331
336
|
const renderBranchRow = useCallback(
|
|
332
337
|
(item: BranchItem, isSelected: boolean, context: { columns: number }) => {
|
|
@@ -450,7 +455,9 @@ export function BranchListScreen({
|
|
|
450
455
|
|
|
451
456
|
// 端末幅を超えた場合は隙間→ラベルの順で詰めて収める
|
|
452
457
|
const clampToWidth = () => {
|
|
453
|
-
const finalWidth = measureDisplayWidth(
|
|
458
|
+
const finalWidth = measureDisplayWidth(
|
|
459
|
+
stripAnsi(lineWithColoredTimestamp),
|
|
460
|
+
);
|
|
454
461
|
if (finalWidth <= columns) {
|
|
455
462
|
return;
|
|
456
463
|
}
|
|
@@ -25,13 +25,12 @@ const REASONING_LABELS: Record<string, string> = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const formatReasoning = (level?: string | null) =>
|
|
28
|
-
level ? REASONING_LABELS[level] ?? level : "Default";
|
|
28
|
+
level ? (REASONING_LABELS[level] ?? level) : "Default";
|
|
29
29
|
|
|
30
30
|
const formatSkip = (skip?: boolean | null) =>
|
|
31
31
|
skip === true ? "Yes" : skip === false ? "No" : "No";
|
|
32
32
|
|
|
33
|
-
const supportsReasoning = (toolId?: string | null) =>
|
|
34
|
-
toolId === "codex-cli";
|
|
33
|
+
const supportsReasoning = (toolId?: string | null) => toolId === "codex-cli";
|
|
35
34
|
|
|
36
35
|
const describe = (opt: BranchQuickStartOption, includeSessionId = true) => {
|
|
37
36
|
const parts = [`Model: ${opt.model ?? "default"}`];
|
|
@@ -103,45 +102,45 @@ export function BranchQuickStartScreen({
|
|
|
103
102
|
const items: QuickStartItem[] = previousOptions.length
|
|
104
103
|
? (() => {
|
|
105
104
|
const order = ["Claude", "Codex", "Gemini", "Qwen", "Other"];
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
105
|
+
const sorted = [...previousOptions].sort((a, b) => {
|
|
106
|
+
const ca = resolveCategory(a.toolId).label;
|
|
107
|
+
const cb = resolveCategory(b.toolId).label;
|
|
108
|
+
return order.indexOf(ca) - order.indexOf(cb);
|
|
109
|
+
});
|
|
111
110
|
|
|
112
|
-
|
|
111
|
+
const flat: QuickStartItem[] = [];
|
|
113
112
|
sorted.forEach((opt, idx) => {
|
|
114
113
|
const cat = resolveCategory(opt.toolId);
|
|
115
114
|
const prevCat =
|
|
116
115
|
idx > 0 ? resolveCategory(sorted[idx - 1]?.toolId).label : null;
|
|
117
116
|
const isNewCategory = prevCat !== cat.label;
|
|
118
117
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
118
|
+
flat.push(
|
|
119
|
+
{
|
|
120
|
+
label: "Resume",
|
|
121
|
+
value: `reuse-continue:${opt.toolId ?? "unknown"}:${idx}`,
|
|
122
|
+
action: "reuse-continue",
|
|
123
|
+
toolId: opt.toolId ?? null,
|
|
124
|
+
description: describe(opt, true),
|
|
125
|
+
groupStart: isNewCategory && flat.length > 0,
|
|
126
|
+
category: cat.label,
|
|
127
|
+
categoryColor: cat.color,
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
label: "New",
|
|
131
|
+
value: `reuse-new:${opt.toolId ?? "unknown"}:${idx}`,
|
|
132
|
+
action: "reuse-new",
|
|
133
|
+
toolId: opt.toolId ?? null,
|
|
134
|
+
description: describe(opt, false),
|
|
135
|
+
groupStart: false,
|
|
136
|
+
category: cat.label,
|
|
137
|
+
categoryColor: cat.color,
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
return flat;
|
|
143
|
+
})()
|
|
145
144
|
: [
|
|
146
145
|
{
|
|
147
146
|
label: "Resume with previous settings",
|
|
@@ -180,11 +179,7 @@ export function BranchQuickStartScreen({
|
|
|
180
179
|
|
|
181
180
|
return (
|
|
182
181
|
<Box flexDirection="column" height={containerHeight}>
|
|
183
|
-
<Header
|
|
184
|
-
title="Quick Start"
|
|
185
|
-
titleColor="cyan"
|
|
186
|
-
version={version}
|
|
187
|
-
/>
|
|
182
|
+
<Header title="Quick Start" titleColor="cyan" version={version} />
|
|
188
183
|
|
|
189
184
|
<Box flexDirection="column" flexGrow={1} marginTop={1}>
|
|
190
185
|
<Box marginBottom={1} flexDirection="column">
|
|
@@ -197,6 +192,7 @@ export function BranchQuickStartScreen({
|
|
|
197
192
|
</Box>
|
|
198
193
|
<Select
|
|
199
194
|
items={items}
|
|
195
|
+
disabled={loading}
|
|
200
196
|
onSelect={(item: QuickStartItem) => {
|
|
201
197
|
if (item.disabled) return;
|
|
202
198
|
onSelect(item.action, item.toolId ?? null);
|
|
@@ -204,13 +200,12 @@ export function BranchQuickStartScreen({
|
|
|
204
200
|
renderItem={(item: QuickStartItem, isSelected) => (
|
|
205
201
|
<Box
|
|
206
202
|
flexDirection="column"
|
|
207
|
-
marginTop={
|
|
203
|
+
marginTop={
|
|
204
|
+
item.groupStart ? 1 : item.category === "Other" ? 1 : 0
|
|
205
|
+
}
|
|
208
206
|
>
|
|
209
207
|
<Text>
|
|
210
|
-
<Text
|
|
211
|
-
color={item.categoryColor}
|
|
212
|
-
inverse={isSelected}
|
|
213
|
-
>
|
|
208
|
+
<Text color={item.categoryColor} inverse={isSelected}>
|
|
214
209
|
{`[${item.category}] `}
|
|
215
210
|
</Text>
|
|
216
211
|
<Text inverse={isSelected}>
|
|
@@ -219,7 +214,7 @@ export function BranchQuickStartScreen({
|
|
|
219
214
|
</Text>
|
|
220
215
|
</Text>
|
|
221
216
|
{item.description && (
|
|
222
|
-
<Text color="gray">
|
|
217
|
+
<Text color="gray"> {item.description}</Text>
|
|
223
218
|
)}
|
|
224
219
|
</Box>
|
|
225
220
|
)}
|
|
@@ -17,13 +17,7 @@ export interface ContinueSessionContext {
|
|
|
17
17
|
export async function resolveContinueSessionId(
|
|
18
18
|
context: ContinueSessionContext,
|
|
19
19
|
): Promise<string | null> {
|
|
20
|
-
const {
|
|
21
|
-
history,
|
|
22
|
-
sessionData,
|
|
23
|
-
branch,
|
|
24
|
-
toolId,
|
|
25
|
-
repoRoot,
|
|
26
|
-
} = context;
|
|
20
|
+
const { history, sessionData, branch, toolId, repoRoot: _repoRoot } = context;
|
|
27
21
|
|
|
28
22
|
// 1) 履歴から最新マッチを探す(末尾から遡る)
|
|
29
23
|
for (let i = history.length - 1; i >= 0; i -= 1) {
|