dsh-edge 0.6.0 → 0.7.0-alpha.2

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/README.i18n.yaml CHANGED
@@ -2,5 +2,5 @@
2
2
  # last confirmed-consistent state. Both languages carry equal authority.
3
3
  # After editing either side, update both and re-record every pair with:
4
4
  # pnpm run doc-pairs -- --write
5
- README.md: f870511de0609d04c9fed66ec1b08a50be3378d6
6
- README.zh.md: 537bee540b01ca55b65d8c08e3e35b16da88fcf6
5
+ README.md: 6807b0997435ce00f9eb1760f25136ad11f05a86
6
+ README.zh.md: 5fcb54f1475f3ff5961a238d2f544daa67f0a9f7
package/README.md CHANGED
@@ -122,7 +122,7 @@ This reference separates code that runs natively in Workers, code adapted at an
122
122
  | DSH transport | Typed HTTP RPC plus mux and host WebSocket downlinks | Reused with an Edge server implementation | Use the upstream fetch carrier for unary methods and preserve its envelopes, schemas, projections, lazy blank-session behavior, bounded content search, prompt and queue mutations, workspace mutations, queue snapshots, and event frames. Durable Object WebSocket hibernation owns both downlinks; mux reconnects replay pending live inbox state, while REST/SSE routes remain a diagnostic compatibility path. |
123
123
  | Workspace registry | Storage-domain global state plus `WorkspaceRecord` rows | Native backend adaptation | Keep the upstream global and record value shapes, including manual session order and archive membership, but map their physical keys and atomic writes to Durable Object storage. Edge constrains the registry to the one native `/workspace` VFS; rename, delete, recreation, and session reordering retain the upstream RPC and Host-frame semantics. |
124
124
  | Existing Web UI | Runtime-loaded shell and `dsh.client` plugin graph | Reused with generic composition fallbacks | Assemble the upstream shell and supported upstream client bundles as Worker assets. Shared slot-occupancy rules hide actions whose provider is absent; Cloudflare serves ordinary assets directly, while `/`, `/login`, and `/api/*` enter the Worker for owner access control. The assembled asset policy prevents every direct or SPA-fallback shell alias from being framed. |
125
- | Other tools | Web Search, filesystem editor tools, MCP, skills, workflows, jobs, and subagents | Search ported; others not ported | Reuse upstream DeepSeek Web Search with its 30-second tool-call timeout. Add the remaining tools individually against Worker-compatible capabilities; do not advertise unavailable host behavior. |
125
+ | Other tools | Web Search, filesystem editor tools, MCP, skills, workflows, jobs, and subagents | Search + file tools ported; others not ported | Reuse upstream DeepSeek Web Search with its 30-second tool-call timeout. File tools (read/write/edit/read_image) adapted via `EdgeFileSystem` backed by Computer VFS. Add the remaining tools individually against Worker-compatible capabilities; do not advertise unavailable host behavior. |
126
126
  | Attachments | Local attachment storage, upstream image references, composer, gallery, lightbox, and provider conversion | Adapted at the native storage seam | Reuse upstream `AttachmentStore`, admission, protocol, authorization, UI, and DeepSeek conversion unchanged. Store immutable PNG/JPEG bytes under their SHA-256 identities in private R2 for new permanent deployments or in a 64 MiB, 512 KiB-chunked DO backend for temporary deployments and owners who select it while upgrading a pre-attachment Worker; session events retain only upstream refs. The first backend is pinned per owner instance so claiming or upgrading cannot strand existing references. |
127
127
  | Authentication and tenancy | Local trusted-user boundary | Single-owner adaptation | Require one high-entropy Worker secret, exchange it for a signed 30-day HttpOnly `SameSite=Strict` cookie, and route every accepted request to one fixed owner object. This intentionally provides no registration, user database, roles, or multi-tenant routing. |
128
128
 
@@ -143,7 +143,7 @@ Cloudflare static assets -> upstream Web shell + client plugin graph
143
143
  -> upstream dsh-llm-deepseek plugin resolves configuration from settings + launch environment
144
144
  -> upstream attachment resolver reads and verifies authorized backend bytes
145
145
  -> upstream LlmRuntime + ReactLoopAgent stream/event pipeline
146
- -> upstream ToolRuntime native bash or web_search call
146
+ -> upstream ToolRuntime native bash, read/write/edit, or web_search call
147
147
  -> upstream WebRuntime + DeepSeek native search provider for web_search
148
148
  -> direct just-bash backend in the owner Durable Object
149
149
  (or optional Computer Worker Shell when LOADER is bound)
package/README.zh.md CHANGED
@@ -122,7 +122,7 @@ curl -b /tmp/dsh-edge-cookie -N -X POST -H 'content-type: application/json' \
122
122
  | DSH transport | Typed HTTP RPC 加 mux/host WebSocket downlink | 复用并提供 Edge 服务端实现 | 对 unary method 使用上游 fetch carrier,并保留其 envelope、schema、projection、lazy blank-session 行为、有界内容搜索、prompt 与 queue mutation、workspace mutation、queue snapshot 和 event frame。两条 downlink 都由 Durable Object WebSocket 休眠机制持有;mux 重连会重放 live inbox 的待处理状态,REST/SSE 路由则保留为诊断兼容路径。 |
123
123
  | Workspace registry | Storage-domain global state 加 `WorkspaceRecord` rows | 原生 backend 适配 | 保持上游 global 和 record value shape,包括手动 session 顺序与 archive membership;仅把物理 key 和原子写入映射到 Durable Object storage。Edge 把 registry 限制为一个原生 `/workspace` VFS;rename、delete、recreate 与 session reorder 保持上游 RPC 和 Host-frame 语义。 |
124
124
  | Existing Web UI | 运行时加载的 shell 和 `dsh.client` 插件 graph | 复用并采用通用 composition fallback | 把上游 shell 和受支持的上游客户端包组装成 Worker 静态资源;共享的 slot occupancy 规则会隐藏缺少 provider 的 action。Cloudflare 直接提供普通资源,`/`、`/login` 与 `/api/*` 则进入 Worker 执行 owner access control。组装后的 asset policy 会阻止所有直接或 SPA-fallback shell alias 被嵌入 frame。 |
125
- | Other tools | Web Search、filesystem editor tools、MCP、skills、workflows、jobs 和 subagents | Search 已移植;其他未移植 | 复用上游 DeepSeek Web Search 及其 30 秒 tool-call timeout。逐个针对 Worker-compatible capabilities 增加其余工具,不宣称不可用的 host 行为。 |
125
+ | Other tools | Web Search、filesystem editor tools、MCP、skills、workflows、jobs 和 subagents | Search + 文件工具已移植;其他未移植 | 复用上游 DeepSeek Web Search 及其 30 秒 tool-call timeout。文件工具(read/write/edit/read_image)通过 `EdgeFileSystem` 适配 Computer VFS。逐个针对 Worker-compatible capabilities 增加其余工具,不宣称不可用的 host 行为。 |
126
126
  | Attachments | 本地 attachment storage、上游 image reference、composer、gallery、lightbox 与 provider conversion | 在原生 storage seam 上适配 | 原样复用上游 `AttachmentStore`、admission、协议、授权、UI 与 DeepSeek conversion。PNG/JPEG 不可变字节按 SHA-256 identity 存入新永久部署的私有 R2,或存入临时部署以及升级旧版 Worker 时由 owner 选择的 64 MiB、按 512 KiB 分块的 DO backend;session event 只保留上游 ref。每个 owner instance 首次选择的 backend 会被固定,认领或升级不会让既有引用失联。 |
127
127
  | Authentication and tenancy | 本地 trusted-user boundary | 单 owner 适配 | 要求一个高熵 Worker secret,把它交换为带签名、有效期 30 天的 HttpOnly `SameSite=Strict` cookie,并把所有已接纳请求路由到一个固定 owner object。这里刻意不提供注册、用户数据库、角色或多租户路由。 |
128
128
 
@@ -143,7 +143,7 @@ Cloudflare static assets -> upstream Web shell + client plugin graph
143
143
  -> upstream dsh-llm-deepseek plugin resolves configuration from settings + launch environment
144
144
  -> 上游 attachment resolver 读取并校验已授权的 backend 字节
145
145
  -> upstream LlmRuntime + ReactLoopAgent stream/event pipeline
146
- -> upstream ToolRuntime native bash or web_search call
146
+ -> upstream ToolRuntime native bash, read/write/edit, or web_search call
147
147
  -> upstream WebRuntime + DeepSeek native search provider for web_search
148
148
  -> direct just-bash backend in the owner Durable Object
149
149
  (or optional Computer Worker Shell when LOADER is bound)
@@ -7,7 +7,7 @@
7
7
 
8
8
  ## DeepSeek Harness
9
9
 
10
- `dsh-edge` assembles published DeepSeek Harness packages and applies 5 version-bound adaptations to the pinned `0.1.1-rc.2` release. DeepSeek Harness remains under its upstream MIT license:
10
+ `dsh-edge` assembles published DeepSeek Harness packages and applies 6 version-bound adaptations to the pinned `0.1.1-rc.2` release. DeepSeek Harness remains under its upstream MIT license:
11
11
 
12
12
  ```text
13
13
  MIT License
package/dist/index.html CHANGED
@@ -39,7 +39,7 @@ window.__ModuleLoader__={
39
39
  return exports.createClientModuleSystem(this,{id:registration.id,exports},options)
40
40
  }
41
41
  }
42
- })()</script><script src="/plugins/@deepseek-ai/dsh-client-modules/client.js?rev=7eb526320903"></script><script src="/plugins/@deepseek-ai/dsh-client-runtime/client.js?rev=aba836a0c42d"></script><script>globalThis["__DSH_BOOT__"] = {"rev":"f1fb92ab810b","entries":[{"id":"@deepseek-ai/dsh-typert-registry","url":"/plugins/@deepseek-ai/dsh-typert-registry/client.js?rev=f41d56e0b747","rev":"f41d56e0b747","inject":[],"immediately":true},{"id":"@deepseek-ai/dsh-api-gateway","url":"/plugins/@deepseek-ai/dsh-api-gateway/client.js?rev=965b70361a00","rev":"965b70361a00","inject":["@deepseek-ai/dsh-typert-registry","@deepseek-ai/dsh-client-connection"],"immediately":true},{"id":"@deepseek-ai/dsh-client-modules","url":"/plugins/@deepseek-ai/dsh-client-modules/client.js?rev=7eb526320903","rev":"7eb526320903","inject":[],"immediately":true},{"id":"@deepseek-ai/dsh-client-connection","url":"/plugins/@deepseek-ai/dsh-client-connection/client.js?rev=70b02b2d3fc2","rev":"70b02b2d3fc2","inject":[],"immediately":true},{"id":"@deepseek-ai/dsh-api-remotes","url":"/plugins/@deepseek-ai/dsh-api-remotes/client.js?rev=9a16f4532366","rev":"9a16f4532366","inject":["@deepseek-ai/dsh-api-gateway"],"immediately":true},{"id":"@deepseek-ai/dsh-client-runtime","url":"/plugins/@deepseek-ai/dsh-client-runtime/client.js?rev=aba836a0c42d","rev":"aba836a0c42d","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-typert-registry","@deepseek-ai/dsh-api-remotes"],"immediately":true},{"id":"@deepseek-ai/dsh-client-ui-theme","url":"/plugins/@deepseek-ai/dsh-client-ui-theme/client.js?rev=e19c47b60a1c","rev":"e19c47b60a1c","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"],"immediately":true},{"id":"@deepseek-ai/dsh-client-locale","url":"/plugins/@deepseek-ai/dsh-client-locale/client.js?rev=2660ca3f6a00","rev":"2660ca3f6a00","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"],"immediately":true},{"id":"@deepseek-ai/dsh-client-ui-layout","url":"/plugins/@deepseek-ai/dsh-client-ui-layout/client.js?rev=abdb7f55acba","rev":"abdb7f55acba","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-theme"]},{"id":"@deepseek-ai/dsh-client-ui-renderer","url":"/plugins/@deepseek-ai/dsh-client-ui-renderer/client.js?rev=79b59d365f3b","rev":"79b59d365f3b","inject":["@deepseek-ai/dsh-client-runtime"],"immediately":true},{"id":"@deepseek-ai/dsh-client-ui-sidebar","url":"/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js?rev=7563cb4b02ca","rev":"7563cb4b02ca","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-layout","@deepseek-ai/dsh-client-locale"]},{"id":"@deepseek-ai/dsh-client-ui-settings","url":"/plugins/@deepseek-ai/dsh-client-ui-settings/client.js?rev=5d1695c62b38","rev":"5d1695c62b38","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-settings-general","url":"/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js?rev=f733efde3f2f","rev":"f733efde3f2f","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-ui-sidebar"]},{"id":"@deepseek-ai/dsh-client-ui-settings-models","url":"/plugins/@deepseek-ai/dsh-client-ui-settings-models/client.js?rev=f12fb342db3b","rev":"f12fb342db3b","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-conversation","url":"/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js?rev=cf4575517765","rev":"cf4575517765","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-ui-layout"]},{"id":"@deepseek-ai/dsh-client-ui-brand-official","url":"/plugins/@deepseek-ai/dsh-client-ui-brand-official/client.js?rev=c426d52ce216","rev":"c426d52ce216","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-sidebar"]},{"id":"@deepseek-ai/dsh-client-ui-attachment","url":"/plugins/@deepseek-ai/dsh-client-ui-attachment/client.js?rev=5349ce7aa495","rev":"5349ce7aa495","inject":["@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-tool","url":"/plugins/@deepseek-ai/dsh-client-ui-tool/client.js?rev=48c8d92e8828","rev":"48c8d92e8828","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-workflow-run","url":"/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js?rev=60e130ad4f36","rev":"60e130ad4f36","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-deliverables","url":"/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js?rev=13a78ee19f2e","rev":"13a78ee19f2e","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-workspace","url":"/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js?rev=2e1cd4f55f0c","rev":"2e1cd4f55f0c","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-sidebar"]},{"id":"@deepseek-ai/dsh-client-ui-input-trigger","url":"/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js?rev=b9564b9138a7","rev":"b9564b9138a7","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale"]},{"id":"@deepseek-ai/dsh-client-ui-commands","url":"/plugins/@deepseek-ai/dsh-client-ui-commands/client.js?rev=887c0ca028a4","rev":"887c0ca028a4","inject":["@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-input-trigger","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-skill","url":"/plugins/@deepseek-ai/dsh-client-ui-skill/client.js?rev=f229a70eecce","rev":"f229a70eecce","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-tool","@deepseek-ai/dsh-client-ui-input-trigger","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-subagent","url":"/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js?rev=0bb1ff842ae8","rev":"0bb1ff842ae8","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives","@deepseek-ai/dsh-client-ui-input-trigger"]},{"id":"@deepseek-ai/dsh-client-ui-jobs","url":"/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js?rev=ed0d04a8c154","rev":"ed0d04a8c154","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives"]},{"id":"@deepseek-ai/dsh-client-ui-model-selection","url":"/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js?rev=639da97bfe66","rev":"639da97bfe66","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-commands","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-permission-presets","url":"/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js?rev=e36eeb24d0eb","rev":"e36eeb24d0eb","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-commands","@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-ui-settings"]},{"id":"@deepseek-ai/dsh-client-ui-agent-preset","url":"/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js?rev=96dbaff92d41","rev":"96dbaff92d41","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-user-questions","url":"/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js?rev=350ccf0385ba","rev":"350ccf0385ba","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-trajectory","url":"/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js?rev=3345fd0d652c","rev":"3345fd0d652c","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"dsh-edge-client-ui","url":"/plugins/dsh-edge-client-ui/client.js?rev=dc3c48739f02","rev":"dc3c48739f02","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-locale"]}]}</script>
42
+ })()</script><script src="/plugins/@deepseek-ai/dsh-client-modules/client.js?rev=7eb526320903"></script><script src="/plugins/@deepseek-ai/dsh-client-runtime/client.js?rev=aba836a0c42d"></script><script>globalThis["__DSH_BOOT__"] = {"rev":"8ba2475029b8","entries":[{"id":"@deepseek-ai/dsh-typert-registry","url":"/plugins/@deepseek-ai/dsh-typert-registry/client.js?rev=f41d56e0b747","rev":"f41d56e0b747","inject":[],"immediately":true},{"id":"@deepseek-ai/dsh-api-gateway","url":"/plugins/@deepseek-ai/dsh-api-gateway/client.js?rev=965b70361a00","rev":"965b70361a00","inject":["@deepseek-ai/dsh-typert-registry","@deepseek-ai/dsh-client-connection"],"immediately":true},{"id":"@deepseek-ai/dsh-client-modules","url":"/plugins/@deepseek-ai/dsh-client-modules/client.js?rev=7eb526320903","rev":"7eb526320903","inject":[],"immediately":true},{"id":"@deepseek-ai/dsh-client-connection","url":"/plugins/@deepseek-ai/dsh-client-connection/client.js?rev=70b02b2d3fc2","rev":"70b02b2d3fc2","inject":[],"immediately":true},{"id":"@deepseek-ai/dsh-api-remotes","url":"/plugins/@deepseek-ai/dsh-api-remotes/client.js?rev=9a16f4532366","rev":"9a16f4532366","inject":["@deepseek-ai/dsh-api-gateway"],"immediately":true},{"id":"@deepseek-ai/dsh-client-runtime","url":"/plugins/@deepseek-ai/dsh-client-runtime/client.js?rev=aba836a0c42d","rev":"aba836a0c42d","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-typert-registry","@deepseek-ai/dsh-api-remotes"],"immediately":true},{"id":"@deepseek-ai/dsh-client-ui-theme","url":"/plugins/@deepseek-ai/dsh-client-ui-theme/client.js?rev=e19c47b60a1c","rev":"e19c47b60a1c","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"],"immediately":true},{"id":"@deepseek-ai/dsh-client-locale","url":"/plugins/@deepseek-ai/dsh-client-locale/client.js?rev=2660ca3f6a00","rev":"2660ca3f6a00","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"],"immediately":true},{"id":"@deepseek-ai/dsh-client-ui-layout","url":"/plugins/@deepseek-ai/dsh-client-ui-layout/client.js?rev=abdb7f55acba","rev":"abdb7f55acba","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-theme"]},{"id":"@deepseek-ai/dsh-client-ui-renderer","url":"/plugins/@deepseek-ai/dsh-client-ui-renderer/client.js?rev=79b59d365f3b","rev":"79b59d365f3b","inject":["@deepseek-ai/dsh-client-runtime"],"immediately":true},{"id":"@deepseek-ai/dsh-client-ui-sidebar","url":"/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js?rev=7563cb4b02ca","rev":"7563cb4b02ca","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-layout","@deepseek-ai/dsh-client-locale"]},{"id":"@deepseek-ai/dsh-client-ui-settings","url":"/plugins/@deepseek-ai/dsh-client-ui-settings/client.js?rev=5d1695c62b38","rev":"5d1695c62b38","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-settings-general","url":"/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js?rev=f733efde3f2f","rev":"f733efde3f2f","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-ui-sidebar"]},{"id":"@deepseek-ai/dsh-client-ui-settings-models","url":"/plugins/@deepseek-ai/dsh-client-ui-settings-models/client.js?rev=f12fb342db3b","rev":"f12fb342db3b","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-conversation","url":"/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js?rev=cf4575517765","rev":"cf4575517765","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-ui-layout"]},{"id":"@deepseek-ai/dsh-client-ui-brand-official","url":"/plugins/@deepseek-ai/dsh-client-ui-brand-official/client.js?rev=c426d52ce216","rev":"c426d52ce216","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-sidebar"]},{"id":"@deepseek-ai/dsh-client-ui-attachment","url":"/plugins/@deepseek-ai/dsh-client-ui-attachment/client.js?rev=5349ce7aa495","rev":"5349ce7aa495","inject":["@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-tool","url":"/plugins/@deepseek-ai/dsh-client-ui-tool/client.js?rev=48c8d92e8828","rev":"48c8d92e8828","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-workflow-run","url":"/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js?rev=60e130ad4f36","rev":"60e130ad4f36","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-deliverables","url":"/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js?rev=13a78ee19f2e","rev":"13a78ee19f2e","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-workspace","url":"/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js?rev=2e1cd4f55f0c","rev":"2e1cd4f55f0c","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-sidebar"]},{"id":"@deepseek-ai/dsh-client-ui-input-trigger","url":"/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js?rev=b9564b9138a7","rev":"b9564b9138a7","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale"]},{"id":"@deepseek-ai/dsh-client-ui-commands","url":"/plugins/@deepseek-ai/dsh-client-ui-commands/client.js?rev=887c0ca028a4","rev":"887c0ca028a4","inject":["@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-input-trigger","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-skill","url":"/plugins/@deepseek-ai/dsh-client-ui-skill/client.js?rev=f229a70eecce","rev":"f229a70eecce","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-tool","@deepseek-ai/dsh-client-ui-input-trigger","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-subagent","url":"/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js?rev=0bb1ff842ae8","rev":"0bb1ff842ae8","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives","@deepseek-ai/dsh-client-ui-input-trigger"]},{"id":"@deepseek-ai/dsh-client-ui-jobs","url":"/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js?rev=ed0d04a8c154","rev":"ed0d04a8c154","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-primitives"]},{"id":"@deepseek-ai/dsh-client-ui-goal","url":"/plugins/@deepseek-ai/dsh-client-ui-goal/client.js?rev=31aac5c02463","rev":"31aac5c02463","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-model-selection","url":"/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js?rev=639da97bfe66","rev":"639da97bfe66","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-commands","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-permission-presets","url":"/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js?rev=e36eeb24d0eb","rev":"e36eeb24d0eb","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-commands","@deepseek-ai/dsh-api-remotes","@deepseek-ai/dsh-client-ui-settings"]},{"id":"@deepseek-ai/dsh-client-ui-agent-preset","url":"/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js?rev=96dbaff92d41","rev":"96dbaff92d41","inject":["@deepseek-ai/dsh-client-connection","@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-api-remotes"]},{"id":"@deepseek-ai/dsh-client-ui-user-questions","url":"/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js?rev=350ccf0385ba","rev":"350ccf0385ba","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"@deepseek-ai/dsh-client-ui-trajectory","url":"/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js?rev=3345fd0d652c","rev":"3345fd0d652c","inject":["@deepseek-ai/dsh-client-locale","@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-conversation"]},{"id":"dsh-edge-client-ui","url":"/plugins/dsh-edge-client-ui/client.js?rev=5402e80fc597","rev":"5402e80fc597","inject":["@deepseek-ai/dsh-client-runtime","@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-locale"]}]}</script>
43
43
  <meta charset="utf-8" />
44
44
  <meta name="viewport" content="width=device-width, initial-scale=1" />
45
45
  <link rel="manifest" href="/manifest.webmanifest" />
@@ -0,0 +1,448 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "@deepseek-ai/dsh-client-ui-goal",
3
+ factory: (require) => {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react_jsx_runtime = require("react/jsx-runtime");
8
+ let react = require("react");
9
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
10
+ //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-goal/src/client/GoalBar.module.css.mjs
11
+ const css$1 = ".nLMEza_dock{box-sizing:border-box;width:calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));margin:0 auto}.nLMEza_bar{box-sizing:border-box;width:100%;max-width:calc(var(--dsh-composer-card-max-width) - 4 * var(--dsh-composer-dock-inset));border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-specific-tip);border-radius:12px;align-items:center;gap:10px;height:36px;margin:0 auto;padding:4px 5px 4px 12px;display:flex}.nLMEza_goalGlyph{color:var(--dsw-alias-label-tertiary);flex:none;display:inline-flex}.nLMEza_label{color:var(--dsw-alias-label-primary);flex:none;font-size:13px;font-weight:500;line-height:24px}.nLMEza_objective{min-width:0;color:var(--dsw-alias-label-primary-dimmed);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:13px;line-height:20px;overflow:hidden}.nLMEza_error{min-width:0;color:var(--dsw-alias-state-error-primary);text-overflow:ellipsis;white-space:nowrap;flex:1;font-size:12px;line-height:20px;overflow:hidden}.nLMEza_objectiveInput{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-base);min-width:0;height:26px;color:var(--dsw-alias-label-primary);border-radius:6px;outline:none;flex:1;padding:0 8px;font-size:13px;line-height:20px}.nLMEza_objectiveInput:focus{border-color:var(--dsw-alias-state-business-primary)}.nLMEza_objectiveInput::placeholder{color:var(--dsw-alias-label-caption)}.nLMEza_actions{flex:none;align-items:center;gap:10px;display:flex}.nLMEza_iconBtn{width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:999px;justify-content:center;align-items:center;padding:0;display:inline-flex}.nLMEza_iconBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}.nLMEza_iconBtn:disabled{opacity:.4;cursor:default}";
12
+ const tagId$1 = "@deepseek-ai/dsh-client-ui-goal/GoalBar.module.css";
13
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
14
+ const tag = document.createElement("style");
15
+ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-goal";
16
+ tag.dataset.pluginCss = tagId$1;
17
+ tag.textContent = css$1;
18
+ document.head.appendChild(tag);
19
+ }
20
+ var GoalBar_module_css_default = {
21
+ "actions": "nLMEza_actions",
22
+ "bar": "nLMEza_bar",
23
+ "dock": "nLMEza_dock",
24
+ "error": "nLMEza_error",
25
+ "goalGlyph": "nLMEza_goalGlyph",
26
+ "iconBtn": "nLMEza_iconBtn",
27
+ "label": "nLMEza_label",
28
+ "objective": "nLMEza_objective",
29
+ "objectiveInput": "nLMEza_objectiveInput"
30
+ };
31
+ //#endregion
32
+ //#region lib/types/client/GoalBar.js
33
+ /**
34
+ * GoalBar: the goal indicator docked above the message composer (input dock
35
+ * strip). A present goal shows a goal glyph, a phase label, the truncated
36
+ * objective, and icon actions — resume when paused, edit (inline form in the
37
+ * same strip), and clear. Goal creation lives on the `/goal` command, not
38
+ * here: loading (undefined), no goal (null), and complete goals render
39
+ * nothing. Live state arrives as the projected whole snapshot; the verbs are
40
+ * the injected face.
41
+ */
42
+ /** Strip label keys per visible phase; complete goals render nothing. */
43
+ const PHASE_LABELS = {
44
+ active: "phase.active",
45
+ paused: "phase.paused",
46
+ blocked: "phase.blocked"
47
+ };
48
+ function GoalBar({ goal, onEdit, onPause, onResume, onClear, t }) {
49
+ const [editing, setEditing] = (0, react.useState)(false);
50
+ const [draft, setDraft] = (0, react.useState)("");
51
+ const [pending, setPending] = (0, react.useState)(false);
52
+ const [actionError, setActionError] = (0, react.useState)(null);
53
+ const [clearedGoalId, setClearedGoalId] = (0, react.useState)(null);
54
+ const pendingRef = (0, react.useRef)(false);
55
+ const goalId = goal?.id;
56
+ (0, react.useEffect)(() => {
57
+ setEditing(false);
58
+ setActionError(null);
59
+ setClearedGoalId(null);
60
+ }, [goalId]);
61
+ const runAction = (0, react.useCallback)(async (action) => {
62
+ if (pendingRef.current) return void 0;
63
+ pendingRef.current = true;
64
+ setPending(true);
65
+ setActionError(null);
66
+ const result = await action();
67
+ pendingRef.current = false;
68
+ setPending(false);
69
+ if (!result.ok) setActionError(`${result.error.message} (${result.error.code})`);
70
+ return result;
71
+ }, []);
72
+ const handleEdit = (0, react.useCallback)(async () => {
73
+ const trimmed = draft.trim();
74
+ if (trimmed === "") return;
75
+ if ((await runAction(() => onEdit(trimmed)))?.ok) setEditing(false);
76
+ }, [
77
+ draft,
78
+ onEdit,
79
+ runAction
80
+ ]);
81
+ const handleClear = (0, react.useCallback)(async (clearedId) => {
82
+ if ((await runAction(onClear))?.ok) setClearedGoalId(clearedId);
83
+ }, [onClear, runAction]);
84
+ if (goal === void 0 || goal === null || goal.phase === "complete" || goal.id === clearedGoalId) return null;
85
+ if (editing) return (0, react_jsx_runtime.jsx)("div", {
86
+ className: GoalBar_module_css_default.dock,
87
+ "data-goal-bar": true,
88
+ children: (0, react_jsx_runtime.jsxs)("div", {
89
+ className: GoalBar_module_css_default.bar,
90
+ children: [
91
+ (0, react_jsx_runtime.jsx)("input", {
92
+ className: GoalBar_module_css_default.objectiveInput,
93
+ type: "text",
94
+ "aria-label": t("objective.aria"),
95
+ value: draft,
96
+ onChange: (e) => {
97
+ setDraft(e.target.value);
98
+ },
99
+ onKeyDown: (e) => {
100
+ if (e.key === "Enter") handleEdit();
101
+ if (e.key === "Escape") setEditing(false);
102
+ },
103
+ autoFocus: true
104
+ }),
105
+ actionError !== null && (0, react_jsx_runtime.jsx)("span", {
106
+ className: GoalBar_module_css_default.error,
107
+ role: "alert",
108
+ children: actionError
109
+ }),
110
+ (0, react_jsx_runtime.jsxs)("div", {
111
+ className: GoalBar_module_css_default.actions,
112
+ children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
113
+ label: t("action.save"),
114
+ side: "bottom",
115
+ delayMs: 500,
116
+ children: (0, react_jsx_runtime.jsx)("button", {
117
+ type: "button",
118
+ className: GoalBar_module_css_default.iconBtn,
119
+ onClick: () => {
120
+ handleEdit();
121
+ },
122
+ disabled: pending || draft.trim() === "",
123
+ "aria-label": t("action.save"),
124
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutline16, { size: 14 })
125
+ })
126
+ }), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
127
+ label: t("action.cancel"),
128
+ side: "bottom",
129
+ delayMs: 500,
130
+ children: (0, react_jsx_runtime.jsx)("button", {
131
+ type: "button",
132
+ className: GoalBar_module_css_default.iconBtn,
133
+ onClick: () => {
134
+ setEditing(false);
135
+ },
136
+ disabled: pending,
137
+ "aria-label": t("action.cancel"),
138
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCloseOutline16, { size: 14 })
139
+ })
140
+ })]
141
+ })
142
+ ]
143
+ })
144
+ });
145
+ const title = goal.phase === "blocked" ? goal.blockedReason?.message : void 0;
146
+ return (0, react_jsx_runtime.jsx)("div", {
147
+ className: GoalBar_module_css_default.dock,
148
+ "data-goal-bar": true,
149
+ children: (0, react_jsx_runtime.jsxs)("div", {
150
+ className: GoalBar_module_css_default.bar,
151
+ title,
152
+ children: [
153
+ (0, react_jsx_runtime.jsx)("span", {
154
+ className: GoalBar_module_css_default.goalGlyph,
155
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconGoalOutline16, { size: 14 })
156
+ }),
157
+ (0, react_jsx_runtime.jsx)("span", {
158
+ className: GoalBar_module_css_default.label,
159
+ children: t(PHASE_LABELS[goal.phase])
160
+ }),
161
+ (0, react_jsx_runtime.jsx)("span", {
162
+ className: GoalBar_module_css_default.objective,
163
+ children: goal.objective
164
+ }),
165
+ actionError !== null && (0, react_jsx_runtime.jsx)("span", {
166
+ className: GoalBar_module_css_default.error,
167
+ role: "alert",
168
+ children: actionError
169
+ }),
170
+ (0, react_jsx_runtime.jsxs)("div", {
171
+ className: GoalBar_module_css_default.actions,
172
+ children: [
173
+ goal.phase === "active" && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
174
+ label: t("action.pause"),
175
+ side: "bottom",
176
+ delayMs: 500,
177
+ children: (0, react_jsx_runtime.jsx)("button", {
178
+ type: "button",
179
+ className: GoalBar_module_css_default.iconBtn,
180
+ disabled: pending,
181
+ onClick: () => {
182
+ runAction(onPause);
183
+ },
184
+ "aria-label": t("action.pause"),
185
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPauseOutline16, { size: 14 })
186
+ })
187
+ }),
188
+ goal.phase === "paused" && (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
189
+ label: t("action.resume"),
190
+ side: "bottom",
191
+ delayMs: 500,
192
+ children: (0, react_jsx_runtime.jsx)("button", {
193
+ type: "button",
194
+ className: GoalBar_module_css_default.iconBtn,
195
+ disabled: pending,
196
+ onClick: () => {
197
+ runAction(onResume);
198
+ },
199
+ "aria-label": t("action.resume"),
200
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlayOutline16, { size: 14 })
201
+ })
202
+ }),
203
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
204
+ label: t("action.edit"),
205
+ side: "bottom",
206
+ delayMs: 500,
207
+ children: (0, react_jsx_runtime.jsx)("button", {
208
+ type: "button",
209
+ className: GoalBar_module_css_default.iconBtn,
210
+ disabled: pending,
211
+ onClick: () => {
212
+ setDraft(goal.objective);
213
+ setEditing(true);
214
+ },
215
+ "aria-label": t("action.edit"),
216
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutline16, { size: 14 })
217
+ })
218
+ }),
219
+ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
220
+ label: t("action.clear"),
221
+ side: "bottom",
222
+ delayMs: 500,
223
+ children: (0, react_jsx_runtime.jsx)("button", {
224
+ type: "button",
225
+ className: GoalBar_module_css_default.iconBtn,
226
+ disabled: pending,
227
+ onClick: () => {
228
+ handleClear(goal.id);
229
+ },
230
+ "aria-label": t("action.clear"),
231
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, { size: 14 })
232
+ })
233
+ })
234
+ ]
235
+ })
236
+ ]
237
+ })
238
+ });
239
+ }
240
+ /** Dock adapter: reads the host-computed 'goal' projection (whole value; absent or null renders nothing). */
241
+ function GoalDock({ useProjection, onEdit, onPause, onResume, onClear, t }) {
242
+ const projection = useProjection("goal");
243
+ return (0, react_jsx_runtime.jsx)(GoalBar, {
244
+ goal: projection === void 0 ? void 0 : projection === null ? null : projection.goal,
245
+ onEdit,
246
+ onPause,
247
+ onResume,
248
+ onClear,
249
+ t
250
+ });
251
+ }
252
+ //#endregion
253
+ //#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-goal/src/client/GoalCommandInputView.module.css.mjs
254
+ const css = ".oRe1gG_row{flex-direction:column;align-items:flex-end;gap:6px;display:flex}.oRe1gG_stack{flex-direction:column;align-items:flex-end;min-width:0;max-width:min(525px,82%);display:flex}.oRe1gG_bubble{overflow-wrap:anywhere;background:var(--dsw-specific-bubble);max-width:100%;color:var(--dsw-alias-label-primary);font:var(--dsw-font-markdown-code);white-space:pre-wrap;border-radius:22px;padding:10px 16px}";
255
+ const tagId = "@deepseek-ai/dsh-client-ui-goal/GoalCommandInputView.module.css";
256
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
257
+ const tag = document.createElement("style");
258
+ tag.dataset.plugin = "@deepseek-ai/dsh-client-ui-goal";
259
+ tag.dataset.pluginCss = tagId;
260
+ tag.textContent = css;
261
+ document.head.appendChild(tag);
262
+ }
263
+ var GoalCommandInputView_module_css_default = {
264
+ "bubble": "oRe1gG_bubble",
265
+ "row": "oRe1gG_row",
266
+ "stack": "oRe1gG_stack"
267
+ };
268
+ //#endregion
269
+ //#region lib/types/client/GoalCommandInputView.js
270
+ /** Right-aligned `/goal` input bubble without ordinary message actions. */
271
+ const GoalCommandInputView = (0, react.memo)(function GoalCommandInputView({ node, t }) {
272
+ const data = node.data;
273
+ return (0, react_jsx_runtime.jsx)("div", {
274
+ className: GoalCommandInputView_module_css_default.row,
275
+ "data-command-input": "",
276
+ role: "group",
277
+ "aria-label": t("commandInput.aria"),
278
+ children: (0, react_jsx_runtime.jsx)("div", {
279
+ className: GoalCommandInputView_module_css_default.stack,
280
+ children: (0, react_jsx_runtime.jsx)("div", {
281
+ className: GoalCommandInputView_module_css_default.bubble,
282
+ children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.MessageText, { text: data.text })
283
+ })
284
+ })
285
+ });
286
+ });
287
+ //#endregion
288
+ //#region lib/types/client/goal-command-input.js
289
+ /**
290
+ * Derive the visible command line from its structured durable run.
291
+ * @param event - `/goal` command run.
292
+ * @returns command text with trailing parser whitespace removed.
293
+ */
294
+ function goalCommandText(event) {
295
+ return `/${event.data.name}${(event.data.args ?? "").trimEnd()}`;
296
+ }
297
+ /** Goal-owned command input projection; the generic command Definition retains the result row. */
298
+ const goalCommandInputDefinition = {
299
+ kind: "goal-command-input",
300
+ target: "chat",
301
+ match: (event) => event.type === "command/run" && event.data.name === "goal" ? {
302
+ id: String(event.data.commandId),
303
+ role: "start"
304
+ } : null,
305
+ start: (_context, match) => {
306
+ if (match.event.type !== "command/run") throw new Error("goal-command-input start requires command/run");
307
+ return {
308
+ commandId: match.event.data.commandId,
309
+ seq: match.event.seq,
310
+ time: match.event.time,
311
+ text: goalCommandText(match.event)
312
+ };
313
+ },
314
+ update: (context) => context.state,
315
+ buildViewNode: (context) => {
316
+ if (context.state === void 0) return null;
317
+ return {
318
+ key: context.key,
319
+ kind: "command-input",
320
+ id: context.id,
321
+ target: "chat",
322
+ anchorSeq: context.state.seq - .1,
323
+ location: context.start?.location ?? { kind: "unresolved" },
324
+ visibility: "visible",
325
+ data: {
326
+ commandId: context.state.commandId,
327
+ text: context.state.text,
328
+ time: context.state.time
329
+ }
330
+ };
331
+ }
332
+ };
333
+ //#endregion
334
+ //#region lib/types/client/locales.js
335
+ /** `goal` namespace dictionaries. */
336
+ /** Simplified Chinese dictionary (the key-set source of truth). */
337
+ const zh = {
338
+ "phase.active": "进行中的目标",
339
+ "phase.paused": "已暂停的目标",
340
+ "phase.blocked": "受阻的目标",
341
+ "objective.aria": "目标内容",
342
+ "commandInput.aria": "命令输入",
343
+ "action.save": "保存目标",
344
+ "action.cancel": "取消编辑",
345
+ "action.pause": "暂停目标",
346
+ "action.resume": "恢复目标",
347
+ "action.edit": "编辑目标",
348
+ "action.clear": "清除目标"
349
+ };
350
+ /** English dictionary, checked complete against the zh key set. */
351
+ const en = {
352
+ "phase.active": "Ongoing Goal",
353
+ "phase.paused": "Paused Goal",
354
+ "phase.blocked": "Blocked Goal",
355
+ "objective.aria": "Goal objective",
356
+ "commandInput.aria": "Command input",
357
+ "action.save": "Save goal",
358
+ "action.cancel": "Cancel edit",
359
+ "action.pause": "Pause goal",
360
+ "action.resume": "Resume goal",
361
+ "action.edit": "Edit goal",
362
+ "action.clear": "Clear goal"
363
+ };
364
+ //#endregion
365
+ //#region lib/types/client/index.js
366
+ /** Dictionary namespace owned by this plugin. */
367
+ const NS = "goal";
368
+ /** Required services for the Goal dock, command-input projection, Remote mutations, and copy. */
369
+ const inject = [
370
+ "slots",
371
+ "sessions",
372
+ "remote",
373
+ "remote.goals",
374
+ "locale",
375
+ "conversationEvents"
376
+ ];
377
+ /**
378
+ * Client plugin body: the GoalBar dock entry with its mutation verbs.
379
+ * @param ctx - client root context.
380
+ */
381
+ function apply(ctx) {
382
+ ctx.conversationEvents.register(goalCommandInputDefinition);
383
+ ctx.effect(() => ctx.locale.register(NS, {
384
+ zh,
385
+ en
386
+ }), "ui-goal: dictionaries");
387
+ ctx.slots.inject("conversation.chat.node", () => ctx.slots.register({
388
+ name: "conversation.chat.node",
389
+ key: "command-input",
390
+ locale: NS
391
+ }, GoalCommandInputView));
392
+ const sessions = ctx.sessions;
393
+ /** The session's current projected CAS ref, read at verb call time (no staleness fence: the RPC's CAS is the guard). */
394
+ const refOf = (sessionId) => {
395
+ const projection = (sessions.binding(sessionId)?.session.projections.faceOf("goal"))?.getSnapshot();
396
+ if (projection == null) return void 0;
397
+ return {
398
+ id: projection.goal.id,
399
+ revision: projection.goal.revision
400
+ };
401
+ };
402
+ const noCurrentGoal = {
403
+ ok: false,
404
+ error: {
405
+ code: "no-current-goal",
406
+ message: "no current goal to mutate",
407
+ details: {}
408
+ }
409
+ };
410
+ ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
411
+ name: "conversation.input.dock",
412
+ id: "goal",
413
+ order: 10,
414
+ locale: NS,
415
+ inject: (sessionId) => ({
416
+ onEdit: async (objective) => {
417
+ const ref = refOf(sessionId);
418
+ if (ref === void 0) return noCurrentGoal;
419
+ return await ctx.remote.goals.edit(sessionId, ref, { objective });
420
+ },
421
+ onPause: async () => {
422
+ const ref = refOf(sessionId);
423
+ if (ref === void 0) return noCurrentGoal;
424
+ return await ctx.remote.goals.pause(sessionId, ref);
425
+ },
426
+ onResume: async () => {
427
+ const ref = refOf(sessionId);
428
+ if (ref === void 0) return noCurrentGoal;
429
+ return await ctx.remote.goals.resume(sessionId, ref);
430
+ },
431
+ onClear: async () => {
432
+ const ref = refOf(sessionId);
433
+ if (ref === void 0) return noCurrentGoal;
434
+ return await ctx.remote.goals.clear(sessionId, ref);
435
+ }
436
+ })
437
+ }, GoalDock));
438
+ }
439
+ //#endregion
440
+ exports.GoalBar = GoalBar;
441
+ exports.GoalDock = GoalDock;
442
+ exports.apply = apply;
443
+ exports.inject = inject;
444
+ return module.exports;
445
+ }
446
+ });
447
+
448
+ //# sourceMappingURL=client.js.map
@@ -713,7 +713,8 @@ window.__ModuleLoader__.load({
713
713
  const inject = [
714
714
  "slots",
715
715
  "locale",
716
- "settingsScope"
716
+ "settingsScope",
717
+ "workspaces"
717
718
  ];
718
719
  function apply(ctx) {
719
720
  const mirror = ctx.settingsScope.describe();
@@ -758,6 +759,24 @@ window.__ModuleLoader__.load({
758
759
  locale: "settings.edge"
759
760
  }, EdgeDirectoryFlow);
760
761
  }));
762
+ const workspaces = ctx.workspaces;
763
+ const originalOpenPath = workspaces.openPath.bind(workspaces);
764
+ workspaces.openPath = async (path) => {
765
+ try {
766
+ await originalOpenPath(path);
767
+ } catch {
768
+ const url = `/api/workspace/file?path=${encodeURIComponent(path)}`;
769
+ const res = await globalThis.fetch(url);
770
+ if (!res.ok) throw new Error(`path open failed: ${res.status === 413 ? "file too large" : await res.text()}`);
771
+ const blob = await res.blob();
772
+ const blobUrl = URL.createObjectURL(blob);
773
+ const a = document.createElement("a");
774
+ a.href = blobUrl;
775
+ a.download = path.split("/").pop() ?? "file";
776
+ a.click();
777
+ URL.revokeObjectURL(blobUrl);
778
+ }
779
+ };
761
780
  }
762
781
  //#endregion
763
782
  exports.apply = apply;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-edge",
3
- "version": "0.6.0",
3
+ "version": "0.7.0-alpha.2",
4
4
  "description": "Your DeepSeek Harness, anywhere — deploy a persistent personal coding agent to Cloudflare Workers in one command",
5
5
  "author": "pawaca",
6
6
  "license": "MIT",
@@ -66,6 +66,9 @@
66
66
  "@deepseek-ai/dsh-compaction-basic": "0.1.1-rc.2",
67
67
  "@deepseek-ai/dsh-compaction-tool-result-pruner": "0.1.1-rc.2",
68
68
  "@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
69
+ "@deepseek-ai/dsh-fs": "0.1.1-rc.2",
70
+ "@deepseek-ai/dsh-goal": "0.1.1-rc.2",
71
+ "@deepseek-ai/dsh-goal-round-driver": "0.1.1-rc.2",
69
72
  "@deepseek-ai/dsh-host-apiproxy": "0.1.1-rc.2",
70
73
  "@deepseek-ai/dsh-launch-environment": "0.1.1-rc.2",
71
74
  "@deepseek-ai/dsh-llm": "0.1.1-rc.2",
@@ -86,7 +89,10 @@
86
89
  "@deepseek-ai/dsh-timeout": "0.1.1-rc.2",
87
90
  "@deepseek-ai/dsh-token-meter": "0.1.1-rc.2",
88
91
  "@deepseek-ai/dsh-system-prompt": "0.1.1-rc.2",
92
+ "@deepseek-ai/dsh-sandbox": "0.1.1-rc.2",
89
93
  "@deepseek-ai/dsh-tool-call-timeout-policy": "0.1.1-rc.2",
94
+ "@deepseek-ai/dsh-tool-fs": "0.1.1-rc.2",
95
+ "@deepseek-ai/dsh-tool-goal": "0.1.1-rc.2",
90
96
  "@deepseek-ai/dsh-tool-web": "0.1.1-rc.2",
91
97
  "@deepseek-ai/dsh-tools": "0.1.1-rc.2",
92
98
  "@deepseek-ai/dsh-web": "0.1.1-rc.2",