chore: initialize beadboard baseline

This commit is contained in:
zenchantlive 2026-02-11 17:42:51 -08:00
commit 292a72f861
30 changed files with 2983 additions and 0 deletions

44
.beads/.gitignore vendored Normal file
View file

@ -0,0 +1,44 @@
# SQLite databases
*.db
*.db?*
*.db-journal
*.db-wal
*.db-shm
# Daemon runtime files
daemon.lock
daemon.log
daemon.pid
bd.sock
sync-state.json
last-touched
# Local version tracking (prevents upgrade notification spam after git ops)
.local_version
# Legacy database files
db.sqlite
bd.db
# Worktree redirect file (contains relative path to main repo's .beads/)
# Must not be committed as paths would be wrong in other clones
redirect
# Merge artifacts (temporary files from 3-way merge)
beads.base.jsonl
beads.base.meta.json
beads.left.jsonl
beads.left.meta.json
beads.right.jsonl
beads.right.meta.json
# Sync state (local-only, per-machine)
# These files are machine-specific and should not be shared across clones
.sync.lock
sync_base.jsonl
# NOTE: Do NOT add negation patterns (e.g., !issues.jsonl) here.
# They would override fork protection in .git/info/exclude, allowing
# contributors to accidentally commit upstream issue databases.
# The JSONL files (issues.jsonl, interactions.jsonl) and config files
# are tracked by git by default since no pattern above ignores them.

81
.beads/README.md Normal file
View file

@ -0,0 +1,81 @@
# Beads - AI-Native Issue Tracking
Welcome to Beads! This repository uses **Beads** for issue tracking - a modern, AI-native tool designed to live directly in your codebase alongside your code.
## What is Beads?
Beads is issue tracking that lives in your repo, making it perfect for AI coding agents and developers who want their issues close to their code. No web UI required - everything works through the CLI and integrates seamlessly with git.
**Learn more:** [github.com/steveyegge/beads](https://github.com/steveyegge/beads)
## Quick Start
### Essential Commands
```bash
# Create new issues
bd create "Add user authentication"
# View all issues
bd list
# View issue details
bd show <issue-id>
# Update issue status
bd update <issue-id> --status in_progress
bd update <issue-id> --status done
# Sync with git remote
bd sync
```
### Working with Issues
Issues in Beads are:
- **Git-native**: Stored in `.beads/issues.jsonl` and synced like code
- **AI-friendly**: CLI-first design works perfectly with AI coding agents
- **Branch-aware**: Issues can follow your branch workflow
- **Always in sync**: Auto-syncs with your commits
## Why Beads?
✨ **AI-Native Design**
- Built specifically for AI-assisted development workflows
- CLI-first interface works seamlessly with AI coding agents
- No context switching to web UIs
🚀 **Developer Focused**
- Issues live in your repo, right next to your code
- Works offline, syncs when you push
- Fast, lightweight, and stays out of your way
🔧 **Git Integration**
- Automatic sync with git commits
- Branch-aware issue tracking
- Intelligent JSONL merge resolution
## Get Started with Beads
Try Beads in your own projects:
```bash
# Install Beads
curl -sSL https://raw.githubusercontent.com/steveyegge/beads/main/scripts/install.sh | bash
# Initialize in your repo
bd init
# Create your first issue
bd create "Try out Beads"
```
## Learn More
- **Documentation**: [github.com/steveyegge/beads/docs](https://github.com/steveyegge/beads/tree/main/docs)
- **Quick Start Guide**: Run `bd quickstart`
- **Examples**: [github.com/steveyegge/beads/examples](https://github.com/steveyegge/beads/tree/main/examples)
---
*Beads: Issue tracking that moves at the speed of thought* ⚡

62
.beads/config.yaml Normal file
View file

@ -0,0 +1,62 @@
# Beads Configuration File
# This file configures default behavior for all bd commands in this repository
# All settings can also be set via environment variables (BD_* prefix)
# or overridden with command-line flags
# Issue prefix for this repository (used by bd init)
# If not set, bd init will auto-detect from directory name
# Example: issue-prefix: "myproject" creates issues like "myproject-1", "myproject-2", etc.
# issue-prefix: ""
# Use no-db mode: load from JSONL, no SQLite, write back after each command
# When true, bd will use .beads/issues.jsonl as the source of truth
# instead of SQLite database
# no-db: false
# Disable daemon for RPC communication (forces direct database access)
# no-daemon: false
# Disable auto-flush of database to JSONL after mutations
# no-auto-flush: false
# Disable auto-import from JSONL when it's newer than database
# no-auto-import: false
# Enable JSON output by default
# json: false
# Default actor for audit trails (overridden by BD_ACTOR or --actor)
# actor: ""
# Path to database (overridden by BEADS_DB or --db)
# db: ""
# Auto-start daemon if not running (can also use BEADS_AUTO_START_DAEMON)
# auto-start-daemon: true
# Debounce interval for auto-flush (can also use BEADS_FLUSH_DEBOUNCE)
# flush-debounce: "5s"
# Git branch for beads commits (bd sync will commit to this branch)
# IMPORTANT: Set this for team projects so all clones use the same sync branch.
# This setting persists across clones (unlike database config which is gitignored).
# Can also use BEADS_SYNC_BRANCH env var for local override.
# If not set, bd sync will require you to run 'bd config set sync.branch <branch>'.
# sync-branch: "beads-sync"
# Multi-repo configuration (experimental - bd-307)
# Allows hydrating from multiple repositories and routing writes to the correct JSONL
# repos:
# primary: "." # Primary repo (where this database lives)
# additional: # Additional repos to hydrate from (read-only)
# - ~/beads-planning # Personal planning repo
# - ~/work-planning # Work planning repo
# Integration settings (access with 'bd config get/set')
# These are stored in the database, not in this file:
# - jira.url
# - jira.project
# - linear.url
# - linear.api-key
# - github.org
# - github.repo

View file

48
.beads/issues.jsonl Normal file
View file

@ -0,0 +1,48 @@
{"id":"bb-29x","title":"Quality Gates, Testing, and Performance Validation","description":"Establish verification confidence through unit/integration tests, boundary tests, and performance baselines for parser and realtime workflows.","acceptance_criteria":"Core functionality is covered by automated checks and target baselines are recorded.","status":"open","priority":1,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:15.8368971-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:15.8368971-08:00","labels":["perf","quality","testing"],"dependencies":[{"issue_id":"bb-29x","depends_on_id":"bb-ymg","type":"blocks","created_at":"2026-02-11T17:12:23.6722466-08:00","created_by":"zenchantlive"},{"issue_id":"bb-29x","depends_on_id":"bb-xhm","type":"blocks","created_at":"2026-02-11T17:12:24.1823625-08:00","created_by":"zenchantlive"},{"issue_id":"bb-29x","depends_on_id":"bb-bvn","type":"blocks","created_at":"2026-02-11T17:12:24.6873031-08:00","created_by":"zenchantlive"},{"issue_id":"bb-29x","depends_on_id":"bb-u6f","type":"blocks","created_at":"2026-02-11T17:12:25.193566-08:00","created_by":"zenchantlive"}]}
{"id":"bb-29x.1","title":"Implement unit tests for parser, pathing, scanner, and bd bridge","description":"Add focused fast tests for foundational modules and error handling paths.","acceptance_criteria":"Unit tests cover nominal and edge-case logic for each foundational module.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:16.6578316-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:16.6578316-08:00","labels":["tests","unit"],"dependencies":[{"issue_id":"bb-29x.1","depends_on_id":"bb-29x","type":"parent-child","created_at":"2026-02-11T17:12:16.6594181-08:00","created_by":"zenchantlive"}]}
{"id":"bb-29x.2","title":"Implement API integration tests for read, mutate, and SSE routes","description":"Validate route contracts and interaction boundaries across read/write/realtime layers.","acceptance_criteria":"Integration suite verifies route behavior and error semantics.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:17.4912736-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:17.4912736-08:00","labels":["integration","tests"],"dependencies":[{"issue_id":"bb-29x.2","depends_on_id":"bb-29x","type":"parent-child","created_at":"2026-02-11T17:12:17.4923012-08:00","created_by":"zenchantlive"},{"issue_id":"bb-29x.2","depends_on_id":"bb-29x.1","type":"blocks","created_at":"2026-02-11T17:12:38.9423299-08:00","created_by":"zenchantlive"}]}
{"id":"bb-29x.3","title":"Record parser and realtime performance baseline against PRD targets","description":"Measure parse latency and update propagation using realistic sample sizes and document outcomes.","acceptance_criteria":"Performance report exists with methodology and observed timings.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:18.3210495-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:18.3210495-08:00","labels":["benchmark","perf"],"dependencies":[{"issue_id":"bb-29x.3","depends_on_id":"bb-29x","type":"parent-child","created_at":"2026-02-11T17:12:18.3220949-08:00","created_by":"zenchantlive"},{"issue_id":"bb-29x.3","depends_on_id":"bb-29x.2","type":"blocks","created_at":"2026-02-11T17:12:39.4534943-08:00","created_by":"zenchantlive"}]}
{"id":"bb-29x.4","title":"Document operational runbook and boundary rationale","description":"Write architecture docs covering scanner policy, bd bridge behavior, and consistency guardrails for future maintainers.","acceptance_criteria":"Runbook documents startup, troubleshooting, and boundary rules.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:19.1385778-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:19.1385778-08:00","labels":["docs","runbook"],"dependencies":[{"issue_id":"bb-29x.4","depends_on_id":"bb-29x","type":"parent-child","created_at":"2026-02-11T17:12:19.1402086-08:00","created_by":"zenchantlive"},{"issue_id":"bb-29x.4","depends_on_id":"bb-29x.2","type":"blocks","created_at":"2026-02-11T17:12:39.9591458-08:00","created_by":"zenchantlive"}]}
{"id":"bb-6aj","title":"Project Registry and Multi-Project Scanner","description":"Support multiple Windows project roots using profile-scoped registry storage and safe discovery scanning tuned for developer machines.","acceptance_criteria":"Projects can be added/removed/listed and discovered via scanner with deterministic normalization.","status":"open","priority":0,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:47.7205517-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:47.7205517-08:00","labels":["multi-project","scanner"],"dependencies":[{"issue_id":"bb-6aj","depends_on_id":"bb-92d","type":"blocks","created_at":"2026-02-11T17:12:19.6374139-08:00","created_by":"zenchantlive"}]}
{"id":"bb-6aj.1","title":"Persist project registry in %USERPROFILE%\\\\.beadboard\\\\projects.json","description":"Implement read/write management for registry file in user profile path, isolated from repository files and safe for local machine usage.","acceptance_criteria":"Registry file is created lazily and survives app restarts.","status":"open","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:48.5403111-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:48.5403111-08:00","labels":["config","registry"],"dependencies":[{"issue_id":"bb-6aj.1","depends_on_id":"bb-6aj","type":"parent-child","created_at":"2026-02-11T17:11:48.5419102-08:00","created_by":"zenchantlive"}]}
{"id":"bb-6aj.2","title":"Implement registry API for add/remove/list operations","description":"Expose robust API endpoints with path validation and normalized identity checks to prevent duplicates.","acceptance_criteria":"API supports add, remove, list and returns clear validation errors.","status":"open","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:49.3542564-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:49.3542564-08:00","labels":["api","registry"],"dependencies":[{"issue_id":"bb-6aj.2","depends_on_id":"bb-6aj","type":"parent-child","created_at":"2026-02-11T17:11:49.3558158-08:00","created_by":"zenchantlive"},{"issue_id":"bb-6aj.2","depends_on_id":"bb-6aj.1","type":"blocks","created_at":"2026-02-11T17:12:26.7117348-08:00","created_by":"zenchantlive"}]}
{"id":"bb-6aj.3","title":"Build scanner with profile-root default and depth/ignore controls","description":"Scan %USERPROFILE% and user-defined roots for .beads directories with bounded recursion and ignore patterns to protect performance.","acceptance_criteria":"Scanner discovers projects without traversing entire drives by default.","status":"open","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:50.1925005-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:50.1925005-08:00","labels":["performance","scanner"],"dependencies":[{"issue_id":"bb-6aj.3","depends_on_id":"bb-6aj","type":"parent-child","created_at":"2026-02-11T17:11:50.1940841-08:00","created_by":"zenchantlive"},{"issue_id":"bb-6aj.3","depends_on_id":"bb-6aj.1","type":"blocks","created_at":"2026-02-11T17:12:27.2225981-08:00","created_by":"zenchantlive"}]}
{"id":"bb-6aj.3.1","title":"Add explicit full-drive scan mode for C:/D: by user action","description":"Provide an opt-in scan mode for full drive enumeration while retaining safe defaults and progress reporting expectations.","acceptance_criteria":"Full-drive scan is only activated explicitly, never by default startup logic.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:51.0244174-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:51.0244174-08:00","labels":["optional","scanner"],"dependencies":[{"issue_id":"bb-6aj.3.1","depends_on_id":"bb-6aj.3","type":"parent-child","created_at":"2026-02-11T17:11:51.0259617-08:00","created_by":"zenchantlive"}]}
{"id":"bb-6aj.4","title":"Implement aggregate project issue context model","description":"Define normalized project identity payload attached to every issue for cross-project Kanban, timeline, and session views.","acceptance_criteria":"Aggregated read output always includes stable project metadata.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:51.8518922-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:51.8518922-08:00","labels":["aggregation","data-model"],"dependencies":[{"issue_id":"bb-6aj.4","depends_on_id":"bb-6aj","type":"parent-child","created_at":"2026-02-11T17:11:51.8534893-08:00","created_by":"zenchantlive"},{"issue_id":"bb-6aj.4","depends_on_id":"bb-6aj.2","type":"blocks","created_at":"2026-02-11T17:12:27.7270195-08:00","created_by":"zenchantlive"}]}
{"id":"bb-92d","title":"Foundation and Read/Write Boundary","description":"Establish the Windows-native Next.js foundation, canonical Beads schema handling, and strict data boundaries: read from JSONL, write only via bd.exe. This epic defines the non-negotiable invariants that all later work must preserve.","acceptance_criteria":"App boots on Windows, schema/parser contracts exist, and no direct issues.jsonl write path exists in code.","status":"closed","priority":0,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:41.0756295-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:28:27.8108066-08:00","closed_at":"2026-02-11T17:28:27.8108066-08:00","close_reason":"Completed foundation milestone: bootstrap, licensing/docs, schema contracts, parser, windows path normalization, and write-boundary guardrails.","labels":["beadboard","foundation","windows"]}
{"id":"bb-92d.1","title":"Bootstrap Next.js 15 + React 19 + TypeScript strict","description":"Initialize project scaffold with strict TypeScript, App Router baseline, and repeatable scripts for lint/typecheck/test in PowerShell.","acceptance_criteria":"npm install and dev startup work on Windows; strict type checking enabled.","status":"closed","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:41.9363647-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:23:14.0089901-08:00","closed_at":"2026-02-11T17:23:14.0089901-08:00","close_reason":"Bootstrapped Next.js 15 + React 19 + strict TypeScript; install/typecheck/dev startup verified on Windows.","labels":["foundation","nextjs"],"dependencies":[{"issue_id":"bb-92d.1","depends_on_id":"bb-92d","type":"parent-child","created_at":"2026-02-11T17:11:41.9379355-08:00","created_by":"zenchantlive"}]}
{"id":"bb-92d.2","title":"Add MIT license and baseline repository docs","description":"Add LICENSE and baseline docs that state Windows-native support, read/write boundaries, and required runtime dependencies.","acceptance_criteria":"MIT license present and docs describe core architecture constraints.","status":"closed","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:42.7699961-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:23:50.7519159-08:00","closed_at":"2026-02-11T17:23:50.7519159-08:00","close_reason":"Added MIT license and baseline repository documentation with architecture boundary rules.","labels":["docs","license"],"dependencies":[{"issue_id":"bb-92d.2","depends_on_id":"bb-92d","type":"parent-child","created_at":"2026-02-11T17:11:42.7715653-08:00","created_by":"zenchantlive"}]}
{"id":"bb-92d.3","title":"Define canonical Beads TypeScript schema types","description":"Implement comprehensive issue types covering ids, status, priority, dependencies, timestamps, metadata, and session fields used by dashboard views.","acceptance_criteria":"All required PRD fields are represented and reused across parser/API/UI layers.","status":"closed","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:43.6016519-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:24:57.9851942-08:00","closed_at":"2026-02-11T17:24:57.9851942-08:00","close_reason":"Added canonical Beads TypeScript schema contracts and validated via typecheck contract test.","labels":["schema","types"],"dependencies":[{"issue_id":"bb-92d.3","depends_on_id":"bb-92d","type":"parent-child","created_at":"2026-02-11T17:11:43.6032338-08:00","created_by":"zenchantlive"}]}
{"id":"bb-92d.4","title":"Implement JSONL parser with defaults and malformed-line tolerance","description":"Parse one JSON object per line, skip blank/malformed lines, apply default status/type/priority, preserve priority=0, and filter tombstones by default.","acceptance_criteria":"Parser tests cover malformed lines, defaults, and tombstone behavior.","status":"closed","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:44.4153013-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:26:37.2602624-08:00","closed_at":"2026-02-11T17:26:37.2602624-08:00","close_reason":"Implemented JSONL parser with schema defaults, malformed-line tolerance, and tombstone filtering options.","labels":["jsonl","parser"],"dependencies":[{"issue_id":"bb-92d.4","depends_on_id":"bb-92d","type":"parent-child","created_at":"2026-02-11T17:11:44.4168806-08:00","created_by":"zenchantlive"},{"issue_id":"bb-92d.4","depends_on_id":"bb-92d.3","type":"blocks","created_at":"2026-02-11T17:12:25.6958301-08:00","created_by":"zenchantlive"}]}
{"id":"bb-92d.4.1","title":"Add parser tests for priority=0, tombstone filtering, and dependency parsing","description":"Create focused tests that protect parser behavior for critical edge cases and dependency structures used by graph/timeline views.","acceptance_criteria":"Tests fail before implementation and pass after parser is complete.","status":"closed","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:45.2638563-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:26:36.8997779-08:00","closed_at":"2026-02-11T17:26:36.8997779-08:00","close_reason":"Added parser behavior tests for defaults, malformed lines, tombstones, and priority=0.","labels":["parser","tests"],"dependencies":[{"issue_id":"bb-92d.4.1","depends_on_id":"bb-92d.4","type":"parent-child","created_at":"2026-02-11T17:11:45.2654252-08:00","created_by":"zenchantlive"}]}
{"id":"bb-92d.5","title":"Implement Windows path normalization utilities","description":"Create centralized helpers for canonical path keys, display formatting, and cross-drive normalization to avoid duplicate project identities.","acceptance_criteria":"Canonicalization is consistent for C:\\ and D:\\ style paths.","status":"closed","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:46.0751161-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:27:27.7164974-08:00","closed_at":"2026-02-11T17:27:27.7164974-08:00","close_reason":"Implemented Windows path normalization utilities with canonicalization, keying, and display transformations.","labels":["paths","windows"],"dependencies":[{"issue_id":"bb-92d.5","depends_on_id":"bb-92d","type":"parent-child","created_at":"2026-02-11T17:11:46.0767429-08:00","created_by":"zenchantlive"}]}
{"id":"bb-92d.6","title":"Add guardrail test preventing direct writes to .beads/issues.jsonl","description":"Enforce read/write boundary by scanning source for forbidden direct file write patterns targeting Beads issue files.","acceptance_criteria":"Guardrail test fails on boundary violations and passes when write path uses bd bridge only.","status":"closed","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:46.9013352-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:28:27.4699395-08:00","closed_at":"2026-02-11T17:28:27.4699395-08:00","close_reason":"Added guardrail scanner and automated test to block direct writes to .beads/issues.jsonl.","labels":["guardrail","safety"],"dependencies":[{"issue_id":"bb-92d.6","depends_on_id":"bb-92d","type":"parent-child","created_at":"2026-02-11T17:11:46.9029535-08:00","created_by":"zenchantlive"}]}
{"id":"bb-ag8","title":"TEMP_DELETE_ME","status":"closed","priority":4,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:10:04.5765506-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:10:10.3812634-08:00","closed_at":"2026-02-11T17:10:10.3812634-08:00","close_reason":"cleanup temp test issue"}
{"id":"bb-bvn","title":"Dependency Graph (React Flow)","description":"Visualize issue relationships and blocked chains through an interactive graph backed by parsed dependency edges.","acceptance_criteria":"Graph renders dependencies correctly and supports navigation to issue details.","status":"open","priority":2,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:09.2057278-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:09.2057278-08:00","labels":["graph","react-flow"],"dependencies":[{"issue_id":"bb-bvn","depends_on_id":"bb-trz","type":"blocks","created_at":"2026-02-11T17:12:22.6642419-08:00","created_by":"zenchantlive"}]}
{"id":"bb-bvn.1","title":"Parse dependency edges and build adjacency structures","description":"Extract edges for blocks, parent, relates_to, duplicates, and supersedes to support graph rendering and analysis.","acceptance_criteria":"Adjacency output is complete and consistent for all supported edge types.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:10.0434044-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:10.0434044-08:00","labels":["graph","parser"],"dependencies":[{"issue_id":"bb-bvn.1","depends_on_id":"bb-bvn","type":"parent-child","created_at":"2026-02-11T17:12:10.0449367-08:00","created_by":"zenchantlive"}]}
{"id":"bb-bvn.2","title":"Implement React Flow graph view with pan/zoom/select interactions","description":"Render nodes and edges with interactive navigation and issue selection integration.","acceptance_criteria":"Users can pan, zoom, and select nodes to inspect linked issue context.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:10.8683725-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:10.8683725-08:00","labels":["graph","ui"],"dependencies":[{"issue_id":"bb-bvn.2","depends_on_id":"bb-bvn","type":"parent-child","created_at":"2026-02-11T17:12:10.8694189-08:00","created_by":"zenchantlive"},{"issue_id":"bb-bvn.2","depends_on_id":"bb-bvn.1","type":"blocks","created_at":"2026-02-11T17:12:36.8736785-08:00","created_by":"zenchantlive"}]}
{"id":"bb-bvn.3","title":"Add blocked-chain highlighting and cycle anomaly signaling","description":"Improve graph decision support by emphasizing blocked paths and flagging unexpected cycle conditions.","acceptance_criteria":"Blocked paths and cycle warnings are visible and actionable.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:11.687878-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:11.687878-08:00","labels":["analysis","graph"],"dependencies":[{"issue_id":"bb-bvn.3","depends_on_id":"bb-bvn","type":"parent-child","created_at":"2026-02-11T17:12:11.6890831-08:00","created_by":"zenchantlive"},{"issue_id":"bb-bvn.3","depends_on_id":"bb-bvn.2","type":"blocks","created_at":"2026-02-11T17:12:37.378326-08:00","created_by":"zenchantlive"}]}
{"id":"bb-tpc","title":"Live File Watching and SSE Transport","description":"Deliver real-time dashboard updates by watching Beads issue files and streaming one-way change notifications via SSE.","acceptance_criteria":"File changes trigger UI refresh without manual reload and reconnect behavior is stable.","status":"open","priority":0,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:52.6737283-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:52.6737283-08:00","labels":["realtime","sse","watcher"],"dependencies":[{"issue_id":"bb-tpc","depends_on_id":"bb-6aj","type":"blocks","created_at":"2026-02-11T17:12:20.1444149-08:00","created_by":"zenchantlive"}]}
{"id":"bb-tpc.1","title":"Implement chokidar watch manager for registered projects","description":"Start/stop watchers per active project and ensure watcher lifecycle tracks registry changes without leaking handles.","acceptance_criteria":"Watcher list updates correctly when projects are added or removed.","status":"open","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:53.5050717-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:53.5050717-08:00","labels":["chokidar","watcher"],"dependencies":[{"issue_id":"bb-tpc.1","depends_on_id":"bb-tpc","type":"parent-child","created_at":"2026-02-11T17:11:53.5071586-08:00","created_by":"zenchantlive"},{"issue_id":"bb-tpc.1","depends_on_id":"bb-6aj.2","type":"blocks","created_at":"2026-02-11T17:12:28.2304516-08:00","created_by":"zenchantlive"}]}
{"id":"bb-tpc.2","title":"Add debounce/coalescing and transient lock handling for file change bursts","description":"Coalesce rapid updates from agent activity and handle temporary read lock contention without surfacing noisy errors.","acceptance_criteria":"Burst writes produce stable event cadence and no hard failures from temporary locks.","status":"open","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:54.315119-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:54.315119-08:00","labels":["stability","watcher"],"dependencies":[{"issue_id":"bb-tpc.2","depends_on_id":"bb-tpc","type":"parent-child","created_at":"2026-02-11T17:11:54.3172104-08:00","created_by":"zenchantlive"},{"issue_id":"bb-tpc.2","depends_on_id":"bb-tpc.1","type":"blocks","created_at":"2026-02-11T17:12:28.7308524-08:00","created_by":"zenchantlive"}]}
{"id":"bb-tpc.3","title":"Implement SSE events API endpoint with heartbeat and event IDs","description":"Create SSE route supporting keepalive heartbeats and resumable event consumption patterns for browser clients.","acceptance_criteria":"SSE stream remains alive and clients can reconnect automatically.","status":"open","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:55.1518352-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:55.1518352-08:00","labels":["api","sse"],"dependencies":[{"issue_id":"bb-tpc.3","depends_on_id":"bb-tpc","type":"parent-child","created_at":"2026-02-11T17:11:55.1533991-08:00","created_by":"zenchantlive"},{"issue_id":"bb-tpc.3","depends_on_id":"bb-tpc.2","type":"blocks","created_at":"2026-02-11T17:12:29.2599782-08:00","created_by":"zenchantlive"}]}
{"id":"bb-tpc.4","title":"Build frontend SSE client with scoped React Query invalidation","description":"Consume server events and invalidate only affected query keys, limiting unnecessary re-fetches in multi-project mode.","acceptance_criteria":"Changed project views refresh while unrelated views remain stable.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:56.0008015-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:56.0008015-08:00","labels":["frontend","react-query"],"dependencies":[{"issue_id":"bb-tpc.4","depends_on_id":"bb-tpc","type":"parent-child","created_at":"2026-02-11T17:11:56.0024218-08:00","created_by":"zenchantlive"},{"issue_id":"bb-tpc.4","depends_on_id":"bb-tpc.3","type":"blocks","created_at":"2026-02-11T17:12:29.768818-08:00","created_by":"zenchantlive"}]}
{"id":"bb-trz","title":"Kanban Experience (Baseline Dashboard)","description":"Ship a production-ready Kanban baseline inspired by prototype behavior but backed by real Beads project data and strict typing.","acceptance_criteria":"Users can inspect and filter live Beads issues through stable Kanban workflows.","status":"open","priority":1,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:56.8115491-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:11:56.8115491-08:00","labels":["kanban","ui"],"dependencies":[{"issue_id":"bb-trz","depends_on_id":"bb-92d","type":"blocks","created_at":"2026-02-11T17:12:20.6480287-08:00","created_by":"zenchantlive"}]}
{"id":"bb-trz.1","title":"Implement Kanban column layout for Beads statuses","description":"Render columns for open, in_progress, blocked, deferred, and closed with responsive behavior and clear status counts.","acceptance_criteria":"All statuses map correctly and render with stable ordering.","status":"in_progress","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:57.6278082-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:41:44.604363-08:00","labels":["columns","kanban"],"dependencies":[{"issue_id":"bb-trz.1","depends_on_id":"bb-trz","type":"parent-child","created_at":"2026-02-11T17:11:57.6288535-08:00","created_by":"zenchantlive"},{"issue_id":"bb-trz.1","depends_on_id":"bb-92d.4","type":"blocks","created_at":"2026-02-11T17:12:30.2796473-08:00","created_by":"zenchantlive"}]}
{"id":"bb-trz.2","title":"Build bead cards with priority/type/labels/assignee/dependency metadata","description":"Design compact cards exposing the most actionable issue metadata while preserving readability at high board density.","acceptance_criteria":"Cards show id, priority, type, labels, assignee, and dependency indicators.","status":"in_progress","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:58.4435327-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:41:46.1569931-08:00","labels":["cards","kanban"],"dependencies":[{"issue_id":"bb-trz.2","depends_on_id":"bb-trz","type":"parent-child","created_at":"2026-02-11T17:11:58.4450798-08:00","created_by":"zenchantlive"},{"issue_id":"bb-trz.2","depends_on_id":"bb-trz.1","type":"blocks","created_at":"2026-02-11T17:12:30.7837277-08:00","created_by":"zenchantlive"}]}
{"id":"bb-trz.3","title":"Implement detail slide-out panel with full issue metadata","description":"Add focused issue detail panel showing description, timestamps, dependencies, and lifecycle fields used by power users.","acceptance_criteria":"Selecting a card opens detail panel with complete issue context.","status":"in_progress","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:11:59.2746013-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:41:44.9885171-08:00","labels":["details","kanban"],"dependencies":[{"issue_id":"bb-trz.3","depends_on_id":"bb-trz","type":"parent-child","created_at":"2026-02-11T17:11:59.2756402-08:00","created_by":"zenchantlive"},{"issue_id":"bb-trz.3","depends_on_id":"bb-trz.2","type":"blocks","created_at":"2026-02-11T17:12:31.2944-08:00","created_by":"zenchantlive"}]}
{"id":"bb-trz.4","title":"Add search/filter/stats controls for status/type/priority/labels","description":"Provide fast filtering and at-a-glance counts, including critical issue indicators, for daily planning and triage workflows.","acceptance_criteria":"Search and filters apply consistently across board and counts.","status":"in_progress","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:00.0927161-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:41:45.8866335-08:00","labels":["filters","stats"],"dependencies":[{"issue_id":"bb-trz.4","depends_on_id":"bb-trz","type":"parent-child","created_at":"2026-02-11T17:12:00.0942721-08:00","created_by":"zenchantlive"},{"issue_id":"bb-trz.4","depends_on_id":"bb-trz.2","type":"blocks","created_at":"2026-02-11T17:12:31.798413-08:00","created_by":"zenchantlive"}]}
{"id":"bb-u6f","title":"Agent Session Views and Metrics","description":"Group work by agent session and actor fields to provide auditability and practical productivity insights for asynchronous coding workflows.","acceptance_criteria":"Session-based summaries and detail views are available per project and aggregate contexts.","status":"open","priority":2,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:12.5083912-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:12.5083912-08:00","labels":["agents","sessions"],"dependencies":[{"issue_id":"bb-u6f","depends_on_id":"bb-tpc","type":"blocks","created_at":"2026-02-11T17:12:23.1727361-08:00","created_by":"zenchantlive"}]}
{"id":"bb-u6f.1","title":"Extract and normalize session identity fields from issue data","description":"Derive session grouping from closed_by_session, assignee, and created_by with robust fallback semantics.","acceptance_criteria":"Issues are consistently assigned to session buckets when data exists.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:13.3239834-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:13.3239834-08:00","labels":["agents","data"],"dependencies":[{"issue_id":"bb-u6f.1","depends_on_id":"bb-u6f","type":"parent-child","created_at":"2026-02-11T17:12:13.3255058-08:00","created_by":"zenchantlive"}]}
{"id":"bb-u6f.2","title":"Build session list and detail views for claimed/completed/open outcomes","description":"Present session-level issue outcomes and navigation for operational review and accountability.","acceptance_criteria":"Users can inspect session summaries and drill into individual session issue sets.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:14.1559358-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:14.1559358-08:00","labels":["agents","ui"],"dependencies":[{"issue_id":"bb-u6f.2","depends_on_id":"bb-u6f","type":"parent-child","created_at":"2026-02-11T17:12:14.157502-08:00","created_by":"zenchantlive"},{"issue_id":"bb-u6f.2","depends_on_id":"bb-u6f.1","type":"blocks","created_at":"2026-02-11T17:12:37.9045555-08:00","created_by":"zenchantlive"}]}
{"id":"bb-u6f.3","title":"Add baseline productivity metrics (completion rate, throughput, active span)","description":"Compute lightweight operational metrics from session issue events and timestamps.","acceptance_criteria":"Metrics are available with documented definitions and caveats.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:15.0144056-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:15.0144056-08:00","labels":["agents","metrics"],"dependencies":[{"issue_id":"bb-u6f.3","depends_on_id":"bb-u6f","type":"parent-child","created_at":"2026-02-11T17:12:15.0155323-08:00","created_by":"zenchantlive"},{"issue_id":"bb-u6f.3","depends_on_id":"bb-u6f.2","type":"blocks","created_at":"2026-02-11T17:12:38.4424336-08:00","created_by":"zenchantlive"}]}
{"id":"bb-xhm","title":"Timeline and Activity Feed","description":"Provide a chronological activity view derived from issue snapshots and updates, enabling users to review agent/system activity over time.","acceptance_criteria":"Users can inspect chronological issue lifecycle events with useful filtering.","status":"open","priority":2,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:05.8525088-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:05.8525088-08:00","labels":["activity","timeline"],"dependencies":[{"issue_id":"bb-xhm","depends_on_id":"bb-tpc","type":"blocks","created_at":"2026-02-11T17:12:22.1602338-08:00","created_by":"zenchantlive"}]}
{"id":"bb-xhm.1","title":"Define activity event model for created/updated/closed/reopened actions","description":"Create stable event schema to represent issue lifecycle transitions and their project/session attribution.","acceptance_criteria":"Event model supports all required timeline activity types.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:06.6781387-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:06.6781387-08:00","labels":["model","timeline"],"dependencies":[{"issue_id":"bb-xhm.1","depends_on_id":"bb-xhm","type":"parent-child","created_at":"2026-02-11T17:12:06.6791721-08:00","created_by":"zenchantlive"}]}
{"id":"bb-xhm.2","title":"Implement snapshot diffing for derived timeline events","description":"Compare periodic snapshots and watcher updates to infer meaningful change events without requiring write interception.","acceptance_criteria":"Diff engine emits deterministic event records for relevant field changes.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:07.5007059-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:07.5007059-08:00","labels":["diff","timeline"],"dependencies":[{"issue_id":"bb-xhm.2","depends_on_id":"bb-xhm","type":"parent-child","created_at":"2026-02-11T17:12:07.501756-08:00","created_by":"zenchantlive"},{"issue_id":"bb-xhm.2","depends_on_id":"bb-xhm.1","type":"blocks","created_at":"2026-02-11T17:12:35.3430513-08:00","created_by":"zenchantlive"},{"issue_id":"bb-xhm.2","depends_on_id":"bb-tpc.2","type":"blocks","created_at":"2026-02-11T17:12:35.8495336-08:00","created_by":"zenchantlive"}]}
{"id":"bb-xhm.3","title":"Build timeline UI with date grouping and project/assignee/event filters","description":"Render reverse-chronological feed suitable for morning review workflows with practical filter controls.","acceptance_criteria":"Timeline view supports grouping and filter combinations with acceptable performance.","status":"open","priority":2,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:08.3834905-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:08.3834905-08:00","labels":["timeline","ui"],"dependencies":[{"issue_id":"bb-xhm.3","depends_on_id":"bb-xhm","type":"parent-child","created_at":"2026-02-11T17:12:08.3851144-08:00","created_by":"zenchantlive"},{"issue_id":"bb-xhm.3","depends_on_id":"bb-xhm.2","type":"blocks","created_at":"2026-02-11T17:12:36.3627477-08:00","created_by":"zenchantlive"}]}
{"id":"bb-ymg","title":"CLI Write-Back via bd.exe","description":"Enable safe issue mutations from UI by routing all write operations through bd.exe and reflecting results through realtime reconciliation.","acceptance_criteria":"No direct JSONL writes exist; all mutations use bd commands and recover cleanly from failures.","status":"open","priority":1,"issue_type":"epic","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:00.9164956-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:00.9164956-08:00","labels":["bd-cli","mutation"],"dependencies":[{"issue_id":"bb-ymg","depends_on_id":"bb-trz","type":"blocks","created_at":"2026-02-11T17:12:21.1512868-08:00","created_by":"zenchantlive"},{"issue_id":"bb-ymg","depends_on_id":"bb-tpc","type":"blocks","created_at":"2026-02-11T17:12:21.6536312-08:00","created_by":"zenchantlive"}]}
{"id":"bb-ymg.1","title":"Implement bd bridge using child_process.execFile with project-scoped cwd","description":"Wrap bd execution with command argument safety, Windows path compatibility, stdout/stderr parsing, and project-specific current working directory.","acceptance_criteria":"Bridge executes supported bd commands and returns structured result/error payloads.","status":"open","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:01.7327732-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:01.7327732-08:00","labels":["bridge","execfile"],"dependencies":[{"issue_id":"bb-ymg.1","depends_on_id":"bb-ymg","type":"parent-child","created_at":"2026-02-11T17:12:01.7343468-08:00","created_by":"zenchantlive"},{"issue_id":"bb-ymg.1","depends_on_id":"bb-6aj.2","type":"blocks","created_at":"2026-02-11T17:12:32.3039711-08:00","created_by":"zenchantlive"}]}
{"id":"bb-ymg.1.1","title":"Resolve bd.exe location from PATH and configuration fallback","description":"Add detection logic for bd executable and actionable errors when not found, including setup guidance.","acceptance_criteria":"Missing bd path returns clear setup instructions and diagnostics.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:02.5593205-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:02.5593205-08:00","labels":["bridge","setup"],"dependencies":[{"issue_id":"bb-ymg.1.1","depends_on_id":"bb-ymg.1","type":"parent-child","created_at":"2026-02-11T17:12:02.5603636-08:00","created_by":"zenchantlive"}]}
{"id":"bb-ymg.2","title":"Implement mutation API for create/update/close/reopen/comment operations","description":"Expose strict server-side mutation endpoints translating UI actions to corresponding bd commands with validated arguments.","acceptance_criteria":"All required mutation operations execute via bd and return normalized responses.","status":"open","priority":0,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:03.3757503-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:03.3757503-08:00","labels":["api","mutation"],"dependencies":[{"issue_id":"bb-ymg.2","depends_on_id":"bb-ymg","type":"parent-child","created_at":"2026-02-11T17:12:03.377343-08:00","created_by":"zenchantlive"},{"issue_id":"bb-ymg.2","depends_on_id":"bb-ymg.1","type":"blocks","created_at":"2026-02-11T17:12:32.810993-08:00","created_by":"zenchantlive"},{"issue_id":"bb-ymg.2","depends_on_id":"bb-ymg.1.1","type":"blocks","created_at":"2026-02-11T17:12:33.313807-08:00","created_by":"zenchantlive"}]}
{"id":"bb-ymg.3","title":"Add optimistic updates with rollback and SSE reconciliation","description":"Apply immediate UI updates for responsiveness, rollback on command failure, and reconcile with watcher-triggered authoritative state updates.","acceptance_criteria":"Failed mutations restore previous UI state and emit meaningful error feedback.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:04.1956393-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:04.1956393-08:00","labels":["optimistic","state"],"dependencies":[{"issue_id":"bb-ymg.3","depends_on_id":"bb-ymg","type":"parent-child","created_at":"2026-02-11T17:12:04.1966728-08:00","created_by":"zenchantlive"},{"issue_id":"bb-ymg.3","depends_on_id":"bb-ymg.2","type":"blocks","created_at":"2026-02-11T17:12:33.8246167-08:00","created_by":"zenchantlive"}]}
{"id":"bb-ymg.4","title":"Implement drag-and-drop status transitions mapped to bd commands","description":"Map card moves to valid status transitions and use close/reopen semantics where applicable instead of direct file manipulation.","acceptance_criteria":"DnD transitions call proper bd commands and reject invalid transitions safely.","status":"open","priority":1,"issue_type":"task","owner":"jordanlive121@gmail.com","created_at":"2026-02-11T17:12:05.0129676-08:00","created_by":"zenchantlive","updated_at":"2026-02-11T17:12:05.0129676-08:00","labels":["dnd","kanban"],"dependencies":[{"issue_id":"bb-ymg.4","depends_on_id":"bb-ymg","type":"parent-child","created_at":"2026-02-11T17:12:05.014527-08:00","created_by":"zenchantlive"},{"issue_id":"bb-ymg.4","depends_on_id":"bb-ymg.2","type":"blocks","created_at":"2026-02-11T17:12:34.329788-08:00","created_by":"zenchantlive"},{"issue_id":"bb-ymg.4","depends_on_id":"bb-trz.1","type":"blocks","created_at":"2026-02-11T17:12:34.8422542-08:00","created_by":"zenchantlive"}]}

4
.beads/metadata.json Normal file
View file

@ -0,0 +1,4 @@
{
"database": "beads.db",
"jsonl_export": "issues.jsonl"
}

3
.gitattributes vendored Normal file
View file

@ -0,0 +1,3 @@
# Use bd merge for beads JSONL files
.beads/issues.jsonl merge=beads

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
node_modules/
.next/
*.tsbuildinfo
.worktrees/
worktrees/

40
AGENTS.md Normal file
View file

@ -0,0 +1,40 @@
# Agent Instructions
This project uses **bd** (beads) for issue tracking. Run `bd onboard` to get started.
## Quick Reference
```bash
bd ready # Find available work
bd show <id> # View issue details
bd update <id> --status in_progress # Claim work
bd close <id> # Complete work
bd sync # Sync with git
```
## Landing the Plane (Session Completion)
**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
**MANDATORY WORKFLOW:**
1. **File issues for remaining work** - Create issues for anything that needs follow-up
2. **Run quality gates** (if code changed) - Tests, linters, builds
3. **Update issue status** - Close finished work, update in-progress items
4. **PUSH TO REMOTE** - This is MANDATORY:
```bash
git pull --rebase
bd sync
git push
git status # MUST show "up to date with origin"
```
5. **Clean up** - Clear stashes, prune remote branches
6. **Verify** - All changes committed AND pushed
7. **Hand off** - Provide context for next session
**CRITICAL RULES:**
- Work is NOT complete until `git push` succeeds
- NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 Zenchant
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

23
README.md Normal file
View file

@ -0,0 +1,23 @@
# BeadBoard
Windows-native Beads dashboard built with Next.js 15, React 19, and TypeScript.
## Core Rules
- Read source of truth from `.beads/issues.jsonl`.
- Perform all writes through `bd.exe`.
- Never write directly to `.beads/issues.jsonl`.
- Use Windows-safe path normalization for all project path operations.
## Stack
- Next.js 15 (App Router)
- React 19
- TypeScript (strict)
## Local Development
- `npm install`
- `npm run dev`
- `npm run typecheck`
- `npm run test`
## Scope
BeadBoard provides Kanban, dependency graph, timeline, and agent-session views over one or more registered Windows project roots.

View file

@ -0,0 +1,260 @@
# BeadBoard Implementation Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Build a Windows-native Beads dashboard that reads `.beads/issues.jsonl` directly and performs all mutations through `bd.exe`.
**Architecture:** The app uses Next.js App Router APIs for filesystem reads, project scanning, watcher lifecycle, SSE broadcasting, and CLI mutation bridging. Frontend uses React Query for server-state synchronization and Zustand for UI-local state plus optimistic transition coordination. Windows path normalization is centralized and enforced at all boundaries to prevent cross-drive and casing inconsistencies.
**Tech Stack:** Next.js 15, React 19, TypeScript (strict), Tailwind CSS, Zustand, TanStack Query, chokidar, React Flow, `child_process.execFile`.
---
### Task 1: Repository Bootstrap and Runtime Guardrails
**Files:**
- Create: `package.json`
- Create: `tsconfig.json`
- Create: `next.config.ts`
- Create: `LICENSE`
- Create: `src/app/layout.tsx`
- Create: `src/app/page.tsx`
**Step 1: Write failing environment checks**
- Add a smoke test placeholder for app boot and runtime config verification.
**Step 2: Run verification to confirm missing implementation**
- Run: `npm run test` (expected to fail before setup).
**Step 3: Implement minimal app bootstrap**
- Initialize Next.js 15 + React 19 + TypeScript strict setup.
- Add MIT license file.
**Step 4: Re-run checks**
- Run: `npm run lint` and `npm run typecheck`.
**Step 5: Commit**
- Commit message: `chore: bootstrap beadboard foundation`
### Task 2: Canonical Types and JSONL Parser
**Files:**
- Create: `src/lib/types.ts`
- Create: `src/lib/parser.ts`
- Create: `tests/lib/parser.test.ts`
**Step 1: Write failing parser tests**
- Cover defaults, malformed lines, tombstone filtering, `priority=0` preservation.
**Step 2: Run targeted test**
- Run: `npm run test -- tests/lib/parser.test.ts` (expected fail).
**Step 3: Implement parser + DTO normalization**
- Parse one JSON object per line, skip malformed lines, apply defaults.
**Step 4: Run tests**
- Run parser tests and full typecheck.
**Step 5: Commit**
- Commit message: `feat: add beads schema and robust jsonl parser`
### Task 3: Windows Pathing + Project Registry
**Files:**
- Create: `src/lib/pathing.ts`
- Create: `src/lib/projects-registry.ts`
- Create: `src/app/api/projects/route.ts`
- Test: `tests/lib/pathing.test.ts`
**Step 1: Write failing path tests**
- Validate canonicalization for `C:\` and `D:\`, stable key generation.
**Step 2: Implement path utility + registry persistence**
- Use `%USERPROFILE%\\.beadboard\\projects.json` as registry location.
**Step 3: Implement API route**
- Support add/list/remove with validation and normalized identity.
**Step 4: Verify**
- Run path tests + API handler tests.
**Step 5: Commit**
- Commit message: `feat: add windows path normalization and project registry`
### Task 4: Read API and Multi-Project Aggregation
**Files:**
- Create: `src/app/api/beads/route.ts`
- Create: `src/lib/read-service.ts`
- Test: `tests/api/beads-route.test.ts`
**Step 1: Write failing API tests**
- Single project read, aggregate read, filter params, error behavior.
**Step 2: Implement read service**
- Read `.beads/issues.jsonl` directly via `fs`.
**Step 3: Implement route layer**
- Query support for project, status, type, priority, assignee, label.
**Step 4: Verify**
- Run route tests and typecheck.
**Step 5: Commit**
- Commit message: `feat: add beads read api for single and aggregate views`
### Task 5: Scanner and Discovery Controls
**Files:**
- Create: `src/lib/scanner.ts`
- Create: `src/app/api/scan/route.ts`
- Test: `tests/lib/scanner.test.ts`
**Step 1: Write failing scanner tests**
- Depth limits, ignore patterns, profile-root default behavior.
**Step 2: Implement scanner**
- Default root `%USERPROFILE%`, plus user-added roots.
- Add explicit full-drive mode action.
**Step 3: Implement scan API**
- Trigger scan + return discovered project candidates.
**Step 4: Verify**
- Run scanner tests.
**Step 5: Commit**
- Commit message: `feat: add windows-safe project scanner and scan api`
### Task 6: Watcher + SSE Event Bus
**Files:**
- Create: `src/lib/watcher.ts`
- Create: `src/lib/sse-bus.ts`
- Create: `src/app/api/events/route.ts`
- Test: `tests/lib/watcher.test.ts`
**Step 1: Write failing watcher tests**
- Debounced change emission, lock retry behavior, multi-project handling.
**Step 2: Implement watcher manager**
- Chokidar watchers for registered projects.
**Step 3: Implement SSE endpoint**
- Heartbeat, reconnect-safe events, project-scoped payloads.
**Step 4: Verify**
- Run watcher/event tests.
**Step 5: Commit**
- Commit message: `feat: add live file watching and sse updates`
### Task 7: bd.exe Mutation Bridge + API
**Files:**
- Create: `src/lib/bd-bridge.ts`
- Create: `src/app/api/mutate/route.ts`
- Test: `tests/lib/bd-bridge.test.ts`
**Step 1: Write failing bridge tests**
- Command invocation, cwd routing, stdout/stderr error mapping.
**Step 2: Implement execFile bridge**
- Resolve `bd.exe` from PATH, enforce project CWD, parse outputs.
**Step 3: Implement mutate API**
- `create`, `update`, `close`, `reopen`, `comment` actions.
**Step 4: Verify**
- Run bridge tests and mutation route tests.
**Step 5: Commit**
- Commit message: `feat: add bd cli mutation bridge and api`
### Task 8: Frontend State and Realtime Sync
**Files:**
- Create: `src/lib/query-client.ts`
- Create: `src/lib/store.ts`
- Create: `src/lib/sse-client.ts`
- Modify: `src/app/layout.tsx`
**Step 1: Write failing state tests**
- Query invalidation + optimistic rollback cases.
**Step 2: Implement Query + Zustand providers**
- Distinguish server cache from UI-local state.
**Step 3: Implement SSE client integration**
- Auto reconnect and scoped invalidation for changed projects.
**Step 4: Verify**
- Run state/integration tests.
**Step 5: Commit**
- Commit message: `feat: wire react-query zustand and realtime invalidation`
### Task 9: Feature Views (Kanban, Graph, Timeline, Sessions)
**Files:**
- Create: `src/components/kanban/*`
- Create: `src/components/graph/*`
- Create: `src/components/timeline/*`
- Create: `src/components/agents/*`
- Create: `src/app/graph/page.tsx`
- Create: `src/app/timeline/page.tsx`
- Create: `src/app/agents/page.tsx`
**Step 1: Write failing UI tests**
- Column rendering, card detail open, graph node interaction, timeline grouping.
**Step 2: Implement Kanban baseline**
- Columns, card metadata, details panel, filters/stats.
**Step 3: Implement Graph with React Flow**
- Edges from dependencies, pan/zoom/select, blocked-chain highlighting.
**Step 4: Implement Timeline + Session views**
- Derived activity and session grouping/metrics.
**Step 5: Verify**
- Run component tests and visual smoke check.
**Step 6: Commit**
- Commit message: `feat: deliver dashboard views for kanban graph timeline and sessions`
### Task 10: Quality Gates and Boundary Enforcement
**Files:**
- Create: `tests/guards/no-direct-jsonl-write.test.ts`
- Create: `docs/architecture/read-write-boundary.md`
- Modify: `package.json`
**Step 1: Write failing guard test**
- Detect direct writes to `.beads/issues.jsonl` in application code.
**Step 2: Implement boundary guard tooling**
- Add CI script and local verification command.
**Step 3: Add performance checks**
- Parser benchmark and SSE latency smoke measurements.
**Step 4: Verify full pipeline**
- Run `npm run lint && npm run typecheck && npm run test`.
**Step 5: Commit**
- Commit message: `chore: enforce read-write boundaries and quality gates`
## Execution Sequence and Parallelization
- Sequential core chain: Task 1 -> Task 2 -> Task 3 -> Task 4 -> Task 6 -> Task 7 -> Task 8
- Parallel branch A (after Task 3): Task 5
- Parallel branch B (after Task 4 and Task 8): Task 9
- Final gate: Task 10
## Completion Criteria
- Windows-native workflow validated in PowerShell/CMD
- Reads from JSONL only
- Mutations executed only via `bd.exe`
- Real-time updates delivered via SSE
- Kanban, Graph, Timeline, Agent Session views functional
- Boundary guard test prevents direct JSONL writes

View file

@ -0,0 +1,162 @@
# BeadBoard Product Requirements Document (PRD)
Version: 1.1
Date: February 12, 2026
License: MIT
## 1. Product Summary
BeadBoard is a Windows-native web dashboard for Beads that provides a unified interface for Kanban planning, dependency visualization, timeline auditing, and agent-session tracking across multiple projects.
The app must run without WSL and without Unix-only shell assumptions. It reads Beads data directly from `.beads/issues.jsonl` and performs all mutations through `bd.exe`.
## 2. Problem Statement
Current Beads ecosystem tools are often Unix/macOS oriented, creating friction for Windows-native development flows. Users need:
- Native Windows path support (`C:\...`, `D:\...`)
- Multi-project visibility in one dashboard
- Real-time monitoring of agent activity
- A strict read/write boundary that preserves Beads/Dolt consistency
## 3. Goals
- Build a modern dashboard on Next.js 15 + React 19 + TypeScript
- Use `.beads/issues.jsonl` as source of truth for reads
- Use `bd.exe` exclusively for writes (`create`, `update`, `close`, `comment`, `reopen`)
- Provide real-time updates via file watching + SSE
- Support multi-project workflows across Windows-native paths
## 4. Non-Negotiable Constraints
- Stack: Next.js 15, React 19, TypeScript (strict)
- Platform: Windows native (no WSL assumptions)
- Reads: parse `.beads/issues.jsonl` directly
- Writes: must route through `bd.exe` via `child_process.execFile`
- Never write directly to `issues.jsonl`
- License: MIT
## 5. Architecture
### 5.1 Frontend
- React 19 UI with Tailwind
- Views: Kanban, Dependency Graph, Timeline, Agent Sessions
- State: React Query (server/cache) + Zustand (UI state, optimistic UI state coordination)
### 5.2 Backend (Next.js App Router API)
- Read layer: Node `fs` + JSONL parser
- Watch layer: `chokidar` on project `.beads` files
- Transport: Server-Sent Events (SSE) for one-way real-time updates
- Write layer: `child_process.execFile` wrapper over `bd.exe`
### 5.3 Path and Project Handling
- Project root for this repo: `C:\Users\Zenchant\codex\beadboard`
- User project registry stored in profile path: `%USERPROFILE%\\.beadboard\\projects.json`
- Normalize paths with Windows-safe utilities before comparison/storage
- Display paths in readable normalized form while preserving canonical behavior
## 6. Approved Product Decisions
- Graph library: React Flow (faster delivery for interactive DAG use cases)
- Mutation scope in phase 1: include comments and reopen in addition to create/update/close
- Demo clip is reference-only (not a runtime mode)
- Auto-scan policy:
- Default: auto-scan `%USERPROFILE%` and user-added roots
- Optional: explicit “scan all drives” action for broader discovery
## 7. Core Functional Requirements
### 7.1 Kanban Board
- Status columns: `open`, `in_progress`, `blocked`, `deferred`, `closed`
- Card metadata: id, priority, type, labels, assignee, dependency count
- Detail panel with full bead metadata
- Search/filter by text, type, priority, label
### 7.2 Multi-Project Support
- Register/remove project roots
- Discover `.beads` directories under approved scan roots
- Switch between per-project and aggregate views
### 7.3 Real-Time Updates
- Watch `issues.jsonl` changes with debounce
- Publish change events via SSE
- Client auto-reconnect and query invalidation on relevant updates
### 7.4 Dependency Graph
- Parse dependency edges (`blocks`, `parent`, `relates_to`, `duplicates`, `supersedes`)
- Render interactive graph with pan/zoom/select
- Highlight blocked chains and flag cycles/anomalies
### 7.5 Timeline / Activity Feed
- Derive timeline events from snapshots + updates
- Group chronologically
- Filter by project, agent/session, and event type
### 7.6 Agent Session View
- Group issues by `closed_by_session`, `assignee`, `created_by`
- Display claimed/completed/open outcomes per session
### 7.7 CLI Write-Back
- Mutations must execute `bd.exe` in target project CWD
- Supported operations:
- Create bead
- Update bead fields/status
- Close bead with reason
- Reopen bead
- Add comment
- Optimistic UI updates with rollback on CLI failure
## 8. Data Handling Requirements
- Input format: JSONL (one object per line)
- Ignore blank lines
- Skip malformed JSON lines safely
- Apply defaults:
- `status = open` when absent
- `issue_type = task` when absent
- `priority = 2` when absent (`0` is valid and must be preserved)
- Exclude `tombstone` from standard views unless explicitly requested
## 9. Quality, Reliability, and Safety
- Strict read/write boundary tests must verify no direct JSONL write path exists
- Graceful handling for:
- File locks/transient read failures
- Missing `bd.exe`
- Command failures with actionable errors
- All logic must remain Windows-safe and avoid Unix-only assumptions
## 10. Performance Targets
- Startup/render readiness target: < 2s (local dev expectation)
- Parse performance target: < 100ms for 1000 beads
- Live update propagation target: < 500ms from file change to UI refresh
- Scan performance: practical defaults with bounded recursion and ignore rules
## 11. Scope by Priority
### P0
- Foundation, schema/types, path normalization
- JSONL read layer and API
- Registry + scanner
- Watcher + SSE
### P1
- Kanban UI
- CLI mutation bridge and APIs (including comments/reopen)
- Optimistic update/rollback
- Hardening + test coverage for boundaries
### P2
- Timeline
- Dependency Graph
- Agent Session views
## 12. Out of Scope (Initial Release)
- Full-drive auto-scan by default
- WebSocket transport
- Direct DB replacement for JSONL source of truth
- Any direct write to `.beads/issues.jsonl`
## 13. Risks and Mitigations
- Risk: stale/partial views during rapid CLI writes
Mitigation: debounce + SSE invalidation + eventual re-read reconciliation
- Risk: path mismatch across different Windows forms
Mitigation: centralized normalization and canonical path keys
- Risk: CLI output format drift
Mitigation: tolerant parsing and startup version checks
## 14. Acceptance Criteria (System-Level)
- Runs natively on Windows PowerShell/CMD without WSL
- Reads from `.beads/issues.jsonl` successfully for registered projects
- All writes performed via `bd.exe` and reflected back via watcher/SSE
- Kanban, Timeline, Graph, and Agent Session views function against real bead data
- No direct `issues.jsonl` write implementation exists in app code

View file

@ -0,0 +1,226 @@
# BeadBoard Parallel Agent Dispatch Plan
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** Run the next BeadBoard implementation phase in parallel with low merge risk, while preserving strict read/write boundaries (`issues.jsonl` read-only, writes only through `bd.exe`).
**Architecture:** Split work by subsystem with clear file ownership: registry persistence + API, scanner, and Kanban UI baseline. Keep each agent on dependency-safe beads and synchronize through an integration lead at checkpoints.
**Tech Stack:** Next.js 15, React 19, TypeScript strict, Node `fs`, Windows path utilities, React Query, Zustand.
---
## Parallelization Model
### Agent Roles
1. **Agent A (Registry/API Track)**
- Primary beads: `bb-6aj.1`, then `bb-6aj.2`
- Scope: profile-scoped project registry + API endpoints for add/remove/list
- Files expected:
- `src/lib/registry.ts`
- `src/app/api/projects/route.ts`
- tests under `tests/lib/` and `tests/api/`
2. **Agent B (Kanban UI Track)**
- Primary beads: `bb-trz.1`, then `bb-trz.2`, then `bb-trz.3`, then `bb-trz.4`
- Scope: tracer bullet 1 Kanban baseline (demo-inspired UI with production typing)
- Files expected:
- `src/app/page.tsx`
- `src/components/kanban/*`
- `src/components/shared/*`
- UI tests under `tests/`
3. **Agent C (Scanner Track)**
- Primary beads: `bb-6aj.3`, then `bb-6aj.3.1` (optional if time remains)
- Scope: bounded scanner rooted at `%USERPROFILE%` with explicit full-drive opt-in mode
- Files expected:
- `src/lib/scanner.ts`
- `src/app/api/scan/route.ts` (if created in this phase)
- tests under `tests/lib/`
4. **Lead Agent (Integrator/Verifier)**
- No primary feature bead; owns integration + verification
- Scope: merges, resolves small conflicts, runs checks, updates bead states
---
## Dependency Rules (Do Not Break)
1. `bb-6aj.2` must start only after `bb-6aj.1` is complete (hard dependency).
2. `bb-6aj.3` depends on `bb-6aj.1` (hard dependency).
3. `bb-trz.2` depends on `bb-trz.1`.
4. `bb-trz.3` and `bb-trz.4` depend on `bb-trz.2`.
5. No direct writes to `.beads/issues.jsonl` under any condition.
---
## Checkpoint Sequence
### Checkpoint 0: Branch Preparation
1. Create feature branches from current baseline:
- `feat/registry-api`
- `feat/kanban-baseline`
- `feat/scanner`
2. Each agent works only in its branch.
### Checkpoint 1: Foundation Delivery
1. Agent A finishes `bb-6aj.1`.
2. Agent B finishes `bb-trz.1`.
3. Agent C remains blocked until `bb-6aj.1` closes, then starts `bb-6aj.3`.
4. Lead verifies:
- `npm run typecheck`
- `npm run test`
### Checkpoint 2: Mid-Phase Delivery
1. Agent A completes `bb-6aj.2`.
2. Agent B completes `bb-trz.2`.
3. Agent C completes `bb-6aj.3`.
4. Lead rebases/merges and reruns:
- `npm run typecheck`
- `npm run test`
- `npm run dev` (startup sanity)
### Checkpoint 3: Tracer-1 Completion
1. Agent B completes `bb-trz.3` and `bb-trz.4`.
2. Lead runs manual UI smoke for Kanban baseline.
3. Lead optionally uses browser automation for verification once app is up.
---
## Agent Prompt Pack
### Prompt: Agent A (Registry/API)
```text
You are Agent A on BeadBoard.
Mission:
1) Complete bb-6aj.1
2) Complete bb-6aj.2
Constraints:
- Windows-native paths only
- Persist registry at %USERPROFILE%\.beadboard\projects.json
- Normalize paths safely (no Unix assumptions)
- No direct writes to .beads/issues.jsonl
- Maintain strict TS types and add tests
Deliverables:
- src/lib/registry.ts (or equivalent)
- src/app/api/projects/route.ts with add/remove/list
- tests covering malformed paths, duplicate normalization, lazy file creation
- bead updates with concise implementation notes
Verification before close:
- npm run typecheck
- npm run test
```
### Prompt: Agent B (Kanban Baseline)
```text
You are Agent B on BeadBoard.
Mission:
1) Complete bb-trz.1
2) Complete bb-trz.2
3) Complete bb-trz.3
4) Complete bb-trz.4
Constraints:
- Rebuild demo style as production Next.js/TS components
- Use real parser data path, no sample-data-only architecture
- Preserve status ordering: open, in_progress, blocked, deferred, closed
- Read boundary only; all writes are future bd bridge work
- Keep components modular and typed
Deliverables:
- Kanban columns
- Card component with id/priority/type/labels/assignee/dep count
- Detail panel with timestamps/dependencies
- Search/filter/stats controls
- tests for rendering and filtering behavior
Verification before close:
- npm run typecheck
- npm run test
- npm run dev (manual check of kanban page)
```
### Prompt: Agent C (Scanner)
```text
You are Agent C on BeadBoard.
Mission:
1) Complete bb-6aj.3
2) Optionally complete bb-6aj.3.1 if time permits
Constraints:
- Default scan root is %USERPROFILE%, not full-drive crawl
- Implement bounded recursion and ignore patterns
- Explicit full-drive scan must be opt-in only
- Windows-safe path normalization throughout
- No shell-specific assumptions
Deliverables:
- src/lib/scanner.ts
- optional scan API route if needed for invoking scanner
- tests for depth limit, ignore behavior, and root selection
Verification before close:
- npm run typecheck
- npm run test
```
### Prompt: Lead Agent (Integration)
```text
You are Lead Agent for BeadBoard integration.
Mission:
1) Integrate outputs from Agent A/B/C at checkpoints
2) Keep bead statuses accurate
3) Run verification and capture failures with file-level notes
Rules:
- Do not mask failing tests
- Resolve merge conflicts without changing boundary contracts
- Ensure no direct writes to .beads/issues.jsonl
Verification gates:
- npm run typecheck
- npm run test
- npm run dev startup check
Completion condition:
- Tracer bullet 1 Kanban baseline visible and functional
- Registry + scanner foundations merged and passing checks
```
---
## First Task to Start Now
1. Start **Agent A** on `bb-6aj.1` (unblocks both `bb-6aj.2` and `bb-6aj.3`).
2. In parallel, start **Agent B** on `bb-trz.1`.
3. Start **Agent C** only after `bb-6aj.1` is closed.
---
## Run Commands (Lead)
```powershell
# show ready tasks
bd ready
# claim task
bd update bb-6aj.1 --claim
# run verification
npm run typecheck
npm run test
npm run dev
```

4
next-env.d.ts vendored Normal file
View file

@ -0,0 +1,4 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file is auto-generated by Next.js type tooling.

9
next.config.ts Normal file
View file

@ -0,0 +1,9 @@
import type { NextConfig } from 'next';
import path from 'node:path';
const nextConfig: NextConfig = {
reactStrictMode: true,
outputFileTracingRoot: path.join(process.cwd()),
};
export default nextConfig;

1508
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

26
package.json Normal file
View file

@ -0,0 +1,26 @@
{
"name": "beadboard",
"version": "0.1.0",
"private": true,
"license": "MIT",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"typecheck": "tsc --noEmit",
"test": "node --test tests/bootstrap.test.mjs && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --test tests/guards/no-direct-jsonl-write.test.mjs"
},
"dependencies": {
"next": "15.5.7",
"react": "19.2.1",
"react-dom": "19.2.1"
},
"devDependencies": {
"@types/node": "^22.10.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"tsx": "^4.21.0",
"typescript": "^5.7.2"
}
}

15
src/app/layout.tsx Normal file
View file

@ -0,0 +1,15 @@
import type { Metadata } from 'next';
import type { ReactNode } from 'react';
export const metadata: Metadata = {
title: 'BeadBoard',
description: 'Windows-native Beads dashboard',
};
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}

7
src/app/page.tsx Normal file
View file

@ -0,0 +1,7 @@
export default function Page() {
return (
<main>
<h1>BeadBoard</h1>
</main>
);
}

85
src/lib/parser.ts Normal file
View file

@ -0,0 +1,85 @@
import type { BeadDependency, BeadIssue, ParseableBeadIssue } from './types';
export interface ParseIssuesOptions {
includeTombstones?: boolean;
}
function normalizeDependencies(value: unknown): BeadDependency[] {
if (!Array.isArray(value)) {
return [];
}
return value
.map((item) => {
if (!item || typeof item !== 'object') {
return null;
}
const dep = item as { type?: unknown; target?: unknown };
if (typeof dep.type !== 'string' || typeof dep.target !== 'string') {
return null;
}
return {
type: dep.type as BeadDependency['type'],
target: dep.target,
};
})
.filter((dep): dep is BeadDependency => dep !== null);
}
function normalizeIssue(raw: ParseableBeadIssue): BeadIssue {
return {
id: raw.id,
title: raw.title,
description: typeof raw.description === 'string' ? raw.description : null,
status: (raw.status ?? 'open') as BeadIssue['status'],
priority: typeof raw.priority === 'number' ? raw.priority : 2,
issue_type: (raw.issue_type ?? 'task') as BeadIssue['issue_type'],
assignee: typeof raw.assignee === 'string' ? raw.assignee : null,
owner: typeof raw.owner === 'string' ? raw.owner : null,
labels: Array.isArray(raw.labels) ? raw.labels.filter((x): x is string => typeof x === 'string') : [],
dependencies: normalizeDependencies(raw.dependencies),
created_at: typeof raw.created_at === 'string' ? raw.created_at : '',
updated_at: typeof raw.updated_at === 'string' ? raw.updated_at : '',
closed_at: typeof raw.closed_at === 'string' ? raw.closed_at : null,
close_reason: typeof raw.close_reason === 'string' ? raw.close_reason : null,
closed_by_session: typeof raw.closed_by_session === 'string' ? raw.closed_by_session : null,
created_by: typeof raw.created_by === 'string' ? raw.created_by : null,
due_at: typeof raw.due_at === 'string' ? raw.due_at : null,
estimated_minutes: typeof raw.estimated_minutes === 'number' ? raw.estimated_minutes : null,
external_ref: typeof raw.external_ref === 'string' ? raw.external_ref : null,
metadata: typeof raw.metadata === 'object' && raw.metadata !== null ? (raw.metadata as Record<string, unknown>) : {},
};
}
export function parseIssuesJsonl(text: string, options: ParseIssuesOptions = {}): BeadIssue[] {
const includeTombstones = options.includeTombstones ?? false;
const issues: BeadIssue[] = [];
for (const line of text.split(/\r?\n/)) {
const trimmed = line.trim();
if (!trimmed) {
continue;
}
try {
const parsed = JSON.parse(trimmed) as ParseableBeadIssue;
if (!parsed.id || !parsed.title) {
continue;
}
const normalized = normalizeIssue(parsed);
if (!includeTombstones && normalized.status === 'tombstone') {
continue;
}
issues.push(normalized);
} catch {
// Skip malformed lines to keep parser resilient against partial writes.
continue;
}
}
return issues;
}

36
src/lib/pathing.ts Normal file
View file

@ -0,0 +1,36 @@
import path from 'node:path';
function normalizeDriveLetter(input: string): string {
if (/^[a-z]:/.test(input)) {
return `${input[0].toUpperCase()}${input.slice(1)}`;
}
return input;
}
function trimTrailingSeparator(input: string): string {
if (/^[A-Za-z]:\\$/.test(input)) {
return input;
}
return input.replace(/[\\/]+$/, '');
}
export function canonicalizeWindowsPath(input: string): string {
const withBackslashes = input.replaceAll('/', '\\');
const normalized = path.win32.normalize(withBackslashes);
const withDriveCase = normalizeDriveLetter(normalized);
return trimTrailingSeparator(withDriveCase);
}
export function windowsPathKey(input: string): string {
return canonicalizeWindowsPath(input).toLowerCase();
}
export function toDisplayPath(input: string): string {
return canonicalizeWindowsPath(input).replaceAll('\\', '/');
}
export function sameWindowsPath(a: string, b: string): boolean {
return windowsPathKey(a) === windowsPathKey(b);
}

61
src/lib/types.ts Normal file
View file

@ -0,0 +1,61 @@
export const BEAD_STATUSES = [
'open',
'in_progress',
'blocked',
'deferred',
'closed',
'tombstone',
'pinned',
'hooked',
] as const;
export type BeadStatus = (typeof BEAD_STATUSES)[number];
export const BEAD_DEPENDENCY_TYPES = [
'blocks',
'parent',
'relates_to',
'duplicates',
'supersedes',
'replies_to',
] as const;
export type BeadDependencyType = (typeof BEAD_DEPENDENCY_TYPES)[number];
export const CORE_ISSUE_TYPES = ['task', 'bug', 'feature', 'epic', 'chore'] as const;
export type CoreIssueType = (typeof CORE_ISSUE_TYPES)[number];
export type BeadIssueType = CoreIssueType | (string & {});
export interface BeadDependency {
type: BeadDependencyType;
target: string;
}
export interface BeadIssue {
id: string;
title: string;
description: string | null;
status: BeadStatus;
priority: number;
issue_type: BeadIssueType;
assignee: string | null;
owner: string | null;
labels: string[];
dependencies: BeadDependency[];
created_at: string;
updated_at: string;
closed_at: string | null;
close_reason: string | null;
closed_by_session: string | null;
created_by: string | null;
due_at: string | null;
estimated_minutes: number | null;
external_ref: string | null;
metadata: Record<string, unknown>;
}
export interface ParseableBeadIssue extends Partial<BeadIssue> {
id: string;
title: string;
}

30
tests/bootstrap.test.mjs Normal file
View file

@ -0,0 +1,30 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs';
const requiredFiles = [
'package.json',
'tsconfig.json',
'next.config.ts',
'src/app/layout.tsx',
'src/app/page.tsx',
];
test('bootstrap scaffold files exist', () => {
for (const file of requiredFiles) {
assert.equal(fs.existsSync(file), true, `missing file: ${file}`);
}
});
test('package.json has next/react/typescript scripts and deps', () => {
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
assert.equal(pkg.dependencies.next?.startsWith('15'), true, 'next@15 required');
assert.equal(pkg.dependencies.react?.startsWith('19'), true, 'react@19 required');
assert.equal(pkg.dependencies['react-dom']?.startsWith('19'), true, 'react-dom@19 required');
assert.equal(pkg.devDependencies.typescript?.length > 0, true, 'typescript required');
assert.equal(typeof pkg.scripts.dev, 'string', 'dev script required');
assert.equal(typeof pkg.scripts.build, 'string', 'build script required');
assert.equal(typeof pkg.scripts.start, 'string', 'start script required');
assert.equal(typeof pkg.scripts.typecheck, 'string', 'typecheck script required');
});

View file

@ -0,0 +1,9 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { scanForDirectIssuesJsonlWrites } from '../../tools/guardrails/no-direct-jsonl-write.mjs';
test('source tree contains no direct write calls targeting .beads/issues.jsonl', () => {
const violations = scanForDirectIssuesJsonlWrites('src');
assert.deepEqual(violations, []);
});

51
tests/lib/parser.test.ts Normal file
View file

@ -0,0 +1,51 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import { parseIssuesJsonl } from '../../src/lib/parser';
test('parseIssuesJsonl applies defaults and preserves priority 0', () => {
const input = [
JSON.stringify({ id: 'bb-1', title: 'One', priority: 0 }),
JSON.stringify({ id: 'bb-2', title: 'Two' }),
].join('\n');
const result = parseIssuesJsonl(input);
assert.equal(result.length, 2);
assert.equal(result[0].priority, 0);
assert.equal(result[0].status, 'open');
assert.equal(result[0].issue_type, 'task');
assert.equal(result[1].priority, 2);
});
test('parseIssuesJsonl skips malformed and blank lines', () => {
const input = [' ', '{bad json', JSON.stringify({ id: 'bb-3', title: 'Three' })].join('\n');
const result = parseIssuesJsonl(input);
assert.equal(result.length, 1);
assert.equal(result[0].id, 'bb-3');
});
test('parseIssuesJsonl filters tombstones by default', () => {
const input = [
JSON.stringify({ id: 'bb-4', title: 'Live', status: 'open' }),
JSON.stringify({ id: 'bb-5', title: 'Gone', status: 'tombstone' }),
].join('\n');
const result = parseIssuesJsonl(input);
assert.equal(result.length, 1);
assert.equal(result[0].id, 'bb-4');
});
test('parseIssuesJsonl can include tombstones when requested', () => {
const input = [
JSON.stringify({ id: 'bb-4', title: 'Live', status: 'open' }),
JSON.stringify({ id: 'bb-5', title: 'Gone', status: 'tombstone' }),
].join('\n');
const result = parseIssuesJsonl(input, { includeTombstones: true });
assert.equal(result.length, 2);
});

30
tests/lib/pathing.test.ts Normal file
View file

@ -0,0 +1,30 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import {
canonicalizeWindowsPath,
windowsPathKey,
toDisplayPath,
sameWindowsPath,
} from '../../src/lib/pathing';
test('canonicalizeWindowsPath normalizes separators and drive casing', () => {
const input = 'c:/Users/Zenchant/codex/beadboard/';
const result = canonicalizeWindowsPath(input);
assert.equal(result, 'C:\\Users\\Zenchant\\codex\\beadboard');
});
test('windowsPathKey is case-insensitive stable key', () => {
const a = windowsPathKey('C:/Users/Zenchant/codex/beadboard');
const b = windowsPathKey('c:\\users\\zenchant\\codex\\beadboard\\');
assert.equal(a, b);
});
test('toDisplayPath renders forward slashes for UI readability', () => {
const display = toDisplayPath('C:\\Users\\Zenchant\\codex\\beadboard');
assert.equal(display, 'C:/Users/Zenchant/codex/beadboard');
});
test('sameWindowsPath handles case/separator differences', () => {
assert.equal(sameWindowsPath('D:/Repos/One', 'd:\\repos\\one\\'), true);
});

View file

@ -0,0 +1,49 @@
import type {
BeadIssue,
BeadStatus,
BeadDependencyType,
BeadIssueType,
BeadDependency,
ParseableBeadIssue,
} from '../../src/lib/types';
const status: BeadStatus = 'open';
const depType: BeadDependencyType = 'blocks';
const issueType: BeadIssueType = 'task';
const dependency: BeadDependency = {
type: depType,
target: 'bb-123',
};
const issue: BeadIssue = {
id: 'bb-123',
title: 'Test issue',
status,
priority: 0,
issue_type: issueType,
description: 'schema contract',
assignee: 'agent',
owner: 'owner@example.com',
labels: ['test'],
dependencies: [dependency],
created_at: '2026-02-12T00:00:00Z',
updated_at: '2026-02-12T00:00:00Z',
closed_at: null,
close_reason: null,
closed_by_session: null,
created_by: 'zenchantlive',
due_at: null,
estimated_minutes: null,
external_ref: null,
metadata: {},
};
const parseable: ParseableBeadIssue = {
id: issue.id,
title: issue.title,
};
if (!parseable.id || !parseable.title) {
throw new Error('invalid parseable issue contract');
}

View file

@ -0,0 +1,64 @@
import fs from 'node:fs';
import path from 'node:path';
const WRITE_APIS = [
'writeFile',
'writeFileSync',
'appendFile',
'appendFileSync',
'createWriteStream',
];
function listFilesRecursive(dir) {
const entries = fs.readdirSync(dir, { withFileTypes: true });
const files = [];
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
if (entry.isDirectory()) {
files.push(...listFilesRecursive(fullPath));
} else if (/\.(ts|tsx|js|mjs|cjs)$/i.test(entry.name)) {
files.push(fullPath);
}
}
return files;
}
function findLineNumber(source, index) {
const prefix = source.slice(0, index);
return prefix.split(/\r?\n/).length;
}
export function scanForDirectIssuesJsonlWrites(rootDir) {
if (!fs.existsSync(rootDir)) {
return [];
}
const files = listFilesRecursive(rootDir);
const violations = [];
for (const filePath of files) {
const source = fs.readFileSync(filePath, 'utf8');
const lowered = source.toLowerCase();
if (!lowered.includes('issues.jsonl')) {
continue;
}
for (const api of WRITE_APIS) {
const regex = new RegExp(`${api}\\s*\\([\\s\\S]{0,300}?issues\\.jsonl`, 'gi');
let match = regex.exec(source);
while (match) {
violations.push({
file: filePath.replaceAll('\\\\', '/'),
line: findLineNumber(source, match.index),
snippet: match[0].slice(0, 160),
});
match = regex.exec(source);
}
}
}
return violations;
}

20
tsconfig.json Normal file
View file

@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "es2022"],
"allowJs": false,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [{ "name": "next" }]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}