Skip to content

Claude Code 对接 #14

Description

@SATA260

Claude Code 对接 模块

功能职责

把本机已安装的 Claude Code 接到现有对话里,让用户用和 Claude Code CLI、官方 Claude Code 扩展相同的操作把代码写完。

  • 发现本机是否装了 Claude Code、是否已取得 Claude 授权、Claude Code 有哪些模型与权限档
  • 一个对话只走 Claude Code,并记住 Claude 的 session 编号
  • 切换 Claude Code 的模型、推理强度、权限档;只把用户改过的项交给 Claude Code
  • Claude Code 的 / 命令与官方扩展按钮是同一套动作
  • 给本条消息挂上 Claude Code 认的文件提及或图片
  • 向 Claude Code 发送、排队、手动打断
  • 按 Claude Code 的方式分叉对话、归档、改标题、新开对话
  • 回放 Claude Code 的可见进展:正文、推理、命令、改文件、方案
  • 回答 Claude Code 已知的反问:跑命令、改文件、选择题、MCP 弹出的表单
  • Claude Code 问了本模块认不出的新提问,提示不兼容并回包,避免转圈
  • Claude Code 的 /mcp/skills/plugins/hooks 等只提示去终端改 Claude 配置,不在本模块里改

边界

  • 这是对接本机已安装的 Claude Code,不是给本地模型再加一个供应商;不走本地对话的工具、记忆装载和压缩。
  • 绑了 Claude Code 的对话不能中途改成本地模型或 Codex;要换就开新对话。
  • 一个 Claude Code 对话同时只有一个进行中的回合;多个 Claude Code 对话可以同时各跑一个。同一仓库允许同时开多个 Claude 窗口,不全局串行。进行中再发下一条只排队,不打断;要停掉当前一轮只能手动打断。当前一轮结束或被打断后,再开排队里的下一条。
  • 共用本机已有的 Claude 配置与授权,不另存密钥。未取得 Claude 授权时可以看选项,不能开回合。
  • 本模块落下的历史只给人看,不写回 Claude Code 当上下文;Claude 的 session 失效就失败,不静默再开一条 session。
  • 归档、分叉不删本机 Claude 记录。分叉是新对话加新的 Claude session,原对话不动。
  • /mcp/skills/plugins/hooks 只提示去终端,不改 Claude 配置文件。这不等于不回答运行中弹出来的 MCP 表单:表单要做完整作答界面。
  • 跑命令、改文件、选择题、MCP 表单都走完整界面。只有官方新加、本模块认不出的提问才提示不兼容;提示不兼容并回包,不等于用户拒绝了那条命令或改文件。
  • 工作目录跟当前仓库根走,不是每个对话自选。进程重启后,做到一半的 Claude Code 回合失败,不替用户重发。
  • Claude 的 Plan 是官方权限档之一,不是 Codex 那种单独的 Plan 开关。权限档用官方值:defaultacceptEditsplanautodontAskbypassPermissions

内部拆分

引擎目录(Catalog)

管本机有没有 Claude Code、是否已取得 Claude 授权、Claude Code 允许选哪些模型与权限档。不管对话,不管开回合。

type EngineStatus struct {
	Available  bool
	Authorized bool
	Version    string
	Hint       string // 不可用时给人看的原因,如未安装或未授权
}

type ModelInfo struct {
	ID            string
	Efforts       []string // 该 Claude 模型支持的推理强度
	DefaultEffort string
	Hidden        bool
	IsDefault     bool
}

type ModeInfo struct {
	ID   string // Claude 的权限档名,如 default、acceptEdits、plan、auto
	Kind string // permission
}

func Probe() (EngineStatus, error)     // 查看本机 Claude Code 是否可用、是否已取得授权。
func ListModels() ([]ModelInfo, error) // 列出 Claude Code 模型及各自支持的推理强度。
func ListModes() ([]ModeInfo, error)   // 列出 Claude Code 的官方权限档。

会话(Session)

管走 Claude Code 的对话容器、Claude session 编号、新建、归档、改标题、分叉。不管 Claude 配置项的值,不管回合怎么跑。

type Session struct {
	ID              string
	ClaudeSessionID string // Claude session 编号,首次开回合后才有
	Title           string
	ActiveTurnID    string // 同时只能有一个进行中的回合
	Archived        bool
}

func Create(userID string) (Session, error)                    // 创建一条只走 Claude Code 的对话。
func Get(sessionID string) (Session, error)                    // 读取对话。
func BindClaudeSession(sessionID, claudeSessionID string) error // 记下 Claude session 编号,只能写一次。
func Archive(sessionID string) error                           // 归档,之后不能再向 Claude Code 开回合。
func Rename(sessionID, title string) error                     // 改对话标题。
func Fork(sessionID string) (Session, error)                   // 按已落盘历史分叉出新对话和新的 Claude session,原对话不动。
func ClaimActiveTurn(sessionID, turnID string) error           // 标成当前执行;同时只能有一个。
func ClearActiveTurn(sessionID, turnID string) error           // 清掉当前执行标记。

官方配置(Settings)

管这个对话里生效的 Claude 模型、推理强度、权限档,以及只有改过的项才交给 Claude Code。不管发消息,不管命令怎么拆词。

type Settings struct {
	Model          string
	Effort         string
	PermissionMode string   // Claude 的官方权限档,如 default、plan、auto
	Cwd            string   // 仓库根
	Overridden     []string // 用户改过、需要交给 Claude Code 的字段名
}

func Effective(sessionID string) (Settings, error)             // 返回 Claude 默认与用户覆盖合并后的生效配置。
func Apply(sessionID string, patch Settings) (Settings, error) // 只记下用户改过的 Claude 项。

命令(Command)

管把 Claude Code 斜杠名和官方扩展按钮收成同一套动作:能做的交给会话、配置、回合或附件,不能做的只提示去终端。不管怎么对 Claude Code 说话。

type CommandAction string // apply_settings | turn | session | attach | hint

type CommandSpec struct {
	Name   string        // 与 Claude 斜杠同名,如 model、plan、branch、mcp
	Action CommandAction
	Hint   string        // hint 时给人看的话
}

type CommandResult struct {
	Hint string // 不能在本模块落地时给人看的说明
}

func List() []CommandSpec                                        // 列出与 Claude 斜杠、官方扩展按钮共用的命令。
func Invoke(sessionID, name, args string) (CommandResult, error) // 执行同名动作,或返回去终端改 Claude 配置的提示。

附件(Attachment)

管本条将要带给 Claude Code 的文件提及和图片。不管发送,不管工作目录从哪来。

type Input struct {
	Text     string
	Mentions []string // 仓库内路径,对 Claude Code 的文件提及
	Images   []string // 本地图片路径
}

func Mention(sessionID, path string) error      // 把仓库内文件挂到待发给 Claude Code 的内容上。
func AttachImage(sessionID, path string) error  // 把本地图片挂到待发给 Claude Code 的内容上。
func TakeDraft(sessionID string) (Input, error) // 取出本条附件草稿并清空。

回合(Turn)

管一次用户请求对应的那一轮 Claude Code 工作:开始、排队、手动打断。不管实录怎么记,不管人怎么点批准。

type InputMode string // start | queue

type TurnStatus string // queued | running | waiting_approval | completed | failed | cancelled

type Turn struct {
	ID        string
	SessionID string
	Status    TurnStatus
}

func Start(sessionID, content string, input Input, mode InputMode) (turnID string, err error) // 空闲则向 Claude Code 开新一轮;进行中则排队,不打断。
func Queue(sessionID, content string, input Input) (turnID string, err error)                 // 等当前 Claude Code 一轮结束或被打断后再开。
func Cancel(turnID string) error                                                              // 用户手动打断当前一轮,并向 Claude Code 传播取消。
func Continue(turnID string) error                                                            // 反问有了结果后让 Claude Code 继续。

实录(Transcript)

管把 Claude Code 的进展落成给人看、可回放的记录。不管驱动 Claude Code,不管改磁盘。

type ProgressKind string // user | text | reasoning | command | file_change | plan | notice

type Progress struct {
	Kind    ProgressKind
	Text    string
	Command string
	Paths   []string
	Diff    string
}

func AppendUser(sessionID, turnID, text string, input Input) error // 记下用户这一条。
func AppendProgress(sessionID, turnID string, item Progress) error // 记下 Claude Code 的推理、正文、命令、改文件、方案或提示。
func Hydrate(sessionID string) ([]Progress, error)                // 按已落下的记录回放。

审批(Approval)

管 Claude Code 已知的反问:跑命令、改文件、选择题、MCP 弹出的表单。不管官方新加、本模块认不出的提问,不管本地模型那套工具审批。

type DecisionScope string // once | session

type AskKind string // command | file_change | question | form

type ApprovalAsk struct {
	Kind              AskKind
	Command           string
	Paths             []string
	Diff              string
	Prompt            string   // 选择题或表单给人看的题面
	Options           []string // 选择题的选项
	Fields            []string // MCP 表单字段名
	ExternalRequestID string   // 用来回给 Claude Code 的那张问票
}

type AskAnswer struct {
	Approved bool
	Scope    DecisionScope
	Choice   string   // 选择题选中的项
	Values   []string // 表单填写结果
}

func Require(turnID string, ask ApprovalAsk) (approvalID string, err error) // 登记一条 Claude Code 已知的反问。
func Decide(approvalID string, answer AskAnswer) error                      // 按人对已知反问的作答记下结果。
func Expire(approvalID string) error                                        // 过期按拒绝回给 Claude Code,避免死等。

Claude(Claude)

管对本机 Claude Code 说话:开 session、开一轮、打断、分叉、压缩、评审,以及把反问递进递出。不管本模块有多少对话,不管本地模型。

func StartSession(cwd string, settings Settings) (claudeSessionID string, err error)                         // 让 Claude Code 新建一条 session。
func ResumeSession(claudeSessionID string) error                                                             // 接上已有的 Claude session。
func ForkSession(claudeSessionID string) (newClaudeSessionID string, err error)                              // 按 Claude 已落盘历史分叉出新 session。
func StartTurn(claudeSessionID string, input Input, settings Settings) (turnID string, err error)            // 让 Claude Code 开始一轮。
func Interrupt(claudeSessionID, turnID string) error                                                         // 按用户请求打断 Claude Code 当前一轮。
func Compact(claudeSessionID string) error                                                                   // 让 Claude Code 自己压缩上下文。
func Review(claudeSessionID string) error                                                                    // 让 Claude Code 评审当前工作区改动。
func ReplyAsk(requestID string, answer AskAnswer) error                                                      // 把人对已知反问的回答回给 Claude Code。
func RejectUnknown(requestID string) error                                                                   // 官方新加、认不出的提问:提示不兼容并回包,避免卡死。

流程

用户选 Claude Code、改 Claude 配置、带文件发送、排队、回答已知反问、分叉、手动打断或重连;Claude 的配置类斜杠只给提示。

// 用户打开新对话并选 Claude Code
Catalog.Probe(...)
Catalog.ListModels(...)
Catalog.ListModes(...)
Session.Create(...)
Settings.Effective(...)

// 用户切换 Claude 模型或权限档
Settings.Apply(...)
Command.Invoke(...)

// 用户挂上文件并发送给 Claude Code
Attachment.Mention(...)
Turn.Start(...)
Session.ClaimActiveTurn(...)
Claude.StartSession(...)
Session.BindClaudeSession(...)
Claude.StartTurn(...)
Transcript.AppendUser(...)

// Claude Code 流出进展
Transcript.AppendProgress(...)

// 用户回答 Claude Code 的命令、改文件、选择题或 MCP 表单
Approval.Require(...)
Approval.Decide(...)
Claude.ReplyAsk(...)
Turn.Continue(...)

// Claude Code 问了认不出的新提问
Transcript.AppendProgress(...)
Claude.RejectUnknown(...)
Turn.Continue(...)

// 用户在 Claude Code 进行中再发一条,先排队
Turn.Queue(...)
Transcript.AppendUser(...)

// 用户手动打断当前一轮;排着的下一条再开
Turn.Cancel(...)
Claude.Interrupt(...)
Session.ClearActiveTurn(...)
Turn.Start(...)
Session.ClaimActiveTurn(...)
Claude.StartTurn(...)

// 用户按 Claude Code 方式分叉对话
Command.Invoke(...)
Claude.ForkSession(...)
Session.Fork(...)

// 用户重连
Transcript.Hydrate(...)

// 用户点 Claude Code 的配置类斜杠
Command.Invoke(...)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    moduleSingle-module objects, interfaces, and design

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions