@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.
- package/README.ja.md +323 -0
- package/README.md +347 -0
- package/bin/gwt.js +5 -0
- package/package.json +125 -0
- package/src/claude-history.ts +717 -0
- package/src/claude.ts +292 -0
- package/src/cli/ui/__tests__/SKIPPED_TESTS.md +119 -0
- package/src/cli/ui/__tests__/acceptance/branchList.acceptance.test.tsx.skip +239 -0
- package/src/cli/ui/__tests__/acceptance/navigation.acceptance.test.tsx +214 -0
- package/src/cli/ui/__tests__/acceptance/realtimeUpdate.acceptance.test.tsx.skip +219 -0
- package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +183 -0
- package/src/cli/ui/__tests__/components/App.shortcuts.test.tsx +313 -0
- package/src/cli/ui/__tests__/components/App.test.tsx +270 -0
- package/src/cli/ui/__tests__/components/common/Confirm.test.tsx +66 -0
- package/src/cli/ui/__tests__/components/common/ErrorBoundary.test.tsx +103 -0
- package/src/cli/ui/__tests__/components/common/Input.test.tsx +92 -0
- package/src/cli/ui/__tests__/components/common/LoadingIndicator.test.tsx +127 -0
- package/src/cli/ui/__tests__/components/common/Select.memo.test.tsx +264 -0
- package/src/cli/ui/__tests__/components/common/Select.test.tsx +246 -0
- package/src/cli/ui/__tests__/components/parts/Footer.test.tsx +62 -0
- package/src/cli/ui/__tests__/components/parts/Header.test.tsx +54 -0
- package/src/cli/ui/__tests__/components/parts/ScrollableList.test.tsx +68 -0
- package/src/cli/ui/__tests__/components/parts/Stats.test.tsx +135 -0
- package/src/cli/ui/__tests__/components/screens/AIToolSelectorScreen.test.tsx +153 -0
- package/src/cli/ui/__tests__/components/screens/BranchCreatorScreen.test.tsx +215 -0
- package/src/cli/ui/__tests__/components/screens/BranchListScreen.test.tsx +293 -0
- package/src/cli/ui/__tests__/components/screens/ExecutionModeSelectorScreen.test.tsx +161 -0
- package/src/cli/ui/__tests__/components/screens/PRCleanupScreen.test.tsx +215 -0
- package/src/cli/ui/__tests__/components/screens/SessionSelectorScreen.test.tsx +99 -0
- package/src/cli/ui/__tests__/components/screens/WorktreeManagerScreen.test.tsx +127 -0
- package/src/cli/ui/__tests__/hooks/useGitData.test.ts.skip +228 -0
- package/src/cli/ui/__tests__/hooks/useScreenState.test.ts +146 -0
- package/src/cli/ui/__tests__/hooks/useTerminalSize.test.ts +98 -0
- package/src/cli/ui/__tests__/integration/branchList.test.tsx.skip +253 -0
- package/src/cli/ui/__tests__/integration/edgeCases.test.tsx +306 -0
- package/src/cli/ui/__tests__/integration/navigation.test.tsx +405 -0
- package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx +505 -0
- package/src/cli/ui/__tests__/integration/realtimeUpdate.test.tsx.skip +216 -0
- package/src/cli/ui/__tests__/performance/branchList.performance.test.tsx +180 -0
- package/src/cli/ui/__tests__/performance/useMemoOptimization.test.tsx +237 -0
- package/src/cli/ui/__tests__/utils/branchFormatter.test.ts +775 -0
- package/src/cli/ui/__tests__/utils/statisticsCalculator.test.ts +243 -0
- package/src/cli/ui/components/App.tsx +793 -0
- package/src/cli/ui/components/common/Confirm.tsx +40 -0
- package/src/cli/ui/components/common/ErrorBoundary.tsx +57 -0
- package/src/cli/ui/components/common/Input.tsx +36 -0
- package/src/cli/ui/components/common/LoadingIndicator.tsx +95 -0
- package/src/cli/ui/components/common/Select.tsx +216 -0
- package/src/cli/ui/components/parts/Footer.tsx +41 -0
- package/src/cli/ui/components/parts/Header.test.tsx +85 -0
- package/src/cli/ui/components/parts/Header.tsx +63 -0
- package/src/cli/ui/components/parts/MergeStatusList.tsx +75 -0
- package/src/cli/ui/components/parts/ProgressBar.tsx +73 -0
- package/src/cli/ui/components/parts/ScrollableList.tsx +24 -0
- package/src/cli/ui/components/parts/Stats.tsx +67 -0
- package/src/cli/ui/components/screens/AIToolSelectorScreen.tsx +116 -0
- package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +70 -0
- package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +104 -0
- package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +213 -0
- package/src/cli/ui/components/screens/BranchListScreen.tsx +299 -0
- package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +149 -0
- package/src/cli/ui/components/screens/PRCleanupScreen.tsx +167 -0
- package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +100 -0
- package/src/cli/ui/components/screens/WorktreeManagerScreen.tsx +117 -0
- package/src/cli/ui/hooks/useBatchMerge.ts +96 -0
- package/src/cli/ui/hooks/useGitData.ts +157 -0
- package/src/cli/ui/hooks/useScreenState.ts +44 -0
- package/src/cli/ui/hooks/useTerminalSize.ts +33 -0
- package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +102 -0
- package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +151 -0
- package/src/cli/ui/types.ts +295 -0
- package/src/cli/ui/utils/baseBranch.ts +34 -0
- package/src/cli/ui/utils/branchFormatter.ts +222 -0
- package/src/cli/ui/utils/statisticsCalculator.ts +44 -0
- package/src/codex.ts +139 -0
- package/src/config/builtin-tools.ts +44 -0
- package/src/config/constants.ts +100 -0
- package/src/config/env-history.ts +45 -0
- package/src/config/index.ts +204 -0
- package/src/config/tools.ts +293 -0
- package/src/git.ts +1102 -0
- package/src/github.ts +158 -0
- package/src/index.test.ts +87 -0
- package/src/index.ts +684 -0
- package/src/index.ts.backup +1543 -0
- package/src/launcher.ts +142 -0
- package/src/repositories/git.repository.ts +129 -0
- package/src/repositories/github.repository.ts +83 -0
- package/src/repositories/worktree.repository.ts +69 -0
- package/src/services/BatchMergeService.ts +251 -0
- package/src/services/WorktreeOrchestrator.ts +115 -0
- package/src/services/__tests__/BatchMergeService.test.ts +518 -0
- package/src/services/__tests__/WorktreeOrchestrator.test.ts +258 -0
- package/src/services/dependency-installer.ts +199 -0
- package/src/services/git.service.ts +113 -0
- package/src/services/github.service.ts +61 -0
- package/src/services/worktree.service.ts +66 -0
- package/src/types/api.ts +241 -0
- package/src/types/tools.ts +235 -0
- package/src/utils/spinner.ts +54 -0
- package/src/utils/terminal.ts +272 -0
- package/src/utils.test.ts +43 -0
- package/src/utils.ts +60 -0
- package/src/web/client/index.html +12 -0
- package/src/web/client/src/components/BranchGraph.tsx +231 -0
- package/src/web/client/src/components/EnvEditor.tsx +145 -0
- package/src/web/client/src/components/Terminal.tsx +137 -0
- package/src/web/client/src/hooks/useBranches.ts +41 -0
- package/src/web/client/src/hooks/useConfig.ts +31 -0
- package/src/web/client/src/hooks/useSessions.ts +59 -0
- package/src/web/client/src/hooks/useWorktrees.ts +47 -0
- package/src/web/client/src/index.css +834 -0
- package/src/web/client/src/lib/api.ts +184 -0
- package/src/web/client/src/lib/websocket.ts +174 -0
- package/src/web/client/src/main.tsx +29 -0
- package/src/web/client/src/pages/BranchDetailPage.tsx +847 -0
- package/src/web/client/src/pages/BranchListPage.tsx +264 -0
- package/src/web/client/src/pages/ConfigManagementPage.tsx +203 -0
- package/src/web/client/src/router.tsx +27 -0
- package/src/web/client/vite.config.ts +21 -0
- package/src/web/server/env/importer.ts +54 -0
- package/src/web/server/index.ts +74 -0
- package/src/web/server/pty/manager.ts +189 -0
- package/src/web/server/routes/branches.ts +126 -0
- package/src/web/server/routes/config.ts +220 -0
- package/src/web/server/routes/index.ts +37 -0
- package/src/web/server/routes/sessions.ts +130 -0
- package/src/web/server/routes/worktrees.ts +108 -0
- package/src/web/server/services/branches.ts +368 -0
- package/src/web/server/services/worktrees.ts +85 -0
- package/src/web/server/websocket/handler.ts +180 -0
- package/src/worktree.ts +703 -0
package/src/types/api.ts
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web UI API型定義
|
|
3
|
+
*
|
|
4
|
+
* データモデル仕様: specs/SPEC-d5e56259/data-model.md
|
|
5
|
+
* REST API仕様: specs/SPEC-d5e56259/contracts/rest-api.yaml
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Branch - Gitブランチ
|
|
10
|
+
*/
|
|
11
|
+
export interface Branch {
|
|
12
|
+
name: string;
|
|
13
|
+
type: "local" | "remote";
|
|
14
|
+
commitHash: string;
|
|
15
|
+
commitMessage?: string | null;
|
|
16
|
+
author?: string | null;
|
|
17
|
+
commitDate?: string | null; // ISO8601
|
|
18
|
+
mergeStatus: "unmerged" | "merged" | "unknown";
|
|
19
|
+
hasUnpushedCommits: boolean;
|
|
20
|
+
worktreePath?: string | null;
|
|
21
|
+
baseBranch?: string | null;
|
|
22
|
+
divergence?: {
|
|
23
|
+
ahead: number;
|
|
24
|
+
behind: number;
|
|
25
|
+
upToDate: boolean;
|
|
26
|
+
} | null;
|
|
27
|
+
prInfo?: {
|
|
28
|
+
number: number;
|
|
29
|
+
title: string;
|
|
30
|
+
state: "open" | "merged" | "closed";
|
|
31
|
+
mergedAt?: string | null;
|
|
32
|
+
} | null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Worktree - Gitワークツリー
|
|
37
|
+
*/
|
|
38
|
+
export interface Worktree {
|
|
39
|
+
path: string;
|
|
40
|
+
branchName: string;
|
|
41
|
+
head: string;
|
|
42
|
+
isLocked: boolean;
|
|
43
|
+
isPrunable: boolean;
|
|
44
|
+
isProtected: boolean;
|
|
45
|
+
createdAt?: string | null; // ISO8601
|
|
46
|
+
lastAccessedAt?: string | null; // ISO8601
|
|
47
|
+
divergence?: Branch["divergence"];
|
|
48
|
+
prInfo?: Branch["prInfo"];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* AIToolSession - AI Tool実行セッション
|
|
53
|
+
*/
|
|
54
|
+
export interface AIToolSession {
|
|
55
|
+
sessionId: string; // UUID v4
|
|
56
|
+
toolType: "claude-code" | "codex-cli" | "custom";
|
|
57
|
+
toolName?: string | null;
|
|
58
|
+
mode: "normal" | "continue" | "resume";
|
|
59
|
+
worktreePath: string;
|
|
60
|
+
ptyPid?: number | null;
|
|
61
|
+
websocketId?: string | null;
|
|
62
|
+
status: "pending" | "running" | "completed" | "failed";
|
|
63
|
+
startedAt: string; // ISO8601
|
|
64
|
+
endedAt?: string | null; // ISO8601
|
|
65
|
+
exitCode?: number | null;
|
|
66
|
+
errorMessage?: string | null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* CustomAITool - カスタムAI Tool設定
|
|
71
|
+
*/
|
|
72
|
+
export interface EnvironmentVariable {
|
|
73
|
+
key: string;
|
|
74
|
+
value: string;
|
|
75
|
+
lastUpdated?: string | null;
|
|
76
|
+
importedFromOs?: boolean;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface EnvironmentHistoryEntry {
|
|
80
|
+
key: string;
|
|
81
|
+
action: "add" | "update" | "delete" | "import";
|
|
82
|
+
timestamp: string;
|
|
83
|
+
source: "ui" | "os" | "cli";
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface CustomAITool {
|
|
87
|
+
id: string; // UUID v4 or slug
|
|
88
|
+
displayName: string;
|
|
89
|
+
icon?: string | null;
|
|
90
|
+
command: string;
|
|
91
|
+
executionType: "path" | "bunx" | "command";
|
|
92
|
+
defaultArgs?: string[] | null;
|
|
93
|
+
modeArgs: {
|
|
94
|
+
normal?: string[];
|
|
95
|
+
continue?: string[];
|
|
96
|
+
resume?: string[];
|
|
97
|
+
};
|
|
98
|
+
permissionSkipArgs?: string[] | null;
|
|
99
|
+
env?: EnvironmentVariable[] | null;
|
|
100
|
+
description?: string | null;
|
|
101
|
+
createdAt?: string | null; // ISO8601
|
|
102
|
+
updatedAt?: string | null; // ISO8601
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* REST API Response wrappers
|
|
107
|
+
*/
|
|
108
|
+
export interface SuccessResponse<T = unknown> {
|
|
109
|
+
success: true;
|
|
110
|
+
data: T;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface ErrorResponse {
|
|
114
|
+
success: false;
|
|
115
|
+
error: string;
|
|
116
|
+
details?: string | null;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export type ApiResponse<T> = SuccessResponse<T> | ErrorResponse;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* API Endpoints
|
|
123
|
+
*/
|
|
124
|
+
export interface HealthResponse {
|
|
125
|
+
success: true;
|
|
126
|
+
status: string;
|
|
127
|
+
timestamp: string; // ISO8601
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type BranchListResponse = SuccessResponse<Branch[]>;
|
|
131
|
+
export type BranchResponse = SuccessResponse<Branch>;
|
|
132
|
+
export type BranchSyncResponse = SuccessResponse<BranchSyncResult>;
|
|
133
|
+
export type WorktreeListResponse = SuccessResponse<Worktree[]>;
|
|
134
|
+
export type WorktreeResponse = SuccessResponse<Worktree>;
|
|
135
|
+
export type SessionListResponse = SuccessResponse<AIToolSession[]>;
|
|
136
|
+
export type SessionResponse = SuccessResponse<AIToolSession>;
|
|
137
|
+
export interface ConfigPayload {
|
|
138
|
+
version: string;
|
|
139
|
+
updatedAt?: string | null;
|
|
140
|
+
env?: EnvironmentVariable[] | null;
|
|
141
|
+
history?: EnvironmentHistoryEntry[] | null;
|
|
142
|
+
tools: CustomAITool[];
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export type ConfigResponse = SuccessResponse<ConfigPayload>;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* API Request bodies
|
|
149
|
+
*/
|
|
150
|
+
export interface CreateWorktreeRequest {
|
|
151
|
+
branchName: string;
|
|
152
|
+
createBranch?: boolean;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export interface BranchSyncRequest {
|
|
156
|
+
worktreePath: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export interface StartSessionRequest {
|
|
160
|
+
toolType: "claude-code" | "codex-cli" | "custom";
|
|
161
|
+
toolName?: string | null;
|
|
162
|
+
mode: "normal" | "continue" | "resume";
|
|
163
|
+
worktreePath: string;
|
|
164
|
+
skipPermissions?: boolean;
|
|
165
|
+
bypassApprovals?: boolean;
|
|
166
|
+
extraArgs?: string[];
|
|
167
|
+
customToolId?: string | null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export type UpdateConfigRequest = ConfigPayload;
|
|
171
|
+
|
|
172
|
+
export interface CleanupResponse {
|
|
173
|
+
success: true;
|
|
174
|
+
deleted: string[];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface BranchSyncResult {
|
|
178
|
+
branch: Branch;
|
|
179
|
+
divergence?: Branch["divergence"];
|
|
180
|
+
fetchStatus: "success";
|
|
181
|
+
pullStatus: "success" | "failed";
|
|
182
|
+
warnings?: string[];
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* WebSocket Messages
|
|
187
|
+
*/
|
|
188
|
+
export interface WebSocketMessage {
|
|
189
|
+
type: string;
|
|
190
|
+
data?: unknown;
|
|
191
|
+
timestamp?: string; // ISO8601
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export interface InputMessage extends WebSocketMessage {
|
|
195
|
+
type: "input";
|
|
196
|
+
data: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export interface ResizeMessage extends WebSocketMessage {
|
|
200
|
+
type: "resize";
|
|
201
|
+
data: {
|
|
202
|
+
cols: number;
|
|
203
|
+
rows: number;
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export interface PingMessage extends WebSocketMessage {
|
|
208
|
+
type: "ping";
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface OutputMessage extends WebSocketMessage {
|
|
212
|
+
type: "output";
|
|
213
|
+
data: string;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface ExitMessage extends WebSocketMessage {
|
|
217
|
+
type: "exit";
|
|
218
|
+
data: {
|
|
219
|
+
code: number;
|
|
220
|
+
signal?: string;
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface ErrorMessage extends WebSocketMessage {
|
|
225
|
+
type: "error";
|
|
226
|
+
data: {
|
|
227
|
+
message: string;
|
|
228
|
+
code?: string;
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export interface PongMessage extends WebSocketMessage {
|
|
233
|
+
type: "pong";
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export type ClientMessage = InputMessage | ResizeMessage | PingMessage;
|
|
237
|
+
export type ServerMessage =
|
|
238
|
+
| OutputMessage
|
|
239
|
+
| ExitMessage
|
|
240
|
+
| ErrorMessage
|
|
241
|
+
| PongMessage;
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* カスタムAIツール対応機能の型定義
|
|
3
|
+
*
|
|
4
|
+
* この型定義ファイルは、設定ファイル(tools.json)のスキーマと
|
|
5
|
+
* 内部で使用するデータ構造を定義します。
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// 設定ファイルのスキーマ
|
|
10
|
+
// ============================================================================
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* ツール実行方式
|
|
14
|
+
*
|
|
15
|
+
* - path: 絶対パスで直接実行(例: /usr/local/bin/my-tool)
|
|
16
|
+
* - bunx: bunx経由でパッケージを実行(例: @org/package@latest)
|
|
17
|
+
* - command: PATH環境変数から探して実行(例: aider)
|
|
18
|
+
*/
|
|
19
|
+
export type ToolExecutionType = "path" | "bunx" | "command";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* 実行モード別引数
|
|
23
|
+
*
|
|
24
|
+
* 各モードで使用する引数の配列を定義します。
|
|
25
|
+
* 少なくとも1つのモードを定義する必要があります。
|
|
26
|
+
*/
|
|
27
|
+
export interface ModeArgs {
|
|
28
|
+
/**
|
|
29
|
+
* 通常モード時の引数
|
|
30
|
+
*/
|
|
31
|
+
normal?: string[];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 継続モード時の引数
|
|
35
|
+
*/
|
|
36
|
+
continue?: string[];
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 再開モード時の引数
|
|
40
|
+
*/
|
|
41
|
+
resume?: string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* カスタムAIツール定義
|
|
46
|
+
*
|
|
47
|
+
* tools.jsonファイルで定義される個別のツール設定。
|
|
48
|
+
*/
|
|
49
|
+
export interface CustomAITool {
|
|
50
|
+
/**
|
|
51
|
+
* ツールの一意識別子
|
|
52
|
+
*
|
|
53
|
+
* 小文字英数字とハイフンのみ使用可能(パターン: ^[a-z0-9-]+$)
|
|
54
|
+
* ビルトインツール(claude-code, codex-cli)との重複は不可。
|
|
55
|
+
*/
|
|
56
|
+
id: string;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* UI表示名
|
|
60
|
+
*
|
|
61
|
+
* ツール選択画面で表示される名前。日本語も使用可能。
|
|
62
|
+
*/
|
|
63
|
+
displayName: string;
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* アイコン文字(オプション)
|
|
67
|
+
*
|
|
68
|
+
* ツール選択画面で表示されるUnicode文字。
|
|
69
|
+
*/
|
|
70
|
+
icon?: string;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 実行方式
|
|
74
|
+
*
|
|
75
|
+
* - "path": 絶対パスで直接実行
|
|
76
|
+
* - "bunx": bunx経由でパッケージを実行
|
|
77
|
+
* - "command": PATH環境変数から探して実行
|
|
78
|
+
*/
|
|
79
|
+
type: ToolExecutionType;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* 実行パス/パッケージ名/コマンド名
|
|
83
|
+
*
|
|
84
|
+
* typeに応じた値を設定:
|
|
85
|
+
* - type="path": 絶対パス(例: /usr/local/bin/my-tool)
|
|
86
|
+
* - type="bunx": パッケージ名(例: @org/package@latest)
|
|
87
|
+
* - type="command": コマンド名(例: aider)
|
|
88
|
+
*/
|
|
89
|
+
command: string;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* デフォルト引数(オプション)
|
|
93
|
+
*
|
|
94
|
+
* ツール実行時に常に付与される引数。
|
|
95
|
+
* 最終的な引数は: defaultArgs + modeArgs[mode] + permissionSkipArgs + extraArgs
|
|
96
|
+
*/
|
|
97
|
+
defaultArgs?: string[];
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* モード別引数
|
|
101
|
+
*
|
|
102
|
+
* normal/continue/resumeの各モードで使用する引数。
|
|
103
|
+
* 少なくとも1つのモードを定義する必要があります。
|
|
104
|
+
*/
|
|
105
|
+
modeArgs: ModeArgs;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 権限スキップ時の引数(オプション)
|
|
109
|
+
*
|
|
110
|
+
* ユーザーが権限スキップを有効にした場合に追加される引数。
|
|
111
|
+
*/
|
|
112
|
+
permissionSkipArgs?: string[];
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* 環境変数(オプション)
|
|
116
|
+
*
|
|
117
|
+
* ツール起動時に設定される環境変数。
|
|
118
|
+
* APIキーや設定ファイルパスなどを指定。
|
|
119
|
+
*/
|
|
120
|
+
env?: Record<string, string>;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* ツール設定ファイル全体
|
|
125
|
+
*
|
|
126
|
+
* ~/.gwt/tools.json のスキーマ。
|
|
127
|
+
*/
|
|
128
|
+
export interface ToolsConfig {
|
|
129
|
+
/**
|
|
130
|
+
* 設定フォーマットのバージョン
|
|
131
|
+
*
|
|
132
|
+
* セマンティックバージョニング形式。
|
|
133
|
+
*/
|
|
134
|
+
version: string;
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* 設定ファイルの最終更新日時(ISO8601)
|
|
138
|
+
*/
|
|
139
|
+
updatedAt?: string;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* すべてのツールで共有する環境変数
|
|
143
|
+
*/
|
|
144
|
+
env?: Record<string, string>;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* カスタムツール定義の配列
|
|
148
|
+
*
|
|
149
|
+
* 空配列も許可(ビルトインツールのみ使用)。
|
|
150
|
+
*/
|
|
151
|
+
customTools: CustomAITool[];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ============================================================================
|
|
155
|
+
// 内部使用の型定義
|
|
156
|
+
// ============================================================================
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* 統合ツール設定
|
|
160
|
+
*
|
|
161
|
+
* ビルトインツールとカスタムツールを統合して扱うための内部型。
|
|
162
|
+
* getAllTools() 関数がこの型の配列を返します。
|
|
163
|
+
*/
|
|
164
|
+
export interface AIToolConfig {
|
|
165
|
+
/**
|
|
166
|
+
* ツールID
|
|
167
|
+
*
|
|
168
|
+
* ビルトイン: "claude-code" | "codex-cli"
|
|
169
|
+
* カスタム: CustomAITool.id
|
|
170
|
+
*/
|
|
171
|
+
id: string;
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* UI表示名
|
|
175
|
+
*/
|
|
176
|
+
displayName: string;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* アイコン文字(オプション)
|
|
180
|
+
*/
|
|
181
|
+
icon?: string;
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* ビルトインツールかどうか
|
|
185
|
+
*
|
|
186
|
+
* true: Claude Code または Codex CLI
|
|
187
|
+
* false: カスタムツール
|
|
188
|
+
*/
|
|
189
|
+
isBuiltin: boolean;
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* カスタムツールの場合、元の設定
|
|
193
|
+
*
|
|
194
|
+
* isBuiltin=false の場合のみ存在。
|
|
195
|
+
*/
|
|
196
|
+
customConfig?: CustomAITool;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* ツール起動オプション
|
|
201
|
+
*
|
|
202
|
+
* launchCustomAITool() 関数の引数として使用。
|
|
203
|
+
*/
|
|
204
|
+
export interface LaunchOptions {
|
|
205
|
+
/**
|
|
206
|
+
* 実行モード
|
|
207
|
+
*/
|
|
208
|
+
mode?: "normal" | "continue" | "resume";
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* 権限スキップを有効にするか
|
|
212
|
+
*
|
|
213
|
+
* true の場合、permissionSkipArgs が追加されます。
|
|
214
|
+
*/
|
|
215
|
+
skipPermissions?: boolean;
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* 追加引数
|
|
219
|
+
*
|
|
220
|
+
* コマンドラインから -- 以降に渡された引数。
|
|
221
|
+
*/
|
|
222
|
+
extraArgs?: string[];
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* 作業ディレクトリ(ワークツリーパス)
|
|
226
|
+
*
|
|
227
|
+
* ツール起動時のcwdとして使用されます。
|
|
228
|
+
*/
|
|
229
|
+
cwd?: string;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* 共有環境変数(共通env + ローカル取り込み)
|
|
233
|
+
*/
|
|
234
|
+
sharedEnv?: Record<string, string>;
|
|
235
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const SPINNER_FRAMES = [
|
|
2
|
+
"⠋",
|
|
3
|
+
"⠙",
|
|
4
|
+
"⠹",
|
|
5
|
+
"⠸",
|
|
6
|
+
"⠼",
|
|
7
|
+
"⠴",
|
|
8
|
+
"⠦",
|
|
9
|
+
"⠧",
|
|
10
|
+
"⠇",
|
|
11
|
+
"⠏",
|
|
12
|
+
] as const;
|
|
13
|
+
const FRAME_INTERVAL_MS = 80;
|
|
14
|
+
|
|
15
|
+
function isWritableStream(
|
|
16
|
+
stream: NodeJS.WriteStream | undefined,
|
|
17
|
+
): stream is NodeJS.WriteStream {
|
|
18
|
+
return Boolean(stream && typeof stream.write === "function");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* CLI用の簡易スピナーを開始する。
|
|
23
|
+
* 戻り値の関数を呼び出すとスピナーが停止して行をクリアします。
|
|
24
|
+
*/
|
|
25
|
+
export function startSpinner(message: string): () => void {
|
|
26
|
+
const stream = process.stdout;
|
|
27
|
+
|
|
28
|
+
if (!isWritableStream(stream) || stream.isTTY === false) {
|
|
29
|
+
return () => {};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
let frameIndex = 0;
|
|
33
|
+
let active = true;
|
|
34
|
+
const padding = " ".repeat(message.length + 2);
|
|
35
|
+
|
|
36
|
+
const render = () => {
|
|
37
|
+
if (!active) return;
|
|
38
|
+
const frame = SPINNER_FRAMES[frameIndex];
|
|
39
|
+
frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;
|
|
40
|
+
stream.write(`\r${frame} ${message}`);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
render();
|
|
44
|
+
const timer = setInterval(render, FRAME_INTERVAL_MS);
|
|
45
|
+
|
|
46
|
+
const stop = () => {
|
|
47
|
+
if (!active) return;
|
|
48
|
+
active = false;
|
|
49
|
+
clearInterval(timer);
|
|
50
|
+
stream.write(`\r${padding}\r`);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return stop;
|
|
54
|
+
}
|