Repository navigation
feat(kilo-cli): add the Kilo host and the feature placement finder - #15232
Merged
Merged
Conversation
This was referenced Oct 19, 2026
eshurakov
approved these changes
Oct 19, 2026
# Conflicts: # migration-tracking/plans/v2-host-strategy.md
Contributor
|
➖ v2 migration progress: 0.1% → 0.1% (0 done, 0 total, 0 dropped; 12/9854 cells) No change to the progress map. |
This was referenced Oct 19, 2026
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #15229 (the host, plan unit U-E0-01, #15172, and the automation behind the
v2-feature-placementskill). Stacked on #15228.What Problem This Solves
The v2 line had no Kilo entry point.
bun devran the upstream CLI, so the only way to add a Kilo plugin was a marked line in an upstream built-in list (the Gateway inpackages/core/src/plugin/provider.ts). Every new Kilo feature would add another line to a shared upstream file. The placement skill also had no tool: its commands had to be run by hand, and several of them gave wrong answers.Why This Change Was Made
packages/kilo-cliis Kilo's entry.src/index.tsmirrorspackages/cli/src/index.ts(the upstream handler map, the same layers,Global.layerWithcomposition point) and adds KILO_* environment translation (src/env.ts), Kilo's app name (src/app.ts) and a serve handler (src/serve.ts, mirror of the upstream one) that passesKiloHost.overridesto the server.src/host.tsreplacesSdkPlugins.nodewith a node that registersKiloPluginsthroughSdkPlugins.register, and replacesApp.nodewith Kilo's app name.bun dev(script/dev-isolated.ts) starts this entry. The CLI builds every server command fromselfCommand(), so the background service,--standaloneandserve --stdioall run the host'sservewith the overrides.packages/kilo-pluginnow exportsKiloPlugins(the Gateway plugin). The Gateway registration leftprovider.ts; that file and its test are back to the upstream version. Upstream'sKiloPluginis back in the built-in list and runs before host-registered plugins; the Gateway overwrites its OpenCode referer and title (the core Gateway tests now run both in that order).SdkPlugins.registertyping seam. The loader gives a registered plugin only its Scope. The host provides the Gateway'sBuswithEffect.provideServicefrom the replacement node'sdeps, the same global Bus. Limit, recorded in the strategy and the skill: a Location service (for exampleSessionCompaction.Service) cannot be given this way; that needs one seam inplugin/supervisor.tswhen the first feature needs it.ServerProcess.starttakesoverridesand passes them tocreateRoutes, which already accepts them.Options.overridesinpackages/cli/src/server-process.tspasses them through.packages/cli/package.jsonexports./*like core, server and util. Each is inshared-patches.jsonwith its missing seam.env.tstranslates the 17 v1KILO_*names whoseOPENCODE_*name v2 reads (v1 flag modules onmainintersected with v2 reads). No prefix rule: v2 readsOPENCODE_API_KEYas the OpenCode Zen key, soKILO_API_KEYmust not be copied.bun devprofile moved into the host package (packages/kilo-cli/.gitignore), so its two root.gitignorelines went. The rootdevscript stays (it is the onlybun deventry, and upstream's script runs the upstream CLI with the real data). The README patch stays (a package does not own the front page). The other.gitignorepatterns are not host entries.["opencode", "serve", "--service"](packages/client/src/effect/service.ts:61) is never used by the CLI or TUI: they passselfCommand(), so the host spawns itself. The default stays for clients that pass no command (D-4). The TUI built-in list (KiloTeamsinpackages/tui/src/plugin/builtins.ts) keeps its marked line: the list is in the TUI process, whichSdkPluginsdoes not reach; a generic seam needs an@opencode/tuiexport plus an extension point (not fewer lines), and the config path (tui/src/plugin/context.tsx) loads only npm packages or local files, which a compiled binary does not have.bun script/upstream/placement.ts <path-or-module>prints, mechanically, the plugin domains and hooks that match a module, the upstream plugins that are or extend it, its service nodes with the host call, theOPENCODE_*variables it reads, existing seams and markers, whether the path is Kilo-owned, and a suggested first rung.--importsfails when a logic package (packages/kilo-*-core) imports@opencode/*and prints the distinct core-internal modules per adapter. CI runs--imports, and a newkilo packagesjob runs thekilo-pluginandkilo-clitests (Turborepo runs only the package tests listed inturbo.json; this avoids another shared patch)..kilo/skills/v2-feature-placement/SKILL.mdwas run under POSIXsh. Fixed: the hook listing (missed editor methods and non-readonly hooks), the upstream plugin search (**does not expand insh, and tool plugins have nodefine(), the node search for single-file areas, the environment search (missedpackages/util), the import checks (rg -ohprints help, so every count was 124), and the pre-commit patch checks (need--worktree). The host step now says where each kind of change goes.v2-migration,kilocode-merge-minimizerand the fork conventions say the host exists.User Impact
bun devstarts the Kilo host. The Kilo Gateway provider and the/teamscommands work as before; the plugin list showskilocode.gatewaywith sourcesdk.<repo>/.kilo-v2-devtopackages/kilo-cli/.kilo-v2-dev. Move an existing profile there, or keep usingKILO_V2_PROFILE.KILO_CONFIG_DIR,KILO_CONFIG_CONTENT,KILO_SERVER_PASSWORDand the other translated names now work on the v2 CLI.KiloPlugins, with no upstream edit.Evidence
Self-test (real CLI, isolated profiles,
--standalonewhere a service port could collide):vscode-self-testharness, signed in withKILO_API_KEYfrom the v1 auth file): processes arepackages/kilo-cli/src/index.ts --standaloneandpackages/kilo-cli/src/index.ts serve --stdio --port 0DeepSeek: DeepSeek V4.1 Flash(Kilo Gateway), asked forVERSIONinmath.ts: one search, answer1.2.3, no log errors/teamshows/team,/teams,/org,/orgs("Switch between Kilo Gateway teams")bun dev run --standalone --model kilo/deepseek/deepseek-v4.1-flash "Reply with only the word PONG"printsPONGbun dev plugin list --builtinlistskilocode.gateway sdk; the service process ispackages/kilo-cli/src/index.ts serve --service;bun dev modelslists the Gateway free models;bun dev service stopstops itAutomated checks:
bun testinpackages/kilo-cli(isolated HOME/XDG)kilocode.gateway(sdk, active) and serves the Kilo provider from a local Gateway fixture, and a host service smoke (service set port,service start,/api/plugin,service stopwith isolated HOME and XDG). A mutation check (upstream serve handler in the host) makes the service smoke failbun testinpackages/kilo-pluginbun test test/kilocode/gateway.test.ts test/plugin/provider-kilo.test.tsinpackages/corebun test test/process.test.tsinpackages/server;bun test test/kilocodeinpackages/cli(dev-isolatednow runs the host)bun testinpackages/cli(whole package)debug-paths.test.tscompareshomewith the real home, and my isolation setOPENCODE_TEST_HOME. It passes with only XDG isolatedbun run script/build.ts --single --skip-install, thenscript/service-smoke.tswith isolated HOME and XDGbun testandbun run typecheckinscript/upstreambun typecheckinpackages/kilo-cli,packages/kilo-plugin,packages/corebun run checkpackages/plugins/figmaand thetsgo -bpackages fail onzstdCompressSync: TypeScript also loads@types/node@22.13.9from the enclosing main checkout'snode_modules. Not related to the changebun script/check-shared-patches.ts,bun script/check-opencode-annotations.ts,bun script/check-workflows.tsbun script/upstream/progress.ts, then--checkShared-patch baseline (
check-shared-patches.ts):Two feature files retired (
provider.ts,provider-kilo.test.ts), three generic seam files added.filesrises by one, which is why the limit goes up in this PR.Import rule (
bun script/upstream/placement.ts --imports):packages/kilo-gateway-core0@opencode/*imports. Core-internal modules per adapter:packages/core/src/kilocode2 (bus, variant),packages/kilo-cli/src3 (app, bus, plugin/sdk: the host's composition seams),packages/kilo-plugin/src0 (its import of@opencode/core/kilocode/gatewayis Kilo-owned),packages/tui/src/kilocode0. Distinct total 4.Placement finder on the strategy's examples:
session/compaction.tsgives thesession.compactionhook,opencode.config.compaction(transform onSessionCompaction.Service) and a location node;tool/plugin/grep.tsgives the file asopencode.tool.grepwith the tool hooks andToolEditor.update("grep", ...);util/src/global.tsgives no hook andGlobal.node.replace(Global.layerWith(...)).Progress map: no change, 12/9854 before and after. The host is v2 infrastructure with no v1 cell; no disposition added.
Skipped tests: none. Mirrored files:
packages/kilo-cli/src/index.ts(frompackages/cli/src/index.ts) andpackages/kilo-cli/src/serve.ts(frompackages/cli/src/commands/handlers/serve.ts), both at v2.0.30.Limits: only the free and DeepSeek V4.1 Flash models were exercised; team switching was not run.
Placement
Global.layerWithpointpackages/kilo-cli/src/{index,serve,app}.ts(index and serve are mirrors)SdkPlugins.register, Bus provided by the hostpackages/kilo-cli/src/host.ts,KiloPluginsinpackages/kilo-plugin/src/index.ts;provider.tsback to upstreamKILO_*environment translationpackages/kilo-cli/src/env.tsscript/dev-isolated.ts,packages/kilo-cli/.gitignore; 2 root.gitignorelines removedoverridesonServerProcess.startpackages/server/src/process.ts, 3 lineskilocode_change(host) seamOptions.overridespass-throughServerProcess.runbuilt the server options itselfpackages/cli/src/server-process.ts, 2 lineskilocode_change(host) seam./*export of@opencode/cli./runand./server-process, so no entry could reachCommands,Runtimeor a handlerpackages/cli/package.json, 1 unmarked JSON lineSdkPlugins.registertypingEffect.provideServiceKiloTeamsTUI registrationpackages/tui/src/plugin/builtins.ts, seam text updateddevscript, READMEshared-patches.jsontexts updatedplacement.ts, tests, CI jobs, skillsscript/upstream/placement.ts,.github/workflows/kilo-v2.ymlShared files touched:
packages/server/src/process.ts(3),packages/cli/src/server-process.ts(3),packages/cli/package.json(3),.gitignore(3, two lines removed),packages/core/src/plugin/provider.tsandpackages/core/test/plugin/provider-kilo.test.ts(restored to upstream). Core-internal imports added:@opencode/core/app,@opencode/core/bus,@opencode/core/plugin/sdkin the host.