@dsh-workbench/shared 0.1.0

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 (206) hide show
  1. package/dist/api/blocker-table.d.ts +9 -0
  2. package/dist/api/blocker-table.js +130 -0
  3. package/dist/api/blocker.d.ts +30 -0
  4. package/dist/api/blocker.js +1 -0
  5. package/dist/api/context-ref.d.ts +10 -0
  6. package/dist/api/context-ref.js +40 -0
  7. package/dist/api/dsh-client.d.ts +170 -0
  8. package/dist/api/dsh-client.js +1 -0
  9. package/dist/api/dsh.d.ts +153 -0
  10. package/dist/api/dsh.js +1 -0
  11. package/dist/api/facts.d.ts +27 -0
  12. package/dist/api/facts.js +146 -0
  13. package/dist/api/host-write.d.ts +12 -0
  14. package/dist/api/host-write.js +17 -0
  15. package/dist/api/long-task.d.ts +18 -0
  16. package/dist/api/long-task.js +22 -0
  17. package/dist/api/unit-board.d.ts +14 -0
  18. package/dist/api/unit-board.js +29 -0
  19. package/dist/api/unit.d.ts +54 -0
  20. package/dist/api/unit.js +1 -0
  21. package/dist/api/workbench-client.d.ts +19 -0
  22. package/dist/api/workbench-client.js +33 -0
  23. package/dist/api/workbench-contract.d.ts +32 -0
  24. package/dist/api/workbench-contract.js +1 -0
  25. package/dist/components/ApprovalDetail.d.ts +27 -0
  26. package/dist/components/ApprovalDetail.js +33 -0
  27. package/dist/components/CardHead.d.ts +16 -0
  28. package/dist/components/CardHead.js +14 -0
  29. package/dist/components/ChoiceGroup.d.ts +14 -0
  30. package/dist/components/ChoiceGroup.js +7 -0
  31. package/dist/components/LongTaskRow.d.ts +16 -0
  32. package/dist/components/LongTaskRow.js +28 -0
  33. package/dist/components/MockStrip.d.ts +14 -0
  34. package/dist/components/MockStrip.js +7 -0
  35. package/dist/components/ResourceStates.d.ts +18 -0
  36. package/dist/components/ResourceStates.js +17 -0
  37. package/dist/components/SaveBar.d.ts +12 -0
  38. package/dist/components/SaveBar.js +6 -0
  39. package/dist/components/StateDot.d.ts +5 -0
  40. package/dist/components/StateDot.js +10 -0
  41. package/dist/components/board-module.d.ts +67 -0
  42. package/dist/components/board-module.js +1 -0
  43. package/dist/components/icons.d.ts +18 -0
  44. package/dist/components/icons.js +81 -0
  45. package/dist/config/constants.d.ts +27 -0
  46. package/dist/config/constants.js +27 -0
  47. package/dist/config/storage.d.ts +4 -0
  48. package/dist/config/storage.js +27 -0
  49. package/dist/host/__tests__/fakes.d.ts +41 -0
  50. package/dist/host/__tests__/fakes.js +76 -0
  51. package/dist/host/__tests__/preflight-fixtures.d.ts +19 -0
  52. package/dist/host/__tests__/preflight-fixtures.js +47 -0
  53. package/dist/host/cli-error.d.ts +8 -0
  54. package/dist/host/cli-error.js +70 -0
  55. package/dist/host/context-inject.d.ts +24 -0
  56. package/dist/host/context-inject.js +74 -0
  57. package/dist/host/data-root.d.ts +3 -0
  58. package/dist/host/data-root.js +12 -0
  59. package/dist/host/events.d.ts +9 -0
  60. package/dist/host/events.js +70 -0
  61. package/dist/host/facts.d.ts +24 -0
  62. package/dist/host/facts.js +44 -0
  63. package/dist/host/git.d.ts +55 -0
  64. package/dist/host/git.js +64 -0
  65. package/dist/host/http.d.ts +36 -0
  66. package/dist/host/http.js +242 -0
  67. package/dist/host/long-task.d.ts +58 -0
  68. package/dist/host/long-task.js +148 -0
  69. package/dist/host/mount-units.d.ts +52 -0
  70. package/dist/host/mount-units.js +186 -0
  71. package/dist/host/opencli-runtime.d.ts +22 -0
  72. package/dist/host/opencli-runtime.js +46 -0
  73. package/dist/host/opencli.d.ts +37 -0
  74. package/dist/host/opencli.js +152 -0
  75. package/dist/host/plugin-source.d.ts +31 -0
  76. package/dist/host/plugin-source.js +81 -0
  77. package/dist/host/preflight.d.ts +58 -0
  78. package/dist/host/preflight.js +233 -0
  79. package/dist/host/probe-cache.d.ts +6 -0
  80. package/dist/host/probe-cache.js +19 -0
  81. package/dist/host/probe-libs.d.ts +45 -0
  82. package/dist/host/probe-libs.js +61 -0
  83. package/dist/host/probe-units.d.ts +17 -0
  84. package/dist/host/probe-units.js +102 -0
  85. package/dist/host/probe-verdict.d.ts +7 -0
  86. package/dist/host/probe-verdict.js +143 -0
  87. package/dist/host/provision.d.ts +14 -0
  88. package/dist/host/provision.js +12 -0
  89. package/dist/host/shell.d.ts +14 -0
  90. package/dist/host/shell.js +23 -0
  91. package/dist/host/tool-approval.d.ts +29 -0
  92. package/dist/host/tool-approval.js +190 -0
  93. package/dist/host/tool-kit.d.ts +19 -0
  94. package/dist/host/tool-kit.js +37 -0
  95. package/dist/host/tool-scope.d.ts +32 -0
  96. package/dist/host/tool-scope.js +84 -0
  97. package/dist/host/unit-face.d.ts +66 -0
  98. package/dist/host/unit-face.js +1 -0
  99. package/dist/host/unit-libs.d.ts +37 -0
  100. package/dist/host/unit-libs.js +1 -0
  101. package/dist/host/unit-readiness.d.ts +7 -0
  102. package/dist/host/unit-readiness.js +5 -0
  103. package/dist/host/unit-registry.d.ts +9 -0
  104. package/dist/host/unit-registry.js +33 -0
  105. package/dist/host/value-handoff.d.ts +16 -0
  106. package/dist/host/value-handoff.js +21 -0
  107. package/dist/host/version-range.d.ts +2 -0
  108. package/dist/host/version-range.js +73 -0
  109. package/dist/host/workspace-store.d.ts +19 -0
  110. package/dist/host/workspace-store.js +133 -0
  111. package/dist/host/write-result.d.ts +1 -0
  112. package/dist/host/write-result.js +18 -0
  113. package/dist/host.d.ts +19 -0
  114. package/dist/host.js +19 -0
  115. package/dist/i18n/en.d.ts +2 -0
  116. package/dist/i18n/en.js +162 -0
  117. package/dist/i18n/index.d.ts +172 -0
  118. package/dist/i18n/index.js +3 -0
  119. package/dist/i18n/merge.d.ts +6 -0
  120. package/dist/i18n/merge.js +40 -0
  121. package/dist/i18n/zh.d.ts +163 -0
  122. package/dist/i18n/zh.js +162 -0
  123. package/dist/index.d.ts +33 -0
  124. package/dist/index.js +33 -0
  125. package/dist/lib/blocker-action.d.ts +13 -0
  126. package/dist/lib/blocker-action.js +12 -0
  127. package/dist/lib/busy.d.ts +5 -0
  128. package/dist/lib/busy.js +7 -0
  129. package/dist/lib/react.d.ts +10 -0
  130. package/dist/lib/react.js +9 -0
  131. package/dist/lib/text.d.ts +4 -0
  132. package/dist/lib/text.js +48 -0
  133. package/dist/lib/ui.d.ts +11 -0
  134. package/dist/lib/ui.js +37 -0
  135. package/package.json +44 -0
  136. package/src/api/__tests__/blocker-table.test.ts +253 -0
  137. package/src/api/__tests__/facts.test.ts +274 -0
  138. package/src/api/__tests__/host-write.test.ts +55 -0
  139. package/src/api/__tests__/long-task.test.ts +52 -0
  140. package/src/api/__tests__/unit-board.test.ts +76 -0
  141. package/src/api/blocker-table.ts +155 -0
  142. package/src/api/blocker.ts +25 -0
  143. package/src/api/context-ref.ts +47 -0
  144. package/src/api/dsh-client.ts +176 -0
  145. package/src/api/dsh.ts +156 -0
  146. package/src/api/facts.ts +166 -0
  147. package/src/api/host-write.ts +27 -0
  148. package/src/api/long-task.ts +38 -0
  149. package/src/api/unit-board.ts +44 -0
  150. package/src/api/unit.ts +59 -0
  151. package/src/api/workbench-client.test.ts +92 -0
  152. package/src/api/workbench-client.ts +59 -0
  153. package/src/api/workbench-contract.ts +40 -0
  154. package/src/components/ApprovalDetail.tsx +57 -0
  155. package/src/components/CardHead.tsx +74 -0
  156. package/src/components/ChoiceGroup.tsx +38 -0
  157. package/src/components/LongTaskRow.tsx +65 -0
  158. package/src/components/MockStrip.tsx +40 -0
  159. package/src/components/ResourceStates.tsx +44 -0
  160. package/src/components/SaveBar.tsx +31 -0
  161. package/src/components/StateDot.tsx +31 -0
  162. package/src/components/board-module.ts +73 -0
  163. package/src/components/icons.tsx +232 -0
  164. package/src/config/constants.test.ts +41 -0
  165. package/src/config/constants.ts +52 -0
  166. package/src/config/storage.test.ts +82 -0
  167. package/src/config/storage.ts +25 -0
  168. package/src/host/__tests__/fakes.ts +116 -0
  169. package/src/host/__tests__/opencli-runtime.test.ts +46 -0
  170. package/src/host/cli-error.ts +77 -0
  171. package/src/host/data-root.ts +13 -0
  172. package/src/host/facts.ts +69 -0
  173. package/src/host/git.ts +99 -0
  174. package/src/host/http.ts +311 -0
  175. package/src/host/long-task.ts +235 -0
  176. package/src/host/opencli-runtime.ts +66 -0
  177. package/src/host/opencli.ts +210 -0
  178. package/src/host/plugin-source.ts +145 -0
  179. package/src/host/provision.ts +34 -0
  180. package/src/host/shell.ts +42 -0
  181. package/src/host/tool-approval.ts +243 -0
  182. package/src/host/tool-kit.ts +56 -0
  183. package/src/host/unit-face.ts +65 -0
  184. package/src/host/unit-libs.ts +41 -0
  185. package/src/host/value-handoff.ts +38 -0
  186. package/src/host/workspace-store.ts +161 -0
  187. package/src/host/write-result.ts +16 -0
  188. package/src/host.ts +19 -0
  189. package/src/i18n/en.ts +170 -0
  190. package/src/i18n/index.test.ts +15 -0
  191. package/src/i18n/index.ts +12 -0
  192. package/src/i18n/merge.test.ts +60 -0
  193. package/src/i18n/merge.ts +54 -0
  194. package/src/i18n/zh.test.ts +40 -0
  195. package/src/i18n/zh.ts +170 -0
  196. package/src/index.ts +33 -0
  197. package/src/lib/blocker-action.test.ts +40 -0
  198. package/src/lib/blocker-action.ts +28 -0
  199. package/src/lib/busy.test.ts +27 -0
  200. package/src/lib/busy.ts +11 -0
  201. package/src/lib/react.test.ts +26 -0
  202. package/src/lib/react.ts +16 -0
  203. package/src/lib/text.test.ts +92 -0
  204. package/src/lib/text.ts +46 -0
  205. package/src/lib/ui.test.ts +93 -0
  206. package/src/lib/ui.ts +38 -0
@@ -0,0 +1,162 @@
1
+ export const zh = {
2
+ 'brand.name': '工作台',
3
+ 'toggle.open': '打开侧边栏',
4
+ 'toggle.collapse': '收起侧边栏',
5
+ 'project.label': '切换项目',
6
+ 'workspace.section': '工作区',
7
+ 'project.none': '未选择项目',
8
+ 'project.empty': '还没有项目。用下面的「添加项目」选一个目录。',
9
+ 'project.add': '添加项目…',
10
+ 'session.new': '新会话',
11
+ 'session.new.label': '在当前项目新建会话',
12
+ 'session.empty': '这个项目还没有会话。',
13
+ 'session.noProject': '先添加一个项目。',
14
+ 'session.pinned': '已置顶',
15
+ 'session.actions': '{name} 的操作',
16
+ 'status.idle': '空闲',
17
+ 'status.running': '运行中',
18
+ 'status.waitingApproval': '等待授权',
19
+ 'status.planReview': '等待计划确认',
20
+ 'status.waitingAnswer': '等待回答',
21
+ 'status.completed': '已完成',
22
+ 'status.subagentsRunning.one': '{n} 个子代理运行中',
23
+ 'status.subagentsRunning.other': '{n} 个子代理运行中',
24
+ 'time.now': '刚刚',
25
+ 'time.minutes': '{n} 分钟前',
26
+ 'time.hours': '{n} 小时前',
27
+ 'time.days': '{n} 天前',
28
+ 'panels.title': '面板模块',
29
+ 'panels.reset': '恢复默认',
30
+ 'panels.enabled': '这个项目已启用',
31
+ 'panels.disabled': '这个项目未启用',
32
+ 'panels.choose': '选择模块',
33
+ 'panels.failed': '改配置失败了,再试一次。',
34
+ 'panels.hintEffect': '停用 = agent 拿不到相关数据',
35
+ 'panels.dragHint': '拖动调整顺序',
36
+ 'panels.unknownStep': '这一层没有套件提供',
37
+ 'panels.labelWithHint': '{label}({hint})',
38
+ 'panels.dep.missingPlugin': '⚠ 还没装好',
39
+ 'panels.dep.missingCommands': '⚠ 需要更新',
40
+ 'panels.dep.unchecked': '⚠ 检测不了',
41
+ 'panels.tab.modules': '面板配置',
42
+ 'panels.tab.market': '工作台模块市场',
43
+ 'panels.browseMarket': '浏览模块市场',
44
+ 'panels.noneInstalled': '这些模块要的插件都还没装',
45
+ 'panels.noneInstalledHint': '装好之后它们会回到这里,再由你决定放哪几个上板。',
46
+ 'panels.market.installed': '已装',
47
+ 'panels.market.outdated': '要更新',
48
+ 'panels.market.hasNew': '有新版本',
49
+ 'panels.market.missing': '未装',
50
+ 'panels.market.unchecked': '状态未知',
51
+ 'panels.market.checking': '检测中',
52
+ 'panels.market.sectionInstalled': '已安装',
53
+ 'panels.market.sectionPending': '未安装',
54
+ 'panels.market.sectionShared': '共用依赖',
55
+ 'panels.market.sharedUsedBy': '供 {modules} 使用',
56
+ 'panels.market.listSeparator': '、',
57
+ 'panels.market.sharedMissing': '未装',
58
+ 'panels.market.sharedOutdated': '有新版',
59
+ 'panels.market.sharedUnsatisfied': '版本不对',
60
+ 'panels.market.sharedOk': '已装',
61
+ 'panels.market.versionArrow': '{from} → {to}',
62
+ 'panels.market.lead': '装在这台机器上,所有项目共用。',
63
+ 'panels.market.install': '安装',
64
+ 'panels.market.update': '更新',
65
+ 'panels.market.uninstall': '卸载',
66
+ 'panels.market.installing': '正在安装…',
67
+ 'panels.market.updating': '正在更新…',
68
+ 'panels.market.uninstalling': '正在卸载…',
69
+ 'panels.market.confirmUninstall': '要卸载吗?',
70
+ 'panels.market.confirmUninstallDetail': '卸载后这台机器上就没有它了,所有项目的面板也会把它一起拿掉(绑定与设置不会丢)。',
71
+ 'panels.market.confirmYes': '确定卸载',
72
+ 'panels.market.confirmNo': '取消',
73
+ 'panels.market.failed': '没成功:{reason}',
74
+ 'panels.market.needEnv': '先在启动工作台的终端里设 {env}',
75
+ 'panels.market.noSource': '这个模块没声明怎么装,只能自己动手',
76
+ 'panels.market.badSource': '安装方式没写全,只能自己动手',
77
+ 'panels.market.empty': '暂无可用模块',
78
+ 'panels.market.foot': '装好后到那个项目的面板页勾选它,模块才会出现。',
79
+ 'panels.market.recheck': '重新检查更新',
80
+ 'panels.market.checkUpdates': '检查更新',
81
+ 'panels.market.checkedAt': '最近检查:{time}',
82
+ 'panels.market.justNow': '刚刚',
83
+ 'panels.market.minutesAgo': '{n} 分钟前',
84
+ 'panels.market.hoursAgo': '{n} 小时前',
85
+ 'blocker.fix.install': '帮我安装',
86
+ 'blocker.fix.update': '帮我升级',
87
+ 'blocker.fix.running': '正在执行…',
88
+ 'blocker.fix.failed': '执行失败:',
89
+ 'blocker.retry': '重试',
90
+ 'blocker.retry.running': '重试中…',
91
+ 'blocker.copy': '复制命令',
92
+ 'blocker.market.open': '去模块市场',
93
+ 'blocker.login.title': '需要登录 {platform}',
94
+ 'blocker.login.titleGeneric': '需要登录',
95
+ 'blocker.login.hint': '工作台用你的浏览器登录态;登录一次就行,之后不用再登。',
96
+ 'blocker.login.go': '去登录',
97
+ 'blocker.login.manual': '在终端执行 `opencli coding team-current`,按提示完成登录后重试。',
98
+ 'blocker.forbidden.title': '没有权限访问 {platform}',
99
+ 'blocker.forbidden.titleGeneric': '没有权限',
100
+ 'blocker.forbidden.hint': '账号已登录,但没有这个项目/仓库的权限;申请之后再试。',
101
+ 'blocker.forbidden.open': '打开权限页',
102
+ 'blocker.timeout.hint': '无头浏览器可能没起来,重试一次通常就好。',
103
+ 'blocker.exec.hint': '确认 opencli 已安装且在 PATH 里(which opencli)。',
104
+ 'blocker.unknown.title': '出了点问题',
105
+ 'panels.reading': '正在读取面板配置…',
106
+ 'panels.empty': '面板里还没有模块',
107
+ 'panels.emptyHint': '也可以直接跟 agent 说:「把某个模块加到面板」。',
108
+ 'env.title': '准备工作台',
109
+ 'env.checking': '正在检测运行环境…',
110
+ 'env.installing': '正在安装缺失的依赖…',
111
+ 'env.failed': '还差一步就能用了',
112
+ 'env.elapsed': '已等待 {seconds} 秒',
113
+ 'env.stepFailed.install': '装不上',
114
+ 'env.stepFailed.path': '装了但还找不到',
115
+ 'env.stepFailed.shell': '执行通道不可用',
116
+ 'env.bridge.ok': '已连接',
117
+ 'env.bridge.short': '没连上',
118
+ 'env.bridge.why': '面板的数据要走你浏览器里的登录态:这个通道没连上,模块就取不到数据(不拦路,但先修好它)。',
119
+ 'env.bridge.daemon': '后台服务没起来:正常它会自己起,先在终端跑下面这条命令。',
120
+ 'env.bridge.extension': '浏览器扩展没连上:在 Chrome 应用商店装一次就好(装完回来点「重试」)。已经装过的话,先跑下面这条命令。',
121
+ 'env.bridge.extensionLink': '去 Chrome 应用商店装扩展',
122
+ 'env.bridge.profile': '连上了多个浏览器 profile,但没选默认的那个:先看有哪些(下面这条命令),再选一个。',
123
+ 'env.bridge.stale': '默认的浏览器 profile 已经失效(它记的是上一次的扩展实例):重新选一个。',
124
+ 'env.bridge.unknown': '没认出是哪种问题:下面原始输出里有 opencli 自己给的步骤。',
125
+ 'env.fix.title': '怎么解决',
126
+ 'env.fix.why': '工作台用它自己那份 opencli(与你在终端里那套分开装,互不影响),这台机器上还没装好它。',
127
+ 'env.fix.whyPath': 'opencli 装上了,但当前环境还找不到它 —— 通常是 PATH 或终端会话的问题。',
128
+ 'env.fix.whyShell': '工作台拿不到执行命令的通道,所以取不了数据 —— 这一步用户自己装不了。',
129
+ 'env.fix.step': '在终端里运行下面这条命令,装好之后点「重试」:',
130
+ 'env.fix.stepPath': '新开一个终端窗口(或确认 npm 的全局 bin 目录在 PATH 里),然后点「重试」。',
131
+ 'env.fix.stepShell': '重启一次工作台(或 dsh);如果反复出现,说明执行通道没配好。',
132
+ 'env.fix.permission': '权限不够:在命令前加 sudo 重跑,或先把 npm 的全局目录配到你的用户目录。',
133
+ 'env.fix.network': '网络不通:检查网络或代理设置后重试。',
134
+ 'env.fix.details': '详细输出(排障用)',
135
+ 'env.retry': '重试',
136
+ 'env.copyCommand': '复制命令',
137
+ 'env.copied': '已复制',
138
+ 'env.step.opencli': '检测工作台的 opencli',
139
+ 'env.step.codingPlugin': '检测 coding 插件',
140
+ 'env.step.bridge': '检测浏览器通道',
141
+ 'env.step.warm': '预热站点登录态',
142
+ 'env.warm.done': '已预热 {n} 个站点',
143
+ 'env.warm.short': '这次没热上 —— 不影响用,面板第一次读取会自己补',
144
+ 'env.unit.missingPlugin': '这个模块还没装好',
145
+ 'env.unit.missingCommandsHint': '更新之后就能用了。',
146
+ 'env.unit.unchecked': '检测不了:拿不到执行通道',
147
+ 'env.unit.uncheckedHint': '不是这个模块的问题,是执行通道不可用 —— 重启一次工作台再试。',
148
+ 'env.unit.missingCommands': '这个模块的版本旧了',
149
+ 'env.unit.hint': '装好之后点重试;不影响其它模块。',
150
+ 'rightbar.label': '数据面板',
151
+ 'rightbar.expand': '展开数据面板',
152
+ 'rightbar.collapse': '收起数据面板',
153
+ 'rightbar.refresh': '刷新',
154
+ 'rightbar.refreshing': '刷新中…',
155
+ 'rightbar.updatedAt': '更新于 {time}',
156
+ 'rightbar.noProject': '当前会话没有所属项目',
157
+ 'coding.notARepo.title': '这个项目不是 Coding 仓库',
158
+ 'error.unknown': '出错了',
159
+ 'board.title': '看板',
160
+ 'panel.conversation': '对话',
161
+ 'panels.label': '全局面板',
162
+ };
@@ -0,0 +1,33 @@
1
+ export * from './api/blocker-table';
2
+ export * from './api/blocker';
3
+ export * from './api/context-ref';
4
+ export * from './api/dsh-client';
5
+ export * from './api/dsh';
6
+ export * from './api/facts';
7
+ export * from './api/host-write';
8
+ export * from './api/long-task';
9
+ export * from './api/unit-board';
10
+ export * from './api/unit';
11
+ export * from './api/workbench-client';
12
+ export * from './api/workbench-contract';
13
+ export * from './components/ApprovalDetail';
14
+ export * from './components/CardHead';
15
+ export * from './components/ChoiceGroup';
16
+ export * from './components/LongTaskRow';
17
+ export * from './components/MockStrip';
18
+ export * from './components/ResourceStates';
19
+ export * from './components/SaveBar';
20
+ export * from './components/StateDot';
21
+ export * from './components/board-module';
22
+ export * from './components/icons';
23
+ export * from './config/constants';
24
+ export * from './config/storage';
25
+ export * from './i18n/en';
26
+ export * from './i18n/index';
27
+ export * from './i18n/merge';
28
+ export * from './i18n/zh';
29
+ export * from './lib/blocker-action';
30
+ export * from './lib/busy';
31
+ export * from './lib/react';
32
+ export * from './lib/text';
33
+ export * from './lib/ui';
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ export * from './api/blocker-table';
2
+ export * from './api/blocker';
3
+ export * from './api/context-ref';
4
+ export * from './api/dsh-client';
5
+ export * from './api/dsh';
6
+ export * from './api/facts';
7
+ export * from './api/host-write';
8
+ export * from './api/long-task';
9
+ export * from './api/unit-board';
10
+ export * from './api/unit';
11
+ export * from './api/workbench-client';
12
+ export * from './api/workbench-contract';
13
+ export * from './components/ApprovalDetail';
14
+ export * from './components/CardHead';
15
+ export * from './components/ChoiceGroup';
16
+ export * from './components/LongTaskRow';
17
+ export * from './components/MockStrip';
18
+ export * from './components/ResourceStates';
19
+ export * from './components/SaveBar';
20
+ export * from './components/StateDot';
21
+ export * from './components/board-module';
22
+ export * from './components/icons';
23
+ export * from './config/constants';
24
+ export * from './config/storage';
25
+ export * from './i18n/en';
26
+ export * from './i18n/index';
27
+ export * from './i18n/merge';
28
+ export * from './i18n/zh';
29
+ export * from './lib/blocker-action';
30
+ export * from './lib/busy';
31
+ export * from './lib/react';
32
+ export * from './lib/text';
33
+ export * from './lib/ui';
@@ -0,0 +1,13 @@
1
+ export type BlockerLabelTranslate = (key: string) => string;
2
+ export interface BlockerActionShape {
3
+ readonly kind: string;
4
+ readonly label: string;
5
+ readonly text?: string | undefined;
6
+ }
7
+ export interface BlockerLabelState {
8
+ readonly retrying: boolean;
9
+ readonly running: string | null;
10
+ readonly copied: string | null;
11
+ }
12
+ export declare function blockerPending(busy: boolean, running: string | null): boolean;
13
+ export declare function blockerActionLabel(action: BlockerActionShape, state: BlockerLabelState, t: BlockerLabelTranslate): string;
@@ -0,0 +1,12 @@
1
+ export function blockerPending(busy, running) {
2
+ return busy || running !== null;
3
+ }
4
+ export function blockerActionLabel(action, state, t) {
5
+ if (action.kind === 'retry' && state.retrying)
6
+ return t('blocker.retry.running');
7
+ if (state.running === action.label)
8
+ return t('blocker.fix.running');
9
+ if (action.kind === 'copy' && state.copied === action.text)
10
+ return t('env.copied');
11
+ return action.label;
12
+ }
@@ -0,0 +1,5 @@
1
+ export interface BusyHold {
2
+ readonly visible: boolean;
3
+ readonly releaseInMs: number;
4
+ }
5
+ export declare function holdBusy(since: number | null, now: number, floorMs: number): BusyHold;
@@ -0,0 +1,7 @@
1
+ export function holdBusy(since, now, floorMs) {
2
+ if (since === null)
3
+ return { visible: false, releaseInMs: 0 };
4
+ const elapsed = Math.max(0, now - since);
5
+ const left = floorMs - elapsed;
6
+ return left <= 0 ? { visible: false, releaseInMs: 0 } : { visible: true, releaseInMs: left };
7
+ }
@@ -0,0 +1,10 @@
1
+ import type * as ReactTypes from 'react';
2
+ export declare const h: typeof ReactTypes.createElement;
3
+ export declare const Fragment: ReactTypes.ExoticComponent<ReactTypes.FragmentProps>;
4
+ export declare const useState: typeof ReactTypes.useState;
5
+ export declare const useEffect: typeof ReactTypes.useEffect;
6
+ export declare const useMemo: typeof ReactTypes.useMemo;
7
+ export declare const useCallback: typeof ReactTypes.useCallback;
8
+ export declare const useRef: typeof ReactTypes.useRef;
9
+ export declare const useSyncExternalStore: typeof ReactTypes.useSyncExternalStore;
10
+ export type { ReactNode, CSSProperties, ChangeEvent } from 'react';
@@ -0,0 +1,9 @@
1
+ const react = require('react');
2
+ export const h = react.createElement;
3
+ export const Fragment = react.Fragment;
4
+ export const useState = react.useState;
5
+ export const useEffect = react.useEffect;
6
+ export const useMemo = react.useMemo;
7
+ export const useCallback = react.useCallback;
8
+ export const useRef = react.useRef;
9
+ export const useSyncExternalStore = react.useSyncExternalStore;
@@ -0,0 +1,4 @@
1
+ export declare function quoteShellArg(value: unknown): string;
2
+ export declare function tailLines(text: string | null | undefined, lines?: number): string;
3
+ export declare function parseJsonLoose(text: string | null | undefined): unknown;
4
+ export declare function excerpt(text: string | null | undefined, limit?: number): string;
@@ -0,0 +1,48 @@
1
+ export function quoteShellArg(value) {
2
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
3
+ }
4
+ export function tailLines(text, lines = 6) {
5
+ const all = String(text ?? '')
6
+ .trim()
7
+ .split('\n');
8
+ return all.slice(-lines).join('\n');
9
+ }
10
+ export function parseJsonLoose(text) {
11
+ const raw = String(text ?? '').trim();
12
+ if (!raw)
13
+ return undefined;
14
+ try {
15
+ return JSON.parse(raw);
16
+ }
17
+ catch {
18
+ const starts = [raw.indexOf('['), raw.indexOf('{')].filter((index) => index >= 0);
19
+ if (starts.length === 0)
20
+ return undefined;
21
+ const from = Math.min(...starts);
22
+ const open = raw[from];
23
+ const close = open === '[' ? ']' : '}';
24
+ const to = raw.lastIndexOf(close);
25
+ if (to <= from)
26
+ return undefined;
27
+ try {
28
+ return JSON.parse(raw.slice(from, to + 1));
29
+ }
30
+ catch {
31
+ return undefined;
32
+ }
33
+ }
34
+ }
35
+ const MARKDOWN_IMAGE = /!\[[^\]]*\]\([^)]*\)/g;
36
+ const MARKDOWN_LINK = /\[([^\]]*)\]\([^)]*\)/g;
37
+ const MARKDOWN_MARKS = /[*`_>#]/g;
38
+ export function excerpt(text, limit = 80) {
39
+ const flat = String(text ?? '')
40
+ .replace(MARKDOWN_IMAGE, ' ')
41
+ .replace(MARKDOWN_LINK, '$1')
42
+ .replace(MARKDOWN_MARKS, ' ')
43
+ .replace(/\s+/g, ' ')
44
+ .trim();
45
+ if (flat.length <= limit)
46
+ return flat;
47
+ return `${flat.slice(0, limit).trimEnd()}…`;
48
+ }
@@ -0,0 +1,11 @@
1
+ export declare function cx(...parts: Array<string | false | null | undefined>): string;
2
+ export type TimeTranslate = (key: string, params?: Record<string, unknown>) => string;
3
+ export declare function relativeTime(epochMs: number, t: TimeTranslate): string;
4
+ export declare function shortenPath(path: unknown): string;
5
+ export declare const LINK_BUTTON_STYLE: {
6
+ readonly display: "inline-flex";
7
+ readonly alignItems: "center";
8
+ readonly gap: "var(--wb-gap-xs)";
9
+ readonly textDecoration: "none";
10
+ };
11
+ export declare function parseLocalTimestamp(text: string | null | undefined): number;
package/dist/lib/ui.js ADDED
@@ -0,0 +1,37 @@
1
+ export function cx(...parts) {
2
+ return parts.filter(Boolean).join(' ');
3
+ }
4
+ const MINUTE = 60 * 1000;
5
+ export function relativeTime(epochMs, t) {
6
+ if (!Number.isFinite(epochMs))
7
+ return '';
8
+ const diff = Date.now() - epochMs;
9
+ if (diff < MINUTE)
10
+ return t('time.now');
11
+ if (diff < 60 * MINUTE)
12
+ return t('time.minutes', { n: Math.floor(diff / MINUTE) });
13
+ if (diff < 24 * 60 * MINUTE)
14
+ return t('time.hours', { n: Math.floor(diff / (60 * MINUTE)) });
15
+ if (diff < 7 * 24 * 60 * MINUTE)
16
+ return t('time.days', { n: Math.floor(diff / (24 * 60 * MINUTE)) });
17
+ return new Date(epochMs).toLocaleDateString();
18
+ }
19
+ export function shortenPath(path) {
20
+ if (typeof path !== 'string')
21
+ return '';
22
+ const hit = path.match(/^\/Users\/[^/]+/);
23
+ return hit === null ? path : path.replace(hit[0], '~');
24
+ }
25
+ export const LINK_BUTTON_STYLE = {
26
+ display: 'inline-flex',
27
+ alignItems: 'center',
28
+ gap: 'var(--wb-gap-xs)',
29
+ textDecoration: 'none',
30
+ };
31
+ const LOCAL_TIMESTAMP = /^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2}):(\d{2})$/;
32
+ export function parseLocalTimestamp(text) {
33
+ const raw = String(text ?? '').trim();
34
+ if (!LOCAL_TIMESTAMP.test(raw))
35
+ return Number.NaN;
36
+ return new Date(raw.replace(' ', 'T')).getTime();
37
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@dsh-workbench/shared",
3
+ "version": "0.1.0",
4
+ "description": "工作台与模块共享的纯代码与契约类型:类型、纯逻辑、哑组件、平台解析。宿主侧的东西从 /host 进(不影响浏览器产物)。",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "default": "./dist/index.js"
11
+ },
12
+ "./host": {
13
+ "types": "./dist/host.d.ts",
14
+ "default": "./dist/host.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "src",
19
+ "dist"
20
+ ],
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "peerDependencies": {
25
+ "react": "*"
26
+ },
27
+ "devDependencies": {
28
+ "@arch-guard/core": "^0.10.0",
29
+ "@types/node": "^20.0.0",
30
+ "@types/react": "^19.0.0",
31
+ "@vitest/coverage-v8": "^5.0.2",
32
+ "react": "^18.0.0",
33
+ "vitest": "^5.0.2"
34
+ },
35
+ "scripts": {
36
+ "build": "tsc -p tsconfig.build.json",
37
+ "typecheck": "tsc --noEmit",
38
+ "test": "vitest run",
39
+ "coverage": "vitest run --coverage",
40
+ "selfcheck": "node scripts/check-state.mjs",
41
+ "arch:report": "arch-guard --report-only",
42
+ "arch": "arch-guard"
43
+ }
44
+ }