refactor: rename sisyphus_task to delegate_task

- Rename directories: sisyphus-task → delegate-task
- Rename types: SisyphusTaskArgs → DelegateTaskArgs, etc.
- Rename functions: createSisyphusTask → createDelegateTask
- Rename constants: SISYPHUS_TASK_* → DELEGATE_TASK_*
- Update tool name: sisyphus_task → delegate_task
- Update all prompts, docs, and tests
This commit is contained in:
justsisyphus
2026-01-16 17:34:40 +09:00
parent 6008388a4e
commit 188bbef018
46 changed files with 289 additions and 303 deletions

View File

@@ -96,7 +96,7 @@ oh-my-opencode/
- **Over-exploration**: Stop searching when sufficient context found
- **High temperature**: Don't use >0.3 for code-related agents
- **Broad tool access**: Prefer explicit `include` over unrestricted access
- **Sequential agent calls**: Use `sisyphus_task` for parallel execution
- **Sequential agent calls**: Use `delegate_task` for parallel execution
- **Heavy PreToolUse logic**: Slows every tool call
- **Self-planning for complex tasks**: Spawn planning agent (Prometheus) instead
- **Trust agent self-reports**: ALWAYS verify results independently

View File

@@ -583,7 +583,7 @@ Hand your best tools to your best colleagues. Now they can properly refactor, na
- **ast_grep_search**: AST-aware code pattern search (25 languages)
- **ast_grep_replace**: AST-aware code replacement
- **call_omo_agent**: Spawn specialized explore/librarian agents. Supports `run_in_background` parameter for async execution.
- **sisyphus_task**: Category-based task delegation with specialized agents. Supports pre-configured categories (visual, business-logic) or direct agent targeting. Use `background_output` to retrieve results and `background_cancel` to cancel tasks. See [Categories](#categories).
- **delegate_task**: Category-based task delegation with specialized agents. Supports pre-configured categories (visual, business-logic) or direct agent targeting. Use `background_output` to retrieve results and `background_cancel` to cancel tasks. See [Categories](#categories).
#### Session Management
@@ -922,7 +922,7 @@ Available agents: `oracle`, `librarian`, `explore`, `frontend-ui-ux-engineer`, `
Oh My OpenCode includes built-in skills that provide additional capabilities:
- **playwright**: Browser automation with Playwright MCP. Use for web scraping, testing, screenshots, and browser interactions.
- **git-master**: Git expert for atomic commits, rebase/squash, and history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with `sisyphus_task(category='quick', skills=['git-master'], ...)` to save context.
- **git-master**: Git expert for atomic commits, rebase/squash, and history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with `delegate_task(category='quick', skills=['git-master'], ...)` to save context.
Disable built-in skills via `disabled_skills` in `~/.config/opencode/oh-my-opencode.json` or `.opencode/oh-my-opencode.json`:
@@ -1061,7 +1061,7 @@ Configure concurrency limits for background agent tasks. This controls how many
### Categories
Categories enable domain-specific task delegation via the `sisyphus_task` tool. Each category applies runtime presets (model, temperature, prompt additions) when calling the `Sisyphus-Junior` agent.
Categories enable domain-specific task delegation via the `delegate_task` tool. Each category applies runtime presets (model, temperature, prompt additions) when calling the `Sisyphus-Junior` agent.
**Default Categories:**
@@ -1073,12 +1073,12 @@ Categories enable domain-specific task delegation via the `sisyphus_task` tool.
**Usage:**
```
// Via sisyphus_task tool
sisyphus_task(category="visual", prompt="Create a responsive dashboard component")
sisyphus_task(category="business-logic", prompt="Design the payment processing flow")
// Via delegate_task tool
delegate_task(category="visual", prompt="Create a responsive dashboard component")
delegate_task(category="business-logic", prompt="Design the payment processing flow")
// Or target a specific agent directly
sisyphus_task(agent="oracle", prompt="Review this architecture")
delegate_task(agent="oracle", prompt="Review this architecture")
```
**Custom Categories:**

View File

@@ -580,7 +580,7 @@ gh repo star code-yeongyu/oh-my-opencode
- **ast_grep_search**AST 感知的代码模式搜索25 种语言)
- **ast_grep_replace**AST 感知的代码替换
- **call_omo_agent**:生成专业的 explore/librarian 智能体。支持 `run_in_background` 参数进行异步执行。
- **sisyphus_task**基于类别的任务委派使用专业智能体。支持预配置的类别visual、business-logic或直接指定智能体。使用 `background_output` 检索结果,使用 `background_cancel` 取消任务。参见[类别](#类别)。
- **delegate_task**基于类别的任务委派使用专业智能体。支持预配置的类别visual、business-logic或直接指定智能体。使用 `background_output` 检索结果,使用 `background_cancel` 取消任务。参见[类别](#类别)。
#### 会话管理
@@ -931,7 +931,7 @@ Oh My OpenCode 从以下位置读取和执行钩子:
Oh My OpenCode 包含提供额外功能的内置技能:
- **playwright**:使用 Playwright MCP 进行浏览器自动化。用于网页抓取、测试、截图和浏览器交互。
- **git-master**Git 专家用于原子提交、rebase/squash 和历史搜索blame、bisect、log -S。**强烈推荐**:与 `sisyphus_task(category='quick', skills=['git-master'], ...)` 一起使用以节省上下文。
- **git-master**Git 专家用于原子提交、rebase/squash 和历史搜索blame、bisect、log -S。**强烈推荐**:与 `delegate_task(category='quick', skills=['git-master'], ...)` 一起使用以节省上下文。
通过 `~/.config/opencode/oh-my-opencode.json` 或 `.opencode/oh-my-opencode.json` 中的 `disabled_skills` 禁用内置技能:
@@ -1070,7 +1070,7 @@ Oh My OpenCode 包含提供额外功能的内置技能:
### 类别
类别通过 `sisyphus_task` 工具实现领域特定的任务委派。每个类别预配置一个专业的 `Sisyphus-Junior-{category}` 智能体,带有优化的模型设置和提示。
类别通过 `delegate_task` 工具实现领域特定的任务委派。每个类别预配置一个专业的 `Sisyphus-Junior-{category}` 智能体,带有优化的模型设置和提示。
**默认类别:**
@@ -1082,12 +1082,12 @@ Oh My OpenCode 包含提供额外功能的内置技能:
**使用方法:**
```
// 通过 sisyphus_task 工具
sisyphus_task(category="visual", prompt="创建一个响应式仪表板组件")
sisyphus_task(category="business-logic", prompt="设计支付处理流程")
// 通过 delegate_task 工具
delegate_task(category="visual", prompt="创建一个响应式仪表板组件")
delegate_task(category="business-logic", prompt="设计支付处理流程")
// 或直接指定特定智能体
sisyphus_task(agent="oracle", prompt="审查这个架构")
delegate_task(agent="oracle", prompt="审查这个架构")
```
**自定义类别:**

View File

@@ -9,7 +9,7 @@ Instead of delegating everything to a single AI agent, it's far more efficient t
- **Category**: "What kind of work is this?" (determines model, temperature, prompt mindset)
- **Skill**: "What tools and knowledge are needed?" (injects specialized knowledge, MCP tools, workflows)
By combining these two concepts, you can generate optimal agents through `sisyphus_task`.
By combining these two concepts, you can generate optimal agents through `delegate_task`.
---
@@ -30,10 +30,10 @@ A Category is an agent configuration preset optimized for specific domains.
### Usage
Specify the `category` parameter when invoking the `sisyphus_task` tool.
Specify the `category` parameter when invoking the `delegate_task` tool.
```typescript
sisyphus_task(
delegate_task(
category="visual-engineering",
prompt="Add a responsive chart component to the dashboard page"
)
@@ -72,7 +72,7 @@ A Skill is a mechanism that injects **specialized knowledge (Context)** and **to
Add desired skill names to the `skills` array.
```typescript
sisyphus_task(
delegate_task(
category="quick",
skills=["git-master"],
prompt="Commit current changes. Follow commit message style."
@@ -124,7 +124,7 @@ You can create powerful specialized agents by combining Categories and Skills.
---
## 5. sisyphus_task Prompt Guide
## 5. delegate_task Prompt Guide
When delegating, **clear and specific** prompts are essential. Include these 7 elements:

View File

@@ -149,4 +149,4 @@ You can control related features in `oh-my-opencode.json`.
1. **Don't Rush**: Invest sufficient time in the interview with Prometheus. The more perfect the plan, the faster the execution.
2. **Single Plan Principle**: No matter how large the task, contain all TODOs in one plan file (`.md`). This prevents context fragmentation.
3. **Active Delegation**: During execution, delegate to specialized agents via `sisyphus_task` rather than modifying code directly.
3. **Active Delegation**: During execution, delegate to specialized agents via `delegate_task` rather than modifying code directly.

View File

@@ -53,7 +53,7 @@ agents/
## ANTI-PATTERNS
- **Trusting reports**: NEVER trust subagent self-reports; always verify outputs.
- **High temp**: Don't use >0.3 for code agents (Sisyphus/Prometheus use 0.1).
- **Sequential calls**: Prefer `sisyphus_task` with `run_in_background` for parallelism.
- **Sequential calls**: Prefer `delegate_task` with `run_in_background` for parallelism.
## SHARED PROMPTS
- **build-prompt.ts**: Unified base for Sisyphus and Builder variants.

View File

@@ -29,7 +29,7 @@ export function createExploreAgent(model: string = DEFAULT_MODEL): AgentConfig {
"write",
"edit",
"task",
"sisyphus_task",
"delegate_task",
"call_omo_agent",
])

View File

@@ -26,7 +26,7 @@ export function createLibrarianAgent(model: string = DEFAULT_MODEL): AgentConfig
"write",
"edit",
"task",
"sisyphus_task",
"delegate_task",
"call_omo_agent",
])

View File

@@ -275,7 +275,7 @@ const metisRestrictions = createAgentToolRestrictions([
"write",
"edit",
"task",
"sisyphus_task",
"delegate_task",
])
const DEFAULT_MODEL = "anthropic/claude-opus-4-5"

View File

@@ -353,7 +353,7 @@ export function createMomusAgent(model: string = DEFAULT_MODEL): AgentConfig {
"write",
"edit",
"task",
"sisyphus_task",
"delegate_task",
])
const base = {

View File

@@ -102,7 +102,7 @@ export function createOracleAgent(model: string = DEFAULT_MODEL): AgentConfig {
"write",
"edit",
"task",
"sisyphus_task",
"delegate_task",
])
const base = {

View File

@@ -2,13 +2,13 @@ import type { AgentConfig } from "@opencode-ai/sdk"
import type { AgentPromptMetadata } from "./types"
import type { AvailableAgent, AvailableSkill } from "./sisyphus-prompt-builder"
import type { CategoryConfig } from "../config/schema"
import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../tools/sisyphus-task/constants"
import { DEFAULT_CATEGORIES, CATEGORY_DESCRIPTIONS } from "../tools/delegate-task/constants"
import { createAgentToolRestrictions } from "../shared/permission-compat"
/**
* Orchestrator Sisyphus - Master Orchestrator Agent
*
* Orchestrates work via sisyphus_task() to complete ALL tasks in a todo list until fully done
* Orchestrates work via delegate_task() to complete ALL tasks in a todo list until fully done
* You are the conductor of a symphony of specialized agents.
*/
@@ -65,8 +65,8 @@ Categories spawn \`Sisyphus-Junior-{category}\` with optimized settings:
${categoryRows.join("\n")}
\`\`\`typescript
sisyphus_task(category="visual-engineering", prompt="...") // UI/frontend work
sisyphus_task(category="ultrabrain", prompt="...") // Backend/strategic work
delegate_task(category="visual-engineering", prompt="...") // UI/frontend work
delegate_task(category="ultrabrain", prompt="...") // Backend/strategic work
\`\`\``
}
@@ -95,9 +95,9 @@ ${skillRows.join("\n")}
**Usage:**
\`\`\`typescript
sisyphus_task(category="visual-engineering", skills=["frontend-ui-ux"], prompt="...")
sisyphus_task(category="general", skills=["playwright"], prompt="...") // Browser testing
sisyphus_task(category="visual-engineering", skills=["frontend-ui-ux", "playwright"], prompt="...") // UI with browser testing
delegate_task(category="visual-engineering", skills=["frontend-ui-ux"], prompt="...")
delegate_task(category="general", skills=["playwright"], prompt="...") // Browser testing
delegate_task(category="visual-engineering", skills=["frontend-ui-ux", "playwright"], prompt="...") // UI with browser testing
\`\`\`
**IMPORTANT:**
@@ -297,8 +297,8 @@ Search **external references** (docs, OSS, web). Fire proactively when unfamilia
**ANTI-PATTERN (DO NOT DO THIS):**
\`\`\`typescript
// ❌ WRONG: Background for simple searches
sisyphus_task(agent="explore", prompt="Find where X is defined") // Just use grep!
sisyphus_task(agent="librarian", prompt="How to use Y") // Just use context7!
delegate_task(agent="explore", prompt="Find where X is defined") // Just use grep!
delegate_task(agent="librarian", prompt="How to use Y") // Just use context7!
// ✅ CORRECT: Direct tools for most cases
grep(pattern="functionName", path="src/")
@@ -310,8 +310,8 @@ context7_query-docs(libraryId, query)
\`\`\`typescript
// Only for massive parallel research with 5+ independent queries
// AND you have other implementation work to do simultaneously
sisyphus_task(agent="explore", prompt="...") // Query 1
sisyphus_task(agent="explore", prompt="...") // Query 2
delegate_task(agent="explore", prompt="...") // Query 1
delegate_task(agent="explore", prompt="...") // Query 2
// ... continue implementing other code while these run
\`\`\`
@@ -690,10 +690,10 @@ If the user's approach seems problematic:
</Constraints>
<role>
You are the MASTER ORCHESTRATOR - the conductor of a symphony of specialized agents via \`sisyphus_task()\`. Your sole mission is to ensure EVERY SINGLE TASK in a todo list gets completed to PERFECTION.
You are the MASTER ORCHESTRATOR - the conductor of a symphony of specialized agents via \`delegate_task()\`. Your sole mission is to ensure EVERY SINGLE TASK in a todo list gets completed to PERFECTION.
## CORE MISSION
Orchestrate work via \`sisyphus_task()\` to complete ALL tasks in a given todo list until fully done.
Orchestrate work via \`delegate_task()\` to complete ALL tasks in a given todo list until fully done.
## IDENTITY & PHILOSOPHY
@@ -709,16 +709,16 @@ You do NOT execute tasks yourself. You DELEGATE, COORDINATE, and VERIFY. Think o
- ✅ YOU CAN: Read files, run commands, verify results, check tests, inspect outputs
- ❌ YOU MUST DELEGATE: Code writing, file modification, bug fixes, test creation
2. **VERIFY OBSESSIVELY**: Subagents LIE. Always verify their claims with your own tools (Read, Bash, lsp_diagnostics).
3. **PARALLELIZE WHEN POSSIBLE**: If tasks are independent (no dependencies, no file conflicts), invoke multiple \`sisyphus_task()\` calls in PARALLEL.
4. **ONE TASK PER CALL**: Each \`sisyphus_task()\` call handles EXACTLY ONE task. Never batch multiple tasks.
5. **CONTEXT IS KING**: Pass COMPLETE, DETAILED context in every \`sisyphus_task()\` prompt.
3. **PARALLELIZE WHEN POSSIBLE**: If tasks are independent (no dependencies, no file conflicts), invoke multiple \`delegate_task()\` calls in PARALLEL.
4. **ONE TASK PER CALL**: Each \`delegate_task()\` call handles EXACTLY ONE task. Never batch multiple tasks.
5. **CONTEXT IS KING**: Pass COMPLETE, DETAILED context in every \`delegate_task()\` prompt.
6. **WISDOM ACCUMULATES**: Gather learnings from each task and pass to the next.
### CRITICAL: DETAILED PROMPTS ARE MANDATORY
**The #1 cause of agent failure is VAGUE PROMPTS.**
When calling \`sisyphus_task()\`, your prompt MUST be:
When calling \`delegate_task()\`, your prompt MUST be:
- **EXHAUSTIVELY DETAILED**: Include EVERY piece of context the agent needs
- **EXPLICITLY STRUCTURED**: Use the 7-section format (TASK, EXPECTED OUTCOME, REQUIRED SKILLS, REQUIRED TOOLS, MUST DO, MUST NOT DO, CONTEXT)
- **CONCRETE, NOT ABSTRACT**: Exact file paths, exact commands, exact expected outputs
@@ -726,12 +726,12 @@ When calling \`sisyphus_task()\`, your prompt MUST be:
**BAD (will fail):**
\`\`\`
sisyphus_task(category="ultrabrain", prompt="Fix the auth bug")
delegate_task(category="ultrabrain", prompt="Fix the auth bug")
\`\`\`
**GOOD (will succeed):**
\`\`\`
sisyphus_task(
delegate_task(
category="ultrabrain",
prompt="""
## TASK
@@ -875,7 +875,7 @@ Before processing sequentially, check if there are PARALLELIZABLE tasks:
1. **Identify parallelizable task group** from the parallelization map (from Step 1)
2. **If parallelizable group found** (e.g., Tasks 2, 3, 4 can run simultaneously):
- Prepare DETAILED execution prompts for ALL tasks in the group
- Invoke multiple \`sisyphus_task()\` calls IN PARALLEL (single message, multiple calls)
- Invoke multiple \`delegate_task()\` calls IN PARALLEL (single message, multiple calls)
- Wait for ALL to complete
- Process ALL responses and update wisdom repository
- Mark ALL completed tasks
@@ -889,16 +889,16 @@ Before processing sequentially, check if there are PARALLELIZABLE tasks:
- Extract the EXACT task text
- Analyze the task nature
#### 3.2: Choose Category or Agent for sisyphus_task()
#### 3.2: Choose Category or Agent for delegate_task()
**sisyphus_task() has TWO modes - choose ONE:**
**delegate_task() has TWO modes - choose ONE:**
{CATEGORY_SECTION}
\`\`\`typescript
sisyphus_task(agent="oracle", prompt="...") // Expert consultation
sisyphus_task(agent="explore", prompt="...") // Codebase search
sisyphus_task(agent="librarian", prompt="...") // External research
delegate_task(agent="oracle", prompt="...") // Expert consultation
delegate_task(agent="explore", prompt="...") // Codebase search
delegate_task(agent="librarian", prompt="...") // External research
\`\`\`
{AGENT_SECTION}
@@ -970,7 +970,7 @@ STRATEGIC CATEGORY JUSTIFICATION (MANDATORY):
---
**BEFORE invoking sisyphus_task(), you MUST state:**
**BEFORE invoking delegate_task(), you MUST state:**
\`\`\`
Category: [general OR specific-category]
@@ -987,7 +987,7 @@ Justification: [Brief for general, EXTENSIVE for strategic/most-capable]
#### 3.3: Prepare Execution Directive (DETAILED PROMPT IS EVERYTHING)
**CRITICAL: The quality of your \`sisyphus_task()\` prompt determines success or failure.**
**CRITICAL: The quality of your \`delegate_task()\` prompt determines success or failure.**
**RULE: If your prompt is short, YOU WILL FAIL. Make it EXHAUSTIVELY DETAILED.**
@@ -1063,7 +1063,7 @@ NOTEPAD PATH: .sisyphus/notepads/{plan-name}/ (READ for wisdom, WRITE findings)
PLAN PATH: .sisyphus/plans/{plan-name}.md (READ ONLY - NEVER MODIFY)
### Inherited Wisdom from Notepad (READ BEFORE EVERY DELEGATION)
[Extract from .sisyphus/notepads/{plan-name}/*.md before calling sisyphus_task]
[Extract from .sisyphus/notepads/{plan-name}/*.md before calling delegate_task]
- Conventions discovered: [from learnings.md]
- Successful approaches: [from learnings.md]
- Failed approaches to avoid: [from issues.md]
@@ -1082,12 +1082,12 @@ PLAN PATH: .sisyphus/plans/{plan-name}.md (READ ONLY - NEVER MODIFY)
**PROMPT LENGTH CHECK**: Your prompt should be 50-200 lines. If it's under 20 lines, it's TOO SHORT.
#### 3.4: Invoke via sisyphus_task()
#### 3.4: Invoke via delegate_task()
**CRITICAL: Pass the COMPLETE 7-section directive from 3.3. SHORT PROMPTS = FAILURE.**
\`\`\`typescript
sisyphus_task(
delegate_task(
agent="[selected-agent-name]", // Agent you chose in step 3.2
background=false, // ALWAYS false for task delegation - wait for completion
prompt=\`
@@ -1153,7 +1153,7 @@ Task N: [exact task description]
**⚠️ CRITICAL: SUBAGENTS LIE. NEVER trust their claims. ALWAYS verify yourself.**
**⚠️ YOU ARE THE QA GATE. If you don't verify, NO ONE WILL.**
After \`sisyphus_task()\` completes, you MUST perform COMPREHENSIVE QA:
After \`delegate_task()\` completes, you MUST perform COMPREHENSIVE QA:
**STEP 1: PROJECT-LEVEL CODE VERIFICATION (MANDATORY)**
1. **Run \`lsp_diagnostics\` at DIRECTORY or PROJECT level**:
@@ -1203,12 +1203,12 @@ After \`sisyphus_task()\` completes, you MUST perform COMPREHENSIVE QA:
If task reports FAILED or BLOCKED:
- **THINK**: "What information or help is needed to fix this?"
- **IDENTIFY**: Which agent is best suited to provide that help?
- **INVOKE**: via \`sisyphus_task()\` with MORE DETAILED prompt including failure context
- **INVOKE**: via \`delegate_task()\` with MORE DETAILED prompt including failure context
- **RE-ATTEMPT**: Re-invoke with new insights/guidance and EXPANDED context
- If external blocker: Document and continue to next independent task
- Maximum 3 retry attempts per task
**NEVER try to analyze or fix failures yourself. Always delegate via \`sisyphus_task()\`.**
**NEVER try to analyze or fix failures yourself. Always delegate via \`delegate_task()\`.**
**FAILURE RECOVERY PROMPT EXPANSION**: When retrying, your prompt MUST include:
- What was attempted
@@ -1256,7 +1256,7 @@ TOTAL TIME: [duration]
### THE GOLDEN RULE
**YOU ORCHESTRATE, YOU DO NOT EXECUTE.**
Every time you're tempted to write code, STOP and ask: "Should I delegate this via \`sisyphus_task()\`?"
Every time you're tempted to write code, STOP and ask: "Should I delegate this via \`delegate_task()\`?"
The answer is almost always YES.
### WHAT YOU CAN DO vs WHAT YOU MUST DELEGATE
@@ -1278,11 +1278,11 @@ The answer is almost always YES.
- [X] Git commits (delegate to git-master)
**DELEGATION TARGETS:**
- \`sisyphus_task(category="ultrabrain", background=false)\` → backend/logic implementation
- \`sisyphus_task(category="visual-engineering", background=false)\` → frontend/UI implementation
- \`sisyphus_task(agent="git-master", background=false)\` → ALL git commits
- \`sisyphus_task(agent="document-writer", background=false)\` → documentation
- \`sisyphus_task(agent="debugging-master", background=false)\` → complex debugging
- \`delegate_task(category="ultrabrain", background=false)\` → backend/logic implementation
- \`delegate_task(category="visual-engineering", background=false)\` → frontend/UI implementation
- \`delegate_task(agent="git-master", background=false)\` → ALL git commits
- \`delegate_task(agent="document-writer", background=false)\` → documentation
- \`delegate_task(agent="debugging-master", background=false)\` → complex debugging
**⚠️ CRITICAL: background=false is MANDATORY for all task delegations.**
@@ -1352,8 +1352,8 @@ All learnings, decisions, and insights MUST be recorded in the notepad system fo
\`\`\`
**Usage Protocol:**
1. **BEFORE each sisyphus_task() call** → Read notepad files to gather accumulated wisdom
2. **INCLUDE in every sisyphus_task() prompt** → Pass relevant notepad content as "INHERITED WISDOM" section
1. **BEFORE each delegate_task() call** → Read notepad files to gather accumulated wisdom
2. **INCLUDE in every delegate_task() prompt** → Pass relevant notepad content as "INHERITED WISDOM" section
3. After each task completion → Instruct subagent to append findings to appropriate category
4. When encountering issues → Document in issues.md or problems.md
@@ -1366,7 +1366,7 @@ All learnings, decisions, and insights MUST be recorded in the notepad system fo
**READING NOTEPAD BEFORE DELEGATION (MANDATORY):**
Before EVERY \`sisyphus_task()\` call, you MUST:
Before EVERY \`delegate_task()\` call, you MUST:
1. Check if notepad exists: \`glob(".sisyphus/notepads/{plan-name}/*.md")\`
2. If exists, read recent entries (use Read tool, focus on recent ~50 lines per file)
@@ -1380,7 +1380,7 @@ Read(".sisyphus/notepads/my-plan/learnings.md")
Read(".sisyphus/notepads/my-plan/issues.md")
Read(".sisyphus/notepads/my-plan/decisions.md")
# Then include in sisyphus_task prompt:
# Then include in delegate_task prompt:
## INHERITED WISDOM FROM PREVIOUS TASKS
- Pattern discovered: Use kebab-case for file names (learnings.md)
- Avoid: Direct DOM manipulation - use React refs instead (issues.md)
@@ -1395,11 +1395,11 @@ Read(".sisyphus/notepads/my-plan/decisions.md")
1. **Executing tasks yourself**: NEVER write implementation code, NEVER read/write/edit files directly
2. **Ignoring parallelizability**: If tasks CAN run in parallel, they SHOULD run in parallel
3. **Batch delegation**: NEVER send multiple tasks to one \`sisyphus_task()\` call (one task per call)
3. **Batch delegation**: NEVER send multiple tasks to one \`delegate_task()\` call (one task per call)
4. **Losing context**: ALWAYS pass accumulated wisdom in EVERY prompt
5. **Giving up early**: RETRY failed tasks (max 3 attempts)
6. **Rushing**: Quality over speed - but parallelize when possible
7. **Direct file operations**: NEVER use Read/Write/Edit/Bash for file operations - ALWAYS use \`sisyphus_task()\`
7. **Direct file operations**: NEVER use Read/Write/Edit/Bash for file operations - ALWAYS use \`delegate_task()\`
8. **SHORT PROMPTS**: If your prompt is under 30 lines, it's TOO SHORT. EXPAND IT.
9. **Wrong category/agent**: Match task type to category/agent systematically (see Decision Matrix)
@@ -1441,7 +1441,7 @@ If task cannot be completed after 3 attempts:
You are the MASTER ORCHESTRATOR. Your job is to:
1. **CREATE TODO** to track overall progress
2. **READ** the todo list (check for parallelizability)
3. **DELEGATE** via \`sisyphus_task()\` with DETAILED prompts (parallel when possible)
3. **DELEGATE** via \`delegate_task()\` with DETAILED prompts (parallel when possible)
4. **⚠️ QA VERIFY** - Run project-level \`lsp_diagnostics\`, build, and tests after EVERY delegation
5. **ACCUMULATE** wisdom from completions
6. **REPORT** final status
@@ -1449,9 +1449,9 @@ You are the MASTER ORCHESTRATOR. Your job is to:
**CRITICAL REMINDERS:**
- NEVER execute tasks yourself
- NEVER read/write/edit files directly
- ALWAYS use \`sisyphus_task(category=...)\` or \`sisyphus_task(agent=...)\`
- ALWAYS use \`delegate_task(category=...)\` or \`delegate_task(agent=...)\`
- PARALLELIZE when tasks are independent
- One task per \`sisyphus_task()\` call (never batch)
- One task per \`delegate_task()\` call (never batch)
- Pass COMPLETE context in EVERY prompt (50+ lines minimum)
- Accumulate and forward all learnings
- **⚠️ RUN lsp_diagnostics AT PROJECT/DIRECTORY LEVEL after EVERY delegation**
@@ -1489,7 +1489,7 @@ export function createOrchestratorSisyphusAgent(ctx?: OrchestratorContext): Agen
])
return {
description:
"Orchestrates work via sisyphus_task() to complete ALL tasks in a todo list until fully done",
"Orchestrates work via delegate_task() to complete ALL tasks in a todo list until fully done",
mode: "primary" as const,
model: ctx?.model ?? DEFAULT_MODEL,
temperature: 0.1,

View File

@@ -291,8 +291,8 @@ Or should I just note down this single fix?"
**Research First:**
\`\`\`typescript
sisyphus_task(agent="explore", prompt="Find all usages of [target] using lsp_find_references pattern...", background=true)
sisyphus_task(agent="explore", prompt="Find test coverage for [affected code]...", background=true)
delegate_task(agent="explore", prompt="Find all usages of [target] using lsp_find_references pattern...", background=true)
delegate_task(agent="explore", prompt="Find test coverage for [affected code]...", background=true)
\`\`\`
**Interview Focus:**
@@ -315,9 +315,9 @@ sisyphus_task(agent="explore", prompt="Find test coverage for [affected code]...
**Pre-Interview Research (MANDATORY):**
\`\`\`typescript
// Launch BEFORE asking user questions
sisyphus_task(agent="explore", prompt="Find similar implementations in codebase...", background=true)
sisyphus_task(agent="explore", prompt="Find project patterns for [feature type]...", background=true)
sisyphus_task(agent="librarian", prompt="Find best practices for [technology]...", background=true)
delegate_task(agent="explore", prompt="Find similar implementations in codebase...", background=true)
delegate_task(agent="explore", prompt="Find project patterns for [feature type]...", background=true)
delegate_task(agent="librarian", prompt="Find best practices for [technology]...", background=true)
\`\`\`
**Interview Focus** (AFTER research):
@@ -356,7 +356,7 @@ Based on your stack, I'd recommend NextAuth.js - it integrates well with Next.js
Run this check:
\`\`\`typescript
sisyphus_task(agent="explore", prompt="Find test infrastructure: package.json test scripts, test config files (jest.config, vitest.config, pytest.ini, etc.), existing test files (*.test.*, *.spec.*, test_*). Report: 1) Does test infra exist? 2) What framework? 3) Example test file patterns.", background=true)
delegate_task(agent="explore", prompt="Find test infrastructure: package.json test scripts, test config files (jest.config, vitest.config, pytest.ini, etc.), existing test files (*.test.*, *.spec.*, test_*). Report: 1) Does test infra exist? 2) What framework? 3) Example test file patterns.", background=true)
\`\`\`
#### Step 2: Ask the Test Question (MANDATORY)
@@ -445,13 +445,13 @@ Add to draft immediately:
**Research First:**
\`\`\`typescript
sisyphus_task(agent="explore", prompt="Find current system architecture and patterns...", background=true)
sisyphus_task(agent="librarian", prompt="Find architectural best practices for [domain]...", background=true)
delegate_task(agent="explore", prompt="Find current system architecture and patterns...", background=true)
delegate_task(agent="librarian", prompt="Find architectural best practices for [domain]...", background=true)
\`\`\`
**Oracle Consultation** (recommend when stakes are high):
\`\`\`typescript
sisyphus_task(agent="oracle", prompt="Architecture consultation needed: [context]...", background=false)
delegate_task(agent="oracle", prompt="Architecture consultation needed: [context]...", background=false)
\`\`\`
**Interview Focus:**
@@ -468,9 +468,9 @@ sisyphus_task(agent="oracle", prompt="Architecture consultation needed: [context
**Parallel Investigation:**
\`\`\`typescript
sisyphus_task(agent="explore", prompt="Find how X is currently handled...", background=true)
sisyphus_task(agent="librarian", prompt="Find official docs for Y...", background=true)
sisyphus_task(agent="librarian", prompt="Find OSS implementations of Z...", background=true)
delegate_task(agent="explore", prompt="Find how X is currently handled...", background=true)
delegate_task(agent="librarian", prompt="Find official docs for Y...", background=true)
delegate_task(agent="librarian", prompt="Find OSS implementations of Z...", background=true)
\`\`\`
**Interview Focus:**
@@ -496,17 +496,17 @@ sisyphus_task(agent="librarian", prompt="Find OSS implementations of Z...", back
**For Understanding Codebase:**
\`\`\`typescript
sisyphus_task(agent="explore", prompt="Find all files related to [topic]. Show patterns, conventions, and structure.", background=true)
delegate_task(agent="explore", prompt="Find all files related to [topic]. Show patterns, conventions, and structure.", background=true)
\`\`\`
**For External Knowledge:**
\`\`\`typescript
sisyphus_task(agent="librarian", prompt="Find official documentation for [library]. Focus on [specific feature] and best practices.", background=true)
delegate_task(agent="librarian", prompt="Find official documentation for [library]. Focus on [specific feature] and best practices.", background=true)
\`\`\`
**For Implementation Examples:**
\`\`\`typescript
sisyphus_task(agent="librarian", prompt="Find open source implementations of [feature]. Look for production-quality examples.", background=true)
delegate_task(agent="librarian", prompt="Find open source implementations of [feature]. Look for production-quality examples.", background=true)
\`\`\`
## Interview Mode Anti-Patterns
@@ -599,7 +599,7 @@ todoWrite([
**BEFORE generating the plan**, summon Metis to catch what you might have missed:
\`\`\`typescript
sisyphus_task(
delegate_task(
agent="Metis (Plan Consultant)",
prompt=\`Review this planning session before I generate the work plan:
@@ -750,7 +750,7 @@ If no, the plan is ready. Run \`/start-work\` to begin."
\`\`\`typescript
// After generating initial plan
while (true) {
const result = sisyphus_task(
const result = delegate_task(
agent="Momus (Plan Reviewer)",
prompt=".sisyphus/plans/{name}.md",
background=false

View File

@@ -138,13 +138,13 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
})
})
describe("tool safety (task/sisyphus_task blocked, call_omo_agent allowed)", () => {
test("task and sisyphus_task remain blocked, call_omo_agent is allowed via tools format", () => {
describe("tool safety (task/delegate_task blocked, call_omo_agent allowed)", () => {
test("task and delegate_task remain blocked, call_omo_agent is allowed via tools format", () => {
// #given
const override = {
tools: {
task: true,
sisyphus_task: true,
delegate_task: true,
call_omo_agent: true,
read: true,
},
@@ -158,25 +158,25 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
const permission = result.permission as Record<string, string> | undefined
if (tools) {
expect(tools.task).toBe(false)
expect(tools.sisyphus_task).toBe(false)
expect(tools.delegate_task).toBe(false)
// call_omo_agent is NOW ALLOWED for subagents to spawn explore/librarian
expect(tools.call_omo_agent).toBe(true)
expect(tools.read).toBe(true)
}
if (permission) {
expect(permission.task).toBe("deny")
expect(permission.sisyphus_task).toBe("deny")
expect(permission.delegate_task).toBe("deny")
// call_omo_agent is NOW ALLOWED for subagents to spawn explore/librarian
expect(permission.call_omo_agent).toBe("allow")
}
})
test("task and sisyphus_task remain blocked when using permission format override", () => {
test("task and delegate_task remain blocked when using permission format override", () => {
// #given
const override = {
permission: {
task: "allow",
sisyphus_task: "allow",
delegate_task: "allow",
call_omo_agent: "allow",
read: "allow",
},
@@ -185,17 +185,17 @@ describe("createSisyphusJuniorAgentWithOverrides", () => {
// #when
const result = createSisyphusJuniorAgentWithOverrides(override as Parameters<typeof createSisyphusJuniorAgentWithOverrides>[0])
// #then - task/sisyphus_task blocked, but call_omo_agent allowed for explore/librarian spawning
// #then - task/delegate_task blocked, but call_omo_agent allowed for explore/librarian spawning
const tools = result.tools as Record<string, boolean> | undefined
const permission = result.permission as Record<string, string> | undefined
if (tools) {
expect(tools.task).toBe(false)
expect(tools.sisyphus_task).toBe(false)
expect(tools.delegate_task).toBe(false)
expect(tools.call_omo_agent).toBe(true)
}
if (permission) {
expect(permission.task).toBe("deny")
expect(permission.sisyphus_task).toBe("deny")
expect(permission.delegate_task).toBe("deny")
expect(permission.call_omo_agent).toBe("allow")
}
})

View File

@@ -14,7 +14,7 @@ Execute tasks directly. NEVER delegate or spawn other agents.
<Critical_Constraints>
BLOCKED ACTIONS (will fail if attempted):
- task tool: BLOCKED
- sisyphus_task tool: BLOCKED
- delegate_task tool: BLOCKED
ALLOWED: call_omo_agent - You CAN spawn explore/librarian agents for research.
You work ALONE for implementation. No delegation of implementation tasks.
@@ -75,7 +75,7 @@ function buildSisyphusJuniorPrompt(promptAppend?: string): string {
// Core tools that Sisyphus-Junior must NEVER have access to
// Note: call_omo_agent is ALLOWED so subagents can spawn explore/librarian
const BLOCKED_TOOLS = ["task", "sisyphus_task"]
const BLOCKED_TOOLS = ["task", "delegate_task"]
export const SISYPHUS_JUNIOR_DEFAULTS = {
model: "anthropic/claude-sonnet-4-5",

View File

@@ -122,7 +122,7 @@ IMPORTANT: If codebase appears undisciplined, verify before assuming:
const SISYPHUS_PRE_DELEGATION_PLANNING = `### Pre-Delegation Planning (MANDATORY)
**BEFORE every \`sisyphus_task\` call, EXPLICITLY declare your reasoning.**
**BEFORE every \`delegate_task\` call, EXPLICITLY declare your reasoning.**
#### Step 1: Identify Task Requirements
@@ -160,27 +160,27 @@ Ask yourself:
**MANDATORY FORMAT:**
\`\`\`
I will use sisyphus_task with:
I will use delegate_task with:
- **Category/Agent**: [name]
- **Reason**: [why this choice fits the task]
- **Skills** (if any): [skill names]
- **Expected Outcome**: [what success looks like]
\`\`\`
**Then** make the sisyphus_task call.
**Then** make the delegate_task call.
#### Examples
**✅ CORRECT: Explicit Pre-Declaration**
\`\`\`
I will use sisyphus_task with:
I will use delegate_task with:
- **Category**: visual
- **Reason**: This task requires building a responsive dashboard UI with animations - visual design is the core requirement
- **Skills**: ["frontend-ui-ux"]
- **Expected Outcome**: Fully styled, responsive dashboard component with smooth transitions
sisyphus_task(
delegate_task(
category="visual",
skills=["frontend-ui-ux"],
prompt="Create a responsive dashboard component with..."
@@ -190,13 +190,13 @@ sisyphus_task(
**✅ CORRECT: Agent-Specific Delegation**
\`\`\`
I will use sisyphus_task with:
I will use delegate_task with:
- **Agent**: oracle
- **Reason**: This architectural decision involves trade-offs between scalability and complexity - requires high-IQ strategic analysis
- **Skills**: []
- **Expected Outcome**: Clear recommendation with pros/cons analysis
sisyphus_task(
delegate_task(
agent="oracle",
skills=[],
prompt="Evaluate this microservices architecture proposal..."
@@ -206,13 +206,13 @@ sisyphus_task(
**✅ CORRECT: Background Exploration**
\`\`\`
I will use sisyphus_task with:
I will use delegate_task with:
- **Agent**: explore
- **Reason**: Need to find all authentication implementations across the codebase - this is contextual grep
- **Skills**: []
- **Expected Outcome**: List of files containing auth patterns
sisyphus_task(
delegate_task(
agent="explore",
background=true,
prompt="Find all authentication implementations in the codebase"
@@ -223,7 +223,7 @@ sisyphus_task(
\`\`\`
// Immediately calling without explicit reasoning
sisyphus_task(category="visual", prompt="Build a dashboard")
delegate_task(category="visual", prompt="Build a dashboard")
\`\`\`
**❌ WRONG: Vague Reasoning**
@@ -231,12 +231,12 @@ sisyphus_task(category="visual", prompt="Build a dashboard")
\`\`\`
I'll use visual category because it's frontend work.
sisyphus_task(category="visual", ...)
delegate_task(category="visual", ...)
\`\`\`
#### Enforcement
**BLOCKING VIOLATION**: If you call \`sisyphus_task\` without the 4-part declaration, you have violated protocol.
**BLOCKING VIOLATION**: If you call \`delegate_task\` without the 4-part declaration, you have violated protocol.
**Recovery**: Stop, declare explicitly, then proceed.`
@@ -247,11 +247,11 @@ const SISYPHUS_PARALLEL_EXECUTION = `### Parallel Execution (DEFAULT behavior)
\`\`\`typescript
// CORRECT: Always background, always parallel
// Contextual Grep (internal)
sisyphus_task(agent="explore", prompt="Find auth implementations in our codebase...")
sisyphus_task(agent="explore", prompt="Find error handling patterns here...")
delegate_task(agent="explore", prompt="Find auth implementations in our codebase...")
delegate_task(agent="explore", prompt="Find error handling patterns here...")
// Reference Grep (external)
sisyphus_task(agent="librarian", prompt="Find JWT best practices in official docs...")
sisyphus_task(agent="librarian", prompt="Find how production apps handle auth in Express...")
delegate_task(agent="librarian", prompt="Find JWT best practices in official docs...")
delegate_task(agent="librarian", prompt="Find how production apps handle auth in Express...")
// Continue working immediately. Collect with background_output when needed.
// WRONG: Sequential or blocking
@@ -274,7 +274,7 @@ Pass \`resume=session_id\` to continue previous agent with FULL CONTEXT PRESERVE
**Example:**
\`\`\`
sisyphus_task(resume="ses_abc123", prompt="The previous search missed X. Also look for Y.")
delegate_task(resume="ses_abc123", prompt="The previous search missed X. Also look for Y.")
\`\`\`
### Search Stop Conditions

View File

@@ -13,7 +13,7 @@ import { createOrchestratorSisyphusAgent, orchestratorSisyphusAgent } from "./or
import { createMomusAgent } from "./momus"
import type { AvailableAgent } from "./sisyphus-prompt-builder"
import { deepMerge } from "../shared"
import { DEFAULT_CATEGORIES } from "../tools/sisyphus-task/constants"
import { DEFAULT_CATEGORIES } from "../tools/delegate-task/constants"
import { resolveMultipleSkills } from "../features/opencode-skill-loader/skill-content"
type AgentSource = AgentFactory | AgentConfig

View File

@@ -84,7 +84,7 @@ export const HookNameSchema = z.enum([
"claude-code-hooks",
"auto-slash-command",
"edit-error-recovery",
"sisyphus-task-retry",
"delegate-task-retry",
"prometheus-md-only",
"start-work",
"sisyphus-orchestrator",

View File

@@ -61,7 +61,7 @@ features/
- Session-scoped MCP server lifecycle management
## ANTI-PATTERNS
- Sequential execution for independent tasks (use `sisyphus_task`)
- Sequential execution for independent tasks (use `delegate_task`)
- Trusting agent self-reports without verification
- Blocking main thread during loader initialization
- Manual version bumping in `package.json`

View File

@@ -980,7 +980,7 @@ describe("BackgroundManager.trackTask", () => {
sessionID: "session-1",
parentSessionID: "parent-session",
description: "external task",
agent: "sisyphus_task",
agent: "delegate_task",
concurrencyKey: "external-key",
}
@@ -1015,7 +1015,7 @@ describe("BackgroundManager.resume concurrency key", () => {
sessionID: "session-1",
parentSessionID: "parent-session",
description: "external task",
agent: "sisyphus_task",
agent: "delegate_task",
concurrencyKey: "external-key",
})

View File

@@ -180,7 +180,7 @@ export class BackgroundManager {
tools: {
...getAgentToolRestrictions(input.agent),
task: false,
sisyphus_task: false,
delegate_task: false,
call_omo_agent: true,
},
parts: [{ type: "text", text: input.prompt }],
@@ -249,7 +249,7 @@ export class BackgroundManager {
}
/**
* Track a task created elsewhere (e.g., from sisyphus_task) for notification tracking.
* Track a task created elsewhere (e.g., from delegate_task) for notification tracking.
* This allows tasks created by other tools to receive the same toast/prompt notifications.
*/
async trackTask(input: {
@@ -296,7 +296,7 @@ export class BackgroundManager {
return existingTask
}
const concurrencyGroup = input.concurrencyKey ?? input.agent ?? "sisyphus_task"
const concurrencyGroup = input.concurrencyKey ?? input.agent ?? "delegate_task"
// Acquire concurrency slot if a key is provided
if (input.concurrencyKey) {
@@ -310,7 +310,7 @@ export class BackgroundManager {
parentMessageID: "",
description: input.description,
prompt: "",
agent: input.agent || "sisyphus_task",
agent: input.agent || "delegate_task",
status: "running",
startedAt: new Date(),
progress: {
@@ -409,7 +409,7 @@ export class BackgroundManager {
tools: {
...getAgentToolRestrictions(existingTask.agent),
task: false,
sisyphus_task: false,
delegate_task: false,
call_omo_agent: true,
},
parts: [{ type: "text", text: input.prompt }],

View File

@@ -45,12 +45,12 @@ Don't wait—these run async while main session works.
\`\`\`
// Fire all at once, collect results later
sisyphus_task(agent="explore", prompt="Project structure: PREDICT standard patterns for detected language → REPORT deviations only")
sisyphus_task(agent="explore", prompt="Entry points: FIND main files → REPORT non-standard organization")
sisyphus_task(agent="explore", prompt="Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) → REPORT project-specific rules")
sisyphus_task(agent="explore", prompt="Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments → LIST forbidden patterns")
sisyphus_task(agent="explore", prompt="Build/CI: FIND .github/workflows, Makefile → REPORT non-standard patterns")
sisyphus_task(agent="explore", prompt="Test patterns: FIND test configs, test structure → REPORT unique conventions")
delegate_task(agent="explore", prompt="Project structure: PREDICT standard patterns for detected language → REPORT deviations only")
delegate_task(agent="explore", prompt="Entry points: FIND main files → REPORT non-standard organization")
delegate_task(agent="explore", prompt="Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) → REPORT project-specific rules")
delegate_task(agent="explore", prompt="Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments → LIST forbidden patterns")
delegate_task(agent="explore", prompt="Build/CI: FIND .github/workflows, Makefile → REPORT non-standard patterns")
delegate_task(agent="explore", prompt="Test patterns: FIND test configs, test structure → REPORT unique conventions")
\`\`\`
<dynamic-agents>
@@ -76,9 +76,9 @@ max_depth=$(find . -type d -not -path '*/node_modules/*' -not -path '*/.git/*' |
Example spawning:
\`\`\`
// 500 files, 50k lines, depth 6, 15 large files → spawn 5+5+2+1 = 13 additional agents
sisyphus_task(agent="explore", prompt="Large file analysis: FIND files >500 lines, REPORT complexity hotspots")
sisyphus_task(agent="explore", prompt="Deep modules at depth 4+: FIND hidden patterns, internal conventions")
sisyphus_task(agent="explore", prompt="Cross-cutting concerns: FIND shared utilities across directories")
delegate_task(agent="explore", prompt="Large file analysis: FIND files >500 lines, REPORT complexity hotspots")
delegate_task(agent="explore", prompt="Deep modules at depth 4+: FIND hidden patterns, internal conventions")
delegate_task(agent="explore", prompt="Cross-cutting concerns: FIND shared utilities across directories")
// ... more based on calculation
\`\`\`
</dynamic-agents>
@@ -240,7 +240,7 @@ Launch document-writer agents for each location:
\`\`\`
for loc in AGENTS_LOCATIONS (except root):
sisyphus_task(agent="document-writer", prompt=\\\`
delegate_task(agent="document-writer", prompt=\\\`
Generate AGENTS.md for: \${loc.path}
- Reason: \${loc.reason}
- 30-80 lines max

View File

@@ -1,6 +1,6 @@
---
name: git-master
description: "MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with sisyphus_task(category='quick', skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'."
description: "MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with delegate_task(category='quick', skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'."
---
# Git Master Agent

View File

@@ -95,7 +95,7 @@ Interpret creatively and make unexpected choices that feel genuinely designed fo
const gitMasterSkill: BuiltinSkill = {
name: "git-master",
description:
"MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with sisyphus_task(category='quick', skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'.",
"MUST USE for ANY git operations. Atomic commits, rebase/squash, history search (blame, bisect, log -S). STRONGLY RECOMMENDED: Use with delegate_task(category='quick', skills=['git-master'], ...) to save context. Triggers: 'commit', 'rebase', 'squash', 'who wrote', 'when was X added', 'find the commit that'.",
template: `# Git Master Agent
You are a Git expert combining three specializations:

View File

@@ -24,7 +24,7 @@ export const TARGET_TOOLS = new Set([
export const AGENT_TOOLS = new Set([
"task",
"call_omo_agent",
"sisyphus_task",
"delegate_task",
]);
export const REMINDER_MESSAGE = `
@@ -32,13 +32,13 @@ export const REMINDER_MESSAGE = `
You called a search/fetch tool directly without leveraging specialized agents.
RECOMMENDED: Use sisyphus_task with explore/librarian agents for better results:
RECOMMENDED: Use delegate_task with explore/librarian agents for better results:
\`\`\`
// Parallel exploration - fire multiple agents simultaneously
sisyphus_task(agent="explore", prompt="Find all files matching pattern X")
sisyphus_task(agent="explore", prompt="Search for implementation of Y")
sisyphus_task(agent="librarian", prompt="Lookup documentation for Z")
delegate_task(agent="explore", prompt="Find all files matching pattern X")
delegate_task(agent="explore", prompt="Search for implementation of Y")
delegate_task(agent="librarian", prompt="Lookup documentation for Z")
// Then continue your work while they run in background
// System will notify you when each completes
@@ -50,5 +50,5 @@ WHY:
- Specialized agents have domain expertise
- Reduces context window usage in main session
ALWAYS prefer: Multiple parallel sisyphus_task calls > Direct tool calls
ALWAYS prefer: Multiple parallel delegate_task calls > Direct tool calls
`;

View File

@@ -145,13 +145,7 @@ export function createClaudeCodeHooksHook(
const hookContent = result.messages.join("\n\n")
log(`[claude-code-hooks] Injecting ${result.messages.length} hook messages`, { sessionID: input.sessionID, contentLength: hookContent.length, isFirstMessage })
if (isFirstMessage) {
const idx = output.parts.findIndex((p) => p.type === "text" && p.text)
if (idx >= 0) {
output.parts[idx].text = `${hookContent}\n\n${output.parts[idx].text ?? ""}`
log("UserPromptSubmit hooks prepended to first message parts directly", { sessionID: input.sessionID })
}
} else if (contextCollector) {
if (contextCollector) {
log("[DEBUG] Registering hook content to contextCollector", {
sessionID: input.sessionID,
contentLength: hookContent.length,
@@ -168,14 +162,6 @@ export function createClaudeCodeHooksHook(
sessionID: input.sessionID,
contentLength: hookContent.length,
})
} else {
const idx = output.parts.findIndex((p) => p.type === "text" && p.text)
if (idx >= 0) {
output.parts[idx].text = `${hookContent}\n\n${output.parts[idx].text ?? ""}`
log("Hook content prepended to message (fallback)", {
sessionID: input.sessionID,
})
}
}
}
}
@@ -257,7 +243,7 @@ export function createClaudeCodeHooksHook(
const cachedInput = getToolInput(input.sessionID, input.tool, input.callID) || {}
// Use metadata if available and non-empty, otherwise wrap output.output in a structured object
// This ensures plugin tools (call_omo_agent, sisyphus_task, task) that return strings
// This ensures plugin tools (call_omo_agent, delegate_task, task) that return strings
// get their results properly recorded in transcripts instead of empty {}
const metadata = output.metadata as Record<string, unknown> | undefined
const hasMetadata = metadata && typeof metadata === "object" && Object.keys(metadata).length > 0

View File

@@ -1,18 +1,18 @@
import { describe, expect, it } from "bun:test"
import {
SISYPHUS_TASK_ERROR_PATTERNS,
detectSisyphusTaskError,
DELEGATE_TASK_ERROR_PATTERNS,
detectDelegateTaskError,
buildRetryGuidance,
} from "./index"
describe("sisyphus-task-retry", () => {
describe("SISYPHUS_TASK_ERROR_PATTERNS", () => {
describe("DELEGATE_TASK_ERROR_PATTERNS", () => {
// #given error patterns are defined
// #then should include all known sisyphus_task error types
// #then should include all known delegate_task error types
it("should contain all known error patterns", () => {
expect(SISYPHUS_TASK_ERROR_PATTERNS.length).toBeGreaterThan(5)
expect(DELEGATE_TASK_ERROR_PATTERNS.length).toBeGreaterThan(5)
const patternTexts = SISYPHUS_TASK_ERROR_PATTERNS.map(p => p.pattern)
const patternTexts = DELEGATE_TASK_ERROR_PATTERNS.map(p => p.pattern)
expect(patternTexts).toContain("run_in_background")
expect(patternTexts).toContain("skills")
expect(patternTexts).toContain("category OR subagent_type")
@@ -21,14 +21,14 @@ describe("sisyphus-task-retry", () => {
})
})
describe("detectSisyphusTaskError", () => {
describe("detectDelegateTaskError", () => {
// #given tool output with run_in_background error
// #when detecting error
// #then should return matching error info
it("should detect run_in_background missing error", () => {
const output = "❌ Invalid arguments: 'run_in_background' parameter is REQUIRED. Use run_in_background=false for task delegation."
const result = detectSisyphusTaskError(output)
const result = detectDelegateTaskError(output)
expect(result).not.toBeNull()
expect(result?.errorType).toBe("missing_run_in_background")
@@ -37,7 +37,7 @@ describe("sisyphus-task-retry", () => {
it("should detect skills missing error", () => {
const output = "❌ Invalid arguments: 'skills' parameter is REQUIRED. Use skills=[] if no skills needed."
const result = detectSisyphusTaskError(output)
const result = detectDelegateTaskError(output)
expect(result).not.toBeNull()
expect(result?.errorType).toBe("missing_skills")
@@ -46,7 +46,7 @@ describe("sisyphus-task-retry", () => {
it("should detect category/subagent mutual exclusion error", () => {
const output = "❌ Invalid arguments: Provide EITHER category OR subagent_type, not both."
const result = detectSisyphusTaskError(output)
const result = detectDelegateTaskError(output)
expect(result).not.toBeNull()
expect(result?.errorType).toBe("mutual_exclusion")
@@ -55,7 +55,7 @@ describe("sisyphus-task-retry", () => {
it("should detect unknown category error", () => {
const output = '❌ Unknown category: "invalid-cat". Available: visual-engineering, ultrabrain, quick'
const result = detectSisyphusTaskError(output)
const result = detectDelegateTaskError(output)
expect(result).not.toBeNull()
expect(result?.errorType).toBe("unknown_category")
@@ -64,7 +64,7 @@ describe("sisyphus-task-retry", () => {
it("should detect unknown agent error", () => {
const output = '❌ Unknown agent: "fake-agent". Available agents: explore, librarian, oracle'
const result = detectSisyphusTaskError(output)
const result = detectDelegateTaskError(output)
expect(result).not.toBeNull()
expect(result?.errorType).toBe("unknown_agent")
@@ -73,7 +73,7 @@ describe("sisyphus-task-retry", () => {
it("should return null for successful output", () => {
const output = "Background task launched.\n\nTask ID: bg_12345\nSession ID: ses_abc"
const result = detectSisyphusTaskError(output)
const result = detectDelegateTaskError(output)
expect(result).toBeNull()
})

View File

@@ -1,12 +1,12 @@
import type { PluginInput } from "@opencode-ai/plugin"
export interface SisyphusTaskErrorPattern {
export interface DelegateTaskErrorPattern {
pattern: string
errorType: string
fixHint: string
}
export const SISYPHUS_TASK_ERROR_PATTERNS: SisyphusTaskErrorPattern[] = [
export const DELEGATE_TASK_ERROR_PATTERNS: DelegateTaskErrorPattern[] = [
{
pattern: "run_in_background",
errorType: "missing_run_in_background",
@@ -45,7 +45,7 @@ export const SISYPHUS_TASK_ERROR_PATTERNS: SisyphusTaskErrorPattern[] = [
{
pattern: "Cannot call primary agent",
errorType: "primary_agent",
fixHint: "Primary agents cannot be called via sisyphus_task. Use a subagent like 'explore', 'oracle', or 'librarian'",
fixHint: "Primary agents cannot be called via delegate_task. Use a subagent like 'explore', 'oracle', or 'librarian'",
},
{
pattern: "Skills not found",
@@ -59,10 +59,10 @@ export interface DetectedError {
originalOutput: string
}
export function detectSisyphusTaskError(output: string): DetectedError | null {
export function detectDelegateTaskError(output: string): DetectedError | null {
if (!output.includes("❌")) return null
for (const errorPattern of SISYPHUS_TASK_ERROR_PATTERNS) {
for (const errorPattern of DELEGATE_TASK_ERROR_PATTERNS) {
if (output.includes(errorPattern.pattern)) {
return {
errorType: errorPattern.errorType,
@@ -80,16 +80,16 @@ function extractAvailableList(output: string): string | null {
}
export function buildRetryGuidance(errorInfo: DetectedError): string {
const pattern = SISYPHUS_TASK_ERROR_PATTERNS.find(
const pattern = DELEGATE_TASK_ERROR_PATTERNS.find(
(p) => p.errorType === errorInfo.errorType
)
if (!pattern) {
return `[sisyphus_task ERROR] Fix the error and retry with correct parameters.`
return `[delegate_task ERROR] Fix the error and retry with correct parameters.`
}
let guidance = `
[sisyphus_task CALL FAILED - IMMEDIATE RETRY REQUIRED]
[delegate_task CALL FAILED - IMMEDIATE RETRY REQUIRED]
**Error Type**: ${errorInfo.errorType}
**Fix**: ${pattern.fixHint}
@@ -101,11 +101,11 @@ export function buildRetryGuidance(errorInfo: DetectedError): string {
}
guidance += `
**Action**: Retry sisyphus_task NOW with corrected parameters.
**Action**: Retry delegate_task NOW with corrected parameters.
Example of CORRECT call:
\`\`\`
sisyphus_task(
delegate_task(
description="Task description",
prompt="Detailed prompt...",
category="general", // OR subagent_type="explore"
@@ -118,15 +118,15 @@ sisyphus_task(
return guidance
}
export function createSisyphusTaskRetryHook(_ctx: PluginInput) {
export function createDelegateTaskRetryHook(_ctx: PluginInput) {
return {
"tool.execute.after": async (
input: { tool: string; sessionID: string; callID: string },
output: { title: string; output: string; metadata: unknown }
) => {
if (input.tool.toLowerCase() !== "sisyphus_task") return
if (input.tool.toLowerCase() !== "delegate_task") return
const errorInfo = detectSisyphusTaskError(output.output)
const errorInfo = detectDelegateTaskError(output.output)
if (errorInfo) {
const guidance = buildRetryGuidance(errorInfo)
output.output += `\n${guidance}`

View File

@@ -30,4 +30,4 @@ export { createPrometheusMdOnlyHook } from "./prometheus-md-only";
export { createTaskResumeInfoHook } from "./task-resume-info";
export { createStartWorkHook } from "./start-work";
export { createSisyphusOrchestratorHook } from "./sisyphus-orchestrator";
export { createSisyphusTaskRetryHook } from "./sisyphus-task-retry";
export { createDelegateTaskRetryHook } from "./delegate-task-retry";

View File

@@ -12,7 +12,7 @@ You ARE the planner. You ARE NOT an implementer. You DO NOT write code. You DO N
| Write/Edit | \`.sisyphus/**/*.md\` ONLY | Everything else |
| Read | All files | - |
| Bash | Research commands only | Implementation commands |
| sisyphus_task | explore, librarian | - |
| delegate_task | explore, librarian | - |
**IF YOU TRY TO WRITE/EDIT OUTSIDE \`.sisyphus/\`:**
- System will BLOCK your action
@@ -36,9 +36,9 @@ You ARE the planner. Your job: create bulletproof work plans.
### Research Protocol
1. **Fire parallel background agents** for comprehensive context:
\`\`\`
sisyphus_task(agent="explore", prompt="Find existing patterns for [topic] in codebase", background=true)
sisyphus_task(agent="explore", prompt="Find test infrastructure and conventions", background=true)
sisyphus_task(agent="librarian", prompt="Find official docs and best practices for [technology]", background=true)
delegate_task(agent="explore", prompt="Find existing patterns for [topic] in codebase", background=true)
delegate_task(agent="explore", prompt="Find test infrastructure and conventions", background=true)
delegate_task(agent="librarian", prompt="Find official docs and best practices for [technology]", background=true)
\`\`\`
2. **Wait for results** before planning - rushed plans fail
3. **Synthesize findings** into informed requirements
@@ -101,14 +101,14 @@ TELL THE USER WHAT AGENTS YOU WILL LEVERAGE NOW TO SATISFY USER'S REQUEST.
## EXECUTION RULES
- **TODO**: Track EVERY step. Mark complete IMMEDIATELY after each.
- **PARALLEL**: Fire independent agent calls simultaneously via sisyphus_task(background=true) - NEVER wait sequentially.
- **BACKGROUND FIRST**: Use sisyphus_task for exploration/research agents (10+ concurrent if needed).
- **PARALLEL**: Fire independent agent calls simultaneously via delegate_task(background=true) - NEVER wait sequentially.
- **BACKGROUND FIRST**: Use delegate_task for exploration/research agents (10+ concurrent if needed).
- **VERIFY**: Re-read request after completion. Check ALL requirements met before reporting done.
- **DELEGATE**: Don't do everything yourself - orchestrate specialized agents for their strengths.
## WORKFLOW
1. Analyze the request and identify required capabilities
2. Spawn exploration/librarian agents via sisyphus_task(background=true) in PARALLEL (10+ if needed)
2. Spawn exploration/librarian agents via delegate_task(background=true) in PARALLEL (10+ if needed)
3. Always Use Plan agent with gathered context to create detailed work breakdown
4. Execute with continuous verification against original requirements

View File

@@ -154,11 +154,11 @@ describe("prometheus-md-only", () => {
).resolves.toBeUndefined()
})
test("should inject read-only warning when Prometheus calls sisyphus_task", async () => {
test("should inject read-only warning when Prometheus calls delegate_task", async () => {
// #given
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
const input = {
tool: "sisyphus_task",
tool: "delegate_task",
sessionID: TEST_SESSION_ID,
callID: "call-1",
}
@@ -216,7 +216,7 @@ describe("prometheus-md-only", () => {
// #given
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
const input = {
tool: "sisyphus_task",
tool: "delegate_task",
sessionID: TEST_SESSION_ID,
callID: "call-1",
}
@@ -257,11 +257,11 @@ describe("prometheus-md-only", () => {
).resolves.toBeUndefined()
})
test("should not inject warning for non-Prometheus agents calling sisyphus_task", async () => {
test("should not inject warning for non-Prometheus agents calling delegate_task", async () => {
// #given
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
const input = {
tool: "sisyphus_task",
tool: "delegate_task",
sessionID: TEST_SESSION_ID,
callID: "call-1",
}

View File

@@ -61,7 +61,7 @@ function getMessageDir(sessionID: string): string | null {
return null
}
const TASK_TOOLS = ["sisyphus_task", "task", "call_omo_agent"]
const TASK_TOOLS = ["delegate_task", "task", "call_omo_agent"]
function getAgentFromMessageFiles(sessionID: string): string | undefined {
const messageDir = getMessageDir(sessionID)

View File

@@ -66,8 +66,8 @@ describe("sisyphus-orchestrator hook", () => {
})
describe("tool.execute.after handler", () => {
test("should ignore non-sisyphus_task tools", async () => {
// #given - hook and non-sisyphus_task tool
test("should ignore non-delegate_task tools", async () => {
// #given - hook and non-delegate_task tool
const hook = createSisyphusOrchestratorHook(createMockPluginInput())
const output = {
title: "Test Tool",
@@ -110,7 +110,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when
await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID },
{ tool: "delegate_task", sessionID },
output
)
@@ -134,14 +134,14 @@ describe("sisyphus-orchestrator hook", () => {
// #when
await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID },
{ tool: "delegate_task", sessionID },
output
)
// #then - standalone verification reminder appended
expect(output.output).toContain("Task completed successfully")
expect(output.output).toContain("MANDATORY:")
expect(output.output).toContain("sisyphus_task(resume=")
expect(output.output).toContain("delegate_task(resume=")
cleanupMessageStorage(sessionID)
})
@@ -171,7 +171,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when
await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID },
{ tool: "delegate_task", sessionID },
output
)
@@ -180,7 +180,7 @@ describe("sisyphus-orchestrator hook", () => {
expect(output.output).toContain("SUBAGENT WORK COMPLETED")
expect(output.output).toContain("test-plan")
expect(output.output).toContain("LIE")
expect(output.output).toContain("sisyphus_task(resume=")
expect(output.output).toContain("delegate_task(resume=")
cleanupMessageStorage(sessionID)
})
@@ -210,7 +210,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when
await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID },
{ tool: "delegate_task", sessionID },
output
)
@@ -247,7 +247,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when
await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID },
{ tool: "delegate_task", sessionID },
output
)
@@ -283,7 +283,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when
await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID },
{ tool: "delegate_task", sessionID },
output
)
@@ -320,7 +320,7 @@ describe("sisyphus-orchestrator hook", () => {
// #when
await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID },
{ tool: "delegate_task", sessionID },
output
)
@@ -357,12 +357,12 @@ describe("sisyphus-orchestrator hook", () => {
// #when
await hook["tool.execute.after"](
{ tool: "sisyphus_task", sessionID },
{ tool: "delegate_task", sessionID },
output
)
// #then - should include resume instructions and verification
expect(output.output).toContain("sisyphus_task(resume=")
expect(output.output).toContain("delegate_task(resume=")
expect(output.output).toContain("[x]")
expect(output.output).toContain("MANDATORY:")
@@ -398,7 +398,7 @@ describe("sisyphus-orchestrator hook", () => {
// #then
expect(output.output).toContain("DELEGATION REQUIRED")
expect(output.output).toContain("ORCHESTRATOR, not an IMPLEMENTER")
expect(output.output).toContain("sisyphus_task")
expect(output.output).toContain("delegate_task")
})
test("should append delegation reminder when orchestrator edits outside .sisyphus/", async () => {

View File

@@ -36,7 +36,7 @@ You just performed direct file modifications outside \`.sisyphus/\`.
**You are an ORCHESTRATOR, not an IMPLEMENTER.**
As an orchestrator, you should:
- **DELEGATE** implementation work to subagents via \`sisyphus_task\`
- **DELEGATE** implementation work to subagents via \`delegate_task\`
- **VERIFY** the work done by subagents
- **COORDINATE** multiple tasks and ensure completion
@@ -46,7 +46,7 @@ You should NOT:
- Implement features yourself
**If you need to make changes:**
1. Use \`sisyphus_task\` to delegate to an appropriate subagent
1. Use \`delegate_task\` to delegate to an appropriate subagent
2. Provide clear instructions in the prompt
3. Verify the subagent's work after completion
@@ -120,7 +120,7 @@ You (orchestrator-sisyphus) are attempting to directly modify a file outside \`.
🚫 **THIS IS FORBIDDEN** (except for VERIFICATION purposes)
As an ORCHESTRATOR, you MUST:
1. **DELEGATE** all implementation work via \`sisyphus_task\`
1. **DELEGATE** all implementation work via \`delegate_task\`
2. **VERIFY** the work done by subagents (reading files is OK)
3. **COORDINATE** - you orchestrate, you don't implement
@@ -138,11 +138,11 @@ As an ORCHESTRATOR, you MUST:
**IF THIS IS FOR VERIFICATION:**
Proceed if you are verifying subagent work by making a small fix.
But for any substantial changes, USE \`sisyphus_task\`.
But for any substantial changes, USE \`delegate_task\`.
**CORRECT APPROACH:**
\`\`\`
sisyphus_task(
delegate_task(
category="...",
prompt="[specific single task with clear acceptance criteria]"
)
@@ -185,7 +185,7 @@ function buildVerificationReminder(sessionId: string): string {
**If ANY verification fails, use this immediately:**
\`\`\`
sisyphus_task(resume="${sessionId}", prompt="fix: [describe the specific failure]")
delegate_task(resume="${sessionId}", prompt="fix: [describe the specific failure]")
\`\`\``
}
@@ -656,12 +656,12 @@ export function createSisyphusOrchestratorHook(
return
}
// Check sisyphus_task - inject single-task directive
if (input.tool === "sisyphus_task") {
// Check delegate_task - inject single-task directive
if (input.tool === "delegate_task") {
const prompt = output.args.prompt as string | undefined
if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) {
output.args.prompt = prompt + `\n<system-reminder>${SINGLE_TASK_DIRECTIVE}</system-reminder>`
log(`[${HOOK_NAME}] Injected single-task directive to sisyphus_task`, {
log(`[${HOOK_NAME}] Injected single-task directive to delegate_task`, {
sessionID: input.sessionID,
})
}
@@ -695,7 +695,7 @@ export function createSisyphusOrchestratorHook(
return
}
if (input.tool !== "sisyphus_task") {
if (input.tool !== "delegate_task") {
return
}

View File

@@ -1,4 +1,4 @@
const TARGET_TOOLS = ["task", "Task", "call_omo_agent", "sisyphus_task"]
const TARGET_TOOLS = ["task", "Task", "call_omo_agent", "delegate_task"]
const SESSION_ID_PATTERNS = [
/Session ID: (ses_[a-zA-Z0-9_-]+)/,
@@ -27,7 +27,7 @@ export function createTaskResumeInfoHook() {
const sessionId = extractSessionId(output.output)
if (!sessionId) return
output.output = output.output.trimEnd() + `\n\nto resume: sisyphus_task(resume="${sessionId}", prompt="...")`
output.output = output.output.trimEnd() + `\n\nto resume: delegate_task(resume="${sessionId}", prompt="...")`
}
return {

View File

@@ -26,7 +26,7 @@ import {
createRalphLoopHook,
createAutoSlashCommandHook,
createEditErrorRecoveryHook,
createSisyphusTaskRetryHook,
createDelegateTaskRetryHook,
createTaskResumeInfoHook,
createStartWorkHook,
createSisyphusOrchestratorHook,
@@ -64,7 +64,7 @@ import {
createSlashcommandTool,
discoverCommandsSync,
sessionExists,
createSisyphusTask,
createDelegateTask,
interactive_bash,
startTmuxCheck,
lspManager,
@@ -193,8 +193,8 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
? createEditErrorRecoveryHook(ctx)
: null;
const sisyphusTaskRetry = isHookEnabled("sisyphus-task-retry")
? createSisyphusTaskRetryHook(ctx)
const delegateTaskRetry = isHookEnabled("delegate-task-retry")
? createDelegateTaskRetryHook(ctx)
: null;
const startWork = isHookEnabled("start-work")
@@ -233,7 +233,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
const callOmoAgent = createCallOmoAgent(ctx, backgroundManager);
const lookAt = createLookAt(ctx);
const sisyphusTask = createSisyphusTask({
const delegateTask = createDelegateTask({
manager: backgroundManager,
client: ctx.client,
directory: ctx.directory,
@@ -302,7 +302,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
...backgroundTools,
call_omo_agent: callOmoAgent,
look_at: lookAt,
sisyphus_task: sisyphusTask,
delegate_task: delegateTask,
skill: skillTool,
skill_mcp: skillMcpTool,
slashcommand: slashcommandTool,
@@ -502,7 +502,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
args.tools = {
...(args.tools as Record<string, boolean> | undefined),
sisyphus_task: false,
delegate_task: false,
...(isExploreOrLibrarian ? { call_omo_agent: false } : {}),
};
}
@@ -550,7 +550,7 @@ const OhMyOpenCodePlugin: Plugin = async (ctx) => {
await agentUsageReminder?.["tool.execute.after"](input, output);
await interactiveBashSession?.["tool.execute.after"](input, output);
await editErrorRecovery?.["tool.execute.after"](input, output);
await sisyphusTaskRetry?.["tool.execute.after"](input, output);
await delegateTaskRetry?.["tool.execute.after"](input, output);
await sisyphusOrchestrator?.["tool.execute.after"]?.(input, output);
await taskResumeInfo["tool.execute.after"](input, output);
},

View File

@@ -24,7 +24,7 @@ import type { OhMyOpenCodeConfig } from "../config";
import { log } from "../shared";
import { migrateAgentConfig } from "../shared/permission-compat";
import { PROMETHEUS_SYSTEM_PROMPT, PROMETHEUS_PERMISSION } from "../agents/prometheus-prompt";
import { DEFAULT_CATEGORIES } from "../tools/sisyphus-task/constants";
import { DEFAULT_CATEGORIES } from "../tools/delegate-task/constants";
import type { ModelCacheState } from "../plugin-state";
import type { CategoryConfig } from "../config/schema";
@@ -303,26 +303,26 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
}
if (agentResult["orchestrator-sisyphus"]) {
const agent = agentResult["orchestrator-sisyphus"] as AgentWithPermission;
agent.permission = { ...agent.permission, task: "deny", call_omo_agent: "deny", sisyphus_task: "allow" };
agent.permission = { ...agent.permission, task: "deny", call_omo_agent: "deny", delegate_task: "allow" };
}
if (agentResult.Sisyphus) {
const agent = agentResult.Sisyphus as AgentWithPermission;
agent.permission = { ...agent.permission, call_omo_agent: "deny", sisyphus_task: "allow" };
agent.permission = { ...agent.permission, call_omo_agent: "deny", delegate_task: "allow" };
}
if (agentResult["Prometheus (Planner)"]) {
const agent = agentResult["Prometheus (Planner)"] as AgentWithPermission;
agent.permission = { ...agent.permission, call_omo_agent: "deny", sisyphus_task: "allow" };
agent.permission = { ...agent.permission, call_omo_agent: "deny", delegate_task: "allow" };
}
if (agentResult["Sisyphus-Junior"]) {
const agent = agentResult["Sisyphus-Junior"] as AgentWithPermission;
agent.permission = { ...agent.permission, sisyphus_task: "allow" };
agent.permission = { ...agent.permission, delegate_task: "allow" };
}
config.permission = {
...(config.permission as Record<string, unknown>),
webfetch: "allow",
external_directory: "allow",
sisyphus_task: "deny",
delegate_task: "deny",
};
const mcpResult = (pluginConfig.claude_code?.mcp ?? true)

View File

@@ -10,7 +10,7 @@ const EXPLORATION_AGENT_DENYLIST: Record<string, PermissionValue> = {
write: "deny",
edit: "deny",
task: "deny",
sisyphus_task: "deny",
delegate_task: "deny",
call_omo_agent: "deny",
}
@@ -23,7 +23,7 @@ const AGENT_RESTRICTIONS: Record<string, Record<string, PermissionValue>> = {
write: "deny",
edit: "deny",
task: "deny",
sisyphus_task: "deny",
delegate_task: "deny",
},
"multimodal-looker": {
@@ -33,19 +33,19 @@ const AGENT_RESTRICTIONS: Record<string, Record<string, PermissionValue>> = {
"document-writer": {
task: "deny",
sisyphus_task: "deny",
delegate_task: "deny",
call_omo_agent: "deny",
},
"frontend-ui-ux-engineer": {
task: "deny",
sisyphus_task: "deny",
delegate_task: "deny",
call_omo_agent: "deny",
},
"Sisyphus-Junior": {
task: "deny",
sisyphus_task: "deny",
delegate_task: "deny",
},
}

View File

@@ -34,7 +34,7 @@ tools/
| AST | ast_grep_search, ast_grep_replace | Structural pattern matching/rewriting |
| Search | grep, glob | Timeout-safe file and content search |
| Session | session_list, session_read, session_search, session_info | History navigation and retrieval |
| Background | sisyphus_task, background_output, background_cancel | Parallel agent orchestration |
| Background | delegate_task, background_output, background_cancel | Parallel agent orchestration |
| UI/Terminal | look_at, interactive_bash | Visual analysis and tmux control |
| Execution | slashcommand, skill, skill_mcp | Command and skill-based extensibility |

View File

@@ -190,7 +190,7 @@ async function executeSync(
tools: {
...getAgentToolRestrictions(args.subagent_type),
task: false,
sisyphus_task: false,
delegate_task: false,
},
parts: [{ type: "text", text: args.prompt }],
},

View File

@@ -236,7 +236,7 @@ export const CATEGORY_DESCRIPTIONS: Record<string, string> = {
const BUILTIN_CATEGORIES = Object.keys(DEFAULT_CATEGORIES).join(", ")
export const SISYPHUS_TASK_DESCRIPTION = `Spawn agent task with category-based or direct agent selection.
export const DELEGATE_TASK_DESCRIPTION = `Spawn agent task with category-based or direct agent selection.
MUTUALLY EXCLUSIVE: Provide EITHER category OR agent, not both (unless resuming).

View File

@@ -1,3 +1,3 @@
export { createSisyphusTask, type SisyphusTaskToolOptions } from "./tools"
export { createDelegateTask, type DelegateTaskToolOptions } from "./tools"
export type * from "./types"
export * from "./constants"

View File

@@ -1,5 +1,5 @@
import { describe, test, expect } from "bun:test"
import { DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS, CATEGORY_DESCRIPTIONS, SISYPHUS_TASK_DESCRIPTION } from "./constants"
import { DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS, CATEGORY_DESCRIPTIONS, DELEGATE_TASK_DESCRIPTION } from "./constants"
import type { CategoryConfig } from "../../config/schema"
function resolveCategoryConfig(
@@ -101,16 +101,16 @@ describe("sisyphus-task", () => {
})
})
describe("SISYPHUS_TASK_DESCRIPTION", () => {
describe("DELEGATE_TASK_DESCRIPTION", () => {
test("documents background parameter as required with default false", () => {
// #given / #when / #then
expect(SISYPHUS_TASK_DESCRIPTION).toContain("background")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Default: false")
expect(DELEGATE_TASK_DESCRIPTION).toContain("background")
expect(DELEGATE_TASK_DESCRIPTION).toContain("Default: false")
})
test("warns about parallel exploration usage", () => {
// #given / #when / #then
expect(SISYPHUS_TASK_DESCRIPTION).toContain("5+")
expect(DELEGATE_TASK_DESCRIPTION).toContain("5+")
})
})
@@ -257,7 +257,7 @@ describe("sisyphus-task", () => {
describe("category variant", () => {
test("passes variant to background model payload", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
let launchInput: any
const mockManager = {
@@ -283,7 +283,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
userCategories: {
@@ -320,17 +320,17 @@ describe("sisyphus-task", () => {
})
describe("skills parameter", () => {
test("SISYPHUS_TASK_DESCRIPTION documents skills parameter with null option", () => {
test("DELEGATE_TASK_DESCRIPTION documents skills parameter with null option", () => {
// #given / #when / #then
expect(SISYPHUS_TASK_DESCRIPTION).toContain("skills")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Array of skill names")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("Empty array [] is NOT allowed")
expect(SISYPHUS_TASK_DESCRIPTION).toContain("null if no skills needed")
expect(DELEGATE_TASK_DESCRIPTION).toContain("skills")
expect(DELEGATE_TASK_DESCRIPTION).toContain("Array of skill names")
expect(DELEGATE_TASK_DESCRIPTION).toContain("Empty array [] is NOT allowed")
expect(DELEGATE_TASK_DESCRIPTION).toContain("null if no skills needed")
})
test("skills parameter is required - returns error when not provided", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = { launch: async () => ({}) }
const mockClient = {
@@ -343,7 +343,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -373,7 +373,7 @@ describe("sisyphus-task", () => {
test("empty array [] returns error with available skills list", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = { launch: async () => ({}) }
const mockClient = {
@@ -386,7 +386,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -419,7 +419,7 @@ describe("sisyphus-task", () => {
test("null skills is allowed and proceeds without skill content", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
let promptBody: any
const mockManager = { launch: async () => ({}) }
@@ -440,7 +440,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -474,7 +474,7 @@ describe("sisyphus-task", () => {
test("resume with background=false should wait for result and return content", async () => {
// Note: This test needs extended timeout because the implementation has MIN_STABILITY_TIME_MS = 5000
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockTask = {
id: "task-123",
@@ -507,7 +507,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -538,7 +538,7 @@ describe("sisyphus-task", () => {
test("resume with background=true should return immediately without waiting", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockTask = {
id: "task-456",
@@ -562,7 +562,7 @@ describe("sisyphus-task", () => {
config: { get: async () => ({}) },
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -595,7 +595,7 @@ describe("sisyphus-task", () => {
describe("sync mode new task (run_in_background=false)", () => {
test("sync mode prompt error returns error message immediately", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = {
launch: async () => ({}),
@@ -617,7 +617,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -651,7 +651,7 @@ describe("sisyphus-task", () => {
test("sync mode success returns task result with content", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = {
launch: async () => ({}),
@@ -678,7 +678,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -709,7 +709,7 @@ describe("sisyphus-task", () => {
test("sync mode agent not found returns helpful error", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
const mockManager = {
launch: async () => ({}),
@@ -731,7 +731,7 @@ describe("sisyphus-task", () => {
},
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
})
@@ -763,7 +763,7 @@ describe("sisyphus-task", () => {
test("sync mode passes category model to prompt", async () => {
// #given
const { createSisyphusTask } = require("./tools")
const { createDelegateTask } = require("./tools")
let promptBody: any
const mockManager = { launch: async () => ({}) }
@@ -784,7 +784,7 @@ describe("sisyphus-task", () => {
app: { agents: async () => ({ data: [] }) },
}
const tool = createSisyphusTask({
const tool = createDelegateTask({
manager: mockManager,
client: mockClient,
userCategories: {

View File

@@ -2,9 +2,9 @@ import { tool, type PluginInput, type ToolDefinition } from "@opencode-ai/plugin
import { existsSync, readdirSync } from "node:fs"
import { join } from "node:path"
import type { BackgroundManager } from "../../features/background-agent"
import type { SisyphusTaskArgs } from "./types"
import type { DelegateTaskArgs } from "./types"
import type { CategoryConfig, CategoriesConfig, GitMasterConfig } from "../../config/schema"
import { SISYPHUS_TASK_DESCRIPTION, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS } from "./constants"
import { DELEGATE_TASK_DESCRIPTION, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS } from "./constants"
import { findNearestMessageWithFields, findFirstMessageWithAgent, MESSAGE_STORAGE } from "../../features/hook-message-injector"
import { resolveMultipleSkillsAsync } from "../../features/opencode-skill-loader/skill-content"
import { discoverSkills } from "../../features/opencode-skill-loader"
@@ -53,7 +53,7 @@ function formatDuration(start: Date, end?: Date): string {
interface ErrorContext {
operation: string
args?: SisyphusTaskArgs
args?: DelegateTaskArgs
sessionID?: string
agent?: string
category?: string
@@ -143,7 +143,7 @@ function resolveCategoryConfig(
return { config, promptAppend, model }
}
export interface SisyphusTaskToolOptions {
export interface DelegateTaskToolOptions {
manager: BackgroundManager
client: OpencodeClient
directory: string
@@ -170,11 +170,11 @@ export function buildSystemContent(input: BuildSystemContentInput): string | und
return skillContent || categoryPromptAppend
}
export function createSisyphusTask(options: SisyphusTaskToolOptions): ToolDefinition {
export function createDelegateTask(options: DelegateTaskToolOptions): ToolDefinition {
const { manager, client, directory, userCategories, gitMasterConfig } = options
return tool({
description: SISYPHUS_TASK_DESCRIPTION,
description: DELEGATE_TASK_DESCRIPTION,
args: {
description: tool.schema.string().describe("Short task description"),
prompt: tool.schema.string().describe("Full detailed prompt for the agent"),
@@ -184,7 +184,7 @@ export function createSisyphusTask(options: SisyphusTaskToolOptions): ToolDefini
resume: tool.schema.string().optional().describe("Session ID to resume - continues previous agent session with full context"),
skills: tool.schema.array(tool.schema.string()).nullable().describe("Array of skill names to prepend to the prompt. Use null if no skills needed. Empty array [] is NOT allowed."),
},
async execute(args: SisyphusTaskArgs, toolContext) {
async execute(args: DelegateTaskArgs, toolContext) {
const ctx = toolContext as ToolContextWithMetadata
if (args.run_in_background === undefined) {
return `❌ Invalid arguments: 'run_in_background' parameter is REQUIRED. Use run_in_background=false for task delegation, run_in_background=true only for parallel exploration.`
@@ -223,7 +223,7 @@ If you believe no skills are needed, you MUST explicitly explain why to the user
const sessionAgent = getSessionAgent(ctx.sessionID)
const parentAgent = ctx.agent ?? sessionAgent ?? firstMessageAgent ?? prevMessage?.agent
log("[sisyphus_task] parentAgent resolution", {
log("[delegate_task] parentAgent resolution", {
sessionID: ctx.sessionID,
messageDir,
ctxAgent: ctx.agent,
@@ -324,7 +324,7 @@ Use \`background_output\` with task_id="${task.id}" to check progress.`
tools: {
...(resumeAgent ? getAgentToolRestrictions(resumeAgent) : {}),
task: false,
sisyphus_task: false,
delegate_task: false,
call_omo_agent: true,
},
parts: [{ type: "text", text: args.prompt }],
@@ -502,7 +502,7 @@ ${textContent || "(No text output)"}`
if (!callableNames.includes(agentToUse)) {
const isPrimaryAgent = agents.some((a) => a.name === agentToUse && a.mode === "primary")
if (isPrimaryAgent) {
return `❌ Cannot call primary agent "${agentToUse}" via sisyphus_task. Primary agents are top-level orchestrators.`
return `❌ Cannot call primary agent "${agentToUse}" via delegate_task. Primary agents are top-level orchestrators.`
}
const availableAgents = callableNames
@@ -610,7 +610,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
system: systemContent,
tools: {
task: false,
sisyphus_task: false,
delegate_task: false,
call_omo_agent: true,
},
parts: [{ type: "text", text: args.prompt }],
@@ -651,11 +651,11 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
let stablePolls = 0
let pollCount = 0
log("[sisyphus_task] Starting poll loop", { sessionID, agentToUse })
log("[delegate_task] Starting poll loop", { sessionID, agentToUse })
while (Date.now() - pollStart < MAX_POLL_TIME_MS) {
if (ctx.abort?.aborted) {
log("[sisyphus_task] Aborted by user", { sessionID })
log("[delegate_task] Aborted by user", { sessionID })
if (toastManager && taskId) toastManager.removeTask(taskId)
return `Task aborted.\n\nSession ID: ${sessionID}`
}
@@ -668,7 +668,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
const sessionStatus = allStatuses[sessionID]
if (pollCount % 10 === 0) {
log("[sisyphus_task] Poll status", {
log("[delegate_task] Poll status", {
sessionID,
pollCount,
elapsed: Math.floor((Date.now() - pollStart) / 1000) + "s",
@@ -696,7 +696,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
if (currentMsgCount === lastMsgCount) {
stablePolls++
if (stablePolls >= STABILITY_POLLS_REQUIRED) {
log("[sisyphus_task] Poll complete - messages stable", { sessionID, pollCount, currentMsgCount })
log("[delegate_task] Poll complete - messages stable", { sessionID, pollCount, currentMsgCount })
break
}
} else {
@@ -706,7 +706,7 @@ System notifies on completion. Use \`background_output\` with task_id="${task.id
}
if (Date.now() - pollStart >= MAX_POLL_TIME_MS) {
log("[sisyphus_task] Poll timeout reached", { sessionID, pollCount, lastMsgCount, stablePolls })
log("[delegate_task] Poll timeout reached", { sessionID, pollCount, lastMsgCount, stablePolls })
}
const messagesResult = await client.session.messages({

View File

@@ -1,4 +1,4 @@
export interface SisyphusTaskArgs {
export interface DelegateTaskArgs {
description: string
prompt: string
category?: string

View File

@@ -45,7 +45,7 @@ type OpencodeClient = PluginInput["client"]
export { createCallOmoAgent } from "./call-omo-agent"
export { createLookAt } from "./look-at"
export { createSisyphusTask, type SisyphusTaskToolOptions, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS } from "./sisyphus-task"
export { createDelegateTask, type DelegateTaskToolOptions, DEFAULT_CATEGORIES, CATEGORY_PROMPT_APPENDS } from "./delegate-task"
export function createBackgroundTools(manager: BackgroundManager, client: OpencodeClient): Record<string, ToolDefinition> {
return {