🎉 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
+472
View File
@@ -0,0 +1,472 @@
#!/usr/bin/env node
/**
* PR-C Deprecation Check Script
* Scans OpenClaw config and plugin state for deprecated modules.
*
* Run: node scripts/check-deprecations.mjs
*
* Checks:
* 1. Active Memory blocking mode
* 2. Dreaming REM phase enabled
* 3. Dream Diary generation
* 4. QMD search mode / QMD engine references
* 5. Honcho memory plugin enabled
* 6. LanceDB memory plugin enabled
* 7. memory-wiki plugin loaded
* 8. Commitments auto-infer
* 9. Grounded Backfill / REM Backfill CLI usage
*/
import { readFileSync, existsSync, readdirSync } from "node:fs";
import { join } from "node:path";
import { homedir } from "node:os";
import { warnOnce, warnMany } from "./lib/deprecation-warning.mjs";
const AGENTS_HOME = join(homedir(), ".openclaw");
const CONFIG_PATH = join(AGENTS_HOME, "openclaw.json");
const OPENCLAW_HOME = process.env.OPENCLAW_HOME || "/opt/homebrew/lib/node_modules/openclaw";
const EXTENSIONS_DIR = join(OPENCLAW_HOME, "dist", "extensions");
// Load user config
function loadConfig() {
if (!existsSync(CONFIG_PATH)) return null;
try {
return JSON.parse(readFileSync(CONFIG_PATH, "utf8"));
} catch {
return null;
}
}
// Load plugin entry for a given extension id
function loadPlugin(id) {
const pluginJsonPath = join(EXTENSIONS_DIR, id, "openclaw.plugin.json");
if (!existsSync(pluginJsonPath)) return null;
try {
return JSON.parse(readFileSync(pluginJsonPath, "utf8"));
} catch {
return null;
}
}
// Check if a plugin is enabled in user config
function isPluginEnabled(config, pluginId) {
const entries = config?.plugins?.entries;
if (!entries) return false;
const entry = entries[pluginId];
if (!entry) return false;
return entry.enabled !== false;
}
// ─── Check Functions ────────────────────────────────
function checkActiveMemoryBlocking(config) {
const warnings = [];
const entry = config?.plugins?.entries?.["active-memory"];
if (!entry) return warnings;
const mode = entry.config?.mode;
if (mode === "blocking") {
warnings.push({
key: "active-memory.blocking",
message: "active-memory blocking mode is deprecated. Set mode to 'precompute' instead."
});
}
return warnings;
}
function checkDreamingRemPhase(config) {
const warnings = [];
const entry = config?.plugins?.entries?.["memory-core"];
if (!entry) return warnings;
const dreaming = entry.config?.dreaming;
if (!dreaming) return warnings;
// Check REM phase enabled
const remEnabled = dreaming?.phases?.rem?.enabled;
if (remEnabled === true) {
warnings.push({
key: "dreaming.rem-phase",
message: "Dreaming REM phase is deprecated. It will be replaced by Collect/Promote."
});
}
return warnings;
}
function checkDreamDiary(config) {
const warnings = [];
const entry = config?.plugins?.entries?.["memory-core"];
if (!entry) return warnings;
const dreaming = entry.config?.dreaming;
if (!dreaming) return warnings;
// Dream Diary is implied by REM phase or certain storage modes
const storage = dreaming?.storage;
const hasDiaryMode = storage?.mode === "separate" || storage?.mode === "both";
const separateReports = storage?.separateReports === true;
if (hasDiaryMode || separateReports) {
warnings.push({
key: "dreaming.dream-diary",
message: "Dream Diary generation is deprecated and will be removed."
});
}
// Also check if dreaming has a configured model (used for diary)
if (dreaming?.model) {
warnings.push({
key: "dreaming.diary-model",
message: "Dreaming diary model override is deprecated."
});
}
return warnings;
}
function checkQmdReference(config) {
const warnings = [];
// Check memory search config for QMD
const memorySearch = config?.agents?.defaults?.memorySearch;
if (memorySearch?.provider === "qmd" || memorySearch?.backend === "qmd") {
warnings.push({
key: "qmd.memory-search",
message: "QMD memory engine is legacy. Migrate to Builtin MemoryCore."
});
}
// Check active-memory QMD reference
const activeCfg = config?.plugins?.entries?.["active-memory"]?.config;
if (activeCfg?.qmd?.searchMode) {
warnings.push({
key: "qmd.active-memory",
message: "QMD search mode in active-memory is legacy. Remove qmd config."
});
}
return warnings;
}
function checkHonchoLanceDB(config) {
const warnings = [];
// Check if honcho or lancedb plugins are loaded
const pluginEntries = config?.plugins?.entries || {};
if (pluginEntries["memory-honcho"]?.enabled !== false && isPluginInExtensions("honcho")) {
warnings.push({
key: "honcho.plugin",
message: "Honcho memory plugin is legacy. Existing data readable during migration."
});
}
if (pluginEntries["memory-lancedb"]?.enabled !== false && isPluginInExtensions("lancedb")) {
warnings.push({
key: "lancedb.plugin",
message: "LanceDB memory plugin is legacy. Existing data readable during migration."
});
}
return warnings;
}
function checkMemoryWiki(config) {
const warnings = [];
const entry = config?.plugins?.entries?.["memory-wiki"];
if (entry?.enabled !== false) {
// Check if memory-wiki extension exists and isn't disabled
const wikiPlugin = loadPlugin("memory-wiki");
if (wikiPlugin) {
warnings.push({
key: "memory-wiki.plugin",
message: "memory-wiki plugin is legacy. wiki_search/wiki_get/wiki_apply/wiki_lint/wiki_status remain available during migration."
});
}
}
return warnings;
}
function checkCommitmentsAutoInfer(config) {
const warnings = [];
// Commitments auto-infer is part of the session-memory bundled module
const commitments = config?.commitments;
if (commitments?.autoInfer === true) {
warnings.push({
key: "commitments.auto-infer",
message: "Commitments auto-infer is deprecated. Use explicit cron tasks instead."
});
}
return warnings;
}
function checkGroundedBackfill(config) {
const warnings = [];
// Grounded Backfill is a CLI feature — we check if related config exists
const dreaming = config?.plugins?.entries?.["memory-core"]?.config?.dreaming;
if (!dreaming) return warnings;
// If dreaming has unusual storage paths that suggest backfill usage
const storage = dreaming?.storage;
if (storage?.mode === "separate") {
warnings.push({
key: "backfill.storage-mode",
message: "Grounded Backfill / REM Backfill is deprecated and will not evolve further."
});
}
return warnings;
}
// ─── Helpers ────────────────────────────────────────
function isPluginInExtensions(name) {
try {
const dirs = readdirSync(EXTENSIONS_DIR, { withFileTypes: true })
.filter(d => d.isDirectory());
for (const d of dirs) {
if (d.name.includes(name)) return true;
// Check plugin.json
const pluginPath = join(EXTENSIONS_DIR, d.name, "openclaw.plugin.json");
if (existsSync(pluginPath)) {
const plugin = JSON.parse(readFileSync(pluginPath, "utf8"));
if (plugin.id?.includes(name)) return true;
}
}
} catch {}
return false;
}
// ─── Legacy Registry (PR-1 Freeze) ───────────────────
// Maps deprecation keys to replacement info and migration window.
// Used to enhance check-deprecations output.
const LEGACY_REGISTRY = {
"active-memory.blocking": {
module: "active-memory blocking mode",
status: "Active. Deprecated.",
replacement: 'Set mode to "precompute" in active-memory config',
migrationWindow: "90 days from 2026-06-04",
removalTarget: "2026-09-04",
},
"dreaming.rem-phase": {
module: "Dreaming REM phase",
status: "Active. Deprecated.",
replacement: "Collect/Promote two-phase dreaming (PR-5)",
migrationWindow: "90 days from 2026-06-04",
removalTarget: "2026-09-04",
},
"dreaming.dream-diary": {
module: "Dream Diary",
status: "Active. Deprecated.",
replacement: "Inline dreaming output (no separate diary storage)",
migrationWindow: "90 days from 2026-06-04",
removalTarget: "2026-09-04",
},
"dreaming.diary-model": {
module: "Dream Diary model override",
status: "Active. Deprecated.",
replacement: "Use default dreaming model",
migrationWindow: "90 days from 2026-06-04",
removalTarget: "2026-09-04",
},
"qmd.memory-search": {
module: "QMD memory search engine",
status: "Active. Deprecated.",
replacement: "Builtin MemoryCore FTS5 + BM25",
migrationWindow: "90 days from 2026-06-04",
removalTarget: "2026-09-04",
},
"qmd.active-memory": {
module: "QMD active-memory search mode",
status: "Active. Deprecated.",
replacement: "Remove qmd config block from active-memory",
migrationWindow: "90 days from 2026-06-04",
removalTarget: "2026-09-04",
},
"honcho.plugin": {
module: "Honcho memory plugin",
status: "Legacy. Data readable during migration.",
replacement: "memory-core (FTS5 + BM25)",
migrationWindow: "60 days from 2026-06-04",
removalTarget: "2026-08-04",
},
"lancedb.plugin": {
module: "LanceDB memory plugin",
status: "Legacy. Data readable during migration.",
replacement: "memory-core (FTS5 + BM25)",
migrationWindow: "60 days from 2026-06-04",
removalTarget: "2026-08-04",
},
"memory-wiki.plugin": {
module: "memory-wiki plugin",
status: "Active. Deprecated.",
replacement: "memory-core wiki compilation",
migrationWindow: "90 days from 2026-06-04",
removalTarget: "2026-09-04",
},
"commitments.auto-infer": {
module: "Commitments auto-infer",
status: "Active. Deprecated.",
replacement: "Explicit cron tasks (use cron tool)",
migrationWindow: "90 days from 2026-06-04",
removalTarget: "2026-09-04",
},
"backfill.storage-mode": {
module: "Grounded Backfill / REM Backfill CLI",
status: "Active. Deprecated.",
replacement: "No replacement. Stop using immediately.",
migrationWindow: "Immediate — effective 2026-06-04",
removalTarget: "2026-06-04",
},
};
function getLegacyInfo(key) {
return LEGACY_REGISTRY[key] || null;
}
function formatLegacyTable(warnings) {
// Group warnings by their legacy info
const seen = new Set();
const rows = [];
for (const w of warnings) {
if (seen.has(w.key)) continue;
seen.add(w.key);
const info = LEGACY_REGISTRY[w.key] || {
module: w.key,
status: "Unknown",
replacement: "N/A",
migrationWindow: "N/A",
removalTarget: "N/A",
};
rows.push(info);
}
return rows;
}
// ─── Main ────────────────────────────────────────────
function runAllChecks() {
const config = loadConfig();
const allWarnings = [];
const checkResults = [];
if (!config) {
console.warn("[DEPRECATED][OpenClaw v2] config: Could not load openclaw.json");
return { warnings: [], results: [{ name: "config", error: "Could not load config" }] };
}
const checks = [
{ name: "active-memory blocking mode", fn: () => checkActiveMemoryBlocking(config) },
{ name: "dreaming REM phase", fn: () => checkDreamingRemPhase(config) },
{ name: "dream diary", fn: () => checkDreamDiary(config) },
{ name: "QMD reference", fn: () => checkQmdReference(config) },
{ name: "Honcho / LanceDB", fn: () => checkHonchoLanceDB(config) },
{ name: "memory-wiki", fn: () => checkMemoryWiki(config) },
{ name: "commitments auto-infer", fn: () => checkCommitmentsAutoInfer(config) },
{ name: "grounded backfill", fn: () => checkGroundedBackfill(config) },
];
console.log("");
console.log("═══════════════════════════════════════");
console.log(" PR-C: Deprecation Warning Check");
console.log(` Architecture Freeze: 2026-06-04`);
console.log(` ${new Date().toISOString()}`);
console.log("═══════════════════════════════════════");
console.log("");
for (const check of checks) {
try {
const warnings = check.fn();
checkResults.push({ name: check.name, warnings, passed: warnings.length === 0 });
allWarnings.push(...warnings);
} catch (e) {
checkResults.push({ name: check.name, warnings: [], passed: false, error: e.message });
}
}
// Emit warnings (deduplicated)
if (allWarnings.length > 0) {
console.log(" ⚠ Deprecation warnings found:\n");
for (const w of allWarnings) {
warnOnce(w.key, w.message);
}
} else {
console.log(" ✓ No deprecation warnings found.");
}
// Summary
console.log("");
const checksWithWarnings = checkResults.filter(c => c.warnings.length > 0);
const checksFailed = checkResults.filter(c => c.error);
console.log(` Checks run: ${checks.length}`);
console.log(` With warnings: ${checksWithWarnings.length}`);
console.log(` Total warnings: ${allWarnings.length}`);
if (checksFailed.length > 0) {
console.log(` Check errors: ${checksFailed.length}`);
for (const c of checksFailed) {
console.log(`${c.name}: ${c.error}`);
}
}
// ─── PR-1 Enhanced Output: Legacy Table ─────────────
if (allWarnings.length > 0) {
const legacyRows = formatLegacyTable(allWarnings);
console.log("");
console.log(" ─────────────────────────────────────────────");
console.log(" Deprecated Modules (PR-1 Legacy Inventory):");
console.log(" ─────────────────────────────────────────────");
console.log("");
for (const row of legacyRows) {
console.log(` Module: ${row.module}`);
console.log(` Status: ${row.status}`);
console.log(` Replacement: ${row.replacement}`);
console.log(` Migration Window: ${row.migrationWindow}`);
console.log(` Removal Target: ${row.removalTarget}`);
console.log("");
}
// Migration timeline
console.log(" ─────────────────────────────────────────────");
console.log(" Migration Timeline:");
console.log("");
console.log(" Day 0 2026-06-04 Freeze active");
console.log(" Day 30 2026-07-04 Legacy warnings active");
console.log(" Day 60 2026-08-04 Honcho/LanceDB read-only cutoff");
console.log(" Day 90 2026-09-04 All legacy modules removed");
console.log("");
// Per-module key list for scripting
console.log(" Deprecated keys:");
for (const w of allWarnings) {
const info = LEGACY_REGISTRY[w.key];
const target = info ? info.removalTarget : "N/A";
console.log(`${w.key} (removal: ${target})`);
}
}
console.log("");
return { warnings: allWarnings, results: checkResults };
}
// Run if called as main
if (process.argv[1]?.includes("check-deprecations")) {
const result = runAllChecks();
process.exit(0); // Never fail on deprecation warnings
}
export { runAllChecks, loadConfig, LEGACY_REGISTRY, getLegacyInfo, formatLegacyTable,
checkActiveMemoryBlocking, checkDreamingRemPhase, checkDreamDiary,
checkQmdReference, checkHonchoLanceDB, checkMemoryWiki,
checkCommitmentsAutoInfer, checkGroundedBackfill };