Skip to content

Commit 968727c

Browse files
committed
fix: restrict agent permissions to openspec directories
1 parent df9bb34 commit 968727c

1 file changed

Lines changed: 23 additions & 10 deletions

File tree

src/config.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,21 @@ import type { Hooks } from "@opencode-ai/plugin";
22
import { isOpenSpecProject } from "./utils/detection";
33
import { OPENSPEC_SYSTEM_PROMPT } from "./prompts";
44

5-
export function createConfigHook(ctx: { directory: string }): Hooks["config"] {
5+
export function createConfigHook(ctx: { directory: string }, log: (msg: string, ...args: any[]) => void): Hooks["config"] {
66
return async (config) => {
7+
log("[OpenSpec Plugin] Config hook triggered.");
8+
79
// 1. Check if this is an OpenSpec project
810
const mockCtx = { directory: ctx.directory } as any;
911

10-
if (!await isOpenSpecProject(mockCtx)) {
12+
const isActive = await isOpenSpecProject(mockCtx);
13+
if (!isActive) {
14+
log("[OpenSpec Plugin] Config hook: Not an OpenSpec project, skipping.");
1115
return;
1216
}
1317

18+
log("[OpenSpec Plugin] Config hook: Injecting openspec-plan agent.");
19+
1420
// 2. Define the OpenSpec Plan Agent
1521
const openSpecAgent = {
1622
name: "openspec-plan",
@@ -19,22 +25,29 @@ export function createConfigHook(ctx: { directory: string }): Hooks["config"] {
1925
prompt: OPENSPEC_SYSTEM_PROMPT,
2026
permission: {
2127
edit: {
22-
"**/*.spec.md": "allow",
23-
"**/project.md": "allow",
24-
"**/AGENTS.md": "allow",
25-
// Allow creating new spec directories
26-
"specs/**": "allow",
27-
"openspec/**": "allow"
28+
// Allow editing specific root files
29+
"project.md": "allow",
30+
"AGENTS.md": "allow",
31+
// Allow editing anything in openspec directory
32+
"openspec/**": "allow",
33+
// Allow editing anything in specs directory (standard OpenSpec structure)
34+
"specs/**": "allow"
2835
}
2936
},
3037
color: "#FF6B6B" // Distinctive color for the agent
3138
};
3239

3340
// 3. Inject into configuration
34-
// We use 'any' cast here to bypass strict type checking on the config object structure
35-
// because we are dynamically extending it.
3641
const agentConfig = (config.agent || {}) as any;
42+
43+
// Check if already injected to avoid potential re-injection loops
44+
if (agentConfig["openspec-plan"]) {
45+
log("[OpenSpec Plugin] Agent already exists, updating...");
46+
}
47+
3748
agentConfig["openspec-plan"] = openSpecAgent;
3849
config.agent = agentConfig;
50+
51+
log("[OpenSpec Plugin] Config hook: Injection complete.");
3952
};
4053
}

0 commit comments

Comments
 (0)