@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
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { isolatedHome, toolchainOpencliDir, vendorPeerLink, vendorPluginsDir } from './paths.js';
|
|
4
|
+
import { quoteShellArg } from './shell-text.js';
|
|
5
|
+
|
|
6
|
+
export const CHANNEL_PLUGIN_NAME = 'opencli-plugin-workbench';
|
|
7
|
+
export const CHANNEL_PLUGIN_SITE = 'workbench';
|
|
8
|
+
|
|
9
|
+
export interface ChannelPluginPlan {
|
|
10
|
+
readonly dest: string;
|
|
11
|
+
readonly version: string;
|
|
12
|
+
readonly commands: readonly string[];
|
|
13
|
+
readonly line: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function textOf(value: unknown): string {
|
|
17
|
+
return typeof value === 'string' ? value.trim() : '';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function channelVersionOf(dir: string): string | undefined {
|
|
21
|
+
try {
|
|
22
|
+
const parsed: unknown = JSON.parse(readFileSync(join(dir, 'opencli-plugin.json'), 'utf8'));
|
|
23
|
+
if (typeof parsed !== 'object' || parsed === null) return undefined;
|
|
24
|
+
const version = textOf((parsed as Record<string, unknown>)['version']);
|
|
25
|
+
return version === '' ? undefined : version;
|
|
26
|
+
} catch {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function channelPluginPlan(options: {
|
|
32
|
+
readonly channelDir: string;
|
|
33
|
+
readonly command?: string;
|
|
34
|
+
}): ChannelPluginPlan | undefined {
|
|
35
|
+
const version = channelVersionOf(options.channelDir);
|
|
36
|
+
if (version === undefined) return undefined;
|
|
37
|
+
const command = options.command ?? 'opencli';
|
|
38
|
+
const dest = join(vendorPluginsDir(), CHANNEL_PLUGIN_NAME);
|
|
39
|
+
const peer = vendorPeerLink();
|
|
40
|
+
const commands = [
|
|
41
|
+
`rm -rf ${quoteShellArg(dest)} && mkdir -p ${quoteShellArg(dest)} && cp -R ${quoteShellArg(options.channelDir)}/. ${quoteShellArg(dest)}/`,
|
|
42
|
+
`rm -rf ${quoteShellArg(peer.dir)} && mkdir -p ${quoteShellArg(peer.parent)} && ln -s ${quoteShellArg(toolchainOpencliDir())} ${quoteShellArg(peer.dir)}`,
|
|
43
|
+
`(${quoteShellArg(command)} plugin uninstall ${quoteShellArg(CHANNEL_PLUGIN_SITE)} || true)`,
|
|
44
|
+
`${quoteShellArg(command)} plugin install ${quoteShellArg(dest)}`,
|
|
45
|
+
];
|
|
46
|
+
return { dest, version, commands, line: commands.join(' && ') };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function channelInstalledVersion(): string | undefined {
|
|
50
|
+
return channelVersionOf(join(vendorPluginsDir(), CHANNEL_PLUGIN_NAME));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function channelSiteInstalled(): boolean {
|
|
54
|
+
return existsSync(join(isolatedHome(), '.opencli', 'plugins', CHANNEL_PLUGIN_SITE));
|
|
55
|
+
}
|
package/src/host/cli.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DshHostContext } from '../api/dsh.js';
|
|
2
|
+
import type { CliPort } from '../contract/cli.js';
|
|
3
|
+
import { adaptersOf } from './adapters.js';
|
|
4
|
+
|
|
5
|
+
export function cliPortOf(ctx: DshHostContext): CliPort {
|
|
6
|
+
return { command: adaptersOf(ctx).runtime.opencliCommand(ctx).command };
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function cliCommandOf(ctx: DshHostContext): string {
|
|
10
|
+
return cliPortOf(ctx).command;
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function baseName(value: string): string {
|
|
2
|
+
const parts = value.trim().split(/[\\/]/);
|
|
3
|
+
return parts[parts.length - 1] ?? '';
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function isOpencli(name: string): boolean {
|
|
7
|
+
return name === 'opencli' || name === 'opencli.cmd' || name === 'opencli.exe';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function commandNamesMatch(declared: string, resolved: string): boolean {
|
|
11
|
+
const left = baseName(declared);
|
|
12
|
+
const right = baseName(resolved);
|
|
13
|
+
if (left === '' || right === '') return false;
|
|
14
|
+
return left === right || (isOpencli(left) && isOpencli(right));
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class WorkbenchDataError extends Error {
|
|
2
|
+
readonly code: string;
|
|
3
|
+
readonly detail?: string;
|
|
4
|
+
readonly hint?: string;
|
|
5
|
+
readonly project?: unknown;
|
|
6
|
+
readonly helpUrl?: string;
|
|
7
|
+
|
|
8
|
+
constructor(
|
|
9
|
+
code: string,
|
|
10
|
+
message: string,
|
|
11
|
+
extra: { detail?: string; hint?: string; project?: unknown; helpUrl?: string } = {},
|
|
12
|
+
) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'WorkbenchDataError';
|
|
15
|
+
this.code = code;
|
|
16
|
+
if (extra.detail !== undefined) this.detail = extra.detail;
|
|
17
|
+
if (extra.hint !== undefined) this.hint = extra.hint;
|
|
18
|
+
if (extra.project !== undefined) this.project = extra.project;
|
|
19
|
+
if (extra.helpUrl !== undefined) this.helpUrl = extra.helpUrl;
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/host/data-root.ts
CHANGED
package/src/host/diy-debug.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { clockOf } from './time.js';
|
|
1
2
|
/**
|
|
2
3
|
* 调试约定的两个相位:`debugging` 正占着用户的屏,`paused` 已暂停但仍持着约定。
|
|
3
4
|
*/
|
|
@@ -156,5 +157,5 @@ export function createDebugStore(): DebugStore {
|
|
|
156
157
|
* @returns 形如「会话 x(自 HH:mm:ssZ 起在调试 y)」的中文串。
|
|
157
158
|
*/
|
|
158
159
|
export function debugOwnerText(state: DebugState): string {
|
|
159
|
-
return `会话 ${state.sessionId}(自 ${
|
|
160
|
+
return `会话 ${state.sessionId}(自 ${clockOf(state.startedAt)}Z 起在调试 ${state.unit})`;
|
|
160
161
|
}
|
package/src/host/diy-record.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { clockOf } from './time.js';
|
|
1
2
|
/**
|
|
2
3
|
* 录制交接的三个相位:`armed` 等用户在外站页面上动手,`recording` 正在录,`finished` 录完待取。
|
|
3
4
|
*/
|
|
@@ -274,6 +275,6 @@ export function createRecordStore(): RecordStore {
|
|
|
274
275
|
* @returns 形如「会话 x(自 HH:mm:ssZ 起在录 y 的「动作」)」的中文串。
|
|
275
276
|
*/
|
|
276
277
|
export function recordOwnerText(state: RecordState): string {
|
|
277
|
-
const at =
|
|
278
|
+
const at = clockOf(state.startedAt);
|
|
278
279
|
return `会话 ${state.sessionId}(自 ${at}Z 起在录 ${state.unit} 的「${state.action}」)`;
|
|
279
280
|
}
|
package/src/host/facts.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import type { UnitManifest } from '../contract/unit.js';
|
|
3
|
+
import { FACT_SCOPE_SUFFIX } from '../contract/facts.js';
|
|
3
4
|
|
|
4
5
|
export interface FactChange {
|
|
5
6
|
readonly rev: number;
|
|
@@ -19,7 +20,7 @@ export interface FactLog {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export function createFactLog(options: { readonly epoch?: string } = {}): FactLog {
|
|
22
|
-
const epoch = options.epoch ?? `e${
|
|
23
|
+
const epoch = options.epoch ?? `e${randomUUID()}`;
|
|
23
24
|
let rev = 0;
|
|
24
25
|
const last = new Map<string, number>();
|
|
25
26
|
const listeners = new Set<(change: FactChange) => void>();
|
package/src/host/git.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DshShell } from '../api/dsh.js';
|
|
2
|
-
import { quoteShellArg, tailLines } from '
|
|
3
|
-
import { runShell } from '
|
|
2
|
+
import { quoteShellArg, tailLines } from '../host/shell-text.js';
|
|
3
|
+
import { runShell } from '../host/shell.js';
|
|
4
4
|
|
|
5
5
|
export type OriginRead =
|
|
6
6
|
| { readonly kind: 'ok'; readonly remote: string }
|
package/src/host/http.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
type ProvisionHandler,
|
|
8
8
|
type ProvisionRequest,
|
|
9
9
|
} from './provision.js';
|
|
10
|
-
import { WorkbenchDataError } from '
|
|
10
|
+
import { WorkbenchDataError } from './data-error.js';
|
|
11
11
|
import { writeResultForClient } from './write-result.js';
|
|
12
12
|
|
|
13
13
|
export type RouteHandler = (search: URLSearchParams) => Promise<unknown> | unknown;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 跨平台库的「能力 → 首选实现」表:外壳 arch 的 S68 与 DIY 模块的 `source` 判据共用这一份,
|
|
3
|
+
* 避免两边各写一张表后漂开。
|
|
4
|
+
*
|
|
5
|
+
* 能力名是「做什么」,`preferred` 是「用什么」;两者不是同一个层级(类似 datetime → dayjs)。
|
|
6
|
+
* 手写轮子的指纹只认最常见的直连写法;`importsPreferred()` 负责判断这个文件是否已经在用首选库。
|
|
7
|
+
*/
|
|
8
|
+
export interface LibCapability {
|
|
9
|
+
readonly capability: string;
|
|
10
|
+
readonly preferred: string;
|
|
11
|
+
readonly pattern: RegExp;
|
|
12
|
+
readonly why: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** 手写轮子的硬指纹;按能力名稳定排序,方便两边报告与测试对照。 */
|
|
16
|
+
export const LIB_CAPABILITIES: readonly LibCapability[] = [
|
|
17
|
+
{
|
|
18
|
+
capability: 'process-spawn',
|
|
19
|
+
preferred: 'execa',
|
|
20
|
+
pattern: /from\s+['"]node:child_process['"]/,
|
|
21
|
+
why: '自己起进程要用 execa;同步/跨平台差异交给它',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
capability: 'cli-locate',
|
|
25
|
+
preferred: 'which',
|
|
26
|
+
pattern: /\bprocess\.env\.(?:PATH|PATHEXT)\b/,
|
|
27
|
+
why: '自己扫 PATH/PATHEXT 要用 which(它处理 PATHEXT 与 Path 大小写)',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
capability: 'file-lock',
|
|
31
|
+
preferred: 'proper-lockfile',
|
|
32
|
+
pattern: /\bprocess\.kill\([^)]*,\s*0\)|flag:\s*['"]wx['"]/,
|
|
33
|
+
why: '自己抢文件锁要用 proper-lockfile(stale / 重试 / 跨平台)',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
capability: 'atomic-state',
|
|
37
|
+
preferred: 'write-file-atomic',
|
|
38
|
+
pattern: /writeFileSync\([^)]*\.(?:sync\.json|self-update\.json)/,
|
|
39
|
+
why: '自己直写状态文件要用 write-file-atomic(防写一半)',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 这个文件是否已经 import 了某个首选库(静态或动态 import 都算)。
|
|
45
|
+
* @param source 文件全文。
|
|
46
|
+
* @param preferred 首选库包名。
|
|
47
|
+
* @returns 有 import 就 `true`。
|
|
48
|
+
*/
|
|
49
|
+
export function importsPreferred(source: string, preferred: string): boolean {
|
|
50
|
+
const escaped = preferred.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
51
|
+
return new RegExp(`(?:from\\s*|import\\s*\\(\\s*)['"]${escaped}['"]`).test(source);
|
|
52
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LibNeed, SupplySource } from '../contract/needs.js';
|
|
2
|
+
import { npmRegistryOf } from './plugin-source.js';
|
|
3
|
+
import { quoteShellArg } from './shell-text.js';
|
|
4
|
+
import { libsPrefix, npmCacheDir } from './paths.js';
|
|
5
|
+
|
|
6
|
+
export type NpmSource = Extract<SupplySource, { kind: 'npm' }>;
|
|
7
|
+
|
|
8
|
+
export function libInstallCommand(options: {
|
|
9
|
+
readonly need: LibNeed;
|
|
10
|
+
readonly source: NpmSource;
|
|
11
|
+
readonly version?: string | undefined;
|
|
12
|
+
}): string {
|
|
13
|
+
const { need, source, version } = options;
|
|
14
|
+
const registry = npmRegistryOf(source, process.env);
|
|
15
|
+
const spec = version ?? need.version ?? 'latest';
|
|
16
|
+
const registryFlag = registry.ok ? ` --registry ${quoteShellArg(registry.value)}` : '';
|
|
17
|
+
return `npm i --prefix ${quoteShellArg(libsPrefix())} ${quoteShellArg(`${need.name}@${spec}`)}${registryFlag} --cache ${quoteShellArg(npmCacheDir())}`;
|
|
18
|
+
}
|
package/src/host/long-task.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { epochOf } from './time.js';
|
|
2
|
+
import { runsRouteOf, type LongTaskStatus, type LongTaskStep } from '../contract/long-task.js';
|
|
2
3
|
|
|
3
4
|
const LIVE: ReadonlySet<string> = new Set<LongTaskStatus>(['running', 'needs-login']);
|
|
4
5
|
|
|
@@ -104,7 +105,7 @@ export function createLongTaskRegistry<S extends LongTaskBase>(deps: LongTaskDep
|
|
|
104
105
|
},
|
|
105
106
|
|
|
106
107
|
current(workspace) {
|
|
107
|
-
const floor =
|
|
108
|
+
const floor = epochOf(now()) - recentMs;
|
|
108
109
|
const newest = new Map<string, LongTaskBase>();
|
|
109
110
|
for (const snapshot of runs.values()) {
|
|
110
111
|
if (snapshot.workspace !== workspace) continue;
|
|
@@ -112,7 +113,7 @@ export function createLongTaskRegistry<S extends LongTaskBase>(deps: LongTaskDep
|
|
|
112
113
|
}
|
|
113
114
|
return [...newest.values()]
|
|
114
115
|
.filter(
|
|
115
|
-
(snapshot) => LIVE.has(snapshot.status) ||
|
|
116
|
+
(snapshot) => LIVE.has(snapshot.status) || epochOf(snapshot.at) >= floor,
|
|
116
117
|
)
|
|
117
118
|
.reverse()
|
|
118
119
|
.map((snapshot) => ({ ...deps.view(snapshot as S), id: snapshot.id }));
|