2025-10-28 13:53:34 +00:00
|
|
|
## Cross-Runtime Compatibility
|
|
|
|
|
|
|
|
|
|
### CLI Argument Parsing
|
|
|
|
|
The module uses a robust cross-runtime approach for parsing command-line arguments:
|
|
|
|
|
|
|
|
|
|
**Key Implementation:**
|
|
|
|
|
- `getUserArgs()` utility (in `ts/smartcli.helpers.ts`) handles process.argv differences across Node.js, Deno, and Bun
|
|
|
|
|
- Uses `process.execPath` basename detection instead of content-based heuristics
|
|
|
|
|
- Prefers `Deno.args` when available (for Deno run/compiled), unless argv is explicitly provided
|
|
|
|
|
|
|
|
|
|
**Runtime Differences:**
|
|
|
|
|
- **Node.js**: `process.argv = ["/path/to/node", "/path/to/script.js", ...userArgs]`
|
|
|
|
|
- **Deno (run)**: `process.argv = ["deno", "/path/to/script.ts", ...userArgs]` (but `Deno.args` is preferred)
|
|
|
|
|
- **Deno (compiled)**: `process.argv = ["/path/to/executable", ...userArgs]` (custom executable name)
|
|
|
|
|
- **Bun**: `process.argv = ["/path/to/bun", "/path/to/script.ts", ...userArgs]`
|
|
|
|
|
|
|
|
|
|
**How it works:**
|
|
|
|
|
1. If `Deno.args` exists and no custom argv provided, use it directly
|
|
|
|
|
2. Otherwise, detect runtime by checking `process.execPath` basename
|
|
|
|
|
3. If basename is a known launcher (node, deno, bun, tsx, ts-node), skip 2 args
|
|
|
|
|
4. If basename is unknown (compiled executable), skip only 1 arg
|
|
|
|
|
5. Safety check: if offset would skip everything, don't skip anything (handles test edge cases)
|
|
|
|
|
|
|
|
|
|
This approach works correctly with:
|
|
|
|
|
- Standard runtime execution
|
|
|
|
|
- Compiled executables (Deno compile, Node pkg, etc.)
|
|
|
|
|
- Custom-named executables
|
|
|
|
|
- Test environments with unusual argv setups
|