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 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: serverUrl,
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: serverUrl,
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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-weiyuan-init",
3
- "version": "1.0.99",
3
+ "version": "1.0.101",
4
4
  "description": "OpenClaw Weiyuan Skill 一键初始化工具",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {