Skip to content

feat: add experimental voice-steered design mode#11436

Draft
Drixled wants to merge 2 commits into
mainfrom
feat/design-mode-voice
Draft

feat: add experimental voice-steered design mode#11436
Drixled wants to merge 2 commits into
mainfrom
feat/design-mode-voice

Conversation

@Drixled

@Drixled Drixled commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Adds an experimental kilo design command for voice-steered browser editing.

  • Adds the in-process design session orchestrator, terminal surface, voice protocol/adapters, and tests.
  • Adds a Swift Apple Speech sidecar plus a small in-repo design fixture app.
  • Keeps the command dev-only and isolated under src/kilocode/design with a changeset.
  • Includes the loading voice lifecycle state used by the sidecar before listening begins.

This is an exploratory MVP for evaluating the continuous voice-to-edit loop rather than a production feature.

Drixled added 2 commits June 7, 2026 01:32
Add `kilo design`, an experimental, dev-gated launch command for
voice-steered live design iteration. It runs one in-process Kilo session
driven by a continuous voice loop: speak (or type, in fake-voice mode),
turns auto-segment on end-of-utterance and dispatch to the agent while
edits stream back into a browser canvas. Escape interrupts and clears.

- Pure core (protocol/reducer/metadata/orchestrator) with unit tests
- Terminal voice console (voice-activity meter, rolling transcript, status)
- Apple Speech sidecar (packages/kilo-voice-sidecar) with continuous
  listening, automatic silence-window segmentation, and a watchdog
- Zero-install browser canvas fixture (packages/kilo-design-fixture)
- Auto-approve session permissions; dispatch errors surfaced on the console
if (event.properties.sessionID === session.sessionID) orchestrator.agentOpen()
})
const offClose = yield* bus.subscribeCallback(Session.Event.TurnClose, (event) => {
if (event.properties.sessionID === session.sessionID) orchestrator.agentClose(event.properties.reason)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Turn-close events can race with a new turn after Esc

TurnClose is session-scoped here, so after escape() a late "interrupted" close from the canceled turn will still call agentClose() even if the user has already started a fresh turn. Because the orchestrator does not track which turn the close belongs to, that stale close clears state.active for the new turn and lets subsequent input dispatch immediately instead of queueing. This can reorder or overlap turns whenever a new utterance arrives before the cancel fully settles.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Effect.sync(() => {
offOpen()
offClose()
void orchestrator.stop()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Async shutdown is dropped on exit

orchestrator.stop() is the only path that tells the sidecar/helper process to shut down and waits for Process.stop(...). Calling it with void inside Effect.sync means the command can finish and hit the top-level process.exit() before that promise resolves, leaving kilo-voice-sidecar or a custom --voice-helper-command running after kilo design exits.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

}

func setActivation(_ value: String) {
lock.async { self.activation = value }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: push-to-talk is advertised but never changes capture behavior

This setter only stores the mode. Nothing in beginAudio(), startTimer(), or the stdin command handlers branches on activation, so --voice-activation push-to-talk still runs the exact same always-listening loop as continuous. Since the CLI exposes this as a supported choice, users opting into push-to-talk will get continuous microphone capture with no warning.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 3 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/opencode/src/kilocode/design/cmd.ts 187 Session-scoped TurnClose events can close a newer turn after Esc, allowing out-of-order or overlapping dispatches.
packages/opencode/src/kilocode/design/cmd.ts 200 Cleanup drops the orchestrator.stop() promise, so the voice helper may survive process exit.
packages/kilo-voice-sidecar/Sources/kilo-voice-sidecar/main.swift 321 push-to-talk is exposed as a supported mode but never changes the sidecar's behavior.
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
packages/opencode/test/kilocode/design/ The new tests cover queueing and fake-voice flow, but they do not exercise the stale TurnClose race after escape() or verify sidecar shutdown behavior.
Files Reviewed (29 files)
  • .changeset/design-mode-voice.md - 0 issues
  • packages/kilo-design-fixture/AGENTS.md - 0 issues
  • packages/kilo-design-fixture/package.json - 0 issues
  • packages/kilo-design-fixture/public/index.html - 0 issues
  • packages/kilo-design-fixture/public/styles.css - 0 issues
  • packages/kilo-design-fixture/serve.ts - 0 issues
  • packages/kilo-voice-sidecar/.gitignore - 0 issues
  • packages/kilo-voice-sidecar/Package.swift - 0 issues
  • packages/kilo-voice-sidecar/Sources/kilo-voice-sidecar/Info.plist - 0 issues
  • packages/kilo-voice-sidecar/Sources/kilo-voice-sidecar/main.swift - 1 issue
  • packages/opencode/src/index.ts - 0 issues
  • packages/opencode/src/kilocode/design/browser.ts - 0 issues
  • packages/opencode/src/kilocode/design/cmd.ts - 2 issues
  • packages/opencode/src/kilocode/design/metadata.ts - 0 issues
  • packages/opencode/src/kilocode/design/orchestrator.ts - 0 issues
  • packages/opencode/src/kilocode/design/session.ts - 0 issues
  • packages/opencode/src/kilocode/design/state.ts - 0 issues
  • packages/opencode/src/kilocode/design/surface/terminal.ts - 0 issues
  • packages/opencode/src/kilocode/design/surface/view.ts - 0 issues
  • packages/opencode/src/kilocode/design/voice/adapter.ts - 0 issues
  • packages/opencode/src/kilocode/design/voice/fake.ts - 0 issues
  • packages/opencode/src/kilocode/design/voice/local.ts - 0 issues
  • packages/opencode/src/kilocode/design/voice/protocol.ts - 0 issues
  • packages/opencode/src/kilocode/design/voice/sidecar.ts - 0 issues
  • packages/opencode/test/kilocode/design/metadata.test.ts - 0 issues
  • packages/opencode/test/kilocode/design/orchestrator.test.ts - 0 issues
  • packages/opencode/test/kilocode/design/protocol.test.ts - 0 issues
  • packages/opencode/test/kilocode/design/state.test.ts - 0 issues
  • packages/opencode/test/kilocode/design/view.test.ts - 0 issues

Fix these issues in Kilo Cloud


Reviewed by gpt-5.4-2026-03-05 · 730,293 tokens

Review guidance: REVIEW.md from base branch main

@Drixled Drixled marked this pull request as draft June 18, 2026 18:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant