Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 19 additions & 4 deletions docs/architecture/cli-product-line-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -494,10 +494,10 @@ Configuration 只能覆盖产品定义明确允许的默认值;用户插件只
Plugin/Tool、可执行 Skill/Command、MCP/LSP/Formatter、远程 Reference 等 L2/L3 内容在 OC-R2 完成归属模块保护
前只发现和展示;完成后仍须在首次启用或能力扩大时确认。它们无需先迁移;
显式导入用于用户希望取得 BitFun 独立管理快照的场景。当前只落地两个经过评审的窄切片:Desktop 与
`bitfun mcp import` 可以预览 OpenCode / Claude Code 中语义等价的 MCP 安全声明,只有显式 `--apply` 才原子写入现有
`bitfun mcp import` 可以预览 OpenCodeClaude Code 与 Codex 中语义等价的 MCP 安全声明,只有显式 `--apply` 才原子写入现有
BitFun MCP 配置;`bitfun hooks` 和统一 `/hooks` 可预览 Claude Code / Codex 中受支持的同步 command Hook,并用精确
计划指纹确认后复制到现有原生 Hook 层。两者都不写回来源文件,也不表示通用 Canonical Config 导入已进入 CLI-P1。
MCP 的 Codex 投影、凭据、header、env、cwd、通用导入记录和 undo 均未实现;Hook 的 OpenCode、非 command 或依赖
MCP 的凭据、header、env、cwd、通用导入记录和 undo 均未实现;Hook 的 OpenCode、非 command 或依赖
外部 Runtime 的 handler 仍只静态展示。其他资产在 CLI-P0 仍截止到 Dry-run,只有各自经过评审的 apply 切片才能写入:

```text
Expand All @@ -512,6 +512,13 @@ Hook C0:脱敏发现 -> 精确命令预览 | 指纹确认 -> 原子发布本
返回类型化 `action-required`;无关待办只进入结构化状态或 `stderr` 摘要,不等待不可见输入,也不自动批准。
当前只能静态预览的 custom tool 名称只显示“已发现,未执行”。

Codex MCP 快照沿用同一 `bitfun mcp import` 心智:local stdio 只在没有 environment 且无需 effective working directory
时接纳;显式 cwd 或当前 workspace 形成的隐式 cwd 都返回“需要设置”,避免导入后改用 BitFun 进程目录。remote 只接纳无
userinfo/query/fragment/header/bearer 和额外 OAuth 语义的纯 HTTPS URL;其他字段返回“需要设置”或“不支持”,不做降级
复制。导入结果仍为 disabled、`autoStart: false`。Desktop 在已有导入卡内默认选中全部 eligible 项并允许逐项取消;
plan stale 后只保留旧选择与新 eligible 项的交集,新候选不自动选中。CLI 保持默认全量和重复 `--candidate` 缩小集合,
仅在展示名重复时附带既有 candidate ID 消歧,不新增生态专用命令。

导入预览只使用四种用户可读结论:可直接使用、需要转换、会发生功能降级、输入无效。每项同时说明是原地
引用、写入 BitFun 配置、继续保持外部来源还是不支持;不得用“已映射”推导为已写入、已信任或已启用。

Expand Down Expand Up @@ -545,7 +552,8 @@ Hook C0:脱敏发现 -> 精确命令预览 | 指纹确认 -> 原子发布本
报告也不属于当前实现。

现有对 `.claude/.codex/.opencode/.agents` Skill 根的直接发现已经保留来源身份和全局/项目使用范围,并在 GUI/TUI
展示来源和默认覆盖状态,模式配置再展示实际采用项;固定根顺序保持为 Skill Registry 的独立回归契约。
展示来源和默认覆盖状态,模式配置再展示实际采用项;固定根顺序保持为 Skill Registry 的独立回归契约。Registry 仅按
既有 source slot 在内部选择来源方言,不向用户增加主选择器,也不让本地与 Remote 分支各自猜测路径。
Skill Registry 还保留来源资产声明的隐式调用意图:Claude `SKILL.md` 的 `disable-model-invocation: true` 与 Codex
`agents/openai.yaml` 的 `policy.allow_implicit_invocation: false` 都会让 Skill 不进入模型自动目录,但不影响 `/skills`、
模式配置和显式加载。Claude `user-invocable: false` 与上述模型调用策略相互独立:它只让 Skill 不进入 Web/CLI 的用户
Expand All @@ -558,13 +566,20 @@ Skill Registry 还保留来源资产声明的隐式调用意图:Claude `SKILL.
分组以及 `\$` 转义;缺失的位置参数保留原占位符,模板没有未转义占位符时才追加 `ARGUMENTS:` 段。该展开器只处理
字符串,不执行命令、脚本或动态变量。未携带 `arguments` 的旧工具调用保持原 Skill 正文不变。

Claude Skill 使用目录名作为稳定调用身份;frontmatter `description` 可缺省并回退正文首个非空段落,可选
`when_to_use` 只能与已有描述合并,合并后限制为 1536 个 Unicode 字符。`arguments` 可声明为空白分隔字符串或字符串列表,并按顺序把
`$name` 绑定到同一个调用参数列表;缺失命名参数展开为空,位置参数兼容规则不变。Codex Skill 在缺少 `name` 时回退
目录名,但仍要求 `description`。`.agents/.opencode/.bitfun/.cursor` 继续使用原有严格语义。Claude `allowed-tools` 不授予
预批准;`context`/`fork`、`agent`、`model`、`effort`、`hooks`、`paths`、`shell`、`runtime` 及动态 shell/runtime 变量等未接通行为会
整体拒绝加载,而不是静默忽略后部分执行。

这项能力不新增导入记录、来源图、后台 watcher 或第二套刷新生命周期。用户只需要一个手动入口:`/reload` 同时刷新
Skill Registry 并失效当前 Session 的 Workspace Instructions 缓存;`/reload skills` 与 `/reload instructions` 用于只刷新
一类内容。Desktop、Embedded CLI 与 Shared TUI 共用同一 core 协调入口,但 Skill Registry 刷新和 Session
`UserContext` 缓存失效仍由各自既有 owner 完成。指令变更从下一条消息开始生效;运行期不承诺文件监听或当前生成中的
消息热替换。缓存 generation 会拒绝活动 Turn 在失效之后写回的旧构建结果;旧 `/reload-skills` 输入仅作为隐藏兼容别名
映射到 `/reload skills`,不增加第二个命令入口。
本切片也不实现 `allowed-tools`、`context`、`fork`、`agent`、`model`、命名参数、动态 shell/runtime 变量、URL、祖先目录
本切片也不实现 `allowed-tools` 的权限预批准、`context`、`fork`、`agent`、`model`、动态 shell/runtime 变量、URL、祖先目录
级联、插件 Runtime 或 OpenCode 复杂 Hook。后续只有在存在稳定消费方和独立安全边界时才扩展这些语义。

Skill 说明和索引可按 L1 处理,脚本、URL 和外部依赖按 L2 确认;显式导入仍不得复制凭据值。MCP 启用状态按
Expand Down
35 changes: 27 additions & 8 deletions docs/architecture/extensions/external-ai-work-sources-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ MCP 安全子集,以及 Codex Subagent、MCP 安全子集;三种生态使用
Codex/Claude Code 运行时适配、primary agent 替换和外部 Subagent 续接仍属于后续阶段,不能因来源被识别就宣称已经可用。OpenCode、Claude Code 与 Codex 的本地 Hook 脱敏目录
已作为独立只读切片接入;在此之上,Claude Code 与 Codex 的同步 command 子集可经精确命令审阅复制为 BitFun 管理的
原生 Hook 层,仍由唯一 `AgentHookEngine` 执行。OpenCode handler、非 command/异步 handler 和未审阅声明仍不可执行。
独立的 MCP C0a 快照导入复用上述来源与现有 MCP 配置 owner:Desktop 和根 CLI 可预览 OpenCode / Claude Code
中语义等价的安全声明,并在用户显式确认后原子写入 disabled 原生条目。Codex 导入投影、凭据/header/env/cwd
迁移、通用导入记录、undo、Peer/Remote 写入均未实现;这不改变外部 MCP 持续兼容来源的运行路径。
独立的 MCP C0a 快照导入复用上述来源与现有 MCP 配置 owner:Desktop 和根 CLI 可预览 OpenCodeClaude Code
与 Codex 中语义等价的安全声明,并在用户显式确认后原子写入 disabled 原生条目。凭据/header/env/cwd 迁移、
通用导入记录、undo、Peer/Remote 写入均未实现;这不改变外部 MCP 持续兼容来源的运行路径。

## 0. 当前 MCP 快照导入契约(C0a)

快照导入是显式复制,不是持续同步,也不改变现有外部 MCP 兼容来源。Desktop 与根 CLI 只负责展示脱敏预览并发送
typed intent;OpenCode / Claude Code sibling adapter 复用各自已合并的解析结果生成私有安全投影,外部来源协调器固定
当前 candidate 与行为版本,core 负责重新规划,最终仍由唯一 MCP 配置 service 校验并写入 `mcp_servers`。
Codex 继续参与现有只读发现,但当前没有导入投影
typed intent;OpenCodeClaude Code 与 Codex sibling adapter 复用各自已合并的解析结果生成私有安全投影,外部来源
协调器固定当前 candidate 与行为版本,core 负责重新规划,最终仍由唯一 MCP 配置 service 校验并写入
`mcp_servers`。Codex 的投影与其运行准备共用同一当前 candidate/version fencing,不建立第二套解析或缓存

公开的 versioned plan/apply DTO 只包含 schema version、plan fingerprint、candidate ID、display name、transport、建议
native ID、disposition 和稳定 reason code,不包含 command arguments、URL、原始 JSON、凭据、environment/header 值或
Expand All @@ -42,10 +42,15 @@ native ID、disposition 和稳定 reason code,不包含 command arguments、UR
当前只复制能够与原生配置保持等价语义的声明:

- 无显式 environment/cwd 的 local stdio command 与 adapter 已解析 arguments;
- 无 userinfo、query、fragment、header 或 provider OAuth 变化的 HTTPS streamable HTTP URL。
- 无 userinfo、query、fragment、header、bearer token 或 provider OAuth 变化的 HTTPS streamable HTTP URL。

environment 值或引用、header/authorization、cwd、未知字段和其他 transport 不猜测、不复制、不记录。导入条目始终为
`enabled: false` 与 `autoStart: false`;local 条目不继承完整父进程环境,只保留 MCP runtime owner 提供的安全环境。
Codex 的 legacy `name` 是上游忽略的展示字段,不进入导入结果或行为版本;`startup_timeout_sec`、`tool_timeout_sec`、
`enabled_tools`、`disabled_tools`、approval、environment/scopes/OAuth 与并行调用等运行敏感字段仍按不支持处理,不能因
静态发现成功而丢弃语义后导入。
Codex 未显式声明 cwd 时,其兼容运行投影仍会把当前 workspace 作为 effective cwd;现有原生快照格式不会保留这项隐式
语义,因此 workspace 场景的 local 声明返回“需要设置”,不能以“没有 cwd 字段”为由导入后继承 BitFun 进程目录。

native ID 优先使用外部 logical name,再使用稳定生态后缀和最小可用数字后缀;超长名称使用 bounded digest,已有条目
永不覆盖。plan fingerprint 同时绑定脱敏 plan、私有投影和当前原生 MCP 配置摘要。apply 会重新发现并重建 plan;来源或
Expand All @@ -59,6 +64,11 @@ native ID 优先使用外部 logical name,再使用稳定生态后缀和最小
写入口、导入 journal、tombstone、undo、外部应用回写或插件安装/激活策略;导入后仍由既有 MCP manager 完成复核、编辑、
启用和删除。

Desktop 的导入卡默认选中当前 plan 中全部 eligible 项,用户可在原卡片内取消个别条目;每项同时显示来源生态和
用户/项目使用范围,不增加新的向导或主选择器。apply 只发送当前选中 candidate。若并发来源或目标配置变化导致 plan
stale,界面替换为服务端返回的新 plan,并只保留“旧选择与新 eligible candidate 的交集”;新出现的 candidate 不自动
勾选,避免一次旧确认扩大到用户未见过的内容。取消、完成或切换作用域会清空这份易失选择。

## 1. 产品判断与竞品启示

竞品事实与 BitFun 的产品判断分开记录:
Expand Down Expand Up @@ -268,7 +278,7 @@ OpenCode Subagent 属于 L2:adapter 只读取声明,不执行外部代码;
| Subagent | 用户/项目声明的安全子集 | 用户/项目 `agents/**/*.md` 的安全子集 | 用户/项目 `[agents]`、角色文件与安全配置层子集 | prompt、描述、精确模型和可表达工具请求进入既有归属模块;权限、私有 MCP/Hook、推理/并发等没有对应实现的字段会阻止激活。 |
| MCP | 用户/显式目录/项目配置的安全子集 | user/project/local 原生层的安全子集 | 用户与项目 `config.toml` 原生层的安全子集 | 支持可表达的 stdio 与 HTTPS Streamable HTTP;发现不启动 Server,首次激活继续经 BitFun MCP 审批。OAuth、remote executor、per-tool policy 等不完整语义明确降级。 |
| Standalone Tool | 已有单文件 JavaScript 子集 | 无稳定的 runtime-free standalone Tool 来源 | 无稳定的 runtime-free standalone Tool 来源 | TypeScript、package/plugin Tool 与动态工具注册依赖独立 Plugin Host,不在声明式 adapter 中猜测。 |
| Skill | 由现有 Skill 加载模块发现 `.opencode` 等标准根 | 由现有 Skill 加载模块发现 `.claude` 标准根 | 由现有 Skill 加载模块发现 `.codex`、`.agents` 标准根 | Skill 的加载、覆盖、模式开关与执行仍由同一个 Skill 模块负责,不复制进外部来源管理模块。 |
| Skill | 由现有 Skill 加载模块发现 `.opencode` 等标准根 | 由现有 Skill 加载模块发现 `.claude` 标准根;目录名是调用身份,描述可回退正文首段,`when_to_use` 合入索引,声明参数可做纯文本命名展开 | 由现有 Skill 加载模块发现 `.codex`、`.agents` 标准根;`.codex` 缺少 `name` 时回退目录名 | Skill 的加载、覆盖、模式开关与执行仍由同一个 Skill 模块负责,不复制进外部来源管理模块;未接通的运行时字段整体拒绝。 |
| Hook | 静态目录 | 脱敏目录;同步 command 子集可审阅导入 | 脱敏目录;同步 command 子集可审阅导入 | 仅复制到私有原生快照并由 `AgentHookEngine` 执行;OpenCode、非 command、异步、未知或依赖未观察激活语义的 handler 不导入。 |

生态原生语义由各 adapter 以契约测试固定,不抽象成全局优先级:
Expand All @@ -277,6 +287,15 @@ OpenCode Subagent 属于 L2:adapter 只读取声明,不执行外部代码;
`/frontend:component` 的原生命名空间;同层重名无效,遵循 Claude Code 当前“personal 覆盖 project”的 Skill/legacy Command
规则,同名 Skill 仅通过有界名称索引遮蔽 Command。
只展开 `$ARGUMENTS`、`$ARGUMENTS[N]` 和 `$N` 纯文本参数;shell、文件引用和改变 Agent、模型、工具或 Hook 的字段整体阻止激活。
- Skill Registry 继续拥有所有根的发现、覆盖、显式加载与刷新,只用既有稳定 source slot 在内部选择格式方言,不向用户
暴露主选择器,也不按路径字符串临时猜测。`.claude` Skill 的调用名固定为目录名;`description` 缺失时取正文首个
非空段落,并与可选 `when_to_use` 合并为最多 1536 个 Unicode 字符的模型索引说明。`arguments` 可为以空白分隔的名称
字符串或字符串列表;名称按参数顺序绑定并由现有纯文本参数展开器处理,缺失命名参数展开为空,既有缺失位置参数仍保留
占位符。`.codex` Skill 只增加上游已有的目录名 fallback,`description` 仍必填;`.agents`、`.opencode`、`.bitfun` 和
`.cursor` 的严格格式不变。本地与 Remote 发现及实际加载必须使用同一方言映射,避免目录显示可用而执行时重新解析失败。
- Claude `allowed-tools` 不能授予 BitFun 工具预批准,因此安全降级为无额外权限;`context`/`fork`、`agent`、`model`、
`effort`、`hooks`、`paths`、`shell`、`runtime` 等会改变执行行为而当前没有等价 owner 的字段阻止加载。Claude runtime 变量与动态
shell 注入也不执行。此切片不增加插件 Skill、祖先活动目录、文件 watcher、URL 来源或另一条 reload 命令。
- Claude Subagent 扫描用户与逐层项目 `.claude/agents/**/*.md`,近工作目录定义整项覆盖;Claude MCP 保留
`local > project > user` 的整项覆盖,local 只读取与规范化当前工作区严格匹配的项目项。
- Codex Subagent 从用户与逐层项目 `[agents]`、角色文件合并,缺失字段按 Codex 层级继承;`enabled`、默认模型等已支持
Expand Down
12 changes: 6 additions & 6 deletions src/apps/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ bitfun sessions list
bitfun usage
bitfun doctor
bitfun health
bitfun mcp import # preview safe OpenCode / Claude Code MCP declarations
bitfun mcp import # preview safe OpenCode / Claude Code / Codex MCP declarations
bitfun mcp import --apply # copy eligible declarations as disabled native entries
bitfun mcp import --apply --candidate <candidate-id> # repeat to select a subset
bitfun mcp import --apply --candidate <candidate-id> --native-id <native-id>
Expand All @@ -30,11 +30,11 @@ bitfun update --check # report only; do not install
```

`bitfun mcp import` is an explicit snapshot operation, not continuous sync. It
does not copy credentials, headers, environment values, or working directories,
and Codex MCP import is not supported in the current slice. Apply revalidates the
preview and never overwrites an existing native entry; imported entries remain
disabled until reviewed and enabled through the existing MCP manager. Use
`--format json` for the versioned machine-readable plan or result.
does not copy credentials, headers, environment values, or explicit working
directories. Apply revalidates the preview and never overwrites an existing
native entry; imported entries remain disabled until reviewed and enabled
through the existing MCP manager. Use `--format json` for the versioned
machine-readable plan or result.

Official Linux archive installations check for updates before interactive TUI
startup at most once every six hours. That check only fetches the release
Expand Down
Loading