diff --git a/.kimi/README.md b/.kimi/README.md index 7cf5f0f9c..e479da82f 100644 --- a/.kimi/README.md +++ b/.kimi/README.md @@ -2,12 +2,12 @@ This directory contains the ECC (Everything Claude Code) configuration for the Kimi Code CLI harness. -## What is installed +## What Kimi Code discovers natively -- `rules/ecc/` — shared coding rules and guidelines -- `skills/ecc/` — reusable skills -- `commands/` — slash commands -- `AGENTS.md` — agent instructions +- `AGENTS.md` — project instructions loaded by Kimi Code's hierarchical instruction discovery +- `skills/` — project skills loaded by Kimi Code's native Agent Skills discovery + +ECC also copies shared rules, agents, and legacy command shims into `.kimi/` for portability and reference. Kimi Code's native invocation surface is Agent Skills (`/skill:` and `/flow:`), not arbitrary Markdown files in `commands/`. ## Manual install @@ -20,6 +20,8 @@ bash ./install.sh --target kimi --profile minimal - The `kimi` target installs into the project-level `./.kimi/` directory. - Kimi Code CLI's own config (`~/.kimi-code/config.toml`, plugins) is **not** touched by ECC install. - Use `npx ecc doctor --target kimi` to check install health. +- Kimi Code provider configuration remains separate. Use the [official providers and models guide](https://moonshotai.github.io/kimi-cli/en/configuration/providers.html) for Kimi API, OpenAI-compatible, Anthropic, or other supported endpoints. +- Kimi Code's [Agent Skills guide](https://moonshotai.github.io/kimi-cli/en/customization/skills.html) documents the `.kimi/skills/` discovery contract. ## Self-hosted model compute diff --git a/README.md b/README.md index 52f5075fd..c373cce50 100644 --- a/README.md +++ b/README.md @@ -50,32 +50,28 @@ ECC v2.0.0 adds the public Hermes operator story on top of that reusable layer: --- - +
- - - -
+ - ECC Pro
- Private repos · GitHub App · $19/seat/mo -
+ ECC Tools
+ ECC Pro + GitHub App +
+ Install free · Private repos from $19/seat/mo
+ - Sponsor
- Fund the OSS · From $5/mo -
+
+ Sponsor ECC +
+ Fund the OSS · From $5/mo
- + + + Discord
Community -
- Discussions · Q&A · Show & Tell -
-
- - GitHub App
- Install · PR audits · Free tier -
+
+ Discord · Q&A · Show & Tell
@@ -106,32 +102,31 @@ ECC v2.0.0 adds the public Hermes operator story on top of that reusable layer: This repo is the raw code only. The guides explain everything. - +
- - - -
+ -The Shorthand Guide to ECC
+The Shorthand Guide to ECC
The Shorthand Guide

Setup, foundations, philosophy. Read this first. (thread)
+ -The Longform Guide to ECC
+The Longform Guide to ECC
The Longform Guide

Token optimization, memory persistence, evals, parallelization. (thread)
- -
+ -The Shorthand Guide to Everything Agentic Security
+The Shorthand Guide to Everything Agentic Security
The Security Guide

Attack vectors, sandboxing, sanitization, CVEs, AgentShield. (thread) -
+ + + | Topic | What You'll Learn | |-------|-------------------| @@ -144,6 +139,52 @@ This repo is the raw code only. The guides explain everything. --- +## Self-host Kimi with ECC + Itô compute + +The Kimi Code harness and the model-serving layer are separate. ECC configures the agent harness; you bring an API endpoint or self-host an open-weight Kimi model on your own GPU capacity. + + + + + + + +
+ + Itô Markets
+ 1. Get GPU capacity +

+ Use Itô or any GPU provider. +
+ + Moonshot AI — Kimi
+ 2. Serve Kimi +

+ Expose the chosen checkpoint through a Kimi- or OpenAI-compatible endpoint. +
+ + ECC Tools
+ 3. Run Kimi Code with ECC +

+ Install project instructions and skills, then start kimi. +
+ +Configure the endpoint using Kimi Code's official provider guide, then install the ECC project surface: + +```bash +bash ./install.sh --target kimi --profile minimal +npx ecc doctor --target kimi +kimi +``` + +Kimi Code discovers the installed `.kimi/AGENTS.md` instructions and `.kimi/skills/` workflows natively. The installer dry-run and regression suite verify that the Kimi target stays inside the project-local `.kimi/` root. + +Run or self-host any open-source model on owned or rented GPUs. Itô is ECC's preferred compute sponsor; any GPU provider works. The sponsorship link is passive: it does not invoke an RFQ, reserve capacity, provision compute, or configure serving. Separately, `ecc ito find` invokes the explicitly configured canonical Itô CLI and submits a live authenticated RFQ; it does not reserve capacity. Managed inference through Itô is not live yet. + +This three-beat strip is also the video outline: capacity → serving endpoint → Kimi Code with ECC. + +--- + ## What's New ### v2.0.0 — The Agent Harness Operating System (Jun 2026) diff --git a/assets/images/community/discord.svg b/assets/images/community/discord.svg new file mode 100644 index 000000000..afd2765d5 --- /dev/null +++ b/assets/images/community/discord.svg @@ -0,0 +1,4 @@ + + Discord + + diff --git a/assets/images/community/heart.svg b/assets/images/community/heart.svg new file mode 100644 index 000000000..d92a60740 --- /dev/null +++ b/assets/images/community/heart.svg @@ -0,0 +1,4 @@ + + Support ECC + + diff --git a/package.json b/package.json index 5779d6d0a..213cc7a35 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "agent.yaml", "assets/ecc-icon.svg", "assets/hero.png", + "assets/images/community/", "assets/images/sponsors/", "agents/", "commands/", diff --git a/tests/scripts/ito-compute-sponsor.test.js b/tests/scripts/ito-compute-sponsor.test.js index 4fe29a65f..85b664c2f 100644 --- a/tests/scripts/ito-compute-sponsor.test.js +++ b/tests/scripts/ito-compute-sponsor.test.js @@ -56,6 +56,31 @@ function assertExactComputeRoute(content) { ); } +function assertExactHref(content, expectedHref) { + const expected = new URL(expectedHref); + const hrefs = [...content.matchAll(/\bhref="([^"]+)"/g)].map(match => match[1]); + const properties = [ + 'protocol', + 'hostname', + 'port', + 'username', + 'password', + 'pathname', + 'search', + 'hash', + ]; + const hasExactHref = hrefs.some((href) => { + try { + const candidate = new URL(href); + return properties.every(property => candidate[property] === expected[property]); + } catch { + return false; + } + }); + + assert.ok(hasExactHref, `Should include the exact href ${expectedHref}`); +} + function assertHonestComputeCopy(content) { assertExactComputeRoute(content); assert.match(content, /preferred compute sponsor/i); @@ -70,6 +95,16 @@ function assertHonestComputeCopy(content) { assert.doesNotMatch(content, /ECC only (?:links|provides this link)/i); } +function extractNamedTable(content, ariaLabel) { + const escapedLabel = ariaLabel.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const match = content.match( + new RegExp(`]*aria-label="${escapedLabel}"[^>]*>([\\s\\S]*?)<\\/table>`) + ); + + assert.ok(match, `Should include the "${ariaLabel}" table`); + return match[1]; +} + function main() { console.log('\n=== Testing Ito compute-sponsor surface ===\n'); @@ -128,6 +163,151 @@ function main() { || url.startsWith('https://fonts.googleapis.com/css2?') ))); }], + ['README keeps the three primary choices and all three guides inline', () => { + const readme = read('README.md'); + const primaryLinks = extractNamedTable(readme, 'ECC primary links'); + const guides = extractNamedTable(readme, 'ECC guides'); + + assert.strictEqual((primaryLinks.match(/ { + const readme = read('README.md'); + const localModelPath = extractNamedTable(readme, 'Local Kimi model path'); + + assert.strictEqual((localModelPath.match(/ { + const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-kimi-home-')); + const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-kimi-project-')); + + try { + const result = spawnSync( + process.execPath, + [ + path.join(REPO_ROOT, 'scripts', 'install-apply.js'), + '--target', + 'kimi', + '--profile', + 'minimal', + '--dry-run', + '--json', + ], + { + cwd: projectDir, + env: { ...process.env, HOME: homeDir }, + encoding: 'utf8', + maxBuffer: 20 * 1024 * 1024, + } + ); + assert.strictEqual(result.status, 0, result.stderr); + + const plan = JSON.parse(result.stdout).plan; + const targetRoot = path.resolve(plan.targetRoot); + const destinations = plan.operations.map(operation => ( + path.resolve(operation.destinationPath) + )); + const relativeDestinations = destinations.map(destination => ( + path.relative(targetRoot, destination).replaceAll(path.sep, '/') + )); + + assert.strictEqual(plan.target, 'kimi'); + assert.strictEqual(plan.adapter.id, 'kimi-project'); + assert.strictEqual(plan.adapter.kind, 'project'); + assert.deepStrictEqual(plan.warnings, []); + assert.ok(plan.operations.length > 0); + assert.ok(destinations.every(destination => ( + destination === targetRoot || destination.startsWith(`${targetRoot}${path.sep}`) + ))); + assert.ok(relativeDestinations.includes('AGENTS.md')); + assert.ok(relativeDestinations.some(destination => destination.startsWith('skills/'))); + assert.ok(relativeDestinations.every(destination => ( + !/^\.(?:claude|codex|cursor|gemini|hermes|opencode|openclaw|qwen|zed)\//.test(destination) + ))); + + const apply = spawnSync( + process.execPath, + [ + path.join(REPO_ROOT, 'scripts', 'install-apply.js'), + '--target', + 'kimi', + '--profile', + 'minimal', + '--json', + ], + { + cwd: projectDir, + env: { ...process.env, HOME: homeDir }, + encoding: 'utf8', + maxBuffer: 30 * 1024 * 1024, + } + ); + assert.strictEqual(apply.status, 0, apply.stderr); + assert.strictEqual(JSON.parse(apply.stdout).result.target, 'kimi'); + assert.ok(fs.existsSync(path.join(projectDir, '.kimi', 'AGENTS.md'))); + assert.ok(fs.readdirSync(path.join(projectDir, '.kimi', 'skills')).length > 0); + + const doctor = spawnSync( + process.execPath, + [ + path.join(REPO_ROOT, 'scripts', 'doctor.js'), + '--target', + 'kimi', + '--json', + ], + { + cwd: projectDir, + env: { ...process.env, HOME: homeDir }, + encoding: 'utf8', + maxBuffer: 30 * 1024 * 1024, + } + ); + assert.strictEqual(doctor.status, 0, doctor.stderr); + const doctorResult = JSON.parse(doctor.stdout).results.find(result => ( + result.adapter.target === 'kimi' + )); + assert.ok(doctorResult); + assert.strictEqual(doctorResult.exists, true); + } finally { + fs.rmSync(homeDir, { recursive: true, force: true }); + fs.rmSync(projectDir, { recursive: true, force: true }); + } + }], ['sponsor roster keeps Itô and Moonshot distinct from node tooling', () => { const sponsors = read('SPONSORS.md'); assert.ok(sponsors.includes('[**Itô**]')); diff --git a/tests/scripts/npm-publish-surface.test.js b/tests/scripts/npm-publish-surface.test.js index c00205ee1..bac522796 100644 --- a/tests/scripts/npm-publish-surface.test.js +++ b/tests/scripts/npm-publish-surface.test.js @@ -88,6 +88,7 @@ function buildExpectedPublishPaths(repoRoot) { "VERSION", "assets/ecc-icon.svg", "assets/hero.png", + "assets/images/community", "docs/CODEX-NAVIGATION-GUIDE.md", "docs/COMMAND-AGENT-MAP.md", "assets/images/sponsors", @@ -164,6 +165,8 @@ function main() { "plugins/ecc/.codex-plugin/plugin.json", "assets/ecc-icon.svg", "assets/hero.png", + "assets/images/community/discord.svg", + "assets/images/community/heart.svg", "docs/CODEX-NAVIGATION-GUIDE.md", "docs/COMMAND-AGENT-MAP.md", "schemas/install-state.schema.json",