82728808d4
dsh-web-app owns --host/--port/--dev/--workspace-root/--trusted-host and its --help in a web-startup row; the rows it configures wait for the webStartup service, and the client-plugin HMR receiver now ships disabled so --dev is a row toggle rather than a runtime insert (the Loader cannot resolve a row inserted from inside a mounting plugin). dsh-headless owns the task positional and rejects a missing task as its own usage error. Its runner ships disabled, not merely waiting: the schema requires the task, and a row's config is validated when its fiber is created, before the startup row can supply one. A composition has exactly one command-line owner, so the patch disables the web startup row and this one provides webStartup too, leaving the web rows on their composed one-shot values. The keyless web scaffold provides the same three values with no arguments, which is what an embedding host with no command line does.
358 lines
13 KiB
YAML
358 lines
13 KiB
YAML
# The dsh-web-app bundle patch: the browser surface over the dsh-base layer.
|
|
# Applied after dsh-base's insert; rows here override base rows by id, with
|
|
# the profile's own cordis.patch.yml and any --patch overlays still to come.
|
|
#
|
|
# A patch replaces the targeted row's whole `config`, so each row below
|
|
# restates every key it owns.
|
|
#
|
|
# Rows this app configures from flags declare `inject: [webStartup]`: they wait
|
|
# until the web-startup row has parsed --host/--port/--dev/--workspace-root/
|
|
# --trusted-host and provided that service with the resolved values.
|
|
# `dsh --profile web --help` therefore prints this app's own help and exits
|
|
# without ever binding a port.
|
|
|
|
# ── surface-specific values the base deliberately omits ─────────────────────
|
|
|
|
- id: system-prompt
|
|
config:
|
|
persona: >-
|
|
You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.
|
|
|
|
# TODO: Re-enable shared HMR for Web after its reload lifecycle is tested.
|
|
- id: hmr
|
|
disabled: true
|
|
|
|
# Web content search runs on an ephemeral in-memory index. The service
|
|
# activates at boot, while first-search defers the node:sqlite import and
|
|
# in-memory handle so Node 22 startup stays quiet until content search
|
|
# actually uses SQLite. That search then reconciles this boot's sources.
|
|
- id: session-query-sqlite
|
|
config:
|
|
path: ':memory:'
|
|
openAt: first-search
|
|
|
|
- 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
|
|
|
|
# ── web-only host rows, the transport layer, and the browser roster ─────────
|
|
|
|
# `dsh.client` rows are the browser roster the modules node half scans into
|
|
# window.__DSH_BOOT__; the modules row is simultaneously a host row.
|
|
- insert:
|
|
- 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: !!js dshHomePath('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
|
|
|
|
# Resolve bind host, SSH launch, and display once at boot, then mount the
|
|
# matching dual-face directory picker. Mount -native or -browse directly in
|
|
# an overlay to pin the interaction.
|
|
- id: directory-picker
|
|
name: '@deepseek-ai/dsh-host-directory-picker-auto'
|
|
|
|
# The API gateway: the transport-agnostic dispatch face every client shape
|
|
# shares. The base layer's agent-default-model service owns the default model.
|
|
- id: api-gateway
|
|
name: '@deepseek-ai/dsh-host-apiproxy'
|
|
|
|
# Owns the web flag family and its --help; provides webStartup with the
|
|
# values this invocation resolved. Nothing waiting on it starts first.
|
|
- id: web-startup
|
|
name: '@deepseek-ai/dsh-web-app/startup'
|
|
|
|
# ── layer 2: transport/service ──────────────────────────────────────────────
|
|
|
|
# Plain route-registration carrier; host and port arrive as `dsh web`
|
|
# flag patches over these defaults. The dist is served by the web-runtime
|
|
# row below through the fallback seat.
|
|
- id: webserver
|
|
name: '@deepseek-ai/dsh-host-webserver'
|
|
inject: [webStartup]
|
|
config:
|
|
host: 127.0.0.1
|
|
port: 3080
|
|
|
|
# Web glue owned by this bundle: resolves the built frontend dist (an
|
|
# assembly fact of dsh-web-app, never user config), mounts the
|
|
# frontend-static fallback owner, registers the web-surface prompt
|
|
# section and bash runtime variables, and prints the URL line. `dsh web`
|
|
# patches mode/lanAddresses over these defaults. A complete agent-preset
|
|
# persona suppresses the prompt section for that agent while retaining
|
|
# these host-owned shell variables.
|
|
- id: web-runtime
|
|
name: '@deepseek-ai/dsh-web-app'
|
|
inject: [webStartup]
|
|
config:
|
|
mode: production
|
|
printUrl: true
|
|
surfaceContext: true
|
|
|
|
# The client-plugin HMR receiver ships disabled; `--dev` enables it.
|
|
- id: client-hmr
|
|
name: '@deepseek-ai/dsh-client-hmr'
|
|
inject: [webStartup]
|
|
disabled: true
|
|
|
|
# ── browser plugin roster (dshClient rows; node halves are layer-2 hosts) ──
|
|
|
|
# Dual-face: node half scans this very tree for dsh.client rows, composes
|
|
# window.__DSH_BOOT__, serves /plugins/<id>/client.js; browser half is the
|
|
# module table the shell kernel constructs before cordis exists (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'
|
|
inject: [webStartup]
|
|
|
|
- id: api-remotes
|
|
name: '@deepseek-ai/dsh-api-remotes'
|
|
|
|
- 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'
|
|
|
|
# Tool call tree, generic fallback, and keyed business Tool views.
|
|
- id: ui-tool
|
|
name: '@deepseek-ai/dsh-client-ui-tool'
|
|
|
|
# Turn tail: the produced-files row under each closing assistant message.
|
|
# Remove this entry to turn the surface off; the tail hole renders empty.
|
|
- id: ui-deliverables
|
|
name: '@deepseek-ai/dsh-client-ui-deliverables'
|
|
|
|
|
|
- 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'
|
|
|
|
- id: ui-permission
|
|
name: '@deepseek-ai/dsh-client-ui-permission'
|
|
|
|
# The agent-preset row in General settings: the default preset for
|
|
# sessions created later. Absent a roster it renders nothing.
|
|
- id: ui-agent-preset
|
|
name: '@deepseek-ai/dsh-client-ui-agent-preset'
|
|
|
|
# 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'
|
|
|
|
# ── the agent plane moves behind agent presets ─────────────────────────────
|
|
#
|
|
# Every row below composes what ONE agent contributes to the host registries:
|
|
# its tools, its prompt sections, its delegation backends. The base keeps them
|
|
# for the TUI, which is single-session and composes its agent process-wide; the
|
|
# Web surface disables them here and lets each session mount a preset instead.
|
|
#
|
|
# Disabling rather than deleting is deliberate: the base is shared, and a row
|
|
# absent from a surface overlay would silently reappear the day someone reorders
|
|
# the composition.
|
|
|
|
# `bash-env` STAYS in the host plane: `apps/cli/src/web.ts` injects it to
|
|
# publish `DSH_WEB_URL`/`DSH_WEB_MODE`, and a host row that injects a service is
|
|
# the criterion for host-plane ownership — injection resolves before any session
|
|
# exists, so there is no agent to key by. Behind a preset realm those variables
|
|
# would never reach the model's shell at all.
|
|
|
|
- id: tool-bash
|
|
disabled: true
|
|
|
|
# The background-task REGISTRY stays on the host plane; only the model-facing
|
|
# `task_*` controls move. Its producers — `tool-bash` here, `tool-pty` and a
|
|
# non-continuable `tool-subagent` elsewhere — are preset rows that resolve it
|
|
# with `ctx.get`, and an entry-local realm around the registry is invisible to
|
|
# every sibling row outside that realm, so `run_in_background` answered
|
|
# "background tasks unavailable" while the controls sat in the catalog. That is
|
|
# the `goals` criterion read from inside the preset: a Service a row outside its
|
|
# realm READS belongs to the plane both can see. The registry is keyed by owning
|
|
# agent, so one host instance serves every session exactly as before presets.
|
|
|
|
- id: tool-tasks
|
|
disabled: true
|
|
|
|
- id: tool-fs
|
|
disabled: true
|
|
|
|
- id: tool-fs-search
|
|
disabled: true
|
|
|
|
- id: tool-str-replace-editor
|
|
disabled: true
|
|
|
|
# The `skill` REGISTRY stays in the host plane. It is host+per-scope layered
|
|
# (the tools-registry shape): deployment-level providers — repository plugins,
|
|
# a host skill-local row — register into its global layer, while a preset's
|
|
# `skill-local` registers into that preset's layer, and each agent reads the
|
|
# merged catalog its scope chain selects. Only the per-agent rows move behind
|
|
# presets: the base host `skill-local` row is disabled here (presets own local
|
|
# discovery), and `tool-skill` is what a preset mounts to give its agent the
|
|
# catalog and loader at all.
|
|
|
|
- id: skill-local
|
|
disabled: true
|
|
|
|
- id: tool-skill
|
|
disabled: true
|
|
|
|
# The goal SERVICE, its session driver, and the `/goal` command STAY on the
|
|
# host plane; only the model-facing tool moves. The Gateway serves the goal
|
|
# domain as Remote endpoints, and a Remote method picks its receiver Service
|
|
# from a generated descriptor — it resolves `goals` on the host, so a
|
|
# per-session realm would answer `service-unavailable` for every browser call.
|
|
# That is the `bash-env` criterion read from the other side: injection is not
|
|
# the only host relationship a Service can have. The registry is keyed by
|
|
# session, so one host instance serves every session exactly as before presets.
|
|
|
|
- id: tool-goal
|
|
disabled: true
|
|
|
|
- id: plan-mode
|
|
disabled: true
|
|
|
|
- id: token-meter
|
|
disabled: true
|
|
|
|
- id: compact-basic
|
|
disabled: true
|
|
|
|
- id: command-compact
|
|
disabled: true
|
|
|
|
- id: tool-result-prune
|
|
disabled: true
|
|
|
|
# The subagent registry and its backends STAY in the host plane. `subagents` is
|
|
# a process singleton with a cross-session query surface (`listChildren`,
|
|
# `followup`) that the host api-proxy serves to the browser, and a provider
|
|
# registers under a globally unique name, so a per-session copy would both
|
|
# starve that host row and collide on the second session. What a preset
|
|
# chooses is which delegation TOOLS its agent sees, below.
|
|
|
|
- id: tool-subagent-control
|
|
disabled: true
|
|
|
|
- id: tool-subagent-list-agents
|
|
disabled: true
|
|
|
|
- id: tool-subagent
|
|
disabled: true
|
|
|
|
- id: tool-subagent-fork
|
|
disabled: true
|
|
|
|
# `tool-subagent-report` is host-plane for the same reason as the registry, not
|
|
# because a preset may not want it: it registers a CONTINUABLE SETUP on that
|
|
# singleton rather than a tool this agent calls, and the setup list is not
|
|
# scope-aware — one copy per mounted preset means every child gets `report`
|
|
# registered once per live session, which throws on the second.
|
|
|
|
- id: workflow-workerthread
|
|
disabled: true
|
|
|
|
- id: tool-workflow
|
|
disabled: true
|
|
|
|
- id: tool-ralph
|
|
disabled: true
|
|
|
|
- id: workspace-context
|
|
disabled: true
|
|
|
|
- id: tool-todo
|
|
disabled: true
|
|
|
|
- id: tool-web
|
|
disabled: true
|
|
|
|
# The preset roster. `config/agent-presets/` ships with the deployment and is
|
|
# read-only (its entries carry `system` trust);
|
|
# `$DSH_HOME/.agent-presets` is where a person — or an agent — authors their own, and
|
|
# carries the same trust as shell access because a preset IS a composition.
|
|
# `roots` is an assembly fact, not user config: the shipped preset directory
|
|
# ships beside this file, so AppCLIEntry resolves it and patches it in — the
|
|
# same treatment `distIndex` gets on the webserver row.
|
|
- insert:
|
|
- id: agent-presets
|
|
name: '@deepseek-ai/dsh-agent-presets'
|
|
config:
|
|
default: standard
|