macp-sdk-typescript 0.18.0 → 0.20.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 +15 -0
- package/README.md +35 -1
- package/dist/client.d.ts +73 -1
- package/dist/client.js +119 -1
- package/dist/constants.d.ts +12 -0
- package/dist/constants.js +13 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/receipt.d.ts +42 -0
- package/dist/receipt.js +52 -0
- package/dist/types.d.ts +76 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,21 @@ All notable changes to `macp-sdk-typescript` are documented here. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
|
|
5
5
|
project uses [Semantic Versioning](https://semver.org/).
|
|
6
6
|
|
|
7
|
+
## [0.20.0](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/compare/v0.19.0...v0.20.0) (2026-10-26)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* runtime-issued decision receipts — getDecisionReceipt, getReceiptKeys, trustedKeysFromJwks (RFC-MACP-0013 §13) ([#210](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/issues/210)) ([931d9e1](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/931d9e13d7695a9f4659d0538e85dcb709eaeb20))
|
|
13
|
+
|
|
14
|
+
## [0.19.0](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/compare/v0.18.0...v0.19.0) (2026-10-26)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### Features
|
|
18
|
+
|
|
19
|
+
* capability-gated whatIfReplay and HISTORY_UNAVAILABLE (RFC-MACP-0012 §8.1) ([c5bc5cf](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/c5bc5cf6d8206c30f5d69f6fde44800e8d294fa6))
|
|
20
|
+
* **claude-agent-sdk:** Claude Agent SDK subagents reach a binding MACP decision (W3.5) ([573bf33](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/commit/573bf335d433ad13bcb5668d1563b67494df4442))
|
|
21
|
+
|
|
7
22
|
## [0.18.0](https://github.com/multiagentcoordinationprotocol/macp-sdk-typescript/compare/v0.17.1...v0.18.0) (2026-10-25)
|
|
8
23
|
|
|
9
24
|
|
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ client.close();
|
|
|
72
72
|
|
|
73
73
|
The SDK uses a **three-layer** design:
|
|
74
74
|
|
|
75
|
-
- **Low-level transport** (`MacpClient`): typed wrappers around every `MACPRuntimeService` RPC — `initialize`, `send`, `openStream`, `getSession`, `cancelSession`, `suspendSession`, `resumeSession`, `listSessions`, `getManifest`, `listModes`, `listRoots`, `listExtModes`, `registerExtMode`, `unregisterExtMode`, `promoteMode`, the policy RPCs (`register`/`unregister`/`get`/`listPolicies`), plus streaming watchers (`ModeRegistryWatcher`, `RootsWatcher`, `SignalWatcher`, `PolicyWatcher`, `SessionLifecycleWatcher`).
|
|
75
|
+
- **Low-level transport** (`MacpClient`): typed wrappers around every `MACPRuntimeService` RPC — `initialize`, `send`, `openStream`, `getSession`, `cancelSession`, `suspendSession`, `resumeSession`, `listSessions`, `getManifest`, `listModes`, `listRoots`, `listExtModes`, `registerExtMode`, `unregisterExtMode`, `promoteMode`, the policy RPCs (`register`/`unregister`/`get`/`listPolicies`, and `whatIfReplay` where the runtime advertises it), `getDecisionReceipt`/`getReceiptKeys` where the runtime advertises receipts, plus streaming watchers (`ModeRegistryWatcher`, `RootsWatcher`, `SignalWatcher`, `PolicyWatcher`, `SessionLifecycleWatcher`).
|
|
76
76
|
- **High-level session helpers**: one class per coordination mode (`DecisionSession`, `ProposalSession`, `TaskSession`, `HandoffSession`, `QuorumSession`) — wraps `MacpClient`, builds envelopes, encodes payloads, and maintains a local state projection.
|
|
77
77
|
- **Agent framework** (`src/agent/`): event-driven `Participant` with strategy-based handlers, bootstrap runner (`fromBootstrap`), gRPC/HTTP transports, and the optional cancel-callback HTTP server.
|
|
78
78
|
|
|
@@ -335,6 +335,17 @@ server via `fromBootstrap()`; for the manual path use
|
|
|
335
335
|
See [`docs/api/cancel-callback.md`](docs/api/cancel-callback.md) and
|
|
336
336
|
[`examples/cancel-callback.ts`](examples/cancel-callback.ts).
|
|
337
337
|
|
|
338
|
+
## Framework Integrations
|
|
339
|
+
|
|
340
|
+
Framework adapters live under [`integrations/`](integrations/). Each is a separate npm package
|
|
341
|
+
with its own version and release tag.
|
|
342
|
+
|
|
343
|
+
| Framework | Package | |
|
|
344
|
+
| --- | --- | --- |
|
|
345
|
+
| LangGraph | [`@multiagentcoordinationprotocol/langgraph`](integrations/langgraph/) | `MacpConsensusNode`: a graph node whose participants evaluate and vote through a Decision or Quorum session and write the commitment into graph state |
|
|
346
|
+
| Claude Agent SDK | [`@multiagentcoordinationprotocol/claude-agent-sdk`](integrations/claude-agent-sdk/) | `claudeEvaluator` runs a Claude agent as a participant; `macpConsensusServer` gives a lead agent an `mcp__macp__consensus` tool whose subagents evaluate and vote, returning the commitment |
|
|
347
|
+
| OpenAI Agents SDK | planned | |
|
|
348
|
+
|
|
338
349
|
## Authentication
|
|
339
350
|
|
|
340
351
|
```typescript
|
|
@@ -452,6 +463,29 @@ const result = verifyReceipt(receipt, { 'prod-2026': 'TDVzkxaSf6_Oxu7mmn5TbCkF80
|
|
|
452
463
|
| `attestations[i]` | `valid`, `invalid`, `unknown_key` or `unsupported` (any other `alg`, and every `vendor` attestation) |
|
|
453
464
|
| `verdict` | `attested` (integrity holds and at least one attestation is valid), `integrity_only`, `unverified` (integrity fails, so attestations are not checked), or `refused` (unknown `receipt_format`) |
|
|
454
465
|
|
|
466
|
+
To trust a published key set (a JWK Set, such as a runtime's `GetReceiptKeys` response; RFC-MACP-0013 §13), convert it with `trustedKeysFromJwks(jwks)`:
|
|
467
|
+
|
|
468
|
+
```typescript
|
|
469
|
+
import { trustedKeysFromJwks, verifyReceipt } from 'macp-sdk-typescript/receipt';
|
|
470
|
+
|
|
471
|
+
const trustedKeys = trustedKeysFromJwks(jwks); // { 'example-1': 'TDVzkxaSf6_…' }
|
|
472
|
+
verifyReceipt(receipt, trustedKeys).verdict; // 'attested'
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
It keeps only Ed25519 public keys (`kty` `OKP`, `crv` `Ed25519`) with a `kid` and an `x`, whose `alg` (if any) is `EdDSA` and `use` (if any) is `sig`. It drops a key that carries a private member (`d`, `k`, …) and any `kid` that more than one entry of the set claims, even when the other entry is a key it can't use (an EC key, say). It never throws: anything that isn't a key set gives `{}`. Deciding to trust the set is still up to you.
|
|
476
|
+
|
|
477
|
+
### Fetching a runtime-issued receipt
|
|
478
|
+
|
|
479
|
+
A runtime that advertises `capabilities.decisionReceipt.getDecisionReceipt` issues receipts itself (RFC-MACP-0013 §13). Fetch one for a resolved session, fetch the runtime's key set, and verify:
|
|
480
|
+
|
|
481
|
+
```typescript
|
|
482
|
+
const { receipt, raw } = await client.getDecisionReceipt(sessionId); // raw: the exact bytes served
|
|
483
|
+
const jwks = await client.getReceiptKeys(); // { keys: [] } from an unsigned runtime
|
|
484
|
+
verifyReceipt(receipt, trustedKeysFromJwks(jwks)).verdict; // 'attested', or 'integrity_only' if unsigned
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
Both methods throw `MacpSdkError` without sending anything when the runtime doesn't advertise the capability. A session the runtime can't issue a receipt for (not resolved yet, or resolved without a `CommitmentPayload`) gives `MacpTransportError` with `macpErrorCode` `RECEIPT_UNAVAILABLE`.
|
|
488
|
+
|
|
455
489
|
If you hold the snake_case §3 projection (a receipt's `commitment`) instead of a `CommitmentPayload`, convert it with `commitmentFromProjection(projection)`.
|
|
456
490
|
|
|
457
491
|
`verifyReceipt` never throws. `buildReceipt` throws `MacpSdkError` on a missing field, and when `commitmentWire` is not the wire encoding of the commitment. Signing is deterministic: the same inputs always produce the same receipt.
|
package/dist/client.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as grpc from '@grpc/grpc-js';
|
|
2
2
|
import { type AuthConfig } from './auth';
|
|
3
3
|
import { ProtoRegistry } from './proto-registry';
|
|
4
|
-
import type {
|
|
4
|
+
import type { DecisionReceiptResult, ReceiptKeySet } from './receipt';
|
|
5
|
+
import type { Ack, AgentManifest, Envelope, InitializeResult, ModeDescriptor, PolicyDescriptor, SessionMetadata, Root, WhatIfReplayResult } from './types';
|
|
5
6
|
interface MacpClientOptions {
|
|
6
7
|
address: string;
|
|
7
8
|
/**
|
|
@@ -99,8 +100,21 @@ export declare class MacpClient {
|
|
|
99
100
|
private readonly defaultDeadlineMs?;
|
|
100
101
|
private readonly clientName;
|
|
101
102
|
private readonly clientVersion;
|
|
103
|
+
/** The last {@link initialize} result; capability-gated RPCs read its capabilities. */
|
|
104
|
+
private initializeResult?;
|
|
105
|
+
/** An `Initialize` that {@link requireCapability} started and is still in flight. */
|
|
106
|
+
private pendingInit?;
|
|
107
|
+
/** The runtime's capabilities from the last {@link initialize}; `undefined` before one. */
|
|
108
|
+
get serverCapabilities(): Record<string, unknown> | undefined;
|
|
102
109
|
constructor(options: MacpClientOptions);
|
|
103
110
|
private requireAuth;
|
|
111
|
+
/**
|
|
112
|
+
* Throws {@link MacpSdkError}, without sending anything, unless
|
|
113
|
+
* `capabilities.<group>.<flag>` from {@link initialize} is `true`. Calls
|
|
114
|
+
* `Initialize` once if this client hasn't; concurrent first callers share
|
|
115
|
+
* that one in-flight call (and the first caller's deadline).
|
|
116
|
+
*/
|
|
117
|
+
private requireCapability;
|
|
104
118
|
private metadata;
|
|
105
119
|
private deadline;
|
|
106
120
|
private unary;
|
|
@@ -226,6 +240,64 @@ export declare class MacpClient {
|
|
|
226
240
|
auth?: AuthConfig;
|
|
227
241
|
deadlineMs?: number;
|
|
228
242
|
}): Promise<PolicyDescriptor[]>;
|
|
243
|
+
/**
|
|
244
|
+
* Replay a session's accepted history under a candidate policy and report how
|
|
245
|
+
* the outcome would differ (RFC-MACP-0012 §8.1). Read-only and advisory: the
|
|
246
|
+
* session, its history and the policy registry are untouched, and the
|
|
247
|
+
* candidate is never registered.
|
|
248
|
+
*
|
|
249
|
+
* The RPC is optional, so this checks `capabilities.policyRegistry.whatIfReplay`
|
|
250
|
+
* from {@link initialize} first (calling it once if this client hasn't) and
|
|
251
|
+
* throws {@link MacpSdkError} without sending anything when the runtime
|
|
252
|
+
* doesn't advertise it. Runtime refusals arrive as {@link MacpTransportError}
|
|
253
|
+
* with `macpErrorCode` set: `SESSION_NOT_FOUND`, `FORBIDDEN` (authorized as
|
|
254
|
+
* {@link getSession}), `INVALID_POLICY_DEFINITION` (the candidate fails
|
|
255
|
+
* RegisterPolicy admission, or its mode is neither the session's nor `*`),
|
|
256
|
+
* `HISTORY_UNAVAILABLE` (history compacted), `INTERNAL_ERROR`.
|
|
257
|
+
*/
|
|
258
|
+
whatIfReplay(sessionId: string, candidate: PolicyDescriptor, options?: {
|
|
259
|
+
auth?: AuthConfig;
|
|
260
|
+
deadlineMs?: number;
|
|
261
|
+
}): Promise<WhatIfReplayResult>;
|
|
262
|
+
/**
|
|
263
|
+
* Fetch the runtime-issued decision receipt for a resolved session
|
|
264
|
+
* (RFC-MACP-0013 §13). Returns the parsed `macp-receipt/1` object and `raw`,
|
|
265
|
+
* the exact JSON text the runtime served, which is stable across calls
|
|
266
|
+
* (§13 item 6), so it can be stored or forwarded byte for byte. Verify it
|
|
267
|
+
* with `verifyReceipt(receipt, trustedKeysFromJwks(await getReceiptKeys()))`;
|
|
268
|
+
* this method does not.
|
|
269
|
+
*
|
|
270
|
+
* The RPC is optional, so this checks
|
|
271
|
+
* `capabilities.decisionReceipt.getDecisionReceipt` from {@link initialize}
|
|
272
|
+
* first (calling it once if this client hasn't) and throws
|
|
273
|
+
* {@link MacpSdkError} without sending anything when the runtime doesn't
|
|
274
|
+
* advertise it. Authorized as {@link getSession}. Runtime refusals arrive as
|
|
275
|
+
* {@link MacpTransportError} with `macpErrorCode` set: `RECEIPT_UNAVAILABLE`
|
|
276
|
+
* (no receipt can be issued: not resolved yet, or resolved without a
|
|
277
|
+
* `CommitmentPayload`), `SESSION_NOT_FOUND`, `FORBIDDEN`,
|
|
278
|
+
* `INTERNAL_ERROR`. A `receipt_json` that isn't a JSON object throws
|
|
279
|
+
* {@link MacpSdkError}.
|
|
280
|
+
*/
|
|
281
|
+
getDecisionReceipt(sessionId: string, options?: {
|
|
282
|
+
auth?: AuthConfig;
|
|
283
|
+
deadlineMs?: number;
|
|
284
|
+
}): Promise<DecisionReceiptResult>;
|
|
285
|
+
/**
|
|
286
|
+
* Fetch the JWK Set of public keys the runtime signs receipts with
|
|
287
|
+
* (RFC-MACP-0013 §13 item 8); an unsigned runtime returns `{keys: []}`. Pass
|
|
288
|
+
* it to `trustedKeysFromJwks` for the map `verifyReceipt` takes. Whether
|
|
289
|
+
* to trust these keys is the caller's decision.
|
|
290
|
+
*
|
|
291
|
+
* Gated on `capabilities.decisionReceipt.getDecisionReceipt` like
|
|
292
|
+
* {@link getDecisionReceipt}. Needs transport auth only, like
|
|
293
|
+
* {@link getManifest}: `auth` is optional and falls back to the client's.
|
|
294
|
+
* A `jwks_json` that isn't a JSON object with a `keys` array throws
|
|
295
|
+
* {@link MacpSdkError}.
|
|
296
|
+
*/
|
|
297
|
+
getReceiptKeys(options?: {
|
|
298
|
+
auth?: AuthConfig;
|
|
299
|
+
deadlineMs?: number;
|
|
300
|
+
}): Promise<ReceiptKeySet>;
|
|
229
301
|
/**
|
|
230
302
|
* Fetch a single page of sessions (proto ≥ 0.1.6). `pageSize: 0` (or absent)
|
|
231
303
|
* lets the server choose the page size; the server MAY cap it. Callers MUST
|
package/dist/client.js
CHANGED
|
@@ -276,6 +276,14 @@ class MacpClient {
|
|
|
276
276
|
defaultDeadlineMs;
|
|
277
277
|
clientName;
|
|
278
278
|
clientVersion;
|
|
279
|
+
/** The last {@link initialize} result; capability-gated RPCs read its capabilities. */
|
|
280
|
+
initializeResult;
|
|
281
|
+
/** An `Initialize` that {@link requireCapability} started and is still in flight. */
|
|
282
|
+
pendingInit;
|
|
283
|
+
/** The runtime's capabilities from the last {@link initialize}; `undefined` before one. */
|
|
284
|
+
get serverCapabilities() {
|
|
285
|
+
return this.initializeResult?.capabilities;
|
|
286
|
+
}
|
|
279
287
|
constructor(options) {
|
|
280
288
|
this.auth = options.auth;
|
|
281
289
|
this.secure = options.secure ?? true;
|
|
@@ -314,6 +322,23 @@ class MacpClient {
|
|
|
314
322
|
throw new errors_1.MacpSdkError('this operation requires auth; pass auth= or configure client.auth');
|
|
315
323
|
return selected;
|
|
316
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* Throws {@link MacpSdkError}, without sending anything, unless
|
|
327
|
+
* `capabilities.<group>.<flag>` from {@link initialize} is `true`. Calls
|
|
328
|
+
* `Initialize` once if this client hasn't; concurrent first callers share
|
|
329
|
+
* that one in-flight call (and the first caller's deadline).
|
|
330
|
+
*/
|
|
331
|
+
async requireCapability(group, flag, rpc, rfc, deadlineMs) {
|
|
332
|
+
const capabilities = this.serverCapabilities ??
|
|
333
|
+
(await (this.pendingInit ??= this.initialize(deadlineMs).finally(() => {
|
|
334
|
+
this.pendingInit = undefined;
|
|
335
|
+
}))).capabilities;
|
|
336
|
+
const advertised = capabilities?.[group];
|
|
337
|
+
if (advertised?.[flag] !== true) {
|
|
338
|
+
throw new errors_1.MacpSdkError(`this runtime does not advertise capabilities.${group}.${flag}; ` +
|
|
339
|
+
`${rpc} is optional and a client MUST NOT call it otherwise (${rfc})`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
317
342
|
metadata(auth) {
|
|
318
343
|
const selected = auth ?? this.auth;
|
|
319
344
|
if (!selected)
|
|
@@ -360,7 +385,7 @@ class MacpClient {
|
|
|
360
385
|
});
|
|
361
386
|
}
|
|
362
387
|
async initialize(deadlineMs) {
|
|
363
|
-
|
|
388
|
+
const result = await this.unary('Initialize', {
|
|
364
389
|
supportedProtocolVersions: ['1.0'],
|
|
365
390
|
clientInfo: {
|
|
366
391
|
name: this.clientName,
|
|
@@ -380,6 +405,8 @@ class MacpClient {
|
|
|
380
405
|
experimental: { features: {} },
|
|
381
406
|
},
|
|
382
407
|
}, undefined, deadlineMs);
|
|
408
|
+
this.initializeResult = result;
|
|
409
|
+
return result;
|
|
383
410
|
}
|
|
384
411
|
async send(envelope, options) {
|
|
385
412
|
const auth = this.requireAuth(options?.auth);
|
|
@@ -513,6 +540,83 @@ class MacpClient {
|
|
|
513
540
|
const res = await this.unary('ListPolicies', { mode: mode || '' }, auth, options?.deadlineMs);
|
|
514
541
|
return res.descriptors || [];
|
|
515
542
|
}
|
|
543
|
+
/**
|
|
544
|
+
* Replay a session's accepted history under a candidate policy and report how
|
|
545
|
+
* the outcome would differ (RFC-MACP-0012 §8.1). Read-only and advisory: the
|
|
546
|
+
* session, its history and the policy registry are untouched, and the
|
|
547
|
+
* candidate is never registered.
|
|
548
|
+
*
|
|
549
|
+
* The RPC is optional, so this checks `capabilities.policyRegistry.whatIfReplay`
|
|
550
|
+
* from {@link initialize} first (calling it once if this client hasn't) and
|
|
551
|
+
* throws {@link MacpSdkError} without sending anything when the runtime
|
|
552
|
+
* doesn't advertise it. Runtime refusals arrive as {@link MacpTransportError}
|
|
553
|
+
* with `macpErrorCode` set: `SESSION_NOT_FOUND`, `FORBIDDEN` (authorized as
|
|
554
|
+
* {@link getSession}), `INVALID_POLICY_DEFINITION` (the candidate fails
|
|
555
|
+
* RegisterPolicy admission, or its mode is neither the session's nor `*`),
|
|
556
|
+
* `HISTORY_UNAVAILABLE` (history compacted), `INTERNAL_ERROR`.
|
|
557
|
+
*/
|
|
558
|
+
async whatIfReplay(sessionId, candidate, options) {
|
|
559
|
+
const auth = this.requireAuth(options?.auth);
|
|
560
|
+
await this.requireCapability('policyRegistry', 'whatIfReplay', 'WhatIfReplay', 'RFC-MACP-0012 §8.1', options?.deadlineMs);
|
|
561
|
+
const res = await this.unary('WhatIfReplay', { sessionId, candidate }, auth, options?.deadlineMs);
|
|
562
|
+
// proto3 `optional` decodes with a synthetic oneof discriminator; an unset
|
|
563
|
+
// first_divergence is absent, never "0" (index 0 is the SessionStart).
|
|
564
|
+
const result = {
|
|
565
|
+
...res,
|
|
566
|
+
denials: res.denials ?? [],
|
|
567
|
+
entries: res.entries ?? [],
|
|
568
|
+
};
|
|
569
|
+
delete result._firstDivergence;
|
|
570
|
+
return result;
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Fetch the runtime-issued decision receipt for a resolved session
|
|
574
|
+
* (RFC-MACP-0013 §13). Returns the parsed `macp-receipt/1` object and `raw`,
|
|
575
|
+
* the exact JSON text the runtime served, which is stable across calls
|
|
576
|
+
* (§13 item 6), so it can be stored or forwarded byte for byte. Verify it
|
|
577
|
+
* with `verifyReceipt(receipt, trustedKeysFromJwks(await getReceiptKeys()))`;
|
|
578
|
+
* this method does not.
|
|
579
|
+
*
|
|
580
|
+
* The RPC is optional, so this checks
|
|
581
|
+
* `capabilities.decisionReceipt.getDecisionReceipt` from {@link initialize}
|
|
582
|
+
* first (calling it once if this client hasn't) and throws
|
|
583
|
+
* {@link MacpSdkError} without sending anything when the runtime doesn't
|
|
584
|
+
* advertise it. Authorized as {@link getSession}. Runtime refusals arrive as
|
|
585
|
+
* {@link MacpTransportError} with `macpErrorCode` set: `RECEIPT_UNAVAILABLE`
|
|
586
|
+
* (no receipt can be issued: not resolved yet, or resolved without a
|
|
587
|
+
* `CommitmentPayload`), `SESSION_NOT_FOUND`, `FORBIDDEN`,
|
|
588
|
+
* `INTERNAL_ERROR`. A `receipt_json` that isn't a JSON object throws
|
|
589
|
+
* {@link MacpSdkError}.
|
|
590
|
+
*/
|
|
591
|
+
async getDecisionReceipt(sessionId, options) {
|
|
592
|
+
const auth = this.requireAuth(options?.auth);
|
|
593
|
+
await this.requireCapability('decisionReceipt', 'getDecisionReceipt', 'GetDecisionReceipt', 'RFC-MACP-0013 §13', options?.deadlineMs);
|
|
594
|
+
const res = await this.unary('GetDecisionReceipt', { sessionId }, auth, options?.deadlineMs);
|
|
595
|
+
const raw = res.receiptJson ?? '';
|
|
596
|
+
const receipt = parseJsonObject(raw, 'receipt_json');
|
|
597
|
+
return { receipt: receipt, raw };
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Fetch the JWK Set of public keys the runtime signs receipts with
|
|
601
|
+
* (RFC-MACP-0013 §13 item 8); an unsigned runtime returns `{keys: []}`. Pass
|
|
602
|
+
* it to `trustedKeysFromJwks` for the map `verifyReceipt` takes. Whether
|
|
603
|
+
* to trust these keys is the caller's decision.
|
|
604
|
+
*
|
|
605
|
+
* Gated on `capabilities.decisionReceipt.getDecisionReceipt` like
|
|
606
|
+
* {@link getDecisionReceipt}. Needs transport auth only, like
|
|
607
|
+
* {@link getManifest}: `auth` is optional and falls back to the client's.
|
|
608
|
+
* A `jwks_json` that isn't a JSON object with a `keys` array throws
|
|
609
|
+
* {@link MacpSdkError}.
|
|
610
|
+
*/
|
|
611
|
+
async getReceiptKeys(options) {
|
|
612
|
+
await this.requireCapability('decisionReceipt', 'getDecisionReceipt', 'GetReceiptKeys', 'RFC-MACP-0013 §13', options?.deadlineMs);
|
|
613
|
+
const res = await this.unary('GetReceiptKeys', {}, options?.auth, options?.deadlineMs);
|
|
614
|
+
const jwks = parseJsonObject(res.jwksJson ?? '', 'jwks_json');
|
|
615
|
+
if (!Array.isArray(jwks.keys)) {
|
|
616
|
+
throw new errors_1.MacpSdkError('runtime returned a jwks_json with no keys array');
|
|
617
|
+
}
|
|
618
|
+
return jwks;
|
|
619
|
+
}
|
|
516
620
|
/**
|
|
517
621
|
* Fetch a single page of sessions (proto ≥ 0.1.6). `pageSize: 0` (or absent)
|
|
518
622
|
* lets the server choose the page size; the server MAY cap it. Callers MUST
|
|
@@ -641,3 +745,17 @@ class MacpClient {
|
|
|
641
745
|
}
|
|
642
746
|
}
|
|
643
747
|
exports.MacpClient = MacpClient;
|
|
748
|
+
/** Parses runtime-served JSON text that must be an object, else throws {@link MacpSdkError}. */
|
|
749
|
+
function parseJsonObject(text, field) {
|
|
750
|
+
let value;
|
|
751
|
+
try {
|
|
752
|
+
value = JSON.parse(text);
|
|
753
|
+
}
|
|
754
|
+
catch (err) {
|
|
755
|
+
throw new errors_1.MacpSdkError(`runtime returned a ${field} that is not valid JSON: ${err.message}`);
|
|
756
|
+
}
|
|
757
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
758
|
+
throw new errors_1.MacpSdkError(`runtime returned a ${field} that is not a JSON object`);
|
|
759
|
+
}
|
|
760
|
+
return value;
|
|
761
|
+
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -37,6 +37,18 @@ export declare const INVALID_REQUEST = "INVALID_REQUEST";
|
|
|
37
37
|
export declare const STREAM_LAGGED = "STREAM_LAGGED";
|
|
38
38
|
/** GetManifest for an agent this runtime does not host — NOT_FOUND. */
|
|
39
39
|
export declare const AGENT_NOT_FOUND = "AGENT_NOT_FOUND";
|
|
40
|
+
/**
|
|
41
|
+
* WhatIfReplay on a session whose full accepted history the runtime no longer
|
|
42
|
+
* holds (e.g. compacted when it ended) — FAILED_PRECONDITION. RFC-MACP-0012 §8.1.
|
|
43
|
+
*/
|
|
44
|
+
export declare const HISTORY_UNAVAILABLE = "HISTORY_UNAVAILABLE";
|
|
45
|
+
/**
|
|
46
|
+
* GetDecisionReceipt named a session no receipt can be issued for: not
|
|
47
|
+
* RESOLVED, resolved without a `CommitmentPayload`, or issuance failed —
|
|
48
|
+
* FAILED_PRECONDITION. RFC-MACP-0013 §13. **Provisional** in the spec's error
|
|
49
|
+
* registry (not yet in the parity contract's permanent set).
|
|
50
|
+
*/
|
|
51
|
+
export declare const RECEIPT_UNAVAILABLE = "RECEIPT_UNAVAILABLE";
|
|
40
52
|
export declare const DENY_VETO = "veto";
|
|
41
53
|
export declare const DENY_VETO_HOLD = "veto_hold";
|
|
42
54
|
export declare const DENY_QUORUM_NOT_MET = "quorum_not_met";
|
package/dist/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.KNOWN_DENY_CODES = exports.DENY_UNSPECIFIED = exports.DENY_INVALID_RULES = exports.DENY_UNSUPPORTED_SCHEMA_VERSION = exports.DENY_REASSIGNMENT_NOT_ALLOWED = exports.DENY_OUTPUT_REQUIRED = exports.DENY_CRITERION_NOT_MET = exports.DENY_DECLINE_NOT_BACKED = exports.DENY_DECLINE_OVER_APPROVAL = exports.DENY_NO_VOTES = exports.DENY_EVALUATION_REQUIRED = exports.DENY_CONFIDENCE_BELOW_MINIMUM = exports.DENY_THRESHOLD_NOT_MET = exports.DENY_QUORUM_NOT_MET = exports.DENY_VETO_HOLD = exports.DENY_VETO = exports.AGENT_NOT_FOUND = exports.STREAM_LAGGED = exports.INVALID_REQUEST = exports.REGISTRY_READ_ONLY = exports.INVALID_POLICY_DEFINITION = exports.UNKNOWN_POLICY_VERSION = exports.INVALID_SESSION_ID = exports.POLICY_DENIED = exports.INTERNAL_ERROR = exports.RATE_LIMITED = exports.PAYLOAD_TOO_LARGE = exports.DUPLICATE_MESSAGE = exports.UNAUTHENTICATED = exports.FORBIDDEN = exports.MODE_NOT_SUPPORTED = exports.SESSION_NOT_OPEN = exports.SESSION_NOT_FOUND = exports.SESSION_ALREADY_EXISTS = exports.INVALID_ENVELOPE = exports.UNSUPPORTED_PROTOCOL_VERSION = exports.STANDARD_MODES = exports.MODE_MULTI_ROUND = exports.MODE_QUORUM = exports.MODE_HANDOFF = exports.MODE_TASK = exports.MODE_PROPOSAL = exports.MODE_DECISION = exports.DEFAULT_POLICY_VERSION = exports.DEFAULT_CONFIGURATION_VERSION = exports.DEFAULT_MODE_VERSION = exports.MACP_VERSION = void 0;
|
|
3
|
+
exports.KNOWN_DENY_CODES = exports.DENY_UNSPECIFIED = exports.DENY_INVALID_RULES = exports.DENY_UNSUPPORTED_SCHEMA_VERSION = exports.DENY_REASSIGNMENT_NOT_ALLOWED = exports.DENY_OUTPUT_REQUIRED = exports.DENY_CRITERION_NOT_MET = exports.DENY_DECLINE_NOT_BACKED = exports.DENY_DECLINE_OVER_APPROVAL = exports.DENY_NO_VOTES = exports.DENY_EVALUATION_REQUIRED = exports.DENY_CONFIDENCE_BELOW_MINIMUM = exports.DENY_THRESHOLD_NOT_MET = exports.DENY_QUORUM_NOT_MET = exports.DENY_VETO_HOLD = exports.DENY_VETO = exports.RECEIPT_UNAVAILABLE = exports.HISTORY_UNAVAILABLE = exports.AGENT_NOT_FOUND = exports.STREAM_LAGGED = exports.INVALID_REQUEST = exports.REGISTRY_READ_ONLY = exports.INVALID_POLICY_DEFINITION = exports.UNKNOWN_POLICY_VERSION = exports.INVALID_SESSION_ID = exports.POLICY_DENIED = exports.INTERNAL_ERROR = exports.RATE_LIMITED = exports.PAYLOAD_TOO_LARGE = exports.DUPLICATE_MESSAGE = exports.UNAUTHENTICATED = exports.FORBIDDEN = exports.MODE_NOT_SUPPORTED = exports.SESSION_NOT_OPEN = exports.SESSION_NOT_FOUND = exports.SESSION_ALREADY_EXISTS = exports.INVALID_ENVELOPE = exports.UNSUPPORTED_PROTOCOL_VERSION = exports.STANDARD_MODES = exports.MODE_MULTI_ROUND = exports.MODE_QUORUM = exports.MODE_HANDOFF = exports.MODE_TASK = exports.MODE_PROPOSAL = exports.MODE_DECISION = exports.DEFAULT_POLICY_VERSION = exports.DEFAULT_CONFIGURATION_VERSION = exports.DEFAULT_MODE_VERSION = exports.MACP_VERSION = void 0;
|
|
4
4
|
exports.MACP_VERSION = '1.0';
|
|
5
5
|
exports.DEFAULT_MODE_VERSION = '1.0.0';
|
|
6
6
|
exports.DEFAULT_CONFIGURATION_VERSION = 'config.default';
|
|
@@ -44,6 +44,18 @@ exports.INVALID_REQUEST = 'INVALID_REQUEST';
|
|
|
44
44
|
exports.STREAM_LAGGED = 'STREAM_LAGGED';
|
|
45
45
|
/** GetManifest for an agent this runtime does not host — NOT_FOUND. */
|
|
46
46
|
exports.AGENT_NOT_FOUND = 'AGENT_NOT_FOUND';
|
|
47
|
+
/**
|
|
48
|
+
* WhatIfReplay on a session whose full accepted history the runtime no longer
|
|
49
|
+
* holds (e.g. compacted when it ended) — FAILED_PRECONDITION. RFC-MACP-0012 §8.1.
|
|
50
|
+
*/
|
|
51
|
+
exports.HISTORY_UNAVAILABLE = 'HISTORY_UNAVAILABLE';
|
|
52
|
+
/**
|
|
53
|
+
* GetDecisionReceipt named a session no receipt can be issued for: not
|
|
54
|
+
* RESOLVED, resolved without a `CommitmentPayload`, or issuance failed —
|
|
55
|
+
* FAILED_PRECONDITION. RFC-MACP-0013 §13. **Provisional** in the spec's error
|
|
56
|
+
* registry (not yet in the parity contract's permanent set).
|
|
57
|
+
*/
|
|
58
|
+
exports.RECEIPT_UNAVAILABLE = 'RECEIPT_UNAVAILABLE';
|
|
47
59
|
// Structured POLICY_DENIED denial codes (`PolicyDenial.code`, runtime ≥ 0.9.0;
|
|
48
60
|
// RFC-MACP-0012 §6.2). Open set — names match python-sdk's exports.
|
|
49
61
|
exports.DENY_VETO = 'veto';
|
package/dist/index.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export * from './proposal';
|
|
|
14
14
|
export * from './proto-registry';
|
|
15
15
|
export * from './retry';
|
|
16
16
|
export * from './quorum';
|
|
17
|
-
export { RECEIPT_FORMAT, buildReceipt, commitmentFromProjection, verifyReceipt, type AttestationOutcome, type BuildReceiptOptions, type DecisionReceipt, type JwsAttestation, type ReceiptAttestation, type ReceiptCommitment, type ReceiptIntegrity, type ReceiptSigner, type ReceiptVerdict, type ReceiptVerification, type VendorAttestation, } from './receipt';
|
|
17
|
+
export { RECEIPT_FORMAT, buildReceipt, commitmentFromProjection, trustedKeysFromJwks, verifyReceipt, type AttestationOutcome, type BuildReceiptOptions, type DecisionReceipt, type DecisionReceiptResult, type JwsAttestation, type ReceiptAttestation, type ReceiptCommitment, type ReceiptIntegrity, type ReceiptJwk, type ReceiptKeySet, type ReceiptSigner, type ReceiptVerdict, type ReceiptVerification, type VendorAttestation, } from './receipt';
|
|
18
18
|
export * from './task';
|
|
19
19
|
export * from './types';
|
|
20
20
|
export * from './validation';
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
};
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.agent = exports.VERSION = exports.verifyReceipt = exports.commitmentFromProjection = exports.buildReceipt = exports.RECEIPT_FORMAT = exports.logger = exports.configureLogging = exports.verifyCommitmentHash = exports.isCanonicalCommitmentHash = exports.commitmentHash = exports.Auth = void 0;
|
|
39
|
+
exports.agent = exports.VERSION = exports.verifyReceipt = exports.trustedKeysFromJwks = exports.commitmentFromProjection = exports.buildReceipt = exports.RECEIPT_FORMAT = exports.logger = exports.configureLogging = exports.verifyCommitmentHash = exports.isCanonicalCommitmentHash = exports.commitmentHash = exports.Auth = void 0;
|
|
40
40
|
// Auth: export only the public constructors and types. The helpers
|
|
41
41
|
// `validateAuth`, `authSender`, `assertSenderMatchesIdentity`, and
|
|
42
42
|
// `metadataFromAuth` are SDK-internal — importable from the `./auth`
|
|
@@ -84,6 +84,7 @@ var receipt_1 = require("./receipt");
|
|
|
84
84
|
Object.defineProperty(exports, "RECEIPT_FORMAT", { enumerable: true, get: function () { return receipt_1.RECEIPT_FORMAT; } });
|
|
85
85
|
Object.defineProperty(exports, "buildReceipt", { enumerable: true, get: function () { return receipt_1.buildReceipt; } });
|
|
86
86
|
Object.defineProperty(exports, "commitmentFromProjection", { enumerable: true, get: function () { return receipt_1.commitmentFromProjection; } });
|
|
87
|
+
Object.defineProperty(exports, "trustedKeysFromJwks", { enumerable: true, get: function () { return receipt_1.trustedKeysFromJwks; } });
|
|
87
88
|
Object.defineProperty(exports, "verifyReceipt", { enumerable: true, get: function () { return receipt_1.verifyReceipt; } });
|
|
88
89
|
__exportStar(require("./task"), exports);
|
|
89
90
|
__exportStar(require("./types"), exports);
|
package/dist/receipt.d.ts
CHANGED
|
@@ -49,6 +49,32 @@ export interface DecisionReceipt {
|
|
|
49
49
|
issued_at: string;
|
|
50
50
|
attestations: ReceiptAttestation[];
|
|
51
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* {@link MacpClient.getDecisionReceipt}'s result: the parsed receipt and the
|
|
54
|
+
* `receipt_json` text exactly as the runtime served it, so a caller can store
|
|
55
|
+
* the issued bytes unchanged (RFC-MACP-0013 §13 item 6 serves them
|
|
56
|
+
* byte-identical). `receipt` is parsed, not validated: {@link verifyReceipt}
|
|
57
|
+
* is the authority on whether it is a well-formed `macp-receipt/1`.
|
|
58
|
+
*/
|
|
59
|
+
export interface DecisionReceiptResult {
|
|
60
|
+
receipt: DecisionReceipt;
|
|
61
|
+
raw: string;
|
|
62
|
+
}
|
|
63
|
+
/** One JWK of a receipt key set (`schemas/json/macp-receipt-keys.schema.json`). */
|
|
64
|
+
export interface ReceiptJwk {
|
|
65
|
+
kid: string;
|
|
66
|
+
kty: string;
|
|
67
|
+
crv?: string;
|
|
68
|
+
x?: string;
|
|
69
|
+
alg?: string;
|
|
70
|
+
use?: string;
|
|
71
|
+
[member: string]: unknown;
|
|
72
|
+
}
|
|
73
|
+
/** A JWK Set [RFC 7517] of receipt verification keys, as `GetReceiptKeys` returns it. */
|
|
74
|
+
export interface ReceiptKeySet {
|
|
75
|
+
keys: ReceiptJwk[];
|
|
76
|
+
[member: string]: unknown;
|
|
77
|
+
}
|
|
52
78
|
/**
|
|
53
79
|
* Signs a receipt with Ed25519: either a 32-byte private key seed, or a
|
|
54
80
|
* callback that returns the 64-byte signature over `signingInput` (for a key
|
|
@@ -122,3 +148,19 @@ export declare function buildReceipt(commitment: CommitmentPayload, options: Bui
|
|
|
122
148
|
* Never throws: malformed input yields an outcome, not an exception.
|
|
123
149
|
*/
|
|
124
150
|
export declare function verifyReceipt(receipt: unknown, trustedKeys: Record<string, string>): ReceiptVerification;
|
|
151
|
+
/**
|
|
152
|
+
* Turns a receipt key set (the JWK Set `GetReceiptKeys` returns, RFC-MACP-0013
|
|
153
|
+
* §13 item 8) into the `kid → x` map {@link verifyReceipt} takes. Choosing to
|
|
154
|
+
* trust the set is the caller's decision; this only converts it.
|
|
155
|
+
*
|
|
156
|
+
* A key is kept only if it is an Ed25519 public key (`kty` `OKP`, `crv`
|
|
157
|
+
* `Ed25519`) with a non-empty `kid` and `x`, an `alg` (if any) of `EdDSA`, a
|
|
158
|
+
* `use` (if any) of `sig`, and no private member (`d`, `p`, `q`, `dp`, `dq`,
|
|
159
|
+
* `qi`, `oth`, `k`): a key set that publishes private key material is
|
|
160
|
+
* misconfigured and is not trusted silently. A `kid` that more than one entry
|
|
161
|
+
* of the set claims is dropped entirely, even when the other entry is a key
|
|
162
|
+
* this function can't use (an EC key, say): item 8 makes kids unique across
|
|
163
|
+
* the whole set, so a repeated one leaves the set ambiguous about which key it
|
|
164
|
+
* names. Never throws: input that is not a key set yields `{}`.
|
|
165
|
+
*/
|
|
166
|
+
export declare function trustedKeysFromJwks(jwks: unknown): Record<string, string>;
|
package/dist/receipt.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.RECEIPT_FORMAT = void 0;
|
|
|
4
4
|
exports.commitmentFromProjection = commitmentFromProjection;
|
|
5
5
|
exports.buildReceipt = buildReceipt;
|
|
6
6
|
exports.verifyReceipt = verifyReceipt;
|
|
7
|
+
exports.trustedKeysFromJwks = trustedKeysFromJwks;
|
|
7
8
|
/**
|
|
8
9
|
* RFC-MACP-0013 Appendix A decision receipts (`macp-receipt/1`).
|
|
9
10
|
*
|
|
@@ -374,3 +375,54 @@ function verifyReceipt(receipt, trustedKeys) {
|
|
|
374
375
|
verdict: outcomes.includes('valid') ? 'attested' : 'integrity_only',
|
|
375
376
|
};
|
|
376
377
|
}
|
|
378
|
+
/** JWK private-key members (RFC 7518 §6); RFC-MACP-0013 §13 item 8 forbids them in a key set. */
|
|
379
|
+
const PRIVATE_JWK_MEMBERS = ['d', 'p', 'q', 'dp', 'dq', 'qi', 'oth', 'k'];
|
|
380
|
+
const isNonEmptyString = (v) => typeof v === 'string' && v.length > 0;
|
|
381
|
+
/** An Ed25519 public verification key usable for an EdDSA `jws` attestation. */
|
|
382
|
+
function usableEd25519Key(key) {
|
|
383
|
+
if (!isRecord(key))
|
|
384
|
+
return false;
|
|
385
|
+
if (key.kty !== 'OKP' || key.crv !== 'Ed25519')
|
|
386
|
+
return false;
|
|
387
|
+
if (!isNonEmptyString(key.kid) || !isNonEmptyString(key.x))
|
|
388
|
+
return false;
|
|
389
|
+
if (key.alg !== undefined && key.alg !== 'EdDSA')
|
|
390
|
+
return false;
|
|
391
|
+
if (key.use !== undefined && key.use !== 'sig')
|
|
392
|
+
return false;
|
|
393
|
+
return !PRIVATE_JWK_MEMBERS.some((m) => Object.prototype.hasOwnProperty.call(key, m));
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Turns a receipt key set (the JWK Set `GetReceiptKeys` returns, RFC-MACP-0013
|
|
397
|
+
* §13 item 8) into the `kid → x` map {@link verifyReceipt} takes. Choosing to
|
|
398
|
+
* trust the set is the caller's decision; this only converts it.
|
|
399
|
+
*
|
|
400
|
+
* A key is kept only if it is an Ed25519 public key (`kty` `OKP`, `crv`
|
|
401
|
+
* `Ed25519`) with a non-empty `kid` and `x`, an `alg` (if any) of `EdDSA`, a
|
|
402
|
+
* `use` (if any) of `sig`, and no private member (`d`, `p`, `q`, `dp`, `dq`,
|
|
403
|
+
* `qi`, `oth`, `k`): a key set that publishes private key material is
|
|
404
|
+
* misconfigured and is not trusted silently. A `kid` that more than one entry
|
|
405
|
+
* of the set claims is dropped entirely, even when the other entry is a key
|
|
406
|
+
* this function can't use (an EC key, say): item 8 makes kids unique across
|
|
407
|
+
* the whole set, so a repeated one leaves the set ambiguous about which key it
|
|
408
|
+
* names. Never throws: input that is not a key set yields `{}`.
|
|
409
|
+
*/
|
|
410
|
+
function trustedKeysFromJwks(jwks) {
|
|
411
|
+
const result = {};
|
|
412
|
+
if (!isRecord(jwks) || !Array.isArray(jwks.keys))
|
|
413
|
+
return result;
|
|
414
|
+
// Count every entry's string kid, usable or not, before keeping any.
|
|
415
|
+
const claims = new Map();
|
|
416
|
+
for (const key of jwks.keys) {
|
|
417
|
+
if (isRecord(key) && typeof key.kid === 'string')
|
|
418
|
+
claims.set(key.kid, (claims.get(key.kid) ?? 0) + 1);
|
|
419
|
+
}
|
|
420
|
+
for (const key of jwks.keys) {
|
|
421
|
+
if (!usableEd25519Key(key) || claims.get(key.kid) !== 1)
|
|
422
|
+
continue;
|
|
423
|
+
// defineProperty, not assignment: a kid of "__proto__" must become an own
|
|
424
|
+
// key (which verifyReceipt's hasOwnProperty lookup finds), not a prototype.
|
|
425
|
+
Object.defineProperty(result, key.kid, { value: key.x, enumerable: true, writable: true, configurable: true });
|
|
426
|
+
}
|
|
427
|
+
return result;
|
|
428
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -100,6 +100,82 @@ export interface PolicyRegistryCapability {
|
|
|
100
100
|
* admission, not this list, is authoritative. Runtime ≥ 0.9.0.
|
|
101
101
|
*/
|
|
102
102
|
ruleExtensions?: string[];
|
|
103
|
+
/**
|
|
104
|
+
* The runtime implements the optional, read-only `WhatIfReplay` RPC
|
|
105
|
+
* (RFC-MACP-0012 §8.1); {@link MacpClient.whatIfReplay} refuses to call it
|
|
106
|
+
* otherwise. Proto ≥ 0.1.12.
|
|
107
|
+
*/
|
|
108
|
+
whatIfReplay?: boolean;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* `capabilities.decisionReceipt` (`macp.v1.DecisionReceiptCapability`, proto
|
|
112
|
+
* ≥ 0.1.13): optional runtime-issued decision receipts (RFC-MACP-0013 §13).
|
|
113
|
+
*/
|
|
114
|
+
export interface DecisionReceiptCapability {
|
|
115
|
+
/**
|
|
116
|
+
* The runtime implements `GetDecisionReceipt` and `GetReceiptKeys`;
|
|
117
|
+
* {@link MacpClient.getDecisionReceipt} and {@link MacpClient.getReceiptKeys}
|
|
118
|
+
* refuse to call them otherwise.
|
|
119
|
+
*/
|
|
120
|
+
getDecisionReceipt?: boolean;
|
|
121
|
+
/**
|
|
122
|
+
* Every receipt issued from now on carries at least one EdDSA `jws`
|
|
123
|
+
* attestation. Says nothing about receipts issued earlier.
|
|
124
|
+
*/
|
|
125
|
+
signed?: boolean;
|
|
126
|
+
}
|
|
127
|
+
/** How one replay handled one history entry (`macp.v1.WhatIfEntryOutcome`). */
|
|
128
|
+
export interface WhatIfEntryOutcome {
|
|
129
|
+
kind: 'KIND_UNSPECIFIED' | 'KIND_APPLIED' | 'KIND_NOT_OPEN' | 'KIND_REFUSED' | 'KIND_NO_SESSION';
|
|
130
|
+
/** Session state after the entry, for `KIND_APPLIED`. */
|
|
131
|
+
state: string;
|
|
132
|
+
/** MACP error code, for `KIND_REFUSED`. */
|
|
133
|
+
errorCode: string;
|
|
134
|
+
/** For a `POLICY_DENIED` refusal, the §6.2 detail JSON; see {@link parseErrorDetails}. */
|
|
135
|
+
details: Buffer;
|
|
136
|
+
}
|
|
137
|
+
/** One accepted-history entry as both replays handled it. `historyIndex` is 0-based; the SessionStart is 0. */
|
|
138
|
+
export interface WhatIfEntry {
|
|
139
|
+
historyIndex: string;
|
|
140
|
+
messageId: string;
|
|
141
|
+
messageType: string;
|
|
142
|
+
recorded: WhatIfEntryOutcome | null;
|
|
143
|
+
candidate: WhatIfEntryOutcome | null;
|
|
144
|
+
}
|
|
145
|
+
/** One replay's final outcome (`macp.v1.WhatIfOutcome`). */
|
|
146
|
+
export interface WhatIfOutcome {
|
|
147
|
+
/** `SESSION_STATE_UNSPECIFIED` when the candidate refused the SessionStart. */
|
|
148
|
+
state: string;
|
|
149
|
+
/** The resolving Commitment's payload bytes; empty if unresolved. */
|
|
150
|
+
resolution: Buffer;
|
|
151
|
+
resolvedByHistoryIndex: string;
|
|
152
|
+
/** Empty if unresolved. */
|
|
153
|
+
resolvedByMessageId: string;
|
|
154
|
+
resolvedByMessageType: string;
|
|
155
|
+
}
|
|
156
|
+
/** A `POLICY_DENIED` the candidate produced; `details` as {@link WhatIfEntryOutcome.details}. */
|
|
157
|
+
export interface WhatIfDenial {
|
|
158
|
+
historyIndex: string;
|
|
159
|
+
messageId: string;
|
|
160
|
+
details: Buffer;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* `macp.v1.WhatIfReplayResponse`: a session's accepted history replayed under
|
|
164
|
+
* its bound policy (`recorded`) and under a candidate. Advisory, never binding.
|
|
165
|
+
* uint64 fields are decimal strings, as elsewhere in this client.
|
|
166
|
+
*/
|
|
167
|
+
export interface WhatIfReplayResult {
|
|
168
|
+
candidatePolicyId: string;
|
|
169
|
+
/** The policy the session is bound to (`policy.default` if none was named). */
|
|
170
|
+
recordedPolicyId: string;
|
|
171
|
+
recorded: WhatIfOutcome | null;
|
|
172
|
+
candidate: WhatIfOutcome | null;
|
|
173
|
+
/** First history index the two replays handled differently; absent when they agree throughout. */
|
|
174
|
+
firstDivergence?: string;
|
|
175
|
+
/** Every POLICY_DENIED the candidate produced, in history order. */
|
|
176
|
+
denials: WhatIfDenial[];
|
|
177
|
+
/** One entry per accepted-history entry, in history order. */
|
|
178
|
+
entries: WhatIfEntry[];
|
|
103
179
|
}
|
|
104
180
|
export interface InitializeResult {
|
|
105
181
|
selectedProtocolVersion: string;
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "macp-sdk-typescript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "TypeScript SDK for the MACP Rust runtime",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@grpc/grpc-js": "^1.14.3",
|
|
62
62
|
"@grpc/proto-loader": "^0.8.0",
|
|
63
|
-
"@multiagentcoordinationprotocol/proto": "^0.1.
|
|
63
|
+
"@multiagentcoordinationprotocol/proto": "^0.1.13",
|
|
64
64
|
"@noble/curves": "^1.9.7",
|
|
65
65
|
"@noble/hashes": "^1.8.0",
|
|
66
66
|
"protobufjs": "^8.6.5"
|