Skip to content

Commit 1012bdb

Browse files
hrishi maneclaude
andcommitted
feat(kiro): add Kiro ACP provider with agent picker, /agent command, and Opus 4.7
Adds Kiro as a first-class ACP provider layered on top of upstream's shared ACP infrastructure (PR pingdotgg#1355). Kiro is an Amazon CLI (`kiro-cli acp`) speaking the Agent Communication Protocol over stdio; authentication is OIDC via `kiro-cli login` (out-of-band). Highlights: - Full ACP lifecycle: initialize → session/new → session/prompt/cancel, with streaming `session/update` notifications and `{stopReason: "end_turn"}` turn end via RPC response. - Agent discovery via `kiro-cli agent list`, cached at `~/.t3/caches/kiro.json` and surfaced through `ModelCapabilities.agentOptions`. Agents are a spawn-time CLI flag (`--agent <name>`) so `sendTurn` respawns the child process when the selected agent changes mid-session. - `/agent` slash command opens the TraitsPicker, mirroring `/model`. Gated on whether the current model exposes `agentOptions`. - TraitsPicker now closes on agent selection (`closeOnClick` MenuRadioItem). - `normalizeProviderModelOptionsWithCapabilities` gains a `case "kiro"` — previously the kiro dispatch path dropped `{ agent }` silently because the switch fell through to `undefined`, so the server never received the agent selection even though the composer store held it. - `_kiro.dev/commands/available` notifications runtime-patch slash commands; `_kiro.dev/metadata` surfaces context window usage. - Built-in Kiro models include Opus 4.7 (aliased as `opus`), Sonnet 4.6, Haiku 4.5, Deepseek 3.2. Hidden traps documented in PATCH.md: - Three hardcoded ProviderKind arrays in `composerDraftStore.ts` all need `"kiro"` or model selection silently reverts to previous provider. - `normalizeProviderModelOptionsWithCapabilities` switch needs an explicit `case "kiro"` or agent selection never reaches the server. - ACP `authMethodId` is made optional: Kiro returns empty `authMethods` and per spec the client must skip `authenticate`. - `_kiro.dev/*` ext requests the adapter doesn't handle must return JSON-RPC error `-32601` (not empty-object success). - `mcpServers: []` is required in `session/new`; omission exits kiro-cli silently. Test coverage: - `KiroAdapter.integration.test.ts` — 8 tests covering start/stop/listSessions, streaming, runtime events, agent flag propagation, respawn on agent change. - `KiroAdapter.parsing.test.ts` — ACP message parsing. - `packages/shared/src/model.test.ts` — 4 new tests for `normalizeKiro*` and provider-switch wiring. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent f6978db commit 1012bdb

37 files changed

Lines changed: 2898 additions & 61 deletions

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
registry=https://registry.npmjs.org/

AGENTS.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,11 @@ Docs:
5151
- Codex-Monitor (Tauri, feature-complete, strong reference implementation): https://github.com/Dimillian/CodexMonitor
5252

5353
Use these as implementation references when designing protocol handling, UX flows, and operational safeguards.
54+
55+
## Fork-specific: Kiro Provider
56+
57+
This repo (`t3code-kiro`) is a fork of `pingdotgg/t3code` that patches a Kiro ACP provider on top of upstream. Before making changes that touch providers, the composer, or ACP:
58+
59+
- Read `PATCH.md` for the maintenance guide (sync workflow, conflict zones, verification checklist).
60+
- Read `docs/KIRO.md` for Kiro ACP protocol notes (OIDC auth, `_kiro.dev/*` ext methods, agent discovery).
61+
- Adding a new provider requires updating **three** hardcoded `ProviderKind` arrays in `apps/web/src/composerDraftStore.ts` — see "Hidden Traps" in `PATCH.md`. Missing one produces a silent no-op (model selection reverts in UI with no error).

PATCH.md

Lines changed: 355 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#!/usr/bin/env bun
2+
/**
3+
* Mock ACP agent that imitates kiro-cli ACP protocol for integration tests.
4+
*
5+
* Responds to: initialize, session/new, session/prompt, session/cancel.
6+
* Emits: session/update (agent_message_chunk), _kiro.dev/metadata extension.
7+
*/
8+
import * as Effect from "effect/Effect";
9+
10+
import * as NodeServices from "@effect/platform-node/NodeServices";
11+
import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
12+
13+
import * as EffectAcpAgent from "effect-acp/agent";
14+
15+
const sessionId = "kiro-mock-session-1";
16+
17+
const program = Effect.gen(function* () {
18+
const agent = yield* EffectAcpAgent.AcpAgent;
19+
20+
yield* agent.handleInitialize(() =>
21+
Effect.succeed({
22+
protocolVersion: 1,
23+
agentCapabilities: {},
24+
agentInfo: {
25+
name: "kiro-mock-agent",
26+
version: "0.0.0",
27+
},
28+
}),
29+
);
30+
31+
yield* agent.handleAuthenticate(() => Effect.succeed({}));
32+
33+
yield* agent.handleCreateSession(() =>
34+
Effect.succeed({
35+
sessionId,
36+
}),
37+
);
38+
39+
yield* agent.handleLoadSession(() => Effect.succeed({}));
40+
41+
yield* agent.handleCancel(() => Effect.void);
42+
43+
yield* agent.handlePrompt((request) =>
44+
Effect.gen(function* () {
45+
const requestedSessionId = String(request.sessionId ?? sessionId);
46+
47+
// Emit a content delta
48+
yield* agent.client.sessionUpdate({
49+
sessionId: requestedSessionId,
50+
update: {
51+
sessionUpdate: "agent_message_chunk",
52+
content: { type: "text", text: "hello from kiro mock" },
53+
},
54+
});
55+
56+
// Emit kiro metadata extension notification
57+
yield* agent.client.extNotification("_kiro.dev/metadata", {
58+
contextUsagePercentage: 10,
59+
});
60+
61+
return { stopReason: "end_turn" };
62+
}),
63+
);
64+
65+
yield* agent.handleUnknownExtRequest((_method, _params) => Effect.succeed({}));
66+
67+
return yield* Effect.never;
68+
}).pipe(
69+
Effect.provide(EffectAcpAgent.layerStdio()),
70+
Effect.scoped,
71+
Effect.provide(NodeServices.layer),
72+
);
73+
74+
NodeRuntime.runMain(program);

apps/server/src/git/Services/TextGeneration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import type { ChatAttachment, ModelSelection } from "@t3tools/contracts";
1313
import type { TextGenerationError } from "@t3tools/contracts";
1414

1515
/** Providers that support git text generation (commit messages, PR content, branch names). */
16-
export type TextGenerationProvider = "codex" | "claudeAgent" | "cursor" | "opencode";
16+
export type TextGenerationProvider = "codex" | "claudeAgent" | "cursor" | "opencode" | "kiro";
1717

1818
export interface CommitMessageGenerationInput {
1919
cwd: string;

0 commit comments

Comments
 (0)