@melra/sdk 0.3.0-alpha.10 → 0.3.0-alpha.12

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.md CHANGED
@@ -3,8 +3,9 @@
3
3
  TypeScript client for [MELRA](https://github.com/XAGI-Lab/melra), a local-only
4
4
  MCP server that turns one tool call into a governed, verified, receipted task.
5
5
 
6
- The client spawns a MELRA server over stdio and speaks the task and workflow
7
- tools for you, so you work with typed requests instead of raw MCP plumbing.
6
+ The client spawns a MELRA server over stdio, or connects to one already running
7
+ over HTTP or a Unix socket, and speaks the task and workflow tools for you, so
8
+ you work with typed requests instead of raw MCP plumbing.
8
9
 
9
10
  ```bash
10
11
  npm install @melra/sdk
@@ -63,6 +64,44 @@ const melra = await MelraClient.connect({
63
64
  });
64
65
  ```
65
66
 
67
+ ## Connecting to a running server
68
+
69
+ `melra serve --http` and `melra serve --socket <path>` serve the same MCP tools
70
+ to any number of clients. Pass `url` or `socketPath` instead of a command, plus
71
+ the bearer token the server printed (or was given as `MELRA_HTTP_TOKEN`). Every
72
+ method below works the same on all three transports.
73
+
74
+ ```ts
75
+ import { MelraClient } from "@melra/sdk";
76
+
77
+ const token = process.env.MELRA_HTTP_TOKEN;
78
+ if (token === undefined) throw new Error("set MELRA_HTTP_TOKEN");
79
+
80
+ // The MCP URL `serve --http` prints; the bare origin works too.
81
+ const overHttp = await MelraClient.connect({
82
+ url: "http://127.0.0.1:7457/mcp",
83
+ token,
84
+ });
85
+
86
+ // Not on Windows, where the server refuses sockets as well.
87
+ const overSocket = await MelraClient.connect({
88
+ socketPath: `${process.env.XDG_RUNTIME_DIR}/melra.sock`,
89
+ token,
90
+ });
91
+
92
+ await overHttp.close();
93
+ await overSocket.close();
94
+ ```
95
+
96
+ The token is never read from the environment for you: a library that picks up
97
+ a credential on its own and sends it to whatever URL it was handed is how
98
+ tokens leak. A plain `http:` URL is refused unless its host is loopback
99
+ (`localhost`, `127.0.0.0/8`, `[::1]`) — the token drives the machine, and over
100
+ cleartext it is readable by anything on the path. Put TLS in front and use
101
+ `https:`, or, on a network you trust end to end such as a private container
102
+ network, pass `allowInsecureHttp: true`. A wrong token fails `connect()` with
103
+ `melra_unauthorized`.
104
+
66
105
  ## Workflows
67
106
 
68
107
  `planWorkflow`, `advanceWorkflow`, `workflowStatus`, `cancelWorkflow`, and
package/dist/index.d.ts CHANGED
@@ -1,12 +1,40 @@
1
1
  import { type WorkflowAdvanceResult, type WorkflowDefinitionInput, type WorkflowInput, type WorkflowRun, type ApprovalResponse, type TaskRequestInput } from "@melra/protocol";
2
- export interface MelraClientOptions {
2
+ interface ClientIdentity {
3
+ clientName?: string;
4
+ clientVersion?: string;
5
+ }
6
+ /** Spawn `melra serve` (or `command`) as a child and speak MCP over stdio. */
7
+ export interface MelraStdioOptions extends ClientIdentity {
3
8
  command?: string;
4
9
  args?: string[];
5
10
  cwd?: string;
6
11
  env?: Record<string, string>;
7
- clientName?: string;
8
- clientVersion?: string;
9
12
  }
13
+ /**
14
+ * Connect to a running `melra serve --http`. `url` is the MCP endpoint it
15
+ * prints (`http://127.0.0.1:7457/mcp`); plain `http:` is accepted only for a
16
+ * loopback host, since the token would otherwise cross the network in clear.
17
+ */
18
+ export interface MelraHttpOptions extends ClientIdentity {
19
+ url: string | URL;
20
+ token: string;
21
+ /**
22
+ * Send the token over plain `http:` to a host that is not loopback. Off by
23
+ * default; turn it on only for a network you trust end to end, such as a
24
+ * private container network, and prefer `https:` everywhere else.
25
+ */
26
+ allowInsecureHttp?: boolean;
27
+ }
28
+ /** Connect to a running `melra serve --socket <path>`. Not on Windows. */
29
+ export interface MelraSocketOptions extends ClientIdentity {
30
+ socketPath: string;
31
+ token: string;
32
+ }
33
+ type Without<K extends string> = {
34
+ [P in K]?: never;
35
+ };
36
+ type StdioKeys = "command" | "args" | "cwd" | "env";
37
+ export type MelraClientOptions = (MelraStdioOptions & Without<"url" | "socketPath" | "token" | "allowInsecureHttp">) | (MelraHttpOptions & Without<StdioKeys | "socketPath">) | (MelraSocketOptions & Without<StdioKeys | "url" | "allowInsecureHttp">);
10
38
  export declare function parseMelraToolResult(result: unknown): Record<string, unknown>;
11
39
  export declare class MelraClient {
12
40
  private readonly client;
@@ -29,4 +57,5 @@ export declare class MelraClient {
29
57
  controlWorkflow(workflowId: string, action: "pause" | "resume" | "suspend"): Promise<WorkflowRun>;
30
58
  close(): Promise<void>;
31
59
  }
60
+ export {};
32
61
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAQL,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,iBAAiB,CAAC;AAEzB,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAOD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS7E;AAED,qBAAa,WAAW;IACF,OAAO,CAAC,QAAQ,CAAC,MAAM;IAA3C,OAAO;WAEM,OAAO,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,WAAW,CAAC;YAgB9D,IAAI;IASZ,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAQhD,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAQjE,OAAO,CACX,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAO7B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAIxD,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAIxD,OAAO,CAAC,KAAK,EAAE;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAc9B,YAAY,CAChB,UAAU,EAAE,uBAAuB,GAClC,OAAO,CAAC,WAAW,CAAC;IASjB,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,gBAAgB,EAAO,EAClC,MAAM,GAAE,aAAa,EAAO,GAC3B,OAAO,CAAC,qBAAqB,CAAC;IAW3B,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAOxD,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAOxD,eAAe,CACnB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GACrC,OAAO,CAAC,WAAW,CAAC;IAOjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -2,6 +2,8 @@
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
4
4
  import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
5
+ import { StreamableHTTPError } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
6
+ import { httpTransport, socketTransport } from "./remote.js";
5
7
  import { WorkflowAdvanceInputSchema, WorkflowAdvanceResultSchema, WorkflowControlInputSchema, WorkflowDefinitionSchema, WorkflowIdInputSchema, WorkflowRunSchema, TaskRequestSchema, } from "@melra/protocol";
6
8
  export function parseMelraToolResult(result) {
7
9
  const response = result;
@@ -18,18 +20,33 @@ export class MelraClient {
18
20
  this.client = client;
19
21
  }
20
22
  static async connect(options = {}) {
21
- const transport = new StdioClientTransport({
22
- command: options.command ?? "melra",
23
- args: options.args ?? ["serve"],
24
- ...(options.cwd === undefined ? {} : { cwd: options.cwd }),
25
- ...(options.env === undefined ? {} : { env: options.env }),
26
- stderr: "pipe",
27
- });
23
+ const transport = options.url !== undefined
24
+ ? httpTransport(options.url, options.token, options.allowInsecureHttp === true)
25
+ : options.socketPath !== undefined
26
+ ? socketTransport(options.socketPath, options.token)
27
+ : new StdioClientTransport({
28
+ command: options.command ?? "melra",
29
+ args: options.args ?? ["serve"],
30
+ ...(options.cwd === undefined ? {} : { cwd: options.cwd }),
31
+ ...(options.env === undefined ? {} : { env: options.env }),
32
+ stderr: "pipe",
33
+ });
28
34
  const client = new Client({
29
35
  name: options.clientName ?? "melra-sdk",
30
36
  version: options.clientVersion ?? "0.1.0",
31
37
  });
32
- await client.connect(transport);
38
+ try {
39
+ await client.connect(transport);
40
+ }
41
+ catch (error) {
42
+ // `Client.connect` has already closed the transport. Without an OAuth
43
+ // provider the MCP client reports a refused token as a generic POST
44
+ // failure; name it, since it is the one failure a caller can fix.
45
+ if (error instanceof StreamableHTTPError && error.code === 401) {
46
+ throw new Error("melra_unauthorized: the server refused the token; use the one `melra serve` printed or MELRA_HTTP_TOKEN", { cause: error });
47
+ }
48
+ throw error;
49
+ }
33
50
  return new MelraClient(client);
34
51
  }
35
52
  async call(name, args) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
2
+ /**
3
+ * The token is the key to a machine-control API. Over `https:` it is
4
+ * encrypted wherever it goes; over `http:` it is readable by anything on the
5
+ * path, which is nothing only when the path is loopback. A remote `http:`
6
+ * URL means a proxy without TLS, and the SDK refuses to hand it the token
7
+ * rather than leave that to every caller to notice. `allowInsecureHttp` is the
8
+ * explicit opt-out for a network the caller trusts, matching the Python SDK.
9
+ */
10
+ export declare function httpTransport(url: string | URL, token: string, allowInsecureHttp?: boolean): Transport;
11
+ /**
12
+ * Streamable HTTP over a Unix socket. The server names its socket requests
13
+ * `http://localhost`, so that is the URL; the bytes go to `socketPath`.
14
+ */
15
+ export declare function socketTransport(socketPath: string, token: string): Transport;
16
+ //# sourceMappingURL=remote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AA8B/E;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,GAAG,GAAG,EACjB,KAAK,EAAE,MAAM,EACb,iBAAiB,UAAQ,GACxB,SAAS,CAoBX;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAc5E"}
package/dist/remote.js ADDED
@@ -0,0 +1,110 @@
1
+ // Copyright 2026 XAGI Labs Private Limited
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { request as httpRequest } from "node:http";
4
+ import { Readable } from "node:stream";
5
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
6
+ /** Loopback is the only place a cleartext bearer token never crosses a wire. */
7
+ function isLoopbackHost(hostname) {
8
+ // `URL` has already normalised `127.1` to `127.0.0.1` and brackets IPv6.
9
+ return (hostname === "localhost" ||
10
+ hostname === "[::1]" ||
11
+ /^127\.\d+\.\d+\.\d+$/.test(hostname));
12
+ }
13
+ function requireToken(token) {
14
+ // `token: process.env.MELRA_HTTP_TOKEN ?? ""` would otherwise connect with
15
+ // `Bearer ` and fail later as a confusing 401.
16
+ if (token.trim() === "")
17
+ throw new Error("melra_token_required");
18
+ return token.trim();
19
+ }
20
+ function bearer(token) {
21
+ return { headers: { authorization: `Bearer ${requireToken(token)}` } };
22
+ }
23
+ // ponytail: the SDK declares `sessionId?: string` on this transport, which
24
+ // `exactOptionalPropertyTypes` reads as incompatible with the `Transport` it
25
+ // implements. Cast once here, as `apps/cli/src/conformance.ts` does.
26
+ function asTransport(transport) {
27
+ return transport;
28
+ }
29
+ /**
30
+ * The token is the key to a machine-control API. Over `https:` it is
31
+ * encrypted wherever it goes; over `http:` it is readable by anything on the
32
+ * path, which is nothing only when the path is loopback. A remote `http:`
33
+ * URL means a proxy without TLS, and the SDK refuses to hand it the token
34
+ * rather than leave that to every caller to notice. `allowInsecureHttp` is the
35
+ * explicit opt-out for a network the caller trusts, matching the Python SDK.
36
+ */
37
+ export function httpTransport(url, token, allowInsecureHttp = false) {
38
+ const parsed = new URL(url);
39
+ // `serve --http` prints both the console URL and the MCP URL; accept either,
40
+ // as `melra conformance --url` does. The console URL carries `?token=`,
41
+ // which has no business riding along on every MCP request.
42
+ if (!parsed.pathname.endsWith("/mcp")) {
43
+ parsed.pathname = `${parsed.pathname.replace(/\/$/, "")}/mcp`;
44
+ parsed.search = "";
45
+ }
46
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
47
+ throw new Error(`melra_unsupported_url: ${parsed.protocol} is not http(s)`);
48
+ }
49
+ if (parsed.protocol === "http:" && !allowInsecureHttp && !isLoopbackHost(parsed.hostname)) {
50
+ throw new Error(`melra_insecure_url: refusing to send the token over plain http to ${parsed.hostname}; use https, a loopback address, or allowInsecureHttp`);
51
+ }
52
+ return asTransport(new StreamableHTTPClientTransport(parsed, { requestInit: bearer(token) }));
53
+ }
54
+ /**
55
+ * Streamable HTTP over a Unix socket. The server names its socket requests
56
+ * `http://localhost`, so that is the URL; the bytes go to `socketPath`.
57
+ */
58
+ export function socketTransport(socketPath, token) {
59
+ // Mirrors the server, which refuses `--socket` on Windows: a named pipe's
60
+ // ACL is not a mode it can check, so there is nothing to connect to.
61
+ if (process.platform === "win32") {
62
+ throw new Error("socket_transport_unsupported_on_windows: use stdio or loopback HTTP");
63
+ }
64
+ return asTransport(new StreamableHTTPClientTransport(new URL("http://localhost/mcp"), {
65
+ fetch: socketFetch(socketPath),
66
+ requestInit: bearer(token),
67
+ }));
68
+ }
69
+ /**
70
+ * `fetch` over a Unix socket, built on `http.request`, which is the one client
71
+ * in Node that takes a `socketPath` without a dependency. The response body is
72
+ * streamed rather than buffered because Streamable HTTP answers with SSE, and
73
+ * a buffered stream would deliver nothing until the server closed it.
74
+ */
75
+ function socketFetch(socketPath) {
76
+ return async (input, init) => {
77
+ const outgoing = new Request(input, init);
78
+ outgoing.signal.throwIfAborted();
79
+ const url = new URL(outgoing.url);
80
+ // Request bodies are small JSON-RPC messages, so buffering them is fine.
81
+ const body = outgoing.body === null
82
+ ? undefined
83
+ : Buffer.from(await outgoing.arrayBuffer());
84
+ return await new Promise((resolveResponse, rejectResponse) => {
85
+ const request = httpRequest({
86
+ socketPath,
87
+ path: `${url.pathname}${url.search}`,
88
+ method: outgoing.method,
89
+ headers: Object.fromEntries(outgoing.headers),
90
+ }, (incoming) => {
91
+ const headers = new Headers();
92
+ for (const [name, value] of Object.entries(incoming.headers)) {
93
+ if (value !== undefined) {
94
+ headers.set(name, Array.isArray(value) ? value.join(", ") : value);
95
+ }
96
+ }
97
+ const status = incoming.statusCode ?? 500;
98
+ resolveResponse(new Response(status === 204 || status === 304
99
+ ? null
100
+ : Readable.toWeb(incoming), { status, headers }));
101
+ });
102
+ // `close()` aborts the transport's long-lived SSE GET; destroying the
103
+ // request is what actually releases the socket.
104
+ outgoing.signal.addEventListener("abort", () => request.destroy(new Error("aborted")));
105
+ request.on("error", rejectResponse);
106
+ request.end(body);
107
+ });
108
+ };
109
+ }
110
+ //# sourceMappingURL=remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melra/sdk",
3
- "version": "0.3.0-alpha.10",
3
+ "version": "0.3.0-alpha.12",
4
4
  "description": "TypeScript task and workflow client SDK for MELRA.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -21,13 +21,16 @@
21
21
  "dist"
22
22
  ],
23
23
  "dependencies": {
24
- "@modelcontextprotocol/sdk": "1.30.0",
25
- "@melra/protocol": "0.3.0-alpha.10"
24
+ "@modelcontextprotocol/sdk": "1.32.1",
25
+ "@melra/protocol": "0.3.0-alpha.12"
26
+ },
27
+ "devDependencies": {
28
+ "@melra/server": "0.3.0-alpha.12"
26
29
  },
27
30
  "scripts": {
28
31
  "build": "tsc -p tsconfig.json",
29
32
  "clean": "rm -rf dist",
30
33
  "test": "vitest run",
31
- "typecheck": "tsc -p tsconfig.json --noEmit"
34
+ "typecheck": "tsc -p tsconfig.test.json"
32
35
  }
33
36
  }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -1,173 +0,0 @@
1
- // Copyright 2026 XAGI Labs Private Limited
2
- // SPDX-License-Identifier: Apache-2.0
3
- import { describe, expect, it, vi } from "vitest";
4
- import { WorkflowDefinitionSchema } from "@melra/protocol";
5
- import { MelraClient, parseMelraToolResult } from "./index.js";
6
- describe("TypeScript SDK result parsing", () => {
7
- it("parses the server's JSON text contract", () => {
8
- expect(parseMelraToolResult({
9
- content: [{ type: "text", text: '{"verified":true}' }],
10
- })).toEqual({ verified: true });
11
- });
12
- it("does not hide MCP tool errors", () => {
13
- expect(() => parseMelraToolResult({
14
- isError: true,
15
- content: [{ type: "text", text: "approval_required" }],
16
- })).toThrow("approval_required");
17
- });
18
- });
19
- describe("TypeScript workflow SDK", () => {
20
- it("calls the exact workflow tools with typed arguments", async () => {
21
- const workflowId = "11111111-1111-4111-8111-111111111111";
22
- const traceId = "22222222-2222-4222-8222-222222222222";
23
- const definition = WorkflowDefinitionSchema.parse({
24
- schemaVersion: "1.0.0",
25
- id: "33333333-3333-4333-8333-333333333333",
26
- version: 1,
27
- name: "SDK workflow",
28
- nodes: [
29
- {
30
- id: "inspect",
31
- type: "operation",
32
- request: {
33
- goal: "Inspect",
34
- operation: { kind: "system", action: "info" },
35
- },
36
- },
37
- ],
38
- });
39
- const run = {
40
- schemaVersion: "1.0.0",
41
- id: workflowId,
42
- definitionId: definition.id,
43
- definitionVersion: 1,
44
- status: "planned",
45
- stateVersion: 2,
46
- nodes: { inspect: { status: "pending", taskIds: [] } },
47
- traceId,
48
- createdAt: "2026-07-30T12:00:00.000Z",
49
- updatedAt: "2026-07-30T12:00:00.000Z",
50
- };
51
- const callTool = vi.fn(async ({ name }) => ({
52
- content: [
53
- {
54
- type: "text",
55
- text: JSON.stringify(name === "melra_workflow_advance"
56
- ? { run, tasks: [], events: [] }
57
- : run),
58
- },
59
- ],
60
- }));
61
- const client = new MelraClient({
62
- callTool,
63
- async close() { },
64
- });
65
- const approval = {
66
- approvalId: "44444444-4444-4444-8444-444444444444",
67
- phrase: "APPROVE exact",
68
- };
69
- const answer = {
70
- nodeId: "inspect",
71
- value: "ship it",
72
- };
73
- await client.planWorkflow(definition);
74
- await client.advanceWorkflow(workflowId, [approval], [answer]);
75
- await client.workflowStatus(workflowId);
76
- await client.controlWorkflow(workflowId, "pause");
77
- await client.cancelWorkflow(workflowId);
78
- expect(callTool.mock.calls.map(([input]) => input)).toEqual([
79
- {
80
- name: "melra_workflow_plan",
81
- arguments: { definition },
82
- },
83
- {
84
- name: "melra_workflow_advance",
85
- arguments: { workflowId, approvals: [approval], inputs: [answer] },
86
- },
87
- {
88
- name: "melra_workflow_status",
89
- arguments: { workflowId },
90
- },
91
- {
92
- name: "melra_workflow_control",
93
- arguments: { workflowId, action: "pause" },
94
- },
95
- {
96
- name: "melra_workflow_cancel",
97
- arguments: { workflowId },
98
- },
99
- ]);
100
- });
101
- it("plans a definition written by hand, defaults and all", async () => {
102
- const run = {
103
- schemaVersion: "1.0.0",
104
- id: "55555555-5555-4555-8555-555555555555",
105
- definitionId: "66666666-6666-4666-8666-666666666666",
106
- definitionVersion: 1,
107
- status: "planned",
108
- stateVersion: 2,
109
- nodes: { inspect: { status: "pending", taskIds: [] } },
110
- traceId: "77777777-7777-4777-8777-777777777777",
111
- createdAt: "2026-08-08T12:00:00.000Z",
112
- updatedAt: "2026-08-08T12:00:00.000Z",
113
- };
114
- const callTool = vi.fn(async (_input) => ({
115
- content: [{ type: "text", text: JSON.stringify(run) }],
116
- }));
117
- const client = new MelraClient({ callTool, async close() { } });
118
- // No `dependsOn`, `constraints`, `forbiddenEffects`, `requiredEvidence`, or
119
- // `budget`. Requiring those would mean writing out `constraints: []` — where
120
- // any other value is a policy deny — just to satisfy the compiler.
121
- await client.planWorkflow({
122
- schemaVersion: "1.0.0",
123
- id: run.definitionId,
124
- version: 1,
125
- name: "Handwritten workflow",
126
- nodes: [
127
- {
128
- id: "inspect",
129
- type: "operation",
130
- request: {
131
- goal: "Inspect",
132
- operation: { kind: "system", action: "info" },
133
- },
134
- },
135
- ],
136
- });
137
- // The server still receives the complete definition, so the defaults are
138
- // applied once here rather than differing per caller.
139
- expect(callTool.mock.calls[0]?.[0]).toEqual({
140
- name: "melra_workflow_plan",
141
- arguments: {
142
- definition: {
143
- schemaVersion: "1.0.0",
144
- id: run.definitionId,
145
- version: 1,
146
- name: "Handwritten workflow",
147
- nodes: [
148
- {
149
- id: "inspect",
150
- type: "operation",
151
- dependsOn: [],
152
- request: {
153
- goal: "Inspect",
154
- operation: { kind: "system", action: "info" },
155
- constraints: [],
156
- forbiddenEffects: [],
157
- requiredEvidence: [],
158
- budget: { maxSteps: 10, maxDurationMs: 120_000, maxRetries: 2 },
159
- },
160
- },
161
- ],
162
- },
163
- },
164
- });
165
- });
166
- it("names the missing receipt selector without a round trip", async () => {
167
- const callTool = vi.fn();
168
- const client = new MelraClient({ callTool, async close() { } });
169
- await expect(client.receipt({})).rejects.toThrow("taskId or receiptId is required");
170
- expect(callTool).not.toHaveBeenCalled();
171
- });
172
- });
173
- //# sourceMappingURL=index.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}