From b63082a3bb9272ce0ad457a619fd28e98810b152 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 14 Mar 2026 13:44:02 +0900 Subject: [PATCH] fix(skills): correct invalid task tool references --- .opencode/skills/github-triage/SKILL.md | 8 ++-- .opencode/skills/work-with-pr/SKILL.md | 2 +- .../project-skill-tool-references.test.ts | 41 +++++++++++++++++++ 3 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 src/features/opencode-skill-loader/project-skill-tool-references.test.ts diff --git a/.opencode/skills/github-triage/SKILL.md b/.opencode/skills/github-triage/SKILL.md index 7e2cefec0..ae534022a 100644 --- a/.opencode/skills/github-triage/SKILL.md +++ b/.opencode/skills/github-triage/SKILL.md @@ -11,14 +11,14 @@ Read-only GitHub triage orchestrator. Fetch open issues/PRs, classify, spawn 1 b ## Architecture -**1 ISSUE/PR = 1 TASKCREATE = 1 `quick` SUBAGENT (background). NO EXCEPTIONS.** +**1 ISSUE/PR = 1 `task_create` = 1 `quick` SUBAGENT (background). NO EXCEPTIONS.** | Rule | Value | |------|-------| | Category | `quick` | | Execution | `run_in_background=true` | | Parallelism | ALL items simultaneously | -| Tracking | `TaskCreate` per item | +| Tracking | `task_create` per item | | Output | `/tmp/{YYYYMMDD-HHmmss}/issue-{N}.md` or `pr-{N}.md` | --- @@ -140,7 +140,7 @@ fi ``` For each item: - 1. TaskCreate(subject="Triage: #{number} {title}") + 1. task_create(subject="Triage: #{number} {title}") 2. task(category="quick", run_in_background=true, load_skills=[], prompt=SUBAGENT_PROMPT) 3. Store mapping: item_number -> { task_id, background_task_id } ``` @@ -482,7 +482,7 @@ NEVER merge. NEVER comment. NEVER review. Write to file ONLY. Poll `background_output()` per task. As each completes: 1. Parse report. -2. `TaskUpdate(id=task_id, status="completed", description=REPORT_SUMMARY)` +2. `task_update(id=task_id, status="completed", description=REPORT_SUMMARY)` 3. Stream to user immediately. --- diff --git a/.opencode/skills/work-with-pr/SKILL.md b/.opencode/skills/work-with-pr/SKILL.md index 7a7c44450..67282c54f 100644 --- a/.opencode/skills/work-with-pr/SKILL.md +++ b/.opencode/skills/work-with-pr/SKILL.md @@ -94,7 +94,7 @@ Use the git-master skill's atomic commit principles. The reason for atomic commi Each commit should pair implementation with its tests. Load `git-master` skill when committing: ``` -task(category="git", load_skills=["git-master"], prompt="Commit the changes atomically following git-master conventions. Repository is at {WORKTREE_PATH}.") +task(category="quick", load_skills=["git-master"], prompt="Commit the changes atomically following git-master conventions. Repository is at {WORKTREE_PATH}.") ``` ### Pre-push local validation diff --git a/src/features/opencode-skill-loader/project-skill-tool-references.test.ts b/src/features/opencode-skill-loader/project-skill-tool-references.test.ts new file mode 100644 index 000000000..c417f6c21 --- /dev/null +++ b/src/features/opencode-skill-loader/project-skill-tool-references.test.ts @@ -0,0 +1,41 @@ +/// + +import { describe, expect, test } from "bun:test" +import { readFileSync } from "node:fs" +import { join } from "node:path" +import { fileURLToPath } from "node:url" + +const PROJECT_ROOT = fileURLToPath(new URL("../../..", import.meta.url)) + +function readProjectSkill(...segments: string[]) { + return readFileSync(join(PROJECT_ROOT, ".opencode", "skills", ...segments, "SKILL.md"), "utf8") +} + +describe("project skill tool references", () => { + describe("#given work-with-pr skill instructions", () => { + test("#when reading the commit delegation example #then it uses a real task category", () => { + const skillContent = readProjectSkill("work-with-pr") + + const usesQuickCategory = skillContent.includes( + 'task(category="quick", load_skills=["git-master"], prompt="Commit the changes atomically following git-master conventions. Repository is at {WORKTREE_PATH}.")' + ) + + expect(usesQuickCategory).toBe(true) + expect(skillContent).not.toContain('task(category="git"') + }) + }) + + describe("#given github-triage skill instructions", () => { + test("#when reading task tracking examples #then they use the real task management tool names", () => { + const skillContent = readProjectSkill("github-triage") + + const usesRealToolNames = + skillContent.includes("task_create(subject=\"Triage: #{number} {title}\")") + && skillContent.includes("task_update(id=task_id, status=\"completed\", description=REPORT_SUMMARY)") + + expect(usesRealToolNames).toBe(true) + expect(skillContent).not.toContain("TaskCreate(") + expect(skillContent).not.toContain("TaskUpdate(") + }) + }) +})