brainstorming
Structured design dialogue that validates ideas before implementation begins.
discovery-tree-workflow
Use when planning and tracking work - creates visible, emergent work breakdown using TypeScript API with just-in-time planning and hierarchical task trees
Full skill instructions
Discovery Trees make work visible through hierarchical task breakdown that emerges just-in-time. Track work programmatically with the TypeScript API, grow the tree as you discover new requirements, maintain focus by capturing distractions.
Core principle: Start minimal, plan just-in-time, grow through discovery, make status visible.
Announce at start: "I'm using the Discovery Tree workflow to track this work."
Always use when:
Instead of:
API Location: This skill includes a ready-to-use TypeScript API in src/discovery-tree.ts - a unified entry point that consolidates database operations and Shortcut integration.
TypeScript Execution: All code examples use top-level await (no async wrapper needed). Single-line imports only.
Every Discovery Tree starts with setting workspace context, then creating an epic (container) and root task (actual work):
// Import from discovery-tree-workflow skill's src directory
// IMPORTANT: Use single-line imports only
import {
setWorkspace,
createTask,
addDependency,
updateTask,
closeTask,
findReadyTasks,
getEpicStatus,
drawTree
} from '~/.claude/skills/discovery-tree-workflow/src/discovery-tree.js';
// Set workspace context
await setWorkspace({ workspacePath: '/path/to/project' });
// Create epic (container for all work)
const epic = await createTask({
title: "Feature: User Authentication",
type: "epic",
priority: 1
});
// Create root task (describes the user value)
const rootTask = await createTask({
title: "User Authentication [root]",
type: "task",
priority: 1
});
// Link root task to epic
await addDependency({
taskId: rootTask.id,
dependsOnId: epic.id,
type: "parent-child"
});
Why both epic and root task?
Have a quick conversation (2-10 minutes) to identify first level of work:
Questions to ask:
Create tasks for what you discover:
// Create main tasks
const task1 = await createTask({
title: "API endpoint for login",
type: "task",
priority: 1
});
const task2 = await createTask({
title: "Password validation logic",
type: "task",
priority: 1
});
const task3 = await createTask({
title: "Session management",
type: "task",
priority: 1
});
// Link them to root task
await addDependency({
taskId: task1.id,
dependsOnId: rootTask.id,
type: "parent-child"
});
await addDependency({
taskId: task2.id,
dependsOnId: rootTask.id,
type: "parent-child"
});
await addDependency({
taskId: task3.id,
dependsOnId: rootTask.id,
type: "parent-child"
});
Don't over-plan: Stop when you have enough to start. More detail emerges as you work.
Pick a task and claim it:
// Find what's ready to work on
const readyTasks = await findReadyTasks({ limit: 10 });
// Claim the first ready task
await updateTask({
taskId: readyTasks[0].id,
status: "in_progress"
});
As you work:
blocked status// Discovered more work
const subtask = await createTask({
title: "Validate email format",
type: "task",
priority: 1
});
await addDependency({
taskId: subtask.id,
dependsOnId: task1.id,
type: "parent-child"
});
// Found blocker
const blocker = await createTask({
title: "Database schema needs user table",
type: "task",
priority: 0
});
await updateTask({
taskId: task1.id,
status: "blocked"
});
When task is done:
await closeTask({
taskId: task1.id,
reason: "Completed"
});
// Update parent with what was accomplished
await updateTask({
taskId: rootTask.id,
notes: "Completed: API endpoint for login. Previously: Initial setup"
});
IMPORTANT: Update parent task with what was accomplished to keep context accurate as subtasks complete.
Check progress:
const status = await getEpicStatus({ epicId: epic.id });
console.log(`Progress: ${status.completionPercentage}%`);
console.log(`${status.completedTasks}/${status.totalTasks} tasks complete`);
// See what's ready to work on next
const nextReady = await findReadyTasks({ limit: 5 });
If more work remains: Claim next task, repeat cycle
If work emerges: Add to tree, keep going
If blocked: Mark blocked, work on unblocked tasks
// Bottom-up view from any task (current → parent → grandparent → root)
const tree = await getDependencyTree({ taskId: currentTask.id });
// Visual tree (top-down view from epic)
const visualTree = await drawTree({ taskId: epic.id });
console.log(visualTree); // Display to user
// Epic completion stats
const epicStatus = await getEpicStatus({ epicId: epic.id });
discovered-from dependency| Action | API Function |
|---|---|
| Set workspace | setWorkspace({ workspacePath }) |
| Create epic | createTask({ title, type: "epic", priority: 1 }) |
| Create task | createTask({ title, type: "task", priority }) |
| Link to parent | addDependency({ taskId, dependsOnId, type: "parent-child" }) |
| Claim task | updateTask({ taskId, status: "in_progress" }) |
| Complete task | closeTask({ taskId, reason }) |
| Update task | updateTask({ taskId, notes, description, title }) |
| View tree | getDependencyTree({ taskId }) |
| Draw visual tree | drawTree({ taskId }) |
| Check progress | getEpicStatus({ epicId }) |
| Find ready work | findReadyTasks({ limit }) |
| Mark blocked | updateTask({ taskId, status: "blocked" }) |
| Show task details | showTask({ taskId }) |
| Append notes | appendNotes({ taskId, notes }) |
// Something came up while working
const distraction = await createTask({
title: "Refactor utils.ts for clarity",
type: "task",
priority: 3
});
await addDependency({
taskId: distraction.id,
dependsOnId: currentParent.id,
type: "parent-child"
});
// Now it's captured, back to current work
// Realized task is bigger than expected
const subtask1 = await createTask({
title: "Part 1: Schema validation",
type: "task",
priority: 1
});
const subtask2 = await createTask({
title: "Part 2: Error handling",
type: "task",
priority: 1
});
await addDependency({
taskId: subtask1.id,
dependsOnId: complexTask.id,
type: "parent-child"
});
await addDependency({
taskId: subtask2.id,
dependsOnId: complexTask.id,
type: "parent-child"
});
// Parent stays open until children done
await updateTask({
taskId: complexTask.id,
status: "open"
});
// Found something that must be done first
const prerequisite = await createTask({
title: "Add user_id column to sessions table",
type: "task",
priority: 0
});
await addDependency({
taskId: currentTask.id,
dependsOnId: prerequisite.id,
type: "blocks"
});
await updateTask({
taskId: currentTask.id,
status: "blocked"
});
await updateTask({
taskId: prerequisite.id,
status: "in_progress"
});
// When requirements change and tree needs reorganizing
await setWorkspace({ workspacePath });
// Create new epic/structure
const newEpic = await createTask({
title: "Revised Approach",
type: "epic",
priority: 1
});
// Create tasks programmatically
const tasks = await Promise.all([
createTask({ title: "New component A", type: "task", priority: 1 }),
createTask({ title: "New component B", type: "task", priority: 1 }),
createTask({ title: "Integration layer", type: "task", priority: 2 })
]);
// Link all at once
for (const task of tasks) {
await addDependency({
taskId: task.id,
dependsOnId: newEpic.id,
type: "parent-child"
});
}
// Close obsolete tasks
await closeTask({
taskId: oldTask.id,
reason: "Superseded by revised approach"
});
type TaskType = "bug" | "feature" | "task" | "epic" | "chore";
type TaskStatus = "open" | "in_progress" | "blocked" | "closed";
type DependencyType = "parent-child" | "blocks" | "related" | "discovered-from";
interface Task {
id: string;
title: string;
description: string;
status: TaskStatus;
priority: number;
taskType: TaskType;
createdAt: string;
updatedAt: string;
}
interface EpicStatus {
epicId: string;
totalTasks: number;
completedTasks: number;
inProgressTasks: number;
blockedTasks: number;
openTasks: number;
completionPercentage: number;
}
STOP if you catch yourself:
closeTask()findReadyTasks() when looking for next workAll of these mean: Use Discovery Trees with the TypeScript API for visible, emergent planning.
Just-in-time planning:
Emergent structure:
Visual progress:
Focus maintenance:
Structured design dialogue that validates ideas before implementation begins.
Comprehensive design intelligence for web and mobile UI/UX across 10 technology stacks.
Comprehensive implementation plans for multi-step tasks, breaking down specs into bite-sized, testable steps.
Introduction to the obra skills system with mandatory skill invocation rules and best practices.
Execute a written implementation plan with critical review and task checkpoints.
Delegate independent tasks to specialized agents working concurrently with isolated context.
Isolated git worktrees with smart directory selection and safety verification.
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
Plan searchable and shareable content that drives traffic, builds authority, and generates leads.
README-first repository scanner that extracts commands and classifies reproduction candidates without executing them.
Brainstorm and prioritize marketing strategies tailored to your SaaS stage, budget, and goals.
Plan and optimize your website's page hierarchy, navigation, URL structure, and internal linking.
The world's fastest calendar for remote work
Capture, organize, and utilize your knowledge effortlessly.
Instant Summaries of Audio & Video Interviews with AnySummary
Transform PDFs into engaging mind maps.
Chat with any PDF instantly
Create an optimal daily plan using your voice
A productivity platform to centralize organizational knowledge and workflows with contextual AI assistance.
AskYourPDF Pricing Plans: Tailored to Your Needs