diff --git a/.changeset/instant-agent-manager-terminal.md b/.changeset/instant-agent-manager-terminal.md new file mode 100644 index 00000000000..4893a22b6d4 --- /dev/null +++ b/.changeset/instant-agent-manager-terminal.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Accept terminal input immediately while the Agent Manager shell starts. diff --git a/.changeset/jetbrains-cli-mode-visibility.md b/.changeset/jetbrains-cli-mode-visibility.md new file mode 100644 index 00000000000..bc9cf774d13 --- /dev/null +++ b/.changeset/jetbrains-cli-mode-visibility.md @@ -0,0 +1,5 @@ +--- +"@kilocode/kilo-jetbrains": minor +--- + +Log whether the JetBrains plugin downloads Core or uses the bundled/cached version, and mark the Core version shown in the popup as "Bundled" when it wasn't downloaded. diff --git a/.changeset/opencode-v1-17-9-to-v1-17-13.md b/.changeset/opencode-v1-17-9-to-v1-17-13.md new file mode 100644 index 00000000000..529fce727e5 --- /dev/null +++ b/.changeset/opencode-v1-17-9-to-v1-17-13.md @@ -0,0 +1,21 @@ +--- +"@kilocode/cli": patch +"kilo-code": patch +--- + +Changes from opencode v1.17.9 to v1.17.13 upstream: + +- Core Improvements: MCP servers can append their instructions to the model context, and MCP resources are available as tools with template listing. +- Core Improvements: Model variants are generated from models.dev data, including modes exposed as models. +- Core Improvements: Tool definitions pass `strict` through for Codex parity, and Gemini requests support video and audio media. +- Core Bugfixes: Interrupted assistant steps settle instead of leaving sessions stuck busy. +- Core Bugfixes: MCP OAuth reconnects after authorization even when the server is disabled, refreshes credentials on reauthentication, requests refresh token scope, surfaces completion errors, and binds its callback to the IPv4 loopback. +- Core Bugfixes: MCP tool results prefer content over structured output, and denied resource template tools stay hidden. +- Core Bugfixes: Stale GitHub Copilot Responses item IDs are no longer replayed, and OpenAI reasoning variants are forced where required. +- Core Bugfixes: Adaptive thinking is enabled for Claude Sonnet 5, and expired promos were removed from the zen catalog. +- Core Bugfixes: Preserve released prompt history during database replay and keep native event streams connected for all supported Kilo events. +- Core Bugfixes: Remote skill manifests support optional per-skill versions; changing a version refreshes the cached skill atomically, and skill base directories are emitted as filesystem paths. +- CLI Improvements: Ports increment from the default when busy. +- CLI Improvements: Use `--auto` to start the TUI in a run-scoped auto-approve mode, and leave the mode mid-session from the command palette. +- TUI Improvements: Redesigned crash screen, model picker sorted by release date, bindable diff viewer and Move Session commands, main-branch diff source, and inline skill load errors. +- TUI Bugfixes: File autocomplete is scoped to the session, multi-day durations format correctly, and root sessions load in the session switcher. diff --git a/.changeset/privacy-mode-tui.md b/.changeset/privacy-mode-tui.md new file mode 100644 index 00000000000..9131915a7e9 --- /dev/null +++ b/.changeset/privacy-mode-tui.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Add a privacy mode that blurs PII in the TUI (personal balance, Kilo Pass usage, etc.) and requires confirmation before `/profile` reveals email, name, balance, and team. Toggle with the new `/privacy` command or by setting `privacy_mode` in `kilo.json`. The `kilo profile` CLI command is unaffected. \ No newline at end of file diff --git a/.changeset/prompt-rail-panel-edge.md b/.changeset/prompt-rail-panel-edge.md new file mode 100644 index 00000000000..e6de692cc30 --- /dev/null +++ b/.changeset/prompt-rail-panel-edge.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Move the prompt navigator rail to the panel edge so it is harder to open by accident, and keep it clear of the pane splitter while resizing. diff --git a/.changeset/quiet-jetbrains-watchers.md b/.changeset/quiet-jetbrains-watchers.md new file mode 100644 index 00000000000..3e07e6c6981 --- /dev/null +++ b/.changeset/quiet-jetbrains-watchers.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Fix high CPU and runaway memory growth in the JetBrains background `kilo serve` process on macOS by no longer eagerly starting native file watchers, matching the VS Code backend. diff --git a/.changeset/quiet-sqlite-lock-errors.md b/.changeset/quiet-sqlite-lock-errors.md new file mode 100644 index 00000000000..db7cb238f9d --- /dev/null +++ b/.changeset/quiet-sqlite-lock-errors.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Show a concise retryable message when concurrent Kilo processes temporarily lock the SQLite database instead of printing the full server error trace. diff --git a/.changeset/quiet-worktrees-list.md b/.changeset/quiet-worktrees-list.md new file mode 100644 index 00000000000..71bd8445ece --- /dev/null +++ b/.changeset/quiet-worktrees-list.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Prevent Agent Manager overview requests from timing out while refreshing Git statistics across many worktrees. diff --git a/.changeset/worktree-slash-commands.md b/.changeset/worktree-slash-commands.md new file mode 100644 index 00000000000..bc008e5df72 --- /dev/null +++ b/.changeset/worktree-slash-commands.md @@ -0,0 +1,5 @@ +--- +"kilo-code": minor +--- + +Support model, agent, variant, and sandbox slash commands in Agent Manager worktree prompts. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 1d4d1916ab9..e3b64495f37 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,4 +2,4 @@ blank_issues_enabled: false contact_links: - name: 💬 Join our Discord url: https://kilo.ai/discord - about: For quick questions or real-time discussion. Note that issues are searchable and help others with the same question. + about: For support, troubleshooting, how-to questions, and real-time discussion. diff --git a/.github/workflows/disabled/compliance-close.yml.disabled b/.github/workflows/disabled/compliance-close.yml.disabled index 14e68701e57..a83824e5cf6 100644 --- a/.github/workflows/disabled/compliance-close.yml.disabled +++ b/.github/workflows/disabled/compliance-close.yml.disabled @@ -34,10 +34,48 @@ jobs: const now = Date.now(); const twoHours = 2 * 60 * 60 * 1000; + const orgMemberAssociations = new Set(['OWNER', 'MEMBER']); + const agentLogin = 'opencode-agent[bot]'; + const { data: file } = await github.rest.repos.getContent({ + owner: context.repo.owner, + repo: context.repo.repo, + path: '.github/TEAM_MEMBERS', + ref: 'dev', + }); + const teamMembers = new Set( + Buffer.from(file.content, 'base64') + .toString() + .split('\n') + .map((line) => line.trim().toLowerCase()) + .filter(Boolean) + ); + + function isExempt(item) { + const login = item.user?.login?.toLowerCase(); + return ( + login === agentLogin || + orgMemberAssociations.has(item.author_association) || + (login && teamMembers.has(login)) + ); + } for (const item of items) { const isPR = !!item.pull_request; const kind = isPR ? 'PR' : 'issue'; + const login = item.user?.login; + + if (isExempt(item)) { + core.info(`Skipping ${kind} #${item.number}; author ${login || 'unknown'} is exempt`); + try { + await github.rest.issues.removeLabel({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: item.number, + name: 'needs:compliance', + }); + } catch (e) {} + continue; + } const { data: comments } = await github.rest.issues.listComments({ owner: context.repo.owner, diff --git a/.github/workflows/disabled/duplicate-issues.yml.disabled b/.github/workflows/disabled/duplicate-issues.yml.disabled index c90320bd45c..f0e68202481 100644 --- a/.github/workflows/disabled/duplicate-issues.yml.disabled +++ b/.github/workflows/disabled/duplicate-issues.yml.disabled @@ -17,12 +17,31 @@ jobs: with: fetch-depth: 1 + - name: Check exempt issue author + id: author + run: | + LOGIN="${{ github.event.issue.user.login }}" + ASSOCIATION="${{ github.event.issue.author_association }}" + + if [ "$LOGIN" = "opencode-agent[bot]" ] || + [ "$ASSOCIATION" = "OWNER" ] || + [ "$ASSOCIATION" = "MEMBER" ] || + grep -qxiF "$LOGIN" .github/TEAM_MEMBERS; then + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "Skipping issue automation for exempt author: $LOGIN ($ASSOCIATION)" + else + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + - uses: ./.github/actions/setup-bun + if: steps.author.outputs.skip != 'true' - name: Install opencode + if: steps.author.outputs.skip != 'true' run: curl -fsSL https://kilo.ai/install | bash - name: Check duplicates and compliance + if: steps.author.outputs.skip != 'true' env: OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -38,6 +57,7 @@ jobs: opencode run -m opencode/claude-sonnet-4-6 "A new issue has been created: Issue number: ${{ github.event.issue.number }} + Issue author association: ${{ github.event.issue.author_association }} Lookup this issue with gh issue view ${{ github.event.issue.number }}. @@ -49,6 +69,8 @@ jobs: Check whether the issue follows our contributing guidelines and issue templates. + If the issue author association is OWNER or MEMBER, skip this compliance check. Do not add the needs:compliance label for organization-owned issues. + This project has three issue templates that every issue MUST use one of: 1. Bug Report - requires a Description field with real content @@ -83,7 +105,7 @@ jobs: Based on your findings, post a SINGLE comment on issue #${{ github.event.issue.number }}. Build the comment as follows: - If the issue is NOT compliant, start the comment with: + If the issue is NOT compliant and the author association is not OWNER or MEMBER, start the comment with: Then explain what needs to be fixed and that they have 2 hours to edit the issue before it is automatically closed. Also add the label needs:compliance to the issue using: gh issue edit ${{ github.event.issue.number }} --add-label needs:compliance @@ -129,12 +151,31 @@ jobs: with: fetch-depth: 1 + - name: Check exempt issue author + id: author + run: | + LOGIN="${{ github.event.issue.user.login }}" + ASSOCIATION="${{ github.event.issue.author_association }}" + + if [ "$LOGIN" = "opencode-agent[bot]" ] || + [ "$ASSOCIATION" = "OWNER" ] || + [ "$ASSOCIATION" = "MEMBER" ] || + grep -qxiF "$LOGIN" .github/TEAM_MEMBERS; then + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "Skipping issue automation for exempt author: $LOGIN ($ASSOCIATION)" + else + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + - uses: ./.github/actions/setup-bun + if: steps.author.outputs.skip != 'true' - name: Install opencode + if: steps.author.outputs.skip != 'true' run: curl -fsSL https://kilo.ai/install | bash - name: Recheck compliance + if: steps.author.outputs.skip != 'true' env: OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -148,9 +189,12 @@ jobs: } run: | opencode run -m opencode/claude-sonnet-4-6 "Issue #${{ github.event.issue.number }} was previously flagged as non-compliant and has been edited. + Issue author association: ${{ github.event.issue.author_association }} Lookup this issue with gh issue view ${{ github.event.issue.number }}. + If the issue author association is OWNER or MEMBER, remove the needs:compliance label if present, delete the previous compliance comment if present, and do not post a new comment. + Re-check whether the issue now follows our contributing guidelines and issue templates. This project has three issue templates that every issue MUST use one of: diff --git a/.github/workflows/disabled/storybook.yml.disabled b/.github/workflows/disabled/storybook.yml.disabled index 1e652104d69..be2e099d0ed 100644 --- a/.github/workflows/disabled/storybook.yml.disabled +++ b/.github/workflows/disabled/storybook.yml.disabled @@ -9,6 +9,7 @@ on: - "bun.lock" - "packages/storybook/**" - "packages/ui/**" + - "packages/session-ui/**" pull_request: branches: [dev] paths: @@ -17,6 +18,7 @@ on: - "bun.lock" - "packages/storybook/**" - "packages/ui/**" + - "packages/session-ui/**" workflow_dispatch: concurrency: diff --git a/.github/workflows/disabled/triage.yml.disabled b/.github/workflows/disabled/triage.yml.disabled index 0b2c9d89a1c..a1dfc0840b3 100644 --- a/.github/workflows/disabled/triage.yml.disabled +++ b/.github/workflows/disabled/triage.yml.disabled @@ -16,13 +16,32 @@ jobs: with: fetch-depth: 1 + - name: Check exempt issue author + id: author + run: | + LOGIN="${{ github.event.issue.user.login }}" + ASSOCIATION="${{ github.event.issue.author_association }}" + + if [ "$LOGIN" = "opencode-agent[bot]" ] || + [ "$ASSOCIATION" = "OWNER" ] || + [ "$ASSOCIATION" = "MEMBER" ] || + grep -qxiF "$LOGIN" .github/TEAM_MEMBERS; then + echo "skip=true" >> "$GITHUB_OUTPUT" + echo "Skipping issue automation for exempt author: $LOGIN ($ASSOCIATION)" + else + echo "skip=false" >> "$GITHUB_OUTPUT" + fi + - name: Setup Bun + if: steps.author.outputs.skip != 'true' uses: ./.github/actions/setup-bun - name: Install opencode + if: steps.author.outputs.skip != 'true' run: curl -fsSL https://kilo.ai/install | bash - name: Triage issue + if: steps.author.outputs.skip != 'true' env: OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2e02e5b705e..9df9c697de3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -66,7 +66,6 @@ jobs: echo 'general=true' >> "$GITHUB_OUTPUT" echo 'settings=[{"os":"linux","index":1,"total":2,"host":"blacksmith-4vcpu-ubuntu-2404","run":true,"packages":true},{"os":"linux","index":2,"total":2,"host":"blacksmith-4vcpu-ubuntu-2404","run":true,"packages":false},{"os":"macos","index":1,"total":1,"host":"macos-15","run":true,"packages":true},{"os":"windows","index":1,"total":4,"host":"blacksmith-4vcpu-windows-2025","run":true,"packages":true},{"os":"windows","index":2,"total":4,"host":"blacksmith-4vcpu-windows-2025","run":true,"packages":false},{"os":"windows","index":3,"total":4,"host":"blacksmith-4vcpu-windows-2025","run":true,"packages":false},{"os":"windows","index":4,"total":4,"host":"blacksmith-4vcpu-windows-2025","run":true,"packages":false}]' >> "$GITHUB_OUTPUT" # kilocode_change end - unit: # kilocode_change start name: ${{ !matrix.settings.run && 'unit (unchanged)' || matrix.settings.total > 1 && format('unit ({0}, {1}/{2})', matrix.settings.os, matrix.settings.index, matrix.settings.total) || format('unit ({0})', matrix.settings.os) }} @@ -146,6 +145,8 @@ jobs: - name: Run non-CLI unit tests if: matrix.settings.run && matrix.settings.packages run: bun turbo test:ci --output-logs=errors-only --log-order=grouped --log-prefix=task --filter='!@kilocode/cli' --filter='!@kilocode/kilo-jetbrains' + env: + KILO_EXPERIMENTAL_DISABLE_FILEWATCHER: "true" # kilocode_change - non-CLI tests use the watcher-free unit-test profile # kilocode_change end # kilocode_change start - ensure the Darwin profile cannot suppress its own validation @@ -222,10 +223,15 @@ jobs: turbo-${{ runner.os }}-${{ hashFiles('turbo.json', 'bun.lock') }}- turbo-${{ runner.os }}- + - name: Check generated client + if: runner.os == 'Linux' + working-directory: packages/client + run: bun run check:generated - name: Run HttpApi exerciser gates run: bun turbo test:httpapi --filter='@kilocode/cli' env: - KILO_EXPERIMENTAL_DISABLE_FILEWATCHER: "true" # kilocode_change - same rationale as the CLI unit step: a watcher per scenario instance is too heavy for the exerciser + KILO_EXPERIMENTAL_DISABLE_FILEWATCHER: "true" # kilocode_change - a watcher per scenario instance is too heavy for the exerciser + # kilocode_change end # kilocode_change start @@ -251,7 +257,6 @@ jobs: echo "unit=${{ needs.unit.result }}" test "${{ needs.unit.result }}" = "success" # kilocode_change end - # kilocode_change start required: name: test (linux) diff --git a/.kilo/skills/icon-vscode/SKILL.md b/.kilo/skills/icon-vscode/SKILL.md new file mode 100644 index 00000000000..7eb5b388746 --- /dev/null +++ b/.kilo/skills/icon-vscode/SKILL.md @@ -0,0 +1,63 @@ +--- +name: icon-vscode +description: Create or review icons for Kilo's VS Code extension, webviews, and shared icon registry. +--- + +# VS Code Icons + +Use this skill for icon work in `packages/kilo-vscode/`, `packages/kilo-ui/`, and the shared `packages/ui/` icon registry. Keep official VS Code workbench rules separate from Kilo's webview design system. + +## Choose the icon system first + +| Surface | Use | Source of truth | Theme handling | +|---|---|---|---| +| VS Code commands, menus, and editor actions | Codicon, for example `$(add)`, or a 16x16 single-color SVG only when needed | `packages/kilo-vscode/package.json` records usages; [VS Code command icons](https://code.visualstudio.com/api/references/contribution-points#contributes.commands) defines the contract | VS Code themes Codicons; SVGs use light/dark contribution fields | +| Activity bar and view containers | 24x24 centered single-color icon by the VS Code convention; existing Kilo branding is an intentional asset exception | `packages/kilo-vscode/package.json`, `packages/kilo-vscode/assets/icons/` | Follow the contribution point; do not redesign the existing brand mark | +| Marketplace and extension branding | Packaged brand asset | `packages/kilo-vscode/package.json`, `packages/kilo-vscode/assets/icons/` | Existing Kilo assets define their own palette and variants | +| Webview buttons and UI | `Icon` or `IconButton` from `@kilocode/kilo-ui` | `packages/kilo-ui/src/components/icon.tsx`, then `packages/ui/src/components/icon.tsx` | `currentColor` and the VS Code theme bridge | +| Extension-contributed product icon | Existing WOFF2 font entry, for example `$(kilo-logo)` | `contributes.icons` in `packages/kilo-vscode/package.json` and its usages | VS Code product-icon theming | + +Do not draw a custom SVG when an appropriate Codicon or existing registry icon already exists. Do not use a webview icon directly in `package.json`, or a VS Code contribution icon directly in the webview. + +## Existing repository conventions + +- Search `packages/kilo-ui/src/components/icon.tsx` first for Kilo-only icons, then `packages/ui/src/components/icon.tsx` for shared icons. Preserve the existing key spelling, which is mostly kebab-case, and match a visual sibling before adding a new one. +- Webview registry icons are inline SVG path strings, not standalone files. They use `fill="currentColor"` or `stroke="currentColor"`; do not add theme duplicates or literal palettes to registry entries. Standalone brand artwork may use light/dark variants. +- Match the closest registry sibling's `viewBox`. The shared set is mostly `20 20`, with existing `16 16` entries; Kilo-only entries also intentionally use `24 24`. Icons render at 16px (`small`), 20px (`normal`), or 24px (`medium`/`large`). Never paste a path onto a different canvas without rebalancing it. +- The extension's current brand assets are `kilo-light.svg`, `kilo-dark.svg`, `kilo-light.png`, `kilo-dark.png`, and `logo-outline-black.png`. The WOFF2 file is a packaged contribution font, not an editable icon source. +- Registry icons are decorative by default. Icon buttons need an `aria-label` or visible button text; a tooltip or arbitrary `label` attribute is not sufficient unless the wrapper maps it to an accessible name. + +## Geometry rules + +1. Give each icon one clear semantic meaning. A small `+`, status mark, or active-state fill is an acceptable modifier. +2. Start from at least one existing sibling with the same role and match its `viewBox`, visual weight, caps, joins, and padding. Official command SVGs use a 16x16 canvas with 1px padding; official view-container icons use a centered 24x24 canvas. +3. Keep round-capped endpoints away from the edge so caps are not clipped. For registry icons, use the sibling's bounds rather than imposing a new universal padding rule. +4. Use static SVG geometry such as `path`, `rect`, `circle`, `ellipse`, `line`, `polyline`, `polygon`, and `g`. No raster images, external resources, gradients, filters, embedded fonts, or ` + +
+ ${input.body}${input.script ? `\n ` : ""} + +