From 3eb97110c65aa7a9820d111e27d7158c7d8164d1 Mon Sep 17 00:00:00 2001 From: Stranmor Date: Tue, 3 Mar 2026 03:32:07 +0300 Subject: [PATCH 001/110] feat: support file:// URIs in agent prompt field --- src/agents/builtin-agents/agent-overrides.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/agents/builtin-agents/agent-overrides.ts b/src/agents/builtin-agents/agent-overrides.ts index 89873def6..4220f713b 100644 --- a/src/agents/builtin-agents/agent-overrides.ts +++ b/src/agents/builtin-agents/agent-overrides.ts @@ -44,6 +44,10 @@ export function mergeAgentConfig( const { prompt_append, ...rest } = migratedOverride const merged = deepMerge(base, rest as Partial) + if (merged.prompt && typeof merged.prompt === 'string' && merged.prompt.startsWith('file://')) { + merged.prompt = resolvePromptAppend(merged.prompt, directory) + } + if (prompt_append && merged.prompt) { merged.prompt = merged.prompt + "\n" + resolvePromptAppend(prompt_append, directory) } From 229c6b0cdb9ae1e51baa18cd8387378a43feaffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9F=A9=E6=BE=8D?= <38775458+DarkFunct@users.noreply.github.com> Date: Fri, 6 Mar 2026 23:28:58 +0800 Subject: [PATCH 002/110] fix(todo-sync): provide default priority to prevent SQLite NOT NULL violation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit extractPriority() returns undefined when task metadata has no priority field, but OpenCode's TodoTable requires priority as NOT NULL. This causes a silent SQLiteError that prevents all Task→Todo syncing. Add ?? "medium" fallback so todos always have a valid priority. --- src/tools/task/todo-sync.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/task/todo-sync.ts b/src/tools/task/todo-sync.ts index c11849f8b..1fa9f5956 100644 --- a/src/tools/task/todo-sync.ts +++ b/src/tools/task/todo-sync.ts @@ -65,7 +65,7 @@ export function syncTaskToTodo(task: Task): TodoInfo | null { id: task.id, content: task.subject, status: todoStatus, - priority: extractPriority(task.metadata), + priority: extractPriority(task.metadata) ?? "medium", }; } From 6d8bc95fa67e0eb627c6664ab8091ced90429e23 Mon Sep 17 00:00:00 2001 From: tc9011 Date: Wed, 11 Mar 2026 10:34:25 +0800 Subject: [PATCH 003/110] fix: github copilot model version for Sisyphus agent --- docs/guide/installation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/installation.md b/docs/guide/installation.md index 218fac03f..25160013b 100644 --- a/docs/guide/installation.md +++ b/docs/guide/installation.md @@ -199,7 +199,7 @@ When GitHub Copilot is the best available provider, oh-my-opencode uses these mo | Agent | Model | | ------------- | --------------------------------- | -| **Sisyphus** | `github-copilot/claude-opus-4-6` | +| **Sisyphus** | `github-copilot/claude-opus-4.6` | | **Oracle** | `github-copilot/gpt-5.4` | | **Explore** | `github-copilot/grok-code-fast-1` | | **Librarian** | `github-copilot/gemini-3-flash` | From edfa411684ef9e73f74e3c3025f6989c6271fb76 Mon Sep 17 00:00:00 2001 From: Gujiassh Date: Thu, 12 Mar 2026 19:58:57 +0900 Subject: [PATCH 004/110] fix(session-manager): match todo filenames exactly Stop sibling session IDs from colliding in stable JSON storage by requiring an exact todo filename match instead of a substring filter. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/tools/session-manager/storage.test.ts | 20 ++++++++++++++++++++ src/tools/session-manager/storage.ts | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/tools/session-manager/storage.test.ts b/src/tools/session-manager/storage.test.ts index 447362719..f4e3c1cb0 100644 --- a/src/tools/session-manager/storage.test.ts +++ b/src/tools/session-manager/storage.test.ts @@ -168,6 +168,26 @@ describe("session-manager storage", () => { expect(todos).toEqual([]) }) + test("readSessionTodos only reads the exact session todo file", async () => { + // given + writeFileSync( + join(TEST_TODO_DIR, "ses_1.json"), + JSON.stringify([{ id: "todo_exact", content: "Exact match", status: "pending" }]), + ) + writeFileSync( + join(TEST_TODO_DIR, "ses_10.json"), + JSON.stringify([{ id: "todo_collision", content: "Wrong session", status: "completed" }]), + ) + + // when + const todos = await readSessionTodos("ses_1") + + // then + expect(todos).toHaveLength(1) + expect(todos[0].id).toBe("todo_exact") + expect(todos[0].content).toBe("Exact match") + }) + test("getSessionInfo returns null for non-existent session", async () => { // when const info = await getSessionInfo("ses_nonexistent") diff --git a/src/tools/session-manager/storage.ts b/src/tools/session-manager/storage.ts index 59fda3ffc..2455cd29e 100644 --- a/src/tools/session-manager/storage.ts +++ b/src/tools/session-manager/storage.ts @@ -277,7 +277,7 @@ export async function readSessionTodos(sessionID: string): Promise { try { const allFiles = await readdir(TODO_DIR) - const todoFiles = allFiles.filter((f) => f.includes(sessionID) && f.endsWith(".json")) + const todoFiles = allFiles.filter((f) => f === `${sessionID}.json`) for (const file of todoFiles) { try { From 1e0823a0fc577abc383d82434da5efcd7104076d Mon Sep 17 00:00:00 2001 From: Gujiassh Date: Fri, 13 Mar 2026 01:25:13 +0900 Subject: [PATCH 005/110] fix(delegate-task): report the real background task id Keep background task metadata aligned with the background_output contract so callers do not pass a session id where the task manager expects a background task id. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus --- src/tools/delegate-task/background-task.test.ts | 4 ++-- src/tools/delegate-task/background-task.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/delegate-task/background-task.test.ts b/src/tools/delegate-task/background-task.test.ts index f6ff49cb0..7b631f659 100644 --- a/src/tools/delegate-task/background-task.test.ts +++ b/src/tools/delegate-task/background-task.test.ts @@ -102,7 +102,7 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => //#then - output and metadata should include canonical session linkage expectFn(result).toContain("") expectFn(result).toContain("session_id: ses_sub_123") - expectFn(result).toContain("task_id: ses_sub_123") + expectFn(result).toContain("task_id: bg_resolved") expectFn(result).toContain("background_task_id: bg_resolved") expectFn(result).toContain("Background Task ID: bg_resolved") expectFn(metadataCalls).toHaveLength(1) @@ -150,7 +150,7 @@ describeFn("executeBackgroundTask output/session metadata compatibility", () => //#then - late session id still propagates to task metadata contract expectFn(result).toContain("session_id: ses_late_123") - expectFn(result).toContain("task_id: ses_late_123") + expectFn(result).toContain("task_id: bg_late") expectFn(result).toContain("background_task_id: bg_late") expectFn(metadataCalls).toHaveLength(1) expectFn(metadataCalls[0].metadata.sessionId).toBe("ses_late_123") diff --git a/src/tools/delegate-task/background-task.ts b/src/tools/delegate-task/background-task.ts index 1e0d2a697..04e0b1cb4 100644 --- a/src/tools/delegate-task/background-task.ts +++ b/src/tools/delegate-task/background-task.ts @@ -82,7 +82,7 @@ export async function executeBackgroundTask( } const taskMetadataBlock = sessionId - ? `\n\n\nsession_id: ${sessionId}\ntask_id: ${sessionId}\nbackground_task_id: ${task.id}\n` + ? `\n\n\nsession_id: ${sessionId}\ntask_id: ${task.id}\nbackground_task_id: ${task.id}\n` : "" return `Background task launched. From a7a7799b44eada0f3710b0c426c80e199fb0c2f2 Mon Sep 17 00:00:00 2001 From: djdembeck Date: Thu, 12 Mar 2026 15:53:23 -0500 Subject: [PATCH 006/110] fix(agents): add termination criteria to Sisyphus-Junior default --- src/agents/sisyphus-junior/default.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/agents/sisyphus-junior/default.ts b/src/agents/sisyphus-junior/default.ts index bdd5467e7..d53a815b6 100644 --- a/src/agents/sisyphus-junior/default.ts +++ b/src/agents/sisyphus-junior/default.ts @@ -35,6 +35,11 @@ Task NOT complete without: - ${verificationText} + +STOP after first successful verification. Do NOT re-verify. +Maximum status checks: 2. Then stop regardless. + +