openclaw-weiyuan-init 1.0.99 → 1.0.101
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/commands.js +22 -5
- package/lib/identity.js +24 -3
- package/package.json +1 -1
package/lib/commands.js
CHANGED
|
@@ -6,7 +6,7 @@ const { execFile } = require('child_process');
|
|
|
6
6
|
const { promisify } = require('util');
|
|
7
7
|
const { downloadFile, resolvePackageSource } = require('./downloader');
|
|
8
8
|
const { extractZip } = require('./extractor');
|
|
9
|
-
const { createIdentityFile } = require('./identity');
|
|
9
|
+
const { createIdentityFile, normalizeBusinessServerUrl } = require('./identity');
|
|
10
10
|
const { checkServer, initSkill } = require('./server');
|
|
11
11
|
const { printBanner } = require('./utils');
|
|
12
12
|
const execFileAsync = promisify(execFile);
|
|
@@ -163,10 +163,10 @@ function describeInitErrorMessage(error) {
|
|
|
163
163
|
const msg = String(error && error.message || error || '').trim();
|
|
164
164
|
if (!msg) return 'unknown_error';
|
|
165
165
|
if (msg.includes('no_bound_account_for_repair')) {
|
|
166
|
-
return '
|
|
166
|
+
return '当前智能体没有绑定任何微元账号,请先使用官网固定加入命令,或执行“邀请加入微元”的专用命令完成首次接入';
|
|
167
167
|
}
|
|
168
168
|
if (msg.includes('invite_registration_required')) {
|
|
169
|
-
return '普通 init
|
|
169
|
+
return '普通 init 仅用于修复或恢复身份文件;首次注册请使用官网固定加入命令,或使用“邀请加入微元”复制出的专用命令';
|
|
170
170
|
}
|
|
171
171
|
if (msg.includes('agent_register_token_used') || msg.includes('agent_already_registered')) {
|
|
172
172
|
return '该智能体已完成接入,不能再次使用邀请专用命令重复注册新账号;如需补全或找回微元系统文件,请改用普通 init 命令';
|
|
@@ -400,6 +400,16 @@ function normalizeServerUrl(raw) {
|
|
|
400
400
|
}
|
|
401
401
|
}
|
|
402
402
|
|
|
403
|
+
function isAgentRegisterServerUrl(raw) {
|
|
404
|
+
if (!raw || typeof raw !== 'string') return false;
|
|
405
|
+
try {
|
|
406
|
+
const url = new URL(raw.trim());
|
|
407
|
+
return /^\/(?:api\/)?agent-register(?:\/|$)/.test(String(url.pathname || '/'));
|
|
408
|
+
} catch (_) {
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
403
413
|
function parseServerFallbacks(raw) {
|
|
404
414
|
if (!raw || typeof raw !== 'string') return [];
|
|
405
415
|
return raw
|
|
@@ -608,6 +618,7 @@ async function runInit(options) {
|
|
|
608
618
|
let serverUrl = serverCandidates[0] || DEFAULT_CONFIG.serverUrl;
|
|
609
619
|
const force = options.force || false;
|
|
610
620
|
const hasInviteJoin = Boolean(options.project && options.code);
|
|
621
|
+
const hasRegisterInitServer = serverCandidates.some((candidate) => isAgentRegisterServerUrl(candidate));
|
|
611
622
|
const identityPath = path.join(workspacePath, DEFAULT_CONFIG.identityFile);
|
|
612
623
|
const workspaceExists = await fs.pathExists(workspacePath);
|
|
613
624
|
const weiyuanExists = await fs.pathExists(weiyuanPath);
|
|
@@ -621,7 +632,7 @@ async function runInit(options) {
|
|
|
621
632
|
try {
|
|
622
633
|
await runAcrossServerCandidates(serverCandidates, 'join_existing_workspace', async (candidate) => {
|
|
623
634
|
const identity = await fs.readJson(identityPath);
|
|
624
|
-
identity.serverBaseUrl = candidate;
|
|
635
|
+
identity.serverBaseUrl = normalizeBusinessServerUrl(candidate);
|
|
625
636
|
await fs.writeJson(identityPath, identity, { spaces: 2 });
|
|
626
637
|
await runJoin(weiyuanPath, identityPath, options.project, options.code, false);
|
|
627
638
|
});
|
|
@@ -640,6 +651,12 @@ async function runInit(options) {
|
|
|
640
651
|
console.log(chalk.yellow('\n⚠️ 检测到已有工作目录,准备继续执行补齐流程(身份/入组)...\n'));
|
|
641
652
|
} else {
|
|
642
653
|
if (coreReady) {
|
|
654
|
+
if (hasRegisterInitServer) {
|
|
655
|
+
console.log(chalk.cyan('\n✅ 已检测到该智能体已接入微元系统。'));
|
|
656
|
+
console.log(chalk.white('本次不会重新初始化,也不建议使用 --force 进行覆盖更新。'));
|
|
657
|
+
console.log(chalk.gray('如需补全或恢复当前绑定身份,请直接使用普通 init;如需加入项目,请执行项目邀请命令。\n'));
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
643
660
|
console.log(chalk.yellow(`\n⚠️ 工作目录已存在且文件完整: ${workspacePath}`));
|
|
644
661
|
console.log(chalk.gray(' 如需更新微元系统,请使用带 --force 的更新命令\n'));
|
|
645
662
|
return;
|
|
@@ -759,7 +776,7 @@ async function runInit(options) {
|
|
|
759
776
|
try {
|
|
760
777
|
serverUrl = await runAcrossServerCandidates(serverCandidates, 'join_after_init', async (candidate) => {
|
|
761
778
|
const identity = await fs.readJson(identityPath);
|
|
762
|
-
identity.serverBaseUrl = candidate;
|
|
779
|
+
identity.serverBaseUrl = normalizeBusinessServerUrl(candidate);
|
|
763
780
|
await fs.writeJson(identityPath, identity, { spaces: 2 });
|
|
764
781
|
await runJoin(weiyuanPath, identityPath, options.project, options.code, true);
|
|
765
782
|
});
|
package/lib/identity.js
CHANGED
|
@@ -44,6 +44,26 @@ function buildRecoveryHint(workspacePath) {
|
|
|
44
44
|
return `wrh_${sha256Hex([host, username.toLowerCase(), workspace].join('|'))}`;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function normalizeBusinessServerUrl(serverUrl) {
|
|
48
|
+
const fallback = 'https://api.magon.com.cn/api';
|
|
49
|
+
if (!serverUrl || typeof serverUrl !== 'string') return fallback;
|
|
50
|
+
try {
|
|
51
|
+
const url = new URL(String(serverUrl).trim());
|
|
52
|
+
const rawPath = String(url.pathname || '/');
|
|
53
|
+
if (/^\/(?:api\/)?agent-register(?:\/|$)/.test(rawPath)) {
|
|
54
|
+
url.pathname = '/api';
|
|
55
|
+
} else if (!rawPath || rawPath === '/') {
|
|
56
|
+
url.pathname = '/api';
|
|
57
|
+
} else if (!rawPath.startsWith('/api')) {
|
|
58
|
+
url.pathname = `/api${rawPath.startsWith('/') ? '' : '/'}${rawPath}`;
|
|
59
|
+
}
|
|
60
|
+
url.hash = '';
|
|
61
|
+
return url.toString().replace(/\/$/, '');
|
|
62
|
+
} catch (_) {
|
|
63
|
+
return fallback;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
47
67
|
async function registerIdentity(serverUrl, identity) {
|
|
48
68
|
const body = {
|
|
49
69
|
lobsterId: identity.lobsterId,
|
|
@@ -93,12 +113,13 @@ async function registerIdentity(serverUrl, identity) {
|
|
|
93
113
|
|
|
94
114
|
async function createIdentityFile(identityPath, serverUrl, workspacePath) {
|
|
95
115
|
try {
|
|
116
|
+
const businessServerUrl = normalizeBusinessServerUrl(serverUrl);
|
|
96
117
|
if (await fs.pathExists(identityPath)) {
|
|
97
118
|
const existing = await fs.readJson(identityPath).catch(() => ({}));
|
|
98
119
|
if (existing && existing.version === 1 && existing.lobsterId && existing.secretKeyBase64 && existing.publicKeyBase64) {
|
|
99
120
|
const identity = {
|
|
100
121
|
...existing,
|
|
101
|
-
serverBaseUrl:
|
|
122
|
+
serverBaseUrl: businessServerUrl,
|
|
102
123
|
meta: {
|
|
103
124
|
...(existing.meta && typeof existing.meta === 'object' ? existing.meta : {}),
|
|
104
125
|
workspace: workspacePath,
|
|
@@ -121,7 +142,7 @@ async function createIdentityFile(identityPath, serverUrl, workspacePath) {
|
|
|
121
142
|
const identityHash = sha256Hex(JSON.stringify({ lobsterId: kp.lobsterId, publicKeyBase64: kp.publicKeyBase64 }));
|
|
122
143
|
const identity = {
|
|
123
144
|
version: 1,
|
|
124
|
-
serverBaseUrl:
|
|
145
|
+
serverBaseUrl: businessServerUrl,
|
|
125
146
|
lobsterId: kp.lobsterId,
|
|
126
147
|
publicKeyBase64: kp.publicKeyBase64,
|
|
127
148
|
secretKeyBase64: kp.secretKeyBase64,
|
|
@@ -161,4 +182,4 @@ async function readIdentityFile(identityPath) {
|
|
|
161
182
|
}
|
|
162
183
|
}
|
|
163
184
|
|
|
164
|
-
module.exports = { createIdentityFile, readIdentityFile, buildRecoveryHint };
|
|
185
|
+
module.exports = { createIdentityFile, readIdentityFile, buildRecoveryHint, normalizeBusinessServerUrl };
|