@codemcp/ade-harnesses 0.1.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +20 -12
- package/.prettierignore +0 -1
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-format.log +0 -6
- package/.turbo/turbo-lint.log +0 -4
- package/.turbo/turbo-test.log +0 -23
- package/.turbo/turbo-typecheck.log +0 -4
- package/eslint.config.mjs +0 -40
- package/src/index.spec.ts +0 -45
- package/src/index.ts +0 -47
- package/src/permission-policy.ts +0 -173
- package/src/skills-installer.ts +0 -54
- package/src/types.ts +0 -12
- package/src/util.ts +0 -221
- package/src/writers/claude-code.spec.ts +0 -320
- package/src/writers/claude-code.ts +0 -107
- package/src/writers/cline.spec.ts +0 -212
- package/src/writers/cline.ts +0 -24
- package/src/writers/copilot.spec.ts +0 -258
- package/src/writers/copilot.ts +0 -105
- package/src/writers/cursor.spec.ts +0 -219
- package/src/writers/cursor.ts +0 -95
- package/src/writers/kiro.spec.ts +0 -228
- package/src/writers/kiro.ts +0 -89
- package/src/writers/opencode.spec.ts +0 -258
- package/src/writers/opencode.ts +0 -67
- package/src/writers/roo-code.spec.ts +0 -197
- package/src/writers/roo-code.ts +0 -71
- package/src/writers/universal.spec.ts +0 -134
- package/src/writers/universal.ts +0 -84
- package/src/writers/windsurf.spec.ts +0 -178
- package/src/writers/windsurf.ts +0 -89
- package/tsconfig.build.json +0 -8
- package/tsconfig.json +0 -7
- package/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.vitest.json +0 -7
- package/vitest.config.ts +0 -5
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { mkdtemp, rm, readFile } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import type {
|
|
6
|
-
AutonomyProfile,
|
|
7
|
-
LogicalConfig,
|
|
8
|
-
PermissionPolicy
|
|
9
|
-
} from "@codemcp/ade-core";
|
|
10
|
-
import { universalWriter } from "./universal.js";
|
|
11
|
-
|
|
12
|
-
function autonomyPolicy(profile: AutonomyProfile): PermissionPolicy {
|
|
13
|
-
switch (profile) {
|
|
14
|
-
case "rigid":
|
|
15
|
-
return {
|
|
16
|
-
profile,
|
|
17
|
-
capabilities: {
|
|
18
|
-
read: "ask",
|
|
19
|
-
edit_write: "ask",
|
|
20
|
-
search_list: "ask",
|
|
21
|
-
bash_safe: "ask",
|
|
22
|
-
bash_unsafe: "ask",
|
|
23
|
-
web: "ask",
|
|
24
|
-
task_agent: "ask"
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
case "sensible-defaults":
|
|
28
|
-
return {
|
|
29
|
-
profile,
|
|
30
|
-
capabilities: {
|
|
31
|
-
read: "allow",
|
|
32
|
-
edit_write: "allow",
|
|
33
|
-
search_list: "allow",
|
|
34
|
-
bash_safe: "allow",
|
|
35
|
-
bash_unsafe: "ask",
|
|
36
|
-
web: "ask",
|
|
37
|
-
task_agent: "allow"
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
case "max-autonomy":
|
|
41
|
-
return {
|
|
42
|
-
profile,
|
|
43
|
-
capabilities: {
|
|
44
|
-
read: "allow",
|
|
45
|
-
edit_write: "allow",
|
|
46
|
-
search_list: "allow",
|
|
47
|
-
bash_safe: "allow",
|
|
48
|
-
bash_unsafe: "allow",
|
|
49
|
-
web: "ask",
|
|
50
|
-
task_agent: "allow"
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
describe("universalWriter", () => {
|
|
57
|
-
let dir: string;
|
|
58
|
-
|
|
59
|
-
beforeEach(async () => {
|
|
60
|
-
dir = await mkdtemp(join(tmpdir(), "ade-harness-universal-"));
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
afterEach(async () => {
|
|
64
|
-
await rm(dir, { recursive: true, force: true });
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it("has correct metadata", () => {
|
|
68
|
-
expect(universalWriter.id).toBe("universal");
|
|
69
|
-
expect(universalWriter.label).toBe("Universal (AGENTS.md + .mcp.json)");
|
|
70
|
-
expect(universalWriter.description).toContain("AGENTS.md");
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("writes AGENTS.md instructions when provided", async () => {
|
|
74
|
-
const config: LogicalConfig = {
|
|
75
|
-
mcp_servers: [],
|
|
76
|
-
instructions: ["Follow the workflow.", "Keep changes focused."],
|
|
77
|
-
cli_actions: [],
|
|
78
|
-
knowledge_sources: [],
|
|
79
|
-
skills: [],
|
|
80
|
-
git_hooks: [],
|
|
81
|
-
setup_notes: []
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
await universalWriter.install(config, dir);
|
|
85
|
-
|
|
86
|
-
const content = await readFile(join(dir, "AGENTS.md"), "utf-8");
|
|
87
|
-
expect(content).toContain("# AGENTS");
|
|
88
|
-
expect(content).toContain("Follow the workflow.");
|
|
89
|
-
expect(content).toContain("Keep changes focused.");
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("documents autonomy as guidance only because Universal has no enforceable permission schema", async () => {
|
|
93
|
-
const config: LogicalConfig = {
|
|
94
|
-
mcp_servers: [
|
|
95
|
-
{
|
|
96
|
-
ref: "workflows",
|
|
97
|
-
command: "npx",
|
|
98
|
-
args: ["-y", "@codemcp/workflows"],
|
|
99
|
-
env: {},
|
|
100
|
-
allowedTools: ["whats_next"]
|
|
101
|
-
}
|
|
102
|
-
],
|
|
103
|
-
instructions: [],
|
|
104
|
-
cli_actions: [],
|
|
105
|
-
knowledge_sources: [],
|
|
106
|
-
skills: [],
|
|
107
|
-
git_hooks: [],
|
|
108
|
-
setup_notes: [],
|
|
109
|
-
permission_policy: autonomyPolicy("sensible-defaults")
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
await universalWriter.install(config, dir);
|
|
113
|
-
|
|
114
|
-
const agents = await readFile(join(dir, "AGENTS.md"), "utf-8");
|
|
115
|
-
expect(agents).toContain("## Autonomy");
|
|
116
|
-
expect(agents).toContain("documentation-only guidance");
|
|
117
|
-
expect(agents).toContain("no enforceable harness-level permission schema");
|
|
118
|
-
expect(agents).toContain("Profile: `sensible-defaults`");
|
|
119
|
-
expect(agents).toContain("- `read`: allow");
|
|
120
|
-
expect(agents).toContain("- `bash_unsafe`: ask");
|
|
121
|
-
expect(agents).toContain("- `web`: ask");
|
|
122
|
-
expect(agents).toContain(
|
|
123
|
-
"MCP permissions are not re-modeled by autonomy here"
|
|
124
|
-
);
|
|
125
|
-
|
|
126
|
-
const mcpRaw = await readFile(join(dir, ".mcp.json"), "utf-8");
|
|
127
|
-
const mcp = JSON.parse(mcpRaw);
|
|
128
|
-
expect(mcp.mcpServers.workflows).toEqual({
|
|
129
|
-
command: "npx",
|
|
130
|
-
args: ["-y", "@codemcp/workflows"]
|
|
131
|
-
});
|
|
132
|
-
expect(mcp.mcpServers.workflows).not.toHaveProperty("allowedTools");
|
|
133
|
-
});
|
|
134
|
-
});
|
package/src/writers/universal.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { writeFile } from "node:fs/promises";
|
|
3
|
-
import type {
|
|
4
|
-
AutonomyCapability,
|
|
5
|
-
LogicalConfig,
|
|
6
|
-
PermissionDecision
|
|
7
|
-
} from "@codemcp/ade-core";
|
|
8
|
-
import type { HarnessWriter } from "../types.js";
|
|
9
|
-
import { writeMcpServers, writeGitHooks } from "../util.js";
|
|
10
|
-
|
|
11
|
-
const CAPABILITY_ORDER: AutonomyCapability[] = [
|
|
12
|
-
"read",
|
|
13
|
-
"edit_write",
|
|
14
|
-
"search_list",
|
|
15
|
-
"bash_safe",
|
|
16
|
-
"bash_unsafe",
|
|
17
|
-
"web",
|
|
18
|
-
"task_agent"
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
function formatCapabilityGuidance(
|
|
22
|
-
capability: AutonomyCapability,
|
|
23
|
-
decision: PermissionDecision
|
|
24
|
-
): string {
|
|
25
|
-
return `- \`${capability}\`: ${decision}`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function renderAutonomyGuidance(config: LogicalConfig): string | undefined {
|
|
29
|
-
const policy = config.permission_policy;
|
|
30
|
-
if (!policy) {
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const capabilityLines = CAPABILITY_ORDER.map((capability) =>
|
|
35
|
-
formatCapabilityGuidance(capability, policy.capabilities[capability])
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
return [
|
|
39
|
-
"## Autonomy",
|
|
40
|
-
"",
|
|
41
|
-
"Universal harness limitation: `AGENTS.md` + `.mcp.json` provide documentation and server registration only; there is no enforceable harness-level permission schema here.",
|
|
42
|
-
"",
|
|
43
|
-
"Treat this autonomy profile as documentation-only guidance for built-in/basic operations.",
|
|
44
|
-
"",
|
|
45
|
-
`Profile: \`${policy.profile}\``,
|
|
46
|
-
"",
|
|
47
|
-
"Built-in/basic capability guidance:",
|
|
48
|
-
...capabilityLines,
|
|
49
|
-
"",
|
|
50
|
-
"MCP permissions are not re-modeled by autonomy here; any MCP approvals must come from provisioning-aware consuming harnesses rather than the Universal writer."
|
|
51
|
-
].join("\n");
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export const universalWriter: HarnessWriter = {
|
|
55
|
-
id: "universal",
|
|
56
|
-
label: "Universal (AGENTS.md + .mcp.json)",
|
|
57
|
-
description:
|
|
58
|
-
"Cross-tool standard — AGENTS.md + .mcp.json (portable instructions and MCP registration, not enforceable permissions)",
|
|
59
|
-
async install(config: LogicalConfig, projectRoot: string) {
|
|
60
|
-
const autonomyGuidance = renderAutonomyGuidance(config);
|
|
61
|
-
const instructionSections = [...config.instructions];
|
|
62
|
-
if (autonomyGuidance) {
|
|
63
|
-
instructionSections.push(autonomyGuidance);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (instructionSections.length > 0) {
|
|
67
|
-
const lines = [
|
|
68
|
-
"# AGENTS",
|
|
69
|
-
"",
|
|
70
|
-
...instructionSections.flatMap((instruction) => [instruction, ""])
|
|
71
|
-
];
|
|
72
|
-
await writeFile(
|
|
73
|
-
join(projectRoot, "AGENTS.md"),
|
|
74
|
-
lines.join("\n"),
|
|
75
|
-
"utf-8"
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
await writeMcpServers(config.mcp_servers, {
|
|
80
|
-
path: join(projectRoot, ".mcp.json")
|
|
81
|
-
});
|
|
82
|
-
await writeGitHooks(config.git_hooks, projectRoot);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { mkdtemp, rm, readFile } from "node:fs/promises";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import type { LogicalConfig } from "@codemcp/ade-core";
|
|
6
|
-
import { windsurfWriter } from "./windsurf.js";
|
|
7
|
-
|
|
8
|
-
describe("windsurfWriter", () => {
|
|
9
|
-
let dir: string;
|
|
10
|
-
|
|
11
|
-
beforeEach(async () => {
|
|
12
|
-
dir = await mkdtemp(join(tmpdir(), "ade-harness-windsurf-"));
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
afterEach(async () => {
|
|
16
|
-
await rm(dir, { recursive: true, force: true });
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it("has correct metadata", () => {
|
|
20
|
-
expect(windsurfWriter.id).toBe("windsurf");
|
|
21
|
-
expect(windsurfWriter.label).toBe("Windsurf");
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it("writes .windsurf/mcp.json with forwarded MCP approvals", async () => {
|
|
25
|
-
const config: LogicalConfig = {
|
|
26
|
-
mcp_servers: [
|
|
27
|
-
{
|
|
28
|
-
ref: "workflows",
|
|
29
|
-
command: "npx",
|
|
30
|
-
args: ["-y", "@codemcp/workflows"],
|
|
31
|
-
env: { API_KEY: "test" },
|
|
32
|
-
allowedTools: ["whats_next", "proceed_to_phase"]
|
|
33
|
-
}
|
|
34
|
-
],
|
|
35
|
-
instructions: [],
|
|
36
|
-
cli_actions: [],
|
|
37
|
-
knowledge_sources: [],
|
|
38
|
-
skills: [],
|
|
39
|
-
git_hooks: [],
|
|
40
|
-
setup_notes: []
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
await windsurfWriter.install(config, dir);
|
|
44
|
-
|
|
45
|
-
const raw = await readFile(join(dir, ".windsurf", "mcp.json"), "utf-8");
|
|
46
|
-
const parsed = JSON.parse(raw);
|
|
47
|
-
expect(parsed.mcpServers["workflows"]).toEqual({
|
|
48
|
-
command: "npx",
|
|
49
|
-
args: ["-y", "@codemcp/workflows"],
|
|
50
|
-
env: { API_KEY: "test" },
|
|
51
|
-
alwaysAllow: ["whats_next", "proceed_to_phase"]
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it("records autonomy as advisory guidance because Windsurf has no verified committed built-in permission schema", async () => {
|
|
56
|
-
const rigidRoot = join(dir, "rigid");
|
|
57
|
-
const sensibleRoot = join(dir, "sensible");
|
|
58
|
-
const maxRoot = join(dir, "max");
|
|
59
|
-
|
|
60
|
-
const rigidConfig: LogicalConfig = {
|
|
61
|
-
mcp_servers: [],
|
|
62
|
-
instructions: [],
|
|
63
|
-
cli_actions: [],
|
|
64
|
-
knowledge_sources: [],
|
|
65
|
-
skills: [],
|
|
66
|
-
git_hooks: [],
|
|
67
|
-
setup_notes: [],
|
|
68
|
-
permission_policy: autonomyPolicy("rigid")
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
const sensibleConfig: LogicalConfig = {
|
|
72
|
-
...rigidConfig,
|
|
73
|
-
permission_policy: autonomyPolicy("sensible-defaults")
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const maxConfig: LogicalConfig = {
|
|
77
|
-
...rigidConfig,
|
|
78
|
-
permission_policy: autonomyPolicy("max-autonomy")
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
await windsurfWriter.install(rigidConfig, rigidRoot);
|
|
82
|
-
await windsurfWriter.install(sensibleConfig, sensibleRoot);
|
|
83
|
-
await windsurfWriter.install(maxConfig, maxRoot);
|
|
84
|
-
|
|
85
|
-
const rigidRules = await readFile(
|
|
86
|
-
join(rigidRoot, ".windsurfrules"),
|
|
87
|
-
"utf-8"
|
|
88
|
-
);
|
|
89
|
-
const sensibleRules = await readFile(
|
|
90
|
-
join(sensibleRoot, ".windsurfrules"),
|
|
91
|
-
"utf-8"
|
|
92
|
-
);
|
|
93
|
-
const maxRules = await readFile(join(maxRoot, ".windsurfrules"), "utf-8");
|
|
94
|
-
|
|
95
|
-
expect(rigidRules).toContain("Windsurf limitation:");
|
|
96
|
-
expect(rigidRules).toContain("advisory only");
|
|
97
|
-
expect(rigidRules).toContain(
|
|
98
|
-
"Ask before: read files, edit and write files, search and list files, safe local shell commands, unsafe local shell commands, web and network access, task or agent delegation."
|
|
99
|
-
);
|
|
100
|
-
|
|
101
|
-
expect(sensibleRules).toContain("Windsurf limitation:");
|
|
102
|
-
expect(sensibleRules).toContain(
|
|
103
|
-
"May proceed without extra approval: read files, edit and write files, search and list files, safe local shell commands, task or agent delegation."
|
|
104
|
-
);
|
|
105
|
-
expect(sensibleRules).toContain(
|
|
106
|
-
"Ask before: unsafe local shell commands, web and network access."
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
expect(maxRules).toContain("Windsurf limitation:");
|
|
110
|
-
expect(maxRules).toContain(
|
|
111
|
-
"May proceed without extra approval: read files, edit and write files, search and list files, safe local shell commands, unsafe local shell commands, task or agent delegation."
|
|
112
|
-
);
|
|
113
|
-
expect(maxRules).toContain("Ask before: web and network access.");
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it("writes .windsurfrules with instructions", async () => {
|
|
117
|
-
const config: LogicalConfig = {
|
|
118
|
-
mcp_servers: [],
|
|
119
|
-
instructions: ["Follow TDD."],
|
|
120
|
-
cli_actions: [],
|
|
121
|
-
knowledge_sources: [],
|
|
122
|
-
skills: [],
|
|
123
|
-
git_hooks: [],
|
|
124
|
-
setup_notes: []
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
await windsurfWriter.install(config, dir);
|
|
128
|
-
|
|
129
|
-
const content = await readFile(join(dir, ".windsurfrules"), "utf-8");
|
|
130
|
-
expect(content).toContain("Follow TDD.");
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
function autonomyPolicy(
|
|
135
|
-
profile: "rigid" | "sensible-defaults" | "max-autonomy"
|
|
136
|
-
): LogicalConfig["permission_policy"] {
|
|
137
|
-
switch (profile) {
|
|
138
|
-
case "rigid":
|
|
139
|
-
return {
|
|
140
|
-
profile,
|
|
141
|
-
capabilities: {
|
|
142
|
-
read: "ask",
|
|
143
|
-
edit_write: "ask",
|
|
144
|
-
search_list: "ask",
|
|
145
|
-
bash_safe: "ask",
|
|
146
|
-
bash_unsafe: "ask",
|
|
147
|
-
web: "ask",
|
|
148
|
-
task_agent: "ask"
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
case "sensible-defaults":
|
|
152
|
-
return {
|
|
153
|
-
profile,
|
|
154
|
-
capabilities: {
|
|
155
|
-
read: "allow",
|
|
156
|
-
edit_write: "allow",
|
|
157
|
-
search_list: "allow",
|
|
158
|
-
bash_safe: "allow",
|
|
159
|
-
bash_unsafe: "ask",
|
|
160
|
-
web: "ask",
|
|
161
|
-
task_agent: "allow"
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
case "max-autonomy":
|
|
165
|
-
return {
|
|
166
|
-
profile,
|
|
167
|
-
capabilities: {
|
|
168
|
-
read: "allow",
|
|
169
|
-
edit_write: "allow",
|
|
170
|
-
search_list: "allow",
|
|
171
|
-
bash_safe: "allow",
|
|
172
|
-
bash_unsafe: "allow",
|
|
173
|
-
web: "ask",
|
|
174
|
-
task_agent: "allow"
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
}
|
package/src/writers/windsurf.ts
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import type { AutonomyCapability, LogicalConfig } from "@codemcp/ade-core";
|
|
3
|
-
import type { HarnessWriter } from "../types.js";
|
|
4
|
-
import {
|
|
5
|
-
writeMcpServers,
|
|
6
|
-
alwaysAllowEntry,
|
|
7
|
-
writeRulesFile,
|
|
8
|
-
writeGitHooks
|
|
9
|
-
} from "../util.js";
|
|
10
|
-
import { hasPermissionPolicy } from "../permission-policy.js";
|
|
11
|
-
|
|
12
|
-
export const windsurfWriter: HarnessWriter = {
|
|
13
|
-
id: "windsurf",
|
|
14
|
-
label: "Windsurf",
|
|
15
|
-
description: "Codeium's AI IDE — .windsurf/mcp.json + .windsurfrules",
|
|
16
|
-
async install(config: LogicalConfig, projectRoot: string) {
|
|
17
|
-
await writeMcpServers(config.mcp_servers, {
|
|
18
|
-
path: join(projectRoot, ".windsurf", "mcp.json"),
|
|
19
|
-
transform: alwaysAllowEntry
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
await writeRulesFile(
|
|
23
|
-
getWindsurfRules(config),
|
|
24
|
-
join(projectRoot, ".windsurfrules")
|
|
25
|
-
);
|
|
26
|
-
await writeGitHooks(config.git_hooks, projectRoot);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
function getWindsurfRules(config: LogicalConfig): string[] {
|
|
31
|
-
if (!hasPermissionPolicy(config)) {
|
|
32
|
-
return config.instructions;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const { capabilities } = config.permission_policy!;
|
|
36
|
-
const allow = listCapabilities(capabilities, "allow");
|
|
37
|
-
const ask = listCapabilities(capabilities, "ask");
|
|
38
|
-
const deny = listCapabilities(capabilities, "deny");
|
|
39
|
-
|
|
40
|
-
const autonomyGuidance = [
|
|
41
|
-
"Windsurf limitation: ADE could not verify a stable committed project-local permission schema for Windsurf built-in tools, so this autonomy policy is advisory only and should be applied conservatively.",
|
|
42
|
-
formatGuidance(allow, ask, deny)
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
return [...autonomyGuidance, ...config.instructions];
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function listCapabilities(
|
|
49
|
-
capabilities: NonNullable<LogicalConfig["permission_policy"]>["capabilities"],
|
|
50
|
-
decision: "ask" | "allow" | "deny"
|
|
51
|
-
): string[] {
|
|
52
|
-
return (Object.entries(capabilities) as Array<[AutonomyCapability, string]>)
|
|
53
|
-
.filter(([, value]) => value === decision)
|
|
54
|
-
.map(([capability]) => CAPABILITY_LABELS[capability]);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function formatGuidance(
|
|
58
|
-
allow: string[],
|
|
59
|
-
ask: string[],
|
|
60
|
-
deny: string[]
|
|
61
|
-
): string {
|
|
62
|
-
const lines = ["Autonomy guidance for Windsurf built-in capabilities:"];
|
|
63
|
-
|
|
64
|
-
if (allow.length > 0) {
|
|
65
|
-
lines.push(`- May proceed without extra approval: ${allow.join(", ")}.`);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (ask.length > 0) {
|
|
69
|
-
lines.push(`- Ask before: ${ask.join(", ")}.`);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (deny.length > 0) {
|
|
73
|
-
lines.push(
|
|
74
|
-
`- Do not use unless the user explicitly overrides: ${deny.join(", ")}.`
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return lines.join("\n");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const CAPABILITY_LABELS: Record<AutonomyCapability, string> = {
|
|
82
|
-
read: "read files",
|
|
83
|
-
edit_write: "edit and write files",
|
|
84
|
-
search_list: "search and list files",
|
|
85
|
-
bash_safe: "safe local shell commands",
|
|
86
|
-
bash_unsafe: "unsafe local shell commands",
|
|
87
|
-
web: "web and network access",
|
|
88
|
-
task_agent: "task or agent delegation"
|
|
89
|
-
};
|
package/tsconfig.build.json
DELETED