Replace user-facing and protocol-visible "opencode" strings with "kilo"
across MCP auth flow, CLI commands, server metadata, and other areas
that were missed or reverted during upstream merges.
Files changed:
- mcp/index.ts: MCP client name and auth toast message
- cli/cmd/mcp.ts: config file reference, placeholder, debug client name
- cli/cmd/pr.ts: binary invocations and user messages
- server/server.ts: OpenAPI spec title and description
- server/mdns.ts: mDNS service host and name
- session/retry.ts: credits URL
- provider/provider.ts: CLI command in error message
- acp/agent.ts: auth method name and description
- tool/webfetch.ts: User-Agent header
Disable the catch-all proxy route that forwards unmatched requests to
app.opencode.ai. This proxy served static assets from an external domain,
which raises privacy/security concerns as users' requests are sent to a
third-party host.
The catch-all route now returns a 404 instead of proxying. The proxy
import is commented out. Changes are marked with kilocode_change markers
to keep upstream merge diffs minimal.
* fix: renamed pattern arrays used for permission rules
* fix: rename savePatternRules to saveAlwaysRules
* feat: generate hierarchical always patterns in bash tool
* feat: validate saveAlwaysRules against always array only
* feat: pass always field through extension bridge to webview
* feat: show hierarchical always patterns in PermissionDock dropdown
* fix: rename pattern to rule in PermissionDock translations, styles, and data-slots
* fix(vscode): correct auto-run comment in PermissionDock
* feat(kilo-vscode): strip trailing wildcard from permission rule labels
* fix: deduplicate permission rules and strip wildcards from display labels
* refactor: move hierarchy to metadata.rules, restore always to arity prefix
* feat: pass always field to permission dock for non-bash tool rules
* fix: correct bash test assertion to check metadata.rules and fix indentation
* fix: hide permission rules dropdown for non-bash tools
* fix: align always-rules route descriptions, whitespace, and restore multi-command tests
Replace the config disable:true approach with a proper Agent.remove()
function that scans config directories for the agent's markdown file
and deletes it, then refreshes state via Instance.dispose().
- Add Agent.remove() in agent.ts with RemoveError
- Add POST /kilocode/agent/remove route
- Mount KilocodeRoutes in server.ts
- Update KiloProvider to call the new backend route
- Regenerate SDK
File paths as query parameters can fail due to URL encoding issues.
Switch to POST /kilocode/skill/remove with the location in the JSON
request body, which avoids encoding problems entirely.
Also log the SDK error response to aid debugging.
The DELETE endpoint was returning data that somehow rendered as empty
rows in the webview. Simplify the approach:
- Webview optimistically removes the skill from its signal immediately
- Extension fires DELETE to the backend (deletes from disk + cache)
- Extension invalidates cachedSkillsMessage so next tab visit fetches
fresh data
- No second skillsLoaded message is sent after removal, avoiding the
stale data overwrite that caused the UI corruption
The DELETE /kilocode/skill endpoint now returns the updated skills
list (Skill.Info[]) instead of a boolean. The extension uses this
response directly to update the webview, eliminating the need for a
separate GET /skill round-trip that could return stale cached data.
Also normalize paths in Skill.remove() with path.resolve() to ensure
location strings match regardless of path format differences.
Rename routes/skill.ts to routes/kilocode.ts with KilocodeRoutes
export, mounted at /kilocode. This is the single home for all future
kilo-specific CLI endpoints, avoiding conflicts with the existing
/kilo gateway routes and keeping all kilo changes out of server.ts.
SDK: client.kilocode.removeSkill()
Extract the inline DELETE /skill endpoint from server.ts into a
dedicated packages/opencode/src/server/routes/skill.ts file, reducing
kilo-specific changes in the shared server.ts and minimizing future
merge conflicts with upstream.
The route is mounted at /skill and uses the same lazy() pattern as
other kilo-specific route files (telemetry, enhance-prompt, etc.).
Add Skill.remove() that deletes the skill directory from disk and
mutates the cached Instance.state in-place so subsequent GET /skill
calls return the updated list.
Add DELETE /skill?location=... server endpoint, regenerate the SDK,
and update KiloProvider to call the SDK method instead of deleting
files directly from the extension.
Add the Enhance Prompt feature to the VS Code extension, matching the
legacy extension's behaviour. A ✨ sparkle button in the chat input
toolbar rewrites the user's draft prompt using an LLM.
CLI:
- POST /enhance-prompt endpoint using LLM.stream with small model
- System prompt as agent.prompt for caching; user text as user message
- clean() strips code fences and surrounding quotes from LLM output
Extension:
- KiloProvider handler using SDK client.enhancePrompt.enhance()
- Shows VS Code error notification on failure
- WandSparkles icon from lucide-solid via @kilocode/kilo-ui
- Spin animation while enhancement is in flight
- Empty-input click shows feature description (all 16 i18n locales)
- Ctrl+Z / ⌘Z undo restores original draft
- Guard checks isBusy/isDisabled/enhancing matching canEnhance()
Tests:
- 11 unit tests for clean() in enhance-prompt.test.ts
Migration plan:
- Removed feature row (parity achieved)
- Deleted prompt-improvement.md spec doc
* fix: resolve diff viewer race condition and add diagnostics for Agent Manager
onRequestWorktreeDiff now awaits stateReady before resolving the diff
target, preventing a race where startDiffWatch fires before state loads
from disk. Added diagnostic logging to resolveDiffTarget, diff polling,
and the server-side /experimental/worktree/diff endpoint so silent
failures become visible in the output channel.
* fix: guard stateReady await so rejection doesn't break diff polling
* docs: clarify why .catch() is required on stateReady await
- Use kilo-ui Checkbox instead of raw <input> in CloudSessionList
- Replace `any` types in KiloRoutesDeps with structural types
- Inject Identifier dep instead of duplicating ID generation logic
- Delete unused fetchCloudSessions() in api/sessions.ts
- Add Array.isArray guard on data.messages in import endpoint
- Avoid mutating data.info in-place during cloud session import
- Translate session.cloud.import.* i18n keys across all 15 locales
- Remove obsolete checkbox CSS (now handled by kilo-ui)
The imported session was never registered with the cloud sync system
because Session.Event.Created was not fired. KiloSessions.init()
subscribes to this event to call KiloSessions.create(), which registers
the session with the ingest API and creates the session_share record
needed for incremental sync. Now uses Database.effect() to publish the
event after the DB transaction completes.
The import endpoint was using Storage.write() which writes JSON files,
but the CLI reads sessions from SQLite via Database. Rewrote to use
Database.use() with Drizzle inserts into SessionTable, MessageTable,
and PartTable — matching the pattern from the CLI's import command.
Imports a cloud session into local storage with fresh IDs (ses_, msg_,
prt_) to avoid collisions with the cloud session during sync. Passes
Storage and Instance deps from server.ts to the gateway routes.