@fieldwangai/agentflow 0.1.149 → 0.1.154

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 (195) hide show
  1. package/README.md +20 -33
  2. package/README.zh-CN.md +14 -34
  3. package/agents/agentflow-node-executor-code.md +13 -3
  4. package/agents/agentflow-node-executor-planning.md +13 -3
  5. package/agents/agentflow-node-executor-requirement.md +13 -3
  6. package/agents/agentflow-node-executor-test.md +13 -3
  7. package/agents/agentflow-node-executor-ui.md +13 -3
  8. package/agents/agentflow-node-executor.md +13 -3
  9. package/agents/en/agentflow-node-executor.md +13 -3
  10. package/agents/zh/agentflow-node-executor.md +13 -3
  11. package/bin/agentflow.mjs +3 -3
  12. package/bin/lib/admin-builtin-pipelines.mjs +3 -2
  13. package/bin/lib/agent-runners.mjs +0 -929
  14. package/bin/lib/auth.mjs +2 -1
  15. package/bin/lib/catalog-agents.mjs +2 -1
  16. package/bin/lib/catalog-flows.mjs +167 -88
  17. package/bin/lib/composer-agent.mjs +3 -793
  18. package/bin/lib/composer-skill-router.mjs +3 -323
  19. package/bin/lib/exec-buffered.mjs +32 -0
  20. package/bin/lib/flow-dsl/cli.mjs +276 -0
  21. package/bin/lib/flow-dsl/codegen.mjs +358 -0
  22. package/bin/lib/flow-dsl/defs.mjs +103 -0
  23. package/bin/lib/flow-dsl/index.mjs +77 -0
  24. package/bin/lib/flow-dsl/ir.mjs +305 -0
  25. package/bin/lib/flow-dsl/layout.mjs +115 -0
  26. package/bin/lib/flow-dsl/legacy-yaml.mjs +268 -0
  27. package/bin/lib/flow-dsl/lint.mjs +241 -0
  28. package/bin/lib/flow-dsl/packages.mjs +251 -0
  29. package/bin/lib/flow-dsl/parser.mjs +444 -0
  30. package/bin/lib/flow-import.mjs +96 -26
  31. package/bin/lib/flow-write.mjs +48 -12
  32. package/bin/lib/help.mjs +10 -30
  33. package/bin/lib/html-escape.mjs +19 -0
  34. package/bin/lib/http-util.mjs +49 -0
  35. package/bin/lib/legacy-flow-execution.mjs +43 -0
  36. package/bin/lib/locales/en.json +1 -1
  37. package/bin/lib/locales/zh.json +1 -1
  38. package/bin/lib/main.mjs +153 -283
  39. package/bin/lib/marketplace.mjs +206 -61
  40. package/bin/lib/model-config.mjs +10 -0
  41. package/bin/lib/node-package-archive.mjs +240 -0
  42. package/bin/lib/node-package-bootstrap.mjs +72 -0
  43. package/bin/lib/node-package-manifest.mjs +174 -0
  44. package/bin/lib/paths.mjs +42 -19
  45. package/bin/lib/prd-workflow-routes.mjs +2949 -0
  46. package/bin/lib/prd-workflow-server.mjs +4884 -0
  47. package/bin/lib/run-events.mjs +0 -66
  48. package/bin/lib/schedule-config.mjs +4 -4
  49. package/bin/lib/skill-runtime.mjs +35 -0
  50. package/bin/lib/startup-storage-migrations.mjs +274 -0
  51. package/bin/lib/ui-server.mjs +1106 -18013
  52. package/bin/lib/user-env.mjs +16 -0
  53. package/bin/lib/workspace-auto-layout.mjs +234 -0
  54. package/bin/lib/workspace-flow-store.mjs +478 -0
  55. package/bin/lib/workspace-graph-merge.mjs +41 -34
  56. package/bin/lib/workspace-preview.mjs +74 -0
  57. package/bin/lib/workspace-routes.mjs +3088 -0
  58. package/bin/lib/workspace-server.mjs +6199 -0
  59. package/bin/lib/workspace-state.mjs +331 -0
  60. package/bin/lib/workspace.mjs +2 -1
  61. package/builtin/nodes/agent_subAgent.md +1 -0
  62. package/builtin/nodes/control_agent_toBool.md +2 -0
  63. package/builtin/nodes/control_anyOne.md +2 -0
  64. package/builtin/nodes/control_cancelled.md +2 -0
  65. package/builtin/nodes/control_cd_workspace.md +5 -11
  66. package/builtin/nodes/control_delay.md +2 -0
  67. package/builtin/nodes/control_end.md +2 -0
  68. package/builtin/nodes/control_if.md +1 -0
  69. package/builtin/nodes/control_interval_loop.md +2 -0
  70. package/builtin/nodes/control_load_mcp.md +24 -0
  71. package/builtin/nodes/control_load_skills.md +8 -23
  72. package/builtin/nodes/control_start.md +2 -0
  73. package/builtin/nodes/control_toBool.md +2 -0
  74. package/builtin/nodes/control_user_workspace.md +2 -0
  75. package/builtin/nodes/control_wait_until.md +2 -0
  76. package/builtin/nodes/display_ascii.md +1 -0
  77. package/builtin/nodes/display_chart.md +1 -0
  78. package/builtin/nodes/display_html.md +1 -0
  79. package/builtin/nodes/display_image.md +1 -0
  80. package/builtin/nodes/display_markdown.md +1 -0
  81. package/builtin/nodes/display_mermaid.md +1 -0
  82. package/builtin/nodes/display_react_app.md +1 -0
  83. package/builtin/nodes/display_table.md +1 -0
  84. package/builtin/nodes/provide_bool.md +1 -0
  85. package/builtin/nodes/provide_file.md +1 -0
  86. package/builtin/nodes/provide_password.md +1 -0
  87. package/builtin/nodes/provide_str.md +1 -0
  88. package/builtin/nodes/tool_display_share_link.md +1 -0
  89. package/builtin/nodes/tool_get_env.md +2 -0
  90. package/builtin/nodes/tool_git_checkout.md +1 -0
  91. package/builtin/nodes/tool_git_worktree_load.md +1 -0
  92. package/builtin/nodes/tool_git_worktree_unload.md +1 -0
  93. package/builtin/nodes/tool_gitlab_create_mr.md +1 -0
  94. package/builtin/nodes/tool_jenkins_build.md +2 -0
  95. package/builtin/nodes/tool_load_key.md +2 -0
  96. package/builtin/nodes/tool_nodejs.md +17 -19
  97. package/builtin/nodes/tool_print.md +2 -0
  98. package/builtin/nodes/tool_save_key.md +2 -0
  99. package/builtin/nodes/tool_set_run_env.md +1 -0
  100. package/builtin/nodes/tool_user_ask.md +2 -0
  101. package/builtin/nodes/tool_user_check.md +2 -0
  102. package/builtin/nodes/tool_wecom_send_app_markdown.md +1 -0
  103. package/builtin/nodes/tool_wecom_send_group_markdown.md +1 -0
  104. package/builtin/nodes/workspace_one_click_task.md +44 -0
  105. package/builtin/nodes/workspace_run.md +16 -0
  106. package/builtin/nodes/workspace_scheduled_run.md +16 -0
  107. package/builtin/pipelines/module-migrate/scripts/gate.mjs +37 -0
  108. package/builtin/pipelines/module-migrate/scripts/static-check.mjs +82 -0
  109. package/builtin/pipelines/module-migrate/workspace.flow.js +172 -0
  110. package/builtin/pipelines/module-migrate/workspace.layout.json +134 -0
  111. package/builtin/pipelines/new/scripts/lint-flow.mjs +38 -0
  112. package/builtin/pipelines/new/workspace.flow.js +91 -0
  113. package/builtin/pipelines/new/workspace.layout.json +70 -0
  114. package/builtin/web-ui/dist/assets/{WorkflowAssistantThread-DPbR2UaN.js → WorkflowAssistantThread-CKClwj96.js} +1 -1
  115. package/builtin/web-ui/dist/assets/index-BZ5KqLur.js +870 -0
  116. package/builtin/web-ui/dist/assets/index-CEXmmwM2.css +1 -0
  117. package/builtin/web-ui/dist/index.html +2 -2
  118. package/package.json +2 -1
  119. package/reference/flow-control-capabilities.md +77 -158
  120. package/reference/flow-layout.md +1 -1
  121. package/reference/flow-prompt-handler-check.md +2 -2
  122. package/skills/agentflow-author-flow/SKILL.md +8 -47
  123. package/skills/agentflow-cli/SKILL.md +158 -25
  124. package/skills/agentflow-cli/agents/openai.yaml +2 -2
  125. package/skills/agentflow-cli/scripts/agentflow-cli.mjs +668 -18
  126. package/skills/agentflow-cli/scripts/agentflow-runtime.mjs +97 -0
  127. package/skills/agentflow-flow-add-instances/SKILL.md +7 -248
  128. package/skills/agentflow-flow-dsl/SKILL.md +206 -0
  129. package/skills/agentflow-flow-dsl/agents/openai.yaml +4 -0
  130. package/skills/agentflow-flow-dsl/references/node-calls.md +39 -0
  131. package/skills/agentflow-flow-edit-node-fields/SKILL.md +4 -73
  132. package/skills/agentflow-flow-recipes/SKILL.md +7 -18
  133. package/skills/agentflow-flow-recipes/references/recipes.md +97 -43
  134. package/skills/agentflow-flow-sync-ui/SKILL.md +3 -54
  135. package/skills/agentflow-node-dsl/SKILL.md +212 -0
  136. package/skills/agentflow-node-dsl/agents/openai.yaml +4 -0
  137. package/skills/agentflow-node-reference/SKILL.md +5 -4
  138. package/skills/agentflow-node-reference/references/builtin-nodes.md +166 -115
  139. package/skills/agentflow-placeholder-reference/SKILL.md +2 -2
  140. package/skills/agentflow-runtime-reference/SKILL.md +2 -2
  141. package/skills/agentflow-runtime-reference/references/runtime.md +1 -1
  142. package/skills/agentflow-workspace-ascii/SKILL.md +9 -16
  143. package/skills/agentflow-workspace-graph/SKILL.md +62 -48
  144. package/skills/agentflow-workspace-html/SKILL.md +7 -2
  145. package/skills/agentflow-workspace-image/SKILL.md +6 -2
  146. package/skills/agentflow-workspace-markdown/SKILL.md +14 -21
  147. package/skills/agentflow-workspace-mermaid/SKILL.md +8 -16
  148. package/bin/lib/api-runner.mjs +0 -387
  149. package/bin/lib/apply.mjs +0 -903
  150. package/bin/lib/composer-flow-instances.mjs +0 -68
  151. package/bin/lib/composer-flow-skeleton.mjs +0 -334
  152. package/bin/lib/composer-flow-validate.mjs +0 -47
  153. package/bin/lib/composer-model-router.mjs +0 -185
  154. package/bin/lib/composer-node-schema.mjs +0 -303
  155. package/bin/lib/composer-planner.mjs +0 -751
  156. package/bin/lib/composer-script-ops.mjs +0 -233
  157. package/bin/lib/flow-static-preview.mjs +0 -104
  158. package/bin/lib/hub-login.mjs +0 -54
  159. package/bin/lib/hub-publish.mjs +0 -159
  160. package/bin/lib/hub-remote.mjs +0 -189
  161. package/bin/lib/hub.mjs +0 -299
  162. package/bin/lib/jenkins.mjs +0 -380
  163. package/bin/lib/node-execute.mjs +0 -539
  164. package/bin/lib/normalize-node-tool-command.mjs +0 -97
  165. package/bin/lib/runtime-context.mjs +0 -243
  166. package/bin/lib/scheduler.mjs +0 -601
  167. package/bin/lib/ui-print.mjs +0 -94
  168. package/bin/pipeline/build-node-prompt.mjs +0 -271
  169. package/bin/pipeline/check-cache.mjs +0 -191
  170. package/bin/pipeline/check-flow.mjs +0 -543
  171. package/bin/pipeline/collect-nodes.mjs +0 -212
  172. package/bin/pipeline/compute-cache-md5.mjs +0 -177
  173. package/bin/pipeline/ensure-run-dir.mjs +0 -71
  174. package/bin/pipeline/gc.mjs +0 -129
  175. package/bin/pipeline/get-env.mjs +0 -59
  176. package/bin/pipeline/get-resolved-values.mjs +0 -344
  177. package/bin/pipeline/load-key.mjs +0 -62
  178. package/bin/pipeline/parse-flow.mjs +0 -708
  179. package/bin/pipeline/post-process-control-if.mjs +0 -23
  180. package/bin/pipeline/post-process-node.mjs +0 -490
  181. package/bin/pipeline/pre-process-node.mjs +0 -1430
  182. package/bin/pipeline/resolve-inputs.mjs +0 -201
  183. package/bin/pipeline/run-tool-nodejs.mjs +0 -167
  184. package/bin/pipeline/save-key.mjs +0 -93
  185. package/bin/pipeline/snapshot-prior-round.mjs +0 -70
  186. package/bin/pipeline/validate-for-ui.mjs +0 -234
  187. package/bin/pipeline/validate-script-output.mjs +0 -130
  188. package/bin/pipeline/write-result.mjs +0 -182
  189. package/builtin/pipelines/module-migrate/flow.yaml +0 -819
  190. package/builtin/pipelines/new/flow.yaml +0 -545
  191. package/builtin/pipelines/new/scripts/check-flow.mjs +0 -9
  192. package/builtin/pipelines/new/scripts/collect-nodes.mjs +0 -211
  193. package/builtin/web-ui/dist/assets/index-BSCpd5la.js +0 -889
  194. package/builtin/web-ui/dist/assets/index-DZ328oSo.css +0 -1
  195. package/skills/agentflow-node-authoring/SKILL.md +0 -57
@@ -1,243 +0,0 @@
1
- import path from "path";
2
- import yaml from "js-yaml";
3
- import { getFlowDir } from "./workspace.mjs";
4
- import { PACKAGE_ROOT, PIPELINES_DIR } from "./paths.mjs";
5
- import { listSkills, listSkillsFromSources, workspaceSkillSources } from "./skill-registry.mjs";
6
-
7
- function parseJsonObject(raw) {
8
- if (raw == null) return null;
9
- if (typeof raw === "object" && !Array.isArray(raw)) return raw;
10
- const text = String(raw || "").trim();
11
- if (!text) return null;
12
- try {
13
- const parsed = JSON.parse(text);
14
- return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
15
- } catch {
16
- return null;
17
- }
18
- }
19
-
20
- export function getPipelineFlowDir(workspaceRoot, flowName, flowJson = null) {
21
- if (flowJson?.flowDir && typeof flowJson.flowDir === "string" && flowJson.flowDir.trim()) {
22
- return path.isAbsolute(flowJson.flowDir) ? path.resolve(flowJson.flowDir) : path.resolve(workspaceRoot, flowJson.flowDir);
23
- }
24
- return getFlowDir(workspaceRoot, flowName) || path.join(path.resolve(workspaceRoot), PIPELINES_DIR, flowName);
25
- }
26
-
27
- export function buildDefaultWorkspaceContext(workspaceRoot, flowName, flowJson = null) {
28
- const pipelineWorkspace = path.resolve(workspaceRoot);
29
- const flowDir = getPipelineFlowDir(workspaceRoot, flowName, flowJson);
30
- return {
31
- version: 1,
32
- label: "pipeline",
33
- cwd: pipelineWorkspace,
34
- workspaceRoot: pipelineWorkspace,
35
- pipelineWorkspace,
36
- flowDir,
37
- previous: null,
38
- };
39
- }
40
-
41
- export function normalizeWorkspaceContext(raw, workspaceRoot, flowName, flowJson = null) {
42
- const base = buildDefaultWorkspaceContext(workspaceRoot, flowName, flowJson);
43
- const parsed = parseJsonObject(raw);
44
- if (!parsed) return base;
45
- const cwdRaw = parsed.cwd || parsed.workspaceRoot || parsed.path || "";
46
- const cwd = cwdRaw ? path.resolve(String(cwdRaw)) : base.cwd;
47
- return {
48
- ...base,
49
- ...parsed,
50
- version: 1,
51
- cwd,
52
- workspaceRoot: cwd,
53
- pipelineWorkspace: path.resolve(parsed.pipelineWorkspace || base.pipelineWorkspace),
54
- flowDir: path.resolve(parsed.flowDir || base.flowDir),
55
- previous: parsed.previous && typeof parsed.previous === "object" ? parsed.previous : null,
56
- };
57
- }
58
-
59
- export function normalizeSkillsContext(raw) {
60
- const parsed = parseJsonObject(raw);
61
- if (!parsed) return null;
62
- return {
63
- version: 1,
64
- ...parsed,
65
- skills: Array.isArray(parsed.skills) ? parsed.skills : [],
66
- skillKeys: Array.isArray(parsed.skillKeys) ? parsed.skillKeys : [],
67
- sources: Array.isArray(parsed.sources) ? parsed.sources : [],
68
- warnings: Array.isArray(parsed.warnings) ? parsed.warnings : [],
69
- };
70
- }
71
-
72
- export function expandRuntimePlaceholders(text, workspaceContext, extra = {}) {
73
- if (text == null) return "";
74
- const raw = String(text).trim();
75
- if (!raw) return "";
76
- const values = {
77
- workspaceRoot: workspaceContext.workspaceRoot || workspaceContext.cwd || "",
78
- cwd: workspaceContext.cwd || workspaceContext.workspaceRoot || "",
79
- pipelineWorkspace: workspaceContext.pipelineWorkspace || "",
80
- flowDir: workspaceContext.flowDir || "",
81
- ...extra,
82
- };
83
- return raw.replace(/\$\{([^}]+)\}/g, (_, key) => {
84
- const k = String(key || "").trim();
85
- return values[k] != null ? String(values[k]) : "";
86
- });
87
- }
88
-
89
- export function resolveWorkspaceTarget(rawTarget, workspaceContext, extra = {}) {
90
- const expanded = expandRuntimePlaceholders(rawTarget, workspaceContext, extra).trim();
91
- if (!expanded || expanded === "pipeline" || expanded === "pipeline-workspace") {
92
- return workspaceContext.pipelineWorkspace;
93
- }
94
- if (expanded === "current" || expanded === ".") return workspaceContext.cwd;
95
- if (expanded === "flowDir") return workspaceContext.flowDir;
96
- return path.isAbsolute(expanded) ? path.resolve(expanded) : path.resolve(workspaceContext.cwd, expanded);
97
- }
98
-
99
- export function scanSkillsFromPaths(paths, opts = {}) {
100
- const sources = (paths || []).map((entry, index) => ({
101
- source: entry.source || `runtime-${index}`,
102
- sourceLabel: entry.sourceLabel || entry.label || entry.dir,
103
- dir: path.resolve(entry.dir),
104
- installedBy: entry.installedBy || "runtime",
105
- }));
106
- return listSkillsFromSources(sources, { ...opts, warnMissing: true });
107
- }
108
-
109
- export function parseSkillKeyList(raw) {
110
- if (Array.isArray(raw)) return raw.map((x) => String(x || "").trim()).filter(Boolean);
111
- return String(raw || "")
112
- .split(/[\s,]+/)
113
- .map((x) => x.trim())
114
- .filter(Boolean);
115
- }
116
-
117
- function skillBodyFromRegistryItem(skill) {
118
- return {
119
- name: skill.name,
120
- key: skill.key,
121
- description: skill.description,
122
- frontmatter: skill.frontmatter,
123
- source: skill.source,
124
- sourceLabel: skill.sourceLabel,
125
- path: skill.path,
126
- body: skill.body,
127
- };
128
- }
129
-
130
- export function buildSkillsContextFromRegistry({ workspaceContext, skillKeys = [], mergeMode = "replace" }) {
131
- const wc = workspaceContext;
132
- const wanted = parseSkillKeyList(skillKeys);
133
- const registryWorkspaceRoot = wc.pipelineWorkspace || wc.workspaceRoot || wc.cwd || process.cwd();
134
- const registry = listSkills(PACKAGE_ROOT, registryWorkspaceRoot);
135
- const skillBodies = [];
136
- const warnings = [];
137
- const seenKeys = new Set();
138
-
139
- for (const raw of wanted) {
140
- const key = String(raw || "").trim();
141
- if (!key) continue;
142
- const match = registry.find((skill) => skill.key === key || skill.name === key || skill.id === key);
143
- if (!match) {
144
- warnings.push(`skill not found: ${key}`);
145
- continue;
146
- }
147
- const dedupeKey = match.key || match.path || match.name;
148
- if (seenKeys.has(dedupeKey)) continue;
149
- seenKeys.add(dedupeKey);
150
- skillBodies.push(skillBodyFromRegistryItem(match));
151
- }
152
-
153
- return {
154
- version: 1,
155
- workspaceRoot: wc.workspaceRoot,
156
- cwd: wc.cwd,
157
- pipelineWorkspace: wc.pipelineWorkspace,
158
- flowDir: wc.flowDir,
159
- source: "public-registry",
160
- mergeMode,
161
- requestedSkillKeys: wanted,
162
- skills: skillBodies.map(({ body, ...meta }) => meta),
163
- skillKeys: skillBodies.map((s) => s.key),
164
- sources: [...new Set(skillBodies.map((s) => s.sourceLabel || s.source || "").filter(Boolean))],
165
- loadedCount: skillBodies.length,
166
- warnings,
167
- skillBodies,
168
- };
169
- }
170
-
171
- export function buildSkillsContext({ workspaceContext, source = "current-workspace", paths = [], include = [], exclude = [], mergeMode = "replace" }) {
172
- const wc = workspaceContext;
173
- const sourcePaths = [];
174
- const addWorkspace = (root, label) => {
175
- sourcePaths.push(...workspaceSkillSources(root, label, label));
176
- };
177
- if (source === "pipeline-workspace") {
178
- addWorkspace(wc.pipelineWorkspace, "pipeline");
179
- } else if (source === "explicit-paths") {
180
- for (const p of paths) {
181
- const resolved = path.isAbsolute(p) ? path.resolve(p) : path.resolve(wc.cwd, p);
182
- sourcePaths.push({ dir: resolved, label: "explicit" });
183
- }
184
- } else if (source === "all") {
185
- addWorkspace(wc.cwd, "current");
186
- if (path.resolve(wc.cwd) !== path.resolve(wc.pipelineWorkspace)) addWorkspace(wc.pipelineWorkspace, "pipeline");
187
- } else {
188
- addWorkspace(wc.cwd, "current");
189
- }
190
- const scanned = scanSkillsFromPaths(sourcePaths, { include, exclude });
191
- return {
192
- version: 1,
193
- workspaceRoot: wc.workspaceRoot,
194
- cwd: wc.cwd,
195
- source,
196
- mergeMode,
197
- skills: scanned.skills.map(({ body, ...meta }) => meta),
198
- skillKeys: scanned.skills.map((s) => s.key),
199
- sources: sourcePaths.map((p) => p.dir),
200
- loadedCount: scanned.skills.length,
201
- warnings: scanned.warnings,
202
- skillBodies: scanned.skills.map((s) => ({
203
- name: s.name,
204
- key: s.key,
205
- description: s.description,
206
- frontmatter: s.frontmatter,
207
- sourceLabel: s.sourceLabel,
208
- path: s.path,
209
- body: s.body,
210
- })),
211
- };
212
- }
213
-
214
- function renderSkillFrontmatter(frontmatter) {
215
- if (!frontmatter || typeof frontmatter !== "object" || Array.isArray(frontmatter)) return "";
216
- const extra = Object.fromEntries(
217
- Object.entries(frontmatter).filter(([key, value]) => {
218
- if (key === "name" || key === "description") return false;
219
- if (value == null) return false;
220
- if (typeof value === "string" && value.trim() === "") return false;
221
- return true;
222
- }),
223
- );
224
- if (Object.keys(extra).length === 0) return "";
225
- return yaml.dump(extra, { lineWidth: 100, noRefs: true }).trim();
226
- }
227
-
228
- export function renderSkillsContextForPrompt(skillsContext) {
229
- const ctx = normalizeSkillsContext(skillsContext);
230
- if (!ctx || !Array.isArray(ctx.skillBodies) || ctx.skillBodies.length === 0) return "";
231
- const blocks = ctx.skillBodies.slice(0, 20).map((skill) => {
232
- const body = String(skill.body || "").trim();
233
- const frontmatter = renderSkillFrontmatter(skill.frontmatter);
234
- const header = [
235
- `### ${skill.name}`,
236
- skill.description ? `说明:${skill.description}` : "",
237
- `来源:${skill.path || skill.sourceLabel || ""}`,
238
- frontmatter ? `元数据:\n${frontmatter}` : "",
239
- ].filter(Boolean).join("\n");
240
- return [header, body.slice(0, 16000)].filter(Boolean).join("\n\n");
241
- });
242
- return ["## 已加载 Skills", ...blocks].join("\n\n");
243
- }