openclaw-weiyuan-init 1.0.127 → 1.0.128
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
|
@@ -21,7 +21,7 @@ const DEFAULT_CONFIG = {
|
|
|
21
21
|
workspaceName: 'workspace-weiyuan',
|
|
22
22
|
upgradeBaseUrl: 'https://api.magon.com.cn/upgrade',
|
|
23
23
|
downloadUrl: '',
|
|
24
|
-
serverUrl: 'https://api.magon.com.cn
|
|
24
|
+
serverUrl: 'https://api.magon.com.cn',
|
|
25
25
|
identityFile: '.weiyuan',
|
|
26
26
|
serverFallbacks: []
|
|
27
27
|
};
|
|
@@ -168,6 +168,11 @@ function printInitAccountWelcome(initInfo) {
|
|
|
168
168
|
const ruleInjectionMessage = String(initInfo.ruleInjectionMessage || '').trim();
|
|
169
169
|
const targetAccountId = String(initInfo.targetAccountId || '').trim();
|
|
170
170
|
const ownerAccountId = String(initInfo.ownerAccountId || '').trim();
|
|
171
|
+
const dashboardUrl = String(initInfo.dashboardUrl || '').trim();
|
|
172
|
+
const officialSiteUrl = String(initInfo.officialSiteUrl || 'https://www.magon.com.cn/').trim();
|
|
173
|
+
const loginUrl = String(initInfo.loginUrl || 'https://api.magon.com.cn/api/login').trim();
|
|
174
|
+
const bindPhoneUrl = String(initInfo.bindPhoneUrl || 'https://api.magon.com.cn/api/account/bind-phone').trim();
|
|
175
|
+
const skillDownloadUrl = String(initInfo.skillDownloadUrl || 'https://api.magon.com.cn/api/downloads/weiyuan-agent-cli-skill.md').trim();
|
|
171
176
|
if (bindInit) {
|
|
172
177
|
console.log(chalk.cyan(`\n【${modeLabel}绑定成功】`));
|
|
173
178
|
if (welcome) console.log(chalk.white(welcome));
|
|
@@ -191,9 +196,15 @@ function printInitAccountWelcome(initInfo) {
|
|
|
191
196
|
: '请牢记该账号信息;当前账号中心已切换为验证码登录体系。'
|
|
192
197
|
)
|
|
193
198
|
);
|
|
194
|
-
console.log(chalk.white(
|
|
195
|
-
console.log(chalk.white(
|
|
196
|
-
console.log(chalk.white(
|
|
199
|
+
console.log(chalk.white(`微元系统官方网站为:${officialSiteUrl}`));
|
|
200
|
+
console.log(chalk.white(`微元系统登录页面为:${loginUrl}`));
|
|
201
|
+
console.log(chalk.white(`微元系统绑定手机号页面为:${bindPhoneUrl}`));
|
|
202
|
+
console.log(chalk.white(`微元系统智能体 skill 下载地址为:${skillDownloadUrl}`));
|
|
203
|
+
if (dashboardUrl) {
|
|
204
|
+
console.log(chalk.white(`个人驾驶舱地址为:${dashboardUrl}`));
|
|
205
|
+
console.log(chalk.white('请把这个驾驶舱链接保存好;后续优先直接打开该链接即可,不必每次都先回登录页查找入口。'));
|
|
206
|
+
}
|
|
207
|
+
console.log(chalk.white('如果你想把微元系统能力导入到 workbuddy、豆包等智能体,可以直接下载上面的 skill 文件并导入。'));
|
|
197
208
|
console.log(chalk.white('建议立即前往“绑定手机号”页面完成手机号绑定,后续即可通过登录页获取验证码登录,并可在登录后修改用户名和密码。'));
|
|
198
209
|
} else if (recovered) {
|
|
199
210
|
console.log(chalk.cyan('\n【微元身份已同步】'));
|
|
@@ -217,7 +228,7 @@ function describeInitErrorMessage(error) {
|
|
|
217
228
|
return '绑定命令已被使用,不能重复执行。请回到微元系统驾驶舱重新生成最新绑定命令';
|
|
218
229
|
}
|
|
219
230
|
if (msg.includes('bind_token_expired')) {
|
|
220
|
-
return '
|
|
231
|
+
return '绑定命令已过期。注意:这通常只代表旧命令失效,不代表当前绑定状态已失效;如果驾驶舱已显示“已绑定”,请直接继续使用,或回到驾驶舱重新生成最新绑定命令';
|
|
221
232
|
}
|
|
222
233
|
if (msg.includes('unbind_token_not_found')) {
|
|
223
234
|
return '解绑命令无效:未找到对应解绑令牌。请回到微元系统驾驶舱重新生成最新解绑命令后再执行';
|
|
@@ -226,7 +237,7 @@ function describeInitErrorMessage(error) {
|
|
|
226
237
|
return '解绑命令已被使用,不能重复执行。请回到微元系统驾驶舱重新生成最新解绑命令';
|
|
227
238
|
}
|
|
228
239
|
if (msg.includes('unbind_token_expired')) {
|
|
229
|
-
return '
|
|
240
|
+
return '解绑命令已过期。注意:这通常只代表旧命令失效,不代表当前绑定状态异常;请回到微元系统驾驶舱重新生成最新解绑命令';
|
|
230
241
|
}
|
|
231
242
|
if (msg.includes('target_not_found')) {
|
|
232
243
|
return '服务器未找到本次绑定/解绑对应的目标账号,通常是命令域名错误、令牌对应账号已失效,或服务端数据尚未同步';
|
|
@@ -507,7 +518,7 @@ function normalizeServerUrl(raw) {
|
|
|
507
518
|
try {
|
|
508
519
|
const url = new URL(cleaned);
|
|
509
520
|
const p = (url.pathname || '/').replace(/\/+$/, '');
|
|
510
|
-
if (!p || p === '/') url.pathname = '
|
|
521
|
+
if (!p || p === '/' || p === '/api' || /^\/(?:api\/)?v1(?:\/|$)/.test(p)) url.pathname = '';
|
|
511
522
|
url.hash = '';
|
|
512
523
|
return url.toString().replace(/\/$/, '');
|
|
513
524
|
} catch (_) {
|
|
@@ -662,6 +673,7 @@ function buildAgentConversationGuide(projectId) {
|
|
|
662
673
|
'请至少再给用户补充 2 个场景示例:',
|
|
663
674
|
'1. 项目场景:用户说“帮我创建一个项目”,你继续追问项目名称、目标、负责人等关键信息,再完成创建。',
|
|
664
675
|
'2. 协作场景:用户说“帮我在当前项目里建一个测试任务,明天下午提醒我跟进”,你要继续补全信息并直接帮他处理。',
|
|
676
|
+
'如果系统已经返回个人驾驶舱链接,你必须把该链接原样输出给用户,并提醒用户保存这个入口,后续可直接打开使用。',
|
|
665
677
|
joinedProjectLine,
|
|
666
678
|
'',
|
|
667
679
|
'你还必须明确告诉用户:',
|
package/lib/identity.js
CHANGED
|
@@ -46,17 +46,15 @@ function buildRecoveryHint(workspacePath) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
function normalizeBusinessServerUrl(serverUrl) {
|
|
49
|
-
const fallback = 'https://api.magon.com.cn
|
|
49
|
+
const fallback = 'https://api.magon.com.cn';
|
|
50
50
|
if (!serverUrl || typeof serverUrl !== 'string') return fallback;
|
|
51
51
|
try {
|
|
52
52
|
const url = new URL(String(serverUrl).trim());
|
|
53
53
|
const rawPath = String(url.pathname || '/');
|
|
54
54
|
if (/^\/(?:api\/)?agent-(?:register|bind)(?:\/|$)/.test(rawPath)) {
|
|
55
|
-
url.pathname = '
|
|
56
|
-
} else if (!rawPath || rawPath === '/') {
|
|
57
|
-
url.pathname = '
|
|
58
|
-
} else if (!rawPath.startsWith('/api')) {
|
|
59
|
-
url.pathname = `/api${rawPath.startsWith('/') ? '' : '/'}${rawPath}`;
|
|
55
|
+
url.pathname = '';
|
|
56
|
+
} else if (!rawPath || rawPath === '/' || rawPath === '/api' || /^\/(?:api\/)?v1(?:\/|$)/.test(rawPath)) {
|
|
57
|
+
url.pathname = '';
|
|
60
58
|
}
|
|
61
59
|
url.hash = '';
|
|
62
60
|
return url.toString().replace(/\/$/, '');
|
|
@@ -190,22 +188,21 @@ async function createIdentityFile(identityPath, serverUrl, workspacePath) {
|
|
|
190
188
|
}
|
|
191
189
|
if (initInfo && Array.isArray(initInfo.joinedProjectIds)) {
|
|
192
190
|
identity.joinedProjectIds = initInfo.joinedProjectIds.map((x) => String(x || '').trim()).filter(Boolean);
|
|
193
|
-
} else {
|
|
194
|
-
delete identity.joinedProjectIds;
|
|
195
191
|
}
|
|
196
192
|
if (initInfo && typeof initInfo.currentProjectId === 'string' && initInfo.currentProjectId.trim()) {
|
|
197
193
|
identity.currentProjectId = String(initInfo.currentProjectId).trim();
|
|
198
|
-
} else {
|
|
199
|
-
|
|
194
|
+
} else if (!identity.currentProjectId && Array.isArray(identity.joinedProjectIds) && identity.joinedProjectIds.length) {
|
|
195
|
+
identity.currentProjectId = String(identity.joinedProjectIds[0] || '').trim() || identity.currentProjectId;
|
|
196
|
+
}
|
|
197
|
+
if (initInfo && initInfo.projectCursors && typeof initInfo.projectCursors === 'object' && !Array.isArray(initInfo.projectCursors)) {
|
|
198
|
+
identity.projectCursors = Object.fromEntries(
|
|
199
|
+
Object.entries(initInfo.projectCursors)
|
|
200
|
+
.map(([k, v]) => [String(k || '').trim(), Number(v || 0)])
|
|
201
|
+
.filter(([k, v]) => k && Number.isFinite(v))
|
|
202
|
+
);
|
|
203
|
+
} else if (!identity.projectCursors || typeof identity.projectCursors !== 'object' || Array.isArray(identity.projectCursors)) {
|
|
204
|
+
identity.projectCursors = {};
|
|
200
205
|
}
|
|
201
|
-
identity.projectCursors =
|
|
202
|
-
initInfo && initInfo.projectCursors && typeof initInfo.projectCursors === 'object' && !Array.isArray(initInfo.projectCursors)
|
|
203
|
-
? Object.fromEntries(
|
|
204
|
-
Object.entries(initInfo.projectCursors)
|
|
205
|
-
.map(([k, v]) => [String(k || '').trim(), Number(v || 0)])
|
|
206
|
-
.filter(([k, v]) => k && Number.isFinite(v))
|
|
207
|
-
)
|
|
208
|
-
: {};
|
|
209
206
|
const nextIdentity = applyIdentityProxyMetadata(identity, initInfo);
|
|
210
207
|
await fs.writeJson(identityPath, nextIdentity, { spaces: 2 });
|
|
211
208
|
return { created: true, initInfo: initInfo || null };
|
|
@@ -240,22 +237,21 @@ async function createIdentityFile(identityPath, serverUrl, workspacePath) {
|
|
|
240
237
|
}
|
|
241
238
|
if (initInfo && Array.isArray(initInfo.joinedProjectIds)) {
|
|
242
239
|
identity.joinedProjectIds = initInfo.joinedProjectIds.map((x) => String(x || '').trim()).filter(Boolean);
|
|
243
|
-
} else {
|
|
244
|
-
delete identity.joinedProjectIds;
|
|
245
240
|
}
|
|
246
241
|
if (initInfo && typeof initInfo.currentProjectId === 'string' && initInfo.currentProjectId.trim()) {
|
|
247
242
|
identity.currentProjectId = String(initInfo.currentProjectId).trim();
|
|
248
|
-
} else {
|
|
249
|
-
|
|
243
|
+
} else if (!identity.currentProjectId && Array.isArray(identity.joinedProjectIds) && identity.joinedProjectIds.length) {
|
|
244
|
+
identity.currentProjectId = String(identity.joinedProjectIds[0] || '').trim() || identity.currentProjectId;
|
|
245
|
+
}
|
|
246
|
+
if (initInfo && initInfo.projectCursors && typeof initInfo.projectCursors === 'object' && !Array.isArray(initInfo.projectCursors)) {
|
|
247
|
+
identity.projectCursors = Object.fromEntries(
|
|
248
|
+
Object.entries(initInfo.projectCursors)
|
|
249
|
+
.map(([k, v]) => [String(k || '').trim(), Number(v || 0)])
|
|
250
|
+
.filter(([k, v]) => k && Number.isFinite(v))
|
|
251
|
+
);
|
|
252
|
+
} else if (!identity.projectCursors || typeof identity.projectCursors !== 'object' || Array.isArray(identity.projectCursors)) {
|
|
253
|
+
identity.projectCursors = {};
|
|
250
254
|
}
|
|
251
|
-
identity.projectCursors =
|
|
252
|
-
initInfo && initInfo.projectCursors && typeof initInfo.projectCursors === 'object' && !Array.isArray(initInfo.projectCursors)
|
|
253
|
-
? Object.fromEntries(
|
|
254
|
-
Object.entries(initInfo.projectCursors)
|
|
255
|
-
.map(([k, v]) => [String(k || '').trim(), Number(v || 0)])
|
|
256
|
-
.filter(([k, v]) => k && Number.isFinite(v))
|
|
257
|
-
)
|
|
258
|
-
: {};
|
|
259
255
|
const nextIdentity = applyIdentityProxyMetadata(identity, initInfo);
|
|
260
256
|
await fs.writeJson(identityPath, nextIdentity, { spaces: 2 });
|
|
261
257
|
return { created: true, initInfo: initInfo || null };
|
package/package.json
CHANGED
|
@@ -1052,7 +1052,7 @@ const DEFAULT_REPLY_TEMPLATES: ReplyTemplateMap = {
|
|
|
1052
1052
|
"runtime.upgrade": { text: "更新成功。" },
|
|
1053
1053
|
}
|
|
1054
1054
|
|
|
1055
|
-
const WEIYUAN_OFFICIAL_WEBSITE = "https://
|
|
1055
|
+
const WEIYUAN_OFFICIAL_WEBSITE = "https://www.magon.com.cn/"
|
|
1056
1056
|
|
|
1057
1057
|
function withOfficialWebsiteIfLinkPresent(obj: Record<string, unknown>, message: string): { message: string; officialWebsite: string } | null {
|
|
1058
1058
|
const hasDashboard = typeof obj.dashboardLink === "string" && obj.dashboardLink.trim().length > 0
|
|
@@ -1124,9 +1124,31 @@ function formatWatermark(): { time: string; traceId: string } {
|
|
|
1124
1124
|
}
|
|
1125
1125
|
|
|
1126
1126
|
function buildMandatoryDisplay(actionKey: string | undefined, core: unknown): string | undefined {
|
|
1127
|
-
if (!actionKey) return undefined
|
|
1128
1127
|
const c = asRecord(core)
|
|
1129
1128
|
const { time, traceId } = formatWatermark()
|
|
1129
|
+
const account = typeof c.account === "string" ? c.account.trim() : ""
|
|
1130
|
+
const dashboardLink = typeof c.dashboardLink === "string" ? c.dashboardLink.trim() : (typeof c.dashboardUrl === "string" ? c.dashboardUrl.trim() : "")
|
|
1131
|
+
const bindPhoneUrl = typeof c.bindPhoneUrl === "string" ? c.bindPhoneUrl.trim() : ""
|
|
1132
|
+
const loginUrl = typeof c.loginUrl === "string" ? c.loginUrl.trim() : ""
|
|
1133
|
+
const officialWebsite = typeof c.officialWebsite === "string"
|
|
1134
|
+
? c.officialWebsite.trim()
|
|
1135
|
+
: (typeof c.officialSiteUrl === "string" ? c.officialSiteUrl.trim() : WEIYUAN_OFFICIAL_WEBSITE)
|
|
1136
|
+
if (account && (dashboardLink || bindPhoneUrl || loginUrl || officialWebsite)) {
|
|
1137
|
+
return [
|
|
1138
|
+
`### 🌀 微元系统账号入口 (不可修改)(数据时间:${time} | Trace_ID:${traceId})`,
|
|
1139
|
+
"| 项目 | 内容 |",
|
|
1140
|
+
"| --- | --- |",
|
|
1141
|
+
`| 微元账号 | ${account} |`,
|
|
1142
|
+
`| 个人驾驶舱 | ${dashboardLink || "未返回"} |`,
|
|
1143
|
+
`| 手机号绑定 | ${bindPhoneUrl || "未返回"} |`,
|
|
1144
|
+
`| 登录页面 | ${loginUrl || "未返回"} |`,
|
|
1145
|
+
`| 官方网站 | ${officialWebsite || WEIYUAN_OFFICIAL_WEBSITE} |`,
|
|
1146
|
+
"",
|
|
1147
|
+
`- **重点提醒**:个人驾驶舱链接是重点入口,请立即保存:${dashboardLink || "当前未返回,请重新获取一次加入成功结果"}`,
|
|
1148
|
+
"-----------------------------------",
|
|
1149
|
+
].join("\n")
|
|
1150
|
+
}
|
|
1151
|
+
if (!actionKey) return undefined
|
|
1130
1152
|
if (actionKey.startsWith("project.")) {
|
|
1131
1153
|
const projectName = pickProjectName(c)
|
|
1132
1154
|
const projectId = typeof c.projectId === "string" ? c.projectId : "未获取"
|
|
@@ -1507,7 +1529,7 @@ function buildDialogueData(raw: unknown, detailed: boolean, actionKey?: string,
|
|
|
1507
1529
|
const quickActions = showOperationalInfo ? collectQuickActions(raw).slice(0, 3) : []
|
|
1508
1530
|
const base = enforceOutputQuality(conciseMessageFromCore(slim, actionKey, templates), slim, actionKey)
|
|
1509
1531
|
const tip = pickMicroTip(actionKey)
|
|
1510
|
-
const mandatoryDisplay = buildMandatoryDisplay(actionKey,
|
|
1532
|
+
const mandatoryDisplay = buildMandatoryDisplay(actionKey, raw)
|
|
1511
1533
|
const friendly = withMicroPrefix(tip ? `${base}\n${tip}` : base)
|
|
1512
1534
|
const messageRaw = mandatoryDisplay ? `🌐【微元项目模式】\n${mandatoryDisplay}\n${friendly}` : friendly
|
|
1513
1535
|
const message = applyExpressionPolicyText(messageRaw, "已处理完成。", actionKey)
|
|
@@ -5,7 +5,7 @@ import type { WeiyuanIdentityFileV1 } from "./types"
|
|
|
5
5
|
export const DEFAULT_IDENTITY_PATH = ".weiyuan"
|
|
6
6
|
|
|
7
7
|
export function normalizeServerBaseUrl(raw: string): string {
|
|
8
|
-
const fallback = "https://api.magon.com.cn
|
|
8
|
+
const fallback = "https://api.magon.com.cn"
|
|
9
9
|
if (!raw || typeof raw !== "string") return fallback
|
|
10
10
|
const cleaned = raw.trim().replace(/^[`'"\s]+|[`'"\s]+$/g, "")
|
|
11
11
|
if (!cleaned) return fallback
|
|
@@ -21,16 +21,17 @@ export function normalizeServerBaseUrl(raw: string): string {
|
|
|
21
21
|
url.protocol = "https:"
|
|
22
22
|
const rawPath = String(url.pathname || "/")
|
|
23
23
|
if (/^\/(?:api\/)?agent-(?:register|bind)(?:\/|$)/.test(rawPath)) {
|
|
24
|
-
url.pathname = "
|
|
24
|
+
url.pathname = ""
|
|
25
25
|
} else {
|
|
26
|
-
if (!url.pathname || url.pathname === "/"
|
|
27
|
-
if (!url.pathname.startsWith("/api")) url.pathname = `/api${url.pathname.startsWith("/") ? "" : "/"}${url.pathname}`
|
|
26
|
+
if (!url.pathname || url.pathname === "/" || url.pathname === "/api" || /^\/(?:api\/)?v1(?:\/|$)/.test(rawPath)) url.pathname = ""
|
|
28
27
|
}
|
|
29
28
|
url.hash = ""
|
|
30
29
|
return url.toString().replace(/\/$/, "")
|
|
31
30
|
}
|
|
32
31
|
if (/^\/(?:api\/)?agent-(?:register|bind)(?:\/|$)/.test(String(url.pathname || "/"))) {
|
|
33
|
-
url.pathname = "
|
|
32
|
+
url.pathname = ""
|
|
33
|
+
} else if (String(url.pathname || "") === "/api" || /^\/(?:api\/)?v1(?:\/|$)/.test(String(url.pathname || "/"))) {
|
|
34
|
+
url.pathname = ""
|
|
34
35
|
}
|
|
35
36
|
url.hash = ""
|
|
36
37
|
return url.toString().replace(/\/$/, "")
|