Commit Graph
284 Commits
Author SHA1 Message Date
bowenliang123 55a675ef8b style(detail): tidy the trend detail head row
Restyle the request detail header for a cleaner, more consistent look:
- even 8px gaps and center-aligned items on the single wrapping row
- time pinned right with tabular figures
- provider figures (actual prompt / output / cache) as uniform neutral
  pills with tabular numbers, replacing the plain spans and the two
  same-green accent colors
- marker chip tinted with the warn color, matching the event list chips
2026-08-24 18:12:12 +08:00
bowenliang123 0d052f243c chore: bump version to 0.30.1 2026-08-24 18:10:23 +08:00
bowenliang123 c3c6015a95 feat: step-level cache hit rate on the step detail line
Drop the heuristic estimate from the step header; show the provider-reported
cache-hit share of the billed prompt (cacheRead / prompt, truncated to two
decimals) instead. The host folds each request's cacheReadTokens into its
record (stateVersion 9); the stats board reuses the same formula via a shared
format helper.
2026-08-24 17:57:50 +08:00
bowenliang123 1e1dc14cd1 chore: bump version to 0.30.0 2026-08-24 17:19:41 +08:00
bowenliang123 d0b8f0daa0 chore(config): trim comments in build config, scripts and docs tooling
Compress the CSS-channel note in tsdown.config.ts, the vitest lane
explainer and the release workflow header; fix the install-hooks header
(git only consults .git/hooks when core.hooksPath is unset); slim the
social-preview generator and bundle-patch comments.
2026-08-24 17:16:40 +08:00
bowenliang123 89fc5674c7 chore(tests): strip comment noise in the test suite
Remove assertion restatements, act narrations and decorative section
markers; keep fixture math, harness-gotcha rationale and slot maps.
Fix stale comments: ctxSlots maps (trendMode shift), a dangling fixture
fragment, and the cardRig 'expanded via header' claim.
2026-08-24 17:16:34 +08:00
bowenliang123 0eea57067a chore(client): strip comment noise in the client half
Apply the full-repo comment audit to client logic and components: drop
narration-style JSDoc and duplicated cross-file comments, keep only
non-obvious contracts (module-table require, projection keys, hooks
rules, no-white-screen guarantees). Fix stale claims: locale fallback
chain (en, not zh), unfounded 'harness block vocabulary' mirror, kind-chip
tint mapping, stats tooltip z-index, onToolFocus parenthetical.
2026-08-24 17:16:31 +08:00
bowenliang123 aaf1aa50a3 chore(host): strip comment noise in host and shared modules
Apply the full-repo comment audit to the host half and shared wire types:
delete restatements and decorative headers, compress rationale comments to
one line, and fix stale references (agent-loop buildRequest, live-surface
image cell, five->four priced categories). Kept only contract notes,
invariants (plain-JSON precondition, shadow-seqs protocol) and verified
dsh-mirror pins.
2026-08-24 17:16:27 +08:00
bowenliang123 79db9bd5d9 test(chart): align trend-chart assertions with the current render
The turn strip renders each label inside a nested `lc-turn-label` span
(added with the scroll-centering work), so the label assertions must read
through textOf instead of expecting a bare string. The scroll/layout
handlers also call updateTurnLabels (querySelectorAll over the scroller),
which the fake scroll elements must stub — an empty querySelectorAll keeps
the label-centering a no-op without touching the asserted behaviors.
2026-08-24 15:49:09 +08:00
bowenliang123 1164371424 docs: update AGENTS.md with pre-commit checklist and best practices 2026-08-24 15:44:10 +08:00
bowenliang123 d7486585fe style(browser): wrap markdown and long tokens in detail cards
Markdown cards render soft line breaks (a single newline now breaks the
line via white-space: pre-line — two newlines still separate paragraphs)
and long unbroken tokens wrap in place: the section card gets min-width: 0
so it shrinks below its content, the body adds overflow-wrap: anywhere
with horizontal overflow hidden, and code blocks keep pre-wrap with
overflow-wrap so long code lines wrap instead of scrolling sideways.
2026-08-24 15:38:40 +08:00
bowenliang123 c23ff27ac4 feat(browser): red run-state dot on failed tool-result rows
A failed tool result now leads its collapsed row with the chat's red
run-state dot (6px core, 10px halo) right after the chevron, so the
failure scans without expanding. The failure state comes from the fold's
`err` stamp OR the conversation snapshot's `isError` — the mismatch
matters: dsh only stamps the event envelope's `error` info
conditionally, while the snapshot block always carries `isError`. The
redundant ⚠ suffix on the tool-name chip is dropped (the dot marks
failures), and per-row conversation lookups are hoisted into one `conv`
for the merged condition.
2026-08-24 15:37:58 +08:00
bowenliang123 66c964d0ee feat(browser): tool-result detail cards — run-state pill, line count and raw/markdown switch
The call half of an expanded tool result drops its argument-count badge
(the rows below already show the arguments); the head's right edge now
carries a run-state pill — green OK by default, red Failed with the
payload's terminal `exit N` code when the fold's `err` stamp or the
snapshot's `isError` marks a failure (exit recovered from the dsh
`[exit code: N]` marker). The payload card heads its line count before
the raw/markdown switch (switch stays at the far right), and its text now
renders through the same switchable prose anatomy as every other detail
section instead of the fixed dim raw view.
2026-08-24 15:36:06 +08:00
akouandClaude Opus 5 78bbb0fbdf docs: add dshfind badge to README (#15)
dsh-context is listed on dshfind (a DeepSeek Harness plugin directory)
and currently carries the "Featured" mark there. The badge links back to
the listing page.


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

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 09:52:48 +08:00
Bowen Liang cd3b9ae146 chore: bump version to 0.29.1 2026-08-24 04:01:48 +08:00
Bowen Liang 25fe067c2e fix: keep turn strip labels centered in their block's visible slice while scrolling 2026-08-24 04:01:47 +08:00
Bowen Liang ef5166675a chore: bump version to 0.29.0 2026-08-24 03:50:38 +08:00
Bowen Liang fd5b6224d7 feat: official-chrome plugin settings card, plus default trend display preference
Rework the Settings \u2192 Plugins card onto the framework's own patterns:
collapsed by default like the official PluginCard (header button discloses
the controls in place, chevron rotates), and each preference row is the
official settings-row pattern \u2014 a selector pill opening the shared Menu
dropdown from dsh-client-ui-primitives. Picking an option writes
immediately through the settings scope (display preferences, like the
official Language row).

Add a second preference, defaultTrendMode (total/diff): the Context tab's
trend chart opens cumulative or per-request diff per the stored choice;
in-chart toggling stays mount-local and never writes back. The settings
store's choose() generalizes to set(field, value), with one prefsOf()
validator shared by scope sync and the local echo.
2026-08-24 03:50:30 +08:00
Bowen Liang 0219d8045f feat: per-user settings namespace with default trend granularity preference
Register the dsh-context settings namespace on the Host (dsh-settings seam,
schemastery schema, optional composition) and claim its Plugin configuration
card in the browser (settings.plugin.item, keyed by namespace). The card
edits the default trend granularity the Context tab opens with; in-chart
toggling stays mount-local and never writes back.

Degrades cleanly: no settings provider -> no registration, no card, step
default; remote browser (memory mode) -> unavailable scope, no card.
2026-08-24 03:36:57 +08:00
Bowen Liang df2844345a docs: fix incorrect version in compatibility 2026-08-24 03:24:34 +08:00
Bowen Liang ae3e4cc0e3 chore: bump version to 0.28.0 2026-08-24 03:12:31 +08:00
Bowen Liang 5dfe5d57cb docs: describe event producer labels, mode kind, and net reclaimed deltas 2026-08-24 03:09:27 +08:00
Bowen Liang 185c7ffced feat(host): show net freed tokens on compaction and prune rows
The row carried the producer's gross shadow price, while the trend chart
visualizes the net drop. The shadow-price protocol guarantees the
replacement folds in synchronously after the metering event, so rewrite
the event's tokens to removed-minus-replacement at that moment; a
metering event left without a replacement keeps the gross price.
2026-08-24 03:08:59 +08:00
Bowen Liang d0560b6b6b feat(host,client): record plan-mode toggles and resume model switches
Plan mode includes a guidance section in every model request while
active, so its durable plan/mode event is a real context-composition
change and earns a neutral mode event row (own kind chip + filter).
A request header logged with reason 'resume' carrying a different model
is likewise a real switch made between sessions — record it alongside
the in-session 'change' ones.
2026-08-24 03:06:07 +08:00
Bowen Liang e4dab4d17e feat(host,client): show the notice summary on inject event rows
A notice-form source already carries the producer's bounded one-line
account; record it as the event's detail and render the row as
title · producer · account, matching the dsh transcript row shape.
2026-08-24 03:02:07 +08:00
Bowen Liang dc29e0bc67 fix(host): classify any non-'user' source kind as injected context
The dsh transcript treats a user/message as injected context whenever its
durable source kind is not 'user'; the fold's narrower check (plugin /
skill-invocation / has form) misclassified formless producers — goal
continuation rounds, team relays — as user messages, skewing the token
attribution and hiding their inject events. Keep the form check as a
fallback for foreign sources without a readable kind.
2026-08-24 02:58:46 +08:00
Bowen Liang e30e33fc57 feat(host): label injection events with their producer source
Mirror the dsh transcript's context provenance on inject events:
agent-instructions names its reconciled file paths, a plugin source its
plugin id, and any other producer (skill-catalog, ...) its durable kind,
so the events panel shows '目录更新 · skill-catalog' style rows like the
harness GUI does.
2026-08-24 02:54:15 +08:00
Bowen Liang e207083a56 feat(client): frame attachment cards with a hover affordance
Each image attachment card now carries its own border (border-l1, 8px
radius); hover strengthens the frame to border-l2 and washes the card with
the interactive row hover token — the same affordance as the browser's
clickable category and message rows.
2026-08-24 02:36:49 +08:00
Bowen Liang e6dcfeea1c feat(client): preview image attachments in a chat-style lightbox
The attachment card's thumbnail click used to open the full image in a new
browser tab. Now the whole card (tile + metadata column) is one click
target, and clicking it opens an in-page preview modal mirroring the chat
history's ImageLightbox recipe: body portal via the module-table react-dom,
blurred mask on the same dsw theme variables, contain-fit image, circular
close control (IconCloseOutline16 from the seeded ui-primitives), Escape/
mask close, and focus restored to the opener. The ui-attachment package
itself is not seeded into the browser module table and cross-plugin value
imports are gated off, so the recipe is ported onto the plugin's lc-*
classes with fallbacks; load failures still retry on click.
2026-08-24 02:36:41 +08:00
Bowen Liang f1fa552876 chore: bump version to 0.27.0 2026-08-24 00:18:26 +08:00
Bowen Liang 239ce675f0 feat(client): restate the Context Stats hint as current-context contents 2026-08-24 00:18:16 +08:00
Bowen Liang e8e6cde049 docs: add usage note for read tool before edit tool in AGENTS.md 2026-08-24 00:04:49 +08:00
Bowen Liang d68422a630 feat: count Context Stats images within the current context only
The image count moves off the persisted whole-session counter onto a
per-node imgs field (absent when zero), and the view sums it over the
live surface — matching the Tool Calls cell's semantics: images of a
message compacted or pruned out of the context stop counting. The
persisted-state shape changes, so stateVersion bumps to 8 and cached
rows are refolded.
2026-08-24 00:02:08 +08:00
Bowen Liang 39554df985 feat: add a Tool Calls cell to the Context Stats board
The cell sits left of Images and counts the tool calls whose result is
live in the current context: one tool/result folds to exactly one tool
surface node, so the host derives the figure at view time from the live
surface (no persisted counter, no state-version bump). Calls still in
flight and results compacted or pruned out of the surface are excluded.
2026-08-24 00:01:47 +08:00
Bowen Liang 69c175e76a feat(client): narrow the Context Stats board cells
Shrink the stat-cell grid minimum (76px -> 62px), gap (8px -> 6px) and
padding (8px -> 6px) so the board's nine cells pack tighter.
2026-08-24 00:01:43 +08:00
Bowen Liang c4153d525c chore: bump version to 0.26.1 2026-08-23 23:37:28 +08:00
Bowen Liang 6b9566226d docs: update AGENTS.md to clarify local git clone instructions 2026-08-23 23:36:35 +08:00
Bowen Liang 05ec9bba40 docs: update AGENTS.md to include English usage in PR descriptions and commit messages 2026-08-23 23:34:57 +08:00
Bowen Liang e53c375a15 feat(client): hide the composer while the Context tab is active (#14)
* feat: add PR checks workflow for automated testing and validation

* feat(client): hide the composer while the Context tab is active

The view ring mounts one view at a time, so the tab's .lc-root existing
inside the shell scrollport is exactly 'Context tab active' — a single
:has() rule hides the sticky composer seat and hands its height to the
dashboard. display:none keeps the seat mounted, so drafts survive the
round trip.

Interactive takeovers (approval / question / plan-review panels) replace
the bar inside the same seat; keep the seat visible while one is present
so a pending decision is never hidden behind the focus mode.

Closes #11

* ci: build before test in PR checks

Client tests mount the built bundle (viewBed.ts reads lib/client.js), so
pnpm test without a prior build fails with ENOENT in a clean checkout.
2026-08-23 23:33:15 +08:00
Bowen Liang 9af89c6668 chore: bump version to 0.26.0 2026-08-23 23:04:12 +08:00
Bowen Liang a26f5437c3 fix(client): hoist hooks above early returns — React #310 on data/event arrival
ContextViewBody returned the loading frame BEFORE its displayRequests/
markers useMemos: when the projection value landed on the same mounted
instance (a pure timing race), the hook count grew between renders and
React threw #310, which the ErrorBoundary masked as a '数据读取失败'
card. EventList returned its empty branch before useRef/useLayoutEffect:
an empty -> non-empty transition in one instance at best corrupts the
hook list (React logs 'Expected static flag was missing') and at worst
throws the same #310 on builds that don't recover.

Both early returns now sit below every hook; data-less renders fall back
to empty collections so the memos stay unconditional.

Regression tests mount the built client bundle on real React in jsdom and
drive both transitions (loading -> loaded, events empty -> non-empty),
failing on a boundary catch or any hook-order console error.

Closes #12
2026-08-23 23:03:47 +08:00
sxgitmiao be751da48d feat(client): add Total/Diff display mode to the Context History chart
Adds a display-mode pair (全量/增量, Total/Diff) next to the Step/Turn granularity group in the Context History card. Diff mode plots each request's per-category |change| vs the previous request, with the hover tip reporting the signed net change (Δ +1.2k / Δ −535.5k); Total keeps the cumulative composition and stays the default.

Original PR by @xieshuaix (delta toggle); reworked before merge: the on/off delta switch became a two-way mode control (mode: 'total' | 'diff' end to end), the two toggle groups were wrapped so the title's auto-margin push happens once, trend.hint was shortened/localized, and the fiber-slot/button-count tests were updated.
2026-08-23 22:49:09 +08:00
Bowen Liang 095e2f525e fix(host): tag skill results even when the tool/call event is gone
- drop the redundant node.cat === 'tool' guard (categoryOf always
  returns 'tool' in the tool/result case)
- fall back to the rendered <skill_content> wrapper when node.tool is
  unresolvable (trimmed window, replay), so a skill load never silently
  degrades to an ordinary untagged tool row; the wrapper only appears in
  genuine skill results
- regression test for the fallback path, and that a plain tool result
  without the wrapper stays untagged
2026-08-23 22:25:30 +08:00
Bowen Liang 02807de68c Update src/client/i18n.ts 2026-08-23 21:34:56 +08:00
tangjunyan.5703 a2641b7d29 feat(host): surface skill-tool loads as tagged tool results + Skill inject event
A skill load via the `skill` tool returns the loaded skill's instructions
as a tool result. Keep it a tool result (that is what it is), but make it
findable: tag the node with the skill name (so the Context browser labels the
row `Skill · <name>`) and record an inject event so a `Skill 注入(name)`
entry shows in the Context Events card.

- fold: detect tool/result with node.tool === 'skill', parse the skill name
  from the rendered <skill_content name="…"> wrapper, set node.skill, emit a
  sub:'skill' inject event. Category stays 'tool'.
- browser: tool row shows the Skill · <name> tag when node.skill is set.
- i18n: add node.skillTag (zh/en).
- test: regression for the skill-tool result path.
2026-08-23 18:45:35 +08:00
bowenliang123 c2fb81eaaa chore: bump version to 0.25.3 2026-08-23 05:14:04 +08:00
bowenliang123 c27904b5f5 feat(client): chip the collapsed User Messages rows that carry image uploads
The row joins the conversation snapshot and counts image blocks via the
same imageRefOf the expanded body uses; the chip (localized 'attach.image',
×N when several) shows only while collapsed — expanded, the image grid
speaks for itself.
2026-08-23 05:13:56 +08:00
bowenliang123 70496e77c9 chore: bump version to 0.25.2 2026-08-23 05:11:36 +08:00
bowenliang123 93cf924445 fix(host): drop unnecessary ?? 0 guards on TimelineState.images (stateVersion 7 refold guarantees it) 2026-08-23 05:11:27 +08:00
bowenliang123 57ff90dfc3 chore: unify the repo on TypeScript — tests, vitest config, and the social-preview generator move from .mjs to .ts
vitest (esbuild) and Node 24 type stripping run the .ts files directly;
helper imports go extensionless like src. Typecheck stays scoped to src/
as before.
2026-08-23 05:11:27 +08:00