@dsh-workbench/shared 0.3.3 → 0.3.5

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 (193) hide show
  1. package/dist/api/blocker-table.d.ts +13 -0
  2. package/dist/api/blocker-table.js +13 -0
  3. package/dist/api/blocker.d.ts +6 -0
  4. package/dist/api/context-ref.d.ts +31 -0
  5. package/dist/api/context-ref.js +28 -0
  6. package/dist/api/dsh-client.d.ts +99 -0
  7. package/dist/api/dsh.d.ts +55 -3
  8. package/dist/api/facts.d.ts +42 -0
  9. package/dist/api/facts.js +33 -0
  10. package/dist/api/host-write.d.ts +19 -1
  11. package/dist/api/host-write.js +12 -0
  12. package/dist/api/long-task.d.ts +36 -0
  13. package/dist/api/long-task.js +27 -0
  14. package/dist/api/unit-board.d.ts +25 -0
  15. package/dist/api/unit-board.js +16 -0
  16. package/dist/api/unit-declaration.d.ts +36 -0
  17. package/dist/api/unit-declaration.js +24 -0
  18. package/dist/api/unit.d.ts +32 -0
  19. package/dist/api/unit.js +5 -0
  20. package/dist/api/workbench-client.d.ts +25 -0
  21. package/dist/api/workbench-client.js +13 -0
  22. package/dist/api/workbench-contract.d.ts +12 -0
  23. package/dist/components/Activity.d.ts +33 -0
  24. package/dist/components/Activity.js +24 -0
  25. package/dist/components/ApprovalDetail.d.ts +15 -1
  26. package/dist/components/ApprovalDetail.js +13 -1
  27. package/dist/components/ApprovalPlan.d.ts +14 -0
  28. package/dist/components/ApprovalPlan.js +8 -0
  29. package/dist/components/Card.d.ts +13 -0
  30. package/dist/components/Card.js +10 -0
  31. package/dist/components/CardAnchor.d.ts +14 -0
  32. package/dist/components/CardAnchor.js +11 -0
  33. package/dist/components/CardBoundary.d.ts +20 -0
  34. package/dist/components/CardBoundary.js +14 -0
  35. package/dist/components/CardHead.d.ts +13 -0
  36. package/dist/components/CardHead.js +10 -0
  37. package/dist/components/ChoiceGroup.d.ts +24 -0
  38. package/dist/components/ChoiceGroup.js +12 -0
  39. package/dist/components/Field.d.ts +10 -0
  40. package/dist/components/Field.js +7 -0
  41. package/dist/components/Form.css +6 -0
  42. package/dist/components/Form.d.ts +20 -0
  43. package/dist/components/Form.js +58 -0
  44. package/dist/components/FormActions.d.ts +14 -0
  45. package/dist/components/FormActions.js +5 -0
  46. package/dist/components/FormNodes.d.ts +103 -0
  47. package/dist/components/FormNodes.js +153 -0
  48. package/dist/components/FormRows.d.ts +20 -0
  49. package/dist/components/FormRows.js +14 -0
  50. package/dist/components/FormTypes.d.ts +59 -0
  51. package/dist/components/FormTypes.js +1 -0
  52. package/dist/components/Link.d.ts +12 -0
  53. package/dist/components/Link.js +9 -0
  54. package/dist/components/LongTaskRow.d.ts +19 -0
  55. package/dist/components/LongTaskRow.js +13 -0
  56. package/dist/components/Note.d.ts +11 -0
  57. package/dist/components/Note.js +8 -0
  58. package/dist/components/ResourceStates.d.ts +25 -0
  59. package/dist/components/ResourceStates.js +22 -0
  60. package/dist/components/Rows.d.ts +17 -0
  61. package/dist/components/Rows.js +11 -0
  62. package/dist/components/SaveBar.d.ts +12 -0
  63. package/dist/components/SaveBar.js +9 -0
  64. package/dist/components/SelectField.d.ts +26 -0
  65. package/dist/components/SelectField.js +22 -0
  66. package/dist/components/SelectFieldNodes.d.ts +24 -0
  67. package/dist/components/SelectFieldNodes.js +24 -0
  68. package/dist/components/SettingsSection.d.ts +11 -0
  69. package/dist/components/SettingsSection.js +8 -0
  70. package/dist/components/Spinner.d.ts +9 -0
  71. package/dist/components/Spinner.js +6 -0
  72. package/dist/components/Stack.d.ts +8 -0
  73. package/dist/components/Stack.js +5 -0
  74. package/dist/components/StateBlock.d.ts +13 -0
  75. package/dist/components/StateBlock.js +10 -0
  76. package/dist/components/TextField.d.ts +8 -0
  77. package/dist/components/TextField.js +5 -0
  78. package/dist/components/board-module.d.ts +30 -0
  79. package/dist/components/icons.d.ts +38 -0
  80. package/dist/components/icons.js +35 -0
  81. package/dist/config/constants.d.ts +45 -0
  82. package/dist/config/constants.js +45 -0
  83. package/dist/config/storage.d.ts +4 -0
  84. package/dist/config/storage.js +4 -0
  85. package/dist/host/browser-read.d.ts +1 -0
  86. package/dist/host/browser-read.js +1 -0
  87. package/dist/host/http.d.ts +3 -0
  88. package/dist/host/http.js +10 -1
  89. package/dist/host/tool-approval.d.ts +5 -0
  90. package/dist/host/tool-approval.js +11 -5
  91. package/dist/host/unit-face.d.ts +5 -1
  92. package/dist/host.d.ts +1 -0
  93. package/dist/host.js +1 -0
  94. package/dist/i18n/en.d.ts +1 -0
  95. package/dist/i18n/en.js +22 -8
  96. package/dist/i18n/index.d.ts +25 -9
  97. package/dist/i18n/index.js +1 -0
  98. package/dist/i18n/merge.d.ts +5 -0
  99. package/dist/i18n/merge.js +2 -0
  100. package/dist/i18n/zh.d.ts +23 -8
  101. package/dist/i18n/zh.js +22 -8
  102. package/dist/index.d.ts +7 -2
  103. package/dist/index.js +7 -2
  104. package/dist/lib/blocker-action.d.ts +22 -0
  105. package/dist/lib/blocker-action.js +13 -0
  106. package/dist/lib/board-fact.d.ts +27 -0
  107. package/dist/lib/board-fact.js +18 -0
  108. package/dist/lib/busy.d.ts +10 -0
  109. package/dist/lib/busy.js +7 -0
  110. package/dist/lib/diy-debug.d.ts +42 -2
  111. package/dist/lib/diy-debug.js +19 -1
  112. package/dist/lib/diy-record.d.ts +98 -0
  113. package/dist/lib/diy-record.js +96 -0
  114. package/dist/lib/form-problem.d.ts +10 -0
  115. package/dist/lib/form-problem.js +10 -0
  116. package/dist/lib/panel-state.d.ts +60 -0
  117. package/dist/lib/panel-state.js +30 -0
  118. package/dist/lib/react.d.ts +39 -0
  119. package/dist/lib/react.js +36 -0
  120. package/dist/lib/text.d.ts +22 -0
  121. package/dist/lib/text.js +22 -0
  122. package/dist/lib/ui.d.ts +50 -0
  123. package/dist/lib/ui.js +41 -0
  124. package/package.json +1 -1
  125. package/src/api/blocker-table.ts +13 -0
  126. package/src/api/blocker.ts +6 -0
  127. package/src/api/context-ref.ts +31 -0
  128. package/src/api/dsh-client.ts +99 -0
  129. package/src/api/dsh.ts +56 -1
  130. package/src/api/facts.ts +42 -0
  131. package/src/api/host-write.ts +20 -1
  132. package/src/api/long-task.ts +36 -0
  133. package/src/api/unit-board.ts +25 -0
  134. package/src/api/unit-declaration.ts +36 -0
  135. package/src/api/unit.ts +32 -0
  136. package/src/api/workbench-client.ts +25 -0
  137. package/src/api/workbench-contract.ts +12 -0
  138. package/src/components/Activity.tsx +33 -0
  139. package/src/components/ApprovalDetail.tsx +17 -1
  140. package/src/components/ApprovalPlan.tsx +14 -0
  141. package/src/components/Card.tsx +13 -0
  142. package/src/components/CardAnchor.tsx +14 -0
  143. package/src/components/CardBoundary.tsx +20 -0
  144. package/src/components/CardHead.tsx +13 -0
  145. package/src/components/ChoiceGroup.tsx +24 -0
  146. package/src/components/Field.tsx +10 -0
  147. package/src/components/Form.css +6 -0
  148. package/src/components/Form.test.tsx +475 -0
  149. package/src/components/Form.tsx +78 -0
  150. package/src/components/FormActions.tsx +14 -0
  151. package/src/components/FormNodes.tsx +193 -0
  152. package/src/components/FormRows.tsx +20 -0
  153. package/src/components/FormTypes.ts +65 -0
  154. package/src/components/FormWiring.test.tsx +88 -0
  155. package/src/components/Link.tsx +12 -0
  156. package/src/components/LongTaskRow.tsx +19 -0
  157. package/src/components/Note.tsx +11 -0
  158. package/src/components/ResourceStates.tsx +25 -0
  159. package/src/components/Rows.tsx +17 -0
  160. package/src/components/SaveBar.tsx +12 -0
  161. package/src/components/SelectField.tsx +26 -0
  162. package/src/components/SelectFieldNodes.tsx +24 -0
  163. package/src/components/SettingsSection.tsx +11 -0
  164. package/src/components/Spinner.tsx +9 -0
  165. package/src/components/Stack.tsx +8 -0
  166. package/src/components/StateBlock.tsx +13 -0
  167. package/src/components/TextField.tsx +8 -0
  168. package/src/components/board-module.ts +30 -0
  169. package/src/components/icons.tsx +38 -0
  170. package/src/config/constants.ts +48 -0
  171. package/src/config/storage.ts +4 -0
  172. package/src/host/browser-read.ts +1 -0
  173. package/src/host/http.ts +15 -1
  174. package/src/host/tool-approval.ts +18 -4
  175. package/src/host/unit-face.ts +6 -1
  176. package/src/host.ts +1 -0
  177. package/src/i18n/en.ts +22 -8
  178. package/src/i18n/index.ts +3 -0
  179. package/src/i18n/merge.ts +5 -0
  180. package/src/i18n/zh.ts +23 -8
  181. package/src/index.ts +7 -2
  182. package/src/lib/blocker-action.ts +22 -0
  183. package/src/lib/board-fact.ts +27 -0
  184. package/src/lib/busy.ts +10 -0
  185. package/src/lib/diy-debug.test.ts +2 -1
  186. package/src/lib/diy-debug.ts +44 -3
  187. package/src/lib/diy-record.test.ts +171 -0
  188. package/src/lib/diy-record.ts +185 -0
  189. package/src/lib/form-problem.ts +10 -0
  190. package/src/lib/panel-state.ts +60 -0
  191. package/src/lib/react.ts +39 -0
  192. package/src/lib/text.ts +22 -0
  193. package/src/lib/ui.ts +50 -0
@@ -1,37 +1,82 @@
1
+ /** 外壳插件的包名:浏览器模块表与宿主按它注册、认领这枚插件。 */
1
2
  export declare const PLUGIN_ID = "@dsh-workbench/core";
3
+ /** 与外壳同批发布的兄弟包名:`release.ts` 用它判一版三包是否都已在源上。 */
2
4
  export declare const RELEASE_SIBLINGS: readonly ["@dsh-workbench/shared", "@dsh-workbench/module-tools"];
5
+ /** 外壳宿主 HTTP API 的根前缀;prefs / actions / provision 等路由都挂在它下面。 */
3
6
  export declare const API_PREFIX = "/workbench/api";
7
+ /** 模块偏好读写的路由前缀,挂在外壳 API 下:走写通道,拒写回 write-refused。 */
4
8
  export declare const PREFS_PREFIX = "/workbench/api/prefs";
9
+ /** 事实(facts)SSE 事件流的端点路径;前端 `EventSource` 按它带 `since` 游标续传。 */
5
10
  export declare const EVENTS_PATH = "/workbench/events";
11
+ /** 写动作的路由前缀,挂在外壳 API 下:模块的写通道 POST 到这里。 */
6
12
  export declare const ACTIONS_PREFIX = "/workbench/api/actions";
13
+ /** 机器供给(provision)的路由前缀:只收 POST,装机时用它铺一份运行环境。 */
7
14
  export declare const PROVISION_PREFIX = "/workbench/api/provision";
15
+ /** 面板运行态上报的路径段:崩溃与卡片收尾分别 POST 到 `panel-state/crash`、`panel-state/cards`。 */
8
16
  export declare const PANEL_STATE_PATH = "panel-state";
17
+ /** DIY 调试动作的路径段;宿主按它登记 `/workbench/api/diy-debug` 前缀。 */
9
18
  export declare const DIY_DEBUG_PATH = "diy-debug";
19
+ /** 调试动作的子路径(`diy-debug/act`);仓内暂无调用点,动作现走 `DIY_DEBUG_SERVICE`。 */
10
20
  export declare const DIY_DEBUG_ACT_PATH = "diy-debug/act";
21
+ /** DIY 录制交接的路径段;宿主按它登记 `/workbench/api/diy-record` 前缀。 */
22
+ export declare const DIY_RECORD_PATH = "diy-record";
23
+ /** 录制动作的子路径(`diy-record/act`);仓内暂无调用点,录制现走 `DIY_RECORD_SERVICE`。 */
24
+ export declare const DIY_RECORD_ACT_PATH = "diy-record/act";
25
+ /** 面板运行态的路由前缀,挂在外壳 API 下:上报口用它,拒报回 report-refused。 */
11
26
  export declare const PANEL_STATE_PREFIX = "/workbench/api/panel-state";
27
+ /** 钉住的 opencli 插件版本:`opencli-runtime` 按它校验、取那一份。 */
12
28
  export declare const OPENCLI_PIN = "1.8.8";
29
+ /** 缺陷看板套件的 dsh 服务名(`workbenchCodingIssues`):套件照它登记自己那份服务。 */
13
30
  export declare const CODING_ISSUES_SERVICE = "workbenchCodingIssues";
31
+ /** 面板套件的 dsh 服务名(`workbenchPanels`):宿主经它取套件公布的清单与订阅。 */
14
32
  export declare const PANELS_SERVICE = "workbenchPanels";
33
+ /** 单元花名册服务的 dsh 服务名(`workbenchUnits`):模块经它认领自己的单元。 */
15
34
  export declare const UNITS_SERVICE = "workbenchUnits";
35
+ /** 面板运行态服务的 dsh 服务名(`workbenchPanelState`):宿主注册,读口按它取。 */
16
36
  export declare const PANEL_STATE_SERVICE = "workbenchPanelState";
37
+ /** DIY 调试约定服务的 dsh 服务名(`workbenchDiyDebug`):调试动作走它,不走 HTTP。 */
17
38
  export declare const DIY_DEBUG_SERVICE = "workbenchDiyDebug";
39
+ /** DIY 录制交接服务的 dsh 服务名(`workbenchDiyRecord`):`diy-acts.ts` 经它收发录制三拍。 */
40
+ export declare const DIY_RECORD_SERVICE = "workbenchDiyRecord";
41
+ /** 会话投影服务的 dsh 服务名(`sessionProjections`):宿主经 `stateOf(session, 'agentPreset')` 读那一档。 */
42
+ export declare const SESSION_PROJECTIONS_SERVICE = "sessionProjections";
43
+ /** 面板清单一次取回的行数上限(条):外部模块拿它当 opencli `--pageSize`。 */
18
44
  export declare const PANEL_LIST_LIMIT = 50;
45
+ /** 单次 opencli 调用的默认超时(毫秒);调用点没传 `timeoutMs` 时按它算。 */
19
46
  export declare const OPENCLI_TIMEOUT_MS = 120000;
47
+ /** 同时最多几条 opencli 在跑(条):`opencli.ts` 超出就排队。 */
20
48
  export declare const OPENCLI_MAX_CONCURRENT = 4;
49
+ /** 启动预热站点那一跳的超时(毫秒);超时按未热对待,不挡面板。 */
21
50
  export declare const WARM_TIMEOUT_MS = 20000;
51
+ /** 装 / 卸模块包的超时(毫秒):pnpm 与取包内容都按它算。 */
22
52
  export declare const INSTALL_TIMEOUT_MS = 300000;
53
+ /** 查 registry 版本那一次请求的超时(毫秒)。 */
23
54
  export declare const VERSION_CHECK_TIMEOUT_MS = 10000;
55
+ /** 版本查询结果的缓存有效期(毫秒):期内不发第二次请求。 */
24
56
  export declare const VERSION_CHECK_TTL_MS = 600000;
57
+ /** 单元探测结果的缓存有效期(毫秒)。 */
25
58
  export declare const PROBE_TTL_MS = 30000;
59
+ /** 加载态至少显示多久(毫秒):一瞬完成的读写也得让用户看见那一下。 */
26
60
  export declare const MIN_BUSY_MS = 500;
61
+ /** 工具读出来的值交给面板后的保留时长(毫秒):过期就不再算这一拍。 */
27
62
  export declare const HANDOFF_TTL_MS = 15000;
63
+ /** 跑本地 git 命令的超时(毫秒);短于对外的 `OPENCLI_TIMEOUT_MS`。 */
28
64
  export declare const GIT_TIMEOUT_MS = 10000;
65
+ /** 面板轮询事实的间隔(毫秒):SSE 断了走这条兜底轮询。 */
29
66
  export declare const PANEL_POLL_MS = 2000;
67
+ /** 没起中文名的工作区默认标题:左栏按它分组、显示。 */
30
68
  export declare const DEFAULT_WORKSPACE_TITLE = "default-workspace";
69
+ /** 记住当前项目的 localStorage 键。 */
31
70
  export declare const STORAGE_KEY_PROJECT = "dsh-workbench.project";
71
+ /** 记住右栏展开与否的 localStorage 键。 */
32
72
  export declare const STORAGE_KEY_RIGHTBAR = "dsh-workbench.rightbar.expanded";
73
+ /** 记住右栏当前列的 localStorage 键。 */
33
74
  export declare const STORAGE_KEY_RIGHTBAR_COLUMN = "dsh-workbench.rightbar.column";
75
+ /** 记住右栏宽度(像素数字的字符串)的 localStorage 键。 */
34
76
  export declare const STORAGE_KEY_RIGHTBAR_WIDTH = "dsh-workbench.rightbar.width";
77
+ /** 右栏宽度达到或超过多少像素就按全屏对待(阈值,像素)。 */
35
78
  export declare const RIGHTBAR_FULLSCREEN_WIDTH = 768;
79
+ /** dsh i18n 的命名空间:词表都注册在它下面,`ctx.locale.register` / `bind` 按它取。 */
36
80
  export declare const LOCALE_NS = "workbench";
81
+ /** 外壳支持的语言标识,顺序即回退顺序:首项是基准,其余词表必须与它逐键同构。 */
37
82
  export declare const LOCALES: readonly ["zh", "en"];
@@ -1,40 +1,85 @@
1
+ /** 外壳插件的包名:浏览器模块表与宿主按它注册、认领这枚插件。 */
1
2
  export const PLUGIN_ID = "@dsh-workbench/core";
3
+ /** 与外壳同批发布的兄弟包名:`release.ts` 用它判一版三包是否都已在源上。 */
2
4
  export const RELEASE_SIBLINGS = [
3
5
  "@dsh-workbench/shared",
4
6
  "@dsh-workbench/module-tools",
5
7
  ];
8
+ /** 外壳宿主 HTTP API 的根前缀;prefs / actions / provision 等路由都挂在它下面。 */
6
9
  export const API_PREFIX = "/workbench/api";
10
+ /** 模块偏好读写的路由前缀,挂在外壳 API 下:走写通道,拒写回 write-refused。 */
7
11
  export const PREFS_PREFIX = `${API_PREFIX}/prefs`;
12
+ /** 事实(facts)SSE 事件流的端点路径;前端 `EventSource` 按它带 `since` 游标续传。 */
8
13
  export const EVENTS_PATH = "/workbench/events";
14
+ /** 写动作的路由前缀,挂在外壳 API 下:模块的写通道 POST 到这里。 */
9
15
  export const ACTIONS_PREFIX = `${API_PREFIX}/actions`;
16
+ /** 机器供给(provision)的路由前缀:只收 POST,装机时用它铺一份运行环境。 */
10
17
  export const PROVISION_PREFIX = `${API_PREFIX}/provision`;
18
+ /** 面板运行态上报的路径段:崩溃与卡片收尾分别 POST 到 `panel-state/crash`、`panel-state/cards`。 */
11
19
  export const PANEL_STATE_PATH = "panel-state";
20
+ /** DIY 调试动作的路径段;宿主按它登记 `/workbench/api/diy-debug` 前缀。 */
12
21
  export const DIY_DEBUG_PATH = "diy-debug";
22
+ /** 调试动作的子路径(`diy-debug/act`);仓内暂无调用点,动作现走 `DIY_DEBUG_SERVICE`。 */
13
23
  export const DIY_DEBUG_ACT_PATH = `${DIY_DEBUG_PATH}/act`;
24
+ /** DIY 录制交接的路径段;宿主按它登记 `/workbench/api/diy-record` 前缀。 */
25
+ export const DIY_RECORD_PATH = "diy-record";
26
+ /** 录制动作的子路径(`diy-record/act`);仓内暂无调用点,录制现走 `DIY_RECORD_SERVICE`。 */
27
+ export const DIY_RECORD_ACT_PATH = `${DIY_RECORD_PATH}/act`;
28
+ /** 面板运行态的路由前缀,挂在外壳 API 下:上报口用它,拒报回 report-refused。 */
14
29
  export const PANEL_STATE_PREFIX = `${API_PREFIX}/${PANEL_STATE_PATH}`;
30
+ /** 钉住的 opencli 插件版本:`opencli-runtime` 按它校验、取那一份。 */
15
31
  export const OPENCLI_PIN = "1.8.8";
32
+ /** 缺陷看板套件的 dsh 服务名(`workbenchCodingIssues`):套件照它登记自己那份服务。 */
16
33
  export const CODING_ISSUES_SERVICE = "workbenchCodingIssues";
34
+ /** 面板套件的 dsh 服务名(`workbenchPanels`):宿主经它取套件公布的清单与订阅。 */
17
35
  export const PANELS_SERVICE = "workbenchPanels";
36
+ /** 单元花名册服务的 dsh 服务名(`workbenchUnits`):模块经它认领自己的单元。 */
18
37
  export const UNITS_SERVICE = "workbenchUnits";
38
+ /** 面板运行态服务的 dsh 服务名(`workbenchPanelState`):宿主注册,读口按它取。 */
19
39
  export const PANEL_STATE_SERVICE = "workbenchPanelState";
40
+ /** DIY 调试约定服务的 dsh 服务名(`workbenchDiyDebug`):调试动作走它,不走 HTTP。 */
20
41
  export const DIY_DEBUG_SERVICE = "workbenchDiyDebug";
42
+ /** DIY 录制交接服务的 dsh 服务名(`workbenchDiyRecord`):`diy-acts.ts` 经它收发录制三拍。 */
43
+ export const DIY_RECORD_SERVICE = "workbenchDiyRecord";
44
+ /** 会话投影服务的 dsh 服务名(`sessionProjections`):宿主经 `stateOf(session, 'agentPreset')` 读那一档。 */
45
+ export const SESSION_PROJECTIONS_SERVICE = "sessionProjections";
46
+ /** 面板清单一次取回的行数上限(条):外部模块拿它当 opencli `--pageSize`。 */
21
47
  export const PANEL_LIST_LIMIT = 50;
48
+ /** 单次 opencli 调用的默认超时(毫秒);调用点没传 `timeoutMs` 时按它算。 */
22
49
  export const OPENCLI_TIMEOUT_MS = 120_000;
50
+ /** 同时最多几条 opencli 在跑(条):`opencli.ts` 超出就排队。 */
23
51
  export const OPENCLI_MAX_CONCURRENT = 4;
52
+ /** 启动预热站点那一跳的超时(毫秒);超时按未热对待,不挡面板。 */
24
53
  export const WARM_TIMEOUT_MS = 20_000;
54
+ /** 装 / 卸模块包的超时(毫秒):pnpm 与取包内容都按它算。 */
25
55
  export const INSTALL_TIMEOUT_MS = 300_000;
56
+ /** 查 registry 版本那一次请求的超时(毫秒)。 */
26
57
  export const VERSION_CHECK_TIMEOUT_MS = 10_000;
58
+ /** 版本查询结果的缓存有效期(毫秒):期内不发第二次请求。 */
27
59
  export const VERSION_CHECK_TTL_MS = 600_000;
60
+ /** 单元探测结果的缓存有效期(毫秒)。 */
28
61
  export const PROBE_TTL_MS = 30_000;
62
+ /** 加载态至少显示多久(毫秒):一瞬完成的读写也得让用户看见那一下。 */
29
63
  export const MIN_BUSY_MS = 500;
64
+ /** 工具读出来的值交给面板后的保留时长(毫秒):过期就不再算这一拍。 */
30
65
  export const HANDOFF_TTL_MS = 15_000;
66
+ /** 跑本地 git 命令的超时(毫秒);短于对外的 `OPENCLI_TIMEOUT_MS`。 */
31
67
  export const GIT_TIMEOUT_MS = 10_000;
68
+ /** 面板轮询事实的间隔(毫秒):SSE 断了走这条兜底轮询。 */
32
69
  export const PANEL_POLL_MS = 2000;
70
+ /** 没起中文名的工作区默认标题:左栏按它分组、显示。 */
33
71
  export const DEFAULT_WORKSPACE_TITLE = "default-workspace";
72
+ /** 记住当前项目的 localStorage 键。 */
34
73
  export const STORAGE_KEY_PROJECT = "dsh-workbench.project";
74
+ /** 记住右栏展开与否的 localStorage 键。 */
35
75
  export const STORAGE_KEY_RIGHTBAR = "dsh-workbench.rightbar.expanded";
76
+ /** 记住右栏当前列的 localStorage 键。 */
36
77
  export const STORAGE_KEY_RIGHTBAR_COLUMN = "dsh-workbench.rightbar.column";
78
+ /** 记住右栏宽度(像素数字的字符串)的 localStorage 键。 */
37
79
  export const STORAGE_KEY_RIGHTBAR_WIDTH = "dsh-workbench.rightbar.width";
80
+ /** 右栏宽度达到或超过多少像素就按全屏对待(阈值,像素)。 */
38
81
  export const RIGHTBAR_FULLSCREEN_WIDTH = 768;
82
+ /** dsh i18n 的命名空间:词表都注册在它下面,`ctx.locale.register` / `bind` 按它取。 */
39
83
  export const LOCALE_NS = "workbench";
84
+ /** 外壳支持的语言标识,顺序即回退顺序:首项是基准,其余词表必须与它逐键同构。 */
40
85
  export const LOCALES = ["zh", "en"];
@@ -1,4 +1,8 @@
1
+ /** 读 localStorage 里的一段文本;没有这个键、或存储不可用(隐私模式)时返回 null。 */
1
2
  export declare function readText(key: string): string | null;
3
+ /** 写一段文本进 localStorage;`value` 为 null 时删掉这个键,写不进去就静默作罢。 */
2
4
  export declare function writeText(key: string, value: string | null): void;
5
+ /** 读一个布尔开关:键不存在时返回 `fallback`,只有存进去的 `'true'` 算真。 */
3
6
  export declare function readFlag(key: string, fallback: boolean): boolean;
7
+ /** 把一个布尔开关写进 localStorage(存 `'true'` / `'false'`);失败静默。 */
4
8
  export declare function writeFlag(key: string, value: boolean): void;
@@ -1,3 +1,4 @@
1
+ /** 读 localStorage 里的一段文本;没有这个键、或存储不可用(隐私模式)时返回 null。 */
1
2
  export function readText(key) {
2
3
  try {
3
4
  return window.localStorage.getItem(key);
@@ -6,6 +7,7 @@ export function readText(key) {
6
7
  return null;
7
8
  }
8
9
  }
10
+ /** 写一段文本进 localStorage;`value` 为 null 时删掉这个键,写不进去就静默作罢。 */
9
11
  export function writeText(key, value) {
10
12
  try {
11
13
  if (value === null)
@@ -16,12 +18,14 @@ export function writeText(key, value) {
16
18
  catch {
17
19
  }
18
20
  }
21
+ /** 读一个布尔开关:键不存在时返回 `fallback`,只有存进去的 `'true'` 算真。 */
19
22
  export function readFlag(key, fallback) {
20
23
  const raw = readText(key);
21
24
  if (raw === null)
22
25
  return fallback;
23
26
  return raw === 'true';
24
27
  }
28
+ /** 把一个布尔开关写进 localStorage(存 `'true'` / `'false'`);失败静默。 */
25
29
  export function writeFlag(key, value) {
26
30
  writeText(key, value ? 'true' : 'false');
27
31
  }
@@ -1,6 +1,7 @@
1
1
  import type { DshShell } from '../api/dsh.js';
2
2
  export declare const BROWSER_SCREEN_SESSION = "workbench";
3
3
  export declare const BROWSER_READ_SESSION = "workbench-read";
4
+ export declare const BROWSER_RECORD_SESSION = "workbench-rec";
4
5
  export interface BrowserReadResult {
5
6
  readonly ok: boolean;
6
7
  readonly code: string;
@@ -3,6 +3,7 @@ import { backgroundLine } from './opencli-window.js';
3
3
  import { runShell } from './shell.js';
4
4
  export const BROWSER_SCREEN_SESSION = 'workbench';
5
5
  export const BROWSER_READ_SESSION = 'workbench-read';
6
+ export const BROWSER_RECORD_SESSION = 'workbench-rec';
6
7
  const DEFAULT_TIMEOUT_MS = 25000;
7
8
  const DEFAULT_RETRY_MS = 1200;
8
9
  const DEFAULT_SETTLE_MS = 900;
@@ -44,3 +44,6 @@ export declare function registerPanelState(ctx: DshHostContext, store: PanelStat
44
44
  export declare function registerDiyDebugAct(ctx: DshHostContext, resource: PostResource, log?: {
45
45
  bump(facts: readonly string[]): unknown;
46
46
  } | undefined): () => void;
47
+ export declare function registerDiyRecordAct(ctx: DshHostContext, resource: PostResource, log?: {
48
+ bump(facts: readonly string[]): unknown;
49
+ } | undefined): () => void;
package/dist/host/http.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { unitFactScope } from '../api/facts.js';
2
2
  import { parseCardsReport, parseCrashReport } from '../lib/panel-state.js';
3
- import { ACTIONS_PREFIX, API_PREFIX, DIY_DEBUG_PATH, PANEL_STATE_PREFIX, PLUGIN_ID, PREFS_PREFIX, PROVISION_PREFIX } from '../config/constants.js';
3
+ import { ACTIONS_PREFIX, API_PREFIX, DIY_DEBUG_PATH, DIY_RECORD_PATH, PANEL_STATE_PREFIX, PLUGIN_ID, PREFS_PREFIX, PROVISION_PREFIX } from '../config/constants.js';
4
4
  import { parseProvisionBody, } from './provision.js';
5
5
  import { WorkbenchDataError } from '../host/opencli.js';
6
6
  import { writeResultForClient } from './write-result.js';
@@ -264,3 +264,12 @@ export function registerDiyDebugAct(ctx, resource, log) {
264
264
  wrote: () => log?.bump(['diy-debug']),
265
265
  });
266
266
  }
267
+ export function registerDiyRecordAct(ctx, resource, log) {
268
+ return registerPost(ctx, {
269
+ prefix: `${API_PREFIX}/${DIY_RECORD_PATH}`,
270
+ what: '工作台 DIY 录制交接动作',
271
+ refusedCode: 'action-refused',
272
+ resources: [resource],
273
+ wrote: () => log?.bump(['diy-record']),
274
+ });
275
+ }
@@ -18,6 +18,10 @@ export type ApprovalFacts = ApprovalDetail | {
18
18
  };
19
19
  export declare const APPROVAL_NOTE_ARG = "approval_note";
20
20
  export declare const APPROVAL_NOTE_LIMIT = 40;
21
+ export declare const APPROVAL_DETAIL_LIMIT = 20;
22
+ export declare const APPROVAL_QUESTION_LIMIT = 40;
23
+ export declare const APPROVAL_SEPARATOR_LIMIT = 8;
24
+ export declare const APPROVAL_HEADLINE_LIMIT: number;
21
25
  export declare function withApprovalNote(parameters: Record<string, unknown>, options?: {
22
26
  readonly required?: boolean | undefined;
23
27
  }): Record<string, unknown>;
@@ -40,6 +44,7 @@ export type ApprovalPolicy = (call: ApprovalCall) => ApprovalVerdict | undefined
40
44
  export interface ApprovalContext {
41
45
  readonly writes?: boolean | undefined;
42
46
  readonly policy?: ApprovalPolicy | undefined;
47
+ readonly declaredNote?: boolean | undefined;
43
48
  readonly detailOf?: ((call: ApprovalCall) => ApprovalFacts | undefined | Promise<ApprovalFacts | undefined>) | undefined;
44
49
  }
45
50
  export declare function approvalFor(call: ApprovalCall, context?: ApprovalContext): Promise<AskDecision | undefined>;
@@ -1,5 +1,9 @@
1
1
  export const APPROVAL_NOTE_ARG = 'approval_note';
2
2
  export const APPROVAL_NOTE_LIMIT = 40;
3
+ export const APPROVAL_DETAIL_LIMIT = 20;
4
+ export const APPROVAL_QUESTION_LIMIT = 40;
5
+ export const APPROVAL_SEPARATOR_LIMIT = 8;
6
+ export const APPROVAL_HEADLINE_LIMIT = APPROVAL_DETAIL_LIMIT + APPROVAL_QUESTION_LIMIT + APPROVAL_NOTE_LIMIT + APPROVAL_SEPARATOR_LIMIT;
3
7
  const NOTE_SCHEMA = {
4
8
  type: 'string',
5
9
  description: '一句话说明你这次想拿它干什么(要点头时显示在审批屏上;40 字以内)。',
@@ -20,12 +24,15 @@ export function withApprovalNote(parameters, options = {}) {
20
24
  ...(required.length === 0 ? {} : { required }),
21
25
  };
22
26
  }
27
+ function oneLine(text) {
28
+ return text.replace(/\s+/g, ' ').trim();
29
+ }
23
30
  function approvalNoteOf(call) {
24
31
  const raw = call.arguments;
25
32
  const value = typeof raw === 'object' && raw !== null ? raw[APPROVAL_NOTE_ARG] : undefined;
26
33
  if (typeof value !== 'string')
27
34
  return undefined;
28
- const line = value.replace(/\s+/g, ' ').trim();
35
+ const line = oneLine(value);
29
36
  if (line === '')
30
37
  return undefined;
31
38
  return line.length > APPROVAL_NOTE_LIMIT ? `${line.slice(0, APPROVAL_NOTE_LIMIT)}…` : line;
@@ -40,9 +47,8 @@ function compose(detail, verdict, note) {
40
47
  en: `${detail.en} — ${verdict.question.en}`,
41
48
  zh: `${detail.zh} —— ${verdict.question.zh}`,
42
49
  };
43
- if (note === undefined)
44
- return base;
45
- return { en: `${base.en} — ${note}`, zh: `${base.zh} —— ${note}` };
50
+ const line = note === undefined ? base : { en: `${base.en} — ${note}`, zh: `${base.zh} —— ${note}` };
51
+ return { en: oneLine(line.en), zh: oneLine(line.zh) };
46
52
  }
47
53
  export async function approvalFor(call, context = {}) {
48
54
  if (context.writes !== true)
@@ -78,6 +84,6 @@ export async function approvalFor(call, context = {}) {
78
84
  return {
79
85
  kind: 'ask',
80
86
  reason: verdict.reason,
81
- displayReason: compose(facts, verdict, approvalNoteOf(call)),
87
+ displayReason: compose(facts, verdict, context.declaredNote === true ? approvalNoteOf(call) : undefined),
82
88
  };
83
89
  }
@@ -7,6 +7,10 @@ import type { UnitCapability } from './unit-libs.js';
7
7
  import type { ApprovalCall, ApprovalFacts, ApprovalPolicy } from '../host/tool-approval.js';
8
8
  import type { ValueHandoff } from '../host/value-handoff.js';
9
9
  import type { WorkspaceStore } from '../host/workspace-store.js';
10
+ export interface ToolScopeContext {
11
+ readonly workspace: string | null;
12
+ readonly preset: string | null;
13
+ }
10
14
  export interface UnitMountDeps {
11
15
  readonly manifest: UnitManifest;
12
16
  readonly ctx: DshHostContext;
@@ -40,7 +44,7 @@ export interface UnitMountResult {
40
44
  registerTools(): Array<() => void>;
41
45
  readonly factsOf?: ((call: UnitCall) => readonly string[] | undefined) | undefined;
42
46
  readonly gate?: {
43
- deniedTools(workspace: string | null): readonly string[];
47
+ deniedTools(context: ToolScopeContext): readonly string[];
44
48
  subscribe(listener: () => void): () => void;
45
49
  };
46
50
  readonly context?: {
package/dist/host.d.ts CHANGED
@@ -9,6 +9,7 @@ export * from './lib/ui.js';
9
9
  export * from './lib/panel-state.js';
10
10
  export * from './lib/board-fact.js';
11
11
  export * from './lib/diy-debug.js';
12
+ export * from './lib/diy-record.js';
12
13
  export * from './api/blocker-table.js';
13
14
  export * from './host/browser-find.js';
14
15
  export * from './host/browser-read.js';
package/dist/host.js CHANGED
@@ -9,6 +9,7 @@ export * from './lib/ui.js';
9
9
  export * from './lib/panel-state.js';
10
10
  export * from './lib/board-fact.js';
11
11
  export * from './lib/diy-debug.js';
12
+ export * from './lib/diy-record.js';
12
13
  export * from './api/blocker-table.js';
13
14
  export * from './host/browser-find.js';
14
15
  export * from './host/browser-read.js';
package/dist/i18n/en.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  import type { WorkbenchMessages } from './zh.js';
2
+ /** 外壳自带的英文词表:键必须与 `zh` 逐一对应,值不许为空串。 */
2
3
  export declare const en: Record<keyof WorkbenchMessages, string>;
package/dist/i18n/en.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** 外壳自带的英文词表:键必须与 `zh` 逐一对应,值不许为空串。 */
1
2
  export const en = {
2
3
  'brand.name': 'Workbench',
3
4
  'toggle.open': 'Open sidebar',
@@ -408,18 +409,31 @@ export const en = {
408
409
  'configSync.noSource': 'This machine has no other profile to sync from',
409
410
  'configSync.emptyProviders': 'The workbench has no model provider yet — sync the llm- rows from some profile, or configure one under Models.',
410
411
  'configSync.failed': 'The sync did not go through; try again.',
411
- 'debug.status': 'Workbench DIY debugging',
412
- 'debug.status.trouble': 'Workbench DIY debugging needs attention',
413
- 'debug.stalled': 'Workbench DIY debugging paused',
412
+ 'debug.workspace': 'this workspace',
413
+ 'debug.status': 'Debugging “{title}”',
414
+ 'debug.status.trouble': 'Debugging needs your attention ({title})',
415
+ 'debug.stalled': 'Debugging paused ({title})',
414
416
  'debug.act.pause': 'Pause debugging',
415
417
  'debug.act.resume': 'Resume debugging',
416
418
  'debug.act.stop': 'Stop debugging',
417
419
  'debug.act.stop.ask': 'Confirm stop',
418
- 'debug.card.here.title': 'Workbench DIY debugging is on',
420
+ 'debug.card.here.title': 'Debugging “{title}”',
419
421
  'debug.card.here.note': 'Do not switch workspaces or touch the panel',
420
- 'debug.card.away.title': 'Workbench DIY debugging is on',
421
- 'debug.card.away.note': 'Switch to the Workbench DIY workspace',
422
+ 'debug.card.away.note': 'Switch back to “{title}”',
422
423
  'debug.card.paused.note': 'Paused',
423
- 'debug.card.hidden.note': 'Switch to the Workbench panel',
424
- 'debug.back': 'Back to the workshop screen',
424
+ 'debug.card.hidden.note': 'Switch back to the Workbench panel',
425
+ 'record.waiting': 'Recording handoff · your turn',
426
+ 'record.waiting.note': 'Press "Start recording" on that page, then "Stop recording" when done (it will not switch you back)',
427
+ 'record.recording': 'Recording',
428
+ 'record.recording.note': 'Press "Stop recording" when done; if the bar is gone press Halt so the agent grabs it first',
429
+ 'record.finished': 'Recording finished',
430
+ 'record.finished.note': 'This run is done — the agent will grab it and wrap up on its own',
431
+ 'record.act.cancel': 'Cancel',
432
+ 'record.act.halt': 'Halt',
433
+ 'approval.record.site': 'Site',
434
+ 'approval.record.what': 'Records',
435
+ 'approval.record.lands': 'Lands in',
436
+ 'approval.record.noUrl': 'no site given (this call gets refused)',
437
+ 'approval.record.oneAction': 'one action',
438
+ 'approval.record.noSwitch': 'it will not switch you back (the leftbar footer shows the state)',
425
439
  };
@@ -1,4 +1,5 @@
1
1
  import { type WorkbenchMessages } from './zh.js';
2
+ /** 外壳自带的两份词表(`zh` 为基准、`en` 同构):`client.tsx` 拿它当合并各套件词表的底座。 */
2
3
  export declare const dictionaries: {
3
4
  zh: {
4
5
  readonly 'brand.name': "工作台";
@@ -410,24 +411,39 @@ export declare const dictionaries: {
410
411
  readonly 'configSync.noSource': "这台机器上只有工作台这一个 profile,没有可同步的来源";
411
412
  readonly 'configSync.emptyProviders': "工作台还没有任何模型供应商 —— 去「配置同步」从某个 profile 把 llm- 那几行搬过来,或自己去「模型」里配。";
412
413
  readonly 'configSync.failed': "同步没成功,再试一次。";
413
- readonly 'debug.status': "工作台 DIY 开发调试中";
414
- readonly 'debug.status.trouble': "工作台 DIY 开发调试异常";
415
- readonly 'debug.stalled': "工作台 DIY 调试暂停";
414
+ readonly 'debug.workspace': "这个工作区";
415
+ readonly 'debug.status': "「{title}」调试中";
416
+ readonly 'debug.status.trouble': "调试要你看一眼({title})";
417
+ readonly 'debug.stalled': "调试已暂停({title})";
416
418
  readonly 'debug.act.pause': "暂停调试";
417
419
  readonly 'debug.act.resume': "继续调试";
418
420
  readonly 'debug.act.stop': "结束调试";
419
421
  readonly 'debug.act.stop.ask': "确认结束";
420
- readonly 'debug.card.here.title': "当前工作台 DIY 开发调试中";
422
+ readonly 'debug.card.here.title': "正在调试「{title}」";
421
423
  readonly 'debug.card.here.note': "请勿切换工作区和操作面板";
422
- readonly 'debug.card.away.title': "工作台 DIY 开发调试中";
423
- readonly 'debug.card.away.note': "请切换到工作台 DIY 工作区";
424
+ readonly 'debug.card.away.note': "请切回「{title}」那一屏";
424
425
  readonly 'debug.card.paused.note': "已暂停";
425
- readonly 'debug.card.hidden.note': "请切换到工作台面板";
426
- readonly 'debug.back': "回到工坊那一屏";
426
+ readonly 'debug.card.hidden.note': "请切回工作台面板";
427
+ readonly 'record.waiting': "取证交接 · 等你出手";
428
+ readonly 'record.waiting.note': "请在那一页按「开始录制」,做完按「结束录制」(录完不替你切回来)";
429
+ readonly 'record.recording': "录制中";
430
+ readonly 'record.recording.note': "做完按「结束录制」;浮条没了按「停」,让 agent 先取再收";
431
+ readonly 'record.finished': "录制完成";
432
+ readonly 'record.finished.note': "这一段录完了 —— agent 会自己来取并收工,不用你点";
433
+ readonly 'record.act.cancel': "取消";
434
+ readonly 'record.act.halt': "停";
435
+ readonly 'approval.record.site': "站点";
436
+ readonly 'approval.record.what': "录制功能";
437
+ readonly 'approval.record.lands': "落点";
438
+ readonly 'approval.record.noUrl': "没给站点地址(这次会被当场拒)";
439
+ readonly 'approval.record.oneAction': "一次操作";
440
+ readonly 'approval.record.noSwitch': "录完不会替你切回来(左栏底部会亮一条状态)";
427
441
  };
428
- en: Record<"time.now" | "time.ago" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.fix.update" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "project.add.busy" | "project.add.failed" | "project.search.label" | "project.search.placeholder" | "project.search.empty" | "project.group.workspaces" | "project.group.defaultWorkspace" | "project.group.workshop" | "project.rename.row" | "project.rename.current" | "project.rename.title" | "project.rename.description" | "project.rename.field" | "project.rename.placeholder" | "project.rename.hint" | "project.rename.save" | "project.rename.saving" | "project.rename.cancel" | "project.rename.failed" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.list.label" | "session.copy" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.compact.approval" | "status.compact.planReview" | "status.compact.answer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "project.attention.warning.one" | "project.attention.warning.other" | "project.attention.running.one" | "project.attention.running.other" | "project.attention.done.one" | "project.attention.done.other" | "project.attention.state.warning" | "project.attention.state.running" | "project.attention.state.done" | "hover.copied" | "time.short.minutes" | "time.short.hours" | "time.short.days" | "time.short.months" | "time.short.years" | "panels.title" | "panels.groupBoardless" | "panels.groupPlugins" | "panels.market.defaultHint" | "panels.market.defaultLabel" | "panels.market.defaultLocked" | "panels.followAll" | "panels.followAllConfirmTitle" | "panels.followAllConfirmDetail" | "panels.followAllConfirmAck" | "panels.followAllConfirmYes" | "panels.followAllConfirmNo" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.buildModule" | "panels.failed" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.hintJoin" | "panels.dep.failed" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.notActive" | "panels.market.notUsable" | "panels.market.broken" | "panels.market.hasNew" | "panels.market.hasProblem" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.swapSlow" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.failed" | "panels.market.needEnv" | "panels.market.needCommands" | "panels.market.localMark" | "panels.market.localHint" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.sectionPlugins" | "panels.market.moduleOutdated" | "panels.market.moduleRefused" | "panels.market.moduleRefusedDetail" | "panels.market.moduleRestartHint" | "panels.market.pendingRestart" | "panels.market.workbenchName" | "panels.market.workbenchLocal" | "panels.market.pluginKeptInUse" | "panels.market.pluginKeptUnsure" | "panels.market.pluginKeptHeld" | "panels.market.pluginKeptUnnamed" | "panels.market.pluginBroken" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNotWorkbenchModule" | "panels.market.add.problemNotModuleOrPlugin" | "panels.market.add.failureNotModuleOrPlugin" | "panels.market.add.installedPlugin" | "panels.market.add.pluginPreview" | "panels.market.add.pluginAlias" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureInstalled" | "panels.market.add.failureGeneric" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.classifying" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.restartWhy" | "panels.market.add.restartWhy.no-hmr" | "panels.market.add.restartWhy.package-moved" | "panels.market.add.restartWhy.host-module" | "panels.market.add.restartWhy.unmanaged-plugin" | "panels.market.add.restartWhy.module-comparison" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "rightbar.openPlatform" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label" | "configSync.nav" | "configSync.lead" | "configSync.source" | "configSync.sourceBroken" | "configSync.sourceRows" | "configSync.sourceDead" | "configSync.refresh" | "configSync.loading" | "configSync.readHint" | "configSync.tag.new" | "configSync.tag.differs" | "configSync.conflictNote" | "configSync.code.lang" | "configSync.code.copy" | "configSync.code.copied" | "configSync.code.wrap" | "configSync.code.unwrap" | "configSync.code.collapse" | "configSync.code.collapseAria" | "configSync.code.expandAria" | "configSync.code.expand" | "configSync.missing" | "configSync.apply" | "configSync.applyNone" | "configSync.applying" | "configSync.applied" | "configSync.appliedIds" | "configSync.skippedIds" | "configSync.nothing" | "configSync.unreadable" | "configSync.noSource" | "configSync.emptyProviders" | "configSync.failed" | "debug.status" | "debug.status.trouble" | "debug.stalled" | "debug.act.pause" | "debug.act.resume" | "debug.act.stop" | "debug.act.stop.ask" | "debug.card.here.title" | "debug.card.here.note" | "debug.card.away.title" | "debug.card.away.note" | "debug.card.paused.note" | "debug.card.hidden.note" | "debug.back", string>;
442
+ en: Record<"time.now" | "time.ago" | "time.minutes" | "time.hours" | "time.days" | "blocker.retry" | "blocker.copy" | "blocker.unknown.title" | "blocker.login.go" | "blocker.login.titleGeneric" | "blocker.login.title" | "blocker.login.manual" | "blocker.login.hint" | "blocker.forbidden.open" | "blocker.forbidden.titleGeneric" | "blocker.forbidden.title" | "blocker.forbidden.hint" | "blocker.timeout.hint" | "blocker.exec.hint" | "blocker.fix.install" | "blocker.fix.update" | "blocker.market.open" | "env.unit.failed" | "env.unit.failedHint" | "env.unit.missingPlugin" | "env.unit.hint" | "env.unit.missingCommands" | "env.unit.missingCommandsHint" | "env.unit.unchecked" | "env.unit.uncheckedHint" | "brand.name" | "toggle.open" | "toggle.collapse" | "project.label" | "workspace.section" | "project.none" | "project.empty" | "project.add" | "project.add.busy" | "project.add.failed" | "project.search.label" | "project.search.placeholder" | "project.search.empty" | "project.group.workspaces" | "project.group.defaultWorkspace" | "project.group.workshop" | "project.rename.row" | "project.rename.current" | "project.rename.title" | "project.rename.description" | "project.rename.field" | "project.rename.placeholder" | "project.rename.hint" | "project.rename.save" | "project.rename.saving" | "project.rename.cancel" | "project.rename.failed" | "session.new" | "session.new.label" | "session.empty" | "session.noProject" | "session.list.label" | "session.copy" | "session.pinned" | "session.actions" | "status.idle" | "status.running" | "status.waitingApproval" | "status.planReview" | "status.waitingAnswer" | "status.compact.approval" | "status.compact.planReview" | "status.compact.answer" | "status.completed" | "status.subagentsRunning.one" | "status.subagentsRunning.other" | "project.attention.warning.one" | "project.attention.warning.other" | "project.attention.running.one" | "project.attention.running.other" | "project.attention.done.one" | "project.attention.done.other" | "project.attention.state.warning" | "project.attention.state.running" | "project.attention.state.done" | "hover.copied" | "time.short.minutes" | "time.short.hours" | "time.short.days" | "time.short.months" | "time.short.years" | "panels.title" | "panels.groupBoardless" | "panels.groupPlugins" | "panels.market.defaultHint" | "panels.market.defaultLabel" | "panels.market.defaultLocked" | "panels.followAll" | "panels.followAllConfirmTitle" | "panels.followAllConfirmDetail" | "panels.followAllConfirmAck" | "panels.followAllConfirmYes" | "panels.followAllConfirmNo" | "panels.enabled" | "panels.disabled" | "panels.choose" | "panels.buildModule" | "panels.failed" | "panels.dragHint" | "panels.unknownStep" | "panels.labelWithHint" | "panels.hintJoin" | "panels.dep.failed" | "panels.dep.missingPlugin" | "panels.dep.missingCommands" | "panels.dep.unchecked" | "panels.tab.modules" | "panels.tab.market" | "panels.browseMarket" | "panels.noneInstalled" | "panels.noneInstalledHint" | "panels.market.installed" | "panels.market.notActive" | "panels.market.notUsable" | "panels.market.broken" | "panels.market.hasNew" | "panels.market.hasProblem" | "panels.market.missing" | "panels.market.unchecked" | "panels.market.checking" | "panels.market.sectionInstalled" | "panels.market.sectionPending" | "panels.market.sectionShared" | "panels.market.sharedUsedBy" | "panels.market.listSeparator" | "panels.market.sharedMissing" | "panels.market.sharedOutdated" | "panels.market.sharedUnsatisfied" | "panels.market.sharedOk" | "panels.market.versionArrow" | "panels.market.lead" | "panels.market.install" | "panels.market.update" | "panels.market.swapSlow" | "panels.market.uninstall" | "panels.market.uninstallLabel" | "panels.market.installing" | "panels.market.updating" | "panels.market.uninstalling" | "panels.market.confirmUninstallTitle" | "panels.market.confirmUninstallDetail" | "panels.market.confirmUninstallAck" | "panels.market.confirmYes" | "panels.market.confirmNo" | "panels.market.failed" | "panels.market.needEnv" | "panels.market.needCommands" | "panels.market.localMark" | "panels.market.localHint" | "panels.market.noSource" | "panels.market.badSource" | "panels.market.empty" | "panels.market.sectionPlugins" | "panels.market.moduleOutdated" | "panels.market.moduleRefused" | "panels.market.moduleRefusedDetail" | "panels.market.moduleRestartHint" | "panels.market.pendingRestart" | "panels.market.workbenchName" | "panels.market.workbenchLocal" | "panels.market.pluginKeptInUse" | "panels.market.pluginKeptUnsure" | "panels.market.pluginKeptHeld" | "panels.market.pluginKeptUnnamed" | "panels.market.pluginBroken" | "panels.market.restartNeeded" | "panels.market.foot" | "panels.market.recheck" | "panels.market.checkUpdates" | "panels.market.checkedAt" | "panels.market.justNow" | "panels.market.minutesAgo" | "panels.market.hoursAgo" | "panels.market.add.description" | "panels.market.add.specPlaceholder" | "panels.market.add.guideToggle" | "panels.market.add.guideHide" | "panels.market.add.guideIdTitle" | "panels.market.add.guideIdExample" | "panels.market.add.guideIdHint" | "panels.market.add.guideGitTitle" | "panels.market.add.guideGitExample" | "panels.market.add.guideGitHint" | "panels.market.add.guidePathTitle" | "panels.market.add.guidePathExample" | "panels.market.add.guidePathHint" | "panels.market.add.guideExampleLabel" | "panels.market.add.guideFill" | "panels.market.add.guideSafety" | "panels.market.add.registryLegend" | "panels.market.add.registryOfficial" | "panels.market.add.registryMirror" | "panels.market.add.registryWithHost" | "panels.market.add.registryToggle" | "panels.market.add.installVersion" | "panels.market.add.registryDefault" | "panels.market.add.registryCustom" | "panels.market.add.registryCustomPlaceholder" | "panels.market.add.registryCustomHint" | "panels.market.add.registryCustomInvalid" | "panels.market.add.run" | "panels.market.add.edit" | "panels.market.add.changeRegistry" | "panels.market.add.installingTitle" | "panels.market.add.installedTitle" | "panels.market.add.failedTitle" | "panels.market.add.cancelledTitle" | "panels.market.add.failureNetworkHost" | "panels.market.add.problemInvalid" | "panels.market.add.problemInstalled" | "panels.market.add.problemNotFound" | "panels.market.add.problemNotPackage" | "panels.market.add.problemNotBundle" | "panels.market.add.problemNotWorkbenchModule" | "panels.market.add.problemNotModuleOrPlugin" | "panels.market.add.failureNotModuleOrPlugin" | "panels.market.add.installedPlugin" | "panels.market.add.pluginPreview" | "panels.market.add.pluginAlias" | "panels.market.add.problemNetwork" | "panels.market.add.problemUnknown" | "panels.market.add.failureNetwork" | "panels.market.add.failureNotFound" | "panels.market.add.failureNoMatchingVersion" | "panels.market.add.failureDiskFull" | "panels.market.add.failurePermission" | "panels.market.add.failureBuildBlocked" | "panels.market.add.failureIntegrity" | "panels.market.add.failureTimeout" | "panels.market.add.failurePnpmMissing" | "panels.market.add.failureInstalled" | "panels.market.add.failureGeneric" | "panels.market.add.approveTitle" | "panels.market.add.approveCaution" | "panels.market.add.approveRun" | "panels.market.add.restart" | "panels.market.add.tookEffect" | "panels.market.add.details" | "panels.market.add.open" | "panels.market.add.title" | "panels.market.add.intro" | "panels.market.add.specLabel" | "panels.market.add.specHint" | "panels.market.add.exampleTitle" | "panels.market.add.exampleFill" | "panels.market.add.registryLabel" | "panels.market.add.registryProfile" | "panels.market.add.registryPnpm" | "panels.market.add.check" | "panels.market.add.checking" | "panels.market.add.classifying" | "panels.market.add.change" | "panels.market.add.previewTitle" | "panels.market.add.fieldName" | "panels.market.add.fieldVersion" | "panels.market.add.fieldDescription" | "panels.market.add.fieldSource" | "panels.market.add.install" | "panels.market.add.installing" | "panels.market.add.cancel" | "panels.market.add.close" | "panels.market.add.retry" | "panels.market.add.changeSource" | "panels.market.add.approveBuilds" | "panels.market.add.approveHint" | "panels.market.add.doneApplied" | "panels.market.add.doneRestart" | "panels.market.add.restartWhy" | "panels.market.add.restartWhy.no-hmr" | "panels.market.add.restartWhy.package-moved" | "panels.market.add.restartWhy.host-module" | "panels.market.add.restartWhy.unmanaged-plugin" | "panels.market.add.restartWhy.module-comparison" | "panels.market.add.cancelled" | "panels.market.add.failed" | "panels.market.add.removed" | "panels.market.add.supplyPending" | "panels.market.add.supplyFailed" | "panels.market.add.notModule" | "panels.market.add.removedRestart" | "panels.market.add.remove" | "panels.market.add.problem.invalidSpec" | "panels.market.add.problem.alreadyInstalled" | "panels.market.add.problem.notFound" | "panels.market.add.problem.notAPackage" | "panels.market.add.problem.notABundle" | "panels.market.add.problem.network" | "panels.market.add.problem.unknown" | "panels.market.add.reason.invalidSpec" | "panels.market.add.reason.incompatible" | "panels.market.add.reason.notBundle" | "panels.market.add.reason.notRemovable" | "panels.market.add.reason.bundleInUse" | "panels.market.add.reason.stopProfile" | "panels.market.add.reason.staleApproval" | "panels.market.add.reason.operationError" | "panels.market.add.reason.buildBlocked" | "panels.market.add.reason.pnpmMissing" | "panels.market.add.reason.noMatchingVersion" | "panels.market.add.reason.diskFull" | "panels.market.add.reason.permission" | "panels.market.add.reason.integrity" | "panels.market.add.reason.timeout" | "panels.market.add.reason.network" | "panels.market.add.reason.notFound" | "panels.market.add.reason.unknown" | "blocker.fix.running" | "blocker.fix.failed" | "blocker.retry.running" | "panels.reading" | "panels.cardBroken" | "panels.cardRetry" | "panels.empty" | "panels.emptyHint" | "env.title" | "env.checking" | "env.installing" | "env.failed" | "env.elapsed" | "env.stepFailed.install" | "env.stepFailed.path" | "env.stepFailed.shell" | "env.bridge.ok" | "env.bridge.short" | "env.bridge.why" | "env.bridge.daemon" | "env.bridge.extension" | "env.bridge.extensionLink" | "env.bridge.profile" | "env.bridge.stale" | "env.bridge.unknown" | "env.fix.title" | "env.fix.why" | "env.fix.whyPath" | "env.fix.whyShell" | "env.fix.step" | "env.fix.stepPath" | "env.fix.stepShell" | "env.fix.permission" | "env.fix.network" | "env.fix.details" | "env.retry" | "env.copyCommand" | "env.copied" | "env.step.opencli" | "env.step.codingPlugin" | "env.step.bridge" | "env.step.warm" | "env.warm.done" | "env.warm.short" | "rightbar.label" | "rightbar.expand" | "rightbar.collapse" | "rightbar.column.label" | "rightbar.column.workbench" | "rightbar.column.dsh" | "rightbar.refresh" | "rightbar.refreshing" | "rightbar.updatedAt" | "rightbar.noProject" | "rightbar.openPlatform" | "coding.notARepo.title" | "error.unknown" | "board.title" | "panel.conversation" | "panels.label" | "configSync.nav" | "configSync.lead" | "configSync.source" | "configSync.sourceBroken" | "configSync.sourceRows" | "configSync.sourceDead" | "configSync.refresh" | "configSync.loading" | "configSync.readHint" | "configSync.tag.new" | "configSync.tag.differs" | "configSync.conflictNote" | "configSync.code.lang" | "configSync.code.copy" | "configSync.code.copied" | "configSync.code.wrap" | "configSync.code.unwrap" | "configSync.code.collapse" | "configSync.code.collapseAria" | "configSync.code.expandAria" | "configSync.code.expand" | "configSync.missing" | "configSync.apply" | "configSync.applyNone" | "configSync.applying" | "configSync.applied" | "configSync.appliedIds" | "configSync.skippedIds" | "configSync.nothing" | "configSync.unreadable" | "configSync.noSource" | "configSync.emptyProviders" | "configSync.failed" | "debug.workspace" | "debug.status" | "debug.status.trouble" | "debug.stalled" | "debug.act.pause" | "debug.act.resume" | "debug.act.stop" | "debug.act.stop.ask" | "debug.card.here.title" | "debug.card.here.note" | "debug.card.away.note" | "debug.card.paused.note" | "debug.card.hidden.note" | "record.waiting" | "record.waiting.note" | "record.recording" | "record.recording.note" | "record.finished" | "record.finished.note" | "record.act.cancel" | "record.act.halt" | "approval.record.site" | "approval.record.what" | "approval.record.lands" | "approval.record.noUrl" | "approval.record.oneAction" | "approval.record.noSwitch", string>;
429
443
  };
444
+ /** 中文词表的键类型(从 `zh.ts` 转出):`en` 与模块词表都得覆盖同一批键。 */
430
445
  export type { WorkbenchMessages };
446
+ /** 一份按语言分的词表:`zh` / `en` 必须同键,另可带模块自己那份语言。 */
431
447
  export interface Dictionaries {
432
448
  readonly zh: Readonly<Record<string, string>>;
433
449
  readonly en: Readonly<Record<string, string>>;
@@ -1,3 +1,4 @@
1
1
  import { en } from './en.js';
2
2
  import { zh } from './zh.js';
3
+ /** 外壳自带的两份词表(`zh` 为基准、`en` 同构):`client.tsx` 拿它当合并各套件词表的底座。 */
3
4
  export const dictionaries = { zh, en };
@@ -1,15 +1,20 @@
1
1
  import type { Dictionaries } from './index.js';
2
+ /** 一个套件交上来的词表:`unit` 是套件 id(也是键前缀),`messages` 缺省表示这次不参与合并。 */
2
3
  export interface MessagesContribution {
3
4
  readonly unit: string;
4
5
  readonly messages?: Dictionaries | undefined;
5
6
  }
7
+ /** 把各套件的词表合到外壳底座上:键必须以 `<unit>.` 开头、不许撞已有键,违规当场抛错。 */
6
8
  export declare function mergeMessages(base: Dictionaries, contributions: readonly MessagesContribution[]): Dictionaries;
9
+ /** 一条没合进去的贡献:哪个套件 + 为什么被拒(人话原因)。 */
7
10
  export interface MessagesProblem {
8
11
  readonly unit: string;
9
12
  readonly reason: string;
10
13
  }
14
+ /** 合并结果:合出来的词表 + 被跳过的贡献;`problems` 为空即全部合上了。 */
11
15
  export interface MessagesMerge {
12
16
  readonly dictionaries: Dictionaries;
13
17
  readonly problems: readonly MessagesProblem[];
14
18
  }
19
+ /** 逐份试合、坏的跳过:一份贡献不合规只记进 `problems`,不影响其余套件与已有词表。 */
15
20
  export declare function mergeMessagesSkipping(base: Dictionaries, contributions: readonly MessagesContribution[]): MessagesMerge;
@@ -14,6 +14,7 @@ function assertSelfConsistent(unit, messages) {
14
14
  }
15
15
  }
16
16
  }
17
+ /** 把各套件的词表合到外壳底座上:键必须以 `<unit>.` 开头、不许撞已有键,违规当场抛错。 */
17
18
  export function mergeMessages(base, contributions) {
18
19
  const zh = { ...base.zh };
19
20
  const en = { ...base.en };
@@ -43,6 +44,7 @@ function reasonOf(error) {
43
44
  return error.message;
44
45
  return typeof error === 'string' ? error : String(error);
45
46
  }
47
+ /** 逐份试合、坏的跳过:一份贡献不合规只记进 `problems`,不影响其余套件与已有词表。 */
46
48
  export function mergeMessagesSkipping(base, contributions) {
47
49
  let dictionaries = base;
48
50
  const accepted = [];