9 Commits
Author SHA1 Message Date
787f2a9390 refactor(cli): commander-authoritative argv handling for SSH / cc:// and remote bypass (recovery of #1939) (#2098)
* fix(cli): mirror programmatic args onto process.argv (hardened)

Address CodeRabbit's Critical finding: cliMain() parses process.argv
directly, so a programmatic main(args) call must reflect args there or
it silently runs the host's argv.

Restores the args->argv sync but hardened against the three bugs the
multi-agent review confirmed in the earlier scoped/serialized version:
- no restore (was F3: a finally-restore flipped argv out from under the
  SIGINT handler and bypass-safety notice while the session was live)
- length-guarded exec/script slots (was F4: <2 host argv entries, e.g.
  node -e, dropped the flag past commander's argv.slice(2))
- no serialization chain (was F2: overlapping calls hung indefinitely)

For the normal binary launch (args defaulted from process.argv.slice(2))
the assignment is a value-identical no-op. Tests: programmatic args
reach cliMain, argv is not restored, and the exec/script slots are
padded under a short host argv.

Verified: 48 entrypoint+safety tests, tsc, build, and e2e re-probes of
all former --yolo bug scenarios on the built binary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(cli): ssh strip-all dangerous-skip tokens; docs+tests for native alias

Address the latest Copilot + CodeRabbit findings on the native-alias PR:

- ssh argv pre-scan removed only the first dangerous-skip token, so
  `ssh --yolo --dangerously-skip-permissions host` (or a repeat) left a
  survivor that re-enabled bypass after the ssh rewrite. Strip every
  matching token. (connect already used the filter helper.) [Copilot]
- web/src/data/cliFlags.ts: list the flag as
  '--yolo, --dangerously-skip-permissions' to match the commander
  registration, not just the description. [Copilot]
- Replace the source-string-count registration test with (a) a
  behavioral test that the built CLI lists the alias in --help — proving
  the main-command registration is live, not dead code or the wrong
  command — and (b) a structured .option() assertion plus a check that
  the ssh pre-scan handles the alias (ssh --help renders root help, so
  the ssh --yolo path is the pre-scan, not the commander option).
  [CodeRabbit]
- PR description rewritten to describe the native alias instead of the
  removed argv rewrite. [Copilot]

Verified: 23 cli + 10 safety tests, tsc, build, e2e (--yolo --help lists
the alias; ssh --help; mcp add --yolo names the typed flag).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(cli): runtime coverage for dangerous-skip strip; share one helper

CodeRabbit (approved, follow-up): the strip-all fix was only source-
checked, so the strip loop could regress unnoticed. Extract the argv
scanners into src/utils/dangerousSkipFlags.ts (isDangerousSkipFlag /
hasDangerousSkipFlag / stripDangerousSkipFlags) and unit-test them at
runtime: both spellings detected, every token stripped (canonical +
--yolo + repeats), input not mutated.

Both the direct-connect and ssh rewrites in main.tsx now use the shared
stripDangerousSkipFlags — the ssh path's bespoke single-splice while
loop (the original survivor bug) is gone, replaced by an in-place
splice(0, len, ...strip). One tested code path instead of two.

Verified: helper + 23 cli + 10 safety tests, tsc, build, e2e.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style(cli): semicolon + strip both spellings in safety-test reset

Copilot review nits:
- statusNoticeDefinitions.tsx: add the trailing semicolon to the
  parenthesized return to match the file's semicolon style.
- safety.test.tsx: the beforeEach argv reset filtered only
  --dangerously-skip-permissions; strip --yolo too so the 'without the
  flag' cases can't go order-dependent if the runner is invoked with
  --yolo in argv.
- PR description re-synced to the native-alias approach (the earlier
  edit had reverted to the old 'normalize via argv rewrite' wording).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(cli): notice names --yolo; move import out of boot-critical block

Both bots on 50772d28:
- The bypass-safety notice fires for --yolo but its text named only
  '--dangerously-skip-permissions is active'. Reword to '... (alias
  --yolo) is active' so the message matches what the user typed. Add a
  rendered-notice regression assertion for the --yolo case. [CodeRabbit + Copilot]
- Move the dangerousSkipFlags import out of the boot-critical header
  block (it ran before profileCheckpoint('main_tsx_entry'), adding
  pre-checkpoint work in the order-preserving bundle) down to the
  regular internal-import group. [Copilot]

Verified: 39 cli+safety+helper tests, tsc, build, e2e.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(cli): honor -- end-of-options in the raw-argv dangerous-skip scanners

Copilot (3x on 5cd0e304): the pre-commander scanners matched --yolo /
--dangerously-skip-permissions anywhere in argv, so a positional after
the -- marker (openclaude -p -- --yolo, cc://… -- --yolo, ssh host --
--yolo) was misread as the bypass flag — enabling bypass / stripping the
token / false-firing the safety notice, even though commander treats it
as positional. Pre-existing for the canonical flag, but the short alias
makes it far likelier.

Make the shared helpers --aware in one place: hasDangerousSkipFlag and
stripDangerousSkipFlags only consider option-position tokens (before the
first --) and preserve everything from -- onward. Route the safety
notice's hasDangerouslySkipPermissionsArg through the same helper.

Regression tests: helper ignores/preserves post-- tokens; the notice
does not fire for -p -- --yolo.

Verified: 41 helper+safety+cli tests, tsc, build, e2e.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(cli): don't leak args via process.argv; stop simulating commander in the scanner

Address jatmn's two P1 findings, both by removing a band-aid rather than
adding another:

- P1a: main() no longer mirrors its args onto the process-global
  process.argv. Verified there is no production or SDK caller that passes
  custom args (the sole entry is the no-arg auto-run), so the mirror only
  risked leaking a programmatic invocation's args (including a bypass
  flag) into an overlapping call or the host process. Back to the baseline
  signature; cliMain parses the real process.argv.

- P1b: revert the end-of-options ("--") handling in the dangerous-skip
  scanner. As jatmn notes, correctly classifying "--yolo" (it can be a
  required option value like "--system-prompt --yolo", or follow a "--"
  consumed as a variadic value) requires commander's option-arity state
  machine, the exact simulation this feature was reworked to delete. The
  scanner now mirrors the canonical --dangerously-skip-permissions
  presence check exactly: both spellings behave identically, and the
  approximation is documented as a pre-existing limitation of
  pre-commander scanning.

Net: every difference between --yolo and the canonical flag is now either
native-commander-correct (the registration) or an identical approximation
(the raw scanners). No new argv mutation, no parser simulation.

Verified: 38 cli+helper+safety tests, tsc, build, e2e.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(cli): clarify main() argv comment — skills/--update do rewrite argv

Copilot: the "does not mirror args onto process.argv" comment was
misleading — the skills and --update fast-paths reassign process.argv to
re-route to their subcommand. Note the exception; the no-mirror rule is
about not injecting the caller's args into the general cliMain flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(setup): name the --yolo alias in the root/sudo bypass error

Copilot: the root/sudo safety error printed only
--dangerously-skip-permissions; a user who typed --yolo saw a flag they
didn't use. Mention both spellings, matching the ssh help and cliFlags.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(cli): import Command from @commander-js/extra-typings, matching prod

Copilot: the alias behavioral test built its probe Command from
'commander', but production registers options via
@commander-js/extra-typings. Use the same package so the test exercises
the exact parser prod uses.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ssh): don't treat an option value as the permission-bypass alias

jatmn P1: `ssh host --permission-mode --yolo` stripped --yolo as a bypass
flag (enabling bypass) and left --permission-mode valueless, whereas
commander parses --yolo as the (invalid) mode value and rejects it — a
silent privilege escalation. Same class affected --model / --resume /
--fallback-model.

Reorder the ssh pre-parser so value-taking flags consume their value —
including a dangerous-skip token in the value slot — BEFORE the
dangerous-skip strip runs. Extract the whole flag pre-parse into a pure,
unit-tested helper (parseSshFlags) so the security-sensitive arity
handling has regression coverage: escalation guards for
--permission-mode/--model + a value of --yolo, plus genuine standalone
--yolo still enabling bypass.

Verified: 6 ssh + dangerousSkipFlags + cli tests, tsc, build, e2e.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(cli): update ssh-path source assertion for parseSshFlags extraction

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(cli): revert unrelated --bare doc; drop stray blank line

CodeRabbit/Copilot on the rebased branch:
- Revert the --bare help rewrite (background prefetches / CLAUDE_CODE_SIMPLE
  / expanded flag list) in main.tsx and web/src/data/cliFlags.ts — it is
  unrelated to the --yolo alias and broadens scope. cliFlags.ts now changes
  only the --yolo alias line.
- Remove the stray double blank line before cliMain.

Skipped CodeRabbit's "alias order breaks property naming" (Major): verified
against @commander-js/extra-typings that '--yolo, --dangerously-skip-
permissions' maps BOTH spellings to opts().dangerouslySkipPermissions
(commander keys off the last long flag); opts().yolo is undefined. Bypass
is not broken.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ssh): honor the -- end-of-options marker in the ssh pre-parser

CodeRabbit Critical + jatmn P1 ("respect option arity/end-of-options
semantics"): `ssh host -- --yolo` (or `-- --local`, `-- --permission-mode
x`) parsed the post-`--` tokens as flags, so a positional --yolo escalated
to bypass. parseSshFlags now parses only the prefix before `--` and keeps
everything from `--` on positional. This is unambiguous here because the
ssh subcommand registers no variadic options that could consume `--` as a
value.

The connect (cc://) path is deliberately left plain and documented: it
rewrites to the main command, which HAS variadic options (--add-dir …)
that commander lets consume `--` as a value, so a naive `--` split there
would be the incomplete simulation flagged in P1b. That false-positive is
pre-existing for the canonical flag.

Skipped (both pre-existing, ported verbatim / out of scope): extractFlag
mixed `--flag=x --flag y` precedence, and the setup.ts root/sudo message
not naming --allow-dangerously-skip-permissions.

Verified: 8 ssh + cli tests, tsc, build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor: make --yolo/bypass Commander-authoritative on cc:// connect + notice

* fixup! address CodeRabbit/Copilot review findings on #2098

- Restore parseMaxTurnsCommanderArgument for --max-turns validation.
- Generalize root/sudo error message for all bypass modes/flags.
- Clarify cli.tsx comment about main() not leaking args into process.argv.
- Detect -p/--print in all commander-accepted forms (including --print= and -p<value>).
- Correct dangerousSkipFlags.ts doc: SSH strips, cc:// preserves for Commander.
- Extend live help test to ssh and open subcommands.

* fixup! extract hasPrintFlag helper + regression tests

- Move print-flag detection to src/utils/printFlag.ts so it is unit-testable.
- Add regression tests for -p, --print, --print=prompt, -pprompt, and -- separator.
- Import the helper in main.tsx and drop the local copy.

* fixup! use hasPrintFlag in every startup print-mode check

- Replace exact-string includes in the SSH headless rejection and the main
  print-mode gate with the shared hasPrintFlag predicate.
- Add source assertions confirming cc:// rewrite, SSH rejection, and main
  print-mode gate all use the same helper.

* fixup! align dangerously-skip notice comment with commander-authoritative mode

- Remove stale 'reads from process.argv' text; the notice now keys off the
  resolved permissionMode.

* fixup! add SIGINT handler to hasPrintFlag source assertions

- Include the SIGINT print-mode gate in the source-level consistency check.

* fixup! restore maxTurns forwarding dropped during rebase

- Re-add options.maxTurns to sessionConfig and the interactive REPL props for
  direct-connect, SSH, remote viewer, and remote creation paths (matches main).

* fixup! address Copilot suppressed comments on #2098

- parseSshFlags now consumes required-arg values unconditionally, matching
  commander and preventing flag-like values from leaking into later guards.
- Drop the now-unused isDangerousSkipFlag import from sshPreParse.ts.
- Make the dangerously-skip notice text mode-agnostic so settings-driven
  bypassPermissions is not mislabeled as a CLI flag.

* fixup: left-to-right SSH parse and fullAccess sandbox warning

- Rewrite parseSshFlags as a single left-to-right arity-aware scan.
  Value-taking flags now consume every occurrence (including equals forms)
  and always consume the next token as their value, even if it resembles a
  flag (e.g. --permission-mode --local or --model --yolo value).
- Cover fullAccess with the dangerously-skip-permissions sandbox warning and
  add focused regression tests for bypassPermissions/fullAccess rendering.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fixup: preserve missing SSH option values and embedded equals

- Keep value-taking SSH flags in remaining when they have no available value
  (last token before -- or trailing), letting commander report the missing
  required argument.
- Use slice after the prefix for equals-form values so embedded '=' characters
  are preserved (e.g. --model=provider=model).
- Add regression tests for last-token, before--, and embedded-equals cases.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fixup: arity-aware print detection and optional --resume for SSH

- hasPrintFlag now skips tokens consumed as values by preceding value-taking
  options (required, optional, and variadic), so --system-prompt --print=custom
  is no longer misclassified as print mode.
- parseSshFlags treats --resume as an optional-value option: a bare --resume is
  forwarded, a non-option value is consumed, and following flags (e.g. --yolo)
  remain available for their own parsing.
- Added focused regression tests for both fixes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fixup: handle inline values and -- in hasPrintFlag

- Do not advance past a following flag when a required/optional/variadic option
  already provided its value inline via =.
- Stop the scan when a value-taking option is immediately followed by --.
- Added regression tests for --model=foo --print and --model -- --print.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fixup! address jatmn review: arity-aware print/SSH parsing + fullAccess notice

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fixup! correct bypassPermissions notice wording

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Address remaining CodeRabbit findings on #2098

- Sync hasPrintFlag with all root-command required/variadic/optional options, including hidden/feature-gated flags (--agent-id, --sdk-url, --channels, etc.).

- Treat the SDK 'full-access' spelling as fullAccess in the dangerous-skip-permissions status notice so the stronger warning is shown.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(cli): make hasPrintFlag the single pre-Commander print classifier

- Replace all startup .includes('-p')/.includes('--print') checks with the
  arity-aware hasPrintFlag() predicate so value-consumed tokens are not
  misclassified as print mode.
- Centralize SSH headless detection in sshArgvImpliesHeadless(), covering both
  tail argv after host/cwd and flags forwarded via extraCliArgs (e.g.
  --resume=--print).
- Soften the fullAccess status-notice wording to match runtime behavior: most
  consent checks are bypassed, but hard deny rules and user-interaction prompts
  still apply.
- Add/extend tests for interactivity, SSH flag pre-parsing, status notices, and
  a regression check that prevents naive print-token checks from re-entering.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(ssh): preserve --resume= values and run headless guard before host extraction

- Keep the inline value attached when forwarding --resume=... extraCliArgs so
  optional-value semantics are preserved (e.g. --resume=--print resumes a
  conversation named "--print", it does not enable print mode).
- Move the SSH headless guard before host/cwd extraction in main.tsx so print
  flags that appear before the host are rejected.
- Update tests: --resume=--print is no longer headless, required-value options
  like --model -p remain non-headless, and add coverage for print flags before
  the host.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* fix(cli): remove repeatable single-value options from VARIADIC_OPTIONS

--plugin-dir and --provider-env-file are registered as repeatable
single-value options, not variadic. Keeping them in VARIADIC_OPTIONS made the
arity model wrong and could consume extra tokens if check order changed. They
are already covered by REQUIRED_VALUE_OPTIONS.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-19 13:52:52 +08:00
BogdanandGitHub 108a413493 fix(bg): preserve detached session terminal outcomes (#2133)
* fix(bg): preserve detached session terminal outcomes

* fix(bg): harden terminal outcome routing
2026-08-16 15:56:55 +08:00
மனோஜ்குமார் பழனிச்சாமிandGitHub 95eeb0bde3 feat(cli): add --yolo alias for --dangerously-skip-permissions (#2097)
Register the alias on the main command and the ssh stub. Recognize it in
the cc:// and ssh raw-argv scans, and in both skills pre-parse boolean sets
(leading and trailing), so  and
 route correctly. Update the web flags docs.

Includes source-scan + help-text tests proving the alias is wired through.
The SSH/argv refactor remains on the existing feat/yolo-flag branch for a
separate follow-up PR.
2026-08-07 09:47:47 +08:00
3kin0xandGitHub f292b057b5 fix: await main() in cli entrypoint to prevent premature exit in Node 24.x (#1697) 2026-07-07 11:05:50 +08:00
BogdanandGitHub 5af6f95c46 feat(config): add explicit provider env-file loading (#1668)
* feat(config): add explicit provider env-file loading

* fix(config): handle escaped quotes in provider env files

* fix(config): polish env-file parser review feedback

* fix(config): preserve provider env-file precedence

* test(config): cover provider env-file precedence

* fix(config): preserve provider env-file values

* fix(config): allow documented env-file setup vars

* fix(config): preserve provider flag precedence
2026-06-18 08:51:59 +08:00
BogdanandGitHub a1b3346f65 feat(cli): add local background sessions (#1642)
* feat(cli): add local background sessions

Add local detached background sessions backed by an OpenClaude-owned registry under the resolved config directory.

- implement --bg spawning plus ps, logs, logs -f, kill, and an explicit attach limitation
- harden registry metadata validation, atomic writes, ID/name collision handling, and terminal-name reuse
- precreate child log files with precise ownership cleanup and register metadata only after spawn succeeds
- verify live PIDs against the session command before treating registry entries as running
- wait for process-tree termination and escalate to SIGKILL before marking sessions killed
- skip live local background sessions during --continue transcript selection
- preserve Node heap flags for detached children while avoiding stale launcher relaunch state
- handle -- separators so dash-prefixed prompts remain positional
- document storage, safety model, name reuse, and the current attach limitation

Validation:
- bun test
- bun run typecheck
- bun run smoke
- isolated built-CLI --bg/ps/logs/kill smoke
- CodeRabbit review findings addressed

* test(utils): prevent bg registry mock leakage

Restore complete bg registry and UDS module mocks after conversation recovery tests so Bun's process-global mock.module registry cannot leak partial module exports into later CLI tests.

CI exposed this under Bun 1.3.13 when conversationRecovery.test ran before the bgRegistry and bg CLI test files.

* test(utils): exercise bg registry without global mock

Replace the conversation recovery bgRegistry module mock with real registry metadata backed by a short-lived live child process. This keeps UDS as the only mocked boundary and avoids leaking a mocked registry module into later CLI registry tests under Bun 1.3.13.

* test(utils): isolate background registry state

Stop the conversation recovery test from using process-wide bgRegistry mocks or real child processes by injecting the live-session dependencies directly.

Pin and serialize the bg registry test config directory through the shared env mutation lock so path/cache state cannot leak from neighboring tests under Bun CI ordering.

* test(utils): document Bun mock restoration

Explain why conversation recovery tests re-register full module exports after mock.restore(), matching the CodeRabbit-requested Bun 1.3.13 isolation workaround.

* test(cli): isolate background registry root

Avoid relying on process-wide CLAUDE_CONFIG_DIR state in bgRegistry tests. Use a registry-local test root override so CI file ordering and mocked path modules cannot redirect background session metadata into another test's temp directory.

* test(utils): cover live session fallback paths

Add focused coverage for collectLiveBackgroundSessionIds when UDS discovery fails but registry data remains available, and when registry refresh fails but UDS data remains available.

* fix(cli): harden background session management

Validate persisted and newly-created background session PIDs before exposing them to management commands.

Reserve named live sessions with an atomic registry write, release reservations when sessions become terminal, and cover concurrent duplicate-name attempts.

Split local session management dispatch from background spawning so ps/logs/attach/kill avoid provider startup while --bg still inherits profile routing.

* fix(cli): address background session review findings

Preserve positional prompts when --bg is combined with optional-value flags such as --debug.

Recover stale name reservations whose owner metadata is missing or terminal while preserving in-flight reservations from live creators.

Cover both reviewer findings with focused parser and registry regression tests.

* fix(cli): respect delimiter for background flags

Limit background and print-mode flag detection to arguments before the -- delimiter so flag-shaped prompts remain positional.

Keep optional resume/from-pr flags out of the required-value table and add regressions for delimiter and optional-flag prompt handling.

* refactor(cli): share delimiter argument helper

Move args-before-delimiter handling into the existing dependency-free CLI args utility.

Use a dynamic import from the entrypoint so background flag routing shares the helper without adding top-level module load to version and management fast paths.

* test(cli): cover background entrypoint routing

Export the CLI entrypoint for controlled tests and add isolated importer injection so runtime routing tests do not leak global module mocks.

Replace the delimiter source-layout assertion with execution-level coverage for management commands, real background flags, and flag-shaped prompt text after --.

* fix(cli): preserve background resume selectors

Keep space-separated --resume, -r, and --from-pr values attached when building background child args.

Mark live background sessions stale when PID command identity cannot be read, avoiding termination of reused unrelated PIDs.

* fix(cli): track unknown background session identity

Represent unreadable live PID identity as a non-terminal unknown state so active sessions stay excluded from resume selection.

Refuse to terminate unknown live PIDs because the process command cannot be positively matched to the background session.

* fix(cli): honor background resume selectors

Avoid adding a generated --session-id to non-forked background resume launches so the spawned print-mode child satisfies the existing resume/session-id contract.

Pass --from-pr through headless print mode and resolve PR-linked sessions through the shared conversation recovery path.

Add regression coverage for background resume launch args and PR selector matching.

* fix(cli): treat PR resume as headless resume source

Include --from-pr in print-mode resume guards so PR-linked headless resumes can run without a prompt and share resume-only options.

Skip eager startup hooks for headless PR resumes and add explicit --session-id launch coverage.

* fix(cli): keep background PR resumes live

Resolve non-forked --from-pr background launches to the selected transcript id before writing registry metadata.

Preserve PID identity refresh for PR-resume children by matching the stored invocation when argv does not carry the transcript id.

Add regressions for launch registration and registry refresh.

* test(cli): cover PR resume lookup failures

Add regression coverage for non-forked background --from-pr launches when the selector cannot be resolved.

Verify the launch planner returns the same clear error used by handleBgFlag().
2026-06-17 11:09:23 +08:00
f4c3be850e chore: remove dead code and add knip gate to CI check (#1612)
Delete 32 unreferenced source files (~4,000 lines) verified dead by
import-specifier grep and knip: test-only token utilities, orphaned hooks
(useTaskListWatcher, useSkillImprovementSurvey + its component), the
removed DevBar and ConfigTool UIs, unregistered bundled skills (stuck,
verifyContent), unused analytics sinks, the benchmark command, and
stale migrations/helpers.

Remove unused dependencies code-excerpt, stack-utils, and tsx from
package.json plus their entries in build stub/external lists.

Add knip with a tuned knip.json (entrypoints, build-time stub targets,
subprocess-launched fixtures, and runtime-string-imported SDKs ignored;
providerAutoDetect kept intentionally as provider pre-wiring) and wire
`bun run deadcode` into the `check` script so dead code stays dead.

Co-authored-by: OpenClaude <openclaude@gitlawb.com>
2026-06-14 10:13:37 +08:00
chioarubandGitHub cfcc5d06bd Fix OpenGateway provider flag API key routing (#1466)
* fix(provider): route OpenGateway provider credentials

* fix(provider): preserve CLI provider after settings env

* test: stabilize attribution settings mocks

* fix(provider): preserve OPENAI_API_BASE overrides
2026-06-02 21:54:19 +08:00
ArkhAngelLifeJiggyandGitHub 4d0603e990 fix(entrypoint): apply --max-old-space-size=8192 universally, not just CCR (#1191)
Closes #402 — JavaScript heap OOM during large tasks.

The CLI entry point only set --max-old-space-size=8192 when
CLAUDE_CODE_REMOTE=true, leaving local users with V8's ~2 GB default
ceiling. Long agentic tasks (multi-file refactors, large prompts, tool
loops) hit that ceiling and abort with:
  FATAL ERROR: Ineffective mark-compacts near heap limit
  Allocation failed - JavaScript heap out of memory

Fix: remove the CCR gate and apply the 8 GB cap unconditionally, with a
user-override guard -- if the runner already set NODE_OPTIONS
--max-old-space-size to an explicit value, their setting is preserved
(no silent clobbering).

Files changed:
- src/entrypoints/cli.tsx — remove CLAUDE_CODE_REMOTE guard, add
  user-override predicate, update comments
- src/entrypoints/cli.test.ts — 6 regression tests (new file)
2026-05-16 22:16:31 +08:00