npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bernierllc/work-item-core

v0.1.4

Published

Universal work item management with configurable types, statuses, maturity levels, dependency tracking, and hierarchical relationships

Readme

@bernierllc/work-item-core

A comprehensive TypeScript library for managing work items with hierarchical relationships, dependency tracking, maturity progression, and status management.

Installation

npm install @bernierllc/work-item-core

Features

  • Complete CRUD Operations - Create, read, update, delete work items
  • Hierarchical Relationships - Parent/child relationships with tree traversal
  • Dependency Management - Track dependencies with circular detection (DFS algorithm)
  • Blocking Detection - Identify blocking items using BFS-style traversal
  • Maturity Progression - State machine for work item maturity levels
  • Status Management - Track work item status through lifecycle
  • Assignment Management - Assign work items to team members or agents
  • Readiness Checks - Determine if work items are ready to start
  • Query & Filtering - Powerful filtering, sorting, and pagination
  • Batch Operations - Efficient bulk create and update operations
  • Statistics & Reporting - Comprehensive project analytics
  • Storage Abstraction - Pluggable storage backend (memory included for testing)

Quick Start

import { WorkItemManager, MemoryWorkItemStorage } from '@bernierllc/work-item-core';

// Initialize with in-memory storage
const storage = new MemoryWorkItemStorage();
const manager = new WorkItemManager(storage);

// Create a work item
const result = await manager.create({
  project_id: 'proj_123',
  title: 'Implement user authentication',
  work_type_id: 'type_feature',
  maturity_level_id: 'maturity_planned',
  status_id: 'status_open',
  priority: 8
});

if (result.success) {
  console.log('Created work item:', result.data);
}

Core Concepts

Work Item

A work item represents a unit of work in a project. Each work item has:

  • Identity: id, project_id, title, description
  • Classification: work_type_id (feature, bug, refactor, documentation, chore)
  • Maturity: maturity_level_id (idea → discovery → planned → ready → active → complete)
  • Status: status_id (open, blocked, in-progress, in-review, done, cancelled)
  • Priority: priority (1-10, higher = more important)
  • Relationships: parent_work_item_id, depends_on_work_item_ids
  • Assignment: assigned_to (team member or agent identifier)
  • Metadata: created_at, updated_at, created_from_session_id

Maturity Levels

Work items progress through maturity levels:

  1. idea - Initial concept
  2. discovery - Research and investigation
  3. planned - Defined and estimated
  4. ready - Ready to start work
  5. active - Work in progress
  6. complete - Finished and verified

Work Types

  • feature - New functionality
  • bug - Defect or issue
  • refactor - Code improvement
  • documentation - Documentation work
  • chore - Maintenance tasks

Statuses

  • open - Not yet started
  • blocked - Cannot proceed (waiting on dependencies)
  • in-progress - Actively being worked on
  • in-review - Under review
  • done - Completed successfully
  • cancelled - Work abandoned

Usage Examples

Creating Work Items

// Create a simple work item
const result = await manager.create({
  project_id: 'proj_123',
  title: 'Add login form',
  work_type_id: 'type_feature',
  maturity_level_id: 'maturity_planned',
  status_id: 'status_open',
  priority: 5
});

// Create with dependencies
const dependent = await manager.create({
  project_id: 'proj_123',
  title: 'Add logout button',
  depends_on_work_item_ids: [result.data!.id],
  priority: 3
});

// Create batch
const batch = await manager.createBatch([
  { project_id: 'proj_123', title: 'Task 1', priority: 5 },
  { project_id: 'proj_123', title: 'Task 2', priority: 4 },
  { project_id: 'proj_123', title: 'Task 3', priority: 3 }
]);

Hierarchical Relationships

// Create parent work item
const epic = await manager.create({
  project_id: 'proj_123',
  title: 'User Management Epic',
  work_type_id: 'type_feature',
  priority: 10
});

// Create child work items
const story1 = await manager.create({
  project_id: 'proj_123',
  title: 'User login',
  parent_work_item_id: epic.data!.id,
  priority: 8
});

const story2 = await manager.create({
  project_id: 'proj_123',
  title: 'User registration',
  parent_work_item_id: epic.data!.id,
  priority: 7
});

// Get all children
const children = await manager.getChildren(epic.data!.id, false); // Direct children only
const allDescendants = await manager.getChildren(epic.data!.id, true); // Recursive

// Get ancestors
const ancestors = await manager.getAncestors(story1.data!.id);

// Move work item to different parent
await manager.move(story1.data!.id, 'other_epic_id');

Dependency Management

// Add dependency
await manager.addDependency('work_item_1', 'work_item_2'); // 1 depends on 2

// Remove dependency
await manager.removeDependency('work_item_1', 'work_item_2');

// Get dependencies
const deps = await manager.getDependencies('work_item_1', false); // Direct only
const allDeps = await manager.getDependencies('work_item_1', true); // Transitive

// Get blocked items (items waiting for this one)
const blockedItems = await manager.getBlockedItems('work_item_1');

// Check for circular dependencies
const circularCheck = await manager.checkCircularDependencies(
  'work_item_1',
  'work_item_2'
);

if (!circularCheck.valid) {
  console.log('Circular dependency detected:', circularCheck.cycle);
}

// Validate all dependencies
const validation = await manager.validateDependencies('work_item_1');
if (!validation.valid) {
  console.log('Invalid dependencies:', validation.missing_dependencies);
}

Status Management

// Update status
await manager.updateStatus('work_item_1', 'status_in_progress');

// Status transitions are validated
const result = await manager.updateStatus('work_item_1', 'status_done');
if (!result.success) {
  console.log('Status update failed:', result.error);
}

Maturity Progression

// Promote to next maturity level
const promoted = await manager.promoteMaturity('work_item_1');

if (!promoted.success) {
  console.log('Cannot promote:', promoted.error);
}

// Promote to specific level
await manager.promoteMaturity('work_item_1', 'maturity_ready');

// Check if promotion is allowed
const canPromote = await manager.canPromote('work_item_1', 'maturity_active');
if (!canPromote.valid) {
  console.log('Cannot promote:', canPromote.reason);
}

Assignment Management

// Assign to team member
await manager.assign('work_item_1', 'user:[email protected]');

// Assign to agent
await manager.assign('work_item_1', 'agent:claude');

// Unassign
await manager.unassign('work_item_1');

// Get all assigned items for a person
const assigned = await manager.getAssignedItems('user:[email protected]', {
  status_ids: ['status_in_progress']
});

Readiness Checks

// Check if work item is ready to start
const readiness = await manager.isReadyToStart('work_item_1');

if (readiness.ready) {
  console.log('Ready to start!');
} else {
  console.log('Blocking reasons:', readiness.blocking_reasons);
}

Querying Work Items

// Query with filters
const results = await manager.query(
  {
    project_id: 'proj_123',
    work_type_ids: ['type_feature', 'type_bug'],
    maturity_level_ids: ['maturity_ready', 'maturity_active'],
    status_ids: ['status_open', 'status_in_progress'],
    priority_min: 5,
    priority_max: 10,
    blocks_project: true,
    assigned_to: 'user:[email protected]',
    has_dependencies: false,
    is_blocked: false
  },
  {
    sort_by: 'priority',
    sort_order: 'desc',
    limit: 20,
    offset: 0
  }
);

// Get unassigned high-priority items
const unassigned = await manager.query({
  project_id: 'proj_123',
  assigned_to: null,
  priority_min: 8
});

// Get root items (no parent)
const rootItems = await manager.query({
  project_id: 'proj_123',
  parent_work_item_id: null
});

Statistics & Reporting

// Get project statistics
const stats = await manager.getStatistics('proj_123');

console.log('Total items:', stats.total_count);
console.log('By work type:', stats.by_work_type);
console.log('By maturity:', stats.by_maturity_level);
console.log('By status:', stats.by_status);
console.log('By priority:', stats.by_priority);
console.log('Assigned:', stats.assigned_count);
console.log('Unassigned:', stats.unassigned_count);
console.log('Ready to start:', stats.ready_count);
console.log('Blocked:', stats.blocked_count);

// Get dependency graph
const graph = await manager.getDependencyGraph({
  project_id: 'proj_123'
});

console.log('Nodes:', graph.nodes.length);
console.log('Edges:', graph.edges.length);

Batch Operations

// Create multiple items efficiently
const created = await manager.createBatch([
  {
    project_id: 'proj_123',
    title: 'Feature 1',
    priority: 8
  },
  {
    project_id: 'proj_123',
    title: 'Feature 2',
    priority: 7
  }
]);

// Update multiple items
const updated = await manager.updateBatch([
  {
    id: 'item_1',
    updates: { priority: 10, assigned_to: 'user:[email protected]' }
  },
  {
    id: 'item_2',
    updates: { status_id: 'status_in_progress' }
  }
]);

console.log(`Created ${created.successful.length} items`);
console.log(`Updated ${updated.successful.length} items`);
if (created.failed.length > 0) {
  console.log('Failures:', created.failed);
}

Custom Storage Backend

Implement the WorkItemStorage interface for your database:

import { WorkItemStorage, WorkItem } from '@bernierllc/work-item-core';

class PostgresWorkItemStorage implements WorkItemStorage {
  async saveWorkItem(workItem: WorkItem): Promise<void> {
    // Save to PostgreSQL
  }

  async getWorkItem(id: string): Promise<WorkItem | null> {
    // Retrieve from PostgreSQL
  }

  async deleteWorkItem(id: string): Promise<void> {
    // Delete from PostgreSQL
  }

  async queryWorkItems(
    filters: WorkItemFilters,
    options?: WorkItemQueryOptions
  ): Promise<WorkItem[]> {
    // Query PostgreSQL with filters
  }

  // Implement remaining methods...
}

// Use custom storage
const storage = new PostgresWorkItemStorage();
const manager = new WorkItemManager(storage);

API Reference

WorkItemManager

Constructor

constructor(
  storage: WorkItemStorage,
  config?: {
    maturityLevels?: MaturityLevel[];
    statuses?: WorkItemStatus[];
    workTypes?: WorkType[];
  }
)

CRUD Operations

  • create(input: CreateWorkItemInput): Promise<WorkItemResult<WorkItem>>
  • get(workItemId: string, include_details?: boolean): Promise<WorkItemResult<WorkItem>>
  • update(workItemId: string, updates: UpdateWorkItemInput): Promise<WorkItemResult<WorkItem>>
  • delete(workItemId: string): Promise<WorkItemResult<void>>
  • exists(workItemId: string): Promise<boolean>
  • query(filters: WorkItemFilters, options?: WorkItemQueryOptions): Promise<WorkItem[]>

Hierarchy Management

  • getChildren(workItemId: string, recursive?: boolean): Promise<WorkItem[]>
  • getAncestors(workItemId: string): Promise<WorkItem[]>
  • move(workItemId: string, newParentId: string | null): Promise<WorkItemResult<WorkItem>>

Dependency Management

  • addDependency(workItemId: string, dependsOnId: string): Promise<WorkItemResult<WorkItem>>
  • removeDependency(workItemId: string, dependsOnId: string): Promise<WorkItemResult<WorkItem>>
  • getDependencies(workItemId: string, recursive?: boolean): Promise<WorkItem[]>
  • getBlockedItems(workItemId: string): Promise<WorkItem[]>
  • checkCircularDependencies(workItemId: string, dependsOnId: string): Promise<DependencyValidationResult>
  • validateDependencies(workItemId: string): Promise<DependencyValidationResult>

Status & Maturity

  • updateStatus(workItemId: string, statusId: string): Promise<WorkItemResult<WorkItem>>
  • promoteMaturity(workItemId: string, maturityId?: string): Promise<WorkItemResult<WorkItem>>
  • canPromote(workItemId: string, maturityId: string): Promise<ValidationResult>

Assignment

  • assign(workItemId: string, assignee: string): Promise<WorkItemResult<WorkItem>>
  • unassign(workItemId: string): Promise<WorkItemResult<WorkItem>>
  • getAssignedItems(assignee: string, filters?: WorkItemFilters): Promise<WorkItem[]>

Readiness & Validation

  • isReadyToStart(workItemId: string): Promise<ReadinessResult>
  • validate(workItem: WorkItem | CreateWorkItemInput): Promise<ValidationResult>

Batch Operations

  • createBatch(inputs: CreateWorkItemInput[]): Promise<BatchResult<WorkItem>>
  • updateBatch(updates: Array<{ id: string; updates: UpdateWorkItemInput }>): Promise<BatchResult<WorkItem>>

Statistics & Reporting

  • getStatistics(projectId: string): Promise<WorkItemStatistics>
  • getDependencyGraph(filters: WorkItemFilters): Promise<DependencyGraph>

Configuration

Custom Maturity Levels

const customMaturityLevels = [
  { id: 'backlog', name: 'Backlog', order: 1 },
  { id: 'sprint', name: 'In Sprint', order: 2 },
  { id: 'done', name: 'Done', order: 3 }
];

const manager = new WorkItemManager(storage, {
  maturityLevels: customMaturityLevels
});

Custom Statuses

const customStatuses = [
  { id: 'todo', name: 'To Do', category: 'not_started' },
  { id: 'doing', name: 'Doing', category: 'in_progress' },
  { id: 'testing', name: 'Testing', category: 'in_progress' },
  { id: 'finished', name: 'Finished', category: 'completed' }
];

const manager = new WorkItemManager(storage, {
  statuses: customStatuses
});

Custom Work Types

const customWorkTypes = [
  { id: 'story', name: 'User Story', icon: '📖' },
  { id: 'spike', name: 'Spike', icon: '🔬' },
  { id: 'epic', name: 'Epic', icon: '🎯' }
];

const manager = new WorkItemManager(storage, {
  workTypes: customWorkTypes
});

Integration Status

  • Logger: not-applicable - Core package with no logging requirements
  • Docs-Suite: ready - Complete TypeDoc API documentation
  • NeverHub: not-applicable - Core package with no service discovery needs

TypeScript Support

This package is written in TypeScript with strict mode enabled and includes complete type definitions.

import type {
  WorkItem,
  CreateWorkItemInput,
  UpdateWorkItemInput,
  WorkItemFilters,
  WorkItemResult,
  ValidationResult,
  ReadinessResult,
  WorkItemStatistics
} from '@bernierllc/work-item-core';

Algorithm Details

This package implements sophisticated graph algorithms for dependency management:

Circular Dependency Detection (DFS)

Uses Depth-First Search (DFS) to detect circular dependencies:

  • Maintains visited set and stack for path tracking
  • Detects cycles when revisiting a node in current path
  • Returns all circular dependency chains found
  • Time complexity: O(V + E) where V = work items, E = dependencies

Blocking Detection (BFS-style)

Uses Breadth-First Search (BFS) traversal for blocking analysis:

  • Identifies incomplete dependencies blocking work item start
  • Computes readiness by checking all dependency statuses
  • Returns blocking items with reasons for blocking
  • Time complexity: O(V + E) for full traversal

Transitive Dependencies

Recursive algorithm for finding all transitive dependencies:

  • Depth-limited to prevent infinite recursion (default max depth: 10)
  • Uses visited set to prevent duplicate processing
  • Returns flattened list of all direct and transitive dependencies
  • Time complexity: O(V + E) with early termination on visited nodes

Testing

The package includes comprehensive tests with 90%+ coverage:

npm test              # Run tests in watch mode
npm run test:run      # Run tests once
npm run test:coverage # Generate coverage report

Test Coverage

  • Branches: 90.13%
  • Functions: 93.61%
  • Lines: 91.15%
  • Statements: 91.15%

Includes tests for:

  • CRUD operations with validation
  • Hierarchical relationships
  • Dependency management and circular detection
  • Status and maturity progression
  • Assignment workflows
  • Readiness checks
  • Batch operations
  • Edge cases and error conditions

License

Copyright (c) 2025 Bernier LLC

This file is licensed to the client under a limited-use license. The client may use and modify this code only within the scope of the project it was delivered for. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.

See Also