@akiojin/gwt 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.ja.md +323 -0
  2. package/README.md +347 -0
  3. package/bin/gwt.js +5 -0
  4. package/package.json +125 -0
  5. package/src/claude-history.ts +717 -0
  6. package/src/claude.ts +292 -0
  7. package/src/cli/ui/__tests__/SKIPPED_TESTS.md +119 -0
  8. package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +239 -0
  9. package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +214 -0
  10. package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +219 -0
  11. package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +183 -0
  12. package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +313 -0
  13. package/src/cli/ui/__tests__/components/App.test.tsx +270 -0
  14. package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +66 -0
  15. package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +103 -0
  16. package/src/cli/ui/__tests__/components/common/Input.test.tsx +92 -0
  17. package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +127 -0
  18. package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +264 -0
  19. package/src/cli/ui/__tests__/components/common/Select.test.tsx +246 -0
  20. package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +62 -0
  21. package/src/cli/ui/__tests__/components/parts/Header.test.tsx +54 -0
  22. package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +68 -0
  23. package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +135 -0
  24. package/src/cli/ui/__tests__/components/screens/AIToolSelectorScreen.test.tsx +153 -0
  25. package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +215 -0
  26. package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +293 -0
  27. package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +161 -0
  28. package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +215 -0
  29. package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +99 -0
  30. package/src/cli/ui/__tests__/components/screens/WorktreeManagerScreen.test.tsx +127 -0
  31. package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +228 -0
  32. package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +146 -0
  33. package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +98 -0
  34. package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +253 -0
  35. package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +306 -0
  36. package/src/cli/ui/__tests__/integration/navigation.test.tsx +405 -0
  37. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +505 -0
  38. package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +216 -0
  39. package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +180 -0
  40. package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +237 -0
  41. package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +775 -0
  42. package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +243 -0
  43. package/src/cli/ui/components/App.tsx +793 -0
  44. package/src/cli/ui/components/common/Confirm.tsx +40 -0
  45. package/src/cli/ui/components/common/ErrorBoundary.tsx +57 -0
  46. package/src/cli/ui/components/common/Input.tsx +36 -0
  47. package/src/cli/ui/components/common/LoadingIndicator.tsx +95 -0
  48. package/src/cli/ui/components/common/Select.tsx +216 -0
  49. package/src/cli/ui/components/parts/Footer.tsx +41 -0
  50. package/src/cli/ui/components/parts/Header.test.tsx +85 -0
  51. package/src/cli/ui/components/parts/Header.tsx +63 -0
  52. package/src/cli/ui/components/parts/MergeStatusList.tsx +75 -0
  53. package/src/cli/ui/components/parts/ProgressBar.tsx +73 -0
  54. package/src/cli/ui/components/parts/ScrollableList.tsx +24 -0
  55. package/src/cli/ui/components/parts/Stats.tsx +67 -0
  56. package/src/cli/ui/components/screens/AIToolSelectorScreen.tsx +116 -0
  57. package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +70 -0
  58. package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +104 -0
  59. package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +213 -0
  60. package/src/cli/ui/components/screens/BranchListScreen.tsx +299 -0
  61. package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +149 -0
  62. package/src/cli/ui/components/screens/PRCleanupScreen.tsx +167 -0
  63. package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +100 -0
  64. package/src/cli/ui/components/screens/WorktreeManagerScreen.tsx +117 -0
  65. package/src/cli/ui/hooks/useBatchMerge.ts +96 -0
  66. package/src/cli/ui/hooks/useGitData.ts +157 -0
  67. package/src/cli/ui/hooks/useScreenState.ts +44 -0
  68. package/src/cli/ui/hooks/useTerminalSize.ts +33 -0
  69. package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +102 -0
  70. package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +151 -0
  71. package/src/cli/ui/types.ts +295 -0
  72. package/src/cli/ui/utils/baseBranch.ts +34 -0
  73. package/src/cli/ui/utils/branchFormatter.ts +222 -0
  74. package/src/cli/ui/utils/statisticsCalculator.ts +44 -0
  75. package/src/codex.ts +139 -0
  76. package/src/config/builtin-tools.ts +44 -0
  77. package/src/config/constants.ts +100 -0
  78. package/src/config/env-history.ts +45 -0
  79. package/src/config/index.ts +204 -0
  80. package/src/config/tools.ts +293 -0
  81. package/src/git.ts +1102 -0
  82. package/src/github.ts +158 -0
  83. package/src/index.test.ts +87 -0
  84. package/src/index.ts +684 -0
  85. package/src/index.ts.backup +1543 -0
  86. package/src/launcher.ts +142 -0
  87. package/src/repositories/git.repository.ts +129 -0
  88. package/src/repositories/github.repository.ts +83 -0
  89. package/src/repositories/worktree.repository.ts +69 -0
  90. package/src/services/BatchMergeService.ts +251 -0
  91. package/src/services/WorktreeOrchestrator.ts +115 -0
  92. package/src/services/__tests__/BatchMergeService.test.ts +518 -0
  93. package/src/services/__tests__/WorktreeOrchestrator.test.ts +258 -0
  94. package/src/services/dependency-installer.ts +199 -0
  95. package/src/services/git.service.ts +113 -0
  96. package/src/services/github.service.ts +61 -0
  97. package/src/services/worktree.service.ts +66 -0
  98. package/src/types/api.ts +241 -0
  99. package/src/types/tools.ts +235 -0
  100. package/src/utils/spinner.ts +54 -0
  101. package/src/utils/terminal.ts +272 -0
  102. package/src/utils.test.ts +43 -0
  103. package/src/utils.ts +60 -0
  104. package/src/web/client/index.html +12 -0
  105. package/src/web/client/src/components/BranchGraph.tsx +231 -0
  106. package/src/web/client/src/components/EnvEditor.tsx +145 -0
  107. package/src/web/client/src/components/Terminal.tsx +137 -0
  108. package/src/web/client/src/hooks/useBranches.ts +41 -0
  109. package/src/web/client/src/hooks/useConfig.ts +31 -0
  110. package/src/web/client/src/hooks/useSessions.ts +59 -0
  111. package/src/web/client/src/hooks/useWorktrees.ts +47 -0
  112. package/src/web/client/src/index.css +834 -0
  113. package/src/web/client/src/lib/api.ts +184 -0
  114. package/src/web/client/src/lib/websocket.ts +174 -0
  115. package/src/web/client/src/main.tsx +29 -0
  116. package/src/web/client/src/pages/BranchDetailPage.tsx +847 -0
  117. package/src/web/client/src/pages/BranchListPage.tsx +264 -0
  118. package/src/web/client/src/pages/ConfigManagementPage.tsx +203 -0
  119. package/src/web/client/src/router.tsx +27 -0
  120. package/src/web/client/vite.config.ts +21 -0
  121. package/src/web/server/env/importer.ts +54 -0
  122. package/src/web/server/index.ts +74 -0
  123. package/src/web/server/pty/manager.ts +189 -0
  124. package/src/web/server/routes/branches.ts +126 -0
  125. package/src/web/server/routes/config.ts +220 -0
  126. package/src/web/server/routes/index.ts +37 -0
  127. package/src/web/server/routes/sessions.ts +130 -0
  128. package/src/web/server/routes/worktrees.ts +108 -0
  129. package/src/web/server/services/branches.ts +368 -0
  130. package/src/web/server/services/worktrees.ts +85 -0
  131. package/src/web/server/websocket/handler.ts +180 -0
  132. package/src/worktree.ts +703 -0
@@ -0,0 +1,180 @@
1
+ /**
2
+ * WebSocket Handler
3
+ *
4
+ * PTYプロセスとブラウザ間のWebSocket通信を仲介します。
5
+ * 仕様: specs/SPEC-d5e56259/contracts/websocket.md
6
+ */
7
+
8
+ import type { FastifyRequest } from "fastify";
9
+ import type { WebSocket } from "@fastify/websocket";
10
+ import type { PTYManager } from "../pty/manager.js";
11
+ import type {
12
+ ClientMessage,
13
+ InputMessage,
14
+ ResizeMessage,
15
+ OutputMessage,
16
+ ExitMessage,
17
+ ErrorMessage,
18
+ PongMessage,
19
+ } from "../../../types/api.js";
20
+
21
+ /**
22
+ * WebSocketハンドラー
23
+ */
24
+ export class WebSocketHandler {
25
+ constructor(private ptyManager: PTYManager) {}
26
+
27
+ /**
28
+ * WebSocket接続を処理
29
+ */
30
+ public handle(connection: WebSocket, request: FastifyRequest): void {
31
+ const url = new URL(
32
+ request.url,
33
+ `http://${request.hostname || "localhost"}`,
34
+ );
35
+ const sessionId = url.searchParams.get("sessionId");
36
+
37
+ if (!sessionId) {
38
+ this.sendError(connection, "Missing sessionId parameter");
39
+ connection.close();
40
+ return;
41
+ }
42
+
43
+ const instance = this.ptyManager.get(sessionId);
44
+ if (!instance) {
45
+ this.sendError(connection, `Session not found: ${sessionId}`);
46
+ connection.close();
47
+ return;
48
+ }
49
+
50
+ const { ptyProcess } = instance;
51
+
52
+ // セッションステータスを更新
53
+ this.ptyManager.updateStatus(sessionId, "running");
54
+
55
+ // PTYプロセスからの出力をWebSocketに転送
56
+ ptyProcess.onData((data) => {
57
+ this.sendOutput(connection, data);
58
+ });
59
+
60
+ // PTYプロセス終了時の処理
61
+ ptyProcess.onExit(({ exitCode, signal }) => {
62
+ this.ptyManager.updateStatus(sessionId, "completed", exitCode);
63
+ this.sendExit(connection, exitCode, signal);
64
+ connection.close();
65
+ });
66
+
67
+ // クライアントからのメッセージを処理
68
+ connection.on("message", (rawMessage) => {
69
+ try {
70
+ const message: ClientMessage = JSON.parse(rawMessage.toString());
71
+ this.handleClientMessage(message, ptyProcess, connection);
72
+ } catch (error) {
73
+ const errorMsg = error instanceof Error ? error.message : String(error);
74
+ this.sendError(connection, `Invalid message format: ${errorMsg}`);
75
+ }
76
+ });
77
+
78
+ // 接続エラー時の処理
79
+ connection.on("error", (error) => {
80
+ console.error(`WebSocket error for session ${sessionId}:`, error);
81
+ this.ptyManager.updateStatus(
82
+ sessionId,
83
+ "failed",
84
+ undefined,
85
+ error.message,
86
+ );
87
+ });
88
+
89
+ // 接続クローズ時の処理
90
+ connection.on("close", () => {
91
+ console.log(`WebSocket closed for session ${sessionId}`);
92
+ // PTYプロセスは残す(バックグラウンドで実行継続)
93
+ });
94
+ }
95
+
96
+ /**
97
+ * クライアントメッセージを処理
98
+ */
99
+ private handleClientMessage(
100
+ message: ClientMessage,
101
+ ptyProcess: ReturnType<typeof import("node-pty").spawn>,
102
+ connection: WebSocket,
103
+ ): void {
104
+ switch (message.type) {
105
+ case "input": {
106
+ const inputMsg = message as InputMessage;
107
+ ptyProcess.write(inputMsg.data);
108
+ break;
109
+ }
110
+ case "resize": {
111
+ const resizeMsg = message as ResizeMessage;
112
+ ptyProcess.resize(resizeMsg.data.cols, resizeMsg.data.rows);
113
+ break;
114
+ }
115
+ case "ping": {
116
+ this.sendPong(connection);
117
+ break;
118
+ }
119
+ default: {
120
+ const unknownMsg = message as { type: string };
121
+ this.sendError(connection, `Unknown message type: ${unknownMsg.type}`);
122
+ break;
123
+ }
124
+ }
125
+ }
126
+
127
+ /**
128
+ * 出力メッセージを送信
129
+ */
130
+ private sendOutput(connection: WebSocket, data: string): void {
131
+ const message: OutputMessage = {
132
+ type: "output",
133
+ data,
134
+ timestamp: new Date().toISOString(),
135
+ };
136
+ connection.send(JSON.stringify(message));
137
+ }
138
+
139
+ /**
140
+ * 終了メッセージを送信
141
+ */
142
+ private sendExit(connection: WebSocket, code: number, signal?: number): void {
143
+ const exitData: { code: number; signal?: string } = { code };
144
+ if (signal !== undefined) {
145
+ exitData.signal = String(signal);
146
+ }
147
+
148
+ const message: ExitMessage = {
149
+ type: "exit",
150
+ data: exitData,
151
+ timestamp: new Date().toISOString(),
152
+ };
153
+ connection.send(JSON.stringify(message));
154
+ }
155
+
156
+ /**
157
+ * エラーメッセージを送信
158
+ */
159
+ private sendError(connection: WebSocket, errorMsg: string): void {
160
+ const message: ErrorMessage = {
161
+ type: "error",
162
+ data: {
163
+ message: errorMsg,
164
+ },
165
+ timestamp: new Date().toISOString(),
166
+ };
167
+ connection.send(JSON.stringify(message));
168
+ }
169
+
170
+ /**
171
+ * Pongメッセージを送信
172
+ */
173
+ private sendPong(connection: WebSocket): void {
174
+ const message: PongMessage = {
175
+ type: "pong",
176
+ timestamp: new Date().toISOString(),
177
+ };
178
+ connection.send(JSON.stringify(message));
179
+ }
180
+ }