Skip to content

Add a built-in Kiro CLI ACP provider preset #3235

Description

@guanbear

The workflow

I want to use Kiro CLI as a final cross-model reviewer in a persisted bb Workflow:

  1. Run Codex planning and implementation/review stages.
  2. Start Kiro CLI through its stdio ACP server for the final review.
  3. Select an exact Kiro model and reasoning effort from bb (claude-opus-5, high).
  4. Keep the Kiro events, tool calls, and reasoning visible in the normal bb timeline.

Kiro CLI 2.21.1 already exposes the required interface:

kiro-cli acp [OPTIONS]
  --model <MODEL>
  --effort <EFFORT>
  --trust-all-tools

The workflow itself works, but configuring it in bb currently requires a custom ACP entry plus a local argument-reordering wrapper.

What happens today

Kiro is not included in KNOWN_ACP_AGENTS, so it is not detected or configured like OpenCode, omp, Grok Build, or Hermes:

export const KNOWN_ACP_AGENTS: readonly AcpAgentDefinition[] = [
{
id: "acp-cursor",
displayName: "Cursor",
icon: declaredIcon("cursor"),
iconTint: { light: "#111827", dark: "#F5F5F5" },
signInCommand: "cursor-agent login",
installUrl: "https://cursor.com/docs/cli/installation",
dialect: "cursor",
providerUsage: true,
providerInstallation: true,
parameterizedModelPicker: true,
primaryModels: [
"default",
"grok-4.6",
"gpt-5.6-sol",
"claude-opus-5",
"claude-fable-5",
"composer-2.5",
],
reasoningProbePriorityModelIds: ["grok-4.6", "grok-4.5"],
fork: "none",
launch: {
displayName: "Cursor",
command: "cursor-agent",
args: ["acp"],
env: {},
modelCli: {
listArgs: ["--list-models"],
primaryModels: [],
},
nativeSkillRoots: {
user: recursiveRoots([
".cursor/skills",
".agents/skills",
CLAUDE_SKILLS_ROOT,
".codex/skills",
]),
project: ancestorRoots(
recursiveRoots([
".cursor/skills",
".agents/skills",
CLAUDE_SKILLS_ROOT,
".codex/skills",
]),
),
},
},
nativeRootsResolver: resolveCursorNativeRoots,
},
{
id: "acp-opencode",
displayName: "opencode",
icon: declaredIcon("opencode"),
iconTint: { light: "#2563EB", dark: "#2563EB" },
signInCommand: "opencode auth login",
installUrl: "https://opencode.ai/docs",
visibility: "installed",
dialect: "opencode",
supportsManualCompaction: true,
fork: "tip",
launch: {
displayName: "opencode",
command: "opencode",
args: ["acp"],
env: {},
nativeSkillRoots: {
user: [CLAUDE_SKILLS_ROOT, ".agents/skills"],
project: ancestorRoots([
".opencode/skills",
CLAUDE_SKILLS_ROOT,
".agents/skills",
]),
},
},
nativeRootsResolver: resolveOpenCodeNativeRoots,
},
{
id: "acp-omp",
displayName: "omp",
icon: declaredIcon("omp"),
iconTint: { light: "#9333EA", dark: "#9333EA" },
signInCommand: "omp login",
installUrl: "https://github.com/can1357/omp",
visibility: "installed",
supportsManualCompaction: true,
fork: "tip",
launch: {
displayName: "omp",
command: "omp",
args: ["acp"],
env: {},
nativeSkillRoots: {
user: plainRoots([
".agent/skills",
".agents/skills",
CLAUDE_SKILLS_ROOT,
]),
project: ancestorRoots([
".omp/skills",
".pi/skills",
".agent/skills",
".agents/skills",
CLAUDE_SKILLS_ROOT,
".codex/skills",
".opencode/skills",
]),
},
},
nativeRootsResolver: resolveOmpNativeRoots,
},
{
id: "acp-grok",
displayName: "Grok Build",
icon: declaredIcon("grok"),
signInCommand: "grok login",
installUrl: "https://docs.x.ai/docs/grok-build",
visibility: "installed",
dialect: "grok",
fork: "none",
reasoningLevels: ["low", "medium", "high"],
launch: {
displayName: "Grok Build",
command: "grok",
args: ["agent", "stdio"],
env: {},
modelCli: {
listArgs: ["models"],
selectFlag: "--model",
primaryModels: ["grok-4.5", "grok-composer-2.5-fast"],
},
permissionCli: {
full: ["--always-approve"],
insertAfterArgs: 1,
},
reasoningCli: {
flag: "--reasoning-effort",
supportedLevels: ["low", "medium", "high"],
levelValues: {
none: "low",
xhigh: "high",
ultracode: "high",
max: "high",
},
defaultLevel: "high",
},
nativeSkillRoots: {
user: recursiveRoots([".agents/skills"]),
project: [
{ path: ".grok/skills", recursive: true, ancestors: true },
{ path: ".agents/skills", recursive: true, ancestors: true },
],
},
},
nativeRootsResolver: resolveGrokNativeRoots,
},
{
id: "acp-hermes-agent",

A custom agent can describe reasoningCli, but bb prepends its flag before the configured agent arguments:

async function resolveAgentLaunchArgs(
params: AcpSessionParams,
): Promise<{ args: string[]; warning: string | undefined }> {
const selection = params.modelSelection;
const agentArgs = applyPermissionCliArgs(
params.agent.args,
params.permissionCli,
params.permissionMode,
);
const prefixArgs: string[] = [];
let warning: string | undefined;
if (selection && "selectFlag" in selection) {
let resolved: string | undefined;
const variantReasoningLevel =
params.reasoningCli === undefined ? selection.reasoningLevel : undefined;
if (
variantReasoningLevel !== undefined ||
selection.serviceTier === "fast"
) {
const key = JSON.stringify(selection.listCommand);
const catalog =
cachedModelCatalog?.key === key
? cachedModelCatalog.catalog
: await loadAgentModelCatalog(selection.listCommand);
resolved = catalog?.resolveVariant({
model: selection.model,
reasoningLevel: variantReasoningLevel,
serviceTier: selection.serviceTier,
});
if (resolved === undefined && variantReasoningLevel !== undefined) {
warning = `Model "${selection.model}" has no ${variantReasoningLevel} reasoning variant; launching it at its default effort.`;
}
}
prefixArgs.push(selection.selectFlag, resolved ?? selection.model);
}
if (
params.reasoningCli !== undefined &&
params.launchReasoningLevel !== undefined
) {
const reasoningValue = resolveHintReasoningValue({
hint: params.reasoningCli,
reasoningLevel: params.launchReasoningLevel,
});
if (reasoningValue !== undefined) {
prefixArgs.push(params.reasoningCli.flag, reasoningValue);
} else if (warning === undefined) {
warning = `Reasoning level "${params.launchReasoningLevel}" is not supported by this ACP agent's launch flag; launching it at its default effort.`;
}
}
return {
args: [...prefixArgs, ...agentArgs],
warning,

For a direct configuration like this:

{
  "id": "kiro",
  "displayName": "Kiro CLI",
  "command": "kiro-cli",
  "args": ["acp"],
  "reasoningCli": {
    "flag": "--effort",
    "supportedLevels": ["low", "medium", "high", "xhigh", "max"],
    "defaultLevel": "high"
  }
}

bb constructs the equivalent of:

kiro-cli --effort high acp

but Kiro expects:

kiro-cli acp --effort high

The current workaround is a local kiro-bb-acp wrapper that accepts bb's prefix ordering and rewrites it before execing kiro-cli acp. With that wrapper, a real Workflow call succeeded and bb recorded:

provider: acp-kiro
model: claude-opus-5
reasoning: high
status: succeeded

The Kiro child thread also emitted normal reasoning and command-execution timeline events, so the underlying ACP bridge is compatible.

What you would expect

Preferably add Kiro CLI as an installed-only known ACP agent, so users with kiro-cli on PATH can select it without maintaining custom JSON or a wrapper.

The preset should preserve:

  • command: kiro-cli
  • ACP subcommand: acp
  • model selection through Kiro's ACP/model support
  • reasoning levels low, medium, high, xhigh, and max via --effort
  • full permission mapping via --trust-all-tools, while retaining safer bb permission modes where possible

If a built-in preset is not desired, a generic placement option for reasoningCli/modelCli analogous to permissionCli.insertAfterArgs would make direct custom configuration possible. For Kiro, the flags need to be inserted after the first configured argument (acp).

Acceptance criteria could be:

  1. An installed Kiro CLI appears as an ACP provider without custom wrapper code.
  2. Starting a thread with model claude-opus-5 and reasoning high launches kiro-cli acp --effort high (or applies the equivalent native ACP selection).
  3. The resolved model and reasoning remain visible in the thread/workflow metadata.
  4. Existing custom ACP providers retain their current argument ordering.

Context and alternatives

  • Verified with bb Desktop 0.42.1 on macOS 26.6 and Kiro CLI 2.21.1.
  • Verified against bb main at 06aeaa994942ae7527dc49d2268c1f801e8542a0.
  • Successful local Workflow run: wfr_7953418e-eaa6-45e0-a203-e61f33523b79; Kiro child thread: thr_sn5ky4um9s.
  • The workaround is functional but machine-local and easy to lose during migration.
  • I searched open and closed bb issues for Kiro, reasoningCli insertAfterArgs, and ACP subcommand flag placement and found no matching request.
  • I do not think this requires a Kiro-side issue: current Kiro CLI already exposes stdio ACP plus the required model, effort, and permission flags.

AGENT GENERATED

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    provider-acpBuilt-in plugin: provider-acpprovidersCross-provider bridges, models, login

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions