add skills

This commit is contained in:
YeonGyu-Kim
2026-03-14 12:45:53 +09:00
parent 0dcfcd372b
commit c7518eae2d
81 changed files with 19037 additions and 0 deletions
@@ -0,0 +1,32 @@
{
"eval_id": 3,
"eval_name": "refactor-split-constants",
"prompt": "Refactor src/tools/delegate-task/constants.ts to split DEFAULT_CATEGORIES and CATEGORY_MODEL_REQUIREMENTS into separate files. Keep backward compatibility with the barrel export. Make a PR.",
"assertions": [
{
"id": "worktree-isolation",
"text": "Plan uses git worktree in a sibling directory",
"type": "manual"
},
{
"id": "multiple-atomic-commits",
"text": "Uses 2+ commits for the multi-file refactor",
"type": "manual"
},
{
"id": "barrel-export",
"text": "Maintains backward compatibility via barrel re-export in constants.ts or index.ts",
"type": "manual"
},
{
"id": "three-gates",
"text": "Verification loop includes all 3 gates",
"type": "manual"
},
{
"id": "real-constants-file",
"text": "References actual src/tools/delegate-task/constants.ts file and its exports",
"type": "manual"
}
]
}
@@ -0,0 +1,10 @@
{
"run_id": "eval-3-with_skill",
"expectations": [
{"text": "Plan uses git worktree in a sibling directory", "passed": true, "evidence": "../omo-wt/refactor-delegate-task-constants"},
{"text": "Uses 2+ commits for the multi-file refactor", "passed": true, "evidence": "Commit 1: category defaults+appends, Commit 2: plan agent prompt+names"},
{"text": "Maintains backward compatibility via barrel re-export", "passed": true, "evidence": "constants.ts converted to re-export from 4 new files, full import map verified"},
{"text": "Verification loop includes all 3 gates", "passed": true, "evidence": "Gate A (CI), Gate B (review-work), Gate C (Cubic)"},
{"text": "References actual src/tools/delegate-task/constants.ts", "passed": true, "evidence": "654 lines analyzed, 4 responsibilities identified, full external+internal import map"}
]
}
@@ -0,0 +1,221 @@
# Code Changes
## New File: `src/tools/delegate-task/default-categories.ts`
```typescript
import type { CategoryConfig } from "../../config/schema"
export const DEFAULT_CATEGORIES: Record<string, CategoryConfig> = {
"visual-engineering": { model: "google/gemini-3.1-pro", variant: "high" },
ultrabrain: { model: "openai/gpt-5.4", variant: "xhigh" },
deep: { model: "openai/gpt-5.3-codex", variant: "medium" },
artistry: { model: "google/gemini-3.1-pro", variant: "high" },
quick: { model: "anthropic/claude-haiku-4-5" },
"unspecified-low": { model: "anthropic/claude-sonnet-4-6" },
"unspecified-high": { model: "anthropic/claude-opus-4-6", variant: "max" },
writing: { model: "kimi-for-coding/k2p5" },
}
export const CATEGORY_DESCRIPTIONS: Record<string, string> = {
"visual-engineering": "Frontend, UI/UX, design, styling, animation",
ultrabrain: "Use ONLY for genuinely hard, logic-heavy tasks. Give clear goals only, not step-by-step instructions.",
deep: "Goal-oriented autonomous problem-solving. Thorough research before action. For hairy problems requiring deep understanding.",
artistry: "Complex problem-solving with unconventional, creative approaches - beyond standard patterns",
quick: "Trivial tasks - single file changes, typo fixes, simple modifications",
"unspecified-low": "Tasks that don't fit other categories, low effort required",
"unspecified-high": "Tasks that don't fit other categories, high effort required",
writing: "Documentation, prose, technical writing",
}
```
## New File: `src/tools/delegate-task/category-prompt-appends.ts`
```typescript
export const VISUAL_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on VISUAL/UI tasks.
...
</Category_Context>`
// (exact content from lines 8-95 of constants.ts)
export const ULTRABRAIN_CATEGORY_PROMPT_APPEND = `<Category_Context>
...
</Category_Context>`
// (exact content from lines 97-117)
export const ARTISTRY_CATEGORY_PROMPT_APPEND = `<Category_Context>
...
</Category_Context>`
// (exact content from lines 119-134)
export const QUICK_CATEGORY_PROMPT_APPEND = `<Category_Context>
...
</Caller_Warning>`
// (exact content from lines 136-186)
export const UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND = `<Category_Context>
...
</Caller_Warning>`
// (exact content from lines 188-209)
export const UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND = `<Category_Context>
...
</Category_Context>`
// (exact content from lines 211-224)
export const WRITING_CATEGORY_PROMPT_APPEND = `<Category_Context>
...
</Category_Context>`
// (exact content from lines 226-250)
export const DEEP_CATEGORY_PROMPT_APPEND = `<Category_Context>
...
</Category_Context>`
// (exact content from lines 252-281)
export const CATEGORY_PROMPT_APPENDS: Record<string, string> = {
"visual-engineering": VISUAL_CATEGORY_PROMPT_APPEND,
ultrabrain: ULTRABRAIN_CATEGORY_PROMPT_APPEND,
deep: DEEP_CATEGORY_PROMPT_APPEND,
artistry: ARTISTRY_CATEGORY_PROMPT_APPEND,
quick: QUICK_CATEGORY_PROMPT_APPEND,
"unspecified-low": UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND,
"unspecified-high": UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND,
writing: WRITING_CATEGORY_PROMPT_APPEND,
}
```
## New File: `src/tools/delegate-task/plan-agent-prompt.ts`
```typescript
import type {
AvailableCategory,
AvailableSkill,
} from "../../agents/dynamic-agent-prompt-builder"
import { truncateDescription } from "../../shared/truncate-description"
/**
* System prompt prepended to plan agent invocations.
* Instructs the plan agent to first gather context via explore/librarian agents,
* then summarize user requirements and clarify uncertainties before proceeding.
* Also MANDATES dependency graphs, parallel execution analysis, and category+skill recommendations.
*/
export const PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS = `<system>
...
</CRITICAL_REQUIREMENT_DEPENDENCY_PARALLEL_EXECUTION_CATEGORY_SKILLS>
`
// (exact content from lines 324-430)
export const PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS = `### REQUIRED OUTPUT FORMAT
...
`
// (exact content from lines 432-569)
function renderPlanAgentCategoryRows(categories: AvailableCategory[]): string[] {
const sorted = [...categories].sort((a, b) => a.name.localeCompare(b.name))
return sorted.map((category) => {
const bestFor = category.description || category.name
const model = category.model || ""
return `| \`${category.name}\` | ${bestFor} | ${model} |`
})
}
function renderPlanAgentSkillRows(skills: AvailableSkill[]): string[] {
const sorted = [...skills].sort((a, b) => a.name.localeCompare(b.name))
return sorted.map((skill) => {
const domain = truncateDescription(skill.description).trim() || skill.name
return `| \`${skill.name}\` | ${domain} |`
})
}
export function buildPlanAgentSkillsSection(
categories: AvailableCategory[] = [],
skills: AvailableSkill[] = []
): string {
const categoryRows = renderPlanAgentCategoryRows(categories)
const skillRows = renderPlanAgentSkillRows(skills)
return `### AVAILABLE CATEGORIES
| Category | Best For | Model |
|----------|----------|-------|
${categoryRows.join("\n")}
### AVAILABLE SKILLS (ALWAYS EVALUATE ALL)
Skills inject specialized expertise into the delegated agent.
YOU MUST evaluate EVERY skill and justify inclusions/omissions.
| Skill | Domain |
|-------|--------|
${skillRows.join("\n")}`
}
export function buildPlanAgentSystemPrepend(
categories: AvailableCategory[] = [],
skills: AvailableSkill[] = []
): string {
return [
PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS,
buildPlanAgentSkillsSection(categories, skills),
PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS,
].join("\n\n")
}
```
## New File: `src/tools/delegate-task/plan-agent-names.ts`
```typescript
/**
* List of agent names that should be treated as plan agents (receive plan system prompt).
* Case-insensitive matching is used.
*/
export const PLAN_AGENT_NAMES = ["plan"]
/**
* Check if the given agent name is a plan agent (receives plan system prompt).
*/
export function isPlanAgent(agentName: string | undefined): boolean {
if (!agentName) return false
const lowerName = agentName.toLowerCase().trim()
return PLAN_AGENT_NAMES.some(name => lowerName === name || lowerName.includes(name))
}
/**
* Plan family: plan + prometheus. Shares mutual delegation blocking and task tool permission.
* Does NOT share system prompt (only isPlanAgent controls that).
*/
export const PLAN_FAMILY_NAMES = ["plan", "prometheus"]
/**
* Check if the given agent belongs to the plan family (blocking + task permission).
*/
export function isPlanFamily(category: string): boolean
export function isPlanFamily(category: string | undefined): boolean
export function isPlanFamily(category: string | undefined): boolean {
if (!category) return false
const lowerCategory = category.toLowerCase().trim()
return PLAN_FAMILY_NAMES.some(
(name) => lowerCategory === name || lowerCategory.includes(name)
)
}
```
## Modified File: `src/tools/delegate-task/constants.ts`
```typescript
export * from "./default-categories"
export * from "./category-prompt-appends"
export * from "./plan-agent-prompt"
export * from "./plan-agent-names"
```
## Unchanged: `src/tools/delegate-task/index.ts`
```typescript
export { createDelegateTask, resolveCategoryConfig, buildSystemContent, buildTaskPrompt } from "./tools"
export type { DelegateTaskToolOptions, SyncSessionCreatedEvent, BuildSystemContentInput } from "./tools"
export type * from "./types"
export * from "./constants"
```
No changes needed. `export * from "./constants"` transitively re-exports everything from the 4 new files.
@@ -0,0 +1,104 @@
# Execution Plan: Split delegate-task/constants.ts
## Phase 0: Setup
```bash
git fetch origin dev
git worktree add ../omo-wt/refactor-delegate-task-constants origin/dev -b refactor/split-delegate-task-constants
cd ../omo-wt/refactor-delegate-task-constants
```
## Phase 1: Implement
### Analysis
`src/tools/delegate-task/constants.ts` is 654 lines with 4 distinct responsibilities:
1. **Category defaults** (lines 285-316): `DEFAULT_CATEGORIES`, `CATEGORY_DESCRIPTIONS`
2. **Category prompt appends** (lines 8-305): 8 `*_CATEGORY_PROMPT_APPEND` string constants + `CATEGORY_PROMPT_APPENDS` record
3. **Plan agent prompts** (lines 318-620): `PLAN_AGENT_SYSTEM_PREPEND_*`, builder functions
4. **Plan agent names** (lines 626-654): `PLAN_AGENT_NAMES`, `isPlanAgent`, `PLAN_FAMILY_NAMES`, `isPlanFamily`
Note: `CATEGORY_MODEL_REQUIREMENTS` is already in `src/shared/model-requirements.ts`. No move needed.
### New Files
| File | Responsibility | ~LOC |
|------|---------------|------|
| `default-categories.ts` | `DEFAULT_CATEGORIES`, `CATEGORY_DESCRIPTIONS` | ~40 |
| `category-prompt-appends.ts` | 8 prompt append constants + `CATEGORY_PROMPT_APPENDS` record | ~300 (exempt: prompt text) |
| `plan-agent-prompt.ts` | Plan agent system prompt constants + builder functions | ~250 (exempt: prompt text) |
| `plan-agent-names.ts` | `PLAN_AGENT_NAMES`, `isPlanAgent`, `PLAN_FAMILY_NAMES`, `isPlanFamily` | ~30 |
| `constants.ts` (updated) | Re-exports from all 4 files (backward compat) | ~5 |
### Commit 1: Extract category defaults and prompt appends
**Files changed**: 3 new + 1 modified
- Create `src/tools/delegate-task/default-categories.ts`
- Create `src/tools/delegate-task/category-prompt-appends.ts`
- Modify `src/tools/delegate-task/constants.ts` (remove extracted code, add re-exports)
### Commit 2: Extract plan agent prompt and names
**Files changed**: 2 new + 1 modified
- Create `src/tools/delegate-task/plan-agent-prompt.ts`
- Create `src/tools/delegate-task/plan-agent-names.ts`
- Modify `src/tools/delegate-task/constants.ts` (final: re-exports only)
### Local Validation
```bash
bun run typecheck
bun test src/tools/delegate-task/
bun run build
```
## Phase 2: PR Creation
```bash
git push -u origin refactor/split-delegate-task-constants
gh pr create --base dev --title "refactor(delegate-task): split constants.ts into focused modules" --body-file /tmp/pr-body.md
```
## Phase 3: Verify Loop
- **Gate A**: `gh pr checks --watch`
- **Gate B**: `/review-work` (5-agent review)
- **Gate C**: Wait for cubic-dev-ai[bot] "No issues found"
## Phase 4: Merge
```bash
gh pr merge --squash --delete-branch
git worktree remove ../omo-wt/refactor-delegate-task-constants
```
## Import Update Strategy
No import updates needed. Backward compatibility preserved through:
1. `constants.ts` re-exports everything from the 4 new files
2. `index.ts` already does `export * from "./constants"` (unchanged)
3. All external consumers import from `"../tools/delegate-task/constants"` or `"./constants"` -- both still work
### External Import Map (Verified -- NO CHANGES NEEDED)
| Consumer | Imports | Source Path |
|----------|---------|-------------|
| `src/agents/atlas/prompt-section-builder.ts` | `CATEGORY_DESCRIPTIONS` | `../../tools/delegate-task/constants` |
| `src/agents/builtin-agents.ts` | `CATEGORY_DESCRIPTIONS` | `../tools/delegate-task/constants` |
| `src/plugin/available-categories.ts` | `CATEGORY_DESCRIPTIONS` | `../tools/delegate-task/constants` |
| `src/plugin-handlers/category-config-resolver.ts` | `DEFAULT_CATEGORIES` | `../tools/delegate-task/constants` |
| `src/shared/merge-categories.ts` | `DEFAULT_CATEGORIES` | `../tools/delegate-task/constants` |
| `src/shared/merge-categories.test.ts` | `DEFAULT_CATEGORIES` | `../tools/delegate-task/constants` |
### Internal Import Map (Within delegate-task/ -- NO CHANGES NEEDED)
| Consumer | Imports |
|----------|---------|
| `categories.ts` | `DEFAULT_CATEGORIES`, `CATEGORY_PROMPT_APPENDS` |
| `tools.ts` | `CATEGORY_DESCRIPTIONS` |
| `prompt-builder.ts` | `buildPlanAgentSystemPrepend`, `isPlanAgent` |
| `subagent-resolver.ts` | `isPlanFamily` |
| `sync-continuation.ts` | `isPlanFamily` |
| `sync-prompt-sender.ts` | `isPlanFamily` |
| `tools.test.ts` | `DEFAULT_CATEGORIES`, `CATEGORY_PROMPT_APPENDS`, `CATEGORY_DESCRIPTIONS`, `isPlanAgent`, `PLAN_AGENT_NAMES`, `isPlanFamily`, `PLAN_FAMILY_NAMES` |
@@ -0,0 +1,41 @@
# PR Title
```
refactor(delegate-task): split constants.ts into focused modules
```
# PR Body
## Summary
- Split the 654-line `src/tools/delegate-task/constants.ts` into 4 single-responsibility modules: `default-categories.ts`, `category-prompt-appends.ts`, `plan-agent-prompt.ts`, `plan-agent-names.ts`
- `constants.ts` becomes a pure re-export barrel, preserving all existing import paths (`from "./constants"` and `from "./delegate-task"`)
- Zero import changes across the codebase (6 external + 7 internal consumers verified)
## Motivation
`constants.ts` at 654 lines violates the project's 200 LOC soft limit (`modular-code-enforcement.md` rule) and bundles 4 unrelated responsibilities: category model configs, category prompt text, plan agent prompts, and plan agent name utilities.
## Changes
| New File | Responsibility | LOC |
|----------|---------------|-----|
| `default-categories.ts` | `DEFAULT_CATEGORIES`, `CATEGORY_DESCRIPTIONS` | ~25 |
| `category-prompt-appends.ts` | 8 `*_PROMPT_APPEND` constants + `CATEGORY_PROMPT_APPENDS` record | ~300 (prompt-exempt) |
| `plan-agent-prompt.ts` | Plan system prompt constants + `buildPlanAgentSystemPrepend()` | ~250 (prompt-exempt) |
| `plan-agent-names.ts` | `PLAN_AGENT_NAMES`, `isPlanAgent`, `PLAN_FAMILY_NAMES`, `isPlanFamily` | ~30 |
| `constants.ts` (updated) | 4-line re-export barrel | 4 |
## Backward Compatibility
All 13 consumers continue importing from `"./constants"` or `"../tools/delegate-task/constants"` with zero changes. The re-export chain: new modules -> `constants.ts` -> `index.ts` -> external consumers.
## Note on CATEGORY_MODEL_REQUIREMENTS
`CATEGORY_MODEL_REQUIREMENTS` already lives in `src/shared/model-requirements.ts`. No move needed. The AGENTS.md reference to it being in `constants.ts` is outdated.
## Testing
- `bun run typecheck` passes
- `bun test src/tools/delegate-task/` passes (all existing tests untouched)
- `bun run build` succeeds
@@ -0,0 +1,84 @@
# Verification Strategy
## Gate A: CI (Blocking)
```bash
gh pr checks --watch
```
**Expected CI jobs** (from `ci.yml`):
1. **Tests (split)**: mock-heavy isolated + batch `bun test`
2. **Typecheck**: `bun run typecheck` (tsc --noEmit)
3. **Build**: `bun run build`
4. **Schema auto-commit**: If schema changes detected
**Likely failure points**: None. This is a pure refactor with re-exports. No runtime behavior changes.
**If CI fails**:
- Typecheck error: Missing re-export or import cycle. Fix in the new modules, amend commit.
- Test error: `tools.test.ts` imports all symbols from `"./constants"`. Re-export barrel must be complete.
## Gate B: review-work (5-Agent Review)
Invoke after CI passes:
```
/review-work
```
**5 parallel agents**:
1. **Oracle (goal/constraint)**: Verify backward compat claim. Check all 13 import paths resolve.
2. **Oracle (code quality)**: Verify single-responsibility per file, LOC limits, no catch-all violations.
3. **Oracle (security)**: No security implications in this refactor.
4. **QA (hands-on execution)**: Run `bun test src/tools/delegate-task/` and verify all pass.
5. **Context miner**: Check no related open issues/PRs conflict.
**Expected verdict**: Pass. Pure structural refactor with no behavioral changes.
## Gate C: Cubic (External Bot)
Wait for `cubic-dev-ai[bot]` to post "No issues found" on the PR.
**If Cubic flags issues**: Likely false positives on "large number of new files". Address in PR comments if needed.
## Pre-Gate Local Validation (Before Push)
```bash
# In worktree
bun run typecheck
bun test src/tools/delegate-task/
bun run build
# Verify re-exports are complete
bun -e "import * as c from './src/tools/delegate-task/constants'; console.log(Object.keys(c).sort().join('\n'))"
```
Expected exports from constants.ts (13 total):
- `ARTISTRY_CATEGORY_PROMPT_APPEND`
- `CATEGORY_DESCRIPTIONS`
- `CATEGORY_PROMPT_APPENDS`
- `DEFAULT_CATEGORIES`
- `DEEP_CATEGORY_PROMPT_APPEND`
- `PLAN_AGENT_NAMES`
- `PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS`
- `PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS`
- `PLAN_FAMILY_NAMES`
- `QUICK_CATEGORY_PROMPT_APPEND`
- `ULTRABRAIN_CATEGORY_PROMPT_APPEND`
- `UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND`
- `UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND`
- `VISUAL_CATEGORY_PROMPT_APPEND`
- `WRITING_CATEGORY_PROMPT_APPEND`
- `buildPlanAgentSkillsSection`
- `buildPlanAgentSystemPrepend`
- `isPlanAgent`
- `isPlanFamily`
## Merge Strategy
```bash
gh pr merge --squash --delete-branch
git worktree remove ../omo-wt/refactor-delegate-task-constants
```
Squash merge collapses the 2 atomic commits into 1 clean commit on dev.
@@ -0,0 +1 @@
{"total_tokens": null, "duration_ms": 181000, "total_duration_seconds": 181}
@@ -0,0 +1,10 @@
{
"run_id": "eval-3-without_skill",
"expectations": [
{"text": "Plan uses git worktree in a sibling directory", "passed": false, "evidence": "git checkout -b only, no worktree"},
{"text": "Uses 2+ commits for the multi-file refactor", "passed": false, "evidence": "Single atomic commit: 'refactor: split delegate-task constants and category model requirements'"},
{"text": "Maintains backward compatibility via barrel re-export", "passed": true, "evidence": "Re-exports from new files, zero consumer changes"},
{"text": "Verification loop includes all 3 gates", "passed": false, "evidence": "Only mentions typecheck/test/build. No review-work or Cubic."},
{"text": "References actual src/tools/delegate-task/constants.ts", "passed": true, "evidence": "654 lines, detailed responsibility breakdown, full import maps"}
]
}
@@ -0,0 +1,342 @@
# Code Changes
## 1. NEW: `src/tools/delegate-task/default-categories.ts`
```typescript
import type { CategoryConfig } from "../../config/schema"
export const DEFAULT_CATEGORIES: Record<string, CategoryConfig> = {
"visual-engineering": { model: "google/gemini-3.1-pro", variant: "high" },
ultrabrain: { model: "openai/gpt-5.4", variant: "xhigh" },
deep: { model: "openai/gpt-5.3-codex", variant: "medium" },
artistry: { model: "google/gemini-3.1-pro", variant: "high" },
quick: { model: "anthropic/claude-haiku-4-5" },
"unspecified-low": { model: "anthropic/claude-sonnet-4-6" },
"unspecified-high": { model: "anthropic/claude-opus-4-6", variant: "max" },
writing: { model: "kimi-for-coding/k2p5" },
}
```
## 2. NEW: `src/tools/delegate-task/category-descriptions.ts`
```typescript
export const CATEGORY_DESCRIPTIONS: Record<string, string> = {
"visual-engineering": "Frontend, UI/UX, design, styling, animation",
ultrabrain: "Use ONLY for genuinely hard, logic-heavy tasks. Give clear goals only, not step-by-step instructions.",
deep: "Goal-oriented autonomous problem-solving. Thorough research before action. For hairy problems requiring deep understanding.",
artistry: "Complex problem-solving with unconventional, creative approaches - beyond standard patterns",
quick: "Trivial tasks - single file changes, typo fixes, simple modifications",
"unspecified-low": "Tasks that don't fit other categories, low effort required",
"unspecified-high": "Tasks that don't fit other categories, high effort required",
writing: "Documentation, prose, technical writing",
}
```
## 3. NEW: `src/tools/delegate-task/category-prompt-appends.ts`
```typescript
export const VISUAL_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on VISUAL/UI tasks.
...
</Category_Context>`
export const ULTRABRAIN_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on DEEP LOGICAL REASONING / COMPLEX ARCHITECTURE tasks.
...
</Category_Context>`
export const ARTISTRY_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on HIGHLY CREATIVE / ARTISTIC tasks.
...
</Category_Context>`
export const QUICK_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on SMALL / QUICK tasks.
...
</Caller_Warning>`
export const UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on tasks that don't fit specific categories but require moderate effort.
...
</Caller_Warning>`
export const UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on tasks that don't fit specific categories but require substantial effort.
...
</Category_Context>`
export const WRITING_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on WRITING / PROSE tasks.
...
</Category_Context>`
export const DEEP_CATEGORY_PROMPT_APPEND = `<Category_Context>
You are working on GOAL-ORIENTED AUTONOMOUS tasks.
...
</Category_Context>`
export const CATEGORY_PROMPT_APPENDS: Record<string, string> = {
"visual-engineering": VISUAL_CATEGORY_PROMPT_APPEND,
ultrabrain: ULTRABRAIN_CATEGORY_PROMPT_APPEND,
deep: DEEP_CATEGORY_PROMPT_APPEND,
artistry: ARTISTRY_CATEGORY_PROMPT_APPEND,
quick: QUICK_CATEGORY_PROMPT_APPEND,
"unspecified-low": UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND,
"unspecified-high": UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND,
writing: WRITING_CATEGORY_PROMPT_APPEND,
}
```
> Note: Each `*_CATEGORY_PROMPT_APPEND` contains the full template string from the original. Abbreviated with `...` here for readability. The actual code would contain the complete unmodified prompt text.
## 4. NEW: `src/tools/delegate-task/plan-agent-prompt.ts`
```typescript
import type {
AvailableCategory,
AvailableSkill,
} from "../../agents/dynamic-agent-prompt-builder"
import { truncateDescription } from "../../shared/truncate-description"
export const PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS = `<system>
BEFORE you begin planning, you MUST first understand the user's request deeply.
...
</CRITICAL_REQUIREMENT_DEPENDENCY_PARALLEL_EXECUTION_CATEGORY_SKILLS>
<FINAL_OUTPUT_FOR_CALLER>
...
</FINAL_OUTPUT_FOR_CALLER>
`
export const PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS = `### REQUIRED OUTPUT FORMAT
...
`
function renderPlanAgentCategoryRows(categories: AvailableCategory[]): string[] {
const sorted = [...categories].sort((a, b) => a.name.localeCompare(b.name))
return sorted.map((category) => {
const bestFor = category.description || category.name
const model = category.model || ""
return `| \`${category.name}\` | ${bestFor} | ${model} |`
})
}
function renderPlanAgentSkillRows(skills: AvailableSkill[]): string[] {
const sorted = [...skills].sort((a, b) => a.name.localeCompare(b.name))
return sorted.map((skill) => {
const domain = truncateDescription(skill.description).trim() || skill.name
return `| \`${skill.name}\` | ${domain} |`
})
}
export function buildPlanAgentSkillsSection(
categories: AvailableCategory[] = [],
skills: AvailableSkill[] = []
): string {
const categoryRows = renderPlanAgentCategoryRows(categories)
const skillRows = renderPlanAgentSkillRows(skills)
return `### AVAILABLE CATEGORIES
| Category | Best For | Model |
|----------|----------|-------|
${categoryRows.join("\n")}
### AVAILABLE SKILLS (ALWAYS EVALUATE ALL)
Skills inject specialized expertise into the delegated agent.
YOU MUST evaluate EVERY skill and justify inclusions/omissions.
| Skill | Domain |
|-------|--------|
${skillRows.join("\n")}`
}
export function buildPlanAgentSystemPrepend(
categories: AvailableCategory[] = [],
skills: AvailableSkill[] = []
): string {
return [
PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS,
buildPlanAgentSkillsSection(categories, skills),
PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS,
].join("\n\n")
}
```
> Note: Template strings abbreviated with `...`. Full unmodified content in the actual file.
## 5. NEW: `src/tools/delegate-task/plan-agent-identity.ts`
```typescript
/**
* List of agent names that should be treated as plan agents (receive plan system prompt).
* Case-insensitive matching is used.
*/
export const PLAN_AGENT_NAMES = ["plan"]
/**
* Check if the given agent name is a plan agent (receives plan system prompt).
*/
export function isPlanAgent(agentName: string | undefined): boolean {
if (!agentName) return false
const lowerName = agentName.toLowerCase().trim()
return PLAN_AGENT_NAMES.some(name => lowerName === name || lowerName.includes(name))
}
/**
* Plan family: plan + prometheus. Shares mutual delegation blocking and task tool permission.
* Does NOT share system prompt (only isPlanAgent controls that).
*/
export const PLAN_FAMILY_NAMES = ["plan", "prometheus"]
/**
* Check if the given agent belongs to the plan family (blocking + task permission).
*/
export function isPlanFamily(category: string): boolean
export function isPlanFamily(category: string | undefined): boolean
export function isPlanFamily(category: string | undefined): boolean {
if (!category) return false
const lowerCategory = category.toLowerCase().trim()
return PLAN_FAMILY_NAMES.some(
(name) => lowerCategory === name || lowerCategory.includes(name)
)
}
```
## 6. MODIFIED: `src/tools/delegate-task/constants.ts` (barrel re-export)
```typescript
export { DEFAULT_CATEGORIES } from "./default-categories"
export { CATEGORY_DESCRIPTIONS } from "./category-descriptions"
export {
VISUAL_CATEGORY_PROMPT_APPEND,
ULTRABRAIN_CATEGORY_PROMPT_APPEND,
ARTISTRY_CATEGORY_PROMPT_APPEND,
QUICK_CATEGORY_PROMPT_APPEND,
UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND,
UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND,
WRITING_CATEGORY_PROMPT_APPEND,
DEEP_CATEGORY_PROMPT_APPEND,
CATEGORY_PROMPT_APPENDS,
} from "./category-prompt-appends"
export {
PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS,
PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS,
buildPlanAgentSkillsSection,
buildPlanAgentSystemPrepend,
} from "./plan-agent-prompt"
export {
PLAN_AGENT_NAMES,
isPlanAgent,
PLAN_FAMILY_NAMES,
isPlanFamily,
} from "./plan-agent-identity"
```
## 7. NEW: `src/shared/category-model-requirements.ts`
```typescript
import type { ModelRequirement } from "./model-requirements"
export const CATEGORY_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
"visual-engineering": {
fallbackChain: [
{
providers: ["google", "github-copilot", "opencode"],
model: "gemini-3.1-pro",
variant: "high",
},
{ providers: ["zai-coding-plan", "opencode"], model: "glm-5" },
{
providers: ["anthropic", "github-copilot", "opencode"],
model: "claude-opus-4-6",
variant: "max",
},
{ providers: ["opencode-go"], model: "glm-5" },
{ providers: ["kimi-for-coding"], model: "k2p5" },
],
},
ultrabrain: {
fallbackChain: [
// ... full content from original
],
},
deep: {
fallbackChain: [
// ... full content from original
],
requiresModel: "gpt-5.3-codex",
},
artistry: {
fallbackChain: [
// ... full content from original
],
requiresModel: "gemini-3.1-pro",
},
quick: {
fallbackChain: [
// ... full content from original
],
},
"unspecified-low": {
fallbackChain: [
// ... full content from original
],
},
"unspecified-high": {
fallbackChain: [
// ... full content from original
],
},
writing: {
fallbackChain: [
// ... full content from original
],
},
}
```
> Note: Each category's `fallbackChain` contains the exact same entries as the original `model-requirements.ts`. Abbreviated here.
## 8. MODIFIED: `src/shared/model-requirements.ts`
**Remove** `CATEGORY_MODEL_REQUIREMENTS` from the file body. **Add** re-export at the end:
```typescript
export type FallbackEntry = {
providers: string[];
model: string;
variant?: string;
};
export type ModelRequirement = {
fallbackChain: FallbackEntry[];
variant?: string;
requiresModel?: string;
requiresAnyModel?: boolean;
requiresProvider?: string[];
};
export const AGENT_MODEL_REQUIREMENTS: Record<string, ModelRequirement> = {
// ... unchanged, full agent entries stay here
};
export { CATEGORY_MODEL_REQUIREMENTS } from "./category-model-requirements"
```
## Summary of Changes
| File | Lines Before | Lines After | Action |
|------|-------------|-------------|--------|
| `constants.ts` | 654 | ~25 | Rewrite as barrel re-export |
| `default-categories.ts` | - | ~15 | **NEW** |
| `category-descriptions.ts` | - | ~12 | **NEW** |
| `category-prompt-appends.ts` | - | ~280 | **NEW** (mostly exempt prompt text) |
| `plan-agent-prompt.ts` | - | ~270 | **NEW** (mostly exempt prompt text) |
| `plan-agent-identity.ts` | - | ~35 | **NEW** |
| `model-requirements.ts` | 311 | ~165 | Remove CATEGORY_MODEL_REQUIREMENTS |
| `category-model-requirements.ts` | - | ~150 | **NEW** |
**Zero consumer files modified.** Backward compatibility maintained through barrel re-exports.
@@ -0,0 +1,131 @@
# Execution Plan: Refactor constants.ts
## Context
`src/tools/delegate-task/constants.ts` is **654 lines** with 6 distinct responsibilities. Violates the 200 LOC modular-code-enforcement rule. `CATEGORY_MODEL_REQUIREMENTS` is actually in `src/shared/model-requirements.ts` (311 lines, also violating 200 LOC), not in `constants.ts`.
## Pre-Flight Analysis
### Current `constants.ts` responsibilities:
1. **Category prompt appends** (8 template strings, ~274 LOC prompt text)
2. **DEFAULT_CATEGORIES** (Record<string, CategoryConfig>, ~10 LOC)
3. **CATEGORY_PROMPT_APPENDS** (map of category->prompt, ~10 LOC)
4. **CATEGORY_DESCRIPTIONS** (map of category->description, ~10 LOC)
5. **Plan agent prompts** (2 template strings + 4 builder functions, ~250 LOC prompt text)
6. **Plan agent identity utils** (`isPlanAgent`, `isPlanFamily`, ~30 LOC)
### Current `model-requirements.ts` responsibilities:
1. Types (`FallbackEntry`, `ModelRequirement`)
2. `AGENT_MODEL_REQUIREMENTS` (~146 LOC)
3. `CATEGORY_MODEL_REQUIREMENTS` (~148 LOC)
### Import dependency map for `constants.ts`:
**Internal consumers (within delegate-task/):**
| File | Imports |
|------|---------|
| `categories.ts` | `DEFAULT_CATEGORIES`, `CATEGORY_PROMPT_APPENDS` |
| `tools.ts` | `CATEGORY_DESCRIPTIONS` |
| `tools.test.ts` | `DEFAULT_CATEGORIES`, `CATEGORY_PROMPT_APPENDS`, `CATEGORY_DESCRIPTIONS`, `isPlanAgent`, `PLAN_AGENT_NAMES`, `isPlanFamily`, `PLAN_FAMILY_NAMES` |
| `prompt-builder.ts` | `buildPlanAgentSystemPrepend`, `isPlanAgent` |
| `subagent-resolver.ts` | `isPlanFamily` |
| `sync-continuation.ts` | `isPlanFamily` |
| `sync-prompt-sender.ts` | `isPlanFamily` |
| `index.ts` | `export * from "./constants"` (barrel) |
**External consumers (import from `"../../tools/delegate-task/constants"`):**
| File | Imports |
|------|---------|
| `agents/atlas/prompt-section-builder.ts` | `CATEGORY_DESCRIPTIONS` |
| `agents/builtin-agents.ts` | `CATEGORY_DESCRIPTIONS` |
| `plugin/available-categories.ts` | `CATEGORY_DESCRIPTIONS` |
| `plugin-handlers/category-config-resolver.ts` | `DEFAULT_CATEGORIES` |
| `shared/merge-categories.ts` | `DEFAULT_CATEGORIES` |
| `shared/merge-categories.test.ts` | `DEFAULT_CATEGORIES` |
**External consumers of `CATEGORY_MODEL_REQUIREMENTS`:**
| File | Import path |
|------|-------------|
| `tools/delegate-task/categories.ts` | `../../shared/model-requirements` |
## Step-by-Step Execution
### Step 1: Create branch
```bash
git checkout -b refactor/split-category-constants dev
```
### Step 2: Split `constants.ts` into 5 focused files
#### 2a. Create `default-categories.ts`
- Move `DEFAULT_CATEGORIES` record
- Import `CategoryConfig` type from config schema
- ~15 LOC
#### 2b. Create `category-descriptions.ts`
- Move `CATEGORY_DESCRIPTIONS` record
- No dependencies
- ~12 LOC
#### 2c. Create `category-prompt-appends.ts`
- Move all 8 `*_CATEGORY_PROMPT_APPEND` template string constants
- Move `CATEGORY_PROMPT_APPENDS` mapping record
- No dependencies (all self-contained template strings)
- ~280 LOC (mostly prompt text, exempt from 200 LOC per modular-code-enforcement)
#### 2d. Create `plan-agent-prompt.ts`
- Move `PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS`
- Move `PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS`
- Move `renderPlanAgentCategoryRows()`, `renderPlanAgentSkillRows()`
- Move `buildPlanAgentSkillsSection()`, `buildPlanAgentSystemPrepend()`
- Imports: `AvailableCategory`, `AvailableSkill` from agents, `truncateDescription` from shared
- ~270 LOC (mostly prompt text, exempt)
#### 2e. Create `plan-agent-identity.ts`
- Move `PLAN_AGENT_NAMES`, `isPlanAgent()`
- Move `PLAN_FAMILY_NAMES`, `isPlanFamily()`
- No dependencies
- ~35 LOC
### Step 3: Convert `constants.ts` to barrel re-export file
Replace entire contents with re-exports from the 5 new files. This maintains 100% backward compatibility for all existing importers.
### Step 4: Split `model-requirements.ts`
#### 4a. Create `src/shared/category-model-requirements.ts`
- Move `CATEGORY_MODEL_REQUIREMENTS` record
- Import `ModelRequirement` type from `./model-requirements`
- ~150 LOC
#### 4b. Update `model-requirements.ts`
- Remove `CATEGORY_MODEL_REQUIREMENTS`
- Add re-export: `export { CATEGORY_MODEL_REQUIREMENTS } from "./category-model-requirements"`
- Keep types (`FallbackEntry`, `ModelRequirement`) and `AGENT_MODEL_REQUIREMENTS`
- ~165 LOC (now under 200)
### Step 5: Verify no import breakage
- Run `bun run typecheck` to confirm all imports resolve
- Run `bun test` to confirm no behavioral regressions
- Run `bun run build` to confirm build succeeds
### Step 6: Verify LSP diagnostics clean
- Check `lsp_diagnostics` on all new and modified files
### Step 7: Commit and create PR
- Single atomic commit: `refactor: split delegate-task constants and category model requirements into focused modules`
- Create PR with description
## Files Modified
| File | Action |
|------|--------|
| `src/tools/delegate-task/constants.ts` | Rewrite as barrel re-export |
| `src/tools/delegate-task/default-categories.ts` | **NEW** |
| `src/tools/delegate-task/category-descriptions.ts` | **NEW** |
| `src/tools/delegate-task/category-prompt-appends.ts` | **NEW** |
| `src/tools/delegate-task/plan-agent-prompt.ts` | **NEW** |
| `src/tools/delegate-task/plan-agent-identity.ts` | **NEW** |
| `src/shared/model-requirements.ts` | Remove CATEGORY_MODEL_REQUIREMENTS, add re-export |
| `src/shared/category-model-requirements.ts` | **NEW** |
**Zero changes to any consumer files.** All existing imports work via barrel re-exports.
@@ -0,0 +1,39 @@
## Summary
- Split `src/tools/delegate-task/constants.ts` (654 LOC, 6 responsibilities) into 5 focused modules: `default-categories.ts`, `category-descriptions.ts`, `category-prompt-appends.ts`, `plan-agent-prompt.ts`, `plan-agent-identity.ts`
- Extract `CATEGORY_MODEL_REQUIREMENTS` from `src/shared/model-requirements.ts` (311 LOC) into `category-model-requirements.ts`, bringing both files under the 200 LOC limit
- Convert original files to barrel re-exports for 100% backward compatibility (zero consumer changes)
## Motivation
Both files violate the project's 200 LOC modular-code-enforcement rule. `constants.ts` mixed 6 unrelated responsibilities (category configs, prompt templates, plan agent builders, identity utils). `model-requirements.ts` mixed agent and category model requirements.
## Changes
### `src/tools/delegate-task/`
| New File | Responsibility |
|----------|---------------|
| `default-categories.ts` | `DEFAULT_CATEGORIES` record |
| `category-descriptions.ts` | `CATEGORY_DESCRIPTIONS` record |
| `category-prompt-appends.ts` | 8 prompt template constants + `CATEGORY_PROMPT_APPENDS` map |
| `plan-agent-prompt.ts` | Plan agent system prompts + builder functions |
| `plan-agent-identity.ts` | `isPlanAgent`, `isPlanFamily` + name lists |
`constants.ts` is now a barrel re-export file (~25 LOC).
### `src/shared/`
| New File | Responsibility |
|----------|---------------|
| `category-model-requirements.ts` | `CATEGORY_MODEL_REQUIREMENTS` record |
`model-requirements.ts` retains types + `AGENT_MODEL_REQUIREMENTS` and re-exports `CATEGORY_MODEL_REQUIREMENTS`.
## Backward Compatibility
All existing import paths (`from "./constants"`, `from "../../tools/delegate-task/constants"`, `from "../../shared/model-requirements"`) continue to work unchanged. Zero consumer files modified.
## Testing
- `bun run typecheck` passes
- `bun test` passes (existing `tools.test.ts` validates all re-exported symbols)
- `bun run build` succeeds
@@ -0,0 +1,128 @@
# Verification Strategy
## 1. Type Safety
### 1a. LSP diagnostics on all new files
```
lsp_diagnostics("src/tools/delegate-task/default-categories.ts")
lsp_diagnostics("src/tools/delegate-task/category-descriptions.ts")
lsp_diagnostics("src/tools/delegate-task/category-prompt-appends.ts")
lsp_diagnostics("src/tools/delegate-task/plan-agent-prompt.ts")
lsp_diagnostics("src/tools/delegate-task/plan-agent-identity.ts")
lsp_diagnostics("src/shared/category-model-requirements.ts")
```
### 1b. LSP diagnostics on modified files
```
lsp_diagnostics("src/tools/delegate-task/constants.ts")
lsp_diagnostics("src/shared/model-requirements.ts")
```
### 1c. Full typecheck
```bash
bun run typecheck
```
Expected: 0 errors. This confirms all 14 consumer files (8 internal + 6 external) resolve their imports correctly through the barrel re-exports.
## 2. Behavioral Regression
### 2a. Existing test suite
```bash
bun test src/tools/delegate-task/tools.test.ts
```
This test file imports `DEFAULT_CATEGORIES`, `CATEGORY_PROMPT_APPENDS`, `CATEGORY_DESCRIPTIONS`, `isPlanAgent`, `PLAN_AGENT_NAMES`, `isPlanFamily`, `PLAN_FAMILY_NAMES` from `./constants`. If the barrel re-export is correct, all these tests pass unchanged.
### 2b. Category resolver tests
```bash
bun test src/tools/delegate-task/category-resolver.test.ts
```
This exercises `resolveCategoryConfig()` which imports `DEFAULT_CATEGORIES` and `CATEGORY_PROMPT_APPENDS` from `./constants` and `CATEGORY_MODEL_REQUIREMENTS` from `../../shared/model-requirements`.
### 2c. Model selection tests
```bash
bun test src/tools/delegate-task/model-selection.test.ts
```
### 2d. Merge categories tests
```bash
bun test src/shared/merge-categories.test.ts
```
Imports `DEFAULT_CATEGORIES` from `../tools/delegate-task/constants` (external path).
### 2e. Full test suite
```bash
bun test
```
## 3. Build Verification
```bash
bun run build
```
Confirms ESM bundle + declarations emit correctly with the new file structure.
## 4. Export Completeness Verification
### 4a. Verify `constants.ts` re-exports match original exports
Cross-check that every symbol previously exported from `constants.ts` is still exported. The original file exported these symbols:
- `VISUAL_CATEGORY_PROMPT_APPEND`
- `ULTRABRAIN_CATEGORY_PROMPT_APPEND`
- `ARTISTRY_CATEGORY_PROMPT_APPEND`
- `QUICK_CATEGORY_PROMPT_APPEND`
- `UNSPECIFIED_LOW_CATEGORY_PROMPT_APPEND`
- `UNSPECIFIED_HIGH_CATEGORY_PROMPT_APPEND`
- `WRITING_CATEGORY_PROMPT_APPEND`
- `DEEP_CATEGORY_PROMPT_APPEND`
- `DEFAULT_CATEGORIES`
- `CATEGORY_PROMPT_APPENDS`
- `CATEGORY_DESCRIPTIONS`
- `PLAN_AGENT_SYSTEM_PREPEND_STATIC_BEFORE_SKILLS`
- `PLAN_AGENT_SYSTEM_PREPEND_STATIC_AFTER_SKILLS`
- `buildPlanAgentSkillsSection`
- `buildPlanAgentSystemPrepend`
- `PLAN_AGENT_NAMES`
- `isPlanAgent`
- `PLAN_FAMILY_NAMES`
- `isPlanFamily`
All 19 must be re-exported from the barrel.
### 4b. Verify `model-requirements.ts` re-exports match original exports
Original exports: `FallbackEntry`, `ModelRequirement`, `AGENT_MODEL_REQUIREMENTS`, `CATEGORY_MODEL_REQUIREMENTS`. All 4 must still be available.
## 5. LOC Compliance Check
Verify each new file is under 200 LOC (excluding prompt template text per modular-code-enforcement rule):
| File | Expected Total LOC | Non-prompt LOC | Compliant? |
|------|-------------------|----------------|------------|
| `default-categories.ts` | ~15 | ~15 | Yes |
| `category-descriptions.ts` | ~12 | ~12 | Yes |
| `category-prompt-appends.ts` | ~280 | ~15 | Yes (prompt exempt) |
| `plan-agent-prompt.ts` | ~270 | ~40 | Yes (prompt exempt) |
| `plan-agent-identity.ts` | ~35 | ~35 | Yes |
| `category-model-requirements.ts` | ~150 | ~150 | Yes |
| `model-requirements.ts` (after) | ~165 | ~165 | Yes |
| `constants.ts` (after) | ~25 | ~25 | Yes |
## 6. Consumer Impact Matrix
Verify zero consumer files need changes:
| Consumer File | Import Path | Should Still Work? |
|--------------|-------------|-------------------|
| `delegate-task/categories.ts` | `./constants` | Yes (barrel) |
| `delegate-task/tools.ts` | `./constants` | Yes (barrel) |
| `delegate-task/tools.test.ts` | `./constants` | Yes (barrel) |
| `delegate-task/prompt-builder.ts` | `./constants` | Yes (barrel) |
| `delegate-task/subagent-resolver.ts` | `./constants` | Yes (barrel) |
| `delegate-task/sync-continuation.ts` | `./constants` | Yes (barrel) |
| `delegate-task/sync-prompt-sender.ts` | `./constants` | Yes (barrel) |
| `delegate-task/index.ts` | `./constants` | Yes (barrel) |
| `agents/atlas/prompt-section-builder.ts` | `../../tools/delegate-task/constants` | Yes (barrel) |
| `agents/builtin-agents.ts` | `../tools/delegate-task/constants` | Yes (barrel) |
| `plugin/available-categories.ts` | `../tools/delegate-task/constants` | Yes (barrel) |
| `plugin-handlers/category-config-resolver.ts` | `../tools/delegate-task/constants` | Yes (barrel) |
| `shared/merge-categories.ts` | `../tools/delegate-task/constants` | Yes (barrel) |
| `shared/merge-categories.test.ts` | `../tools/delegate-task/constants` | Yes (barrel) |
| `delegate-task/categories.ts` | `../../shared/model-requirements` | Yes (re-export) |
@@ -0,0 +1 @@
{"total_tokens": null, "duration_ms": 229000, "total_duration_seconds": 229}