Skip to content
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6d69435
refactor: rewrite kimi-cli from Python to Bun + TypeScript + React Ink
Yuandiaodiaodiao Apr 3, 2026
441cc09
feat(ts): persist input history to disk matching Python implementation
Yuandiaodiaodiao Apr 3, 2026
0608a11
Implement notification toast stack to separate UI notifications from …
Yuandiaodiaodiao Apr 3, 2026
9bc2058
feat(ui): enhance StatusBar with git info, tips rotation, and inline …
Yuandiaodiaodiao Apr 3, 2026
aa90610
feat(ui): improve slash menu, model command, keyboard shortcuts and w…
Yuandiaodiaodiao Apr 3, 2026
e6f62a4
fix: revert .python-version back to 3.14
Yuandiaodiaodiao Apr 3, 2026
5734481
feat(ui): add shell mode, @ file mention, multiline input, clipboard …
Yuandiaodiaodiao Apr 3, 2026
6443fc1
fix(ui): limit slash menu to 6 visible items and strip ctrl-key chars…
Yuandiaodiaodiao Apr 3, 2026
9956208
fix(ui): align status bar, slash menu, welcome box, and prompt with P…
Yuandiaodiaodiao Apr 3, 2026
86a1632
fix(ui): prevent Ctrl+X/O/V/J from leaking characters into input
Yuandiaodiaodiao Apr 3, 2026
549e31a
refactor(ui): unify input handling into single useInput in Prompt
Yuandiaodiaodiao Apr 3, 2026
15544af
feat(ui): add interactive panels for slash commands, Ctrl+V image pas…
Yuandiaodiaodiao Apr 3, 2026
580ecc1
fix(ui): add windowed scrolling to ChoicePanel for long lists
Yuandiaodiaodiao Apr 3, 2026
10d08f9
feat(ts): subagent model alias, concurrent tool exec, static message …
Yuandiaodiaodiao Apr 3, 2026
af250ec
feat(ts): approval UI, subagent registration, renderer, input refactor
Yuandiaodiaodiao Apr 4, 2026
25df79a
docs: update CLAUDE.md with full project architecture; add log4js dep
Yuandiaodiaodiao Apr 4, 2026
ec22fd5
feat(ts): shell refactor, panel system, approval flow, and UI improve…
Yuandiaodiaodiao Apr 5, 2026
090fa31
feat(ts): refactor kimisoul loop, enhance grep/ask_user tools, simpli…
Yuandiaodiaodiao Apr 5, 2026
0ad8bc0
feat(ts): handle terminal resize without remounting Shell UI
Yuandiaodiaodiao Apr 5, 2026
9f9b2dc
feat(ts): use resizeKey to rebuild Shell JSX subtree on terminal resize
Yuandiaodiaodiao Apr 5, 2026
46ee45a
feat(ts): align TS codebase structure 1:1 with Python, fix circular i…
Yuandiaodiaodiao Apr 5, 2026
4e16534
feat(wire): complete wire mode implementation and comprehensive docum…
Yuandiaodiaodiao Apr 5, 2026
0f685d0
feat(ts): enhance soul/toolset/wire layers, add TaskPanel, improve CL…
Yuandiaodiaodiao Apr 6, 2026
09bbd7b
test(e2e): update wire e2e tests, remove real LLM test, fix helpers
Yuandiaodiaodiao Apr 6, 2026
5f19230
test: update unit tests for config, context, grep, logging and compac…
Yuandiaodiaodiao Apr 6, 2026
4683fba
chore: untrack .python-version
Yuandiaodiaodiao Apr 6, 2026
0a60a91
chore: remove unused renderer infrastructure files and add linux-x64-…
Yuandiaodiaodiao Apr 7, 2026
6cc2f7e
feat(ts): align error hierarchy, retry and connection recovery with P…
Yuandiaodiaodiao Apr 8, 2026
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
134 changes: 134 additions & 0 deletions .github/workflows/ci-kimi-cli-ts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: CI - Kimi CLI (TypeScript)

on:
push:
branches: [main]
pull_request:
branches: [main]

permissions:
contents: write

jobs:
typecheck-and-test:
name: Typecheck & Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- run: bun install --frozen-lockfile

- name: Typecheck
run: ./node_modules/.bin/tsc --noEmit --skipLibCheck

- name: Test
run: bun test

build-binaries:
name: Build Binary (${{ matrix.os }}-${{ matrix.arch }})
needs: typecheck-and-test
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- os: linux
arch: x64
runner: ubuntu-latest
target: bun-linux-x64
artifact: kimi-linux-x64
- os: linux
arch: arm64
runner: ubuntu-latest
target: bun-linux-arm64
artifact: kimi-linux-arm64
- os: darwin
arch: x64
runner: macos-13
target: bun-darwin-x64
artifact: kimi-darwin-x64
- os: darwin
arch: arm64
runner: macos-14
target: bun-darwin-arm64
artifact: kimi-darwin-arm64
- os: windows
arch: x64
runner: windows-latest
target: bun-windows-x64
artifact: kimi-windows-x64

steps:
- uses: actions/checkout@v4

- uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- run: bun install --frozen-lockfile

- name: Build standalone binary
run: bun build src/kimi_cli_ts/index.ts --compile --outfile dist/kimi --target=${{ matrix.target }}

- name: Verify binary (unix)
if: matrix.os != 'windows'
run: |
chmod +x dist/kimi
dist/kimi --version
dist/kimi --help
Comment on lines +77 to +82
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 CI tries to run cross-compiled ARM64 binary on x64 runner, which will always fail

The linux-arm64 matrix entry uses runner: ubuntu-latest (x64) but compiles with --target=bun-linux-arm64. The verify step at lines 77-82 then tries to execute the ARM64 binary (dist/kimi --version) on an x64 host, which will fail with an exec format error. The condition if: matrix.os != 'windows' doesn't exclude this case.

Suggested change
- name: Verify binary (unix)
if: matrix.os != 'windows'
run: |
chmod +x dist/kimi
dist/kimi --version
dist/kimi --help
- name: Verify binary (unix)
if: matrix.os != 'windows' && matrix.arch == matrix.runner_arch
run: |
chmod +x dist/kimi
dist/kimi --version
dist/kimi --help
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


- name: Verify binary (windows)
if: matrix.os == 'windows'
run: |
dist\kimi.exe --version
dist\kimi.exe --help

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: dist/kimi*
if-no-files-found: error

release:
name: Create Release
needs: build-binaries
if: github.event_name == 'push' && github.ref == 'refs/heads/main' && startsWith(github.event.head_commit.message, 'release:')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Get version
id: version
run: echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT

- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts/

- name: Prepare release assets
run: |
mkdir -p release
for dir in artifacts/kimi-*; do
name=$(basename "$dir")
if [[ "$name" == *windows* ]]; then
(cd "$dir" && zip -r "../../release/${name}.zip" .)
else
chmod +x "$dir/kimi"
tar -czf "release/${name}.tar.gz" -C "$dir" kimi
fi
done
ls -la release/

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ steps.version.outputs.version }}
name: v${{ steps.version.outputs.version }}
files: release/*
generate_release_notes: true
13 changes: 12 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,15 @@ node_modules/
static/
.memo/
.entire
.claude
.claude

# TypeScript / Bun
out
*.tgz
coverage
*.lcov
logs
*.log
*.tsbuildinfo
.eslintcache
.cache
111 changes: 111 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
---
description: Use Bun instead of Node.js, npm, pnpm, or vite.
globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
alwaysApply: false
---

Default to using Bun instead of Node.js.

- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
- Use `bun test` instead of `jest` or `vitest`
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
- Bun automatically loads .env, so don't use dotenv.

## APIs

- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
- `Bun.redis` for Redis. Don't use `ioredis`.
- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
- `WebSocket` is built-in. Don't use `ws`.
- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
- Bun.$`ls` instead of execa.

## Testing

Use `bun test` to run tests.

```ts#index.test.ts
import { test, expect } from "bun:test";

test("hello world", () => {
expect(1).toBe(1);
});
```

## Frontend

Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.

Server:

```ts#index.ts
import index from "./index.html"

Bun.serve({
routes: {
"/": index,
"/api/users/:id": {
GET: (req) => {
return new Response(JSON.stringify({ id: req.params.id }));
},
},
},
// optional websocket support
websocket: {
open: (ws) => {
ws.send("Hello, world!");
},
message: (ws, message) => {
ws.send(message);
},
close: (ws) => {
// handle close
}
},
development: {
hmr: true,
console: true,
}
})
```

HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.

```html#index.html
<html>
<body>
<h1>Hello, world!</h1>
<script type="module" src="./frontend.tsx"></script>
</body>
</html>
```

With the following `frontend.tsx`:

```tsx#frontend.tsx
import React from "react";

// import .css files directly and it works
import './index.css';

import { createRoot } from "react-dom/client";

const root = createRoot(document.body);

export default function Frontend() {
return <h1>Hello, world!</h1>;
}

root.render(<Frontend />);
```

Then, run index.ts

```sh
bun --hot ./index.ts
```

For more information, read the Bun API docs in `node_modules/bun-types/docs/**.md`.
Loading