@aiyiran/myclaw 1.1.24 → 1.1.26

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.
Files changed (83) hide show
  1. package/.claude/settings.local.json +25 -1
  2. package/assets/myclaw-artifacts.js +1070 -126
  3. package/assets/myclaw-inject.js +913 -121
  4. package/delete_agents.js +268 -0
  5. package/index.js +361 -20
  6. package/package.json +1 -1
  7. package/patches/patch-manifest.json +10 -0
  8. package/server/sync_workspace.py +444 -14
  9. package/skills/yiran-course-template-pipeline/README.md +127 -0
  10. package/skills/yiran-course-template-pipeline/SKILL.md +65 -0
  11. package/skills/yiran-course-template-pipeline/assets/a100-teacher.example.html +66 -0
  12. package/skills/yiran-course-template-pipeline/assets/student-template.html +64 -0
  13. package/skills/yiran-course-template-pipeline/assets/teacher-portrait-demo.html +105 -0
  14. package/skills/yiran-course-template-pipeline/assets/teacher-task-view.html +110 -0
  15. package/skills/yiran-course-template-pipeline/prompts//351/230/266/346/256/2651-demo/347/224/237/346/210/220.md +92 -0
  16. package/skills/yiran-course-template-pipeline/prompts//351/230/266/346/256/2652-student/347/224/237/346/210/220.md +115 -0
  17. package/skills/yiran-course-template-pipeline/prompts//351/230/266/346/256/2653-teacher/347/224/237/346/210/220.md +131 -0
  18. package/skills/yiran-course-template-pipeline/prompts//351/230/266/346/256/2654-/346/211/223/345/214/205/350/220/275/347/233/230.md +77 -0
  19. package/skills/yiran-course-template-pipeline/references/student-example.json +38 -0
  20. package/skills/yiran-course-template-pipeline/references/student-fields.md +195 -0
  21. package/skills/yiran-course-template-pipeline/references/student-scaffold.json +34 -0
  22. package/skills/yiran-course-template-pipeline/references/teacher-fields.md +265 -0
  23. package/skills/yiran-course-template-pipeline/references/teacher-scaffold.json +25 -0
  24. package/skills/yiran-course-template-pipeline/scripts/build_template_views.py +125 -0
  25. package/skills/yiran-course-template-pipeline/scripts/move_template_task.py +59 -0
  26. package/skills/yiran-course-template-pipeline/scripts/render_student_page.py +52 -0
  27. package/skills/yiran-course-template-pipeline/scripts/render_teacher_view.py +108 -0
  28. package/skills/yiran-playground-template-use/SKILL.md +105 -0
  29. package/skills/yiran-playground-template-use/prompts/remix-handoff.txt +11 -0
  30. package/skills/yiran-playground-template-use/scripts/build_template_index.py +103 -0
  31. package/skills/yiran-playground-template-use/scripts/deploy_template.py +34 -0
  32. package/skills/yiran-playground-template-use/scripts/deploy_to_workspace.py +211 -0
  33. package/skills/yiran-playground-template-use/scripts/prepare_playgrounds.py +39 -0
  34. package/skills/yiran-playground-template-use/scripts/query_template.py +171 -0
  35. package/skills/yiran-playground-template-use/scripts/run_playgrounds_flow.py +44 -0
  36. package/skills/yiran-playground-template-use/scripts/start_tui_handoff.py +77 -0
  37. package/skills/yiran-playground-template-use/search-agent-prompt.md +39 -0
  38. package/skills/yiran-playground-template-use/template-index.json +136 -0
  39. package/skills/yiran-playground-template-use/template-index.md +38 -0
  40. package/skills/yiran-playground-template-use/templates/a100_/347/273/231/344/276/235/347/204/266/350/200/201/345/270/210/350/256/276/350/256/241/344/270/200/344/270/252AI/347/224/273/345/203/217/__demo__.html +140 -0
  41. package/skills/yiran-playground-template-use/templates/a100_/347/273/231/344/276/235/347/204/266/350/200/201/345/270/210/350/256/276/350/256/241/344/270/200/344/270/252AI/347/224/273/345/203/217/__student-view__.html +64 -0
  42. package/skills/yiran-playground-template-use/templates/a100_/347/273/231/344/276/235/347/204/266/350/200/201/345/270/210/350/256/276/350/256/241/344/270/200/344/270/252AI/347/224/273/345/203/217/__student__.json +38 -0
  43. package/skills/yiran-playground-template-use/templates/a100_/347/273/231/344/276/235/347/204/266/350/200/201/345/270/210/350/256/276/350/256/241/344/270/200/344/270/252AI/347/224/273/345/203/217/__teacher-view__.html +52 -0
  44. package/skills/yiran-playground-template-use/templates/a100_/347/273/231/344/276/235/347/204/266/350/200/201/345/270/210/350/256/276/350/256/241/344/270/200/344/270/252AI/347/224/273/345/203/217/__teacher__.json +36 -0
  45. package/skills/yiran-playground-template-use/templates/a100_/347/273/231/344/276/235/347/204/266/350/200/201/345/270/210/350/256/276/350/256/241/344/270/200/344/270/252AI/347/224/273/345/203/217/index.html +61 -0
  46. package/skills/yiran-playground-template-use/templates/a101_/345/201/2323/345/274/240/345/220/214/344/270/273/351/242/230/345/233/276/347/211/207/__demo__.html +131 -0
  47. package/skills/yiran-playground-template-use/templates/a101_/345/201/2323/345/274/240/345/220/214/344/270/273/351/242/230/345/233/276/347/211/207/__student-view__.html +64 -0
  48. package/skills/yiran-playground-template-use/templates/a101_/345/201/2323/345/274/240/345/220/214/344/270/273/351/242/230/345/233/276/347/211/207/__student__.json +34 -0
  49. package/skills/yiran-playground-template-use/templates/a101_/345/201/2323/345/274/240/345/220/214/344/270/273/351/242/230/345/233/276/347/211/207/__teacher-view__.html +52 -0
  50. package/skills/yiran-playground-template-use/templates/a101_/345/201/2323/345/274/240/345/220/214/344/270/273/351/242/230/345/233/276/347/211/207/__teacher__.json +34 -0
  51. package/skills/yiran-playground-template-use/templates/a103_/345/201/232/344/270/200/344/270/252/344/273/213/347/273/215/351/241/265/351/235/242/__demo__.html +77 -0
  52. package/skills/yiran-playground-template-use/templates/a103_/345/201/232/344/270/200/344/270/252/344/273/213/347/273/215/351/241/265/351/235/242/__student-view__.html +64 -0
  53. package/skills/yiran-playground-template-use/templates/a103_/345/201/232/344/270/200/344/270/252/344/273/213/347/273/215/351/241/265/351/235/242/__student__.json +38 -0
  54. package/skills/yiran-playground-template-use/templates/a103_/345/201/232/344/270/200/344/270/252/344/273/213/347/273/215/351/241/265/351/235/242/__teacher-view__.html +52 -0
  55. package/skills/yiran-playground-template-use/templates/a103_/345/201/232/344/270/200/344/270/252/344/273/213/347/273/215/351/241/265/351/235/242/__teacher__.json +34 -0
  56. package/skills/yiran-playground-template-use/templates/b100_/345/201/232/344/270/200/344/270/252/346/214/211/351/222/256/351/241/265/351/235/242/__demo__.html +162 -0
  57. package/skills/yiran-playground-template-use/templates/b100_/345/201/232/344/270/200/344/270/252/346/214/211/351/222/256/351/241/265/351/235/242/__student-view__.html +64 -0
  58. package/skills/yiran-playground-template-use/templates/b100_/345/201/232/344/270/200/344/270/252/346/214/211/351/222/256/351/241/265/351/235/242/__student__.json +34 -0
  59. package/skills/yiran-playground-template-use/templates/b100_/345/201/232/344/270/200/344/270/252/346/214/211/351/222/256/351/241/265/351/235/242/__teacher-view__.html +52 -0
  60. package/skills/yiran-playground-template-use/templates/b100_/345/201/232/344/270/200/344/270/252/346/214/211/351/222/256/351/241/265/351/235/242/__teacher__.json +34 -0
  61. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271/__demo__.html +180 -0
  62. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271/__student-view__.html +64 -0
  63. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271/__student__.json +38 -0
  64. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271/__teacher-view__.html +52 -0
  65. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271/__teacher__.json +41 -0
  66. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271/demo.html +180 -0
  67. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271/index.html +121 -0
  68. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271//345/260/217/347/273/204/345/220/211/347/245/245/347/211/251_26.png +0 -0
  69. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271//345/260/217/347/273/204/345/233/276/345/275/242/346/240/207/345/277/227_83.png +0 -0
  70. package/skills/yiran-playground-template-use/templates/c100_/347/273/231/345/260/217/347/273/204/344/275/234/345/223/201/345/201/232/344/270/200/346/254/241/345/260/217/344/277/256/346/224/271//347/217/255/347/272/247/345/260/217/347/273/204/345/276/275/347/253/240_47.png +0 -0
  71. package/skills/yiran-skill-media/SKILL.md +6 -15
  72. package/skills/yiran-skill-media/scripts/generate.py +47 -18
  73. package/skills/yiran-skill-media/scripts/generation_log.json +1 -56
  74. package/skills/yiran-skill-media/scripts/providers/__pycache__/__init__.cpython-311.pyc +0 -0
  75. package/skills/yiran-skill-media/scripts/providers/__pycache__/__init__.cpython-37.pyc +0 -0
  76. package/skills/yiran-skill-media/scripts/providers/__pycache__/jimeng_image.cpython-37.pyc +0 -0
  77. package/skills/yiran-skill-media/scripts/providers/__pycache__/jimeng_video.cpython-311.pyc +0 -0
  78. package/skills/yiran-skill-media/scripts/providers/__pycache__/jimeng_video.cpython-37.pyc +0 -0
  79. package/skills/yiran-skill-media/scripts/providers/__pycache__/minimax_image.cpython-37.pyc +0 -0
  80. package/skills/yiran-skill-media/scripts/providers/__pycache__/minimax_music.cpython-37.pyc +0 -0
  81. package/skills/yiran-skill-media/scripts/providers/__pycache__/minimax_video.cpython-311.pyc +0 -0
  82. package/skills/yiran-skill-media/scripts/providers/__pycache__/minimax_video.cpython-37.pyc +0 -0
  83. package/skills/yiran-skill-media/scripts/providers/__pycache__/vapi_image.cpython-37.pyc +0 -0
@@ -0,0 +1,268 @@
1
+ /**
2
+ * ============================================================================
3
+ * MyClaw — delete_agents 核心模块
4
+ * ============================================================================
5
+ *
6
+ * 提供 Agent 批量删除的底层能力,被以下两处复用:
7
+ * 1. CLI:mc delete (交互式批量删除)
8
+ * 2. API:sync_workspace.py /api/agents /api/agents/trash
9
+ *
10
+ * 导出:
11
+ * listAllAgents() → 取 JSON注册 ∪ agents文件夹 的并集,附统计信息
12
+ * trashPath(p) → 跨平台移入回收站(macOS/Windows/Linux)
13
+ * deleteRegisteredAgent(id)→ 调用 openclaw agents delete --force
14
+ * deleteOrphanAgent(ag) → 对孤立 agent 的所有路径执行 trashPath
15
+ * ============================================================================
16
+ */
17
+
18
+ 'use strict';
19
+
20
+ const fs = require('fs');
21
+ const path = require('path');
22
+ const os = require('os');
23
+ const { spawnSync, execSync } = require('child_process');
24
+
25
+ // ─────────────────────────────────────────────
26
+ // 路径工具
27
+ // ─────────────────────────────────────────────
28
+
29
+ function getOpenclawDir() {
30
+ if (process.platform === 'win32' || fs.existsSync('/root/.openclaw')) {
31
+ return '/root/.openclaw';
32
+ }
33
+ return path.join(os.homedir(), '.openclaw');
34
+ }
35
+
36
+ // ─────────────────────────────────────────────
37
+ // listAllAgents
38
+ // ─────────────────────────────────────────────
39
+
40
+ /**
41
+ * 返回所有 Agent 的信息列表(JSON注册表 ∪ agents文件夹)。
42
+ *
43
+ * @returns {Array<{
44
+ * id: string,
45
+ * inJson: boolean, — 是否在 openclaw.json 里注册
46
+ * inFolder: boolean, — agents/ 目录下是否有对应文件夹
47
+ * workspace: string, — workspace 目录绝对路径
48
+ * agentDir: string, — agent 配置目录(含 auth-profiles.json)
49
+ * sessionsDir: string, — 会话记录目录
50
+ * sessionCount: number, — .jsonl 会话文件数量
51
+ * lastUpdated: number|null — 最近会话 mtime(毫秒时间戳)
52
+ * }>}
53
+ */
54
+ function listAllAgents() {
55
+ const base = getOpenclawDir();
56
+ const configPath = path.join(base, 'openclaw.json');
57
+ const agentsDir = path.join(base, 'agents');
58
+
59
+ // ── 1. 读取 JSON 注册的 agent ──
60
+ const jsonAgents = {};
61
+ try {
62
+ const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
63
+ for (const entry of ((cfg.agents || {}).list || [])) {
64
+ if (entry && entry.id) {
65
+ jsonAgents[entry.id] = {
66
+ workspace: entry.workspace || '',
67
+ agentDir: entry.agentDir || '',
68
+ };
69
+ }
70
+ }
71
+ } catch (_) {}
72
+
73
+ // ── 2. 扫描 agents/ 文件夹 ──
74
+ const folderIds = new Set();
75
+ try {
76
+ if (fs.existsSync(agentsDir)) {
77
+ for (const name of fs.readdirSync(agentsDir)) {
78
+ if (fs.statSync(path.join(agentsDir, name)).isDirectory()) {
79
+ folderIds.add(name);
80
+ }
81
+ }
82
+ }
83
+ } catch (_) {}
84
+
85
+ // ── 3. 合并并集 ──
86
+ const allIds = [...new Set([...Object.keys(jsonAgents), ...folderIds])].sort();
87
+ const result = [];
88
+
89
+ for (const id of allIds) {
90
+ const inJson = id in jsonAgents;
91
+ const inFolder = folderIds.has(id);
92
+
93
+ const workspace = inJson ? jsonAgents[id].workspace : path.join(base, 'workspace-' + id);
94
+ const agentDir = inJson ? jsonAgents[id].agentDir : path.join(agentsDir, id, 'agent');
95
+ const sessionsDir = path.join(agentsDir, id, 'sessions');
96
+
97
+ // ── 统计会话 ──
98
+ let sessionCount = 0;
99
+ let lastUpdated = null;
100
+
101
+ try {
102
+ if (fs.existsSync(sessionsDir)) {
103
+ const files = fs.readdirSync(sessionsDir).filter(f => f.endsWith('.jsonl'));
104
+ sessionCount = files.length;
105
+ const mtimes = files
106
+ .map(f => { try { return fs.statSync(path.join(sessionsDir, f)).mtimeMs; } catch (_) { return 0; } })
107
+ .filter(Boolean);
108
+ if (mtimes.length > 0) lastUpdated = Math.max(...mtimes);
109
+ }
110
+ } catch (_) {}
111
+
112
+ // fallback:用目录 mtime
113
+ if (lastUpdated === null) {
114
+ try {
115
+ const dir = fs.existsSync(workspace) ? workspace : path.join(agentsDir, id);
116
+ if (fs.existsSync(dir)) lastUpdated = fs.statSync(dir).mtimeMs;
117
+ } catch (_) {}
118
+ }
119
+
120
+ result.push({ id, inJson, inFolder, workspace, agentDir, sessionsDir, sessionCount, lastUpdated });
121
+ }
122
+
123
+ // 按最后更新时间降序(最新在前),null 排最后
124
+ result.sort((a, b) => {
125
+ if (a.lastUpdated === null && b.lastUpdated === null) return 0;
126
+ if (a.lastUpdated === null) return 1;
127
+ if (b.lastUpdated === null) return -1;
128
+ return b.lastUpdated - a.lastUpdated;
129
+ });
130
+
131
+ return result;
132
+ }
133
+
134
+ // ─────────────────────────────────────────────
135
+ // trashPath — 跨平台移入回收站
136
+ // ─────────────────────────────────────────────
137
+
138
+ /**
139
+ * 将指定路径移入系统回收站。
140
+ *
141
+ * @param {string} p - 要删除的文件/目录路径
142
+ * @returns {{ ok: boolean, dest?: string, method?: string, note?: string, error?: string }}
143
+ */
144
+ function trashPath(p) {
145
+ if (!p || typeof p !== 'string') return { ok: false, error: '路径无效' };
146
+ p = path.normalize(p);
147
+ if (!fs.existsSync(p)) return { ok: true, note: '路径不存在,跳过' };
148
+
149
+ try {
150
+ const plat = process.platform;
151
+
152
+ // ── macOS ──
153
+ if (plat === 'darwin') {
154
+ const trashDir = path.join(os.homedir(), '.Trash');
155
+ const base = path.basename(p);
156
+ let dest = path.join(trashDir, base);
157
+ if (fs.existsSync(dest)) dest = path.join(trashDir, base + '.' + Date.now());
158
+ fs.renameSync(p, dest);
159
+ return { ok: true, dest };
160
+ }
161
+
162
+ // ── Windows ──
163
+ if (plat === 'win32') {
164
+ // 文件用 DeleteFile,目录用 DeleteDirectory
165
+ const isDir = fs.statSync(p).isDirectory();
166
+ const safePath = p.replace(/'/g, '');
167
+ const method = isDir ? 'DeleteDirectory' : 'DeleteFile';
168
+ const extraArgs = isDir
169
+ ? `'${safePath}', 'OnlyErrorDialogs', 'SendToRecycleBin'`
170
+ : `'${safePath}', 'OnlyErrorDialogs', 'SendToRecycleBin'`;
171
+ const psCmd = `Add-Type -AssemblyName Microsoft.VisualBasic; [Microsoft.VisualBasic.FileIO.FileSystem]::${method}(${extraArgs})`;
172
+ const ret = spawnSync('powershell', ['-NoProfile', '-Command', psCmd], { timeout: 15000 });
173
+ if (ret.status === 0) return { ok: true, method: 'powershell' };
174
+ return { ok: false, error: (ret.stderr || Buffer.alloc(0)).toString().trim() };
175
+ }
176
+
177
+ // ── Linux ──
178
+ for (const cmd of [['gio', 'trash', p], ['trash-put', p]]) {
179
+ const ret = spawnSync(cmd[0], cmd.slice(1), { timeout: 10000 });
180
+ if (ret.status === 0) return { ok: true, method: cmd[0] };
181
+ if (ret.error && ret.error.code === 'ENOENT') continue; // 命令不存在
182
+ }
183
+ // 兜底:直接删除并告知用户
184
+ fs.rmSync(p, { recursive: true, force: true });
185
+ return { ok: true, method: 'rm', note: '未找到回收站工具(gio/trash-put),已直接删除' };
186
+
187
+ } catch (e) {
188
+ return { ok: false, error: e.message };
189
+ }
190
+ }
191
+
192
+ // ─────────────────────────────────────────────
193
+ // deleteRegisteredAgent — 删除已在 JSON 注册的 agent
194
+ // ─────────────────────────────────────────────
195
+
196
+ /**
197
+ * 调用 openclaw agents delete --force 删除已注册的 agent。
198
+ * 会同时清理 JSON 条目、workspace 和 agentDir。
199
+ *
200
+ * @param {string} id
201
+ * @returns {{ ok: boolean, error?: string }}
202
+ */
203
+ function deleteRegisteredAgent(id) {
204
+ try {
205
+ execSync('openclaw agents delete ' + id + ' --force', {
206
+ stdio: 'pipe',
207
+ timeout: 30000,
208
+ });
209
+ return { ok: true };
210
+ } catch (e) {
211
+ const stderr = e.stderr ? e.stderr.toString().trim() : e.message;
212
+ return { ok: false, error: stderr };
213
+ }
214
+ }
215
+
216
+ // ─────────────────────────────────────────────
217
+ // deleteOrphanAgent — 删除孤立 agent(仅有文件夹)
218
+ // ─────────────────────────────────────────────
219
+
220
+ /**
221
+ * 阶段1:对孤立 agent 模拟官方最小删除行为。
222
+ * 依次 trash:workspace 目录、agents/xxx/agent/ 子目录(不含 sessions)。
223
+ *
224
+ * @param {{ id: string, workspace: string }} ag
225
+ * @returns {{ ok: boolean, results: Array }}
226
+ */
227
+ function deleteOrphanAgent(ag) {
228
+ const base = getOpenclawDir();
229
+ const agentSubdir = path.join(base, 'agents', ag.id, 'agent'); // 只删 agent/ 子目录
230
+
231
+ const targets = [ag.workspace, agentSubdir].filter(Boolean);
232
+ const results = targets.map(p => ({ path: p, ...trashPath(p) }));
233
+ const ok = results.every(r => r.ok);
234
+ return { ok, results };
235
+ }
236
+
237
+ // ─────────────────────────────────────────────
238
+ // cleanAgentDirs — 阶段2:清理 agents/<id>/ 整个目录(含 sessions)
239
+ // ─────────────────────────────────────────────
240
+
241
+ /**
242
+ * 阶段2:清理 agents/<id>/ 整个目录(含 sessions/)。
243
+ * 对注册 agent 和孤立 agent 均适用:
244
+ * - 注册 agent:openclaw delete 已清理 agent/ 子目录,此步清理 sessions/ 残余
245
+ * - 孤立 agent:deleteOrphanAgent 已清理 agent/ 子目录,此步清理 sessions/ 残余
246
+ *
247
+ * @param {string} id
248
+ * @returns {{ ok: boolean, results: Array }}
249
+ */
250
+ function cleanAgentDirs(id) {
251
+ const base = getOpenclawDir();
252
+ const agentRoot = path.join(base, 'agents', id);
253
+ const res = trashPath(agentRoot);
254
+ return { ok: res.ok, results: [{ path: agentRoot, ...res }] };
255
+ }
256
+
257
+ // ─────────────────────────────────────────────
258
+ // module.exports
259
+ // ─────────────────────────────────────────────
260
+
261
+ module.exports = {
262
+ listAllAgents,
263
+ trashPath,
264
+ deleteRegisteredAgent,
265
+ deleteOrphanAgent,
266
+ cleanAgentDirs,
267
+ getOpenclawDir,
268
+ };