🎉 init: 小龙的工作空间

This commit is contained in:
大海
2026-06-06 10:40:48 +08:00
commit a188ee1426
3201 changed files with 231817 additions and 0 deletions
+120
View File
@@ -0,0 +1,120 @@
#!/usr/bin/env node
/**
* Guard 1: Memory Backend Guard
* Prevents proliferation beyond the allowed memory backends.
*
* → Architecture Freeze v2 (PR-1): docs/architecture-freeze-v2.md
* → Core: memory-core | Legacy: memory-wiki
*
* Allowed plugins (kind="memory" or has memory tools):
* - memory-core (primary — Core §2)
* - active-memory (recall injector — Core §2)
* - memory-wiki (legacy, allowed for now — Legacy §4)
* - Builtin/QMD (internal engine, not a plugin)
*
* FAIL: any new memory plugin appears
* PASS: within allowed list
*/
import { readdirSync, readFileSync, existsSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";
const OPENCLAW_HOME = process.env.OPENCLAW_HOME || "/opt/homebrew/lib/node_modules/openclaw";
const EXTENSIONS_DIR = join(OPENCLAW_HOME, "dist", "extensions");
// Allowed memory plugin IDs
const ALLOWED_MEMORY_PLUGINS = new Set([
"memory-core",
"active-memory",
"memory-wiki",
]);
// Plugin IDs that have memory contracts but are not "kind: memory"
const KNOWN_MEMORY_RELATED = new Set([
"memory-lancedb", // legacy, being deprecated
]);
function guardMemoryBackends() {
const issues = [];
const found = [];
if (!existsSync(EXTENSIONS_DIR)) {
issues.push({ level: "ERROR", msg: `Extensions dir not found: ${EXTENSIONS_DIR}` });
return { pass: false, found, issues };
}
const extDirs = readdirSync(EXTENSIONS_DIR, { withFileTypes: true })
.filter(d => d.isDirectory())
.map(d => d.name);
for (const extDir of extDirs) {
const pluginJsonPath = join(EXTENSIONS_DIR, extDir, "openclaw.plugin.json");
if (!existsSync(pluginJsonPath)) continue;
try {
const plugin = JSON.parse(readFileSync(pluginJsonPath, "utf8"));
const pluginId = plugin.id || extDir;
const kind = plugin.kind || "";
const contracts = plugin.contracts || {};
const tools = contracts.tools || [];
const memoryTools = tools.filter(t => t.startsWith("memory_") || t.startsWith("wiki_"));
const isMemoryPlugin =
kind === "memory" ||
tools.includes("memory_search") ||
tools.includes("memory_get") ||
memoryTools.length >= 2;
if (isMemoryPlugin) {
found.push({ id: pluginId, kind, memoryTools });
if (!ALLOWED_MEMORY_PLUGINS.has(pluginId) && !KNOWN_MEMORY_RELATED.has(pluginId)) {
issues.push({
level: "FAIL",
msg: `UNEXPECTED memory plugin: ${pluginId} (kind=${kind}, tools=${memoryTools.join(",")})`
});
}
}
} catch (e) {
issues.push({ level: "WARN", msg: `Could not parse ${pluginJsonPath}: ${e.message}` });
}
}
const pass = issues.filter(i => i.level === "FAIL").length === 0;
return { pass, found, issues };
}
// Run
const result = guardMemoryBackends();
console.log("");
console.log("═══════════════════════════════════════");
console.log(" Guard 1: Memory Backend Guard");
console.log("═══════════════════════════════════════");
console.log("");
if (result.found.length === 0) {
console.log(" No memory plugins found.");
} else {
console.log(` Memory plugins found: ${result.found.length}`);
for (const f of result.found) {
const status = ALLOWED_MEMORY_PLUGINS.has(f.id) ? "✓" :
KNOWN_MEMORY_RELATED.has(f.id) ? "⚠ (legacy)" : "✗ UNEXPECTED";
console.log(` ${status} ${f.id} (kind="${f.kind}", tools: ${f.memoryTools.join(", ")})`);
}
}
for (const issue of result.issues) {
console.log(` [${issue.level}] ${issue.msg}`);
}
if (result.pass) {
console.log("");
console.log(" ✓ PASS: memory backend count within allowed list");
process.exit(0);
} else {
console.log("");
console.log(" ✗ FAIL: unexpected memory backend(s) detected");
process.exit(1);
}