@kyo-so/cli 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.ja.md +1 -1
- package/README.md +44 -7
- package/README.zh-CN.md +1 -1
- package/dist/acp/AcpAgentProcess.d.ts +4 -1
- package/dist/acp/AgentOutputAccumulator.d.ts +29 -0
- package/dist/acp/codexRetryUpdate.d.ts +6 -0
- package/dist/bin/kyoso.js +1752 -692
- package/dist/cli/pluginRuntimeContract.d.ts +4 -4
- package/dist/cli/progress.d.ts +5 -0
- package/dist/config/projectScope.d.ts +1 -1
- package/dist/config/schema.d.ts +6 -0
- package/dist/core/constants.d.ts +1 -1
- package/dist/core/errors.d.ts +5 -0
- package/dist/core/progress.d.ts +83 -0
- package/dist/core/progressDispatcher.d.ts +12 -0
- package/dist/core/reviewBudget.d.ts +8 -0
- package/dist/core/runReview.d.ts +4 -0
- package/dist/core/types.d.ts +35 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1518 -659
- package/dist/judge/provider.d.ts +1 -0
- package/dist/judge/signals.d.ts +4 -0
- package/dist/mcp/progress.d.ts +18 -0
- package/dist/utils/env.d.ts +5 -1
- package/examples/kyoso.toml +7 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,43 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.15.0] - 2026-07-21
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Add `agents.codex.openRouter` retry configuration for OpenRouter Codex
|
|
15
|
+
reviews. It maps idle timeout, stream retries, and request retries to the
|
|
16
|
+
fixed provider preset without changing omitted Codex runtime defaults.
|
|
17
|
+
- Record observed ACP stream retries, discarded retry-message bytes, and ACP
|
|
18
|
+
output timestamps in model-call audit records and JSONL trace events.
|
|
19
|
+
- Add typed core review-progress events, bounded non-blocking progress delivery,
|
|
20
|
+
CLI stderr renderers (`auto`, `plain`, `jsonl`, and `off`), and graceful
|
|
21
|
+
SIGINT cancellation through primary and verifier ACP subprocesses.
|
|
22
|
+
- Add MCP `notifications/progress` support when a client provides a
|
|
23
|
+
`progressToken`, with per-request monotonic sequences and fixed-field messages.
|
|
24
|
+
Whether progress is displayed remains client-dependent.
|
|
25
|
+
- Propagate MCP cancellation through primary and verification ACP subprocesses
|
|
26
|
+
and in-flight OpenAI or Anthropic judge calls without converting cancellation
|
|
27
|
+
into a normal result or judge fallback.
|
|
28
|
+
- Add a release-gated mock Responses SSE integration suite for the pinned Codex
|
|
29
|
+
ACP adapter, covering stream retries and exhaustion without credentials or an
|
|
30
|
+
externally configurable provider base URL.
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- Prevent incomplete Codex message chunks from leaking into final agent output
|
|
35
|
+
after a structured stream retry, while retaining full wire-byte accounting
|
|
36
|
+
and output-limit enforcement.
|
|
37
|
+
- Bound retry-progress trace writes per primary agent and preserve retry
|
|
38
|
+
metrics when an output cap stops a session.
|
|
39
|
+
- Treat a terminal Codex ACP system error as a failed agent result even when
|
|
40
|
+
the adapter returns an ACP `end_turn` response.
|
|
41
|
+
|
|
42
|
+
### Changed
|
|
43
|
+
|
|
44
|
+
- Promote the Marketplace Plugin to `0.7.3` and pin its Codex and Claude Code
|
|
45
|
+
MCP definitions and Skill fallbacks to `@kyo-so/cli@0.14.0`.
|
|
46
|
+
|
|
10
47
|
## [0.14.0] - 2026-07-19
|
|
11
48
|
|
|
12
49
|
### Changed
|
package/README.ja.md
CHANGED
|
@@ -154,7 +154,7 @@ Use Kyoso diff_review on the current diff. I need a second opinion before mergin
|
|
|
154
154
|
|
|
155
155
|
## CLI
|
|
156
156
|
|
|
157
|
-
package-runner の実行経路では、package と executable を必ず別指定します: `npx -y --package=@kyo-so/cli kyoso` と `bunx --package @kyo-so/cli kyoso` です。workflowで固定する場合は、`@kyo-so/cli@0.
|
|
157
|
+
package-runner の実行経路では、package と executable を必ず別指定します: `npx -y --package=@kyo-so/cli kyoso` と `bunx --package @kyo-so/cli kyoso` です。workflowで固定する場合は、`@kyo-so/cli@0.14.0` のようにpackage名へcomplete SemVer pinを付けます。以下の例の `kyoso` は、すでにインストールされた executable の省略形です。Naming note: npm パッケージは `@kyo-so/cli` (製品名 Kyo-so に対応) で、インストールされる CLI コマンドは短い `kyoso` です。
|
|
158
158
|
|
|
159
159
|
Bun fallback は Bun `1.3.14` で検証済みです。古い Bun では npx 形式またはインストール済みの `kyoso` を使い、複数bin packageからの Bun のbinary推論に依存しないでください。
|
|
160
160
|
|
package/README.md
CHANGED
|
@@ -152,7 +152,7 @@ Manual setup examples are kept in `examples/codex-config.toml` and `examples/cla
|
|
|
152
152
|
|
|
153
153
|
## CLI
|
|
154
154
|
|
|
155
|
-
The package-runner execution paths always select the package and executable separately: `npx -y --package=@kyo-so/cli kyoso` and `bunx --package @kyo-so/cli kyoso`. Add a complete SemVer pin after the package name when a workflow needs one, for example `@kyo-so/cli@0.
|
|
155
|
+
The package-runner execution paths always select the package and executable separately: `npx -y --package=@kyo-so/cli kyoso` and `bunx --package @kyo-so/cli kyoso`. Add a complete SemVer pin after the package name when a workflow needs one, for example `@kyo-so/cli@0.14.0`. The examples below abbreviate an already installed executable as `kyoso`. Naming note: the npm package is `@kyo-so/cli` (matching the product name Kyo-so), while the installed CLI command is the shorter `kyoso`.
|
|
156
156
|
|
|
157
157
|
The Bun fallback is verified on Bun `1.3.14`. On an older Bun, use the npx form or an installed `kyoso`; do not rely on Bun inferring a binary from a multi-bin package.
|
|
158
158
|
|
|
@@ -168,6 +168,36 @@ kyoso setup codex --write --skill-only
|
|
|
168
168
|
kyoso setup claude-code --write --skill-only
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
+
### Progress and cancellation
|
|
172
|
+
|
|
173
|
+
Review results always use stdout: Markdown by default and JSON with `--json`.
|
|
174
|
+
Progress and errors use stderr, so structured output remains pipe-safe.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
kyoso plan --goal "Review this plan" --plan plan.md --json --progress jsonl \
|
|
178
|
+
>result.json 2>progress.jsonl
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`--progress auto|plain|jsonl|off` defaults to `auto`: it shows plain,
|
|
182
|
+
line-oriented progress only when stderr is a TTY. Use `plain` to force
|
|
183
|
+
human-readable stderr output, `jsonl` for one typed event per stderr line, or
|
|
184
|
+
`off` to suppress progress. Progress never includes prompts, selected-file
|
|
185
|
+
contents, diffs, or model message/thought text.
|
|
186
|
+
|
|
187
|
+
Press Ctrl-C once to request graceful cancellation of the review and its ACP
|
|
188
|
+
child agents; Kyoso exits with status 130 after cleanup. Press it a second time
|
|
189
|
+
to force immediate exit.
|
|
190
|
+
|
|
191
|
+
For MCP tools, Kyoso sends `notifications/progress` only when the client supplies
|
|
192
|
+
a `progressToken` in request metadata. Each request receives its own monotonically
|
|
193
|
+
increasing sequence and no `total`, because review work is dynamic. Kyoso supports
|
|
194
|
+
MCP progress notifications when the client requests them; whether progress is
|
|
195
|
+
displayed is controlled by the MCP client.
|
|
196
|
+
|
|
197
|
+
An MCP `notifications/cancelled` request aborts the review, including primary and
|
|
198
|
+
verification ACP subprocesses and an in-flight LLM judge. A cancelled tool call is
|
|
199
|
+
not converted into a normal review result. MCP stdout remains JSON-RPC only.
|
|
200
|
+
|
|
171
201
|
## Usage Examples
|
|
172
202
|
|
|
173
203
|
Review an implementation plan with selected code:
|
|
@@ -291,7 +321,7 @@ Kyoso loads config in this order:
|
|
|
291
321
|
|
|
292
322
|
Unknown keys are rejected. Boolean and numeric config keys are converted to their schema types; string keys remain strings. The complete config is then validated.
|
|
293
323
|
|
|
294
|
-
Project `kyoso.toml` is declarative and does not require trust approval. It can set safe project-scoped keys such as agent `enabled` / `model` / `effort` / `role` / `timeoutMs`, the Codex-only `provider
|
|
324
|
+
Project `kyoso.toml` is declarative and does not require trust approval. It can set safe project-scoped keys such as agent `enabled` / `model` / `effort` / `role` / `timeoutMs`, the Codex-only `provider`, OpenRouter model, or retry-policy override after user-global authorization, workspace byte limits and additive `workspace.deny`, verification settings, advisory judge settings, and tightening-only security/network/CISA settings.
|
|
295
325
|
|
|
296
326
|
`entrypoints.*`, `tools.*`, and `reviewPolicy.*` are user-global policy. A disabled entrypoint or tool returns a structured policy block before agents start. `firstClassClient = "codex"`, `workspace.readOnly = true`, `network.mediatedWeb.enabled = false`, and `audit.includeFileContents = false` are fixed or reserved values; unsupported values are rejected instead of acting as no-ops.
|
|
297
327
|
|
|
@@ -310,7 +340,7 @@ CODEX_CONFIG = '{"model":"gpt-5.5"}'
|
|
|
310
340
|
|
|
311
341
|
### Agents
|
|
312
342
|
|
|
313
|
-
Agent keys: `agents.<codex|claude>.<enabled|model|effort|role|timeoutMs>`. Codex also supports `agents.codex.provider`: `"openrouter"` selects the external provider, while `"default"` resets an inherited OpenRouter selection to normal Codex behavior; Claude has no provider setting. Selecting the provider from a project requires the global-config-only `agents.codex.allowProjectProvider` allowlist; see [Codex OpenRouter project opt-in](#codex-openrouter-project-opt-in) for the full rules. The `command`, `args`, and `env` keys are also global-config-only (see [Files and precedence](#files-and-precedence)).
|
|
343
|
+
Agent keys: `agents.<codex|claude>.<enabled|model|effort|role|timeoutMs>`. Codex also supports `agents.codex.provider`: `"openrouter"` selects the external provider, while `"default"` resets an inherited OpenRouter selection to normal Codex behavior; Claude has no provider setting. `agents.codex.openRouter.streamIdleTimeoutMs`, `streamMaxRetries`, and `requestMaxRetries` configure the selected OpenRouter transport only. Selecting the provider or changing that retry policy from a project requires the global-config-only `agents.codex.allowProjectProvider` allowlist; see [Codex OpenRouter project opt-in](#codex-openrouter-project-opt-in) for the full rules. The `command`, `args`, and `env` keys are also global-config-only (see [Files and precedence](#files-and-precedence)).
|
|
314
344
|
|
|
315
345
|
Omit `agents.<name>.model` or `agents.<name>.effort` to use each agent's own default. Codex uses the local Codex config, such as `~/.codex/config.toml` (or `$CODEX_HOME/config.toml` when `CODEX_HOME` is set); Claude uses the adapter default.
|
|
316
346
|
|
|
@@ -350,13 +380,20 @@ Then opt in only in the project that needs OpenRouter:
|
|
|
350
380
|
[agents.codex]
|
|
351
381
|
provider = "openrouter"
|
|
352
382
|
model = "openai/o4-mini"
|
|
383
|
+
|
|
384
|
+
[agents.codex.openRouter]
|
|
385
|
+
streamIdleTimeoutMs = 90000
|
|
386
|
+
streamMaxRetries = 3
|
|
387
|
+
requestMaxRetries = 2
|
|
353
388
|
```
|
|
354
389
|
|
|
355
390
|
`model` is required and must not be blank when `provider = "openrouter"`. It is an OpenRouter model ID; Kyoso does not validate the catalog or whether that model supports tool calling, so confirm tool support with the provider.
|
|
356
391
|
|
|
357
|
-
`
|
|
392
|
+
`agents.codex.openRouter` is experimental. `streamIdleTimeoutMs` is an integer of at least `1000`; `streamMaxRetries` and `requestMaxRetries` are integers from `0` through `100`, where `0` disables that retry class. These fields require `provider = "openrouter"`; omitting them leaves the corresponding Codex runtime defaults unchanged. Retry can regenerate an unfinished Codex turn rather than resume its bytes, so do not broadly enable it until partial-output protection ships in the next release.
|
|
393
|
+
|
|
394
|
+
`allowProjectProvider` applies to a project `provider`, a project `model` override while OpenRouter is inherited, and a project `agents.codex.openRouter.*` override while OpenRouter is inherited; its list must contain the absolute canonical directory containing the resolved project configuration file, not the invocation cwd or a lexical path, with no descendant or glob matching. A project configuration file (including trusted `kyoso.config.ts`) and an allowlist entry that resolve through symlinks to that directory match; entries resolving elsewhere, or unresolvable paths, fail closed. A user-global `provider = "openrouter"` needs no allowlist entry. An explicit CLI pair of `--set agents.codex.provider=openrouter` and `--set agents.codex.model=<model>` in the same invocation is also allowed without it; a project model cannot supply the CLI override's model. `allowProjectProvider` is not a `--set` path and legacy boolean values are rejected.
|
|
358
395
|
|
|
359
|
-
When a user-global config selects OpenRouter, a project can explicitly opt out with `provider = "default"`. This reset needs neither a model nor authorization, clears the inherited OpenRouter model unless the same layer explicitly supplies a normal Codex model, and prevents OpenRouter key forwarding for that project.
|
|
396
|
+
When a user-global config selects OpenRouter, a project can explicitly opt out with `provider = "default"`. This reset needs neither a model nor authorization, clears the inherited OpenRouter model unless the same layer explicitly supplies a normal Codex model, clears inherited OpenRouter retry policy, and prevents OpenRouter key forwarding for that project. A retry policy in the same reset layer remains invalid because it requires `provider = "openrouter"`.
|
|
360
397
|
|
|
361
398
|
Set the key in the process environment that starts the Codex or Claude client running Kyoso. A direct environment variable is the primary path; a secret manager such as 1Password is optional and is not a Kyoso dependency:
|
|
362
399
|
|
|
@@ -370,7 +407,7 @@ The Marketplace Plugin exposes the `OPENROUTER_API_KEY` variable name to its MCP
|
|
|
370
407
|
|
|
371
408
|
New manual MCP registrations omit `OPENROUTER_API_KEY` by default. Add it only with `--with-openrouter` after intentionally selecting the provider; existing registrations are never rewritten. The `kyoso setup ... --with-openrouter` output and the manual setup examples remain user-managed client-registration templates. In a Claude Code registration, `${OPENROUTER_API_KEY}` must be expanded by the client; Kyoso ignores only a whole unexpanded credential placeholder — `${NAME}`, `$NAME`, or `%NAME%`, with optional surrounding whitespace — and emits a sanitized warning containing only the variable name. Values with any other text are preserved. The same rule applies to custom credential-like names ending in `_KEY`, `_TOKEN`, `_SECRET`, or `_PASSWORD`; non-credential templates are preserved.
|
|
372
409
|
|
|
373
|
-
Prefer this user-authorized project-scoped opt-in. A global `provider = "openrouter"` is inherited by projects until a project sets `provider = "default"`; merely omitting `provider` does not unset it. The fixed OpenRouter Responses API preset is beta; custom endpoints, provider routing, fallbacks, and judge integration are not exposed. To keep the key bound to that preset, OpenRouter mode rejects a `CODEX_CONFIG` with a top-level `profile` or `profiles` field and rejects a non-object `model_providers` value before launching the child. For an object value, it replaces `model_providers` with only the fixed `kyoso-openrouter` entry and emits a sanitized warning with the discarded-entry count only; provider IDs and configuration values never appear. Apart from those rejected fields, it preserves unrelated `CODEX_CONFIG` fields outside `model`, `model_provider`, and `model_providers`, so no foreign provider configuration can select an endpoint with the key. Claude remains on its configured provider, and the judge does not use `OPENROUTER_API_KEY`.
|
|
410
|
+
Prefer this user-authorized project-scoped opt-in. A global `provider = "openrouter"` is inherited by projects until a project sets `provider = "default"`; merely omitting `provider` does not unset it. The fixed OpenRouter Responses API preset is beta; custom endpoints, provider routing, fallbacks, and judge integration are not exposed. When configured, `streamIdleTimeoutMs`, `streamMaxRetries`, and `requestMaxRetries` map only to `stream_idle_timeout_ms`, `stream_max_retries`, and `request_max_retries`; omitted fields are absent from `CODEX_CONFIG`. To keep the key bound to that preset, OpenRouter mode rejects a `CODEX_CONFIG` with a top-level `profile` or `profiles` field and rejects a non-object `model_providers` value before launching the child. For an object value, it replaces `model_providers` with only the fixed `kyoso-openrouter` entry and emits a sanitized warning with the discarded-entry count only; provider IDs and configuration values never appear. Apart from those rejected fields, it preserves unrelated `CODEX_CONFIG` fields outside `model`, `model_provider`, and `model_providers`, so no foreign provider configuration can select an endpoint with the key. Claude remains on its configured provider, and the judge does not use `OPENROUTER_API_KEY`.
|
|
374
411
|
|
|
375
412
|
After user-global authorization, a project `kyoso.toml` can select the external provider or override its inherited OpenRouter model and route review context to it. For an untrusted repository, use `--ignore-config` and pass only the needed CLI options explicitly.
|
|
376
413
|
|
|
@@ -380,7 +417,7 @@ The real Codex ACP/OpenRouter smoke is release-gated and never runs in tests. On
|
|
|
380
417
|
KYOSO_OPENROUTER_ACP_SMOKE=release KYOSO_OPENROUTER_MODEL=<model> safe-chain bun run smoke:openrouter:codex-acp
|
|
381
418
|
```
|
|
382
419
|
|
|
383
|
-
It accepts no CLI arguments, uses the pinned Codex ACP adapter, and creates fresh empty temporary workspace, `HOME`, and `CODEX_HOME` directories so it cannot use the calling repository or cached Codex login. It returns only a fixed success or failure message without writing the key or model to config, temporary artifacts, or output.
|
|
420
|
+
It accepts no CLI arguments, uses the pinned Codex ACP adapter, and creates fresh empty temporary workspace, `HOME`, and `CODEX_HOME` directories so it cannot use the calling repository or cached Codex login. It returns only a fixed success or failure message without writing the key or model to config, temporary artifacts, or output. This credentialed smoke checks only interoperability; retry correctness is covered by the release-only `KYOSO_CODEX_ACP_MOCK_SSE=1` local mock SSE integration gate.
|
|
384
421
|
|
|
385
422
|
### Agent auth
|
|
386
423
|
|
package/README.zh-CN.md
CHANGED
|
@@ -154,7 +154,7 @@ Use Kyoso diff_review on the current diff. I need a second opinion before mergin
|
|
|
154
154
|
|
|
155
155
|
## CLI
|
|
156
156
|
|
|
157
|
-
package-runner 执行路径始终分别指定 package 和 executable:`npx -y --package=@kyo-so/cli kyoso` 与 `bunx --package @kyo-so/cli kyoso`。需要固定 workflow 时,在 package 名后加 complete SemVer pin,例如 `@kyo-so/cli@0.
|
|
157
|
+
package-runner 执行路径始终分别指定 package 和 executable:`npx -y --package=@kyo-so/cli kyoso` 与 `bunx --package @kyo-so/cli kyoso`。需要固定 workflow 时,在 package 名后加 complete SemVer pin,例如 `@kyo-so/cli@0.14.0`。下面的示例把已安装 executable 简写为 `kyoso`。Naming note: npm package 是 `@kyo-so/cli` (对应产品名 Kyo-so),安装后的 CLI command 是更短的 `kyoso`。
|
|
158
158
|
|
|
159
159
|
Bun fallback 已在 Bun `1.3.14` 上验证。旧版 Bun 请使用 npx 形式或已安装的 `kyoso`,不要依赖 Bun 从多 bin package 推断 binary。
|
|
160
160
|
|
|
@@ -4,7 +4,10 @@ import { BaseAcpAgentManager } from "./AcpAgentManager.js";
|
|
|
4
4
|
export declare class SubprocessAcpAgentManager extends BaseAcpAgentManager {
|
|
5
5
|
private readonly config;
|
|
6
6
|
private readonly parentEnv;
|
|
7
|
-
|
|
7
|
+
private readonly internalOptions;
|
|
8
|
+
constructor(config: KyosoConfig, parentEnv?: NodeJS.ProcessEnv, internalOptions?: {
|
|
9
|
+
openRouterBaseUrlForTest?: string;
|
|
10
|
+
});
|
|
8
11
|
runAgent(input: AgentRunInput): Promise<AgentRunResult>;
|
|
9
12
|
}
|
|
10
13
|
export declare function readWorkspaceFile(workspaceDir: string, requestedPath: string, line?: number | null, limit?: number | null): Promise<string>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type MessagePhase = "commentary" | "final_answer" | "unknown";
|
|
2
|
+
export type AgentOutputMetrics = {
|
|
3
|
+
observedStreamRetries: number;
|
|
4
|
+
discardedRetryMessageBytes: number;
|
|
5
|
+
firstOutputAt?: string;
|
|
6
|
+
lastAcpUpdateAt?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare class AgentOutputAccumulator {
|
|
9
|
+
private readonly segments;
|
|
10
|
+
private readonly messageChunks;
|
|
11
|
+
private retryEpoch;
|
|
12
|
+
private observedStreamRetries;
|
|
13
|
+
private discardedRetryMessageBytes;
|
|
14
|
+
private firstOutputAt;
|
|
15
|
+
private lastAcpUpdateAt;
|
|
16
|
+
private nextChunkSequence;
|
|
17
|
+
addMessageChunk(text: string, meta: {
|
|
18
|
+
messageId?: string;
|
|
19
|
+
phase?: MessagePhase;
|
|
20
|
+
}): void;
|
|
21
|
+
addThoughtChunk(_text: string): void;
|
|
22
|
+
noteUpdate(): void;
|
|
23
|
+
markRetryBoundary(): {
|
|
24
|
+
discardedMessageBytes: number;
|
|
25
|
+
};
|
|
26
|
+
finalRawText(): string;
|
|
27
|
+
metrics(): AgentOutputMetrics;
|
|
28
|
+
private noteOutput;
|
|
29
|
+
}
|