macp-sdk-typescript 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -74,6 +74,21 @@ Every session class follows the same pattern:
74
74
  4. Call `commit()` to finalize
75
75
  5. Read `session.projection` for local state
76
76
 
77
+ ### Session Start Options
78
+
79
+ All `start()` methods accept `contextId` and `extensions` for session-level metadata:
80
+
81
+ ```typescript
82
+ await session.start({
83
+ intent: 'pick a deployment strategy',
84
+ participants: ['alice', 'bob'],
85
+ ttlMs: 60_000,
86
+ contextId: 'ctx-abc', // optional opaque context reference
87
+ extensions: { 'x-trace': Buffer.from('tid') }, // optional typed extension buffers
88
+ roots: [{ uri: 'file:///workspace', name: 'repo' }],
89
+ });
90
+ ```
91
+
77
92
  ## Coordination Modes
78
93
 
79
94
  ### Decision Mode
@@ -177,6 +192,76 @@ session.projection.remainingVotesNeeded('r1'); // number
177
192
  session.projection.votedSenders('r1'); // string[]
178
193
  ```
179
194
 
195
+ ## Agent Framework
196
+
197
+ The `agent` module provides event-driven abstractions for building MACP participants.
198
+
199
+ ### Participant
200
+
201
+ `Participant` wraps a session, projection, and transport into a single event-driven handler:
202
+
203
+ ```typescript
204
+ import { agent } from 'macp-sdk-typescript';
205
+
206
+ const participant = new agent.Participant({
207
+ participantId: 'evaluator',
208
+ sessionId: 'sid-123',
209
+ mode: 'macp.mode.decision.v1',
210
+ client,
211
+ transport: new agent.GrpcTransportAdapter(client, 'sid-123', auth),
212
+ });
213
+
214
+ participant
215
+ .on('Proposal', async (msg, ctx) => {
216
+ await ctx.actions.evaluate({
217
+ proposalId: msg.payload.proposalId,
218
+ recommendation: 'APPROVE',
219
+ confidence: 0.95,
220
+ });
221
+ })
222
+ .onTerminal(async (result) => {
223
+ console.log('session ended:', result.reason);
224
+ });
225
+
226
+ await participant.run();
227
+ ```
228
+
229
+ ### Bootstrap Runner
230
+
231
+ `fromBootstrap()` creates a fully-wired `Participant` from a JSON bootstrap file (typically provided by the runtime orchestrator):
232
+
233
+ ```typescript
234
+ import { agent } from 'macp-sdk-typescript';
235
+
236
+ // Reads from path argument or MACP_BOOTSTRAP_FILE env var
237
+ const participant = agent.fromBootstrap('./bootstrap.json');
238
+ participant.on('Proposal', handler);
239
+ await participant.run();
240
+ ```
241
+
242
+ Bootstrap files can include an `initiator` section for participants that start the session:
243
+
244
+ ```json
245
+ {
246
+ "session_id": "sid-123",
247
+ "participant_id": "coordinator",
248
+ "mode": "macp.mode.decision.v1",
249
+ "runtime_address": "localhost:50051",
250
+ "initiator": {
251
+ "session_start": {
252
+ "intent": "pick deployment strategy",
253
+ "participants": ["coordinator", "evaluator"],
254
+ "ttl_ms": 60000,
255
+ "roots": [{ "uri": "file:///workspace" }]
256
+ },
257
+ "kickoff": {
258
+ "message_type": "Proposal",
259
+ "payload": { "proposalId": "p1", "option": "canary" }
260
+ }
261
+ }
262
+ }
263
+ ```
264
+
180
265
  ## Authentication
181
266
 
182
267
  ```typescript
@@ -2,6 +2,22 @@ import type { AuthConfig } from '../auth';
2
2
  import type { MacpClient } from '../client';
3
3
  import { type TransportAdapter } from './transports';
4
4
  import type { MessageHandler, PhaseChangeHandler, ProjectionLike, SessionActions, TerminalHandler } from './types';
5
+ export interface InitiatorConfig {
6
+ sessionStart: {
7
+ intent: string;
8
+ participants: string[];
9
+ ttlMs: number;
10
+ context?: Record<string, unknown>;
11
+ roots?: Array<{
12
+ uri: string;
13
+ name?: string;
14
+ }>;
15
+ };
16
+ kickoff?: {
17
+ messageType: string;
18
+ payload: Record<string, unknown>;
19
+ };
20
+ }
5
21
  export interface ParticipantConfig {
6
22
  participantId: string;
7
23
  sessionId: string;
@@ -13,6 +29,7 @@ export interface ParticipantConfig {
13
29
  configurationVersion?: string;
14
30
  policyVersion?: string;
15
31
  transport?: TransportAdapter;
32
+ initiator?: InitiatorConfig;
16
33
  }
17
34
  export declare class Participant {
18
35
  readonly participantId: string;
@@ -25,6 +42,7 @@ export declare class Participant {
25
42
  private readonly dispatcher;
26
43
  private readonly session;
27
44
  private readonly transport;
45
+ private readonly initiatorConfig?;
28
46
  private running;
29
47
  private lastPhase;
30
48
  constructor(config: ParticipantConfig);
@@ -35,4 +53,5 @@ export declare class Participant {
35
53
  onTerminal(handler: TerminalHandler): Participant;
36
54
  run(): Promise<void>;
37
55
  stop(): Promise<void>;
56
+ private emitInitiatorEnvelopes;
38
57
  }
@@ -21,6 +21,7 @@ class Participant {
21
21
  dispatcher;
22
22
  session;
23
23
  transport;
24
+ initiatorConfig;
24
25
  running = false;
25
26
  lastPhase;
26
27
  constructor(config) {
@@ -43,6 +44,7 @@ class Participant {
43
44
  this.lastPhase = projection.phase;
44
45
  this.actions = this.buildActions();
45
46
  this.transport = config.transport ?? new transports_1.GrpcTransportAdapter(config.client, config.sessionId, config.auth);
47
+ this.initiatorConfig = config.initiator;
46
48
  }
47
49
  createModeSession(mode, client, opts) {
48
50
  switch (mode) {
@@ -158,6 +160,9 @@ class Participant {
158
160
  if (this.running)
159
161
  return;
160
162
  this.running = true;
163
+ if (this.initiatorConfig && this.session) {
164
+ await this.emitInitiatorEnvelopes();
165
+ }
161
166
  const sessionInfo = {
162
167
  sessionId: this.sessionId,
163
168
  mode: this.mode,
@@ -217,5 +222,29 @@ class Participant {
217
222
  this.running = false;
218
223
  await this.transport.stop();
219
224
  }
225
+ async emitInitiatorEnvelopes() {
226
+ if (!this.initiatorConfig || !this.session)
227
+ return;
228
+ const ss = this.initiatorConfig.sessionStart;
229
+ if ('start' in this.session && typeof this.session.start === 'function') {
230
+ await this.session.start({
231
+ intent: ss.intent,
232
+ participants: ss.participants,
233
+ ttlMs: ss.ttlMs,
234
+ roots: ss.roots,
235
+ });
236
+ }
237
+ const kickoff = this.initiatorConfig.kickoff;
238
+ if (!kickoff)
239
+ return;
240
+ if (kickoff.messageType === 'Proposal' && this.session instanceof decision_1.DecisionSession) {
241
+ const payload = kickoff.payload;
242
+ await this.session.propose({
243
+ proposalId: String(payload.proposalId ?? payload.proposal_id ?? `${this.sessionId}-kickoff`),
244
+ option: String(payload.option ?? 'decide'),
245
+ rationale: payload.rationale !== undefined ? String(payload.rationale) : undefined,
246
+ });
247
+ }
248
+ }
220
249
  }
221
250
  exports.Participant = Participant;
@@ -11,8 +11,28 @@ export interface BootstrapPayload {
11
11
  auth_token?: string;
12
12
  agent_id?: string;
13
13
  secure?: boolean;
14
- /** Mirror of {@link MacpClientOptions.allowInsecure}; required when `secure` is false. */
15
14
  allow_insecure?: boolean;
16
15
  participants?: string[];
16
+ initiator?: {
17
+ session_start: {
18
+ intent: string;
19
+ participants: string[];
20
+ ttl_ms: number;
21
+ mode_version?: string;
22
+ configuration_version?: string;
23
+ policy_version?: string;
24
+ context?: Record<string, unknown>;
25
+ roots?: Array<{
26
+ uri: string;
27
+ name?: string;
28
+ }>;
29
+ };
30
+ kickoff?: {
31
+ message_type: string;
32
+ payload_type?: string;
33
+ payload: Record<string, unknown>;
34
+ };
35
+ };
36
+ metadata?: Record<string, unknown>;
17
37
  }
18
38
  export declare function fromBootstrap(bootstrapPath?: string): Participant;
@@ -69,6 +69,24 @@ function fromBootstrap(bootstrapPath) {
69
69
  allowInsecure: payload.allow_insecure,
70
70
  auth,
71
71
  });
72
+ let initiator;
73
+ if (payload.initiator) {
74
+ const ss = payload.initiator.session_start;
75
+ initiator = {
76
+ sessionStart: {
77
+ intent: ss.intent,
78
+ participants: ss.participants,
79
+ ttlMs: ss.ttl_ms,
80
+ roots: ss.roots,
81
+ },
82
+ kickoff: payload.initiator.kickoff
83
+ ? {
84
+ messageType: payload.initiator.kickoff.message_type,
85
+ payload: payload.initiator.kickoff.payload,
86
+ }
87
+ : undefined,
88
+ };
89
+ }
72
90
  const config = {
73
91
  participantId: payload.participant_id,
74
92
  sessionId: payload.session_id,
@@ -79,6 +97,7 @@ function fromBootstrap(bootstrapPath) {
79
97
  modeVersion: payload.mode_version,
80
98
  configurationVersion: payload.configuration_version,
81
99
  policyVersion: payload.policy_version ?? constants_1.DEFAULT_POLICY_VERSION,
100
+ initiator,
82
101
  };
83
102
  return new participant_1.Participant(config);
84
103
  }
package/dist/client.d.ts CHANGED
@@ -125,6 +125,11 @@ export declare class MacpClient {
125
125
  auth?: AuthConfig;
126
126
  deadlineMs?: number;
127
127
  }): Promise<PolicyDescriptor[]>;
128
+ listSessions(options?: {
129
+ auth?: AuthConfig;
130
+ deadlineMs?: number;
131
+ }): Promise<SessionMetadata[]>;
132
+ watchSessions(auth?: AuthConfig): grpc.ClientReadableStream<any>;
128
133
  watchPolicies(auth?: AuthConfig): grpc.ClientReadableStream<any>;
129
134
  /** @deprecated Use {@link watchPolicies}. Scheduled for removal in 0.4.0. */
130
135
  _watchPolicies(auth?: AuthConfig): grpc.ClientReadableStream<any>;
package/dist/client.js CHANGED
@@ -214,7 +214,7 @@ class MacpClient {
214
214
  websiteUrl: '',
215
215
  },
216
216
  capabilities: {
217
- sessions: { stream: true },
217
+ sessions: { stream: true, listSessions: true, watchSessions: true },
218
218
  cancellation: { cancelSession: true },
219
219
  progress: { progress: true },
220
220
  manifest: { getManifest: true },
@@ -293,6 +293,15 @@ class MacpClient {
293
293
  const res = await this.unary('ListPolicies', { mode: mode || '' }, auth, options?.deadlineMs);
294
294
  return res.descriptors || [];
295
295
  }
296
+ async listSessions(options) {
297
+ const auth = this.requireAuth(options?.auth);
298
+ const res = await this.unary('ListSessions', {}, auth, options?.deadlineMs);
299
+ return res.sessions || [];
300
+ }
301
+ watchSessions(auth) {
302
+ const metadata = this.metadata(auth);
303
+ return metadata ? this.client.WatchSessions({}, metadata) : this.client.WatchSessions({});
304
+ }
296
305
  watchPolicies(auth) {
297
306
  const metadata = this.metadata(auth);
298
307
  return metadata ? this.client.WatchPolicies({}, metadata) : this.client.WatchPolicies({});
@@ -24,7 +24,8 @@ export declare class DecisionSession {
24
24
  intent: string;
25
25
  participants: string[];
26
26
  ttlMs: number;
27
- context?: Buffer | string | Record<string, unknown>;
27
+ contextId?: string;
28
+ extensions?: Record<string, Buffer>;
28
29
  roots?: {
29
30
  uri: string;
30
31
  name?: string;
package/dist/decision.js CHANGED
@@ -47,7 +47,8 @@ class DecisionSession {
47
47
  intent: input.intent,
48
48
  participants: input.participants,
49
49
  ttlMs: input.ttlMs,
50
- context: input.context,
50
+ contextId: input.contextId,
51
+ extensions: input.extensions,
51
52
  roots: input.roots,
52
53
  modeVersion: this.modeVersion,
53
54
  configurationVersion: this.configurationVersion,
@@ -3,7 +3,6 @@ export declare function newSessionId(): string;
3
3
  export declare function newMessageId(): string;
4
4
  export declare function newCommitmentId(): string;
5
5
  export declare function nowUnixMs(): number;
6
- export declare function encodeContext(context?: Buffer | string | Record<string, unknown>): Buffer;
7
6
  export declare function buildSessionStartPayload(input: {
8
7
  intent: string;
9
8
  participants: string[];
@@ -11,7 +10,8 @@ export declare function buildSessionStartPayload(input: {
11
10
  modeVersion?: string;
12
11
  configurationVersion?: string;
13
12
  policyVersion?: string;
14
- context?: Buffer | string | Record<string, unknown>;
13
+ contextId?: string;
14
+ extensions?: Record<string, Buffer>;
15
15
  roots?: Root[];
16
16
  }): SessionStartPayload;
17
17
  export declare function inferOutcomePositive(action: string): boolean;
package/dist/envelope.js CHANGED
@@ -4,7 +4,6 @@ exports.newSessionId = newSessionId;
4
4
  exports.newMessageId = newMessageId;
5
5
  exports.newCommitmentId = newCommitmentId;
6
6
  exports.nowUnixMs = nowUnixMs;
7
- exports.encodeContext = encodeContext;
8
7
  exports.buildSessionStartPayload = buildSessionStartPayload;
9
8
  exports.inferOutcomePositive = inferOutcomePositive;
10
9
  exports.buildCommitmentPayload = buildCommitmentPayload;
@@ -25,15 +24,6 @@ function newCommitmentId() {
25
24
  function nowUnixMs() {
26
25
  return Date.now();
27
26
  }
28
- function encodeContext(context) {
29
- if (!context)
30
- return Buffer.alloc(0);
31
- if (Buffer.isBuffer(context))
32
- return context;
33
- if (typeof context === 'string')
34
- return Buffer.from(context, 'utf8');
35
- return Buffer.from(JSON.stringify(context), 'utf8');
36
- }
37
27
  function buildSessionStartPayload(input) {
38
28
  return {
39
29
  intent: input.intent,
@@ -42,7 +32,8 @@ function buildSessionStartPayload(input) {
42
32
  configurationVersion: input.configurationVersion ?? constants_1.DEFAULT_CONFIGURATION_VERSION,
43
33
  policyVersion: input.policyVersion ?? constants_1.DEFAULT_POLICY_VERSION,
44
34
  ttlMs: input.ttlMs,
45
- context: encodeContext(input.context),
35
+ contextId: input.contextId ?? '',
36
+ extensions: input.extensions ?? {},
46
37
  roots: input.roots ?? [],
47
38
  };
48
39
  }
package/dist/handoff.d.ts CHANGED
@@ -24,7 +24,8 @@ export declare class HandoffSession {
24
24
  intent: string;
25
25
  participants: string[];
26
26
  ttlMs: number;
27
- context?: Buffer | string | Record<string, unknown>;
27
+ contextId?: string;
28
+ extensions?: Record<string, Buffer>;
28
29
  roots?: {
29
30
  uri: string;
30
31
  name?: string;
package/dist/handoff.js CHANGED
@@ -55,7 +55,8 @@ class HandoffSession {
55
55
  intent: input.intent,
56
56
  participants: input.participants,
57
57
  ttlMs: input.ttlMs,
58
- context: input.context,
58
+ contextId: input.contextId,
59
+ extensions: input.extensions,
59
60
  roots: input.roots,
60
61
  modeVersion: this.modeVersion,
61
62
  configurationVersion: this.configurationVersion,
package/dist/policy.js CHANGED
@@ -38,7 +38,7 @@ function buildDecisionPolicy(policyId, description, rules) {
38
38
  policyId,
39
39
  mode: 'macp.mode.decision.v1',
40
40
  description,
41
- rules: Buffer.from(JSON.stringify(rulesJson)),
41
+ rules: JSON.stringify(rulesJson),
42
42
  schemaVersion: 1,
43
43
  };
44
44
  }
@@ -58,7 +58,7 @@ function buildQuorumPolicy(policyId, description, rules) {
58
58
  policyId,
59
59
  mode: 'macp.mode.quorum.v1',
60
60
  description,
61
- rules: Buffer.from(JSON.stringify(rulesJson)),
61
+ rules: JSON.stringify(rulesJson),
62
62
  schemaVersion: 1,
63
63
  };
64
64
  }
@@ -79,7 +79,7 @@ function buildProposalPolicy(policyId, description, rules) {
79
79
  policyId,
80
80
  mode: 'macp.mode.proposal.v1',
81
81
  description,
82
- rules: Buffer.from(JSON.stringify(rulesJson)),
82
+ rules: JSON.stringify(rulesJson),
83
83
  schemaVersion: 1,
84
84
  };
85
85
  }
@@ -97,7 +97,7 @@ function buildTaskPolicy(policyId, description, rules) {
97
97
  policyId,
98
98
  mode: 'macp.mode.task.v1',
99
99
  description,
100
- rules: Buffer.from(JSON.stringify(rulesJson)),
100
+ rules: JSON.stringify(rulesJson),
101
101
  schemaVersion: 1,
102
102
  };
103
103
  }
@@ -112,7 +112,7 @@ function buildHandoffPolicy(policyId, description, rules) {
112
112
  policyId,
113
113
  mode: 'macp.mode.handoff.v1',
114
114
  description,
115
- rules: Buffer.from(JSON.stringify(rulesJson)),
115
+ rules: JSON.stringify(rulesJson),
116
116
  schemaVersion: 1,
117
117
  };
118
118
  }
@@ -24,7 +24,8 @@ export declare class ProposalSession {
24
24
  intent: string;
25
25
  participants: string[];
26
26
  ttlMs: number;
27
- context?: Buffer | string | Record<string, unknown>;
27
+ contextId?: string;
28
+ extensions?: Record<string, Buffer>;
28
29
  roots?: {
29
30
  uri: string;
30
31
  name?: string;
package/dist/proposal.js CHANGED
@@ -47,7 +47,8 @@ class ProposalSession {
47
47
  intent: input.intent,
48
48
  participants: input.participants,
49
49
  ttlMs: input.ttlMs,
50
- context: input.context,
50
+ contextId: input.contextId,
51
+ extensions: input.extensions,
51
52
  roots: input.roots,
52
53
  modeVersion: this.modeVersion,
53
54
  configurationVersion: this.configurationVersion,
package/dist/quorum.d.ts CHANGED
@@ -24,7 +24,8 @@ export declare class QuorumSession {
24
24
  intent: string;
25
25
  participants: string[];
26
26
  ttlMs: number;
27
- context?: Buffer | string | Record<string, unknown>;
27
+ contextId?: string;
28
+ extensions?: Record<string, Buffer>;
28
29
  roots?: {
29
30
  uri: string;
30
31
  name?: string;
package/dist/quorum.js CHANGED
@@ -47,7 +47,8 @@ class QuorumSession {
47
47
  intent: input.intent,
48
48
  participants: input.participants,
49
49
  ttlMs: input.ttlMs,
50
- context: input.context,
50
+ contextId: input.contextId,
51
+ extensions: input.extensions,
51
52
  roots: input.roots,
52
53
  modeVersion: this.modeVersion,
53
54
  configurationVersion: this.configurationVersion,
package/dist/task.d.ts CHANGED
@@ -24,7 +24,8 @@ export declare class TaskSession {
24
24
  intent: string;
25
25
  participants: string[];
26
26
  ttlMs: number;
27
- context?: Buffer | string | Record<string, unknown>;
27
+ contextId?: string;
28
+ extensions?: Record<string, Buffer>;
28
29
  roots?: {
29
30
  uri: string;
30
31
  name?: string;
package/dist/task.js CHANGED
@@ -47,7 +47,8 @@ class TaskSession {
47
47
  intent: input.intent,
48
48
  participants: input.participants,
49
49
  ttlMs: input.ttlMs,
50
- context: input.context,
50
+ contextId: input.contextId,
51
+ extensions: input.extensions,
51
52
  roots: input.roots,
52
53
  modeVersion: this.modeVersion,
53
54
  configurationVersion: this.configurationVersion,
package/dist/types.d.ts CHANGED
@@ -45,6 +45,8 @@ export interface SessionMetadata {
45
45
  participants?: string[];
46
46
  participantActivity?: ParticipantActivity[];
47
47
  initiator?: string;
48
+ contextId?: string;
49
+ extensionKeys?: string[];
48
50
  }
49
51
  export interface ModeDescriptor {
50
52
  mode: string;
@@ -93,7 +95,8 @@ export interface SessionStartPayload {
93
95
  configurationVersion: string;
94
96
  policyVersion?: string;
95
97
  ttlMs: number;
96
- context?: Buffer;
98
+ contextId?: string;
99
+ extensions?: Record<string, Buffer>;
97
100
  roots?: Root[];
98
101
  }
99
102
  export interface CommitmentPayload {
@@ -250,7 +253,7 @@ export interface PolicyDescriptor {
250
253
  policyId: string;
251
254
  mode: string;
252
255
  description: string;
253
- rules: Buffer | Uint8Array;
256
+ rules: string;
254
257
  schemaVersion: number;
255
258
  registeredAtUnixMs?: number;
256
259
  }
@@ -261,3 +264,9 @@ export interface RegistryChanged {
261
264
  export interface RootsChanged {
262
265
  observedAtUnixMs: string;
263
266
  }
267
+ export type SessionLifecycleEventType = 'EVENT_TYPE_UNSPECIFIED' | 'EVENT_TYPE_CREATED' | 'EVENT_TYPE_RESOLVED' | 'EVENT_TYPE_EXPIRED';
268
+ export interface SessionLifecycleEvent {
269
+ eventType: SessionLifecycleEventType;
270
+ session: SessionMetadata;
271
+ observedAtUnixMs: string;
272
+ }
@@ -1,6 +1,6 @@
1
1
  import type { AuthConfig } from './auth';
2
2
  import type { MacpClient } from './client';
3
- import type { Envelope, PolicyDescriptor, RegistryChanged, RootsChanged } from './types';
3
+ import type { Envelope, PolicyDescriptor, RegistryChanged, RootsChanged, SessionLifecycleEvent } from './types';
4
4
  export declare class ModeRegistryWatcher {
5
5
  private readonly client;
6
6
  private readonly auth?;
@@ -45,3 +45,13 @@ export declare class PolicyWatcher {
45
45
  watch(handler: (change: PolicyChange) => void | Promise<void>): Promise<void>;
46
46
  nextChange(): Promise<PolicyChange>;
47
47
  }
48
+ export declare class SessionLifecycleWatcher {
49
+ private readonly client;
50
+ private readonly auth?;
51
+ constructor(client: MacpClient, options?: {
52
+ auth?: AuthConfig;
53
+ });
54
+ events(signal?: AbortSignal): AsyncGenerator<SessionLifecycleEvent, void, void>;
55
+ watch(handler: (event: SessionLifecycleEvent) => void | Promise<void>): Promise<void>;
56
+ nextEvent(): Promise<SessionLifecycleEvent>;
57
+ }
package/dist/watchers.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PolicyWatcher = exports.SignalWatcher = exports.RootsWatcher = exports.ModeRegistryWatcher = void 0;
3
+ exports.SessionLifecycleWatcher = exports.PolicyWatcher = exports.SignalWatcher = exports.RootsWatcher = exports.ModeRegistryWatcher = void 0;
4
4
  function serverStreamToAsyncGenerator(stream) {
5
5
  const queue = [];
6
6
  let resolve = null;
@@ -174,3 +174,36 @@ class PolicyWatcher {
174
174
  }
175
175
  }
176
176
  exports.PolicyWatcher = PolicyWatcher;
177
+ class SessionLifecycleWatcher {
178
+ client;
179
+ auth;
180
+ constructor(client, options) {
181
+ this.client = client;
182
+ this.auth = options?.auth;
183
+ }
184
+ async *events(signal) {
185
+ const stream = this.client.watchSessions(this.auth);
186
+ if (signal) {
187
+ signal.addEventListener('abort', () => stream.cancel(), { once: true });
188
+ }
189
+ const gen = serverStreamToAsyncGenerator(stream);
190
+ for await (const response of gen) {
191
+ if (response.event)
192
+ yield response.event;
193
+ }
194
+ }
195
+ async watch(handler) {
196
+ for await (const event of this.events()) {
197
+ await handler(event);
198
+ }
199
+ }
200
+ async nextEvent() {
201
+ const gen = this.events();
202
+ const result = await gen.next();
203
+ await gen.return(undefined);
204
+ if (result.done)
205
+ throw new Error('stream ended before receiving a session lifecycle event');
206
+ return result.value;
207
+ }
208
+ }
209
+ exports.SessionLifecycleWatcher = SessionLifecycleWatcher;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "macp-sdk-typescript",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "TypeScript SDK for the MACP Rust runtime",
5
5
  "license": "Apache-2.0",
6
6
  "type": "commonjs",
@@ -55,7 +55,7 @@
55
55
  "dependencies": {
56
56
  "@grpc/grpc-js": "^1.14.3",
57
57
  "@grpc/proto-loader": "^0.8.0",
58
- "@multiagentcoordinationprotocol/proto": "^0.1.0",
58
+ "@multiagentcoordinationprotocol/proto": "^0.1.1",
59
59
  "protobufjs": "^8.0.0"
60
60
  },
61
61
  "devDependencies": {