Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# [2.47.0-beta.1](https://github.com/chadbyte/clay/compare/v2.46.0...v2.47.0-beta.1) (2026-07-20)


### Features

* **codex:** add GPT-5.6 sol/terra/luna models ([#384](https://github.com/chadbyte/clay/issues/384)) ([cd56498](https://github.com/chadbyte/clay/commit/cd564984a467926e80e773bc400f3311172bc105))

# [2.46.0](https://github.com/chadbyte/clay/compare/v2.45.0...v2.46.0) (2026-07-03)


Expand Down
28 changes: 10 additions & 18 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -1359,24 +1359,16 @@ function setup(callback) {
}
port = p;
log(sym.bar);
askMode();
// No "single vs multi" question anymore: every deploy runs in the
// (general) multi-user model. Solo users get an auto-provisioned
// default admin with no PIN and no login wall. OS-level user
// isolation stays an opt-in, offered here on Linux and toggleable
// later; everything else is just multi-user.
askOsUsers("multi");
});
});
}

function askMode() {
promptSelect("How will you use Clay?", [
{ label: "Just me (single user)", value: "single" },
{ label: "Multiple users", value: "multi" },
], function (mode) {
if (mode === "single") {
finishSetup(mode, false);
} else {
askOsUsers(mode);
}
});
}

function askOsUsers(mode) {
// Only offer OS user isolation on Linux
if (process.platform !== "linux") {
Expand Down Expand Up @@ -1554,7 +1546,7 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
keepAwake: keepAwake,
dangerouslySkipPermissions: dangerouslySkipPermissions,
osUsers: wantOsUsers || osUsersMode,
mode: mode || "single",
mode: mode || "multi",
setupCompleted: true,
projects: allProjects,
});
Expand Down Expand Up @@ -1729,7 +1721,7 @@ async function devMode(mode, keepAwake, existingPinHash, wantOsUsers) {
debug: true,
keepAwake: keepAwake || false,
dangerouslySkipPermissions: dangerouslySkipPermissions,
mode: mode || "single",
mode: mode || "multi",
setupCompleted: true,
projects: allProjects,
osUsers: wantOsUsers || (prevDevConfig ? (prevDevConfig.osUsers || false) : false),
Expand Down Expand Up @@ -2667,7 +2659,7 @@ var currentVersion = require("../package.json").version;
});
} else {
// Reuse existing config (repeat run)
await devMode(devConfig.mode || "single", devConfig.keepAwake || false, devConfig.pinHash || null, devConfig.osUsers || false);
await devMode(devConfig.mode || "multi", devConfig.keepAwake || false, devConfig.pinHash || null, devConfig.osUsers || false);
}
return;
}
Expand Down Expand Up @@ -2767,7 +2759,7 @@ var currentVersion = require("../package.json").version;

if (isRepeatRun || autoYes) {
// Repeat run or --yes: skip wizard, reuse saved config
var savedMode = (savedConfig && savedConfig.mode) || "single";
var savedMode = (savedConfig && savedConfig.mode) || "multi";
var savedKeepAwake = (savedConfig && savedConfig.keepAwake) || false;
var savedOsUsers = (savedConfig && savedConfig.osUsers) || false;

Expand Down
86 changes: 86 additions & 0 deletions docs/guides/KIRO-INTEGRATION-SUMMARY.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Kiro CLI Integration — Summary

> Adds AWS **Kiro CLI** as a first-class agent runtime in Clay, alongside
> Claude Code and Codex, through the YOKE adapter layer.

## Goal

Make `kiro-cli` usable inside Clay exactly like Claude Code or Codex: pick the
vendor, create a session, chat, approve tools, and switch models — with no
user-visible difference between runtimes.

## How it works

Kiro CLI exposes the **Agent Client Protocol (ACP)** via `kiro-cli acp` —
standard JSON-RPC 2.0 over stdin/stdout, the same editor-agnostic agent
protocol used by Zed. This mirrors the transport strategy Clay already uses for
`codex app-server`.

```
Clay session (vendor=kiro)
-> YOKE Kiro Adapter (lib/yoke/adapters/kiro.js)
-> KiroAcpServer (lib/yoke/kiro-acp-server.js) spawn `kiro-cli acp`
-> kiro-cli binary (JSON-RPC 2.0 over stdio)
```

### Protocol lifecycle (verified against kiro-cli 2.7.0)

| Step | Method | Notes |
|------|--------|-------|
| Handshake | `initialize` | negotiates `agentCapabilities` |
| Create | `session/new` | returns `{ sessionId, modes, models }` |
| Resume | `session/load` | replays history |
| Model | `session/set_model` | `{ sessionId, modelId }` |
| Prompt | `session/prompt` | field is **`prompt`** (array of blocks); resolves with `{ stopReason }` |
| Stream | `session/update` | discriminated by `update.sessionUpdate` |
| Approve | `session/request_permission` | server→client request; reply `{ outcome: { outcome: "selected", optionId } }` |
| Abort | `session/cancel` | notification; in-flight prompt resolves `"cancelled"` |

## Files added

| File | Purpose |
|------|---------|
| `lib/yoke/kiro-acp-server.js` | Child-process JSON-RPC transport (binary lookup, send/notify/respond, auth-error detection) |
| `lib/yoke/adapters/kiro.js` | YOKE adapter: dynamic model catalog, session lifecycle, `session/update` event flattening, permission routing, resume, abort |
| `lib/kiro-defaults.js` | Single source of truth for Kiro defaults (agent/mode) |
| `lib/public/kiro-avatar.svg` | Branded avatar |
| `docs/guides/KIRO-INTEGRATION.md` | Full protocol reference + gotchas |

## Files changed (wiring — mirrors every `codex` touch-point)

- `lib/yoke/index.js` — factory switch, auth (`kiro-cli whoami`), install detection, `createAdapters`
- `lib/sdk-bridge.js` — `detectInstalledVendors`, login command, `KIRO` adapterOptions, neutral interrupt message
- `lib/sdk-message-processor.js`, `lib/project-notifications.js` — auth titles / login command
- `lib/project-sessions.js` — GUI-only session mode for kiro (no TUI adapter)
- Client UI: `index.html` (vendor toggle), `sidebar-sessions.js` / `sidebar-mobile.js` (new-session buttons, install-gated), `app-panels.js` (vendor button + effort levels), `app-rendering.js` / `app-messages.js` / `input.js` / `tools.js` / `mate-sidebar.js` / `sidebar-mates.js` (avatar & name maps)

## Key design decisions

- **Dynamic model catalog** (like Claude, unlike Codex's hardcoded list):
`init()` runs `kiro-cli chat --list-models --format json` and filters out
`[Internal]` / `[Deprecated]` entries. Default is the `auto` router model.
- **Permission name recovery**: the `session/request_permission` payload only
carries `{ toolCallId, title }`, so the adapter caches `kind` + `rawInput`
from the preceding `tool_call` notification and passes the canonical tool
name (`Bash`, `Edit`, ...) to `canUseTool`. Without this, Clay's permission
whitelist matching would break.
- **GUI-only**: kiro sessions always run in GUI mode, same as Codex.
- **Per-project adapter**: the ACP process is scoped to a project cwd/slug.

## Verified end-to-end (against the live binary)

- Init discovers 15 curated models; default `auto`
- Text streams in real time; `result` emitted with usage
- Model selection works (`session/set_model`)
- Bash tool shows approval with canonical name `Bash` + `{command}`; approve/deny routes through `canUseTool`
- Abort interrupts the turn cleanly
- Registers alongside claude/codex in the daemon adapter path

## Known gaps

- Bash `tool_result` content came through empty in the probe (output likely
arrives via a later `tool_call_update` shape); Codex behaves similarly — worth
confirming in the live UI.
- Validated via adapter/daemon-path harnesses, not a live browser session (the
first-run consent wizard requires a TTY). The WebSocket UI paths are wired but
not exercised in a browser.
84 changes: 84 additions & 0 deletions docs/guides/KIRO-INTEGRATION-SUMMARY.ko.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Kiro CLI 통합 — 요약

> AWS **Kiro CLI**를 YOKE 어댑터 계층을 통해 Claude Code, Codex와 나란히
> Clay의 1급 에이전트 런타임으로 추가합니다.

## 목표

`kiro-cli`를 Clay 안에서 Claude Code나 Codex와 똑같이 사용할 수 있게 만듭니다:
벤더 선택, 세션 생성, 대화, 도구 승인, 모델 전환 — 런타임 간 차이를 사용자가
느끼지 못하도록.

## 동작 방식

Kiro CLI는 `kiro-cli acp`를 통해 **Agent Client Protocol(ACP)**을 노출합니다 —
stdin/stdout 기반의 표준 JSON-RPC 2.0로, Zed 등이 사용하는 에디터 독립적
에이전트 프로토콜입니다. Clay가 이미 `codex app-server`에 쓰는 트랜스포트
전략과 동일합니다.

```
Clay 세션 (vendor=kiro)
-> YOKE Kiro 어댑터 (lib/yoke/adapters/kiro.js)
-> KiroAcpServer (lib/yoke/kiro-acp-server.js) `kiro-cli acp` 실행
-> kiro-cli 바이너리 (stdio 기반 JSON-RPC 2.0)
```

### 프로토콜 생명주기 (kiro-cli 2.7.0로 검증)

| 단계 | 메서드 | 비고 |
|------|--------|------|
| 핸드셰이크 | `initialize` | `agentCapabilities` 협상 |
| 생성 | `session/new` | `{ sessionId, modes, models }` 반환 |
| 재개 | `session/load` | 히스토리 재생 |
| 모델 | `session/set_model` | `{ sessionId, modelId }` |
| 프롬프트 | `session/prompt` | 필드명은 **`prompt`**(블록 배열); `{ stopReason }`으로 resolve |
| 스트리밍 | `session/update` | `update.sessionUpdate`로 구분 |
| 승인 | `session/request_permission` | 서버→클라이언트 요청; `{ outcome: { outcome: "selected", optionId } }`로 응답 |
| 중단 | `session/cancel` | 알림(notification); 진행 중 프롬프트는 `"cancelled"`로 resolve |

## 추가한 파일

| 파일 | 목적 |
|------|------|
| `lib/yoke/kiro-acp-server.js` | 자식 프로세스 JSON-RPC 트랜스포트 (바이너리 탐색, send/notify/respond, 인증 오류 감지) |
| `lib/yoke/adapters/kiro.js` | YOKE 어댑터: 동적 모델 목록, 세션 생명주기, `session/update` 이벤트 변환, 권한 라우팅, 재개, 중단 |
| `lib/kiro-defaults.js` | Kiro 기본값(agent/mode) 단일 소스 |
| `lib/public/kiro-avatar.svg` | 브랜드 아바타 |
| `docs/guides/KIRO-INTEGRATION.md` | 전체 프로토콜 참조 + 주의사항 |

## 수정한 파일 (연결 작업 — 모든 `codex` 접점 미러링)

- `lib/yoke/index.js` — 팩토리 분기, 인증(`kiro-cli whoami`), 설치 감지, `createAdapters`
- `lib/sdk-bridge.js` — `detectInstalledVendors`, 로그인 명령, `KIRO` adapterOptions, 중립적 중단 메시지
- `lib/sdk-message-processor.js`, `lib/project-notifications.js` — 인증 타이틀 / 로그인 명령
- `lib/project-sessions.js` — kiro는 GUI 전용 세션 모드 (TUI 어댑터 없음)
- 클라이언트 UI: `index.html`(벤더 토글), `sidebar-sessions.js` / `sidebar-mobile.js`(새 세션 버튼, 설치 시에만 노출), `app-panels.js`(벤더 버튼 + effort 레벨), `app-rendering.js` / `app-messages.js` / `input.js` / `tools.js` / `mate-sidebar.js` / `sidebar-mates.js`(아바타·이름 맵)

## 핵심 설계 결정

- **동적 모델 목록** (Claude와 동일, Codex의 하드코딩 목록과 다름):
`init()`이 `kiro-cli chat --list-models --format json`을 실행하고
`[Internal]` / `[Deprecated]` 항목을 필터링합니다. 기본값은 `auto` 라우터 모델.
- **권한 이름 복원**: `session/request_permission` 페이로드에는
`{ toolCallId, title }`만 담기므로, 어댑터가 직전 `tool_call` 알림의
`kind` + `rawInput`을 캐시해 정식 도구 이름(`Bash`, `Edit` 등)을
`canUseTool`에 전달합니다. 이게 없으면 Clay의 권한 화이트리스트 매칭이 깨집니다.
- **GUI 전용**: kiro 세션은 Codex와 마찬가지로 항상 GUI 모드로 동작합니다.
- **프로젝트별 어댑터**: ACP 프로세스는 프로젝트 cwd/slug 단위로 스코프됩니다.

## 실제 바이너리로 검증 완료

- init 시 15개 큐레이션 모델 노출; 기본값 `auto`
- 텍스트 실시간 스트리밍; `result` 이벤트에 사용량 포함
- 모델 선택 동작 (`session/set_model`)
- Bash 도구가 정식 이름 `Bash` + `{command}`로 승인 UI 표시; 승인/거부가 `canUseTool`로 라우팅
- 중단(abort)이 턴을 깔끔하게 정리
- 데몬 어댑터 경로에서 claude/codex와 나란히 등록

## 알려진 미비점

- 프로브에서 Bash `tool_result` 내용이 비어 있었습니다(출력이 이후
`tool_call_update` 형태로 오는 것으로 추정); Codex도 유사하게 동작 — 실제
UI에서 확인 권장.
- 최초 실행 동의 마법사가 TTY를 요구하여, 브라우저 세션 대신 어댑터/데몬 경로
하네스로 검증했습니다. WebSocket UI 경로는 연결됐지만 브라우저에서는 미검증.
Loading