@akiojin/gwt 4.1.1 → 4.3.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.md +28 -3
- package/dist/claude.d.ts +4 -0
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +13 -1
- package/dist/claude.js.map +1 -1
- package/dist/cli/ui/components/App.d.ts.map +1 -1
- package/dist/cli/ui/components/App.js +68 -68
- package/dist/cli/ui/components/App.js.map +1 -1
- package/dist/cli/ui/components/common/Select.d.ts +3 -1
- package/dist/cli/ui/components/common/Select.d.ts.map +1 -1
- package/dist/cli/ui/components/common/Select.js +13 -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 +6 -1
- package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -1
- package/dist/client/assets/index-ChHC-Puh.css +1 -0
- package/dist/client/assets/index-PqK9jkug.js +78 -0
- package/dist/client/index.html +2 -2
- package/dist/config/builtin-tools.d.ts.map +1 -1
- package/dist/config/builtin-tools.js +3 -0
- package/dist/config/builtin-tools.js.map +1 -1
- package/dist/config/tools.d.ts.map +1 -1
- package/dist/config/tools.js +10 -1
- package/dist/config/tools.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -4
- package/dist/index.js.map +1 -1
- package/dist/launcher.d.ts.map +1 -1
- package/dist/launcher.js +15 -0
- package/dist/launcher.js.map +1 -1
- package/dist/services/aiToolResolver.d.ts.map +1 -1
- package/dist/services/aiToolResolver.js +55 -8
- package/dist/services/aiToolResolver.js.map +1 -1
- package/dist/services/customToolResolver.d.ts.map +1 -1
- package/dist/services/customToolResolver.js +22 -17
- package/dist/services/customToolResolver.js.map +1 -1
- package/dist/utils/prompt.d.ts +12 -0
- package/dist/utils/prompt.d.ts.map +1 -1
- package/dist/utils/prompt.js +60 -10
- package/dist/utils/prompt.js.map +1 -1
- package/dist/utils/webui.js +1 -1
- package/dist/web/client/src/components/BranchGraph.d.ts +5 -0
- package/dist/web/client/src/components/BranchGraph.d.ts.map +1 -1
- package/dist/web/client/src/components/BranchGraph.js +35 -108
- package/dist/web/client/src/components/BranchGraph.js.map +1 -1
- package/dist/web/client/src/components/graph/BranchDetailPanel.d.ts +15 -0
- package/dist/web/client/src/components/graph/BranchDetailPanel.d.ts.map +1 -0
- package/dist/web/client/src/components/graph/BranchDetailPanel.js +57 -0
- package/dist/web/client/src/components/graph/BranchDetailPanel.js.map +1 -0
- package/dist/web/client/src/components/graph/BranchNode.d.ts +13 -0
- package/dist/web/client/src/components/graph/BranchNode.d.ts.map +1 -0
- package/dist/web/client/src/components/graph/BranchNode.js +103 -0
- package/dist/web/client/src/components/graph/BranchNode.js.map +1 -0
- package/dist/web/client/src/components/graph/ClusterNode.d.ts +13 -0
- package/dist/web/client/src/components/graph/ClusterNode.d.ts.map +1 -0
- package/dist/web/client/src/components/graph/ClusterNode.js +109 -0
- package/dist/web/client/src/components/graph/ClusterNode.js.map +1 -0
- package/dist/web/client/src/components/graph/SynapticCanvas.d.ts +17 -0
- package/dist/web/client/src/components/graph/SynapticCanvas.d.ts.map +1 -0
- package/dist/web/client/src/components/graph/SynapticCanvas.js +94 -0
- package/dist/web/client/src/components/graph/SynapticCanvas.js.map +1 -0
- package/dist/web/client/src/components/graph/SynapticEdge.d.ts +13 -0
- package/dist/web/client/src/components/graph/SynapticEdge.d.ts.map +1 -0
- package/dist/web/client/src/components/graph/SynapticEdge.js +113 -0
- package/dist/web/client/src/components/graph/SynapticEdge.js.map +1 -0
- package/dist/web/client/src/components/graph/graphUtils.d.ts +67 -0
- package/dist/web/client/src/components/graph/graphUtils.d.ts.map +1 -0
- package/dist/web/client/src/components/graph/graphUtils.js +175 -0
- package/dist/web/client/src/components/graph/graphUtils.js.map +1 -0
- package/dist/web/client/src/components/graph/index.d.ts +10 -0
- package/dist/web/client/src/components/graph/index.d.ts.map +1 -0
- package/dist/web/client/src/components/graph/index.js +10 -0
- package/dist/web/client/src/components/graph/index.js.map +1 -0
- package/dist/web/client/src/lib/websocket.d.ts.map +1 -1
- package/dist/web/client/src/lib/websocket.js +2 -1
- package/dist/web/client/src/lib/websocket.js.map +1 -1
- package/dist/web/client/vite.config.js +1 -1
- package/dist/web/server/env/importer.d.ts.map +1 -1
- package/dist/web/server/env/importer.js +4 -0
- package/dist/web/server/env/importer.js.map +1 -1
- package/dist/web/server/index.d.ts.map +1 -1
- package/dist/web/server/index.js +9 -0
- package/dist/web/server/index.js.map +1 -1
- package/dist/web/server/pty/manager.d.ts.map +1 -1
- package/dist/web/server/pty/manager.js +24 -1
- 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 +7 -0
- package/dist/web/server/routes/sessions.js.map +1 -1
- package/dist/web/server/tray.d.ts +1 -1
- package/dist/web/server/tray.d.ts.map +1 -1
- package/dist/web/server/tray.js +52 -34
- package/dist/web/server/tray.js.map +1 -1
- package/dist/web/server/websocket/handler.d.ts.map +1 -1
- package/dist/web/server/websocket/handler.js +4 -0
- package/dist/web/server/websocket/handler.js.map +1 -1
- package/package.json +6 -3
- package/src/claude.ts +15 -1
- package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +2 -1
- package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +142 -8
- package/src/cli/ui/__tests__/components/App.test.tsx +4 -3
- package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +1 -0
- package/src/cli/ui/__tests__/components/common/Select.test.tsx +45 -0
- package/src/cli/ui/components/App.tsx +91 -81
- package/src/cli/ui/components/common/Select.tsx +14 -1
- package/src/cli/ui/components/screens/BranchListScreen.tsx +6 -1
- package/src/cli/ui/types.ts +1 -1
- package/src/config/builtin-tools.ts +3 -0
- package/src/config/tools.ts +24 -1
- package/src/index.ts +50 -3
- package/src/launcher.ts +26 -0
- package/src/services/aiToolResolver.ts +75 -9
- package/src/services/customToolResolver.ts +32 -17
- package/src/utils/__tests__/prompt.test.ts +72 -35
- package/src/utils/prompt.ts +79 -10
- package/src/utils/webui.ts +1 -1
- package/src/web/client/src/components/BranchGraph.tsx +51 -208
- package/src/web/client/src/components/graph/BranchDetailPanel.tsx +152 -0
- package/src/web/client/src/components/graph/BranchNode.tsx +200 -0
- package/src/web/client/src/components/graph/ClusterNode.tsx +211 -0
- package/src/web/client/src/components/graph/SynapticCanvas.tsx +171 -0
- package/src/web/client/src/components/graph/SynapticEdge.tsx +311 -0
- package/src/web/client/src/components/graph/graphUtils.ts +265 -0
- package/src/web/client/src/components/graph/index.ts +10 -0
- package/src/web/client/src/index.css +314 -29
- package/src/web/client/src/lib/websocket.ts +2 -1
- package/src/web/client/vite.config.ts +1 -1
- package/src/web/server/env/importer.ts +5 -0
- package/src/web/server/index.ts +10 -0
- package/src/web/server/pty/manager.ts +43 -1
- package/src/web/server/routes/sessions.ts +15 -0
- package/src/web/server/tray.ts +62 -46
- package/src/web/server/websocket/handler.ts +13 -0
- package/dist/client/assets/index-DsDNCy5f.css +0 -1
- package/dist/client/assets/index-v8smkNOL.js +0 -72
package/dist/web/server/tray.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { execa } from "execa";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { createLogger } from "../../logging/logger.js";
|
|
3
|
-
const
|
|
4
|
+
const require = createRequire(import.meta.url);
|
|
5
|
+
// PNG icon (16x16) for macOS/Linux - Base64 encoded
|
|
6
|
+
const TRAY_ICON_PNG_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAADLSURBVDiNpZMxDoJAEEXfLhYewMrOxsLKG3gDj+ANPIKFtScwHoHOxmN4AysLL0BlQ0Ji4W6yLLAgfslkZnbm/0wmA/9G6CogIr4F7IAbcAYOqpoEJBYD+3UADVYAiMgZOAKvboAFwFLENoAtsAdGwAw4qepZRN7A2LIIWCngCjy7t1bVF/D05QBT4K6qOxH5dOwjuwrYApdMvC3wBHzWBTwAr6p6c+wFSBJvEeDsehLVNwZ0sQDqv+kl3xjQxcKNSaZ/s+irNK1fXfwA7LE/RA3w5ggAAAAASUVORK5CYII=";
|
|
7
|
+
// ICO icon for Windows - Base64 encoded
|
|
8
|
+
const TRAY_ICON_ICO_BASE64 = "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAJ1BMVEUAAAAAvNQAvNQAvNQAvNQAvNQAvNQAvNQAvNQAvNQAvNQAvNT////J1ubyAAAAC3RSTlMAJYTcgyQJnJ3U3WXfUogAAAABYktHRAyBs1FjAAAAB3RJTUUH6QwMCRccbOpRBQAAAFdJREFUCNdjYEAARuXNriCarXr37t1tQEYmkN69M4GBoRvE2F3AwAqmd29kYIEwNjEwQxibGbghjN0MXDARJpgaqK6tDAzVUHMQJoPtKgPZyuq8S5WBAQBeRj51tvdhawAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyNS0xMi0xMlQwOToyMzoyOCswMDowMBPEA5UAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjUtMTItMTJUMDk6MjM6MjgrMDA6MDBimbspAAAAAElFTkSuQmCC";
|
|
4
9
|
let trayInitAttempted = false;
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
11
|
let trayInstance = null;
|
|
6
|
-
let trayInitPromise = null;
|
|
7
12
|
function shouldEnableTray(platform = process.platform) {
|
|
8
13
|
// NOTE: `trayicon` is a win32-only dependency.
|
|
9
14
|
if (platform !== "win32")
|
|
@@ -39,7 +44,7 @@ export async function openUrl(url) {
|
|
|
39
44
|
}
|
|
40
45
|
/**
|
|
41
46
|
* システムトレイアイコンを初期化
|
|
42
|
-
* @param url - Web UI のURL
|
|
47
|
+
* @param url - Web UI のURL(メニューから開く)
|
|
43
48
|
* @param opts - オプション設定
|
|
44
49
|
* @param opts.openUrl - URL を開くカスタム関数(テスト用)
|
|
45
50
|
*/
|
|
@@ -48,37 +53,48 @@ export async function startSystemTray(url, opts) {
|
|
|
48
53
|
return;
|
|
49
54
|
trayInitAttempted = true;
|
|
50
55
|
const logger = createLogger({ category: "tray" });
|
|
56
|
+
const open = opts?.openUrl ?? openUrl;
|
|
51
57
|
try {
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
58
|
+
// systray2 をCommonJS requireでインポート(ESM互換性のため)
|
|
59
|
+
const SysTray = require("systray2").default;
|
|
60
|
+
const isWindows = process.platform === "win32";
|
|
61
|
+
const isMacOS = process.platform === "darwin";
|
|
62
|
+
// プラットフォームに応じたアイコンを選択
|
|
63
|
+
const iconBase64 = isWindows ? TRAY_ICON_ICO_BASE64 : TRAY_ICON_PNG_BASE64;
|
|
64
|
+
const openDashboardItem = {
|
|
65
|
+
title: "Open Web UI",
|
|
66
|
+
tooltip: "Open gwt Web UI in browser",
|
|
67
|
+
checked: false,
|
|
68
|
+
enabled: true,
|
|
69
|
+
};
|
|
70
|
+
const exitItem = {
|
|
71
|
+
title: "Exit",
|
|
72
|
+
tooltip: "Close the tray icon",
|
|
73
|
+
checked: false,
|
|
74
|
+
enabled: true,
|
|
75
|
+
};
|
|
76
|
+
trayInstance = new SysTray({
|
|
77
|
+
menu: {
|
|
78
|
+
icon: iconBase64,
|
|
79
|
+
isTemplateIcon: isMacOS,
|
|
80
|
+
title: "gwt",
|
|
81
|
+
tooltip: `gwt Web UI - ${url}`,
|
|
82
|
+
items: [openDashboardItem, SysTray.separator, exitItem],
|
|
65
83
|
},
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
84
|
+
debug: false,
|
|
85
|
+
copyDir: false,
|
|
86
|
+
});
|
|
87
|
+
trayInstance.onClick((action) => {
|
|
88
|
+
if (action.item.title === "Open Web UI") {
|
|
89
|
+
open(url);
|
|
90
|
+
}
|
|
91
|
+
else if (action.item.title === "Exit") {
|
|
92
|
+
trayInstance?.kill(false);
|
|
93
|
+
trayInstance = null;
|
|
74
94
|
}
|
|
75
|
-
trayInstance = tray;
|
|
76
|
-
})
|
|
77
|
-
.catch((err) => {
|
|
78
|
-
if (trayInitPromise !== initPromise)
|
|
79
|
-
return;
|
|
80
|
-
logger.warn({ err }, "System tray failed to initialize");
|
|
81
95
|
});
|
|
96
|
+
await trayInstance.ready();
|
|
97
|
+
logger.info("System tray initialized");
|
|
82
98
|
}
|
|
83
99
|
catch (err) {
|
|
84
100
|
logger.warn({ err }, "System tray failed to initialize");
|
|
@@ -88,11 +104,13 @@ export async function startSystemTray(url, opts) {
|
|
|
88
104
|
* システムトレイアイコンを破棄
|
|
89
105
|
*/
|
|
90
106
|
export function disposeSystemTray() {
|
|
91
|
-
|
|
92
|
-
|
|
107
|
+
try {
|
|
108
|
+
trayInstance?.kill?.(false);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Ignore errors during cleanup
|
|
112
|
+
}
|
|
93
113
|
trayInstance = null;
|
|
94
|
-
instance?.dispose?.();
|
|
95
|
-
instance?.kill?.();
|
|
96
114
|
trayInitAttempted = false;
|
|
97
115
|
}
|
|
98
116
|
//# sourceMappingURL=tray.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tray.js","sourceRoot":"","sources":["../../../src/web/server/tray.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"tray.js","sourceRoot":"","sources":["../../../src/web/server/tray.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAQ/C,oDAAoD;AACpD,MAAM,oBAAoB,GACxB,kcAAkc,CAAC;AAErc,wCAAwC;AACxC,MAAM,oBAAoB,GACxB,kiBAAkiB,CAAC;AAEriB,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAC9B,8DAA8D;AAC9D,IAAI,YAAY,GAAQ,IAAI,CAAC;AAE7B,SAAS,gBAAgB,CACvB,WAA4B,OAAO,CAAC,QAAQ;IAE5C,+CAA+C;IAC/C,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACvC,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,WAAW,EAAE,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACzE,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACvD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACjC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAW;IACvC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,CAAC;QACH,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,MAAM,KAAK,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QACD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAW,EACX,IAA0D;IAE1D,IAAI,iBAAiB,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC;QAAE,OAAO;IACnE,iBAAiB,GAAG,IAAI,CAAC;IAEzB,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,IAAI,EAAE,OAAO,IAAI,OAAO,CAAC;IAEtC,IAAI,CAAC;QACH,8CAA8C;QAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC;QAE5C,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC;QAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC;QAE9C,sBAAsB;QACtB,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC;QAE3E,MAAM,iBAAiB,GAAG;YACxB,KAAK,EAAE,aAAa;YACpB,OAAO,EAAE,4BAA4B;YACrC,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,IAAI;SACd,CAAC;QAEF,MAAM,QAAQ,GAAG;YACf,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,qBAAqB;YAC9B,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,IAAI;SACd,CAAC;QAEF,YAAY,GAAG,IAAI,OAAO,CAAC;YACzB,IAAI,EAAE;gBACJ,IAAI,EAAE,UAAU;gBAChB,cAAc,EAAE,OAAO;gBACvB,KAAK,EAAE,KAAK;gBACZ,OAAO,EAAE,gBAAgB,GAAG,EAAE;gBAC9B,KAAK,EAAE,CAAC,iBAAiB,EAAE,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC;aACxD;YACD,KAAK,EAAE,KAAK;YACZ,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QAEH,YAAY,CAAC,OAAO,CAAC,CAAC,MAAmC,EAAE,EAAE;YAC3D,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,aAAa,EAAE,CAAC;gBACxC,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;iBAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;gBACxC,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC1B,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,kCAAkC,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC;QACH,YAAY,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;IACjC,CAAC;IACD,YAAY,GAAG,IAAI,CAAC;IACpB,iBAAiB,GAAG,KAAK,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/web/server/websocket/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD;;GAEG;AACH,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,aAAa,CAA0C;gBAGrD,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,iBAAiB;IAGnC;;OAEG;IACI,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../../src/web/server/websocket/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAWpD;;GAEG;AACH,qBAAa,gBAAgB;IAIzB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,aAAa,CAA0C;gBAGrD,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,iBAAiB;IAGnC;;OAEG;IACI,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI;IAmGnE;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsC3B;;OAEG;IACH,OAAO,CAAC,UAAU;IASlB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAchB;;OAEG;IACH,OAAO,CAAC,SAAS;IAWjB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,iBAAiB;CAQ1B;AAID,UAAU,WAAW;IACnB,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;CACzC;AAED,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,cAAc,GAAG,WAAW,GACpC,MAAM,GAAG,IAAI,CAqBf"}
|
|
@@ -21,12 +21,14 @@ export class WebSocketHandler {
|
|
|
21
21
|
handle(connection, request) {
|
|
22
22
|
const sessionId = resolveSessionId(request);
|
|
23
23
|
if (!sessionId) {
|
|
24
|
+
this.logger.warn({ error: "Missing sessionId" }, "WebSocket session resolution failed");
|
|
24
25
|
this.sendError(connection, "Missing sessionId parameter");
|
|
25
26
|
connection.close();
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
28
29
|
const instance = this.ptyManager.get(sessionId);
|
|
29
30
|
if (!instance) {
|
|
31
|
+
this.logger.warn({ sessionId, error: "not found" }, "WebSocket session not found");
|
|
30
32
|
this.sendError(connection, `Session not found: ${sessionId}`);
|
|
31
33
|
connection.close();
|
|
32
34
|
return;
|
|
@@ -44,6 +46,7 @@ export class WebSocketHandler {
|
|
|
44
46
|
// PTYプロセス終了時の処理
|
|
45
47
|
ptyProcess.onExit(({ exitCode, signal }) => {
|
|
46
48
|
hasExited = true;
|
|
49
|
+
this.logger.info({ sessionId, exitCode, signal }, "PTY process exited");
|
|
47
50
|
this.clearCleanupTimer(sessionId);
|
|
48
51
|
this.ptyManager.updateStatus(sessionId, "completed", exitCode);
|
|
49
52
|
this.sendExit(connection, exitCode, signal);
|
|
@@ -61,6 +64,7 @@ export class WebSocketHandler {
|
|
|
61
64
|
}
|
|
62
65
|
catch (error) {
|
|
63
66
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
67
|
+
this.logger.warn({ sessionId, error: errorMsg }, "WebSocket message parse error");
|
|
64
68
|
this.sendError(connection, `Invalid message format: ${errorMsg}`);
|
|
65
69
|
}
|
|
66
70
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../../src/web/server/websocket/handler.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../../src/web/server/websocket/handler.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akiojin/gwt",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "Interactive Git worktree manager for Claude Code with graphical branch selection",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -64,7 +64,9 @@
|
|
|
64
64
|
"@radix-ui/react-tooltip": "^1.2.8",
|
|
65
65
|
"@tailwindcss/vite": "^4.1.18",
|
|
66
66
|
"@tanstack/react-query": "^5.66.1",
|
|
67
|
+
"@xyflow/react": "^12.10.0",
|
|
67
68
|
"chalk": "^5.4.1",
|
|
69
|
+
"d3-force": "^3.0.0",
|
|
68
70
|
"execa": "^9.6.0",
|
|
69
71
|
"fastify": "^5.2.1",
|
|
70
72
|
"ink": "^6.3.1",
|
|
@@ -77,8 +79,8 @@
|
|
|
77
79
|
"react-router": "^7.2.0",
|
|
78
80
|
"react-router-dom": "^7.2.0",
|
|
79
81
|
"string-width": "^8.1.0",
|
|
82
|
+
"systray2": "^2.1.4",
|
|
80
83
|
"tailwindcss": "^4.1.18",
|
|
81
|
-
"trayicon": "^1.2.2",
|
|
82
84
|
"ws": "^8.18.0",
|
|
83
85
|
"xterm": "^5.4.0-beta.37",
|
|
84
86
|
"xterm-addon-fit": "^0.9.0-beta.37",
|
|
@@ -91,6 +93,7 @@
|
|
|
91
93
|
"@playwright/test": "^1.51.0",
|
|
92
94
|
"@testing-library/jest-dom": "^6.9.1",
|
|
93
95
|
"@testing-library/react": "^16.3.0",
|
|
96
|
+
"@types/d3-force": "^3.0.10",
|
|
94
97
|
"@types/node": "^25.0.2",
|
|
95
98
|
"@types/react": "^19.2.2",
|
|
96
99
|
"@types/react-dom": "^19.0.3",
|
|
@@ -120,7 +123,7 @@
|
|
|
120
123
|
"vitest": "^4.0.8"
|
|
121
124
|
},
|
|
122
125
|
"lint-staged": {
|
|
123
|
-
"
|
|
126
|
+
"**/*.md": "bunx --bun markdownlint-cli -c .markdownlint.json --ignore CHANGELOG.md --ignore node_modules",
|
|
124
127
|
"*.{ts,tsx}": [
|
|
125
128
|
"bunx eslint --max-warnings=0 --no-warn-ignored",
|
|
126
129
|
"bunx prettier --check"
|
package/src/claude.ts
CHANGED
|
@@ -37,6 +37,7 @@ export class ClaudeError extends Error {
|
|
|
37
37
|
*
|
|
38
38
|
* @param worktreePath - Worktree directory to run Claude Code in
|
|
39
39
|
* @param options - Launch options (mode/session/model/permissions/env)
|
|
40
|
+
* @param options.chrome - Enable Chrome extension integration (adds --chrome flag)
|
|
40
41
|
* @returns Captured session id when available
|
|
41
42
|
*/
|
|
42
43
|
export async function launchClaudeCode(
|
|
@@ -48,6 +49,7 @@ export async function launchClaudeCode(
|
|
|
48
49
|
envOverrides?: Record<string, string>;
|
|
49
50
|
model?: string;
|
|
50
51
|
sessionId?: string | null;
|
|
52
|
+
chrome?: boolean;
|
|
51
53
|
} = {},
|
|
52
54
|
): Promise<{ sessionId?: string | null }> {
|
|
53
55
|
const terminal = getTerminalStreams();
|
|
@@ -169,6 +171,12 @@ export async function launchClaudeCode(
|
|
|
169
171
|
break;
|
|
170
172
|
}
|
|
171
173
|
|
|
174
|
+
// Handle Chrome extension integration
|
|
175
|
+
if (options.chrome) {
|
|
176
|
+
args.push("--chrome");
|
|
177
|
+
console.log(chalk.green(" 🌐 Chrome integration enabled"));
|
|
178
|
+
}
|
|
179
|
+
|
|
172
180
|
// Detect root user for Docker/sandbox environments
|
|
173
181
|
let isRoot = false;
|
|
174
182
|
try {
|
|
@@ -201,7 +209,11 @@ export async function launchClaudeCode(
|
|
|
201
209
|
terminal.exitRawMode();
|
|
202
210
|
resetTerminalModes(terminal.stdout);
|
|
203
211
|
|
|
204
|
-
const baseEnv
|
|
212
|
+
const baseEnv: Record<string, string | undefined> = {
|
|
213
|
+
...process.env,
|
|
214
|
+
...(options.envOverrides ?? {}),
|
|
215
|
+
ENABLE_LSP_TOOL: "true", // Enable TypeScript LSP support in Claude Code
|
|
216
|
+
};
|
|
205
217
|
const launchEnvSource =
|
|
206
218
|
options.skipPermissions && !baseEnv.IS_SANDBOX
|
|
207
219
|
? { ...baseEnv, IS_SANDBOX: "1" }
|
|
@@ -407,6 +419,8 @@ async function isNpxCommandAvailable(): Promise<boolean> {
|
|
|
407
419
|
|
|
408
420
|
/**
|
|
409
421
|
* Checks whether Claude Code is available via `bunx` in the current environment.
|
|
422
|
+
*
|
|
423
|
+
* @returns true if Claude Code can be resolved via bunx, false otherwise.
|
|
410
424
|
*/
|
|
411
425
|
export async function isClaudeCodeAvailable(): Promise<boolean> {
|
|
412
426
|
try {
|
|
@@ -103,6 +103,7 @@ describe("App protected branch handling", () => {
|
|
|
103
103
|
branchListProps.length = 0;
|
|
104
104
|
branchActionProps.length = 0;
|
|
105
105
|
aiToolProps.length = 0;
|
|
106
|
+
branchQuickStartProps.length = 0;
|
|
106
107
|
|
|
107
108
|
useGitDataMock.mockReset();
|
|
108
109
|
switchToProtectedBranchMock.mockReset();
|
|
@@ -194,7 +195,6 @@ describe("App protected branch handling", () => {
|
|
|
194
195
|
await act(async () => {
|
|
195
196
|
actionProps?.onUseExisting();
|
|
196
197
|
await Promise.resolve();
|
|
197
|
-
await Promise.resolve();
|
|
198
198
|
});
|
|
199
199
|
|
|
200
200
|
expect(switchToProtectedBranchMock).toHaveBeenCalledWith({
|
|
@@ -206,6 +206,7 @@ describe("App protected branch handling", () => {
|
|
|
206
206
|
expect(navigateToMock).toHaveBeenCalledWith("branch-action-selector");
|
|
207
207
|
// When branchQuickStart is empty, navigates to ai-tool-selector instead of branch-quick-start
|
|
208
208
|
// So AIToolSelectorScreen should be rendered, not BranchQuickStartScreen
|
|
209
|
+
expect(branchQuickStartProps).toHaveLength(0);
|
|
209
210
|
expect(aiToolProps).not.toHaveLength(0);
|
|
210
211
|
});
|
|
211
212
|
});
|
|
@@ -35,10 +35,10 @@ vi.mock("../../hooks/useScreenState.js", () => ({
|
|
|
35
35
|
useScreenState: (...args: unknown[]) => useScreenStateMock(...args),
|
|
36
36
|
}));
|
|
37
37
|
|
|
38
|
-
vi.mock("../../../../worktree.
|
|
38
|
+
vi.mock("../../../../worktree.ts", async () => {
|
|
39
39
|
const actual = await vi.importActual<
|
|
40
|
-
typeof import("../../../../worktree.
|
|
41
|
-
>("../../../../worktree.
|
|
40
|
+
typeof import("../../../../worktree.ts")
|
|
41
|
+
>("../../../../worktree.ts");
|
|
42
42
|
return {
|
|
43
43
|
...actual,
|
|
44
44
|
getMergedPRWorktrees: getMergedPRWorktreesMock,
|
|
@@ -48,10 +48,10 @@ vi.mock("../../../../worktree.js", async () => {
|
|
|
48
48
|
};
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
vi.mock("../../../../git.
|
|
51
|
+
vi.mock("../../../../git.ts", async () => {
|
|
52
52
|
const actual =
|
|
53
|
-
await vi.importActual<typeof import("../../../../git.
|
|
54
|
-
"../../../../git.
|
|
53
|
+
await vi.importActual<typeof import("../../../../git.ts")>(
|
|
54
|
+
"../../../../git.ts",
|
|
55
55
|
);
|
|
56
56
|
return {
|
|
57
57
|
...actual,
|
|
@@ -92,8 +92,33 @@ describe("App shortcuts integration", () => {
|
|
|
92
92
|
goBackMock.mockClear();
|
|
93
93
|
resetMock.mockClear();
|
|
94
94
|
useGitDataMock.mockReturnValue({
|
|
95
|
-
branches: [
|
|
95
|
+
branches: [
|
|
96
|
+
{
|
|
97
|
+
name: "feature/add-new-feature",
|
|
98
|
+
type: "local",
|
|
99
|
+
branchType: "feature",
|
|
100
|
+
isCurrent: false,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "hotfix/urgent-fix",
|
|
104
|
+
type: "local",
|
|
105
|
+
branchType: "hotfix",
|
|
106
|
+
isCurrent: false,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
96
109
|
worktrees: [
|
|
110
|
+
{
|
|
111
|
+
branch: "feature/add-new-feature",
|
|
112
|
+
path: "/worktrees/feature-add-new-feature",
|
|
113
|
+
isAccessible: true,
|
|
114
|
+
hasUncommittedChanges: false,
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
branch: "hotfix/urgent-fix",
|
|
118
|
+
path: "/worktrees/hotfix-urgent-fix",
|
|
119
|
+
isAccessible: true,
|
|
120
|
+
hasUncommittedChanges: true,
|
|
121
|
+
},
|
|
97
122
|
{
|
|
98
123
|
branch: "feature/existing",
|
|
99
124
|
path: "/worktrees/feature-existing",
|
|
@@ -195,8 +220,102 @@ describe("App shortcuts integration", () => {
|
|
|
195
220
|
expect(navigateToMock).toHaveBeenCalledWith("ai-tool-selector");
|
|
196
221
|
});
|
|
197
222
|
|
|
223
|
+
it("shows warning when cleanup runs without selection", async () => {
|
|
224
|
+
const onExit = vi.fn();
|
|
225
|
+
|
|
226
|
+
render(<App onExit={onExit} />);
|
|
227
|
+
|
|
228
|
+
const initialProps = branchListProps.at(-1);
|
|
229
|
+
expect(initialProps).toBeDefined();
|
|
230
|
+
|
|
231
|
+
act(() => {
|
|
232
|
+
initialProps?.onCleanupCommand?.();
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
await act(async () => {
|
|
236
|
+
await Promise.resolve();
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
const latestProps = branchListProps.at(-1);
|
|
240
|
+
expect(latestProps?.cleanupUI?.footerMessage?.text).toBe(
|
|
241
|
+
"クリーンアップ対象が選択されていません",
|
|
242
|
+
);
|
|
243
|
+
expect(removeWorktreeMock).not.toHaveBeenCalled();
|
|
244
|
+
expect(deleteBranchMock).not.toHaveBeenCalled();
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("marks branches safe only when merged and clean", () => {
|
|
248
|
+
const onExit = vi.fn();
|
|
249
|
+
const refresh = vi.fn();
|
|
250
|
+
useGitDataMock.mockReturnValue({
|
|
251
|
+
branches: [
|
|
252
|
+
{
|
|
253
|
+
name: "feature/merged-clean",
|
|
254
|
+
type: "local",
|
|
255
|
+
branchType: "feature",
|
|
256
|
+
isCurrent: false,
|
|
257
|
+
mergedPR: { number: 101, mergedAt: "2025-01-02T10:00:00Z" },
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
name: "feature/merged-unpushed",
|
|
261
|
+
type: "local",
|
|
262
|
+
branchType: "feature",
|
|
263
|
+
isCurrent: false,
|
|
264
|
+
hasUnpushedCommits: true,
|
|
265
|
+
mergedPR: { number: 102, mergedAt: "2025-01-03T10:00:00Z" },
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "feature/unmerged",
|
|
269
|
+
type: "local",
|
|
270
|
+
branchType: "feature",
|
|
271
|
+
isCurrent: false,
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
worktrees: [
|
|
275
|
+
{
|
|
276
|
+
branch: "feature/merged-clean",
|
|
277
|
+
path: "/worktrees/merged-clean",
|
|
278
|
+
isAccessible: true,
|
|
279
|
+
hasUncommittedChanges: false,
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
branch: "feature/merged-unpushed",
|
|
283
|
+
path: "/worktrees/merged-unpushed",
|
|
284
|
+
isAccessible: true,
|
|
285
|
+
hasUncommittedChanges: false,
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
branch: "feature/unmerged",
|
|
289
|
+
path: "/worktrees/unmerged",
|
|
290
|
+
isAccessible: true,
|
|
291
|
+
hasUncommittedChanges: false,
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
loading: false,
|
|
295
|
+
error: null,
|
|
296
|
+
refresh,
|
|
297
|
+
lastUpdated: null,
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
render(<App onExit={onExit} />);
|
|
301
|
+
|
|
302
|
+
const latestProps = branchListProps.at(-1);
|
|
303
|
+
const safeMap = new Map(
|
|
304
|
+
latestProps?.branches?.map((branch: BranchItem) => [
|
|
305
|
+
branch.name,
|
|
306
|
+
branch.safeToCleanup,
|
|
307
|
+
]),
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
expect(safeMap.get("feature/merged-clean")).toBe(true);
|
|
311
|
+
expect(safeMap.get("feature/merged-unpushed")).toBe(false);
|
|
312
|
+
expect(safeMap.get("feature/unmerged")).toBe(false);
|
|
313
|
+
});
|
|
314
|
+
|
|
198
315
|
it("displays per-branch cleanup indicators and waits before clearing results", async () => {
|
|
199
316
|
vi.useFakeTimers();
|
|
317
|
+
const originalNodeEnv = process.env.NODE_ENV;
|
|
318
|
+
process.env.NODE_ENV = "production";
|
|
200
319
|
|
|
201
320
|
try {
|
|
202
321
|
const onExit = vi.fn();
|
|
@@ -234,8 +353,22 @@ describe("App shortcuts integration", () => {
|
|
|
234
353
|
throw new Error("BranchListScreen props missing");
|
|
235
354
|
}
|
|
236
355
|
|
|
356
|
+
await act(async () => {
|
|
357
|
+
initialProps.onToggleSelect?.("feature/add-new-feature");
|
|
358
|
+
initialProps.onToggleSelect?.("hotfix/urgent-fix");
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
await act(async () => {
|
|
362
|
+
await Promise.resolve();
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
const selectedProps = branchListProps.at(-1);
|
|
366
|
+
expect(selectedProps?.selectedBranches).toEqual([
|
|
367
|
+
"feature/add-new-feature",
|
|
368
|
+
"hotfix/urgent-fix",
|
|
369
|
+
]);
|
|
237
370
|
act(() => {
|
|
238
|
-
|
|
371
|
+
selectedProps?.onCleanupCommand?.();
|
|
239
372
|
});
|
|
240
373
|
|
|
241
374
|
await act(async () => {
|
|
@@ -296,6 +429,7 @@ describe("App shortcuts integration", () => {
|
|
|
296
429
|
),
|
|
297
430
|
).toBe(false);
|
|
298
431
|
} finally {
|
|
432
|
+
process.env.NODE_ENV = originalNodeEnv;
|
|
299
433
|
vi.useRealTimers();
|
|
300
434
|
}
|
|
301
435
|
});
|
|
@@ -251,6 +251,7 @@ describe("App", () => {
|
|
|
251
251
|
});
|
|
252
252
|
|
|
253
253
|
describe("BranchActionSelectorScreen integration", () => {
|
|
254
|
+
// TODO: replace placeholder assertions with real integration checks.
|
|
254
255
|
it("should show BranchActionSelectorScreen after branch selection", () => {
|
|
255
256
|
useGitDataMock.mockImplementation(() => ({
|
|
256
257
|
branches: mockBranches,
|
|
@@ -263,7 +264,7 @@ describe("App", () => {
|
|
|
263
264
|
const onExit = vi.fn();
|
|
264
265
|
const { container } = render(<App onExit={onExit} />);
|
|
265
266
|
|
|
266
|
-
//
|
|
267
|
+
// TODO: verify BranchActionSelectorScreen appears
|
|
267
268
|
expect(container).toBeDefined();
|
|
268
269
|
});
|
|
269
270
|
|
|
@@ -279,7 +280,7 @@ describe("App", () => {
|
|
|
279
280
|
const onExit = vi.fn();
|
|
280
281
|
const { container } = render(<App onExit={onExit} />);
|
|
281
282
|
|
|
282
|
-
//
|
|
283
|
+
// TODO: verify navigation to AIToolSelectorScreen
|
|
283
284
|
expect(container).toBeDefined();
|
|
284
285
|
});
|
|
285
286
|
|
|
@@ -295,7 +296,7 @@ describe("App", () => {
|
|
|
295
296
|
const onExit = vi.fn();
|
|
296
297
|
const { container } = render(<App onExit={onExit} />);
|
|
297
298
|
|
|
298
|
-
//
|
|
299
|
+
// TODO: verify navigation to BranchCreatorScreen
|
|
299
300
|
expect(container).toBeDefined();
|
|
300
301
|
});
|
|
301
302
|
});
|
|
@@ -54,6 +54,7 @@ describe("ModelSelectorScreen initial selection", () => {
|
|
|
54
54
|
|
|
55
55
|
await waitFor(() => expect(selectMocks.length).toBeGreaterThan(0));
|
|
56
56
|
const modelSelect = selectMocks.at(-1);
|
|
57
|
+
expect(modelSelect).toBeDefined();
|
|
57
58
|
const index = modelSelect.initialIndex as number;
|
|
58
59
|
// codex-cli models: ["", gpt-5.2-codex, gpt-5.1-codex-max, gpt-5.1-codex-mini, gpt-5.2]
|
|
59
60
|
// (index 0 = Default/Auto, index 2 = gpt-5.1-codex-max)
|
|
@@ -12,6 +12,9 @@ interface TestItem {
|
|
|
12
12
|
value: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
const delay = (ms = 0): Promise<void> =>
|
|
16
|
+
new Promise((resolve) => setTimeout(resolve, ms));
|
|
17
|
+
|
|
15
18
|
describe("Select", () => {
|
|
16
19
|
const mockItems: TestItem[] = [
|
|
17
20
|
{ label: "Option 1", value: "opt1" },
|
|
@@ -281,4 +284,46 @@ describe("Select", () => {
|
|
|
281
284
|
expect(onSelect).not.toHaveBeenCalled();
|
|
282
285
|
});
|
|
283
286
|
});
|
|
287
|
+
|
|
288
|
+
describe('Space/Escape handlers', () => {
|
|
289
|
+
it('should call onSpace with the currently highlighted item', async () => {
|
|
290
|
+
const onSelect = vi.fn();
|
|
291
|
+
const onSpace = vi.fn();
|
|
292
|
+
const { stdin } = render(
|
|
293
|
+
<Select items={mockItems} onSelect={onSelect} onSpace={onSpace} />
|
|
294
|
+
);
|
|
295
|
+
|
|
296
|
+
stdin.write(' ');
|
|
297
|
+
await delay(10);
|
|
298
|
+
|
|
299
|
+
expect(onSpace).toHaveBeenCalledTimes(1);
|
|
300
|
+
expect(onSpace).toHaveBeenCalledWith(mockItems[0]);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
it('should not trigger onSpace when disabled', async () => {
|
|
304
|
+
const onSelect = vi.fn();
|
|
305
|
+
const onSpace = vi.fn();
|
|
306
|
+
const { stdin } = render(
|
|
307
|
+
<Select items={mockItems} onSelect={onSelect} onSpace={onSpace} disabled />
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
stdin.write(' ');
|
|
311
|
+
await delay(10);
|
|
312
|
+
|
|
313
|
+
expect(onSpace).not.toHaveBeenCalled();
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it('should call onEscape when escape key is pressed', async () => {
|
|
317
|
+
const onSelect = vi.fn();
|
|
318
|
+
const onEscape = vi.fn();
|
|
319
|
+
const { stdin } = render(
|
|
320
|
+
<Select items={mockItems} onSelect={onSelect} onEscape={onEscape} />
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
stdin.write('\u001B');
|
|
324
|
+
await delay(30);
|
|
325
|
+
|
|
326
|
+
expect(onEscape).toHaveBeenCalledTimes(1);
|
|
327
|
+
});
|
|
328
|
+
});
|
|
284
329
|
});
|