@bpmnkit/proxy 0.0.26 → 0.0.27

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.
@@ -18,6 +18,7 @@ import { readFileSync, writeFileSync } from "node:fs";
18
18
  import { createInterface } from "node:readline";
19
19
  import vm from "node:vm";
20
20
  import { Bpmn, Dmn, Form, compactify, compactifyDmn, compactifyForm, expand, expandDmn, expandForm, layoutDmn, layoutProcess, } from "@bpmnkit/core";
21
+ import { handleSdkExecute, handleSdkSearch } from "./sdk-code-mode.js";
21
22
  // ── CLI args ──────────────────────────────────────────────────────────────────
22
23
  function getArg(flag) {
23
24
  const idx = process.argv.indexOf(flag);
@@ -316,6 +317,52 @@ const BPMN_TOOLS = [
316
317
  required: ["diagram"],
317
318
  },
318
319
  },
320
+ {
321
+ name: "sdk_search",
322
+ description: "Inspect the @bpmnkit/core SDK to discover available functions and the CompactDiagram format.\n" +
323
+ "Receives `spec.functions` (available operations) and `spec.compactDiagram` (input/output shape).\n\n" +
324
+ "Example — list all available functions:\n" +
325
+ " return Object.entries(spec.functions).map(([name, s]) => name + ': ' + s.description)\n\n" +
326
+ "Example — get element type list:\n" +
327
+ " return spec.compactDiagram.shape.processes[0].elements[0].type",
328
+ inputSchema: {
329
+ type: "object",
330
+ properties: {
331
+ code: {
332
+ type: "string",
333
+ description: "JavaScript returning a value. Has `spec` as a global.",
334
+ },
335
+ },
336
+ required: ["code"],
337
+ },
338
+ },
339
+ {
340
+ name: "sdk_execute",
341
+ description: "Execute JavaScript using @bpmnkit/core SDK functions. Has `sdk` with parse, exportXml, optimize, layout, analyzeVariables.\n" +
342
+ "All sdk functions take/return strings (XML or JSON). Pass input XML via the `xml` argument.\n" +
343
+ "Call sdk_search first to see function signatures and the CompactDiagram shape.\n\n" +
344
+ "Example — parse, optimize, and re-export:\n" +
345
+ " const compact = sdk.parse(xml)\n" +
346
+ " const { diagram, findings } = JSON.parse(sdk.optimize(compact))\n" +
347
+ " return { findings, xml: sdk.exportXml(JSON.stringify(diagram)) }\n\n" +
348
+ "Example — analyze variable flow:\n" +
349
+ " const compact = sdk.parse(xml)\n" +
350
+ " return JSON.parse(sdk.analyzeVariables(compact))",
351
+ inputSchema: {
352
+ type: "object",
353
+ properties: {
354
+ code: {
355
+ type: "string",
356
+ description: "JavaScript with access to `sdk` and optional `xml` global.",
357
+ },
358
+ xml: {
359
+ type: "string",
360
+ description: "Optional BPMN XML injected as `xml` global inside the sandbox.",
361
+ },
362
+ },
363
+ required: ["code"],
364
+ },
365
+ },
319
366
  ];
320
367
  const DMN_TOOLS = [
321
368
  {
@@ -507,6 +554,15 @@ function callTool(name, args) {
507
554
  throw new Error(`Code execution failed: ${err instanceof Error ? err.message : String(err)}`);
508
555
  }
509
556
  }
557
+ case "sdk_search": {
558
+ const code = args.code;
559
+ return handleSdkSearch(code);
560
+ }
561
+ case "sdk_execute": {
562
+ const code = args.code;
563
+ const xml = args.xml;
564
+ return handleSdkExecute(code, xml);
565
+ }
510
566
  default:
511
567
  throw new Error(`Unknown tool: ${name}`);
512
568
  }
@@ -0,0 +1,27 @@
1
+ import ivm from "isolated-vm";
2
+ export async function runSandboxed(code, ctx, timeoutMs = 5000) {
3
+ const isolate = new ivm.Isolate({ memoryLimit: 64 });
4
+ try {
5
+ const context = await isolate.createContext();
6
+ const jail = context.global;
7
+ await jail.set("global", jail.derefInto());
8
+ for (const [key, value] of Object.entries(ctx.data ?? {})) {
9
+ await jail.set(key, new ivm.ExternalCopy(value).copyInto());
10
+ }
11
+ for (const [key, fn] of Object.entries(ctx.functions ?? {})) {
12
+ await jail.set(key, new ivm.Reference(async (...args) => {
13
+ const result = await fn(...args);
14
+ return new ivm.ExternalCopy(result).copyInto();
15
+ }));
16
+ }
17
+ const fullCode = ctx.bootstrap ? `${ctx.bootstrap}\n${code}` : code;
18
+ return await context.evalClosure(`return (async function() {\n${fullCode}\n})()`, [], {
19
+ result: { promise: true, copy: true },
20
+ timeout: timeoutMs,
21
+ });
22
+ }
23
+ finally {
24
+ isolate.dispose();
25
+ }
26
+ }
27
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1,60 @@
1
+ import vm from "node:vm";
2
+ import { Bpmn, analyzeVariableFlow, applyAutoLayout, compactify, expand, optimize, } from "@bpmnkit/core";
3
+ import { SDK_SPEC } from "./sdk-spec.js";
4
+ function buildSdkContext(xml) {
5
+ return {
6
+ xml: xml ?? "",
7
+ sdk: {
8
+ parse: (rawXml) => {
9
+ const defs = Bpmn.parse(String(rawXml));
10
+ return JSON.stringify(compactify(defs));
11
+ },
12
+ exportXml: (compactJson) => {
13
+ const defs = expand(JSON.parse(String(compactJson)));
14
+ const laidOut = applyAutoLayout(defs);
15
+ return Bpmn.export(laidOut);
16
+ },
17
+ optimize: (compactJson) => {
18
+ const compact = JSON.parse(String(compactJson));
19
+ const defs = expand(compact);
20
+ const report = optimize(defs);
21
+ return JSON.stringify({
22
+ diagram: compact,
23
+ findings: report.findings,
24
+ });
25
+ },
26
+ layout: (compactJson) => {
27
+ const defs = expand(JSON.parse(String(compactJson)));
28
+ const laidOut = applyAutoLayout(defs);
29
+ return JSON.stringify(compactify(laidOut));
30
+ },
31
+ analyzeVariables: (compactJson) => {
32
+ const defs = expand(JSON.parse(String(compactJson)));
33
+ // analyzeVariableFlow operates per-process; run on each and collect
34
+ const results = defs.processes.map((p) => analyzeVariableFlow(p));
35
+ return JSON.stringify(results);
36
+ },
37
+ },
38
+ };
39
+ }
40
+ function runInVm(code, ctx, timeoutMs) {
41
+ const context = vm.createContext(ctx);
42
+ try {
43
+ return vm.runInContext(`(function(){\n${code}\n})()`, context, {
44
+ timeout: timeoutMs,
45
+ });
46
+ }
47
+ catch (err) {
48
+ throw new Error(`Code execution failed: ${err instanceof Error ? err.message : String(err)}`);
49
+ }
50
+ }
51
+ export function handleSdkSearch(code) {
52
+ // JSON round-trip ensures Object.keys works on plain objects inside the vm context
53
+ const result = runInVm(code, { spec: JSON.parse(JSON.stringify(SDK_SPEC)) }, 5000);
54
+ return JSON.stringify(result);
55
+ }
56
+ export function handleSdkExecute(code, xml) {
57
+ const result = runInVm(code, buildSdkContext(xml), 10000);
58
+ return JSON.stringify(result);
59
+ }
60
+ //# sourceMappingURL=sdk-code-mode.js.map
@@ -0,0 +1,67 @@
1
+ // apps/proxy/src/sdk-spec.ts
2
+ // Describes functions available in sdk_execute and the CompactDiagram shape.
3
+ export const SDK_SPEC = {
4
+ functions: {
5
+ "sdk.parse": {
6
+ description: "Parse BPMN XML into a CompactDiagram JSON string.",
7
+ params: "xml: string",
8
+ returns: "string (CompactDiagram JSON)",
9
+ example: "const compact = sdk.parse(xml)",
10
+ },
11
+ "sdk.exportXml": {
12
+ description: "Convert a CompactDiagram JSON string to BPMN XML with auto-layout applied.",
13
+ params: "compactJson: string",
14
+ returns: "string (BPMN XML)",
15
+ example: "const xml = sdk.exportXml(compact)",
16
+ },
17
+ "sdk.optimize": {
18
+ description: "Run the pattern advisor on a CompactDiagram. Returns findings and an optimized diagram.",
19
+ params: "compactJson: string",
20
+ returns: "string (JSON: { diagram: CompactDiagram, findings: Finding[] })",
21
+ example: "const { diagram, findings } = JSON.parse(sdk.optimize(compact))",
22
+ },
23
+ "sdk.layout": {
24
+ description: "Apply automatic ELK layout to a CompactDiagram. Returns updated CompactDiagram JSON.",
25
+ params: "compactJson: string",
26
+ returns: "string (CompactDiagram JSON)",
27
+ example: "const laidOut = JSON.parse(sdk.layout(compact))",
28
+ },
29
+ "sdk.analyzeVariables": {
30
+ description: "Analyze FEEL variable flow across a process. Identifies undeclared inputs and output variable paths.",
31
+ params: "compactJson: string",
32
+ returns: "string (JSON: VariableFlowAnalysis)",
33
+ example: "const analysis = JSON.parse(sdk.analyzeVariables(compact))",
34
+ },
35
+ },
36
+ compactDiagram: {
37
+ description: "Lightweight JSON representation of a BPMN diagram. Input/output format for all sdk functions.",
38
+ shape: {
39
+ processes: [
40
+ {
41
+ id: "string — process id, e.g. 'order-flow'",
42
+ name: "string? — display name",
43
+ elements: [
44
+ {
45
+ id: "string",
46
+ type: "startEvent | endEvent | serviceTask | userTask | businessRuleTask | scriptTask | callActivity | exclusiveGateway | parallelGateway | inclusiveGateway | eventBasedGateway | subProcess | adHocSubProcess | intermediateThrowEvent | intermediateCatchEvent | boundaryEvent",
47
+ name: "string?",
48
+ jobType: "string? — Zeebe job worker type (serviceTask only)",
49
+ decisionId: "string? — DMN decision id (businessRuleTask only)",
50
+ formId: "string? — Camunda form id (userTask only)",
51
+ calledElement: "string? — process id of called process (callActivity only)",
52
+ },
53
+ ],
54
+ flows: [
55
+ {
56
+ id: "string",
57
+ sourceRef: "string — source element id",
58
+ targetRef: "string — target element id",
59
+ condition: "string? — FEEL expression (exclusive gateway outgoing flows only)",
60
+ },
61
+ ],
62
+ },
63
+ ],
64
+ },
65
+ },
66
+ };
67
+ //# sourceMappingURL=sdk-spec.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bpmnkit/proxy",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "description": "Local proxy server for BPMN Kit — AI bridge (SSE/MCP) and Camunda API proxy using stored CLI profiles",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,11 +26,12 @@
26
26
  "dependencies": {
27
27
  "better-sqlite3": "^12.8.0",
28
28
  "imapflow": "^1.2.18",
29
+ "isolated-vm": "^7.0.0",
29
30
  "nodemailer": "^6.10.1",
30
- "@bpmnkit/api": "0.0.18",
31
- "@bpmnkit/core": "0.0.23",
32
- "@bpmnkit/patterns": "0.0.3",
33
- "@bpmnkit/profiles": "0.0.16"
31
+ "@bpmnkit/api": "0.0.19",
32
+ "@bpmnkit/core": "0.0.24",
33
+ "@bpmnkit/patterns": "0.0.4",
34
+ "@bpmnkit/profiles": "0.0.17"
34
35
  },
35
36
  "publishConfig": {
36
37
  "access": "public"