diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4d53c93e03..922518923e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,20 +40,27 @@ jobs: - name: Validate EC600 protocol template (draft) run: | + TEMPLATE_FILE="$(find local-docs -maxdepth 3 -type f -name 'EC600_PROTOCOL_MAPPING_TEMPLATE.md' | head -n 1)" + if [ -z "${TEMPLATE_FILE}" ]; then + echo "No EC600 protocol template found under local-docs/, skip draft validation." + exit 0 + fi python -m opencane.hardware.validate_protocol \ - --mapping local-docs/nanobot-legacy/EC600_PROTOCOL_MAPPING_TEMPLATE.md \ + --mapping "${TEMPLATE_FILE}" \ --stage draft - name: Validate EC600 frozen mapping (freeze gate) run: | + TEMPLATE_FILE="$(find local-docs -maxdepth 3 -type f -name 'EC600_PROTOCOL_MAPPING_TEMPLATE.md' | head -n 1)" + DEFERRED_FILE="$(find local-docs -maxdepth 3 -type f -name 'HARDWARE_JOINT_DEBUG_DEFERRED.md' | head -n 1)" if [ -f "EC600_PROTOCOL_MAPPING_V1.md" ]; then python -m opencane.hardware.validate_protocol \ --mapping EC600_PROTOCOL_MAPPING_V1.md \ --stage freeze - elif grep -q "当前状态:\`Frozen\`" local-docs/nanobot-legacy/EC600_PROTOCOL_MAPPING_TEMPLATE.md; then + elif [ -n "${TEMPLATE_FILE}" ] && grep -q "当前状态:\`Frozen\`" "${TEMPLATE_FILE}"; then echo "Template is Frozen but EC600_PROTOCOL_MAPPING_V1.md is missing." exit 1 - elif grep -q "状态:\`Deferred\`" local-docs/nanobot-legacy/HARDWARE_JOINT_DEBUG_DEFERRED.md; then + elif [ -n "${DEFERRED_FILE}" ] && grep -q "状态:\`Deferred\`" "${DEFERRED_FILE}"; then echo "Freeze gate deferred by HARDWARE_JOINT_DEBUG_DEFERRED.md" else echo "EC600 freeze gate requires EC600_PROTOCOL_MAPPING_V1.md or an explicit Deferred marker." diff --git a/README.md b/README.md index ee2075ef0a..b597776e86 100644 --- a/README.md +++ b/README.md @@ -75,20 +75,17 @@ opencane hardware serve --adapter mock --logs - Security Baseline: `docs/security.md` - Roadmap: `docs/roadmap.md` -### NanoBot Compatibility and Migration +### OpenCane Runtime Conventions -- Primary CLI command is `opencane`, with `nanobot` alias compatibility -- Project branding and product docs are now OpenCane -- Python package/import path uses `opencane` (no longer supports `from nanobot...`) -- Default data directory is `~/.opencane`, with backward-compatible reads from `~/.nanobot` -- Migration guide: `docs/migration-from-nanobot.md` -- Legacy nanobot docs are archived at: `local-docs/nanobot-legacy/` -- Archive README: `local-docs/nanobot-legacy/README.md` +- Primary CLI command: `opencane` +- Python package/import path: `opencane` +- Default data directory: `~/.opencane` +- Local internal docs directory: `local-docs/` ### Acknowledgement -OpenCane is continuously developed based on [HKUDS/nanobot](https://github.com/HKUDS/nanobot). -Thanks to HKUDS for the open-source foundation. +OpenCane is continuously evolved from an upstream open-source foundation by HKUDS. +Thanks to HKUDS for the original engineering base. --- @@ -164,17 +161,14 @@ opencane hardware serve --adapter mock --logs - 安全基线:`docs/security.md` - 路线图:`docs/roadmap.md` -### NanoBot 兼容与迁移 +### OpenCane 运行约定 -- CLI 主命令为 `opencane`,并兼容 `nanobot` 别名 -- 项目品牌与产品文档已切换为 OpenCane -- Python 包与导入路径:使用 `opencane`(不再支持 `from nanobot...`) -- 数据目录:默认 `~/.opencane`,兼容读取历史 `~/.nanobot` -- 迁移说明:`docs/migration-from-nanobot.md` -- 旧版 nanobot 历史文档已归档到:`local-docs/nanobot-legacy/` -- 归档说明见:`local-docs/nanobot-legacy/README.md` +- CLI 主命令:`opencane` +- Python 包与导入路径:`opencane` +- 默认数据目录:`~/.opencane` +- 本地内部文档目录:`local-docs/` ### 致谢 -本项目基于 [HKUDS/nanobot](https://github.com/HKUDS/nanobot) 进行持续开发与场景化演进。 -感谢 HKUDS 团队开源 nanobot,为 OpenCane 的落地提供了坚实基础。 +本项目基于 HKUDS 的上游开源基础进行持续开发与场景化演进。 +感谢 HKUDS 团队提供的原始工程基础。 diff --git a/docs/README.md b/docs/README.md index c9e11009f3..39c1c596ff 100644 --- a/docs/README.md +++ b/docs/README.md @@ -3,9 +3,9 @@ ## 当前状态(2026-02-21) - 代码包名已完成迁移:`opencane` -- CLI 主命令:`opencane`(兼容 `nanobot` 别名) -- 默认数据目录:`~/.opencane`(兼容读取 `~/.nanobot`) -- 历史文档已归档到本地目录:`../local-docs/nanobot-legacy/` +- CLI 主命令:`opencane` +- 默认数据目录:`~/.opencane` +- 历史文档已归档到本地目录:`../local-docs/` ## 阅读顺序 @@ -36,8 +36,7 @@ - 运维手册: `operations-runbook.md` - 安全基线: `security.md` - 路线图: `roadmap.md` -- 迁移说明: `migration-from-nanobot.md` ## 历史文档归档 -- 旧版 nanobot 文档: `../local-docs/nanobot-legacy/` +- 本地历史文档目录: `../local-docs/` diff --git a/docs/migration-from-nanobot.md b/docs/migration-from-nanobot.md deleted file mode 100644 index ea770b1da2..0000000000 --- a/docs/migration-from-nanobot.md +++ /dev/null @@ -1,53 +0,0 @@ -# 从 nanobot 到 OpenCane 的文档迁移说明 - -## 本次调整内容 - -1. 根目录原有 nanobot 文档全部归档到 `local-docs/nanobot-legacy/` -2. 重建 OpenCane 文档体系,统一入口为根目录 `README.md` 和 `docs/README.md` -3. 文档结构从“历史演进 + 分散专题”调整为“产品化结构 + API/运维可执行手册” - -## 命名与兼容 - -- 项目名称:OpenCane -- 代码包名:`opencane` -- CLI 命令:`opencane`(兼容 `nanobot` 别名) -- 配置目录:默认 `~/.opencane`(兼容读取 `~/.nanobot`) - -## 迁移完成状态(2026-02-21) - -已完成: - -- 源码包目录由 `nanobot/` 迁移到 `opencane/` -- 构建与入口脚本迁移到 `opencane`(保留 CLI 别名 `nanobot`) -- 文档、脚本、测试用例中的主命令统一为 `opencane` - -兼容保留: - -- `nanobot` CLI 别名 -- 读取历史数据目录 `~/.nanobot` -- skill frontmatter 兼容 legacy `nanobot` metadata key - -不再兼容: - -- `python -m nanobot` -- `from nanobot...` 导入路径 - -这意味着: - -- 文档中的项目术语统一为 OpenCane -- 建议执行命令使用 `opencane ...` - -## 迁移后的文档分层 - -- 产品层:`docs/overview.md` -- 上手层:`docs/quickstart.md` -- 设计层:`docs/architecture.md`, `docs/data-flow.md` -- 接口层:`docs/api/*.md` -- 运行层:`docs/deployment-config.md`, `docs/operations-runbook.md`, `docs/security.md` -- 规划层:`docs/roadmap.md` - -## 对历史文档的处理策略 - -- 历史文档不删除,全部保留在归档目录 -- 新需求、缺陷修复、上线变更只更新新文档体系 -- 如发现历史文档与当前实现冲突,以新文档和源码为准 diff --git a/docs/overview.md b/docs/overview.md index 0983b40c26..d2b19b74f5 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -29,18 +29,13 @@ OpenCane 是“AI Agent 平台能力 + 智能盲杖后端能力”的统一工 - OTA 固件发布平台 - 多租户控制平面 SaaS -## 3. 运行接口与兼容边界 +## 3. 运行接口 -项目品牌已切换为 OpenCane,但以下运行接口仍保持兼容: +当前运行接口如下: - Python 包/导入:`opencane` -- CLI:`opencane ...`(兼容 `nanobot` 别名) -- 默认配置路径:`~/.opencane/config.json`(兼容读取 `~/.nanobot/config.json`) - -不在兼容范围内: - -- `python -m nanobot` -- `from nanobot...` 导入路径 +- CLI:`opencane ...` +- 默认配置路径:`~/.opencane/config.json` ## 4. 文档使用方式 diff --git a/docs/quickstart.md b/docs/quickstart.md index 7f57333166..cb05b7bac9 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -20,8 +20,6 @@ pip install -e . opencane onboard ``` -如本机已有旧版 `~/.nanobot/config.json`,运行时会自动兼容读取。 - 生成默认配置后,建议直接应用预设模板: ```bash @@ -74,7 +72,7 @@ opencane hardware serve --adapter generic_mqtt --logs 说明: -- `opencane` 为主命令;`nanobot` 作为 CLI 别名可继续使用 +- `opencane` 为主命令 - Python 包导入路径请统一使用 `opencane` ## 7. 常用调试命令 diff --git a/nanobot_arch.png b/nanobot_arch.png deleted file mode 100644 index 09251771fb..0000000000 Binary files a/nanobot_arch.png and /dev/null differ diff --git a/nanobot_logo.png b/nanobot_logo.png deleted file mode 100644 index 01055d15cb..0000000000 Binary files a/nanobot_logo.png and /dev/null differ diff --git a/opencane/channels/dingtalk.py b/opencane/channels/dingtalk.py index 0f5fba0032..39f93d4591 100644 --- a/opencane/channels/dingtalk.py +++ b/opencane/channels/dingtalk.py @@ -33,10 +33,10 @@ ChatbotMessage = None # type: ignore[assignment,misc] -class NanobotDingTalkHandler(CallbackHandler): +class OpenCaneDingTalkHandler(CallbackHandler): """ Standard DingTalk Stream SDK Callback Handler. - Parses incoming messages and forwards them to the Nanobot channel. + Parses incoming messages and forwards them to the OpenCane channel. """ def __init__(self, channel: "DingTalkChannel"): @@ -67,7 +67,7 @@ async def process(self, message: CallbackMessage): logger.info(f"Received DingTalk message from {sender_name} ({sender_id}): {content}") - # Forward to Nanobot via _on_message (non-blocking). + # Forward to OpenCane via _on_message (non-blocking). # Store reference to prevent GC before task completes. task = asyncio.create_task( self.channel._on_message(content, sender_id, sender_name) @@ -132,7 +132,7 @@ async def start(self) -> None: self._client = DingTalkStreamClient(credential) # Register standard handler - handler = NanobotDingTalkHandler(self) + handler = OpenCaneDingTalkHandler(self) self._client.register_callback_handler(ChatbotMessage.TOPIC, handler) logger.info("DingTalk bot started with Stream Mode") @@ -207,7 +207,7 @@ async def send(self, msg: OutboundMessage) -> None: "msgKey": "sampleMarkdown", "msgParam": json.dumps({ "text": msg.content, - "title": "Nanobot Reply", + "title": "OpenCane Reply", }), } @@ -225,7 +225,7 @@ async def send(self, msg: OutboundMessage) -> None: logger.error(f"Error sending DingTalk message: {e}") async def _on_message(self, content: str, sender_id: str, sender_name: str) -> None: - """Handle incoming message (called by NanobotDingTalkHandler). + """Handle incoming message (called by OpenCaneDingTalkHandler). Delegates to BaseChannel._handle_message() which enforces allow_from permission checks before publishing to the bus. diff --git a/scripts/run_control_api_smoke_ci.sh b/scripts/run_control_api_smoke_ci.sh index 1b5dc09bcf..32f7aebe4f 100644 --- a/scripts/run_control_api_smoke_ci.sh +++ b/scripts/run_control_api_smoke_ci.sh @@ -4,7 +4,7 @@ set -euo pipefail CONTROL_API_HOST="${CONTROL_API_HOST:-127.0.0.1}" CONTROL_API_PORT="${CONTROL_API_PORT:-18792}" CONTROL_API_BASE="http://${CONTROL_API_HOST}:${CONTROL_API_PORT}" -SERVER_LOG="${SERVER_LOG:-/tmp/nanobot_mock_control_api.log}" +SERVER_LOG="${SERVER_LOG:-/tmp/opencane_mock_control_api.log}" echo "starting mock control api server at ${CONTROL_API_BASE}" python3 scripts/mock_control_api_server.py \