Commit Graph

75 Commits

Author SHA1 Message Date
Yichen Jiang
b599d1d0af Merge remote-tracking branch 'origin/master' into worktree/web-multimodal-image-input
# Conflicts:
#	.gitignore
#	apps/cli/package.json
#	apps/cli/src/web.ts
#	docs/architecture.i18n.yaml
#	docs/config-catalog.md
#	docs/module-graph.md
#	packages/client/connection/README.md
#	packages/client/connection/src/client/api.ts
#	packages/client/connection/src/client/fixture.ts
#	packages/client/runtime/README.md
#	packages/client/runtime/src/client/sessions/service.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/runtime/src/client/workspaces/service.ts
#	packages/client/ui-conversation/src/client/apply.ts
#	packages/client/ui-conversation/src/client/chat/MessageItem.tsx
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-conversation/src/client/index.ts
#	packages/client/ui-conversation/src/client/service.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx
#	packages/client/ui-conversation/src/client/skeleton/EmptyHero.tsx
#	packages/client/ui-conversation/src/client/skeleton/EmptyState.tsx
#	packages/client/ui-conversation/src/client/skeleton/InputBar.module.css
#	packages/client/ui-conversation/src/client/skeleton/InputBar.tsx
#	packages/client/ui-conversation/tests/apply-inject.spec.tsx
#	packages/client/ui-conversation/tests/input-bar.spec.tsx
#	packages/client/ui-conversation/tests/skeleton.spec.tsx
#	packages/client/ui-trajectory/tests/views.spec.tsx
#	packages/host/apiproxy/src/api-proxy.ts
#	pnpm-lock.yaml
2026-07-27 12:27:30 +08:00
Tianyi Cui
686cb30f9d fix: restore master's test casts mangled by a stale-types eslint --fix
The interrupted pre-commit hook ran eslint --fix while client lib/types
were stale, which stripped two deliberate 'as' casts from master's
tests; one fails typecheck under exactOptionalPropertyTypes without it.
Restore both files to master's content.
2026-07-27 09:41:23 +08:00
Tianyi Cui
e423bfbee6 Merge remote-tracking branch 'origin/master' into worktree-i18n-update-workflow
# Conflicts:
#	.agents/notes/implemented/process/2026-07-02-bilingual-docs-and-pairing-gate.i18n.yaml
#	.agents/skills/dsh-translate-docs/SKILL.md
#	docs/i18n/README.i18n.yaml
2026-07-27 09:39:54 +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
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
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
Tianyi Cui
426da32217 Merge branch 'code-mode-ui/dispatch-spill' into code-mode-ui/shiki 2026-07-26 21:44:17 +08:00
Tianyi Cui
fc38f8c813 Merge branch 'master' into code-mode-ui/live-parallel 2026-07-26 21:04:03 +08:00
Tianyi Cui
8847fb7bd4 Merge branch 'master' into code-mode-ui/web-ui-v1 2026-07-26 20:51:41 +08:00
Tianyi Cui
df8756ccf5 Merge remote-tracking branch 'origin/master' into worktree/i18n-complete-non-readme
# Conflicts:
#	packages/client/i18n/README.md
#	packages/client/locale/README.i18n.yaml
#	packages/client/locale/README.zh.md
#	packages/client/ui-layout/README.md
#	packages/client/ui-theme/README.md
2026-07-26 14:37:46 +08:00
Tianyi Cui
202ef2fc89 Merge branch 'code-mode-ui/dispatch-spill' into code-mode-ui/shiki 2026-07-26 12:30:26 +08:00
Tianyi Cui
6333b51f2f Merge branch 'code-mode-ui/web-ui-v1' into code-mode-ui/live-parallel 2026-07-26 12:30:03 +08:00
Tianyi Cui
104e83109f fix: address review — plain fences while streaming
ds-review-bot finding: a growing fence retokenized on every chunk
(quadratic main-thread work). MarkdownText gains a streaming flag —
the streaming partial renders fences through the plain arm and the
finalize swap highlights once; AssistantMarkdown threads its existing
flag. (The zh Agent Note pair the review also flagged landed earlier
on this branch.) New spec pins plain-while-streaming and
highlighted-after-finalize.
2026-07-26 10:43:52 +08:00
Tianyi Cui
a786911293 fix: address review — non-vacuous error assertion, package contracts
ds-review-bot findings: the browser e2e's error-state check now requires
at least one error sub-row (was >= 0); the runtime README documents the
codeDispatches snapshot contract and the ui-conversation README the code
variant + nested sub-row semantics.
2026-07-26 10:36:35 +08:00
Tianyi Cui
bb3dc50a4b feat(web): shiki syntax highlighting for code surfaces
One highlighter for the client: a synchronous fine-grained shiki core
(JS regex engine, no WASM) in ui-primitives with an explicit grammar
allowlist (typescript, shellscript, json — aliases resolve, unknown
languages take a geometry-identical plain arm). The shared CodeBlock
component owns both arms; markdown fences, the run_code expanded
program body (typescript), and the details panel Input (json) all
route through it. Token colors live in a new ui-theme shiki.css sheet
as --shiki-* custom properties (light/dark blocks), wired through the
shell's base.css chain — tokens-only styling holds; shiki's generated
span tree is the sanctioned innerHTML path (static output, no user
HTML). jsdom specs pin token spans, aliases, both fallbacks, and the
fence route; the built-bundle snapshot asserts the highlighted program
under the code row.
2026-07-26 09:52:37 +08:00
Tianyi Cui
8a79679489 feat(tools): live dispatch lifecycle + native-contract parallel sub-calls in Code Mode
The bridge replaces its serialization queue with a pool that reuses the
native concurrency contract: submissions classify through
registry.executionMode (fail-closed isConcurrencySafe), start strictly in
submission order, overlap up to the validated maxParallelSubCalls config
(default 10; 1 restores serial), and exclusive calls drain the pool, run
alone, and bar later calls. Each started sub-call logs a
tool/code-dispatch-start event at pool entry; the existing
tool/code-dispatch settles the pair (started ⇔ settles exactly once;
abandoned queued calls log neither). SDK prompt guidance now states the
true Promise.all contract — re-recorded across every code/both-mode
snapshot (plus the stale cordis-dynamic-toolchain fixture gaining the
required description arg).

Client: CodeSubCall widens to RunningToolCall | ToolResultNode — starts
land the running shape (rows wear the native running ring), settles
replace in place preserving start order, callTime pairs to the start
time. Fixture emits start/settle pairs; jsdom pins the running sub-row;
runtime specs pin in-place settlement and out-of-order completion.
2026-07-26 06:02:36 +08:00
Tianyi Cui
226dc7a249 docs: translate remaining READMEs 2026-07-26 05:06:39 +08:00
Tianyi Cui
13f7c62318 feat(web): render Code Mode sub-calls as native rows nested under the run_code row
The client indexes tool/code-dispatch events into
ConversationSnapshot.codeDispatches (parent callId -> ToolResultNode-shaped
sub-calls; live mux and history replay build the identical index). ChatView
renders each run_code parent as the new code variant (description summary,
program as the expanded monospace body) with its sub-dispatches as
always-visible indented rows — every sub-row dispatches through the SAME
keyed conversation.chat.toolview hole with the same GenericToolCard
fallback, so custom registrations (bash sample) take over sub-rows exactly
as top-level rows. The details panel resolves sub-callIds to full logged
args and complete output through the native path.

Evidence: fixture turn 64 + built-bundle jsdom snapshot, real-machinery
jsdom suites (nesting, error state, details, running parent, reference
stability), and a recorded code-mode browser e2e round (keyless replay +
aria golden). Scaffold gains a toolsMode patch knob.
2026-07-26 04:02:38 +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
Yichen Jiang
1a27c0f779 refactor(gui): reuse image serialization 2026-07-25 23:27:34 +08:00
Yichen Jiang
c981f18921 Merge remote-tracking branch 'origin/master' into worktree/web-multimodal-image-input
# Conflicts:
#	apps/cli/README.md
#	apps/cli/src/web.ts
#	apps/web/tests/smoke-fixture.e2e.ts
#	docs/architecture.i18n.yaml
#	docs/module-graph.md
#	examples/acp-agent/tests/snapshots/cordis-inspect-jsdoc/stdout.expected.jsonl
#	packages/client/connection/src/client/api.ts
#	packages/client/connection/src/client/fixture.ts
#	packages/client/runtime/README.md
#	packages/client/runtime/src/client/index.ts
#	packages/client/runtime/src/client/sessions/conversation.ts
#	packages/client/runtime/src/client/sessions/service.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/ui-conversation/src/client/apply.ts
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-conversation/src/client/index.ts
#	packages/client/ui-conversation/src/client/service.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx
#	packages/client/ui-conversation/src/client/skeleton/EmptyState.tsx
#	packages/client/ui-conversation/src/client/skeleton/InputBar.tsx
#	packages/client/ui-conversation/src/client/stores.ts
#	packages/client/ui-conversation/tests/apply-inject.spec.tsx
#	packages/client/ui-conversation/tests/service-orchestration.spec.ts
#	packages/client/ui-conversation/tests/skeleton-branches.spec.tsx
#	packages/client/ui-conversation/tests/skeleton.spec.tsx
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/host/apiproxy/package.json
#	packages/host/apiproxy/src/api-proxy.ts
#	packages/host/apiproxy/src/api/sessions.schema.ts
#	packages/host/runtime/package.json
#	packages/host/runtime/src/boot.ts
#	packages/host/runtime/tests/host-runtime.spec.ts
#	packages/host/runtime/tsconfig.json
#	packages/host/webserver/README.md
#	packages/host/webserver/src/index.ts
#	packages/host/webserver/tests/webserver.spec.ts
#	packages/llm/llm-pi-ai/tests/convert.spec.ts
#	packages/ui/acp/src/codec.ts
#	packages/ui/acp/tests/codec.spec.ts
#	pnpm-lock.yaml
2026-07-25 22:35:22 +08:00
imccyu
468c64a078 fix(web): keep composer add action attachment-only 2026-07-25 17:46:05 +08:00
imccyu
08ce02da2b docs(web): finalize workspace UI product flow 2026-07-25 17:46:04 +08:00
imccyu
9eb9c70a8a feat(web): add workspace-aware session flow 2026-07-25 17:45:26 +08:00
Turtle
fac6c35e9a Trim redundant source comments 2026-07-25 13:02:37 +08:00
creatixchu
f57a4a044a fix(gui): address ds-review-bot findings on image attachments
- dsh web gains --provider/--model: a non-deepseek provider mounts the
  matching pi-ai catalog route (ambient credentials), making image input
  reachable from the shipped Web assembly; requires an explicit --model
- attachment-local syncs the publication directories after the hard-link
  publish so a reported durable reference survives a crash (POSIX; Windows
  relies on filesystem metadata journaling)
- the attachment seam gains storage-free validateImage; the host validates a
  complete multi-image prompt before persisting any member, so one malformed
  image cannot strand valid members as unreferenced objects
- startSession sends before navigating: a rejected first send keeps the empty
  state, its error strip, and the complete draft mounted
- the webserver rejects an undeclared-length body the moment it crosses the
  configured limit instead of draining a potentially endless stream to EOF
2026-07-24 20:55:25 +08:00
creatixchu
d2ad02697e Merge remote-tracking branch 'origin/master' into worktree/web-multimodal-image-input 2026-07-24 20:01:36 +08:00
07akioni
6fc92bbb16 fix: ci 2026-07-24 16:32:35 +08:00
Yichen Jiang
3a92e03b26 Merge remote-tracking branch 'origin/worktree/web-multimodal-image-input' into worktree/web-multimodal-image-input
# Conflicts:
#	apps/web/tests/smoke-fixture.e2e.ts
#	docs/architecture.i18n.yaml
#	packages/client/connection/src/client/fixture.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/ui-conversation/package.json
#	packages/client/ui-conversation/src/client/index.ts
#	packages/client/ui-conversation/tests/apply-inject.spec.tsx
#	packages/client/ui-conversation/tests/service-orchestration.spec.ts
#	packages/host/webserver/tests/webserver.spec.ts
#	pnpm-lock.yaml
2026-07-24 16:31:37 +08:00
Yichen Jiang
6b7984a85e Merge remote-tracking branch 'origin/master' into worktree/web-multimodal-image-input
# Conflicts:
#	apps/cli/src/web.ts
#	apps/web/tests/smoke-fixture.e2e.ts
#	docs/architecture.i18n.yaml
#	packages/client/connection/src/client/fixture.ts
#	packages/client/runtime/src/client/sessions/conversation.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/ui-conversation/package.json
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-conversation/src/client/index.ts
#	packages/client/ui-conversation/src/client/service.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx
#	packages/client/ui-conversation/tests/apply-inject.spec.tsx
#	packages/client/ui-conversation/tests/service-orchestration.spec.ts
#	packages/host/runtime/src/api-proxy.ts
#	packages/host/runtime/src/boot.ts
#	packages/host/webserver/tests/webserver.spec.ts
#	pnpm-lock.yaml
2026-07-24 16:29:03 +08:00
creatixchu
fd657e90ea Merge remote-tracking branch 'origin/master' into worktree/web-multimodal-image-input
# Conflicts:
#	apps/cli/src/web.ts
#	apps/web/tests/smoke-fixture.e2e.ts
#	docs/architecture.i18n.yaml
#	packages/client/connection/src/client/fixture.ts
#	packages/client/runtime/src/client/sessions/conversation.ts
#	packages/client/runtime/src/client/sessions/session.ts
#	packages/client/ui-conversation/package.json
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-conversation/src/client/index.ts
#	packages/client/ui-conversation/src/client/service.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx
#	packages/client/ui-conversation/tests/apply-inject.spec.tsx
#	packages/client/ui-conversation/tests/service-orchestration.spec.ts
#	packages/host/runtime/src/api-proxy.ts
#	packages/host/runtime/src/boot.ts
#	packages/host/webserver/tests/webserver.spec.ts
#	pnpm-lock.yaml
2026-07-24 16:15:53 +08:00
07akioni
6f5321cb37 feat: workspace select menu 2026-07-24 16:09:58 +08:00
07akioni
aeb8b1f486 feat: implement new session behavior to clear selection and show empty state
- Added bilingual notes for the new session feature, detailing the transition to an empty state upon session creation.
- Updated `SessionsService` to include a `clear()` method that resets the current selection and persists the empty state.
- Enhanced the `EmptyState` component to reflect the new design, including workspace selection and input handling.
- Modified CSS styles for improved layout and visual consistency in the empty state.
- Updated tests to cover the new session clearing functionality and its effects on the UI.
2026-07-24 14:09:00 +08:00
07akioni
a4b4a4c53d fix: type check 2026-07-24 13:36:27 +08:00
07akioni
3babb2cd42 feat(trajectory): implement trajectory step cell and layout with bilingual support
- Added TrajectoryCell, TrajectoryGroupHeader, and TrajectoryTurn components for rendering trajectory steps and groups.
- Introduced bilingual support with English and Chinese translations for trajectory notes.
- Updated conversation session models to include timestamps for various message types.
- Enhanced layout logic to handle expanded assistant blocks and tool results with duration metrics.
- Added CSS styles for new components to ensure proper display and alignment.
2026-07-24 13:33:35 +08:00
imccyu
a7699cdeb1 ci: coverage/knip 2026-07-24 02:09:43 +08:00
imccyu
76b25f6c65 pkg: fix dep 2026-07-24 02:09:42 +08:00
imccyu
e903a864f7 fix(gui): reconcile the rebase — ui-question joins the client roster
ui-question landed on master as a full dshClient plugin package (composer
question flow); it enters the flat roster, apps/cli deps/refs, and the
smoke graph. Restore the workspace-context and user-interaction host deps
the conflict resolution had dropped.
2026-07-24 02:09:42 +08:00
imccyu
c2e0c16d6a refactor(gui): one plugin-package shape — dshClient manifests, clientBundle preset, purity gate over all nine
Every client plugin package carries dshClient ({platform, inject,
immediately?}) and emits lib/client.js through the shared clientBundle
preset; exports["./client"] points at the bundle. The infrastructure
tier (connection, runtime, ui-theme, i18n, hmr) declares immediately: true
in its manifest — absent means lazy. The bundle purity gate covers all
nine packages: platform modules stay external, INLINE_SAFE wire layers
inline, any other cross-plugin value import is a build error. Migrations
that rule forced: scopeOf became a SessionsService method and
transportError moved into dsh-host-apiproxy's wire layer; the store
engine stays in runtime under a documented temporary exemption
(TODO(webload/store-rehome)).
2026-07-24 02:09:42 +08:00
Tianyi Cui
404da65595 Merge branch 'master' into worktree/web-session-titles
# Conflicts:
#	apps/web/tests/smoke-real.e2e.ts
#	packages/client/connection/tests/fixture.spec.ts
#	packages/host/runtime/README.md
#	packages/host/runtime/src/api-proxy.ts
2026-07-23 22:00:17 +08:00
Tianyi Cui
ea019beae9 Merge branch 'master' into worktree/web-session-titles 2026-07-23 20:51:17 +08:00
Tianyi Cui
d7c4822f95 Merge origin/master into worktree/web-session-titles
# Conflicts:
#	packages/client/connection/src/client/fixture.ts
2026-07-23 20:12:40 +08:00
imccyu
0f63666522 Merge branch 'worktree/web-carrier-chain' into worktree/web-ask-user-question 2026-07-23 20:09:11 +08:00
Yichen Jiang
0d657f4dfa Merge remote-tracking branch 'origin/master' into worktree/web-multimodal-image-input
# Conflicts:
#	apps/cli/src/web.ts
#	apps/web/tests/smoke-fixture.e2e.ts
#	docs/architecture.i18n.yaml
#	packages/client/connection/src/client/fixture.ts
#	packages/client/ui-conversation/README.md
#	packages/client/ui-conversation/package.json
#	packages/client/ui-conversation/src/client/apply.ts
#	packages/client/ui-conversation/src/client/chat/ChatView.tsx
#	packages/client/ui-conversation/src/client/chat/register.ts
#	packages/client/ui-conversation/src/client/contract/slots.ts
#	packages/client/ui-conversation/src/client/contract/views.ts
#	packages/client/ui-conversation/src/client/service.ts
#	packages/client/ui-conversation/src/client/skeleton/ConversationRoot.tsx
#	packages/client/ui-conversation/src/client/stores.ts
#	packages/client/ui-conversation/tests/skeleton-branches.spec.tsx
#	packages/cordis/tool-cordis/src/api-catalog.ts
#	packages/host/runtime/src/boot.ts
#	packages/host/runtime/tests/host-runtime.spec.ts
#	pnpm-lock.yaml
2026-07-23 19:51:50 +08:00
imccyu
3f6158f2c6 Merge branch 'master' into worktree/web-carrier-chain 2026-07-23 19:46:13 +08:00
Yichen Jiang
580e05b794 fix(gui): harden multimodal image attachments 2026-07-23 19:38:37 +08:00