Skip to content

Latest commit

 

History

History
118 lines (90 loc) · 8.03 KB

File metadata and controls

118 lines (90 loc) · 8.03 KB

项目定位

Coding Code 是 AI 编程助手。

模块划分

包级(pnpm workspace):

包 目录 职责
@codingcode/core packages/codingcode 核心引擎:agent loop 与全部编排能力
@codingcode/desktop packages/desktop 桌面端(Electron + React)

packages/sdk、packages/web 目前只有空 src/,尚无实现。

@codingcode/core 内部特性目录:

  • agent:本项目核心,手写 ReAct loop 与编排;不持有 Session、不感知传输协议
  • tools:工具系统,domains/ 下分 fs / bash / web / self / subagent 五个域
  • llm:模型调用与 provider 适配
  • infra:应用配置(config.yaml)、模型清单(models.json)、YAML 存取、日志
  • mcp:Model Context Protocol 集成
  • context:上下文预算与压缩
  • memory:跨会话长期记忆
  • checkpoint:Shadow Git 变更跟踪与回滚
  • hooks:可插拔钩子点
  • subagent:子智能体委派
  • skills:Markdown 技能包装载
  • approval:审批决策链
  • session:会话持久化
  • scheduler:定时调度
  • todo:任务清单
  • rules:全局 / 项目级规则装载
  • server:HTTP / SSE 入口
  • client:HTTP 客户端(AgentClient 的实现)
  • core:通用件(error / result / path),不指向任何功能模块
  • contracts:跨领域共享契约
  • layer.ts:组合根,全量装配

架构要求

依赖倒置:所有非叶子模块利用 port.ts(宽契约;agent 自持的装配端口也在 agent/port.ts)声明自己需要的接口和类型定义,使调用者不需要依赖实现方;只允许依赖下层模块。

分层与允许依赖:

层 落点 允许依赖
L0 通用件 core/ node 内置 + 同目录
L1 共享契约 contracts/ core/ + 同目录 + 第三方(type-only)
L1' 端口契约 各 xxx/port.ts(含 agent/port.ts 的装配端口) core/ + contracts/
L2 实现 tools/、hooks/、session/、approval/、llm/、mcp/、context/ … L0 + L1
L3 组合根 layer.ts、agent/tool-env.ts 全部

架构边界硬规则(由 packages/codingcode/test/architecture/boundaries.test.ts 静态断言,共 29 项):

  • R1 契约不得 import 实现:contracts/ 与 **/port.ts 的相对 import 只能落在 core/、contracts/ 或同目录
  • R2 实现不得依赖消费者模块:agent 自持的装配端口 ToolEnvPort 只在 agent/ 内部出现
  • R3 core/ 零内部依赖:不引用 core/ 之外的任何 src 模块
  • R4 一个概念只允许一处类型定义,canonical 落点为 contracts/
  • 准入:core/ 的 import 只能是 node 内置与同目录;contracts/ 只引用 core/、同目录与第三方
  • 可解析:src/** 的每条相对 import 都必须能在仓库内找到落点

类型落点判据(先判归属,再判引用面):

  • 判据一 —— 有无领域归属:不指向任何功能模块的(错误基类、结果容器、路径运算)→ core/;指向某功能模块的 → 判据二
  • 判据二 —— 引用面,只作用于领域件:仅 1 个 src 领域引用 → 回该领域已有的归属文件;只出现在某调用方接口签名里 → 内联进调用方;≥2 个 src 领域,或 ≥1 个跨包 → contracts/

机制形状例外:z.ZodTypeAny、SDK client、Effect 的 R 通道类型必须留在叶子模块,不得进 contracts/。契约只暴露窄的纯数据描述——MCP 契约返回 McpToolSpec,z.fromJSONSchema 的转换由拥有机制的 tools/catalog.ts 自己做。

开发规则

  • 禁止用户当前轮未明确要求就主动修改仓库中任何内容,包括源代码、配置文件、文档等
  • 禁止用户当前轮未明确要求就主动进行 reset、commit、push 等相关会影响 git 历史或者当前仓库代码的操作,仅用户显式要求进行某类操作才能进行;仅允许 git diff、git log 等无副作用的操作可以自主进行
  • 禁止未在用户指示下补充测试,当开发任务完成后,给用户报告完成程度,由用户决定针对哪些部分写测试
  • 禁止将工具执行细节泄漏到 agent 编排层及其他模块,agent 只依赖端口契约,不得 import 工具实现
  • 禁止将传输协议细节(HTTP / SSE)泄漏到 agent 核心及其他模块,agent 不得依赖 server/、client/
  • 不允许假设“这是未来需要扩展的”,所以现在就不做,应该贴合用户的实际要求
  • 不允许总是有阶段性计划,分阶段完成很容易导致过程产生一堆没用的死代码
  • 不许兼容、兜底旧代码
  • 修改过程中发现错误,如果是本次范围就修改(包括测试),否则要在最后指出
  • 仅允许使用简短注释

测试规则

唯一判据:改生产代码的逻辑,测试必须失败;改不影响行为的文案、命名、注释、格式,测试不应失败。不满足此判据的用例一律不写。

该怎么写:

  • 只断言可观察的行为:给定输入 → 返回值、副作用、状态变化、抛出的错误。断言对象是生产代码的结果,不是测试里自造的数据。
  • 采用 Arrange-Act-Assert:一段准备、一段触发、一段断言,一个用例只验证一个概念。
  • 用例名描述行为与预期,不描述实现细节。
  • 覆盖边界与失败路径(边界值、空集合、错误分支),这里才是缺陷高发区。
  • 按层级选择:纯函数用单元测试;跨模块链路用集成测试(mock 掉外部依赖如 LLM),验证真实装配后的端到端行为。

禁止写的类型:

  1. 文案 / 提示词断言——断言提示词、系统说明、注释、UI 文案包含或不再包含某个字符串。提示词是产品内容,其变更由人工评审守护,不写成测试。
  2. 类型形状断言——运行时断言某字面量有哪些字段、字段是什么类型。类型正确性由 tsc 保证,这类断言恒真且零信息量;确需钉住类型时用编译期的 @ts-expect-error / expectTypeOf,不要写成运行时 expect。
  3. 存在性 / 导出断言——断言文件存在、类 / 函数 / layer 已导出、方法存在。真断裂时编译与上层用例会同时失败,此类用例不提供额外信息。
  4. 常量钉死——断言常量等于它自身的字面量。需要守护的是行为,不是常量的副本。
  5. 测试内重新实现逻辑——在测试里重写一遍待测算法再断言自己写的副本,只证明写法一致,发现不了实现缺陷。
  6. 源码文本 / 结构扫描——用字符串或正则解析源码断言导入、布局或写法。这属于静态分析:类型与导入可解析性由 tsc 保证,无需重复;架构分层等 tsc 无法表达的约束,改用 ESLint 规则或 AST 解析,而不是正则匹配源码文本(现有 test/architecture/boundaries.test.ts、test/hooks/points-coverage.test.ts 应按此方向迁移)。
  7. 占位 / 恒真断言——expect(true).toBe(true)、只 toBeDefined() 不校验值、以及无论如何都会通过的断言。
  8. 重复用例——与已有用例覆盖同一行为的副本;发现重复应合并,不要并存。

其他:

  • 测试必须独立、确定、可任意顺序执行,不依赖执行顺序或共享可变状态(每个用例自备数据并自行清理)。
  • 不为「将来可能的变化」预留用例,只覆盖当前真实存在的行为。
  • 新增 / 删除测试前先取得用户许可(见「开发规则」)。

其他规则

  • 用户要求回答问题时,必须清晰回答每一点问题,不得遗漏
  • 禁止编造任何证据、方案或者代码现状等内容
  • 关于 TypeScript 规范,参考 TypeScript 官方文档,不得使用非官方推荐的方案
  • 设计方案后,须深入解释每一步的理由
  • 关于方案设计,禁止自己编造,只允许查找社区中的成熟实现,且输出时必须贴出相应来源,来源必须真实,保证用户能够打开链接、经得起二次验证