@storacha/clawracha 0.1.12 → 0.1.14

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.
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;AAgH7B,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,GAAG,EAAE,iBAAiB,QAukBpD"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;AAgG7B,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,GAAG,EAAE,iBAAiB,QA8hBpD"}
package/dist/plugin.js CHANGED
@@ -13,7 +13,8 @@ import { FileWatcher } from "./watcher.js";
13
13
  import { createStorachaClient } from "./utils/client.js";
14
14
  import { decodeDelegation, encodeDelegation, readDelegationArg, } from "./utils/delegation.js";
15
15
  import { resolveAgentWorkspace, getAgentIds } from "./utils/workspace.js";
16
- import { readIgnoreFile } from "./utils/ignore.js";
16
+ import { Agent, Name } from "@storacha/ucn/pail";
17
+ import { extract } from "@storacha/client/delegation";
17
18
  const activeSyncers = new Map();
18
19
  // --- Config helpers ---
19
20
  async function loadDeviceConfig(workspace) {
@@ -35,7 +36,7 @@ async function saveDeviceConfig(workspace, config) {
35
36
  await fs.writeFile(configPath, JSON.stringify(config, null, 2));
36
37
  }
37
38
  // --- Service helpers ---
38
- async function startWorkspaceSync(workspace, agentId, pluginConfig, logger) {
39
+ async function startWorkspaceSync(workspace, agentId, pluginConfig, initialAdd, logger) {
39
40
  const deviceConfig = await loadDeviceConfig(workspace);
40
41
  if (!deviceConfig || !deviceConfig.setupComplete) {
41
42
  return null;
@@ -61,23 +62,12 @@ async function startWorkspaceSync(workspace, agentId, pluginConfig, logger) {
61
62
  const updatedConfig = { ...deviceConfig, nameArchive };
62
63
  await saveDeviceConfig(workspace, updatedConfig);
63
64
  },
65
+ initialAdd,
64
66
  });
65
67
  await watcher.start();
66
68
  logger.info(`[${agentId}] Started syncing workspace: ${workspace}`);
67
69
  return { engine, watcher, workspace, agentId };
68
70
  }
69
- /**
70
- * Scan workspace for files, excluding patterns.
71
- * Returns paths relative to workspace.
72
- */
73
- async function scanWorkspaceFiles(workspace, ignorePatterns) {
74
- const { glob } = await import("glob");
75
- return glob("**/*", {
76
- cwd: workspace,
77
- nodir: true,
78
- ignore: ignorePatterns.map((p) => p.includes("/") || p.includes("*") ? p : `${p}/**`),
79
- });
80
- }
81
71
  // --- Plugin entry ---
82
72
  export default function plugin(api) {
83
73
  const pluginConfig = (api.pluginConfig ?? {});
@@ -93,7 +83,8 @@ export default function plugin(api) {
93
83
  for (const agentId of agentIds) {
94
84
  const workspace = resolveAgentWorkspace(ctx.config, agentId);
95
85
  try {
96
- const sync = await startWorkspaceSync(workspace, agentId, pluginConfig, ctx.logger);
86
+ const sync = await startWorkspaceSync(workspace, agentId, pluginConfig, false, // Don't emit "add" events for existing files on startup (handled by initial scan)
87
+ ctx.logger);
97
88
  if (sync) {
98
89
  activeSyncers.set(workspace, sync);
99
90
  }
@@ -205,7 +196,6 @@ export default function plugin(api) {
205
196
  const { agentId, workspace } = requireAgent(opts.agent);
206
197
  const existing = await loadDeviceConfig(workspace);
207
198
  if (existing?.agentKey) {
208
- const { Agent } = await import("@storacha/ucn/pail");
209
199
  const agent = Agent.parse(existing.agentKey);
210
200
  console.log(`Agent already initialized for ${agentId}.`);
211
201
  console.log(`Agent DID: ${agent.did()}`);
@@ -219,7 +209,6 @@ export default function plugin(api) {
219
209
  }
220
210
  return;
221
211
  }
222
- const { Agent } = await import("@storacha/ucn/pail");
223
212
  const agent = await Agent.generate();
224
213
  const agentKey = Agent.format(agent);
225
214
  await saveDeviceConfig(workspace, { agentKey });
@@ -242,7 +231,6 @@ export default function plugin(api) {
242
231
  .description("Set up a NEW workspace (first device). <delegation> is a file path or base64 CID string.")
243
232
  .requiredOption("--agent <id>", "Agent ID")
244
233
  .action(async (delegationArg, opts) => {
245
- let engine = null;
246
234
  try {
247
235
  const { agentId, workspace } = requireAgent(opts.agent);
248
236
  const deviceConfig = await loadDeviceConfig(workspace);
@@ -265,31 +253,11 @@ export default function plugin(api) {
265
253
  deviceConfig.setupComplete = true;
266
254
  await saveDeviceConfig(workspace, deviceConfig);
267
255
  // Initial upload: scan all existing workspace files and sync to Storacha
268
- engine = new SyncEngine(workspace);
269
- await engine.init(deviceConfig);
270
- const userIgnored = await readIgnoreFile(workspace);
271
- const ignorePatterns = [
272
- ".storacha",
273
- "node_modules",
274
- ".git",
275
- "dist",
276
- ...userIgnored,
277
- ];
278
- const allFiles = await scanWorkspaceFiles(workspace, ignorePatterns);
279
- if (allFiles.length > 0) {
280
- const changes = allFiles.map((f) => ({
281
- type: "add",
282
- path: f,
283
- }));
284
- await engine.processChanges(changes);
285
- await engine.sync();
286
- console.log(`Uploaded ${allFiles.length} existing files to Storacha.`);
256
+ const sync = await startWorkspaceSync(workspace, agentId, pluginConfig, true, console);
257
+ if (!sync) {
258
+ throw new Error("Failed to start sync engine");
287
259
  }
288
- // Save name archive after initial sync
289
- const exportedArchive = await engine.exportNameArchive();
290
- deviceConfig.nameArchive = exportedArchive;
291
- await saveDeviceConfig(workspace, deviceConfig);
292
- const { Agent } = await import("@storacha/ucn/pail");
260
+ activeSyncers.set(workspace, sync);
293
261
  const agent = Agent.parse(deviceConfig.agentKey);
294
262
  console.log(`🔥 Storacha workspace ready for ${agentId}!`);
295
263
  console.log(`Agent DID: ${agent.did()}`);
@@ -299,14 +267,6 @@ export default function plugin(api) {
299
267
  console.log("\nSync is now active (no gateway restart needed).");
300
268
  }
301
269
  catch (err) {
302
- if (engine) {
303
- try {
304
- const state = await engine.inspect();
305
- console.error("\nEngine state at failure:");
306
- console.error(JSON.stringify(state, null, 2));
307
- }
308
- catch { }
309
- }
310
270
  console.error(`Error: ${err.message}`);
311
271
  if (err.stack)
312
272
  console.error(err.stack);
@@ -321,7 +281,6 @@ export default function plugin(api) {
321
281
  .description("Join an existing workspace from another device. Arguments are file paths or base64 CID strings.")
322
282
  .requiredOption("--agent <id>", "Agent ID")
323
283
  .action(async (uploadArg, nameArg, opts) => {
324
- let engine = null;
325
284
  try {
326
285
  const { agentId, workspace } = requireAgent(opts.agent);
327
286
  const deviceConfig = await loadDeviceConfig(workspace);
@@ -348,15 +307,12 @@ export default function plugin(api) {
348
307
  deviceConfig.setupComplete = true;
349
308
  await saveDeviceConfig(workspace, deviceConfig);
350
309
  // Pull remote state before watcher starts
310
+ const sync = await startWorkspaceSync(workspace, agentId, pluginConfig, false, console);
351
311
  let pullCount = 0;
352
- engine = new SyncEngine(workspace);
353
- await engine.init(deviceConfig);
354
- pullCount = await engine.pullRemote();
355
- // Save name archive after pull
356
- const exportedArchive = await engine.exportNameArchive();
357
- deviceConfig.nameArchive = exportedArchive;
358
- await saveDeviceConfig(workspace, deviceConfig);
359
- const { Agent } = await import("@storacha/ucn/pail");
312
+ if (sync) {
313
+ pullCount = await sync.engine.pullRemote();
314
+ activeSyncers.set(workspace, sync);
315
+ }
360
316
  const agent = Agent.parse(deviceConfig.agentKey);
361
317
  console.log(`🔥 Joined existing Storacha workspace for ${agentId}!`);
362
318
  console.log(`Agent DID: ${agent.did()}`);
@@ -365,14 +321,6 @@ export default function plugin(api) {
365
321
  console.log("\nSync is now active (no gateway restart needed).");
366
322
  }
367
323
  catch (err) {
368
- if (engine) {
369
- try {
370
- const state = await engine.inspect();
371
- console.error("\nEngine state at failure:");
372
- console.error(JSON.stringify(state, null, 2));
373
- }
374
- catch { }
375
- }
376
324
  console.error(`Error: ${err.message}`);
377
325
  if (err.stack)
378
326
  console.error(err.stack);
@@ -420,33 +368,29 @@ export default function plugin(api) {
420
368
  results.push("⚠️ No upload delegation to re-delegate.");
421
369
  }
422
370
  // Re-delegate name capability
423
- {
424
- const { Agent, Name } = await import("@storacha/ucn/pail");
425
- const { extract } = await import("@storacha/client/delegation");
426
- const agent = Agent.parse(deviceConfig.agentKey);
427
- let name;
428
- if (deviceConfig.nameArchive) {
429
- const archiveBytes = decodeDelegation(deviceConfig.nameArchive);
430
- name = await Name.extract(agent, archiveBytes);
431
- }
432
- else if (deviceConfig.nameDelegation) {
433
- const nameBytes = decodeDelegation(deviceConfig.nameDelegation);
434
- const { ok: nameDel } = await extract(nameBytes);
435
- if (nameDel) {
436
- name = Name.from(agent, [nameDel]);
437
- }
438
- }
439
- if (name) {
440
- const nameDel = await name.grant(targetDID);
441
- const { ok: archiveBytes } = await nameDel.archive();
442
- if (archiveBytes) {
443
- results.push(`Name delegation:\n${encodeDelegation(archiveBytes)}`);
444
- }
371
+ const agent = Agent.parse(deviceConfig.agentKey);
372
+ let name;
373
+ if (deviceConfig.nameArchive) {
374
+ const archiveBytes = decodeDelegation(deviceConfig.nameArchive);
375
+ name = await Name.extract(agent, archiveBytes);
376
+ }
377
+ else if (deviceConfig.nameDelegation) {
378
+ const nameBytes = decodeDelegation(deviceConfig.nameDelegation);
379
+ const { ok: nameDel } = await extract(nameBytes);
380
+ if (nameDel) {
381
+ name = Name.from(agent, [nameDel]);
445
382
  }
446
- else {
447
- results.push("⚠️ No name state available to grant from.");
383
+ }
384
+ if (name) {
385
+ const nameDel = await name.grant(targetDID);
386
+ const { ok: archiveBytes } = await nameDel.archive();
387
+ if (archiveBytes) {
388
+ results.push(`Name delegation:\n${encodeDelegation(archiveBytes)}`);
448
389
  }
449
390
  }
391
+ else {
392
+ results.push("⚠️ No name state available to grant from.");
393
+ }
450
394
  console.log(`🔥 Delegations for ${targetDID}:\n`);
451
395
  for (const r of results) {
452
396
  console.log(r);
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EAEV,YAAY,EACb,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAWxE,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,SAAS,EAAE,MAAM;IAK7B;;;OAGG;IACG,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC/C;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAoD3B;;OAEG;YACW,iBAAiB;IAe/B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAc5C;;OAEG;YACW,kBAAkB;IAUhC;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BnC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC;QACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,SAAS,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC5D,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IAkBI,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC;IAW5B,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;YAM5B,WAAW;CAK1B"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../src/sync.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EAEV,YAAY,EACb,MAAM,kBAAkB,CAAC;AAS1B,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAWxE,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,KAAK,CAA6B;IAC1C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,SAAS,EAAE,MAAM;IAK7B;;;OAGG;IACG,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAoC/C;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;;OAGG;IACG,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyD3B;;OAEG;YACW,iBAAiB;IAe/B;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,WAAW,CAAC;IAc5C;;OAEG;YACW,kBAAkB;IAUhC;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IA0BnC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC;QACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,SAAS,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QAC5D,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;IAkBI,MAAM,IAAI,OAAO,CAAC,SAAS,CAAC;IAW5B,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;YAM5B,WAAW;CAK1B"}
package/dist/sync.js CHANGED
@@ -97,8 +97,7 @@ export class SyncEngine {
97
97
  async sync() {
98
98
  const { name } = this.requireRunning();
99
99
  const beforeEntries = await this.getPailEntries();
100
- let pendingOps = this.pendingOps;
101
- if (pendingOps.length === 0) {
100
+ if (this.pendingOps.length === 0) {
102
101
  // No pending ops — just pull remote
103
102
  try {
104
103
  const result = await Revision.resolve(this.blocks, name, {
@@ -113,28 +112,35 @@ export class SyncEngine {
113
112
  }
114
113
  }
115
114
  else {
116
- while (pendingOps.length > 0) {
117
- if (!this.carFile) {
118
- throw new Error("CAR file not initialized");
119
- }
120
- const { current, revisionBlocks, event, remainingOps } = await applyPendingOps(this.blocks, name, this.current, pendingOps);
121
- this.current = current;
122
- for (const block of revisionBlocks) {
123
- await this.carFile.put(block);
124
- }
125
- await this.storeBlocks(revisionBlocks);
126
- if (event) {
127
- await this.carFile.put(event);
128
- await this.storeBlocks([event]);
129
- }
130
- pendingOps = remainingOps;
131
- await this.possiblyUploadCAR();
132
- if (pendingOps.length > 0) {
133
- this.carFile = await makeTempCar();
115
+ let pendingOps = [...this.pendingOps];
116
+ this.pendingOps = [];
117
+ try {
118
+ while (pendingOps.length > 0) {
119
+ if (!this.carFile) {
120
+ throw new Error("CAR file not initialized");
121
+ }
122
+ const { current, revisionBlocks, event, remainingOps } = await applyPendingOps(this.blocks, name, this.current, pendingOps);
123
+ this.current = current;
124
+ for (const block of revisionBlocks) {
125
+ await this.carFile.put(block);
126
+ }
127
+ await this.storeBlocks(revisionBlocks);
128
+ if (event) {
129
+ await this.carFile.put(event);
130
+ await this.storeBlocks([event]);
131
+ }
132
+ pendingOps = remainingOps;
133
+ await this.possiblyUploadCAR();
134
+ if (pendingOps.length > 0) {
135
+ this.carFile = await makeTempCar();
136
+ }
134
137
  }
135
138
  }
139
+ catch (err) {
140
+ this.pendingOps.unshift(...pendingOps);
141
+ throw err;
142
+ }
136
143
  }
137
- this.pendingOps = [];
138
144
  // Apply remote changes
139
145
  const afterEntries = await this.getPailEntries();
140
146
  const remoteChanges = diffRemoteChanges(beforeEntries, afterEntries);
package/dist/watcher.d.ts CHANGED
@@ -10,6 +10,7 @@ export interface WatcherOptions {
10
10
  config: SyncPluginConfig;
11
11
  onChanges: (changes: FileChange[]) => Promise<void>;
12
12
  debounceMs?: number;
13
+ initialAdd?: boolean;
13
14
  }
14
15
  export declare class FileWatcher {
15
16
  private watcher;
@@ -1 +1 @@
1
- {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,SAAS,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,cAAc;IAKnC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;OAEG;YACW,KAAK;IAanB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAOlC"}
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,gBAAgB,CAAC;IACzB,SAAS,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,UAAU,CAAS;gBAEf,OAAO,EAAE,cAAc;IAKnC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;OAEG;YACW,KAAK;IAanB;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAOlC"}
package/dist/watcher.js CHANGED
@@ -37,7 +37,7 @@ export class FileWatcher {
37
37
  this.watcher = chokidar.watch(watchPaths, {
38
38
  ignored,
39
39
  persistent: true,
40
- ignoreInitial: true,
40
+ ignoreInitial: !this.options.initialAdd,
41
41
  awaitWriteFinish: {
42
42
  stabilityThreshold: 200,
43
43
  pollInterval: 100,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storacha/clawracha",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "description": "OpenClaw plugin for Storacha workspace sync via UCN Pail",
5
5
  "type": "module",
6
6
  "files": [
@@ -36,7 +36,6 @@
36
36
  "@web3-storage/pail": "0.6.3-rc.3",
37
37
  "carstream": "^2.3.0",
38
38
  "chokidar": "^3.6.0",
39
- "glob": "^13.0.5",
40
39
  "multiformats": "^13.0.0"
41
40
  },
42
41
  "devDependencies": {