| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- # 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.
- #
- # The web-startup plugin injects `cmdlineArgs` and provides `webStartup` as an
- # ordinary Cordis service. Rows configured from flags inject that service, so
- # Loader resolves their expressions only after it exists. The web runtime then
- # provides bind-dependent `webRuntime` values to the trust fence.
- # `dsh --profile web --help` provides neither service, so no server binds.
- # ── 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}}.
- # Full-text session search is opt-in (the base row's `openAt: never`). This
- # restatement keeps the Web values on one ephemeral in-memory index; a
- # deployment enabling content search overrides `openAt` to `first-search` in a
- # later patch layer, which defers the node:sqlite import and in-memory handle
- # to the first search so Node 22 startup stays quiet.
- - id: session-query-sqlite
- config:
- path: ':memory:'
- openAt: never
- - id: tools
- config:
- # TEMPORARY workaround: DSH_TOOLS_MODE (native|ptc|both) opts a whole dsh
- # process into PTC mode while per-session tool-presentation 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:
- # Host-owned opt-in sampled when a new Web session receives its preset
- # delegation tools. The Plugins page edits this settings namespace.
- - id: subagent-model-selection-settings
- name: '@deepseek-ai/dsh-tool-subagent/model-selection-settings'
- - id: code-runtime
- name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- - id: message-feedback
- name: '@deepseek-ai/dsh-message-feedback'
- config:
- maxNoteBytes: 8192
- # Browser Session export: `/export` command plus the shared download dialog.
- - id: session-log-download
- name: '@deepseek-ai/dsh-session-log-export'
- - id: workspace
- name: '@deepseek-ai/dsh-workspace'
- - id: session-reference
- name: '@deepseek-ai/dsh-session-reference'
- - id: file-reference-local
- name: '@deepseek-ai/dsh-file-reference-local'
- # Whole-log turn/step counts for the chat stats strip (the sessionStats
- # projection key); the projection registry itself is a base-layer row.
- - id: session-stats
- name: '@deepseek-ai/dsh-session-stats'
- # Whole-log turn outline for the chat turn rail (the turnOutline
- # projection key): every turn stays navigable before its events page in.
- - id: session-turn-outline
- name: '@deepseek-ai/dsh-session-turn-outline'
- # 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'
- # Read-only projection of current Loader entries for trusted client RPCs.
- - id: plugin-inventory
- name: '@deepseek-ai/dsh-host-plugin-inventory'
- # Session commands, cold reads, and live control over Typert Remote.
- - id: session-controller
- name: '@deepseek-ai/dsh-api-session-controller'
- # Configuration-surface reads and writes over Typert Remote. Each method
- # reports an actionable error when its settings-domain provider is absent.
- - id: settings-controller
- name: '@deepseek-ai/dsh-api-settings-controller'
- # Workspace commands and reconnect-safe projection over Typert Remote.
- - id: workspace-controller
- name: '@deepseek-ai/dsh-api-workspace-controller'
- - id: cordis-host-runner
- name: '@deepseek-ai/dsh-cordis-host-runner'
- # Ordinary provider for the parsed Web flags. Its plugin-level injection
- # waits for cmdlineArgs; no launcher metadata or special row kind is needed.
- - id: web-startup
- name: '@deepseek-ai/dsh-web-app/startup'
- # ── layer 2: transport/service ──────────────────────────────────────────────
- # Plain route-registration carrier; host and port come from the app's
- # webStartup provider, with these deployment fallbacks. 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: !!js ctx.webStartup.host ?? '127.0.0.1'
- port: !!js ctx.webStartup.port ?? 3080
- compression: gzip
- compressionLevel: 1
- compressionThresholdBytes: 1024
- # 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 the bash runtime variable, prints the URL line, and opens the
- # canonical local URL after the full tree settles. The webStartup provider
- # supplies invocation-only values; after the server binds, this row samples
- # LAN trust once and provides `webRuntime`. A complete agent-preset persona
- # suppresses the prompt section for that agent while retaining the host-owned
- # shell variable.
- - id: web-runtime
- name: '@deepseek-ai/dsh-web-app'
- inject: [webStartup]
- config:
- openBrowser: !!js ctx.webStartup.openBrowser
- printUrl: true
- surfaceContext: true
- trustedHosts: !!js ctx.webStartup.trustedHosts
- # The client-plugin reload chain, always mounted: it is idle until a
- # rebuild watcher (pnpm run dev:web) actually rewrites client bundles. It
- # is a row rather than a child of web-runtime because its node half is a
- # client-side package, which a host-side bundle cannot import.
- - id: client-hmr
- name: '@deepseek-ai/dsh-client-hmr'
- # ── browser plugin roster (dsh.client rows; node halves are layer-2 hosts) ──
- # Dual-face: the node half scans this tree, composes window.__DSH_BOOT__,
- # and serves /plugins/<id>/client.js; the 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: [webRuntime]
- config:
- # LAN literals derived from the active bind plus --trusted-host extras.
- # A deployment adding authorities keeps this expression and concatenates
- # its literals, for example: ['app.internal', ...ctx.webRuntime.trustedHosts].
- trustedHosts: !!js ctx.webRuntime.trustedHosts
- # Raw Blob and ReadableStream uploads run independently of Connection's
- # RPC and generation service.
- - id: file-upload
- name: '@deepseek-ai/dsh-client-file-upload'
- - id: api-remotes
- name: '@deepseek-ai/dsh-api-remotes'
- - id: cordis-client-runner
- name: '@deepseek-ai/dsh-cordis-client-runner'
- - 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-renderer
- name: '@deepseek-ai/dsh-client-ui-renderer'
- - id: ui-session
- name: '@deepseek-ai/dsh-client-ui-session'
- - 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-settings-models
- name: '@deepseek-ai/dsh-client-ui-settings-models'
- - id: ui-settings-plugin-inventory
- name: '@deepseek-ai/dsh-client-ui-settings-plugin-inventory'
- - id: ui-conversation
- name: '@deepseek-ai/dsh-client-ui-conversation'
- - id: ui-approval
- name: '@deepseek-ai/dsh-client-ui-approval'
- - id: ui-chat
- name: '@deepseek-ai/dsh-client-ui-chat'
- # Official occupants for the generic sidebar and conversation brand slots.
- - id: ui-brand-official
- name: '@deepseek-ai/dsh-client-ui-brand-official'
- - id: ui-attachment
- name: '@deepseek-ai/dsh-client-ui-attachment'
- # Tool call tree, generic fallback, and keyed business Tool views.
- - id: ui-tool
- name: '@deepseek-ai/dsh-client-ui-tool'
- - id: ui-cordis
- name: '@deepseek-ai/dsh-client-ui-cordis'
- # Durable workflow lifecycle as an independent Chat node after the
- # existing generic workflow tool row.
- - id: ui-workflow-run
- name: '@deepseek-ai/dsh-client-ui-workflow-run'
- # 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-input-trigger), the command surface over
- # it (ui-commands), and the reference sources (ui-skill / ui-reference).
- - id: ui-input-trigger
- name: '@deepseek-ai/dsh-client-ui-input-trigger'
- - id: ui-commands
- name: '@deepseek-ai/dsh-client-ui-commands'
- - id: ui-skill
- name: '@deepseek-ai/dsh-client-ui-skill'
- - id: ui-subagent
- name: '@deepseek-ai/dsh-client-ui-subagent'
- - id: ui-reference
- name: '@deepseek-ai/dsh-client-ui-reference'
- # Read-only active Schedule catalog. The shipped Web graph resolves the
- # client package but leaves it disabled; the explicit Schedule overlay
- # enables this same row together with the host Schedule services.
- - id: ui-schedule
- name: '@deepseek-ai/dsh-client-ui-schedule'
- disabled: true
- # Background jobs: the session-header list over the jobsBySession mirror.
- - id: ui-jobs
- name: '@deepseek-ai/dsh-client-ui-jobs'
- # Goal surface: GoalBar in the input dock over the goal session projection.
- - id: ui-goal
- name: '@deepseek-ai/dsh-client-ui-goal'
- # Per-message feedback: Like/Dislike plus an optional note in the
- # assistant-message action strip, over the messageFeedback Remote.
- - id: ui-message-feedback
- name: '@deepseek-ai/dsh-client-ui-message-feedback'
- # Model selection: the /model popupSelect + composer seat over session.models.
- - id: ui-model-selection
- name: '@deepseek-ai/dsh-client-ui-model-selection'
- - id: ui-permission
- name: '@deepseek-ai/dsh-client-ui-permission-presets'
- # 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'
- # Plugin configuration: the host-plane sections a user owns, as expandable
- # cards. A namespace this deployment does not expose renders nothing.
- - id: ui-settings-plugins
- name: '@deepseek-ai/dsh-client-ui-settings-plugins'
- # Plan control: the composer plan seat over the plan projection + /plan channel.
- - id: ui-plan
- name: '@deepseek-ai/dsh-client-ui-plan'
- - id: ui-user-questions
- name: '@deepseek-ai/dsh-client-ui-user-questions'
- - 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.
- # `shell-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
- - id: tool-pwsh
- disabled: true
- # The background-job REGISTRY stays on the host plane; only the model-facing
- # `job_*` controls move. Its producers — `tool-bash` here, `tool-terminal` 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 jobs 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-jobs
- 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-filesystem row — register into its global layer, while a preset's
- # `skill-filesystem` 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-filesystem` 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-filesystem
- disabled: true
- - id: tool-skill
- disabled: true
- # The goal service and session driver stay on the host plane, where Gateway
- # remotes resolve them. Presets own the human command and model-facing tool.
- - id: command-goal
- disabled: true
- - id: tool-goal
- disabled: true
- - id: plan-mode
- disabled: true
- # The token METER stays on the host plane; only the compaction backend that
- # reads it moves. It owns the context-meter projection units, and that table is
- # process-wide, so preset ownership would make the meter a function of which
- # presets happen to be mounted rather than a per-session fact. Same criterion as
- # `tasks` and `goals`; the reasoning has one home in
- # `.agents/notes/implemented/architecture/2026-08-10-host-plane-ownership-after-presets.md`.
- - id: compaction-basic
- disabled: true
- - id: command-compact
- disabled: true
- - id: tool-result-pruner
- 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
- - id: workflow-worker-thread
- disabled: true
- - id: tool-workflow
- disabled: true
- - id: tool-ralph
- disabled: true
- - id: agent-instructions
- disabled: true
- - id: tool-todo
- disabled: true
- - id: tool-web
- disabled: true
- # The preset roster. The shipped presets are bundled inside
- # `dsh-agent-presets` itself and prepended as a read-only `system` root
- # (`includeShippedRoot`); `$DSH_HOME/.agent-presets` is where a person — or an
- # agent — authors their own, appended by the same package (`includeUserRoot`),
- # and carries the same trust as shell access because a preset IS a
- # composition. This row only names the default and any deployment-added
- # `roots`; no launcher patching is involved.
- - insert:
- - id: agent-presets
- name: '@deepseek-ai/dsh-agent-presets'
- config:
- default: standard
|