dsh-at-file
FSMargoo/dsh-at-fileCodex 风格的 `@file` 文件引用,输入框里直接搜索并引用工作区文件。
在 dsh-better-sidebar 新增分支对话页签:开出独立封存 session,注入头/中/尾脉络摘要,并使用与主对话相同的工具。
Adds a Branch Chat tab to dsh-better-sidebar: open an independent archived session from the current main chat, inject a head / middle / tail context digest, and run with the same tools as the main agent. Branch history stays in the branch session and does not appear in the main chat list.
在 dsh-better-sidebar 新增「分支對話」頁籤:從目前主對話開出獨立的封存 session,注入頭/中/尾脈絡摘要,並使用與主 agent 相同的完整工具。分支內容只寫進分支 session,不會進入主對話列表。
This plugin is a companion tab. It does not vendor or fork Better Sidebar.
本插件是 companion 頁籤,不 fork、不安裝第二份、不修改 Better Sidebar。
| Dependency | Role | awesome-dsh-plugin |
|---|---|---|
omdsh-dev/DSH-better-sidebar (dsh-better-sidebar ≥ 0.11.0) | Provides ctx.betterSidebar.registerTab | listed as omdsh-dev/DSH-better-sidebar |
Install Better Sidebar first. If the service or registerTab is missing, this plugin stays loaded but hides the Branch Chat tab and logs the missing capability.
請先安裝 Better Sidebar。缺少 service/registerTab 時,本插件仍會載入,但只停用分支頁籤並寫出缺少的能力。
The planned listing for this repository is in docs/awesome-dsh-plugin.yml. After it is merged into awesome-dsh-plugin, dsh-market can pick it up from the curated registry.
本倉預定上架條目見 docs/awesome-dsh-plugin.yml。合併進 awesome-dsh-plugin 後,dsh-market 會從精選目錄收錄。
# 1. Better Sidebar (already on the curated list / 已在精選目錄)
dsh plugin --profile web add dsh-better-sidebar
# 2. This plugin from GitHub / 從 GitHub 安裝本插件
dsh plugin --profile web add github:kuanfu0430/dsh-sidebar-branch-chat
Restart dsh web, then open the Branch Chat tab from the Better Sidebar tab strip.
重啟 dsh web,在 Better Sidebar 頁籤列開啟「分支對話」。
The root package.json declares dsh.bundle.patch plus cordis.patch.yml, so dsh plugin add can install it. There is no build step.
根目錄 package.json 已宣告 dsh.bundle.patch 與 cordis.patch.yml,可直接用 dsh plugin add 安裝,無需編譯。
dsh-better-sidebar >= 0.11.0. The profile must provide the single Better Sidebar instance.compat.js. Only the public ctx.betterSidebar.registerTab API is used. New behaviour is gated on capability membership, not on a guessed minor version.agents.create / resume. Branches are not subagents: the main chat gets no subagent lifecycle events, and the branch cannot hook back into the main session.composeFrom): same tool roster and model family. A deployment with no roster stays empty; the plugin does not pretend tools exist.archiveSession). Archive failure reports failure and disposes the handle. The branch is invisible in the main session list and search; it only lives in the sidebar tab.{Tool} / answering). Answers grow from text-delta (300 ms poll while busy).MarkdownText seed (same GFM / sanitizer as the main chat). User messages stay plain pre-wrap text.allowed-once / reject). allowed-once grants are not inherited. ask_user_question is not answered in the tab.live: false until the next send or manual switch. This version does not use SSE.cwd and the full write tool set. File / shell / git side effects share the main working tree. The frame hint is a model-visible soft constraint, not a permission boundary.turn/end. Head is the first raw user text; middle lists intervening user questions; tail keeps that turn's tool call / result. In-progress turns are omitted. Caps are in digest.js (16 KB per tool result, 64 KB total).archive / create success means the archive write completed.session/disposed). If the main chat closes mid-create / resume, the new handle is disposed. The branch session itself remains; reopening the main chat can continue it.composedPreset + composeFrom). Model choice is per-branch: the side panel can pick any routable model, does not follow the main chat, and never calls saveSelection / session.selectModel.archive stops the current turn, then hides the branch from the main list.subagent-settled notices in old main chats come from the v1 subagent design. The current design emits none.Host routes under /sidebar-branch/api/* are available only on loopback / the trust fence (same rules as Better Sidebar).
create { sessionId, message, provider?, model?, reasoningEffort? } → { childId }message { sessionId, childId, text, provider?, model?, reasoningEffort? } → { ok: true }flush { sessionId, childId } → { ok: true, flushed }stop { sessionId, childId } → { ok: true, outcome }archive { sessionId, childId } → { ok: true }list { sessionId } → { branches: [{ id, label, activity }] }events { sessionId, childId, afterSeq } → { live, seedLength, events, nextSeq, total, busy, status, draft, queue, approvals }decide { sessionId, childId, approvalId, outcome } → { ok, outcome } (allowed-once / rejected)models { sessionId, childId? } → { current, routable, groups, failures }selectModel { sessionId, childId?, provider, model, reasoningEffort? } → { selected }node --check index.js client.js compat.js composer.js digest.js interaction.js project.js
node ./test.mjs