@cleocode/contracts 2026.4.114 → 2026.4.116

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/peer.d.ts ADDED
@@ -0,0 +1,125 @@
1
+ /**
2
+ * PeerIdentity — canonical type for CANT agent persona records.
3
+ *
4
+ * Introduced by T1210 (v2026.4.110 Wave 0.2) as the SDK-first contract
5
+ * for agent identity. `packages/cant/src/native-loader.ts` produces
6
+ * `PeerIdentity[]` from the canonical seed-agents path; dispatch and
7
+ * CLI layers consume it to drive `cleo agents list` and spawn routing.
8
+ *
9
+ * Design constraints (ADR-055 / D028 boundary rules):
10
+ * - Lives in `packages/contracts/` — ZERO runtime dependencies.
11
+ * - Consumed by `packages/cant/` (loader) and `packages/cleo/` (CLI).
12
+ * - No cross-package relative imports.
13
+ *
14
+ * @module peer
15
+ * @task T1210
16
+ * @epic T1144
17
+ */
18
+ /**
19
+ * Classification of a peer agent's role in the orchestration hierarchy.
20
+ *
21
+ * Mirrors the three-tier model in {@link AgentSpawnCapability}:
22
+ * - `orchestrator` — coordinates multi-agent workflows; may spawn leads and workers
23
+ * - `lead` — specialist; dispatches workers only
24
+ * - `worker` — terminal; executes tasks, cannot spawn
25
+ * - `subagent` — universal base role; resolved to a specific tier at spawn time
26
+ */
27
+ export type PeerKind = 'orchestrator' | 'lead' | 'worker' | 'subagent';
28
+ /**
29
+ * Canonical identity record for a CANT-defined agent persona.
30
+ *
31
+ * Produced by `loadSeedAgentIdentities()` in `packages/cant/src/native-loader.ts`
32
+ * and consumed by the dispatch layer + `cleo agents list`. Every field is
33
+ * required — loaders MUST supply a value for each field, using empty strings
34
+ * for absent optional content in the source `.cant` file.
35
+ *
36
+ * @example
37
+ * ```ts
38
+ * import type { PeerIdentity } from '@cleocode/contracts';
39
+ *
40
+ * const personas: PeerIdentity[] = loadSeedAgentIdentities();
41
+ * for (const p of personas) {
42
+ * console.log(`${p.peerId} (${p.peerKind}): ${p.displayName}`);
43
+ * }
44
+ * ```
45
+ *
46
+ * @task T1210
47
+ * @epic T1144
48
+ */
49
+ export interface PeerIdentity {
50
+ /**
51
+ * Stable business identifier for the agent, matching the `agent <id>:` block
52
+ * name in the `.cant` file and the `agents.agent_id` column in the registry.
53
+ *
54
+ * @example `"cleo-prime"`, `"cleo-dev"`, `"cleo-subagent"`
55
+ */
56
+ peerId: string;
57
+ /**
58
+ * Role classification derived from the `role:` field in the `.cant` agent
59
+ * block. Determines spawn authority in the orchestration hierarchy.
60
+ */
61
+ peerKind: PeerKind;
62
+ /**
63
+ * Absolute path to the canonical `.cant` file that defines this persona.
64
+ *
65
+ * For seed-agents this is inside `packages/agents/seed-agents/` or
66
+ * `packages/agents/cleo-subagent.cant` (universal base). For project-tier
67
+ * personas it is inside `.cleo/cant/agents/`.
68
+ */
69
+ cantFile: string;
70
+ /**
71
+ * Human-readable name for the persona, derived from the `display_name:` or
72
+ * `description:` field. Falls back to the `peerId` value when neither field
73
+ * is present in the source `.cant`.
74
+ */
75
+ displayName: string;
76
+ /**
77
+ * Short description of the persona's purpose, taken from the `description:`
78
+ * field in the `.cant` agent block. Empty string when absent.
79
+ */
80
+ description: string;
81
+ }
82
+ /**
83
+ * Validate that an unknown value conforms to the {@link PeerIdentity} shape.
84
+ *
85
+ * Performs a lightweight structural check without Zod to keep `packages/contracts`
86
+ * dependency-free at runtime. Callers that need schema-level validation
87
+ * (e.g., test fixtures) can use {@link assertPeerIdentity}.
88
+ *
89
+ * @param value - Value to test.
90
+ * @returns `true` when `value` is a valid {@link PeerIdentity}.
91
+ *
92
+ * @example
93
+ * ```ts
94
+ * if (isPeerIdentity(raw)) {
95
+ * console.log(raw.peerId);
96
+ * }
97
+ * ```
98
+ */
99
+ export declare function isPeerIdentity(value: unknown): value is PeerIdentity;
100
+ /**
101
+ * Assert that a value is a valid {@link PeerIdentity}, throwing a descriptive
102
+ * error when the shape does not conform.
103
+ *
104
+ * @param value - Value to assert.
105
+ * @throws {TypeError} When the value does not satisfy {@link isPeerIdentity}.
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * assertPeerIdentity(raw); // throws if invalid
110
+ * console.log(raw.peerId); // safe
111
+ * ```
112
+ */
113
+ export declare function assertPeerIdentity(value: unknown): asserts value is PeerIdentity;
114
+ /**
115
+ * Validate and filter an array of unknown values to {@link PeerIdentity}[].
116
+ *
117
+ * Invalid entries are silently dropped. This is the safe variant for loading
118
+ * from untrusted sources (e.g., the result of parsing a directory of `.cant`
119
+ * files whose format may vary).
120
+ *
121
+ * @param values - Array of unknown values.
122
+ * @returns Array containing only values that pass {@link isPeerIdentity}.
123
+ */
124
+ export declare function filterPeerIdentities(values: unknown[]): PeerIdentity[];
125
+ //# sourceMappingURL=peer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer.d.ts","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAMvE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,QAAQ,EAAE,QAAQ,CAAC;IAEnB;;;;;;OAMG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAapE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAMhF;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CAEtE"}
package/dist/peer.js ADDED
@@ -0,0 +1,82 @@
1
+ /**
2
+ * PeerIdentity — canonical type for CANT agent persona records.
3
+ *
4
+ * Introduced by T1210 (v2026.4.110 Wave 0.2) as the SDK-first contract
5
+ * for agent identity. `packages/cant/src/native-loader.ts` produces
6
+ * `PeerIdentity[]` from the canonical seed-agents path; dispatch and
7
+ * CLI layers consume it to drive `cleo agents list` and spawn routing.
8
+ *
9
+ * Design constraints (ADR-055 / D028 boundary rules):
10
+ * - Lives in `packages/contracts/` — ZERO runtime dependencies.
11
+ * - Consumed by `packages/cant/` (loader) and `packages/cleo/` (CLI).
12
+ * - No cross-package relative imports.
13
+ *
14
+ * @module peer
15
+ * @task T1210
16
+ * @epic T1144
17
+ */
18
+ // ============================================================================
19
+ // Runtime validation
20
+ // ============================================================================
21
+ /**
22
+ * Validate that an unknown value conforms to the {@link PeerIdentity} shape.
23
+ *
24
+ * Performs a lightweight structural check without Zod to keep `packages/contracts`
25
+ * dependency-free at runtime. Callers that need schema-level validation
26
+ * (e.g., test fixtures) can use {@link assertPeerIdentity}.
27
+ *
28
+ * @param value - Value to test.
29
+ * @returns `true` when `value` is a valid {@link PeerIdentity}.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * if (isPeerIdentity(raw)) {
34
+ * console.log(raw.peerId);
35
+ * }
36
+ * ```
37
+ */
38
+ export function isPeerIdentity(value) {
39
+ if (typeof value !== 'object' || value === null)
40
+ return false;
41
+ const v = value;
42
+ return (typeof v['peerId'] === 'string' &&
43
+ v['peerId'].length > 0 &&
44
+ typeof v['peerKind'] === 'string' &&
45
+ ['orchestrator', 'lead', 'worker', 'subagent'].includes(v['peerKind']) &&
46
+ typeof v['cantFile'] === 'string' &&
47
+ v['cantFile'].length > 0 &&
48
+ typeof v['displayName'] === 'string' &&
49
+ typeof v['description'] === 'string');
50
+ }
51
+ /**
52
+ * Assert that a value is a valid {@link PeerIdentity}, throwing a descriptive
53
+ * error when the shape does not conform.
54
+ *
55
+ * @param value - Value to assert.
56
+ * @throws {TypeError} When the value does not satisfy {@link isPeerIdentity}.
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * assertPeerIdentity(raw); // throws if invalid
61
+ * console.log(raw.peerId); // safe
62
+ * ```
63
+ */
64
+ export function assertPeerIdentity(value) {
65
+ if (!isPeerIdentity(value)) {
66
+ throw new TypeError(`Expected PeerIdentity { peerId, peerKind, cantFile, displayName, description } — got: ${JSON.stringify(value)}`);
67
+ }
68
+ }
69
+ /**
70
+ * Validate and filter an array of unknown values to {@link PeerIdentity}[].
71
+ *
72
+ * Invalid entries are silently dropped. This is the safe variant for loading
73
+ * from untrusted sources (e.g., the result of parsing a directory of `.cant`
74
+ * files whose format may vary).
75
+ *
76
+ * @param values - Array of unknown values.
77
+ * @returns Array containing only values that pass {@link isPeerIdentity}.
78
+ */
79
+ export function filterPeerIdentities(values) {
80
+ return values.filter(isPeerIdentity);
81
+ }
82
+ //# sourceMappingURL=peer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer.js","sourceRoot":"","sources":["../src/peer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAgFH,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,CACL,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,QAAQ;QAC/B,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC;QACtB,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,QAAQ;QACjC,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAW,CAAC;QAChF,OAAO,CAAC,CAAC,UAAU,CAAC,KAAK,QAAQ;QACjC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC;QACxB,OAAO,CAAC,CAAC,aAAa,CAAC,KAAK,QAAQ;QACpC,OAAO,CAAC,CAAC,aAAa,CAAC,KAAK,QAAQ,CACrC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,SAAS,CACjB,yFAAyF,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CACjH,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,OAAO,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AACvC,CAAC"}
@@ -11,7 +11,7 @@
11
11
  * @module transport
12
12
  */
13
13
  import type { TransportConfig } from './agent-registry.js';
14
- import type { ConduitMessage } from './conduit.js';
14
+ import type { ConduitMessage, ConduitTopicPublishOptions, ConduitTopicSubscribeOptions, ConduitUnsubscribe } from './conduit.js';
15
15
  /** Configuration passed to Transport.connect(). */
16
16
  export interface TransportConnectConfig extends TransportConfig {
17
17
  /** Agent ID to connect as. */
@@ -45,6 +45,50 @@ export interface Transport {
45
45
  ack(messageIds: string[]): Promise<void>;
46
46
  /** Subscribe to real-time events (SSE/WebSocket). Returns unsubscribe. */
47
47
  subscribe?(handler: (message: ConduitMessage) => void): () => void;
48
+ /**
49
+ * Subscribe agent to a named topic.
50
+ *
51
+ * Optional — only implemented by `LocalTransport`. Cloud transports
52
+ * (HttpTransport, SseTransport) do not yet support topic operations.
53
+ *
54
+ * @param topicName - Topic name, e.g. `"epic-T1149.wave-2"`.
55
+ * @param options - Subscription filter options.
56
+ * @task T1252
57
+ */
58
+ subscribeTopic?(topicName: string, options?: ConduitTopicSubscribeOptions): Promise<void>;
59
+ /**
60
+ * Publish a message to a named topic.
61
+ *
62
+ * Optional — only implemented by `LocalTransport`.
63
+ *
64
+ * @param topicName - Target topic name.
65
+ * @param content - Message content.
66
+ * @param options - Kind and optional payload.
67
+ * @task T1252
68
+ */
69
+ publishToTopic?(topicName: string, content: string, options?: ConduitTopicPublishOptions): Promise<{
70
+ messageId: string;
71
+ }>;
72
+ /**
73
+ * Register a real-time handler for topic messages.
74
+ *
75
+ * Optional — only implemented by `LocalTransport`.
76
+ *
77
+ * @param topicName - Topic name to watch.
78
+ * @param handler - Handler invoked for each new message.
79
+ * @returns Unsubscribe function.
80
+ * @task T1252
81
+ */
82
+ onTopic?(topicName: string, handler: (message: ConduitMessage) => void): ConduitUnsubscribe;
83
+ /**
84
+ * Unsubscribe agent from a named topic.
85
+ *
86
+ * Optional — only implemented by `LocalTransport`.
87
+ *
88
+ * @param topicName - Topic name to leave.
89
+ * @task T1252
90
+ */
91
+ unsubscribeTopic?(topicName: string): Promise<void>;
48
92
  }
49
93
  /** @deprecated Use Transport instead. Will be removed after unification. */
50
94
  export interface AdapterTransportProvider {
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD,mDAAmD;AACnD,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,wCAAwC;IACxC,OAAO,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD,6CAA6C;IAC7C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,8BAA8B;IAC9B,IAAI,CACF,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GACA,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAElC,oDAAoD;IACpD,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAE9E,2DAA2D;IAC3D,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC,0EAA0E;IAC1E,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CACpE;AAMD,4EAA4E;AAC5E,MAAM,WAAW,wBAAwB;IACvC,iEAAiE;IACjE,eAAe,IAAI,OAAO,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EACV,cAAc,EACd,0BAA0B,EAC1B,4BAA4B,EAC5B,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAMtB,mDAAmD;AACnD,MAAM,WAAW,sBAAuB,SAAQ,eAAe;IAC7D,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACxB,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,wCAAwC;IACxC,OAAO,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvD,6CAA6C;IAC7C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,8BAA8B;IAC9B,IAAI,CACF,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GACA,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAElC,oDAAoD;IACpD,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAE9E,2DAA2D;IAC3D,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC,0EAA0E;IAC1E,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IAInE;;;;;;;;;OASG;IACH,cAAc,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1F;;;;;;;;;OASG;IACH,cAAc,CAAC,CACb,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,0BAA0B,GACnC,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAElC;;;;;;;;;OASG;IACH,OAAO,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,kBAAkB,CAAC;IAE5F;;;;;;;OAOG;IACH,gBAAgB,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrD;AAMD,4EAA4E;AAC5E,MAAM,WAAW,wBAAwB;IACvC,iEAAiE;IACjE,eAAe,IAAI,OAAO,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/contracts",
3
- "version": "2026.4.114",
3
+ "version": "2026.4.116",
4
4
  "description": "Domain types, interfaces, and contracts for the CLEO ecosystem",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/conduit.ts CHANGED
@@ -35,6 +35,76 @@ export interface ConduitMessage {
35
35
  timestamp: string;
36
36
  /** Optional structured metadata. */
37
37
  metadata?: Record<string, unknown>;
38
+ /**
39
+ * Message semantics for A2A (Agent-to-Agent) coordination.
40
+ *
41
+ * - `message` — default, backward-compat direct message
42
+ * - `request` — sender expects a response; receiver should reply
43
+ * - `notify` — informational broadcast; no response expected
44
+ * - `subscribe` — sender subscribes to a topic
45
+ *
46
+ * @default `"message"` for backward compatibility
47
+ * @see T1252 CONDUIT A2A
48
+ */
49
+ kind?: 'message' | 'request' | 'notify' | 'subscribe';
50
+ /**
51
+ * Sender peer identity — stable peer ID from PeerIdentity.peerId.
52
+ * Populated for A2A topic messages; absent on legacy direct messages.
53
+ *
54
+ * @see T1252 CONDUIT A2A
55
+ */
56
+ fromPeerId?: string;
57
+ /**
58
+ * Recipient peer identity — agent peerId for direct messages, `null` for
59
+ * topic broadcasts (one-to-many).
60
+ *
61
+ * @see T1252 CONDUIT A2A
62
+ */
63
+ toPeerId?: string | null;
64
+ /**
65
+ * Structured payload accompanying the message.
66
+ *
67
+ * JSON-serializable object; stored as TEXT in the database.
68
+ * Used for structured A2A coordination data (findings, events, etc.).
69
+ *
70
+ * @see T1252 CONDUIT A2A
71
+ */
72
+ payload?: Record<string, unknown>;
73
+ }
74
+
75
+ /**
76
+ * A2A (Agent-to-Agent) topic subscription options.
77
+ *
78
+ * Passed to `subscribeTopic()` to filter messages by kind or event.
79
+ *
80
+ * @see T1252 CONDUIT A2A
81
+ */
82
+ export interface ConduitTopicSubscribeOptions {
83
+ /**
84
+ * Filter messages by kind. When absent, all kinds are delivered.
85
+ * @example `['notify', 'request']`
86
+ */
87
+ filter?: {
88
+ /** Accept only these message kinds. */
89
+ kind?: Array<'message' | 'request' | 'notify' | 'subscribe'>;
90
+ /** Accept only messages whose `payload.event` is in this list. */
91
+ event?: string[];
92
+ };
93
+ }
94
+
95
+ /**
96
+ * Options for publishing a message to a topic.
97
+ *
98
+ * @see T1252 CONDUIT A2A
99
+ */
100
+ export interface ConduitTopicPublishOptions {
101
+ /**
102
+ * Message kind.
103
+ * @default `"message"`
104
+ */
105
+ kind?: 'message' | 'request' | 'notify' | 'subscribe';
106
+ /** Structured payload to attach to the message. */
107
+ payload?: Record<string, unknown>;
38
108
  }
39
109
 
40
110
  /** Options for sending a message. */
@@ -123,6 +193,57 @@ export interface Conduit {
123
193
  /** List currently online agents (optional — may not be supported by all implementations). */
124
194
  listOnline?(): Promise<string[]>;
125
195
 
196
+ // --- A2A Topic Pub-Sub (T1252) ---
197
+
198
+ /**
199
+ * Subscribe this agent to a named topic for broadcast messages.
200
+ *
201
+ * Creates the topic in conduit.db if it does not yet exist (idempotent).
202
+ * The agent will receive messages published to this topic via `onTopic()`.
203
+ *
204
+ * @param topicName - Topic name, e.g. `"epic-T1149.wave-2"` or `"epic-T1149.coordination"`.
205
+ * @param options - Optional subscription filter (kind, event).
206
+ * @throws When no local transport is available (LocalTransport required for topic ops).
207
+ * @see T1252 CONDUIT A2A
208
+ */
209
+ subscribeTopic?(topicName: string, options?: ConduitTopicSubscribeOptions): Promise<void>;
210
+
211
+ /**
212
+ * Publish a message to a topic (broadcast to all current subscribers).
213
+ *
214
+ * @param topicName - Target topic name.
215
+ * @param content - Human-readable message content.
216
+ * @param options - Message kind and optional structured payload.
217
+ * @returns Send result with the assigned message ID.
218
+ * @see T1252 CONDUIT A2A
219
+ */
220
+ publishToTopic?(
221
+ topicName: string,
222
+ content: string,
223
+ options?: ConduitTopicPublishOptions,
224
+ ): Promise<ConduitSendResult>;
225
+
226
+ /**
227
+ * Register a real-time handler for messages on a named topic.
228
+ *
229
+ * @param topicName - Topic name to watch.
230
+ * @param handler - Callback invoked for each message (includes A2A fields).
231
+ * @returns Unsubscribe function that stops delivery to this handler.
232
+ * @see T1252 CONDUIT A2A
233
+ */
234
+ onTopic?(topicName: string, handler: (message: ConduitMessage) => void): ConduitUnsubscribe;
235
+
236
+ /**
237
+ * Unsubscribe this agent from a named topic.
238
+ *
239
+ * Removes the subscription record from conduit.db. The agent will no longer
240
+ * receive messages published to the topic.
241
+ *
242
+ * @param topicName - Topic name to leave.
243
+ * @see T1252 CONDUIT A2A
244
+ */
245
+ unsubscribeTopic?(topicName: string): Promise<void>;
246
+
126
247
  // --- Connection lifecycle ---
127
248
 
128
249
  /** Connect to the messaging backend. */
package/src/index.ts CHANGED
@@ -176,6 +176,8 @@ export type {
176
176
  ConduitSendResult,
177
177
  ConduitState,
178
178
  ConduitStateChange,
179
+ ConduitTopicPublishOptions,
180
+ ConduitTopicSubscribeOptions,
179
181
  ConduitUnsubscribe,
180
182
  } from './conduit.js';
181
183
  // === Configuration Types ===
@@ -491,6 +493,22 @@ export type {
491
493
  SubstitutionSource,
492
494
  VariableResolver,
493
495
  } from './operations/variable-substitution.js';
496
+ // === Worktree Backend SDK Types (T1161) ===
497
+ // Re-exported at top level so @cleocode/worktree-backend and callers can
498
+ // import without the `ops.` namespace hop.
499
+ export type {
500
+ CreateWorktreeOptions,
501
+ CreateWorktreeResult,
502
+ DestroyWorktreeOptions,
503
+ DestroyWorktreeResult,
504
+ ListWorktreesOptions,
505
+ PruneWorktreesOptions,
506
+ PruneWorktreesResult,
507
+ WorktreeHook,
508
+ WorktreeHookResult,
509
+ WorktreeIncludePattern,
510
+ WorktreeListEntry,
511
+ } from './operations/worktree.js';
494
512
  // === Orchestration Hierarchy ===
495
513
  export {
496
514
  type AgentHierarchy,
@@ -499,6 +517,14 @@ export {
499
517
  type OrchestrationHierarchyAPI,
500
518
  OrchestrationLevel,
501
519
  } from './orchestration-hierarchy.js';
520
+ // === Peer Identity (T1210 — SDK-first CANT persona contract) ===
521
+ export {
522
+ assertPeerIdentity,
523
+ filterPeerIdentities,
524
+ isPeerIdentity,
525
+ type PeerIdentity,
526
+ type PeerKind,
527
+ } from './peer.js';
502
528
  // === Playbook DSL Types (T889 / T904 / W4-6) ===
503
529
  export type {
504
530
  PlaybookAgenticNode,
@@ -187,3 +187,113 @@ export interface ConduitSendResult {
187
187
  /** ISO 8601 send timestamp. */
188
188
  sentAt: string;
189
189
  }
190
+
191
+ // ============================================================================
192
+ // A2A Topic Operations (T1252 — Wave 9 Agent-to-Agent coordination)
193
+ // ============================================================================
194
+
195
+ // --------------------------------------------------------------------------
196
+ // conduit.subscribe → register agent subscription to a named topic
197
+ // --------------------------------------------------------------------------
198
+
199
+ /**
200
+ * Parameters for `conduit.subscribe`.
201
+ *
202
+ * @see T1252 CONDUIT A2A
203
+ */
204
+ export interface ConduitSubscribeParams {
205
+ /** Topic name to subscribe to, e.g. `"epic-T1149.wave-2"`. */
206
+ topicName: string;
207
+ /** Send as this agent. Omit to use the active agent from the registry. */
208
+ agentId?: string;
209
+ /** Optional message kind / event filter. */
210
+ filter?: { kind?: string[]; event?: string[] };
211
+ }
212
+
213
+ /**
214
+ * Result of `conduit.subscribe`.
215
+ *
216
+ * @see T1252 CONDUIT A2A
217
+ */
218
+ export interface ConduitSubscribeResult {
219
+ /** The agent id that was subscribed. */
220
+ agentId: string;
221
+ /** Topic name subscribed to. */
222
+ topicName: string;
223
+ /** Human-readable status message. */
224
+ message: string;
225
+ }
226
+
227
+ // --------------------------------------------------------------------------
228
+ // conduit.publish → broadcast a message to a topic
229
+ // --------------------------------------------------------------------------
230
+
231
+ /**
232
+ * Parameters for `conduit.publish`.
233
+ *
234
+ * @see T1252 CONDUIT A2A
235
+ */
236
+ export interface ConduitPublishParams {
237
+ /** Target topic name. */
238
+ topicName: string;
239
+ /** Message content (human-readable). */
240
+ content: string;
241
+ /** Message kind (default `"message"`). */
242
+ kind?: 'message' | 'request' | 'notify' | 'subscribe';
243
+ /** Optional structured payload (JSON-serializable). */
244
+ payload?: Record<string, unknown>;
245
+ /** Publish as this agent. Omit to use the active agent from the registry. */
246
+ agentId?: string;
247
+ }
248
+
249
+ /**
250
+ * Result of `conduit.publish`.
251
+ *
252
+ * @see T1252 CONDUIT A2A
253
+ */
254
+ export interface ConduitPublishResult {
255
+ /** Assigned message id. */
256
+ messageId: string;
257
+ /** Publisher agent id. */
258
+ from: string;
259
+ /** Topic the message was published to. */
260
+ topicName: string;
261
+ /** Transport backing this call. */
262
+ transport: ConduitTransportKind;
263
+ /** ISO 8601 publish timestamp. */
264
+ publishedAt: string;
265
+ }
266
+
267
+ // --------------------------------------------------------------------------
268
+ // conduit.listen → one-shot poll for topic messages
269
+ // --------------------------------------------------------------------------
270
+
271
+ /**
272
+ * Parameters for `conduit.listen`.
273
+ *
274
+ * @see T1252 CONDUIT A2A
275
+ */
276
+ export interface ConduitListenParams {
277
+ /** Topic name to poll. */
278
+ topicName: string;
279
+ /** Listen as this agent. Omit to use the active agent from the registry. */
280
+ agentId?: string;
281
+ /** Maximum messages to return (default 50). */
282
+ limit?: number;
283
+ /** Only return messages created after this ISO 8601 timestamp. */
284
+ since?: string;
285
+ }
286
+
287
+ /**
288
+ * Result of `conduit.listen`.
289
+ *
290
+ * @see T1252 CONDUIT A2A
291
+ */
292
+ export interface ConduitListenResult {
293
+ /** Topic that was polled. */
294
+ topicName: string;
295
+ /** Messages received (may be empty). */
296
+ messages: ConduitInboxMessage[];
297
+ /** Duration of the listen call in milliseconds. */
298
+ listenedForMs: number;
299
+ }
@@ -21,3 +21,4 @@ export * from './system.js';
21
21
  export * from './tasks.js';
22
22
  export * from './validate.js';
23
23
  export * from './variable-substitution.js';
24
+ export * from './worktree.js';