





















@@ -29,8 +29,8 @@ const PLUGIN_DOC_ALIASES = new Map([
2929["tavily", "/tools/tavily"],
3030["tokenjuice", "/tools/tokenjuice"],
3131]);
32-/** @type {ReadonlyMap<string, string>} */
33-const PLUGIN_REFERENCE_EXTRA_SECTIONS = new Map();
32+const MANUAL_SECTION_START = "<!-- openclaw-plugin-reference:manual-start -->";
33+const MANUAL_SECTION_END = "<!-- openclaw-plugin-reference:manual-end -->";
34343535function readJson(relativePath) {
3636return JSON.parse(fs.readFileSync(path.join(ROOT, relativePath), "utf8"));
@@ -377,9 +377,48 @@ function renderRelatedDocs(record) {
377377${record.docs.map((link) => `- ${docLink(link)}`).join("\n")}`;
378378}
379379380-function renderReferencePage(record) {
380+function extractManualReferenceSections(content) {
381+const markerStart = content.indexOf(MANUAL_SECTION_START);
382+if (markerStart !== -1) {
383+const contentStart = markerStart + MANUAL_SECTION_START.length;
384+const markerEnd = content.indexOf(MANUAL_SECTION_END, contentStart);
385+if (markerEnd !== -1) {
386+return content.slice(contentStart, markerEnd).trim();
387+}
388+}
389+390+const surfaceMatch = /\n## Surface\n\n[^\n]*(?:\n|$)/u.exec(content);
391+if (!surfaceMatch?.index) {
392+return "";
393+}
394+const manualStart = surfaceMatch.index + surfaceMatch[0].length;
395+const relatedDocsStart = content.indexOf("\n## Related docs\n", manualStart);
396+const manualEnd = relatedDocsStart === -1 ? content.length : relatedDocsStart;
397+return content.slice(manualStart, manualEnd).trim();
398+}
399+400+function readManualReferenceSections(relativePath) {
401+const fullPath = path.join(ROOT, relativePath);
402+if (!fs.existsSync(fullPath)) {
403+return "";
404+}
405+return extractManualReferenceSections(fs.readFileSync(fullPath, "utf8"));
406+}
407+408+function renderManualReferenceSections(manualSections) {
409+if (!manualSections) {
410+return "";
411+}
412+return `${MANUAL_SECTION_START}
413+414+${manualSections}
415+416+${MANUAL_SECTION_END}`;
417+}
418+419+function renderReferencePage(record, manualSections = "") {
381420const relatedDocs = renderRelatedDocs(record);
382-const extraSections = PLUGIN_REFERENCE_EXTRA_SECTIONS.get(record.id) ?? "";
421+const manualBlock = renderManualReferenceSections(manualSections);
383422return `---
384423summary: "${record.description.replaceAll('"', '\\"')}"
385424read_when:
@@ -398,7 +437,7 @@ ${record.description}
398437399438## Surface
400439401-${record.surface}${extraSections ? `\n\n${extraSections}` : ""}${relatedDocs ? `\n\n${relatedDocs}` : ""}
440+${record.surface}${manualBlock ? `\n\n${manualBlock}` : ""}${relatedDocs ? `\n\n${relatedDocs}` : ""}
402441`;
403442}
404443@@ -493,9 +532,11 @@ function collectPluginRecords() {
493532function writeGeneratedDocs(records) {
494533fs.mkdirSync(path.join(ROOT, REFERENCE_DIR), { recursive: true });
495534for (const record of records) {
535+const relativePath = path.join(REFERENCE_DIR, `${record.id}.md`);
536+const manualSections = readManualReferenceSections(relativePath);
496537fs.writeFileSync(
497-path.join(ROOT, REFERENCE_DIR, `${record.id}.md`),
498-renderReferencePage(record),
538+path.join(ROOT, relativePath),
539+renderReferencePage(record, manualSections),
499540"utf8",
500541);
501542}
@@ -505,10 +546,10 @@ function writeGeneratedDocs(records) {
505546function readGeneratedDocs(records) {
506547return [
507548[REFERENCE_INDEX_PATH, renderReferenceIndex(records)],
508- ...records.map((record) => [
509-path.join(REFERENCE_DIR, `${record.id}.md`),
510-renderReferencePage(record),
511-]),
549+ ...records.map((record) => {
550+const relativePath = path.join(REFERENCE_DIR, `${record.id}.md`);
551+return [relativePath, renderReferencePage(record, readManualReferenceSections(relativePath))];
552+}),
512553];
513554}
514555此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。