Commit Graph
100 Commits
Author SHA1 Message Date
imccyu fe26d793c5 Merge pull request #746 from deepseek-harness/fix/todo-tool-ui
refactor(todos): update TodoRow styling and logic, add IconChecklistOutline16, and enhance AssistantMarkdown rendering
2026-07-28 11:35:36 +08:00
imccyu 8f13e09f31 Merge branch 'master' into fix/todo-tool-ui 2026-07-28 11:32:07 +08:00
imccyu fd9d1b3350 Merge pull request #600 from deepseek-harness/worktree/web-session-model-selector
feat(web): add session model selector
2026-07-28 01:00:38 +08:00
imccyu 730657375f Merge branch 'master' into worktree/web-session-model-selector 2026-07-28 00:56:56 +08:00
imccyu 7e2f6f474d fix: lint 2026-07-28 00:56:37 +08:00
imccyu 2c5c1e72ba fix: merge conflicts 2026-07-28 00:45:27 +08:00
imccyu 94af1589a9 Merge branch 'master' into worktree/web-session-model-selector 2026-07-28 00:40:08 +08:00
imccyu af70af4020 Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector 2026-07-28 00:39:24 +08:00
imccyu cdd4d59ea0 chore(lint): clear the semantic .tsx backlog
Hand fixes for the findings --fix cannot touch, mirroring the fixes
already applied on the fe-docs feature branch (same file, same shape)
so its eventual rebase resolves cleanly:

- restore the return the no-confusing-void-expression autofix ate in
  useAbsentSnapshot (typed S | undefined; hook call kept for hook-order
  stability, undefined returned explicitly);
- re-type DOM queries the no-unnecessary-type-assertion autofix broke:
  getByRole<HTMLButtonElement>(...) generics instead of the removed
  as-casts (the eslint program and the client tsconfig aggregate
  disagree about these casts; the generic form satisfies both);
- justified eslint-disable for the deliberate legacy paths: keyCode 229
  IME-composition detection, execCommand clipboard fallbacks, lib.dom
  clipboard optionality, and the any-typed Reflect.get/this probes in
  test fakes;
- drop the dead react/no-danger directive (eslint-plugin-react is not
  loaded, so the rule never applied) keeping its shiki rationale;
- delete the tautological 'Z' comparison and the renameTarget null
  check already implied by renameBlocked;
- css-module non-null assertions replaced by type widening
  (Button className, TAG_CLASS Record) per the established pattern;
- misc: max-len comment wraps, void generic drop in the deferred test
  helper, unused type imports, floating selectWorkspace promises voided,
  member-delimiter newlines in inline type literals.
2026-07-27 22:23:41 +08:00
imccyu 2adf44fb80 chore(lint): declare contract callbacks property-style
unbound-method flags destructuring a method-style member (method
signatures are bivariant and exempt from the this-context check).
These contract members are all plain callbacks — declare them as
property-style function types so consumers can destructure them
without a false this-binding hazard. Type-level only.
2026-07-27 22:23:10 +08:00
imccyu 49c2e85ac7 chore(lint): apply eslint auto-fixes across the .tsx backlog
Mechanical --fix output over the newly linted .tsx files (indent,
arrow-parens, comma-dangle, member-delimiter-style, unnecessary type
assertions), plus the three generic-arrow test hooks converted to
function declarations up front: the comma-dangle fixer strips the
<T,> disambiguation comma and turns them into parse errors otherwise.
2026-07-27 21:49:40 +08:00
imccyu 36e8141145 chore(lint): bring .tsx files into the eslint, lefthook, and jscpd lanes
.tsx sources and specs were invisible to every lint surface: the eslint
flat-config globs, the lefthook staged-file glob, and the jscpd clone
scan all matched *.ts only. Widen the five eslint file groups (source,
test, client-test, sonar, formatting), the pre-commit glob, and the
jscpd format/pattern to cover .tsx.

Existing .tsx files predate these lanes; follow-up commits on this PR
clear the backlog they surface.
2026-07-27 21:42:08 +08:00
imccyu 4feb657b45 Merge pull request #754 from deepseek-harness/fix/question-composer-row-shrink
fix(ui-question): stop option rows absorbing the capped card's shortfall
2026-07-27 21:19:10 +08:00
imccyu 9b23fe84c1 Merge pull request #751 from deepseek-harness/feat/workspace-native-folder-picker
feat(gui): add native workspace folder picker
2026-07-27 20:59:50 +08:00
imccyu 6d8e5fb3a2 Merge branch 'master' into worktree/web-session-model-selector 2026-07-27 19:36:19 +08:00
imccyu 5cae7874f6 git: add .orig to gitignore 2026-07-27 17:27:41 +08:00
imccyu 67ad0eb887 Merge branch 'master' into fix/remove-orig 2026-07-27 17:23:03 +08:00
imccyu e8cbf6cc72 fix: remove orig 2026-07-27 17:22:01 +08:00
imccyu d8ce036295 Merge pull request #738 from deepseek-harness/feature/delete-workspace
feat(web): delete workspace registrations
2026-07-27 17:08:48 +08:00
imccyu a020400286 Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector 2026-07-27 17:01:42 +08:00
imccyu 0052ea49ff Merge branch 'master' into feature/delete-workspace 2026-07-27 16:59:28 +08:00
imccyu 4918872c5c Merge pull request #740 from deepseek-harness/feat/todo-tool-ui
feat: optimize ui of todo tool
2026-07-27 16:59:18 +08:00
imccyu f3ce520317 Merge branch 'master' into worktree/web-session-model-selector 2026-07-27 16:58:35 +08:00
imccyu cbcb911781 Merge branch 'master' into feat/todo-tool-ui 2026-07-27 16:55:35 +08:00
imccyu 50ec3b1db0 Merge branch 'master' into feat/todo-tool-ui 2026-07-27 16:54:34 +08:00
imccyu 5b81025b58 Merge branch 'master' into feature/delete-workspace 2026-07-27 16:52:24 +08:00
imccyu 62a37ba38a Merge branch 'master' into worktree/web-session-model-selector 2026-07-27 16:19:40 +08:00
imccyu 9249c5504e Merge remote-tracking branch 'origin/master' into worktree/web-session-model-selector 2026-07-27 16:16:17 +08:00
imccyu 6583f896cf fix: module-graph 2026-07-27 16:12:02 +08:00
imccyu 5f589da54d Merge pull request #706 from deepseek-harness/markdown-ui
feat: optimize chat ui
2026-07-27 16:08:48 +08:00
imccyu 52985d688d Merge branch 'master' into markdown-ui 2026-07-27 15:58:13 +08:00
imccyu 228d503230 fix: code-mode fixture snapshot 2026-07-27 15:49:37 +08:00
imccyu b8d7938498 Merge branch 'master' into markdown-ui 2026-07-27 15:44:30 +08:00
imccyu 0a7c8a284d chore 2026-07-27 15:44:10 +08:00
imccyu b241d4332c Merge branch 'master' into markdown-ui 2026-07-27 15:23:13 +08:00
imccyu e14c2aea3d Merge pull request #497 from deepseek-harness/web2-todo
feat(gui): todo display — TodoPanel plan strip + dedicated todo_write tool row
2026-07-27 15:22:03 +08:00
imccyu 8605099282 fix: model selector width 2026-07-27 14:54:27 +08:00
imccyu 3b04941830 Merge the concurrent selector adaptation; ui-model stays the model owner
The remote side re-merged master (i18n workflow round) and restored the
pre-architecture ModelSelector package with the Session-side state
machine. Reconciliation keeps that merge's master content and reasserts
this branch's model architecture: business state lives in ui-model's
shared per-session directory (ctx.models), not on Session/
ConversationSnapshot; the input.model seat entry and the /model popup
stay the two same-source entries; the history modelTarget piggyback stays
removed. The ui-model-selector package, its roster row, and its allowlist
entry go; the smoke-real roster names ui-model.
2026-07-27 13:36:25 +08:00
imccyu 3025a324cd Fix the setEffort arrow shorthand lint finding 2026-07-27 13:10:32 +08:00
imccyu 72717b7b78 Two-level model/effort selection per the MenuDropdown mock
The seat's dropdown follows figma 496:26454: the root pane is the
Model / Effort cell pair (14/22 label, value in the tertiary tone, right
chevron), each drilling into its own list — the provider-grouped model
list over the shared directory, and the High/Max effort levels. The
trigger (313:14108) shows both values: model name plus effort in the
caption tone. Effort is a client-local display echo on the shared
directory state for now — the design pairs the two as one selection, but
no wire carries a per-session effort override yet (the deepseek adapter's
reasoningEffort is deployment config); the directory state documents that
boundary, so wiring it later is a submit-path change, not a UI one.
Escape backs out of a drilled pane before closing.
2026-07-27 13:01:47 +08:00
imccyu b4476d24fe Settle the local gates for the model-selector round
- ui-model README pair (short-form Model Experience + audited registry
  entry + Known Limitations), recorded in the pairing manifest
- llm-deepseek README pair rebased onto master's version with this PR's
  real deltas (friendly names, 256k, selector consumers) on both sides;
  runtime/ui-conversation READMEs revert to master (their sections
  documented the removed Session state machine and control slot)
- config catalog regenerated for the ui-model roster row
- ModelDirectory.store JSDoc; ui-model files join the TODO(gui) coverage
  deferral lane beside their ui-command/ui-slash siblings
2026-07-27 12:11:54 +08:00
imccyu ae0b0cc49b Fix lint findings and calibrate the seat trigger to the figma mock
- unused SessionId import and an unnecessary assertion in ui-model
- two over-length fake-api lines split
- trigger chrome calibrated against figma 313:14108's ToggleButton
  (13/20 medium secondary at 28px; chevron in label-caption = the mock's
  #ADB2B8; the mock's leading icon is invisible there, so the seat has
  none, and its 'High' effort text has no wire concept to render)
2026-07-27 11:46:39 +08:00
imccyu 8dce7981c4 refresh code-mode trajectory ordinals for the todo fixture turn
Turn 65 (todo_write) at the fx-alpha tail slides the 50-message history
window: two head-of-window messages drop out, so every trajectory cell
ordinal shifts down by two. Timing, labels, and cell content are unchanged.
2026-07-27 11:38:02 +08:00
imccyu 190e49356f Revive the composer model selector on the named input.model seat
The original ModelSelector returns as the conversation.input.model seat
occupant (the named single slot the composer bar renders before its primary
button), alongside — not instead of — the /model popup. Both entries are
projections of ONE per-session directory owned by the new ModelService
(ctx.models): the same session.models load, the same selectModel submit,
the same host-reported current — a switch in either entry is what the
other shows next, asserted both ways in the plugin spec.

Trigger chrome follows figma 313:14108's composer ToggleButton (13/20
medium secondary label, 4px gap, caption chevron, 28px chip height
matching the sibling Plan/Read-only selects); the menu keeps the original
upward provider-grouped single-select with keyboard navigation. The
seat honors the owner locked bit as its disabled state.
2026-07-27 11:27:49 +08:00
imccyu f2a9f4a40e retire the stale ACP plan-mapping claim in the todo note
The automation-only ACP bridge deliberately omits todo presentation (its
edge test asserts plan updates are omitted; the todo-write tool note records
the mapping's retirement). Chinese counterpart updated, pair re-recorded;
the TodoPanel header comment drops the same claim.
2026-07-27 10:43:49 +08:00
imccyu 35ce35d8a6 Merge branch 'master' into web2-todo 2026-07-27 10:37:34 +08:00
imccyu c132cbdb6a Adapt session model selection to the slash/input/session architecture
- host trio kept on the merged api-proxy: session.models (provider-grouped
  advisory directory), session.selectModel (validated provider, advisory
  model), installAgentLlmTarget threaded through create/resume/ensureSession;
  the gateway declares the llm inject it reads
- history no longer piggybacks modelTarget: the current target travels on
  session.models alone (the /model popup is the sole consumer)
- new @deepseek-ai/dsh-client-ui-model plugin: /model popupSelect over the
  wire — options load the directory (group label in the detail column,
  provider-local failures listed inline), onSelect routes selectModel;
  failures ride the popup shell's error/retry surface
- ModelSelector package, conversation.composer.control slot, and the
  Session-side modelSelection state machine are removed: model selection
  belongs to the /model popup; the named conversation.input.model seat
  stays empty until a control-seat entry is designed for it
2026-07-27 10:28:45 +08:00
imccyu 8d1a3b89c7 fix runtime README pairing record left with merge conflict markers
The master merge committed the i18n.yaml with unresolved conflict hunks
(carried over from the adapt branch's own master merge); re-recorded via
verify-translation-pairing --write. 518 pairs consistent.
2026-07-27 10:25:12 +08:00
imccyu 6539c8d8fa Merge master (slash/input/session architecture) into web-session-model-selector 2026-07-27 10:23:51 +08:00
imccyu 83d3179d34 disambiguate the snapshot's workspace-group lookup
Latest master seeds a blank session also titled "fixture"; anchor the
session-tree lookup on the expandable group row instead of the first text
match.
2026-07-27 10:14:37 +08:00
imccyu dadb92302f adapt todo display to the slash/input/session architecture
- TodoPanel mounts through a 'conversation.input.dock' list entry
  (todoDockEntry, QueueDock posture, order -1 above the queue rows) instead
  of a ConversationRoot hardcode; the inner component is unchanged and takes
  useSession from the dock entry's standard kit.
- The verify-todo-display.mjs chromium probe is replaced by an assembled
  keyless snapshot (apps/web/tests/todo-display.snapshot.ts, the
  code-mode-fixture idiom) pinning the TodoRow summary/state, the dock
  panel content, and the collapse round-trip over built bundles.
- Fake snapshots across specs gain the todos field; bilingual note/READMEs
  updated for the dock mount and the snapshot.
2026-07-27 10:09:42 +08:00
imccyu 9d63d75a6f Merge remote-tracking branch 'origin/master' into web2-todo
# Conflicts:
#	packages/client/connection/src/client/fixture.ts
#	packages/client/runtime/README.i18n.yaml
#	packages/client/runtime/README.md
#	packages/client/runtime/README.zh.md
#	packages/client/runtime/src/client/index.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/ui-conversation/src/client/apply.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx
#	packages/client/ui-conversation/tests/chat-stats-bash-sample.spec.tsx
#	packages/client/ui-conversation/tests/chat-toolview-slot.spec.tsx
#	packages/client/ui-conversation/tests/chat-view.spec.tsx
#	packages/client/ui-conversation/tests/gate-branch-tails.spec.tsx
#	packages/client/ui-conversation/tests/skeleton.spec.tsx
#	packages/client/ui-trajectory/tests/views.spec.tsx
2026-07-27 10:07:51 +08:00
imccyu b044fe626c chore 2026-07-27 09:06:19 +08:00
imccyu 7a5576a4a8 style: reshape the fixture session guard under max-len and indent rules 2026-07-27 09:02:50 +08:00
imccyu 1b49666cd5 Merge branch 'master' into worktree-slash-split 2026-07-27 08:54:56 +08:00
imccyu dd2d9ca50a refactor: dedupe the jscpd clones; drop the baseline loading gate
- Extract the shared New Session action into WorkspacesService.startSession
  (sidebar button and workspace browser both delegate; recent-Workspace
  targeting and the no-workspace clear live in one place).
- Fold the chip-insertion transaction shared by insert-ref and paste-upgrade
  into one InputMachine helper.
- Share the fixture's session-not-found guard across the sessionId-addressed
  catalog routes.
- Drop the AppFrame baselines-ready loading gate (user ruling: the bare
  status line reads worse than the shell's own pending rendering); both
  column occupants mount from first paint.
2026-07-27 08:51:05 +08:00
imccyu 084e64744a test: defer coverage for the four new client plugin entry files
The exhaustive lane imports the loader-facing src/index.ts of the new
ui-slash/ui-command/ui-skill/ui-subagent packages without executing them
(0% functions); same client-lane deferral as their client/ halves.
2026-07-27 08:30:57 +08:00
imccyu ecdaf0dc24 test(web): connect a Workspace in the e2e boot path and refresh goldens
The startup-selection flow leaves a fresh world (no Workspace) in the
locked view state, so every e2e scenario that types into the composer
now connects one first via the shared connectFreshWorkspace helper
(hero picker create-by-name dialog; the default 'workspace' name keeps
the session-header cwd assertions intact).

Golden refreshes carry the current composer chrome: the plan/model
control seats are empty until their owning plugins register (the seats
shipped without occupants on this branch), the sidebar shows the
connected workspace group pre-send, and the bash details material
renders Input/code/Output as separate nodes. The cancel scenario polls
the frozen-partial swap instead of counting synchronously — the abort
frame reaches the browser over SSE after the host settles.
2026-07-27 08:25:00 +08:00
imccyu 250e2415ae test(web): re-anchor snapshot suites to the startup-selection boot flow
The startup Workspace auto-selection (wired in cd8ed43e4) changed the
boot landing: with any Workspace present the client connects its blank
session directly instead of resting in the locked view state.

- workspace-flow: New Session now reuses the blank session in place
  (no locked interlude); the failed-attach scenario asserts the actual
  recovery semantics — the host publishes the session before rejecting
  attachment, so the next connect reuses it into the hero (connect
  failures log to console, there is no view-state alert surface); the
  rejected-prompt scenario anchors on the sidebar New Session row since
  a send attempt leaves the hero for the engaging retry chrome.
- slash-flow: drop the stale i18n PLUGINS row (the package is locale).
2026-07-27 07:48:07 +08:00
imccyu cbe8735d7c feat(web): wire startup Workspace selection and sync docs
- Mount WorkspacesService.startInitialSelection in the runtime apply (the
  one-shot baseline follower shipped in 98633b5aa without a caller): a
  restored current session wins, an explicit clear stays cleared, a failed
  connect retries on the next baseline projection.
- Cover the policy in client-apply and the assembled workspace-flow
  snapshot; startup now lands in the recent Workspace's blank session, so
  the draft-carry scenario starts from the hero directly.
- Bring docs along: startup-selection paragraphs in the session-scope RFC
  note (both languages), bilingual README pairs for the four new client
  packages, doc-graph regeneration with client-declared events exempt from
  the dispatcher requirement (client dispatch sites are structurally
  invisible to the host-side ts.Program), and pairing re-records.
2026-07-27 06:24:09 +08:00
imccyu 22e4c05e69 style: reflow the send-committed event doc under max-len 2026-07-27 05:36:01 +08:00
imccyu 10bb708eb7 fix: review-bot findings on the provider-hosted shell
- Keep ConversationSession mounted for blank sessions (chrome-less) so the
  draft-persistence mirror stays bound in the hero; hero typing reaches the
  chat store again.
- Restore the baselines-ready gate in AppFrame: empty boot snapshots no
  longer flash the New Workspace hero before either baseline lands.
- Commit ordinary sends through the machine (send-committed event +
  Shell.commitSend): undo can no longer resurrect already-sent content on
  the default-sink path.
- Give the production InputMachine a real wall clock so the typing-run
  merge window actually expires.
- Coalesce concurrent connectWorkspace creates per workspace: the summary
  has no cwd until the host frame lands, so a second New Session inside
  that window minted a duplicate hidden blank session.
2026-07-27 05:07:59 +08:00
imccyu 45ad06ece9 test: defer per-file coverage for the new slash/command client files
Same client-lane debt as the existing GUI exclusions (TODO(gui)): the new
ui-slash/ui-command/ui-skill/ui-sidebar/ui-workspace client files and the
connection fixture keep their uncovered branches until the browser-grade
harness lands.
2026-07-27 04:51:07 +08:00
imccyu 45eee34faf test: adapt suites to the provider-hosted conversation shell
Test-side catch-up with the session-maybe conversation architecture: the
provide channel's descriptor shape and maybeProvideInfo in fakes, the shared
chat-store handle asserted on conversation.session (the session-maybe shell
carries no store), startSession fakes exposing the workspace list snapshot,
strict session slots declining (not throwing) without a session, AppFrame's
removed empty seat and loading gate, and the hero draft asserted on the
machine (the chat-store mirror binds with ConversationSession). Plus three
lint fixes (max-len split, boolean-compare, arrow-parens/unbound-method).
2026-07-27 04:28:42 +08:00
imccyu d1e43fcd8c style: typed queries in slash-flow snapshot, widen chat-apply key union 2026-07-27 04:13:05 +08:00
imccyu f6396f2573 style: fix lint across client packages
eslint --fix autofixes plus manual repairs: max-len line splits
(fake-api handlers, notifier/slots JSDoc, spec signatures), charAt over
non-null-asserted indexing in slash detect/menu cores, Array.from for
code-point capping, typeof assertions for unbound-method in specs,
generic getByRole for the send-button cast, effect disposer void-wrap in
command register, and dropped unused type imports.
2026-07-27 04:13:00 +08:00
imccyu a27be43ac1 feat: slash system / input service / agent scope 2026-07-27 03:28:39 +08:00
imccyu 92700c2375 Merge pull request #644 from deepseek-harness/worktree-websettings
Slot-composed settings surface with locale and theme preferences
2026-07-26 13:59:14 +08:00
imccyu 0fe9ff888d Merge origin/master into worktree-websettings
ui-sidebar shell landed on master (#643: geometry-only shell, the
browsing region moved to the sidebar.workspaces slot); this branch's
sidebar.settings foot seat re-applies on top — the hardcoded foot row
becomes the seat, the seat rides the railIn crossfade, and the shell
spec's renderSlot stub key-splits region vs settings.
2026-07-26 13:15:57 +08:00
imccyu fabc843c22 docs(gui): regenerate graphs for the returning ui-settings-general package 2026-07-26 12:48:30 +08:00
imccyu 7e20322c40 docs(notes): retitle the rejected alternative as per-feature satellite packages
The rejected shape is a settings satellite per feature; the ownerless
copy stays with ui-settings-general, which carries no feature surface.
2026-07-26 12:43:17 +08:00
imccyu a04a223bab refactor(gui): copy-free settings shell; ui-settings-general owns ownerless copy
The shell is now a pure composition face: no dictionaries, no locale
dependency, and three new chrome content seats (settings.trigger /
settings.header / settings.close) whose slot content also carries the
accessible names (trigger text, dialog aria-labelledby, visually hidden
close label). ui-settings-general returns as the owner of copy that
belongs to no single feature: chrome content, the General section with
its item slot, and the settings dictionaries. Slot types split homes —
trigger/header/close/section live in the shell contract; the
settings.general.item entry moves to the locale package (the common
dependency of every item registrant), with ui-theme consuming it
through a re-export seam; the verbatim duplicate merges are gone and
the dependency graph is a clean DAG.
2026-07-26 12:40:17 +08:00
imccyu 9a4be33899 docs(notes): record slot-declaration-as-service as future work
deferRegistration() stays the shipped form; the note pins the follow-up
direction (bridge declarations into slot:<name> services, migrate
registrants to nested ctx.inject, delete the helper) and the boundaries
a separate PR must settle.
2026-07-26 12:09:38 +08:00
imccyu 08251eb180 Merge branch 'master' into worktree-ws-more 2026-07-26 11:20:05 +08:00
imccyu 15c0b6290b docs(notes): state the rejected per-section split without implementation history 2026-07-26 11:18:46 +08:00
imccyu a04ce7afbb refactor(client): shared declaration-aware registration deferral
The five settings-surface registrants carried near-identical
spec-check/ledger-judge/subscribe scaffolding (three jscpd clones);
ui-slots now owns deferRegistration() — ledger-judged presence, refresh
for registrant-localized labels, one-call disposal — and every
registrant shrinks to its registration body.
2026-07-26 04:15:56 +08:00
imccyu c5d323e8e5 fix(gui): follow-ups for the feature-owned settings surfaces
The ui-layout apply bench provides a real LocaleService before the
theme plugin boots (ui-theme now injects slots/locale to register its
Appearance row); drop locale's unused clsx dependency.
2026-07-26 03:22:35 +08:00
imccyu 0c9f310008 test(gui): apply-level suites for the feature-owned settings rows
Locale and ui-theme apply coverage on a real Context + SlotCore:
dictionary assembly, declaration-aware registration both ways,
inject-time getter re-sync, service write-back through the event flow,
HMR collapse recovery, and teardown reclamation. Four settings-surface
packages sit at full per-file coverage.
2026-07-26 02:57:54 +08:00
imccyu a3ee5dd8a0 docs(gui): regenerate graphs and sync the note's English pair
Generated docs follow the ui-models rename and the removed
ui-settings-general package; the English note side picks up the
feature-owner self-registration doctrine.
2026-07-26 02:54:29 +08:00
imccyu 23a60ade67 refactor(gui): features register their own settings surfaces
Settings collaboration direction (recorded in the note): the shell only
provides composition faces — feature plugins register themselves. The
General section moves into the ui-settings shell (order 0, skeleton
rows) and declares the settings.general.item list slot; locale registers
the Language row and ui-theme the Appearance row (each with its own
store mirror, dictionaries, and ledger-judged deferral); the
ui-settings-general package is gone. ui-settings-models becomes
ui-models — a feature package that contributes its Settings section
rather than a settings-owned satellite. The item-slot SlotMap entry is
authored in the ui-settings contract and repeated verbatim in
locale/ui-theme (reference-cycle avoidance; declaration merging keeps
the copies identical).
2026-07-26 02:51:36 +08:00
imccyu b2d8815a34 test(llm-mock-server): poll for the client-closed outcome
The fixed 5ms sleep raced slow CI runners (the server observes the socket
close asynchronously); vi.waitFor polls until the outcome lands.
2026-07-26 02:29:13 +08:00
imccyu 6cc68baddf Merge remote-tracking branch 'origin/master' into worktree-ws-more 2026-07-26 02:26:27 +08:00
imccyu ad419065a0 test(web): stop pre-clicking the fixture group in the title snapshot
The Intent's current-group effect already expands the target workspace;
with intent no longer forcing expansion, the header click collapsed it.
2026-07-26 02:10:59 +08:00
imccyu 4ae86001a5 style(web): wrap a long tree.ts doc line 2026-07-26 02:03:05 +08:00
imccyu d147673dfd refactor(apiproxy): share the workspace-not-found response
The rename/insertSessionBefore lookups tripped the cross-file clone gate;
one helper owns the error row now.
2026-07-26 01:58:53 +08:00
imccyu 9fc8a616a9 test(web): close the per-file coverage gate for the session-list surfaces
New and touched sources reach the CI per-file 100% thresholds: HoverCard
(timers, placement clamp, disabled guard), Menu label/danger/pointer-leave
branches, WorkspaceBrowser (mode switch, search, rail icons, rename dialog,
drag), rows and tree derivations, the workspace fixture stubs, the rename/
insertSessionBefore wire rows, and the entity move semantics. HoverCard's
position state narrows to {left, top} (equivalent refactor, no behavior
change).
2026-07-26 01:48:36 +08:00
imccyu 2ee4cda066 fix(client): lint conformance for the preference services
Replace optional chains on always-present globals with the repo's
typeof guards (store.ts precedent), drop the non-null assertion by
failing loud on an impossible registry miss, and fix two arrow-parens
slips; cover the no-localStorage boot path in both service suites.
2026-07-26 01:30:46 +08:00
imccyu ba5c136871 docs(notes): record the session-list browsing and manual-order decisions 2026-07-26 01:30:14 +08:00
imccyu 8cc46e6025 docs(notes): export settings note contract types
Both sides of the bilingual pair compile in one doc-typecheck program;
module-scoped (exported) declarations keep the shared identifiers from
colliding across the pair.
2026-07-26 01:16:39 +08:00
imccyu f1b877e3c6 fix(web): review-bot round one + regenerate doc catalogs
- rename same-title no-op moves inside the serialized creation chain
- insertSessionBefore maps only the typed WorkspaceMoveInvalidError to
  workspace-move-invalid; storage failures stay internal
- workspace upsert rejects snapshots older than the installed projection
- flat-mode empty state shows when the query hides the intent row
- intent row no longer forces group expansion; header twist stays live
- group-by menu rides a portal; menu clicks stop propagating to the row
- intent row uses the same single-slot indent in both list modes
- regenerate cordis api/catalog + doc graphs
2026-07-26 01:11:17 +08:00
imccyu c5cc348816 test(gui): settings package suites; ledger-judged re-registration
Full per-file coverage for the three settings packages: invariant
companions, store mirroring with revision guards, behavior-shaped
section/shell specs (props-fed, real store engine), and apply-level
suites on a real Context + SlotCore covering declaration-aware deferral
and HMR collapse recovery. All three registrants now judge presence on
the slot ledger instead of a local disposer, which went stale when a
parent redeclaration cascade removed the entry (ds-review-bot finding);
the locale re-register path keeps the same idempotence.
2026-07-26 01:10:23 +08:00
imccyu b1b180e098 fix(gui): CI gate repairs — docs, coverage, HMR re-registration
Regenerate the module-graph/config-catalog/event-graph docs for the
locale rename and new packages; allowlist the three settings READMEs;
complete the RFC code block and add its English pair. Cover the
ThemeService media-query paths (stubbed matchMedia) and mark the
unreachable registry fallback. General section re-registration now
judges presence on the slot ledger instead of a local disposer, which
went stale when an HMR collapse removed the entry.
2026-07-26 00:57:21 +08:00
imccyu ea8b1178cd feat(web): session list one-list, hover card, row menus, rename, manual ordering
Sidebar session list grows the figma 239-10458 feature set and the
workspace/session browsing region moves wholesale into ui-workspace:

- Group-by menu (WorkSpace / In one list): flat mode lists every session
  top-level, strictly newest-first; the choice persists across reloads.
- Session rows get a 500ms hover detail card (title / relative time /
  status line) and a ... menu (Rename / Fork session / Delete session,
  visual-only for now); workspace headers get ... with Rename (wired) and
  Delete workspace (visual-only).
- workspace.rename RPC: trims, rejects duplicate titles on the create
  chain (workspace-name-conflict), no-op on same title; modal dialog with
  client-side duplicate pre-check.
- workspace.insertSessionBefore RPC (DOM-insertBefore semantics, omitted
  anchor appends): HTML5 drag reorder of root sessions inside a workspace
  group; order truth stays host-side, the view refreshes from the
  response/changed frame.
- Activity pinning removed: the session/event touchSession chain is gone;
  workspace accounts are manually owned (new sessions prepend, explicit
  reordering only). Contracts and tests updated, api catalog regenerated.
- ui-sidebar reduced to the column shell (brand, fold state machine, New
  Session, Settings) exposing one sidebar.workspaces hole with a two-fact
  owner share {wide, expandSidebar}; ui-workspace owns the whole region
  (header, search, grouped/flat lists, dialogs, drag) plus the picker via
  a shared WorkspaceCreateFlow. The old sidebar.workspace picker slot and
  its deferral indirection are gone.
- ui-primitives: Menu gains label entries, danger rows, and
  closeOnPointerLeave; new HoverCard (portaled, open-delay, disabled
  guard). Hover card and row menu never coexist.
2026-07-26 00:55:17 +08:00
imccyu 7bcb005f29 Merge branch 'master' into fix-update-builderror 2026-07-26 00:54:08 +08:00
imccyu 6e721b9fdd feat(gui): settings panel with locale and theme preferences
Add the browser Settings surface as slot-composed plugins over new
preference services:

- Rename dsh-client-i18n to dsh-client-locale (locale is the domain
  name); LocaleService adds getLocale()/setLocale(id), immutable
  snapshots, a locale/change event, and dsh.locale persistence.
- ThemeService owns the light/dark/system preference (default system),
  resolves system via prefers-color-scheme, publishes theme/change
  snapshots, persists dsh.theme, and no longer touches the DOM;
  ui-layout's ThemePresenter applies resolved snapshots
  (body[data-ds-dark-theme] + alias tokens) and cleans up on dispose.
- ui-sidebar drops the phase-1 settings dropdown/modal; the foot renders
  the new sidebar.settings slot with the column state.
- New ui-settings shell occupies sidebar.settings: foot trigger row and
  the centered 1080x700 panel (figma 501:29947) with 24% mask, close
  button / mask click / Escape all closing, and a 188px nav projected
  from the settings.section list slot it declares. Nav labels are
  registrant-localized; sections re-register on locale change, so the
  ledger version is the shell's only subscription.
- ui-settings-general registers the General section: Permission and
  Tool Call skeletons, live Language (locale menu) and Appearance
  (Light/Dark/System cubes following the persisted preference); its
  slot store mirrors both service snapshots via apply-side listeners.
- ui-settings-models registers the Models nav entry with an empty
  content column.
- Portaled menus pin z-index above modal overlays (a menu anchored
  inside the settings dialog rendered underneath it and was
  unclickable).
- theme/data/list-pen icons in ui-primitives; settings copy ships as
  zh/en dictionaries; fixture manifests gain the settings rows.
2026-07-26 00:28:43 +08:00
imccyu cf31643480 Merge branch 'master' into fix-update-builderror 2026-07-26 00:06:18 +08:00
imccyu 787b4e6b9e fix(build): derive clean outputs from project graph 2026-07-25 20:30:35 +08:00
imccyu 22875a6c9d fix(build): clean stale workspace residue 2026-07-25 20:06:01 +08:00
imccyu be3a9f6a75 docs: document repository clean workflow 2026-07-25 20:05:29 +08:00
imccyu 1f0d555f60 docs(missions): record workspace GUI closeout lessons 2026-07-25 17:46:05 +08:00