@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.
- package/LICENSE +21 -0
- package/README.md +97 -0
- package/dist/api/blocker-table.d.ts +3 -3
- package/dist/api/blocker-table.js +47 -23
- package/dist/api/dsh.d.ts +19 -1
- package/dist/api/host-write.d.ts +0 -15
- package/dist/api/host-write.js +1 -35
- package/dist/api/workbench-client.js +2 -1
- package/dist/components/Activity.css +0 -1
- package/dist/components/ApprovalDetail.css +1 -2
- package/dist/components/ApprovalDetail.d.ts +1 -1
- package/dist/components/ApprovalPlan.css +0 -1
- package/dist/components/Card.css +0 -1
- package/dist/components/Card.d.ts +1 -1
- package/dist/components/CardBoundary.d.ts +1 -1
- package/dist/components/CardHead.css +0 -1
- package/dist/components/CardHead.d.ts +1 -1
- package/dist/components/ChoiceGroup.css +1 -2
- package/dist/components/ConfirmBar.d.ts +1 -1
- package/dist/components/ConfirmBar.js +1 -1
- package/dist/components/Form.css +1 -1
- package/dist/components/FormActions.js +1 -1
- package/dist/components/LongTaskRow.css +1 -2
- package/dist/components/LongTaskRow.d.ts +1 -1
- package/dist/components/LongTaskRow.js +1 -1
- package/dist/components/Note.css +0 -1
- package/dist/components/ResourceStates.css +0 -1
- package/dist/components/SettingsSection.css +0 -1
- package/dist/components/Spinner.css +0 -1
- package/dist/components/Stack.css +0 -1
- package/dist/components/StateBlock.css +0 -1
- package/dist/components/board-module.d.ts +3 -3
- package/dist/components/icons.d.ts +1 -7
- package/dist/components/icons.js +11 -16
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.js +2 -2
- package/dist/config/storage.d.ts +0 -4
- package/dist/config/storage.js +0 -11
- package/dist/contract/adapters.d.ts +10 -0
- package/dist/contract/cli.d.ts +3 -0
- package/dist/contract/data.d.ts +126 -0
- package/dist/{api → contract}/facts.d.ts +12 -3
- package/dist/{api → contract}/facts.js +19 -1
- package/dist/contract/needs.d.ts +132 -0
- package/dist/contract/needs.js +232 -0
- package/dist/contract/plugin-source.d.ts +1 -0
- package/dist/contract/plugin-source.js +1 -0
- package/dist/contract/protocol/bundle-install.d.ts +136 -0
- package/dist/contract/protocol/bundle-install.js +12 -0
- package/dist/contract/protocol/config-sync.d.ts +55 -0
- package/dist/contract/protocol/config-sync.js +2 -0
- package/dist/contract/protocol/diy.d.ts +4 -0
- package/dist/contract/protocol/diy.js +4 -0
- package/dist/contract/protocol/dsh-plugins.d.ts +11 -0
- package/dist/contract/protocol/dsh-plugins.js +1 -0
- package/dist/contract/protocol/long-tasks.d.ts +13 -0
- package/dist/contract/protocol/long-tasks.js +1 -0
- package/dist/contract/protocol/market-index.d.ts +195 -0
- package/dist/contract/protocol/market-index.js +7 -0
- package/dist/contract/protocol/platform.d.ts +44 -0
- package/dist/contract/protocol/platform.js +1 -0
- package/dist/contract/protocol/preflight-wake.d.ts +7 -0
- package/dist/contract/protocol/preflight-wake.js +1 -0
- package/dist/contract/protocol/profile-create.d.ts +30 -0
- package/dist/contract/protocol/profile-create.js +2 -0
- package/dist/contract/protocol/sidebar-edition.d.ts +14 -0
- package/dist/contract/protocol/sidebar-edition.js +2 -0
- package/dist/contract/protocol/unit-manifests.d.ts +6 -0
- package/dist/contract/protocol/unit-manifests.js +1 -0
- package/dist/contract/unit-board.d.ts +18 -0
- package/dist/contract/unit-board.js +1 -0
- package/dist/contract/unit-capability.d.ts +34 -0
- package/dist/contract/unit-capability.js +1 -0
- package/dist/{api → contract}/unit-declaration.d.ts +7 -5
- package/dist/{api → contract}/unit-declaration.js +19 -13
- package/dist/contract/unit.d.ts +57 -0
- package/dist/contract/unit.js +24 -0
- package/dist/contract/workbench-contract.d.ts +15 -0
- package/dist/contract/workbench-contract.js +1 -0
- package/dist/host/adapter-set.d.ts +26 -0
- package/dist/host/adapter-set.js +243 -0
- package/dist/host/adapter-types.d.ts +79 -0
- package/dist/host/adapter-types.js +23 -0
- package/dist/host/adapters.d.ts +22 -0
- package/dist/host/adapters.js +9 -0
- package/dist/host/browser.d.ts +3 -0
- package/dist/host/browser.js +3 -0
- package/dist/host/changelog.d.ts +21 -0
- package/dist/host/changelog.js +188 -0
- package/dist/host/channel-plugin.d.ts +15 -0
- package/dist/host/channel-plugin.js +42 -0
- package/dist/host/cli.d.ts +4 -0
- package/dist/host/cli.js +7 -0
- package/dist/host/command-name.d.ts +1 -0
- package/dist/host/command-name.js +14 -0
- package/dist/host/data-error.d.ts +13 -0
- package/dist/host/data-error.js +20 -0
- package/dist/host/data-root.js +3 -0
- package/dist/host/diy-debug.js +2 -1
- package/dist/host/diy-record.js +2 -1
- package/dist/host/facts.d.ts +1 -1
- package/dist/host/facts.js +3 -2
- package/dist/host/git.js +2 -2
- package/dist/host/http.js +1 -1
- package/dist/host/lib-capabilities.d.ts +22 -0
- package/dist/host/lib-capabilities.js +37 -0
- package/dist/host/lib-install.d.ts +9 -0
- package/dist/host/lib-install.js +10 -0
- package/dist/host/long-task.d.ts +1 -1
- package/dist/host/long-task.js +4 -3
- package/dist/host/market-index.d.ts +22 -0
- package/dist/host/market-index.js +420 -0
- package/dist/host/needs.d.ts +4 -0
- package/dist/host/needs.js +2 -0
- package/dist/host/patch.d.ts +9 -0
- package/dist/host/patch.js +78 -0
- package/dist/host/paths.d.ts +12 -0
- package/dist/host/paths.js +28 -0
- package/dist/host/platform.d.ts +14 -0
- package/dist/host/platform.js +40 -0
- package/dist/host/plugin-source.d.ts +8 -6
- package/dist/host/plugin-source.js +43 -33
- package/dist/host/plugin.d.ts +4 -0
- package/dist/host/plugin.js +39 -0
- package/dist/host/port-types.d.ts +191 -0
- package/dist/host/port-types.js +1 -0
- package/dist/host/preflight.d.ts +28 -0
- package/dist/host/preflight.js +1 -0
- package/dist/host/profile-port.d.ts +4 -0
- package/dist/host/profile-port.js +4 -0
- package/dist/host/provision.d.ts +2 -2
- package/dist/host/provision.js +5 -3
- package/dist/host/recipe-rules.d.ts +5 -0
- package/dist/host/recipe-rules.js +382 -0
- package/dist/host/recipe.d.ts +14 -0
- package/dist/host/recipe.js +283 -0
- package/dist/host/shell-text.d.ts +9 -2
- package/dist/host/shell-text.js +15 -3
- package/dist/host/shell.d.ts +2 -0
- package/dist/host/shell.js +7 -0
- package/dist/host/spec.d.ts +8 -0
- package/dist/host/spec.js +24 -0
- package/dist/host/supply-index.d.ts +34 -0
- package/dist/host/supply-index.js +202 -0
- package/dist/host/supply-port.d.ts +5 -0
- package/dist/host/supply-port.js +39 -0
- package/dist/host/time.d.ts +12 -0
- package/dist/host/time.js +19 -0
- package/dist/host/tokens.d.ts +26 -0
- package/dist/host/tokens.js +154 -0
- package/dist/host/tool-approval.d.ts +12 -0
- package/dist/host/tool-approval.js +4 -0
- package/dist/host/tool-kit.js +1 -1
- package/dist/host/unit-face.d.ts +5 -4
- package/dist/host/version-range.d.ts +2 -0
- package/dist/host/version-range.js +73 -0
- package/dist/host/version.d.ts +3 -0
- package/dist/host/version.js +29 -0
- package/dist/host.d.ts +47 -16
- package/dist/host.js +47 -16
- package/dist/i18n/en.js +259 -86
- package/dist/i18n/index.d.ts +333 -88
- package/dist/i18n/merge.js +1 -1
- package/dist/i18n/need-text.d.ts +26 -0
- package/dist/i18n/need-text.js +26 -0
- package/dist/i18n/settings.d.ts +70 -0
- package/dist/i18n/settings.js +136 -0
- package/dist/i18n/zh.d.ts +332 -87
- package/dist/i18n/zh.js +260 -87
- package/dist/index.d.ts +24 -8
- package/dist/index.js +24 -8
- package/dist/lib/blocker-action.d.ts +0 -15
- package/dist/lib/blocker-action.js +1 -25
- package/dist/{api → lib}/dsh-client.d.ts +12 -1
- package/dist/lib/dsh-client.js +1 -0
- package/dist/lib/market-index.d.ts +7 -0
- package/dist/lib/market-index.js +25 -0
- package/dist/lib/react-types.d.ts +5 -0
- package/dist/lib/react-types.js +1 -0
- package/dist/lib/react.d.ts +1 -40
- package/dist/lib/react.js +0 -36
- package/dist/lib/ui.js +3 -9
- package/dist/testing/data.d.ts +13 -0
- package/dist/testing/data.js +46 -0
- package/dist/testing/declaration.d.ts +1 -1
- package/dist/testing/declaration.js +1 -1
- package/dist/testing/host-fakes.d.ts +0 -13
- package/dist/testing/host-fakes.js +0 -24
- package/dist/testing/needs.d.ts +16 -0
- package/dist/testing/needs.js +46 -0
- package/dist/testing.d.ts +2 -0
- package/dist/testing.js +2 -0
- package/package.json +18 -2
- package/src/api/__tests__/blocker-table.test.ts +135 -86
- package/src/api/blocker-table.ts +52 -26
- package/src/api/dsh.ts +17 -1
- package/src/api/host-write.ts +0 -43
- package/src/api/workbench-client.test.ts +2 -2
- package/src/api/workbench-client.ts +2 -1
- package/src/components/Activity.css +0 -1
- package/src/components/ApprovalDetail.css +1 -2
- package/src/components/ApprovalDetail.tsx +1 -1
- package/src/components/ApprovalPlan.css +0 -1
- package/src/components/Card.css +0 -1
- package/src/components/Card.tsx +1 -1
- package/src/components/CardAnchor.test.tsx +1 -1
- package/src/components/CardBoundary.tsx +1 -1
- package/src/components/CardHead.css +0 -1
- package/src/components/CardHead.tsx +1 -1
- package/src/components/ChoiceGroup.css +1 -2
- package/src/components/ConfirmBar.tsx +1 -1
- package/src/components/Form.css +1 -1
- package/src/components/Form.tsx +1 -1
- package/src/components/FormActions.tsx +1 -1
- package/src/components/LongTaskRow.css +1 -2
- package/src/components/LongTaskRow.tsx +1 -1
- package/src/components/Note.css +0 -1
- package/src/components/ResourceStates.css +0 -1
- package/src/components/SelectFieldNodes.tsx +0 -1
- package/src/components/SettingsSection.css +0 -1
- package/src/components/Spinner.css +0 -1
- package/src/components/Stack.css +0 -1
- package/src/components/StateBlock.css +0 -1
- package/src/components/__tests__/long-task-row.test.ts +1 -1
- package/src/components/board-module.ts +3 -3
- package/src/components/icons.tsx +16 -24
- package/src/config/constants.ts +2 -2
- package/src/config/storage.test.ts +1 -25
- package/src/config/storage.ts +0 -12
- package/src/{api → contract}/__tests__/facts.test.ts +73 -25
- package/src/{api → contract}/__tests__/long-task.test.ts +3 -3
- package/src/contract/__tests__/needs.test.ts +74 -0
- package/src/{host → contract}/__tests__/unit-declaration.test.ts +1 -1
- package/src/contract/__tests__/unit.test.ts +43 -0
- package/src/contract/adapters.ts +9 -0
- package/src/contract/cli.ts +3 -0
- package/src/contract/data.ts +145 -0
- package/src/{api → contract}/facts.ts +34 -4
- package/src/contract/needs.ts +331 -0
- package/src/contract/plugin-source.ts +1 -0
- package/src/contract/protocol/bundle-install.ts +198 -0
- package/src/contract/protocol/config-sync.ts +65 -0
- package/src/contract/protocol/diy.ts +4 -0
- package/src/contract/protocol/dsh-plugins.ts +13 -0
- package/src/contract/protocol/long-tasks.ts +16 -0
- package/src/contract/protocol/market-index.ts +246 -0
- package/src/contract/protocol/platform.ts +47 -0
- package/src/contract/protocol/preflight-wake.ts +17 -0
- package/src/contract/protocol/profile-create.ts +36 -0
- package/src/contract/protocol/sidebar-edition.ts +19 -0
- package/src/contract/protocol/unit-manifests.ts +8 -0
- package/src/contract/unit-board.ts +23 -0
- package/src/contract/unit-capability.ts +37 -0
- package/src/{host → contract}/unit-declaration.ts +22 -18
- package/src/contract/unit.ts +76 -0
- package/src/contract/workbench-contract.ts +30 -0
- package/src/host/__tests__/adapter-set.test.ts +228 -0
- package/src/host/__tests__/adapters.test.ts +27 -0
- package/src/host/__tests__/changelog.test.ts +102 -0
- package/src/host/__tests__/command-name.test.ts +16 -0
- package/src/host/__tests__/diy-record.test.ts +3 -3
- package/src/host/__tests__/facts.test.ts +5 -5
- package/src/host/__tests__/long-task.test.ts +1 -1
- package/src/host/__tests__/market-index.test.ts +179 -0
- package/src/host/__tests__/plugin-ledger.test.ts +10 -10
- package/src/host/__tests__/provision.test.ts +7 -6
- package/src/host/__tests__/shell-text.test.ts +16 -1
- package/src/host/__tests__/supply-index.test.ts +137 -0
- package/src/host/__tests__/tokens.test.ts +110 -0
- package/src/host/__tests__/version-range.test.ts +21 -0
- package/src/host/adapter-set.ts +298 -0
- package/src/host/adapter-types.ts +105 -0
- package/src/host/adapters.ts +44 -0
- package/src/host/browser.ts +3 -0
- package/src/host/changelog.ts +212 -0
- package/src/host/channel-plugin.ts +55 -0
- package/src/host/cli.ts +11 -0
- package/src/host/command-name.ts +15 -0
- package/src/host/data-error.ts +21 -0
- package/src/host/data-root.ts +2 -0
- package/src/host/diy-debug.ts +2 -1
- package/src/host/diy-record.ts +2 -1
- package/src/host/facts.ts +4 -3
- package/src/host/git.ts +2 -2
- package/src/host/http.ts +1 -1
- package/src/host/lib-capabilities.ts +52 -0
- package/src/host/lib-install.ts +18 -0
- package/src/host/long-task.ts +4 -3
- package/src/host/market-index.ts +413 -0
- package/src/host/needs.ts +6 -0
- package/src/host/patch.ts +93 -0
- package/src/host/paths.ts +37 -0
- package/src/host/platform.ts +48 -0
- package/src/host/plugin-source.ts +48 -56
- package/src/host/plugin.ts +39 -0
- package/src/host/port-types.ts +222 -0
- package/src/host/preflight.ts +31 -0
- package/src/host/profile-port.ts +9 -0
- package/src/host/provision.ts +7 -4
- package/src/host/recipe-rules.ts +330 -0
- package/src/host/recipe.test.ts +334 -0
- package/src/host/recipe.ts +323 -0
- package/src/host/shell-text.ts +15 -3
- package/src/host/shell.ts +9 -0
- package/src/host/spec.ts +32 -0
- package/src/host/supply-index.ts +256 -0
- package/src/host/supply-port.ts +45 -0
- package/src/host/time.ts +22 -0
- package/src/host/tokens.ts +186 -0
- package/src/host/tool-approval.ts +17 -0
- package/src/host/tool-kit.ts +1 -1
- package/src/host/unit-face.ts +5 -4
- package/src/host/version-range.ts +71 -0
- package/src/host/version.ts +30 -0
- package/src/host.ts +47 -16
- package/src/i18n/en.ts +261 -86
- package/src/i18n/merge.test.ts +6 -6
- package/src/i18n/merge.ts +1 -1
- package/src/i18n/need-text.ts +27 -0
- package/src/i18n/settings.ts +141 -0
- package/src/i18n/zh.ts +263 -87
- package/src/index.ts +24 -8
- package/src/lib/blocker-action.ts +0 -28
- package/src/{api → lib}/dsh-client.ts +16 -2
- package/src/lib/market-index.ts +36 -0
- package/src/lib/react-types.ts +5 -0
- package/src/lib/react.ts +1 -40
- package/src/lib/text.test.ts +2 -2
- package/src/lib/ui.test.ts +6 -5
- package/src/lib/ui.ts +3 -9
- package/src/testing/__tests__/declaration.test.ts +1 -1
- package/src/testing/data.ts +66 -0
- package/src/testing/declaration.ts +2 -2
- package/src/testing/host-fakes.ts +0 -38
- package/src/testing/needs.ts +80 -0
- package/src/testing.ts +2 -0
- package/dist/api/unit-board.d.ts +0 -39
- package/dist/api/unit-board.js +0 -45
- package/dist/api/unit.d.ts +0 -85
- package/dist/api/unit.js +0 -8
- package/dist/api/workbench-contract.d.ts +0 -44
- package/dist/components/MockStrip.css +0 -39
- package/dist/components/MockStrip.d.ts +0 -15
- package/dist/components/MockStrip.js +0 -8
- package/dist/components/SaveBar.css +0 -7
- package/dist/host/browser-find.d.ts +0 -38
- package/dist/host/browser-find.js +0 -242
- package/dist/host/browser-read.d.ts +0 -28
- package/dist/host/browser-read.js +0 -243
- package/dist/host/opencli-runtime.d.ts +0 -25
- package/dist/host/opencli-runtime.js +0 -56
- package/dist/host/opencli-window.d.ts +0 -2
- package/dist/host/opencli-window.js +0 -8
- package/dist/host/opencli.d.ts +0 -37
- package/dist/host/opencli.js +0 -155
- package/dist/host/unit-declaration.d.ts +0 -65
- package/dist/host/unit-declaration.js +0 -213
- package/dist/host/unit-libs.d.ts +0 -37
- package/dist/lib/diy-debug.d.ts +0 -80
- package/dist/lib/diy-debug.js +0 -88
- package/dist/lib/diy-record.d.ts +0 -135
- package/dist/lib/diy-record.js +0 -162
- package/dist/lib/lint-probe.d.ts +0 -1
- package/dist/lib/lint-probe.js +0 -6
- package/dist/lib/panel-state.d.ts +0 -120
- package/dist/lib/panel-state.js +0 -176
- package/src/api/__tests__/host-write.test.ts +0 -75
- package/src/api/__tests__/unit-board.test.ts +0 -76
- package/src/api/__tests__/unit.test.ts +0 -38
- package/src/api/unit-board.ts +0 -69
- package/src/api/unit.ts +0 -93
- package/src/api/workbench-contract.ts +0 -59
- package/src/host/__tests__/browser-find.test.ts +0 -330
- package/src/host/__tests__/browser-read.test.ts +0 -228
- package/src/host/__tests__/opencli-runtime.test.ts +0 -46
- package/src/host/browser-find.ts +0 -311
- package/src/host/browser-read.ts +0 -311
- package/src/host/opencli-runtime.ts +0 -79
- package/src/host/opencli-window.ts +0 -11
- package/src/host/opencli.ts +0 -213
- package/src/host/unit-libs.ts +0 -41
- package/src/lib/blocker-action.test.ts +0 -40
- /package/dist/{api/blocker.js → contract/adapters.js} +0 -0
- /package/dist/{api → contract}/blocker.d.ts +0 -0
- /package/dist/{api/dsh-client.js → contract/blocker.js} +0 -0
- /package/dist/{api/workbench-contract.js → contract/cli.js} +0 -0
- /package/dist/{host/unit-libs.js → contract/data.js} +0 -0
- /package/dist/{api → contract}/long-task.d.ts +0 -0
- /package/dist/{api → contract}/long-task.js +0 -0
- /package/src/{api → contract}/blocker.ts +0 -0
- /package/src/{api → contract}/long-task.ts +0 -0
package/dist/lib/panel-state.js
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 留存的工作区上限(LRU,满 64 个丢最旧的)。
|
|
3
|
-
*/
|
|
4
|
-
export const PANEL_STATE_MAX_UNITS = 64;
|
|
5
|
-
/**
|
|
6
|
-
* 每个单元留存的卡片上限(按路由 LRU,满 12 张丢最旧的)。
|
|
7
|
-
*/
|
|
8
|
-
export const PANEL_STATE_MAX_CARDS = 12;
|
|
9
|
-
/**
|
|
10
|
-
* 一次上报最多读入的卡片条数(32 条之后的丢掉)。
|
|
11
|
-
*/
|
|
12
|
-
export const PANEL_STATE_MAX_REPORTS = 32;
|
|
13
|
-
/**
|
|
14
|
-
* 同一原因的连续崩溃算进同一次计数的窗口(10 分钟,毫秒)。
|
|
15
|
-
*/
|
|
16
|
-
export const PANEL_STATE_CRASH_WINDOW_MS = 600000;
|
|
17
|
-
/**
|
|
18
|
-
* 上报文本字段的截断长度(2000 字符;workspace / reason / message 共用)。
|
|
19
|
-
*/
|
|
20
|
-
export const PANEL_STATE_MAX_TEXT = 2000;
|
|
21
|
-
const PHASES = ['idle', 'loading', 'ready', 'error'];
|
|
22
|
-
function asRecord(value) {
|
|
23
|
-
return typeof value === 'object' && value !== null ? value : undefined;
|
|
24
|
-
}
|
|
25
|
-
function textOf(value, max) {
|
|
26
|
-
if (typeof value !== 'string')
|
|
27
|
-
return '';
|
|
28
|
-
const trimmed = value.trim();
|
|
29
|
-
return trimmed.length > max ? trimmed.slice(0, max) : trimmed;
|
|
30
|
-
}
|
|
31
|
-
function atOf(value) {
|
|
32
|
-
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
33
|
-
return null;
|
|
34
|
-
if (value < 0)
|
|
35
|
-
return null;
|
|
36
|
-
return Math.trunc(value);
|
|
37
|
-
}
|
|
38
|
-
function errorOf(raw) {
|
|
39
|
-
const record = asRecord(raw);
|
|
40
|
-
if (record === undefined)
|
|
41
|
-
return undefined;
|
|
42
|
-
const code = textOf(record['code'], 120);
|
|
43
|
-
const message = textOf(record['message'], PANEL_STATE_MAX_TEXT);
|
|
44
|
-
if (code === '' && message === '')
|
|
45
|
-
return undefined;
|
|
46
|
-
return { code: code === '' ? 'unknown' : code, message };
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* 收一批卡片读数上报。
|
|
50
|
-
* @param payload - `POST` 的请求体。
|
|
51
|
-
* @returns 至少收到一条能认的卡片才 `ok: true`;请求体不是对象、`workspace` 为空、`cards` 不是数组,
|
|
52
|
-
* 或一条都认不出(`unit` / `route` / `phase` / `at` 缺一)时 `ok: false` + 中文原因;认不出的单条静默跳过。
|
|
53
|
-
*/
|
|
54
|
-
export function parseCardsReport(payload) {
|
|
55
|
-
const record = asRecord(payload);
|
|
56
|
-
if (record === undefined)
|
|
57
|
-
return { ok: false, message: '请求体要是一个对象' };
|
|
58
|
-
const workspace = textOf(record['workspace'], PANEL_STATE_MAX_TEXT);
|
|
59
|
-
if (workspace === '')
|
|
60
|
-
return { ok: false, message: 'workspace 不能是空的 —— 面板按工作区存' };
|
|
61
|
-
const raw = record['cards'];
|
|
62
|
-
if (!Array.isArray(raw))
|
|
63
|
-
return { ok: false, message: 'cards 要是一个数组' };
|
|
64
|
-
const cards = [];
|
|
65
|
-
for (const item of raw.slice(0, PANEL_STATE_MAX_REPORTS)) {
|
|
66
|
-
const card = asRecord(item);
|
|
67
|
-
if (card === undefined)
|
|
68
|
-
continue;
|
|
69
|
-
const unit = textOf(card['unit'], 200);
|
|
70
|
-
const route = textOf(card['route'], 400);
|
|
71
|
-
const phase = textOf(card['phase'], 20);
|
|
72
|
-
const at = atOf(card['at']);
|
|
73
|
-
if (unit === '' || route === '' || at === null || !PHASES.includes(phase))
|
|
74
|
-
continue;
|
|
75
|
-
const error = errorOf(card['error']);
|
|
76
|
-
cards.push({ unit, route, phase, at, ...(error === undefined ? {} : { error }) });
|
|
77
|
-
}
|
|
78
|
-
if (cards.length === 0)
|
|
79
|
-
return { ok: false, message: 'cards 里没有一条能认的(unit / route / phase / at 都要有)' };
|
|
80
|
-
return { ok: true, value: { workspace, cards } };
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* 收一次卡片崩溃上报。
|
|
84
|
-
* @param payload - `POST` 的请求体。
|
|
85
|
-
* @returns `workspace` / `unit` / `reason` 都不能空,缺一给 `ok: false` + 中文原因;`at` 缺省或不合法时取当前时间。
|
|
86
|
-
*/
|
|
87
|
-
export function parseCrashReport(payload) {
|
|
88
|
-
const record = asRecord(payload);
|
|
89
|
-
if (record === undefined)
|
|
90
|
-
return { ok: false, message: '请求体要是一个对象' };
|
|
91
|
-
const workspace = textOf(record['workspace'], PANEL_STATE_MAX_TEXT);
|
|
92
|
-
const unit = textOf(record['unit'], 200);
|
|
93
|
-
const reason = textOf(record['reason'], PANEL_STATE_MAX_TEXT);
|
|
94
|
-
if (workspace === '')
|
|
95
|
-
return { ok: false, message: 'workspace 不能是空的' };
|
|
96
|
-
if (unit === '')
|
|
97
|
-
return { ok: false, message: 'unit 不能是空的' };
|
|
98
|
-
if (reason === '')
|
|
99
|
-
return { ok: false, message: 'reason 不能是空的(没有原因的崩溃没法查)' };
|
|
100
|
-
return { ok: true, value: { workspace, unit, reason, at: atOf(record['at']) ?? Date.now() } };
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* 造一份面板运行态的留存(进程内存、按工作区分桶,带上面那几条上限的 LRU)。
|
|
104
|
-
* @returns 留存口:`cards` / `crash` 收上报,`snapshot(workspace)` 取全量;没存过的工作区(含 `null`)给一份空的。
|
|
105
|
-
*/
|
|
106
|
-
export function createPanelStateStore() {
|
|
107
|
-
const workspaces = new Map();
|
|
108
|
-
function trim(entry, max) {
|
|
109
|
-
while (entry.size > max) {
|
|
110
|
-
const oldest = entry.keys().next();
|
|
111
|
-
if (oldest.done === true)
|
|
112
|
-
return;
|
|
113
|
-
entry.delete(oldest.value);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
function workspaceEntryOf(workspace) {
|
|
117
|
-
const existing = workspaces.get(workspace);
|
|
118
|
-
if (existing !== undefined)
|
|
119
|
-
return existing;
|
|
120
|
-
const created = { at: 0, units: new Map() };
|
|
121
|
-
workspaces.set(workspace, created);
|
|
122
|
-
trim(workspaces, PANEL_STATE_MAX_UNITS);
|
|
123
|
-
return created;
|
|
124
|
-
}
|
|
125
|
-
function unitEntryOf(entry, unit) {
|
|
126
|
-
const existing = entry.units.get(unit);
|
|
127
|
-
if (existing !== undefined)
|
|
128
|
-
return existing;
|
|
129
|
-
const created = { at: 0, cards: new Map() };
|
|
130
|
-
entry.units.set(unit, created);
|
|
131
|
-
return created;
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
cards(report) {
|
|
135
|
-
const entry = workspaceEntryOf(report.workspace);
|
|
136
|
-
for (const card of report.cards) {
|
|
137
|
-
const unit = unitEntryOf(entry, card.unit);
|
|
138
|
-
unit.cards.delete(card.route);
|
|
139
|
-
unit.cards.set(card.route, card);
|
|
140
|
-
trim(unit.cards, PANEL_STATE_MAX_CARDS);
|
|
141
|
-
if (card.at > unit.at)
|
|
142
|
-
unit.at = card.at;
|
|
143
|
-
if (card.at > entry.at)
|
|
144
|
-
entry.at = card.at;
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
crash(report) {
|
|
148
|
-
const entry = workspaceEntryOf(report.workspace);
|
|
149
|
-
const unit = unitEntryOf(entry, report.unit);
|
|
150
|
-
const previous = unit.crash;
|
|
151
|
-
const counted = previous !== undefined &&
|
|
152
|
-
previous.reason === report.reason &&
|
|
153
|
-
report.at >= previous.at &&
|
|
154
|
-
report.at - previous.at <= PANEL_STATE_CRASH_WINDOW_MS;
|
|
155
|
-
unit.crash = { unit: report.unit, reason: report.reason, at: report.at, count: counted ? previous.count + 1 : 1 };
|
|
156
|
-
if (report.at > unit.at)
|
|
157
|
-
unit.at = report.at;
|
|
158
|
-
if (report.at > entry.at)
|
|
159
|
-
entry.at = report.at;
|
|
160
|
-
},
|
|
161
|
-
snapshot(workspace) {
|
|
162
|
-
if (workspace === null)
|
|
163
|
-
return { workspace: null, at: 0, units: [] };
|
|
164
|
-
const entry = workspaces.get(workspace);
|
|
165
|
-
if (entry === undefined)
|
|
166
|
-
return { workspace, at: 0, units: [] };
|
|
167
|
-
const units = [...entry.units.entries()].map(([unit, one]) => {
|
|
168
|
-
const cards = [...one.cards.values()].sort((a, b) => a.route.localeCompare(b.route));
|
|
169
|
-
const okAt = cards.reduce((best, card) => (card.phase === 'ready' && (best === null || card.at > best) ? card.at : best), null);
|
|
170
|
-
return { unit, at: one.at, okAt, cards, ...(one.crash === undefined ? {} : { crash: one.crash }) };
|
|
171
|
-
});
|
|
172
|
-
units.sort((a, b) => b.at - a.at || a.unit.localeCompare(b.unit));
|
|
173
|
-
return { workspace, at: entry.at, units };
|
|
174
|
-
},
|
|
175
|
-
};
|
|
176
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { writeOutcomeOf, writeRoute } from '../host-write.js';
|
|
3
|
-
|
|
4
|
-
describe('writeRoute', () => {
|
|
5
|
-
it('三条通道各自拼得出路由(面板上的写只有这三条)', () => {
|
|
6
|
-
expect(writeRoute('prefs', 'cmdb')).toBe('prefs/cmdb');
|
|
7
|
-
expect(writeRoute('actions', 'cmdb-release')).toBe('actions/cmdb-release');
|
|
8
|
-
expect(writeRoute('provision', '')).toBe('provision');
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('provision 忽略资源名(它只发 {action, unit},没有资源段)', () => {
|
|
12
|
-
expect(writeRoute('provision', 'issues')).toBe('provision');
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
describe('writeOutcomeOf', () => {
|
|
17
|
-
it('成了 → 值原样交出', () => {
|
|
18
|
-
const outcome = writeOutcomeOf<{ text: string }>({ ok: true, text: '发出去了' }, '网络不通');
|
|
19
|
-
|
|
20
|
-
expect(outcome).toEqual({ ok: true, value: { ok: true, text: '发出去了' } });
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('★ 请求没到(null)→ 用调用方给的那句网络文案', () => {
|
|
24
|
-
expect(writeOutcomeOf(null, '网络不通')).toEqual({ ok: false, message: '网络不通' });
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('★ 宿主说失败 → 原样用宿主的话 + detail(不再包一层"操作失败")', () => {
|
|
28
|
-
const outcome = writeOutcomeOf(
|
|
29
|
-
{ ok: false, error: { code: 'cmdb/release-blocked', message: '生产环境要先审批', detail: 'job 1234' } },
|
|
30
|
-
'网络不通',
|
|
31
|
-
);
|
|
32
|
-
|
|
33
|
-
expect(outcome).toEqual({ ok: false, message: '生产环境要先审批', detail: 'job 1234' });
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('★ 登录态失效那条错误带着 helpUrl → 一路带出去(卡片才能给「去登录 ↗」而不是"还没绑定")', () => {
|
|
37
|
-
const outcome = writeOutcomeOf(
|
|
38
|
-
{
|
|
39
|
-
ok: false,
|
|
40
|
-
error: {
|
|
41
|
-
code: 'cmdb/login-required',
|
|
42
|
-
message: 'CMDB 登录态失效了',
|
|
43
|
-
helpUrl: 'https://cmdb.example.test/login',
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
'网络不通',
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
expect(outcome).toEqual({
|
|
50
|
-
ok: false,
|
|
51
|
-
message: 'CMDB 登录态失效了',
|
|
52
|
-
helpUrl: 'https://cmdb.example.test/login',
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('没有 detail 就不给那个字段(别塞一个 undefined 进类型里)', () => {
|
|
57
|
-
const outcome = writeOutcomeOf({ ok: false, error: { code: 'x', message: '不行' } }, '网络不通');
|
|
58
|
-
|
|
59
|
-
expect(outcome).toEqual({ ok: false, message: '不行' });
|
|
60
|
-
expect(Object.keys(outcome)).not.toContain('detail');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('★ 领域结果那一档(`{ok:false, text}`,没有 `error`)→ 用生产者自己那句话,**不抛异常**', () => {
|
|
64
|
-
const outcome = writeOutcomeOf(
|
|
65
|
-
{ ok: false, text: 'innettest 没有发布配置(configs 查不到)' } as never,
|
|
66
|
-
'网络不通',
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
expect(outcome).toEqual({ ok: false, message: 'innettest 没有发布配置(configs 查不到)' });
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('★ 连话都没说(`{ok:false}`)→ 用调用方的兜底文案,还是不抛', () => {
|
|
73
|
-
expect(writeOutcomeOf({ ok: false } as never, '网络不通')).toEqual({ ok: false, message: '网络不通' });
|
|
74
|
-
});
|
|
75
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import type { ModuleBlocker } from '../blocker.js';
|
|
3
|
-
import type { CapabilityPayload } from '../workbench-contract.js';
|
|
4
|
-
import { gateOf, probeKeyOf, splitBlocker } from '../unit-board.js';
|
|
5
|
-
|
|
6
|
-
function capability(status: CapabilityPayload['status']): CapabilityPayload {
|
|
7
|
-
return { unit: 'issues', status, required: [], missing: [], detail: '测试用的结论' };
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function blocker(id: string, severity: ModuleBlocker['severity']): ModuleBlocker {
|
|
11
|
-
return { id, severity, title: id, actions: [] };
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe('gateOf(能力门)', () => {
|
|
15
|
-
it('★ 还没探到(null)→ 照常取数:探测只是个前置检查,不许把卡片按住', () => {
|
|
16
|
-
expect(gateOf(null, 'capability')).toEqual({ gated: true });
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('ok → 取数;缺插件/缺命令 → 不取(那次平台读注定失败)', () => {
|
|
20
|
-
expect(gateOf(capability('ok'), 'capability')).toEqual({ gated: true });
|
|
21
|
-
expect(gateOf(capability('missing-plugin'), 'capability')).toEqual({ gated: false });
|
|
22
|
-
expect(gateOf(capability('missing-commands'), 'capability')).toEqual({ gated: false });
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it('★ 探不动(unchecked)→ **照常取数**:那是"问不到",不是"没装"(ADR-0016)', () => {
|
|
26
|
-
expect(gateOf(capability('unchecked'), 'capability')).toEqual({ gated: true });
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("mode: 'none' → 永远取数(套件自己决定不要这道门)", () => {
|
|
30
|
-
expect(gateOf(capability('missing-plugin'), 'none')).toEqual({ gated: true });
|
|
31
|
-
expect(gateOf(null, 'none')).toEqual({ gated: true });
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('splitBlocker(一条阻断 + 至多一条提示)', () => {
|
|
36
|
-
it('没有候选 → 两条都没有', () => {
|
|
37
|
-
expect(splitBlocker([])).toEqual({});
|
|
38
|
-
expect(splitBlocker([undefined, undefined])).toEqual({});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('★ 第一条 block 赢(一张卡上压两条阻断,用户不知道该按哪个)', () => {
|
|
42
|
-
const first = blocker('一', 'block');
|
|
43
|
-
const second = blocker('二', 'block');
|
|
44
|
-
|
|
45
|
-
expect(splitBlocker([first, second])).toEqual({ blocker: first });
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('只有 notice → 就是 notice(不拦人)', () => {
|
|
49
|
-
const notice = blocker('降级', 'notice');
|
|
50
|
-
|
|
51
|
-
expect(splitBlocker([undefined, notice])).toEqual({ notice });
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('★ 有阻断时丢掉提示:那一刻提示只是噪声', () => {
|
|
55
|
-
const block = blocker('缺插件', 'block');
|
|
56
|
-
const notice = blocker('降级', 'notice');
|
|
57
|
-
|
|
58
|
-
expect(splitBlocker([notice, block])).toEqual({ blocker: block });
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
describe('probeKeyOf(出错搭车强探的防抖键)', () => {
|
|
63
|
-
it('没有错误 → null(调用方据此不探)', () => {
|
|
64
|
-
expect(probeKeyOf(undefined)).toBeNull();
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('★ 键就是错误码:码没变就不再探(否则"错误 → 强探 → 仍然错误"会转圈)', () => {
|
|
68
|
-
expect(probeKeyOf({ code: 'auth-required', message: '未登录' })).toBe('auth-required');
|
|
69
|
-
expect(probeKeyOf({ code: 'auth-required', message: '未登录(另一个环境)' })).toBe('auth-required');
|
|
70
|
-
expect(probeKeyOf({ code: 'missing-plugin', message: '缺插件' })).toBe('missing-plugin');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('空码给一个稳定的兜底键(不许变成"每次都算新错误")', () => {
|
|
74
|
-
expect(probeKeyOf({ code: '', message: '没说什么' })).toBe('unknown');
|
|
75
|
-
});
|
|
76
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { hasEnvSupply, type UnitManifest } from '../unit.js';
|
|
3
|
-
|
|
4
|
-
function manifest(env?: UnitManifest['env']): UnitManifest {
|
|
5
|
-
return {
|
|
6
|
-
id: 'issues',
|
|
7
|
-
card: { titleKey: 'issues.mine', order: 10 },
|
|
8
|
-
tools: [],
|
|
9
|
-
host: { inject: [] },
|
|
10
|
-
...(env === undefined ? {} : { env }),
|
|
11
|
-
};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe('hasEnvSupply(缺来源时那条回退口径,宿主与浏览器共用一份)', () => {
|
|
15
|
-
it('声明了插件或库 → 有供给', () => {
|
|
16
|
-
expect(hasEnvSupply(manifest({ plugins: [{ name: 'coding', commands: ['x'] }] }))).toBe(true);
|
|
17
|
-
expect(
|
|
18
|
-
hasEnvSupply(
|
|
19
|
-
manifest({
|
|
20
|
-
libs: [
|
|
21
|
-
{
|
|
22
|
-
name: 'opencli-workflow',
|
|
23
|
-
registryEnv: 'WB_NPM',
|
|
24
|
-
registryDefault: 'https://registry.example/',
|
|
25
|
-
purpose: '夹具',
|
|
26
|
-
},
|
|
27
|
-
],
|
|
28
|
-
}),
|
|
29
|
-
),
|
|
30
|
-
).toBe(true);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('★ 只有基座命令(无卡片模块那种)不算供给 —— 它不是市场门槛,只是缺来源时的回退', () => {
|
|
34
|
-
expect(hasEnvSupply(manifest({ command: 'gitops' }))).toBe(false);
|
|
35
|
-
expect(hasEnvSupply(manifest({ plugins: [], libs: [] }))).toBe(false);
|
|
36
|
-
expect(hasEnvSupply(manifest())).toBe(false);
|
|
37
|
-
});
|
|
38
|
-
});
|
package/src/api/unit-board.ts
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import type { ModuleBlocker } from './blocker.js';
|
|
2
|
-
import type { CapabilityPayload } from './workbench-contract.js';
|
|
3
|
-
import type { ApiError } from './workbench-client.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* 卡片闸的两种档:capability 按环境读数判,none 无条件放行。
|
|
7
|
-
*/
|
|
8
|
-
export type GateMode =
|
|
9
|
-
| 'capability'
|
|
10
|
-
| 'none';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* 一次放行判定的结果;gated 为假时卡片不画。
|
|
14
|
-
*/
|
|
15
|
-
export interface UnitGate {
|
|
16
|
-
readonly gated: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 判这张卡现在能不能画。
|
|
21
|
-
* @param capability 环境读数;还没读到给 null。
|
|
22
|
-
* @param mode 闸档。
|
|
23
|
-
* @returns mode 为 none 或读数还没到都放行(先放行让它读);读到明确不通过(ok 与 unchecked 之外)才拦。
|
|
24
|
-
*/
|
|
25
|
-
export function gateOf(capability: CapabilityPayload | null, mode: GateMode): UnitGate {
|
|
26
|
-
if (mode === 'none') return { gated: true };
|
|
27
|
-
if (capability === null) return { gated: true };
|
|
28
|
-
return { gated: capability.status === 'ok' || capability.status === 'unchecked' };
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* 一个单元攒下的卡住态:blocker 顶掉卡片,notice 只提示;组装方产出,卡片消费。
|
|
33
|
-
*/
|
|
34
|
-
export interface UnitBlockers {
|
|
35
|
-
readonly blocker?: ModuleBlocker;
|
|
36
|
-
readonly notice?: ModuleBlocker;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 把候选卡住态分档,每档只留第一个。
|
|
41
|
-
* @param candidates 候选(可能含 undefined),按优先级从高到低给。
|
|
42
|
-
* @returns 分出的 blocker 与 notice;已经有 blocker 时不带 notice(挡住就不必再提示)。
|
|
43
|
-
*/
|
|
44
|
-
export function splitBlocker(candidates: readonly (ModuleBlocker | undefined)[]): UnitBlockers {
|
|
45
|
-
let blocker: ModuleBlocker | undefined;
|
|
46
|
-
let notice: ModuleBlocker | undefined;
|
|
47
|
-
for (const candidate of candidates) {
|
|
48
|
-
if (candidate === undefined) continue;
|
|
49
|
-
if (candidate.severity === 'block') {
|
|
50
|
-
blocker ??= candidate;
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
notice ??= candidate;
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
...(blocker === undefined ? {} : { blocker }),
|
|
57
|
-
...(blocker !== undefined || notice === undefined ? {} : { notice }),
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* 由读口错误算出「出错搭车强探」的防抖键:同一个键只自动重探一次。
|
|
63
|
-
* @param error 读口错误;undefined 表示这次没有错误。
|
|
64
|
-
* @returns 键字符串;空 code 归一到 unknown。
|
|
65
|
-
*/
|
|
66
|
-
export function probeKeyOf(error: ApiError | undefined): string | null {
|
|
67
|
-
if (error === undefined) return null;
|
|
68
|
-
return error.code === '' ? 'unknown' : error.code;
|
|
69
|
-
}
|
package/src/api/unit.ts
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 一张卡片在清单里的静态声明(文案键加排序位);默认显不显示由运行期面板配置定。
|
|
3
|
-
*/
|
|
4
|
-
export interface UnitCard {
|
|
5
|
-
readonly titleKey: string;
|
|
6
|
-
readonly order: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* 一条工具在清单里的样子:全名加会不会写;审批按 writes 认领。
|
|
11
|
-
*/
|
|
12
|
-
export interface UnitTool {
|
|
13
|
-
readonly name: string;
|
|
14
|
-
readonly writes: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* 模块要外壳的哪些服务:inject 缺一个就挂不上,optional 缺了照挂。
|
|
19
|
-
*/
|
|
20
|
-
export interface UnitHostNeeds {
|
|
21
|
-
readonly inject: readonly string[];
|
|
22
|
-
readonly optional?: readonly string[];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* 一个 opencli 插件的来源三选一(git / 本地 / npm);npm 那支的安装源先看 registryEnv 那个环境变量,没设才用 registryDefault。
|
|
27
|
-
*/
|
|
28
|
-
export type PluginSource =
|
|
29
|
-
| { readonly kind: 'git'; readonly url: string }
|
|
30
|
-
| { readonly kind: 'local'; readonly env: string }
|
|
31
|
-
| {
|
|
32
|
-
readonly kind: 'npm';
|
|
33
|
-
readonly package: string;
|
|
34
|
-
readonly registryEnv: string;
|
|
35
|
-
readonly registryDefault?: string;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* 模块要的一个 opencli 插件:名字、它得提供的命令,以及装它的来源(没写就是不代装)。
|
|
40
|
-
*/
|
|
41
|
-
export interface UnitPluginNeed {
|
|
42
|
-
readonly name: string;
|
|
43
|
-
readonly commands?: readonly string[];
|
|
44
|
-
readonly installSource?: PluginSource;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* 模块要的一个共用库:名字、期望范围与它为什么要这个版本(purpose 会进申报文案)。
|
|
49
|
-
*/
|
|
50
|
-
export interface UnitLibNeed {
|
|
51
|
-
readonly name: string;
|
|
52
|
-
readonly version?: string | undefined;
|
|
53
|
-
readonly registryEnv: string;
|
|
54
|
-
readonly registryDefault: string;
|
|
55
|
-
readonly purpose: string;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* 模块的整份环境需要:一条自检命令,加上插件与共用库两张表。
|
|
60
|
-
*/
|
|
61
|
-
export interface UnitEnvNeeds {
|
|
62
|
-
readonly command?: string;
|
|
63
|
-
readonly plugins?: readonly UnitPluginNeed[];
|
|
64
|
-
readonly libs?: readonly UnitLibNeed[];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* 已装插件与源上最新版那一对,用来判该不该提示升级;latest 缺省表示还没查到。
|
|
69
|
-
*/
|
|
70
|
-
export interface PluginRelease {
|
|
71
|
-
readonly installed: string;
|
|
72
|
-
readonly latest?: string;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* 装配期用的模块清单:单元 id、卡片、工具与宿主 / 环境需要,比声明少一层协议包装。
|
|
77
|
-
*/
|
|
78
|
-
export interface UnitManifest {
|
|
79
|
-
readonly id: string;
|
|
80
|
-
readonly card: UnitCard | null;
|
|
81
|
-
readonly tools: readonly UnitTool[];
|
|
82
|
-
readonly host: UnitHostNeeds;
|
|
83
|
-
readonly env?: UnitEnvNeeds;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 判这个模块要不要往外装东西。
|
|
88
|
-
* @param manifest 模块清单。
|
|
89
|
-
* @returns 插件与共用库两张表都空时给 false。
|
|
90
|
-
*/
|
|
91
|
-
export function hasEnvSupply(manifest: UnitManifest): boolean {
|
|
92
|
-
return (manifest.env?.plugins ?? []).length > 0 || (manifest.env?.libs ?? []).length > 0;
|
|
93
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { PluginRelease } from '../api/unit.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 供给动作的那几档(装 / 升 / 卸,模块、共用依赖与插件各一套);写口按它分派。
|
|
5
|
-
*/
|
|
6
|
-
export type ProvisionAction =
|
|
7
|
-
| 'install'
|
|
8
|
-
| 'update'
|
|
9
|
-
| 'uninstall'
|
|
10
|
-
| 'update-dependency'
|
|
11
|
-
| 'install-bundle'
|
|
12
|
-
| 'update-bundle'
|
|
13
|
-
| 'remove-bundle'
|
|
14
|
-
| 'cancel-install'
|
|
15
|
-
| 'update-plugin'
|
|
16
|
-
| 'uninstall-plugin'
|
|
17
|
-
| 'update-workbench';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* 宿主报的一个 opencli 插件此刻的状态:装没装、缺哪些命令、该不该升,以及怎么升。
|
|
21
|
-
*/
|
|
22
|
-
export interface PluginStatePayload {
|
|
23
|
-
readonly name: string;
|
|
24
|
-
readonly status: 'ok' | 'outdated' | 'missing';
|
|
25
|
-
readonly missing: readonly string[];
|
|
26
|
-
readonly install?: 'ready' | 'not-declared' | 'env-missing' | 'malformed';
|
|
27
|
-
readonly command?: string;
|
|
28
|
-
readonly release?: PluginRelease;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* 宿主对「这个单元现在能不能用」的那份读数:状态、缺的命令与插件、修复动作和供给细节。
|
|
33
|
-
*/
|
|
34
|
-
export interface CapabilityPayload {
|
|
35
|
-
readonly unit: string;
|
|
36
|
-
readonly status: 'ok' | 'failed' | 'missing-commands' | 'missing-plugin' | 'unchecked';
|
|
37
|
-
readonly plugin?: string;
|
|
38
|
-
readonly required: readonly string[];
|
|
39
|
-
readonly missing: readonly string[];
|
|
40
|
-
readonly detail: string;
|
|
41
|
-
readonly command?: string;
|
|
42
|
-
readonly fix?: 'install' | 'update';
|
|
43
|
-
readonly plugins?: readonly PluginStatePayload[];
|
|
44
|
-
readonly released?: boolean;
|
|
45
|
-
readonly install?: 'ready' | 'not-declared' | 'env-missing' | 'malformed';
|
|
46
|
-
readonly libs?: readonly LibStatePayload[];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 宿主报的一个共用库此刻的状态(装没装、版本对不对)与它为什么要这个版本。
|
|
51
|
-
*/
|
|
52
|
-
export interface LibStatePayload {
|
|
53
|
-
readonly name: string;
|
|
54
|
-
readonly purpose: string;
|
|
55
|
-
readonly status: 'ok' | 'outdated' | 'missing' | 'unsatisfied';
|
|
56
|
-
readonly installed?: string;
|
|
57
|
-
readonly latest?: string;
|
|
58
|
-
readonly command?: string;
|
|
59
|
-
}
|