clawvault 2.6.3 → 2.6.4

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 (123) hide show
  1. package/README.md +351 -21
  2. package/bin/clawvault.js +8 -2
  3. package/bin/command-runtime.js +9 -1
  4. package/bin/register-maintenance-commands.js +19 -0
  5. package/bin/register-query-commands.js +58 -6
  6. package/bin/register-workgraph-commands.js +451 -0
  7. package/dist/{chunk-VXEOHTSL.js → chunk-2JQ3O2YL.js} +1 -1
  8. package/dist/{chunk-VR5NE7PZ.js → chunk-2RAZ4ZFE.js} +1 -1
  9. package/dist/chunk-2ZDO52B4.js +52 -0
  10. package/dist/chunk-4BQTQMJP.js +93 -0
  11. package/dist/{chunk-MAKNAHAW.js → chunk-5PJ4STIC.js} +98 -8
  12. package/dist/{chunk-IEVLHNLU.js → chunk-627Q3QWK.js} +3 -3
  13. package/dist/{chunk-R6SXNSFD.js → chunk-6NYYDNNG.js} +3 -3
  14. package/dist/chunk-ECRZL5XR.js +50 -0
  15. package/dist/chunk-GNJL4YGR.js +79 -0
  16. package/dist/{chunk-OZ7RIXTO.js → chunk-IIOU45CK.js} +1 -1
  17. package/dist/chunk-L4HSSQ6T.js +152 -0
  18. package/dist/{chunk-DTEHFAL7.js → chunk-LIGHWOH6.js} +1 -1
  19. package/dist/{chunk-PBEE567J.js → chunk-LUBZXECN.js} +2 -2
  20. package/dist/{chunk-PZ2AUU2W.js → chunk-MFL6EEPF.js} +204 -35
  21. package/dist/chunk-MM6QGW3P.js +207 -0
  22. package/dist/{chunk-T76H47ZS.js → chunk-MNPUYCHQ.js} +1 -1
  23. package/dist/{chunk-6546Q4OR.js → chunk-MPOSMDMU.js} +6 -6
  24. package/dist/{chunk-RVYA52PY.js → chunk-NJYJL5AA.js} +1 -1
  25. package/dist/{chunk-Q2J5YTUF.js → chunk-OQGYFZ4A.js} +669 -33
  26. package/dist/{chunk-ME37YNW3.js → chunk-P7SY3D4E.js} +3 -3
  27. package/dist/chunk-RHISK3SZ.js +189 -0
  28. package/dist/{chunk-3BTHWPMB.js → chunk-S5OJEGFG.js} +2 -2
  29. package/dist/{chunk-MGDEINGP.js → chunk-SS4B7P7V.js} +1 -1
  30. package/dist/chunk-U4O6C46S.js +154 -0
  31. package/dist/{chunk-ITPEXLHA.js → chunk-URXDAUVH.js} +24 -5
  32. package/dist/chunk-WIOLLGAD.js +190 -0
  33. package/dist/chunk-WMGIIABP.js +15 -0
  34. package/dist/{chunk-QVMXF7FY.js → chunk-X3SPPUFG.js} +50 -0
  35. package/dist/{chunk-THRJVD4L.js → chunk-Y6VJKXGL.js} +1 -1
  36. package/dist/{chunk-RCBMXTWS.js → chunk-YDWHS4LJ.js} +21 -6
  37. package/dist/{chunk-4VRIMU4O.js → chunk-YNIPYN4F.js} +4 -4
  38. package/dist/{chunk-HIHOUSXS.js → chunk-YXQCA6B7.js} +105 -1
  39. package/dist/cli/index.js +18 -16
  40. package/dist/commands/archive.js +3 -2
  41. package/dist/commands/backlog.js +1 -0
  42. package/dist/commands/blocked.js +1 -0
  43. package/dist/commands/canvas.js +1 -0
  44. package/dist/commands/checkpoint.js +1 -0
  45. package/dist/commands/compat.js +2 -1
  46. package/dist/commands/context.js +5 -3
  47. package/dist/commands/doctor.d.ts +10 -1
  48. package/dist/commands/doctor.js +11 -8
  49. package/dist/commands/embed.js +5 -3
  50. package/dist/commands/entities.js +2 -1
  51. package/dist/commands/graph.js +3 -2
  52. package/dist/commands/inject.d.ts +1 -1
  53. package/dist/commands/inject.js +4 -3
  54. package/dist/commands/kanban.js +1 -0
  55. package/dist/commands/link.js +2 -1
  56. package/dist/commands/migrate-observations.js +3 -2
  57. package/dist/commands/observe.js +8 -6
  58. package/dist/commands/project.js +1 -0
  59. package/dist/commands/rebuild-embeddings.d.ts +21 -0
  60. package/dist/commands/rebuild-embeddings.js +91 -0
  61. package/dist/commands/rebuild.js +6 -4
  62. package/dist/commands/recover.js +1 -0
  63. package/dist/commands/reflect.js +5 -4
  64. package/dist/commands/repair-session.js +1 -0
  65. package/dist/commands/replay.js +7 -6
  66. package/dist/commands/session-recap.js +1 -0
  67. package/dist/commands/setup.js +3 -2
  68. package/dist/commands/shell-init.js +2 -0
  69. package/dist/commands/sleep.d.ts +1 -1
  70. package/dist/commands/sleep.js +8 -6
  71. package/dist/commands/status.js +11 -80
  72. package/dist/commands/sync-bd.js +3 -2
  73. package/dist/commands/tailscale.js +3 -2
  74. package/dist/commands/task.js +1 -0
  75. package/dist/commands/template.js +1 -0
  76. package/dist/commands/wake.d.ts +1 -1
  77. package/dist/commands/wake.js +4 -2
  78. package/dist/index.d.ts +247 -10
  79. package/dist/index.js +285 -152
  80. package/dist/{inject-x65KXWPk.d.ts → inject-DYUrDqQO.d.ts} +2 -2
  81. package/dist/ledger-B7g7jhqG.d.ts +44 -0
  82. package/dist/lib/auto-linker.js +1 -0
  83. package/dist/lib/canvas-layout.js +1 -0
  84. package/dist/lib/config.d.ts +27 -3
  85. package/dist/lib/config.js +4 -1
  86. package/dist/lib/entity-index.js +1 -0
  87. package/dist/lib/project-utils.js +1 -0
  88. package/dist/lib/session-repair.js +1 -0
  89. package/dist/lib/session-utils.js +1 -0
  90. package/dist/lib/tailscale.js +1 -0
  91. package/dist/lib/task-utils.js +1 -0
  92. package/dist/lib/template-engine.js +1 -0
  93. package/dist/lib/webdav.js +1 -0
  94. package/dist/onnxruntime_binding-5QEF3SUC.node +0 -0
  95. package/dist/onnxruntime_binding-BKPKNEGC.node +0 -0
  96. package/dist/onnxruntime_binding-FMOXGIUT.node +0 -0
  97. package/dist/onnxruntime_binding-OI2KMXC5.node +0 -0
  98. package/dist/onnxruntime_binding-UX44MLAZ.node +0 -0
  99. package/dist/onnxruntime_binding-Y2W7N7WY.node +0 -0
  100. package/dist/registry-BR4326o0.d.ts +30 -0
  101. package/dist/store-CA-6sKCJ.d.ts +34 -0
  102. package/dist/thread-B9LhXNU0.d.ts +41 -0
  103. package/dist/transformers.node-A2ZRORSQ.js +46775 -0
  104. package/dist/{types-C74wgGL1.d.ts → types-BbWJoC1c.d.ts} +1 -1
  105. package/dist/workgraph/index.d.ts +5 -0
  106. package/dist/workgraph/index.js +23 -0
  107. package/dist/workgraph/ledger.d.ts +2 -0
  108. package/dist/workgraph/ledger.js +25 -0
  109. package/dist/workgraph/registry.d.ts +2 -0
  110. package/dist/workgraph/registry.js +19 -0
  111. package/dist/workgraph/store.d.ts +2 -0
  112. package/dist/workgraph/store.js +25 -0
  113. package/dist/workgraph/thread.d.ts +2 -0
  114. package/dist/workgraph/thread.js +25 -0
  115. package/dist/workgraph/types.d.ts +54 -0
  116. package/dist/workgraph/types.js +7 -0
  117. package/hooks/clawvault/handler.js +714 -2
  118. package/hooks/clawvault/handler.test.js +153 -0
  119. package/hooks/clawvault/openclaw.plugin.json +72 -0
  120. package/openclaw.plugin.json +14 -2
  121. package/package.json +5 -4
  122. package/dist/chunk-4QYGFWRM.js +0 -88
  123. package/dist/chunk-MXSSG3QU.js +0 -42
@@ -0,0 +1,451 @@
1
+ /**
2
+ * Workgraph CLI commands — multi-agent coordination primitives.
3
+ *
4
+ * Commands:
5
+ * thread create <title> Create a new thread
6
+ * thread list List threads (filterable by status)
7
+ * thread show <path> Show thread details + ledger history
8
+ * thread claim <path> Claim a thread for this agent
9
+ * thread release <path> Release a claimed thread
10
+ * thread done <path> Mark thread complete
11
+ * thread block <path> Mark thread blocked
12
+ * thread unblock <path> Unblock a thread
13
+ * thread decompose <path> Break into sub-threads
14
+ * primitive define <name> Define a new primitive type
15
+ * primitive list List all primitive types
16
+ * primitive create <type> Create an instance of any type
17
+ * ledger show Show recent ledger entries
18
+ * ledger history <path> Show history of a specific file
19
+ */
20
+
21
+ export function registerWorkgraphCommands(program, { chalk, resolveVaultPath }) {
22
+ const agentName = process.env.CLAWVAULT_AGENT || process.env.USER || 'anonymous';
23
+
24
+ // =========================================================================
25
+ // thread
26
+ // =========================================================================
27
+ const threadCmd = program
28
+ .command('thread')
29
+ .description('Coordinate work through threads (workgraph core)');
30
+
31
+ threadCmd
32
+ .command('create <title>')
33
+ .description('Create a new thread')
34
+ .requiredOption('-g, --goal <goal>', 'What success looks like')
35
+ .option('-v, --vault <path>', 'Vault path')
36
+ .option('-a, --actor <name>', 'Agent name', agentName)
37
+ .option('-p, --priority <level>', 'urgent | high | medium | low', 'medium')
38
+ .option('--deps <paths>', 'Comma-separated dependency thread paths')
39
+ .option('--parent <path>', 'Parent thread path')
40
+ .option('--context <refs>', 'Comma-separated vault doc refs for context')
41
+ .option('--tags <tags>', 'Comma-separated tags')
42
+ .action(async (title, opts) => {
43
+ try {
44
+ const vaultPath = resolveVaultPath(opts.vault);
45
+ const { thread } = await import('../dist/workgraph/index.js');
46
+ const t = thread.createThread(vaultPath, title, opts.goal, opts.actor, {
47
+ priority: opts.priority,
48
+ deps: csv(opts.deps),
49
+ parent: opts.parent,
50
+ context_refs: csv(opts.context),
51
+ tags: csv(opts.tags),
52
+ });
53
+ console.log(chalk.green(`✓ Thread created: ${t.path}`));
54
+ console.log(` Title: ${t.fields.title}`);
55
+ console.log(` Status: ${t.fields.status}`);
56
+ console.log(` Priority: ${t.fields.priority}`);
57
+ } catch (err) {
58
+ console.error(chalk.red(`Error: ${err.message}`));
59
+ process.exit(1);
60
+ }
61
+ });
62
+
63
+ threadCmd
64
+ .command('list')
65
+ .description('List threads')
66
+ .option('-v, --vault <path>', 'Vault path')
67
+ .option('-s, --status <status>', 'Filter: open | active | blocked | done | cancelled')
68
+ .option('--json', 'Output as JSON')
69
+ .action(async (opts) => {
70
+ try {
71
+ const vaultPath = resolveVaultPath(opts.vault);
72
+ const { store } = await import('../dist/workgraph/index.js');
73
+ let threads = store.list(vaultPath, 'thread');
74
+ if (opts.status) threads = threads.filter(t => t.fields.status === opts.status);
75
+
76
+ if (opts.json) {
77
+ console.log(JSON.stringify(threads.map(t => ({ path: t.path, ...t.fields })), null, 2));
78
+ return;
79
+ }
80
+
81
+ if (threads.length === 0) {
82
+ console.log(chalk.dim('No threads found.'));
83
+ return;
84
+ }
85
+
86
+ const statusColor = { open: 'blue', active: 'yellow', blocked: 'red', done: 'green', cancelled: 'dim' };
87
+ for (const t of threads) {
88
+ const s = String(t.fields.status);
89
+ const colorFn = chalk[statusColor[s]] || chalk.white;
90
+ const owner = t.fields.owner ? chalk.dim(` (${t.fields.owner})`) : '';
91
+ console.log(` ${colorFn(`[${s}]`)} ${t.fields.title}${owner}`);
92
+ console.log(chalk.dim(` ${t.path}`));
93
+ }
94
+ console.log(chalk.dim(`\n${threads.length} thread(s)`));
95
+ } catch (err) {
96
+ console.error(chalk.red(`Error: ${err.message}`));
97
+ process.exit(1);
98
+ }
99
+ });
100
+
101
+ threadCmd
102
+ .command('show <path>')
103
+ .description('Show thread details and ledger history')
104
+ .option('-v, --vault <path>', 'Vault path')
105
+ .action(async (threadPath, opts) => {
106
+ try {
107
+ const vaultPath = resolveVaultPath(opts.vault);
108
+ const { store, ledger } = await import('../dist/workgraph/index.js');
109
+ const t = store.read(vaultPath, threadPath);
110
+ if (!t) { console.error(chalk.red(`Not found: ${threadPath}`)); process.exit(1); }
111
+
112
+ console.log(chalk.bold(String(t.fields.title)));
113
+ console.log(chalk.dim('─'.repeat(50)));
114
+ console.log(`Status: ${t.fields.status}`);
115
+ console.log(`Owner: ${t.fields.owner || chalk.dim('unclaimed')}`);
116
+ console.log(`Priority: ${t.fields.priority}`);
117
+ if (t.fields.deps?.length) console.log(`Deps: ${(t.fields.deps).join(', ')}`);
118
+ if (t.fields.parent) console.log(`Parent: ${t.fields.parent}`);
119
+ if (t.fields.tags?.length) console.log(`Tags: ${(t.fields.tags).join(', ')}`);
120
+ console.log(`Path: ${t.path}`);
121
+ console.log();
122
+ if (t.body) console.log(t.body);
123
+
124
+ const history = ledger.historyOf(vaultPath, threadPath);
125
+ if (history.length > 0) {
126
+ console.log(chalk.dim('\n─── Ledger History ───'));
127
+ for (const e of history) {
128
+ const time = new Date(e.ts).toLocaleTimeString();
129
+ const data = e.data ? chalk.dim(` ${JSON.stringify(e.data)}`) : '';
130
+ console.log(` ${chalk.dim(time)} ${chalk.cyan(e.op)} by ${e.actor}${data}`);
131
+ }
132
+ }
133
+ } catch (err) {
134
+ console.error(chalk.red(`Error: ${err.message}`));
135
+ process.exit(1);
136
+ }
137
+ });
138
+
139
+ threadCmd
140
+ .command('claim <path>')
141
+ .description('Claim a thread — only you can work on it')
142
+ .option('-v, --vault <path>', 'Vault path')
143
+ .option('-a, --actor <name>', 'Agent name', agentName)
144
+ .action(async (threadPath, opts) => {
145
+ try {
146
+ const vaultPath = resolveVaultPath(opts.vault);
147
+ const { thread } = await import('../dist/workgraph/index.js');
148
+ const t = thread.claim(vaultPath, threadPath, opts.actor);
149
+ console.log(chalk.green(`✓ Claimed: ${threadPath}`));
150
+ console.log(` Owner: ${opts.actor}`);
151
+ } catch (err) {
152
+ console.error(chalk.red(`Error: ${err.message}`));
153
+ process.exit(1);
154
+ }
155
+ });
156
+
157
+ threadCmd
158
+ .command('release <path>')
159
+ .description('Release a claimed thread back to open')
160
+ .option('-v, --vault <path>', 'Vault path')
161
+ .option('-a, --actor <name>', 'Agent name', agentName)
162
+ .option('--reason <reason>', 'Why you are releasing')
163
+ .action(async (threadPath, opts) => {
164
+ try {
165
+ const vaultPath = resolveVaultPath(opts.vault);
166
+ const { thread } = await import('../dist/workgraph/index.js');
167
+ thread.release(vaultPath, threadPath, opts.actor, opts.reason);
168
+ console.log(chalk.green(`✓ Released: ${threadPath}`));
169
+ } catch (err) {
170
+ console.error(chalk.red(`Error: ${err.message}`));
171
+ process.exit(1);
172
+ }
173
+ });
174
+
175
+ threadCmd
176
+ .command('done <path>')
177
+ .description('Mark thread complete')
178
+ .option('-v, --vault <path>', 'Vault path')
179
+ .option('-a, --actor <name>', 'Agent name', agentName)
180
+ .option('-o, --output <text>', 'Output/result summary')
181
+ .action(async (threadPath, opts) => {
182
+ try {
183
+ const vaultPath = resolveVaultPath(opts.vault);
184
+ const { thread } = await import('../dist/workgraph/index.js');
185
+ thread.done(vaultPath, threadPath, opts.actor, opts.output);
186
+ console.log(chalk.green(`✓ Done: ${threadPath}`));
187
+ } catch (err) {
188
+ console.error(chalk.red(`Error: ${err.message}`));
189
+ process.exit(1);
190
+ }
191
+ });
192
+
193
+ threadCmd
194
+ .command('block <path>')
195
+ .description('Mark thread blocked on a dependency')
196
+ .option('-v, --vault <path>', 'Vault path')
197
+ .option('-a, --actor <name>', 'Agent name', agentName)
198
+ .requiredOption('-b, --blocked-by <dep>', 'What is blocking this thread')
199
+ .option('--reason <reason>', 'Why it is blocked')
200
+ .action(async (threadPath, opts) => {
201
+ try {
202
+ const vaultPath = resolveVaultPath(opts.vault);
203
+ const { thread } = await import('../dist/workgraph/index.js');
204
+ thread.block(vaultPath, threadPath, opts.actor, opts.blockedBy, opts.reason);
205
+ console.log(chalk.red(`⊘ Blocked: ${threadPath}`));
206
+ console.log(` Blocked by: ${opts.blockedBy}`);
207
+ } catch (err) {
208
+ console.error(chalk.red(`Error: ${err.message}`));
209
+ process.exit(1);
210
+ }
211
+ });
212
+
213
+ threadCmd
214
+ .command('unblock <path>')
215
+ .description('Unblock a thread')
216
+ .option('-v, --vault <path>', 'Vault path')
217
+ .option('-a, --actor <name>', 'Agent name', agentName)
218
+ .action(async (threadPath, opts) => {
219
+ try {
220
+ const vaultPath = resolveVaultPath(opts.vault);
221
+ const { thread } = await import('../dist/workgraph/index.js');
222
+ thread.unblock(vaultPath, threadPath, opts.actor);
223
+ console.log(chalk.green(`✓ Unblocked: ${threadPath}`));
224
+ } catch (err) {
225
+ console.error(chalk.red(`Error: ${err.message}`));
226
+ process.exit(1);
227
+ }
228
+ });
229
+
230
+ threadCmd
231
+ .command('decompose <path>')
232
+ .description('Break a thread into sub-threads')
233
+ .option('-v, --vault <path>', 'Vault path')
234
+ .option('-a, --actor <name>', 'Agent name', agentName)
235
+ .requiredOption('--sub <specs...>', 'Sub-threads as "title|goal" pairs')
236
+ .action(async (threadPath, opts) => {
237
+ try {
238
+ const vaultPath = resolveVaultPath(opts.vault);
239
+ const { thread } = await import('../dist/workgraph/index.js');
240
+ const subs = opts.sub.map(spec => {
241
+ const [title, ...goalParts] = spec.split('|');
242
+ return { title: title.trim(), goal: goalParts.join('|').trim() || title.trim() };
243
+ });
244
+ const children = thread.decompose(vaultPath, threadPath, subs, opts.actor);
245
+ console.log(chalk.green(`✓ Decomposed ${threadPath} into ${children.length} sub-threads:`));
246
+ for (const c of children) {
247
+ console.log(` → ${c.path}`);
248
+ }
249
+ } catch (err) {
250
+ console.error(chalk.red(`Error: ${err.message}`));
251
+ process.exit(1);
252
+ }
253
+ });
254
+
255
+ // =========================================================================
256
+ // primitive
257
+ // =========================================================================
258
+ const primitiveCmd = program
259
+ .command('primitive')
260
+ .description('Manage workgraph primitive types (define new types, list, create)');
261
+
262
+ primitiveCmd
263
+ .command('define <name>')
264
+ .description('Define a new primitive type that agents can instantiate')
265
+ .requiredOption('-d, --description <desc>', 'What this type represents')
266
+ .option('-v, --vault <path>', 'Vault path')
267
+ .option('-a, --actor <name>', 'Agent name', agentName)
268
+ .option('--fields <specs...>', 'Field definitions as "name:type" (types: string, number, boolean, list, date, ref)')
269
+ .option('--dir <directory>', 'Storage directory name')
270
+ .action(async (name, opts) => {
271
+ try {
272
+ const vaultPath = resolveVaultPath(opts.vault);
273
+ const { registry } = await import('../dist/workgraph/index.js');
274
+ const fields = {};
275
+ if (opts.fields) {
276
+ for (const spec of opts.fields) {
277
+ const [fieldName, fieldType = 'string'] = spec.split(':');
278
+ fields[fieldName.trim()] = { type: fieldType.trim() };
279
+ }
280
+ }
281
+ const typeDef = registry.defineType(vaultPath, name, opts.description, fields, opts.actor, opts.dir);
282
+ console.log(chalk.green(`✓ Defined type: ${typeDef.name}`));
283
+ console.log(` Directory: ${typeDef.directory}/`);
284
+ console.log(` Fields: ${Object.keys(typeDef.fields).join(', ')}`);
285
+ } catch (err) {
286
+ console.error(chalk.red(`Error: ${err.message}`));
287
+ process.exit(1);
288
+ }
289
+ });
290
+
291
+ primitiveCmd
292
+ .command('list')
293
+ .description('List all registered primitive types')
294
+ .option('-v, --vault <path>', 'Vault path')
295
+ .option('--json', 'Output as JSON')
296
+ .action(async (opts) => {
297
+ try {
298
+ const vaultPath = resolveVaultPath(opts.vault);
299
+ const { registry } = await import('../dist/workgraph/index.js');
300
+ const types = registry.listTypes(vaultPath);
301
+
302
+ if (opts.json) {
303
+ console.log(JSON.stringify(types, null, 2));
304
+ return;
305
+ }
306
+
307
+ for (const t of types) {
308
+ const badge = t.builtIn ? chalk.dim('[built-in]') : chalk.cyan(`[${t.createdBy}]`);
309
+ console.log(` ${chalk.bold(t.name)} ${badge}`);
310
+ console.log(chalk.dim(` ${t.description}`));
311
+ console.log(chalk.dim(` dir: ${t.directory}/ fields: ${Object.keys(t.fields).join(', ')}`));
312
+ }
313
+ console.log(chalk.dim(`\n${types.length} type(s) — ${types.filter(t => !t.builtIn).length} agent-defined`));
314
+ } catch (err) {
315
+ console.error(chalk.red(`Error: ${err.message}`));
316
+ process.exit(1);
317
+ }
318
+ });
319
+
320
+ primitiveCmd
321
+ .command('create <type> <title>')
322
+ .description('Create an instance of any primitive type')
323
+ .option('-v, --vault <path>', 'Vault path')
324
+ .option('-a, --actor <name>', 'Agent name', agentName)
325
+ .option('--set <fields...>', 'Set fields as "key=value" pairs')
326
+ .option('--body <text>', 'Markdown body content', '')
327
+ .action(async (type, title, opts) => {
328
+ try {
329
+ const vaultPath = resolveVaultPath(opts.vault);
330
+ const { store } = await import('../dist/workgraph/index.js');
331
+ const fields = { title };
332
+ if (opts.set) {
333
+ for (const pair of opts.set) {
334
+ const eqIdx = pair.indexOf('=');
335
+ if (eqIdx === -1) continue;
336
+ const key = pair.slice(0, eqIdx).trim();
337
+ let val = pair.slice(eqIdx + 1).trim();
338
+ if (val.includes(',')) val = val.split(',').map(s => s.trim());
339
+ fields[key] = val;
340
+ }
341
+ }
342
+ const inst = store.create(vaultPath, type, fields, opts.body, opts.actor);
343
+ console.log(chalk.green(`✓ Created ${type}: ${inst.path}`));
344
+ } catch (err) {
345
+ console.error(chalk.red(`Error: ${err.message}`));
346
+ process.exit(1);
347
+ }
348
+ });
349
+
350
+ // =========================================================================
351
+ // ledger
352
+ // =========================================================================
353
+ const ledgerCmd = program
354
+ .command('ledger')
355
+ .description('View the workgraph audit trail');
356
+
357
+ ledgerCmd
358
+ .command('show')
359
+ .description('Show recent ledger entries')
360
+ .option('-v, --vault <path>', 'Vault path')
361
+ .option('-n, --count <n>', 'Number of entries', '20')
362
+ .option('--actor <name>', 'Filter by actor')
363
+ .option('--json', 'Output as JSON')
364
+ .action(async (opts) => {
365
+ try {
366
+ const vaultPath = resolveVaultPath(opts.vault);
367
+ const { ledger } = await import('../dist/workgraph/index.js');
368
+ let entries = ledger.recent(vaultPath, parseInt(opts.count));
369
+ if (opts.actor) entries = entries.filter(e => e.actor === opts.actor);
370
+
371
+ if (opts.json) {
372
+ console.log(JSON.stringify(entries, null, 2));
373
+ return;
374
+ }
375
+
376
+ if (entries.length === 0) {
377
+ console.log(chalk.dim('No ledger entries.'));
378
+ return;
379
+ }
380
+
381
+ const opColor = { create: 'green', claim: 'yellow', release: 'blue', done: 'green', block: 'red', unblock: 'cyan', cancel: 'dim', update: 'white', delete: 'red', define: 'magenta', decompose: 'cyan' };
382
+ for (const e of entries) {
383
+ const time = new Date(e.ts).toLocaleString();
384
+ const colorFn = chalk[opColor[e.op]] || chalk.white;
385
+ const data = e.data ? chalk.dim(` ${JSON.stringify(e.data)}`) : '';
386
+ console.log(` ${chalk.dim(time)} ${colorFn(e.op.padEnd(10))} ${e.actor.padEnd(15)} ${e.target}${data}`);
387
+ }
388
+ } catch (err) {
389
+ console.error(chalk.red(`Error: ${err.message}`));
390
+ process.exit(1);
391
+ }
392
+ });
393
+
394
+ ledgerCmd
395
+ .command('history <path>')
396
+ .description('Show full history of a specific file')
397
+ .option('-v, --vault <path>', 'Vault path')
398
+ .action(async (targetPath, opts) => {
399
+ try {
400
+ const vaultPath = resolveVaultPath(opts.vault);
401
+ const { ledger } = await import('../dist/workgraph/index.js');
402
+ const history = ledger.historyOf(vaultPath, targetPath);
403
+
404
+ if (history.length === 0) {
405
+ console.log(chalk.dim(`No history for ${targetPath}`));
406
+ return;
407
+ }
408
+
409
+ console.log(chalk.bold(`History: ${targetPath}`));
410
+ console.log(chalk.dim('─'.repeat(50)));
411
+ for (const e of history) {
412
+ const time = new Date(e.ts).toLocaleString();
413
+ const data = e.data ? chalk.dim(` ${JSON.stringify(e.data)}`) : '';
414
+ console.log(` ${chalk.dim(time)} ${chalk.cyan(e.op)} by ${e.actor}${data}`);
415
+ }
416
+ } catch (err) {
417
+ console.error(chalk.red(`Error: ${err.message}`));
418
+ process.exit(1);
419
+ }
420
+ });
421
+
422
+ ledgerCmd
423
+ .command('claims')
424
+ .description('Show all active claims')
425
+ .option('-v, --vault <path>', 'Vault path')
426
+ .action(async (opts) => {
427
+ try {
428
+ const vaultPath = resolveVaultPath(opts.vault);
429
+ const { ledger } = await import('../dist/workgraph/index.js');
430
+ const claims = ledger.allClaims(vaultPath);
431
+
432
+ if (claims.size === 0) {
433
+ console.log(chalk.dim('No active claims.'));
434
+ return;
435
+ }
436
+
437
+ for (const [target, owner] of claims) {
438
+ console.log(` ${chalk.yellow(owner.padEnd(20))} → ${target}`);
439
+ }
440
+ console.log(chalk.dim(`\n${claims.size} active claim(s)`));
441
+ } catch (err) {
442
+ console.error(chalk.red(`Error: ${err.message}`));
443
+ process.exit(1);
444
+ }
445
+ });
446
+ }
447
+
448
+ function csv(value) {
449
+ if (!value) return undefined;
450
+ return String(value).split(',').map(s => s.trim()).filter(Boolean);
451
+ }
@@ -5,7 +5,7 @@ import {
5
5
  } from "./chunk-FHFUXL6G.js";
6
6
  import {
7
7
  resolveVaultPath
8
- } from "./chunk-MXSSG3QU.js";
8
+ } from "./chunk-GNJL4YGR.js";
9
9
  import {
10
10
  listObservationFiles
11
11
  } from "./chunk-Z2XBWN7A.js";
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-MQUJNOHK.js";
4
4
  import {
5
5
  resolveVaultPath
6
- } from "./chunk-MXSSG3QU.js";
6
+ } from "./chunk-GNJL4YGR.js";
7
7
 
8
8
  // src/commands/archive.ts
9
9
  function parsePositiveInteger(raw, label) {
@@ -0,0 +1,52 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined") return require.apply(this, arguments);
11
+ throw Error('Dynamic require of "' + x + '" is not supported');
12
+ });
13
+ var __glob = (map) => (path) => {
14
+ var fn = map[path];
15
+ if (fn) return fn();
16
+ throw new Error("Module not found in bundle: " + path);
17
+ };
18
+ var __esm = (fn, res) => function __init() {
19
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
20
+ };
21
+ var __commonJS = (cb, mod) => function __require2() {
22
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
23
+ };
24
+ var __export = (target, all) => {
25
+ for (var name in all)
26
+ __defProp(target, name, { get: all[name], enumerable: true });
27
+ };
28
+ var __copyProps = (to, from, except, desc) => {
29
+ if (from && typeof from === "object" || typeof from === "function") {
30
+ for (let key of __getOwnPropNames(from))
31
+ if (!__hasOwnProp.call(to, key) && key !== except)
32
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
33
+ }
34
+ return to;
35
+ };
36
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
37
+ // If the importer is in node compatibility mode or this is not an ESM
38
+ // file that has been converted to a CommonJS file using a Babel-
39
+ // compatible transform (i.e. "__esModule" has not been set), then set
40
+ // "default" to the CommonJS "module.exports" for node compatibility.
41
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
42
+ mod
43
+ ));
44
+
45
+ export {
46
+ __require,
47
+ __glob,
48
+ __esm,
49
+ __commonJS,
50
+ __export,
51
+ __toESM
52
+ };
@@ -0,0 +1,93 @@
1
+ import {
2
+ __export
3
+ } from "./chunk-2ZDO52B4.js";
4
+
5
+ // src/workgraph/ledger.ts
6
+ var ledger_exports = {};
7
+ __export(ledger_exports, {
8
+ activityOf: () => activityOf,
9
+ allClaims: () => allClaims,
10
+ append: () => append,
11
+ currentOwner: () => currentOwner,
12
+ historyOf: () => historyOf,
13
+ isClaimed: () => isClaimed,
14
+ ledgerPath: () => ledgerPath,
15
+ readAll: () => readAll,
16
+ readSince: () => readSince,
17
+ recent: () => recent
18
+ });
19
+ import fs from "fs";
20
+ import path from "path";
21
+ var LEDGER_FILE = ".clawvault/ledger.jsonl";
22
+ function ledgerPath(vaultPath) {
23
+ return path.join(vaultPath, LEDGER_FILE);
24
+ }
25
+ function append(vaultPath, actor, op, target, type, data) {
26
+ const entry = {
27
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
28
+ actor,
29
+ op,
30
+ target,
31
+ ...type ? { type } : {},
32
+ ...data && Object.keys(data).length > 0 ? { data } : {}
33
+ };
34
+ const lPath = ledgerPath(vaultPath);
35
+ const dir = path.dirname(lPath);
36
+ if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
37
+ fs.appendFileSync(lPath, JSON.stringify(entry) + "\n", "utf-8");
38
+ return entry;
39
+ }
40
+ function readAll(vaultPath) {
41
+ const lPath = ledgerPath(vaultPath);
42
+ if (!fs.existsSync(lPath)) return [];
43
+ const lines = fs.readFileSync(lPath, "utf-8").split("\n").filter(Boolean);
44
+ return lines.map((line) => JSON.parse(line));
45
+ }
46
+ function readSince(vaultPath, since) {
47
+ return readAll(vaultPath).filter((e) => e.ts >= since);
48
+ }
49
+ function currentOwner(vaultPath, target) {
50
+ const entries = readAll(vaultPath).filter((e) => e.target === target);
51
+ let owner = null;
52
+ for (const e of entries) {
53
+ if (e.op === "claim") owner = e.actor;
54
+ if (e.op === "release" || e.op === "done" || e.op === "cancel") owner = null;
55
+ }
56
+ return owner;
57
+ }
58
+ function isClaimed(vaultPath, target) {
59
+ return currentOwner(vaultPath, target) !== null;
60
+ }
61
+ function historyOf(vaultPath, target) {
62
+ return readAll(vaultPath).filter((e) => e.target === target);
63
+ }
64
+ function activityOf(vaultPath, actor) {
65
+ return readAll(vaultPath).filter((e) => e.actor === actor);
66
+ }
67
+ function allClaims(vaultPath) {
68
+ const claims = /* @__PURE__ */ new Map();
69
+ const entries = readAll(vaultPath);
70
+ for (const e of entries) {
71
+ if (e.op === "claim") claims.set(e.target, e.actor);
72
+ if (e.op === "release" || e.op === "done" || e.op === "cancel") claims.delete(e.target);
73
+ }
74
+ return claims;
75
+ }
76
+ function recent(vaultPath, count = 20) {
77
+ const all = readAll(vaultPath);
78
+ return all.slice(-count);
79
+ }
80
+
81
+ export {
82
+ ledgerPath,
83
+ append,
84
+ readAll,
85
+ readSince,
86
+ currentOwner,
87
+ isClaimed,
88
+ historyOf,
89
+ activityOf,
90
+ allClaims,
91
+ recent,
92
+ ledger_exports
93
+ };