@evolith/sdk 0.1.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/README.es.md ADDED
@@ -0,0 +1,105 @@
1
+ # @evolith/sdk
2
+
3
+ Librería cliente tipada en TypeScript para la **API REST** de Evolith Core y sus
4
+ **herramientas MCP**. Es un envoltorio fino e inyectable por transporte: sin estado
5
+ global, sin configuración de red implícita, y cada método está completamente tipado
6
+ contra los contratos del servidor.
7
+
8
+ > Estado: **experimental**. El paquete se publica desde este monorepo pero todavía no
9
+ > está integrado en una aplicación de primera parte; existe para que consumidores
10
+ > externos (repos satélite, scripts de automatización, el Tracker BFF) puedan hablar
11
+ > con Evolith Core sin volver a derivar los DTOs a mano.
12
+
13
+ ## Propósito
14
+
15
+ Evolith Core expone dos superficies:
16
+
17
+ - una **API REST** versionada servida por `apps/core-api` (versionado por URI bajo el
18
+ prefijo `api/v`, por lo que las rutas reales son `/api/v1/<recurso>`);
19
+ - un conjunto de **herramientas MCP** servidas por `packages/mcp-server` sobre
20
+ JSON-RPC `tools/call`.
21
+
22
+ Este SDK refleja los DTOs de los controladores (`apps/core-api/src/presentation/dtos`)
23
+ y los esquemas de entrada/salida de las herramientas MCP
24
+ (`packages/mcp-server/src/tools/*.tools.ts`) como tipos TypeScript escritos a mano, y
25
+ provee una clase cliente por superficie. Es el único punto de integración tipado para
26
+ que los consumidores no dupliquen las formas de las solicitudes.
27
+
28
+ ## Consumidor previsto
29
+
30
+ - **Repositorios satélite** que ejecutan evaluaciones de compuertas / detección de
31
+ drift contra una API de Evolith Core alojada.
32
+ - **Scripts de automatización y CI** que necesitan acceso tipado a las transiciones de
33
+ fase.
34
+ - **El Tracker BFF**, que custodia el `workspaceRef` opaco y media las llamadas a Core
35
+ en nombre de los usuarios finales.
36
+
37
+ Todos los cuerpos de solicitud reciben un `workspaceRef` opaco (emitido por el Tracker
38
+ BFF) en lugar de credenciales crudas, manteniendo el SDK solo como transporte.
39
+
40
+ ## Cliente REST
41
+
42
+ `EvolithRestClient` es un envoltorio tipado sobre `fetch`. Cada método devuelve el
43
+ `SuccessEnvelope<T>` completo (`{ success, data, meta }`); las respuestas no-2xx lanzan
44
+ `EvolithApiError`.
45
+
46
+ | Método | Verbo / Ruta |
47
+ | --- | --- |
48
+ | `evaluateGate(gateId, body)` | `POST /api/v1/gates/:gateId/evaluate` |
49
+ | `evaluatePhaseGate(phase, body)` | resuelve fase → id de compuerta, luego `evaluateGate` |
50
+ | `transitionPhase(body)` | `POST /api/v1/phases/transition` |
51
+ | `listTopologies()` | `GET /api/v1/architecture/topologies` |
52
+ | `getTopology(id)` | `GET /api/v1/architecture/topologies/:id` |
53
+ | `validateSatellite(body)` | `POST /api/v1/architecture/validate-satellite` |
54
+ | `detectDrift(body)` | `POST /api/v1/architecture/detect-drift` |
55
+ | `invalidateTopologyCache()` | `POST /api/v1/architecture/cache/invalidate` |
56
+ | `initProject(body)` | `POST /api/v1/projects/initialize` |
57
+ | `proposeAdvance(body)` | `POST /api/v1/projects/propose-advance` |
58
+
59
+ Opciones del constructor: `baseUrl` (requerido), `apiKey` (token Bearer opcional),
60
+ `fetch` (implementación personalizada opcional), `timeoutMs` (por defecto `30_000`,
61
+ aplicado vía `AbortController`) y `apiPrefix` (por defecto `/api`).
62
+
63
+ ```ts
64
+ import { EvolithRestClient } from '@evolith/sdk';
65
+
66
+ const client = new EvolithRestClient({ baseUrl: 'http://localhost:3000', apiKey: 'token' });
67
+ const result = await client.evaluatePhaseGate('discovery', { workspaceRef: 'op_abc123' });
68
+ console.log(result.data.passed);
69
+ ```
70
+
71
+ ## Cliente MCP
72
+
73
+ `EvolithMcpClient` es agnóstico al transporte: provee cualquier función que envíe una
74
+ solicitud `tools/call` y devuelva el arreglo de contenido crudo. Cada método convierte
75
+ la respuesta parseada al tipo de salida correcto y reporta `isError`.
76
+
77
+ | Método | Herramienta MCP |
78
+ | --- | --- |
79
+ | `evaluateGate(input)` | `evolith-gate-evaluate` |
80
+ | `validate(input)` | `evolith-validate` |
81
+ | `advancePhase(input)` | `evolith-phase-advance` |
82
+ | `listTopologies(input?)` | `evolith-topology-list` |
83
+ | `getTopology(input)` | `evolith-topology-get` |
84
+ | `call(toolName, input)` | despacho tipado genérico |
85
+
86
+ La fábrica `createJsonRpcTransport(sendRequest)` adapta cualquier emisor JSON-RPC a la
87
+ forma de transporte requerida.
88
+
89
+ ```ts
90
+ import { EvolithMcpClient, createJsonRpcTransport } from '@evolith/sdk';
91
+
92
+ const mcp = new EvolithMcpClient({ transport: createJsonRpcTransport(myRpcFn) });
93
+ const gate = await mcp.evaluateGate({ phase: 'discovery', projectPath: '/repos/my-service' });
94
+ ```
95
+
96
+ ## Testing
97
+
98
+ Las pruebas unitarias viven en `src/__tests__/sdk.spec.ts` y nunca tocan la red: el
99
+ cliente REST se maneja con un `fetch` simulado y el cliente MCP con un transporte
100
+ simulado.
101
+
102
+ ```bash
103
+ npm test # ejecuta la suite de Jest
104
+ npm run test:cov # ejecuta con cobertura (≥85% de cobertura de funciones en los clientes)
105
+ ```
package/README.md ADDED
@@ -0,0 +1,100 @@
1
+ # @evolith/sdk
2
+
3
+ Typed TypeScript client library for the Evolith Core **REST API** and **MCP tools**.
4
+ It is a thin, transport-injectable wrapper: no global state, no implicit network
5
+ configuration, and every method is fully typed against the server contracts.
6
+
7
+ > Status: **experimental**. The package is published from this monorepo but is not
8
+ > yet wired into a first-party application; it exists so external consumers
9
+ > (satellite repos, automation scripts, the Tracker BFF) can talk to Evolith Core
10
+ > without re-deriving DTOs by hand.
11
+
12
+ ## Purpose
13
+
14
+ Evolith Core exposes two surfaces:
15
+
16
+ - a versioned **REST API** served by `apps/core-api` (URI versioning under the
17
+ `api/v` prefix, so live routes are `/api/v1/<resource>`);
18
+ - a set of **MCP tools** served by `packages/mcp-server` over JSON-RPC `tools/call`.
19
+
20
+ This SDK mirrors the controller DTOs (`apps/core-api/src/presentation/dtos`) and the
21
+ MCP tool input/output schemas (`packages/mcp-server/src/tools/*.tools.ts`) as
22
+ hand-authored TypeScript types, and provides one client class per surface. It is the
23
+ single typed integration point so consumers do not duplicate request shapes.
24
+
25
+ ## Intended consumer
26
+
27
+ - **Satellite repositories** running gate evaluations / drift detection against a
28
+ hosted Evolith Core API.
29
+ - **Automation and CI scripts** that need typed access to phase transitions.
30
+ - **The Tracker BFF**, which holds the opaque `workspaceRef` and brokers calls to
31
+ Core on behalf of end users.
32
+
33
+ All request bodies take an opaque `workspaceRef` (issued by the Tracker BFF) rather
34
+ than raw credentials, keeping the SDK transport-only.
35
+
36
+ ## REST client
37
+
38
+ `EvolithRestClient` is a typed `fetch` wrapper. Each method returns the full
39
+ `SuccessEnvelope<T>` (`{ success, data, meta }`); non-2xx responses throw
40
+ `EvolithApiError`.
41
+
42
+ | Method | Verb / Route |
43
+ | --- | --- |
44
+ | `evaluateGate(gateId, body)` | `POST /api/v1/gates/:gateId/evaluate` |
45
+ | `evaluatePhaseGate(phase, body)` | resolves phase → gate id, then `evaluateGate` |
46
+ | `transitionPhase(body)` | `POST /api/v1/phases/transition` |
47
+ | `listTopologies()` | `GET /api/v1/architecture/topologies` |
48
+ | `getTopology(id)` | `GET /api/v1/architecture/topologies/:id` |
49
+ | `validateSatellite(body)` | `POST /api/v1/architecture/validate-satellite` |
50
+ | `detectDrift(body)` | `POST /api/v1/architecture/detect-drift` |
51
+ | `invalidateTopologyCache()` | `POST /api/v1/architecture/cache/invalidate` |
52
+ | `initProject(body)` | `POST /api/v1/projects/initialize` |
53
+ | `proposeAdvance(body)` | `POST /api/v1/projects/propose-advance` |
54
+
55
+ Constructor options: `baseUrl` (required), `apiKey` (optional Bearer token),
56
+ `fetch` (optional custom implementation), `timeoutMs` (default `30_000`, enforced
57
+ via `AbortController`), and `apiPrefix` (default `/api`).
58
+
59
+ ```ts
60
+ import { EvolithRestClient } from '@evolith/sdk';
61
+
62
+ const client = new EvolithRestClient({ baseUrl: 'http://localhost:3000', apiKey: 'token' });
63
+ const result = await client.evaluatePhaseGate('discovery', { workspaceRef: 'op_abc123' });
64
+ console.log(result.data.passed);
65
+ ```
66
+
67
+ ## MCP client
68
+
69
+ `EvolithMcpClient` is transport-agnostic: supply any function that sends a
70
+ `tools/call` request and returns the raw content array. Each method casts the parsed
71
+ response to the correct typed output and reports `isError`.
72
+
73
+ | Method | MCP tool |
74
+ | --- | --- |
75
+ | `evaluateGate(input)` | `evolith-gate-evaluate` |
76
+ | `validate(input)` | `evolith-validate` |
77
+ | `advancePhase(input)` | `evolith-phase-advance` |
78
+ | `listTopologies(input?)` | `evolith-topology-list` |
79
+ | `getTopology(input)` | `evolith-topology-get` |
80
+ | `call(toolName, input)` | generic typed dispatch |
81
+
82
+ The `createJsonRpcTransport(sendRequest)` factory adapts any JSON-RPC sender into the
83
+ required transport shape.
84
+
85
+ ```ts
86
+ import { EvolithMcpClient, createJsonRpcTransport } from '@evolith/sdk';
87
+
88
+ const mcp = new EvolithMcpClient({ transport: createJsonRpcTransport(myRpcFn) });
89
+ const gate = await mcp.evaluateGate({ phase: 'discovery', projectPath: '/repos/my-service' });
90
+ ```
91
+
92
+ ## Testing
93
+
94
+ Unit tests live in `src/__tests__/sdk.spec.ts` and never touch the network — the
95
+ REST client is driven by a mock `fetch` and the MCP client by a mock transport.
96
+
97
+ ```bash
98
+ npm test # run the Jest suite
99
+ npm run test:cov # run with coverage (≥85% function coverage on the clients)
100
+ ```
@@ -0,0 +1,8 @@
1
+ export { EvolithRestClient, EvolithApiError } from './rest/evolith-rest-client.js';
2
+ export type { EvolithRestClientOptions } from './rest/evolith-rest-client.js';
3
+ export type { ApiEnvelope, GatePhase as RestGatePhase, EvaluateGateRequest, EvaluateGateResponse, GateEvidence, GateViolation as RestGateViolation, ViolationSeverity, TransitionPhaseRequest, TransitionPhaseResponse, PhaseTransitionResult, TopologyManifest as RestTopologyManifest, ListTopologiesResponse, GetTopologyResponse, ValidateSatelliteRequest, ValidateSatelliteResponse, DetectDriftRequest, DetectDriftResponse, ValidationResult, InitProjectRequest, InitProjectResponse, ProposeAdvanceRequest, ProposeAdvanceResponse, } from './rest/types.js';
4
+ export { SatellitesClient } from './satellites.client.js';
5
+ export type { SatelliteRecord, SatelliteStatus, SatelliteMode, SatelliteTopology, InitializeSatelliteInput, RegisterSatelliteInput, } from './satellites.client.js';
6
+ export { EvolithMcpClient, createJsonRpcTransport } from './mcp/evolith-mcp-client.js';
7
+ export type { EvolithMcpClientOptions, McpTransport, McpCallResult } from './mcp/evolith-mcp-client.js';
8
+ export type { GatePhase as McpGatePhase, EvaluatorKind, EvidenceMode, ValidateFormat, GateEvaluateInput, GateEvaluateOutput, GateViolation as McpGateViolation, ValidateInput, ValidateOutput, ValidateJsonOutput, ValidationIssue, PhaseAdvanceInput, PhaseAdvanceOutput, TopologyListInput, TopologyListOutput, TopologyGetInput, TopologyGetOutput, TopologyManifest as McpTopologyManifest, McpToolName, McpToolInputMap, McpToolOutputMap, } from './mcp/types.js';
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createJsonRpcTransport = exports.EvolithMcpClient = exports.SatellitesClient = exports.EvolithApiError = exports.EvolithRestClient = void 0;
4
+ var evolith_rest_client_js_1 = require("./rest/evolith-rest-client.js");
5
+ Object.defineProperty(exports, "EvolithRestClient", { enumerable: true, get: function () { return evolith_rest_client_js_1.EvolithRestClient; } });
6
+ Object.defineProperty(exports, "EvolithApiError", { enumerable: true, get: function () { return evolith_rest_client_js_1.EvolithApiError; } });
7
+ var satellites_client_js_1 = require("./satellites.client.js");
8
+ Object.defineProperty(exports, "SatellitesClient", { enumerable: true, get: function () { return satellites_client_js_1.SatellitesClient; } });
9
+ var evolith_mcp_client_js_1 = require("./mcp/evolith-mcp-client.js");
10
+ Object.defineProperty(exports, "EvolithMcpClient", { enumerable: true, get: function () { return evolith_mcp_client_js_1.EvolithMcpClient; } });
11
+ Object.defineProperty(exports, "createJsonRpcTransport", { enumerable: true, get: function () { return evolith_mcp_client_js_1.createJsonRpcTransport; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAqBA,wEAAmF;AAA1E,2HAAA,iBAAiB,OAAA;AAAE,yHAAA,eAAe,OAAA;AA4B3C,+DAA0D;AAAjD,wHAAA,gBAAgB,OAAA;AAWzB,qEAAuF;AAA9E,yHAAA,gBAAgB,OAAA;AAAE,+HAAA,sBAAsB,OAAA"}
@@ -0,0 +1,28 @@
1
+ import type { McpToolName, McpToolInputMap, McpToolOutputMap, GateEvaluateInput, GateEvaluateOutput, ValidateInput, ValidateOutput, PhaseAdvanceInput, PhaseAdvanceOutput, TopologyListInput, TopologyListOutput, TopologyGetInput, TopologyGetOutput } from './types.js';
2
+ export interface McpCallResult<T> {
3
+ content: Array<{
4
+ type: string;
5
+ text?: string;
6
+ }>;
7
+ parsed: T;
8
+ isError: boolean;
9
+ }
10
+ export type McpTransport = <N extends McpToolName>(toolName: N, input: McpToolInputMap[N]) => Promise<Array<{
11
+ type: string;
12
+ text?: string;
13
+ [key: string]: unknown;
14
+ }>>;
15
+ export interface EvolithMcpClientOptions {
16
+ transport: McpTransport;
17
+ }
18
+ export declare class EvolithMcpClient {
19
+ private readonly transport;
20
+ constructor(options: EvolithMcpClientOptions);
21
+ evaluateGate(input: GateEvaluateInput): Promise<McpCallResult<GateEvaluateOutput>>;
22
+ validate(input: ValidateInput): Promise<McpCallResult<ValidateOutput>>;
23
+ advancePhase(input: PhaseAdvanceInput): Promise<McpCallResult<PhaseAdvanceOutput>>;
24
+ listTopologies(input?: TopologyListInput): Promise<McpCallResult<TopologyListOutput>>;
25
+ getTopology(input: TopologyGetInput): Promise<McpCallResult<TopologyGetOutput>>;
26
+ call<N extends McpToolName>(toolName: N, input: McpToolInputMap[N]): Promise<McpCallResult<McpToolOutputMap[N]>>;
27
+ }
28
+ export declare function createJsonRpcTransport(sendRequest: (method: string, params: unknown) => Promise<unknown>): McpTransport;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EvolithMcpClient = void 0;
4
+ exports.createJsonRpcTransport = createJsonRpcTransport;
5
+ class EvolithMcpClient {
6
+ constructor(options) {
7
+ this.transport = options.transport;
8
+ }
9
+ async evaluateGate(input) {
10
+ return this.call('evolith-gate-evaluate', input);
11
+ }
12
+ async validate(input) {
13
+ return this.call('evolith-validate', input);
14
+ }
15
+ async advancePhase(input) {
16
+ return this.call('evolith-phase-advance', input);
17
+ }
18
+ async listTopologies(input) {
19
+ return this.call('evolith-topology-list', input ?? {});
20
+ }
21
+ async getTopology(input) {
22
+ return this.call('evolith-topology-get', input);
23
+ }
24
+ async call(toolName, input) {
25
+ const content = await this.transport(toolName, input);
26
+ const isError = content.some((c) => c.type === 'error' || c.isError === true);
27
+ const textContent = content.find((c) => c.type === 'text');
28
+ const text = textContent?.text ?? '';
29
+ let parsed;
30
+ try {
31
+ parsed = JSON.parse(text);
32
+ }
33
+ catch {
34
+ parsed = text;
35
+ }
36
+ return { content, parsed, isError };
37
+ }
38
+ }
39
+ exports.EvolithMcpClient = EvolithMcpClient;
40
+ function createJsonRpcTransport(sendRequest) {
41
+ return async (toolName, input) => {
42
+ const result = await sendRequest('tools/call', { name: toolName, arguments: input });
43
+ const r = result;
44
+ return r.content ?? [];
45
+ };
46
+ }
47
+ //# sourceMappingURL=evolith-mcp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evolith-mcp-client.js","sourceRoot":"","sources":["../../src/mcp/evolith-mcp-client.ts"],"names":[],"mappings":";;;AAiIA,wDAQC;AA5FD,MAAa,gBAAgB;IAG3B,YAAY,OAAgC;QAC1C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IACrC,CAAC;IAOD,KAAK,CAAC,YAAY,CAAC,KAAwB;QACzC,OAAO,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAOD,KAAK,CAAC,QAAQ,CAAC,KAAoB;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;IAC9C,CAAC;IAOD,KAAK,CAAC,YAAY,CAAC,KAAwB;QACzC,OAAO,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IAOD,KAAK,CAAC,cAAc,CAAC,KAAyB;QAC5C,OAAO,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC;IAOD,KAAK,CAAC,WAAW,CAAC,KAAuB;QACvC,OAAO,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IAClD,CAAC;IAOD,KAAK,CAAC,IAAI,CACR,QAAW,EACX,KAAyB;QAEzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAEtD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAK,CAAS,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;QACvF,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC;QAErC,IAAI,MAA2B,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwB,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,IAAsC,CAAC;QAClD,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IACtC,CAAC;CACF;AA5ED,4CA4EC;AAQD,SAAgB,sBAAsB,CACpC,WAAkE;IAElE,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;QAC/B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACrF,MAAM,CAAC,GAAG,MAA8D,CAAC;QACzE,OAAO,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC;IACzB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './types.js';
2
+ export * from './evolith-mcp-client.js';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types.js"), exports);
18
+ __exportStar(require("./evolith-mcp-client.js"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,0DAAwC"}
@@ -0,0 +1,113 @@
1
+ export type GatePhase = 'discovery' | 'design' | 'construction' | 'qa' | 'release';
2
+ export type EvaluatorKind = 'human' | 'agent' | 'ci';
3
+ export type EvidenceMode = 'full' | 'summary';
4
+ export type ValidateFormat = 'json' | 'summary' | 'table';
5
+ export interface GateEvaluateInput {
6
+ phase: GatePhase;
7
+ projectPath: string;
8
+ corePath?: string;
9
+ rulesetRef?: string;
10
+ evidenceMode?: EvidenceMode;
11
+ evaluatedBy?: EvaluatorKind;
12
+ initiative?: string;
13
+ tenant?: string;
14
+ webhookUrl?: string;
15
+ }
16
+ export interface GateViolation {
17
+ ruleId: string;
18
+ severity: 'error' | 'warning' | 'info';
19
+ message: string;
20
+ artifact?: string;
21
+ remediation?: string;
22
+ }
23
+ export interface GateEvaluateOutput {
24
+ phase: GatePhase;
25
+ passed: boolean;
26
+ violations: GateViolation[];
27
+ evaluatedBy?: EvaluatorKind;
28
+ evaluatedAt?: string;
29
+ summary?: {
30
+ errors: number;
31
+ warnings: number;
32
+ };
33
+ }
34
+ export interface ValidateInput {
35
+ path: string;
36
+ format?: ValidateFormat;
37
+ ruleset?: string;
38
+ corePath?: string;
39
+ topology?: string;
40
+ phase?: string;
41
+ manifest?: string;
42
+ }
43
+ export interface ValidationIssue {
44
+ ruleId: string;
45
+ severity: string;
46
+ title: string;
47
+ blocking: boolean;
48
+ category?: string;
49
+ }
50
+ export interface ValidateJsonOutput {
51
+ status: 'passed' | 'failed';
52
+ rulesChecked: number;
53
+ issues: ValidationIssue[];
54
+ }
55
+ export type ValidateOutput = ValidateJsonOutput | string;
56
+ export interface PhaseAdvanceInput {
57
+ fromPhase: GatePhase;
58
+ toPhase: GatePhase;
59
+ projectPath: string;
60
+ corePath?: string;
61
+ evaluatedBy?: EvaluatorKind;
62
+ initiative?: string;
63
+ tenant?: string;
64
+ webhookUrl?: string;
65
+ }
66
+ export interface PhaseAdvanceOutput {
67
+ fromPhase: GatePhase;
68
+ toPhase: GatePhase;
69
+ allowed: boolean;
70
+ gateEvidence?: GateEvaluateOutput;
71
+ message?: string;
72
+ }
73
+ export interface TopologyListInput {
74
+ corePath?: string;
75
+ }
76
+ export interface TopologyManifest {
77
+ id: string;
78
+ name: string;
79
+ description?: string;
80
+ version?: string;
81
+ [key: string]: unknown;
82
+ }
83
+ export interface TopologyListOutput {
84
+ tool: 'evolith-topology-list';
85
+ count: number;
86
+ topologies: TopologyManifest[];
87
+ timestamp: string;
88
+ }
89
+ export interface TopologyGetInput {
90
+ id: string;
91
+ corePath?: string;
92
+ }
93
+ export interface TopologyGetOutput {
94
+ tool: 'evolith-topology-get';
95
+ id: string;
96
+ topology: TopologyManifest;
97
+ timestamp: string;
98
+ }
99
+ export type McpToolName = 'evolith-gate-evaluate' | 'evolith-validate' | 'evolith-phase-advance' | 'evolith-topology-list' | 'evolith-topology-get';
100
+ export interface McpToolInputMap {
101
+ 'evolith-gate-evaluate': GateEvaluateInput;
102
+ 'evolith-validate': ValidateInput;
103
+ 'evolith-phase-advance': PhaseAdvanceInput;
104
+ 'evolith-topology-list': TopologyListInput;
105
+ 'evolith-topology-get': TopologyGetInput;
106
+ }
107
+ export interface McpToolOutputMap {
108
+ 'evolith-gate-evaluate': GateEvaluateOutput;
109
+ 'evolith-validate': ValidateOutput;
110
+ 'evolith-phase-advance': PhaseAdvanceOutput;
111
+ 'evolith-topology-list': TopologyListOutput;
112
+ 'evolith-topology-get': TopologyGetOutput;
113
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mcp/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { AgentRuntimeRequestWire, AgentRuntimeResult } from '@evolith/agent-runtime';
2
+ export declare class AgentClient {
3
+ private readonly baseUrl;
4
+ private readonly _headers;
5
+ constructor(baseUrl: string, apiKey?: string);
6
+ private get headers();
7
+ handle(input: AgentRuntimeRequestWire): Promise<AgentRuntimeResult>;
8
+ getSkills(): Promise<any>;
9
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentClient = void 0;
4
+ class AgentClient {
5
+ constructor(baseUrl, apiKey) {
6
+ this.baseUrl = baseUrl.replace(/\/$/, '');
7
+ this._headers = {
8
+ 'Content-Type': 'application/json',
9
+ Accept: 'application/json',
10
+ ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
11
+ };
12
+ }
13
+ get headers() {
14
+ return this._headers;
15
+ }
16
+ async handle(input) {
17
+ const res = await fetch(`${this.baseUrl}/v1/agent/handle`, {
18
+ method: 'POST',
19
+ headers: this.headers,
20
+ body: JSON.stringify(input),
21
+ });
22
+ if (!res.ok)
23
+ throw new Error(`Agent handle failed: ${res.status}`);
24
+ return res.json();
25
+ }
26
+ async getSkills() {
27
+ const res = await fetch(`${this.baseUrl}/v1/agent/skills`, {
28
+ headers: this.headers,
29
+ });
30
+ if (!res.ok)
31
+ throw new Error(`Agent list skills failed: ${res.status}`);
32
+ return res.json();
33
+ }
34
+ }
35
+ exports.AgentClient = AgentClient;
36
+ //# sourceMappingURL=agent.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.client.js","sourceRoot":"","sources":["../../src/rest/agent.client.ts"],"names":[],"mappings":";;;AAEA,MAAa,WAAW;IAItB,YAAY,OAAe,EAAE,MAAe;QAC1C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC1C,IAAI,CAAC,QAAQ,GAAG;YACd,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,kBAAkB;YAC1B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzD,CAAC;IACJ,CAAC;IAED,IAAY,OAAO;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAMD,KAAK,CAAC,MAAM,CAAC,KAA8B;QACzC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,kBAAkB,EAAE;YACzD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACnE,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;IAMD,KAAK,CAAC,SAAS;QACb,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,kBAAkB,EAAE;YACzD,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;CACF;AA1CD,kCA0CC"}
@@ -0,0 +1,45 @@
1
+ import type { GatePhase, EvaluateGateRequest, EvaluateGateResponse, TransitionPhaseRequest, TransitionPhaseResponse, ListTopologiesResponse, GetTopologyResponse, ValidateSatelliteRequest, ValidateSatelliteResponse, DetectDriftRequest, DetectDriftResponse, InitProjectRequest, InitProjectResponse, ProposeAdvanceRequest, ProposeAdvanceResponse } from './types.js';
2
+ import { SatellitesClient } from '../satellites.client.js';
3
+ import { AgentClient } from './agent.client.js';
4
+ export interface EvolithRestClientOptions {
5
+ baseUrl: string;
6
+ agentUrl?: string;
7
+ apiKey?: string;
8
+ fetch?: typeof fetch;
9
+ timeoutMs?: number;
10
+ apiPrefix?: string;
11
+ }
12
+ export declare class EvolithRestClient {
13
+ private readonly options;
14
+ private readonly baseUrl;
15
+ private readonly apiPrefix;
16
+ private readonly headers;
17
+ private readonly fetcher;
18
+ private readonly timeoutMs;
19
+ readonly satellites: SatellitesClient;
20
+ readonly agent: AgentClient;
21
+ constructor(options: EvolithRestClientOptions);
22
+ evaluateGate(gateId: string, body: EvaluateGateRequest): Promise<EvaluateGateResponse>;
23
+ evaluatePhaseGate(phase: GatePhase, body: EvaluateGateRequest): Promise<EvaluateGateResponse>;
24
+ transitionPhase(body: TransitionPhaseRequest): Promise<TransitionPhaseResponse>;
25
+ listTopologies(): Promise<ListTopologiesResponse>;
26
+ getTopology(id: string): Promise<GetTopologyResponse>;
27
+ validateSatellite(body: ValidateSatelliteRequest): Promise<ValidateSatelliteResponse>;
28
+ detectDrift(body: DetectDriftRequest): Promise<DetectDriftResponse>;
29
+ invalidateTopologyCache(): Promise<{
30
+ invalidated: boolean;
31
+ keys: string[];
32
+ }>;
33
+ initProject(body: InitProjectRequest): Promise<InitProjectResponse>;
34
+ proposeAdvance(body: ProposeAdvanceRequest): Promise<ProposeAdvanceResponse>;
35
+ private get;
36
+ private post;
37
+ private request;
38
+ }
39
+ export declare class EvolithApiError extends Error {
40
+ readonly status: number;
41
+ readonly statusText: string;
42
+ readonly body: string;
43
+ readonly url: string;
44
+ constructor(status: number, statusText: string, body: string, url: string);
45
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EvolithApiError = exports.EvolithRestClient = void 0;
4
+ const satellites_client_js_1 = require("../satellites.client.js");
5
+ const agent_client_js_1 = require("./agent.client.js");
6
+ class EvolithRestClient {
7
+ constructor(options) {
8
+ this.options = options;
9
+ this.baseUrl = options.baseUrl.replace(/\/$/, '');
10
+ let prefix = options.apiPrefix ?? '/api';
11
+ while (prefix.startsWith('/'))
12
+ prefix = prefix.slice(1);
13
+ while (prefix.endsWith('/'))
14
+ prefix = prefix.slice(0, -1);
15
+ this.apiPrefix = prefix ? `/${prefix}` : '';
16
+ this.headers = {
17
+ 'Content-Type': 'application/json',
18
+ Accept: 'application/json',
19
+ ...(options.apiKey ? { Authorization: `Bearer ${options.apiKey}` } : {}),
20
+ };
21
+ this.fetcher = options.fetch ?? globalThis.fetch;
22
+ this.timeoutMs = options.timeoutMs ?? 30_000;
23
+ this.satellites = new satellites_client_js_1.SatellitesClient(this.baseUrl, options.apiKey);
24
+ this.agent = new agent_client_js_1.AgentClient(options.agentUrl || this.baseUrl, options.apiKey);
25
+ }
26
+ async evaluateGate(gateId, body) {
27
+ return this.post(`/v1/gates/${encodeURIComponent(gateId)}/evaluate`, body);
28
+ }
29
+ async evaluatePhaseGate(phase, body) {
30
+ const phaseToGateId = {
31
+ discovery: 'PG1-01',
32
+ design: 'PG2-01',
33
+ construction: 'PG3-01',
34
+ qa: 'PG4-01',
35
+ release: 'PG5-01',
36
+ };
37
+ return this.evaluateGate(phaseToGateId[phase], body);
38
+ }
39
+ async transitionPhase(body) {
40
+ return this.post('/v1/phases/transition', body);
41
+ }
42
+ async listTopologies() {
43
+ return this.get('/v1/architecture/topologies');
44
+ }
45
+ async getTopology(id) {
46
+ return this.get(`/v1/architecture/topologies/${encodeURIComponent(id)}`);
47
+ }
48
+ async validateSatellite(body) {
49
+ return this.post('/v1/architecture/validate-satellite', body);
50
+ }
51
+ async detectDrift(body) {
52
+ return this.post('/v1/architecture/detect-drift', body);
53
+ }
54
+ async invalidateTopologyCache() {
55
+ return this.post('/v1/architecture/cache/invalidate', {});
56
+ }
57
+ async initProject(body) {
58
+ return this.post('/v1/projects/initialize', body);
59
+ }
60
+ async proposeAdvance(body) {
61
+ return this.post('/v1/projects/propose-advance', body);
62
+ }
63
+ async get(path) {
64
+ return this.request('GET', path, undefined);
65
+ }
66
+ async post(path, body) {
67
+ return this.request('POST', path, body);
68
+ }
69
+ async request(method, path, body) {
70
+ const url = `${this.baseUrl}${this.apiPrefix}${path}`;
71
+ const controller = new AbortController();
72
+ const timeoutId = setTimeout(() => controller.abort(), this.timeoutMs);
73
+ try {
74
+ const response = await this.fetcher(url, {
75
+ method,
76
+ headers: this.headers,
77
+ body: body !== undefined ? JSON.stringify(body) : undefined,
78
+ signal: controller.signal,
79
+ });
80
+ if (!response.ok) {
81
+ const text = await response.text().catch(() => '');
82
+ throw new EvolithApiError(response.status, response.statusText, text, url);
83
+ }
84
+ return (await response.json());
85
+ }
86
+ finally {
87
+ clearTimeout(timeoutId);
88
+ }
89
+ }
90
+ }
91
+ exports.EvolithRestClient = EvolithRestClient;
92
+ class EvolithApiError extends Error {
93
+ constructor(status, statusText, body, url) {
94
+ super(`Evolith API error ${status} (${statusText}) for ${url}: ${body}`);
95
+ this.status = status;
96
+ this.statusText = statusText;
97
+ this.body = body;
98
+ this.url = url;
99
+ this.name = 'EvolithApiError';
100
+ }
101
+ }
102
+ exports.EvolithApiError = EvolithApiError;
103
+ //# sourceMappingURL=evolith-rest-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evolith-rest-client.js","sourceRoot":"","sources":["../../src/rest/evolith-rest-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export * from './evolith-rest-client.js';
3
+ export * from './agent.client.js';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types.js"), exports);
18
+ __exportStar(require("./evolith-rest-client.js"), exports);
19
+ __exportStar(require("./agent.client.js"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rest/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,2DAAyC;AACzC,oDAAkC"}
@@ -0,0 +1,99 @@
1
+ export interface EnvelopeMeta {
2
+ durationMs?: number;
3
+ [key: string]: unknown;
4
+ }
5
+ export interface SuccessEnvelope<T> {
6
+ success: true;
7
+ data: T;
8
+ meta: EnvelopeMeta;
9
+ }
10
+ export interface ErrorEnvelope {
11
+ success: false;
12
+ error: {
13
+ code: string;
14
+ message: string;
15
+ details?: unknown;
16
+ };
17
+ meta: EnvelopeMeta;
18
+ }
19
+ export type ApiEnvelope<T> = SuccessEnvelope<T> | ErrorEnvelope;
20
+ export type GatePhase = 'discovery' | 'design' | 'construction' | 'qa' | 'release';
21
+ export interface EvaluateGateRequest {
22
+ workspaceRef: string;
23
+ }
24
+ export type ViolationSeverity = 'error' | 'warning' | 'info';
25
+ export interface GateViolation {
26
+ ruleId: string;
27
+ severity: ViolationSeverity;
28
+ message: string;
29
+ artifact?: string;
30
+ remediation?: string;
31
+ }
32
+ export interface GateEvidence {
33
+ phase: GatePhase;
34
+ passed: boolean;
35
+ violations: GateViolation[];
36
+ evaluatedBy?: string;
37
+ evaluatedAt?: string;
38
+ summary?: {
39
+ errors: number;
40
+ warnings: number;
41
+ };
42
+ }
43
+ export type EvaluateGateResponse = SuccessEnvelope<GateEvidence>;
44
+ export interface TransitionPhaseRequest {
45
+ from: string;
46
+ to: string;
47
+ tools: string[];
48
+ workspaceRef: string;
49
+ }
50
+ export interface PhaseTransitionResult {
51
+ from: string;
52
+ to: string;
53
+ success: boolean;
54
+ message?: string;
55
+ }
56
+ export type TransitionPhaseResponse = SuccessEnvelope<PhaseTransitionResult>;
57
+ export interface TopologyManifest {
58
+ id: string;
59
+ name: string;
60
+ description?: string;
61
+ version?: string;
62
+ [key: string]: unknown;
63
+ }
64
+ export type ListTopologiesResponse = SuccessEnvelope<TopologyManifest[]>;
65
+ export type GetTopologyResponse = SuccessEnvelope<TopologyManifest>;
66
+ export interface ValidateSatelliteRequest {
67
+ workspaceRef: string;
68
+ }
69
+ export interface DetectDriftRequest {
70
+ workspaceRef: string;
71
+ declaredLevel?: string;
72
+ }
73
+ export interface ValidationResult {
74
+ passed: boolean;
75
+ issues: Array<{
76
+ ruleId: string;
77
+ severity: string;
78
+ title: string;
79
+ blocking: boolean;
80
+ category?: string;
81
+ }>;
82
+ rulesChecked?: number;
83
+ }
84
+ export type ValidateSatelliteResponse = SuccessEnvelope<ValidationResult>;
85
+ export type DetectDriftResponse = SuccessEnvelope<unknown>;
86
+ export interface InitProjectRequest {
87
+ workspaceRef: string;
88
+ name: string;
89
+ type: string;
90
+ options?: Record<string, unknown>;
91
+ }
92
+ export interface ProposeAdvanceRequest {
93
+ workspaceRef: string;
94
+ currentPhase: string;
95
+ targetPhase: string;
96
+ triggerDeploy?: boolean;
97
+ }
98
+ export type InitProjectResponse = SuccessEnvelope<unknown>;
99
+ export type ProposeAdvanceResponse = SuccessEnvelope<unknown>;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rest/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,50 @@
1
+ export type SatelliteStatus = 'provisioning' | 'active' | 'linked' | 'error' | 'archived';
2
+ export type SatelliteMode = 'create' | 'adopt';
3
+ export type SatelliteTopology = 'monolith' | 'modular' | 'micro' | 'distributed' | 'custom';
4
+ export interface SatelliteRecord {
5
+ id: string;
6
+ name: string;
7
+ owner: string;
8
+ repoUrl: string;
9
+ cloneUrl: string;
10
+ sshUrl: string;
11
+ topology: SatelliteTopology | string;
12
+ phase: string;
13
+ status: SatelliteStatus;
14
+ mode: SatelliteMode;
15
+ coreVersion?: string;
16
+ parentCorePath?: string;
17
+ description?: string;
18
+ linkedAt?: string;
19
+ createdAt: string;
20
+ updatedAt: string;
21
+ metadata?: Record<string, unknown>;
22
+ }
23
+ export interface InitializeSatelliteInput {
24
+ mode: SatelliteMode;
25
+ name: string;
26
+ owner: string;
27
+ topology: string;
28
+ phase: string;
29
+ description?: string;
30
+ private?: boolean;
31
+ coreVersion?: string;
32
+ existingRepoUrl?: string;
33
+ }
34
+ export type RegisterSatelliteInput = Omit<InitializeSatelliteInput, 'mode'> & {
35
+ mode?: string;
36
+ repoUrl: string;
37
+ cloneUrl: string;
38
+ sshUrl: string;
39
+ };
40
+ export declare class SatellitesClient {
41
+ private readonly baseUrl;
42
+ private readonly _headers;
43
+ constructor(baseUrl: string, apiKey?: string);
44
+ private get headers();
45
+ register(input: RegisterSatelliteInput): Promise<SatelliteRecord>;
46
+ list(): Promise<SatelliteRecord[]>;
47
+ get(id: string): Promise<SatelliteRecord | null>;
48
+ update(id: string, patch: Partial<SatelliteRecord>): Promise<SatelliteRecord>;
49
+ link(id: string, targetSatelliteId: string): Promise<SatelliteRecord>;
50
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SatellitesClient = void 0;
4
+ class SatellitesClient {
5
+ constructor(baseUrl, apiKey) {
6
+ this.baseUrl = baseUrl.replace(/\/$/, '');
7
+ this._headers = {
8
+ 'Content-Type': 'application/json',
9
+ Accept: 'application/json',
10
+ ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),
11
+ };
12
+ }
13
+ get headers() {
14
+ return this._headers;
15
+ }
16
+ async register(input) {
17
+ const res = await fetch(`${this.baseUrl}/api/v1/satellites`, {
18
+ method: 'POST',
19
+ headers: this.headers,
20
+ body: JSON.stringify(input),
21
+ });
22
+ if (!res.ok)
23
+ throw new Error(`Register satellite failed: ${res.status}`);
24
+ const envelope = await res.json();
25
+ return envelope.data.satellite;
26
+ }
27
+ async list() {
28
+ const res = await fetch(`${this.baseUrl}/api/v1/satellites`, {
29
+ headers: this.headers,
30
+ });
31
+ if (!res.ok)
32
+ throw new Error(`List satellites failed: ${res.status}`);
33
+ const envelope = await res.json();
34
+ return envelope.data.satellites;
35
+ }
36
+ async get(id) {
37
+ const res = await fetch(`${this.baseUrl}/api/v1/satellites/${encodeURIComponent(id)}`, {
38
+ headers: this.headers,
39
+ });
40
+ if (res.status === 404)
41
+ return null;
42
+ if (!res.ok)
43
+ throw new Error(`Get satellite failed: ${res.status}`);
44
+ const envelope = await res.json();
45
+ return envelope.data.satellite;
46
+ }
47
+ async update(id, patch) {
48
+ const res = await fetch(`${this.baseUrl}/api/v1/satellites/${encodeURIComponent(id)}`, {
49
+ method: 'PATCH',
50
+ headers: this.headers,
51
+ body: JSON.stringify(patch),
52
+ });
53
+ if (!res.ok)
54
+ throw new Error(`Update satellite failed: ${res.status}`);
55
+ const envelope = await res.json();
56
+ return envelope.data.satellite;
57
+ }
58
+ async link(id, targetSatelliteId) {
59
+ const res = await fetch(`${this.baseUrl}/api/v1/satellites/${encodeURIComponent(id)}/link`, {
60
+ method: 'POST',
61
+ headers: this.headers,
62
+ body: JSON.stringify({ targetSatelliteId }),
63
+ });
64
+ if (!res.ok)
65
+ throw new Error(`Link satellite failed: ${res.status}`);
66
+ const envelope = await res.json();
67
+ return envelope.data.satellite;
68
+ }
69
+ }
70
+ exports.SatellitesClient = SatellitesClient;
71
+ //# sourceMappingURL=satellites.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"satellites.client.js","sourceRoot":"","sources":["../src/satellites.client.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@evolith/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Typed client library for the Evolith Core REST API and MCP tools",
5
+ "author": "",
6
+ "license": "UNLICENSED",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc -p tsconfig.json",
14
+ "build:watch": "tsc -p tsconfig.json --watch",
15
+ "generate": "echo 'No OpenAPI spec file present — types are hand-authored from the NestJS controller DTOs'",
16
+ "test": "jest",
17
+ "test:cov": "jest --coverage",
18
+ "lint": "eslint \"src/**/*.ts\" --fix"
19
+ },
20
+ "devDependencies": {
21
+ "@evolith/agent-runtime": "*",
22
+ "@types/jest": "30.0.0",
23
+ "@types/node": "26.0.0",
24
+ "jest": "30.4.2",
25
+ "ts-jest": "29.4.11",
26
+ "typescript": "6.0.3"
27
+ },
28
+ "jest": {
29
+ "moduleFileExtensions": [
30
+ "js",
31
+ "json",
32
+ "ts"
33
+ ],
34
+ "rootDir": "src",
35
+ "testRegex": ".*\\.spec\\.ts$",
36
+ "transform": {
37
+ "^.+\\.(t|j)s$": "ts-jest"
38
+ },
39
+ "moduleNameMapper": {
40
+ "^(\\.{1,2}/.*)\\.js$": "$1"
41
+ },
42
+ "collectCoverageFrom": [
43
+ "**/*.(t|j)s"
44
+ ],
45
+ "coverageDirectory": "../coverage",
46
+ "testEnvironment": "node"
47
+ },
48
+ "dependencies": {
49
+ }
50
+ }