🎉 init: 小龙的工作空间
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user