@deepseek-ai/dsh-web-app 0.0.1-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.i18n.yaml +6 -0
- package/README.md +26 -0
- package/README.zh.md +26 -0
- package/cordis.patch.yml +369 -0
- package/lib/index.js +131 -0
- package/lib/invariant.js +25 -0
- package/lib/startup.js +55 -0
- package/lib/types/index.d.ts +67 -0
- package/lib/types/invariant.d.ts +16 -0
- package/lib/types/startup.d.ts +32 -0
- package/package.json +107 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, DeepSeek
|
|
4
|
+
|
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
|
7
|
+
|
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
|
9
|
+
list of conditions and the following disclaimer.
|
|
10
|
+
|
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
|
13
|
+
and/or other materials provided with the distribution.
|
|
14
|
+
|
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
|
16
|
+
contributors may be used to endorse or promote products derived from
|
|
17
|
+
this software without specific prior written permission.
|
|
18
|
+
|
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/README.i18n.yaml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
|
2
|
+
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
|
+
# after editing either side, bring the other along and re-record with:
|
|
4
|
+
# pnpm run verify-translation-pairing --write packages/bundle/web-app/README.md
|
|
5
|
+
README.md: b6fa225f5e0a0a079605a4fb9064b79287ab21cd
|
|
6
|
+
README.zh.md: 68af959719b9bd146eddd143aa9d98400e65fa68
|
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# `@deepseek-ai/dsh-web-app`
|
|
2
|
+
|
|
3
|
+
English | [中文](README.zh.md)
|
|
4
|
+
|
|
5
|
+
The dsh browser-surface bundle. [`cordis.patch.yml`](cordis.patch.yml) rides over [`dsh-base`](../base/README.md): it sets the coding persona, inserts the Web host rows (webserver, API gateway, workspace, projection cache, storage) and the browser plugin roster, and mounts this package's `web-runtime` glue plugin (config `{mode, printUrl, surfaceContext, trustedHosts}`). That plugin resolves the built frontend dist through `@deepseek-ai/dsh-frontend`'s exports, enables the optional HMR row before client-module discovery so the first development graph contains its reload receiver, samples bind-dependent LAN trust once, provides it as `webRuntime` to the browser-trust fence and client roster, mounts the [`frontend-static`](../../host/frontend-static/README.md) fallback owner, registers the harness-source and web-surface prompt sections plus the bash-visible `DSH_WEB_URL`/`DSH_WEB_MODE` runtime variables when `surfaceContext` is true, and prints the `dsh web:` URL line when `printUrl` is true, after its Loader tree settles so a sibling failure cannot announce a dead app. This bundle also owns the app command line: the ordinary `web-startup` provider ([`src/startup.ts`](src/startup.ts)) injects `ctx.cmdlineArgs` ([`dsh-cmdline`](../../boot/cmdline/README.md)), parses `--host`, `--port`, `--dev`, repeatable `--trusted-host`, and the app's `--help`, then provides `webStartup`. Flag-configured rows inject that service and read it directly from lazy config, so nothing binds a port before argument resolution and `dsh --profile web --help` starts no server. [`dsh-headless`](../headless/README.md) is a sibling surface over the same base and does not mount this bundle.
|
|
6
|
+
|
|
7
|
+
## Model Experience
|
|
8
|
+
|
|
9
|
+
### Harness-source and Web-surface context
|
|
10
|
+
|
|
11
|
+
#### What the model sees
|
|
12
|
+
|
|
13
|
+
When `surfaceContext` is true, the `harness:source` section identifies the on-disk Harness implementation without claiming it is the working directory, and the `app:web-surface` global section (order −98) orients the model to the GUI: the canonical local URL, the "this page" referent, the HMR/rebuild update contract for the active mode, and the instruction not to start replacement servers. `DSH_WEB_URL` and `DSH_WEB_MODE` additionally appear in the managed bash environment with their descriptions, resolved per invocation from the live server. When it is false, neither section nor the variables are registered.
|
|
14
|
+
|
|
15
|
+
#### Token effect
|
|
16
|
+
|
|
17
|
+
One source line and one prompt paragraph per session plus two managed-environment variable lines; constant per process.
|
|
18
|
+
|
|
19
|
+
#### KV Cache effect
|
|
20
|
+
|
|
21
|
+
The prompt section sits near the system prompt's head and is stable for the life of the process (port and mode are boot facts), so it does not invalidate the cache across turns.
|
|
22
|
+
|
|
23
|
+
## Known Limitations and Deferred Work
|
|
24
|
+
|
|
25
|
+
- **The frontend dist must be built** — `require.resolve` of the dist fails loud at activation with a build hint; there is no source-serving fallback.
|
|
26
|
+
- **`lanAddresses` is a boot-time snapshot** — interface changes after boot are not re-advertised; the printed LAN URL always matches the configured trust fence.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# `@deepseek-ai/dsh-web-app`
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
dsh 浏览器表层组合包。[`cordis.patch.yml`](cordis.patch.yml) 叠加在 [`dsh-base`](../base/README.md) 之上:设置 coding persona,插入 Web 宿主行(webserver、API 网关、workspace、投影缓存、存储)与浏览器插件名录,并挂载本包的 `web-runtime` 粘合插件(配置为 `{mode, printUrl, surfaceContext, trustedHosts}`)。该插件通过 `@deepseek-ai/dsh-frontend` 的 exports 解析已构建的前端 dist,在客户端模块发现前启用可选的 HMR 行,确保首份开发模式图中包含它的重载接收端,只采样一次依赖 bind 的 LAN 信任信息并将其作为 `webRuntime` 提供给浏览器信任栅栏和客户端名录,挂载 [`frontend-static`](../../host/frontend-static/README.md) 回退席位所有者,在 `surfaceContext` 为 true 时注册 Harness 源码与 Web 表层提示词段落,以及 bash 可见的 `DSH_WEB_URL`/`DSH_WEB_MODE` 运行时变量,并在 `printUrl` 为 true 时等自身的 Loader 配置树结算后再打印 `dsh web:` URL 行,避免兄弟行失败时公告一个已失效的应用。本组合包还持有应用命令行:普通 `web-startup` 提供方([`src/startup.ts`](src/startup.ts))注入 `ctx.cmdlineArgs`([`dsh-cmdline`](../../boot/cmdline/README.md)),解析 `--host`、`--port`、`--dev`、可重复的 `--trusted-host` 以及应用自己的 `--help`,再提供 `webStartup`。由 flag 配置的行会注入该服务,并在惰性配置中直接读取它,因此参数解析完成前不会有任何东西绑定端口,`dsh --profile web --help` 也不会启动服务器。[`dsh-headless`](../headless/README.md) 是同一 base 之上的同级表层,不挂载本组合包。
|
|
6
|
+
|
|
7
|
+
## 模型体验
|
|
8
|
+
|
|
9
|
+
### Harness 源码与 Web 表层上下文
|
|
10
|
+
|
|
11
|
+
#### 模型看到的内容
|
|
12
|
+
|
|
13
|
+
当 `surfaceContext` 为 true 时,`harness:source` 段落标明磁盘上的 Harness 实现,但不会声称它就是工作目录;全局段落 `app:web-surface`(顺序 −98)则向模型说明 GUI:规范的本地 URL、「this page」指代什么、当前模式下 HMR(热模块替换)/重建的更新约定,以及不要启动替代服务器的指令。`DSH_WEB_URL` 与 `DSH_WEB_MODE` 还会连同各自描述出现在受管 bash 环境中,每次调用时从运行中的服务器解析。当它为 false 时,这两个段落和这些变量都不会注册。
|
|
14
|
+
|
|
15
|
+
#### Token 影响
|
|
16
|
+
|
|
17
|
+
每个会话一行源码说明和一段提示词,外加两行受管环境变量;每个进程内保持恒定。
|
|
18
|
+
|
|
19
|
+
#### KV Cache 影响
|
|
20
|
+
|
|
21
|
+
该提示词段落位于系统提示词靠前位置,且在进程整个生命周期内稳定(端口与模式是启动期事实),因此不会使跨轮次缓存失效。
|
|
22
|
+
|
|
23
|
+
## 已知限制与延期工作
|
|
24
|
+
|
|
25
|
+
- **前端 dist 必须已构建**:对 dist 的 `require.resolve` 在激活时明确报错并给出构建提示;没有从源码直接服务的回退路径。
|
|
26
|
+
- **`lanAddresses` 是启动期快照**:启动后的网卡变化不会重新公告;打印的 LAN URL 始终与配置的信任栅栏一致。
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
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 and client
|
|
12
|
+
# roster. `dsh --profile web --help` provides neither service, so no server binds.
|
|
13
|
+
|
|
14
|
+
# ── surface-specific values the base deliberately omits ─────────────────────
|
|
15
|
+
|
|
16
|
+
- id: system-prompt
|
|
17
|
+
config:
|
|
18
|
+
persona: >-
|
|
19
|
+
You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.
|
|
20
|
+
|
|
21
|
+
# TODO: Re-enable shared HMR for Web after its reload lifecycle is tested.
|
|
22
|
+
- id: hmr
|
|
23
|
+
disabled: true
|
|
24
|
+
|
|
25
|
+
# Web content search runs on an ephemeral in-memory index. The service
|
|
26
|
+
# activates at boot, while first-search defers the node:sqlite import and
|
|
27
|
+
# in-memory handle so Node 22 startup stays quiet until content search
|
|
28
|
+
# actually uses SQLite. That search then reconciles this boot's sources.
|
|
29
|
+
- id: session-query-sqlite
|
|
30
|
+
config:
|
|
31
|
+
path: ':memory:'
|
|
32
|
+
openAt: first-search
|
|
33
|
+
|
|
34
|
+
- id: tools
|
|
35
|
+
config:
|
|
36
|
+
# TEMPORARY workaround: DSH_TOOLS_MODE (native|code|both) opts a whole dsh
|
|
37
|
+
# process into Code Mode while per-session tool-mode selection is being
|
|
38
|
+
# designed; unset keeps the schema default (native). Remove the env seam
|
|
39
|
+
# once the web UI owns the choice per session.
|
|
40
|
+
mode: !!js process.env.DSH_TOOLS_MODE
|
|
41
|
+
|
|
42
|
+
# ── web-only host rows, the transport layer, and the browser roster ─────────
|
|
43
|
+
|
|
44
|
+
# `dsh.client` rows are the browser roster the modules node half scans into
|
|
45
|
+
# window.__DSH_BOOT__; the modules row is simultaneously a host row.
|
|
46
|
+
- insert:
|
|
47
|
+
- id: code-runtime
|
|
48
|
+
name: '@deepseek-ai/dsh-code-runtime-worker'
|
|
49
|
+
|
|
50
|
+
- id: storage
|
|
51
|
+
name: '@deepseek-ai/dsh-storage'
|
|
52
|
+
|
|
53
|
+
- id: storage-json
|
|
54
|
+
name: '@deepseek-ai/dsh-storage-json'
|
|
55
|
+
config:
|
|
56
|
+
root: !!js dshHomePath('storages')
|
|
57
|
+
|
|
58
|
+
- id: storage-domain
|
|
59
|
+
name: '@deepseek-ai/dsh-storage-domain'
|
|
60
|
+
config:
|
|
61
|
+
backend: json
|
|
62
|
+
|
|
63
|
+
- id: workspace
|
|
64
|
+
name: '@deepseek-ai/dsh-workspace'
|
|
65
|
+
|
|
66
|
+
- id: session-projection-cache
|
|
67
|
+
name: '@deepseek-ai/dsh-session-projection-cache'
|
|
68
|
+
config:
|
|
69
|
+
writeEveryEvents: 200
|
|
70
|
+
writeIntervalMs: 5000
|
|
71
|
+
|
|
72
|
+
# Resolve bind host, SSH launch, and display once at boot, then mount the
|
|
73
|
+
# matching dual-face directory picker. Mount -native or -browse directly in
|
|
74
|
+
# an overlay to pin the interaction.
|
|
75
|
+
- id: directory-picker
|
|
76
|
+
name: '@deepseek-ai/dsh-host-directory-picker-auto'
|
|
77
|
+
|
|
78
|
+
# The API gateway: the transport-agnostic dispatch face every client shape
|
|
79
|
+
# shares. The base layer's agent-default-model service owns the default model.
|
|
80
|
+
- id: api-gateway
|
|
81
|
+
name: '@deepseek-ai/dsh-host-apiproxy'
|
|
82
|
+
|
|
83
|
+
# Ordinary provider for the parsed Web flags. Its plugin-level injection
|
|
84
|
+
# waits for cmdlineArgs; no launcher metadata or special row kind is needed.
|
|
85
|
+
- id: web-startup
|
|
86
|
+
name: '@deepseek-ai/dsh-web-app/startup'
|
|
87
|
+
|
|
88
|
+
# ── layer 2: transport/service ──────────────────────────────────────────────
|
|
89
|
+
|
|
90
|
+
# Plain route-registration carrier; host and port come from the app's
|
|
91
|
+
# webStartup provider, with these deployment fallbacks. The dist is served by
|
|
92
|
+
# the web-runtime row below through the fallback seat.
|
|
93
|
+
- id: webserver
|
|
94
|
+
name: '@deepseek-ai/dsh-host-webserver'
|
|
95
|
+
inject: [webStartup]
|
|
96
|
+
config:
|
|
97
|
+
host: !!js ctx.webStartup.host ?? '127.0.0.1'
|
|
98
|
+
port: !!js ctx.webStartup.port ?? 3080
|
|
99
|
+
|
|
100
|
+
# Web glue owned by this bundle: resolves the built frontend dist (an
|
|
101
|
+
# assembly fact of dsh-web-app, never user config), mounts the
|
|
102
|
+
# frontend-static fallback owner, registers the web-surface prompt
|
|
103
|
+
# section and bash runtime variables, and prints the URL line. The webStartup
|
|
104
|
+
# provider supplies invocation-only values; after the server binds, this row
|
|
105
|
+
# samples LAN trust once and provides `webRuntime`. A complete agent-preset
|
|
106
|
+
# persona suppresses the prompt section for that agent while retaining
|
|
107
|
+
# these host-owned shell variables.
|
|
108
|
+
- id: web-runtime
|
|
109
|
+
name: '@deepseek-ai/dsh-web-app'
|
|
110
|
+
inject: [webStartup]
|
|
111
|
+
config:
|
|
112
|
+
mode: !!js ctx.webStartup.mode
|
|
113
|
+
printUrl: true
|
|
114
|
+
surfaceContext: true
|
|
115
|
+
trustedHosts: !!js ctx.webStartup.trustedHosts
|
|
116
|
+
|
|
117
|
+
# The client-plugin reload chain: a dev-only row this bundle ships off,
|
|
118
|
+
# which the runtime row turns on before client discovery. It is a row rather
|
|
119
|
+
# than a child of web-runtime because its node half is a client-side package,
|
|
120
|
+
# which a host-side bundle cannot import.
|
|
121
|
+
- id: client-hmr
|
|
122
|
+
name: '@deepseek-ai/dsh-client-hmr'
|
|
123
|
+
inject: [webStartup]
|
|
124
|
+
disabled: true
|
|
125
|
+
|
|
126
|
+
# ── browser plugin roster (dsh.client rows; node halves are layer-2 hosts) ──
|
|
127
|
+
|
|
128
|
+
# Dual-face: this waits for the runtime row to decide whether HMR belongs
|
|
129
|
+
# in the first graph. The node half then scans this tree, composes
|
|
130
|
+
# window.__DSH_BOOT__, and serves /plugins/<id>/client.js; the browser half
|
|
131
|
+
# is the module table the shell kernel constructs before cordis exists
|
|
132
|
+
# (adopted as a plugin entry by the kernel, never fetched).
|
|
133
|
+
- id: modules
|
|
134
|
+
name: '@deepseek-ai/dsh-client-modules'
|
|
135
|
+
inject: [webRuntime]
|
|
136
|
+
|
|
137
|
+
# Owns both ends of the web transport: node half binds the gateway to the
|
|
138
|
+
# webserver under /api; browser half is the fetch/SSE client.
|
|
139
|
+
- id: connection
|
|
140
|
+
name: '@deepseek-ai/dsh-client-connection'
|
|
141
|
+
inject: [webRuntime]
|
|
142
|
+
config:
|
|
143
|
+
# LAN literals derived from the active bind plus --trusted-host extras.
|
|
144
|
+
# A deployment adding authorities keeps this expression and concatenates
|
|
145
|
+
# its literals, for example: ['app.internal', ...ctx.webRuntime.trustedHosts].
|
|
146
|
+
trustedHosts: !!js ctx.webRuntime.trustedHosts
|
|
147
|
+
|
|
148
|
+
- id: api-remotes
|
|
149
|
+
name: '@deepseek-ai/dsh-api-remotes'
|
|
150
|
+
|
|
151
|
+
- id: client-runtime
|
|
152
|
+
name: '@deepseek-ai/dsh-client-runtime'
|
|
153
|
+
|
|
154
|
+
- id: ui-theme
|
|
155
|
+
name: '@deepseek-ai/dsh-client-ui-theme'
|
|
156
|
+
|
|
157
|
+
- id: locale
|
|
158
|
+
name: '@deepseek-ai/dsh-client-locale'
|
|
159
|
+
|
|
160
|
+
- id: ui-layout
|
|
161
|
+
name: '@deepseek-ai/dsh-client-ui-layout'
|
|
162
|
+
|
|
163
|
+
- id: ui-sidebar
|
|
164
|
+
name: '@deepseek-ai/dsh-client-ui-sidebar'
|
|
165
|
+
|
|
166
|
+
- id: ui-settings
|
|
167
|
+
name: '@deepseek-ai/dsh-client-ui-settings'
|
|
168
|
+
|
|
169
|
+
- id: ui-settings-general
|
|
170
|
+
name: '@deepseek-ai/dsh-client-ui-settings-general'
|
|
171
|
+
|
|
172
|
+
- id: ui-models
|
|
173
|
+
name: '@deepseek-ai/dsh-client-ui-models'
|
|
174
|
+
|
|
175
|
+
- id: ui-conversation
|
|
176
|
+
name: '@deepseek-ai/dsh-client-ui-conversation'
|
|
177
|
+
|
|
178
|
+
# Tool call tree, generic fallback, and keyed business Tool views.
|
|
179
|
+
- id: ui-tool
|
|
180
|
+
name: '@deepseek-ai/dsh-client-ui-tool'
|
|
181
|
+
|
|
182
|
+
# Turn tail: the produced-files row under each closing assistant message.
|
|
183
|
+
# Remove this entry to turn the surface off; the tail hole renders empty.
|
|
184
|
+
- id: ui-deliverables
|
|
185
|
+
name: '@deepseek-ai/dsh-client-ui-deliverables'
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
- id: ui-workspace
|
|
189
|
+
name: '@deepseek-ai/dsh-client-ui-workspace'
|
|
190
|
+
|
|
191
|
+
# Input triggers: the '/' | '@' pipeline (ui-slash), the command surface over
|
|
192
|
+
# it (ui-command), and the two reference sources (ui-skill / ui-subagent).
|
|
193
|
+
- id: ui-slash
|
|
194
|
+
name: '@deepseek-ai/dsh-client-ui-slash'
|
|
195
|
+
|
|
196
|
+
- id: ui-command
|
|
197
|
+
name: '@deepseek-ai/dsh-client-ui-command'
|
|
198
|
+
|
|
199
|
+
- id: ui-skill
|
|
200
|
+
name: '@deepseek-ai/dsh-client-ui-skill'
|
|
201
|
+
|
|
202
|
+
- id: ui-subagent
|
|
203
|
+
name: '@deepseek-ai/dsh-client-ui-subagent'
|
|
204
|
+
|
|
205
|
+
# Goal surface: GoalBar in the input dock over the goal session projection.
|
|
206
|
+
- id: ui-goal
|
|
207
|
+
name: '@deepseek-ai/dsh-client-ui-goal'
|
|
208
|
+
|
|
209
|
+
# Model selection: the /model popupSelect + composer seat over session.models.
|
|
210
|
+
- id: ui-model
|
|
211
|
+
name: '@deepseek-ai/dsh-client-ui-model'
|
|
212
|
+
|
|
213
|
+
- id: ui-permission
|
|
214
|
+
name: '@deepseek-ai/dsh-client-ui-permission'
|
|
215
|
+
|
|
216
|
+
# The agent-preset row in General settings: the default preset for
|
|
217
|
+
# sessions created later. Absent a roster it renders nothing.
|
|
218
|
+
- id: ui-agent-preset
|
|
219
|
+
name: '@deepseek-ai/dsh-client-ui-agent-preset'
|
|
220
|
+
|
|
221
|
+
# Plan control: the composer plan seat over the plan projection + /plan channel.
|
|
222
|
+
- id: ui-plan
|
|
223
|
+
name: '@deepseek-ai/dsh-client-ui-plan'
|
|
224
|
+
|
|
225
|
+
- id: ui-question
|
|
226
|
+
name: '@deepseek-ai/dsh-client-ui-question'
|
|
227
|
+
|
|
228
|
+
- id: ui-trajectory
|
|
229
|
+
name: '@deepseek-ai/dsh-client-ui-trajectory'
|
|
230
|
+
|
|
231
|
+
# ── the agent plane moves behind agent presets ─────────────────────────────
|
|
232
|
+
#
|
|
233
|
+
# Every row below composes what ONE agent contributes to the host registries:
|
|
234
|
+
# its tools, its prompt sections, its delegation backends. The base keeps them
|
|
235
|
+
# for the TUI, which is single-session and composes its agent process-wide; the
|
|
236
|
+
# Web surface disables them here and lets each session mount a preset instead.
|
|
237
|
+
#
|
|
238
|
+
# Disabling rather than deleting is deliberate: the base is shared, and a row
|
|
239
|
+
# absent from a surface overlay would silently reappear the day someone reorders
|
|
240
|
+
# the composition.
|
|
241
|
+
|
|
242
|
+
# `bash-env` STAYS in the host plane: `apps/cli/src/web.ts` injects it to
|
|
243
|
+
# publish `DSH_WEB_URL`/`DSH_WEB_MODE`, and a host row that injects a service is
|
|
244
|
+
# the criterion for host-plane ownership — injection resolves before any session
|
|
245
|
+
# exists, so there is no agent to key by. Behind a preset realm those variables
|
|
246
|
+
# would never reach the model's shell at all.
|
|
247
|
+
|
|
248
|
+
- id: tool-bash
|
|
249
|
+
disabled: true
|
|
250
|
+
|
|
251
|
+
# The background-task REGISTRY stays on the host plane; only the model-facing
|
|
252
|
+
# `task_*` controls move. Its producers — `tool-bash` here, `tool-pty` and a
|
|
253
|
+
# non-continuable `tool-subagent` elsewhere — are preset rows that resolve it
|
|
254
|
+
# with `ctx.get`, and an entry-local realm around the registry is invisible to
|
|
255
|
+
# every sibling row outside that realm, so `run_in_background` answered
|
|
256
|
+
# "background tasks unavailable" while the controls sat in the catalog. That is
|
|
257
|
+
# the `goals` criterion read from inside the preset: a Service a row outside its
|
|
258
|
+
# realm READS belongs to the plane both can see. The registry is keyed by owning
|
|
259
|
+
# agent, so one host instance serves every session exactly as before presets.
|
|
260
|
+
|
|
261
|
+
- id: tool-tasks
|
|
262
|
+
disabled: true
|
|
263
|
+
|
|
264
|
+
- id: tool-fs
|
|
265
|
+
disabled: true
|
|
266
|
+
|
|
267
|
+
- id: tool-fs-search
|
|
268
|
+
disabled: true
|
|
269
|
+
|
|
270
|
+
- id: tool-str-replace-editor
|
|
271
|
+
disabled: true
|
|
272
|
+
|
|
273
|
+
# The `skill` REGISTRY stays in the host plane. It is host+per-scope layered
|
|
274
|
+
# (the tools-registry shape): deployment-level providers — repository plugins,
|
|
275
|
+
# a host skill-local row — register into its global layer, while a preset's
|
|
276
|
+
# `skill-local` registers into that preset's layer, and each agent reads the
|
|
277
|
+
# merged catalog its scope chain selects. Only the per-agent rows move behind
|
|
278
|
+
# presets: the base host `skill-local` row is disabled here (presets own local
|
|
279
|
+
# discovery), and `tool-skill` is what a preset mounts to give its agent the
|
|
280
|
+
# catalog and loader at all.
|
|
281
|
+
|
|
282
|
+
- id: skill-local
|
|
283
|
+
disabled: true
|
|
284
|
+
|
|
285
|
+
- id: tool-skill
|
|
286
|
+
disabled: true
|
|
287
|
+
|
|
288
|
+
# The goal SERVICE, its session driver, and the `/goal` command STAY on the
|
|
289
|
+
# host plane; only the model-facing tool moves. The Gateway serves the goal
|
|
290
|
+
# domain as Remote endpoints, and a Remote method picks its receiver Service
|
|
291
|
+
# from a generated descriptor — it resolves `goals` on the host, so a
|
|
292
|
+
# per-session realm would answer `service-unavailable` for every browser call.
|
|
293
|
+
# That is the `bash-env` criterion read from the other side: injection is not
|
|
294
|
+
# the only host relationship a Service can have. The registry is keyed by
|
|
295
|
+
# session, so one host instance serves every session exactly as before presets.
|
|
296
|
+
|
|
297
|
+
- id: tool-goal
|
|
298
|
+
disabled: true
|
|
299
|
+
|
|
300
|
+
- id: plan-mode
|
|
301
|
+
disabled: true
|
|
302
|
+
|
|
303
|
+
- id: token-meter
|
|
304
|
+
disabled: true
|
|
305
|
+
|
|
306
|
+
- id: compact-basic
|
|
307
|
+
disabled: true
|
|
308
|
+
|
|
309
|
+
- id: command-compact
|
|
310
|
+
disabled: true
|
|
311
|
+
|
|
312
|
+
- id: tool-result-prune
|
|
313
|
+
disabled: true
|
|
314
|
+
|
|
315
|
+
# The subagent registry and its backends STAY in the host plane. `subagents` is
|
|
316
|
+
# a process singleton with a cross-session query surface (`listChildren`,
|
|
317
|
+
# `followup`) that the host api-proxy serves to the browser, and a provider
|
|
318
|
+
# registers under a globally unique name, so a per-session copy would both
|
|
319
|
+
# starve that host row and collide on the second session. What a preset
|
|
320
|
+
# chooses is which delegation TOOLS its agent sees, below.
|
|
321
|
+
|
|
322
|
+
- id: tool-subagent-control
|
|
323
|
+
disabled: true
|
|
324
|
+
|
|
325
|
+
- id: tool-subagent-list-agents
|
|
326
|
+
disabled: true
|
|
327
|
+
|
|
328
|
+
- id: tool-subagent
|
|
329
|
+
disabled: true
|
|
330
|
+
|
|
331
|
+
- id: tool-subagent-fork
|
|
332
|
+
disabled: true
|
|
333
|
+
|
|
334
|
+
# `tool-subagent-report` is host-plane for the same reason as the registry, not
|
|
335
|
+
# because a preset may not want it: it registers a CONTINUABLE SETUP on that
|
|
336
|
+
# singleton rather than a tool this agent calls, and the setup list is not
|
|
337
|
+
# scope-aware — one copy per mounted preset means every child gets `report`
|
|
338
|
+
# registered once per live session, which throws on the second.
|
|
339
|
+
|
|
340
|
+
- id: workflow-workerthread
|
|
341
|
+
disabled: true
|
|
342
|
+
|
|
343
|
+
- id: tool-workflow
|
|
344
|
+
disabled: true
|
|
345
|
+
|
|
346
|
+
- id: tool-ralph
|
|
347
|
+
disabled: true
|
|
348
|
+
|
|
349
|
+
- id: workspace-context
|
|
350
|
+
disabled: true
|
|
351
|
+
|
|
352
|
+
- id: tool-todo
|
|
353
|
+
disabled: true
|
|
354
|
+
|
|
355
|
+
- id: tool-web
|
|
356
|
+
disabled: true
|
|
357
|
+
|
|
358
|
+
# The preset roster. `config/agent-presets/` ships with the deployment and is
|
|
359
|
+
# read-only (its entries carry `system` trust);
|
|
360
|
+
# `$DSH_HOME/.agent-presets` is where a person — or an agent — authors their own, and
|
|
361
|
+
# carries the same trust as shell access because a preset IS a composition.
|
|
362
|
+
# `roots` is an assembly fact, not user config: the shipped preset directory
|
|
363
|
+
# ships beside this file, so AppCLIEntry resolves it and patches it in — the
|
|
364
|
+
# same treatment `distIndex` gets on the webserver row.
|
|
365
|
+
- insert:
|
|
366
|
+
- id: agent-presets
|
|
367
|
+
name: '@deepseek-ai/dsh-agent-presets'
|
|
368
|
+
config:
|
|
369
|
+
default: standard
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { networkInterfaces } from "node:os";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import z from "@deepseek-ai/schemastery";
|
|
5
|
+
import { addHarnessSourceSection } from "@deepseek-ai/dsh-app-boot";
|
|
6
|
+
import { enableRow } from "@deepseek-ai/dsh-cmdline";
|
|
7
|
+
import * as FrontendStatic from "@deepseek-ai/dsh-frontend-static";
|
|
8
|
+
//#region lib/types/index.js
|
|
9
|
+
/**
|
|
10
|
+
* @deepseek-ai/dsh-web-app — the browser-surface bundle's runtime glue plugin
|
|
11
|
+
* plus the bundle patch (`cordis.patch.yml`, declared by the `dsh.bundle.patch`
|
|
12
|
+
* manifest field). The plugin owns the browser-surface glue: it resolves
|
|
13
|
+
* the built frontend dist (workspace knowledge of this bundle, never user
|
|
14
|
+
* config), mounts the `frontend-static` fallback owner over it, registers the
|
|
15
|
+
* harness-source and web-surface prompt sections, the bash-visible web runtime
|
|
16
|
+
* variables, and the URL line. App command-line values arrive through the
|
|
17
|
+
* `webStartup` service expressions in the bundle patch.
|
|
18
|
+
* @module @deepseek-ai/dsh-web-app
|
|
19
|
+
*/
|
|
20
|
+
/** Stable Cordis plugin name. */
|
|
21
|
+
const name = "web-app";
|
|
22
|
+
/** This dsh installation's root, from either this package's source or built entry. */
|
|
23
|
+
const SOURCE_ROOT = fileURLToPath(new URL("../../../..", import.meta.url));
|
|
24
|
+
const HMR_ROW_ID = "client-hmr";
|
|
25
|
+
/** Runtime service that releases Web rows after bind-dependent values resolve. */
|
|
26
|
+
const WEB_RUNTIME_SERVICE = "webRuntime";
|
|
27
|
+
/** Services required before the web runtime can mount. */
|
|
28
|
+
const inject = ["httpServer"];
|
|
29
|
+
const Config = z.object({
|
|
30
|
+
mode: z.union([z.const("production"), z.const("development")]).default("production"),
|
|
31
|
+
printUrl: z.boolean().default(true),
|
|
32
|
+
surfaceContext: z.boolean().default(true),
|
|
33
|
+
trustedHosts: z.array(String).default([])
|
|
34
|
+
});
|
|
35
|
+
/** Environment variable naming the canonical local URL of this Web GUI. */
|
|
36
|
+
const DSH_WEB_URL = "DSH_WEB_URL";
|
|
37
|
+
/** Environment variable naming the Web runtime mode. */
|
|
38
|
+
const DSH_WEB_MODE = "DSH_WEB_MODE";
|
|
39
|
+
const LOOPBACK_HOST = "127.0.0.1";
|
|
40
|
+
/** The webserver schema's all-interfaces bind literal. */
|
|
41
|
+
const ALL_INTERFACES_HOST = "0.0.0.0";
|
|
42
|
+
/**
|
|
43
|
+
* Resolve one LAN-trust snapshot from the active server bind.
|
|
44
|
+
*
|
|
45
|
+
* Derived entries are port-less IP literals: DNS rebinding needs an
|
|
46
|
+
* attacker-controlled name, while an IP-literal Host is safe on any port and
|
|
47
|
+
* an OS-assigned port is unknowable before bind.
|
|
48
|
+
* @param bindHost - the active webserver bind host.
|
|
49
|
+
* @param extra - explicit `--trusted-host` values, in argument order.
|
|
50
|
+
* @returns the LAN display addresses and invocation-derived fence authorities.
|
|
51
|
+
*/
|
|
52
|
+
function resolveLanTrust(bindHost, extra) {
|
|
53
|
+
const lanAddresses = bindHost === ALL_INTERFACES_HOST ? Object.values(networkInterfaces()).flat().filter((iface) => iface !== void 0 && iface.family === "IPv4" && !iface.internal).map((iface) => iface.address) : [];
|
|
54
|
+
return {
|
|
55
|
+
lanAddresses,
|
|
56
|
+
trustedHosts: [...lanAddresses, ...extra]
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Model-visible orientation and acceptance boundary for sessions created through `dsh web`. */
|
|
60
|
+
function webSurfacePrompt(webUrl, mode) {
|
|
61
|
+
const updateContract = mode === "development" ? "This Web process was launched with `dsh web --dev`, so its client-plugin HMR receiver is active. No-refresh updates occur only when `pnpm run dev:web` is also running from this same checkout to rebuild client-plugin bundles; verify that watcher before promising automatic updates. Client-plugin changes then reload automatically, while apps/web shell and other plain-package changes still require a rebuild and page refresh. " : "This Web process was launched without `--dev`, so HMR is inactive: rebuild the affected Web artifacts and verify this existing URL after a page refresh. If the user wants no-refresh client-plugin updates, explain that this GUI must be restarted with `dsh web --dev` and `pnpm run dev:web` must also run from this same checkout; do not present either command alone as sufficient. ";
|
|
62
|
+
return `You are interacting with the user through the DeepSeek Harness Web GUI at ${webUrl}. When the user refers to "this page", "this GUI", or "this app" without naming another target, they mean this GUI. The browser provides no implicit DOM, route, or screenshot context. ` + updateContract + "Starting another server does not update this GUI. The apps/web Vite entry builds the shell but is not a standalone application because only dsh web injects window.__DSH_BOOT__. Do not start a replacement server unless the user asks; if one is needed, use a managed background task and verify its exact URL.";
|
|
63
|
+
}
|
|
64
|
+
/** Resolve the canonical loopback URL from the active Web server. */
|
|
65
|
+
function localWebUrl(ctx) {
|
|
66
|
+
const port = ctx.get("httpServer")?.port;
|
|
67
|
+
if (port === void 0) throw new Error("web-app: httpServer service missing while resolving Web runtime");
|
|
68
|
+
return `http://${LOOPBACK_HOST}:${String(port)}`;
|
|
69
|
+
}
|
|
70
|
+
/** Dist location is workspace knowledge of this bundle: resolved through the frontend package exports, not configured. */
|
|
71
|
+
function resolveDistIndex() {
|
|
72
|
+
const require = createRequire(import.meta.url);
|
|
73
|
+
try {
|
|
74
|
+
return require.resolve("@deepseek-ai/dsh-frontend/dist/index.html");
|
|
75
|
+
} catch {
|
|
76
|
+
/* v8 ignore next 2 -- reachable only on a checkout without a built dist; the test tree builds it */
|
|
77
|
+
throw new Error("web-app: frontend dist not built; run pnpm run build from the repository root first");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/** Test hook: hosts with no built frontend dist substitute the resolver; production never touches this. */
|
|
81
|
+
const internals = { resolveDistIndex };
|
|
82
|
+
/**
|
|
83
|
+
* Mount the Web runtime: dist serving, surface prompt, bash runtime
|
|
84
|
+
* variables, and the URL line.
|
|
85
|
+
* @param ctx - plugin context carrying the httpServer service.
|
|
86
|
+
* @param config - validated {@link Config}.
|
|
87
|
+
* @returns nothing once the invocation's client roster and runtime contributions are registered.
|
|
88
|
+
*/
|
|
89
|
+
async function apply(ctx, config) {
|
|
90
|
+
if (config.mode === "development") await enableRow(ctx, HMR_ROW_ID);
|
|
91
|
+
const runtime = resolveLanTrust(ctx.httpServer.host, config.trustedHosts);
|
|
92
|
+
ctx.provide(WEB_RUNTIME_SERVICE, runtime);
|
|
93
|
+
ctx.plugin(FrontendStatic, { distIndex: internals.resolveDistIndex() });
|
|
94
|
+
if (config.surfaceContext) {
|
|
95
|
+
ctx.inject(["systemPrompt"], (promptCtx) => {
|
|
96
|
+
addHarnessSourceSection(promptCtx, SOURCE_ROOT);
|
|
97
|
+
promptCtx.systemPrompt.section({
|
|
98
|
+
name: "app:web-surface",
|
|
99
|
+
order: -98,
|
|
100
|
+
text: () => webSurfacePrompt(localWebUrl(promptCtx), config.mode)
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
ctx.inject(["bashEnv"], (runtimeCtx) => {
|
|
104
|
+
runtimeCtx.bashEnv.register({
|
|
105
|
+
name: "web-runtime",
|
|
106
|
+
variables: {
|
|
107
|
+
[DSH_WEB_URL]: { description: "Canonical local URL of the DeepSeek Harness Web GUI serving this session." },
|
|
108
|
+
[DSH_WEB_MODE]: { description: "Web runtime mode: production, or development when the client-plugin HMR receiver is active." }
|
|
109
|
+
},
|
|
110
|
+
resolve: () => ({
|
|
111
|
+
[DSH_WEB_URL]: localWebUrl(runtimeCtx),
|
|
112
|
+
[DSH_WEB_MODE]: config.mode
|
|
113
|
+
})
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (config.printUrl) {
|
|
118
|
+
const printUrl = () => {
|
|
119
|
+
const lanCandidate = runtime.lanAddresses[0];
|
|
120
|
+
const port = ctx.httpServer.port;
|
|
121
|
+
console.log(`dsh web: ${localWebUrl(ctx)}${lanCandidate === void 0 ? "" : ` (LAN: http://${lanCandidate}:${String(port)})`}`);
|
|
122
|
+
};
|
|
123
|
+
const settled = ctx.get("loader")?.await();
|
|
124
|
+
if (settled === void 0) printUrl();
|
|
125
|
+
else settled.then(() => {
|
|
126
|
+
if (ctx.get("httpServer") !== void 0) printUrl();
|
|
127
|
+
}, () => {});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//#endregion
|
|
131
|
+
export { Config, apply, inject, internals, name, resolveLanTrust };
|
package/lib/invariant.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-web-app`.
|
|
4
|
+
* @module @deepseek-ai/dsh-web-app/invariant
|
|
5
|
+
*/
|
|
6
|
+
const PACKAGE_NAME = "@deepseek-ai/dsh-web-app";
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
const name = "web-app-invariant";
|
|
9
|
+
/** Service required before the companion can register. */
|
|
10
|
+
const inject = ["invariants"];
|
|
11
|
+
/**
|
|
12
|
+
* No runtime invariant: every contribution (frontend-static child plugin,
|
|
13
|
+
* prompt section, bashEnv registration) is registry-disposed with the fiber,
|
|
14
|
+
* and each owning registry's package carries that relation's invariant; the
|
|
15
|
+
* package holds no mutable state of its own to audit.
|
|
16
|
+
*/
|
|
17
|
+
const install = () => {};
|
|
18
|
+
/**
|
|
19
|
+
* Register this package's invariant companion.
|
|
20
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
21
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
22
|
+
*/
|
|
23
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
24
|
+
//#endregion
|
|
25
|
+
export { apply, inject, name };
|
package/lib/startup.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { parseCmdline } from "@deepseek-ai/dsh-cmdline";
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
//#region lib/types/startup.js
|
|
4
|
+
/**
|
|
5
|
+
* The web app's command-line provider: it parses the `dsh --profile web` flag
|
|
6
|
+
* family (`--host`, `--port`, `--dev`, `--trusted-host`) and its `--help`
|
|
7
|
+
* text, then provides the immutable values as {@link WEB_STARTUP_SERVICE}.
|
|
8
|
+
* Ordinary rows inject that service before reading it from lazy config.
|
|
9
|
+
* @module @deepseek-ai/dsh-web-app/startup
|
|
10
|
+
*/
|
|
11
|
+
/** Stable Cordis plugin name. */
|
|
12
|
+
const name = "web-startup";
|
|
13
|
+
/** Services required before the flags can be resolved. */
|
|
14
|
+
const inject = ["cmdlineArgs"];
|
|
15
|
+
/** Service provided by this ordinary plugin and injected by flag-configured rows. */
|
|
16
|
+
const WEB_STARTUP_SERVICE = "webStartup";
|
|
17
|
+
/**
|
|
18
|
+
* This app's command: its flags, its description, and its help text.
|
|
19
|
+
* @returns a fresh program, so one process can parse more than once (tests).
|
|
20
|
+
*/
|
|
21
|
+
function webCommand() {
|
|
22
|
+
return new Command().name("dsh --profile web").description("Serve the DeepSeek Harness browser UI.").helpOption("-h, --help", "show this help").option("--host <host>", "bind host; pass 0.0.0.0 to reach it from another machine").option("--port <port>", "listen port; pass 0 to let the OS pick a free one").option("--dev", "mount the client-plugin HMR receiver (run pnpm run dev:web separately to rebuild bundles)").option("--trusted-host <authority...>", "extra authority the /api browser-trust fence accepts (host or host:port; repeatable)").addHelpText("after", `
|
|
23
|
+
Examples:
|
|
24
|
+
dsh --profile web serve on the composed host and port
|
|
25
|
+
dsh --profile web --port 8080 serve on another port
|
|
26
|
+
dsh --profile web --host 0.0.0.0 reach it from another machine on the LAN
|
|
27
|
+
dsh --profile web --dev mount the client-plugin HMR receiver
|
|
28
|
+
`);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Turn the parsed flags into the value injected rows read.
|
|
32
|
+
* @param program - the parsed web command.
|
|
33
|
+
* @returns this invocation's immutable Web options.
|
|
34
|
+
*/
|
|
35
|
+
function planWebStartup(program) {
|
|
36
|
+
const options = program.opts();
|
|
37
|
+
if (options.port !== void 0 && !/^\d+$/.test(options.port)) program.error(`error: --port must be a number, got ${JSON.stringify(options.port)}`);
|
|
38
|
+
return {
|
|
39
|
+
...options.host !== void 0 && { host: options.host },
|
|
40
|
+
...options.port !== void 0 && { port: Number(options.port) },
|
|
41
|
+
mode: options.dev === true ? "development" : "production",
|
|
42
|
+
trustedHosts: options.trustedHost ?? []
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Parse and provide the Web invocation as an ordinary Cordis service.
|
|
47
|
+
* @param ctx - plugin context carrying the command line.
|
|
48
|
+
* @returns nothing once values are provided, or when the command requested exit.
|
|
49
|
+
*/
|
|
50
|
+
function apply(ctx) {
|
|
51
|
+
const values = parseCmdline(ctx, webCommand(), planWebStartup);
|
|
52
|
+
if (values !== void 0) ctx.provide(WEB_STARTUP_SERVICE, values);
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { WEB_STARTUP_SERVICE, apply, inject, name };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deepseek-ai/dsh-web-app — the browser-surface bundle's runtime glue plugin
|
|
3
|
+
* plus the bundle patch (`cordis.patch.yml`, declared by the `dsh.bundle.patch`
|
|
4
|
+
* manifest field). The plugin owns the browser-surface glue: it resolves
|
|
5
|
+
* the built frontend dist (workspace knowledge of this bundle, never user
|
|
6
|
+
* config), mounts the `frontend-static` fallback owner over it, registers the
|
|
7
|
+
* harness-source and web-surface prompt sections, the bash-visible web runtime
|
|
8
|
+
* variables, and the URL line. App command-line values arrive through the
|
|
9
|
+
* `webStartup` service expressions in the bundle patch.
|
|
10
|
+
* @module @deepseek-ai/dsh-web-app
|
|
11
|
+
*/
|
|
12
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
+
import z from '@deepseek-ai/schemastery';
|
|
14
|
+
/** Stable Cordis plugin name. */
|
|
15
|
+
export declare const name = "web-app";
|
|
16
|
+
/** Services required before the web runtime can mount. */
|
|
17
|
+
export declare const inject: string[];
|
|
18
|
+
/** Web runtime mode: production, or development when the client-plugin HMR receiver is active. */
|
|
19
|
+
export type WebMode = 'production' | 'development';
|
|
20
|
+
/** Plugin config: composed deployment settings plus per-invocation command-line values. */
|
|
21
|
+
export interface Config {
|
|
22
|
+
/** Whether this process mounted the client-plugin HMR receiver (`dsh web --dev`). */
|
|
23
|
+
mode: WebMode;
|
|
24
|
+
/** Print the URL line on activation; a non-interactive layer can turn it off. */
|
|
25
|
+
printUrl: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Register the model-visible surface context (the `app:web-surface` prompt
|
|
28
|
+
* section and the `DSH_WEB_URL`/`DSH_WEB_MODE` bash variables). A one-shot
|
|
29
|
+
* non-interactive layer can turn it off when its user is not in the GUI, so the
|
|
30
|
+
* orientation text would be false.
|
|
31
|
+
*/
|
|
32
|
+
surfaceContext: boolean;
|
|
33
|
+
/** Explicit `--trusted-host` authorities from this invocation. */
|
|
34
|
+
trustedHosts: string[];
|
|
35
|
+
}
|
|
36
|
+
export declare const Config: z<Config>;
|
|
37
|
+
/** Bind-dependent Web values shared by the trust fence and URL display. */
|
|
38
|
+
export interface WebRuntimeValues {
|
|
39
|
+
/** LAN IPv4 literals sampled once when the server binds all interfaces. */
|
|
40
|
+
lanAddresses: string[];
|
|
41
|
+
/** LAN literals followed by explicit invocation authorities. */
|
|
42
|
+
trustedHosts: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Resolve one LAN-trust snapshot from the active server bind.
|
|
46
|
+
*
|
|
47
|
+
* Derived entries are port-less IP literals: DNS rebinding needs an
|
|
48
|
+
* attacker-controlled name, while an IP-literal Host is safe on any port and
|
|
49
|
+
* an OS-assigned port is unknowable before bind.
|
|
50
|
+
* @param bindHost - the active webserver bind host.
|
|
51
|
+
* @param extra - explicit `--trusted-host` values, in argument order.
|
|
52
|
+
* @returns the LAN display addresses and invocation-derived fence authorities.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveLanTrust(bindHost: string, extra: readonly string[]): WebRuntimeValues;
|
|
55
|
+
/** Test hook: hosts with no built frontend dist substitute the resolver; production never touches this. */
|
|
56
|
+
export declare const internals: {
|
|
57
|
+
resolveDistIndex: () => string;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Mount the Web runtime: dist serving, surface prompt, bash runtime
|
|
61
|
+
* variables, and the URL line.
|
|
62
|
+
* @param ctx - plugin context carrying the httpServer service.
|
|
63
|
+
* @param config - validated {@link Config}.
|
|
64
|
+
* @returns nothing once the invocation's client roster and runtime contributions are registered.
|
|
65
|
+
*/
|
|
66
|
+
export declare function apply(ctx: Context, config: Config): Promise<void>;
|
|
67
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for `@deepseek-ai/dsh-web-app`.
|
|
3
|
+
* @module @deepseek-ai/dsh-web-app/invariant
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
6
|
+
/** Cordis companion plugin name. */
|
|
7
|
+
export declare const name = "web-app-invariant";
|
|
8
|
+
/** Service required before the companion can register. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Register this package's invariant companion.
|
|
12
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
13
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
14
|
+
*/
|
|
15
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
16
|
+
//# sourceMappingURL=invariant.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The web app's command-line provider: it parses the `dsh --profile web` flag
|
|
3
|
+
* family (`--host`, `--port`, `--dev`, `--trusted-host`) and its `--help`
|
|
4
|
+
* text, then provides the immutable values as {@link WEB_STARTUP_SERVICE}.
|
|
5
|
+
* Ordinary rows inject that service before reading it from lazy config.
|
|
6
|
+
* @module @deepseek-ai/dsh-web-app/startup
|
|
7
|
+
*/
|
|
8
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
9
|
+
/** Stable Cordis plugin name. */
|
|
10
|
+
export declare const name = "web-startup";
|
|
11
|
+
/** Services required before the flags can be resolved. */
|
|
12
|
+
export declare const inject: string[];
|
|
13
|
+
/** Service provided by this ordinary plugin and injected by flag-configured rows. */
|
|
14
|
+
export declare const WEB_STARTUP_SERVICE = "webStartup";
|
|
15
|
+
/** What the web rows read from {@link WEB_STARTUP_SERVICE}. */
|
|
16
|
+
export interface WebStartupValues {
|
|
17
|
+
/** `--host`, absent when the invocation did not name one. */
|
|
18
|
+
host?: string;
|
|
19
|
+
/** `--port`, absent when the invocation did not name one. */
|
|
20
|
+
port?: number;
|
|
21
|
+
/** Web runtime mode; `--dev` selects development, which also mounts the client-plugin reload chain. */
|
|
22
|
+
mode: 'production' | 'development';
|
|
23
|
+
/** Explicit `--trusted-host` authorities, in argument order. */
|
|
24
|
+
trustedHosts: string[];
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Parse and provide the Web invocation as an ordinary Cordis service.
|
|
28
|
+
* @param ctx - plugin context carrying the command line.
|
|
29
|
+
* @returns nothing once values are provided, or when the command requested exit.
|
|
30
|
+
*/
|
|
31
|
+
export declare function apply(ctx: Context): void;
|
|
32
|
+
//# sourceMappingURL=startup.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deepseek-ai/dsh-web-app",
|
|
3
|
+
"description": "The dsh browser-surface bundle: the web patch layer over dsh-base plus the runtime glue plugin (frontend dist serving, web-surface prompt, bash runtime variables, URL line)",
|
|
4
|
+
"version": "0.0.1-rc.1",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "restricted"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/bundle/web-app"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./startup": {
|
|
22
|
+
"types": "./lib/types/startup.d.ts",
|
|
23
|
+
"default": "./lib/startup.js"
|
|
24
|
+
},
|
|
25
|
+
"./invariant": {
|
|
26
|
+
"types": "./lib/types/invariant.d.ts",
|
|
27
|
+
"default": "./lib/invariant.js"
|
|
28
|
+
},
|
|
29
|
+
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
30
|
+
"./src/*": "./src/*",
|
|
31
|
+
"./package.json": "./package.json"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"lib/index.js",
|
|
35
|
+
"lib/invariant.js",
|
|
36
|
+
"lib/startup.js",
|
|
37
|
+
"cordis.patch.yml",
|
|
38
|
+
"lib/types/**/*.d.ts"
|
|
39
|
+
],
|
|
40
|
+
"license": "BSD-3-Clause",
|
|
41
|
+
"dsh": {
|
|
42
|
+
"bundle": {
|
|
43
|
+
"patch": "./cordis.patch.yml"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"commander": "^15.0.0",
|
|
48
|
+
"@deepseek-ai/dsh-app-boot": "^0.0.1-rc.1",
|
|
49
|
+
"@deepseek-ai/dsh-client-connection": "^0.0.1-rc.1",
|
|
50
|
+
"@deepseek-ai/dsh-agent-presets": "^0.0.1-rc.1",
|
|
51
|
+
"@deepseek-ai/dsh-client-hmr": "^0.0.1-rc.1",
|
|
52
|
+
"@deepseek-ai/dsh-client-locale": "^0.0.1-rc.1",
|
|
53
|
+
"@deepseek-ai/dsh-client-modules": "^0.0.1-rc.1",
|
|
54
|
+
"@deepseek-ai/dsh-api-remotes": "^0.0.1-rc.1",
|
|
55
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.1",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-agent-preset": "^0.0.1-rc.1",
|
|
57
|
+
"@deepseek-ai/dsh-client-ui-command": "^0.0.1-rc.1",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-conversation": "^0.0.1-rc.1",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-deliverables": "^0.0.1-rc.1",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-goal": "^0.0.1-rc.1",
|
|
61
|
+
"@deepseek-ai/dsh-client-ui-model": "^0.0.1-rc.1",
|
|
62
|
+
"@deepseek-ai/dsh-client-ui-models": "^0.0.1-rc.1",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-layout": "^0.0.1-rc.1",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-permission": "^0.0.1-rc.1",
|
|
65
|
+
"@deepseek-ai/dsh-client-ui-plan": "^0.0.1-rc.1",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-question": "^0.0.1-rc.1",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.0.1-rc.1",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "^0.0.1-rc.1",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-skill": "^0.0.1-rc.1",
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-settings-general": "^0.0.1-rc.1",
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-subagent": "^0.0.1-rc.1",
|
|
72
|
+
"@deepseek-ai/dsh-client-ui-slash": "^0.0.1-rc.1",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-theme": "^0.0.1-rc.1",
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-tool": "^0.0.1-rc.1",
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-trajectory": "^0.0.1-rc.1",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-workspace": "^0.0.1-rc.1",
|
|
77
|
+
"@deepseek-ai/dsh-cmdline": "^0.0.1-rc.1",
|
|
78
|
+
"@deepseek-ai/dsh-code-runtime-worker": "^0.0.1-rc.1",
|
|
79
|
+
"@deepseek-ai/dsh-frontend": "^0.0.1-rc.1",
|
|
80
|
+
"@deepseek-ai/dsh-frontend-static": "^0.0.1-rc.1",
|
|
81
|
+
"@deepseek-ai/dsh-host-apiproxy": "^0.0.1-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-host-directory-picker-auto": "^0.0.1-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-host-directory-picker-browse": "^0.0.1-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-host-directory-picker-native": "^0.0.1-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-host-webserver": "^0.0.1-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-session-projection-cache": "^0.0.1-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-storage": "^0.0.1-rc.1",
|
|
88
|
+
"@deepseek-ai/dsh-storage-domain": "^0.0.1-rc.1",
|
|
89
|
+
"@deepseek-ai/dsh-storage-json": "^0.0.1-rc.1",
|
|
90
|
+
"@deepseek-ai/dsh-workspace": "^0.0.1-rc.1",
|
|
91
|
+
"@deepseek-ai/schemastery": "^3.18.1-rc.1"
|
|
92
|
+
},
|
|
93
|
+
"peerDependencies": {
|
|
94
|
+
"@deepseek-ai/dsh-bash-env": "^0.0.1-rc.1",
|
|
95
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
|
|
96
|
+
"@deepseek-ai/dsh-system-prompt": "^0.0.1-rc.1",
|
|
97
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1",
|
|
98
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.1-rc.1"
|
|
99
|
+
},
|
|
100
|
+
"devDependencies": {
|
|
101
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.1-rc.1",
|
|
102
|
+
"@deepseek-ai/dsh-bash-env": "^0.0.1-rc.1",
|
|
103
|
+
"@deepseek-ai/dsh-invariants": "^0.0.1-rc.1",
|
|
104
|
+
"@deepseek-ai/dsh-system-prompt": "^0.0.1-rc.1",
|
|
105
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1"
|
|
106
|
+
}
|
|
107
|
+
}
|