diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index c815011..d601508 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -5,13 +5,13 @@ }, "metadata": { "description": "Polycli host adapters for Claude Code and related agent CLIs", - "version": "0.6.27" + "version": "0.6.28" }, "plugins": [ { "name": "polycli", "description": "Claude Code adapter for the shared polycli companion", - "version": "0.6.27", + "version": "0.6.28", "source": "./plugins/polycli" } ] diff --git a/.github/plugin/marketplace.json b/.github/plugin/marketplace.json index 185bb70..1f2f770 100644 --- a/.github/plugin/marketplace.json +++ b/.github/plugin/marketplace.json @@ -5,13 +5,13 @@ }, "metadata": { "description": "Polycli marketplace for GitHub Copilot CLI", - "version": "0.6.27" + "version": "0.6.28" }, "plugins": [ { "name": "polycli-copilot", "description": "Run the shared polycli companion from GitHub Copilot CLI", - "version": "0.6.27", + "version": "0.6.28", "source": "./plugins/polycli-copilot" } ] diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad6bd5..a940afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,15 @@ Separate from `docs/release.md` (release-focused) and `docs/archive/session-memo --- +## 2026-06-26 — Claude — provider-state review: live re-verify all 11 CLIs + drift fixes (PR #15, v0.6.28 release candidate) + +- Ran a `provider-state-review` Workflow (11 read-only probe agents → per-provider adversarial verify → synthesis, 23 agents) to re-check every provider CLI's **live install + upstream + adapter contract** on top of `v0.6.27`. Headline: **no version gaps, no breaking CLI drift** — all 11 locals == upstream where comparable (claude 2.1.193 / gemini 0.49.0 / qwen 0.19.2 / copilot 1.0.65 / opencode 1.17.11 / pi 0.80.2 / cmd 0.40.8 / mmx 1.0.16 / kimi-code 0.19.1 / grok 0.2.64 / agy 1.0.12); every flag/auth/argv assumption verified intact against live `--help`. +- **(code) copilot resume contract** — `buildCopilotInvocation` now emits `--session-id ` instead of `--resume ` for resume-by-exact-id. copilot 1.0.65's `-r, --resume[=value]` takes an OPTIONAL `=`-attached value (or opens the session picker), so the prior space-separated form would not resume by id; `--session-id ` is the documented by-id flag. Reachable via `ask`/`rescue --provider copilot --resume ` (the companion sets `resumeSessionId`). Regression updated in `copilot.test.js`; all 5 companion bundles regenerated. +- **(code) minimax finish-reason** — `extractMiniMaxResponseFromMmxJson` now honours Anthropic-style `stop_reason` in the `finishReason` fallback (mmx speaks both the OpenAI `finish_reason` and Anthropic Messages `stop_reason` shapes, and the parser already handles Anthropic `content[]` blocks). Pure additive, zero regression; `minimax.test.js` now asserts `finishReason` from the existing `stop_reason` fixture. +- **(docs/comments) kimi version-label refresh** — `kimi-code v0.6.0` → `kimi-code 0.19.1` in `docs/provider-paths.md` + `docs/polycli-v1-public-surface.md`; dropped the re-drifting `v0.6.0` pin from behavioural code comments (`kimi.js`, `review.mjs`, `prompt-runtime.mjs`) since the behaviour is version-general. Bumped the `provider-paths.md` snapshot to 2026-06-26 and replaced the stale `v0.6.21` clause in the `roadmap.md` Current-state section with the 2026-06-26 re-verification note. (Project memory `reference_cli_provider_versions.md` rewritten to the 11-provider reality: pi `@mariozechner`→`@earendil-works`; kimi spawns kimi-code not the shadowed PyPI `kimi-cli`; minimax=`mmx-cli` not `mini-agent`; self-updating kimi/grok/agy have no read-only latest channel.) +- **Deferred / FLAGGED (not changed)** per minimum-diff + the AGENTS.md "flag pre-existing dead code, don't delete" rule: `pi.js` dead `agent_end.result.text`/`resultEvent.error` branches (live `agent_end` carries only `messages[]`/`willRetry`, verified vs pi-agent-core `.d.ts`; harmless); the `opencode.js` billed `run "ping"` auth probe could use non-billing `opencode auth list` but auth-list proves CONFIGURED-not-WORKING, so folding it in would weaken status honesty / risk the four-state; and the JSON/stream-json **event schema** for ~7 providers stays unverified (read-only/cost constraint — needs an execution-allowed run or fixture recapture; gemini/grok fixture meta versions also lag, already tracked by `check:fixture-freshness`). +- Validation: `npm test` 559/559, `npm run release:check` exit 0. Respects the Path B boundary (no shared runtime base, no parser promoted into polycli-utils, timing four-state untouched, cold/retry still unimplemented). + ## 2026-06-19 — Claude — release: v0.6.27 published (review residual cleanup) - Published **v0.6.27** to npm: `@bbingz/polycli@0.6.27` (shasum `397b2349bd3c952c2b612c7f762a9db48e09cb09`) and `@bbingz/polycli-opencode@0.6.27` (shasum `e38d544a851ad67302aa50b7f75d028b80cb6100`), both `latest`. GitHub release `v0.6.27` (`publishedAt` `2026-06-19T09:29:35Z`) + tag `v0.6.27`. Utility packages unchanged. diff --git a/README.ja.md b/README.ja.md index 9736a59..59f10f9 100644 --- a/README.ja.md +++ b/README.ja.md @@ -27,9 +27,9 @@ これは **ユーティリティ専用の Path B モノレポ** です。プロバイダ間の差異を偽の抽象化で覆い隠したり、ランタイム基底クラスを発明したりはしません。公式の上流 CLI をサブプロセスとして組み合わせ、単一のコマンド面を公開し、4 状態の timing スキーマで能力の違いを正直に表現します。 -## 最新リリース: v0.6.27 +## 最新リリース: v0.6.28 -v0.6.26 の Grok ネストエラー修正を土台に、残りの review 残件を解消しました。バックグラウンドジョブのディスクリークを修正(`saveState` は `MAX_JOBS` を超えて削除される terminal ジョブの result/config/log を回収します)。fixture-metadata バリデータは path/meta 契約(`provider` がディレクトリ、`name` がファイル stem に一致)を強制し、cc-X バリデータと OpenCode の exit-2 ソフトシグナルに実行経路テストを追加しました。最新リリースを v0.6.24 と書いたままだった `docs/roadmap.md` の Current-state も同期しました。Claude `ask` / `review` は引き続き headless `claude -p` 既定経路です。詳細は英語の release notes を参照してください: [`docs/release-notes-v0.6.27.md`](./docs/release-notes-v0.6.27.md)。 +v0.6.27 の上に、2026-06-26 の provider-state 再検証を公開します。11 種類の provider CLI についてローカルインストール・上流バージョン・adapter の flag/auth/argv 契約を確認し、バージョン差分や破壊的な CLI ドリフトは見つかりませんでした。Copilot の exact session resume は無効な空白区切りの `--resume ` ではなく `--session-id ` を使うようになり、MiniMax の JSON パーサは Anthropic-style の `stop_reason` を `finishReason` として保持します。Kimi のバージョン表記と provider-state ドキュメントも `kimi-code 0.19.1` に同期しました。Claude `ask` / `review` は引き続き headless `claude -p` 既定経路です。詳細は英語の release notes を参照してください: [`docs/release-notes-v0.6.28.md`](./docs/release-notes-v0.6.28.md)。 ## なぜ polycli を使うのか? diff --git a/README.md b/README.md index a827786..c4ad3bb 100644 --- a/README.md +++ b/README.md @@ -29,16 +29,16 @@ It is a **utility-only Path B monorepo**: it does not unify provider differences behind fake abstractions, and it does not invent a runtime base class. It composes the official upstream CLIs as subprocesses, exposes one command surface, and surfaces honest capability differences in a four-state timing schema. -## Latest release: v0.6.27 +## Latest release: v0.6.28 -The latest patch clears the remaining review residuals on top of v0.6.26's Grok nested-error fix: +The latest patch publishes the 2026-06-26 provider-state re-verification on top of v0.6.27: -- Fixed a background-job disk leak: `saveState` now reclaims the result/config/log artifacts of terminal jobs pruned past `MAX_JOBS` instead of leaving them in the jobs dir forever. -- The fixture-metadata validator enforces the documented path/meta contract (`provider` matches the directory, `name` matches the file stem); the cc-X validator and OpenCode exit-2 soft-signal now have execution-path test coverage. -- Synced the `docs/roadmap.md` Current-state section, which still said the latest release was v0.6.24. -- Builds on v0.6.26 (Grok nested-error fix) and v0.6.25 (re-verified remediation + cc-X endpoint recipes). Claude `ask` and `review` still use headless `claude -p` by default with plan/no-tools/no-MCP constraints; utility packages stay on their independent v1.x cadence. +- Re-checked all 11 provider CLIs against live installs and upstream version sources; no version gaps or breaking flag/auth/argv drift were found. +- Copilot exact session resume now emits `--session-id ` instead of the invalid space-separated `--resume ` form. +- MiniMax JSON parsing now preserves Anthropic-style `stop_reason` as `finishReason` when `mmx` returns Messages-shaped content blocks. +- Kimi version labels and provider-state docs were refreshed for `kimi-code 0.19.1`. Claude `ask` and `review` still use headless `claude -p` by default with plan/no-tools/no-MCP constraints; utility packages stay on their independent v1.x cadence. -See [`docs/release-notes-v0.6.27.md`](./docs/release-notes-v0.6.27.md). +See [`docs/release-notes-v0.6.28.md`](./docs/release-notes-v0.6.28.md). ## Why polycli? diff --git a/README.zh-CN.md b/README.zh-CN.md index 2d270a0..8f1f0c4 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -27,9 +27,9 @@ 这是一个 **utility-only 的 Path B monorepo**:不假装能抹平 provider 之间的差异,也不引入 runtime 基类。它把官方上游 CLI 作为子进程组合起来,统一命令面,并通过四态 timing schema 如实暴露能力差异。 -## 最新版本:v0.6.27 +## 最新版本:v0.6.28 -在 v0.6.26 的 Grok 嵌套 error 修复基础上,清理剩余 review 残留:修复后台 job 磁盘泄漏(`saveState` 现在回收被 `MAX_JOBS` 裁掉的 terminal job 的 result/config/log,不再永久留存);fixture-metadata validator 强制 path/meta 契约(`provider` 配目录、`name` 配文件 stem),cc-X validator 与 OpenCode exit-2 软信号补了执行面测试覆盖;同步了 `docs/roadmap.md` Current-state 段(仍写最新版是 v0.6.24)。Claude `ask` / `review` 仍走 headless `claude -p` 默认路径。详情见英文 release notes:[`docs/release-notes-v0.6.27.md`](./docs/release-notes-v0.6.27.md)。 +在 v0.6.27 基础上发布 2026-06-26 provider-state 复核结果:重新检查 11 个 provider CLI 的本地安装、上游版本源和 adapter flag/auth/argv 契约,未发现版本缺口或破坏性漂移;Copilot 精确 session resume 改为 `--session-id `,避免无效的空格分隔 `--resume `;MiniMax JSON 解析现在把 Anthropic-style `stop_reason` 保留为 `finishReason`;Kimi 版本标签和 provider-state 文档同步到 `kimi-code 0.19.1`。Claude `ask` / `review` 仍走 headless `claude -p` 默认路径。详情见英文 release notes:[`docs/release-notes-v0.6.28.md`](./docs/release-notes-v0.6.28.md)。 ## 为什么要用 polycli? diff --git a/docs/polycli-v1-public-surface.md b/docs/polycli-v1-public-surface.md index 56c2f8c..57d58ac 100644 --- a/docs/polycli-v1-public-surface.md +++ b/docs/polycli-v1-public-surface.md @@ -115,7 +115,7 @@ This keeps v1 small, testable, and publishable without pretending the provider m | `claude` | headless `claude -p` with `--permission-mode plan --tools "" --mcp-config '{"mcpServers":{}}' --strict-mcp-config` | plan/no tools/no MCP; returns synchronous model output and stream timings. Detached tmux TUI remains an explicit/internal runtime mode with `tmuxSession`/`attachCommand` and startup-only timing | | `gemini` | `--approval-mode plan --extensions "" --allowed-mcp-server-names __polycli_prompt_no_mcp__` | plan/no extensions/MCP | | `qwen` | `--approval-mode plan --max-session-turns 20` plus repeated `--exclude-tools ...` | bounded multi-turn/no tools; no forced one-turn cap | -| `kimi` | none — `-p` one-shot rejects `--plan`/`--auto`/`--yolo` | non-interactive single-shot (kimi-code v0.6.0) | +| `kimi` | none — `-p` one-shot rejects `--plan`/`--auto`/`--yolo` | non-interactive single-shot (kimi-code 0.19.1) | | `cmd` | `--permission-mode plan` | plan | | `agy` | `--dangerously-skip-permissions` for ask/rescue; `/review` rejected | agentic session mode; no enforceable non-interactive plan mode | | `grok` | `-p ... --output-format json --always-approve` for ask; review adds `--permission-mode plan` and disables always-approve | structured one-shot; plan review | diff --git a/docs/provider-paths.md b/docs/provider-paths.md index 744c0a6..09cf221 100644 --- a/docs/provider-paths.md +++ b/docs/provider-paths.md @@ -1,6 +1,6 @@ # Provider Paths -Snapshot: 2026-06-15. Review monthly, before release, and whenever a provider CLI or local default model changes. +Snapshot: 2026-06-26. Review monthly, before release, and whenever a provider CLI or local default model changes. This table is a routing reference for humans and host adapters. It is not an automatic routing oracle. `opencode`, `pi`, and `cmd` are model routers, so their "best path" depends on the user's authenticated local model set. @@ -11,7 +11,7 @@ This table is a routing reference for humans and host adapters. It is not an aut | Claude Code / Anthropic coding agent | `claude` | `opencode` Anthropic models | Default polycli `ask`/`review` now uses official headless `claude -p` with plan/no-tools/no-MCP constraints, returning synchronous JSON/stream JSON output. Detached tmux TUI remains available in runtime for explicit/internal callers that need an interactive Claude Code session. | | Gemini | `gemini` | none | Official CLI headless `-p`, `--approval-mode plan`, JSON/stream JSON. Keep isolated cwd and disabled extensions/MCP for review. | | Qwen Code / Qwen Coding Plan | `qwen` | `opencode` Alibaba Coding Plan models | Official Qwen Code default `maxSessionTurns=-1` means do not force ask to one turn. Polycli ask uses a bounded `maxSteps=20`, `approvalMode=plan`, and `--exclude-tools`; review uses the same no-tool stance. SDK `canUseTool` is a better future path if Polycli moves beyond CLI wrapping. | -| Kimi coding | `kimi` (kimi-code v0.6.0) | `opencode` Kimi For Coding models | The `-p` one-shot runner is non-interactive and rejects `--plan`/`--auto`/`--yolo`, so ask uses a plain `-p` invocation and review is prompt-only (like minimax). Default model from `~/.kimi-code/config.toml`. | +| Kimi coding | `kimi` (kimi-code 0.19.1) | `opencode` Kimi For Coding models | The `-p` one-shot runner is non-interactive and rejects `--plan`/`--auto`/`--yolo`, so ask uses a plain `-p` invocation and review is prompt-only (like minimax). Default model from `~/.kimi-code/config.toml`. | | MiniMax text / multimodal | `minimax` via `mmx-cli` | `opencode` MiniMax Coding Plan models | Use official `mmx text chat --message ... --output json --non-interactive`; this replaces `mini-agent` log scraping. | | OpenCode Go / Xiaomi MiMo / Alibaba / multi-provider routing | `opencode` | `pi` for Xiaomi MiMo | Local `opencode auth list` is the source of truth; `~/.config/opencode/opencode.json` can show an empty provider object even when credentials and models exist. Current local OpenCode includes Xiaomi Token Plan, Alibaba Coding Plan, Kimi, MiniMax, Anthropic, and OpenCode Go routes. | | Xiaomi MiMo-V2.5-Pro | `opencode` with OpenCode Go/Xiaomi Token Plan | `pi` default Xiaomi route | Screenshot state is consistent with OpenCode using Xiaomi Token Plan / OpenCode Go, not an empty provider. | diff --git a/docs/release-notes-v0.6.28.md b/docs/release-notes-v0.6.28.md new file mode 100644 index 0000000..6e1a49a --- /dev/null +++ b/docs/release-notes-v0.6.28.md @@ -0,0 +1,38 @@ +# polycli v0.6.28 + +Patch on top of `v0.6.27` that publishes the 2026-06-26 provider-state re-verification and the two adapter fixes it found: Copilot exact session resume and MiniMax finish-reason parsing. + +The v0.6.22 Claude behavior remains unchanged: ordinary Claude `ask` / `review` calls use headless `claude -p` with plan/no-tools/no-MCP constraints, while explicit/internal tmux TUI runtime support remains available. + +## What changed + +### Provider-state re-verification + +- Re-checked all 11 provider CLIs against live local installs, upstream version sources where available, and adapter flag/auth/argv contracts: `claude`, `gemini`, `qwen`, `copilot`, `opencode`, `pi`, `cmd`, `minimax`, `kimi`, `grok`, and `agy`. +- No version gaps or breaking CLI drift were found. Confirmed local versions include claude 2.1.193, gemini 0.49.0, qwen 0.19.2, copilot 1.0.65, opencode 1.17.11, pi 0.80.2, cmd 0.40.8, mmx 1.0.16, kimi-code 0.19.1, grok 0.2.64, and agy 1.0.12. + +### Copilot exact resume + +- `buildCopilotInvocation` now emits `--session-id ` for resume-by-exact-id instead of `--resume `. Copilot CLI 1.0.65 treats `--resume` as an optional-value flag whose by-id examples use `--resume=`; the documented exact by-id flag is `--session-id `. +- This is reachable from host `ask` / `rescue --provider copilot --resume ` paths because the companion maps that option to `resumeSessionId`. + +### MiniMax finish reason + +- `extractMiniMaxResponseFromMmxJson` now preserves root-level `stop_reason` as `finishReason`, matching Anthropic Messages-shaped `mmx` JSON responses with `content[]` text blocks. + +### Docs and durable context + +- Refreshed Kimi labels from the old `kimi-code v0.6.0` reference to `kimi-code 0.19.1`. +- Updated provider-paths, roadmap current state, and local project memory with the 11-provider snapshot and the deliberately deferred follow-ups. + +## Verification + +- Focused runtime tests: Copilot invocation argv and MiniMax `stop_reason` parsing. +- `npm test` and `npm run release:check` green before release. + +## Release artifacts + +- GitHub release `v0.6.28`: https://github.com/bbingz/polycli/releases/tag/v0.6.28 +- npm `@bbingz/polycli@0.6.28` and `@bbingz/polycli-opencode@0.6.28` (`latest`). + +Utility packages stay on the independent v1.x cadence (`@bbingz/polycli-utils@1.0.2`, `@bbingz/polycli-timing@1.0.1`). diff --git a/docs/roadmap.md b/docs/roadmap.md index d4ce842..950d6c5 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # Roadmap -Snapshot: 2026-06-19 (v0.6.27 is the latest public release; it cleans up review residuals — roadmap release-state drift, the cc-X/fixture validator path/meta + status contracts, OpenCode exit-2 execution-path coverage, and the MAX_JOBS terminal-job disk-leak — on top of v0.6.26's Grok nested-error fix and v0.6.25's re-verified remediation + cc-X endpoint recipes, while keeping Claude ask/review on headless `claude -p` defaults). +Snapshot: 2026-06-26 (v0.6.28 is the latest public release; it publishes the provider-state re-verification plus Copilot exact-resume and MiniMax finish-reason parser fixes on top of v0.6.27's review-residual cleanup, while keeping Claude ask/review on headless `claude -p` defaults). This file lives next to `docs/release.md` (what's shipped) and `CHANGELOG.md` (what happened). It answers the complementary question: **what's open, how it's prioritized, and what we're deliberately not doing.** @@ -10,9 +10,9 @@ Living document — update when items land, when priorities shift, or when a def ## Current state -- Latest public release: **v0.6.27** — see `docs/release-notes-v0.6.27.md`. It keeps default Claude ask/review on `claude -p` and is the latest in the post-v0.6.24 patch line (status-wait hardening → re-verified remediation + cc-X recipes → Grok nested-error fix → these review-residual cleanups). -- 11 providers ship in the latest release (claude / gemini / kimi / qwen / minimax / copilot / opencode / pi / cmd / agy / grok). v0.6.21 shipped Claude detached tmux TUI defaults and the third-party review remediation set. -- No unreleased workspace work pending: everything through v0.6.27 (status-wait compatibility, the re-verified remediation, the cc-X endpoint recipes, the Grok nested-error fix, and the validator/doc/disk-leak review residuals) is published. +- Latest public release: **v0.6.28** — see `docs/release-notes-v0.6.28.md`. It keeps default Claude ask/review on `claude -p` and is the latest in the post-v0.6.24 patch line (status-wait hardening -> re-verified remediation + cc-X recipes -> Grok nested-error fix -> review-residual cleanup -> provider-state re-verification). +- 11 providers ship in the latest release (claude / gemini / kimi / qwen / minimax / copilot / opencode / pi / cmd / agy / grok). All 11 CLIs were re-verified against their live installs on 2026-06-26 (every adapter flag/auth/argv contract intact; no version gaps); see `docs/provider-paths.md`. +- Everything through v0.6.28 (status-wait compatibility, the re-verified remediation, the cc-X endpoint recipes, the Grok nested-error fix, the validator/doc/disk-leak review residuals, and the 2026-06-26 provider-state re-verification with Copilot resume / MiniMax parser fixes) is published. - 4 host plugins (polycli / polycli-codex / polycli-copilot / polycli-opencode) plus the optional `@bbingz/polycli` terminal CLI, each with an independent release manifest. - Path B architectural stance is intact: `@bbingz/polycli-utils` / `@bbingz/polycli-timing` are public v1 npm packages; `@bbingz/polycli` is the public terminal CLI surface; `@bbingz/polycli-runtime` remains an internal bundler input (`private: true`); provider modules are flat, not inherited; timing four-state semantics preserved. diff --git a/packages/polycli-runtime/src/copilot.js b/packages/polycli-runtime/src/copilot.js index 039e12d..0f371ba 100644 --- a/packages/polycli-runtime/src/copilot.js +++ b/packages/polycli-runtime/src/copilot.js @@ -91,7 +91,10 @@ export function buildCopilotInvocation({ args.push("--model", model); } if (resumeSessionId) { - args.push("--resume", resumeSessionId); + // Resume by exact id uses `--session-id `. copilot's `-r, --resume[=value]` takes an + // OPTIONAL `=`-attached value (or opens the session picker), so a space-separated + // `--resume ` would not resume by id — `--session-id ` is the documented by-id flag. + args.push("--session-id", resumeSessionId); } else if (continueLast) { args.push("--continue"); } diff --git a/packages/polycli-runtime/src/kimi.js b/packages/polycli-runtime/src/kimi.js index f75acfd..4d38cba 100644 --- a/packages/polycli-runtime/src/kimi.js +++ b/packages/polycli-runtime/src/kimi.js @@ -14,7 +14,7 @@ const KIMI_EXPLICIT_AUTH_ERROR_RE = /\b(unauthenticated|unauthorized|not authent export const TRANSIENT_PROBE_ERROR_PATTERNS = [ /\b(timed out|timeout|429|rate limit|no capacity available|temporar(?:y|ily)|service unavailable|overloaded|try again|econnreset|econnrefused|enotfound|network|socket hang up)\b/i, ]; -// kimi-code v0.6.0 stores its default model in ~/.kimi-code/config.toml (the legacy python +// kimi-code stores its default model in ~/.kimi-code/config.toml (the legacy python // kimi-cli used ~/.kimi/config.toml; that install is migrated, marker `.migrated-to-kimi-code`). const KIMI_CONFIG_PATH = process.env.KIMI_CONFIG_PATH || path.join(os.homedir(), ".kimi-code", "config.toml"); @@ -39,9 +39,9 @@ export function buildKimiInvocation({ // kimi-code one-shot mode: `-p --output-format stream-json`. NOTE: `-p` cannot be // combined with `--yolo`, `--auto`, or `--plan` (the CLI rejects them) — `-p` is itself the // non-interactive headless runner, so no approval flag is passed. Resume is delegated to the - // CLI: `--session ` (kimi-code v0.6.0's `-S, --session [id]`, per its own + // CLI: `--session ` (kimi-code's `-S, --session [id]`, per its own // session.resume_hint) or `-C` to continue the last session. NOTE: the legacy python - // kimi-cli used `-r`; kimi-code v0.6.0 has no `-r` flag and rejects it. + // kimi-cli used `-r`; kimi-code has no `-r` flag and rejects it. const args = ["-p", String(prompt ?? ""), "--output-format", "stream-json"]; if (model) args.push("-m", model); if (resumeLast) { diff --git a/packages/polycli-runtime/src/minimax.js b/packages/polycli-runtime/src/minimax.js index 8fab248..f3a6b85 100644 --- a/packages/polycli-runtime/src/minimax.js +++ b/packages/polycli-runtime/src/minimax.js @@ -209,7 +209,10 @@ export function extractMiniMaxResponseFromMmxJson(text) { : typeof value.text === "string" ? value.text : contentText || (typeof message?.content === "string" ? message.content : ""); - const finishReason = value.finish_reason ?? value.finishReason ?? choice?.finish_reason ?? null; + // mmx speaks both the OpenAI (`finish_reason`) and Anthropic Messages (`stop_reason`) shapes; + // the content-block branch above already handles Anthropic `content[]`, so honour `stop_reason` too. + const finishReason = + value.finish_reason ?? value.finishReason ?? value.stop_reason ?? choice?.finish_reason ?? null; const toolCalls = Array.isArray(value.tool_calls) ? value.tool_calls : Array.isArray(message?.tool_calls) diff --git a/packages/polycli-runtime/test/copilot.test.js b/packages/polycli-runtime/test/copilot.test.js index 21c049a..56efddc 100644 --- a/packages/polycli-runtime/test/copilot.test.js +++ b/packages/polycli-runtime/test/copilot.test.js @@ -47,7 +47,7 @@ test("buildCopilotInvocation enables programmatic json mode with permissions and "--no-ask-user", "--model", "gpt-5.3-codex", - "--resume", + "--session-id", "cop-123", ]); }); diff --git a/packages/polycli-runtime/test/minimax.test.js b/packages/polycli-runtime/test/minimax.test.js index a30af38..8b9a829 100644 --- a/packages/polycli-runtime/test/minimax.test.js +++ b/packages/polycli-runtime/test/minimax.test.js @@ -90,6 +90,8 @@ test("runMiniMaxPrompt parses real mmx content arrays and ignores auth notices o assert.equal(result.response, "pong"); assert.equal(result.error, null); assert.equal(result.model, "MiniMax-M2.7"); + // Anthropic-shape responses carry `stop_reason`, not `finish_reason`. + assert.equal(result.finishReason, "end_turn"); }); test("minimax log helpers extract response blocks and sanitize ansi", () => { diff --git a/packages/polycli-terminal/bin/polycli-companion.bundle.mjs b/packages/polycli-terminal/bin/polycli-companion.bundle.mjs index f6d4f84..1c27f5c 100755 --- a/packages/polycli-terminal/bin/polycli-companion.bundle.mjs +++ b/packages/polycli-terminal/bin/polycli-companion.bundle.mjs @@ -1610,7 +1610,7 @@ function buildCopilotInvocation({ args.push("--model", model); } if (resumeSessionId) { - args.push("--resume", resumeSessionId); + args.push("--session-id", resumeSessionId); } else if (continueLast) { args.push("--continue"); } @@ -2765,7 +2765,7 @@ function extractMiniMaxResponseFromMmxJson(text) { const message = choice?.message ?? choice?.delta ?? null; const contentText = Array.isArray(value.content) ? value.content.filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("") : ""; const response = typeof value.content === "string" ? value.content : typeof value.response === "string" ? value.response : typeof value.text === "string" ? value.text : contentText || (typeof message?.content === "string" ? message.content : ""); - const finishReason = value.finish_reason ?? value.finishReason ?? choice?.finish_reason ?? null; + const finishReason = value.finish_reason ?? value.finishReason ?? value.stop_reason ?? choice?.finish_reason ?? null; const toolCalls = Array.isArray(value.tool_calls) ? value.tool_calls : Array.isArray(message?.tool_calls) ? message.tool_calls : []; return { response, diff --git a/packages/polycli-terminal/package.json b/packages/polycli-terminal/package.json index ffd1bb5..5452ab3 100644 --- a/packages/polycli-terminal/package.json +++ b/packages/polycli-terminal/package.json @@ -1,6 +1,6 @@ { "name": "@bbingz/polycli", - "version": "0.6.27", + "version": "0.6.28", "description": "Terminal CLI for Polycli provider diagnostics and host-compatible commands.", "type": "module", "bin": { diff --git a/plugins/polycli-codex/.codex-plugin/plugin.json b/plugins/polycli-codex/.codex-plugin/plugin.json index ddca17b..41d5eb3 100644 --- a/plugins/polycli-codex/.codex-plugin/plugin.json +++ b/plugins/polycli-codex/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "polycli-codex", - "version": "0.6.27", + "version": "0.6.28", "description": "Codex skill adapter that routes provider CLI work through the shared polycli companion.", "author": { "name": "bing" diff --git a/plugins/polycli-codex/scripts/polycli-companion.bundle.mjs b/plugins/polycli-codex/scripts/polycli-companion.bundle.mjs index f6d4f84..1c27f5c 100755 --- a/plugins/polycli-codex/scripts/polycli-companion.bundle.mjs +++ b/plugins/polycli-codex/scripts/polycli-companion.bundle.mjs @@ -1610,7 +1610,7 @@ function buildCopilotInvocation({ args.push("--model", model); } if (resumeSessionId) { - args.push("--resume", resumeSessionId); + args.push("--session-id", resumeSessionId); } else if (continueLast) { args.push("--continue"); } @@ -2765,7 +2765,7 @@ function extractMiniMaxResponseFromMmxJson(text) { const message = choice?.message ?? choice?.delta ?? null; const contentText = Array.isArray(value.content) ? value.content.filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("") : ""; const response = typeof value.content === "string" ? value.content : typeof value.response === "string" ? value.response : typeof value.text === "string" ? value.text : contentText || (typeof message?.content === "string" ? message.content : ""); - const finishReason = value.finish_reason ?? value.finishReason ?? choice?.finish_reason ?? null; + const finishReason = value.finish_reason ?? value.finishReason ?? value.stop_reason ?? choice?.finish_reason ?? null; const toolCalls = Array.isArray(value.tool_calls) ? value.tool_calls : Array.isArray(message?.tool_calls) ? message.tool_calls : []; return { response, diff --git a/plugins/polycli-copilot/plugin.json b/plugins/polycli-copilot/plugin.json index 7dd2c2c..48d6153 100644 --- a/plugins/polycli-copilot/plugin.json +++ b/plugins/polycli-copilot/plugin.json @@ -1,7 +1,7 @@ { "name": "polycli-copilot", "description": "GitHub Copilot CLI adapter for the shared polycli companion.", - "version": "0.6.27", + "version": "0.6.28", "author": { "name": "bing" }, diff --git a/plugins/polycli-copilot/scripts/polycli-companion.bundle.mjs b/plugins/polycli-copilot/scripts/polycli-companion.bundle.mjs index f6d4f84..1c27f5c 100755 --- a/plugins/polycli-copilot/scripts/polycli-companion.bundle.mjs +++ b/plugins/polycli-copilot/scripts/polycli-companion.bundle.mjs @@ -1610,7 +1610,7 @@ function buildCopilotInvocation({ args.push("--model", model); } if (resumeSessionId) { - args.push("--resume", resumeSessionId); + args.push("--session-id", resumeSessionId); } else if (continueLast) { args.push("--continue"); } @@ -2765,7 +2765,7 @@ function extractMiniMaxResponseFromMmxJson(text) { const message = choice?.message ?? choice?.delta ?? null; const contentText = Array.isArray(value.content) ? value.content.filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("") : ""; const response = typeof value.content === "string" ? value.content : typeof value.response === "string" ? value.response : typeof value.text === "string" ? value.text : contentText || (typeof message?.content === "string" ? message.content : ""); - const finishReason = value.finish_reason ?? value.finishReason ?? choice?.finish_reason ?? null; + const finishReason = value.finish_reason ?? value.finishReason ?? value.stop_reason ?? choice?.finish_reason ?? null; const toolCalls = Array.isArray(value.tool_calls) ? value.tool_calls : Array.isArray(message?.tool_calls) ? message.tool_calls : []; return { response, diff --git a/plugins/polycli-opencode/package.json b/plugins/polycli-opencode/package.json index 539513c..10af50e 100644 --- a/plugins/polycli-opencode/package.json +++ b/plugins/polycli-opencode/package.json @@ -1,6 +1,6 @@ { "name": "@bbingz/polycli-opencode", - "version": "0.6.27", + "version": "0.6.28", "type": "module", "main": "./index.mjs", "exports": { diff --git a/plugins/polycli-opencode/scripts/polycli-companion.bundle.mjs b/plugins/polycli-opencode/scripts/polycli-companion.bundle.mjs index f6d4f84..1c27f5c 100755 --- a/plugins/polycli-opencode/scripts/polycli-companion.bundle.mjs +++ b/plugins/polycli-opencode/scripts/polycli-companion.bundle.mjs @@ -1610,7 +1610,7 @@ function buildCopilotInvocation({ args.push("--model", model); } if (resumeSessionId) { - args.push("--resume", resumeSessionId); + args.push("--session-id", resumeSessionId); } else if (continueLast) { args.push("--continue"); } @@ -2765,7 +2765,7 @@ function extractMiniMaxResponseFromMmxJson(text) { const message = choice?.message ?? choice?.delta ?? null; const contentText = Array.isArray(value.content) ? value.content.filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("") : ""; const response = typeof value.content === "string" ? value.content : typeof value.response === "string" ? value.response : typeof value.text === "string" ? value.text : contentText || (typeof message?.content === "string" ? message.content : ""); - const finishReason = value.finish_reason ?? value.finishReason ?? choice?.finish_reason ?? null; + const finishReason = value.finish_reason ?? value.finishReason ?? value.stop_reason ?? choice?.finish_reason ?? null; const toolCalls = Array.isArray(value.tool_calls) ? value.tool_calls : Array.isArray(message?.tool_calls) ? message.tool_calls : []; return { response, diff --git a/plugins/polycli/.claude-plugin/plugin.json b/plugins/polycli/.claude-plugin/plugin.json index c362e60..ecc7ce6 100644 --- a/plugins/polycli/.claude-plugin/plugin.json +++ b/plugins/polycli/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "polycli", - "version": "0.6.27", + "version": "0.6.28", "description": "Use multiple provider CLIs from one Claude Code plugin, including background job lifecycle.", "author": { "name": "bing" diff --git a/plugins/polycli/scripts/lib/prompt-runtime.mjs b/plugins/polycli/scripts/lib/prompt-runtime.mjs index 414ceaf..17767ed 100644 --- a/plugins/polycli/scripts/lib/prompt-runtime.mjs +++ b/plugins/polycli/scripts/lib/prompt-runtime.mjs @@ -56,7 +56,7 @@ export function buildPromptRuntimeOptions({ }; } - // kimi-code v0.6.0 has no per-invocation ask constraints: `-p` one-shot mode rejects + // kimi-code has no per-invocation ask constraints: `-p` one-shot mode rejects // --plan/--auto and the old --no-thinking/--max-steps-per-turn flags were removed (those // are now config.toml-level). kimi ask therefore uses the plain `-p` invocation. diff --git a/plugins/polycli/scripts/lib/review.mjs b/plugins/polycli/scripts/lib/review.mjs index 5a3160e..b00d2fd 100644 --- a/plugins/polycli/scripts/lib/review.mjs +++ b/plugins/polycli/scripts/lib/review.mjs @@ -98,7 +98,7 @@ export function assertReviewProviderSupported(provider) { const REVIEW_HARD_CONSTRAINTS = { kimi() { - // kimi-code v0.6.0 dropped --no-thinking/--max-steps-per-turn and its -p one-shot mode rejects + // kimi-code dropped --no-thinking/--max-steps-per-turn and its -p one-shot mode rejects // --plan/--auto, so there is no flag-based read-only lever. Review is prompt-only (the review // prompt forbids tools/edits), matching the minimax tier. No extra flags are emitted. return {}; diff --git a/plugins/polycli/scripts/polycli-companion.bundle.mjs b/plugins/polycli/scripts/polycli-companion.bundle.mjs index f6d4f84..1c27f5c 100755 --- a/plugins/polycli/scripts/polycli-companion.bundle.mjs +++ b/plugins/polycli/scripts/polycli-companion.bundle.mjs @@ -1610,7 +1610,7 @@ function buildCopilotInvocation({ args.push("--model", model); } if (resumeSessionId) { - args.push("--resume", resumeSessionId); + args.push("--session-id", resumeSessionId); } else if (continueLast) { args.push("--continue"); } @@ -2765,7 +2765,7 @@ function extractMiniMaxResponseFromMmxJson(text) { const message = choice?.message ?? choice?.delta ?? null; const contentText = Array.isArray(value.content) ? value.content.filter((part) => part?.type === "text" && typeof part.text === "string").map((part) => part.text).join("") : ""; const response = typeof value.content === "string" ? value.content : typeof value.response === "string" ? value.response : typeof value.text === "string" ? value.text : contentText || (typeof message?.content === "string" ? message.content : ""); - const finishReason = value.finish_reason ?? value.finishReason ?? choice?.finish_reason ?? null; + const finishReason = value.finish_reason ?? value.finishReason ?? value.stop_reason ?? choice?.finish_reason ?? null; const toolCalls = Array.isArray(value.tool_calls) ? value.tool_calls : Array.isArray(message?.tool_calls) ? message.tool_calls : []; return { response,