UC JungTL;DR I built uctm (Universal Claude Task Manager) — an npm package that...
I built uctm (Universal Claude Task Manager) — an npm package that installs 6 specialized subagents into Claude Code. You type one request, and it automatically plans the work, builds the code, verifies it, and commits — all through structured XML messaging.
npm install -g uctm
cd your-project && uctm init
claude
# Type: [new-feature] Add user authentication with JWT
# → Pipeline runs automatically
GitHub: UCJung/uc-taskmanager-claude-agent
npm: uctm
Claude Code is powerful, but when you ask it to build something complex, it tries to do everything in one shot. For simple tasks, that works fine. But for anything with multiple files, dependencies between components, or the need for proper testing — things get messy.
I wanted a system where:
uctm uses 6 specialized subagents, each with a single responsibility:
User Request
│
Main Claude (orchestrator)
│
├── router → Analyzes request, picks execution mode
├── planner → Decomposes into TASKs with dependency DAG
├── scheduler → Manages DAG, dispatches ready TASKs
├── builder → Writes the actual code
├── verifier → Runs tests, lint, acceptance checks
└── committer → Writes result report, git commits
Key constraint: Claude Code subagents cannot call other subagents. So Main Claude (the CLI terminal itself) acts as the orchestrator, calling each agent in sequence and passing messages between them.
Not every request needs all 6 agents. The router decides:
| Mode | When | What Happens |
|---|---|---|
| direct | Simple change, no tests needed | Router handles everything alone |
| pipeline | Needs testing, single domain | router → builder → verifier → committer |
| full | Complex, multi-file, dependencies | All 6 agents with DAG management |
The mode is determined by analyzing the request against rules in .agent/router_rule_config.json — fully customizable per project.
This is where it gets interesting. Instead of passing free-form text between agents, uctm uses structured XML messages.
<dispatch to="builder" work="WORK-05" task="TASK-00"
execution-mode="pipeline">
<context>
<project>my-app</project>
<language>ko</language>
<plan-file>works/WORK-05/PLAN.md</plan-file>
</context>
<task-spec>
<file>works/WORK-05/TASK-00.md</file>
<title>Add JWT authentication middleware</title>
<action>implement</action>
<description>Create auth middleware with
token validation...</description>
</task-spec>
<previous-results/>
</dispatch>
<task-result work="WORK-05" task="TASK-00"
agent="builder" status="PASS">
<summary>JWT auth middleware implemented</summary>
<files-changed>
<file action="created" path="src/middleware/auth.js">
JWT verification middleware
</file>
<file action="created" path="tests/auth.test.js">
12 test cases for auth flows
</file>
</files-changed>
<verification>
<check name="test" status="PASS">12/12 passed</check>
</verification>
<context-handoff from="builder" detail-level="FULL">
<what>Auth middleware with JWT validation</what>
<why>Used jsonwebtoken for RS256 support</why>
<caution>Requires JWT_SECRET env variable</caution>
<incomplete>None</incomplete>
</context-handoff>
</task-result>
Why XML? It's parseable, validatable, and token-efficient. Each agent knows exactly what to expect and what to return.
Here's the problem with multi-task pipelines: if TASK-03 needs to know what TASK-00, TASK-01, and TASK-02 did, context grows linearly. With 10+ TASKs, you're burning tokens on history instead of actual work.
uctm solves this with a sliding window on context-handoff:
| Distance | Detail Level | What's Passed |
|---|---|---|
| Previous TASK | FULL | what + why + caution + incomplete (~150 tokens) |
| 2 TASKs ago | SUMMARY | what only (~50 tokens) |
| 3+ TASKs ago | DROP | Nothing (0 tokens) |
This keeps context transfer at a constant ~200 tokens regardless of how many TASKs have completed. In a 10-TASK WORK, this saves ~75,000 tokens compared to passing everything.
TASK-00 → TASK-01 → TASK-02 → TASK-03
TASK-03's builder receives:
TASK-02 context-handoff ← FULL (what/why/caution/incomplete)
TASK-01 context-handoff ← SUMMARY (what only)
TASK-00 context-handoff ← DROP (not transferred)
Here's an actual pipeline run I captured to verify the message format. The request: "Create a simple calculator with add, subtract, multiply, divide."
Input: [new-feature] Create calc.js with 4 arithmetic functions
Output: execution-mode=pipeline + dispatch XML + PLAN.md + TASK-00.md
Router analyzed the request, determined it needs testing (pipeline mode), created the plan files, and generated dispatch XML for builder.
Input: dispatch XML from router
Output: task-result XML with context-handoff
Created: calc.js (4 functions), calc.test.js (8 tests)
Verification: 8/8 tests PASS
Input: builder's task-result XML
Output: Independent verification — re-ran all 8 tests
Checked: progress file, acceptance criteria, file existence
Result: ALL PASS
Input: builder + verifier task-result XMLs
Output: TASK-00_result.md written
Git commit: feat(TASK-00): calc.js ESM module
Commit hash returned
Total: 136K tokens, 96 tool calls, 344 seconds. Every message between agents followed the exact XML spec.
uctm follows an SDD (Specification-Driven Development) philosophy:
Requirements → Architecture → Design are the real assets.
Code is just output.
The spec documents define the XML schemas, context-handoff rules, and pipeline behavior. Agents are .md files — pure prompt definitions. Zero runtime code, zero dependencies.
This means:
uctm init
.agent/router_rule_config.json to tune execution-mode rules# Install globally
npm install -g uctm
# Initialize in your project
cd your-project
uctm init
# Start Claude Code (bypass mode for uninterrupted pipeline)
claude --dangerously-skip-permissions
# Trigger the pipeline with a tagged request
# [new-feature] Add a REST API for user management
# [bugfix] Fix the race condition in data loader
# [enhancement] Improve search query performance
What uctm init does:
.claude/agents/
.agent/router_rule_config.json
CLAUDE.md
works/ directory for WORK filesIf you work with Claude Code and find yourself managing complex multi-file tasks, give uctm a try. It's free, open-source, and takes 30 seconds to install.
GitHub: UCJung/uc-taskmanager-claude-agent
npm: uctm
Questions? Issues? Open a GitHub issue or find me on Discord.