@akiojin/gwt 3.1.2 → 4.0.1

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 (150) hide show
  1. package/README.ja.md +3 -4
  2. package/README.md +3 -4
  3. package/dist/claude.d.ts +21 -0
  4. package/dist/claude.d.ts.map +1 -1
  5. package/dist/claude.js +73 -30
  6. package/dist/claude.js.map +1 -1
  7. package/dist/cli/ui/components/common/Select.d.ts +6 -0
  8. package/dist/cli/ui/components/common/Select.d.ts.map +1 -1
  9. package/dist/cli/ui/components/common/Select.js +3 -2
  10. package/dist/cli/ui/components/common/Select.js.map +1 -1
  11. package/dist/cli/ui/components/screens/AIToolSelectorScreen.d.ts +6 -0
  12. package/dist/cli/ui/components/screens/AIToolSelectorScreen.d.ts.map +1 -1
  13. package/dist/cli/ui/components/screens/AIToolSelectorScreen.js +3 -2
  14. package/dist/cli/ui/components/screens/AIToolSelectorScreen.js.map +1 -1
  15. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +3 -0
  16. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +1 -1
  17. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +3 -2
  18. package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +1 -1
  19. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +3 -0
  20. package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +1 -1
  21. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +3 -2
  22. package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +1 -1
  23. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +3 -0
  24. package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +1 -1
  25. package/dist/cli/ui/components/screens/BranchCreatorScreen.js +3 -2
  26. package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +1 -1
  27. package/dist/cli/ui/components/screens/BranchListScreen.d.ts +3 -0
  28. package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +1 -1
  29. package/dist/cli/ui/components/screens/BranchListScreen.js +3 -4
  30. package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -1
  31. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts +10 -1
  32. package/dist/cli/ui/components/screens/BranchQuickStartScreen.d.ts.map +1 -1
  33. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js +15 -15
  34. package/dist/cli/ui/components/screens/BranchQuickStartScreen.js.map +1 -1
  35. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts +3 -0
  36. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.d.ts.map +1 -1
  37. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js +3 -2
  38. package/dist/cli/ui/components/screens/EnvironmentProfileScreen.js.map +1 -1
  39. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +15 -0
  40. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +1 -1
  41. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +3 -2
  42. package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +1 -1
  43. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts +6 -0
  44. package/dist/cli/ui/components/screens/ModelSelectorScreen.d.ts.map +1 -1
  45. package/dist/cli/ui/components/screens/ModelSelectorScreen.js +3 -7
  46. package/dist/cli/ui/components/screens/ModelSelectorScreen.js.map +1 -1
  47. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +6 -0
  48. package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +1 -1
  49. package/dist/cli/ui/components/screens/PRCleanupScreen.js +3 -2
  50. package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +1 -1
  51. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +6 -0
  52. package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +1 -1
  53. package/dist/cli/ui/components/screens/SessionSelectorScreen.js +3 -2
  54. package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +1 -1
  55. package/dist/cli/ui/hooks/useAppInput.d.ts +20 -0
  56. package/dist/cli/ui/hooks/useAppInput.d.ts.map +1 -0
  57. package/dist/cli/ui/hooks/useAppInput.js +137 -0
  58. package/dist/cli/ui/hooks/useAppInput.js.map +1 -0
  59. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +3 -0
  60. package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +1 -1
  61. package/dist/cli/ui/screens/BranchActionSelectorScreen.js +3 -2
  62. package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +1 -1
  63. package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -1
  64. package/dist/cli/ui/utils/branchFormatter.js +0 -2
  65. package/dist/cli/ui/utils/branchFormatter.js.map +1 -1
  66. package/dist/cli/ui/utils/modelOptions.d.ts.map +1 -1
  67. package/dist/cli/ui/utils/modelOptions.js +25 -16
  68. package/dist/cli/ui/utils/modelOptions.js.map +1 -1
  69. package/dist/client/assets/{index-f5D2XwDh.js → index-v8smkNOL.js} +16 -16
  70. package/dist/client/index.html +1 -1
  71. package/dist/codex.d.ts +32 -0
  72. package/dist/codex.d.ts.map +1 -1
  73. package/dist/codex.js +32 -1
  74. package/dist/codex.js.map +1 -1
  75. package/dist/config/builtin-tools.d.ts +1 -5
  76. package/dist/config/builtin-tools.d.ts.map +1 -1
  77. package/dist/config/builtin-tools.js +1 -18
  78. package/dist/config/builtin-tools.js.map +1 -1
  79. package/dist/gemini.d.ts +17 -0
  80. package/dist/gemini.d.ts.map +1 -1
  81. package/dist/gemini.js +43 -61
  82. package/dist/gemini.js.map +1 -1
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +0 -20
  85. package/dist/index.js.map +1 -1
  86. package/dist/utils/command.d.ts +10 -0
  87. package/dist/utils/command.d.ts.map +1 -0
  88. package/dist/utils/command.js +25 -0
  89. package/dist/utils/command.js.map +1 -0
  90. package/dist/utils/session/index.d.ts +0 -2
  91. package/dist/utils/session/index.d.ts.map +1 -1
  92. package/dist/utils/session/index.js +0 -3
  93. package/dist/utils/session/index.js.map +1 -1
  94. package/dist/utils/session/parsers/index.d.ts +0 -1
  95. package/dist/utils/session/parsers/index.d.ts.map +1 -1
  96. package/dist/utils/session/parsers/index.js +0 -2
  97. package/dist/utils/session/parsers/index.js.map +1 -1
  98. package/dist/utils/session.d.ts +0 -1
  99. package/dist/utils/session.d.ts.map +1 -1
  100. package/dist/utils/session.js +0 -1
  101. package/dist/utils/session.js.map +1 -1
  102. package/dist/utils/terminal.d.ts +34 -0
  103. package/dist/utils/terminal.d.ts.map +1 -1
  104. package/dist/utils/terminal.js +51 -4
  105. package/dist/utils/terminal.js.map +1 -1
  106. package/dist/web/client/src/components/branch-detail/BranchInfoCards.d.ts.map +1 -1
  107. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js +0 -2
  108. package/dist/web/client/src/components/branch-detail/BranchInfoCards.js.map +1 -1
  109. package/package.json +1 -1
  110. package/src/claude.ts +92 -34
  111. package/src/cli/ui/__tests__/components/App.protected-branch.test.tsx +3 -1
  112. package/src/cli/ui/__tests__/components/ModelSelectorScreen.initial.test.tsx +8 -5
  113. package/src/cli/ui/components/common/Select.tsx +9 -2
  114. package/src/cli/ui/components/screens/AIToolSelectorScreen.tsx +9 -2
  115. package/src/cli/ui/components/screens/BatchMergeProgressScreen.tsx +6 -2
  116. package/src/cli/ui/components/screens/BatchMergeResultScreen.tsx +6 -2
  117. package/src/cli/ui/components/screens/BranchCreatorScreen.tsx +6 -2
  118. package/src/cli/ui/components/screens/BranchListScreen.tsx +6 -4
  119. package/src/cli/ui/components/screens/BranchQuickStartScreen.tsx +36 -27
  120. package/src/cli/ui/components/screens/EnvironmentProfileScreen.tsx +6 -2
  121. package/src/cli/ui/components/screens/ExecutionModeSelectorScreen.tsx +18 -2
  122. package/src/cli/ui/components/screens/ModelSelectorScreen.tsx +9 -10
  123. package/src/cli/ui/components/screens/PRCleanupScreen.tsx +9 -2
  124. package/src/cli/ui/components/screens/SessionSelectorScreen.tsx +9 -2
  125. package/src/cli/ui/hooks/useAppInput.ts +171 -0
  126. package/src/cli/ui/screens/BranchActionSelectorScreen.tsx +6 -2
  127. package/src/cli/ui/screens/__tests__/BranchActionSelectorScreen.test.tsx +68 -1
  128. package/src/cli/ui/utils/branchFormatter.ts +0 -1
  129. package/src/cli/ui/utils/modelOptions.test.ts +9 -6
  130. package/src/cli/ui/utils/modelOptions.ts +25 -18
  131. package/src/codex.ts +40 -1
  132. package/src/config/builtin-tools.ts +1 -19
  133. package/src/gemini.ts +47 -68
  134. package/src/index.ts +0 -26
  135. package/src/utils/command.ts +26 -0
  136. package/src/utils/session/index.ts +0 -4
  137. package/src/utils/session/parsers/index.ts +0 -3
  138. package/src/utils/session.ts +0 -1
  139. package/src/utils/terminal.ts +65 -4
  140. package/src/web/client/src/components/branch-detail/BranchInfoCards.tsx +0 -1
  141. package/dist/qwen.d.ts +0 -16
  142. package/dist/qwen.d.ts.map +0 -1
  143. package/dist/qwen.js +0 -202
  144. package/dist/qwen.js.map +0 -1
  145. package/dist/utils/session/parsers/qwen.d.ts +0 -21
  146. package/dist/utils/session/parsers/qwen.d.ts.map +0 -1
  147. package/dist/utils/session/parsers/qwen.js +0 -36
  148. package/dist/utils/session/parsers/qwen.js.map +0 -1
  149. package/src/qwen.ts +0 -273
  150. package/src/utils/session/parsers/qwen.ts +0 -54
package/dist/qwen.js DELETED
@@ -1,202 +0,0 @@
1
- import { execa } from "execa";
2
- import chalk from "chalk";
3
- import { existsSync } from "fs";
4
- import { createChildStdio, getTerminalStreams } from "./utils/terminal.js";
5
- import { findLatestQwenSessionId } from "./utils/session.js";
6
- const QWEN_CLI_PACKAGE = "@qwen-code/qwen-code@latest";
7
- export class QwenError extends Error {
8
- cause;
9
- constructor(message, cause) {
10
- super(message);
11
- this.cause = cause;
12
- this.name = "QwenError";
13
- }
14
- }
15
- export async function launchQwenCLI(worktreePath, options = {}) {
16
- const terminal = getTerminalStreams();
17
- try {
18
- // Check if the worktree path exists
19
- if (!existsSync(worktreePath)) {
20
- throw new Error(`Worktree path does not exist: ${worktreePath}`);
21
- }
22
- console.log(chalk.blue("šŸš€ Launching Qwen CLI..."));
23
- console.log(chalk.gray(` Working directory: ${worktreePath}`));
24
- const args = ["--checkpointing"];
25
- if (options.model) {
26
- args.push("--model", options.model);
27
- console.log(chalk.green(` šŸŽÆ Model: ${options.model}`));
28
- }
29
- // Handle execution mode
30
- // Note: Qwen CLI doesn't have explicit continue/resume CLI options at startup.
31
- // Session management is done via /chat commands during interactive sessions.
32
- const resumeSessionId = options.sessionId && options.sessionId.trim().length > 0
33
- ? options.sessionId.trim()
34
- : null;
35
- const usedExplicitSessionId = Boolean(resumeSessionId) &&
36
- (options.mode === "continue" || options.mode === "resume");
37
- switch (options.mode) {
38
- case "continue":
39
- console.log(chalk.cyan(resumeSessionId
40
- ? ` ā­ļø Starting session (then /chat resume ${resumeSessionId})`
41
- : " ā­ļø Starting session (use /chat resume in the CLI to continue)"));
42
- break;
43
- case "resume":
44
- console.log(chalk.cyan(resumeSessionId
45
- ? ` šŸ”„ Starting session (then /chat resume ${resumeSessionId})`
46
- : " šŸ”„ Starting session (use /chat resume in the CLI to continue)"));
47
- break;
48
- case "normal":
49
- default:
50
- console.log(chalk.green(" ✨ Starting new session"));
51
- break;
52
- }
53
- // Handle skip permissions (YOLO mode)
54
- if (options.skipPermissions) {
55
- args.push("--yolo");
56
- console.log(chalk.yellow(" āš ļø Auto-approving all actions (YOLO mode)"));
57
- }
58
- // Append any pass-through arguments after our flags
59
- if (options.extraArgs && options.extraArgs.length > 0) {
60
- args.push(...options.extraArgs);
61
- }
62
- console.log(chalk.gray(` šŸ“‹ Args: ${args.join(" ")}`));
63
- terminal.exitRawMode();
64
- const baseEnv = Object.fromEntries(Object.entries({
65
- ...process.env,
66
- ...(options.envOverrides ?? {}),
67
- }).filter((entry) => typeof entry[1] === "string"));
68
- const childStdio = createChildStdio();
69
- // Auto-detect locally installed qwen command
70
- const hasLocalQwen = await isQwenCommandAvailable();
71
- try {
72
- const execChild = async (child) => {
73
- try {
74
- await child;
75
- }
76
- catch (execError) {
77
- // Treat SIGINT/SIGTERM as normal exit (user pressed Ctrl+C)
78
- const signal = execError?.signal;
79
- if (signal === "SIGINT" || signal === "SIGTERM") {
80
- return;
81
- }
82
- throw execError;
83
- }
84
- };
85
- if (hasLocalQwen) {
86
- // Use locally installed qwen command
87
- console.log(chalk.green(" ✨ Using locally installed qwen command"));
88
- const child = execa("qwen", args, {
89
- cwd: worktreePath,
90
- shell: true,
91
- stdin: childStdio.stdin,
92
- stdout: childStdio.stdout,
93
- stderr: childStdio.stderr,
94
- env: baseEnv,
95
- });
96
- await execChild(child);
97
- }
98
- else {
99
- // Fallback to bunx
100
- console.log(chalk.cyan(" šŸ”„ Falling back to bunx @qwen-code/qwen-code@latest"));
101
- console.log(chalk.yellow(" šŸ’” Recommended: Install Qwen CLI globally for faster startup"));
102
- console.log(chalk.yellow(" npm install -g @qwen-code/qwen-code"));
103
- console.log("");
104
- // Wait 2 seconds to let user read the message
105
- await new Promise((resolve) => setTimeout(resolve, 2000));
106
- const child = execa("bunx", [QWEN_CLI_PACKAGE, ...args], {
107
- cwd: worktreePath,
108
- shell: true,
109
- stdin: childStdio.stdin,
110
- stdout: childStdio.stdout,
111
- stderr: childStdio.stderr,
112
- env: baseEnv,
113
- });
114
- await execChild(child);
115
- }
116
- }
117
- finally {
118
- childStdio.cleanup();
119
- }
120
- let capturedSessionId = null;
121
- try {
122
- const detected = (await findLatestQwenSessionId(worktreePath)) ?? null;
123
- capturedSessionId = usedExplicitSessionId ? resumeSessionId : detected;
124
- }
125
- catch {
126
- capturedSessionId = usedExplicitSessionId ? resumeSessionId : null;
127
- }
128
- if (capturedSessionId) {
129
- console.log(chalk.cyan(`\n šŸ†” Session tag: ${capturedSessionId}`));
130
- console.log(chalk.gray(` Resume in Qwen CLI: /chat resume ${capturedSessionId}`));
131
- }
132
- else {
133
- console.log(chalk.yellow("\n ā„¹ļø Could not determine Qwen session tag automatically."));
134
- }
135
- return capturedSessionId ? { sessionId: capturedSessionId } : {};
136
- }
137
- catch (error) {
138
- const hasLocalQwen = await isQwenCommandAvailable();
139
- let errorMessage;
140
- const err = error;
141
- if (err.code === "ENOENT") {
142
- if (hasLocalQwen) {
143
- errorMessage =
144
- "qwen command not found. Please ensure Qwen CLI is properly installed.";
145
- }
146
- else {
147
- errorMessage =
148
- "bunx command not found. Please ensure Bun is installed so Qwen CLI can run via bunx.";
149
- }
150
- }
151
- else {
152
- const details = error instanceof Error ? error.message : String(error);
153
- errorMessage = `Failed to launch Qwen CLI: ${details || "Unknown error"}`;
154
- }
155
- if (process.platform === "win32") {
156
- console.error(chalk.red("\nšŸ’” Windows troubleshooting tips:"));
157
- if (hasLocalQwen) {
158
- console.error(chalk.yellow(" 1. Confirm that Qwen CLI is installed and the 'qwen' command is on PATH"));
159
- console.error(chalk.yellow(' 2. Run "qwen --version" to verify the setup'));
160
- }
161
- else {
162
- console.error(chalk.yellow(" 1. Confirm that Bun is installed and bunx is available"));
163
- console.error(chalk.yellow(' 2. Run "bunx @qwen-code/qwen-code@latest -- --version" to verify the setup'));
164
- }
165
- console.error(chalk.yellow(" 3. Restart your terminal or IDE to refresh PATH"));
166
- }
167
- throw new QwenError(errorMessage, error);
168
- }
169
- finally {
170
- terminal.exitRawMode();
171
- }
172
- }
173
- /**
174
- * Check if locally installed `qwen` command is available
175
- * @returns true if `qwen` command exists in PATH, false otherwise
176
- */
177
- async function isQwenCommandAvailable() {
178
- try {
179
- const command = process.platform === "win32" ? "where" : "which";
180
- await execa(command, ["qwen"], { shell: true });
181
- return true;
182
- }
183
- catch {
184
- // qwen command not found in PATH
185
- return false;
186
- }
187
- }
188
- export async function isQwenCLIAvailable() {
189
- try {
190
- await execa("bunx", [QWEN_CLI_PACKAGE, "--version"], { shell: true });
191
- return true;
192
- }
193
- catch (error) {
194
- const err = error;
195
- if (err.code === "ENOENT") {
196
- console.error(chalk.yellow("\nāš ļø bunx command not found"));
197
- console.error(chalk.gray(" Install Bun and confirm that bunx is available before continuing"));
198
- }
199
- return false;
200
- }
201
- }
202
- //# sourceMappingURL=qwen.js.map
package/dist/qwen.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"qwen.js","sourceRoot":"","sources":["../src/qwen.ts"],"names":[],"mappings":"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"}
@@ -1,21 +0,0 @@
1
- /**
2
- * Qwen CLI session parser
3
- *
4
- * Handles session detection for Qwen CLI.
5
- * Session files are stored in ~/.qwen/tmp/<project_hash>/
6
- * and checkpoints in ~/.qwen/tmp/<project_hash>/checkpoints/
7
- */
8
- /**
9
- * Finds the latest Qwen session ID.
10
- *
11
- * Search order:
12
- * 1. ~/.qwen/tmp/<hash>/*.json or *.jsonl
13
- * 2. ~/.qwen/tmp/<hash>/checkpoints/*.json or *.ckpt
14
- *
15
- * Falls back to filename (without extension) if no session ID is found in content.
16
- *
17
- * @param _cwd - Working directory (currently unused, reserved for future per-project filtering)
18
- * @returns Session ID string or null if not found
19
- */
20
- export declare function findLatestQwenSessionId(_cwd: string): Promise<string | null>;
21
- //# sourceMappingURL=qwen.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"qwen.d.ts","sourceRoot":"","sources":["../../../../src/utils/session/parsers/qwen.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH;;;;;;;;;;;GAWG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAuBxB"}
@@ -1,36 +0,0 @@
1
- /**
2
- * Qwen CLI session parser
3
- *
4
- * Handles session detection for Qwen CLI.
5
- * Session files are stored in ~/.qwen/tmp/<project_hash>/
6
- * and checkpoints in ~/.qwen/tmp/<project_hash>/checkpoints/
7
- */
8
- import path from "node:path";
9
- import { homedir } from "node:os";
10
- import { findLatestNestedSessionFile, readSessionIdFromFile, } from "../common.js";
11
- /**
12
- * Finds the latest Qwen session ID.
13
- *
14
- * Search order:
15
- * 1. ~/.qwen/tmp/<hash>/*.json or *.jsonl
16
- * 2. ~/.qwen/tmp/<hash>/checkpoints/*.json or *.ckpt
17
- *
18
- * Falls back to filename (without extension) if no session ID is found in content.
19
- *
20
- * @param _cwd - Working directory (currently unused, reserved for future per-project filtering)
21
- * @returns Session ID string or null if not found
22
- */
23
- export async function findLatestQwenSessionId(_cwd) {
24
- const baseDir = path.join(homedir(), ".qwen", "tmp");
25
- // Try root level first, then checkpoints subdirectory
26
- const latest = (await findLatestNestedSessionFile(baseDir, [], (name) => name.endsWith(".json") || name.endsWith(".jsonl"))) ??
27
- (await findLatestNestedSessionFile(baseDir, ["checkpoints"], (name) => name.endsWith(".json") || name.endsWith(".ckpt")));
28
- if (!latest)
29
- return null;
30
- const fromContent = await readSessionIdFromFile(latest);
31
- if (fromContent)
32
- return fromContent;
33
- // Fallback: use filename (without extension) as tag
34
- return path.basename(latest).replace(/\.[^.]+$/, "");
35
- }
36
- //# sourceMappingURL=qwen.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"qwen.js","sourceRoot":"","sources":["../../../../src/utils/session/parsers/qwen.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAY;IAEZ,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAErD,sDAAsD;IACtD,MAAM,MAAM,GACV,CAAC,MAAM,2BAA2B,CAChC,OAAO,EACP,EAAE,EACF,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC5D,CAAC;QACF,CAAC,MAAM,2BAA2B,CAChC,OAAO,EACP,CAAC,aAAa,CAAC,EACf,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC3D,CAAC,CAAC;IAEL,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,WAAW,GAAG,MAAM,qBAAqB,CAAC,MAAM,CAAC,CAAC;IACxD,IAAI,WAAW;QAAE,OAAO,WAAW,CAAC;IAEpC,oDAAoD;IACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC"}
package/src/qwen.ts DELETED
@@ -1,273 +0,0 @@
1
- import { execa } from "execa";
2
- import chalk from "chalk";
3
- import { existsSync } from "fs";
4
- import { createChildStdio, getTerminalStreams } from "./utils/terminal.js";
5
- import { findLatestQwenSessionId } from "./utils/session.js";
6
-
7
- const QWEN_CLI_PACKAGE = "@qwen-code/qwen-code@latest";
8
-
9
- export class QwenError extends Error {
10
- constructor(
11
- message: string,
12
- public cause?: unknown,
13
- ) {
14
- super(message);
15
- this.name = "QwenError";
16
- }
17
- }
18
-
19
- export async function launchQwenCLI(
20
- worktreePath: string,
21
- options: {
22
- skipPermissions?: boolean;
23
- mode?: "normal" | "continue" | "resume";
24
- extraArgs?: string[];
25
- envOverrides?: Record<string, string>;
26
- model?: string;
27
- sessionId?: string | null;
28
- } = {},
29
- ): Promise<{ sessionId?: string | null }> {
30
- const terminal = getTerminalStreams();
31
-
32
- try {
33
- // Check if the worktree path exists
34
- if (!existsSync(worktreePath)) {
35
- throw new Error(`Worktree path does not exist: ${worktreePath}`);
36
- }
37
-
38
- console.log(chalk.blue("šŸš€ Launching Qwen CLI..."));
39
- console.log(chalk.gray(` Working directory: ${worktreePath}`));
40
-
41
- const args: string[] = ["--checkpointing"];
42
-
43
- if (options.model) {
44
- args.push("--model", options.model);
45
- console.log(chalk.green(` šŸŽÆ Model: ${options.model}`));
46
- }
47
-
48
- // Handle execution mode
49
- // Note: Qwen CLI doesn't have explicit continue/resume CLI options at startup.
50
- // Session management is done via /chat commands during interactive sessions.
51
- const resumeSessionId =
52
- options.sessionId && options.sessionId.trim().length > 0
53
- ? options.sessionId.trim()
54
- : null;
55
- const usedExplicitSessionId =
56
- Boolean(resumeSessionId) &&
57
- (options.mode === "continue" || options.mode === "resume");
58
- switch (options.mode) {
59
- case "continue":
60
- console.log(
61
- chalk.cyan(
62
- resumeSessionId
63
- ? ` ā­ļø Starting session (then /chat resume ${resumeSessionId})`
64
- : " ā­ļø Starting session (use /chat resume in the CLI to continue)",
65
- ),
66
- );
67
- break;
68
- case "resume":
69
- console.log(
70
- chalk.cyan(
71
- resumeSessionId
72
- ? ` šŸ”„ Starting session (then /chat resume ${resumeSessionId})`
73
- : " šŸ”„ Starting session (use /chat resume in the CLI to continue)",
74
- ),
75
- );
76
- break;
77
- case "normal":
78
- default:
79
- console.log(chalk.green(" ✨ Starting new session"));
80
- break;
81
- }
82
-
83
- // Handle skip permissions (YOLO mode)
84
- if (options.skipPermissions) {
85
- args.push("--yolo");
86
- console.log(
87
- chalk.yellow(" āš ļø Auto-approving all actions (YOLO mode)"),
88
- );
89
- }
90
-
91
- // Append any pass-through arguments after our flags
92
- if (options.extraArgs && options.extraArgs.length > 0) {
93
- args.push(...options.extraArgs);
94
- }
95
-
96
- console.log(chalk.gray(` šŸ“‹ Args: ${args.join(" ")}`));
97
-
98
- terminal.exitRawMode();
99
-
100
- const baseEnv = Object.fromEntries(
101
- Object.entries({
102
- ...process.env,
103
- ...(options.envOverrides ?? {}),
104
- }).filter(
105
- (entry): entry is [string, string] => typeof entry[1] === "string",
106
- ),
107
- );
108
-
109
- const childStdio = createChildStdio();
110
-
111
- // Auto-detect locally installed qwen command
112
- const hasLocalQwen = await isQwenCommandAvailable();
113
-
114
- try {
115
- const execChild = async (child: Promise<unknown>) => {
116
- try {
117
- await child;
118
- } catch (execError: unknown) {
119
- // Treat SIGINT/SIGTERM as normal exit (user pressed Ctrl+C)
120
- const signal = (execError as { signal?: unknown })?.signal;
121
- if (signal === "SIGINT" || signal === "SIGTERM") {
122
- return;
123
- }
124
- throw execError;
125
- }
126
- };
127
-
128
- if (hasLocalQwen) {
129
- // Use locally installed qwen command
130
- console.log(chalk.green(" ✨ Using locally installed qwen command"));
131
- const child = execa("qwen", args, {
132
- cwd: worktreePath,
133
- shell: true,
134
- stdin: childStdio.stdin,
135
- stdout: childStdio.stdout,
136
- stderr: childStdio.stderr,
137
- env: baseEnv,
138
- });
139
- await execChild(child);
140
- } else {
141
- // Fallback to bunx
142
- console.log(
143
- chalk.cyan(" šŸ”„ Falling back to bunx @qwen-code/qwen-code@latest"),
144
- );
145
- console.log(
146
- chalk.yellow(
147
- " šŸ’” Recommended: Install Qwen CLI globally for faster startup",
148
- ),
149
- );
150
- console.log(chalk.yellow(" npm install -g @qwen-code/qwen-code"));
151
- console.log("");
152
- // Wait 2 seconds to let user read the message
153
- await new Promise((resolve) => setTimeout(resolve, 2000));
154
- const child = execa("bunx", [QWEN_CLI_PACKAGE, ...args], {
155
- cwd: worktreePath,
156
- shell: true,
157
- stdin: childStdio.stdin,
158
- stdout: childStdio.stdout,
159
- stderr: childStdio.stderr,
160
- env: baseEnv,
161
- });
162
- await execChild(child);
163
- }
164
- } finally {
165
- childStdio.cleanup();
166
- }
167
-
168
- let capturedSessionId: string | null = null;
169
- try {
170
- const detected = (await findLatestQwenSessionId(worktreePath)) ?? null;
171
- capturedSessionId = usedExplicitSessionId ? resumeSessionId : detected;
172
- } catch {
173
- capturedSessionId = usedExplicitSessionId ? resumeSessionId : null;
174
- }
175
-
176
- if (capturedSessionId) {
177
- console.log(chalk.cyan(`\n šŸ†” Session tag: ${capturedSessionId}`));
178
- console.log(
179
- chalk.gray(` Resume in Qwen CLI: /chat resume ${capturedSessionId}`),
180
- );
181
- } else {
182
- console.log(
183
- chalk.yellow(
184
- "\n ā„¹ļø Could not determine Qwen session tag automatically.",
185
- ),
186
- );
187
- }
188
-
189
- return capturedSessionId ? { sessionId: capturedSessionId } : {};
190
- } catch (error: unknown) {
191
- const hasLocalQwen = await isQwenCommandAvailable();
192
- let errorMessage: string;
193
- const err = error as NodeJS.ErrnoException;
194
-
195
- if (err.code === "ENOENT") {
196
- if (hasLocalQwen) {
197
- errorMessage =
198
- "qwen command not found. Please ensure Qwen CLI is properly installed.";
199
- } else {
200
- errorMessage =
201
- "bunx command not found. Please ensure Bun is installed so Qwen CLI can run via bunx.";
202
- }
203
- } else {
204
- const details = error instanceof Error ? error.message : String(error);
205
- errorMessage = `Failed to launch Qwen CLI: ${details || "Unknown error"}`;
206
- }
207
-
208
- if (process.platform === "win32") {
209
- console.error(chalk.red("\nšŸ’” Windows troubleshooting tips:"));
210
- if (hasLocalQwen) {
211
- console.error(
212
- chalk.yellow(
213
- " 1. Confirm that Qwen CLI is installed and the 'qwen' command is on PATH",
214
- ),
215
- );
216
- console.error(
217
- chalk.yellow(' 2. Run "qwen --version" to verify the setup'),
218
- );
219
- } else {
220
- console.error(
221
- chalk.yellow(
222
- " 1. Confirm that Bun is installed and bunx is available",
223
- ),
224
- );
225
- console.error(
226
- chalk.yellow(
227
- ' 2. Run "bunx @qwen-code/qwen-code@latest -- --version" to verify the setup',
228
- ),
229
- );
230
- }
231
- console.error(
232
- chalk.yellow(" 3. Restart your terminal or IDE to refresh PATH"),
233
- );
234
- }
235
-
236
- throw new QwenError(errorMessage, error);
237
- } finally {
238
- terminal.exitRawMode();
239
- }
240
- }
241
-
242
- /**
243
- * Check if locally installed `qwen` command is available
244
- * @returns true if `qwen` command exists in PATH, false otherwise
245
- */
246
- async function isQwenCommandAvailable(): Promise<boolean> {
247
- try {
248
- const command = process.platform === "win32" ? "where" : "which";
249
- await execa(command, ["qwen"], { shell: true });
250
- return true;
251
- } catch {
252
- // qwen command not found in PATH
253
- return false;
254
- }
255
- }
256
-
257
- export async function isQwenCLIAvailable(): Promise<boolean> {
258
- try {
259
- await execa("bunx", [QWEN_CLI_PACKAGE, "--version"], { shell: true });
260
- return true;
261
- } catch (error: unknown) {
262
- const err = error as NodeJS.ErrnoException;
263
- if (err.code === "ENOENT") {
264
- console.error(chalk.yellow("\nāš ļø bunx command not found"));
265
- console.error(
266
- chalk.gray(
267
- " Install Bun and confirm that bunx is available before continuing",
268
- ),
269
- );
270
- }
271
- return false;
272
- }
273
- }
@@ -1,54 +0,0 @@
1
- /**
2
- * Qwen CLI session parser
3
- *
4
- * Handles session detection for Qwen CLI.
5
- * Session files are stored in ~/.qwen/tmp/<project_hash>/
6
- * and checkpoints in ~/.qwen/tmp/<project_hash>/checkpoints/
7
- */
8
-
9
- import path from "node:path";
10
- import { homedir } from "node:os";
11
-
12
- import {
13
- findLatestNestedSessionFile,
14
- readSessionIdFromFile,
15
- } from "../common.js";
16
-
17
- /**
18
- * Finds the latest Qwen session ID.
19
- *
20
- * Search order:
21
- * 1. ~/.qwen/tmp/<hash>/*.json or *.jsonl
22
- * 2. ~/.qwen/tmp/<hash>/checkpoints/*.json or *.ckpt
23
- *
24
- * Falls back to filename (without extension) if no session ID is found in content.
25
- *
26
- * @param _cwd - Working directory (currently unused, reserved for future per-project filtering)
27
- * @returns Session ID string or null if not found
28
- */
29
- export async function findLatestQwenSessionId(
30
- _cwd: string,
31
- ): Promise<string | null> {
32
- const baseDir = path.join(homedir(), ".qwen", "tmp");
33
-
34
- // Try root level first, then checkpoints subdirectory
35
- const latest =
36
- (await findLatestNestedSessionFile(
37
- baseDir,
38
- [],
39
- (name) => name.endsWith(".json") || name.endsWith(".jsonl"),
40
- )) ??
41
- (await findLatestNestedSessionFile(
42
- baseDir,
43
- ["checkpoints"],
44
- (name) => name.endsWith(".json") || name.endsWith(".ckpt"),
45
- ));
46
-
47
- if (!latest) return null;
48
-
49
- const fromContent = await readSessionIdFromFile(latest);
50
- if (fromContent) return fromContent;
51
-
52
- // Fallback: use filename (without extension) as tag
53
- return path.basename(latest).replace(/\.[^.]+$/, "");
54
- }