Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/web-workspace-hint.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---

web: Support a `?workspace=` URL hint plus an ordered `&folder=` list so embedded hosts (the VS Code extension view) can pin and focus the UI on their own workspace folders, in folder order. A host-pushed color-scheme message makes 'system' theme mode follow the host's theme when embedded in VS Code.
112 changes: 112 additions & 0 deletions .github/workflows/vscode-extension.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
name: vscode-extension

# Builds the Kimi Code VS Code extension (apps/kimi-vscode) into a universal
# vsix (self-contained: CLI server bundle + web UI; node-pty natives are
# lifted from the user's own VS Code install at runtime, so no per-platform
# packages are needed).
#
# STATUS: temporarily MANUAL-ONLY — runs solely via workflow_dispatch from the
# Actions tab. Not wired into release.yml yet. To start publishing, set the
# repository secret VSCE_PAT (Azure DevOps PAT for the `moonshot-ai`
# publisher) and dispatch with `publish: true`; to automate later, add a
# release trigger here or call this workflow from release.yml
# (see desktop-build.yml's workflow_call pattern).
on:
workflow_dispatch:
inputs:
publish:
description: 'Publish the vsix to the marketplace (needs VSCE_PAT)'
required: false
type: boolean
default: false
retention-days:
description: 'Artifact retention in days'
required: false
type: number
default: 7

permissions:
contents: read

jobs:
vsix:
name: Universal vsix
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup pnpm
uses: pnpm/action-setup@v6

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: 'pnpm'

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Build Kimi web assets
# The server serves apps/kimi-code/dist-web; it is staged into the
# extension's server/ runtime by prepare:server below.
run: |
pnpm --filter @moonshot-ai/kimi-web run build
node apps/kimi-code/scripts/copy-web-assets.mjs

- name: Build the CLI server bundle
# Single-file JS bundle (dist-native/intermediates/main.cjs) — the
# same artifact the SEA build embeds, but here it runs under VS Code's
# own Electron Node.
run: pnpm --filter @moonshot-ai/kimi-code run build:native:js

- name: Stage the extension server runtime
run: pnpm --filter kimi-vscode run prepare:server

- name: Package the vsix
run: pnpm --filter kimi-vscode run package

- name: Upload vsix
uses: actions/upload-artifact@v7
with:
name: kimi-vscode-vsix
retention-days: ${{ inputs.retention-days }}
path: apps/kimi-vscode/artifacts/*.vsix
if-no-files-found: error

publish:
name: Publish to marketplace
needs: vsix
if: inputs.publish
runs-on: ubuntu-24.04
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Setup pnpm
uses: pnpm/action-setup@v6

- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version-file: .nvmrc
cache: 'pnpm'

- name: Install vsce only
run: pnpm install --frozen-lockfile --filter kimi-vscode

- name: Download vsix
uses: actions/download-artifact@v6
with:
name: kimi-vscode-vsix
path: apps/kimi-vscode/artifacts

- name: Publish
shell: bash
env:
VSCE_PAT: ${{ secrets.VSCE_PAT }}
# --skip-duplicate makes re-runs idempotent after a half-published
# state. When platform-specific packages ever become necessary, build
# them in a matrix and pass all vsix files to --packagePath at once.
run: pnpm --filter kimi-vscode exec vsce publish --packagePath apps/kimi-vscode/artifacts/*.vsix --skip-duplicate
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ plugins/cdn/
.worktrees/
.kimi-code/local.toml
.kimi-sandbox/
.vscode/
.vscode/*
!.vscode/launch.json
!.vscode/tasks.json
# kimi-vscode packaging artifacts (staged runtime + built vsix)
apps/kimi-vscode/server/
apps/kimi-vscode/artifacts/

Dockerfile
docker-compose.yml
Expand Down
17 changes: 17 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Kimi Extension",
"type": "extensionHost",
"request": "launch",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}/apps/kimi-vscode",
"${workspaceFolder}"
],
"outFiles": ["${workspaceFolder}/apps/kimi-vscode/dist/**/*.cjs"],
"preLaunchTask": "build: kimi-vscode",
"presentation": { "group": "kimi", "order": 1 }
}
]
}
19 changes: 19 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build: kimi-vscode",
"type": "shell",
"command": "pnpm -C apps/kimi-vscode run build",
"problemMatcher": [],
"presentation": { "group": "kimi" }
},
{
"label": "watch: kimi-vscode",
"type": "shell",
"command": "pnpm -C apps/kimi-vscode exec tsdown --watch",
"isBackground": true,
"problemMatcher": []
}
]
}
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This is a TypeScript monorepo built for agent-assisted development. Keep the roo

- `apps/kimi-code`: the CLI / TUI application. It consumes core capabilities through `@moonshot-ai/kimi-code-sdk` and must not depend directly on `@moonshot-ai/agent-core`. When writing or modifying its terminal UI, use the `write-tui` skill (`.agents/skills/write-tui/SKILL.md`).
- `apps/kimi-web`: the browser web UI, a peer to the TUI. Vue 3 + Vite + vue-i18n; talks to the server over REST + WebSocket under `/api/v1`. It must not depend on `@moonshot-ai/agent-core` (wire types are re-implemented locally). Debug against the two engines via the root `pnpm dev:v1` / `pnpm dev:v2` backend scripts — the dev Sidebar shows the active backend and switches it at runtime. See `apps/kimi-web/AGENTS.md`.
- `apps/kimi-vscode`: the VS Code extension. An activity-bar webview shell that iframes the server-served kimi-web UI (no UI code of its own, same shell-model as `apps/kimi-desktop`); spawns the local server from the monorepo sources in dev and registers every VS Code workspace folder (multi-root aware) via `POST /api/v1/workspaces`. The web UI's `?workspace=` / `&folder=` query params (`src/lib/workspaceHint.ts`) pin the initial selection and focus all workspace listings on those folders, in VS Code folder order. See `apps/kimi-vscode/README.md`.
- `apps/vis`, `apps/vis/server`, `apps/vis/web`: visual debugging tools for sessions and replays.
- `packages/agent-core`: the unified agent engine, including Agent, Session, profile, skills, tools, plan, permission, background, records, the in-process DI service layer (`src/services/`), and other core capabilities.
- `packages/node-sdk`: the public TypeScript SDK and harness.
Expand Down
6 changes: 6 additions & 0 deletions apps/kimi-vscode/.vscodeignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
**/*.map
src/**
scripts/**
tsconfig.json
tsdown.config.ts
.gitignore
129 changes: 129 additions & 0 deletions apps/kimi-vscode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Kimi Code for VS Code

A VS Code extension (workspace package `kimi-vscode`) that adds a
Kimi icon to the activity bar. Clicking it opens a sidebar webview that embeds
the existing web UI (`apps/kimi-web`) — same UI as the browser and the desktop
app, not a reimplementation.

## How it works

It follows the `apps/kimi-desktop` model (shell + process manager, no UI or
backend code of its own):

1. On first open the extension starts the local Kimi server **in the
foreground** with `KIMI_CODE_EXPERIMENTAL_MULTI_SERVER=1` so it coexists
with a user's own daemon (its port falls through the kap-server `port + 1`
walk). What it spawns depends on how the extension itself was installed:
- **packaged (vsix)**: the CLI's single-file JS bundle (`server/main.cjs`)
running under VS Code's own Electron Node (`ELECTRON_RUN_AS_NODE=1` on
the extension host's `process.execPath` — the same switch VS Code's
`code` launcher uses). The bundle is staged into global storage together
with the embedded web UI and node-pty's native binaries, which are
**lifted from VS Code's own install** (`resources/app/node_modules/
node-pty`, the copy the integrated terminal uses — so the ABI always
matches; lifting the native payloads of another app is the same trick
`p2p-live-share` uses). No platform binaries ship inside the extension.
- **dev (this monorepo)**: the apps/kimi-code sources via tsx (same spawn
line as the root `pnpm dev:kap-server` script, plus `--log-level error`),
serving `apps/kimi-code/dist-web`.
2. The actual origin and bearer token are parsed from the server's ready line
(`Kimi server: http://127.0.0.1:PORT/#token=<token>`), then the extension
registers EVERY workspace folder (single- or multi-root) via
`POST /api/v1/workspaces`, in VS Code folder order (idempotent on root).
3. The webview is a one-file shell whose `<iframe>` points at that origin with
the token in the `#token=` fragment (exactly what `kimi web` appends when
opening a browser), the primary folder in `?workspace=`, and the full
folder list as repeatable `&folder=` params — kimi-web's workspace hint
(`apps/kimi-web/src/lib/workspaceHint.ts`) then pins its initial selection
to the primary folder AND focuses every workspace listing (sidebar groups,
switchers, per-workspace session loading) on exactly those folders, in the
VS Code folder order: the embedded view shows no other workspaces, and
add-workspace entry points are hidden. The server serves the built web UI
same-origin, so the iframe needs no CORS, no special kimi-web build, and no
copied code: the standard self-contained `vite build` output is used as-is.
Because VS Code theming never reaches the cross-origin iframe via
`prefers-color-scheme`, the extension also pushes its active theme kind
through a postMessage bridge (`window.activeColorTheme.kind` +
`onDidChangeActiveColorTheme`, answered by the shell after each load) —
kimi-web's 'system' mode then resolves to the VS Code theme at the
`data-color-scheme` attribute level.

`Kimi Code: Restart Server` (command palette) respawns the server and
re-renders the view. Closing VS Code kills the spawned server.

## Develop

Prereq — build the web UI assets that the server serves (same step as
kimi-desktop's dev flow, rerun when kimi-web / kimi-code change):

```bash
pnpm --filter @moonshot-ai/kimi-web run build
node apps/kimi-code/scripts/copy-web-assets.mjs
```

Then build the extension and open an Extension Development Host (a new VS Code
window running the extension, with this repo root as its workspace):

```bash
pnpm -C apps/kimi-vscode run dev
```

Click the Kimi icon in the activity bar. Server logs go to the
**Output → Kimi Code** channel.

## Debug (F5)

The repo root carries a tracked `.vscode/launch.json` ("Run Kimi Extension")
and `.vscode/tasks.json`. With the repo root folder open:

1. Press **F5** (Run and Debug → "Run Kimi Extension"). The `preLaunchTask`
rebuilds the extension (tsdown, with sourcemaps), then an Extension
Development Host window opens on this repo.
2. Set breakpoints in `apps/kimi-vscode/src/extension.ts` — they bind through
the emitted sourcemap into `dist/extension.cjs`.
3. Iterate: edit source → **Ctrl/Cmd-R (Restart)** in the debug toolbar (the
preLaunchTask rebuilds first). For watch-mode rebuilds, run the
`watch: kimi-vscode` task and use **Developer: Reload Window** in the dev
host.

Caveats: breakpoints only bind after the bundle is built; the spawned Kimi
server is a separate child process, so extension breakpoints do not pause it —
use **Output → Kimi Code** for its logs. In the dev host the extension prefers
the repo's CLI sources (tsx) over the packaged bundle, so after web or CLI
edits just rebuild (`pnpm --filter @moonshot-ai/kimi-web run build && node
apps/kimi-code/scripts/copy-web-assets.mjs`) and run `Kimi Code: Restart
Server` — no repackaging needed.

Checks:

```bash
pnpm -C apps/kimi-vscode run typecheck
```

## Package / release

The vsix is a **universal** package (no per-platform builds): it ships the
CLI's single-file server bundle + the web UI, and node-pty natives come from
the user's own VS Code at runtime.

```bash
# one-time prereqs (also run by CI):
pnpm --filter @moonshot-ai/kimi-web run build
node apps/kimi-code/scripts/copy-web-assets.mjs
pnpm --filter @moonshot-ai/kimi-code run build:native:js

# stage server/ (main.cjs + package.json + dist-web) and package the vsix:
pnpm -C apps/kimi-vscode run prepare:server
pnpm -C apps/kimi-vscode run package # -> apps/kimi-vscode/artifacts/*.vsix
```

Test the packaged flow without installing: `code --install-extension
apps/kimi-vscode/artifacts/kimi-vscode-*.vsix` (then reload the window and
open the Kimi view; uninstall afterwards with
`code --uninstall-extension moonshot-ai.kimi-vscode`).

Release automation lives in `.github/workflows/vscode-extension.yml` —
currently **manual-only** (`workflow_dispatch`), building the universal vsix
as an artifact and publishing to the marketplace only when dispatched with
`publish: true` (requires the `VSCE_PAT` secret for the `moonshot-ai`
publisher; `--skip-duplicate` makes re-runs idempotent).
Binary file added apps/kimi-vscode/media/kimi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions apps/kimi-vscode/media/kimi.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 72 additions & 0 deletions apps/kimi-vscode/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"name": "kimi-vscode",
"displayName": "Kimi Code",
"description": "Kimi Code for VS Code — an activity-bar webview that embeds the Kimi web UI, served by the local Kimi server.",
"version": "0.1.0",
"private": true,
"license": "MIT",
"publisher": "moonshot-ai",
"author": "Moonshot AI",
"homepage": "https://github.com/MoonshotAI/kimi-code",
"type": "module",
"main": "./dist/extension.cjs",
"repository": {
"type": "git",
"url": "https://github.com/MoonshotAI/kimi-code",
"directory": "apps/kimi-vscode"
},
"icon": "media/kimi.png",
"engines": {
"node": ">=24.15.0",
"vscode": "^1.90.0"
},
"categories": [
"AI",
"Chat"
],
"activationEvents": [],
"contributes": {
"viewsContainers": {
"activitybar": [
{
"id": "kimi-vscode",
"title": "Kimi Code",
"icon": "media/kimi.svg"
}
]
},
"views": {
"kimi-vscode": [
{
"type": "webview",
"id": "kimi-vscode.sidebar",
"name": "Kimi",
"icon": "media/kimi.svg",
"contextualTitle": "Kimi Code"
}
]
},
"commands": [
{
"command": "kimi-vscode.restart",
"title": "Restart Server",
"category": "Kimi Code"
}
]
},
"scripts": {
"build": "tsdown",
"dev": "tsdown && code --extensionDevelopmentPath=\"$(pwd)\" \"$(pwd)/../..\"",
"prepare:server": "node scripts/prepare-runtime.mjs",
"vscode:prepublish": "pnpm run build",
"package": "pnpm run build && mkdir -p artifacts && vsce package --out artifacts/",
"typecheck": "tsc --noEmit",
"clean": "rm -rf dist server artifacts"
},
"devDependencies": {
"@types/vscode": "~1.90.0",
"@vscode/vsce": "^3.6.2",
"tsdown": "0.22.0",
"typescript": "6.0.2"
}
}
Loading