192
profiles/opencode/skill/overseer-plan/references/api.md
Normal file
192
profiles/opencode/skill/overseer-plan/references/api.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# Overseer Codemode MCP API
|
||||
|
||||
Execute JavaScript code to interact with Overseer task management.
|
||||
|
||||
## Task Interfaces
|
||||
|
||||
```typescript
|
||||
// Basic task - returned by list(), create(), start(), complete()
|
||||
// Note: Does NOT include context or learnings fields
|
||||
interface Task {
|
||||
id: string;
|
||||
parentId: string | null;
|
||||
description: string;
|
||||
priority: 1 | 2 | 3 | 4 | 5;
|
||||
completed: boolean;
|
||||
completedAt: string | null;
|
||||
startedAt: string | null;
|
||||
createdAt: string; // ISO 8601
|
||||
updatedAt: string;
|
||||
result: string | null; // Completion notes
|
||||
commitSha: string | null; // Auto-populated on complete
|
||||
depth: 0 | 1 | 2; // 0=milestone, 1=task, 2=subtask
|
||||
blockedBy?: string[]; // Blocking task IDs (omitted if empty)
|
||||
blocks?: string[]; // Tasks this blocks (omitted if empty)
|
||||
bookmark?: string; // VCS bookmark name (if started)
|
||||
startCommit?: string; // Commit SHA at start
|
||||
effectivelyBlocked: boolean; // True if task OR ancestor has incomplete blockers
|
||||
}
|
||||
|
||||
// Task with full context - returned by get(), nextReady()
|
||||
interface TaskWithContext extends Task {
|
||||
context: {
|
||||
own: string; // This task's context
|
||||
parent?: string; // Parent's context (depth > 0)
|
||||
milestone?: string; // Root milestone's context (depth > 1)
|
||||
};
|
||||
learnings: {
|
||||
own: Learning[]; // This task's learnings (bubbled from completed children)
|
||||
parent: Learning[]; // Parent's learnings (depth > 0)
|
||||
milestone: Learning[]; // Milestone's learnings (depth > 1)
|
||||
};
|
||||
}
|
||||
|
||||
// Task tree structure - returned by tree()
|
||||
interface TaskTree {
|
||||
task: Task;
|
||||
children: TaskTree[];
|
||||
}
|
||||
|
||||
// Progress summary - returned by progress()
|
||||
interface TaskProgress {
|
||||
total: number;
|
||||
completed: number;
|
||||
ready: number; // !completed && !effectivelyBlocked
|
||||
blocked: number; // !completed && effectivelyBlocked
|
||||
}
|
||||
|
||||
// Task type alias for depth filter
|
||||
type TaskType = "milestone" | "task" | "subtask";
|
||||
```
|
||||
|
||||
## Learning Interface
|
||||
|
||||
```typescript
|
||||
interface Learning {
|
||||
id: string;
|
||||
taskId: string;
|
||||
content: string;
|
||||
sourceTaskId: string | null;
|
||||
createdAt: string;
|
||||
}
|
||||
```
|
||||
|
||||
## Tasks API
|
||||
|
||||
```typescript
|
||||
declare const tasks: {
|
||||
list(filter?: {
|
||||
parentId?: string;
|
||||
ready?: boolean;
|
||||
completed?: boolean;
|
||||
depth?: 0 | 1 | 2; // 0=milestones, 1=tasks, 2=subtasks
|
||||
type?: TaskType; // Alias: "milestone"|"task"|"subtask" (mutually exclusive with depth)
|
||||
}): Promise<Task[]>;
|
||||
get(id: string): Promise<TaskWithContext>;
|
||||
create(input: {
|
||||
description: string;
|
||||
context?: string;
|
||||
parentId?: string;
|
||||
priority?: 1 | 2 | 3 | 4 | 5; // Must be 1-5
|
||||
blockedBy?: string[]; // Cannot be ancestors/descendants
|
||||
}): Promise<Task>;
|
||||
update(id: string, input: {
|
||||
description?: string;
|
||||
context?: string;
|
||||
priority?: 1 | 2 | 3 | 4 | 5;
|
||||
parentId?: string;
|
||||
}): Promise<Task>;
|
||||
start(id: string): Promise<Task>;
|
||||
complete(id: string, input?: { result?: string; learnings?: string[] }): Promise<Task>;
|
||||
reopen(id: string): Promise<Task>;
|
||||
delete(id: string): Promise<void>;
|
||||
block(taskId: string, blockerId: string): Promise<void>;
|
||||
unblock(taskId: string, blockerId: string): Promise<void>;
|
||||
nextReady(milestoneId?: string): Promise<TaskWithContext | null>;
|
||||
tree(rootId?: string): Promise<TaskTree | TaskTree[]>;
|
||||
search(query: string): Promise<Task[]>;
|
||||
progress(rootId?: string): Promise<TaskProgress>;
|
||||
};
|
||||
```
|
||||
|
||||
| Method | Returns | Description |
|
||||
|--------|---------|-------------|
|
||||
| `list` | `Task[]` | Filter by `parentId`, `ready`, `completed`, `depth`, `type` |
|
||||
| `get` | `TaskWithContext` | Get task with full context chain + inherited learnings |
|
||||
| `create` | `Task` | Create task (priority must be 1-5) |
|
||||
| `update` | `Task` | Update description, context, priority, parentId |
|
||||
| `start` | `Task` | **VCS required** - creates bookmark, records start commit |
|
||||
| `complete` | `Task` | **VCS required** - commits changes + bubbles learnings to parent |
|
||||
| `reopen` | `Task` | Reopen completed task |
|
||||
| `delete` | `void` | Delete task + best-effort VCS bookmark cleanup |
|
||||
| `block` | `void` | Add blocker (cannot be self, ancestor, or descendant) |
|
||||
| `unblock` | `void` | Remove blocker relationship |
|
||||
| `nextReady` | `TaskWithContext \| null` | Get deepest ready leaf with full context |
|
||||
| `tree` | `TaskTree \| TaskTree[]` | Get task tree (all milestones if no ID) |
|
||||
| `search` | `Task[]` | Search by description/context/result (case-insensitive) |
|
||||
| `progress` | `TaskProgress` | Aggregate counts for milestone or all tasks |
|
||||
|
||||
## Learnings API
|
||||
|
||||
Learnings are added via `tasks.complete(id, { learnings: [...] })` and bubble to immediate parent (preserving `sourceTaskId`).
|
||||
|
||||
```typescript
|
||||
declare const learnings: {
|
||||
list(taskId: string): Promise<Learning[]>;
|
||||
};
|
||||
```
|
||||
|
||||
| Method | Description |
|
||||
|--------|-------------|
|
||||
| `list` | List learnings for task |
|
||||
|
||||
## VCS Integration (Required for Workflow)
|
||||
|
||||
VCS operations are **automatically handled** by the tasks API:
|
||||
|
||||
| Task Operation | VCS Effect |
|
||||
|----------------|------------|
|
||||
| `tasks.start(id)` | **VCS required** - creates bookmark `task/<id>`, records start commit |
|
||||
| `tasks.complete(id)` | **VCS required** - commits changes (NothingToCommit = success) |
|
||||
| `tasks.delete(id)` | Best-effort bookmark cleanup (logs warning on failure) |
|
||||
|
||||
**VCS (jj or git) is required** for start/complete. Fails with `NotARepository` if none found. CRUD operations work without VCS.
|
||||
|
||||
## Quick Examples
|
||||
|
||||
```javascript
|
||||
// Create milestone with subtask
|
||||
const milestone = await tasks.create({
|
||||
description: "Build authentication system",
|
||||
context: "JWT-based auth with refresh tokens",
|
||||
priority: 1
|
||||
});
|
||||
|
||||
const subtask = await tasks.create({
|
||||
description: "Implement token refresh logic",
|
||||
parentId: milestone.id,
|
||||
context: "Handle 7-day expiry"
|
||||
});
|
||||
|
||||
// Start work (VCS required - creates bookmark)
|
||||
await tasks.start(subtask.id);
|
||||
|
||||
// ... do implementation work ...
|
||||
|
||||
// Complete task with learnings (VCS required - commits changes, bubbles learnings to parent)
|
||||
await tasks.complete(subtask.id, {
|
||||
result: "Implemented using jose library",
|
||||
learnings: ["Use jose instead of jsonwebtoken"]
|
||||
});
|
||||
|
||||
// Get progress summary
|
||||
const progress = await tasks.progress(milestone.id);
|
||||
// -> { total: 2, completed: 1, ready: 1, blocked: 0 }
|
||||
|
||||
// Search tasks
|
||||
const authTasks = await tasks.search("authentication");
|
||||
|
||||
// Get task tree
|
||||
const tree = await tasks.tree(milestone.id);
|
||||
// -> { task: Task, children: TaskTree[] }
|
||||
```
|
||||
177
profiles/opencode/skill/overseer-plan/references/examples.md
Normal file
177
profiles/opencode/skill/overseer-plan/references/examples.md
Normal file
@@ -0,0 +1,177 @@
|
||||
# Examples
|
||||
|
||||
## Example 1: With Breakdown
|
||||
|
||||
### Input (`auth-plan.md`)
|
||||
|
||||
```markdown
|
||||
# Plan: Add Authentication System
|
||||
|
||||
## Implementation
|
||||
1. Create database schema for users/tokens
|
||||
2. Implement auth controller with endpoints
|
||||
3. Add JWT middleware for route protection
|
||||
4. Build frontend login/register forms
|
||||
5. Add integration tests
|
||||
```
|
||||
|
||||
### Execution
|
||||
|
||||
```javascript
|
||||
const milestone = await tasks.create({
|
||||
description: "Add Authentication System",
|
||||
context: `# Add Authentication System\n\n## Implementation\n1. Create database schema...`,
|
||||
priority: 3
|
||||
});
|
||||
|
||||
const subtasks = [
|
||||
{ desc: "Create database schema for users/tokens", done: "Migration runs, tables exist with FK constraints" },
|
||||
{ desc: "Implement auth controller with endpoints", done: "POST /register, /login return expected responses" },
|
||||
{ desc: "Add JWT middleware for route protection", done: "Unauthorized requests return 401, valid tokens pass" },
|
||||
{ desc: "Build frontend login/register forms", done: "Forms render, submit without errors" },
|
||||
{ desc: "Add integration tests", done: "`npm test` passes with auth coverage" }
|
||||
];
|
||||
|
||||
for (const sub of subtasks) {
|
||||
await tasks.create({
|
||||
description: sub.desc,
|
||||
context: `Part of 'Add Authentication System'.\n\nDone when: ${sub.done}`,
|
||||
parentId: milestone.id
|
||||
});
|
||||
}
|
||||
|
||||
return { milestone: milestone.id, subtaskCount: subtasks.length };
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
```
|
||||
Created milestone task_01ABC from plan
|
||||
|
||||
Analyzed plan structure: Found 5 distinct implementation steps
|
||||
Created 5 subtasks:
|
||||
- task_02XYZ: Create database schema for users/tokens
|
||||
- task_03ABC: Implement auth controller with endpoints
|
||||
- task_04DEF: Add JWT middleware for route protection
|
||||
- task_05GHI: Build frontend login/register forms
|
||||
- task_06JKL: Add integration tests
|
||||
|
||||
View structure: execute `await tasks.list({ parentId: "task_01ABC" })`
|
||||
```
|
||||
|
||||
## Example 2: No Breakdown
|
||||
|
||||
### Input (`bugfix-plan.md`)
|
||||
|
||||
```markdown
|
||||
# Plan: Fix Login Validation Bug
|
||||
|
||||
## Problem
|
||||
Login fails when username has spaces
|
||||
|
||||
## Solution
|
||||
Update validation regex in auth.ts line 42
|
||||
```
|
||||
|
||||
### Execution
|
||||
|
||||
```javascript
|
||||
const milestone = await tasks.create({
|
||||
description: "Fix Login Validation Bug",
|
||||
context: `# Fix Login Validation Bug\n\n## Problem\nLogin fails...`,
|
||||
priority: 3
|
||||
});
|
||||
|
||||
return { milestone: milestone.id, breakdown: false };
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
```
|
||||
Created milestone task_01ABC from plan
|
||||
|
||||
Plan describes a cohesive single task. No subtask breakdown needed.
|
||||
|
||||
View task: execute `await tasks.get("task_01ABC")`
|
||||
```
|
||||
|
||||
## Example 3: Epic-Level (Two-Level Hierarchy)
|
||||
|
||||
### Input (`full-auth-plan.md`)
|
||||
|
||||
```markdown
|
||||
# Complete User Authentication System
|
||||
|
||||
## Phase 1: Backend Infrastructure
|
||||
1. Database schema for users/sessions
|
||||
2. Password hashing with bcrypt
|
||||
3. JWT token generation
|
||||
|
||||
## Phase 2: API Endpoints
|
||||
1. POST /auth/register
|
||||
2. POST /auth/login
|
||||
3. POST /auth/logout
|
||||
|
||||
## Phase 3: Frontend
|
||||
1. Login/register forms
|
||||
2. Protected routes
|
||||
3. Session persistence
|
||||
```
|
||||
|
||||
### Execution
|
||||
|
||||
```javascript
|
||||
const milestone = await tasks.create({
|
||||
description: "Complete User Authentication System",
|
||||
context: `<full-markdown>`,
|
||||
priority: 3
|
||||
});
|
||||
|
||||
const phases = [
|
||||
{ name: "Backend Infrastructure", items: [
|
||||
{ desc: "Database schema", done: "Migration runs, tables exist" },
|
||||
{ desc: "Password hashing", done: "bcrypt hashes verified in tests" },
|
||||
{ desc: "JWT tokens", done: "Token generation/validation works" }
|
||||
]},
|
||||
{ name: "API Endpoints", items: [
|
||||
{ desc: "POST /auth/register", done: "Creates user, returns 201" },
|
||||
{ desc: "POST /auth/login", done: "Returns JWT on valid credentials" },
|
||||
{ desc: "POST /auth/logout", done: "Invalidates session, returns 200" }
|
||||
]},
|
||||
{ name: "Frontend", items: [
|
||||
{ desc: "Login/register forms", done: "Forms render, submit successfully" },
|
||||
{ desc: "Protected routes", done: "Redirect to login when unauthenticated" },
|
||||
{ desc: "Session persistence", done: "Refresh maintains logged-in state" }
|
||||
]}
|
||||
];
|
||||
|
||||
for (const phase of phases) {
|
||||
const phaseTask = await tasks.create({
|
||||
description: phase.name,
|
||||
parentId: milestone.id
|
||||
});
|
||||
for (const item of phase.items) {
|
||||
await tasks.create({
|
||||
description: item.desc,
|
||||
context: `Part of '${phase.name}'.\n\nDone when: ${item.done}`,
|
||||
parentId: phaseTask.id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return milestone;
|
||||
```
|
||||
|
||||
### Output
|
||||
|
||||
```
|
||||
Created milestone task_01ABC from plan
|
||||
|
||||
Analyzed plan structure: Found 3 major phases
|
||||
Created as milestone with 3 tasks:
|
||||
- task_02XYZ: Backend Infrastructure (3 subtasks)
|
||||
- task_03ABC: API Endpoints (3 subtasks)
|
||||
- task_04DEF: Frontend (3 subtasks)
|
||||
|
||||
View structure: execute `await tasks.list({ parentId: "task_01ABC" })`
|
||||
```
|
||||
@@ -0,0 +1,210 @@
|
||||
# Implementation Instructions
|
||||
|
||||
**For the skill agent executing `/overseer-plan`.** Follow this workflow exactly.
|
||||
|
||||
## Step 1: Read Markdown File
|
||||
|
||||
Read the provided file using the Read tool.
|
||||
|
||||
## Step 2: Extract Title
|
||||
|
||||
- Parse first `#` heading as title
|
||||
- Strip "Plan: " prefix if present (case-insensitive)
|
||||
- Fallback: use filename without extension
|
||||
|
||||
## Step 3: Create Milestone via MCP
|
||||
|
||||
Basic creation:
|
||||
|
||||
```javascript
|
||||
const milestone = await tasks.create({
|
||||
description: "<extracted-title>",
|
||||
context: `<full-markdown-content>`,
|
||||
priority: <priority-if-provided-else-3>
|
||||
});
|
||||
return milestone;
|
||||
```
|
||||
|
||||
With `--parent` option:
|
||||
|
||||
```javascript
|
||||
const task = await tasks.create({
|
||||
description: "<extracted-title>",
|
||||
context: `<full-markdown-content>`,
|
||||
parentId: "<parent-id>",
|
||||
priority: <priority-if-provided-else-3>
|
||||
});
|
||||
return task;
|
||||
```
|
||||
|
||||
Capture returned task ID for subsequent steps.
|
||||
|
||||
## Step 4: Analyze Plan Structure
|
||||
|
||||
### Breakdown Indicators
|
||||
|
||||
1. **Numbered/bulleted implementation lists (3-7 items)**
|
||||
```markdown
|
||||
## Implementation
|
||||
1. Create database schema
|
||||
2. Build API endpoints
|
||||
3. Add frontend components
|
||||
```
|
||||
|
||||
2. **Clear subsections under implementation/tasks/steps**
|
||||
```markdown
|
||||
### 1. Backend Changes
|
||||
- Modify server.ts
|
||||
|
||||
### 2. Frontend Updates
|
||||
- Update login form
|
||||
```
|
||||
|
||||
3. **File-specific sections**
|
||||
```markdown
|
||||
### `src/auth.ts` - Add JWT validation
|
||||
### `src/middleware.ts` - Create auth middleware
|
||||
```
|
||||
|
||||
4. **Sequential phases**
|
||||
```markdown
|
||||
**Phase 1: Database Layer**
|
||||
**Phase 2: API Layer**
|
||||
```
|
||||
|
||||
### Do NOT Break Down When
|
||||
|
||||
- Only 1-2 steps/items
|
||||
- Plan is a single cohesive fix
|
||||
- Content is exploratory ("investigate", "research")
|
||||
- Work items inseparable
|
||||
- Plan very short (<10 lines)
|
||||
|
||||
## Step 5: Validate Atomicity & Acceptance Criteria
|
||||
|
||||
For each proposed task, verify:
|
||||
- **Atomic**: Can be completed in single commit
|
||||
- **Validated**: Has clear acceptance criteria
|
||||
|
||||
If task too large -> split further.
|
||||
If no validation -> add to context:
|
||||
|
||||
```
|
||||
Done when: <specific observable criteria>
|
||||
```
|
||||
|
||||
Examples of good acceptance criteria:
|
||||
- "Done when: `npm test` passes, new migration applied"
|
||||
- "Done when: API returns 200 with expected payload"
|
||||
- "Done when: Component renders without console errors"
|
||||
- "Done when: Type check passes (`tsc --noEmit`)"
|
||||
|
||||
## Step 6: Oracle Review
|
||||
|
||||
Before creating tasks, invoke Oracle to review the proposed breakdown.
|
||||
|
||||
**Prompt Oracle with:**
|
||||
|
||||
```
|
||||
Review this task breakdown for "<milestone>":
|
||||
|
||||
1. <task> - Done when: <criteria>
|
||||
2. <task> - Done when: <criteria>
|
||||
...
|
||||
|
||||
Check:
|
||||
- Are tasks truly atomic (single commit)?
|
||||
- Is validation criteria clear and observable?
|
||||
- Does milestone deliver demoable increment?
|
||||
- Missing dependencies/blockers?
|
||||
- Any tasks that should be split or merged?
|
||||
```
|
||||
|
||||
Incorporate Oracle's feedback, then proceed to create tasks.
|
||||
|
||||
## Step 7: Create Subtasks (If Breaking Down)
|
||||
|
||||
### Extract for Each Subtask
|
||||
|
||||
1. **Description**: Strip numbering, keep concise (1-10 words), imperative form
|
||||
2. **Context**: Section content + "Part of [milestone description]" + acceptance criteria
|
||||
|
||||
### Flat Breakdown
|
||||
|
||||
```javascript
|
||||
const subtasks = [
|
||||
{ description: "Create database schema", context: "Schema for users/tokens. Part of 'Add Auth'.\n\nDone when: Migration runs, tables exist with FK constraints." },
|
||||
{ description: "Build API endpoints", context: "POST /auth/register, /auth/login. Part of 'Add Auth'.\n\nDone when: Endpoints return expected responses, tests pass." }
|
||||
];
|
||||
|
||||
const created = [];
|
||||
for (const sub of subtasks) {
|
||||
const task = await tasks.create({
|
||||
description: sub.description,
|
||||
context: sub.context,
|
||||
parentId: milestone.id
|
||||
});
|
||||
created.push(task);
|
||||
}
|
||||
return { milestone: milestone.id, subtasks: created };
|
||||
```
|
||||
|
||||
### Epic-Level Breakdown (phases with sub-items)
|
||||
|
||||
```javascript
|
||||
// Create phase as task under milestone
|
||||
const phase = await tasks.create({
|
||||
description: "Backend Infrastructure",
|
||||
context: "Phase 1 context...",
|
||||
parentId: milestoneId
|
||||
});
|
||||
|
||||
// Create subtasks under phase
|
||||
for (const item of phaseItems) {
|
||||
await tasks.create({
|
||||
description: item.description,
|
||||
context: item.context,
|
||||
parentId: phase.id
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
## Step 8: Report Results
|
||||
|
||||
### Subtasks Created
|
||||
|
||||
```
|
||||
Created milestone <id> from plan
|
||||
|
||||
Analyzed plan structure: Found <N> distinct implementation steps
|
||||
Created <N> subtasks:
|
||||
- <id>: <description>
|
||||
- <id>: <description>
|
||||
...
|
||||
|
||||
View structure: execute `await tasks.list({ parentId: "<id>" })`
|
||||
```
|
||||
|
||||
### No Breakdown
|
||||
|
||||
```
|
||||
Created milestone <id> from plan
|
||||
|
||||
Plan describes a cohesive single task. No subtask breakdown needed.
|
||||
|
||||
View task: execute `await tasks.get("<id>")`
|
||||
```
|
||||
|
||||
### Epic-Level Breakdown
|
||||
|
||||
```
|
||||
Created milestone <id> from plan
|
||||
|
||||
Analyzed plan structure: Found <N> major phases
|
||||
Created as milestone with <N> tasks:
|
||||
- <id>: <phase-name> (<M> subtasks)
|
||||
- <id>: <phase-name> (<M> subtasks)
|
||||
...
|
||||
|
||||
View structure: execute `await tasks.list({ parentId: "<id>" })`
|
||||
```
|
||||
Reference in New Issue
Block a user