fix(sisyphus-orchestrator): add cross-platform path validation for Windows support
Add isSisyphusPath() helper function that handles both forward slashes (Unix) and backslashes (Windows) using regex pattern /\.sisyphus[/\\]/. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
parent
83d958580f
commit
571810f1e7
@ -506,6 +506,90 @@ describe("sisyphus-orchestrator hook", () => {
|
||||
// #then
|
||||
expect(output.output).toBe(originalOutput)
|
||||
})
|
||||
|
||||
describe("cross-platform path validation (Windows support)", () => {
|
||||
test("should NOT append reminder when orchestrator writes inside .sisyphus\\ (Windows backslash)", async () => {
|
||||
// #given
|
||||
const hook = createSisyphusOrchestratorHook(createMockPluginInput())
|
||||
const originalOutput = "File written successfully"
|
||||
const output = {
|
||||
title: "Write",
|
||||
output: originalOutput,
|
||||
metadata: { filePath: ".sisyphus\\plans\\work-plan.md" },
|
||||
}
|
||||
|
||||
// #when
|
||||
await hook["tool.execute.after"](
|
||||
{ tool: "Write", sessionID: ORCHESTRATOR_SESSION },
|
||||
output
|
||||
)
|
||||
|
||||
// #then
|
||||
expect(output.output).toBe(originalOutput)
|
||||
expect(output.output).not.toContain("DELEGATION REQUIRED")
|
||||
})
|
||||
|
||||
test("should NOT append reminder when orchestrator writes inside .sisyphus with mixed separators", async () => {
|
||||
// #given
|
||||
const hook = createSisyphusOrchestratorHook(createMockPluginInput())
|
||||
const originalOutput = "File written successfully"
|
||||
const output = {
|
||||
title: "Write",
|
||||
output: originalOutput,
|
||||
metadata: { filePath: ".sisyphus\\plans/work-plan.md" },
|
||||
}
|
||||
|
||||
// #when
|
||||
await hook["tool.execute.after"](
|
||||
{ tool: "Write", sessionID: ORCHESTRATOR_SESSION },
|
||||
output
|
||||
)
|
||||
|
||||
// #then
|
||||
expect(output.output).toBe(originalOutput)
|
||||
expect(output.output).not.toContain("DELEGATION REQUIRED")
|
||||
})
|
||||
|
||||
test("should NOT append reminder for absolute Windows path inside .sisyphus\\", async () => {
|
||||
// #given
|
||||
const hook = createSisyphusOrchestratorHook(createMockPluginInput())
|
||||
const originalOutput = "File written successfully"
|
||||
const output = {
|
||||
title: "Write",
|
||||
output: originalOutput,
|
||||
metadata: { filePath: "C:\\Users\\test\\project\\.sisyphus\\plans\\x.md" },
|
||||
}
|
||||
|
||||
// #when
|
||||
await hook["tool.execute.after"](
|
||||
{ tool: "Write", sessionID: ORCHESTRATOR_SESSION },
|
||||
output
|
||||
)
|
||||
|
||||
// #then
|
||||
expect(output.output).toBe(originalOutput)
|
||||
expect(output.output).not.toContain("DELEGATION REQUIRED")
|
||||
})
|
||||
|
||||
test("should append reminder for Windows path outside .sisyphus\\", async () => {
|
||||
// #given
|
||||
const hook = createSisyphusOrchestratorHook(createMockPluginInput())
|
||||
const output = {
|
||||
title: "Write",
|
||||
output: "File written successfully",
|
||||
metadata: { filePath: "C:\\Users\\test\\project\\src\\code.ts" },
|
||||
}
|
||||
|
||||
// #when
|
||||
await hook["tool.execute.after"](
|
||||
{ tool: "Write", sessionID: ORCHESTRATOR_SESSION },
|
||||
output
|
||||
)
|
||||
|
||||
// #then
|
||||
expect(output.output).toContain("DELEGATION REQUIRED")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@ -14,7 +14,14 @@ import type { BackgroundManager } from "../../features/background-agent"
|
||||
|
||||
export const HOOK_NAME = "sisyphus-orchestrator"
|
||||
|
||||
const ALLOWED_PATH_PREFIX = ".sisyphus/"
|
||||
/**
|
||||
* Cross-platform check if a path is inside .sisyphus/ directory.
|
||||
* Handles both forward slashes (Unix) and backslashes (Windows).
|
||||
*/
|
||||
function isSisyphusPath(filePath: string): boolean {
|
||||
return /\.sisyphus[/\\]/.test(filePath)
|
||||
}
|
||||
|
||||
const WRITE_EDIT_TOOLS = ["Write", "Edit", "write", "edit"]
|
||||
|
||||
const DIRECT_WORK_REMINDER = `
|
||||
@ -549,7 +556,7 @@ export function createSisyphusOrchestratorHook(
|
||||
// Check Write/Edit tools for orchestrator - inject strong warning
|
||||
if (WRITE_EDIT_TOOLS.includes(input.tool)) {
|
||||
const filePath = (output.args.filePath ?? output.args.path ?? output.args.file) as string | undefined
|
||||
if (filePath && !filePath.includes(ALLOWED_PATH_PREFIX)) {
|
||||
if (filePath && !isSisyphusPath(filePath)) {
|
||||
// Store filePath for use in tool.execute.after
|
||||
if (input.callID) {
|
||||
pendingFilePaths.set(input.callID, filePath)
|
||||
@ -593,7 +600,7 @@ export function createSisyphusOrchestratorHook(
|
||||
if (!filePath) {
|
||||
filePath = output.metadata?.filePath as string | undefined
|
||||
}
|
||||
if (filePath && !filePath.includes(ALLOWED_PATH_PREFIX)) {
|
||||
if (filePath && !isSisyphusPath(filePath)) {
|
||||
output.output = (output.output || "") + DIRECT_WORK_REMINDER
|
||||
log(`[${HOOK_NAME}] Direct work reminder appended`, {
|
||||
sessionID: input.sessionID,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user