@codemcp/ade 0.2.5 → 0.3.0

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.
Files changed (45) hide show
  1. package/.agentskills/skills/conventional-commits/SKILL.md +36 -0
  2. package/.beads/issues.jsonl +6 -0
  3. package/.beads/last-touched +1 -1
  4. package/.kiro/agents/ade.json +9 -2
  5. package/.opencode/agents/ade.md +9 -18
  6. package/.vibe/beads-state-ade-fix-no-git-k396xs.json +34 -0
  7. package/.vibe/development-plan-fix-no-git.md +76 -0
  8. package/AGENTS.md +27 -0
  9. package/config.lock.yaml +33 -9
  10. package/config.yaml +3 -0
  11. package/package.json +1 -1
  12. package/packages/cli/dist/index.js +404 -343
  13. package/packages/cli/package.json +1 -1
  14. package/packages/cli/src/commands/conventions.integration.spec.ts +7 -1
  15. package/packages/cli/src/commands/install.ts +19 -1
  16. package/packages/cli/src/commands/setup.ts +19 -1
  17. package/packages/core/package.json +1 -1
  18. package/packages/core/src/catalog/catalog.spec.ts +1 -10
  19. package/packages/core/src/catalog/facets/autonomy.ts +4 -62
  20. package/packages/core/src/index.ts +1 -4
  21. package/packages/core/src/resolver.spec.ts +4 -22
  22. package/packages/core/src/resolver.ts +1 -5
  23. package/packages/core/src/types.ts +0 -20
  24. package/packages/harnesses/package.json +2 -1
  25. package/packages/harnesses/src/permission-policy.ts +1 -165
  26. package/packages/harnesses/src/util.spec.ts +97 -0
  27. package/packages/harnesses/src/util.ts +32 -4
  28. package/packages/harnesses/src/writers/claude-code.spec.ts +14 -46
  29. package/packages/harnesses/src/writers/claude-code.ts +33 -16
  30. package/packages/harnesses/src/writers/cline.spec.ts +1 -41
  31. package/packages/harnesses/src/writers/copilot.spec.ts +2 -42
  32. package/packages/harnesses/src/writers/copilot.ts +19 -32
  33. package/packages/harnesses/src/writers/cursor.spec.ts +1 -41
  34. package/packages/harnesses/src/writers/cursor.ts +28 -40
  35. package/packages/harnesses/src/writers/kiro.spec.ts +1 -41
  36. package/packages/harnesses/src/writers/kiro.ts +23 -24
  37. package/packages/harnesses/src/writers/opencode.spec.ts +5 -47
  38. package/packages/harnesses/src/writers/opencode.ts +153 -10
  39. package/packages/harnesses/src/writers/roo-code.spec.ts +2 -42
  40. package/packages/harnesses/src/writers/roo-code.ts +25 -10
  41. package/packages/harnesses/src/writers/universal.spec.ts +1 -41
  42. package/packages/harnesses/src/writers/universal.ts +45 -31
  43. package/packages/harnesses/src/writers/windsurf.spec.ts +5 -42
  44. package/packages/harnesses/src/writers/windsurf.ts +30 -47
  45. package/skills-lock.json +6 -1
@@ -11,47 +11,7 @@ import { parse as parseYaml } from "yaml";
11
11
  import { opencodeWriter } from "./opencode.js";
12
12
 
13
13
  function autonomyPolicy(profile: AutonomyProfile): PermissionPolicy {
14
- switch (profile) {
15
- case "rigid":
16
- return {
17
- profile,
18
- capabilities: {
19
- read: "ask",
20
- edit_write: "ask",
21
- search_list: "ask",
22
- bash_safe: "ask",
23
- bash_unsafe: "ask",
24
- web: "ask",
25
- task_agent: "ask"
26
- }
27
- };
28
- case "sensible-defaults":
29
- return {
30
- profile,
31
- capabilities: {
32
- read: "allow",
33
- edit_write: "allow",
34
- search_list: "allow",
35
- bash_safe: "allow",
36
- bash_unsafe: "ask",
37
- web: "ask",
38
- task_agent: "allow"
39
- }
40
- };
41
- case "max-autonomy":
42
- return {
43
- profile,
44
- capabilities: {
45
- read: "allow",
46
- edit_write: "allow",
47
- search_list: "allow",
48
- bash_safe: "allow",
49
- bash_unsafe: "allow",
50
- web: "ask",
51
- task_agent: "allow"
52
- }
53
- };
54
- }
14
+ return { profile };
55
15
  }
56
16
 
57
17
  describe("opencodeWriter", () => {
@@ -142,17 +102,16 @@ describe("opencodeWriter", () => {
142
102
  expect(defaultsAgent).toContain('grep: "allow"');
143
103
  expect(defaultsAgent).toContain('list: "allow"');
144
104
  expect(defaultsAgent).toContain('lsp: "allow"');
145
- expect(defaultsAgent).toContain('task: "allow"');
105
+ expect(defaultsAgent).toContain('task: "deny"');
146
106
  expect(defaultsAgent).toContain('skill: "deny"');
147
107
  expect(defaultsAgent).toContain('todoread: "deny"');
148
108
  expect(defaultsAgent).toContain('todowrite: "deny"');
149
109
  expect(defaultsAgent).toContain('webfetch: "ask"');
150
110
  expect(defaultsAgent).toContain('websearch: "ask"');
151
111
  expect(defaultsAgent).toContain('codesearch: "ask"');
152
- expect(defaultsAgent).toContain('external_directory: "deny"');
112
+ expect(defaultsAgent).toContain('external_directory: "ask"');
153
113
  expect(defaultsAgent).toContain('doom_loop: "deny"');
154
114
  expect(defaultsAgent).toContain('"grep *": "allow"');
155
- expect(defaultsAgent).toContain('"cp *": "ask"');
156
115
  expect(defaultsAgent).toContain('"rm *": "deny"');
157
116
  expect(defaultsFrontmatter.permission).toMatchObject({
158
117
  edit: "allow",
@@ -160,21 +119,20 @@ describe("opencodeWriter", () => {
160
119
  grep: "allow",
161
120
  list: "allow",
162
121
  lsp: "allow",
163
- task: "allow",
122
+ task: "deny",
164
123
  skill: "deny",
165
124
  todoread: "deny",
166
125
  todowrite: "deny",
167
126
  webfetch: "ask",
168
127
  websearch: "ask",
169
128
  codesearch: "ask",
170
- external_directory: "deny",
129
+ external_directory: "ask",
171
130
  doom_loop: "deny"
172
131
  });
173
132
  const defaultsPermission = defaultsFrontmatter.permission as {
174
133
  bash: Record<string, string>;
175
134
  };
176
135
  expect(defaultsPermission.bash["grep *"]).toBe("allow");
177
- expect(defaultsPermission.bash["cp *"]).toBe("ask");
178
136
  expect(defaultsPermission.bash["rm *"]).toBe("deny");
179
137
 
180
138
  expect(maxAgent).toContain('"*": "allow"');
@@ -1,8 +1,157 @@
1
1
  import { join } from "node:path";
2
- import type { LogicalConfig, PermissionRule } from "@codemcp/ade-core";
2
+ import type { AutonomyProfile, LogicalConfig } from "@codemcp/ade-core";
3
3
  import type { HarnessWriter } from "../types.js";
4
- import { writeAgentMd, writeGitHooks, writeMcpServers } from "../util.js";
5
- import { getHarnessPermissionRules } from "../permission-policy.js";
4
+ import {
5
+ writeAgentMd,
6
+ writeGitHooks,
7
+ writeMcpServers,
8
+ formatYamlKey
9
+ } from "../util.js";
10
+ import { getAutonomyProfile } from "../permission-policy.js";
11
+
12
+ type PermissionDecision = "ask" | "allow" | "deny";
13
+ type PermissionRule = PermissionDecision | Record<string, PermissionDecision>;
14
+
15
+ const APPLICABLE_TO_ALL: Record<string, PermissionRule> = {
16
+ read: {
17
+ "*": "allow",
18
+ "*.env": "deny",
19
+ "*.env.*": "deny",
20
+ "*.env.example": "allow"
21
+ },
22
+ skill: "deny", //we're using an own skills-mcp
23
+ todoread: "deny", //no agent-proprieatry todo tools
24
+ todowrite: "deny",
25
+ task: "deny",
26
+ lsp: "allow",
27
+ glob: "allow",
28
+ grep: "allow",
29
+ list: "allow",
30
+ external_directory: "ask"
31
+ };
32
+
33
+ const RIGID_RULES: Record<string, PermissionRule> = {
34
+ ...APPLICABLE_TO_ALL,
35
+ "*": "ask",
36
+ webfetch: "ask",
37
+ websearch: "ask",
38
+ codesearch: "ask",
39
+ external_directory: "deny",
40
+ doom_loop: "deny"
41
+ };
42
+
43
+ const SENSIBLE_DEFAULTS_RULES: Record<string, PermissionRule> = {
44
+ ...APPLICABLE_TO_ALL,
45
+ edit: "allow",
46
+ webfetch: "ask",
47
+ websearch: "ask",
48
+ codesearch: "ask",
49
+ bash: {
50
+ "*": "ask",
51
+ "grep *": "allow",
52
+ "rg *": "allow",
53
+ "find *": "allow",
54
+ "fd *": "allow",
55
+ "ls *": "allow",
56
+ "cat *": "allow",
57
+ "head *": "allow",
58
+ "tail *": "allow",
59
+ "wc *": "allow",
60
+ "sort *": "allow",
61
+ "uniq *": "allow",
62
+ "diff *": "allow",
63
+ "echo *": "allow",
64
+ "printf *": "allow",
65
+ pwd: "allow",
66
+ "which *": "allow",
67
+ "type *": "allow",
68
+ whoami: "allow",
69
+ date: "allow",
70
+ "date *": "allow",
71
+ env: "allow",
72
+ "tree *": "allow",
73
+ "file *": "allow",
74
+ "stat *": "allow",
75
+ "readlink *": "allow",
76
+ "realpath *": "allow",
77
+ "dirname *": "allow",
78
+ "basename *": "allow",
79
+ "sed *": "allow",
80
+ "awk *": "allow",
81
+ "cut *": "allow",
82
+ "tr *": "allow",
83
+ "tee *": "allow",
84
+ "xargs *": "allow",
85
+ "jq *": "allow",
86
+ "yq *": "allow",
87
+ "mkdir *": "allow",
88
+ "touch *": "allow",
89
+ "kill *": "ask",
90
+ "rm *": "deny",
91
+ "rmdir *": "deny",
92
+ "curl *": "deny",
93
+ "wget *": "deny",
94
+ "chmod *": "deny",
95
+ "chown *": "deny",
96
+ "sudo *": "deny",
97
+ "su *": "deny",
98
+ "sh *": "deny",
99
+ "bash *": "deny",
100
+ "zsh *": "deny",
101
+ "eval *": "deny",
102
+ "exec *": "deny",
103
+ "source *": "deny",
104
+ ". *": "deny",
105
+ "nohup *": "deny",
106
+ "dd *": "deny",
107
+ "mkfs *": "deny",
108
+ "mount *": "deny",
109
+ "umount *": "deny",
110
+ "killall *": "deny",
111
+ "pkill *": "deny",
112
+ "nc *": "deny",
113
+ "ncat *": "deny",
114
+ "ssh *": "deny",
115
+ "scp *": "deny",
116
+ "rsync *": "deny",
117
+ "docker *": "deny",
118
+ "kubectl *": "deny",
119
+ "systemctl *": "deny",
120
+ "service *": "deny",
121
+ "crontab *": "deny",
122
+ reboot: "deny",
123
+ "shutdown *": "deny",
124
+ "passwd *": "deny",
125
+ "useradd *": "deny",
126
+ "userdel *": "deny",
127
+ "iptables *": "deny"
128
+ },
129
+ doom_loop: "deny"
130
+ };
131
+
132
+ const MAX_AUTONOMY_RULES: Record<string, PermissionRule> = {
133
+ ...APPLICABLE_TO_ALL,
134
+ "*": "allow",
135
+ webfetch: "ask",
136
+ websearch: "ask",
137
+ codesearch: "ask",
138
+ doom_loop: "deny"
139
+ };
140
+
141
+ function getPermissionRules(
142
+ profile: AutonomyProfile | undefined
143
+ ): Record<string, PermissionRule> | undefined {
144
+ switch (profile) {
145
+ case "rigid":
146
+ return RIGID_RULES;
147
+ case "sensible-defaults":
148
+ return SENSIBLE_DEFAULTS_RULES;
149
+ case "max-autonomy":
150
+ return MAX_AUTONOMY_RULES;
151
+ default:
152
+ return undefined;
153
+ }
154
+ }
6
155
 
7
156
  export const opencodeWriter: HarnessWriter = {
8
157
  id: "opencode",
@@ -20,7 +169,7 @@ export const opencodeWriter: HarnessWriter = {
20
169
  defaults: { $schema: "https://opencode.ai/config.json" }
21
170
  });
22
171
 
23
- const permission = getHarnessPermissionRules(config);
172
+ const permission = getPermissionRules(getAutonomyProfile(config));
24
173
 
25
174
  await writeAgentMd(config, {
26
175
  path: join(projectRoot, ".opencode", "agents", "ade.md"),
@@ -59,9 +208,3 @@ function renderYamlMapping(
59
208
 
60
209
  return lines;
61
210
  }
62
-
63
- function formatYamlKey(value: string): string {
64
- return /^[A-Za-z_][A-Za-z0-9_-]*$/.test(value)
65
- ? value
66
- : JSON.stringify(value);
67
- }
@@ -10,47 +10,7 @@ import type {
10
10
  import { rooCodeWriter } from "./roo-code.js";
11
11
 
12
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
- }
13
+ return { profile };
54
14
  }
55
15
 
56
16
  describe("rooCodeWriter", () => {
@@ -174,7 +134,7 @@ describe("rooCodeWriter", () => {
174
134
  await readFile(join(rigidRoot, ".roo", "mcp.json"), "utf-8")
175
135
  );
176
136
 
177
- expect(rigidModes.customModes.ade.groups).toEqual(["mcp"]);
137
+ expect(rigidModes.customModes.ade.groups).toEqual(["read", "mcp"]);
178
138
  expect(defaultsModes.customModes.ade.groups).toEqual([
179
139
  "read",
180
140
  "edit",
@@ -1,5 +1,5 @@
1
1
  import { join } from "node:path";
2
- import type { LogicalConfig } from "@codemcp/ade-core";
2
+ import type { AutonomyProfile, LogicalConfig } from "@codemcp/ade-core";
3
3
  import type { HarnessWriter } from "../types.js";
4
4
  import {
5
5
  readJsonOrEmpty,
@@ -9,7 +9,10 @@ import {
9
9
  writeGitHooks,
10
10
  writeJson
11
11
  } from "../util.js";
12
- import { allowsCapability, hasPermissionPolicy } from "../permission-policy.js";
12
+ import {
13
+ getAutonomyProfile,
14
+ hasPermissionPolicy
15
+ } from "../permission-policy.js";
13
16
 
14
17
  export const rooCodeWriter: HarnessWriter = {
15
18
  id: "roo-code",
@@ -48,7 +51,10 @@ async function writeRooModes(
48
51
  name: "ADE",
49
52
  roleDefinition:
50
53
  "ADE — Agentic Development Environment mode generated by ADE.",
51
- groups: getRooModeGroups(config),
54
+ groups: getRooModeGroups(
55
+ getAutonomyProfile(config),
56
+ config.mcp_servers.length > 0
57
+ ),
52
58
  source: "project"
53
59
  }
54
60
  }
@@ -61,11 +67,20 @@ function asRecord(value: unknown): Record<string, unknown> {
61
67
  : {};
62
68
  }
63
69
 
64
- function getRooModeGroups(config: LogicalConfig): string[] {
65
- return [
66
- ...(allowsCapability(config, "read") ? ["read"] : []),
67
- ...(allowsCapability(config, "edit_write") ? ["edit"] : []),
68
- ...(allowsCapability(config, "bash_unsafe") ? ["command"] : []),
69
- ...(config.mcp_servers.length > 0 ? ["mcp"] : [])
70
- ];
70
+ function getRooModeGroups(
71
+ profile: AutonomyProfile | undefined,
72
+ hasMcpServers: boolean
73
+ ): string[] {
74
+ const mcpGroup = hasMcpServers ? ["mcp"] : [];
75
+
76
+ switch (profile) {
77
+ case "rigid":
78
+ return ["read", ...mcpGroup];
79
+ case "sensible-defaults":
80
+ return ["read", "edit", ...mcpGroup];
81
+ case "max-autonomy":
82
+ return ["read", "edit", "command", ...mcpGroup];
83
+ default:
84
+ return ["read", "edit", "command", ...mcpGroup];
85
+ }
71
86
  }
@@ -10,47 +10,7 @@ import type {
10
10
  import { universalWriter } from "./universal.js";
11
11
 
12
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
- }
13
+ return { profile };
54
14
  }
55
15
 
56
16
  describe("universalWriter", () => {
@@ -1,40 +1,16 @@
1
1
  import { join } from "node:path";
2
2
  import { writeFile } from "node:fs/promises";
3
- import type {
4
- AutonomyCapability,
5
- LogicalConfig,
6
- PermissionDecision
7
- } from "@codemcp/ade-core";
3
+ import type { AutonomyProfile, LogicalConfig } from "@codemcp/ade-core";
8
4
  import type { HarnessWriter } from "../types.js";
9
5
  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
- }
6
+ import { getAutonomyProfile } from "../permission-policy.js";
27
7
 
28
8
  function renderAutonomyGuidance(config: LogicalConfig): string | undefined {
29
- const policy = config.permission_policy;
30
- if (!policy) {
9
+ const profile = getAutonomyProfile(config);
10
+ if (!profile) {
31
11
  return undefined;
32
12
  }
33
13
 
34
- const capabilityLines = CAPABILITY_ORDER.map((capability) =>
35
- formatCapabilityGuidance(capability, policy.capabilities[capability])
36
- );
37
-
38
14
  return [
39
15
  "## Autonomy",
40
16
  "",
@@ -42,15 +18,53 @@ function renderAutonomyGuidance(config: LogicalConfig): string | undefined {
42
18
  "",
43
19
  "Treat this autonomy profile as documentation-only guidance for built-in/basic operations.",
44
20
  "",
45
- `Profile: \`${policy.profile}\``,
21
+ `Profile: \`${profile}\``,
46
22
  "",
47
- "Built-in/basic capability guidance:",
48
- ...capabilityLines,
23
+ ...getUniversalProfileGuidance(profile),
49
24
  "",
50
25
  "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
26
  ].join("\n");
52
27
  }
53
28
 
29
+ function getUniversalProfileGuidance(profile: AutonomyProfile): string[] {
30
+ const header = "Built-in/basic capability guidance:";
31
+ switch (profile) {
32
+ case "rigid":
33
+ return [
34
+ header,
35
+ "- `read`: allow",
36
+ "- `edit_write`: ask",
37
+ "- `search_list`: ask",
38
+ "- `bash_safe`: ask",
39
+ "- `bash_unsafe`: ask",
40
+ "- `web`: ask",
41
+ "- `task_agent`: ask"
42
+ ];
43
+ case "sensible-defaults":
44
+ return [
45
+ header,
46
+ "- `read`: allow",
47
+ "- `edit_write`: allow",
48
+ "- `search_list`: allow",
49
+ "- `bash_safe`: allow",
50
+ "- `bash_unsafe`: ask",
51
+ "- `web`: ask",
52
+ "- `task_agent`: allow"
53
+ ];
54
+ case "max-autonomy":
55
+ return [
56
+ header,
57
+ "- `read`: allow",
58
+ "- `edit_write`: allow",
59
+ "- `search_list`: allow",
60
+ "- `bash_safe`: allow",
61
+ "- `bash_unsafe`: allow",
62
+ "- `web`: ask",
63
+ "- `task_agent`: allow"
64
+ ];
65
+ }
66
+ }
67
+
54
68
  export const universalWriter: HarnessWriter = {
55
69
  id: "universal",
56
70
  label: "Universal (AGENTS.md + .mcp.json)",
@@ -95,7 +95,10 @@ describe("windsurfWriter", () => {
95
95
  expect(rigidRules).toContain("Windsurf limitation:");
96
96
  expect(rigidRules).toContain("advisory only");
97
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."
98
+ "May proceed without extra approval: read files."
99
+ );
100
+ expect(rigidRules).toContain(
101
+ "Ask before: 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
102
  );
100
103
 
101
104
  expect(sensibleRules).toContain("Windsurf limitation:");
@@ -134,45 +137,5 @@ describe("windsurfWriter", () => {
134
137
  function autonomyPolicy(
135
138
  profile: "rigid" | "sensible-defaults" | "max-autonomy"
136
139
  ): 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
- }
140
+ return { profile };
178
141
  }