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/braingrid-cli-wrapper

v0.3.0

Published

Type-safe wrapper for BrainGrid CLI

Readme

@bernierllc/braingrid-cli-wrapper

Type-safe wrapper for the BrainGrid CLI that provides a clean, programmatic interface for interacting with BrainGrid projects, requirements, and tasks.

Overview

This package provides atomic utilities for interacting with the BrainGrid CLI in a type-safe manner. It wraps BrainGrid CLI commands with Zod schema validation, ensuring type safety and proper error handling.

Features

  • Type-safe API: Full TypeScript support with Zod schema validation
  • Error Handling: Custom error types with detailed error information
  • CLI Integration: Seamless integration with BrainGrid CLI commands
  • Schema Validation: Automatic validation of CLI responses using Zod schemas
  • Minimal Dependencies: Only depends on execa and zod

Installation

npm install @bernierllc/braingrid-cli-wrapper

Quick Start

import {
  createIdea,
  listProjects,
  createProject,
  listRequirements,
  updateRequirementStatus,
  createTask
} from '@bernierllc/braingrid-cli-wrapper';

// Create a new project
const project = await createProject('My Project', 'Project description');
console.log(`Created project ${project.id}`);

// List all projects
const projects = await listProjects();
console.log(`Found ${projects.length} projects`);

// Create a new requirement (IDEA)
const requirement = await createIdea('Add OAuth2 authentication', project.id);
console.log(`Created requirement ${requirement.id} with status ${requirement.status}`);

// List requirements
const requirements = await listRequirements(project.id);
console.log(`Found ${requirements.length} requirements`);

// Update requirement status
await updateRequirementStatus(requirement.id, 'PLANNED');
console.log(`Updated requirement to PLANNED status`);

// Create a task under a requirement
const task = await createTask(requirement.id, {
  title: 'Build login UI',
  description: 'Create login form component',
  tags: ['DEV', 'frontend'],
  dependencies: []
});
console.log(`Created task ${task.id}`);

API Reference

Commands

createIdea(prompt: string, projectId?: string): Promise<BrainGridRequirement>

Creates a new requirement (IDEA) in BrainGrid.

Input:

  • prompt (string, required): Description of the requirement/idea
  • projectId (string, optional): Project ID to associate with the requirement

Output:

  • Returns a BrainGridRequirement object with:
    • id: Requirement ID
    • projectId: Associated project ID
    • title: Requirement title
    • status: Requirement status (IDEA, PLANNED, IN_PROGRESS, COMPLETED, CANCELLED, PAUSED)
    • description: Optional description
    • createdAt: Optional creation timestamp
    • updatedAt: Optional update timestamp

Example:

const req = await createIdea('Add user authentication system');
// { id: 'req-123', projectId: 'proj-456', title: 'Add user authentication system', status: 'IDEA' }

listProjects(): Promise<BrainGridProject[]>

Lists all projects in BrainGrid.

Input: None

Output:

  • Returns an array of BrainGridProject objects with:
    • id: Project ID
    • name: Project name
    • description: Optional project description

Example:

const projects = await listProjects();
// [{ id: 'proj-1', name: 'My Project', description: 'Project description' }]

createProject(name: string, description?: string): Promise<BrainGridProject>

Creates a new project in BrainGrid.

Input:

  • name (string, required): Project name
  • description (string, optional): Project description

Output:

  • Returns a BrainGridProject object

Example:

const project = await createProject('My Project', 'Project description');
// { id: 'proj-123', name: 'My Project', description: 'Project description' }

listRequirements(projectId?: string): Promise<BrainGridRequirement[]>

Lists requirements, optionally filtered by project.

Input:

  • projectId (string, optional): Filter by project ID

Output:

  • Returns an array of BrainGridRequirement objects

Example:

// List all requirements
const allRequirements = await listRequirements();

// List requirements for a specific project
const projectRequirements = await listRequirements('proj-123');
// [{ id: 'req-1', projectId: 'proj-123', title: 'Add auth', status: 'IDEA' }]

updateRequirementStatus(requirementId: string, status: RequirementStatus): Promise<void>

Updates a requirement's status.

Input:

  • requirementId (string, required): Requirement ID to update
  • status (RequirementStatus, required): New status (IDEA, PLANNED, IN_PROGRESS, COMPLETED, CANCELLED, PAUSED)

Output: Promise that resolves when update is complete

Example:

await updateRequirementStatus('req-123', 'PLANNED');
await updateRequirementStatus('req-123', 'IN_PROGRESS');
await updateRequirementStatus('req-123', 'COMPLETED');

createTask(reqId: string, options: CreateTaskOptions): Promise<BrainGridTask>

Creates a task under a requirement.

Input:

  • reqId (string, required): Requirement ID
  • options (CreateTaskOptions, required):
    • title (string, required): Task title
    • description (string, optional): Task description
    • tags (string[], optional): Task tags
    • dependencies (string[], optional): Task dependency IDs

Output:

  • Returns a BrainGridTask object with:
    • id: Task ID
    • reqId: Parent requirement ID
    • title: Task title
    • status: Task status (TODO, READY, BLOCKED, IN_PROGRESS, COMPLETED, FAILED, PAUSED)
    • description: Optional description
    • tags: Optional array of tags
    • dependencies: Optional array of dependency IDs
    • assignedTo: Optional assignee ID
    • createdAt: Optional creation timestamp
    • updatedAt: Optional update timestamp
    • metadata: Optional metadata object

Example:

const task = await createTask('req-123', {
  title: 'Build login UI',
  description: 'Create login form component',
  tags: ['DEV', 'frontend'],
  dependencies: ['task-100']
});
// { id: 'task-456', reqId: 'req-123', title: 'Build login UI', status: 'TODO', ... }

listTasks(options?: ListTasksOptions): Promise<BrainGridTask[]>

Lists tasks with optional filters.

Input:

  • options (ListTasksOptions, optional):
    • reqId (string, optional): Filter by requirement ID
    • status (TaskStatus[], optional): Filter by status array
    • tags (string[], optional): Filter by tags array

Output:

  • Returns an array of BrainGridTask objects

Example:

// List all tasks
const allTasks = await listTasks();

// List tasks for a specific requirement
const reqTasks = await listTasks({ reqId: 'req-123' });

// List tasks by status
const inProgressTasks = await listTasks({ status: ['IN_PROGRESS'] });

// Combine filters
const filteredTasks = await listTasks({
  reqId: 'req-123',
  status: ['TODO', 'READY'],
  tags: ['DEV']
});

updateTaskStatus(taskId: string, options: UpdateTaskOptions): Promise<void>

Updates task status and metadata.

Input:

  • taskId (string, required): Task ID to update
  • options (UpdateTaskOptions, optional):
    • status (TaskStatus, optional): New task status
    • assignedTo (string, optional): Assignee ID
    • metadata (Record<string, unknown>, optional): Metadata object

Output: Promise that resolves when update is complete

Example:

// Update task status
await updateTaskStatus('task-123', { status: 'IN_PROGRESS' });

// Update with assignee
await updateTaskStatus('task-123', {
  status: 'IN_PROGRESS',
  assignedTo: 'user-456'
});

// Update with metadata
await updateTaskStatus('task-123', {
  status: 'IN_PROGRESS',
  metadata: { progress: 50, notes: 'Half done' }
});

Types

BrainGridProject

interface BrainGridProject {
  id: string;
  name: string;
  description?: string;
}

BrainGridRequirement

interface BrainGridRequirement {
  id: string;
  projectId: string;
  title: string;
  status: RequirementStatus;
  description?: string;
  createdAt?: string;
  updatedAt?: string;
}

BrainGridTask

interface BrainGridTask {
  id: string;
  reqId: string;
  title: string;
  status: TaskStatus;
  description?: string;
  tags?: string[];
  dependencies?: string[];
  assignedTo?: string;
  createdAt?: string;
  updatedAt?: string;
  metadata?: Record<string, unknown>;
}

RequirementStatus

type RequirementStatus = 'IDEA' | 'PLANNED' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED' | 'PAUSED';

TaskStatus

type TaskStatus = 'TODO' | 'READY' | 'BLOCKED' | 'IN_PROGRESS' | 'COMPLETED' | 'FAILED' | 'PAUSED';

Error Handling

The package throws BrainGridCliError when CLI commands fail:

class BrainGridCliError extends Error {
  command: string;
  exitCode: number;
  stderr: string;
}

Example:

import { createIdea, BrainGridCliError } from '@bernierllc/braingrid-cli-wrapper';

try {
  const req = await createIdea('Test requirement');
} catch (error) {
  if (error instanceof BrainGridCliError) {
    console.error(`CLI command failed: ${error.command}`);
    console.error(`Exit code: ${error.exitCode}`);
    console.error(`Error output: ${error.stderr}`);
  }
}

Configuration

Environment Variables

  • BRAINGRID_CLI_PATH: Custom path to the BrainGrid CLI executable (defaults to 'braingrid')

Example:

export BRAINGRID_CLI_PATH=/custom/path/braingrid

Usage Examples

Complete Workflow

import {
  createProject,
  listProjects,
  createIdea,
  listRequirements,
  updateRequirementStatus,
  createTask,
  listTasks,
  updateTaskStatus
} from '@bernierllc/braingrid-cli-wrapper';

async function workflow() {
  // 1. Create or list projects
  const project = await createProject(
    'My Project',
    'Authentication system project'
  );

  // Or list existing projects
  const projects = await listProjects();
  console.log(`Found ${projects.length} projects`);

  // 2. Create a requirement
  const requirement = await createIdea(
    'Build user authentication system',
    project.id
  );

  // 3. List and update requirements
  const requirements = await listRequirements(project.id);
  console.log(`Project has ${requirements.length} requirements`);

  await updateRequirementStatus(requirement.id, 'PLANNED');

  // 4. Create tasks
  const task1 = await createTask(requirement.id, {
    title: 'Design authentication flow',
    tags: ['DESIGN']
  });

  const task2 = await createTask(requirement.id, {
    title: 'Implement login endpoint',
    tags: ['DEV', 'backend'],
    dependencies: [task1.id]
  });

  // 5. List tasks
  const tasks = await listTasks({ reqId: requirement.id });
  console.log(`Created ${tasks.length} tasks`);

  // 6. Update task status
  await updateTaskStatus(task1.id, { status: 'COMPLETED' });
  await updateTaskStatus(task2.id, {
    status: 'IN_PROGRESS',
    assignedTo: 'user-123'
  });

  // 7. Mark requirement as in progress
  await updateRequirementStatus(requirement.id, 'IN_PROGRESS');
}

Error Handling Example

import { createIdea, BrainGridCliError } from '@bernierllc/braingrid-cli-wrapper';

async function createRequirementSafely(prompt: string) {
  try {
    const req = await createIdea(prompt);
    return req;
  } catch (error) {
    if (error instanceof BrainGridCliError) {
      console.error(`BrainGrid CLI error: ${error.message}`);
      console.error(`Command: ${error.command}`);
      console.error(`Exit code: ${error.exitCode}`);
      console.error(`Stderr: ${error.stderr}`);
      throw new Error('Failed to create requirement');
    }
    throw error;
  }
}

Testing

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run tests in watch mode
npm run test:watch

Integration Status

Logger Integration

Status: not-applicable

This is a pure utility core package with no dependencies. Logging is handled by consuming packages. Does not require @bernierllc/logger integration.

Docs-Suite Integration

Status: ready

Complete API documentation with TypeScript types and examples available for documentation suite integration.

NeverHub Integration

Status: not-applicable

Pure utility package with no runtime dependencies. NeverHub integration is handled at the service-level packages that consume this utility. Does not require @bernierllc/neverhub-adapter integration.

Core Package Compliance

This package follows the core package rules:

  • Atomic functionality: Single responsibility - wraps BrainGrid CLI
  • No internal dependencies: Only depends on external packages (execa, zod)
  • Pure functions: Explicit inputs/outputs with type safety
  • Full test coverage: Comprehensive test suite for all commands
  • Single entrypoint: All exports via index.ts
  • Strict typing: TypeScript strict mode enabled, no implicit any
  • Documentation: Complete README with purpose, usage, and examples

License

MIT License - see LICENSE file for details.