open-index/open-npm huggingface dataset:
npm package: @loop-engine/actors
Description: Actor types, constraints, and evidence helpers for Loop Engine transitions
Latest version: 0.1.5
Deprecated: Merged into @loop-engine/sdk

# @loop-engine/actors

[![npm](https://img.shields.io/npm/v/@loop-engine/actors.svg)](https://www.npmjs.com/package/@loop-engine/actors)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Actor types, authorization logic, and AI evidence helpers for Loop Engine transitions.

## Install

```bash
npm install @loop-engine/actors
```

## Quick Start

```ts
import { isAuthorized, buildAIActorEvidence } from "@loop-engine/actors";

const authorized = isAuthorized(
  { type: "human", id: "manager@acme.com" as never },
  { transitionId: "approve" as never, from: "pending" as never, to: "approved" as never, signal: "approve" as never, allowedActors: ["human"] }
);

const evidence = await buildAIActorEvidence({
  modelId: "gpt-4o",
  provider: "openai",
  reasoning: "Demand exceeds reorder point",
  confidence: 0.88,
  prompt: "Recommend replenishment action."
});
```

## Documentation link

https://loopengine.io/docs/packages/actors

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-anthropic
Description: Anthropic adapter for creating Loop Engine AI actor submissions
Author: Better Data, Inc.
Latest version: 0.1.6

# @loop-engine/adapter-anthropic

[![npm](https://img.shields.io/npm/v/@loop-engine/adapter-anthropic.svg)](https://www.npmjs.com/package/@loop-engine/adapter-anthropic)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Anthropic Claude adapter for Loop Engine - use Claude as a governed AI actor with confidence and evidence capture.

## Install

```bash
npm install @loop-engine/adapter-anthropic @anthropic-ai/sdk
```

## Quick Start

```ts
import { createAnthropicActorAdapter } from "@loop-engine/adapter-anthropic";

const adapter = createAnthropicActorAdapter({
  apiKey: process.env.ANTHROPIC_API_KEY!,
  model: "claude-3-5-sonnet-latest"
});

const submission = await adapter.createSubmission({
  signal: "submit_recommendation" as never,
  actorId: "agent:claude" as never,
  prompt: "Analyze demand and recommend PO action"
});
```

## Documentation link

https://loopengine.io/docs/integrations/anthropic

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-commerce-gateway
Description: LLM Commerce Gateway adapter for Loop Engine — AI procurement and pricing actors
Latest version: 0.1.5
Deprecated: Moved to @betterdata/adapter-commerce-gateway

# @loop-engine/adapter-commerce-gateway

`@loop-engine/adapter-commerce-gateway` provides a typed Commerce Gateway client and actor factories that turn live commerce data into governed Loop Engine evidence.

## Install

```bash
npm install @loop-engine/adapter-commerce-gateway
```

Install only the LLM SDK you use:

```bash
npm install @anthropic-ai/sdk
# or
npm install openai
```

## Environment

- `COMMERCE_GATEWAY_URL`
- `COMMERCE_GATEWAY_API_KEY`

## Read/write boundary

- AI actors call **read** endpoints only (`getInventory`, `getDemandForecast`, `getSuppliers`, pricing reads).
- Write operations (`createPurchaseOrder`) run in automation flows after human approval has passed loop guards.

## Quick start

```ts
import { CommerceGatewayClient, buildProcurementActor } from "@loop-engine/adapter-commerce-gateway";

const client = new CommerceGatewayClient({
  baseUrl: process.env.COMMERCE_GATEWAY_URL!,
  apiKey: process.env.COMMERCE_GATEWAY_API_KEY!
});

const actor = buildProcurementActor({
  gatewayClient: client,
  llmProvider: "claude",
  apiKey: process.env.ANTHROPIC_API_KEY!,
  confidenceThreshold: 0.8
});
```

## API surface

- `CommerceGatewayClient`
  - `getInventory(sku)`
  - `getInventoryBatch(skus)`
  - `getDemandForecast(sku, horizon?)`
  - `getSuppliers(sku)`
  - `getCurrentPrice(sku)`
  - `getPriceHistory(sku, days)`
  - `createPurchaseOrder(order)`
  - `recordLoopOutcome(outcome)` (optional endpoint support by deployment)
- `buildProcurementActor(options)`
- `buildPricingActor(options)` (throws: coming in v0.2)
- `buildProcurementEvidence(cgData, llmRecommendation, requestIds)`
- `toLoopOutcomeEvent(input)`
npm package: @loop-engine/adapter-gemini
Description: Loop Engine AI actor adapter for Google Gemini
Author: Better Data, Inc.
Latest version: 0.1.6

# @loop-engine/adapter-gemini

[![npm](https://img.shields.io/npm/v/@loop-engine/adapter-gemini.svg)](https://www.npmjs.com/package/@loop-engine/adapter-gemini)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Google Gemini adapter for Loop Engine - use Gemini models as governed AI actors.

## Install

```bash
npm install @loop-engine/adapter-gemini @google/generative-ai
```

## Quick Start

```ts
import { createGeminiActorAdapter } from "@loop-engine/adapter-gemini";

const adapter = createGeminiActorAdapter(process.env.GOOGLE_AI_API_KEY!, {
  modelId: "gemini-1.5-pro",
  confidenceThreshold: 0.75
});

const { actor, decision } = await adapter.createSubmission({
  loopId: "procurement",
  loopName: "SCM Procurement",
  currentState: "pending_analysis",
  availableSignals: [{ signalId: "submit_recommendation", name: "Submit Recommendation" }],
  instruction: "Analyze demand and recommend action"
});
```

## Documentation link

https://loopengine.io/docs/integrations/gemini

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-grok
Description: Loop Engine AI actor adapter for Grok (xAI); openai SDK included as compatibility shim for xAI endpoint — see README
Author: Better Data, Inc.
Latest version: 0.1.7

# @loop-engine/adapter-grok

[![npm](https://img.shields.io/npm/v/@loop-engine/adapter-grok.svg)](https://www.npmjs.com/package/@loop-engine/adapter-grok)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Grok (xAI) adapter for Loop Engine - use Grok as a governed AI actor via xAI's OpenAI-compatible API.

## Install

```bash
npm install @loop-engine/adapter-grok
```

This adapter uses `openai` as a compatibility shim because the xAI Grok endpoint
is OpenAI API-compatible. No OpenAI credentials are used — set `XAI_API_KEY` only.

## Quick Start

```ts
import { createGrokActorAdapter } from "@loop-engine/adapter-grok";

const adapter = createGrokActorAdapter(process.env.XAI_API_KEY!, {
  modelId: "grok-3",
  confidenceThreshold: 0.75
});

const { actor, decision } = await adapter.createSubmission({
  loopId: "procurement",
  loopName: "SCM Procurement",
  currentState: "pending_analysis",
  availableSignals: [{ signalId: "submit_recommendation", name: "Submit Recommendation" }],
  instruction: "Analyze demand and recommend action"
});
```

## Documentation link

https://loopengine.io/docs/integrations/grok

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-http
Description: [![npm](https://img.shields.io/npm/v/@loop-engine/adapter-http.svg)](https://www.npmjs.com/package/@loop-engine/adapter-http) [![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![Loop Engine](https://img.shields.io/badge/
Latest version: 0.1.5

# @loop-engine/adapter-http

[![npm](https://img.shields.io/npm/v/@loop-engine/adapter-http.svg)](https://www.npmjs.com/package/@loop-engine/adapter-http)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Generic HTTP event adapter for Loop Engine - post loop events to REST/webhook endpoints.

## Install

```bash
npm install @loop-engine/adapter-http
```

## Quick Start

```ts
import { httpEventBus } from "@loop-engine/adapter-http";

const eventBus = httpEventBus({
  webhookUrl: "https://api.example.com/loop-events",
  headers: { Authorization: `Bearer ${process.env.API_TOKEN}` },
  retries: 3
});
```

## Documentation link

https://loopengine.io/docs/integrations/http

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-kafka
Description: [![npm](https://img.shields.io/npm/v/@loop-engine/adapter-kafka.svg)](https://www.npmjs.com/package/@loop-engine/adapter-kafka) [![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![Loop Engine](https://img.shields.io/badg
Latest version: 0.1.5

# @loop-engine/adapter-kafka

[![npm](https://img.shields.io/npm/v/@loop-engine/adapter-kafka.svg)](https://www.npmjs.com/package/@loop-engine/adapter-kafka)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Kafka event adapter for Loop Engine - publish loop events to Kafka topics for streaming and analytics.

## Install

```bash
npm install @loop-engine/adapter-kafka kafkajs
```

## Quick Start

```ts
import { Kafka } from "kafkajs";
import { kafkaEventBus } from "@loop-engine/adapter-kafka";

const kafka = new Kafka({ clientId: "loop-engine", brokers: ["localhost:9092"] });
const eventBus = kafkaEventBus({
  kafka: { producer: () => kafka.producer(), consumer: () => kafka.consumer({ groupId: "loop-engine" }) } as never,
  topic: "loop-events"
});
```

## Documentation link

https://loopengine.io/docs/integrations/kafka

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-memory
Description: In-memory LoopStorageAdapter for local development and tests
Latest version: 0.1.5

# @loop-engine/adapter-memory

[![npm](https://img.shields.io/npm/v/@loop-engine/adapter-memory.svg)](https://www.npmjs.com/package/@loop-engine/adapter-memory)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

In-memory storage adapter for Loop Engine - zero configuration for development and tests.

## Install

```bash
npm install @loop-engine/adapter-memory @loop-engine/sdk
```

## Quick Start

```ts
import { createLoopSystem, GuardRegistry } from "@loop-engine/sdk";
import { MemoryLoopStorageAdapter } from "@loop-engine/adapter-memory";

const guards = new GuardRegistry();
guards.registerBuiltIns();

const { engine } = await createLoopSystem({
  loops: [loopDefinition],
  storage: new MemoryLoopStorageAdapter(),
  guards
});
```

## Documentation link

https://loopengine.io/docs/packages/adapter-memory

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-openai
Description: OpenAI adapter for creating Loop Engine AI actor submissions
Author: Better Data, Inc.
Latest version: 0.1.6

# @loop-engine/adapter-openai

[![npm](https://img.shields.io/npm/v/@loop-engine/adapter-openai.svg)](https://www.npmjs.com/package/@loop-engine/adapter-openai)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

OpenAI adapter for Loop Engine - use GPT models as governed AI actors.

## Install

```bash
npm install @loop-engine/adapter-openai openai
```

## Quick Start

```ts
import { createOpenAIActorAdapter } from "@loop-engine/adapter-openai";

const adapter = createOpenAIActorAdapter({
  apiKey: process.env.OPENAI_API_KEY!,
  model: "gpt-4o"
});

const submission = await adapter.createSubmission({
  signal: "submit_recommendation" as never,
  actorId: "agent:openai" as never,
  prompt: "Analyze inventory and recommend replenishment"
});
```

## Documentation link

https://loopengine.io/docs/integrations/openai

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-openclaw
Description: OpenClaw gateway EventBus adapter for Loop Engine
Author: Better Data, Inc.
Latest version: 0.1.7

# @loop-engine/adapter-openclaw

`@loop-engine/adapter-openclaw` forwards Loop Engine lifecycle events to an OpenClaw gateway over WebSocket while still emitting events on a local bus.

## Install

```bash
npm install @loop-engine/adapter-openclaw ws
```

## Connection strategy

The adapter connects to the OpenClaw gateway WebSocket at `ws://127.0.0.1:18789` by default.

### Scenario A — Local / self-hosted

Run the gateway as a local process alongside your Loop Engine runtime (standard dev and on-prem setup):

```ts
import { OpenClawEventBus } from "@loop-engine/adapter-openclaw";

const bus = new OpenClawEventBus({
  channel: "whatsapp",
  target: "+15551234567"
});
```

### Scenario B — Serverless / edge (Vercel, Cloudflare Workers, AWS Lambda)

A persistent WebSocket to a local gateway is not compatible with stateless serverless functions.

- Option 1: run this adapter in a long-lived sidecar/worker process (recommended).
- Option 2: use a hosted OpenClaw gateway URL and pass it to `gatewayUrl`.

> ⚠️ Do not instantiate `OpenClawEventBus` inside a Vercel serverless function.  
> The WebSocket connection will be dropped on function termination.  
> See [deployment guide](https://loopengine.io/docs/examples/openclaw) for the sidecar pattern.

## Required: channel and target

OpenClaw send delivery requires **both** `channel` and `target`.  
`channel` alone is insufficient and delivery can fail silently.

```ts
import { OpenClawEventBus } from "@loop-engine/adapter-openclaw";
import { InMemoryEventBus } from "@loop-engine/events";

const innerBus = new InMemoryEventBus();

const bus = new OpenClawEventBus(innerBus, {
  gatewayUrl: "ws://127.0.0.1:18789",
  channel: "whatsapp", // delivery channel
  target: "+1-555-000-0001", // recipient: phone, username, or room ID
  idempotencyKey: () => crypto.randomUUID()
});
```

Supported `channel` values and `target` semantics:

- `whatsapp` -> E.164 phone number
- `telegram` -> chat ID or `@username`
- `slack` -> channel ID or user ID
- `discord` -> channel ID

## Prerequisites

- OpenClaw gateway reachable at `ws://127.0.0.1:18789` (or custom URL)
- A configured destination `channel` and recipient `target` supported by OpenClaw

## Usage

```ts
import { createLoopSystem } from "@loop-engine/sdk";
import { OpenClawEventBus } from "@loop-engine/adapter-openclaw";

const eventBus = new OpenClawEventBus({
  channel: "whatsapp",
  target: "+15551234567",
  events: ["loop.transition.executed", "loop.completed", "loop.guard.failed"],
  approvalStates: ["PENDING_BUYER_APPROVAL"]
});

const system = await createLoopSystem({ loops: [/* loop definitions */], eventBus });
```

## Approval detection

By default, transitions to states matching `PENDING` or `APPROVAL` trigger an approval request message. Set `approvalStates` to override this with explicit state names.

## Cleanup

Call `disconnect()` on shutdown to clear reconnect timers and close the socket cleanly.
npm package: @loop-engine/adapter-pagerduty
Description: Route Loop Engine approval-required states to PagerDuty incidents
Latest version: 0.1.5

# @loop-engine/adapter-pagerduty

`@loop-engine/adapter-pagerduty` sends Loop Engine approval-required actions to PagerDuty as Events API v2 incidents.

## Install

```bash
npm install @loop-engine/adapter-pagerduty
```

## Trigger an incident for approval

```ts
import { PagerDutyNotifier } from "@loop-engine/adapter-pagerduty";

const pagerduty = new PagerDutyNotifier({
  integrationKey: process.env.PAGERDUTY_INTEGRATION_KEY!,
  severity: "warning",
  serviceContext: "Loop Engine / Procurement Agent",
  approvalUrl: (loopId) => `https://app.betterdata.co/loops/${loopId}`
});

const dedupKey = await pagerduty.notify("loop_po_0017", {
  loopId: "loop_po_0017",
  loopName: "purchase-order",
  actor: { type: "ai-agent", id: "procurement-agent" as never },
  input: { vendor: "Acme Medical Devices", amount: 9200 },
  summary: "AI requested $9,200 PO to Acme Medical Devices"
});
```

## Resolve incident after decision

```ts
await pagerduty.resolve(dedupKey, "approved");
```

## Events API endpoint

This package posts directly to `https://events.pagerduty.com/v2/enqueue` with `trigger` and `resolve` events and a stable dedup key (`loop-engine-${loopId}`).
npm package: @loop-engine/adapter-postgres
Description: [![npm](https://img.shields.io/npm/v/@loop-engine/adapter-postgres.svg)](https://www.npmjs.com/package/@loop-engine/adapter-postgres) [![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE) [![Loop Engine](https://img.shields.i
Latest version: 0.1.5

# @loop-engine/adapter-postgres

[![npm](https://img.shields.io/npm/v/@loop-engine/adapter-postgres.svg)](https://www.npmjs.com/package/@loop-engine/adapter-postgres)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

PostgreSQL storage adapter for Loop Engine - persist loop state and transitions to Postgres.

## Install

```bash
npm install @loop-engine/adapter-postgres @loop-engine/sdk pg
```

## Quick Start

```ts
import { Pool } from "pg";
import { createLoopSystem } from "@loop-engine/sdk";
import { createSchema, postgresStore } from "@loop-engine/adapter-postgres";

const pool = new Pool({ connectionString: process.env.DATABASE_URL });
await createSchema(pool);

const { engine } = await createLoopSystem({
  loops: [loopDefinition],
  storage: postgresStore(pool)
});
```

## Documentation link

https://loopengine.io/docs/integrations/postgres

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/adapter-vercel-ai
Description: Govern Vercel AI SDK tool calls with Loop Engine approval gates and audit trails
Latest version: 0.1.5

# @loop-engine/adapter-vercel-ai

`@loop-engine/adapter-vercel-ai` wraps Vercel AI SDK tools with Loop Engine governance.

## Why this adapter

Vercel AI SDK tool calls execute as soon as the model selects a tool. This adapter inserts a structural loop so high-impact tool calls can require explicit human approval while preserving a complete transition audit trail.

## Install

```bash
npm install @loop-engine/adapter-vercel-ai ai
```

## Core API

```ts
wrapTool<TInput, TOutput>(
  tool: CoreTool<TInput, TOutput>,
  config: GovernedToolConfig<TInput>
): CoreTool<TInput, TOutput>
```

## Example

```ts
import { tool } from "ai";
import { wrapTool } from "@loop-engine/adapter-vercel-ai";
import { z } from "zod";

const submitPurchaseOrder = wrapTool(
  tool({
    description: "Submit a purchase order to the procurement system",
    parameters: z.object({
      vendor: z.string(),
      amount: z.number(),
      items: z.array(z.string())
    }),
    execute: async ({ vendor, amount, items }) => {
      return { orderId: "PO-0042", status: "submitted", vendor, amount, items };
    }
  }),
  {
    loopDefinition: purchaseOrderLoop,
    engine,
    requiresApproval: ({ amount }) => amount > 5000,
    onApprovalRequired: async (loopId, input) => {
      console.log(`Loop ${loopId} requires approval for $${input.amount} PO`);
    },
    actor: { type: "ai-agent", id: "procurement-agent" as never }
  }
);
```

Drop the wrapped tool into `streamText` or `useChat` without changing the rest of your tool routing.
npm package: @loop-engine/core
Description: Core domain model and schemas for Loop Engine
Latest version: 0.1.5
Deprecated: Merged into @loop-engine/sdk

# @loop-engine/core

[![npm](https://img.shields.io/npm/v/@loop-engine/core.svg)](https://www.npmjs.com/package/@loop-engine/core)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Branded ID types, Zod schemas, and core domain types for Loop Engine.

## Install

```bash
npm install @loop-engine/core
```

## Quick Start

```ts
import { LoopIdSchema, LoopDefinitionSchema } from "@loop-engine/core";

const loopId = LoopIdSchema.parse("expense.approval");

const parsed = LoopDefinitionSchema.parse({
  loopId,
  version: "1.0.0",
  name: "Expense Approval",
  description: "Simple approval loop",
  states: [{ stateId: "submitted", label: "Submitted" }, { stateId: "approved", label: "Approved", terminal: true }],
  initialState: "submitted",
  transitions: [{ transitionId: "approve", from: "submitted", to: "approved", signal: "approve", allowedActors: ["human"] }]
});
```

## Documentation link

https://loopengine.io/docs/packages/core

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/dsl
Description: YAML/JSON loop authoring, parsing, and validation
Latest version: 0.1.5
Deprecated: Merged into @loop-engine/sdk

# @loop-engine/dsl

[![npm](https://img.shields.io/npm/v/@loop-engine/dsl.svg)](https://www.npmjs.com/package/@loop-engine/dsl)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Parse, validate, and serialize Loop Engine loop definitions from YAML or TypeScript.

## Install

```bash
npm install @loop-engine/dsl
```

## Quick Start

```ts
import { parseLoopYaml, validateLoopDefinition } from "@loop-engine/dsl";

const definition = parseLoopYaml(`
loopId: expense.approval
version: "1.0.0"
name: Expense Approval
description: Demo
states: [{ stateId: submitted, label: Submitted }, { stateId: approved, label: Approved, terminal: true }]
initialState: submitted
transitions: [{ transitionId: approve, from: submitted, to: approved, signal: approve, allowedActors: [human] }]
`);

const result = validateLoopDefinition(definition);
console.log(result.valid, result.errors);
```

## Documentation link

https://loopengine.io/docs/packages/dsl

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/events
Description: Typed Loop Engine lifecycle event contracts and in-memory event bus
Latest version: 0.1.5
Deprecated: Merged into @loop-engine/sdk

# @loop-engine/events

[![npm](https://img.shields.io/npm/v/@loop-engine/events.svg)](https://www.npmjs.com/package/@loop-engine/events)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Typed event definitions and factory functions for Loop Engine runtime events.

## Install

```bash
npm install @loop-engine/events
```

## Quick Start

```ts
import { createLoopStartedEvent, createLoopTransitionExecutedEvent, type LoopEvent } from "@loop-engine/events";

const started = createLoopStartedEvent({
  loopId: "expense.approval" as never,
  aggregateId: "EXP-1" as never,
  initialState: "submitted" as never,
  actor: { type: "human", id: "manager@acme.com" as never },
  definition: { loopId: "expense.approval" as never, version: "1.0.0", name: "Expense Approval" }
});

const transitioned: LoopEvent = createLoopTransitionExecutedEvent({
  loopId: started.loopId,
  aggregateId: started.aggregateId,
  transitionId: "approve" as never,
  fromState: "submitted" as never,
  toState: "approved" as never,
  signal: "approve" as never,
  actor: started.actor
});
```

## Documentation link

https://loopengine.io/docs/packages/events

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/guards
Description: Deterministic policy guard registry and built-in guard evaluators
Latest version: 0.1.5
Deprecated: Merged into @loop-engine/sdk

# @loop-engine/guards

[![npm](https://img.shields.io/npm/v/@loop-engine/guards.svg)](https://www.npmjs.com/package/@loop-engine/guards)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Built-in guard implementations and guard evaluation pipeline for Loop Engine.

## Install

```bash
npm install @loop-engine/guards
```

## Quick Start

```ts
import { GuardRegistry, evaluateGuards } from "@loop-engine/guards";

const guards = new GuardRegistry();
guards.registerBuiltIns();

const summary = await evaluateGuards(
  [{ guardId: "human-only" as never, severity: "hard", evaluatedBy: "runtime", description: "Human only" }],
  { actor: { type: "human", id: "manager@acme.com" as never }, loopId: "expense.approval" as never, aggregateId: "EXP-1" as never, fromState: "pending" as never, toState: "approved" as never, signal: "approve" as never },
  guards
);
```

## Documentation link

https://loopengine.io/docs/packages/guards

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/observability
Description: Metrics, timelines, and replay utilities for Loop Engine execution traces
Latest version: 0.1.5

# @loop-engine/observability

[![npm](https://img.shields.io/npm/v/@loop-engine/observability.svg)](https://www.npmjs.com/package/@loop-engine/observability)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Loop timeline reconstruction, replay validation, and observability helpers for Loop Engine.

## Install

```bash
npm install @loop-engine/observability
```

## Quick Start

```ts
import { buildTimeline, replayLoop } from "@loop-engine/observability";

const timeline = buildTimeline(instance, history);
const replay = replayLoop(definition, history);

console.log({
  aggregateId: timeline.aggregateId,
  durationMs: timeline.durationMs,
  transitions: timeline.transitions.length,
  replayValid: replay.valid
});
```

## Documentation link

https://loopengine.io/docs/packages/observability

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/registry-client
Description: Registry discovery client for loop definition catalogs.
Latest version: 0.1.7

# @loop-engine/registry-client

Loop definition registry with local, HTTP, and Better Data adapters.

## Install

```bash
npm install @loop-engine/registry-client
```

## The default: local registry

For most use cases, pass your loop definitions directly to `createLoopSystem`:

```ts
import { createLoopSystem } from "@loop-engine/sdk";
import { procurement, replenishment } from "./loops";

const { engine } = await createLoopSystem({
  loops: [procurement, replenishment]
});
```

No registry needed. No external dependency. Works offline.

## Loading from a directory

```ts
import { localRegistry } from "@loop-engine/registry-client";
import { createLoopSystem } from "@loop-engine/sdk";

const { engine } = await createLoopSystem({
  loops: [],
  registry: localRegistry({ loopsDir: "./loops" })
});
```

Loop YAML files in `./loops/` are parsed and registered automatically.
Works in Node.js only. In browser, use the `definitions[]` array.

## Loading YAML from disk + inline definitions

```ts
import { localRegistry } from "@loop-engine/registry-client";

const registry = localRegistry({
  loopsDir: "./loops",
  definitions: [customLoop]
});
```

Inline definitions are applied after directory load and override matching loop IDs.
When IDs conflict, inline definitions take precedence over directory-loaded definitions.

## HTTP registry (any server)

```ts
import { httpRegistry } from "@loop-engine/registry-client";

const registry = httpRegistry({
  baseUrl: "https://your-registry.example.com",
  headers: { Authorization: `Bearer ${token}` }
});
```

The server must implement the REST contract (see `docs/http-api.md`).

## Running a local registry server

To run the reference server locally:

```bash
cd packages/registry-client
npx ts-node examples/server.ts
```

Then point `httpRegistry` at it:

```ts
const registry = httpRegistry({ baseUrl: "http://localhost:3001" });
```

The reference server stores definitions in memory.
Replace the Map-based storage with a database for production.

## Better Data platform registry

```ts
import { betterDataRegistry } from "@loop-engine/registry-client/betterdata";

const registry = betterDataRegistry({
  apiKey: process.env.BD_API_KEY!,
  orgId: "your-org-id"
});
```

Requires a Better Data platform account.
See [betterdata.co/docs/loop-registry](https://betterdata.co/docs/loop-registry) for setup instructions.

## LoopRegistry interface

All adapters implement this interface. You can build your own:

```ts
import type { LoopRegistry } from "@loop-engine/registry-client";

const myRegistry: LoopRegistry = {
  get: async (id) => {
    return null;
  },
  getVersion: async (id, version) => {
    return null;
  },
  list: async (options) => {
    return [];
  },
  has: async (id) => {
    return false;
  },
  register: async (definition, options) => {},
  remove: async (id) => {
    return false;
  }
};
```
npm package: @loop-engine/runtime
Description: Loop Engine runtime for state transitions, guard evaluation, and event emission
Latest version: 0.1.5

# @loop-engine/runtime

[![npm](https://img.shields.io/npm/v/@loop-engine/runtime.svg)](https://www.npmjs.com/package/@loop-engine/runtime)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

The Loop Engine runtime for governed loop lifecycle, transition execution, and event emission.

## Install

```bash
npm install @loop-engine/runtime @loop-engine/adapter-memory @loop-engine/guards
```

## Quick Start

```ts
import { createLoopSystem } from "@loop-engine/runtime";
import { createMemoryLoopStorageAdapter } from "@loop-engine/adapter-memory";
import { GuardRegistry } from "@loop-engine/guards";

const guardRegistry = new GuardRegistry();
guardRegistry.registerBuiltIns();
const registry = { get: () => loopDefinition, list: () => [loopDefinition] };
const system = createLoopSystem({ registry, storage: createMemoryLoopStorageAdapter(), guardRegistry });

await system.startLoop({ loopId: "expense.approval" as never, aggregateId: "EXP-1" as never, actor: { type: "human", id: "manager@acme.com" as never } });
await system.transition({ aggregateId: "EXP-1" as never, transitionId: "approve" as never, actor: { type: "human", id: "manager@acme.com" as never } });
```

## Documentation link

https://loopengine.io/docs/packages/runtime

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/sdk
Description: Primary Loop Engine entrypoint combining runtime, DSL, guards, signals, and adapters
Latest version: 0.1.7

# @loop-engine/sdk

[![npm](https://img.shields.io/npm/v/@loop-engine/sdk.svg)](https://www.npmjs.com/package/@loop-engine/sdk)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

The main Loop Engine SDK - runtime, DSL, guards, signals, events, and adapters in one import.

## Install

```bash
npm install @loop-engine/sdk
```

## Quick Start

```ts
import { createLoopSystem, parseLoopYaml } from "@loop-engine/sdk";

const loop = parseLoopYaml(`
loopId: expense.approval
version: "1.0.0"
name: Expense Approval
description: Demo
states: [{ stateId: submitted, label: Submitted }, { stateId: approved, label: Approved, terminal: true }]
initialState: submitted
transitions: [{ transitionId: approve, from: submitted, to: approved, signal: approve, allowedActors: [human] }]
`);

const { engine } = await createLoopSystem({ loops: [loop] });
await engine.startLoop({ loopId: "expense.approval" as never, aggregateId: "EXP-1" as never, actor: { type: "human", id: "manager@acme.com" as never } });
await engine.transition({ aggregateId: "EXP-1" as never, transitionId: "approve" as never, actor: { type: "human", id: "manager@acme.com" as never } });
```

## Documentation link

https://loopengine.io/docs/packages/sdk

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/signals
Description: Signal detection rules and signal engine for proactive loop triggers
Latest version: 0.1.5
Deprecated: Merged into @loop-engine/sdk

# @loop-engine/signals

[![npm](https://img.shields.io/npm/v/@loop-engine/signals.svg)](https://www.npmjs.com/package/@loop-engine/signals)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

Signal schemas and registry utilities for validating Loop Engine signal payloads.

## Install

```bash
npm install @loop-engine/signals
```

## Quick Start

```ts
import { z } from "zod";
import { SignalRegistry } from "@loop-engine/signals";

const registry = new SignalRegistry();
registry.register({
  signalId: "submit_recommendation" as never,
  name: "Submit Recommendation",
  schema: z.object({ sku: z.string(), demandChange: z.number() })
});

const ok = registry.validatePayload("submit_recommendation" as never, { sku: "SKU-1", demandChange: 0.82 });
```

## Documentation link

https://loopengine.io/docs/packages/signals

## License

Apache-2.0 © Better Data, Inc.
npm package: @loop-engine/ui-devtools
Description: React devtools components for inspecting Loop Engine state, events, and metrics
Latest version: 0.1.5

# @loop-engine/ui-devtools

[![npm](https://img.shields.io/npm/v/@loop-engine/ui-devtools.svg)](https://www.npmjs.com/package/@loop-engine/ui-devtools)
[![Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](LICENSE)
[![Loop Engine](https://img.shields.io/badge/loopengine.io-docs-blue)](https://loopengine.io/docs)

React developer tools for visualizing Loop Engine state, transitions, and events during development.

## Install

```bash
npm install @loop-engine/ui-devtools react react-dom
```

## Quick Start

```tsx
import { DevtoolsPanel } from "@loop-engine/ui-devtools";

export function App() {
  return (
    <>
      <main>My Loop Engine app</main>
      <DevtoolsPanel apiUrl="http://localhost:3000/api" />
    </>
  );
}
```

## Documentation link

https://loopengine.io/docs/packages/ui-devtools

## License

Apache-2.0 © Better Data, Inc.