Skip to content

xinyuan0801/d-connect

Repository files navigation

d-connect

Tribute: 本项目在整体思路和使用形态上受 cc-connect 启发,感谢原项目提供的方向参考。

d-connect 是一个运行在本机上的守护进程,用来把本地 Agent CLI 桥接到 IM 平台。

Note

所有 Agent 以 SOLO 形式运行

它解决什么问题

  • 在 IM 里直接让本地 Agent 看代码、改代码、回答问题。
  • 把巡检、日报、提醒等任务交给 loop 定时执行,并自动回投聊天窗口。

功能展示

定时任务
聊天内直接发送 /loop,把自然语言需求转成可执行的定时任务。

定时任务
语音输入
语音识别结果自动纳入同一会话流程,适合移动端快速提问。

支持语音输入
图片识别与理解
直接发图给 Agent,适合看图说明、读截图排障等场景。

图片识别
Guard 安全拦截
支持按项目开启 Guard,在请求进入 Agent 前拦截敏感内容。

可配置 guard 拦截

当前支持

类别 当前支持
IM 平台 DingTalkDiscord
Agent CLI claudecodecodexopencodeqoderiflow
运行环境 Node.js >=22

5 分钟跑通

前置要求

  • Node.js >=22
  • 已安装并能直接执行至少一个 Agent CLI:claudecodexopencodeqodercliiflow
  • 如果要接真实 IM,还需要对应平台的机器人凭证
  • DingTalk 凭证获取参考
  • Discord 凭证获取参考
  • Discord 需要在 Developer Portal 创建 bot,拿到 bot token,并为 bot 开启 MESSAGE CONTENT INTENT(群聊文本触发需要)

1. 安装

npm install -g @xinyuan0801/d-connect

2. 生成配置

d-connect init

执行后会进入一个交互式 TUI 向导,用来选择 Agent 类型、工作目录、IM 平台、allowFrom 访问范围(允许所有人或指定用户 ID)以及平台凭证:

init 配置 TUI

3. 启动守护进程

d-connect start

进程启动成功后,你便可以通过钉钉或 Discord 和你本地的 coding agent 对话

配置示例

下面是一份常见的 Claude Code + DingTalk 配置:

{
  "configVersion": 1,
  "log": {
    "level": "info"
  },
  "loop": {
    "silent": false
  },
  "projects": [
    {
      "name": "my-backend",
      "agent": {
        "type": "claudecode",
        "options": {
          "workDir": "/path/to/repo",
          "cmd": "claude",
          "model": "claude-sonnet-4-20250514"
        }
      },
      "guard": {
        "enabled": false
      },
      "platforms": [
        {
          "type": "dingtalk",
          "options": {
            "clientId": "dingxxxx",
            "clientSecret": "xxxx",
            "allowFrom": "*",
            "processingNotice": "处理中..."
          }
        }
      ]
    }
  ]
}

如果你想接 Discord,可以把 platforms 改成下面这样:

[
  {
    "type": "discord",
    "options": {
      "botToken": "discord-bot-token",
      "allowFrom": "123456789012345678",
      "requireMention": true
    }
  }
]

如果你想接 Codex CLI,可以把 agent 改成下面这样:

{
  "type": "codex",
  "options": {
    "workDir": "/path/to/repo",
    "cmd": "codex",
    "model": "gpt-5-codex",
    "mode": "full-auto",
    "reasoning_effort": "high",
    "search": true
  }
}

如果你想接 OpenCode CLI,可以把 agent 改成下面这样:

{
  "type": "opencode",
  "options": {
    "workDir": "/path/to/repo",
    "cmd": "opencode",
    "model": "anthropic/claude-sonnet-4"
  }
}

关键字段

字段 含义
name 项目名,后续命令通过 -p 使用
agent.type Agent CLI 类型,当前支持 claudecode / codex / opencode / qoder / iflow
agent.options.workDir Agent 实际工作的仓库目录
agent.options.cmd 可执行命令名或完整路径
agent.options.model Agent 使用的模型名;留空则走对应 CLI 默认值
agent.options.mode codex 专用,支持 suggest / full-auto / yolo
agent.options.reasoning_effort codex 专用,支持 low / medium / high / xhigh
agent.options.search codex 专用,是否打开 live web search
agent.options.addDirs codex 专用,额外可写目录列表
guard.enabled 是否启用项目级 Guard
guard.rules 自定义 Guard 规则,优先级高于默认规则
platforms[].options.allowFrom 允许访问的用户 ID 列表;逗号分隔,"*" 表示全部允许;init 向导会显式询问此项

平台字段补充

  • DingTalk
    • clientId / clientSecret:平台凭证
    • processingNotice:处理中反馈开关;非 "none" 时会在原消息上贴 🤔思考中 表情并在处理结束后撤回,设为 "none" 可关闭
  • Discord
    • botToken:Discord bot token,鉴权方式与 openclaw 一样是标准 Bot Token
    • requireMention:群聊里是否要求显式 @bot 或回复 bot 消息;DM 不受此项影响,默认 true

Codex 适配补充

  • 当前 codex 适配按本地验证过的 codex-cli 0.114.0 接入。
  • 非交互执行走 codex exec --json,续聊走 codex exec resume <thread_id> ...
  • mode: "full-auto" 会映射到 --full-automode: "yolo" 会映射到 --dangerously-bypass-approvals-and-sandbox
  • reasoning_effort 会映射到当前 CLI 的 -c model_reasoning_effort="..." 配置覆盖。

OpenCode 适配补充

  • 当前 opencode 适配按本机验证过的 opencode-ai 1.2.26 CLI 接入。
  • 非交互执行走 opencode run --format json,续聊走 opencode run --session <session_id> <prompt>
  • 会话 ID 与消息内容从 CLI 的顶层 sessionID / part 流式事件里提取。
  • agent.options.model 会映射到 --model

Claude Code Agent Team 补充

  • Claude Code agent team 仍然复用当前聊天 session;lead 继续作为默认聊天入口,teammate 活动会以结构化进度卡片回投到同一条 IM 时间线。
  • d-connect 会默认替 claudecode 打开 agent team 所需的环境开关;只有你自己显式覆盖时才会使用自定义值。
  • Claude 本地 team 状态目录位于 ~/.claude/teams/*,任务文件位于 ~/.claude/tasks/*d-connect 会读取这些文件来恢复 /team 状态和 teammate 摘要。

聊天内命令

在 IM 中发送 / 开头消息即可:

命令 作用
/help 查看命令帮助
/new [name] 新建并切换到一个逻辑 session
/list 列出当前聊天对象下的 session
`/switch <id name>`
/stop 停止当前活跃 session 对应的 Agent 进程
/team 查看当前 Claude agent team 状态
/team members 查看当前 team 成员
/team tasks 查看当前 team 任务
/team ask <member> <message> 让 lead 把任务转给指定 teammate
/team stop <member> 让 lead 停掉指定 teammate 的当前任务
/team cleanup 让 lead 清理并收尾当前 team
/loop <request> 用自然语言描述定时任务
/loop list 列出当前聊天对象下的 loop
/loop add <expr> <prompt> 直接创建 loop
/loop del <id> 删除 loop

这些命令的回执默认是中文提示,偶尔会夹带一点不影响下班的冷幽默。 loop 默认每次执行都会使用全新的独立上下文,不继承当前聊天 session,也不会复用该任务上一次执行的历史;任务结果仍会回投到创建它的那个聊天对象。 /team 系列命令目前只对 claudecode 生效:/team/team members/team tasks 会优先读取本地 ~/.claude snapshot,/team ask|stop|cleanup 则转发固定 prompt 给 lead agent,不会直接改写 Claude 的 mailbox 文件。

常用 CLI 命令

命令 作用
d-connect init 创建配置文件
d-connect add 给现有配置追加一个项目
d-connect start 启动本地守护进程
d-connect restart 重启本地守护进程
d-connect send -p <project> -s <sessionKey> "hello" 从本地直接向某个会话发送消息
d-connect loop add -p <project> -s <sessionKey> -e "*/30 * * * * *" "status" 添加 loop
d-connect loop list -p <project> 查看项目下的 loop
d-connect loop del -i <job-id> 删除 loop

运行数据目录

运行数据固定写入 .d-connect/

  • 配置文件是普通路径,例如 ./config.json,则运行目录是配置文件同级的 .d-connect/
  • 配置文件本身位于 .d-connect/config.json,则直接复用该目录

常见文件:

  • .d-connect/ipc.sock
  • .d-connect/sessions/sessions.json
  • .d-connect/loops/jobs.json
  • .d-connect/logs/d-connect.log

本地开发

常用命令

pnpm install
pnpm run build
pnpm test
pnpm run dev init -c ./config.json
pnpm run dev add -c ./config.json
pnpm run dev start -c ./config.json
pnpm run dev send -p <project> -s local:debug "hello"
pnpm run dev loop add -p <project> -s local:debug -e "*/30 * * * * *" "status"
pnpm run dev loop list -p <project>

本地联调

先启动 daemon:

pnpm run dev start -c ./config.json

另一个终端发送消息:

pnpm run dev send -p my-backend -s local:alice "请给我当前项目结构"
pnpm run dev send -p my-backend -s local:bob "你好"

再加一个 loop 验证调度:

pnpm run dev loop add -p my-backend -s local:alice -e "*/20 * * * * *" "输出一次状态"

目录概览

  • src/bootstrap/**:CLI 入口与 daemon 启动编排
  • src/config/**:配置加载、校验、init / add 向导
  • src/services/**:会话、命令、消息 relay
  • src/adapters/agent/**:各类 Agent CLI 适配器
  • src/adapters/platform/**:DingTalk / Discord 适配器
  • src/ipc/**:本地 IPC
  • src/scheduler/**:loop 调度与持久化
  • tests/**:Vitest 测试

平台联调提示

DingTalk

  • init / add 交互向导支持 DingTalk 和 Discord;--yes 以及 start 自动生成的兜底模板仍默认是 DingTalk
  • 机器人消息走 CALLBACK,不是普通 EVENT
  • 收到 callback 后需要显式回执,否则平台大约 60 秒后可能重投
  • 当前实现按 msgId 做 10 分钟去重
  • 即时回复仍使用入站消息里的 sessionWebhook
  • 异步回投/loop 会直接走机器人主动发送:群聊用 /v1.0/robot/groupMessages/send,单聊用 /v1.0/robot/oToMessages/batchSend,不再尝试 sessionWebhook
  • 历史旧版 DeliveryTarget 若缺少 conversationType、群聊所需的 openConversationId 或单聊所需的 userId,会被直接忽略,不再尝试发送
  • 图片、视频、文件等入站内容会下载到 agent.options.workDir/.d-connect/dingtalk-media

Discord

  • 认证使用标准 Bot Token
  • 群聊文本触发依赖 MESSAGE CONTENT INTENT;如果没开,群消息可能只能看到 mention/事件元信息,看不到正文
  • 当前实现默认只处理两类群聊消息:显式 @bot,或回复 bot 的消息;把 requireMention 设为 false 后,allow-list 命中的用户在群里发言都会触发
  • DM 不要求 mention,只要 allowFrom 放行就会进入同一条平台链路
  • 即时回复会在开始处理该条用户消息时立刻补一个 👀 reaction,回复成功结束后移除它并补一个 💯;正文仍走引用回复,异步回投/loop 仍然只走 POST /channels/{channel.id}/messages
  • 持久化 DeliveryTarget 只依赖 channelId;如果历史 target 缺失 channelId,loop 不会尝试回投
  • 出站消息默认禁用 allowed_mentions.parse,避免 Agent 文本意外触发 @everyone 或角色 mention

测试与构建

pnpm test
pnpm run build

如果你改了配置、平台适配器、IPC、调度或公共运行链路,建议不要跳过这两步。

常见问题

agent cli not found

  • 确认对应 CLI 已安装且可以在终端里直接执行
  • 或在 agent.options.cmd 填完整命令路径

session is busy

  • 同一逻辑 session 正在处理上一条请求
  • 等处理完成,或先 /new 新开一个 session

qoder 调用 AskUserQuestion 后看起来停住

  • d-connect 会在检测到 AskUserQuestion 工具调用后结束当前这一轮,避免 CLI 一直阻塞
  • 聊天窗口会收到问题摘要,直接回复你的选择(例如 dev / prod)即可继续同一 session

IPC 无法连接

  • 确认 daemon 已启动
  • 确认 .d-connect/ipc.sock 已生成

loop 没有回投到 IM

  • 确认该 sessionKey 最近收到过至少一条真实平台消息
  • loop 默认使用按 job.id 隔离的执行会话;如果你在排查“为什么没继承上一轮聊天上下文”,这是当前设计,不是故障
  • DingTalk 场景下,优先检查 .d-connect/sessions/sessions.json 里的 DeliveryTarget 是否带有 conversationTyperobotCode,以及群聊所需的 openConversationId 或单聊所需的 userId
  • 若历史 DingTalk target 缺这些主动发送字段,会被直接忽略
  • Discord 场景下,优先检查 .d-connect/sessions/sessions.json 里的 DeliveryTarget 是否带有 channelId

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors