@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
@@ -11222,6 +11222,23 @@ var B = class {
11222
11222
  }
11223
11223
  }
11224
11224
  };
11225
+ var kt = class extends B {
11226
+ get cursor() {
11227
+ return this.value ? 0 : 1;
11228
+ }
11229
+ get _value() {
11230
+ return this.cursor === 0;
11231
+ }
11232
+ constructor(e) {
11233
+ super(e, false), this.value = !!e.initialValue, this.on("userInput", () => {
11234
+ this.value = this._value;
11235
+ }), this.on("confirm", (s) => {
11236
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s, this.state = "submit", this.close();
11237
+ }), this.on("cursor", () => {
11238
+ this.value = !this.value;
11239
+ });
11240
+ }
11241
+ };
11225
11242
  var Lt = class extends B {
11226
11243
  options;
11227
11244
  cursor = 0;
@@ -11556,6 +11573,33 @@ var X2 = ({ cursor: e, options: r2, style: s, output: i = process.stdout, maxIte
11556
11573
  for (const A3 of d3) for (const b of A3) C2.push(b);
11557
11574
  return $2 && C2.push(c), C2;
11558
11575
  };
11576
+ var Rt = (e) => {
11577
+ const r2 = e.active ?? "Yes", s = e.inactive ?? "No";
11578
+ return new kt({ active: r2, inactive: s, signal: e.signal, input: e.input, output: e.output, initialValue: e.initialValue ?? true, render() {
11579
+ const i = e.withGuide ?? _.withGuide, a = `${i ? `${t("gray", h)}
11580
+ ` : ""}${W2(this.state)} ${e.message}
11581
+ `, o2 = this.value ? r2 : s;
11582
+ switch (this.state) {
11583
+ case "submit": {
11584
+ const u2 = i ? `${t("gray", h)} ` : "";
11585
+ return `${a}${u2}${t("dim", o2)}`;
11586
+ }
11587
+ case "cancel": {
11588
+ const u2 = i ? `${t("gray", h)} ` : "";
11589
+ return `${a}${u2}${t(["strikethrough", "dim"], o2)}${i ? `
11590
+ ${t("gray", h)}` : ""}`;
11591
+ }
11592
+ default: {
11593
+ const u2 = i ? `${t("cyan", h)} ` : "", l = i ? t("cyan", x2) : "";
11594
+ return `${a}${u2}${this.value ? `${t("green", z2)} ${r2}` : `${t("dim", H2)} ${t("dim", r2)}`}${e.vertical ? i ? `
11595
+ ${t("cyan", h)} ` : `
11596
+ ` : ` ${t("dim", "/")} `}${this.value ? `${t("dim", H2)} ${t("dim", s)}` : `${t("green", z2)} ${s}`}
11597
+ ${l}
11598
+ `;
11599
+ }
11600
+ }
11601
+ } }).prompt();
11602
+ };
11559
11603
  var R2 = { message: (e = [], { symbol: r2 = t("gray", h), secondarySymbol: s = t("gray", h), output: i = process.stdout, spacing: a = 1, withGuide: o2 } = {}) => {
11560
11604
  const u2 = [], l = o2 ?? _.withGuide, n = l ? s : "", c = l ? `${r2} ` : "", p2 = l ? `${s} ` : "";
11561
11605
  for (let g2 = 0; g2 < a; g2++) u2.push(n);
@@ -12595,49 +12639,6 @@ var backpressureFacet = {
12595
12639
  };
12596
12640
 
12597
12641
  // ../core/dist/catalog/facets/autonomy.js
12598
- var ALL_CAPABILITIES = [
12599
- "read",
12600
- "edit_write",
12601
- "search_list",
12602
- "bash_safe",
12603
- "bash_unsafe",
12604
- "web",
12605
- "task_agent"
12606
- ];
12607
- function capabilityMap(defaultDecision, overrides = {}) {
12608
- return Object.fromEntries(ALL_CAPABILITIES.map((capability) => [
12609
- capability,
12610
- overrides[capability] ?? defaultDecision
12611
- ]));
12612
- }
12613
- function autonomyPolicy(profile) {
12614
- switch (profile) {
12615
- case "rigid":
12616
- return {
12617
- profile,
12618
- capabilities: capabilityMap("ask")
12619
- };
12620
- case "sensible-defaults":
12621
- return {
12622
- profile,
12623
- capabilities: capabilityMap("ask", {
12624
- read: "allow",
12625
- edit_write: "allow",
12626
- search_list: "allow",
12627
- bash_safe: "allow",
12628
- task_agent: "allow",
12629
- web: "ask"
12630
- })
12631
- };
12632
- case "max-autonomy":
12633
- return {
12634
- profile,
12635
- capabilities: capabilityMap("allow", {
12636
- web: "ask"
12637
- })
12638
- };
12639
- }
12640
- }
12641
12642
  var autonomyFacet = {
12642
12643
  id: "autonomy",
12643
12644
  label: "Autonomy",
@@ -12652,7 +12653,7 @@ var autonomyFacet = {
12652
12653
  recipe: [
12653
12654
  {
12654
12655
  writer: "permission-policy",
12655
- config: autonomyPolicy("rigid")
12656
+ config: { profile: "rigid" }
12656
12657
  }
12657
12658
  ]
12658
12659
  },
@@ -12663,7 +12664,7 @@ var autonomyFacet = {
12663
12664
  recipe: [
12664
12665
  {
12665
12666
  writer: "permission-policy",
12666
- config: autonomyPolicy("sensible-defaults")
12667
+ config: { profile: "sensible-defaults" }
12667
12668
  }
12668
12669
  ]
12669
12670
  },
@@ -12674,7 +12675,7 @@ var autonomyFacet = {
12674
12675
  recipe: [
12675
12676
  {
12676
12677
  writer: "permission-policy",
12677
- config: autonomyPolicy("max-autonomy")
12678
+ config: { profile: "max-autonomy" }
12678
12679
  }
12679
12680
  ]
12680
12681
  }
@@ -12874,11 +12875,7 @@ function mergePermissionPolicy(existing, incoming) {
12874
12875
  }
12875
12876
  return {
12876
12877
  ...existing,
12877
- ...incoming,
12878
- capabilities: {
12879
- ...existing.capabilities,
12880
- ...incoming.capabilities
12881
- }
12878
+ ...incoming
12882
12879
  };
12883
12880
  }
12884
12881
  function collectDocsets(choices, catalog) {
@@ -21871,7 +21868,7 @@ async function installSkills(skills, projectRoot) {
21871
21868
  }
21872
21869
 
21873
21870
  // ../harnesses/dist/util.js
21874
- import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
21871
+ import { access as access2, mkdir as mkdir3, readFile as readFile5, writeFile as writeFile4 } from "fs/promises";
21875
21872
  import { dirname as dirname5, join as join9 } from "path";
21876
21873
  async function readJsonOrEmpty(path2) {
21877
21874
  try {
@@ -21938,10 +21935,19 @@ async function writeAgentMd(config, opts) {
21938
21935
  await writeFile4(opts.path, content, "utf-8");
21939
21936
  }
21940
21937
  async function writeGitHooks(hooks, projectRoot) {
21941
- if (!hooks)
21938
+ if (!hooks || hooks.length === 0)
21939
+ return;
21940
+ const gitDir = join9(projectRoot, ".git");
21941
+ try {
21942
+ await access2(gitDir);
21943
+ } catch {
21944
+ R2.warn("Git hooks were configured but could not be installed: the project is not a git repository.\nRun `git init` and re-run setup to install the hooks.");
21942
21945
  return;
21946
+ }
21947
+ const hooksDir = join9(gitDir, "hooks");
21948
+ await mkdir3(hooksDir, { recursive: true });
21943
21949
  for (const hook of hooks) {
21944
- const hookPath = join9(projectRoot, ".git", "hooks", hook.phase);
21950
+ const hookPath = join9(hooksDir, hook.phase);
21945
21951
  await writeFile4(hookPath, hook.script, { mode: 493 });
21946
21952
  }
21947
21953
  }
@@ -21975,28 +21981,28 @@ ${skill.body}
21975
21981
  }
21976
21982
  return modified;
21977
21983
  }
21984
+ function formatYamlKey(value) {
21985
+ return /^[A-Za-z_][A-Za-z0-9_-]*$/.test(value) ? value : JSON.stringify(value);
21986
+ }
21978
21987
 
21979
21988
  // ../harnesses/dist/writers/universal.js
21980
21989
  import { join as join10 } from "path";
21981
21990
  import { writeFile as writeFile5 } from "fs/promises";
21982
- var CAPABILITY_ORDER = [
21983
- "read",
21984
- "edit_write",
21985
- "search_list",
21986
- "bash_safe",
21987
- "bash_unsafe",
21988
- "web",
21989
- "task_agent"
21990
- ];
21991
- function formatCapabilityGuidance(capability, decision) {
21992
- return `- \`${capability}\`: ${decision}`;
21991
+
21992
+ // ../harnesses/dist/permission-policy.js
21993
+ function getAutonomyProfile(config) {
21994
+ return config.permission_policy?.profile;
21993
21995
  }
21996
+ function hasPermissionPolicy(config) {
21997
+ return config.permission_policy !== void 0;
21998
+ }
21999
+
22000
+ // ../harnesses/dist/writers/universal.js
21994
22001
  function renderAutonomyGuidance(config) {
21995
- const policy = config.permission_policy;
21996
- if (!policy) {
22002
+ const profile = getAutonomyProfile(config);
22003
+ if (!profile) {
21997
22004
  return void 0;
21998
22005
  }
21999
- const capabilityLines = CAPABILITY_ORDER.map((capability) => formatCapabilityGuidance(capability, policy.capabilities[capability]));
22000
22006
  return [
22001
22007
  "## Autonomy",
22002
22008
  "",
@@ -22004,14 +22010,51 @@ function renderAutonomyGuidance(config) {
22004
22010
  "",
22005
22011
  "Treat this autonomy profile as documentation-only guidance for built-in/basic operations.",
22006
22012
  "",
22007
- `Profile: \`${policy.profile}\``,
22013
+ `Profile: \`${profile}\``,
22008
22014
  "",
22009
- "Built-in/basic capability guidance:",
22010
- ...capabilityLines,
22015
+ ...getUniversalProfileGuidance(profile),
22011
22016
  "",
22012
22017
  "MCP permissions are not re-modeled by autonomy here; any MCP approvals must come from provisioning-aware consuming harnesses rather than the Universal writer."
22013
22018
  ].join("\n");
22014
22019
  }
22020
+ function getUniversalProfileGuidance(profile) {
22021
+ const header = "Built-in/basic capability guidance:";
22022
+ switch (profile) {
22023
+ case "rigid":
22024
+ return [
22025
+ header,
22026
+ "- `read`: allow",
22027
+ "- `edit_write`: ask",
22028
+ "- `search_list`: ask",
22029
+ "- `bash_safe`: ask",
22030
+ "- `bash_unsafe`: ask",
22031
+ "- `web`: ask",
22032
+ "- `task_agent`: ask"
22033
+ ];
22034
+ case "sensible-defaults":
22035
+ return [
22036
+ header,
22037
+ "- `read`: allow",
22038
+ "- `edit_write`: allow",
22039
+ "- `search_list`: allow",
22040
+ "- `bash_safe`: allow",
22041
+ "- `bash_unsafe`: ask",
22042
+ "- `web`: ask",
22043
+ "- `task_agent`: allow"
22044
+ ];
22045
+ case "max-autonomy":
22046
+ return [
22047
+ header,
22048
+ "- `read`: allow",
22049
+ "- `edit_write`: allow",
22050
+ "- `search_list`: allow",
22051
+ "- `bash_safe`: allow",
22052
+ "- `bash_unsafe`: allow",
22053
+ "- `web`: ask",
22054
+ "- `task_agent`: allow"
22055
+ ];
22056
+ }
22057
+ }
22015
22058
  var universalWriter = {
22016
22059
  id: "universal",
22017
22060
  label: "Universal (AGENTS.md + .mcp.json)",
@@ -22039,162 +22082,6 @@ var universalWriter = {
22039
22082
 
22040
22083
  // ../harnesses/dist/writers/claude-code.js
22041
22084
  import { join as join11 } from "path";
22042
-
22043
- // ../harnesses/dist/permission-policy.js
22044
- var SENSIBLE_DEFAULTS_RULES = {
22045
- read: {
22046
- "*": "allow",
22047
- "*.env": "deny",
22048
- "*.env.*": "deny",
22049
- "*.env.example": "allow"
22050
- },
22051
- edit: "allow",
22052
- glob: "allow",
22053
- grep: "allow",
22054
- list: "allow",
22055
- lsp: "allow",
22056
- task: "allow",
22057
- todoread: "deny",
22058
- todowrite: "deny",
22059
- skill: "deny",
22060
- webfetch: "ask",
22061
- websearch: "ask",
22062
- codesearch: "ask",
22063
- bash: {
22064
- "*": "deny",
22065
- "grep *": "allow",
22066
- "rg *": "allow",
22067
- "find *": "allow",
22068
- "fd *": "allow",
22069
- ls: "allow",
22070
- "ls *": "allow",
22071
- "cat *": "allow",
22072
- "head *": "allow",
22073
- "tail *": "allow",
22074
- "wc *": "allow",
22075
- "sort *": "allow",
22076
- "uniq *": "allow",
22077
- "diff *": "allow",
22078
- "echo *": "allow",
22079
- "printf *": "allow",
22080
- pwd: "allow",
22081
- "which *": "allow",
22082
- "type *": "allow",
22083
- whoami: "allow",
22084
- date: "allow",
22085
- "date *": "allow",
22086
- env: "allow",
22087
- "tree *": "allow",
22088
- "file *": "allow",
22089
- "stat *": "allow",
22090
- "readlink *": "allow",
22091
- "realpath *": "allow",
22092
- "dirname *": "allow",
22093
- "basename *": "allow",
22094
- "sed *": "allow",
22095
- "awk *": "allow",
22096
- "cut *": "allow",
22097
- "tr *": "allow",
22098
- "tee *": "allow",
22099
- "xargs *": "allow",
22100
- "jq *": "allow",
22101
- "yq *": "allow",
22102
- "mkdir *": "allow",
22103
- "touch *": "allow",
22104
- "cp *": "ask",
22105
- "mv *": "ask",
22106
- "ln *": "ask",
22107
- "npm *": "ask",
22108
- "node *": "ask",
22109
- "pip *": "ask",
22110
- "python *": "ask",
22111
- "python3 *": "ask",
22112
- "rm *": "deny",
22113
- "rmdir *": "deny",
22114
- "curl *": "deny",
22115
- "wget *": "deny",
22116
- "chmod *": "deny",
22117
- "chown *": "deny",
22118
- "sudo *": "deny",
22119
- "su *": "deny",
22120
- "sh *": "deny",
22121
- "bash *": "deny",
22122
- "zsh *": "deny",
22123
- "eval *": "deny",
22124
- "exec *": "deny",
22125
- "source *": "deny",
22126
- ". *": "deny",
22127
- "nohup *": "deny",
22128
- "dd *": "deny",
22129
- "mkfs *": "deny",
22130
- "mount *": "deny",
22131
- "umount *": "deny",
22132
- "kill *": "deny",
22133
- "killall *": "deny",
22134
- "pkill *": "deny",
22135
- "nc *": "deny",
22136
- "ncat *": "deny",
22137
- "ssh *": "deny",
22138
- "scp *": "deny",
22139
- "rsync *": "deny",
22140
- "docker *": "deny",
22141
- "kubectl *": "deny",
22142
- "systemctl *": "deny",
22143
- "service *": "deny",
22144
- "crontab *": "deny",
22145
- reboot: "deny",
22146
- "shutdown *": "deny",
22147
- "passwd *": "deny",
22148
- "useradd *": "deny",
22149
- "userdel *": "deny",
22150
- "iptables *": "deny"
22151
- },
22152
- external_directory: "deny",
22153
- doom_loop: "deny"
22154
- };
22155
- function getAutonomyProfile(config) {
22156
- return config.permission_policy?.profile;
22157
- }
22158
- function hasPermissionPolicy(config) {
22159
- return config.permission_policy !== void 0;
22160
- }
22161
- function getCapabilityDecision(config, capability) {
22162
- return config.permission_policy?.capabilities?.[capability];
22163
- }
22164
- function allowsCapability(config, capability) {
22165
- return getCapabilityDecision(config, capability) === "allow";
22166
- }
22167
- function keepsWebOnAsk(config) {
22168
- return getCapabilityDecision(config, "web") === "ask";
22169
- }
22170
- function getHarnessPermissionRules(config) {
22171
- switch (config.permission_policy?.profile) {
22172
- case "rigid":
22173
- return {
22174
- "*": "ask",
22175
- webfetch: "ask",
22176
- websearch: "ask",
22177
- codesearch: "ask",
22178
- external_directory: "deny",
22179
- doom_loop: "deny"
22180
- };
22181
- case "sensible-defaults":
22182
- return SENSIBLE_DEFAULTS_RULES;
22183
- case "max-autonomy":
22184
- return {
22185
- "*": "allow",
22186
- webfetch: "ask",
22187
- websearch: "ask",
22188
- codesearch: "ask",
22189
- external_directory: "deny",
22190
- doom_loop: "deny"
22191
- };
22192
- default:
22193
- return void 0;
22194
- }
22195
- }
22196
-
22197
- // ../harnesses/dist/writers/claude-code.js
22198
22085
  var claudeCodeWriter = {
22199
22086
  id: "claude-code",
22200
22087
  label: "Claude Code",
@@ -22217,7 +22104,7 @@ async function writeClaudeSettings(config, projectRoot) {
22217
22104
  const existingPerms = existing.permissions ?? {};
22218
22105
  const existingAllow = asStringArray2(existingPerms.allow);
22219
22106
  const existingAsk = asStringArray2(existingPerms.ask);
22220
- const autonomyRules = getClaudeAutonomyRules(config);
22107
+ const autonomyRules = getClaudeAutonomyRules(getAutonomyProfile(config));
22221
22108
  const mcpRules = getClaudeMcpAllowRules(config);
22222
22109
  const allowRules = [
22223
22110
  .../* @__PURE__ */ new Set([...existingAllow, ...autonomyRules.allow, ...mcpRules])
@@ -22243,6 +22130,7 @@ function getClaudeMcpAllowRules(config) {
22243
22130
  for (const server of config.mcp_servers) {
22244
22131
  const allowedTools = server.allowedTools;
22245
22132
  if (!allowedTools || allowedTools.includes("*")) {
22133
+ allowRules.push(`mcp__${server.ref}__*`);
22246
22134
  continue;
22247
22135
  }
22248
22136
  for (const tool of allowedTools) {
@@ -22251,41 +22139,40 @@ function getClaudeMcpAllowRules(config) {
22251
22139
  }
22252
22140
  return allowRules;
22253
22141
  }
22254
- function getClaudeAutonomyRules(config) {
22255
- const ask = keepsWebOnAsk(config) ? ["WebFetch", "WebSearch"] : [];
22256
- return {
22257
- allow: [
22258
- ...allowsCapability(config, "read") ? ["Read"] : [],
22259
- ...allowsCapability(config, "edit_write") ? ["Edit"] : [],
22260
- ...allowsCapability(config, "search_list") ? ["Glob", "Grep"] : [],
22261
- ...allowsCapability(config, "bash_unsafe") ? ["Bash"] : [],
22262
- ...allowsCapability(config, "task_agent") ? ["TodoWrite"] : []
22263
- ],
22264
- ask
22265
- };
22142
+ function getClaudeAutonomyRules(profile) {
22143
+ switch (profile) {
22144
+ case "rigid":
22145
+ return {
22146
+ allow: ["Read"],
22147
+ ask: [
22148
+ "Edit",
22149
+ "Write",
22150
+ "Glob",
22151
+ "Grep",
22152
+ "Bash",
22153
+ "WebFetch",
22154
+ "WebSearch",
22155
+ "TodoWrite"
22156
+ ]
22157
+ };
22158
+ case "sensible-defaults":
22159
+ return {
22160
+ allow: ["Read", "Edit", "Write", "Glob", "Grep", "TodoWrite"],
22161
+ ask: ["WebFetch", "WebSearch"]
22162
+ };
22163
+ case "max-autonomy":
22164
+ return {
22165
+ allow: ["Read", "Edit", "Write", "Glob", "Grep", "Bash", "TodoWrite"],
22166
+ ask: ["WebFetch", "WebSearch"]
22167
+ };
22168
+ default:
22169
+ return { allow: [], ask: [] };
22170
+ }
22266
22171
  }
22267
22172
 
22268
22173
  // ../harnesses/dist/writers/cursor.js
22269
22174
  import { mkdir as mkdir4, writeFile as writeFile6 } from "fs/promises";
22270
22175
  import { join as join12 } from "path";
22271
- var CURSOR_CAPABILITY_ORDER = [
22272
- "read",
22273
- "edit_write",
22274
- "search_list",
22275
- "bash_safe",
22276
- "bash_unsafe",
22277
- "web",
22278
- "task_agent"
22279
- ];
22280
- var CURSOR_CAPABILITY_LABELS = {
22281
- read: "read project files",
22282
- edit_write: "edit and write project files",
22283
- search_list: "search and list project contents",
22284
- bash_safe: "run safe local shell commands",
22285
- bash_unsafe: "run high-impact shell commands",
22286
- web: "use web or network access",
22287
- task_agent: "delegate or decompose work into agent tasks"
22288
- };
22289
22176
  var cursorWriter = {
22290
22177
  id: "cursor",
22291
22178
  label: "Cursor",
@@ -22318,21 +22205,36 @@ function getCursorAutonomyNotes(config) {
22318
22205
  if (!hasPermissionPolicy(config)) {
22319
22206
  return [];
22320
22207
  }
22321
- const allowedCapabilities = CURSOR_CAPABILITY_ORDER.filter((capability) => getCapabilityDecision(config, capability) === "allow").map((capability) => CURSOR_CAPABILITY_LABELS[capability]);
22322
- const approvalGatedCapabilities = CURSOR_CAPABILITY_ORDER.filter((capability) => getCapabilityDecision(config, capability) === "ask").map((capability) => CURSOR_CAPABILITY_LABELS[capability]);
22208
+ const profile = getAutonomyProfile(config);
22323
22209
  return [
22324
- `Cursor autonomy note (documented, not enforced): ${getAutonomyProfile(config) ?? "custom"}.`,
22210
+ `Cursor autonomy note (documented, not enforced): ${profile ?? "custom"}.`,
22325
22211
  "Cursor has no verified committed project-local built-in ask/allow/deny config surface, so ADE documents autonomy intent here instead of writing unsupported permission config.",
22326
- ...allowedCapabilities.length > 0 ? [
22327
- `Prefer handling these built-in capabilities without extra approval when Cursor permits it: ${allowedCapabilities.join(", ")}.`
22328
- ] : [],
22329
- ...approvalGatedCapabilities.length > 0 ? [
22330
- `Request approval before these capabilities: ${approvalGatedCapabilities.join(", ")}.`
22331
- ] : [],
22212
+ ...getCursorProfileGuidance(profile),
22332
22213
  "Web and network access must remain approval-gated.",
22333
22214
  "MCP server registration stays in .cursor/mcp.json; MCP tool approvals remain owned by provisioning and are not enforced or re-modeled in this rules file."
22334
22215
  ];
22335
22216
  }
22217
+ function getCursorProfileGuidance(profile) {
22218
+ switch (profile) {
22219
+ case "rigid":
22220
+ return [
22221
+ "Prefer handling these built-in capabilities without extra approval when Cursor permits it: read project files.",
22222
+ "Request approval before these capabilities: edit and write project files, search and list project contents, run safe local shell commands, run high-impact shell commands, use web or network access, delegate or decompose work into agent tasks."
22223
+ ];
22224
+ case "sensible-defaults":
22225
+ return [
22226
+ "Prefer handling these built-in capabilities without extra approval when Cursor permits it: read project files, edit and write project files, search and list project contents, run safe local shell commands, delegate or decompose work into agent tasks.",
22227
+ "Request approval before these capabilities: run high-impact shell commands, use web or network access."
22228
+ ];
22229
+ case "max-autonomy":
22230
+ return [
22231
+ "Prefer handling these built-in capabilities without extra approval when Cursor permits it: read project files, edit and write project files, search and list project contents, run safe local shell commands, run high-impact shell commands, delegate or decompose work into agent tasks.",
22232
+ "Request approval before these capabilities: use web or network access."
22233
+ ];
22234
+ default:
22235
+ return [];
22236
+ }
22237
+ }
22336
22238
 
22337
22239
  // ../harnesses/dist/writers/copilot.js
22338
22240
  import { join as join13 } from "path";
@@ -22347,7 +22249,7 @@ var copilotWriter = {
22347
22249
  transform: stdioEntry
22348
22250
  });
22349
22251
  const tools = [
22350
- ...getBuiltInTools(config),
22252
+ ...getBuiltInTools(getAutonomyProfile(config)),
22351
22253
  ...getForwardedMcpTools(config.mcp_servers)
22352
22254
  ];
22353
22255
  await writeAgentMd(config, {
@@ -22361,19 +22263,17 @@ var copilotWriter = {
22361
22263
  await writeGitHooks(config.git_hooks, projectRoot);
22362
22264
  }
22363
22265
  };
22364
- function getBuiltInTools(config) {
22365
- if (!hasPermissionPolicy(config)) {
22366
- return ["read", "edit", "search", "execute", "agent", "web"];
22266
+ function getBuiltInTools(profile) {
22267
+ switch (profile) {
22268
+ case "rigid":
22269
+ return ["read"];
22270
+ case "sensible-defaults":
22271
+ return ["read", "edit", "search", "agent"];
22272
+ case "max-autonomy":
22273
+ return ["read", "edit", "search", "execute", "agent", "todo"];
22274
+ default:
22275
+ return ["read", "edit", "search", "execute", "agent", "web"];
22367
22276
  }
22368
- return [
22369
- ...allowsCapability(config, "read") ? ["read"] : [],
22370
- ...allowsCapability(config, "edit_write") ? ["edit"] : [],
22371
- ...allowsCapability(config, "search_list") ? ["search"] : [],
22372
- ...allowsCapability(config, "bash_unsafe") ? ["execute"] : [],
22373
- ...allowsCapability(config, "task_agent") ? ["agent"] : [],
22374
- ...allowsCapability(config, "task_agent") && allowsCapability(config, "bash_unsafe") ? ["todo"] : [],
22375
- ...!keepsWebOnAsk(config) && allowsCapability(config, "web") ? ["web"] : []
22376
- ];
22377
22277
  }
22378
22278
  function getForwardedMcpTools(servers) {
22379
22279
  return servers.flatMap((server) => {
@@ -22404,9 +22304,6 @@ function renderCopilotAgentMcpServers(servers) {
22404
22304
  }
22405
22305
  return lines;
22406
22306
  }
22407
- function formatYamlKey(value) {
22408
- return /^[A-Za-z_][A-Za-z0-9_-]*$/.test(value) ? value : JSON.stringify(value);
22409
- }
22410
22307
 
22411
22308
  // ../harnesses/dist/writers/windsurf.js
22412
22309
  import { join as join14 } from "path";
@@ -22427,41 +22324,37 @@ function getWindsurfRules(config) {
22427
22324
  if (!hasPermissionPolicy(config)) {
22428
22325
  return config.instructions;
22429
22326
  }
22430
- const { capabilities } = config.permission_policy;
22431
- const allow = listCapabilities(capabilities, "allow");
22432
- const ask = listCapabilities(capabilities, "ask");
22433
- const deny = listCapabilities(capabilities, "deny");
22434
22327
  const autonomyGuidance = [
22435
22328
  "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.",
22436
- formatGuidance(allow, ask, deny)
22329
+ getWindsurfProfileGuidance(getAutonomyProfile(config))
22437
22330
  ];
22438
22331
  return [...autonomyGuidance, ...config.instructions];
22439
22332
  }
22440
- function listCapabilities(capabilities, decision) {
22441
- return Object.entries(capabilities).filter(([, value]) => value === decision).map(([capability]) => CAPABILITY_LABELS[capability]);
22442
- }
22443
- function formatGuidance(allow, ask, deny) {
22444
- const lines = ["Autonomy guidance for Windsurf built-in capabilities:"];
22445
- if (allow.length > 0) {
22446
- lines.push(`- May proceed without extra approval: ${allow.join(", ")}.`);
22447
- }
22448
- if (ask.length > 0) {
22449
- lines.push(`- Ask before: ${ask.join(", ")}.`);
22450
- }
22451
- if (deny.length > 0) {
22452
- lines.push(`- Do not use unless the user explicitly overrides: ${deny.join(", ")}.`);
22333
+ function getWindsurfProfileGuidance(profile) {
22334
+ const header = "Autonomy guidance for Windsurf built-in capabilities:";
22335
+ switch (profile) {
22336
+ case "rigid":
22337
+ return [
22338
+ header,
22339
+ "- May proceed without extra approval: read files.",
22340
+ "- 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."
22341
+ ].join("\n");
22342
+ case "sensible-defaults":
22343
+ return [
22344
+ header,
22345
+ "- May proceed without extra approval: read files, edit and write files, search and list files, safe local shell commands, task or agent delegation.",
22346
+ "- Ask before: unsafe local shell commands, web and network access."
22347
+ ].join("\n");
22348
+ case "max-autonomy":
22349
+ return [
22350
+ header,
22351
+ "- 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.",
22352
+ "- Ask before: web and network access."
22353
+ ].join("\n");
22354
+ default:
22355
+ return `${header} follow project conventions.`;
22453
22356
  }
22454
- return lines.join("\n");
22455
22357
  }
22456
- var CAPABILITY_LABELS = {
22457
- read: "read files",
22458
- edit_write: "edit and write files",
22459
- search_list: "search and list files",
22460
- bash_safe: "safe local shell commands",
22461
- bash_unsafe: "unsafe local shell commands",
22462
- web: "web and network access",
22463
- task_agent: "task or agent delegation"
22464
- };
22465
22358
 
22466
22359
  // ../harnesses/dist/writers/cline.js
22467
22360
  import { join as join15 } from "path";
@@ -22510,7 +22403,7 @@ async function writeRooModes(config, projectRoot) {
22510
22403
  slug: "ade",
22511
22404
  name: "ADE",
22512
22405
  roleDefinition: "ADE \u2014 Agentic Development Environment mode generated by ADE.",
22513
- groups: getRooModeGroups(config),
22406
+ groups: getRooModeGroups(getAutonomyProfile(config), config.mcp_servers.length > 0),
22514
22407
  source: "project"
22515
22408
  }
22516
22409
  }
@@ -22519,13 +22412,18 @@ async function writeRooModes(config, projectRoot) {
22519
22412
  function asRecord(value) {
22520
22413
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
22521
22414
  }
22522
- function getRooModeGroups(config) {
22523
- return [
22524
- ...allowsCapability(config, "read") ? ["read"] : [],
22525
- ...allowsCapability(config, "edit_write") ? ["edit"] : [],
22526
- ...allowsCapability(config, "bash_unsafe") ? ["command"] : [],
22527
- ...config.mcp_servers.length > 0 ? ["mcp"] : []
22528
- ];
22415
+ function getRooModeGroups(profile, hasMcpServers) {
22416
+ const mcpGroup = hasMcpServers ? ["mcp"] : [];
22417
+ switch (profile) {
22418
+ case "rigid":
22419
+ return ["read", ...mcpGroup];
22420
+ case "sensible-defaults":
22421
+ return ["read", "edit", ...mcpGroup];
22422
+ case "max-autonomy":
22423
+ return ["read", "edit", "command", ...mcpGroup];
22424
+ default:
22425
+ return ["read", "edit", "command", ...mcpGroup];
22426
+ }
22529
22427
  }
22530
22428
 
22531
22429
  // ../harnesses/dist/writers/kiro.js
@@ -22542,33 +22440,31 @@ var kiroWriter = {
22542
22440
  autoApprove: server.allowedTools ?? ["*"]
22543
22441
  })
22544
22442
  });
22443
+ const tools = getKiroTools(getAutonomyProfile(config), config.mcp_servers);
22545
22444
  await writeJson(join17(projectRoot, ".kiro", "agents", "ade.json"), {
22546
22445
  name: "ade",
22547
22446
  description: "ADE \u2014 Agentic Development Environment agent with project conventions and tools.",
22548
22447
  prompt: config.instructions.join("\n\n") || "ADE \u2014 Agentic Development Environment agent.",
22549
22448
  mcpServers: getKiroAgentMcpServers(config.mcp_servers),
22550
- tools: getKiroTools(config),
22551
- allowedTools: getKiroAllowedTools(config),
22449
+ tools,
22450
+ allowedTools: tools,
22552
22451
  useLegacyMcpJson: true
22553
22452
  });
22554
22453
  await writeGitHooks(config.git_hooks, projectRoot);
22555
22454
  }
22556
22455
  };
22557
- function getKiroTools(config) {
22558
- const mcpTools = getKiroForwardedMcpTools(config.mcp_servers);
22559
- if (!hasPermissionPolicy(config)) {
22560
- return ["read", "write", "shell", "spec", ...mcpTools];
22456
+ function getKiroTools(profile, servers) {
22457
+ const mcpTools = getKiroForwardedMcpTools(servers);
22458
+ switch (profile) {
22459
+ case "rigid":
22460
+ return ["read", "shell", "spec", ...mcpTools];
22461
+ case "sensible-defaults":
22462
+ return ["read", "write", "shell", "spec", ...mcpTools];
22463
+ case "max-autonomy":
22464
+ return ["read", "write", "shell(*)", "spec", ...mcpTools];
22465
+ default:
22466
+ return ["read", "write", "shell", "spec", ...mcpTools];
22561
22467
  }
22562
- return [
22563
- ...getCapabilityDecision(config, "read") !== "deny" ? ["read"] : [],
22564
- ...allowsCapability(config, "edit_write") ? ["write"] : [],
22565
- ...allowsCapability(config, "bash_unsafe") ? ["shell(*)"] : ["shell"],
22566
- "spec",
22567
- ...mcpTools
22568
- ];
22569
- }
22570
- function getKiroAllowedTools(config) {
22571
- return getKiroTools(config);
22572
22468
  }
22573
22469
  function getKiroForwardedMcpTools(servers) {
22574
22470
  return servers.flatMap((server) => {
@@ -22591,6 +22487,142 @@ function getKiroAgentMcpServers(servers) {
22591
22487
 
22592
22488
  // ../harnesses/dist/writers/opencode.js
22593
22489
  import { join as join18 } from "path";
22490
+ var APPLICABLE_TO_ALL = {
22491
+ read: {
22492
+ "*": "allow",
22493
+ "*.env": "deny",
22494
+ "*.env.*": "deny",
22495
+ "*.env.example": "allow"
22496
+ },
22497
+ skill: "deny",
22498
+ //we're using an own skills-mcp
22499
+ todoread: "deny",
22500
+ //no agent-proprieatry todo tools
22501
+ todowrite: "deny",
22502
+ task: "deny",
22503
+ lsp: "allow",
22504
+ glob: "allow",
22505
+ grep: "allow",
22506
+ list: "allow",
22507
+ external_directory: "ask"
22508
+ };
22509
+ var RIGID_RULES = {
22510
+ ...APPLICABLE_TO_ALL,
22511
+ "*": "ask",
22512
+ webfetch: "ask",
22513
+ websearch: "ask",
22514
+ codesearch: "ask",
22515
+ external_directory: "deny",
22516
+ doom_loop: "deny"
22517
+ };
22518
+ var SENSIBLE_DEFAULTS_RULES = {
22519
+ ...APPLICABLE_TO_ALL,
22520
+ edit: "allow",
22521
+ webfetch: "ask",
22522
+ websearch: "ask",
22523
+ codesearch: "ask",
22524
+ bash: {
22525
+ "*": "ask",
22526
+ "grep *": "allow",
22527
+ "rg *": "allow",
22528
+ "find *": "allow",
22529
+ "fd *": "allow",
22530
+ "ls *": "allow",
22531
+ "cat *": "allow",
22532
+ "head *": "allow",
22533
+ "tail *": "allow",
22534
+ "wc *": "allow",
22535
+ "sort *": "allow",
22536
+ "uniq *": "allow",
22537
+ "diff *": "allow",
22538
+ "echo *": "allow",
22539
+ "printf *": "allow",
22540
+ pwd: "allow",
22541
+ "which *": "allow",
22542
+ "type *": "allow",
22543
+ whoami: "allow",
22544
+ date: "allow",
22545
+ "date *": "allow",
22546
+ env: "allow",
22547
+ "tree *": "allow",
22548
+ "file *": "allow",
22549
+ "stat *": "allow",
22550
+ "readlink *": "allow",
22551
+ "realpath *": "allow",
22552
+ "dirname *": "allow",
22553
+ "basename *": "allow",
22554
+ "sed *": "allow",
22555
+ "awk *": "allow",
22556
+ "cut *": "allow",
22557
+ "tr *": "allow",
22558
+ "tee *": "allow",
22559
+ "xargs *": "allow",
22560
+ "jq *": "allow",
22561
+ "yq *": "allow",
22562
+ "mkdir *": "allow",
22563
+ "touch *": "allow",
22564
+ "kill *": "ask",
22565
+ "rm *": "deny",
22566
+ "rmdir *": "deny",
22567
+ "curl *": "deny",
22568
+ "wget *": "deny",
22569
+ "chmod *": "deny",
22570
+ "chown *": "deny",
22571
+ "sudo *": "deny",
22572
+ "su *": "deny",
22573
+ "sh *": "deny",
22574
+ "bash *": "deny",
22575
+ "zsh *": "deny",
22576
+ "eval *": "deny",
22577
+ "exec *": "deny",
22578
+ "source *": "deny",
22579
+ ". *": "deny",
22580
+ "nohup *": "deny",
22581
+ "dd *": "deny",
22582
+ "mkfs *": "deny",
22583
+ "mount *": "deny",
22584
+ "umount *": "deny",
22585
+ "killall *": "deny",
22586
+ "pkill *": "deny",
22587
+ "nc *": "deny",
22588
+ "ncat *": "deny",
22589
+ "ssh *": "deny",
22590
+ "scp *": "deny",
22591
+ "rsync *": "deny",
22592
+ "docker *": "deny",
22593
+ "kubectl *": "deny",
22594
+ "systemctl *": "deny",
22595
+ "service *": "deny",
22596
+ "crontab *": "deny",
22597
+ reboot: "deny",
22598
+ "shutdown *": "deny",
22599
+ "passwd *": "deny",
22600
+ "useradd *": "deny",
22601
+ "userdel *": "deny",
22602
+ "iptables *": "deny"
22603
+ },
22604
+ doom_loop: "deny"
22605
+ };
22606
+ var MAX_AUTONOMY_RULES = {
22607
+ ...APPLICABLE_TO_ALL,
22608
+ "*": "allow",
22609
+ webfetch: "ask",
22610
+ websearch: "ask",
22611
+ codesearch: "ask",
22612
+ doom_loop: "deny"
22613
+ };
22614
+ function getPermissionRules(profile) {
22615
+ switch (profile) {
22616
+ case "rigid":
22617
+ return RIGID_RULES;
22618
+ case "sensible-defaults":
22619
+ return SENSIBLE_DEFAULTS_RULES;
22620
+ case "max-autonomy":
22621
+ return MAX_AUTONOMY_RULES;
22622
+ default:
22623
+ return void 0;
22624
+ }
22625
+ }
22594
22626
  var opencodeWriter = {
22595
22627
  id: "opencode",
22596
22628
  label: "OpenCode",
@@ -22606,7 +22638,7 @@ var opencodeWriter = {
22606
22638
  }),
22607
22639
  defaults: { $schema: "https://opencode.ai/config.json" }
22608
22640
  });
22609
- const permission = getHarnessPermissionRules(config);
22641
+ const permission = getPermissionRules(getAutonomyProfile(config));
22610
22642
  await writeAgentMd(config, {
22611
22643
  path: join18(projectRoot, ".opencode", "agents", "ade.md"),
22612
22644
  extraFrontmatter: permission ? renderYamlMapping("permission", permission) : void 0,
@@ -22617,19 +22649,16 @@ var opencodeWriter = {
22617
22649
  };
22618
22650
  function renderYamlMapping(key, value, indent = 0) {
22619
22651
  const prefix = " ".repeat(indent);
22620
- const lines = [`${prefix}${formatYamlKey2(key)}:`];
22652
+ const lines = [`${prefix}${formatYamlKey(key)}:`];
22621
22653
  for (const [childKey, childValue] of Object.entries(value)) {
22622
22654
  if (typeof childValue === "object" && childValue !== null && !Array.isArray(childValue)) {
22623
22655
  lines.push(...renderYamlMapping(childKey, childValue, indent + 2));
22624
22656
  continue;
22625
22657
  }
22626
- lines.push(`${" ".repeat(indent + 2)}${formatYamlKey2(childKey)}: ${JSON.stringify(childValue)}`);
22658
+ lines.push(`${" ".repeat(indent + 2)}${formatYamlKey(childKey)}: ${JSON.stringify(childValue)}`);
22627
22659
  }
22628
22660
  return lines;
22629
22661
  }
22630
- function formatYamlKey2(value) {
22631
- return /^[A-Za-z_][A-Za-z0-9_-]*$/.test(value) ? value : JSON.stringify(value);
22632
- }
22633
22662
 
22634
22663
  // ../harnesses/dist/index.js
22635
22664
  var allHarnessWriters = [
@@ -22767,7 +22796,23 @@ async function runSetup(projectRoot, catalog) {
22767
22796
  To use the latest defaults, remove .ade/skills/ and re-run setup.`
22768
22797
  );
22769
22798
  }
22770
- await installSkills(logicalConfig.skills, projectRoot);
22799
+ if (logicalConfig.skills.length > 0) {
22800
+ const confirmInstall = await Rt({
22801
+ message: `Install ${logicalConfig.skills.length} skill(s) now?`,
22802
+ initialValue: true
22803
+ });
22804
+ if (typeof confirmInstall === "symbol") {
22805
+ Nt("Setup cancelled.");
22806
+ return;
22807
+ }
22808
+ if (confirmInstall) {
22809
+ await installSkills(logicalConfig.skills, projectRoot);
22810
+ } else {
22811
+ R2.info(
22812
+ "Skills not installed. Run manually when ready:\n npx @codemcp/skills experimental_install"
22813
+ );
22814
+ }
22815
+ }
22771
22816
  if (logicalConfig.knowledge_sources.length > 0) {
22772
22817
  R2.info(
22773
22818
  "Knowledge sources selected. Initialize them separately:\n npx @codemcp/knowledge init"
@@ -22852,7 +22897,23 @@ async function runInstall(projectRoot, harnessIds) {
22852
22897
  To use the latest defaults, remove .ade/skills/ and re-run install.`
22853
22898
  );
22854
22899
  }
22855
- await installSkills(logicalConfig.skills, projectRoot);
22900
+ if (logicalConfig.skills.length > 0) {
22901
+ const confirmInstall = await Rt({
22902
+ message: `Install ${logicalConfig.skills.length} skill(s) now?`,
22903
+ initialValue: true
22904
+ });
22905
+ if (typeof confirmInstall === "symbol") {
22906
+ Nt("Install cancelled.");
22907
+ return;
22908
+ }
22909
+ if (confirmInstall) {
22910
+ await installSkills(logicalConfig.skills, projectRoot);
22911
+ } else {
22912
+ R2.info(
22913
+ "Skills not installed. Run manually when ready:\n npx @codemcp/skills experimental_install"
22914
+ );
22915
+ }
22916
+ }
22856
22917
  if (logicalConfig.knowledge_sources.length > 0) {
22857
22918
  R2.info(
22858
22919
  "Knowledge sources configured. Initialize them separately:\n npx @codemcp/knowledge init"