Skip to main content

@stoneforge/core

The foundation layer for every Stoneforge package. Defines canonical types, structured error handling, collision-resistant ID generation, and utility functions.
No dependencies. This package has zero external dependencies (except yaml for playbook parsing) and can be used standalone.

Installation

npm install @stoneforge/core

Quick Start

import type { Task, Entity, Document } from '@stoneforge/core/types';

const task: Task = {
  id: 'el-abc123',
  type: 'task',
  title: 'Implement feature',
  status: 'open',
  priority: 2,
  createdBy: 'el-operator',
  createdAt: new Date().toISOString(),
  updatedAt: new Date().toISOString(),
  tags: ['backend'],
  metadata: {},
};

Core Types

Element (Base Type)

All stored objects inherit from Element:
id
ElementId
required
Unique identifier with format el-{hash} or el-{hash}.{child}
type
ElementType
required
One of: task, entity, document, plan, workflow, channel, message, team, library, playbook
createdBy
EntityId
required
Entity that created this element
createdAt
string
required
ISO 8601 timestamp
updatedAt
string
required
ISO 8601 timestamp
tags
string[]
default:"[]"
User-defined tags for categorization
metadata
Record<string, unknown>
default:"{}"
Arbitrary JSON-serializable metadata

Task

Work item with status, priority, and assignments.
import type { Task, TaskStatus, TaskType } from '@stoneforge/core';

interface Task extends Element {
  type: 'task';
  title: string;
  status: TaskStatus; // 'open' | 'in_progress' | 'blocked' | 'closed'
  priority: number;    // 0-4 (0=none, 4=critical)
  taskType?: TaskType; // 'feature' | 'bug' | 'chore' | 'docs'
  assignees?: EntityId[];
  estimate?: number;   // story points or hours
  startedAt?: string;
  completedAt?: string;
  dueDate?: string;
  closeReason?: string;
}

Entity

Actor in the system (human or agent).
import type { Entity, EntityRole } from '@stoneforge/core';

interface Entity extends Element {
  type: 'entity';
  name: string;
  role: EntityRole; // 'human' | 'director' | 'worker' | 'steward'
  email?: string;
  managerId?: EntityId;
  publicKey?: string; // Ed25519 public key for signature verification
}

Document

Versioned content with content type.
import type { Document, DocumentStatus } from '@stoneforge/core';

interface Document extends Element {
  type: 'document';
  title: string;
  content: string;
  contentType: string; // 'text/markdown', 'application/json', etc.
  version: number;
  status: DocumentStatus; // 'active' | 'archived' | 'deleted'
  category?: string;
  libraryId?: LibraryId;
}

Collection Types

Collection of related tasks with status tracking.
interface Plan extends Element {
  type: 'plan';
  title: string;
  status: PlanStatus; // 'draft' | 'active' | 'completed' | 'cancelled'
  targetDate?: string;
  completedAt?: string;
  cancelReason?: string;
}

ID System

Collision-resistant, hierarchical, human-readable IDs.

ID Format

  • Root IDs: el-{hash} (e.g., el-a1b2c3d4)
  • Child IDs: el-{hash}.{child} (e.g., el-a1b2c3d4.1.2)
Hash is derived from: identifier + createdBy + timestampNs + nonce

Generation

import { generateId } from '@stoneforge/core/id';

const id = await generateId({
  identifier: 'implement-auth',
  createdBy: 'el-operator',
});
// => 'el-a1b2c3d4'

Parsing & Validation

import { parseId } from '@stoneforge/core/id';

const { root, depth, hash, components, isRoot } = parseId('el-a1b2c3d4.1.2');
// {
//   root: 'el-a1b2c3d4',
//   depth: 2,
//   hash: 'a1b2c3d4',
//   components: ['a1b2c3d4', '1', '2'],
//   isRoot: false
// }

Error Handling

Structured error hierarchy with typed error codes.

Error Classes

Invalid input or constraint violation.
import { ValidationError, invalidInput } from '@stoneforge/core/errors';

throw invalidInput('title', 'Title must not be empty');
// ValidationError: Invalid input for field 'title': Title must not be empty

Factory Functions

notFound
(type: string, id: string) => NotFoundError
Generic not found error
entityNotFound
(id: EntityId) => NotFoundError
Entity-specific not found
invalidInput
(field: string, message: string) => ValidationError
Invalid field value
alreadyExists
(type: string, field: string, value: string) => ConflictError
Duplicate resource
cycleDetected
(type: string, cycle: string[]) => ConflictError
Circular dependency
immutable
(field: string, reason: string) => ConstraintError
Cannot modify field

Utilities

Mention Parsing

Extract @mentions from text.
import { parseMentions, extractMentionedNames } from '@stoneforge/core/utils';

const text = 'Assign to @alice and @bob';
const mentions = parseMentions(text);
// [{ name: 'alice', ... }, { name: 'bob', ... }]

const names = extractMentionedNames(text);
// ['alice', 'bob']

Entry Points

import * from '@stoneforge/core';
// Everything (types, errors, id, utils)

API Reference

ID Functions

FunctionSignatureDescription
generateId(input: GenerateIdInput) => Promise<ElementId>Generate a root ID
generateChildId(parentId: ElementId, childNumber: number) => ElementIdGenerate a child ID
generateIdHash(components: IdHashComponents) => Promise<string>Hash from components
parseId(id: ElementId) => ParsedIdExtract ID components
getIdRoot(id: ElementId) => ElementIdGet root segment
getIdParent(id: ElementId) => ElementId | nullGet parent ID
getIdDepth(id: ElementId) => numberGet nesting depth
isValidIdFormat(id: string) => booleanValidate ID format
isValidRootId(id: string) => booleanCheck if root-level

Type Guards

FunctionType
isElement(value: unknown) => value is Element
isTask(value: unknown) => value is Task
isEntity(value: unknown) => value is Entity
isDocument(value: unknown) => value is Document
isPlan(value: unknown) => value is Plan
isWorkflow(value: unknown) => value is Workflow
isChannel(value: unknown) => value is Channel
isMessage(value: unknown) => value is Message

Validators

All type guards have a corresponding validate* function that throws ValidationError on failure.
import { validateTask, validateEntity } from '@stoneforge/core';

validateTask(element);   // throws if not a valid Task
validateEntity(element); // throws if not a valid Entity
No Runtime Dependencies: This package has minimal dependencies and can be used in any JavaScript/TypeScript environment.

Next Steps

Storage Package

Learn how to persist data with SQLite

Quarry API

Use the main API to create and query elements

Build docs developers (and LLMs) love