agenr 0.9.86 → 0.9.88

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/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.88] - 2026-03-12
4
+
5
+ ### Fixed
6
+
7
+ - Updated the OpenClaw plugin for `openclaw@2026.3.11` by migrating agenr command lifecycle handling from the stale typed `api.on("command", ...)` path to named `api.registerHook(["command:new", "command:reset"], ...)` registration, restoring clean command-hook compatibility and removing current-release hook registration warnings.
8
+ - Removed temporary OpenClaw prompt-build debug instrumentation after confirming `prependSystemContext` and `prependContext` injection is functioning in the sandbox.
9
+
10
+ ## [0.9.87] - 2026-03-12
11
+
12
+ ### Changed
13
+
14
+ - Added an OpenClaw `prependSystemContext` agenr-first memory doctrine that supersedes legacy markdown-memory guidance without replacing OpenClaw's dynamically built system prompt.
15
+ - Split OpenClaw prompt-build injection into stable doctrine (`prependSystemContext`) and dynamic recalled memory (`prependContext`), preserving existing session-start, mid-session, signal, and nudge behavior.
16
+ - Added the `openclawMemoryDoctrine.enabled` plugin config gate, default-enabled, so operators can disable the stable doctrine block without turning off dynamic memory injection.
17
+ - Updated OpenClaw plugin docs, architecture notes, and regression coverage to reflect the new doctrine/system-context path and its no-op-session behavior.
18
+
3
19
  ## [0.9.86] - 2026-03-12
4
20
 
5
21
  ### Fixed
@@ -23,7 +23,7 @@ import {
23
23
  runSimpleStream,
24
24
  toErrorMessage,
25
25
  walCheckpoint
26
- } from "./chunk-2WXGL442.js";
26
+ } from "./chunk-NQQUVGQO.js";
27
27
  import {
28
28
  MILLISECONDS_PER_DAY,
29
29
  parseDaysBetween,
@@ -39,7 +39,7 @@ import {
39
39
  toErrorMessage,
40
40
  updateRecallMetadata,
41
41
  walCheckpoint
42
- } from "./chunk-2WXGL442.js";
42
+ } from "./chunk-NQQUVGQO.js";
43
43
  import {
44
44
  toNumber,
45
45
  toRowsAffected,
package/dist/cli-main.js CHANGED
@@ -42,7 +42,7 @@ import {
42
42
  runStoreService,
43
43
  runTraceService,
44
44
  ui
45
- } from "./chunk-3DJDQDWN.js";
45
+ } from "./chunk-JK4M3SD3.js";
46
46
  import {
47
47
  ConflictAlreadyResolvedError,
48
48
  REVIEW_QUEUE_PATH,
@@ -57,7 +57,7 @@ import {
57
57
  showFlaggedMerges,
58
58
  toConflictLogRow,
59
59
  toRecord
60
- } from "./chunk-SC2E7CS3.js";
60
+ } from "./chunk-3WWWJ6MN.js";
61
61
  import {
62
62
  APP_VERSION,
63
63
  DEFAULT_AROUND_RADIUS_DAYS,
@@ -165,7 +165,7 @@ import {
165
165
  walCheckpoint,
166
166
  warnIfLocked,
167
167
  writeConfig
168
- } from "./chunk-2WXGL442.js";
168
+ } from "./chunk-NQQUVGQO.js";
169
169
  import {
170
170
  getCoRecallNeighbors,
171
171
  getTopCoRecallEdges,
@@ -15104,12 +15104,12 @@ function registerMaintainCommand(program) {
15104
15104
  "--only <tasks>",
15105
15105
  "Comma-separated task names: quality,edge-decay,clusters,conflicts,consolidation,retirement,reflection"
15106
15106
  ).option("--prune-edges", "When edge decay runs, delete edges below the configured decay floor").option("--verbose", "Show detailed per-task output").action(async (opts) => {
15107
- const { runMaintainCommand } = await import("./maintain-ULYZ53FZ.js");
15107
+ const { runMaintainCommand } = await import("./maintain-K5UXHWUO.js");
15108
15108
  const result = await runMaintainCommand(opts);
15109
15109
  process.exitCode = result.exitCode;
15110
15110
  });
15111
15111
  maintainCommand.command("history").description("Show past maintenance runs").option("--db <path>", "Database path override").option("--limit <n>", "Max runs to show (default: 10)", parseIntOption).option("--json", "Output as JSON").action(async (opts) => {
15112
- const { runMaintainHistoryCommand } = await import("./maintain-ULYZ53FZ.js");
15112
+ const { runMaintainHistoryCommand } = await import("./maintain-K5UXHWUO.js");
15113
15113
  const result = await runMaintainHistoryCommand(opts);
15114
15114
  process.exitCode = result.exitCode;
15115
15115
  });
@@ -17,7 +17,7 @@ import {
17
17
  resolveConflict,
18
18
  runConsolidationOrchestrator,
19
19
  toRecord
20
- } from "./chunk-SC2E7CS3.js";
20
+ } from "./chunk-3WWWJ6MN.js";
21
21
  import {
22
22
  DEFAULT_DB_PATH,
23
23
  DEFAULT_TASK_MODEL,
@@ -43,7 +43,7 @@ import {
43
43
  resolveModelForLlmClient,
44
44
  runSimpleStream,
45
45
  walCheckpoint
46
- } from "./chunk-2WXGL442.js";
46
+ } from "./chunk-NQQUVGQO.js";
47
47
  import {
48
48
  decayCoRecallEdges,
49
49
  getLastRecallActivity,
@@ -122,6 +122,7 @@ type BeforePromptBuildEvent = {
122
122
  type BeforePromptBuildResult = {
123
123
  systemPrompt?: string;
124
124
  prependContext?: string;
125
+ prependSystemContext?: string;
125
126
  };
126
127
  type BeforeResetEvent = {
127
128
  sessionFile?: string;
@@ -155,6 +156,22 @@ type PluginToolOptions = {
155
156
  names?: string[];
156
157
  optional?: boolean;
157
158
  };
159
+ type InternalHookEvent = {
160
+ type: "command" | "session" | "agent" | "gateway" | "message";
161
+ action: string;
162
+ sessionKey: string;
163
+ context: Record<string, unknown>;
164
+ timestamp: Date;
165
+ messages: string[];
166
+ };
167
+ type InternalHookHandler = (event: InternalHookEvent) => Promise<void> | void;
168
+ type PluginHookOptions = {
169
+ priority?: number;
170
+ entry?: unknown;
171
+ name?: string;
172
+ description?: string;
173
+ register?: boolean;
174
+ };
158
175
  type PluginApi = {
159
176
  id: string;
160
177
  name: string;
@@ -162,6 +179,7 @@ type PluginApi = {
162
179
  pluginConfig?: Record<string, unknown>;
163
180
  logger: PluginLogger;
164
181
  registerTool?: (tool: PluginTool, opts?: PluginToolOptions) => void;
182
+ registerHook?: (events: string | string[], handler: InternalHookHandler, opts?: PluginHookOptions) => void;
165
183
  on: {
166
184
  (hook: "before_agent_start", handler: (event: BeforeAgentStartEvent, ctx: PluginHookAgentContext) => Promise<BeforeAgentStartResult | undefined> | BeforeAgentStartResult | undefined): void;
167
185
  (hook: "before_prompt_build", handler: (event: BeforePromptBuildEvent, ctx: PluginHookAgentContext) => Promise<BeforePromptBuildResult | undefined> | BeforePromptBuildResult | undefined): void;
@@ -24,7 +24,7 @@ import {
24
24
  runStoreService,
25
25
  runTraceService,
26
26
  setSessionProject
27
- } from "../chunk-3DJDQDWN.js";
27
+ } from "../chunk-JK4M3SD3.js";
28
28
  import {
29
29
  KNOWLEDGE_TYPES,
30
30
  SCOPE_LEVELS,
@@ -41,7 +41,7 @@ import {
41
41
  sanitizeInjectedContextText,
42
42
  stripInjectedContext,
43
43
  toErrorMessage
44
- } from "../chunk-2WXGL442.js";
44
+ } from "../chunk-NQQUVGQO.js";
45
45
  import {
46
46
  MILLISECONDS_PER_DAY,
47
47
  __export,
@@ -50,10 +50,6 @@ import {
50
50
  toStringValue
51
51
  } from "../chunk-UGIJJOPV.js";
52
52
 
53
- // src/openclaw-plugin/index.ts
54
- import os3 from "os";
55
- import path7 from "path";
56
-
57
53
  // src/prompts/handoff/summary.ts
58
54
  var HANDOFF_SUMMARY_SYSTEM_PROMPT = `You are a session summarizer for an AI agent memory system. Your job is
59
55
  to produce a concise handoff note from a conversation transcript so the
@@ -3652,32 +3648,61 @@ async function runHandoffForSession(opts) {
3652
3648
  }
3653
3649
  }
3654
3650
 
3655
- // src/openclaw-plugin/session-surfaced-memory-service.ts
3656
- function createSessionSurfacedMemoryService(sessionKey) {
3657
- return {
3658
- recordByIntent(intent, entryIds, options) {
3659
- return recordSessionSurfacedMemoryByIntent(
3660
- sessionKey,
3661
- { entryIds, intent },
3662
- options
3663
- );
3664
- },
3665
- dedupeEntryIds() {
3666
- return querySessionSurfacedMemory(sessionKey).dedupeEntryIds();
3667
- },
3668
- hasDedupeEntry(entryId) {
3669
- return querySessionSurfacedMemory(sessionKey).hasDedupeEntry(entryId);
3670
- },
3671
- beforeResetOwnedEntryIds() {
3672
- return querySessionSurfacedMemory(sessionKey).beforeResetOwnedEntryIds();
3673
- },
3674
- applyCommandResetPolicy() {
3675
- return applySessionSurfacedMemoryCommandResetPolicy(sessionKey);
3676
- },
3677
- applyBeforeResetPolicy() {
3678
- return applySessionSurfacedMemoryBeforeResetPolicy(sessionKey);
3679
- }
3680
- };
3651
+ // src/openclaw-plugin/system-context.ts
3652
+ var OPENCLAW_AGENR_MEMORY_DOCTRINE = [
3653
+ "## agenr Memory Doctrine",
3654
+ "This doctrine supersedes any older baseline prompt or workspace wording that treats markdown journals or markdown memory files as the primary continuity system.",
3655
+ "- agenr is the durable memory system.",
3656
+ "- `SOUL.md` and `IDENTITY.md` define identity and constitution.",
3657
+ "- `TOOLS.md` contains short environment-specific notes.",
3658
+ "- `AGENTS.md` contains workspace operating rules.",
3659
+ "- Markdown journals and markdown memory files are deprecated as the primary memory system.",
3660
+ "- If older baseline or workspace wording conflicts with this doctrine, follow the agenr-first doctrine instead.",
3661
+ "",
3662
+ "### Recall Before Guessing",
3663
+ "- Use agenr recall when prior context may matter, especially for project work, prior decisions, preferences, and standing constraints.",
3664
+ "- Do not claim to remember something unless it is in the current context, explicitly recalled, or directly verified.",
3665
+ "",
3666
+ "### Project-Scoped Memory",
3667
+ "- Use project-scoped store and recall deliberately.",
3668
+ "- Set the `project` field for project-specific memory.",
3669
+ "- Prefer focused project recall over noisy global recall.",
3670
+ "",
3671
+ "### Memory Lifetime",
3672
+ "- `temporary` - short-horizon context that may matter soon but should not persist indefinitely.",
3673
+ "- `permanent` - durable knowledge worth keeping across sessions until retired.",
3674
+ "- `core` - rare always-on context injected at session start.",
3675
+ "- Core is rare and expensive. If something can be recalled when needed, it should usually be `permanent`, not `core`.",
3676
+ "- Project-specific details are usually not `core`.",
3677
+ "",
3678
+ "### Importance Is Suppression",
3679
+ "- `10` = rare foundational constraint.",
3680
+ "- `9` = critical durable fact or decision.",
3681
+ "- `8` = urgent or significant cross-session context.",
3682
+ "- `7` = normal durable memory.",
3683
+ "- `6` = routine verified observation.",
3684
+ "- `5` = borderline item, use sparingly.",
3685
+ "- Not everything should be stored.",
3686
+ "- High importance does not automatically imply `core`.",
3687
+ "- If it is not worth recalling later, do not store it.",
3688
+ "",
3689
+ "### Confidence-Aware Writes",
3690
+ "- Verified facts can be stored confidently.",
3691
+ "- Inferred or uncertain claims should be verified first or stored cautiously.",
3692
+ "- Do not poison memory with hallucinated facts.",
3693
+ "",
3694
+ "### Anti-Duplication",
3695
+ "- Do not maintain a parallel markdown memory system.",
3696
+ "- Do not mirror agenr memory into markdown logs unless the user explicitly requests a human-readable artifact."
3697
+ ].join("\n");
3698
+ function isOpenClawMemoryDoctrineEnabled(config) {
3699
+ return config?.openclawMemoryDoctrine?.enabled !== false;
3700
+ }
3701
+ function buildPrependSystemContext(config) {
3702
+ if (!isOpenClawMemoryDoctrineEnabled(config)) {
3703
+ return void 0;
3704
+ }
3705
+ return OPENCLAW_AGENR_MEMORY_DOCTRINE;
3681
3706
  }
3682
3707
 
3683
3708
  // src/db/signals.ts
@@ -3787,6 +3812,34 @@ function resolveSignalConfig(pluginConfig) {
3787
3812
  };
3788
3813
  }
3789
3814
 
3815
+ // src/openclaw-plugin/session-surfaced-memory-service.ts
3816
+ function createSessionSurfacedMemoryService(sessionKey) {
3817
+ return {
3818
+ recordByIntent(intent, entryIds, options) {
3819
+ return recordSessionSurfacedMemoryByIntent(
3820
+ sessionKey,
3821
+ { entryIds, intent },
3822
+ options
3823
+ );
3824
+ },
3825
+ dedupeEntryIds() {
3826
+ return querySessionSurfacedMemory(sessionKey).dedupeEntryIds();
3827
+ },
3828
+ hasDedupeEntry(entryId) {
3829
+ return querySessionSurfacedMemory(sessionKey).hasDedupeEntry(entryId);
3830
+ },
3831
+ beforeResetOwnedEntryIds() {
3832
+ return querySessionSurfacedMemory(sessionKey).beforeResetOwnedEntryIds();
3833
+ },
3834
+ applyCommandResetPolicy() {
3835
+ return applySessionSurfacedMemoryCommandResetPolicy(sessionKey);
3836
+ },
3837
+ applyBeforeResetPolicy() {
3838
+ return applySessionSurfacedMemoryBeforeResetPolicy(sessionKey);
3839
+ }
3840
+ };
3841
+ }
3842
+
3790
3843
  // src/openclaw-plugin/hooks/before-prompt-build-shared.ts
3791
3844
  function getRecallEntryId(item) {
3792
3845
  if (typeof item !== "object" || item === null) {
@@ -7866,11 +7919,15 @@ async function handleBeforePromptBuild(event, ctx, params) {
7866
7919
  return;
7867
7920
  }
7868
7921
  logPromptBuildSections(params.debug, sectionResult.sections);
7922
+ const prependSystemContext = buildPrependSystemContext(params.config);
7869
7923
  const prependContext = buildPrependContext(params.debug, sectionResult.sections);
7870
- if (!prependContext) {
7924
+ if (!prependSystemContext && !prependContext) {
7871
7925
  return;
7872
7926
  }
7873
- return { prependContext };
7927
+ return {
7928
+ prependSystemContext,
7929
+ prependContext
7930
+ };
7874
7931
  } catch (err) {
7875
7932
  params.logger.warn(
7876
7933
  `agenr plugin before_prompt_build signal check failed: ${toErrorMessage(err)}`
@@ -8025,6 +8082,120 @@ async function handleBeforeReset(event, ctx, params) {
8025
8082
  }
8026
8083
  }
8027
8084
 
8085
+ // src/openclaw-plugin/hooks/command-events.ts
8086
+ import os3 from "os";
8087
+ import path7 from "path";
8088
+ var log3 = createLogger("command");
8089
+ function toCommandHookEvent(event) {
8090
+ return {
8091
+ type: "command",
8092
+ action: event.action,
8093
+ sessionKey: event.sessionKey,
8094
+ timestamp: event.timestamp,
8095
+ messages: Array.isArray(event.messages) ? event.messages : [],
8096
+ context: event.context ?? {}
8097
+ };
8098
+ }
8099
+ function resolveCommandAgentId(sessionKey) {
8100
+ const parsed = parseOpenClawSessionIdentity(sessionKey);
8101
+ const agentId = parsed.agentId?.trim();
8102
+ return agentId && agentId.length > 0 ? agentId : "main";
8103
+ }
8104
+ function applyCommandResetPolicy(sessionKey, sessionId) {
8105
+ clearMidSessionState(sessionKey);
8106
+ createSessionSurfacedMemoryService(sessionKey).applyCommandResetPolicy();
8107
+ if (sessionId && sessionId !== sessionKey) {
8108
+ clearMidSessionState(sessionId);
8109
+ createSessionSurfacedMemoryService(sessionId).applyCommandResetPolicy();
8110
+ }
8111
+ }
8112
+ async function handleCommandEvent(event, params) {
8113
+ try {
8114
+ debugLog(
8115
+ params.debug,
8116
+ "command",
8117
+ "triggered action=" + event.action + " sessionKey=" + event.sessionKey
8118
+ );
8119
+ const sessionKey = event.sessionKey?.trim() ?? "";
8120
+ if (!sessionKey) {
8121
+ return;
8122
+ }
8123
+ const sessionEntry = event.context.sessionEntry;
8124
+ const sessionId = sessionEntry?.sessionId?.trim() || sessionKey;
8125
+ applyCommandResetPolicy(sessionKey, sessionId);
8126
+ const sessionFile = typeof sessionEntry?.sessionFile === "string" && sessionEntry.sessionFile.trim() ? sessionEntry.sessionFile.trim() : null;
8127
+ log3.info(
8128
+ `command hook: fired action=${event.action} sessionKey=${sessionKey} sessionFile=${sessionFile ?? "none"}`
8129
+ );
8130
+ let messages = [];
8131
+ if (sessionFile) {
8132
+ messages = await params.testingApi.readAndParseSessionJsonl(sessionFile);
8133
+ }
8134
+ if (messages.length === 0) {
8135
+ return;
8136
+ }
8137
+ const agentId = resolveCommandAgentId(sessionKey);
8138
+ const sessionsDir = params.config?.sessionsDir ?? path7.join(os3.homedir(), `.openclaw/agents/${agentId}/sessions`);
8139
+ const defaultProject = params.config?.project?.trim() || void 0;
8140
+ const sessionProjectState = await getSessionProjectState(sessionKey, params.config);
8141
+ const projectAttribution = resolveOpenClawHandoffProjectAttribution({
8142
+ sessionProjectState,
8143
+ defaultProject
8144
+ });
8145
+ const storeConfig = {
8146
+ ...params.config,
8147
+ logger: params.logger
8148
+ };
8149
+ await params.testingApi.runHandoffForSession({
8150
+ messages,
8151
+ sessionFile,
8152
+ sessionId,
8153
+ sessionKey,
8154
+ agentId,
8155
+ agenrPath: params.agenrPath,
8156
+ budget: params.budget,
8157
+ defaultProject: projectAttribution.project ?? void 0,
8158
+ projectAttribution,
8159
+ storeConfig,
8160
+ sessionsDir,
8161
+ includeBackground: params.includeBackground,
8162
+ logEnabled: params.handoffLogEnabled,
8163
+ logDir: params.handoffLogDir,
8164
+ debugEnabled: params.debug,
8165
+ logger: params.logger,
8166
+ source: "command",
8167
+ dbPath: params.config?.dbPath
8168
+ });
8169
+ debugLog(params.debug, "command", "handoff complete");
8170
+ } catch (err) {
8171
+ params.logger.warn(
8172
+ `agenr plugin command hook failed: ${toErrorMessage(err)}`
8173
+ );
8174
+ }
8175
+ }
8176
+ function registerAgenrCommandHooks(api, params) {
8177
+ if (api.registerHook) {
8178
+ api.registerHook(
8179
+ ["command:new", "command:reset"],
8180
+ async (event) => handleCommandEvent(event, params),
8181
+ {
8182
+ name: "agenr-command-events",
8183
+ description: "Handle OpenClaw command lifecycle events for agenr reset cleanup and session handoff continuity."
8184
+ }
8185
+ );
8186
+ return;
8187
+ }
8188
+ api.on(
8189
+ "command",
8190
+ async (event) => {
8191
+ if (event.action !== "new" && event.action !== "reset") {
8192
+ return;
8193
+ }
8194
+ await handleCommandEvent(toCommandHookEvent(event), params);
8195
+ }
8196
+ );
8197
+ }
8198
+
8028
8199
  // src/openclaw-plugin/hooks/register-tools.ts
8029
8200
  import { Type } from "@sinclair/typebox";
8030
8201
 
@@ -8494,7 +8665,6 @@ var plugin = {
8494
8665
  name: "agenr memory context",
8495
8666
  description: "Injects agenr long-term memory into every agent session via before_prompt_build",
8496
8667
  register(api) {
8497
- const log3 = createLogger("plugin");
8498
8668
  const config = api.pluginConfig;
8499
8669
  const debug = isDebugEnabled(config);
8500
8670
  const includeBackground = config?.handoff?.includeBackground ?? false;
@@ -8526,6 +8696,17 @@ var plugin = {
8526
8696
  logger: api.logger,
8527
8697
  testingApi
8528
8698
  };
8699
+ const commandParams = {
8700
+ config,
8701
+ debug,
8702
+ budget,
8703
+ includeBackground,
8704
+ handoffLogEnabled,
8705
+ handoffLogDir,
8706
+ agenrPath,
8707
+ logger: api.logger,
8708
+ testingApi
8709
+ };
8529
8710
  const toolParams = {
8530
8711
  config,
8531
8712
  debug,
@@ -8533,82 +8714,7 @@ var plugin = {
8533
8714
  };
8534
8715
  api.on("before_prompt_build", (event, ctx) => handleBeforePromptBuild(event, ctx, promptBuildParams));
8535
8716
  api.on("before_reset", (event, ctx) => handleBeforeReset(event, ctx, resetParams));
8536
- api.on(
8537
- "command",
8538
- async (event, ctx) => {
8539
- try {
8540
- debugLog(debug, "command", "triggered action=" + event.action + " sessionKey=" + event.sessionKey);
8541
- if (event.action !== "new" && event.action !== "reset") {
8542
- return;
8543
- }
8544
- if (event.action === "new" || event.action === "reset") {
8545
- const resetKey = event.sessionKey;
8546
- if (resetKey) {
8547
- clearMidSessionState(resetKey);
8548
- createSessionSurfacedMemoryService(resetKey).applyCommandResetPolicy();
8549
- }
8550
- const resetSessionId = event.context?.sessionEntry?.sessionId?.trim() ?? "";
8551
- if (resetSessionId && resetSessionId !== resetKey) {
8552
- clearMidSessionState(resetSessionId);
8553
- createSessionSurfacedMemoryService(resetSessionId).applyCommandResetPolicy();
8554
- }
8555
- }
8556
- const sessionKey = event.sessionKey;
8557
- if (!sessionKey) {
8558
- return;
8559
- }
8560
- const sessionFile = event.context?.sessionEntry?.sessionFile ?? null;
8561
- const sessionId = event.context?.sessionEntry?.sessionId ?? sessionKey;
8562
- log3.info(
8563
- `command hook: fired action=${event.action} sessionKey=${sessionKey} sessionFile=${sessionFile ?? "none"}`
8564
- );
8565
- let messages = [];
8566
- if (sessionFile) {
8567
- messages = await testingApi.readAndParseSessionJsonl(sessionFile);
8568
- }
8569
- if (messages.length === 0) {
8570
- return;
8571
- }
8572
- const agentId = ctx.agentId?.trim() || "main";
8573
- const sessionsDir = config?.sessionsDir ?? path7.join(os3.homedir(), `.openclaw/agents/${agentId}/sessions`);
8574
- const defaultProject = config?.project?.trim() || void 0;
8575
- const sessionProjectState = await getSessionProjectState(sessionKey, config);
8576
- const projectAttribution = resolveOpenClawHandoffProjectAttribution({
8577
- sessionProjectState,
8578
- defaultProject
8579
- });
8580
- const storeConfig = {
8581
- ...config,
8582
- logger: api.logger
8583
- };
8584
- await testingApi.runHandoffForSession({
8585
- messages,
8586
- sessionFile,
8587
- sessionId,
8588
- sessionKey,
8589
- agentId,
8590
- agenrPath,
8591
- budget,
8592
- defaultProject: projectAttribution.project ?? void 0,
8593
- projectAttribution,
8594
- storeConfig,
8595
- sessionsDir,
8596
- includeBackground,
8597
- logEnabled: handoffLogEnabled,
8598
- logDir: handoffLogDir,
8599
- debugEnabled: debug,
8600
- logger: api.logger,
8601
- source: "command",
8602
- dbPath: config?.dbPath
8603
- });
8604
- debugLog(debug, "command", "handoff complete");
8605
- } catch (err) {
8606
- api.logger.warn(
8607
- `agenr plugin command hook failed: ${toErrorMessage(err)}`
8608
- );
8609
- }
8610
- }
8611
- );
8717
+ registerAgenrCommandHooks(api, commandParams);
8612
8718
  registerAgenrTools(api, toolParams);
8613
8719
  }
8614
8720
  };
@@ -94,6 +94,17 @@
94
94
  }
95
95
  }
96
96
  },
97
+ "openclawMemoryDoctrine": {
98
+ "type": "object",
99
+ "description": "Stable agenr-first doctrine injected with prependSystemContext.",
100
+ "additionalProperties": false,
101
+ "properties": {
102
+ "enabled": {
103
+ "type": "boolean",
104
+ "description": "Set false to disable stable doctrine injection while preserving dynamic prependContext memory injection."
105
+ }
106
+ }
107
+ },
97
108
  "dbPath": {
98
109
  "type": "string",
99
110
  "description": "Path to agenr DB. Defaults to AGENR_DB_PATH env or ~/.agenr/knowledge.db."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agenr",
3
- "version": "0.9.86",
3
+ "version": "0.9.88",
4
4
  "openclaw": {
5
5
  "extensions": [
6
6
  "dist/openclaw-plugin/index.js"
@@ -7,25 +7,6 @@ import {
7
7
  toStringValue
8
8
  } from "./chunk-UGIJJOPV.js";
9
9
 
10
- // src/utils/errors.ts
11
- function toErrorMessage(error) {
12
- if (error instanceof Error) {
13
- return error.message;
14
- }
15
- if (error !== null && typeof error === "object") {
16
- const maybeMessage = error.message;
17
- if (typeof maybeMessage === "string") {
18
- return maybeMessage;
19
- }
20
- try {
21
- return JSON.stringify(error);
22
- } catch {
23
- return String(error);
24
- }
25
- }
26
- return String(error);
27
- }
28
-
29
10
  // src/config.ts
30
11
  import fs2 from "fs";
31
12
  import os3 from "os";
@@ -213,6 +194,25 @@ function buildProjectFilter(params) {
213
194
  };
214
195
  }
215
196
 
197
+ // src/utils/errors.ts
198
+ function toErrorMessage(error) {
199
+ if (error instanceof Error) {
200
+ return error.message;
201
+ }
202
+ if (error !== null && typeof error === "object") {
203
+ const maybeMessage = error.message;
204
+ if (typeof maybeMessage === "string") {
205
+ return maybeMessage;
206
+ }
207
+ try {
208
+ return JSON.stringify(error);
209
+ } catch {
210
+ return String(error);
211
+ }
212
+ }
213
+ return String(error);
214
+ }
215
+
216
216
  // src/utils/fs.ts
217
217
  import os2 from "os";
218
218
  import path2 from "path";
@@ -1512,6 +1512,12 @@ var APP_VERSION = (() => {
1512
1512
  return "0.0.0";
1513
1513
  })();
1514
1514
 
1515
+ // src/db/client.ts
1516
+ import { createClient } from "@libsql/client";
1517
+ import fs3 from "fs/promises";
1518
+ import os4 from "os";
1519
+ import path4 from "path";
1520
+
1515
1521
  // src/utils/logger.ts
1516
1522
  var verboseEnabled = false;
1517
1523
  function isMockedConsoleFn(fn) {
@@ -1552,12 +1558,6 @@ function createLogger(prefix) {
1552
1558
  };
1553
1559
  }
1554
1560
 
1555
- // src/db/client.ts
1556
- import { createClient } from "@libsql/client";
1557
- import fs3 from "fs/promises";
1558
- import os4 from "os";
1559
- import path4 from "path";
1560
-
1561
1561
  // src/db/schema/definitions.ts
1562
1562
  var CREATE_IDX_ENTRIES_EMBEDDING_SQL = `
1563
1563
  CREATE INDEX IF NOT EXISTS idx_entries_embedding ON entries (