@convilyn/sdk-author 0.7.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.
@@ -0,0 +1,1158 @@
1
+ import { ZodTypeAny, TypeOf } from 'zod';
2
+ import { Server } from 'node:http';
3
+
4
+ /** The SDK release version (independent of the manifest schema version). */
5
+ declare const VERSION = "0.7.0";
6
+ /**
7
+ * The schema version stamped into a compiled manifest's `sdk_version` field —
8
+ * kept in lockstep with the Python / Go author SDKs' manifest format.
9
+ */
10
+ declare const MANIFEST_SDK_VERSION = "1.0.0";
11
+
12
+ /**
13
+ * Typed errors raised by the Author SDK — a faithful port of the Python / Go
14
+ * author SDKs.
15
+ *
16
+ * ConvilynAuthorError base; everything the SDK throws
17
+ * ├── InvalidSignatureError inbound HMAC verification failed
18
+ * ├── ConvilynStartupError server cannot safely start (fail-closed gate)
19
+ * └── ConfirmationInvalidError confirmation-handshake token rejected
20
+ */
21
+ /** Base class for every error the Author SDK throws. */
22
+ declare class ConvilynAuthorError extends Error {
23
+ constructor(message: string);
24
+ }
25
+ /** Stable machine-readable reason for an {@link InvalidSignatureError}. */
26
+ type InvalidSignatureReason = 'missing_secret' | 'missing_header' | 'invalid_timestamp' | 'timestamp_out_of_range' | 'signature_mismatch';
27
+ /**
28
+ * Raised when an inbound HMAC signature fails verification. `reason` is a stable
29
+ * machine-readable code; `message` is human-readable and safe to log. Reasons
30
+ * are intentionally coarse to avoid leaking signing details to attackers.
31
+ */
32
+ declare class InvalidSignatureError extends ConvilynAuthorError {
33
+ readonly reason: InvalidSignatureReason;
34
+ constructor(reason: InvalidSignatureReason, message: string);
35
+ }
36
+ /**
37
+ * Raised when the server cannot safely start — e.g. `serve()` without
38
+ * `CONVILYN_HMAC_SECRET` and without the explicit insecure-local-dev opt-in.
39
+ * Port of the Python / Go `ConvilynStartupError` (fail-closed startup
40
+ * contract).
41
+ */
42
+ declare class ConvilynStartupError extends ConvilynAuthorError {
43
+ constructor(message: string);
44
+ }
45
+ /**
46
+ * Raised when a platform API call (via {@link ConvilynClient}) returns a non-2xx
47
+ * response. `status` is the HTTP status; `body` is the parsed JSON (or text) the
48
+ * server returned.
49
+ */
50
+ declare class ConvilynApiError extends ConvilynAuthorError {
51
+ readonly status: number;
52
+ readonly body: unknown;
53
+ constructor(status: number, message: string, body: unknown);
54
+ }
55
+ /** Stable machine-readable reason for a {@link ConfirmationInvalidError}. */
56
+ type ConfirmationInvalidReason = 'malformed' | 'expired' | 'digest_mismatch' | 'signature_mismatch';
57
+ /**
58
+ * Raised when a confirmation-handshake token fails verification. `reason` is a
59
+ * stable machine-readable code (maps to the framework's `CONFIRMATION_INVALID`).
60
+ */
61
+ declare class ConfirmationInvalidError extends ConvilynAuthorError {
62
+ readonly reason: ConfirmationInvalidReason;
63
+ constructor(reason: ConfirmationInvalidReason, message: string);
64
+ }
65
+
66
+ /**
67
+ * Inbound HMAC verification for calls from the Convilyn gateway, plus the
68
+ * matching signer. Mirrors the gateway's `mcp_gateway/hmac_signer.py` and the
69
+ * Python / Go author SDKs **byte-for-byte**, so a TS-authored server is
70
+ * interchangeable behind the same gateway.
71
+ *
72
+ * Wire format:
73
+ * - `x-convilyn-signature` — HMAC-SHA256 hex digest
74
+ * - `x-convilyn-timestamp` — Unix seconds (integer string)
75
+ * - `x-convilyn-server-id` — server name, audit-only (NOT in the signed payload)
76
+ *
77
+ * Signed payload = `<timestamp>` bytes + `.` + raw body bytes. Comparison is
78
+ * constant-time; a timestamp tolerance window defends against replay.
79
+ *
80
+ * This is a public author capability: a server using its own HTTP framework
81
+ * (instead of the SDK's runtime) calls {@link verifySignature} to reject forged
82
+ * requests.
83
+ */
84
+ /** HMAC header names (lowercase; match the gateway's signer). */
85
+ declare const SIGNATURE_HEADER = "x-convilyn-signature";
86
+ declare const TIMESTAMP_HEADER = "x-convilyn-timestamp";
87
+ declare const SERVER_ID_HEADER = "x-convilyn-server-id";
88
+ /** Default replay window (seconds) vs the gateway clock. */
89
+ declare const DEFAULT_HMAC_TOLERANCE_SECONDS = 300;
90
+ /**
91
+ * Body accepted by the signer / verifier. The gateway signs the **raw body
92
+ * bytes**, so a binary or non-UTF-8 body MUST be passed as `Uint8Array` — a
93
+ * lossy-decoded `string` re-encodes as UTF-8 and will not reproduce the digest
94
+ * (the request is rejected, never falsely accepted).
95
+ */
96
+ type RequestBody = string | Uint8Array;
97
+ /**
98
+ * Produce the `{ signature, timestamp }` pair for an outbound request, mirroring
99
+ * the gateway's signer. Useful for tests and for clients calling a
100
+ * developer-hosted server directly. `unixSeconds` is truncated to an integer.
101
+ */
102
+ declare function signRequest(secret: string, body: RequestBody, unixSeconds: number): {
103
+ signature: string;
104
+ timestamp: string;
105
+ };
106
+ /** Tunables for {@link verifySignature}. */
107
+ interface VerifyOptions {
108
+ /** Max clock skew (seconds) vs the gateway; `<= 0` uses the default 300. */
109
+ toleranceSeconds?: number;
110
+ /** Override "now" (Unix seconds) for tests; defaults to the real clock. */
111
+ now?: () => number;
112
+ }
113
+ /**
114
+ * Verify an inbound HMAC signature; throw {@link InvalidSignatureError} on any
115
+ * failure (missing secret/headers, malformed or out-of-tolerance timestamp, or
116
+ * digest mismatch). Header keys must be lowercased.
117
+ */
118
+ declare function verifySignature(secret: string, body: RequestBody, headers: Record<string, string | undefined>, options?: VerifyOptions): void;
119
+
120
+ /**
121
+ * Core value types shared across the Author SDK — tool results, error details,
122
+ * data references, and the manifest schema rows. Mirrors the Go SDK's `types.go`
123
+ * and the Python `types.py`. Domain fields are camelCase; the snake_case wire
124
+ * mapping lives in `manifest.ts` (and, later, the JSON-RPC runtime).
125
+ */
126
+ /** Reference to data stored in the ToolDataStore (the LLM sees only the summary). */
127
+ interface ToolDataRef {
128
+ refId: string;
129
+ summary: string;
130
+ }
131
+ /** Structured error detail for a failed tool execution. */
132
+ interface ToolError {
133
+ code: string;
134
+ message: string;
135
+ details?: Record<string, unknown>;
136
+ }
137
+ /** Result returned from a tool execution. Build via {@link ToolResult.ok} / `.fail`. */
138
+ interface ToolResult {
139
+ success: boolean;
140
+ data?: Record<string, unknown>;
141
+ error?: ToolError;
142
+ executionTimeMs?: number;
143
+ /**
144
+ * Optional LLM-facing one-line summary. When set it becomes the wire
145
+ * envelope's required `summary`; otherwise the JSON-RPC runtime derives one.
146
+ * (Added in A3; omitting it preserves the A1 `ok` / `fail` shapes exactly.)
147
+ */
148
+ summary?: string;
149
+ }
150
+ /** Constructors for {@link ToolResult} (mirrors Python `ToolResult.ok` / `.fail`). */
151
+ declare const ToolResult: {
152
+ ok(data: Record<string, unknown>, summary?: string): ToolResult;
153
+ fail(code: string, message: string, details?: Record<string, unknown>, summary?: string): ToolResult;
154
+ };
155
+ /** Manifest schema for a single tool. */
156
+ interface ToolSpec {
157
+ name: string;
158
+ description: string;
159
+ inputSchema: Record<string, unknown>;
160
+ idempotent: boolean;
161
+ outputSchema?: Record<string, unknown>;
162
+ }
163
+ /** Manifest schema for the server section. */
164
+ interface ServerSpec {
165
+ name: string;
166
+ version: string;
167
+ description: string;
168
+ mcpServerName?: string;
169
+ }
170
+ /** One line of a compliance report. */
171
+ interface ComplianceResult {
172
+ passed: boolean;
173
+ checkName: string;
174
+ message: string;
175
+ details?: Record<string, unknown>;
176
+ }
177
+ /** Full report from a local compliance run. */
178
+ interface ComplianceReport {
179
+ results: ComplianceResult[];
180
+ }
181
+ /** True when every check in the report passed. */
182
+ declare function allChecksPassed(report: ComplianceReport): boolean;
183
+ /** Just the failing checks of a report. */
184
+ declare function failedChecks(report: ComplianceReport): ComplianceResult[];
185
+
186
+ /**
187
+ * The compiled blueprint of a ToolServer — its tools and capabilities described
188
+ * without running any code. The gateway consumes this to configure routing and
189
+ * agent tool binding. Port of the Python / Go `ConvilynManifest`.
190
+ *
191
+ * Serialisation maps the camelCase domain to the snake_case wire shape and keeps
192
+ * empty lists as `[]` (never omitted), matching the Python/Go output byte-exactly.
193
+ */
194
+
195
+ /** Options for constructing a {@link ConvilynManifest}. */
196
+ interface ConvilynManifestOptions {
197
+ tools?: ToolSpec[];
198
+ capabilities?: string[];
199
+ sdkVersion?: string;
200
+ }
201
+ /** The compiled blueprint of a ToolServer. */
202
+ declare class ConvilynManifest {
203
+ readonly sdkVersion: string;
204
+ readonly server: ServerSpec;
205
+ readonly tools: ToolSpec[];
206
+ readonly capabilities: string[];
207
+ constructor(server: ServerSpec, options?: ConvilynManifestOptions);
208
+ /** The platform wire object (snake_case; empty lists kept as `[]`). */
209
+ toWire(): Record<string, unknown>;
210
+ /** The manifest serialised as 2-space-indented JSON. */
211
+ toJson(): string;
212
+ /** Write the manifest to a JSON file (default `convilyn.manifest.json`). */
213
+ save(path?: string): Promise<string>;
214
+ /** Parse a manifest from its wire object. */
215
+ static fromWire(wire: Record<string, unknown>): ConvilynManifest;
216
+ /** Parse a manifest from a JSON string. */
217
+ static fromJson(data: string): ConvilynManifest;
218
+ /** Read a manifest from a JSON file (default `convilyn.manifest.json`). */
219
+ static load(path?: string): Promise<ConvilynManifest>;
220
+ }
221
+
222
+ /**
223
+ * Environment-driven SDK configuration for a tool server. Port of the Go
224
+ * `SDKConfig` / Python frozen `SDKConfig`. Read it with {@link SDKConfig.fromEnv};
225
+ * construct directly (with explicit options) in tests.
226
+ */
227
+ /** Construction options for {@link SDKConfig}; each falls back to a default. */
228
+ interface SDKConfigOptions {
229
+ serverHost?: string;
230
+ serverPort?: number;
231
+ logLevel?: string;
232
+ awsRegion?: string;
233
+ dynamodbEndpoint?: string;
234
+ toolDataTable?: string;
235
+ environment?: string;
236
+ apiKey?: string;
237
+ platformUrl?: string;
238
+ hmacSecret?: string;
239
+ hmacToleranceSeconds?: number;
240
+ /** Secret for minting / verifying confirmation-handshake tokens. */
241
+ toolConfirmationSecret?: string;
242
+ /** Whether the process runs in AWS Lambda (set by {@link SDKConfig.fromEnv}). */
243
+ lambda?: boolean;
244
+ }
245
+ type EnvLike = Record<string, string | undefined>;
246
+ /** Immutable SDK configuration. */
247
+ declare class SDKConfig {
248
+ #private;
249
+ readonly serverHost: string;
250
+ readonly serverPort: number;
251
+ readonly logLevel: string;
252
+ readonly awsRegion: string;
253
+ readonly dynamodbEndpoint: string;
254
+ readonly toolDataTable: string;
255
+ readonly environment: string;
256
+ readonly apiKey: string;
257
+ readonly platformUrl: string;
258
+ readonly hmacSecret: string;
259
+ readonly hmacToleranceSeconds: number;
260
+ readonly toolConfirmationSecret: string;
261
+ constructor(options?: SDKConfigOptions);
262
+ /** True when running in AWS Lambda. */
263
+ get isLambda(): boolean;
264
+ /** True for a local/dev environment (relaxes HMAC). */
265
+ get isLocal(): boolean;
266
+ /** Load configuration from environment variables, falling back to defaults. */
267
+ static fromEnv(env?: EnvLike): SDKConfig;
268
+ }
269
+
270
+ /**
271
+ * Pluggable store for large tool outputs — tools return `{ ref_id, summary }` so
272
+ * the LLM context stays small, then the agent retrieves the full data later by
273
+ * `ref_id`. Port of the Python `DataStoreProtocol` / Go `DataStore`.
274
+ */
275
+
276
+ /**
277
+ * Stores and retrieves large tool outputs by `ref_id`. `get` resolves to `null`
278
+ * for an unknown id — a miss is not an error.
279
+ */
280
+ interface DataStore {
281
+ store(data: Record<string, unknown>): Promise<string>;
282
+ get(refId: string): Promise<Record<string, unknown> | null>;
283
+ }
284
+ /** Generate a `ref_id` in the mcp-shared format `td_<12-hex>`. */
285
+ declare function generateRefId(): string;
286
+ /**
287
+ * Zero-dependency {@link DataStore} for local development and testing. Data is
288
+ * lost when the process exits.
289
+ */
290
+ declare class InMemoryDataStore implements DataStore {
291
+ #private;
292
+ store(data: Record<string, unknown>): Promise<string>;
293
+ get(refId: string): Promise<Record<string, unknown> | null>;
294
+ /** Number of stored entries. */
295
+ get size(): number;
296
+ }
297
+ /**
298
+ * Build the appropriate {@link DataStore} for the config. A1 ships the in-memory
299
+ * store; the DynamoDB-backed production store lands in a later increment, keyed
300
+ * off `config.isLambda`.
301
+ */
302
+ declare function createDataStore(_config?: SDKConfig): DataStore;
303
+
304
+ /**
305
+ * Execution context injected into tools that opt in (by accepting it). Exposes
306
+ * the request id, the shared {@link DataStore}, and a progress channel. Port of
307
+ * the Python / Go `ToolContext`.
308
+ */
309
+
310
+ /** Receives progress reports emitted via {@link ToolContext.reportProgress}. */
311
+ interface ProgressBackend {
312
+ report(requestId: string, percent: number, message: string): void;
313
+ }
314
+ /**
315
+ * Dev-mode {@link ProgressBackend} that writes each report to a sink (defaults
316
+ * to `process.stderr`). Inject `write` for tests or to silence it.
317
+ */
318
+ declare class ConsoleProgressBackend implements ProgressBackend {
319
+ #private;
320
+ constructor(write?: (line: string) => void);
321
+ report(requestId: string, percent: number, message: string): void;
322
+ }
323
+ /**
324
+ * Execution context passed to a tool. Holds the request id, the shared
325
+ * {@link DataStore}, and an optional {@link ProgressBackend}.
326
+ */
327
+ declare class ToolContext {
328
+ #private;
329
+ readonly requestId: string;
330
+ readonly dataStore: DataStore;
331
+ constructor(requestId: string, dataStore: DataStore, progress?: ProgressBackend | null);
332
+ /**
333
+ * Emit a progress update (0–100). Throws {@link RangeError} when `percent` is
334
+ * out of range; a no-op when no {@link ProgressBackend} is wired.
335
+ */
336
+ reportProgress(percent: number, message: string): void;
337
+ }
338
+ /**
339
+ * Build a {@link ToolContext} from a request payload, reading `request_id`
340
+ * (defaulting to `"unknown"`).
341
+ */
342
+ declare function createToolContext(dataStore: DataStore, payload: Record<string, unknown>): ToolContext;
343
+
344
+ /**
345
+ * `WorkflowSpec` — an immutable fluent builder for the portable workflow
346
+ * authoring artifact the platform consumes.
347
+ *
348
+ * Two wire shapes, one method each (single responsibility per contract):
349
+ *
350
+ * - `compile()` emits the snake_case {@link WorkflowBlueprint} — the PUBLIC
351
+ * publish artifact the Developer Portal's `submit_workflow` accepts, in
352
+ * cross-SDK parity with the Python author SDK's `compile()`.
353
+ * - `toExportPayload()` emits the camelCase {@link ExportPayload} — the
354
+ * user_workflows authoring/canvas contract
355
+ * (`docs/contracts/user_workflows/user_workflows_openapi.yaml`), which
356
+ * carries UI-only metadata (positions, notes, canvasLayout) the blueprint
357
+ * deliberately omits.
358
+ *
359
+ * Every `with*` / `add*` / `use*` method returns a NEW `WorkflowSpec` (the
360
+ * receiver is never mutated), matching the project's immutability rule. Contract
361
+ * constraints are enforced client-side so a bad spec fails fast with a clear
362
+ * {@link ConvilynAuthorError} instead of a server 422.
363
+ */
364
+ /** Lifecycle visibility of a persisted workflow (set via the platform, not here). */
365
+ type Visibility = 'private' | 'public' | 'archived';
366
+ /** Provenance of a workflow's fork source. */
367
+ type SourceType = 'curated' | 'user' | 'blank';
368
+ /** 2D position on the Builder canvas — pure UI metadata, ignored by the agent. */
369
+ interface Position {
370
+ x: number;
371
+ y: number;
372
+ }
373
+ /**
374
+ * One tool the agent may call. `toolName` is the
375
+ * `"server-name:tool_name"` form (e.g. `"doc-parser-mcp:extract_text"`).
376
+ * `position` is UI-only and does not affect execution order.
377
+ */
378
+ interface ToolPaletteItem {
379
+ toolName: string;
380
+ position: Position;
381
+ note?: string;
382
+ }
383
+ /** Optional Builder-only canvas state. Ignored by the compiler and the agent. */
384
+ interface CanvasLayout {
385
+ edges?: Array<{
386
+ from: string;
387
+ to: string;
388
+ }>;
389
+ viewport?: {
390
+ zoom?: number;
391
+ pan?: Position;
392
+ };
393
+ }
394
+ /** The camelCase user_workflows authoring/canvas artifact (`ExportPayload`). */
395
+ interface ExportPayload {
396
+ schemaVersion: string;
397
+ name: string;
398
+ description?: string;
399
+ systemPrompt: string;
400
+ toolPalette: ToolPaletteItem[];
401
+ canvasLayout?: CanvasLayout;
402
+ tags: string[];
403
+ }
404
+ /**
405
+ * Public blueprint schema version. The platform's translator is keyed on
406
+ * this so its internal workflow contract can evolve without breaking an
407
+ * already-published author SDK. Mirrors the Python SDK's `PUBLIC_SCHEMA_VERSION`.
408
+ */
409
+ declare const PUBLIC_SCHEMA_VERSION = "1";
410
+ /** Public agent-mode knobs an author may set on a blueprint. */
411
+ interface BlueprintAgentConfig {
412
+ system_prompt?: string;
413
+ max_iterations?: number;
414
+ temperature?: number;
415
+ }
416
+ /** MCP server and tool configuration ("server:tool" refs). */
417
+ interface BlueprintMcpConfig {
418
+ mcp_servers: string[];
419
+ tools: string[];
420
+ }
421
+ /**
422
+ * The compiled PUBLIC publish artifact — snake_case, in cross-SDK parity with
423
+ * the Python author SDK's `WorkflowBlueprint`. This is what the Developer
424
+ * Portal's `submit_workflow` accepts; platform-internal fields (category,
425
+ * platform, prompt-template ids) are injected by the server-side translator.
426
+ */
427
+ interface WorkflowBlueprint {
428
+ public_schema_version: string;
429
+ spec_id: string;
430
+ version: string;
431
+ name: string;
432
+ description?: string;
433
+ keywords?: string[];
434
+ agent_config?: BlueprintAgentConfig;
435
+ mcp_config?: BlueprintMcpConfig;
436
+ }
437
+ /** Cross-SDK alias — the Python SDK names its `compile()` output the same way. */
438
+ type CompiledWorkflowSpec = WorkflowBlueprint;
439
+ /** Immutable builder for a portable workflow spec. */
440
+ declare class WorkflowSpec {
441
+ #private;
442
+ constructor(name: string, options?: {
443
+ specId?: string;
444
+ version?: string;
445
+ });
446
+ get name(): string;
447
+ get description(): string | undefined;
448
+ get systemPrompt(): string;
449
+ get schemaVersion(): string;
450
+ get specId(): string | undefined;
451
+ get version(): string;
452
+ get tags(): readonly string[];
453
+ get toolPalette(): readonly ToolPaletteItem[];
454
+ get canvasLayout(): CanvasLayout | undefined;
455
+ withName(name: string): WorkflowSpec;
456
+ withDescription(description: string): WorkflowSpec;
457
+ withSystemPrompt(systemPrompt: string): WorkflowSpec;
458
+ withSchemaVersion(schemaVersion: string): WorkflowSpec;
459
+ /** Set the portal spec id (`dev_<developer-id>.<name>` namespace). */
460
+ withSpecId(specId: string): WorkflowSpec;
461
+ /** Set the blueprint semver version (default `1.0.0`). */
462
+ withVersion(version: string): WorkflowSpec;
463
+ /** Replace the tag set. */
464
+ withTags(tags: string[]): WorkflowSpec;
465
+ /** Append a tag (no-op if already present). */
466
+ addTag(tag: string): WorkflowSpec;
467
+ /**
468
+ * Add (or replace, by `toolName`) one tool on the palette. Rejects the
469
+ * `request_user_input` tool (invariant I3) and palettes larger than
470
+ * {@link MAX_TOOLS}.
471
+ */
472
+ addTool(toolName: string, options?: {
473
+ position?: Position;
474
+ note?: string;
475
+ }): WorkflowSpec;
476
+ /** Add several tools by name (default canvas position), de-duplicated. */
477
+ useTools(...toolNames: string[]): WorkflowSpec;
478
+ withCanvasLayout(canvasLayout: CanvasLayout): WorkflowSpec;
479
+ /**
480
+ * The PUBLIC publish blueprint (snake_case; Python-SDK parity). This is the
481
+ * shape `submitWorkflow` / `convilyn-author push` send to the Developer
482
+ * Portal. Requires a `specId` (constructor option or {@link withSpecId}).
483
+ *
484
+ * Mirrors the Python SDK's `exclude_none` semantics: `agent_config` is
485
+ * emitted only when a systemPrompt is set, `mcp_config` only when the
486
+ * palette is non-empty. UI-only metadata (positions, notes, canvasLayout)
487
+ * is deliberately NOT emitted — the portal's blueprint schema rejects
488
+ * unknown fields; that data belongs to {@link toExportPayload}.
489
+ */
490
+ compile(): WorkflowBlueprint;
491
+ /** The compiled blueprint serialised as 2-space-indented JSON. */
492
+ compileJson(): string;
493
+ /** Write the compiled blueprint to a JSON file (default `workflow.spec.json`). */
494
+ save(path?: string): Promise<string>;
495
+ /**
496
+ * The camelCase user_workflows `ExportPayload` (canvas/authoring contract).
497
+ * Carries the UI-only metadata (positions, notes, canvasLayout) that the
498
+ * publish blueprint omits.
499
+ */
500
+ toExportPayload(): ExportPayload;
501
+ /** Rebuild a {@link WorkflowSpec} from a user_workflows `ExportPayload`. */
502
+ static fromExportPayload(payload: ExportPayload): WorkflowSpec;
503
+ /**
504
+ * Rebuild a {@link WorkflowSpec} from a publish blueprint. Lossy for canvas
505
+ * metadata by design — that data lives in the `ExportPayload` contract.
506
+ */
507
+ static fromBlueprint(blueprint: WorkflowBlueprint): WorkflowSpec;
508
+ /**
509
+ * Parse a spec from a JSON string. Shape-sniffs: objects carrying `spec_id`
510
+ * or `public_schema_version` parse as a blueprint; anything else as an
511
+ * `ExportPayload` — so `push --workflow-file` accepts both file formats.
512
+ */
513
+ static fromJson(data: string): WorkflowSpec;
514
+ /** Read a saved spec from a JSON file (default `workflow.spec.json`). */
515
+ static load(path?: string): Promise<WorkflowSpec>;
516
+ }
517
+
518
+ /**
519
+ * The five high-level workflow policies an author may attach to a published
520
+ * workflow. Grounded in `docs/contracts/sdk_public_openapi.yaml`
521
+ * (§WorkflowPolicies) — camelCase wire, every field optional. These attach to a
522
+ * community-workflow patch (the platform client, a later increment), so they are
523
+ * standalone here and are NOT folded into {@link WorkflowSpec.compile}.
524
+ */
525
+ /** Failure categories that trigger a retry. */
526
+ type RetryCategory = 'transient' | 'rate_limited' | 'tool_error';
527
+ /** When and how a failed step is retried. */
528
+ interface RetryPolicy {
529
+ /** 1–10. */
530
+ maxAttempts?: number;
531
+ /** ≥ 0. */
532
+ backoffMs?: number;
533
+ retryOn?: RetryCategory[];
534
+ }
535
+ /** Per-workflow wall-clock + step-count bound. */
536
+ interface TimeoutPolicy {
537
+ /** ≥ 1. */
538
+ maxStepCount?: number;
539
+ /** ≥ 1. */
540
+ maxWallClockSeconds?: number;
541
+ }
542
+ /** Structural + quality checks the final artefact must pass. */
543
+ interface OutputValidationPolicy {
544
+ requiredSections?: string[];
545
+ /** ≥ 0. */
546
+ minLengthChars?: number;
547
+ qualityRubric?: string;
548
+ }
549
+ /** Situations in which the workflow must pause for a human answer. */
550
+ type PauseTrigger = 'ambiguity' | 'high_cost' | 'low_confidence';
551
+ /** When the workflow must pause for a human. */
552
+ interface HumanReviewPolicy {
553
+ pauseFor?: PauseTrigger[];
554
+ slotPromptStyle?: 'terse' | 'verbose';
555
+ }
556
+ /** What to do when retries are exhausted or output validation fails. */
557
+ type FallbackAction = 'abort' | 'return_partial' | 'escalate';
558
+ /** Behaviour after retries are exhausted / validation fails. */
559
+ interface FallbackPolicy {
560
+ action?: FallbackAction;
561
+ escalationContact?: string;
562
+ }
563
+ /** The five policies; declare only those you want to constrain. */
564
+ interface WorkflowPolicies {
565
+ retry?: RetryPolicy;
566
+ timeout?: TimeoutPolicy;
567
+ outputValidation?: OutputValidationPolicy;
568
+ humanReview?: HumanReviewPolicy;
569
+ fallback?: FallbackPolicy;
570
+ }
571
+ /**
572
+ * Validate + normalise a {@link WorkflowPolicies} object: range-checks the
573
+ * numeric bounds from the contract and returns a fresh object containing only
574
+ * the sub-policies that were supplied. Throws {@link ConvilynAuthorError} on an
575
+ * out-of-range value.
576
+ */
577
+ declare function buildWorkflowPolicies(input: WorkflowPolicies): WorkflowPolicies;
578
+
579
+ /**
580
+ * `defineTool` — declare a tool for a {@link ToolServer}. The author supplies a
581
+ * Zod schema for the input; the SDK derives the manifest `input_schema`
582
+ * (JSON Schema) from it via `zod-to-json-schema`, statically types the handler
583
+ * args via `z.infer`, and validates inbound `/mcp` arguments against it at
584
+ * runtime. (Design decision: TS has no type-hint reflection, so the
585
+ * schema is author-supplied — Zod is the single source for schema + types +
586
+ * validation. `zod` is a peerDependency and is **not** re-exported.)
587
+ */
588
+
589
+ /** A handler's return — sync or async {@link ToolResult}. */
590
+ type ToolHandlerResult = ToolResult | Promise<ToolResult>;
591
+ /** A compiled tool: its manifest spec, its input validator, and its handler. */
592
+ interface ToolDefinition {
593
+ readonly name: string;
594
+ readonly description: string;
595
+ readonly idempotent: boolean;
596
+ /** The Zod schema; used to validate inbound `/mcp` arguments. */
597
+ readonly inputSchema: ZodTypeAny;
598
+ /** The JSON Schema derived from `inputSchema` (manifest `input_schema`). */
599
+ readonly jsonSchema: Record<string, unknown>;
600
+ /** Optional manifest `output_schema` (a JSON Schema object). */
601
+ readonly outputSchema?: Record<string, unknown>;
602
+ /** Runs the tool with already-validated arguments. */
603
+ readonly handler: (args: unknown, ctx: ToolContext) => ToolHandlerResult;
604
+ /** The manifest row for this tool. */
605
+ toSpec(): ToolSpec;
606
+ }
607
+ /** Definition object accepted by {@link defineTool}. */
608
+ interface ToolDefinitionInput<S extends ZodTypeAny> {
609
+ name: string;
610
+ description: string;
611
+ /** A Zod object schema describing the tool's arguments. */
612
+ input: S;
613
+ idempotent: boolean;
614
+ /** Receives arguments typed by `input` (via `z.infer`) and the execution context. */
615
+ handler: (args: TypeOf<S>, ctx: ToolContext) => ToolHandlerResult;
616
+ /** Optional JSON Schema for the tool's output (manifest only; not validated). */
617
+ outputSchema?: Record<string, unknown>;
618
+ }
619
+ /**
620
+ * Declare a tool. Returns a {@link ToolDefinition} ready to register on a
621
+ * {@link ToolServer}. The `input` Zod schema is the single source of truth for
622
+ * the manifest schema, the handler's argument types, and runtime validation.
623
+ */
624
+ declare function defineTool<S extends ZodTypeAny>(def: ToolDefinitionInput<S>): ToolDefinition;
625
+
626
+ /**
627
+ * JSON-RPC 2.0 envelope types + constructors for the `/mcp` runtime. The wire
628
+ * shape matches the `mcp-shared` framework and the Python / Go author SDKs so a
629
+ * TS-authored server is interchangeable behind the same gateway:
630
+ *
631
+ * request { jsonrpc:"2.0", method:"tools/call", params:{ name, arguments, context? }, id }
632
+ * response { jsonrpc:"2.0", result?, error?:{ code, message, data? }, id }
633
+ *
634
+ * Tool-level outcomes (validation failures, tool errors) ride inside `result`
635
+ * as a ToolResult envelope — only protocol-level faults use the `error` member.
636
+ */
637
+ /** JSON-RPC protocol version string. */
638
+ declare const JSONRPC_VERSION = "2.0";
639
+ /** The single method the runtime dispatches. */
640
+ declare const TOOLS_CALL = "tools/call";
641
+ /** An inbound JSON-RPC request. */
642
+ interface JSONRPCRequest {
643
+ jsonrpc: string;
644
+ method: string;
645
+ params?: Record<string, unknown>;
646
+ id?: string | number | null;
647
+ }
648
+ /** The `error` member of a JSON-RPC response. */
649
+ interface JSONRPCErrorObject {
650
+ code: number;
651
+ message: string;
652
+ data?: Record<string, unknown>;
653
+ }
654
+ /** An outbound JSON-RPC response (exactly one of `result` / `error`). */
655
+ interface JSONRPCResponse {
656
+ jsonrpc: typeof JSONRPC_VERSION;
657
+ result?: unknown;
658
+ error?: JSONRPCErrorObject;
659
+ id: string | number | null;
660
+ }
661
+
662
+ /**
663
+ * `ToolServer` — the registry of an author's tools and the transport-free
664
+ * JSON-RPC dispatcher behind the `/mcp` endpoint. {@link ToolServer.dispatch} is
665
+ * pure (request in, response out), so it is unit-testable without sockets; the
666
+ * Node `http` wiring lives in `http-runtime.ts`.
667
+ *
668
+ * Dispatch contract (matches the `mcp-shared` framework):
669
+ * - only `tools/call` is supported; any other method → `-32601`.
670
+ * - missing `params.name` → `-32602`; unknown tool → `-32601`.
671
+ * - input that fails the tool's Zod schema → a `validation_error` ToolResult
672
+ * envelope inside `result` (NOT a JSON-RPC error).
673
+ * - a handler that throws → `-32603`.
674
+ * - the built-in `get_tool_data` resolves a `ref_id` from the DataStore; it is
675
+ * not listed in the manifest (the platform injects it globally).
676
+ */
677
+
678
+ /** The built-in tool that resolves an offloaded `ref_id` to its full payload. */
679
+ declare const GET_TOOL_DATA = "get_tool_data";
680
+ /** Options for constructing a {@link ToolServer}. */
681
+ interface ToolServerOptions {
682
+ tools?: ToolDefinition[];
683
+ capabilities?: string[];
684
+ /** Backing store for `ref_id` offload + retrieval; defaults to in-memory. */
685
+ dataStore?: DataStore;
686
+ sdkVersion?: string;
687
+ }
688
+ /** The registry of an author's tools plus the JSON-RPC dispatcher. */
689
+ declare class ToolServer {
690
+ #private;
691
+ readonly server: ServerSpec;
692
+ readonly dataStore: DataStore;
693
+ constructor(server: ServerSpec, options?: ToolServerOptions);
694
+ /** Register a tool. Throws on a duplicate name. Chainable. */
695
+ register(tool: ToolDefinition): this;
696
+ /** Names of the registered (author) tools. */
697
+ get toolNames(): string[];
698
+ /** Number of registered (author) tools — the `/health` `tool_count`. */
699
+ get toolCount(): number;
700
+ /** The compiled manifest blueprint for this server. */
701
+ manifest(): ConvilynManifest;
702
+ /**
703
+ * Dispatch one JSON-RPC request. Pure and transport-free: never throws for a
704
+ * tool fault — protocol faults become a JSON-RPC `error`, tool/validation
705
+ * faults become a ToolResult envelope inside `result`.
706
+ */
707
+ dispatch(request: JSONRPCRequest): Promise<JSONRPCResponse>;
708
+ }
709
+
710
+ /**
711
+ * Node `http` runtime for a {@link ToolServer}. Exposes the three endpoints the
712
+ * gateway expects:
713
+ *
714
+ * GET /health → { status, server, version, tool_count }
715
+ * GET /manifest → the server manifest (snake_case wire object)
716
+ * POST /mcp → HMAC-verified JSON-RPC `tools/call` dispatch
717
+ *
718
+ * The HMAC signature covers the **raw request body bytes**, so the body buffer is
719
+ * captured before any `JSON.parse`. Verification reuses {@link verifySignature}
720
+ * (byte-for-byte parity with the gateway signer). No external dependencies.
721
+ */
722
+
723
+ /** Options for {@link serve}; unset fields fall back to {@link SDKConfig}. */
724
+ interface ServeOptions {
725
+ port?: number;
726
+ host?: string;
727
+ /** HMAC secret for `/mcp` verification. Required to accept signed requests. */
728
+ hmacSecret?: string;
729
+ toleranceSeconds?: number;
730
+ /**
731
+ * Explicit INSECURE local-development opt-in: with no secret configured,
732
+ * `serve` refuses to start unless this is `true` (set by `convilyn-author
733
+ * dev`) or `CONVILYN_DEV_INSECURE=1` is in the environment. A configured
734
+ * secret always wins — the opt-in never bypasses verification.
735
+ */
736
+ allowInsecure?: boolean;
737
+ /** Pre-built config; defaults to {@link SDKConfig.fromEnv}. */
738
+ config?: SDKConfig;
739
+ }
740
+ /**
741
+ * Environment variable that explicitly opts a bare `serve()` process into
742
+ * INSECURE local development (no inbound signature verification). Port of the
743
+ * Python `ENV_DEV_INSECURE` / Go `EnvDevInsecure`.
744
+ */
745
+ declare const ENV_DEV_INSECURE = "CONVILYN_DEV_INSECURE";
746
+ /**
747
+ * True iff the operator explicitly opted into insecure local dev. Any other
748
+ * value (including unset) is "not opted in" — the secure default is
749
+ * fail-closed.
750
+ */
751
+ declare function devInsecureRequested(env?: NodeJS.ProcessEnv): boolean;
752
+ /**
753
+ * Build and start an HTTP server for `toolServer`. Returns the listening
754
+ * {@link Server}; await its `listening` event (and read `.address()`) for the
755
+ * bound port when `port` is `0`.
756
+ *
757
+ * **Fail-closed:** unless an HMAC secret is configured, `serve` throws
758
+ * {@link ConvilynStartupError} — independent of `CONVILYN_ENVIRONMENT` or the
759
+ * bind host. Insecure local development must be opted into explicitly, either
760
+ * via `allowInsecure: true` (passed by `convilyn-author dev`) or by setting
761
+ * `CONVILYN_DEV_INSECURE=1`. Port of the Python `start_server`.
762
+ */
763
+ declare function serve(toolServer: ToolServer, options?: ServeOptions): Server;
764
+
765
+ /**
766
+ * Serialises an author-facing {@link ToolResult} into the snake_case ToolResult
767
+ * **wire envelope** the gateway expects. The author SDK keeps the result ergonomic
768
+ * (`ToolResult.ok` / `.fail`); this module bridges it to the richer wire shape:
769
+ *
770
+ * { summary, status, data?, ref_id?, validation_errors?, error?,
771
+ * success, error_code, error_message }
772
+ *
773
+ * `summary` is required on the wire (1–2000 chars); it is taken from
774
+ * {@link ToolResult.summary} when the author set one, otherwise derived here.
775
+ *
776
+ * Scope: statuses `ok` / `tool_error` / `validation_error`. The
777
+ * `needs_confirmation` handshake and `cost_micro_u` / `cost_breakdown` land in a
778
+ * follow-up.
779
+ */
780
+
781
+ /** Tool execution status carried on the wire (A3 subset). */
782
+ type ToolStatus = 'ok' | 'tool_error' | 'validation_error';
783
+ /** One field-level validation failure (status `validation_error`). */
784
+ interface ValidationIssueWire {
785
+ field: string;
786
+ issue: string;
787
+ expected?: string;
788
+ }
789
+ /** The snake_case ToolResult envelope as published on the wire. */
790
+ interface ToolResultWire {
791
+ summary: string;
792
+ status: ToolStatus;
793
+ data?: Record<string, unknown>;
794
+ ref_id?: string;
795
+ validation_errors?: ValidationIssueWire[];
796
+ error?: {
797
+ code: string;
798
+ message: string;
799
+ details?: Record<string, unknown>;
800
+ };
801
+ success: boolean;
802
+ error_code: string | null;
803
+ error_message: string | null;
804
+ }
805
+ /** Inline payloads larger than this (bytes, UTF-8) are offloaded to the DataStore. */
806
+ declare const OUTPUT_INLINE_THRESHOLD_BYTES = 16384;
807
+
808
+ /**
809
+ * Local, offline compliance checks for a {@link ToolServer} — the producer of
810
+ * the {@link ComplianceReport} the `convilyn-author test` command (and the A5
811
+ * local harness) report. No platform calls; nothing leaves the process.
812
+ *
813
+ * Checks are deliberately non-invasive: schemas and the runtime plumbing are
814
+ * exercised, but author tool handlers are NOT blindly invoked (they may have
815
+ * real side effects / external calls). `get_tool_data` is exercised against a
816
+ * value the harness stores itself.
817
+ */
818
+
819
+ /**
820
+ * Run the local compliance suite against a server, returning a
821
+ * {@link ComplianceReport}. Use {@link allChecksPassed} / {@link failedChecks}
822
+ * (from `./types`) to interpret it.
823
+ */
824
+ declare function runComplianceChecks(server: ToolServer): Promise<ComplianceReport>;
825
+
826
+ /**
827
+ * Confirmation-handshake token signing — byte-for-byte compatible with the
828
+ * `mcp-shared` framework and the Python / Go author SDKs, so a token minted by a
829
+ * TS-authored server verifies against the gateway (and vice versa).
830
+ *
831
+ * Token wire format: `base64url("<expires>:<digest>:<sig>")` (RFC 4648 url-safe,
832
+ * **padding kept**), where
833
+ * digest = sha256hex(canonicalJson(normalizeForDigest(arguments)))
834
+ * sig = hmacSha256hex(secret, "<toolName>|<expires>|<digest>")
835
+ *
836
+ * This is a **distinct** scheme from the inbound request HMAC in `./auth` (which
837
+ * signs `<timestamp>.<body>`); the two are not interchangeable.
838
+ *
839
+ * Byte-exactness notes:
840
+ * - `canonicalJson` matches Python `json.dumps(sort_keys=True, separators=(",",":"))`
841
+ * with the default `ensure_ascii=True` — every code point ≥ 0x80 is emitted as
842
+ * `\uXXXX` (surrogate pairs for non-BMP), keys sorted by UTF-16 code unit.
843
+ * - `normalizeForDigest` strips volatile presigned-URL query params before hashing
844
+ * (re-encoding kept params with Python `quote_plus` semantics) so a re-presigned
845
+ * URL still matches the confirmed arguments.
846
+ */
847
+ /** Confirmation token lifetime (seconds); matches the framework constant. */
848
+ declare const CONFIRMATION_TTL_SECONDS = 300;
849
+ /** Recursively drop volatile presign params from any URL strings within `value`. */
850
+ declare function normalizeForDigest(value: unknown): unknown;
851
+ /** Arguments passed to {@link mintConfirmationToken} / {@link verifyConfirmationToken}. */
852
+ interface ConfirmationTokenInput {
853
+ toolName: string;
854
+ arguments: Record<string, unknown>;
855
+ /** Unix seconds at which the token expires. */
856
+ expiresAtUnix: number;
857
+ secret: string;
858
+ }
859
+ /**
860
+ * Mint a confirmation token for a tool call, byte-for-byte compatible with the
861
+ * gateway / Python / Go signer.
862
+ */
863
+ declare function mintConfirmationToken(input: ConfirmationTokenInput): string;
864
+ /** Verification input (`expiresAtUnix` is ignored — it is read from the token). */
865
+ interface VerifyConfirmationInput {
866
+ toolName: string;
867
+ arguments: Record<string, unknown>;
868
+ token: string;
869
+ secret: string;
870
+ /** Override "now" (Unix seconds) for tests; defaults to the real clock. */
871
+ now?: () => number;
872
+ }
873
+ /**
874
+ * Verify a confirmation token against the (re-)supplied arguments. Throws
875
+ * {@link ConfirmationInvalidError} on a malformed / expired / mismatched token.
876
+ * The `confirmation_token` argument (present on the confirming re-call) is
877
+ * stripped before re-computing the digest.
878
+ */
879
+ declare function verifyConfirmationToken(input: VerifyConfirmationInput): void;
880
+
881
+ /**
882
+ * Wire types for the Developer Portal (`/api/v1/developers/*`) consumed by
883
+ * {@link ConvilynClient}. Keys are snake_case, matching the platform's
884
+ * Developer Portal API. These mirror the platform response models, not any
885
+ * Python/Go SDK internal structure.
886
+ */
887
+
888
+ /** Server verification-pipeline status (`ServerVerificationStatus`). */
889
+ type ServerVerificationStatus = 'submitted' | 'validating' | 'sandbox_testing' | 'verified' | 'active' | 'rejected' | 'test_failed' | 'suspended';
890
+ /** Workflow verification-pipeline status (`WorkflowVerificationStatus`). */
891
+ type WorkflowVerificationStatus = 'submitted' | 'validating' | 'sandbox_testing' | 'active' | 'rejected' | 'suspended';
892
+ /** Body for `POST /developers/register`. */
893
+ interface DeveloperRegisterRequest {
894
+ email: string;
895
+ name: string;
896
+ company?: string;
897
+ }
898
+ /** Response of `POST /developers/register`. The `api_key` is shown only once. */
899
+ interface DeveloperRegisterResponse {
900
+ developer_id: string;
901
+ api_key: string;
902
+ status: string;
903
+ }
904
+ /** Body for `POST /developers/servers`. `endpoint_url` must be https + public. */
905
+ interface ServerSubmitRequest {
906
+ manifest: Record<string, unknown>;
907
+ endpoint_url: string;
908
+ }
909
+ /** Response of `POST /developers/servers`. */
910
+ interface ServerSubmitResponse {
911
+ server_id: string;
912
+ server_name: string;
913
+ status: ServerVerificationStatus;
914
+ }
915
+ /** A registered server (item in `GET /developers/servers`). */
916
+ interface DeveloperServer {
917
+ server_id: string;
918
+ server_name: string;
919
+ endpoint_url: string;
920
+ status: ServerVerificationStatus;
921
+ tools: string[];
922
+ created_at?: string | null;
923
+ }
924
+ /** Response of `GET /developers/servers/{id}/status`. */
925
+ interface ServerStatusResponse {
926
+ server_id: string;
927
+ status: ServerVerificationStatus;
928
+ message?: string | null;
929
+ }
930
+ /** Response of a sandbox test run (`POST /developers/servers/{id}/test`). */
931
+ interface TestRunResponse {
932
+ run_id: string;
933
+ status: string;
934
+ results: Record<string, unknown>;
935
+ tool_call_log: Array<Record<string, unknown>>;
936
+ }
937
+ /** Body for `POST /developers/workflows`. */
938
+ interface WorkflowSubmitRequest {
939
+ /** Compiled workflow spec — the `WorkflowSpec.compile()` blueprint (a plain
940
+ * object is also accepted for hand-built specs). */
941
+ workflow_spec: WorkflowBlueprint | Record<string, unknown>;
942
+ /** Server ids whose tools this workflow uses (1–20). */
943
+ server_ids: string[];
944
+ }
945
+ /** Response of `POST /developers/workflows`. */
946
+ interface WorkflowSubmitResponse {
947
+ workflow_id: string;
948
+ spec_id: string;
949
+ status: WorkflowVerificationStatus;
950
+ }
951
+ /** Response of `GET /developers/workflows/{id}/status`. */
952
+ interface WorkflowStatusResponse {
953
+ workflow_id: string;
954
+ spec_id: string;
955
+ status: WorkflowVerificationStatus;
956
+ validation_errors: string[];
957
+ }
958
+ /** A submitted workflow in list view (`GET /developers/workflows`). */
959
+ interface WorkflowListItem {
960
+ workflow_id: string;
961
+ spec_id: string;
962
+ name: string;
963
+ version: string;
964
+ status: WorkflowVerificationStatus;
965
+ server_ids: string[];
966
+ created_at?: string | null;
967
+ }
968
+ /** Per-server health check captured during a workflow test run. */
969
+ interface WorkflowServerCheck {
970
+ server_id: string;
971
+ server_name: string;
972
+ passed: boolean;
973
+ checks: Array<Record<string, unknown>>;
974
+ }
975
+ /** Response of `POST /developers/workflows/{id}/test`. */
976
+ interface WorkflowTestResponse {
977
+ workflow_id: string;
978
+ status: string;
979
+ validation: Record<string, unknown>;
980
+ server_checks: WorkflowServerCheck[];
981
+ all_passed: boolean;
982
+ }
983
+ /** Lifecycle status of a hosted author runtime. */
984
+ type RuntimeStatus = 'provisioning' | 'active' | 'rolling_back' | 'inactive' | 'failed';
985
+ /** Request body of `POST /developers/runtimes/hosted`. */
986
+ interface DeployHostedRequest {
987
+ manifest: Record<string, unknown>;
988
+ region: string;
989
+ workflow_spec?: Record<string, unknown>;
990
+ }
991
+ /** Response of `POST /developers/runtimes/hosted` (202). */
992
+ interface DeployHostedResponse {
993
+ runtime_id: string;
994
+ status: RuntimeStatus;
995
+ endpoint_url?: string | null;
996
+ region: string;
997
+ version: number;
998
+ workflow_id?: string | null;
999
+ }
1000
+ /** Response of `POST /developers/runtimes/{id}/rollback`. */
1001
+ interface RollbackResponse {
1002
+ runtime_id: string;
1003
+ version: number;
1004
+ status: RuntimeStatus;
1005
+ }
1006
+ /** One log line from `GET /developers/runtimes/{id}/logs`. */
1007
+ interface RuntimeLogEntry {
1008
+ timestamp: string;
1009
+ level: string;
1010
+ message: string;
1011
+ }
1012
+
1013
+ /**
1014
+ * `ConvilynClient` — a fetch-based client for the **Developer Portal**
1015
+ * (`/api/v1/developers/*`), the platform's third-party author/publish surface.
1016
+ *
1017
+ * This is the TypeScript counterpart of the Python `convilyn_sdk.ConvilynClient`
1018
+ * (`sdk/author-python/src/convilyn_sdk/client.py`): the author BUILDS a tool
1019
+ * server + workflow spec locally (`ToolServer`, `WorkflowSpec`,
1020
+ * `runComplianceChecks`), then INTEGRATES its own artifacts by registering them
1021
+ * through the portal:
1022
+ *
1023
+ * POST /developers/register — mint a `cvl_` developer key (no auth)
1024
+ * POST /developers/servers — submit a tool-server manifest
1025
+ * GET /developers/servers — list
1026
+ * GET /developers/servers/{id}/status — verification status
1027
+ * POST /developers/servers/{id}/test — sandbox test
1028
+ * DELETE /developers/servers/{id} — deactivate
1029
+ * POST /developers/workflows — submit a compiled workflow spec
1030
+ * GET /developers/workflows — list
1031
+ * GET /developers/workflows/{id}/status — status
1032
+ * POST /developers/workflows/{id}/test — sandbox test
1033
+ * DELETE /developers/workflows/{id} — deactivate
1034
+ * POST /developers/runtimes/hosted — deploy to the hosted author runtime
1035
+ * POST /developers/runtimes/{id}/rollback — flip to the previous version
1036
+ * GET /developers/runtimes/{id}/logs — recent runtime log lines
1037
+ *
1038
+ * Auth: `Authorization: Bearer <cvl_ developer key>`, read from
1039
+ * `CONVILYN_API_KEY` (`config.ts`). This SDK deliberately does NOT call the
1040
+ * first-party console surfaces (`/user_workflows/*`, `/mcp/tools/catalog`) — those
1041
+ * are JWT/session endpoints owned by the web UI, not an author-publishing API.
1042
+ * Response bodies are snake_case, matching the platform's Developer Portal
1043
+ * API.
1044
+ */
1045
+
1046
+ /** The subset of `fetch` the client uses (so a fake can be injected in tests). */
1047
+ type FetchLike = (url: string, init?: {
1048
+ method?: string;
1049
+ headers?: Record<string, string>;
1050
+ body?: string;
1051
+ }) => Promise<{
1052
+ ok: boolean;
1053
+ status: number;
1054
+ json(): Promise<unknown>;
1055
+ text(): Promise<string>;
1056
+ }>;
1057
+ /** Options for {@link ConvilynClient}; unset fields fall back to {@link SDKConfig}. */
1058
+ interface ConvilynClientOptions {
1059
+ /** Full API base incl. `/api/v1`; defaults to `${platformUrl}/api/v1`. */
1060
+ baseUrl?: string;
1061
+ /** `cvl_` developer key; defaults to `CONVILYN_API_KEY`. */
1062
+ apiKey?: string;
1063
+ /** Injected `fetch` (defaults to the global). */
1064
+ fetch?: FetchLike;
1065
+ config?: SDKConfig;
1066
+ }
1067
+ /** Fetch-based client for the Developer Portal author/publish endpoints. */
1068
+ declare class ConvilynClient {
1069
+ #private;
1070
+ readonly baseUrl: string;
1071
+ constructor(options?: ConvilynClientOptions);
1072
+ /** The `cvl_` developer key currently in use (empty until set or registered). */
1073
+ get apiKey(): string;
1074
+ /**
1075
+ * `POST /developers/register` — create a developer account and mint a `cvl_`
1076
+ * key. No auth required. The returned key is captured on this client for
1077
+ * subsequent calls (and returned so the caller can persist it — it is shown
1078
+ * only once).
1079
+ */
1080
+ register(request: DeveloperRegisterRequest): Promise<DeveloperRegisterResponse>;
1081
+ /** `POST /developers/servers` — submit a tool-server manifest for verification. */
1082
+ submitServer(request: ServerSubmitRequest): Promise<ServerSubmitResponse>;
1083
+ /** `GET /developers/servers` — list this developer's servers. */
1084
+ listServers(): Promise<DeveloperServer[]>;
1085
+ /** `GET /developers/servers/{id}/status` — verification status of a server. */
1086
+ serverStatus(serverId: string): Promise<ServerStatusResponse>;
1087
+ /** `POST /developers/servers/{id}/test` — trigger a sandbox test run. */
1088
+ testServer(serverId: string, slots?: Record<string, unknown>): Promise<TestRunResponse>;
1089
+ /** `DELETE /developers/servers/{id}` — deactivate a server. */
1090
+ deactivateServer(serverId: string): Promise<void>;
1091
+ /** `POST /developers/workflows` — submit a compiled workflow spec + its server ids. */
1092
+ submitWorkflow(request: WorkflowSubmitRequest): Promise<WorkflowSubmitResponse>;
1093
+ /** `GET /developers/workflows` — list this developer's workflows. */
1094
+ listWorkflows(): Promise<WorkflowListItem[]>;
1095
+ /** `GET /developers/workflows/{id}/status` — verification status of a workflow. */
1096
+ workflowStatus(workflowId: string): Promise<WorkflowStatusResponse>;
1097
+ /** `POST /developers/workflows/{id}/test` — sandbox-test a submitted workflow. */
1098
+ testWorkflow(workflowId: string, testInput?: Record<string, unknown>): Promise<WorkflowTestResponse>;
1099
+ /** `DELETE /developers/workflows/{id}` — deactivate a workflow. */
1100
+ deactivateWorkflow(workflowId: string): Promise<void>;
1101
+ /**
1102
+ * `POST /developers/runtimes/hosted` — deploy a tool server into the
1103
+ * Convilyn-Hosted Author Runtime. Counterpart to {@link submitServer}:
1104
+ * instead of registering a caller-deployed endpoint, the platform
1105
+ * provisions a sandboxed Lambda and returns its public endpoint URL.
1106
+ *
1107
+ * Backends without the hosted stack answer 503 `HOSTED_NOT_AVAILABLE`
1108
+ * (older builds: 501); environments with the router unmounted answer 404.
1109
+ * All surface as {@link ConvilynApiError} — catch and fall back to
1110
+ * `push --endpoint-url` (BYO) when a hard guarantee is needed.
1111
+ */
1112
+ deployHostedRuntime(manifest: Record<string, unknown>, options: {
1113
+ region: string;
1114
+ workflowSpec?: Record<string, unknown>;
1115
+ }): Promise<DeployHostedResponse>;
1116
+ /**
1117
+ * `POST /developers/runtimes/{id}/rollback` — atomically flip the runtime
1118
+ * back to its previous active version.
1119
+ */
1120
+ rollbackHostedRuntime(runtimeId: string): Promise<RollbackResponse>;
1121
+ /**
1122
+ * `GET /developers/runtimes/{id}/logs` — recent runtime log lines.
1123
+ * `since` is an ISO-8601 timestamp or relative shorthand (`"5m"`, `"1h"`)
1124
+ * interpreted server-side; `limit` defaults to 100 (server caps ~1000).
1125
+ * Accepts either a bare list or an `{entries: [...]}` envelope (mirror of
1126
+ * the Python client) so the SDK survives the wire shape stabilising.
1127
+ */
1128
+ getHostedRuntimeLogs(runtimeId: string, options?: {
1129
+ since?: string;
1130
+ limit?: number;
1131
+ }): Promise<RuntimeLogEntry[]>;
1132
+ }
1133
+
1134
+ /**
1135
+ * Local testing harness — invoke a registered tool in-process and get its wire
1136
+ * envelope back, without standing up an HTTP server. Lets authors unit-test
1137
+ * their tools (and the platform's confirmation / validation behaviour) directly
1138
+ * against a {@link ToolServer}.
1139
+ *
1140
+ * It drives the same transport-free `ToolServer.dispatch` the `/mcp` runtime
1141
+ * uses, so what you assert in a test is exactly what the gateway would receive.
1142
+ */
1143
+
1144
+ /** Options for {@link invokeTool}. */
1145
+ interface InvokeToolOptions {
1146
+ /** `request_id` surfaced to the tool's {@link ToolContext}. */
1147
+ requestId?: string;
1148
+ }
1149
+ /**
1150
+ * Invoke `toolName` on `server` with `args` and return the ToolResult wire
1151
+ * envelope. Throws {@link ConvilynAuthorError} if the dispatch returns a
1152
+ * JSON-RPC protocol error (unknown tool / method / bad params) — tool-level
1153
+ * outcomes (`tool_error` / `validation_error`) come back as an envelope, not a
1154
+ * throw, so they can be asserted on.
1155
+ */
1156
+ declare function invokeTool(server: ToolServer, toolName: string, args?: Record<string, unknown>, options?: InvokeToolOptions): Promise<ToolResultWire>;
1157
+
1158
+ export { type BlueprintAgentConfig, type BlueprintMcpConfig, CONFIRMATION_TTL_SECONDS, type CanvasLayout, type CompiledWorkflowSpec, type ComplianceReport, type ComplianceResult, ConfirmationInvalidError, type ConfirmationInvalidReason, type ConfirmationTokenInput, ConsoleProgressBackend, ConvilynApiError, ConvilynAuthorError, ConvilynClient, type ConvilynClientOptions, ConvilynManifest, type ConvilynManifestOptions, ConvilynStartupError, DEFAULT_HMAC_TOLERANCE_SECONDS, type DataStore, type DeployHostedRequest, type DeployHostedResponse, type DeveloperRegisterRequest, type DeveloperRegisterResponse, type DeveloperServer, ENV_DEV_INSECURE, type ExportPayload, type FallbackAction, type FallbackPolicy, type FetchLike, GET_TOOL_DATA, type HumanReviewPolicy, InMemoryDataStore, InvalidSignatureError, type InvalidSignatureReason, type InvokeToolOptions, type JSONRPCErrorObject, type JSONRPCRequest, type JSONRPCResponse, JSONRPC_VERSION, MANIFEST_SDK_VERSION, OUTPUT_INLINE_THRESHOLD_BYTES, type OutputValidationPolicy, PUBLIC_SCHEMA_VERSION, type PauseTrigger, type Position, type ProgressBackend, type RequestBody, type RetryCategory, type RetryPolicy, type RollbackResponse, type RuntimeLogEntry, type RuntimeStatus, SDKConfig, type SDKConfigOptions, SERVER_ID_HEADER, SIGNATURE_HEADER, type ServeOptions, type ServerSpec, type ServerStatusResponse, type ServerSubmitRequest, type ServerSubmitResponse, type ServerVerificationStatus, type SourceType, TIMESTAMP_HEADER, TOOLS_CALL, type TestRunResponse, type TimeoutPolicy, ToolContext, type ToolDataRef, type ToolDefinition, type ToolDefinitionInput, type ToolError, type ToolHandlerResult, type ToolPaletteItem, ToolResult, type ToolResultWire, ToolServer, type ToolServerOptions, type ToolSpec, type ToolStatus, VERSION, type ValidationIssueWire, type VerifyConfirmationInput, type VerifyOptions, type Visibility, type WorkflowBlueprint, type WorkflowListItem, type WorkflowPolicies, type WorkflowServerCheck, WorkflowSpec, type WorkflowStatusResponse, type WorkflowSubmitRequest, type WorkflowSubmitResponse, type WorkflowTestResponse, type WorkflowVerificationStatus, allChecksPassed, buildWorkflowPolicies, createDataStore, createToolContext, defineTool, devInsecureRequested, failedChecks, generateRefId, invokeTool, mintConfirmationToken, normalizeForDigest, runComplianceChecks, serve, signRequest, verifyConfirmationToken, verifySignature };