diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbcafb7..a3d8feb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,8 +3,8 @@ name: CI on: push: branches: [main] - pull_request: - branches: [main] + # Stacked PRs target feature branches; every PR still needs the same gates. + pull_request: {} concurrency: group: ci-${{ github.workflow }}-${{ github.ref }} @@ -77,13 +77,18 @@ jobs: timeout-minutes: 5 steps: - uses: actions/checkout@v6 - - name: Verify required docs exist + - name: Verify current documentation + run: node scripts/check-docs.mjs + + desktop-rust: + name: Desktop Rust check + test + runs-on: macos-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v6 + - name: Show Rust toolchain + run: rustc --version && cargo --version + - name: Check and test Tauri backend run: | - for f in README.md CONTRIBUTING.md SECURITY.md \ - docs/DEVELOPMENT_PLAN.md docs/VISUAL_DESIGN.html \ - docs/design/sandbox-plan-worktree.md \ - docs/design/plugin-security.md \ - docs/design/effort-levels.md; do - test -f "$f" || { echo "MISSING: $f"; exit 1; } - done - echo "All M0 docs present" + cargo check --manifest-path apps/desktop/src-tauri/Cargo.toml --locked + cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml --locked diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..95fe1d2 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,67 @@ +# DeepCode repository guidance + +## North star + +DeepCode is a DeepSeek-powered coding agent with CLI, Tauri desktop, VS Code, +and LSP surfaces. The active modernization plan is +[`docs/CODEX_ALIGNMENT_PLAN.md`](docs/CODEX_ALIGNMENT_PLAN.md). It supersedes +the original milestone plan for new architecture decisions. + +## Layout + +- `packages/core`: provider, agent loop, tools, config, sessions, sandbox, + hooks, MCP, skills, plugins, tasks, and worktrees. +- `packages/shared-ui`: cross-client types only. +- `apps/cli`: interactive and headless CLI. +- `apps/desktop`: React/Vite renderer plus the Rust/Tauri backend in + `src-tauri`. +- `apps/lsp` and `apps/vscode`: editor integrations. +- `scripts`: release and repository checks. +- `docs`: current plans plus historical design snapshots. + +Do not edit generated `dist/`, `target/`, release artifacts, or lockfiles unless +the task requires it. + +## Setup and verification + +Use Node 22 and pnpm 9. + +```bash +pnpm install --frozen-lockfile +pnpm typecheck +pnpm lint +pnpm format:check +pnpm test +pnpm build +pnpm docs:check +cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml +``` + +Run the smallest relevant package test while iterating, then the full relevant +gate before handing off. Changes to the Rust backend require `cargo fmt --check` +and `cargo test`. Changes to sandbox, permissions, credentials, plugins, hooks, +or process execution require focused adversarial tests. + +## Engineering constraints + +- Preserve existing user changes and backward-compatible CLI behavior unless a + migration is explicitly documented. +- All tool execution must pass through one explicit permission policy. Never + make safety depend on a host remembering to pass an optional argument. +- Do not expose DeepSeek credentials to a renderer or webview. Treat the VS Code + extension host and its webview as different trust boundaries. +- Cancellation is complete only when providers, child process groups, pending + approvals, and subsequent writes have stopped. +- Do not force-delete worktree branches or discard unmerged user work. +- Keep legacy session files read-only during migrations; prefer format + detection and dual-read/single-write adapters. +- Keep provider-specific behavior behind provider capabilities. Do not claim + exact Codex or Claude parity when DeepSeek constraints differ. +- New public behavior needs tests and user-facing documentation in the same PR. + +## Definition of done + +A change is done when its behavior is tested at the correct boundary, relevant +quality gates pass, security and migration consequences are documented, and the +diff contains no unrelated generated or user-owned changes. For architecture +work, update the alignment plan or an ADR with the decision and rollback path. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4d16a0e..8a4a8bf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,14 +1,14 @@ # Contributing to DeepCode -感谢你对 DeepCode 感兴趣。DeepCode 是 Claude Code 的 DeepSeek 版 —— 完整复刻 Claude Code 全部能力,底层 LLM 切换到 DeepSeek。 +感谢你对 DeepCode 感兴趣。DeepCode 是一个由 DeepSeek 驱动的本地 coding agent,正在收敛 CLI、桌面端和编辑器端的运行时语义。 > 在写代码前请先读: > -> 1. [`docs/DEVELOPMENT_PLAN.md`](docs/DEVELOPMENT_PLAN.md) — 整体开发方案 v0.5 -> 2. [`docs/VISUAL_DESIGN.html`](docs/VISUAL_DESIGN.html) — 视觉设计 v0.4(11 屏 mockup) -> 3. [`docs/design/sandbox-plan-worktree.md`](docs/design/sandbox-plan-worktree.md) — sandbox × plan mode × worktree 三者关系 -> 4. [`docs/design/plugin-security.md`](docs/design/plugin-security.md) — plugin 安全模型 -> 5. [`docs/design/effort-levels.md`](docs/design/effort-levels.md) — effort levels 到 DeepSeek 的参数映射 +> 1. [`AGENTS.md`](AGENTS.md) — 仓库操作、验证与安全约束 +> 2. [`docs/CODEX_ALIGNMENT_PLAN.md`](docs/CODEX_ALIGNMENT_PLAN.md) — 当前架构与 PR 路线 +> 3. [`docs/DEVELOPMENT_PLAN.md`](docs/DEVELOPMENT_PLAN.md) — 原始里程碑历史快照 +> 4. [`docs/design/sandbox-plan-worktree.md`](docs/design/sandbox-plan-worktree.md) — sandbox × plan mode × worktree 三者关系 +> 5. [`docs/design/plugin-security.md`](docs/design/plugin-security.md) — plugin 安全模型 ## 项目结构 @@ -21,7 +21,7 @@ deepcode/ │ └── shared-ui/ # CLI 与桌面客户端共享类型 ├── apps/ │ ├── cli/ # @deepcode/cli — npm 包,命令 `deepcode` -│ └── desktop/ # Mac 客户端(Electron + React) +│ └── desktop/ # Mac 客户端(Tauri 2 + Rust + React) ├── docs/ │ ├── DEVELOPMENT_PLAN.md │ ├── VISUAL_DESIGN.html @@ -36,7 +36,7 @@ deepcode/ ### 必需 -- Node.js ≥ 20(推荐 LTS) +- Node.js ≥ 22 - pnpm ≥ 9 - Git ≥ 2.30 - ripgrep(CLI Grep 工具依赖) @@ -55,6 +55,8 @@ cd deepcode pnpm install pnpm typecheck pnpm build +pnpm test +pnpm docs:check ``` ## 工作流 @@ -70,8 +72,7 @@ pnpm build ```bash git checkout -b feat/ # ... write code ... -pnpm test # 跑单测 -pnpm test:e2e # 跑集成测试(需 DEEPSEEK_API_KEY) +pnpm test pnpm lint pnpm typecheck ``` @@ -141,21 +142,13 @@ pnpm --filter @deepcode/core test # 单包 使用 vitest。test 文件 `*.test.ts` 与源码并列。 -### 集成测试 +### 集成与真实 provider 测试 -```bash -pnpm test:e2e -``` - -需要 `DEEPSEEK_API_KEY` 环境变量。CI 自动注入;本地开发需要在 `.env.local` 里设。 +默认测试不请求 DeepSeek API。真实 provider 用例位于 `packages/core/src/providers/deepseek.live.test.ts`,只有显式提供测试凭证并按测试文件说明启用时才运行;不要把凭证写入仓库或测试日志。 ### 安全测试(M3.5 起强制) -```bash -pnpm test:security -``` - -跑 `docs/design/sandbox-plan-worktree.md` §7 + `docs/design/plugin-security.md` §9 的全部测试。每个改 `packages/core/src/sandbox/` 或 `packages/core/src/plugins/` 的 PR 必须跑。 +安全测试属于 `@deepcode/core` 测试套件。每个修改 `packages/core/src/sandbox/`、permissions、credentials、hooks、process execution 或 plugins 的 PR 必须运行 core 全套测试和对应的 focused test files;Linux kernel sandbox 集成测试还需要 bwrap/slirp4netns 与 CI 中的 opt-in 环境。 ## 代码风格 diff --git a/MORNING_REPORT.md b/MORNING_REPORT.md index ec3fc8c..9b09c21 100644 --- a/MORNING_REPORT.md +++ b/MORNING_REPORT.md @@ -1,5 +1,7 @@ # 进度汇报 — 第七轮 "继续推进 to completion" +> **历史快照(2026-05)**:本文件保留当时的交接记录,不代表当前能力、测试数或发布状态。当前方向与事实基线见 [`docs/CODEX_ALIGNMENT_PLAN.md`](docs/CODEX_ALIGNMENT_PLAN.md),实时验证以 CI 为准。 + > 持续覆盖。前六轮内容见 git 历史。 ## TL;DR diff --git a/README.md b/README.md index 5d0105d..7cd4a31 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,10 @@ # DeepCode -**Claude Code 的 DeepSeek 版** —— 完整复刻 Claude Code 全部能力,底层 LLM 切换到 **DeepSeek** +**面向真实代码库的 DeepSeek coding agent** —— CLI、macOS 桌面端与编辑器接入共享一个持续演进的核心 [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) -[![Tests](https://img.shields.io/badge/tests-549%20passing-brightgreen.svg)](.github/workflows/ci.yml) -[![v1 scope](https://img.shields.io/badge/v1%20scope-~98%25-brightgreen.svg)](MORNING_REPORT.md) +[![CI](https://github.com/oratis/deepcode/actions/workflows/ci.yml/badge.svg)](https://github.com/oratis/deepcode/actions/workflows/ci.yml) @@ -14,12 +13,12 @@ ## 这是什么 -如果你在用 **Claude Code** 但希望底层模型用 **DeepSeek** 而不是 Claude,DeepCode 就是为你做的。 +DeepCode 让 DeepSeek 可以在本地代码库中执行读取、编辑、命令、审阅、MCP 和可恢复会话工作。项目最初以 Claude Code 兼容为目标,现在正转向经过验证的 Codex 式运行模型:统一任务生命周期、可靠中断、清晰权限边界和跨客户端一致行为。 -- ✅ **完整对齐** Claude Code 的全部能力:工具调用 / MCP / 子代理 / hooks / skills / plugins / sandbox / checkpointing / 输出风格 / 5 档 effort levels -- ✅ **四种形态**:Node.js CLI · Mac 客户端 · VS Code 扩展 · LSP bridge (Neovim/Emacs/Sublime) -- ✅ **零迁移成本**:settings.json / hooks / MCP servers / skills / agents 与 Claude Code 1:1 对齐。见 [docs/MIGRATION_FROM_CLAUDE_CODE.md](docs/MIGRATION_FROM_CLAUDE_CODE.md) -- ✅ **同安全保证**:sandbox-exec (macOS) + bwrap (Linux) + ed25519 marketplace signatures + DNS proxy + pipeline analysis ([docs/security-model.md](docs/security-model.md)) +- **已可用**:Node.js CLI、Tauri macOS 客户端、核心工具、MCP、hooks、skills、plugins、sandbox、sessions、background tasks 与 voice input。 +- **在收敛**:VS Code/LSP、统一权限、真实取消、thread/turn/item 协议与跨客户端恢复。 +- **兼容优先**:继续读取既有 `settings.json`、`DEEPCODE.md`、`AGENTS.md` 和 Claude 风格扩展资产,但不以未经验证的“1:1 parity”作为安全或完成度承诺。 +- **设计路线**:完整审查、正反方审议和分阶段 PR 见 [Codex alignment plan](docs/CODEX_ALIGNMENT_PLAN.md)。 ## 快速上手 @@ -38,30 +37,11 @@ deepcode --model deepseek-reasoner --effort high Mac 客户端(v1 即将发布):拖入 Applications → 首启完成 onboarding。 -## 完成度 +## 当前工程基线 -``` -M0 设计骨架 ████████████████████ 100% -M1 内核 MVP ████████████████████ 100% -M2 CLI MVP ████████████████████ 100% -M3 modes/hooks/memory ████████████████████ 100% -M3c MCP/compact/etc. ████████████████████ 100% -M3c-rest ████████████████████ 100% -M3.5 sandbox ████████████████████ 100% -M4 skills/agents/style ████████████████████ 100% -M5 plugins manifest ████████████████████ 100% -M5.1 plugin subprocess ████████████████████ 100% -M5.2 marketplace ████████████████████ 100% -M6 Mac client ██████████████████░░ 90% (UI 11 屏 + IPC 协议完,等装 Electron binary) -M7 file panel + rewind ████░░░░░░░░░░░░░░░░ 20% (UI 骨架;Monaco 等 binary) -M8 polish ████████████████████ 100% -M9 release pipeline ██████████████████░░ 90% -v1.1 VS Code/JetBrains █████░░░░░░░░░░░░░░░ 25% (VS Code 骨架 + LSP 骨架) -``` - -**549 个测试通过 · CI ubuntu + macOS 双矩阵绿色**。 +主分支执行 typecheck、lint、format、Vitest、TypeScript build,并在 CI 中覆盖 macOS/Linux;Tauri Rust backend 也纳入单独检查。不要从 README 中读取静态测试总数,当前结果以 [CI](https://github.com/oratis/deepcode/actions/workflows/ci.yml) 为准。 -详细汇报:[MORNING_REPORT.md](MORNING_REPORT.md) +已知架构差距和处理顺序记录在 [docs/CODEX_ALIGNMENT_PLAN.md](docs/CODEX_ALIGNMENT_PLAN.md)。[MORNING_REPORT.md](MORNING_REPORT.md) 是早期历史快照,不再表示当前进度。 ## 文档地图 @@ -79,6 +59,7 @@ v1.1 VS Code/JetBrains █████░░░░░░░░░░░░░ | 文件 | 内容 | | ---------------------------------------------------------------------------- | --------------------------------------------------- | +| [docs/CODEX_ALIGNMENT_PLAN.md](docs/CODEX_ALIGNMENT_PLAN.md) | 当前整体改造计划、审计证据、正反方审议与 PR 路线 | | [docs/DEVELOPMENT_PLAN.md](docs/DEVELOPMENT_PLAN.md) | 整体开发方案 v0.5(1500+ 行 / §3 模块 / §6 里程碑) | | [docs/VISUAL_DESIGN.html](docs/VISUAL_DESIGN.html) | 视觉设计 v0.4(11 屏 mockup) | | [docs/security-model.md](docs/security-model.md) | 威胁模型 + 防御层 + 攻击向量测试 + 已知缺口 | @@ -95,7 +76,7 @@ packages/ shared-ui/ # @deepcode/shared-ui — types shared between CLI + Mac client + VS Code apps/ cli/ # deepcode-cli — Node.js CLI (npm publishable) - desktop/ # @deepcode/desktop — Electron Mac client + desktop/ # @deepcode/desktop — Tauri 2 + React Mac client vscode/ # @deepcode/vscode — VS Code extension (v1.1) lsp/ # @deepcode/lsp — LSP bridge for Neovim/Emacs/Sublime (v1.1) docs/ @@ -113,7 +94,8 @@ scripts/ ## 致谢 -- **Anthropic** 的 [Claude Code](https://github.com/anthropics/claude-code) —— 对齐基准 +- **OpenAI Codex** —— 当前运行模型与客户端架构的重要公开参考 +- **Anthropic Claude Code** —— 早期兼容设计的重要参考 - **DeepSeek** —— 模型与 API - **MCP** 生态 —— Model Context Protocol 协议 diff --git a/docs/BEHAVIOR_PARITY.md b/docs/BEHAVIOR_PARITY.md index 36b1842..3898874 100644 --- a/docs/BEHAVIOR_PARITY.md +++ b/docs/BEHAVIOR_PARITY.md @@ -1,5 +1,7 @@ # Behavior Parity — DeepCode vs Claude Code +> **历史快照(Claude 兼容矩阵)**:本文件记录既有兼容目标,不再作为当前完成度或安全保证。当前事实、已知分叉与 Codex 对齐路线见 [`CODEX_ALIGNMENT_PLAN.md`](CODEX_ALIGNMENT_PLAN.md)。 + > This document tracks where DeepCode's behavior **aligns with**, **deviates from**, or **deliberately enhances** Claude Code. It grows alongside the codebase. Last updated reflects what main contains. Legend: `✅` matches · `🟡` matches with caveats · `🔄` deferred · `⚠️` deliberately differs · `🆕` DeepCode-only addition diff --git a/docs/CODEX_ALIGNMENT_PLAN.md b/docs/CODEX_ALIGNMENT_PLAN.md new file mode 100644 index 0000000..3cf0eb3 --- /dev/null +++ b/docs/CODEX_ALIGNMENT_PLAN.md @@ -0,0 +1,408 @@ +# DeepCode × Codex 整体改造计划 + +> 状态:已完成正反方审议,按仲裁结论执行
+> 基线:`main@38fcc3a`
+> 日期:2026-08-01
+> 决策原则:采用 Codex 已公开验证的产品与工程模式,但保留 DeepCode 的 DeepSeek 定位、品牌和向后兼容性。 + +## 1. 结论先行 + +DeepCode 当前已经不是一个“从零开始”的项目:核心工具、DeepSeek provider、会话、MCP、hooks、sandbox、skills、plugins、CLI、Tauri 桌面端和初步 IDE 接入均已存在,主分支也能完整通过构建与测试。 + +真正的问题是各界面在各自直接拼装 agent loop,导致协议、会话、权限、恢复、后台任务和 UI 状态逐渐分叉。继续按功能清单补齐只会扩大这种分叉。 + +因此本计划不以“继续复刻 Claude Code 菜单”为主线,而以 Codex 的三项核心设计为北星: + +1. **统一运行时语义**:先让所有 host 使用不可绕过的 runtime factory,再把 Thread → Turn → Item/Event 固化成协议事实源。 +2. **可信的长任务执行**:可恢复、可中断、可观察;worktree 只有在保留与冲突语义修复后才用于隔离并行写入。 +3. **客户端薄、运行时厚**:CLI、桌面端、VS Code/LSP 不再各自复制 agent orchestration;具体是 in-process、sidecar 还是 daemon,必须由打包 spike 证明后决定。 + +首要架构决策调整为:先从 CLI 已验证的组装逻辑中提取 `RuntimeHost`,强制统一安全默认值、取消和配置加载;随后以实验 capability 建立最小协议,并在至少两个真实客户端使用后再冻结稳定面。`apps/server` 的 transport 与桌面打包方式不预设;不会立刻重写为 Rust,也不会一次性移除现有 API。 + +## 2. 调研依据 + +本计划基于 2026-08-01 刷新的 Codex 官方手册、官方开源仓库和 DeepCode 当前主分支,而不是基于记忆或旧截图。 + +主要官方参考: + +- [Codex Best practices](https://learn.chatgpt.com/guides/best-practices.md):计划优先、`AGENTS.md`、测试/审阅闭环、技能和长期任务。 +- [Codex Subagents](https://learn.chatgpt.com/docs/agent-configuration/subagents.md):主线程负责决策,子代理负责有界探索;写操作优先 worktree 隔离。 +- [Codex App Server](https://learn.chatgpt.com/docs/app-server.md):JSON-RPC、Thread/Turn/Item、审批、流式事件、恢复/分叉/中断/转向。 +- [Codex Worktrees](https://learn.chatgpt.com/docs/environments/git-worktrees.md):并行本地任务的隔离模型。 +- [Codex code review](https://learn.chatgpt.com/docs/code-review.md):以 diff 和可定位反馈为核心的审阅闭环。 +- [Codex `AGENTS.md`](https://learn.chatgpt.com/docs/agent-configuration/agents-md):仓库级持久指令和就近覆盖规则。 +- [openai/codex](https://github.com/openai/codex):官方开源实现;其 `codex-rs` 已将 protocol、app-server、core、thread-store、tools、sandbox、hooks、skills 和客户端拆成独立边界。 + +这里的“对齐”是设计原则与行为模型对齐,不是复制 OpenAI 的商标、文案、私有服务或逐像素克隆 UI。 + +## 3. 当前事实基线 + +### 3.1 验证结果 + +在 `main@38fcc3a` 上执行: + +```bash +pnpm typecheck +pnpm lint +pnpm format:check +pnpm test +pnpm build +``` + +这些命令全部通过: + +- 910 tests passed +- 12 tests skipped(真实 DeepSeek API、Linux bwrap/netns 等条件测试) +- 3 条 lint warning,无 error +- 当前根 TypeScript build 成功 + +这并不等于全仓覆盖完整:根 `tsconfig.json` 未引用 LSP/VS Code,`pnpm build` 不执行 Cargo check/test,VS Code 使用 `--passWithNoTests`,headless 测试也没有真实 agent E2E。README 的“549 tests”以及多份 handoff/milestone 状态已经明显过期,因此 PR 0 必须同时修正文档和 CI 覆盖。 + +### 3.2 已有优势 + +- `packages/core` 已具备较完整的 agent/tool/provider 基础。 +- MCP、skills、plugins、hooks、sandbox、sessions、snapshots、worktree 均有实现与测试。 +- CLI 已有 resume、background tasks、headless、voice 等可用行为。 +- Tauri 桌面端已有 session sidebar、composer、inspector、file diff/history 等交互骨架。 +- macOS/Linux 双平台 CI 与 release 工具链已存在。 + +### 3.3 关键差距 + +| 优先级 | 差距 | 当前证据 | 后果 | +| ------ | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| P0 | VS Code/LSP 可绕过中央门禁 | `runAgent` 仅在 `opts.mode` 存在时调用 dispatcher;VS Code/LSP 注册完整工具却没有传 mode/permissions/sandbox | Write/Bash 可在缺少统一审批和沙箱时执行 | +| P0 | 桌面 renderer 直接持有 provider 与 agent loop | `apps/desktop/src/lib/mac-agent.ts` 在 WebView 中创建 `DeepSeekProvider`,并明确缺少 hooks/session runtime/autoCompact | 凭证边界偏弱,运行时能力缺失,无法可靠后台执行 | +| P0 | 中断语义不一致 | desktop 有 `AbortController`;LSP `deepcode.abort` 只删除 id,没有中止实际 agent | UI 显示“已停止”但任务仍可能继续写文件 | +| P0 | 桌面 runtime 打包方案未成立 | Tauri app 未打包 Node/server sidecar,安装机也不能假设有 Node 22;core 依赖 Node API | 不能直接宣称“Tauri 后端托管 TypeScript server” | +| P0 | 会话只是 message JSONL | `packages/core/src/sessions/storage.ts` 只存 `StoredMessage`,meta 与 events 分散 | 无法可靠表示未完成 turn、审批、tool item、fork、steer、parent/child agent | +| P0 | 权限与工具执行不是运行时统一能力 | 多个 host 自己决定传哪些 mode/permissions/hooks/sandbox 参数 | 相同设置在不同界面产生不同行为 | +| P1 | 没有统一 Thread/Turn/Item 协议 | `packages/core/src/ipc/protocol.ts` 仍是窄 IPC map;CLI、desktop、LSP、VS Code 分别调用 `runAgent` | 行为、恢复、审批和事件格式持续分叉 | +| P1 | 桌面 fixture 未进入自动验收 | 普通 Vite 入口依赖 Tauri 是预期行为;`preview-app.html` 可工作但没有视觉/交互 gate | UI 改造缺少稳定、可自动化的验收入口 | +| P1 | CLI/desktop 大文件承担过多职责 | `commands.ts` 1344 行、`Repl.tsx` 1017 行、`repl.ts` 963 行、Tauri `commands.rs` 882 行 | 修改成本高,难以建立可测试边界 | +| P1 | VS Code 与 LSP 仍是独立 MVP | VS Code 直接调用 core;LSP 仅支持 executeCommand 且 README 仍标注 TODO | 不能共享 thread history、审批、任务和配置 | +| P1 | 配置叙事仍以 Claude 兼容为中心 | README、BEHAVIOR_PARITY、settings JSON 都围绕 Claude parity | 新能力缺少稳定的 DeepCode 自身产品模型 | +| P1 | 文档真实性不足 | README、HANDOFF、MORNING_REPORT、core README 相互矛盾 | 用户和后续 agent 会基于错误状态做决策 | +| P2 | 可观察性不足 | 没有统一 trace id、结构化运行日志、协议录制/回放 | 难以诊断跨客户端和长任务问题 | +| P1 | worktree 退出语义不安全 | `removeWorktree` 强删 branch,但用户文案声称 branch 会保留 | 并行写入可能丢失未合并工作 | + +## 4. 目标产品模型 + +### 4.1 用户心智 + +- **Project**:一个工作目录及其持久配置。 +- **Thread**:一个可恢复、可分叉、可归档的连续目标。 +- **Turn**:用户的一次请求以及 agent 为此执行的完整工作;现有 `runAgent` 内部所谓 turn 改称 **Model Step**,不能直接投影成用户级 Turn。 +- **Item**:turn 中可独立展示、持久化和审阅的单位,例如消息、命令、工具调用、文件变更、审批、计划更新。 +- **Task/Agent**:thread 下的有界子工作;读任务可共享工作区,写任务在 worktree 安全语义完成后才默认隔离。 + +协议内部以这组术语为目标。原有 `session` 在兼容期映射为 `thread`,但首批 PR 不做全仓 UI 改名;等两个客户端消费新模型后再统一用户术语。 + +### 4.2 桌面端信息架构 + +桌面端不追求复制某一版 Codex 截图,而采用其稳定交互原则: + +- 左栏:Projects / Threads,支持搜索、pin、archive、fork 和状态筛选。 +- 中栏:Turn timeline。消息、plan、tool、command、file change、approval 都是结构化 item。 +- 顶部:当前 project、branch/worktree、运行状态、model/effort、权限 profile。 +- Composer:文本/图片/文件上下文、Plan/Default 模式、发送/interrupt;steer 先定义为“下一安全边界注入”或“取消后重启”,验证 provider 约束后再启用。 +- 右栏:先收敛现有 Changes / Files / Inspector;Terminal / Agents / Context 后置到有真实数据源时。 +- Diff review:先交付文件级 diff 与反馈回传;逐行反馈、单项 revert 和 review all 后置。 +- 长任务状态:Planning / Running / Waiting approval / Waiting input / Blocked / Completed / Failed / Interrupted。 + +### 4.3 CLI 与 IDE + +- CLI 保留终端优先体验,但内部成为 app-server 的一个客户端。 +- VS Code 直接消费统一协议,不再自行创建 provider/agent loop。 +- LSP 只保留真正的编辑器传输兼容;DeepCode 自有丰富事件走 app-server protocol,而不是伪装成 LSP command。 +- headless/CI 继续提供稳定 JSON/JSONL 输出,并由协议事件投影生成。 + +## 5. 目标工程架构 + +```mermaid +flowchart LR + CLI["CLI / headless"] --> Host["RuntimeHost"] + VSCode["VS Code / LSP"] --> Host + Desktop["Tauri desktop"] --> Boundary["Packaging boundary (ADR)"] + Boundary --> Host + Host --> P["experimental protocol"] + P --> Server["optional app-server transport"] + Host --> Runtime["packages/core runtime"] + Runtime --> Threads["thread store"] + Runtime --> Tools["tool + permission pipeline"] + Runtime --> Providers["provider adapters"] + Tools --> Sandbox["sandbox / worktree"] +``` + +### 5.1 `packages/protocol` + +职责: + +- 版本化 request/response/notification schema。 +- `Thread`、`Turn`、`Item`、`Agent`、`Approval`、`Usage`、`Error` 类型。 +- JSON Schema 与 TypeScript 类型生成入口。 +- 协议兼容测试与录制/回放 fixtures。 +- 不依赖 Node、Tauri、React 或具体 provider。 + +首批实验方法只覆盖一个垂直切片: + +```text +initialize +thread/start +thread/read +thread/resume +turn/start +turn/interrupt +turn/completed notification +item/started notification +item/completed notification +approval/request server request +user-input/request server request +``` + +delta 默认只流式传输、不落盘。fork/archive/search、agent graph 等在垂直切片稳定后再加入。实验字段必须显式 capability 协商;至少由两个客户端消费并经过兼容测试后才升为 stable。 + +### 5.2 `RuntimeHost` 与 `apps/server` + +职责: + +- `RuntimeHost` 先统一 provider、tools、config、trust、permissions、hooks、MCP、sandbox 与取消的组装,且安全门禁不可选。 +- `apps/server` 在桌面打包 ADR 后创建;JSONL stdio 只承诺单客户端 ownership 和完成后的跨客户端恢复。 +- 若要多个客户端附着同一个 active turn,必须采用单 daemon + Unix socket/命名管道,并明确锁、订阅、背压与重连;不能把 stdio 当作共享 daemon。 +- 初始化握手、client capabilities 与协议版本协商先保持 experimental。 +- credentials、config、hooks、MCP、sandbox 等只在可信后端加载。 +- graceful shutdown 与未完成 turn 恢复标记。 +- renderer/webview 永远不直接读取 API key;VS Code extension host 属于可信进程,但也应通过统一 runtime 获取 credentials,而不是复制逻辑。 + +### 5.3 `packages/core` + +保留现有可用模块,先建立不可绕过的 `RuntimeHost`,再把“一个 `runAgent(opts)` 函数”逐步重构为可恢复状态机: + +- `AgentRuntime`:处理一个用户级 turn 的生命周期;内部 provider round-trip 为 model step。 +- `ThreadRuntime`:维护 history、active turn、pending approvals、task graph。 +- `ItemEmitter`:把 provider/tool/hook 事件规范化成协议 item。 +- `RuntimeServices`:provider、tools、permissions、sessions、hooks、MCP、worktrees 的依赖容器。 + +当前 `turn_complete` 事件发生在工具执行前,语义其实是 model step complete;必须先更名/适配,不能直接公开为用户级 `turn/completed`。现有 `runAgent` 在迁移期作为兼容 facade 调用新 runtime。 + +### 5.4 持久化 + +采用 append-only rollout JSONL + 可重建索引: + +- 每条记录有 `schemaVersion`、`sequence`、`timestamp`、`threadId`、`turnId?`、`itemId?`。 +- message、tool、approval、file change、status、fork relation 都进入同一事件日志。 +- metadata/index 允许 list/search/pin/archive,不作为完整事实源。 +- 写入先临时文件/原子 rename 或单 writer queue,避免并发损坏。 +- core 与 desktop 目前存在两种 legacy session 格式,且历史版本未完整写入所有 tool 事件。迁移采用格式探测、**双读单写**与 normalization;不修改旧文件,也不声称能恢复从未持久化的数据。 + +### 5.5 权限、工具与沙箱 + +统一顺序: + +```text +model tool call +→ schema validation +→ mode/profile policy +→ repo/user allow-deny rules +→ hook preflight +→ approval request(如需) +→ sandbox/worktree execution +→ hook postflight +→ item persistence +→ client notification +``` + +原则: + +- 默认 workspace-write + 网络受控;扩大边界必须可解释。 +- 权限 profile 与批准策略分开,不能用一个 `mode` 同时表达两者。 +- 写工具以 workspace/worktree 为边界;破坏性动作做目标解析和窄审批。 +- 所有 host 使用同一 pipeline,禁止 renderer 或 IDE 绕过。 + +### 5.6 配置与指令 + +- `AGENTS.md` 成为首选跨 agent 仓库说明;继续读取 `DEEPCODE.md` 作为 DeepCode 专属兼容层。 +- 继续使用现有多层 `settings.json` loader,暂不引入 TOML;先补逐 key provenance 与 deprecated/ignored diagnostics。 +- 配置加载结果提供 provenance,UI 能解释某个值来自 user、project、local override 还是 CLI。 +- 运行时公开 `config/read` 与 `config/diagnostics`,各客户端不自行合并配置。 + +## 6. 分阶段 PR 路线 + +每个 PR 都必须可独立构建、可回滚,并保持现有 CLI 主路径可用。默认创建 draft PR,验证充分后再转 ready。 + +### PR 0 — 事实基线与改造契约 + +- 新增本计划与审议记录。 +- 新增精简 `AGENTS.md`,写明仓库结构、检查命令、完成标准和安全约束。 +- 修正 README/核心文档中的测试数、技术栈、过期状态与“完整复刻”绝对表述。 +- 增加 docs freshness 检查,至少验证关键数字来自测试报告或不再硬编码。 +- 根 typecheck/build 纳入 LSP、VS Code;CI 增加 Cargo check/test,并让当前 coverage 缺口显式可见。 + +验收:文档互不矛盾;新 agent 可只读 `AGENTS.md` 完成 setup、test、review;CI 覆盖全部 workspace 与 Rust backend。 + +### PR 1 — 安全 RuntimeHost 与真实取消 + +- 从 CLI 组装提取 `RuntimeHost`,强制默认 mode、permissions、trust 与 sandbox;host 不能通过漏传 `mode` 绕过 dispatcher。 +- CLI、headless、LSP、VS Code 先共享 factory;修复 LSP 假 abort。 +- provider、pending approval、前台命令、Rust Bash 与 process group 真实取消;定义后台任务不随 turn 隐式存活的 ownership。 +- 修复 worktree 退出强删 branch 与用户文案矛盾。 + +验收:启动延迟写文件的命令并取消,等待后目标文件仍不存在;所有 host 的 Write/Bash 都有一致门禁;worktree 退出不丢未合并工作。 + +### PR 2 — Legacy session 兼容层 + +- 探测 core `.meta.json + message JSONL` 与 desktop `session_meta + typed record JSONL`。 +- 双读旧格式、单写 normalization 后的新格式;旧文件只读且不改字节。 +- 增加截断尾行、中部损坏 diagnostics、并发 writer ownership 测试。 + +验收:两种旧格式可读;重启后顺序连续;中部损坏不静默;不虚构旧版本未保存的 tool history。 + +### PR 3 — 实验性 lifecycle 与协议 + +- 明确 User Turn 与 Model Step;修复当前 `turn_complete` 语义。 +- 新建无 Node/Tauri/React/provider 依赖的实验 protocol package。 +- 只实现 start/read/resume/interrupt 与 completed item 持久化;delta 不落盘。 +- 日志、fixture 和 rollout 同期做敏感信息脱敏。 + +验收:lifecycle invariants、record/replay、重启恢复、terminal state 幂等和协议 golden tests。 + +### PR 4 — Desktop runtime packaging ADR/spike + +- 在 bundled Node sidecar、单可执行 sidecar、Rust runtime 与过渡 renderer loop 中做可发布选择。 +- 必须在签名后的 `.app`、无系统 Node 环境中证明启动、退出、取消、升级和恢复。 +- 同时决定单客户端 stdio 还是多客户端 daemon/socket,不提前承诺 active turn 跨端附着。 + +验收:形成 ADR、可复现 spike、安装包体积/冷启动/签名结果和失败回滚路径。 + +### PR 5 — App-server 垂直切片与 CLI + +- 按 ADR 创建 app-server/transport,实现实验 initialize、start/read/resume/interrupt。 +- CLI 通过同一 handler/client 使用 RuntimeHost,保留外观与 headless JSON/JSONL 兼容。 +- 明确单 owner、断线、背压、重连和 active turn 限制。 + +验收:CLI 原有行为不回退;新增 transport、断线、背压、中断和恢复 e2e。 + +### PR 6 — Desktop runtime migration + +- 按 ADR 把 runtime 移出 renderer,移除 WebView 中的 provider/API key。 +- React 只消费协议事件;接入真实 interrupt、恢复与 structured items。 +- 把 `preview-app.html` 变成自动化 fixture harness;收敛现有 Changes/Files/Inspector。 + +验收:签名 app、凭证边界、Tauri IPC、重启恢复、浏览器 fixture 与视觉测试。 + +### PR 7 — VS Code 与 LSP 收敛 + +- VS Code 改用同一 runtime/protocol,删除重复 provider/runtime 组装。 +- 支持 read/resume、structured tool items、approval、interrupt 与 diff context。 +- LSP 只承担编辑器兼容;移除 `passWithNoTests`,增加真正测试。 + +验收:完成后的 thread 可在 CLI、desktop、VS Code 间恢复;事件和权限语义一致。 + +### PR 8 — 配置、扩展、多代理与 review 收尾 + +- 现有 JSON config 增加 provenance/diagnostics;统一 `AGENTS.md`、`DEEPCODE.md`、MCP、skills、plugins、hooks。 +- 在 worktree 语义安全后启用隔离写任务;sub-agent 深度维持安全上限,按真实需求扩展 agent graph。 +- diff review、可定位反馈、trace id、结构化日志与脱敏导出。 +- 删除完成迁移的旧 IPC/facade;更新所有用户文档。 +- release candidate、迁移演练、性能预算和回滚说明。 + +验收:端到端 golden journey、性能基线、安全 review、文档与 release gate。 + +## 7. 横向验收标准 + +### 7.1 行为 + +- 一个已完成或已中断的 thread 可以从 CLI 创建,在 desktop 恢复,再在 VS Code 继续;active turn 跨端附着取决于 daemon ADR。 +- active turn 可以 interrupt,且中断后不再发生文件写入;steer 只有在安全边界语义经测试后才启用。 +- 重启 server 后未完成 turn 有明确状态,不会伪装成完成。 +- approval、ask-user、tool、file change 在所有客户端具有同一 id 和最终状态。 + +### 7.2 安全 + +- renderer/webview/VS Code webview 中不存在 provider credential。 +- 所有写入与命令经过同一 permission pipeline。 +- 日志、rollout、protocol fixture 默认脱敏凭证与敏感 header。 +- 不可信 repo 不能通过配置/hooks/plugin 自动扩大权限。 + +### 7.3 质量 + +- 主分支不允许新增 `passWithNoTests` 的产品代码包。 +- protocol/core/server 的公共行为必须有 contract 或 e2e test。 +- CI 持续执行 typecheck、lint、format、test、build;关键安全测试按平台运行。 +- 大文件目标:新增业务模块不超过 500 行;现有超大文件随触达拆分,不做无收益搬家。 + +### 7.4 性能 + +- PR 4 spike 记录 app-server/sidecar 冷启动、安装包体积与内存基线,再据实设预算。 +- 取消请求到子进程停止的目标预算在 PR 1 基准测试后锁定。 +- thread list 和长列表 UI 的 SLO 在有真实数据模型与 fixtures 后锁定,避免先写任意数字。 + +## 8. 风险与缓解 + +| 风险 | 缓解 | +| -------------------------- | ------------------------------------------------------------------------------- | +| 改造面过大导致长期分支 | 按安全 host → legacy 兼容 → 实验协议 → 打包 ADR → client 的顺序,小 PR | +| 追逐 Codex 每周变化 | 只对齐稳定原则;协议做版本/capability;记录参考日期 | +| UI 重做先于运行时导致返工 | 先确定 item/lifecycle,再重做 timeline 和 inspector | +| 旧用户配置/会话损坏 | 格式探测、旧文件只读、双读单写、明确回滚窗口 | +| 子代理并行写冲突 | 先修复 worktree 保留/恢复语义,再启用隔离写;合并前统一 review/test | +| 桌面无法托管 Node runtime | PR 4 在签名 app 和无系统 Node 环境做 sidecar/daemon spike,ADR 后才定 transport | +| 为“对齐”牺牲 DeepSeek 特性 | provider capability 由运行时发现;保留 DeepSeek cache、pricing、reasoner 特性 | +| PR 过多难审 | 每个 PR 有单一架构边界、明确依赖和可执行验收命令 | + +## 9. 决策规则 + +后续遇到未写明的选择,按以下顺序裁决: + +1. 安全与数据可恢复性。 +2. 跨客户端一致性。 +3. 可测试、可观察、可回滚。 +4. 用户完成任务的速度与清晰度。 +5. 向后兼容。 +6. 实现便利。 + +若 Codex 的公开行为与 DeepSeek/provider 约束冲突,保留统一产品心智,但允许底层实现不同;在 diagnostics 和文档中明确差异,不伪装完全兼容。 + +## 10. 审议与推进机制 + +本计划已完成一次正式正反方审议: + +- 正方负责证明该架构能降低分叉、提升安全与长期交付速度。 +- 反方负责寻找过度设计、迁移风险、错误优先级和可更小切入点。 +- 仲裁只采纳有代码证据、测试证据或官方设计依据的观点。 +- 审议结论写回本文件,并据此调整 PR 顺序和 scope。 + +审议完成后自动进入 PR 0 与 PR 1,不再等待逐项产品决策;只有凭证、付费、不可逆发布、破坏性数据迁移或权限扩大需要额外确认。 + +## 11. 审议记录 + +### 11.1 正方结论 + +正方支持“统一 runtime、Thread/Turn/Item、可信后端持有凭证、append-only 恢复模型”的主方向,证据是四个 host 虽共享 `runAgent`,但实际传入的 session、permissions、hooks、sandbox、autoCompact 和 task manager 完全不同。正方要求保留真实 interrupt、旧数据兼容和协议不变量,并建议先做最小 protocol/thread-store,不把 UI 或 transport 混入。 + +### 11.2 反方结论 + +反方认可收敛方向,但反对原 PR 顺序,关键证据如下: + +- Tauri app 没有 Node sidecar,无法直接托管现有 TypeScript core/server。 +- stdio 是一对一 transport,不能同时声称多客户端单 runtime owner。 +- `runAgent` 的 dispatcher 因 `mode` 可选而可被 VS Code/LSP 绕过,安全修复不能排到后期。 +- 现有 `turn_complete` 实际是 model step 事件,不能直接公开成用户级 turn lifecycle。 +- core 与 desktop 有两种 legacy session 格式,一次性 importer 会固化数据缺失。 +- worktree 退出会强删 branch,尚不能作为默认隔离承诺。 +- 当前根 build/CI 未覆盖 LSP、VS Code 与 Cargo,910 tests 不能代表全仓完整基线。 + +### 11.3 仲裁决定 + +| 议题 | 决定 | +| -------------- | ------------------------------------------------------------------------------- | +| 总方向 | 保留统一 runtime 和 Thread/Turn/Item 北星 | +| 第一实现优先级 | 接受反方:CI 真实基线后立即修安全门禁、取消和 worktree 数据丢失 | +| 协议 | 接受双方共同建议:最小 experimental slice,两个客户端验证后再 stable | +| 桌面后端 | 接受反方:先做签名 app/无 Node 环境 packaging ADR,不预设 Tauri 承载 TS runtime | +| transport | stdio 只承诺单客户端;active turn 多端共享必须 daemon/socket ADR | +| 会话迁移 | 接受反方:双读单写、旧文件只读,不做一次性破坏迁移 | +| 配置 | 接受反方:沿用 JSON loader 并补 provenance/diagnostics,TOML 后置 | +| UI | 采用 Codex 的结构化工作流原则;术语换皮、Terminal/Agents 面板、逐行 review 后置 | +| 子代理 | 深度 1 视为当前安全限制,不把“加深层级”本身当目标 | + +此仲裁已反映到 PR 路线。后续若没有新的代码证据推翻这些事实,按本版本自动推进。 diff --git a/docs/DEVELOPMENT_PLAN.md b/docs/DEVELOPMENT_PLAN.md index e757d4c..f1c1f2e 100644 --- a/docs/DEVELOPMENT_PLAN.md +++ b/docs/DEVELOPMENT_PLAN.md @@ -1,5 +1,7 @@ # DeepCode 开发方案 v0.5 +> **历史快照(原始里程碑计划)**:本文保留早期产品决策与实现背景,其中 Electron、测试数、完成度和部分能力声明已经过期。新架构决策与执行顺序以 [`CODEX_ALIGNMENT_PLAN.md`](CODEX_ALIGNMENT_PLAN.md) 为准。 + > **一句话定位**:DeepCode 是 Claude Code 的 DeepSeek 版 —— 整体复刻 Claude Code 的全部能力(agent loop / 工具调用 / MCP / 子代理 / hooks / 沙箱 / 会话恢复 / 上下文压缩 / 审批模式 / skills / plugins / harness / 输出风格 / checkpointing),但底层 LLM 全面切换到 **DeepSeek**,提供 **Mac 客户端 + Node.js CLI** 双形态(v1.1 追加 VS Code + JetBrains IDE 扩展),用户首次启动即填入 `DEEPSEEK_API_KEY` 立即可用。Mac 客户端支持 **Claude Code 式自动更新**(后台拉新版 → "Relaunch to update vX.Y.Z" 浮层 → 一键重启升级)。所有 release 走 **GitHub Releases**。 > **变更记录**: diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index 5057082..5365349 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -1,5 +1,7 @@ # DeepCode — Session Handoff +> **历史快照(2026-05)**:本文件用于追溯早期实现,包含已过期的 commit、测试数和待办。当前架构与推进顺序见 [`CODEX_ALIGNMENT_PLAN.md`](CODEX_ALIGNMENT_PLAN.md),仓库操作规范见 [`../AGENTS.md`](../AGENTS.md)。 + A new Claude Code session can pick up DeepCode from this document alone. It's intentionally dense — read once top-to-bottom, then keep open as a map. diff --git a/docs/SHIPPING_MAC.md b/docs/SHIPPING_MAC.md index 3a7de78..67e197b 100644 --- a/docs/SHIPPING_MAC.md +++ b/docs/SHIPPING_MAC.md @@ -1,142 +1,36 @@ -# Shipping the Mac client (M6 → v1) +# Shipping the macOS client -End-to-end checklist for going from the current `apps/desktop` skeleton -to a notarized `.dmg` published on GitHub Releases. +DeepCode Desktop uses **Tauri 2 + Rust + React**. The earlier Electron shipping +instructions have been retired because following them would install unrelated +dependencies and bypass the actual release pipeline. -This document is for the human maintainer; the agent can't do steps that -require an Apple Developer ID or a real device. +The maintained release checklist is [`RELEASING.md`](RELEASING.md). In short: -## Prerequisites +1. Verify the full TypeScript and Rust gates. +2. Keep CLI, desktop, Tauri config, and Cargo versions in sync. +3. Build the Tauri app and run `scripts/sign-and-notarize.sh`. +4. Validate the notarized DMG before pushing a release tag. +5. Treat in-app updates as unavailable until the Tauri signing key, + `createUpdaterArtifacts`, signed updater artifact, and `latest.json` feed are + all configured as described in `RELEASING.md`. -1. **Apple Developer Program membership** ($99/year). -2. **Xcode** installed (provides codesign + altool). -3. A **Developer ID Application** certificate downloaded into the - login keychain. Generate via Xcode → Settings → Accounts → Manage - Certificates → "+" → Developer ID Application. -4. An **app-specific password** for the Apple ID: - https://appleid.apple.com → Sign-In and Security → App-Specific - Passwords. (Used by notarytool — do NOT use your main Apple ID - password.) -5. **GitHub Personal Access Token** with `repo` scope, for - `electron-builder` to publish releases. +Do not restore `electron-builder`, `electron-updater`, Electron templates, or a +`latest-mac.yml` feed. They are not part of the current application. -## One-time CI secrets - -In the repo's GitHub Actions secrets, add: - -| Name | Value | -| ----------------------------- | ---------------------------------------------- | -| `APPLE_ID` | Your Apple Developer login email | -| `APPLE_APP_SPECIFIC_PASSWORD` | The app-specific password from step 4 | -| `APPLE_TEAM_ID` | 10-char team ID (Membership tab in dev portal) | -| `CSC_LINK` | Base64-encoded `.p12` of the Developer ID cert | -| `CSC_KEY_PASSWORD` | Password used when exporting the `.p12` | -| `GH_TOKEN` | The PAT from step 5 | - -To export the `.p12`: +## Local verification ```bash -# In Keychain Access: select your Developer ID Application cert + private -# key → Export → set a password → save as cert.p12, then: -base64 -i cert.p12 -o cert.p12.b64 -# Paste contents of cert.p12.b64 into the CSC_LINK secret. +pnpm typecheck +pnpm lint +pnpm format:check +pnpm test +pnpm build +cargo check --manifest-path apps/desktop/src-tauri/Cargo.toml --locked +cargo test --manifest-path apps/desktop/src-tauri/Cargo.toml --locked +pnpm --filter @deepcode/desktop tauri:build +bash scripts/sign-and-notarize.sh ``` -## First local build - -```bash -# 1. Install the heavy deps (~250 MB) -pnpm add -D --filter @deepcode/desktop \ - electron electron-builder electron-updater \ - vite @vitejs/plugin-react \ - tailwindcss postcss autoprefixer \ - concurrently wait-on - -# 2. Activate the .template configs -mv apps/desktop/vite.config.template.ts apps/desktop/vite.config.ts -mv apps/desktop/postcss.config.template.js apps/desktop/postcss.config.js - -# 3. Dev mode (vite HMR + electron auto-reload) -pnpm --filter @deepcode/desktop dev - -# 4. Package an unsigned .app for local testing -pnpm --filter @deepcode/desktop pack - -# 5. Full signed + notarized .dmg -APPLE_ID=...@... \ -APPLE_APP_SPECIFIC_PASSWORD=xxxx-xxxx-xxxx-xxxx \ -APPLE_TEAM_ID=ABCDEF1234 \ -CSC_LINK=$(base64 -i ~/Downloads/cert.p12) \ -CSC_KEY_PASSWORD=mypassword \ -pnpm --filter @deepcode/desktop dist -``` - -The signed `.dmg` lands in `apps/desktop/release/`. - -## Releasing via tag - -```bash -# Make sure main is green, then: -git tag v1.0.0 -git push origin v1.0.0 -``` - -The `.github/workflows/release.yml` workflow: - -1. Runs the test/build matrix. -2. Publishes `deepcode-cli` to npm. -3. Builds + signs + notarizes the Mac `.dmg`. -4. Creates a GitHub Release tagged with `v1.0.0` and attaches the `.dmg`. -5. `electron-updater` in installed clients picks up the new release via - the GitHub releases feed (see main.ts `setupAutoUpdater`). - -## Sanity-checking notarization - -After the upload, run: - -```bash -xcrun notarytool history --apple-id "$APPLE_ID" \ - --password "$APPLE_APP_SPECIFIC_PASSWORD" --team-id "$APPLE_TEAM_ID" - -# Or check a single submission: -xcrun notarytool info --apple-id "$APPLE_ID" ... -``` - -Once Apple says "Accepted", verify locally: - -```bash -spctl -a -t exec -vv /Applications/DeepCode.app -# Should print: accepted, source=Notarized Developer ID -``` - -## Auto-update flow - -1. User opens an old DeepCode build (v1.0.0). -2. `electron-updater.checkForUpdatesAndNotify()` polls the GitHub Releases - feed once per launch. -3. If a newer release exists, downloads it in the background. -4. On download complete, fires `updater:update-downloaded` IPC event → - the renderer's `UpdateBanner` shows "DeepCode vX.Y.Z is ready to - install. Relaunch to update." -5. User clicks "Relaunch now" → main process calls `app.relaunch()` + - `app.quit()`. (Wiring TBD — currently `window.location.reload()` stub.) - -## Common failures - -- **"Invalid Developer ID Certificate"** — usually the `.p12` doesn't - include the private key. Re-export with both checked. -- **Notarization stuck "In Progress"** — Apple's servers can take 30 min - during peak hours. Wait or open the dev portal to inspect. -- **`spctl` rejects** — make sure `dmg.notarize: true` is set in - `electron-builder.yml`. (It is, but worth re-checking.) -- **App opens then immediately crashes** — first run after notarization - needs `xattr -d com.apple.quarantine /Applications/DeepCode.app` if you - copied the .app outside the .dmg. - -## What's still hardcoded that should be parametrized later - -- `appId: dev.deepcode.client` — fine for v1, may want a more specific - team-prefixed ID for marketplace listings. -- `category: developer-tools` — fine. -- Icon: needs a real `.icns` at `build-resources/icon.icns` (currently - missing — provide one before first build). +Signing and notarization require the Apple credentials documented in +`RELEASING.md`. Never place certificate material, app-specific passwords, or +Tauri updater private keys in the repository or command output. diff --git a/docs/quickstart.md b/docs/quickstart.md index 2e249cd..badf8bf 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -1,8 +1,10 @@ # DeepCode Quickstart -DeepCode is a Claude-Code-parity coding agent driven by **DeepSeek**. It ships -two ways: a **CLI** (`deepcode`) and a **macOS desktop app**. Both share the same -`@deepcode/core` kernel, so behavior is identical. +DeepCode is a coding agent driven by **DeepSeek**. It ships as a **CLI** +(`deepcode`) and a **macOS desktop app**, with VS Code/LSP integrations under +active development. The clients reuse `@deepcode/core`, but some runtime, +permission, and recovery behavior is still being unified; see the +[alignment plan](CODEX_ALIGNMENT_PLAN.md) for current gaps. > Requirements: **Node ≥ 22** for the CLI. A **DeepSeek API key** (get one at > ). macOS 12+ for the desktop app. diff --git a/package.json b/package.json index dbca6f5..6f0a30f 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "lint:fix": "eslint . --fix", "format": "prettier --write \"**/*.{ts,tsx,json,md,yml,yaml}\"", "format:check": "prettier --check \"**/*.{ts,tsx,json,md,yml,yaml}\"", + "docs:check": "node scripts/check-docs.mjs", "clean": "pnpm -r clean", "prepare": "husky || true" }, diff --git a/packages/core/README.md b/packages/core/README.md index 7820bfa..818d030 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -1,38 +1,27 @@ # @deepcode/core -DeepCode 的内核包 —— agent loop / providers / tools / MCP / sandbox / harness。 -**完全 UI 无关**,CLI 和 Mac 桌面客户端都依赖这个包。 +DeepCode 的 TypeScript 内核包:agent loop、DeepSeek provider、tools、config、sessions、MCP、sandbox、hooks、skills、plugins、tasks 与 worktrees。 -> 详见 [`docs/DEVELOPMENT_PLAN.md`](../../docs/DEVELOPMENT_PLAN.md) §3 关键模块设计。 +> 当前架构方向见 [`docs/CODEX_ALIGNMENT_PLAN.md`](../../docs/CODEX_ALIGNMENT_PLAN.md)。原始模块规划保留在 [`docs/DEVELOPMENT_PLAN.md`](../../docs/DEVELOPMENT_PLAN.md) 中作为历史快照。 ## 当前状态 -M0 骨架 — 所有模块都是 placeholder。实际实现按 §6 里程碑展开: - -| 模块 | 文件 | 里程碑 | -| ------------------------------------------------------------- | --------------------------- | ------ | -| agent loop | `src/agent.ts` | M1 | -| DeepSeek provider | `src/providers/deepseek.ts` | M1 | -| Read/Write/Edit/Bash/Grep/Glob tools | `src/tools/` | M1 | -| Sessions (jsonl + 文件快照) | `src/sessions.ts` | M1 | -| Credentials (Keychain + 文件) | `src/credentials.ts` | M2 | -| Config (settings.json 三层) | `src/config.ts` | M2 | -| Slash commands | `src/slash-commands.ts` | M2 | -| Hooks (9 events × 5 handler types) | `src/hooks.ts` | M3 | -| MCP client | `src/mcp.ts` | M3 | -| Compaction | `src/compaction.ts` | M3 | -| Memory dual system | `src/memory.ts` | M3 | -| Harness (system-reminder injector / plan mode / tasks / cron) | `src/harness.ts` | M3 | -| Sandbox (bwrap / sandbox-exec) | `src/sandbox.ts` | M3.5 | -| Skills | `src/skills.ts` | M4 | -| Sub-agents | `src/sub-agents.ts` | M4 | -| Output styles | `src/output-styles.ts` | M4 | -| Plugins | `src/plugins.ts` | M5 | +主要模块均已有实现与测试。当前最重要的已知限制不是“缺少骨架”,而是不同 host 对 `runAgent` 的组装不一致:CLI 传入完整 permissions/hooks/sandbox/session/task services,desktop、LSP 与 VS Code 只传入其中一部分。后续通过不可绕过的 `RuntimeHost` 收敛,而不是继续增加 host-specific wiring。 + +关键入口: + +- `src/agent.ts`:现有 agent loop 与兼容 facade。 +- `src/providers/`:DeepSeek provider 与 capability/pricing。 +- `src/tools/`:内置工具和 registry。 +- `src/harness/tool-dispatcher.ts`:mode、permissions 与 hook gate。 +- `src/sessions/`:legacy JSONL session 与 snapshots。 +- `src/config/`:多层 `settings.json` loader。 +- `src/sandbox/`:macOS sandbox-exec 与 Linux bwrap/network isolation。 ## API 入口 ```ts -import { VERSION, PROJECT_NAME } from '@deepcode/core'; +import { runAgent, ToolRegistry, BUILTIN_TOOLS } from '@deepcode/core'; ``` -完整 API 表面将随 M1 实现展开,参见 `docs/core-api.md`(M1 产出)。 +公共 API 见 [`docs/core-api.md`](../../docs/core-api.md)。新 host 不应直接复制 CLI 的组装代码;在 `RuntimeHost` 落地前,新增入口必须显式传入 mode、permissions、trust 与 sandbox policy。 diff --git a/scripts/check-docs.mjs b/scripts/check-docs.mjs new file mode 100644 index 0000000..b9595e3 --- /dev/null +++ b/scripts/check-docs.mjs @@ -0,0 +1,77 @@ +import { readFileSync, existsSync } from 'node:fs'; +import { resolve } from 'node:path'; +import process from 'node:process'; + +const root = resolve(import.meta.dirname, '..'); +const failures = []; + +const read = (path) => readFileSync(resolve(root, path), 'utf8'); + +const required = [ + 'AGENTS.md', + 'README.md', + 'CONTRIBUTING.md', + 'SECURITY.md', + 'docs/CODEX_ALIGNMENT_PLAN.md', + 'docs/quickstart.md', + 'docs/security-model.md', +]; + +for (const path of required) { + if (!existsSync(resolve(root, path))) failures.push(`missing required document: ${path}`); +} + +const currentDocs = [ + 'README.md', + 'CONTRIBUTING.md', + 'packages/core/README.md', + 'docs/quickstart.md', +]; +const staleCount = /(?:tests[- ]|测试[::]?\s*|测试\s+)[0-9]{2,}\s*(?:passing|passed|个测试通过)?/i; +for (const path of currentDocs) { + const body = read(path); + if (staleCount.test(body)) failures.push(`${path}: hard-codes a test count; link to CI instead`); +} + +for (const path of currentDocs) { + if (/Electron Mac client|Electron \+ React|electron-builder/.test(read(path))) { + failures.push(`${path}: documents the retired Electron desktop stack`); + } +} + +const historical = [ + 'MORNING_REPORT.md', + 'docs/HANDOFF.md', + 'docs/BEHAVIOR_PARITY.md', + 'docs/DEVELOPMENT_PLAN.md', +]; +for (const path of historical) { + const firstLines = read(path).split('\n').slice(0, 12).join('\n'); + if (!firstLines.includes('历史快照')) { + failures.push(`${path}: legacy status document must be marked as 历史快照 near the top`); + } +} + +const rootTsconfig = JSON.parse(read('tsconfig.json')); +const refs = new Set((rootTsconfig.references ?? []).map((entry) => entry.path)); +for (const path of [ + './packages/core', + './packages/shared-ui', + './apps/cli', + './apps/desktop', + './apps/lsp', + './apps/vscode', +]) { + if (!refs.has(path)) failures.push(`tsconfig.json: missing workspace reference ${path}`); +} + +if (!read('CONTRIBUTING.md').includes('Node.js ≥ 22')) { + failures.push('CONTRIBUTING.md: Node requirement must match package.json (>=22)'); +} + +if (failures.length > 0) { + process.stderr.write(`${failures.map((failure) => `- ${failure}`).join('\n')}\n`); + process.exitCode = 1; +} else { + process.stdout.write('Documentation consistency checks passed.\n'); +} diff --git a/tsconfig.json b/tsconfig.json index 676c282..b2e6051 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,8 @@ { "path": "./packages/core" }, { "path": "./packages/shared-ui" }, { "path": "./apps/cli" }, - { "path": "./apps/desktop" } + { "path": "./apps/desktop" }, + { "path": "./apps/lsp" }, + { "path": "./apps/vscode" } ] }