Crux
API Reference@use-crux/core

Plan

Reference for the canonical plan primitive.

import { plan } from "@use-crux/core/plan";

import type {
  CreatePlanInput,
  JsonObject,
  JsonValue,
  Plan,
  PlanHandle,
  PlanUpdate,
} from "@use-crux/core/plan";

Overview

plan() creates a persistent intent document and returns a command handle. The handle contains the stable ID plus commands; it does not embed a stale Plan snapshot.

const roadmap = await plan({
  title: "Launch plan",
  content: "Research, draft, review, publish.",
  metadata: { threadId: "thread-123" },
});

Plans emit canonical plan.operation observability artifacts for creation and updates. Local devtools uses those artifacts for the Plans views.

plan(input)

Creates a plan.

const roadmap = await plan({
  title: "Cloud migration guide",
  content: "## Objective\nWrite the migration guide.",
});
interface CreatePlanInput {
  title: string;
  content?: string;
  metadata?: JsonObject;
}

Metadata must be JSON-safe.

plan.ref(planId)

Returns a handle for an existing plan without reading the store first.

const roadmap = plan.ref(planId);
const latest = await roadmap.get();

plan.list(options?)

Lists plans from the configured store.

const plans = await plan.list({
  metadata: { threadId: "thread-123" },
  limit: 20,
});
interface PlanListOptions {
  metadata?: Record<string, JsonValue>;
  limit?: number;
}

plan.tool(options?)

Creates a focused prompt tool that persists a new plan. After a model call, use created() to get the created handle.

const makePlan = plan.tool({
  template: "## Goal\n\n## Constraints\n\n## Steps",
  onCreated: (roadmap) => {
    console.log(roadmap.id);
  },
});

await generate(
  prompt({
    system: "Create a concise execution plan.",
    tools: { makePlan },
  }),
  { model, input: { request } },
);

const roadmap = makePlan.created();

created() throws CreationToolNotCreatedError if the tool did not create an entity.

PlanHandle

interface PlanHandle {
  readonly id: string;
  get(): Promise<Plan | null>;
  update(update: PlanUpdate): Promise<Plan>;
  asContext(options?: PlanContextOptions): Context;
  asTools(): Record<string, ToolDef>;
}

get()

Reads the latest plan.

const current = await roadmap.get();

update(update)

Updates title, content, or metadata. The version increments when title or content changes.

await roadmap.update({
  content: "Updated approach.",
});
interface PlanUpdate {
  title?: string;
  content?: string;
  metadata?: JsonObject;
}

asContext(options?)

Returns a Crux context that resolves the latest plan at prompt time.

prompt({
  use: [roadmap.asContext()],
});

Options:

interface PlanContextOptions {
  priority?: number;
  mode?: "full" | "reference";
  renderContext?: (plan: Plan) => string;
}

asTools()

Returns focused tools for reading and updating the bound plan.

const tools = roadmap.asTools();

prompt({
  tools: {
    getPlan: tools.getPlan,
    updatePlan: tools.updatePlan,
  },
});

Types

interface Plan {
  id: string;
  title: string;
  content: string;
  version: number;
  metadata?: JsonObject;
  createdAt: number;
  updatedAt: number;
}

On this page