@cleocode/contracts 2026.3.74 → 2026.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-registry.d.ts +82 -0
- package/dist/agent-registry.d.ts.map +1 -0
- package/dist/agent-registry.js +12 -0
- package/dist/agent-registry.js.map +1 -0
- package/dist/code-symbol.d.ts +56 -0
- package/dist/code-symbol.d.ts.map +1 -0
- package/dist/code-symbol.js +10 -0
- package/dist/code-symbol.js.map +1 -0
- package/dist/conduit.d.ts +14 -7
- package/dist/conduit.d.ts.map +1 -1
- package/dist/conduit.js +4 -1
- package/dist/conduit.js.map +1 -1
- package/dist/data-accessor.d.ts +47 -0
- package/dist/data-accessor.d.ts.map +1 -1
- package/dist/data-accessor.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/lafs.d.ts +1 -1
- package/dist/lafs.js +1 -1
- package/dist/orchestration-hierarchy.d.ts +81 -0
- package/dist/orchestration-hierarchy.d.ts.map +1 -0
- package/dist/orchestration-hierarchy.js +31 -0
- package/dist/orchestration-hierarchy.js.map +1 -0
- package/dist/task.d.ts +2 -0
- package/dist/task.d.ts.map +1 -1
- package/dist/transport.d.ts +49 -5
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +10 -3
- package/dist/transport.js.map +1 -1
- package/dist/wasm/index.d.ts +114 -0
- package/dist/wasm/index.d.ts.map +1 -0
- package/dist/wasm/index.js +184 -0
- package/dist/wasm/index.js.map +1 -0
- package/package.json +1 -1
- package/src/agent-registry.ts +104 -0
- package/src/code-symbol.ts +73 -0
- package/src/conduit.ts +14 -7
- package/src/data-accessor.ts +56 -0
- package/src/index.ts +32 -1
- package/src/lafs.ts +2 -2
- package/src/orchestration-hierarchy.ts +107 -0
- package/src/task.ts +3 -0
- package/src/transport.ts +69 -5
- package/src/wasm/index.ts +193 -0
package/src/data-accessor.ts
CHANGED
|
@@ -17,6 +17,26 @@ import type { ArchivedTask } from './archive.js';
|
|
|
17
17
|
import type { Session } from './session.js';
|
|
18
18
|
import type { Task, TaskPriority, TaskSize, TaskStatus, TaskType } from './task.js';
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Agent instance row shape for DataAccessor methods.
|
|
22
|
+
* Mirrors the agent_instances Drizzle table in core but avoids Drizzle dependency.
|
|
23
|
+
*/
|
|
24
|
+
export interface DataAccessorAgentInstance {
|
|
25
|
+
id: string;
|
|
26
|
+
agentType: string;
|
|
27
|
+
status: string;
|
|
28
|
+
sessionId: string | null;
|
|
29
|
+
taskId: string | null;
|
|
30
|
+
startedAt: string;
|
|
31
|
+
lastHeartbeat: string;
|
|
32
|
+
stoppedAt: string | null;
|
|
33
|
+
errorCount: number;
|
|
34
|
+
totalTasksCompleted: number;
|
|
35
|
+
capacity: string;
|
|
36
|
+
metadataJson: string | null;
|
|
37
|
+
parentAgentId: string | null;
|
|
38
|
+
}
|
|
39
|
+
|
|
20
40
|
/** Archive-specific fields for task upsert. */
|
|
21
41
|
export interface ArchiveFields {
|
|
22
42
|
archivedAt?: string;
|
|
@@ -83,6 +103,7 @@ export interface TaskFieldUpdates {
|
|
|
83
103
|
modifiedBy?: string | null;
|
|
84
104
|
sessionId?: string | null;
|
|
85
105
|
updatedAt?: string | null;
|
|
106
|
+
assignee?: string | null;
|
|
86
107
|
}
|
|
87
108
|
|
|
88
109
|
/**
|
|
@@ -227,6 +248,41 @@ export interface DataAccessor {
|
|
|
227
248
|
|
|
228
249
|
/** Remove a single session by ID. */
|
|
229
250
|
removeSingleSession(sessionId: string): Promise<void>;
|
|
251
|
+
|
|
252
|
+
// ---- Agent instances ----
|
|
253
|
+
|
|
254
|
+
/** List agent instances with optional filters. Returns rows from agent_instances table. */
|
|
255
|
+
listAgentInstances(filters?: {
|
|
256
|
+
status?: string | string[];
|
|
257
|
+
agentType?: string | string[];
|
|
258
|
+
}): Promise<DataAccessorAgentInstance[]>;
|
|
259
|
+
|
|
260
|
+
/** Get a single agent instance by ID. Returns null if not found. */
|
|
261
|
+
getAgentInstance(agentId: string): Promise<DataAccessorAgentInstance | null>;
|
|
262
|
+
|
|
263
|
+
// ---- Agent task claiming ----
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Atomically claim a task for an agent.
|
|
267
|
+
*
|
|
268
|
+
* Uses `UPDATE ... WHERE assignee IS NULL OR assignee = agentId` to prevent
|
|
269
|
+
* race conditions. Throws if the task is already claimed by a different agent.
|
|
270
|
+
*
|
|
271
|
+
* @param taskId - ID of the task to claim.
|
|
272
|
+
* @param agentId - Agent identifier claiming the task.
|
|
273
|
+
* @throws {Error} When the task is not found or is already claimed by another agent.
|
|
274
|
+
*/
|
|
275
|
+
claimTask(taskId: string, agentId: string): Promise<void>;
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Release a claimed task, clearing its assignee.
|
|
279
|
+
*
|
|
280
|
+
* No-op if the task is not currently claimed.
|
|
281
|
+
*
|
|
282
|
+
* @param taskId - ID of the task to unclaim.
|
|
283
|
+
* @throws {Error} When the task is not found.
|
|
284
|
+
*/
|
|
285
|
+
unclaimTask(taskId: string): Promise<void>;
|
|
230
286
|
}
|
|
231
287
|
|
|
232
288
|
// Factory functions (createDataAccessor, getAccessor) live in @cleocode/core,
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,13 @@
|
|
|
8
8
|
|
|
9
9
|
// === Provider Adapter Contracts ===
|
|
10
10
|
export type { AdapterHealthStatus, CLEOProviderAdapter } from './adapter.js';
|
|
11
|
+
// === Agent Registry (credential management) ===
|
|
12
|
+
export type {
|
|
13
|
+
AgentCredential,
|
|
14
|
+
AgentListFilter,
|
|
15
|
+
AgentRegistryAPI,
|
|
16
|
+
TransportConfig,
|
|
17
|
+
} from './agent-registry.js';
|
|
11
18
|
// === Archive Types ===
|
|
12
19
|
export type {
|
|
13
20
|
ArchiveCycleTimesReport,
|
|
@@ -33,6 +40,13 @@ export type {
|
|
|
33
40
|
SupersededEntry,
|
|
34
41
|
} from './brain.js';
|
|
35
42
|
export type { AdapterCapabilities } from './capabilities.js';
|
|
43
|
+
// === Code Symbol Types (tree-sitter AST) ===
|
|
44
|
+
export type {
|
|
45
|
+
BatchParseResult,
|
|
46
|
+
CodeSymbol,
|
|
47
|
+
CodeSymbolKind,
|
|
48
|
+
ParseResult,
|
|
49
|
+
} from './code-symbol.js';
|
|
36
50
|
// === Conduit Protocol (agent-to-agent communication) ===
|
|
37
51
|
export type {
|
|
38
52
|
Conduit,
|
|
@@ -76,6 +90,7 @@ export type {
|
|
|
76
90
|
ArchiveFields,
|
|
77
91
|
ArchiveFile,
|
|
78
92
|
DataAccessor,
|
|
93
|
+
DataAccessorAgentInstance,
|
|
79
94
|
QueryTasksResult,
|
|
80
95
|
TaskFieldUpdates,
|
|
81
96
|
TaskQueryFilters,
|
|
@@ -182,6 +197,14 @@ export type {
|
|
|
182
197
|
export * as ops from './operations/index.js';
|
|
183
198
|
// Commonly used ops types re-exported at top level for convenience
|
|
184
199
|
export type { BrainState } from './operations/orchestrate.js';
|
|
200
|
+
// === Orchestration Hierarchy ===
|
|
201
|
+
export {
|
|
202
|
+
type AgentHierarchy,
|
|
203
|
+
type AgentHierarchyEntry,
|
|
204
|
+
type EscalationChain,
|
|
205
|
+
type OrchestrationHierarchyAPI,
|
|
206
|
+
OrchestrationLevel,
|
|
207
|
+
} from './orchestration-hierarchy.js';
|
|
185
208
|
export type { AdapterPathProvider } from './provider-paths.js';
|
|
186
209
|
// === Result Types (Dashboard, Stats, Log, Context, Sequence, Analysis, Deps) ===
|
|
187
210
|
export type {
|
|
@@ -313,7 +336,12 @@ export type {
|
|
|
313
336
|
TesseraTemplate,
|
|
314
337
|
TesseraVariable,
|
|
315
338
|
} from './tessera.js';
|
|
316
|
-
|
|
339
|
+
// === Transport (low-level wire protocol) ===
|
|
340
|
+
export type {
|
|
341
|
+
AdapterTransportProvider,
|
|
342
|
+
Transport,
|
|
343
|
+
TransportConnectConfig,
|
|
344
|
+
} from './transport.js';
|
|
317
345
|
// === WarpChain Types ===
|
|
318
346
|
export type {
|
|
319
347
|
ChainShape,
|
|
@@ -329,3 +357,6 @@ export type {
|
|
|
329
357
|
WarpLink,
|
|
330
358
|
WarpStage,
|
|
331
359
|
} from './warp-chain.js';
|
|
360
|
+
|
|
361
|
+
// === WASM SDK (Rust crate bindings) ===
|
|
362
|
+
export * as wasm from './wasm/index.js';
|
package/src/lafs.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* LAFS (LLM-Agent-First Schema) unified envelope types.
|
|
3
3
|
*
|
|
4
4
|
* Defines canonical LAFS types inline (contracts has ZERO external dependencies).
|
|
5
|
-
* In the main CLEO codebase these are re-exported from @cleocode/lafs
|
|
5
|
+
* In the main CLEO codebase these are re-exported from @cleocode/lafs;
|
|
6
6
|
* here they are defined as plain interfaces for maximum portability.
|
|
7
7
|
*
|
|
8
8
|
* @epic T4654
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
|
-
// Canonical LAFS types (inlined from @cleocode/lafs
|
|
13
|
+
// Canonical LAFS types (inlined from @cleocode/lafs)
|
|
14
14
|
// ---------------------------------------------------------------------------
|
|
15
15
|
|
|
16
16
|
/** LAFS error category. */
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestration Hierarchy — 5-level agent hierarchy types.
|
|
3
|
+
*
|
|
4
|
+
* Codifies the agent authority chain from ORCH-PLAN.md:
|
|
5
|
+
* Level 0: HITL (Human-In-The-Loop) — Owner, final authority
|
|
6
|
+
* Level 1: Prime Orchestrator — Cross-project coordination
|
|
7
|
+
* Level 2: Project Lead — Project-level architecture decisions
|
|
8
|
+
* Level 3: Team Lead — Team-level task management, can spawn ephemeral agents
|
|
9
|
+
* Level 4: Ephemeral — Task-scoped agents spawned by Team Leads
|
|
10
|
+
*
|
|
11
|
+
* @see docs/specs/CLEO-ORCH-PLAN.md
|
|
12
|
+
* @task T217
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Hierarchy levels
|
|
17
|
+
// ============================================================================
|
|
18
|
+
|
|
19
|
+
/** The 5 orchestration levels in order of authority. */
|
|
20
|
+
export enum OrchestrationLevel {
|
|
21
|
+
/** Level 0: Human owner. Final authority. Never contacted by agents directly. */
|
|
22
|
+
HITL = 0,
|
|
23
|
+
/** Level 1: Prime Orchestrator. Cross-project coordination. Breaks ties. */
|
|
24
|
+
Prime = 1,
|
|
25
|
+
/** Level 2: Project Lead. Architecture decisions within a project. */
|
|
26
|
+
ProjectLead = 2,
|
|
27
|
+
/** Level 3: Team Lead. Task management. Can spawn ephemeral agents. */
|
|
28
|
+
TeamLead = 3,
|
|
29
|
+
/** Level 4: Ephemeral agent. Task-scoped, short-lived. */
|
|
30
|
+
Ephemeral = 4,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Agent hierarchy membership
|
|
35
|
+
// ============================================================================
|
|
36
|
+
|
|
37
|
+
/** An agent's position in the orchestration hierarchy. */
|
|
38
|
+
export interface AgentHierarchyEntry {
|
|
39
|
+
/** The agent's unique ID (e.g. 'cleo-rust-lead'). */
|
|
40
|
+
agentId: string;
|
|
41
|
+
/** Display name for human-readable output. */
|
|
42
|
+
displayName: string;
|
|
43
|
+
/** The agent's orchestration level. */
|
|
44
|
+
level: OrchestrationLevel;
|
|
45
|
+
/** The agent's direct superior (null for HITL). */
|
|
46
|
+
reportsTo: string | null;
|
|
47
|
+
/** Agents this agent directly manages (empty for Ephemeral). */
|
|
48
|
+
manages: string[];
|
|
49
|
+
/** Project scope (null for cross-project agents like Prime). */
|
|
50
|
+
projectId: string | null;
|
|
51
|
+
/** Team scope within a project (e.g. 'cleocode', 'signaldock'). */
|
|
52
|
+
teamId: string | null;
|
|
53
|
+
/** Whether this agent can spawn ephemeral sub-agents. */
|
|
54
|
+
canSpawn: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The full agent hierarchy tree. */
|
|
58
|
+
export interface AgentHierarchy {
|
|
59
|
+
/** All agents in the hierarchy, keyed by agentId. */
|
|
60
|
+
agents: Record<string, AgentHierarchyEntry>;
|
|
61
|
+
/** The Prime Orchestrator agent ID. */
|
|
62
|
+
primeId: string;
|
|
63
|
+
/** Project IDs in this hierarchy. */
|
|
64
|
+
projectIds: string[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Escalation chain
|
|
69
|
+
// ============================================================================
|
|
70
|
+
|
|
71
|
+
/** An escalation path from an agent to its authority chain. */
|
|
72
|
+
export interface EscalationChain {
|
|
73
|
+
/** The requesting agent. */
|
|
74
|
+
fromAgentId: string;
|
|
75
|
+
/** Ordered list of agents to escalate to (nearest first). */
|
|
76
|
+
chain: string[];
|
|
77
|
+
/** The final authority (PRIME or HITL). */
|
|
78
|
+
finalAuthority: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ============================================================================
|
|
82
|
+
// Hierarchy API
|
|
83
|
+
// ============================================================================
|
|
84
|
+
|
|
85
|
+
/** API for querying and managing the agent hierarchy. */
|
|
86
|
+
export interface OrchestrationHierarchyAPI {
|
|
87
|
+
/** Get the full hierarchy. */
|
|
88
|
+
getHierarchy(): AgentHierarchy;
|
|
89
|
+
|
|
90
|
+
/** Get a single agent's hierarchy entry. */
|
|
91
|
+
getAgent(agentId: string): AgentHierarchyEntry | null;
|
|
92
|
+
|
|
93
|
+
/** Get all agents at a specific level. */
|
|
94
|
+
getAgentsAtLevel(level: OrchestrationLevel): AgentHierarchyEntry[];
|
|
95
|
+
|
|
96
|
+
/** Get the escalation chain for an agent. */
|
|
97
|
+
getEscalationChain(agentId: string): EscalationChain;
|
|
98
|
+
|
|
99
|
+
/** Get all agents managed by a specific agent (direct reports). */
|
|
100
|
+
getDirectReports(agentId: string): AgentHierarchyEntry[];
|
|
101
|
+
|
|
102
|
+
/** Check if agent A has authority over agent B. */
|
|
103
|
+
hasAuthority(agentIdA: string, agentIdB: string): boolean;
|
|
104
|
+
|
|
105
|
+
/** Get all agents scoped to a project. */
|
|
106
|
+
getProjectAgents(projectId: string): AgentHierarchyEntry[];
|
|
107
|
+
}
|
package/src/task.ts
CHANGED
|
@@ -214,6 +214,9 @@ export interface Task {
|
|
|
214
214
|
* @task T060
|
|
215
215
|
*/
|
|
216
216
|
pipelineStage?: string | null;
|
|
217
|
+
|
|
218
|
+
/** Agent ID that has claimed/is assigned to this task. Null when unclaimed. */
|
|
219
|
+
assignee?: string | null;
|
|
217
220
|
}
|
|
218
221
|
|
|
219
222
|
// ---------------------------------------------------------------------------
|
package/src/transport.ts
CHANGED
|
@@ -1,12 +1,76 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Transport
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Transport — Low-level wire protocol adapters for agent messaging.
|
|
3
|
+
*
|
|
4
|
+
* Transport is the HOW layer: it moves messages over the wire using
|
|
5
|
+
* HTTP polling, SSE, WebSocket, or in-process napi-rs calls.
|
|
6
|
+
*
|
|
7
|
+
* The Conduit interface (conduit.ts) wraps Transport to provide
|
|
8
|
+
* high-level messaging semantics (WHAT the agent wants to do).
|
|
9
|
+
*
|
|
10
|
+
* @see docs/specs/SIGNALDOCK-UNIFIED-AGENT-REGISTRY.md Section 4
|
|
11
|
+
* @module transport
|
|
5
12
|
*/
|
|
6
13
|
|
|
14
|
+
import type { TransportConfig } from './agent-registry.js';
|
|
15
|
+
import type { ConduitMessage } from './conduit.js';
|
|
16
|
+
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Transport connection config
|
|
19
|
+
// ============================================================================
|
|
20
|
+
|
|
21
|
+
/** Configuration passed to Transport.connect(). */
|
|
22
|
+
export interface TransportConnectConfig extends TransportConfig {
|
|
23
|
+
/** Agent ID to connect as. */
|
|
24
|
+
agentId: string;
|
|
25
|
+
/** API key for authentication. */
|
|
26
|
+
apiKey: string;
|
|
27
|
+
/** Base URL of the messaging API. */
|
|
28
|
+
apiBaseUrl: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Transport interface
|
|
33
|
+
// ============================================================================
|
|
34
|
+
|
|
35
|
+
/** Low-level wire transport for agent messaging. */
|
|
36
|
+
export interface Transport {
|
|
37
|
+
/** Transport name for logging/debugging (e.g. 'http', 'sse', 'ws', 'local'). */
|
|
38
|
+
readonly name: string;
|
|
39
|
+
|
|
40
|
+
/** Connect to the messaging backend. */
|
|
41
|
+
connect(config: TransportConnectConfig): Promise<void>;
|
|
42
|
+
|
|
43
|
+
/** Disconnect from the messaging backend. */
|
|
44
|
+
disconnect(): Promise<void>;
|
|
45
|
+
|
|
46
|
+
/** Send a message payload. */
|
|
47
|
+
push(
|
|
48
|
+
to: string,
|
|
49
|
+
content: string,
|
|
50
|
+
options?: {
|
|
51
|
+
conversationId?: string;
|
|
52
|
+
replyTo?: string;
|
|
53
|
+
},
|
|
54
|
+
): Promise<{ messageId: string }>;
|
|
55
|
+
|
|
56
|
+
/** Poll for new messages (non-destructive peek). */
|
|
57
|
+
poll(options?: { limit?: number; since?: string }): Promise<ConduitMessage[]>;
|
|
58
|
+
|
|
59
|
+
/** Acknowledge processed messages (marks as delivered). */
|
|
60
|
+
ack(messageIds: string[]): Promise<void>;
|
|
61
|
+
|
|
62
|
+
/** Subscribe to real-time events (SSE/WebSocket). Returns unsubscribe. */
|
|
63
|
+
subscribe?(handler: (message: ConduitMessage) => void): () => void;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// Legacy adapter (kept for backward compatibility during migration)
|
|
68
|
+
// ============================================================================
|
|
69
|
+
|
|
70
|
+
/** @deprecated Use Transport instead. Will be removed after unification. */
|
|
7
71
|
export interface AdapterTransportProvider {
|
|
8
|
-
/** Create a transport instance for inter-agent communication */
|
|
72
|
+
/** Create a transport instance for inter-agent communication. */
|
|
9
73
|
createTransport(): unknown;
|
|
10
|
-
/** Name of this transport type for logging/debugging */
|
|
74
|
+
/** Name of this transport type for logging/debugging. */
|
|
11
75
|
readonly transportName: string;
|
|
12
76
|
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central WASM SDK for CLEO Core Contracts
|
|
3
|
+
*
|
|
4
|
+
* Provides unified access to all Rust crate WASM modules:
|
|
5
|
+
* - lafs-core: LAFS envelope types and validation
|
|
6
|
+
* - conduit-core: Conduit wire types and CANT metadata
|
|
7
|
+
* - cant-core: CANT grammar parser (via @cleocode/cant)
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { initWasm, lafs, conduit } from '@cleocode/contracts/wasm';
|
|
12
|
+
*
|
|
13
|
+
* await initWasm();
|
|
14
|
+
*
|
|
15
|
+
* // LAFS
|
|
16
|
+
* const meta = new lafs.WasmLafsMeta('tasks.list', 'http');
|
|
17
|
+
* const envelope = lafs.WasmLafsEnvelope.createSuccess('{"tasks":[]}', meta);
|
|
18
|
+
*
|
|
19
|
+
* // Conduit
|
|
20
|
+
* const msg = new conduit.WasmConduitMessage('msg-1', 'agent-a', 'Hello', '2026-03-25T00:00:00Z');
|
|
21
|
+
* const cant = new conduit.WasmCantMetadata('actionable', '["@agent"]', '["T123"]', '["#tag"]');
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** Resolved type of the lafs-core WASM module. */
|
|
26
|
+
type LafsWasmModule = typeof import('./lafs-core/lafs_core.js');
|
|
27
|
+
/** Resolved type of the conduit-core WASM module. */
|
|
28
|
+
type ConduitWasmModule = typeof import('./conduit-core/conduit_core.js');
|
|
29
|
+
|
|
30
|
+
// WASM module instances
|
|
31
|
+
let lafsModule: LafsWasmModule | null = null;
|
|
32
|
+
let conduitModule: ConduitWasmModule | null = null;
|
|
33
|
+
let isInitialized = false;
|
|
34
|
+
let isInitializing = false;
|
|
35
|
+
let initPromise: Promise<void> | null = null;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Initialize all WASM modules
|
|
39
|
+
* Must be called before using any WASM classes/functions
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* import { initWasm, lafs, conduit } from '@cleocode/contracts/wasm';
|
|
44
|
+
*
|
|
45
|
+
* await initWasm();
|
|
46
|
+
*
|
|
47
|
+
* // Now you can use WASM classes
|
|
48
|
+
* const meta = new lafs.WasmLafsMeta('tasks.list', 'http');
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export async function initWasm(): Promise<void> {
|
|
52
|
+
if (isInitialized) return;
|
|
53
|
+
if (isInitializing) {
|
|
54
|
+
return initPromise!;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
isInitializing = true;
|
|
58
|
+
initPromise = (async () => {
|
|
59
|
+
try {
|
|
60
|
+
// Dynamic imports to avoid loading if not needed
|
|
61
|
+
const [lafs, conduit] = await Promise.all([
|
|
62
|
+
import('./lafs-core/lafs_core.js'),
|
|
63
|
+
import('./conduit-core/conduit_core.js'),
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
// Initialize modules
|
|
67
|
+
await Promise.all([lafs.default(), conduit.default()]);
|
|
68
|
+
|
|
69
|
+
lafsModule = lafs;
|
|
70
|
+
conduitModule = conduit;
|
|
71
|
+
isInitialized = true;
|
|
72
|
+
} catch (_error) {
|
|
73
|
+
throw new Error('WASM initialization failed. Ensure WASM files are present.');
|
|
74
|
+
}
|
|
75
|
+
})();
|
|
76
|
+
|
|
77
|
+
await initPromise;
|
|
78
|
+
isInitializing = false;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Check if WASM is initialized and ready to use
|
|
83
|
+
*
|
|
84
|
+
* @returns true if WASM modules are loaded and initialized
|
|
85
|
+
*/
|
|
86
|
+
export function isWasmReady(): boolean {
|
|
87
|
+
return isInitialized;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* LAFS Core WASM exports
|
|
92
|
+
*
|
|
93
|
+
* Available after calling initWasm():
|
|
94
|
+
* - WasmLafsTransport - Transport type (Cli, Http, Grpc, Sdk)
|
|
95
|
+
* - WasmLafsMeta - Metadata for LAFS envelopes
|
|
96
|
+
* - WasmLafsEnvelope - The main LAFS response envelope
|
|
97
|
+
* - createTransport() - Helper to create transport from string
|
|
98
|
+
*/
|
|
99
|
+
export const lafs = {
|
|
100
|
+
/**
|
|
101
|
+
* LAFS Transport enum
|
|
102
|
+
* Use WasmLafsTransport.cli(), .http(), .grpc(), or .sdk()
|
|
103
|
+
*/
|
|
104
|
+
get WasmLafsTransport() {
|
|
105
|
+
if (!lafsModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
106
|
+
return lafsModule.WasmLafsTransport;
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* LAFS Metadata constructor
|
|
111
|
+
* new WasmLafsMeta(operation: string, transport: string)
|
|
112
|
+
*/
|
|
113
|
+
get WasmLafsMeta() {
|
|
114
|
+
if (!lafsModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
115
|
+
return lafsModule.WasmLafsMeta;
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* LAFS Envelope class
|
|
120
|
+
* Use WasmLafsEnvelope.createSuccess() or .createError()
|
|
121
|
+
*/
|
|
122
|
+
get WasmLafsEnvelope() {
|
|
123
|
+
if (!lafsModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
124
|
+
return lafsModule.WasmLafsEnvelope;
|
|
125
|
+
},
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Helper function to create transport from string
|
|
129
|
+
* @param transport - "cli", "http", "grpc", or "sdk"
|
|
130
|
+
*/
|
|
131
|
+
get createTransport() {
|
|
132
|
+
if (!lafsModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
133
|
+
return lafsModule.create_transport;
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Conduit Core WASM exports
|
|
139
|
+
*
|
|
140
|
+
* Available after calling initWasm():
|
|
141
|
+
* - WasmConduitMessage - Agent-to-agent messages
|
|
142
|
+
* - WasmConduitState - Connection states (Disconnected, Connecting, Connected, etc.)
|
|
143
|
+
* - WasmCantMetadata - CANT parsing results
|
|
144
|
+
* - parseConduitMessage() - Parse message from JSON
|
|
145
|
+
* - createConduitState() - Create state from string
|
|
146
|
+
*/
|
|
147
|
+
export const conduit = {
|
|
148
|
+
/**
|
|
149
|
+
* Conduit Message constructor
|
|
150
|
+
* new WasmConduitMessage(id, from, content, timestamp)
|
|
151
|
+
*/
|
|
152
|
+
get WasmConduitMessage() {
|
|
153
|
+
if (!conduitModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
154
|
+
return conduitModule.WasmConduitMessage;
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Conduit State enum
|
|
159
|
+
* Use WasmConduitState.disconnected(), .connecting(), .connected(), etc.
|
|
160
|
+
*/
|
|
161
|
+
get WasmConduitState() {
|
|
162
|
+
if (!conduitModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
163
|
+
return conduitModule.WasmConduitState;
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* CANT Metadata constructor
|
|
168
|
+
* new WasmCantMetadata(directiveType, addressesJson, taskRefsJson, tagsJson)
|
|
169
|
+
*/
|
|
170
|
+
get WasmCantMetadata() {
|
|
171
|
+
if (!conduitModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
172
|
+
return conduitModule.WasmCantMetadata;
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Parse a ConduitMessage from JSON string
|
|
177
|
+
* @param json - JSON string
|
|
178
|
+
* @returns WasmConduitMessage or undefined
|
|
179
|
+
*/
|
|
180
|
+
get parseConduitMessage() {
|
|
181
|
+
if (!conduitModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
182
|
+
return conduitModule.parse_conduit_message;
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Create a ConduitState from string
|
|
187
|
+
* @param state - "disconnected", "connecting", "connected", "reconnecting", "error"
|
|
188
|
+
*/
|
|
189
|
+
get createConduitState() {
|
|
190
|
+
if (!conduitModule) throw new Error('WASM not initialized. Call initWasm() first.');
|
|
191
|
+
return conduitModule.create_conduit_state;
|
|
192
|
+
},
|
|
193
|
+
};
|