diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 975db32af..2a0447bdf 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -5,3 +5,11 @@ # P1-01 include 规范化(2026-09-27) 5524a35241ba67ba061aa1a279fd943213601a2f 7a90db6d94bf70e4e200cb39c0122bdb1fc7fa66 + +# P2-02 / P2-03 / P2-04 已合入本分支的纯搬迁与 include 改写 +4009835e29da6c901a0c4ea1ef13a6e99479bbf5 +bd8ac3ebd916eafbce1040cea39ff9d966bb3493 +8c8538b0e83a2f57d00597d7c5b853777fd55c63 +bb94c967934cf3c355a143435bc2b292a917275f +05ab77d55f9b0c073708b17a0e3c34580b92ac78 +295041e71071b2fa66bbc3c8517a1697c9d6c00b diff --git a/CLAUDE.md b/CLAUDE.md index 3eba740eb..9dae53c55 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -259,7 +259,7 @@ Rewind support uses per-user-turn checkpoints. `SessionManager::track_file_write - **父目录 mtime 不能替代子目录 mtime。** 在已有 hash 目录里新建 `workspace.json` 不会改 `projects_dir` 的 mtime,只会改那个 hash 目录的。所以缓存键必须是每个 hash 目录自己的时间戳。 - **写路径主动失效。** `register_new` / `set_name` / `hide` 都 `dir_probes_.erase(hash)`。写盘走 atomic_file 的 tmp+rename、rename 本就会推进目录 mtime,这层只是不把可见性正确性押在文件系统的时间戳行为上。 -回归测试:`tests/desktop/workspace_registry_test.cpp` 的 `WorkspaceRegistryProbeCache.*`(其中 `MarkerAddedLaterIsStillPickedUp` 就是负缓存不能挡住后补 marker 的哨兵)+ `web/src/lib/sidebarAuxiliaryFetch.test.js`。 +回归测试:`tests/workspace/workspace_registry_test.cpp` 的 `WorkspaceRegistryProbeCache.*`(其中 `MarkerAddedLaterIsStillPickedUp` 就是负缓存不能挡住后补 marker 的哨兵)+ `web/src/lib/sidebarAuxiliaryFetch.test.js`。 Daemon session multiplexing uses `SessionRegistry`. Each session entry owns its own `SessionManager`, `PermissionManager`, `AgentLoop`, async permission prompter, and question prompter. `EventDispatcher` gives each emitted event a monotonic sequence number and keeps a bounded replay ring. @@ -307,7 +307,7 @@ The desktop shell runs a webview against workspace-local daemon processes. It do Key modules: -- `workspace_registry`: persisted workspace list and names. +- `workspace_registry` (lives in `src/workspace/workspace_registry.{hpp,cpp}` since refactor20260927 P2-04; shared with daemon, TUI and headless): persisted workspace list and names. - `daemon_pool`: per-workspace daemon process management. - `web_host`: native webview wrapper and bridge binding. - `tray_icon_win` and `notifications_win`: Windows tray and notification integration (`notifications*` and `custom_toast*` now live in `src/platform/native_ui/`, refactor20260927 P2-03). @@ -554,7 +554,7 @@ SidePanel 折叠 UI:`ChatView` 把 `SidePanel` 包到 `
5MB → 415 `{error:"file too large",size:N}`;前 512 字节出现 `\0` → 415 `{error:"binary"}`;不存在 → 404。实现:`src/workspace/files_handler.{hpp,cpp}`(D21 从 web 移出,纯函数,17 个 unit test 覆盖路径越权 / 噪音过滤 / 排序 / 二进制嗅探) | | `GET /api/commands?workspace=` → `{builtins:[{name,description}][, skills:[{name,description}]]}` | InputBar 斜杠下拉的命令清单。builtins **硬编码白名单 = init + compact**(描述与 TUI `register_builtin_commands` / `register_init_command` 对齐)。**`workspace` 参数(由 `expand-webui-skill-commands` 引入)**:缺省 → 不返回 `skills` 字段(向后兼容旧客户端);提供 → handler 用 `acecode::initialize_skill_registry(tmp, *cfg, workspace_cwd)` 临时构造一个 SkillRegistry 扫该 workspace 的项目链(`.agent/skills`、`.acecode/skills` + 全局 + external_dirs),与 daemon 全局 SkillRegistry 合并(workspace local 优先,first-wins by name),按字典序输出 skills 字段。`/init` `/compact` 在 web 端选中后只插入输入框 + chip 高亮,daemon 端**不**做特殊执行(原 add-webui-slash-commands 决策);`/ args` 由下面新加的 expander 真展开。实现:`src/web/handlers/commands_handler.{hpp,cpp}`(纯函数 `build_commands_payload` + gtest case)| | `POST /api/sessions/:id/messages`(行为扩展) | `expand-webui-skill-commands` 引入:在 `send_input` 之前调 `try_expand_skill_command(text, registry)`(`src/web/handlers/skill_command_expander.{hpp,cpp}`)。命中已知 skill 名(按 session 的 workspace cwd 临时 scan)→ text 被替换为 `build_skill_invocation_hint(meta, args)` 的**轻量提示**:`[SYSTEM: User invoked / skill] + Description + Use skill_view(name=...) to load full SKILL.md + User's request: `。**不**注入 SKILL.md body / supporting_files,LLM 第一次看到提示后主动 invoke `skill_view` tool 把 SKILL.md 拉一次进 context,后续重复同名 `/skill` 调用不再注入(避免 context 膨胀)。TUI `src/skills/skill_commands.cpp::cmd.execute` 也走同一个 `build_skill_invocation_hint`,跨端行为统一。Builtin (`/init`/`/compact`) 不在 SkillRegistry 中 → 透传走普通 user message;未知命令 (`/foobar`) 同样透传。**不**新增执行端点,**不**改 AgentLoop API | | `POST /api/open-in-explorer` body `{path}` → `{ok:true}` / 400 `{ok:false,error}` / 501 | webapp 兼容模式(Edge --app,无 webview bridge)右键菜单「在资源管理器中打开」的 REST 通路。门控 = `WebServerDeps.open_in_explorer` 回调是否注入(worker.cpp 仅在 `native_folder_picker_enabled` 时填,复用 `desktop::open_path_in_file_manager`:接受任意现存本地绝对普通文件或目录,不做 workspace/managed-root 边界判断)。Windows 文件用 Explorer `/select` 选中,目录保持直接打开。前端 `DesktopContextMenu::openTargetInExplorer` bridge 优先、REST 兜底 | @@ -562,7 +562,7 @@ SidePanel 折叠 UI:`ChatView` 把 `SidePanel` 包到 `
` / `` / ``(`utils/paths.hpp` 自带)与各自已 include 的头;`config.hpp` 透传 include 保证只经它间接拿到这三个函数的文件(含平台专属 .cpp / .mm)照常编译 | +| 用例清单不变 | 满足:`tests` 名单 5115、ctest 注册名 5119、SKIP 集合 9 条与参照逐条相同,0 增 0 减,失败集合前后都为空 | 第 3、4 节 | + +## 2. 本机构建(Windows,全新目录 `build-p2`) + +Ninja + MSVC 2022,Release,`BUILD_TESTING=ON`,`ACECODE_BUILD_DESKTOP=ON`,x64-windows-static,只读复用 `N:/Users/shao/acecode/build/vcpkg_installed`,configure 前写 File API query;脚本 `N:\Users\shao\acecode-p2-04-rec\build-p2.cmd`(先 `vcvars64`)。 + +| 步骤 | 结果 | +|---|---| +| configure | 通过(`acecode_assert_known_roots` / `acecode_require_sources` 护栏均通过;`src/ipc/`、`src/workspace/` 被 GLOB_RECURSE 收进 `acecode_testable`,四个显式清单路径命中) | +| `cmake --build --target acecode acecode-desktop acecode_unit_tests --parallel 8` | 通过(全新目录首轮 1020 步,17:34–17:40,0 error / 0 warning-as-error) | +| `--target computer_use_native_smoke computer_use_broker_smoke agent_browser_host_smoke agent_browser_pointer_demo acecode_upgrade_restart_smoke` | 通过(`acecode_upgrade_restart_smoke` 的源 `tests/desktop/helpers/upgrade_restart_smoke.cpp` include 了搬走的 `ipc/runtime_files.hpp`、`ipc/daemon_protocol.hpp`,一并证明新 include 根生效) | +| D24 重放后的增量重建(同一目录 `build-p2`,同一脚本:re-configure + 主目标 392 步 + 冒烟目标 9 步,21:13–21:19) | 通过,exit 0,0 error | +| 合入 P2-02 之后的增量重建(同一目录、同一脚本:re-configure + 主目标 421 步 + 冒烟目标 4 步,21:27–21:33) | 通过,exit 0,0 error;第 4 节的快照与第 3 节的单测都取自这次重建产物 | + +## 3. 单测 + +### 3.1 desktop 冒烟(启动、打开 workspace)的替代验证 + +开跑前 `tasklist` 显示用户正开着桌面版(`acecode-desktop.exe` PID 13680,`~/.acecode/logs/desktop-2026-09-27.log` 19:46 / 19:49 两次启动,并带着两个 `acecode.exe` daemon),且本会话的 computer-use 屏幕访问申请被用户拒绝,没有截图手段。按简报约定改为跑 `tests/desktop` + `tests/workspace` + `tests/ipc` 的全部用例(37 个测试文件、54 个 suite,过滤器 `N:\Users\shao\acecode-p2-04-rec\subset-flags.txt`,隔离 HOME `N:\acecode-p2-04-iso2`): + +```text +build-p2\tests\acecode_unit_tests.exe --gtest_flagfile=subset-flags.txt --gtest_output=xml:subset-results.xml +[==========] 383 tests from 54 test suites ran. (717 ms total) +[ PASSED ] 382 tests. +[ SKIPPED ] 1 test: NativeNotifications.OptInDeliversSelfDrawnToast(需 ACECODE_RUN_NOTIFICATION_SMOKE=1 的手动冒烟,与基线一致) +``` + +合入 P2-02 前后各跑一次,结果相同:0 失败(用户桌面版正在运行的情况下 `DesktopSingleInstance.*` 7 项也全部通过)。其中搬走的测试文件对应的 suite:`FilesHandler` 25 项全过(任务行点名「files_handler 相关测试通过」)、`WorkspaceRegistry` / `WorkspaceRegistryProbeCache` / `WorkspaceRegistryOrder` / `WorkspaceRegistryDefault` 23 + 4 + 6 + 6 项全过、`DaemonRuntimeFiles` 15 项全过、`AgentBrowserRuntime` 5 项全过、`DesktopOpenRequest` 5 项全过;引用搬走头的 `DaemonPool`(23)/ `PickActive`(6)/ `WorkspaceProfile`(10)同样通过。结果 XML:`N:\Users\shao\acecode-p2-04-rec\subset-results.xml`。 + +### 3.2 全量单测(隔离 HOME / TEMP:`N:\acecode-p2-04-iso\{home,tmp}`,仓库外) + +```text +python scripts\refactor\gtest_inventory.py --binary N:\Users\shao\acecode-p2-04\build-p2\tests\acecode_unit_tests.exe --run --ctest-dir N:\Users\shao\acecode-p2-04\build-p2 --timeout 7200 --output N:\Users\shao\acecode-p2-04-rec\gtest.json +``` + +USERPROFILE / HOME / APPDATA / LOCALAPPDATA / TEMP / TMP 全部指到仓库外(`N:\acecode-p2-04-rec\test-run.cmd`),对合入 P2-02 之后重建的 `build-p2` 跑,21:34–21:40: + +| 项目 | 参照(P2-02 之后的 master,同一台机器) | P2-04(合入后,HEAD 的 `957fb508`) | +|---|---|---| +| 列出 / 执行 / SKIP / 失败 | 5115 / 5114 / 9 / 0 | **5115 / 5114 / 9 / 0** | +| ctest 注册名 | 5119 | 5119 | +| SKIP 清单 | 9 条 | 同一 9 条:`ChannelBridge.RealBridgeStartsWithoutConnectingAnAccount`、`ChannelSetup.RealDependencyInstallationIsOptionalAndUsesTemporaryState`、`ImageGenerationNetworkSmoke.{AbortReturnsPromptlyDuringGeneration,GeneratesOneImageFromRealEndpoint}`、`NativeNotifications.OptInDeliversSelfDrawnToast`、`RssSearchBackendLive.HostedEndpointReturnsSearchableResults`、`SessionReplayRealJsonl.UserSessionDbcoding5_2026_04_26`、`SystemPromptTest.PosixPromptStaysCleanOfWindowsGuidance`、`Utf8PathTest.ExtendedLengthPathIsIdentityOnPosix` | +| 失败清单 | 空 | 空(用户桌面版全程在运行,`DesktopSingleInstance.*` / `ComputerUsePointerOverlay.*` 这次都没有抖动) | + +合入 master 之前对 D24 重放树也起跑过一轮全量,跑到一半因为要合入 P2-02 并重建而被我手动中止(只杀了本 worktree 的 `acecode_unit_tests.exe`),不计入结果;合入前的树上另跑过 3.1 节的子集(相同结果)。 + +## 4. 目标快照与用例清单对照(参照 `acecode-p2-shared/master-windows-{targets,gtest}.json`) + +参照文件在 2026-09-27 21:2x 换成了 P2-02 合入后的 master(59 target / 3572 元组;5115 用例 / 9 SKIP / 0 失败),下面的对照都取自合入 `ec64edcb` 之后重建的 `build-p2`(第 2 节最后一行)。 + +```text +python scripts/refactor/cmake_target_snapshot.py --build-dir build-p2 --configuration Release --map scripts/refactor/src_layout_map.tsv --reverse-map --compare N:/Users/shao/acecode-p2-shared/master-windows-targets.json --output N:/Users/shao/acecode-p2-04-rec/targets-compare-merged.json +``` + +| 项目 | 参照(master `94938fa4` 之后,原样物理路径) | P2-04 `build-p2` | +|---|---|---| +| target 数 / 元组数 | 59 / 3572 | 59 / 3572 | +| target 增减 | — | 0 / 0 | +| 元组增减,`--reverse-map` 直接对照参照(工具原始输出) | — | 67 removed / 67 added,分三类:(a) 25 对 `nlohmann_json.natvis` 元组只差 vcpkg 路径前缀(参照在主检出采集,`vcpkg_installed` 在其源根下记成 `build/vcpkg_installed/...`;本 worktree 只读复用同一目录、位于源根之外,记成绝对路径;与 P1-01 记录的环境差异同一条);(b) 42 对是 **P2-02 搬走的文件**(`src/llm/{llm_provider.hpp,model_family.*,tool_icons.hpp,tool_protocol_names.*}`、`src/utils/{diff_utils,diff_view_truncate,word_diff}.*`、`tests/llm/…`、`tests/utils/diff_*` 及其在 5 个 target 里的 .obj):参照是**原样**物理路径,本侧 `--reverse-map` 把它们反查回 `src/tool/…`、`src/provider/llm_provider.hpp` 旧路径,于是两侧写法不同;(c) 本任务搬走的 17 个文件反查后与参照相同,**不在差异里** | +| 元组增减,两侧都换算回旧路径(参照用工具自己的 `translate_for_comparison(reverse=True)` 换算,42 条元组变动;本侧再归一 (a) 的前缀;`compare_snapshots.py --before 参照(反查) --after 本侧(反查+归一)`) | — | **`unexpected=false`,0 增 0 减,targets_added / targets_removed / unexpected_added / unexpected_removed 全空** —— 即「按映射换算回旧路径后每个文件所属的 target 不变」 | +| 元组增减,两侧都用原样物理路径(本侧不加 `--reverse-map`,只归一 (a)) | — | 22 removed / 22 added,**恰好就是本任务搬的 17 个文件 + `files_handler.cpp.obj` 在 5 个消费 target 里的对象**,一一对应、target 相同:`acecode_unit_tests` 的 5 个测试(`tests/{daemon,desktop,web}/…` → `tests/{ipc,workspace}/…`)、`acecode_native_bridge_support` 的 4 个 .cpp、`acecode_testable` 的 `files_handler.cpp` 与 7 个 .hpp、`acecode` / `acecode_unit_tests` / `concurrent_session_writer` / `remote_web_proxy_test_child` / `state_file_claim_worker` 的 `files_handler.cpp.obj`;没有其它差异(`N:\Users\shao\acecode-p2-04-rec\compare-targets-merged-raw.json`) | + +搬走文件的归属抽样(反查后):`acecode_native_bridge_support` 仍含 `src/daemon/runtime_files.cpp`、`src/desktop/{agent_browser_runtime,open_request,workspace_registry}.cpp`;`acecode_testable` 仍含 `src/web/handlers/files_handler.cpp` 与 7 个搬走的 .hpp;`acecode` / `acecode_unit_tests` 等 5 个 target 仍消费 `@build/CMakeFiles/acecode_testable.dir/src/web/handlers/files_handler.cpp.obj`(对象路径由 `bf1ef7db` 同样反查)。`utils/paths.cpp` 只增内容不增文件,本任务没有新增文件。脚本:`N:\Users\shao\acecode-p2-04-rec\normalize_vcpkg_prefix.py`(只改那 25 个值)、参照反查的几行 Python 见同目录记录。 + +用例清单对照(`compare_snapshots.py --before 参照(反查) --after 本侧(反查+归一) --gtest-before master-windows-gtest.json --gtest-after gtest.json`,`N:\Users\shao\acecode-p2-04-rec\compare-final.json`):targets `unexpected=false`;gtest 段 `tests_before = tests_after = 5115`、`tests_added / tests_removed` 为空、`skipped_added / skipped_removed` 为空、`failures_before / failures_after` 为空、ctest 5119 → 5119。搬走的 5 个测试文件里的用例名不变(gtest 按 suite 名注册,与文件位置无关),所以清单不增不减。 + +## 5. lint 变化(同一台机器同一工具,报告模式) + +| 项目 | 开工前(master `4b6ce35c`) | 合入 P2-02 前的 P2-04(`c2b217f9`) | 合入后的 master(`ec64edcb`,P2-02 记录) | 合入后的 P2-04(HEAD) | +|---|---|---|---|---| +| 分层违规总数 | 161(R8 119 / R1 18 / R9 10 / R2 6 / R3 5 / R5 1 / R10 1 / R14 1) | 161(逐规则相同,findings 集合相同) | 153(P2-02 消掉 8 条:R1 -5、R2 -2、R3 -1) | 153(R8 119 / R1 13 / R9 10 / R2 4 / R3 4 / R5 1 / R10 1 / R14 1;与 161 基线的差异 = P2-02 消掉的 8 条 + `hook_registry.cpp` 行号 -1) | +| include 边数(`include_edges`) | 2654 | 2654(20 个文件把 `config/config.hpp` 边换成 `utils/paths.hpp` 边,`config.hpp` 新增对 `utils/paths.hpp` 的边,`paths.cpp` 新增对 `constants.hpp` 的边;`expert_registry.cpp` / `hook_registry.cpp` / `paths_test.cpp` 原本已有 `utils/paths.hpp`,各少一条边,合计持平) | — | 2679 | +| `validate_map --strict` | exit 0 | exit 0(0 findings) | exit 0 | exit 0(0 findings;17 条 P2-04 行进入 `planned_or_obsolete_rows`) | +| `check_file_size --strict` / `check_ownership --strict` | exit 0 | exit 0(config.cpp 上限同步下调到 2857) | exit 0 | exit 0 | +| `normalize_includes --check` src / tests | exit 0 | exit 0 | exit 0 | exit 0(含冲突解决后的两个文件) | +| `check_doc_paths` findings | 85(工具原始计数;P1-01 / P2-02 记录的 84 是按 (file,line,path) 去重后的数,`docs/help/conversation.html:46` 同一路径报了两次) | **82**(去重 81):搬迁引入的 6 处(CLAUDE.md ×3、docs/agent-browser.md、docs/desktop-shell/multi-workspace.md、web/README.md)已改回;另修掉 `docs/desktop-shell/design.md` 里本就指错目录的 `src/desktop/runtime_files.{hpp,cpp}`、`tests/desktop/runtime_files_test.cpp` 三处。`openspec/**` 按工具约定不扫描 | 84(去重) | 82(去重 81,与合入前相同) | +| 工具自测 `unittest discover scripts/refactor/tests` | 71 项通过(`4b6ce35c`) | 72 项通过(`bf1ef7db` 新增 1 项,本任务未改工具) | 72 | 72 项通过 | +| `migrate_branch.py --check --layout current` | — | exit 1(P2 期间预期,记录即可):counts layers 2350 / migration_paths 60 / documentation 82 / map 0 / include_normalization 0 / ownership 0 / seed 0(`N:\Users\shao\acecode-p2-04-rec\migrate-check.json`,采集于 D24 重放之前的树;重放只删了转发头与工具改动,不影响这些计数) | — | 未重跑 | + +**为什么总数没有下降。** `check_layers` 在过渡模式下先按 `src_layout_map.tsv` 把每个文件换算到最终路径再归模块:`src/desktop/workspace_registry.hpp` 等 7 个头在开工前就有精确映射行,已经被算作 `workspace` / `ipc` 模块(rank 6 / 5),所以 `agent_loop.cpp → desktop/workspace_registry.hpp` 这类边在基线里从来不是 R1 / R2 违规。基线的 18 条 R1 与 6 条 R2 全部属于 P2-02 / P2-05 / P2-06 / P2-07 的清单(config → permissions、session → session_registry、utils → config、hooks → skills、prompt → agent 等),没有一条涉及本任务的文件,因此本任务能做到的是「不上升」而不是「下降」。任务行「lint 显示指向 desktop、web 的反向边消失」按**物理位置**核对如下(`git grep` 两个提交的 include 行): + +| 反向边(includer 模块 → 被包含头的物理目录) | 开工前 `4b6ce35c` | 之后 HEAD | +|---|---|---| +| agent(`src/agent_loop.cpp:5`)→ desktop/workspace_registry.hpp | 有 | `workspace/workspace_registry.hpp` | +| session(`global_session_catalog.cpp:3`、`global_session_search.cpp:4`)→ desktop/workspace_registry.hpp | 有 | workspace/ | +| tool(`workspace_tools.cpp:3`)→ desktop/workspace_registry.hpp | 有 | workspace/ | +| tool(`agent_browser/browser_tools.cpp:5`、`agent_browser/cdp_client.cpp:4`)→ desktop/agent_browser_runtime.hpp | 有 | ipc/ | +| environment(`data_dir_migration.hpp:27`)→ daemon/runtime_files.hpp | 有 | ipc/ | +| tui(`path_reference/path_reference.cpp:3`)→ web/handlers/files_handler.hpp | 有 | workspace/ | +| tui(`settings/settings_center.cpp:12`、`commands/desktop_command.hpp:3`)→ desktop/{workspace_registry,open_request}.hpp | 有 | workspace/、ipc/ | +| headless(`headless_runner.cpp:13`)→ desktop/workspace_registry.hpp(R5 平级) | 有 | workspace/ | +| web(`server_impl.hpp:16`)→ desktop/workspace_registry.hpp(R5 平级) | 有 | workspace/ | +| daemon(`worker.cpp:8/14`)→ desktop/{daemon_protocol,workspace_registry}.hpp | 有 | ipc/、workspace/ | +| cli(`main.cpp:189`)→ desktop/workspace_registry.hpp | 有 | workspace/ | +| desktop(`daemon_pool.cpp:3/5`、`main.cpp:51`)→ daemon/{guid,runtime_files}.hpp | 有 | ipc/ | +| tests 12 处 → desktop / daemon / web 旧路径 | 有 | ipc/、workspace/ | + +HEAD 上 `git grep` 旧物理路径(`desktop/workspace_registry.hpp`、`daemon/runtime_files.hpp`、`web/handlers/files_handler.hpp` 等)在 src / tests 里 0 命中。`src/ipc/runtime_files.cpp → daemon/platform.hpp` 是本任务留下的唯一一条指向 daemon 物理目录的边(见 `b2439902`)。 + +## 6. `get_*_dir` 拆分的判定方法(`82cae6a8`) + +扫描 `config.hpp` 及其 4 个直接包含头(`desktop_close_behavior.hpp`、`saved_models.hpp`、`computer_use/pointer_appearance.hpp`、`utils/constants.hpp`)声明的全部标识符,对每个 include 了 `config/config.hpp` 的 src / tests 文件检查正文里用到哪些:除三个函数外一个都没用到的共 20 个(layout-map 估计 19 个,多出的是 `runtime_files.cpp`,它另外只用 `utils/constants.hpp` 且已直接 include):`daemon/startup_diagnostics`、`memory/memory_paths`、`channels/runtime`、`desktop/edge_app_launcher`、`desktop/single_instance_posix`、`experts/expert_registry`、`hooks/hook_config`、`hooks/hook_registry`、`loop/loop_store`、`provider/auth/github_auth`、`provider/auth/xai_auth`、`session/session_storage`、`session/thread_service`、`tool/theme_create_tool`、`upgrade/apply`、`upgrade/diagnostics`、`ipc/agent_browser_runtime`、`ipc/open_request`、`ipc/runtime_files`、`tests/utils/paths_test`(后者与 `expert_registry` / `hook_registry` 原本已有 `utils/paths.hpp`,只删 config 行)。`daemon/cli.cpp`、`daemon/service_win.cpp`、`skills/skill_init.cpp`、`hooks/hook_payload.cpp` 另外用了 `AppConfig` / `load_config` / `ModelProfile`,保留 config include。签名、namespace(`acecode`)、`get_run_dir` 的 override 语义、`resolve_data_dir` 的 redirect 缓存语义都不动,运行期行为零变化。 + +## 7. 触碰到的不变量(§7.3) + +- §7.3.8 路径:`get_*_dir` 三个函数只是逐字节搬家;`tests/utils/paths_test.cpp` 与 daemon / desktop / ipc / workspace 相关用例随第 3 节运行。 +- §7.3.9 构建边界:`acecode-desktop` 仍只链 `acecode_desktop_support` + `acecode_native_bridge_support`;搬走的四个 .cpp 仍在 `ACECODE_NATIVE_BRIDGE_SUPPORT_SOURCES`,第 4 节的目标快照证明每个文件所属 target 不变;EXCLUDE_FROM_ALL 冒烟目标都能构建(第 2 节)。 +- 其余不变量(prompt cache 前缀、provider 历史出口、审批门、单写者、锁序、PA)本任务不触碰,守护测试随全量单测运行。 + +## 8. 遗留与需主代理决定的事项 + +1. **lint 总数只做到「不上升」(161 → 161)**,原因见第 5 节:任务点名的反向边在过渡模式下本来就按映射归到 ipc / workspace,基线里没有本任务能消掉的 finding。tasks.md 3.3「lint 显示指向 desktop、web 的反向边消失」以第 5 节的物理边对照表为准,请主代理确认这样验收。 +2. **`src/ipc/runtime_files.cpp → daemon/platform.hpp`**(`b2439902`)是与 P2-03 的交叉点:P2-03 把 `daemon/platform*` 搬到 `platform/process/os_process*` 后,合入方重跑 `normalize_includes.py --scope src` 即可自动改到新路径(映射表已有该行);两边合入顺序不限。 +3. **`CMakeLists.txt` 与 P2-03 相邻行冲突**:本任务只改 `ACECODE_NATIVE_BRIDGE_SUPPORT_SOURCES` 的 4 行(原 228 / 233 / 239 / 243 行)与 396 行的 ws2_32 注释,P2-03 改同一清单里紧邻的 `daemon/platform_*`、`desktop/custom_toast*`、`desktop/locale`、`utils/clipboard` 等行,git 会把相邻改动报成冲突,逐行保留双方即可(没有语义冲突)。 +4. **Linux / macOS 未在本机构建**:`82cae6a8` 的非 Windows 分支只做了逐段人工核对(第 1 节),`agent_browser_host_mac.mm` 的 include 改写由 normalize 完成、未编译;请合入前跑 `refactor-matrix`。 +5. **desktop 冒烟改为替代验证**(第 3.1 节):用户桌面版正在运行 + computer-use 屏幕访问被拒,没有做「启动 build-p2 的 acecode-desktop.exe 并截图」;若需要真机截图,请主代理在桌面版关闭后用 `build-p2\acecode-desktop.exe`(daemon 在同目录)补做。 +6. **开工时按简报旧口径做过、D24 后丢弃的三件事**(备份分支 `backup/P2-04-pre-d24`,仅本机,未推送):7 个转发头 + 7 条 exception 行;`validate_map.py` 识别转发头的修正(否则转发头会被报成「destination collision」,与 D24 的判断一致);`test_migrate_branch` 终态夹具剥掉 exception 行。D24 之后三者都不再需要,分支里没有任何工具改动。 +7. `check_doc_paths` 的「不多于 84」以工具原始计数为准是 85 → 82(第 5 节有口径说明);`docs/desktop-shell/design.md` 的三处修正超出「只改搬走文件的路径字面量」一点点(它们本就指错目录,但指向的正是本任务搬走的文件),若不希望在本任务里改,回退 `c2b217f9` 里该文件的两行即可,findings 会回到 85。 +8. `layout-map.md` 的 P2-04 行「19 个文件」实测为 20 个(多出 `runtime_files.cpp`),表内数字未改;按顶部规则由主代理决定是否回写。 +9. **参照快照的口径**:主代理 21:2x 换上的 `master-windows-targets.json` 是 P2-02 之后 master 的**原样**物理路径快照(含 `src/llm/…`),不是 `--reverse-map` 之后的;直接拿本侧 `--reverse-map` 的输出去比,P2-02 搬走的 42 条元组会被报成假差异(第 4 节 (b))。本记录改为两侧都换算回旧路径再比(用工具自己的 `translate_for_comparison(reverse=True)`),并附一份原样路径对照证明差异只剩本任务的 17 个文件。后续 P2 任务对照时建议参照也用 `--reverse-map` 采集,或统一用原样路径 + 只允许本任务搬走文件的一一对应差异。 +10. 主检出 `N:/Users/shao/acecode` reflog 里 19:15 的 checkout / merge 不是本会话做的:本会话所有 git / cmake / python 命令都带 `cd /n/Users/shao/acecode-p2-04 &&` 或 `git -C N:/Users/shao/acecode-p2-04`,构建脚本内 `cd /d N:\Users\shao\acecode-p2-04`;本会话在 17:41(首轮构建结束)到 21:13(用量限制重置)之间没有执行过任何命令。 + +## 9. Codex 接手复核(2026-09-28,合入 P2-03 前) + +已合入最新 master `0c0e37cb`,当前源码提交 `f3483845d986230f848dbe75ad5c623b5e769ff4`。[refactor-matrix 36332588494](https://github.com/tmoonlight/acecode/actions/runs/36332588494) 的四平台全新构建均通过: + +| 平台 | target / 编译元组 | 列出 / 执行 / SKIP / 失败 | +|---|---|---| +| Windows x64 | 59 / 3572 | 5115 / 5108 / 10 / 3 | +| Linux x64 | 50 / 3486 | 5035 / 5026 / 16 / 0 | +| macOS arm64 | 57 / 3631 | 5040 / 5033 / 14 / 11 | +| Deepin x64 | 13 / 1372 | 不启用测试 | + +相对 post-p0,目标增减和既有元组删除均为 0,新增元组只有前序 P2-02 的 43 / 19 条。本任务全部搬迁文件保持原目标与编译属性。产物与对照 JSON 在仓库外 `N:/Users/shao/AppData/Local/Temp/codex-refactor20260928/ci/p2-04/` 及 `ci-audit-p2-04-*.json`。 + +原始 CTest 参数化名称含运行时指针 / 对象字节,不作逐字节等值声明;本次核对 GoogleTest suite / case 集合、CTest 注册数量和 SKIP 用例集合,均无增删。快照比较在两侧统一使用 `translate_for_comparison(reverse=True)`,所有既有目标依赖和编译属性保持。 + +Deepin artifact 的 `source_revision` 因容器 Git 的 `dubious ownership` 报错为空。已从同一 build job 的 checkout 日志核对完整提交号,与传入的不可变 `source_ref` 一致;没有把空字段当作来源验证通过。Deepin 按原矩阵约定只构建 CLI / Desktop,不运行单测。 + +矩阵是基线采集工作流,其成功状态不代表所有断言通过。Windows 的失败未超出 post-p0 基线;macOS 的 10 项既有失败仍在,另有 `OpenAiProviderErrorRecovery.SseKeepaliveCommentsDoNotTriggerRetry`,这项已在 P1 验收及 P2-02 记录为既有时序抖动。本次保留其失败,没有删除用例、增加 SKIP 或修改断言。Linux 完整测试为 0 失败。 + +### 9.1 实际 Desktop 工作区与文件预览验证 + +补齐第 3.1 节当时未执行的真机链路。先在本工作区运行 `pnpm install --frozen-lockfile` / `pnpm build`,再用全新、可被共享启动器识别的 `build/windows-x64-desktop-release` 配置并构建 CLI / Desktop。MSVC x64 + Ninja Release,只读复用主检出的 vcpkg 依赖,519 步构建成功。通过 `python scripts/dev_environment.py desktop --yes` 启动,启动器确认复用本工作区产物并完成增量检查。 + +HOME / USERPROFILE / APPDATA / LOCALAPPDATA / TEMP / TMP 均为仓库外 `N:/ac-p204-0928/` 的独立目录,WebView2 profile 也独立。通过该实例的 WebView2 CDP 操作 DOM,未使用屏幕截图: + +1. Desktop 窗口启动,页面标识 `__ACECODE_DESKTOP_SHELL__` 为 true,原生 bridge 可调用。 +2. 在隔离 daemon 中注册 `N:/ac-p204-0928/workspace-one`,HTTP 201;原生 `aceDesktop_listWorkspaces` 能读到该工作区。 +3. `aceDesktop_activateWorkspace` 成功,返回相同 cwd / hash,daemon 保持 running。 +4. 在实际页面选择该工作区,展开文件面板,点击 `p2-04-smoke.txt`,文件预览中显示 `P2-04 workspace file handler smoke`。同时原生工作区状态为 active / available / running。 +5. 通过 `aceDesktop_quitApp` 正常退出,本次 Desktop PID 48772 和 daemon PID 40576 均已结束;原有用户 Desktop PID 13680 仍在运行。 + +检查摘要为仓库外 `p2-04-desktop-smoke.json`;构建与启动日志为 `p2-04-native-build.log` / `p2-04-desktop-launch.log`。测试文件仅写入隔离工作区,没有修改项目源码。 + +P2-03 合入后仍须同步最新 master,解决 CMake 相邻改动并复验;本节不提前勾选 P2-04。 + +## 10. 同步 P2-03 后的集成复验(2026-09-28) + +P2-03 已由 PR #79 合入 master(`b7be0dcb`)。本分支的合并提交为 `aa6872f961b6f4e73210bac0e5de1cb8db9594c9`。14 个文件的冲突均为相邻 include / CMake 路径或文档路径,保留 P2-04 的 ipc / workspace 路径及 utils/paths 分离,同时采用 P2-03 的 platform / pty 路径。P2-03 完成标记已在 tasks.md 更新。 + +- src / tests include 规范化、映射、分层阻断项、行数、所有权检查和 `git diff --cached --check` 全部通过;OpenSpec strict 校验及前端完整 `pnpm test` 通过。 +- 全新目录 `build/p2-04-integrated-aa6872f9` 配置并构建 CLI / Desktop / GoogleTest / 五个冒烟目标,1046 步完成,退出码 0。 +- File API 目标对照:59 target / 3573 元组。相对 P2-02 后的同机 master 快照,目标差异 0、既有元组删除 0,唯一新增为 P2-03 的 `lsp_platform_aliases.hpp`;P2-04 搬迁文件的归属和编译属性全部保持。 +- 完整本机 GoogleTest 在独立短路径 `N:/a04i/` 完成:5115 项列出、5114 项执行、9 项跳过、0 失败、退出码 0;结果见仓库外 `p2-04-integrated-gtest.json`。 +- 用官方开发启动器启动本次集成目录的 Desktop,再次验证原生桥激活工作区与 UI 文件预览。Desktop PID 56752 / daemon PID 47836 均为该目录产物,正常退出后两个进程均结束,用户原 Desktop PID 13680 保持运行;无屏幕截图。证据为仓库外 `p2-04-integrated-desktop-smoke.json`。 +- [集成版本四平台 CI 36336644249](https://github.com/tmoonlight/acecode/actions/runs/36336644249) 全部构建完成,源码固定为 `aa6872f961b6f4e73210bac0e5de1cb8db9594c9`。逐项结果如下;任务完成标记在 PR 合入后更新。 + +| 平台 | target / 编译元组 | 列出 / 执行 / SKIP / 失败 | +|---|---|---| +| Windows x64 | 59 / 3573 | 5115 / 5108 / 10 / 4 | +| Linux x64 | 50 / 3487 | 5035 / 5026 / 16 / 0 | +| macOS arm64 | 57 / 3632 | 5040 / 5033 / 14 / 10 | +| Deepin x64 | 13 / 1373 | 不配置测试 | + +四平台目标、既有元组和编译属性均保持;相对 post-p0 的新增仅为已验收的 P2-02 抽出物和 P2-03 别名头(正常平台 44、Deepin 20)。用例与 SKIP 集合保持。Deepin provenance 的源码字段仍受容器 Git safe.directory 问题影响为空,已独立核对 build job 108668654269 的 checkout 日志为完整 `aa6872f9` SHA,不把空字段作为来源证明。 + +Windows 保留基线中的 HookRunner / 两个 Python 脚本失败,原有 MCP 失败本次未出现;另有 `AgentLoopTurnSteering.InterruptStartsStructuredTurnBeforeOrdinaryQueue` 在等待第二次 provider 调用的 250ms 断言失败。该项在未集成 P2-04 的原始 P2-05 CI 36334375820 同样失败,两次失败位置完全一致(测试总时长分别 747ms / 884ms)。源码核对确认本 P2-04 对 AgentLoop 仅把 workspace_registry 的 include 改成新模块路径,测试与 stub provider 完全未变;本机完整测试以及本次额外 20 次原断言重复运行全部通过。原始 P2-05 本机也有独立的 20 次通过记录。现有证据指向原有时间窗对 Windows CI 调度速度敏感;保留这项失败及推断依据,未修改、跳过或放宽断言。它不能被记成单测全绿。完整日志与重复记录保存在仓库外 `p2-04-integrated-steering-repeat.log` / `ci/p2-04-integrated/windows-x64/gtest-run.log`。 + +macOS 的 10 项失败均与 post-p0 基线相同,之前记录的 SSE 时序抖动本次未出现。Linux 完整测试为 0 失败。分层违规降至 152 项;P2-04 要消除的 IPC / workspace 反向依赖已消除,后续 P2 任务负责剩余项。 + +补齐 P2-02 / P2-03 / P2-04 六个纯搬迁和 include 提交的 blame-ignore 登记。上述验收补录和登记不改变已验证源码、测试或 CMake。 diff --git a/scripts/layers/size_baseline.txt b/scripts/layers/size_baseline.txt index 2286e74fd..e5b92f547 100644 --- a/scripts/layers/size_baseline.txt +++ b/scripts/layers/size_baseline.txt @@ -19,7 +19,7 @@ src/apps/tui/markdown/mermaid_renderer.cpp 2484 src/apps/tui/settings/management_center.cpp 2146 src/apps/tui/settings/settings_center.cpp 2842 src/apps/tui/tui_helpers.cpp 1386 -src/base/config/config.cpp 2875 +src/base/config/config.cpp 2857 src/base/platform/native_ui/custom_toast_win.cpp 1230 src/domain/experts/expert_registry.cpp 1882 src/domain/sandbox/command_classifier.cpp 1013 diff --git a/src/agent_loop.cpp b/src/agent_loop.cpp index 8797b25fc..9aa68a12d 100644 --- a/src/agent_loop.cpp +++ b/src/agent_loop.cpp @@ -2,7 +2,7 @@ #include "agent_loop_doom_guard.hpp" #include "agent_loop_shell_guard.hpp" #include "computer_use/runtime.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "sandbox/exec_permission.hpp" #include "prompt/context_usage_breakdown.hpp" #include "prompt/system_prompt.hpp" diff --git a/src/channels/runtime.cpp b/src/channels/runtime.cpp index 2ff6723f5..81c3cea88 100644 --- a/src/channels/runtime.cpp +++ b/src/channels/runtime.cpp @@ -1,9 +1,9 @@ #include "runtime.hpp" -#include "config/config.hpp" #include "platform/process/os_process.hpp" #include "remote_control/remote_control_service.hpp" #include "utils/atomic_file.hpp" #include "utils/logger.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/commands/desktop_command.hpp b/src/commands/desktop_command.hpp index 9eec6a3ca..e7ac6bebc 100644 --- a/src/commands/desktop_command.hpp +++ b/src/commands/desktop_command.hpp @@ -1,6 +1,6 @@ #pragma once -#include "desktop/open_request.hpp" +#include "ipc/open_request.hpp" #include #include diff --git a/src/config/config.cpp b/src/config/config.cpp index 0cb859d22..435b987d8 100644 --- a/src/config/config.cpp +++ b/src/config/config.cpp @@ -482,24 +482,6 @@ ModelProfile legacy_model_profile_from_config(const AppConfig& cfg) { return profile; } -std::string get_acecode_dir() { - // 数据目录路径解析全部委托给 paths.cpp,RunMode 决定 User vs Service 根目录 - // (Decision 8)。User 模式行为与历史一致 — TUI / standalone daemon 不受影响。 - return resolve_data_dir(get_run_mode()); -} - -std::string get_run_dir() { - // desktop 多 workspace 模式下 daemon 启动时会调 set_run_dir_override, - // 把 run/ 切到 per-workspace 路径(避免共享 ~/.acecode/run/ 互相覆盖锁文件)。 - auto override_path = get_run_dir_override(); - if (!override_path.empty()) return override_path; - return path_to_utf8(path_from_utf8(get_acecode_dir()) / constants::SUBDIR_RUN); -} - -std::string get_logs_dir() { - return path_to_utf8(path_from_utf8(get_acecode_dir()) / constants::SUBDIR_LOGS); -} - std::vector validate_config(const AppConfig& cfg) { std::vector errors; if (cfg.web.port < 1 || cfg.web.port > 65535) { diff --git a/src/config/config.hpp b/src/config/config.hpp index 4baf5bd86..a0c16153b 100644 --- a/src/config/config.hpp +++ b/src/config/config.hpp @@ -4,6 +4,7 @@ #include "saved_models.hpp" #include "computer_use/pointer_appearance.hpp" #include "utils/constants.hpp" +#include "utils/paths.hpp" #include #include @@ -668,16 +669,6 @@ bool refresh_default_session_preferences_from_config( const std::string& explicit_path = {}, std::string* error = nullptr); -// Get the path to ~/.acecode/ directory -std::string get_acecode_dir(); - -// Get the path to ~/.acecode/run/ (creates it if missing on first call site — -// callers are responsible for filesystem::create_directories when needed). -std::string get_run_dir(); - -// Get the path to ~/.acecode/logs/ (callers handle create_directories). -std::string get_logs_dir(); - // Validate runtime-affecting config values. Returns an empty vector on success; // otherwise each entry is a human-readable error message. Daemon mode callers // should abort on non-empty result. diff --git a/src/daemon/cli.cpp b/src/daemon/cli.cpp index 85a4a4255..c4f88ffba 100644 --- a/src/daemon/cli.cpp +++ b/src/daemon/cli.cpp @@ -2,7 +2,7 @@ #include "cli.hpp" #include "platform/process/os_process.hpp" -#include "runtime_files.hpp" +#include "ipc/runtime_files.hpp" #include "startup_diagnostics.hpp" #include "worker.hpp" #include "cli/interactive_options.hpp" diff --git a/src/daemon/heartbeat.cpp b/src/daemon/heartbeat.cpp index a10fb7d60..285c274fb 100644 --- a/src/daemon/heartbeat.cpp +++ b/src/daemon/heartbeat.cpp @@ -1,6 +1,6 @@ #include "heartbeat.hpp" -#include "runtime_files.hpp" +#include "ipc/runtime_files.hpp" #include "utils/logger.hpp" #include diff --git a/src/daemon/startup_diagnostics.cpp b/src/daemon/startup_diagnostics.cpp index 6c6df58c6..9960eab66 100644 --- a/src/daemon/startup_diagnostics.cpp +++ b/src/daemon/startup_diagnostics.cpp @@ -1,6 +1,6 @@ #include "startup_diagnostics.hpp" -#include "config/config.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/daemon/worker.cpp b/src/daemon/worker.cpp index b02088f31..88d5c485c 100644 --- a/src/daemon/worker.cpp +++ b/src/daemon/worker.cpp @@ -5,20 +5,20 @@ #include "platform/native_ui/folder_picker.hpp" #include "platform/native_ui/context_picker.hpp" #include "environment/terminal_runtime.hpp" -#include "desktop/daemon_protocol.hpp" +#include "ipc/daemon_protocol.hpp" #include "platform/native_ui/open_in_explorer.hpp" #include "version.hpp" #include "tool/spawn_subagent_tool.hpp" #include "tool/thread_tools.hpp" #include "tool/workspace_tools.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "experts/expert_registry.hpp" #include "connectors/connector_first_start_auth.hpp" -#include "guid.hpp" +#include "ipc/guid.hpp" #include "heartbeat.hpp" #include "mcp_runtime.hpp" #include "platform/process/os_process.hpp" -#include "runtime_files.hpp" +#include "ipc/runtime_files.hpp" #include "provider/cwd_model_override.hpp" #include "provider/copilot_provider.hpp" #include "provider/model_pool_status.hpp" diff --git a/src/desktop/agent_browser_host.cpp b/src/desktop/agent_browser_host.cpp index 9b1bad5eb..48a57a843 100644 --- a/src/desktop/agent_browser_host.cpp +++ b/src/desktop/agent_browser_host.cpp @@ -1,7 +1,7 @@ #include "agent_browser_host.hpp" #include "agent_browser_navigation_state.hpp" -#include "agent_browser_runtime.hpp" +#include "ipc/agent_browser_runtime.hpp" #include "window_chrome.hpp" #include "platform/process/os_process.hpp" diff --git a/src/desktop/agent_browser_host_mac.mm b/src/desktop/agent_browser_host_mac.mm index 5b5fc750e..a41604dc6 100644 --- a/src/desktop/agent_browser_host_mac.mm +++ b/src/desktop/agent_browser_host_mac.mm @@ -3,7 +3,7 @@ #ifdef __APPLE__ #include "agent_browser_navigation_state.hpp" -#include "agent_browser_runtime.hpp" +#include "ipc/agent_browser_runtime.hpp" #include "platform/process/os_process.hpp" #include "utils/atomic_file.hpp" diff --git a/src/desktop/daemon_pool.cpp b/src/desktop/daemon_pool.cpp index f0bbd6a48..62043cdce 100644 --- a/src/desktop/daemon_pool.cpp +++ b/src/desktop/daemon_pool.cpp @@ -1,9 +1,9 @@ #include "daemon_pool.hpp" -#include "daemon/guid.hpp" +#include "ipc/guid.hpp" #include "platform/process/os_process.hpp" -#include "daemon/runtime_files.hpp" -#include "daemon_protocol.hpp" +#include "ipc/runtime_files.hpp" +#include "ipc/daemon_protocol.hpp" #include "utils/constants.hpp" #include "utils/logger.hpp" #include "version.hpp" diff --git a/src/desktop/edge_app_launcher.cpp b/src/desktop/edge_app_launcher.cpp index 057439078..611fb0f29 100644 --- a/src/desktop/edge_app_launcher.cpp +++ b/src/desktop/edge_app_launcher.cpp @@ -1,8 +1,8 @@ #include "edge_app_launcher.hpp" -#include "config/config.hpp" #include "utils/encoding.hpp" #include "utils/logger.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/desktop/main.cpp b/src/desktop/main.cpp index bf8ed019b..ea78eb73a 100644 --- a/src/desktop/main.cpp +++ b/src/desktop/main.cpp @@ -15,7 +15,7 @@ #include "daemon_pool.hpp" #include "agent_browser_host.hpp" -#include "agent_browser_runtime.hpp" +#include "ipc/agent_browser_runtime.hpp" #include "context_items.hpp" #include "platform/native_ui/context_picker.hpp" #include "desktop_about.hpp" @@ -26,7 +26,7 @@ #include "platform/native_ui/folder_picker.hpp" #include "platform/locale.hpp" #include "platform/native_ui/notifications.hpp" -#include "open_request.hpp" +#include "ipc/open_request.hpp" #include "platform/native_ui/open_in_explorer.hpp" #include "pick_active.hpp" #include "single_instance.hpp" @@ -40,7 +40,7 @@ #include "url_builder.hpp" #include "web_host.hpp" #include "web_host_close_policy.hpp" -#include "workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #ifdef ACECODE_DEEPIN #include "deepin_window_effects.hpp" @@ -48,7 +48,7 @@ #include "config/config.hpp" #include "platform/process/os_process.hpp" -#include "daemon/runtime_files.hpp" +#include "ipc/runtime_files.hpp" #include "platform/clipboard.hpp" #include "utils/base64.hpp" #include "utils/cwd_hash.hpp" diff --git a/src/desktop/pick_active.hpp b/src/desktop/pick_active.hpp index 43a69b23d..f14e33f96 100644 --- a/src/desktop/pick_active.hpp +++ b/src/desktop/pick_active.hpp @@ -9,7 +9,7 @@ // 注意: 第 1/2 步选中的 hash 必须**仍存在于 registry**;不在 registry 的 hash // 视为无效(目录被删 / scan 没扫到),进入下一优先级。 -#include "workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include diff --git a/src/desktop/single_instance_posix.cpp b/src/desktop/single_instance_posix.cpp index b72dc186c..fab890b76 100644 --- a/src/desktop/single_instance_posix.cpp +++ b/src/desktop/single_instance_posix.cpp @@ -9,8 +9,8 @@ #ifndef _WIN32 -#include "config/config.hpp" #include "utils/logger.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/environment/data_dir_migration.hpp b/src/environment/data_dir_migration.hpp index d1424b9b0..86d6a7d09 100644 --- a/src/environment/data_dir_migration.hpp +++ b/src/environment/data_dir_migration.hpp @@ -24,7 +24,7 @@ // // 纯逻辑(校验、排除规则、阈值)不依赖 web 层,进 acecode_testable 单测。 -#include "daemon/runtime_files.hpp" +#include "ipc/runtime_files.hpp" #include "utils/paths.hpp" #include diff --git a/src/experts/expert_registry.cpp b/src/experts/expert_registry.cpp index f539a60e2..5faa83190 100644 --- a/src/experts/expert_registry.cpp +++ b/src/experts/expert_registry.cpp @@ -1,6 +1,5 @@ #include "expert_registry.hpp" -#include "config/config.hpp" #include "utils/atomic_file.hpp" #include "utils/encoding.hpp" #include "utils/paths.hpp" diff --git a/src/headless/headless_runner.cpp b/src/headless/headless_runner.cpp index fe034f2bf..2dd661d22 100644 --- a/src/headless/headless_runner.cpp +++ b/src/headless/headless_runner.cpp @@ -10,7 +10,7 @@ #include "config/config.hpp" #include "daemon/mcp_runtime.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "hooks/hook_config.hpp" #include "hooks/hook_manager.hpp" #include "lsp/lsp_service.hpp" diff --git a/src/hooks/hook_config.cpp b/src/hooks/hook_config.cpp index 0abca2a5d..9ecbfb669 100644 --- a/src/hooks/hook_config.cpp +++ b/src/hooks/hook_config.cpp @@ -1,8 +1,8 @@ #include "hook_config.hpp" -#include "config/config.hpp" #include "utils/atomic_file.hpp" #include "utils/encoding.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/hooks/hook_registry.cpp b/src/hooks/hook_registry.cpp index 3027a5629..bc0cfa6ae 100644 --- a/src/hooks/hook_registry.cpp +++ b/src/hooks/hook_registry.cpp @@ -1,6 +1,5 @@ #include "hook_registry.hpp" -#include "config/config.hpp" #include "skills/default_skill_seeder.hpp" #include "utils/atomic_file.hpp" #include "utils/encoding.hpp" diff --git a/src/desktop/agent_browser_runtime.cpp b/src/ipc/agent_browser_runtime.cpp similarity index 99% rename from src/desktop/agent_browser_runtime.cpp rename to src/ipc/agent_browser_runtime.cpp index 8f9254013..349a2bdc6 100644 --- a/src/desktop/agent_browser_runtime.cpp +++ b/src/ipc/agent_browser_runtime.cpp @@ -1,7 +1,7 @@ #include "agent_browser_runtime.hpp" -#include "config/config.hpp" #include "utils/atomic_file.hpp" +#include "utils/paths.hpp" #include "utils/url_encoding.hpp" #include "utils/utf8_path.hpp" diff --git a/src/desktop/agent_browser_runtime.hpp b/src/ipc/agent_browser_runtime.hpp similarity index 100% rename from src/desktop/agent_browser_runtime.hpp rename to src/ipc/agent_browser_runtime.hpp diff --git a/src/desktop/daemon_protocol.hpp b/src/ipc/daemon_protocol.hpp similarity index 100% rename from src/desktop/daemon_protocol.hpp rename to src/ipc/daemon_protocol.hpp diff --git a/src/daemon/guid.hpp b/src/ipc/guid.hpp similarity index 100% rename from src/daemon/guid.hpp rename to src/ipc/guid.hpp diff --git a/src/desktop/open_request.cpp b/src/ipc/open_request.cpp similarity index 99% rename from src/desktop/open_request.cpp rename to src/ipc/open_request.cpp index 97c6e5c4c..d18672938 100644 --- a/src/desktop/open_request.cpp +++ b/src/ipc/open_request.cpp @@ -1,7 +1,7 @@ #include "open_request.hpp" -#include "config/config.hpp" #include "utils/atomic_file.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include "utils/uuid.hpp" diff --git a/src/desktop/open_request.hpp b/src/ipc/open_request.hpp similarity index 100% rename from src/desktop/open_request.hpp rename to src/ipc/open_request.hpp diff --git a/src/daemon/runtime_files.cpp b/src/ipc/runtime_files.cpp similarity index 99% rename from src/daemon/runtime_files.cpp rename to src/ipc/runtime_files.cpp index ffe2d3cfd..476d72ccc 100644 --- a/src/daemon/runtime_files.cpp +++ b/src/ipc/runtime_files.cpp @@ -1,9 +1,9 @@ #include "runtime_files.hpp" -#include "config/config.hpp" #include "utils/atomic_file.hpp" #include "utils/constants.hpp" #include "utils/logger.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include "platform/process/os_process.hpp" diff --git a/src/daemon/runtime_files.hpp b/src/ipc/runtime_files.hpp similarity index 100% rename from src/daemon/runtime_files.hpp rename to src/ipc/runtime_files.hpp diff --git a/src/loop/loop_store.cpp b/src/loop/loop_store.cpp index e5fc871a0..1cb6b3f50 100644 --- a/src/loop/loop_store.cpp +++ b/src/loop/loop_store.cpp @@ -1,6 +1,6 @@ #include "loop_store.hpp" -#include "config/config.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include "utils/uuid.hpp" diff --git a/src/main.cpp b/src/main.cpp index 0773081b0..6938c8c0b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -186,7 +186,7 @@ #include "session/session_storage.hpp" #include "session/compact_notice.hpp" #include "history/input_history_store.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include #include diff --git a/src/memory/memory_paths.cpp b/src/memory/memory_paths.cpp index a12542554..a3b09345f 100644 --- a/src/memory/memory_paths.cpp +++ b/src/memory/memory_paths.cpp @@ -1,6 +1,6 @@ #include "memory_paths.hpp" -#include "config/config.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/path_reference/path_reference.cpp b/src/path_reference/path_reference.cpp index 3e8d86f7c..e750c9e4c 100644 --- a/src/path_reference/path_reference.cpp +++ b/src/path_reference/path_reference.cpp @@ -1,6 +1,6 @@ #include "path_reference.hpp" -#include "web/handlers/files_handler.hpp" +#include "workspace/files_handler.hpp" #include #include diff --git a/src/provider/auth/github_auth.cpp b/src/provider/auth/github_auth.cpp index 50bfa8a55..d1ebe9e27 100644 --- a/src/provider/auth/github_auth.cpp +++ b/src/provider/auth/github_auth.cpp @@ -1,6 +1,6 @@ #include "github_auth.hpp" -#include "config/config.hpp" #include "network/proxy_resolver.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/provider/auth/xai_auth.cpp b/src/provider/auth/xai_auth.cpp index 9a4f2a4b6..c736eeed0 100644 --- a/src/provider/auth/xai_auth.cpp +++ b/src/provider/auth/xai_auth.cpp @@ -1,8 +1,8 @@ #include "xai_auth.hpp" -#include "config/config.hpp" #include "network/proxy_resolver.hpp" #include "utils/atomic_file.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/session/global_session_catalog.cpp b/src/session/global_session_catalog.cpp index e7e8d17d3..7eb4cf524 100644 --- a/src/session/global_session_catalog.cpp +++ b/src/session/global_session_catalog.cpp @@ -1,6 +1,6 @@ #include "global_session_catalog.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "utils/cwd_hash.hpp" #include "utils/utf8_path.hpp" diff --git a/src/session/global_session_search.cpp b/src/session/global_session_search.cpp index 0bdda067b..01d44cffc 100644 --- a/src/session/global_session_search.cpp +++ b/src/session/global_session_search.cpp @@ -1,7 +1,7 @@ #include "global_session_search.hpp" #include "session_user_message_search.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/session/session_storage.cpp b/src/session/session_storage.cpp index a4d990ca3..2f820766f 100644 --- a/src/session/session_storage.cpp +++ b/src/session/session_storage.cpp @@ -3,10 +3,10 @@ #include "session_serializer.hpp" #include "session_title_generator.hpp" #include "task_suggestion_store.hpp" -#include "config/config.hpp" #include "llm/context_usage.hpp" #include "utils/atomic_file.hpp" #include "utils/cwd_hash.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/session/thread_service.cpp b/src/session/thread_service.cpp index 6c77197b0..634ef5bd1 100644 --- a/src/session/thread_service.cpp +++ b/src/session/thread_service.cpp @@ -9,9 +9,9 @@ #include "thread_repair.hpp" #include "llm/message_predicates.hpp" #include "llm/token_estimate.hpp" -#include "config/config.hpp" #include "utils/encoding.hpp" #include "utils/logger.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/tool/agent_browser/browser_tools.cpp b/src/tool/agent_browser/browser_tools.cpp index cddec6b2d..2b9efcc62 100644 --- a/src/tool/agent_browser/browser_tools.cpp +++ b/src/tool/agent_browser/browser_tools.cpp @@ -2,7 +2,7 @@ #include "cdp_client.hpp" -#include "desktop/agent_browser_runtime.hpp" +#include "ipc/agent_browser_runtime.hpp" #include "utils/logger.hpp" #include "utils/utf8_path.hpp" diff --git a/src/tool/agent_browser/cdp_client.cpp b/src/tool/agent_browser/cdp_client.cpp index 17ba68d06..f6638cc56 100644 --- a/src/tool/agent_browser/cdp_client.cpp +++ b/src/tool/agent_browser/cdp_client.cpp @@ -1,7 +1,7 @@ #include "cdp_client.hpp" #include "platform/process/os_process.hpp" -#include "desktop/agent_browser_runtime.hpp" +#include "ipc/agent_browser_runtime.hpp" #include "utils/encoding.hpp" #include diff --git a/src/tool/theme_create_tool.cpp b/src/tool/theme_create_tool.cpp index 5f62b2db2..51882858d 100644 --- a/src/tool/theme_create_tool.cpp +++ b/src/tool/theme_create_tool.cpp @@ -1,9 +1,9 @@ #include "theme_create_tool.hpp" -#include "config/config.hpp" #include "headless/headless_mode.hpp" #include "session/session_manager.hpp" #include "themes/theme_drafts.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" namespace acecode { diff --git a/src/tool/workspace_tools.cpp b/src/tool/workspace_tools.cpp index 4cedb41e9..a0ebaead9 100644 --- a/src/tool/workspace_tools.cpp +++ b/src/tool/workspace_tools.cpp @@ -1,6 +1,6 @@ #include "workspace_tools.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "utils/tool_args_parser.hpp" #include "utils/utf8_path.hpp" diff --git a/src/tui/settings/settings_center.cpp b/src/tui/settings/settings_center.cpp index 88cf9f14a..200757c73 100644 --- a/src/tui/settings/settings_center.cpp +++ b/src/tui/settings/settings_center.cpp @@ -9,7 +9,7 @@ #include "permissions.hpp" #include "config/request_headers.hpp" #include "config/settings_mutations.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "network/proxy_resolver.hpp" #include "provider/auth/github_auth.hpp" #include "session/session_storage.hpp" diff --git a/src/upgrade/apply.cpp b/src/upgrade/apply.cpp index 54d35734b..3a04feb80 100644 --- a/src/upgrade/apply.cpp +++ b/src/upgrade/apply.cpp @@ -4,7 +4,7 @@ #include "platform/terminal/console.hpp" #include "diagnostics.hpp" #include "package.hpp" -#include "config/config.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/upgrade/diagnostics.cpp b/src/upgrade/diagnostics.cpp index db9e2b301..a752c1542 100644 --- a/src/upgrade/diagnostics.cpp +++ b/src/upgrade/diagnostics.cpp @@ -1,8 +1,8 @@ #include "diagnostics.hpp" #include "apply.hpp" -#include "config/config.hpp" #include "utils/logger.hpp" +#include "utils/paths.hpp" #include "utils/utf8_path.hpp" #include diff --git a/src/utils/paths.cpp b/src/utils/paths.cpp index 4d82a0d0f..ef41f0959 100644 --- a/src/utils/paths.cpp +++ b/src/utils/paths.cpp @@ -1,6 +1,7 @@ #include "paths.hpp" #include "atomic_file.hpp" +#include "constants.hpp" #include "encoding.hpp" #include "logger.hpp" #include "utf8_path.hpp" @@ -352,6 +353,24 @@ std::string get_run_dir_override() { return g_run_dir_override; } +std::string get_acecode_dir() { + // 数据目录路径解析全部委托给 paths.cpp,RunMode 决定 User vs Service 根目录 + // (Decision 8)。User 模式行为与历史一致 — TUI / standalone daemon 不受影响。 + return resolve_data_dir(get_run_mode()); +} + +std::string get_run_dir() { + // desktop 多 workspace 模式下 daemon 启动时会调 set_run_dir_override, + // 把 run/ 切到 per-workspace 路径(避免共享 ~/.acecode/run/ 互相覆盖锁文件)。 + auto override_path = get_run_dir_override(); + if (!override_path.empty()) return override_path; + return path_to_utf8(path_from_utf8(get_acecode_dir()) / constants::SUBDIR_RUN); +} + +std::string get_logs_dir() { + return path_to_utf8(path_from_utf8(get_acecode_dir()) / constants::SUBDIR_LOGS); +} + RunMode override_run_mode_for_test(RunMode mode) { RunMode prev = g_mode.load(); g_mode.store(mode); diff --git a/src/utils/paths.hpp b/src/utils/paths.hpp index 65c27f901..27fe184ab 100644 --- a/src/utils/paths.hpp +++ b/src/utils/paths.hpp @@ -103,7 +103,7 @@ void log_deferred_data_dir_resolution_warning(); // 的解析告警,避免跨测试污染。 void reset_data_dir_cache_for_test(); -// 进程级 run/ 目录覆盖。非空时 config::get_run_dir() 直接返回这个,而不再 +// 进程级 run/ 目录覆盖。非空时 get_run_dir() 直接返回这个,而不再 // 用 /run/ 默认。 // // 用途: desktop 多 workspace 模式下,每个 workspace 的 daemon 必须有独立的 @@ -119,6 +119,17 @@ void reset_data_dir_cache_for_test(); void set_run_dir_override(const std::string& path); std::string get_run_dir_override(); +// ── 数据目录快捷函数(原 config.hpp,refactor20260927 P2-04 移到这里;运行期行为不变) +// Get the path to ~/.acecode/ directory +std::string get_acecode_dir(); + +// Get the path to ~/.acecode/run/ (creates it if missing on first call site — +// callers are responsible for filesystem::create_directories when needed). +std::string get_run_dir(); + +// Get the path to ~/.acecode/logs/ (callers handle create_directories). +std::string get_logs_dir(); + // === 测试专用 helper(只在测试代码用,生产路径不应调) === // 直接覆盖当前 RunMode,绕过 once-only 保护;返回原值方便 test fixture 还原。 diff --git a/src/web/handlers/git_handler.cpp b/src/web/handlers/git_handler.cpp index c12ac8a5d..90e8c062f 100644 --- a/src/web/handlers/git_handler.cpp +++ b/src/web/handlers/git_handler.cpp @@ -2,7 +2,7 @@ #include "gitinfo/git_context_collector.hpp" #include "gitinfo/git_context_core.hpp" -#include "files_handler.hpp" +#include "workspace/files_handler.hpp" #include #include diff --git a/src/web/server_impl.hpp b/src/web/server_impl.hpp index f9d25e73f..2ef5162b3 100644 --- a/src/web/server_impl.hpp +++ b/src/web/server_impl.hpp @@ -13,7 +13,7 @@ #include "config/saved_models_editor.hpp" #include "saved_model_reasoning_sync.hpp" #include "config/request_headers.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "hooks/hook_manager.hpp" #include "environment/data_dir_migration.hpp" #include "loop/loop_store.hpp" @@ -49,7 +49,7 @@ #include "utils/base64.hpp" #include "utils/cwd_hash.hpp" #include "platform/terminal/terminal_title.hpp" -#include "web/handlers/files_handler.hpp" +#include "workspace/files_handler.hpp" #include "web/handlers/fork_handler.hpp" #include "web/handlers/history_handler.hpp" #include "web/handlers/grok_auth_handler.hpp" diff --git a/src/web/handlers/files_handler.cpp b/src/workspace/files_handler.cpp similarity index 100% rename from src/web/handlers/files_handler.cpp rename to src/workspace/files_handler.cpp diff --git a/src/web/handlers/files_handler.hpp b/src/workspace/files_handler.hpp similarity index 100% rename from src/web/handlers/files_handler.hpp rename to src/workspace/files_handler.hpp diff --git a/src/desktop/workspace_registry.cpp b/src/workspace/workspace_registry.cpp similarity index 100% rename from src/desktop/workspace_registry.cpp rename to src/workspace/workspace_registry.cpp diff --git a/src/desktop/workspace_registry.hpp b/src/workspace/workspace_registry.hpp similarity index 100% rename from src/desktop/workspace_registry.hpp rename to src/workspace/workspace_registry.hpp diff --git a/tests/agent_loop/agent_loop_tool_lifecycle_events_test.cpp b/tests/agent_loop/agent_loop_tool_lifecycle_events_test.cpp index 03a89fed6..026659902 100644 --- a/tests/agent_loop/agent_loop_tool_lifecycle_events_test.cpp +++ b/tests/agent_loop/agent_loop_tool_lifecycle_events_test.cpp @@ -5,7 +5,7 @@ #include #include "agent_loop.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "permissions.hpp" #include "llm/llm_provider.hpp" #include "session/event_dispatcher.hpp" diff --git a/tests/cpp_source_paths.json b/tests/cpp_source_paths.json index fd11323a6..6b1a3fb09 100644 --- a/tests/cpp_source_paths.json +++ b/tests/cpp_source_paths.json @@ -6,8 +6,8 @@ "desktop/agent_browser_navigation_state.cpp": "src/desktop/agent_browser_navigation_state.cpp", "desktop/agent_browser_navigation_state.hpp": "src/desktop/agent_browser_navigation_state.hpp", "desktop/agent_browser_page_directory.hpp": "src/desktop/agent_browser_page_directory.hpp", - "desktop/agent_browser_runtime.cpp": "src/desktop/agent_browser_runtime.cpp", - "desktop/agent_browser_runtime.hpp": "src/desktop/agent_browser_runtime.hpp", + "desktop/agent_browser_runtime.cpp": "src/ipc/agent_browser_runtime.cpp", + "desktop/agent_browser_runtime.hpp": "src/ipc/agent_browser_runtime.hpp", "desktop/context_picker.cpp": "src/platform/native_ui/context_picker.cpp", "desktop/main.cpp": "src/desktop/main.cpp", "desktop/splash_screen.cpp": "src/desktop/splash_screen.cpp", diff --git a/tests/desktop/daemon_pool_test.cpp b/tests/desktop/daemon_pool_test.cpp index f623665c9..c627cb5be 100644 --- a/tests/desktop/daemon_pool_test.cpp +++ b/tests/desktop/daemon_pool_test.cpp @@ -6,7 +6,7 @@ #include #include "platform/process/os_process.hpp" -#include "daemon/runtime_files.hpp" +#include "ipc/runtime_files.hpp" #include "desktop/daemon_pool.hpp" #include "desktop/daemon_supervisor.hpp" diff --git a/tests/desktop/helpers/upgrade_restart_smoke.cpp b/tests/desktop/helpers/upgrade_restart_smoke.cpp index 28e6e801a..48ebbb2ad 100644 --- a/tests/desktop/helpers/upgrade_restart_smoke.cpp +++ b/tests/desktop/helpers/upgrade_restart_smoke.cpp @@ -1,9 +1,9 @@ // Opt-in runtime regression with an old packaged daemon and the new daemon. // The caller supplies an isolated USERPROFILE/HOME and temporary run directory. #include "platform/process/os_process.hpp" -#include "daemon/runtime_files.hpp" +#include "ipc/runtime_files.hpp" #include "desktop/daemon_pool.hpp" -#include "desktop/daemon_protocol.hpp" +#include "ipc/daemon_protocol.hpp" #include "desktop/daemon_supervisor.hpp" #include "version.hpp" diff --git a/tests/desktop/pick_active_test.cpp b/tests/desktop/pick_active_test.cpp index e79c63e11..060d96e40 100644 --- a/tests/desktop/pick_active_test.cpp +++ b/tests/desktop/pick_active_test.cpp @@ -4,7 +4,7 @@ #include #include "desktop/pick_active.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "utils/cwd_hash.hpp" #include diff --git a/tests/desktop/workspace_profile_test.cpp b/tests/desktop/workspace_profile_test.cpp index edc18008c..fd8f0b123 100644 --- a/tests/desktop/workspace_profile_test.cpp +++ b/tests/desktop/workspace_profile_test.cpp @@ -5,7 +5,7 @@ #include -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "utils/cwd_hash.hpp" #include "utils/utf8_path.hpp" diff --git a/tests/desktop/agent_browser_runtime_test.cpp b/tests/ipc/agent_browser_runtime_test.cpp similarity index 99% rename from tests/desktop/agent_browser_runtime_test.cpp rename to tests/ipc/agent_browser_runtime_test.cpp index 4b5d5d194..f2a0b40c5 100644 --- a/tests/desktop/agent_browser_runtime_test.cpp +++ b/tests/ipc/agent_browser_runtime_test.cpp @@ -1,6 +1,6 @@ #include -#include "desktop/agent_browser_runtime.hpp" +#include "ipc/agent_browser_runtime.hpp" #include "utils/utf8_path.hpp" #include diff --git a/tests/desktop/open_request_test.cpp b/tests/ipc/open_request_test.cpp similarity index 99% rename from tests/desktop/open_request_test.cpp rename to tests/ipc/open_request_test.cpp index 1571ab3f4..27189a4f8 100644 --- a/tests/desktop/open_request_test.cpp +++ b/tests/ipc/open_request_test.cpp @@ -1,6 +1,6 @@ #include -#include "desktop/open_request.hpp" +#include "ipc/open_request.hpp" #include #include diff --git a/tests/daemon/runtime_files_test.cpp b/tests/ipc/runtime_files_test.cpp similarity index 99% rename from tests/daemon/runtime_files_test.cpp rename to tests/ipc/runtime_files_test.cpp index dba8c4bf5..1fa3d5d31 100644 --- a/tests/daemon/runtime_files_test.cpp +++ b/tests/ipc/runtime_files_test.cpp @@ -1,7 +1,7 @@ #include #include "platform/process/os_process.hpp" -#include "daemon/runtime_files.hpp" +#include "ipc/runtime_files.hpp" #include #include diff --git a/tests/tool/workspace_tools_test.cpp b/tests/tool/workspace_tools_test.cpp index 73283cc5f..e83a10415 100644 --- a/tests/tool/workspace_tools_test.cpp +++ b/tests/tool/workspace_tools_test.cpp @@ -1,6 +1,6 @@ #include -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "session/session_manager.hpp" #include "tool/workspace_tools.hpp" #include "utils/utf8_path.hpp" diff --git a/tests/utils/paths_test.cpp b/tests/utils/paths_test.cpp index 70e9f0000..1154c286e 100644 --- a/tests/utils/paths_test.cpp +++ b/tests/utils/paths_test.cpp @@ -11,7 +11,6 @@ #include -#include "config/config.hpp" #include "utils/paths.hpp" #include diff --git a/tests/web/web_server_smoke_test.cpp b/tests/web/web_server_smoke_test.cpp index c983c8206..2dc5ac70b 100644 --- a/tests/web/web_server_smoke_test.cpp +++ b/tests/web/web_server_smoke_test.cpp @@ -32,7 +32,7 @@ #include "config/saved_models_revision.hpp" #include "permissions.hpp" #include "desktop/daemon_supervisor.hpp" -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "experts/expert_registry.hpp" #include "hooks/hook_manager.hpp" #include "loop/loop_store.hpp" diff --git a/tests/web/files_handler_test.cpp b/tests/workspace/files_handler_test.cpp similarity index 99% rename from tests/web/files_handler_test.cpp rename to tests/workspace/files_handler_test.cpp index 7e1552d61..293cd6a8a 100644 --- a/tests/web/files_handler_test.cpp +++ b/tests/workspace/files_handler_test.cpp @@ -9,7 +9,7 @@ #include -#include "web/handlers/files_handler.hpp" +#include "workspace/files_handler.hpp" #include "utils/encoding.hpp" #include diff --git a/tests/desktop/workspace_registry_test.cpp b/tests/workspace/workspace_registry_test.cpp similarity index 99% rename from tests/desktop/workspace_registry_test.cpp rename to tests/workspace/workspace_registry_test.cpp index 03e4cb2d3..227dc1e2f 100644 --- a/tests/desktop/workspace_registry_test.cpp +++ b/tests/workspace/workspace_registry_test.cpp @@ -4,7 +4,7 @@ #include -#include "desktop/workspace_registry.hpp" +#include "workspace/workspace_registry.hpp" #include "session/session_storage.hpp" #include "utils/cwd_hash.hpp" diff --git a/web/README.md b/web/README.md index 37e62bfda..23438c04f 100644 --- a/web/README.md +++ b/web/README.md @@ -140,4 +140,4 @@ bundle 体积 ~461KB(gzip ~156KB)。嵌入二进制约 +600KB(hex 编码 2x)。 ## 历史 -本项目 v1 是原生 ES Modules + Custom Elements + Bootstrap,单点 11 个 `` 元素 + 手写 `style.css`。重构 PR 把全部前端换成 React + Vite + Tailwind v4,保留 `lib/api.js` / `lib/auth.js` / `lib/connection.js` 的协议层不变,daemon 端 0 改动。后续 `enhance-webui-chat-rendering` 把 `lib/markdown.js` 从手写极简版升级到 markdown-it 管线,Message 加 hover copy/fork actions,ToolBlock 引入 diff2html 渲染 hunks。再后 `add-webui-side-panel` 在单会话视图右侧加固定 280px 的 SidePanel(文件 / 变更 / 预览 三 tab),后端新增 `GET /api/files` + `GET /api/files/content` 两个端点(`src/web/handlers/files_handler.{hpp,cpp}` 纯函数 + 17 个 unit test),前端抽 `lib/diff.js` / `lib/lang.js` / `lib/sessionChanges.js` 三个共用模块。当前 SidePanel 已拆成右侧 `更改` / `文件` 导航面板和中间 `PreviewDetailsPanel`:文件 tab 按 workspace/cwd 保留,会话更改 tab 按 session id 保留,关闭整个预览面板会清掉当前可见 tab 集。 +本项目 v1 是原生 ES Modules + Custom Elements + Bootstrap,单点 11 个 `` 元素 + 手写 `style.css`。重构 PR 把全部前端换成 React + Vite + Tailwind v4,保留 `lib/api.js` / `lib/auth.js` / `lib/connection.js` 的协议层不变,daemon 端 0 改动。后续 `enhance-webui-chat-rendering` 把 `lib/markdown.js` 从手写极简版升级到 markdown-it 管线,Message 加 hover copy/fork actions,ToolBlock 引入 diff2html 渲染 hunks。再后 `add-webui-side-panel` 在单会话视图右侧加固定 280px 的 SidePanel(文件 / 变更 / 预览 三 tab),后端新增 `GET /api/files` + `GET /api/files/content` 两个端点(`src/workspace/files_handler.{hpp,cpp}` 纯函数 + 17 个 unit test),前端抽 `lib/diff.js` / `lib/lang.js` / `lib/sessionChanges.js` 三个共用模块。当前 SidePanel 已拆成右侧 `更改` / `文件` 导航面板和中间 `PreviewDetailsPanel`:文件 tab 按 workspace/cwd 保留,会话更改 tab 按 session id 保留,关闭整个预览面板会清掉当前可见 tab 集。