# 目标目录结构（Target Directory Structure）

> 设计原则：**域优先、层校验** — 按功能领域组织目录，通过 `layer-contract.config.json` 强制执行层依赖方向。不做扁平化 `packages/core/src/[types|repo|service|...]` 大杂烩。

## 层级模型

```
Types ─→ Config ─→ Repo ─→ Service ─→ Runtime ─→ UI
```

## 执行状态（Phase A）

- 状态：进行中（本轮只做合同与门禁，不进行目录搬迁）。
- 本轮目标：
  - 落地 `check:layer-coverage`（映射覆盖率 100%）。
  - 落地 `check:shared-types`（shared types 共享门槛）。
  - 将以上两项接入 `type-check` 与 runbook。
- 明确不做：
  - 不移动 `packages/core/src/` 目录结构。
  - 不改变业务行为或 UI 语义。

## 执行状态（Phase B - Slice 1）

- 状态：进行中（类型抽离 + presenter contract 解耦，仍不搬目录）。
- 本轮已完成：
  - 新增 `packages/core/src/shared/toolPresenterContracts.ts`，承接 `ToolPresenter` / `ToolBlocksPresenter` / `createToolBlocksPresenter` / `isToolBlocksPresenter` 作为共享合同。
  - `packages/core/src/tools/presenters/types.ts` 降级为兼容 re-export，避免一次性大爆炸改动。
  - `ToolRouter`、`ToolRegistry`、以及各 `packages/core/src/tools/modules/*/presenter*.tsx` 的 contract 类型导入改为指向 shared 合同层，减少对 `packages/core/src/tools/presenters/` 的直接耦合。
  - 新增 `packages/core/src/shared/toolPresenterContracts.test.ts`，锁定 blocks presenter 标记与类型守卫行为。
- 明确不做：
  - 不迁移 `packages/core/src/tools/presenters/*` 到 `packages/core/src/components/tool/*`。
  - 不改任何 tool UI 文案、交互逻辑、审批流语义。

## 执行状态（Phase B - Slice 2）

- 状态：进行中（继续类型抽离，不搬目录）。
- 本轮已完成：
  - 新增 `packages/core/src/shared/approvalPromptContracts.ts`，统一承接 `ConfirmMenuOption` / `ConfirmMenuDecision` 与各类 `*ApprovalDecision`。
  - `packages/core/src/tools/presenters/ConfirmMenu.tsx` 与 `packages/core/src/components/ui/ConfirmMenu.tsx` 改为消费 shared 合同，并保留类型 re-export 兼容入口。
  - `bash/edit/fsRead/fsWrite/skill` 五个 approval prompt 统一改为 shared decision 类型输入，并保留原文件 `export type` 兼容。
  - 新增 `packages/core/src/shared/approvalPromptContracts.test.ts`，锁定关键 union 合同。
- 明确不做：
  - 不修改审批菜单交互逻辑（键位、提交、取消、反馈）与文案。
  - 不移动任何目录或组件位置。

## 执行状态（Phase B - Slice 3）

- 状态：进行中（细化类型统一，不搬目录）。
- 本轮已完成：
  - `packages/core/src/components/tool/ToolHeaderLine.tsx` 删除本地 `ToolHeaderStatus` 重复定义，改为复用并 re-export `packages/core/src/shared/toolMessageTypes` 的同名类型。
  - `packages/core/src/components/tool/ToolSubline.tsx` 删除本地 `ToolSublineStatus` 重复定义，改为复用并 re-export `packages/core/src/shared/toolMessageTypes` 的同名类型。
- 明确不做：
  - 不调整 header/subline 的渲染逻辑、文案、缩进与配色。

## 执行状态（Phase B - Slice 4）

- 状态：进行中（继续抽离 interactive prompt 类型合同，不搬目录）。
- 本轮已完成：
  - 新增 `packages/core/src/shared/interactivePromptContracts.ts`，集中定义 ask/plan-mode 交互提示的类型合同。
  - `askQuestions.ts`、`interactivePrompts.ts`、`planModeQuestions.ts` 改为消费 shared 合同并保留 type re-export，保持现有导入兼容。
  - 新增 `packages/core/src/shared/interactivePromptContracts.test.ts`，锁定核心 union/结构类型。
- 明确不做：
  - 不修改任何问题文案、fallback 文案与 prompt 解析逻辑。
  - 不移动目录结构。

## 执行状态（Phase B - Slice 5）

- 状态：进行中（单实现收敛，不搬目录）。
- 本轮已完成：
  - `packages/core/src/tools/presenters/ApprovalHeader.tsx` 改为转发 `packages/core/src/components/ui/ApprovalHeader`。
  - `packages/core/src/tools/presenters/MarkdownBlock.tsx` 改为转发 `packages/core/src/components/ui/MarkdownBlock`（含 `parseMarkdown` / `renderInline`）。
  - 保留原导入路径，避免调用方改动。
- 明确不做：
  - 不改变 ApprovalHeader / MarkdownBlock 的渲染行为。
  - 不处理 ConfirmMenu 双实现（留到后续独立切片）。

## 执行状态（Phase B - Slice 6）

- 状态：进行中（继续单实现收敛，不搬目录）。
- 本轮已完成：
  - `packages/core/src/tools/presenters/ConfirmMenu.tsx` 改为转发 `packages/core/src/components/ui/ConfirmMenu`，并由 shared 合同导出类型。
  - 保留原 `packages/core/src/tools/presenters/ConfirmMenu` 导入入口，避免调用方改动。
- 明确不做：
  - 不改 ConfirmMenu 任何键盘交互/焦点/提交语义。

## 执行状态（Phase B - Slice 7）

- 状态：进行中（fallback presenter 解耦，不搬目录）。
- 本轮已完成：
  - 新增 `packages/core/src/components/tool/FallbackToolPresenter.tsx` 承接 fallback presenter 实现。
  - `packages/core/src/tools/presenters/fallback.tsx` 降级为兼容 re-export。
  - `packages/core/src/components/tool/ToolRouter.tsx` 不再依赖 `packages/core/src/tools/presenters/fallback`，改为依赖本层组件实现。
- 明确不做：
  - 不修改 fallback 的展示逻辑、surface suffix 规则和错误详情渲染规则。

## 执行状态（Phase B - Slice 8）

- 状态：进行中（todo 类型合同统一，不搬目录）。
- 本轮已完成：
  - 新增 `packages/core/src/shared/todoContracts.ts`，统一 `TodoStatus` / `TodoItem` / `TODO_STATUSES`。
  - `packages/core/src/tools/modules/todoWrite/handler.ts` 与 `packages/core/src/tools/runtime/todosFile.ts` 改为消费 shared todo 合同。
  - 保留 `todoWrite/handler.ts` 与 `todosFile.ts` 的类型导出兼容入口，避免调用方改动。
  - 新增 `packages/core/src/shared/todoContracts.test.ts`。
- 明确不做：
  - 不修改 TodoWrite 业务校验、文件路径与写入行为。

## 执行状态（Phase B - Slice 9）

- 状态：进行中（继续去除 todoWrite 内部类型耦合，不搬目录）。
- 本轮已完成：
  - `packages/core/src/tools/modules/todoWrite/presenter.tsx` 不再从 `./handler` 获取 `TodoItem`，改为直接使用 `packages/core/src/shared/todoContracts`。
- 明确不做：
  - 不修改 todo 列表展示逻辑或状态文案。

## 执行状态（Phase C - Slice 1）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/skills/SkillStore.ts` 与 `packages/core/src/skills/SkillStore.test.ts` 迁移到 `packages/core/src/features/skills/`。
  - `packages/core/src/tools/modules/skill/handler.ts` 与 `packages/core/src/tools/modules/skill/index.ts` 改为引用 `packages/core/src/features/skills/SkillStore`。
  - 在 `packages/core/src/skills/SkillStore.ts` 保留兼容 re-export，降低一次性迁移风险。
  - `layer-contract.config.json` 增补 `packages/core/src/features/skills` 的 Repo 层映射。
- 明确不做：
  - 不改 SkillStore 的扫描逻辑、缓存语义和 skill 工具行为。

## 执行状态（Phase C - Slice 2）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/commands/CommandStore.ts` 与 `packages/core/src/commands/CommandStore.test.ts` 迁移到 `packages/core/src/features/commands/`。
  - `packages/core/src/commands/render.ts` 与 `packages/core/src/commands/render.test.ts` 迁移到 `packages/core/src/features/commands/`。
  - `packages/core/src/features/commands/registry.ts` 与 `packages/core/src/tools/modules/slashCommand/*` 改为引用 `packages/core/src/features/commands/{CommandStore,render}`。
  - 在 `packages/core/src/commands/CommandStore.ts` 与 `packages/core/src/commands/render.ts` 保留兼容 re-export，降低一次性迁移风险。
  - `layer-contract.config.json` 增补 `packages/core/src/features/commands/CommandStore.ts` 的 Repo 层映射。
- 明确不做：
  - 不改 slash command 的解析、派发与输出语义。
  - 不改 CommandStore 的扫描逻辑与命令覆盖优先级。

## 执行状态（Phase C - Slice 3）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/services/models.ts` 与 `packages/core/src/services/models.test.ts` 迁移到 `packages/core/src/core/models/`。
  - `packages/core/src/services/modelContextCatalog.ts` 与 `packages/core/src/services/modelContextCatalog.test.ts` 迁移到 `packages/core/src/core/models/`。
  - 在 `packages/core/src/services/models.ts` 与 `packages/core/src/services/modelContextCatalog.ts` 保留兼容 re-export，避免一次性迁移上层调用方。
  - `layer-contract.config.json` 增补 `packages/core/src/core/models/{models,modelContextCatalog}.ts` 的 Repo 层映射（过渡期）。
- 明确不做：
  - 不改模型拉取逻辑、catalog 缓存策略、错误映射与超时行为。
  - 不改 `adapters/setup/connectionTest` 的调用路径与用户可见输出。

## 执行状态（Phase C - Slice 4）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/invokables/{types.ts,charBudget.ts,charBudget.test.ts}` 迁移到 `packages/core/src/shared/invokables/`。
  - `packages/core/src/tools/modules/skill/{handler.ts,index.ts}` 改为引用 `packages/core/src/shared/invokables/charBudget`。
  - 在 `packages/core/src/invokables/{types.ts,charBudget.ts}` 保留兼容 re-export，确保旧导入路径仍可用。
- 明确不做：
  - 不改 `truncateByCharBudget` 行为和截断语义。
  - 不改 skill 工具的输出格式与命令拼接策略。

## 执行状态（Phase C - Slice 5）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/catN.ts` 与 `packages/core/src/utils/catN.test.ts` 迁移到 `packages/core/src/shared/utils/`。
  - `edit` 工具与 `patchStartLineNumber` 改为引用 `packages/core/src/shared/utils/catN`。
  - 在 `packages/core/src/utils/catN.ts` 保留兼容 re-export，避免旧导入路径一次性失效。
- 明确不做：
  - 不改 `stripCatNPrefixes` 的解析规则与正则语义。
  - 不改 edit/patch 的业务流程与输出文案。

## 执行状态（Phase C - Slice 6）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/paths.ts` 与 `packages/core/src/utils/paths.test.ts` 迁移到 `packages/core/src/shared/utils/`。
  - `tools/modules/{read,write,edit,notebookEdit}`、`tools/executor/*`、`adapters/permissions/permissionKeys.ts` 改为引用 `packages/core/src/shared/utils/paths`。
  - `packages/core/src/tools/utils/paths.ts` 改为桥接到 `packages/core/src/shared/utils/paths`。
  - 在 `packages/core/src/utils/paths.ts` 保留兼容 re-export，保证旧导入路径可用。
- 明确不做：
  - 不改绝对路径校验、路径归一化与显示格式语义。
  - 不改任意工具模块的业务逻辑与权限策略。

## 执行状态（Phase C - Slice 7）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/planMode.ts` 与 `packages/core/src/utils/planMode.test.ts` 迁移到 `packages/core/src/shared/utils/`。
  - `tools/modules/{edit,write,exitPlanMode}`、`tools/executor/policyPreflight.ts`、`features/semantics/core/modeSemantics.ts` 改为引用 `packages/core/src/shared/utils/planMode`。
  - 在 `packages/core/src/utils/planMode.ts` 保留兼容 re-export，保证旧导入路径仍可用。
- 明确不做：
  - 不改 plan mode reminder 文案、拼接规则与路径显示语义。
  - 不改编辑权限约束（plan mode 限制）和执行流程。

## 执行状态（Phase C - Slice 8）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/toolUi.ts` 迁移到 `packages/core/src/shared/utils/toolUi.ts`。
  - `packages/core/src/utils/toolErrorUi.ts` 与 `packages/core/src/utils/toolErrorUi.test.ts` 迁移到 `packages/core/src/shared/utils/`。
  - `components/tool/*` 与 `tools/modules/{bash,glob,grep,read,write}/presenter.tsx`、`tools/presenters/ToolUiPrimitives.tsx` 改为引用 `packages/core/src/shared/utils/{toolUi,toolErrorUi}`。
  - 在 `packages/core/src/utils/toolUi.ts` 与 `packages/core/src/utils/toolErrorUi.ts` 保留兼容 re-export。
- 明确不做：
  - 不改 tool subline 缩进、前缀符号与渲染样式。
  - 不改 compact error detail 的过滤规则与文案策略。

## 执行状态（Phase C - Slice 9）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/terminal.ts`、`packages/core/src/utils/terminal.test.ts`、`packages/core/src/utils/terminal.ansiAudit.test.ts` 迁移到 `packages/core/src/shared/utils/`。
  - `entrypoints/*`、`legacy/runLegacyCli.tsx`、`screens/perf/TranscriptPerfScreen.tsx`、`features/commands/registry.ts` 改为引用 `packages/core/src/shared/utils/terminal`。
  - `TranscriptPerfScreen` 与 `runLegacyCli` 对应测试的 `vi.mock` 路径同步到新位置。
  - ANSI audit 白名单路径更新为 `packages/core/src/shared/utils/terminal.ts`。
  - 在 `packages/core/src/utils/terminal.ts` 保留兼容 re-export。
- 明确不做：
  - 不改终端清屏时机、TTY 检测和 ANSI 样式定义。
  - 不改命令 registry 的输出语义与文案。

## 执行状态（Phase C - Slice 10）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/inkStreams.ts` 与 `packages/core/src/utils/inkStreams.test.ts` 迁移到 `packages/core/src/shared/utils/`。
  - `services/runtimeUiBridge.tsx` 与 `legacy/runLegacyCli.tsx` 改为引用 `packages/core/src/shared/utils/inkStreams`。
  - `runtimeUiBridge` 与 `runLegacyCli` 对应测试里的 `vi.mock` 路径同步到新位置。
  - 在 `packages/core/src/utils/inkStreams.ts` 保留兼容 re-export。
- 明确不做：
  - 不改 Ink stdout 安全代理逻辑与默认行列回退策略。
  - 不改 static output reset 行为与异常吞掉策略。

## 执行状态（Phase C - Slice 11）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/consoleLogger.ts` 与 `packages/core/src/utils/consoleLogger.test.ts` 迁移到 `packages/core/src/shared/utils/`。
  - `subagents/registry.ts` 改为引用 `packages/core/src/shared/utils/consoleLogger`。
  - 在 `packages/core/src/utils/consoleLogger.ts` 保留兼容 re-export。
- 明确不做：
  - 不改 console logger 的 WebSocket 服务、HTML 输出和序列化逻辑。
  - 不改 subagent 运行时日志的触发时机与日志内容。

## 执行状态（Phase C - Slice 12）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/toolFormatting.ts` 与 `packages/core/src/utils/toolFormatting.test.ts` 迁移到 `packages/core/src/shared/utils/`。
  - `tools/modules/*/presenter.tsx`、`tools/executor/handlers/taskSubAgent.ts`、`features/repl/*`、`features/tools/presentation/*`、`features/semantics/selectors/*` 改为引用 `packages/core/src/shared/utils/toolFormatting`。
  - 相关 `presenter.branches.test.tsx` 的 `vi.doMock`/`vi.importActual` 路径同步到新位置。
  - 在 `packages/core/src/utils/toolFormatting.ts` 保留兼容 re-export。
- 明确不做：
  - 不改 tool call/result 格式化规则、计数规则与摘要文案。
  - 不改 task/tool message 映射语义。

## 执行状态（Phase C - Slice 13）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/config.ts` 迁移到 `packages/core/src/shared/utils/config.ts`。
  - 在 `packages/core/src/utils/config.ts` 保留兼容 re-export。
- 明确不做：
  - 不改任何运行时配置加载逻辑（`packages/core/src/env/config.ts` / `packages/core/src/core/config/*`）。
  - 不改默认配置字段和值语义。

## 执行状态（Phase C - Slice 14）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/utils/theme.ts` 迁移到 `packages/core/src/shared/utils/theme.ts`。
  - 在 `packages/core/src/utils/theme.ts` 保留兼容 re-export。
- 明确不做：
  - 不改任何主题色值、主题字段和 `getTheme()` 返回语义。
  - 暂不改现有调用方导入路径（保持兼容入口以降低改动面）。

## 执行状态（Phase C - Slice 15）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/tools/**` 下所有 `utils/theme` 依赖切换为 `shared/utils/theme`（含 presenter 与相关测试 mock）。
- 明确不做：
  - 不改任意 presenter 的渲染逻辑、文案、样式规则。
  - 不改主题定义和颜色值，仅做导入路径收敛。

## 执行状态（Phase C - Slice 16）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/components/**`、`packages/core/src/screens/**`、`packages/core/src/ui/**` 下剩余 `utils/theme` 依赖切换为 `shared/utils/theme`（含相关测试 mock 与类型导入）。
- 明确不做：
  - 不改 UI 文案、布局、交互和样式行为。
  - 不改主题定义，仅做导入路径收敛。

## 执行状态（Phase C - Slice 17）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/adapters/setup/connectionTest.ts` 与对应测试对 `services/{models,modelContextCatalog}` 的导入切换为 `core/models/*`。
  - `connectionTest.test.ts` 的 `vi.mock` 目标路径同步到 `core/models/*`。
- 明确不做：
  - 不改连接测试逻辑、错误映射与模型 context 推断语义。
  - 不删除 `packages/core/src/services/{models,modelContextCatalog}` 兼容 re-export 文件。

## 执行状态（Phase C - Slice 18）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `scripts/check-no-ansi.mjs` 的白名单与失败提示从 `packages/core/src/utils/terminal.ts` 切换为 `packages/core/src/shared/utils/terminal.ts`。
  - `scripts/surface-screen-model-smoke.tsx` 对 `inkStreams` 的导入切换为 `packages/core/src/shared/utils/inkStreams.ts`。
  - `scripts/check-coverage-thresholds.mjs` 对 `planMode` 的覆盖率目标切换为 `packages/core/src/shared/utils/planMode.ts`。
  - `CODEMAP.md` 与 `docs/pitfalls/summary.md` 中对应索引路径收敛到 canonical 位置（`shared/utils`、`features/commands`）。
- 明确不做：
  - 不改任何运行时行为、工具逻辑或 UI 交互。
  - 不删除旧 shim 文件，仅做索引与脚本路径收敛。

## 执行状态（Phase C - Slice 19）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/services/models.ts` 与 `packages/core/src/services/modelContextCatalog.ts` 两个已无调用方的兼容 re-export shim。
  - `scripts/layer-contract.config.json` 移除上述两个过渡 Repo 映射条目，仅保留 `packages/core/src/core/models/*` canonical 映射。
- 明确不做：
  - 不改 `packages/core/src/core/models/*` 的实现逻辑、错误映射或网络请求行为。
  - 不改 `runtimeUiBridge` 等仍位于 `packages/core/src/services/` 的模块职责。

## 执行状态（Phase C - Slice 20）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/commands/CommandStore.ts`、`packages/core/src/commands/render.ts` 与 `packages/core/src/skills/SkillStore.ts` 三个已无调用方的兼容 re-export shim。
  - `scripts/layer-contract.config.json` 移除上述三项过渡映射条目，仅保留 `packages/core/src/features/{commands,skills}` canonical 映射。
- 明确不做：
  - 不改 custom commands 的扫描/渲染语义。
  - 不改 skill store 的扫描、缓存与加载行为。

## 执行状态（Phase C - Slice 21）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/utils/*` 下 11 个 legacy re-export shim 文件（已全量切换到 `packages/core/src/shared/utils/*`）。
  - 删除 `packages/core/src/invokables/{types.ts,charBudget.ts}` 两个 legacy re-export shim 文件（已切换到 `packages/core/src/shared/invokables/*`）。
  - `scripts/layer-contract.config.json` 的 Types 映射移除 `packages/core/src/utils` 与 `packages/core/src/invokables` 过渡条目，仅保留 `packages/core/src/shared` 作为 canonical 类型/纯工具入口。
- 明确不做：
  - 不改任何 shared utils/shared invokables 的实现逻辑与对外函数语义。
  - 不改工具执行流程、UI 渲染逻辑或命令行为。

## 执行状态（Phase C - Slice 22）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/tools/presenters/*ApprovalPrompt.tsx` 中对 `./ConfirmMenu` 与 `./ApprovalHeader` 的依赖切换为直接引用 `packages/core/src/components/ui/{ConfirmMenu,ApprovalHeader}`。
  - 生产路径不再依赖这两个 wrapper 文件，降低 `tools/presenters` 与 UI 组件之间的中间层耦合。
- 明确不做：
  - 不改审批提示文案、键盘交互与 decision 映射语义。
  - 不删除现有 wrapper 文件（留待后续切片处理测试收敛）。

## 执行状态（Phase C - Slice 23）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/tools/modules/{webFetch,notebookEdit,task,exitPlanMode,skill,enterPlanMode,webSearch}/presenter.tsx` 中对 `../../presenters/fallback` 的依赖切换为直接引用 `packages/core/src/components/tool/FallbackToolPresenter`。
  - `packages/core/src/tools/modules/skill/presenter.interactions.test.tsx` 的 mock 目标同步到新路径。
- 明确不做：
  - 不改 fallback 渲染逻辑、surface suffix 规则和 tool summary 文案。
  - 不删除 `packages/core/src/tools/presenters/fallback.tsx` wrapper（留待后续切片统一收口）。

## 执行状态（Phase C - Slice 24）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/fallback.tsx`（已无生产调用方）。
  - `packages/core/src/tools/presenters/fallback.test.tsx` 改为直接验证 `packages/core/src/components/tool/FallbackToolPresenter`。
- 明确不做：
  - 不改 fallback 的渲染实现与行为，只移除中转 wrapper。
  - 不调整工具模块的 UI 展示文案和状态映射逻辑。

## 执行状态（Phase C - Slice 25）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/{ApprovalHeader,ConfirmMenu,MarkdownBlock}.tsx` 三个已无生产调用方的 wrapper。
  - `packages/core/src/tools/presenters/*` 与 `packages/core/src/components/ui/*` 相关测试改为直接引用 `packages/core/src/components/ui/*`。
  - 移除仅用于 wrapper 对齐的冗余基线断言，保留功能与交互断言。
  - `scripts/check-duplicate-presenters-parity.mjs` 清空已下线 wrapper 的对照项，消除已知结构下的长期假告警。
- 明确不做：
  - 不改 ConfirmMenu/ApprovalHeader/MarkdownBlock 的实现逻辑与交互语义。
  - 不改审批流程 decision 映射和 UI 文案。

## 执行状态（Phase C - Slice 26）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `CLAUDE.md` 的 Supporting Modules 索引从 `packages/core/src/utils/` 同步为 `packages/core/src/shared/utils/`，与当前目录事实一致。
- 明确不做：
  - 不改任何运行时逻辑与测试行为，仅修正文档索引路径。

## 执行状态（Phase C - Slice 27）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/types.ts`（已无代码调用方，shared 合同已是唯一实现）。
  - `CODEMAP.md`、`CLAUDE.md`、`plans/ui/formax-tool-ui-migration-test-prompt.md` 中的 blocks presenter helper 索引统一切换到 `packages/core/src/shared/toolPresenterContracts.ts`。
- 明确不做：
  - 不改 presenter contract 类型定义与运行时行为，仅删除中转 shim 并修正文档索引。

## 执行状态（Phase C - Slice 28）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `plans/ui/BACKLOG-approval-preview.md` 中 Approval 相关组件索引改为当前事实路径（`components/ui/ApprovalHeader`、`components/ui/MarkdownBlock`、`tools/presenters/ApprovalPreview`）。
- 明确不做：
  - 不改 Approval UI 任何实现，仅修正 backlog 文档路径。

## 执行状态（Phase C - Slice 29）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `ApprovalPreview` 实现迁移到 `packages/core/src/components/tool/ApprovalPreview.tsx`。
  - `packages/core/src/tools/modules/write/WriteApprovalToolBlock.tsx` 与对应测试改为直接依赖 `components/tool/ApprovalPreview`。
  - `packages/core/src/tools/presenters/ApprovalPreview.tsx` 降级为兼容 re-export，避免一次性影响剩余调用方/测试。
- 明确不做：
  - 不改 preview 样式、文案与 remaining lines 展示语义。
  - 不触发 `PatchApprovalPreview`/`PatchPreview` 的迁移（留后续切片）。

## 执行状态（Phase C - Slice 30）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `PatchPreview` 实现迁移到 `packages/core/src/components/tool/PatchPreview.tsx`。
  - `packages/core/src/tools/modules/edit/presenter.tsx` 与 `packages/core/src/tools/presenters/PatchApprovalPreview.tsx` 改为直接依赖 `components/tool/PatchPreview`。
  - `packages/core/src/tools/presenters/PatchPreview.tsx` 降级为兼容 re-export，避免一次性影响既有测试入口。
- 明确不做：
  - 不改 patch diff 计算、行号渲染与高亮规则语义。
  - 不调整 edit tool 的文案和审批行为。

## 执行状态（Phase C - Slice 31）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `PatchApprovalPreview` 实现迁移到 `packages/core/src/components/tool/PatchApprovalPreview.tsx`。
  - `packages/core/src/tools/modules/edit/EditApprovalToolBlock.tsx` 与对应测试改为直接依赖 `components/tool/PatchApprovalPreview`。
  - `packages/core/src/tools/presenters/PatchApprovalPreview.tsx` 降级为兼容 re-export，降低迁移风险。
- 明确不做：
  - 不改 patch approval 视觉样式与行号计算语义。
  - 暂不迁移 `useSnippetStartLineNumber`（当前通过兼容路径复用）。

## 执行状态（Phase C - Slice 32）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `snippetStartLine.ts` 与 `useSnippetStartLineNumber.ts` 实现迁移到 `packages/core/src/components/tool/`。
  - `packages/core/src/components/tool/PatchApprovalPreview.tsx` 改为直接依赖同层 hook/util，不再反向依赖 `tools/presenters`。
  - `packages/core/src/tools/presenters/{snippetStartLine,useSnippetStartLineNumber}.ts` 降级为兼容 re-export，保证现有测试入口稳定。
- 明确不做：
  - 不改 snippet 匹配算法与行号推断行为。
  - 不改 patch approval UI 渲染逻辑。

## 执行状态（Phase C - Slice 33）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `packages/core/src/features/repl/controller/streaming/patchStartLineNumber.ts` 改为直接依赖 `packages/core/src/components/tool/snippetStartLine.ts`，移除对 `tools/presenters` 的反向耦合。
  - `packages/core/src/features/repl/controller/streaming/patchStartLineNumber.test.ts` 的 spy 目标同步到新路径。
  - 删除 `packages/core/src/tools/presenters/snippetStartLine.ts` 兼容 shim；相关单测改为直接验证 `components/tool` 实现。
- 明确不做：
  - 不改 `computeEditPatchStartLineNumber` 的匹配策略与 fallback 顺序。
  - 不改 patch preview/approval 的 UI 渲染逻辑。

## 执行状态（Phase C - Slice 34）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/useSnippetStartLineNumber.ts` 兼容 shim（已无生产调用方）。
  - `packages/core/src/tools/presenters/useSnippetStartLineNumber.test.tsx` 改为直接验证 `packages/core/src/components/tool/useSnippetStartLineNumber.ts`。
- 明确不做：
  - 不改 hook 的异步读文件时序和错误兜底行为。
  - 不改 patch approval 的起始行推断语义。

## 执行状态（Phase C - Slice 35）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/ApprovalPreview.tsx` 兼容 shim（已无生产调用方）。
  - `packages/core/src/tools/presenters/ApprovalPreview.test.tsx` 改为直接验证 `packages/core/src/components/tool/ApprovalPreview.tsx`。
  - `plans/ui/BACKLOG-approval-preview.md` 的现状索引同步到组件层真实路径。
- 明确不做：
  - 不改 Approval preview 的布局、文案与 remaining lines 计算规则。
  - 不改 approval 流程和交互语义。

## 执行状态（Phase C - Slice 36）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/PatchPreview.tsx` 兼容 shim（已无生产调用方）。
  - `packages/core/src/tools/presenters/PatchPreview.test.tsx` 改为直接验证 `packages/core/src/components/tool/PatchPreview.tsx`。
- 明确不做：
  - 不改 patch diff 算法、行号显示策略与截断规则。
  - 不改 edit 审批流的 UI 文案与交互语义。

## 执行状态（Phase C - Slice 37）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/PatchApprovalPreview.tsx` 兼容 shim（已无生产调用方）。
  - `packages/core/src/tools/presenters/PatchApprovalPreview.test.tsx` 改为直接验证 `packages/core/src/components/tool/PatchApprovalPreview.tsx`。
- 明确不做：
  - 不改 patch approval 的路径解析、宽度回退与 snippet 行号推断逻辑。
  - 不改 edit 审批流程的 UI 文案与交互语义。

## 执行状态（Phase C - Slice 38）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `ToolUiPrimitives` 实现迁移到 `packages/core/src/components/tool/ToolUiPrimitives.tsx`。
  - `packages/core/src/tools/presenters/ToolUiPrimitives.tsx` 降级为兼容 re-export，保证现有调用方与 mock 路径稳定。
- 明确不做：
  - 不改 Tool header/subline/indent 的视觉渲染与 pulse 行为。
  - 不改 `ToolUiBlocks` 的 block 渲染顺序和语义。

## 执行状态（Phase C - Slice 39）

- 状态：进行中（目录迁移第一批，低风险）。
- 本轮已完成：
  - `LocalBashPresenter` 实现迁移到 `packages/core/src/components/tool/LocalBashPresenter.tsx`。
  - `packages/core/src/tools/presenters/LocalBashPresenter.tsx` 降级为兼容 re-export，避免一次性改动全部调用方。
  - `packages/core/src/legacy/bootstrap/tooling.ts` 与对应测试改为直接依赖 `components/tool/LocalBashPresenter`。
- 明确不做：
  - 不改 LocalBash 输出截断规则、状态渲染和 expanded 语义。
  - 不改 tooling 注册顺序与 runtime 初始化行为。

## 执行状态（Phase C - Slice 40）

- 状态：进行中（目录迁移第一批，低风险，批量路径收敛）。
- 本轮已完成：
  - 下列实现迁移到 `packages/core/src/components/tool/`：`AskUserQuestionToolBlock`、`BashApprovalToolBlock`、`FsReadApprovalToolBlock`、`bashApprovalPrompt`、`editApprovalPrompt`、`fsReadApprovalPrompt`、`fsWriteApprovalPrompt`、`skillApprovalPrompt`。
  - `packages/core/src/tools/presenters/` 同名文件降级为兼容 re-export，避免一次性修改全部测试入口。
  - `packages/core/src/tools/modules/*` 中对以上 presenter 的生产导入与测试 mock 路径统一切到 `components/tool/*`。
  - 文档索引（`CODEMAP.md`、`docs/inventories/interactive-input-inventory.md`、`plans/ui/formax-tool-ui-migration-test-prompt.md`）同步到新事实路径。
- 明确不做：
  - 不改 approval/ask 交互语义与 payload 映射。
  - 不改 ConfirmMenu/ApprovalHeader 视觉与键盘交互规则。

## 执行状态（Phase C - Slice 41）

- 状态：进行中（目录迁移第一批，低风险，批量 shim 清理）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/` 下以下兼容 shim：`AskUserQuestionToolBlock`、`BashApprovalToolBlock`、`FsReadApprovalToolBlock`、`bashApprovalPrompt`、`editApprovalPrompt`、`fsReadApprovalPrompt`、`fsWriteApprovalPrompt`、`skillApprovalPrompt`。
  - 对应 `packages/core/src/tools/presenters/*.test.tsx` 全部改为直接引用 `packages/core/src/components/tool/*`。
  - `docs/contracts/interactive-input-contract.md` 的 AskUserQuestion 关联路径更新到组件层事实路径。
- 明确不做：
  - 不改 approval/ask 交互行为、键位语义、decision payload。
  - 不改测试断言语义，仅更新导入目标与兼容层收口。

## 执行状态（Phase C - Slice 42）

- 状态：进行中（目录迁移第一批，低风险，剩余 shim 清理）。
- 本轮已完成：
  - 删除 `packages/core/src/tools/presenters/LocalBashPresenter.tsx` 与 `packages/core/src/tools/presenters/ToolUiPrimitives.tsx` 兼容 shim。
  - `packages/core/src/tools/modules/*` 中对 `ToolUiPrimitives` 的导入与相关测试 mock 路径统一切到 `packages/core/src/components/tool/ToolUiPrimitives`。
  - `packages/core/src/tools/presenters/{LocalBashPresenter,ToolUiPrimitives}.test.tsx` 改为直接验证 `packages/core/src/components/tool/*` 实现。
- 明确不做：
  - 不改 LocalBash 呈现逻辑（输出截断、expanded、error 状态）。
  - 不改 ToolUiPrimitives 的渲染与 pulse 行为。

## 执行状态（Phase C - Slice 43）

- 状态：进行中（目录迁移第一批，低风险，测试目录收口）。
- 本轮已完成：
  - 将 `packages/core/src/tools/presenters` 下剩余测试批量迁移到对应所有者目录：
    - tool 相关测试迁移至 `packages/core/src/components/tool/*`
    - ui 兼容测试迁移至 `packages/core/src/components/ui/*presenter-compat.test.tsx`
  - `packages/core/src/tools/presenters` 目录内测试清空（目录层面完成收口）。
  - `docs/contracts/interactive-input-contract.md` 的 approval prompt 测试路径同步更新至 `packages/core/src/components/tool/*approvalPrompt.test.tsx`。
- 明确不做：
  - 不改任何生产实现，仅做测试文件归位与导入路径修正。
  - 不删减既有断言语义，只修复迁移带来的路径/时序稳定性问题。

## 执行状态（Phase C - Slice 44）

- 状态：进行中（目录迁移第一批，低风险，文档与尾差清理）。
- 本轮已完成：
  - 删除空目录 `packages/core/src/tools/presenters/`（代码与测试已全部归位到 `components` 层）。
  - `CLAUDE.md` Tool System 索引从 `packages/core/src/tools/presenters/` 更新为 `packages/core/src/components/tool/`。
  - `docs/runbooks/runbook.md` 中 `check:presenter-parity` 排障说明改为基于 `PAIRS` 配置的当前事实流程。
  - UI 兼容测试标题文案从历史 `tools/presenters/*` 更新为组件层语义，降低误导。
- 明确不做：
  - 不改任何运行时代码路径，仅清理迁移后文档与测试元信息尾差。

## 执行状态（Phase C - Slice 45）

- 状态：进行中（目录迁移第一批，低风险，导入路径一致性）。
- 本轮已完成：
  - `packages/core/src/components/tool/*ApprovalPrompt*.tsx` 内对 UI 组件的导入由 `../../components/ui/*` 统一收敛为 `../ui/*`。
  - 对应 mapping/branches 测试中的 `vi.mock` 目标路径同步收敛到 `../ui/*`。
  - `packages/core/src/components/ui/ConfirmMenu.presenter-branches.test.tsx` 组件导入路径收敛为同目录相对导入。
- 明确不做：
  - 不改 approval prompt 交互逻辑，仅做导入路径规范化。
  - 不改任意测试断言语义。

## 执行状态（Phase C - Slice 46）

- 状态：进行中（目录迁移第一批，低风险，tool block 归位）。
- 本轮已完成：
  - 将 `WriteApprovalToolBlock`、`EditApprovalToolBlock`、`EditPlanFileBlock` 及对应测试从 `packages/core/src/tools/modules/{write,edit}/` 迁移到 `packages/core/src/components/tool/`。
  - `packages/core/src/tools/modules/{write,edit}/presenter.tsx` 切换为引用 `packages/core/src/components/tool/*` 的新位置实现。
  - 迁移后组件与测试的相对导入统一按 `components` 层内路径修正（`../ui/*`、`./*`、`../../shared/*`、`../../features/*`、`../../tools/runtime/*`）。
- 明确不做：
  - 不改 write/edit approval 的交互逻辑、decision payload 与文案。
  - 不改 write/edit presenter 的渲染策略，仅变更模块归属与导入路径。

## 执行状态（Phase C - Slice 47）

- 状态：进行中（目录迁移第一批，低风险，测试类型依赖收敛）。
- 本轮已完成：
  - `packages/core/src/tools/modules/*/presenter*.test.tsx` 中 `Msg` 类型导入由 `packages/core/src/components/tool/ToolMessage` 统一收敛为 `packages/core/src/shared/toolMessageTypes`。
  - 覆盖 ask/bash/edit/enterPlanMode/exitPlanMode/glob/grep/killShell/notebookEdit/read/search/skill/task/taskOutput/todoWrite/webFetch/webSearch/write 等模块测试，减少测试层对 UI 组件文件的反向类型耦合。
- 明确不做：
  - 不改任何 presenter 运行时代码与渲染行为。
  - 不改测试断言语义，仅做类型导入路径收敛。

## 执行状态（Phase C - Slice 48）

- 状态：进行中（目录迁移第一批，低风险，REPL 消息类型去 UI 依赖）。
- 本轮已完成：
  - `packages/core/src/features/repl/**` 与 `packages/core/src/screens/**` 中所有 `import type { Msg } from */components/tool/ToolMessage*` 统一切换为 `*/shared/toolMessageTypes*`。
  - 保留 `ToolMessage` 组件的运行时渲染导入路径不变，仅收敛类型来源，避免 Service/Runtime 层对 UI 组件路径产生类型耦合。
- 明确不做：
  - 不改任何消息投影、流式拼接、surface reset 或渲染分支逻辑。
  - 不改 `ToolMessage` 组件实现与展示行为。

## 执行状态（Phase C - Slice 49）

- 状态：进行中（目录迁移第一批，低风险，Config 目录启动）。
- 本轮已完成：
  - `packages/core/src/env/modelTier.ts` 与对应测试迁移到 `packages/core/src/config/modelTier.{ts,test.ts}`。
  - `packages/core/src/env/modelTier.ts` 保留兼容 re-export（桥接到 `packages/core/src/config/modelTier.js`），降低一次性迁移风险。
  - `features/commands`、`screens`、`tools/executor`、`ui/model` 的 `modelTier` 导入统一改为 `packages/core/src/config/modelTier`。
  - `scripts/layer-contract.config.json` 的 Config 层映射新增 `packages/core/src/config`。
- 明确不做：
  - 不改 model tier 解析、默认模型选择与 env 覆盖优先级语义。
  - 不改 REPL/TaskSubAgent 的业务流程，仅切换配置模块归属。

## 执行状态（Phase C - Slice 50）

- 状态：进行中（目录迁移第一批，低风险，Config 目录扩展）。
- 本轮已完成：
  - `packages/core/src/env/configPaths.ts` 与对应测试迁移到 `packages/core/src/config/configPaths.{ts,test.ts}`。
  - `packages/core/src/env/configPaths.ts` 保留兼容 re-export（桥接到 `packages/core/src/config/configPaths.js`）。
  - `features/commands/replDoctorService`、`core/diagnostics`、`core/config/show`、`cli/main` 等调用方导入统一改为 `packages/core/src/config/configPaths`。
- 明确不做：
  - 不改配置路径计算逻辑、默认目录约定与环境变量解析语义。
  - 不改 replDoctor 的诊断输出行为，仅调整模块归属与导入路径。

## 执行状态（Phase C - Slice 51）

- 状态：进行中（目录迁移第一批，低风险，Config 目录扩展）。
- 本轮已完成：
  - `packages/core/src/env/configFiles.ts` 迁移到 `packages/core/src/config/configFiles.ts`。
  - `packages/core/src/env/nodeFileStore.ts` 与测试迁移到 `packages/core/src/config/nodeFileStore.{ts,test.ts}`。
  - `packages/core/src/env/configFiles.ts` 与 `packages/core/src/env/nodeFileStore.ts` 保留兼容 re-export。
  - `packages/core/src/env/config.ts` 内部导入改为直接引用 `packages/core/src/config/{configFiles,nodeFileStore}`。
- 明确不做：
  - 不改 runtime config 的解析与合并行为，仅调整模块归属与导入路径。
  - 不改 node file store 的文件写入/原子写/权限容错语义。

## 执行状态（Phase C - Slice 52）

- 状态：进行中（目录迁移第一批，低风险，Config 目录扩展）。
- 本轮已完成：
  - `packages/core/src/env/runtimeFlags.ts` 与测试迁移到 `packages/core/src/config/runtimeFlags.{ts,test.ts}`。
  - `packages/core/src/env/runtimeFlags.ts` 保留兼容 re-export（桥接到 `packages/core/src/config/runtimeFlags.js`）。
  - `chat/engine`、`runtime/createRuntime`、`screens/REPL`、`features/repl`、`legacy/bootstrap` 的 `runtimeFlags` 导入统一切到 `packages/core/src/config/runtimeFlags`。
- 明确不做：
  - 不改 runtime flags 的解析规则与默认值，仅切换模块归属。
  - 不改 REPL/runtime 启动行为、chat engine 流程与 bash mode 逻辑。

## 执行状态（Phase C - Slice 53）

- 状态：进行中（目录迁移第一批，低风险，Config 目录扩展）。
- 本轮已完成：
  - `packages/core/src/env/config.ts` 与测试迁移到 `packages/core/src/config/config.{ts,test.ts}`。
  - `packages/core/src/env/config.ts` 保留兼容 re-export（桥接到 `packages/core/src/config/config.js`）。
  - `services/runtimeUiBridge`、`cli/main`、`screens/REPL`、`features/repl`、`legacy/bootstrap`、`tools/executor/taskSubAgent` 等调用方导入统一切到 `packages/core/src/config/config`。
  - `CODEMAP.md` 的 runtime config 入口更新到 `packages/core/src/config/config.ts`。
- 明确不做：
  - 不改 runtime config 解析/合并逻辑与默认值语义。
  - 不改 REPL/chat/taskSubAgent 的行为，仅调整配置模块归属与导入路径。

## 执行状态（Phase C - Slice 54）

- 状态：进行中（目录迁移第一批，低风险，Config 兼容层收口）。
- 本轮已完成：
  - 删除 `packages/core/src/env/{config,configFiles,configPaths,modelTier,nodeFileStore,runtimeFlags}.ts` 兼容 re-export 文件。
  - `scripts/layer-contract.config.json` 的 Config 层映射移除 `packages/core/src/env`，仅保留 `packages/core/src/config` 与 `packages/core/src/core/config`。
- 明确不做：
  - 不改任何配置加载行为与运行时逻辑，仅清理已无调用方的兼容层文件。
  - 不修改 `dotenv/config` 入口行为。

## 执行状态（Phase C - Slice 55）

- 状态：进行中（目录迁移第一批，低风险，core/config 向 config/settings 下沉）。
- 本轮已完成：
  - `packages/core/src/core/config/{schema.ts,schema.test.ts,fileStore.ts,paths.ts}` 迁移到 `packages/core/src/config/settings/`。
  - 在 `packages/core/src/core/config/{schema,fileStore,paths}.ts` 保留兼容 re-export，避免一次性改动所有调用方。
  - `CODEMAP.md` 的配置 schema 事实路径更新到 `packages/core/src/config/settings/schema.ts`。
- 明确不做：
  - 不改 config schema、file store、paths 的字段定义与行为逻辑，仅调整模块归属。
  - 不改 `core/config/resolve`、`persist`、`show`、`migrate` 的行为。

## 执行状态（Phase C - Slice 56）

- 状态：进行中（目录迁移第一批，低风险，core/config 向 config/settings 下沉）。
- 本轮已完成：
  - `packages/core/src/core/config/{configFiles,resolve,persist,migrate,show}.{ts,test.ts}` 迁移到 `packages/core/src/config/settings/`。
  - `packages/core/src/core/config/{configFiles,resolve,persist,migrate,show}.ts` 保留兼容 re-export，避免一次性修改所有调用方。
  - `CODEMAP.md` 的 config resolve 事实路径更新到 `packages/core/src/config/settings/resolve.ts`。
- 明确不做：
  - 不改配置解析/持久化/迁移/展示逻辑，仅变更模块归属与导入层次。
  - 不改 `cli`、`features/commands`、`config loader` 的行为。

## 执行状态（Phase C - Slice 57）

- 状态：进行中（目录迁移第一批，低风险，core/config shim 清理）。
- 本轮已完成：
  - 业务代码导入从 `packages/core/src/core/config/*` 统一收敛到 `packages/core/src/config/settings/*`。
  - 删除 `packages/core/src/core/config/{schema,fileStore,paths,configFiles,resolve,persist,migrate,show}.ts` shim 文件（已无调用方）。
  - `scripts/layer-contract.config.json` 的 Config 层映射移除 `packages/core/src/core/config`，仅保留 `packages/core/src/config`。
  - `docs/environment-variables.md` 的 resolve 事实路径更新到 `packages/core/src/config/settings/resolve.ts`。
- 明确不做：
  - 不改配置解析/迁移/持久化行为，仅做路径收敛与 shim 收口。
  - 不改 CLI/REPL/setup 的用户可见语义。

## 执行状态（Phase C - Slice 58）

- 状态：进行中（目录迁移第一批，低风险，文档路径对齐）。
- 本轮已完成：
  - `AGENTS.md` 与 `CLAUDE.md` 中 runtime config / config merge 的事实路径更新为 `packages/core/src/config/{config.ts,settings/*}`。
- 明确不做：
  - 不改任何运行时代码，仅同步文档路径，避免后续排障误导。

## 执行状态（Phase C - Slice 59）

- 状态：进行中（目录迁移第二批，Runtime 合并线启动，低风险切片）。
- 本轮已完成：
  - `packages/core/src/cli/exitCodes.ts` 迁移到 `packages/core/src/runtime/cli/exitCodes.ts`。
  - `packages/core/src/cli/exitCodes.ts` 保留兼容 re-export（桥接到 `packages/core/src/runtime/cli/exitCodes.js`）。
- 明确不做：
  - 不改 CLI 参数解析/帮助文本/命令分发逻辑，仅迁移独立常量模块路径。

## 执行状态（Phase C - Slice 60）

- 状态：进行中（目录迁移第二批，Runtime 合并线，低风险切片）。
- 本轮已完成：
  - `packages/core/src/cli/{args,help,json}.ts` 迁移到 `packages/core/src/runtime/cli/{args,help,json}.ts`。
  - `packages/core/src/cli/{args,help,json}.ts` 保留兼容 re-export（桥接到 `packages/core/src/runtime/cli/*`）。
  - `packages/core/src/cli/main.ts` 与 `packages/core/src/entrypoints/cli.tsx` 改为直接导入 `packages/core/src/runtime/cli/*`，减少 shim 跳转层。
- 明确不做：
  - 不改参数解析规则、help 文案、JSON envelope 结构，仅迁移模块归属路径。

## 执行状态（Phase C - Slice 61）

- 状态：进行中（目录迁移第二批，Runtime 合并线，低风险切片）。
- 本轮已完成：
  - `packages/core/src/cli/main.ts` 迁移到 `packages/core/src/runtime/cli/main.ts`。
  - `packages/core/src/cli/main.ts` 保留兼容 re-export（桥接到 `packages/core/src/runtime/cli/main.js`）。
  - `packages/core/src/entrypoints/cli.tsx` 改为直接导入 `packages/core/src/runtime/cli/main.ts`。
- 明确不做：
  - 不改 CLI 命令分发逻辑、返回结构、错误处理分支，仅迁移模块归属路径。

## 执行状态（Phase C - Slice 62）

- 状态：进行中（目录迁移第二批，Runtime 合并线，低风险切片）。
- 本轮已完成：
  - `packages/core/src/cli/{args,help,main}.test.ts` 迁移到 `packages/core/src/runtime/cli/{args,help,main}.test.ts`。
  - 迁移后测试内相对导入已对齐 `packages/core/src/runtime/cli` 目录层级。
- 明确不做：
  - 不改测试断言与用例语义，仅调整测试文件归属与导入路径。

## 执行状态（Phase C - Slice 63）

- 状态：进行中（目录迁移第二批，Runtime 合并线，shim 收口切片）。
- 本轮已完成：
  - 删除 `packages/core/src/cli/{args,help,json,main,exitCodes}.ts` 兼容 shim，彻底收口到 `packages/core/src/runtime/cli/*`。
  - `packages/core/src/cli/binWrapper.test.ts` 迁移到 `packages/core/src/runtime/cli/binWrapper.test.ts`，并修正仓库根路径计算。
  - `README.md`、`CODEMAP.md`、`CLAUDE.md` 的 CLI 事实路径更新为 `packages/core/src/runtime/cli/*`。
- 明确不做：
  - 不改任何 CLI 行为、命令语义与输出格式，仅做路径收口与文档同步。

## 执行状态（Phase C - Slice 64）

- 状态：进行中（目录迁移第二批，Runtime 合并线，命令解析器收拢）。
- 本轮已完成：
  - `packages/core/src/serve/command.{ts,test.ts}` 迁移到 `packages/core/src/runtime/cli/serveCommand.{ts,test.ts}`。
  - `packages/core/src/web/command.{ts,test.ts}` 迁移到 `packages/core/src/runtime/cli/webCommand.{ts,test.ts}`。
  - `packages/core/src/runtime/cli/main.ts` 改为直接导入 `./serveCommand` 与 `./webCommand`。
  - `packages/core/src/serve/command.ts` 与 `packages/core/src/web/command.ts` 保留兼容 re-export shim。
  - `CODEMAP.md` 的 serve/web command 事实路径同步到 `packages/core/src/runtime/cli/*`。
- 明确不做：
  - 不改 `serve/web` 参数语义、默认值、help 文案与错误消息，仅迁移模块归属与导入路径。

## 执行状态（Phase C - Slice 65）

- 状态：进行中（目录迁移第二批，Runtime 合并线，shim 收口）。
- 本轮已完成：
  - 删除 `packages/core/src/serve/command.ts` 与 `packages/core/src/web/command.ts` 兼容 shim。
  - `serve/web` 命令解析唯一事实源已收敛到 `packages/core/src/runtime/cli/{serveCommand,webCommand}.ts`。
- 明确不做：
  - 不改 `formax serve` / `formax web` 的参数行为与 help 文案，仅收口路径层兼容文件。

## 执行状态（Phase C - Slice 66）

- 状态：进行中（目录迁移第二批，Runtime 合并线，network/serve/web 归拢）。
- 本轮已完成：
  - `packages/core/src/network/runtime.{ts,test.ts}` 迁移到 `packages/core/src/runtime/network/runtime.{ts,test.ts}`。
  - `packages/core/src/serve/localServer.ts` 迁移到 `packages/core/src/runtime/serve/localServer.ts`。
  - `packages/core/src/web/localUi.ts` 迁移到 `packages/core/src/runtime/web/localUi.ts`。
  - `packages/core/src/entrypoints/cli.tsx`、`packages/core/src/app-server/devBridge.ts`、`packages/core/src/runtime/cli/{serveCommand,webCommand}.ts` 等调用方改为直连 `packages/core/src/runtime/*`。
  - 旧路径保留最薄 shim：`packages/core/src/network/runtime.ts`、`packages/core/src/serve/localServer.ts`、`packages/core/src/web/localUi.ts`。
  - `CODEMAP.md` 与 `CLAUDE.md` 的相关事实路径同步到 `packages/core/src/runtime/{network,serve,web}`。
- 明确不做：
  - 不改 serve/web/network 运行逻辑、参数语义与对外行为，仅迁移模块归属与导入路径。

## 执行状态（Phase C - Slice 67）

- 状态：进行中（目录迁移第二批，Runtime 合并线，shim 收口）。
- 本轮已完成：
  - 删除 `packages/core/src/network/runtime.ts`、`packages/core/src/serve/localServer.ts`、`packages/core/src/web/localUi.ts` 兼容 shim。
  - `scripts/layer-contract.config.json` 的 Runtime 映射移除 `packages/core/src/cli`、`packages/core/src/network`、`packages/core/src/serve`、`packages/core/src/web` 陈旧路径，仅保留现状入口。
- 明确不做：
  - 不改 runtime 行为与启动参数语义，仅删除无调用 shim 并同步门禁映射。

## 执行状态（Phase C - Slice 68）

- 状态：进行中（目录迁移第二批，Runtime 合并线，bootstrap 归拢）。
- 本轮已完成：
  - `packages/core/src/legacy/bootstrap/*`（源码 + 测试）迁移到 `packages/core/src/runtime/bootstrap/*`。
  - `packages/core/src/runtime/createRuntime.{ts,test.ts}` 与 `packages/core/src/legacy/runLegacyCli.tsx` 改为直接导入 `packages/core/src/runtime/bootstrap/*`。
  - `packages/core/src/legacy/bootstrap/*` 保留兼容 shim（桥接到 `packages/core/src/runtime/bootstrap/*`），避免一次性改动潜在外部引用。
  - `CODEMAP.md` 的 runtime assembly slices 事实路径更新到 `packages/core/src/runtime/bootstrap/*`。
- 明确不做：
  - 不改 REPL 启动逻辑、setup 流程与 runtime 组装行为，仅迁移模块归属与导入路径。

## 执行状态（Phase C - Slice 69）

- 状态：进行中（目录迁移第二批，Runtime 合并线，shim 收口）。
- 本轮已完成：
  - 删除 `packages/core/src/legacy/bootstrap/*` 兼容 shim，`bootstrap` 唯一事实源收敛到 `packages/core/src/runtime/bootstrap/*`。
  - `scripts/layer-contract.config.json` 的 Runtime 映射移除 `packages/core/src/legacy/bootstrap` 陈旧路径，仅保留 `packages/core/src/legacy/runLegacyCli.tsx`。
- 明确不做：
  - 不改 `runLegacyCli` 与 runtime 组装行为，仅删除无调用 shim 并同步门禁映射。

## 执行状态（Phase C - Slice 70）

- 状态：进行中（目录迁移第二批，Runtime 合并线，legacy 入口归拢）。
- 本轮已完成：
  - `packages/core/src/legacy/runLegacyCli.{tsx,test.tsx}` 迁移到 `packages/core/src/runtime/bootstrap/runLegacyCli.{tsx,test.tsx}`。
  - `packages/core/src/entrypoints/cli.tsx` 改为直接导入 `packages/core/src/runtime/bootstrap/runLegacyCli`。
  - `packages/core/src/legacy/runLegacyCli.tsx` 保留兼容 shim（桥接到 `packages/core/src/runtime/bootstrap/runLegacyCli.js`）。
  - `CODEMAP.md`、`CLAUDE.md` 的 runLegacyCli 事实路径同步为 `packages/core/src/runtime/bootstrap/runLegacyCli.tsx`。
- 明确不做：
  - 不改 REPL 启动行为与错误处理语义，仅迁移入口模块归属与导入路径。

## 执行状态（Phase C - Slice 71）

- 状态：进行中（目录迁移第二批，Runtime 合并线，legacy 收口）。
- 本轮已完成：
  - 删除 `packages/core/src/legacy/runLegacyCli.tsx` 兼容 shim。
  - 删除空目录 `packages/core/src/legacy/`。
  - `scripts/layer-contract.config.json` 的 Runtime 映射移除 `packages/core/src/legacy/runLegacyCli.tsx` 陈旧路径。
- 明确不做：
  - 不改 REPL 启动行为，仅删除无调用兼容层并同步门禁映射。

## 执行状态（Phase C - Slice 72）

- 状态：进行中（目录迁移第二批，文档路径一致性收口）。
- 本轮已完成：
  - `AGENTS.md` 的项目结构说明从 `packages/core/src/cli`/`packages/core/src/legacy` 更新为 `packages/core/src/runtime/cli`/`packages/core/src/runtime/bootstrap`。
  - `packages/core/src/core/README.md` 的上层调用路径从 `packages/core/src/legacy` 更新为 `packages/core/src/runtime/bootstrap`。
- 明确不做：
  - 不改任何运行时代码与行为，仅同步文档事实路径。

## 执行状态（Phase C - Slice 73）

- 状态：进行中（目录迁移第二批，TUI 目录重命名收口）。
- 本轮已完成：
  - `packages/core/src/ui/**` 迁移为 `packages/core/src/tui/**`，并同步核心调用方导入：
    - `packages/core/src/screens/REPL.tsx`
    - `packages/core/src/features/repl/useReplController.ts`
    - `packages/core/src/features/repl/controller/ui/overlays.ts`
    - `packages/core/src/features/repl/controller/session/localCommandInjection.ts`
    - `packages/core/src/services/runtimeUiBridge.tsx`
  - 对应测试 mock 路径切换为 `packages/core/src/tui/**`（`packages/core/src/screens/REPL.coverage.test.tsx`、`packages/core/src/services/runtimeUiBridge.test.tsx`）。
  - 门禁脚本同步：
    - `scripts/check-ui-boundaries.mjs` 扫描根切换为 `packages/core/src/tui`
    - `scripts/check-core-boundaries.mjs` 禁止依赖目标切换为 `packages/core/src/tui/**`（并兼容拦截 legacy `packages/core/src/ui/**` 字符串）
    - `scripts/layer-contract.config.json` Service 映射改为 `packages/core/src/tui`
  - 文档路径事实同步：
    - `AGENTS.md`、`CLAUDE.md`、`CODEMAP.md`、`packages/core/src/hooks/README.md`
- 明确不做：
  - 不改任何 overlay 行为与 UI 交互语义，仅迁移目录归属并收敛边界门禁。

## 执行状态（Phase C - Slice 74）

- 状态：进行中（目录迁移第二批，技能与辅助计划文档路径收口）。
- 本轮已完成：
  - `.codex/skills/formax-config-settings-workflow/SKILL.md` 中 ConfigDialog 路径与测试命令统一到 `packages/core/src/tui/config/*`。
  - `.codex/skills/formax-permissions-workflow/SKILL.md` 中 PermissionsDialog 路径与测试命令统一到 `packages/core/src/tui/permissions/*`。
  - `AGENTS.md` 的项目结构说明由 `ui/` 更新为 `tui/`。
  - `plans/config-settings/TODO.md` 与 `plans/hooks/TODO.md` 中的 `packages/core/src/ui/*` 历史路径更新为 `packages/core/src/tui/*`。
- 明确不做：
  - 不改任何运行时代码、边界规则或 UI 行为，仅收敛文档与技能指引路径事实。

## 执行状态（Phase C - Slice 75）

- 状态：进行中（目录迁移第二批，TUI 公共工具入口收口）。
- 本轮已完成：
  - 新增 `packages/core/src/tui/{theme,toolFormatting,consoleLogger,inkStreams}.ts` 四个稳定入口（当前转发到 `packages/core/src/shared/utils/*` 实现）。
  - 全仓 UI/Presenter/REPL 相关导入切换到 `packages/core/src/tui/*` 入口：
    - 主题：`theme`
    - 工具文案格式化：`toolFormatting`
    - 浏览器日志桥：`consoleLogger`
    - Ink stdout 安全适配：`inkStreams`
  - `Repo` 层文件 `packages/core/src/features/repl/sessionSave/reader.ts` 保持依赖 `shared/utils/toolFormatting`，避免跨层违规。
  - 相关门禁通过：`check:layer-contracts`、`check:layer-coverage`、`check:shared-types`。
- 明确不做：
  - 不搬动 `packages/core/src/shared/utils/*` 实现文件本体，仅先收敛调用入口，后续再按层策略决定是否迁实现。

## 执行状态（Phase C - Slice 76）

- 状态：进行中（目录迁移第二批，死 shim / dead barrel 清理）。
- 本轮已完成：
  - 删除无调用 shim：`packages/core/src/runtime/bootstrap/renderReplApp.tsx`。
  - `packages/core/src/runtime/bootstrap/runLegacyCli.tsx` 改为直接依赖 `packages/core/src/services/runtimeUiBridge` 的 `renderLegacyReplApp`。
  - `packages/core/src/runtime/bootstrap/runLegacyCli.test.tsx` 的 mock 目标同步到 `packages/core/src/services/runtimeUiBridge.js`。
  - 删除无调用 shim：`packages/core/src/tools/utils/paths.ts`。
  - 删除无调用 barrel：`packages/core/src/tui/config/index.tsx`、`packages/core/src/tui/hooks/index.ts`。
  - 验证通过：`runLegacyCli.test.tsx`、`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不改 runtime 启动行为，不改路径解析逻辑实现，仅去除中间桥接层。

## 执行状态（Phase C - Slice 77）

- 状态：进行中（目录迁移第二批，TUI 工具实现实迁）。
- 本轮已完成：
  - `packages/core/src/shared/utils/theme.ts` 实现迁移到 `packages/core/src/tui/theme.ts`。
  - `packages/core/src/shared/utils/consoleLogger.ts` 实现迁移到 `packages/core/src/tui/consoleLogger.ts`。
  - `packages/core/src/shared/utils/inkStreams.ts` 实现迁移到 `packages/core/src/tui/inkStreams.ts`。
  - `packages/core/src/shared/utils/consoleLogger.test.ts` 迁移到 `packages/core/src/tui/consoleLogger.test.ts`。
  - `packages/core/src/shared/utils/inkStreams.test.ts` 迁移到 `packages/core/src/tui/inkStreams.test.ts`。
  - 删除 `packages/core/src/shared/utils/` 下上述已迁实现文件，避免双事实源。
  - 验证通过：`tui/inkStreams.test.ts`、`runLegacyCli.test.tsx`、`runtimeUiBridge.test.tsx`、`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 暂不迁移 `shared/utils/toolFormatting.ts`（`Repo` 层仍有合法依赖），避免引入跨层违规。

## 执行状态（Phase C - Slice 78）

- 状态：进行中（目录迁移第二批，脚本路径收口）。
- 本轮已完成：
  - `scripts/surface-screen-model-smoke.tsx` 对 `inkStreams` 的导入从 `packages/core/src/shared/utils/inkStreams` 切换到 `packages/core/src/tui/inkStreams`。
  - 全仓复扫 `shared/utils/inkStreams` 残留引用，确认仅该脚本存在旧路径依赖并已收敛。
  - 验证通过：`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不调整 smoke 脚本行为逻辑，仅做路径事实修正。

## 执行状态（Phase C - Slice 79）

- 状态：进行中（目录迁移第二批，UI 常量归位）。
- 本轮已完成：
  - 新增 `packages/core/src/components/tool/toolUi.ts`，承接 Tool transcript subline 的 UI 常量定义。
  - `packages/core/src/components/tool/ToolUiPrimitives.tsx` 与 `packages/core/src/components/tool/ToolSubline.tsx` 改为本地依赖 `./toolUi`。
  - 删除 `packages/core/src/shared/utils/toolUi.ts`，避免 UI 常量继续滞留在 shared/utils。
  - 验证通过：`ToolSubline.test.tsx`、`ToolUiPrimitives.test.tsx`、`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不调整任何 subline 文案、缩进或渲染行为，仅收敛文件归属与导入路径。

## 执行状态（Phase C - Slice 80）

- 状态：进行中（目录迁移第二批，dead code 收敛）。
- 本轮已完成：
  - 删除无调用文件 `packages/core/src/shared/utils/config.ts`。
  - 全仓复扫 `ModelProfile`/`GlobalConfig` 等导出符号，确认无任何业务依赖。
  - 验证通过：`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不改任何配置读写逻辑；仅移除未接入代码路径。

## 执行状态（Phase C - Slice 81）

- 状态：进行中（目录迁移第二批，Presenter 错误摘要工具归位）。
- 本轮已完成：
  - `pickCompactErrorDetailLine` 从 `packages/core/src/shared/utils/toolErrorUi.ts` 迁移到 `packages/core/src/tools/utils/toolErrorUi.ts`。
  - 对应测试迁移到 `packages/core/src/tools/utils/toolErrorUi.test.ts`。
  - 更新调用方导入：
    - `packages/core/src/components/tool/{FallbackToolPresenter,ToolMessage}.tsx`
    - `packages/core/src/tools/modules/{bash,glob,grep,read,write}/presenter.tsx`
  - 删除 `packages/core/src/shared/utils/toolErrorUi.{ts,test.ts}`，避免 shared 承担 Presenter 专用工具职责。
- 明确不做：
  - 不修改错误摘要筛选规则（pattern 集合与返回策略保持不变），仅调整文件归属与导入路径。

## 执行状态（Phase C - Slice 82）

- 状态：进行中（目录迁移第二批，dead util 收敛）。
- 本轮已完成：
  - 删除无调用文件 `packages/core/src/tools/utils/globPattern.ts`。
  - 全仓复扫 `globPatternToRegex` 符号，确认无任何调用方。
  - 验证通过：`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不改任何 glob 工具行为；仅移除未接入路径。

## 执行状态（Phase C - Slice 83）

- 状态：进行中（目录迁移第二批，门禁路径对齐）。
- 本轮已完成：
  - `scripts/check-core-boundaries.mjs` 中 commands/skills 扫描根从旧路径 `packages/core/src/{commands,skills}` 切换为 `packages/core/src/features/{commands,skills}`。
  - 移除脚本内对 `packages/core/src/ui` 目录常量的相对路径判定分支，保持与当前 `packages/core/src/tui` 目录事实一致。
  - 保留对非相对导入字符串 `packages/core/src/ui/` 的兜底拦截，避免 legacy 路径回流。
- 明确不做：
  - 本轮不调整 core 包依赖白名单与 core→config 依赖规则，仅做目录路径事实对齐。

## 执行状态（Phase C - Slice 84）

- 状态：进行中（目录迁移第二批，core 门禁规则对齐）。
- 本轮已完成：
  - `scripts/check-core-boundaries.mjs` 增加 `packages/core/src/config/**` 作为 core 合法依赖目标，匹配现有 `core/* -> config/settings/*` 的真实依赖。
  - 更新 core 外部依赖允许集，显式允许 `@anthropic-ai/sdk` 与 `openai`（对应 `packages/core/src/core/models/models.ts` 的既有实现）。
  - 保留对 `ink` 的禁止依赖约束，维持 core 无 UI 依赖。
  - 验证通过：`core:boundaries`、`ui:boundaries`、`features:boundaries`。
- 明确不做：
  - 不修改任何业务实现或模型拉取逻辑，仅修正规则与当前代码事实不一致的问题。

## 执行状态（Phase C - Slice 85）

- 状态：进行中（目录迁移第二批，边界文档同步）。
- 本轮已完成：
  - 同步 `CLAUDE.md` 中的 core 边界描述，改为与当前门禁脚本一致：
    - 允许 `core -> config/adapters`
    - 继续禁止 `core -> tui/screens/tools/modules` 等 UI/runtime 方向依赖。
  - 保持 `bun run core:boundaries` 作为唯一判定标准，避免文档与脚本出现双事实源。
- 明确不做：
  - 不调整任何代码导入或边界脚本逻辑，仅同步文档契约表述。

## 执行状态（Phase C - Slice 86）

- 状态：进行中（目录迁移第二批，controller/ui 入口收口）。
- 本轮已完成：
  - `packages/core/src/features/repl/controller/ui/ui.ts` 重命名为目录入口 `packages/core/src/features/repl/controller/ui/index.ts`。
  - 外部调用方导入收敛为目录导入：
    - `packages/core/src/features/repl/useReplController.ts`
    - `packages/core/src/screens/REPL.tsx`
  - 验证通过：`useReplController.test.tsx`、`REPL.overlays.test.tsx`、`REPL.test.tsx`、`features:boundaries`、`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不改 `messages/overlays/surfaceReset` 的实现逻辑，仅收敛入口文件命名与导入路径。

## 执行状态（Phase C - Slice 87）

- 状态：进行中（目录迁移第二批，controller barrel 统一）。
- 本轮已完成：
  - `packages/core/src/features/repl/controller/{canonical,session,shared}` 的 barrel 统一为目录入口 `index.ts`：
    - `canonical/canonical.ts -> canonical/index.ts`
    - `session/session.ts -> session/index.ts`
    - `shared/shared.ts -> shared/index.ts`
  - 同步外部导入到目录入口：
    - `packages/core/src/features/repl/useReplController.ts`
    - `packages/core/src/screens/REPL.tsx`
    - `packages/core/src/features/repl/controller/send/sendOrchestration.ts`
  - 验证通过：`useReplController.test.tsx`、`REPL.overlays.test.tsx`、`REPL.test.tsx`、`features:boundaries`、`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不改任何 canonical/session/shared 子模块实现，仅统一入口命名与路径。

## 执行状态（Phase C - Slice 88）

- 状态：进行中（目录迁移第二批，semantics barrel 收口）。
- 本轮已完成：
  - `packages/core/src/features/semantics/core/core.ts` 重命名为 `packages/core/src/features/semantics/core/index.ts`。
  - `packages/core/src/features/semantics/projection/projection.ts` 重命名为 `packages/core/src/features/semantics/projection/index.ts`。
  - 相关调用方导入改为目录入口：
    - `packages/core/src/features/repl/useReplController.ts`
    - `packages/core/src/features/repl/controller/canonical/canonicalEventOrchestration.ts`
    - `packages/core/src/features/repl/controller/canonical/canonicalEventOrchestration.test.ts`
    - `packages/core/src/features/repl/controller/canonical/canonicalInvariants.ts`
  - 验证通过：`canonicalEventOrchestration.test.ts`、`useReplController.test.tsx`、`REPL.test.tsx`、`features:boundaries`、`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不调整 semantics 规则实现，仅统一 barrel 入口命名与导入路径。

## 执行状态（Phase C - Slice 89）

- 状态：进行中（目录迁移第二批，semantics 入口命名补齐）。
- 本轮已完成：
  - `packages/core/src/features/semantics/adapters/adapters.ts` 重命名为 `packages/core/src/features/semantics/adapters/index.ts`。
  - `packages/core/src/features/semantics/runtime/runtime.ts` 重命名为 `packages/core/src/features/semantics/runtime/index.ts`。
  - 验证通过：`runtimeReplayParity.test.ts`、`turnInputBuilder.contract.test.ts`、`features:boundaries`、`check:layer-contracts`、`check:layer-coverage`。
- 明确不做：
  - 不改 adapters/runtime 子模块实现与导出内容，仅统一入口文件命名。

## 执行状态（Phase C - Slice 90）

- 状态：进行中（feature 收敛，subagents 归位）。
- 本轮已完成：
  - `packages/core/src/subagents/**` 迁移到 `packages/core/src/features/subagents/**`（包含 `registry` / `runner` / `builtins` / `agentsWizard` / `types` 与 `prompts/`）。
  - `runtime/bootstrap`、`tools/executor/handlers/taskSubAgent`、`features/repl/controller/ui/overlays` 的生产导入切换到 `packages/core/src/features/subagents/*`。
  - `layer-contract.config.json` 增补 `packages/core/src/features/subagents` 映射，并将 `packages/core/src/features/subagents/types.ts` 标注到 Types 层。
  - `AGENTS.md`、`CLAUDE.md`、`CODEMAP.md`、`packages/core/src/tools/README.md` 的 subagents 事实路径更新到 `packages/core/src/features/subagents/*`。
- 明确不做：
  - 不改 subagent 运行逻辑、allow/deny 语义与 prompt 内容，仅做目录归位与导入路径收敛。

## 执行状态（Phase C - Slice 91）

- 状态：进行中（feature 收敛，subagents shim 硬收口）。
- 本轮已完成：
  - 删除 `packages/core/src/subagents/*` 全部兼容 shim（`README` / `registry` / `runner` / `builtins` / `agentsWizard` / `types`）。
  - `layer-contract.config.json` Service 映射移除 `packages/core/src/subagents`，仅保留 `packages/core/src/features/subagents`。
- 明确不做：
  - 不改任何 subagent 业务行为，仅删除已无调用兼容层并同步门禁映射。

## 目标结构

```
packages/core/src/
│
│  ════════════════════ Types 层 ════════════════════
│
├── shared/                          # 跨层类型、纯工具、合同
│   ├── frontmatter.ts
│   ├── inputContracts.ts
│   ├── toolContracts.ts
│   ├── toolMessageTypes.ts
│   ├── runtimeEventSource.ts
│   ├── invokables/                  # ← 合并原 packages/core/src/invokables
│   │   ├── types.ts
│   │   └── charBudget.ts
│   └── utils/                       # ← 合并原 packages/core/src/utils（纯函数）
│       ├── paths.ts
│       └── catN.ts
│
│  ════════════════════ Config 层 ════════════════════
│
├── config/                          # ← 合并原 packages/core/src/env + packages/core/src/core/config
│   ├── config.ts                    #   (原 env/config.ts)
│   ├── configFiles.ts               #   (原 env/configFiles.ts)
│   ├── configPaths.ts               #   (原 env/configPaths.ts)
│   ├── modelTier.ts                 #   (原 env/modelTier.ts)
│   ├── nodeFileStore.ts             #   (原 env/nodeFileStore.ts)
│   ├── runtimeFlags.ts              #   (原 env/runtimeFlags.ts)
│   └── settings/                    #   (原 core/config)
│       ├── engine.ts
│       ├── schema.ts
│       ├── store.ts
│       └── types.ts
│
│  ════════════════════ Repo 层 ════════════════════
│
├── adapters/                        # 持久化与外部 IO（不变）
│   ├── fs/
│   ├── permissions/
│   ├── audit/
│   ├── diagnostics/
│   └── setup/
│
│  ════════════════════ Service 层 ════════════════════
│
├── core/                            # 领域无关的 Service 基础设施
│   ├── app/                         #   createApp, eventBus
│   ├── approval/                    #   approval rules
│   ├── auth/                        #   认证
│   ├── audit/                       #   audit schema（纯 schema，不是 IO）
│   ├── diagnostics/                 #   doctor, debugBundle, status
│   ├── errors/                      #   error codes
│   ├── models/                      # ← 合并原 packages/core/src/services/{models,modelContextCatalog}
│   │   ├── models.ts
│   │   └── modelContextCatalog.ts
│   ├── policy/                      #   policy engine
│   └── setup/                       #   session setup
│
├── chat/                            # LLM 引擎（不变）
│   ├── engine.ts
│   └── context/
│
├── streaming/                       # 流处理（不变）
│   ├── types.ts                     #   (同时归属 Types 层)
│   ├── index.ts
│   ├── anthropic/
│   └── openai/
│
├── prompts/                         # Prompt 构建（不变）
│   ├── types.ts                     #   (同时归属 Types 层)
│   ├── system.ts
│   ├── init.ts
│   ├── compact.ts
│   └── reminders/
│
├── hooks/                           # Hook 系统（不变）
│
├── tools/                           # 工具系统（Service 部分）
│   ├── modules/
│   ├── executor/
│   ├── catalog/
│   ├── specs/
│   ├── runtime/
│   ├── utils/
│   ├── patches/
│   ├── registry.ts
│   ├── loader.ts
│   └── types.ts
│   # ⚠️ presenters/ 移出 → 见 UI 层
│
├── features/
│   ├── semantics/                   # 语义核心（不变）
│   │   ├── core/                    #   (Types 层)
│   │   ├── adapters/                #   (Service 层)
│   │   ├── projection/              #   (Service 层)
│   │   ├── runtime/                 #   (Service 层)
│   │   ├── selectors/               #   (Service 层)
│   │   └── __tests__/
│   │
│   ├── repl/                        # REPL 领域
│   │   ├── controller/              #   [Service]
│   │   ├── sessionSave/             #   [Repo]
│   │   ├── mode.ts                  #   [Service]
│   │   ├── planSession.ts           #   [Service]
│   │   ├── injectedBlocks.ts        #   [Service]
│   │   ├── reminders/               #   [Service]
│   │   ├── useReplController.ts     #   [Service] 主控 hook
│   │   ├── useInputAudit.test.ts    #   [Service]
│   │   ├── keys/                    #   [UI]
│   │   ├── overlays/                #   [UI]
│   │   ├── inputScopeContext.tsx     #   [UI]
│   │   ├── replUiContext.tsx         #   [UI]
│   │   └── planContext.tsx           #   [UI]
│   │
│   ├── commands/                    # ← 合并原 packages/core/src/commands + packages/core/src/features/commands
│   │   ├── CommandStore.ts          #   [Repo]
│   │   ├── registry.ts              #   [Service]
│   │   ├── adapter.ts               #   [Service]
│   │   ├── configDialogService.ts   #   [Service]
│   │   ├── permissionsDialogService.ts
│   │   ├── replDoctorService.ts     #   [Service]
│   │   ├── replEnvironmentService.ts
│   │   ├── resumeDialogService.ts   #   [Service]
│   │   ├── contracts.ts             #   [Service]
│   │   └── render.ts               #   [UI]
│   │
│   ├── sessionTitle/                # 会话标题生成（不变）
│   │
│   ├── skills/                      # ← 移入 features（原 packages/core/src/skills）
│       ├── SkillStore.ts            #   [Repo]
│       └── SkillStore.test.ts
│
│   └── subagents/                   # ← 移入 features（原 packages/core/src/subagents）
│       ├── builtins.ts              #   [Service]
│       ├── registry.ts              #   [Service]
│       ├── runner.ts                #   [Service]
│       ├── agentsWizard.ts          #   [Service]
│       ├── types.ts                 #   [Types]
│       └── prompts/                 #   [Service]
│
│  ════════════════════ Runtime 层 ════════════════════
│
├── app-server/                      # JSON-RPC 服务端（不变，独立 top-level）
│   ├── server.ts
│   ├── protocol.ts
│   ├── protocol/
│   ├── jsonrpc.ts
│   ├── threadStore.ts
│   ├── turnRunner.ts
│   ├── devBridge.ts
│   ├── replayStateSnapshot.ts
│   ├── threadStateReducer.ts
│   ├── index.ts
│   ├── store/
│   ├── transport/
│   └── turn/
│
├── runtime/                         # ← 合并原 runtime + cli + legacy + serve + web + network
│   ├── createRuntime.ts             #   (原 packages/core/src/runtime/)
│   ├── cli/                         #   (原 packages/core/src/cli)
│   │   ├── main.ts
│   │   ├── args.ts
│   │   ├── help.ts
│   │   ├── json.ts
│   │   └── exitCodes.ts
│   ├── bootstrap/                   #   (原 packages/core/src/legacy/bootstrap)
│   ├── serve/                       #   (原 packages/core/src/serve)
│   ├── web/                         #   (原 packages/core/src/web)
│   └── network/                     #   (原 packages/core/src/network)
│
├── entrypoints/                     # 入口文件（不变）
│
│  ════════════════════ UI 层 ════════════════════
│
├── screens/                         # Ink 屏幕（不变）
│   ├── REPL.tsx
│   ├── repl/
│   └── ...
│
├── components/                      # Ink 组件
│   ├── chat/
│   ├── tool/                        # ← 吸收原 tools/presenters
│   │   ├── ConfirmMenu.tsx
│   │   ├── AskUserQuestionToolBlock.tsx
│   │   ├── BashApprovalToolBlock.tsx
│   │   ├── PatchPreview.tsx
│   │   ├── MarkdownBlock.tsx
│   │   └── ...
│   └── ui/
│
├── tui/                             # ← 重命名原 packages/core/src/ui
│   ├── toolFormatting.ts
│   ├── consoleLogger.ts
│   ├── inkStreams.ts
│   ├── theme.ts
│   └── ...
│
└── services/                        # ← 仅保留 UI 层桥接
    └── runtimeUiBridge.tsx           #   [UI] Runtime-UI 桥接
```

## Before → After 迁移对照

| #   | 原目录                       | 文件数 | 目标位置                 | 操作                               |
| --- | ---------------------------- | ------ | ------------------------ | ---------------------------------- |
| 1   | `packages/core/src/shared`                 | 8      | `packages/core/src/shared/`            | **保留** + 吸收 invokables、utils  |
| 2   | `packages/core/src/invokables`             | 3      | `packages/core/src/shared/invokables/` | **合并**                           |
| 3   | `packages/core/src/utils`                  | 20     | `packages/core/src/shared/utils/`      | **合并**                           |
| 4   | `packages/core/src/env`                    | 11     | `packages/core/src/config/`            | **合并**为 config 顶层             |
| 5   | `packages/core/src/core/config`            | 14     | `packages/core/src/config/settings/`   | **合并**为 config 子目录           |
| 6   | `packages/core/src/core/{其余 8 个子目录}` | ~37    | `packages/core/src/core/`              | **保留** + 吸收 services/models    |
| 7   | `packages/core/src/adapters`               | 36     | `packages/core/src/adapters/`          | **不变**                           |
| 8   | `packages/core/src/chat`                   | 13     | `packages/core/src/chat/`              | **不变**                           |
| 9   | `packages/core/src/streaming`              | 11     | `packages/core/src/streaming/`         | **不变**                           |
| 10  | `packages/core/src/prompts`                | 14     | `packages/core/src/prompts/`           | **不变**                           |
| 11  | `packages/core/src/hooks`                  | 14     | `packages/core/src/hooks/`             | **不变**                           |
| 12  | `packages/core/src/subagents`              | 17     | `packages/core/src/features/subagents/`| **移入** features                  |
| 13  | `packages/core/src/tools`                  | 225    | `packages/core/src/tools/`             | **保留** − presenters              |
| 14  | `packages/core/src/tools/presenters`       | 45     | `packages/core/src/components/tool/`   | **搬迁**                           |
| 15  | `packages/core/src/features/semantics`     | 67     | 不变                     | **不变**                           |
| 16  | `packages/core/src/features/repl`          | 121    | 不变                     | **不变**（内部层标注）             |
| 17  | `packages/core/src/features/commands`      | 16     | `packages/core/src/features/commands/` | **吸收** packages/core/src/commands              |
| 18  | `packages/core/src/commands`               | 4      | `packages/core/src/features/commands/` | **合并**                           |
| 19  | `packages/core/src/features/sessionTitle`  | 9      | 不变                     | **不变**                           |
| 20  | `packages/core/src/features/tools`         | 19     | `packages/core/src/features/tools/`    | **不变**                           |
| 21  | `packages/core/src/skills`                 | 2      | `packages/core/src/features/skills/`   | **移入** features                  |
| 22  | `packages/core/src/services`               | 6      | 拆分                     | models→`core/models/`, bridge→保留 |
| 23  | `packages/core/src/cli`                    | 9      | `packages/core/src/runtime/cli/`       | **合并**                           |
| 24  | `packages/core/src/runtime`                | 2      | `packages/core/src/runtime/`           | **保留** + 吸收其他 Runtime 目录   |
| 25  | `packages/core/src/legacy`                 | 17     | `packages/core/src/runtime/bootstrap/` | **合并**                           |
| 26  | `packages/core/src/serve`                  | 3      | `packages/core/src/runtime/serve/`     | **合并**                           |
| 27  | `packages/core/src/web`                    | 3      | `packages/core/src/runtime/web/`       | **合并**                           |
| 28  | `packages/core/src/network`                | 2      | `packages/core/src/runtime/network/`   | **合并**                           |
| 29  | `packages/core/src/app-server`             | 32     | `packages/core/src/app-server/`        | **不变**                           |
| 30  | `packages/core/src/entrypoints`            | 6      | `packages/core/src/entrypoints/`       | **不变**                           |
| 31  | `packages/core/src/screens`                | 39     | `packages/core/src/screens/`           | **不变**                           |
| 32  | `packages/core/src/components`             | 42     | `packages/core/src/components/`        | **保留** + 吸收 tools/presenters   |
| 33  | `packages/core/src/ui`                     | 54     | `packages/core/src/tui/`               | **重命名**                         |

## 对应 `layer-contract.config.json`

```json
{
  "layerOrder": ["Types", "Config", "Repo", "Service", "Runtime", "UI"],
  "scanRoots": ["src", "packages/web-reference-react/src"],
  "layers": {
    "Types": [
      "packages/core/src/shared",
      "packages/core/src/prompts/types.ts",
      "packages/core/src/streaming/types.ts",
      "packages/core/src/features/semantics/core"
    ],
    "Config": ["packages/core/src/config"],
    "Repo": [
      "packages/core/src/adapters",
      "packages/core/src/features/repl/sessionSave",
      "packages/core/src/features/commands/CommandStore.ts",
      "packages/core/src/features/skills",
      "packages/core/src/features/subagents/types.ts"
    ],
    "Service": [
      "packages/core/src/core",
      "packages/core/src/chat",
      "packages/core/src/streaming",
      "packages/core/src/prompts",
      "packages/core/src/hooks",
      "packages/core/src/tools",
      "packages/core/src/features/subagents",
      "packages/core/src/features/commands",
      "packages/core/src/features/sessionTitle",
      "packages/core/src/features/semantics/projection",
      "packages/core/src/features/semantics/adapters",
      "packages/core/src/features/semantics/runtime",
      "packages/core/src/features/semantics/selectors",
      "packages/core/src/features/repl/controller",
      "packages/core/src/features/tools"
    ],
    "Runtime": ["packages/core/src/runtime", "packages/core/src/app-server", "packages/core/src/entrypoints"],
    "UI": [
      "packages/core/src/tui",
      "packages/core/src/screens",
      "packages/core/src/components",
      "packages/core/src/services/runtimeUiBridge.tsx",
      "packages/core/src/features/repl/keys",
      "packages/core/src/features/repl/overlays",
      "packages/core/src/features/repl/inputScopeContext.tsx",
      "packages/core/src/features/repl/replUiContext.tsx",
      "packages/core/src/features/repl/planContext.tsx",
      "packages/core/src/features/commands/render.ts",
      "packages/web-reference-react/src"
    ]
  }
}
```

## 变化统计

| 指标                 | 当前 | 目标                 |
| -------------------- | ---- | -------------------- |
| `packages/core/src/` 顶层目录数    | 27   | 16                   |
| 未映射到层的目录     | 8    | 0                    |
| 跨层混放的目录       | 4    | 0                    |
| 需搬迁的文件（估算） | —    | ~100 个文件          |
| 不动的目录           | —    | 17 个（占总量 60%+） |

## 执行状态（Phase E - Slice 92）

- 状态：已完成（层映射修正 + Service->UI 违规清零）。
- 本轮已完成：
  - `scripts/layer-contract.config.json` 完成硬切映射：`packages/core/src/tui`/`packages/core/src/screens`/`packages/core/src/components` 归 UI。
  - 新增 `allowedImports` 机制并落地入口白名单，`check-layer-contracts` 支持 `staleAllowedImports` 漂移提示。
  - `packages/core/src/features/repl/*` 对 Dialog 类型依赖从 `tui/*Dialog.tsx` 抽离到 `packages/core/src/shared/replDialogContracts.ts`，清零 Repl Service->UI 类型违规。
  - `packages/core/src/core/errors/codes.ts` 与 `packages/core/src/core/setup/types.ts` 分别归位到 Types/Config 映射，避免 UI->Repo 误伤。
- 明确不做：
  - 不调整 REPL、Dialog、Tool 行为与交互语义，仅做分层治理与类型归位。

## 执行状态（Phase F - Slice 93）

- 状态：已完成（当前链路 shim 收口）。
- 本轮已完成：
  - 全链路移除对 `packages/core/src/tui/toolFormatting` 的依赖，统一改为 `packages/core/src/shared/utils/toolFormatting`。
  - 删除 shim 文件 `packages/core/src/tui/toolFormatting.ts`。
  - 新增 `packages/core/src/shared/utils/snippetStartLine.ts`，Service 侧改为直接依赖 shared；`packages/core/src/components/tool/snippetStartLine.ts` 保留最薄 re-export。
  - `scripts/layer-contract.config.json` 移除 `toolFormatting` 与 `snippetStartLine` 的过渡例外映射。
  - 同步合同与 runbook 的 `allowedImports` 说明与排障路径。
- 明确不做：
  - 不做全仓 shim 清理，仅处理 Phase E/F 当前链路。

## 执行状态（Phase C - Slice 94）

- 状态：进行中（目录迁移第一批，文档路径事实收口）。
- 本轮已完成：
  - 活跃文档中的历史路径同步到现状目录：
    - `README.md`: `packages/core/src/subagents/README.md -> packages/core/src/features/subagents/README.md`
    - `ARCHITECTURE.md`: `packages/core/src/env/config.ts -> packages/core/src/config/config.ts`
    - `docs/pitfalls/summary.md`: `packages/core/src/ui/* -> packages/core/src/tui/*`，`packages/core/src/legacy/runLegacyCli.tsx -> packages/core/src/runtime/bootstrap/runLegacyCli.tsx`
  - 保持实现不变，仅修正文档导航与排障链接，减少后续排障误导。
- 明确不做：
  - 不改任何运行时代码与分层规则，仅做文档事实收敛。

## 执行状态（Phase C - Slice 95）

- 状态：进行中（目录迁移第一批，门禁术语历史兼容收口）。
- 本轮已完成：
  - `scripts/check-core-boundaries.mjs` 移除 `packages/core/src/ui/*` 的非相对导入字符串兼容分支，仅保留当前事实路径 `packages/core/src/tui/*` 与 `packages/core/src/screens/*` 检查。
  - 目的为消除“目录迁移已完成但门禁仍含历史路径术语”的噪音，避免后续排障误判。
- 明确不做：
  - 不改变任何分层规则方向与业务行为，仅收口历史兼容分支。

## 执行状态（Phase C - Slice 96）

- 状态：已完成（目录迁移第一批验收收口）。
- 本轮已完成：
  - 按 Phase C 验收口径完成全量检查并通过：
    - `bun run type-check`
    - `bun run test -- packages/core/src/features/commands packages/core/src/tools/modules/slashCommand packages/core/src/core/config`
    - `bun run check:layer-contracts`
    - `bun run check:layer-coverage`
    - `bun run check:shared-types`
  - 当前门禁状态：
    - `layer-contracts`: `baseline=0, current=0`
    - `layer-coverage`: `mapped=549, unmapped=0`
    - `shared-types`: `packages/core/src/platform/types/shared` 尚未建立，检查按合同策略跳过（不阻断）。
- 明确不做：
  - 不进入 Phase D（已决议不执行），后续按既定 E/F 与 feature 收口策略推进。

## 执行状态（Phase C - Slice 97）

- 状态：进行中（当前链路 shim 进一步收口，低风险）。
- 本轮已完成：
  - 删除 `packages/core/src/components/tool/snippetStartLine.ts` 薄 re-export shim。
  - 组件与测试调用方改为直接依赖 `packages/core/src/shared/utils/snippetStartLine`：
    - `packages/core/src/components/tool/useSnippetStartLineNumber.ts`
    - `packages/core/src/components/tool/snippetStartLine.test.ts`
  - 保持 `findSnippetStartLineNumber` 实现与行为不变，仅减少一层路径跳转。
- 明确不做：
  - 不调整行号计算算法与 patch 渲染行为，仅做导入链路收口。

## 执行状态（Phase C - Slice 98）

- 状态：进行中（无调用兼容层批量删除）。
- 本轮已完成：
  - 删除 `packages/core/src/features/repl/controller/send/taskResult.ts` 薄 shim，并移除其重复测试文件。
  - REPL 调用方直接改为依赖 `packages/core/src/features/semantics/selectors/taskResultParsing`：
    - `packages/core/src/features/repl/controller/streaming/streamingToolCompletion.ts`
    - `packages/core/src/features/repl/controller/canonical/canonicalTurnMessageMapping.ts`
  - 删除无仓内调用的兼容导出/别名：
    - `packages/core/src/tui/agents/AgentsDialog.tsx` 类型 re-export
    - `packages/core/src/streaming/index.ts` 中 `createStreamClient` alias
    - `packages/core/src/features/commands/registry.ts` 中 `getSlashCommandSuggestions`
- 明确不做：
  - 不触碰 `legacy transcript` / `legacy session reader` / `config migrate` 等行为兼容逻辑，本轮仅删除无调用导出层。

## 执行状态（Phase C - Slice 99）

- 状态：进行中（Skills 事实源补齐）。
- 本轮已完成：
  - 新增 `docs/contracts/skills-contract.md`，将 Skills 的目录发现、优先级、命名规则、元数据语义与 `.skills`/`.formax/skills` 长期并行支持治理写入规范性合同。
  - `docs/index.md` 的 Contracts 区新增 Skills 合同入口，避免此类事实仅散落在实现/测试中。
- 明确不做：
  - 不改 `SkillStore` 运行逻辑，本轮仅补齐文档事实源并建立后续变更流程约束。
