From c08e0a11ec8b176b9db09fa26020dc9077b933c5 Mon Sep 17 00:00:00 2001 From: yousali Date: Thu, 23 Apr 2026 20:00:03 +0800 Subject: [PATCH 1/2] feat: add Kimi CLI skills-only support --- .changeset/kind-rings-notice.md | 11 +++ docs/cli.md | 2 +- docs/commands.md | 1 + docs/supported-tools.md | 3 +- .../.openspec.yaml | 2 + .../README.md | 3 + .../design.md | 85 +++++++++++++++++++ .../proposal.md | 38 +++++++++ .../specs/ai-tool-paths/spec.md | 12 +++ .../specs/cli-init/spec.md | 37 ++++++++ .../tasks.md | 22 +++++ openspec/specs/ai-tool-paths/spec.md | 7 +- openspec/specs/cli-init/spec.md | 20 ++++- src/core/config.ts | 1 + test/core/init.test.ts | 20 +++++ 15 files changed, 257 insertions(+), 7 deletions(-) create mode 100644 .changeset/kind-rings-notice.md create mode 100644 openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/.openspec.yaml create mode 100644 openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/README.md create mode 100644 openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/design.md create mode 100644 openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/proposal.md create mode 100644 openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/ai-tool-paths/spec.md create mode 100644 openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/cli-init/spec.md create mode 100644 openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/tasks.md diff --git a/.changeset/kind-rings-notice.md b/.changeset/kind-rings-notice.md new file mode 100644 index 0000000000..ab0b42d0f7 --- /dev/null +++ b/.changeset/kind-rings-notice.md @@ -0,0 +1,11 @@ +--- +"@fission-ai/openspec": minor +--- + +### New Features + +- **Kimi CLI support** — OpenSpec can now initialize Kimi CLI as a supported skills-only tool using `.kimi/skills/` + +### Other + +- Added Kimi-specific docs and init coverage aligned with skill-based `/skill:openspec-*` usage diff --git a/docs/cli.md b/docs/cli.md index ddcdaa0a41..5bbe6e0184 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -89,7 +89,7 @@ openspec init [path] [options] `--profile custom` uses whatever workflows are currently selected in global config (`openspec config profile`). -**Supported tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf` +**Supported tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `gemini`, `github-copilot`, `iflow`, `kilocode`, `kimi`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf` **Examples:** diff --git a/docs/commands.md b/docs/commands.md index fd4bb7fe13..9d641b516b 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -618,6 +618,7 @@ Different AI tools use slightly different command syntax. Use the format that ma | Cursor | `/opsx-propose`, `/opsx-apply` | | Windsurf | `/opsx-propose`, `/opsx-apply` | | Copilot (IDE) | `/opsx-propose`, `/opsx-apply` | +| Kimi CLI | Skill-based invocations such as `/skill:openspec-propose`, `/skill:openspec-apply-change` (no generated `opsx-*` command files) | | Trae | Skill-based invocations such as `/openspec-propose`, `/openspec-apply-change` (no generated `opsx-*` command files) | The intent is the same across tools, but how commands are surfaced can differ by integration. diff --git a/docs/supported-tools.md b/docs/supported-tools.md index dc55009204..b47b73c2a4 100644 --- a/docs/supported-tools.md +++ b/docs/supported-tools.md @@ -40,6 +40,7 @@ You can enable expanded workflows (`new`, `continue`, `ff`, `verify`, `sync`, `b | iFlow (`iflow`) | `.iflow/skills/openspec-*/SKILL.md` | `.iflow/commands/opsx-.md` | | Junie (`junie`) | `.junie/skills/openspec-*/SKILL.md` | `.junie/commands/opsx-.md` | | Kilo Code (`kilocode`) | `.kilocode/skills/openspec-*/SKILL.md` | `.kilocode/workflows/opsx-.md` | +| Kimi CLI (`kimi`) | `.kimi/skills/openspec-*/SKILL.md` | Not generated (no command adapter; use skill-based `/skill:openspec-*` invocations) | | Kiro (`kiro`) | `.kiro/skills/openspec-*/SKILL.md` | `.kiro/prompts/opsx-.prompt.md` | | OpenCode (`opencode`) | `.opencode/skills/openspec-*/SKILL.md` | `.opencode/commands/opsx-.md` | | Pi (`pi`) | `.pi/skills/openspec-*/SKILL.md` | `.pi/prompts/opsx-.md` | @@ -71,7 +72,7 @@ openspec init --tools none openspec init --profile core ``` -**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `forgecode`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf` +**Available tool IDs (`--tools`):** `amazon-q`, `antigravity`, `auggie`, `bob`, `claude`, `cline`, `codex`, `codebuddy`, `continue`, `costrict`, `crush`, `cursor`, `factory`, `forgecode`, `gemini`, `github-copilot`, `iflow`, `junie`, `kilocode`, `kimi`, `kiro`, `opencode`, `pi`, `qoder`, `qwen`, `roocode`, `trae`, `windsurf` ## Workflow-Dependent Installation diff --git a/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/.openspec.yaml b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/.openspec.yaml new file mode 100644 index 0000000000..8b394c6609 --- /dev/null +++ b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-04-23 diff --git a/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/README.md b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/README.md new file mode 100644 index 0000000000..335f01ef74 --- /dev/null +++ b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/README.md @@ -0,0 +1,3 @@ +# add-kimi-cli-skills-only-support + +Add Kimi CLI as a supported skills-only tool without a command adapter diff --git a/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/design.md b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/design.md new file mode 100644 index 0000000000..f8827390e1 --- /dev/null +++ b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/design.md @@ -0,0 +1,85 @@ +## Context + +Kimi CLI is not another Claude/Codex-style adapter target. Its extension model is built around discovered skills, not external command files: + +- skills are discovered from `.kimi/skills/` +- skills are exposed as `/skill:` +- no stable `.kimi/commands/` or prompt-file loading mechanism was found in the Kimi CLI codebase + +OpenSpec's existing architecture can already represent that shape: + +- `AI_TOOLS` can advertise a `skillsDir` +- `init` can install skills for any selected tool with `skillsDir` +- when command generation is attempted for a tool without an adapter, OpenSpec already records `commandsSkipped` + +## Goals + +- Add Kimi CLI using the same narrow `skills-only` pattern already used by Trae +- Keep the implementation small: metadata, docs, and a focused regression test +- Make the spec text match the current code path for adapterless tools + +## Non-Goals + +- designing a Kimi-specific command adapter without upstream support +- changing tool capability modeling across the whole generation pipeline +- reworking `delivery=commands` behavior for all adapterless tools + +## Decisions + +### 1. Represent Kimi CLI as an adapterless tool with `.kimi` + +Add a new `AI_TOOLS` entry: + +```ts +{ name: 'Kimi CLI', value: 'kimi', available: true, successLabel: 'Kimi CLI', skillsDir: '.kimi' } +``` + +This matches Kimi CLI's project-local skills root and lets existing init/update detection paths treat it as a supported tool. + +### 2. Do not add a Kimi command adapter + +No `src/core/command-generation/adapters/kimi.ts` file will be added, and the command adapter registry will remain unchanged. + +Rationale: + +- Kimi CLI exposes skills dynamically as `/skill:` +- the previous upstream PR stalled specifically because no legitimate adapter target was available +- adding a fake `.kimi/commands/...` path would create behavior OpenSpec cannot justify against upstream Kimi CLI behavior + +### 3. Document Kimi by its real invocation surface + +Kimi documentation in OpenSpec must use Kimi's actual skill invocation form: + +- supported-tools: no generated command files, use `/skill:openspec-*` +- commands doc: examples such as `/skill:openspec-propose` + +The docs must not claim generated `opsx-*` files or `/openspec-*` direct invocations for Kimi. + +### 4. Keep the change compatible with existing Trae-style behavior + +This change intentionally follows the current adapterless-tool behavior already present in the codebase: + +- skills are created whenever delivery includes skills +- command generation is skipped when no adapter exists +- init output reports `Commands skipped for: kimi (no adapter)` + +This keeps the Kimi change small and avoids overlapping implementation work already captured in `add-tool-command-surface-capabilities`. + +## Test Strategy + +Add one focused regression test in `test/core/init.test.ts`: + +- configure `delivery=both` +- run init with `--tools kimi` +- verify Kimi skills are created under `.kimi/skills/...` +- verify init reports the skipped command generation path for `kimi` + +That test is enough for this narrow change because: + +- adapterless update behavior already has generic coverage +- CLI tool-id rendering is derived from `AI_TOOLS` +- no command adapter or path formatting logic is being introduced + +## Risks / Trade-offs + +The main trade-off is scope: Kimi will inherit the current adapterless-tool behavior, including the broader limitation that `delivery=commands` is not yet capability-aware for skills-invocable tools. That is acceptable for this change because it matches the existing Trae/ForgeCode model and keeps the implementation aligned with verified Kimi CLI behavior. diff --git a/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/proposal.md b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/proposal.md new file mode 100644 index 0000000000..f2f447ee3c --- /dev/null +++ b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/proposal.md @@ -0,0 +1,38 @@ +## Why + +OpenSpec already has user demand for Kimi CLI support, but the previous upstream attempt stalled because it assumed Kimi needed a command adapter. Local review of the Kimi CLI codebase shows a different integration surface: Kimi discovers `SKILL.md` files from `.kimi/skills/` and exposes them through `/skill:`, but it does not provide a stable, file-based custom command directory like Claude Code or Codex. + +OpenSpec already supports tools that install skills without a command adapter. Trae and ForgeCode are the existing examples. Kimi should follow the same pattern instead of introducing undocumented `.kimi/commands/...` behavior. + +## What Changes + +- Add Kimi CLI as a supported tool in `AI_TOOLS` with `skillsDir: '.kimi'` +- Document Kimi CLI as a skills-only integration in supported tools and command usage docs +- Align change specs so `cli-init` explicitly allows selected tools with `skillsDir` but no registered command adapter + +## Capabilities + +### New Capabilities + +_None._ + +### Modified Capabilities + +- `ai-tool-paths`: define the `.kimi` skills root for Kimi CLI +- `cli-init`: clarify that adapterless tools remain valid selections and skip command-file generation with an informational message + +## Impact + +- `src/core/config.ts` - add Kimi CLI tool metadata +- `docs/supported-tools.md` - add Kimi CLI row and tool id +- `docs/commands.md` - document `/skill:openspec-*` usage for Kimi CLI +- `docs/cli.md` - include `kimi` in the supported `--tools` list +- `test/core/init.test.ts` - cover Kimi CLI as an adapterless tool during init + +## Non-Goals + +- Adding `src/core/command-generation/adapters/kimi.ts` +- Defining a `.kimi/commands/...` output path +- Changing the broader delivery model for adapterless tools under `delivery=commands` + +That broader capability-aware delivery work is already being explored separately in `add-tool-command-surface-capabilities`. This change stays narrow and follows the existing Trae/ForgeCode pattern. diff --git a/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/ai-tool-paths/spec.md b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/ai-tool-paths/spec.md new file mode 100644 index 0000000000..e981874b47 --- /dev/null +++ b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/ai-tool-paths/spec.md @@ -0,0 +1,12 @@ +# ai-tool-paths Delta Specification + +## MODIFIED Requirements + +### Requirement: Path configuration for supported tools + +The `AI_TOOLS` array SHALL include `skillsDir` for tools that support the Agent Skills specification. + +#### Scenario: Kimi CLI paths defined + +- **WHEN** looking up the `kimi` tool +- **THEN** `skillsDir` SHALL be `.kimi` diff --git a/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/cli-init/spec.md b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/cli-init/spec.md new file mode 100644 index 0000000000..193ff116a6 --- /dev/null +++ b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/specs/cli-init/spec.md @@ -0,0 +1,37 @@ +# cli-init Delta Specification + +## MODIFIED Requirements + +### Requirement: Slash Command Generation + +The command SHALL generate opsx slash commands only for selected tools that have a registered command adapter, while keeping adapterless tools valid for skill generation. + +#### Scenario: Generating slash commands for a tool with a registered adapter + +- **WHEN** a tool with a registered command adapter is selected during initialization +- **THEN** create 9 slash command files using the tool's command adapter: + - `/opsx:explore` + - `/opsx:new` + - `/opsx:continue` + - `/opsx:apply` + - `/opsx:ff` + - `/opsx:verify` + - `/opsx:sync` + - `/opsx:archive` + - `/opsx:bulk-archive` +- **AND** use tool-specific path conventions (e.g., `.claude/commands/opsx/` for Claude) +- **AND** include tool-specific frontmatter format + +#### Scenario: Selected tool has no command adapter + +- **GIVEN** a selected tool has `skillsDir` configured but no registered command adapter +- **WHEN** initialization includes command generation +- **THEN** skill generation for that tool SHALL still remain valid +- **AND** command-file generation SHALL be skipped for that tool +- **AND** the command output SHALL include `Commands skipped for: (no adapter)` + +#### Scenario: Kimi CLI skips command-file generation + +- **WHEN** the user selects Kimi CLI during initialization +- **THEN** OpenSpec SHALL treat it as a supported tool with `skillsDir: '.kimi'` +- **AND** command-file generation SHALL be skipped because no Kimi adapter is registered diff --git a/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/tasks.md b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/tasks.md new file mode 100644 index 0000000000..10a71dfb20 --- /dev/null +++ b/openspec/changes/archive/2026-04-23-add-kimi-cli-skills-only-support/tasks.md @@ -0,0 +1,22 @@ +## 1. Change Artifacts + +- [x] 1.1 Write proposal, design, and spec deltas for Kimi CLI skills-only support + +## 2. Tool Metadata + +- [x] 2.1 Add `Kimi CLI` to `src/core/config.ts` with `value: 'kimi'` and `skillsDir: '.kimi'` + +## 3. Documentation + +- [x] 3.1 Update `docs/supported-tools.md` with a Kimi CLI row that clearly states there is no command adapter +- [x] 3.2 Update `docs/commands.md` to document Kimi CLI usage via `/skill:openspec-*` +- [x] 3.3 Update `docs/cli.md` so the supported `--tools` list includes `kimi` + +## 4. Tests + +- [x] 4.1 Add a targeted init regression test for `--tools kimi` under adapterless command generation + +## 5. Validation + +- [x] 5.1 Validate the change artifacts with `openspec validate` +- [x] 5.2 Run targeted tests and fix any regressions diff --git a/openspec/specs/ai-tool-paths/spec.md b/openspec/specs/ai-tool-paths/spec.md index 9743f366d2..04cf38a0fa 100644 --- a/openspec/specs/ai-tool-paths/spec.md +++ b/openspec/specs/ai-tool-paths/spec.md @@ -2,7 +2,6 @@ ## Purpose Define AI tool path metadata used to generate OpenSpec skills and commands in tool-specific directories. - ## Requirements ### Requirement: AIToolOption skillsDir field @@ -38,6 +37,11 @@ The `AI_TOOLS` array SHALL include `skillsDir` for tools that support the Agent - **WHEN** looking up the `windsurf` tool - **THEN** `skillsDir` SHALL be `.windsurf` +#### Scenario: Kimi CLI paths defined + +- **WHEN** looking up the `kimi` tool +- **THEN** `skillsDir` SHALL be `.kimi` + #### Scenario: Tools without skillsDir - **WHEN** a tool has no `skillsDir` defined @@ -57,4 +61,3 @@ The system SHALL handle paths correctly across operating systems. - **WHEN** constructing skill paths on macOS or Linux - **THEN** the system SHALL use `path.join()` for consistency - diff --git a/openspec/specs/cli-init/spec.md b/openspec/specs/cli-init/spec.md index a1a70e59be..f53a0580a3 100644 --- a/openspec/specs/cli-init/spec.md +++ b/openspec/specs/cli-init/spec.md @@ -200,11 +200,11 @@ The command SHALL generate Agent Skills for selected AI tools. ### Requirement: Slash Command Generation -The command SHALL generate opsx slash commands for selected AI tools. +The command SHALL generate opsx slash commands only for selected tools that have a registered command adapter, while keeping adapterless tools valid for skill generation. -#### Scenario: Generating slash commands for a tool +#### Scenario: Generating slash commands for a tool with a registered adapter -- **WHEN** a tool is selected during initialization +- **WHEN** a tool with a registered command adapter is selected during initialization - **THEN** create 9 slash command files using the tool's command adapter: - `/opsx:explore` - `/opsx:new` @@ -218,6 +218,20 @@ The command SHALL generate opsx slash commands for selected AI tools. - **AND** use tool-specific path conventions (e.g., `.claude/commands/opsx/` for Claude) - **AND** include tool-specific frontmatter format +#### Scenario: Selected tool has no command adapter + +- **GIVEN** a selected tool has `skillsDir` configured but no registered command adapter +- **WHEN** initialization includes command generation +- **THEN** skill generation for that tool SHALL still remain valid +- **AND** command-file generation SHALL be skipped for that tool +- **AND** the command output SHALL include `Commands skipped for: (no adapter)` + +#### Scenario: Kimi CLI skips command-file generation + +- **WHEN** the user selects Kimi CLI during initialization +- **THEN** OpenSpec SHALL treat it as a supported tool with `skillsDir: '.kimi'` +- **AND** command-file generation SHALL be skipped because no Kimi adapter is registered + ### Requirement: Config File Generation The command SHALL create an OpenSpec config file with schema settings. diff --git a/src/core/config.ts b/src/core/config.ts index 4e6bb24b58..68f1abd33c 100644 --- a/src/core/config.ts +++ b/src/core/config.ts @@ -38,6 +38,7 @@ export const AI_TOOLS: AIToolOption[] = [ { name: 'iFlow', value: 'iflow', available: true, successLabel: 'iFlow', skillsDir: '.iflow' }, { name: 'Junie', value: 'junie', available: true, successLabel: 'Junie', skillsDir: '.junie' }, { name: 'Kilo Code', value: 'kilocode', available: true, successLabel: 'Kilo Code', skillsDir: '.kilocode' }, + { name: 'Kimi CLI', value: 'kimi', available: true, successLabel: 'Kimi CLI', skillsDir: '.kimi' }, { name: 'Kiro', value: 'kiro', available: true, successLabel: 'Kiro', skillsDir: '.kiro' }, { name: 'OpenCode', value: 'opencode', available: true, successLabel: 'OpenCode', skillsDir: '.opencode' }, { name: 'Pi', value: 'pi', available: true, successLabel: 'Pi', skillsDir: '.pi' }, diff --git a/test/core/init.test.ts b/test/core/init.test.ts index c2499e4d65..a3cee15216 100644 --- a/test/core/init.test.ts +++ b/test/core/init.test.ts @@ -168,6 +168,26 @@ describe('InitCommand', () => { expect(await fileExists(skillFile)).toBe(true); }); + it('should support Kimi CLI as an adapterless skills-only tool', async () => { + saveGlobalConfig({ + featureFlags: {}, + profile: 'core', + delivery: 'both', + }); + + const initCommand = new InitCommand({ tools: 'kimi', force: true }); + await initCommand.execute(testDir); + + const skillFile = path.join(testDir, '.kimi', 'skills', 'openspec-explore', 'SKILL.md'); + expect(await fileExists(skillFile)).toBe(true); + + const commandsDir = path.join(testDir, '.kimi', 'commands'); + expect(await directoryExists(commandsDir)).toBe(false); + + const logCalls = (console.log as unknown as { mock: { calls: unknown[][] } }).mock.calls.flat().map(String); + expect(logCalls).toContain('Commands skipped for: kimi (no adapter)'); + }); + it('should create skills for multiple tools at once', async () => { const initCommand = new InitCommand({ tools: 'claude,cursor', force: true }); From 624ad1a79562e9e2c9748935d851d20195ba5d86 Mon Sep 17 00:00:00 2001 From: yousali Date: Thu, 23 Apr 2026 20:17:01 +0800 Subject: [PATCH 2/2] test: relax Kimi adapterless log assertion --- test/core/init.test.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/core/init.test.ts b/test/core/init.test.ts index a3cee15216..7157e3a2b0 100644 --- a/test/core/init.test.ts +++ b/test/core/init.test.ts @@ -185,7 +185,11 @@ describe('InitCommand', () => { expect(await directoryExists(commandsDir)).toBe(false); const logCalls = (console.log as unknown as { mock: { calls: unknown[][] } }).mock.calls.flat().map(String); - expect(logCalls).toContain('Commands skipped for: kimi (no adapter)'); + expect( + logCalls.some( + (entry) => entry.includes('Commands skipped for: kimi') && entry.includes('(no adapter)'), + ), + ).toBe(true); }); it('should create skills for multiple tools at once', async () => {