fix(task-tool): add task ID validation and improve lock acquisition safety

- Add task ID pattern validation (T-[A-Za-z0-9-]+) to prevent path traversal
- Refactor lock mechanism to use UUID-based IDs for reliable ownership tracking
- Implement atomic lock creation with stale lock detection and cleanup
- Add lock acquisition checks in create/update/delete handlers
- Expand task-reminder hook to track split tool names and clean up on session deletion
- Add comprehensive test coverage for validation and lock handling
This commit is contained in:
YeonGyu-Kim
2026-02-01 23:48:48 +09:00
parent 172446795c
commit f853d885fa
9 changed files with 206 additions and 54 deletions
+25
View File
@@ -122,4 +122,29 @@ describe("TaskReminderHook", () => {
expect(output1.output).toContain("task tools haven't been used")
expect(output2.output).not.toContain("task tools haven't been used")
})
test("cleans up counters on session.deleted", async () => {
//#given
const sessionID = "test-session"
const output = { output: "Result" }
//#when
for (let i = 0; i < 10; i++) {
await hook["tool.execute.after"]?.(
{ tool: "bash", sessionID, callID: `call-${i}` },
output
)
}
await hook.event?.({ event: { type: "session.deleted", properties: { info: { id: sessionID } } } })
const outputAfterDelete = { output: "Result" }
for (let i = 0; i < 9; i++) {
await hook["tool.execute.after"]?.(
{ tool: "bash", sessionID, callID: `call-after-${i}` },
outputAfterDelete
)
}
//#then
expect(outputAfterDelete.output).not.toContain("task tools haven't been used")
})
})
+16 -2
View File
@@ -1,10 +1,17 @@
import type { PluginInput } from "@opencode-ai/plugin"
const TASK_TOOLS = new Set(["task"])
const TASK_TOOLS = new Set([
"task",
"task_create",
"task_list",
"task_get",
"task_update",
"task_delete",
])
const TURN_THRESHOLD = 10
const REMINDER_MESSAGE = `
The task tools haven't been used recently. If you're working on tasks that would benefit from tracking progress, consider using TaskCreate to add new tasks and TaskUpdate to update task status (set to in_progress when starting, completed when done).`
The task tools haven't been used recently. If you're tracking work, use task with action=create/update (or task_create/task_update) to record progress.`
interface ToolExecuteInput {
tool: string
@@ -41,5 +48,12 @@ export function createTaskReminderHook(_ctx: PluginInput) {
return {
"tool.execute.after": toolExecuteAfter,
event: async ({ event }: { event: { type: string; properties?: unknown } }) => {
if (event.type !== "session.deleted") return
const props = event.properties as { info?: { id?: string } } | undefined
const sessionId = props?.info?.id
if (!sessionId) return
sessionCounters.delete(sessionId)
},
}
}