* feat: add dev:local script to run CLI against local cloud dev server
* fix(cli): validate --cloud flag has a value in dev-local.ts
---------
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
* fix(memory): drop filename allowlist from diff durability check
hasDurableDiff mixed two signals in one bit: did the turn do real work,
and should it skip the consolidation throttle. The allowlist deciding
both was filename and extension based, so small edits outside the listed
patterns could be dropped as echo or trivial.
Split it: hasUserEdit (any non-generated file change) now gates echo and
trivial, hasSubstantialDiff (20+ lines churn, any language) decides the
throttle bypass. The filename allowlist and its English word list are
gone.
* refactor(memory): keep single-word name for generated regex
* fix(agent-manager): defer automatic branch naming until intent is clear
Agent Manager auto branch naming (PR #11741) renamed the placeholder
branch on the first user message, so a read-only question like "check if
issue #11903 was fixed?" locked the branch to investigate-issue-11903
immediately. Renaming is one-shot, so a later pivot to actually fixing the
issue could not recover the branch name.
Defer naming until there is evidence of a durable workstream:
- The first user message never triggers a rename via the send path;
prompts 2-4 may, and after four prompts without a rename the worktree
disarms permanently (fixing an unbounded-retry bug where null responses
re-fired an LLM call on every message forever).
- A new idle trigger renames once when the armed session goes idle and the
worktree already has work (dirty files or commits ahead of base), so a
single detailed first prompt that produces edits still gets named without
naming on message 1.
- The rename itself only runs while the session is idle: names generated
while the agent is busy are held and applied on the next idle transition
with all guards re-checked, removing mid-turn name-capture races.
Also tighten the CLI branch-name prompt to return null for read-only
status/verification questions as a second layer behind the structural
gates.
* fix(agent-manager): address review on branch naming
- generateOnIdle now checks the auto-naming setting before dispatching,
matching prompt(), so a setting toggled off after arming disarms without
a wasted LLM roundtrip.
- prompt() also suppresses dispatch while a rename is pending, closing the
redundant-generation window the busy path left open; the generate comment
now accurately describes both the immediate and pending rename paths.
- Expose forget(worktreeId) and call it from both worktree-removal handlers
so the controller's pending/model/idleAttempted entries are reclaimed when
a worktree is deleted mid-flight.
- hasWork logs the rev-list error instead of silently swallowing it, while
still failing safe to false (placeholder name kept).
- Reword the CLI prompt's null condition to a clear "only ask a question and
do not describe work to perform", dropping the vague temporal clause.
* fix(agent-manager): clean busySessions in forget and call before worktree removal
* feat: add AI image generation tool
Port the legacy generate_image tool to the opencode-based CLI as a
Kilo-owned tool gated by experimental.image_generation config flag.
- New generate_image tool with prompt/path/image/model params
- Routes through Kilo Gateway (zero-config) or BYO OpenRouter key
- Supports text-to-image generation and image editing
- Dynamic model discovery via GET /kilo/models/images endpoint
- VS Code settings toggle + live model dropdown in Experimental tab
- Writes image to disk and returns inline FilePart attachment
- Fallback model catalog for offline resilience
* refactor: change default image model to openrouter/auto
* fix: address bot review feedback
- Remove unused fetchKiloImageModels import in tool
- Normalize jpg→jpeg MIME in parser, input image, and attachment
- Replace mismatched extensions in ensureExtension (not just append)
- Add assertExternalDirectoryEffect for output path traversal guard
- Map unauthorized errors to 401 (not 400) in image models handler
- Keep last known model list on fetch failure (don't overwrite with empty)
- Fix tool description (remove false web search claim, fix grammar)
- Remove duplicated provider resolver tests
* fix: add retry for image models request to handle backend startup race
* fix(image-generation): address kilo bot review comments
- ensureExtension replaces mismatched image extensions instead of
appending (photo.jpg + PNG -> photo.png, not photo.jpg.png)
- Gateway /models/images normalizes errors to 400/401 matching every
other gateway route (was leaking undeclared upstream statuses)
- Add 401 response to openapi.json + SDK types for /kilo/models/images
to match the gateway's errors(400, 401) declaration
* fix(gateway): align /models/images error handling with other gateway routes
* refactor: switch image generation to effect HttpClient
* test: cover kilo models images endpoint in httpapi exercise scenarios
* Exclude POST-only and parameterized API endpoints from link checker
* Add ImageModelsProvider to agent manager context tree
* chore(deps): bump @openrouter/ai-sdk-provider to 2.10.0
Switches imageModel() to OpenRouter's POST /api/v1/images endpoint for
proper image usage/billing and image-specific params.
* fix: address image generation PR review feedback
- revert @openrouter/ai-sdk-provider 2.9.0->2.10.0 bump (image tool uses raw HTTP, not the SDK)
- translate image generation settings strings across all locales
- use central KILO_OPENROUTER_BASE instead of hardcoded URL fallback
- remove completed plan file
* chore: refresh source-links.md after URL refactor
* feat(opencode): experimental SWE-Pruner for task-aware tool output pruning
Adds an experimental.swe_pruner config flag (default off). When enabled,
the read and grep tools advertise an optional context_focus_question
parameter; when the agent provides it, large outputs are skimmed by the
small model down to the lines relevant to the question, with omitted
sections marked inline. Failures fall back to the full output.
Based on SWE-Pruner (arXiv:2601.16746).
* chore: regenerate source-links for swe-pruner arxiv reference
* fix(opencode): address swe-pruner review suggestions
Harden the skimmer instruction against prompt injection from untrusted
tool output, and document that pruning runs before the tool.execute.after
hook so plugins observe the model-facing output.
* feat(ui): surface SWE-Pruner activity on read/grep tool rows
The read renderer hides tool output entirely, so pruning was invisible in
the webview even though the model received the pruned output. Show a
'SWE-Pruner · kept/total' row driven by the swePruner tool metadata.
* chore: retrigger CI (flaky windows/jetbrains tests, review service delivery error)
* feat(opencode): configurable SWE-Pruner skimming model
Adds experimental.swe_pruner_model (provider/model format) with a model
selector in the VS Code Experimental tab, shown when SWE-Pruner is
enabled. Falls back to the configured small model when unset or when the
configured model is unavailable.
* fix(ui): localize the SWE-Pruner pruning indicator
Replace the hardcoded label with a ui.tool.swePruned i18n key
(interpolated kept/total) added to all 20 shared UI locales.
* chore: retrigger CI (windows bun install network timeout on tree-sitter-powershell)
---------
Co-authored-by: marius-kilocode <marius@kilocode.ai>
Point the notification at getting-started/settings instead of the CLI
platform page, and add the opencode migration callout there so the
neutral page is self-contained for VS Code and JetBrains users too.
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
Move the leftover-.opencode-directory detection off the always-on config
warning and into the cloud notifications list (client.kilo.notifications),
so it flows through each client's per-id dismissal: dismiss it once and it
won't return unless the directory is still present.
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
The settings sidebar used a fixed 150px width that clipped long
localized labels (e.g. German 'Automatisch genehmigen',
'Autovervollständigung'). The Kilo override intended to set 180px
but was dead: it lacked the [data-orientation=vertical] qualifier the
upstream rule has, so the upstream 150px won on specificity.
Match the upstream selector specificity and switch to content-driven
sizing (width: auto, min-width: 180px) so the list grows to fit the
longest translated label instead of truncating it.
A plain Error thrown when no changes are found became an untyped
defect through EffectBridge.fromPromise, which the error middleware
masked as a generic 500 "Unexpected server error". Declare a
CommitMessageNoChangesError (Schema.ErrorClass, httpApiStatus 422)
on the endpoint and translate the domain NoChangesError defect into
that typed failure, so the real message surfaces. The extension now
shows it directly instead of prepending a redundant prefix.
Kilo no longer falls back to opencode configuration stored in `.opencode`
directories. This change adds detection for both global and project-level
opencode configuration directories and issues a warning to guide users
on how to migrate their settings to the new Kilo configuration paths.
- Implement `KilocodeConfig.detectOpencodeConfig` to identify legacy
config locations.
- Add warning messages to the CLI configuration loading process.
- Update documentation to include migration instructions.
- Add tests to verify detection of global and project-level opencode
configs.
Co-authored-by: kiloconnect[bot] <240665456+kiloconnect[bot]@users.noreply.github.com>
* feat(commit-message): add language parameter to commit message generation
Add support for generating commit messages in the user's selected UI language.
The language parameter flows through the entire stack: VSCode extension passes
the selected locale, the HTTP API accepts the new field, and the generation
service appends language instructions to the system prompt for non-English
locales.
- Update CommitMessageRequest types to include optional language field
- Modify VSCode service to pass selected locale to the API
- Append language requirements to system prompt when language is not English
- Update OpenAPI specification and regenerate SDK types
- Add test coverage for language instruction generation
* feat(commit-message): add configurable language setting for AI-generated commit messages
Add a new `kilo-code.new.languageCommitMessage` VS Code setting that allows
users to choose a specific language for AI-generated commit messages,
independent of the UI language. When set to "sync" (default), the commit
message language follows the Kilo Code UI language.
- Add language selector dropdown to CommitMessageTab settings UI
- Add getCommitMessageLanguage() helper in i18n service
- Pass languageCommitMessage setting through KiloProvider to webview
- Add translation strings for all 20 supported locales
* refactor(locale): standardize commit message terminology across locale files
Replace literal translations of "commit" with the loanword form in Brazilian
Portuguese and Spanish locale dictionaries, correct a Korean typo (커AI → 커밋),
translate an untranslated English label in Norwegian, and align terminology with
conventional usage across all four affected language packs.
* style(i18n): fix prettier formatting on commit-message language strings
---------
Co-authored-by: marius-kilocode <marius@kilocode.ai>
* feat(vscode): jump transcript to message on timeline bar click
* fix(vscode): jump to the exact chunk containing the clicked timeline part
---------
Co-authored-by: Sylwester Liljegren <sylwester.liljegren@softronic.se>