@akiojin/gwt 4.8.0 → 4.9.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 +1 -1
- package/README.md +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +1 -1
- package/dist/cli/ui/components/screens/BranchListScreen.js +3 -1
- package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +3 -7
- package/dist/config/index.js.map +1 -1
- package/dist/config/profiles.d.ts +2 -2
- package/dist/config/profiles.d.ts.map +1 -1
- package/dist/config/profiles.js +4 -7
- package/dist/config/profiles.js.map +1 -1
- package/dist/config/tools.d.ts +1 -1
- package/dist/config/tools.d.ts.map +1 -1
- package/dist/config/tools.js +3 -43
- package/dist/config/tools.js.map +1 -1
- package/dist/utils/command.d.ts +11 -0
- package/dist/utils/command.d.ts.map +1 -1
- package/dist/utils/command.js +33 -0
- package/dist/utils/command.js.map +1 -1
- package/dist/web/client/src/pages/ConfigPage.js +1 -1
- package/dist/web/client/src/pages/ConfigPage.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/ui/components/screens/BranchListScreen.tsx +4 -2
- package/src/config/index.ts +3 -7
- package/src/config/profiles.ts +4 -7
- package/src/config/tools.ts +3 -56
- package/src/utils/command.ts +37 -0
- package/src/web/client/src/pages/ConfigPage.tsx +2 -2
- package/src/index.ts.backup +0 -1543
package/package.json
CHANGED
|
@@ -640,7 +640,7 @@ export const BranchListScreen = React.memo(function BranchListScreen({
|
|
|
640
640
|
)}
|
|
641
641
|
</Box>
|
|
642
642
|
|
|
643
|
-
{/* Tool Status - FR-019, FR-021 */}
|
|
643
|
+
{/* Tool Status - FR-019, FR-021, FR-022 */}
|
|
644
644
|
{toolStatuses && toolStatuses.length > 0 && (
|
|
645
645
|
<Box>
|
|
646
646
|
<Text dimColor>Tools: </Text>
|
|
@@ -648,7 +648,9 @@ export const BranchListScreen = React.memo(function BranchListScreen({
|
|
|
648
648
|
<React.Fragment key={tool.id}>
|
|
649
649
|
<Text>{tool.name}: </Text>
|
|
650
650
|
<Text color={tool.status === "installed" ? "green" : "yellow"}>
|
|
651
|
-
{tool.status
|
|
651
|
+
{tool.status === "installed" && tool.version
|
|
652
|
+
? tool.version
|
|
653
|
+
: tool.status}
|
|
652
654
|
</Text>
|
|
653
655
|
{index < toolStatuses.length - 1 && <Text dimColor> | </Text>}
|
|
654
656
|
</React.Fragment>
|
package/src/config/index.ts
CHANGED
|
@@ -52,11 +52,8 @@ const DEFAULT_CONFIG: AppConfig = {
|
|
|
52
52
|
export async function loadConfig(): Promise<AppConfig> {
|
|
53
53
|
const configPaths = [
|
|
54
54
|
path.join(process.cwd(), ".gwt.json"),
|
|
55
|
-
path.join(process.cwd(), ".claude-worktree.json"), // 後方互換性
|
|
56
55
|
path.join(homedir(), ".config", "gwt", "config.json"),
|
|
57
|
-
path.join(homedir(), ".config", "claude-worktree", "config.json"), // 後方互換性
|
|
58
56
|
path.join(homedir(), ".gwt.json"),
|
|
59
|
-
path.join(homedir(), ".claude-worktree.json"), // 後方互換性
|
|
60
57
|
];
|
|
61
58
|
|
|
62
59
|
for (const configPath of configPaths) {
|
|
@@ -79,10 +76,9 @@ export async function loadConfig(): Promise<AppConfig> {
|
|
|
79
76
|
return {
|
|
80
77
|
...DEFAULT_CONFIG,
|
|
81
78
|
defaultBaseBranch:
|
|
82
|
-
process.env.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
enableGitHubIntegration: process.env.CLAUDE_WORKTREE_GITHUB !== "false",
|
|
79
|
+
process.env.GWT_BASE_BRANCH || DEFAULT_CONFIG.defaultBaseBranch,
|
|
80
|
+
skipPermissions: process.env.GWT_SKIP_PERMISSIONS === "true",
|
|
81
|
+
enableGitHubIntegration: process.env.GWT_GITHUB !== "false",
|
|
86
82
|
enableDebugMode:
|
|
87
83
|
process.env.DEBUG_CLEANUP === "true" || process.env.DEBUG === "true",
|
|
88
84
|
};
|
package/src/config/profiles.ts
CHANGED
|
@@ -29,16 +29,13 @@ import {
|
|
|
29
29
|
/**
|
|
30
30
|
* 設定ディレクトリのパスを取得
|
|
31
31
|
*
|
|
32
|
-
*
|
|
32
|
+
* 環境変数 GWT_HOME が設定されている場合はそれを使用、それ以外はホームディレクトリ
|
|
33
33
|
*/
|
|
34
34
|
function getConfigDir(): string {
|
|
35
35
|
const worktreeHome =
|
|
36
36
|
process.env.GWT_HOME && process.env.GWT_HOME.trim().length > 0
|
|
37
37
|
? process.env.GWT_HOME
|
|
38
|
-
:
|
|
39
|
-
process.env.CLAUDE_WORKTREE_HOME.trim().length > 0
|
|
40
|
-
? process.env.CLAUDE_WORKTREE_HOME
|
|
41
|
-
: homedir();
|
|
38
|
+
: homedir();
|
|
42
39
|
return path.join(worktreeHome, ".gwt");
|
|
43
40
|
}
|
|
44
41
|
|
|
@@ -133,11 +130,11 @@ async function mutateProfiles(
|
|
|
133
130
|
}
|
|
134
131
|
|
|
135
132
|
/**
|
|
136
|
-
*
|
|
133
|
+
* プロファイル設定ファイルのパス
|
|
137
134
|
*
|
|
138
135
|
* @deprecated 内部では getProfilesConfigPath() を使用してください。
|
|
139
136
|
* この定数はモジュールロード時に評価されるため、
|
|
140
|
-
* 実行中に環境変数(GWT_HOME
|
|
137
|
+
* 実行中に環境変数(GWT_HOME)を変更しても反映されません。
|
|
141
138
|
*/
|
|
142
139
|
export const PROFILES_CONFIG_PATH = getProfilesConfigPath();
|
|
143
140
|
|
package/src/config/tools.ts
CHANGED
|
@@ -7,14 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import path from "node:path";
|
|
10
|
-
import {
|
|
11
|
-
readFile,
|
|
12
|
-
writeFile,
|
|
13
|
-
mkdir,
|
|
14
|
-
rename,
|
|
15
|
-
access,
|
|
16
|
-
cp,
|
|
17
|
-
} from "node:fs/promises";
|
|
10
|
+
import { readFile, writeFile, mkdir, rename } from "node:fs/promises";
|
|
18
11
|
import type {
|
|
19
12
|
ToolsConfig,
|
|
20
13
|
CustomAITool,
|
|
@@ -28,60 +21,17 @@ const logger = createLogger({ category: "config" });
|
|
|
28
21
|
|
|
29
22
|
/**
|
|
30
23
|
* ツール設定ファイルのパス
|
|
31
|
-
*
|
|
24
|
+
* 環境変数 GWT_HOME が設定されている場合はそれを使用、それ以外はホームディレクトリ
|
|
32
25
|
*/
|
|
33
26
|
export const WORKTREE_HOME =
|
|
34
27
|
process.env.GWT_HOME && process.env.GWT_HOME.trim().length > 0
|
|
35
28
|
? process.env.GWT_HOME
|
|
36
|
-
:
|
|
37
|
-
process.env.CLAUDE_WORKTREE_HOME.trim().length > 0
|
|
38
|
-
? process.env.CLAUDE_WORKTREE_HOME
|
|
39
|
-
: homedir();
|
|
29
|
+
: homedir();
|
|
40
30
|
|
|
41
|
-
const LEGACY_CONFIG_DIR = path.join(homedir(), ".claude-worktree");
|
|
42
31
|
export const CONFIG_DIR = path.join(WORKTREE_HOME, ".gwt");
|
|
43
32
|
export const TOOLS_CONFIG_PATH = path.join(CONFIG_DIR, "tools.json");
|
|
44
33
|
const TEMP_CONFIG_PATH = `${TOOLS_CONFIG_PATH}.tmp`;
|
|
45
34
|
|
|
46
|
-
/**
|
|
47
|
-
* レガシー設定ディレクトリから新しいディレクトリへ移行
|
|
48
|
-
*/
|
|
49
|
-
async function migrateLegacyConfig(): Promise<void> {
|
|
50
|
-
try {
|
|
51
|
-
// 新しいディレクトリが既に存在する場合は移行不要
|
|
52
|
-
try {
|
|
53
|
-
await access(CONFIG_DIR);
|
|
54
|
-
return;
|
|
55
|
-
} catch {
|
|
56
|
-
// 新しいディレクトリが存在しない場合は続行
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// レガシーディレクトリの存在を確認
|
|
60
|
-
try {
|
|
61
|
-
await access(LEGACY_CONFIG_DIR);
|
|
62
|
-
} catch {
|
|
63
|
-
// レガシーディレクトリも存在しない場合は移行不要
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// レガシーディレクトリを新しいディレクトリにコピー
|
|
68
|
-
await mkdir(path.dirname(CONFIG_DIR), { recursive: true });
|
|
69
|
-
await cp(LEGACY_CONFIG_DIR, CONFIG_DIR, { recursive: true });
|
|
70
|
-
logger.info(
|
|
71
|
-
{ from: LEGACY_CONFIG_DIR, to: CONFIG_DIR },
|
|
72
|
-
"Legacy config migrated",
|
|
73
|
-
);
|
|
74
|
-
console.log(
|
|
75
|
-
`✅ Migrated configuration from ${LEGACY_CONFIG_DIR} to ${CONFIG_DIR}`,
|
|
76
|
-
);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
// 移行に失敗しても継続(エラーログのみ)
|
|
79
|
-
if (process.env.DEBUG) {
|
|
80
|
-
console.error("Failed to migrate legacy config:", error);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
35
|
const DEFAULT_CONFIG: ToolsConfig = {
|
|
86
36
|
version: "1.0.0",
|
|
87
37
|
env: {},
|
|
@@ -98,9 +48,6 @@ const DEFAULT_CONFIG: ToolsConfig = {
|
|
|
98
48
|
* @throws JSON構文エラー時
|
|
99
49
|
*/
|
|
100
50
|
export async function loadToolsConfig(): Promise<ToolsConfig> {
|
|
101
|
-
// 最初の呼び出し時にレガシー設定の移行を試行
|
|
102
|
-
await migrateLegacyConfig();
|
|
103
|
-
|
|
104
51
|
try {
|
|
105
52
|
const content = await readFile(TOOLS_CONFIG_PATH, "utf-8");
|
|
106
53
|
const config = JSON.parse(content) as ToolsConfig;
|
package/src/utils/command.ts
CHANGED
|
@@ -59,6 +59,7 @@ export interface CommandLookupResult {
|
|
|
59
59
|
available: boolean;
|
|
60
60
|
path: string | null;
|
|
61
61
|
source: "installed" | "bunx";
|
|
62
|
+
version?: string | null;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
/**
|
|
@@ -69,6 +70,7 @@ export interface ToolStatus {
|
|
|
69
70
|
name: string;
|
|
70
71
|
status: "installed" | "bunx";
|
|
71
72
|
path: string | null;
|
|
73
|
+
version?: string | null;
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
/**
|
|
@@ -85,6 +87,33 @@ export function clearCommandLookupCache(): void {
|
|
|
85
87
|
commandLookupCache.clear();
|
|
86
88
|
}
|
|
87
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Gets the version of a command by running it with --version.
|
|
92
|
+
* FR-022: Returns version in "v{version}" format, null on failure.
|
|
93
|
+
* FR-023: Times out after 3 seconds to minimize startup delay.
|
|
94
|
+
*
|
|
95
|
+
* @param commandPath - Full path to the command
|
|
96
|
+
* @returns Version string (e.g., "v1.0.3") or null on failure
|
|
97
|
+
*/
|
|
98
|
+
export async function getCommandVersion(
|
|
99
|
+
commandPath: string,
|
|
100
|
+
): Promise<string | null> {
|
|
101
|
+
try {
|
|
102
|
+
const result = await execa(commandPath, ["--version"], {
|
|
103
|
+
timeout: 3000,
|
|
104
|
+
stdin: "ignore",
|
|
105
|
+
stdout: "pipe",
|
|
106
|
+
stderr: "ignore",
|
|
107
|
+
});
|
|
108
|
+
// Extract version number from output
|
|
109
|
+
// Examples: "claude 1.0.3", "codex 0.77.0", "gemini 0.1.0"
|
|
110
|
+
const match = result.stdout.match(/(\d+\.\d+(?:\.\d+)?(?:-[\w.]+)?)/);
|
|
111
|
+
return match ? `v${match[1]}` : null;
|
|
112
|
+
} catch {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
88
117
|
/**
|
|
89
118
|
* Finds a command by checking PATH first, then fallback paths.
|
|
90
119
|
* Results are cached for the lifetime of the process (FR-020).
|
|
@@ -141,6 +170,13 @@ export async function findCommand(
|
|
|
141
170
|
lookupResult = { available: true, path: null, source: "bunx" };
|
|
142
171
|
}
|
|
143
172
|
|
|
173
|
+
// Step 4: Get version for installed commands (FR-022)
|
|
174
|
+
if (lookupResult.source === "installed" && lookupResult.path) {
|
|
175
|
+
lookupResult.version = await getCommandVersion(lookupResult.path);
|
|
176
|
+
} else {
|
|
177
|
+
lookupResult.version = null;
|
|
178
|
+
}
|
|
179
|
+
|
|
144
180
|
// Cache the result (FR-020)
|
|
145
181
|
commandLookupCache.set(commandName, lookupResult);
|
|
146
182
|
|
|
@@ -181,6 +217,7 @@ export async function detectAllToolStatuses(): Promise<ToolStatus[]> {
|
|
|
181
217
|
name: tool.displayName,
|
|
182
218
|
status: result.source,
|
|
183
219
|
path: result.path,
|
|
220
|
+
version: result.version ?? null,
|
|
184
221
|
};
|
|
185
222
|
}),
|
|
186
223
|
);
|
|
@@ -275,8 +275,8 @@ export function ConfigPage() {
|
|
|
275
275
|
</p>
|
|
276
276
|
<h3 className="mt-1 text-lg font-semibold">登録済みツール</h3>
|
|
277
277
|
<p className="mt-2 text-sm text-muted-foreground">
|
|
278
|
-
CLI と Web UI は同じ設定を参照します。更新すると
|
|
279
|
-
|
|
278
|
+
CLI と Web UI は同じ設定を参照します。更新すると ~/.gwt/tools.json
|
|
279
|
+
に保存されます。
|
|
280
280
|
</p>
|
|
281
281
|
</CardHeader>
|
|
282
282
|
<CardContent>
|