@garydevenay/emporion 0.0.1

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 (102) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +173 -0
  3. package/dist/src/cli.d.ts +7 -0
  4. package/dist/src/cli.js +2101 -0
  5. package/dist/src/cli.js.map +1 -0
  6. package/dist/src/config.d.ts +2 -0
  7. package/dist/src/config.js +41 -0
  8. package/dist/src/config.js.map +1 -0
  9. package/dist/src/demo.d.ts +1 -0
  10. package/dist/src/demo.js +140 -0
  11. package/dist/src/demo.js.map +1 -0
  12. package/dist/src/did.d.ts +13 -0
  13. package/dist/src/did.js +155 -0
  14. package/dist/src/did.js.map +1 -0
  15. package/dist/src/errors.d.ts +23 -0
  16. package/dist/src/errors.js +25 -0
  17. package/dist/src/errors.js.map +1 -0
  18. package/dist/src/handshake.d.ts +9 -0
  19. package/dist/src/handshake.js +131 -0
  20. package/dist/src/handshake.js.map +1 -0
  21. package/dist/src/identity.d.ts +17 -0
  22. package/dist/src/identity.js +105 -0
  23. package/dist/src/identity.js.map +1 -0
  24. package/dist/src/index.d.ts +5 -0
  25. package/dist/src/index.js +5 -0
  26. package/dist/src/index.js.map +1 -0
  27. package/dist/src/logger.d.ts +11 -0
  28. package/dist/src/logger.js +41 -0
  29. package/dist/src/logger.js.map +1 -0
  30. package/dist/src/persistent-agent.d.ts +2 -0
  31. package/dist/src/persistent-agent.js +24 -0
  32. package/dist/src/persistent-agent.js.map +1 -0
  33. package/dist/src/protocol/company.d.ts +36 -0
  34. package/dist/src/protocol/company.js +211 -0
  35. package/dist/src/protocol/company.js.map +1 -0
  36. package/dist/src/protocol/contracts.d.ts +119 -0
  37. package/dist/src/protocol/contracts.js +404 -0
  38. package/dist/src/protocol/contracts.js.map +1 -0
  39. package/dist/src/protocol/credential-reference.d.ts +71 -0
  40. package/dist/src/protocol/credential-reference.js +136 -0
  41. package/dist/src/protocol/credential-reference.js.map +1 -0
  42. package/dist/src/protocol/dissemination.d.ts +47 -0
  43. package/dist/src/protocol/dissemination.js +111 -0
  44. package/dist/src/protocol/dissemination.js.map +1 -0
  45. package/dist/src/protocol/envelope.d.ts +71 -0
  46. package/dist/src/protocol/envelope.js +203 -0
  47. package/dist/src/protocol/envelope.js.map +1 -0
  48. package/dist/src/protocol/identity.d.ts +18 -0
  49. package/dist/src/protocol/identity.js +143 -0
  50. package/dist/src/protocol/identity.js.map +1 -0
  51. package/dist/src/protocol/index.d.ts +22 -0
  52. package/dist/src/protocol/index.js +12 -0
  53. package/dist/src/protocol/index.js.map +1 -0
  54. package/dist/src/protocol/market.d.ts +96 -0
  55. package/dist/src/protocol/market.js +293 -0
  56. package/dist/src/protocol/market.js.map +1 -0
  57. package/dist/src/protocol/messaging.d.ts +87 -0
  58. package/dist/src/protocol/messaging.js +296 -0
  59. package/dist/src/protocol/messaging.js.map +1 -0
  60. package/dist/src/protocol/repository.d.ts +87 -0
  61. package/dist/src/protocol/repository.js +651 -0
  62. package/dist/src/protocol/repository.js.map +1 -0
  63. package/dist/src/protocol/resolution.d.ts +86 -0
  64. package/dist/src/protocol/resolution.js +305 -0
  65. package/dist/src/protocol/resolution.js.map +1 -0
  66. package/dist/src/protocol/shared.d.ts +14 -0
  67. package/dist/src/protocol/shared.js +45 -0
  68. package/dist/src/protocol/shared.js.map +1 -0
  69. package/dist/src/protocol/versioning.d.ts +21 -0
  70. package/dist/src/protocol/versioning.js +69 -0
  71. package/dist/src/protocol/versioning.js.map +1 -0
  72. package/dist/src/storage.d.ts +36 -0
  73. package/dist/src/storage.js +156 -0
  74. package/dist/src/storage.js.map +1 -0
  75. package/dist/src/topics.d.ts +3 -0
  76. package/dist/src/topics.js +27 -0
  77. package/dist/src/topics.js.map +1 -0
  78. package/dist/src/transport.d.ts +114 -0
  79. package/dist/src/transport.js +291 -0
  80. package/dist/src/transport.js.map +1 -0
  81. package/dist/src/types.d.ts +95 -0
  82. package/dist/src/types.js +2 -0
  83. package/dist/src/types.js.map +1 -0
  84. package/dist/test/cli.test.d.ts +1 -0
  85. package/dist/test/cli.test.js +122 -0
  86. package/dist/test/cli.test.js.map +1 -0
  87. package/dist/test/economy.test.d.ts +1 -0
  88. package/dist/test/economy.test.js +661 -0
  89. package/dist/test/economy.test.js.map +1 -0
  90. package/dist/test/helpers.d.ts +12 -0
  91. package/dist/test/helpers.js +57 -0
  92. package/dist/test/helpers.js.map +1 -0
  93. package/dist/test/integration.test.d.ts +1 -0
  94. package/dist/test/integration.test.js +287 -0
  95. package/dist/test/integration.test.js.map +1 -0
  96. package/dist/test/protocol.test.d.ts +1 -0
  97. package/dist/test/protocol.test.js +448 -0
  98. package/dist/test/protocol.test.js.map +1 -0
  99. package/dist/test/unit.test.d.ts +1 -0
  100. package/dist/test/unit.test.js +87 -0
  101. package/dist/test/unit.test.js.map +1 -0
  102. package/package.json +60 -0
@@ -0,0 +1,2101 @@
1
+ #!/usr/bin/env node
2
+ import { once } from "node:events";
3
+ import { AgentTransport } from "./transport.js";
4
+ import { createLogger } from "./logger.js";
5
+ import { loadPersistentIdentityMaterial } from "./persistent-agent.js";
6
+ import * as Protocol from "./protocol/index.js";
7
+ import { sha256Hex } from "./protocol/shared.js";
8
+ import { TransportStorage } from "./storage.js";
9
+ const DEFAULT_IO = {
10
+ stdout(message) {
11
+ process.stdout.write(message);
12
+ },
13
+ stderr(message) {
14
+ process.stderr.write(message);
15
+ }
16
+ };
17
+ function parseArgs(argv) {
18
+ const commandPath = [];
19
+ const options = new Map();
20
+ let index = 0;
21
+ while (index < argv.length && !argv[index]?.startsWith("--")) {
22
+ commandPath.push(argv[index]);
23
+ index += 1;
24
+ }
25
+ while (index < argv.length) {
26
+ const token = argv[index];
27
+ if (!token?.startsWith("--")) {
28
+ throw new Error(`Unexpected positional argument: ${token ?? ""}`);
29
+ }
30
+ const optionName = token.slice(2);
31
+ if (optionName.length === 0) {
32
+ throw new Error("Option names must not be blank");
33
+ }
34
+ const nextToken = argv[index + 1];
35
+ const value = !nextToken || nextToken.startsWith("--") ? "true" : nextToken;
36
+ const existing = options.get(optionName) ?? [];
37
+ existing.push(value);
38
+ options.set(optionName, existing);
39
+ index += value === "true" ? 1 : 2;
40
+ }
41
+ return { commandPath, options };
42
+ }
43
+ function commandMatches(commandPath, ...expected) {
44
+ return commandPath.length === expected.length && expected.every((value, index) => commandPath[index] === value);
45
+ }
46
+ function getOptionValues(args, name) {
47
+ return args.options.get(name) ?? [];
48
+ }
49
+ function hasFlag(args, name) {
50
+ return getOptionValues(args, name).includes("true");
51
+ }
52
+ function getOptionalOption(args, name) {
53
+ const values = getOptionValues(args, name).filter((value) => value !== "true");
54
+ return values.at(-1);
55
+ }
56
+ function requireOption(args, name) {
57
+ const value = getOptionalOption(args, name);
58
+ if (!value || value.trim().length === 0) {
59
+ throw new Error(`Missing required option --${name}`);
60
+ }
61
+ return value;
62
+ }
63
+ function getCsvOptionValues(args, name) {
64
+ return getOptionValues(args, name)
65
+ .flatMap((value) => value.split(","))
66
+ .map((value) => value.trim())
67
+ .filter((value) => value.length > 0 && value !== "true");
68
+ }
69
+ function parsePositiveInteger(value, fieldName) {
70
+ const parsed = Number.parseInt(value, 10);
71
+ if (!Number.isInteger(parsed) || parsed <= 0) {
72
+ throw new Error(`${fieldName} must be a positive integer`);
73
+ }
74
+ return parsed;
75
+ }
76
+ function parseNonNegativeInteger(value, fieldName) {
77
+ const parsed = Number.parseInt(value, 10);
78
+ if (!Number.isInteger(parsed) || parsed < 0) {
79
+ throw new Error(`${fieldName} must be a non-negative integer`);
80
+ }
81
+ return parsed;
82
+ }
83
+ function parseOptionalNonNegativeInteger(args, name) {
84
+ const value = getOptionalOption(args, name);
85
+ return value === undefined ? undefined : parseNonNegativeInteger(value, `--${name}`);
86
+ }
87
+ function parseEnum(value, fieldName, allowed) {
88
+ if (allowed.includes(value)) {
89
+ return value;
90
+ }
91
+ throw new Error(`${fieldName} must be one of: ${allowed.join(", ")}`);
92
+ }
93
+ function now() {
94
+ return new Date().toISOString();
95
+ }
96
+ function sleep(ms) {
97
+ return new Promise((resolve) => setTimeout(resolve, ms));
98
+ }
99
+ function isStateWithLatestEventId(value) {
100
+ return (typeof value === "object" &&
101
+ value !== null &&
102
+ typeof value.latestEventId === "string" &&
103
+ Array.isArray(value.eventIds));
104
+ }
105
+ function defaultObjectId(kind, seed) {
106
+ return `emporion:${kind}:${sha256Hex(seed)}`;
107
+ }
108
+ function toProtocolJsonObject(value) {
109
+ return value;
110
+ }
111
+ function toProtocolValue(value) {
112
+ return value;
113
+ }
114
+ function parsePaymentTerms(args, options) {
115
+ const amountOption = options?.amountOption ?? "amount-sats";
116
+ const currencyOption = options?.currencyOption ?? "currency";
117
+ const settlementOption = options?.settlementOption ?? "settlement";
118
+ return {
119
+ amountSats: parsePositiveInteger(requireOption(args, amountOption), `--${amountOption}`),
120
+ currency: parseEnum(getOptionalOption(args, currencyOption) ?? "SAT", `--${currencyOption}`, ["BTC", "SAT"]),
121
+ settlementMethod: parseEnum(getOptionalOption(args, settlementOption) ?? "lightning", `--${settlementOption}`, ["lightning", "custodial"])
122
+ };
123
+ }
124
+ function mergePaymentTerms(args, current, options) {
125
+ const amountOption = options?.amountOption ?? "amount-sats";
126
+ const currencyOption = options?.currencyOption ?? "currency";
127
+ const settlementOption = options?.settlementOption ?? "settlement";
128
+ const amountValue = getOptionalOption(args, amountOption);
129
+ const currencyValue = getOptionalOption(args, currencyOption);
130
+ const settlementValue = getOptionalOption(args, settlementOption);
131
+ return {
132
+ amountSats: amountValue ? parsePositiveInteger(amountValue, `--${amountOption}`) : current.amountSats,
133
+ currency: currencyValue
134
+ ? parseEnum(currencyValue, `--${currencyOption}`, ["BTC", "SAT"])
135
+ : current.currency,
136
+ settlementMethod: settlementValue
137
+ ? parseEnum(settlementValue, `--${settlementOption}`, ["lightning", "custodial"])
138
+ : current.settlementMethod
139
+ };
140
+ }
141
+ function parseLightningRefs(args) {
142
+ return getOptionValues(args, "lightning-ref")
143
+ .filter((value) => value !== "true")
144
+ .map((value) => {
145
+ const match = /^([^:]+):([^:]+):(.+)$/.exec(value);
146
+ if (!match) {
147
+ throw new Error("--lightning-ref must use <type>:<network>:<reference>");
148
+ }
149
+ const [, type, network, reference] = match;
150
+ if (!type || !network || !reference) {
151
+ throw new Error("--lightning-ref must use <type>:<network>:<reference>");
152
+ }
153
+ return {
154
+ type: parseEnum(type, "--lightning-ref type", [
155
+ "bolt11",
156
+ "bolt12-offer",
157
+ "bolt12-invoice-request",
158
+ "custodial-payment-ref"
159
+ ]),
160
+ network: parseEnum(network, "--lightning-ref network", [
161
+ "bitcoin",
162
+ "testnet",
163
+ "signet",
164
+ "regtest"
165
+ ]),
166
+ reference
167
+ };
168
+ });
169
+ }
170
+ function parseJsonOption(args, name) {
171
+ const value = requireOption(args, name);
172
+ try {
173
+ return JSON.parse(value);
174
+ }
175
+ catch (error) {
176
+ throw new Error(`--${name} must be valid JSON: ${error.message}`);
177
+ }
178
+ }
179
+ function getUniqueOptionValues(args, name) {
180
+ return [...new Set(getOptionValues(args, name).filter((value) => value !== "true"))].sort();
181
+ }
182
+ function writeJson(io, value) {
183
+ io.stdout(`${JSON.stringify(value, null, 2)}\n`);
184
+ }
185
+ async function withCliContext(dataDir, fn) {
186
+ const identityMaterial = await loadPersistentIdentityMaterial(dataDir);
187
+ const repository = await Protocol.ProtocolRepository.create(dataDir);
188
+ const transportStorage = await TransportStorage.create(dataDir, identityMaterial.storagePrimaryKey, createLogger("error"));
189
+ await transportStorage.initializeDefaults();
190
+ try {
191
+ return await fn({
192
+ dataDir,
193
+ identityMaterial,
194
+ repository,
195
+ transportStorage,
196
+ signer: {
197
+ did: identityMaterial.agentIdentity.did,
198
+ publicKey: identityMaterial.transportKeyPair.publicKey,
199
+ secretKey: identityMaterial.transportKeyPair.secretKey
200
+ }
201
+ });
202
+ }
203
+ finally {
204
+ await transportStorage.close();
205
+ await repository.close();
206
+ }
207
+ }
208
+ async function readRequiredState(repository, objectKind, objectId) {
209
+ const state = await repository.readObjectState(objectKind, objectId);
210
+ if (!state) {
211
+ throw new Error(`No ${objectKind} state found for ${objectId}`);
212
+ }
213
+ return state;
214
+ }
215
+ async function ensureAgentProfileExists(context) {
216
+ const profile = await context.repository.readObjectState("agent-profile", context.identityMaterial.agentIdentity.did);
217
+ if (profile) {
218
+ return profile;
219
+ }
220
+ const result = await appendEnvelope(context, {
221
+ objectKind: "agent-profile",
222
+ objectId: context.identityMaterial.agentIdentity.did,
223
+ eventKind: "agent-profile.created",
224
+ subjectId: context.identityMaterial.agentIdentity.did,
225
+ payload: {}
226
+ });
227
+ return result.state;
228
+ }
229
+ function listActiveSpaceMemberDids(context, spaceId) {
230
+ const members = [];
231
+ for (const membership of context.repository.getSnapshot().spaceMemberships.values()) {
232
+ if (membership.spaceId === spaceId && membership.status !== "removed") {
233
+ members.push(membership.memberDid);
234
+ }
235
+ }
236
+ return [...new Set(members)].sort();
237
+ }
238
+ async function appendEnvelope(context, input) {
239
+ const currentState = await context.repository.readObjectState(input.objectKind, input.objectId);
240
+ const previousEventIds = isStateWithLatestEventId(currentState) ? [currentState.latestEventId] : [];
241
+ const unsignedEnvelope = Protocol.createUnsignedEnvelope({
242
+ objectKind: input.objectKind,
243
+ objectId: input.objectId,
244
+ eventKind: input.eventKind,
245
+ actorDid: context.identityMaterial.agentIdentity.did,
246
+ subjectId: input.subjectId,
247
+ issuedAt: input.issuedAt ?? now(),
248
+ previousEventIds,
249
+ payload: input.payload,
250
+ ...(input.attachments ? { attachments: input.attachments } : {})
251
+ });
252
+ const envelope = Protocol.signProtocolEnvelope(unsignedEnvelope, context.signer);
253
+ await context.repository.appendEnvelope(envelope);
254
+ const nextState = await context.repository.readObjectState(input.objectKind, input.objectId);
255
+ if (nextState) {
256
+ const controlFeed = await context.transportStorage.openFeed("control");
257
+ const announcement = Protocol.createProtocolAnnouncement(envelope, nextState);
258
+ await controlFeed.append(Protocol.protocolAnnouncementToJson(announcement));
259
+ }
260
+ return {
261
+ envelope,
262
+ state: nextState
263
+ };
264
+ }
265
+ async function handleAgentInit(args, io) {
266
+ const dataDir = requireOption(args, "data-dir");
267
+ await withCliContext(dataDir, async (context) => {
268
+ const displayName = getOptionalOption(args, "display-name");
269
+ const bio = getOptionalOption(args, "bio");
270
+ const currentProfile = await context.repository.readObjectState("agent-profile", context.identityMaterial.agentIdentity.did);
271
+ let mutation;
272
+ if (!currentProfile) {
273
+ mutation = await appendEnvelope(context, {
274
+ objectKind: "agent-profile",
275
+ objectId: context.identityMaterial.agentIdentity.did,
276
+ eventKind: "agent-profile.created",
277
+ subjectId: context.identityMaterial.agentIdentity.did,
278
+ payload: {
279
+ ...(displayName ? { displayName } : {}),
280
+ ...(bio ? { bio } : {})
281
+ }
282
+ });
283
+ }
284
+ else if (displayName !== undefined || bio !== undefined) {
285
+ const profile = currentProfile;
286
+ if (displayName !== profile.displayName || bio !== profile.bio) {
287
+ mutation = await appendEnvelope(context, {
288
+ objectKind: "agent-profile",
289
+ objectId: context.identityMaterial.agentIdentity.did,
290
+ eventKind: "agent-profile.updated",
291
+ subjectId: context.identityMaterial.agentIdentity.did,
292
+ payload: {
293
+ ...(displayName !== undefined ? { displayName } : {}),
294
+ ...(bio !== undefined ? { bio } : {})
295
+ }
296
+ });
297
+ }
298
+ }
299
+ writeJson(io, {
300
+ command: "agent.init",
301
+ identity: context.identityMaterial.agentIdentity,
302
+ profile: mutation?.state ??
303
+ (await context.repository.readObjectState("agent-profile", context.identityMaterial.agentIdentity.did)),
304
+ eventId: mutation?.envelope.eventId
305
+ });
306
+ });
307
+ }
308
+ async function handleAgentShow(args, io) {
309
+ const dataDir = requireOption(args, "data-dir");
310
+ await withCliContext(dataDir, async (context) => {
311
+ writeJson(io, {
312
+ command: "agent.show",
313
+ identity: context.identityMaterial.agentIdentity,
314
+ profile: await context.repository.readObjectState("agent-profile", context.identityMaterial.agentIdentity.did)
315
+ });
316
+ });
317
+ }
318
+ async function handleAgentPaymentEndpointAdd(args, io) {
319
+ const dataDir = requireOption(args, "data-dir");
320
+ await withCliContext(dataDir, async (context) => {
321
+ await ensureAgentProfileExists(context);
322
+ const capabilities = getCsvOptionValues(args, "capability");
323
+ if (capabilities.length === 0) {
324
+ throw new Error("At least one --capability is required");
325
+ }
326
+ const accountId = getOptionalOption(args, "account-id");
327
+ const nodeUri = getOptionalOption(args, "node-uri");
328
+ const bolt12Offer = getOptionalOption(args, "bolt12-offer");
329
+ const endpoint = {
330
+ id: requireOption(args, "id"),
331
+ network: parseEnum(getOptionalOption(args, "network") ?? "bitcoin", "--network", [
332
+ "bitcoin",
333
+ "testnet",
334
+ "signet",
335
+ "regtest"
336
+ ]),
337
+ custodial: hasFlag(args, "custodial"),
338
+ capabilities,
339
+ ...(accountId ? { accountId } : {}),
340
+ ...(nodeUri ? { nodeUri } : {}),
341
+ ...(bolt12Offer ? { bolt12Offer } : {})
342
+ };
343
+ const result = await appendEnvelope(context, {
344
+ objectKind: "agent-profile",
345
+ objectId: context.identityMaterial.agentIdentity.did,
346
+ eventKind: "agent-profile.payment-endpoint-added",
347
+ subjectId: context.identityMaterial.agentIdentity.did,
348
+ payload: Protocol.paymentEndpointToJson(endpoint)
349
+ });
350
+ writeJson(io, {
351
+ command: "agent.payment-endpoint.add",
352
+ eventId: result.envelope.eventId,
353
+ profile: result.state
354
+ });
355
+ });
356
+ }
357
+ async function handleAgentPaymentEndpointRemove(args, io) {
358
+ const dataDir = requireOption(args, "data-dir");
359
+ const paymentEndpointId = requireOption(args, "payment-endpoint-id");
360
+ await withCliContext(dataDir, async (context) => {
361
+ await ensureAgentProfileExists(context);
362
+ const result = await appendEnvelope(context, {
363
+ objectKind: "agent-profile",
364
+ objectId: context.identityMaterial.agentIdentity.did,
365
+ eventKind: "agent-profile.payment-endpoint-removed",
366
+ subjectId: context.identityMaterial.agentIdentity.did,
367
+ payload: {
368
+ paymentEndpointId
369
+ }
370
+ });
371
+ writeJson(io, {
372
+ command: "agent.payment-endpoint.remove",
373
+ eventId: result.envelope.eventId,
374
+ profile: result.state
375
+ });
376
+ });
377
+ }
378
+ async function handleAgentWalletAttestationAdd(args, io) {
379
+ const dataDir = requireOption(args, "data-dir");
380
+ await withCliContext(dataDir, async (context) => {
381
+ await ensureAgentProfileExists(context);
382
+ const attestedAt = getOptionalOption(args, "attested-at") ?? now();
383
+ const artifact = getOptionalOption(args, "artifact") ?? "";
384
+ const attestedCapacitySats = parseOptionalNonNegativeInteger(args, "capacity-sats");
385
+ const artifactUri = getOptionalOption(args, "artifact-uri");
386
+ const attestation = {
387
+ attestationId: requireOption(args, "attestation-id"),
388
+ issuerDid: getOptionalOption(args, "issuer-did") ?? context.identityMaterial.agentIdentity.did,
389
+ subjectDid: context.identityMaterial.agentIdentity.did,
390
+ walletAccountId: requireOption(args, "wallet-account-id"),
391
+ network: parseEnum(getOptionalOption(args, "network") ?? "bitcoin", "--network", [
392
+ "bitcoin",
393
+ "testnet",
394
+ "signet",
395
+ "regtest"
396
+ ]),
397
+ currency: parseEnum(getOptionalOption(args, "currency") ?? "SAT", "--currency", ["BTC", "SAT"]),
398
+ attestedBalanceSats: parseNonNegativeInteger(requireOption(args, "balance-sats"), "--balance-sats"),
399
+ ...(attestedCapacitySats !== undefined ? { attestedCapacitySats } : {}),
400
+ attestedAt,
401
+ expiresAt: requireOption(args, "expires-at"),
402
+ artifactHash: Protocol.createCredentialArtifactHash(artifact),
403
+ ...(artifactUri ? { artifactUri } : {})
404
+ };
405
+ const result = await appendEnvelope(context, {
406
+ objectKind: "agent-profile",
407
+ objectId: context.identityMaterial.agentIdentity.did,
408
+ eventKind: "agent-profile.wallet-attestation-added",
409
+ subjectId: context.identityMaterial.agentIdentity.did,
410
+ payload: Protocol.custodialWalletAttestationToJson(attestation)
411
+ });
412
+ writeJson(io, {
413
+ command: "agent.wallet-attestation.add",
414
+ eventId: result.envelope.eventId,
415
+ profile: result.state
416
+ });
417
+ });
418
+ }
419
+ async function handleAgentWalletAttestationRemove(args, io) {
420
+ const dataDir = requireOption(args, "data-dir");
421
+ const attestationId = requireOption(args, "attestation-id");
422
+ await withCliContext(dataDir, async (context) => {
423
+ await ensureAgentProfileExists(context);
424
+ const result = await appendEnvelope(context, {
425
+ objectKind: "agent-profile",
426
+ objectId: context.identityMaterial.agentIdentity.did,
427
+ eventKind: "agent-profile.wallet-attestation-removed",
428
+ subjectId: context.identityMaterial.agentIdentity.did,
429
+ payload: {
430
+ attestationId
431
+ }
432
+ });
433
+ writeJson(io, {
434
+ command: "agent.wallet-attestation.remove",
435
+ eventId: result.envelope.eventId,
436
+ profile: result.state
437
+ });
438
+ });
439
+ }
440
+ async function handleAgentFeedbackAdd(args, io) {
441
+ const dataDir = requireOption(args, "data-dir");
442
+ await withCliContext(dataDir, async (context) => {
443
+ await ensureAgentProfileExists(context);
444
+ const issuedAt = getOptionalOption(args, "issued-at") ?? now();
445
+ const artifact = getOptionalOption(args, "artifact") ?? "";
446
+ const headline = getOptionalOption(args, "headline");
447
+ const comment = getOptionalOption(args, "comment");
448
+ const expiresAt = getOptionalOption(args, "expires-at");
449
+ const artifactUri = getOptionalOption(args, "artifact-uri");
450
+ const revocationRef = getOptionalOption(args, "revocation-ref");
451
+ const completionArtifactRef = getOptionalOption(args, "completion-artifact-ref");
452
+ const rulingRef = getOptionalOption(args, "ruling-ref");
453
+ const credential = {
454
+ credentialId: requireOption(args, "credential-id"),
455
+ issuerDid: requireOption(args, "issuer-did"),
456
+ subjectDid: context.identityMaterial.agentIdentity.did,
457
+ relatedContractId: requireOption(args, "contract-id"),
458
+ relatedAgreementId: requireOption(args, "agreement-id"),
459
+ ...(completionArtifactRef ? { completionArtifactRef } : {}),
460
+ ...(rulingRef ? { rulingRef } : {}),
461
+ summary: {
462
+ score: parseNonNegativeInteger(requireOption(args, "score"), "--score"),
463
+ maxScore: parsePositiveInteger(requireOption(args, "max-score"), "--max-score"),
464
+ ...(headline ? { headline } : {}),
465
+ ...(comment ? { comment } : {})
466
+ },
467
+ issuedAt,
468
+ ...(expiresAt ? { expiresAt } : {}),
469
+ artifactHash: Protocol.createCredentialArtifactHash(artifact),
470
+ ...(artifactUri ? { artifactUri } : {}),
471
+ ...(revocationRef ? { revocationRef } : {})
472
+ };
473
+ const recorded = await appendEnvelope(context, {
474
+ objectKind: "feedback-credential-ref",
475
+ objectId: credential.credentialId,
476
+ eventKind: "feedback-credential-ref.recorded",
477
+ subjectId: credential.credentialId,
478
+ payload: Protocol.feedbackCredentialRefToJson(credential),
479
+ issuedAt
480
+ });
481
+ const added = await appendEnvelope(context, {
482
+ objectKind: "agent-profile",
483
+ objectId: context.identityMaterial.agentIdentity.did,
484
+ eventKind: "agent-profile.feedback-credential-added",
485
+ subjectId: context.identityMaterial.agentIdentity.did,
486
+ payload: Protocol.feedbackCredentialRefToJson(credential)
487
+ });
488
+ writeJson(io, {
489
+ command: "agent.feedback.add",
490
+ feedbackEventId: recorded.envelope.eventId,
491
+ profileEventId: added.envelope.eventId,
492
+ profile: added.state,
493
+ feedback: await context.repository.readObjectState("feedback-credential-ref", credential.credentialId)
494
+ });
495
+ });
496
+ }
497
+ async function handleAgentFeedbackRemove(args, io) {
498
+ const dataDir = requireOption(args, "data-dir");
499
+ const credentialId = requireOption(args, "credential-id");
500
+ await withCliContext(dataDir, async (context) => {
501
+ await ensureAgentProfileExists(context);
502
+ const feedbackState = await context.repository.readObjectState("feedback-credential-ref", credentialId);
503
+ if (feedbackState) {
504
+ await appendEnvelope(context, {
505
+ objectKind: "feedback-credential-ref",
506
+ objectId: credentialId,
507
+ eventKind: "feedback-credential-ref.revoked",
508
+ subjectId: credentialId,
509
+ payload: {}
510
+ });
511
+ }
512
+ const removed = await appendEnvelope(context, {
513
+ objectKind: "agent-profile",
514
+ objectId: context.identityMaterial.agentIdentity.did,
515
+ eventKind: "agent-profile.feedback-credential-removed",
516
+ subjectId: context.identityMaterial.agentIdentity.did,
517
+ payload: {
518
+ credentialId
519
+ }
520
+ });
521
+ writeJson(io, {
522
+ command: "agent.feedback.remove",
523
+ profileEventId: removed.envelope.eventId,
524
+ profile: removed.state,
525
+ feedback: await context.repository.readObjectState("feedback-credential-ref", credentialId)
526
+ });
527
+ });
528
+ }
529
+ async function handleCompanyCreate(args, io) {
530
+ const dataDir = requireOption(args, "data-dir");
531
+ await withCliContext(dataDir, async (context) => {
532
+ const issuedAt = now();
533
+ const description = getOptionalOption(args, "description");
534
+ const payload = {
535
+ name: requireOption(args, "name"),
536
+ initialOwners: [context.identityMaterial.agentIdentity.did],
537
+ ...(description ? { description } : {})
538
+ };
539
+ const companyDid = Protocol.deriveCompanyDidFromGenesis({
540
+ actorDid: context.identityMaterial.agentIdentity.did,
541
+ issuedAt,
542
+ payload
543
+ });
544
+ const result = await appendEnvelope(context, {
545
+ objectKind: "company",
546
+ objectId: companyDid,
547
+ eventKind: "company.genesis",
548
+ subjectId: companyDid,
549
+ payload: payload,
550
+ issuedAt
551
+ });
552
+ writeJson(io, {
553
+ command: "company.create",
554
+ companyDid,
555
+ eventId: result.envelope.eventId,
556
+ state: result.state
557
+ });
558
+ });
559
+ }
560
+ async function handleCompanyShow(args, io) {
561
+ const dataDir = requireOption(args, "data-dir");
562
+ const companyDid = requireOption(args, "company-did");
563
+ await withCliContext(dataDir, async (context) => {
564
+ writeJson(io, {
565
+ command: "company.show",
566
+ state: await context.repository.readObjectState("company", companyDid)
567
+ });
568
+ });
569
+ }
570
+ async function handleCompanyUpdate(args, io) {
571
+ const dataDir = requireOption(args, "data-dir");
572
+ const companyDid = requireOption(args, "company-did");
573
+ const name = getOptionalOption(args, "name");
574
+ const description = getOptionalOption(args, "description");
575
+ if (name === undefined && description === undefined) {
576
+ throw new Error("At least one of --name or --description is required");
577
+ }
578
+ await withCliContext(dataDir, async (context) => {
579
+ const result = await appendEnvelope(context, {
580
+ objectKind: "company",
581
+ objectId: companyDid,
582
+ eventKind: "company.profile-updated",
583
+ subjectId: companyDid,
584
+ payload: {
585
+ ...(name !== undefined ? { name } : {}),
586
+ ...(description !== undefined ? { description } : {})
587
+ }
588
+ });
589
+ writeJson(io, {
590
+ command: "company.update",
591
+ eventId: result.envelope.eventId,
592
+ state: result.state
593
+ });
594
+ });
595
+ }
596
+ async function handleCompanyRoleChange(args, io, mode) {
597
+ const dataDir = requireOption(args, "data-dir");
598
+ const companyDid = requireOption(args, "company-did");
599
+ await withCliContext(dataDir, async (context) => {
600
+ const result = await appendEnvelope(context, {
601
+ objectKind: "company",
602
+ objectId: companyDid,
603
+ eventKind: mode === "grant" ? "company.role-granted" : "company.role-revoked",
604
+ subjectId: companyDid,
605
+ payload: {
606
+ memberDid: requireOption(args, "member-did"),
607
+ role: parseEnum(requireOption(args, "role"), "--role", ["owner", "operator", "member"])
608
+ }
609
+ });
610
+ writeJson(io, {
611
+ command: mode === "grant" ? "company.grant-role" : "company.revoke-role",
612
+ eventId: result.envelope.eventId,
613
+ state: result.state
614
+ });
615
+ });
616
+ }
617
+ async function handleCompanyMarketMembership(args, io, mode) {
618
+ const dataDir = requireOption(args, "data-dir");
619
+ const companyDid = requireOption(args, "company-did");
620
+ const marketplaceId = requireOption(args, "marketplace");
621
+ await withCliContext(dataDir, async (context) => {
622
+ const result = await appendEnvelope(context, {
623
+ objectKind: "company",
624
+ objectId: companyDid,
625
+ eventKind: mode === "join" ? "company.market-joined" : "company.market-left",
626
+ subjectId: companyDid,
627
+ payload: {
628
+ marketplaceId
629
+ }
630
+ });
631
+ writeJson(io, {
632
+ command: mode === "join" ? "company.join-market" : "company.leave-market",
633
+ eventId: result.envelope.eventId,
634
+ state: result.state
635
+ });
636
+ });
637
+ }
638
+ async function handleCompanyTreasuryAttest(args, io) {
639
+ const dataDir = requireOption(args, "data-dir");
640
+ const companyDid = requireOption(args, "company-did");
641
+ const attestedAt = getOptionalOption(args, "attested-at") ?? now();
642
+ const artifact = getOptionalOption(args, "artifact") ?? "";
643
+ await withCliContext(dataDir, async (context) => {
644
+ const attestedCapacitySats = parseOptionalNonNegativeInteger(args, "capacity-sats");
645
+ const artifactUri = getOptionalOption(args, "artifact-uri");
646
+ const attestation = {
647
+ attestationId: requireOption(args, "attestation-id"),
648
+ issuerDid: getOptionalOption(args, "issuer-did") ?? context.identityMaterial.agentIdentity.did,
649
+ subjectDid: companyDid,
650
+ walletAccountId: requireOption(args, "wallet-account-id"),
651
+ network: parseEnum(getOptionalOption(args, "network") ?? "bitcoin", "--network", [
652
+ "bitcoin",
653
+ "testnet",
654
+ "signet",
655
+ "regtest"
656
+ ]),
657
+ currency: parseEnum(getOptionalOption(args, "currency") ?? "SAT", "--currency", ["BTC", "SAT"]),
658
+ attestedBalanceSats: parseNonNegativeInteger(requireOption(args, "balance-sats"), "--balance-sats"),
659
+ ...(attestedCapacitySats !== undefined ? { attestedCapacitySats } : {}),
660
+ attestedAt,
661
+ expiresAt: requireOption(args, "expires-at"),
662
+ artifactHash: Protocol.createCredentialArtifactHash(artifact),
663
+ ...(artifactUri ? { artifactUri } : {})
664
+ };
665
+ const result = await appendEnvelope(context, {
666
+ objectKind: "company",
667
+ objectId: companyDid,
668
+ eventKind: "company.treasury-attested",
669
+ subjectId: companyDid,
670
+ payload: Protocol.custodialWalletAttestationToJson(attestation)
671
+ });
672
+ writeJson(io, {
673
+ command: "company.treasury-attest",
674
+ eventId: result.envelope.eventId,
675
+ state: result.state
676
+ });
677
+ });
678
+ }
679
+ async function handleCompanyTreasuryReserve(args, io) {
680
+ const dataDir = requireOption(args, "data-dir");
681
+ const companyDid = requireOption(args, "company-did");
682
+ const createdAt = getOptionalOption(args, "created-at") ?? now();
683
+ await withCliContext(dataDir, async (context) => {
684
+ const result = await appendEnvelope(context, {
685
+ objectKind: "company",
686
+ objectId: companyDid,
687
+ eventKind: "company.treasury-reserved",
688
+ subjectId: companyDid,
689
+ payload: {
690
+ reservationId: requireOption(args, "reservation-id"),
691
+ amountSats: parsePositiveInteger(requireOption(args, "amount-sats"), "--amount-sats"),
692
+ reason: requireOption(args, "reason"),
693
+ createdAt
694
+ }
695
+ });
696
+ writeJson(io, {
697
+ command: "company.treasury.reserve",
698
+ eventId: result.envelope.eventId,
699
+ state: result.state
700
+ });
701
+ });
702
+ }
703
+ async function handleCompanyTreasuryRelease(args, io) {
704
+ const dataDir = requireOption(args, "data-dir");
705
+ const companyDid = requireOption(args, "company-did");
706
+ await withCliContext(dataDir, async (context) => {
707
+ const result = await appendEnvelope(context, {
708
+ objectKind: "company",
709
+ objectId: companyDid,
710
+ eventKind: "company.treasury-released",
711
+ subjectId: companyDid,
712
+ payload: {
713
+ reservationId: requireOption(args, "reservation-id")
714
+ }
715
+ });
716
+ writeJson(io, {
717
+ command: "company.treasury.release",
718
+ eventId: result.envelope.eventId,
719
+ state: result.state
720
+ });
721
+ });
722
+ }
723
+ async function handleMarketProductCreate(args, io) {
724
+ const dataDir = requireOption(args, "data-dir");
725
+ await withCliContext(dataDir, async (context) => {
726
+ const issuedAt = now();
727
+ const description = getOptionalOption(args, "description");
728
+ const payload = {
729
+ marketplaceId: requireOption(args, "marketplace"),
730
+ ownerDid: getOptionalOption(args, "owner-did") ?? context.identityMaterial.agentIdentity.did,
731
+ title: requireOption(args, "title"),
732
+ ...(description ? { description } : {})
733
+ };
734
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("product", toProtocolValue({
735
+ actorDid: context.identityMaterial.agentIdentity.did,
736
+ issuedAt,
737
+ payload: toProtocolJsonObject(payload)
738
+ }));
739
+ const result = await appendEnvelope(context, {
740
+ objectKind: "product",
741
+ objectId,
742
+ eventKind: "product.created",
743
+ subjectId: objectId,
744
+ payload: toProtocolJsonObject(payload),
745
+ issuedAt
746
+ });
747
+ writeJson(io, {
748
+ command: "market.product.create",
749
+ objectId,
750
+ eventId: result.envelope.eventId,
751
+ state: result.state
752
+ });
753
+ });
754
+ }
755
+ async function handleMarketProductUpdate(args, io) {
756
+ const dataDir = requireOption(args, "data-dir");
757
+ const objectId = requireOption(args, "id");
758
+ const title = getOptionalOption(args, "title");
759
+ const description = getOptionalOption(args, "description");
760
+ if (title === undefined && description === undefined) {
761
+ throw new Error("At least one of --title or --description is required");
762
+ }
763
+ await withCliContext(dataDir, async (context) => {
764
+ const result = await appendEnvelope(context, {
765
+ objectKind: "product",
766
+ objectId,
767
+ eventKind: "product.updated",
768
+ subjectId: objectId,
769
+ payload: toProtocolJsonObject({
770
+ ...(title !== undefined ? { title } : {}),
771
+ ...(description !== undefined ? { description } : {})
772
+ })
773
+ });
774
+ writeJson(io, {
775
+ command: "market.product.update",
776
+ objectId,
777
+ eventId: result.envelope.eventId,
778
+ state: result.state
779
+ });
780
+ });
781
+ }
782
+ async function handleMarketProductStateChange(args, io, eventKind) {
783
+ const dataDir = requireOption(args, "data-dir");
784
+ const objectId = requireOption(args, "id");
785
+ await withCliContext(dataDir, async (context) => {
786
+ const result = await appendEnvelope(context, {
787
+ objectKind: "product",
788
+ objectId,
789
+ eventKind,
790
+ subjectId: objectId,
791
+ payload: {}
792
+ });
793
+ writeJson(io, {
794
+ command: `market.product.${eventKind.split(".")[1]}`,
795
+ objectId,
796
+ eventId: result.envelope.eventId,
797
+ state: result.state
798
+ });
799
+ });
800
+ }
801
+ async function handleMarketListingPublish(args, io) {
802
+ const dataDir = requireOption(args, "data-dir");
803
+ await withCliContext(dataDir, async (context) => {
804
+ const issuedAt = now();
805
+ const productId = getOptionalOption(args, "product-id");
806
+ const payload = {
807
+ marketplaceId: requireOption(args, "marketplace"),
808
+ sellerDid: getOptionalOption(args, "seller-did") ?? context.identityMaterial.agentIdentity.did,
809
+ title: requireOption(args, "title"),
810
+ ...(productId ? { productId } : {}),
811
+ paymentTerms: parsePaymentTerms(args)
812
+ };
813
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("listing", toProtocolValue({
814
+ actorDid: context.identityMaterial.agentIdentity.did,
815
+ issuedAt,
816
+ payload: toProtocolJsonObject(payload)
817
+ }));
818
+ const result = await appendEnvelope(context, {
819
+ objectKind: "listing",
820
+ objectId,
821
+ eventKind: "listing.published",
822
+ subjectId: objectId,
823
+ payload: toProtocolJsonObject(payload),
824
+ issuedAt
825
+ });
826
+ writeJson(io, {
827
+ command: "market.listing.publish",
828
+ objectId,
829
+ eventId: result.envelope.eventId,
830
+ state: result.state
831
+ });
832
+ });
833
+ }
834
+ async function handleMarketListingRevise(args, io) {
835
+ const dataDir = requireOption(args, "data-dir");
836
+ const objectId = requireOption(args, "id");
837
+ await withCliContext(dataDir, async (context) => {
838
+ const state = await readRequiredState(context.repository, "listing", objectId);
839
+ const title = getOptionalOption(args, "title");
840
+ const paymentTerms = mergePaymentTerms(args, state.paymentTerms);
841
+ const result = await appendEnvelope(context, {
842
+ objectKind: "listing",
843
+ objectId,
844
+ eventKind: "listing.revised",
845
+ subjectId: objectId,
846
+ payload: toProtocolJsonObject({
847
+ ...(title !== undefined ? { title } : {}),
848
+ paymentTerms
849
+ })
850
+ });
851
+ writeJson(io, {
852
+ command: "market.listing.revise",
853
+ objectId,
854
+ eventId: result.envelope.eventId,
855
+ state: result.state
856
+ });
857
+ });
858
+ }
859
+ async function handleSimpleMarketStateChange(args, io, objectKind, eventKind) {
860
+ const dataDir = requireOption(args, "data-dir");
861
+ const objectId = requireOption(args, "id");
862
+ await withCliContext(dataDir, async (context) => {
863
+ const result = await appendEnvelope(context, {
864
+ objectKind,
865
+ objectId,
866
+ eventKind,
867
+ subjectId: objectId,
868
+ payload: {}
869
+ });
870
+ writeJson(io, {
871
+ command: `market.${objectKind}.${eventKind.split(".")[1]}`,
872
+ objectId,
873
+ eventId: result.envelope.eventId,
874
+ state: result.state
875
+ });
876
+ });
877
+ }
878
+ async function handleMarketRequestPublish(args, io) {
879
+ const dataDir = requireOption(args, "data-dir");
880
+ await withCliContext(dataDir, async (context) => {
881
+ const issuedAt = now();
882
+ const payload = {
883
+ marketplaceId: requireOption(args, "marketplace"),
884
+ requesterDid: getOptionalOption(args, "requester-did") ?? context.identityMaterial.agentIdentity.did,
885
+ title: requireOption(args, "title"),
886
+ paymentTerms: parsePaymentTerms(args)
887
+ };
888
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("request", toProtocolValue({
889
+ actorDid: context.identityMaterial.agentIdentity.did,
890
+ issuedAt,
891
+ payload: toProtocolJsonObject(payload)
892
+ }));
893
+ const result = await appendEnvelope(context, {
894
+ objectKind: "request",
895
+ objectId,
896
+ eventKind: "request.published",
897
+ subjectId: objectId,
898
+ payload: toProtocolJsonObject(payload),
899
+ issuedAt
900
+ });
901
+ writeJson(io, {
902
+ command: "market.request.publish",
903
+ objectId,
904
+ eventId: result.envelope.eventId,
905
+ state: result.state
906
+ });
907
+ });
908
+ }
909
+ async function handleMarketRequestRevise(args, io) {
910
+ const dataDir = requireOption(args, "data-dir");
911
+ const objectId = requireOption(args, "id");
912
+ await withCliContext(dataDir, async (context) => {
913
+ const state = await readRequiredState(context.repository, "request", objectId);
914
+ const title = getOptionalOption(args, "title");
915
+ const paymentTerms = mergePaymentTerms(args, state.paymentTerms);
916
+ const result = await appendEnvelope(context, {
917
+ objectKind: "request",
918
+ objectId,
919
+ eventKind: "request.revised",
920
+ subjectId: objectId,
921
+ payload: toProtocolJsonObject({
922
+ ...(title !== undefined ? { title } : {}),
923
+ paymentTerms
924
+ })
925
+ });
926
+ writeJson(io, {
927
+ command: "market.request.revise",
928
+ objectId,
929
+ eventId: result.envelope.eventId,
930
+ state: result.state
931
+ });
932
+ });
933
+ }
934
+ async function handleMarketOfferSubmit(args, io) {
935
+ const dataDir = requireOption(args, "data-dir");
936
+ await withCliContext(dataDir, async (context) => {
937
+ const issuedAt = now();
938
+ const targetObjectId = getOptionalOption(args, "target-object-id");
939
+ const lightningRefs = parseLightningRefs(args);
940
+ const payload = {
941
+ marketplaceId: requireOption(args, "marketplace"),
942
+ proposerDid: getOptionalOption(args, "proposer-did") ?? context.identityMaterial.agentIdentity.did,
943
+ ...(targetObjectId ? { targetObjectId } : {}),
944
+ paymentTerms: parsePaymentTerms(args),
945
+ ...(lightningRefs.length > 0 ? { lightningRefs } : {})
946
+ };
947
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("offer", toProtocolValue({
948
+ actorDid: context.identityMaterial.agentIdentity.did,
949
+ issuedAt,
950
+ payload: toProtocolJsonObject(payload)
951
+ }));
952
+ const result = await appendEnvelope(context, {
953
+ objectKind: "offer",
954
+ objectId,
955
+ eventKind: "offer.submitted",
956
+ subjectId: objectId,
957
+ payload: toProtocolJsonObject(payload),
958
+ issuedAt
959
+ });
960
+ writeJson(io, {
961
+ command: "market.offer.submit",
962
+ objectId,
963
+ eventId: result.envelope.eventId,
964
+ state: result.state
965
+ });
966
+ });
967
+ }
968
+ async function handleMarketOfferCounter(args, io) {
969
+ const dataDir = requireOption(args, "data-dir");
970
+ const objectId = requireOption(args, "id");
971
+ await withCliContext(dataDir, async (context) => {
972
+ const state = await readRequiredState(context.repository, "offer", objectId);
973
+ const lightningRefs = parseLightningRefs(args);
974
+ const result = await appendEnvelope(context, {
975
+ objectKind: "offer",
976
+ objectId,
977
+ eventKind: "offer.countered",
978
+ subjectId: objectId,
979
+ payload: toProtocolJsonObject({
980
+ paymentTerms: mergePaymentTerms(args, state.paymentTerms),
981
+ ...(lightningRefs.length > 0 ? { lightningRefs } : {})
982
+ })
983
+ });
984
+ writeJson(io, {
985
+ command: "market.offer.counter",
986
+ objectId,
987
+ eventId: result.envelope.eventId,
988
+ state: result.state
989
+ });
990
+ });
991
+ }
992
+ async function handleMarketBidSubmit(args, io) {
993
+ const dataDir = requireOption(args, "data-dir");
994
+ await withCliContext(dataDir, async (context) => {
995
+ const issuedAt = now();
996
+ const targetObjectId = getOptionalOption(args, "target-object-id");
997
+ const lightningRefs = parseLightningRefs(args);
998
+ const payload = {
999
+ marketplaceId: requireOption(args, "marketplace"),
1000
+ proposerDid: getOptionalOption(args, "proposer-did") ?? context.identityMaterial.agentIdentity.did,
1001
+ ...(targetObjectId ? { targetObjectId } : {}),
1002
+ paymentTerms: parsePaymentTerms(args),
1003
+ ...(lightningRefs.length > 0 ? { lightningRefs } : {})
1004
+ };
1005
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("bid", toProtocolValue({
1006
+ actorDid: context.identityMaterial.agentIdentity.did,
1007
+ issuedAt,
1008
+ payload: toProtocolJsonObject(payload)
1009
+ }));
1010
+ const result = await appendEnvelope(context, {
1011
+ objectKind: "bid",
1012
+ objectId,
1013
+ eventKind: "bid.submitted",
1014
+ subjectId: objectId,
1015
+ payload: toProtocolJsonObject(payload),
1016
+ issuedAt
1017
+ });
1018
+ writeJson(io, {
1019
+ command: "market.bid.submit",
1020
+ objectId,
1021
+ eventId: result.envelope.eventId,
1022
+ state: result.state
1023
+ });
1024
+ });
1025
+ }
1026
+ async function handleMarketBidCounter(args, io) {
1027
+ const dataDir = requireOption(args, "data-dir");
1028
+ const objectId = requireOption(args, "id");
1029
+ await withCliContext(dataDir, async (context) => {
1030
+ const state = await readRequiredState(context.repository, "bid", objectId);
1031
+ const lightningRefs = parseLightningRefs(args);
1032
+ const result = await appendEnvelope(context, {
1033
+ objectKind: "bid",
1034
+ objectId,
1035
+ eventKind: "bid.countered",
1036
+ subjectId: objectId,
1037
+ payload: toProtocolJsonObject({
1038
+ paymentTerms: mergePaymentTerms(args, state.paymentTerms),
1039
+ ...(lightningRefs.length > 0 ? { lightningRefs } : {})
1040
+ })
1041
+ });
1042
+ writeJson(io, {
1043
+ command: "market.bid.counter",
1044
+ objectId,
1045
+ eventId: result.envelope.eventId,
1046
+ state: result.state
1047
+ });
1048
+ });
1049
+ }
1050
+ function deriveAgreementCounterparties(sourceKind, sourceState, actorDid, explicitCounterparties) {
1051
+ if (explicitCounterparties.length > 0) {
1052
+ return [...new Set(explicitCounterparties)].sort();
1053
+ }
1054
+ switch (sourceKind) {
1055
+ case "offer":
1056
+ return [...new Set([sourceState.proposerDid, actorDid])].sort();
1057
+ case "bid":
1058
+ return [...new Set([sourceState.proposerDid, actorDid])].sort();
1059
+ case "listing":
1060
+ return [...new Set([sourceState.sellerDid, actorDid])].sort();
1061
+ case "request":
1062
+ return [...new Set([sourceState.requesterDid, actorDid])].sort();
1063
+ }
1064
+ }
1065
+ async function handleMarketAgreementCreate(args, io) {
1066
+ const dataDir = requireOption(args, "data-dir");
1067
+ const sourceKind = parseEnum(requireOption(args, "source-kind"), "--source-kind", [
1068
+ "offer",
1069
+ "bid",
1070
+ "listing",
1071
+ "request"
1072
+ ]);
1073
+ const sourceObjectId = requireOption(args, "source-id");
1074
+ await withCliContext(dataDir, async (context) => {
1075
+ const issuedAt = now();
1076
+ const sourceState = await readRequiredState(context.repository, sourceKind, sourceObjectId);
1077
+ const marketplaceId = getOptionalOption(args, "marketplace") ?? sourceState.marketplaceId;
1078
+ const paymentTerms = getOptionalOption(args, "amount-sats") || getOptionalOption(args, "currency") || getOptionalOption(args, "settlement")
1079
+ ? mergePaymentTerms(args, sourceState.paymentTerms)
1080
+ : sourceState.paymentTerms;
1081
+ const deliverables = getCsvOptionValues(args, "deliverable");
1082
+ if (deliverables.length === 0) {
1083
+ throw new Error("At least one --deliverable is required");
1084
+ }
1085
+ const counterparties = deriveAgreementCounterparties(sourceKind, sourceState, context.identityMaterial.agentIdentity.did, getCsvOptionValues(args, "counterparty"));
1086
+ const lightningRefs = parseLightningRefs(args);
1087
+ const payload = {
1088
+ marketplaceId,
1089
+ sourceObjectKind: sourceKind,
1090
+ sourceObjectId,
1091
+ counterparties,
1092
+ deliverables,
1093
+ paymentTerms,
1094
+ ...(lightningRefs.length > 0 ? { lightningRefs } : {})
1095
+ };
1096
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("agreement", toProtocolValue({
1097
+ actorDid: context.identityMaterial.agentIdentity.did,
1098
+ issuedAt,
1099
+ payload: toProtocolJsonObject(payload)
1100
+ }));
1101
+ const result = await appendEnvelope(context, {
1102
+ objectKind: "agreement",
1103
+ objectId,
1104
+ eventKind: "agreement.created",
1105
+ subjectId: objectId,
1106
+ payload: toProtocolJsonObject(payload),
1107
+ issuedAt
1108
+ });
1109
+ writeJson(io, {
1110
+ command: "market.agreement.create",
1111
+ objectId,
1112
+ eventId: result.envelope.eventId,
1113
+ state: result.state
1114
+ });
1115
+ });
1116
+ }
1117
+ async function handleContractCreate(args, io) {
1118
+ const dataDir = requireOption(args, "data-dir");
1119
+ await withCliContext(dataDir, async (context) => {
1120
+ const issuedAt = now();
1121
+ const sponsorDid = getOptionalOption(args, "sponsor-did");
1122
+ const companyDid = getOptionalOption(args, "company-did");
1123
+ const payload = {
1124
+ originRef: {
1125
+ objectKind: parseEnum(requireOption(args, "origin-kind"), "--origin-kind", [
1126
+ "agreement",
1127
+ "listing",
1128
+ "request",
1129
+ "offer",
1130
+ "bid"
1131
+ ]),
1132
+ objectId: requireOption(args, "origin-id")
1133
+ },
1134
+ parties: getCsvOptionValues(args, "party"),
1135
+ ...(sponsorDid ? { sponsorDid } : {}),
1136
+ ...(companyDid ? { companyDid } : {}),
1137
+ scope: requireOption(args, "scope"),
1138
+ milestones: parseJsonOption(args, "milestones-json"),
1139
+ deliverableSchema: parseJsonOption(args, "deliverable-schema-json"),
1140
+ proofPolicy: parseJsonOption(args, "proof-policy-json"),
1141
+ resolutionPolicy: parseJsonOption(args, "resolution-policy-json"),
1142
+ settlementPolicy: parseJsonOption(args, "settlement-policy-json"),
1143
+ deadlinePolicy: parseJsonOption(args, "deadline-policy-json")
1144
+ };
1145
+ if (payload.parties.length === 0) {
1146
+ throw new Error("At least one --party is required");
1147
+ }
1148
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("contract", toProtocolValue({
1149
+ actorDid: context.identityMaterial.agentIdentity.did,
1150
+ issuedAt,
1151
+ payload: toProtocolJsonObject(payload)
1152
+ }));
1153
+ const result = await appendEnvelope(context, {
1154
+ objectKind: "contract",
1155
+ objectId,
1156
+ eventKind: "contract.created",
1157
+ subjectId: objectId,
1158
+ payload: Protocol.contractCreatedPayloadToJson(payload),
1159
+ issuedAt
1160
+ });
1161
+ writeJson(io, {
1162
+ command: "contract.create",
1163
+ objectId,
1164
+ eventId: result.envelope.eventId,
1165
+ state: result.state
1166
+ });
1167
+ });
1168
+ }
1169
+ async function handleContractMilestoneAction(args, io, eventKind) {
1170
+ const dataDir = requireOption(args, "data-dir");
1171
+ const contractId = requireOption(args, "id");
1172
+ const milestoneId = requireOption(args, "milestone-id");
1173
+ await withCliContext(dataDir, async (context) => {
1174
+ const payload = eventKind === "contract.milestone-opened"
1175
+ ? { milestoneId }
1176
+ : eventKind === "contract.milestone-rejected"
1177
+ ? { milestoneId, reason: requireOption(args, "reason") }
1178
+ : {
1179
+ milestoneId,
1180
+ ...(getUniqueOptionValues(args, "evidence-bundle-id").length > 0
1181
+ ? { evidenceBundleIds: getUniqueOptionValues(args, "evidence-bundle-id") }
1182
+ : {}),
1183
+ ...(getUniqueOptionValues(args, "oracle-attestation-id").length > 0
1184
+ ? { oracleAttestationIds: getUniqueOptionValues(args, "oracle-attestation-id") }
1185
+ : {})
1186
+ };
1187
+ const result = await appendEnvelope(context, {
1188
+ objectKind: "contract",
1189
+ objectId: contractId,
1190
+ eventKind,
1191
+ subjectId: contractId,
1192
+ payload: toProtocolJsonObject(payload)
1193
+ });
1194
+ writeJson(io, {
1195
+ command: `contract.${eventKind.split(".")[1]}`,
1196
+ objectId: contractId,
1197
+ eventId: result.envelope.eventId,
1198
+ state: result.state
1199
+ });
1200
+ });
1201
+ }
1202
+ async function handleContractStateChange(args, io, eventKind) {
1203
+ const dataDir = requireOption(args, "data-dir");
1204
+ const contractId = requireOption(args, "id");
1205
+ await withCliContext(dataDir, async (context) => {
1206
+ const result = await appendEnvelope(context, {
1207
+ objectKind: "contract",
1208
+ objectId: contractId,
1209
+ eventKind,
1210
+ subjectId: contractId,
1211
+ payload: {}
1212
+ });
1213
+ writeJson(io, {
1214
+ command: `contract.${eventKind.split(".")[1]}`,
1215
+ objectId: contractId,
1216
+ eventId: result.envelope.eventId,
1217
+ state: result.state
1218
+ });
1219
+ });
1220
+ }
1221
+ async function handleEvidenceRecord(args, io) {
1222
+ const dataDir = requireOption(args, "data-dir");
1223
+ await withCliContext(dataDir, async (context) => {
1224
+ const issuedAt = now();
1225
+ const artifactRefs = getOptionalOption(args, "artifact-json")
1226
+ ? parseJsonOption(args, "artifact-json")
1227
+ : [];
1228
+ const verifierRefs = getOptionalOption(args, "verifier-json")
1229
+ ? parseJsonOption(args, "verifier-json")
1230
+ : [];
1231
+ const reproInstructions = getOptionalOption(args, "repro");
1232
+ const executionTranscriptRefs = getUniqueOptionValues(args, "execution-transcript-ref");
1233
+ const hashes = Object.fromEntries(getUniqueOptionValues(args, "hash").map((entry) => {
1234
+ const [name, hash] = entry.split("=", 2);
1235
+ if (!name || !hash) {
1236
+ throw new Error("--hash must use <name>=<hex-hash>");
1237
+ }
1238
+ return [name, hash];
1239
+ }));
1240
+ const payload = {
1241
+ contractId: requireOption(args, "contract-id"),
1242
+ milestoneId: requireOption(args, "milestone-id"),
1243
+ submitterDid: context.identityMaterial.agentIdentity.did,
1244
+ artifactRefs,
1245
+ verifierRefs,
1246
+ proofModes: getCsvOptionValues(args, "proof-mode"),
1247
+ ...(reproInstructions ? { reproInstructions } : {}),
1248
+ hashes,
1249
+ executionTranscriptRefs
1250
+ };
1251
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("evidence-bundle", toProtocolValue({
1252
+ actorDid: context.identityMaterial.agentIdentity.did,
1253
+ issuedAt,
1254
+ payload: toProtocolJsonObject(payload)
1255
+ }));
1256
+ const result = await appendEnvelope(context, {
1257
+ objectKind: "evidence-bundle",
1258
+ objectId,
1259
+ eventKind: "evidence-bundle.recorded",
1260
+ subjectId: objectId,
1261
+ payload: Protocol.evidenceBundlePayloadToJson(payload),
1262
+ issuedAt
1263
+ });
1264
+ writeJson(io, {
1265
+ command: "evidence.record",
1266
+ objectId,
1267
+ eventId: result.envelope.eventId,
1268
+ state: result.state
1269
+ });
1270
+ });
1271
+ }
1272
+ async function handleOracleAttest(args, io) {
1273
+ const dataDir = requireOption(args, "data-dir");
1274
+ await withCliContext(dataDir, async (context) => {
1275
+ const issuedAt = getOptionalOption(args, "issued-at") ?? now();
1276
+ const milestoneId = getOptionalOption(args, "milestone-id");
1277
+ const payload = {
1278
+ oracleDid: context.identityMaterial.agentIdentity.did,
1279
+ claimType: requireOption(args, "claim-type"),
1280
+ subjectRef: {
1281
+ objectKind: parseEnum(requireOption(args, "subject-kind"), "--subject-kind", [
1282
+ "contract",
1283
+ "evidence-bundle",
1284
+ "dispute-case"
1285
+ ]),
1286
+ objectId: requireOption(args, "subject-id"),
1287
+ ...(milestoneId ? { milestoneId } : {})
1288
+ },
1289
+ outcome: parseEnum(requireOption(args, "outcome"), "--outcome", [
1290
+ "satisfied",
1291
+ "unsatisfied",
1292
+ "accepted",
1293
+ "rejected",
1294
+ "completed",
1295
+ "breached"
1296
+ ]),
1297
+ evidenceRefs: getUniqueOptionValues(args, "evidence-ref"),
1298
+ issuedAt,
1299
+ expiresAt: requireOption(args, "expires-at")
1300
+ };
1301
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("oracle-attestation", toProtocolValue({
1302
+ actorDid: context.identityMaterial.agentIdentity.did,
1303
+ issuedAt,
1304
+ payload: toProtocolJsonObject(payload)
1305
+ }));
1306
+ const result = await appendEnvelope(context, {
1307
+ objectKind: "oracle-attestation",
1308
+ objectId,
1309
+ eventKind: "oracle-attestation.recorded",
1310
+ subjectId: objectId,
1311
+ payload: Protocol.oracleAttestationPayloadToJson(payload),
1312
+ issuedAt
1313
+ });
1314
+ writeJson(io, {
1315
+ command: "oracle.attest",
1316
+ objectId,
1317
+ eventId: result.envelope.eventId,
1318
+ state: result.state
1319
+ });
1320
+ });
1321
+ }
1322
+ async function handleDisputeOpen(args, io) {
1323
+ const dataDir = requireOption(args, "data-dir");
1324
+ await withCliContext(dataDir, async (context) => {
1325
+ const issuedAt = now();
1326
+ const payload = {
1327
+ contractId: requireOption(args, "contract-id"),
1328
+ ...(getOptionalOption(args, "milestone-id") ? { milestoneId: getOptionalOption(args, "milestone-id") } : {}),
1329
+ reason: requireOption(args, "reason")
1330
+ };
1331
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("dispute-case", toProtocolValue({
1332
+ actorDid: context.identityMaterial.agentIdentity.did,
1333
+ issuedAt,
1334
+ payload: toProtocolJsonObject(payload)
1335
+ }));
1336
+ const result = await appendEnvelope(context, {
1337
+ objectKind: "dispute-case",
1338
+ objectId,
1339
+ eventKind: "dispute.opened",
1340
+ subjectId: objectId,
1341
+ payload: toProtocolJsonObject(payload),
1342
+ issuedAt
1343
+ });
1344
+ writeJson(io, {
1345
+ command: "dispute.open",
1346
+ objectId,
1347
+ eventId: result.envelope.eventId,
1348
+ state: result.state
1349
+ });
1350
+ });
1351
+ }
1352
+ async function handleDisputeAddEvidence(args, io) {
1353
+ const dataDir = requireOption(args, "data-dir");
1354
+ const objectId = requireOption(args, "id");
1355
+ await withCliContext(dataDir, async (context) => {
1356
+ const evidenceBundleIds = getUniqueOptionValues(args, "evidence-bundle-id");
1357
+ if (evidenceBundleIds.length === 0) {
1358
+ throw new Error("At least one --evidence-bundle-id is required");
1359
+ }
1360
+ const result = await appendEnvelope(context, {
1361
+ objectKind: "dispute-case",
1362
+ objectId,
1363
+ eventKind: "dispute.evidence-added",
1364
+ subjectId: objectId,
1365
+ payload: {
1366
+ evidenceBundleIds
1367
+ }
1368
+ });
1369
+ writeJson(io, {
1370
+ command: "dispute.add-evidence",
1371
+ objectId,
1372
+ eventId: result.envelope.eventId,
1373
+ state: result.state
1374
+ });
1375
+ });
1376
+ }
1377
+ async function handleDisputeRequestOracle(args, io) {
1378
+ const dataDir = requireOption(args, "data-dir");
1379
+ const objectId = requireOption(args, "id");
1380
+ await withCliContext(dataDir, async (context) => {
1381
+ const result = await appendEnvelope(context, {
1382
+ objectKind: "dispute-case",
1383
+ objectId,
1384
+ eventKind: "dispute.oracle-requested",
1385
+ subjectId: objectId,
1386
+ payload: {}
1387
+ });
1388
+ writeJson(io, {
1389
+ command: "dispute.request-oracle",
1390
+ objectId,
1391
+ eventId: result.envelope.eventId,
1392
+ state: result.state
1393
+ });
1394
+ });
1395
+ }
1396
+ async function handleDisputeRule(args, io) {
1397
+ const dataDir = requireOption(args, "data-dir");
1398
+ const objectId = requireOption(args, "id");
1399
+ await withCliContext(dataDir, async (context) => {
1400
+ const deterministicVerifierId = getOptionalOption(args, "deterministic-verifier-id");
1401
+ const summary = getOptionalOption(args, "summary");
1402
+ const ruling = {
1403
+ outcome: parseEnum(requireOption(args, "outcome"), "--outcome", [
1404
+ "fulfilled",
1405
+ "breach",
1406
+ "refund",
1407
+ "partial",
1408
+ "rejected-claim"
1409
+ ]),
1410
+ resolutionMode: parseEnum(requireOption(args, "resolution-mode"), "--resolution-mode", [
1411
+ "deterministic",
1412
+ "oracle",
1413
+ "mutual",
1414
+ "hybrid"
1415
+ ]),
1416
+ ...(deterministicVerifierId ? { deterministicVerifierId } : {}),
1417
+ oracleAttestationIds: getUniqueOptionValues(args, "oracle-attestation-id"),
1418
+ evidenceBundleIds: getUniqueOptionValues(args, "evidence-bundle-id"),
1419
+ approverDids: getCsvOptionValues(args, "approver"),
1420
+ ...(summary ? { summary } : {})
1421
+ };
1422
+ const result = await appendEnvelope(context, {
1423
+ objectKind: "dispute-case",
1424
+ objectId,
1425
+ eventKind: "dispute.ruled",
1426
+ subjectId: objectId,
1427
+ payload: Protocol.disputeRulingToJson(ruling)
1428
+ });
1429
+ writeJson(io, {
1430
+ command: "dispute.rule",
1431
+ objectId,
1432
+ eventId: result.envelope.eventId,
1433
+ state: result.state
1434
+ });
1435
+ });
1436
+ }
1437
+ async function handleDisputeClose(args, io) {
1438
+ const dataDir = requireOption(args, "data-dir");
1439
+ const objectId = requireOption(args, "id");
1440
+ await withCliContext(dataDir, async (context) => {
1441
+ const result = await appendEnvelope(context, {
1442
+ objectKind: "dispute-case",
1443
+ objectId,
1444
+ eventKind: "dispute.closed",
1445
+ subjectId: objectId,
1446
+ payload: {}
1447
+ });
1448
+ writeJson(io, {
1449
+ command: "dispute.close",
1450
+ objectId,
1451
+ eventId: result.envelope.eventId,
1452
+ state: result.state
1453
+ });
1454
+ });
1455
+ }
1456
+ async function handleSpaceCreate(args, io) {
1457
+ const dataDir = requireOption(args, "data-dir");
1458
+ await withCliContext(dataDir, async (context) => {
1459
+ const issuedAt = now();
1460
+ const spaceId = getOptionalOption(args, "id") ?? defaultObjectId("space", toProtocolValue({
1461
+ actorDid: context.identityMaterial.agentIdentity.did,
1462
+ issuedAt,
1463
+ ownerRef: {
1464
+ kind: requireOption(args, "owner-kind"),
1465
+ id: requireOption(args, "owner-id")
1466
+ }
1467
+ }));
1468
+ const membershipPolicy = getOptionalOption(args, "membership-policy-json")
1469
+ ? parseJsonOption(args, "membership-policy-json")
1470
+ : {
1471
+ mode: "invite-only",
1472
+ ownerMemberDids: [context.identityMaterial.agentIdentity.did]
1473
+ };
1474
+ const encryptionPolicy = getOptionalOption(args, "encryption-policy-json")
1475
+ ? parseJsonOption(args, "encryption-policy-json")
1476
+ : {
1477
+ mode: "member-sealed-box",
1478
+ keyAgreementMethod: "did-keyagreement-v1"
1479
+ };
1480
+ const payload = {
1481
+ spaceKind: parseEnum(requireOption(args, "space-kind"), "--space-kind", [
1482
+ "direct-inbox",
1483
+ "contract-thread",
1484
+ "company-room",
1485
+ "market-room"
1486
+ ]),
1487
+ ownerRef: {
1488
+ kind: parseEnum(requireOption(args, "owner-kind"), "--owner-kind", [
1489
+ "agent",
1490
+ "company",
1491
+ "marketplace",
1492
+ "contract",
1493
+ "dispute"
1494
+ ]),
1495
+ id: requireOption(args, "owner-id")
1496
+ },
1497
+ membershipPolicy,
1498
+ encryptionPolicy
1499
+ };
1500
+ const created = await appendEnvelope(context, {
1501
+ objectKind: "space",
1502
+ objectId: spaceId,
1503
+ eventKind: "space.created",
1504
+ subjectId: spaceId,
1505
+ payload: Protocol.spacePayloadToJson(payload),
1506
+ issuedAt
1507
+ });
1508
+ const membershipObjectId = `${spaceId}:${context.identityMaterial.agentIdentity.did}`;
1509
+ await appendEnvelope(context, {
1510
+ objectKind: "space-membership",
1511
+ objectId: membershipObjectId,
1512
+ eventKind: "space-membership.member-added",
1513
+ subjectId: membershipObjectId,
1514
+ payload: Protocol.spaceMembershipPayloadToJson({
1515
+ spaceId,
1516
+ memberDid: context.identityMaterial.agentIdentity.did,
1517
+ role: "owner"
1518
+ })
1519
+ });
1520
+ writeJson(io, {
1521
+ command: "space.create",
1522
+ objectId: spaceId,
1523
+ eventId: created.envelope.eventId,
1524
+ state: created.state
1525
+ });
1526
+ });
1527
+ }
1528
+ async function handleSpaceMembershipAction(args, io, eventKind) {
1529
+ const dataDir = requireOption(args, "data-dir");
1530
+ const spaceId = requireOption(args, "space-id");
1531
+ const memberDid = requireOption(args, "member-did");
1532
+ const objectId = getOptionalOption(args, "id") ?? `${spaceId}:${memberDid}`;
1533
+ await withCliContext(dataDir, async (context) => {
1534
+ const payload = eventKind === "space-membership.member-added"
1535
+ ? Protocol.spaceMembershipPayloadToJson({
1536
+ spaceId,
1537
+ memberDid,
1538
+ role: parseEnum(getOptionalOption(args, "role") ?? "member", "--role", [
1539
+ "owner",
1540
+ "moderator",
1541
+ "member"
1542
+ ])
1543
+ })
1544
+ : eventKind === "space-membership.member-role-updated"
1545
+ ? toProtocolJsonObject({
1546
+ role: parseEnum(requireOption(args, "role"), "--role", ["owner", "moderator", "member"])
1547
+ })
1548
+ : {};
1549
+ const result = await appendEnvelope(context, {
1550
+ objectKind: "space-membership",
1551
+ objectId,
1552
+ eventKind,
1553
+ subjectId: objectId,
1554
+ payload
1555
+ });
1556
+ writeJson(io, {
1557
+ command: `space.${eventKind.split(".")[1]}`,
1558
+ objectId,
1559
+ eventId: result.envelope.eventId,
1560
+ state: result.state
1561
+ });
1562
+ });
1563
+ }
1564
+ async function handleMessageSend(args, io) {
1565
+ const dataDir = requireOption(args, "data-dir");
1566
+ await withCliContext(dataDir, async (context) => {
1567
+ const issuedAt = now();
1568
+ const spaceId = requireOption(args, "space-id");
1569
+ const activeMemberDids = listActiveSpaceMemberDids(context, spaceId);
1570
+ if (activeMemberDids.length === 0) {
1571
+ throw new Error("The target space has no active members");
1572
+ }
1573
+ const encryptedBody = await Protocol.encryptMessageForRecipients({
1574
+ plaintext: requireOption(args, "body"),
1575
+ senderDid: context.identityMaterial.agentIdentity.did,
1576
+ senderKeyAgreementPublicKey: context.identityMaterial.agentIdentity.keyAgreementPublicKey,
1577
+ senderKeyAgreementSecretKey: context.identityMaterial.keyAgreementKeyPair.secretKey,
1578
+ recipientDids: activeMemberDids
1579
+ });
1580
+ const payload = {
1581
+ spaceId,
1582
+ messageType: getOptionalOption(args, "message-type") ?? "text",
1583
+ metadata: getOptionalOption(args, "metadata-json")
1584
+ ? parseJsonOption(args, "metadata-json")
1585
+ : {},
1586
+ encryptedBody,
1587
+ sentAt: issuedAt
1588
+ };
1589
+ const objectId = getOptionalOption(args, "id") ?? defaultObjectId("message", toProtocolValue({
1590
+ actorDid: context.identityMaterial.agentIdentity.did,
1591
+ issuedAt,
1592
+ payload: toProtocolJsonObject(payload)
1593
+ }));
1594
+ const result = await appendEnvelope(context, {
1595
+ objectKind: "message",
1596
+ objectId,
1597
+ eventKind: "message.sent",
1598
+ subjectId: objectId,
1599
+ payload: Protocol.messageSentPayloadToJson(payload),
1600
+ issuedAt
1601
+ });
1602
+ writeJson(io, {
1603
+ command: "message.send",
1604
+ objectId,
1605
+ eventId: result.envelope.eventId,
1606
+ state: result.state
1607
+ });
1608
+ });
1609
+ }
1610
+ async function handleMessageEdit(args, io) {
1611
+ const dataDir = requireOption(args, "data-dir");
1612
+ const objectId = requireOption(args, "id");
1613
+ await withCliContext(dataDir, async (context) => {
1614
+ const current = await readRequiredState(context.repository, "message", objectId);
1615
+ const activeMemberDids = listActiveSpaceMemberDids(context, current.spaceId);
1616
+ const encryptedBody = await Protocol.encryptMessageForRecipients({
1617
+ plaintext: requireOption(args, "body"),
1618
+ senderDid: context.identityMaterial.agentIdentity.did,
1619
+ senderKeyAgreementPublicKey: context.identityMaterial.agentIdentity.keyAgreementPublicKey,
1620
+ senderKeyAgreementSecretKey: context.identityMaterial.keyAgreementKeyPair.secretKey,
1621
+ recipientDids: activeMemberDids
1622
+ });
1623
+ const result = await appendEnvelope(context, {
1624
+ objectKind: "message",
1625
+ objectId,
1626
+ eventKind: "message.edited",
1627
+ subjectId: objectId,
1628
+ payload: Protocol.messageSentPayloadToJson({
1629
+ spaceId: current.spaceId,
1630
+ messageType: current.messageType,
1631
+ metadata: getOptionalOption(args, "metadata-json")
1632
+ ? parseJsonOption(args, "metadata-json")
1633
+ : current.metadata,
1634
+ encryptedBody
1635
+ })
1636
+ });
1637
+ writeJson(io, {
1638
+ command: "message.edit",
1639
+ objectId,
1640
+ eventId: result.envelope.eventId,
1641
+ state: result.state
1642
+ });
1643
+ });
1644
+ }
1645
+ async function handleMessageDelete(args, io) {
1646
+ const dataDir = requireOption(args, "data-dir");
1647
+ const objectId = requireOption(args, "id");
1648
+ await withCliContext(dataDir, async (context) => {
1649
+ const result = await appendEnvelope(context, {
1650
+ objectKind: "message",
1651
+ objectId,
1652
+ eventKind: "message.deleted",
1653
+ subjectId: objectId,
1654
+ payload: {}
1655
+ });
1656
+ writeJson(io, {
1657
+ command: "message.delete",
1658
+ objectId,
1659
+ eventId: result.envelope.eventId,
1660
+ state: result.state
1661
+ });
1662
+ });
1663
+ }
1664
+ async function handleMessageReact(args, io) {
1665
+ const dataDir = requireOption(args, "data-dir");
1666
+ const objectId = requireOption(args, "id");
1667
+ await withCliContext(dataDir, async (context) => {
1668
+ const result = await appendEnvelope(context, {
1669
+ objectKind: "message",
1670
+ objectId,
1671
+ eventKind: "message.reacted",
1672
+ subjectId: objectId,
1673
+ payload: {
1674
+ reaction: requireOption(args, "reaction")
1675
+ }
1676
+ });
1677
+ writeJson(io, {
1678
+ command: "message.react",
1679
+ objectId,
1680
+ eventId: result.envelope.eventId,
1681
+ state: result.state
1682
+ });
1683
+ });
1684
+ }
1685
+ async function handleContractEntries(args, io) {
1686
+ const dataDir = requireOption(args, "data-dir");
1687
+ const contractId = requireOption(args, "id");
1688
+ await withCliContext(dataDir, async (context) => {
1689
+ writeJson(io, {
1690
+ command: "contract.entries",
1691
+ contractId,
1692
+ entries: await context.repository.listContractEntries(contractId)
1693
+ });
1694
+ });
1695
+ }
1696
+ async function handleSpaceEntries(args, io) {
1697
+ const dataDir = requireOption(args, "data-dir");
1698
+ const spaceId = requireOption(args, "space-id");
1699
+ await withCliContext(dataDir, async (context) => {
1700
+ writeJson(io, {
1701
+ command: "space.entries",
1702
+ spaceId,
1703
+ entries: await context.repository.listSpaceEntries(spaceId)
1704
+ });
1705
+ });
1706
+ }
1707
+ async function handleObjectShow(args, io) {
1708
+ const dataDir = requireOption(args, "data-dir");
1709
+ const kind = parseEnum(requireOption(args, "kind"), "--kind", [
1710
+ "agent-profile",
1711
+ "company",
1712
+ "product",
1713
+ "listing",
1714
+ "request",
1715
+ "offer",
1716
+ "bid",
1717
+ "agreement",
1718
+ "feedback-credential-ref",
1719
+ "contract",
1720
+ "evidence-bundle",
1721
+ "oracle-attestation",
1722
+ "dispute-case",
1723
+ "space",
1724
+ "space-membership",
1725
+ "message"
1726
+ ]);
1727
+ const objectId = requireOption(args, "id");
1728
+ await withCliContext(dataDir, async (context) => {
1729
+ writeJson(io, {
1730
+ command: "object.show",
1731
+ kind,
1732
+ objectId,
1733
+ state: await context.repository.readObjectState(kind, objectId)
1734
+ });
1735
+ });
1736
+ }
1737
+ async function handleMarketList(args, io) {
1738
+ const dataDir = requireOption(args, "data-dir");
1739
+ const marketplaceId = requireOption(args, "marketplace");
1740
+ await withCliContext(dataDir, async (context) => {
1741
+ writeJson(io, {
1742
+ command: "market.list",
1743
+ marketplaceId,
1744
+ entries: await context.repository.listMarketplaceEntries(marketplaceId)
1745
+ });
1746
+ });
1747
+ }
1748
+ async function handleServe(args, io) {
1749
+ const dataDir = requireOption(args, "data-dir");
1750
+ const logLevel = parseEnum(getOptionalOption(args, "log-level") ?? "info", "--log-level", [
1751
+ "debug",
1752
+ "info",
1753
+ "warn",
1754
+ "error"
1755
+ ]);
1756
+ const bootstrap = getCsvOptionValues(args, "bootstrap");
1757
+ const marketplaces = getCsvOptionValues(args, "marketplace");
1758
+ const companyIds = getCsvOptionValues(args, "company");
1759
+ const connectDids = getCsvOptionValues(args, "connect-did");
1760
+ const connectNoiseKeys = getCsvOptionValues(args, "connect-noise-key");
1761
+ const exitAfterMs = getOptionalOption(args, "exit-after-ms");
1762
+ const watchProtocol = !hasFlag(args, "no-watch-protocol");
1763
+ const transportConfig = {
1764
+ dataDir,
1765
+ logLevel,
1766
+ ...(bootstrap.length > 0 ? { bootstrap } : {})
1767
+ };
1768
+ const transport = await AgentTransport.create(transportConfig);
1769
+ const topics = [];
1770
+ const seenControlLengths = new Map();
1771
+ const discoveryIntervalMs = 2_000;
1772
+ let discoveryInterval;
1773
+ try {
1774
+ await transport.start();
1775
+ if (hasFlag(args, "agent-topic")) {
1776
+ topics.push({ kind: "agent", agentDid: transport.identity.did });
1777
+ }
1778
+ for (const marketplaceId of marketplaces) {
1779
+ topics.push({ kind: "marketplace", marketplaceId });
1780
+ }
1781
+ for (const companyId of companyIds) {
1782
+ topics.push({ kind: "company", companyId });
1783
+ }
1784
+ for (const topic of topics) {
1785
+ await transport.joinTopic(topic);
1786
+ }
1787
+ for (const did of connectDids) {
1788
+ await transport.connectToDid(did);
1789
+ }
1790
+ for (const publicKey of connectNoiseKeys) {
1791
+ await transport.connectToNoiseKey(publicKey);
1792
+ }
1793
+ writeJson(io, {
1794
+ command: "serve",
1795
+ identity: transport.identity,
1796
+ topics,
1797
+ connectedPeers: [...transport.getPeerSessions().values()]
1798
+ });
1799
+ if (watchProtocol) {
1800
+ discoveryInterval = setInterval(() => {
1801
+ void (async () => {
1802
+ for (const session of transport.getPeerSessions().values()) {
1803
+ const remoteFeed = transport.getRemoteFeed(session.remoteControlFeedKey);
1804
+ if (!remoteFeed) {
1805
+ continue;
1806
+ }
1807
+ await remoteFeed.update({ wait: false });
1808
+ const seenLength = seenControlLengths.get(session.remoteControlFeedKey) ?? 0;
1809
+ if (remoteFeed.length <= seenLength) {
1810
+ continue;
1811
+ }
1812
+ for (let index = seenLength; index < remoteFeed.length; index += 1) {
1813
+ const entry = await remoteFeed.get(index);
1814
+ if (Protocol.isProtocolAnnouncement(entry)) {
1815
+ io.stdout(`${JSON.stringify({ command: "serve.discovery", remoteDid: session.remoteDid, announcement: entry }, null, 2)}\n`);
1816
+ }
1817
+ }
1818
+ seenControlLengths.set(session.remoteControlFeedKey, remoteFeed.length);
1819
+ }
1820
+ })().catch((error) => {
1821
+ io.stderr(`${error instanceof Error ? error.message : String(error)}\n`);
1822
+ });
1823
+ }, discoveryIntervalMs);
1824
+ }
1825
+ if (exitAfterMs) {
1826
+ await sleep(parsePositiveInteger(exitAfterMs, "--exit-after-ms"));
1827
+ return;
1828
+ }
1829
+ await Promise.race([once(process, "SIGINT"), once(process, "SIGTERM")]);
1830
+ }
1831
+ finally {
1832
+ if (discoveryInterval) {
1833
+ clearInterval(discoveryInterval);
1834
+ }
1835
+ await transport.stop();
1836
+ }
1837
+ }
1838
+ function usage() {
1839
+ return [
1840
+ "Usage:",
1841
+ " emporion agent init --data-dir <path> [--display-name <name>] [--bio <text>]",
1842
+ " emporion agent show --data-dir <path>",
1843
+ " emporion agent payment-endpoint add --data-dir <path> --id <id> --capability <cap>[,<cap>...]",
1844
+ " emporion agent wallet-attestation add --data-dir <path> --attestation-id <id> --wallet-account-id <id> --balance-sats <n> --expires-at <iso>",
1845
+ " emporion agent feedback add --data-dir <path> --credential-id <id> --issuer-did <did> --contract-id <id> --agreement-id <id> --score <n> --max-score <n>",
1846
+ " emporion company create --data-dir <path> --name <name> [--description <text>]",
1847
+ " emporion company update --data-dir <path> --company-did <did> [--name <name>] [--description <text>]",
1848
+ " emporion company grant-role --data-dir <path> --company-did <did> --member-did <did> --role <owner|operator|member>",
1849
+ " emporion company treasury-attest --data-dir <path> --company-did <did> --attestation-id <id> --wallet-account-id <id> --balance-sats <n> --expires-at <iso>",
1850
+ " emporion market product create --data-dir <path> --marketplace <id> --title <title>",
1851
+ " emporion market listing publish --data-dir <path> --marketplace <id> --title <title> --amount-sats <n>",
1852
+ " emporion market request publish --data-dir <path> --marketplace <id> --title <title> --amount-sats <n>",
1853
+ " emporion market offer submit --data-dir <path> --marketplace <id> --amount-sats <n>",
1854
+ " emporion market bid submit --data-dir <path> --marketplace <id> --amount-sats <n>",
1855
+ " emporion market agreement create --data-dir <path> --source-kind <offer|bid|listing|request> --source-id <id> --deliverable <text>",
1856
+ " emporion contract create --data-dir <path> --origin-kind <kind> --origin-id <id> --party <did>[,<did>...] --scope <text> --milestones-json <json> --deliverable-schema-json <json> --proof-policy-json <json> --resolution-policy-json <json> --settlement-policy-json <json> --deadline-policy-json <json>",
1857
+ " emporion evidence record --data-dir <path> --contract-id <id> --milestone-id <id> --proof-mode <mode>[,<mode>...] [--artifact-json <json>] [--verifier-json <json>]",
1858
+ " emporion oracle attest --data-dir <path> --claim-type <type> --subject-kind <kind> --subject-id <id> --outcome <outcome> --expires-at <iso>",
1859
+ " emporion dispute open --data-dir <path> --contract-id <id> --reason <text>",
1860
+ " emporion space create --data-dir <path> --space-kind <kind> --owner-kind <kind> --owner-id <id>",
1861
+ " emporion message send --data-dir <path> --space-id <id> --body <text>",
1862
+ " emporion market list --data-dir <path> --marketplace <id>",
1863
+ " emporion object show --data-dir <path> --kind <kind> --id <id>",
1864
+ " emporion serve --data-dir <path> [--marketplace <id>] [--company <did>] [--agent-topic]"
1865
+ ].join("\n");
1866
+ }
1867
+ export async function runCli(argv, io = DEFAULT_IO) {
1868
+ try {
1869
+ const args = parseArgs(argv);
1870
+ if (args.commandPath.length === 0 || hasFlag(args, "help")) {
1871
+ io.stdout(`${usage()}\n`);
1872
+ return 0;
1873
+ }
1874
+ if (commandMatches(args.commandPath, "agent", "init"))
1875
+ return await handleAgentInit(args, io).then(() => 0);
1876
+ if (commandMatches(args.commandPath, "agent", "show"))
1877
+ return await handleAgentShow(args, io).then(() => 0);
1878
+ if (commandMatches(args.commandPath, "agent", "payment-endpoint", "add")) {
1879
+ return await handleAgentPaymentEndpointAdd(args, io).then(() => 0);
1880
+ }
1881
+ if (commandMatches(args.commandPath, "agent", "payment-endpoint", "remove")) {
1882
+ return await handleAgentPaymentEndpointRemove(args, io).then(() => 0);
1883
+ }
1884
+ if (commandMatches(args.commandPath, "agent", "wallet-attestation", "add")) {
1885
+ return await handleAgentWalletAttestationAdd(args, io).then(() => 0);
1886
+ }
1887
+ if (commandMatches(args.commandPath, "agent", "wallet-attestation", "remove")) {
1888
+ return await handleAgentWalletAttestationRemove(args, io).then(() => 0);
1889
+ }
1890
+ if (commandMatches(args.commandPath, "agent", "feedback", "add")) {
1891
+ return await handleAgentFeedbackAdd(args, io).then(() => 0);
1892
+ }
1893
+ if (commandMatches(args.commandPath, "agent", "feedback", "remove")) {
1894
+ return await handleAgentFeedbackRemove(args, io).then(() => 0);
1895
+ }
1896
+ if (commandMatches(args.commandPath, "company", "create"))
1897
+ return await handleCompanyCreate(args, io).then(() => 0);
1898
+ if (commandMatches(args.commandPath, "company", "show"))
1899
+ return await handleCompanyShow(args, io).then(() => 0);
1900
+ if (commandMatches(args.commandPath, "company", "update"))
1901
+ return await handleCompanyUpdate(args, io).then(() => 0);
1902
+ if (commandMatches(args.commandPath, "company", "grant-role")) {
1903
+ return await handleCompanyRoleChange(args, io, "grant").then(() => 0);
1904
+ }
1905
+ if (commandMatches(args.commandPath, "company", "revoke-role")) {
1906
+ return await handleCompanyRoleChange(args, io, "revoke").then(() => 0);
1907
+ }
1908
+ if (commandMatches(args.commandPath, "company", "join-market")) {
1909
+ return await handleCompanyMarketMembership(args, io, "join").then(() => 0);
1910
+ }
1911
+ if (commandMatches(args.commandPath, "company", "leave-market")) {
1912
+ return await handleCompanyMarketMembership(args, io, "leave").then(() => 0);
1913
+ }
1914
+ if (commandMatches(args.commandPath, "company", "treasury-attest")) {
1915
+ return await handleCompanyTreasuryAttest(args, io).then(() => 0);
1916
+ }
1917
+ if (commandMatches(args.commandPath, "company", "treasury-reserve")) {
1918
+ return await handleCompanyTreasuryReserve(args, io).then(() => 0);
1919
+ }
1920
+ if (commandMatches(args.commandPath, "company", "treasury-release")) {
1921
+ return await handleCompanyTreasuryRelease(args, io).then(() => 0);
1922
+ }
1923
+ if (commandMatches(args.commandPath, "market", "product", "create")) {
1924
+ return await handleMarketProductCreate(args, io).then(() => 0);
1925
+ }
1926
+ if (commandMatches(args.commandPath, "market", "product", "update")) {
1927
+ return await handleMarketProductUpdate(args, io).then(() => 0);
1928
+ }
1929
+ if (commandMatches(args.commandPath, "market", "product", "publish")) {
1930
+ return await handleMarketProductStateChange(args, io, "product.published").then(() => 0);
1931
+ }
1932
+ if (commandMatches(args.commandPath, "market", "product", "unpublish")) {
1933
+ return await handleMarketProductStateChange(args, io, "product.unpublished").then(() => 0);
1934
+ }
1935
+ if (commandMatches(args.commandPath, "market", "product", "retire")) {
1936
+ return await handleMarketProductStateChange(args, io, "product.retired").then(() => 0);
1937
+ }
1938
+ if (commandMatches(args.commandPath, "market", "listing", "publish")) {
1939
+ return await handleMarketListingPublish(args, io).then(() => 0);
1940
+ }
1941
+ if (commandMatches(args.commandPath, "market", "listing", "revise")) {
1942
+ return await handleMarketListingRevise(args, io).then(() => 0);
1943
+ }
1944
+ if (commandMatches(args.commandPath, "market", "listing", "withdraw")) {
1945
+ return await handleSimpleMarketStateChange(args, io, "listing", "listing.withdrawn").then(() => 0);
1946
+ }
1947
+ if (commandMatches(args.commandPath, "market", "listing", "expire")) {
1948
+ return await handleSimpleMarketStateChange(args, io, "listing", "listing.expired").then(() => 0);
1949
+ }
1950
+ if (commandMatches(args.commandPath, "market", "request", "publish")) {
1951
+ return await handleMarketRequestPublish(args, io).then(() => 0);
1952
+ }
1953
+ if (commandMatches(args.commandPath, "market", "request", "revise")) {
1954
+ return await handleMarketRequestRevise(args, io).then(() => 0);
1955
+ }
1956
+ if (commandMatches(args.commandPath, "market", "request", "close")) {
1957
+ return await handleSimpleMarketStateChange(args, io, "request", "request.closed").then(() => 0);
1958
+ }
1959
+ if (commandMatches(args.commandPath, "market", "request", "expire")) {
1960
+ return await handleSimpleMarketStateChange(args, io, "request", "request.expired").then(() => 0);
1961
+ }
1962
+ if (commandMatches(args.commandPath, "market", "offer", "submit")) {
1963
+ return await handleMarketOfferSubmit(args, io).then(() => 0);
1964
+ }
1965
+ if (commandMatches(args.commandPath, "market", "offer", "counter")) {
1966
+ return await handleMarketOfferCounter(args, io).then(() => 0);
1967
+ }
1968
+ if (commandMatches(args.commandPath, "market", "offer", "accept")) {
1969
+ return await handleSimpleMarketStateChange(args, io, "offer", "offer.accepted").then(() => 0);
1970
+ }
1971
+ if (commandMatches(args.commandPath, "market", "offer", "reject")) {
1972
+ return await handleSimpleMarketStateChange(args, io, "offer", "offer.rejected").then(() => 0);
1973
+ }
1974
+ if (commandMatches(args.commandPath, "market", "offer", "cancel")) {
1975
+ return await handleSimpleMarketStateChange(args, io, "offer", "offer.canceled").then(() => 0);
1976
+ }
1977
+ if (commandMatches(args.commandPath, "market", "offer", "expire")) {
1978
+ return await handleSimpleMarketStateChange(args, io, "offer", "offer.expired").then(() => 0);
1979
+ }
1980
+ if (commandMatches(args.commandPath, "market", "bid", "submit")) {
1981
+ return await handleMarketBidSubmit(args, io).then(() => 0);
1982
+ }
1983
+ if (commandMatches(args.commandPath, "market", "bid", "counter")) {
1984
+ return await handleMarketBidCounter(args, io).then(() => 0);
1985
+ }
1986
+ if (commandMatches(args.commandPath, "market", "bid", "accept")) {
1987
+ return await handleSimpleMarketStateChange(args, io, "bid", "bid.accepted").then(() => 0);
1988
+ }
1989
+ if (commandMatches(args.commandPath, "market", "bid", "reject")) {
1990
+ return await handleSimpleMarketStateChange(args, io, "bid", "bid.rejected").then(() => 0);
1991
+ }
1992
+ if (commandMatches(args.commandPath, "market", "bid", "cancel")) {
1993
+ return await handleSimpleMarketStateChange(args, io, "bid", "bid.canceled").then(() => 0);
1994
+ }
1995
+ if (commandMatches(args.commandPath, "market", "bid", "expire")) {
1996
+ return await handleSimpleMarketStateChange(args, io, "bid", "bid.expired").then(() => 0);
1997
+ }
1998
+ if (commandMatches(args.commandPath, "market", "agreement", "create")) {
1999
+ return await handleMarketAgreementCreate(args, io).then(() => 0);
2000
+ }
2001
+ if (commandMatches(args.commandPath, "market", "agreement", "complete")) {
2002
+ return await handleSimpleMarketStateChange(args, io, "agreement", "agreement.completed").then(() => 0);
2003
+ }
2004
+ if (commandMatches(args.commandPath, "market", "agreement", "cancel")) {
2005
+ return await handleSimpleMarketStateChange(args, io, "agreement", "agreement.canceled").then(() => 0);
2006
+ }
2007
+ if (commandMatches(args.commandPath, "market", "agreement", "dispute")) {
2008
+ return await handleSimpleMarketStateChange(args, io, "agreement", "agreement.disputed").then(() => 0);
2009
+ }
2010
+ if (commandMatches(args.commandPath, "market", "list"))
2011
+ return await handleMarketList(args, io).then(() => 0);
2012
+ if (commandMatches(args.commandPath, "contract", "create"))
2013
+ return await handleContractCreate(args, io).then(() => 0);
2014
+ if (commandMatches(args.commandPath, "contract", "open-milestone")) {
2015
+ return await handleContractMilestoneAction(args, io, "contract.milestone-opened").then(() => 0);
2016
+ }
2017
+ if (commandMatches(args.commandPath, "contract", "submit-milestone")) {
2018
+ return await handleContractMilestoneAction(args, io, "contract.milestone-submitted").then(() => 0);
2019
+ }
2020
+ if (commandMatches(args.commandPath, "contract", "accept-milestone")) {
2021
+ return await handleContractMilestoneAction(args, io, "contract.milestone-accepted").then(() => 0);
2022
+ }
2023
+ if (commandMatches(args.commandPath, "contract", "reject-milestone")) {
2024
+ return await handleContractMilestoneAction(args, io, "contract.milestone-rejected").then(() => 0);
2025
+ }
2026
+ if (commandMatches(args.commandPath, "contract", "pause")) {
2027
+ return await handleContractStateChange(args, io, "contract.paused").then(() => 0);
2028
+ }
2029
+ if (commandMatches(args.commandPath, "contract", "resume")) {
2030
+ return await handleContractStateChange(args, io, "contract.resumed").then(() => 0);
2031
+ }
2032
+ if (commandMatches(args.commandPath, "contract", "complete")) {
2033
+ return await handleContractStateChange(args, io, "contract.completed").then(() => 0);
2034
+ }
2035
+ if (commandMatches(args.commandPath, "contract", "cancel")) {
2036
+ return await handleContractStateChange(args, io, "contract.canceled").then(() => 0);
2037
+ }
2038
+ if (commandMatches(args.commandPath, "contract", "dispute")) {
2039
+ return await handleContractStateChange(args, io, "contract.disputed").then(() => 0);
2040
+ }
2041
+ if (commandMatches(args.commandPath, "contract", "entries")) {
2042
+ return await handleContractEntries(args, io).then(() => 0);
2043
+ }
2044
+ if (commandMatches(args.commandPath, "evidence", "record"))
2045
+ return await handleEvidenceRecord(args, io).then(() => 0);
2046
+ if (commandMatches(args.commandPath, "oracle", "attest"))
2047
+ return await handleOracleAttest(args, io).then(() => 0);
2048
+ if (commandMatches(args.commandPath, "dispute", "open"))
2049
+ return await handleDisputeOpen(args, io).then(() => 0);
2050
+ if (commandMatches(args.commandPath, "dispute", "add-evidence")) {
2051
+ return await handleDisputeAddEvidence(args, io).then(() => 0);
2052
+ }
2053
+ if (commandMatches(args.commandPath, "dispute", "request-oracle")) {
2054
+ return await handleDisputeRequestOracle(args, io).then(() => 0);
2055
+ }
2056
+ if (commandMatches(args.commandPath, "dispute", "rule"))
2057
+ return await handleDisputeRule(args, io).then(() => 0);
2058
+ if (commandMatches(args.commandPath, "dispute", "close"))
2059
+ return await handleDisputeClose(args, io).then(() => 0);
2060
+ if (commandMatches(args.commandPath, "space", "create"))
2061
+ return await handleSpaceCreate(args, io).then(() => 0);
2062
+ if (commandMatches(args.commandPath, "space", "add-member")) {
2063
+ return await handleSpaceMembershipAction(args, io, "space-membership.member-added").then(() => 0);
2064
+ }
2065
+ if (commandMatches(args.commandPath, "space", "remove-member")) {
2066
+ return await handleSpaceMembershipAction(args, io, "space-membership.member-removed").then(() => 0);
2067
+ }
2068
+ if (commandMatches(args.commandPath, "space", "mute-member")) {
2069
+ return await handleSpaceMembershipAction(args, io, "space-membership.member-muted").then(() => 0);
2070
+ }
2071
+ if (commandMatches(args.commandPath, "space", "set-role")) {
2072
+ return await handleSpaceMembershipAction(args, io, "space-membership.member-role-updated").then(() => 0);
2073
+ }
2074
+ if (commandMatches(args.commandPath, "space", "entries"))
2075
+ return await handleSpaceEntries(args, io).then(() => 0);
2076
+ if (commandMatches(args.commandPath, "message", "send"))
2077
+ return await handleMessageSend(args, io).then(() => 0);
2078
+ if (commandMatches(args.commandPath, "message", "edit"))
2079
+ return await handleMessageEdit(args, io).then(() => 0);
2080
+ if (commandMatches(args.commandPath, "message", "delete"))
2081
+ return await handleMessageDelete(args, io).then(() => 0);
2082
+ if (commandMatches(args.commandPath, "message", "react"))
2083
+ return await handleMessageReact(args, io).then(() => 0);
2084
+ if (commandMatches(args.commandPath, "object", "show"))
2085
+ return await handleObjectShow(args, io).then(() => 0);
2086
+ if (commandMatches(args.commandPath, "serve"))
2087
+ return await handleServe(args, io).then(() => 0);
2088
+ throw new Error(`Unknown command: ${args.commandPath.join(" ")}`);
2089
+ }
2090
+ catch (error) {
2091
+ io.stderr(`${error instanceof Error ? error.message : String(error)}\n`);
2092
+ return 1;
2093
+ }
2094
+ }
2095
+ const executedPath = process.argv[1] ? new URL(`file://${process.argv[1]}`).href : "";
2096
+ if (import.meta.url === executedPath) {
2097
+ void runCli(process.argv.slice(2)).then((exitCode) => {
2098
+ process.exitCode = exitCode;
2099
+ });
2100
+ }
2101
+ //# sourceMappingURL=cli.js.map