`dsh` shipped two config trees that were 43 rows the same: apps/cli/cordis.yml composed web as 74 flat rows, while the TUI booted examples/tui-agent/cordis.yml whose single `@deepseek-ai/dsh-tui-demo` row mounted twelve plugins behind a twenty-key pass-through Config. Neither file was what its location claimed — apps/cli hardcoded the "example" as the product default and the "demo" bundle was the application — and every capability change had to be made twice. - apps/cli/base.cordis.yml holds the 43 shared rows; tui.cordis.yml and web.cordis.yml are patch lists stating only what differs per surface - overlays apply as SIBLING patch lists at one include level, because include patches never cross an include boundary. Precedence: base < surface < (--config | personal ~/.dsh/config.yaml) < launcher flag/profile patches - `--config` now applies an overlay INSTEAD OF the personal one, so a demo or test tree never inherits the user's route; new `--config-replace` boots a file as the entire tree (the old `--config` behaviour). Both survive /resume - vendor/include: index each `insert`ed row as it is added so a later patch can configure or disable it. Upstream built the id index once before the patch loop, leaving every surface-only row — the whole TUI front door — silently unpatchable from user config. Logged as local modification 8 - session identity moves to dsh-agent-loop's CONFIGURED_AGENT_IDENTITIES_KEY; dsh-tui's MAIN_SESSION_ID_KEY is deleted (only the bundle read it) - delete examples/tui-agent, examples/cordis-agent, packages/examples/tui-demo; TUI tests → apps/cli/tests, cordis e2e → packages/cordis/tool-cordis/tests, examples/code-mode survives as an overlay leaf - `dsh web` gains --config, threaded into AppCLIEntry as an extra overlay Three latent defects surfaced and are fixed here: the TUI captured the optional sessionQuery service once at construction and could permanently disable /resume when it won the mount race; the session-store root silently reverted to a project-local ./.sessions; --config-replace was dropped by the resume handoff. Verified by booting each tree through the real Loader (TUI 55 entries, web 75, zero unsettled) rather than reading YAML. All eight terminal snapshots replay byte-identically; 14/14 PTY smoke, 112/112 snapshots, 25/25 doc-sync, hygiene and lint clean.
168 lines
5.5 KiB
YAML
168 lines
5.5 KiB
YAML
# `dsh web` — the browser surface, as a patch list over `base.cordis.yml`.
|
|
# The launcher includes the base and applies this file, then any `--config`
|
|
# overlay, then AppCLIEntry's profile-json and CLI-flag patches, as sibling patch
|
|
# lists at ONE include level: patches never cross an include boundary, so
|
|
# stacking overlays as nested includes would silently stop reaching base rows.
|
|
#
|
|
# A patch replaces the targeted row's whole `config`, so each row below restates
|
|
# every key it owns. `--dev` appends the dsh-client-hmr row in code
|
|
# (AppCLIEntry) — prod and dev differ by exactly that one row.
|
|
|
|
# ── surface-specific values the base deliberately omits ─────────────────────
|
|
|
|
- id: system-prompt
|
|
config:
|
|
persona: ''
|
|
|
|
- id: tools
|
|
config:
|
|
# TEMPORARY workaround: DSH_TOOLS_MODE (native|code|both) opts a whole dsh
|
|
# process into Code Mode while per-session tool-mode selection is being
|
|
# designed; unset keeps the schema default (native). Remove the env seam
|
|
# once the web UI owns the choice per session.
|
|
mode: !!js process.env.DSH_TOOLS_MODE
|
|
|
|
- id: agent-loop
|
|
config:
|
|
agents: []
|
|
|
|
- id: llm-deepseek
|
|
config:
|
|
apiKey: !!js process.env.DEEPSEEK_API_KEY
|
|
baseURL: !!js process.env.DEEPSEEK_BASE_URL
|
|
|
|
- id: fs-local
|
|
|
|
# ── web-only host rows, the transport layer, and the browser roster ─────────
|
|
|
|
# `dshClient` rows are the browser roster the modules node half scans into
|
|
# window.__DSH_BOOT__; the modules row is simultaneously a host row.
|
|
- insert:
|
|
- id: session-projection
|
|
name: '@deepseek-ai/dsh-session-projection'
|
|
|
|
- id: code-runtime
|
|
name: '@deepseek-ai/dsh-code-runtime-worker'
|
|
|
|
- id: storage
|
|
name: '@deepseek-ai/dsh-storage'
|
|
|
|
- id: storage-json
|
|
name: '@deepseek-ai/dsh-storage-json'
|
|
config:
|
|
root: './.storages'
|
|
|
|
- id: storage-domain
|
|
name: '@deepseek-ai/dsh-storage-domain'
|
|
config:
|
|
backend: json
|
|
|
|
- id: workspace
|
|
name: '@deepseek-ai/dsh-workspace'
|
|
|
|
- id: session-projection-cache
|
|
name: '@deepseek-ai/dsh-session-projection-cache'
|
|
config:
|
|
writeEveryEvents: 200
|
|
writeIntervalMs: 5000
|
|
|
|
- id: tool-todo
|
|
name: '@deepseek-ai/dsh-tool-todo'
|
|
|
|
# The API gateway: the transport-agnostic dispatch face every client shape
|
|
# shares. provider/model are the host default routing — the profile json's
|
|
# mapping target (user config overrides these engineering defaults).
|
|
- id: api-gateway
|
|
name: '@deepseek-ai/dsh-host-apiproxy'
|
|
config:
|
|
provider: deepseek
|
|
model: deepseek-v4-flash
|
|
|
|
# ── layer 2: transport/service ──────────────────────────────────────────────
|
|
|
|
# Plain route-registration carrier. distIndex is an assembly fact, not user
|
|
# config — AppCLIEntry resolves the frontend dist and patches it in; host and
|
|
# port arrive as CLI-flag patches over these defaults.
|
|
- id: webserver
|
|
name: '@deepseek-ai/dsh-host-webserver'
|
|
config:
|
|
host: 127.0.0.1
|
|
port: 3080
|
|
|
|
# ── browser plugin roster (dshClient rows; node halves are layer-2 hosts) ──
|
|
|
|
# Dual-face: node half scans this very tree for dshClient rows, composes
|
|
# window.__DSH_BOOT__, serves /plugins/<id>/client.js; browser half is the
|
|
# module table the shell kernel constructs before cordis exists (§4.7 —
|
|
# adopted as a plugin entry by the kernel, never fetched).
|
|
- id: modules
|
|
name: '@deepseek-ai/dsh-client-modules'
|
|
|
|
# Owns both ends of the web transport: node half binds the gateway to the
|
|
# webserver under /api; browser half is the fetch/SSE client.
|
|
- id: connection
|
|
name: '@deepseek-ai/dsh-client-connection'
|
|
|
|
- id: client-runtime
|
|
name: '@deepseek-ai/dsh-client-runtime'
|
|
|
|
- id: ui-theme
|
|
name: '@deepseek-ai/dsh-client-ui-theme'
|
|
|
|
- id: locale
|
|
name: '@deepseek-ai/dsh-client-locale'
|
|
|
|
- id: ui-layout
|
|
name: '@deepseek-ai/dsh-client-ui-layout'
|
|
|
|
- id: ui-sidebar
|
|
name: '@deepseek-ai/dsh-client-ui-sidebar'
|
|
|
|
- id: ui-settings
|
|
name: '@deepseek-ai/dsh-client-ui-settings'
|
|
|
|
- id: ui-settings-general
|
|
name: '@deepseek-ai/dsh-client-ui-settings-general'
|
|
|
|
- id: ui-models
|
|
name: '@deepseek-ai/dsh-client-ui-models'
|
|
|
|
- id: ui-conversation
|
|
name: '@deepseek-ai/dsh-client-ui-conversation'
|
|
|
|
|
|
- id: ui-workspace
|
|
name: '@deepseek-ai/dsh-client-ui-workspace'
|
|
|
|
# Input triggers: the '/' | '@' pipeline (ui-slash), the command surface over
|
|
# it (ui-command), and the two reference sources (ui-skill / ui-subagent).
|
|
- id: ui-slash
|
|
name: '@deepseek-ai/dsh-client-ui-slash'
|
|
|
|
- id: ui-command
|
|
name: '@deepseek-ai/dsh-client-ui-command'
|
|
|
|
- id: ui-skill
|
|
name: '@deepseek-ai/dsh-client-ui-skill'
|
|
|
|
- id: ui-subagent
|
|
name: '@deepseek-ai/dsh-client-ui-subagent'
|
|
|
|
# Goal surface: GoalBar in the input dock over the goal session projection.
|
|
- id: ui-goal
|
|
name: '@deepseek-ai/dsh-client-ui-goal'
|
|
|
|
# Model selection: the /model popupSelect + composer seat over session.models.
|
|
- id: ui-model
|
|
name: '@deepseek-ai/dsh-client-ui-model'
|
|
|
|
# Plan control: the composer plan seat over the plan projection + /plan channel.
|
|
- id: ui-plan
|
|
name: '@deepseek-ai/dsh-client-ui-plan'
|
|
|
|
- id: ui-question
|
|
name: '@deepseek-ai/dsh-client-ui-question'
|
|
|
|
- id: ui-trajectory
|
|
name: '@deepseek-ai/dsh-client-ui-trajectory'
|