fix: clarify Prometheus file permission error message (fixes #2150)
This commit is contained in:
@@ -17,7 +17,7 @@ export const PLANNING_CONSULT_WARNING = `
|
|||||||
|
|
||||||
${createSystemDirective(SystemDirectiveTypes.PROMETHEUS_READ_ONLY)}
|
${createSystemDirective(SystemDirectiveTypes.PROMETHEUS_READ_ONLY)}
|
||||||
|
|
||||||
You are being invoked by ${getAgentDisplayName("prometheus")}, a READ-ONLY planning agent.
|
You are being invoked by ${getAgentDisplayName("prometheus")}, a planning agent restricted to .sisyphus/*.md plan files only.
|
||||||
|
|
||||||
**CRITICAL CONSTRAINTS:**
|
**CRITICAL CONSTRAINTS:**
|
||||||
- DO NOT modify any files (no Write, Edit, or any file mutations)
|
- DO NOT modify any files (no Write, Edit, or any file mutations)
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ export function createPrometheusMdOnlyHook(ctx: PluginInput) {
|
|||||||
|
|
||||||
const toolName = input.tool
|
const toolName = input.tool
|
||||||
|
|
||||||
// Inject read-only warning for task tools called by Prometheus
|
// Inject planning-only warning for task tools called by Prometheus
|
||||||
if (TASK_TOOLS.includes(toolName)) {
|
if (TASK_TOOLS.includes(toolName)) {
|
||||||
const prompt = output.args.prompt as string | undefined
|
const prompt = output.args.prompt as string | undefined
|
||||||
if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) {
|
if (prompt && !prompt.includes(SYSTEM_DIRECTIVE_PREFIX)) {
|
||||||
output.args.prompt = PLANNING_CONSULT_WARNING + prompt
|
output.args.prompt = PLANNING_CONSULT_WARNING + prompt
|
||||||
log(`[${HOOK_NAME}] Injected read-only planning warning to ${toolName}`, {
|
log(`[${HOOK_NAME}] Injected planning warning to ${toolName}`, {
|
||||||
sessionID: input.sessionID,
|
sessionID: input.sessionID,
|
||||||
tool: toolName,
|
tool: toolName,
|
||||||
agent: agentName,
|
agent: agentName,
|
||||||
@@ -54,9 +54,8 @@ export function createPrometheusMdOnlyHook(ctx: PluginInput) {
|
|||||||
agent: agentName,
|
agent: agentName,
|
||||||
})
|
})
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`[${HOOK_NAME}] ${getAgentDisplayName("prometheus")} can only write/edit .md files inside .sisyphus/ directory. ` +
|
`[${HOOK_NAME}] Prometheus is a planning agent. File operations restricted to .sisyphus/*.md plan files only. Use task() to delegate implementation. ` +
|
||||||
`Attempted to modify: ${filePath}. ` +
|
`Attempted to modify: ${filePath}. ` +
|
||||||
`${getAgentDisplayName("prometheus")} is a READ-ONLY planner. Use /start-work to execute the plan. ` +
|
|
||||||
`APOLOGIZE TO THE USER, REMIND OF YOUR PLAN WRITING PROCESSES, TELL USER WHAT YOU WILL GOING TO DO AS THE PROCESS, WRITE THE PLAN`
|
`APOLOGIZE TO THE USER, REMIND OF YOUR PLAN WRITING PROCESSES, TELL USER WHAT YOU WILL GOING TO DO AS THE PROCESS, WRITE THE PLAN`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ describe("prometheus-md-only", () => {
|
|||||||
//#when //#then
|
//#when //#then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should enforce md-only restriction for Prometheus display name Plan Builder", async () => {
|
test("should enforce md-only restriction for Prometheus display name Plan Builder", async () => {
|
||||||
@@ -85,7 +85,7 @@ describe("prometheus-md-only", () => {
|
|||||||
//#when //#then
|
//#when //#then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should enforce md-only restriction for Prometheus display name Planner", async () => {
|
test("should enforce md-only restriction for Prometheus display name Planner", async () => {
|
||||||
@@ -104,7 +104,7 @@ describe("prometheus-md-only", () => {
|
|||||||
//#when //#then
|
//#when //#then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should enforce md-only restriction for uppercase PROMETHEUS", async () => {
|
test("should enforce md-only restriction for uppercase PROMETHEUS", async () => {
|
||||||
@@ -123,7 +123,7 @@ describe("prometheus-md-only", () => {
|
|||||||
//#when //#then
|
//#when //#then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should not enforce restriction for non-Prometheus agent", async () => {
|
test("should not enforce restriction for non-Prometheus agent", async () => {
|
||||||
@@ -185,7 +185,7 @@ describe("prometheus-md-only", () => {
|
|||||||
// when / #then
|
// when / #then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should allow Prometheus to write .md files inside .sisyphus/", async () => {
|
test("should allow Prometheus to write .md files inside .sisyphus/", async () => {
|
||||||
@@ -262,7 +262,7 @@ describe("prometheus-md-only", () => {
|
|||||||
// when / #then
|
// when / #then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files inside .sisyphus/")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should block Edit tool for non-.md files", async () => {
|
test("should block Edit tool for non-.md files", async () => {
|
||||||
@@ -280,7 +280,7 @@ describe("prometheus-md-only", () => {
|
|||||||
// when / #then
|
// when / #then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should allow bash commands from Prometheus", async () => {
|
test("should allow bash commands from Prometheus", async () => {
|
||||||
@@ -337,7 +337,7 @@ describe("prometheus-md-only", () => {
|
|||||||
).resolves.toBeUndefined()
|
).resolves.toBeUndefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should inject read-only warning when Prometheus calls task", async () => {
|
test("should inject planning warning when Prometheus calls task", async () => {
|
||||||
// given
|
// given
|
||||||
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
|
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
|
||||||
const input = {
|
const input = {
|
||||||
@@ -357,7 +357,7 @@ describe("prometheus-md-only", () => {
|
|||||||
expect(output.args.prompt).toContain("DO NOT modify any files")
|
expect(output.args.prompt).toContain("DO NOT modify any files")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should inject read-only warning when Prometheus calls task", async () => {
|
test("should inject planning warning when Prometheus calls task", async () => {
|
||||||
// given
|
// given
|
||||||
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
|
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
|
||||||
const input = {
|
const input = {
|
||||||
@@ -376,7 +376,7 @@ describe("prometheus-md-only", () => {
|
|||||||
expect(output.args.prompt).toContain(SYSTEM_DIRECTIVE_PREFIX)
|
expect(output.args.prompt).toContain(SYSTEM_DIRECTIVE_PREFIX)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should inject read-only warning when Prometheus calls call_omo_agent", async () => {
|
test("should inject planning warning when Prometheus calls call_omo_agent", async () => {
|
||||||
// given
|
// given
|
||||||
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
|
const hook = createPrometheusMdOnlyHook(createMockPluginInput())
|
||||||
const input = {
|
const input = {
|
||||||
@@ -540,7 +540,7 @@ describe("prometheus-md-only", () => {
|
|||||||
// when / then - should block because boulder says prometheus
|
// when / then - should block because boulder says prometheus
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should fall back to message files when session not in boulder", async () => {
|
test("should fall back to message files when session not in boulder", async () => {
|
||||||
@@ -573,7 +573,7 @@ describe("prometheus-md-only", () => {
|
|||||||
// when / then - should block because falls back to message files (prometheus)
|
// when / then - should block because falls back to message files (prometheus)
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -675,7 +675,7 @@ describe("prometheus-md-only", () => {
|
|||||||
// when / #then
|
// when / #then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files inside .sisyphus/")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should allow nested .sisyphus directories (ctx.directory may be parent)", async () => {
|
test("should allow nested .sisyphus directories (ctx.directory may be parent)", async () => {
|
||||||
@@ -713,7 +713,7 @@ describe("prometheus-md-only", () => {
|
|||||||
// when / #then
|
// when / #then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files inside .sisyphus/")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should allow case-insensitive .SISYPHUS directory", async () => {
|
test("should allow case-insensitive .SISYPHUS directory", async () => {
|
||||||
@@ -790,7 +790,7 @@ describe("prometheus-md-only", () => {
|
|||||||
// when / #then
|
// when / #then
|
||||||
await expect(
|
await expect(
|
||||||
hook["tool.execute.before"](input, output)
|
hook["tool.execute.before"](input, output)
|
||||||
).rejects.toThrow("can only write/edit .md files")
|
).rejects.toThrow("File operations restricted to .sisyphus/*.md plan files only")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user