@dsh-plugin/dsh-loader 1.0.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/README.md +226 -0
- package/README.zh-CN.md +202 -0
- package/bin/dshloader.mjs +42 -0
- package/cordis.patch.yml +8 -0
- package/package.json +59 -0
- package/src/adapters/dsh-1-x.js +236 -0
- package/src/adapters/index.js +59 -0
- package/src/api.js +56 -0
- package/src/client.js +330 -0
- package/src/index.js +105 -0
- package/src/registry.js +242 -0
- package/src/services/services.js +28 -0
- package/src/services/settings.js +174 -0
- package/src/services/web.js +71 -0
- package/src/setup.mjs +125 -0
- package/src/stable/agent.d.ts +1 -0
- package/src/stable/agent.js +2 -0
- package/src/stable/llm.d.ts +1 -0
- package/src/stable/llm.js +2 -0
- package/src/stable/runtime.d.ts +1 -0
- package/src/stable/runtime.js +5 -0
- package/src/stable/schema-form.d.ts +1 -0
- package/src/stable/schema-form.js +2 -0
- package/src/stable/settings.d.ts +1 -0
- package/src/stable/settings.js +2 -0
- package/src/stable/tools.d.ts +1 -0
- package/src/stable/tools.js +5 -0
- package/src/stable/ui-primitives.d.ts +4 -0
- package/src/stable/ui-primitives.js +6 -0
- package/src/stable/ui-settings.d.ts +6 -0
- package/src/stable/ui-settings.js +4 -0
- package/src/stable/ui-slots.d.ts +1 -0
- package/src/stable/ui-slots.js +2 -0
- package/src/stable/web-react.d.ts +1 -0
- package/src/stable/web-react.js +2 -0
- package/src/version.js +5 -0
package/src/setup.mjs
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// One-shot profile injection script (design.md §3.6 / §6 / M6).
|
|
2
|
+
//
|
|
3
|
+
// `dshloader setup <profile>`:
|
|
4
|
+
// - adds `@dsh-plugin/dsh-loader` to the profile package.json dependencies
|
|
5
|
+
// (if missing);
|
|
6
|
+
// - appends the dshloader `insert` entry to cordis.patch.yml (if missing);
|
|
7
|
+
// - does NOT reorder the insert list — cordis is reactive DI, so position
|
|
8
|
+
// does not affect whether service aliases / module redirects take effect
|
|
9
|
+
// (design.md §1.2 / §6.2).
|
|
10
|
+
//
|
|
11
|
+
// `dshloader dump-config <profile>`: best-effort validation that runs
|
|
12
|
+
// `dsh --profile <name> --dump-config` when the dsh CLI is available.
|
|
13
|
+
//
|
|
14
|
+
// `dshloader info [profile]`: prints dshloader version, detected dsh version,
|
|
15
|
+
// selected adapter, and registered aliases (AC-OB-03, P2 — minimal).
|
|
16
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
17
|
+
import { join, resolve } from 'node:path';
|
|
18
|
+
import { spawnSync } from 'node:child_process';
|
|
19
|
+
import { LOADER_VERSION, LOG_PREFIX } from './version.js';
|
|
20
|
+
import { detectDshVersion, AdapterRegistry, UnsupportedDshVersionError } from './registry.js';
|
|
21
|
+
import { registerHostAdapters } from './adapters/index.js';
|
|
22
|
+
|
|
23
|
+
const LOADER_PKG = '@dsh-plugin/dsh-loader';
|
|
24
|
+
const PATCH_ENTRY = `- id: dsh-loader\n name: '${LOADER_PKG}'`;
|
|
25
|
+
|
|
26
|
+
export function dshHome() {
|
|
27
|
+
const env = process.env.DSH_HOME?.trim();
|
|
28
|
+
return env ? resolve(env) : join(process.env.HOME ?? '~', '.dsh');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function profileDir(profileName) {
|
|
32
|
+
return join(dshHome(), 'profiles', profileName);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function readJson(path) {
|
|
36
|
+
try {
|
|
37
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
38
|
+
} catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function writeJson(path, data) {
|
|
44
|
+
writeFileSync(path, JSON.stringify(data, undefined, 2) + '\n');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Ensure dshloader is listed in the profile package.json dependencies. */
|
|
48
|
+
export function injectDependency(pkgPath) {
|
|
49
|
+
const manifest = readJson(pkgPath) ?? { name: '', dependencies: {} };
|
|
50
|
+
manifest.dependencies = manifest.dependencies ?? {};
|
|
51
|
+
if (manifest.dependencies[LOADER_PKG] === undefined) {
|
|
52
|
+
manifest.dependencies[LOADER_PKG] = '^' + LOADER_VERSION;
|
|
53
|
+
writeJson(pkgPath, manifest);
|
|
54
|
+
return { added: true, manifest };
|
|
55
|
+
}
|
|
56
|
+
return { added: false, manifest };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Ensure the dshloader insert entry exists in cordis.patch.yml (no reorder). */
|
|
60
|
+
export function injectPatch(patchPath) {
|
|
61
|
+
let text = '';
|
|
62
|
+
try {
|
|
63
|
+
text = readFileSync(patchPath, 'utf8');
|
|
64
|
+
} catch {
|
|
65
|
+
text = '';
|
|
66
|
+
}
|
|
67
|
+
if (text.includes("id: dsh-loader")) {
|
|
68
|
+
return { added: false, text };
|
|
69
|
+
}
|
|
70
|
+
const insertion = `- insert:\n ${PATCH_ENTRY}\n`;
|
|
71
|
+
const next = text.length === 0 ? insertion : text.endsWith('\n') ? text + insertion : text + '\n' + insertion;
|
|
72
|
+
writeFileSync(patchPath, next);
|
|
73
|
+
return { added: true, text: next };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Run `dshloader setup <profile>`.
|
|
78
|
+
* @param {string} profileName
|
|
79
|
+
* @returns {{ profileDir: string, dependencyAdded: boolean, patchAdded: boolean }}
|
|
80
|
+
*/
|
|
81
|
+
export function setupProfile(profileName) {
|
|
82
|
+
const dir = profileDir(profileName);
|
|
83
|
+
if (!existsSync(dir)) {
|
|
84
|
+
throw new Error(`${LOG_PREFIX} profile directory not found: ${dir}`);
|
|
85
|
+
}
|
|
86
|
+
const pkgPath = join(dir, 'package.json');
|
|
87
|
+
const patchPath = join(dir, 'cordis.patch.yml');
|
|
88
|
+
const dep = injectDependency(pkgPath);
|
|
89
|
+
const patch = injectPatch(patchPath);
|
|
90
|
+
console.log(`${LOG_PREFIX} setup ${profileName}: dependency ${dep.added ? 'added' : 'already present'}, patch ${patch.added ? 'appended' : 'already present'}`);
|
|
91
|
+
console.log(`${LOG_PREFIX} note: insert position is irrelevant — cordis reactive DI resolves aliases regardless of order (design.md §6.2)`);
|
|
92
|
+
return { profileDir: dir, dependencyAdded: dep.added, patchAdded: patch.added };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Best-effort dump-config validation. Returns { ok, output } (never throws). */
|
|
96
|
+
export function dumpConfig(profileName) {
|
|
97
|
+
const dir = profileDir(profileName);
|
|
98
|
+
if (!existsSync(dir)) {
|
|
99
|
+
return { ok: false, output: `${LOG_PREFIX} profile directory not found: ${dir}` };
|
|
100
|
+
}
|
|
101
|
+
const result = spawnSync('dsh', ['--profile', profileName, '--dump-config'], {
|
|
102
|
+
encoding: 'utf8',
|
|
103
|
+
timeout: 60_000,
|
|
104
|
+
});
|
|
105
|
+
const output = (result.stdout ?? '') + (result.stderr ?? '');
|
|
106
|
+
return { ok: result.status === 0, output };
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** Print dshloader status for a profile (AC-OB-03, minimal). */
|
|
110
|
+
export function info(profileName) {
|
|
111
|
+
console.log(`${LOG_PREFIX} version ${LOADER_VERSION}`);
|
|
112
|
+
const dir = profileName ? profileDir(profileName) : undefined;
|
|
113
|
+
const dshVersion = detectDshVersion(dir ? { profileDir: dir } : {});
|
|
114
|
+
console.log(`${LOG_PREFIX} detected dsh version: ${dshVersion ?? '<unknown>'}`);
|
|
115
|
+
if (dshVersion) {
|
|
116
|
+
try {
|
|
117
|
+
const reg = registerHostAdapters(new AdapterRegistry());
|
|
118
|
+
const { factory, mode } = reg.select(dshVersion);
|
|
119
|
+
console.log(`${LOG_PREFIX} selected adapter: ${factory.name} (supports ${factory.supports}, mode ${mode})`);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.log(`${LOG_PREFIX} adapter selection: ${error.message}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return { loaderVersion: LOADER_VERSION, dshVersion };
|
|
125
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@deepseek-ai/dsh-agent';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@deepseek-ai/dsh-llm';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@deepseek-ai/dsh-client-runtime/client';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@deepseek-ai/dsh-client-schema-form';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@deepseek-ai/dsh-settings';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@deepseek-ai/dsh-tools';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Stable re-export: @dsh-plugin/dsh-loader/ui-primitives
|
|
2
|
+
//
|
|
3
|
+
// Plugins import UI primitives from this subpath instead of directly
|
|
4
|
+
// from @deepseek-ai/dsh-client-ui-primitives. When dsh renames the
|
|
5
|
+
// package, only this file (and the adapter's packageAliases) change.
|
|
6
|
+
export * from '@deepseek-ai/dsh-client-ui-primitives';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Stable subpath types: @dsh-plugin/dsh-loader/ui-settings
|
|
2
|
+
// Side-effect import triggers the dsh-client-ui-settings/client SlotMap
|
|
3
|
+
// merge (adds 'settings.section') so PropsRuntime<'settings.section'>
|
|
4
|
+
// stays typed. Re-export keeps values/types reachable.
|
|
5
|
+
import '@deepseek-ai/dsh-client-ui-settings/client';
|
|
6
|
+
export * from '@deepseek-ai/dsh-client-ui-settings/client';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@deepseek-ai/dsh-client-ui-slots';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@deepseek-ai/dsh-client-web-react';
|