@storacha/clawracha 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -23,21 +23,31 @@ openclaw plugins install @storacha/clawracha
23
23
 
24
24
  Setup is done via slash commands in your chat session with the agent (not CLI commands).
25
25
 
26
- ### New workspace (first device)
26
+ ### Step 1: Initialize the agent
27
27
 
28
28
  ```
29
- /storacha-init <upload-delegation-b64>
29
+ /storacha-init
30
30
  ```
31
31
 
32
- Creates a fresh workspace with a new UCN Name. You'll need an upload delegation from a Storacha space owner.
32
+ Generates an agent identity and displays the Agent DID. You'll need this DID to create delegations.
33
33
 
34
- ### Join an existing workspace (additional devices)
34
+ ### Step 2: Choose your path
35
+
36
+ **New workspace (first device):**
37
+
38
+ ```
39
+ /storacha-setup <upload-delegation-b64>
40
+ ```
41
+
42
+ Have the space owner create an upload delegation for your Agent DID, then import it. Creates a fresh UCN Name and starts syncing.
43
+
44
+ **Join an existing workspace (additional devices):**
35
45
 
36
46
  ```
37
47
  /storacha-join <upload-delegation-b64> <name-delegation-b64>
38
48
  ```
39
49
 
40
- Joins an existing workspace from another device. Both delegations are required — get them by running `/storacha-grant` on the existing device. The join command pulls all remote files before the watcher starts, so your local workspace is fully synced from the start.
50
+ Get both delegations by running `/storacha-grant` on the existing device. The join command pulls all remote files before the watcher starts, so your local workspace is fully synced from the start.
41
51
 
42
52
  ### Grant access to another device
43
53
 
@@ -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;AAwC7B;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,GAAG,EAAE,iBAAiB,QA6apD"}
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;AAwC7B;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,GAAG,EAAE,iBAAiB,QAyepD"}
package/dist/plugin.js CHANGED
@@ -62,7 +62,7 @@ export default function plugin(api) {
62
62
  }
63
63
  const deviceConfig = await loadDeviceConfig(workspace);
64
64
  if (!deviceConfig || !deviceConfig.setupComplete) {
65
- ctx.logger.info("Setup not complete. Run /storacha-init or /storacha-join first.");
65
+ ctx.logger.info("Setup not complete. Run /storacha-init first, then /storacha-setup or /storacha-join.");
66
66
  return;
67
67
  }
68
68
  const storachaClient = await createStorachaClient(deviceConfig);
@@ -114,7 +114,7 @@ export default function plugin(api) {
114
114
  content: [
115
115
  {
116
116
  type: "text",
117
- text: "Sync not initialized. Run /storacha-init or /storacha-join first.",
117
+ text: "Sync not initialized. Run /storacha-init first, then /storacha-setup or /storacha-join.",
118
118
  },
119
119
  ],
120
120
  details: null,
@@ -140,7 +140,7 @@ export default function plugin(api) {
140
140
  content: [
141
141
  {
142
142
  type: "text",
143
- text: "Sync not initialized. Run /storacha-init or /storacha-join first.",
143
+ text: "Sync not initialized. Run /storacha-init first, then /storacha-setup or /storacha-join.",
144
144
  },
145
145
  ],
146
146
  details: null,
@@ -162,19 +162,72 @@ export default function plugin(api) {
162
162
  // --- Slash Commands ---
163
163
  api.registerCommand({
164
164
  name: "storacha-init",
165
- description: "Initialize a NEW Storacha workspace (first device). Usage: /storacha-init <upload-delegation-b64>",
165
+ description: "Generate an agent identity for Storacha sync",
166
+ handler: async (_ctx) => {
167
+ const workspace = workspaceDir;
168
+ if (!workspace)
169
+ return { text: "No workspace configured." };
170
+ // Check if already initialized
171
+ const existing = await loadDeviceConfig(workspace);
172
+ if (existing?.agentKey) {
173
+ const { Agent } = await import("@storacha/ucn/pail");
174
+ const agent = Agent.parse(existing.agentKey);
175
+ return {
176
+ text: [
177
+ "Agent already initialized.",
178
+ `Agent DID: \`${agent.did()}\``,
179
+ "",
180
+ existing.setupComplete
181
+ ? "Setup is complete. Use `/storacha-status` to check sync state."
182
+ : "**Next step — choose one:**",
183
+ ...(!existing.setupComplete
184
+ ? [
185
+ "- **New workspace:** Have the space owner create an upload delegation for this DID, then run `/storacha-setup <upload-b64>`",
186
+ "- **Join existing:** Have the other device run `/storacha-grant <this-DID>`, then run `/storacha-join <upload-b64> <name-b64>`",
187
+ ]
188
+ : []),
189
+ ].join("\n"),
190
+ };
191
+ }
192
+ const { Agent } = await import("@storacha/ucn/pail");
193
+ const agent = await Agent.generate();
194
+ const agentKey = Agent.format(agent);
195
+ const config = { agentKey };
196
+ await saveDeviceConfig(workspace, config);
197
+ return {
198
+ text: [
199
+ "\u{1f525} Agent initialized!",
200
+ `Agent DID: \`${agent.did()}\``,
201
+ "",
202
+ "**Next step \u2014 choose one:**",
203
+ "- **New workspace:** Have the space owner create an upload delegation for this DID, then run `/storacha-setup <upload-b64>`",
204
+ "- **Join existing workspace:** Have the other device run `/storacha-grant <this-DID>`, then run `/storacha-join <upload-b64> <name-b64>`",
205
+ ].join("\n"),
206
+ };
207
+ },
208
+ });
209
+ api.registerCommand({
210
+ name: "storacha-setup",
211
+ description: "Set up a NEW Storacha workspace (first device). Usage: /storacha-setup <upload-delegation-b64>",
166
212
  acceptsArgs: true,
167
213
  handler: async (_ctx) => {
168
214
  const workspace = workspaceDir;
169
215
  if (!workspace)
170
216
  return { text: "No workspace configured." };
217
+ const config = await loadDeviceConfig(workspace);
218
+ if (!config?.agentKey) {
219
+ return { text: "Run `/storacha-init` first to generate an agent identity." };
220
+ }
221
+ if (config.setupComplete) {
222
+ return { text: "Setup already complete. Use `/storacha-status` to check sync state." };
223
+ }
171
224
  const b64 = _ctx.args?.trim();
172
225
  if (!b64) {
173
226
  return {
174
227
  text: [
175
- "Usage: `/storacha-init <upload-delegation-b64>`",
228
+ "Usage: `/storacha-setup <upload-delegation-b64>`",
176
229
  "",
177
- "This creates a **new** workspace. If you're syncing from an existing device, use `/storacha-join` instead.",
230
+ "This creates a **new** workspace. If you're joining an existing workspace, use `/storacha-join` instead.",
178
231
  ].join("\n"),
179
232
  };
180
233
  }
@@ -184,20 +237,16 @@ export default function plugin(api) {
184
237
  if (!delegation) {
185
238
  return { text: `Invalid delegation: ${error}` };
186
239
  }
187
- const { Agent } = await import("@storacha/ucn/pail");
188
- const agent = await Agent.generate();
189
- const agentKey = Agent.format(agent);
190
240
  const spaceDID = delegation.capabilities[0]?.with;
191
- const config = {
192
- agentKey,
193
- uploadDelegation: b64,
194
- spaceDID: spaceDID ?? undefined,
195
- setupComplete: true,
196
- };
241
+ config.uploadDelegation = b64;
242
+ config.spaceDID = spaceDID ?? undefined;
243
+ config.setupComplete = true;
197
244
  await saveDeviceConfig(workspace, config);
245
+ const { Agent } = await import("@storacha/ucn/pail");
246
+ const agent = Agent.parse(config.agentKey);
198
247
  return {
199
248
  text: [
200
- "\u{1f525} Storacha workspace initialized!",
249
+ "\u{1f525} Storacha workspace ready!",
201
250
  `Agent DID: \`${agent.did()}\``,
202
251
  `Space: \`${spaceDID ?? "unknown"}\``,
203
252
  "",
@@ -211,7 +260,7 @@ export default function plugin(api) {
211
260
  });
212
261
  api.registerCommand({
213
262
  name: "storacha-join",
214
- description: "Join an existing Storacha workspace from another device. Usage: /storacha-join <upload-delegation-b64> <name-delegation-b64>",
263
+ description: "Join an existing Storacha workspace from another device. Run /storacha-init first. Usage: /storacha-join <upload-delegation-b64> <name-delegation-b64>",
215
264
  acceptsArgs: true,
216
265
  handler: async (_ctx) => {
217
266
  const workspace = workspaceDir;
@@ -224,7 +273,7 @@ export default function plugin(api) {
224
273
  "Usage: `/storacha-join <upload-delegation-b64> <name-delegation-b64>`",
225
274
  "",
226
275
  "Get both delegations by running `/storacha-grant` on the existing device.",
227
- "If you're setting up a **new** workspace, use `/storacha-init` instead.",
276
+ "If you're setting up a **new** workspace, use `/storacha-setup` instead.",
228
277
  ].join("\n"),
229
278
  };
230
279
  }
@@ -253,17 +302,20 @@ export default function plugin(api) {
253
302
  if (!nameDelegation) {
254
303
  return { text: `Invalid name delegation: ${nameErr}` };
255
304
  }
305
+ const config = await loadDeviceConfig(workspace);
306
+ if (!config?.agentKey) {
307
+ return { text: "Run `/storacha-init` first to generate an agent identity." };
308
+ }
309
+ if (config.setupComplete) {
310
+ return { text: "Setup already complete. Use `/storacha-status` to check sync state." };
311
+ }
256
312
  const { Agent } = await import("@storacha/ucn/pail");
257
- const agent = await Agent.generate();
258
- const agentKey = Agent.format(agent);
313
+ const agent = Agent.parse(config.agentKey);
259
314
  const spaceDID = uploadDelegation.capabilities[0]?.with;
260
- const config = {
261
- agentKey,
262
- uploadDelegation: uploadB64,
263
- nameDelegation: nameB64,
264
- spaceDID: spaceDID ?? undefined,
265
- setupComplete: true,
266
- };
315
+ config.uploadDelegation = uploadB64;
316
+ config.nameDelegation = nameB64;
317
+ config.spaceDID = spaceDID ?? undefined;
318
+ config.setupComplete = true;
267
319
  await saveDeviceConfig(workspace, config);
268
320
  // Pull remote state immediately before watcher starts
269
321
  let pullCount = 0;
@@ -314,7 +366,7 @@ export default function plugin(api) {
314
366
  const config = await loadDeviceConfig(workspace);
315
367
  if (!config) {
316
368
  return {
317
- text: "Not initialized. Run `/storacha-init` or `/storacha-join` first.",
369
+ text: "Not initialized. Run `/storacha-init` first.",
318
370
  };
319
371
  }
320
372
  const results = [];
@@ -403,7 +455,7 @@ export default function plugin(api) {
403
455
  const config = await loadDeviceConfig(workspace);
404
456
  if (!config)
405
457
  return {
406
- text: "Not initialized. Run /storacha-init or /storacha-join first.",
458
+ text: "Not initialized. Run `/storacha-init` first.",
407
459
  };
408
460
  const lines = [
409
461
  "\u{1f525} Storacha Sync Status",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storacha/clawracha",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "description": "OpenClaw plugin for Storacha workspace sync via UCN Pail",
5
5
  "type": "module",
6
6
  "files": [