clawvault 2.5.3 → 2.6.0

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.
Files changed (95) hide show
  1. package/README.md +159 -159
  2. package/bin/clawvault.js +111 -111
  3. package/bin/command-registration.test.js +166 -166
  4. package/bin/command-runtime.js +93 -93
  5. package/bin/command-runtime.test.js +154 -154
  6. package/bin/help-contract.test.js +39 -39
  7. package/bin/register-config-commands.js +153 -153
  8. package/bin/register-config-route-commands.test.js +121 -121
  9. package/bin/register-core-commands.js +237 -237
  10. package/bin/register-kanban-commands.js +56 -56
  11. package/bin/register-kanban-commands.test.js +83 -83
  12. package/bin/register-maintenance-commands.js +282 -282
  13. package/bin/register-project-commands.js +209 -209
  14. package/bin/register-project-commands.test.js +206 -206
  15. package/bin/register-query-commands.js +317 -317
  16. package/bin/register-query-commands.test.js +65 -65
  17. package/bin/register-resilience-commands.js +182 -182
  18. package/bin/register-resilience-commands.test.js +81 -81
  19. package/bin/register-route-commands.js +114 -114
  20. package/bin/register-session-lifecycle-commands.js +206 -206
  21. package/bin/register-tailscale-commands.js +106 -106
  22. package/bin/register-task-commands.js +348 -348
  23. package/bin/register-task-commands.test.js +69 -69
  24. package/bin/register-template-commands.js +75 -72
  25. package/bin/register-template-commands.test.js +87 -0
  26. package/bin/register-vault-operations-commands.js +300 -300
  27. package/bin/test-helpers/cli-command-fixtures.js +119 -119
  28. package/dashboard/lib/graph-diff.js +104 -104
  29. package/dashboard/lib/graph-diff.test.js +75 -75
  30. package/dashboard/lib/vault-parser.js +556 -556
  31. package/dashboard/lib/vault-parser.test.js +254 -254
  32. package/dashboard/public/app.js +796 -796
  33. package/dashboard/public/index.html +52 -52
  34. package/dashboard/public/styles.css +221 -221
  35. package/dashboard/server.js +374 -374
  36. package/dist/{chunk-J5EMBUPK.js → chunk-4OXMU5S2.js} +1 -1
  37. package/dist/{chunk-3FP5BJ42.js → chunk-4QYGFWRM.js} +1 -1
  38. package/dist/{chunk-4IV3R2F5.js → chunk-4TE4JMLA.js} +1 -1
  39. package/dist/{chunk-5GZFTAL7.js → chunk-AZYOKJYC.js} +128 -42
  40. package/dist/{chunk-FG6RJMCN.js → chunk-HA5M6KJB.js} +4 -4
  41. package/dist/{chunk-IZEY5S74.js → chunk-IEVLHNLU.js} +1 -1
  42. package/dist/{chunk-CLE2HHNT.js → chunk-IVRIKYFE.js} +18 -11
  43. package/dist/{chunk-AY4PGUVL.js → chunk-KL4NAOMO.js} +1 -1
  44. package/dist/{chunk-O7XHXF7F.js → chunk-MAKNAHAW.js} +4 -4
  45. package/dist/{chunk-OSMS7QIG.js → chunk-ME37YNW3.js} +2 -2
  46. package/dist/chunk-MFAWT5O5.js +301 -0
  47. package/dist/{chunk-TPDH3JPP.js → chunk-PBEE567J.js} +1 -1
  48. package/dist/{chunk-S2IG7VNM.js → chunk-Q2J5YTUF.js} +2 -2
  49. package/dist/{chunk-IOALNTAN.js → chunk-QWQ3TIKS.js} +103 -29
  50. package/dist/{chunk-YCVDVI5B.js → chunk-R2MIW5G7.js} +1 -1
  51. package/dist/{chunk-M25QVSJM.js → chunk-RVYA52PY.js} +1 -1
  52. package/dist/{chunk-NZ4ZZNSR.js → chunk-THRJVD4L.js} +1 -1
  53. package/dist/{chunk-4GBPTBFJ.js → chunk-TIGW564L.js} +1 -1
  54. package/dist/{chunk-LMEMZGUV.js → chunk-UEOUADMO.js} +3 -3
  55. package/dist/{chunk-GFJ3LIIB.js → chunk-XAVB4GB4.js} +1 -1
  56. package/dist/cli/index.js +15 -13
  57. package/dist/commands/backlog.js +3 -1
  58. package/dist/commands/blocked.js +3 -1
  59. package/dist/commands/canvas.js +3 -1
  60. package/dist/commands/context.js +3 -3
  61. package/dist/commands/doctor.js +9 -7
  62. package/dist/commands/embed.js +2 -2
  63. package/dist/commands/kanban.js +4 -2
  64. package/dist/commands/observe.js +7 -5
  65. package/dist/commands/project.js +5 -3
  66. package/dist/commands/rebuild.js +6 -4
  67. package/dist/commands/replay.js +6 -4
  68. package/dist/commands/setup.js +2 -2
  69. package/dist/commands/sleep.js +7 -5
  70. package/dist/commands/status.js +8 -6
  71. package/dist/commands/tailscale.js +3 -3
  72. package/dist/commands/task.js +4 -2
  73. package/dist/commands/template.d.ts +10 -1
  74. package/dist/commands/template.js +47 -55
  75. package/dist/commands/wake.js +2 -2
  76. package/dist/index.js +23 -22
  77. package/dist/lib/project-utils.js +4 -2
  78. package/dist/lib/tailscale.js +2 -2
  79. package/dist/lib/task-utils.d.ts +14 -13
  80. package/dist/lib/task-utils.js +3 -1
  81. package/dist/lib/template-engine.d.ts +1 -0
  82. package/dist/lib/webdav.js +1 -1
  83. package/hooks/clawvault/HOOK.md +83 -83
  84. package/hooks/clawvault/handler.js +816 -816
  85. package/hooks/clawvault/handler.test.js +263 -263
  86. package/package.json +94 -94
  87. package/templates/checkpoint.md +34 -19
  88. package/templates/daily-note.md +34 -19
  89. package/templates/daily.md +34 -19
  90. package/templates/decision.md +39 -17
  91. package/templates/handoff.md +34 -19
  92. package/templates/lesson.md +31 -16
  93. package/templates/person.md +37 -19
  94. package/templates/project.md +84 -23
  95. package/templates/task.md +81 -0
@@ -1,3 +1,11 @@
1
+ import {
2
+ TEMPLATE_EXTENSION,
3
+ buildTemplateIndex,
4
+ listTemplateDefinitions,
5
+ normalizeTemplateName,
6
+ parseTemplateDefinition,
7
+ renderDocumentFromTemplate
8
+ } from "../chunk-MFAWT5O5.js";
1
9
  import {
2
10
  buildTemplateVariables,
3
11
  renderTemplate
@@ -6,26 +14,8 @@ import {
6
14
  // src/commands/template.ts
7
15
  import * as fs from "fs";
8
16
  import * as path from "path";
9
- import { fileURLToPath } from "url";
10
17
  var VAULT_CONFIG_FILE = ".clawvault.json";
11
- var TEMPLATE_EXTENSION = ".md";
12
- function resolveBuiltinTemplatesDir(override) {
13
- if (override) {
14
- const resolved = path.resolve(override);
15
- return fs.existsSync(resolved) ? resolved : null;
16
- }
17
- const moduleDir = path.dirname(fileURLToPath(import.meta.url));
18
- const candidates = [
19
- path.resolve(moduleDir, "../templates"),
20
- path.resolve(moduleDir, "../../templates")
21
- ];
22
- for (const candidate of candidates) {
23
- if (fs.existsSync(candidate) && fs.statSync(candidate).isDirectory()) {
24
- return candidate;
25
- }
26
- }
27
- return null;
28
- }
18
+ var TEMPLATE_LIST_IGNORED_BUILTINS = /* @__PURE__ */ new Set(["daily"]);
29
19
  function findVaultRoot(start) {
30
20
  let current = path.resolve(start);
31
21
  while (true) {
@@ -48,53 +38,41 @@ function resolveVaultPath(options) {
48
38
  const cwd = options.cwd ?? process.cwd();
49
39
  return findVaultRoot(cwd);
50
40
  }
51
- function normalizeTemplateName(name) {
52
- const base = path.basename(name, path.extname(name));
53
- return base.trim();
54
- }
55
41
  function slugify(text) {
56
42
  return text.toLowerCase().replace(/[^\w\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-").trim();
57
43
  }
58
- function listTemplateFiles(dir, ignore) {
59
- const entries = /* @__PURE__ */ new Map();
60
- if (!fs.existsSync(dir)) return entries;
61
- for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
62
- if (!entry.isFile() || !entry.name.endsWith(TEMPLATE_EXTENSION)) continue;
63
- const name = normalizeTemplateName(entry.name);
64
- if (!name) continue;
65
- if (ignore?.has(name)) continue;
66
- entries.set(name, path.join(dir, entry.name));
67
- }
68
- return entries;
44
+ function buildTemplateIndexForContext(options) {
45
+ const vaultPath = resolveVaultPath(options) ?? void 0;
46
+ return buildTemplateIndex({
47
+ vaultPath,
48
+ builtinDir: options.builtinDir,
49
+ ignoreBuiltinNames: TEMPLATE_LIST_IGNORED_BUILTINS
50
+ });
69
51
  }
70
- function buildTemplateIndex(options) {
71
- const index = /* @__PURE__ */ new Map();
72
- const builtinDir = resolveBuiltinTemplatesDir(options.builtinDir);
73
- if (builtinDir) {
74
- const ignore = /* @__PURE__ */ new Set(["daily"]);
75
- for (const [name, filePath] of listTemplateFiles(builtinDir, ignore)) {
76
- index.set(name, filePath);
77
- }
78
- }
79
- const vaultPath = resolveVaultPath(options);
80
- if (vaultPath) {
81
- const vaultTemplatesDir = path.join(vaultPath, "templates");
82
- for (const [name, filePath] of listTemplateFiles(vaultTemplatesDir)) {
83
- index.set(name, filePath);
84
- }
85
- }
86
- return index;
52
+ function listTemplateDefinitions2(options = {}) {
53
+ const vaultPath = resolveVaultPath(options) ?? void 0;
54
+ return listTemplateDefinitions({
55
+ vaultPath,
56
+ builtinDir: options.builtinDir,
57
+ ignoreBuiltinNames: TEMPLATE_LIST_IGNORED_BUILTINS
58
+ }).map((definition) => ({
59
+ name: definition.name,
60
+ primitive: definition.primitive,
61
+ description: definition.description,
62
+ fields: Object.keys(definition.fields),
63
+ path: definition.path,
64
+ format: definition.format
65
+ }));
87
66
  }
88
67
  function listTemplates(options = {}) {
89
- const index = buildTemplateIndex(options);
90
- return [...index.keys()].sort();
68
+ return listTemplateDefinitions2(options).map((definition) => definition.name);
91
69
  }
92
70
  function createFromTemplate(name, options = {}) {
93
71
  const templateName = normalizeTemplateName(name);
94
72
  if (!templateName) {
95
73
  throw new Error("Template name is required.");
96
74
  }
97
- const index = buildTemplateIndex(options);
75
+ const index = buildTemplateIndexForContext(options);
98
76
  const templatePath = index.get(templateName);
99
77
  if (!templatePath) {
100
78
  const available = [...index.keys()].sort();
@@ -107,7 +85,20 @@ function createFromTemplate(name, options = {}) {
107
85
  const type = options.type ?? templateName;
108
86
  const title = options.title ?? `${type} ${date}`.trim();
109
87
  const variables = buildTemplateVariables({ title, type, date }, now);
110
- const rendered = renderTemplate(raw, variables);
88
+ const parsedTemplate = parseTemplateDefinition(raw, templateName, templatePath);
89
+ const rendered = parsedTemplate.format === "schema" ? renderDocumentFromTemplate(parsedTemplate, {
90
+ title,
91
+ type,
92
+ now,
93
+ variables: {
94
+ ...variables,
95
+ content: "",
96
+ links_line: "",
97
+ owner_link: "",
98
+ project_link: "",
99
+ team_links_line: ""
100
+ }
101
+ }).markdown : renderTemplate(raw, variables);
111
102
  const cwd = options.cwd ?? process.cwd();
112
103
  const slug = slugify(title) || slugify(templateName) || `template-${date}`;
113
104
  const outputPath = path.join(cwd, `${slug}${TEMPLATE_EXTENSION}`);
@@ -143,5 +134,6 @@ function addTemplate(file, options) {
143
134
  export {
144
135
  addTemplate,
145
136
  createFromTemplate,
137
+ listTemplateDefinitions2 as listTemplateDefinitions,
146
138
  listTemplates
147
139
  };
@@ -4,11 +4,11 @@ import {
4
4
  import "../chunk-7ZRP733D.js";
5
5
  import {
6
6
  ClawVault
7
- } from "../chunk-AY4PGUVL.js";
7
+ } from "../chunk-KL4NAOMO.js";
8
8
  import {
9
9
  parseObservationMarkdown
10
10
  } from "../chunk-FHFUXL6G.js";
11
- import "../chunk-O7XHXF7F.js";
11
+ import "../chunk-MAKNAHAW.js";
12
12
  import "../chunk-2CDEETQN.js";
13
13
  import "../chunk-ZZA73MFY.js";
14
14
  import {
package/dist/index.js CHANGED
@@ -1,7 +1,3 @@
1
- import {
2
- buildTemplateVariables,
3
- renderTemplate
4
- } from "./chunk-7766SIJP.js";
5
1
  import {
6
2
  buildSessionRecap,
7
3
  formatSessionRecapMarkdown,
@@ -9,7 +5,7 @@ import {
9
5
  } from "./chunk-ZKGY7WTT.js";
10
6
  import {
11
7
  setupCommand
12
- } from "./chunk-M25QVSJM.js";
8
+ } from "./chunk-RVYA52PY.js";
13
9
  import {
14
10
  registerSyncBdCommand,
15
11
  syncBdCommand
@@ -22,14 +18,14 @@ import {
22
18
  import {
23
19
  rebuildCommand,
24
20
  registerRebuildCommand
25
- } from "./chunk-TPDH3JPP.js";
21
+ } from "./chunk-PBEE567J.js";
26
22
  import {
27
23
  registerReplayCommand,
28
24
  replayCommand
29
- } from "./chunk-4IV3R2F5.js";
25
+ } from "./chunk-4TE4JMLA.js";
30
26
  import {
31
27
  doctor
32
- } from "./chunk-LMEMZGUV.js";
28
+ } from "./chunk-UEOUADMO.js";
33
29
  import "./chunk-7ZRP733D.js";
34
30
  import {
35
31
  graphCommand,
@@ -44,12 +40,12 @@ import {
44
40
  kanbanCommand,
45
41
  parseKanbanMarkdown,
46
42
  syncKanbanBoard
47
- } from "./chunk-J5EMBUPK.js";
43
+ } from "./chunk-4OXMU5S2.js";
48
44
  import "./chunk-4VQTUVH7.js";
49
45
  import "./chunk-J7ZWCI2C.js";
50
46
  import {
51
47
  registerCliCommands
52
- } from "./chunk-FG6RJMCN.js";
48
+ } from "./chunk-HA5M6KJB.js";
53
49
  import {
54
50
  registerTailscaleCommands,
55
51
  registerTailscaleDiscoverCommand,
@@ -60,7 +56,7 @@ import {
60
56
  tailscaleServeCommand,
61
57
  tailscaleStatusCommand,
62
58
  tailscaleSyncCommand
63
- } from "./chunk-NZ4ZZNSR.js";
59
+ } from "./chunk-THRJVD4L.js";
64
60
  import {
65
61
  CLAWVAULT_SERVE_PATH,
66
62
  DEFAULT_SERVE_PORT,
@@ -81,13 +77,13 @@ import {
81
77
  serveVault,
82
78
  stopTailscaleServe,
83
79
  syncWithPeer
84
- } from "./chunk-4GBPTBFJ.js";
85
- import "./chunk-CLE2HHNT.js";
80
+ } from "./chunk-TIGW564L.js";
81
+ import "./chunk-IVRIKYFE.js";
86
82
  import {
87
83
  SessionWatcher,
88
84
  observeCommand,
89
85
  registerObserveCommand
90
- } from "./chunk-OSMS7QIG.js";
86
+ } from "./chunk-ME37YNW3.js";
91
87
  import {
92
88
  parseSessionFile
93
89
  } from "./chunk-P5EPF6MB.js";
@@ -106,19 +102,19 @@ import {
106
102
  normalizeContextProfileInput,
107
103
  registerContextCommand,
108
104
  resolveContextProfile
109
- } from "./chunk-GFJ3LIIB.js";
105
+ } from "./chunk-XAVB4GB4.js";
110
106
  import {
111
107
  getObserverStaleness,
112
108
  getScaledObservationThresholdBytes,
113
109
  observeActiveSessions,
114
110
  parseSessionSourceLabel
115
- } from "./chunk-IZEY5S74.js";
111
+ } from "./chunk-IEVLHNLU.js";
116
112
  import "./chunk-HRLWZGMA.js";
117
113
  import {
118
114
  Compressor,
119
115
  Observer,
120
116
  Reflector
121
- } from "./chunk-S2IG7VNM.js";
117
+ } from "./chunk-Q2J5YTUF.js";
122
118
  import {
123
119
  archiveProject,
124
120
  createProject,
@@ -127,17 +123,17 @@ import {
127
123
  listProjects,
128
124
  readProject,
129
125
  updateProject
130
- } from "./chunk-5GZFTAL7.js";
126
+ } from "./chunk-AZYOKJYC.js";
131
127
  import {
132
128
  ClawVault,
133
129
  createVault,
134
130
  findVault
135
- } from "./chunk-AY4PGUVL.js";
131
+ } from "./chunk-KL4NAOMO.js";
136
132
  import "./chunk-FHFUXL6G.js";
137
133
  import {
138
134
  embedCommand,
139
135
  registerEmbedCommand
140
- } from "./chunk-3FP5BJ42.js";
136
+ } from "./chunk-4QYGFWRM.js";
141
137
  import {
142
138
  QMD_INSTALL_COMMAND,
143
139
  QMD_INSTALL_URL,
@@ -148,7 +144,7 @@ import {
148
144
  hasQmd,
149
145
  qmdEmbed,
150
146
  qmdUpdate
151
- } from "./chunk-O7XHXF7F.js";
147
+ } from "./chunk-MAKNAHAW.js";
152
148
  import {
153
149
  buildInjectionResult,
154
150
  deterministicInjectMatches,
@@ -211,7 +207,12 @@ import {
211
207
  queryTransitions,
212
208
  readAllTransitions,
213
209
  updateTask
214
- } from "./chunk-IOALNTAN.js";
210
+ } from "./chunk-QWQ3TIKS.js";
211
+ import "./chunk-MFAWT5O5.js";
212
+ import {
213
+ buildTemplateVariables,
214
+ renderTemplate
215
+ } from "./chunk-7766SIJP.js";
215
216
  import {
216
217
  checkOpenClawCompatibility,
217
218
  compatCommand,
@@ -6,8 +6,10 @@ import {
6
6
  listProjects,
7
7
  readProject,
8
8
  updateProject
9
- } from "../chunk-5GZFTAL7.js";
10
- import "../chunk-IOALNTAN.js";
9
+ } from "../chunk-AZYOKJYC.js";
10
+ import "../chunk-QWQ3TIKS.js";
11
+ import "../chunk-MFAWT5O5.js";
12
+ import "../chunk-7766SIJP.js";
11
13
  export {
12
14
  archiveProject,
13
15
  createProject,
@@ -21,8 +21,8 @@ import {
21
21
  serveVault,
22
22
  stopTailscaleServe,
23
23
  syncWithPeer
24
- } from "../chunk-4GBPTBFJ.js";
25
- import "../chunk-CLE2HHNT.js";
24
+ } from "../chunk-TIGW564L.js";
25
+ import "../chunk-IVRIKYFE.js";
26
26
  export {
27
27
  CLAWVAULT_SERVE_PATH,
28
28
  DEFAULT_SERVE_PORT,
@@ -63,6 +63,19 @@ interface TaskTransitionOptions {
63
63
  confidence?: number;
64
64
  reason?: string | null;
65
65
  }
66
+ type CreateTaskOptions = {
67
+ source?: string;
68
+ owner?: string;
69
+ project?: string;
70
+ priority?: TaskPriority;
71
+ due?: string;
72
+ content?: string;
73
+ tags?: string[];
74
+ description?: string;
75
+ estimate?: string;
76
+ parent?: string;
77
+ depends_on?: string[];
78
+ };
66
79
  /**
67
80
  * Slugify a title for use as filename
68
81
  * Deterministic: same title = same slug
@@ -111,19 +124,7 @@ declare function listBacklogItems(vaultPath: string, filters?: BacklogFilterOpti
111
124
  /**
112
125
  * Create a new task
113
126
  */
114
- declare function createTask(vaultPath: string, title: string, options?: {
115
- source?: string;
116
- owner?: string;
117
- project?: string;
118
- priority?: TaskPriority;
119
- due?: string;
120
- content?: string;
121
- tags?: string[];
122
- description?: string;
123
- estimate?: string;
124
- parent?: string;
125
- depends_on?: string[];
126
- }): Task;
127
+ declare function createTask(vaultPath: string, title: string, options?: CreateTaskOptions): Task;
127
128
  /**
128
129
  * Update an existing task
129
130
  */
@@ -23,7 +23,9 @@ import {
23
23
  slugify,
24
24
  updateBacklogItem,
25
25
  updateTask
26
- } from "../chunk-IOALNTAN.js";
26
+ } from "../chunk-QWQ3TIKS.js";
27
+ import "../chunk-MFAWT5O5.js";
28
+ import "../chunk-7766SIJP.js";
27
29
  export {
28
30
  completeTask,
29
31
  createBacklogItem,
@@ -3,6 +3,7 @@ interface TemplateVariables {
3
3
  date: string;
4
4
  datetime: string;
5
5
  type: string;
6
+ [key: string]: string | number | boolean | null | undefined;
6
7
  }
7
8
  declare function buildTemplateVariables(input?: Partial<TemplateVariables>, now?: Date): TemplateVariables;
8
9
  declare function renderTemplate(template: string, variables: TemplateVariables): string;
@@ -14,7 +14,7 @@ import {
14
14
  handlePut,
15
15
  isPathSafe,
16
16
  resolveWebDAVPath
17
- } from "../chunk-CLE2HHNT.js";
17
+ } from "../chunk-IVRIKYFE.js";
18
18
  export {
19
19
  WEBDAV_PREFIX,
20
20
  checkAuth,
@@ -1,83 +1,83 @@
1
- ---
2
- name: clawvault
3
- description: "Context resilience - recovery detection, auto-checkpoint, and session context injection"
4
- metadata:
5
- openclaw:
6
- emoji: "🐘"
7
- events: ["gateway:startup", "gateway:heartbeat", "command:new", "session:start", "compaction:memoryFlush", "cron.weekly"]
8
- requires:
9
- bins: ["clawvault"]
10
- ---
11
-
12
- # ClawVault Hook
13
-
14
- Integrates ClawVault's context death resilience into OpenClaw:
15
-
16
- - **On gateway startup**: Checks for context death, alerts agent
17
- - **On heartbeat**: Runs cheap threshold checks and observes active sessions when needed
18
- - **On /new command**: Auto-checkpoints before session reset
19
- - **On context compaction**: Forces incremental observation flush before context is lost
20
- - **On session start**: Injects relevant vault context for the initial prompt
21
- - **On weekly cron**: Runs `clawvault reflect` every Sunday midnight (UTC)
22
-
23
- ## Installation
24
-
25
- ```bash
26
- npm install -g clawvault
27
- openclaw hooks install clawvault
28
- openclaw hooks enable clawvault
29
-
30
- # Verify
31
- openclaw hooks list --verbose
32
- openclaw hooks info clawvault
33
- openclaw hooks check
34
- ```
35
-
36
- After enabling, restart your OpenClaw gateway process so hook registration reloads.
37
-
38
- ## Requirements
39
-
40
- - ClawVault CLI installed globally
41
- - Vault initialized (`clawvault setup` or `CLAWVAULT_PATH` set)
42
-
43
- ## What It Does
44
-
45
- ### Gateway Startup
46
-
47
- 1. Runs `clawvault recover --clear`
48
- 2. If context death detected, injects warning into first agent turn
49
- 3. Clears dirty death flag for clean session start
50
-
51
- ### Command: /new
52
-
53
- 1. Creates automatic checkpoint with session info
54
- 2. Captures state even if agent forgot to handoff
55
- 3. Ensures continuity across session resets
56
-
57
- ### Session Start
58
-
59
- 1. Extracts the initial user prompt (`context.initialPrompt` or first user message)
60
- 2. Runs `clawvault context "<prompt>" --format json --profile auto -v <vaultPath>`
61
- - Delegates profile selection to the shared context intent policy (`incident`, `planning`, `handoff`, or `default`)
62
- 3. Injects up to 4 relevant context bullets into session messages
63
-
64
- Injection format:
65
-
66
- ```text
67
- [ClawVault] Relevant context for this task:
68
- - <title> (<age>): <snippet>
69
- - <title> (<age>): <snippet>
70
- ```
71
-
72
- ### Event Compatibility
73
-
74
- The hook accepts canonical OpenClaw events (`gateway:startup`, `gateway:heartbeat`, `command:new`, `session:start`, `compaction:memoryFlush`, `cron.weekly`) and tolerates alias payload shapes (`event`, `eventName`, `name`, `hook`, `trigger`) to remain robust across runtime wrappers.
75
-
76
- ## Configuration Notes
77
-
78
- The hook auto-detects vault path via:
79
-
80
- 1. `CLAWVAULT_PATH` environment variable
81
- 2. Walking up from cwd to find `.clawvault.json`
82
-
83
- If `openclaw hooks enable clawvault` fails with hook-not-found, run `openclaw hooks install clawvault` first and verify discovery with `openclaw hooks list --verbose`.
1
+ ---
2
+ name: clawvault
3
+ description: "Context resilience - recovery detection, auto-checkpoint, and session context injection"
4
+ metadata:
5
+ openclaw:
6
+ emoji: "🐘"
7
+ events: ["gateway:startup", "gateway:heartbeat", "command:new", "session:start", "compaction:memoryFlush", "cron.weekly"]
8
+ requires:
9
+ bins: ["clawvault"]
10
+ ---
11
+
12
+ # ClawVault Hook
13
+
14
+ Integrates ClawVault's context death resilience into OpenClaw:
15
+
16
+ - **On gateway startup**: Checks for context death, alerts agent
17
+ - **On heartbeat**: Runs cheap threshold checks and observes active sessions when needed
18
+ - **On /new command**: Auto-checkpoints before session reset
19
+ - **On context compaction**: Forces incremental observation flush before context is lost
20
+ - **On session start**: Injects relevant vault context for the initial prompt
21
+ - **On weekly cron**: Runs `clawvault reflect` every Sunday midnight (UTC)
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install -g clawvault
27
+ openclaw hooks install clawvault
28
+ openclaw hooks enable clawvault
29
+
30
+ # Verify
31
+ openclaw hooks list --verbose
32
+ openclaw hooks info clawvault
33
+ openclaw hooks check
34
+ ```
35
+
36
+ After enabling, restart your OpenClaw gateway process so hook registration reloads.
37
+
38
+ ## Requirements
39
+
40
+ - ClawVault CLI installed globally
41
+ - Vault initialized (`clawvault setup` or `CLAWVAULT_PATH` set)
42
+
43
+ ## What It Does
44
+
45
+ ### Gateway Startup
46
+
47
+ 1. Runs `clawvault recover --clear`
48
+ 2. If context death detected, injects warning into first agent turn
49
+ 3. Clears dirty death flag for clean session start
50
+
51
+ ### Command: /new
52
+
53
+ 1. Creates automatic checkpoint with session info
54
+ 2. Captures state even if agent forgot to handoff
55
+ 3. Ensures continuity across session resets
56
+
57
+ ### Session Start
58
+
59
+ 1. Extracts the initial user prompt (`context.initialPrompt` or first user message)
60
+ 2. Runs `clawvault context "<prompt>" --format json --profile auto -v <vaultPath>`
61
+ - Delegates profile selection to the shared context intent policy (`incident`, `planning`, `handoff`, or `default`)
62
+ 3. Injects up to 4 relevant context bullets into session messages
63
+
64
+ Injection format:
65
+
66
+ ```text
67
+ [ClawVault] Relevant context for this task:
68
+ - <title> (<age>): <snippet>
69
+ - <title> (<age>): <snippet>
70
+ ```
71
+
72
+ ### Event Compatibility
73
+
74
+ The hook accepts canonical OpenClaw events (`gateway:startup`, `gateway:heartbeat`, `command:new`, `session:start`, `compaction:memoryFlush`, `cron.weekly`) and tolerates alias payload shapes (`event`, `eventName`, `name`, `hook`, `trigger`) to remain robust across runtime wrappers.
75
+
76
+ ## Configuration Notes
77
+
78
+ The hook auto-detects vault path via:
79
+
80
+ 1. `CLAWVAULT_PATH` environment variable
81
+ 2. Walking up from cwd to find `.clawvault.json`
82
+
83
+ If `openclaw hooks enable clawvault` fails with hook-not-found, run `openclaw hooks install clawvault` first and verify discovery with `openclaw hooks list --verbose`.