Releases: levelcodeai/levelcode
Release list
LevelCode v0.9.0
LevelCode v0.9.0
Two features this release: paste JSON and watch it tidy itself, and Kimi K3 arrives in LevelCode Cloud.
Highlights
JSON beautifies itself on paste
Working with minified JSON — one giant line, escaped, straight from a log or an API response? Paste it into LevelCode and it lands pretty-printed.
- Any buffer. A
.jsonfile, a.txt, an untitled scratch tab — it doesn't matter what the editor thinks the buffer is. (That's the difference from the built-in format on paste, which only fires in a buffer already known to be JSON.) - Only when it's actually JSON. It transforms a paste only when the whole thing is a valid JSON object or array. A bare number, a string, code that merely contains JSON, JSON with trailing prose, or already-formatted JSON — all left exactly as pasted. Non-JSON pastes are never touched.
- Yours to tune.
levelcode.jsonPaste.enabledturns it off;levelcode.jsonPaste.indentfollows your editor's indentation by default, or takes a number of spaces or"tab". And a normal paste is always one click away via the paste options.
It lives in the Notepad++ Pack, alongside the macros and line operations.
Kimi K3, in LevelCode Cloud
Moonshot's Kimi K3 — a 2.8-trillion-parameter model with a 1,048,576-token context window, built for long-horizon coding and agentic work — is now a selectable Pro model in LevelCode Cloud. Sign in, open the model picker, and choose it. No API key of your own required.
- A choice, not a default. Your plan's flagship is unchanged. K3 sits in the picker with its cost shown honestly: it runs about 4× the credits per turn of the default (it reasons on every turn, and that reasoning is billed), so a Pro budget goes roughly a quarter as far on it. Pick it when the task is worth it.
- The editor now meters it correctly. Select K3 and the context gauge reflects its real ~1M window instead of the old 200K default — so long sessions don't warn "full" five times too early.
Under the hood
extensions/levelcode-npp-pack/— a pureanalyzePaste()core (no editor dependency, fully unit-tested) behind aDocumentPasteEditProvider, so the paste transform is decided by tested logic and the size guard is measured in real UTF-8 bytes.extensions/levelcode-ai/providers/catalog.js— a capabilities row formoonshotai/kimi-k3(1,048,576 ctx) so the meter is right; the model itself becomes selectable via the LevelCode Cloud roster, no editor release required.extensions/levelcode-ai/scripts/kimi-k3-spike.js— a standalone harness that drives the real agent tool-loop against K3, to confirm an always-on-reasoning model survives the round-trip before it's leaned on. Seedocs/KIMI-K3.mdfor the full scope.
Test coverage
test/jsonBeautify.test.js— 13 cases: minified→pretty round-trips, the container-only / trailing-junk / already-formatted guards, indentation, and a UTF-8-byte size cap that a multibyte payload can't slip past.- The pre-build CI gate now discovers every bundled extension's suite (not just one), so the new Notepad++-Pack tests run on each release.
Full changelog: v0.8.1...v0.9.0
LevelCode v0.8.1
LevelCode v0.8.1
The version LevelCode reports is now its own.
v0.8.0 turned on auto-update — and the first thing it revealed was that the editor had been describing itself with somebody else's version number. The update dialog read "Current Version: 1.126.0", dated months earlier, next to a commit that really was LevelCode's. Half upstream, half LevelCode, and confusing whichever half you trusted.
This is also the first release delivered by auto-update itself: if you are on v0.8.0, this one most likely installed on its own.
Highlights
The version you see is the version you have
1.126.0 is the Code-OSS base LevelCode is built on, and it has to stay 1.x — extensions declare compatibility against it (engines.vscode), so renaming it to 0.8.1 would reject every extension that requires ^1.x. The release version now travels alongside it instead:
- Update tooltip —
Current Version: 0.8.1 (<commit>), with a Released date that reflects this release rather than the upstream base's build. - About — shows both,
0.8.1 — Code-OSS 1.126.0. About gets pasted into bug reports, where the base version is what explains extension-compatibility behaviour, so dropping it would lose real information.
Both values are stamped into the app at build time from the git tag.
If you are updating from v0.8.0: the update prompt you saw still said
1.126.0. That build predates the stamp and has no release version to read — the corrected display appears once v0.8.1 is running. Nothing went wrong.
Development builds can no longer impersonate a release
A build made from a commit after a release used to stamp that release's bare version — a local build five commits past v0.8.0 called itself 0.8.0. Off-tag builds are now labelled 0.8.0-5-g1a2b3c4, so a development build is visibly one. Builds cut at an exact tag are unaffected and stay clean.
Anything that isn't a recognisable version now fails the build outright rather than shipping a nonsense product version.
Under the hood
scripts/stamp-levelcode-version.mjs— new. WriteslevelcodeVersion+levelcodeReleaseDateinto the built app'sproduct.json, leavingversionuntouched for extension compatibility. Refuses malformed input with a non-zero exit.scripts/build-macos.sh— runs the stamp, tag-derived, after the existing strip steps. A checkout with no reachable tag skips it and falls back to the base version.patches/levelcode-core.patch— 11 → 14 entries: optional product fields, the update tooltip, and the native About dialog.docs/CORE-PATCHES.md— documents the three new core touches, and a regeneration hazard that silently fattened the patch by ~95 unrelated lines the one time it was hit.
Test coverage
The release gate now runs 14 suites, up from 13. It previously entered a single extension directory before collecting tests, so levelcode-updater's suite — including the check that the updater's Download button can never hand a user a raw .app.zip — was never executed in CI. It now discovers every extension, so a new suite is gated the moment it is added.
The gate also fails loudly if it matches zero test files. Reporting success while running nothing is the same class of bug as the one above.
Full changelog: v0.8.0...v0.8.1
LevelCode v0.8.0
LevelCode v0.8.0
The release that makes Check for Updates… real.
Until now that dialog always answered "There are currently no updates available." That was correct behaviour rather than a bug: the update feed deliberately refused to hand the built-in updater anything, because there was nothing it could safely install. Squirrel installs a signed .zip of the app, never a .dmg — and LevelCode only ever published dmgs.
v0.8.0 ships the missing artifact and the client-side plumbing around it. This is the first build published with update assets attached, so it is the release the update path starts from.
Highlights
Signed, notarized update assets
scripts/make-dmg.sh now emits LevelCode-<arch>.app.zip alongside the .dmg — on the Developer-ID path only.
- The dmg stays the human download (open, drag to Applications); the zip is update-only. They are not interchangeable.
- Built with
ditto -c -k --sequesterRsrc --keepParent, which preserves the stapled notarization ticket — so an app installed by an update still validates offline, with no Gatekeeper prompt. Re-zipping withzip(1)would drop it. - Emitted only when real Developer ID signing is used. Squirrel refuses an update whose signing identity doesn't match the running app, so an ad-hoc build can never masquerade as an update asset.
- The zip is cut after notarization completes, never before — an unstapled app would otherwise ship.
The Download button can't hand you a raw zip
The notify-only updater's Download action preferred the feed's url. That was correct while url was a release page — but now that the feed serves the signed .app.zip there, the same code would have started a raw zip download instead of opening a page.
Download now resolves product.downloadUrl → this release's notes page → the feed base, with the install artifact dropped from the human path entirely. A future feed change cannot put a zip back behind that button.
Updates roll out behind two independent guards
The server only offers a build to the auto-installing updater when both hold: signed feed assets are declared live, and the resolved release actually has a signed zip for that architecture. Releases cut before this one therefore stay notify-only on their own, rather than relying on the rollout being performed in the right order. Architecture matching is by exact filename, so an Intel install can never be handed the arm64 build.
Under the hood
scripts/make-dmg.sh— emits the Squirrel update asset (plus a local-only.sha256for hand-verifying a publish); header step list corrected to match the script, and the "unnotarized" warning scoped to the ad-hoc path it actually describes.extensions/levelcode-updater/update.js— new puredownloadUrl(feed, product, base)helper.extensions/levelcode-updater/extension.js— the Download action now delegates to it.docs/AUTO-UPDATE.md— new. The full feed contract, rollout order, risks, and the exit test, including which failure modes are enforced in code versus only documented.docs/RELEASING.md— publishing steps updated for the second asset, and an explicit note that the.sha256sidecars stay local (the feed reads GitHub's own asset digest).
Test coverage
extensions/levelcode-updater/test/update.test.js— 9 cases, 2 new, covering the Download path: the helper never returnsfeed.urleven when that is a signed.app.zip, falls back to a page rather than an artifact, and tolerates a null feed or product. Both new cases were mutation-checked — restoring the previous preference order fails them.- The release CI gate continues to run the 13
levelcode-aisuites. Note thelevelcode-updatertests are not part of that gate yet and are currently run manually.
Full changelog: v0.7.2...v0.8.0
LevelCode v0.7.2
LevelCode v0.7.2
A focused follow-up to v0.7.1 that lands the headline feature: repository project rules. Drop an AGENTS.md into a repo and the agent follows your conventions from the first turn. Plus two autopilot/UX refinements and a clearer always-on working indicator.
Highlights
Project rules — AGENTS.md drives the agent
LevelCode now reads a project rules file from each workspace folder and folds it into the agent's system prompt.
- Standard files: looks for
AGENTS.mdfirst, then falls back toCLAUDE.mdor.cursorrulesso existing repos keep working without a rename. - Multi-root aware: each folder's rules are labelled by folder name when detected; first-present file per folder wins.
- ** Cached & bounded:** loaded once per run into the byte-stable system block, so it rides the prompt cache (~0.1× on reads); capped at 16 KB per file with a truncation marker.
- Visible but quiet: when rules are active, a timeline chip (
📋 project rules · AGENTS.md) appears at the top of the run. - Trust model: rules are repository-author text injected by design, but they yield to any direct request in the conversation and cannot disable host-side safety gates (deletion,
sudo, force-push, remote-piped shells, publishing, etc.).
See the full write-up in docs/PROJECT-RULES.md.
Autopilot reacts immediately
The Autopilot toggle was snapshotted at run start, so flipping it mid-run had no effect on the in-flight run. It is now read live at every command decision, meaning the switch takes effect on the very next command.
A persistent working indicator
The previous working status was an ephemeral inline element that tool cards and streaming bubbles frequently cleared. The UI now shows a persistent bar above the composer whenever a run is streaming, with a label that tracks the current activity:
- Thinking
- Running command
- Responding
It hides the instant the run ends, and it is an ARIA live region so screen readers announce state changes.
Under the hood
extensions/levelcode-ai/projectRules.js— pure, injected-file-system loader for rules discovery and truncation.extensions/levelcode-ai/agent.js— reads rules once per run and renders the active-rules timeline chip.extensions/levelcode-ai/test/projectRules.test.js— 12 cases covering discovery, alias fallback, first-present-wins, multi-root labels, empty-file skip, truncation, throwing reader, and a real-filesystem smoke test.docs/PROJECT-RULES.md— documentation for users of the feature.
Test coverage
The release CI gate now runs 13 test files, including the new projectRules suite.
Full changelog: v0.7.1...v0.7.2
LevelCode v0.7.1
LevelCode v0.7.1
A feature-rich point release on v0.7.0 that makes day-to-day agent work faster and more legible: an autopilot mode, context compaction for long sessions, real cost + cache visibility in the editor, a redesigned command-approval card, and the fix that makes the Agents window reachable again.
Highlights
Autopilot — the agent runs, it doesn't ask
A new approvals control in the chat status bar. Default Approvals asks before every command (unchanged). Flip to Autopilot and the agent runs commands for you and verifies its own work instead of pausing — except a danger set that always stops and asks:
- deleting files (
rm,rimraf,git clean,find … -delete, thedelete_filetool) - discarding uncommitted work (
git reset --hard,git checkout -- .,git restore) sudo, force-push / history rewrite, piping a remote script into a shell, publishing a package, and writes outside the project.
The classifier (commandSafety.js) is a pure, unit-tested security gate, deliberately biased to ask when unsure. File edits stay reviewable with Keep/Undo in either mode.
Context compaction — long sessions don't hit the wall
The agent transcript only ever grew, and a long run used to dead-end with "start a new chat." The context-window popover now has a Compact button: it summarizes the earlier turns into a briefing, keeps the most recent turns verbatim, and the session continues. The cut lands only on a safe goal boundary, so a tool_use/tool_result pair is never orphaned (agentMemory.js, unit-tested).
Cost and cache, made visible
- Running $ spend — the response bar shows what each run cost and the credits left, in real retail micro-dollars from the metered gateway (no more
length/4estimates). - Cache read — the context-window popover (click the ring in the status bar) shows
cache_read_input_tokensas a share of the turn's input, with the dot greening in proportion to the hit rate. Prompt caching bills those reads at ~0.1×, so this is the savings made legible.
The command-approval card is a proper permission dialog
Redesigned: a clear title, the reason, the command in a recessed well, and Skip / Run at opposite ends. Approving now re-engages auto-scroll so you follow the output; the shell highlighter can no longer drop a character from the displayed command; and the misleading zsh · cwd label is gone.
The Agents window is reachable again
v0.7.0 shipped a regression where a de-branding change gated OPEN_AGENTS_WINDOW_PRECONDITION on the wrong flag, making the Agents window (plus the Agent Plugins view and chat participants) unreachable. Fixed — the de-brand is gated on the specific menu item now, never on Setup.hidden.
Under the hood
- Prompt-caching internals extracted into pure, exported functions (
splitOutCachedTokens,withRollingCacheBreakpoint), each with tests. - New coverage:
agentMemory,commandSafety,promptCaching,shHighlight— the release CI gate now runs 12 test files before it builds.
Notable new modules
extensions/levelcode-ai/commandSafety.js— the autopilot danger classifierextensions/levelcode-ai/agentMemory.js— the compaction transcript surgeryextensions/levelcode-ai/test/{agentMemory,commandSafety,promptCaching,shHighlight}.test.js
Full changelog: v0.7.0...v0.7.1
LevelCode v0.7.0
LevelCode v0.7.0
Fixes multi-root workspaces in the agent — added folders were previously invisible and unreachable — and finishes the de-branding sweep.
Highlights
Multi-root workspaces now work end-to-end in the agent
The agent's tool layer resolved every path against workspaceFolders[0], and its sandbox check rejected anything outside it — so any folder added with File → Add Folder was invisible and unreachable.
Worse, the failure was self-contradicting: list_files was already multi-root aware (via findFiles/asRelativePath), so it happily listed folder-name-prefixed paths that every other tool then refused to resolve. The agent could see a file and not read it.
resolveWorkspacePath()— one shared resolver. The sandbox is now the union of workspace folders, read live per call, so a folder added mid-session works on the very next tool call. It accepts theasRelativePathfolder-name-prefix convention, probes the other folders for reads, and on create targets the named folder (else the first).searchsweeps every folder and prefixes hits with the folder name, so results feed straight back intoread_file/edit_file.run_commandtakes an optionalfolderinput to pick the working directory.- System prompt names every workspace folder per run, and path errors hint the addressable folder names.
reviewSession(applyEdit/applyDelete) uses the same resolver, so the agent and the Keep/Undo pipeline can never disagree about where a file lives.
Adds test/workspacePaths.test.js — 14 cases, including a literal repro of the mid-session Add Folder bug and folder-escape rejections.
The Agents aquarium is ours now
The Agents-window easter egg (sessions.developerJoy.enabled) rendered its swimming "fish" as the literal VS Code logo silhouette, tinted with VS Code's three release-channel colours (#007ACC / #24bfa5 / #E04F00). It's now the LevelCode double chevron in our brand-gradient stops (#6a3fe0 / #7069ff / #4fb2ff) — same easter egg, our mark.
This was the last reachable Microsoft mark in the shipped app, completing the de-branding that landed in v0.6.0.
Also — landed server-side since v0.6.0 (no update needed)
v0.6.0's notes flagged that the metered LevelCode Cloud gateway still had to forward cache_control upstream before prompt caching would land. It now does, and it's verified in production: cache reads are non-zero and grow across turns, with OpenRouter reporting an ~87% cache-read discount on affected generations. Because it's server-side, every client already benefits — including builds older than v0.7.0.
Changed files
extensions/levelcode-ai/agent.jsextensions/levelcode-ai/reviewSession.jsextensions/levelcode-ai/test/workspacePaths.test.jsscripts/de-brand.mjsdocs/CORE-PATCHES.md
Full changelog: v0.6.0...v0.7.0
LevelCode v0.6.0
LevelCode v0.6.0
Maintenance release focused on AI cost efficiency: prompt caching now works across every provider path, cutting redundant input-token spend on long agent runs.
Highlights
Prompt caching now actually works (all providers)
The agent loop re-sends tools + system + the entire growing transcript every turn. Previously no cache breakpoints were attached, so each turn re-paid the full input price for the whole prefix — producing input-token usage an order of magnitude above output (e.g. 21M input vs 175k output on a single run).
Two latent gaps are fixed:
- Direct Anthropic (BYOK):
systemwas sent as a plain string, so the advertisedcache_controlnever attached andcache_read_input_tokensstayed0. It's now sent as an ephemeral-cached block (caches tools + system), with acache_controlbreakpoint rolled onto the last message (caches the transcript). - OpenRouter & LevelCode Cloud gateway (OpenAI-compatible): now reads
prompt_tokens_details.cached_tokensso cache hits are visible in the context meter (split out ofprompt_tokensso the meter total stays exact), and writescache_controlbreakpoints only for Claude-family models via a newisAnthropicFamily()guard. GPT / Gemini / DeepSeek auto-cache and would ignore or reject the field.
Impact: Direct-Anthropic (BYOK) and OpenRouter benefit immediately. For the metered LevelCode Cloud gateway, the client now sends the caching hint, but the gateway proxy must forward cache_control upstream for the cache to land server-side.
Adds 4 test cases (translate.test.js) covering the breakpoints and the Claude-family gate.
Fixes
- Release tooling:
gh release delete-assetaccepts a single<tag> <asset-name>per call; the publish flow now splits it into one call per asset (each with-y) so releases aren't silently mis-dropped or blocked on an interactive prompt.
Changed files
extensions/levelcode-ai/providers/anthropic.jsextensions/levelcode-ai/providers/openaiCompat.jsextensions/levelcode-ai/providers/translate.jsextensions/levelcode-ai/test/translate.test.jsdocs/RELEASING.md
Full changelog: v0.5.0...v0.6.0
LevelCode v0.5.0
Draft — not for release as-is. The attached UNSIGNED-LevelCode-<arch>.app.zip
files are CI build artifacts with no Developer ID signature or notarization.
To finish the release locally (your signing cert never touches CI):
gh release download v0.5.0 --pattern 'UNSIGNED-*.app.zip'- For each arch — unzip into
VSCode-darwin-<arch>/, then
CODESIGN_IDENTITY="Developer ID Application: …" NOTARY_PROFILE=levelcode-notary ./scripts/make-dmg.sh <arch>
(signs → dmg → notarizes → staples →LevelCode-<arch>.dmg). gh release upload v0.5.0 LevelCode-arm64.dmg LevelCode-x64.dmg- Delete the
UNSIGNED-*.app.zipassets, add real notes, and publish.
Full runbook: docs/RELEASING.md.
LevelCode v0.4.0
Draft — not for release as-is. The attached UNSIGNED-LevelCode-<arch>.app.zip
files are CI build artifacts with no Developer ID signature or notarization.
To finish the release locally (your signing cert never touches CI):
gh release download v0.4.0 --pattern 'UNSIGNED-*.app.zip'- For each arch — unzip into
VSCode-darwin-<arch>/, then
CODESIGN_IDENTITY="Developer ID Application: …" NOTARY_PROFILE=levelcode-notary ./scripts/make-dmg.sh <arch>
(signs → dmg → notarizes → staples →LevelCode-<arch>.dmg). gh release upload v0.4.0 LevelCode-arm64.dmg LevelCode-x64.dmg- Delete the
UNSIGNED-*.app.zipassets, add real notes, and publish.
Full runbook: docs/RELEASING.md.
LevelCode v0.3.0
Draft — not for release as-is. The attached UNSIGNED-LevelCode-<arch>.app.zip
files are CI build artifacts with no Developer ID signature or notarization.
To finish the release locally (your signing cert never touches CI):
gh release download v0.3.0 --pattern 'UNSIGNED-*.app.zip'- For each arch — unzip into
VSCode-darwin-<arch>/, then
CODESIGN_IDENTITY="Developer ID Application: …" NOTARY_PROFILE=levelcode-notary ./scripts/make-dmg.sh <arch>
(signs → dmg → notarizes → staples →LevelCode-<arch>.dmg). gh release upload v0.3.0 LevelCode-arm64.dmg LevelCode-x64.dmg- Delete the
UNSIGNED-*.app.zipassets, add real notes, and publish.
Full runbook: docs/RELEASING.md.