@zhin.js/scaffold-wizard 0.2.6 → 1.1.1
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/lib/adapter-configurers.d.ts.map +1 -1
- package/lib/adapter-configurers.js +2 -1
- package/lib/adapter-configurers.js.map +1 -1
- package/lib/adapter.js +1 -1
- package/lib/adapter.js.map +1 -1
- package/lib/ai.d.ts +1 -7
- package/lib/ai.d.ts.map +1 -1
- package/lib/ai.js +0 -63
- package/lib/ai.js.map +1 -1
- package/lib/apply.d.ts +4 -4
- package/lib/apply.d.ts.map +1 -1
- package/lib/apply.js +6 -23
- package/lib/apply.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -3
- package/lib/index.js.map +1 -1
- package/lib/optional-peers.d.ts.map +1 -1
- package/lib/optional-peers.js +5 -16
- package/lib/optional-peers.js.map +1 -1
- package/lib/project-config-plan.d.ts +2 -1
- package/lib/project-config-plan.d.ts.map +1 -1
- package/lib/project-config-plan.js +29 -83
- package/lib/project-config-plan.js.map +1 -1
- package/lib/project-deps.d.ts +1 -1
- package/lib/project-deps.d.ts.map +1 -1
- package/lib/project-deps.js +5 -7
- package/lib/project-deps.js.map +1 -1
- package/lib/types.d.ts +1 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/zhin-stack-deps.d.ts +1 -0
- package/lib/zhin-stack-deps.d.ts.map +1 -1
- package/lib/zhin-stack-deps.js +32 -20
- package/lib/zhin-stack-deps.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter-configurers.ts +2 -1
- package/src/adapter.ts +1 -1
- package/src/ai.ts +1 -70
- package/src/apply.ts +9 -22
- package/src/index.ts +2 -3
- package/src/optional-peers.ts +4 -14
- package/src/project-config-plan.ts +35 -79
- package/src/project-deps.ts +5 -6
- package/src/types.ts +2 -2
- package/src/zhin-stack-deps.ts +31 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zhin-stack-deps.d.ts","sourceRoot":"","sources":["../src/zhin-stack-deps.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsF,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE7I;;;GAGG;AACH,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"zhin-stack-deps.d.ts","sourceRoot":"","sources":["../src/zhin-stack-deps.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsF,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE7I;;;GAGG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CtB,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,mBAAmB,CAAC;AA0DhE,4DAA4D;AAC5D,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,qCAAqC,CAAC;AAEnE,gCAAgC;AAChC,wBAAgB,sBAAsB,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAIpF;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAKrE;AAED,oDAAoD;AACpD,wBAAgB,oCAAoC,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAgB5G;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,kCAAkC,CAChD,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,MAAM,EAAE,CAYV;AAED,wBAAgB,uCAAuC,CACrD,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,wBAAwB,EAAE,CA0B5B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,qBAAqB,EAAE,wBAAwB,EAAE,CAAC;IAClD,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,kBAAkB,GAAG,MAAM,EAAE,CASnF;AAED,wBAAgB,6BAA6B,CAC3C,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,GAAG,CAAC,EAAE,eAAe,GACpB,kBAAkB,CAkBpB;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAItG"}
|
package/lib/zhin-stack-deps.js
CHANGED
|
@@ -22,6 +22,7 @@ export const ZHIN_STACK_VERSIONS = {
|
|
|
22
22
|
'@zhin.js/layout': 'latest',
|
|
23
23
|
'@zhin.js/page': 'latest',
|
|
24
24
|
'@zhin.js/prompt-section': 'latest',
|
|
25
|
+
'@zhin.js/skill': 'latest',
|
|
25
26
|
'@zhin.js/tool': 'latest',
|
|
26
27
|
'@zhin.js/client': 'latest',
|
|
27
28
|
'@zhin.js/contract': 'latest',
|
|
@@ -58,6 +59,12 @@ function parseMajor(versionSpec) {
|
|
|
58
59
|
const match = versionSpec.trim().replace(/^[\^~>=<]+/, '').match(/^(\d+)/);
|
|
59
60
|
return match ? Number(match[1]) : undefined;
|
|
60
61
|
}
|
|
62
|
+
function parseMajorMinor(versionSpec) {
|
|
63
|
+
if (!versionSpec?.trim())
|
|
64
|
+
return undefined;
|
|
65
|
+
const match = versionSpec.trim().replace(/^[\^~>=<]+/, '').match(/^(\d+)\.(\d+)/);
|
|
66
|
+
return match ? [Number(match[1]), Number(match[2])] : undefined;
|
|
67
|
+
}
|
|
61
68
|
function getDeclaredPackageVersion(pkg, name) {
|
|
62
69
|
return pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];
|
|
63
70
|
}
|
|
@@ -74,25 +81,32 @@ function readInstalledMajor(cwd, packageName) {
|
|
|
74
81
|
return undefined;
|
|
75
82
|
}
|
|
76
83
|
}
|
|
84
|
+
function readInstalledVersion(cwd, packageName) {
|
|
85
|
+
const pkgJson = path.join(cwd, 'package.json');
|
|
86
|
+
if (!fs.existsSync(pkgJson))
|
|
87
|
+
return undefined;
|
|
88
|
+
try {
|
|
89
|
+
const req = createRequire(pkgJson);
|
|
90
|
+
const installed = req(`${packageName}/package.json`);
|
|
91
|
+
return installed.version;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
77
97
|
function resolvePackageMajor(cwd, pkg, packageName) {
|
|
78
98
|
return readInstalledMajor(cwd, packageName) ?? parseMajor(getDeclaredPackageVersion(pkg, packageName));
|
|
79
99
|
}
|
|
100
|
+
function supportsSplitAiInstallation(versionSpec) {
|
|
101
|
+
const version = parseMajorMinor(versionSpec);
|
|
102
|
+
if (!version)
|
|
103
|
+
return undefined;
|
|
104
|
+
const [major, minor] = version;
|
|
105
|
+
return major >= 4 || (major === 1 && minor >= 1);
|
|
106
|
+
}
|
|
80
107
|
function resolveStackVersion(packageName) {
|
|
81
108
|
return ZHIN_STACK_VERSIONS[packageName] ?? 'latest';
|
|
82
109
|
}
|
|
83
|
-
function collectZhinPluginsFromConfig(config) {
|
|
84
|
-
// legacy 数组形式:条目即包名
|
|
85
|
-
if (Array.isArray(config.plugins)) {
|
|
86
|
-
const plugins = config.plugins.filter((p) => typeof p === 'string');
|
|
87
|
-
return [...new Set(plugins.filter((p) => p.startsWith('@zhin.js/')))];
|
|
88
|
-
}
|
|
89
|
-
// 新 runtime:plugins 为 instanceKey 映射,包名在 package.json zhin.plugins 清单中,
|
|
90
|
-
// 无法从配置推导;仅收集直接以包名出现的键(防御性)
|
|
91
|
-
if (config.plugins && typeof config.plugins === 'object') {
|
|
92
|
-
return Object.keys(config.plugins).filter((key) => key.startsWith('@zhin.js/'));
|
|
93
|
-
}
|
|
94
|
-
return [];
|
|
95
|
-
}
|
|
96
110
|
/** create-zhin / minimal-bot 默认 Host 端口(避免与常见 8086 占用冲突) */
|
|
97
111
|
export const DEFAULT_CREATE_BOT_HTTP_PORT = 8068;
|
|
98
112
|
/** create-zhin 生成项目的 .npmrc(避免全局 strict-peer-dependencies 阻断 AI 栈安装) */
|
|
@@ -110,6 +124,7 @@ export function getCreateBotPnpmConfig(_aiEnabled) {
|
|
|
110
124
|
export function getCreateBotBaseDependencies() {
|
|
111
125
|
return {
|
|
112
126
|
'zhin.js': ZHIN_STACK_VERSIONS['zhin.js'],
|
|
127
|
+
'@zhin.js/skill': ZHIN_STACK_VERSIONS['@zhin.js/skill'],
|
|
113
128
|
};
|
|
114
129
|
}
|
|
115
130
|
/** 根据 zhin.config 推导应声明的 @zhin.js/* / zhin.js 依赖 */
|
|
@@ -117,9 +132,6 @@ export function getRequiredZhinDependenciesForConfig(config) {
|
|
|
117
132
|
const deps = {
|
|
118
133
|
'zhin.js': ZHIN_STACK_VERSIONS['zhin.js'],
|
|
119
134
|
};
|
|
120
|
-
for (const plugin of collectZhinPluginsFromConfig(config)) {
|
|
121
|
-
deps[plugin] = resolveStackVersion(plugin);
|
|
122
|
-
}
|
|
123
135
|
const database = config.database;
|
|
124
136
|
if (database && typeof database === 'object' && !Array.isArray(database)) {
|
|
125
137
|
deps['@zhin.js/database'] = ZHIN_STACK_VERSIONS['@zhin.js/database'];
|
|
@@ -147,13 +159,13 @@ export function findOutdatedZhinStackInPackageJson(pkg, required) {
|
|
|
147
159
|
}
|
|
148
160
|
export function findInstalledZhinStackIncompatibilities(cwd, pkg, config) {
|
|
149
161
|
const issues = [];
|
|
150
|
-
const
|
|
162
|
+
const zhinVersion = readInstalledVersion(cwd, 'zhin.js') ?? getDeclaredPackageVersion(pkg, 'zhin.js');
|
|
151
163
|
const agentDeclared = getDeclaredPackageVersion(pkg, '@zhin.js/agent');
|
|
152
164
|
const aiEnabled = isAiEnabledInConfig(config);
|
|
153
|
-
if (
|
|
165
|
+
if (supportsSplitAiInstallation(zhinVersion) === false && (aiEnabled || agentDeclared)) {
|
|
154
166
|
issues.push({
|
|
155
167
|
package: 'zhin.js',
|
|
156
|
-
reason: 'zhin.js
|
|
168
|
+
reason: 'zhin.js 1.1.x 稳定线才支持当前 @zhin.js/agent 与 AI 安装分层,请升级 zhin.js',
|
|
157
169
|
});
|
|
158
170
|
}
|
|
159
171
|
if (aiEnabled && !agentDeclared) {
|
|
@@ -163,7 +175,7 @@ export function findInstalledZhinStackIncompatibilities(cwd, pkg, config) {
|
|
|
163
175
|
if (agentMajor != null && agentMajor < 1 && aiEnabled) {
|
|
164
176
|
issues.push({
|
|
165
177
|
package: '@zhin.js/agent',
|
|
166
|
-
reason: '@zhin.js/agent 1.x 与 zhin.js
|
|
178
|
+
reason: '@zhin.js/agent 1.x 与 zhin.js 1.1.x 稳定线 / AI SDK 7 配套,请升级 @zhin.js/agent',
|
|
167
179
|
});
|
|
168
180
|
}
|
|
169
181
|
return issues;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zhin-stack-deps.js","sourceRoot":"","sources":["../src/zhin-stack-deps.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"zhin-stack-deps.js","sourceRoot":"","sources":["../src/zhin-stack-deps.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zhin.js/scaffold-wizard",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Shared interactive scaffold wizard for create-zhin-app and @zhin.js/cli",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./lib/index.js",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"fs-extra": "^11.4.0",
|
|
22
22
|
"inquirer": "^14.0.2",
|
|
23
23
|
"qrcode": "^1.5.4",
|
|
24
|
-
"
|
|
25
|
-
"
|
|
24
|
+
"yaml": "^2.9.0",
|
|
25
|
+
"@zhin.js/plugin-runtime": "1.1.10"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -371,7 +371,7 @@ export async function configureQQBot(ctx: EndpointConfigureContext): Promise<Rec
|
|
|
371
371
|
{
|
|
372
372
|
type: 'select',
|
|
373
373
|
name: 'botKind',
|
|
374
|
-
message: ' 公域 / 私域(决定频道消息 intents
|
|
374
|
+
message: ' 公域 / 私域(决定频道消息 intents;群聊与群成员事件两边都有):',
|
|
375
375
|
choices: [
|
|
376
376
|
{
|
|
377
377
|
name: 'public — 公域(频道仅 @;+ 群聊/私聊)',
|
|
@@ -388,6 +388,7 @@ export async function configureQQBot(ctx: EndpointConfigureContext): Promise<Rec
|
|
|
388
388
|
|
|
389
389
|
const sharedIntents = [
|
|
390
390
|
'GROUP_AND_C2C_EVENT',
|
|
391
|
+
'GROUP_MEMBER',
|
|
391
392
|
'GUILDS',
|
|
392
393
|
'GUILD_MEMBERS',
|
|
393
394
|
'DIRECT_MESSAGE',
|
package/src/adapter.ts
CHANGED
|
@@ -413,7 +413,7 @@ export async function configureAdapters(): Promise<AdapterSetupResult> {
|
|
|
413
413
|
package: adapterDef.package,
|
|
414
414
|
instanceKey: 'sandbox',
|
|
415
415
|
config: {
|
|
416
|
-
endpoints: [{
|
|
416
|
+
endpoints: [{ id: 'sandbox-bot', owner: 'sandbox-user' }],
|
|
417
417
|
},
|
|
418
418
|
});
|
|
419
419
|
continue;
|
package/src/ai.ts
CHANGED
|
@@ -5,8 +5,6 @@ import { formatEnvValue } from './env.js';
|
|
|
5
5
|
export interface AISetupConfig {
|
|
6
6
|
enabled: boolean;
|
|
7
7
|
agentProvider?: string;
|
|
8
|
-
/** @deprecated Use agentProvider. Kept for one compatibility cycle. */
|
|
9
|
-
defaultProvider?: string;
|
|
10
8
|
providers?: Record<string, {
|
|
11
9
|
sdk?: string;
|
|
12
10
|
apiKey?: string;
|
|
@@ -134,9 +132,8 @@ function defaultModelForProvider(driver: string): string {
|
|
|
134
132
|
return entry?.defaultModel ?? '';
|
|
135
133
|
}
|
|
136
134
|
|
|
137
|
-
export function resolveAISetupAgentProvider(config: Pick<AISetupConfig, 'agentProvider' | '
|
|
135
|
+
export function resolveAISetupAgentProvider(config: Pick<AISetupConfig, 'agentProvider' | 'providers'>): string {
|
|
138
136
|
return config.agentProvider
|
|
139
|
-
?? config.defaultProvider
|
|
140
137
|
?? Object.keys(config.providers ?? {})[0]
|
|
141
138
|
?? 'openai';
|
|
142
139
|
}
|
|
@@ -529,72 +526,6 @@ export function generateAIConfigYaml(config: AISetupConfig): string {
|
|
|
529
526
|
return lines.join('\n');
|
|
530
527
|
}
|
|
531
528
|
|
|
532
|
-
/**
|
|
533
|
-
* 生成 TOML 格式的 AI 配置段
|
|
534
|
-
*/
|
|
535
|
-
export function generateAIConfigToml(config: AISetupConfig): string {
|
|
536
|
-
if (!config.enabled) return '';
|
|
537
|
-
|
|
538
|
-
const lines: string[] = [
|
|
539
|
-
'',
|
|
540
|
-
'[ai]',
|
|
541
|
-
`memoryMcp = ${config.memoryMcp ?? false}`,
|
|
542
|
-
];
|
|
543
|
-
|
|
544
|
-
if (config.providers) {
|
|
545
|
-
for (const [name, providerConfig] of Object.entries(config.providers)) {
|
|
546
|
-
lines.push('', `[ai.providers.${name}]`);
|
|
547
|
-
lines.push(`sdk = "${providerConfig.sdk ?? providerSdkFor(name)}"`);
|
|
548
|
-
if (providerConfig.apiKey) lines.push(`apiKey = "${providerConfig.apiKey}"`);
|
|
549
|
-
if (providerConfig.host) lines.push(`host = "${providerConfig.host}"`);
|
|
550
|
-
if (providerConfig.models?.length) {
|
|
551
|
-
lines.push(`models = ${JSON.stringify(providerConfig.models)}`);
|
|
552
|
-
}
|
|
553
|
-
if (providerConfig.baseUrl) lines.push(`baseUrl = "${providerConfig.baseUrl}"`);
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
const providerAlias = resolveAISetupAgentProvider(config);
|
|
558
|
-
lines.push('', '[ai.agents.zhin]');
|
|
559
|
-
lines.push(`provider = "${providerAlias}"`);
|
|
560
|
-
const zhinModel = resolveAISetupAgentModel(config, providerAlias);
|
|
561
|
-
if (zhinModel) lines.push(`model = "${zhinModel}"`);
|
|
562
|
-
|
|
563
|
-
if (config.trigger) {
|
|
564
|
-
lines.push('', '[ai.trigger]');
|
|
565
|
-
lines.push(`respondToAt = ${config.trigger.respondToAt}`);
|
|
566
|
-
lines.push(`respondToPrivate = ${config.trigger.respondToPrivate}`);
|
|
567
|
-
lines.push(`prefixes = ${JSON.stringify(config.trigger.prefixes)}`);
|
|
568
|
-
lines.push(`ignorePrefixes = ${JSON.stringify(config.trigger.ignorePrefixes)}`);
|
|
569
|
-
lines.push(`timeout = ${config.trigger.timeout}`);
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
if (config.sessions) {
|
|
573
|
-
lines.push('', '[ai.sessions]');
|
|
574
|
-
lines.push(`useDatabase = ${config.sessions.useDatabase}`);
|
|
575
|
-
lines.push(`maxHistory = ${config.sessions.maxHistory}`);
|
|
576
|
-
lines.push(`expireMs = ${config.sessions.expireMs}`);
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
if (config.context) {
|
|
580
|
-
lines.push('', '[ai.context]');
|
|
581
|
-
lines.push(`enabled = ${config.context.enabled}`);
|
|
582
|
-
lines.push(`maxRecentMessages = ${config.context.maxRecentMessages}`);
|
|
583
|
-
lines.push(`summaryThreshold = ${config.context.summaryThreshold}`);
|
|
584
|
-
lines.push(`keepAfterSummary = ${config.context.keepAfterSummary}`);
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
if (config.agent) {
|
|
588
|
-
lines.push('', '[ai.agent]');
|
|
589
|
-
lines.push(`execSecurity = "${config.agent.execSecurity}"`);
|
|
590
|
-
lines.push(`execPreset = "${config.agent.execPreset}"`);
|
|
591
|
-
lines.push(`execAllowlist = ${JSON.stringify(config.agent.execAllowlist)}`);
|
|
592
|
-
lines.push(`phaseTrace = ${config.agent.phaseTrace}`);
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
return lines.join('\n');
|
|
596
|
-
}
|
|
597
|
-
|
|
598
529
|
/**
|
|
599
530
|
* 生成 JSON 格式的 AI 配置段
|
|
600
531
|
*/
|
package/src/apply.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import yaml from 'yaml';
|
|
4
|
-
import {
|
|
4
|
+
import { readPluginConfigurationMap } from '@zhin.js/plugin-runtime';
|
|
5
5
|
import type { AdapterSetupResult, AISetupConfig, DatabaseConfig, InitOptions } from './types.js';
|
|
6
6
|
import {
|
|
7
7
|
collectAdapterPluginConfigs,
|
|
@@ -13,31 +13,21 @@ import { generateAIEnvVars, materializeAIConfig } from './ai.js';
|
|
|
13
13
|
import { generateDatabaseEnvVars, mergeEnvText } from './env.js';
|
|
14
14
|
import { ensureDatabaseForAdapters, ensureDatabaseForAI, getAIDependencies } from './project-deps.js';
|
|
15
15
|
import { DEFAULT_CREATE_BOT_HTTP_PORT, ZHIN_STACK_VERSIONS } from './zhin-stack-deps.js';
|
|
16
|
-
import { packageToInstanceKey } from './project-config-plan.js';
|
|
17
16
|
|
|
18
17
|
export function applyDatabaseToConfig(config: Record<string, unknown>, database: DatabaseConfig): void {
|
|
19
18
|
// 物化为可落盘对象:非 SQLite 连接参数引用 .env(${VAR}),明文密码不进配置文件
|
|
20
19
|
config.database = materializeDatabaseConfig(database);
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
/**
|
|
24
|
-
export function
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (typeof entry !== 'string') continue;
|
|
29
|
-
map[packageToInstanceKey(entry)] ??= {};
|
|
30
|
-
}
|
|
31
|
-
return map;
|
|
32
|
-
}
|
|
33
|
-
if (value && typeof value === 'object') {
|
|
34
|
-
return { ...(value as Record<string, unknown>) };
|
|
35
|
-
}
|
|
36
|
-
return {};
|
|
22
|
+
/** Returns a mutable copy of the canonical Plugin instance configuration map. */
|
|
23
|
+
export function clonePluginConfigurationMap(
|
|
24
|
+
config: Readonly<Record<string, unknown>>,
|
|
25
|
+
): Record<string, unknown> {
|
|
26
|
+
return { ...readPluginConfigurationMap(config) };
|
|
37
27
|
}
|
|
38
28
|
|
|
39
29
|
export function applyAdaptersToConfig(config: Record<string, unknown>, result: AdapterSetupResult): void {
|
|
40
|
-
const plugins =
|
|
30
|
+
const plugins = clonePluginConfigurationMap(config);
|
|
41
31
|
for (const instance of result.instances) {
|
|
42
32
|
plugins[instance.instanceKey] = mergeAdapterInstanceConfig(
|
|
43
33
|
instance.instanceKey,
|
|
@@ -46,8 +36,6 @@ export function applyAdaptersToConfig(config: Record<string, unknown>, result: A
|
|
|
46
36
|
);
|
|
47
37
|
}
|
|
48
38
|
config.plugins = plugins;
|
|
49
|
-
// legacy endpoints 列表不被 runtime 配置 schema 接受(additionalProperties: false)
|
|
50
|
-
delete config.endpoints;
|
|
51
39
|
}
|
|
52
40
|
|
|
53
41
|
function endpointId(endpoint: unknown): string | undefined {
|
|
@@ -327,12 +315,11 @@ export function buildRuntimeConfigDocument(options: InitOptions): Record<string,
|
|
|
327
315
|
return doc;
|
|
328
316
|
}
|
|
329
317
|
|
|
330
|
-
/**
|
|
318
|
+
/** Serialize a Root Runtime YAML or JSON configuration document. */
|
|
331
319
|
export function serializeRuntimeConfig(
|
|
332
320
|
doc: Record<string, unknown>,
|
|
333
|
-
format: 'yaml' | 'json'
|
|
321
|
+
format: 'yaml' | 'json',
|
|
334
322
|
): string {
|
|
335
323
|
if (format === 'json') return `${JSON.stringify(doc, null, 2)}\n`;
|
|
336
|
-
if (format === 'toml') return stringifyToml(doc);
|
|
337
324
|
return yaml.stringify(doc);
|
|
338
325
|
}
|
package/src/index.ts
CHANGED
|
@@ -27,7 +27,6 @@ export {
|
|
|
27
27
|
generateAIEnvVars,
|
|
28
28
|
generateAIConfigYaml,
|
|
29
29
|
generateAIConfigJSON,
|
|
30
|
-
generateAIConfigToml,
|
|
31
30
|
RECOMMENDED_AI_DEFAULTS,
|
|
32
31
|
} from './ai.js';
|
|
33
32
|
|
|
@@ -46,7 +45,7 @@ export {
|
|
|
46
45
|
listAIDependencyNames,
|
|
47
46
|
formatAIDependencyHint,
|
|
48
47
|
isAiEnabledInConfig,
|
|
49
|
-
|
|
48
|
+
resolveAgentProviderFromConfig,
|
|
50
49
|
getRequiredAIDependenciesForConfig,
|
|
51
50
|
diagnoseAIDependencies,
|
|
52
51
|
formatAIDependencyFixCommand,
|
|
@@ -119,7 +118,7 @@ export {
|
|
|
119
118
|
mergePluginManifestIntoPackageJson,
|
|
120
119
|
finalizeWizardOptions,
|
|
121
120
|
applyWizardOptionsToConfig,
|
|
122
|
-
|
|
121
|
+
clonePluginConfigurationMap,
|
|
123
122
|
materializeDatabaseConfig,
|
|
124
123
|
buildRuntimeConfigDocument,
|
|
125
124
|
serializeRuntimeConfig,
|
package/src/optional-peers.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { readPluginConfigurationMap } from '@zhin.js/plugin-runtime';
|
|
3
4
|
import { findMissingPackageDependencies, findUnresolvedPackageInstalls, type PackageJsonLike } from './project-deps.js';
|
|
4
5
|
|
|
5
6
|
export const SPEECH_PACKAGE = '@zhin.js/speech';
|
|
@@ -38,21 +39,10 @@ function readSpeechStrategy(config: Record<string, unknown>): string | undefined
|
|
|
38
39
|
}
|
|
39
40
|
|
|
40
41
|
function configUsesHtmlImageAdapter(config: Record<string, unknown>): boolean {
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
: [];
|
|
44
|
-
for (const plugin of plugins) {
|
|
42
|
+
for (const instanceKey of Object.keys(readPluginConfigurationMap(config))) {
|
|
43
|
+
if (ADAPTERS_PREFER_HTML_IMAGE.has(instanceKey)) return true;
|
|
45
44
|
for (const ctx of ADAPTERS_PREFER_HTML_IMAGE) {
|
|
46
|
-
if (
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
// 新 runtime 配置形态:plugins 为 instanceKey → 配置 的映射,instanceKey 即适配器 context
|
|
50
|
-
if (config.plugins && typeof config.plugins === 'object' && !Array.isArray(config.plugins)) {
|
|
51
|
-
for (const instanceKey of Object.keys(config.plugins as Record<string, unknown>)) {
|
|
52
|
-
if (ADAPTERS_PREFER_HTML_IMAGE.has(instanceKey)) return true;
|
|
53
|
-
for (const ctx of ADAPTERS_PREFER_HTML_IMAGE) {
|
|
54
|
-
if (instanceKey.includes(`adapter-${ctx}`)) return true;
|
|
55
|
-
}
|
|
45
|
+
if (instanceKey.includes(`adapter-${ctx}`)) return true;
|
|
56
46
|
}
|
|
57
47
|
}
|
|
58
48
|
const endpoints = Array.isArray(config.endpoints) ? config.endpoints : [];
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import yaml from 'yaml';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
readPluginConfigurationMap,
|
|
6
|
+
ROOT_CONFIG_FILE_NAMES,
|
|
7
|
+
rootConfigFormat,
|
|
8
|
+
selectRootConfigFile,
|
|
9
|
+
type RootConfigFormat,
|
|
10
|
+
} from '@zhin.js/plugin-runtime';
|
|
5
11
|
import { providerSdkFor } from './ai.js';
|
|
6
12
|
|
|
7
13
|
const CONSOLE_URL = 'https://console.zhin.dev';
|
|
8
|
-
const CONFIG_CANDIDATES = [
|
|
9
|
-
'zhin.config.yml',
|
|
10
|
-
'zhin.config.yaml',
|
|
11
|
-
'zhin.config.json',
|
|
12
|
-
'zhin.config.toml',
|
|
13
|
-
'zhin.config.ts',
|
|
14
|
-
] as const;
|
|
15
14
|
const SANDBOX_PLUGIN = '@zhin.js/adapter-sandbox';
|
|
16
15
|
const LEGACY_AI_PROVIDER_FIELDS = ['driver', 'api', 'preset', 'spec'] as const;
|
|
17
16
|
|
|
@@ -23,7 +22,7 @@ export function packageToInstanceKey(packageName: string): string {
|
|
|
23
22
|
return name.replace(/^(adapter|plugin|service)-/, '');
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
export type ProjectConfigFormat =
|
|
25
|
+
export type ProjectConfigFormat = RootConfigFormat;
|
|
27
26
|
|
|
28
27
|
export interface LoadedProjectConfig {
|
|
29
28
|
status: 'loaded' | 'missing' | 'unsupported';
|
|
@@ -70,12 +69,7 @@ export interface ConsoleConfigDiagnosis {
|
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
function configFormatFromPath(filePath: string): ProjectConfigFormat | null {
|
|
73
|
-
|
|
74
|
-
if (ext === '.yml' || ext === '.yaml') return 'yaml';
|
|
75
|
-
if (ext === '.json') return 'json';
|
|
76
|
-
if (ext === '.toml') return 'toml';
|
|
77
|
-
if (ext === '.ts') return 'ts';
|
|
78
|
-
return null;
|
|
72
|
+
return rootConfigFormat(filePath) ?? null;
|
|
79
73
|
}
|
|
80
74
|
|
|
81
75
|
function cloneConfig(config: Record<string, unknown>): Record<string, unknown> {
|
|
@@ -83,39 +77,28 @@ function cloneConfig(config: Record<string, unknown>): Record<string, unknown> {
|
|
|
83
77
|
}
|
|
84
78
|
|
|
85
79
|
function parseConfig(content: string, format: ProjectConfigFormat): Record<string, unknown> {
|
|
86
|
-
if (format === 'yaml') {
|
|
87
|
-
const parsed = yaml.parse(content) as unknown;
|
|
88
|
-
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
89
|
-
? parsed as Record<string, unknown>
|
|
90
|
-
: {};
|
|
91
|
-
}
|
|
92
80
|
if (format === 'json') {
|
|
93
81
|
const parsed = JSON.parse(content) as unknown;
|
|
94
82
|
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
95
83
|
? parsed as Record<string, unknown>
|
|
96
84
|
: {};
|
|
97
85
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
: {};
|
|
103
|
-
}
|
|
104
|
-
return {};
|
|
86
|
+
const parsed = yaml.parse(content) as unknown;
|
|
87
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed)
|
|
88
|
+
? parsed as Record<string, unknown>
|
|
89
|
+
: {};
|
|
105
90
|
}
|
|
106
91
|
|
|
107
92
|
function serializeConfig(config: Record<string, unknown>, format: ProjectConfigFormat): string {
|
|
108
93
|
if (format === 'json') return `${JSON.stringify(config, null, 2)}\n`;
|
|
109
|
-
if (format === 'toml') return stringifyToml(config as Record<string, unknown>);
|
|
110
94
|
return yaml.stringify(config);
|
|
111
95
|
}
|
|
112
96
|
|
|
113
97
|
function findProjectConfigPath(cwd: string): string | null {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return null;
|
|
98
|
+
const existing = ROOT_CONFIG_FILE_NAMES
|
|
99
|
+
.map((candidate) => path.join(cwd, candidate))
|
|
100
|
+
.filter((configPath) => fs.existsSync(configPath));
|
|
101
|
+
return selectRootConfigFile(existing) ?? null;
|
|
119
102
|
}
|
|
120
103
|
|
|
121
104
|
export function loadProjectConfig(cwd = process.cwd(), configPath?: string): LoadedProjectConfig {
|
|
@@ -126,7 +109,7 @@ export function loadProjectConfig(cwd = process.cwd(), configPath?: string): Loa
|
|
|
126
109
|
cwd,
|
|
127
110
|
config: {},
|
|
128
111
|
writable: false,
|
|
129
|
-
message: '未找到
|
|
112
|
+
message: '未找到 Root YAML/JSON 配置文件',
|
|
130
113
|
};
|
|
131
114
|
}
|
|
132
115
|
|
|
@@ -144,51 +127,35 @@ export function loadProjectConfig(cwd = process.cwd(), configPath?: string): Loa
|
|
|
144
127
|
};
|
|
145
128
|
}
|
|
146
129
|
|
|
147
|
-
|
|
130
|
+
const content = fs.readFileSync(resolvedPath, 'utf8');
|
|
131
|
+
const config = parseConfig(content, format);
|
|
132
|
+
try {
|
|
133
|
+
readPluginConfigurationMap(config, relativePath);
|
|
134
|
+
} catch (error) {
|
|
148
135
|
return {
|
|
149
136
|
status: 'unsupported',
|
|
150
137
|
cwd,
|
|
151
138
|
configPath: resolvedPath,
|
|
152
139
|
relativePath,
|
|
153
140
|
format,
|
|
154
|
-
config
|
|
141
|
+
config,
|
|
155
142
|
writable: false,
|
|
156
|
-
message:
|
|
143
|
+
message: `${error instanceof Error ? error.message : String(error)};请先运行 zhin migrate`,
|
|
157
144
|
};
|
|
158
145
|
}
|
|
159
|
-
|
|
160
|
-
const content = fs.readFileSync(resolvedPath, 'utf8');
|
|
161
146
|
return {
|
|
162
147
|
status: 'loaded',
|
|
163
148
|
cwd,
|
|
164
149
|
configPath: resolvedPath,
|
|
165
150
|
relativePath,
|
|
166
151
|
format,
|
|
167
|
-
config
|
|
152
|
+
config,
|
|
168
153
|
writable: true,
|
|
169
154
|
};
|
|
170
155
|
}
|
|
171
156
|
|
|
172
157
|
function ensurePlugins(config: Record<string, unknown>, pluginsToAdd: readonly string[], mutations: string[]): void {
|
|
173
|
-
|
|
174
|
-
// legacy 数组形式:保持原形态追加,避免改写旧项目结构
|
|
175
|
-
const plugins = config.plugins.filter((p): p is string => typeof p === 'string');
|
|
176
|
-
let changed = false;
|
|
177
|
-
for (const plugin of pluginsToAdd) {
|
|
178
|
-
if (plugins.includes(plugin)) continue;
|
|
179
|
-
plugins.push(plugin);
|
|
180
|
-
mutations.push(`added ${plugin} to plugins`);
|
|
181
|
-
changed = true;
|
|
182
|
-
}
|
|
183
|
-
if (changed) {
|
|
184
|
-
config.plugins = plugins;
|
|
185
|
-
}
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
// 新 Plugin Runtime:plugins 为 <instanceKey>: <配置> 映射
|
|
189
|
-
const plugins = config.plugins && typeof config.plugins === 'object'
|
|
190
|
-
? { ...(config.plugins as Record<string, unknown>) }
|
|
191
|
-
: {};
|
|
158
|
+
const plugins = { ...readPluginConfigurationMap(config) };
|
|
192
159
|
let changed = false;
|
|
193
160
|
for (const pkg of pluginsToAdd) {
|
|
194
161
|
const instanceKey = packageToInstanceKey(pkg);
|
|
@@ -197,7 +164,7 @@ function ensurePlugins(config: Record<string, unknown>, pluginsToAdd: readonly s
|
|
|
197
164
|
mutations.push(`added ${instanceKey} (${pkg}) to plugins`);
|
|
198
165
|
changed = true;
|
|
199
166
|
}
|
|
200
|
-
if (changed ||
|
|
167
|
+
if (changed || config.plugins === undefined) {
|
|
201
168
|
config.plugins = plugins;
|
|
202
169
|
}
|
|
203
170
|
}
|
|
@@ -321,6 +288,8 @@ function applyAiLegacyMigration(config: Record<string, unknown>, mutations: stri
|
|
|
321
288
|
|
|
322
289
|
export function createProjectConfigPlan(options: ProjectConfigPlanOptions): ProjectConfigPlan {
|
|
323
290
|
const cwd = options.cwd ?? options.loaded?.cwd ?? process.cwd();
|
|
291
|
+
const configuredFormat = options.format
|
|
292
|
+
?? (options.configPath ? configFormatFromPath(options.configPath) ?? undefined : undefined);
|
|
324
293
|
const loaded = options.loaded ?? (
|
|
325
294
|
options.config
|
|
326
295
|
? {
|
|
@@ -328,9 +297,9 @@ export function createProjectConfigPlan(options: ProjectConfigPlanOptions): Proj
|
|
|
328
297
|
cwd,
|
|
329
298
|
configPath: options.configPath,
|
|
330
299
|
relativePath: options.configPath ? path.relative(cwd, options.configPath) : undefined,
|
|
331
|
-
format:
|
|
300
|
+
format: configuredFormat,
|
|
332
301
|
config: options.config,
|
|
333
|
-
writable: Boolean(options.configPath &&
|
|
302
|
+
writable: Boolean(options.configPath && configuredFormat),
|
|
334
303
|
}
|
|
335
304
|
: loadProjectConfig(cwd, options.configPath)
|
|
336
305
|
);
|
|
@@ -373,7 +342,7 @@ export function createProjectConfigPlan(options: ProjectConfigPlanOptions): Proj
|
|
|
373
342
|
|
|
374
343
|
export function renderProjectConfigPatch(plan: ProjectConfigPlan): string {
|
|
375
344
|
if (!plan.changed) return '配置无需改动。';
|
|
376
|
-
const format = plan.format
|
|
345
|
+
const format = plan.format ?? 'yaml';
|
|
377
346
|
const name = plan.relativePath ?? 'zhin.config.yml';
|
|
378
347
|
return [
|
|
379
348
|
`# ${name}`,
|
|
@@ -384,7 +353,7 @@ export function renderProjectConfigPatch(plan: ProjectConfigPlan): string {
|
|
|
384
353
|
|
|
385
354
|
export async function applyProjectConfigPlan(plan: ProjectConfigPlan): Promise<boolean> {
|
|
386
355
|
if (!plan.changed) return false;
|
|
387
|
-
if (!plan.writable || !plan.configPath || !plan.format
|
|
356
|
+
if (!plan.writable || !plan.configPath || !plan.format) return false;
|
|
388
357
|
await fs.writeFile(plan.configPath, serializeConfig(plan.after, plan.format));
|
|
389
358
|
return true;
|
|
390
359
|
}
|
|
@@ -395,20 +364,7 @@ export function diagnoseConsoleConfig(config: Record<string, unknown>): ConsoleC
|
|
|
395
364
|
: {};
|
|
396
365
|
const corsOrigins = Array.isArray(http.corsOrigins) ? http.corsOrigins : [];
|
|
397
366
|
|
|
398
|
-
|
|
399
|
-
// legacy 数组形式配置
|
|
400
|
-
const plugins = config.plugins.filter((p): p is string => typeof p === 'string');
|
|
401
|
-
return {
|
|
402
|
-
missingSandboxPlugin: !plugins.includes(SANDBOX_PLUGIN),
|
|
403
|
-
missingConsoleOrigin: !hasConsoleOrigin(corsOrigins.filter((origin): origin is string => typeof origin === 'string')),
|
|
404
|
-
missingHttpToken: typeof http.token !== 'string' || http.token.trim().length === 0,
|
|
405
|
-
};
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// 新 Plugin Runtime:Console Host 由 CLI 装配,无需 host 插件;Sandbox 为 plugins.sandbox 实例
|
|
409
|
-
const plugins = config.plugins && typeof config.plugins === 'object'
|
|
410
|
-
? config.plugins as Record<string, unknown>
|
|
411
|
-
: {};
|
|
367
|
+
const plugins = readPluginConfigurationMap(config);
|
|
412
368
|
return {
|
|
413
369
|
missingSandboxPlugin: !('sandbox' in plugins),
|
|
414
370
|
missingConsoleOrigin: !hasConsoleOrigin(corsOrigins.filter((origin): origin is string => typeof origin === 'string')),
|