This document describes the architecture and design decisions for the Ohno task management system.
Ohno is a TypeScript monorepo providing task management for AI agent workflows with multiple integration options.
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ prd-analyzer │ │ product-manager │ │ project-harness │
│ (skill) │ │ (skill) │ │ (skill) │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└───────────────────────┼───────────────────────┘
│ write via MCP/CLI
▼
┌─────────────────────────┐
│ .ohno/tasks.db │
│ (SQLite database) │
└────────────┬────────────┘
│ read + watch
▼
┌─────────────────────────┐
│ ohno serve (CLI) │
│ HTTP + file watcher │
└────────────┬────────────┘
│ generate
▼
┌─────────────────────────┐
│ .ohno/kanban.html │
│ (self-contained board) │
└─────────────────────────┘
Decision: TypeScript monorepo with shared core package
Structure:
packages/
├── ohno-core/ # Shared database layer (sql.js)
├── ohno-mcp/ # MCP server (36 tools)
└── ohno-cli/ # CLI tool (26 commands)
Rationale:
- Code Reuse: Database logic shared across MCP server and CLI
- Type Safety: TypeScript ensures type consistency across packages
- Maintainability: Single codebase, unified build system (Turborepo)
- NPM Publishing: Each package published independently to npm
- Testability: Shared test infrastructure (Vitest workspace)
Packages:
| Package | Description | Published As | Dependencies |
|---|---|---|---|
ohno-core |
SQLite database layer, schema, utilities | @stevestomp/ohno-core |
sql.js |
ohno-mcp |
MCP server for Claude Code | @stevestomp/ohno-mcp |
@modelcontextprotocol/sdk, zod, ohno-core |
ohno-cli |
CLI + HTTP server + kanban generator | @stevestomp/ohno-cli |
commander, chokidar, ohno-core |
Decision: Node.js + TypeScript
Rationale:
| Criterion | Rating | Notes |
|---|---|---|
| Distribution | 9/10 | NPM + npx provides zero-install experience |
| Type Safety | 10/10 | Full type checking across packages |
| Ecosystem | 10/10 | Rich ecosystem (Commander, Chokidar, sql.js) |
| MCP Support | 10/10 | Official MCP SDK available for TypeScript |
| Cross-Platform | 10/10 | Works on macOS, Linux, Windows |
| Developer Experience | 9/10 | Excellent tooling (tsc, Vitest, tsx) |
Key factors:
- MCP SDK officially supports TypeScript/Node.js
- sql.js provides SQLite via WebAssembly (no native compilation required)
- Commander.js simplifies CLI development
- Chokidar provides cross-platform file watching
- Zero-install via
npx @stevestomp/ohno-cliandnpx @stevestomp/ohno-mcp
Previous implementation: Python (stdlib-only) - rewritten to TypeScript in v0.5.0 for MCP support and better ecosystem integration.
Decision: SQLite via sql.js with shared schema
Exports:
TaskDatabaseclass (CRUD operations)- Type definitions (Task, TaskActivity, ProjectStatus, etc.)
- Utility functions (findOhnoDir, generateTaskId, etc.)
- Schema constants (CREATE_* SQL statements)
Key Features:
- Synchronous API (sql.js) - simpler than async
- Automatic schema migration (adds columns if missing)
- Transaction support for consistency
- Prepared statements for performance
- Type-safe query results
Schema tables:
projects -- Root container
epics -- High-level features (P0-P3 priority)
stories -- User stories under epics
tasks -- Individual work items
task_activity -- Activity log (audit trail)
task_files -- Associated files
task_dependencies -- Task relationships (blocks, requires, relates_to)
task_failures -- Failure pattern tracking (for kaizen integration)
task_handoffs -- Handoff session tracking (subagent reporting)Design Philosophy:
- Read-only for visualizations (ohno-cli serve/sync)
- Read-write for task management (ohno-mcp, ohno-cli CRUD)
- Skills write via MCP tools or CLI commands
- Database acts as source of truth
Decision: Model Context Protocol server with 36 tools
Tool Categories:
| Category | Tools | Purpose |
|---|---|---|
| Query | get_project_status, get_session_context, get_tasks, get_task, get_next_task, get_next_batch, get_blocked_tasks, get_kanban_board | Read task state |
| Status Updates | update_task_status, update_task_progress, set_blocker, resolve_blocker, set_needs_rework, update_task_wip | Track progress |
| Activity Logging | add_task_activity, set_handoff_notes, summarize_task_activity, record_task_failure | Session continuity |
| Task CRUD | create_task, update_task, archive_task | Manage tasks |
| Story CRUD | create_story, get_story, list_stories, update_story | Manage stories |
| Epic CRUD | create_epic, get_epic, get_epics, update_epic | Manage epics |
| Dependencies | add_dependency, remove_dependency, get_task_dependencies | Task relationships |
| Handoffs | set_task_handoff, get_task_handoff, compact_story_handoffs, delete_epic_handoffs | Subagent handoff data |
Key Features:
- Zod schema validation for all tool parameters
- Automatic database discovery (walks up to find
.ohno/) - Rich return types with joined epic/story info
- Error handling with descriptive messages
Usage:
{
"mcpServers": {
"ohno": {
"command": "npx",
"args": ["@stevestomp/ohno-mcp"]
}
}
}Decision: Commander.js CLI with 26 commands
Command Categories:
| Category | Commands | Purpose |
|---|---|---|
| Visualization | serve, sync, kanban, status, init | Kanban board + setup |
| Task Management | tasks, task, create, start, done, review, block, unblock | Task CRUD operations |
| Epic Management | epics, epic get/create/update/delete | Epic CRUD operations |
| Story Management | stories, story get/create/update/delete | Story CRUD operations |
| Dependencies | dep add, dep rm, dep list | Relationship management |
| AI Agent | context, next, update-wip, set-handoff, compact-handoffs, delete-handoffs | Session continuity + handoffs |
Key Features:
--jsonflag on all commands for machine parsing- Global
--no-colorand--dirflags - Exit codes for CI/CD integration (0=success, 1=error)
- Colored output with chalk (respects NO_COLOR env var)
- Automatic directory discovery (walks up to find
.ohno/)
HTTP Server (serve command):
- Express-based HTTP server on port 3333 (configurable)
- Serves self-contained HTML (inline CSS/JS)
- File watcher (chokidar) monitors tasks.db changes
- Auto-regenerates kanban.html on change
- Live reload via client-side polling
Distribution:
# Zero install
npx @stevestomp/ohno-cli serve
# Global install
npm install -g @stevestomp/ohno-cli
ohno serveDecision: Turborepo + TypeScript compiler
Build Pipeline:
turbo build
→ ohno-core (tsc) # Builds first (dependency)
→ ohno-mcp (tsc) # Uses ohno-core types
→ ohno-cli (tsc) # Uses ohno-core types
Configuration:
turbo.json: Task dependencies and cachingtsconfig.json: Per-package TypeScript configvitest.workspace.ts: Shared test configurationpackage.json: Workspace management (npm workspaces)
Scripts:
npm run build: Build all packagesnpm run test: Run all testsnpm run clean: Remove build artifactsnpm run dev: Development mode (tsx)
Decision: Walk-up search with override
Priority (highest to lowest):
1. --dir /explicit/path argument (CLI)
2. OHNO_DIR environment variable (both)
3. Walk up from cwd to find .ohno/
4. Error if not found (suggest 'ohno init')
Rationale: Follows git's model for finding .git/. Works from any subdirectory.
Implementation: findOhnoDir() in ohno-core/utils.ts
Decision: Minimal configuration, convention over configuration
Priority (lowest to highest):
1. Built-in defaults
2. Environment variables (OHNO_*)
3. Command-line flags
Environment variables:
OHNO_DIR=/path # Override directory discovery
OHNO_PORT=3333 # HTTP server port
NO_COLOR=1 # Disable colored output (standard)No config file by design:
- Simplicity: Zero-config works out of the box
- 12-factor: Environment variables for configuration
- Portability: Works in CI/CD without setup
| Concern | Mitigation |
|---|---|
| XSS in task titles | HTML escaping in template generation |
| SQL injection | Prepared statements via sql.js |
| Path traversal | HTTP server restricted to .ohno/ directory |
| Network exposure | Bind to 127.0.0.1 by default (localhost only) |
| Dependency vulnerabilities | Regular npm audit, pinned versions |
Critical: Server binds to localhost by default. Use --host 0.0.0.0 for network access.
In Scope:
- Task CRUD via MCP tools and CLI
- Kanban HTML visualization
- Database watching and live reload
- HTTP serving with CORS support
- Project statistics and reporting
- JSON output for programmatic access
- Initialization of .ohno/ structure
- Session context for AI continuity
Out of Scope:
- Authentication/authorization (local-only tool)
- Real-time WebSocket updates (uses polling)
- Multi-project management (one .ohno per project)
- Git hooks auto-installation (user configuration)
- Cloud sync/backup (local-first)
- Complex web-based editing (board supports basic edit/delete)
Design Principle:
Skills ──write──> tasks.db ──read──> kanban board ✓ Correct
Skills ──write──> tasks.db <──write── kanban board ✗ Bidirectional coupling
CLI commands provide write access for human users and agents, but the visual board remains read-only.
CREATE TABLE projects (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
created_at TEXT,
updated_at TEXT
);
CREATE TABLE epics (
id TEXT PRIMARY KEY,
project_id TEXT,
title TEXT NOT NULL,
description TEXT,
priority TEXT DEFAULT 'P2', -- P0, P1, P2, P3
status TEXT DEFAULT 'todo',
created_at TEXT,
updated_at TEXT
);
CREATE TABLE stories (
id TEXT PRIMARY KEY,
epic_id TEXT,
title TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'todo',
created_at TEXT,
updated_at TEXT
);
CREATE TABLE tasks (
id TEXT PRIMARY KEY,
story_id TEXT,
title TEXT NOT NULL,
status TEXT DEFAULT 'todo', -- todo, in_progress, review, done, blocked
task_type TEXT, -- feature, bug, chore, spike, test
estimate_hours REAL,
description TEXT,
context_summary TEXT, -- AI-generated context
working_files TEXT, -- Comma-separated file paths
blockers TEXT, -- Blocker description
handoff_notes TEXT, -- Notes for next session
progress_percent INTEGER DEFAULT 0, -- 0-100
actual_hours REAL,
created_at TEXT,
updated_at TEXT,
created_by TEXT,
activity_summary TEXT, -- Summarized activity log
source TEXT DEFAULT 'human', -- human, pokayokay-plan, kaizen-fix, kaizen-suggest
needs_rework INTEGER DEFAULT 0, -- Flag for tasks needing retry
work_in_progress TEXT, -- JSON WIP metadata
wip_updated_at TEXT
);CREATE TABLE task_activity (
id TEXT PRIMARY KEY,
task_id TEXT NOT NULL,
activity_type TEXT, -- note, file_change, decision, progress
description TEXT,
old_value TEXT,
new_value TEXT,
actor TEXT,
created_at TEXT
);
CREATE TABLE task_files (
id TEXT PRIMARY KEY,
task_id TEXT NOT NULL,
file_path TEXT NOT NULL,
file_type TEXT, -- created, modified, referenced
created_at TEXT
);
CREATE TABLE task_dependencies (
id TEXT PRIMARY KEY,
task_id TEXT NOT NULL,
depends_on_task_id TEXT NOT NULL,
dependency_type TEXT DEFAULT 'blocks', -- blocks, requires, relates_to
created_at TEXT
);
CREATE TABLE task_failures (
id TEXT PRIMARY KEY,
task_id TEXT NOT NULL,
failure_type TEXT NOT NULL, -- spec, quality, implementation
failure_reason TEXT NOT NULL,
attempt INTEGER,
created_at TEXT
);
CREATE TABLE task_handoffs (
task_id TEXT PRIMARY KEY,
status TEXT NOT NULL, -- PASS, FAIL, BLOCKED
summary TEXT NOT NULL,
files_changed TEXT, -- JSON array of file paths
full_details TEXT,
created_at TEXT,
compacted_at TEXT
);CREATE INDEX idx_tasks_status ON tasks(status);
CREATE INDEX idx_tasks_story_id ON tasks(story_id);
CREATE INDEX idx_task_activity_task_id ON task_activity(task_id);
CREATE INDEX idx_task_deps_task_id ON task_dependencies(task_id);
CREATE INDEX idx_task_failures_task_id ON task_failures(task_id);Primary: NPM + npx
# Zero install (recommended)
npx @stevestomp/ohno-cli serve
npx @stevestomp/ohno-mcp
# Global install
npm install -g @stevestomp/ohno-cli
ohno serve
# Local project install
npm install @stevestomp/ohno-cli
npx ohno serveMCP Server:
- Installed via Claude Code settings
- Runs as subprocess communicating via stdio
- Automatic database discovery
Publishing:
- Packages published to npm under @stevestomp scope
- Semantic versioning (v0.16.x currently)
- Automated via GitHub Actions
# Install dependencies
npm install
# Build all packages
npm run build
# Run tests
npm run test
# Development mode (auto-rebuild)
npm run dev
# Clean build artifacts
npm run clean- Unit tests: Core database operations (db.test.ts)
- Integration tests: CLI commands (cli.test.ts), MCP server (server.test.ts)
- Test framework: Vitest (fast, ESM-native)
- Coverage: Focus on ohno-core (shared logic)
- Run tests:
npm run test - Build packages:
npm run build - Update version:
npm version patch/minor/major - Publish to npm:
npm publish --workspace packages/ohno-* - Tag release:
git tag vX.Y.Z && git push --tags
- GitHub Actions workflow for automated publishing
- Better error messages with suggestions
- Progress bars for long operations
- Filtering in kanban board UI
- Drag-and-drop task reordering
- WebSocket support for real-time updates (replaces polling)
- Plugin system for custom task types
- Export to multiple formats (CSV, JSON, Markdown)
- Import from Jira/Linear/GitHub Issues
- Native file watching (inotify/FSEvents) for faster updates
- Docker image for containerized deployment
- Multi-user/authentication (local-first tool)
- Cloud sync/hosting (use git for sync)
- Complex project management (Gantt charts, resource allocation)
- Time tracking integration (use dedicated tools)
- v0.16.x (Current): Epic/Story CRUD, handoff system, terminal kanban, batch operations
- v0.13.x: Field selection for get_tasks/get_task, WIP metadata
- v0.5.x: TypeScript rewrite, MCP server, monorepo
- v0.4.x: Python implementation (deprecated)
- v0.1.x: Initial Python prototype
See main README for contribution guidelines. Key points:
- Use TypeScript strict mode
- Write tests for new features
- Follow existing code style
- Update ARCHITECTURE.md for design decisions