@multi-agent-protocol/sdk 0.0.5 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,9 +1,89 @@
1
1
  'use strict';
2
2
 
3
+ var agenticMesh = require('agentic-mesh');
3
4
  var ulid = require('ulid');
4
5
  var events = require('events');
5
6
  var zod = require('zod');
6
7
 
8
+ var __defProp = Object.defineProperty;
9
+ var __getOwnPropNames = Object.getOwnPropertyNames;
10
+ var __esm = (fn, res) => function __init() {
11
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
+ };
13
+ var __export = (target, all) => {
14
+ for (var name in all)
15
+ __defProp(target, name, { get: all[name], enumerable: true });
16
+ };
17
+
18
+ // src/stream/agentic-mesh.ts
19
+ var agentic_mesh_exports = {};
20
+ __export(agentic_mesh_exports, {
21
+ agenticMeshStream: () => agenticMeshStream
22
+ });
23
+ async function agenticMeshStream(config) {
24
+ if (!config.transport.active) {
25
+ await config.transport.start();
26
+ }
27
+ const connected = await config.transport.connect(config.peer);
28
+ if (!connected) {
29
+ throw new Error(`Failed to connect to peer: ${config.peer.peerId}`);
30
+ }
31
+ const streamId = `map-${config.localPeerId}-${Date.now()}`;
32
+ const tunnelStream = new agenticMesh.TunnelStream({
33
+ transport: config.transport,
34
+ peerId: config.peer.peerId,
35
+ streamId
36
+ });
37
+ await tunnelStream.open();
38
+ return tunnelStreamToMapStream(tunnelStream);
39
+ }
40
+ function tunnelStreamToMapStream(tunnel) {
41
+ let readingAborted = false;
42
+ const readable = new ReadableStream({
43
+ async start(controller) {
44
+ try {
45
+ for await (const frame of tunnel) {
46
+ if (readingAborted) break;
47
+ controller.enqueue(frame);
48
+ }
49
+ if (!readingAborted) {
50
+ controller.close();
51
+ }
52
+ } catch (error) {
53
+ if (!readingAborted) {
54
+ controller.error(error);
55
+ }
56
+ }
57
+ },
58
+ cancel() {
59
+ readingAborted = true;
60
+ tunnel.close().catch(() => {
61
+ });
62
+ }
63
+ });
64
+ const writable = new WritableStream({
65
+ async write(message) {
66
+ if (!tunnel.isOpen) {
67
+ throw new Error("Stream is not open");
68
+ }
69
+ await tunnel.write(message);
70
+ },
71
+ async close() {
72
+ await tunnel.close();
73
+ },
74
+ abort() {
75
+ readingAborted = true;
76
+ tunnel.close().catch(() => {
77
+ });
78
+ }
79
+ });
80
+ return { readable, writable };
81
+ }
82
+ var init_agentic_mesh = __esm({
83
+ "src/stream/agentic-mesh.ts"() {
84
+ }
85
+ });
86
+
7
87
  // src/types/index.ts
8
88
  function isOrphanedAgent(agent) {
9
89
  return agent.ownerId === null;
@@ -89,6 +169,7 @@ var SESSION_METHODS = {
89
169
  SESSION_CLOSE: "map/session/close"
90
170
  };
91
171
  var AUTH_METHODS = {
172
+ AUTHENTICATE: "map/authenticate",
92
173
  AUTH_REFRESH: "map/auth/refresh"
93
174
  };
94
175
  var PERMISSION_METHODS = {
@@ -102,7 +183,9 @@ var NOTIFICATION_METHODS = {
102
183
  EVENT: "map/event",
103
184
  MESSAGE: "map/message",
104
185
  /** Client acknowledges received events (for backpressure) */
105
- SUBSCRIBE_ACK: "map/subscribe.ack"
186
+ SUBSCRIBE_ACK: "map/subscribe.ack",
187
+ /** Server notifies client that auth is about to expire */
188
+ AUTH_EXPIRING: "map/auth/expiring"
106
189
  };
107
190
  var MAP_METHODS = {
108
191
  ...CORE_METHODS,
@@ -137,7 +220,10 @@ var AUTH_ERROR_CODES = {
137
220
  AUTH_REQUIRED: 1e3,
138
221
  AUTH_FAILED: 1001,
139
222
  TOKEN_EXPIRED: 1002,
140
- PERMISSION_DENIED: 1003
223
+ PERMISSION_DENIED: 1003,
224
+ INSUFFICIENT_SCOPE: 1004,
225
+ METHOD_NOT_SUPPORTED: 1005,
226
+ INVALID_CREDENTIALS: 1006
141
227
  };
142
228
  var ROUTING_ERROR_CODES = {
143
229
  ADDRESS_NOT_FOUND: 2e3,
@@ -211,7 +297,8 @@ var CAPABILITY_REQUIREMENTS = {
211
297
  [SESSION_METHODS.SESSION_LIST]: [],
212
298
  [SESSION_METHODS.SESSION_LOAD]: [],
213
299
  [SESSION_METHODS.SESSION_CLOSE]: [],
214
- // Auth
300
+ // Auth (no capability required - anyone can authenticate)
301
+ [AUTH_METHODS.AUTHENTICATE]: [],
215
302
  [AUTH_METHODS.AUTH_REFRESH]: [],
216
303
  // Permissions (system-only, no capability check - enforced by participant type)
217
304
  [PERMISSION_METHODS.PERMISSIONS_UPDATE]: [],
@@ -382,6 +469,27 @@ var MAPRequestError = class _MAPRequestError extends Error {
382
469
  { category: "auth" }
383
470
  );
384
471
  }
472
+ static insufficientScope(required) {
473
+ return new _MAPRequestError(
474
+ AUTH_ERROR_CODES.INSUFFICIENT_SCOPE,
475
+ required ? `Insufficient scope: ${required}` : "Insufficient scope",
476
+ { category: "auth" }
477
+ );
478
+ }
479
+ static methodNotSupported(method) {
480
+ return new _MAPRequestError(
481
+ AUTH_ERROR_CODES.METHOD_NOT_SUPPORTED,
482
+ `Authentication method not supported: ${method}`,
483
+ { category: "auth" }
484
+ );
485
+ }
486
+ static invalidCredentials(details) {
487
+ return new _MAPRequestError(
488
+ AUTH_ERROR_CODES.INVALID_CREDENTIALS,
489
+ details ?? "Invalid credentials",
490
+ { category: "auth" }
491
+ );
492
+ }
385
493
  // ==========================================================================
386
494
  // Routing Errors (2xxx)
387
495
  // ==========================================================================
@@ -563,6 +671,7 @@ var MAPTimeoutError = class extends Error {
563
671
  };
564
672
 
565
673
  // src/stream/index.ts
674
+ init_agentic_mesh();
566
675
  function ndJsonStream(readable, writable) {
567
676
  const encoder = new TextEncoder();
568
677
  const decoder = new TextDecoder();
@@ -2394,6 +2503,33 @@ var ACPStreamConnection = class extends events.EventEmitter {
2394
2503
  });
2395
2504
  }
2396
2505
  // ===========================================================================
2506
+ // Extension Methods
2507
+ // ===========================================================================
2508
+ /**
2509
+ * Call an ACP extension method on the target agent.
2510
+ *
2511
+ * Extension methods are prefixed with "_" (e.g., "_macro/spawnAgent").
2512
+ * The agent must support the extension for this to succeed.
2513
+ *
2514
+ * @param method - The extension method name (e.g., "_macro/spawnAgent")
2515
+ * @param params - Parameters to pass to the extension method
2516
+ * @returns The result from the extension method
2517
+ *
2518
+ * @example
2519
+ * ```typescript
2520
+ * const result = await acp.callExtension("_macro/spawnAgent", {
2521
+ * task: "Implement feature X",
2522
+ * cwd: "/project"
2523
+ * });
2524
+ * ```
2525
+ */
2526
+ async callExtension(method, params) {
2527
+ if (!this.#initialized) {
2528
+ throw new Error("Must call initialize() before callExtension()");
2529
+ }
2530
+ return this.#sendRequest(method, params);
2531
+ }
2532
+ // ===========================================================================
2397
2533
  // Lifecycle
2398
2534
  // ===========================================================================
2399
2535
  /**
@@ -2435,6 +2571,8 @@ var ClientConnection = class _ClientConnection {
2435
2571
  #connected = false;
2436
2572
  #lastConnectOptions;
2437
2573
  #isReconnecting = false;
2574
+ #lastResumeToken;
2575
+ #onTokenExpiring;
2438
2576
  constructor(stream, options = {}) {
2439
2577
  this.#connection = new BaseConnection(stream, options);
2440
2578
  this.#options = options;
@@ -2500,11 +2638,70 @@ var ClientConnection = class _ClientConnection {
2500
2638
  await client.connect({ auth: options?.auth });
2501
2639
  return client;
2502
2640
  }
2641
+ /**
2642
+ * Connect to a MAP server via agentic-mesh transport.
2643
+ *
2644
+ * Handles:
2645
+ * - Dynamic import of agentic-mesh (optional peer dependency)
2646
+ * - Stream creation over encrypted mesh tunnel
2647
+ * - Auto-configuration of createStream for reconnection
2648
+ * - Initial MAP protocol connect handshake
2649
+ *
2650
+ * Requires `agentic-mesh` to be installed as a peer dependency.
2651
+ *
2652
+ * @param options - Mesh connection options
2653
+ * @returns Connected ClientConnection instance
2654
+ *
2655
+ * @example
2656
+ * ```typescript
2657
+ * import { createNebulaTransport } from 'agentic-mesh';
2658
+ *
2659
+ * const transport = createNebulaTransport({
2660
+ * configPath: '/etc/nebula/config.yml',
2661
+ * });
2662
+ *
2663
+ * const client = await ClientConnection.connectMesh({
2664
+ * transport,
2665
+ * peer: { peerId: 'server', address: '10.0.0.1', port: 4242 },
2666
+ * localPeerId: 'my-client',
2667
+ * name: 'MeshClient',
2668
+ * reconnection: true
2669
+ * });
2670
+ *
2671
+ * const agents = await client.listAgents();
2672
+ * ```
2673
+ */
2674
+ static async connectMesh(options) {
2675
+ const { agenticMeshStream: agenticMeshStream2 } = await Promise.resolve().then(() => (init_agentic_mesh(), agentic_mesh_exports));
2676
+ const streamConfig = {
2677
+ transport: options.transport,
2678
+ peer: options.peer,
2679
+ localPeerId: options.localPeerId,
2680
+ timeout: options.timeout
2681
+ };
2682
+ const stream = await agenticMeshStream2(streamConfig);
2683
+ const createStream = async () => agenticMeshStream2(streamConfig);
2684
+ const reconnection = options.reconnection === true ? { enabled: true } : typeof options.reconnection === "object" ? options.reconnection : void 0;
2685
+ const client = new _ClientConnection(stream, {
2686
+ name: options.name,
2687
+ capabilities: options.capabilities,
2688
+ createStream,
2689
+ reconnection
2690
+ });
2691
+ await client.connect({ auth: options.auth });
2692
+ return client;
2693
+ }
2503
2694
  // ===========================================================================
2504
2695
  // Connection Lifecycle
2505
2696
  // ===========================================================================
2506
2697
  /**
2507
2698
  * Connect to the MAP system
2699
+ *
2700
+ * @param options - Connection options
2701
+ * @param options.sessionId - Specific session ID to use
2702
+ * @param options.resumeToken - Token to resume a previously disconnected session
2703
+ * @param options.auth - Authentication credentials
2704
+ * @param options.onTokenExpiring - Callback invoked before token expires for proactive refresh
2508
2705
  */
2509
2706
  async connect(options) {
2510
2707
  const params = {
@@ -2520,10 +2717,134 @@ var ClientConnection = class _ClientConnection {
2520
2717
  this.#sessionId = result.sessionId;
2521
2718
  this.#serverCapabilities = result.capabilities;
2522
2719
  this.#connected = true;
2720
+ if (result.resumeToken) {
2721
+ this.#lastResumeToken = result.resumeToken;
2722
+ }
2723
+ if (options?.onTokenExpiring) {
2724
+ this.#onTokenExpiring = options.onTokenExpiring;
2725
+ this.#setupTokenExpiryMonitoring(result);
2726
+ }
2523
2727
  this.#connection._transitionTo("connected");
2524
2728
  this.#lastConnectOptions = options;
2525
2729
  return result;
2526
2730
  }
2731
+ /**
2732
+ * Get the resume token for this session.
2733
+ * Can be used to reconnect and restore session state after disconnection.
2734
+ *
2735
+ * @returns The resume token, or undefined if not available
2736
+ */
2737
+ getResumeToken() {
2738
+ return this.#lastResumeToken;
2739
+ }
2740
+ /**
2741
+ * Reconnect to the server, optionally using a resume token to restore session.
2742
+ *
2743
+ * @param resumeToken - Token to resume previous session. If not provided, uses the last known token.
2744
+ * @returns Connect response result
2745
+ *
2746
+ * @example
2747
+ * ```typescript
2748
+ * // Save token before disconnect
2749
+ * const token = await client.disconnect();
2750
+ *
2751
+ * // Later, reconnect with the token
2752
+ * const result = await client.reconnect(token);
2753
+ * console.log('Reconnected:', result.reconnected);
2754
+ * ```
2755
+ */
2756
+ async reconnect(resumeToken) {
2757
+ const tokenToUse = resumeToken ?? this.#lastResumeToken;
2758
+ return this.connect({
2759
+ ...this.#lastConnectOptions,
2760
+ resumeToken: tokenToUse
2761
+ });
2762
+ }
2763
+ /**
2764
+ * Set up monitoring for token expiration
2765
+ */
2766
+ #setupTokenExpiryMonitoring(connectResult) {
2767
+ const principal = connectResult.principal;
2768
+ if (!principal?.expiresAt || !this.#onTokenExpiring) {
2769
+ return;
2770
+ }
2771
+ const expiresAt = principal.expiresAt;
2772
+ const now = Date.now();
2773
+ const warningTime = expiresAt - 6e4;
2774
+ const delay = warningTime - now;
2775
+ if (delay > 0) {
2776
+ setTimeout(async () => {
2777
+ if (!this.#connected || !this.#onTokenExpiring) return;
2778
+ try {
2779
+ const newCredentials = await this.#onTokenExpiring(expiresAt);
2780
+ if (newCredentials) {
2781
+ const refreshResult = await this.refreshAuth({
2782
+ method: newCredentials.method,
2783
+ credential: newCredentials.credential
2784
+ });
2785
+ if (refreshResult.success && refreshResult.principal?.expiresAt) {
2786
+ this.#setupTokenExpiryMonitoring({
2787
+ ...connectResult,
2788
+ principal: refreshResult.principal
2789
+ });
2790
+ }
2791
+ }
2792
+ } catch {
2793
+ }
2794
+ }, delay);
2795
+ }
2796
+ }
2797
+ /**
2798
+ * Authenticate with the server after connection.
2799
+ *
2800
+ * Use this when the server returns `authRequired` in the connect response,
2801
+ * indicating that authentication is needed before accessing protected resources.
2802
+ *
2803
+ * @param auth - Authentication credentials
2804
+ * @returns Authentication result with principal if successful
2805
+ *
2806
+ * @example
2807
+ * ```typescript
2808
+ * const connectResult = await client.connect();
2809
+ *
2810
+ * if (connectResult.authRequired) {
2811
+ * const authResult = await client.authenticate({
2812
+ * method: 'api-key',
2813
+ * credential: process.env.API_KEY,
2814
+ * });
2815
+ *
2816
+ * if (authResult.success) {
2817
+ * console.log('Authenticated as:', authResult.principal?.id);
2818
+ * }
2819
+ * }
2820
+ * ```
2821
+ */
2822
+ async authenticate(auth) {
2823
+ const params = {
2824
+ method: auth.method,
2825
+ credential: auth.credential
2826
+ };
2827
+ const result = await this.#connection.sendRequest(AUTH_METHODS.AUTHENTICATE, params);
2828
+ if (result.success && result.sessionId) {
2829
+ this.#sessionId = result.sessionId;
2830
+ }
2831
+ return result;
2832
+ }
2833
+ /**
2834
+ * Refresh authentication credentials.
2835
+ *
2836
+ * Use this to update credentials before they expire for long-lived connections.
2837
+ *
2838
+ * @param auth - New authentication credentials
2839
+ * @returns Updated principal information
2840
+ */
2841
+ async refreshAuth(auth) {
2842
+ const params = {
2843
+ method: auth.method,
2844
+ credential: auth.credential
2845
+ };
2846
+ return this.#connection.sendRequest(AUTH_METHODS.AUTH_REFRESH, params);
2847
+ }
2527
2848
  /**
2528
2849
  * Disconnect from the MAP system
2529
2850
  * @param reason - Optional reason for disconnecting
@@ -2538,6 +2859,9 @@ var ClientConnection = class _ClientConnection {
2538
2859
  reason ? { reason } : void 0
2539
2860
  );
2540
2861
  resumeToken = result.resumeToken;
2862
+ if (resumeToken) {
2863
+ this.#lastResumeToken = resumeToken;
2864
+ }
2541
2865
  } finally {
2542
2866
  for (const stream of this.#acpStreams.values()) {
2543
2867
  await stream.close();
@@ -3231,6 +3555,66 @@ var AgentConnection = class _AgentConnection {
3231
3555
  await agent.connect({ auth: options?.auth });
3232
3556
  return agent;
3233
3557
  }
3558
+ /**
3559
+ * Connect and register an agent via agentic-mesh transport.
3560
+ *
3561
+ * Handles:
3562
+ * - Dynamic import of agentic-mesh (optional peer dependency)
3563
+ * - Stream creation over encrypted mesh tunnel
3564
+ * - Auto-configuration of createStream for reconnection
3565
+ * - Initial MAP protocol connect handshake
3566
+ * - Agent registration
3567
+ *
3568
+ * Requires `agentic-mesh` to be installed as a peer dependency.
3569
+ *
3570
+ * @param options - Mesh connection and agent options
3571
+ * @returns Connected and registered AgentConnection instance
3572
+ *
3573
+ * @example
3574
+ * ```typescript
3575
+ * import { createNebulaTransport } from 'agentic-mesh';
3576
+ *
3577
+ * const transport = createNebulaTransport({
3578
+ * configPath: '/etc/nebula/config.yml',
3579
+ * });
3580
+ *
3581
+ * const agent = await AgentConnection.connectMesh({
3582
+ * transport,
3583
+ * peer: { peerId: 'server', address: '10.0.0.1', port: 4242 },
3584
+ * localPeerId: 'my-agent',
3585
+ * name: 'MeshWorker',
3586
+ * role: 'processor',
3587
+ * reconnection: true
3588
+ * });
3589
+ *
3590
+ * agent.onMessage(handleMessage);
3591
+ * await agent.busy();
3592
+ * ```
3593
+ */
3594
+ static async connectMesh(options) {
3595
+ const { agenticMeshStream: agenticMeshStream2 } = await Promise.resolve().then(() => (init_agentic_mesh(), agentic_mesh_exports));
3596
+ const streamConfig = {
3597
+ transport: options.transport,
3598
+ peer: options.peer,
3599
+ localPeerId: options.localPeerId,
3600
+ timeout: options.timeout
3601
+ };
3602
+ const stream = await agenticMeshStream2(streamConfig);
3603
+ const createStream = async () => agenticMeshStream2(streamConfig);
3604
+ const reconnection = options.reconnection === true ? { enabled: true } : typeof options.reconnection === "object" ? options.reconnection : void 0;
3605
+ const agent = new _AgentConnection(stream, {
3606
+ name: options.name,
3607
+ role: options.role,
3608
+ capabilities: options.capabilities,
3609
+ visibility: options.visibility,
3610
+ parent: options.parent,
3611
+ scopes: options.scopes,
3612
+ createStream,
3613
+ reconnection
3614
+ });
3615
+ await agent.connect({ auth: options.auth });
3616
+ return agent;
3617
+ }
3234
3618
  // ===========================================================================
3235
3619
  // Connection Lifecycle
3236
3620
  // ===========================================================================
@@ -3267,6 +3651,62 @@ var AgentConnection = class _AgentConnection {
3267
3651
  this.#connection._transitionTo("connected");
3268
3652
  return { connection: connectResult, agent: registerResult.agent };
3269
3653
  }
3654
+ /**
3655
+ * Authenticate with the server after connection.
3656
+ *
3657
+ * Use this when the server returns `authRequired` in the connect response,
3658
+ * indicating that authentication is needed before registering or accessing
3659
+ * protected resources.
3660
+ *
3661
+ * @param auth - Authentication credentials
3662
+ * @returns Authentication result with principal if successful
3663
+ *
3664
+ * @example
3665
+ * ```typescript
3666
+ * const agent = new AgentConnection(stream, { name: 'MyAgent' });
3667
+ *
3668
+ * // First connect to get auth requirements
3669
+ * const connectResult = await agent.connectOnly();
3670
+ *
3671
+ * if (connectResult.authRequired) {
3672
+ * const authResult = await agent.authenticate({
3673
+ * method: 'api-key',
3674
+ * token: process.env.AGENT_API_KEY,
3675
+ * });
3676
+ *
3677
+ * if (authResult.success) {
3678
+ * // Now register the agent
3679
+ * await agent.register({ name: 'MyAgent', role: 'worker' });
3680
+ * }
3681
+ * }
3682
+ * ```
3683
+ */
3684
+ async authenticate(auth) {
3685
+ const params = {
3686
+ method: auth.method,
3687
+ credential: auth.token
3688
+ };
3689
+ const result = await this.#connection.sendRequest(AUTH_METHODS.AUTHENTICATE, params);
3690
+ if (result.success && result.sessionId) {
3691
+ this.#sessionId = result.sessionId;
3692
+ }
3693
+ return result;
3694
+ }
3695
+ /**
3696
+ * Refresh authentication credentials.
3697
+ *
3698
+ * Use this to update credentials before they expire for long-lived connections.
3699
+ *
3700
+ * @param auth - New authentication credentials
3701
+ * @returns Updated principal information
3702
+ */
3703
+ async refreshAuth(auth) {
3704
+ const params = {
3705
+ method: auth.method,
3706
+ credential: auth.token
3707
+ };
3708
+ return this.#connection.sendRequest(AUTH_METHODS.AUTH_REFRESH, params);
3709
+ }
3270
3710
  /**
3271
3711
  * Disconnect from the MAP system
3272
3712
  * @param reason - Optional reason for disconnecting
@@ -4558,7 +4998,7 @@ var EventSchema = zod.z.object({
4558
4998
  var SubscriptionFilterSchema = zod.z.object({
4559
4999
  eventTypes: zod.z.array(EventTypeSchema).optional(),
4560
5000
  scopes: zod.z.array(ScopeIdSchema).optional(),
4561
- agents: zod.z.array(AgentIdSchema).optional(),
5001
+ fromAgents: zod.z.array(AgentIdSchema).optional(),
4562
5002
  includeChildren: zod.z.boolean().optional(),
4563
5003
  _meta: MetaSchema
4564
5004
  }).strict();
@@ -5297,6 +5737,334 @@ function toAgent(agentId) {
5297
5737
  function toScope(scopeId) {
5298
5738
  return formatAddress("scope", scopeId);
5299
5739
  }
5740
+ var MAPMeshPeer = class _MAPMeshPeer {
5741
+ #meshPeer;
5742
+ #config;
5743
+ #gitService;
5744
+ constructor(meshPeer, config) {
5745
+ this.#meshPeer = meshPeer;
5746
+ this.#config = config;
5747
+ this.#gitService = meshPeer.git ? new GitSyncServiceImpl(meshPeer.git, config.git?.repoPath ?? process.cwd()) : null;
5748
+ }
5749
+ // ===========================================================================
5750
+ // Static Factory
5751
+ // ===========================================================================
5752
+ /**
5753
+ * Create a new MAPMeshPeer.
5754
+ *
5755
+ * Requires `agentic-mesh` to be installed as a peer dependency.
5756
+ *
5757
+ * @param config - Peer configuration
5758
+ * @returns Promise resolving to the created peer (not yet started)
5759
+ */
5760
+ static async create(config) {
5761
+ const meshPeer = agenticMesh.createMeshPeer({
5762
+ peerId: config.peerId,
5763
+ peerName: config.peerName,
5764
+ transport: config.transport,
5765
+ git: config.git,
5766
+ peers: config.peers,
5767
+ map: config.map
5768
+ });
5769
+ return new _MAPMeshPeer(meshPeer, config);
5770
+ }
5771
+ // ===========================================================================
5772
+ // Properties
5773
+ // ===========================================================================
5774
+ /** Unique peer identifier */
5775
+ get peerId() {
5776
+ return this.#meshPeer.peerId;
5777
+ }
5778
+ /** Display name for this peer */
5779
+ get peerName() {
5780
+ return this.#meshPeer.peerName;
5781
+ }
5782
+ /** Whether the peer is currently running */
5783
+ get isRunning() {
5784
+ return this.#meshPeer.isRunning;
5785
+ }
5786
+ /** List of connected peer IDs */
5787
+ get connectedPeers() {
5788
+ return this.#meshPeer.connectedPeers;
5789
+ }
5790
+ /** Git sync service (null if git not enabled) */
5791
+ get git() {
5792
+ return this.#gitService;
5793
+ }
5794
+ // ===========================================================================
5795
+ // Lifecycle
5796
+ // ===========================================================================
5797
+ /**
5798
+ * Start the mesh peer.
5799
+ *
5800
+ * This starts the transport, MAP server, and git service (if enabled),
5801
+ * then connects to any initial peers specified in the config.
5802
+ */
5803
+ async start() {
5804
+ await this.#meshPeer.start(this.#config.transport);
5805
+ }
5806
+ /**
5807
+ * Stop the mesh peer.
5808
+ *
5809
+ * This disconnects from all peers, unregisters all agents,
5810
+ * stops the git service, MAP server, and transport.
5811
+ */
5812
+ async stop() {
5813
+ await this.#meshPeer.stop();
5814
+ }
5815
+ // ===========================================================================
5816
+ // Peer Connections
5817
+ // ===========================================================================
5818
+ /**
5819
+ * Connect to a remote peer.
5820
+ *
5821
+ * After connecting, agents on both peers will be discoverable
5822
+ * and messages can be routed between them.
5823
+ *
5824
+ * @param endpoint - Peer endpoint to connect to
5825
+ */
5826
+ async connectToPeer(endpoint) {
5827
+ await this.#meshPeer.connectToPeer(endpoint);
5828
+ }
5829
+ /**
5830
+ * Disconnect from a peer.
5831
+ *
5832
+ * @param peerId - ID of peer to disconnect from
5833
+ * @param reason - Optional reason for disconnecting
5834
+ */
5835
+ async disconnectFromPeer(peerId, reason) {
5836
+ await this.#meshPeer.disconnectFromPeer(peerId, reason);
5837
+ }
5838
+ /**
5839
+ * Check if connected to a specific peer.
5840
+ *
5841
+ * @param peerId - Peer ID to check
5842
+ * @returns true if connected
5843
+ */
5844
+ isConnectedTo(peerId) {
5845
+ return this.connectedPeers.includes(peerId);
5846
+ }
5847
+ // ===========================================================================
5848
+ // Agent Management
5849
+ // ===========================================================================
5850
+ /**
5851
+ * Create and register a local agent on this peer's MapServer.
5852
+ *
5853
+ * @param config - Agent configuration
5854
+ * @returns The created agent
5855
+ */
5856
+ async createAgent(config) {
5857
+ const agentConn = await this.#meshPeer.createAgent(config);
5858
+ return new LocalAgentImpl(agentConn);
5859
+ }
5860
+ /**
5861
+ * Get a local agent by ID.
5862
+ *
5863
+ * @param agentId - Agent ID to look up
5864
+ * @returns The agent, or undefined if not found
5865
+ */
5866
+ getAgent(agentId) {
5867
+ const conn = this.#meshPeer.getAgentConnection(agentId);
5868
+ return conn ? new LocalAgentImpl(conn) : void 0;
5869
+ }
5870
+ /**
5871
+ * Get all local agents on this peer.
5872
+ */
5873
+ getLocalAgents() {
5874
+ return this.#meshPeer.getLocalAgents();
5875
+ }
5876
+ /**
5877
+ * Get all known agents (local and discovered from connected peers).
5878
+ */
5879
+ getAllAgents() {
5880
+ return this.#meshPeer.getAllAgents();
5881
+ }
5882
+ // ===========================================================================
5883
+ // Scope Management
5884
+ // ===========================================================================
5885
+ /**
5886
+ * Create a scope on this peer's MapServer.
5887
+ *
5888
+ * @param config - Scope configuration
5889
+ * @returns The created scope
5890
+ */
5891
+ createScope(config) {
5892
+ return this.#meshPeer.createScope(config);
5893
+ }
5894
+ /**
5895
+ * Get a scope by ID.
5896
+ *
5897
+ * @param scopeId - Scope ID to look up
5898
+ * @returns The scope, or undefined if not found
5899
+ */
5900
+ getScope(scopeId) {
5901
+ return this.#meshPeer.getScope(scopeId);
5902
+ }
5903
+ /**
5904
+ * List all scopes on this peer.
5905
+ */
5906
+ listScopes() {
5907
+ return this.#meshPeer.listScopes();
5908
+ }
5909
+ // ===========================================================================
5910
+ // Messaging
5911
+ // ===========================================================================
5912
+ /**
5913
+ * Send a message from an agent to an address.
5914
+ *
5915
+ * Messages are routed to local agents or forwarded to connected peers.
5916
+ *
5917
+ * @param from - Sending agent ID
5918
+ * @param to - Destination address
5919
+ * @param payload - Message payload
5920
+ * @param meta - Optional message metadata
5921
+ * @returns Send result with delivery status
5922
+ */
5923
+ async send(from, to, payload, meta) {
5924
+ return this.#meshPeer.send(from, to, payload, meta);
5925
+ }
5926
+ // ===========================================================================
5927
+ // Events
5928
+ // ===========================================================================
5929
+ /**
5930
+ * Subscribe to events from this peer's MapServer.
5931
+ *
5932
+ * @param filter - Optional filter for event types
5933
+ * @returns Event subscription
5934
+ */
5935
+ subscribe(filter) {
5936
+ return this.#meshPeer.subscribe(this.peerId, filter);
5937
+ }
5938
+ /**
5939
+ * Register a handler for peer connection events.
5940
+ *
5941
+ * @param handler - Function called when a peer connects
5942
+ * @returns Unsubscribe function
5943
+ */
5944
+ onPeerConnected(handler) {
5945
+ this.#meshPeer.on("peer:connected", handler);
5946
+ return () => this.#meshPeer.off("peer:connected", handler);
5947
+ }
5948
+ /**
5949
+ * Register a handler for peer disconnection events.
5950
+ *
5951
+ * @param handler - Function called when a peer disconnects
5952
+ * @returns Unsubscribe function
5953
+ */
5954
+ onPeerDisconnected(handler) {
5955
+ this.#meshPeer.on("peer:disconnected", handler);
5956
+ return () => this.#meshPeer.off("peer:disconnected", handler);
5957
+ }
5958
+ /**
5959
+ * Register a handler for agent registration events.
5960
+ *
5961
+ * @param handler - Function called when an agent registers
5962
+ * @returns Unsubscribe function
5963
+ */
5964
+ onAgentRegistered(handler) {
5965
+ this.#meshPeer.on("agent:registered", handler);
5966
+ return () => this.#meshPeer.off("agent:registered", handler);
5967
+ }
5968
+ /**
5969
+ * Register a handler for agent unregistration events.
5970
+ *
5971
+ * @param handler - Function called when an agent unregisters
5972
+ * @returns Unsubscribe function
5973
+ */
5974
+ onAgentUnregistered(handler) {
5975
+ this.#meshPeer.on("agent:unregistered", handler);
5976
+ return () => this.#meshPeer.off("agent:unregistered", handler);
5977
+ }
5978
+ /**
5979
+ * Register a handler for error events.
5980
+ *
5981
+ * @param handler - Function called when an error occurs
5982
+ * @returns Unsubscribe function
5983
+ */
5984
+ onError(handler) {
5985
+ this.#meshPeer.on("error", handler);
5986
+ return () => this.#meshPeer.off("error", handler);
5987
+ }
5988
+ };
5989
+ var LocalAgentImpl = class {
5990
+ #conn;
5991
+ constructor(conn) {
5992
+ this.#conn = conn;
5993
+ }
5994
+ get agentId() {
5995
+ return this.#conn.agentId;
5996
+ }
5997
+ get name() {
5998
+ return this.#conn.name;
5999
+ }
6000
+ get role() {
6001
+ return this.#conn.role;
6002
+ }
6003
+ get state() {
6004
+ return this.#conn.state;
6005
+ }
6006
+ async busy() {
6007
+ await this.#conn.updateState("busy");
6008
+ }
6009
+ async idle() {
6010
+ await this.#conn.updateState("idle");
6011
+ }
6012
+ async updateState(state) {
6013
+ await this.#conn.updateState(state);
6014
+ }
6015
+ async updateMetadata(metadata) {
6016
+ await this.#conn.updateMetadata(metadata);
6017
+ }
6018
+ async send(to, payload, meta) {
6019
+ return this.#conn.send(to, payload, meta);
6020
+ }
6021
+ onMessage(handler) {
6022
+ const wrappedHandler = (message) => handler(message);
6023
+ this.#conn.on("message", wrappedHandler);
6024
+ return () => {
6025
+ this.#conn.off("message", wrappedHandler);
6026
+ };
6027
+ }
6028
+ async unregister(reason) {
6029
+ await this.#conn.unregister(reason);
6030
+ }
6031
+ };
6032
+ var GitSyncServiceImpl = class {
6033
+ #service;
6034
+ #defaultRepoPath;
6035
+ #defaultClient = null;
6036
+ constructor(service, defaultRepoPath) {
6037
+ this.#service = service;
6038
+ this.#defaultRepoPath = defaultRepoPath;
6039
+ }
6040
+ get isRunning() {
6041
+ return true;
6042
+ }
6043
+ get httpPort() {
6044
+ return this.#service.httpPort;
6045
+ }
6046
+ createSyncClient(repoPath) {
6047
+ return this.#service.createSyncClient(repoPath);
6048
+ }
6049
+ #getDefaultClient() {
6050
+ if (!this.#defaultClient) {
6051
+ this.#defaultClient = this.#service.createSyncClient(this.#defaultRepoPath);
6052
+ }
6053
+ return this.#defaultClient;
6054
+ }
6055
+ async sync(peerId, options) {
6056
+ return this.#getDefaultClient().sync(peerId, options);
6057
+ }
6058
+ async pull(peerId, branch, options) {
6059
+ return this.#getDefaultClient().pull(peerId, branch, options);
6060
+ }
6061
+ async push(peerId, branch, options) {
6062
+ return this.#getDefaultClient().push(peerId, branch, options);
6063
+ }
6064
+ async clone(peerId, destPath, options) {
6065
+ return this.#getDefaultClient().clone(peerId, destPath, options);
6066
+ }
6067
+ };
5300
6068
 
5301
6069
  // src/acp/adapter.ts
5302
6070
  var ACPAgentAdapter = class {
@@ -5687,6 +6455,7 @@ exports.LIFECYCLE_METHODS = LIFECYCLE_METHODS;
5687
6455
  exports.MAPConnectionError = MAPConnectionError;
5688
6456
  exports.MAPErrorDataSchema = MAPErrorDataSchema;
5689
6457
  exports.MAPErrorSchema = MAPErrorSchema;
6458
+ exports.MAPMeshPeer = MAPMeshPeer;
5690
6459
  exports.MAPNotificationSchema = MAPNotificationSchema;
5691
6460
  exports.MAPRequestError = MAPRequestError;
5692
6461
  exports.MAPRequestSchema = MAPRequestSchema;
@@ -5736,6 +6505,7 @@ exports.SubscriptionIdSchema = SubscriptionIdSchema;
5736
6505
  exports.SystemAddressSchema = SystemAddressSchema;
5737
6506
  exports.TimestampSchema = TimestampSchema;
5738
6507
  exports.TransportTypeSchema = TransportTypeSchema;
6508
+ exports.agenticMeshStream = agenticMeshStream;
5739
6509
  exports.buildAgentsGetResponse = buildAgentsGetResponse;
5740
6510
  exports.buildAgentsListResponse = buildAgentsListResponse;
5741
6511
  exports.buildAgentsRegisterResponse = buildAgentsRegisterResponse;