openclaw-hybrid-memory 2026.7.52 → 2026.7.53
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.
- package/cli/commands/manage/register-maintenance-orchestrator.ts +14 -6
- package/dist/cli/commands/manage/register-maintenance-orchestrator.js +4 -4
- package/dist/cli/commands/manage/register-maintenance-orchestrator.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { homedir } from "node:os";
|
|
7
7
|
import { dirname, join } from "node:path";
|
|
8
|
-
import {
|
|
8
|
+
import { stepGuardEligible } from "../../../services/cron-guard.js";
|
|
9
9
|
import {
|
|
10
10
|
effectiveCadenceLabel,
|
|
11
11
|
formatMaintenanceSummary,
|
|
@@ -128,12 +128,20 @@ export function registerMaintenanceOrchestratorCommands(maintenance: Chainable,
|
|
|
128
128
|
// Look up each requested name individually rather than filtering result.steps down to the
|
|
129
129
|
// matches — a name that belongs to a tier not requested (e.g. `cycle --include <nightly-step>
|
|
130
130
|
// --force`) or that --exclude also removed never produces a step result at all, so it would
|
|
131
|
-
// otherwise vanish from
|
|
132
|
-
// false "didn't run" report never firing (an even quieter version of the bug #2031 closes).
|
|
131
|
+
// otherwise vanish from a filtered list entirely and slip past a not-run check.
|
|
133
132
|
const requested = includeNames.map((name) => ({ name, result: result.steps.find((s) => s.name === name) }));
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
// "didn't run" = no result at all, a skipped_* status, or "deferred" (pushed before the
|
|
134
|
+
// runner was ever invoked — time budget exceeded or the rate-limit circuit breaker
|
|
135
|
+
// preemptively deferred it). "failed"/"rate_limited" DID invoke the runner, so they're
|
|
136
|
+
// excluded here; those are already reflected in process.exitCode via computeExitCode() above.
|
|
137
|
+
// Flag ANY requested step that didn't run, not just when all of them didn't — a partial
|
|
138
|
+
// --include run where only one of several explicitly-named steps silently didn't execute is
|
|
139
|
+
// exactly the false-success #2031 closes for the single-step case.
|
|
140
|
+
const notRun = requested.filter(
|
|
141
|
+
(r) => !r.result || r.result.status.startsWith("skipped") || r.result.status === "deferred",
|
|
142
|
+
);
|
|
143
|
+
if (notRun.length > 0) {
|
|
144
|
+
const detail = notRun
|
|
137
145
|
.map((r) =>
|
|
138
146
|
r.result
|
|
139
147
|
? `${r.name}: ${r.result.status} — ${r.result.summary}`
|
|
@@ -74,12 +74,12 @@ function registerMaintenanceOrchestratorCommands(maintenance, b) {
|
|
|
74
74
|
if (result.exitCode !== 0) process.exitCode = result.exitCode;
|
|
75
75
|
const includeNames = parseStepList(opts?.include);
|
|
76
76
|
if ((opts?.force || opts?.full) && includeNames?.length && !opts?.allowSkip) {
|
|
77
|
-
const
|
|
77
|
+
const notRun = includeNames.map((name) => ({
|
|
78
78
|
name,
|
|
79
79
|
result: result.steps.find((s) => s.name === name)
|
|
80
|
-
}));
|
|
81
|
-
if (
|
|
82
|
-
const detail =
|
|
80
|
+
})).filter((r) => !r.result || r.result.status.startsWith("skipped") || r.result.status === "deferred");
|
|
81
|
+
if (notRun.length > 0) {
|
|
82
|
+
const detail = notRun.map((r) => r.result ? `${r.name}: ${r.result.status} — ${r.result.summary}` : `${r.name}: no result (wrong tier, excluded, or unregistered runner)`).join("; ");
|
|
83
83
|
console.error(`maintenance ${result.tierLabel}: selected step(s) did not run (${detail}). Pass --allow-skip to treat this as a non-strict status check.`);
|
|
84
84
|
if (!process.exitCode) process.exitCode = 3;
|
|
85
85
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-maintenance-orchestrator.js","names":[],"sources":["../../../../cli/commands/manage/register-maintenance-orchestrator.ts"],"sourcesContent":["/**\n * Maintenance orchestrator CLI: cycle, nightly, full, steps.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { readStepGuardTimestampMs, stepGuardEligible } from \"../../../services/cron-guard.js\";\nimport {\n effectiveCadenceLabel,\n formatMaintenanceSummary,\n listMaintenanceSteps,\n resolveStepGuardIntervalMs,\n runMaintenanceOrchestrator,\n toOrchestratorRunSummary,\n} from \"../../../services/maintenance-orchestrator.js\";\nimport { atomicWriteFile } from \"../../../utils/atomic-write.js\";\nimport { formatTimestampUtcFromMs } from \"../../../utils/dates.js\";\nimport { type CommanderOptsParent, readHybridMemVerbose } from \"../../global-verbose.js\";\nimport { type Chainable, withExit } from \"../../shared.js\";\nimport type { ManageBindings } from \"./bindings.js\";\nimport { buildCliMaintenanceRunners } from \"./maintenance-step-runners.js\";\n\nfunction parseStepList(raw?: string): string[] | undefined {\n if (!raw?.trim()) return undefined;\n return raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nexport function registerMaintenanceOrchestratorCommands(maintenance: Chainable, b: ManageBindings): void {\n const openclawDir = join(homedir(), \".openclaw\");\n\n const runTier = async (\n tiers: Array<\"cycle\" | \"nightly\">,\n opts?: {\n dryRun?: boolean;\n force?: boolean;\n full?: boolean;\n verbose?: boolean;\n include?: string;\n exclude?: string;\n maxRuntimeMin?: string;\n json?: boolean;\n summaryOut?: string;\n allowSkip?: boolean;\n },\n ) => {\n const verbose = !!opts?.verbose;\n const runStartedMs = Date.now();\n const runStartedIso = new Date(runStartedMs).toISOString();\n if (process.env.HM_RUN_ID) {\n process.env.HM_ORCHESTRATOR_RUN_ID = process.env.HM_RUN_ID;\n }\n const memoryDir = b.resolvedSqlitePath ? dirname(b.resolvedSqlitePath) : join(homedir(), \".openclaw\", \"memory\");\n const backfillMarker = join(memoryDir, \".backfill-decay-done\");\n const runners = buildCliMaintenanceRunners(b, {\n verbose,\n backfillDecayMarker: backfillMarker,\n scanOverrides: { force: opts?.force, full: opts?.full },\n });\n // `> 0` (not just finite) — \"0\" is a truthy, finite string that would otherwise produce a\n // zero-minute budget, which the orchestrator's `elapsed >= maxRuntimeMs` check treats as\n // already-exceeded before the first step runs, deferring every step including the one the\n // operator asked for. Treat a non-positive value the same as \"no budget\", consistent with\n // guardIntervalMs <= 0 meaning \"always eligible\" elsewhere in this file.\n const parsedMaxRuntimeMin = opts?.maxRuntimeMin ? Number(opts.maxRuntimeMin) : undefined;\n const maxRuntimeMs =\n parsedMaxRuntimeMin !== undefined && Number.isFinite(parsedMaxRuntimeMin) && parsedMaxRuntimeMin > 0\n ? parsedMaxRuntimeMin * 60_000\n : undefined;\n\n const isJsonMode = opts?.json || !!opts?.summaryOut?.trim() || !!process.env.HM_SUMMARY?.trim();\n const log = isJsonMode ? (m: string) => console.error(m) : (m: string) => console.log(m);\n const warn = (m: string) => console.error(m);\n\n const result = await runMaintenanceOrchestrator(\n {\n cfg: b.cfg,\n runners,\n openclawDir,\n logger: { info: log, warn },\n oneTimeMarkerExists: (path) => existsSync(join(memoryDir, path)),\n journalDb: b.factsDb.getRawDb(),\n },\n {\n tiers,\n dryRun: opts?.dryRun,\n force: opts?.force || opts?.full,\n verbose,\n include: parseStepList(opts?.include),\n exclude: parseStepList(opts?.exclude),\n maxRuntimeMs,\n },\n );\n\n const orchestratorSummary = toOrchestratorRunSummary(result, {\n runId: result.runId,\n job: process.env.HM_JOB,\n startedAt: result.startedAt ?? runStartedIso,\n finishedAt: result.finishedAt,\n durationMs: result.durationMs ?? Date.now() - runStartedMs,\n });\n\n const summaryOutPath = opts?.summaryOut?.trim() || process.env.HM_SUMMARY?.trim();\n if (summaryOutPath) {\n atomicWriteFile(summaryOutPath, `${JSON.stringify(orchestratorSummary, null, 2)}\\n`);\n }\n\n if (opts?.json) {\n console.log(JSON.stringify(orchestratorSummary, null, 2));\n } else {\n const { summaryLine, lines } = formatMaintenanceSummary(result.tierLabel, result.steps);\n console.log(summaryLine);\n for (const line of lines) console.log(line);\n }\n if (result.exitCode !== 0) process.exitCode = result.exitCode;\n\n // An explicit, forced --include run (whether via the dedicated `step <name>` command or\n // `cycle`/`nightly`/`full --include x,y --force`) is a targeted \"run this now and verify it\"\n // diagnostic — computeExitCode() treats \"skipped\" as benign because it's normal cadence-guard\n // behavior in an ordinary full/nightly run, so it doesn't cover \"the step(s) I explicitly asked\n // for didn't execute\" (#2031). Scoped to include+force so ordinary unforced --include automation\n // (which can legitimately skip by cadence) keeps its existing exit-0-on-skip behavior.\n const includeNames = parseStepList(opts?.include);\n if ((opts?.force || opts?.full) && includeNames?.length && !opts?.allowSkip) {\n // Look up each requested name individually rather than filtering result.steps down to the\n // matches — a name that belongs to a tier not requested (e.g. `cycle --include <nightly-step>\n // --force`) or that --exclude also removed never produces a step result at all, so it would\n // otherwise vanish from `selected` entirely and slip past the \"every(...)\" check below with a\n // false \"didn't run\" report never firing (an even quieter version of the bug #2031 closes).\n const requested = includeNames.map((name) => ({ name, result: result.steps.find((s) => s.name === name) }));\n const didNotRun = requested.every((r) => !r.result || r.result.status.startsWith(\"skipped\"));\n if (didNotRun) {\n const detail = requested\n .map((r) =>\n r.result\n ? `${r.name}: ${r.result.status} — ${r.result.summary}`\n : `${r.name}: no result (wrong tier, excluded, or unregistered runner)`,\n )\n .join(\"; \");\n console.error(\n `maintenance ${result.tierLabel}: selected step(s) did not run (${detail}). ` +\n \"Pass --allow-skip to treat this as a non-strict status check.\",\n );\n if (!process.exitCode) process.exitCode = 3;\n }\n }\n\n return result;\n };\n\n const commonOptions = (cmd: Chainable) =>\n cmd\n .option(\"--dry-run\", \"List steps and guard status without executing\")\n .option(\"--force\", \"Bypass per-step guards and scan watermarks (not feature gates)\")\n .option(\"--full\", \"Alias for --force\")\n .option(\"-v, --verbose\", \"Detailed per-step output\")\n .option(\"--include <steps>\", \"Comma-separated step names to run only\")\n .option(\"--exclude <steps>\", \"Comma-separated step names to skip\")\n .option(\"--max-runtime-min <n>\", \"Optional time budget in minutes\")\n .option(\"--json\", \"Emit orchestrator run summary as JSON\")\n .option(\"--summary-out <path>\", \"Write orchestrator run summary JSON to path\")\n .option(\n \"--allow-skip\",\n \"With --include --force: exit 0 even if the selected step(s) didn't execute (locked/gated/guarded)\",\n );\n\n commonOptions(\n maintenance\n .command(\"cycle\")\n .description(\"Run cycle-tier maintenance steps (local gateway-native work)\")\n .action(\n withExit(async (opts, cmd?: CommanderOptsParent) => {\n await runTier([\"cycle\"], { ...opts, verbose: !!opts?.verbose || readHybridMemVerbose(cmd) });\n }),\n ),\n );\n\n commonOptions(\n maintenance\n .command(\"nightly\")\n .description(\"Run all non-cycle steps (staggered guards decide which execute)\")\n .action(\n withExit(async (opts, cmd?: CommanderOptsParent) => {\n await runTier([\"nightly\"], { ...opts, verbose: !!opts?.verbose || readHybridMemVerbose(cmd) });\n }),\n ),\n );\n\n commonOptions(\n maintenance\n .command(\"full\")\n .description(\"Run cycle + nightly tiers in sequence\")\n .action(\n withExit(async (opts, cmd?: CommanderOptsParent) => {\n await runTier([\"cycle\", \"nightly\"], { ...opts, verbose: !!opts?.verbose || readHybridMemVerbose(cmd) });\n }),\n ),\n );\n\n // `maintenance step <name>` runs exactly one named step in isolation (#2028). Named `step` (singular)\n // to avoid colliding with the `maintenance run` JobRun-inspection group and the `steps` list command.\n //\n // Bounded by default (#2032): this command is meant for isolated diagnostic/verification runs, so\n // unlike cycle/nightly/full it caps runtime unless the operator overrides --max-runtime-min. Long\n // CPU/LLM-bound steps (e.g. passive-observer scanning a large first-run backlog) already consult the\n // orchestrator-wide deadline between sessions/chunks, so this cap actually bounds wall-clock time.\n const DEFAULT_STEP_MAX_RUNTIME_MIN = \"15\";\n\n commonOptions(\n maintenance\n .command(\"step <step>\")\n .description(\n \"Run exactly one named maintenance step in isolation (bypasses that step's cadence guard). Use `maintenance steps` to list valid names.\",\n ),\n ).action(\n withExit(async (step: string, opts, cmd?: CommanderOptsParent) => {\n const stepName = step?.trim();\n const validNames = listMaintenanceSteps().map((s) => s.name);\n if (!stepName || !validNames.includes(stepName)) {\n console.error(`Unknown maintenance step: ${stepName || \"(none)\"}`);\n console.error(`Valid steps (${validNames.length}):`);\n for (const name of validNames) console.error(` ${name}`);\n process.exitCode = 1;\n return;\n }\n // Force so the targeted step actually runs even if its cadence guard has not expired (this\n // command is an explicit \"run this step now\" diagnostic). include=[step] across both tiers\n // means the orchestrator executes ONLY that step and no unrelated stages (#2028). runTier()\n // itself checks whether this forced, explicitly-included step actually executed (#2031).\n await runTier([\"cycle\", \"nightly\"], {\n ...opts,\n include: stepName,\n force: true,\n maxRuntimeMin: opts?.maxRuntimeMin ?? DEFAULT_STEP_MAX_RUNTIME_MIN,\n verbose: !!opts?.verbose || readHybridMemVerbose(cmd),\n });\n }),\n );\n\n maintenance\n .command(\"steps\")\n .description(\"List registered maintenance steps with tier, guard interval, and cadence\")\n .option(\"--json\", \"Output JSON\")\n .action(\n withExit(async (opts?: { json?: boolean }) => {\n const rows = listMaintenanceSteps().map((step) => {\n const guardMs = resolveStepGuardIntervalMs(step, b.cfg);\n const guard = stepGuardEligible(step.name, guardMs, openclawDir);\n return {\n name: step.name,\n tier: step.tier,\n guardIntervalMs: guardMs,\n cadence: effectiveCadenceLabel(guardMs),\n llmTier: step.llmTier,\n dependsOn: step.dependsOn ?? [],\n featureGate: step.featureGate ? step.featureGate(b.cfg) : true,\n lastRunAt: guard.lastRunMs ? formatTimestampUtcFromMs(guard.lastRunMs) : null,\n nextEligibleAt: guard.nextEligibleMs ? formatTimestampUtcFromMs(guard.nextEligibleMs) : null,\n eligibleNow: guard.eligible,\n };\n });\n if (opts?.json) {\n console.log(JSON.stringify(rows, null, 2));\n return;\n }\n console.log(`Maintenance steps (${rows.length} registered):`);\n for (const row of rows) {\n const gate = row.featureGate ? \"\" : \" [gate:off]\";\n console.log(\n ` ${row.name.padEnd(28)} ${row.tier.padEnd(8)} ${row.cadence.padEnd(18)} llm=${row.llmTier}${gate}${row.eligibleNow ? \" *due*\" : \"\"}`,\n );\n }\n }),\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"register-maintenance-orchestrator.js","names":[],"sources":["../../../../cli/commands/manage/register-maintenance-orchestrator.ts"],"sourcesContent":["/**\n * Maintenance orchestrator CLI: cycle, nightly, full, steps.\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { stepGuardEligible } from \"../../../services/cron-guard.js\";\nimport {\n effectiveCadenceLabel,\n formatMaintenanceSummary,\n listMaintenanceSteps,\n resolveStepGuardIntervalMs,\n runMaintenanceOrchestrator,\n toOrchestratorRunSummary,\n} from \"../../../services/maintenance-orchestrator.js\";\nimport { atomicWriteFile } from \"../../../utils/atomic-write.js\";\nimport { formatTimestampUtcFromMs } from \"../../../utils/dates.js\";\nimport { type CommanderOptsParent, readHybridMemVerbose } from \"../../global-verbose.js\";\nimport { type Chainable, withExit } from \"../../shared.js\";\nimport type { ManageBindings } from \"./bindings.js\";\nimport { buildCliMaintenanceRunners } from \"./maintenance-step-runners.js\";\n\nfunction parseStepList(raw?: string): string[] | undefined {\n if (!raw?.trim()) return undefined;\n return raw\n .split(\",\")\n .map((s) => s.trim())\n .filter(Boolean);\n}\n\nexport function registerMaintenanceOrchestratorCommands(maintenance: Chainable, b: ManageBindings): void {\n const openclawDir = join(homedir(), \".openclaw\");\n\n const runTier = async (\n tiers: Array<\"cycle\" | \"nightly\">,\n opts?: {\n dryRun?: boolean;\n force?: boolean;\n full?: boolean;\n verbose?: boolean;\n include?: string;\n exclude?: string;\n maxRuntimeMin?: string;\n json?: boolean;\n summaryOut?: string;\n allowSkip?: boolean;\n },\n ) => {\n const verbose = !!opts?.verbose;\n const runStartedMs = Date.now();\n const runStartedIso = new Date(runStartedMs).toISOString();\n if (process.env.HM_RUN_ID) {\n process.env.HM_ORCHESTRATOR_RUN_ID = process.env.HM_RUN_ID;\n }\n const memoryDir = b.resolvedSqlitePath ? dirname(b.resolvedSqlitePath) : join(homedir(), \".openclaw\", \"memory\");\n const backfillMarker = join(memoryDir, \".backfill-decay-done\");\n const runners = buildCliMaintenanceRunners(b, {\n verbose,\n backfillDecayMarker: backfillMarker,\n scanOverrides: { force: opts?.force, full: opts?.full },\n });\n // `> 0` (not just finite) — \"0\" is a truthy, finite string that would otherwise produce a\n // zero-minute budget, which the orchestrator's `elapsed >= maxRuntimeMs` check treats as\n // already-exceeded before the first step runs, deferring every step including the one the\n // operator asked for. Treat a non-positive value the same as \"no budget\", consistent with\n // guardIntervalMs <= 0 meaning \"always eligible\" elsewhere in this file.\n const parsedMaxRuntimeMin = opts?.maxRuntimeMin ? Number(opts.maxRuntimeMin) : undefined;\n const maxRuntimeMs =\n parsedMaxRuntimeMin !== undefined && Number.isFinite(parsedMaxRuntimeMin) && parsedMaxRuntimeMin > 0\n ? parsedMaxRuntimeMin * 60_000\n : undefined;\n\n const isJsonMode = opts?.json || !!opts?.summaryOut?.trim() || !!process.env.HM_SUMMARY?.trim();\n const log = isJsonMode ? (m: string) => console.error(m) : (m: string) => console.log(m);\n const warn = (m: string) => console.error(m);\n\n const result = await runMaintenanceOrchestrator(\n {\n cfg: b.cfg,\n runners,\n openclawDir,\n logger: { info: log, warn },\n oneTimeMarkerExists: (path) => existsSync(join(memoryDir, path)),\n journalDb: b.factsDb.getRawDb(),\n },\n {\n tiers,\n dryRun: opts?.dryRun,\n force: opts?.force || opts?.full,\n verbose,\n include: parseStepList(opts?.include),\n exclude: parseStepList(opts?.exclude),\n maxRuntimeMs,\n },\n );\n\n const orchestratorSummary = toOrchestratorRunSummary(result, {\n runId: result.runId,\n job: process.env.HM_JOB,\n startedAt: result.startedAt ?? runStartedIso,\n finishedAt: result.finishedAt,\n durationMs: result.durationMs ?? Date.now() - runStartedMs,\n });\n\n const summaryOutPath = opts?.summaryOut?.trim() || process.env.HM_SUMMARY?.trim();\n if (summaryOutPath) {\n atomicWriteFile(summaryOutPath, `${JSON.stringify(orchestratorSummary, null, 2)}\\n`);\n }\n\n if (opts?.json) {\n console.log(JSON.stringify(orchestratorSummary, null, 2));\n } else {\n const { summaryLine, lines } = formatMaintenanceSummary(result.tierLabel, result.steps);\n console.log(summaryLine);\n for (const line of lines) console.log(line);\n }\n if (result.exitCode !== 0) process.exitCode = result.exitCode;\n\n // An explicit, forced --include run (whether via the dedicated `step <name>` command or\n // `cycle`/`nightly`/`full --include x,y --force`) is a targeted \"run this now and verify it\"\n // diagnostic — computeExitCode() treats \"skipped\" as benign because it's normal cadence-guard\n // behavior in an ordinary full/nightly run, so it doesn't cover \"the step(s) I explicitly asked\n // for didn't execute\" (#2031). Scoped to include+force so ordinary unforced --include automation\n // (which can legitimately skip by cadence) keeps its existing exit-0-on-skip behavior.\n const includeNames = parseStepList(opts?.include);\n if ((opts?.force || opts?.full) && includeNames?.length && !opts?.allowSkip) {\n // Look up each requested name individually rather than filtering result.steps down to the\n // matches — a name that belongs to a tier not requested (e.g. `cycle --include <nightly-step>\n // --force`) or that --exclude also removed never produces a step result at all, so it would\n // otherwise vanish from a filtered list entirely and slip past a not-run check.\n const requested = includeNames.map((name) => ({ name, result: result.steps.find((s) => s.name === name) }));\n // \"didn't run\" = no result at all, a skipped_* status, or \"deferred\" (pushed before the\n // runner was ever invoked — time budget exceeded or the rate-limit circuit breaker\n // preemptively deferred it). \"failed\"/\"rate_limited\" DID invoke the runner, so they're\n // excluded here; those are already reflected in process.exitCode via computeExitCode() above.\n // Flag ANY requested step that didn't run, not just when all of them didn't — a partial\n // --include run where only one of several explicitly-named steps silently didn't execute is\n // exactly the false-success #2031 closes for the single-step case.\n const notRun = requested.filter(\n (r) => !r.result || r.result.status.startsWith(\"skipped\") || r.result.status === \"deferred\",\n );\n if (notRun.length > 0) {\n const detail = notRun\n .map((r) =>\n r.result\n ? `${r.name}: ${r.result.status} — ${r.result.summary}`\n : `${r.name}: no result (wrong tier, excluded, or unregistered runner)`,\n )\n .join(\"; \");\n console.error(\n `maintenance ${result.tierLabel}: selected step(s) did not run (${detail}). ` +\n \"Pass --allow-skip to treat this as a non-strict status check.\",\n );\n if (!process.exitCode) process.exitCode = 3;\n }\n }\n\n return result;\n };\n\n const commonOptions = (cmd: Chainable) =>\n cmd\n .option(\"--dry-run\", \"List steps and guard status without executing\")\n .option(\"--force\", \"Bypass per-step guards and scan watermarks (not feature gates)\")\n .option(\"--full\", \"Alias for --force\")\n .option(\"-v, --verbose\", \"Detailed per-step output\")\n .option(\"--include <steps>\", \"Comma-separated step names to run only\")\n .option(\"--exclude <steps>\", \"Comma-separated step names to skip\")\n .option(\"--max-runtime-min <n>\", \"Optional time budget in minutes\")\n .option(\"--json\", \"Emit orchestrator run summary as JSON\")\n .option(\"--summary-out <path>\", \"Write orchestrator run summary JSON to path\")\n .option(\n \"--allow-skip\",\n \"With --include --force: exit 0 even if the selected step(s) didn't execute (locked/gated/guarded)\",\n );\n\n commonOptions(\n maintenance\n .command(\"cycle\")\n .description(\"Run cycle-tier maintenance steps (local gateway-native work)\")\n .action(\n withExit(async (opts, cmd?: CommanderOptsParent) => {\n await runTier([\"cycle\"], { ...opts, verbose: !!opts?.verbose || readHybridMemVerbose(cmd) });\n }),\n ),\n );\n\n commonOptions(\n maintenance\n .command(\"nightly\")\n .description(\"Run all non-cycle steps (staggered guards decide which execute)\")\n .action(\n withExit(async (opts, cmd?: CommanderOptsParent) => {\n await runTier([\"nightly\"], { ...opts, verbose: !!opts?.verbose || readHybridMemVerbose(cmd) });\n }),\n ),\n );\n\n commonOptions(\n maintenance\n .command(\"full\")\n .description(\"Run cycle + nightly tiers in sequence\")\n .action(\n withExit(async (opts, cmd?: CommanderOptsParent) => {\n await runTier([\"cycle\", \"nightly\"], { ...opts, verbose: !!opts?.verbose || readHybridMemVerbose(cmd) });\n }),\n ),\n );\n\n // `maintenance step <name>` runs exactly one named step in isolation (#2028). Named `step` (singular)\n // to avoid colliding with the `maintenance run` JobRun-inspection group and the `steps` list command.\n //\n // Bounded by default (#2032): this command is meant for isolated diagnostic/verification runs, so\n // unlike cycle/nightly/full it caps runtime unless the operator overrides --max-runtime-min. Long\n // CPU/LLM-bound steps (e.g. passive-observer scanning a large first-run backlog) already consult the\n // orchestrator-wide deadline between sessions/chunks, so this cap actually bounds wall-clock time.\n const DEFAULT_STEP_MAX_RUNTIME_MIN = \"15\";\n\n commonOptions(\n maintenance\n .command(\"step <step>\")\n .description(\n \"Run exactly one named maintenance step in isolation (bypasses that step's cadence guard). Use `maintenance steps` to list valid names.\",\n ),\n ).action(\n withExit(async (step: string, opts, cmd?: CommanderOptsParent) => {\n const stepName = step?.trim();\n const validNames = listMaintenanceSteps().map((s) => s.name);\n if (!stepName || !validNames.includes(stepName)) {\n console.error(`Unknown maintenance step: ${stepName || \"(none)\"}`);\n console.error(`Valid steps (${validNames.length}):`);\n for (const name of validNames) console.error(` ${name}`);\n process.exitCode = 1;\n return;\n }\n // Force so the targeted step actually runs even if its cadence guard has not expired (this\n // command is an explicit \"run this step now\" diagnostic). include=[step] across both tiers\n // means the orchestrator executes ONLY that step and no unrelated stages (#2028). runTier()\n // itself checks whether this forced, explicitly-included step actually executed (#2031).\n await runTier([\"cycle\", \"nightly\"], {\n ...opts,\n include: stepName,\n force: true,\n maxRuntimeMin: opts?.maxRuntimeMin ?? DEFAULT_STEP_MAX_RUNTIME_MIN,\n verbose: !!opts?.verbose || readHybridMemVerbose(cmd),\n });\n }),\n );\n\n maintenance\n .command(\"steps\")\n .description(\"List registered maintenance steps with tier, guard interval, and cadence\")\n .option(\"--json\", \"Output JSON\")\n .action(\n withExit(async (opts?: { json?: boolean }) => {\n const rows = listMaintenanceSteps().map((step) => {\n const guardMs = resolveStepGuardIntervalMs(step, b.cfg);\n const guard = stepGuardEligible(step.name, guardMs, openclawDir);\n return {\n name: step.name,\n tier: step.tier,\n guardIntervalMs: guardMs,\n cadence: effectiveCadenceLabel(guardMs),\n llmTier: step.llmTier,\n dependsOn: step.dependsOn ?? [],\n featureGate: step.featureGate ? step.featureGate(b.cfg) : true,\n lastRunAt: guard.lastRunMs ? formatTimestampUtcFromMs(guard.lastRunMs) : null,\n nextEligibleAt: guard.nextEligibleMs ? formatTimestampUtcFromMs(guard.nextEligibleMs) : null,\n eligibleNow: guard.eligible,\n };\n });\n if (opts?.json) {\n console.log(JSON.stringify(rows, null, 2));\n return;\n }\n console.log(`Maintenance steps (${rows.length} registered):`);\n for (const row of rows) {\n const gate = row.featureGate ? \"\" : \" [gate:off]\";\n console.log(\n ` ${row.name.padEnd(28)} ${row.tier.padEnd(8)} ${row.cadence.padEnd(18)} llm=${row.llmTier}${gate}${row.eligibleNow ? \" *due*\" : \"\"}`,\n );\n }\n }),\n );\n}\n"],"mappings":"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"}
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-hybrid-memory",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.53",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "openclaw-hybrid-memory",
|
|
9
|
-
"version": "2026.7.
|
|
9
|
+
"version": "2026.7.53",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@lancedb/lancedb": "^0.30.0",
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openclaw-hybrid-memory",
|
|
3
|
-
"version": "2026.7.
|
|
3
|
+
"version": "2026.7.53",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Give your OpenClaw agent lasting memory: structured facts, semantic search, auto-capture & recall, decay, optional credential vault. Part of Hybrid Memory v3.",
|
|
6
6
|
"files": [
|