1042 Commits
Author SHA1 Message Date
bowenliang123 6f8dd889de feat(overview): auto-open the trend overview at a step threshold
Add the per-user overviewAutoSteps preference (100/200/300 steps, or off; 200 by default) to the plugin settings card. Once a session's retained step count reaches the threshold, the trend switches to its Overview ribbon and clears the mutually exclusive DNA/Adaptive faces; the auto activation fires once per session so a reader's own toggle-off sticks. The threshold counts raw retained steps, independent of the step/turn granularity.
2026-10-21 11:53:38 +08:00
bowenliang123 229f7b15ac fix(cost): make DeepSeek peak pricing explicit and weekday-based
The tooltip and shared type still described the pre-#78 scheme (peak at
list price, off at half), while models.dev lists DeepSeek's off-peak
rates and the estimator doubles the peak bucket. Correct the wording in
both locales, the cost type, and the READMEs; only DeepSeek's peak
buckets double, every other provider prices at list.

Express the peak clock in Beijing Time directly (Monday-Friday
09:00-12:00 and 14:00-18:00, weekends off-peak) and rename isPeakUtc to
isBeijingPeak. The UTC-to-Beijing refactor is behavior-preserving, so no
stateVersion bump is needed. Statutory holidays are deliberately not
modeled; record that limitation in docs/compatibility.md.

Refs #178
2026-10-21 10:42:31 +08:00
bowenliang123 18075e6b66 fix(overview): track pointer hover locally on the ribbon
The ribbon rendered its cursor and tip from the parent's hoveredSeq, which
contextView throttles with a 140ms trailing update and a transition so pointer
sweeps cannot re-render the whole view; during a sweep the readout froze at the
first record and jumped once after the pointer rested.

Keep the pointer's record in local state, as the bars face already does, and
relay it upstream unchanged: the readout now follows every record change while
the browser preview keeps its throttle. hoveredSeq's only producer is this
pointer, so the local record wins while the pointer is inside; leaving drops it.
2026-10-21 10:27:51 +08:00
bowenliang123 811422252e feat(overview): flag turn quartiles and align the turn strip
The Overview face now plants the same quartile and full-span poles in turn
granularity as in step granularity, labeled with the turn number each pole
lands on (step poles keep the step's 1-based position). The shared pole
classes become lc-trend-flag/lc-trend-flag-label since they carry either
number in both faces.

The turn strip's blocks grow by record span — the ribbon's own x unit — so
one-record-per-turn aggregates stay equal width and the strip labels line up
with the poles; step mode keeps its step-proportional blocks. A trimmed head
keeps absolute turn numbers on both layers.
2026-10-21 10:08:38 +08:00
bowenliang123 1bc481c8f1 fix(docs): clarify instructions for loading the code-review skill 2026-10-20 10:35:19 +08:00
bowenliang123 026ffca599 feat(context): fold the range off the step-start daily ledger
Context Insights now reads contextActivity for every range-scoped figure: a step's settlement, tool run, and wall time book on the local day its step/start fired, so a step crossing midnight stays on its start day. The KPI band, Token Stats, and session selection share the daily ledger; turns, tool calls, and step wall time join each day, and contextActivity's stateVersion moves to 5 so cached rows cold-refold. The Activity heatmap drops the Steps metric for daily token volume; Timing Stats stays session-lifetime and is labeled as such.

Refs #172
2026-10-20 08:42:51 +08:00
bowenliang123 16ecd2af38 chore(compat): support the dsh 0.2.1 line
The plugin declared two supported dsh releases while the line it actually
runs on — 0.2.1 — was outside the matrix, so the seams the plugin rides were
never probed against it.

The 0.2.1 line continues the V4 Config-form generation with every seam spelled
as at 0.2.0-rc.2, so the baseline entry is the same with the two facts that
differ: the line vendors cordis 4.0.5, and it adds the `web-deepseek-api`
entry the balance fold falls back to. The compat matrix now runs the plugin
against that tag's real sources like any other line, and the workflows fetch
it.

The driver's staging follows the line: the values package grew a sibling
module its entry re-exports by relative path, so the entry is staged under its
own name and the sibling rides along.
2026-10-20 06:01:36 +08:00
bowenliang123 00d8afa224 fix(host): read the balance facts from the DeepSeek platform's own row
The capsule could ask the platform for a balance it would never get, with a
credential it had no business reading.

The fold matched its settings row by SHAPE — the first section carrying a
top-level `apiKeyEnv` — so a row belonging to another provider supplied the
credential, and that row's `baseURL` was used verbatim as the API root, so a
path-carrying endpoint (`/v1/tools`, `/anthropic`) asked for
`<baseURL>/user/balance` and the capsule stayed empty.

The fold now takes only DeepSeek platform rows: the `llm` provider directory
names the API-key model's own row (whatever the entry is called), and dsh's
stock entry ids are the fallback. Another provider's key is never read and
never sent, and a row whose credential does not resolve sends no request at
all.

The endpoint is the platform ROOT: only the origin of the row's endpoint
override counts, so the account route is always `/user/balance` on the
deployment's own DeepSeek origin. The projection is read redacted, so a row's
literal key never enters the fold.

The compat matrix pins the seams this reads: the redaction option, the
provider directory, and the stock entry ids each line ships.

Fixes #176
2026-10-20 06:00:52 +08:00
bowenliang123 c22ccb2039 fix(client): keep the zero residual row on the timing card
The overhead slice is the wall-minus-slices residual, and the live fold prices
an open step's model/tool windows before its wall time — so the residual
transiently clamps to zero at every step boundary. Dropping zero rows hid the
row mid-step and restored it at step/end, resizing the card on every step.

The residual row now keeps its dimmed slot (0.0% / —) whenever any slice
carries time; every other zero slice stays hidden, so a zero row cannot borrow
the session's count and read as "many calls, no time". A timing with no priced
slice at all keeps the empty state.
2026-10-19 11:43:07 +08:00
bowenliang123 90a699c611 feat(client): keep the file title row on one line when it fits
Drop the forced chip row: the title, the tally and the chips share one line
whenever they fit and fold naturally when they don't; only the phone-width chip
fold keeps its reserved height. The README screenshot is refreshed to the
one-row layout.
2026-10-19 10:40:42 +08:00
bowenliang123 79eb243481 feat(client): move the file tally into the card title row
The file count and the added/removed line deltas now sit right of the title
("File Activity 41 files +493 −464"), the standalone tally row is gone, and
the chips keep the title row's right edge. Below the one-line breakpoint the
chips take a row of their own and the title reserves that folded height, so
tally digits cannot add or drop a row mid-session.
2026-10-19 10:40:18 +08:00
bowenliang123 a3f572244b feat(client): drop the collapsed file row's error dot
Failures now surface only on the expanded op rows. The collapsed row's
aggregate tally added little on its own (its edit ops already flag the failing
tool call), so FileEntry.errs — which existed only for that dot — and the
files.errs strings go with it; each op keeps its own err flag for the expanded
dots.
2026-10-19 10:39:53 +08:00
bowenliang123 abce91a6a6 feat(client): move file-op values and step stamps to the row's right edge
Expanded file rows now end in one right-aligned meta group: the read window,
the line delta, the failure dot and the stamp+time. The turn/step stamp is the
Context Browser's own (`stepStampOf`, reusing browser.stepAt/stepAtTip): the
first request that carried the op's result node, merged with the op time, or
the time alone when no logged request carries the op yet. Nested Code-Mode ops
scope through the shared `surfaceSeqOf` helper, and the meta group wraps onto
its own right-aligned line on phone-width cards.
2026-10-19 10:39:29 +08:00
bowenliang123 fb6f2a92ec docs: refresh the file activity screenshot
The README embeds docs/file-activity.png, which still showed the dropped
scope line and the old chip/search/sort placement.
2026-10-19 08:42:45 +08:00
bowenliang123 a9f34e8f58 feat(client): tint the file activity all-files chip blue
The aggregate chip now reads blue in every state: solid info-blue while it is
the active scope (theme foreground text) and blue label text when another kind
chip narrows the list. The kind chips keep their purpose colors.

It rides the theme's existing state-business-primary / button-info-fill /
label-primary-foreground aliases, so light and dark themes both resolve.
2026-10-19 08:42:25 +08:00
bowenliang123 daaf84a49b feat(client): move the file activity filters into the card title row
Drop the scope line and put the five kind chips in its top-right slot. The
search box now leads the row below, the sort toggle sits on that row's right
edge, and the meta row keeps only the file tally and line deltas. The unused
scope prop, its computation and the files.scopeLatest keys go with the line;
the picked step/turn still reads in the request detail header.

The count-bearing chips widen as their tallies gain digits, so the title row
reserves its folded height on narrow cards — the same guarantee the old
controls band carried, applied to the row the chips now live in.
2026-10-19 08:42:02 +08:00
bowenliang123 a7ce2158c1 chore(release): 0.73.3 2026-10-19 08:06:02 +08:00
Bowen Liang 92e50e9376 fix(context): address Copilot review findings (#169)
- pass the active locale into the /context modal's browser so memoized step
  labels re-translate while the dialog stays open;
- re-run the height-cap measurement and its ResizeObserver after the hidden
  sidebar copy remounts;
- restore DNA band hover reveal for off-window rows: keyed rows, key→index
  map, scroll the window into place, then reveal after the commit;
- only window the file list when every row measures the same height: real
  long-path wrapping made the fixed-pitch spacers too short (scroll jumps);
- re-clamp the chart tip when a different DNA band changes its width;
- keep a tiny DNA bar's colour instead of emitting an empty gradient.

Tests cover the off-window band reveal, the mixed-height file-list fallback,
and the sub-pixel DNA bar.
2026-10-19 08:01:49 +08:00
Bowen Liang c786c51b50 fix(context): keep DNA strands aligned across bars (#168)
The earlier gradient-stop cap sampled every bar's runs independently, which
broke the shared px-per-token invariant: the same band landed on a different
offset in each column, so neighbouring bars' colour strands no longer lined up.

Quantize internal band boundaries to one shared 2px grid (the final boundary
stays exact so the bar stays filled), merging same-colour runs and absorbing
sub-grid slivers. The tooltip and hit-testing still read the untouched band
model; only the rendered gradient changes.

Adds snapDnaRuns unit coverage plus exact-gradient expectations.
2026-10-19 07:47:44 +08:00
Bowen Liang a694adfb34 perf(context): cut context-tab render, hover and DNA costs (#167)
* perf(context): cut context-tab render, hover and DNA costs

P0 — interaction/caching:
- isolate pointer hovers: chart-local hover stays immediate, cross-card previews
  trail (140ms; 220ms in DNA mode) so sweeps cannot stack full-view renders;
- cache pure projections (assemble, DNA/file derivations) across hover/remount;
- remove forced layout from the flow/timing read paths, gate the hidden sidebar
  copy, memoize picker options and tool tallies.

P1 — windowing/lazy rendering:
- window trend bars, file-activity rows, timing-strip segments (dense gradient)
  and the browser DNA feed; off-screen rows use content-visibility;
- lazy-mount the browser card and the below-fold event/file row behind
  height-matched skeletons, mounted on an idle slice / near the viewport;
- window DNA bands on long total-mode logs, tighten the DNA window, sample
  per-bar gradient stops, and keep DNA+delta eager so its churn axis stays exact;
- force-mount + reveal for stats file-pill jumps into the lazy row.

Rendering-only by construction: axes, tooltips, ordering, DNA hit-testing and
every readout still come from the full model; scrolling only changes which rows
are in the DOM. Measured on a 987-step session: mount 986-1251ms -> ~510ms,
first paint 480-592ms -> ~80ms, zero long tasks; tab DOM 15,929 -> 3,226
(below-fold mounted ~4.7k); hover 30 -> 0 long tasks; DNA toggle 875 -> ~230ms.

Tests: new window/lazy/DNA/cache specs; lint, typecheck and 138-file 100%
per-file coverage green.

* fix(context): second-review follow-ups

- keep DNA bands fresh per header epoch, and force eager DNA+delta on long
  logs so per-key churn axes stay exact;
- correct windowed spacer heights for the container flex gap: the file list
  and the DNA feed now reproduce the full scroll height exactly;
- re-translate memoized picker/tooltip labels when the locale changes;
- re-observe lazy mounts across detach/reattach (a collapsed sidebar copy)
  via a callback ref, keep forced mounts for stats jumps, and clear the
  chart's local hover/DNA state on mouse leave;
- shrink the window for a mount that already has DNA on, and add the async
  subagent count to the flow-measurement deps;
- repair the skeleton background rule and restore the accidentally
  globalized .lc-heat-ctl .lc-card-sub selector.
2026-10-19 07:38:56 +08:00
bowenliang123 2ee5c96c9d chore(release): 0.73.2 2026-10-18 21:30:13 +08:00
bowenliang123 48c423a24d fix(client): reclaim the Fleet tab's top on entry (#164)
The harness keeps one resident `[data-conversation-scroll]` scrollport across
tab switches and the chat bottom-anchors it, so a long session's scrollTop
rode into the Fleet tab and clamped to the page's own scroll floor — the tab
opened at its bottom. The page now re-claims the top per session in a layout
effect, on both the loading frame and the full page, so the inherited
position never paints. No per-session ledger here: the page's height settles
in late passes (forest arms, then details), so a restored position clamps
against the slim first frame and scroll anchoring re-pins the bottom — the
Context tab's ledger stays as is, its content lands at full height in one
commit.

Fixes #164
2026-10-18 21:25:37 +08:00
bowenliang123 dd8e66955d fix(client): hide an expanded JsonTree row's inline preview
The rule matched `[class$="_summary"]` — the plugin bundle's `[hash]_<local>`
css-module naming — but the tree renders from the shell's Vite build, whose
scoped names end with `_<line>` (`_summary_1alm6_198`). It never matched, so an
expanded node showed its inline preview and then the same values again as its
children.

Match the `_summary`/`_preview`/`_punctuation` locals as substrings and hide the
comma stranded behind the preview, with a regression test covering the shell
build and test spellings. Drop the compat pin that described the plugin build
instead of the shell's, and add `css.punctuation` to the JsonTree seam needles.
2026-10-18 16:38:38 +08:00
bowenliang123 29b08f5158 chore(release): 0.73.1 2026-10-18 15:24:53 +08:00
Johnny a2d14dbad1 fix(client): key the hover tip's measurement on its inputs (#163)
Fix the touch-triggered React #185 in the insights hover tip: key the measure pass on its inputs (side, label, rect, viewport) instead of tip identity, and re-measure a relabelled tip at the same rect.

Based on the original fix direction from @nexw.

Fixes #162
2026-10-18 15:22:08 +08:00
bowenliang123 679dc669f4 fix(client): keep the block map's height steady when rows open
Opening a category or an exact row grew the rows region's flex base, and
the capped card charged the whole deficit to the map — the only other
shrinkable item — folding it to its 40px floor on every pick. The map sat
in the fixed zone but still changed shape under the click.

Pin the map's flex base so opened rows scroll the rows region instead of
squeezing it; a percentage ceiling still folds the map when a capped card
is genuinely too short (a content-sized card ignores it). The /context
dialog's hard viewport cap is the one real pressure: while the map shows,
the dialog fills its cap and the browser card and rows region size from
the leftover, so the map folds exactly to what is left instead of
overflowing.
2026-10-18 11:01:37 +08:00
bowenliang123 0cd9762bad feat(client): add a by-name sort to File Activity
The sort toggle ordered rows by counts, recency, and path; the row's own
last segment — the bold name a reader scans for — had no order of its
own, so same-named files in different directories never grouped. Name
leads on the displayed last segment (either separator style, via the
shared leafNameOf) and the full path breaks ties between rows that share
a name.

The Preferences picker, the host Config union, the shared
DefaultFileSort vocabulary, and both dictionaries carry the fourth
option; glyphOf now reuses the same leaf helper instead of its own split.
2026-10-17 12:47:42 +08:00
bowenliang123 3ee45f6d81 feat(client): make the stats pills jump into the browser and File Activity
The Input / Output capsules were dead weight beside the jumpable figures:
every destination sat below the fold. Human Inputs now opens the Context
Browser's User Messages category — the same one-shot catFocus relay the
skill and answer figures ride — and Read / Written / Searched / Images
land on the File Activity card with that kind chip picked: a one-shot
filter focus the card applies, hands back to the caller, and clears its
own text lens and open row for.

The pills became hover links: pointer, lifted wash, focus ring and an
action title, with Enter/Space parity through one shared jump wiring. A
pill carrying its own ? bubble keeps the native title off so a single
hover shows a single hint. The figure relay was unified as onJump
(onFigureClick is gone), and the browser reveal grew into revealCard,
which the File Activity landing shares.
2026-10-17 12:29:43 +08:00
bowenliang123 f3be3b4c03 fix(client): end the context browser flush with the left cards
The tab capped the browser column at the left cards' height bounded by
the host scrollport's slice from the card's top edge; that slice added
the scroll offset on top of rect coordinates, so a scrolled or short
pane clamped the card far below the left column — an empty gap under
the composition + trend cards.

Cap the column at the left cards' measured span alone (first card top to
last card bottom, rounded up): the row's stretch then makes it the
card's height, so it ends flush with the two cards at every width where
they sit side by side, while the DNA feed still scrolls inside the card.
Drop the pane-fit plumbing and its now-dead scrollport observation, and
replace the README's stale three-times claim.
2026-10-17 11:32:25 +08:00
bowenliang123 efed68b05f fix(client): keep the browser's fixed zone still across every host
The /context dialog scrolled as a whole while the DNA feed rode it, and
scrubbing the composition bar dragged the dialog too — the row reveal's
nearest scrollable ancestor was the dialog card itself. In the tab, the
3x left-column cap let the card outgrow the pane and change height on
every DNA toggle, dragging the head off-screen and the cards below with
it; band picks scrolled the page via scrollIntoView.

Make the card's own fixed zone the rule in every host: head, DNA lens
and block map stay put while only the rows region scrolls. The tab
column caps at the left column's height bounded by the host scrollport's
slice from the card's top edge (browserCapOf), so toggling DNA or
opening categories never moves the cards below; the /context dialog
becomes a filled flex column whose browser card shrinks instead. Row
reveals bind to the card (revealRowInCard): scrubbing and picks never
scroll above it, and the rows region contains its wheel so the page only
moves when the pointer leaves.
2026-10-17 11:02:14 +08:00
bowenliang123 0103b07747 chore(release): 0.73.0 2026-10-17 09:48:22 +08:00
bowenliang123 a03e606f08 fix(client): paint the DNA trend bars on the shared token scale
DnaBar's gradient stops were percentages of each bar's own total, so the
browser rasterized common strands differently per bar (sub-pixel bands
flipping visible/merged between steps) and inherited bands read thicker
and thinner across the chart. Stops now ride the shared per-token pixel
scale (CHART_H/maxTotal) and are byte-identical in every bar; the bar
height reuses the same scale. Live-measured on a 99-bar session with the
duration curve off: adjacent-bar common-row pixel diffs dropped 589 -> 11,
the remainder being genuinely new top-of-bar strands.
2026-10-17 09:35:33 +08:00
bowenliang123 a4bec7d544 refactor(client): split the browser card into a fixed head and a scrolling rows region 2026-10-17 07:08:04 +08:00
bowenliang123 feacf5d906 feat(client): stripe the context browser's rows with a faint even-row wash
Row lists (the DNA flat feed, category bodies, tool schemas) previously read
as one undifferentiated white field. One rule keyed on the shared .lc-br-elem
row factory stripes every list: `nth-child(even of .lc-br-elem)` keeps the
phase stable across toolbars, notes and filtered-out rows, the tint is 60% of
the theme's interactive hover wash so it sits under hover and open states,
and an open row keeps its active highlight alone.
2026-10-17 02:49:33 +08:00
bowenliang123 9c55959456 fix(client): exempt the DNA faces from the browser's category focus
Opening a browser row/category persists focusCat with no visible UI; with DNA
on, TrendChart then scaled bar heights to the focused category's share
(focusOf) while the band data and the lifetime slices stayed in full-context
offsets — dark slices floating above half-height bars. The DNA faces now pass
no focus into preprocessTrend (the stacked faces keep it), and the previously
false-positive 'focus is ignored' test now discriminates: with the axis driven
by a second bar, focused heights (22px) diverge from the full-context share
(56px).
2026-10-17 01:25:01 +08:00
bowenliang123 f4db11776f fix(client): ride the fetch routes as browser-relative spellings
The client POSTed every plugin route as a root-absolute /api/dsh-context/*
path, which stripped a reverse proxy's /app/dsh prefix at the gateway —
every poll 404ed at it, the panel retried on an aggressive backoff, and
the deployment fell into the issue #159 reconnect loop. The six route
constants now live in one module as their browser-relative spellings:
fetch resolves them against the page's document base, the same idiom
dsh's own stream/socket clients ride, so a prefixed proxy keeps its
prefix and a direct deployment resolves to the exact same URLs before
and after. A host/client pairing spec pins each spelling to its route
registration, and docs/compatibility.md gains the §5.8 client-seam rule.

Fixes #159
2026-10-16 23:50:58 +08:00
bowenliang123 8331602b0b docs(vitest): state the pool rationale as measured runtime
Review follow-up to 2ce42f6: "~30% off the coverage gate" reads as a
pass/fail claim, and the file count next to it rots as specs are added. The
comment now names the measured runtime and keeps only the two facts that
cannot be read off the config: the per-worker environment an amortized ~30%
buys, and why the pool stays client-only.
2026-10-16 23:22:08 +08:00
bowenliang123 2ce42f6e7a perf(client): run the client suite in the vmThreads pool
Vitest 5's duration diagnostics flagged that the jsdom environment was created
once per client file — 111 times, 36% of tracked time. vmThreads creates it
once per worker while keeping per-file isolation, so the same 153 files /
2429 tests and the same 100%-per-file coverage scope (131 instrumented files)
now finish in ~16.7s instead of ~24.0s: paired interleaved medians of five
gate runs, and ~46% faster at the CI runner's four workers.

Client-only: the host project fails under vmThreads (10 files), and the
`isolate: false` shortcut the same hint offers fails two client files.
Peak process-tree memory rises ~0.9 GB (3.0 -> 3.9 GB).
2026-10-16 23:18:16 +08:00
bowenliang123 e620e4fbf6 chore(deps): update vitest to 5.0.5
Vitest 5 needs Node >=22.12 and Vite >=6.4 — already satisfied (node 24, vite
8.3.1 auto-installed as its peer) — and needs no config or test change here:
`clearMocks` now defaults on, inline projects inherit the root config, and `-t`
joins suites with ">", none of which this repo relies on.

Paired interleaved runs against v4.1.12, on two warm checkouts and alternating
the version per pair to cancel machine drift: `vitest run` 22.40s -> 20.95s and
`vitest run --coverage` 26.09s -> 25.65s (median per-pair delta -5.8%), with the
same 153 files / 2429 tests and the same 131-file coverage scope at 100% per
file.
2026-10-16 23:06:48 +08:00
bowenliang123 9217fca879 feat(client): echo a DNA band hover onto its feed row
Hovering a band on the DNA bar now lights the row it names below — a message
band its exact feed row, a tool-schema band the tools group row, the system
band the system row — the reverse of the row-hover-to-band link, so the two
surfaces read as one surface. The echoed row also scrolls into view, confined
to the nearest scrollable ancestor's own scrollport (the capped column): the
row only has to reach the scrollport's visible slice, since a capped column
usually extends below the page fold and a page scroll would drag the pointer
off the pinned band mid-scrub. Clicking a band still lands on the row and
expands it.
2026-10-16 22:33:19 +08:00
bowenliang123 ef478dee24 feat(client): cap the context browser at 3x the composition + trend cards' height
The DNA flat feed lays every message out at once, and an uncapped card would
outgrow the page. The browser column now measures the composition and trend
cards stacked beside it — per render, followed by a ResizeObserver for pane
drags and card reflows — and tops out at three times their sum, scrolling
taller content inside; the card head (title, composition bar, notices, and the
DNA feed's lens) stays pinned above the scrolling list. The /context modal
keeps its own single-card scroll and stays uncapped.
2026-10-16 22:10:46 +08:00
bowenliang123 26cfc8052e feat(client): lay the DNA context feed out flat in reading order, newest on top
In DNA mode the category accordion yields to one flat list of every assembled
item: the model reads the prompt oldest-first, so the list presents that order
bottom-up — the newest message is row one, and the tool schemas (one group row
opening into the category body) plus the system prompt close the list. Each row
carries its #prompt position, a category chip tinted with the category's own
palette color, its introducing-step stamp and token price, and expands into the
same full content.

A text lens pinned in the card head filters the feed's rows and the open tools
group's schemas alike (the served system prompt text included); hovering a row
lights its exact band — or its band group for the header rows — on the DNA bar
without reporting upward; a category jump (catFocus) drops back to the
accordion, which has no row landing in the feed.
2026-10-16 22:09:48 +08:00
bowenliang123 781c81e216 fix(client): shrink the /context modal's side margins to two thirds
The card was pinned by the fixed 720px cap, so wide panes left large
proportional blank space on both sides. Width is now
min(calc(33.333% + 480px), calc(100% - 32px)): each side margin is
exactly 2/3 of the old layout's at every pane width, and the narrow
gutter floor drops from 24px to 16px.
2026-10-16 20:54:03 +08:00
bowenliang123 aca1574c25 feat(client): render JSON-detected section bodies as the harness JsonTree
Whole-text JSON payloads (a leading { or [ that parses) open on the shell's
JsonTree inspector instead of markdown: the switch offers Raw|JSON there
(markdown is meaningless on structured payloads), the tree opens two levels
deep via the expanders' own click path (focus restored, capped at 100), and
an expanded row drops its inline preview Chrome-DevTools style. The JsonTree
faces are pinned per baseline and probed by the compat matrix.
2026-10-16 18:45:26 +08:00
bowenliang123 dd690e0599 fix(client): give the native selects dsh's form-field border
The 1px border-l2 hairline on a white layer-2 background reads as
borderless. Adopt dsh's own form-field recipe (0.5px solid border-l4,
the settings inputs/selects idiom) for all four native selects: the
overview coverage picker, the fleet sort/filter, and the context
browser step picker.
2026-10-16 16:37:35 +08:00
bowenliang123 7ae8de869d feat(client): add a session coverage picker to Context Insights, defaulting to all
Archived sessions fold back into every figure the page derives off the
session list: rowsOfSnapshot now tags archived rows instead of dropping
them, and one coveredRowsOf pass scopes the KPI band, charts, heatmap,
skills, and the session grid together. A "Filter sessions" select next to
the list's search box offers dsh's own archived-filter set — All (show
archived) by default, Hide archived, Archived only. The Active Sessions
card follows the picked coverage (Sessions incl. the window's archived
count under All; Active/Archived Sessions over the full-list total under
the narrow scopes), archived cards wear an Archived tag and refuse to
open like dsh does, and kpisOf drops its now-unused listed param.
2026-10-16 15:58:28 +08:00
Copilot ca5a3e8d3d chore: declare supported DSH engine range via engines.dsh in package.json (#155)
Authored-by: bowenliang123 <liang.bowen.123@qq.com>
2026-10-15 21:59:03 +08:00
Copilot ba65d6ea96 doc(readme): Add Chinese README translation (#154)
Authored-by: bowenliang123 <liang.bowen.123@qq.com>
2026-10-15 21:36:40 +08:00
bowenliang123 ca89acfd93 chore(release): 0.72.0 2026-10-15 15:47:04 +08:00
bowenliang123 8d634dc719 fix(client): make the block-map toggle span the browser bar block
Wrap the meta row and the composition bar into one main column with the
enlarged map toggle as a right column stretching across both rows, so the
figures shift left of the card edge instead of crowding the button.
2026-10-15 15:26:02 +08:00