From 184ed23007d14e48d42a6f8f1d82113cb97e5b46 Mon Sep 17 00:00:00 2001 From: marius-kilocode Date: Tue, 25 Aug 2026 14:54:59 +0200 Subject: [PATCH 1/2] fix(cli): address startup review feedback --- .changeset/fix-cli-startup-followup.md | 5 +++++ .../opencode/src/kilocode/cli/lazy-commands.ts | 14 ++++++++++---- packages/opencode/src/kilocode/cli/setup.ts | 1 - packages/opencode/src/kilocode/help-command.ts | 9 ++++++--- .../test/kilocode/cli/bootstrap-runtime.test.ts | 9 +++++++++ 5 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 .changeset/fix-cli-startup-followup.md diff --git a/.changeset/fix-cli-startup-followup.md b/.changeset/fix-cli-startup-followup.md new file mode 100644 index 0000000000..23d9ac25a0 --- /dev/null +++ b/.changeset/fix-cli-startup-followup.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Fix CLI help disposal and shell completion after startup optimization. diff --git a/packages/opencode/src/kilocode/cli/lazy-commands.ts b/packages/opencode/src/kilocode/cli/lazy-commands.ts index ee49d9d5b6..c9490e833b 100644 --- a/packages/opencode/src/kilocode/cli/lazy-commands.ts +++ b/packages/opencode/src/kilocode/cli/lazy-commands.ts @@ -19,6 +19,10 @@ export function hasLazyCommandSelection() { return selected } +export function markLazyCommandSelection() { + selected = true +} + export function lazy(input: { command: string | readonly string[] aliases?: string | readonly string[] @@ -29,9 +33,11 @@ export function lazy(input: { const load = () => (state.task ??= input.load()) if (completion) { tasks.push( - load().then((command) => { - state.command = command - }), + load() + .then((command) => { + state.command = command + }) + .catch(() => undefined), ) } return { @@ -39,7 +45,7 @@ export function lazy(input: { aliases: input.aliases, describe: input.describe, builder: ((args: Argv) => { - selected = true + markLazyCommandSelection() if (state.command) return build(state.command, args) return load().then((command) => build(command, args)) }) as never, diff --git a/packages/opencode/src/kilocode/cli/setup.ts b/packages/opencode/src/kilocode/cli/setup.ts index 7557d3c88a..3d1e8bae98 100644 --- a/packages/opencode/src/kilocode/cli/setup.ts +++ b/packages/opencode/src/kilocode/cli/setup.ts @@ -153,7 +153,6 @@ export namespace KiloCli { if (narrow) { const { KiloCliBootstrapRuntime } = await import("@/kilocode/cli/bootstrap-runtime") await KiloCliBootstrapRuntime.dispose() - return } const { InstanceRuntime } = await import("@/project/instance-runtime") await InstanceRuntime.disposeAllInstances() // safety net (no-op if already disposed) diff --git a/packages/opencode/src/kilocode/help-command.ts b/packages/opencode/src/kilocode/help-command.ts index ecb5f90f14..fa92607751 100644 --- a/packages/opencode/src/kilocode/help-command.ts +++ b/packages/opencode/src/kilocode/help-command.ts @@ -1,13 +1,15 @@ import { cmd } from "../cli/cmd/cmd" import { generateHelp } from "./help" import type { Argv } from "yargs" +import { markLazyCommandSelection } from "@/kilocode/cli/lazy-commands" export function createHelpCommand(root?: () => Argv) { return cmd({ command: "help [command]", describe: "show full CLI reference", - builder: (yargs) => - yargs + builder: (yargs) => { + markLazyCommandSelection() + return yargs .positional("command", { describe: "command to show help for", type: "string", @@ -22,7 +24,8 @@ export function createHelpCommand(root?: () => Argv) { type: "string", choices: ["md", "text"] as const, default: "md" as const, - }), + }) + }, async handler(args) { if (!args.command && !args.all) { if (root) { diff --git a/packages/opencode/test/kilocode/cli/bootstrap-runtime.test.ts b/packages/opencode/test/kilocode/cli/bootstrap-runtime.test.ts index 4ac32559b5..4bcbf15995 100644 --- a/packages/opencode/test/kilocode/cli/bootstrap-runtime.test.ts +++ b/packages/opencode/test/kilocode/cli/bootstrap-runtime.test.ts @@ -1,5 +1,7 @@ import { describe, expect, test } from "bun:test" import { KiloCli } from "../../../src/kilocode/cli/setup" +import { createHelpCommand } from "../../../src/kilocode/help-command" +import yargs from "yargs" describe("CLI bootstrap runtime selection", () => { test("uses the narrow runtime for worker-backed TUI launches", () => { @@ -11,4 +13,11 @@ describe("CLI bootstrap runtime selection", () => { expect(KiloCli.workerTui({ _: [], mini: true })).toBe(false) expect(KiloCli.workerTui({ _: [], worktree: "feature" })).toBe(false) }) + + test("keeps full bootstrap when the eager help command is selected", () => { + const command = createHelpCommand() + if (typeof command.builder !== "function") throw new Error("help builder is not a function") + command.builder(yargs([])) + expect(KiloCli.workerTui({ _: [] })).toBe(false) + }) }) From 9af0f67c00df7e6d51c505f9c05aea47a044f520 Mon Sep 17 00:00:00 2001 From: marius-kilocode Date: Tue, 25 Aug 2026 16:32:33 +0200 Subject: [PATCH 2/2] fix(cli): avoid narrow shutdown runtime load --- packages/opencode/src/kilocode/cli/lazy-commands.ts | 4 ++++ packages/opencode/src/kilocode/cli/setup.ts | 1 + .../opencode/test/kilocode/cli/bootstrap-runtime.test.ts | 6 +++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/kilocode/cli/lazy-commands.ts b/packages/opencode/src/kilocode/cli/lazy-commands.ts index c9490e833b..b917fab6d1 100644 --- a/packages/opencode/src/kilocode/cli/lazy-commands.ts +++ b/packages/opencode/src/kilocode/cli/lazy-commands.ts @@ -19,6 +19,10 @@ export function hasLazyCommandSelection() { return selected } +export function resetLazyCommandSelection() { + selected = false +} + export function markLazyCommandSelection() { selected = true } diff --git a/packages/opencode/src/kilocode/cli/setup.ts b/packages/opencode/src/kilocode/cli/setup.ts index 3d1e8bae98..7557d3c88a 100644 --- a/packages/opencode/src/kilocode/cli/setup.ts +++ b/packages/opencode/src/kilocode/cli/setup.ts @@ -153,6 +153,7 @@ export namespace KiloCli { if (narrow) { const { KiloCliBootstrapRuntime } = await import("@/kilocode/cli/bootstrap-runtime") await KiloCliBootstrapRuntime.dispose() + return } const { InstanceRuntime } = await import("@/project/instance-runtime") await InstanceRuntime.disposeAllInstances() // safety net (no-op if already disposed) diff --git a/packages/opencode/test/kilocode/cli/bootstrap-runtime.test.ts b/packages/opencode/test/kilocode/cli/bootstrap-runtime.test.ts index 4bcbf15995..7f580e3b6f 100644 --- a/packages/opencode/test/kilocode/cli/bootstrap-runtime.test.ts +++ b/packages/opencode/test/kilocode/cli/bootstrap-runtime.test.ts @@ -1,9 +1,13 @@ -import { describe, expect, test } from "bun:test" +import { afterEach, beforeEach, describe, expect, test } from "bun:test" import { KiloCli } from "../../../src/kilocode/cli/setup" import { createHelpCommand } from "../../../src/kilocode/help-command" +import { resetLazyCommandSelection } from "../../../src/kilocode/cli/lazy-commands" import yargs from "yargs" describe("CLI bootstrap runtime selection", () => { + beforeEach(resetLazyCommandSelection) + afterEach(resetLazyCommandSelection) + test("uses the narrow runtime for worker-backed TUI launches", () => { expect(KiloCli.workerTui({ _: [] })).toBe(true) expect(KiloCli.workerTui({ _: ["./project"] })).toBe(true)