Skip to content

feat(forge): support CNB (cnb.cool) as a forge provider - #1066

Merged
xintaofei merged 3 commits into
spacering-net:mainfrom
abigmiu:feat/cnb-forge
Nov 3, 2026
Merged

xintaofei merged 3 commits into
spacering-net:mainfrom
abigmiu:feat/cnb-forge

Conversation

@abigmiu

@abigmiu abigmiu commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

What

Adds CNB (cnb.cool) as a fourth forge provider, alongside GitHub, GitLab and Gitea — in the repository panel, the delivery path, auto-processing, and Settings → Version Control.

CNB is not a GitHub/Gitea dialect, and the differences produce silently wrong answers rather than 404s, so it gets its own client (src-tauri/src/forge/cnb.rs):

  • the REST base is a separate host (api.cnb.cool), not the web origin;
  • auth is Authorization: Bearer <token>;
  • every id is a string on the wire, including an issue's number;
  • issues and merge requests are separate collections (/-/issues, /-/pulls);
  • a merged merge request is state: "closed" + is_merged: true — the flag, not the state, says "landed";
  • 403 means a missing token scope, and errmsg names it.

Behaviour worth reviewing

  • Issue bodies are read on demand. CNB's issue list omits body (its pull list carries one), so forge_issue_detail fetches the item when the panel opens — one request, only for the item being read. Every other forge ships the body on the row and never takes this path (the command errors loudly if one ever does).
  • Search is hidden on CNB's merge-request tab. keyword exists on issues only; on pulls it is ignored, so the box would be a control whose input is dropped. A query left over from the other tab is cleared rather than silently kept.
  • No least_recently_updated order for CNB. Its order_by has no ascending-updated spelling.
  • No diff counters / commit count / check strip for CNB — its pull payload carries none, and saying so beats zeroes. mergeable_state: "checking" maps to "unknown", not "mergeable".
  • Merge is guarded by the head SHA (CNB's merge endpoint takes none), and returns Ok(None) after landing — the merge succeeded even if the read-back fails.

Tests

  • Rust unit tests in forge/cnb.rs pin the wire-shape traps: string numbers, absent issue body, refs/heads/ stripping, the merged flag beating closed, the per-collection spelling of "all", and file paths recovered from URLs (filename is only a base name).
  • An #[ignore]d live smoke test (CNB_TEST_TOKEN=… cargo test … forge::cnb::tests::live -- --ignored) for wire-shape drift.
  • Frontend: useIssueBody draws nothing until the read lands (rather than flashing "No description"), and a row that arrives with a body never pays for a second read.

Checks

  • pnpm lint . ✅
  • cargo check --features test-utils ✅
  • pnpm test — 2 pre-existing failures unrelated to this change (task-schedule-dialog is date-dependent and fails at HEAD; activity-rows is a timing flake)

abigmiu and others added 3 commits October 30, 2026 14:30
CNB is Tencent's code hosting platform. Its API is not a GitHub or Gitea
dialect: the REST base is a separate host (api.cnb.cool), auth is a Bearer
token, ids are strings on the wire, and issues/merge requests are separate
collections. A GitHub fallback would answer every request with an HTML page
and a 200, so it gets its own provider variant and client.

Backend:
- forge/cnb.rs: list/detail/comments/labels/state/create for issues and
  merge requests, changed-file list, merge, and the delivery path
  (find/create/get pull), plus the scan used by auto-processing
- ForgeProvider::Cnb wired through mod.rs, auth.rs (host detection,
  api_base_for, web_origin), auto, deliver and every forge_* command
- validate_cnb_token: GET /user against api.cnb.cool, with 403 read as a
  missing scope rather than a bad token
- forge_issue_detail: CNB's issue LIST omits the body, so the panel reads
  the item itself when it opens (CNB only; other forges ship it on the row)

Frontend:
- CNB accounts section, add-account dialog, token validation
- merge-request wording for CNB everywhere GitLab already had it
- forge page: hide the search box on CNB's PR tab (no keyword parameter),
  drop least-recently-updated from its sort options (no ascending updated
  order), and reset a filter that the current forge cannot apply
- useIssueBody: fetch an issue's description on demand, drawing nothing
  until the answer lands rather than flashing "No description"
- i18n for all 10 locales
CNB's issue list carries no body, and both places that mint a task (the
trigger dialog and an auto-processing scan) build the prompt's snapshot
from a list row, so every CNB issue task handed its agent a title and an
empty fence. Task creation now reads the issue body when the snapshot
has none, and the trigger dialog's preview reads it too, so what it shows
is what the envelope wraps. useIssueBody moves to its own module for the
two callers and no longer waits forever without a folder.

Also: an empty last_acted_at/created_at (CNB's spelling of no time) no
longer shadows updated_at or reaches the panel, and cnb.cool skips the
Gitea/GitLab probe its web host answers with HTML.
CNB's git server documents a FIXED username, cnb, with the access token
as the password. Delivery only used that placeholder when the stored
username was empty, and the app's own push/pull/clone credential path
always sent the account's login, so every authenticated git operation
against a CNB account sent the wrong name. Both now send cnb for a CNB
account.

The token hint asked for repo-code:r, which cannot push a delivery; it
now asks for repo-code:rw in every locale. useIssueBody's cache key also
carries the folder, so one repository's spacering-net#42 never answers for another's.
@xintaofei

Copy link
Copy Markdown
Collaborator

codeg work task 459 is done — #1066 (19 files, +379/-77).

@xintaofei
xintaofei merged commit 25c897e into spacering-net:main Nov 3, 2026
13 checks passed
xintaofei added a commit that referenced this pull request Nov 3, 2026
This release adds CNB repository support and global system instruction editing, makes tasks awaiting your response easier to continue, and improves notifications and conversation history.

## New

- **CNB (cnb.cool) joins the supported code hosting platforms**, with issue and merge request management, automatic issue processing, and task delivery through merge requests. (#1066, @abigmiu)
- **Global system instructions can be viewed and edited directly in agent settings** for supported agents such as Claude Code, Codex and OpenCode, making it easier to set preferences and working rules. (#1060, @ana52070)
- **Channel and webhook notifications can be limited to top-level session completions and errors**, reducing sub-agent notifications while keeping permission requests and questions visible.

## Improved

- **Tasks awaiting permission, an answer or plan approval now prioritize “Respond”**, opening the conversation so you can handle the request and let the task continue.
- **Webhook notifications include conversation, agent and parent-session details**, making their source and delegation relationships easier to identify.
- **Expandable steps in the execution timeline highlight on hover and keyboard focus**, making it easier to see which step you are about to open.
- **Self-updated Hermes 0.22.6 installations retain provider-grouped model selection and mode switching**, with reasoning effort available alongside them.
- **Updated Claude Code to claude-agent-acp 0.100.0 and CodeBuddy to 2.179.3.**

## Fixed

- **OpenCode’s `/` menu once again lists the skills it loads**, making them available in chat, automation and task editors.
- **OpenCode’s default model lists in Settings correctly hide disabled models and providers.** (#1079, @xyalter)
- **DeepSeek Harness 0.2.x history correctly displays tool output, failures and cache-write usage**, including conversations migrated from earlier versions. (#1086, @Cuinnchen)
- **PowerShell in the built-in terminal and “Run on this computer” loads your profile**, allowing fnm, conda, aliases and other environment customizations to work.
- **Reopening a Pi conversation correctly restores its message history**, fixing cases where the conversation appeared empty.
- **Claude Code preserves the original conversation and explains why it cannot be restored**, avoiding an unexpected switch to an empty session when it is held by a background task or its worktree cannot be reopened.
- **Claude Code replies triggered by MCP prompt commands no longer appear twice in the conversation.**

Thanks to @abigmiu, @ana52070, @xyalter and @Cuinnchen for contributing to this release, and to @grykom, @branll, @DaYePython and @ZhangSanMo for the reports and suggestions.

-----------------------------

# 发布版本 0.42.0

这一版新增 CNB 仓库支持和全局系统提示词编辑,让等待你回应的任务更容易继续,并改进消息通知与历史会话展示。

## 新增

- **新增腾讯 CNB(cnb.cool)支持**,可管理 Issue 和合并请求、自动处理 Issue,并将任务成果交付为合并请求。(#1066,@abigmiu)
- **支持在智能体设置中直接查看和编辑全局系统提示词**,适用于 Claude Code、Codex、OpenCode 等智能体,方便配置角色、回复偏好和工作规范。(#1060,@ana52070)
- **消息渠道和 Webhook 可仅推送主会话的完成与错误通知**,减少子智能体的通知干扰,同时保留授权请求和提问提醒。

## 改进

- **等待授权、回答问题或审批计划的任务会优先显示「去回应」**,点击即可打开会话处理请求,回应后任务会自动继续。
- **Webhook 通知会附带会话、智能体及父会话信息**,方便识别消息来源和委派关系。
- **执行过程中可展开的步骤会在鼠标悬停或键盘聚焦时高亮**,更容易看清即将打开的步骤。
- **兼容自行升级的 Hermes 0.22.6**,保留按供应商分组的模型选择和模式切换,并支持调整推理强度。
- **Claude Code 适配器更新至 claude-agent-acp 0.100.0,CodeBuddy 更新至 2.179.3。**

## 修复

- **OpenCode 的 `/` 菜单恢复显示已加载的技能**,可在聊天、自动化和任务编辑器中直接选用。
- **OpenCode 设置中的默认模型列表会正确隐藏已禁用的模型和供应商。**(#1079,@xyalter)
- **DeepSeek Harness 0.2.x 的历史会话能正确显示工具输出、失败状态和缓存写入用量**,从旧版迁移的会话也能正常查看。(#1086,@Cuinnchen)
- **内置终端和「在本机运行」会正确加载 PowerShell 个人配置**,让 fnm、conda、命令别名等自定义环境正常生效。
- **重新打开 Pi 会话时可以正确恢复历史消息**,修复部分会话记录显示为空的问题。
- **Claude Code 无法恢复会话时会保留原会话并说明原因**,避免因后台任务占用或工作树无法重新打开而误切到空白会话。
- **Claude Code 使用 MCP 提示词命令时,同一轮对话不再重复显示。**

感谢 @abigmiu、@ana52070、@xyalter 和 @Cuinnchen 为本次发布做出的贡献,也感谢 @grykom、@branll、@DaYePython 和 @ZhangSanMo 的问题反馈和功能建议。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants