Repository: denoland/deno
Pull request: fix(compile): use execPath for process.argv[1] in standalone binaries

## Summary

In compiled (standalone) binaries, `process.argv[1]` was set to the internal
temp extraction path (e.g. `/tmp/deno-compile-foo/path/to/main.ts`) instead of
the binary path. This caused npm CLI tools like `@google/gemini-cli` to see the
temp path as a positional argument, breaking their argument parsing.

For example, running `gemini -p "hello"` would fail with:
```
Cannot use both a positional prompt and the --prompt (-p) flag together
```
because the temp path leaked into `process.argv` and was parsed as a positional arg
by yargs.

## Fix

For standalone binaries (`Deno.build.standalone`), `process.argv[1]` now uses
`Deno.execPath()` (the compiled binary path), matching Node.js SEA behavior
where `argv[0]` and `argv[1]` both point to the executable.

Related: #28915 (fixes `argv[0]`, this PR fixes `argv[1]`)

## Test plan
- [x] New spec test `compile::standalone_process_argv` verifies `argv[1] === Deno.execPath()` and user args start at `argv[2]`
- [x] Manual verification with compiled `@google/gemini-cli`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Changed files:
filename: ext/node/polyfills/process.ts
patch: @@ -1332,7 +1332,9 @@ internals.__bootstrapNodeProcess = function (
   if (!warmup) {
     argv0 = argv0Val || "";
     argv[0] = argv0;
-    argv[1] = Deno.mainModule?.startsWith("file:")
+    argv[1] = Deno.build.standalone
+      ? Deno.execPath()
+      : Deno.mainModule?.startsWith("file:")
       ? pathFromURL(new URL(Deno.mainModule))
       : join(Deno.cwd(), "$deno$node.mjs");
     // Manually concatenate these arrays to avoid triggering the getter

filename: tests/specs/compile/standalone_process_argv/__test__.jsonc
patch: @@ -0,0 +1,31 @@
+{
+  "tempDir": true,
+  "tests": {
+    "argv_no_temp_path": {
+      "steps": [
+        {
+          "if": "unix",
+          "args": "compile -A --output main main.ts",
+          "output": "[WILDCARD]"
+        },
+        {
+          "if": "unix",
+          "commandName": "./main",
+          "args": ["--foo", "bar"],
+          "output": "main.out"
+        },
+        {
+          "if": "windows",
+          "args": "compile -A --output main.exe main.ts",
+          "output": "[WILDCARD]"
+        },
+        {
+          "if": "windows",
+          "commandName": "./main.exe",
+          "args": ["--foo", "bar"],
+          "output": "main.out"
+        }
+      ]
+    }
+  }
+}

filename: tests/specs/compile/standalone_process_argv/main.out
patch: @@ -0,0 +1,2 @@
+argv1_ok
+user_args: ["--foo","bar"]

filename: tests/specs/compile/standalone_process_argv/main.ts
patch: @@ -0,0 +1,20 @@
+import process from "node:process";
+
+// In a compiled binary, process.argv[1] should be the binary path
+// (same as Deno.execPath()), not an internal temp extraction path
+// like "deno-compile-<name>/path/to/module.ts".
+const argv1 = process.argv[1];
+const execPath = Deno.execPath();
+
+// argv[1] should equal the binary path
+if (argv1 !== execPath) {
+  console.error(
+    `FAIL: process.argv[1] (${argv1}) !== Deno.execPath() (${execPath})`,
+  );
+  process.exit(1);
+}
+
+// User args should start at argv[2]
+const userArgs = process.argv.slice(2);
+console.log(`argv1_ok`);
+console.log(`user_args: ${JSON.stringify(userArgs)}`);

filename: tools/lint_plugins/no_deno_api_in_polyfills.ts
patch: @@ -14,7 +14,7 @@
 // Paths are relative to the repo root.
 export const EXPECTED_VIOLATIONS: Record<string, number> = {
   "ext/node/polyfills/fs.ts": 54,
-  "ext/node/polyfills/process.ts": 28,
+  "ext/node/polyfills/process.ts": 30,
   "ext/node/polyfills/os.ts": 22,
   "ext/node/polyfills/internal/child_process.ts": 21,
   "ext/node/polyfills/internal/fs/utils.mjs": 10,