ProtoRegistry API Reference

The ProtoRegistry handles protobuf serialization and deserialization for all MACP message types.

Constructor

import { ProtoRegistry } from 'macp-sdk-typescript';

const registry = new ProtoRegistry();                    // default proto dir
const registry = new ProtoRegistry('/path/to/proto');    // custom proto dir

Loads and resolves all .proto files at construction time (synchronous).

Properties

PropertyTypeDescription
protoDirstringResolved path to the proto directory

Methods

getKnownTypeName(mode, messageType)

Look up the canonical protobuf type name for a given mode and message type.

registry.getKnownTypeName('macp.mode.decision.v1', 'Proposal');
// → 'macp.modes.decision.v1.ProposalPayload'

registry.getKnownTypeName('', 'SessionStart');
// → 'macp.v1.SessionStartPayload'

registry.getKnownTypeName('ext.multi_round.v1', 'Contribute');
// → 'macp.modes.multi_round.v1.ContributePayload'  (canonical protobuf, proto ≥ 0.1.4)

registry.getKnownTypeName('unknown', 'Unknown');
// → undefined

encodeMessage(typeName, value)

Encode a TypeScript object to a protobuf Buffer using a specific type name.

const buffer = registry.encodeMessage(
  'macp.modes.decision.v1.ProposalPayload',
  { proposalId: 'p1', option: 'A' },
);

decodeMessage(typeName, payload)

Decode a protobuf Buffer to a TypeScript object.

const obj = registry.decodeMessage(
  'macp.modes.decision.v1.ProposalPayload',
  buffer,
);
// → { proposalId: 'p1', option: 'A' }

Decoding uses defaults: false, so proto3 scalars at their default value (empty string, 0, empty bytes) are absent from the result — with one exception: non-repeated bool fields are materialized to false when absent. Without this, an explicit false (e.g. Commitment.outcome_positive on a decline) would be indistinguishable from unset and mis-read as positive. long values decode as strings, enums as their names, bytes as Buffer.

encodeKnownPayload(mode, messageType, value)

Convenience: look up the type name and encode in one step.

const buffer = registry.encodeKnownPayload(
  'macp.mode.decision.v1',
  'Proposal',
  { proposalId: 'p1', option: 'A' },
);

ext.multi_round.v1 Contribute encodes as canonical protobuf (ContributePayload) as of proto 0.1.4 / runtime 0.5.0.

Throws if no mapping exists for the given mode/messageType combination.

decodeKnownPayload(mode, messageType, payload)

Convenience: look up the type name and decode in one step.

const obj = registry.decodeKnownPayload(
  'macp.mode.decision.v1',
  'Proposal',
  buffer,
);

For unmapped mode/messageType combinations, attempts a UTF-8 fallback decode: valid JSON yields { encoding: 'json', json }, anything else yields { encoding: 'text', text, payloadBase64 }. Returns undefined for empty unmapped payloads.

ext.multi_round.v1 Contribute decodes both wire formats: legacy JSON ({"value":"..."}, replayed verbatim from pre-proto histories) is tried first, then canonical protobuf. Both normalize to { value: string }. The two encodings are not disjoint on their first byte — the canonical proto tag byte for field 1 (0x0A) is itself insignificant JSON whitespace, so at specific value byte-lengths a genuine canonical payload also parses as valid JSON (issue #104). A canonicality tie-break resolves the ambiguity: a successful JSON parse is trusted only when the same bytes are not also the exact canonical proto encoding (decode as proto, re-encode, compare bytes) — see isCanonicalProto in src/proto-registry.ts and Testing § Parity Contract Gate for the cross-SDK context. One narrow, symmetric residual survives by construction (a payload starting with a literal newline byte whose remainder exactly forms a complete proto field-1 string misreads as proto) — documented in that method's own docblock, and unreachable by any encoder this SDK ships.

Type Mappings

Core Messages

messageTypeProto Type
SessionStartmacp.v1.SessionStartPayload
Commitmentmacp.v1.CommitmentPayload
Signalmacp.v1.SignalPayload
Progressmacp.v1.ProgressPayload

Mode Messages

Each mode maps its message types to proto types in the corresponding .proto file. For the full mapping, see MODE_MAP in src/proto-registry.ts.