Skip to content

chore/fix/refactor: dependency cleanup, auto-fix trust hardening, blame/file-history extraction - #2128

Merged
gfargo merged 3 commits into
mainfrom
claude/github-issues-review-swnyi0
Aug 16, 2026
Merged

chore/fix/refactor: dependency cleanup, auto-fix trust hardening, blame/file-history extraction#2128
gfargo merged 3 commits into
mainfrom
claude/github-issues-review-swnyi0

Conversation

@gfargo

@gfargo gfargo commented Aug 16, 2026

Copy link
Copy Markdown
Owner

What

Three independent, self-contained changes picked up from a GitHub issues review:

  1. Remove unused @langchain/community dependency — a 22MB production dependency that's never imported directly.
  2. Harden the auto-fix trust boundary further — finishes the hardening items left open after the core exploit fix in fix(autofix): reject autoFixTool/autoFixToolOptions/autoFixToolApiKey from project config #2097.
  3. Extract blame/file-history input handlers — continues the per-surface extraction of inkInput.ts's router.

Closes #1925
Closes #1840

Part of #1722blame/file-history are extracted; diff/status/history remain and are documented as follow-up on the issue (they're far more entangled with each other and other cross-cutting concerns than the surfaces extracted so far, so they weren't a safe verbatim lift under time pressure).

How

#1925: @langchain/community itself was unused, but transitively supplied @langchain/classic and @langchain/textsplitters, which src/lib/langchain/chains/summarize/index.ts and src/lib/parsers/default/index.ts import directly without declaring. Promoted those two to explicit pinned dependencies (matching the exact versions already validated by CI) and dropped @langchain/community plus its now-orphaned transitive deps.

#1840: The repo-committed-config exploit itself (autoFixTool/autoFixToolOptions controlled by a hostile .coco.json) was already fixed in #2097. This closes the three items the maintainer's own follow-up comment left open:

  • Per-adapter option allowlisting (codex/claude/gemini), closing CodexAdapter's unbounded -c key=value passthrough into codex's config namespace.
  • TaskList.autoFix() now shows the resolved command (binary + args) and requires explicit confirmation before running, instead of only printing the finding's title.
  • A hostileProjectConfig.test.ts chains the real trust-boundary filter into the real adapter allowlist (nothing mocked in between) to prove a hostile config's flags never reach spawn's argv, plus a completeness test that fails the build if a new top-level Config key isn't explicitly triaged as trusted/untrusted.
  • (An initial attempt also flipped the project-config trust boundary from a blocklist to an allowlist per the issue's own suggestion, but a real attempt broke noVerify and would likely break other per-command flags that live outside the schema-visible Config shape — reverted that piece in favor of the completeness test, which achieves the same guarantee for the surface where the actual bug lived.)

#1722: changelog/rebase/conflicts/overlay extractions had already landed separately (in #2066, not linked to this issue). This PR extracts the two remaining small surfaces the issue calls out — blame and file-history (7 branches each) — into surfaces/blame/input.ts / surfaces/fileHistory/input.ts, each exporting a slotted handleXInput(state, inputValue, key, context, slot) mirroring handleConflictsInput's non-contiguous-branch pattern (the two views are interleaved with each other and, at the jump-top/jump-bottom chords, with changelog). Verbatim lifts — inkInput.test.ts's existing 475 cases pass unchanged.

Validation

  • npm test passes locally (lint + jest + build + packaged-CLI smoke) — 7,023 passed, 14 skipped, 0 failed
  • New behavior has tests (adapter allowlist rejection cases, prepareAutoFix/TaskList confirm-flow cases, trust-boundary completeness test, per-slot blame/fileHistory handler tests)
  • schema.json regenerated and diffed — no drift (neither change touches the Config type shape)
  • Docs — no user-facing docs changes needed
  • Commits follow Conventional Commits

Notes

No breaking changes. The TaskList.autoFix() confirm-before-run step is a small UX change (auto-fix now requires an explicit confirm even for a well-configured trusted setup) — flagging in case that's worth a mention in release notes.


Generated by Claude Code

gfargo added 3 commits August 16, 2026 12:57
@langchain/community itself was never imported, but it was transitively
providing @langchain/classic and @langchain/textsplitters, which
src/lib/langchain/chains/summarize/index.ts and
src/lib/parsers/default/index.ts import directly without declaring them.
Promote those two to explicit pinned dependencies and drop the unused
22MB @langchain/community package plus its now-orphaned transitive deps
(binary-extensions, flat, math-expression-evaluator, uuid).

Fixes #1925.
The core exploit (repo-committed .coco.json controlling autoFixTool/
autoFixToolOptions) was already fixed in #2097. This finishes the
remaining hardening items from the issue:

- Per-adapter option allowlisting: each adapter (codex, claude, gemini)
  now filters autoFixToolOptions through an explicit allowlist of known
  tuning flags and drops anything else, warning on the rejected keys.
  This closes CodexAdapter's `-c key=value` passthrough, which used to
  forward any unrecognized key straight into codex's config namespace.
- TaskList.autoFix() now shows the exact resolved command (binary +
  args) and requires an explicit confirmation before running it, instead
  of silently spawning the tool after only printing the finding's title.
  Adapters expose `buildArgs()`/`binary` and autofix/index.ts exposes a
  new `prepareAutoFix()` that resolves the command without running it,
  so the preview reflects the adapter's real logic rather than a
  reimplementation of it.
- A hostileProjectConfig test chains the real trust-boundary filter into
  the real adapter allowlist (nothing mocked in between) to prove a
  hostile project config's flags never reach spawn's argv, and a
  completeness test asserts every schema-visible top-level Config key is
  explicitly triaged as trusted or untrusted, so a future executing
  feature can't silently land unprotected the way autoFixTool did.

An initial attempt also flipped the project-config trust boundary from
a blocklist to an allowlist per the issue's suggestion, but a real
attempt broke `noVerify` and would likely break other per-command flags
that live outside the schema-visible Config shape — hand-enumerating
that whole surface was too risky. The completeness test achieves the
same "someone remembered to check" guarantee for the schema-visible
surface where the actual #1840 fields lived, without touching the
untyped per-command flag surface.
Continues the per-surface extraction of inkInput.ts's router, following
the pattern already established for bisect, changelog, rebase, and
conflicts. Blame and file-history are the two remaining views the issue
calls out as small (7 branches each) — their handlers are interleaved
with each other (both are simple linear-list views living side by side
at every call site) and, at the jump-top/jump-bottom chords, with
changelog's inline handling too.

New surfaces/blame/input.ts and surfaces/fileHistory/input.ts each
export a slotted handleXInput(state, inputValue, key, context, slot)
mirroring handleConflictsInput's non-contiguous-branch pattern. Each
slot is a verbatim lift of its original inline block; the existing
inkInput.test.ts suite (475 tests) passes unchanged, confirming no
behavior drift, plus new dedicated per-slot tests for both handlers.

Diff, status, and history remain inline — the largest three surfaces
(21/18/17 branches respectively) — as further follow-up work.
@gfargo
gfargo merged commit 4b73e48 into main Aug 16, 2026
21 checks passed
@gfargo
gfargo deleted the claude/github-issues-review-swnyi0 branch August 16, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant