You are running as part of a multi-agent development system called JAT (Jomarchy Agent Tools). This system enables parallel, coordinated work across codebases using multiple AI coding agents.
/jat:start # Start a session (pick a task)
/jat:start jat-abc123 # Start a specific task
/jat:complete # Complete your task
/jat:verify # Verify in browserCommand prefix: Claude Code uses
/jat:commands. Other agents (Pi, Codex, Gemini, etc.) use/skill:jat-skills. The behavior is identical.
- One agent = one session = one task - Each session handles exactly one task
- File declarations prevent conflicts - Declare files when starting a task via
--files - Memory coordinates work - Past session context surfaces via
.jat/memory/ - JAT Tasks is the task queue - Pick from ready work, update status, close when done
- Signals track your state - The IDE monitors agents through
jat-signal
This project uses jt (JAT Tasks) for issue tracking.
jt ready # Find available work (highest priority, no blockers)
jt show <id> # View task details
jt show <id> --json # JSON format
jt update <id> --status in_progress --assignee AgentName
jt close <id> --reason "Completed" # Routes to approver/requester/creator (see Task Identity below)
jt list --status open # List all open tasks
jt search "keyword" # Search tasks
jt create "Title" --approver "username" # Set who must review/accept completed work
jt create "Title" --creator "username" --approver "username" # Both actors (usually same person)Status values (use underscores, not hyphens):
Agent-workable (agents pick these up via jt ready):
open- Available to startin_progress- Being worked on
Paused / mid-flight (agents do NOT pick these up):
waiting- Ball in counterparty's court (awaiting their input)blocked- Blocked by external dependencysubmitted- In routing target's queue for acceptance (see Task Identity below)accepted- Routing target approved, pending deploydeployed- Shipped, pending archive/closeout
Terminal / special:
closed- Completeddev- Internal/dev-only (hidden from clients)
Task types: bug, feature, task, epic, chore (recurring scheduled task), chat
Every task carries three actor fields, written once at creation time. These drive reply-routing in /tasks-fast, the "Reply to" header in compose, and the jt close acceptance queue.
| Field | Meaning | Mutability |
|---|---|---|
creator |
Who actually pressed the button that spawned the task (the ingest source's authenticated user, or the agent that ran jt create). Immutable snapshot. |
Read-only after creation |
requester |
Who originally asked for the work (e.g. a client emailing feedback). May differ from creator when someone files on behalf of another. | Editable (advanced) |
approver |
Who must sign off when the work is done. Defaults to requester. Set this when the approver is different from the requester. |
Editable (advanced) |
Each field is a {email, name, role, source, ...} snapshot (JSONB in postgres, TEXT in SQLite) with an optional matching _id UUID column in postgres. In 95% of cases all three are the same person and you don't set anything — ingest paths call buildTaskIdentity() which fills them in from the authenticated user.
Flags on jt create / jt update:
jt create "Fix login bug" --approver "mike" # mike must accept; creator/requester default to current user
jt create "Refactor cache" # all three default to current user (most common)
jt create "On behalf of X" --requester "x@client.com" --approver "x@client.com" # filed on X's behalf
jt update jat-abc --approver "mike" # change approver post-creation
# --requester is a deprecated alias that sets both requester + approver to the same valueRouting priority on jt close: the close handler resolves a routing target in order approver → requester → creator (first non-null wins), then decides the outcome:
| Condition | Outcome |
|---|---|
| No target resolved (all three null) | closed immediately |
Target resolved, previous_assignee != target |
submitted → target's queue for accept/reject |
Target resolved, previous_assignee == target |
accepted automatically (target delegated the work themselves) |
The self-accept rule: previous_assignee is auto-stashed whenever assignee changes. When jw creates a task (approver=jw) and spawns an agent, the assignee flips from jw → agent, stashing previous_assignee=jw. At close time, previous_assignee == approver signals that jw delegated it — work is auto-accepted. When a third party (e.g. jw) works on a task that mike should sign off on (approver=mike), previous_assignee=jw != approver=mike, so it goes to submitted for mike to review. Match is by email OR UUID — either works.
Examples:
- jw creates task, spawns agent → agent completes →
accepted(jw is creator + approver, delegated to agent) - mike files feedback via widget → jw's agent works on it → agent completes →
submittedto mike (creator=mike, jw is transient assignee) - jw files on behalf of mike (
--approver mike), spawns agent → agent completes →submittedto mike
Ingest contract: all task-creation paths (API, voice, feedback widget, scheduler, Supabase ingest) route through buildTaskIdentity() (ide/src/lib/server/task-identity.ts). Any new ingest source MUST use this helper — do not write identity columns directly. See ide/docs/prd-task-identity-routing.md for the full spec.
jt dep add parent-id child-id # parent depends on child
jt dep tree task-id # Show dependency tree
jt dep remove parent-id child-idEpics are blocked by their children (children are READY, epic waits):
# Create epic
jt create "Epic title" --type epic --priority 1
# Create children
jt create "Child task" --type task --priority 2
# Set dependencies: epic depends on children (NOT children on epic)
jt dep add epic-id child-idAgent identities for multi-agent coordination. All tools are in ~/.local/bin/.
# Identity
am-register --name AgentName --program pi --model sonnet
am-whoami
am-agents # List all agents
# See what other agents are doing (real-time state from tmux + signals)
jt agents # Active agents with state, task, files
jt agents --json # JSON output for programmatic use
jt agents --project jat # Filter by project
jt agents --all # Include inactive agents
# File Declarations (prevent conflicts) - via jt on the task itself
jt update task-id --status in_progress --assignee AgentName --files "src/**/*.ts"Cross-session context is handled by agent memory (.jat/memory/).
The IDE tracks your state through signals. Emit them in order:
# 1. Starting (after registration)
jat-signal starting '{"agentName":"NAME","sessionId":"ID","project":"PROJECT","model":"MODEL","gitBranch":"BRANCH","gitStatus":"clean","tools":["bash","read","write","edit"],"uncommittedFiles":[]}'
# 2. Working (before coding)
jat-signal working '{"taskId":"ID","taskTitle":"TITLE","approach":"PLAN"}'
# 3. Needs Input (before asking user)
jat-signal needs_input '{"taskId":"ID","question":"QUESTION","questionType":"clarification"}'
# 4. Review (when work is done)
jat-signal review '{"taskId":"ID","taskTitle":"TITLE","summary":["ITEM1","ITEM2"]}'
# Waiting (async question — posts comment, sets status=waiting, pauses session)
jat-signal waiting '{"taskId":"ID","question":"QUESTION"}'Signal types: starting, working, needs_input, waiting, review, completing, complete
Spawn agent
|
v
STARTING /jat:start
| jat-signal working
v
WORKING <--> NEEDS INPUT
| jat-signal review
v
REVIEW Work done, awaiting user
| /jat:complete
v
COMPLETE Task closed, session ends
To work on another task: spawn a new agent session.
CRITICAL: When you need user input, ALWAYS use jat-signal needs_input + AskUserQuestion tool. Never ask questions in plain text — the IDE renders AskUserQuestion as clickable buttons, plain text questions get buried in terminal output.
Common scenarios:
- Can't reproduce a bug → ask user for more details
- Multiple valid approaches → ask user to choose
- Uncertain if fix is correct → ask user to verify
- Need credentials/access → ask user to provide
- Task seems like a duplicate → ask user to confirm
Pattern:
# 1. ALWAYS signal first (so IDE shows needs-input state)
jat-signal needs_input '{"taskId":"ID","question":"QUESTION","questionType":"decision"}'
# 2. THEN use AskUserQuestion tool with concrete options
# AskUserQuestion(["Commit fix as-is", "Investigate further", "Close as won't-fix"])
# 3. After user responds, signal working again
jat-signal working '{"taskId":"ID","taskTitle":"TITLE","approach":"Updated approach..."}'Question types: clarification, decision, approval, blocker, duplicate_check
When the human isn't available to answer interactively (overnight agent, scheduled task, long-running work), use jat-signal waiting instead of AskUserQuestion. This bundles three operations into one call:
- Posts a
questioncomment to the task's comment thread (visible in IDE) - Updates task status to
waiting(agents won't pick it up viajt ready) - Pauses the session (kills tmux cleanly; can be resumed later)
jat-signal waiting '{
"taskId": "jat-abc",
"question": "Should the export include archived items? I can proceed with either but need your call.",
"reason": "blocked on scope decision"
}'The human answers by posting an answer comment in the IDE. When the session resumes (new agent picks up the task), it reads the comment thread for context.
Use AskUserQuestion when the dev is present at the terminal. Use jat-signal waiting when they're not.
MANDATORY: You MUST emit jat-signal review BEFORE presenting any results or summary to the user. This applies to ALL task types - code changes, research, investigation, documentation. No exceptions.
- Emit
reviewsignal with summary, files modified, and/or findings - Show "READY FOR REVIEW" banner with bullet-point summary
- Wait for user to run
/jat:complete - Complete handles: mail check, verify, commit, close, release, announce
Never say "Task Complete" until jt close has run.
Never present results without emitting review signal first.
These tools emit progress signals automatically:
jat-step verifying --task ID --title TITLE --agent NAME # 0%
jat-step committing --task ID --title TITLE --agent NAME # 25%
jat-step closing --task ID --title TITLE --agent NAME # 50%
jat-step releasing --task ID --title TITLE --agent NAME # 75%
jat-step complete --task ID --title TITLE --agent NAME # 100%All tools are bash commands in ~/.local/bin/. Every tool has --help.
| Tool | Purpose |
|---|---|
jt |
JAT Tasks CLI for task management |
jt agents |
List active agents with real-time state, task, and reserved files |
jt-epic-child |
Set epic-child dependency correctly |
| Tool | Purpose |
|---|---|
am-register |
Create agent identity |
am-agents |
List agents (registry only) |
am-whoami |
Current identity |
| Tool | Purpose |
|---|---|
jat-signal |
Emit status signal to IDE |
jat-step |
Emit completion step signal |
| Tool | Purpose |
|---|---|
browser-start.js |
Launch Chrome with CDP |
browser-nav.js |
Navigate to URL |
browser-screenshot.js |
Capture screenshot |
browser-eval.js |
Execute JS in page |
browser-pick.js |
Click element |
browser-wait.js |
Wait for condition |
| Tool | Purpose |
|---|---|
db-query |
Run SQL, returns JSON |
db-schema |
Show table structure |
jat-secret |
Retrieve secrets |
| Tool | Purpose |
|---|---|
jat-search |
Unified search across tasks, memory, and files |
Use jat-search as your primary context retrieval tool. Search broadly first, then drill into specific sources:
jat-search "auth middleware" # Meta search (all sources)
jat-search tasks "OAuth timeout" --json # Deep task search
jat-search memory "browser automation" # Memory search (past sessions)
jat-search files "refreshToken" # File content search| Tool | Purpose |
|---|---|
jat-skills |
Browse, install, and manage skills from the catalog |
Skills installed via jat-skills install are automatically synced to your agent program. Claude Code gets them as commands in ~/.claude/commands/, Pi gets them in ~/.pi/agent/skills/, and other agents receive skill summaries via prompt injection at spawn.
Use the task type as prefix:
git commit -m "task(jat-abc): Add feature X"
git commit -m "bug(jat-abc): Fix race condition"
git commit -m "feat(jat-abc): Implement new endpoint"- Declare files when starting task - use
--filesonjt updateto prevent conflicts - Use task IDs everywhere - commits, memory entries
- Update task status -
in_progresswhen working,closedwhen done - Emit signals in order - starting -> working -> review -> complete
- ALWAYS signal review before presenting results - emit
jat-signal reviewBEFORE any summary output - NEVER ask questions in plain text - always use
jat-signal needs_input+AskUserQuestiontool so IDE renders buttons - Push to remote - work is NOT complete until
git pushsucceeds