Skip to content

Repository files navigation

dull

Doubtfully Useful LLM Ledger — a local web UI for monitoring and managing project planning files, paired with a set of Claude Code skills and hooks that enforce a structured idea-to-task workflow.


What It Does

dull watches your project's planning documents (docs/, CLAUDE.md, AGENTS.md, task YAML files) and surfaces them in a browser-based UI in real time. Run it alongside a Claude Code session so both you and the agent share the same live view of project state.

Beyond the UI, the repo ships:

  • Skills — reusable Claude Code behaviors you invoke with /skill-name
  • Hooks — Node scripts that fire automatically on agent actions to enforce data integrity

Quick Start

npm install
npm start           # serves on http://0.0.0.0:6768

# pick a port
DULL_PORT=4000 npm start

# point at a different project root
node bin/dull.js --root /path/to/my-project

CLI flags:

Flag Short Default Description
--port -p 6768 Port to listen on
--root -r cwd Project root to watch
--host 0.0.0.0 Host to bind

Project Structure

.claude/
  settings.json          # Claude Code permissions and hook config

skills/                  # Skills loaded by Claude Code
  decision-close/
  decision-record/
  idea-approve/
  idea-capture/
  idea-close/
  idea-elaborate/
  idea-review/
  spec-approve/
  spec-close/
  spec-create/
  spec-review/
  status/
  task-done/
  task-load/
  task-plan/
  task-start/
  task-tdd/
  task-update/

hooks/                   # Hook scripts (must be wired into settings.json)
  post_write_idea_guard.js
  post_write_task_validator.js
  stop_task_guard.js

docs/
  IDEAS.yaml             # Idea registry
  SPECS.yaml             # Spec registry
  TASKS.yaml             # Task registry
  DECISIONS.yaml         # Decision registry
  ideas/                 # Per-idea detail files (IDEA-NNN.md)
  specs/                 # Per-spec detail files (SPEC-NNN.md)
  tasks/                 # Per-task detail files (DOMAIN-NNN.yaml)
  decisions/             # Per-decision detail files (DEC-NNN.md)

The Workflow Pipeline

Work flows through four stages, each with its own registry file and optional detail document.

IDEA → SPEC → TASK → DECISION

Ideas (docs/IDEAS.yaml + docs/ideas/IDEA-NNN.md)

Raw captures of anything worth exploring. Status flow:

captured → elaborating → review → approved  (archived)
                                → rejected  (archived)
                       → parked             (stays live)
  • captured — written down, no analysis yet
  • elaborating — being fleshed out by human or agent
  • review — waiting for a human decision
  • parked — not now, maybe later

Detail files follow the template at docs/ideas/.template.md. Required sections: ## The Idea, ## Elaboration, ## Review Notes, ## Decision.

Specs (docs/SPECS.yaml + docs/specs/SPEC-NNN.md)

Approved ideas become specs — precise contracts for what will be built. Status flow:

draft → review → accepted  (stays live, spawns tasks)
               → rejected  (archived)
               → draft     (sent back for revision)
       → parked            (stays live)

Accepted specs remain in the live registry as a reference for the tasks they spawned.

Tasks (docs/TASKS.yaml + docs/tasks/DOMAIN-NNN.yaml)

Concrete units of work derived from specs (or created directly). Status values:

planning → ready → in-progress → done
                 → blocked
                 → abandoned

ID format: <DOMAIN>-<NNN> — e.g. AUTH-001, UI-003. Detail files carry full context: objective, acceptance criteria, work log, and handoff context written on completion.

Decisions (docs/DECISIONS.yaml)

Standing rules and choices that govern the project. Never deleted — only superseded or retired.

proposed → active → superseded
                  → retired

Each decision has a single rule: field — one sentence, plain English, actionable.


Skills

Skills are Markdown files in skills/ that Claude Code loads when you invoke them. Invoke any skill with /skill-name in a Claude Code session.

Ideas

Skill Description
/idea-capture Record a new idea. Generates an ID, creates the detail file, and asks who owns the elaboration step.
/idea-elaborate Begin or continue elaboration on a captured idea. Respects soft locks if another owner is active.
/idea-review Present an elaborated idea to a human for a decision. Outcomes: approve, park, reject, abandon, or send back.
/idea-approve Approve an idea and promote it to tasks. Runs /task-plan for each task, archives the idea from the live index.
/idea-close Close an idea as parked, rejected, or abandoned. Parked stays live; rejected/abandoned move to archive.

Specs

Skill Description
/spec-create Create a new spec from a parent idea or a description. Reads the spec template and adds an entry to docs/specs.yaml.
/spec-review Present a spec to a human for a decision. Outcomes: accept, send back to draft, park, or reject.
/spec-approve Accept a spec and spawn or update its tasks. Spec stays in the live index as a reference.
/spec-close Close a spec as parked, rejected, or abandoned.

Tasks

Skill Description
/task-plan Plan a new task. Reads the task template, creates a registry entry and detail file. Run before any implementation.
/task-start Start a task. Validates dependencies, loads handoff context, transitions status to in-progress. Run before touching code.
/task-load Load and summarize a task's full context without changing its status.
/task-update Record a progress note, mark blocked, or add references during an active task session.
/task-tdd TDD workflow: loads and starts a task, runs red-green-refactor loop with progress updates, stops at review for human sign-off.
/task-done Close a task. Validates acceptance criteria, writes handoff context, updates status to done.

Decisions

Skill Description
/decision-record Record a new architectural or process decision. Adds an entry to docs/decisions.yaml and creates a detail file.
/decision-close Supersede or retire an existing decision. Neither is deleted — decisions are permanent records.

Utility

Skill Description
/status Summarize current task state: counts by status, active and blocked tasks, anything needing attention.

Hooks

Hooks are Node scripts that Claude Code executes automatically on specific events. They must be registered in .claude/settings.json — they do not activate just by being present in hooks/.

Wiring Hooks

Add this block to .claude/settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "node hooks/post_write_idea_guard.js",
            "timeout": 10
          },
          {
            "type": "command",
            "command": "node hooks/post_write_task_validator.js",
            "timeout": 10
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "node hooks/stop_task_guard.js",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

post_write_idea_guard.js

Fires after any Write/Edit to docs/ideas/*.md. Two non-blocking checks:

  1. Soft lock — warns if the file's owner_id doesn't match the writing agent. Prevents one agent from clobbering another's in-progress elaboration.
  2. Structure — warns if any required section (## The Idea, ## Elaboration, ## Review Notes, ## Decision) is missing.

Both checks emit warnings only — they never block the write.

post_write_task_validator.js

Fires after any Write/Edit to docs/tasks/*.yaml. Checks:

  1. All required fields present: id, title, status, created, updated, objective, acceptance_criteria
  2. status is a valid value (planning, ready, in-progress, blocked, done, abandoned)
  3. acceptance_criteria is not empty when status is in-progress or done
  4. handoff_context.summary is filled when status is done

Warnings only — non-blocking. Fixes are expected before ending the session.

stop_task_guard.js

Fires when the agent tries to end a session. Scans docs/tasks.yaml for any task with status: in-progress. If found, blocks the session from ending with a message naming the open tasks.

To end the session cleanly: mark open tasks done (with handoff context filled) or change them to blocked with a reason in the work log.

This is the only blocking hook — it prevents incomplete work from going silent at session end.


Development

npm install

# dev mode — hot-reloads server and UI
npm run dev

# build the UI
npm run build

The server is Fastify serving a Preact + Tailwind frontend. File watching uses chokidar. Watched paths are configured in src/config.js.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages