openclaw-weiyuan-init 1.0.90 → 1.0.93

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.
@@ -68,7 +68,14 @@
68
68
  - 未收到本轮完整人工确认,禁止执行高危动作。
69
69
  - 禁止通过隐式参数、脚本捷径、自动补全或直调 API 绕过确认流程。
70
70
 
71
- ## 七、需求(漏洞)上报 与 项目风险上报规则
71
+ ## 七、Todo(当前我要做什么)规则
72
+ - Todo 是独立于项目任务(task)的行动清单能力,不等于 task 状态本身。
73
+ - 当用户表达“我今天/明天要做什么、帮我整理待办、同步我的行动清单”时,默认走 `todo.*` 命令链路。
74
+ - 先查后写:先读取现有清单(如 `todo.list` 或上下文快照),再执行 `todo.upsert/todo.complete/todo.delete`。
75
+ - 改期或改文案时,优先 `todo.upsert itemId=...` 就地更新,禁止直接新增重复事项。
76
+ - Todo 可不关联任务;遇到会议、沟通、安排类事项,允许仅写“时间 + 事项”。
77
+
78
+ ## 八、需求(漏洞)上报 与 项目风险上报规则
72
79
 
73
80
  ### 1. 需求(漏洞)上报
74
81
  - 适用范围:
@@ -128,14 +135,14 @@
128
135
  - 禁止把需求(漏洞)写进项目风险池。
129
136
  - 禁止把项目风险写进系统级需求(漏洞)池。
130
137
 
131
- ## 八、回复边界与执行边界
138
+ ## 九、回复边界与执行边界
132
139
  - 禁止把未实现能力说成已实现。
133
140
  - 禁止把规划能力包装成现成功能。
134
141
  - 禁止在信息不完整时替用户做关键决策。
135
142
  - 禁止输出互相冲突的结论。
136
143
  - 禁止在微元系统场景下越权执行与当前任务无关的动作。
137
144
 
138
- ## 九、信息层级要求
145
+ ## 十、信息层级要求
139
146
  - 默认只输出:
140
147
  - 当前结果
141
148
  - 当前影响
@@ -148,14 +155,14 @@
148
155
  - 调试信息
149
156
  - 仅当用户明确要求“详细说明”“展开技术细节”时,才补充接口、字段、路由、模块分工、规则逻辑等信息。
150
157
 
151
- ## 十、统一执行优先级
158
+ ## 十一、统一执行优先级
152
159
  - 安全与高危确认优先。
153
160
  - 用户当前明确目标优先。
154
161
  - 微元系统既有规则与边界优先。
155
162
  - 输出必须可理解、可执行、可追踪。
156
163
  - 始终保持微元场景下的风格统一与回复稳定。
157
164
 
158
- ## 十一、规范注入提示
165
+ ## 十二、规范注入提示
159
166
  - 第一次加入微元系统后,应立即阅读本规范,并将关键要点同步到 `agent.md`、`MEMORY.md`、`SOUL.md` 或等价长期记忆文件。
160
167
  - 每次微元系统更新后,应再次阅读更新内容与本规范,并刷新上述文件中的微元场景规则。
161
168
  - 注入时必须注明:
@@ -68,7 +68,14 @@
68
68
  - 未收到本轮完整人工确认,禁止执行高危动作。
69
69
  - 禁止通过隐式参数、脚本捷径、自动补全或直调 API 绕过确认流程。
70
70
 
71
- ## 七、需求(漏洞)上报 与 项目风险上报规则
71
+ ## 七、Todo(当前我要做什么)规则
72
+ - Todo 是独立于项目任务(task)的行动清单能力,不等于 task 状态本身。
73
+ - 当用户表达“我今天/明天要做什么、帮我整理待办、同步我的行动清单”时,默认走 `todo.*` 命令链路。
74
+ - 先查后写:先读取现有清单(如 `todo.list` 或上下文快照),再执行 `todo.upsert/todo.complete/todo.delete`。
75
+ - 改期或改文案时,优先 `todo.upsert itemId=...` 就地更新,禁止直接新增重复事项。
76
+ - Todo 可不关联任务;遇到会议、沟通、安排类事项,允许仅写“时间 + 事项”。
77
+
78
+ ## 八、需求(漏洞)上报 与 项目风险上报规则
72
79
 
73
80
  ### 1. 需求(漏洞)上报
74
81
  - 适用范围:
@@ -128,14 +135,14 @@
128
135
  - 禁止把需求(漏洞)写进项目风险池。
129
136
  - 禁止把项目风险写进系统级需求(漏洞)池。
130
137
 
131
- ## 八、回复边界与执行边界
138
+ ## 九、回复边界与执行边界
132
139
  - 禁止把未实现能力说成已实现。
133
140
  - 禁止把规划能力包装成现成功能。
134
141
  - 禁止在信息不完整时替用户做关键决策。
135
142
  - 禁止输出互相冲突的结论。
136
143
  - 禁止在微元系统场景下越权执行与当前任务无关的动作。
137
144
 
138
- ## 九、信息层级要求
145
+ ## 十、信息层级要求
139
146
  - 默认只输出:
140
147
  - 当前结果
141
148
  - 当前影响
@@ -148,14 +155,14 @@
148
155
  - 调试信息
149
156
  - 仅当用户明确要求“详细说明”“展开技术细节”时,才补充接口、字段、路由、模块分工、规则逻辑等信息。
150
157
 
151
- ## 十、统一执行优先级
158
+ ## 十一、统一执行优先级
152
159
  - 安全与高危确认优先。
153
160
  - 用户当前明确目标优先。
154
161
  - 微元系统既有规则与边界优先。
155
162
  - 输出必须可理解、可执行、可追踪。
156
163
  - 始终保持微元场景下的风格统一与回复稳定。
157
164
 
158
- ## 十一、规范注入提示
165
+ ## 十二、规范注入提示
159
166
  - 第一次加入微元系统后,应立即阅读本规范,并将关键要点同步到 `agent.md`、`MEMORY.md`、`SOUL.md` 或等价长期记忆文件。
160
167
  - 每次微元系统更新后,应再次阅读更新内容与本规范,并刷新上述文件中的微元场景规则。
161
168
  - 注入时必须注明:
package/lib/commands.js CHANGED
@@ -86,6 +86,28 @@ function renderFixedMessage(template, vars = {}) {
86
86
  return String(template).replace(/\{(\w+)\}/g, (_, k) => (vars[k] !== undefined ? String(vars[k]) : ""));
87
87
  }
88
88
 
89
+ function printInitAccountWelcome(initInfo) {
90
+ if (!initInfo || typeof initInfo !== 'object') return;
91
+ const account = String(initInfo.account || '').trim();
92
+ if (!account) return;
93
+ const defaultPassword = String(initInfo.defaultPassword || '').trim() || '123456';
94
+ const rows = Array.isArray(initInfo.securityQuestions) ? initInfo.securityQuestions : [];
95
+ console.log(chalk.cyan('\n【已成功加入微元系统】'));
96
+ console.log(chalk.white(`你的默认账号为:${account}`));
97
+ console.log(chalk.white(`初始密码为:${defaultPassword}`));
98
+ if (rows.length) {
99
+ console.log(chalk.white('随机密保问题和答案:'));
100
+ rows.slice(0, 2).forEach((row, idx) => {
101
+ const q = String((row && row.question) || '').trim() || `问题${idx + 1}`;
102
+ const a = String((row && row.answer) || '').trim() || '-';
103
+ console.log(chalk.white(`${idx + 1}. ${q}:${a}`));
104
+ });
105
+ }
106
+ console.log(chalk.white('请牢记这些内容,之后你可以通过官网直接登录微元系统以及更改你的账号名称和密码'));
107
+ console.log(chalk.white('微元系统官方网站为:https://app-ay9bunzcmltt.appmiaoda.com/'));
108
+ console.log(chalk.white('微元系统登录页面为:https://api.magon.com.cn/api/login'));
109
+ }
110
+
89
111
  function printReleaseNotes(notes) {
90
112
  if (!notes) return;
91
113
  const lines = Array.isArray(notes.changes) ? notes.changes.filter(Boolean).slice(0, 8) : [];
@@ -145,6 +167,13 @@ function weiyuanCliRulesMarkdown() {
145
167
  '- 二次确认固定用词:第一步输入“是”,第二步输入“同意”。',
146
168
  '- 禁止通过隐式参数、脚本捷径或自动化跳过确认。',
147
169
  '',
170
+ '## Todo 行动清单规则',
171
+ '- Todo 是独立于 task 的“当前我要做什么”清单,不等于任务状态字段。',
172
+ '- 当用户表达“今天/明天要做什么、整理待办、同步行动清单”时,默认使用 `todo.*` 命令。',
173
+ '- 先查后写:先读取现有清单(todo.list 或上下文快照),再执行 upsert/complete/delete。',
174
+ '- 修改已有事项(改期/改文案)优先 `todo.upsert itemId=...`,禁止直接新增重复事项。',
175
+ '- Todo 可不关联 task;会议/沟通/安排类事项允许仅写“时间+事项”。',
176
+ '',
148
177
  '## 上报分流规则',
149
178
  '- 具体功能异常、需求新增、漏洞修复,走“需求(漏洞)上报”。',
150
179
  '- 影响项目推进、交付、协作、资源、节奏的问题,走“项目风险上报”。',
@@ -361,12 +390,39 @@ async function runJoin(weiyuanPath, identityPath, projectId, code, fromInit = fa
361
390
  async function ensureSkillRuntime(weiyuanPath) {
362
391
  const pkgPath = path.join(weiyuanPath, 'package.json');
363
392
  const tsconfigPath = path.join(weiyuanPath, 'tsconfig.json');
393
+ const capabilityCompatContent = `export const CAPABILITY_ACTION = {
394
+ PROJECT_DELETE: "project.delete",
395
+ TASK_DELETE: "task.delete",
396
+ DOC_DELETE: "doc.delete",
397
+ BACKUP_RESTORE: "backup.restore",
398
+ BACKUP_DELETE: "backup.delete",
399
+ BACKUP_PRUNE: "backup.prune",
400
+ BACKUP_PRUNE_PLAN: "backup.prune_plan",
401
+ BACKUP_VERIFY: "backup.verify",
402
+ BACKUP_RESTORE_DRY_RUN: "backup.restore_dry_run",
403
+ BACKUP_DIFF: "backup.diff",
404
+ } as const
405
+
406
+ export const CAPABILITY_ACTION_ALLOWLIST = new Set<string>(Object.values(CAPABILITY_ACTION))
407
+ `;
364
408
  if (!await fs.pathExists(pkgPath)) {
365
409
  await fs.writeJson(pkgPath, DEFAULT_SKILL_PACKAGE_JSON, { spaces: 2 });
366
410
  }
367
411
  if (!await fs.pathExists(tsconfigPath)) {
368
412
  await fs.writeJson(tsconfigPath, DEFAULT_SKILL_TSCONFIG, { spaces: 2 });
369
413
  }
414
+ // Compatibility guard: some custom upgrade bundles miss capabilityActions.ts.
415
+ // Auto-create fallback files so CLI can boot instead of crashing on module resolution.
416
+ const capabilityCandidates = [
417
+ path.join(weiyuanPath, 'src', 'capabilityActions.ts'),
418
+ path.join(weiyuanPath, 'server', 'src', 'capabilityActions.ts')
419
+ ];
420
+ for (const file of capabilityCandidates) {
421
+ if (!await fs.pathExists(file)) {
422
+ await fs.ensureDir(path.dirname(file));
423
+ await fs.writeFile(file, capabilityCompatContent, 'utf8');
424
+ }
425
+ }
370
426
  await execFileAsync('npm', ['--prefix', weiyuanPath, 'install'], { cwd: weiyuanPath });
371
427
  }
372
428
 
@@ -396,6 +452,7 @@ async function runCliInit(weiyuanPath, identityPath, serverUrl) {
396
452
  async function runInit(options) {
397
453
  printBanner();
398
454
  const fixedMessages = getFixedMessages();
455
+ let initIdentityInfo = null;
399
456
 
400
457
  const invite = decodeInviteToken(options.invite);
401
458
  if (invite) {
@@ -533,14 +590,9 @@ async function runInit(options) {
533
590
  } else {
534
591
  try {
535
592
  serverUrl = await runAcrossServerCandidates(serverCandidates, 'identity_init', async (candidate) => {
536
- try {
537
- await runCliInit(weiyuanPath, identityPath, candidate);
538
- return;
539
- } catch (error) {
540
- const created = await createIdentityFile(identityPath, candidate, workspacePath);
541
- if (created) return;
542
- throw error;
543
- }
593
+ const created = await createIdentityFile(identityPath, candidate, workspacePath);
594
+ if (!created || !created.created) throw new Error('identity_create_failed');
595
+ initIdentityInfo = created.initInfo || null;
544
596
  });
545
597
  spinner.succeed(`身份文件: ${DEFAULT_CONFIG.identityFile}`);
546
598
  } catch (error) {
@@ -573,10 +625,12 @@ async function runInit(options) {
573
625
  }
574
626
  spinner.succeed(`已加入项目: ${options.project}`);
575
627
  printRulesInjectionHint();
628
+ printInitAccountWelcome(initIdentityInfo);
576
629
  console.log(renderFixedMessage(fixedMessages.sceneB, { projectId: options.project }));
577
630
  return;
578
631
  }
579
632
  printRulesInjectionHint();
633
+ printInitAccountWelcome(initIdentityInfo);
580
634
  console.log(fixedMessages.sceneA);
581
635
  }
582
636
 
package/lib/identity.js CHANGED
@@ -41,23 +41,39 @@ async function registerIdentity(serverUrl, identity) {
41
41
  const timestampMs = String(Date.now());
42
42
  const nonce = `nonce_${Math.random().toString(16).slice(2)}`;
43
43
  const bodySha256Base64 = sha256Base64(JSON.stringify(body));
44
- const canonical = canonicalRequest('POST', '/v1/init', timestampMs, nonce, bodySha256Base64);
45
- const signature = signEd25519Base64(canonical, identity.secretKeyBase64);
46
-
47
- const res = await axios.post(`${serverUrl.replace(/\/$/, '')}/v1/init`, body, {
48
- headers: {
49
- 'Content-Type': 'application/json',
50
- 'X-Weiyuan-Lobster-Id': identity.lobsterId,
51
- 'X-Weiyuan-Timestamp': timestampMs,
52
- 'X-Weiyuan-Nonce': nonce,
53
- 'X-Weiyuan-Signature': signature
54
- },
55
- timeout: 12000,
56
- validateStatus: () => true
57
- });
58
- if (res.status !== 200) {
59
- throw new Error(`identity_register_failed_status_${res.status}`);
44
+ const base = serverUrl.replace(/\/$/, '');
45
+ const candidates = [
46
+ { path: '/v1/init', url: `${base}/v1/init` },
47
+ base.endsWith('/api')
48
+ ? { path: '/v1/init', url: `${base.slice(0, -4)}/v1/init` }
49
+ : { path: '/api/v1/init', url: `${base}/api/v1/init` }
50
+ ];
51
+ let res = null;
52
+ let lastStatus = 0;
53
+ for (const item of candidates) {
54
+ const canonical = canonicalRequest('POST', item.path, timestampMs, nonce, bodySha256Base64);
55
+ const signature = signEd25519Base64(canonical, identity.secretKeyBase64);
56
+ const current = await axios.post(item.url, body, {
57
+ headers: {
58
+ 'Content-Type': 'application/json',
59
+ 'X-Weiyuan-Lobster-Id': identity.lobsterId,
60
+ 'X-Weiyuan-Timestamp': timestampMs,
61
+ 'X-Weiyuan-Nonce': nonce,
62
+ 'X-Weiyuan-Signature': signature
63
+ },
64
+ timeout: 12000,
65
+ validateStatus: () => true
66
+ });
67
+ lastStatus = current.status;
68
+ if (current.status === 404) continue;
69
+ res = current;
70
+ break;
71
+ }
72
+ if (!res || res.status !== 200) {
73
+ throw new Error(`identity_register_failed_status_${lastStatus || 0}`);
60
74
  }
75
+ const envelope = res.data && typeof res.data === 'object' ? res.data : {};
76
+ return envelope.data && typeof envelope.data === 'object' ? envelope.data : envelope;
61
77
  }
62
78
 
63
79
  async function createIdentityFile(identityPath, serverUrl, workspacePath) {
@@ -65,7 +81,7 @@ async function createIdentityFile(identityPath, serverUrl, workspacePath) {
65
81
  if (await fs.pathExists(identityPath)) {
66
82
  const existing = await fs.readJson(identityPath).catch(() => ({}));
67
83
  if (existing && existing.version === 1 && existing.lobsterId && existing.secretKeyBase64 && existing.publicKeyBase64) {
68
- return true;
84
+ return { created: true, initInfo: null };
69
85
  }
70
86
  }
71
87
 
@@ -88,11 +104,11 @@ async function createIdentityFile(identityPath, serverUrl, workspacePath) {
88
104
  }
89
105
  };
90
106
 
91
- await registerIdentity(serverUrl, identity);
107
+ const initInfo = await registerIdentity(serverUrl, identity);
92
108
  await fs.writeJson(identityPath, identity, { spaces: 2 });
93
- return true;
109
+ return { created: true, initInfo: initInfo || null };
94
110
  } catch (error) {
95
- return false;
111
+ return { created: false, initInfo: null };
96
112
  }
97
113
  }
98
114
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-weiyuan-init",
3
- "version": "1.0.90",
3
+ "version": "1.0.93",
4
4
  "description": "OpenClaw Weiyuan Skill 一键初始化工具",
5
5
  "main": "bin/cli.js",
6
6
  "bin": {