macp-sdk-typescript 0.2.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/CHANGELOG.md +73 -0
- package/LICENSE +201 -0
- package/README.md +307 -0
- package/dist/agent/dispatcher.d.ts +16 -0
- package/dist/agent/dispatcher.js +61 -0
- package/dist/agent/index.d.ts +6 -0
- package/dist/agent/index.js +25 -0
- package/dist/agent/participant.d.ts +38 -0
- package/dist/agent/participant.js +221 -0
- package/dist/agent/runner.d.ts +18 -0
- package/dist/agent/runner.js +84 -0
- package/dist/agent/strategies.d.ts +40 -0
- package/dist/agent/strategies.js +106 -0
- package/dist/agent/transports.d.ts +35 -0
- package/dist/agent/transports.js +125 -0
- package/dist/agent/types.d.ts +72 -0
- package/dist/agent/types.js +2 -0
- package/dist/auth.d.ts +52 -0
- package/dist/auth.js +112 -0
- package/dist/client.d.ts +171 -0
- package/dist/client.js +384 -0
- package/dist/constants.d.ts +26 -0
- package/dist/constants.js +29 -0
- package/dist/decision.d.ts +65 -0
- package/dist/decision.js +148 -0
- package/dist/envelope.d.ts +50 -0
- package/dist/envelope.js +97 -0
- package/dist/errors.d.ts +44 -0
- package/dist/errors.js +114 -0
- package/dist/handoff.d.ts +73 -0
- package/dist/handoff.js +160 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +57 -0
- package/dist/policy.d.ts +76 -0
- package/dist/policy.js +118 -0
- package/dist/projections/decision.d.ts +49 -0
- package/dist/projections/decision.js +132 -0
- package/dist/projections/handoff.d.ts +28 -0
- package/dist/projections/handoff.js +111 -0
- package/dist/projections/proposal.d.ts +40 -0
- package/dist/projections/proposal.js +123 -0
- package/dist/projections/quorum.d.ts +36 -0
- package/dist/projections/quorum.js +107 -0
- package/dist/projections/task.d.ts +54 -0
- package/dist/projections/task.js +127 -0
- package/dist/projections.d.ts +5 -0
- package/dist/projections.js +21 -0
- package/dist/proposal.d.ts +69 -0
- package/dist/proposal.js +155 -0
- package/dist/proto-registry.d.ts +12 -0
- package/dist/proto-registry.js +165 -0
- package/dist/quorum.d.ts +65 -0
- package/dist/quorum.js +144 -0
- package/dist/retry.d.ts +14 -0
- package/dist/retry.js +48 -0
- package/dist/task.d.ts +73 -0
- package/dist/task.js +166 -0
- package/dist/types.d.ts +263 -0
- package/dist/types.js +2 -0
- package/dist/validation.d.ts +17 -0
- package/dist/validation.js +92 -0
- package/dist/watchers.d.ts +47 -0
- package/dist/watchers.js +176 -0
- package/package.json +72 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
export interface Root {
|
|
2
|
+
uri: string;
|
|
3
|
+
name?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface Envelope {
|
|
6
|
+
macpVersion: string;
|
|
7
|
+
mode: string;
|
|
8
|
+
messageType: string;
|
|
9
|
+
messageId: string;
|
|
10
|
+
sessionId: string;
|
|
11
|
+
sender: string;
|
|
12
|
+
timestampUnixMs: string;
|
|
13
|
+
payload: Buffer;
|
|
14
|
+
}
|
|
15
|
+
export interface MacpErrorShape {
|
|
16
|
+
code: string;
|
|
17
|
+
message: string;
|
|
18
|
+
sessionId?: string;
|
|
19
|
+
messageId?: string;
|
|
20
|
+
details?: Buffer;
|
|
21
|
+
}
|
|
22
|
+
export interface Ack {
|
|
23
|
+
ok?: boolean;
|
|
24
|
+
duplicate?: boolean;
|
|
25
|
+
messageId?: string;
|
|
26
|
+
sessionId?: string;
|
|
27
|
+
acceptedAtUnixMs?: string;
|
|
28
|
+
sessionState?: string;
|
|
29
|
+
error?: MacpErrorShape;
|
|
30
|
+
}
|
|
31
|
+
export interface ParticipantActivity {
|
|
32
|
+
participantId: string;
|
|
33
|
+
lastMessageAtUnixMs: string;
|
|
34
|
+
messageCount: number;
|
|
35
|
+
}
|
|
36
|
+
export interface SessionMetadata {
|
|
37
|
+
sessionId?: string;
|
|
38
|
+
mode?: string;
|
|
39
|
+
state?: string;
|
|
40
|
+
startedAtUnixMs?: string;
|
|
41
|
+
expiresAtUnixMs?: string;
|
|
42
|
+
modeVersion?: string;
|
|
43
|
+
configurationVersion?: string;
|
|
44
|
+
policyVersion?: string;
|
|
45
|
+
participants?: string[];
|
|
46
|
+
participantActivity?: ParticipantActivity[];
|
|
47
|
+
initiator?: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ModeDescriptor {
|
|
50
|
+
mode: string;
|
|
51
|
+
modeVersion: string;
|
|
52
|
+
title?: string;
|
|
53
|
+
description?: string;
|
|
54
|
+
determinismClass?: string;
|
|
55
|
+
participantModel?: string;
|
|
56
|
+
messageTypes?: string[];
|
|
57
|
+
terminalMessageTypes?: string[];
|
|
58
|
+
schemaUris?: Record<string, string>;
|
|
59
|
+
}
|
|
60
|
+
export interface TransportEndpoint {
|
|
61
|
+
transport: string;
|
|
62
|
+
uri: string;
|
|
63
|
+
contentTypes?: string[];
|
|
64
|
+
metadata?: Record<string, string>;
|
|
65
|
+
}
|
|
66
|
+
export interface AgentManifest {
|
|
67
|
+
agentId?: string;
|
|
68
|
+
title?: string;
|
|
69
|
+
description?: string;
|
|
70
|
+
supportedModes?: string[];
|
|
71
|
+
inputContentTypes?: string[];
|
|
72
|
+
outputContentTypes?: string[];
|
|
73
|
+
metadata?: Record<string, string>;
|
|
74
|
+
transportEndpoints?: TransportEndpoint[];
|
|
75
|
+
}
|
|
76
|
+
export interface InitializeResult {
|
|
77
|
+
selectedProtocolVersion: string;
|
|
78
|
+
runtimeInfo?: {
|
|
79
|
+
name?: string;
|
|
80
|
+
title?: string;
|
|
81
|
+
version?: string;
|
|
82
|
+
description?: string;
|
|
83
|
+
websiteUrl?: string;
|
|
84
|
+
};
|
|
85
|
+
supportedModes?: string[];
|
|
86
|
+
instructions?: string;
|
|
87
|
+
capabilities?: Record<string, unknown>;
|
|
88
|
+
}
|
|
89
|
+
export interface SessionStartPayload {
|
|
90
|
+
intent: string;
|
|
91
|
+
participants: string[];
|
|
92
|
+
modeVersion: string;
|
|
93
|
+
configurationVersion: string;
|
|
94
|
+
policyVersion?: string;
|
|
95
|
+
ttlMs: number;
|
|
96
|
+
context?: Buffer;
|
|
97
|
+
roots?: Root[];
|
|
98
|
+
}
|
|
99
|
+
export interface CommitmentPayload {
|
|
100
|
+
commitmentId: string;
|
|
101
|
+
action: string;
|
|
102
|
+
authorityScope: string;
|
|
103
|
+
reason: string;
|
|
104
|
+
modeVersion: string;
|
|
105
|
+
policyVersion?: string;
|
|
106
|
+
configurationVersion: string;
|
|
107
|
+
outcomePositive?: boolean;
|
|
108
|
+
}
|
|
109
|
+
export interface SignalPayload {
|
|
110
|
+
signalType: string;
|
|
111
|
+
data?: Buffer;
|
|
112
|
+
confidence?: number;
|
|
113
|
+
correlationSessionId?: string;
|
|
114
|
+
}
|
|
115
|
+
export interface ProgressPayload {
|
|
116
|
+
progressToken: string;
|
|
117
|
+
progress: number;
|
|
118
|
+
total: number;
|
|
119
|
+
message?: string;
|
|
120
|
+
targetMessageId?: string;
|
|
121
|
+
}
|
|
122
|
+
export interface DecisionProposalPayload {
|
|
123
|
+
proposalId: string;
|
|
124
|
+
option: string;
|
|
125
|
+
rationale?: string;
|
|
126
|
+
supportingData?: Buffer;
|
|
127
|
+
}
|
|
128
|
+
export interface DecisionEvaluationPayload {
|
|
129
|
+
proposalId: string;
|
|
130
|
+
recommendation: string;
|
|
131
|
+
confidence: number;
|
|
132
|
+
reason?: string;
|
|
133
|
+
}
|
|
134
|
+
export interface DecisionObjectionPayload {
|
|
135
|
+
proposalId: string;
|
|
136
|
+
reason: string;
|
|
137
|
+
severity?: string;
|
|
138
|
+
}
|
|
139
|
+
export interface DecisionVotePayload {
|
|
140
|
+
proposalId: string;
|
|
141
|
+
vote: string;
|
|
142
|
+
reason?: string;
|
|
143
|
+
}
|
|
144
|
+
export interface ProposalModeProposalPayload {
|
|
145
|
+
proposalId: string;
|
|
146
|
+
title: string;
|
|
147
|
+
summary?: string;
|
|
148
|
+
details?: Buffer;
|
|
149
|
+
tags?: string[];
|
|
150
|
+
}
|
|
151
|
+
export interface CounterProposalPayload {
|
|
152
|
+
proposalId: string;
|
|
153
|
+
supersedesProposalId: string;
|
|
154
|
+
title: string;
|
|
155
|
+
summary?: string;
|
|
156
|
+
details?: Buffer;
|
|
157
|
+
}
|
|
158
|
+
export interface AcceptPayload {
|
|
159
|
+
proposalId: string;
|
|
160
|
+
reason?: string;
|
|
161
|
+
}
|
|
162
|
+
export interface RejectPayload {
|
|
163
|
+
proposalId: string;
|
|
164
|
+
terminal?: boolean;
|
|
165
|
+
reason?: string;
|
|
166
|
+
}
|
|
167
|
+
export interface WithdrawPayload {
|
|
168
|
+
proposalId: string;
|
|
169
|
+
reason?: string;
|
|
170
|
+
}
|
|
171
|
+
export interface TaskRequestPayload {
|
|
172
|
+
taskId: string;
|
|
173
|
+
title: string;
|
|
174
|
+
instructions: string;
|
|
175
|
+
requestedAssignee?: string;
|
|
176
|
+
input?: Buffer;
|
|
177
|
+
deadlineUnixMs?: number;
|
|
178
|
+
}
|
|
179
|
+
export interface TaskAcceptPayload {
|
|
180
|
+
taskId: string;
|
|
181
|
+
assignee: string;
|
|
182
|
+
reason?: string;
|
|
183
|
+
}
|
|
184
|
+
export interface TaskRejectPayload {
|
|
185
|
+
taskId: string;
|
|
186
|
+
assignee: string;
|
|
187
|
+
reason?: string;
|
|
188
|
+
}
|
|
189
|
+
export interface TaskUpdatePayload {
|
|
190
|
+
taskId: string;
|
|
191
|
+
status: string;
|
|
192
|
+
progress: number;
|
|
193
|
+
message?: string;
|
|
194
|
+
partialOutput?: Buffer;
|
|
195
|
+
}
|
|
196
|
+
export interface TaskCompletePayload {
|
|
197
|
+
taskId: string;
|
|
198
|
+
assignee: string;
|
|
199
|
+
output?: Buffer;
|
|
200
|
+
summary?: string;
|
|
201
|
+
}
|
|
202
|
+
export interface TaskFailPayload {
|
|
203
|
+
taskId: string;
|
|
204
|
+
assignee: string;
|
|
205
|
+
errorCode?: string;
|
|
206
|
+
reason?: string;
|
|
207
|
+
retryable?: boolean;
|
|
208
|
+
}
|
|
209
|
+
export interface HandoffOfferPayload {
|
|
210
|
+
handoffId: string;
|
|
211
|
+
targetParticipant: string;
|
|
212
|
+
scope?: string;
|
|
213
|
+
reason?: string;
|
|
214
|
+
}
|
|
215
|
+
export interface HandoffContextPayload {
|
|
216
|
+
handoffId: string;
|
|
217
|
+
contentType: string;
|
|
218
|
+
context?: Buffer;
|
|
219
|
+
}
|
|
220
|
+
export interface HandoffAcceptPayload {
|
|
221
|
+
handoffId: string;
|
|
222
|
+
acceptedBy: string;
|
|
223
|
+
reason?: string;
|
|
224
|
+
}
|
|
225
|
+
export interface HandoffDeclinePayload {
|
|
226
|
+
handoffId: string;
|
|
227
|
+
declinedBy: string;
|
|
228
|
+
reason?: string;
|
|
229
|
+
}
|
|
230
|
+
export interface ApprovalRequestPayload {
|
|
231
|
+
requestId: string;
|
|
232
|
+
action: string;
|
|
233
|
+
summary: string;
|
|
234
|
+
details?: Buffer;
|
|
235
|
+
requiredApprovals: number;
|
|
236
|
+
}
|
|
237
|
+
export interface ApprovePayload {
|
|
238
|
+
requestId: string;
|
|
239
|
+
reason?: string;
|
|
240
|
+
}
|
|
241
|
+
export interface QuorumRejectPayload {
|
|
242
|
+
requestId: string;
|
|
243
|
+
reason?: string;
|
|
244
|
+
}
|
|
245
|
+
export interface AbstainPayload {
|
|
246
|
+
requestId: string;
|
|
247
|
+
reason?: string;
|
|
248
|
+
}
|
|
249
|
+
export interface PolicyDescriptor {
|
|
250
|
+
policyId: string;
|
|
251
|
+
mode: string;
|
|
252
|
+
description: string;
|
|
253
|
+
rules: Buffer | Uint8Array;
|
|
254
|
+
schemaVersion: number;
|
|
255
|
+
registeredAtUnixMs?: number;
|
|
256
|
+
}
|
|
257
|
+
export interface RegistryChanged {
|
|
258
|
+
registry: string;
|
|
259
|
+
observedAtUnixMs: string;
|
|
260
|
+
}
|
|
261
|
+
export interface RootsChanged {
|
|
262
|
+
observedAtUnixMs: string;
|
|
263
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare function validateSessionId(sid: string): void;
|
|
2
|
+
export declare function validateVote(value: string): string;
|
|
3
|
+
export declare function validateRecommendation(value: string): string;
|
|
4
|
+
export declare function validateConfidence(value: number): void;
|
|
5
|
+
export declare function validateSeverity(value: string): string;
|
|
6
|
+
export declare function validateParticipantCount(count: number): void;
|
|
7
|
+
export declare function validateSignalType(signalType: string, data?: Buffer | Uint8Array): void;
|
|
8
|
+
export declare function validateTtlMs(ttlMs: number): void;
|
|
9
|
+
export declare function validateParticipants(participants: string[]): void;
|
|
10
|
+
export declare function validateRequiredField(fieldName: string, value: string): void;
|
|
11
|
+
export declare function validateSessionStart(input: {
|
|
12
|
+
intent: string;
|
|
13
|
+
participants: string[];
|
|
14
|
+
ttlMs: number;
|
|
15
|
+
modeVersion: string;
|
|
16
|
+
configurationVersion: string;
|
|
17
|
+
}): void;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSessionId = validateSessionId;
|
|
4
|
+
exports.validateVote = validateVote;
|
|
5
|
+
exports.validateRecommendation = validateRecommendation;
|
|
6
|
+
exports.validateConfidence = validateConfidence;
|
|
7
|
+
exports.validateSeverity = validateSeverity;
|
|
8
|
+
exports.validateParticipantCount = validateParticipantCount;
|
|
9
|
+
exports.validateSignalType = validateSignalType;
|
|
10
|
+
exports.validateTtlMs = validateTtlMs;
|
|
11
|
+
exports.validateParticipants = validateParticipants;
|
|
12
|
+
exports.validateRequiredField = validateRequiredField;
|
|
13
|
+
exports.validateSessionStart = validateSessionStart;
|
|
14
|
+
const errors_1 = require("./errors");
|
|
15
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
16
|
+
const BASE64URL_RE = /^[A-Za-z0-9_-]{22,}$/;
|
|
17
|
+
function validateSessionId(sid) {
|
|
18
|
+
if (!UUID_RE.test(sid) && !BASE64URL_RE.test(sid)) {
|
|
19
|
+
throw new errors_1.MacpSessionError(`session_id must be UUID v4/v7 or base64url (22+ chars), got: ${sid}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const VALID_VOTES = new Set(['APPROVE', 'REJECT', 'ABSTAIN']);
|
|
23
|
+
function validateVote(value) {
|
|
24
|
+
const normalized = value.toUpperCase();
|
|
25
|
+
if (!VALID_VOTES.has(normalized)) {
|
|
26
|
+
throw new errors_1.MacpSessionError(`invalid vote value '${value}': must be one of APPROVE, REJECT, ABSTAIN`);
|
|
27
|
+
}
|
|
28
|
+
return normalized;
|
|
29
|
+
}
|
|
30
|
+
const VALID_RECOMMENDATIONS = new Set(['APPROVE', 'REVIEW', 'BLOCK', 'REJECT']);
|
|
31
|
+
function validateRecommendation(value) {
|
|
32
|
+
const normalized = value.toUpperCase();
|
|
33
|
+
if (!VALID_RECOMMENDATIONS.has(normalized)) {
|
|
34
|
+
throw new errors_1.MacpSessionError(`invalid recommendation '${value}': must be one of APPROVE, REVIEW, BLOCK, REJECT`);
|
|
35
|
+
}
|
|
36
|
+
return normalized;
|
|
37
|
+
}
|
|
38
|
+
function validateConfidence(value) {
|
|
39
|
+
if (value < 0.0 || value > 1.0) {
|
|
40
|
+
throw new errors_1.MacpSessionError(`confidence must be in [0.0, 1.0], got ${value}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const VALID_SEVERITIES = new Set(['critical', 'high', 'medium', 'low']);
|
|
44
|
+
function validateSeverity(value) {
|
|
45
|
+
const normalized = value.toLowerCase();
|
|
46
|
+
if (!VALID_SEVERITIES.has(normalized)) {
|
|
47
|
+
throw new errors_1.MacpSessionError(`invalid severity '${value}': must be one of critical, high, medium, low`);
|
|
48
|
+
}
|
|
49
|
+
return normalized;
|
|
50
|
+
}
|
|
51
|
+
const MAX_PARTICIPANTS = 1000;
|
|
52
|
+
function validateParticipantCount(count) {
|
|
53
|
+
if (count > MAX_PARTICIPANTS) {
|
|
54
|
+
throw new errors_1.MacpSessionError(`Maximum ${MAX_PARTICIPANTS} participants per session`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function validateSignalType(signalType, data) {
|
|
58
|
+
if (data && data.length > 0 && !signalType.trim()) {
|
|
59
|
+
throw new errors_1.MacpSessionError('signalType must be non-empty when data is present');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const MAX_TTL_MS = 86_400_000; // 24 hours
|
|
63
|
+
function validateTtlMs(ttlMs) {
|
|
64
|
+
if (!Number.isFinite(ttlMs) || ttlMs < 1 || ttlMs > MAX_TTL_MS) {
|
|
65
|
+
throw new errors_1.MacpSessionError(`ttl_ms must be in [1, ${MAX_TTL_MS}], got ${ttlMs}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function validateParticipants(participants) {
|
|
69
|
+
if (!participants.length) {
|
|
70
|
+
throw new errors_1.MacpSessionError('participants must be non-empty');
|
|
71
|
+
}
|
|
72
|
+
const seen = new Set();
|
|
73
|
+
for (const p of participants) {
|
|
74
|
+
if (seen.has(p)) {
|
|
75
|
+
throw new errors_1.MacpSessionError(`duplicate participant: ${p}`);
|
|
76
|
+
}
|
|
77
|
+
seen.add(p);
|
|
78
|
+
}
|
|
79
|
+
validateParticipantCount(participants.length);
|
|
80
|
+
}
|
|
81
|
+
function validateRequiredField(fieldName, value) {
|
|
82
|
+
if (!value?.trim()) {
|
|
83
|
+
throw new errors_1.MacpSessionError(`${fieldName} must be non-empty`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function validateSessionStart(input) {
|
|
87
|
+
validateRequiredField('intent', input.intent);
|
|
88
|
+
validateParticipants(input.participants);
|
|
89
|
+
validateTtlMs(input.ttlMs);
|
|
90
|
+
validateRequiredField('modeVersion', input.modeVersion);
|
|
91
|
+
validateRequiredField('configurationVersion', input.configurationVersion);
|
|
92
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AuthConfig } from './auth';
|
|
2
|
+
import type { MacpClient } from './client';
|
|
3
|
+
import type { Envelope, PolicyDescriptor, RegistryChanged, RootsChanged } from './types';
|
|
4
|
+
export declare class ModeRegistryWatcher {
|
|
5
|
+
private readonly client;
|
|
6
|
+
private readonly auth?;
|
|
7
|
+
constructor(client: MacpClient, options?: {
|
|
8
|
+
auth?: AuthConfig;
|
|
9
|
+
});
|
|
10
|
+
changes(signal?: AbortSignal): AsyncGenerator<RegistryChanged, void, void>;
|
|
11
|
+
watch(handler: (change: RegistryChanged) => void | Promise<void>): Promise<void>;
|
|
12
|
+
nextChange(): Promise<RegistryChanged>;
|
|
13
|
+
}
|
|
14
|
+
export declare class RootsWatcher {
|
|
15
|
+
private readonly client;
|
|
16
|
+
private readonly auth?;
|
|
17
|
+
constructor(client: MacpClient, options?: {
|
|
18
|
+
auth?: AuthConfig;
|
|
19
|
+
});
|
|
20
|
+
changes(signal?: AbortSignal): AsyncGenerator<RootsChanged, void, void>;
|
|
21
|
+
watch(handler: (change: RootsChanged) => void | Promise<void>): Promise<void>;
|
|
22
|
+
nextChange(): Promise<RootsChanged>;
|
|
23
|
+
}
|
|
24
|
+
export declare class SignalWatcher {
|
|
25
|
+
private readonly client;
|
|
26
|
+
private readonly auth?;
|
|
27
|
+
constructor(client: MacpClient, options?: {
|
|
28
|
+
auth?: AuthConfig;
|
|
29
|
+
});
|
|
30
|
+
signals(signal?: AbortSignal): AsyncGenerator<Envelope, void, void>;
|
|
31
|
+
watch(handler: (envelope: Envelope) => void | Promise<void>): Promise<void>;
|
|
32
|
+
nextSignal(): Promise<Envelope>;
|
|
33
|
+
}
|
|
34
|
+
export interface PolicyChange {
|
|
35
|
+
descriptors: PolicyDescriptor[];
|
|
36
|
+
observedAtUnixMs: number;
|
|
37
|
+
}
|
|
38
|
+
export declare class PolicyWatcher {
|
|
39
|
+
private readonly client;
|
|
40
|
+
private readonly auth?;
|
|
41
|
+
constructor(client: MacpClient, options?: {
|
|
42
|
+
auth?: AuthConfig;
|
|
43
|
+
});
|
|
44
|
+
changes(signal?: AbortSignal): AsyncGenerator<PolicyChange, void, void>;
|
|
45
|
+
watch(handler: (change: PolicyChange) => void | Promise<void>): Promise<void>;
|
|
46
|
+
nextChange(): Promise<PolicyChange>;
|
|
47
|
+
}
|
package/dist/watchers.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PolicyWatcher = exports.SignalWatcher = exports.RootsWatcher = exports.ModeRegistryWatcher = void 0;
|
|
4
|
+
function serverStreamToAsyncGenerator(stream) {
|
|
5
|
+
const queue = [];
|
|
6
|
+
let resolve = null;
|
|
7
|
+
stream.on('data', (data) => {
|
|
8
|
+
queue.push({ value: data });
|
|
9
|
+
if (resolve) {
|
|
10
|
+
resolve();
|
|
11
|
+
resolve = null;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
stream.on('error', (error) => {
|
|
15
|
+
queue.push({ error });
|
|
16
|
+
if (resolve) {
|
|
17
|
+
resolve();
|
|
18
|
+
resolve = null;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
stream.on('end', () => {
|
|
22
|
+
queue.push({ done: true });
|
|
23
|
+
if (resolve) {
|
|
24
|
+
resolve();
|
|
25
|
+
resolve = null;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
[Symbol.asyncIterator]() {
|
|
30
|
+
return this;
|
|
31
|
+
},
|
|
32
|
+
async next() {
|
|
33
|
+
while (true) {
|
|
34
|
+
const item = queue.shift();
|
|
35
|
+
if (item) {
|
|
36
|
+
if ('done' in item)
|
|
37
|
+
return { value: undefined, done: true };
|
|
38
|
+
if ('error' in item)
|
|
39
|
+
throw item.error;
|
|
40
|
+
return { value: item.value, done: false };
|
|
41
|
+
}
|
|
42
|
+
await new Promise((r) => {
|
|
43
|
+
resolve = r;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
async return() {
|
|
48
|
+
stream.cancel();
|
|
49
|
+
return { value: undefined, done: true };
|
|
50
|
+
},
|
|
51
|
+
async throw(err) {
|
|
52
|
+
stream.cancel();
|
|
53
|
+
throw err;
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
class ModeRegistryWatcher {
|
|
58
|
+
client;
|
|
59
|
+
auth;
|
|
60
|
+
constructor(client, options) {
|
|
61
|
+
this.client = client;
|
|
62
|
+
this.auth = options?.auth;
|
|
63
|
+
}
|
|
64
|
+
async *changes(signal) {
|
|
65
|
+
const stream = this.client.watchModeRegistry(this.auth);
|
|
66
|
+
if (signal) {
|
|
67
|
+
signal.addEventListener('abort', () => stream.cancel(), { once: true });
|
|
68
|
+
}
|
|
69
|
+
yield* serverStreamToAsyncGenerator(stream);
|
|
70
|
+
}
|
|
71
|
+
async watch(handler) {
|
|
72
|
+
for await (const change of this.changes()) {
|
|
73
|
+
await handler(change);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
async nextChange() {
|
|
77
|
+
const gen = this.changes();
|
|
78
|
+
const result = await gen.next();
|
|
79
|
+
await gen.return(undefined);
|
|
80
|
+
if (result.done)
|
|
81
|
+
throw new Error('stream ended before receiving a change');
|
|
82
|
+
return result.value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
exports.ModeRegistryWatcher = ModeRegistryWatcher;
|
|
86
|
+
class RootsWatcher {
|
|
87
|
+
client;
|
|
88
|
+
auth;
|
|
89
|
+
constructor(client, options) {
|
|
90
|
+
this.client = client;
|
|
91
|
+
this.auth = options?.auth;
|
|
92
|
+
}
|
|
93
|
+
async *changes(signal) {
|
|
94
|
+
const stream = this.client.watchRoots(this.auth);
|
|
95
|
+
if (signal) {
|
|
96
|
+
signal.addEventListener('abort', () => stream.cancel(), { once: true });
|
|
97
|
+
}
|
|
98
|
+
yield* serverStreamToAsyncGenerator(stream);
|
|
99
|
+
}
|
|
100
|
+
async watch(handler) {
|
|
101
|
+
for await (const change of this.changes()) {
|
|
102
|
+
await handler(change);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async nextChange() {
|
|
106
|
+
const gen = this.changes();
|
|
107
|
+
const result = await gen.next();
|
|
108
|
+
await gen.return(undefined);
|
|
109
|
+
if (result.done)
|
|
110
|
+
throw new Error('stream ended before receiving a change');
|
|
111
|
+
return result.value;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.RootsWatcher = RootsWatcher;
|
|
115
|
+
class SignalWatcher {
|
|
116
|
+
client;
|
|
117
|
+
auth;
|
|
118
|
+
constructor(client, options) {
|
|
119
|
+
this.client = client;
|
|
120
|
+
this.auth = options?.auth;
|
|
121
|
+
}
|
|
122
|
+
async *signals(signal) {
|
|
123
|
+
const stream = this.client.watchSignals(this.auth);
|
|
124
|
+
if (signal) {
|
|
125
|
+
signal.addEventListener('abort', () => stream.cancel(), { once: true });
|
|
126
|
+
}
|
|
127
|
+
const gen = serverStreamToAsyncGenerator(stream);
|
|
128
|
+
for await (const response of gen) {
|
|
129
|
+
if (response.envelope)
|
|
130
|
+
yield response.envelope;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async watch(handler) {
|
|
134
|
+
for await (const envelope of this.signals()) {
|
|
135
|
+
await handler(envelope);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async nextSignal() {
|
|
139
|
+
const gen = this.signals();
|
|
140
|
+
const result = await gen.next();
|
|
141
|
+
await gen.return(undefined);
|
|
142
|
+
if (result.done)
|
|
143
|
+
throw new Error('stream ended before receiving a signal');
|
|
144
|
+
return result.value;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.SignalWatcher = SignalWatcher;
|
|
148
|
+
class PolicyWatcher {
|
|
149
|
+
client;
|
|
150
|
+
auth;
|
|
151
|
+
constructor(client, options) {
|
|
152
|
+
this.client = client;
|
|
153
|
+
this.auth = options?.auth;
|
|
154
|
+
}
|
|
155
|
+
async *changes(signal) {
|
|
156
|
+
const stream = this.client.watchPolicies(this.auth);
|
|
157
|
+
if (signal) {
|
|
158
|
+
signal.addEventListener('abort', () => stream.cancel(), { once: true });
|
|
159
|
+
}
|
|
160
|
+
yield* serverStreamToAsyncGenerator(stream);
|
|
161
|
+
}
|
|
162
|
+
async watch(handler) {
|
|
163
|
+
for await (const change of this.changes()) {
|
|
164
|
+
await handler(change);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
async nextChange() {
|
|
168
|
+
const gen = this.changes();
|
|
169
|
+
const result = await gen.next();
|
|
170
|
+
await gen.return(undefined);
|
|
171
|
+
if (result.done)
|
|
172
|
+
throw new Error('stream ended before receiving a policy change');
|
|
173
|
+
return result.value;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
exports.PolicyWatcher = PolicyWatcher;
|
package/package.json
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "macp-sdk-typescript",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "TypeScript SDK for the MACP Rust runtime",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "commonjs",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"CHANGELOG.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -p tsconfig.json",
|
|
23
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
24
|
+
"lint": "eslint src/",
|
|
25
|
+
"lint:fix": "eslint src/ --fix",
|
|
26
|
+
"format": "prettier --write 'src/**/*.ts' 'tests/**/*.ts' --ignore-unknown",
|
|
27
|
+
"format:check": "prettier --check 'src/**/*.ts' 'tests/**/*.ts' --ignore-unknown",
|
|
28
|
+
"test": "vitest run --config vitest.config.ts",
|
|
29
|
+
"test:watch": "vitest --config vitest.config.ts",
|
|
30
|
+
"test:coverage": "vitest run --coverage --config vitest.config.ts",
|
|
31
|
+
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
32
|
+
"example:decision": "tsx examples/decision-smoke.ts",
|
|
33
|
+
"example:proposal": "tsx examples/proposal-smoke.ts",
|
|
34
|
+
"example:task": "tsx examples/task-smoke.ts",
|
|
35
|
+
"example:handoff": "tsx examples/handoff-smoke.ts",
|
|
36
|
+
"example:quorum": "tsx examples/quorum-smoke.ts",
|
|
37
|
+
"example:watch": "tsx examples/watch-smoke.ts",
|
|
38
|
+
"example:bearer": "tsx examples/bearer-smoke.ts",
|
|
39
|
+
"prepublishOnly": "npm run check && npm run lint && npm run format:check && npm test && npm run build"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"macp",
|
|
46
|
+
"multi-agent",
|
|
47
|
+
"coordination",
|
|
48
|
+
"grpc",
|
|
49
|
+
"protocol"
|
|
50
|
+
],
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "https://github.com/multiagentcoordinationprotocol/typescript-sdk.git"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@grpc/grpc-js": "^1.14.3",
|
|
57
|
+
"@grpc/proto-loader": "^0.8.0",
|
|
58
|
+
"@multiagentcoordinationprotocol/proto": "^0.1.0",
|
|
59
|
+
"protobufjs": "^8.0.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@types/node": "^22.14.0",
|
|
63
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
64
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
65
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
66
|
+
"eslint": "^9.0.0",
|
|
67
|
+
"prettier": "^3.0.0",
|
|
68
|
+
"tsx": "^4.21.0",
|
|
69
|
+
"typescript": "^5.8.3",
|
|
70
|
+
"vitest": "^3.0.0"
|
|
71
|
+
}
|
|
72
|
+
}
|