macp-sdk-typescript 0.2.2 → 0.3.0

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/errors.d.ts CHANGED
@@ -5,6 +5,18 @@ export declare class MacpSdkError extends Error {
5
5
  export declare class MacpTransportError extends MacpSdkError {
6
6
  constructor(message: string);
7
7
  }
8
+ /**
9
+ * Structured NACK record. Mirrors python-sdk's `AckFailure` dataclass so
10
+ * cross-SDK code can share the same shape when logging or persisting a
11
+ * rejected message.
12
+ */
13
+ export interface AckFailure {
14
+ code: string;
15
+ message: string;
16
+ sessionId: string;
17
+ messageId: string;
18
+ reasons: string[];
19
+ }
8
20
  export declare class MacpAckError extends MacpSdkError {
9
21
  readonly ack: Ack;
10
22
  /** Optional gRPC trailing metadata for extracting additional error details. */
@@ -12,14 +24,15 @@ export declare class MacpAckError extends MacpSdkError {
12
24
  key: string;
13
25
  value: string | Buffer;
14
26
  }>;
27
+ /** Structured NACK record — parity with python-sdk `MacpAckError.failure`. */
28
+ readonly failure: AckFailure;
15
29
  constructor(ack: Ack, grpcMetadata?: Array<{
16
30
  key: string;
17
31
  value: string | Buffer;
18
32
  }>);
19
- /** Extract structured denial reasons from the ACK error details and/or gRPC trailing metadata. */
20
- get reasons(): string[];
21
- private _parseAckReasons;
22
- private _parseGrpcMetadataReasons;
33
+ private static _extractReasons;
34
+ private static _parseAckReasons;
35
+ private static _parseGrpcMetadataReasons;
23
36
  }
24
37
  export declare class MacpSessionError extends MacpSdkError {
25
38
  constructor(message: string);
package/dist/errors.js CHANGED
@@ -19,26 +19,35 @@ class MacpAckError extends MacpSdkError {
19
19
  ack;
20
20
  /** Optional gRPC trailing metadata for extracting additional error details. */
21
21
  grpcMetadata;
22
+ /** Structured NACK record — parity with python-sdk `MacpAckError.failure`. */
23
+ failure;
22
24
  constructor(ack, grpcMetadata) {
23
25
  super(`${ack.error?.code ?? 'UNKNOWN'}: ${ack.error?.message ?? 'runtime returned nack'}`);
24
26
  this.name = 'MacpAckError';
25
27
  this.ack = ack;
26
28
  this.grpcMetadata = grpcMetadata;
29
+ const reasons = MacpAckError._extractReasons(ack, grpcMetadata);
30
+ this.failure = {
31
+ code: ack.error?.code ?? 'UNKNOWN',
32
+ message: ack.error?.message ?? 'runtime returned nack',
33
+ sessionId: ack.sessionId ?? ack.error?.sessionId ?? '',
34
+ messageId: ack.messageId ?? ack.error?.messageId ?? '',
35
+ reasons,
36
+ };
27
37
  }
28
- /** Extract structured denial reasons from the ACK error details and/or gRPC trailing metadata. */
29
- get reasons() {
38
+ static _extractReasons(ack, grpcMetadata) {
30
39
  // First try: parse from ack.error.details (matches Python _parse_ack_reasons)
31
- const fromDetails = this._parseAckReasons();
40
+ const fromDetails = MacpAckError._parseAckReasons(ack);
32
41
  if (fromDetails.length > 0)
33
42
  return fromDetails;
34
43
  // Second try: parse from gRPC trailing metadata (matches Python _parse_grpc_metadata_reasons)
35
- return this._parseGrpcMetadataReasons();
44
+ return MacpAckError._parseGrpcMetadataReasons(grpcMetadata);
36
45
  }
37
- _parseAckReasons() {
38
- if (!this.ack.error?.details)
46
+ static _parseAckReasons(ack) {
47
+ if (!ack.error?.details)
39
48
  return [];
40
49
  try {
41
- const details = this.ack.error.details;
50
+ const details = ack.error.details;
42
51
  const raw = Buffer.isBuffer(details) ? details.toString('utf-8') : String(details);
43
52
  const parsed = JSON.parse(raw);
44
53
  const reasons = parsed.reasons;
@@ -48,11 +57,11 @@ class MacpAckError extends MacpSdkError {
48
57
  return [];
49
58
  }
50
59
  }
51
- _parseGrpcMetadataReasons() {
52
- if (!this.grpcMetadata)
60
+ static _parseGrpcMetadataReasons(grpcMetadata) {
61
+ if (!grpcMetadata)
53
62
  return [];
54
63
  try {
55
- for (const item of this.grpcMetadata) {
64
+ for (const item of grpcMetadata) {
56
65
  if (item.key === 'macp-error-details-bin') {
57
66
  const data = Buffer.isBuffer(item.value)
58
67
  ? item.value.toString('utf-8')
package/dist/handoff.d.ts CHANGED
@@ -40,14 +40,6 @@ export declare class HandoffSession {
40
40
  sender?: string;
41
41
  auth?: AuthConfig;
42
42
  }): Promise<Ack>;
43
- /**
44
- * @deprecated Use {@link addContext} instead. Scheduled for removal in 0.4.0.
45
- * First call logs a one-shot warning to guide migrations without spamming long-lived processes.
46
- */
47
- sendContext(input: HandoffContextPayload & {
48
- sender?: string;
49
- auth?: AuthConfig;
50
- }): Promise<Ack>;
51
43
  acceptHandoff(input: HandoffAcceptPayload & {
52
44
  sender?: string;
53
45
  auth?: AuthConfig;
package/dist/handoff.js CHANGED
@@ -6,14 +6,6 @@ const constants_1 = require("./constants");
6
6
  const envelope_1 = require("./envelope");
7
7
  const handoff_1 = require("./projections/handoff");
8
8
  const validation_1 = require("./validation");
9
- let sendContextWarned = false;
10
- function warnSendContextOnce() {
11
- if (sendContextWarned)
12
- return;
13
- sendContextWarned = true;
14
- // eslint-disable-next-line no-console
15
- console.warn('[macp-sdk-typescript] HandoffSession.sendContext() is deprecated and will be removed in 0.4.0. Use addContext() instead.');
16
- }
17
9
  class HandoffSession {
18
10
  client;
19
11
  sessionId;
@@ -95,14 +87,6 @@ class HandoffSession {
95
87
  });
96
88
  return this.sendAndTrack(envelope, input.auth);
97
89
  }
98
- /**
99
- * @deprecated Use {@link addContext} instead. Scheduled for removal in 0.4.0.
100
- * First call logs a one-shot warning to guide migrations without spamming long-lived processes.
101
- */
102
- async sendContext(input) {
103
- warnSendContextOnce();
104
- return this.addContext(input);
105
- }
106
90
  async acceptHandoff(input) {
107
91
  (0, validation_1.validateRequiredField)('handoffId', input.handoffId);
108
92
  const envelope = (0, envelope_1.buildEnvelope)({
package/dist/index.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- export * from './auth';
1
+ export { Auth, type AuthConfig, type BearerAuthOptions } from './auth';
2
+ export * from './base-session';
2
3
  export * from './client';
3
4
  export * from './constants';
4
5
  export * from './decision';
5
6
  export * from './envelope';
6
7
  export * from './errors';
7
8
  export * from './handoff';
9
+ export * from './logging';
8
10
  export * from './policy';
9
11
  export * from './projections';
10
12
  export * from './proposal';
package/dist/index.js CHANGED
@@ -36,14 +36,22 @@ var __importStar = (this && this.__importStar) || (function () {
36
36
  };
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.agent = void 0;
40
- __exportStar(require("./auth"), exports);
39
+ exports.agent = exports.Auth = void 0;
40
+ // Auth: export only the public constructors and types. The helpers
41
+ // `validateAuth`, `authSender`, `assertSenderMatchesIdentity`, and
42
+ // `metadataFromAuth` are SDK-internal — importable from the `./auth`
43
+ // submodule if needed, but intentionally absent from the top-level surface
44
+ // to match python-sdk's `__all__` (which only exposes `AuthConfig`).
45
+ var auth_1 = require("./auth");
46
+ Object.defineProperty(exports, "Auth", { enumerable: true, get: function () { return auth_1.Auth; } });
47
+ __exportStar(require("./base-session"), exports);
41
48
  __exportStar(require("./client"), exports);
42
49
  __exportStar(require("./constants"), exports);
43
50
  __exportStar(require("./decision"), exports);
44
51
  __exportStar(require("./envelope"), exports);
45
52
  __exportStar(require("./errors"), exports);
46
53
  __exportStar(require("./handoff"), exports);
54
+ __exportStar(require("./logging"), exports);
47
55
  __exportStar(require("./policy"), exports);
48
56
  __exportStar(require("./projections"), exports);
49
57
  __exportStar(require("./proposal"), exports);
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Structured logger for the MACP SDK.
3
+ *
4
+ * Parity with python-sdk's `macp_sdk._logging.logger` + `configure_logging()`:
5
+ * production Node apps need controllable log levels (silent by default-ish,
6
+ * opt-in verbose) and the ability to re-route to Pino / Winston / etc.
7
+ */
8
+ export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';
9
+ export type LogSink = (level: Exclude<LogLevel, 'silent'>, args: unknown[]) => void;
10
+ export declare const logger: {
11
+ error: (...args: unknown[]) => void;
12
+ warn: (...args: unknown[]) => void;
13
+ info: (...args: unknown[]) => void;
14
+ debug: (...args: unknown[]) => void;
15
+ };
16
+ export declare function configureLogging(options: {
17
+ level?: LogLevel;
18
+ sink?: LogSink;
19
+ }): void;
20
+ /** Test-only: reset to env-derived level + default sink. */
21
+ export declare function _resetLoggingForTests(): void;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /**
3
+ * Structured logger for the MACP SDK.
4
+ *
5
+ * Parity with python-sdk's `macp_sdk._logging.logger` + `configure_logging()`:
6
+ * production Node apps need controllable log levels (silent by default-ish,
7
+ * opt-in verbose) and the ability to re-route to Pino / Winston / etc.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.logger = void 0;
11
+ exports.configureLogging = configureLogging;
12
+ exports._resetLoggingForTests = _resetLoggingForTests;
13
+ const LEVEL_ORDER = {
14
+ silent: 0,
15
+ error: 1,
16
+ warn: 2,
17
+ info: 3,
18
+ debug: 4,
19
+ };
20
+ const defaultSink = (level, args) => {
21
+ const method = level === 'debug' || level === 'info' ? 'log' : level;
22
+ // eslint-disable-next-line no-console
23
+ (console[method] ?? console.log)('[macp-sdk]', ...args);
24
+ };
25
+ function envLevel() {
26
+ const raw = typeof process !== 'undefined' ? process.env?.MACP_LOG_LEVEL?.toLowerCase() : undefined;
27
+ if (raw && raw in LEVEL_ORDER)
28
+ return raw;
29
+ return 'warn';
30
+ }
31
+ const state = {
32
+ level: envLevel(),
33
+ sink: defaultSink,
34
+ };
35
+ function shouldLog(level) {
36
+ return LEVEL_ORDER[state.level] >= LEVEL_ORDER[level];
37
+ }
38
+ function emit(level, args) {
39
+ if (!shouldLog(level))
40
+ return;
41
+ state.sink(level, args);
42
+ }
43
+ exports.logger = {
44
+ error: (...args) => emit('error', args),
45
+ warn: (...args) => emit('warn', args),
46
+ info: (...args) => emit('info', args),
47
+ debug: (...args) => emit('debug', args),
48
+ };
49
+ function configureLogging(options) {
50
+ if (options.level !== undefined) {
51
+ if (!(options.level in LEVEL_ORDER)) {
52
+ throw new Error(`configureLogging: unknown level "${options.level}"`);
53
+ }
54
+ state.level = options.level;
55
+ }
56
+ if (options.sink !== undefined) {
57
+ state.sink = options.sink;
58
+ }
59
+ }
60
+ /** Test-only: reset to env-derived level + default sink. */
61
+ function _resetLoggingForTests() {
62
+ state.level = envLevel();
63
+ state.sink = defaultSink;
64
+ }
package/dist/policy.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import type { PolicyDescriptor } from './types';
2
- export interface CommitmentRulesInput {
2
+ export interface CommitmentRules {
3
3
  authority?: 'initiator_only' | 'any_participant' | 'designated_role';
4
4
  designatedRoles?: string[];
5
+ /** Decision-specific: require quorum before commit. Ignored for other modes. */
6
+ requireVoteQuorum?: boolean;
5
7
  }
6
- export interface DecisionVotingRules {
8
+ export interface VotingRules {
7
9
  algorithm?: 'none' | 'majority' | 'supermajority' | 'unanimous' | 'weighted' | 'plurality';
8
10
  threshold?: number;
9
11
  quorum?: {
@@ -12,62 +14,65 @@ export interface DecisionVotingRules {
12
14
  };
13
15
  weights?: Record<string, number>;
14
16
  }
15
- export interface DecisionObjectionHandling {
17
+ export interface ObjectionHandlingRules {
16
18
  criticalSeverityVetoes?: boolean;
17
19
  vetoThreshold?: number;
18
20
  }
19
- export interface DecisionEvaluationRules {
21
+ export interface EvaluationRules {
20
22
  minimumConfidence?: number;
21
23
  requiredBeforeVoting?: boolean;
22
24
  }
23
- export interface DecisionCommitmentRules {
24
- authority?: 'initiator_only' | 'any_participant' | 'designated_role';
25
- designatedRoles?: string[];
26
- requireVoteQuorum?: boolean;
25
+ export interface QuorumThreshold {
26
+ type: 'n_of_m' | 'percentage' | 'weighted';
27
+ value: number;
28
+ }
29
+ export interface AbstentionRules {
30
+ countsTowardQuorum?: boolean;
31
+ interpretation?: 'neutral' | 'implicit_reject' | 'ignored';
32
+ }
33
+ export interface ProposalAcceptanceRules {
34
+ criterion?: 'all_parties' | 'counterparty' | 'initiator';
35
+ }
36
+ export interface CounterProposalRules {
37
+ maxRounds?: number;
38
+ }
39
+ export interface RejectionRules {
40
+ terminalOnAnyReject?: boolean;
41
+ }
42
+ export interface TaskAssignmentRules {
43
+ allowReassignmentOnReject?: boolean;
44
+ }
45
+ export interface TaskCompletionRules {
46
+ requireOutput?: boolean;
47
+ }
48
+ export interface HandoffAcceptanceRules {
49
+ implicitAcceptTimeoutMs?: number;
27
50
  }
28
51
  export interface DecisionPolicyRulesInput {
29
- voting?: DecisionVotingRules;
30
- objectionHandling?: DecisionObjectionHandling;
31
- evaluation?: DecisionEvaluationRules;
32
- commitment?: DecisionCommitmentRules;
52
+ voting?: VotingRules;
53
+ objectionHandling?: ObjectionHandlingRules;
54
+ evaluation?: EvaluationRules;
55
+ commitment?: CommitmentRules;
33
56
  }
34
57
  export interface QuorumPolicyRulesInput {
35
- threshold?: {
36
- type: 'n_of_m' | 'percentage' | 'weighted';
37
- value: number;
38
- };
39
- abstention?: {
40
- countsTowardQuorum?: boolean;
41
- interpretation?: 'neutral' | 'implicit_reject' | 'ignored';
42
- };
43
- commitment?: CommitmentRulesInput;
58
+ threshold?: QuorumThreshold;
59
+ abstention?: AbstentionRules;
60
+ commitment?: CommitmentRules;
44
61
  }
45
62
  export interface ProposalPolicyRulesInput {
46
- acceptance?: {
47
- criterion?: 'all_parties' | 'counterparty' | 'initiator';
48
- };
49
- counterProposal?: {
50
- maxRounds?: number;
51
- };
52
- rejection?: {
53
- terminalOnAnyReject?: boolean;
54
- };
55
- commitment?: CommitmentRulesInput;
63
+ acceptance?: ProposalAcceptanceRules;
64
+ counterProposal?: CounterProposalRules;
65
+ rejection?: RejectionRules;
66
+ commitment?: CommitmentRules;
56
67
  }
57
68
  export interface TaskPolicyRulesInput {
58
- assignment?: {
59
- allowReassignmentOnReject?: boolean;
60
- };
61
- completion?: {
62
- requireOutput?: boolean;
63
- };
64
- commitment?: CommitmentRulesInput;
69
+ assignment?: TaskAssignmentRules;
70
+ completion?: TaskCompletionRules;
71
+ commitment?: CommitmentRules;
65
72
  }
66
73
  export interface HandoffPolicyRulesInput {
67
- acceptance?: {
68
- implicitAcceptTimeoutMs?: number;
69
- };
70
- commitment?: CommitmentRulesInput;
74
+ acceptance?: HandoffAcceptanceRules;
75
+ commitment?: CommitmentRules;
71
76
  }
72
77
  export declare function buildDecisionPolicy(policyId: string, description: string, rules: DecisionPolicyRulesInput): PolicyDescriptor;
73
78
  export declare function buildQuorumPolicy(policyId: string, description: string, rules: QuorumPolicyRulesInput): PolicyDescriptor;
package/dist/policy.js CHANGED
@@ -5,13 +5,13 @@ exports.buildQuorumPolicy = buildQuorumPolicy;
5
5
  exports.buildProposalPolicy = buildProposalPolicy;
6
6
  exports.buildTaskPolicy = buildTaskPolicy;
7
7
  exports.buildHandoffPolicy = buildHandoffPolicy;
8
+ // ── Builder helpers ─────────────────────────────────────────────────
8
9
  function serializeCommitment(commitment) {
9
10
  return {
10
11
  authority: commitment?.authority ?? 'initiator_only',
11
12
  designated_roles: commitment?.designatedRoles ?? [],
12
13
  };
13
14
  }
14
- // ── Builder helpers ─────────────────────────────────────────────────
15
15
  function buildDecisionPolicy(policyId, description, rules) {
16
16
  const rulesJson = {
17
17
  voting: {
@@ -0,0 +1,20 @@
1
+ import type { ProtoRegistry } from '../proto-registry';
2
+ import type { Envelope } from '../types';
3
+ /**
4
+ * Abstract base for in-process mode-state tracking — parity with python-sdk's
5
+ * `macp_sdk.base_projection.BaseProjection`. Maintains a shared transcript,
6
+ * phase string, and commitment payload; subclasses override `applyMode`
7
+ * to handle mode-specific envelopes. `SessionStart` and `Commitment` are
8
+ * handled here so custom modes get the common lifecycle for free.
9
+ */
10
+ export declare abstract class BaseProjection {
11
+ readonly transcript: Envelope[];
12
+ phase: string;
13
+ commitment?: Record<string, unknown>;
14
+ protected abstract readonly mode: string;
15
+ get isCommitted(): boolean;
16
+ get isPositiveOutcome(): boolean | undefined;
17
+ applyEnvelope(envelope: Envelope, protoRegistry: ProtoRegistry): void;
18
+ /** Handle a mode-specific (non-Commitment) envelope. */
19
+ protected abstract applyMode(envelope: Envelope, protoRegistry: ProtoRegistry): void;
20
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseProjection = void 0;
4
+ /**
5
+ * Abstract base for in-process mode-state tracking — parity with python-sdk's
6
+ * `macp_sdk.base_projection.BaseProjection`. Maintains a shared transcript,
7
+ * phase string, and commitment payload; subclasses override `applyMode`
8
+ * to handle mode-specific envelopes. `SessionStart` and `Commitment` are
9
+ * handled here so custom modes get the common lifecycle for free.
10
+ */
11
+ class BaseProjection {
12
+ transcript = [];
13
+ phase = '';
14
+ commitment;
15
+ get isCommitted() {
16
+ return this.commitment !== undefined;
17
+ }
18
+ get isPositiveOutcome() {
19
+ if (!this.commitment)
20
+ return undefined;
21
+ const val = this.commitment.outcomePositive ??
22
+ this.commitment.outcome_positive;
23
+ return val !== undefined ? Boolean(val) : true;
24
+ }
25
+ applyEnvelope(envelope, protoRegistry) {
26
+ if (envelope.mode !== this.mode)
27
+ return;
28
+ this.transcript.push(envelope);
29
+ if (envelope.messageType === 'Commitment') {
30
+ this.commitment = protoRegistry.decodeKnownPayload(envelope.mode, envelope.messageType, envelope.payload);
31
+ this.phase = 'Committed';
32
+ return;
33
+ }
34
+ this.applyMode(envelope, protoRegistry);
35
+ }
36
+ }
37
+ exports.BaseProjection = BaseProjection;
@@ -1,3 +1,4 @@
1
+ export * from './projections/base';
1
2
  export * from './projections/decision';
2
3
  export * from './projections/proposal';
3
4
  export * from './projections/task';
@@ -14,6 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./projections/base"), exports);
17
18
  __exportStar(require("./projections/decision"), exports);
18
19
  __exportStar(require("./projections/proposal"), exports);
19
20
  __exportStar(require("./projections/task"), exports);
package/dist/task.d.ts CHANGED
@@ -32,7 +32,7 @@ export declare class TaskSession {
32
32
  }[];
33
33
  sender?: string;
34
34
  }): Promise<Ack>;
35
- request(input: TaskRequestPayload & {
35
+ requestTask(input: TaskRequestPayload & {
36
36
  sender?: string;
37
37
  auth?: AuthConfig;
38
38
  }): Promise<Ack>;
@@ -44,15 +44,15 @@ export declare class TaskSession {
44
44
  sender?: string;
45
45
  auth?: AuthConfig;
46
46
  }): Promise<Ack>;
47
- update(input: TaskUpdatePayload & {
47
+ updateTask(input: TaskUpdatePayload & {
48
48
  sender?: string;
49
49
  auth?: AuthConfig;
50
50
  }): Promise<Ack>;
51
- complete(input: TaskCompletePayload & {
51
+ completeTask(input: TaskCompletePayload & {
52
52
  sender?: string;
53
53
  auth?: AuthConfig;
54
54
  }): Promise<Ack>;
55
- fail(input: TaskFailPayload & {
55
+ failTask(input: TaskFailPayload & {
56
56
  sender?: string;
57
57
  auth?: AuthConfig;
58
58
  }): Promise<Ack>;
package/dist/task.js CHANGED
@@ -63,7 +63,7 @@ class TaskSession {
63
63
  });
64
64
  return this.sendAndTrack(envelope, this.auth);
65
65
  }
66
- async request(input) {
66
+ async requestTask(input) {
67
67
  (0, validation_1.validateRequiredField)('taskId', input.taskId);
68
68
  (0, validation_1.validateRequiredField)('title', input.title);
69
69
  (0, validation_1.validateRequiredField)('instructions', input.instructions);
@@ -98,7 +98,7 @@ class TaskSession {
98
98
  });
99
99
  return this.sendAndTrack(envelope, input.auth);
100
100
  }
101
- async update(input) {
101
+ async updateTask(input) {
102
102
  (0, validation_1.validateRequiredField)('taskId', input.taskId);
103
103
  const envelope = (0, envelope_1.buildEnvelope)({
104
104
  mode: constants_1.MODE_TASK,
@@ -109,7 +109,7 @@ class TaskSession {
109
109
  });
110
110
  return this.sendAndTrack(envelope, input.auth);
111
111
  }
112
- async complete(input) {
112
+ async completeTask(input) {
113
113
  (0, validation_1.validateRequiredField)('taskId', input.taskId);
114
114
  const envelope = (0, envelope_1.buildEnvelope)({
115
115
  mode: constants_1.MODE_TASK,
@@ -120,7 +120,7 @@ class TaskSession {
120
120
  });
121
121
  return this.sendAndTrack(envelope, input.auth);
122
122
  }
123
- async fail(input) {
123
+ async failTask(input) {
124
124
  (0, validation_1.validateRequiredField)('taskId', input.taskId);
125
125
  const envelope = (0, envelope_1.buildEnvelope)({
126
126
  mode: constants_1.MODE_TASK,
@@ -48,10 +48,22 @@ export declare class PolicyWatcher {
48
48
  export declare class SessionLifecycleWatcher {
49
49
  private readonly client;
50
50
  private readonly auth?;
51
+ private deprecatedEventsWarned;
52
+ private deprecatedNextEventWarned;
51
53
  constructor(client: MacpClient, options?: {
52
54
  auth?: AuthConfig;
53
55
  });
54
- events(signal?: AbortSignal): AsyncGenerator<SessionLifecycleEvent, void, void>;
56
+ changes(signal?: AbortSignal): AsyncGenerator<SessionLifecycleEvent, void, void>;
55
57
  watch(handler: (event: SessionLifecycleEvent) => void | Promise<void>): Promise<void>;
58
+ nextChange(): Promise<SessionLifecycleEvent>;
59
+ /**
60
+ * @deprecated Use {@link changes} — renamed for parity with python-sdk's
61
+ * `SessionLifecycleWatcher.changes()` and the uniform `changes()` name
62
+ * used by all other watchers in both SDKs. Will be removed in 0.5.0.
63
+ */
64
+ events(signal?: AbortSignal): AsyncGenerator<SessionLifecycleEvent, void, void>;
65
+ /**
66
+ * @deprecated Use {@link nextChange}. Will be removed in 0.5.0.
67
+ */
56
68
  nextEvent(): Promise<SessionLifecycleEvent>;
57
69
  }
package/dist/watchers.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SessionLifecycleWatcher = exports.PolicyWatcher = exports.SignalWatcher = exports.RootsWatcher = exports.ModeRegistryWatcher = void 0;
4
+ const logging_1 = require("./logging");
4
5
  function serverStreamToAsyncGenerator(stream) {
5
6
  const queue = [];
6
7
  let resolve = null;
@@ -177,11 +178,13 @@ exports.PolicyWatcher = PolicyWatcher;
177
178
  class SessionLifecycleWatcher {
178
179
  client;
179
180
  auth;
181
+ deprecatedEventsWarned = false;
182
+ deprecatedNextEventWarned = false;
180
183
  constructor(client, options) {
181
184
  this.client = client;
182
185
  this.auth = options?.auth;
183
186
  }
184
- async *events(signal) {
187
+ async *changes(signal) {
185
188
  const stream = this.client.watchSessions(this.auth);
186
189
  if (signal) {
187
190
  signal.addEventListener('abort', () => stream.cancel(), { once: true });
@@ -193,17 +196,39 @@ class SessionLifecycleWatcher {
193
196
  }
194
197
  }
195
198
  async watch(handler) {
196
- for await (const event of this.events()) {
199
+ for await (const event of this.changes()) {
197
200
  await handler(event);
198
201
  }
199
202
  }
200
- async nextEvent() {
201
- const gen = this.events();
203
+ async nextChange() {
204
+ const gen = this.changes();
202
205
  const result = await gen.next();
203
206
  await gen.return(undefined);
204
207
  if (result.done)
205
208
  throw new Error('stream ended before receiving a session lifecycle event');
206
209
  return result.value;
207
210
  }
211
+ /**
212
+ * @deprecated Use {@link changes} — renamed for parity with python-sdk's
213
+ * `SessionLifecycleWatcher.changes()` and the uniform `changes()` name
214
+ * used by all other watchers in both SDKs. Will be removed in 0.5.0.
215
+ */
216
+ async *events(signal) {
217
+ if (!this.deprecatedEventsWarned) {
218
+ this.deprecatedEventsWarned = true;
219
+ logging_1.logger.warn('[deprecated] SessionLifecycleWatcher.events() — use changes() instead');
220
+ }
221
+ yield* this.changes(signal);
222
+ }
223
+ /**
224
+ * @deprecated Use {@link nextChange}. Will be removed in 0.5.0.
225
+ */
226
+ async nextEvent() {
227
+ if (!this.deprecatedNextEventWarned) {
228
+ this.deprecatedNextEventWarned = true;
229
+ logging_1.logger.warn('[deprecated] SessionLifecycleWatcher.nextEvent() — use nextChange() instead');
230
+ }
231
+ return this.nextChange();
232
+ }
208
233
  }
209
234
  exports.SessionLifecycleWatcher = SessionLifecycleWatcher;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "macp-sdk-typescript",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
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.1",
58
+ "@multiagentcoordinationprotocol/proto": "^0.1.2",
59
59
  "protobufjs": "^8.0.0"
60
60
  },
61
61
  "devDependencies": {