Skip to content

fix(engines): drop the non-existent run subcommand from the kilocode invocation (#1012) - #1013

Merged
frankbria merged 2 commits into
mainfrom
fix/1012-kilocode-run
Aug 1, 2026
Merged

fix(engines): drop the non-existent run subcommand from the kilocode invocation (#1012)#1013
frankbria merged 2 commits into
mainfrom
fix/1012-kilocode-run

Conversation

@frankbria

Copy link
Copy Markdown
Owner

Closes #1012.

Problem

KilocodeAdapter.build_command built kilo run <prompt> --auto --workspace <path>. There is no run subcommand. Verified against kilocode 0.22.0: usage is kilocode [options] [command] [prompt] and the only commands are auth, config, debug, models — the prompt is a bare positional.

So run was swallowed as the prompt, the real prompt became a stray argument, --auto never took effect, and the CLI opened its interactive TUI and hung until the adapter's timeout, writing nothing. --engine kilocode could not do any work at all.

This is the third shipped engine with an invented invocation, after #913 (opencode's non-existent --non-interactive) and #914 (codex's invented app-server protocol). Found while building the binary-gated tier for #915 — which is exactly what that tier is for.

Evidence — reproduced live, both directions

Broken (exactly what the adapter built):

$ kilo run "Create a file kilo_probe.txt containing exactly: works" --auto --workspace $D
exit=124                 # killed at the timeout
$ ls $D                  # nothing written
out.log                  # contains the Kilo Code TUI banner

Working (identical, minus the bogus subcommand):

$ kilo "Create a file kilo_probe.txt containing exactly: works" --auto --workspace $D
exit=0
$ ls $D
kilo_probe.txt           # "✓ Task Completed / Created kilo_probe.txt with the content 'works'"

--workspace is honoured, so unlike #1007 there is no cwd problem here — only the invented subcommand.

Changes

The invocationrun removed; the prompt is the leading positional.

require_file_changes=True — the TUI path could exit 0 having written nothing, and gates would then run on an unchanged tree with the task markable DONE. Same guard claude-code got in #739/#819 and opencode in #913. KilocodeAdapter was the last shipped coding-agent adapter without it.

The unit test was pinning the bug. It asserted cmd[1] == "run" — i.e. that the adapter agrees with itself. It now asserts the prompt is the leading positional and that run is absent, so restoring the bug fails the suite.

A binary-gated smoke tier (test_kilocode_smoke_1012.py) runs the adapter's own build_command output against the installed kilo:

  • kilo --help lists no run command — asserted against the CLI's own help, so it fails if kilocode ever adds one and the adapter needs revisiting
  • the old invocation hangs and writes nothing (pins the bug, so nobody restores it believing it worked)
  • the adapter's command writes a real file — not "exit 0", which the TUI path could also produce
  • a run that writes nothing is not reported completed

Demo — real binary

tests/core/adapters/test_kilocode_smoke_1012.py .....            [100%]
5 passed in 53.95s

  17.2s  test_the_adapter_command_actually_writes_a_file          -> smoke.txt written
   9.8s  test_a_run_that_writes_nothing_is_not_reported_completed -> guard fired
  20.0s  test_the_old_invocation_hangs_and_writes_nothing         -> timeout, no file

The file on disk is the outcome evidence: the adapter drove real kilocode to completion and the delegated agent wrote real code.

Review

codex review --base main (cross-family, pre-PR) raised one [P2]: gating the smoke tests on shutil.which alone meant a plain uv run pytest on any machine with the CLI installed would start making real model calls — real credentials, real money, network-dependent flakiness.

Confirmed and fixed in 2d8937f: both smoke files now also require CODEFRAME_ENGINE_SMOKE=1. I applied it to the pre-existing opencode smoke file too, since it had the same defect. Verified both directions:

default:                     202 passed,  9 skipped in  2.3s   (was 53s of real model calls)
CODEFRAME_ENGINE_SMOKE=1:      5 passed             in 54.0s   (real kilo, real files)

Tests

tests/core/adapters/ — 202 passed, 9 skipped (default); +5 real-binary tests under the opt-in flag. ruff check clean.

Known limitations

…e invocation (#1012)

`KilocodeAdapter` built `kilo run <prompt> --auto --workspace <path>`, but
there is no `run` subcommand. Verified against kilocode 0.22.0, whose usage is
`kilocode [options] [command] [prompt]` with commands auth/config/debug/models
only — so `run` was swallowed as the prompt, `--auto` never took effect, and
the CLI opened its interactive TUI and hung until the adapter's timeout,
writing nothing. `--engine kilocode` could not do any work at all.

Reproduced both directions against the real binary:

    kilo run "Create kilo_probe.txt ..." --auto -w $D   -> exit 124, TUI banner, no file
    kilo     "Create kilo_probe.txt ..." --auto -w $D   -> exit 0, "Task Completed", file written

Also sets require_file_changes=True: the TUI path could exit 0 having written
nothing, and gates would then pass on an unchanged tree (the #739/#913 class).

The unit test asserted `cmd[1] == "run"` — pinning the bug rather than the CLI's
contract. It now asserts the prompt is the leading positional, and a new
binary-gated smoke tier drives the adapter's own build_command against the
installed kilo: it writes a real file, a no-work run is not reported completed,
and the old invocation is pinned as hanging-and-writing-nothing.
…ary-gated (#1012)

codex review [P2]: gating only on shutil.which meant a plain `uv run pytest`
on any machine with the CLI installed would start driving real kilocode (and,
pre-existing from #913, real opencode) sessions — real credentials, real model
calls, real money, 20-240s each — making the default suite depend on network
and live agent behaviour.

Both smoke files now also require CODEFRAME_ENGINE_SMOKE=1. Verified both
directions: default run is 202 passed / 9 skipped in 2.3s (was 53s of real
model calls); CODEFRAME_ENGINE_SMOKE=1 runs all 5 kilocode smoke tests against
the real binary in 54s.

The workflow that sets this for the scheduled tier is #915's scope.
@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Claude finished @frankbria's task in 3m 32s —— View job


GLM precision review — no defects found

Scoped to concrete defects only (logic errors, null/unhandled error paths, security, data loss, contract breaks, resource leaks). Style, architecture, naming, and test coverage are handled by a separate general-purpose review and intentionally not commented on here.

What I verified against the checked-out code

No findings to report.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

✅ GLM review: no defects found.

Scoped to concrete defects (logic errors, unhandled error paths, security, data loss, contract breaks, resource leaks). Traced the kilocode invocation fix and the require_file_changes=True guard through SubprocessAdapter.run() and detect_modified_files: timeout/exit-124/non-zero paths all resolve to failed before the guard, and the guard matches the established claude-code (#739/#819) and opencode (#913) pattern. No inline findings.

@frankbria
frankbria merged commit 5efe242 into main Aug 1, 2026
10 of 11 checks passed
@frankbria
frankbria deleted the fix/1012-kilocode-run branch August 1, 2026 05:14
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.

[P0.29] Kilocode adapter invokes a run subcommand that does not exist — the CLI opens the TUI and the task hangs

1 participant