@akiojin/gwt 2.13.0 → 2.14.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 +33 -0
- package/README.md +31 -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 +14 -2
- 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-DPWWHorC.js +72 -0
- package/dist/client/assets/index-DsDNCy5f.css +1 -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 +49 -7
- 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 +113 -361
- 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 +24 -0
- package/dist/web/server/tray.d.ts.map +1 -0
- package/dist/web/server/tray.js +79 -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/common/Select.test.tsx +11 -0
- package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +17 -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 +43 -23
- 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 +54 -7
- 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 +222 -694
- 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 +93 -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/logging/logger.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface LoggerConfig {
|
|
|
17
17
|
sync?: boolean;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
21
|
* Create a pino logger with unified structure and category field.
|
|
22
22
|
* - Writes to a single file stream (no per-component files)
|
|
23
23
|
* - Adds `category` to each log record
|
|
@@ -51,7 +51,10 @@ export function createLogger(config: LoggerConfig = {}): Logger {
|
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
if (config.sync) {
|
|
54
|
-
const destinationStream = pino.destination({
|
|
54
|
+
const destinationStream = pino.destination({
|
|
55
|
+
dest: destination,
|
|
56
|
+
sync: true,
|
|
57
|
+
});
|
|
55
58
|
return pino(options, destinationStream);
|
|
56
59
|
}
|
|
57
60
|
|
package/src/qwen.ts
CHANGED
|
@@ -52,6 +52,9 @@ export async function launchQwenCLI(
|
|
|
52
52
|
options.sessionId && options.sessionId.trim().length > 0
|
|
53
53
|
? options.sessionId.trim()
|
|
54
54
|
: null;
|
|
55
|
+
const usedExplicitSessionId =
|
|
56
|
+
Boolean(resumeSessionId) &&
|
|
57
|
+
(options.mode === "continue" || options.mode === "resume");
|
|
55
58
|
switch (options.mode) {
|
|
56
59
|
case "continue":
|
|
57
60
|
console.log(
|
|
@@ -94,10 +97,14 @@ export async function launchQwenCLI(
|
|
|
94
97
|
|
|
95
98
|
terminal.exitRawMode();
|
|
96
99
|
|
|
97
|
-
const baseEnv =
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
100
|
+
const baseEnv = Object.fromEntries(
|
|
101
|
+
Object.entries({
|
|
102
|
+
...process.env,
|
|
103
|
+
...(options.envOverrides ?? {}),
|
|
104
|
+
}).filter(
|
|
105
|
+
(entry): entry is [string, string] => typeof entry[1] === "string",
|
|
106
|
+
),
|
|
107
|
+
);
|
|
101
108
|
|
|
102
109
|
const childStdio = createChildStdio();
|
|
103
110
|
|
|
@@ -105,12 +112,13 @@ export async function launchQwenCLI(
|
|
|
105
112
|
const hasLocalQwen = await isQwenCommandAvailable();
|
|
106
113
|
|
|
107
114
|
try {
|
|
108
|
-
const execChild = async (child:
|
|
115
|
+
const execChild = async (child: Promise<unknown>) => {
|
|
109
116
|
try {
|
|
110
117
|
await child;
|
|
111
|
-
} catch (execError:
|
|
118
|
+
} catch (execError: unknown) {
|
|
112
119
|
// Treat SIGINT/SIGTERM as normal exit (user pressed Ctrl+C)
|
|
113
|
-
|
|
120
|
+
const signal = (execError as { signal?: unknown })?.signal;
|
|
121
|
+
if (signal === "SIGINT" || signal === "SIGTERM") {
|
|
114
122
|
return;
|
|
115
123
|
}
|
|
116
124
|
throw execError;
|
|
@@ -127,7 +135,7 @@ export async function launchQwenCLI(
|
|
|
127
135
|
stdout: childStdio.stdout,
|
|
128
136
|
stderr: childStdio.stderr,
|
|
129
137
|
env: baseEnv,
|
|
130
|
-
}
|
|
138
|
+
});
|
|
131
139
|
await execChild(child);
|
|
132
140
|
} else {
|
|
133
141
|
// Fallback to bunx
|
|
@@ -150,7 +158,7 @@ export async function launchQwenCLI(
|
|
|
150
158
|
stdout: childStdio.stdout,
|
|
151
159
|
stderr: childStdio.stderr,
|
|
152
160
|
env: baseEnv,
|
|
153
|
-
}
|
|
161
|
+
});
|
|
154
162
|
await execChild(child);
|
|
155
163
|
}
|
|
156
164
|
} finally {
|
|
@@ -159,12 +167,10 @@ export async function launchQwenCLI(
|
|
|
159
167
|
|
|
160
168
|
let capturedSessionId: string | null = null;
|
|
161
169
|
try {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
resumeSessionId ??
|
|
165
|
-
null;
|
|
170
|
+
const detected = (await findLatestQwenSessionId(worktreePath)) ?? null;
|
|
171
|
+
capturedSessionId = usedExplicitSessionId ? resumeSessionId : detected;
|
|
166
172
|
} catch {
|
|
167
|
-
capturedSessionId = resumeSessionId
|
|
173
|
+
capturedSessionId = usedExplicitSessionId ? resumeSessionId : null;
|
|
168
174
|
}
|
|
169
175
|
|
|
170
176
|
if (capturedSessionId) {
|
|
@@ -181,11 +187,12 @@ export async function launchQwenCLI(
|
|
|
181
187
|
}
|
|
182
188
|
|
|
183
189
|
return capturedSessionId ? { sessionId: capturedSessionId } : {};
|
|
184
|
-
} catch (error:
|
|
190
|
+
} catch (error: unknown) {
|
|
185
191
|
const hasLocalQwen = await isQwenCommandAvailable();
|
|
186
192
|
let errorMessage: string;
|
|
193
|
+
const err = error as NodeJS.ErrnoException;
|
|
187
194
|
|
|
188
|
-
if (
|
|
195
|
+
if (err.code === "ENOENT") {
|
|
189
196
|
if (hasLocalQwen) {
|
|
190
197
|
errorMessage =
|
|
191
198
|
"qwen command not found. Please ensure Qwen CLI is properly installed.";
|
|
@@ -194,7 +201,8 @@ export async function launchQwenCLI(
|
|
|
194
201
|
"bunx command not found. Please ensure Bun is installed so Qwen CLI can run via bunx.";
|
|
195
202
|
}
|
|
196
203
|
} else {
|
|
197
|
-
|
|
204
|
+
const details = error instanceof Error ? error.message : String(error);
|
|
205
|
+
errorMessage = `Failed to launch Qwen CLI: ${details || "Unknown error"}`;
|
|
198
206
|
}
|
|
199
207
|
|
|
200
208
|
if (process.platform === "win32") {
|
|
@@ -250,8 +258,9 @@ export async function isQwenCLIAvailable(): Promise<boolean> {
|
|
|
250
258
|
try {
|
|
251
259
|
await execa("bunx", [QWEN_CLI_PACKAGE, "--version"], { shell: true });
|
|
252
260
|
return true;
|
|
253
|
-
} catch (error:
|
|
254
|
-
|
|
261
|
+
} catch (error: unknown) {
|
|
262
|
+
const err = error as NodeJS.ErrnoException;
|
|
263
|
+
if (err.code === "ENOENT") {
|
|
255
264
|
console.error(chalk.yellow("\n⚠️ bunx command not found"));
|
|
256
265
|
console.error(
|
|
257
266
|
chalk.gray(
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import { platform } from "os";
|
|
3
|
+
import { getToolById } from "../config/tools.js";
|
|
4
|
+
import {
|
|
5
|
+
CODEX_DEFAULT_ARGS,
|
|
6
|
+
CLAUDE_PERMISSION_SKIP_ARGS,
|
|
7
|
+
} from "../shared/aiToolConstants.js";
|
|
8
|
+
import { prepareCustomToolExecution } from "./customToolResolver.js";
|
|
9
|
+
import type { LaunchOptions } from "../types/tools.js";
|
|
10
|
+
|
|
11
|
+
const DETECTION_COMMAND = platform() === "win32" ? "where" : "which";
|
|
12
|
+
const MIN_BUN_MAJOR = 1;
|
|
13
|
+
|
|
14
|
+
export const CLAUDE_CLI_PACKAGE = "@anthropic-ai/claude-code@latest";
|
|
15
|
+
export const CODEX_CLI_PACKAGE = "@openai/codex@latest";
|
|
16
|
+
|
|
17
|
+
export type ResolverErrorCode =
|
|
18
|
+
| "COMMAND_NOT_FOUND"
|
|
19
|
+
| "BUNX_NOT_FOUND"
|
|
20
|
+
| "BUN_TOO_OLD"
|
|
21
|
+
| "CUSTOM_TOOL_NOT_FOUND";
|
|
22
|
+
|
|
23
|
+
export interface ResolvedCommand {
|
|
24
|
+
command: string;
|
|
25
|
+
args: string[];
|
|
26
|
+
usesFallback: boolean;
|
|
27
|
+
env?: NodeJS.ProcessEnv;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class AIToolResolutionError extends Error {
|
|
31
|
+
constructor(
|
|
32
|
+
public code: ResolverErrorCode,
|
|
33
|
+
message: string,
|
|
34
|
+
public hints?: string[],
|
|
35
|
+
) {
|
|
36
|
+
super(message);
|
|
37
|
+
this.name = "AIToolResolutionError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function commandExists(command: string): Promise<boolean> {
|
|
42
|
+
try {
|
|
43
|
+
await execa(DETECTION_COMMAND, [command], { shell: true });
|
|
44
|
+
return true;
|
|
45
|
+
} catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
let bunxCheckPromise: Promise<void> | null = null;
|
|
51
|
+
|
|
52
|
+
async function ensureBunxAvailable(): Promise<void> {
|
|
53
|
+
if (!bunxCheckPromise) {
|
|
54
|
+
bunxCheckPromise = (async () => {
|
|
55
|
+
const bunxExists = await commandExists("bunx");
|
|
56
|
+
if (!bunxExists) {
|
|
57
|
+
throw new AIToolResolutionError(
|
|
58
|
+
"BUNX_NOT_FOUND",
|
|
59
|
+
"bunx command not found. Install Bun 1.0+ so bunx is available on PATH.",
|
|
60
|
+
[
|
|
61
|
+
"Install Bun: https://bun.sh/docs/installation",
|
|
62
|
+
"After installation, restart your terminal so bunx is on PATH.",
|
|
63
|
+
],
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const { stdout } = await execa("bun", ["--version"]);
|
|
69
|
+
const version = stdout.trim();
|
|
70
|
+
const major = parseInt(version.split(".")[0] ?? "0", 10);
|
|
71
|
+
if (!Number.isFinite(major) || major < MIN_BUN_MAJOR) {
|
|
72
|
+
throw new AIToolResolutionError(
|
|
73
|
+
"BUN_TOO_OLD",
|
|
74
|
+
`Detected Bun ${version}. Bun ${MIN_BUN_MAJOR}.0+ is required for bunx fallback execution.`,
|
|
75
|
+
[
|
|
76
|
+
"Upgrade Bun: curl -fsSL https://bun.sh/install | bash",
|
|
77
|
+
"Verify with 'bun --version' (needs >= 1.0)",
|
|
78
|
+
],
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
} catch (error: unknown) {
|
|
82
|
+
if (error instanceof AIToolResolutionError) {
|
|
83
|
+
throw error;
|
|
84
|
+
}
|
|
85
|
+
const err = error as NodeJS.ErrnoException;
|
|
86
|
+
if (err?.code === "ENOENT") {
|
|
87
|
+
throw new AIToolResolutionError(
|
|
88
|
+
"BUNX_NOT_FOUND",
|
|
89
|
+
"bun command not found while verifying bunx. Install Bun 1.0+ and ensure it is on PATH.",
|
|
90
|
+
[
|
|
91
|
+
"Install Bun: https://bun.sh/docs/installation",
|
|
92
|
+
"After installation, run 'bun --version' to confirm.",
|
|
93
|
+
],
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
throw new AIToolResolutionError(
|
|
97
|
+
"BUN_TOO_OLD",
|
|
98
|
+
`Failed to verify Bun version: ${err?.message ?? "unknown error"}`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
await bunxCheckPromise;
|
|
106
|
+
} catch (error) {
|
|
107
|
+
bunxCheckPromise = null;
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface ClaudeCommandOptions {
|
|
113
|
+
mode?: "normal" | "continue" | "resume";
|
|
114
|
+
skipPermissions?: boolean;
|
|
115
|
+
extraArgs?: string[];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function buildClaudeArgs(options: ClaudeCommandOptions = {}): string[] {
|
|
119
|
+
const args: string[] = [];
|
|
120
|
+
|
|
121
|
+
switch (options.mode) {
|
|
122
|
+
case "continue":
|
|
123
|
+
args.push("-c");
|
|
124
|
+
break;
|
|
125
|
+
case "resume":
|
|
126
|
+
args.push("-r");
|
|
127
|
+
break;
|
|
128
|
+
default:
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (options.skipPermissions) {
|
|
133
|
+
args.push(...CLAUDE_PERMISSION_SKIP_ARGS);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (options.extraArgs?.length) {
|
|
137
|
+
args.push(...options.extraArgs);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return args;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export async function resolveClaudeCommand(
|
|
144
|
+
options: ClaudeCommandOptions = {},
|
|
145
|
+
): Promise<ResolvedCommand> {
|
|
146
|
+
const args = buildClaudeArgs(options);
|
|
147
|
+
|
|
148
|
+
if (await commandExists("claude")) {
|
|
149
|
+
return {
|
|
150
|
+
command: "claude",
|
|
151
|
+
args,
|
|
152
|
+
usesFallback: false,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
await ensureBunxAvailable();
|
|
157
|
+
return {
|
|
158
|
+
command: "bunx",
|
|
159
|
+
args: [CLAUDE_CLI_PACKAGE, ...args],
|
|
160
|
+
usesFallback: true,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export interface CodexCommandOptions {
|
|
165
|
+
mode?: "normal" | "continue" | "resume";
|
|
166
|
+
bypassApprovals?: boolean;
|
|
167
|
+
extraArgs?: string[];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export function buildCodexArgs(options: CodexCommandOptions = {}): string[] {
|
|
171
|
+
const args: string[] = [];
|
|
172
|
+
|
|
173
|
+
switch (options.mode) {
|
|
174
|
+
case "continue":
|
|
175
|
+
args.push("resume", "--last");
|
|
176
|
+
break;
|
|
177
|
+
case "resume":
|
|
178
|
+
args.push("resume");
|
|
179
|
+
break;
|
|
180
|
+
default:
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (options.bypassApprovals) {
|
|
185
|
+
args.push("--yolo");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (options.extraArgs?.length) {
|
|
189
|
+
args.push(...options.extraArgs);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
args.push(...CODEX_DEFAULT_ARGS);
|
|
193
|
+
return args;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export async function resolveCodexCommand(
|
|
197
|
+
options: CodexCommandOptions = {},
|
|
198
|
+
): Promise<ResolvedCommand> {
|
|
199
|
+
const args = buildCodexArgs(options);
|
|
200
|
+
|
|
201
|
+
if (await commandExists("codex")) {
|
|
202
|
+
return {
|
|
203
|
+
command: "codex",
|
|
204
|
+
args,
|
|
205
|
+
usesFallback: false,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await ensureBunxAvailable();
|
|
210
|
+
return {
|
|
211
|
+
command: "bunx",
|
|
212
|
+
args: [CODEX_CLI_PACKAGE, ...args],
|
|
213
|
+
usesFallback: true,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface CustomToolCommandOptions extends LaunchOptions {
|
|
218
|
+
toolId: string;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export async function resolveCustomToolCommand(
|
|
222
|
+
options: CustomToolCommandOptions,
|
|
223
|
+
): Promise<ResolvedCommand> {
|
|
224
|
+
const tool = await getToolById(options.toolId);
|
|
225
|
+
if (!tool) {
|
|
226
|
+
throw new AIToolResolutionError(
|
|
227
|
+
"CUSTOM_TOOL_NOT_FOUND",
|
|
228
|
+
`Custom tool not found: ${options.toolId}`,
|
|
229
|
+
[
|
|
230
|
+
"Update ~/.gwt/tools.json to include this ID",
|
|
231
|
+
"Reload the Web UI after editing the tools list",
|
|
232
|
+
],
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const execution = await prepareCustomToolExecution(tool, options);
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
command: execution.command,
|
|
240
|
+
args: execution.args,
|
|
241
|
+
usesFallback: tool.type === "bunx",
|
|
242
|
+
...(execution.env ? { env: execution.env } : {}),
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export async function isClaudeCodeAvailable(): Promise<boolean> {
|
|
247
|
+
try {
|
|
248
|
+
await resolveClaudeCommand();
|
|
249
|
+
return true;
|
|
250
|
+
} catch (error) {
|
|
251
|
+
if (error instanceof AIToolResolutionError) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
export async function isCodexAvailable(): Promise<boolean> {
|
|
259
|
+
try {
|
|
260
|
+
await resolveCodexCommand();
|
|
261
|
+
return true;
|
|
262
|
+
} catch (error) {
|
|
263
|
+
if (error instanceof AIToolResolutionError) {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Test-helper: resets cached bunx availability check.
|
|
272
|
+
* Not exported in type definitions to avoid production usage.
|
|
273
|
+
*/
|
|
274
|
+
export function __resetBunxCacheForTests(): void {
|
|
275
|
+
bunxCheckPromise = null;
|
|
276
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { execa } from "execa";
|
|
2
|
+
import type { CustomAITool, LaunchOptions } from "../types/tools.js";
|
|
3
|
+
|
|
4
|
+
export interface CustomToolExecutionPlan {
|
|
5
|
+
command: string;
|
|
6
|
+
args: string[];
|
|
7
|
+
env?: NodeJS.ProcessEnv;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const WHICH_COMMAND = process.platform === "win32" ? "where" : "which";
|
|
11
|
+
|
|
12
|
+
export async function resolveCommandPath(commandName: string): Promise<string> {
|
|
13
|
+
try {
|
|
14
|
+
const { stdout } = await execa(WHICH_COMMAND, [commandName]);
|
|
15
|
+
const resolvedPath = (stdout.split("\n")[0] ?? "").trim();
|
|
16
|
+
|
|
17
|
+
if (!resolvedPath) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Command "${commandName}" not found in PATH.\n` +
|
|
20
|
+
"Please ensure it is installed and available in your PATH.",
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return resolvedPath;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Failed to resolve command "${commandName}".\n${reason}\n` +
|
|
29
|
+
"Please ensure the command is installed and available in your PATH.",
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function buildCustomToolArgs(
|
|
35
|
+
tool: CustomAITool,
|
|
36
|
+
options: LaunchOptions = {},
|
|
37
|
+
): string[] {
|
|
38
|
+
const args: string[] = [];
|
|
39
|
+
|
|
40
|
+
if (tool.defaultArgs?.length) {
|
|
41
|
+
args.push(...tool.defaultArgs);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const mode = options.mode ?? "normal";
|
|
45
|
+
const modeArgs = tool.modeArgs?.[mode];
|
|
46
|
+
if (modeArgs?.length) {
|
|
47
|
+
args.push(...modeArgs);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (options.skipPermissions && tool.permissionSkipArgs?.length) {
|
|
51
|
+
args.push(...tool.permissionSkipArgs);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (options.extraArgs?.length) {
|
|
55
|
+
args.push(...options.extraArgs);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return args;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function prepareCustomToolExecution(
|
|
62
|
+
tool: CustomAITool,
|
|
63
|
+
options: LaunchOptions = {},
|
|
64
|
+
): Promise<CustomToolExecutionPlan> {
|
|
65
|
+
const args = buildCustomToolArgs(tool, options);
|
|
66
|
+
const envOverrides: NodeJS.ProcessEnv | undefined = tool.env
|
|
67
|
+
? ({ ...tool.env } as NodeJS.ProcessEnv)
|
|
68
|
+
: undefined;
|
|
69
|
+
|
|
70
|
+
switch (tool.type) {
|
|
71
|
+
case "path": {
|
|
72
|
+
return {
|
|
73
|
+
command: tool.command,
|
|
74
|
+
args,
|
|
75
|
+
...(envOverrides ? { env: envOverrides } : {}),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
case "bunx": {
|
|
79
|
+
return {
|
|
80
|
+
command: "bunx",
|
|
81
|
+
args: [tool.command, ...args],
|
|
82
|
+
...(envOverrides ? { env: envOverrides } : {}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
case "command": {
|
|
86
|
+
const resolved = await resolveCommandPath(tool.command);
|
|
87
|
+
return {
|
|
88
|
+
command: resolved,
|
|
89
|
+
args,
|
|
90
|
+
...(envOverrides ? { env: envOverrides } : {}),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
default: {
|
|
94
|
+
const exhaustive: never = tool.type;
|
|
95
|
+
throw new Error(`Unknown custom tool type: ${exhaustive as string}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared constants for AI tool integrations.
|
|
3
|
+
*
|
|
4
|
+
* These values are consumed by both the CLI (Node) runtime and the Web UI so
|
|
5
|
+
* that command previews, permission flags, and default arguments stay in sync.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const CLAUDE_PERMISSION_SKIP_ARGS = [
|
|
9
|
+
"--dangerously-skip-permissions",
|
|
10
|
+
] as const;
|
|
11
|
+
|
|
12
|
+
export const CODEX_DEFAULT_ARGS = [
|
|
13
|
+
"--enable",
|
|
14
|
+
"web_search_request",
|
|
15
|
+
"--model=gpt-5-codex",
|
|
16
|
+
"--sandbox",
|
|
17
|
+
"workspace-write",
|
|
18
|
+
"-c",
|
|
19
|
+
"model_reasoning_effort=high",
|
|
20
|
+
"-c",
|
|
21
|
+
"model_reasoning_summaries=detailed",
|
|
22
|
+
"-c",
|
|
23
|
+
"sandbox_workspace_write.network_access=true",
|
|
24
|
+
"-c",
|
|
25
|
+
"shell_environment_policy.inherit=all",
|
|
26
|
+
"-c",
|
|
27
|
+
"shell_environment_policy.ignore_default_excludes=true",
|
|
28
|
+
"-c",
|
|
29
|
+
"shell_environment_policy.experimental_use_profile=true",
|
|
30
|
+
] as const;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
declare module "trayicon" {
|
|
2
|
+
export interface TrayIconMenuItem {
|
|
3
|
+
text: string;
|
|
4
|
+
action?: () => void | Promise<void>;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
checked?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface TrayIconOptions {
|
|
10
|
+
icon: Buffer;
|
|
11
|
+
title?: string;
|
|
12
|
+
tooltip?: string;
|
|
13
|
+
action?: () => void | Promise<void>;
|
|
14
|
+
menu?: TrayIconMenuItem[];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface TrayIconInstance {
|
|
18
|
+
setIcon?: (icon: Buffer) => void;
|
|
19
|
+
setTitle?: (title: string) => void;
|
|
20
|
+
dispose?: () => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function create(options: TrayIconOptions): TrayIconInstance;
|
|
24
|
+
|
|
25
|
+
const trayicon: {
|
|
26
|
+
create: typeof create;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default trayicon;
|
|
30
|
+
}
|
package/src/types/tools.ts
CHANGED
|
@@ -69,6 +69,11 @@ export interface CustomAITool {
|
|
|
69
69
|
*/
|
|
70
70
|
icon?: string;
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* 説明文(オプション)
|
|
74
|
+
*/
|
|
75
|
+
description?: string;
|
|
76
|
+
|
|
72
77
|
/**
|
|
73
78
|
* 実行方式
|
|
74
79
|
*
|
|
@@ -118,6 +123,16 @@ export interface CustomAITool {
|
|
|
118
123
|
* APIキーや設定ファイルパスなどを指定。
|
|
119
124
|
*/
|
|
120
125
|
env?: Record<string, string>;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* 作成日時(ISO8601)。tools.jsonのメタデータとして使用。
|
|
129
|
+
*/
|
|
130
|
+
createdAt?: string;
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* 更新日時(ISO8601)。tools.jsonのメタデータとして使用。
|
|
134
|
+
*/
|
|
135
|
+
updatedAt?: string;
|
|
121
136
|
}
|
|
122
137
|
|
|
123
138
|
/**
|
package/src/utils/prompt.ts
CHANGED
|
@@ -22,7 +22,9 @@ export async function waitForEnter(promptMessage: string): Promise<void> {
|
|
|
22
22
|
|
|
23
23
|
if ((stdin as NodeJS.ReadStream & { isRaw?: boolean }).isRaw) {
|
|
24
24
|
try {
|
|
25
|
-
(
|
|
25
|
+
(
|
|
26
|
+
stdin as NodeJS.ReadStream & { setRawMode?: (flag: boolean) => void }
|
|
27
|
+
).setRawMode?.(false);
|
|
26
28
|
} catch {
|
|
27
29
|
// Ignore raw mode errors
|
|
28
30
|
}
|
|
@@ -35,17 +37,21 @@ export async function waitForEnter(promptMessage: string): Promise<void> {
|
|
|
35
37
|
rl.removeAllListeners();
|
|
36
38
|
rl.close();
|
|
37
39
|
const remover = (method: "off" | "removeListener") =>
|
|
38
|
-
(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
(
|
|
41
|
+
stdin as unknown as Record<
|
|
42
|
+
string,
|
|
43
|
+
(event: string, fn: () => void) => void
|
|
44
|
+
>
|
|
45
|
+
)[method]?.("end", onEnd);
|
|
42
46
|
remover("off");
|
|
43
47
|
remover("removeListener");
|
|
44
48
|
const removerErr = (method: "off" | "removeListener") =>
|
|
45
|
-
(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
(
|
|
50
|
+
stdin as unknown as Record<
|
|
51
|
+
string,
|
|
52
|
+
(event: string, fn: () => void) => void
|
|
53
|
+
>
|
|
54
|
+
)[method]?.("error", onEnd);
|
|
49
55
|
removerErr("off");
|
|
50
56
|
removerErr("removeListener");
|
|
51
57
|
if (typeof stdin.pause === "function") {
|