Skip to content

API Documentation

LumenFlow provides TypeScript API documentation generated from source code using TypeDoc.

@lumenflow/core

WU lifecycle, state machine, validators, configuration

@lumenflow/cli

Command implementations, argument parsing

@lumenflow/packs-software-delivery

WU lifecycle, initiatives, delivery metrics, and workflow memory

@lumenflow/agent

Skill loading, agent definitions, verification

WU lifecycle operations are implemented as CLI commands, not as an importable @lumenflow/core function API:

pnpm wu:create --id WU-042 --title "Add email validation" --lane "Framework: Core"
pnpm wu:claim --id WU-042 --lane "Framework: Core"
pnpm wu:done --id WU-042
import { assertTransition } from '@lumenflow/core';

// Throws if the transition is illegal; returns void if it is valid.
assertTransition('ready', 'in_progress', 'WU-042');
import { getConfig, validateConfigFile } from '@lumenflow/core';

// Load resolved config (workspace.yaml's software_delivery block + schema defaults)
const config = getConfig({ projectRoot: '/path/to/repository' });

// Validate a config file directly
const { valid, errors } = validateConfigFile('/path/to/workspace.yaml');
if (!valid) {
  console.error('Config issues:', errors);
}

getRepoPlansDir, getRepoPlanPath, normalizeSpecRef, validateSpecRefs, and normalizeSpecRefs now require an explicit workspace root. This is a source-breaking public API change and is classified for the next major release. Passing the root prevents plan lookup and validation from silently following an unrelated process working directory.

Before:

import { normalizeSpecRef } from '@lumenflow/core/lumenflow-home';
import { validateSpecRefs } from '@lumenflow/core/wu-create-validators';

const planPath = normalizeSpecRef('lumenflow://plans/WU-042-plan.md');
const validation = validateSpecRefs(['lumenflow://plans/WU-042-plan.md']);

After:

import { normalizeSpecRef } from '@lumenflow/core/lumenflow-home';
import { validateSpecRefs } from '@lumenflow/core/wu-create-validators';

const workspaceRoot = '/path/to/repository';
const planPath = normalizeSpecRef('lumenflow://plans/WU-042-plan.md', workspaceRoot);
const validation = validateSpecRefs(['lumenflow://plans/WU-042-plan.md'], workspaceRoot);

The asynchronous delegation registry discovery API remains backward compatible: resolveCanonicalDelegationRegistryDir() can still be called without an argument. Code that already knows its checkout should continue to pass that directory explicitly.

import { syncNdjsonTelemetryToCloud } from '@lumenflow/core/telemetry';
import { emitCostEvent } from '@lumenflow/packs-software-delivery';
import type { CostEvent, CostSummary } from '@lumenflow/packs-software-delivery/metrics';

const event: CostEvent = {
  timestamp: new Date().toISOString(),
  sourceType: 'cost',
  operation: 'llm.classification',
  model: 'gpt-4o-mini',
  inputTokens: 1200,
  outputTokens: 320,
  costUsd: 0.0421,
  wuId: 'WU-101',
  agentId: 'agent-1',
  sessionId: 'session-abc',
};

emitCostEvent({
  timestamp: event.timestamp,
  operation: event.operation,
  model: event.model,
  input_tokens: event.inputTokens,
  output_tokens: event.outputTokens,
  cost_usd: event.costUsd,
  wu_id: event.wuId,
  agent_id: event.agentId,
  session_id: event.sessionId,
});

// Later: include costs.ndjson alongside other telemetry sources in cloud sync
await syncNdjsonTelemetryToCloud();

Local operator summary command:

pnpm cost:summary
pnpm cost:summary --json
import type { HeartbeatInput, HeartbeatResult } from '@lumenflow/control-plane-sdk';

const heartbeatRequest: HeartbeatInput = {
  workspace_id: 'workspace-a',
  session_id: 'session-a',
  agent_id: 'agent-1',
  wu_id: 'WU-102',
  health: {
    busy: false,
    stalled: false,
    last_progress_at: new Date().toISOString(),
  },
};

const heartbeatResponse: HeartbeatResult = {
  status: 'ok',
  server_time: new Date().toISOString(),
  next_heartbeat_ms: 30000,
  assignment: {
    wu_id: 'WU-102',
    action: 'continue',
    hint: 'server-directed cadence',
  },
  budget_remaining_usd: 42.5,
  coalesced_signals: 2,
};
import type { RegisterSessionInput, SessionSummary } from '@lumenflow/control-plane-sdk';

const registerSessionInput: RegisterSessionInput = {
  workspace_id: 'workspace-a',
  session_id: 'session-a',
  agent_id: 'agent-1',
  started_at: new Date().toISOString(),
  lane: 'Framework: Core Lifecycle',
  wu_id: 'WU-103',
  client_type: 'claude-code',
  capabilities: ['session_lifecycle', 'heartbeat'],
  agent_version: '3.10.0',
  host_id: 'host-01',
  metadata: {
    client_type: 'claude-code',
    capabilities: ['session_lifecycle', 'heartbeat'],
    agent_version: '3.10.0',
    host_id: 'host-01',
  },
};

const sessionSummary: SessionSummary = {
  workspace_id: 'workspace-a',
  session_id: 'session-a',
  agent_id: 'agent-1',
  started_at: new Date().toISOString(),
  active: true,
  client_type: 'claude-code',
  capabilities: ['session_lifecycle', 'heartbeat'],
  agent_version: '3.10.0',
  host_id: 'host-01',
  metadata: {
    client_type: 'claude-code',
    capabilities: ['session_lifecycle', 'heartbeat'],
    agent_version: '3.10.0',
    host_id: 'host-01',
  },
};
import {
  resolveLocation,
  readGitState,
  readWuState,
  validateContext,
  LocationType,
} from '@lumenflow/core';

// Resolve current location
const location = await resolveLocation();
if (location.type === LocationType.WORKTREE) {
  console.log(`In worktree: ${location.worktreeName}`);
}

// Read git state
const gitState = await readGitState();
if (gitState.isDirty) {
  console.log('Uncommitted changes present');
}

// Full context validation
const result = await validateContext({
  command: 'wu:done',
  wuId: 'WU-042',
});
import { isAgentBranch, isAgentBranchWithDetails, resolveAgentPatterns } from '@lumenflow/core';

// Check if branch is an agent branch
const isAgent = await isAgentBranch('claude/session-12345');
// true

// Get detailed result
const result = await isAgentBranchWithDetails('claude/session-12345');
console.log(result.patternResult.source);
// 'registry' | 'merged' | 'override' | 'config' | 'defaults'

The Software Delivery pack is the canonical owner of delivery/workflow memory. The @lumenflow/memory package remains available as a deprecated compatibility shell, but new code should use the pack subpath below.

import { startSession, type StartSessionResult } from '@lumenflow/packs-software-delivery/memory';

const projectRoot = '/path/to/repository';
const result: StartSessionResult = await startSession(projectRoot, {
  wuId: 'WU-042',
  agentType: 'claude-code', // example; use your project's configured client
  contextTier: 'full',
});

console.log(result.session.id);
import { createCheckpoint } from '@lumenflow/packs-software-delivery/memory';

const result = await createCheckpoint('/path/to/repository', {
  wuId: 'WU-042',
  note: 'Tests passing, starting implementation',
  progress: 'Validation tests are green',
  nextSteps: 'Wire the validator into the form',
});

console.log(result.checkpoint.id);
import {
  createSignal,
  loadInboxSignalViews,
  type Signal,
} from '@lumenflow/packs-software-delivery/memory';

const projectRoot = '/path/to/repository';
const created = await createSignal(projectRoot, {
  wuId: 'WU-042',
  message: 'Implementation complete',
  type: 'progress',
  sender: 'codex:implementer',
});

const inbox = await loadInboxSignalViews(projectRoot, {
  wuId: 'WU-042',
  unreadOnly: true,
});

const signal: Signal = created.signal;
console.log(signal.id, inbox.length);

There is no loadSkill/listSkills/validateSkill API in @lumenflow/agent. Skill definitions are validated by validateSkillFile/validateAllSkills in @lumenflow/cli/src/validate-agent-skills.ts, an internal helper not currently exposed through the package’s public exports. Invoke it via the internal CLI entry point instead:

node tools/cli-entry.mjs validate-agent-skills
import { verifyWUComplete, type VerificationResult } from '@lumenflow/agent';

// Verify WU completion
const result: VerificationResult = verifyWUComplete('WU-042');
if (result.complete) {
  console.log('All acceptance criteria met');
} else {
  console.log('Failed:', result.failures);
}

The CLI package is primarily used via commands, but exports some utilities:

import { printHeader, createStatusTable } from '@lumenflow/cli';

// Print the LumenFlow CLI banner
printHeader({ version: '5.19.0' });

// Format a status table
const table = createStatusTable({
  head: ['ID', 'Status'],
  rows: [
    ['WU-042', 'done'],
    ['WU-043', 'ready'],
  ],
});
console.log(table);
interface WuSpec {
  id: string;
  title: string;
  lane: string;
  type: 'feature' | 'bug' | 'documentation' | 'refactor';
  status: WuStatus;
  priority: 'P0' | 'P1' | 'P2' | 'P3';
  description: string;
  acceptance: string[];
  code_paths: string[];
  test_paths?: {
    unit?: string[];
    integration?: string[];
    e2e?: string[];
  };
  dependencies?: string[];
  blocked_by?: string[];
  created: string;
  assigned_to?: string;
  notes?: string;
}
enum WuStatus {
  READY = 'ready',
  IN_PROGRESS = 'in_progress',
  BLOCKED = 'blocked',
  WAITING = 'waiting',
  DONE = 'done',
}
interface LocationContext {
  type: LocationType;
  cwd: string;
  gitRoot: string;
  mainCheckout: string;
  worktreeName: string | null;
  worktreeWuId: string | null;
}

enum LocationType {
  MAIN = 'main',
  WORKTREE = 'worktree',
  DETACHED = 'detached',
  UNKNOWN = 'unknown',
}
interface GitState {
  branch: string | null;
  isDetached: boolean;
  isDirty: boolean;
  hasStaged: boolean;
  ahead: number;
  behind: number;
  tracking: string | null;
  modifiedFiles: string[];
  hasError: boolean;
  errorMessage: string | null;
}

To generate TypeDoc documentation locally:

# Install TypeDoc (if not already)
pnpm add -D typedoc typedoc-plugin-markdown

# Generate docs
pnpm typedoc --out docs/api packages/@lumenflow/*/src/index.ts