Commit Graph
264 Commits
Author SHA1 Message Date
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
bowenliang123 4b8d00ee03 chore: bump version to 0.25.1 2026-08-23 05:05:31 +08:00
bowenliang123 eb9ff049f8 fix: exclude sourcemaps from the npm tarball (enumerate shipped files like official dsh packages) 2026-08-23 05:04:52 +08:00
bowenliang123 c4e242b5b1 chore: bump version to 0.25.0 2026-08-23 04:57:47 +08:00
bowenliang123 271f4e3395 refactor(client): unify Context browser detail rendering into one section-card system
Every expanded element body is now a uniform stack of Section cards
(labeled head + body): prose carries the Raw/MD switch in the head, tool
calls/params/images/raw JSON share the same frame, and one blocks→sections
pipeline serves user/assistant/tool-result/injection bodies. Replaces the
floating-switch, bare-pre, and per-kind card idioms; drops the dead
lc-br-blk/lc-br-pre/lc-br-md/lc-br-rich-inline styles and the unused
RichCard/inHead/dim parameters. Element-row tool tags lose their inverted
chip and share the subtle injection-form tag style. Test bed: function
components now receive props.children like real React.
2026-08-23 04:56:17 +08:00
bowenliang123 af8f695854 feat(client): Context tab browser stretches to the left column's height
The /context modal keeps the browser content-sized.
2026-08-23 04:32:56 +08:00
bowenliang123 93dfe3941d feat(client): shorter stats labels (Cache Hit / Cost) 2026-08-23 04:32:55 +08:00
bowenliang123 f15b9ecddc style(client): narrower stats cells (76px min, 8px side padding) 2026-08-23 04:18:32 +08:00
bowenliang123 78245e1b75 feat: whole-session image count in Context Stats
Fold counts image blocks (user uploads + nested tool-result images)
cumulatively over the complete session log, rides the wire snapshot as
an optional additive field, and the stats board shows it as a new cell
between prunes and cache hit. stateVersion 7 refolds cached rows.
2026-08-23 04:18:26 +08:00
bowenliang123 3c48acbed0 fix(host): weekends bill at off-peak rates all day
Follow DeepSeek's peak/off-peak rule adjustment: Saturdays and Sundays
(Beijing Time) no longer distinguish peak windows, so the whole weekend
prices at the half-price off-peak rate. Peak windows are now expressed in
Beijing Time (weekdays 09:00-12:00, 14:00-18:00), equivalent to the old
UTC windows on weekdays. List prices themselves are unchanged.
2026-08-23 03:55:18 +08:00
bowenliang123 61d3e16477 docs: update context-browser-images.png 2026-08-22 19:57:21 +08:00
bowenliang123 c40a919e60 chore: bump version to 0.24.1 2026-08-22 18:08:42 +08:00
bowenliang123 c208f55d07 feat(client): labeled Raw/Sent/Token rows on image cards, shown only when known
Each fact gets its own labeled row: Raw (pre-normalization dims), Sent
(normalized dims + stored size, dynamic B/kB/MB units), Token (estimate).
Facts that dsh never recorded (e.g. no originalDimensions, no byte size)
simply leave no row behind.
2026-08-22 18:08:41 +08:00
bowenliang123 eb5c8ebf2d fix(client): wrap long image attachment filenames instead of truncating 2026-08-22 18:08:35 +08:00
bowenliang123 9859f4702a chore: bump version to 0.24.0 2026-08-22 16:31:55 +08:00
bowenliang123 9dccec4e85 docs: composition card reads the official meter projections; image cards show token costs 2026-08-22 16:31:13 +08:00
bowenliang123 c003916360 feat(client): two equal-width image attachment columns with token badges
The attachment grid becomes a two-column equal-width grid
(repeat(2, minmax(0, 1fr))) and every image card gains a token-cost
line (≈N tokens, with an explanatory tooltip) estimated through the
official DeepSeek image-size conversion on the stored dimensions.
2026-08-22 16:31:13 +08:00
bowenliang123 d3cdc263d6 feat(client): read the official contextBreakdown projection for the composition card
The composition legend and tooltips now show the exact system/tools/
messages counts of the chat composer ring's click-open panel (the
token-meter's contextBreakdown projection) instead of the fold's own
sums re-anchored to the provider total: parts carry the heuristic count
(raw) for display beside the provider-anchored bar width (value), and
the message bucket subdivides into the four surface categories by the
fold's per-category ratios, always summing exactly to the official
message figure. Absent the projection (older harness), the fold's own
sums serve unchanged.
2026-08-22 16:31:05 +08:00
bowenliang123 d9c09782fc feat(host): price image blocks by DeepSeek's official image token calculator
The token-meter heuristic prices image blocks through its generic JSON
branch (~40 tokens for the durable ref), while DeepSeek's vision model
actually bills 117-384 tokens per image by pixel dimensions. Port the
official docs image-token calculator (patch grid 14px, downsample x3,
384-token cap, minPixels 384^2) into src/shared/imageTokens.ts and price
image blocks with it in the fold; unknown dimensions keep the JSON
fallback. stateVersion bumps to 6 so cached rows refold.

The differential fold check replays a parallel image-delta surface so
image-bearing logs still match the official contextBreakdown exactly,
and adapts to the 0.1.1 wire.view contract.
2026-08-22 16:30:55 +08:00
bowenliang123 1ddd99978f docs: update compatibility section in AGENTS.md to clarify runtime dependencies 2026-08-22 13:36:03 +08:00
bowenliang123 1fd605d2d2 docs: add dsh version compatibility contract to AGENTS.md 2026-08-22 13:29:16 +08:00