@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.
Files changed (295) hide show
  1. package/README.ja.md +33 -0
  2. package/README.md +31 -0
  3. package/dist/claude.d.ts.map +1 -1
  4. package/dist/claude.js +17 -11
  5. package/dist/claude.js.map +1 -1
  6. package/dist/cli/ui/components/App.d.ts +0 -6
  7. package/dist/cli/ui/components/App.d.ts.map +1 -1
  8. package/dist/cli/ui/components/App.js +27 -88
  9. package/dist/cli/ui/components/App.js.map +1 -1
  10. package/dist/cli/ui/components/common/Select.js +2 -2
  11. package/dist/cli/ui/components/common/Select.js.map +1 -1
  12. package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +1 -1
  13. package/dist/cli/ui/components/screens/BranchListScreen.js +14 -2
  14. package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -1
  15. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +1 -1
  16. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +3 -3
  17. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +1 -1
  18. package/dist/cli/ui/utils/continueSession.d.ts.map +1 -1
  19. package/dist/cli/ui/utils/continueSession.js +1 -1
  20. package/dist/cli/ui/utils/continueSession.js.map +1 -1
  21. package/dist/client/assets/index-DPWWHorC.js +72 -0
  22. package/dist/client/assets/index-DsDNCy5f.css +1 -0
  23. package/dist/client/index.html +2 -2
  24. package/dist/codex.d.ts.map +1 -1
  25. package/dist/codex.js +21 -11
  26. package/dist/codex.js.map +1 -1
  27. package/dist/config/builtin-tools.d.ts.map +1 -1
  28. package/dist/config/builtin-tools.js +3 -2
  29. package/dist/config/builtin-tools.js.map +1 -1
  30. package/dist/config/shared-env.d.ts +41 -0
  31. package/dist/config/shared-env.d.ts.map +1 -0
  32. package/dist/config/shared-env.js +114 -0
  33. package/dist/config/shared-env.js.map +1 -0
  34. package/dist/gemini.d.ts.map +1 -1
  35. package/dist/gemini.js +20 -17
  36. package/dist/gemini.js.map +1 -1
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +49 -7
  39. package/dist/index.js.map +1 -1
  40. package/dist/logging/logger.d.ts.map +1 -1
  41. package/dist/logging/logger.js +4 -1
  42. package/dist/logging/logger.js.map +1 -1
  43. package/dist/qwen.d.ts.map +1 -1
  44. package/dist/qwen.js +15 -11
  45. package/dist/qwen.js.map +1 -1
  46. package/dist/services/aiToolResolver.d.ts +41 -0
  47. package/dist/services/aiToolResolver.d.ts.map +1 -0
  48. package/dist/services/aiToolResolver.js +194 -0
  49. package/dist/services/aiToolResolver.js.map +1 -0
  50. package/dist/services/customToolResolver.d.ts +10 -0
  51. package/dist/services/customToolResolver.d.ts.map +1 -0
  52. package/dist/services/customToolResolver.js +71 -0
  53. package/dist/services/customToolResolver.js.map +1 -0
  54. package/dist/shared/aiToolConstants.d.ts +9 -0
  55. package/dist/shared/aiToolConstants.d.ts.map +1 -0
  56. package/dist/shared/aiToolConstants.js +29 -0
  57. package/dist/shared/aiToolConstants.js.map +1 -0
  58. package/dist/types/tools.d.ts +12 -0
  59. package/dist/types/tools.d.ts.map +1 -1
  60. package/dist/utils/prompt.d.ts.map +1 -1
  61. package/dist/utils/prompt.js.map +1 -1
  62. package/dist/utils/session.d.ts.map +1 -1
  63. package/dist/utils/session.js +15 -6
  64. package/dist/utils/session.js.map +1 -1
  65. package/dist/utils/terminal.d.ts +12 -3
  66. package/dist/utils/terminal.d.ts.map +1 -1
  67. package/dist/utils/terminal.js +5 -34
  68. package/dist/utils/terminal.js.map +1 -1
  69. package/dist/utils/webui.d.ts +8 -0
  70. package/dist/utils/webui.d.ts.map +1 -0
  71. package/dist/utils/webui.js +35 -0
  72. package/dist/utils/webui.js.map +1 -0
  73. package/dist/web/client/src/components/AIToolLaunchModal.d.ts +9 -0
  74. package/dist/web/client/src/components/AIToolLaunchModal.d.ts.map +1 -0
  75. package/dist/web/client/src/components/AIToolLaunchModal.js +363 -0
  76. package/dist/web/client/src/components/AIToolLaunchModal.js.map +1 -0
  77. package/dist/web/client/src/components/BranchGraph.d.ts.map +1 -1
  78. package/dist/web/client/src/components/BranchGraph.js +46 -49
  79. package/dist/web/client/src/components/BranchGraph.js.map +1 -1
  80. package/dist/web/client/src/components/CustomToolForm.d.ts +23 -0
  81. package/dist/web/client/src/components/CustomToolForm.d.ts.map +1 -0
  82. package/dist/web/client/src/components/CustomToolForm.js +209 -0
  83. package/dist/web/client/src/components/CustomToolForm.js.map +1 -0
  84. package/dist/web/client/src/components/CustomToolList.d.ts +10 -0
  85. package/dist/web/client/src/components/CustomToolList.d.ts.map +1 -0
  86. package/dist/web/client/src/components/CustomToolList.js +57 -0
  87. package/dist/web/client/src/components/CustomToolList.js.map +1 -0
  88. package/dist/web/client/src/components/EnvEditor.d.ts.map +1 -1
  89. package/dist/web/client/src/components/EnvEditor.js +33 -26
  90. package/dist/web/client/src/components/EnvEditor.js.map +1 -1
  91. package/dist/web/client/src/components/EnvironmentEditor.d.ts +17 -0
  92. package/dist/web/client/src/components/EnvironmentEditor.d.ts.map +1 -0
  93. package/dist/web/client/src/components/EnvironmentEditor.js +22 -0
  94. package/dist/web/client/src/components/EnvironmentEditor.js.map +1 -0
  95. package/dist/web/client/src/components/Terminal.d.ts.map +1 -1
  96. package/dist/web/client/src/components/Terminal.js +10 -3
  97. package/dist/web/client/src/components/Terminal.js.map +1 -1
  98. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts +10 -0
  99. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -0
  100. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +104 -0
  101. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -0
  102. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts +22 -0
  103. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.d.ts.map +1 -0
  104. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js +79 -0
  105. package/dist/web/client/src/components/branch-detail/SessionHistoryTable.js.map +1 -0
  106. package/dist/web/client/src/components/branch-detail/TerminalPanel.d.ts +11 -0
  107. package/dist/web/client/src/components/branch-detail/TerminalPanel.d.ts.map +1 -0
  108. package/dist/web/client/src/components/branch-detail/TerminalPanel.js +32 -0
  109. package/dist/web/client/src/components/branch-detail/TerminalPanel.js.map +1 -0
  110. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts +40 -0
  111. package/dist/web/client/src/components/branch-detail/ToolLauncher.d.ts.map +1 -0
  112. package/dist/web/client/src/components/branch-detail/ToolLauncher.js +147 -0
  113. package/dist/web/client/src/components/branch-detail/ToolLauncher.js.map +1 -0
  114. package/dist/web/client/src/components/branch-detail/index.d.ts +5 -0
  115. package/dist/web/client/src/components/branch-detail/index.d.ts.map +1 -0
  116. package/dist/web/client/src/components/branch-detail/index.js +5 -0
  117. package/dist/web/client/src/components/branch-detail/index.js.map +1 -0
  118. package/dist/web/client/src/components/common/BranchCard.d.ts +17 -0
  119. package/dist/web/client/src/components/common/BranchCard.d.ts.map +1 -0
  120. package/dist/web/client/src/components/common/BranchCard.js +36 -0
  121. package/dist/web/client/src/components/common/BranchCard.js.map +1 -0
  122. package/dist/web/client/src/components/common/MetricCard.d.ts +10 -0
  123. package/dist/web/client/src/components/common/MetricCard.d.ts.map +1 -0
  124. package/dist/web/client/src/components/common/MetricCard.js +10 -0
  125. package/dist/web/client/src/components/common/MetricCard.js.map +1 -0
  126. package/dist/web/client/src/components/common/PageHeader.d.ts +12 -0
  127. package/dist/web/client/src/components/common/PageHeader.d.ts.map +1 -0
  128. package/dist/web/client/src/components/common/PageHeader.js +14 -0
  129. package/dist/web/client/src/components/common/PageHeader.js.map +1 -0
  130. package/dist/web/client/src/components/common/SearchInput.d.ts +14 -0
  131. package/dist/web/client/src/components/common/SearchInput.d.ts.map +1 -0
  132. package/dist/web/client/src/components/common/SearchInput.js +15 -0
  133. package/dist/web/client/src/components/common/SearchInput.js.map +1 -0
  134. package/dist/web/client/src/components/common/StatusBadge.d.ts +10 -0
  135. package/dist/web/client/src/components/common/StatusBadge.d.ts.map +1 -0
  136. package/dist/web/client/src/components/common/StatusBadge.js +15 -0
  137. package/dist/web/client/src/components/common/StatusBadge.js.map +1 -0
  138. package/dist/web/client/src/components/common/index.d.ts +6 -0
  139. package/dist/web/client/src/components/common/index.d.ts.map +1 -0
  140. package/dist/web/client/src/components/common/index.js +6 -0
  141. package/dist/web/client/src/components/common/index.js.map +1 -0
  142. package/dist/web/client/src/components/ui/alert.d.ts +9 -0
  143. package/dist/web/client/src/components/ui/alert.d.ts.map +1 -0
  144. package/dist/web/client/src/components/ui/alert.js +25 -0
  145. package/dist/web/client/src/components/ui/alert.js.map +1 -0
  146. package/dist/web/client/src/components/ui/badge.d.ts +10 -0
  147. package/dist/web/client/src/components/ui/badge.d.ts.map +1 -0
  148. package/dist/web/client/src/components/ui/badge.js +25 -0
  149. package/dist/web/client/src/components/ui/badge.js.map +1 -0
  150. package/dist/web/client/src/components/ui/button.d.ts +12 -0
  151. package/dist/web/client/src/components/ui/button.d.ts.map +1 -0
  152. package/dist/web/client/src/components/ui/button.js +33 -0
  153. package/dist/web/client/src/components/ui/button.js.map +1 -0
  154. package/dist/web/client/src/components/ui/card.d.ts +9 -0
  155. package/dist/web/client/src/components/ui/card.d.ts.map +1 -0
  156. package/dist/web/client/src/components/ui/card.js +16 -0
  157. package/dist/web/client/src/components/ui/card.js.map +1 -0
  158. package/dist/web/client/src/components/ui/index.d.ts +8 -0
  159. package/dist/web/client/src/components/ui/index.d.ts.map +1 -0
  160. package/dist/web/client/src/components/ui/index.js +8 -0
  161. package/dist/web/client/src/components/ui/index.js.map +1 -0
  162. package/dist/web/client/src/components/ui/input.d.ts +4 -0
  163. package/dist/web/client/src/components/ui/input.d.ts.map +1 -0
  164. package/dist/web/client/src/components/ui/input.js +8 -0
  165. package/dist/web/client/src/components/ui/input.js.map +1 -0
  166. package/dist/web/client/src/components/ui/select.d.ts +14 -0
  167. package/dist/web/client/src/components/ui/select.d.ts.map +1 -0
  168. package/dist/web/client/src/components/ui/select.js +39 -0
  169. package/dist/web/client/src/components/ui/select.js.map +1 -0
  170. package/dist/web/client/src/components/ui/table.d.ts +11 -0
  171. package/dist/web/client/src/components/ui/table.d.ts.map +1 -0
  172. package/dist/web/client/src/components/ui/table.js +21 -0
  173. package/dist/web/client/src/components/ui/table.js.map +1 -0
  174. package/dist/web/client/src/hooks/useSessions.d.ts.map +1 -1
  175. package/dist/web/client/src/hooks/useSessions.js +6 -1
  176. package/dist/web/client/src/hooks/useSessions.js.map +1 -1
  177. package/dist/web/client/src/lib/utils.d.ts +7 -0
  178. package/dist/web/client/src/lib/utils.d.ts.map +1 -0
  179. package/dist/web/client/src/lib/utils.js +10 -0
  180. package/dist/web/client/src/lib/utils.js.map +1 -0
  181. package/dist/web/client/src/lib/websocket.d.ts +7 -0
  182. package/dist/web/client/src/lib/websocket.d.ts.map +1 -1
  183. package/dist/web/client/src/lib/websocket.js +44 -0
  184. package/dist/web/client/src/lib/websocket.js.map +1 -1
  185. package/dist/web/client/src/pages/BranchDetailPage.d.ts.map +1 -1
  186. package/dist/web/client/src/pages/BranchDetailPage.js +113 -361
  187. package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -1
  188. package/dist/web/client/src/pages/BranchListPage.d.ts.map +1 -1
  189. package/dist/web/client/src/pages/BranchListPage.js +89 -127
  190. package/dist/web/client/src/pages/BranchListPage.js.map +1 -1
  191. package/dist/web/client/src/pages/ConfigManagementPage.d.ts.map +1 -1
  192. package/dist/web/client/src/pages/ConfigManagementPage.js +46 -41
  193. package/dist/web/client/src/pages/ConfigManagementPage.js.map +1 -1
  194. package/dist/web/client/src/pages/ConfigPage.d.ts +3 -0
  195. package/dist/web/client/src/pages/ConfigPage.d.ts.map +1 -0
  196. package/dist/web/client/src/pages/ConfigPage.js +216 -0
  197. package/dist/web/client/src/pages/ConfigPage.js.map +1 -0
  198. package/dist/web/client/vite.config.d.ts.map +1 -1
  199. package/dist/web/client/vite.config.js +8 -1
  200. package/dist/web/client/vite.config.js.map +1 -1
  201. package/dist/web/server/index.d.ts +24 -2
  202. package/dist/web/server/index.d.ts.map +1 -1
  203. package/dist/web/server/index.js +46 -15
  204. package/dist/web/server/index.js.map +1 -1
  205. package/dist/web/server/pty/manager.d.ts +12 -10
  206. package/dist/web/server/pty/manager.d.ts.map +1 -1
  207. package/dist/web/server/pty/manager.js +76 -43
  208. package/dist/web/server/pty/manager.js.map +1 -1
  209. package/dist/web/server/routes/sessions.d.ts.map +1 -1
  210. package/dist/web/server/routes/sessions.js +35 -2
  211. package/dist/web/server/routes/sessions.js.map +1 -1
  212. package/dist/web/server/routes/worktrees.js +2 -2
  213. package/dist/web/server/routes/worktrees.js.map +1 -1
  214. package/dist/web/server/services/worktrees.d.ts.map +1 -1
  215. package/dist/web/server/services/worktrees.js +7 -1
  216. package/dist/web/server/services/worktrees.js.map +1 -1
  217. package/dist/web/server/tray.d.ts +24 -0
  218. package/dist/web/server/tray.d.ts.map +1 -0
  219. package/dist/web/server/tray.js +79 -0
  220. package/dist/web/server/tray.js.map +1 -0
  221. package/dist/web/server/websocket/handler.d.ts +18 -2
  222. package/dist/web/server/websocket/handler.d.ts.map +1 -1
  223. package/dist/web/server/websocket/handler.js +82 -9
  224. package/dist/web/server/websocket/handler.js.map +1 -1
  225. package/package.json +15 -2
  226. package/src/claude.ts +26 -15
  227. package/src/cli/ui/__tests__/components/common/Select.test.tsx +11 -0
  228. package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +17 -1
  229. package/src/cli/ui/__tests__/components/screens/BranchQuickStartScreen.test.tsx +4 -4
  230. package/src/cli/ui/components/App.tsx +33 -133
  231. package/src/cli/ui/components/common/Select.tsx +2 -2
  232. package/src/cli/ui/components/screens/BranchListScreen.tsx +43 -23
  233. package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +41 -46
  234. package/src/cli/ui/utils/continueSession.ts +1 -7
  235. package/src/codex.ts +31 -22
  236. package/src/config/builtin-tools.ts +6 -2
  237. package/src/config/shared-env.ts +139 -0
  238. package/src/gemini.ts +35 -22
  239. package/src/index.ts +54 -7
  240. package/src/logging/logger.ts +5 -2
  241. package/src/qwen.ts +28 -19
  242. package/src/services/aiToolResolver.ts +276 -0
  243. package/src/services/customToolResolver.ts +98 -0
  244. package/src/shared/aiToolConstants.ts +30 -0
  245. package/src/trayicon.d.ts +30 -0
  246. package/src/types/tools.ts +15 -0
  247. package/src/utils/prompt.ts +15 -9
  248. package/src/utils/session.ts +80 -26
  249. package/src/utils/terminal.ts +11 -41
  250. package/src/utils/webui.ts +43 -0
  251. package/src/web/client/components.json +21 -0
  252. package/src/web/client/src/components/AIToolLaunchModal.tsx +575 -0
  253. package/src/web/client/src/components/BranchGraph.tsx +95 -75
  254. package/src/web/client/src/components/CustomToolForm.tsx +386 -0
  255. package/src/web/client/src/components/CustomToolList.tsx +119 -0
  256. package/src/web/client/src/components/EnvEditor.tsx +91 -81
  257. package/src/web/client/src/components/EnvironmentEditor.tsx +97 -0
  258. package/src/web/client/src/components/Terminal.tsx +11 -3
  259. package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +179 -0
  260. package/src/web/client/src/components/branch-detail/SessionHistoryTable.tsx +181 -0
  261. package/src/web/client/src/components/branch-detail/TerminalPanel.tsx +92 -0
  262. package/src/web/client/src/components/branch-detail/ToolLauncher.tsx +327 -0
  263. package/src/web/client/src/components/branch-detail/index.ts +4 -0
  264. package/src/web/client/src/components/common/BranchCard.tsx +117 -0
  265. package/src/web/client/src/components/common/MetricCard.tsx +22 -0
  266. package/src/web/client/src/components/common/PageHeader.tsx +44 -0
  267. package/src/web/client/src/components/common/SearchInput.tsx +40 -0
  268. package/src/web/client/src/components/common/StatusBadge.tsx +37 -0
  269. package/src/web/client/src/components/common/index.ts +5 -0
  270. package/src/web/client/src/components/ui/alert.tsx +63 -0
  271. package/src/web/client/src/components/ui/badge.tsx +44 -0
  272. package/src/web/client/src/components/ui/button.tsx +57 -0
  273. package/src/web/client/src/components/ui/card.tsx +82 -0
  274. package/src/web/client/src/components/ui/index.ts +32 -0
  275. package/src/web/client/src/components/ui/input.tsx +21 -0
  276. package/src/web/client/src/components/ui/select.tsx +156 -0
  277. package/src/web/client/src/components/ui/table.tsx +119 -0
  278. package/src/web/client/src/hooks/useSessions.ts +10 -1
  279. package/src/web/client/src/index.css +46 -816
  280. package/src/web/client/src/lib/utils.ts +10 -0
  281. package/src/web/client/src/lib/websocket.ts +48 -1
  282. package/src/web/client/src/pages/BranchDetailPage.tsx +222 -694
  283. package/src/web/client/src/pages/BranchListPage.tsx +190 -236
  284. package/src/web/client/src/pages/ConfigManagementPage.tsx +94 -76
  285. package/src/web/client/src/pages/ConfigPage.tsx +362 -0
  286. package/src/web/client/vite.config.ts +8 -1
  287. package/src/web/server/index.ts +72 -15
  288. package/src/web/server/pty/manager.ts +128 -55
  289. package/src/web/server/routes/sessions.ts +59 -7
  290. package/src/web/server/routes/worktrees.ts +3 -3
  291. package/src/web/server/services/worktrees.ts +12 -4
  292. package/src/web/server/tray.ts +93 -0
  293. package/src/web/server/websocket/handler.ts +119 -13
  294. package/dist/client/assets/index-DeNwPosA.css +0 -1
  295. package/dist/client/assets/index-Dl798X5w.js +0 -32
@@ -11,7 +11,9 @@ const UUID_REGEX =
11
11
  * @returns true if the string is a valid UUID format
12
12
  */
13
13
  export function isValidUuidSessionId(id: string): boolean {
14
- return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);
14
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
15
+ id,
16
+ );
15
17
  }
16
18
 
17
19
  function pickSessionIdFromObject(obj: unknown): string | null {
@@ -34,7 +36,13 @@ function pickSessionIdFromObject(obj: unknown): string | null {
34
36
  function pickCwdFromObject(obj: unknown): string | null {
35
37
  if (!obj || typeof obj !== "object") return null;
36
38
  const candidate = obj as Record<string, unknown>;
37
- const keys = ["cwd", "workingDirectory", "workdir", "directory", "projectPath"];
39
+ const keys = [
40
+ "cwd",
41
+ "workingDirectory",
42
+ "workdir",
43
+ "directory",
44
+ "projectPath",
45
+ ];
38
46
  for (const key of keys) {
39
47
  const value = candidate[key];
40
48
  if (typeof value === "string" && value.trim().length > 0) {
@@ -118,7 +126,12 @@ async function findLatestFile(
118
126
  async function findNewestSessionIdFromDir(
119
127
  dir: string,
120
128
  recursive: boolean,
121
- options: { since?: number; until?: number; preferClosestTo?: number; windowMs?: number } = {},
129
+ options: {
130
+ since?: number;
131
+ until?: number;
132
+ preferClosestTo?: number;
133
+ windowMs?: number;
134
+ } = {},
122
135
  ): Promise<{ id: string; mtime: number } | null> {
123
136
  try {
124
137
  const files: { fullPath: string; mtime: number }[] = [];
@@ -423,7 +436,12 @@ function generateClaudeProjectPathCandidates(cwd: string): string[] {
423
436
 
424
437
  export async function findLatestClaudeSessionId(
425
438
  cwd: string,
426
- options: { since?: number; until?: number; preferClosestTo?: number; windowMs?: number } = {},
439
+ options: {
440
+ since?: number;
441
+ until?: number;
442
+ preferClosestTo?: number;
443
+ windowMs?: number;
444
+ } = {},
427
445
  ): Promise<string | null> {
428
446
  const found = await findLatestClaudeSession(cwd, options);
429
447
  return found?.id ?? null;
@@ -436,7 +454,12 @@ export interface ClaudeSessionInfo {
436
454
 
437
455
  export async function findLatestClaudeSession(
438
456
  cwd: string,
439
- options: { since?: number; until?: number; preferClosestTo?: number; windowMs?: number } = {},
457
+ options: {
458
+ since?: number;
459
+ until?: number;
460
+ preferClosestTo?: number;
461
+ windowMs?: number;
462
+ } = {},
440
463
  ): Promise<ClaudeSessionInfo | null> {
441
464
  const rootCandidates: string[] = [];
442
465
  if (process.env.CLAUDE_CONFIG_DIR) {
@@ -481,9 +504,15 @@ export async function findLatestClaudeSession(
481
504
  try {
482
505
  const line = lines[i] ?? "";
483
506
  const parsed = JSON.parse(line) as Record<string, unknown>;
484
- const project = typeof parsed.project === "string" ? parsed.project : null;
485
- const sessionId = typeof parsed.sessionId === "string" ? parsed.sessionId : null;
486
- if (project && sessionId && (project === cwd || cwd.startsWith(project))) {
507
+ const project =
508
+ typeof parsed.project === "string" ? parsed.project : null;
509
+ const sessionId =
510
+ typeof parsed.sessionId === "string" ? parsed.sessionId : null;
511
+ if (
512
+ project &&
513
+ sessionId &&
514
+ (project === cwd || cwd.startsWith(project))
515
+ ) {
487
516
  return { id: sessionId, mtime: Date.now() };
488
517
  }
489
518
  } catch {
@@ -513,10 +542,16 @@ export async function waitForClaudeSessionId(
513
542
  const deadline = Date.now() + timeoutMs;
514
543
 
515
544
  while (Date.now() < deadline) {
516
- const opt: { since?: number; until?: number; preferClosestTo?: number; windowMs?: number } = {};
545
+ const opt: {
546
+ since?: number;
547
+ until?: number;
548
+ preferClosestTo?: number;
549
+ windowMs?: number;
550
+ } = {};
517
551
  if (options.since !== undefined) opt.since = options.since;
518
552
  if (options.until !== undefined) opt.until = options.until;
519
- if (options.preferClosestTo !== undefined) opt.preferClosestTo = options.preferClosestTo;
553
+ if (options.preferClosestTo !== undefined)
554
+ opt.preferClosestTo = options.preferClosestTo;
520
555
  if (options.windowMs !== undefined) opt.windowMs = options.windowMs;
521
556
 
522
557
  const found = await findLatestClaudeSession(cwd, opt);
@@ -560,7 +595,13 @@ async function findLatestNestedSessionFile(
560
595
 
561
596
  export async function findLatestGeminiSession(
562
597
  _cwd: string,
563
- options: { since?: number; until?: number; preferClosestTo?: number; windowMs?: number; cwd?: string | null } = {},
598
+ options: {
599
+ since?: number;
600
+ until?: number;
601
+ preferClosestTo?: number;
602
+ windowMs?: number;
603
+ cwd?: string | null;
604
+ } = {},
564
605
  ): Promise<GeminiSessionInfo | null> {
565
606
  // Gemini stores sessions/logs under ~/.gemini/tmp/<project_hash>/(chats|logs).json
566
607
  const baseDir = path.join(homedir(), ".gemini", "tmp");
@@ -588,17 +629,15 @@ export async function findLatestGeminiSession(
588
629
 
589
630
  const ref = options.preferClosestTo;
590
631
  const window = options.windowMs ?? 30 * 60 * 1000;
591
- pool = pool
592
- .slice()
593
- .sort((a, b) => {
594
- if (typeof ref === "number") {
595
- const da = Math.abs(a.mtime - ref);
596
- const db = Math.abs(b.mtime - ref);
597
- if (da === db) return b.mtime - a.mtime;
598
- if (da <= window || db <= window) return da - db;
599
- }
600
- return b.mtime - a.mtime;
601
- });
632
+ pool = pool.slice().sort((a, b) => {
633
+ if (typeof ref === "number") {
634
+ const da = Math.abs(a.mtime - ref);
635
+ const db = Math.abs(b.mtime - ref);
636
+ if (da === db) return b.mtime - a.mtime;
637
+ if (da <= window || db <= window) return da - db;
638
+ }
639
+ return b.mtime - a.mtime;
640
+ });
602
641
 
603
642
  for (const file of pool) {
604
643
  const info = await readSessionInfoFromFile(file.fullPath);
@@ -620,16 +659,31 @@ export async function findLatestGeminiSession(
620
659
 
621
660
  export async function findLatestGeminiSessionId(
622
661
  cwd: string,
623
- options: { since?: number; until?: number; preferClosestTo?: number; windowMs?: number; cwd?: string | null } = {},
662
+ options: {
663
+ since?: number;
664
+ until?: number;
665
+ preferClosestTo?: number;
666
+ windowMs?: number;
667
+ cwd?: string | null;
668
+ } = {},
624
669
  ): Promise<string | null> {
625
- const normalized: { since?: number; until?: number; preferClosestTo?: number; windowMs?: number } = {};
670
+ const normalized: {
671
+ since?: number;
672
+ until?: number;
673
+ preferClosestTo?: number;
674
+ windowMs?: number;
675
+ } = {};
626
676
  if (options.since !== undefined) normalized.since = options.since as number;
627
677
  if (options.until !== undefined) normalized.until = options.until as number;
628
678
  if (options.preferClosestTo !== undefined)
629
679
  normalized.preferClosestTo = options.preferClosestTo as number;
630
- if (options.windowMs !== undefined) normalized.windowMs = options.windowMs as number;
680
+ if (options.windowMs !== undefined)
681
+ normalized.windowMs = options.windowMs as number;
631
682
 
632
- const found = await findLatestGeminiSession(cwd, { ...normalized, cwd: options.cwd ?? cwd });
683
+ const found = await findLatestGeminiSession(cwd, {
684
+ ...normalized,
685
+ cwd: options.cwd ?? cwd,
686
+ });
633
687
  return found?.id ?? null;
634
688
  }
635
689
 
@@ -18,9 +18,9 @@ const DEV_TTY_PATH = "/dev/tty";
18
18
  let cachedStreams: TerminalStreams | null = null;
19
19
 
20
20
  export interface ChildStdio {
21
- stdin: "inherit" | number;
22
- stdout: "inherit" | number;
23
- stderr: "inherit" | number;
21
+ stdin: "inherit" | { file: string; append?: boolean };
22
+ stdout: "inherit" | { file: string; append?: boolean };
23
+ stderr: "inherit" | { file: string; append?: boolean };
24
24
  cleanup: () => void;
25
25
  }
26
26
 
@@ -30,9 +30,9 @@ const DEFAULT_ACK_MESSAGE =
30
30
  function isProcessTTY(): boolean {
31
31
  return Boolean(
32
32
  process.stdin.isTTY &&
33
- process.stdout.isTTY &&
34
- process.stderr.isTTY &&
35
- typeof (process.stdin as NodeJS.ReadStream).setRawMode === "function",
33
+ process.stdout.isTTY &&
34
+ process.stderr.isTTY &&
35
+ typeof (process.stdin as NodeJS.ReadStream).setRawMode === "function",
36
36
  );
37
37
  }
38
38
 
@@ -184,42 +184,12 @@ export function createChildStdio(): ChildStdio {
184
184
  };
185
185
  }
186
186
 
187
- let fdIn: number | null = null;
188
- let fdOut: number | null = null;
189
- let fdErr: number | null = null;
190
-
191
- const cleanup = () => {
192
- for (const fd of [fdIn, fdOut, fdErr]) {
193
- if (fd !== null) {
194
- try {
195
- fs.closeSync(fd);
196
- } catch {
197
- // Ignore close errors.
198
- }
199
- }
200
- }
187
+ return {
188
+ stdin: { file: DEV_TTY_PATH },
189
+ stdout: { file: DEV_TTY_PATH },
190
+ stderr: { file: DEV_TTY_PATH },
191
+ cleanup: () => {},
201
192
  };
202
-
203
- try {
204
- fdIn = fs.openSync(DEV_TTY_PATH, "r");
205
- fdOut = fs.openSync(DEV_TTY_PATH, "w");
206
- fdErr = fs.openSync(DEV_TTY_PATH, "w");
207
-
208
- return {
209
- stdin: fdIn,
210
- stdout: fdOut,
211
- stderr: fdErr,
212
- cleanup,
213
- };
214
- } catch {
215
- cleanup();
216
- return {
217
- stdin: "inherit",
218
- stdout: "inherit",
219
- stderr: "inherit",
220
- cleanup: () => {},
221
- };
222
- }
223
193
  }
224
194
 
225
195
  function isInteractive(stream: NodeJS.ReadStream): boolean {
@@ -0,0 +1,43 @@
1
+ import * as net from "node:net";
2
+
3
+ export function resolveWebUiPort(
4
+ portEnv: string | undefined = process.env.PORT,
5
+ defaultPort = 3000,
6
+ ): number {
7
+ if (!portEnv) {
8
+ return defaultPort;
9
+ }
10
+
11
+ const port = parseInt(portEnv, 10);
12
+ if (Number.isNaN(port) || port <= 0 || port > 65535) {
13
+ return defaultPort;
14
+ }
15
+
16
+ return port;
17
+ }
18
+
19
+ /**
20
+ * 指定ポートが使用中かどうかをチェック
21
+ * @param port - チェックするポート番号
22
+ * @returns 使用中ならtrue、利用可能ならfalse
23
+ */
24
+ export async function isPortInUse(port: number): Promise<boolean> {
25
+ return new Promise((resolve) => {
26
+ const server = net.createServer();
27
+
28
+ server.once("error", (err: NodeJS.ErrnoException) => {
29
+ if (err.code === "EADDRINUSE") {
30
+ resolve(true);
31
+ } else {
32
+ // Other errors (EACCES, etc.) - treat as port not in use
33
+ resolve(false);
34
+ }
35
+ });
36
+
37
+ server.once("listening", () => {
38
+ server.close(() => resolve(false));
39
+ });
40
+
41
+ server.listen(port, "127.0.0.1");
42
+ });
43
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "rsc": false,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "",
8
+ "css": "src/index.css",
9
+ "baseColor": "neutral",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "aliases": {
14
+ "components": "@/components",
15
+ "utils": "@/lib/utils",
16
+ "ui": "@/components/ui",
17
+ "lib": "@/lib",
18
+ "hooks": "@/hooks"
19
+ },
20
+ "iconLibrary": "lucide"
21
+ }