@dsh-workbench/core 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 +148 -105
- package/bin/dsh-workbench +132 -31
- package/bin/dsh-workbench.cmd +5 -0
- package/bin/opencli-isolated +3 -2
- package/bin/opencli-isolated.mjs +44 -0
- package/bin/opencli-node-mode.cjs +1 -0
- package/bin/seed-workshop-windows.mjs +307 -0
- package/client.js +8192 -4904
- package/cordis.patch.yml +62 -37
- package/dist/client/client.body.js +8192 -4904
- package/dist/client/index.js +7186 -3898
- package/dist/host/index.js +7277 -6956
- package/dist/types/app/client.d.ts +3 -1
- package/dist/types/app/host.d.ts +2 -1
- package/dist/types/app/layouts/approval-detail.d.ts +3 -0
- package/dist/types/app/layouts/env-gate/boot-gate.d.ts +1 -12
- package/dist/types/app/layouts/env-gate/gate-text.d.ts +2 -1
- package/dist/types/app/layouts/market/DiscoverPanel.d.ts +8 -0
- package/dist/types/app/layouts/market/add-module-text.d.ts +1 -1
- package/dist/types/app/layouts/market/discover-categories.d.ts +8 -0
- package/dist/types/app/layouts/market/discover-confirm.d.ts +14 -0
- package/dist/types/app/layouts/market/discover-detail.d.ts +12 -0
- package/dist/types/app/layouts/market/discover-dialogs.d.ts +7 -0
- package/dist/types/app/layouts/market/discover-doc.d.ts +18 -0
- package/dist/types/app/layouts/market/discover-init-dialog.d.ts +10 -0
- package/dist/types/app/layouts/market/discover-rows.d.ts +24 -0
- package/dist/types/app/layouts/market/discover-sources-dialog.d.ts +16 -0
- package/dist/types/app/layouts/market/discover-states.d.ts +22 -0
- package/dist/types/app/layouts/market/discover-toolbar.d.ts +23 -0
- package/dist/types/app/layouts/market/discover-versions.d.ts +9 -0
- package/dist/types/app/layouts/market/discover-view.d.ts +38 -0
- package/dist/types/app/layouts/market/market-header.d.ts +13 -0
- package/dist/types/app/layouts/market/panel.d.ts +1 -1
- package/dist/types/app/layouts/market/use-add-module.d.ts +1 -1
- package/dist/types/app/layouts/market/use-discover.d.ts +72 -0
- package/dist/types/app/layouts/market/use-module-versions.d.ts +6 -2
- package/dist/types/app/layouts/rightbar/MarketView.d.ts +6 -3
- package/dist/types/app/layouts/rightbar/Rightbar.d.ts +1 -1
- package/dist/types/app/layouts/rightbar/board-shape.d.ts +1 -14
- package/dist/types/app/layouts/rightbar/market-act.d.ts +6 -3
- package/dist/types/app/layouts/rightbar/market-busy.d.ts +0 -22
- package/dist/types/app/layouts/rightbar/market-change.d.ts +1 -1
- package/dist/types/app/layouts/rightbar/market-hint.d.ts +1 -7
- package/dist/types/app/layouts/rightbar/market-plugin-rows.d.ts +0 -7
- package/dist/types/app/layouts/rightbar/market-row-icon.d.ts +1 -1
- package/dist/types/app/layouts/rightbar/market-row-types.d.ts +2 -2
- package/dist/types/app/layouts/rightbar/market-rows.d.ts +1 -1
- package/dist/types/app/layouts/rightbar/market-section-icon.d.ts +1 -1
- package/dist/types/app/layouts/rightbar/market-settle-hold.d.ts +2 -0
- package/dist/types/app/layouts/rightbar/market-settle.d.ts +17 -0
- package/dist/types/app/layouts/rightbar/market-shared-rows.d.ts +1 -1
- package/dist/types/app/layouts/rightbar/market-update-verdict.d.ts +31 -0
- package/dist/types/app/layouts/rightbar/market-view-text.d.ts +8 -1
- package/dist/types/app/layouts/rightbar/market-workbench-row.d.ts +1 -1
- package/dist/types/app/layouts/rightbar/store.d.ts +2 -0
- package/dist/types/app/layouts/sidebar/LongTaskDot.d.ts +6 -0
- package/dist/types/app/layouts/sidebar/LongTaskHover.d.ts +6 -0
- package/dist/types/app/layouts/sidebar/edition-boot.d.ts +6 -0
- package/dist/types/app/layouts/sidebar/edition.d.ts +5 -0
- package/dist/types/app/layouts/sidebar/use-attention.d.ts +0 -4
- package/dist/types/app/layouts/sidebar/workshop-preset.d.ts +2 -0
- package/dist/types/app/layouts/workbench-settings/AdapterSetItem.d.ts +5 -0
- package/dist/types/app/layouts/workbench-settings/ConfigSyncItem.d.ts +5 -0
- package/dist/types/app/layouts/workbench-settings/ConfigSyncRows.d.ts +11 -0
- package/dist/types/app/layouts/workbench-settings/NewWorkbenchItem.d.ts +5 -0
- package/dist/types/app/layouts/workbench-settings/SettingsItem.d.ts +8 -0
- package/dist/types/app/layouts/workbench-settings/SidebarEditionItem.d.ts +5 -0
- package/dist/types/app/layouts/workbench-settings/WorkbenchSettingsSection.d.ts +5 -0
- package/dist/types/app/units/manifests.d.ts +1 -1
- package/dist/types/{app/units → kernel/client}/registry.d.ts +1 -1
- package/dist/types/kernel/contract/bundle-install.d.ts +2 -0
- package/dist/types/kernel/contract/config-sync.d.ts +2 -0
- package/dist/types/kernel/contract/diy.d.ts +1 -0
- package/dist/types/kernel/contract/dsh-plugins.d.ts +2 -0
- package/dist/types/kernel/contract/index.d.ts +4 -0
- package/dist/types/kernel/contract/long-tasks.d.ts +2 -0
- package/dist/types/kernel/contract/market-index.d.ts +2 -0
- package/dist/types/kernel/contract/platform.d.ts +1 -0
- package/dist/types/kernel/contract/preflight-wake.d.ts +2 -0
- package/dist/types/kernel/contract/profile-create.d.ts +2 -0
- package/dist/types/kernel/contract/sidebar-edition.d.ts +2 -0
- package/dist/types/kernel/contract/unit-manifests.d.ts +2 -0
- package/dist/types/{shared/api → kernel}/host/mount-units.d.ts +2 -1
- package/dist/types/modules/panels/client.d.ts +1 -1
- package/dist/types/modules/panels/model/approval.d.ts +4 -8
- package/dist/types/modules/panels/model/diy-browser-tools.d.ts +1 -1
- package/dist/types/modules/panels/model/diy-changelog.d.ts +2 -0
- package/dist/types/modules/panels/model/diy-context.d.ts +20 -18
- package/dist/types/modules/panels/model/diy-page.d.ts +4 -2
- package/dist/types/modules/panels/model/diy-record-open.d.ts +0 -15
- package/dist/types/modules/panels/model/diy-record-text.d.ts +0 -2
- package/dist/types/modules/panels/model/diy-record.d.ts +1 -31
- package/dist/types/modules/panels/model/diy-report.d.ts +6 -7
- package/dist/types/modules/panels/model/diy-tools.d.ts +1 -0
- package/dist/types/modules/panels/model/long-task-tools.d.ts +0 -11
- package/dist/types/modules/panels/model/market-dependency-update.d.ts +15 -0
- package/dist/types/modules/panels/model/market-dependency.d.ts +15 -10
- package/dist/types/modules/panels/model/market-discover-routes.d.ts +3 -0
- package/dist/types/modules/panels/model/market-discover.d.ts +33 -0
- package/dist/types/modules/panels/model/market-dispatch.d.ts +4 -3
- package/dist/types/modules/panels/model/market-env.d.ts +2 -3
- package/dist/types/modules/panels/model/market-registry.d.ts +3 -3
- package/dist/types/modules/panels/model/market-restart.d.ts +1 -1
- package/dist/types/modules/panels/model/market-route.d.ts +5 -3
- package/dist/types/modules/panels/model/market-sources-act.d.ts +9 -0
- package/dist/types/modules/panels/model/market-types.d.ts +7 -13
- package/dist/types/modules/panels/model/market-update-bundle.d.ts +19 -0
- package/dist/types/modules/panels/model/market-verify.d.ts +15 -0
- package/dist/types/modules/panels/model/market-workbench-update.d.ts +3 -2
- package/dist/types/modules/panels/model/market.d.ts +6 -5
- package/dist/types/modules/panels/model/plugin-actions.d.ts +2 -1
- package/dist/types/modules/panels/model/plugin-section.d.ts +3 -1
- package/dist/types/modules/panels/model/publish-preview-routes.d.ts +2 -0
- package/dist/types/modules/panels/unit.d.ts +8 -5
- package/dist/types/modules/sessions/model/attention.d.ts +0 -11
- package/dist/types/modules/sessions/model/session-node.d.ts +0 -10
- package/dist/types/shared/api/diy.d.ts +6 -4
- package/dist/types/shared/api/host/approval-call.d.ts +0 -9
- package/dist/types/shared/api/host/approval-gate.d.ts +26 -0
- package/dist/types/shared/api/host/bundle-routes.d.ts +2 -1
- package/dist/types/shared/api/host/diy-artifacts.d.ts +3 -0
- package/dist/types/shared/api/host/diy-changelog.d.ts +13 -0
- package/dist/types/shared/api/host/diy-components.d.ts +2 -3
- package/dist/types/shared/api/host/diy-modules.d.ts +25 -0
- package/dist/types/shared/api/host/diy-publish-preview.d.ts +4 -0
- package/dist/types/shared/api/host/diy-recon-fs.d.ts +2 -2
- package/dist/types/shared/api/host/diy-tokens.d.ts +8 -0
- package/dist/types/shared/api/host/host-routes.d.ts +10 -0
- package/dist/types/shared/api/host/long-task-notice.d.ts +0 -20
- package/dist/types/shared/api/host/long-tasks.d.ts +1 -8
- package/dist/types/shared/api/host/market-doc.d.ts +21 -0
- package/dist/types/shared/api/host/market-index-fetch.d.ts +37 -0
- package/dist/types/shared/api/host/market-source-init.d.ts +22 -0
- package/dist/types/shared/api/host/market-sources-store.d.ts +15 -0
- package/dist/types/shared/api/host/permission-mode.d.ts +4 -0
- package/dist/types/shared/api/host/post-channels.d.ts +1 -1
- package/dist/types/shared/api/host/sidebar-edition.d.ts +14 -0
- package/dist/types/shared/api/host/unit-roster-facts.d.ts +1 -1
- package/dist/types/shared/api/host/workspace-root.d.ts +6 -0
- package/dist/types/shared/api/platform/client.d.ts +10 -0
- package/dist/types/shared/api/unit-board.d.ts +4 -0
- package/dist/types/shared/api/write-outcome.d.ts +3 -0
- package/dist/types/shared/components/IconModules.d.ts +2 -0
- package/dist/types/shared/components/PanelFoot.d.ts +0 -9
- package/dist/types/shared/components/blocker-action.d.ts +3 -0
- package/dist/types/shared/dev-surface/index.d.ts +5 -0
- package/dist/types/shared/dev-surface/types.d.ts +79 -0
- package/dist/types/shared/hooks/bundle-queries.d.ts +1 -13
- package/dist/types/shared/hooks/fact-transport.d.ts +4 -0
- package/dist/types/shared/hooks/fact-transports.d.ts +0 -4
- package/dist/types/shared/hooks/market-queries.d.ts +11 -0
- package/dist/types/shared/hooks/panel-state-report.d.ts +0 -12
- package/dist/types/shared/hooks/sidebar-edition.d.ts +2 -0
- package/dist/types/shared/hooks/use-blocker-actions.d.ts +0 -8
- package/dist/types/shared/hooks/use-capabilities.d.ts +1 -55
- package/dist/types/shared/hooks/use-capability-gate.d.ts +1 -2
- package/dist/types/shared/hooks/use-diy-debug.d.ts +0 -13
- package/dist/types/shared/hooks/use-diy-record.d.ts +0 -13
- package/dist/types/shared/hooks/use-host-write.d.ts +1 -1
- package/dist/types/shared/hooks/use-shell-long-tasks.d.ts +1 -7
- package/dist/types/shared/hooks/use-unit-board.d.ts +1 -1
- package/icon.svg +17 -28
- package/package.json +33 -13
- package/preset/diy.patch.yml +3 -3
- package/profile/isolation.patch.yml +18 -7
- package/profile/sandbox.patch.yml +2 -2
- package/scripts/clone-profile.mjs +268 -0
- package/scripts/create-workbench.mjs +166 -0
- package/scripts/seed-profile.sh +22 -10
- package/scripts/seed-workshop.sh +17 -19
- package/skills/workbench-module-diy/BUILD.md +57 -133
- package/skills/workbench-module-diy/COPY.md +89 -0
- package/skills/workbench-module-diy/DATASOURCE.md +173 -116
- package/skills/workbench-module-diy/DESIGN.md +76 -109
- package/skills/workbench-module-diy/FAMILY.md +48 -52
- package/skills/workbench-module-diy/KIT.md +78 -133
- package/skills/workbench-module-diy/LINKAGE.md +66 -105
- package/skills/workbench-module-diy/PANEL.md +81 -171
- package/skills/workbench-module-diy/REVIEW.md +67 -81
- package/skills/workbench-module-diy/SKILL.md +66 -96
- package/skills/workbench-module-diy/STEPS.md +66 -69
- package/skills/workbench-module-diy/TOOLS.md +134 -103
- package/skills/workbench-module-diy/WIRING.md +64 -84
- package/skills/workbench-module-diy/WRITES.md +115 -142
- package/dist/types/app/layouts/config-sync/ConfigSyncSection.d.ts +0 -5
- package/dist/types/shared/api/bundle-install.d.ts +0 -123
- package/dist/types/shared/api/config-sync.d.ts +0 -35
- package/dist/types/shared/api/dsh-plugins.d.ts +0 -11
- package/dist/types/shared/api/host/bundle-manager.d.ts +0 -11
- package/dist/types/shared/api/host/config-sync.d.ts +0 -46
- package/dist/types/shared/api/host/diy-preset-health.d.ts +0 -35
- package/dist/types/shared/api/host/diy-workshop.d.ts +0 -23
- package/dist/types/shared/api/host/dsh-plugins.d.ts +0 -5
- package/dist/types/shared/api/host/installed-module.d.ts +0 -54
- package/dist/types/shared/api/host/installed-module.test.d.ts +0 -1
- package/dist/types/shared/api/host/opencli-command.d.ts +0 -10
- package/dist/types/shared/api/host/opencli-command.test.d.ts +0 -1
- package/dist/types/shared/api/host/opencli.test.d.ts +0 -1
- package/dist/types/shared/api/host/package-content.d.ts +0 -6
- package/dist/types/shared/api/host/package-content.test.d.ts +0 -1
- package/dist/types/shared/api/host/package-kind.d.ts +0 -21
- package/dist/types/shared/api/host/package-kind.test.d.ts +0 -1
- package/dist/types/shared/api/host/package-route.d.ts +0 -23
- package/dist/types/shared/api/host/package-route.test.d.ts +0 -1
- package/dist/types/shared/api/host/plugin-catalog.d.ts +0 -65
- package/dist/types/shared/api/host/plugin-login-hint.d.ts +0 -2
- package/dist/types/shared/api/host/plugin-tools.d.ts +0 -14
- package/dist/types/shared/api/host/plugin-units.d.ts +0 -48
- package/dist/types/shared/api/host/preflight-route.d.ts +0 -15
- package/dist/types/shared/api/host/preflight.d.ts +0 -75
- package/dist/types/shared/api/host/probe-cache.d.ts +0 -6
- package/dist/types/shared/api/host/probe-libs.d.ts +0 -11
- package/dist/types/shared/api/host/probe-units.d.ts +0 -17
- package/dist/types/shared/api/host/probe-verdict.d.ts +0 -7
- package/dist/types/shared/api/host/profile-registries.d.ts +0 -21
- package/dist/types/shared/api/host/registry-declaration.d.ts +0 -23
- package/dist/types/shared/api/host/release.d.ts +0 -24
- package/dist/types/shared/api/host/runtime-seed.d.ts +0 -38
- package/dist/types/shared/api/host/self-update.d.ts +0 -45
- package/dist/types/shared/api/host/version-range.d.ts +0 -2
- package/dist/types/shared/api/host/workshop-root.d.ts +0 -16
- package/dist/types/shared/api/long-tasks.d.ts +0 -19
- package/dist/types/shared/api/unit-manifests.d.ts +0 -6
- package/docs/HANDOFF.md +0 -333
- package/docs/OPERATIONS.md +0 -229
- package/skills/workbench-module-diy/TOOLING.md +0 -55
- /package/dist/types/{app/layouts/rightbar/registry.d.ts → kernel/client/board-registry.d.ts} +0 -0
- /package/dist/types/{app/layouts/rightbar/registry.test.d.ts → kernel/contract/contracts.test.d.ts} +0 -0
- /package/dist/types/{shared/api/host/bundle-manager.test.d.ts → kernel/contract/index.test.d.ts} +0 -0
- /package/dist/types/{shared/api → kernel}/host/unit-readiness.d.ts +0 -0
- /package/dist/types/{shared/api → kernel}/host/unit-registry.d.ts +0 -0
- /package/dist/types/shared/{api/host/diy-workshop.test.d.ts → components/blocker-action.test.d.ts} +0 -0
- /package/dist/types/shared/{api/host/dsh-plugins.test.d.ts → dev-surface/install.d.ts} +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const dshHome = process.env.DSH_HOME?.trim() || join(homedir(), '.dsh');
|
|
9
|
+
const workbenchHome = process.env.DSH_WORKBENCH_HOME?.trim() || join(dshHome, 'workbench');
|
|
10
|
+
const root = join(workbenchHome, 'opencli');
|
|
11
|
+
const isolatedHome = join(root, 'home');
|
|
12
|
+
const main = join(root, 'toolchain', 'node_modules', '@jackwener', 'opencli', 'dist', 'src', 'main.js');
|
|
13
|
+
const realHome = process.env.HOME || process.env.USERPROFILE || homedir();
|
|
14
|
+
const preload = join(dirname(fileURLToPath(import.meta.url)), 'opencli-node-mode.cjs');
|
|
15
|
+
|
|
16
|
+
mkdirSync(isolatedHome, { recursive: true });
|
|
17
|
+
if (!existsSync(main)) {
|
|
18
|
+
process.stderr.write(`dsh-workbench: opencli 的隔离运行时还没装好(${join(root, 'toolchain')})。\n`);
|
|
19
|
+
process.stderr.write(' 打开工作台:启动体检会给出一条能直接照做的安装命令。\n');
|
|
20
|
+
process.exit(127);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const env = {
|
|
24
|
+
...process.env,
|
|
25
|
+
HOME: isolatedHome,
|
|
26
|
+
npm_config_cache: join(root, 'npm-cache'),
|
|
27
|
+
};
|
|
28
|
+
const userConfig = join(realHome, '.npmrc');
|
|
29
|
+
if (existsSync(userConfig)) env.NPM_CONFIG_USERCONFIG = userConfig;
|
|
30
|
+
if (process.versions.electron !== undefined) env.ELECTRON_RUN_AS_NODE = '1';
|
|
31
|
+
|
|
32
|
+
const child = spawn(process.execPath, ['--require', preload, main, ...process.argv.slice(2)], {
|
|
33
|
+
stdio: 'inherit',
|
|
34
|
+
env,
|
|
35
|
+
windowsHide: true,
|
|
36
|
+
});
|
|
37
|
+
child.on('error', (error) => {
|
|
38
|
+
process.stderr.write(`dsh-workbench: opencli 没跑起来:${String(error)}\n`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
});
|
|
41
|
+
child.on('exit', (code, signal) => {
|
|
42
|
+
if (signal !== null) process.kill(process.pid, signal);
|
|
43
|
+
else process.exit(code ?? 1);
|
|
44
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
process.defaultApp = true;
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import {
|
|
4
|
+
existsSync,
|
|
5
|
+
lstatSync,
|
|
6
|
+
mkdirSync,
|
|
7
|
+
readFileSync,
|
|
8
|
+
readlinkSync,
|
|
9
|
+
rmSync,
|
|
10
|
+
symlinkSync,
|
|
11
|
+
writeFileSync,
|
|
12
|
+
} from 'node:fs';
|
|
13
|
+
import { homedir } from 'node:os';
|
|
14
|
+
import { dirname, join, resolve } from 'node:path';
|
|
15
|
+
import which from 'which';
|
|
16
|
+
import writeFileAtomic from 'write-file-atomic';
|
|
17
|
+
|
|
18
|
+
const mode = process.argv[2] === 'full' ? 'full' : process.argv[2] === 'sync' ? 'sync' : 'entry';
|
|
19
|
+
const shellRoot = process.env.DSH_WB_SHELL_ROOT ?? '';
|
|
20
|
+
const home = process.env.DSH_HOME?.trim() || join(homedir(), '.dsh');
|
|
21
|
+
const diy = join(home, 'workbench', 'diy');
|
|
22
|
+
const manifest = join(diy, 'package.json');
|
|
23
|
+
const syncState = join(diy, '.sync.json');
|
|
24
|
+
const syncLock = join(diy, '.sync.lock');
|
|
25
|
+
const pnpmPin = 'pnpm@10.32.1';
|
|
26
|
+
const pnpm = which.sync('pnpm', { nothrow: true }) ?? 'pnpm';
|
|
27
|
+
|
|
28
|
+
function say(message) {
|
|
29
|
+
process.stdout.write(`[dsh-workbench] ${message}\n`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function versionOf(file) {
|
|
33
|
+
try {
|
|
34
|
+
const read = JSON.parse(readFileSync(file, 'utf8'));
|
|
35
|
+
return typeof read.version === 'string' ? read.version : '';
|
|
36
|
+
} catch {
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function shellVersion() {
|
|
42
|
+
if (shellRoot === '') return '';
|
|
43
|
+
const version = versionOf(join(shellRoot, 'package.json'));
|
|
44
|
+
if (version !== '') return version;
|
|
45
|
+
say('读不到工作台版本(DSH_WB_SHELL_ROOT),工坊骨架先不建。');
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function primitivesVersion() {
|
|
50
|
+
if (shellRoot === '') return '';
|
|
51
|
+
try {
|
|
52
|
+
const read = JSON.parse(readFileSync(join(shellRoot, 'package.json'), 'utf8'));
|
|
53
|
+
const version = read.devDependencies?.['@deepseek-ai/dsh-client-ui-primitives'];
|
|
54
|
+
return typeof version === 'string' ? version : '';
|
|
55
|
+
} catch {
|
|
56
|
+
return '';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function repoRoot() {
|
|
61
|
+
const parent = dirname(shellRoot);
|
|
62
|
+
return existsSync(join(parent, 'module-tools')) && existsSync(join(parent, 'shared')) ? parent : '';
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function specs(version) {
|
|
66
|
+
const root = repoRoot();
|
|
67
|
+
if (root !== '') {
|
|
68
|
+
return {
|
|
69
|
+
core: `link:${resolve(shellRoot)}`,
|
|
70
|
+
tools: `link:${resolve(join(root, 'module-tools'))}`,
|
|
71
|
+
shared: `link:${resolve(join(root, 'shared'))}`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
core: `^${version}`,
|
|
76
|
+
tools: `^${version}`,
|
|
77
|
+
shared: `^${version}`,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function ensureSkills() {
|
|
82
|
+
const source = join(shellRoot, 'skills', 'workbench-module-diy');
|
|
83
|
+
if (!existsSync(source)) return;
|
|
84
|
+
const link = join(diy, '.agents', 'skills', 'workbench-module-diy');
|
|
85
|
+
try {
|
|
86
|
+
const stat = lstatSync(link);
|
|
87
|
+
if (!stat.isSymbolicLink()) return;
|
|
88
|
+
if (resolve(readlinkSync(link)) === resolve(source)) return;
|
|
89
|
+
rmSync(link, { force: true });
|
|
90
|
+
} catch {
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
mkdirSync(dirname(link), { recursive: true });
|
|
94
|
+
try {
|
|
95
|
+
symlinkSync(resolve(source), link, process.platform === 'win32' ? 'junction' : 'dir');
|
|
96
|
+
say(`工坊指引已链上:${link}`);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
say(`DIY 指引没挂上(${String(error)})—— 不影响启动。`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function writeSkeleton(version) {
|
|
103
|
+
mkdirSync(join(diy, 'packages'), { recursive: true });
|
|
104
|
+
const target = specs(version);
|
|
105
|
+
const devDependencies = {
|
|
106
|
+
'@dsh-workbench/core': target.core,
|
|
107
|
+
'@dsh-workbench/module-tools': target.tools,
|
|
108
|
+
'@dsh-workbench/shared': target.shared,
|
|
109
|
+
'@types/node': '^24.19.0',
|
|
110
|
+
'@types/react': '^19.3.0',
|
|
111
|
+
esbuild: '^0.28.2',
|
|
112
|
+
react: '^19.3.0',
|
|
113
|
+
typescript: '5.9',
|
|
114
|
+
vitest: '^5.0.2',
|
|
115
|
+
};
|
|
116
|
+
const primitives = primitivesVersion();
|
|
117
|
+
if (primitives !== '') devDependencies['@deepseek-ai/dsh-client-ui-primitives'] = primitives;
|
|
118
|
+
const packageJson = {
|
|
119
|
+
name: 'dsh-workbench-diy',
|
|
120
|
+
version: '0.0.0',
|
|
121
|
+
private: true,
|
|
122
|
+
description: 'DIY 工坊:工作台模块在这里造。这个目录由 dsh-workbench 生成。',
|
|
123
|
+
packageManager: pnpmPin,
|
|
124
|
+
devDependencies,
|
|
125
|
+
pnpm: {
|
|
126
|
+
overrides: {
|
|
127
|
+
'@dsh-workbench/core': target.core,
|
|
128
|
+
'@dsh-workbench/module-tools': target.tools,
|
|
129
|
+
'@dsh-workbench/shared': target.shared,
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
writeFileSync(manifest, `${JSON.stringify(packageJson, null, 2)}\n`, 'utf8');
|
|
134
|
+
writeFileSync(
|
|
135
|
+
join(diy, 'pnpm-workspace.yaml'),
|
|
136
|
+
'packages:\n - "packages/*"\n\nonlyBuiltDependencies:\n - esbuild\n',
|
|
137
|
+
'utf8',
|
|
138
|
+
);
|
|
139
|
+
const store = join(diy, '.pnpm-store').replaceAll('\\', '/');
|
|
140
|
+
const cache = join(diy, '.npm-cache').replaceAll('\\', '/');
|
|
141
|
+
writeFileSync(join(diy, '.npmrc'), `store-dir=${store}\ncache-dir=${cache}\n`, 'utf8');
|
|
142
|
+
writeFileSync(
|
|
143
|
+
join(diy, 'README.md'),
|
|
144
|
+
[
|
|
145
|
+
'# DIY 工坊',
|
|
146
|
+
'',
|
|
147
|
+
'工作台模块在这里造。一个模块一个目录,都住在 `packages/` 下。',
|
|
148
|
+
'',
|
|
149
|
+
'- 造一个新模块:`dsh-wb-module init <名字> --dir packages/module-<名字>`',
|
|
150
|
+
'- 每个模块:`pnpm build` / `pnpm typecheck` / `pnpm test` / `pnpm selfcheck`',
|
|
151
|
+
'',
|
|
152
|
+
].join('\n'),
|
|
153
|
+
'utf8',
|
|
154
|
+
);
|
|
155
|
+
say(`建 DIY 工坊 ${diy}`);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function installedCoreVersion() {
|
|
159
|
+
return versionOf(join(diy, 'node_modules', '@dsh-workbench', 'core', 'package.json'));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function syncVersions(version) {
|
|
163
|
+
const target = specs(version);
|
|
164
|
+
const manifestValue = JSON.parse(readFileSync(manifest, 'utf8'));
|
|
165
|
+
manifestValue.devDependencies = {
|
|
166
|
+
...manifestValue.devDependencies,
|
|
167
|
+
'@dsh-workbench/core': target.core,
|
|
168
|
+
'@dsh-workbench/module-tools': target.tools,
|
|
169
|
+
'@dsh-workbench/shared': target.shared,
|
|
170
|
+
};
|
|
171
|
+
manifestValue.pnpm = {
|
|
172
|
+
...manifestValue.pnpm,
|
|
173
|
+
overrides: {
|
|
174
|
+
'@dsh-workbench/core': target.core,
|
|
175
|
+
'@dsh-workbench/module-tools': target.tools,
|
|
176
|
+
'@dsh-workbench/shared': target.shared,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
writeFileSync(manifest, `${JSON.stringify(manifestValue, null, 2)}\n`, 'utf8');
|
|
180
|
+
say(`工坊工具链对齐到 ${version}`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function writeState(state, version, reason = '') {
|
|
184
|
+
const payload = { state, version, at: new Date().toISOString() };
|
|
185
|
+
if (reason !== '') payload.reason = reason;
|
|
186
|
+
try {
|
|
187
|
+
writeFileAtomic.sync(syncState, `${JSON.stringify(payload)}\n`, 'utf8');
|
|
188
|
+
} catch {
|
|
189
|
+
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function sleep(ms) {
|
|
194
|
+
if (ms <= 0) return;
|
|
195
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function lockAlive() {
|
|
199
|
+
if (!existsSync(syncLock)) return false;
|
|
200
|
+
try {
|
|
201
|
+
const read = JSON.parse(readFileSync(syncLock, 'utf8'));
|
|
202
|
+
if (typeof read.pid !== 'number') return false;
|
|
203
|
+
process.kill(read.pid, 0);
|
|
204
|
+
return true;
|
|
205
|
+
} catch {
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function acquireLock() {
|
|
211
|
+
const waitMs = Number(process.env.DSH_WB_SYNC_WAIT_MS ?? '5000');
|
|
212
|
+
const deadline = Date.now() + (Number.isFinite(waitMs) && waitMs > 0 ? waitMs : 0);
|
|
213
|
+
for (;;) {
|
|
214
|
+
if (!lockAlive()) {
|
|
215
|
+
try {
|
|
216
|
+
rmSync(syncLock, { force: true });
|
|
217
|
+
writeFileSync(syncLock, JSON.stringify({ pid: process.pid, at: new Date().toISOString() }), {
|
|
218
|
+
flag: 'wx',
|
|
219
|
+
});
|
|
220
|
+
return true;
|
|
221
|
+
} catch {
|
|
222
|
+
say('工坊自愈锁没抢到,这一轮跳过。');
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (Date.now() >= deadline) {
|
|
227
|
+
say('另一个工坊自愈正持锁,等过一轮仍没抢到,这一轮跳过。');
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
sleep(Math.min(250, Math.max(0, deadline - Date.now())));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
function releaseLock() {
|
|
235
|
+
try {
|
|
236
|
+
rmSync(syncLock, { force: true });
|
|
237
|
+
} catch {
|
|
238
|
+
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function manifestCoreSpec() {
|
|
243
|
+
try {
|
|
244
|
+
const read = JSON.parse(readFileSync(manifest, 'utf8'));
|
|
245
|
+
return read.devDependencies?.['@dsh-workbench/core'] ?? '';
|
|
246
|
+
} catch {
|
|
247
|
+
return '';
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function install() {
|
|
252
|
+
say('装工坊依赖(第一次会下载 react / typescript / vitest)...');
|
|
253
|
+
return new Promise((resolve) => {
|
|
254
|
+
const child = spawn(`"${pnpm}" install`, {
|
|
255
|
+
cwd: diy,
|
|
256
|
+
stdio: 'inherit',
|
|
257
|
+
shell: true,
|
|
258
|
+
env: process.env,
|
|
259
|
+
windowsHide: true,
|
|
260
|
+
});
|
|
261
|
+
child.on('error', (error) => {
|
|
262
|
+
say(`pnpm 没跑起来:${String(error)}`);
|
|
263
|
+
resolve(1);
|
|
264
|
+
});
|
|
265
|
+
child.on('close', (code) => resolve(code ?? 1));
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const version = shellVersion();
|
|
270
|
+
|
|
271
|
+
if (!existsSync(manifest)) {
|
|
272
|
+
if (mode === 'entry') {
|
|
273
|
+
say('工坊骨架还没建,等 full 那一趟。');
|
|
274
|
+
process.exit(0);
|
|
275
|
+
}
|
|
276
|
+
if (version === '') process.exit(0);
|
|
277
|
+
writeSkeleton(version);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
ensureSkills();
|
|
281
|
+
|
|
282
|
+
const depsMissing = !existsSync(join(diy, 'node_modules'));
|
|
283
|
+
if (depsMissing && mode === 'entry') process.exit(0);
|
|
284
|
+
if (version === '') process.exit(0);
|
|
285
|
+
|
|
286
|
+
const installed = installedCoreVersion();
|
|
287
|
+
const target = specs(version);
|
|
288
|
+
const outdated = manifestCoreSpec() !== target.core || installed !== version;
|
|
289
|
+
if (!depsMissing && !outdated) {
|
|
290
|
+
writeState('ok', version);
|
|
291
|
+
process.exit(0);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (!acquireLock()) process.exit(0);
|
|
295
|
+
let heartbeat = null;
|
|
296
|
+
try {
|
|
297
|
+
writeState('syncing', version);
|
|
298
|
+
heartbeat = globalThis.setInterval(() => writeState('syncing', version), 1000);
|
|
299
|
+
if (outdated) syncVersions(version);
|
|
300
|
+
const code = await install();
|
|
301
|
+
globalThis.clearInterval(heartbeat);
|
|
302
|
+
writeState(code === 0 ? 'ok' : 'failed', version, code === 0 ? '' : 'pnpm install 失败');
|
|
303
|
+
process.exit(code);
|
|
304
|
+
} finally {
|
|
305
|
+
if (heartbeat !== null) globalThis.clearInterval(heartbeat);
|
|
306
|
+
releaseLock();
|
|
307
|
+
}
|