@dsh-workbench/shared 0.3.10 → 1.0.0-beta.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 (391) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +97 -0
  3. package/dist/api/blocker-table.d.ts +3 -3
  4. package/dist/api/blocker-table.js +47 -23
  5. package/dist/api/dsh.d.ts +19 -1
  6. package/dist/api/host-write.d.ts +0 -15
  7. package/dist/api/host-write.js +1 -35
  8. package/dist/api/workbench-client.js +2 -1
  9. package/dist/components/Activity.css +0 -1
  10. package/dist/components/ApprovalDetail.css +1 -2
  11. package/dist/components/ApprovalDetail.d.ts +1 -1
  12. package/dist/components/ApprovalPlan.css +0 -1
  13. package/dist/components/Card.css +0 -1
  14. package/dist/components/Card.d.ts +1 -1
  15. package/dist/components/CardBoundary.d.ts +1 -1
  16. package/dist/components/CardHead.css +0 -1
  17. package/dist/components/CardHead.d.ts +1 -1
  18. package/dist/components/ChoiceGroup.css +1 -2
  19. package/dist/components/ConfirmBar.d.ts +1 -1
  20. package/dist/components/ConfirmBar.js +1 -1
  21. package/dist/components/Form.css +1 -1
  22. package/dist/components/FormActions.js +1 -1
  23. package/dist/components/LongTaskRow.css +1 -2
  24. package/dist/components/LongTaskRow.d.ts +1 -1
  25. package/dist/components/LongTaskRow.js +1 -1
  26. package/dist/components/Note.css +0 -1
  27. package/dist/components/ResourceStates.css +0 -1
  28. package/dist/components/SettingsSection.css +0 -1
  29. package/dist/components/Spinner.css +0 -1
  30. package/dist/components/Stack.css +0 -1
  31. package/dist/components/StateBlock.css +0 -1
  32. package/dist/components/board-module.d.ts +3 -3
  33. package/dist/components/icons.d.ts +1 -7
  34. package/dist/components/icons.js +11 -16
  35. package/dist/config/constants.d.ts +2 -2
  36. package/dist/config/constants.js +2 -2
  37. package/dist/config/storage.d.ts +0 -4
  38. package/dist/config/storage.js +0 -11
  39. package/dist/contract/adapters.d.ts +10 -0
  40. package/dist/contract/cli.d.ts +3 -0
  41. package/dist/contract/data.d.ts +126 -0
  42. package/dist/{api → contract}/facts.d.ts +12 -3
  43. package/dist/{api → contract}/facts.js +19 -1
  44. package/dist/contract/needs.d.ts +132 -0
  45. package/dist/contract/needs.js +232 -0
  46. package/dist/contract/plugin-source.d.ts +1 -0
  47. package/dist/contract/plugin-source.js +1 -0
  48. package/dist/contract/protocol/bundle-install.d.ts +136 -0
  49. package/dist/contract/protocol/bundle-install.js +12 -0
  50. package/dist/contract/protocol/config-sync.d.ts +55 -0
  51. package/dist/contract/protocol/config-sync.js +2 -0
  52. package/dist/contract/protocol/diy.d.ts +4 -0
  53. package/dist/contract/protocol/diy.js +4 -0
  54. package/dist/contract/protocol/dsh-plugins.d.ts +11 -0
  55. package/dist/contract/protocol/dsh-plugins.js +1 -0
  56. package/dist/contract/protocol/long-tasks.d.ts +13 -0
  57. package/dist/contract/protocol/long-tasks.js +1 -0
  58. package/dist/contract/protocol/market-index.d.ts +195 -0
  59. package/dist/contract/protocol/market-index.js +7 -0
  60. package/dist/contract/protocol/platform.d.ts +44 -0
  61. package/dist/contract/protocol/platform.js +1 -0
  62. package/dist/contract/protocol/preflight-wake.d.ts +7 -0
  63. package/dist/contract/protocol/preflight-wake.js +1 -0
  64. package/dist/contract/protocol/profile-create.d.ts +30 -0
  65. package/dist/contract/protocol/profile-create.js +2 -0
  66. package/dist/contract/protocol/sidebar-edition.d.ts +14 -0
  67. package/dist/contract/protocol/sidebar-edition.js +2 -0
  68. package/dist/contract/protocol/unit-manifests.d.ts +6 -0
  69. package/dist/contract/protocol/unit-manifests.js +1 -0
  70. package/dist/contract/unit-board.d.ts +18 -0
  71. package/dist/contract/unit-board.js +1 -0
  72. package/dist/contract/unit-capability.d.ts +34 -0
  73. package/dist/contract/unit-capability.js +1 -0
  74. package/dist/{api → contract}/unit-declaration.d.ts +7 -5
  75. package/dist/{api → contract}/unit-declaration.js +19 -13
  76. package/dist/contract/unit.d.ts +57 -0
  77. package/dist/contract/unit.js +24 -0
  78. package/dist/contract/workbench-contract.d.ts +15 -0
  79. package/dist/contract/workbench-contract.js +1 -0
  80. package/dist/host/adapter-set.d.ts +26 -0
  81. package/dist/host/adapter-set.js +243 -0
  82. package/dist/host/adapter-types.d.ts +79 -0
  83. package/dist/host/adapter-types.js +23 -0
  84. package/dist/host/adapters.d.ts +22 -0
  85. package/dist/host/adapters.js +9 -0
  86. package/dist/host/browser.d.ts +3 -0
  87. package/dist/host/browser.js +3 -0
  88. package/dist/host/changelog.d.ts +21 -0
  89. package/dist/host/changelog.js +188 -0
  90. package/dist/host/channel-plugin.d.ts +15 -0
  91. package/dist/host/channel-plugin.js +42 -0
  92. package/dist/host/cli.d.ts +4 -0
  93. package/dist/host/cli.js +7 -0
  94. package/dist/host/command-name.d.ts +1 -0
  95. package/dist/host/command-name.js +14 -0
  96. package/dist/host/data-error.d.ts +13 -0
  97. package/dist/host/data-error.js +20 -0
  98. package/dist/host/data-root.js +3 -0
  99. package/dist/host/diy-debug.js +2 -1
  100. package/dist/host/diy-record.js +2 -1
  101. package/dist/host/facts.d.ts +1 -1
  102. package/dist/host/facts.js +3 -2
  103. package/dist/host/git.js +2 -2
  104. package/dist/host/http.js +1 -1
  105. package/dist/host/lib-capabilities.d.ts +22 -0
  106. package/dist/host/lib-capabilities.js +37 -0
  107. package/dist/host/lib-install.d.ts +9 -0
  108. package/dist/host/lib-install.js +10 -0
  109. package/dist/host/long-task.d.ts +1 -1
  110. package/dist/host/long-task.js +4 -3
  111. package/dist/host/market-index.d.ts +22 -0
  112. package/dist/host/market-index.js +420 -0
  113. package/dist/host/needs.d.ts +4 -0
  114. package/dist/host/needs.js +2 -0
  115. package/dist/host/patch.d.ts +9 -0
  116. package/dist/host/patch.js +78 -0
  117. package/dist/host/paths.d.ts +12 -0
  118. package/dist/host/paths.js +28 -0
  119. package/dist/host/platform.d.ts +14 -0
  120. package/dist/host/platform.js +40 -0
  121. package/dist/host/plugin-source.d.ts +8 -6
  122. package/dist/host/plugin-source.js +43 -33
  123. package/dist/host/plugin.d.ts +4 -0
  124. package/dist/host/plugin.js +39 -0
  125. package/dist/host/port-types.d.ts +191 -0
  126. package/dist/host/port-types.js +1 -0
  127. package/dist/host/preflight.d.ts +28 -0
  128. package/dist/host/preflight.js +1 -0
  129. package/dist/host/profile-port.d.ts +4 -0
  130. package/dist/host/profile-port.js +4 -0
  131. package/dist/host/provision.d.ts +2 -2
  132. package/dist/host/provision.js +5 -3
  133. package/dist/host/recipe-rules.d.ts +5 -0
  134. package/dist/host/recipe-rules.js +382 -0
  135. package/dist/host/recipe.d.ts +14 -0
  136. package/dist/host/recipe.js +283 -0
  137. package/dist/host/shell-text.d.ts +9 -2
  138. package/dist/host/shell-text.js +15 -3
  139. package/dist/host/shell.d.ts +2 -0
  140. package/dist/host/shell.js +7 -0
  141. package/dist/host/spec.d.ts +8 -0
  142. package/dist/host/spec.js +24 -0
  143. package/dist/host/supply-index.d.ts +34 -0
  144. package/dist/host/supply-index.js +202 -0
  145. package/dist/host/supply-port.d.ts +5 -0
  146. package/dist/host/supply-port.js +39 -0
  147. package/dist/host/time.d.ts +12 -0
  148. package/dist/host/time.js +19 -0
  149. package/dist/host/tokens.d.ts +26 -0
  150. package/dist/host/tokens.js +154 -0
  151. package/dist/host/tool-approval.d.ts +12 -0
  152. package/dist/host/tool-approval.js +4 -0
  153. package/dist/host/tool-kit.js +1 -1
  154. package/dist/host/unit-face.d.ts +5 -4
  155. package/dist/host/version-range.d.ts +2 -0
  156. package/dist/host/version-range.js +73 -0
  157. package/dist/host/version.d.ts +3 -0
  158. package/dist/host/version.js +29 -0
  159. package/dist/host.d.ts +47 -16
  160. package/dist/host.js +47 -16
  161. package/dist/i18n/en.js +259 -86
  162. package/dist/i18n/index.d.ts +333 -88
  163. package/dist/i18n/merge.js +1 -1
  164. package/dist/i18n/need-text.d.ts +26 -0
  165. package/dist/i18n/need-text.js +26 -0
  166. package/dist/i18n/settings.d.ts +70 -0
  167. package/dist/i18n/settings.js +136 -0
  168. package/dist/i18n/zh.d.ts +332 -87
  169. package/dist/i18n/zh.js +260 -87
  170. package/dist/index.d.ts +24 -8
  171. package/dist/index.js +24 -8
  172. package/dist/lib/blocker-action.d.ts +0 -15
  173. package/dist/lib/blocker-action.js +1 -25
  174. package/dist/{api → lib}/dsh-client.d.ts +12 -1
  175. package/dist/lib/dsh-client.js +1 -0
  176. package/dist/lib/market-index.d.ts +7 -0
  177. package/dist/lib/market-index.js +25 -0
  178. package/dist/lib/react-types.d.ts +5 -0
  179. package/dist/lib/react-types.js +1 -0
  180. package/dist/lib/react.d.ts +1 -40
  181. package/dist/lib/react.js +0 -36
  182. package/dist/lib/ui.js +3 -9
  183. package/dist/testing/data.d.ts +13 -0
  184. package/dist/testing/data.js +46 -0
  185. package/dist/testing/declaration.d.ts +1 -1
  186. package/dist/testing/declaration.js +1 -1
  187. package/dist/testing/host-fakes.d.ts +0 -13
  188. package/dist/testing/host-fakes.js +0 -24
  189. package/dist/testing/needs.d.ts +16 -0
  190. package/dist/testing/needs.js +46 -0
  191. package/dist/testing.d.ts +2 -0
  192. package/dist/testing.js +2 -0
  193. package/package.json +18 -2
  194. package/src/api/__tests__/blocker-table.test.ts +135 -86
  195. package/src/api/blocker-table.ts +52 -26
  196. package/src/api/dsh.ts +17 -1
  197. package/src/api/host-write.ts +0 -43
  198. package/src/api/workbench-client.test.ts +2 -2
  199. package/src/api/workbench-client.ts +2 -1
  200. package/src/components/Activity.css +0 -1
  201. package/src/components/ApprovalDetail.css +1 -2
  202. package/src/components/ApprovalDetail.tsx +1 -1
  203. package/src/components/ApprovalPlan.css +0 -1
  204. package/src/components/Card.css +0 -1
  205. package/src/components/Card.tsx +1 -1
  206. package/src/components/CardAnchor.test.tsx +1 -1
  207. package/src/components/CardBoundary.tsx +1 -1
  208. package/src/components/CardHead.css +0 -1
  209. package/src/components/CardHead.tsx +1 -1
  210. package/src/components/ChoiceGroup.css +1 -2
  211. package/src/components/ConfirmBar.tsx +1 -1
  212. package/src/components/Form.css +1 -1
  213. package/src/components/Form.tsx +1 -1
  214. package/src/components/FormActions.tsx +1 -1
  215. package/src/components/LongTaskRow.css +1 -2
  216. package/src/components/LongTaskRow.tsx +1 -1
  217. package/src/components/Note.css +0 -1
  218. package/src/components/ResourceStates.css +0 -1
  219. package/src/components/SelectFieldNodes.tsx +0 -1
  220. package/src/components/SettingsSection.css +0 -1
  221. package/src/components/Spinner.css +0 -1
  222. package/src/components/Stack.css +0 -1
  223. package/src/components/StateBlock.css +0 -1
  224. package/src/components/__tests__/long-task-row.test.ts +1 -1
  225. package/src/components/board-module.ts +3 -3
  226. package/src/components/icons.tsx +16 -24
  227. package/src/config/constants.ts +2 -2
  228. package/src/config/storage.test.ts +1 -25
  229. package/src/config/storage.ts +0 -12
  230. package/src/{api → contract}/__tests__/facts.test.ts +73 -25
  231. package/src/{api → contract}/__tests__/long-task.test.ts +3 -3
  232. package/src/contract/__tests__/needs.test.ts +74 -0
  233. package/src/{host → contract}/__tests__/unit-declaration.test.ts +1 -1
  234. package/src/contract/__tests__/unit.test.ts +43 -0
  235. package/src/contract/adapters.ts +9 -0
  236. package/src/contract/cli.ts +3 -0
  237. package/src/contract/data.ts +145 -0
  238. package/src/{api → contract}/facts.ts +34 -4
  239. package/src/contract/needs.ts +331 -0
  240. package/src/contract/plugin-source.ts +1 -0
  241. package/src/contract/protocol/bundle-install.ts +198 -0
  242. package/src/contract/protocol/config-sync.ts +65 -0
  243. package/src/contract/protocol/diy.ts +4 -0
  244. package/src/contract/protocol/dsh-plugins.ts +13 -0
  245. package/src/contract/protocol/long-tasks.ts +16 -0
  246. package/src/contract/protocol/market-index.ts +246 -0
  247. package/src/contract/protocol/platform.ts +47 -0
  248. package/src/contract/protocol/preflight-wake.ts +17 -0
  249. package/src/contract/protocol/profile-create.ts +36 -0
  250. package/src/contract/protocol/sidebar-edition.ts +19 -0
  251. package/src/contract/protocol/unit-manifests.ts +8 -0
  252. package/src/contract/unit-board.ts +23 -0
  253. package/src/contract/unit-capability.ts +37 -0
  254. package/src/{host → contract}/unit-declaration.ts +22 -18
  255. package/src/contract/unit.ts +76 -0
  256. package/src/contract/workbench-contract.ts +30 -0
  257. package/src/host/__tests__/adapter-set.test.ts +228 -0
  258. package/src/host/__tests__/adapters.test.ts +27 -0
  259. package/src/host/__tests__/changelog.test.ts +102 -0
  260. package/src/host/__tests__/command-name.test.ts +16 -0
  261. package/src/host/__tests__/diy-record.test.ts +3 -3
  262. package/src/host/__tests__/facts.test.ts +5 -5
  263. package/src/host/__tests__/long-task.test.ts +1 -1
  264. package/src/host/__tests__/market-index.test.ts +179 -0
  265. package/src/host/__tests__/plugin-ledger.test.ts +10 -10
  266. package/src/host/__tests__/provision.test.ts +7 -6
  267. package/src/host/__tests__/shell-text.test.ts +16 -1
  268. package/src/host/__tests__/supply-index.test.ts +137 -0
  269. package/src/host/__tests__/tokens.test.ts +110 -0
  270. package/src/host/__tests__/version-range.test.ts +21 -0
  271. package/src/host/adapter-set.ts +298 -0
  272. package/src/host/adapter-types.ts +105 -0
  273. package/src/host/adapters.ts +44 -0
  274. package/src/host/browser.ts +3 -0
  275. package/src/host/changelog.ts +212 -0
  276. package/src/host/channel-plugin.ts +55 -0
  277. package/src/host/cli.ts +11 -0
  278. package/src/host/command-name.ts +15 -0
  279. package/src/host/data-error.ts +21 -0
  280. package/src/host/data-root.ts +2 -0
  281. package/src/host/diy-debug.ts +2 -1
  282. package/src/host/diy-record.ts +2 -1
  283. package/src/host/facts.ts +4 -3
  284. package/src/host/git.ts +2 -2
  285. package/src/host/http.ts +1 -1
  286. package/src/host/lib-capabilities.ts +52 -0
  287. package/src/host/lib-install.ts +18 -0
  288. package/src/host/long-task.ts +4 -3
  289. package/src/host/market-index.ts +413 -0
  290. package/src/host/needs.ts +6 -0
  291. package/src/host/patch.ts +93 -0
  292. package/src/host/paths.ts +37 -0
  293. package/src/host/platform.ts +48 -0
  294. package/src/host/plugin-source.ts +48 -56
  295. package/src/host/plugin.ts +39 -0
  296. package/src/host/port-types.ts +222 -0
  297. package/src/host/preflight.ts +31 -0
  298. package/src/host/profile-port.ts +9 -0
  299. package/src/host/provision.ts +7 -4
  300. package/src/host/recipe-rules.ts +330 -0
  301. package/src/host/recipe.test.ts +334 -0
  302. package/src/host/recipe.ts +323 -0
  303. package/src/host/shell-text.ts +15 -3
  304. package/src/host/shell.ts +9 -0
  305. package/src/host/spec.ts +32 -0
  306. package/src/host/supply-index.ts +256 -0
  307. package/src/host/supply-port.ts +45 -0
  308. package/src/host/time.ts +22 -0
  309. package/src/host/tokens.ts +186 -0
  310. package/src/host/tool-approval.ts +17 -0
  311. package/src/host/tool-kit.ts +1 -1
  312. package/src/host/unit-face.ts +5 -4
  313. package/src/host/version-range.ts +71 -0
  314. package/src/host/version.ts +30 -0
  315. package/src/host.ts +47 -16
  316. package/src/i18n/en.ts +261 -86
  317. package/src/i18n/merge.test.ts +6 -6
  318. package/src/i18n/merge.ts +1 -1
  319. package/src/i18n/need-text.ts +27 -0
  320. package/src/i18n/settings.ts +141 -0
  321. package/src/i18n/zh.ts +263 -87
  322. package/src/index.ts +24 -8
  323. package/src/lib/blocker-action.ts +0 -28
  324. package/src/{api → lib}/dsh-client.ts +16 -2
  325. package/src/lib/market-index.ts +36 -0
  326. package/src/lib/react-types.ts +5 -0
  327. package/src/lib/react.ts +1 -40
  328. package/src/lib/text.test.ts +2 -2
  329. package/src/lib/ui.test.ts +6 -5
  330. package/src/lib/ui.ts +3 -9
  331. package/src/testing/__tests__/declaration.test.ts +1 -1
  332. package/src/testing/data.ts +66 -0
  333. package/src/testing/declaration.ts +2 -2
  334. package/src/testing/host-fakes.ts +0 -38
  335. package/src/testing/needs.ts +80 -0
  336. package/src/testing.ts +2 -0
  337. package/dist/api/unit-board.d.ts +0 -39
  338. package/dist/api/unit-board.js +0 -45
  339. package/dist/api/unit.d.ts +0 -85
  340. package/dist/api/unit.js +0 -8
  341. package/dist/api/workbench-contract.d.ts +0 -44
  342. package/dist/components/MockStrip.css +0 -39
  343. package/dist/components/MockStrip.d.ts +0 -15
  344. package/dist/components/MockStrip.js +0 -8
  345. package/dist/components/SaveBar.css +0 -7
  346. package/dist/host/browser-find.d.ts +0 -38
  347. package/dist/host/browser-find.js +0 -242
  348. package/dist/host/browser-read.d.ts +0 -28
  349. package/dist/host/browser-read.js +0 -243
  350. package/dist/host/opencli-runtime.d.ts +0 -25
  351. package/dist/host/opencli-runtime.js +0 -56
  352. package/dist/host/opencli-window.d.ts +0 -2
  353. package/dist/host/opencli-window.js +0 -8
  354. package/dist/host/opencli.d.ts +0 -37
  355. package/dist/host/opencli.js +0 -155
  356. package/dist/host/unit-declaration.d.ts +0 -65
  357. package/dist/host/unit-declaration.js +0 -213
  358. package/dist/host/unit-libs.d.ts +0 -37
  359. package/dist/lib/diy-debug.d.ts +0 -80
  360. package/dist/lib/diy-debug.js +0 -88
  361. package/dist/lib/diy-record.d.ts +0 -135
  362. package/dist/lib/diy-record.js +0 -162
  363. package/dist/lib/lint-probe.d.ts +0 -1
  364. package/dist/lib/lint-probe.js +0 -6
  365. package/dist/lib/panel-state.d.ts +0 -120
  366. package/dist/lib/panel-state.js +0 -176
  367. package/src/api/__tests__/host-write.test.ts +0 -75
  368. package/src/api/__tests__/unit-board.test.ts +0 -76
  369. package/src/api/__tests__/unit.test.ts +0 -38
  370. package/src/api/unit-board.ts +0 -69
  371. package/src/api/unit.ts +0 -93
  372. package/src/api/workbench-contract.ts +0 -59
  373. package/src/host/__tests__/browser-find.test.ts +0 -330
  374. package/src/host/__tests__/browser-read.test.ts +0 -228
  375. package/src/host/__tests__/opencli-runtime.test.ts +0 -46
  376. package/src/host/browser-find.ts +0 -311
  377. package/src/host/browser-read.ts +0 -311
  378. package/src/host/opencli-runtime.ts +0 -79
  379. package/src/host/opencli-window.ts +0 -11
  380. package/src/host/opencli.ts +0 -213
  381. package/src/host/unit-libs.ts +0 -41
  382. package/src/lib/blocker-action.test.ts +0 -40
  383. /package/dist/{api/blocker.js → contract/adapters.js} +0 -0
  384. /package/dist/{api → contract}/blocker.d.ts +0 -0
  385. /package/dist/{api/dsh-client.js → contract/blocker.js} +0 -0
  386. /package/dist/{api/workbench-contract.js → contract/cli.js} +0 -0
  387. /package/dist/{host/unit-libs.js → contract/data.js} +0 -0
  388. /package/dist/{api → contract}/long-task.d.ts +0 -0
  389. /package/dist/{api → contract}/long-task.js +0 -0
  390. /package/src/{api → contract}/blocker.ts +0 -0
  391. /package/src/{api → contract}/long-task.ts +0 -0
@@ -1,11 +0,0 @@
1
- import { quoteShellArg } from './shell-text.js';
2
-
3
- const OPENCLI_WINDOW_ENV = 'OPENCLI_WINDOW=background';
4
-
5
- export function backgroundPrefix(): readonly string[] {
6
- return [quoteShellArg('env'), quoteShellArg(OPENCLI_WINDOW_ENV)];
7
- }
8
-
9
- export function backgroundLine(command: string, argv: readonly string[]): string {
10
- return [...backgroundPrefix(), quoteShellArg(command), ...argv.map(quoteShellArg)].join(' ');
11
- }
@@ -1,213 +0,0 @@
1
- import type { DshShell } from '../api/dsh.js';
2
- import { OPENCLI_MAX_CONCURRENT, OPENCLI_TIMEOUT_MS } from '../config/constants.js';
3
- import { parseJsonLoose } from '../lib/text.js';
4
- import { quoteShellArg, tailLines } from './shell-text.js';
5
- import { helpUrlOf, parseCliErrorEnvelope } from './cli-error.js';
6
- import { backgroundPrefix } from './opencli-window.js';
7
- import { runShell } from './shell.js';
8
-
9
- const FORBIDDEN_CODES = new Set(['FORBIDDEN', 'PERMISSION_DENIED']);
10
-
11
- const SITE_SESSION_ARGS = ['--site-session', 'persistent'] as const;
12
-
13
- export class WorkbenchDataError extends Error {
14
- readonly code: string;
15
- readonly detail?: string;
16
- readonly hint?: string;
17
- readonly project?: unknown;
18
- readonly helpUrl?: string;
19
-
20
- constructor(
21
- code: string,
22
- message: string,
23
- extra: { detail?: string; hint?: string; project?: unknown; helpUrl?: string } = {},
24
- ) {
25
- super(message);
26
- this.name = 'WorkbenchDataError';
27
- this.code = code;
28
- if (extra.detail !== undefined) this.detail = extra.detail;
29
- if (extra.hint !== undefined) this.hint = extra.hint;
30
- if (extra.project !== undefined) this.project = extra.project;
31
- if (extra.helpUrl !== undefined) this.helpUrl = extra.helpUrl;
32
- }
33
- }
34
-
35
- export interface OpencliResult {
36
- readonly value: unknown;
37
- readonly at: number;
38
- }
39
-
40
- export type OpencliSession = 'persistent' | 'ephemeral' | 'none';
41
-
42
- export function opencliCommandLine(
43
- command: string,
44
- argv: readonly string[],
45
- session: OpencliSession = 'persistent',
46
- ): string {
47
- return [
48
- ...backgroundPrefix(),
49
- quoteShellArg(command),
50
- ...argv.map(quoteShellArg),
51
- ...(session === 'persistent' ? SITE_SESSION_ARGS : []),
52
- '-f',
53
- 'json',
54
- ].join(' ');
55
- }
56
-
57
- export interface Opencli {
58
- json(
59
- args: readonly string[],
60
- options?: { key?: string; workdir?: string; session?: OpencliSession },
61
- ): Promise<OpencliResult>;
62
- }
63
-
64
- export function createOpencli(options: {
65
- shell: DshShell;
66
- plugin: string;
67
- logger?: { warn?(message: string): void } | undefined;
68
- command?: string;
69
- timeoutMs?: number;
70
- maxConcurrent?: number;
71
- }): Opencli {
72
- const {
73
- shell,
74
- plugin,
75
- logger,
76
- command = 'opencli',
77
- timeoutMs = OPENCLI_TIMEOUT_MS,
78
- maxConcurrent = OPENCLI_MAX_CONCURRENT,
79
- } = options;
80
-
81
- const inflight = new Map<string, Promise<OpencliResult>>();
82
-
83
- const MAX_CONCURRENT = maxConcurrent;
84
- let running = 0;
85
- const waiting: Array<() => void> = [];
86
-
87
- async function acquire(): Promise<void> {
88
- if (running < MAX_CONCURRENT) {
89
- running += 1;
90
- return;
91
- }
92
- await new Promise<void>((resolve) => waiting.push(resolve));
93
- }
94
-
95
- function release(): void {
96
- const next = waiting.shift();
97
- if (next === undefined) running -= 1;
98
- else next();
99
- }
100
-
101
- async function runLimited<T>(task: () => Promise<T>): Promise<T> {
102
- await acquire();
103
- try {
104
- return await task();
105
- } finally {
106
- release();
107
- }
108
- }
109
-
110
- async function call(commandLine: string, workdir: string | undefined): Promise<unknown> {
111
- let result;
112
- try {
113
- result = await runShell(shell, commandLine, {
114
- ...(workdir === undefined ? {} : { workdir }),
115
- timeoutMs,
116
- });
117
- } catch (error) {
118
- throw new WorkbenchDataError('cli-exec-failed', `执行 opencli 失败:${String(error)}`, {
119
- hint: '确认 opencli 已安装且在 PATH 里(which opencli)。',
120
- });
121
- }
122
-
123
- if (result.timedOut) {
124
- throw new WorkbenchDataError(
125
- 'cli-timeout',
126
- `opencli 超过 ${Math.round(timeoutMs / 1000)} 秒没有返回`,
127
- { hint: '无头浏览器可能没起来,重试一次通常就好。' },
128
- );
129
- }
130
-
131
- if (result.exitCode !== 0) {
132
- const detail = tailLines(result.stderr || result.stdout, 6);
133
- const envelope = parseCliErrorEnvelope(result.stderr) ?? parseCliErrorEnvelope(result.stdout);
134
-
135
- const url = envelope === undefined ? undefined : helpUrlOf(envelope);
136
- if (envelope?.code === 'AUTH_REQUIRED') {
137
- throw new WorkbenchDataError('auth-required', envelope.message, {
138
- detail,
139
- ...(url === undefined ? {} : { helpUrl: url }),
140
- });
141
- }
142
- if (envelope !== undefined && FORBIDDEN_CODES.has(envelope.code)) {
143
- throw new WorkbenchDataError('permission-denied', envelope.message, {
144
- detail,
145
- ...(url === undefined ? {} : { helpUrl: url }),
146
- });
147
- }
148
- if (envelope !== undefined) {
149
- throw new WorkbenchDataError('cli-command-failed', `${envelope.code}:${envelope.message}`, {
150
- detail,
151
- ...(envelope.help === undefined ? {} : { hint: envelope.help }),
152
- });
153
- }
154
- throw new WorkbenchDataError(
155
- 'cli-unclassified',
156
- `opencli 这条命令没跑通(退出码 ${result.exitCode}),而且没有结构化错误码`,
157
- {
158
- detail,
159
- hint: '多半是插件里没有这条命令(版本旧就会缺),也可能是命令自己失败了:先确认命令存在,再更新插件重试。',
160
- },
161
- );
162
- }
163
-
164
- const parsed = parseJsonLoose(result.stdout);
165
- if (parsed === undefined) {
166
- throw new WorkbenchDataError('cli-bad-output', 'opencli 输出不是 JSON', {
167
- detail: tailLines(result.stdout, 4),
168
- });
169
- }
170
- return parsed;
171
- }
172
-
173
- async function json(
174
- args: readonly string[],
175
- callOptions: { key?: string; workdir?: string; session?: OpencliSession } = {},
176
- ): Promise<OpencliResult> {
177
- const { key, workdir } = callOptions;
178
- const session = callOptions.session ?? 'persistent';
179
- const callKey = key ?? args.map((arg) => String(arg)).join(' ');
180
-
181
- const pending = inflight.get(callKey);
182
- if (pending !== undefined) return pending;
183
-
184
- const commandLine = opencliCommandLine(command, [plugin, ...args], session);
185
-
186
- const once = async (): Promise<OpencliResult> => {
187
- const value = await call(commandLine, workdir);
188
- return { value, at: Date.now() };
189
- };
190
-
191
- const task = runLimited(async (): Promise<OpencliResult> => {
192
- try {
193
- return await once();
194
- } catch (error) {
195
- if (!(error instanceof WorkbenchDataError) || error.code !== 'auth-required') throw error;
196
- return await once();
197
- }
198
- });
199
-
200
- inflight.set(callKey, task);
201
- try {
202
- return await task;
203
- } catch (error) {
204
- const message = error instanceof Error ? error.message : String(error);
205
- logger?.warn?.(`[dsh-workbench] opencli 调用失败:${message}`);
206
- throw error;
207
- } finally {
208
- inflight.delete(callKey);
209
- }
210
- }
211
-
212
- return { json };
213
- }
@@ -1,41 +0,0 @@
1
- import type { PluginSourceProblem } from './plugin-source.js';
2
- import type { PluginRelease, UnitLibNeed, UnitPluginNeed } from '../api/unit.js';
3
-
4
- export interface UnitLibState {
5
- readonly name: string;
6
- readonly purpose: string;
7
- readonly status: 'ok' | 'outdated' | 'missing' | 'unsatisfied';
8
- readonly installed?: string;
9
- readonly latest?: string;
10
- readonly command?: string;
11
- }
12
-
13
- export interface UnitCommands {
14
- readonly unit: string;
15
- readonly plugins?: readonly UnitPluginNeed[];
16
- readonly libs?: readonly UnitLibNeed[];
17
- }
18
-
19
- export interface UnitPluginState {
20
- readonly name: string;
21
- readonly status: "ok" | "outdated" | "missing";
22
- readonly missing: readonly string[];
23
- readonly install?: "ready" | PluginSourceProblem;
24
- readonly command?: string;
25
- readonly release?: PluginRelease;
26
- }
27
-
28
- export interface UnitCapability {
29
- readonly unit: string;
30
- readonly status: "ok" | "failed" | "missing-commands" | "missing-plugin" | "unchecked";
31
- readonly plugin?: string;
32
- readonly required: readonly string[];
33
- readonly missing: readonly string[];
34
- readonly detail: string;
35
- readonly command?: string;
36
- readonly fix?: "install" | "update";
37
- readonly install?: "ready" | PluginSourceProblem;
38
- readonly plugins?: readonly UnitPluginState[];
39
- readonly libs?: readonly UnitLibState[];
40
- readonly released?: boolean;
41
- }
@@ -1,40 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { blockerActionLabel, blockerPending } from './blocker-action.js';
3
-
4
- const t = (key: string): string => `«${key}»`;
5
-
6
- const RETRY = { kind: 'retry', label: '重试' } as const;
7
- const LOGIN = { kind: 'open-url', label: '去登录', url: 'https://cmdb.example/login', inline: true } as const;
8
- const COPY = { kind: 'copy', label: '复制命令', text: 'opencli cmdb envs' } as const;
9
- const FIX = { kind: 'run-fix', label: '帮我安装', unit: 'cmdb', fix: 'install' } as const;
10
-
11
- const idle = { retrying: false, running: null, copied: null } as const;
12
-
13
- describe('阻断态那颗按钮说什么', () => {
14
- it('★ 忙的时候「重试」自己说「重试中…」(用户点的就是它)', () => {
15
- expect(blockerActionLabel(RETRY, { ...idle, retrying: true }, t)).toBe('«blocker.retry.running»');
16
- });
17
-
18
- it('不忙就是原文(不假装忙)', () => {
19
- expect(blockerActionLabel(RETRY, idle, t)).toBe('重试');
20
- });
21
-
22
- it('★ 忙的不是重试本身(安装在路上)→ 「重试」不许跟着说「重试中…」', () => {
23
- expect(blockerActionLabel(RETRY, { ...idle, running: '帮我安装' }, t)).toBe('重试');
24
- expect(blockerActionLabel(LOGIN, { ...idle, retrying: true }, t)).toBe('去登录');
25
- });
26
-
27
- it('安装在路上 → 那颗说「正在执行…」', () => {
28
- expect(blockerActionLabel(FIX, { ...idle, running: '帮我安装' }, t)).toBe('«blocker.fix.running»');
29
- });
30
-
31
- it('复制成功那一下说「已复制」', () => {
32
- expect(blockerActionLabel(COPY, { ...idle, copied: 'opencli cmdb envs' }, t)).toBe('«env.copied»');
33
- });
34
-
35
- it('★ 忙 = 卡片在刷 || 本地动作在跑(少算一半,按钮就又哑了)', () => {
36
- expect(blockerPending(true, null)).toBe(true);
37
- expect(blockerPending(false, '帮我安装')).toBe(true);
38
- expect(blockerPending(false, null)).toBe(false);
39
- });
40
- });
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes