@akiojin/gwt 4.12.0 → 4.12.2
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/bin/gwt.js +35 -9
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +67 -14
- package/dist/claude.js.map +1 -1
- package/dist/cli/ui/App.solid.d.ts.map +1 -1
- package/dist/cli/ui/App.solid.js +40 -8
- package/dist/cli/ui/App.solid.js.map +1 -1
- package/dist/cli/ui/components/solid/WizardController.d.ts.map +1 -1
- package/dist/cli/ui/components/solid/WizardController.js +48 -2
- package/dist/cli/ui/components/solid/WizardController.js.map +1 -1
- package/dist/cli/ui/components/solid/WizardSteps.d.ts +5 -0
- package/dist/cli/ui/components/solid/WizardSteps.d.ts.map +1 -1
- package/dist/cli/ui/components/solid/WizardSteps.js +29 -6
- package/dist/cli/ui/components/solid/WizardSteps.js.map +1 -1
- package/dist/cli/ui/utils/installedVersionCache.d.ts +33 -0
- package/dist/cli/ui/utils/installedVersionCache.d.ts.map +1 -0
- package/dist/cli/ui/utils/installedVersionCache.js +59 -0
- package/dist/cli/ui/utils/installedVersionCache.js.map +1 -0
- package/dist/cli/ui/utils/modelOptions.d.ts.map +1 -1
- package/dist/cli/ui/utils/modelOptions.js +16 -0
- package/dist/cli/ui/utils/modelOptions.js.map +1 -1
- package/dist/codex.d.ts.map +1 -1
- package/dist/codex.js +63 -22
- package/dist/codex.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/logging/reader.d.ts +2 -1
- package/dist/logging/reader.d.ts.map +1 -1
- package/dist/logging/reader.js +37 -1
- package/dist/logging/reader.js.map +1 -1
- package/dist/opentui/index.solid.js +298 -264
- package/dist/services/codingAgentResolver.d.ts.map +1 -1
- package/dist/services/codingAgentResolver.js +8 -6
- package/dist/services/codingAgentResolver.js.map +1 -1
- package/dist/shared/codingAgentConstants.d.ts +3 -0
- package/dist/shared/codingAgentConstants.d.ts.map +1 -1
- package/dist/shared/codingAgentConstants.js +66 -0
- package/dist/shared/codingAgentConstants.js.map +1 -1
- package/dist/utils/bun-runtime.d.ts +12 -0
- package/dist/utils/bun-runtime.d.ts.map +1 -0
- package/dist/utils/bun-runtime.js +13 -0
- package/dist/utils/bun-runtime.js.map +1 -0
- package/dist/utils/session/parsers/codex.d.ts.map +1 -1
- package/dist/utils/session/parsers/codex.js +0 -1
- package/dist/utils/session/parsers/codex.js.map +1 -1
- package/package.json +1 -1
- package/src/claude.ts +79 -15
- package/src/cli/ui/App.solid.tsx +55 -6
- package/src/cli/ui/__tests__/solid/AppSolid.cleanup.test.tsx +91 -0
- package/src/cli/ui/__tests__/solid/components/WizardController.test.tsx +63 -0
- package/src/cli/ui/__tests__/solid/components/WizardSteps.test.tsx +91 -1
- package/src/cli/ui/components/solid/WizardController.tsx +65 -1
- package/src/cli/ui/components/solid/WizardSteps.tsx +55 -10
- package/src/cli/ui/utils/__tests__/installedVersionCache.test.ts +46 -0
- package/src/cli/ui/utils/installedVersionCache.ts +84 -0
- package/src/cli/ui/utils/modelOptions.test.ts +6 -0
- package/src/cli/ui/utils/modelOptions.ts +16 -0
- package/src/codex.ts +78 -22
- package/src/index.ts +5 -0
- package/src/logging/reader.ts +48 -1
- package/src/services/codingAgentResolver.ts +12 -5
- package/src/shared/codingAgentConstants.ts +73 -0
- package/src/utils/bun-runtime.ts +29 -0
- package/src/utils/session/parsers/codex.ts +0 -1
package/src/codex.ts
CHANGED
|
@@ -17,8 +17,14 @@ import {
|
|
|
17
17
|
runAgentWithPty,
|
|
18
18
|
shouldCaptureAgentOutput,
|
|
19
19
|
} from "./logging/agentOutput.js";
|
|
20
|
+
import { createLogger } from "./logging/logger.js";
|
|
21
|
+
import {
|
|
22
|
+
shouldEnableCodexSkillsFlag,
|
|
23
|
+
withCodexSkillsFlag,
|
|
24
|
+
} from "./shared/codingAgentConstants.js";
|
|
20
25
|
|
|
21
26
|
const CODEX_CLI_PACKAGE = "@openai/codex";
|
|
27
|
+
const logger = createLogger({ category: "codex" });
|
|
22
28
|
|
|
23
29
|
/**
|
|
24
30
|
* Reasoning effort levels supported by Codex CLI.
|
|
@@ -47,8 +53,6 @@ export const buildDefaultCodexArgs = (
|
|
|
47
53
|
): string[] => [
|
|
48
54
|
"--enable",
|
|
49
55
|
"web_search_request",
|
|
50
|
-
"--enable",
|
|
51
|
-
"skills",
|
|
52
56
|
`--model=${model}`,
|
|
53
57
|
"--sandbox",
|
|
54
58
|
"workspace-write",
|
|
@@ -171,7 +175,18 @@ export async function launchCodexCLI(
|
|
|
171
175
|
args.push(...options.extraArgs);
|
|
172
176
|
}
|
|
173
177
|
|
|
174
|
-
const
|
|
178
|
+
const requestedVersion = options.version ?? "latest";
|
|
179
|
+
const codexLookup = await findCommand("codex");
|
|
180
|
+
const skillsFlagVersion =
|
|
181
|
+
requestedVersion === "installed"
|
|
182
|
+
? (codexLookup.version ?? null)
|
|
183
|
+
: requestedVersion === "latest"
|
|
184
|
+
? null
|
|
185
|
+
: requestedVersion;
|
|
186
|
+
const codexArgs = withCodexSkillsFlag(
|
|
187
|
+
buildDefaultCodexArgs(model, reasoningEffort),
|
|
188
|
+
shouldEnableCodexSkillsFlag(skillsFlagVersion),
|
|
189
|
+
);
|
|
175
190
|
|
|
176
191
|
args.push(...codexArgs);
|
|
177
192
|
|
|
@@ -191,26 +206,34 @@ export async function launchCodexCLI(
|
|
|
191
206
|
const captureOutput = shouldCaptureAgentOutput(env);
|
|
192
207
|
const childStdio = captureOutput ? null : createChildStdio();
|
|
193
208
|
|
|
194
|
-
//
|
|
195
|
-
const codexLookup = await findCommand("codex");
|
|
209
|
+
// codexLookup is used to decide local vs bunx execution
|
|
196
210
|
|
|
197
211
|
const execChild = async (child: Promise<unknown>) => {
|
|
198
212
|
try {
|
|
199
|
-
await child
|
|
213
|
+
const result = (await child) as {
|
|
214
|
+
exitCode?: number | null;
|
|
215
|
+
signal?: string | null;
|
|
216
|
+
};
|
|
217
|
+
return {
|
|
218
|
+
exitCode: result.exitCode ?? 0,
|
|
219
|
+
signal: result.signal ?? null,
|
|
220
|
+
};
|
|
200
221
|
} catch (execError: unknown) {
|
|
201
222
|
// Treat SIGINT/SIGTERM as normal exit (user pressed Ctrl+C)
|
|
202
223
|
const signal = (execError as { signal?: unknown })?.signal;
|
|
224
|
+
const exitCode =
|
|
225
|
+
(execError as { exitCode?: number | null })?.exitCode ?? null;
|
|
203
226
|
if (signal === "SIGINT" || signal === "SIGTERM") {
|
|
204
|
-
return;
|
|
227
|
+
return { exitCode, signal };
|
|
205
228
|
}
|
|
206
229
|
throw execError;
|
|
207
230
|
}
|
|
208
231
|
};
|
|
209
|
-
// Treat
|
|
210
|
-
// SIGHUP can occur when the PTY closes, SIGINT/SIGTERM are user interrupts
|
|
232
|
+
// Treat SIGINT (2), SIGTERM (15) as normal exit signals (user interrupts)
|
|
211
233
|
const isNormalExitSignal = (signal?: number | null) =>
|
|
212
|
-
signal ===
|
|
234
|
+
signal === 2 || signal === 15;
|
|
213
235
|
const runCommand = async (command: string, commandArgs: string[]) => {
|
|
236
|
+
const runStartedAt = Date.now();
|
|
214
237
|
if (captureOutput) {
|
|
215
238
|
const result = await runAgentWithPty({
|
|
216
239
|
command,
|
|
@@ -219,12 +242,27 @@ export async function launchCodexCLI(
|
|
|
219
242
|
env,
|
|
220
243
|
agentId: "codex-cli",
|
|
221
244
|
});
|
|
222
|
-
|
|
245
|
+
const durationMs = Date.now() - runStartedAt;
|
|
246
|
+
const exitCode = result.exitCode ?? null;
|
|
247
|
+
const signal = result.signal ?? null;
|
|
248
|
+
const signalIsNormal = isNormalExitSignal(signal);
|
|
249
|
+
const hasError =
|
|
250
|
+
(!signalIsNormal && signal !== null && signal !== undefined) ||
|
|
251
|
+
(exitCode !== null && exitCode !== 0);
|
|
252
|
+
if (hasError) {
|
|
253
|
+
logger.error({ exitCode, signal, durationMs }, "Codex CLI exited");
|
|
254
|
+
} else {
|
|
255
|
+
logger.info({ exitCode, signal, durationMs }, "Codex CLI exited");
|
|
256
|
+
}
|
|
257
|
+
if (signalIsNormal) {
|
|
223
258
|
return;
|
|
224
259
|
}
|
|
225
|
-
if (
|
|
260
|
+
if (signal !== null && signal !== undefined) {
|
|
261
|
+
throw new Error(`Codex CLI terminated by signal ${signal}`);
|
|
262
|
+
}
|
|
263
|
+
if (exitCode !== null && exitCode !== 0) {
|
|
226
264
|
throw new Error(
|
|
227
|
-
`Codex CLI exited with code ${
|
|
265
|
+
`Codex CLI exited with code ${exitCode ?? "unknown"}`,
|
|
228
266
|
);
|
|
229
267
|
}
|
|
230
268
|
return;
|
|
@@ -234,19 +272,37 @@ export async function launchCodexCLI(
|
|
|
234
272
|
return;
|
|
235
273
|
}
|
|
236
274
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
275
|
+
try {
|
|
276
|
+
const child = execa(command, commandArgs, {
|
|
277
|
+
cwd: worktreePath,
|
|
278
|
+
stdin: childStdio.stdin,
|
|
279
|
+
stdout: childStdio.stdout,
|
|
280
|
+
stderr: childStdio.stderr,
|
|
281
|
+
env,
|
|
282
|
+
});
|
|
283
|
+
const result = await execChild(child);
|
|
284
|
+
const durationMs = Date.now() - runStartedAt;
|
|
285
|
+
logger.info(
|
|
286
|
+
{
|
|
287
|
+
exitCode: result.exitCode ?? null,
|
|
288
|
+
signal: result.signal,
|
|
289
|
+
durationMs,
|
|
290
|
+
},
|
|
291
|
+
"Codex CLI exited",
|
|
292
|
+
);
|
|
293
|
+
} catch (execError: unknown) {
|
|
294
|
+
const durationMs = Date.now() - runStartedAt;
|
|
295
|
+
const exitCode =
|
|
296
|
+
(execError as { exitCode?: number | null })?.exitCode ?? null;
|
|
297
|
+
const signal =
|
|
298
|
+
(execError as { signal?: string | null })?.signal ?? null;
|
|
299
|
+
logger.error({ exitCode, signal, durationMs }, "Codex CLI failed");
|
|
300
|
+
throw execError;
|
|
301
|
+
}
|
|
245
302
|
};
|
|
246
303
|
|
|
247
304
|
// Determine execution strategy based on version selection
|
|
248
305
|
// FR-063b: "installed" option only appears when local command exists
|
|
249
|
-
const requestedVersion = options.version ?? "latest";
|
|
250
306
|
let selectedVersion = requestedVersion;
|
|
251
307
|
|
|
252
308
|
if (requestedVersion === "installed" && !codexLookup.path) {
|
package/src/index.ts
CHANGED
|
@@ -239,6 +239,8 @@ async function mainSolidUI(): Promise<SelectionResult | undefined> {
|
|
|
239
239
|
useAlternateScreen,
|
|
240
240
|
useMouse,
|
|
241
241
|
enableMouseMovement,
|
|
242
|
+
useConsole: false,
|
|
243
|
+
openConsoleOnError: false,
|
|
242
244
|
},
|
|
243
245
|
);
|
|
244
246
|
} finally {
|
|
@@ -727,6 +729,9 @@ export async function handleAIToolWorkflow(
|
|
|
727
729
|
cwd: worktreePath,
|
|
728
730
|
sharedEnv,
|
|
729
731
|
};
|
|
732
|
+
if (tool === "opencode" && normalizedModel) {
|
|
733
|
+
customLaunchOptions.extraArgs = ["-m", normalizedModel];
|
|
734
|
+
}
|
|
730
735
|
if (toolVersion) {
|
|
731
736
|
customLaunchOptions.version = toolVersion;
|
|
732
737
|
}
|
package/src/logging/reader.ts
CHANGED
|
@@ -14,6 +14,7 @@ export type LogTargetReason =
|
|
|
14
14
|
| "worktree-inaccessible"
|
|
15
15
|
| "current-working-directory"
|
|
16
16
|
| "working-directory"
|
|
17
|
+
| "working-directory-fallback"
|
|
17
18
|
| "no-worktree";
|
|
18
19
|
|
|
19
20
|
export interface LogTargetBranch {
|
|
@@ -115,7 +116,7 @@ export async function listLogFiles(logDir: string): Promise<LogFileInfo[]> {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
return files.sort((a, b) => b.
|
|
119
|
+
return files.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
119
120
|
} catch (error) {
|
|
120
121
|
const err = error as NodeJS.ErrnoException;
|
|
121
122
|
if (err.code === "ENOENT") {
|
|
@@ -125,6 +126,52 @@ export async function listLogFiles(logDir: string): Promise<LogFileInfo[]> {
|
|
|
125
126
|
}
|
|
126
127
|
}
|
|
127
128
|
|
|
129
|
+
const getLatestLogMtimeWithContent = async (
|
|
130
|
+
logDir: string,
|
|
131
|
+
): Promise<number | null> => {
|
|
132
|
+
const files = await listLogFiles(logDir);
|
|
133
|
+
for (const file of files) {
|
|
134
|
+
const lines = await readLogFileLines(file.path);
|
|
135
|
+
if (lines.length > 0) {
|
|
136
|
+
return file.mtimeMs;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return null;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
export async function selectLogTargetByRecency(
|
|
143
|
+
primary: LogTargetResolution,
|
|
144
|
+
fallback: LogTargetResolution,
|
|
145
|
+
): Promise<LogTargetResolution> {
|
|
146
|
+
if (!primary.logDir || !primary.sourcePath) {
|
|
147
|
+
return primary;
|
|
148
|
+
}
|
|
149
|
+
if (!fallback.logDir || !fallback.sourcePath) {
|
|
150
|
+
return primary;
|
|
151
|
+
}
|
|
152
|
+
if (primary.logDir === fallback.logDir) {
|
|
153
|
+
return primary;
|
|
154
|
+
}
|
|
155
|
+
if (primary.reason !== "worktree") {
|
|
156
|
+
return primary;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const [primaryMtime, fallbackMtime] = await Promise.all([
|
|
160
|
+
getLatestLogMtimeWithContent(primary.logDir),
|
|
161
|
+
getLatestLogMtimeWithContent(fallback.logDir),
|
|
162
|
+
]);
|
|
163
|
+
|
|
164
|
+
if (
|
|
165
|
+
fallbackMtime !== null &&
|
|
166
|
+
(primaryMtime === null || fallbackMtime > primaryMtime)
|
|
167
|
+
) {
|
|
168
|
+
return {
|
|
169
|
+
...fallback,
|
|
170
|
+
reason: "working-directory-fallback",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
return primary;
|
|
174
|
+
}
|
|
128
175
|
export async function clearLogFiles(logDir: string): Promise<number> {
|
|
129
176
|
const files = await listLogFiles(logDir);
|
|
130
177
|
let cleared = 0;
|
|
@@ -5,10 +5,13 @@ import { CLAUDE_CODE_TOOL } from "../config/builtin-coding-agents.js";
|
|
|
5
5
|
import {
|
|
6
6
|
CODEX_DEFAULT_ARGS,
|
|
7
7
|
CLAUDE_PERMISSION_SKIP_ARGS,
|
|
8
|
+
shouldEnableCodexSkillsFlag,
|
|
9
|
+
withCodexSkillsFlag,
|
|
8
10
|
} from "../shared/codingAgentConstants.js";
|
|
9
11
|
import { prepareCodingAgentExecution } from "./codingAgentCommandResolver.js";
|
|
10
12
|
import type { CodingAgentLaunchOptions } from "../types/tools.js";
|
|
11
13
|
import { createLogger } from "../logging/logger.js";
|
|
14
|
+
import { findCommand } from "../utils/command.js";
|
|
12
15
|
|
|
13
16
|
const logger = createLogger({ category: "resolver" });
|
|
14
17
|
|
|
@@ -267,17 +270,21 @@ export function buildCodexArgs(options: CodexCommandOptions = {}): string[] {
|
|
|
267
270
|
export async function resolveCodexCommand(
|
|
268
271
|
options: CodexCommandOptions = {},
|
|
269
272
|
): Promise<ResolvedCommand> {
|
|
270
|
-
const
|
|
273
|
+
const codexLookup = await findCommand("codex");
|
|
274
|
+
const baseArgs = buildCodexArgs(options);
|
|
275
|
+
const args = withCodexSkillsFlag(
|
|
276
|
+
baseArgs,
|
|
277
|
+
shouldEnableCodexSkillsFlag(codexLookup.version),
|
|
278
|
+
);
|
|
271
279
|
|
|
272
280
|
// フルパスを取得(node-ptyはシェルを経由しないため必要)
|
|
273
|
-
|
|
274
|
-
if (codexPath) {
|
|
281
|
+
if (codexLookup.source === "installed" && codexLookup.path) {
|
|
275
282
|
logger.info(
|
|
276
|
-
{ command:
|
|
283
|
+
{ command: codexLookup.path, usesFallback: false },
|
|
277
284
|
"Codex command resolved",
|
|
278
285
|
);
|
|
279
286
|
return {
|
|
280
|
-
command:
|
|
287
|
+
command: codexLookup.path,
|
|
281
288
|
args,
|
|
282
289
|
usesFallback: false,
|
|
283
290
|
};
|
|
@@ -28,3 +28,76 @@ export const CODEX_DEFAULT_ARGS = [
|
|
|
28
28
|
"-c",
|
|
29
29
|
"shell_environment_policy.experimental_use_profile=true",
|
|
30
30
|
] as const;
|
|
31
|
+
|
|
32
|
+
export const CODEX_SKILLS_FLAG_DEPRECATED_FROM = "0.80.0";
|
|
33
|
+
|
|
34
|
+
type ParsedVersion = {
|
|
35
|
+
major: number;
|
|
36
|
+
minor: number;
|
|
37
|
+
patch: number;
|
|
38
|
+
prerelease: string | null;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const MODEL_FLAG_PREFIX = "--model=";
|
|
42
|
+
|
|
43
|
+
function normalizeVersion(value?: string | null): string | null {
|
|
44
|
+
if (!value) return null;
|
|
45
|
+
const trimmed = value.trim();
|
|
46
|
+
if (!trimmed) return null;
|
|
47
|
+
return trimmed.replace(/^v/i, "");
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function parseVersion(value?: string | null): ParsedVersion | null {
|
|
51
|
+
const normalized = normalizeVersion(value);
|
|
52
|
+
if (!normalized) return null;
|
|
53
|
+
const match = normalized.match(
|
|
54
|
+
/^(\d+)\.(\d+)(?:\.(\d+))?(?:-([0-9A-Za-z.-]+))?$/,
|
|
55
|
+
);
|
|
56
|
+
if (!match) return null;
|
|
57
|
+
const major = Number(match[1]);
|
|
58
|
+
const minor = Number(match[2]);
|
|
59
|
+
const patch = Number(match[3] ?? "0");
|
|
60
|
+
if (![major, minor, patch].every(Number.isFinite)) return null;
|
|
61
|
+
return {
|
|
62
|
+
major,
|
|
63
|
+
minor,
|
|
64
|
+
patch,
|
|
65
|
+
prerelease: match[4] ?? null,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function compareVersions(a: ParsedVersion, b: ParsedVersion): number {
|
|
70
|
+
if (a.major !== b.major) return a.major - b.major;
|
|
71
|
+
if (a.minor !== b.minor) return a.minor - b.minor;
|
|
72
|
+
if (a.patch !== b.patch) return a.patch - b.patch;
|
|
73
|
+
if (a.prerelease && !b.prerelease) return -1;
|
|
74
|
+
if (!a.prerelease && b.prerelease) return 1;
|
|
75
|
+
if (a.prerelease && b.prerelease) {
|
|
76
|
+
return a.prerelease.localeCompare(b.prerelease);
|
|
77
|
+
}
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function shouldEnableCodexSkillsFlag(version?: string | null): boolean {
|
|
82
|
+
const parsed = parseVersion(version);
|
|
83
|
+
if (!parsed) return false;
|
|
84
|
+
const threshold = parseVersion(CODEX_SKILLS_FLAG_DEPRECATED_FROM);
|
|
85
|
+
if (!threshold) return false;
|
|
86
|
+
return compareVersions(parsed, threshold) < 0;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function withCodexSkillsFlag(
|
|
90
|
+
args: readonly string[],
|
|
91
|
+
enable: boolean,
|
|
92
|
+
): string[] {
|
|
93
|
+
if (!enable) return Array.from(args);
|
|
94
|
+
const alreadyEnabled = args.some(
|
|
95
|
+
(arg, index) => arg === "--enable" && args[index + 1] === "skills",
|
|
96
|
+
);
|
|
97
|
+
if (alreadyEnabled) return Array.from(args);
|
|
98
|
+
const next = Array.from(args);
|
|
99
|
+
const modelIndex = next.findIndex((arg) => arg.startsWith(MODEL_FLAG_PREFIX));
|
|
100
|
+
const insertIndex = modelIndex === -1 ? next.length : modelIndex;
|
|
101
|
+
next.splice(insertIndex, 0, "--enable", "skills");
|
|
102
|
+
return next;
|
|
103
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface BunReexecInput {
|
|
2
|
+
hasBunGlobal: boolean;
|
|
3
|
+
bunExecPath?: string | null;
|
|
4
|
+
argv: string[];
|
|
5
|
+
scriptPath: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface BunReexecCommand {
|
|
9
|
+
command: string;
|
|
10
|
+
args: string[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function buildBunReexecCommand(
|
|
14
|
+
input: BunReexecInput,
|
|
15
|
+
): BunReexecCommand | null {
|
|
16
|
+
if (input.hasBunGlobal) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const scriptPath = input.scriptPath?.trim();
|
|
21
|
+
if (!scriptPath) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const bunCommand = input.bunExecPath?.trim() || "bun";
|
|
26
|
+
const args = [scriptPath, ...(input.argv?.slice(2) ?? [])];
|
|
27
|
+
|
|
28
|
+
return { command: bunCommand, args };
|
|
29
|
+
}
|