@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:
Unique identifier with format el-{hash} or el-{hash}.{child}
One of: task, entity, document, plan, workflow, channel, message, team, library, playbook
Entity that created this element
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
Plan
Workflow
Channel
Team
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 ;
}
Multi-step process with triggers. interface Workflow extends Element {
type : 'workflow' ;
title : string ;
status : WorkflowStatus ; // 'pending' | 'running' | 'completed' | 'failed'
playbookId ?: PlaybookId ;
ephemeral : boolean ;
maxAgeSeconds ?: number ;
}
Communication channel (direct or group). interface Channel extends Element {
type : 'channel' ;
name : string ;
channelType : 'direct' | 'group' ;
members : EntityId [];
visibility : 'public' | 'private' ;
}
Named group of entities with roles. interface Team extends Element {
type : 'team' ;
name : string ;
members : EntityId [];
status : TeamStatus ; // 'active' | 'archived' | 'deleted'
}
ID System
Collision-resistant, hierarchical, human-readable IDs.
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
Root ID
Child ID
Custom Hash
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
ValidationError
NotFoundError
ConflictError
ConstraintError
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
Resource does not exist. import { notFound , entityNotFound } from '@stoneforge/core/errors' ;
throw notFound ( 'task' , taskId );
throw entityNotFound ( entityId );
Resource already exists or state conflict. import { alreadyExists , cycleDetected } from '@stoneforge/core/errors' ;
throw alreadyExists ( 'entity' , 'name' , 'alice' );
throw cycleDetected ( 'dependency' , [ idA , idB ]);
Business rule violation. import { immutable , hasDependents } from '@stoneforge/core/errors' ;
throw immutable ( 'status' , 'Task is closed' );
throw hasDependents ( 'plan' , planId , 3 );
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.
Parse Mentions
Check Mentions
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
Main
Types Only
Errors
ID System
Utils
import * from '@stoneforge/core' ;
// Everything (types, errors, id, utils)
import type { Task , Entity , Document } from '@stoneforge/core/types' ;
// Type definitions only (zero runtime)
import { ValidationError , notFound , invalidInput } from '@stoneforge/core/errors' ;
// Error classes and factory functions
import { generateId , parseId , isValidIdFormat } from '@stoneforge/core/id' ;
// ID generation, parsing, validation
import { parseMentions , hasMentions } from '@stoneforge/core/utils' ;
// Utility functions
API Reference
ID Functions
Function Signature Description 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
Function Type isElement(value: unknown) => value is ElementisTask(value: unknown) => value is TaskisEntity(value: unknown) => value is EntityisDocument(value: unknown) => value is DocumentisPlan(value: unknown) => value is PlanisWorkflow(value: unknown) => value is WorkflowisChannel(value: unknown) => value is ChannelisMessage(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