npm.io
3.0.0 • Published 1 month ago

@x12i/runx

Licence
MIT
Version
3.0.0
Deps
6
Size
790 kB
Vulns
0
Weekly
0

@x12i/runx

Runx is a Catalox-backed capability platform with:

  • Composer@x12i/runx/composer (folder LLM functions → drafts)
  • Auditor / governance@x12i/runx/auditor (static → audit → shadow → contract → lock)
  • Run — JS via createRunx().run; scripts via locked scriptId + production Runner (@x12i/runx/run)

Contracts: @x12i/runx/contracts. LLM folders: llm-functions/ in this package. Redesign docs: docs/redesign/.

Runx stores capability records in Catalox, loads them into an in-memory cache, executes active JavaScript capabilities, and governs script publication. Function / API / script / mapping authoring is owned by Runx Composer (not FuncX). @x12i/funcx is an optional peer for legacy helpers / createClient re-export.


What Runx is good for

Goal How Runx helps
Shared capability catalog One source of truth in Catalox; reload into cache when the catalog changes.
Runtime execution Call runx.run(capabilityId, input, params) for active JavaScript capabilities (v1).
Transparent artifacts Fetch source, tests, docs, and dependency manifests via getCapabilityArtifact / getCapabilityBundle—Runx does not hide generated code.
AI / agent integration Expose the stored capability catalog over MCP (@x12i/runx-mcp, CLI runx-mcp) so clients discover and call tools dynamically.
Reuse before regeneration Capabilities can compose, wrap, or parameterize others; metadata tracks reuse and dependencies.
Runtime condition checks Evaluate whether content meets a JavaScript or JSON rule via checkContentCondition / runx.condition.checkContentCondition (Rendrix templates, filter predicates, JSONLogic, JSONata, optional model).
Ops / UI deliverables Script and UI capabilities are artifact-first (runbooks, React/HTML panels)—export and run outside Runx when needed.

How the pieces fit together

Composer (folder LLM + AI router)  →  candidate draft (no scriptId)
Governance (static/audit/shadow/contract) → lock → scriptId
Catalox catalogs  →  Runx SDK run / artifacts / MCP
  • Composer / Auditor@x12i/runx/composer, @x12i/runx/auditor; instructions in llm-functions/.
  • Catalox — persists capabilities and locked scripts.
  • Run — JS in-process; Python/Bash only through production Runner with locked ids.
  • FuncX — optional peer; runx.* generators for the four Composer modes are deprecated (RUNX_AUTHORING_MODE).

Important: Runx MCP exposes the Runx capability catalog plus optional runx.execute. It does not mirror the full FuncX function catalog.


Capability kinds

Kind Typical use Runtime in v1 core
javascript Transforms, scoring, helpers Executed via runx.run
api-adapter External API connectors Stored; execution path evolving (MCP gated)
composition / wrapper / parameterized Reuse and specialization Stored; JS execution for leaf nodes
ui React / OpenUI / HTML panels Artifacts (not executed in-process by default)
script PowerShell, bash, runbooks Artifacts (controlled runner not enabled by default)

Every capability supports two consumption modes:

  • Runtimeawait runx.run(id, input, params)
  • Artifactawait runx.getCapabilityBundle(id, { includeDependencies: true, ... })

Install

npm install @x12i/runx

Requires Node.js ≥ 20.


Configuration

Copy .env.example to .env for local development (do not commit secrets).

Variable Purpose
MONGO_URI or CATALOX_MONGO_URI Required — Catalox 6 Mongo backend
OPEN_ROUTER_KEY FuncX LLM backend when using funcxCreateOptions
CATALOX_RECORD_HISTORY Set to 1 to enable record history (requires S3/R2 env)
RUNX_CAPABILITIES_CATALOG_ID Override default runx-capabilities
RUNX_RUNTIME_PACKAGES_CATALOG_ID Override default runx-runtime-packages

You can also pass a custom catalox instance into createRunx({ catalox }) for tests or alternate backends.


Quick start (SDK)

import { createRunx } from "@x12i/runx";
import type { RunxCapability } from "@x12i/runx";

const runx = await createRunx({
  // Optional: FuncX for authoring
  // funcxCreateOptions: { backend: "openrouter", ... },
});

await runx.bootstrap();   // ensure Runx catalogs exist in Catalox
await runx.reload();        // load capabilities into the in-memory cache

// Persist a capability (often produced by FuncX authoring, then normalized)
const capability: RunxCapability = {
  capabilityId: "normalize-finding",
  displayName: "Normalize finding",
  description: "Maps raw finding input to a canonical shape",
  kind: "javascript",
  status: "active",
  revision: 1,
  runtime: {
    runtimeLanguage: "javascript",
    executionRuntime: "node",
    moduleFormat: "esm",
    entrypoint: "run",
    executionKind: "node-js",
  },
  contract: {
    inputSchema: { type: "object" },
    outputSchema: { type: "object" },
  },
  artifacts: {
    javascript: {
      language: "javascript",
      moduleFormat: "esm",
      source: `export async function run(input, params = {}, _context = {}) {
        return { normalized: input, params };
      }`,
      filename: "normalize-finding.mjs",
      entrypoint: "run",
      exports: ["run"],
      sourceHash: "",
      sizeBytes: 0,
    },
  },
  dependencies: { internalCapabilities: [], runtimePackages: [] },
  reuse: { searchKeys: [], reusedFrom: [] },
  exposure: { publicName: "normalize-finding", toolExposureMode: "input-only" },
  tags: ["example"],
  audit: { createdAt: new Date().toISOString(), createdBy: "app" },
};

await runx.putCapability(capability);
await runx.reloadCapability("normalize-finding");

// Run
const result = await runx.run("normalize-finding", { title: "Issue" }, {});
if (result.ok) console.log(result.output);

// Export full bundle (code + dependency manifest)
const bundle = await runx.getCapabilityBundle("normalize-finding", {
  includeDependencies: true,
  includeTests: true,
});
Condition evaluation (checkContentCondition)

Use the built-in runtime evaluator to answer: does this content meet this condition?

import {
  checkContentCondition,
  seedCheckContentConditionCapability,
} from "@x12i/runx";
// Or import only the library: import { checkContentCondition } from "@x12i/runx/condition";

// Direct (no Catalox)
const result = await checkContentCondition({
  content: { status: "active", score: 91 },
  condition: "content.status === 'active' && content.score >= parameters.minScore",
  parameters: { minScore: 80 },
  conditionType: "javascript",
});
// { ok: true, meetsCondition: true, reasoning: "..." }

// Via stored capability (after seeding once per catalog)
await seedCheckContentConditionCapability(runx);
await runx.reloadCapability("runx.condition.checkContentCondition");
const runResult = await runx.run("runx.condition.checkContentCondition", {
  content: { department: "Finance" },
  conditionType: "json",
  condition: {
    all: [{ path: "content.department", op: "eq", value: "Finance" }],
  },
}, {});

Supported condition types:

conditionType Formats Notes
javascript expression, return body, function Sandboxed node:vm; Rendrix {{tokens}} from parameters
json native filter predicate (all / any / not), JSONLogic, JSONata wrapper options.jsonConditionFormat: auto (default) or explicit
either custom semantic rules mode: "hybrid" or mode: "model" + client / funcx on createRunx

Authoring flows (FuncX runx.condition.create*) can smoke-test generated rules with verifyConditionWithRunx(runx, input).

Typical application flow
  1. createRunx() — connect to Catalox (from env or injected client).
  2. bootstrap() — create Runx catalog entries if missing.
  3. reload() — refresh the in-memory cache from Catalox.
  4. Author — use FuncX runx.* skills, then putCapability (or upsert via your pipeline).
  5. run / getCapabilityBundle / getCapabilityArtifact — execute or export.
  6. reloadCapability(id) after external catalog edits.

createCapability() on the client is reserved for a future end-to-end path; today, persist with putCapability after FuncX authoring (see error message in createRunx.ts).


MCP: expose capabilities to AI clients

Install globally or use npx:

npx @x12i/runx-mcp runx-mcp --transport stdio

Each active executable capability becomes a tool named runx.<capabilityId>. UI/script capabilities can expose artifact/bundle tools when configured (--expose-artifacts, --expose-bundles).

Cursor / Claude Desktop (stdio)
{
  "mcpServers": {
    "runx": {
      "command": "npx",
      "args": ["-y", "@x12i/runx-mcp", "runx-mcp", "--transport", "stdio", "--active-only"],
      "env": {
        "MONGO_URI": "mongodb://..."
      }
    }
  }
}
Programmatic server
import { createRunx } from "@x12i/runx";
import { createRunxMcpStdioServer } from "@x12i/runx-mcp";

const runx = await createRunx();
await runx.bootstrap();
await runx.reload();

const mcp = await createRunxMcpStdioServer({
  runx,
  exposure: { activeOnly: true, exposeArtifactTools: true },
});
await mcp.start();

HTTP transport: createRunxMcpHttpServer or runx-mcp --transport http --port 3334.

Read-only catalog context is available as MCP resources (e.g. runx://catalog/capabilities, runx://capabilities/{id}/artifacts/javascript). See docs/mcp.md for tool naming, security defaults, and exposure policy.


Main API surface

Method Description
bootstrap() Ensure Runx Catalox catalogs exist
load() / reload() Refresh in-memory cache from Catalox
putCapability / getCapability / listCapabilities CRUD against the capability catalog
run(capabilityId, input?, params?, options?) Execute (JavaScript in v1 core)
getCapabilityArtifact / getCapabilityBundle / exportCapability Artifact and export paths
activateCapability / archiveCapability / deleteCapability Lifecycle
getToolSpec / listToolSpecs Tool metadata for integrators
listRuntimePackages / putRuntimePackage Allowed npm packages for sandboxed runs
checkContentCondition Evaluate content against a JS/JSON condition (also @x12i/runx/condition)
seedCheckContentConditionCapability Idempotent putCapability for runx.condition.checkContentCondition
verifyConditionWithRunx Authoring smoke-test helper wrapping runx.run for the condition capability

Types are exported from @x12i/runx. Subpath export: @x12i/runx/condition. MCP: @x12i/runx-mcp.


Development

npm install
npm run build
npm test
# Live tests (Mongo/Catalox + condition evaluator; requires .env with MONGO_URI):
RUNX_LIVE_TESTS=1 npm run test:live

Live suite covers catalog bootstrap, runx.condition.checkContentCondition seed/run/bundle, and direct checkContentCondition against Mongo when RUNX_LIVE_TESTS=1 (or deprecated FIRESTORE_LIVE_TESTS=1).


Documentation

Doc Contents
docs/specs.md Full product and package specification
docs/mcp.md MCP tools, resources, prompts, security
docs/appendix.md Supplementary notes

V1 scope (read before production)

  • JavaScript capabilities are fully executed in the core library; other executable kinds are stored and exposed but may return unsupported_kind until implemented.
  • Condition evaluation (runx.condition.checkContentCondition) sandboxes condition JavaScript in node:vm; the outer capability module still runs in the host Node process. Seed with seedCheckContentConditionCapability before calling via runx.run.
  • Scripts are not executed through Runx or MCP by default—use artifacts and an external runner.
  • Authoring goes through FuncX, not runx.createCapability().
  • MCP reflects the Runx catalog dynamically; tighten exposure with --active-only, kind/id allowlists, and auth policies for HTTP deployments.

License

MIT

Keywords