agenr 0.6.6 → 0.6.8

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,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.6.8] - 2026-02-19
4
+
5
+ ### Fixed
6
+ - fix(openclaw-plugin): OpenClaw plugin now uses api.on("before_agent_start") instead of api.registerHook("agent:bootstrap"). The previous approach registered the handler in the gateway bundle's internal handlers map, which is a different module instance from the embedded agent runner. The typed hook system (api.on) uses the shared global plugin registry and works correctly across both bundles.
7
+
8
+ ## [0.6.7] - 2026-02-19
9
+
10
+ ### Fixed
11
+ - fix(openclaw-plugin): add name and description to registerHook opts to resolve OpenClaw hook registration warning
12
+
3
13
  ## [0.6.6] - 2026-02-19
4
14
 
5
15
  ### Added
package/dist/cli-main.js CHANGED
@@ -12451,7 +12451,22 @@ function resolveWatcherPidPath(configDir) {
12451
12451
  async function writeWatcherPid(configDir) {
12452
12452
  const pidPath = resolveWatcherPidPath(configDir);
12453
12453
  await fs26.mkdir(path25.dirname(pidPath), { recursive: true });
12454
- await fs26.writeFile(pidPath, String(process.pid), "utf8");
12454
+ const tmpPath = `${pidPath}.${process.pid}.${Date.now()}.tmp`;
12455
+ let handle = null;
12456
+ try {
12457
+ handle = await fs26.open(tmpPath, "w");
12458
+ await handle.writeFile(String(process.pid), "utf8");
12459
+ await handle.sync();
12460
+ await handle.close();
12461
+ handle = null;
12462
+ await fs26.rename(tmpPath, pidPath);
12463
+ } catch (error) {
12464
+ if (handle) {
12465
+ await handle.close().catch(() => void 0);
12466
+ }
12467
+ await fs26.unlink(tmpPath).catch(() => void 0);
12468
+ throw error;
12469
+ }
12455
12470
  }
12456
12471
  async function deleteWatcherPid(configDir) {
12457
12472
  try {
@@ -12778,6 +12793,8 @@ async function runIngestCommand(inputPaths, options, deps) {
12778
12793
  loadWatchStateFn: deps?.loadWatchStateFn ?? loadWatchState,
12779
12794
  saveWatchStateFn: deps?.saveWatchStateFn ?? saveWatchState,
12780
12795
  isWatcherRunningFn: deps?.isWatcherRunningFn ?? isWatcherRunning,
12796
+ readWatcherPidFn: deps?.readWatcherPidFn ?? readWatcherPid,
12797
+ resolveWatcherPidPathFn: deps?.resolveWatcherPidPathFn ?? resolveWatcherPidPath,
12781
12798
  nowFn: deps?.nowFn ?? (() => /* @__PURE__ */ new Date()),
12782
12799
  sleepFn: deps?.sleepFn ?? sleep,
12783
12800
  shouldShutdownFn: deps?.shouldShutdownFn ?? isShutdownRequested
@@ -12785,8 +12802,8 @@ async function runIngestCommand(inputPaths, options, deps) {
12785
12802
  const clackOutput = { output: process.stderr };
12786
12803
  clack4.intro(banner(), clackOutput);
12787
12804
  if (await resolvedDeps.isWatcherRunningFn()) {
12788
- const pid = await readWatcherPid();
12789
- const pidFile = resolveWatcherPidPath();
12805
+ const pid = await resolvedDeps.readWatcherPidFn();
12806
+ const pidFile = resolvedDeps.resolveWatcherPidPathFn();
12790
12807
  clack4.log.error(
12791
12808
  formatError(
12792
12809
  `agenr watcher is running (PID ${pid ?? "unknown"}). Stop the watcher before running ingest.
@@ -16259,6 +16276,7 @@ async function runWatchCommand(file, options, deps) {
16259
16276
  const clackOutput = { output: process.stderr };
16260
16277
  warnIfLocked();
16261
16278
  installSignalHandlers();
16279
+ clack10.intro(banner(), clackOutput);
16262
16280
  try {
16263
16281
  await resolvedDeps.writeWatcherPidFn();
16264
16282
  } catch (error) {
@@ -16286,7 +16304,6 @@ async function runWatchCommand(file, options, deps) {
16286
16304
  const raw = options.raw === true;
16287
16305
  const contextEnabled = Boolean(options.context);
16288
16306
  const modeConfig = await resolveWatchMode(file, options, resolvedDeps.statFileFn);
16289
- clack10.intro(banner(), clackOutput);
16290
16307
  for (const warning of modeConfig.warnings) {
16291
16308
  process.stderr.write(`${warning}
16292
16309
  `);
@@ -16364,13 +16381,12 @@ async function runWatchCommand(file, options, deps) {
16364
16381
  },
16365
16382
  onCycle: (result, ctx) => {
16366
16383
  cycleCount += 1;
16367
- const timestamp = formatClock(resolvedDeps.nowFn());
16384
+ const now = resolvedDeps.nowFn();
16385
+ const timestamp = formatClock(now);
16368
16386
  const fileLabel = result.filePath ? ` | file=${result.filePath}` : "";
16369
16387
  if (json) {
16370
- process.stdout.write(
16371
- `${JSON.stringify({ cycle: cycleCount, at: resolvedDeps.nowFn().toISOString(), ...result })}
16372
- `
16373
- );
16388
+ process.stdout.write(`${JSON.stringify({ cycle: cycleCount, at: now.toISOString(), ...result })}
16389
+ `);
16374
16390
  }
16375
16391
  if (result.error) {
16376
16392
  clack10.log.warn(formatWarn(`[${timestamp}] Cycle ${cycleCount}: ${result.error}${fileLabel}`), clackOutput);
@@ -1,10 +1,10 @@
1
- type HookEvent = {
2
- type: string;
3
- action: string;
4
- sessionKey: string;
5
- context: Record<string, unknown>;
6
- timestamp: Date;
7
- messages: string[];
1
+ type BeforeAgentStartEvent = {
2
+ sessionKey?: string;
3
+ prompt?: string;
4
+ [key: string]: unknown;
5
+ };
6
+ type BeforeAgentStartResult = {
7
+ prependContext?: string;
8
8
  };
9
9
  type PluginLogger = {
10
10
  debug?: (message: string) => void;
@@ -18,7 +18,7 @@ type PluginApi = {
18
18
  version?: string;
19
19
  pluginConfig?: Record<string, unknown>;
20
20
  logger: PluginLogger;
21
- registerHook: (events: string | string[], handler: (event: HookEvent) => Promise<void> | void) => void;
21
+ on: (hook: "before_agent_start", handler: (event: BeforeAgentStartEvent) => Promise<BeforeAgentStartResult | undefined> | BeforeAgentStartResult | undefined) => void;
22
22
  };
23
23
 
24
24
  declare const plugin: {
@@ -1,7 +1,3 @@
1
- // src/openclaw-plugin/index.ts
2
- import os from "os";
3
- import path2 from "path";
4
-
5
1
  // src/openclaw-plugin/recall.ts
6
2
  import { spawn } from "child_process";
7
3
  import path from "path";
@@ -114,7 +110,6 @@ function formatRecallAsMarkdown(result) {
114
110
  }
115
111
 
116
112
  // src/openclaw-plugin/index.ts
117
- var AGENR_CONTEXT_PATH = path2.join(os.homedir(), ".agenr", "AGENR.md");
118
113
  var SKIP_SESSION_PATTERNS = [":subagent:", ":cron:"];
119
114
  function shouldSkipSession(sessionKey) {
120
115
  return SKIP_SESSION_PATTERNS.some((pattern) => sessionKey.includes(pattern));
@@ -122,42 +117,39 @@ function shouldSkipSession(sessionKey) {
122
117
  var plugin = {
123
118
  id: "agenr",
124
119
  name: "agenr memory context",
125
- description: "Injects agenr long-term memory into every agent session via agent:bootstrap",
120
+ description: "Injects agenr long-term memory into every agent session via before_agent_start",
126
121
  register(api) {
127
- api.registerHook("agent:bootstrap", async (event) => {
128
- try {
129
- const ctx = event.context;
130
- if (!Array.isArray(ctx.bootstrapFiles)) {
131
- return;
132
- }
133
- const sessionKey = ctx.sessionKey ?? event.sessionKey ?? "";
134
- if (shouldSkipSession(sessionKey)) {
135
- return;
136
- }
137
- const config = api.pluginConfig;
138
- if (config?.enabled === false) {
122
+ api.on(
123
+ "before_agent_start",
124
+ async (event) => {
125
+ try {
126
+ const sessionKey = event.sessionKey ?? "";
127
+ if (shouldSkipSession(sessionKey)) {
128
+ return;
129
+ }
130
+ const config = api.pluginConfig;
131
+ if (config?.enabled === false) {
132
+ return;
133
+ }
134
+ const agenrPath = resolveAgenrPath(config);
135
+ const budget = resolveBudget(config);
136
+ const result = await runRecall(agenrPath, budget);
137
+ if (!result) {
138
+ return;
139
+ }
140
+ const markdown = formatRecallAsMarkdown(result);
141
+ if (!markdown.trim()) {
142
+ return;
143
+ }
144
+ return { prependContext: markdown };
145
+ } catch (err) {
146
+ api.logger.warn(
147
+ `agenr plugin before_agent_start recall failed: ${err instanceof Error ? err.message : String(err)}`
148
+ );
139
149
  return;
140
150
  }
141
- const agenrPath = resolveAgenrPath(config);
142
- const budget = resolveBudget(config);
143
- const result = await runRecall(agenrPath, budget);
144
- if (!result) {
145
- return;
146
- }
147
- const markdown = formatRecallAsMarkdown(result);
148
- if (!markdown.trim()) {
149
- return;
150
- }
151
- const file = {
152
- name: "AGENR.md",
153
- path: AGENR_CONTEXT_PATH,
154
- content: markdown,
155
- missing: false
156
- };
157
- ctx.bootstrapFiles.push(file);
158
- } catch {
159
151
  }
160
- });
152
+ );
161
153
  }
162
154
  };
163
155
  var openclaw_plugin_default = plugin;
package/package.json CHANGED
@@ -1,16 +1,21 @@
1
1
  {
2
2
  "name": "agenr",
3
- "version": "0.6.6",
3
+ "version": "0.6.8",
4
4
  "openclaw": {
5
- "extensions": [
6
- "dist/openclaw-plugin/index.js"
7
- ]
5
+ "extensions": ["dist/openclaw-plugin/index.js"]
8
6
  },
9
7
  "description": "AGENt memoRy -- Memory infrastructure for AI agents",
10
8
  "type": "module",
11
9
  "bin": {
12
10
  "agenr": "dist/cli.js"
13
11
  },
12
+ "scripts": {
13
+ "build": "tsup src/cli.ts src/cli-main.ts src/openclaw-plugin/index.ts --format esm --dts",
14
+ "dev": "tsup src/cli.ts src/cli-main.ts --format esm --watch",
15
+ "test": "vitest run",
16
+ "test:watch": "vitest",
17
+ "typecheck": "tsc --noEmit"
18
+ },
14
19
  "dependencies": {
15
20
  "@clack/prompts": "^1.0.1",
16
21
  "@libsql/client": "^0.17.0",
@@ -53,11 +58,9 @@
53
58
  "README.md"
54
59
  ],
55
60
  "author": "agenr-ai",
56
- "scripts": {
57
- "build": "tsup src/cli.ts src/cli-main.ts src/openclaw-plugin/index.ts --format esm --dts",
58
- "dev": "tsup src/cli.ts src/cli-main.ts --format esm --watch",
59
- "test": "vitest run",
60
- "test:watch": "vitest",
61
- "typecheck": "tsc --noEmit"
61
+ "pnpm": {
62
+ "overrides": {
63
+ "fast-xml-parser": "^5.3.6"
64
+ }
62
65
  }
63
- }
66
+ }