npm.io
0.6.0 • Published 5d ago

@xtrape/capsule-contracts-node

Licence
Apache-2.0
Version
0.6.0
Deps
1
Size
754 kB
Vulns
0
Weekly
0

Xtrape Contracts for Node.js

TypeScript contracts and Zod schemas for Xtrape Agent, Worker, and Panel wire protocols.

The npm name @xtrape/capsule-contracts-node is a legacy compatibility identifier. Capsule is not a current Xtrape concept. New code should use the canonical Worker* exports; the existing Capsule* exports and services wire field remain available until a versioned protocol migration removes them.

Contract Authority Boundary

Name Role
xtrape-contracts The future language-neutral schema authority for Xtrape contracts (not yet a separate repository).
xtrape-contracts-nodejs (this repo) The TypeScript / Zod runtime validation and type implementation.

Until a standalone xtrape-contracts exists, this package hosts the executable TypeScript schemas, but it is not a separate conceptual authority: the canonical model lives in xtrape-docs (runtime-platform/02..04, architecture/11). When the two disagree, the canonical architecture docs win and this package is corrected to match.

Xtrape CE 0.1 Phase 0 Contracts

The CE 0.1 runtime loop (Telegram → server-ce → demo xtrape-service → reply) depends on a frozen set of schemas, exported from this package and validated by tests/ce-contracts.spec.ts (including a field/enum surface guard):

Export Used by
CE_CONTRACT_VERSION (1) version negotiation across agent server-ce
ServiceManifestSchema / ServiceManifest service registration descriptor
ServiceInstanceSchema / ServiceInstance registered instance with resolvable address
AgentHeartbeatSchema / AgentHeartbeat heartbeat / health reporting
ConversationMessageSchema / ConversationMessage message routing + reply envelope
ErrorModelSchema / ErrorModel (+ CeErrorCode) structured error responses
import { ServiceManifestSchema, CE_CONTRACT_VERSION } from "@xtrape/capsule-contracts-node";

const manifest = ServiceManifestSchema.parse({
  contractVersion: CE_CONTRACT_VERSION,
  service: { id: "demo-echo-service", name: "Demo Echo Service", version: "0.6.0" },
  runtime: { language: "node", agent: "xtrape-agent-nodejs" },
  capabilities: ["status.query"],
  message: { supportedTypes: ["QUERY"] },
});

These schemas are frozen for CE 0.1: changing a field or enum is a contract change that must bump CE_CONTRACT_VERSION and update the surface guard. See the matching examples in xtrape-docs/docs/runtime-platform/01-phase-0-runtime-mvp.md.

License: Apache-2.0 Status: Release Train 0.6.0 Docs

@xtrape/capsule-contracts-node is the current published TypeScript contract package for Panel CE, Agent SDKs, and Worker integrations. It exports Zod schemas, inferred TypeScript types, enum values, ID helpers, pagination helpers, and protocol error helpers for the Agent/Admin/System wire contracts.

Package status: This package follows the unified Xtrape 0.6.0 release train. The npm package name remains a compatibility identifier, but release versioning now follows the shared Xtrape train version.

Install

This repository tracks the 0.6.0 snapshot train. Until the 0.6.0 npm cut is published, install the latest published compatibility package:

pnpm add @xtrape/capsule-contracts-node@^0.5.1

For this repository itself:

pnpm install
pnpm build

What is Included

The package currently exports:

  • Zod itself as z for consumers that want one compatible Zod instance.
  • Status enum arrays and types: AgentStatus, WorkerStatus (plus the legacy CapsuleServiceStatus alias), HealthStatus, CommandStatus, DangerLevel, AuditActorType, AuditResult, TokenStatus, AgentMode.
  • Admin schemas: users, sessions, registration token requests/responses.
  • Agent schemas: registration, heartbeat, service report, command result.
  • Worker schemas: Worker Manifest, Worker Runtime Report, Worker Instance, health, config, Action, and Worker Instance detail. Legacy Capsule-named aliases remain available for wire compatibility.
  • Command schemas: create command, command detail, command result.
  • Audit and dashboard schemas.
  • System health/version schemas.

The additive v0.4 Worker endpoint aliases and their legacy mappings are recorded in spec/worker-compatibility-v0.4.json. The older CE v0.1 OpenAPI file remains the historical baseline rather than being silently rewritten into a different protocol version.

Known contract drift: the historical structured sources still disagree on some Command and effective-status enum values. The WorkerStatus export is an alias of the currently shipped binding; it does not claim that the unresolved enum migration documented in xtrape-docs has been completed.

  • Helpers: parseSort, paginate, HttpError, ListQueryBase.

Validate Agent Registration

import { RegisterAgentRequestSchema } from "@xtrape/capsule-contracts-node";

const request = RegisterAgentRequestSchema.parse(input);

// request.registrationToken starts with opstage_reg_
// request.agent.mode is embedded or ophub

Lowercase aliases are also exported for backend compatibility:

import { registerAgentRequestSchema } from "@xtrape/capsule-contracts-node";

const request = registerAgentRequestSchema.parse(input);

v0.3 External-Agent Compatibility and Metadata

v0.3 adds the legacy ophub Agent-mode wire value for the historical Go external-Agent runtime. It represents one or more local Workers. It is not the canonical Gateway role: Gateway routes Agent/control-plane traffic while preserving Agent protocol semantics.

import { RegisterAgentRequestSchema, ServiceReportRequestSchema } from "@xtrape/capsule-contracts-node";

RegisterAgentRequestSchema.parse({
  registrationToken: "opstage_reg_...",
  agent: {
    code: "ophub-a",
    name: "External Agent A",
    mode: "ophub",
    runtime: "go",
  },
});

ServiceReportRequestSchema.parse({
  services: [
    {
      code: "svc-one",
      name: "Service One",
      version: "0.3.0",
      runtime: "nodejs",
      manifest: {
        kind: "CapsuleService",
        code: "svc-one",
        name: "Service One",
        version: "0.3.0",
        runtime: "nodejs",
        agentMode: "ophub",
        capabilities: [{ name: "inventory.read", label: "Inventory read" }],
        events: [{ name: "inventory.changed", direction: "publish", designOnly: true }],
      },
    },
  ],
});

Capability metadata is implemented as declarative service metadata. Event metadata is intentionally a foundation for future legacy event routing work; designOnly events must not be treated as a working event bus.

Validate Service Report

import { ServiceReportRequestSchema } from "@xtrape/capsule-contracts-node";

const report = ServiceReportRequestSchema.parse({
  services: [
    {
      code: "hello-capsule",
      name: "Hello Capsule",
      version: "0.1.0",
      runtime: "nodejs",
      manifest: {
        kind: "CapsuleService",
        schemaVersion: "1.0",
        code: "hello-capsule",
        name: "Hello Capsule",
        version: "0.1.0",
        runtime: "nodejs",
        agentMode: "embedded",
      },
    },
  ],
});

Validate Health Report

import { HealthReportInputSchema } from "@xtrape/capsule-contracts-node";

const health = HealthReportInputSchema.parse({
  status: "UP",
  message: "ok",
  details: { uptimeSeconds: 123 },
});

Allowed health statuses are:

import { HealthStatus } from "@xtrape/capsule-contracts-node";

console.log(HealthStatus); // ["UP", "DEGRADED", "DOWN", "UNKNOWN"]

HealthStatus is the protocol-level status reported by Agents and Capsule Services:

  • UP
  • DEGRADED
  • DOWN
  • UNKNOWN

Xtrape Panel may derive an operator-facing effectiveStatus such as:

  • HEALTHY
  • UNHEALTHY
  • STALE
  • OFFLINE

Validate Config and Action Definitions

import {
  ConfigItemInputSchema,
  ActionDefinitionInputSchema,
} from "@xtrape/capsule-contracts-node";

const config = ConfigItemInputSchema.parse({
  key: "UPSTREAM_BASE_URL",
  type: "string",
  sensitive: false,
  valuePreview: "https://api.example.test",
});

const action = ActionDefinitionInputSchema.parse({
  name: "reload-cache",
  label: "Reload Cache",
  dangerLevel: "MEDIUM",
  requiresConfirmation: true,
});

Validate Action Prepare Result

Use ActionPrepareResultSchema to validate the action-prepare payload directly:

import { ActionPrepareResultSchema } from "@xtrape/capsule-contracts-node";

const prepare = ActionPrepareResultSchema.parse({
  initialPayload: { message: "hello" },
  currentState: { service: "ready" },
  inputSchema: {
    type: "object",
    properties: {
      message: { type: "string", default: "hello" },
    },
  },
});

When reported back to Xtrape Panel for an ACTION_PREPARE command, this shape is placed under ReportCommandResultRequest.data. Command result reporting still uses ReportCommandResultRequestSchema:

import { ReportCommandResultRequestSchema } from "@xtrape/capsule-contracts-node";

const prepareResult = ReportCommandResultRequestSchema.parse({
  success: true,
  data: {
    action: { name: "echo", label: "Echo", dangerLevel: "LOW" },
    inputSchema: {
      type: "object",
      properties: { message: { type: "string", default: "hello" } },
    },
    initialPayload: { message: "hello" },
    currentState: { service: "ready" },
  },
});

Validate Command Result

import { ReportCommandResultRequestSchema } from "@xtrape/capsule-contracts-node";

const result = ReportCommandResultRequestSchema.parse({
  success: true,
  message: "Done",
  data: { count: 1 },
  startedAt: new Date().toISOString(),
  finishedAt: new Date().toISOString(),
});

Failed results should include an operator-safe message and structured error:

ReportCommandResultRequestSchema.parse({
  success: false,
  message: "Provider challenge page detected.",
  error: {
    code: "ACTION_FAILED",
    retryable: false,
  },
});

Error Codes

The ErrorCode export contains protocol-level error code constants currently used by CE and SDKs:

import { ErrorCode } from "@xtrape/capsule-contracts-node";

throw new Error(ErrorCode.VALIDATION_FAILED);

Currently exported codes include:

  • INTERNAL_ERROR
  • VALIDATION_FAILED
  • UNAUTHORIZED
  • FORBIDDEN
  • NOT_FOUND
  • CONFLICT
  • CAPSULE_SERVICE_CODE_TAKEN (persisted compatibility identifier for a Worker ownership conflict)
  • CSRF_INVALID
  • ACTION_REQUIRES_CONFIRMATION
  • COMMAND_EXPIRED
  • TOKEN_REVOKED
  • TOKEN_EXPIRED
  • AGENT_REVOKED
  • AGENT_DISABLED

See the OpenAPI contract and docs site for endpoint-specific errors.

ID generation

This package validates IDs at the wire boundary (via Zod) but does not mint them. Until v0.1.x there was a small newId() helper plus an idPrefixes table; both were removed in 0.2.0 to keep the contracts surface focused on the wire spec — see CHANGELOG.md and the "Breaking changes" section at the top of this README.

Consumers that need local ID generation should provide their own factory. Example using nanoid directly:

import { customAlphabet } from "nanoid";

const idBody = customAlphabet("0123456789abcdefghijklmnopqrstuvwxyz", 21);
const commandId = `cmd_${idBody()}`;

Documented ID prefixes in use across CE and the Agent SDK include wks_, usr_, agt_, tok_, svc_, hlr_, cfg_, act_, cmd_, crs_, and aud_. These are enforced by the Zod schemas via z.string().startsWith(...).

List Helpers

import {
  ListQueryBase,
  parseSort,
  paginate,
} from "@xtrape/capsule-contracts-node";

const query = ListQueryBase.parse({ page: "1", pageSize: "20" });
const sort = parseSort("-createdAt", ["createdAt", "name"]);
const response = paginate(items, query.page, query.pageSize, total);

Used By

  • xtrape-panel-ce — Xtrape Panel CE backend validation and protocol handling.
  • xtrape-agent-nodejs — Node embedded Agent SDK request/response types.
  • xtrape-demo — End-to-end runnable Worker that imports these schemas through the Agent SDK.
  • Worker implementations that want local validation before reporting to Xtrape Panel.

Compatibility

Package Compatible with
@xtrape/capsule-contracts-node@0.2.x Xtrape Panel CE 0.2.x and Agent SDK 0.2.x
@xtrape/capsule-contracts-node@0.1.x Xtrape Panel CE 0.1.x and Agent SDK 0.1.x

Pin matching minor versions across CE, Agent SDK, and Contracts. The wire protocol may still evolve before v1.0.

Breaking changes in 0.2.0

  • newId() removed. The helper minted random IDs with a prefix; it was never used by CE (entity IDs are minted in the backend). External consumers that imported newId must wire their own factory — see the ID generation section above.
  • idPrefixes constant and IdPrefix type removed. Same rationale.
  • nanoid runtime dependency removed as a consequence. Consumers that relied on a transitive nanoid install must now add it directly.

The wire schemas themselves are unchanged between 0.1.x and 0.2.x; existing 0.1.x agents continue to validate against a 0.2.x backend.

Schema Stability

The package follows semver. During the current pre-1.0 release-train phase, the guarantees per schema group are:

Group Stability Notes
Status enums (AgentStatus, CapsuleServiceStatus, HealthStatus, CommandStatus, DangerLevel, TokenStatus) Stable New values may be added in minor versions; existing values will not be removed before v1.0.
Agent Backend wire schemas (RegisterAgentRequest, AgentHeartbeat*, ServiceReport*, ReportCommandResult*) Evolving Field shape is stable; additive optional fields may land in minor versions. Required fields will not be added before v1.0 without a deprecation cycle.
Worker shapes (WorkerManifest, WorkerRuntimeReport, WorkerInstance, HealthReportInput, ConfigItemInput, ActionDefinitionInput) Evolving Legacy aliases retain the existing physical wire shapes.
Persisted shapes (Agent, CapsuleService, ConfigItem, ActionDefinition, Command*, AuditEvent, User) Evolving Track CE storage; safe to consume read-only.
ActionPrepareResultSchema Provisional Added in 0.1.0-public-review.0. Field shape may still tighten before v1.0.
Command.type enum Evolving Currently ACTION_PREPARE / ACTION_EXECUTE. New types may be added.
Error codes (ErrorCode) Evolving New codes may be added. Existing codes will not change meaning before v1.0.
Helpers (parseSort, paginate, HttpError, ListQueryBase) Provisional Helpful for backend-style consumers but not strictly part of the wire spec; may move to a separate utility package in a future minor. (newId / idPrefixes / IdPrefix were removed in 0.2.0 — see "Breaking changes in 0.2.0" above.)

Until v1.0, pin to a single minor across CE / Agent SDK / Contracts. Breaking changes will be called out in CHANGELOG.md.

Documentation

Contributing

See CONTRIBUTING.md for schema change workflow and PR checks. See SECURITY.md for vulnerability reporting and contract validation safety guidance.

License

Apache-2.0. "Xtrape" and "Opstage" are trademarks of their respective owners; the open-source license does not grant trademark rights.

v0.4 legacy event routing Experimental

v0.4 adds an experimental legacy event routing contract surface for CE's built-in SQLite-backed in-process event-to-command router. It is intentionally small, single-node, and disabled by default; it is not a standalone Bus Server, external broker (NATS / RabbitMQ / Redis Streams / Kafka), workflow DSL, or service mesh. No fan-out (maxCommandsPerEvent) in v0.4 — one matched route produces at most one ACTION_EXECUTE command.

Key exports:

  • BusEventEnvelopeSchema
  • PublishBusEventRequestSchema
  • PublishBusEventResponseSchema
  • BusRouteRuleSchema
  • CreateBusRouteRuleRequestSchema

Minimal event payload:

BusEventEnvelopeSchema.parse({
  eventType: "demo.item.created",
  sourceServiceCode: "demo-worker",
  payload: { itemId: "item-1" },
});

All schemas include or default experimental: "v0.4-experimental"; consumers should treat the wire surface as unstable until v1.0.

Keywords