Commit Graph
624 Commits
Author SHA1 Message Date
bowenliang123 73318a5cd6 style(client): reword the token-estimate footer note
Spell out DeepSeek Harness instead of the dsh shorthand and name the
note's subject (Token 数量统计 / Token amount) in both locales.
2026-09-14 10:27:43 +08:00
Bowen Liang 445c80d0c8 chore: release v0.52.0 2026-09-14 02:08:19 +08:00
Bowen Liang ee63b59e75 fix(client): group the /context slash row under a localized section heading
The slash menu renders one source-title row per trigger source, titled
from the harness's own slash.menu dictionary; the plugin's source name
`context` is not a key there, so the row showed the bare raw name and
read as a duplicate command (closes #67). Candidates now carry a
localized `section`, which the menu renders in place of the
source-title row — 上下文 in Chinese, Context in English.
2026-09-14 02:04:47 +08:00
Bowen Liang 022768ef54 fix(client): light the skill bucket in the trend chart's category hover-link
The hover-link's re-light rules are a hand-enumerated CSS list keyed by
category, and the skill bucket joined the vocabulary without one — hovering
the browser's skill section (or the overview's) dimmed every bar with
nothing lit. Add the missing rule and pin the list-must-track-Category
constraint next to it.
2026-09-14 01:32:04 +08:00
Bowen Liang afd9af63f0 feat: surface skill occupancy through a dedicated skill-injection category
The fold buckets all three skill-content shapes the harness injects — the
<available_skills> catalog digest, a user-explicit /name invocation's
instructions message, and the content a skill-tool load returns — into a
new 'skill' composition category instead of burying them in inject/tool
(closes #66). Skill-tool loads keep their tool identity stamped, so the
call tallies, hit counts, and failure marking are unchanged.

stateVersion 18 → 19: the per-category sums change shape, so cached rows
refold from the durable log on upgrade (docs/compatibility.md).

The trend chart, overview, Token donut, stats, and the Context browser all
gain the seventh bucket (orange-500); the browser's skill section pins its
rows like injects, so long sessions keep listing what the sums count.
2026-09-14 01:11:37 +08:00
Bowen Liang 4de2f2cf9e feat(client): show the turn's step total in step-granularity labels
detail.step/tip.step now read "第 s 步 (共 n 步)" / "Turn t · Step s of n" —
the same per-turn tally a turn-mode bar's stepCount carries, so step and
turn granularities agree on how busy a turn was. A shared turnStepsOf()
getter feeds the trend tooltip, the detail head, the files scope label,
and the browser picker/meta rows.
2026-09-14 00:00:34 +08:00
Bowen Liang 3d594ba316 feat(client): deepen the stats cache-hit cell to two decimals with a formula tip
The Context stats grid's cache-hit cell now carries the chat stats line's
figure two decimals deep and explains itself through the shared stat-tip
bubble (the whole-session cache-read share of billed input), localized in
both locales.
2026-09-13 23:59:56 +08:00
Bowen Liang 4f19c5ecde chore: release v0.51.1 2026-09-13 22:01:26 +08:00
Bowen Liang 765297659d fix(client): repair the crushed file-activity card and the narrow-pane floors
The Tailwind responsive fold (ff10cff) retired the `.lc-col` flex rule and
moved every flex-row child onto per-element `flex-1 min-w-[min(360px,100%)]`
utilities — but the file-activity card's own root was missed. As an lc-card
size container its intrinsic inline-size is zero, so under `flex: 0 1 auto`
the whole card collapsed to its chrome (~18px) in EVERY host at EVERY width,
crushing its content into one-character columns (issue #65). The root now
rides the shared column idiom like its sibling cards.

Two more narrow-pane defects fell out of the same audit:

- A content-box card read the `min-w-[min(360px,100%)]` floor as its content
  width, so on sub-360px panes every floored card overflowed its row by its
  own padding+border (18px), clipping past the pane edge. The plugin ships no
  preflight, so `.lc-root .lc-card` now sets border-box itself.

- The events card's kind chips had no wrap fold of their own, so the English
  chip row spilled past the card edge under 380px; it now rides the same
  `@max-[380px]/lc-card:flex-wrap` variant as the file card's chips.

Verified in the browser across the right-Sidebar pane at its drag minimum
(~300px), 510px, 822px (the two-across threshold) and 856px, the full-width
tab at 390px and 1440px, and the /context modal, in both locales: the file
card shares its row again, no vertical crush, no right-edge clipping, no
horizontal overflow.

Fixes #65
2026-09-13 22:00:56 +08:00
Bowen Liang de2d971b8a chore: release v0.51.0 2026-09-13 17:17:33 +08:00
Bowen Liang b6020146df feat: make the tool-definition default sort a plugin setting
New 'Tool Schemas - Default sort' row in Settings -> Plugins -> dsh-context
(ahead of the File Activity one): size, call count, or name, persisted per
user through the dsh-context settings namespace. The Context browser reads
it as the mount-time default for its tools toolbar; in-toolbar toggling
stays session-local and never writes back. The default default is now call
count. Degradation mirrors the existing preferences: the host schema is
loose (a stale persisted value falls back to the default), the client drops
values outside the vocabulary, and a host without the settings surface (or
a section missing the field) keeps the schema default, so the tools list
stays fully functional either way.
2026-09-13 16:47:20 +08:00
Bowen Liang 4dded7add5 feat(client): rank tool definitions by call hits with a count sort
The Context browser's tool-definition rows now carry a per-tool call-hit
tally (xN) over the shown step's assembled surface — one paired tool-result
node is one completed call, the same accounting as the stats' toolCalls, so
the tally follows the step picker (a past step re-tallies over its own
surface). The tools toolbar gains a count sort ranked by that tally; ties
break by tool name. A zero tally names a definition the shown step never
called.
2026-09-13 16:46:39 +08:00
Bowen Liang 96435c85c3 refactor(client): move the animations into the Tailwind theme and utilities
The five animations become --animate-* theme tokens with their keyframes
(emitted only when used): the donut sweep, stacked-bar and trend-bar
entrances, the agent link's flow dash and the running node's glow. The
entrance delays ride the element-scoped --lc-i stagger slot inside the
token shorthand and resolve per element, the running glow becomes a
conditional animate-lc-agent-glow class on the halo, and the sheets'
prefers-reduced-motion blocks become motion-reduce:animate-none on the
animated elements. The sheets keep what utilities cannot own: the
transform origins, the flow dash's linecap/dasharray, the halo's state
fills, and the seg arc's dasharray transition.

Element transitions deliberately stay in the sheets: all of them follow
the harness motion tokens (--ds-transition-duration/--ds-ease-in-out with
host fallbacks) over exact per-element property lists, where preset
durations/easings would freeze host-following values and Tailwind's
property bundles (transition-colors etc.) would transition more than the
design intends. transition-behavior and transition-delay have no use in
the plugin.

Verified in the browser via computed styles: the donut sweep resolves to
lc-donut-in 0.45s cubic-bezier(0.4,0,0.2,1) with a per-element delay and
backwards fill, and emulated prefers-reduced-motion yields animation:
none.
2026-09-13 11:40:24 +08:00
Bowen Liang 58299eeacb refactor(client): move static SVG fill/stroke chrome to Tailwind utilities
The donut rings' fill-none/stroke-4, the agent ring's track fill/stroke
and 9px arcs, the resting transparent halo fill, the link lines' width
and opacity, the node caption's fill token, and the jump glyph's
fill-current become fill-*/stroke-* utilities on the elements, and their
sheet rules shrink to what the utilities cannot own: the state-class
fills and the free remainder's color-mix (state-driven, kept per the
established boundary), the flow dash's linecap/dasharray/animation, and
the live link's opacity override — which still wins its tie with the
base utility because sheets inject after the utilities channel.

Data-driven strokes keep flowing as before: donut slices and
family-colored links carry var() values through inline styles and the
stroke attribute (var() cannot live in a presentation attribute), and
the icon logo keeps its fixed brand fills.

Verified: full chain green, all emitted utilities present in the client
bundle, and the rendered donuts, agent ring, links and jump glyph
unchanged in the browser.
2026-09-13 10:55:54 +08:00
Bowen Liang 7b09d5b044 fix(client): point the plugin-name row at the repo instead of the releases page 2026-09-13 10:52:48 +08:00
Bowen Liang ff10cff71c refactor(client): fold the responsive layout into Tailwind variants and intrinsic flex
All seven hand-written @container blocks move out of the sheets: the
head-band stack, the stats grid's wide/narrow columns, the donut row's
gap fold and stack, and the events/file rows' narrow-card wraps now ride
@min/@max-[…]/lc-card utilities on the elements (named lc-card /
lc-head-row containers). Reviewing that migration against the shared
column idiom folded the head band's 720px container query away entirely —
the rows were already flex-wrap rows, so the head cards take the same
`flex-1 min-w-[min(360px,100%)]` floor as every other column and wrap
intrinsically. The count grid became repeat(auto-fit, minmax(108px,1fr))
— 108px is the floor where the longest English label fits — replacing
the 700px/320px breakpoints and filling the card at every width instead
of jumping 3 to 6 columns.

What stays hand-written: the 240px donut stack and 380px row wraps (the
ring/legend and the 92px/46px reservations are measured-content facts,
and Tailwind's preset container scale is rem-based where this plugin is
px-anchored), plus the lc-card container definition whose .lc-root scope
deliberately keeps the /context modal's cards container-less.

Verified in the browser across 1280/900/736/640/390 in both locales and
in the /context modal: same folds at the same widths, no overflow, no
horizontal scrollbars. The visible delta is the count grid filling
intermediate widths with 4/5 columns.
2026-09-13 10:09:27 +08:00
Bowen Liang 17183882be refactor(client): move pure pseudo-state styling to Tailwind state variants
The 20 hover/focus rules that are leaf styles (no state class re-asserts
them) become hover:/focus:/group-hover: variants on the elements' own
class lists, and their sheet rules are deleted: row and button hover
tints, retry/close/gate brightness, input focus borders, underline
hints, the three styled-tip reveals (named group/tip), the plugin-info
row underlines (group/pi), and the agent halo's hover/focus wash
(group/agent — the React hover state keeps driving the inspector;
lc-agent-hover stays as a test anchor).

The hover/lit(-on) cascade pyramids stay hand-written in the sheets —
the gran/rich-seg/rich-copy/fa-chip toggles and the settings card's
open state need ordered overrides over their own hover rules, several
of those state classes double as test anchors and DOM query hooks, and
moving them would mean a chip factory for zero visual change.
Transitions, animations and all harness --dsw-* tokens stay in sheets.

Behavior notes: variant utilities carry (0,2,0) specificity, so they
keep beating the sheet base rules exactly as the old :hover rules did;
Tailwind media-guards hover behind (hover: hover), so touch devices no
longer get sticky hover styling (dsh web is desktop-first).
2026-09-13 09:41:30 +08:00
Bowen Liang 75fada4fb3 refactor(client): adopt Tailwind color tokens for the plugin's palette
Replace the hand-picked hex literals with the nearest standard Tailwind
tokens now emitted by the CSS channel: the category/timing/ring accents
(indigo, amber, green, purple, blue, teal, pink, violet, red, slate-400)
and the neutral chart tracks and zebra fills, recast as color-mix over
--color-neutral-500 at the original alphas.

Donut and agent-graph ring segments now carry their stroke as an inline
style instead of the presentation attribute: the colors are CSS variables
and var() is unusable in an attribute. Free segments keep their class
rule by omitting the inline stroke. Visual output is unchanged (the v4
values are the nearest equivalents of the former v3 hexes); harness
--dsw-* semantic tokens, the logo fills and the language identity colors
stay as-is.
2026-09-13 09:18:40 +08:00
Bowen Liang f1ab3a18c6 feat(build): emit the plugin accent palette as Tailwind color tokens
Declare the 11 Tailwind palette tokens the plugin's sheets and TS data
layer consume in the Tailwind entry's @theme static block, values lifted
verbatim from the pinned tailwindcss theme.css. static is load-bearing:
the consumers reference them via plain var()/inline styles, never a
compiled utility, so used-only emission would never see them.
2026-09-13 09:18:08 +08:00
Bowen Liang 55aa1fecc3 feat(build): compile Tailwind layout utilities into the client CSS channel
The global-CSS channel now runs @tailwindcss/node's compiler over a new
entry sheet (src/client/styles/tailwind.css) and feeds the resolved
@source globs through the oxide scanner; scanned sources join the watch
graph so class-list edits rebuild the sheet. The entry carries no
preflight and no theme import — just the spacing scale anchored to 4px —
and emits utilities unlayered, so the injected <style> cascade matches
the hand-written sheets it precedes. lightningcss and the Tailwind
packages are pinned to one exact version each: the config process loads
the oxide and lightningcss native bindings together, and duplicate
copies break the napi calls.
2026-09-13 01:55:31 +08:00
Bowen Liang 2379dd92db docs: describe the models.dev-priced cost estimate and the stateVersion 18 upgrade
The Context Stats card row now names the models.dev source (DeepSeek
peak/off-peak aware), and the compatibility page's upgrade section
drops the stale 'stateVersion stays unchanged' claim: the cost rework
bumps it 16 -> 18, so cached rows refold and idle sessions re-fold on
their next live event.
2026-09-13 00:35:26 +08:00
Bowen Liang 7cf9284362 feat(stats): estimate session cost from models.dev prices
Replace the hardcoded DeepSeek rate table with a client-fetched price
book: @opencode-ai/models reads the models.dev registry once per page
load, every entry is re-proved at the boundary, and a failed fetch
degrades to a dash + note with backed-off automatic retries.

- cost totals rekey per (provider, model); only DeepSeek splits a
  pricing period (peak windows at list price, all other hours half
  price) — every other provider bills everything at list price
- provider ids resolve through a shared rename table (deepseek-official,
  kimi-coding, minimax-cn, zai-coding-cn) with verbatim passthrough for
  unmapped ids; model ids match exactly, case-insensitively, or by
  suffix (k3 -> kimi-k3), ambiguous matches price nothing
- CNY display converts at the fixed 1 CNY = 0.15 USD; the tooltip lists
  per-1M rates for the models the session billed, with peak|off-peak
  pairs and the DeepSeek note shown on DeepSeek sessions only
- stateVersion 18: cached rows refold from the log, which rebuilds the
  new cost keys and periods
2026-09-13 00:35:03 +08:00
Bowen Liang 0b14f793b8 docs(readme): describe the Token card as composition around the billed total 2026-09-12 09:06:58 +08:00
Bowen Liang addfca6c65 chore: release v0.50.0 2026-09-12 08:58:04 +08:00
Bowen Liang 4c276c87da chore(deps): update oxlint to 1.82.0
oxlint-tsgolint stays an explicit exact devDependency: oxlint declares
it only as an optional peer dependency, so no package manager installs
it for us and type-aware linting fails loudly without it.
2026-09-12 01:50:11 +08:00
Bowen Liang befa7a986c chore(deps): update tsdown to 0.23.0
No config changes needed: the config only uses deps.neverBundle /
deps.alwaysBundle and dts, all carried over. The rolldown-plugin-dts
0.28.5 bump emits direct export declarations instead of declare +
re-export in lib/index.d.ts; the exported surface is unchanged and the
built JS is byte-identical.
2026-09-12 01:45:29 +08:00
Bowen Liang 8bfcf65d31 feat(client): count whole-session human inputs on the stats board 2026-09-12 01:24:46 +08:00
Bowen Liang fb50c1ab8e docs(readme): update context-overview.png 2026-09-12 00:44:57 +08:00
Bowen Liang 8d2ddeff55 feat(client): move the context-event tallies onto the events card's kind filters
The Context Stats card's inject/compaction/prune cells duplicated what the
events card already tracks. Drop the three cells (the grid falls to five:
turns, steps, tool calls, cache hit, cost) and show each tally inside the
matching kind-filter button instead, sourced from the same precomputed
counts the stats card used.
2026-09-12 00:35:30 +08:00
Bowen Liang b68a6d50ad fix(client): cite the official model IDs in the cost tooltip
The rates themselves check out against the official pricing pages (both
currencies, both families, and the Beijing peak windows), but the flash
row's label named deepseek-v4.1-flash — the model VERSION, not an API ID.
The page's current flash ID is deepseek-flash, with deepseek-v4-flash as
the accepted legacy ID, so the label and the tip's applies-to list now
cite those; the tip also drops the colloquial hardcoded phrasing for a
plain for-reference-only note.
2026-09-12 00:28:36 +08:00
Bowen Liang 02ae427c8e style(client): rename the zh answer-decode label to 模型输出 2026-09-12 00:13:02 +08:00
Bowen Liang 3ed80aa9e0 feat(client): the Context card swaps its image count for the chat line's cache hit
The images cell said little about the session; the eighth cell now shows
the whole-session prompt-side cache-hit rate off the official tokenUsage
projection — the same source and formula as the chat stats line under the
composer, truncated to one decimal (cacheHitPercent gains a precision
parameter; the two-decimal default keeps the request detail's figure).
2026-09-12 00:05:45 +08:00
Bowen Liang 36aadbb618 refactor(client): pair the head band into two rows
The head band's four cards quartered one row; now the session-shape card
sits beside the plugin card, and the two donut cards share the row below
(token / timing). Each row halves its width and folds to stacked when a
half would drop under ~350px.

The wider cards unlock roomier insides: the context card's eight cells
can lay out in ONE line on roomy panes (no longer pinned to 2x4), and
the donut legends flow into as many 160px-min columns as the card offers
(the composition legend's auto-fill idiom) — one in a narrow pane, two
on a classic 1280px viewport, more when the rows stack full-width.
2026-09-11 23:54:09 +08:00
Bowen Liang 423e9423eb refactor(client): split the Token card by composition around the chat-line total
The donut center now carries the whole-session billed total — the same
figure the harness chat stats line shows under the composer (uncached
input + cache read + cache write + output off the official tokenUsage
projection) — instead of the cache-hit share.

The slices answer WHAT the tokens are rather than how the provider
cached them: the six composition categories share the provider-reported
prompt-side total by the composition card's own estimated ratios (their
counts carry the ≈ marker), and the provider-exact output closes the
ring, so the parts equal the chat line's figure by construction.

The cache-read/cache-write/uncached bucket view and its four locale
keys are gone; tokens.total is new.
2026-09-11 23:26:36 +08:00
Bowen Liang 5f7dbd6d0d docs: add instruction to run 'git push' after creating commits 2026-09-11 22:19:32 +08:00
Bowen Liang 296324cc70 fix(client): remount trend bars on granularity switch so the entrance rise replays
A turn aggregate IS its last step's record (the same seq), so with a
plain seq key a step ↔ turn switch reused those bars' DOM nodes — the
entrance animation had already finished on them and CSS never replays an
animation on a reused node, leaving every turn's last step bar popping
in unanimated. Keying ChartBar by seq + granularity forces a remount;
mode (Total/Delta) switches already remount through the stack ↔ arms
structural change.
2026-09-11 22:14:54 +08:00
Bowen Liang d5dc784292 feat(client): ease-in entrance animations for the context charts
The donut slices sweep in clockwise from 12 o'clock, the composition
stacked bar grows open segment by segment, and the trend chart bars rise
from their baseline — all staggered in layout order, transform-only (no
layout thrash), running once per mount and disabled under
prefers-reduced-motion (the harness's own idiom).

- the stagger caps (trend bars 20, stacked pieces 8) so long logs and
  long DNA band lists still settle in well under a second
- the auto-compaction reserve band stays unanimated: as an overlay its
  growth would smear the stripes, and it reads as chrome, not data
- covers the tab, the /context modal and the right Sidebar, which all
  render the same chart components
2026-09-11 22:13:56 +08:00
Bowen Liang 3518ace01f style(client): drop the stale V4.1 Pro routing note from the cost tip
V4 Pro now carries its own list prices, so the "until V4.1 Pro ships, Pro
requests are routed to and billed at V4.1 Flash rates" note in the cost
tooltip is no longer true; lead the covered model list with the current
deepseek-flash spelling.
2026-09-11 21:54:27 +08:00
Bowen Liang 08def011a0 fix(client): price deepseek-v4-pro at its own V4 Pro list rates
DeepSeek has ended the routing window: deepseek-v4-pro (DeepSeek-V4-Pro-0813)
now bills at its own published table instead of riding the V4.1 Flash triple —
USD peak hit $0.044 / miss $1.32 / out $3.96, CNY peak ¥0.3 / ¥9 / ¥27,
off-peak half price. Flash rates are unchanged.
2026-09-11 21:54:21 +08:00
bowenliang123 97ae8ff2ee feat(client): preview File Activity files in the right Sidebar
Clicking a file name in the File Activity card now opens the file's preview
tab in the right Sidebar — the shipped document-preview viewer, reached the
same way the built-in Files sidebar reaches it — on harnesses that serve that
column (dsh 0.1.5-rc.1+). The address is built with the harness's own
browser-safe `fileAddressFor`, inlined by the client bundle exactly as the
Sidebar's file types inline it, so a path under the workspace collapses to the
session-relative spelling and every route to one file settles on one tab.

The capability is OPTIONAL by contract, like the tab registration itself: the
opener reads `ctx.sidebarRight.openResource` through the runtime boundary and
re-proves it per call, and reports whether the column took the address. An
absent column, a face that refuses the address, or an unencodable log path
falls through to the pre-existing system-open behavior, so an older line is
fully functional and nothing becomes an inert click. Pattern rows and
directory targets are never previewable.

Adds the `@deepseek-ai/dsh-util-workspace-path` dev dependency (itself
browser-safe), allows it in the client bundle purity gate, pins the
resource-navigation seam in the compat matrix, and covers the address builder,
the card's preview-then-fallback click, and the optional opener per baseline.
2026-09-11 18:45:28 +08:00
bowenliang123 fffc511949 chore: release v0.49.4 2026-09-11 16:20:38 +08:00
bowenliang123 3f22d9745e docs: make compatibility.md the single source for the compatibility rules
AGENTS.md carried the full compatibility matrix — per-generation event
vocabulary, the moving V3 client seams, and the runtime gate's internals —
duplicating what docs/compatibility.md exists to document. Restate only the
requirements there and point at that page, keeping the agent-facing anchors
that have no user-facing home: the single shape-driven fold path
(`logShapes.ts`'s `firstTokenTimeOfStream` / `replaceRangeOf` / `isTokenChunk`,
`applyTimeline`), the upstream implementation mirrors (`dsh-token-meter`'s
`estimateSystemMessage`, `dsh-llm`'s `assistantStreamFirstTokenTime`), the
gated-inject rule for newer-only seams, and the baseline verification
mechanism.

docs/compatibility.md gains the previously undocumented baseline gate
(including the running-tree-first probe and fail-open behavior) and names the
V2 stream paths in full.
2026-09-11 16:20:10 +08:00
bowenliang123 65e5f0efd4 fix(host): probe the running module tree before the profiles mirror
The baseline gate resolved the harness version from the healed
`$DSH_HOME/profiles/node_modules` mirror first, but that mirror is only as
fresh as the last CLI profile boot: it is rewritten by whichever installation
last healed it, and a packaged desktop host never heals it at all. A leftover
global CLI could therefore pin the mirror below the baseline and gate a
healthy desktop harness — an upgrade modal plus fallback (unfolded) projection
units on every launch (issue #59).

Resolve through the module tree the plugin is actually bound to instead: its
own ESM resolution (`import.meta.resolve`, the same pipeline its runtime
imports use, so an embedding shell that redirects plugin imports — the
packaged desktop's ASAR resolver bridge — redirects the probe too) of the
library packages it imports. A witness that lands inside this package's own
tree is the plugin's dependency closure (a `link:`-installed dev checkout's
pinned devDependencies), never the harness, so it is discarded. The home
mirror stays as the fallback for a dev checkout and for a running anchor that
cannot answer; the CLI package is still probed only through it.

Fail-open is unchanged: any unresolvable package, non-file URL, or unreadable
manifest degrades to `undefined`, which never trips the gate.
2026-09-11 16:18:47 +08:00
bowenliang123 2d13585f6f chore: release v0.49.3 2026-09-11 14:09:39 +08:00
bowenliang123 be3f598959 style(client): lead the placement menu with 全部 and shorten the tab option to 标签页 / Tab 2026-09-11 14:06:55 +08:00
bowenliang123 5322d1e6d4 fix(client): fail the placement open to 全部 on unreadable or unpersisted config
A config problem must never leave a Context entry hidden:

- a scope value the plugin cannot understand (present but invalid)
  degrades the placement to `all` instead of stranding the previously
  chosen one — the read path now distinguishes invalid from missing,
  and only a genuinely absent field (older Host half) keeps the
  current state;
- a placement write that fails to persist no longer keeps the
  optimistic echo in-session: unless the scope's truth itself carries
  a valid placement, the rollback degrades to `all` (other fields
  keep the existing keep-the-echo behavior).
2026-09-11 14:02:35 +08:00
bowenliang123 f688211fe5 style(client): the placement's both option reads 全部 / All 2026-09-11 14:02:19 +08:00
bowenliang123 abb903e4e7 style(client): rename the placement row label to 入口位置 / Entry Options 2026-09-11 13:56:37 +08:00
bowenliang123 a4add07664 feat: add a placement preference (tab / sidebar / both) for the Context view
Closes #58: the Context panel hung off two registrations at once (the
conversation tab and the right-Sidebar guide entry), with no way to keep
just one. A new per-user `defaultPlacement` preference — the first row of
the Plugin configuration card — picks who carries the view: the
conversation tab, the right Sidebar, or both (the default, so existing
deployments see no change).

- shared: `DefaultPlacement` vocabulary (`all` | `tab` | `sidebar`) on the
  settings namespace; the Host schema gains a loose `defaultPlacement`
  field so a stale persisted value degrades to `all`
- client: `placement.ts` mounts each registration through its own factory
  and, on a preference flip, disposes exactly what the new value drops
  (the harness's own dynamic-mount idiom); `watchSidebarContextTab`
  returns its deferred-inject disposer so the sidebar mount can be taken
  down and put back; the settings card leads with the placement row
2026-09-11 13:44:21 +08:00
bowenliang123 b687a4fc6f chore(release): update pnpm action to use the latest version 2026-09-11 11:33:24 +08:00