### AGENTS # Agent Runtime Notes The Kun desktop app has one live agent runtime: the bundled **Kun** runtime. The same runtime also serves the standalone Kun TUI and non-interactive clients. GUI and TUI are independent clients that may be active at the same time; neither client owns the runtime lifecycle or the canonical model configuration. Do not add a second live provider, provider switcher, runtime diagnostics panel, or legacy CodeWhale/Reasonix process path. Code (including Design tasks), Work, and Connect phone all enter the same Kun HTTP/SSE boundary. Connect phone still uses the internal `claw` name, and Work retains the internal `write` name, for compatibility. ## Client Surface Boundary - Every turn records its initiating surface (`gui`, `tui`, `cli`, `api`, `im`, or `extension`). Continuations and delegated child turns inherit it. - Provider kind `gui` is reserved for capabilities that require the desktop workbench, such as Design canvas mutation or Computer Use. Those providers must not be advertised or executable on TUI/CLI/API/IM turns. - Runtime-backed goals, todos, plans, Skills, MCP, attachments, approvals, structured input, and subagents are shared Kun capabilities, not GUI tools. - Keep the immutable Kun system prompt client-neutral. Put interface-specific guidance in the dynamic per-turn context after the stable prefix. - Never switch a process-global tool registry or prompt based on whichever client connected most recently; GUI and TUI can run concurrently. ## Allowed Extension Path 1. Add protocol fields in `kun/src/contracts/`. 2. Add agent behavior in `kun/src/loop/`, `kun/src/services/`, or a new port/adapter under `kun/src/ports/` and `kun/src/adapters/`. 3. Add HTTP endpoints under `kun/src/server/routes/`. 4. Map the endpoint/event in `src/renderer/src/agent/kun-runtime.ts` and `src/renderer/src/agent/kun-mapper.ts`. 5. Add settings only under `agents.kun`. ## Prompt-Managed Plan Worktrees - `agents.kun.lab.planWorktree.enabled` gates this experiment and defaults to false. It applies only to Direct plan builds; Graph keeps its normal current- workspace flow and its own node isolation. - On execution, Renderer first saves the plan, then reads the exact local repository root, checked-out branch, and dirty-file count through the generic Git branch API. A non-Git workspace, unavailable Git, or detached HEAD blocks the send with a concrete error. - Renderer injects a fixed Git lifecycle protocol and the authoritative plan snapshot into the next user input on the current task. It does not fork or select another task, change the task workspace, close the plan panel, create a host run record, or monitor integration. - The Agent creates a uniquely named temporary branch/worktree, performs all implementation and validation there, rebases when the target moved, uses `merge --ff-only`, and cleans up only after ancestry or unchanged-work proof. - Uncommitted source-checkout changes remain exactly as-is and are excluded from the worktree baseline. The Agent must never stash, reset, clean, switch, commit, or otherwise manipulate them. If they block integration, preserve the temporary worktree/branch and report the recovery details. - Repository paths, branch names, prefixes, titles, and plan Markdown are structurally encoded inside the user input. None of this dynamic context may enter the immutable system prefix, including when switching Code and Design. - Legacy `planBuildRunId` and admission fields may still be parsed from stored history, but they are inert: they do not freeze input, recover a run, rebind a workspace, or receive special task presentation. ## Forbidden Paths - No `AgentSwitcher`. - No `ConnectionStatusBar`. - No `RuntimeDiagnosticsDialog` or runtime self-check UI. - No CodeWhale/Reasonix adapter, process manager, RPC bridge, updater, or importer. - No legacy drawing/painting starter card outside the current Design mode. - No `/usage` or `/runtime` slash command that opens a runtime control panel. The standalone TUI may expose `/usage` as a read-only report backed by `GET /v1/usage`; it must not add runtime diagnostics or control actions. ## Legacy Data Rule Old persisted keys may be read only inside settings migration: - `agentProvider: codewhale | reasonix | deepseek-runtime` maps to `kun`. - `agents.codewhale`, `agents.reasonix`, and legacy `deepseek` values seed `agents.kun` once. - Saved settings must contain only `agents.kun`. - Old Connect phone (internal Claw) `agentThreadIds.codewhale/reasonix` fold into `agentThreadIds.kun`. ## Verification Run: ```bash npm run typecheck npm test npm run build ``` Manual smoke: - Code can create a Kun thread, stream a reply, approve/deny tools, and interrupt a turn. - CodeWhale parity endpoints still work through Kun: thread search/archive filters, fork, session resume, request_user_input submit/cancel, and usage. - Cache telemetry uses DeepSeek native `prompt_cache_hit_tokens` / `prompt_cache_miss_tokens`; hot Kun turns should stay above 90% cache hit after the stable prefix is warm. - Immutable prefix drift and malformed tool-call/tool-result history must be caught before a request reaches DeepSeek. - A Code-workbench conversation can choose Code or Design for every next turn; accepted turns freeze their own surface while the Code-owned thread and timeline remain stable. The first accepted Design turn locks only its document/output/style profile, and later Code turns remain valid. - With the Lab experiment enabled, a Direct plan build sends the prompt-managed worktree protocol on the same task, leaves dirty source files untouched, and preserves unresolved worktree/branch state for manual recovery. Graph does not receive that protocol. - Work can open the workspace, request inline completion, and use selected-text assistant actions. - Connect phone can save settings and run a manual task through a Kun thread. - Settings -> Agents shows only Kun. The full plan is in [`docs/kun-architecture.md`](./kun-architecture.md). --- ### AGENTS.Zh CN # 代理运行时说明 Kun 桌面应用当前只有一个可运行的本地 Agent 运行时:仓库自带的同名 **Kun** 运行时。 不要新增第二套运行时、运行时切换器、运行时诊断面板,或旧的 CodeWhale / Reasonix 进程路径。Code(含 Design 任务)、Work、连接手机都统一走同一个 Kun HTTP/SSE 边界。连接手机在代码内部仍沿用 `claw` 命名,Work 内部仍沿用 `write` 命名,作为兼容标识。 ## 允许的扩展路径 1. 在 `kun/src/contracts/` 中新增协议字段。 2. 在 `kun/src/loop/`、`kun/src/services/` 或 `kun/src/ports/` / `kun/src/adapters/` 下新增端口与适配器来实现新行为。 3. 在 `kun/src/server/routes/` 下新增 HTTP 接口。 4. 在 `src/renderer/src/agent/kun-runtime.ts` 与 `src/renderer/src/agent/kun-mapper.ts` 中完成端点与事件映射。 5. 仅在 `agents.kun` 下新增设置项。 ## 提示词管理的计划 Worktree 边界 - `agents.kun.lab.planWorktree.enabled` 是默认关闭的实验开关,仅适用于 Direct 计划构建; Graph 保持当前工作区流程和自身节点隔离。 - Renderer 点击执行时先保存计划,再用通用 Git 分支 API 读取精确仓库根、本地当前分支和 脏文件数。非 Git、Git 不可用或 detached HEAD 会阻止发送,脏工作区不会被阻止。 - 应用只把固定 Git 生命周期协议和权威计划快照注入当前任务的下一条 user input,不创建 或切换任务、不改变 workspace、不关闭计划面板,也不持久化或监听宿主运行记录。 - Agent 从目标分支的已提交 HEAD 创建唯一临时分支和 worktree,在其中实现、测试、提交、 必要时 rebase,并只用 `merge --ff-only` 合入。源 checkout 的未提交修改不进入基线, 且不得被 stash、reset、clean、切换或提交。 - 只有证明临时提交已包含在目标分支后才能非强制清理。测试失败、冲突无法可靠解决或合入 受阻时必须保留 worktree 和分支并报告恢复信息。 - 动态分支、路径、标题、脏文件数和 Markdown 经过结构化编码后只进入 user input; Code / Design 切换也不得改变 immutable system prefix。 - 旧 `planBuildRunId` 等字段仅作历史解析,不再触发恢复、输入冻结、workspace 重绑或特殊展示。 ## 禁止路径 - 不要新增 `AgentSwitcher`。 - 不要新增 `ConnectionStatusBar`。 - 不要新增 `RuntimeDiagnosticsDialog` 或运行时自检 UI。 - 不要恢复 CodeWhale/Reasonix 的适配器、进程管理、RPC 桥、更新器或导入器。 - 不要恢复独立于当前 Design 模式之外的旧绘图/绘画启动卡片。 - 不要新增打开运行时控制面板的 `/usage` 或 `/runtime` 斜杠命令。 ## 旧数据兼容规则 旧的持久化 key 仅在 settings 迁移时按只读路径使用: - `agentProvider: codewhale | reasonix | deepseek-runtime` 映射为 `kun`。 - `agents.codewhale`、`agents.reasonix` 和旧 `deepseek` 的值会一次性写入 `agents.kun`。 - 保存后的 settings 仅保留 `agents.kun`。 - 旧连接手机(内部 Claw)的 `agentThreadIds.codewhale/reasonix` 会并入 `agentThreadIds.kun`。 ## 验证清单 执行: ```bash npm run typecheck npm test npm run build ``` 手工冒烟检查: - Code 可以创建 Kun 会话、流式回传回复、进行工具审批/拒绝、以及中断回合。 - CodeWhale 的等价能力应保持在 Kun 下可用:会话搜索/归档筛选、fork、会话恢复、`request_user_input` 提交与取消、usage 查询。 - 缓存指标使用 DeepSeek 原生 `prompt_cache_hit_tokens` / `prompt_cache_miss_tokens`;在稳定前缀热身后,热门对话的 hit rate 应长期保持在 90% 以上。 - 不可变前缀漂移与异常的 tool-call/tool-result 历史必须在请求下发 DeepSeek 前被拦截。 - Code 可在同一会话中切换下一回合的 Code / Design 意图;Design 在共享时间线中创建、 迭代、预览与导出设计稿。 - 开启实验后,Direct 计划构建在当前任务发送提示词 Worktree 协议,保持源目录脏文件原样, 并在失败时保留现场;Graph 不注入该协议。 - Work 可以打开工作区、发起 inline 补全、使用选中文本助手动作。 - 连接手机可以保存设置,并通过 Kun 会话执行手工任务。 - 设置 -> Agent 仅显示 Kun。 完整方案见 [`docs/kun-architecture.md`](./kun-architecture.md)。 --- ### CONTRIBUTING.En # Contributing [Simplified Chinese](./CONTRIBUTING.zh-CN.md) Thank you for contributing to Kun. This document explains how contributors should collaborate on the project, what standards to follow, and how changes should be proposed. ## Project Taste Code is easy. Good taste is rare. For Kun, taste means clear workflows, restrained interfaces, humane copy, and behavior that feels obvious after one use. Strong contributions show judgment, not just implementation. ## Contribution Scope Contributions are welcome for: - bug fixes - UI and UX improvements - runtime integration improvements - documentation - localization - build and release workflow improvements ## Branch Strategy The expected branch flow is: - `develop`: active collaboration and daily integration branch - `master`: stable release branch, updated by maintainers from `develop` - feature branches: optional short-lived branches created from `develop` Rules: - Do not develop directly on `master` - Prefer starting work from the latest `develop` - If you create a feature branch, branch off from `develop` - Open pull requests into `develop` unless maintainers explicitly request another base branch ## Before You Start 1. Make sure your local repository is up to date. 2. Switch to `develop`. 3. Install dependencies with `npm install`. 4. Confirm the project starts or builds successfully before making changes. ## Shape of a Typical PR A well-structured PR for Kun is focused and self-contained. It typically: - Touches **1-3 new files** and modifies **2-5 existing files** for wiring - Scopes to a single feature, fix, or documentation update - Includes a video or GIF if the UI changed - Includes unit tests if project logic changed - Passes `npm run typecheck`, `npm run build`, and `npm run test` If you discover related work that needs doing, open a separate issue rather than expanding the PR scope. ## Local Development Checklist Before opening a PR, contributors should verify: - the app still runs in development with `npm run dev` - type checking passes with `npm run typecheck` - production build passes with `npm run build` - unit tests pass with `npm run test` - UI changes include a video or GIF that shows the changed flow - logic changes include unit tests for the changed behavior - documentation is updated if behavior, setup, or workflow changed - localization is updated if user-facing text changed ### CI Verification Commands ```bash # Type checking npm run typecheck # Production build npm run build # Unit tests npm run test # Full development smoke test npm run dev ``` ## Coding Expectations - Keep changes focused and scoped - Avoid unrelated refactors in the same PR - Follow existing project structure and naming conventions - Prefer readable code over clever code - Preserve cross-platform behavior where possible - Do not commit secrets, API keys, tokens, or machine-specific private paths ## Documentation Expectations When your change affects project usage or collaboration, update the relevant docs: - `README.md` and `README.en.md` for project-level usage - `docs/DEVELOPMENT.md` and `docs/DEVELOPMENT.zh-CN.md` for workflow/process updates - this contributing guide when standards change ## Pull Request Standards Each PR should: - have a clear and specific title - explain what changed and why - describe user-facing impact - mention any setup, migration, or compatibility notes - stay reasonably small when possible Recommended PR structure: ```text ## Summary What this PR does in 1-2 sentences. ## Why The problem or gap it addresses. ## Validation How you verified the change (commands run, manual tests performed). ## Media Attach a video or GIF if UI changed. Screenshots are welcome as extra context. ## Tests List unit tests added or updated if project logic changed. ``` For most contributions, opening the PR from a short-lived feature branch is preferred over pushing directly to `develop` or `master`. ## Review Standards Reviewers should evaluate: - correctness - regressions - product taste and interaction quality - clarity and maintainability - consistency with current architecture - documentation completeness - whether validation steps were actually performed ## Commit Guidance Good commits are: - small enough to review - logically grouped - written with clear commit messages Follow conventional commits: - `feat:` New feature - `fix:` Bug fix - `docs:` Documentation changes - `refactor:` Code refactoring - `style:` Formatting, UI polish - `chore:` Maintenance tasks Examples: - `docs: rewrite README and contribution guides` - `feat: improve runtime connection recovery` - `fix: handle missing Kun binary path` ## Reporting Issues When reporting issues, please include: - Operating system and version - Kun version (from Settings or the About dialog) - Bundled `kun` version (`kun --version` in the same directory, if available) - Steps to reproduce the issue - Expected vs actual behavior - Relevant error messages, logs, or screenshots ## Contributor Behavior Please collaborate in a way that is: - respectful - clear - constructive - open to feedback If a change is large or risky, align with maintainers before investing heavily in implementation. ## Need Help? If requirements are unclear, ask for clarification before making broad architectural or workflow changes. Feel free to open an issue for any questions about contributing. ## License External contributions are accepted under the [Contributor License Agreement](../CLA.md). By submitting a contribution, you agree to grant the project owner the rights described in the CLA, including the right to sublicense and relicense your contribution as part of Kun under commercial, proprietary, noncommercial, or other license terms. The project itself remains available under the [PolyForm Noncommercial License 1.0.0](../LICENSE) unless the project owner grants a separate written commercial license. --- ### CONTRIBUTING # Contributing [简体中文](./CONTRIBUTING.zh-CN.md) Thank you for contributing to Kun. This document explains how contributors should collaborate on the project, what standards to follow, and how changes should be proposed. ## Project Taste Code is easy. Good taste is rare. For Kun, taste means clear workflows, restrained interfaces, humane copy, and behavior that feels obvious after one use. Strong contributions show judgment, not just implementation. ## Contribution Scope Contributions are welcome for: - bug fixes - UI and UX improvements - runtime integration improvements - documentation - localization - build and release workflow improvements ## Branch Strategy The expected branch flow is: - `develop`: active collaboration and daily integration branch - `master`: stable release branch, updated by maintainers from `develop` - feature branches: optional short-lived branches created from `develop` Rules: - Do not develop directly on `master` - Prefer starting work from the latest `develop` - If you create a feature branch, branch off from `develop` - Open pull requests into `develop` unless maintainers explicitly request another base branch ## Before You Start 1. Make sure your local repository is up to date. 2. Switch to `develop`. 3. Install dependencies with `npm install`. 4. Confirm the project starts or builds successfully before making changes. ## Shape of a Typical PR A well-structured PR for Kun is focused and self-contained. It typically: - Touches **1-3 new files** and modifies **2-5 existing files** for wiring - Scopes to a single feature, fix, or documentation update - Includes a video or GIF if the UI changed - Includes unit tests if project logic changed - Passes `npm run typecheck`, `npm run build`, and `npm run test` If you discover related work that needs doing, open a separate issue rather than expanding the PR scope. ## Local Development Checklist Before opening a PR, contributors should verify: - the app still runs in development with `npm run dev` - type checking passes with `npm run typecheck` - production build passes with `npm run build` - unit tests pass with `npm run test` - UI changes include a video or GIF that shows the changed flow - logic changes include unit tests for the changed behavior - documentation is updated if behavior, setup, or workflow changed - localization is updated if user-facing text changed ### CI Verification Commands ```bash # Type checking npm run typecheck # Production build npm run build # Unit tests npm run test # Full development smoke test npm run dev ``` ## Coding Expectations - Keep changes focused and scoped - Avoid unrelated refactors in the same PR - Follow existing project structure and naming conventions - Prefer readable code over clever code - Preserve cross-platform behavior where possible - Do not commit secrets, API keys, tokens, or machine-specific private paths ## Documentation Expectations When your change affects project usage or collaboration, update the relevant docs: - `README.md` and `README.en.md` for project-level usage - `docs/DEVELOPMENT.md` and `docs/DEVELOPMENT.zh-CN.md` for workflow/process updates - this contributing guide when standards change ## Pull Request Standards Each PR should: - have a clear and specific title - explain what changed and why - describe user-facing impact - mention any setup, migration, or compatibility notes - stay reasonably small when possible Recommended PR structure: ```text ## Summary What this PR does in 1-2 sentences. ## Why The problem or gap it addresses. ## Validation How you verified the change (commands run, manual tests performed). ## Media Attach a video or GIF if UI changed. Screenshots are welcome as extra context. ## Tests List unit tests added or updated if project logic changed. ``` For most contributions, opening the PR from a short-lived feature branch is preferred over pushing directly to `develop` or `master`. ## Review Standards Reviewers should evaluate: - correctness - regressions - product taste and interaction quality - clarity and maintainability - consistency with current architecture - documentation completeness - whether validation steps were actually performed ## Commit Guidance Good commits are: - small enough to review - logically grouped - written with clear commit messages Follow conventional commits: - `feat:` New feature - `fix:` Bug fix - `docs:` Documentation changes - `refactor:` Code refactoring - `style:` Formatting, UI polish - `chore:` Maintenance tasks Examples: - `docs: rewrite README and contribution guides` - `feat: improve runtime connection recovery` - `fix: handle missing Kun binary path` ## Reporting Issues When reporting issues, please include: - Operating system and version - Kun version (from Settings or the About dialog) - Bundled `kun` version (`kun --version` in the same directory, if available) - Steps to reproduce the issue - Expected vs actual behavior - Relevant error messages, logs, or screenshots ## Contributor Behavior Please collaborate in a way that is: - respectful - clear - constructive - open to feedback If a change is large or risky, align with maintainers before investing heavily in implementation. ## Need Help? If requirements are unclear, ask for clarification before making broad architectural or workflow changes. Feel free to open an issue for any questions about contributing. ## License External contributions are accepted under the [Contributor License Agreement](../CLA.md). By submitting a contribution, you agree to grant the project owner the rights described in the CLA, including the right to sublicense and relicense your contribution as part of Kun under commercial, proprietary, noncommercial, or other license terms. The project itself remains available under the [PolyForm Noncommercial License 1.0.0](../LICENSE) unless the project owner grants a separate written commercial license. ## 飞书 / Lark 流式 smoke 测试(发版前必跑) 本节对应 `feature/feishu-streaming-with-live-fix` 引入的飞书 / Lark SDK markdown 流式回复功能。发版前必须手工跑一遍下列 case。 ### 自动化已覆盖 | 维度 | 覆盖方式 | |---|---| | 单条流式正常路径 | `src/main/feishu-streamer.test.ts` happy-path case | | reasoning delta 过滤 | 同上,reasoning case | | 跨 turn 过滤 | 同上,cross-turn case | | append 失败 → setContent(partial) | 同上,append-failure case | | SSE 订阅失败 → 一次性 send fallback | `src/main/claw-runtime.test.ts` streaming fallback case | | `feishuStream = false` → 走原轮询 | 同上,feishuStream=false case | | 集成 chat 视图实时性 | `src/renderer/src/components/chat/MessageTimeline.tool-summary.test.ts` live bubble case | | onClawChannelActivity 自动切 thread | `src/renderer/src/store/chat-store-navigation-actions.test.ts` 路由 case | ### 手工 smoke checklist - [ ] **单条对话**:发"你好" → streaming 卡出现 → 1-2 秒内开始刷字 - [ ] **长回答**:写一段代码 → 验证 30k 字符切卡能跨第二张卡 - [ ] **故意限流**:把 `outbound.retry.maxAttempts = 1` → 触发限流 → 观察 fallback 到一次性 send - [ ] **故意 turn_failed**:用会抛错的 MCP 工具 → 观察 partial 补发 - [ ] **群聊 @bot**:`replyInThread: true` 仍生效,streaming 卡出现在 thread 里 - [ ] **DM**:`replyInThread: false` 默认 - [ ] **Connect phone 视图实时性**(关键 —— 本期修复):bot 收到消息后 chat 视图立即出现 streaming 文本,不卡 - [ ] **主动点击 thread**:从 streaming 状态切到该 thread → blocks 与 liveAssistant 内容一致 - [ ] **跨 turn 隔离**:在 turn A streaming 中再来一条消息触发 turn B → turn A 收尾,turn B 独立开卡 ### 验证命令 ```bash npm run typecheck npm run lint npm run test npm run build npm run build:kun # Electron 手动启动 + 真飞书账号(本机 + 测试机器人 appId/secret) npm run dev ``` --- ### CONTRIBUTING.Zh CN # 贡献说明 [English](./CONTRIBUTING.md) 感谢你为 Kun 做贡献。 这份文档说明了贡献者应该如何协作、遵循什么标准,以及改动应如何提交。 ## 项目品味 代码不难,难得的是好品味。 在 Kun 里,品味意味着清晰的流程、克制的界面、自然的文案,以及用一次就能理解的行为。好的贡献不只是把功能做出来,也要体现判断力。 ## 贡献范围 欢迎以下方向的贡献: - 缺陷修复 - UI / UX 优化 - 运行时集成改进 - 文档补充与修订 - 本地化内容完善 - 构建和发布流程优化 ## 分支策略 建议采用以下分支流转方式: - `develop`:协作与日常集成分支 - `master`:稳定发布分支,由维护者从 `develop` 合入 - 功能分支:可选,从 `develop` 拉出的短期分支 规则如下: - 不要直接在 `master` 上开发 - 日常开发优先从最新 `develop` 开始 - 如果要建立功能分支,应从 `develop` 拉出 - 除非维护者明确指定,否则 PR 默认提到 `develop` ## 开始之前 1. 先确保本地仓库已同步到最新状态。 2. 切换到 `develop` 分支。 3. 运行 `npm install` 安装依赖。 4. 在修改前先确认项目可以正常启动或构建。 ## 典型 PR 的结构 一个结构良好的 Kun PR 应该聚焦且自包含。通常: - 涉及 **1-3 个新文件**,修改 **2-5 个现有文件**进行接入 - 范围限定在单个功能、修复或文档更新 - 如果界面有变化,附带视频或 GIF - 如果项目逻辑有变化,附带单元测试 - 通过 `npm run typecheck`、`npm run build` 和 `npm run test` 如果在开发过程中发现其他需要处理的问题,请单独开 issue,不要扩大当前 PR 的范围。 ## 本地开发检查清单 在发起 PR 之前,贡献者应至少确认: - 应用可通过 `npm run dev` 正常开发运行 - `npm run typecheck` 通过 - `npm run build` 通过 - `npm run test` 通过 - UI 改动已附带展示变更流程的视频或 GIF - 逻辑改动已为变更行为补充单元测试 - 如果改动影响使用方式、安装方式或流程,已同步更新文档 - 如果改动影响用户可见文案,已同步更新本地化内容 ### CI 验证命令 ```bash # 类型检查 npm run typecheck # 生产构建 npm run build # 单元测试 npm run test # 完整开发冒烟测试 npm run dev ``` ## 代码要求 - 改动尽量聚焦、范围清晰 - 不要在同一个 PR 里夹带无关重构 - 尽量遵循现有项目结构和命名方式 - 优先写易读、易维护的代码 - 尽量保持跨平台行为一致 - 不要提交密钥、Token、API Key 或带有隐私的机器本地路径 ## 文档要求 当你的改动会影响项目使用方式或协作方式时,请同步更新相关文档: - `README.md` 和 `README.en.md`:项目级说明 - `docs/DEVELOPMENT.md` 和 `docs/DEVELOPMENT.zh-CN.md`:开发流程与协作规范 - 当前这份贡献说明:当贡献标准发生变化时更新 ## Pull Request 标准 每个 PR 应尽量满足: - 标题清晰、具体 - 说明改了什么以及为什么改 - 写清楚用户侧会受到什么影响 - 如有安装、迁移、兼容性注意事项,应明确说明 - 规模尽量可控,方便评审 推荐 PR 描述结构: ```text ## Summary 用一两句话说明这个 PR 做了什么。 ## Why 要解决的问题或填补的空白。 ## Validation 如何验证改动(执行的命令、手动测试步骤)。 ## Media 如果界面有变化,附上视频或 GIF。截图可以作为补充材料。 ## Tests 如果项目逻辑有变化,列出新增或更新的单元测试。 ``` 对于大多数贡献,建议从短期功能分支发起 PR,而不是直接向 `develop` 或 `master` 推送提交。 ## 评审标准 评审时建议重点关注: - 正确性 - 是否引入回归 - 产品品味与交互质量 - 可读性与可维护性 - 是否符合当前架构方向 - 文档是否同步完整 - 校验步骤是否真实执行 ## Commit 建议 好的 Commit 应该: - 颗粒度适中,便于审阅 - 按逻辑分组 - 提交信息清晰明确 遵循 conventional commits 规范: - `feat:` 新功能 - `fix:` 缺陷修复 - `docs:` 文档变更 - `refactor:` 代码重构 - `style:` 格式化、界面调整 - `chore:` 维护任务 示例: - `docs: rewrite README and contribution guides` - `feat: improve runtime connection recovery` - `fix: handle missing Kun binary path` ## 提交 Issue 提交 Issue 时,请尽可能包含以下信息: - 操作系统及版本 - Kun 版本(可在设置页或关于对话框查看) - 内置的 `kun` 版本(如可用,在同目录下执行 `kun --version`) - 复现步骤 - 预期行为与实际行为 - 相关错误信息、日志或截图 ## 贡献者协作方式 请以以下方式协作: - 尊重他人 - 表达清晰 - 反馈建设性 - 愿意讨论与调整 如果改动范围较大或风险较高,建议先和维护者对齐方向,再投入较多实现成本。 ## 需要帮助? 如果需求或边界不明确,先沟通确认,再进行较大范围的架构或流程调整。如有任何关于贡献的问题,欢迎提 Issue。 ## 许可证 外部贡献基于英文 [Contributor License Agreement](../CLA.md) 接收。提交贡献即表示你同意 CLA 中的授权条款,包括项目所有者可将你的贡献作为 Kun 的一部分进行再授权、商业授权或其他形式授权。 项目本身默认仍基于 [PolyForm Noncommercial License 1.0.0](../LICENSE) 发布;除非项目所有者另行提供书面商业授权。 --- ### DESIGN MODE # Design mode (设计模式) Design mode is a Design task type inside the **Code** (`chat`) workbench, alongside the top-level **Work** workspace. It is an AI design workstation: you describe a UI, an agent produces a single-file interactive artifact, a live canvas renders it, and you iterate — with a first-class, two-way bridge to the coding agent that ships it. > Implementation history lives in [`DESIGN_MODE_PLAN.md`](../DESIGN_MODE_PLAN.md) > (the original plan) and the `feat(design): …` commits on `feature/design-mode`. --- ## 1. What it is The loop: 1. Describe a design in the right pane (with a design-context form: brand color, tone, design-system preset, structured tokens). 2. The design agent writes **one self-contained HTML document** to a reserved path under `.kun-design/`. 3. The center **canvas** live-renders it (a ``, refreshed as the agent writes). 4. Iterate in place — each turn snapshots a new version. 5. Hand the approved design to the coding agent ("Implement in code"), which publishes a shared design system and opens a fresh code thread. Product positioning: | Mode | Primary job | Output | |---|---|---| | **Code** | Work against a real repository, edit files, run commands, review changes, and ship implementation. | Code diffs, plans, todos, reviews, runnable app changes. | | **Design** | Turn requirements, references, or existing UI into visual direction before implementation. | UI drafts, interactive HTML prototypes, graph artifacts, exported prototypes, shared `DESIGN_SYSTEM.md`. | | **Work** | Draft, edit, polish, and export office documents. | Document workspaces, inline completions/edits, `HTML / PDF / DOC / DOCX` exports. | Design mode is therefore not a legacy painting shortcut. It is the design leg of Kun's requirement -> design -> plan -> code -> verify loop, sharing the same runtime, provider configuration, approvals, and thread mechanics as Code and Work. Positioning: this is the only one of the surveyed tools where design lives **inside the coding-agent IDE** with an organic design↔code loop (see §11). --- ## 2. Architecture Design mode renders inside the Code `Workbench`, alongside Work — `AppShell` only forks `settings` vs `Workbench`, so no shell change was needed. - **Route**: `AppRoute` gains `'design'`; `openDesign` / `ensureDesignThreadForWorkspace` / `createDesignThread` historically mirrored the internal `write` navigation actions (`chat-store-navigation-actions.ts`). The design thread is tracked in a thin registry (`design/design-thread-registry.ts`). - **Tabs**: `WorkspaceModeTabs` renders Code / Work; the shared composer selects Code / Design task type. - **Three panes** (`components/design/`): - `DesignSidebar` — mode tabs + artifact list (per-kind icons, version count, implement / delete / rename, provenance + drift badges) + "New design" / "New canvas". - `DesignCanvas` — the live canvas: preview / code (shiki-highlighted) / live (the real running app from code mode) views, viewport switch, device frame, light/dark background, export, reload. Early-returns `DesignGraphView` for `graph` artifacts. - `DesignAgentPanel` — the composer + a collapsible design-context form (brand-color picker, tone chips, design-system preset) + iterate/new/busy hint. - **Store**: `design/design-workspace-store.ts` (thin zustand store) holds artifacts, active id, canvas/viewport state, the design context, settings-driven knobs, the error banner, and the design-system hash. It is the single owner of artifact mutations + on-disk persistence. ### File map ``` src/renderer/src/design/ design-types.ts DesignArtifact, DesignArtifactKind ('html'|'graph'), DesignCanvasView, viewports, createDesignArtifactId design-context.ts DesignContext, presets, craft baseline, formatDesignContextLines / formatDesignSystemMarkdown, hashDesignSystem design-turn-prompt.ts buildDesignTurnPrompt / buildDesignFromCodePrompt / buildDesignImageNodePrompt design-implement-prompt.ts buildImplementDesignPrompt (design → code) design-graph.ts node-canvas doc model + topo sort design-graph-run.ts runDesignNode (node → agent turn → await output) design-artifact-persistence.ts meta.json sidecars + reconstruct-from-disk design-workspace-store.ts the store src/renderer/src/components/design/ DesignWorkspaceView / DesignSidebar / DesignCanvas / DesignAgentPanel / DesignGraphView ``` --- ## 3. Artifact model & durability A `DesignArtifact` = `{ id, kind, title, relativePath, createdAt, updatedAt, versions[], implementedAt?, implementedThreadId?, implementedDesignSystemHash? }`. - **On disk**: each artifact is a directory `.kun-design//`: - HTML artifacts: `v1.html`, `v2.html`, … (the latest is the current document). - Graph artifacts: `graph.json` (+ `.html` / `.png` node outputs). - `meta.json` — a sidecar mirroring the artifact's metadata. - HTML `meta.json` may include `prototypeLinks[]`, the outgoing planned flow transitions to other screen artifacts. - **Durability**: the artifact list used to be in-memory only and was lost on reload. Now every mutation (`upsert` / `addVersion` / `markImplemented` / `rename`) writes `meta.json`, and on load `rehydrateArtifacts()` rebuilds the list from `window.kunGui.listWorkspaceDirectory('.kun-design')` — reading each `meta.json`, falling back to reconstructing from the on-disk files when a sidecar is missing. `removeArtifact` deletes the whole dir (`deleteWorkspaceEntry`) and a session-scoped `removedArtifactIds` guard stops a not-yet-flushed delete from resurfacing on the next mount. --- ## 4. The design loop - `buildDesignTurnPrompt` produces the turn: write ONE standalone HTML document to the exact reserved path, build it incrementally (small skeleton then `edit` calls, every payload < ~4000 chars), finish with ``. The design context + the craft baseline (§10) are appended. - **Live canvas**: `DesignCanvas` watches the artifact file (`startWriteWorkspaceFileWatch`, with a retry while the file does not yet exist) and reloads the webview (not remount) once a complete document exists. The webview is used (not `srcdoc`/`blob`) because the parent CSP kills inline-script iframes; `authorizeWritePrototype` allow-lists the `file://` URL. - **Iterate-in-place**: when an artifact is active, the next turn passes its current version as `basePath` ("read it first, apply ONLY the changes") instead of starting fresh; a new version is appended. --- ## 5. Design ↔ code integration (the moat) This is what makes design mode "organic", not isolated: 1. **Implement in code** (`implementDesignInCode`) — publishes the shared design system to `.kun-design/DESIGN_SYSTEM.md`, builds an implement prompt, opens a **fresh code thread**, dispatches the turn, and records provenance (`markImplemented`). 2. **Shared design system** — `DESIGN_SYSTEM.md` is the single source of truth both the design agent and the code agent read; the design context is injected into both. 3. **Reverse-design** (`sendDesignFromCode`) — turn an existing UI file into an iterable HTML mockup (the inverse of implement), closing the round trip. Exposed from the file-preview panel ("Redesign"). 4. **Requirement → design** (`exploreSddRequirementInDesign`) — a bridge from the SDD requirement flow into the design canvas. 5. **Unified preview** — the canvas `live` view shows the real running app served by code mode's dev server, so the design canvas and the real product share one surface. 6. **Bidirectional drift** — provenance is two-way: - **Design drift** (`updatedAt > implementedAt`) → ⟳ badge ("re-implement"). - **Code drift** — `implementDesignInCode` snapshots a hash of the published `DESIGN_SYSTEM.md` onto the artifact; on load the store re-reads `DESIGN_SYSTEM.md` and compares, so an artifact implemented against an **older** shared design system shows a ⚠ badge. ✓ = in sync. --- ## 6. Node canvas (graph artifacts) A `graph` artifact is a small design pipeline on a React Flow canvas (`DesignGraphView`), persisted as `graph.json`. - **Node kinds**: - `prompt` — carries text / context. - `design` — generates an HTML artifact at `.kun-design//.html`. - `image` — generates an image at `.kun-design//.png` (multimodal). - **Execution engine** (`runDesignNode` + `runGraph`): **Run** topologically orders the nodes (Kahn; cycles are rejected), then runs each `design`/`image` node **in order** — collecting upstream nodes' text along incoming edges, dispatching one agent turn, and awaiting that node's output before the next. HTML nodes poll the file until it ends in ``; image nodes poll the directory until the `.png` appears. Per-node status is live (running / done / error); design outputs preview inline (a docked webview panel), image outputs render inline (`readWorkspaceImage` → ``). - Minimap + grid background; hover-delete on nodes; empty-graph hint. --- ## 7. Settings Design settings are a full slice (`AppSettingsV1.design`, `DesignSettingsV1`, ~20 fields: workspace root, brand/tone/preset, tokens (radius/density/font), model / provider / reasoning effort, generation prompt, implement stack hint, inject-into-code, publish-design-system, canvas defaults, live refresh, device frame, …). Rendered as a multi-card settings tab. > **Landmine — adding a design settings field touches 9 places** or settings-sync > infinite-loops: `DesignSettingsV1` + the patch type, `defaultDesignSettings` / > `normalizeDesignSettings` / `mergeDesignSettings`, the `.strict()` > `designSettingsPatchSchema` (in `app-ipc-schemas.ts`), `index.ts applySettingsPatch`, > `settings-utils.ts mergeSettings/coerceRendererSettings`, the store > `loadDesignSettings`, and the UI. The `.strict()` belongs on the design sub-schema, > not the top-level envelope. --- ## 8. Export `design:export-prototype` (main IPC, mirrors `write:export`) exports the current prototype to a standalone **HTML** file or a **PDF** (rendered via a hidden `BrowserWindow` + `printToPDF`, reusing the internal Work export pipeline), through a native save dialog that defaults to the artifact title. Buttons live on the canvas toolbar. --- ## 9. Built-in "design system & craft" skill `src/main/skill-bundled.ts` seeds a built-in skill into `~/.kun/skills/design-system/` on first launch (idempotent marker, mirrors `ensureBundledUiPlugins`). Its `SKILL.md` carries design-system-first thinking and the anti-AI-slop craft baseline, so the agent auto-gets design guidance (triggers on design prompts, or via `load_skill`). Honors deletion; appears after the next runtime restart. --- ## 10. Design context, tokens & craft - **Design context** = brand color, tone, design-system preset, structured tokens (radius / density / font), free-form guidelines. It is injected into the design turn, the implement turn, and the reverse-design turn. - **14 presets** (shadcn / radix / material / iOS / fluent / ant / chakra / carbon / polaris / bootstrap / geist / brutalism / editorial / none). - **Craft baseline** (`DESIGN_CRAFT_LINES`) — an anti-AI-slop rubric appended to every generation prompt: avoid cream/sand backgrounds, purple→blue gradients, bounce easing, nested cards, low-contrast gray-on-tint; verify contrast; provide a `prefers-reduced-motion` fallback; use a real type scale and one spacing scale. --- ## 11. Positioning vs reference projects | Capability | Design mode | AI-CanvasPro | open-design | penpot | |---|---|---|---|---| | Paradigm | design mode **inside** a coding-agent IDE | multimodal generative node canvas | agent-native design app | vector design platform | | Artifact | single-file HTML | text/image/video/audio/3D | web/mobile/decks/video | vector SVG/components | | **Design ↔ code** | **strong, in-IDE loop** | none | hand-off to code agents | MCP + design-as-code | | Design system / tokens | presets + structured tokens + `DESIGN_SYSTEM.md` | none | 150 `DESIGN.md` systems | first-class design tokens | | Export | HTML / PDF | local save | HTML/PDF/PPTX/MP4 | SVG/CSS/HTML/JSON | | Node canvas | prompt/design/image + run engine | mature (7 node types) | automation | none | | Collaboration / MCP | — / deferred (§14) | — | parallel sessions | realtime / MCP | The deliberate **moat** is design↔code; the deliberate **non-goals** are penpot's vector editor and realtime collaboration (heavy, off the agent-native thesis). --- ## 12. Stitch alignment plan Reference: [Stitch - Design with AI](https://stitch.withgoogle.com/) and Google Labs' March 18, 2026 announcement describe Stitch as an AI-native infinite software-design canvas for natural-language UI creation, project-wide design agent reasoning, images/text/code as canvas context, Agent Manager parallel directions, DESIGN.md import/export, instant prototype playback, voice critiques, and MCP/developer-tool export. Kun should align by strengthening the same workflow spine while keeping the in-IDE design-to-code advantage: 1. **Canvas maturity first**: selection, lock/visibility, nudge, snap, grouping, resize, rotate, layer order, device frames, and keyboard handling must feel predictable before adding larger agent flows. Locked or hidden layers are non-editable across hit-test, marquee, inspector, delete/duplicate, drag, and keyboard nudge. Keyboard editing now includes group/ungroup, stable block layer ordering, and ancestor-root normalization for duplicate/delete. The inspector exposes multi-selection align and distribute controls backed by the same shape ops the design agent can call. Resize handles now use the same object/grid snap guides as move gestures, while only moving the dragged edge. Move snapping now ignores hidden layers and descendants of hidden parents, so invisible board content cannot create ghost alignment pulls. The layers panel now flattens the board into a predictable top-to-bottom tree, supports collapsing frame/group subtrees, and exposes explicit lock/visibility controls for screen readers and tooltips. Rectangle, ellipse, frame, and screen-frame creation now use the same snap guide system while preserving strict square/circle drawing when Shift is held. Arrow and line endpoints snap to grid/object guide positions during creation, while Shift keeps its independent angle-lock behavior. The zoom menu now exposes explicit grid and object-snap toggles, so users can inspect or draw freely without changing hidden state. The canvas now includes a minimap navigator that shows visible top-level board content, highlights selected layers, and recenters the viewport by click/drag for multi-screen and multi-direction boards. Text creation supports both click-to-edit and drag-to-size snapped note boxes so board text can act as first-class design context. Arrow/line point editing now supports vertex drag, midpoint insertion, and Option/Alt-click or double-click vertex deletion for path cleanup. Drag-created shapes, text boxes, screens, lines, and freehand strokes now record one undo entry using their final bounds/points, so redo restores the object the user actually drew instead of the pointer-down preview. Cmd/Ctrl+D now duplicates the editable selection roots as one selected block with a single undo/redo entry, matching the copy/paste and Alt/Option-drag interaction model; cloned frame subtrees now rewrite internal frame ownership so descendants point at the new frame, not the source. Shape copy/cut/paste now works for editable selection roots, preserves full subtrees, offsets repeat pastes, and keeps cut and paste undo/redo as single canvas changes; image paste remains the fallback when no shape clipboard exists. Freehand strokes are simplified on commit to preserve the drawn contour while keeping render/persistence/AI-snapshot payloads bounded. Rotation now has visible corner handles, undo grouping, and 15°/45° modifier snapping instead of relying on the inspector field alone. Spacebar pan is a true temporary hand tool and restores the previous drawing/editing tool on release; middle-mouse drag also temporarily routes to the hand tool for infinite-board navigation without changing the active drawing/editing tool. Alt/Option-drag duplicates the current editable selection only once the pointer really moves, drags the copy, and records duplicate+move as a single undoable canvas change. Shift-dragging an existing selection now locks movement to the dominant horizontal or vertical axis while preserving same-axis snapping. Shift/Cmd/Ctrl marquee selection adds hits to the existing selection instead of replacing it; Alt/Option marquee subtracts hits from the current selection. Marquee results are normalized to editable root layers so parent and child overlaps do not create mixed selections. Fit-all now frames visible board content, while fit-selection uses the same editable-root selection semantics as marquee/duplicate/delete. 2. **Infinite board as project memory**: the board is the source of visual context for screens, references, image slots, text notes, tokens, components, and generated variants. Agent snapshots should stay compact but preserve selected layers, nearby screens, and design-system bindings. Canvas snapshots now mark `selected`, `inView`, and `nearSelection` shapes and, when capped, prioritize those local-context layers before older/offscreen board content. Line/freehand vertices are sampled per shape with `pointsOmitted` reported so long annotations do not dominate the prompt. 3. **Parallel directions**: build on `variant-matrix`, `add-screens`, and multi-page mode to support named exploration branches ("directions") that can be generated, compared, accepted, or archived on the board. Multi-page runs now stamp their generated screens with a shared direction id/name and the design sidebar exposes those direction groups with persisted accept/archive controls. Archived directions move out of the main direction list into a restore-able archived section. The sidebar now exposes a comparison summary for active directions: screen coverage, prototype links, implemented count, shared screens, and per-direction unique screens. It can open a visual side-by-side compare overlay with one live HTML preview column per direction and synchronized switching for shared or partially covered screen names. Remaining work: pixel/style diff overlays plus richer archive filtering. 4. **Google-compatible DESIGN.md**: root `DESIGN.md` is the canonical public project theme. The Design canvas discovers and validates it, projects it as a deterministic specimen board, and maps compatible tokens into native canvas state. Kun-generated project handoff lives at `.kun-design/HANDOFF.md`; legacy `.kun-design/DESIGN.md` and `.kun-design/design-system.json` remain compatibility/migration inputs and never compete as theme sources. Per-artifact `DESIGN.md` files remain local implementation notes rather than project themes. 5. **Prototype playback**: HTML screen frames now persist planned `prototypeLinks[]` from the multi-page planner's `linksTo` metadata, render those links as a non-editing flow overlay on the board, and expose a Play overlay for stepping through generated screens from the selected frame. Generated HTML links whose `href` matches the planned flow are captured in Play mode and route to the target screen. Unknown local/relative prototype links are now captured as missing targets instead of letting the webview drift away; the player can seed the design rail with a request to create and wire the missing next screen. Remaining work: deeper stateful interaction capture for non-navigation controls. 6. **Voice and critique loop**: route voice input into the design rail and let the agent run a critique/repair pass against the selected screen, frame, or whole board. The canvas toolbar now exposes a local critique entry point: it runs the design-system lint pass against the current editable selection subtree (or the whole board when nothing is selected), stashes findings into the next canvas prompt, opens the design rail, and seeds a focused repair request. Voice input remains the next layer on top of that repair loop. 7. **MCP/developer-tool bridge**: ship the deferred design-artifacts MCP server once packaged-startup verification is available, then expose read-only artifact/design-system resources to coding tools. --- ## 13. Extension seams The discriminated unions are designed so later phases **add a case**, never rewrite: `DesignArtifactKind` (`'html' | 'graph'` — penpot is a future member), `DesignCanvasView` (`'preview' | 'code' | 'live'`), `DesignGraphNodeKind` (`'prompt' | 'design' | 'image'`). The canvas renderer and the turn builder branch on these. --- ## 14. Deferred: MCP exposure (the plan) Exposing design artifacts to agents over MCP is fully mapped but intentionally not shipped — it touches `main/index.ts`'s startup child-process gating in ~6 sites (the most startup-critical file) and cannot be verified without a packaged run. The plan: 1. Add read-only `/design/internal/list` + `/design/internal/read` to `ScheduleRuntime.handleInternalRequest` (`schedule-runtime.ts`); resolve the workspace server-side via `settings.write.activeWorkspaceRoot`; reuse the existing bearer-token auth. 2. Add `src/main/design-artifacts-mcp-server.ts` (mirror `claw-schedule-mcp-server.ts`) — a stdio MCP server proxying to those endpoints, registering `design_list_artifacts` / `design_read_artifact`. 3. Add `design-artifacts-mcp-node-entry.ts`; handle the launch flag in `main/index.ts` (generalize `runningClawScheduleMcpServer`'s 6 gate sites). 4. Inject the server into the Kun config in `kun-process.ts` (mirror `buildGuiScheduleKunMcpServer`), and package the entry via `package.json`. --- ## 15. Runtime-only behaviors to verify Typecheck/lint/unit tests cover the code shape, not these (need a real `npm run dev`): - Artifact rehydration (list survives reload), PDF export (hidden-window `printToPDF`). - Node-canvas execution (sequential agent turns, live status), image nodes (the agent must land the generated image at the node path — `generate_image` writes to `.deepseekgui-images/` by default, so the node prompt asks it to copy to the reserved path; if it doesn't, the node shows an error rather than breaking). - The built-in design skill activating (appears after a runtime restart). - The code-drift ⚠ badge appearing after the shared design system changes. --- ### DEVELOPMENT.En # Development Workflow [Simplified Chinese](./DEVELOPMENT.zh-CN.md) This document defines how developers should work in this repository, especially around the default branch, pull requests, and contribution quality standards. ## Development Baseline - `develop` is the active collaboration and daily integration branch - `master` is the stable release branch, updated by maintainers from `develop` - Routine feature and fix work should start from the latest `develop` - Short-lived feature branches are encouraged for non-trivial changes ## Recommended Workflow 1. Update your local repository. 2. Switch to `develop`. 3. Pull the latest changes from `develop`. 4. Create an optional feature branch from `develop` for your work. 5. Implement and validate your changes locally. 6. Open a PR back into `develop`. 7. Merge after review and passing checks. ## Example Commands ### Sync `develop` ```bash git checkout develop git pull origin develop ``` ### Create a feature branch from `develop` ```bash git checkout develop git pull origin develop git checkout -b feat/short-description ``` ### Push your branch ```bash git push origin feat/short-description ``` ## Pull Request Flow Default target branch: - `develop` Typical PR path: 1. Develop on a short-lived feature branch created from `develop` 2. Push the branch to the remote 3. Open a PR into `develop` 4. Address review feedback 5. Merge after approval and passing checks ## Required Validation Before PR At minimum, run: ```bash npm run typecheck npm run build npm run test ``` If your change affects runtime behavior or UI, also run: ```bash npm run dev ``` Manually verify the affected workflow before opening the PR. ## PR Quality Standard Code is easy. Good taste is rare. Review should protect the product experience, not only the implementation. A PR should be: - focused on one main purpose - easy to review - supported by validation results - documented when behavior changes Your PR description should include: - what changed - why it changed - how you verified it - a video or GIF if UI behavior changed - unit tests added or updated if project logic changed ## Change Scope Standard Prefer: - one topic per PR - minimal unrelated formatting churn - no opportunistic refactors unless they are necessary for the change Avoid: - mixing docs, refactors, and feature work without explanation - large undocumented behavior changes - bypassing normal review for risky changes ## Localization Standard If you change user-facing text: - update English and Chinese strings together when possible - keep wording consistent across docs and UI ## Documentation Standard Update documentation when changes affect: - setup - commands - runtime requirements - branch strategy - release behavior - contributor workflow ## Merge Guidance Merge contribution changes into `develop` only after: - review feedback is addressed - checks pass - the change is considered stable enough for the daily integration branch `master` is reserved for stable releases. After maintainers decide the current `develop` state is ready to publish, they merge `develop` into `master`. ## Suggested Branch Naming Examples: - `feat/runtime-settings` - `fix/connection-probe` - `docs/bilingual-readme` - `refactor/chat-store` ## Maintainer Notes If maintainers later adjust protected branches, required reviewers, or stricter automated gates, this document should be updated to match the repository rules. --- ### DEVELOPMENT # Development Workflow [简体中文](./DEVELOPMENT.zh-CN.md) This document defines how developers should work in this repository, especially around the default branch, pull requests, and contribution quality standards. ## Development Baseline - `develop` is the active collaboration and daily integration branch - `master` is the stable release branch, updated by maintainers from `develop` - Routine feature and fix work should start from the latest `develop` - Short-lived feature branches are encouraged for non-trivial changes ## Recommended Workflow 1. Update your local repository. 2. Switch to `develop`. 3. Pull the latest changes from `develop`. 4. Create an optional feature branch from `develop` for your work. 5. Implement and validate your changes locally. 6. Open a PR back into `develop`. 7. Merge after review and passing checks. ## Example Commands ### Sync `develop` ```bash git checkout develop git pull origin develop ``` ### Create a feature branch from `develop` ```bash git checkout develop git pull origin develop git checkout -b feat/short-description ``` ### Push your branch ```bash git push origin feat/short-description ``` ## Pull Request Flow Default target branch: - `develop` Typical PR path: 1. Develop on a short-lived feature branch created from `develop` 2. Push the branch to the remote 3. Open a PR into `develop` 4. Address review feedback 5. Merge after approval and passing checks ## Required Validation Before PR At minimum, run: ```bash npm run typecheck npm run build npm run test ``` If your change affects runtime behavior or UI, also run: ```bash npm run dev ``` Manually verify the affected workflow before opening the PR. ## PR Quality Standard Code is easy. Good taste is rare. Review should protect the product experience, not only the implementation. A PR should be: - focused on one main purpose - easy to review - supported by validation results - documented when behavior changes Your PR description should include: - what changed - why it changed - how you verified it - a video or GIF if UI behavior changed - unit tests added or updated if project logic changed ## Change Scope Standard Prefer: - one topic per PR - minimal unrelated formatting churn - no opportunistic refactors unless they are necessary for the change Avoid: - mixing docs, refactors, and feature work without explanation - large undocumented behavior changes - bypassing normal review for risky changes ## Localization Standard If you change user-facing text: - update English and Chinese strings together when possible - keep wording consistent across docs and UI ## Documentation Standard Update documentation when changes affect: - setup - commands - runtime requirements - branch strategy - release behavior - contributor workflow ## Merge Guidance Merge contribution changes into `develop` only after: - review feedback is addressed - checks pass - the change is considered stable enough for the daily integration branch `master` is reserved for stable releases. After maintainers decide the current `develop` state is ready to publish, they merge `develop` into `master`. ## Release Automation Stable releases are published by GitHub Actions when a same-repository PR from `develop` into `master` is merged. The release workflow: - computes the next `vX.Y.Z` patch tag from the latest three-part semver tag - reuses a tag that already points at the merge commit when a workflow is rerun - builds signed and notarized macOS arm64/x64 packages, a Windows x64 installer, and Linux x64 AppImage plus deb packages - uploads release assets and update metadata to GitHub Releases and the R2 `stable` channel - promotes R2 `stable/latest` only after all platform uploads succeed Repository maintainers must configure these GitHub Actions secrets before the first automated release: - R2: `R2_BUCKET`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_PUBLIC_BASE_URL`, and either `R2_ACCOUNT_ID` or `R2_ENDPOINT` - Optional R2 override: `R2_RELEASE_PREFIX` - macOS signing: `MAC_CODESIGN_P12_BASE64`, `CSC_KEY_PASSWORD`, `APPLE_API_KEY_BASE64`, `APPLE_API_KEY_ID`, `APPLE_API_ISSUER` The repository Actions settings must allow `GITHUB_TOKEN` to write repository contents so the workflow can create tags and publish releases. The local `npm run release:mac` and `npm run release:win` commands remain available as manual fallback tools. ## Suggested Branch Naming Examples: - `feat/runtime-settings` - `fix/connection-probe` - `docs/bilingual-readme` - `refactor/chat-store` ## Maintainer Notes If maintainers later adjust protected branches, required reviewers, or stricter automated gates, this document should be updated to match the repository rules. --- ### DEVELOPMENT.Zh CN # 开发流程 [English](./DEVELOPMENT.md) 这份文档定义了本仓库的开发协作方式,重点说明默认分支、PR 流程,以及贡献质量标准。 ## 开发基线 - `develop` 是开发协作与日常集成分支 - `master` 是稳定发布分支,由维护者从 `develop` 合入 - 日常功能开发和缺陷修复都应从最新 `develop` 开始 - 对于稍大一些的改动,建议使用短期功能分支 ## 推荐流程 1. 先同步本地仓库。 2. 切换到 `develop`。 3. 拉取 `develop` 最新代码。 4. 如有需要,从 `develop` 拉出功能分支开展开发。 5. 在本地完成实现并做好校验。 6. 提交 PR 回到 `develop`。 7. 在通过评审和检查后合并。 ## 示例命令 ### 同步 `develop` ```bash git checkout develop git pull origin develop ``` ### 从 `develop` 拉功能分支 ```bash git checkout develop git pull origin develop git checkout -b feat/short-description ``` ### 推送分支 ```bash git push origin feat/short-description ``` ## Pull Request 流程 默认目标分支: - `develop` 典型流程如下: 1. 在从 `develop` 拉出的短期功能分支上开发 2. 将分支推送到远端 3. 发起指向 `develop` 的 PR 4. 根据 Review 意见继续修改 5. 在通过校验并获得认可后合并 ## PR 前必须做的校验 至少执行: ```bash npm run typecheck npm run build npm run test ``` 如果改动影响运行时行为或 UI,额外建议执行: ```bash npm run dev ``` 并手动验证受影响流程后再发起 PR。 ## PR 质量标准 代码不难,难得的是好品味。评审要守住产品体验,而不只是实现是否能跑。 一个合格的 PR 应当: - 目标明确,只围绕一个主要主题 - 易于审阅 - 有明确的校验结果支撑 - 行为变更时同步更新文档 PR 描述建议至少包含: - 改了什么 - 为什么要改 - 如何验证 - 如果涉及 UI,附上视频或 GIF - 如果涉及项目逻辑,列出新增或更新的单元测试 ## 改动范围标准 推荐: - 一个 PR 聚焦一个主题 - 尽量减少无关格式化改动 - 非必要不要顺手做大范围重构 避免: - 没有解释就把文档、重构、功能改动混在一起 - 大范围行为变化却没有文档说明 - 对高风险改动绕过正常评审流程 ## 本地化标准 如果修改了用户可见文案: - 尽量同步更新中英文内容 - 保持文档和 UI 用词一致 ## 文档标准 当改动影响以下内容时,应同步更新文档: - 安装或初始化方式 - 命令使用方式 - 运行时要求 - 分支策略 - 发布流程 - 贡献者协作方式 ## 合并建议 贡献改动只有在满足以下条件后,才应该合入 `develop`: - Review 意见已处理 - 检查项通过 - 改动已经达到适合进入日常集成分支的稳定程度 `master` 仅用于稳定发布。维护者确认 `develop` 中的改动适合发布后,再将 `develop` 合入 `master`。 ## 自动发布 当同仓库内从 `develop` 指向 `master` 的 PR 被合并后,GitHub Actions 会自动发布稳定版本。 每次合并发布 PR 前,发布负责人必须完成[稳定版发版交验清单与故障排查](./release-validation-checklist.md),重点核验 Graph 时序、Linux AppImage、Windows NSIS/跨范围迁移、打包后的 Electron/Extension smoke、跨平台 evidence 和 R2 `stable/latest`。 发布 workflow 会: - 基于最新三段式 semver tag 自动生成下一个 `vX.Y.Z` patch tag - 如果 rerun 时当前 merge commit 已经有 tag,则复用该 tag - 构建已签名并公证的 macOS arm64/x64 包、Windows x64 安装器、Linux x64 AppImage 与 deb - 将发布产物和更新元数据上传到 GitHub Releases 与 R2 `stable` 渠道 - 只有在全部平台上传成功后,才会 promote R2 `stable/latest` 首次自动发布前,维护者需要配置这些 GitHub Actions secrets: - R2:`R2_BUCKET`、`R2_ACCESS_KEY_ID`、`R2_SECRET_ACCESS_KEY`、`R2_PUBLIC_BASE_URL`,以及 `R2_ACCOUNT_ID` 或 `R2_ENDPOINT` - 可选 R2 覆盖项:`R2_RELEASE_PREFIX` - macOS 签名:`MAC_CODESIGN_P12_BASE64`、`CSC_KEY_PASSWORD`、`APPLE_API_KEY_BASE64`、`APPLE_API_KEY_ID`、`APPLE_API_ISSUER` 仓库的 Actions 设置还需要允许 `GITHUB_TOKEN` 写入 repository contents,这样 workflow 才能创建 tag 并发布 Release。 本地 `npm run release:mac` 和 `npm run release:win` 命令保留为手动兜底工具。 ## 分支命名建议 示例: - `feat/runtime-settings` - `fix/connection-probe` - `docs/bilingual-readme` - `refactor/chat-store` ## 维护者说明 如果后续仓库调整受保护分支、强制 Reviewer、自动化测试门禁等规则,应同步更新本文件,保持与真实仓库规则一致。 --- ### KUN CONFIG # Kun Agent 与模型配置说明 本文说明 Kun(桌面应用与运行时)的本地配置文件在哪里、哪些字段由 UI 管理、哪些字段适合手工扩展,以及模型上下文压缩阈值应该如何配置。 ## 配置文件分层 Kun 有两层配置。 1. GUI settings 这是桌面应用自己的设置文件,保存设置页里的 Agent 运行时选项。 - macOS: `~/Library/Application Support/Kun/kun-settings.json` - Windows: `%APPDATA%/Kun/kun-settings.json` - Linux: `~/.config/Kun/kun-settings.json` Agent 运行时设置在 `agents.kun` 下,例如端口、data dir、默认模型、审批策略、sandbox、token economy 等。多数用户通过设置页修改这些字段。 2. Kun runtime config 这是 Kun 本地运行时读取的高级配置文件。默认路径是: ```text ~/.kun/data/config.json ``` 如果 `agents.kun.dataDir` 改成了别的目录,实际路径就是: ```text /config.json ``` `kun serve --config ` 可以显式指定配置文件;如果没有指定,Kun 会尝试读取 `{dataDir}/config.json`。 ## 启动时的读取顺序 GUI 启动 Kun 时会按下面的顺序合并配置。 1. GUI 读取 `kun-settings.json`(旧版 `deepseek-gui-settings.json` 会自动迁移),得到 `agents.kun` 和通用 provider 配置。 2. GUI 在启动 Kun 前同步 `/config.json`,写入 UI 管理的 token economy、默认压缩摘要参数、默认模型 profiles、runtime tuning、MCP search 和附件能力。 3. Kun serve 读取 `/config.json` 或 `--config` 指定的文件。 4. CLI 参数和环境变量会覆盖 `serve` 里的基础启动字段,例如 `--model`、`--port`、`KUN_MODEL`、`KUN_PORT`。 5. AgentLoop、review loop 和子 Agent 都从同一份模型配置加载模型能力与上下文压缩阈值。 ## 从旧目录升级 旧版本可能把 GUI 管理的 Runtime 数据放在 `~/.deepseekgui/kun`。新版 GUI 取得单实例锁后、加载设置和启动 Runtime 前,会执行可恢复迁移: - 如果设置仍选择旧目录,整份旧 Runtime 存储会以同卷原子改名迁到 `~/.kun/data`,包括线程、事件、附件、凭据、索引和 `config.json`。 - 如果新目录已经有数据,它会先被改名为相邻的 `data.pre-deepseekgui-migration-.bak`。其中不冲突的线程和身份 数据会补入迁移后的存储;发生冲突的版本继续完整保留在备份中。 - 旧路径随后成为指向新目录的符号链接(macOS/Linux)或目录联接 (Windows),仅用于旧版本兼容。当前 GUI 只使用新路径。 - 设置文件会先生成 `kun-settings.json.pre-runtime-data-migration-.bak`,再把 `agents.kun.dataDir` 改为 `~/.kun/data`。 - 迁移器与 GUI 使用完全相同的 settings 查找顺序;如果当前设置仍位于 旧 Electron userData 目录,或 settings 文件是符号链接,会备份并改写 实际生效的那一份,不会让旁边的过期设置抢占配置权威。 - 迁移前会检查是否仍有 Kun Runtime 进程使用旧目录。发现活跃写入者时 会在任何目录改名前停止迁移;如果写入者恰好在切换窗口重新创建旧 目录,该目录会完整保留为冲突备份,并回滚两个标准目录的名称。 迁移日志 `kun-runtime-data-migration-v2.json` 和报告 `kun-runtime-data-migration-v2-report.json` 位于上方列出的 GUI settings 目录。迁移可在下次启动续跑;如果遇到文件占用、权限、跨卷或链接创建 失败,GUI 会保留所有原目录和备份,并阻止 Runtime、配置同步、凭据迁移 及清理任务继续写旧目录。 迁移完成后,`~/.kun/data/config.json` 是唯一自动生效的 Runtime 配置。 当前 GUI 不会再发现、复制或回退读取独立的 `~/.deepseekgui/kun/config.json`。兼容链接下看到的同名文件只是新配置的 同一个文件。若真实旧目录在后续升级中再次出现,它会被隔离为 `kun.post-migration-.bak`,其中的配置不会覆盖新配置。用户 显式选择的自定义 `dataDir` 不参与这次标准目录迁移。 这也适用于迁移完成后的后续版本:用户后来改成自定义目录时,完成态 迁移日志不会再把它强制改回 `~/.kun/data`。若旧设置仍在但新旧目录都 不存在,则执行空存储切换并在新目录开始,不会永久阻止 Runtime 启动。 ## 推荐的 config.json 结构 ```json { "serve": { "host": "127.0.0.1", "port": 18899, "dataDir": "~/.kun/data", "runtimeToken": "", "apiKey": "", "baseUrl": "https://api.deepseek.com/beta", "model": "deepseek-v4-pro", "approvalPolicy": "auto", "sandboxMode": "workspace-write" }, "models": { "profiles": { "deepseek-v4-pro": { "contextWindowTokens": 1000000, "contextCompaction": { "softThreshold": 980000, "hardThreshold": 990000 }, "inputModalities": ["text"], "outputModalities": ["text"], "supportsToolCalling": true, "messageParts": ["text"] } } }, "contextCompaction": { "defaultSoftThreshold": 96000, "defaultHardThreshold": 108800, "summaryMode": "model", "summaryTimeoutMs": 15000, "summaryMaxTokens": 2048, "summaryInputMaxBytes": 98304 }, "runtime": { "streamIdleTimeoutMs": 450000, "toolStorm": { "enabled": true }, "toolArgumentRepair": { "maxStringBytes": 524288 } } } ``` GUI 管理的运行时会在 `runtimeToken` 为空时自动生成并保存本地访问令牌。 ## 模型配置写在哪里 模型相关配置写在顶层 `models.profiles`。 每个 key 是模型 ID。模型 ID 会按小写匹配,也支持 provider 前缀,例如请求模型是 `vendor/deepseek-v4-pro` 时,也可以匹配 `deepseek-v4-pro`。 ```json { "models": { "profiles": { "my-128k-model": { "aliases": ["vendor/my-128k-model"], "contextWindowTokens": 128000, "contextCompaction": { "softRatio": 0.85, "hardRatio": 0.93 }, "inputModalities": ["text"], "outputModalities": ["text"], "supportsToolCalling": true, "messageParts": ["text"] } } } } ``` 可用字段: - `aliases`: 这个 profile 还要匹配的模型别名。 - `contextWindowTokens`: 模型上下文窗口大小。 - `contextCompaction.softThreshold`: 达到多少 input tokens 后开始压缩。 - `contextCompaction.hardThreshold`: 达到多少 input tokens 后强制更激进压缩。 - `contextCompaction.softRatio`: 按 `contextWindowTokens` 比例计算 soft threshold。 - `contextCompaction.hardRatio`: 按 `contextWindowTokens` 比例计算 hard threshold。 - `inputModalities`: 输入模态,目前常用 `["text"]` 或 `["text", "image"]`。 - `outputModalities`: 输出模态,通常是 `["text"]`。 - `supportsToolCalling`: 模型是否支持 tool calling。 - `messageParts`: 模型消息 part 能力,例如 `["text"]` 或 `["text", "image_url"]`。 如果同时写了 `softThreshold` 和 `softRatio`,显式 token 阈值优先。`hardThreshold` 必须大于或等于 `softThreshold`。 ## 默认模型 profile Kun 内置 DeepSeek V4 默认模型画像: ```json { "models": { "profiles": { "deepseek-v4-pro": { "contextWindowTokens": 1000000, "contextCompaction": { "softThreshold": 980000, "hardThreshold": 990000 }, "inputModalities": ["text"], "outputModalities": ["text"], "supportsToolCalling": true, "messageParts": ["text"] }, "deepseek-v4-flash": { "aliases": ["deepseek-chat", "deepseek-reasoner"], "contextWindowTokens": 1000000, "contextCompaction": { "softThreshold": 980000, "hardThreshold": 990000 }, "inputModalities": ["text"], "outputModalities": ["text"], "supportsToolCalling": true, "messageParts": ["text"] } } } } ``` 也就是说,V4 是 1M 上下文,正常情况下接近 `980k` input tokens 才触发上下文压缩;接近 `990k` 时进入更强的压缩策略。 ## 全局压缩配置写在哪里 全局压缩配置写在顶层 `contextCompaction`。它只负责“不知道具体模型 profile 时的兜底阈值”和“摘要行为”,不要再把模型窗口大小写在这里。 ```json { "contextCompaction": { "defaultSoftThreshold": 96000, "defaultHardThreshold": 108800, "summaryMode": "model", "summaryTimeoutMs": 15000, "summaryMaxTokens": 2048, "summaryInputMaxBytes": 98304 } } ``` 字段说明: - `defaultSoftThreshold`: 未匹配到模型 profile 时,达到多少 input tokens 开始压缩。 - `defaultHardThreshold`: 未匹配到模型 profile 时,达到多少 input tokens 强制压缩。 - `summaryMode`: GUI 管理的配置默认并归一为 `model`。手工维护 `config.json` 时仍可显式写 `heuristic` 使用本地摘要骨架;`model` 模式下模型摘要失败、 超时或返回空文本时会自动降级为本地摘要骨架。 - `summaryTimeoutMs`: 模型摘要调用超时时间。 - `summaryMaxTokens`: 模型摘要输出 token 上限。 - `summaryInputMaxBytes`: 摘要输入文本最大字节数。 ## Agent 配置写在哪里 普通 Agent 运行时配置由 GUI settings 的 `agents.kun` 管理。主要字段: ```json { "agents": { "kun": { "binaryPath": "", "port": 18899, "autoStart": true, "dataDir": "~/.kun/data", "model": "deepseek-v4-pro", "approvalPolicy": "auto", "sandboxMode": "workspace-write", "tokenEconomyMode": false, "insecure": false } } } ``` 设置页会保存这些字段。GUI 模式下默认模型以 `agents.kun.model` 为准;`config.json` 里的 `serve.model` 更适合 standalone `kun serve` 使用,因为 GUI 启动时会把设置页里的模型作为启动参数传给 Kun。 ## Hooks 配置写在哪里 Hooks 写在 `config.json` 顶层的 `hooks` 数组里,GUI 启动 Kun 时通过 `--data-dir` 自动加载,无需额外开关: ```json { "hooks": [ { "phase": "PreToolUse", "matcher": "bash|write_file|mcp__*", "command": "node ~/.kun-hooks/guard.js", "timeoutMs": 10000 }, { "phase": "UserPromptSubmit", "command": "~/.kun-hooks/prompt-context.sh" } ] } ``` 支持的 `phase`:`PreToolUse`、`PostToolUse`(工具调用前后,可改写参数 / 输出、拒绝或自动放行)、`UserPromptSubmit`(回合开始前,可拒绝或注入 上下文)、`TurnStart`、`TurnEnd`、`PreCompact`(只读通知)。命令通过 stdin 收到 JSON invocation,退出码 `0` + stdout JSON 返回结构化结果, 退出码 `2` 阻断动作,其余非零只产生 `hook_warning` 事件。完整参考 (各阶段载荷、失败语义、示例脚本)见 [kun-hooks.md](kun-hooks.md)。 ## 用户如何自定义 常见做法: 1. 在设置页修改端口、data dir、默认模型、审批策略、sandbox 和 token economy。 2. 打开 `/config.json`,在 `models.profiles` 里增加或覆盖模型 profile。 3. 如果要把自定义模型作为 GUI 默认模型,把 `agents.kun.model` 改成该模型 ID。 4. 重启 Kun runtime,让新配置生效。 自定义 1M 模型并在 950k 左右开始压缩: ```json { "models": { "profiles": { "vendor/my-1m-model": { "aliases": ["my-1m-model"], "contextWindowTokens": 1000000, "contextCompaction": { "softThreshold": 950000, "hardThreshold": 980000 }, "inputModalities": ["text"], "outputModalities": ["text"], "supportsToolCalling": true, "messageParts": ["text"] } } } } ``` 自定义图片输入模型: ```json { "models": { "profiles": { "vision-model": { "contextWindowTokens": 128000, "contextCompaction": { "softRatio": 0.75, "hardRatio": 0.9 }, "inputModalities": ["text", "image"], "outputModalities": ["text"], "supportsToolCalling": true, "messageParts": ["text", "image_url"] } } } } ``` ## 兼容旧配置 旧版本曾支持把模型 profile 写在: ```json { "contextCompaction": { "modelProfiles": {} } } ``` 这个位置仍然会被读取,以免已有用户配置失效。但新配置请使用: ```json { "models": { "profiles": {} } } ``` 当两个位置都写了同一个模型时,`models.profiles` 的配置优先。 ## 相关源码 - 默认 GUI Agent 设置:`src/shared/app-settings-kun.ts` - GUI 同步 `/config.json`:`src/main/kun-process.ts` - Kun config schema:`kun/src/config/kun-config.ts` - 模型 profile 解析:`kun/src/loop/model-context-profile.ts` - 上下文压缩器:`kun/src/loop/context-compactor.ts` - serve 解析入口:`kun/src/cli/serve.ts` - 示例配置:`kun/config.example.json` --- ### UI PLUGINS # UI 插件开发指南(形象工坊) Kun 的「形象工坊」允许任何人制作并安装自己的视觉形象包:既可以替换工作台里的 泳动小鸟、欢迎/睡觉/坐着等状态形象,也可以给应用主体、侧边栏、主舞台和写作/设计工作面换上主题背景, 再配合主题 token 与进行中文案完成一套皮肤。v1.5 起可以把一张完整人物立绘放进 Kun 会话舞台;v1.6 的 `scene` 进一步提供左右导轨、卡片、背景式构图、五类专属美术槽位、 人物焦点/蒙版以及宿主内置动效,让每个人物主题拥有不同的 UI 语言而不开放任意 CSS。 **iKun 模式就是一个随应用分发的示例**:它会在首次启动时自动安装 (id 为 `ikun`,见 `src/main/ui-plugin-bundled.ts`),在形象工坊里与第三方插件同级。 它额外带有应用针对 `ikun` id 制作的专属动画;第三方插件使用通用的形象与背景框架。 **一个 UI 插件就是一个文件夹**:`manifest.json` + 被 manifest 引用的图片。 插件是纯声明式的,没有任何可执行代码;应用不会执行插件中的 JS、HTML、CSS 或 SVG。 启用主题时,Kun 主进程会重新读取并校验已安装的 manifest 和图片,根据固定槽位生成宿主 CSS, 再通过 Electron 内部的 CDP 接口注入工作台。这个实现不开放远程调试端口,也没有插件脚本入口。 ```text my-plugin/ ├── manifest.json ├── img/ │ ├── swim.png │ ├── portrait.png │ └── stage.webp ├── scene/ │ ├── backdrop.webp │ ├── frame.png │ └── emblem.png └── artwork/ └── stage-source.svg # 可选的创作源文件,不会安装或执行 ``` 安装方式:`设置 → 形象工坊 → 安装插件文件夹…`,选中插件目录即可。 应用校验 manifest 和图片后,只把 **manifest 与被 `figures` / `backgrounds` / `scene` 引用的图片** 复制进应用数据目录(`~/.kun/ui-plugins//`);未引用的创作源文件不会复制。 官方示例见 [`examples/ui-plugins/starlight/`](../examples/ui-plugins/starlight/)。它同时演示了 旧版兼容的形象槽位、背景路径简写和完整背景图层对象。 ## manifest.json 参考 ``` /* Detailed source-code truncated for AI context efficiency. */ ``` ### 顶层字段 | 字段 | 必填 | 规则 | |---|---|---| | `id` | ✓ | 2–40 位小写字母/数字/连字符;保留字 `default` / `kun` / `on` / `off` / `none` 不可用(`ikun` 被预装示例占用,重装会覆盖它) | | `name` | ✓ | ≤60 字符 | | `version` | ✓ | 语义化版本,如 `1.0.0` | | `author` / `description` | | ≤80 / ≤240 字符 | | `figures` | 至少一类 | 形象槽位对象;活动小形象支持 `png/webp/jpg/jpeg/gif`;`portrait` 仅支持静态 `png/webp/jpg/jpeg` | | `backgrounds` | 至少一类 | `light` / `dark` 主题下可放 `app` / `sidebar` / `stage` / `write` / `design`;图片仅支持静态 `png/webp/jpg/jpeg`(不支持 APNG、animated WebP) | | `presentation` | | 人物舞台的严格声明式配置;一旦提供就必须同时提供 `figures.portrait` | | `scene` | | v1.6 专属场景;必须同时提供完整 `presentation` 回退、`figures.portrait` 与至少一个 `artwork` 槽位 | | `labels` | | 仅 `zh` / `en`;键限 `working` / `workingSprint` / `workingDive` / `workingSurf`;每条 ≤24 字符 | | `tokens` | | 仅 `light` / `dark`;键限 `--ds-*`;值禁止 `url()`、分号、花括号等;总数 ≤60 | | `features.cameos` | | `true` 时启用主会话两侧的不定时出没彩蛋 | `figures` 和 `backgrounds` 可以分别省略,但二者合计至少要包含一个有效图片槽位;空对象等同于未提供。 所有图片路径都必须是插件目录内的相对路径,禁止绝对路径、`..` 与反斜杠。 ## 背景图层(backgrounds) `backgrounds` 按主题和区域组织。五个内部区域彼此独立;`write` / `design` 是稳定兼容键,可省略,此时继续使用 `stage`: | 槽位 | 作用区域 | 默认透明度 | |---|---|---| | `app` | 整个工作台内容区的底层背景 | `0.22` | | `sidebar` | 左侧栏背景 | `0.18` | | `stage` | 主内容/会话舞台背景 | `0.32` | | `write` | Work 办公工作面(稳定内部键) | `0.50` | | `design` | Code 内 Design 白板(稳定内部键) | `0.50` | 顶栏(`topbar`)不属于上述五个背景槽位,仍由主题 token `--ds-topbar-bg` 控制。 一个图层可以直接写成图片路径,也可以写成对象: ```json { "backgrounds": { "light": { "app": "img/paper-texture.jpg", "sidebar": { "path": "img/sidebar.webp", "fit": "contain", "position": "bottom-right", "opacity": 0.14 } } } } ``` - 字符串是 `{ "path": "…" }` 的简写。 - `fit` 可为 `cover` 或 `contain`,默认 `cover`。 - `position` 默认 `center`,可为 `top-left` / `top` / `top-right` / `left` / `center` / `right` / `bottom-left` / `bottom` / `bottom-right`。 - `opacity` 范围为 `0`–`1`;省略时使用上表对应区域的默认值。 - `light` 与 `dark` **不会互相回退**。例如只声明 `light.stage` 时,深色主题不会偷偷沿用它; 如需两种主题显示同一张图,请在两边都显式声明。 背景图片本身不携带布局或样式权限。应用只读取图像像素,再在固定的安全图层中应用上述 `fit`、`position`、`opacity` 参数;插件不能提供选择器、CSS 值或脚本。 ## 人物舞台(presentation,v1.5) `figures.portrait` 是会话舞台使用的主人物图片。建议使用透明背景的原始人物立绘,不要把 Kun 的侧栏、顶栏、输入框或其它应用界面烘焙进图片。Kun 会保留人物原画,只在图片外侧 绘制宿主框景和氛围层,不会重新设计人物。portrait 必须是静态 PNG/JPEG/WebP;GIF、APNG 和 animated WebP 会在安装及每次加载时被拒绝,避免绕过“减少动态效果”或持续占用解码资源。 这个限制不影响 `swim`、`greet` 等既有活动小形象继续使用 GIF。 `presentation` 必须完整包含下面三个对象。所有键和取值都是严格白名单;未知键、缺失键、 任意 CSS、选择器、URL 或布局字符串都会让安装失败。 ### `character` | 字段 | 可选值/范围 | 作用 | |---|---|---| | `anchor` | `top-right` / `right` / `bottom-right` | 人物在会话舞台右侧的锚点 | | `size` | `medium` / `large` / `hero` | 宿主预设的立绘尺寸 | | `offsetX` / `offsetY` | `-12`–`12` 的整数 | 在锚点基础上的百分比微调 | | `opacity` | `0`–`1` 的有限数字 | 整个人物层透明度 | | `frame` | `soft-card` / `paper` / `crystal` / `hologram` / `backstage` / `portal` / `polaroid` / `ticket` / `seal` | 九种宿主绘制的框景语言 | | `motion` | `none` / `breathe` / `float` | 固定的轻动效;系统开启“减少动态效果”时自动关闭 | | `contentReserve` | `none` / `narrow` / `wide` | 给消息和输入框预留人物空间,避免遮挡 | ### `readability` | 字段 | 可选值 | 作用 | |---|---|---| | `scrim` | `none` / `opposite-character` / `full` | 不加遮罩、只保护人物对侧文字区、或保护整个舞台 | | `strength` | `soft` / `medium` / `strong` | 固定遮罩强度 | ### `surfaces` `sidebar`、`topbar`、`composer`、`cards` 四个键都必须提供。每个键只能选择 `solid` / `translucent` / `glass` / `strong-glass`。这些名称映射到 Kun 内置材质, 插件不能覆盖模糊半径、阴影、边框或 CSS 属性。 人物层、装饰层和遮罩层均为 `pointer-events: none` 且 `aria-hidden`;不会拦截聊天、输入或 辅助技术。会话舞台窄于 980px 或开启专注模式时,人物与装饰自动隐藏并归还内容宽度。 ## 专属人物场景(scene,v1.6) `scene` 是 `presentation` 之上的渐进增强。它不允许插件传入 DOM、CSS 或动画代码,而是让 插件从 Kun 固定的场景积木中组合专属 UI。声明 `scene` 时仍必须保留完整 `presentation`, 供只认识 v1.5 的宿主安全回退。`scene.apiVersion` 当前只能是 `"1.6"`。 ### 场景布局和人物 - `layout`: `rail-right` / `rail-left` / `card-right` / `card-left` / `backdrop-right` / `backdrop-center`。导轨和卡片布局会由宿主给消息列与输入框预留左右空间; 背景布局始终放在内容层下方。 - `character.scale`: `compact` / `standard` / `hero`;`fit`: `contain` / `cover`; `focalPoint` 使用背景图层相同的九宫格位置。 - `character.mask`: `none` / `soft-card` / `circle` / `arch` / `diamond` / `hologram` / `portal` / `polaroid` / `ticket`。 - `offsetX` / `offsetY` 是 `-12`–`12` 的整数,`opacity` 为 `0`–`1`,`flipX` 为布尔值。 - 人物 `motion.preset` 为 `none` / `breathe` / `float` / `sway`;所有 motion 还必须指定 `speed`(`slow` / `normal` / `fast`)与 `phase`(`a` / `b` / `c`)。 ### 专属美术槽位 `artwork` 至少声明一个槽位:`backdrop` / `ambient` 位于整个舞台的安全底层; `frame` / `foreground` / `emblem` 位于裁切后的人物视觉区。每层必须完整提供: | 字段 | 可选值/范围 | |---|---| | `path` / `darkPath` | 插件内静态 PNG/JPEG/WebP 相对路径;`darkPath` 可选,深色模式覆盖默认图 | | `anchor` | 九宫格位置 | | `size` | `small` / `medium` / `large` / `full` | | `fit` | `contain` / `cover` | | `offsetX` / `offsetY` | `-12`–`12` 的整数 | | `opacity` | `0`–`1` | | `blend` | `normal`;仅 `backdrop` / `ambient` 可用 `screen` / `soft-light` | | `motion.preset` | `none` / `float` / `drift-x` / `drift-y` / `pulse` / `orbit` / `twinkle` / `scan` | 人物和美术动效都由宿主实现,系统开启“减少动态效果”时自动停止。不要把 Kun 的输入框、 消息、侧栏等界面烘焙进这些图;宿主会负责真实 UI 的避让和层级。 ### 宿主外观配方 `chrome` 必须包含 `sidebar`、`topbar`、`composer`、`cards` 四项。每项可选 `inherit` / `soft` / `editorial` / `paper` / `crystal` / `hologram` / `backstage` / `portal` / `polaroid` / `ticket` / `seal`,也可以使用 11 套人物专属配方: `botanical` / `fortune-ledger` / `dream-gate` / `washi` / `scrapbook` / `aurora` / `synth` / `midnight-pass` / `nautical` / `grand-line` / `dimension-lab` / `starlight`。 人物专属配方由 Kun 宿主实现,会以同一套视觉语言同时处理侧边栏、顶栏、输入框、用户/助手 消息、普通卡片与表格表面。例如 `botanical` 使用柔和植物感层次,`fortune-ledger` 使用账簿式 线条,`synth` 与 `dimension-lab` 使用不同的未来界面语言。插件只选择白名单名称;不能提供 选择器、属性值、DOM 或控件,所有装饰保持在真实交互层下方,不会拦截输入。 四项可以独立选择,但人物主题通常应让四项使用同一个专属配方,以保证会话卡片、输入区和 导航区与人物形象保持一致。这些名称是 Kun 固定的表面配方,不是 CSS 权限。 场景舞台、人物视觉区、装饰图和可读性遮罩均为不可交互安全层。窗口变窄、专注模式开启或 终端面板展开时,宿主会隐藏整套场景并取消消息列/输入框位移,避免任何图片或装饰遮挡输入。 ## 宿主受控的 CDP 主题注入 CDP 是 Kun 应用主题的**宿主实现细节**,不是 manifest 能申请的代码执行能力。激活一次插件时: 1. 渲染层只把插件 `id` 发给主进程。 2. 主进程从 `~/.kun/ui-plugins//` 重新读取并规范化 manifest,重新校验全部引用图片。 3. Kun 自己的样式生成器把白名单 token、固定背景槽位以及已归一化的人物/场景数值变量组合成 CSS。 4. 主进程短暂附加 `mainWindow.webContents.debugger`,调用固定的 `Runtime.evaluate` 程序, 只用 `style.textContent` 创建或更新一个宿主管理的 `