npm package: @git-stunts/alfred-live
Description: In-memory control plane for Alfred: adaptive values, config registry, command router.
Author: James Ross
Latest version: 0.10.3

# @git-stunts/alfred-live

```text

      .o.       oooo   .o88o.                          .o8
     .888.      `888   888 `"                         "888
    .8"888.      888  o888oo  oooo d8b  .ooooo.   .oooo888
   .8' `888.     888   888    `888""8P d88' `88b d88' `888
  .88ooo8888.    888   888     888     888ooo888 888   888
 .8'     `888.   888   888     888     888    .o 888   888
o88o     o8888o o888o o888o   d888b    `Y8bod8P' `Y8bod88P"

       ,gggg,      ,a8a,  ,ggg,         ,gg ,ggggggg,
      d8" "8I     ,8" "8,dP""Y8a       ,8P,dP""""""Y8b
      88  ,dP     d8   8bYb, `88       d8'd8'    a  Y8
   8888888P"      88   88 `"  88       88 88     "Y8P'
      88          88   88     88       88 `8baaaa
      88          Y8   8P     I8       8I,d8P""""
 ,aa,_88          `8, ,8'     `8,     ,8'd8"
dP" "88P     8888  "8,8"       Y8,   ,8P Y8,
Yb,_,d88b,,_ `8b,  ,d8b,        Yb,_,dP  `Yba,,_____,
 "Y8P"  "Y88888"Y88P" "Y8        "Y8P"     `"Y8888888

```

In-memory control plane for Alfred. This package provides live configuration primitives and a command router that work across Node, Bun, Deno, and browsers.

## Install

```bash
pnpm add @git-stunts/alfred-live
```

```bash
npx jsr add @git-stunts/alfred-live
```

## Roadmap

See the ecosystem roadmap at [ROADMAP.md](https://github.com/git-stunts/alfred/blob/main/ROADMAP.md).

## Quick Start

```javascript
import { Adaptive, ConfigRegistry, CommandRouter } from '@git-stunts/alfred-live';

const retryCount = new Adaptive(3);

const registry = new ConfigRegistry();
registry.register('retry/count', retryCount, {
  parse: (value) => {
    const parsed = Number(value);
    if (!Number.isFinite(parsed)) {
      throw new Error('retry/count must be a number');
    }
    return parsed;
  },
  format: (value) => value.toString(),
});

const router = new CommandRouter(registry);

router.execute({ type: 'read_config', path: 'retry/count' });
router.execute({ type: 'write_config', path: 'retry/count', value: '5' });
router.execute({ type: 'list_config', prefix: 'retry' });
```

## Command Channel (JSONL)

Alfred Live exposes a canonical JSONL envelope for sending commands over
stdin/stdout. Use the helper functions to decode, validate, and execute.

```javascript
import {
  CommandRouter,
  ConfigRegistry,
  executeCommandLine,
  decodeCommandEnvelope,
  encodeCommandEnvelope,
} from '@git-stunts/alfred-live';

const registry = new ConfigRegistry();
const router = new CommandRouter(registry);

const line = JSON.stringify({
  id: 'cmd-1',
  cmd: 'list_config',
  args: { prefix: 'retry' },
});

const decoded = decodeCommandEnvelope(line);
if (!decoded.ok) throw new Error(decoded.error.message);

const resultLine = executeCommandLine(router, line);
if (!resultLine.ok) throw new Error(resultLine.error.message);
console.log(resultLine.data);

const outgoing = encodeCommandEnvelope({
  id: 'cmd-2',
  cmd: 'read_config',
  args: { path: 'retry/count' },
});
if (outgoing.ok) console.log(outgoing.data);
```

## Audit + Auth Hooks

Attach audit and auth hooks when executing JSONL command lines. Audits record
attempt + result events, and auth runs before validation/execution.

```javascript
import {
  CommandRouter,
  ConfigRegistry,
  InMemoryAuditSink,
  opaqueTokenAuth,
  executeCommandLine,
} from '@git-stunts/alfred-live';

const registry = new ConfigRegistry();
const router = new CommandRouter(registry);

const audit = new InMemoryAuditSink();
const auth = opaqueTokenAuth(['secret-token']);

const line = JSON.stringify({
  id: 'cmd-1',
  cmd: 'list_config',
  args: { prefix: 'retry' },
  auth: 'secret-token',
});

const resultLine = executeCommandLine(router, line, { audit, auth });
console.log(resultLine.data);
console.log(audit.entries());
```

Pass `{ includeRaw: true }` to `executeCommandLine()` if you want audit events to include raw payloads.

## CLI (`alfredctl`)

`alfredctl` emits JSONL commands to stdout. Pipe its output into your control
plane transport (stdin/stdout, ssh, etc.).

```bash
alfredctl list retry
alfredctl read retry/count
alfredctl write retry/count 5
```

## Live Policies

Live policies are described with a `LivePolicyPlan` and then bound to a registry
via a `ControlPlane`. Binding creates the config entries and returns an executable
policy stack.

```javascript
import { ConfigRegistry, ControlPlane, LivePolicyPlan } from '@git-stunts/alfred-live';
import { Policy } from '@git-stunts/alfred';

const registry = new ConfigRegistry();
const controlPlane = new ControlPlane(registry);

const livePlan = LivePolicyPlan.timeout('timeout', 5_000)
  .wrap(
    LivePolicyPlan.retry('retry', {
      retries: 3,
      delay: 150,
      maxDelay: 3_000,
      backoff: 'exponential',
      jitter: 'decorrelated',
    })
  )
  .wrap(
    LivePolicyPlan.static(
      Policy.circuitBreaker({
        threshold: 5,
        duration: 60_000,
      })
    )
  )
  .wrap(LivePolicyPlan.bulkhead('bulkhead', { limit: 10, queueLimit: 50 }));

const result = controlPlane.registerLivePolicy(livePlan, 'gateway/api');
if (!result.ok) throw new Error(result.error.message);

const { policy } = result.data;

const execution = await policy.execute(() => fetch('https://api.example.com'));
if (!execution.ok) throw new Error(execution.error.message);

// Live update, no redeploy.
registry.write('gateway/api/retry/retries', '5');
```

## Path Semantics

- Paths are relative, slash-delimited (`bulkhead/api`).
- Prefix matching uses path semantics.
- Exact prefix: `bulkhead` matches `bulkhead` and `bulkhead/api`.
- Child-only wildcard: `bulkhead/*` matches children only (e.g. `bulkhead/api`), not `bulkhead` itself.
- Glob-style prefix: `bulkhead*` matches `bulkhead` and `bulkhead2`.

## Examples

- `alfred-live/examples/control-plane/basic.js` — in-process registry + command router usage.
- `alfred-live/examples/control-plane/jsonl-channel.js` — JSONL command envelope execution.
- `alfred-live/examples/control-plane/live-policies.js` — live policy wrappers driven by registry state.

## Status

v0.10.2 control plane primitives implemented:

- `Adaptive<T>` live values with version + updatedAt.
- `ConfigRegistry` for typed config and validation.
- Command router for `read_config`, `write_config`, `list_config`.
- `LivePolicyPlan` + `ControlPlane.registerLivePolicy` for live policy stacks.
- Canonical JSONL command envelope + helpers.
- `alfredctl` CLI for emitting JSONL commands.
- Audit-first command pipeline + auth hooks.