cordis.patch.yml 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. # The dsh-web-app bundle patch: the browser surface over the dsh-base layer.
  2. # Applied after dsh-base's insert; rows here override base rows by id, with
  3. # the profile's own cordis.patch.yml and any --patch overlays still to come.
  4. #
  5. # A patch replaces the targeted row's whole `config`, so each row below
  6. # restates every key it owns.
  7. #
  8. # The web-startup plugin injects `cmdlineArgs` and provides `webStartup` as an
  9. # ordinary Cordis service. Rows configured from flags inject that service, so
  10. # Loader resolves their expressions only after it exists. The web runtime then
  11. # provides bind-dependent `webRuntime` values to the trust fence.
  12. # `dsh --profile web --help` provides neither service, so no server binds.
  13. # ── surface-specific values the base deliberately omits ─────────────────────
  14. - id: system-prompt
  15. config:
  16. persona: >-
  17. You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.
  18. # TODO: Re-enable shared HMR for Web after its reload lifecycle is tested.
  19. - id: hmr
  20. disabled: true
  21. # Full-text session search is opt-in (the base row's `openAt: never`). This
  22. # restatement keeps the Web values on one ephemeral in-memory index; a
  23. # deployment enabling content search overrides `openAt` to `first-search` in a
  24. # later patch layer, which defers the node:sqlite import and in-memory handle
  25. # to the first search so Node 22 startup stays quiet.
  26. - id: session-query-sqlite
  27. config:
  28. path: ':memory:'
  29. openAt: never
  30. - id: tools
  31. config:
  32. # TEMPORARY workaround: DSH_TOOLS_MODE (native|code|both) opts a whole dsh
  33. # process into Code Mode while per-session tool-presentation selection is being
  34. # designed; unset keeps the schema default (native). Remove the env seam
  35. # once the web UI owns the choice per session.
  36. mode: !!js process.env.DSH_TOOLS_MODE
  37. # ── web-only host rows, the transport layer, and the browser roster ─────────
  38. # `dsh.client` rows are the browser roster the modules node half scans into
  39. # window.__DSH_BOOT__; the modules row is simultaneously a host row.
  40. - insert:
  41. - id: code-runtime
  42. name: '@deepseek-ai/dsh-code-runtime-worker-thread'
  43. - id: message-feedback
  44. name: '@deepseek-ai/dsh-message-feedback'
  45. config:
  46. maxNoteBytes: 8192
  47. # Browser Session export: `/export` command plus the shared download dialog.
  48. - id: session-log-download
  49. name: '@deepseek-ai/dsh-session-log-export'
  50. - id: workspace
  51. name: '@deepseek-ai/dsh-workspace'
  52. # Whole-log turn/step counts for the chat stats strip (the sessionStats
  53. # projection key); the projection registry itself is a base-layer row.
  54. - id: session-stats
  55. name: '@deepseek-ai/dsh-session-stats'
  56. # Resolve bind host, SSH launch, and display once at boot, then mount the
  57. # matching dual-face directory picker. Mount -native or -browse directly in
  58. # an overlay to pin the interaction.
  59. - id: directory-picker
  60. name: '@deepseek-ai/dsh-host-directory-picker-auto'
  61. # Read-only projection of current Loader entries for trusted client RPCs.
  62. - id: plugin-inventory
  63. name: '@deepseek-ai/dsh-host-plugin-inventory'
  64. # The API gateway: the transport-agnostic dispatch face every client shape
  65. # shares. The base layer's agent-default-model service owns the default model.
  66. - id: api-gateway
  67. name: '@deepseek-ai/dsh-host-apiproxy'
  68. - id: cordis-host-runner
  69. name: '@deepseek-ai/dsh-cordis-host-runner'
  70. # Ordinary provider for the parsed Web flags. Its plugin-level injection
  71. # waits for cmdlineArgs; no launcher metadata or special row kind is needed.
  72. - id: web-startup
  73. name: '@deepseek-ai/dsh-web-app/startup'
  74. # ── layer 2: transport/service ──────────────────────────────────────────────
  75. # Plain route-registration carrier; host and port come from the app's
  76. # webStartup provider, with these deployment fallbacks. The dist is served by
  77. # the web-runtime row below through the fallback seat.
  78. - id: webserver
  79. name: '@deepseek-ai/dsh-host-webserver'
  80. inject: [webStartup]
  81. config:
  82. host: !!js ctx.webStartup.host ?? '127.0.0.1'
  83. port: !!js ctx.webStartup.port ?? 3080
  84. # Web glue owned by this bundle: resolves the built frontend dist (an
  85. # assembly fact of dsh-web-app, never user config), mounts the
  86. # frontend-static fallback owner, registers the web-surface prompt
  87. # section and the bash runtime variable, and prints the URL line. The
  88. # webStartup provider supplies invocation-only values; after the server
  89. # binds, this row samples LAN trust once and provides `webRuntime`. A
  90. # complete agent-preset persona suppresses the prompt section for that
  91. # agent while retaining the host-owned shell variable.
  92. - id: web-runtime
  93. name: '@deepseek-ai/dsh-web-app'
  94. inject: [webStartup]
  95. config:
  96. printUrl: true
  97. surfaceContext: true
  98. trustedHosts: !!js ctx.webStartup.trustedHosts
  99. # The client-plugin reload chain, always mounted: it is idle until a
  100. # rebuild watcher (pnpm run dev:web) actually rewrites client bundles. It
  101. # is a row rather than a child of web-runtime because its node half is a
  102. # client-side package, which a host-side bundle cannot import.
  103. - id: client-hmr
  104. name: '@deepseek-ai/dsh-client-hmr'
  105. # ── browser plugin roster (dsh.client rows; node halves are layer-2 hosts) ──
  106. # Dual-face: the node half scans this tree, composes window.__DSH_BOOT__,
  107. # and serves /plugins/<id>/client.js; the browser half is the module table
  108. # the shell kernel constructs before cordis exists (adopted as a plugin
  109. # entry by the kernel, never fetched).
  110. - id: modules
  111. name: '@deepseek-ai/dsh-client-modules'
  112. # Owns both ends of the web transport: node half binds the gateway to the
  113. # webserver under /api; browser half is the fetch/SSE client.
  114. - id: connection
  115. name: '@deepseek-ai/dsh-client-connection'
  116. inject: [webRuntime]
  117. config:
  118. # LAN literals derived from the active bind plus --trusted-host extras.
  119. # A deployment adding authorities keeps this expression and concatenates
  120. # its literals, for example: ['app.internal', ...ctx.webRuntime.trustedHosts].
  121. trustedHosts: !!js ctx.webRuntime.trustedHosts
  122. - id: api-remotes
  123. name: '@deepseek-ai/dsh-api-remotes'
  124. - id: client-runtime
  125. name: '@deepseek-ai/dsh-client-runtime'
  126. - id: cordis-client-runner
  127. name: '@deepseek-ai/dsh-cordis-client-runner'
  128. - id: ui-theme
  129. name: '@deepseek-ai/dsh-client-ui-theme'
  130. - id: locale
  131. name: '@deepseek-ai/dsh-client-locale'
  132. - id: ui-layout
  133. name: '@deepseek-ai/dsh-client-ui-layout'
  134. - id: ui-renderer
  135. name: '@deepseek-ai/dsh-client-ui-renderer'
  136. - id: ui-sidebar
  137. name: '@deepseek-ai/dsh-client-ui-sidebar'
  138. - id: ui-settings
  139. name: '@deepseek-ai/dsh-client-ui-settings'
  140. - id: ui-settings-general
  141. name: '@deepseek-ai/dsh-client-ui-settings-general'
  142. - id: ui-settings-models
  143. name: '@deepseek-ai/dsh-client-ui-settings-models'
  144. - id: ui-settings-plugin-inventory
  145. name: '@deepseek-ai/dsh-client-ui-settings-plugin-inventory'
  146. - id: ui-conversation
  147. name: '@deepseek-ai/dsh-client-ui-conversation'
  148. - id: ui-attachment
  149. name: '@deepseek-ai/dsh-client-ui-attachment'
  150. # Tool call tree, generic fallback, and keyed business Tool views.
  151. - id: ui-tool
  152. name: '@deepseek-ai/dsh-client-ui-tool'
  153. - id: ui-cordis
  154. name: '@deepseek-ai/dsh-client-ui-cordis'
  155. # Durable workflow lifecycle as an independent Chat node after the
  156. # existing generic workflow tool row.
  157. - id: ui-workflow-run
  158. name: '@deepseek-ai/dsh-client-ui-workflow-run'
  159. # Turn tail: the produced-files row under each closing assistant message.
  160. # Remove this entry to turn the surface off; the tail hole renders empty.
  161. - id: ui-deliverables
  162. name: '@deepseek-ai/dsh-client-ui-deliverables'
  163. - id: ui-workspace
  164. name: '@deepseek-ai/dsh-client-ui-workspace'
  165. # Input triggers: the '/' | '@' pipeline (ui-input-trigger), the command surface over
  166. # it (ui-commands), and the two reference sources (ui-skill / ui-subagent).
  167. - id: ui-input-trigger
  168. name: '@deepseek-ai/dsh-client-ui-input-trigger'
  169. - id: ui-commands
  170. name: '@deepseek-ai/dsh-client-ui-commands'
  171. - id: ui-skill
  172. name: '@deepseek-ai/dsh-client-ui-skill'
  173. - id: ui-subagent
  174. name: '@deepseek-ai/dsh-client-ui-subagent'
  175. # Background jobs: the session-header list over the jobsBySession mirror.
  176. - id: ui-jobs
  177. name: '@deepseek-ai/dsh-client-ui-jobs'
  178. # Goal surface: GoalBar in the input dock over the goal session projection.
  179. - id: ui-goal
  180. name: '@deepseek-ai/dsh-client-ui-goal'
  181. # Per-message feedback: Like/Dislike plus an optional note in the
  182. # assistant-message action strip, over the messageFeedback Remote.
  183. - id: ui-message-feedback
  184. name: '@deepseek-ai/dsh-client-ui-message-feedback'
  185. # Model selection: the /model popupSelect + composer seat over session.models.
  186. - id: ui-model-selection
  187. name: '@deepseek-ai/dsh-client-ui-model-selection'
  188. - id: ui-permission
  189. name: '@deepseek-ai/dsh-client-ui-permission-presets'
  190. # The agent-preset row in General settings: the default preset for
  191. # sessions created later. Absent a roster it renders nothing.
  192. - id: ui-agent-preset
  193. name: '@deepseek-ai/dsh-client-ui-agent-preset'
  194. # Plugin configuration: the host-plane sections a user owns, as expandable
  195. # cards. A namespace this deployment does not expose renders nothing.
  196. - id: ui-settings-plugins
  197. name: '@deepseek-ai/dsh-client-ui-settings-plugins'
  198. # Plan control: the composer plan seat over the plan projection + /plan channel.
  199. - id: ui-plan
  200. name: '@deepseek-ai/dsh-client-ui-plan'
  201. - id: ui-user-questions
  202. name: '@deepseek-ai/dsh-client-ui-user-questions'
  203. - id: ui-trajectory
  204. name: '@deepseek-ai/dsh-client-ui-trajectory'
  205. # ── the agent plane moves behind agent presets ─────────────────────────────
  206. #
  207. # Every row below composes what ONE agent contributes to the host registries:
  208. # its tools, its prompt sections, its delegation backends. The base keeps them
  209. # for the TUI, which is single-session and composes its agent process-wide; the
  210. # Web surface disables them here and lets each session mount a preset instead.
  211. #
  212. # Disabling rather than deleting is deliberate: the base is shared, and a row
  213. # absent from a surface overlay would silently reappear the day someone reorders
  214. # the composition.
  215. # `shell-env` STAYS in the host plane: `apps/cli/src/web.ts` injects it to
  216. # publish `DSH_WEB_URL`/`DSH_WEB_MODE`, and a host row that injects a service is
  217. # the criterion for host-plane ownership — injection resolves before any session
  218. # exists, so there is no agent to key by. Behind a preset realm those variables
  219. # would never reach the model's shell at all.
  220. - id: tool-bash
  221. disabled: true
  222. - id: tool-pwsh
  223. disabled: true
  224. # The background-job REGISTRY stays on the host plane; only the model-facing
  225. # `job_*` controls move. Its producers — `tool-bash` here, `tool-terminal` and a
  226. # non-continuable `tool-subagent` elsewhere — are preset rows that resolve it
  227. # with `ctx.get`, and an entry-local realm around the registry is invisible to
  228. # every sibling row outside that realm, so `run_in_background` answered
  229. # "background jobs unavailable" while the controls sat in the catalog. That is
  230. # the `goals` criterion read from inside the preset: a Service a row outside its
  231. # realm READS belongs to the plane both can see. The registry is keyed by owning
  232. # agent, so one host instance serves every session exactly as before presets.
  233. - id: tool-jobs
  234. disabled: true
  235. - id: tool-fs
  236. disabled: true
  237. - id: tool-fs-search
  238. disabled: true
  239. - id: tool-str-replace-editor
  240. disabled: true
  241. # The `skill` REGISTRY stays in the host plane. It is host+per-scope layered
  242. # (the tools-registry shape): deployment-level providers — repository plugins,
  243. # a host skill-filesystem row — register into its global layer, while a preset's
  244. # `skill-filesystem` registers into that preset's layer, and each agent reads the
  245. # merged catalog its scope chain selects. Only the per-agent rows move behind
  246. # presets: the base host `skill-filesystem` row is disabled here (presets own local
  247. # discovery), and `tool-skill` is what a preset mounts to give its agent the
  248. # catalog and loader at all.
  249. - id: skill-filesystem
  250. disabled: true
  251. - id: tool-skill
  252. disabled: true
  253. # The goal SERVICE, its session driver, and the `/goal` command STAY on the
  254. # host plane; only the model-facing tool moves. The Gateway serves the goal
  255. # domain as Remote endpoints, and a Remote method picks its receiver Service
  256. # from a generated descriptor — it resolves `goals` on the host, so a
  257. # per-session realm would answer `service-unavailable` for every browser call.
  258. # That is the `shell-env` criterion read from the other side: injection is not
  259. # the only host relationship a Service can have. The registry is keyed by
  260. # session, so one host instance serves every session exactly as before presets.
  261. - id: tool-goal
  262. disabled: true
  263. - id: plan-mode
  264. disabled: true
  265. # The token METER stays on the host plane; only the compaction backend that
  266. # reads it moves. It owns the context-meter projection units, and that table is
  267. # process-wide, so preset ownership would make the meter a function of which
  268. # presets happen to be mounted rather than a per-session fact. Same criterion as
  269. # `tasks` and `goals`; the reasoning has one home in
  270. # `.agents/notes/implemented/architecture/2026-08-10-host-plane-ownership-after-presets.md`.
  271. - id: compaction-basic
  272. disabled: true
  273. - id: command-compact
  274. disabled: true
  275. - id: tool-result-pruner
  276. disabled: true
  277. # The subagent registry and its backends STAY in the host plane. `subagents` is
  278. # a process singleton with a cross-session query surface (`listChildren`,
  279. # `followup`) that the host api-proxy serves to the browser, and a provider
  280. # registers under a globally unique name, so a per-session copy would both
  281. # starve that host row and collide on the second session. What a preset
  282. # chooses is which delegation TOOLS its agent sees, below.
  283. - id: tool-subagent-control
  284. disabled: true
  285. - id: tool-subagent-list-agents
  286. disabled: true
  287. - id: tool-subagent
  288. disabled: true
  289. - id: tool-subagent-fork
  290. disabled: true
  291. # `tool-subagent-report` is host-plane for the same reason as the registry, not
  292. # because a preset may not want it: it registers a CONTINUABLE SETUP on that
  293. # singleton rather than a tool this agent calls, and the setup list is not
  294. # scope-aware — one copy per mounted preset means every child gets `report`
  295. # registered once per live session, which throws on the second.
  296. - id: workflow-worker-thread
  297. disabled: true
  298. - id: tool-workflow
  299. disabled: true
  300. - id: tool-ralph
  301. disabled: true
  302. - id: agent-instructions
  303. disabled: true
  304. - id: tool-todo
  305. disabled: true
  306. - id: tool-web
  307. disabled: true
  308. # The preset roster. `config/agent-presets/` ships with the deployment and is
  309. # read-only (its entries carry `system` trust); `$DSH_HOME/.agent-presets` is
  310. # where a person — or an agent — authors their own, and carries the same trust
  311. # as shell access because a preset IS a composition.
  312. #
  313. # Only the SHIPPED root is an assembly fact: it sits beside the installed app's
  314. # own config, so `apps/cli`'s `composeProfile` resolves and patches it in — the
  315. # same treatment `distIndex` gets on the webserver row. The writable root is
  316. # `dsh-agent-presets`' own default (`includeUserRoot`), so a composition that
  317. # never reaches that patch still finds a person's presets.
  318. - insert:
  319. - id: agent-presets
  320. name: '@deepseek-ai/dsh-agent-presets'
  321. config:
  322. default: standard