This release includes 1 security fix for security teams reviewing exposed deployments.
Topics
Affected surfaces
Summary
AI summaryUpdates below, setting.key, and forward/backward/wrap across a mixed release.
Full changelog
Repo hygiene: dropped dead React-hooks dir, locked the package manager to npm, made
npm run buildrebuilddist/from scratch, added a command registry as the single source of truth for autocomplete +/help+ dispatch validation, lifted ACP test coverage from 0% to ~45% on the testable surface, removed allas anycasts from the settings screen, upgradedconfto v13, fixed the tsconfig sotsc --noEmitis now genuinely clean (was silently emitting 445+ errors), patched the high-severityviteadvisory, switched CI from bun to npm, addedCONTRIBUTING.md+SECURITY.md, extracted the synchronous ACP handlers + pure helpers out of thestartAcpServer()closure into a testableserverHandlers.tsmodule (89.7% line coverage on the extracted surface; 0 → 25.7% onserver.ts), migratedrelease-binaries.ymlfrom bun to npm (keeping bun only for thebun build --compilebinary step), removed the deprecated + vulnerablepkgdevDependency (0 high/critical advisories remaining), and hardened the build withnoEmitOnError: true.
Removed
src/hooks/deleted. This directory (index.ts+useAgent.ts) was a
leftover from the old Ink-based TUI: it importedreact(which is not in
package.json) and was kept out oftscvia anexcludeintsconfig.json,
so the project type-checked only because the dead code was hidden. Nobody
imported it (grep "from.*hooks/" src/returned zero hits), and it referenced
arunAgentsignature that no longer exists. Thesrc/hooks/**/*exclude
entry is removed fromtsconfig.json—tsc --noEmitis now clean with
nothing hidden.
Changed
- Single package manager: npm.
bun.lockis removed andpackage-lock.json
is now the canonical lockfile (previously both were git-ignored and drifted).
.gitignoreno longer ignorespackage-lock.json; other lockfiles
(yarn.lock,pnpm-lock.yaml,bun.lock*) stay ignored. /autocomplete trimmed. Five rarely-tab-completed utility/legacy
commands were dropped from the/dropdown —/clear,/exit,
/context-save,/context-load,/context-clear— to cut clutter. They
remain fully dispatchable and listed in/help. (/sessionswas kept in
the dropdown as a primary navigation command.)npm run buildnow wipesdist/first (rm -rf dist && tsc …). The
bun build --compilebinary step reads fromdist/, so a staledist/
(e.g. leftover output from the now-deletedsrc/hooks/dir, or a renamed
module) could ship outdated JS. A clean rebuild on every build closes that
hole.src/acp/**/*.tsadded to the Vitest coverage scope so the editor-
integration layer is measured alongsideutils/,api/, andconfig/.confupgraded 12 → 13 (^13.1.0). BringsrootSchema/ajvOptions
options, a.delete()dot-notation typing fix, and updated transitive deps
(dot-prop8→9,ajvpatch bumps). Held below v14 pending a separate
engine/compat review — the v13 bump was all this release needed.tsconfig.jsonnow declares"types": ["node"]. Without it,tsc --noEmitwas silently emitting 445+TS2591: Cannot find name 'fs'/'path'/ 'process'/…errors across 86 files —npm run buildappeared to succeed
only because the config doesn't setnoEmitOnError, so the broken JS was
written todist/alongside the errors. Withtypes: ["node"]the type
check is genuinely clean (0 errors). This was a long-standing latent issue
masked by the emit-on-error behaviour.npm audit fixpatched the high-severityviteadvisory
(GHSA-v6wh-96g9-6wx3 / GHSA-fx2h-pf6j-xcff —launch-editorUNC path +
server.fs.denybypass on Windows) by bumping the transitivevite
brought in byvitest. One advisory remains: a single low inesbuild
(GHSA-g7r4-m6w7-qqqr — dev-server-only arbitrary file read on Windows),
pulled in transitively byvitest/tsx, with no fix short of a major bump
of those dev tools. Removingpkg(below) cleared the prior moderate
advisory, sonpm auditnow reports 0 high/critical (1 low total).
Added
- Command registry — single source of truth for slash-command metadata
(src/renderer/commands/registry.ts). Previously three places carried the
same data and drifted: theCOMMAND_DESCRIPTIONSrecord inApp.ts(123
hand-typed rows driving/autocomplete), thehelpCategoriesarray in
components/Help.ts(hand-typed/helprows), and thecaselabels in
renderer/commands.ts+acp/commands.ts. NowApp.tsandHelp.tsboth
derive from the registry, and two new tests (registry.test.ts) enforce the
invariant at build time: every top-levelcaselabel in either dispatcher
must exist in the registry — adding acase 'foo':without a registry
entry now fails CI. The registry also exposesresolveCommand(),
ALL_COMMAND_NAMES, andALL_ALIASESso the dispatchers themselves can
move to registry lookups incrementally. - ACP layer test coverage. Two new test files lift the previously
untested ACP adapter from 0% to meaningful coverage:src/acp/session.test.ts(35 tests) coversbuildProjectContext,
toolCallMeta(every tool → ACP kind mapping), andbuildRawOutput
(diff formatting for edits, stdout surfacing for commands, error paths).
toolCallMetaandbuildRawOutputwere promoted from module-private to
exported specifically so they can be tested in isolation.src/acp/commands.test.ts(10 tests) coversinitWorkspace— the
filesystem bootstrap that runs on every ACPsession/new:.codeep/
creation, project initialization, the read+write permission grant, and
the informed-consent banners for custom slash commands and lifecycle
hooks. Uses an isolated tmpdir per test (same pattern as
checkpoints.test.ts).- Together they catch regressions in the data-shaping surface and the
onboarding flow without mocking the agent loop, which is exercised
end-to-end bytoolExecution.test.ts.
- Settings screen: all 7
as anycasts removed. Previously every
config.set/config.getcall inSettings.tsusedsetting.key as any
becauseSettingItem.keywas typed asstringrather thankeyof ConfigSchema. Now:ConfigSchemais exported fromconfig/index.tsso consumers can
reference its keys.SettingItem.keyis typed askeyof ConfigSchema— a typo'd or unknown
setting key is now a compile error, not a silent runtime no-op.- All writes go through a single typed
writeSetting(setting, value)
helper. The unavoidableas ConfigSchema[K]cast lives in exactly one
audited spot instead of seven call sites, andconfig.get(setting.key)
no longer needs any cast. - 13 new tests (
Settings.test.ts) pin the write path: number editing +
clamping, select cycling (forward/backward/wrap), escape-abort, and the
updateRateLimits()side effect for the rate-limit settings.
CONTRIBUTING.md+SECURITY.mdadded. Previously the repo had
neither — the README's "Contributing" section was one sentence pointing
at GitHub issues. The new files cover:CONTRIBUTING.md: the npm-based setup, the test/build/type-check loop
(including "what gets a test" guidance), code style, an architecture
reading order for new contributors, the provider-integration flow, and
the release pipeline.SECURITY.md: how to report a vulnerability (GitHub Security Advisories
preferred), what's in/out of scope for an agent that can edit files and
run shell commands, and a list of the hardening features already in place
(project permissions, confirmation modes, hook trust gate, keychain
storage, telemetry opt-out) so contributors don't regress them.- The README's "Contributing" section now links to both.
- CI workflow switched from bun to npm (
.github/workflows/ci.yml).
The workflow usedbun install --frozen-lockfile, butbun.lockwas
removed and.gitignoredwhen npm became canonical (#2), so the gate
would fail on a clean checkout. Now usesactions/setup-node@v5with
Node 20 +npm ci+npx tsc --noEmit+npm test, consistent with
CONTRIBUTING.md.release-binaries.ymlstill uses bun (its
bun build --compilestep produces the cross-platform binaries — that's
tracked as a separate migration, not safe to flip blindly). server.tsrefactor: extracted handlers + pure helpers to module scope.
startAcpServer()was a ~1300-line closure whose 12+ request handlers
(session/set_mode,session/set_config_option,session/list,
session/delete, …) were unreachable by unit tests because they captured
the live stdio transport. The refactor lifts them into two testable
surfaces:server.tsmodule-scope exports — the pure helpers
(formatToolInputForPermission,resolveLocalPath,
collectEmbeddedContext,providerHasKey,buildConfigOptions,
AGENT_MODES) now carryexportand are covered byserver.test.ts.- New
serverHandlers.tsmodule — the four synchronous session
handlers (handleSetMode,handleSetConfigOption,handleSessionList,
handleSessionDelete) plus a pureapplyConfigOptionhelper, each
taking an explicit(msg, deps)pair wheredeps = { transport, sessions }. The transport is stubbed in tests via a recorded-call
array, which is what makes the assertions readable. startAcpServer()now constructs onehandlerDepsobject and delegates
to the extracted functions, keeping the dispatch loop intact.- The async handlers (
handleSessionPrompt,handleSessionNew,
handleSessionLoad,handleSessionResume, image/vision, agent loop)
stay in the closure for now — they reach into MCP spawning, the
keychain, andrunAgentSession, each of which needs its own extraction
pass. Tracked as a follow-up. - Coverage:
serverHandlers.tsat 89.7% lines / 87% statements;
server.tsup from 0% to 25.7%. 56 new tests acrossserver.test.ts
(34) andserverHandlers.test.ts(22).
release-binaries.ymlmigrated from bun to npm (build + publish-npm
jobs).bun install→npm ci,bun run→npm run,
setup-bun→setup-node@v5(Node 20 build, Node 24 publish). Only the
bun build --compilestep keeps bun — it produces the distributed
standalone binaries and has no npm-side equivalent (the deprecatedpkg
was never wired into CI). This makes CI + release consistent with the
canonical npm toolchain (#8 fixed the same drift inci.yml).- Removed deprecated
pkgdevDependency.pkgwas unmaintained since
2023 (archived by Vercel), carried a moderate-severity advisory, and its
build:binaryscript was never invoked by any workflow — the release
pipeline usesbun build --compileinstead. Removedpkg, the
build:binaryscript, and the top-level"pkg"config block from
package.json.npm auditnow reports 0 high/critical (was 1 high).
@yao-pkg/pkg(the active fork) stays available if we ever need an
npm-side path to standalone binaries. - Added
noEmitOnError: truetotsconfig.json. Now thattsc --noEmit
is clean (0 errors), this flag hardens the build:tscwill refuse to emit
dist/if a type error slips in, so a broken build can no longer be masked
by a staledist/. Prevents regressions of the kind that #7 fixed (445+
errors silently emitted for months). - Lifted
handleListProviders+buildProviderListinto
serverHandlers.ts. The provider-catalog handler was the simplest
remaining async-safe handler — pure shape mapping overPROVIDERS+ a
singletransport.respond. Extracted asbuildProviderList()(pure,
testable shape) +handleListProviders(msg, deps)(thin wrapper). 5 new
tests pin the shape includingdynamicModelsflagging for open-ended
providers (OpenRouter, Ollama).serverHandlers.tscoverage now at
89.7% lines.
Breaking Changes
- Removed `src/hooks/` directory (dead React‑hooks code).
- Locked to npm: removed `bun.lock`, made `package-lock.json` canonical, and stopped ignoring it in `.gitignore`.
- Changed `npm run build` to always wipe `dist/` first (`rm -rf dist && tsc …`).
Security Fixes
- Patched high‑severity Vite advisory via transitive bump (GHSA-v6wh-96g9-6wx3, GHSA-fx2h-pf6j-xcff).
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About Codeep
All releases →Related context
Related tools
Earlier breaking changes
- v2.8.0 `codeep account push` and `account sync` no longer transfer API keys unless `/keysync on` is enabled
- v2.4.1 MiniMax M3 replaces MiniMax-M2.7 as default model across all providers.
- v2.0.0 McpServer protocol now optional fields `command`, `args`, plus new `url` and `headers`; version bumped to 2.0.0.
Beta — feedback welcome: [email protected]