@agentunion/fastaun 0.5.17 → 0.5.19

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 (95) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/_packed_docs/CHANGELOG.md +83 -0
  3. package/_packed_docs/INDEX.md +163 -16
  4. package/_packed_docs/KITE_DOCS_GUIDE.md +52 -20
  5. package/_packed_docs/agent.md/SCHEMA.md +266 -207
  6. package/_packed_docs/aun/345/210/206/345/270/203/345/274/217/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +64 -31
  7. package/_packed_docs/aun/346/265/213/350/257/225/350/277/220/350/241/214/346/214/207/345/215/227.md +8 -6
  8. package/_packed_docs/protocol/01-/350/272/253/344/273/275/344/270/216/345/207/255/350/257/201/345/215/217/350/256/256-auth.md +39 -39
  9. package/_packed_docs/protocol/07-/351/224/231/350/257/257/347/240/201/344/270/216/347/212/266/346/200/201/346/234/272.md +1 -1
  10. package/_packed_docs/protocol/10-Group-/345/255/220/345/215/217/350/256/256.md +28 -9
  11. package/_packed_docs/protocol/11-Storage-/345/255/220/345/215/217/350/256/256.md +20 -2
  12. package/_packed_docs/protocol/agent.md/SCHEMA.md +4 -0
  13. package/_packed_docs/sdk/04-/350/277/236/346/216/245/344/270/216/350/256/244/350/257/201.md +5 -2
  14. package/_packed_docs/sdk/06-API/346/211/213/345/206/214.md +246 -241
  15. package/_packed_docs/sdk/09-group-rpc-manual.md +46 -14
  16. package/_packed_docs/sdk/09-message-rpc-manual.md +40 -2
  17. package/_packed_docs/sdk/09-storage-rpc-manual.md +69 -38
  18. package/_packed_docs/sdk/AUN_DOCS_GUIDE.md +25 -5
  19. package/_packed_docs/sdk/INDEX.md +78 -18
  20. package/dist/agent-md-schema.d.ts +2 -0
  21. package/dist/agent-md-schema.js +46 -9
  22. package/dist/agent-md-schema.js.map +1 -1
  23. package/dist/agent-md.d.ts +46 -1
  24. package/dist/agent-md.js +492 -30
  25. package/dist/agent-md.js.map +1 -1
  26. package/dist/aid-store.d.ts +9 -1
  27. package/dist/aid-store.js +139 -18
  28. package/dist/aid-store.js.map +1 -1
  29. package/dist/aid.d.ts +17 -1
  30. package/dist/aid.js +67 -7
  31. package/dist/aid.js.map +1 -1
  32. package/dist/auth.d.ts +6 -1
  33. package/dist/auth.js +428 -15
  34. package/dist/auth.js.map +1 -1
  35. package/dist/cert-utils.d.ts +1 -1
  36. package/dist/cert-utils.js +19 -7
  37. package/dist/cert-utils.js.map +1 -1
  38. package/dist/client/delivery.d.ts +4 -1
  39. package/dist/client/delivery.js +264 -68
  40. package/dist/client/delivery.js.map +1 -1
  41. package/dist/client/rpc-pipeline.js +29 -14
  42. package/dist/client/rpc-pipeline.js.map +1 -1
  43. package/dist/client/v2-e2ee.d.ts +8 -1
  44. package/dist/client/v2-e2ee.js +893 -529
  45. package/dist/client/v2-e2ee.js.map +1 -1
  46. package/dist/client.d.ts +87 -1
  47. package/dist/client.js +816 -35
  48. package/dist/client.js.map +1 -1
  49. package/dist/errors.js +4 -3
  50. package/dist/errors.js.map +1 -1
  51. package/dist/events.d.ts +5 -1
  52. package/dist/events.js +47 -6
  53. package/dist/events.js.map +1 -1
  54. package/dist/facades.d.ts +85 -3
  55. package/dist/facades.js +104 -4
  56. package/dist/facades.js.map +1 -1
  57. package/dist/index.d.ts +9 -4
  58. package/dist/index.js +3 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/keystore/aid-db.d.ts +5 -0
  61. package/dist/keystore/aid-db.js +48 -0
  62. package/dist/keystore/aid-db.js.map +1 -1
  63. package/dist/keystore/index.d.ts +8 -0
  64. package/dist/keystore/local-identity-store.js +10 -3
  65. package/dist/keystore/local-identity-store.js.map +1 -1
  66. package/dist/keystore/local-token-store.d.ts +6 -1
  67. package/dist/keystore/local-token-store.js +24 -1
  68. package/dist/keystore/local-token-store.js.map +1 -1
  69. package/dist/org-protocol.d.ts +98 -0
  70. package/dist/org-protocol.js +1689 -0
  71. package/dist/org-protocol.js.map +1 -0
  72. package/dist/ownership-proof.d.ts +117 -0
  73. package/dist/ownership-proof.js +436 -0
  74. package/dist/ownership-proof.js.map +1 -0
  75. package/dist/ownership-v21.d.ts +178 -0
  76. package/dist/ownership-v21.js +635 -0
  77. package/dist/ownership-v21.js.map +1 -0
  78. package/dist/ownership-workflow.d.ts +82 -0
  79. package/dist/ownership-workflow.js +872 -0
  80. package/dist/ownership-workflow.js.map +1 -0
  81. package/dist/seq-tracker.d.ts +1 -0
  82. package/dist/seq-tracker.js +10 -1
  83. package/dist/seq-tracker.js.map +1 -1
  84. package/dist/tools/cross-sdk-agent.d.ts +89 -1
  85. package/dist/tools/cross-sdk-agent.js +338 -7
  86. package/dist/tools/cross-sdk-agent.js.map +1 -1
  87. package/dist/transport.d.ts +7 -0
  88. package/dist/transport.js +108 -4
  89. package/dist/transport.js.map +1 -1
  90. package/dist/v2/e2ee/decrypt.d.ts +1 -0
  91. package/dist/v2/e2ee/decrypt.js +9 -1
  92. package/dist/v2/e2ee/decrypt.js.map +1 -1
  93. package/dist/version.d.ts +1 -1
  94. package/dist/version.js +1 -1
  95. package/package.json +8 -8
@@ -3,11 +3,15 @@ import * as http from 'node:http';
3
3
  import * as https from 'node:https';
4
4
  import * as crypto from 'node:crypto';
5
5
  import * as fs from 'node:fs';
6
+ import * as path from 'node:path';
6
7
  import { URL } from 'node:url';
8
+ import { fileURLToPath } from 'node:url';
7
9
  import { AUNClient } from '../client.js';
8
10
  import { AIDStore } from '../aid-store.js';
9
11
  import { publicKeyFingerprint } from '../cert-utils.js';
10
12
  import { VERSION } from '../version.js';
13
+ import { canonicalJson, digest, buildRequestBinding, verifyMembershipBinding, ProtocolError } from '../org-protocol.js';
14
+ import { ownershipTaskResult } from '../ownership-workflow.js';
11
15
  function envBool(name, fallback = false) {
12
16
  const raw = process.env[name];
13
17
  if (raw == null)
@@ -105,7 +109,7 @@ function sendJson(res, status, data) {
105
109
  });
106
110
  res.end(body);
107
111
  }
108
- class CrossSdkTsAgent {
112
+ export class CrossSdkTsAgent {
109
113
  language = 'ts';
110
114
  sdkVersion = VERSION;
111
115
  aid = textOf(process.env.AUN_TEST_AID || 'cross-ts.agentid.pub').trim();
@@ -125,6 +129,8 @@ class CrossSdkTsAgent {
125
129
  rpcObservedTransports = new WeakSet();
126
130
  groupChangedEvents = [];
127
131
  groupInviteEvents = [];
132
+ readStateEvents = [];
133
+ ownershipEvents = [];
128
134
  traces = new Map();
129
135
  sendResults = new Map();
130
136
  inlineRealtimePayloadV1 = true;
@@ -166,6 +172,21 @@ class CrossSdkTsAgent {
166
172
  });
167
173
  this.client.on('group.changed', (data) => this.storeGroupChangedPublicEvent(data));
168
174
  this.client.on('group.invite_received', (data) => this.storeGroupInviteEvent(data));
175
+ for (const event of ['message.read_changed', 'group.read_changed', 'read_state_sync']) {
176
+ this.client.on(event, (payload) => { this.readStateEvents.push({ event, payload: jsonSafe(payload) }); });
177
+ }
178
+ for (const event of ['ownership.request', 'ownership.pending', 'ownership.progress', 'ownership.completed', 'ownership.rejected', 'ownership.stopped', 'ownership.error', 'ownership.action_required']) {
179
+ this.client.on(event, (payload) => {
180
+ this.ownershipEvents.push({ event, payload: jsonSafe(payload) });
181
+ });
182
+ }
183
+ for (const suffix of ['join_requested', 'join_approved', 'join_rejected', 'invite_created', 'invite_accepted', 'invite_rejected']) {
184
+ const event = 'org.member.' + suffix;
185
+ this.client.on(event, (value) => {
186
+ const payload = value;
187
+ this.recordTrace(textOf(payload.org_id), { stage: event, payload });
188
+ });
189
+ }
169
190
  }
170
191
  installTransportRpcObserver() {
171
192
  const transport = this.client._transport;
@@ -292,7 +313,14 @@ class CrossSdkTsAgent {
292
313
  debug: this.debug,
293
314
  });
294
315
  try {
295
- const registered = await store.register(this.aid);
316
+ const fixedIdentityFile = textOf(process.env.AUN_TEST_FIXED_IDENTITY_FILE).trim();
317
+ if (fixedIdentityFile) {
318
+ const identity = JSON.parse(fs.readFileSync(fixedIdentityFile, 'utf-8'));
319
+ if (identity.aid !== this.aid)
320
+ throw new Error('固定测试身份与配置 AID 不一致');
321
+ store._keystore.saveIdentity(this.aid, identity);
322
+ }
323
+ const registered = fixedIdentityFile ? store.load(this.aid) : await store.register(this.aid, { type: 'service' });
296
324
  if (!registered.ok) {
297
325
  const loaded = store.load(this.aid);
298
326
  if (!loaded.ok) {
@@ -301,6 +329,8 @@ class CrossSdkTsAgent {
301
329
  }
302
330
  }
303
331
  catch (err) {
332
+ if (textOf(process.env.AUN_TEST_FIXED_IDENTITY_FILE).trim())
333
+ throw err;
304
334
  const localIdentity = internal._auth?.loadIdentityOrNone?.(this.aid);
305
335
  if (!localIdentity) {
306
336
  throw new Error(`registerAid failed and no local identity exists: ${err instanceof Error ? err.message : String(err)}`);
@@ -310,11 +340,15 @@ class CrossSdkTsAgent {
310
340
  if (!loaded.ok) {
311
341
  throw new Error(`load identity failed: ${loaded.error.code}: ${loaded.error.message}`);
312
342
  }
313
- const uploaded = await store.uploadAgentMd(this.aid, this.agentMdContent(this.aid, this.aid, 'agent', 'Cross-SDK TypeScript test agent'));
314
- if (!uploaded.ok) {
315
- throw new Error(`upload agent.md failed: ${uploaded.error.code}: ${uploaded.error.message}`);
316
- }
317
343
  this.client.loadIdentity(loaded.data.aid);
344
+ const checked = await store.checkAgentMd(this.aid);
345
+ const localEtag = checked.ok ? String(checked.data.local_etag ?? '').trim() : '';
346
+ const remoteEtag = checked.ok ? String(checked.data.remote_etag ?? '').trim() : '';
347
+ const inSync = Boolean(localEtag && remoteEtag && localEtag === remoteEtag);
348
+ const remoteFound = checked.ok && checked.data.remote_found === true;
349
+ if (!inSync && !remoteFound) {
350
+ await this.client._ensureInitialAgentMd();
351
+ }
318
352
  this.installTransportRpcObserver();
319
353
  await this.client.connect({ auto_reconnect: false, background_sync: backgroundSync });
320
354
  }
@@ -330,6 +364,96 @@ class CrossSdkTsAgent {
330
364
  public_key_fingerprint: cert ? publicKeyFingerprint(cert) : '',
331
365
  };
332
366
  }
367
+ async ownershipBind(req, res) {
368
+ const body = await readJson(req);
369
+ const role = textOf(body.role).trim().toLowerCase();
370
+ const peerAid = textOf(body.peer_aid).trim();
371
+ if (!['owner', 'subject'].includes(role) || !peerAid) {
372
+ sendJson(res, 400, { ok: false, error_code: 'bad_request', error_message: 'role and peer_aid are required' });
373
+ return;
374
+ }
375
+ try {
376
+ const task = role === 'owner' ? await this.client.bindSubaid(peerAid) : await this.client.bindOwneraid(peerAid);
377
+ sendJson(res, 200, { ok: true, operation_id: task.operation_id, task: jsonSafe(task) });
378
+ }
379
+ catch (err) {
380
+ sendJson(res, 500, {
381
+ ok: false,
382
+ error_code: textOf(err?.stringCode ?? err?.code ?? (err instanceof Error ? err.name : 'Error')),
383
+ error_message: err instanceof Error ? err.message : String(err),
384
+ });
385
+ }
386
+ }
387
+ async ownershipAction(req, res, action) {
388
+ const body = await readJson(req);
389
+ const operationId = textOf(body.operation_id).trim(), subAid = textOf(body.sub_aid).trim(), newOwnerAid = textOf(body.new_owner_aid).trim();
390
+ if ((action === 'accept' || action === 'reject') ? !operationId : !subAid || action === 'transfer' && !newOwnerAid) {
391
+ sendJson(res, 400, { ok: false, error_code: 'bad_request', error_message: action === 'accept' || action === 'reject' ? 'operation_id is required' : 'sub_aid and transfer new_owner_aid are required' });
392
+ return;
393
+ }
394
+ try {
395
+ const task = action === 'accept' ? await this.client.acceptOwnershipRequest(operationId)
396
+ : action === 'reject' ? await this.client.rejectOwnershipRequest(operationId, body.reason)
397
+ : action === 'release' ? await this.client.releaseSubaid(subAid)
398
+ : await this.client.transferSubaid(subAid, newOwnerAid);
399
+ sendJson(res, 200, { ok: true, operation_id: task.operation_id, task: jsonSafe(task) });
400
+ }
401
+ catch (err) {
402
+ sendJson(res, 500, {
403
+ ok: false,
404
+ error_code: textOf(err?.stringCode ?? err?.code ?? (err instanceof Error ? err.name : 'Error')),
405
+ error_message: err instanceof Error ? err.message : String(err),
406
+ });
407
+ }
408
+ }
409
+ ownershipPublicTask(record) {
410
+ const decision = record.local_decision;
411
+ if (!['pending', 'accept', 'reject'].includes(String(decision)) || typeof record.initiator_aid !== 'string' || !record.initiator_aid)
412
+ throw new Error('persisted ownership approval context is unavailable');
413
+ return { ...ownershipTaskResult(record), initiator_aid: record.initiator_aid, local_approval: decision === 'accept' ? 'accepted' : decision === 'reject' ? 'rejected' : 'pending' };
414
+ }
415
+ async ownershipStatus(url, res) {
416
+ const internal = this.client;
417
+ if (!internal._tokenStore.listOwnershipTasks)
418
+ throw new Error('ownership task store is unavailable');
419
+ const operationId = textOf(url.searchParams.get('operation_id')).trim(), selectedSub = textOf(url.searchParams.get('sub_aid')).trim();
420
+ const records = internal._tokenStore.listOwnershipTasks(this.aid).map((item) => item.task).filter((record) => (!operationId || record.operation_id === operationId) && (!selectedSub || record.sub_aid === selectedSub));
421
+ const tasks = records.map((record) => this.ownershipPublicTask(record)), task = tasks[tasks.length - 1] ?? null;
422
+ const subAid = textOf(task?.sub_aid ?? selectedSub).trim() || this.aid;
423
+ const consensus = await this.client.checkOwnershipConsensus(subAid);
424
+ const files = { agent_md: null, owner_md: null, storage_agent_md: null }, fileErrors = {};
425
+ let nsProtocol = null;
426
+ try {
427
+ const current = await internal._getOwnershipFiles().readAgent(subAid);
428
+ nsProtocol = current.protocol;
429
+ if (!current.exists)
430
+ fileErrors.agent_md = 'not_found';
431
+ else
432
+ files.agent_md = { raw_base64: Buffer.from(current.content, 'utf8').toString('base64'), sha256: crypto.createHash('sha256').update(current.content, 'utf8').digest('hex'), etag: current.etag };
433
+ }
434
+ catch (err) {
435
+ fileErrors.agent_md = err instanceof Error ? err.message : String(err);
436
+ }
437
+ const ownerAid = textOf(task?.operation === 'release' ? task.owner_aid : consensus.owner_aid ?? task?.new_owner_aid ?? task?.owner_aid).trim();
438
+ const readStorageFile = async (name, read) => {
439
+ try {
440
+ const current = await read();
441
+ if (!current.exists)
442
+ fileErrors[name] = 'not_found';
443
+ else
444
+ files[name] = { raw_base64: Buffer.from(current.content, 'utf8').toString('base64'), sha256: crypto.createHash('sha256').update(current.content, 'utf8').digest('hex'), revision: current.revision };
445
+ }
446
+ catch (err) {
447
+ fileErrors[name] = err instanceof Error ? err.message : String(err);
448
+ }
449
+ };
450
+ await Promise.all([
451
+ ownerAid ? readStorageFile('owner_md', () => internal._getOwnershipFiles().readOwner(ownerAid, subAid)) : Promise.resolve().then(() => { fileErrors.owner_md = 'owner_aid is unavailable'; }),
452
+ readStorageFile('storage_agent_md', () => internal._getOwnershipStorage().readObject(subAid, 'agent.md')),
453
+ ]);
454
+ const events = this.ownershipEvents.filter((item) => (!operationId || item.payload?.operation_id === operationId) && (!selectedSub || item.payload?.sub_aid === selectedSub));
455
+ sendJson(res, 200, { ok: true, task, tasks, events, consensus: consensus, files, file_errors: fileErrors, ns_protocol: nsProtocol });
456
+ }
333
457
  recordTrace(traceId, item) {
334
458
  if (!traceId)
335
459
  return;
@@ -439,6 +563,7 @@ class CrossSdkTsAgent {
439
563
  this.rawPushRpcMethods = [];
440
564
  this.groupChangedEvents = [];
441
565
  this.groupInviteEvents = [];
566
+ this.readStateEvents = [];
442
567
  this.rawPushObservationId = textOf(body.observation_id ?? '');
443
568
  sendJson(res, 200, { ok: true, observation_id: this.rawPushObservationId });
444
569
  return;
@@ -477,6 +602,7 @@ class CrossSdkTsAgent {
477
602
  rpc_calls: rpcEntries,
478
603
  group_changed_events: groupChangedEvents.slice(-limit),
479
604
  group_invite_events: groupInviteEvents.slice(-limit),
605
+ read_state_events: this.readStateEvents.slice(-limit),
480
606
  });
481
607
  return;
482
608
  }
@@ -484,6 +610,34 @@ class CrossSdkTsAgent {
484
610
  sendJson(res, 200, this.identity());
485
611
  return;
486
612
  }
613
+ if (req.method === 'POST' && url.pathname === '/ownership/bind') {
614
+ await this.ownershipBind(req, res);
615
+ return;
616
+ }
617
+ if (req.method === 'POST' && url.pathname === '/ownership/accept') {
618
+ await this.ownershipAction(req, res, 'accept');
619
+ return;
620
+ }
621
+ if (req.method === 'POST' && url.pathname === '/ownership/reject') {
622
+ await this.ownershipAction(req, res, 'reject');
623
+ return;
624
+ }
625
+ if (req.method === 'POST' && url.pathname === '/ownership/release') {
626
+ await this.ownershipAction(req, res, 'release');
627
+ return;
628
+ }
629
+ if (req.method === 'POST' && url.pathname === '/ownership/transfer') {
630
+ await this.ownershipAction(req, res, 'transfer');
631
+ return;
632
+ }
633
+ if (req.method === 'GET' && url.pathname === '/ownership/status') {
634
+ await this.ownershipStatus(url, res);
635
+ return;
636
+ }
637
+ if (req.method === 'GET' && url.pathname === '/ownership/events') {
638
+ sendJson(res, 200, { ok: true, events: this.ownershipEvents });
639
+ return;
640
+ }
487
641
  if (req.method === 'POST' && url.pathname === '/send') {
488
642
  await this.send(req, res);
489
643
  return;
@@ -496,6 +650,10 @@ class CrossSdkTsAgent {
496
650
  await this.pull(req, res);
497
651
  return;
498
652
  }
653
+ if (req.method === 'POST' && url.pathname === '/message/call') {
654
+ await this.messageCall(req, res);
655
+ return;
656
+ }
499
657
  if (req.method === 'GET' && url.pathname === '/sync/state') {
500
658
  this.syncState(url, res);
501
659
  return;
@@ -721,6 +879,39 @@ class CrossSdkTsAgent {
721
879
  });
722
880
  }
723
881
  }
882
+ async messageCall(req, res) {
883
+ const body = await readJson(req);
884
+ const traceId = textOf(body.trace_id || crypto.randomUUID().replace(/-/g, ''));
885
+ const method = textOf(body.method).trim();
886
+ const params = jsonObjectOf(body.params) ?? {};
887
+ if (!method) {
888
+ sendJson(res, 400, { ok: false, trace_id: traceId, error_code: 'bad_request', error_message: 'method is required' });
889
+ return;
890
+ }
891
+ try {
892
+ let result;
893
+ if (method === 'message.read')
894
+ result = await this.client.message.read(params);
895
+ else if (method === 'message.read_state')
896
+ result = await this.client.message.readState(params);
897
+ else
898
+ result = await this.client.call(method, params);
899
+ const response = { ok: true, trace_id: traceId, method, result: jsonSafe(result) };
900
+ this.recordTrace(traceId, { stage: 'message_call', method, result: response });
901
+ sendJson(res, 200, response);
902
+ }
903
+ catch (err) {
904
+ const error = {
905
+ ok: false,
906
+ trace_id: traceId,
907
+ method,
908
+ error_code: err instanceof Error ? err.name : 'Error',
909
+ error_message: err instanceof Error ? err.message : String(err),
910
+ };
911
+ this.recordTrace(traceId, { stage: 'message_call_error', method, error });
912
+ sendJson(res, 500, error);
913
+ }
914
+ }
724
915
  syncNamespace(scope, groupId = '') {
725
916
  if (scope === 'p2p')
726
917
  return `p2p:${this.aid}`;
@@ -940,6 +1131,76 @@ class CrossSdkTsAgent {
940
1131
  store.close();
941
1132
  }
942
1133
  }
1134
+ async orgProtocol(params) {
1135
+ const op = textOf(params.op);
1136
+ const now = Math.floor(Date.now() / 1000);
1137
+ if (op === 'request')
1138
+ return buildRequestBinding(textOf(params.method), textOf(params.target), params.params, textOf(params.credential_cid), textOf(params.nonce), textOf(params.request_id), now, now + 300);
1139
+ if (['register', 'sign', 'certificate', 'create'].includes(op)) {
1140
+ const store = this.aidStore();
1141
+ try {
1142
+ if (op === 'register') {
1143
+ const registered = await store.register(textOf(params.org_id), { type: 'org', owner: this.aid, exttype: 'company' });
1144
+ if (!registered.ok)
1145
+ throw new Error(String(registered.error));
1146
+ }
1147
+ const loaded = op === 'certificate'
1148
+ ? await store.resolve(textOf(params.as_aid), { skipAgentMd: true })
1149
+ : (params.as_aid || params.org_id) ? store.load(textOf(params.as_aid ?? params.org_id)) : null;
1150
+ if (loaded && !loaded.ok)
1151
+ throw new Error(String(loaded.error));
1152
+ const identity = loaded?.data?.aid ?? this.client.currentAid;
1153
+ const result = { cert_fingerprint: identity.certFingerprint, certificate: identity.certPem };
1154
+ if (op === 'sign') {
1155
+ const signed = await identity.sign(Buffer.from(canonicalJson(params.payload)));
1156
+ if (!signed.ok)
1157
+ throw new Error(String(signed.error));
1158
+ result.signature = { cert_fingerprint: identity.certFingerprint, timestamp: now, signature: signed.data.signature };
1159
+ }
1160
+ else if (op === 'create') {
1161
+ result.credential = params.membership_binding
1162
+ ? this.client.org.member.createCredential(params.membership_binding, identity, params.options)
1163
+ : this.client.credential.create(params.options, identity);
1164
+ }
1165
+ return result;
1166
+ }
1167
+ finally {
1168
+ store.close();
1169
+ }
1170
+ }
1171
+ const value = params.document ?? params.payload;
1172
+ const result = { canonical: new TextDecoder().decode(canonicalJson(value)), digest: digest(value), error_code: '' };
1173
+ if (op === 'verify' || op === 'verify_full') {
1174
+ const certificates = params.certificates;
1175
+ const resolver = (fingerprint) => certificates[fingerprint];
1176
+ try {
1177
+ if (op === 'verify_full') {
1178
+ const actual = jsonObjectOf(params.context) ?? params;
1179
+ const memberships = jsonObjectOf(params.memberships) ?? {};
1180
+ result.verification = { ...this.client.credential.verify(value, { resolveCertificate: resolver, resolveActorCertificate: resolver,
1181
+ resolveStatus: (cid) => params.statuses?.[cid], now, audience: textOf(actual.audience), subject: textOf(actual.subject) || undefined,
1182
+ ns: textOf(actual.ns), action: textOf(actual.action), resource: textOf(actual.resource), rootIssuer: textOf(actual.root_issuer) || undefined,
1183
+ params: jsonObjectOf(actual.params) ?? {}, units: jsonObjectOf(actual.units) ?? {}, clientIp: textOf(actual.client_ip), method: textOf(actual.method), target: textOf(actual.target),
1184
+ requestId: textOf(actual.request_id), nonce: textOf(actual.nonce), requestBinding: actual.request_binding, proofChain: actual.proof_chain, membershipBinding: actual.membership_binding,
1185
+ orgSigner: textOf(actual.org_signer) || undefined, actor: textOf(actual.actor) || undefined, for: textOf(actual.for) || undefined, representationProof: actual.representation_proof,
1186
+ resolveMembershipStatus: (binding, credential) => { const current = jsonObjectOf(memberships[String(binding.membership_id)]); return current?.status === 'active' && current.credential_cid === credential.cid; },
1187
+ resolveOwnership: (subject, owner) => (jsonObjectOf(params.ownerships) ?? {})[subject] === owner, checkRateLimit: () => params.rate_limit_allowed === true }) };
1188
+ }
1189
+ else if (params.kind === 'credential')
1190
+ result.verification = { ...this.client.credential.verifySignature(value, resolver, now, textOf(params.audience)) };
1191
+ else if (params.kind === 'binding')
1192
+ await verifyMembershipBinding(value, resolver, now, textOf(params.expected_org_signer));
1193
+ else
1194
+ result.verification = { ...this.client.credential.verifyRegistrationReceipt(value, params.credential, params.request, resolver, textOf(params.service_aid), now) };
1195
+ }
1196
+ catch (error) {
1197
+ if (!(error instanceof ProtocolError))
1198
+ throw error;
1199
+ result.error_code = error.code;
1200
+ }
1201
+ }
1202
+ return result;
1203
+ }
943
1204
  async groupCall(req, res) {
944
1205
  const body = await readJson(req);
945
1206
  const traceId = textOf(body.trace_id || crypto.randomUUID().replace(/-/g, ''));
@@ -955,6 +1216,48 @@ class CrossSdkTsAgent {
955
1216
  try {
956
1217
  let result;
957
1218
  switch (method) {
1219
+ case 'sdk.org.protocol':
1220
+ result = await this.orgProtocol(params);
1221
+ break;
1222
+ case 'org.lifecycle.create':
1223
+ result = await this.client.org.lifecycle.create(params);
1224
+ break;
1225
+ case 'org.lifecycle.dissolve':
1226
+ result = await this.client.org.lifecycle.dissolve(params);
1227
+ break;
1228
+ case 'org.lifecycle.transfer':
1229
+ result = await this.client.org.lifecycle.transfer(params);
1230
+ break;
1231
+ case 'org.lifecycle.transferAccept':
1232
+ result = await this.client.org.lifecycle.transferAccept(params);
1233
+ break;
1234
+ case 'org.member.join':
1235
+ result = await this.client.org.member.join(params);
1236
+ break;
1237
+ case 'org.member.approveJoin':
1238
+ result = await this.client.org.member.approveJoin(params);
1239
+ break;
1240
+ case 'org.member.rejectJoin':
1241
+ result = await this.client.org.member.rejectJoin(params);
1242
+ break;
1243
+ case 'org.member.invite':
1244
+ result = await this.client.org.member.invite(params);
1245
+ break;
1246
+ case 'org.member.inviteAccept':
1247
+ result = await this.client.org.member.inviteAccept(params);
1248
+ break;
1249
+ case 'org.member.inviteReject':
1250
+ result = await this.client.org.member.inviteReject(params);
1251
+ break;
1252
+ case 'org.member.leave':
1253
+ result = await this.client.org.member.leave(params);
1254
+ break;
1255
+ case 'org.member.offboard':
1256
+ result = await this.client.org.member.offboard(params);
1257
+ break;
1258
+ case 'org.credential.getStatus':
1259
+ result = await this.client.org.credential.getStatus(params);
1260
+ break;
958
1261
  case 'sdk.update_group_index':
959
1262
  result = await this.client.group.updateGroupIndex(params);
960
1263
  break;
@@ -988,6 +1291,12 @@ class CrossSdkTsAgent {
988
1291
  case 'group.get_member_statuses':
989
1292
  result = await this.client.group.getMemberStatuses(params);
990
1293
  break;
1294
+ case 'group.read':
1295
+ result = await this.client.group.read(params);
1296
+ break;
1297
+ case 'group.read_state':
1298
+ result = await this.client.group.readState(params);
1299
+ break;
991
1300
  default: result = await this.client.call(method, params);
992
1301
  }
993
1302
  const response = { ok: true, trace_id: traceId, method, result: jsonSafe(result) };
@@ -1750,6 +2059,27 @@ class CrossSdkTsAgent {
1750
2059
  '',
1751
2060
  ].join('\n');
1752
2061
  }
2062
+ agentMdContentForUpload(aid, name, type, description) {
2063
+ let content = '';
2064
+ try {
2065
+ const manager = this.client._agentMdManager;
2066
+ const managed = manager?.readContent?.(aid);
2067
+ content = typeof managed === 'string' ? managed : '';
2068
+ }
2069
+ catch {
2070
+ content = '';
2071
+ }
2072
+ if (content && (content.includes('owner:') || content.includes('ownership_proof:') || content.includes('ownership_release:')))
2073
+ return content;
2074
+ try {
2075
+ content = fs.readFileSync(path.join(this.aunPath, 'AIDs', aid, 'agent.md'), 'utf-8');
2076
+ if (content.includes('owner:') || content.includes('ownership_proof:') || content.includes('ownership_release:'))
2077
+ return content;
2078
+ }
2079
+ catch {
2080
+ }
2081
+ return this.agentMdContent(aid, name, type, description);
2082
+ }
1753
2083
  aidStore() {
1754
2084
  return new AIDStore({
1755
2085
  aunPath: this.aunPath,
@@ -1834,5 +2164,6 @@ async function main() {
1834
2164
  process.on('SIGINT', () => { void shutdown(); });
1835
2165
  process.on('SIGTERM', () => { void shutdown(); });
1836
2166
  }
1837
- void main();
2167
+ if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url))
2168
+ void main();
1838
2169
  //# sourceMappingURL=cross-sdk-agent.js.map