diff --git a/CMakeLists.txt b/CMakeLists.txt index 340d2ab..8c40c2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,16 +11,19 @@ option(DSTALK_BUILD_GUI "Build the SDL3 GUI frontend" OFF) option(DSTALK_BUILD_WEB "Build the web UI frontend" OFF) option(DSTALK_BUILD_TESTS "Build dstalk tests" ON) -add_subdirectory(dstalk-core) -add_subdirectory(dstalk-cli) -add_subdirectory(plugins) +add_subdirectory(dstalk_core) +add_subdirectory(dstalk_cli) +# 插件按依赖层级分三个目录 / Plugins split into three directories by dependency tier +add_subdirectory(plugins_base) +add_subdirectory(plugins_middle) +add_subdirectory(plugins_upper) if(DSTALK_BUILD_GUI) - add_subdirectory(dstalk-gui) + add_subdirectory(dstalk_gui) endif() if(DSTALK_BUILD_WEB) - add_subdirectory(dstalk-web) + add_subdirectory(dstalk_web) endif() if(DSTALK_BUILD_TESTS) diff --git a/README.md b/README.md index 9683643..e0b29ba 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ dstalk 是一款 AI 编程助手命令行工具, 通过调用大模型在终端 ┌───────────────────────────────────────────────────────────┐ │ 前端层 (Frontends) │ │ ┌──────────────────┐ ┌──────────────────────────┐ │ -│ │ dstalk-cli │ │ dstalk-gui │ │ +│ │ dstalk_cli │ │ dstalk_gui │ │ │ │ ANSI 终端 UI │ │ SDL3 图形化 UI │ │ │ └────────┬─────────┘ └─────────────┬─────────────┘ │ │ └──────────────┬───────────────┘ │ @@ -24,7 +24,7 @@ dstalk 是一款 AI 编程助手命令行工具, 通过调用大模型在终端 └──────────────────────────┼─────────────────────────────────┘ │ ┌──────────────────────────▼─────────────────────────────────┐ -│ 核心层 (dstalk-core.dll) — 插件宿主 │ +│ 核心层 (dstalk_core.dll) — 插件宿主 │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Host: 插件加载 · 服务注册 · 事件总线 · 配置管理 │ │ │ └──────────────────────────────────────────────────────┘ │ @@ -33,15 +33,15 @@ dstalk 是一款 AI 编程助手命令行工具, 通过调用大模型在终端 │ │ (ai) │ │ (ai) │ │ (http) │ │ 客户端 │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │ -│ │ session │ │ context │ │ file-io │ │ tools │ │ +│ │ session │ │ context │ │ file_io │ │ tools │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` -- **dstalk-core** —— C11/C++20 插件化宿主 DLL, 负责插件加载、服务注册、事件总线、配置管理 -- **dstalk-cli** —— 命令行前端, ANSI 终端 UI -- **dstalk-gui** —— 图形化前端, SDL3 跨平台窗口 -- **plugins/** —— 9 个功能插件, 编译为独立 DLL, 通过 C ABI 动态注册服务 +- **dstalk_core** —— C11/C++20 插件化宿主 DLL, 负责插件加载、服务注册、事件总线、配置管理 +- **dstalk_cli** —— 命令行前端, ANSI 终端 UI +- **dstalk_gui** —— 图形化前端, SDL3 跨平台窗口 +- **plugins_base/、plugins_middle/、plugins_upper/** —— 9 个功能插件按三层架构分布, 编译为独立 DLL, 通过 C ABI 动态注册服务 核心与界面完全解耦, 可编写自己的前端或把 AI 能力嵌入到现有工具中。 @@ -65,7 +65,7 @@ dstalk 是一款 AI 编程助手命令行工具, 通过调用大模型在终端 cd tools && setup.bat # 1. 安装工具链 (CMake / Ninja / LLVM / Conan2) build.bat # 2. 编译 # 3. 创建 config.toml # 见教程: docs/tutorial/quick-start.md -build/dstalk-cli/dstalk-cli.exe # 4. 运行 +build/dstalk_cli/dstalk_cli.exe # 4. 运行 # 5. 输入自然语言 # "帮我写一个 C 程序" ``` diff --git a/build.bat b/build.bat index 2333614..471ce42 100644 --- a/build.bat +++ b/build.bat @@ -140,7 +140,7 @@ if !errorlevel! neq 0 ( echo. echo ============================================ echo 编译成功! -echo build\dstalk-core\dstalk.dll -echo build\dstalk-cli\dstalk-cli.exe +echo build\bin\dstalk.dll +echo build\bin\dstalk_cli.exe echo ============================================ pause diff --git a/docs/explanation/architecture.md b/docs/explanation/architecture.md index fb06424..5d63d13 100644 --- a/docs/explanation/architecture.md +++ b/docs/explanation/architecture.md @@ -13,7 +13,7 @@ dstalk 选择的不是单体架构,而是**以 C ABI 为边界的插件架构* 2. **能力会增长**。LSP 集成、文件管理、会话持久化、工具调用——这些能力不是 CLI 启动时必须加载的。使用者可能只需要聊天,不需要 LSP。插件架构让能力按需加载,启动更快,内存更省。 -3. **插件作者不是核心团队**。第三方应该能用自己的编译器、自己的 C++ 标准库版本编写插件,而不必须链接 dstalk-core 的静态库。这要求 ABI 稳定。C ABI 是唯一具有跨编译器二进制兼容性的选择。 +3. **插件作者不是核心团队**。第三方应该能用自己的编译器、自己的 C++ 标准库版本编写插件,而不必须链接 dstalk_core 的静态库。这要求 ABI 稳定。C ABI 是唯一具有跨编译器二进制兼容性的选择。 **一句话心智模型**: 不要想象一个胖二进制把所有功能静态链接在一起;想象一个内核 (host) + 一圈可插拔的服务单元 (plugin),内核只负责编排,不负责实现。 @@ -29,7 +29,7 @@ dstalk 的架构由 3 层组成。从上到下看,每一层依赖下一层提 │ 实现具体能力:AI 聊天、文件读写、LSP... │ │ 通过服务注册表向其他插件暴露自己的功能 │ ├────────────────────────────────────────────┤ -│ Host (dstalk-core) │ +│ Host (dstalk_core) │ │ 拥有事件总线、服务注册表、插件加载器、配置 │ │ 提供一个 dstalk_host_api_t 接口给所有插件 │ ├────────────────────────────────────────────┤ @@ -48,7 +48,7 @@ Host 拥有四样东西: - **配置存储 (ConfigStore)**: 管理 `config.toml` 的加载和键值查询。 - **事件总线 (EventBus)**: 插件间松耦合通信的唯一通道。 - **服务注册表 (ServiceRegistry)**: 按名称 + 版本号存储和查找服务 vtable。 -- **插件加载器 (PluginLoader)**: 扫描 `plugins/` 目录、加载 DLL、按依赖拓扑排序后调用初始化。 +- **插件加载器 (PluginLoader)**: 扫描 `plugins_base/`、`plugins_middle/`、`plugins_upper/` 三层目录、加载 DLL、按依赖拓扑排序后调用初始化。 Host 启动时,按严格顺序执行: 1. 分配上述四个组件。 diff --git a/docs/explanation/plugin-lifecycle.md b/docs/explanation/plugin-lifecycle.md index 2ea440c..5e08734 100644 --- a/docs/explanation/plugin-lifecycle.md +++ b/docs/explanation/plugin-lifecycle.md @@ -52,7 +52,7 @@ Host 调用 `load_plugin(path)`,由 `PluginLoader` 执行: { "http", "config", NULL } ``` -依赖名称与目标插件的 `info->name` 字段匹配(如 `"file-io"` 不是 DLL 的文件名),因此依赖声明和插件命名必须一致。 +依赖名称与目标插件的 `info->name` 字段匹配(如 `"file_io"` 不是 DLL 的文件名),因此依赖声明和插件命名必须一致。 --- diff --git a/docs/explanation/security-logging.md b/docs/explanation/security-logging.md index f07a48c..036ed20 100644 --- a/docs/explanation/security-logging.md +++ b/docs/explanation/security-logging.md @@ -18,7 +18,7 @@ ## 文件清单 -### 1. `plugins/openai/src/openai_plugin.cpp` -- 安全 +### 1. `plugins_upper/openai/src/openai_plugin.cpp` -- 安全 | 行号 | 调用 | 内容 | 风险 | |------|------|------|------| @@ -31,7 +31,7 @@ **parse_response() 错误路径 (行 135-151)**: HTTP 错误响应体仅用于提取 JSON `error.message` 字段放入 `r.error`,不会输出到日志。原始 response_body 在解析后被 `g_host->free()` 释放。 -### 2. `plugins/anthropic/src/anthropic_plugin.cpp` -- 安全 +### 2. `plugins_upper/anthropic/src/anthropic_plugin.cpp` -- 安全 | 行号 | 调用 | 内容 | 风险 | |------|------|------|------| @@ -42,7 +42,7 @@ **build_headers_json() (行 59-65)**: 构建 `{"x-api-key":"","anthropic-version":"2023-06-01"}` 仅用于 HTTP 请求,不经过日志路径。 -### 3. `plugins/network/src/network_plugin.cpp` -- 安全 +### 3. `plugins_middle/network/src/network_plugin.cpp` -- 安全 | 行号 | 调用 | 内容 | 风险 | |------|------|------|------| @@ -52,7 +52,7 @@ **do_post_stream() 异常路径 (行 280-282)**: `catch (std::exception& e)` 将 `e.what()` 赋值给 `result_body`。Beast/ASIO 异常消息为 OS 级别错误描述(如 "Connection refused"),不含 HTTP header/body 内容。 -### 4. `plugins/config/src/config_plugin.cpp` -- 安全 +### 4. `plugins_base/config/src/config_plugin.cpp` -- 安全 | 行号 | 调用 | 内容 | 风险 | |------|------|------|------| @@ -60,7 +60,7 @@ ConfigStore 仅提供 get/set/load_file,无日志输出。 -### 5. `dstalk-core/src/host.cpp` -- 基础设施(不动) +### 5. `dstalk_core/src/host.cpp` -- 基础设施(不动) | 行号 | 调用 | 内容 | 风险 | |------|------|------|------| @@ -68,13 +68,13 @@ ConfigStore 仅提供 get/set/load_file,无日志输出。 该文件是日志基础设施 (`host_log_impl`),仅负责格式化输出。安全性依赖于调用方不传敏感数据(本审计已确认所有调用方均安全)。按 W9.3 禁忌不修改此文件。 -### 6. `dstalk-core/src/plugin_loader.cpp` -- 安全 +### 6. `dstalk_core/src/plugin_loader.cpp` -- 安全 | 行号 | 调用 | 内容 | 风险 | |------|------|------|------| | -- | 无任何日志调用 | -- | 无 | -### 7. `plugins/session/src/session_plugin.cpp` -- 安全 +### 7. `plugins_middle/session/src/session_plugin.cpp` -- 安全 | 行号 | 调用 | 内容 | 风险 | |------|------|------|------| @@ -82,7 +82,7 @@ ConfigStore 仅提供 get/set/load_file,无日志输出。 该插件处理消息内容(role/content)但不记录任何消息数据到日志。 -### 8. `plugins/lsp/src/lsp_plugin.cpp` -- 低风险 +### 8. `plugins_base/lsp/src/lsp_plugin.cpp` -- 低风险 | 行号 | 调用 | 内容 | 风险 | |------|------|------|------| diff --git a/docs/tutorial/quick-start.md b/docs/tutorial/quick-start.md index ce8da84..27bb8ee 100644 --- a/docs/tutorial/quick-start.md +++ b/docs/tutorial/quick-start.md @@ -32,8 +32,8 @@ build.bat ``` 编译产物输出到 `build/` 目录。核心产物: -- `build/dstalk-core/dstalk.dll` —— 核心 DLL -- `build/dstalk-cli/dstalk-cli.exe` —— 命令行前端 +- `build/dstalk_core/dstalk.dll` —— 核心 DLL +- `build/dstalk_cli/dstalk_cli.exe` —— 命令行前端 - `build/plugins/*.dll` —— 功能插件 --- @@ -69,10 +69,10 @@ api.model = "gpt-4o" --- -## 4. 运行 dstalk-cli +## 4. 运行 dstalk_cli ```bash -build/dstalk-cli/dstalk-cli.exe +build/dstalk_cli/dstalk_cli.exe ``` 启动后显示欢迎横幅: diff --git a/dstalk-cli/CMakeLists.txt b/dstalk_cli/CMakeLists.txt similarity index 65% rename from dstalk-cli/CMakeLists.txt rename to dstalk_cli/CMakeLists.txt index a616718..f9afad1 100644 --- a/dstalk-cli/CMakeLists.txt +++ b/dstalk_cli/CMakeLists.txt @@ -1,17 +1,17 @@ # ============================================================ -# dstalk-cli — 命令行前端 (ANSI 转义码) +# dstalk_cli — 命令行前端 (ANSI 转义码) # ============================================================ -add_executable(dstalk-cli +add_executable(dstalk_cli src/main.cpp ) -set_target_properties(dstalk-cli PROPERTIES +set_target_properties(dstalk_cli PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) find_package(Boost REQUIRED CONFIG) -target_link_libraries(dstalk-cli +target_link_libraries(dstalk_cli PRIVATE dstalk boost::boost dstalk_boost_config ) diff --git a/dstalk-cli/src/main.cpp b/dstalk_cli/src/main.cpp similarity index 99% rename from dstalk-cli/src/main.cpp rename to dstalk_cli/src/main.cpp index df795f5..931b47b 100644 --- a/dstalk-cli/src/main.cpp +++ b/dstalk_cli/src/main.cpp @@ -480,7 +480,7 @@ int main(int argc, char* argv[]) } } - // 初始化主机(加载配置 + 自动扫描 plugins/ 目录加载插件) / Init host: load config + auto-scan plugins/ directory + // 初始化主机(加载配置 + 自动扫描 plugins_base/middle/upper 目录加载插件) / Init host: load config + auto-scan plugins_base/middle/upper directories if (dstalk_init(config_path) != 0) { std::fprintf(stderr, CLR_RED "[dstalk] 初始化失败\n" CLR_RESET); return EXIT_CONFIG; diff --git a/dstalk-core/CMakeLists.txt b/dstalk_core/CMakeLists.txt similarity index 96% rename from dstalk-core/CMakeLists.txt rename to dstalk_core/CMakeLists.txt index 6656ca2..57b6a34 100644 --- a/dstalk-core/CMakeLists.txt +++ b/dstalk_core/CMakeLists.txt @@ -1,5 +1,5 @@ # ============================================================ -# dstalk-core — 核心 DLL (插件宿主) +# dstalk_core — 核心 DLL (插件宿主) # 包含: 插件管理 / 服务注册 / 事件总线 / 配置存储 # ============================================================ diff --git a/dstalk-core/include/dstalk/dstalk_host.h b/dstalk_core/include/dstalk/dstalk_host.h similarity index 100% rename from dstalk-core/include/dstalk/dstalk_host.h rename to dstalk_core/include/dstalk/dstalk_host.h diff --git a/dstalk-core/include/dstalk/dstalk_lsp.h b/dstalk_core/include/dstalk/dstalk_lsp.h similarity index 100% rename from dstalk-core/include/dstalk/dstalk_lsp.h rename to dstalk_core/include/dstalk/dstalk_lsp.h diff --git a/dstalk-core/include/dstalk/dstalk_services.h b/dstalk_core/include/dstalk/dstalk_services.h similarity index 100% rename from dstalk-core/include/dstalk/dstalk_services.h rename to dstalk_core/include/dstalk/dstalk_services.h diff --git a/dstalk-core/include/dstalk/dstalk_types.h b/dstalk_core/include/dstalk/dstalk_types.h similarity index 100% rename from dstalk-core/include/dstalk/dstalk_types.h rename to dstalk_core/include/dstalk/dstalk_types.h diff --git a/dstalk-core/src/boost_json.cpp b/dstalk_core/src/boost_json.cpp similarity index 100% rename from dstalk-core/src/boost_json.cpp rename to dstalk_core/src/boost_json.cpp diff --git a/dstalk-core/src/config_store.cpp b/dstalk_core/src/config_store.cpp similarity index 97% rename from dstalk-core/src/config_store.cpp rename to dstalk_core/src/config_store.cpp index a9961dc..b6f5fbb 100644 --- a/dstalk-core/src/config_store.cpp +++ b/dstalk_core/src/config_store.cpp @@ -5,7 +5,7 @@ */ #include "config_store.hpp" -#include "../../plugins/config/include/toml_parse.h" +#include "../../plugins_base/config/include/toml_parse.h" #include #include diff --git a/dstalk-core/src/config_store.hpp b/dstalk_core/src/config_store.hpp similarity index 100% rename from dstalk-core/src/config_store.hpp rename to dstalk_core/src/config_store.hpp diff --git a/dstalk-core/src/event_bus.cpp b/dstalk_core/src/event_bus.cpp similarity index 100% rename from dstalk-core/src/event_bus.cpp rename to dstalk_core/src/event_bus.cpp diff --git a/dstalk-core/src/event_bus.hpp b/dstalk_core/src/event_bus.hpp similarity index 100% rename from dstalk-core/src/event_bus.hpp rename to dstalk_core/src/event_bus.hpp diff --git a/dstalk-core/src/host.cpp b/dstalk_core/src/host.cpp similarity index 96% rename from dstalk-core/src/host.cpp rename to dstalk_core/src/host.cpp index 087c0d4..b32a6f7 100644 --- a/dstalk-core/src/host.cpp +++ b/dstalk_core/src/host.cpp @@ -225,14 +225,22 @@ DSTALK_API int dstalk_init(const char* config_path) } } - // 扫描插件目录 / Scan plugin directory - const char* plugin_dir = g_config->get("plugin_dir"); - if (!plugin_dir) plugin_dir = "plugins"; - int loaded = load_plugins_from_directory(plugin_dir); + // 扫描插件目录 / Scan plugin directories + // 优先扫描三级插件目录,回退到单一 plugins/ 目录(构建输出) + // Prefer three-tier plugin dirs, fall back to single plugins/ dir (build output) + const char* dirs[] = { + "plugins_base", "plugins_middle", "plugins_upper", + "../plugins_base", "../plugins_middle", "../plugins_upper", + "plugins", "../plugins", + nullptr + }; + int loaded = 0; + for (int i = 0; dirs[i]; ++i) { + int n = load_plugins_from_directory(dirs[i]); + if (n > 0) loaded += n; + } if (loaded <= 0) { - host_log(DSTALK_LOG_WARN, - "No plugins found in '%s', trying '../plugins'", plugin_dir); - loaded = load_plugins_from_directory("../plugins"); + host_log(DSTALK_LOG_WARN, "No plugins found in any plugin directory"); } // 初始化所有插件 / Initialize all plugins diff --git a/dstalk-core/src/plugin_loader.cpp b/dstalk_core/src/plugin_loader.cpp similarity index 98% rename from dstalk-core/src/plugin_loader.cpp rename to dstalk_core/src/plugin_loader.cpp index 8fddc77..d749a3b 100644 --- a/dstalk-core/src/plugin_loader.cpp +++ b/dstalk_core/src/plugin_loader.cpp @@ -78,7 +78,9 @@ int PluginLoader::load_plugin(const char* path) has_dotdot = true; break; } - if (comp == "plugins") { + std::string comp_str = comp.string(); + if (comp_str == "plugins" || + comp_str.substr(0, 8) == "plugins_") { in_plugins_dir = true; } } @@ -91,8 +93,8 @@ int PluginLoader::load_plugin(const char* path) return -1; } - // 目录约束:必须位于 'plugins' 目录下或为纯文件名 - // Directory constraint: must be under a 'plugins' directory or be a plain filename + // 目录约束:必须位于 'plugins' 或 'plugins_*' 目录下,或为纯文件名 + // Directory constraint: must be under a 'plugins' or 'plugins_*' directory, or be a plain filename if (!in_plugins_dir && p.has_parent_path()) { if (host_api_) { host_api_->log(DSTALK_LOG_ERROR, diff --git a/dstalk-core/src/plugin_loader.hpp b/dstalk_core/src/plugin_loader.hpp similarity index 100% rename from dstalk-core/src/plugin_loader.hpp rename to dstalk_core/src/plugin_loader.hpp diff --git a/dstalk-core/src/service_registry.cpp b/dstalk_core/src/service_registry.cpp similarity index 100% rename from dstalk-core/src/service_registry.cpp rename to dstalk_core/src/service_registry.cpp diff --git a/dstalk-core/src/service_registry.hpp b/dstalk_core/src/service_registry.hpp similarity index 100% rename from dstalk-core/src/service_registry.hpp rename to dstalk_core/src/service_registry.hpp diff --git a/dstalk-gui/CMakeLists.txt b/dstalk_gui/CMakeLists.txt similarity index 75% rename from dstalk-gui/CMakeLists.txt rename to dstalk_gui/CMakeLists.txt index fc5b88d..aa66207 100644 --- a/dstalk-gui/CMakeLists.txt +++ b/dstalk_gui/CMakeLists.txt @@ -1,15 +1,15 @@ # ============================================================ -# dstalk-gui — 图形化前端 (SDL3) +# dstalk_gui — 图形化前端 (SDL3) # ============================================================ # 启用 DSTALK_BUILD_GUI=ON 前,确保 deps/conanfile.txt 中包含 sdl 依赖 find_package(SDL3 REQUIRED CONFIG) -add_executable(dstalk-gui +add_executable(dstalk_gui src/main.cpp ) -target_link_libraries(dstalk-gui +target_link_libraries(dstalk_gui PRIVATE dstalk SDL3::SDL3 diff --git a/dstalk-gui/src/main.cpp b/dstalk_gui/src/main.cpp similarity index 100% rename from dstalk-gui/src/main.cpp rename to dstalk_gui/src/main.cpp diff --git a/dstalk-web/CMakeLists.txt b/dstalk_web/CMakeLists.txt similarity index 59% rename from dstalk-web/CMakeLists.txt rename to dstalk_web/CMakeLists.txt index b1154f9..5b91e66 100644 --- a/dstalk-web/CMakeLists.txt +++ b/dstalk_web/CMakeLists.txt @@ -1,20 +1,20 @@ # ============================================================ -# dstalk-web — Web 前端 / Web frontend (Boost.Beast HTTP + SSE) +# dstalk_web — Web 前端 / Web frontend (Boost.Beast HTTP + SSE) # ============================================================ find_package(Boost REQUIRED CONFIG) -add_executable(dstalk-web +add_executable(dstalk_web src/main.cpp ) -set_target_properties(dstalk-web PROPERTIES +set_target_properties(dstalk_web PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) -target_compile_features(dstalk-web PRIVATE cxx_std_20) +target_compile_features(dstalk_web PRIVATE cxx_std_20) -target_link_libraries(dstalk-web +target_link_libraries(dstalk_web PRIVATE dstalk boost::boost @@ -23,5 +23,5 @@ target_link_libraries(dstalk-web # Windows: Boost.Asio 需要 Winsock / Boost.Asio requires Winsock if(WIN32) - target_link_libraries(dstalk-web PRIVATE ws2_32) + target_link_libraries(dstalk_web PRIVATE ws2_32) endif() diff --git a/dstalk-web/src/main.cpp b/dstalk_web/src/main.cpp similarity index 96% rename from dstalk-web/src/main.cpp rename to dstalk_web/src/main.cpp index e2f463b..49b8053 100644 --- a/dstalk-web/src/main.cpp +++ b/dstalk_web/src/main.cpp @@ -1,7 +1,7 @@ /* * @file main.cpp - * @brief Boost.Beast HTTP server frontend for dstalk-web: SSE streaming chat, embedded web UI, CORS support. - * dstalk-web 的 Boost.Beast HTTP 服务端:SSE 流式对话、嵌入式网页界面、CORS 支持。 + * @brief Boost.Beast HTTP server frontend for dstalk_web: SSE streaming chat, embedded web UI, CORS support. + * dstalk_web 的 Boost.Beast HTTP 服务端:SSE 流式对话、嵌入式网页界面、CORS 支持。 * Copyright (c) 2026 dstalk contributors. GPLv3. */ @@ -423,18 +423,18 @@ public: beast::error_code ec; acceptor_.open(ep.protocol(), ec); if (ec) { - std::fprintf(stderr, "[dstalk-web] acceptor.open: %s\n", ec.message().c_str()); + std::fprintf(stderr, "[dstalk_web] acceptor.open: %s\n", ec.message().c_str()); return; } acceptor_.set_option(asio::socket_base::reuse_address(true), ec); acceptor_.bind(ep, ec); if (ec) { - std::fprintf(stderr, "[dstalk-web] acceptor.bind: %s\n", ec.message().c_str()); + std::fprintf(stderr, "[dstalk_web] acceptor.bind: %s\n", ec.message().c_str()); return; } acceptor_.listen(asio::socket_base::max_listen_connections, ec); if (ec) { - std::fprintf(stderr, "[dstalk-web] acceptor.listen: %s\n", ec.message().c_str()); + std::fprintf(stderr, "[dstalk_web] acceptor.listen: %s\n", ec.message().c_str()); return; } } @@ -499,9 +499,9 @@ int main(int argc, char* argv[]) } } - // 初始化 dstalk 主机(加载配置 + 自动扫描 plugins/ 目录) / Init dstalk host (load config + auto-scan plugins/) + // 初始化 dstalk 主机(加载配置 + 自动扫描 plugins_base/middle/upper 目录) / Init dstalk host (load config + auto-scan plugins_base/middle/upper) if (dstalk_init(config_path) != 0) { - std::fprintf(stderr, "[dstalk-web] dstalk_init failed\n"); + std::fprintf(stderr, "[dstalk_web] dstalk_init failed\n"); return 3; } @@ -512,10 +512,10 @@ int main(int argc, char* argv[]) g_session = static_cast(dstalk_service_query("session", 1)); if (!g_ai) { - std::fprintf(stderr, "[dstalk-web] AI service not found (check plugins directory)\n"); + std::fprintf(stderr, "[dstalk_web] AI service not found (check plugins directory)\n"); } if (!g_session) { - std::fprintf(stderr, "[dstalk-web] Session service not found\n"); + std::fprintf(stderr, "[dstalk_web] Session service not found\n"); } // 从配置自动加载 AI 设置 / Auto-load AI settings from config @@ -546,8 +546,8 @@ int main(int argc, char* argv[]) listener.run(); // 打印启动信息 / Print startup message - std::printf("[dstalk-web] running at http://%s:%u\n", web_host, web_port); - std::printf("[dstalk-web] Press Ctrl+C to stop\n"); + std::printf("[dstalk_web] running at http://%s:%u\n", web_host, web_port); + std::printf("[dstalk_web] Press Ctrl+C to stop\n"); // 运行事件循环(阻塞直到 g_ioc->stop() 被信号处理函数调用) / Run event loop (blocks until g_ioc->stop() called by signal handler) ioc.run(); @@ -556,6 +556,6 @@ int main(int argc, char* argv[]) g_ioc = nullptr; dstalk_shutdown(); - std::printf("[dstalk-web] stopped\n"); + std::printf("[dstalk_web] stopped\n"); return 0; } diff --git a/dstalk-web/src/web_ui.hpp b/dstalk_web/src/web_ui.hpp similarity index 98% rename from dstalk-web/src/web_ui.hpp rename to dstalk_web/src/web_ui.hpp index 1d9565f..1529dba 100644 --- a/dstalk-web/src/web_ui.hpp +++ b/dstalk_web/src/web_ui.hpp @@ -1,7 +1,7 @@ /* * @file web_ui.hpp - * @brief Embedded HTML/JS chat UI served by dstalk-web. - * 嵌入的 HTML/JS 聊天界面,由 dstalk-web 提供。 + * @brief Embedded HTML/JS chat UI served by dstalk_web. + * 嵌入的 HTML/JS 聊天界面,由 dstalk_web 提供。 * Copyright (c) 2026 dstalk contributors. GPLv3. */ diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt deleted file mode 100644 index 2a4f7da..0000000 --- a/plugins/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -# ============================================================ -# 插件目录 — 所有功能插件 / Plugin directory — all functional plugins -# ============================================================ - -# 基础插件(无依赖) / Base plugins (no dependencies) -add_subdirectory(config) -add_subdirectory(file-io) -add_subdirectory(lsp) - -# 依赖基础插件的插件 / Plugins depending on base plugins only -add_subdirectory(network) # 依赖 config / depends on config -add_subdirectory(session) # 依赖 file_io / depends on file_io -add_subdirectory(tools) # 依赖 file_io / depends on file_io - -# 依赖其他插件的插件 / Plugins depending on non-base plugins -add_subdirectory(context) # 依赖 session / depends on session -add_subdirectory(openai) # 依赖 http, config / depends on http, config -add_subdirectory(anthropic) # 依赖 http, config / depends on http, config diff --git a/plugins/file-io/CMakeLists.txt b/plugins/file-io/CMakeLists.txt deleted file mode 100644 index 9e5223e..0000000 --- a/plugins/file-io/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_library(plugin-file-io SHARED src/file_io_plugin.cpp) - -target_link_libraries(plugin-file-io PRIVATE dstalk) - -set_target_properties(plugin-file-io PROPERTIES - PREFIX "" - LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins" - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins" -) diff --git a/plugins_base/CMakeLists.txt b/plugins_base/CMakeLists.txt new file mode 100644 index 0000000..9effc56 --- /dev/null +++ b/plugins_base/CMakeLists.txt @@ -0,0 +1,7 @@ +# ============================================================ +# 基础插件(无依赖) / Base plugins (no dependencies) +# ============================================================ + +add_subdirectory(config) +add_subdirectory(file_io) +add_subdirectory(lsp) diff --git a/plugins/config/CMakeLists.txt b/plugins_base/config/CMakeLists.txt similarity index 100% rename from plugins/config/CMakeLists.txt rename to plugins_base/config/CMakeLists.txt diff --git a/plugins/config/include/toml_parse.h b/plugins_base/config/include/toml_parse.h similarity index 100% rename from plugins/config/include/toml_parse.h rename to plugins_base/config/include/toml_parse.h diff --git a/plugins/config/src/config_plugin.cpp b/plugins_base/config/src/config_plugin.cpp similarity index 100% rename from plugins/config/src/config_plugin.cpp rename to plugins_base/config/src/config_plugin.cpp diff --git a/plugins_base/file_io/CMakeLists.txt b/plugins_base/file_io/CMakeLists.txt new file mode 100644 index 0000000..384c03f --- /dev/null +++ b/plugins_base/file_io/CMakeLists.txt @@ -0,0 +1,9 @@ +add_library(plugin-file_io SHARED src/file_io_plugin.cpp) + +target_link_libraries(plugin-file_io PRIVATE dstalk) + +set_target_properties(plugin-file_io PROPERTIES + PREFIX "" + LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins" +) diff --git a/plugins/file-io/src/file_io_plugin.cpp b/plugins_base/file_io/src/file_io_plugin.cpp similarity index 98% rename from plugins/file-io/src/file_io_plugin.cpp rename to plugins_base/file_io/src/file_io_plugin.cpp index 55b029a..9483981 100644 --- a/plugins/file-io/src/file_io_plugin.cpp +++ b/plugins_base/file_io/src/file_io_plugin.cpp @@ -91,7 +91,7 @@ static void on_shutdown() { } static dstalk_plugin_info_t g_info = { - "file-io", // name 名称 + "file_io", // name 名称 "1.0.0", // version 版本 "Basic file I/O service", // description 描述 DSTALK_API_VERSION, // api_version diff --git a/plugins/lsp/CMakeLists.txt b/plugins_base/lsp/CMakeLists.txt similarity index 100% rename from plugins/lsp/CMakeLists.txt rename to plugins_base/lsp/CMakeLists.txt diff --git a/plugins/lsp/src/lsp_plugin.cpp b/plugins_base/lsp/src/lsp_plugin.cpp similarity index 100% rename from plugins/lsp/src/lsp_plugin.cpp rename to plugins_base/lsp/src/lsp_plugin.cpp diff --git a/plugins_middle/CMakeLists.txt b/plugins_middle/CMakeLists.txt new file mode 100644 index 0000000..2504a9a --- /dev/null +++ b/plugins_middle/CMakeLists.txt @@ -0,0 +1,7 @@ +# ============================================================ +# 依赖基础插件的插件 / Plugins depending on base plugins only +# ============================================================ + +add_subdirectory(network) # 依赖 config / depends on config +add_subdirectory(session) # 依赖 file_io / depends on file_io +add_subdirectory(tools) # 依赖 file_io / depends on file_io diff --git a/plugins/network/CMakeLists.txt b/plugins_middle/network/CMakeLists.txt similarity index 100% rename from plugins/network/CMakeLists.txt rename to plugins_middle/network/CMakeLists.txt diff --git a/plugins/network/src/network_plugin.cpp b/plugins_middle/network/src/network_plugin.cpp similarity index 99% rename from plugins/network/src/network_plugin.cpp rename to plugins_middle/network/src/network_plugin.cpp index abc3a1f..496733f 100644 --- a/plugins/network/src/network_plugin.cpp +++ b/plugins_middle/network/src/network_plugin.cpp @@ -89,7 +89,7 @@ static std::unordered_map parse_headers_json(const cha } // ============================================================ -// HTTP 客户端实现(改编自 dstalk-core HttpClient) / HTTP Client implementation (adapted from dstalk-core HttpClient) +// HTTP 客户端实现(改编自 dstalk_core HttpClient) / HTTP Client implementation (adapted from dstalk_core HttpClient) // ============================================================ struct HttpClientCtx { asio::io_context ioc; diff --git a/plugins/session/CMakeLists.txt b/plugins_middle/session/CMakeLists.txt similarity index 100% rename from plugins/session/CMakeLists.txt rename to plugins_middle/session/CMakeLists.txt diff --git a/plugins/session/src/session_plugin.cpp b/plugins_middle/session/src/session_plugin.cpp similarity index 100% rename from plugins/session/src/session_plugin.cpp rename to plugins_middle/session/src/session_plugin.cpp diff --git a/plugins/tools/CMakeLists.txt b/plugins_middle/tools/CMakeLists.txt similarity index 100% rename from plugins/tools/CMakeLists.txt rename to plugins_middle/tools/CMakeLists.txt diff --git a/plugins/tools/src/tools_plugin.cpp b/plugins_middle/tools/src/tools_plugin.cpp similarity index 100% rename from plugins/tools/src/tools_plugin.cpp rename to plugins_middle/tools/src/tools_plugin.cpp diff --git a/plugins_upper/CMakeLists.txt b/plugins_upper/CMakeLists.txt new file mode 100644 index 0000000..cd1de25 --- /dev/null +++ b/plugins_upper/CMakeLists.txt @@ -0,0 +1,7 @@ +# ============================================================ +# 依赖其他插件的插件 / Plugins depending on non-base plugins +# ============================================================ + +add_subdirectory(context) # 依赖 session / depends on session +add_subdirectory(openai) # 依赖 http, config / depends on http, config +add_subdirectory(anthropic) # 依赖 http, config / depends on http, config diff --git a/plugins/anthropic/CMakeLists.txt b/plugins_upper/anthropic/CMakeLists.txt similarity index 100% rename from plugins/anthropic/CMakeLists.txt rename to plugins_upper/anthropic/CMakeLists.txt diff --git a/plugins/anthropic/src/anthropic_plugin.cpp b/plugins_upper/anthropic/src/anthropic_plugin.cpp similarity index 100% rename from plugins/anthropic/src/anthropic_plugin.cpp rename to plugins_upper/anthropic/src/anthropic_plugin.cpp diff --git a/plugins/context/CMakeLists.txt b/plugins_upper/context/CMakeLists.txt similarity index 100% rename from plugins/context/CMakeLists.txt rename to plugins_upper/context/CMakeLists.txt diff --git a/plugins/context/src/context_plugin.cpp b/plugins_upper/context/src/context_plugin.cpp similarity index 100% rename from plugins/context/src/context_plugin.cpp rename to plugins_upper/context/src/context_plugin.cpp diff --git a/plugins/openai/CMakeLists.txt b/plugins_upper/openai/CMakeLists.txt similarity index 94% rename from plugins/openai/CMakeLists.txt rename to plugins_upper/openai/CMakeLists.txt index 9ce1216..8b4782c 100644 --- a/plugins/openai/CMakeLists.txt +++ b/plugins_upper/openai/CMakeLists.txt @@ -11,10 +11,10 @@ add_library(plugin-openai SHARED target_link_libraries(plugin-openai PRIVATE dstalk) # Boost.JSON (header-only) -find_package(Boost REQUIRED CONFIG) target_link_libraries(plugin-openai PRIVATE boost::boost dstalk_boost_config) set_target_properties(plugin-openai PROPERTIES + PREFIX "" LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins ) diff --git a/plugins/openai/src/openai_plugin.cpp b/plugins_upper/openai/src/openai_plugin.cpp similarity index 100% rename from plugins/openai/src/openai_plugin.cpp rename to plugins_upper/openai/src/openai_plugin.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b0c4d2d..d2720f2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -18,11 +18,11 @@ add_test(NAME dstalk-smoke-test COMMAND dstalk-smoke-test) add_executable(dstalk-host-api-test host_api_test.cpp - ${CMAKE_SOURCE_DIR}/dstalk-core/src/service_registry.cpp + ${CMAKE_SOURCE_DIR}/dstalk_core/src/service_registry.cpp ) target_include_directories(dstalk-host-api-test - PRIVATE ${CMAKE_SOURCE_DIR}/dstalk-core/src + PRIVATE ${CMAKE_SOURCE_DIR}/dstalk_core/src ) target_compile_features(dstalk-host-api-test @@ -41,11 +41,11 @@ add_test(NAME dstalk-host-api-test COMMAND dstalk-host-api-test) add_executable(dstalk-event-bus-test event_bus_test.cpp - ${CMAKE_SOURCE_DIR}/dstalk-core/src/event_bus.cpp + ${CMAKE_SOURCE_DIR}/dstalk_core/src/event_bus.cpp ) target_include_directories(dstalk-event-bus-test - PRIVATE ${CMAKE_SOURCE_DIR}/dstalk-core/src + PRIVATE ${CMAKE_SOURCE_DIR}/dstalk_core/src ) target_compile_features(dstalk-event-bus-test @@ -60,11 +60,11 @@ add_test(NAME dstalk-event-bus-test COMMAND dstalk-event-bus-test) add_executable(dstalk-service-registry-test service_registry_test.cpp - ${CMAKE_SOURCE_DIR}/dstalk-core/src/service_registry.cpp + ${CMAKE_SOURCE_DIR}/dstalk_core/src/service_registry.cpp ) target_include_directories(dstalk-service-registry-test - PRIVATE ${CMAKE_SOURCE_DIR}/dstalk-core/src + PRIVATE ${CMAKE_SOURCE_DIR}/dstalk_core/src ) target_compile_features(dstalk-service-registry-test @@ -95,12 +95,12 @@ add_test(NAME dstalk-context-plugin-test COMMAND dstalk-context-plugin-test) add_executable(dstalk-plugin-loader-test plugin_loader_test.cpp - ${CMAKE_SOURCE_DIR}/dstalk-core/src/plugin_loader.cpp - ${CMAKE_SOURCE_DIR}/dstalk-core/src/boost_json.cpp + ${CMAKE_SOURCE_DIR}/dstalk_core/src/plugin_loader.cpp + ${CMAKE_SOURCE_DIR}/dstalk_core/src/boost_json.cpp ) target_include_directories(dstalk-plugin-loader-test - PRIVATE ${CMAKE_SOURCE_DIR}/dstalk-core/src + PRIVATE ${CMAKE_SOURCE_DIR}/dstalk_core/src ) target_compile_features(dstalk-plugin-loader-test @@ -134,7 +134,7 @@ add_executable(dstalk-anthropic-plugin-test ) target_include_directories(dstalk-anthropic-plugin-test - PRIVATE ${CMAKE_SOURCE_DIR}/dstalk-core/include + PRIVATE ${CMAKE_SOURCE_DIR}/dstalk_core/include ) target_compile_definitions(dstalk-anthropic-plugin-test @@ -161,7 +161,7 @@ add_executable(dstalk-openai-plugin-test ) target_include_directories(dstalk-openai-plugin-test - PRIVATE ${CMAKE_SOURCE_DIR}/dstalk-core/include + PRIVATE ${CMAKE_SOURCE_DIR}/dstalk_core/include ) target_compile_definitions(dstalk-openai-plugin-test @@ -190,7 +190,7 @@ add_executable(dstalk-network-plugin-test ) target_include_directories(dstalk-network-plugin-test - PRIVATE ${CMAKE_SOURCE_DIR}/dstalk-core/include + PRIVATE ${CMAKE_SOURCE_DIR}/dstalk_core/include ) target_compile_definitions(dstalk-network-plugin-test diff --git a/tests/anthropic_plugin_test.cpp b/tests/anthropic_plugin_test.cpp index a357463..036b421 100644 --- a/tests/anthropic_plugin_test.cpp +++ b/tests/anthropic_plugin_test.cpp @@ -9,7 +9,7 @@ */ #define BOOST_JSON_HEADER_ONLY #define BOOST_ALL_NO_LIB -#include "../plugins/anthropic/src/anthropic_plugin.cpp" +#include "../plugins_upper/anthropic/src/anthropic_plugin.cpp" #include #include diff --git a/tests/network_plugin_test.cpp b/tests/network_plugin_test.cpp index cfbb842..5cc107f 100644 --- a/tests/network_plugin_test.cpp +++ b/tests/network_plugin_test.cpp @@ -9,7 +9,7 @@ */ #define _CRT_SECURE_NO_WARNINGS #define BOOST_ASIO_DISABLE_STD_TO_ADDRESS -#include "../plugins/network/src/network_plugin.cpp" +#include "../plugins_middle/network/src/network_plugin.cpp" #include #include diff --git a/tests/openai_plugin_test.cpp b/tests/openai_plugin_test.cpp index 90034e0..b25c046 100644 --- a/tests/openai_plugin_test.cpp +++ b/tests/openai_plugin_test.cpp @@ -9,7 +9,7 @@ */ #define BOOST_JSON_HEADER_ONLY #define BOOST_ALL_NO_LIB -#include "../plugins/openai/src/openai_plugin.cpp" +#include "../plugins_upper/openai/src/openai_plugin.cpp" #include #include diff --git a/tests/plugin_loader_test.cpp b/tests/plugin_loader_test.cpp index fe47d72..79b1cdd 100644 --- a/tests/plugin_loader_test.cpp +++ b/tests/plugin_loader_test.cpp @@ -82,8 +82,8 @@ static void reset_log_state() { g_last_log_msg[0] = '\0'; } -// Get the absolute path to the build output plugins/ directory -// 获取构建输出 plugins/ 目录的绝对路径 +// Get the absolute path to the plugin tier directory (plugins_base / middle / upper) +// 获取插件层级目录 (plugins_base / middle / upper) 的绝对路径 static fs::path get_plugins_dir() { #ifdef DSTALK_TEST_PLUGINS_DIR return fs::path(DSTALK_TEST_PLUGINS_DIR); @@ -121,10 +121,10 @@ int main() CHECK(loader.load_plugin("../plugins/test.dll") == -1, "T1.3: ../ traversal rejected"); - // T1.4: 不在 plugins/ 目录下 / not under plugins/ dir + // T1.4: 不在插件 tier 目录下 / not under plugin tier dir auto tmp = fs::temp_directory_path() / "dstalk_test_no_plugins" / "test.dll"; CHECK(loader.load_plugin(tmp.string().c_str()) == -1, - "T1.4: path not under plugins/ dir rejected"); + "T1.4: path not under plugin tier dir rejected"); // T1.5: 路径中间的 .. 段 / .. segment in middle of path CHECK(loader.load_plugin("plugins/../secret/test.dll") == -1, @@ -134,9 +134,9 @@ int main() CHECK(loader.load_plugin("plugins/test") == -1, "T1.6: no extension rejected"); - // T1.7: 合法扩展名但不在 plugins/ 下 / valid extension but not under plugins/ + // T1.7: 合法扩展名但不在插件 tier 目录下 / valid extension but not under plugin tier dir CHECK(loader.load_plugin("/etc/someconfig.so") == -1, - "T1.7: .so extension but not under plugins/ rejected"); + "T1.7: .so extension but not under plugin tier dir rejected"); } // ======================================================================== @@ -149,7 +149,7 @@ int main() fs::path plugins_dir = get_plugins_dir(); fs::path dll_config = plugins_dir / "plugin-config.dll"; - fs::path dll_fileio = plugins_dir / "plugin-file-io.dll"; + fs::path dll_fileio = plugins_dir / "plugin-file_io.dll"; bool have_plugins = fs::exists(dll_config) && fs::exists(dll_fileio); @@ -206,7 +206,7 @@ int main() fs::path plugins_dir = get_plugins_dir(); std::vector dlls; - for (auto name : {"plugin-config.dll", "plugin-file-io.dll", + for (auto name : {"plugin-config.dll", "plugin-file_io.dll", "plugin-context.dll", "plugin-session.dll"}) { fs::path p = plugins_dir / name; if (fs::exists(p)) dlls.push_back(p); diff --git a/tests/smoke_test.cpp b/tests/smoke_test.cpp index bc8de32..96ea57e 100644 --- a/tests/smoke_test.cpp +++ b/tests/smoke_test.cpp @@ -58,7 +58,7 @@ int main() << "model = \"gpt-4o\"\n"; } - // 初始化主机(会自动扫描 plugins/ 加载插件)/ Init host (auto-scans plugins/ to load plugins) + // 初始化主机(会自动扫描 plugins_base/middle/upper 加载插件)/ Init host (auto-scans plugins_base/middle/upper to load plugins) if (dstalk_init(config_path.string().c_str()) != 0) { std::cerr << "dstalk_init failed\n"; return 1; @@ -112,7 +112,7 @@ int main() return 1; } } else { - std::cerr << "[WARN] file_io service not found (plugin may not be in plugins/ dir)\n"; + std::cerr << "[WARN] file_io service not found (plugin may not be in plugins_base/ dir)\n"; } // 测试服务查询: session / Test service query: session diff --git a/模块目录和功能说明.md b/模块目录和功能说明.md index 514b017..614436e 100644 --- a/模块目录和功能说明.md +++ b/模块目录和功能说明.md @@ -4,19 +4,19 @@ | 目录 | 功能说明 | |------|---------| -| `dstalk-core/` | 核心网关库(dstalk.dll / libdstalk.so),提供插件加载、服务注册、事件总线、配置存储、日志、内存管理 | +| `dstalk_core/` | 核心网关库(dstalk.dll / libdstalk.so),提供插件加载、服务注册、事件总线、配置存储、日志、内存管理 | ## 二、前端模块 | 目录 | 功能说明 | |------|---------| -| `dstalk-cli/` | 命令行前端:ANSI 终端交互、命令解析、流式对话、工具调用、批处理/管道模式 | -| `dstalk-gui/` | 图形界面前端:SDL3 窗口化界面、暗色主题、流式对话(默认关闭) | -| `dstalk-web/` | Web 前端:Boost.Beast HTTP + SSE 流式推送、内嵌 HTML/CSS/JS 聊天界面(默认关闭) | +| `dstalk_cli/` | 命令行前端:ANSI 终端交互、命令解析、流式对话、工具调用、批处理/管道模式 | +| `dstalk_gui/` | 图形界面前端:SDL3 窗口化界面、暗色主题、流式对话(默认关闭) | +| `dstalk_web/` | Web 前端:Boost.Beast HTTP + SSE 流式推送、内嵌 HTML/CSS/JS 聊天界面(默认关闭) | ## 三、插件模块 -所有插件位于 `plugins/` 目录下,通过 C ABI 与核心网关通信。 +插件按依赖层级分布在三个目录下,通过 C ABI 与核心网关通信。 ### 3.1 基础插件(无依赖) @@ -24,9 +24,9 @@ | 目录 | 服务名 | 功能说明 | |------|--------|---------| -| `plugins/config/` | `"config"` | TOML 配置文件解析、键值读写 | -| `plugins/file-io/` | `"file_io"` | 文件读写服务 | -| `plugins/lsp/` | `"lsp"` | 语言服务器协议 JSON-RPC 客户端(诊断、悬停、补全),自行管理子进程 | +| `plugins_base/config/` | `"config"` | TOML 配置文件解析、键值读写 | +| `plugins_base/file_io/` | `"file_io"` | 文件读写服务 | +| `plugins_base/lsp/` | `"lsp"` | 语言服务器协议 JSON-RPC 客户端(诊断、悬停、补全),自行管理子进程 | ### 3.2 只依赖基础插件的插件 @@ -34,9 +34,9 @@ | 目录 | 服务名 | 功能说明 | 依赖 | |------|--------|---------|------| -| `plugins/network/` | `"http"` | HTTP/HTTPS POST 和流式请求(Boost.Beast + OpenSSL) | `config` | -| `plugins/session/` | `"session"` | 会话消息历史管理、保存/加载、Token 计数 | `file_io` | -| `plugins/tools/` | `"tools"` | 工具注册、Schema 管理、执行分发(内置 file_read/file_write) | `file_io` | +| `plugins_middle/network/` | `"http"` | HTTP/HTTPS POST 和流式请求(Boost.Beast + OpenSSL) | `config` | +| `plugins_middle/session/` | `"session"` | 会话消息历史管理、保存/加载、Token 计数 | `file_io` | +| `plugins_middle/tools/` | `"tools"` | 工具注册、Schema 管理、执行分发(内置 file_read/file_write) | `file_io` | ### 3.3 依赖其他插件的插件 @@ -44,9 +44,9 @@ | 目录 | 服务名 | 功能说明 | 依赖 | |------|--------|---------|------| -| `plugins/context/` | `"context"` | Token 计数(UTF-8 字节估算)、上下文窗口裁剪 | `session` | -| `plugins/openai/` | `"ai.openai"` | OpenAI 兼容格式 AI 接入(chat/stream/tools、SSE 解析) | `http`、`config` | -| `plugins/anthropic/` | `"ai.anthropic"` | Anthropic Claude Messages API 接入(chat/stream、SSE 解析) | `http`、`config` | +| `plugins_upper/context/` | `"context"` | Token 计数(UTF-8 字节估算)、上下文窗口裁剪 | `session` | +| `plugins_upper/openai/` | `"ai.openai"` | OpenAI 兼容格式 AI 接入(chat/stream/tools、SSE 解析) | `http`、`config` | +| `plugins_upper/anthropic/` | `"ai.anthropic"` | Anthropic Claude Messages API 接入(chat/stream、SSE 解析) | `http`、`config` | ### 3.4 规划中的插件(尚未实现) diff --git a/编码规范和命名规范.md b/编码规范和命名规范.md index cc4ac21..fecb83a 100644 --- a/编码规范和命名规范.md +++ b/编码规范和命名规范.md @@ -69,7 +69,7 @@ int ConfigStore::load_file(const char* path) | 类型 | 规则 | 示例 | |------|------|------| -| 目录名 | 小写英文 + 数字 + 下划线/连字符,字母或下划线开头 | `dstalk-core`、`file-io`、`plugins` | +| 目录名 | 小写英文 + 数字 + 下划线/连字符,字母或下划线开头 | `dstalk_core`、`file_io`、`plugins` | | 源文件 | 小写英文 + 下划线,字母开头 | `config_store.cpp`、`openai_plugin.cpp` | | 头文件 | 同源文件规则 | `dstalk_host.h`、`event_bus.hpp` | | 测试文件 | `<模块名>_test.cpp` | `event_bus_test.cpp`、`openai_plugin_test.cpp` | @@ -99,7 +99,7 @@ int ConfigStore::load_file(const char* path) | 类型 | 规则 | 示例 | |------|------|------| -| 插件目录 | 功能名,小写 + 连字符 | `plugins/openai/`、`plugins/file-io/` | +| 插件目录 | 功能名,小写 + 下划线 | `plugins_upper/openai/`、`plugins_base/file_io/` | | 插件源文件 | `<功能名>_plugin.cpp` | `openai_plugin.cpp`、`session_plugin.cpp` | | CMake 目标 | `plugin-<功能名>` | `plugin-openai`、`plugin-network` | | 服务注册名 | 小写 + 点号分级 | `"ai.openai"`、`"http"`、`"session"` | @@ -116,13 +116,13 @@ int ConfigStore::load_file(const char* path) ### 4.1 目录 README -- `dstalk/`(根目录)和所有二级目录(`dstalk-core/`、`dstalk-cli/`、`plugins/` 等)必须有 `README.md` -- 三级目录(如 `plugins/openai/`)如内容简单可暂不添加 +- `dstalk/`(根目录)和所有二级目录(`dstalk_core/`、`dstalk_cli/`、`plugins_base/`、`plugins_middle/`、`plugins_upper/` 等)必须有 `README.md` +- 三级目录(如 `plugins_upper/openai/`)如内容简单可暂不添加 ### 4.2 include 路径 -- 公共头文件放在 `dstalk-core/include/dstalk/` 下 -- 私有实现头文件放在 `dstalk-core/src/` 下 +- 公共头文件放在 `dstalk_core/include/dstalk/` 下 +- 私有实现头文件放在 `dstalk_core/src/` 下 - 插件不得被 core 反向依赖(core 禁止 `#include` 插件目录下的文件) ### 4.3 内存管理 @@ -135,4 +135,4 @@ int ConfigStore::load_file(const char* path) - 所有目标输出到 `${CMAKE_BINARY_DIR}/bin`(可执行文件)或 `${CMAKE_BINARY_DIR}/plugins`(插件 DLL) - 新前端通过 `option(DSTALK_BUILD_XXX)` 控制,默认 OFF -- 插件在 `plugins/CMakeLists.txt` 中按依赖顺序 `add_subdirectory` +- 插件在 `plugins_base/CMakeLists.txt`、`plugins_middle/CMakeLists.txt`、`plugins_upper/CMakeLists.txt` 中按依赖顺序 `add_subdirectory`