Skip to content

feat(agent-hook-plugin): add the CodeBuddy Code CLI as a host adapter - #5860

Merged
t0saki merged 19 commits into
volcengine:mainfrom
caozeal:feat/codebuddy-memory-plugin
Oct 26, 2026
Merged

t0saki merged 19 commits into
volcengine:mainfrom
caozeal:feat/codebuddy-memory-plugin

Conversation

@caozeal

@caozeal caozeal commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Closes #5857

Draft no longer — this is the adapter version @t0saki asked for in the review. Reworked from the standalone Claude-Code-shaped plugin into an agent-hook-plugin host adapter, following the KimiCode precedent (#4787). Everything the review kept carries over: the host contract (now hosts/codebuddy/DESIGN.md) and the transcript decoder (hosts/codebuddy-turns.mjs).

Depends on #6436 (the HARNESS_KEYS line), which @t0saki asked to land first so this PR stops re-bumping six plugins on every rebase — merge that one first, then rebase this branch onto main.

What it adds

  • hosts/codebuddy.mjs — event mapping (a stages map plus an envelope), the is_internal_continuation prompt gate, a deny-only guard that goes through the shared preToolUseOutput(), and the capture/commit policy. CodeBuddy matches Claude Code on event names and the output envelope, so the adapter is thin; the real work is the decoder.
  • hosts/codebuddy-turns.mjs — decodes CodeBuddy's JSONL transcript, where tool calls are separate records and the human ask is wrapped in host-injected markup (<user_query>, <system-reminder>, …). Mirrors the server-side workbuddy adapter's parsing; a parity test fails when the two block-tag lists drift.
  • hosts/codebuddy/ — the plugin manifest, hooks, MCP config, DESIGN.md (the measured host contract, plus a new section recording the adapter mapping and the v1 scope), and the three skills.
  • Installer support: --harness codebuddy assembles a self-contained plugin (the shared runtime beside the adapters, because CodeBuddy installs the plugin directory wholesale into its cache), registers a local marketplace, and installs through the host CLI. Detection, TUI, validation, uninstall, and next steps follow the KimiCode path; the uninstall also removes the host's cached copy, which the CLI leaves behind.

What the review changed

  • Standalone plugin → adapter: no more duplicated ~4k lines to fix twice. config.mjs, the vendored shared/, lib/, the doctor, and the six per-event scripts are gone; the shared runtime covers them.
  • rootKeyFallback, the ov.conf legacy section, and the repo-root marketplace are dropped (§4.2; no legacy installs to keep working; --plugin-dir covers local dev).
  • The hard-coded compressor defaults (hy3) are gone — §4.1 wants host defaults in the schema, and a private model name does not belong there. Users configure recallCompress* as on any other host.
  • The export * shims and the probe-history comments are gone; that history lives in DESIGN.md.
  • v1 has no subagent capture, as Cursor and KimiCode: the dispatcher has no subagent stage, so adding one is a follow-up that would benefit every host (§3.1).
  • Docs: a section of 08-community-plugins.md in both languages instead of a numbered page — hooks are still Beta on the host side and recall runs only in the TUI, so the community section sets the right expectations. The 16-capability-reference.md rows and the {harness} entry in configuration/02-client.md are in place.

One thing to veto if you disagree

The three skills (openviking-memory, openviking-skills, ov-experience-memory) ship inside hosts/codebuddy/skills/, following the Cursor adapter rather than KimiCode — CodeBuddy's plugin system loads them natively. If you would rather v1 stay hooks + MCP only, say so and they come out.

Verification (same gates as pr.yml, run locally)

  • node sync.mjs leaves the tree clean (this PR touches no shared-library file)
  • check-plugin-version-bumps.sh origin/main: agent-hook-plugin 0.5.23 -> 0.5.24 ok
  • full test glob (105 files): 1354 pass, 0 fail, 8 conditional skips — including 34 new adapter/decoder tests
  • installer tests: 22/22; bash -n on install.sh and the marketplace staging script
  • sandbox end-to-end: install.sh --yes --harness codebuddy assembles the plugin, registers the marketplace, installs through the CLI, and passes validation; the installed copy answers the hook smoke test and the URI guard; --uninstall leaves nothing behind (including the host's cache)
  • install/uninstall driven against a throwaway HOME; the real ~/.codebuddy was never touched

CI on this PR will wait on the first-time-contributor approval, as before, so none of the above has been confirmed by CI yet.

@ZaynJarvis ZaynJarvis added the agent-plugins Agent harness and plugin integrations label Oct 12, 2026
@caozeal
caozeal marked this pull request as ready for review October 17, 2026 00:40
@caozeal
caozeal force-pushed the feat/codebuddy-memory-plugin branch from 5823c6e to 040cceb Compare October 17, 2026 00:57
@caozeal

caozeal commented Oct 17, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto the current main and resolved the conflicts — the branch is now mergeable again.

What changed since the first push:

  • Conflict resolution: every conflicted file was a version line. Upstream had already bumped the six registered plugins past the versions this PR first targeted, so I kept upstream's newer versions (including the PLUGIN_VERSION constant in dsh's config.mjs, which upstream had already moved themselves) rather than dragging them back.
  • Re-bump on top: because the merge-base moved, the version-bump gate compares head against a base that already contains upstream's newer versions, so each plugin got one more patch: claude-code 0.7.13, codex 0.11.12, agent-hook 0.5.22, opencode 0.5.18, dsh 0.5.27, pi 0.4.21.
  • Re-synced the vendored shared runtime: upstream moved the shared library forward after the first push (extra-header plumbing in ov-http, non-JSON 2xx detection, tightened recall digest prompt), so sync.mjs was re-run and the regenerated copies are committed.

Verification (same gates as pr.yml, run locally):

  • node sync.mjs leaves the tree clean
  • check-plugin-version-bumps.sh origin/main: all six ok
  • codebuddy plugin tests: 34/34
  • shared suite: 577/577
  • installer tests: 22/22, bash -n on all installer scripts
  • full CI glob (108 test files): 1340 pass, 0 fail, 8 conditional skips

The CI runs on this PR are still waiting on the first-time-contributor approval, so none of the above has been confirmed by CI yet.

@t0saki

t0saki commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the thorough work here — especially docs/HOST-CONTRACT.md. Measuring the host instead of assuming it, and writing down which of your own assumptions turned out wrong, is exactly what the plugin guide asks for, and it made this PR easy to review. You asked which parts to redo, so here is my answer to the questions in #5857.

Shape: please move this to an agent-hook-plugin host adapter instead of a standalone copy of the Claude Code plugin.

I diffed every script against claude-code-memory-plugin. Apart from cb-transcript.mjs, almost all of the differences are renames (cc_ → cb_), comments, and state paths. auto-recall.mjs differs by six real lines (is_internal_continuation); auto-capture.mjs, session-start.mjs, subagent-stop.mjs, config.mjs and the hook timeouts are carried over as-is. That is roughly 4k lines that would have to be fixed twice from now on, which is the first smell in §9 of 18-plugin-development.md, and §2.1 says not to copy a whole Claude Code or Codex directory just to add a host name.

Your contract shows CodeBuddy matches Claude Code on event names and the output envelope. In agent-hook-plugin, that part is a stages map plus an envelope(). The real work is the transcript decoder, and CodeBuddy's message / function_call / function_call_result records don't reuse anything from cc-transcript.mjs anyway. KimiCode is the precedent here: it also has a native plugin manifest and landed as hosts/kimicode.mjs + kimicode-turns.mjs (#4787). Roughly:

  • hosts/codebuddy.mjs: stages, envelope, prompt() returning "" for is_internal_continuation, guard() (deny only, no Bash, as your contract justifies).
  • hosts/codebuddy-turns.mjs: your cb-transcript.mjs logic, plugged into incremental-turn-capture.mjs.
  • hosts/codebuddy/: the manifest, hooks and MCP config. HOST-CONTRACT.md can live there as DESIGN.md.
  • Install through examples/memory-plugin-shared/install.sh --harness codebuddy the same way kimicode does. (The installer is in this repo, so "lives outside this repository" in the description isn't quite right.)

Subagent capture is the one thing the dispatcher can't express today. I'd ship v1 without it and document it as unsupported, as Cursor and KimiCode do. If it turns out to matter, a follow-up PR can add a subagent stage to the dispatcher, with the reason spelled out (§3.1), so every host gets it.

Smaller things that apply whichever way this goes:

  1. rootKeyFallback: true in config.mjs — §4.2 says a new host must not copy this from a reference plugin. CodeBuddy has no legacy installs to keep working.
  2. The ov.conf codebuddy section / codebuddy.enabled "legacy" path is new compatibility surface for a host with no history. Please drop it.
  3. examples/.codebuddy-plugin/marketplace.json duplicates the root marketplace under the same name, only to support a local-directory install. --plugin-dir already covers local dev.
  4. cb-transcript.mjs: TOOL_RESULT_MAX_CHARS = 0 makes truncateToolResult() always return null (dead branch); the cfg parameter is unused; and the JSON-array fallback in parseTranscript isn't backed by anything in the contract.
  5. uri-guard.mjs falls back through toolName ?? tool ?? name, which the contract never observed. Use tool_name/tool_input only, and go through the shared preToolUseOutput() rather than building the deny by hand.
  6. The host compressor defaults ("codebuddy", "hy3") are hard-coded in the adapter. §4.1 wants host-specific defaults declared in the schema.
  7. The scripts/lib/*.mjs one-line export * shims and the long probe-history comments (P0/P6 notes) can go. Keep that history in the design doc or the PR description.
  8. HOST_BLOCK_TAGS now exists in both workbuddy.py and JS. A cross-reference comment on both sides, or a small parity test, would keep them from drifting.

Docs: please start under Community Plugins. ZCode and Kimi Code are both agent-hook-plugin adapters, and both are documented as sections of 08-community-plugins.md rather than as numbered pages of their own. The overview reaches them through the "ZCode / AstrBot / …" row. For CodeBuddy, I'd move 20-codebuddy.md into a section there (en + zh) and fold the overview row into that existing one. Hooks are still Beta on the host side, and recall only runs in the TUI, so the community section sets the right expectations for now. The rows in 16-capability-reference.md and the {harness} entry in configuration/02-client.md should stay as they are.

On the version-bump cost: I'd take you up on your offer and land the HARNESS_KEYS line as its own small PR first, so this one stops having to re-bump six plugins on every rebase. The branch is also behind main and conflicting right now.

Happy to review the adapter version. The contract work and the transcript decoder carry over almost unchanged.


感谢这份细致的工作,尤其是 docs/HOST-CONTRACT.md:你实测了宿主行为,没有靠推断,还记下了哪些自己的假设被推翻了。这正是插件开发指南要求的做法,也让这个 PR 很好 review。你问哪些部分需要重做,下面是我对 #5857 里几个问题的回答。

接入形态:请改成 agent-hook-plugin 的宿主适配器,不要单独复制一份 Claude Code 插件。

我把每个脚本都和 claude-code-memory-plugin 逐一 diff 过。除了 cb-transcript.mjs,差异几乎全是改名(cc_ → cb_)、注释和状态路径。auto-recall.mjs 只有 6 行实质差异(is_internal_continuation);auto-capture.mjs、session-start.mjs、subagent-stop.mjs、config.mjs 和 hook 超时值都是原样搬过来的。这意味着以后约 4k 行代码每次修复都要改两份。这正是 18-plugin-development.md §9 列的第一条气味,§2.1 也明确说不要只为新增宿主名称就复制整个 Claude Code 或 Codex 目录。

你的契约文档已经证明,CodeBuddy 在事件名和输出 envelope 上和 Claude Code 一致。这部分在 agent-hook-plugin 里就是一个 stages 映射加一个 envelope()。真正的工作量在 transcript 解码,而 CodeBuddy 的 message / function_call / function_call_result 记录本来就用不上 cc-transcript.mjs 的任何代码。KimiCode 是现成先例:它同样有原生插件 manifest,最后以 hosts/kimicode.mjs + kimicode-turns.mjs 合入(#4787)。大致这样拆:

  • hosts/codebuddy.mjs:stages、envelope;prompt() 遇到 is_internal_continuation 返回 "";guard() 只做 deny、不 guard Bash,理由你的契约里已经有了。
  • hosts/codebuddy-turns.mjs:放 cb-transcript.mjs 的逻辑,接到 incremental-turn-capture.mjs 上。
  • hosts/codebuddy/:manifest、hooks 和 MCP 配置。HOST-CONTRACT.md 可以放在这里作为 DESIGN.md。
  • 安装和 kimicode 一样,走 examples/memory-plugin-shared/install.sh --harness codebuddy。安装器就在本仓库,PR 描述里说它"在仓库之外"不太准确。

目前 dispatcher 唯一表达不了的是子代理采集。我建议 v1 先不做,并在文档里标为不支持,Cursor 和 KimiCode 也是这样处理的。如果之后确实需要,再单独提 PR 给 dispatcher 加子代理阶段,并按 §3.1 写清理由,这样所有宿主都能受益。

无论走哪条路都需要改的小问题:

  1. config.mjs 里的 rootKeyFallback: true:§4.2 规定新宿主不能从参考插件照抄这个选项。CodeBuddy 没有需要兼容的旧安装。
  2. 读取 ov.conf 里 codebuddy 段和 codebuddy.enabled 的"legacy"路径,是给一个没有历史的宿主新增的兼容面,请删掉。
  3. examples/.codebuddy-plugin/marketplace.json 用同一个名字重复了根目录的 marketplace,只是为了支持本地目录安装。本地开发用 --plugin-dir 就够了。
  4. cb-transcript.mjs:TOOL_RESULT_MAX_CHARS = 0 让 truncateToolResult() 永远返回 null,是死分支;cfg 参数没有被使用;parseTranscript 对 JSON 数组的兜底,在契约里找不到依据。
  5. uri-guard.mjs 依次回退到 toolName ?? tool ?? name,这些字段契约里从没观察到过。只用 tool_name/tool_input,并通过共享的 preToolUseOutput() 生成拒绝结果,不要手工拼。
  6. 宿主压缩器的默认值("codebuddy"、"hy3")写死在适配器里。§4.1 要求宿主特有的默认值在 schema 里声明。
  7. scripts/lib/*.mjs 里只有一行 export * 的转发壳可以删掉,长篇的探测过程注释(P0/P6 记录)也可以删。这些过程记录放在设计文档或 PR 描述里即可。
  8. HOST_BLOCK_TAGS 现在在 workbuddy.py 和 JS 里各有一份。建议两边互相注明出处,或加一个小的对照测试,避免以后漂移。

文档:建议先放在社区插件一栏。 ZCode 和 Kimi Code 都是 agent-hook-plugin 适配器,文档都是 08-community-plugins.md 里的一个小节,没有单独的编号页;总览页通过 "ZCode / AstrBot / …" 那一行指向它们。CodeBuddy 建议同样处理:把 20-codebuddy.md 的内容改成那里的一个小节(中英文都要),总览页的那一行也并入现有的社区行。宿主的 hook 功能目前还是 Beta,召回也只在 TUI 里生效,放在社区栏对用户的预期更准确。16-capability-reference.md 里的行和 configuration/02-client.md 里的 {harness} 条目保持不变。

关于版本连带 bump 的成本:我同意你的提议,先把 HARNESS_KEYS 这一行单独提一个小 PR 合入,这样这个 PR 不用每次 rebase 都重新 bump 六个插件。另外,分支目前落后 main,并且有冲突。

改成适配器版本后我很乐意继续 review。契约文档和 transcript 解码这两部分基本可以原样保留。

caozeal added a commit to caozeal/OpenViking that referenced this pull request Oct 22, 2026
Per the review of volcengine#5860, the integration is documented as a section of
08-community-plugins.md in both languages rather than as a numbered page
of its own: the host's hook feature is still Beta and recall runs only
in the TUI, so the community section sets the right expectations. The
overview reaches it through the existing ZCode / AstrBot row, and the
{harness} enum in the client configuration reference gains `codebuddy`.
@caozeal
caozeal force-pushed the feat/codebuddy-memory-plugin branch from 040cceb to 8735dc5 Compare October 22, 2026 05:33
@caozeal caozeal changed the title feat(codebuddy-memory-plugin): add the CodeBuddy Code CLI as a plugin harness feat(codebuddy-memory-plugin): add the CodeBuddy Code CLI as an agent-hook adapter Oct 22, 2026
@caozeal caozeal changed the title feat(codebuddy-memory-plugin): add the CodeBuddy Code CLI as an agent-hook adapter feat(agent-hook-plugin): add the CodeBuddy Code CLI as a host adapter Oct 22, 2026
caozeal and others added 17 commits October 26, 2026 03:57
CodeBuddy matches Claude Code on event names and the output envelope, so
the adapter is a stages map plus an envelope, following the KimiCode
precedent: hosts/codebuddy.mjs owns the event mapping, the deny-only
guard (this host has no advisory channel under PreToolUse), the
is_internal_continuation prompt gate, and the capture/commit policy;
hosts/codebuddy-turns.mjs decodes CodeBuddy's JSONL transcript — where
tool calls are separate records and the human ask is wrapped in
host-injected markup — into the incremental turns the dispatcher sends.

The host contract the adapter was measured against moves in as
hosts/codebuddy/DESIGN.md, with a new section recording the adapter
mapping and the v1 scope: no subagent capture (the dispatcher has no
subagent stage), no resume/compact archive injection, and no hard-coded
compressor defaults. The three skills ship with the plugin.
The decoder cases are the ones real transcripts taught us: host blocks
around the ask, a quoted earlier turn that must not be mistaken for the
current one, host-authored records that carry no human text, and tool
calls that are separate records from the messages they belong to — plus
the incremental cursor and a parity test against the server-side
workbuddy adapter's block-tag list. The adapter cases drive the guard,
the continuation gate, the envelopes, the commit policy, and the capture
path through the real hook entry against a mock OpenViking, including
the idempotent cursor and the offline queue.
`--harness codebuddy` assembles a self-contained plugin under
~/.openviking/agent-integrations/codebuddy/marketplace/openviking-memory
— the shared runtime beside the adapters, because CodeBuddy installs
the plugin directory wholesale into its cache — registers it as a local
marketplace, and installs it through the host CLI. Detection, selection,
validation, uninstall, and the printed next steps follow the KimiCode
path. The uninstall also removes the host's cached copy, which the CLI
leaves behind.
Per the review of volcengine#5860, the integration is documented as a section of
08-community-plugins.md in both languages rather than as a numbered page
of its own: the host's hook feature is still Beta and recall runs only
in the TUI, so the community section sets the right expectations. The
overview reaches it through the existing ZCode / AstrBot row, and the
{harness} enum in the client configuration reference gains `codebuddy`.
The plugin changed, so every host-facing manifest takes a patch bump as
the version gate requires, and the CodeBuddy manifest joins the PAIRED
list: the host and the local marketplace both resolve an installed
plugin by the manifest version.
The test sets every harness toggle explicitly before tui_finish_selection;
the new codebuddy entry has to be named too, or the unset variable fails
the comparison under `set -e`.
…lost

The `codebuddy` line in the header's harness table was written without its
leading `#`, so every run of the script executed it as a command —
`codebuddy a local marketplace registered with codebuddy, installed from
~/.codebuddy/plugins` — starting a stray host session with the comment text
as its prompt. That is what stalled the test glob once: the TUI test feeds
the prelude to bash over stdin, the line ran, and the spawned session held
the runner's output pipe open.

While here, the two things that line's neighbours exposed: the top-level
toggle defaults need `SEL_CODEBUDDY` (and `SEL_KIMICODE`, which the reset
block already had) or `set -u` trips on the unset variable, and the TUI's
selectable count has to grow with the new item or the codebuddy entry is
never enumerated.
The CodeBuddy adapter changes the distributed plugin on top of the 0.5.24
release that added codebuddy to the harness keys, so every paired
host-facing manifest takes the next patch version.
… to the assistant

A tool call the model makes before writing text followed the user
message in the transcript and was folded into the user turn, so it was
captured with role user. Tool records now open an assistant turn unless
they follow an assistant message. Also drops an unused re-export.
The three skills under hosts/codebuddy/skills were committed but not
listed in SKILL_TARGETS, so sync never refreshed them and its drift
checks did not cover them.
No other agent-hook host reads captureMode, and the trigger list only
held batches back. CodeBuddy now sends every captured batch like the
other hosts.
ov-memory-doctor.mjs has no codebuddy client and falls back to Cursor,
so pointing CodeBuddy users at it reports the wrong host.
The capability reference claimed a 20,000-token threshold, a synchronous
PreCompact commit and a commit at the next start. The adapter commits
every commitTurnThreshold captured messages like Kimi Code, runs capture
detached, and SessionStart only replays queued writes.
The installer resolves each harness through channels.json, but the
release and docs-download generators hard-code their harness lists and
left codebuddy out, so a release-pinned CodeBuddy install had no entry.
Uninstall removed the plugin cache and marketplace even when the
codebuddy CLI was missing or its uninstall failed, leaving an enabled
plugin whose hooks point at deleted files. Now the files go only after
the CLI uninstall succeeds; otherwise the installer prints the commands.
The assembled plugin also no longer carries a stale hosts/codebuddy copy.
The package description and READMEs still named only the earlier hosts.
The uninstall kept every file whenever `codebuddy plugin uninstall`
failed, which it always does when install registered the marketplace
but could not install the plugin. That left a marketplace and files no
uninstall run could remove. A plugin missing from `codebuddy plugin list`
now counts as gone. The manual fallback commands are separated with `;`
so a failing first step no longer blocks the rest.
A detected ~/.codebuddy with no CLI and no OpenViking files means nothing was installed, so the keep-the-files warning was noise. Also tidy a decoder comment the role fix left stale.
@t0saki
t0saki force-pushed the feat/codebuddy-memory-plugin branch from 3c4f276 to 6be6daf Compare October 26, 2026 03:58
The zh link used the English anchor, which breaks the built-anchor check, and the section sat between the legacy custom-integration anchors and their heading. Move it next to Kimi Code in both languages.
@t0saki
t0saki merged commit 55e7357 into volcengine:main Oct 26, 2026
10 of 11 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in OpenViking project Oct 26, 2026
@t0saki

t0saki commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator

Merged — thanks for the careful work, especially the measured host contract and the decoder.

To land it we pushed a few fixes on top of your branch:

  • Version: rebased onto main after feat(config-schema): accept the codebuddy harness key #6436 and bumped agent-hook to 0.5.25.
  • Decoder: a tool call made before any assistant text is now attributed to the assistant, not the user (with a regression test).
  • Skills: the bundled skills are registered in sync.mjs, so they stay in step with examples/skills.
  • Capture: dropped the keyword capture gate, which no other agent-hook host has.
  • Docs:
    • removed the doctor advice (the doctor has no codebuddy client yet);
    • aligned the commit-policy rows with the adapter;
    • fixed the zh section anchor.
  • Release: added codebuddy to the release channel lists.
  • Uninstall: only removes the plugin files once CodeBuddy has actually let go of the plugin.

Known gap: SessionEnd/PreCompact don't commit when Stop has already sent the last turns. Kimi Code has the same behaviour, and it will be fixed for both hosts separately.


已合并,感谢细致的工作,尤其是实测的宿主契约和 transcript 解码器。

为了合入,我们在你的分支上追加了几处修复:

  • 版本: 在 feat(config-schema): accept the codebuddy harness key #6436 之后 rebase 到 main,agent-hook 升到 0.5.25。
  • 解码器: 模型在写任何文字之前就调用工具时,这次调用现在算在助手名下,不再算成用户的(附回归测试)。
  • Skill: 自带的 skill 已在 sync.mjs 登记,会和 examples/skills 保持一致。
  • 采集: 去掉了 keyword 采集过滤,其他 agent-hook 宿主都没有这个。
  • 文档:
    • 去掉了运行 doctor 的建议(doctor 目前还不支持 codebuddy);
    • commit 策略的描述改成和适配器一致;
    • 修正了中文版的章节锚点。
  • 发布: release 渠道列表加上了 codebuddy。
  • 卸载: 只有在 CodeBuddy 真正卸掉插件之后,才删除插件文件。

已知问题:Stop 已经把最后几轮发出去时,SessionEnd/PreCompact 不会再 commit。Kimi Code 也是这样,会单独修复,两个宿主一起改。

panfuy pushed a commit to panfuy/OpenViking that referenced this pull request Oct 29, 2026
commit 6afd9ba300848cd302cd00bc944b4f1d02e28476
Author: Jiahui Zhou <zhoujiahui.01@bytedance.com>
Date:   Wed Oct 28 19:37:30 2026 +0800

    feat(reindex) user orphan convergence (#6663)

    * fix(reindex): converge namespace inventories and orphan vectors

    Use complete vector inventories across fixed user and global scopes, reconcile resource, skill, memory, and peer orphans fail-closed, and preserve shared semantic queue, tags, task, and lock semantics.

    Co-authored-by: TRAE CLI <traecli@bytedance.com>

    * test(reindex): consolidate maintenance contract coverage

    ---------

    Co-authored-by: TRAE CLI <traecli@bytedance.com>
    Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>

commit 71038a1d44a89ee26f3288167b42fca16f842137
Author: bot-of-qin-ctx <qin_haojie@qq.com>
Date:   Wed Oct 28 19:15:48 2026 +0800

    fix(ci): switch API integration tests to Seed 2.1 Lite (#6735)

    Co-authored-by: qin-ptr <222410531+qin-ptr@users.noreply.github.com>
    Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>

commit a8e334c31c9df168983e6bd72422a3c8431715b3
Author: Qin Haojie <qinhaojie.exe@bytedance.com>
Date:   Wed Oct 28 17:53:09 2026 +0800

    fix(embedding): 在线检索绕过入库并发限制 (#6730)

    查询 embedding 不再占用或等待 max_concurrent 名额,入库仍由原有并发控制限流。
    解除 OpenAI 兼容客户端的活跃连接数限制,保留空闲连接复用上限。

commit eb8ae9491453f31f7c2bdd470da9621a648c73d4
Author: wang2-lat <wangjoy569@gmail.com>
Date:   Wed Oct 28 05:38:56 2026 -0400

    fix(gateway): relay a null "tools" in Responses replies instead of failing (#6309)

    An OpenAI-compatible upstream may echo "tools": null in a Responses object.
    public_response() filtered the hidden openviking_ tools out of any present
    "tools" key, so a null value raised TypeError and the request failed with
    "Invalid model tool response". Only filter when the value is a list and
    relay anything else unchanged.

    Fixes #6284

    Co-authored-by: wang2-lat <210931573+wang2-lat@users.noreply.github.com>

commit 8d7c6615d37f73eeec60d2444d31539a64fb2def
Author: Kiko0301 <xrk0301@163.com>
Date:   Wed Oct 28 17:38:22 2026 +0800

    fix(session): keep links whose endpoint probe fails transiently (#6666)

    filter_valid_links probed each link endpoint with a bare except that mapped every read failure to 'endpoint missing', permanently dropping the link. A transient storage error (timeout, hiccup) therefore severed an extracted link whose endpoints were in fact intact. Keep only typed not-found (and empty content) as the missing signal; on any other failure treat the endpoint as existing so the link survives and the rewrite below either lands it or surfaces the real storage error - matching the sibling replacement-target probe in memory_updater, which never maps transient errors to missing.

    Co-authored-by: Kiko0301 <191240073+Kiko0301@users.noreply.github.com>

commit e3768cccfd08bf7c8fdb4ae6cc683808a680e891
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Wed Oct 28 17:37:05 2026 +0800

    feat(pathlock): observe Redis acquisition latency and slow calls (#6722)

    * feat(pathlock): log slow Redis acquisitions for diagnostics

    * feat(pathlock): export Redis acquisition latency and slow-call metrics

commit 76ae604142ee32d20c1ecca1aa46370c23b66fd0
Author: chenjw <chenjunwen@bytedance.com>
Date:   Wed Oct 28 17:36:06 2026 +0800

    rerank: add optional candidate isolation for Jev (#6724)

commit 196e58201a6535b06d02a1f35ec2a34be628d6cf
Author: Alec Chen <alec929@gmail.com>
Date:   Wed Oct 28 17:35:44 2026 +0800

    fix(plugins): read profile and memory listings from peer scope (#5246)

    * fix(plugins): read profile and memory listings from peer scope

    SessionStart profile injection read `viking://user/<space>/memories/...`
    unconditionally, while capture has written to
    `viking://user/<space>/peers/<id>/memories/...` since the user/peer memory
    isolation model landed. The reader and the writer therefore never agreed on a
    path: `<user-profile>` was empty for every repository workspace, whatever was
    in the peer profile.

    `actorPeerId` was already accepted by `buildProfileBlock` and already passed by
    its caller, but it only becomes the `X-OpenViking-Actor-Peer` request header.
    That header is a view filter, not a path rewrite, so it could not redirect the
    hardcoded URIs.

    Resolve each category independently, peer scope first, user scope as fallback:

        const roots = [];
        if (actorPeerId) roots.push(`.../peers/${actorPeerId}/memories`);
        roots.push(`.../memories`);

    Per category rather than per scope, because a peer that has `preferences/` or
    `entities/` but no `profile.md` would otherwise win the scope and drop the user
    profile from the block entirely - a state that occurs in practice, not just in
    theory. That case is covered by a test.

    Request cost is unchanged in the common case (5 calls), 6 when a peer has
    listings but no profile, and 8 when the peer is absent entirely, which
    reproduces the previous `null` result exactly.

    Also fixes the test that should have caught this. Its mock answered
    `content/read` with the same body for any URI and asserted the user-scope URI,
    so it encoded the bug as expected behavior. The mock now serves a distinct body
    per scope and the peer-routing test asserts the peer body is present and the
    user body is absent.

    New unit coverage in `profile-inject.test.mjs` drives `buildProfileBlock`
    against a scope-aware fetch double and asserts which scope supplied each
    category.

    Vendored copies regenerated with `examples/memory-plugin-shared/sync.mjs`.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    * chore(plugins): bump the six distributed plugins for the peer-scope fix

    `examples/memory-plugin-shared/lib/profile-inject.mjs` changed, and the shared
    library counts as a change to every plugin that vendors it. CI's
    `check-plugin-version-bumps.sh` fails any plugin whose files changed without its
    version string moving, because hosts install by that string: a frozen version
    means users keep the build they already have no matter how many fixes land.

    Main moved twice while this branch was open. #5161 bumped every one of these
    plugins, and the kimi-code host landed afterwards with its own agent-hook bump,
    so between them main now carries a number at or past the one this branch had
    written for four of the six. Taking main's side of a version conflict and
    leaving it would satisfy the check on the letter and freeze users on the fix, so
    each plugin moves again, one patch past what main reached:

      claude-code-memory-plugin     0.6.1 -> 0.6.2   (#5161 wrote 0.6.1)
      codex-memory-plugin          0.10.1 -> 0.10.2  (#5161 wrote 0.10.1)
      agent-hook-plugin             0.5.0 -> 0.5.1   (kimicode wrote 0.5.0)
      opencode-plugin               0.4.1 -> 0.4.2   (#5161 wrote 0.4.1)
      dsh-memory-plugin             0.5.2 -> 0.5.3   (#5161 wrote 0.5.2)
      pi-coding-agent-extension     0.4.1 -> 0.4.2   (#5161 wrote 0.4.1)

    Four files beyond the watched manifests move with them:

    - `agent-hook-plugin/hosts/{cursor,trae,zcode,kimicode}/openviking.integration.json`,
      the installer manifest paired with `plugin.json`. The check fails when the two
      disagree, since a plugin that reports upgraded and behaves otherwise is worse
      than one that did not upgrade at all. `kimicode` is new on main and its
      manifest carried 0.5.0, the same value main's `plugin.json` had, so it is
      aligned on the same pass as the other three.
    - `dsh-memory-plugin/config.mjs` `PLUGIN_VERSION`, which `resolveConfig` passes
      to `buildPluginConfig`. Bumping only the manifest would leave the loader
      reporting one version while the config assembler read another, and
      `plugin-config.test` asserts the two agree.
    - `claude-code-memory-plugin/package.json` and both `dsh` lockfiles, which no
      check reads. Kept in step with the manifests to match the previous
      shared-library changes, #5132 and #5161.

    `bash .github/scripts/check-plugin-version-bumps.sh origin/main` reports `ok`
    for all six.

    Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

    * fix(plugins): choose one read scope from the actor peer

    Read the profile and both listings from a single root, picked from
    actorPeerId, so the read mirrors what capture writes. Drop the user-scope
    fallback, the scope loop and the want* state along with it, which also
    removes the length === 0 listing check.

    Remove the peer-scope test file; the codex mock already covers which scope
    is read by serving a different body per scope.

    Document the scope choice in the two capability reference files.

    * chore(plugins): move pi and the Kimi manifests past main's numbers

    Main spent the values this branch carried: #5321 took pi to 0.4.2 and the
    Kimi Code host landed agent-hook at 0.5.0. Take pi to 0.4.3 and the four
    agent-hook host manifests to 0.5.1, keeping hosts/kimicode/kimi.plugin.json
    in step with plugin.json the way main has it.

    * fix(plugins): inject both user and peer memories at session start

    Profile, preferences and entities carry no message range, so extraction
    writes the user's own facts to the user root even inside a peer session.
    Reading only the peer root hid them.

    With an actor peer, buildProfileBlock now reads both roots (six reads plus
    the skill catalog in one Promise.all). The user profile comes first and
    stays whole when it fits; the peer profile, minus lines it shares with the
    user profile, gets what is left of the same profile budget, elided when
    too long or replaced by a one-line pointer to its URI below 200 tokens.
    Preferences and entities list the user root before the peer root under
    the existing listing budget. Without a peer the block is unchanged.

    Bumps all six distributed plugins.

    ---------

    Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
    Co-authored-by: zhengxiao.wu <wzx1459931670@gmail.com>

commit c493dfc68ba6a85d5b6b860f8e18afa6cc890fa8
Author: JamesHu <88982073+Huxc2020@users.noreply.github.com>
Date:   Wed Oct 28 17:34:17 2026 +0800

    fix(memory): preserve role and peer in event chatlogs (#5113)

    * fix(memory): preserve role and peer in event chatlogs

    * test(memory): expect role and peer in upstream chatlog cases

    Upstream empty-message chatlog tests still treated peer_id as the speaker.
    Align those expectations with role-preserving labels.

    Co-authored-by: JamesHu <Huxc2020@users.noreply.github.com>

    * test(memory): load events.yaml from builtin_memory_templates_dir

    #6374 moved the bundled memory templates to system_assets and dropped the
    PromptManager import from this test module.

    ---------

    Co-authored-by: Cursor Agent <cursoragent@cursor.com>
    Co-authored-by: JamesHu <Huxc2020@users.noreply.github.com>
    Co-authored-by: zhengxiao.wu <wzx1459931670@gmail.com>

commit a586e73146e17bb498ed61f7e211fc4c15e16fb5
Author: bot-of-qin-ctx <qin_haojie@qq.com>
Date:   Wed Oct 28 17:20:16 2026 +0800

    fix(sdk/go): omit unset write and session options (#6725)

    Allow server defaults to apply to optional resource, batch-write, and
    session fields while preserving explicit values and Extra conflicts.

    Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>

commit e93f5fd3e74d3ac222280dadd09c3de35556d240
Author: Evo <r2668940489@gmail.com>
Date:   Wed Oct 28 17:13:11 2026 +0800

    fix(studio): open settings when saved credentials are rejected (#6689)

    Co-authored-by: r266-tech <r266-tech@users.noreply.github.com>

commit 6b92f9f691eae9353c021114d9cf044f2fc81e5c
Author: Vladimir Babin <vovababin@gmail.com>
Date:   Wed Oct 28 17:11:53 2026 +0800

    fix(compile): accept preserve_complete in child preview hook (#6696)

    The Compile pipeline installs complete_tool_result as the child agent's
    _preview_tool_result hook, but AgentLoop now calls that hook with a
    preserve_complete keyword argument. The hook kept its old two-parameter
    signature, so every preview call inside a Compile child raised
    TypeError and the pipeline swallowed it as 'Final review incomplete',
    publishing compiled output without the final review stage.

    Signed-off-by: Vladimir Babin <vovababin@gmail.com>

commit a1ae099393ae5eaa27ca539e4a76b181f9cb03d4
Author: LI <2484593937@qq.com>
Date:   Wed Oct 28 17:08:48 2026 +0800

    fix(ollama): bracket IPv6 hosts in tags requests (#6700)

commit e5aae34111e3df5e9de3ea939d6030b5dcab1c38
Author: akushonkamen <74654766+akushonkamen@users.noreply.github.com>
Date:   Wed Oct 28 17:02:19 2026 +0800

    fix(opencode): skip child-session capture and commit under skipSubagentSessions (#6027) (#6032)

    OpenCode child-agent sessions (session.created with parentID) were
    captured as ordinary human user messages: createSessionState() already
    derived the oc-<parent>__subagent-<id> session id from parentID, but
    handleEvent(), flushPendingMessages(), and the flushSession commit
    branch gated on isCaptureEnabled() only. Committing such a session let
    memory extraction attribute a spawned agent's task prompt to the human
    and update the human's profile.md.

    Store parentId on the session state (persisted across restarts) and
    gate message capture, flush/recovery sends, and lifecycle commits on
    config.skipSubagentSessions && parentId, matching the contract the dsh
    plugin already implements. The default (skipSubagentSessions: false,
    env OPENVIKING_SKIP_SUBAGENT_SESSIONS) keeps current behavior.

    Regression: a child session and a primary session delivering the same
    prompt text — the child must produce zero capture/commit requests
    (including after a manager reload from the persisted state file and on
    session.deleted) while the primary session is still captured.

    Fixes #6027

    Signed-off-by: akushonkamen <akushonkamen@163.com>
    Co-authored-by: zhengxiao.wu <zhengxiao.wu@bytedance.com>

commit 716fcf220e10b416c5d9c1368ae363c249d0179a
Author: hezhang-1216 <zhanghe.1216@bytedance.com>
Date:   Wed Oct 28 16:25:39 2026 +0800

    perf(system-assets): 避免重复执行启动同步 (#6701)

    * perf(system-assets): 使用清单摘要避免重复启动同步

    * fix(system): 系统资产同步遇锁冲突时退避重试

    * fix(system): 支持只读节点跳过系统资产同步

    * fix(system-assets): 构建并持久化镜像清单

    * fix(system-assets): 隔离清单构建期依赖

    * fix(system-assets): 兼容 editable wheel 构建

    * fix(system-assets): 启动开关覆盖默认账户同步

    * refactor(system-assets): 统一构建与运行时资产映射

    * test(system-assets): 精简启动同步契约测试

    ---------

    Co-authored-by: zhanghe.1216 <@bytedance.com>
    Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>

commit f3660180d64244b61ad4d7cdb0d60dbc237a264d
Author: Lusen Dong <cicomaple@gmail.com>
Date:   Wed Oct 28 15:28:09 2026 +0800

    fix(storage): surface LevelDB exec_op failures (#6716)

    Co-authored-by: TRAE CLI <traecli@bytedance.com>

commit 96ae3cef929fbe84fdbe54e14fae88a4280f67e6
Author: Xinmin Zeng <135568692+fancyboi999@users.noreply.github.com>
Date:   Wed Oct 28 00:27:10 2026 -0700

    fix(studio): preserve session list failures and retry state (#6709)

    * fix(studio): preserve session list failures and retry state (#6705)

    * fix(studio): keep initial session queries pending

commit f048ad080b372c3ac58e40334dfeaef8ea2249cd
Author: Xinmin Zeng <135568692+fancyboi999@users.noreply.github.com>
Date:   Wed Oct 28 00:21:43 2026 -0700

    fix(studio): adapt session panes to the available width (#6706) (#6710)

commit f5457afbe9608f4514da6bd87f0dd837d447cf99
Author: Xinmin Zeng <135568692+fancyboi999@users.noreply.github.com>
Date:   Wed Oct 28 00:19:18 2026 -0700

    fix(studio): fit dashboard metrics to their container (#6707) (#6711)

commit 9163513e187b7041939be245fcde16f28ccbef38
Author: Xinmin Zeng <135568692+fancyboi999@users.noreply.github.com>
Date:   Wed Oct 28 00:15:09 2026 -0700

    fix(studio): contain long skill metadata (#6708) (#6712)

commit 7192600efab4931a78dff83d0ffef9c0e04b45bb
Author: MaojiaSheng <shengmaojia@bytedance.com>
Date:   Wed Oct 28 14:49:14 2026 +0800

    fix(admin): allow role demotion and case-insensitive role input (#6714)

commit 5e0ed4305a190253f68c44d823b5b6b1f3caf925
Author: ShaoZegangByte <shaozegang@bytedance.com>
Date:   Wed Oct 28 13:59:32 2026 +0800

    Feat/l2 chunk size (#6660)

    * fix: 修复飞书标题尾空格,调整原生 L2 分块并移除 L1 采样上限

    * fix: L1截断逻辑恢复为 main

commit 4adcab74984896ced40c32cbaa1a656463946fe7
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Wed Oct 28 13:25:55 2026 +0800

    fix(pathlock): revoke lease authorization after token loss (#6704)

    * fix(pathlock): revoke lease authorization after token loss

    Track per-token confirmation deadlines for explicit and background renewal, preserve release capabilities after invalidation, and bound cleanup retries to prevent stale authorization and registry growth.

    * test(pathlock): cover Redis renewal timeout and network recovery

    Delay real Redis replies through a local TCP proxy to exercise the 20ms command timeout, retain lease authorization during a short interruption, and verify renewal and file writes recover afterwards.

    * feat(pathlock): distinguish lease invalidation causes for diagnostics

    Retain the first invalidation reason and timestamp through cleanup, and expose cause-specific log context with regression coverage and bilingual documentation.

commit 7cfa8fbe10423b746ab3fea528035d925451af62
Author: chenjw <chenjunwen@bytedance.com>
Date:   Wed Oct 28 13:20:57 2026 +0800

    docs: add RAG and memory evaluation guide (#6702)

    * docs: add RAG and memory evaluation guide

    * docs: streamline evaluation guide by scenario

    * docs: add bilingual guides and use VikingBot for memory evaluation

    * docs: separate routine VikingBot evaluation from mem0 comparisons

    * docs: clarify reproduction reference and judge leniency

    * docs: simplify VikingBot reference to the one-command runner

    * docs: clarify agent frameworks and single-turn memory QA

    * docs: note research reproduction uses for VikingBot evaluation

    * docs: clarify shared-service evaluation safety and framework scope

commit 54d4c0fac91fae976325ebed618d7278ff9b5c77
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Tue Oct 27 22:31:53 2026 +0800

    fix(pathlock): prevent path aliases from bypassing locks (#6687)

    Share logical path validation across acquisition, lease coverage, Redis, and SQLite, and reject ambiguous Lua batch paths before mutation.

commit f3d408a409abd2ca31742928f1565b8a80306e88
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Tue Oct 27 21:55:58 2026 +0800

    fix(pathlock): reject Redis Tree locks spanning scopes (#6685)

    * fix(pathlock): reject Redis Tree locks spanning scopes

    Prevent global Tree locks from reporting success without excluding account and system descendants; validate acquisition and token upgrades and document supported roots.

    * fix format

commit 15cf3ae28bed80753cf49b7613bfbcafd2e3961c
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Tue Oct 27 21:21:12 2026 +0800

    feat(ragfs): add transactional SQLite path locks (#6679)

    * feat(ragfs): add transactional SQLite path locks

    Avoid recursive business-directory scans with indexed atomic locking, recover transient Busy errors across lock operations, and add lease refresh metrics and reproducible benchmarks.

    * feat(ragfs): default SQLite lock database to workspace

    Resolve the shared lock database from the final workspace at binding initialization, while preserving explicit paths and creating parent directories automatically.

    * docs(pathlock): clarify SQLite limits for EFS deployments

    Direct EFS replicas to shared Redis PathLock and QueueFS, and explain why network-hosted SQLite or independent container databases cannot coordinate them.

    * fix(pathlock): prevent expired SQLite conflicts from reviving

    Fully remove stale conflicting targets, ancestor Tree locks, and Tree descendants in the acquisition transaction while retaining bounded global cleanup.

    * fix(pathlock): resolve SQLite defaults for canonical config paths

    Derive omitted or null SQLite paths from storage.workspace and create parent directories before provider initialization so direct config_path clients can start and share locks.

commit 3f85145b71a8e011df4deba1eced057b0409f147
Author: MaojiaSheng <shengmaojia@bytedance.com>
Date:   Tue Oct 27 20:40:25 2026 +0800

    fix(privacy): pause automatic session secret discovery (#6680)

commit ecd54b27c4831d6a798d25e4fad45018893f0212
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Tue Oct 27 20:30:17 2026 +0800

    perf(pathlock): batch Redis lease refresh by scope (#6665)

    * perf(pathlock): batch Redis lease refresh to reduce owner lock wait

    Refresh paths in bounded per-scope scripts while preserving per-path outcomes and fallback providers.

    * fix(pathlock): preserve batch refresh invalid request errors

    Decode script-level errors before per-path results so two-path batches cannot misclassify invalid requests as internal errors.

commit 3901724ac4e4e3602599de34887aeea96a29bf9e
Author: Jiahui Zhou <zhoujiahui.01@bytedance.com>
Date:   Tue Oct 27 20:24:01 2026 +0800

    feat(encryption): support inline local root key (#6678)

    Allow the local encryption provider to read a 32-byte hexadecimal root key directly from ov.conf while preserving the existing file default and envelope format. Validate source exclusivity, cover cross-mode compatibility, and document the security boundary.

    Co-authored-by: TRAE CLI <noreply@bytedance.com>
    Co-authored-by: TRAE CLI <traecli@bytedance.com>

commit d4a50718f2169948ce9d7045408c9287b4c9f781
Author: Lusen Dong <cicomaple@gmail.com>
Date:   Tue Oct 27 19:21:09 2026 +0800

    feat(cli): add OVPack progress feedback (#6675)

    Signed-off-by: lusendong.6789 <lusendong.6789@bytedance.com>
    Co-authored-by: TRAE CLI <traecli@bytedance.com>

commit e2145009cc2736df9e11b8cc8c41b479f8822169
Author: MaojiaSheng <shengmaojia@bytedance.com>
Date:   Tue Oct 27 19:08:09 2026 +0800

    feat(auth): support self-service user API key rotation (#6649)

    * feat(auth): support self-service user API key rotation

    Allow USER to list users in its own account while completely omitting other users credentials, and to rotate only its own key with personal API key authentication. Preserve existing ROOT and ADMIN key visibility.

    Automatically save self-rotated keys to the active CLI configuration with explicit stderr notices, atomic replacement, concurrent-edit detection, and recoverable output on save failure. Keep sudo and other-user rotations from replacing the personal key.

    Validation: 383 server tests and 45 Rust CLI tests passed; 15 permission cases passed after the final auth typing adjustment. Ruff lint, Rust formatting for changed modules, and diff checks passed. Mypy remains failing on existing repository typing issues.

    * feat: update ov privacy commands for agent use

    * feat: fix some review issues

commit b34a7dc484237e3d9b2050cd6c316e8a17cfc53b
Author: runyunzhou <164479727+runyunzhou@users.noreply.github.com>
Date:   Tue Oct 27 18:47:29 2026 +0800

    fix(server): preserve MySQL isolation and legacy API compatibility (#6674)

    Prevent cross-service task collisions and orphaned records while keeping MySQL deployments, account-store fallback, and deprecated SDK timeout calls working.

commit e15732a8eeb6533c327ebc0e6b458af4ae69462a
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Tue Oct 27 17:35:27 2026 +0800

    fix(cli): poll task status for add-resource --wait (#6487)

    * fix wait behavior

    * fix(cli): harden resource task waiting and interruption

    * chore: separate CLI CI changes from wait fix

    * refactor(cli): extract resource wait tests into dedicated module

    * refactor(cli): limit wait fix to task polling and exit handling

    * fix(cli): preserve cancellation and interruption error semantics

    Return CANCELLED for cancelled resource tasks and preserve the JSON error envelope on Ctrl+C while retaining exit code 130. Cover null cancellation results and interruption output selected through CLI flags or configuration.

commit db808df316cee8812c7a129329ee1d8ca59bf632
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Tue Oct 27 17:22:14 2026 +0800

    test(ci): mock models for integration tests without credentials (#6657)

    Use deterministic embedding and VLM responses so basic API and CLI tests can run on fork PRs without model secrets.

commit f6e0ed9f48e82a715fc34fb3a7d865296dd49ab7
Author: dingben <1162833047@qq.com>
Date:   Tue Oct 27 17:06:10 2026 +0800

    fix(storage): require manage for shared resource deletion (#6643)

    * fix(storage): require manage for shared resource deletion

    * fix(storage): align resource mutation ACL requirements

    * refactor(storage): simplify import cleanup and trim ACL tests

    * fix(parse): clean generated image mappings internally

    * test(storage): reduce ACL coverage to core contracts

    * refactor(storage): use manage directly for removal authorization

    * fix(service): scope manage checks to public move and delete

    ---------

    Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>

commit 25b5a5e5c89ab34587e38419074fb964dd7ae2a6
Author: t0saki <15712521+t0saki@users.noreply.github.com>
Date:   Tue Oct 27 16:59:34 2026 +0800

    feat(gateway): configure session expiry in seconds (#6651)

    * test(gateway): require cross-pod delivery only for the idle tail

    Co-authored-by: TRAE CLI <traecli@bytedance.com>

    * feat(gateway): configure session expiry in seconds

    Replace session_ttl_days with session_ttl_seconds (default 30 days,
    minimum 3600) so a Redis-backed gateway can keep idle sessions for an
    hour or two. The floor keeps the TTL above capture's default 600-second
    idle tail. A legacy session_ttl_days is still accepted and converted to
    seconds; the chart default becomes session_ttl_seconds: 604800.

    ---------

    Co-authored-by: TRAE CLI <traecli@bytedance.com>

commit 1e7b90a41fef968f25da363c14f9fff0e4be0372
Author: t0saki <15712521+t0saki@users.noreply.github.com>
Date:   Tue Oct 27 15:56:57 2026 +0800

    feat(dsh): support DeepSeek Harness Desktop (#6626)

    * feat(dsh): support DeepSeek Harness Desktop

    DeepSeek Harness Desktop keeps its plugins in a reserved `desktop` profile
    that only the `dsh` launcher inside the app may change; npm `dsh` refuses it
    and no `dsh` can boot it or run `--dump-config` on it. The bundle itself runs
    there unchanged, so this teaches the installer, docs and CI about Desktop and
    fixes three bundle issues found along the way.

    - install.sh: macOS-only `dsh-desktop` harness (auto-detected, coexists with
      `dsh`; `--dsh-profile desktop` routes to it), launcher lookup, initialized
      and quit checks, Plugins-page fallback, `plugin ls` verification.
    - dsh bundle 0.5.30: `pwsh` URI notice, keep pre-step decision fields,
      Plugins-page detail doc via `meta.detail`.
    - shared uri-guard: `pwsh`/`powershell` count as shell tools (version bumps
      for every plugin consuming the shared lib).
    - docs (en/zh): Desktop section and troubleshooting in 17-dsh and related pages.
    - CI: host-compat Desktop launcher-emulation smoke step.

    Claude-Session: https://claude.ai/code/session_016CaBZ9C7WXtiTg7q5jBshj

    * docs(dsh): make the Desktop Plugins page a manual option with its own auth step

    The Plugins page only adds the bundle and never asks for OpenViking
    credentials, so present it as the manual path (the only one on Windows)
    after the installer, with writing ovcli.conf as its first step. Match the
    real Desktop UI: Add plugin, enter the package, Install, with the install
    source menu; drop the unverified "Install a third-party plugin" and
    "Enable now" labels from the docs and the installer's fallback hint.

    Claude-Session: https://claude.ai/code/session_016CaBZ9C7WXtiTg7q5jBshj

commit 9853c3319fb4027b19e72f0fbbbeec2abb2eef79
Author: z1gon <130889443+ehz0ah@users.noreply.github.com>
Date:   Tue Oct 27 15:00:39 2026 +0800

    ci(maf): add trusted PyPI publishing (#6483)

    * ci(maf): add trusted PyPI publishing

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    * chore(maf): name package for Microsoft Agent Framework

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    * chore(maf): license standalone adapter under MIT

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    ---------

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

commit f9bc07fad1b3f4fbe7e6b20bf92091e51123c897
Author: baojun-zhang <zhangbaojun.1@bytedance.com>
Date:   Tue Oct 27 14:04:46 2026 +0800

    feat(multiwrite): 多写 IOPS 优化 (#6646)

    1. 去除启动 checkpoint ticker,避免重复启动导致的 IOPS 峰值
    2. 增加随机值设置初次 checkpoint 时机,防止多实例同时启动导致并发 IOPS 峰值
    3. flush worker 使用内存缓存记录account 分区信息,而不是每个 batch 查询 account 分区信息
    4. 增加部分进度日志

commit f9e55078b08876d312c763a0c82b456dfb0e444c
Author: dingben <1162833047@qq.com>
Date:   Tue Oct 27 11:27:10 2026 +0800

    Fix/resource move acl 20261027 (#6641)

    * fix(storage): require manage for resource moves and overwrites

    * test(storage): annotate ACL move test doubles

commit 60e48ca4ab0bd7409e764eaab5fb1dcfd263a169
Author: Qin Haojie <qinhaojie.exe@bytedance.com>
Date:   Tue Oct 27 11:26:47 2026 +0800

    refactor(session): remove legacy path compatibility (#6642)

    Stop probing obsolete session storage paths during normal operations and
    reject the legacy session URI alias. Update bundled callers to use current
    session URIs.

commit fb92347a09d810c787ef723b5bc6f5c038d17d1e
Author: ordinary being <majiantong666@qq.com>
Date:   Tue Oct 27 11:06:46 2026 +0800

    fix(queue): stop deduplicating the retries that run before a lease exists (#6197)

    The memory-parent window (45s, #769) is skipped for retries that hold a lease:
    _enqueue_semantic_retry already calls enqueue(..., deduplicate_memory=False) and
    raises if the queue still answers 'deduplicated'.

    The retries that run before a lease is acquired do not. breaker.check() happens
    before work.acquire_lock(), so an open circuit breaker re-enqueues through
    SemanticMessageWork.reenqueue's no-lock branch, which called
    queue.enqueue(msg) with deduplication on. If the message was first queued less
    than 45s earlier, the retry was replaced by 'deduplicated', the caller still
    returned ProcessResult.requeued(), and the worker ACKed the only delivery -
    the work was lost with no error and no replacement.

    SkillSemanticMessageWork.reenqueue has the same shape.

    Pass deduplicate_memory=False in both no-lock branches, reusing the flag the
    lock-owning path introduced rather than adding a second mechanism.

    Reachable for memory-context messages without a coalesce_key (utils/summarizer.py
    derives context_type from the URI), and for a stale message downgraded to
    file-only work, since that path clears coalesce_key before retrying.

    Does not add retry bounding or backoff; that stays with #4451.

    Co-authored-by: helson <helson@users.noreply.github.com>

commit 2425cf41b9120bffdc83723afc9d8473a7794407
Author: hezhang-1216 <zhanghe.1216@bytedance.com>
Date:   Tue Oct 27 10:29:06 2026 +0800

    fix(compile): 禁止 system 命名空间作为输出目录Fix/system compile to namespace (#6634)

    * fix(compile): skip snapshots for system skills

    * fix(compile): 禁止 system 命名空间作为输出目录

    ---------

    Co-authored-by: fujiajie.168 <fujiajie.168@bytedance.com>
    Co-authored-by: zhanghe.1216 <@bytedance.com>

commit 5c066d97094d713238c483c10691d7b4e1cfbf6e
Author: hezhang-1216 <zhanghe.1216@bytedance.com>
Date:   Mon Oct 26 23:02:36 2026 +0800

    fix(storage): 修复递归删除导致 PathLock 提前失效 (#6631)

    * fix(storage): 修复递归删除导致 PathLock 提前失效

    将目录锁迁移到父目录 sidecar,并兼容旧锁与 handoff;删除获锁后重新确认目标状态,避免并发请求沿用过期判断。

    * test(storage): 补充 PathLock 路径关系矩阵

    使用共享文件系统上的独立 Manager 验证祖先、后代与兄弟路径的冲突和非冲突语义,防止 sidecar 迁移引入锁范围回归。

    * fix(storage): 收敛 PathLock sidecar 迁移协议

    拆分 Tree 路径解析并修正根路径寻址,撤回无关的 Snapshot 行为变化,同时明确新旧锁协议的切换约束,降低迁移影响范围。

    ---------

    Co-authored-by: zhanghe.1216 <@bytedance.com>

commit 5ec33e2973364cb9a4e92ddd2233a62442134e51
Author: zhanglistar <zhanglinuxstar@gmail.com>
Date:   Mon Oct 26 21:47:20 2026 +0800

    ci: run Rust CLI tests before publishing (#6624)

    * ci: run Rust CLI tests before publishing

    * ci: use default stack size for Rust CLI tests

    * ci: restore test stack override for CLI help tests

commit d840333cfdd9964ca7258933053dc21d176b95d1
Author: xiejianqiao <xiejianqiao.1027@bytedance.com>
Date:   Mon Oct 26 20:11:13 2026 +0800

    fix(storage): 修复中文路径的旧版锁交接恢复 (#6620)

    Co-authored-by: TRAE CLI <traecli@bytedance.com>

commit 026f1a23b8873ce9654effedf8f8eb7e3d8f319a
Author: t0saki <15712521+t0saki@users.noreply.github.com>
Date:   Mon Oct 26 19:08:11 2026 +0800

    feat(gateway): run the standalone gateway as a multi-replica service on Redis (#6513)

    * feat(gateway): let clients override the context profile with X-OpenViking-Context

    * feat(gateway): accept OpenViking API keys in place of gateway keys

    * feat(gateway): run the standalone gateway as a multi-replica service on Redis

    Make the standalone gateway deployable as a stateless Kubernetes service:

    - Storage ports with SQLite (default) and Redis (standalone or Cluster)
      adapters for kernel state and management data; atomic writes are single-slot
      Lua scripts, session data expires after session_ttl_days.
    - Headless deployment settings: management_api switch, tenancy=key,
      default_upstreams/default_profile, stdout request logs.
    - Concurrent capture delivery with a bounded shutdown drain, startup waiting
      for OpenViking on public binds, longer keep-alive, SSE idle heartbeats.
    - X-OpenViking-Upstream-URL lets a host in front of the gateway pick one of
      the key's upstreams by base_url; any other URL is refused with 403.
    - OpenViking 402/403 refusals reject the request; 401 during capture revokes
      the cached key.
    - Helm chart, image self-check, operations docs and a kind acceptance suite.

    * fix(gateway): address review of the multi-replica gateway

    - Refuse requests only on OpenViking 402/403. Any other /health error,
      including the missing identity OV returns when its account store fails,
      degrades to revocation_check_unavailable as before.
    - Delete a key after a 401 during capture only when /health also returns
      401. OpenViking answers 401 for its own model auth failures too.
    - Queue Redis commands beyond pool_size instead of failing with
      "Too many connections"; redis-py async pools never block.
    - Refuse to create a new Volcengine KMS root key when the configured
      key_file is missing but the default one exists: earlier releases
      ignored key_file and kept the key at the default path.

commit 07b5181d61c18d8a0c187bb7a9bc53729fca4058
Author: Qin Haojie <qinhaojie.exe@bytedance.com>
Date:   Mon Oct 26 18:41:16 2026 +0800

    fix(metrics): 复用标准 SDK 并修复长耗时统计 (#6474)

    * fix(metrics): 修复长耗时 P95/P99 封顶与分桶混算

    扩展耗时分桶并按实际桶布局隔离分位数统计,避免慢操作失真及滚动升级时混算;同步原生锁扫描指标、看板和文档。

    * refactor(metrics): 复用标准 SDK 完成指标统计与导出

    保留业务指标名、标签和监控接入,将 Python 与 RAGFS 耗时累计交给 OpenTelemetry SDK,并使用官方 OTLP 导出器及 Prometheus 客户端,删除手写分桶与协议实现。

    * refactor(metrics): 清理 SDK 接入后的重复接口和旧兼容层

    统一状态删除入口,把原生校验保留在输入边界,移除无调用的全局入口、转发工厂、重复开关及只为旧测试保留的兼容分支。

commit df87b21857c9023f1be30cc981a1f2f49cca49f1
Author: baojun-zhang <zhangbaojun.1@bytedance.com>
Date:   Mon Oct 26 18:08:15 2026 +0800

    feat(ragfs): gate existing data reconciliation (#6617)

    Add a multi-write backup option to control whether startup scans pre-existing primary files into V2 metadata.

    Document the default disabled behavior and the conditions where historical backfill can be skipped.

commit c81e4e123fdc8dfa7985410611e2bde32bfa6f8e
Author: Caucher Wang <caucherw@gmail.com>
Date:   Mon Oct 26 17:59:37 2026 +0800

    docs: add Rules (Beta) guides and API reference (#6613)

    * docs: add customer-facing Rules Beta guides and API reference

    * docs: place VikingBot rule tool note in introduction

    * docs: mark rule search Beta in existing VikingBot tool tables

    * docs: use Chinese terminology throughout rule documentation

    * Revert "docs: use Chinese terminology throughout rule documentation"

    This reverts commit c32a3be402b4bde739fe8021c8b63f44ec0a64a7.

    ---------

    Co-authored-by: zeyu wang <wangzeyu.bd@bytedance.com>

commit d6271e630b04808c58905aa509df58fe63c8a506
Author: MaojiaSheng <shengmaojia@bytedance.com>
Date:   Mon Oct 26 17:05:06 2026 +0800

    fix(auth): reveal only the caller's own user API key in admin listings (#6610)

    * fix(auth): mask stored user API keys in admin listings

    * fix(auth): reveal only the caller's own user key in admin listings

    - non-ROOT list_users responses keep plaintext api_key solely for the
      caller's own row, requiring strict match of listing account, row user
      and the account/user segments embedded in the key; all other rows stay
      masked key_prefix
    - apply the same rule to MCP list_users(include_credentials=true)
    - CLI list-users merges api_key/key_prefix into one api_key table column,
      masks by default, and reveals plaintext via --reveal-api-keys
    - move FileStore from api_keys/legacy.py to account_stores/file.py and
      require the three-segment key format; update memory doctor diagnostics
    - sync zh/en docs and tests

    Co-authored-by: TRAE CLI <traecli@bytedance.com>

    ---------

    Co-authored-by: TRAE CLI <traecli@bytedance.com>

commit 1f323923ab5b4a7e6051169bb452b542ef984347
Author: Zayn Jarvis <zaynjarvis@gmail.com>
Date:   Mon Oct 26 02:01:17 2026 -0700

    docs: refresh WeChat group QR code (#6602)

commit 22a28101089515ddef85b96617449924baef9f35
Author: leebai <39912100+leeebai@users.noreply.github.com>
Date:   Mon Oct 26 15:52:29 2026 +0800

    feat: add DingTalk connector OAuth auth (#6609)

    * feat(feishu_doc): support connector oauth imports

    * feat: add dingtalk connector auth

    ---------

    Co-authored-by: duyuxuan <duyuxuan.0518@bytedance.com>
    Co-authored-by: baile <baile@bytedance.com>

commit c7239e819eb77f1c33525f421528f46eedb5dd9a
Author: t0saki <15712521+t0saki@users.noreply.github.com>
Date:   Mon Oct 26 15:44:32 2026 +0800

    fix(retrieve): opt-in rerank for context mode and decouple rerank.threshold (#6605)

    Context mode recalls through QUICK find()/find_skills, so a configured
    reranker never affected it (#6182). Add retrieval.apply_rerank_to_context
    (default false): one rerank call over the merged, deduplicated pool before
    quota allocation and budgeting, with wider recall, skill abstracts filled
    first, and fallback to vector scores.

    rerank.threshold now filters only scores the reranker produced; vector-only
    paths default to 0 unless the request sets score_threshold. Extract the
    rerank scoring into openviking/retrieve/rerank_scoring.py so the retriever
    and the context assembler share it.

    Fixes #6182

commit 7993aa83ab23b6ad8b966740f5d68e488a268714
Author: Caucher Wang <caucherw@gmail.com>
Date:   Mon Oct 26 15:22:51 2026 +0800

    feat(rule): add rule service and expose new tool (openviking_rule_search) to agents (#6364)

    * feat(rules): add compiled rule service and SDK

    * refactor(rules): remove undefined condition field

    * refactor(rules): judge applicability clauses separately

    * refactor(rules): rename exception field

    * refactor(rules): drop legacy exception alias

    * refactor(rules): batch Jev applicability judgments

    * refactor(rules): use direct Jev judgments

    * fix(rules): require applicability conditions

    * fix(rules): send only true Jev criteria

    * refactor(rules): simplify rendered guidance

    * feat(rules): add rule search example skill

    * fix(rules): make compile tasks complete reliably

    * refactor(rules): use scenarios and simplify rule lifecycle

    * feat(bot): expose compiled rule search to agents

    * docs(bot): name rule applicability fields

    * docs(bot): use exception rule field

    * test(bot): remove legacy rule field reference

    * docs(rules): clarify scenario semantics

    * docs(rules): clarify compile clients and move scenario guide

    * docs(rules): simplify rule search guidance

    * docs(rules): describe Jev matcher configuration accurately

    * docs(rules): document Jev matcher fields

    * refactor(rules): decouple Jev judgments from reranking

    * refactor(rules): simplify Jev provider configuration

    * refactor(rules): reuse shared time utilities

    * refactor(bot): declare complete tool result delivery

    * fix(docs): register rule scenario concept pages

    * fix(rules): harden compilation and resource ingestion

    * #6531 bug fix

    * docs-update-on-vlm-thinking-override

    * fix(rules): constrain updates and archive lifecycle

    * test: skip system asset sync for mock service

    * Revert "test: skip system asset sync for mock service"

    This reverts commit 0e8a17498715a3b4ff3dac03becea3a0bf3d6bd6.

    ---------

    Co-authored-by: zeyu wang <wangzeyu.bd@bytedance.com>

commit d15b28dd2953d42bc75ec9f399cfcae51371511e
Author: leowld <56757310+leowld@users.noreply.github.com>
Date:   Mon Oct 26 14:44:19 2026 +0800

    feat(studio): improve Compile first-use workflow (#6491)

    * feat(studio): improve Compile first-use workflow

    * fix(studio): refresh filesystem caches after Compile completes

commit f2ed858206160e07cb1abcde544c45253026cb07
Author: baojun-zhang <zhangbaojun.1@bytedance.com>
Date:   Mon Oct 26 14:29:10 2026 +0800

    fix(multiwrite): 取消删除 v1 元数据时 glob 操作,在 import account 阶段进行删除 && 增加迁移阶段执行进度日志 (#6604)

commit 55e735769af639c87749a0516a34902e4d556ebb
Author: CodePlayer <18304010993@163.com>
Date:   Mon Oct 26 13:10:20 2026 +0800

    feat(agent-hook-plugin): add the CodeBuddy Code CLI as a host adapter (#5860)

    * feat(agent-hook-plugin): add the CodeBuddy Code host adapter

    CodeBuddy matches Claude Code on event names and the output envelope, so
    the adapter is a stages map plus an envelope, following the KimiCode
    precedent: hosts/codebuddy.mjs owns the event mapping, the deny-only
    guard (this host has no advisory channel under PreToolUse), the
    is_internal_continuation prompt gate, and the capture/commit policy;
    hosts/codebuddy-turns.mjs decodes CodeBuddy's JSONL transcript — where
    tool calls are separate records and the human ask is wrapped in
    host-injected markup — into the incremental turns the dispatcher sends.

    The host contract the adapter was measured against moves in as
    hosts/codebuddy/DESIGN.md, with a new section recording the adapter
    mapping and the v1 scope: no subagent capture (the dispatcher has no
    subagent stage), no resume/compact archive injection, and no hard-coded
    compressor defaults. The three skills ship with the plugin.

    * test(agent-hook-plugin): cover the CodeBuddy adapter and its decoder

    The decoder cases are the ones real transcripts taught us: host blocks
    around the ask, a quoted earlier turn that must not be mistaken for the
    current one, host-authored records that carry no human text, and tool
    calls that are separate records from the messages they belong to — plus
    the incremental cursor and a parity test against the server-side
    workbuddy adapter's block-tag list. The adapter cases drive the guard,
    the continuation gate, the envelopes, the commit policy, and the capture
    path through the real hook entry against a mock OpenViking, including
    the idempotent cursor and the offline queue.

    * feat(installer): install the CodeBuddy Code integration

    `--harness codebuddy` assembles a self-contained plugin under
    ~/.openviking/agent-integrations/codebuddy/marketplace/openviking-memory
    — the shared runtime beside the adapters, because CodeBuddy installs
    the plugin directory wholesale into its cache — registers it as a local
    marketplace, and installs it through the host CLI. Detection, selection,
    validation, uninstall, and the printed next steps follow the KimiCode
    path. The uninstall also removes the host's cached copy, which the CLI
    leaves behind.

    * docs: document CodeBuddy Code under Community Plugins

    Per the review of #5860, the integration is documented as a section of
    08-community-plugins.md in both languages rather than as a numbered page
    of its own: the host's hook feature is still Beta and recall runs only
    in the TUI, so the community section sets the right expectations. The
    overview reaches it through the existing ZCode / AstrBot row, and the
    {harness} enum in the client configuration reference gains `codebuddy`.

    * chore(plugins): bump agent-hook-plugin for the CodeBuddy host

    The plugin changed, so every host-facing manifest takes a patch bump as
    the version gate requires, and the CodeBuddy manifest joins the PAIRED
    list: the host and the local marketplace both resolve an installed
    plugin by the manifest version.

    * test(installer): name the codebuddy toggle in the TUI selection test

    The test sets every harness toggle explicitly before tui_finish_selection;
    the new codebuddy entry has to be named too, or the unset variable fails
    the comparison under `set -e`.

    * fix(installer): restore the comment marker the codebuddy header line lost

    The `codebuddy` line in the header's harness table was written without its
    leading `#`, so every run of the script executed it as a command —
    `codebuddy a local marketplace registered with codebuddy, installed from
    ~/.codebuddy/plugins` — starting a stray host session with the comment text
    as its prompt. That is what stalled the test glob once: the TUI test feeds
    the prelude to bash over stdin, the line ran, and the spawned session held
    the runner's output pipe open.

    While here, the two things that line's neighbours exposed: the top-level
    toggle defaults need `SEL_CODEBUDDY` (and `SEL_KIMICODE`, which the reset
    block already had) or `set -u` trips on the unset variable, and the TUI's
    selectable count has to grow with the new item or the codebuddy entry is
    never enumerated.

    * chore(plugins): bump agent-hook-plugin to 0.5.25 for the CodeBuddy host

    The CodeBuddy adapter changes the distributed plugin on top of the 0.5.24
    release that added codebuddy to the harness keys, so every paired
    host-facing manifest takes the next patch version.

    * fix(agent-hook-plugin): attribute CodeBuddy tool use before any reply to the assistant

    A tool call the model makes before writing text followed the user
    message in the transcript and was folded into the user turn, so it was
    captured with role user. Tool records now open an assistant turn unless
    they follow an assistant message. Also drops an unused re-export.

    * chore(plugins): register the CodeBuddy skill copies with the shared sync

    The three skills under hosts/codebuddy/skills were committed but not
    listed in SKILL_TARGETS, so sync never refreshed them and its drift
    checks did not cover them.

    * refactor(agent-hook-plugin): drop the CodeBuddy keyword capture gate

    No other agent-hook host reads captureMode, and the trigger list only
    held batches back. CodeBuddy now sends every captured batch like the
    other hosts.

    * docs: drop the CodeBuddy doctor advice

    ov-memory-doctor.mjs has no codebuddy client and falls back to Cursor,
    so pointing CodeBuddy users at it reports the wrong host.

    * docs: describe the CodeBuddy commit policy the adapter implements

    The capability reference claimed a 20,000-token threshold, a synchronous
    PreCompact commit and a commit at the next start. The adapter commits
    every commitTurnThreshold captured messages like Kimi Code, runs capture
    detached, and SessionStart only replays queued writes.

    * chore(plugins): publish a codebuddy release channel

    The installer resolves each harness through channels.json, but the
    release and docs-download generators hard-code their harness lists and
    left codebuddy out, so a release-pinned CodeBuddy install had no entry.

    * fix(installer): keep CodeBuddy plugin files until the host uninstalls it

    Uninstall removed the plugin cache and marketplace even when the
    codebuddy CLI was missing or its uninstall failed, leaving an enabled
    plugin whose hooks point at deleted files. Now the files go only after
    the CLI uninstall succeeds; otherwise the installer prints the commands.
    The assembled plugin also no longer carries a stale hosts/codebuddy copy.

    * docs(agent-hook-plugin): list CodeBuddy Code among the supported hosts

    The package description and READMEs still named only the earlier hosts.

    * fix(installer): clean up a CodeBuddy plugin the host never installed

    The uninstall kept every file whenever `codebuddy plugin uninstall`
    failed, which it always does when install registered the marketplace
    but could not install the plugin. That left a marketplace and files no
    uninstall run could remove. A plugin missing from `codebuddy plugin list`
    now counts as gone. The manual fallback commands are separated with `;`
    so a failing first step no longer blocks the rest.

    * fix(installer): stay quiet when there is no CodeBuddy install to remove

    A detected ~/.codebuddy with no CLI and no OpenViking files means nothing was installed, so the keep-the-files warning was noise. Also tidy a decoder comment the role fix left stale.

    * docs: fix the CodeBuddy notes anchor and placement

    The zh link used the English anchor, which breaks the built-anchor check, and the section sat between the legacy custom-integration anchors and their heading. Move it next to Kimi Code in both languages.

    ---------

    Co-authored-by: zhengxiao.wu <zhengxiao.wu@bytedance.com>

commit 9a57854d51dd598e10a96f4d805268a0f1c16736
Author: CodePlayer <18304010993@163.com>
Date:   Mon Oct 26 11:57:29 2026 +0800

    feat(config-schema): accept the codebuddy harness key (#6436)

    Add `codebuddy` to HARNESS_KEYS so a `plugin.codebuddy` section in ov.conf
    resolves to a real harness override instead of being reported as a typo.
    This is the shared-library half of the CodeBuddy Code integration; the host
    adapter that consumes it lands separately in agent-hook-plugin.

    The shared library reaches every registered plugin, so all six take a patch
    bump as the version gate requires.

commit 009c483f20806d63979cec0f3a7fb1304fd600df
Author: bot-of-qin-ctx <qin_haojie@qq.com>
Date:   Mon Oct 26 11:40:46 2026 +0800

    fix(deps): require SDK 0.1.17 for Compile APIs (#6596)

    Use the published SDK that supports directory diffs and Compile write options.
    Refresh the lockfile, including the existing bot numpy requirement.

    Co-authored-by: qin-ptr <222410531+qin-ptr@users.noreply.github.com>
    Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>

commit 178988b059c7e5a691b60d7ce8dcdf2b66249827
Author: baojun-zhang <zhangbaojun.1@bytedance.com>
Date:   Mon Oct 26 11:36:05 2026 +0800

    fix(ragfs): 在外部租约下跳过冗余加密锁 (#6595)

commit 4ab22a4923452362b60aef2826c2083ce36168d2
Author: Jiahui Zhou <zhoujiahui.01@bytedance.com>
Date:   Sat Oct 24 00:17:08 2026 +0800

    fix(release): pin wheel and CLI versions to release tag (#6488)

commit 2260f6899e882a8d7f693cca4dd8559dfc66b8cf
Author: z1gon <130889443+ehz0ah@users.noreply.github.com>
Date:   Fri Oct 23 18:22:49 2026 +0800

    fix(langchain): isolate session commits and report reset failures (#6479)

    * fix(langchain): isolate capture commit policies

    (cherry picked from commit e2440e409b14e1f47b95ceaec2a3b6d547140932)
    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    * fix(langchain): report history reset recreation failures

    (cherry picked from commit 3b2591cde30a1e6e41f158bd1052795eeddfa814)
    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    * test(langchain): validate session lifecycle fixes

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    ---------

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>
    Co-authored-by: ktz03 <2484593937@qq.com>

commit d164def87a2a376df6653eab5c206e00109777b1
Author: t0saki <15712521+t0saki@users.noreply.github.com>
Date:   Fri Oct 23 16:43:27 2026 +0800

    Revert "feat(plugins): redact secrets in captured transcripts before sending …" (#6475)

    This reverts commit b4d6d11fdff747f4d835209282a506468c1561aa.

commit b4d6d11fdff747f4d835209282a506468c1561aa
Author: t0saki <15712521+t0saki@users.noreply.github.com>
Date:   Fri Oct 23 16:35:05 2026 +0800

    feat(plugins): redact secrets in captured transcripts before sending (#6455)

    * feat(plugins): add gitleaks-based secret redaction engine

    * feat(plugins): redact captured messages before sending under captureRedact

    * docs(plugins): document captureRedact secret redaction

    * chore(plugins): bump plugin versions for capture redaction

commit d5022f57559fef83b14c63789ca75a0b2dc7a9c9
Author: z1gon <130889443+ehz0ah@users.noreply.github.com>
Date:   Fri Oct 23 16:19:07 2026 +0800

    fix(langchain): honor nested filters and index field selectors (#6404)

    * fix(langchain): match nested JSON store filters

    (cherry picked from commit f6471b877ce1967455a7fd78015281c5f82308e5)
    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    * fix(langchain): index LangGraph store field selectors

    (cherry picked from commit 3c7bcae3f5410b7b6d7c38ee17563721ccb8fe39)
    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    * test(langgraph): cover filtered recall of selected fields

    Exercise selected index fields and nested filters together through sync, async and batch search. Check caller values remain unchanged and document projection refresh behavior in both guides.

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    * docs(langchain): clarify reserved nested filter operators

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>

    ---------

    Signed-off-by: Hao Zhe <haozhe4547@gmail.com>
    Co-authored-by: ktz03 <2484593937@qq.com>

commit 0d546854b4be4b24a277c1b3ca7cf06c02d61a14
Author: Wenxi Zhu <58896580+J-StrawHat@users.noreply.github.com>
Date:   Fri Oct 23 11:51:09 2026 +0800

    feat(privacy): support automatic privacy extraction and restore for sessions (#6278)

    * feat(privacy): add rule-based session credential extraction

    * feat(session): apply privacy policy to message writes

    * feat(privacy): restore session credentials on content reads

    * feat(sdk): support session privacy policy

    * docs(privacy): document session privacy policies and behavior

    * test(privacy): cover session extraction and restoration

    * refactor(privacy): remove session privacy policy switches

    * perf(privacy): move session credential extraction to Rust

    * feat(privacy): reuse registered credentials in session writes

    * feat(privacy): restore owner-bound references in session reads

    * docs(privacy): update session extraction and restore documentation

    * test(privacy): cover session credential reuse and restoration

    * feat(privacy): shorten session privacy field IDs

    * fix(privacy): preserve markdown credential boundaries

    * feat(privacy): prefer credentials and shorten session placeholders

    * fix(docs): escape privacy placeholders

    * fix(privacy): scope Basic detection and reuse batch text references

    * fix(privacy): map session IDs to valid privacy targets

    * fix(privacy): preserve privacy references on default reads

    * fix(docs): escape privacy placeholders in MCP guides

    * fix(privacy): unify skill and session placeholder restoration

    * fix(privacy): keep session placeholders consistent across messages

commit 078199e37224f4376fab7411fb3029ee059b63a4
Author: jmCalvinhyl <mjh5987@gmail.com>
Date:   Fri Oct 23 11:45:37 2026 +0800

    fix(studio): restore internal Markdown images and navigation (#6388)

    Allow viking image and link protocols while retaining default sanitization.
    Reuse authenticated image downloads and resource navigation, preserve enclosing
    links, and add keyboard navigation and lifecycle regression coverage.

    Co-authored-by: leowld <56757310+leowld@users.noreply.github.com>

commit 07c84bf7474a49749e23a0161619853afd964dff
Author: leowld <56757310+leowld@users.noreply.github.com>
Date:   Fri Oct 23 11:41:13 2026 +0800

    feat(studio): align filesystem CLI commands and task interactions (#6463)

    * feat(studio): add workspace setup and dual-provider experience

    * fix(studio): guard workspace changes and preserve saved sessions

    * fix(studio): preserve distinct workspaces on HTTP deployments

    * fix(web-studio): move hosted connection choice to verification step

    * fix(web-studio): label hosted connections by workspace identity

    * fix(web-studio): restore hosted address and key steps

    * fix(web-studio): switch among saved connections across providers

    * fix(studio): bind upload queues to their source connection

    Queued uploads outlived their provider and resolved later requests through the mutable global client. Capture an independent client for the source connection, abort pending operations on unmount, and verify ownership before queued uploads and import continuations.

    Cover two-file workspace switches, same-service credential changes, delayed remote responses, normal sequential uploads, and StrictMode task loading.

    * Align fork main with upstream source tree

    * feat(studio): manage snapshots and OVPack in filesystem

    * fix(studio): show snapshot changes in a bounded comparison view

    * feat(studio): compare selected snapshot versions separately

    * feat(studio): compare snapshots when versions change

    * fix(studio): open comparison from version history only

    * style(studio): place version comparison below history

    * feat(studio): refine snapshot history and comparison

    * fix(studio): render internal Markdown images and preserve navigation

    * fix(studio): enable snapshots for hosted connections

    * feat(studio): show OVPack controls for hosted resources

    * refactor(studio): separate OVPack import and export tabs

    * fix(studio): make OVPack file picker prominent

    * fix(studio): close OVPack dialog after successful import

    * fix(studio): finish OVPack import after closing dialog

    * fix(studio): keep OVPack import dialog open while loading

    * chore(studio): remove unused snapshot restore flow

    * fix(studio): compare snapshots when a file is absent

    * feat(studio): align terminal commands and task interactions

    * feat(studio): show terminal command parameter hints

    * feat(studio): show CLI panel for hosted connections

    * fix(studio): separate history dialog actions

    * fix(studio): hide new session action on empty draft

    * docs(studio): add CLI interaction demo

    * test(studio): cover visible new session action

    * fix(studio): address CLI review findings

    * fix(studio): refresh explorer caches after compile

    ---------

    Co-authored-by: OpenViking Auto Deploy <openviking-auto-deploy@users.noreply.github.com>
    Co-authored-by: OpenViking Fork Sync <openviking-fork-sync@users.noreply.github.com>

commit 824e9c7ff5e7cebbc36f55257c39f8bbe75d5a24
Author: duyuxuan0518 <92612407+duyuxuan0518@users.noreply.github.com>
Date:   Thu Oct 22 23:00:08 2026 +0800

    feat(connector): support oauth refs for document imports (#6447)

    * feat(feishu_doc): support connector oauth imports

    * feat(connector): support confluence oauth ref

    * fix(connector): avoid persisting display config in watch auth state

commit 4c29ed7ff0859c991f1184f0af30973f3d679840
Author: hezhang-1216 <zhanghe.1216@bytedance.com>
Date:   Thu Oct 22 19:57:49 2026 +0800

    feat(system): 建立 Account 级 system 目录与资产同步 (#6374)

    * feat(system): 建立 system 命名空间基础契约

    * feat(system): 增加 system 命名空间固定权限控制

    * feat(system): 实现 FILE_ONLY 文件操作与索引隔离

    * refactor(system): 统一内置资产的打包来源

    将示例 Skill 和记忆模板迁入 system_assets,确保源码、运行时加载路径与发布包使用同一事实来源。

    * feat(system): 同步 Account 内置系统资产

    在 Account 初始化时幂等创建 system 目录并同步缺失或变化的官方资产,严格隔离 custom 内容且不触发语义与向量链路。

    * feat(memory): 迁移 Account 自定义记忆模板存储路径

    * fix(compile): 支持直接使用系统内置示例 Skill

    * fix(system): 修复内置 Skill 同步导致的启动失败

    * fix(docs): 避免隐私占位符被 Vue 解析

    * fix(memory): 清理自定义模板备份并优化 YAML 排版

    * test(system): 更新 llm-wiki 示例 Skill 描述

    * fix(system): 启动时同步所有活跃账户的系统资源

    * docs(system): 移除 llm-wiki 示例描述中的测试字样

    * fix(compile): 统一 Runtime 的 Skill 命名空间校验

    * fix(system): 避免首次启动同步系统资源死锁

    * fix(system): 跳过已同步的默认 Account

    * fix(memory): 统一受管模板写入校验

    确保通用 write、batch-write 及文件转移入口无法绕过 Account Memory Template 的锁定字段契约,同时保留普通 custom 资产的自由写入能力。

    * fix(system): 修复系统资产迁移索引与模板回写

    ---------

    Co-authored-by: zhanghe.1216 <@bytedance.com>

commit 3266cd865e32eabcf4956f4ab388b9d40409cf65
Author: Danny Ward <71604164+dannyward630@users.noreply.github.com>
Date:   Thu Oct 22 06:01:04 2026 -0400

    fix(memory): skip unfixable event resolution retries (#6429)

commit c973ad1c4f0f69e6e26e0483f5c9e575c5a843dd
Author: akushonkamen <74654766+akushonkamen@users.noreply.github.com>
Date:   Thu Oct 22 17:31:36 2026 +0800

    fix(session): respect configured thinking in patch merge and repair budget-exhausted extraction (#6104)

    * fix(session): respect configured thinking in patch merge and repair budget-exhausted extraction

    PatchMergePolicyOptimizer forced per-call thinking=True for experiences/
    trajectories merges, overriding a deployment's configured thinking=False
    (volcengine backend per-call value takes precedence over its config). The
    single format retry reused the same thinking mode and output cap without
    showing the model its truncated program, so a reasoning-heavy merge that
    consumed the completion budget failed terminally as parse_error after a
    ~2h session commit (#6096).

    - policy_optimizer: add thinking field (bool | None, default None); None
      defers to the VLM backend's configured thinking policy, explicit
      True/False still override.
    - extract_loop: accept thinking: Optional[bool] = None and pass it
      through verbatim so the backend default applies when unset; callers
      passing True/False are unchanged.
    - extract_loop: classify a response as budget_exhausted when its
      finish_reason is 'length' or its completion tokens reach the resolved
      output cap; the single repair now appends the failed assistant
      program, renders …
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent-plugins Agent harness and plugin integrations

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Feature]: add a CodeBuddy Code memory plugin host

3 participants