@dsh-workbench/shared 0.3.11 → 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 +1 -1
- 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 -1
- package/dist/components/icons.js +11 -4
- package/dist/config/constants.d.ts +2 -2
- package/dist/config/constants.js +2 -2
- 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/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.js +1 -0
- package/dist/contract/unit-capability.d.ts +34 -0
- package/dist/contract/unit-capability.js +1 -0
- package/dist/{host → 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-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 +224 -71
- package/dist/i18n/index.d.ts +298 -73
- 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 +297 -72
- package/dist/i18n/zh.js +226 -73
- package/dist/index.d.ts +23 -7
- package/dist/index.js +23 -7
- package/dist/{api → lib}/dsh-client.d.ts +11 -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.d.ts +0 -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 +1 -1
- package/src/api/host-write.ts +0 -1
- 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 -8
- package/src/config/constants.ts +2 -2
- 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/{api → contract}/unit-board.ts +0 -1
- 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-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 +224 -71
- 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 +227 -73
- package/src/index.ts +23 -7
- package/src/lib/blocker-action.ts +0 -1
- package/src/{api → lib}/dsh-client.ts +12 -1
- package/src/lib/market-index.ts +36 -0
- package/src/lib/react.ts +0 -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-declaration.d.ts +0 -65
- 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.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__/unit.test.ts +0 -38
- 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/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/unit-board.js → contract/cli.js} +0 -0
- /package/dist/{api/workbench-contract.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/dist/{host/unit-libs.js → contract/plugin-source.js} +0 -0
- /package/dist/{api → contract}/unit-board.d.ts +0 -0
- /package/src/{api → contract}/blocker.ts +0 -0
- /package/src/{api → contract}/long-task.ts +0 -0
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { OPENCLI_PIN } from '../config/constants.js';
|
|
2
|
-
import { quoteShellArg } from './shell-text.js';
|
|
3
|
-
import { dshHome } from './data-root.js';
|
|
4
|
-
export { dshHome };
|
|
5
|
-
export function isolatedRoot() {
|
|
6
|
-
return `${dshHome()}/workbench/opencli`;
|
|
7
|
-
}
|
|
8
|
-
export function isolatedHome() {
|
|
9
|
-
return `${isolatedRoot()}/home`;
|
|
10
|
-
}
|
|
11
|
-
export const OPENCLI_NPM_PACKAGE = '@jackwener/opencli';
|
|
12
|
-
export function toolchainDir() {
|
|
13
|
-
return `${isolatedRoot()}/toolchain`;
|
|
14
|
-
}
|
|
15
|
-
export function toolchainOpencliDir() {
|
|
16
|
-
return `${toolchainDir()}/node_modules/${OPENCLI_NPM_PACKAGE}`;
|
|
17
|
-
}
|
|
18
|
-
export function vendorPrefix() {
|
|
19
|
-
return `${isolatedRoot()}/plugins-npm`;
|
|
20
|
-
}
|
|
21
|
-
export function vendorPluginsDir() {
|
|
22
|
-
return `${vendorPrefix()}/node_modules`;
|
|
23
|
-
}
|
|
24
|
-
export const OPENCLI_CATALOG_ENV = 'DSH_WB_OPENCLI_CATALOG';
|
|
25
|
-
export function cliCatalogPath() {
|
|
26
|
-
const override = process.env[OPENCLI_CATALOG_ENV]?.trim();
|
|
27
|
-
return override === undefined || override === ''
|
|
28
|
-
? `${toolchainOpencliDir()}/cli-manifest.json`
|
|
29
|
-
: override;
|
|
30
|
-
}
|
|
31
|
-
export function vendorPeerLink() {
|
|
32
|
-
const base = `${vendorPrefix()}/node_modules`;
|
|
33
|
-
const [scope] = OPENCLI_NPM_PACKAGE.split('/');
|
|
34
|
-
return { dir: `${base}/${OPENCLI_NPM_PACKAGE}`, parent: `${base}/${scope}` };
|
|
35
|
-
}
|
|
36
|
-
export function npmCacheDir() {
|
|
37
|
-
return `${isolatedRoot()}/npm-cache`;
|
|
38
|
-
}
|
|
39
|
-
export function isolatedCommand() {
|
|
40
|
-
return `${isolatedRoot()}/bin/opencli`;
|
|
41
|
-
}
|
|
42
|
-
export function libsPrefix() {
|
|
43
|
-
return `${isolatedRoot()}/libs`;
|
|
44
|
-
}
|
|
45
|
-
export function libDir(name) {
|
|
46
|
-
return `${libsPrefix()}/node_modules/${name}`;
|
|
47
|
-
}
|
|
48
|
-
export function libInstallCommand(options) {
|
|
49
|
-
const { need, version } = options;
|
|
50
|
-
const registry = process.env[need.registryEnv]?.trim() || need.registryDefault;
|
|
51
|
-
const spec = version ?? need.version ?? 'latest';
|
|
52
|
-
return `npm i --prefix '${libsPrefix()}' ${quoteShellArg(`${need.name}@${spec}`)} --registry '${registry}' --cache '${npmCacheDir()}'`;
|
|
53
|
-
}
|
|
54
|
-
export function isolatedInstallCommand() {
|
|
55
|
-
return `npm i --prefix '${toolchainDir()}' ${OPENCLI_NPM_PACKAGE}@${OPENCLI_PIN} --cache '${npmCacheDir()}'`;
|
|
56
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { quoteShellArg } from './shell-text.js';
|
|
2
|
-
const OPENCLI_WINDOW_ENV = 'OPENCLI_WINDOW=background';
|
|
3
|
-
export function backgroundPrefix() {
|
|
4
|
-
return [quoteShellArg('env'), quoteShellArg(OPENCLI_WINDOW_ENV)];
|
|
5
|
-
}
|
|
6
|
-
export function backgroundLine(command, argv) {
|
|
7
|
-
return [...backgroundPrefix(), quoteShellArg(command), ...argv.map(quoteShellArg)].join(' ');
|
|
8
|
-
}
|
package/dist/host/opencli.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { DshShell } from '../api/dsh.js';
|
|
2
|
-
export declare class WorkbenchDataError extends Error {
|
|
3
|
-
readonly code: string;
|
|
4
|
-
readonly detail?: string;
|
|
5
|
-
readonly hint?: string;
|
|
6
|
-
readonly project?: unknown;
|
|
7
|
-
readonly helpUrl?: string;
|
|
8
|
-
constructor(code: string, message: string, extra?: {
|
|
9
|
-
detail?: string;
|
|
10
|
-
hint?: string;
|
|
11
|
-
project?: unknown;
|
|
12
|
-
helpUrl?: string;
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
export interface OpencliResult {
|
|
16
|
-
readonly value: unknown;
|
|
17
|
-
readonly at: number;
|
|
18
|
-
}
|
|
19
|
-
export type OpencliSession = 'persistent' | 'ephemeral' | 'none';
|
|
20
|
-
export declare function opencliCommandLine(command: string, argv: readonly string[], session?: OpencliSession): string;
|
|
21
|
-
export interface Opencli {
|
|
22
|
-
json(args: readonly string[], options?: {
|
|
23
|
-
key?: string;
|
|
24
|
-
workdir?: string;
|
|
25
|
-
session?: OpencliSession;
|
|
26
|
-
}): Promise<OpencliResult>;
|
|
27
|
-
}
|
|
28
|
-
export declare function createOpencli(options: {
|
|
29
|
-
shell: DshShell;
|
|
30
|
-
plugin: string;
|
|
31
|
-
logger?: {
|
|
32
|
-
warn?(message: string): void;
|
|
33
|
-
} | undefined;
|
|
34
|
-
command?: string;
|
|
35
|
-
timeoutMs?: number;
|
|
36
|
-
maxConcurrent?: number;
|
|
37
|
-
}): Opencli;
|
package/dist/host/opencli.js
DELETED
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { OPENCLI_MAX_CONCURRENT, OPENCLI_TIMEOUT_MS } from '../config/constants.js';
|
|
2
|
-
import { parseJsonLoose } from '../lib/text.js';
|
|
3
|
-
import { quoteShellArg, tailLines } from './shell-text.js';
|
|
4
|
-
import { helpUrlOf, parseCliErrorEnvelope } from './cli-error.js';
|
|
5
|
-
import { backgroundPrefix } from './opencli-window.js';
|
|
6
|
-
import { runShell } from './shell.js';
|
|
7
|
-
const FORBIDDEN_CODES = new Set(['FORBIDDEN', 'PERMISSION_DENIED']);
|
|
8
|
-
const SITE_SESSION_ARGS = ['--site-session', 'persistent'];
|
|
9
|
-
export class WorkbenchDataError extends Error {
|
|
10
|
-
code;
|
|
11
|
-
detail;
|
|
12
|
-
hint;
|
|
13
|
-
project;
|
|
14
|
-
helpUrl;
|
|
15
|
-
constructor(code, message, extra = {}) {
|
|
16
|
-
super(message);
|
|
17
|
-
this.name = 'WorkbenchDataError';
|
|
18
|
-
this.code = code;
|
|
19
|
-
if (extra.detail !== undefined)
|
|
20
|
-
this.detail = extra.detail;
|
|
21
|
-
if (extra.hint !== undefined)
|
|
22
|
-
this.hint = extra.hint;
|
|
23
|
-
if (extra.project !== undefined)
|
|
24
|
-
this.project = extra.project;
|
|
25
|
-
if (extra.helpUrl !== undefined)
|
|
26
|
-
this.helpUrl = extra.helpUrl;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
export function opencliCommandLine(command, argv, session = 'persistent') {
|
|
30
|
-
return [
|
|
31
|
-
...backgroundPrefix(),
|
|
32
|
-
quoteShellArg(command),
|
|
33
|
-
...argv.map(quoteShellArg),
|
|
34
|
-
...(session === 'persistent' ? SITE_SESSION_ARGS : []),
|
|
35
|
-
'-f',
|
|
36
|
-
'json',
|
|
37
|
-
].join(' ');
|
|
38
|
-
}
|
|
39
|
-
export function createOpencli(options) {
|
|
40
|
-
const { shell, plugin, logger, command = 'opencli', timeoutMs = OPENCLI_TIMEOUT_MS, maxConcurrent = OPENCLI_MAX_CONCURRENT, } = options;
|
|
41
|
-
const inflight = new Map();
|
|
42
|
-
const MAX_CONCURRENT = maxConcurrent;
|
|
43
|
-
let running = 0;
|
|
44
|
-
const waiting = [];
|
|
45
|
-
async function acquire() {
|
|
46
|
-
if (running < MAX_CONCURRENT) {
|
|
47
|
-
running += 1;
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
await new Promise((resolve) => waiting.push(resolve));
|
|
51
|
-
}
|
|
52
|
-
function release() {
|
|
53
|
-
const next = waiting.shift();
|
|
54
|
-
if (next === undefined)
|
|
55
|
-
running -= 1;
|
|
56
|
-
else
|
|
57
|
-
next();
|
|
58
|
-
}
|
|
59
|
-
async function runLimited(task) {
|
|
60
|
-
await acquire();
|
|
61
|
-
try {
|
|
62
|
-
return await task();
|
|
63
|
-
}
|
|
64
|
-
finally {
|
|
65
|
-
release();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
async function call(commandLine, workdir) {
|
|
69
|
-
let result;
|
|
70
|
-
try {
|
|
71
|
-
result = await runShell(shell, commandLine, {
|
|
72
|
-
...(workdir === undefined ? {} : { workdir }),
|
|
73
|
-
timeoutMs,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
throw new WorkbenchDataError('cli-exec-failed', `执行 opencli 失败:${String(error)}`, {
|
|
78
|
-
hint: '确认 opencli 已安装且在 PATH 里(which opencli)。',
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
if (result.timedOut) {
|
|
82
|
-
throw new WorkbenchDataError('cli-timeout', `opencli 超过 ${Math.round(timeoutMs / 1000)} 秒没有返回`, { hint: '无头浏览器可能没起来,重试一次通常就好。' });
|
|
83
|
-
}
|
|
84
|
-
if (result.exitCode !== 0) {
|
|
85
|
-
const detail = tailLines(result.stderr || result.stdout, 6);
|
|
86
|
-
const envelope = parseCliErrorEnvelope(result.stderr) ?? parseCliErrorEnvelope(result.stdout);
|
|
87
|
-
const url = envelope === undefined ? undefined : helpUrlOf(envelope);
|
|
88
|
-
if (envelope?.code === 'AUTH_REQUIRED') {
|
|
89
|
-
throw new WorkbenchDataError('auth-required', envelope.message, {
|
|
90
|
-
detail,
|
|
91
|
-
...(url === undefined ? {} : { helpUrl: url }),
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
if (envelope !== undefined && FORBIDDEN_CODES.has(envelope.code)) {
|
|
95
|
-
throw new WorkbenchDataError('permission-denied', envelope.message, {
|
|
96
|
-
detail,
|
|
97
|
-
...(url === undefined ? {} : { helpUrl: url }),
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
if (envelope !== undefined) {
|
|
101
|
-
throw new WorkbenchDataError('cli-command-failed', `${envelope.code}:${envelope.message}`, {
|
|
102
|
-
detail,
|
|
103
|
-
...(envelope.help === undefined ? {} : { hint: envelope.help }),
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
throw new WorkbenchDataError('cli-unclassified', `opencli 这条命令没跑通(退出码 ${result.exitCode}),而且没有结构化错误码`, {
|
|
107
|
-
detail,
|
|
108
|
-
hint: '多半是插件里没有这条命令(版本旧就会缺),也可能是命令自己失败了:先确认命令存在,再更新插件重试。',
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
const parsed = parseJsonLoose(result.stdout);
|
|
112
|
-
if (parsed === undefined) {
|
|
113
|
-
throw new WorkbenchDataError('cli-bad-output', 'opencli 输出不是 JSON', {
|
|
114
|
-
detail: tailLines(result.stdout, 4),
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
return parsed;
|
|
118
|
-
}
|
|
119
|
-
async function json(args, callOptions = {}) {
|
|
120
|
-
const { key, workdir } = callOptions;
|
|
121
|
-
const session = callOptions.session ?? 'persistent';
|
|
122
|
-
const callKey = key ?? args.map((arg) => String(arg)).join(' ');
|
|
123
|
-
const pending = inflight.get(callKey);
|
|
124
|
-
if (pending !== undefined)
|
|
125
|
-
return pending;
|
|
126
|
-
const commandLine = opencliCommandLine(command, [plugin, ...args], session);
|
|
127
|
-
const once = async () => {
|
|
128
|
-
const value = await call(commandLine, workdir);
|
|
129
|
-
return { value, at: Date.now() };
|
|
130
|
-
};
|
|
131
|
-
const task = runLimited(async () => {
|
|
132
|
-
try {
|
|
133
|
-
return await once();
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
if (!(error instanceof WorkbenchDataError) || error.code !== 'auth-required')
|
|
137
|
-
throw error;
|
|
138
|
-
return await once();
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
inflight.set(callKey, task);
|
|
142
|
-
try {
|
|
143
|
-
return await task;
|
|
144
|
-
}
|
|
145
|
-
catch (error) {
|
|
146
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
147
|
-
logger?.warn?.(`[dsh-workbench] opencli 调用失败:${message}`);
|
|
148
|
-
throw error;
|
|
149
|
-
}
|
|
150
|
-
finally {
|
|
151
|
-
inflight.delete(callKey);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return { json };
|
|
155
|
-
}
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 声明协议当前版本;模块清单的 dsh.workbench.apiVersion 要写这个整数。
|
|
3
|
-
*/
|
|
4
|
-
export const WORKBENCH_API_VERSION = 1;
|
|
5
|
-
/**
|
|
6
|
-
* 外壳愿意认的协议版本;不在表里的模块当场被拒,不猜语义。
|
|
7
|
-
*/
|
|
8
|
-
export const SUPPORTED_API_VERSIONS = [WORKBENCH_API_VERSION];
|
|
9
|
-
/**
|
|
10
|
-
* 协议认得的全部键;写了别的键不会被采纳(外壳静默忽略),所以字段名拼错不会有提示。
|
|
11
|
-
*/
|
|
12
|
-
export const DECLARATION_KEYS = [
|
|
13
|
-
'apiVersion',
|
|
14
|
-
'unit',
|
|
15
|
-
'card',
|
|
16
|
-
'tools',
|
|
17
|
-
'host',
|
|
18
|
-
'env',
|
|
19
|
-
];
|
|
20
|
-
/**
|
|
21
|
-
* 协议要求必写的键;env 不在其中(没有环境需要就不写)。
|
|
22
|
-
*/
|
|
23
|
-
export const DECLARATION_REQUIRED_KEYS = [
|
|
24
|
-
'apiVersion',
|
|
25
|
-
'unit',
|
|
26
|
-
'card',
|
|
27
|
-
'tools',
|
|
28
|
-
'host',
|
|
29
|
-
];
|
|
30
|
-
const CARD_KEYS = ['titleKey', 'order'];
|
|
31
|
-
const TOOL_KEYS = ['name', 'writes', 'key'];
|
|
32
|
-
const TOOL_KEY_SHAPE = /^[a-z][a-zA-Z0-9]*$/;
|
|
33
|
-
const HOST_KEYS = ['inject', 'optional'];
|
|
34
|
-
function text(value) {
|
|
35
|
-
return typeof value === 'string' ? value.trim() : '';
|
|
36
|
-
}
|
|
37
|
-
function isRecord(value) {
|
|
38
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
39
|
-
}
|
|
40
|
-
function outsideKeys(value, allowed) {
|
|
41
|
-
return Object.keys(value).filter((key) => !allowed.includes(key));
|
|
42
|
-
}
|
|
43
|
-
function listOf(keys) {
|
|
44
|
-
return keys.map((key) => JSON.stringify(key)).join(' / ');
|
|
45
|
-
}
|
|
46
|
-
function stringArrayProblems(at, value) {
|
|
47
|
-
if (!Array.isArray(value))
|
|
48
|
-
return [`${at} 要是一串字符串,现在是 ${JSON.stringify(value)}`];
|
|
49
|
-
return value.flatMap((item, index) => text(item) === '' ? [`${at}[${index}] 不是非空字符串:${JSON.stringify(item)}`] : []);
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* 查清单里 dsh.workbench 那一段的形状,回一串给人看的问题(中文,带字段路径)。
|
|
53
|
-
* @param subject 报错时用的主语,一般是包名。
|
|
54
|
-
* @param raw 清单里那段原始值,可能什么都不是。
|
|
55
|
-
* @returns 空数组表示形状过得去;版本不对就当场返回(后面的字段无从判起)。
|
|
56
|
-
*/
|
|
57
|
-
export function declarationProblemsOf(subject, raw) {
|
|
58
|
-
if (!isRecord(raw))
|
|
59
|
-
return [`${subject}: dsh.workbench 不是一个对象 —— ${JSON.stringify(raw)}`];
|
|
60
|
-
const version = raw.apiVersion;
|
|
61
|
-
if (version === undefined) {
|
|
62
|
-
return [
|
|
63
|
-
`${subject}: dsh.workbench 没有 apiVersion —— 协议从 v${WORKBENCH_API_VERSION} 起,` +
|
|
64
|
-
`写 \`"apiVersion": ${WORKBENCH_API_VERSION}\`。缺它 = 外壳不认这个模块(ADR-0038 §2.3)`,
|
|
65
|
-
];
|
|
66
|
-
}
|
|
67
|
-
if (!Number.isInteger(version) || !SUPPORTED_API_VERSIONS.includes(version)) {
|
|
68
|
-
return [
|
|
69
|
-
`${subject}: dsh.workbench.apiVersion 是 ${JSON.stringify(version)},这里只认 ` +
|
|
70
|
-
`${SUPPORTED_API_VERSIONS.join(' / ')}(要整数)`,
|
|
71
|
-
];
|
|
72
|
-
}
|
|
73
|
-
const problems = [];
|
|
74
|
-
const unknown = outsideKeys(raw, DECLARATION_KEYS);
|
|
75
|
-
if (unknown.length > 0) {
|
|
76
|
-
problems.push(`${subject}: dsh.workbench 里有协议 v${WORKBENCH_API_VERSION} 不认识的键 ${listOf(unknown)} —— ` +
|
|
77
|
-
`只有 ${listOf(DECLARATION_KEYS)}。(拼错的键会被外壳**静默忽略**:那句声明等于没写)`);
|
|
78
|
-
}
|
|
79
|
-
for (const key of DECLARATION_REQUIRED_KEYS) {
|
|
80
|
-
if (raw[key] === undefined) {
|
|
81
|
-
problems.push(`${subject}: dsh.workbench 缺 ${key}` +
|
|
82
|
-
(key === 'card' ? '(这个模块没有卡片就写 `"card": null`)' : ''));
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const card = raw.card;
|
|
86
|
-
if (card !== undefined && card !== null) {
|
|
87
|
-
if (!isRecord(card)) {
|
|
88
|
-
problems.push(`${subject}: dsh.workbench.card 要么是对象、要么是 null,现在是 ${JSON.stringify(card)}`);
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
const extra = outsideKeys(card, CARD_KEYS);
|
|
92
|
-
if (extra.length > 0) {
|
|
93
|
-
problems.push(`${subject}: dsh.workbench.card 里有不认的键 ${listOf(extra)} —— card 只有 ${listOf(CARD_KEYS)}` +
|
|
94
|
-
`(卡片默认显不显示由运行期的面板配置决定,清单里没有这一位)`);
|
|
95
|
-
}
|
|
96
|
-
if (text(card.titleKey) === '') {
|
|
97
|
-
problems.push(`${subject}: dsh.workbench.card.titleKey 要是非空字符串(面板那一格的文案键)`);
|
|
98
|
-
}
|
|
99
|
-
if (typeof card.order !== 'number' || !Number.isFinite(card.order)) {
|
|
100
|
-
problems.push(`${subject}: dsh.workbench.card.order 要是数字,现在是 ${JSON.stringify(card.order)}`);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
const tools = raw.tools;
|
|
105
|
-
if (tools !== undefined) {
|
|
106
|
-
if (!Array.isArray(tools)) {
|
|
107
|
-
problems.push(`${subject}: dsh.workbench.tools 要是一串声明,现在是 ${JSON.stringify(tools)}`);
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
const seen = new Set();
|
|
111
|
-
const seenKeys = new Set();
|
|
112
|
-
tools.forEach((tool, index) => {
|
|
113
|
-
const at = `dsh.workbench.tools[${index}]`;
|
|
114
|
-
if (!isRecord(tool)) {
|
|
115
|
-
problems.push(`${subject}: ${at} 要是对象,现在是 ${JSON.stringify(tool)}`);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
const extra = outsideKeys(tool, TOOL_KEYS);
|
|
119
|
-
if (extra.length > 0) {
|
|
120
|
-
problems.push(`${subject}: ${at} 里有不认的键 ${listOf(extra)} —— tools 只有 ${listOf(TOOL_KEYS)}`);
|
|
121
|
-
}
|
|
122
|
-
const name = text(tool.name);
|
|
123
|
-
if (name === '') {
|
|
124
|
-
problems.push(`${subject}: ${at}.name 要是非空字符串`);
|
|
125
|
-
}
|
|
126
|
-
else if (seen.has(name)) {
|
|
127
|
-
problems.push(`${subject}: ${at}.name「${name}」与前面那条撞了 —— 工具名会进 dsh 的工具表,不许重`);
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
seen.add(name);
|
|
131
|
-
}
|
|
132
|
-
if (typeof tool.writes !== 'boolean') {
|
|
133
|
-
problems.push(`${subject}: ${at}.writes 要是 true / false(它是"这会写"的唯一声明,缺了审批无从认领)`);
|
|
134
|
-
}
|
|
135
|
-
if (tool.key !== undefined) {
|
|
136
|
-
const key = text(tool.key);
|
|
137
|
-
if (!TOOL_KEY_SHAPE.test(key)) {
|
|
138
|
-
problems.push(`${subject}: ${at}.key 要是 lowerCamelCase 的标识符(如 \`sync\` / \`podLogs\`),` +
|
|
139
|
-
`现在是 ${JSON.stringify(tool.key)} —— 它会变成生成物里的键名,所以不引号、不许带点或横线`);
|
|
140
|
-
}
|
|
141
|
-
else if (seenKeys.has(key)) {
|
|
142
|
-
problems.push(`${subject}: ${at}.key「${key}」与前面那条撞了 —— 生成物里的键只能有一个`);
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
seenKeys.add(key);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
const host = raw.host;
|
|
152
|
-
if (host !== undefined) {
|
|
153
|
-
if (!isRecord(host)) {
|
|
154
|
-
problems.push(`${subject}: dsh.workbench.host 要是对象,现在是 ${JSON.stringify(host)}`);
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
const extra = outsideKeys(host, HOST_KEYS);
|
|
158
|
-
if (extra.length > 0) {
|
|
159
|
-
problems.push(`${subject}: dsh.workbench.host 里有不认的键 ${listOf(extra)} —— host 只有 ${listOf(HOST_KEYS)}`);
|
|
160
|
-
}
|
|
161
|
-
if (host.inject === undefined) {
|
|
162
|
-
problems.push(`${subject}: dsh.workbench.host.inject 没写 —— 它声明这个模块要外壳的哪几个服务,` +
|
|
163
|
-
`外壳靠它判"能不能挂"。一个都不要也要写 \`"inject": []\``);
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.inject`, host.inject));
|
|
167
|
-
}
|
|
168
|
-
if (host.optional !== undefined) {
|
|
169
|
-
problems.push(...stringArrayProblems(`${subject}: dsh.workbench.host.optional`, host.optional));
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
if (raw.env !== undefined && !isRecord(raw.env)) {
|
|
174
|
-
problems.push(`${subject}: dsh.workbench.env 要是对象(command / plugins / libs)—— ` +
|
|
175
|
-
`语义由门禁的 env 判据查,这里只查形状`);
|
|
176
|
-
}
|
|
177
|
-
return problems;
|
|
178
|
-
}
|
|
179
|
-
/**
|
|
180
|
-
* 读一份清单:先查形状,过了再把声明规整成 manifest。
|
|
181
|
-
* @param subject 报错时用的主语。
|
|
182
|
-
* @param raw 清单里 dsh.workbench 那段原始值。
|
|
183
|
-
* @returns 有问题时只有 problems;没问题时 declaration 与 manifest 都给,manifest 里的字符串已 trim。
|
|
184
|
-
*/
|
|
185
|
-
export function readDeclaration(subject, raw) {
|
|
186
|
-
const problems = declarationProblemsOf(subject, raw);
|
|
187
|
-
if (problems.length > 0)
|
|
188
|
-
return { problems };
|
|
189
|
-
const declaration = raw;
|
|
190
|
-
const card = declaration.card;
|
|
191
|
-
return {
|
|
192
|
-
declaration,
|
|
193
|
-
problems: [],
|
|
194
|
-
manifest: {
|
|
195
|
-
id: text(declaration.unit),
|
|
196
|
-
card: card === null
|
|
197
|
-
? null
|
|
198
|
-
: {
|
|
199
|
-
titleKey: text(card.titleKey),
|
|
200
|
-
order: card.order,
|
|
201
|
-
},
|
|
202
|
-
tools: declaration.tools.map((tool) => ({
|
|
203
|
-
name: text(tool.name),
|
|
204
|
-
writes: tool.writes,
|
|
205
|
-
})),
|
|
206
|
-
host: {
|
|
207
|
-
inject: [...(declaration.host.inject ?? [])],
|
|
208
|
-
...(declaration.host.optional === undefined ? {} : { optional: [...declaration.host.optional] }),
|
|
209
|
-
},
|
|
210
|
-
...(declaration.env === undefined ? {} : { env: declaration.env }),
|
|
211
|
-
},
|
|
212
|
-
};
|
|
213
|
-
}
|
package/dist/host/unit-libs.d.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import type { PluginSourceProblem } from './plugin-source.js';
|
|
2
|
-
import type { PluginRelease, UnitLibNeed, UnitPluginNeed } from '../api/unit.js';
|
|
3
|
-
export interface UnitLibState {
|
|
4
|
-
readonly name: string;
|
|
5
|
-
readonly purpose: string;
|
|
6
|
-
readonly status: 'ok' | 'outdated' | 'missing' | 'unsatisfied';
|
|
7
|
-
readonly installed?: string;
|
|
8
|
-
readonly latest?: string;
|
|
9
|
-
readonly command?: string;
|
|
10
|
-
}
|
|
11
|
-
export interface UnitCommands {
|
|
12
|
-
readonly unit: string;
|
|
13
|
-
readonly plugins?: readonly UnitPluginNeed[];
|
|
14
|
-
readonly libs?: readonly UnitLibNeed[];
|
|
15
|
-
}
|
|
16
|
-
export interface UnitPluginState {
|
|
17
|
-
readonly name: string;
|
|
18
|
-
readonly status: "ok" | "outdated" | "missing";
|
|
19
|
-
readonly missing: readonly string[];
|
|
20
|
-
readonly install?: "ready" | PluginSourceProblem;
|
|
21
|
-
readonly command?: string;
|
|
22
|
-
readonly release?: PluginRelease;
|
|
23
|
-
}
|
|
24
|
-
export interface UnitCapability {
|
|
25
|
-
readonly unit: string;
|
|
26
|
-
readonly status: "ok" | "failed" | "missing-commands" | "missing-plugin" | "unchecked";
|
|
27
|
-
readonly plugin?: string;
|
|
28
|
-
readonly required: readonly string[];
|
|
29
|
-
readonly missing: readonly string[];
|
|
30
|
-
readonly detail: string;
|
|
31
|
-
readonly command?: string;
|
|
32
|
-
readonly fix?: "install" | "update";
|
|
33
|
-
readonly install?: "ready" | PluginSourceProblem;
|
|
34
|
-
readonly plugins?: readonly UnitPluginState[];
|
|
35
|
-
readonly libs?: readonly UnitLibState[];
|
|
36
|
-
readonly released?: boolean;
|
|
37
|
-
}
|
package/dist/lib/diy-debug.d.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 调试约定的两个相位:`debugging` 正占着用户的屏,`paused` 已暂停但仍持着约定。
|
|
3
|
-
*/
|
|
4
|
-
export type DebugPhase = 'debugging' | 'paused';
|
|
5
|
-
/**
|
|
6
|
-
* 调试约定收得下的三个人话动作:暂停 / 继续 / 结束。
|
|
7
|
-
*/
|
|
8
|
-
export type DebugIntent = 'pause' | 'resume' | 'stop';
|
|
9
|
-
/**
|
|
10
|
-
* 把工具入参收成人话动作。
|
|
11
|
-
* @param value - 任意入参值。
|
|
12
|
-
* @returns `'pause'` / `'resume'` / `'stop'` 原样;别的值(含 `undefined`、多余空白、大小写不同)给 `null`,由调用方拒。
|
|
13
|
-
*/
|
|
14
|
-
export declare function parseDebugIntent(value: unknown): DebugIntent | null;
|
|
15
|
-
/**
|
|
16
|
-
* 调试约定的有效期(4 小时,毫秒):超过它没动静的约定算过期、当场让人。
|
|
17
|
-
*/
|
|
18
|
-
export declare const DEBUG_STALE_MS: number;
|
|
19
|
-
/**
|
|
20
|
-
* 一份活着的调试约定:相位 + 谁的会话 + 哪个工作区 / 板 / 单元 + 起于何时(`at` 是最后一次动作)。
|
|
21
|
-
*/
|
|
22
|
-
export interface DebugState {
|
|
23
|
-
readonly phase: DebugPhase;
|
|
24
|
-
readonly sessionId: string;
|
|
25
|
-
readonly workspacePath: string;
|
|
26
|
-
readonly title: string;
|
|
27
|
-
readonly board: string;
|
|
28
|
-
readonly unit: string;
|
|
29
|
-
readonly name: string;
|
|
30
|
-
readonly startedAt: number;
|
|
31
|
-
readonly at: number;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* 建立约定要交的那几件:会话、工作区、板、单元、名字,以及此刻的时间戳。
|
|
35
|
-
*/
|
|
36
|
-
export interface DebugPact {
|
|
37
|
-
readonly sessionId: string;
|
|
38
|
-
readonly workspacePath: string;
|
|
39
|
-
readonly title: string;
|
|
40
|
-
readonly board: string;
|
|
41
|
-
readonly unit: string;
|
|
42
|
-
readonly name: string;
|
|
43
|
-
readonly now: number;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* 约定被拒的原因码:自己已持有 / 别人持着 / 不是持有者 / 没有约定 / 已暂停 / 已在调试。
|
|
47
|
-
*/
|
|
48
|
-
export type DebugRefusal = 'already-held' | 'held-by-other' | 'not-owner' | 'none' | 'already-paused' | 'already-debugging';
|
|
49
|
-
/**
|
|
50
|
-
* 一次约定动作的结果:成功带新状态,失败带拒绝码。
|
|
51
|
-
*/
|
|
52
|
-
export type DebugMove = {
|
|
53
|
-
readonly ok: true;
|
|
54
|
-
readonly state: DebugState;
|
|
55
|
-
} | {
|
|
56
|
-
readonly ok: false;
|
|
57
|
-
readonly code: DebugRefusal;
|
|
58
|
-
};
|
|
59
|
-
/**
|
|
60
|
-
* 调试约定的存取口(外壳持有一份):`live` 取当前有效的约定,`begin` / `pause` / `resume` / `stop` 推相位。
|
|
61
|
-
*/
|
|
62
|
-
export interface DebugStore {
|
|
63
|
-
live(now: number): DebugState | null;
|
|
64
|
-
begin(pact: DebugPact): DebugMove;
|
|
65
|
-
pause(sessionId: string, now: number): DebugMove;
|
|
66
|
-
resume(sessionId: string, now: number): DebugMove;
|
|
67
|
-
stop(sessionId: string, now: number): DebugMove;
|
|
68
|
-
settle?(): Promise<void>;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* 造一份新的调试约定存储(进程内存,同一时刻只可能有一份有效约定)。
|
|
72
|
-
* @returns 存取口;动作成不成都在返回的 `DebugMove` 里,不抛异常。
|
|
73
|
-
*/
|
|
74
|
-
export declare function createDebugStore(): DebugStore;
|
|
75
|
-
/**
|
|
76
|
-
* 「谁还占着」的一句话,用于别人来抢时说清现况。
|
|
77
|
-
* @param state - 当前有效的那份约定。
|
|
78
|
-
* @returns 形如「会话 x(自 HH:mm:ssZ 起在调试 y)」的中文串。
|
|
79
|
-
*/
|
|
80
|
-
export declare function debugOwnerText(state: DebugState): string;
|
package/dist/lib/diy-debug.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 把工具入参收成人话动作。
|
|
3
|
-
* @param value - 任意入参值。
|
|
4
|
-
* @returns `'pause'` / `'resume'` / `'stop'` 原样;别的值(含 `undefined`、多余空白、大小写不同)给 `null`,由调用方拒。
|
|
5
|
-
*/
|
|
6
|
-
export function parseDebugIntent(value) {
|
|
7
|
-
return value === 'pause' || value === 'resume' || value === 'stop' ? value : null;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* 调试约定的有效期(4 小时,毫秒):超过它没动静的约定算过期、当场让人。
|
|
11
|
-
*/
|
|
12
|
-
export const DEBUG_STALE_MS = 4 * 60 * 60 * 1000;
|
|
13
|
-
function alive(state, now) {
|
|
14
|
-
if (state === null)
|
|
15
|
-
return null;
|
|
16
|
-
return now - state.at <= DEBUG_STALE_MS ? state : null;
|
|
17
|
-
}
|
|
18
|
-
function ownerOf(state, sessionId, now) {
|
|
19
|
-
const held = alive(state, now);
|
|
20
|
-
if (held === null)
|
|
21
|
-
return 'none';
|
|
22
|
-
return held.sessionId === sessionId ? held : 'not-owner';
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* 造一份新的调试约定存储(进程内存,同一时刻只可能有一份有效约定)。
|
|
26
|
-
* @returns 存取口;动作成不成都在返回的 `DebugMove` 里,不抛异常。
|
|
27
|
-
*/
|
|
28
|
-
export function createDebugStore() {
|
|
29
|
-
let held = null;
|
|
30
|
-
const live = (now) => alive(held, now);
|
|
31
|
-
return {
|
|
32
|
-
live,
|
|
33
|
-
begin(pact) {
|
|
34
|
-
const current = alive(held, pact.now);
|
|
35
|
-
if (current !== null) {
|
|
36
|
-
return { ok: false, code: current.sessionId === pact.sessionId ? 'already-held' : 'held-by-other' };
|
|
37
|
-
}
|
|
38
|
-
const state = {
|
|
39
|
-
phase: 'debugging',
|
|
40
|
-
sessionId: pact.sessionId,
|
|
41
|
-
workspacePath: pact.workspacePath,
|
|
42
|
-
title: pact.title,
|
|
43
|
-
board: pact.board,
|
|
44
|
-
unit: pact.unit,
|
|
45
|
-
name: pact.name,
|
|
46
|
-
startedAt: pact.now,
|
|
47
|
-
at: pact.now,
|
|
48
|
-
};
|
|
49
|
-
held = state;
|
|
50
|
-
return { ok: true, state };
|
|
51
|
-
},
|
|
52
|
-
pause(sessionId, now) {
|
|
53
|
-
const found = ownerOf(held, sessionId, now);
|
|
54
|
-
if (typeof found === 'string')
|
|
55
|
-
return { ok: false, code: found };
|
|
56
|
-
if (found.phase === 'paused')
|
|
57
|
-
return { ok: false, code: 'already-paused' };
|
|
58
|
-
const state = { ...found, phase: 'paused', at: now };
|
|
59
|
-
held = state;
|
|
60
|
-
return { ok: true, state };
|
|
61
|
-
},
|
|
62
|
-
resume(sessionId, now) {
|
|
63
|
-
const found = ownerOf(held, sessionId, now);
|
|
64
|
-
if (typeof found === 'string')
|
|
65
|
-
return { ok: false, code: found };
|
|
66
|
-
if (found.phase === 'debugging')
|
|
67
|
-
return { ok: false, code: 'already-debugging' };
|
|
68
|
-
const state = { ...found, phase: 'debugging', at: now };
|
|
69
|
-
held = state;
|
|
70
|
-
return { ok: true, state };
|
|
71
|
-
},
|
|
72
|
-
stop(sessionId, now) {
|
|
73
|
-
const found = ownerOf(held, sessionId, now);
|
|
74
|
-
if (typeof found === 'string')
|
|
75
|
-
return { ok: false, code: found };
|
|
76
|
-
held = null;
|
|
77
|
-
return { ok: true, state: found };
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* 「谁还占着」的一句话,用于别人来抢时说清现况。
|
|
83
|
-
* @param state - 当前有效的那份约定。
|
|
84
|
-
* @returns 形如「会话 x(自 HH:mm:ssZ 起在调试 y)」的中文串。
|
|
85
|
-
*/
|
|
86
|
-
export function debugOwnerText(state) {
|
|
87
|
-
return `会话 ${state.sessionId}(自 ${new Date(state.startedAt).toISOString().slice(11, 19)}Z 起在调试 ${state.unit})`;
|
|
88
|
-
}
|