@storacha/clawracha 0.0.9 → 0.0.11-rc.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.
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;AAyC7B;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,GAAG,EAAE,iBAAiB,QAyepD"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,qBAAqB,CAAC;AAyC7B;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,GAAG,EAAE,iBAAiB,QA4hBpD"}
package/dist/plugin.js CHANGED
@@ -165,46 +165,53 @@ export default function plugin(api) {
165
165
  name: "storacha-init",
166
166
  description: "Generate an agent identity for Storacha sync",
167
167
  handler: async (_ctx) => {
168
- const workspace = workspaceDir;
169
- if (!workspace)
170
- return { text: "No workspace configured." };
171
- // Check if already initialized
172
- const existing = await loadDeviceConfig(workspace);
173
- if (existing?.agentKey) {
168
+ try {
169
+ const workspace = workspaceDir;
170
+ if (!workspace)
171
+ return { text: "No workspace configured." };
172
+ // Check if already initialized
173
+ const existing = await loadDeviceConfig(workspace);
174
+ if (existing?.agentKey) {
175
+ const { Agent } = await import("@storacha/ucn/pail");
176
+ const agent = Agent.parse(existing.agentKey);
177
+ return {
178
+ text: [
179
+ "Agent already initialized.",
180
+ `Agent DID: \`${agent.did()}\``,
181
+ "",
182
+ existing.setupComplete
183
+ ? "Setup is complete. Use `/storacha-status` to check sync state."
184
+ : "**Next step — choose one:**",
185
+ ...(!existing.setupComplete
186
+ ? [
187
+ "- **New workspace:** Have the space owner create an upload delegation for this DID, then run `/storacha-setup <upload-b64>`",
188
+ "- **Join existing:** Have the other device run `/storacha-grant <this-DID>`, then run `/storacha-join <upload-b64> <name-b64>`",
189
+ ]
190
+ : []),
191
+ ].join("\n"),
192
+ };
193
+ }
174
194
  const { Agent } = await import("@storacha/ucn/pail");
175
- const agent = Agent.parse(existing.agentKey);
195
+ const agent = await Agent.generate();
196
+ const agentKey = Agent.format(agent);
197
+ const config = { agentKey };
198
+ await saveDeviceConfig(workspace, config);
176
199
  return {
177
200
  text: [
178
- "Agent already initialized.",
201
+ "\u{1f525} Agent initialized!",
179
202
  `Agent DID: \`${agent.did()}\``,
180
203
  "",
181
- existing.setupComplete
182
- ? "Setup is complete. Use `/storacha-status` to check sync state."
183
- : "**Next step choose one:**",
184
- ...(!existing.setupComplete
185
- ? [
186
- "- **New workspace:** Have the space owner create an upload delegation for this DID, then run `/storacha-setup <upload-b64>`",
187
- "- **Join existing:** Have the other device run `/storacha-grant <this-DID>`, then run `/storacha-join <upload-b64> <name-b64>`",
188
- ]
189
- : []),
204
+ "**Next step \u2014 choose one:**",
205
+ "- **New workspace:** Have the space owner create an upload delegation for this DID, then run `/storacha-setup <upload-b64>`",
206
+ "- **Join existing workspace:** Have the other device run `/storacha-grant <this-DID>`, then run `/storacha-join <upload-b64> <name-b64>`",
190
207
  ].join("\n"),
191
208
  };
192
209
  }
193
- const { Agent } = await import("@storacha/ucn/pail");
194
- const agent = await Agent.generate();
195
- const agentKey = Agent.format(agent);
196
- const config = { agentKey };
197
- await saveDeviceConfig(workspace, config);
198
- return {
199
- text: [
200
- "\u{1f525} Agent initialized!",
201
- `Agent DID: \`${agent.did()}\``,
202
- "",
203
- "**Next step \u2014 choose one:**",
204
- "- **New workspace:** Have the space owner create an upload delegation for this DID, then run `/storacha-setup <upload-b64>`",
205
- "- **Join existing workspace:** Have the other device run `/storacha-grant <this-DID>`, then run `/storacha-join <upload-b64> <name-b64>`",
206
- ].join("\n"),
207
- };
210
+ catch (err) {
211
+ return {
212
+ text: `\u274c Command failed: ${err.message}\n\`\`\`\n${err.stack ?? err}\n\`\`\``,
213
+ };
214
+ }
208
215
  },
209
216
  });
210
217
  api.registerCommand({
@@ -212,41 +219,58 @@ export default function plugin(api) {
212
219
  description: "Set up a NEW Storacha workspace (first device). Usage: /storacha-setup <upload-delegation-b64>",
213
220
  acceptsArgs: true,
214
221
  handler: async (_ctx) => {
215
- const workspace = workspaceDir;
216
- if (!workspace)
217
- return { text: "No workspace configured." };
218
- const config = await loadDeviceConfig(workspace);
219
- if (!config?.agentKey) {
220
- return { text: "Run `/storacha-init` first to generate an agent identity." };
221
- }
222
- if (config.setupComplete) {
223
- return { text: "Setup already complete. Use `/storacha-status` to check sync state." };
224
- }
225
- const b64 = _ctx.args?.trim();
226
- if (!b64) {
222
+ try {
223
+ const workspace = workspaceDir;
224
+ if (!workspace)
225
+ return { text: "No workspace configured." };
226
+ const config = await loadDeviceConfig(workspace);
227
+ if (!config?.agentKey) {
228
+ return {
229
+ text: "Run `/storacha-init` first to generate an agent identity.",
230
+ };
231
+ }
232
+ if (config.setupComplete) {
233
+ return {
234
+ text: "Setup already complete. Use `/storacha-status` to check sync state.",
235
+ };
236
+ }
237
+ const b64 = _ctx.args?.trim();
238
+ if (!b64) {
239
+ return {
240
+ text: [
241
+ "Usage: `/storacha-setup <upload-delegation-b64>`",
242
+ "",
243
+ "This creates a **new** workspace. If you're joining an existing workspace, use `/storacha-join` instead.",
244
+ ].join("\n"),
245
+ };
246
+ }
227
247
  return {
228
248
  text: [
229
- "Usage: `/storacha-setup <upload-delegation-b64>`",
249
+ "You ran '/storacha-setup' without the following command argument:",
230
250
  "",
231
- "This creates a **new** workspace. If you're joining an existing workspace, use `/storacha-join` instead.",
251
+ b64,
232
252
  ].join("\n"),
233
253
  };
234
- }
235
- // Validate delegation
236
- const bytes = decodeDelegation(b64);
237
- const { ok: delegation, error } = await extractDelegation(bytes);
238
- if (!delegation) {
239
- return { text: `Invalid delegation: ${error}` };
240
- }
241
- const spaceDID = delegation.capabilities[0]?.with;
242
- config.uploadDelegation = b64;
243
- config.spaceDID = spaceDID ?? undefined;
244
- config.setupComplete = true;
245
- await saveDeviceConfig(workspace, config);
246
- const { Agent } = await import("@storacha/ucn/pail");
247
- const agent = Agent.parse(config.agentKey);
248
- return {
249
- text: [
254
+ /*
255
+ // Validate delegation
256
+ const bytes = decodeDelegation(b64);
257
+ const { ok: delegation, error } = await extractDelegation(bytes);
258
+ if (!delegation) {
259
+ return { text: `Invalid delegation: ${error}` };
260
+ }
261
+
262
+ const spaceDID = delegation.capabilities[0]?.with;
263
+
264
+ config.uploadDelegation = b64;
265
+ config.spaceDID = spaceDID ?? undefined;
266
+ config.setupComplete = true;
267
+ await saveDeviceConfig(workspace, config);
268
+
269
+ const { Agent } = await import("@storacha/ucn/pail");
270
+ const agent = Agent.parse(config.agentKey);
271
+
272
+ return {
273
+ text: [
250
274
  "\u{1f525} Storacha workspace ready!",
251
275
  `Agent DID: \`${agent.did()}\``,
252
276
  `Space: \`${spaceDID ?? "unknown"}\``,
@@ -255,8 +279,14 @@ export default function plugin(api) {
255
279
  "",
256
280
  "To add another device, run `/storacha-grant <their-agent-DID>` here,",
257
281
  "then `/storacha-join <upload-b64> <name-b64>` on the other device.",
258
- ].join("\n"),
259
- };
282
+ ].join("\n"),
283
+ };*/
284
+ }
285
+ catch (err) {
286
+ return {
287
+ text: `\u274c Command failed: ${err.message}\n\`\`\`\n${err.stack ?? err}\n\`\`\``,
288
+ };
289
+ }
260
290
  },
261
291
  });
262
292
  api.registerCommand({
@@ -264,92 +294,103 @@ export default function plugin(api) {
264
294
  description: "Join an existing Storacha workspace from another device. Run /storacha-init first. Usage: /storacha-join <upload-delegation-b64> <name-delegation-b64>",
265
295
  acceptsArgs: true,
266
296
  handler: async (_ctx) => {
267
- const workspace = workspaceDir;
268
- if (!workspace)
269
- return { text: "No workspace configured." };
270
- const args = _ctx.args?.trim();
271
- if (!args) {
297
+ try {
298
+ const workspace = workspaceDir;
299
+ if (!workspace)
300
+ return { text: "No workspace configured." };
301
+ const args = _ctx.args?.trim();
302
+ if (!args) {
303
+ return {
304
+ text: [
305
+ "Usage: `/storacha-join <upload-delegation-b64> <name-delegation-b64>`",
306
+ "",
307
+ "Get both delegations by running `/storacha-grant` on the existing device.",
308
+ "If you're setting up a **new** workspace, use `/storacha-setup` instead.",
309
+ ].join("\n"),
310
+ };
311
+ }
312
+ const spaceIdx = args.indexOf(" ");
313
+ if (spaceIdx === -1) {
314
+ return {
315
+ text: "Two arguments required: `/storacha-join <upload-b64> <name-b64>`",
316
+ };
317
+ }
318
+ const uploadB64 = args.slice(0, spaceIdx).trim();
319
+ const nameB64 = args.slice(spaceIdx + 1).trim();
320
+ if (!uploadB64 || !nameB64) {
321
+ return {
322
+ text: "Two arguments required: `/storacha-join <upload-b64> <name-b64>`",
323
+ };
324
+ }
325
+ // Validate upload delegation
326
+ const uploadBytes = decodeDelegation(uploadB64);
327
+ const { ok: uploadDelegation, error: uploadErr } = await extractDelegation(uploadBytes);
328
+ if (!uploadDelegation) {
329
+ return { text: `Invalid upload delegation: ${uploadErr}` };
330
+ }
331
+ // Validate name delegation
332
+ const nameBytes = decodeDelegation(nameB64);
333
+ const { ok: nameDelegation, error: nameErr } = await extractDelegation(nameBytes);
334
+ if (!nameDelegation) {
335
+ return { text: `Invalid name delegation: ${nameErr}` };
336
+ }
337
+ const config = await loadDeviceConfig(workspace);
338
+ if (!config?.agentKey) {
339
+ return {
340
+ text: "Run `/storacha-init` first to generate an agent identity.",
341
+ };
342
+ }
343
+ if (config.setupComplete) {
344
+ return {
345
+ text: "Setup already complete. Use `/storacha-status` to check sync state.",
346
+ };
347
+ }
348
+ const { Agent } = await import("@storacha/ucn/pail");
349
+ const agent = Agent.parse(config.agentKey);
350
+ const spaceDID = uploadDelegation.capabilities[0]?.with;
351
+ config.uploadDelegation = uploadB64;
352
+ config.nameDelegation = nameB64;
353
+ config.spaceDID = spaceDID ?? undefined;
354
+ config.setupComplete = true;
355
+ await saveDeviceConfig(workspace, config);
356
+ // Pull remote state immediately before watcher starts
357
+ let pullCount = 0;
358
+ try {
359
+ const storachaClient = await createStorachaClient(config);
360
+ const engine = new SyncEngine(storachaClient, workspace);
361
+ await engine.init(config);
362
+ pullCount = await engine.pullRemote();
363
+ // Save name archive after pull
364
+ const nameArchive = await engine.exportNameArchive();
365
+ config.nameArchive = nameArchive;
366
+ await saveDeviceConfig(workspace, config);
367
+ }
368
+ catch (err) {
369
+ return {
370
+ text: [
371
+ "\u26a0\ufe0f Delegations saved but initial pull failed:",
372
+ `\`${err.message}\``,
373
+ "",
374
+ "Restart the gateway to retry.",
375
+ ].join("\n"),
376
+ };
377
+ }
272
378
  return {
273
379
  text: [
274
- "Usage: `/storacha-join <upload-delegation-b64> <name-delegation-b64>`",
380
+ "\u{1f525} Joined existing Storacha workspace!",
381
+ `Agent DID: \`${agent.did()}\``,
382
+ `Space: \`${spaceDID ?? "unknown"}\``,
383
+ `Pulled ${pullCount} files from remote.`,
275
384
  "",
276
- "Get both delegations by running `/storacha-grant` on the existing device.",
277
- "If you're setting up a **new** workspace, use `/storacha-setup` instead.",
385
+ "Restart the gateway to start syncing.",
278
386
  ].join("\n"),
279
387
  };
280
388
  }
281
- const spaceIdx = args.indexOf(" ");
282
- if (spaceIdx === -1) {
283
- return {
284
- text: "Two arguments required: `/storacha-join <upload-b64> <name-b64>`",
285
- };
286
- }
287
- const uploadB64 = args.slice(0, spaceIdx).trim();
288
- const nameB64 = args.slice(spaceIdx + 1).trim();
289
- if (!uploadB64 || !nameB64) {
290
- return {
291
- text: "Two arguments required: `/storacha-join <upload-b64> <name-b64>`",
292
- };
293
- }
294
- // Validate upload delegation
295
- const uploadBytes = decodeDelegation(uploadB64);
296
- const { ok: uploadDelegation, error: uploadErr } = await extractDelegation(uploadBytes);
297
- if (!uploadDelegation) {
298
- return { text: `Invalid upload delegation: ${uploadErr}` };
299
- }
300
- // Validate name delegation
301
- const nameBytes = decodeDelegation(nameB64);
302
- const { ok: nameDelegation, error: nameErr } = await extractDelegation(nameBytes);
303
- if (!nameDelegation) {
304
- return { text: `Invalid name delegation: ${nameErr}` };
305
- }
306
- const config = await loadDeviceConfig(workspace);
307
- if (!config?.agentKey) {
308
- return { text: "Run `/storacha-init` first to generate an agent identity." };
309
- }
310
- if (config.setupComplete) {
311
- return { text: "Setup already complete. Use `/storacha-status` to check sync state." };
312
- }
313
- const { Agent } = await import("@storacha/ucn/pail");
314
- const agent = Agent.parse(config.agentKey);
315
- const spaceDID = uploadDelegation.capabilities[0]?.with;
316
- config.uploadDelegation = uploadB64;
317
- config.nameDelegation = nameB64;
318
- config.spaceDID = spaceDID ?? undefined;
319
- config.setupComplete = true;
320
- await saveDeviceConfig(workspace, config);
321
- // Pull remote state immediately before watcher starts
322
- let pullCount = 0;
323
- try {
324
- const storachaClient = await createStorachaClient(config);
325
- const engine = new SyncEngine(storachaClient, workspace);
326
- await engine.init(config);
327
- pullCount = await engine.pullRemote();
328
- // Save name archive after pull
329
- const nameArchive = await engine.exportNameArchive();
330
- config.nameArchive = nameArchive;
331
- await saveDeviceConfig(workspace, config);
332
- }
333
389
  catch (err) {
334
390
  return {
335
- text: [
336
- "\u26a0\ufe0f Delegations saved but initial pull failed:",
337
- `\`${err.message}\``,
338
- "",
339
- "Restart the gateway to retry.",
340
- ].join("\n"),
391
+ text: `\u274c Command failed: ${err.message}\n\`\`\`\n${err.stack ?? err}\n\`\`\``,
341
392
  };
342
393
  }
343
- return {
344
- text: [
345
- "\u{1f525} Joined existing Storacha workspace!",
346
- `Agent DID: \`${agent.did()}\``,
347
- `Space: \`${spaceDID ?? "unknown"}\``,
348
- `Pulled ${pullCount} files from remote.`,
349
- "",
350
- "Restart the gateway to start syncing.",
351
- ].join("\n"),
352
- };
353
394
  },
354
395
  });
355
396
  api.registerCommand({
@@ -357,121 +398,137 @@ export default function plugin(api) {
357
398
  description: "Grant another device access. Usage: /storacha-grant <target-DID>",
358
399
  acceptsArgs: true,
359
400
  handler: async (_ctx) => {
360
- const workspace = workspaceDir;
361
- if (!workspace)
362
- return { text: "No workspace configured." };
363
- const targetDID = _ctx.args?.trim();
364
- if (!targetDID || !targetDID.startsWith("did:")) {
365
- return { text: "Usage: `/storacha-grant <did:key:z...>`" };
366
- }
367
- const config = await loadDeviceConfig(workspace);
368
- if (!config) {
369
- return {
370
- text: "Not initialized. Run `/storacha-init` first.",
371
- };
372
- }
373
- const results = [];
374
- // Re-delegate upload capability
375
- if (config.uploadDelegation) {
376
- try {
377
- const storachaClient = await createStorachaClient(config);
378
- const audience = { did: () => targetDID };
379
- const uploadDelegation = await storachaClient.createDelegation(audience, [
380
- "space/blob/add",
381
- "space/index/add",
382
- "upload/add",
383
- "filecoin/offer",
384
- ]);
385
- const { ok: archiveBytes } = await uploadDelegation.archive();
386
- if (archiveBytes) {
387
- const b64 = encodeDelegation(archiveBytes);
388
- results.push("**Upload delegation:**\n```\n" + b64 + "\n```");
389
- }
401
+ try {
402
+ const workspace = workspaceDir;
403
+ if (!workspace)
404
+ return { text: "No workspace configured." };
405
+ const targetDID = _ctx.args?.trim();
406
+ if (!targetDID || !targetDID.startsWith("did:")) {
407
+ return { text: "Usage: `/storacha-grant <did:key:z...>`" };
390
408
  }
391
- catch (err) {
392
- results.push(`\u274c Failed to create upload delegation: ${err.message}`);
409
+ const config = await loadDeviceConfig(workspace);
410
+ if (!config) {
411
+ return {
412
+ text: "Not initialized. Run `/storacha-init` first.",
413
+ };
393
414
  }
394
- }
395
- else {
396
- results.push("\u26a0\ufe0f No upload delegation to re-delegate.");
397
- }
398
- // Re-delegate name (pail sync) capability
399
- if (config.nameDelegation) {
400
- try {
401
- const { Agent, Name } = await import("@storacha/ucn/pail");
402
- const agent = Agent.parse(config.agentKey);
403
- let name;
404
- if (config.nameArchive) {
405
- const archiveBytes = decodeDelegation(config.nameArchive);
406
- name = await Name.extract(agent, archiveBytes);
415
+ const results = [];
416
+ // Re-delegate upload capability
417
+ if (config.uploadDelegation) {
418
+ try {
419
+ const storachaClient = await createStorachaClient(config);
420
+ const audience = { did: () => targetDID };
421
+ const uploadDelegation = await storachaClient.createDelegation(audience, [
422
+ "space/blob/add",
423
+ "space/index/add",
424
+ "upload/add",
425
+ "filecoin/offer",
426
+ ]);
427
+ const { ok: archiveBytes } = await uploadDelegation.archive();
428
+ if (archiveBytes) {
429
+ const b64 = encodeDelegation(archiveBytes);
430
+ results.push("**Upload delegation:**\n```\n" + b64 + "\n```");
431
+ }
407
432
  }
408
- else {
409
- const nameBytes = decodeDelegation(config.nameDelegation);
410
- const { ok: nameDel } = await extractDelegation(nameBytes);
411
- if (!nameDel) {
412
- results.push("\u274c Failed to extract name delegation.");
433
+ catch (err) {
434
+ results.push(`\u274c Failed to create upload delegation: ${err.message}`);
435
+ }
436
+ }
437
+ else {
438
+ results.push("\u26a0\ufe0f No upload delegation to re-delegate.");
439
+ }
440
+ // Re-delegate name (pail sync) capability
441
+ if (config.nameDelegation) {
442
+ try {
443
+ const { Agent, Name } = await import("@storacha/ucn/pail");
444
+ const agent = Agent.parse(config.agentKey);
445
+ let name;
446
+ if (config.nameArchive) {
447
+ const archiveBytes = decodeDelegation(config.nameArchive);
448
+ name = await Name.extract(agent, archiveBytes);
413
449
  }
414
450
  else {
415
- name = Name.from(agent, [nameDel]);
451
+ const nameBytes = decodeDelegation(config.nameDelegation);
452
+ const { ok: nameDel } = await extractDelegation(nameBytes);
453
+ if (!nameDel) {
454
+ results.push("\u274c Failed to extract name delegation.");
455
+ }
456
+ else {
457
+ name = Name.from(agent, [nameDel]);
458
+ }
416
459
  }
417
- }
418
- if (name) {
419
- const nameDel = await name.grant(targetDID);
420
- const { ok: archiveBytes } = await nameDel.archive();
421
- if (archiveBytes) {
422
- const b64 = encodeDelegation(archiveBytes);
423
- results.push("**Name delegation:**\n```\n" + b64 + "\n```");
460
+ if (name) {
461
+ const nameDel = await name.grant(targetDID);
462
+ const { ok: archiveBytes } = await nameDel.archive();
463
+ if (archiveBytes) {
464
+ const b64 = encodeDelegation(archiveBytes);
465
+ results.push("**Name delegation:**\n```\n" + b64 + "\n```");
466
+ }
424
467
  }
425
468
  }
469
+ catch (err) {
470
+ results.push(`\u274c Failed to create name delegation: ${err.message}`);
471
+ }
426
472
  }
427
- catch (err) {
428
- results.push(`\u274c Failed to create name delegation: ${err.message}`);
473
+ else {
474
+ results.push("\u26a0\ufe0f No name delegation to re-delegate.");
429
475
  }
476
+ if (results.length === 0) {
477
+ return { text: "Nothing to grant. Set up this device first." };
478
+ }
479
+ return {
480
+ text: [
481
+ `\u{1f525} Delegations for \`${targetDID}\`:`,
482
+ "",
483
+ ...results,
484
+ "",
485
+ "The target device should run:",
486
+ "`/storacha-join <upload-b64> <name-b64>`",
487
+ ].join("\n"),
488
+ };
430
489
  }
431
- else {
432
- results.push("\u26a0\ufe0f No name delegation to re-delegate.");
433
- }
434
- if (results.length === 0) {
435
- return { text: "Nothing to grant. Set up this device first." };
490
+ catch (err) {
491
+ return {
492
+ text: `\u274c Command failed: ${err.message}\n\`\`\`\n${err.stack ?? err}\n\`\`\``,
493
+ };
436
494
  }
437
- return {
438
- text: [
439
- `\u{1f525} Delegations for \`${targetDID}\`:`,
440
- "",
441
- ...results,
442
- "",
443
- "The target device should run:",
444
- "`/storacha-join <upload-b64> <name-b64>`",
445
- ].join("\n"),
446
- };
447
495
  },
448
496
  });
449
497
  api.registerCommand({
450
498
  name: "storacha-status",
451
499
  description: "Show Storacha sync status",
452
500
  handler: async (_ctx) => {
453
- const workspace = workspaceDir;
454
- if (!workspace)
455
- return { text: "No workspace configured." };
456
- const config = await loadDeviceConfig(workspace);
457
- if (!config)
501
+ try {
502
+ const workspace = workspaceDir;
503
+ if (!workspace)
504
+ return { text: "No workspace configured." };
505
+ const config = await loadDeviceConfig(workspace);
506
+ if (!config)
507
+ return {
508
+ text: "Not initialized. Run `/storacha-init` first.",
509
+ };
510
+ const lines = [
511
+ "\u{1f525} Storacha Sync Status",
512
+ `Agent: configured`,
513
+ `Upload delegation: ${config.uploadDelegation ? "\u2705" : "\u274c not set"}`,
514
+ `Name delegation: ${config.nameDelegation ? "\u2705" : "\u274c not set"}`,
515
+ `Space DID: ${config.spaceDID ?? "unknown"}`,
516
+ `Name Archive: ${config.nameArchive ? "saved" : "not created"}`,
517
+ `Setup complete: ${config.setupComplete ? "\u2705" : "\u274c"}`,
518
+ ];
519
+ if (syncEngine) {
520
+ const status = await syncEngine.status();
521
+ lines.push(`Running: ${status.running}`, `Last Sync: ${status.lastSync
522
+ ? new Date(status.lastSync).toISOString()
523
+ : "never"}`, `Entries: ${status.entryCount}`, `Pending: ${status.pendingChanges}`);
524
+ }
525
+ return { text: lines.join("\n") };
526
+ }
527
+ catch (err) {
458
528
  return {
459
- text: "Not initialized. Run `/storacha-init` first.",
529
+ text: `\u274c Command failed: ${err.message}\n\`\`\`\n${err.stack ?? err}\n\`\`\``,
460
530
  };
461
- const lines = [
462
- "\u{1f525} Storacha Sync Status",
463
- `Agent: configured`,
464
- `Upload delegation: ${config.uploadDelegation ? "\u2705" : "\u274c not set"}`,
465
- `Name delegation: ${config.nameDelegation ? "\u2705" : "\u274c not set"}`,
466
- `Space DID: ${config.spaceDID ?? "unknown"}`,
467
- `Name Archive: ${config.nameArchive ? "saved" : "not created"}`,
468
- `Setup complete: ${config.setupComplete ? "\u2705" : "\u274c"}`,
469
- ];
470
- if (syncEngine) {
471
- const status = await syncEngine.status();
472
- lines.push(`Running: ${status.running}`, `Last Sync: ${status.lastSync ? new Date(status.lastSync).toISOString() : "never"}`, `Entries: ${status.entryCount}`, `Pending: ${status.pendingChanges}`);
473
531
  }
474
- return { text: lines.join("\n") };
475
532
  },
476
533
  });
477
534
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storacha/clawracha",
3
- "version": "0.0.9",
3
+ "version": "0.0.11-rc.0",
4
4
  "description": "OpenClaw plugin for Storacha workspace sync via UCN Pail",
5
5
  "type": "module",
6
6
  "files": [
@@ -36,7 +36,7 @@
36
36
  "@web3-storage/pail": "0.6.3-rc.3",
37
37
  "carstream": "^2.3.0",
38
38
  "chokidar": "^3.6.0",
39
- "multiformats": "^13.0.0"
39
+ "multiformats": "^13.3.6"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@ipld/unixfs": "^3.0.0",