@dsh-workbench/adapter-probe 1.1.8 → 1.1.9
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/dist/browser-wake.d.ts +1 -0
- package/dist/browser-wake.js +7 -0
- package/dist/command-name.d.ts +1 -0
- package/dist/command-name.js +12 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/preflight-route.d.ts +8 -3
- package/dist/preflight-route.js +8 -3
- package/dist/preflight.d.ts +10 -3
- package/dist/preflight.js +74 -62
- package/dist/probe-libs.js +4 -2
- package/dist/probe-port.d.ts +2 -0
- package/dist/probe-port.js +6 -0
- package/dist/probe-units.js +4 -2
- package/dist/probe-verdict.js +2 -1
- package/dist/release-port.d.ts +20 -0
- package/dist/release-port.js +7 -0
- package/dist/runtime-seed.d.ts +2 -1
- package/dist/runtime-seed.js +18 -4
- package/dist/supply-port.d.ts +2 -0
- package/dist/supply-port.js +48 -0
- package/package.json +5 -5
package/dist/browser-wake.d.ts
CHANGED
package/dist/browser-wake.js
CHANGED
|
@@ -261,3 +261,10 @@ export function createDesktopBrowser(options) {
|
|
|
261
261
|
}
|
|
262
262
|
return { observe, wake };
|
|
263
263
|
}
|
|
264
|
+
export function bridgeFixCommand(command, issues) {
|
|
265
|
+
if (issues.includes('profile') || issues.includes('stale'))
|
|
266
|
+
return `${command} profile list`;
|
|
267
|
+
if (issues.includes('daemon'))
|
|
268
|
+
return `${command} daemon restart`;
|
|
269
|
+
return undefined;
|
|
270
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function commandNamesMatch(declared: string, resolved: string): boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const SCRIPT_EXTENSION = /\.(cmd|exe|bat)$/i;
|
|
2
|
+
function baseName(value) {
|
|
3
|
+
const parts = value.trim().split(/[\\/]/);
|
|
4
|
+
return (parts[parts.length - 1] ?? '').replace(SCRIPT_EXTENSION, '');
|
|
5
|
+
}
|
|
6
|
+
export function commandNamesMatch(declared, resolved) {
|
|
7
|
+
const left = baseName(declared);
|
|
8
|
+
const right = baseName(resolved);
|
|
9
|
+
if (left === '' || right === '')
|
|
10
|
+
return false;
|
|
11
|
+
return left === right;
|
|
12
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,3 +12,7 @@ export * from './toolchain.js';
|
|
|
12
12
|
export * from './version-range.js';
|
|
13
13
|
export * from './install.js';
|
|
14
14
|
export * from './self-update.js';
|
|
15
|
+
export { createProbePort } from './probe-port.js';
|
|
16
|
+
export { createSupplyPort } from './supply-port.js';
|
|
17
|
+
export { packageRootOf } from '@dsh-workbench/shared/host';
|
|
18
|
+
export { resetReleaseCache } from './release-port.js';
|
package/dist/index.js
CHANGED
|
@@ -12,3 +12,7 @@ export * from './toolchain.js';
|
|
|
12
12
|
export * from './version-range.js';
|
|
13
13
|
export * from './install.js';
|
|
14
14
|
export * from './self-update.js';
|
|
15
|
+
export { createProbePort } from './probe-port.js';
|
|
16
|
+
export { createSupplyPort } from './supply-port.js';
|
|
17
|
+
export { packageRootOf } from '@dsh-workbench/shared/host';
|
|
18
|
+
export { resetReleaseCache } from './release-port.js';
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import type { DshHostContext, DshShell } from '@dsh-workbench/shared';
|
|
1
|
+
import type { DshHostContext, DshShell, RuntimeCapabilities } from '@dsh-workbench/shared';
|
|
2
2
|
import type { RouteTable } from '@dsh-workbench/shared/host';
|
|
3
3
|
import { type DesktopBrowser } from './browser-wake.js';
|
|
4
4
|
export declare function registerPreflight(input: {
|
|
5
5
|
routes: RouteTable;
|
|
6
6
|
ctx: DshHostContext;
|
|
7
7
|
shell: DshShell;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
runtimeCommands: Readonly<Record<string, string>>;
|
|
9
|
+
runtimeCapabilities?: RuntimeCapabilities | undefined;
|
|
10
|
+
runtimeCheck?: (() => Promise<{
|
|
11
|
+
ok: boolean;
|
|
12
|
+
detail: string;
|
|
13
|
+
}>) | undefined;
|
|
14
|
+
runtimeLabel?: string | undefined;
|
|
10
15
|
warmReads: () => readonly (readonly string[])[];
|
|
11
16
|
desktopBrowser?: DesktopBrowser | undefined;
|
|
12
17
|
}): void;
|
package/dist/preflight-route.js
CHANGED
|
@@ -21,20 +21,25 @@ function desktopBrowserOf(input) {
|
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
23
|
export function registerPreflight(input) {
|
|
24
|
+
const command = input.runtimeCommands['opencli'] ?? Object.values(input.runtimeCommands)[0] ?? 'opencli';
|
|
25
|
+
const installCommand = process.env.DSH_WORKBENCH_OPENCLI_INSTALL;
|
|
24
26
|
const desktopBrowser = input.desktopBrowser ??
|
|
25
27
|
desktopBrowserOf({
|
|
26
28
|
ctx: input.ctx,
|
|
27
29
|
shell: input.shell,
|
|
28
|
-
command
|
|
30
|
+
command,
|
|
29
31
|
});
|
|
30
32
|
const profileDir = profileDirOf(input.ctx);
|
|
31
33
|
const surface = hostSurface({ profile: profileDir === null ? undefined : basename(profileDir) });
|
|
32
34
|
const preflight = createPreflight({
|
|
33
35
|
shell: input.shell,
|
|
34
|
-
command
|
|
35
|
-
...(
|
|
36
|
+
command,
|
|
37
|
+
...(installCommand === undefined || installCommand === '' ? {} : { installCommand }),
|
|
36
38
|
logger: input.ctx.logger,
|
|
37
39
|
warmReads: input.warmReads,
|
|
40
|
+
...(input.runtimeCapabilities === undefined ? {} : { capabilities: input.runtimeCapabilities }),
|
|
41
|
+
...(input.runtimeCheck === undefined ? {} : { runtimeCheck: input.runtimeCheck }),
|
|
42
|
+
...(input.runtimeLabel === undefined ? {} : { runtimeLabel: input.runtimeLabel }),
|
|
38
43
|
probeDiy: createDiyPresetProbe(input.ctx),
|
|
39
44
|
...(surface.deployment === 'desktop'
|
|
40
45
|
? {
|
package/dist/preflight.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { DshShell } from '@dsh-workbench/shared';
|
|
1
|
+
import type { DshShell, RuntimeCapabilities } from '@dsh-workbench/shared';
|
|
2
2
|
import type { DiyPresetVerdict } from './diy-preset-health.js';
|
|
3
3
|
import { type LocalNpmProvision, type LocalPnpmProvision } from './toolchain.js';
|
|
4
4
|
import type { DesktopBrowser } from './browser-wake.js';
|
|
5
|
-
export type PreflightStepId = 'toolchain' | '
|
|
5
|
+
export type PreflightStepId = 'toolchain' | 'runtime' | 'cli' | 'bridge' | 'diy' | 'warm';
|
|
6
6
|
export type PreflightStepStatus = 'pending' | 'running' | 'ok' | 'warn' | 'failed';
|
|
7
7
|
export interface PreflightStep {
|
|
8
8
|
readonly id: PreflightStepId;
|
|
@@ -23,6 +23,7 @@ export declare function classifyFailure(text: string): PreflightFailure;
|
|
|
23
23
|
export type PreflightGuidance = 'install' | 'path' | 'shell';
|
|
24
24
|
export declare function probeDesktopToolchain(shell: DshShell): Promise<ToolchainReport>;
|
|
25
25
|
export type PreflightBridgeIssue = 'daemon' | 'extension' | 'profile' | 'stale' | 'unknown';
|
|
26
|
+
export declare const BRIDGE_ISSUE_ORDER: readonly PreflightBridgeIssue[];
|
|
26
27
|
export declare function readBridgeReport(stdout: string): {
|
|
27
28
|
readonly ok: boolean;
|
|
28
29
|
readonly issues: readonly PreflightBridgeIssue[];
|
|
@@ -50,7 +51,7 @@ export interface Preflight {
|
|
|
50
51
|
}): Promise<PreflightSnapshot>;
|
|
51
52
|
snapshot(): PreflightSnapshot;
|
|
52
53
|
}
|
|
53
|
-
export declare
|
|
54
|
+
export declare function opencliInstallCommandDefault(): string;
|
|
54
55
|
export interface BridgeVerdict {
|
|
55
56
|
readonly ok: boolean;
|
|
56
57
|
readonly detail: string;
|
|
@@ -78,4 +79,10 @@ export declare function createPreflight(options: {
|
|
|
78
79
|
provisionNpm?: (() => Promise<LocalNpmProvision>) | undefined;
|
|
79
80
|
provisionPnpm?: (() => Promise<LocalPnpmProvision>) | undefined;
|
|
80
81
|
desktopBrowser?: DesktopBrowser | undefined;
|
|
82
|
+
capabilities?: RuntimeCapabilities | undefined;
|
|
83
|
+
runtimeCheck?: (() => Promise<{
|
|
84
|
+
ok: boolean;
|
|
85
|
+
detail: string;
|
|
86
|
+
}>) | undefined;
|
|
87
|
+
runtimeLabel?: string | undefined;
|
|
81
88
|
}): Preflight;
|
package/dist/preflight.js
CHANGED
|
@@ -5,6 +5,7 @@ import { runShell } from '@dsh-workbench/shared/host';
|
|
|
5
5
|
import { DIY_UPGRADE_COMMAND } from './diy-preset-health.js';
|
|
6
6
|
import { opencliInstallCommand } from './install.js';
|
|
7
7
|
import { desktopPnpmPath, LOCAL_NPM_VERSION, LOCAL_PNPM_VERSION, } from './toolchain.js';
|
|
8
|
+
import { bridgeFixCommand } from './browser-wake.js';
|
|
8
9
|
export function classifyFailure(text) {
|
|
9
10
|
const lower = text.toLowerCase();
|
|
10
11
|
if (/eacces|eperm|permission denied|operation not permitted/.test(lower))
|
|
@@ -51,6 +52,7 @@ export async function probeDesktopToolchain(shell) {
|
|
|
51
52
|
];
|
|
52
53
|
return { ok: !nodeMissing, detail: parts.join(' · '), nodeMissing, npmMissing, pnpmProblem };
|
|
53
54
|
}
|
|
55
|
+
export const BRIDGE_ISSUE_ORDER = ['profile', 'stale', 'daemon', 'extension', 'unknown'];
|
|
54
56
|
export function readBridgeReport(stdout) {
|
|
55
57
|
const text = String(stdout ?? '');
|
|
56
58
|
const ok = /^\[OK\] Daemon:/m.test(text) && /^\[OK\] Extension:/m.test(text) && /^\[OK\] Connectivity:/m.test(text);
|
|
@@ -72,8 +74,7 @@ export function readBridgeReport(stdout) {
|
|
|
72
74
|
found.delete('extension');
|
|
73
75
|
if (found.size === 0)
|
|
74
76
|
found.add('unknown');
|
|
75
|
-
|
|
76
|
-
return { ok: false, issues: order.filter((issue) => found.has(issue)), detail: issuesSection(text) };
|
|
77
|
+
return { ok: false, issues: BRIDGE_ISSUE_ORDER.filter((issue) => found.has(issue)), detail: issuesSection(text) };
|
|
77
78
|
}
|
|
78
79
|
function issuesSection(text) {
|
|
79
80
|
const lines = text.split('\n');
|
|
@@ -82,29 +83,28 @@ function issuesSection(text) {
|
|
|
82
83
|
return tailLines(text, 6);
|
|
83
84
|
return lines.slice(start).join('\n').trim();
|
|
84
85
|
}
|
|
85
|
-
function
|
|
86
|
-
|
|
87
|
-
return `${command} profile list`;
|
|
88
|
-
if (issues.includes('daemon'))
|
|
89
|
-
return `${command} daemon restart`;
|
|
90
|
-
return undefined;
|
|
86
|
+
export function opencliInstallCommandDefault() {
|
|
87
|
+
return opencliInstallCommand();
|
|
91
88
|
}
|
|
92
|
-
export const OPENCLI_INSTALL_COMMAND = opencliInstallCommand();
|
|
93
89
|
const WARMABLE_BRIDGE_ISSUES = ['daemon', 'stale'];
|
|
94
90
|
export function canWarm(bridge) {
|
|
95
91
|
return bridge.ok || bridge.issues.every((issue) => WARMABLE_BRIDGE_ISSUES.includes(issue));
|
|
96
92
|
}
|
|
97
|
-
function step(id) {
|
|
98
|
-
return { id, status: 'pending' };
|
|
93
|
+
function step(id, label) {
|
|
94
|
+
return { id, status: 'pending', ...(label === undefined || label === '' ? {} : { label }) };
|
|
99
95
|
}
|
|
100
96
|
export function createPreflight(options) {
|
|
101
97
|
const { shell, command = 'opencli', logger } = options;
|
|
102
|
-
const
|
|
98
|
+
const capabilities = options.capabilities ?? { console: true, pluginMarket: true, browserBridge: true };
|
|
99
|
+
const withConsole = capabilities.console;
|
|
100
|
+
const withBridge = capabilities.browserBridge;
|
|
101
|
+
const installCommand = options.installCommand ?? opencliInstallCommandDefault();
|
|
103
102
|
const warmReads = () => options.warmReads?.() ?? [];
|
|
104
103
|
const steps = () => [
|
|
105
104
|
...(options.probeToolchain === undefined ? [] : [step('toolchain')]),
|
|
106
|
-
step('
|
|
107
|
-
step('
|
|
105
|
+
...(options.runtimeCheck === undefined ? [] : [step('runtime', options.runtimeLabel)]),
|
|
106
|
+
...(withConsole ? [step('cli')] : []),
|
|
107
|
+
...(withBridge ? [step('bridge')] : []),
|
|
108
108
|
...(options.probeDiy === undefined ? [] : [step('diy')]),
|
|
109
109
|
...(warmReads().length === 0 ? [] : [step('warm')]),
|
|
110
110
|
];
|
|
@@ -273,62 +273,74 @@ export function createPreflight(options) {
|
|
|
273
273
|
});
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
patchStep('
|
|
283
|
-
|
|
284
|
-
phase: 'failed',
|
|
285
|
-
error: version.detail,
|
|
286
|
-
failure: classifyFailure(version.detail),
|
|
287
|
-
guidance: 'shell',
|
|
288
|
-
});
|
|
276
|
+
if (options.runtimeCheck !== undefined) {
|
|
277
|
+
patchStep('runtime', { status: 'running' });
|
|
278
|
+
const verdict = await options.runtimeCheck().catch((error) => ({
|
|
279
|
+
ok: false,
|
|
280
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
281
|
+
}));
|
|
282
|
+
patchStep('runtime', { status: verdict.ok ? 'ok' : 'failed', detail: verdict.detail, action: undefined });
|
|
283
|
+
if (!verdict.ok)
|
|
284
|
+
return set({ phase: 'failed', error: verdict.detail, failure: 'missing', guidance: 'install' });
|
|
289
285
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
set({ phase: 'installing' });
|
|
301
|
-
patchStep('opencli', { status: 'running', action: installCommand, command: installCommand });
|
|
302
|
-
const installed = await installOpencli();
|
|
303
|
-
if (!installed.ok) {
|
|
304
|
-
patchStep('opencli', {
|
|
305
|
-
status: 'failed',
|
|
306
|
-
detail: installed.detail,
|
|
307
|
-
command: installCommand,
|
|
308
|
-
});
|
|
309
|
-
return set({
|
|
310
|
-
phase: 'failed',
|
|
311
|
-
error: installed.detail,
|
|
312
|
-
failure: classifyFailure(installed.detail),
|
|
313
|
-
guidance: 'install',
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
patchStep('opencli', { status: 'running', action: `${command} --version` });
|
|
317
|
-
version = await probeVersion();
|
|
318
|
-
if (!version.ok) {
|
|
319
|
-
patchStep('opencli', { status: 'failed', detail: version.detail, command: installCommand });
|
|
286
|
+
const diyStarted = options.probeDiy?.();
|
|
287
|
+
if (withConsole) {
|
|
288
|
+
patchStep('cli', { status: 'running', action: `${command} --version` });
|
|
289
|
+
if (diyStarted !== undefined)
|
|
290
|
+
patchStep('diy', { status: 'running' });
|
|
291
|
+
let version = await probeVersion();
|
|
292
|
+
if (!version.ok && !version.missing) {
|
|
293
|
+
patchStep('cli', { status: 'failed', detail: version.detail, action: undefined });
|
|
320
294
|
return set({
|
|
321
295
|
phase: 'failed',
|
|
322
296
|
error: version.detail,
|
|
323
297
|
failure: classifyFailure(version.detail),
|
|
324
|
-
guidance: '
|
|
298
|
+
guidance: 'shell',
|
|
325
299
|
});
|
|
326
300
|
}
|
|
301
|
+
if (!version.ok) {
|
|
302
|
+
if (toolchain?.npmMissing === true && installCommand.trim().startsWith('npm ')) {
|
|
303
|
+
patchStep('cli', { status: 'failed', detail: '没有 npm:装不了 opencli(只影响 opencli 安装)' });
|
|
304
|
+
return set({
|
|
305
|
+
phase: 'failed',
|
|
306
|
+
error: '没有 npm:装不了 opencli(只影响 opencli 安装)',
|
|
307
|
+
failure: 'missing',
|
|
308
|
+
guidance: 'install',
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
set({ phase: 'installing' });
|
|
312
|
+
patchStep('cli', { status: 'running', action: installCommand, command: installCommand });
|
|
313
|
+
const installed = await installOpencli();
|
|
314
|
+
if (!installed.ok) {
|
|
315
|
+
patchStep('cli', {
|
|
316
|
+
status: 'failed',
|
|
317
|
+
detail: installed.detail,
|
|
318
|
+
command: installCommand,
|
|
319
|
+
});
|
|
320
|
+
return set({
|
|
321
|
+
phase: 'failed',
|
|
322
|
+
error: installed.detail,
|
|
323
|
+
failure: classifyFailure(installed.detail),
|
|
324
|
+
guidance: 'install',
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
patchStep('cli', { status: 'running', action: `${command} --version` });
|
|
328
|
+
version = await probeVersion();
|
|
329
|
+
if (!version.ok) {
|
|
330
|
+
patchStep('cli', { status: 'failed', detail: version.detail, command: installCommand });
|
|
331
|
+
return set({
|
|
332
|
+
phase: 'failed',
|
|
333
|
+
error: version.detail,
|
|
334
|
+
failure: classifyFailure(version.detail),
|
|
335
|
+
guidance: 'path',
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
patchStep('cli', { status: 'ok', detail: version.detail, action: undefined });
|
|
327
340
|
}
|
|
328
|
-
patchStep('opencli', { status: 'ok', detail: version.detail, action: undefined });
|
|
329
341
|
patchStep('bridge', { status: 'running', action: `${command} doctor` });
|
|
330
|
-
const bridge = await probeBridge();
|
|
331
|
-
if (options.desktopBrowser !== undefined && bridge.ok) {
|
|
342
|
+
const bridge = withBridge ? await probeBridge() : { ok: true, detail: '', issues: [] };
|
|
343
|
+
if (withBridge && options.desktopBrowser !== undefined && bridge.ok) {
|
|
332
344
|
await options.desktopBrowser.observe().catch(() => undefined);
|
|
333
345
|
}
|
|
334
346
|
const healable = !bridge.ok && warmReads().length > 0 && canWarm(bridge);
|
|
@@ -340,7 +352,7 @@ export function createPreflight(options) {
|
|
|
340
352
|
...(bridge.command === undefined ? {} : { command: bridge.command }),
|
|
341
353
|
});
|
|
342
354
|
}
|
|
343
|
-
const settled = await warmSites(bridge);
|
|
355
|
+
const settled = withBridge ? await warmSites(bridge) : bridge;
|
|
344
356
|
const diyGap = await settleDiy(diyStarted);
|
|
345
357
|
logger?.warn?.(`[dsh-workbench] 环境体检:${current.steps.map((item) => `${item.id}=${item.status}`).join(' ')}`);
|
|
346
358
|
return set({
|
package/dist/probe-libs.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
-
import { libInstallCommand
|
|
3
|
+
import { libInstallCommand } from '@dsh-workbench/adapter-runtime';
|
|
4
|
+
import { needIdOf, npmSourceOf } from '@dsh-workbench/shared/host';
|
|
4
5
|
import { libDir } from '@dsh-workbench/adapter-runtime';
|
|
5
6
|
import { npmRegistryOf } from '@dsh-workbench/adapter-supply';
|
|
6
|
-
import { isNewerVersion
|
|
7
|
+
import { isNewerVersion } from '@dsh-workbench/adapter-profile';
|
|
8
|
+
import { latestVersion, resetReleaseCache } from './release-port.js';
|
|
7
9
|
import { checkVersionRange } from './version-range.js';
|
|
8
10
|
export function installedLibVersion(name) {
|
|
9
11
|
try {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { probeUnits } from './probe-units.js';
|
|
2
|
+
import { registerPreflight } from './preflight-route.js';
|
|
3
|
+
import { declaredPluginCommands } from '@dsh-workbench/adapter-supply';
|
|
4
|
+
export function createProbePort() {
|
|
5
|
+
return { probeUnits, registerPreflight, declaredPluginCommands };
|
|
6
|
+
}
|
package/dist/probe-units.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { commandNamesMatch } from './command-name.js';
|
|
2
|
+
import { OPENCLI_TIMEOUT_MS, PROBE_TTL_MS, buildSupplyIndex, NEED_KIND_SPECS, needIdOf, npmSourceOf, parseJsonLoose, quoteShellArg, runShell, } from '@dsh-workbench/shared/host';
|
|
2
3
|
import { npmRegistryOf } from '@dsh-workbench/adapter-supply';
|
|
3
|
-
import { probeRelease } from '
|
|
4
|
+
import { probeRelease } from './release-port.js';
|
|
4
5
|
import { createTimedMemo } from './probe-cache.js';
|
|
5
6
|
import { probeLibs } from './probe-libs.js';
|
|
6
7
|
import { aggregate, binStateOf, envStateOf, extensionStateOf } from './probe-verdict.js';
|
|
@@ -95,6 +96,7 @@ async function loadCapabilities(options) {
|
|
|
95
96
|
const { shell, runtimeCommands, units, force } = options;
|
|
96
97
|
const index = buildSupplyIndex(units.map((unit) => ({ id: unit.unit, needs: unit.needs })), {
|
|
97
98
|
env: process.env,
|
|
99
|
+
packagePrefix: 'opencli-plugin-',
|
|
98
100
|
});
|
|
99
101
|
const binNames = [
|
|
100
102
|
...new Set(units.flatMap((unit) => unit.needs.filter((need) => need.kind === 'bin').map((need) => need.name.trim()).filter((name) => name !== ''))),
|
package/dist/probe-verdict.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { binInstallCommand
|
|
1
|
+
import { binInstallCommand } from '@dsh-workbench/adapter-runtime';
|
|
2
|
+
import { needIdOf, quoteShellArg } from '@dsh-workbench/shared/host';
|
|
2
3
|
import { resolvePluginSource } from '@dsh-workbench/adapter-supply';
|
|
3
4
|
import { isNewerVersion } from '@dsh-workbench/adapter-profile';
|
|
4
5
|
import { currentHostOs } from './platform.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const latestVersion: (options: {
|
|
2
|
+
readonly shell: import("@dsh-workbench/shared").DshShell;
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly registry: string;
|
|
5
|
+
readonly force?: boolean;
|
|
6
|
+
}) => Promise<string | undefined>;
|
|
7
|
+
export declare const missingReleaseParts: (options: {
|
|
8
|
+
readonly shell: import("@dsh-workbench/shared").DshShell;
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly registry: string;
|
|
11
|
+
readonly version: string;
|
|
12
|
+
readonly force?: boolean;
|
|
13
|
+
}) => Promise<readonly string[]>;
|
|
14
|
+
export declare const probeRelease: (options: {
|
|
15
|
+
readonly shell: import("@dsh-workbench/shared").DshShell;
|
|
16
|
+
readonly package: string;
|
|
17
|
+
readonly registry?: string | undefined;
|
|
18
|
+
readonly force?: boolean;
|
|
19
|
+
}) => Promise<import("@dsh-workbench/shared").PluginRelease | undefined>;
|
|
20
|
+
export declare const resetReleaseCache: () => void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createReleasePort } from '@dsh-workbench/adapter-profile';
|
|
2
|
+
import { npmCacheDir, vendorPrefix } from '@dsh-workbench/adapter-runtime';
|
|
3
|
+
const port = createReleasePort({ cacheDir: npmCacheDir(), prefix: vendorPrefix() });
|
|
4
|
+
export const latestVersion = port.latestVersion;
|
|
5
|
+
export const missingReleaseParts = port.missingReleaseParts;
|
|
6
|
+
export const probeRelease = port.probeRelease;
|
|
7
|
+
export const resetReleaseCache = port.reset;
|
package/dist/runtime-seed.d.ts
CHANGED
|
@@ -24,9 +24,10 @@ export declare function runtimeSeedPaths(root: string, platform?: NodeJS.Platfor
|
|
|
24
24
|
export declare function runtimeSeedRootOf(ctx: DshHostContext): string | null;
|
|
25
25
|
export declare function coversWritableRoot(workspaceRoot: string, root: string): boolean;
|
|
26
26
|
export declare function warnUnwritableRoot(ctx: DshHostContext): void;
|
|
27
|
-
export declare function
|
|
27
|
+
export declare function wrapperRootOf(fallbackRoot: string): string;
|
|
28
28
|
export declare function isInstalledCopy(packageRoot: string): boolean;
|
|
29
29
|
export declare function opencliWrapperScript(packageRoot: string, home: string, platform?: NodeJS.Platform): string;
|
|
30
|
+
export declare const runtimeWrapperScript: typeof opencliWrapperScript;
|
|
30
31
|
export interface SeedCommand {
|
|
31
32
|
readonly file: string;
|
|
32
33
|
readonly args: readonly string[];
|
package/dist/runtime-seed.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { execa } from 'execa';
|
|
2
|
+
import { toolchainManifestOf } from '@dsh-workbench/adapter-runtime';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
2
4
|
import writeFileAtomic from 'write-file-atomic';
|
|
3
5
|
import { chmodSync, closeSync, mkdirSync, openSync, readFileSync, rmSync, } from 'node:fs';
|
|
4
6
|
import { delimiter, dirname, join, sep } from 'node:path';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
7
|
import { quoteShellArg } from '@dsh-workbench/shared/host';
|
|
7
8
|
import { ensureToolchain, localNpmCache, provisionLocalPnpmSync } from './toolchain.js';
|
|
8
9
|
export function opencliBinName(platform = process.platform) {
|
|
@@ -51,19 +52,25 @@ export function warnUnwritableRoot(ctx) {
|
|
|
51
52
|
return;
|
|
52
53
|
ctx.logger?.warn?.(`[dsh-workbench] 可写根 ${workspaceRoot} 盖不住 ${root}:市场装插件、自举命令可能被沙箱挡(把 profile/sandbox.patch.yml 那一行写进这个 profile 的 cordis.patch.yml 再重启)`);
|
|
53
54
|
}
|
|
54
|
-
export function
|
|
55
|
-
|
|
55
|
+
export function wrapperRootOf(fallbackRoot) {
|
|
56
|
+
try {
|
|
57
|
+
return dirname(createRequire(import.meta.url).resolve('@dsh-workbench/adapter-runtime/package.json'));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return fallbackRoot;
|
|
61
|
+
}
|
|
56
62
|
}
|
|
57
63
|
export function isInstalledCopy(packageRoot) {
|
|
58
64
|
return packageRoot.split(sep).includes('node_modules');
|
|
59
65
|
}
|
|
60
66
|
export function opencliWrapperScript(packageRoot, home, platform = process.platform) {
|
|
61
|
-
const script = join(packageRoot, 'bin', 'opencli-isolated.mjs');
|
|
67
|
+
const script = join(wrapperRootOf(packageRoot), 'bin', 'opencli-isolated.mjs');
|
|
62
68
|
if (platform === 'win32') {
|
|
63
69
|
return `@echo off\r\nset "DSH_HOME=${home}"\r\nnode "${script}" %*\r\n`;
|
|
64
70
|
}
|
|
65
71
|
return `#!/bin/sh\nexport DSH_HOME=${quoteShellArg(home)}\nexec node ${quoteShellArg(script)} "$@"\n`;
|
|
66
72
|
}
|
|
73
|
+
export const runtimeWrapperScript = opencliWrapperScript;
|
|
67
74
|
export function workshopSeedPlan(packageRoot, home, root, platform = process.platform) {
|
|
68
75
|
const script = join(packageRoot, 'scripts', 'seed-workshop.sh');
|
|
69
76
|
const env = { DSH_HOME: home, DSH_WB_SHELL_ROOT: packageRoot };
|
|
@@ -155,6 +162,13 @@ export function seedRuntimeFiles(options) {
|
|
|
155
162
|
for (const dir of [paths.entryDir, paths.opencliBinDir, paths.opencliHome, paths.workshopPackages]) {
|
|
156
163
|
mkdirSync(dir, { recursive: true });
|
|
157
164
|
}
|
|
165
|
+
const manifest = join(paths.opencliRoot, 'toolchain', 'package.json');
|
|
166
|
+
mkdirSync(dirname(manifest), { recursive: true });
|
|
167
|
+
if (readText(manifest) !== toolchainManifestOf()) {
|
|
168
|
+
writeFileAtomic.sync(manifest, toolchainManifestOf(), 'utf8');
|
|
169
|
+
done.push(manifest);
|
|
170
|
+
}
|
|
171
|
+
rmSync(join(paths.opencliRoot, 'toolchain', 'pnpm-workspace.yaml'), { force: true });
|
|
158
172
|
const wanted = opencliWrapperScript(options.packageRoot, options.home, platform);
|
|
159
173
|
if (readText(paths.opencliBin) !== wanted) {
|
|
160
174
|
rmSync(paths.opencliBin, { force: true });
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { cliCatalogPath, ensureLibsBinOnPath, ensureLibsOpencliPeer, isolatedHome, libInstallCommand, libUninstallCommand, vendorPluginsDir } from '@dsh-workbench/adapter-runtime';
|
|
2
|
+
import { isolatedRoot } from '@dsh-workbench/adapter-runtime';
|
|
3
|
+
import { createRegistryNotebook, isNewerVersion } from '@dsh-workbench/adapter-profile';
|
|
4
|
+
import { latestVersion, missingReleaseParts, probeRelease } from './release-port.js';
|
|
5
|
+
import { opencliInstallCommand } from './install.js';
|
|
6
|
+
import { startSelfUpdate } from './self-update.js';
|
|
7
|
+
import { declarationGaps, declarationRefusalOf, moduleDeclarationOf, packageRouteOf, pathDeclarationOf, pluginInstallPlan, profileDirOf, profileModules, readInstalledModule, readProfilePackage, registryDeclarationOf, resolvePluginSource, splitNpmSpec, } from '@dsh-workbench/adapter-supply';
|
|
8
|
+
import { readBundleManager, refusalReason } from '@dsh-workbench/shared/host';
|
|
9
|
+
import { OPENCLI_MANIFEST_FILE } from '@dsh-workbench/adapter-runtime';
|
|
10
|
+
export function createSupplyPort() {
|
|
11
|
+
const port = {
|
|
12
|
+
isolatedRoot,
|
|
13
|
+
isolatedHome,
|
|
14
|
+
pluginPackagePrefix: () => 'opencli-plugin-',
|
|
15
|
+
pluginManifestFile: () => OPENCLI_MANIFEST_FILE,
|
|
16
|
+
cliCatalogPath,
|
|
17
|
+
vendorPluginsDir,
|
|
18
|
+
runtimeInstallCommand: opencliInstallCommand,
|
|
19
|
+
afterLibInstall() {
|
|
20
|
+
ensureLibsOpencliPeer();
|
|
21
|
+
ensureLibsBinOnPath();
|
|
22
|
+
},
|
|
23
|
+
profileDirOf,
|
|
24
|
+
profileModules,
|
|
25
|
+
readBundleManager,
|
|
26
|
+
refusalReason,
|
|
27
|
+
readInstalledModule,
|
|
28
|
+
readProfilePackage,
|
|
29
|
+
createRegistryNotebook,
|
|
30
|
+
declarationGaps,
|
|
31
|
+
moduleDeclarationOf,
|
|
32
|
+
registryDeclarationOf,
|
|
33
|
+
pathDeclarationOf,
|
|
34
|
+
declarationRefusalOf,
|
|
35
|
+
latestVersion,
|
|
36
|
+
missingReleaseParts,
|
|
37
|
+
isNewerVersion,
|
|
38
|
+
pluginInstallPlan,
|
|
39
|
+
packageRouteOf,
|
|
40
|
+
probeRelease,
|
|
41
|
+
resolvePluginSource,
|
|
42
|
+
splitNpmSpec,
|
|
43
|
+
libInstallCommand,
|
|
44
|
+
libUninstallCommand,
|
|
45
|
+
startSelfUpdate,
|
|
46
|
+
};
|
|
47
|
+
return { ...port, env: port, modules: port };
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-workbench/adapter-probe",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"description": "Workbench adapter-probe adapter.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"execa": "^10.2.0",
|
|
17
17
|
"proper-lockfile": "^4.1.2",
|
|
18
18
|
"write-file-atomic": "^8.0.0",
|
|
19
|
-
"@dsh-workbench/adapter-
|
|
20
|
-
"@dsh-workbench/adapter-supply": "1.1.
|
|
21
|
-
"@dsh-workbench/shared": "1.1.
|
|
22
|
-
"@dsh-workbench/adapter-
|
|
19
|
+
"@dsh-workbench/adapter-runtime": "1.1.9",
|
|
20
|
+
"@dsh-workbench/adapter-supply": "1.1.9",
|
|
21
|
+
"@dsh-workbench/shared": "1.1.9",
|
|
22
|
+
"@dsh-workbench/adapter-profile": "1.1.9"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/node": "^24.19.0",
|