Restore packages/ui/src/components/markdown.css. Upstream moved markdown
styling into the new session-ui package and deleted this file, but Kilo still
ships packages/ui's markdown component to the VS Code webview, so the rules
went missing while their consumer stayed. The copy button lost
position: absolute and opacity: 0, so it rendered below every code block
instead of in its corner, and showed the copy and check icons at once because
nothing hid the check state.
The palette showed "Enable auto-approve permissions" next to "Enable
auto-approve mode", which reads as the same command twice. They are not: one
lasts for the TUI run and is what --auto and --yolo seed, the other saves a
rule to global config. Both now say which they are and carry a desc, which
the palette already renders. The saved one is enforced server side, so its
desc says it covers every client. No behaviour change, and the command names
are untouched so the slash aliases still work.
Tests no longer depend on the developer's credential store. Credential
imports Global.data/auth.json on startup, and the catalog, plugin and
models-dev layers built Credential.node without overriding Global, so results
changed depending on whether the machine was logged in. They now use a temp
data directory, as the integration suite already did. That suite in turn set
KILO_AUTH_CONTENT at module scope; bun shares one process across test files,
so it leaked into credential.test.ts, whose auth.json cases then read "{}"
and found no credentials. Scoped with beforeAll/afterAll.
macOS-only failures, all merge gaps in Kilo tests:
- sandbox/state.test.ts runs a script in a subprocess; the LayerNode
migration put AppNodeBuilder.build in it without adding the import
- sandbox/session-tools.test.ts mocked MCP without clients(), which
upstream's resource tools now call
- sandbox/session.test.ts built SessionV2 without binding SessionExecution
Generated files: schema.gen.ts was formatted by an older prettier than the
one main's dependency bump resolves, so the generator no longer reproduced it
and the migration check called the schema stale. packages/client was missing
Pty.sessionID and the compaction include field. Both regenerated.
Also corrected the listener comment: it claimed application services still
come from AppRuntime, but the SessionV2 and MoveSession builds sit inside
KiloListener's Layer.fresh boundary and self-provide their subtrees, which is
deliberate since both bind this listener's own LocationServiceMap.
AppLayer was still missing EventV2, ProjectV2 and ProjectCopy, so
createListenerRoutes compensated by providing the whole application graph.
KiloListener wraps the routes in Layer.fresh, so that build ran against a
new memo map and stood up a second copy of every service, including the
database, plugins and the event bus.
Adding the three nodes to AppLayer lets the listener drop that provide, so
it resolves the same instances the rest of the process uses.
tool-input-delta and -end now just return. The guard only needs to not call
ensureToolCall; reading the part back cost a query per streamed chunk and
the result was discarded.
--yolo approved root permissions but subagent asks still keyed off
--dangerously-skip-permissions, so tracked task permissions were rejected
and the session was marked headless. Both now follow the same flag.
ACP resource parsing used an empty catch, which AGENTS.md forbids. Only a
non-URL uri is expected there, so parse without throwing and keep the
fallback for that case alone.
- tool-input delta/end no longer recreate a settled call as a pending part
- outputTokenMax is back in overflow accounting, with RuntimeFlags rewired
- MCP server instructions reach the system prompt again (sys.mcp call site)
- session revert decodes stored messages through the Kilo normalize boundary
- shell tool titles runs with the model description and keeps it in metadata
- subdirectory snapshots drop newly ignored files: the ignore check and the
index removal ran from the instance dir, but candidates are worktree
relative
- customize-opencode builtin stays unregistered after the boot.ts rename
- --auto is interpreted in one place; the flag beside it now covers only
--yolo and --dangerously-skip-permissions
- --cloud-fork works again, validateSession had landed before the import
- TUI block tool skips the empty title row, opencode catalog gate reads
credentials per reload, TUI worker logs crashes, Snowflake OAuth uses the
Kilo page, annotations guard covers the shared packages
- tests: startRun spawned without the solid preload so every run under it
died on the JSX runtime; two upstream tests get a permission fixture since
headless auto-rejects bash; one expected a single error record where Kilo
emits two, as it did before this merge
- changeset for the range, help snapshot, llmgateway indentation
The RunScriptManager keys entries by worktreeId and the webview sends
"local" for whichever project's local context is selected, so in
multi-project mode two projects' local runs collided in one entry: a
second project's Run button stopped the first project's script, and the
state payload spread every project's run statuses into the active
project's push, rendering foreign local rows as running.
The provider now namespaces the local key as <projectId>:local at the
message boundary (ambient project scope, no webview protocol change),
RunController treats the qualified suffix as a local run (repo root cwd,
"local" branch label), each project's state payload is filtered to its
own worktrees plus its un-namespaced local key, and runStatus emissions
are routed with a projectId stamp so background-project statuses land in
their own webview store. ScriptTerminalManager keys inherit the same
qualification, and its view mapping already namespaces run terminals to
the matching project bucket.
Generation was failing. Upstream added a guard in this range that rejects
duplicate session event variants, and Kilo's tool-content codec on the shared
event schema was tripping it, so openapi.json and the SDK were stale and a temp
packages/sdk/js/openapi.json got committed by accident.
Move the codec off the event schema into core/src/kilocode/event-storage.ts,
keyed by event type and applied only at the SQL boundary. Session events are on
the wire now (SessionEvent.Durable backs /api/session/{id}/history), so a
transform there forked the generated API. Shipped readers still parse old rows
and the wire contract goes back to upstream's. Drops the consumer-side
normalizers in the TUI and sync-v2 that existed only to undo the widening.
Also: restore the Kilo HttpApi title and a few branding strings, balance five
kilocode_change markers, drop a duplicate TUI palette entry, and teach
check-model-tool-network about the LayerNode wiring that replaced
Layer.provide(ToolNetwork.httpLayer).
* fix(agent-manager): align Cmd+/ fallback with platform binding and one-shot echo
* fix(agent-manager): expire dropped terminal-shortcut echoes at press time
The backend exited before binding with 'Service not found:
ControlPlaneMoveSession'. Upstream's v2 ServerApi groups declare location
and session middleware that must be satisfied when the layer is built,
but Kilo's listener path composes the routes itself and only createRoutes
carried that chain. MoveSession and PtyTicket were also dropped from the
app runtime graph during the layer-node migration.
The corrupted-cache recovery in ModelsDev.populate acquired the flock and
fetched unconditionally, while the background refresh fiber runs the same
recovery on layer build. When refresh won the lock race it rewrote a valid
cache file, but populate still fetched again because it never re-read the
cache after acquiring the lock. The result was a duplicated network call,
which the corrupted-cache test catches as calls.length == 2 on slow CI
runners (fast local machines almost always take the single-fetch path).
Re-run loadFromDisk under the flock, mirroring the re-check refresh
already performs, so whichever fiber recovers second reuses the valid
cache instead of refetching.
Panel terminal tabs reuse the tab bar's chrome: right-click Close/Close
Others, arrow-key navigation, overflow scrolling with edge fades, and
frozen widths while closing. The new-terminal button sits next to the
last tab instead of the panel edge, and the strip loses its top padding,
stray dividers, and off-center plus button.