ddchat-connect
v1.0.1
Published
自研 IM 桥接多 Agent 服务
Readme
ddchat-connect
Linco / DDChat 对接 Claude Code 和 Codex 的本机 Agent 连接器。
它运行在用户自己的电脑上,负责把 Linco IM 服务端的消息转发给本机 Agent CLI,并把 Agent 的回复、工具调用、权限确认、附件和生成文件回传给 IM。仓库内置的 Web 页面只是本地自测页面,不是正式 IM 前端。
定位
- 本插件是本机 Agent 连接器,不是鉴权服务,也不是托管式多租户服务。
- Linco IM 服务端负责校验连接 query 中的
token=appId:appSecret。 - 插件连接 IM 时会把本机配置的
appId/appSecret拼成单个token查询参数传给服务端。 - IM WebSocket 地址由代码内置,并按 Agent 类型区分:
Claude Code: wss://chat.ddjf.info/socket/ai/claude
Codex: wss://chat.ddjf.info/socket/ai/codex普通用户初始化时不需要填写 wsUrl,私有化部署可在 .ddchat/config.json 中覆盖。
功能特性
- npm CLI 安装和启动:支持
ddchat-connect init/start/stop/doctor,可用start --daemon后台运行。 - 远端 IM 默认按配置连接,用户只需配置
appId/appSecret。 - 本地测试页的模拟前端 IM 默认不连接:需要本地页面联调时需显式添加
--local-im或--mock-im。 - 内置 Linco IM WebSocket 地址:用户只需配置
appId/appSecret,插件会在连接时拼成token=appId:appSecret。 - 多 Agent 连接:一个进程可同时连接 Claude Code 和 Codex 对应的 Linco 端点。
- 本地自测页面:用于调试本机 Agent 桥接能力。
- 本地访问 token:首次启动自动生成
localToken,保护本地测试页和本地 WebSocket。 - Claude Code 流式桥接:使用
stream-json输入/输出格式实时推送回复。 - Codex 桥接:第一版使用系统安装的
codex exec --json,沿用系统 Codex 登录和配置。 - 会话隔离:每个 Agent 和远端 session 都创建独立 session、workspace、attachments、outbox。
- Markdown 展示:支持 GFM Markdown、代码块、表格、引用和安全链接。
- 工具调用展示:Agent 工具输入、输出和错误以可折叠卡片展示。
- 权限确认:Agent 请求工具权限时可在前端批准或拒绝。
- 附件上传:支持普通文件和图片;图片作为多模态内容发送,普通文件保存为本地路径引用。
- 图片粘贴:支持从剪贴板粘贴图片。
- 文件下发:Agent 生成文件放入 outbox 后,前端自动展示下载/预览卡片。
- 斜杠命令:内置
/help、/pwd、/cd、/new、/stop、/base、/status、/list。 - Windows Git Bash 检测:Windows 下自动查找 Git Bash,也可手动指定。
前置条件
- Node.js 18+
- 已安装 Claude Code CLI,终端可执行
claude - Claude Code 已完成登录或 API Key 配置
- 如需启用 Codex:已安装 Codex CLI,终端可执行
codex,并已完成系统 Codex 登录或配置 - Windows 用户建议安装 Git for Windows
安装
开发源码运行:
npm install
npm start作为 npm CLI 使用时:
npm install -g ddchat-connect
ddchat-connect init --token "appId:appSecret" --agent claude
ddchat-connect doctor
ddchat-connect start
# 后台运行
ddchat-connect start --daemon
# 停止后台服务
ddchat-connect stop本地开发也可以用:
node bin/ddchat-connect.js init --token "appId:appSecret" --agent claude
node bin/ddchat-connect.js doctor
node bin/ddchat-connect.js start初始化配置
推荐方式:
ddchat-connect init --token "appId:appSecret" --agent claude可选参数:
ddchat-connect init \
--token "appId:appSecret" \
--agent claude \
--account default \
--force说明:
--token格式为appId:appSecret。--agent必填,指定 Agent 类型(如claude或codex)。- token 按第一个冒号切分,所以
appSecret内部可以包含冒号。 --force用于覆盖已有账号配置。- 初始化不会询问或写入
wsUrl。 - 多次执行
init并传入不同--agent可在同一账号下启用多个 Agent。
配置文件
配置统一保存在用户主目录下的 .ddchat 根目录:
~/.ddchat/config.jsonWindows 示例:
C:\Users\<用户名>\.ddchat\config.json示例结构:
{
"localWeb": {
"token": "auto-generated-local-token"
},
"defaultChannel": "ddchat",
"defaultAccount": "default",
"channels": {
"ddchat": {
"accounts": {
"default": {
"appId": "your-app-id",
"appSecret": "your-app-secret"
}
}
}
}
}配置含义:
localWeb.token:本地测试页访问 token,首次启动或初始化时自动生成。defaultAccount:默认账号名。appId/appSecret:本机保存的 Linco 应用凭证;插件连接 Linco IM 时会拼成 query 参数token=appId:appSecret。agents.claude/agents.codex:按 Agent 配置启用状态、CLI 命令和可选私有化wsUrl覆盖。
默认不需要把内置 wsUrl 写入配置文件。启用 Codex 的最小配置示例:
{
"agents": {
"codex": {
"enabled": true,
"bin": "codex"
}
}
}私有化部署可覆盖某个 Agent 的连接地址:
{
"agents": {
"codex": {
"enabled": true,
"bin": "codex",
"wsUrl": "wss://example.internal/socket/ai/codex"
}
}
}启动
默认启动本地服务,并按配置连接远端 IM;本地测试页不会自动连接模拟前端 IM:
ddchat-connect start需要使用本地测试页模拟前端 IM 时,显式启用:
ddchat-connect start --local-im
# 等价写法
ddchat-connect start --mock-im后台启动:
ddchat-connect start --daemon后台启动并启用本地模拟前端 IM:
ddchat-connect start --daemon --local-im停止后台服务:
ddchat-connect stop后台模式会把 PID 和日志写入:
~/.ddchat/ddchat-connect.pid
~/.ddchat/logs/daemon.out.log
~/.ddchat/logs/daemon.err.log启动后终端会输出本地测试页地址,例如:
本地测试页: http://127.0.0.1:3000/?localToken=xxxx请使用这条带 localToken 的地址打开测试页面。直接访问 http://127.0.0.1:3000 会被拒绝。
源码开发时也可以继续使用:
npm start源码开发后台运行:
npm start -- --daemon环境检查
ddchat-connect doctor会检查:
- Node.js 版本
- 配置文件是否存在
appId/appSecret是否已配置为 Linco token 来源- 本地测试 token 是否已生成
- 已启用 Agent 的 CLI 是否可用
- Windows Git Bash 是否可用
DDChat Home、sessions 目录是否可写
doctor 不会请求真实 IM 服务端做鉴权;token=appId:appSecret 的鉴权由 Linco IM 服务端负责。
本地自测页面
本地页面仅用于开发和自测:
- 页面通过本机 WebSocket 连接当前插件服务。
- 页面不会直接连接供应商 IM WebSocket。
- 页面需要
localToken才能访问。 - 页面可测试消息、附件、工具调用、权限确认和 outbox 文件下发。
附件上传
默认限制:
- 单次最多 50 个附件
- 单文件最大 50 MB
- 单次附件总大小最大 250 MB
- 默认拦截可执行文件和高风险脚本扩展名,例如
.exe、.bat、.cmd、.ps1、.dll
图片附件会直接作为当前 Agent 的多模态图片输入;Codex 当前会降级为文本占位提示。普通文件会保存到当前 session 的附件目录,并把本地路径附加给 Agent。
Agent 生成文件下发
每个 session 都有独立 outbox 目录。Agent 如果需要把文件发给用户,应保存或复制到该目录。服务端会自动扫描新文件并推送到前端显示。
可通过本地命令查看路径:
/base输出中会包含:
附件目录: .../attachments
outbox 目录: .../outbox斜杠命令
| 命令 | 说明 |
| --- | --- |
| /help | 显示可用命令和附件说明 |
| /commands | 显示本地命令和当前 Agent 原生命令说明 |
| /status | 显示当前会话状态 |
| /pwd | 显示当前工作目录 |
| /cd | 列出当前目录内容 |
| /cd <路径> | 切换工作目录,并开启新的 Agent 会话 |
| /new | 开启新 Agent 会话,清除上下文 |
| /stop | 停止当前 Agent 进程,下次消息尝试恢复当前会话 |
| /base | 显示 DDChat 运行目录、附件目录和 outbox 目录 |
| /list | 列出当前 IM 会话最近 10 条 Agent Session 历史 |
| /list <条数> | 按指定条数列出最近的 Agent Session 历史 |
除上述本地命令外,其他 /xxx 会透传给当前 Agent CLI。
常用环境变量
| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| PORT | 3000 | 本地 HTTP 服务端口 |
| HOST | 127.0.0.1 | 本地 HTTP 服务监听地址 |
| CLAUDE_BIN | claude | Claude Code CLI 命令或路径 |
| CODEX_BIN | codex | Codex CLI 命令或路径 |
| DDCHAT_CLAUDE_ENABLED | 无配置文件时为启用 | 是否启用 Claude 连接器 |
| DDCHAT_CODEX_ENABLED | false | 是否启用 Codex 连接器 |
| DDCHAT_CLAUDE_WS_URL | wss://chat.ddjf.info/socket/ai/claude | Claude 端点覆盖 |
| DDCHAT_CODEX_WS_URL | wss://chat.ddjf.info/socket/ai/codex | Codex 端点覆盖 |
| DDCHAT_LOCAL_AGENT | claude | 本地测试页默认使用的 Agent |
| CLAUDE_SYSTEM_PROMPT | 内置中文 Markdown 输出提示词 | 附加给 Claude 的系统提示词 |
| CLAUDE_CODE_GIT_BASH_PATH | 自动检测 | Windows 下 Git Bash 路径 |
| MAX_WS_PAYLOAD_BYTES | 367001600 | WebSocket 最大消息体大小 |
| MAX_ATTACHMENT_COUNT | 50 | 单次最大附件数量 |
| MAX_ATTACHMENT_BYTES | 52428800 | 单附件大小限制 |
| MAX_TOTAL_ATTACHMENT_BYTES | 262144000 | 单次附件总大小限制 |
| MAX_OUTGOING_ATTACHMENT_BYTES | 52428800 | outbox 单文件下发大小限制 |
| MAX_MESSAGE_QUEUE | 10 | Claude 忙碌时的最大排队消息数 |
| ATTACHMENTS_DIR_NAME | attachments | session 运行目录下的附件目录名 |
| OUTBOX_DIR_NAME | outbox | session 运行目录下的下发目录名 |
| ALLOW_UNSAFE_ATTACHMENTS | 0 | 设置为 1 时允许上传默认拦截的高风险扩展名 |
| UNSAFE_ATTACHMENT_EXTENSIONS | 内置扩展名列表 | 逗号分隔的高风险扩展名列表 |
| DDCHAT_CHANNEL | ddchat | 选择配置文件中的 IM 渠道 |
| DDCHAT_ACCOUNT | default | 选择配置文件中的 IM 账号 |
| DDCHAT_TOKEN | 空 | appId:appSecret 简写形式;连接 Linco 时作为 query 参数 token 发送 |
| DDCHAT_APP_ID | 配置文件值 | Linco IM 应用 ID |
| DDCHAT_APP_SECRET | 配置文件值 | Linco IM 应用密钥 |
| DDCHAT_AGENT_ID | main | Linco 连接器标识,可由配置文件或环境变量指定 |
| DDCHAT_WS_URL | wss://chat.ddjf.info/socket/ai/claude | Claude 旧版端点覆盖,普通用户不需要配置 |
| DDCHAT_HOME | ~/.ddchat | 运行数据根目录 |
| DDCHAT_SESSIONS_DIR | ~/.ddchat/sessions | session 数据目录 |
| CLAUDE_GRACEFUL_SHUTDOWN_MS | 3000 | Claude 进程优雅关闭时间 |
运行目录
默认目录结构:
~/.ddchat/
├── config.json
├── claude/
│ └── sessions/
│ └── sid_xxxxxxxx/
│ ├── session.json
│ ├── workspace/
│ ├── attachments/
│ └── outbox/
└── codex/
└── sessions/
└── sid_xxxxxxxx/
├── session.json
├── workspace/
├── attachments/
└── outbox/说明:
config.json保存用户配置和本地测试 token。claude/sessions/和codex/sessions/分别保存对应 Agent 的会话元数据、工作目录、上传附件和下发文件。attachments/保存用户上传的普通文件。outbox/用于 Agent 生成文件并自动下发给前端。- Codex 默认使用系统安装时的认证和配置,不会创建项目托管的
codex-home。
安全注意事项
- 默认只监听
127.0.0.1,不建议直接暴露到公网。 - 本地测试页受
localToken保护,请不要把带 token 的 URL 发给不可信的人。 appSecret保存在本机~/.ddchat/config.json,请保护好用户电脑和配置文件。- 插件不负责校验
token=appId:appSecret;真实鉴权由 Linco IM 服务端完成。 - Agent 的工具权限请求会转发给前端确认,但最终权限边界仍取决于本机 Agent 配置和用户批准。
- 危险命令检测只是基础提示,不应视为完整沙箱或安全隔离机制。
- 上传附件会落盘到本机,请不要上传或下发不应保存在本机的敏感文件。
项目结构
.
├── bin/
│ └── ddchat-connect.js # npm CLI 入口
├── public/
│ └── index.html # 本地自测页面
├── src/
│ ├── agentRunner.js # Agent 运行器门面
│ ├── agents/ # Claude/Codex Provider
│ ├── attachmentHandler.js # 上传附件保存、校验和 Agent 输入构造
│ ├── claudeRunner.js # Claude Code 子进程、stream-json 解析、权限处理
│ ├── config.js # 配置文件、环境变量和 Git Bash 检测
│ ├── danger.js # 高风险命令文本检测
│ ├── httpStatic.js # 静态文件、本地 client config 和 outbox 下载接口
│ ├── localAuth.js # 本地测试 token 生成和校验
│ ├── outgoingAttachmentHandler.js # outbox 扫描和附件下发
│ ├── protocol.js # WebSocket 消息封装
│ ├── serverApp.js # 可复用服务启动入口
│ ├── session.js # session 状态和 Agent 进程清理
│ ├── slashCommands.js # /help、/cd、/new 等斜杠命令
│ └── wsServer.js # WebSocket 连接、消息分发和 session 生命周期
├── server.js # 兼容 npm start 的入口
├── package.json
└── package-lock.json开发命令
npm install
npm start
node bin/ddchat-connect.js --help
node bin/ddchat-connect.js doctor当前项目没有配置测试、lint 或构建脚本。
