* feat(opencode): add PR link detect and parse helpers
detectPrLink runs gh pr view, parsePrUrl accepts GitHub and GitLab PR
URLs, and a Storage helper holds the manual override.
* feat(opencode): add kilo pr link, unlink, and status commands
kilo pr becomes a parent command with checkout preserved. link and
unlink write the Storage override; the next heartbeat persists it.
* feat(opencode): advertise prLink on the heartbeat and ingest it
getSessions resolves the Storage override, cleared, or detected link,
puts prLink on the heartbeat, and syncs the session_pr_link item.
* fix(opencode): encode worktree in pr link override storage key
The manual override key used the raw absolute worktree path. Storage
builds the file with path.join, so a Windows drive colon made an invalid
filename and kilo pr link failed. Encode the worktree so the key is one
valid path segment on both platforms.
* test(opencode): cover kilo pr status outputs
Extract the status handler body so it is testable, then assert the four
outputs: stored link, cleared, detected, and no link. Split captured
output on os.EOL so the test passes on Windows.
* refactor(opencode): remove dead pr-link code found in simplify pass
detectPrLink now reuses parsePrUrl instead of hand-parsing the URL and
number, drop the dead github.com special case, and inline the
prLinkTripleKey helper.
* fix(opencode): clear pr-link dedupe map on session delete
* docs(kilo-docs): regenerate CLI reference for kilo pr subcommands
* chore: add session-pr-link changeset and bump facade allowlist
Main landed the same httpapi design (git-opt-in fixtures, --shard flag)
and the same permission.create readiness wait. Resolution adopts main's
implementations and keeps this branch's unique work on top: the
--shards child-process orchestrator (adapted to main's zero-based
shard indexing), scenario retry with backoff gated on state-reset,
project.update isolation, and exerciser env stripping. Removed the
superseded agentsReady/probe machinery and this branch's duplicate
round-robin filter (double-sharding silently dropped scenarios).
Validated: coverage, auth, and 4-shard effect passes all green
(315 checks, 0 failures).
Closes#12996. Part of #12986.
- websearch resolves KILO_WEBSEARCH_PROVIDER, EXA_API_KEY and
PARALLEL_API_KEY through Env.Service in the tool body and threads
them into the pure helpers; selectWebSearchProvider takes the
override as a parameter.
- mcp-websearch no longer snapshots EXA_API_KEY into a module-level
URL at import time; exaUrl(key) derives it per call, so BYOK keys
set or cleared after startup are honored.
- Tool registry provides Env.node.
- kilo-tool-process-env allowlist is now empty; check:architecture
drops from 15 to 9 classified ratchet sites.
- Transform/model tests confirmed running in-process via plain
bun test (455 tests, <1s), the other half of #12996.
warpgrep.ts, the third file in the original ratchet, was already
removed on main.
- 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
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).