@dsh-workbench/core 0.2.5 → 0.2.7

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.
Files changed (38) hide show
  1. package/README.md +13 -9
  2. package/bin/dsh-workbench +12 -43
  3. package/client.js +914 -350
  4. package/dist/client/client.body.js +914 -350
  5. package/dist/client/index.js +915 -351
  6. package/dist/host/index.js +1314 -667
  7. package/dist/types/app/client.d.ts +216 -6
  8. package/dist/types/app/layouts/config-sync/ConfigSyncSection.d.ts +5 -0
  9. package/dist/types/app/layouts/rightbar/__tests__/market-order.test.d.ts +1 -0
  10. package/dist/types/app/layouts/rightbar/__tests__/market-running-display.test.d.ts +1 -0
  11. package/dist/types/app/layouts/rightbar/__tests__/market-workbench-act.test.d.ts +1 -0
  12. package/dist/types/app/layouts/rightbar/market-act.d.ts +2 -1
  13. package/dist/types/app/layouts/rightbar/market-rows.d.ts +3 -0
  14. package/dist/types/app/layouts/rightbar/market-settle-hold.d.ts +13 -0
  15. package/dist/types/app/layouts/rightbar/market-settle.d.ts +22 -0
  16. package/dist/types/app/layouts/rightbar/market-transient-state.d.ts +22 -0
  17. package/dist/types/app/layouts/rightbar/market-view-text.d.ts +26 -1
  18. package/dist/types/app/layouts/sidebar/workspace-groups.d.ts +4 -1
  19. package/dist/types/modules/panels/__tests__/market-tools-harness.d.ts +3 -0
  20. package/dist/types/modules/panels/model/market-workbench-update.d.ts +19 -0
  21. package/dist/types/modules/panels/model/market.d.ts +4 -0
  22. package/dist/types/modules/sessions/index.d.ts +1 -1
  23. package/dist/types/modules/sessions/model/session-node.d.ts +1 -0
  24. package/dist/types/shared/api/bundle-install.d.ts +1 -0
  25. package/dist/types/shared/api/config-sync.d.ts +35 -0
  26. package/dist/types/shared/api/config-sync.test.d.ts +1 -0
  27. package/dist/types/shared/api/host/__tests__/config-sync.test.d.ts +1 -0
  28. package/dist/types/shared/api/host/__tests__/post-channels.test.d.ts +1 -0
  29. package/dist/types/shared/api/host/__tests__/self-update.test.d.ts +1 -0
  30. package/dist/types/shared/api/host/bundle-manager.d.ts +1 -0
  31. package/dist/types/shared/api/host/bundle-routes.d.ts +1 -1
  32. package/dist/types/shared/api/host/config-sync.d.ts +46 -0
  33. package/dist/types/shared/api/host/post-channels.d.ts +18 -0
  34. package/dist/types/shared/api/host/self-update.d.ts +45 -0
  35. package/docs/HANDOFF.md +19 -14
  36. package/docs/OPERATIONS.md +40 -8
  37. package/package.json +4 -4
  38. package/scripts/seed-profile.sh +21 -85
@@ -1,11 +1,14 @@
1
1
  #!/usr/bin/env bash
2
2
  #
3
3
  # 一次性引导:从 shipped 的 web 模板创建 workbench profile,
4
- # 继承 web 的配置(bundle 清单 + 设置快照 + 设置引用到的依赖),
4
+ # 继承 web 的 **bundle 清单**(这台机器上装了哪些 bundle),
5
5
  # 再加上会话 / 存储 / 附件的隔离层。
6
6
  #
7
- # 幂等 / 可续跑:profile 已存在就跳过创建,patch 已非空就跳过继承,
8
- # 隔离层已存在就跳过追加,依赖已在 node_modules 就跳过安装
7
+ # **设置不在这里继承**(这里曾经把 web 的 cordis.patch.yml 快照一份过来):
8
+ # 工作台自己的 patch 是唯一真相,想搬 web 的哪几行由用户走「设置 → 配置同步」。
9
+ # 为什么这么分(安装 vs 设置)、为什么不再是自动的:.scratch/config-sync/spec.md
10
+ #
11
+ # 幂等 / 可续跑:profile 已存在就跳过创建,隔离层已存在就跳过追加
9
12
  # —— 重复运行不会覆盖任何东西。
10
13
  # 安全:全程只**读** web 的 profile 目录,只**写** workbench 自己的目录。
11
14
  #
@@ -39,11 +42,6 @@ die() {
39
42
 
40
43
  DST_PATCH="$DST_PROFILE/cordis.patch.yml"
41
44
 
42
- # dsh 生成的 patch 文件带一段注释头,所以"是否还是空层"不能直接和 [] 比。
43
- is_pristine_patch() {
44
- [ "$(grep -v '^[[:space:]]*#' "$1" | tr -d '[:space:]')" = "[]" ]
45
- }
46
-
47
45
  # ── 第 1 步:创建 profile ────────────────────────────────────────────────
48
46
  # --from-default-profile web 只复制 web 模板的 bundle 列表
49
47
  # (dsh-base + dsh-web-app),**不**复制 web 的 cordis.patch.yml。
@@ -85,90 +83,25 @@ fs.writeFileSync(process.env.WB_MANIFEST, JSON.stringify(wb, null, 2) + "\n");
85
83
  console.log("→ 已继承 web 的 bundle 列表: " + merged.join(", "));
86
84
  '
87
85
 
88
- # ── 第 3 步:把 web 的设置文档复制过来,作为「继承」的起点 ──────────────
89
- # profiles/<name>/cordis.patch.yml 就是 Settings 页的活文档
90
- # (config-editor.documentPath === profileContext.patchPath)。
91
- # 复制一份快照,两边之后各自独立演进 —— 这正是「互不干扰」的实现方式。
92
- if is_pristine_patch "$DST_PATCH"; then
93
- cp "$SRC_PROFILE/cordis.patch.yml" "$DST_PATCH"
94
- echo "→ 已继承 web 的配置快照"
95
- else
96
- echo "→ profile 的 patch 已非空,跳过继承(避免覆盖你自己的改动)"
97
- fi
98
-
99
- # ── 第 4 步:追加会话 / 存储 / 附件隔离层 ───────────────────────────────
86
+ # ── 第 3 步:追加会话 / 存储 / 附件隔离层 ───────────────────────────────
100
87
  if grep -q 'id: session-persistence-jsonl' "$DST_PATCH"; then
101
88
  echo "→ 隔离层已存在,跳过"
102
89
  else
90
+ # dsh 生成的 profile patch 是「三行横幅注释 + 一个空数组 []」。空数组本身是一个**完整的
91
+ # YAML 文档**,往后直接接一个序列,解析就会在最外层报
92
+ # "end of the stream or a document separator is expected",profile 直接起不来
93
+ # (实测 dsh 0.2.1-alpha.3:setup 出来的 profile 报这条,去掉那行 [] 才起)。
94
+ # 所以追加之前先把那行单独的 [] 拿掉;本来就没有(或已经是序列)时这一步什么都不做。
95
+ if grep -qx '\[\]' "$DST_PATCH"; then
96
+ grep -vx '\[\]' "$DST_PATCH" >"$DST_PATCH.tmp" && mv "$DST_PATCH.tmp" "$DST_PATCH"
97
+ echo "→ 模板 patch 里的空数组 [] 已让位(否则接不上隔离层)"
98
+ fi
103
99
  printf '\n' >>"$DST_PATCH"
104
100
  cat "$ISOLATION" >>"$DST_PATCH"
105
101
  echo "→ 已追加隔离层(sessions / storages / attachments 分家)"
106
102
  fi
107
103
 
108
- # ── 第 5 步:继承「被 patch 点名」的依赖 ────────────────────────────────
109
- # 第 3 步把 web 的设置文档整份复制了过来,而那份文档是**按 name: 点名**插件的。
110
- # 出厂 @deepseek-ai/* 由 dsh 安装本体解析,不必装;但自己装的第三方包
111
- # (例如 @deepseek-ai/dsh-web-search-exa)只住在 profile 的 node_modules 里
112
- # —— 不跟着继承的话,那一行会以 "failed to import" 静默不激活,功能凭空少一块。
113
- #
114
- # 只继承**被 patch 引用**的那些:web 的 dependencies 里可能有装了却没有任何行
115
- # 引用的包(本机就有 @aipanel/dsh-client 与 @aipanel/dsh-plugin),整份搬过来
116
- # 只是死重量。反过来说,**不能只写进 package.json** —— node_modules 得跟上,
117
- # 否则症状一模一样。
118
- WANTED="$(
119
- WB_MANIFEST="$DST_PROFILE/package.json" \
120
- WEB_MANIFEST="$SRC_PROFILE/package.json" \
121
- PATCH="$DST_PATCH" \
122
- node -e '
123
- const fs = require("node:fs");
124
- const read = (p) => JSON.parse(fs.readFileSync(p, "utf8"));
125
- const wb = read(process.env.WB_MANIFEST);
126
- const web = read(process.env.WEB_MANIFEST);
127
-
128
- // patch 里非注释行的 `name:` —— 注释掉的条目(# 开头)不算引用。
129
- const referenced = new Set();
130
- for (const line of fs.readFileSync(process.env.PATCH, "utf8").split("\n")) {
131
- if (/^\s*#/.test(line)) continue;
132
- const m = /^\s*-?\s*name:\s*"?([^"\s#]+)/.exec(line);
133
- if (m) referenced.add(m[1]);
134
- }
135
-
136
- // workbench 自己已有的声明优先 —— 重复 seed 不会覆盖你钉住的版本。
137
- const own = wb.dependencies || {};
138
- const missing = {};
139
- for (const [name, version] of Object.entries(web.dependencies || {})) {
140
- if (referenced.has(name) && !(name in own)) missing[name] = version;
141
- }
142
- if (Object.keys(missing).length > 0) {
143
- wb.dependencies = Object.assign({}, missing, own);
144
- fs.writeFileSync(process.env.WB_MANIFEST, JSON.stringify(wb, null, 2) + "\n");
145
- }
146
-
147
- // 报出全部「被点名」的依赖(不只是这次新加的):node_modules 也可能被清过。
148
- console.log(
149
- Object.keys(web.dependencies || {})
150
- .filter((name) => referenced.has(name))
151
- .join(" "),
152
- );
153
- '
154
- )"
155
-
156
- WANTED_MISSING=0
157
- if [ -n "$WANTED" ]; then
158
- echo "→ patch 引用的依赖(须在 profile 内可解析): $WANTED"
159
- for dep in $WANTED; do
160
- [ -d "$DST_PROFILE/node_modules/$dep" ] || WANTED_MISSING=1
161
- done
162
- fi
163
-
164
- if [ "$WANTED_MISSING" = "1" ]; then
165
- echo "→ node_modules 缺这些依赖,装进 profile(走 dsh 的包管理器)"
166
- dsh plugin --profile "$(basename "$DST_PROFILE")" install
167
- else
168
- echo "→ 依赖已齐备,跳过安装"
169
- fi
170
-
171
- # ── 第 6 步:建 DIY 工坊 ────────────────────────────────────────────────
104
+ # ── 第 4 步:建 DIY 工坊 ────────────────────────────────────────────────
172
105
  #
173
106
  # 工坊是 DIY 模式的落点:agent 在那里造模块(一个模块一个目录),而 **DIY 会话的 cwd 就是它**。
174
107
  # 骨架 + 依赖 + 稳定入口都交给 `scripts/seed-workshop.sh` —— 启动器(bin/dsh-workbench)
@@ -186,7 +119,10 @@ fi
186
119
 
187
120
  cat <<EOF
188
121
 
189
- profile '$DST_PROFILE' 的骨架好了(bundle 清单 + 设置快照 + 隔离层)。
122
+ profile '$DST_PROFILE' 的骨架好了(bundle 清单 + 会话/存储/附件隔离层)。
123
+
124
+ 设置**不在**这里继承:想要 web 那边的模型供应商 / 搜索源 / MCP,起工作台后去
125
+ 「设置 → 配置同步」按行勾(读的是那个 profile 的 cordis.patch.yml;搬完重启生效)。
190
126
 
191
127
  装 bundle —— 两条**等价**的路,任选一条(都走 dsh 的 runPluginCommand,装完会
192
128
  把 bundle 登记进 profile 清单):