@codemcp/ade 0.2.6 → 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.
@@ -0,0 +1,36 @@
1
+ ---
2
+ name: conventional-commits
3
+ description: Conventional Commits specification for structured commit messages
4
+ ---
5
+
6
+ # Conventional Commits
7
+
8
+ ## Format
9
+
10
+ ```
11
+ <type>[optional scope]: <description>
12
+
13
+ [optional body]
14
+
15
+ [optional footer(s)]
16
+ ```
17
+
18
+ ## Types
19
+
20
+ - `feat`: A new feature (correlates with MINOR in SemVer)
21
+ - `fix`: A bug fix (correlates with PATCH in SemVer)
22
+ - `docs`: Documentation only changes
23
+ - `style`: Changes that do not affect the meaning of the code
24
+ - `refactor`: A code change that neither fixes a bug nor adds a feature
25
+ - `perf`: A code change that improves performance
26
+ - `test`: Adding missing tests or correcting existing tests
27
+ - `chore`: Changes to the build process or auxiliary tools
28
+
29
+ ## Rules
30
+
31
+ - Subject line must not exceed 72 characters
32
+ - Use imperative mood in the subject line ("add" not "added")
33
+ - Do not end the subject line with a period
34
+ - Separate subject from body with a blank line
35
+ - Use the body to explain what and why, not how
36
+ - `BREAKING CHANGE:` footer or `!` after type/scope for breaking changes
@@ -50,3 +50,9 @@
50
50
  {"id":"ade-3.3","title":"Fix","description":"Implement the solution based on your analysis: - If exists: Follow the design from it - Otherwise: Elaborate design options and present them to the user Before implementing, assess the approach: - How critical is this system? What is the blast radius if the fix causes issues? - Should this be a minimal fix or a more comprehensive solution? Make targeted changes that address the root cause without introducing new issues. Be careful to maintain existing functionality while fixing the bug.","status":"open","priority":3,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-18T16:29:10.265074+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-18T16:29:10.265074+01:00","dependencies":[{"issue_id":"ade-3.3","depends_on_id":"ade-3","type":"parent-child","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"ade-3.3","depends_on_id":"ade-3.2","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
51
51
  {"id":"ade-3.4","title":"Verify","description":"Test the fix thoroughly to ensure the original bug is resolved and no new issues were introduced. Run existing tests, create new ones if needed, and verify the solution is robust.","status":"open","priority":3,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-18T16:29:10.449967+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-18T16:29:10.449967+01:00","dependencies":[{"issue_id":"ade-3.4","depends_on_id":"ade-3","type":"parent-child","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"ade-3.4","depends_on_id":"ade-3.3","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
52
52
  {"id":"ade-3.5","title":"Finalize","description":"Ensure code quality and documentation accuracy through systematic cleanup and review. **STEP 1: Code Cleanup** Systematically clean up development artifacts: - Remove all temporary debug output statements used during bug investigation (console logging, print statements, debug output functions) - Address each TODO/FIXME comment by either implementing the solution or documenting why it's deferred - Remove completed TODOs and convert remaining ones to proper issue tracking if needed - Remove temporary debugging code, test code blocks, and commented-out code - Ensure proper error handling replaces temporary debug logging **STEP 2: Documentation Review** Review and update documentation to reflect the bug fix: - If exists, update it if design details were refined or changed during the fix - Compare documentation against the actual bug fix implementation - Update only the documentation sections that have functional changes - Remove references to investigation iterations, progress notes, and temporary decisions - Ensure documentation describes the final fixed state, not the debugging process - Ask the user to review document updates **STEP 3: Final Validation** - Run existing tests to ensure cleanup didn't break functionality - Verify documentation accuracy with a final review - Ensure bug fix is ready for production - Update task progress and mark completed work as you finalize the bug fix","status":"open","priority":3,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-18T16:29:10.642935+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-18T16:29:10.642935+01:00","dependencies":[{"issue_id":"ade-3.5","depends_on_id":"ade-3","type":"parent-child","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"ade-3.5","depends_on_id":"ade-3.4","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
53
+ {"id":"ade-4","title":"ade: bugfix (development-plan-fix-no-git.md)","description":"Responsible vibe engineering session using bugfix workflow for ade","status":"open","priority":2,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-19T10:33:06.662828+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-19T10:33:06.662828+01:00"}
54
+ {"id":"ade-4.1","title":"Reproduce","description":"Gather specific information to reliably reproduce the reported bug: - What are the exact OS, browser/runtime versions, and hardware specs? - What is the precise sequence of actions that trigger the bug? - What error messages, logs, or stack traces are available? - Does this happen every time or intermittently? - How many users are affected and what is the business impact? Create test cases that demonstrate the problem. Document your findings and create tasks as needed.","status":"open","priority":3,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-19T10:33:06.80022+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-19T10:33:06.80022+01:00","dependencies":[{"issue_id":"ade-4.1","depends_on_id":"ade-4","type":"parent-child","created_at":"0001-01-01T00:00:00Z"}]}
55
+ {"id":"ade-4.2","title":"Analyze","description":"Examine the code paths involved in the bug, identify the root cause, and understand why the issue occurs. Use debugging tools, add logging, and trace through the problematic code. Document your analysis and create tasks as needed.","status":"open","priority":3,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-19T10:33:06.939399+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-19T10:33:06.939399+01:00","dependencies":[{"issue_id":"ade-4.2","depends_on_id":"ade-4","type":"parent-child","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"ade-4.2","depends_on_id":"ade-4.1","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
56
+ {"id":"ade-4.3","title":"Fix","description":"Implement the solution based on your analysis: - If exists: Follow the design from it - Otherwise: Elaborate design options and present them to the user Before implementing, assess the approach: - How critical is this system? What is the blast radius if the fix causes issues? - Should this be a minimal fix or a more comprehensive solution? Make targeted changes that address the root cause without introducing new issues. Be careful to maintain existing functionality while fixing the bug.","status":"open","priority":3,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-19T10:33:07.076548+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-19T10:33:07.076548+01:00","dependencies":[{"issue_id":"ade-4.3","depends_on_id":"ade-4","type":"parent-child","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"ade-4.3","depends_on_id":"ade-4.2","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
57
+ {"id":"ade-4.4","title":"Verify","description":"Test the fix thoroughly to ensure the original bug is resolved and no new issues were introduced. Run existing tests, create new ones if needed, and verify the solution is robust.","status":"open","priority":3,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-19T10:33:07.222264+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-19T10:33:07.222264+01:00","dependencies":[{"issue_id":"ade-4.4","depends_on_id":"ade-4","type":"parent-child","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"ade-4.4","depends_on_id":"ade-4.3","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
58
+ {"id":"ade-4.5","title":"Finalize","description":"Ensure code quality and documentation accuracy through systematic cleanup and review. **STEP 1: Code Cleanup** Systematically clean up development artifacts: - Remove all temporary debug output statements used during bug investigation (console logging, print statements, debug output functions) - Address each TODO/FIXME comment by either implementing the solution or documenting why it's deferred - Remove completed TODOs and convert remaining ones to proper issue tracking if needed - Remove temporary debugging code, test code blocks, and commented-out code - Ensure proper error handling replaces temporary debug logging **STEP 2: Documentation Review** Review and update documentation to reflect the bug fix: - If exists, update it if design details were refined or changed during the fix - Compare documentation against the actual bug fix implementation - Update only the documentation sections that have functional changes - Remove references to investigation iterations, progress notes, and temporary decisions - Ensure documentation describes the final fixed state, not the debugging process - Ask the user to review document updates **STEP 3: Final Validation** - Run existing tests to ensure cleanup didn't break functionality - Verify documentation accuracy with a final review - Ensure bug fix is ready for production - Update task progress and mark completed work as you finalize the bug fix","status":"open","priority":3,"issue_type":"task","owner":"github@beimir.net","created_at":"2026-03-19T10:33:07.356694+01:00","created_by":"Oliver Jägle","updated_at":"2026-03-19T10:33:07.356694+01:00","dependencies":[{"issue_id":"ade-4.5","depends_on_id":"ade-4","type":"parent-child","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"ade-4.5","depends_on_id":"ade-4.4","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
@@ -1 +1 @@
1
- ade-3.5
1
+ ade-4.5
@@ -14,7 +14,14 @@
14
14
  "autoApprove": ["*"]
15
15
  }
16
16
  },
17
- "tools": ["read", "write", "spec", "@workflows/*", "@agentskills/*", "shell"],
18
- "allowedTools": ["read", "write", "spec", "@workflows/*", "@agentskills/*"],
17
+ "tools": ["read", "write", "shell", "spec", "@workflows/*", "@agentskills/*"],
18
+ "allowedTools": [
19
+ "read",
20
+ "write",
21
+ "shell",
22
+ "spec",
23
+ "@workflows/*",
24
+ "@agentskills/*"
25
+ ],
19
26
  "useLegacyMcpJson": true
20
27
  }
@@ -7,25 +7,25 @@ permission:
7
7
  "*.env": "deny"
8
8
  "*.env.*": "deny"
9
9
  "*.env.example": "allow"
10
- edit: "allow"
10
+ skill: "deny"
11
+ todoread: "deny"
12
+ todowrite: "deny"
13
+ task: "deny"
14
+ lsp: "allow"
11
15
  glob: "allow"
12
16
  grep: "allow"
13
17
  list: "allow"
14
- lsp: "allow"
15
- task: "allow"
16
- todoread: "deny"
17
- todowrite: "deny"
18
- skill: "deny"
18
+ external_directory: "ask"
19
+ edit: "allow"
19
20
  webfetch: "ask"
20
21
  websearch: "ask"
21
22
  codesearch: "ask"
22
23
  bash:
23
- "*": "deny"
24
+ "*": "ask"
24
25
  "grep *": "allow"
25
26
  "rg *": "allow"
26
27
  "find *": "allow"
27
28
  "fd *": "allow"
28
- ls: "allow"
29
29
  "ls *": "allow"
30
30
  "cat *": "allow"
31
31
  "head *": "allow"
@@ -60,14 +60,7 @@ permission:
60
60
  "yq *": "allow"
61
61
  "mkdir *": "allow"
62
62
  "touch *": "allow"
63
- "cp *": "ask"
64
- "mv *": "ask"
65
- "ln *": "ask"
66
- "npm *": "ask"
67
- "node *": "ask"
68
- "pip *": "ask"
69
- "python *": "ask"
70
- "python3 *": "ask"
63
+ "kill *": "ask"
71
64
  "rm *": "deny"
72
65
  "rmdir *": "deny"
73
66
  "curl *": "deny"
@@ -88,7 +81,6 @@ permission:
88
81
  "mkfs *": "deny"
89
82
  "mount *": "deny"
90
83
  "umount *": "deny"
91
- "kill *": "deny"
92
84
  "killall *": "deny"
93
85
  "pkill *": "deny"
94
86
  "nc *": "deny"
@@ -107,7 +99,6 @@ permission:
107
99
  "useradd *": "deny"
108
100
  "userdel *": "deny"
109
101
  "iptables *": "deny"
110
- external_directory: "deny"
111
102
  doom_loop: "deny"
112
103
  ---
113
104
 
@@ -0,0 +1,34 @@
1
+ {
2
+ "conversationId": "ade-fix-no-git-k396xs",
3
+ "projectPath": "/Users/oliverjaegle/projects/privat/codemcp/ade",
4
+ "epicId": "ade-4",
5
+ "phaseTasks": [
6
+ {
7
+ "phaseId": "reproduce",
8
+ "phaseName": "Reproduce",
9
+ "taskId": "ade-4.1"
10
+ },
11
+ {
12
+ "phaseId": "analyze",
13
+ "phaseName": "Analyze",
14
+ "taskId": "ade-4.2"
15
+ },
16
+ {
17
+ "phaseId": "fix",
18
+ "phaseName": "Fix",
19
+ "taskId": "ade-4.3"
20
+ },
21
+ {
22
+ "phaseId": "verify",
23
+ "phaseName": "Verify",
24
+ "taskId": "ade-4.4"
25
+ },
26
+ {
27
+ "phaseId": "finalize",
28
+ "phaseName": "Finalize",
29
+ "taskId": "ade-4.5"
30
+ }
31
+ ],
32
+ "createdAt": "2026-03-19T09:33:07.866Z",
33
+ "updatedAt": "2026-03-19T09:33:07.866Z"
34
+ }
@@ -0,0 +1,76 @@
1
+ # Development Plan: ade (fix-no-git branch)
2
+
3
+ *Generated on 2026-03-19 by Vibe Feature MCP*
4
+ *Workflow: [bugfix](https://mrsimpson.github.io/responsible-vibe-mcp/workflows/bugfix)*
5
+
6
+ ## Goal
7
+ Fix `writeGitHooks` crashing with ENOENT when run in a non-git directory. Instead of throwing, it should detect the absence of `.git` and emit a warning, then skip gracefully (Option B).
8
+
9
+ ## Reproduce
10
+ <!-- beads-phase-id: ade-4.1 -->
11
+ ### Bug Description
12
+ When `ade setup` is run in a non-git directory and pre-commit hooks are configured, `writeGitHooks` tries to open `.git/hooks/pre-commit` for writing. Since `.git` doesn't exist, Node throws `ENOENT` and the whole process crashes.
13
+
14
+ ### Error
15
+ ```
16
+ Error: ENOENT: no such file or directory, open '/private/tmp/manual-test/.git/hooks/pre-commit'
17
+ ```
18
+
19
+ ### Root Cause (already identified via code reading)
20
+ `packages/harnesses/src/util.ts` → `writeGitHooks()` writes directly to `.git/hooks/<phase>` without checking if `.git` exists.
21
+
22
+ ### Tasks
23
+
24
+ ## Analyze
25
+ <!-- beads-phase-id: ade-4.2 -->
26
+ ### Phase Entrance Criteria
27
+ - [x] Bug is reproducible and root cause is identified.
28
+ - [x] Affected code location is known (`writeGitHooks` in `packages/harnesses/src/util.ts`).
29
+
30
+ ### Analysis
31
+ - `writeGitHooks` is a shared utility called by every harness writer (universal, cursor, copilot, cline, claude-code, roo-code, opencode, kiro, windsurf).
32
+ - The fix belongs in `writeGitHooks` itself — one place, all callers benefit.
33
+ - Chosen approach: **Option B** — check for `.git` existence; if absent, emit a `clack.log.warn(...)` and return early. This keeps the user informed (backpressure) without crashing.
34
+ - `clack` is already used throughout the codebase; it is available in `util.ts`.
35
+
36
+ ### Tasks
37
+
38
+ ## Fix
39
+ <!-- beads-phase-id: ade-4.3 -->
40
+ ### Phase Entrance Criteria
41
+ - [x] Root cause is confirmed to be in `writeGitHooks`.
42
+ - [x] Fix strategy (Option B: warn + skip) is agreed upon.
43
+
44
+ ### Tasks
45
+ - [ ] In `writeGitHooks`: use `fs/promises.access` to check for `.git` directory existence before writing hooks.
46
+ - [ ] If `.git` is absent, call `clack.log.warn(...)` with a clear message and return.
47
+ - [ ] Also ensure `.git/hooks` directory is created if `.git` exists but `hooks` subdir is missing (use `mkdir` with `recursive: true`).
48
+ - [ ] Add / update unit tests in `install.spec.ts` or `util.spec.ts` to cover the non-git-repo case.
49
+
50
+ ## Verify
51
+ <!-- beads-phase-id: ade-4.4 -->
52
+ ### Phase Entrance Criteria
53
+ - [ ] `writeGitHooks` checks for `.git` existence and warns instead of crashing.
54
+ - [ ] `.git/hooks` dir is created when `.git` exists but `hooks` subdir is missing.
55
+ - [ ] Unit tests cover the new behavior.
56
+
57
+ ### Tasks
58
+ - [ ] Run existing test suite and confirm no regressions.
59
+ - [ ] Manually verify the warning message is shown when run outside a git repo.
60
+
61
+ ## Finalize
62
+ <!-- beads-phase-id: ade-4.5 -->
63
+ ### Phase Entrance Criteria
64
+ - [ ] All tests pass.
65
+ - [ ] Warning behavior verified.
66
+
67
+ ### Tasks
68
+ - [ ] Squash WIP commits: `git reset --soft <first commit of this branch>`. Then, create a conventional commit. In the message, first summarize the intentions and key decisions from the development plan. Then, add a brief summary of the key changes and their side effects and dependencies.
69
+
70
+ ## Key Decisions
71
+ - **Option B (warn + skip)** chosen over silent skip so users receive feedback that hooks were not installed — this preserves backpressure (user knows something was skipped).
72
+ - Fix is centralised in `writeGitHooks` utility; no changes needed in individual harness writers.
73
+
74
+ ## Notes
75
+ - `clack` import must be added to `util.ts` if not already present.
76
+ - All harness writers already import `writeGitHooks` from `../util.js` — no call-site changes needed.
package/AGENTS.md ADDED
@@ -0,0 +1,27 @@
1
+ # AGENTS
2
+
3
+ You are an AI assistant that helps users develop software features using the workflows server.
4
+ IMPORTANT: Call whats_next() after each user message to get phase-specific instructions and maintain the development workflow.
5
+ Each tool call returns a JSON response with an "instructions" field. Follow these instructions immediately after you receive them.
6
+ Use the development plan which you will retrieve via whats_next() to record important insights and decisions as per the structure of the plan.
7
+ Do not use your own task management tools.
8
+
9
+ ## Autonomy
10
+
11
+ Universal harness limitation: `AGENTS.md` + `.mcp.json` provide documentation and server registration only; there is no enforceable harness-level permission schema here.
12
+
13
+ Treat this autonomy profile as documentation-only guidance for built-in/basic operations.
14
+
15
+ Profile: `sensible-defaults`
16
+
17
+ Built-in/basic capability guidance:
18
+
19
+ - `read`: allow
20
+ - `edit_write`: allow
21
+ - `search_list`: allow
22
+ - `bash_safe`: allow
23
+ - `bash_unsafe`: ask
24
+ - `web`: ask
25
+ - `task_agent`: allow
26
+
27
+ MCP permissions are not re-modeled by autonomy here; any MCP approvals must come from provisioning-aware consuming harnesses rather than the Universal writer.
package/config.lock.yaml CHANGED
@@ -1,9 +1,10 @@
1
1
  version: 1
2
- generated_at: 2026-03-18T11:52:51.718Z
2
+ generated_at: 2026-03-19T09:28:46.177Z
3
3
  choices:
4
4
  process: codemcp-workflows
5
5
  practices:
6
6
  - adr-nygard
7
+ - conventional-commits
7
8
  autonomy: sensible-defaults
8
9
  harnesses:
9
10
  - universal
@@ -104,15 +105,38 @@ logical_config:
104
105
 
105
106
  - Title should be a short noun phrase (e.g. "Use PostgreSQL for
106
107
  persistence")
108
+ - name: conventional-commits
109
+ description: Conventional Commits specification for structured commit messages
110
+ body: |-
111
+ # Conventional Commits
112
+
113
+ ## Format
114
+ ```
115
+ <type>[optional scope]: <description>
116
+
117
+ [optional body]
118
+
119
+ [optional footer(s)]
120
+ ```
121
+
122
+ ## Types
123
+ - `feat`: A new feature (correlates with MINOR in SemVer)
124
+ - `fix`: A bug fix (correlates with PATCH in SemVer)
125
+ - `docs`: Documentation only changes
126
+ - `style`: Changes that do not affect the meaning of the code
127
+ - `refactor`: A code change that neither fixes a bug nor adds a feature
128
+ - `perf`: A code change that improves performance
129
+ - `test`: Adding missing tests or correcting existing tests
130
+ - `chore`: Changes to the build process or auxiliary tools
131
+
132
+ ## Rules
133
+ - Subject line must not exceed 72 characters
134
+ - Use imperative mood in the subject line ("add" not "added")
135
+ - Do not end the subject line with a period
136
+ - Separate subject from body with a blank line
137
+ - Use the body to explain what and why, not how
138
+ - `BREAKING CHANGE:` footer or `!` after type/scope for breaking changes
107
139
  git_hooks: []
108
140
  setup_notes: []
109
141
  permission_policy:
110
142
  profile: sensible-defaults
111
- capabilities:
112
- read: allow
113
- edit_write: allow
114
- search_list: allow
115
- bash_safe: allow
116
- bash_unsafe: ask
117
- web: ask
118
- task_agent: allow
package/config.yaml CHANGED
@@ -2,7 +2,10 @@ choices:
2
2
  process: codemcp-workflows
3
3
  practices:
4
4
  - adr-nygard
5
+ - conventional-commits
5
6
  autonomy: sensible-defaults
7
+ excluded_docsets:
8
+ - conventional-commits-spec
6
9
  harnesses:
7
10
  - universal
8
11
  - opencode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemcp/ade",
3
- "version": "0.2.6",
3
+ "version": "0.3.0",
4
4
  "description": "ADE CLI — Agentic Development Environment setup and configuration tool",
5
5
  "license": "MIT",
6
6
  "keywords": [
@@ -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);
@@ -21824,7 +21868,7 @@ async function installSkills(skills, projectRoot) {
21824
21868
  }
21825
21869
 
21826
21870
  // ../harnesses/dist/util.js
21827
- 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";
21828
21872
  import { dirname as dirname5, join as join9 } from "path";
21829
21873
  async function readJsonOrEmpty(path2) {
21830
21874
  try {
@@ -21891,10 +21935,19 @@ async function writeAgentMd(config, opts) {
21891
21935
  await writeFile4(opts.path, content, "utf-8");
21892
21936
  }
21893
21937
  async function writeGitHooks(hooks, projectRoot) {
21894
- 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.");
21895
21945
  return;
21946
+ }
21947
+ const hooksDir = join9(gitDir, "hooks");
21948
+ await mkdir3(hooksDir, { recursive: true });
21896
21949
  for (const hook of hooks) {
21897
- const hookPath = join9(projectRoot, ".git", "hooks", hook.phase);
21950
+ const hookPath = join9(hooksDir, hook.phase);
21898
21951
  await writeFile4(hookPath, hook.script, { mode: 493 });
21899
21952
  }
21900
21953
  }
@@ -22434,7 +22487,27 @@ function getKiroAgentMcpServers(servers) {
22434
22487
 
22435
22488
  // ../harnesses/dist/writers/opencode.js
22436
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
+ };
22437
22509
  var RIGID_RULES = {
22510
+ ...APPLICABLE_TO_ALL,
22438
22511
  "*": "ask",
22439
22512
  webfetch: "ask",
22440
22513
  websearch: "ask",
@@ -22443,31 +22516,17 @@ var RIGID_RULES = {
22443
22516
  doom_loop: "deny"
22444
22517
  };
22445
22518
  var SENSIBLE_DEFAULTS_RULES = {
22446
- read: {
22447
- "*": "allow",
22448
- "*.env": "deny",
22449
- "*.env.*": "deny",
22450
- "*.env.example": "allow"
22451
- },
22519
+ ...APPLICABLE_TO_ALL,
22452
22520
  edit: "allow",
22453
- glob: "allow",
22454
- grep: "allow",
22455
- list: "allow",
22456
- lsp: "allow",
22457
- task: "allow",
22458
- todoread: "deny",
22459
- todowrite: "deny",
22460
- skill: "deny",
22461
22521
  webfetch: "ask",
22462
22522
  websearch: "ask",
22463
22523
  codesearch: "ask",
22464
22524
  bash: {
22465
- "*": "deny",
22525
+ "*": "ask",
22466
22526
  "grep *": "allow",
22467
22527
  "rg *": "allow",
22468
22528
  "find *": "allow",
22469
22529
  "fd *": "allow",
22470
- ls: "allow",
22471
22530
  "ls *": "allow",
22472
22531
  "cat *": "allow",
22473
22532
  "head *": "allow",
@@ -22502,14 +22561,7 @@ var SENSIBLE_DEFAULTS_RULES = {
22502
22561
  "yq *": "allow",
22503
22562
  "mkdir *": "allow",
22504
22563
  "touch *": "allow",
22505
- "cp *": "ask",
22506
- "mv *": "ask",
22507
- "ln *": "ask",
22508
- "npm *": "ask",
22509
- "node *": "ask",
22510
- "pip *": "ask",
22511
- "python *": "ask",
22512
- "python3 *": "ask",
22564
+ "kill *": "ask",
22513
22565
  "rm *": "deny",
22514
22566
  "rmdir *": "deny",
22515
22567
  "curl *": "deny",
@@ -22530,7 +22582,6 @@ var SENSIBLE_DEFAULTS_RULES = {
22530
22582
  "mkfs *": "deny",
22531
22583
  "mount *": "deny",
22532
22584
  "umount *": "deny",
22533
- "kill *": "deny",
22534
22585
  "killall *": "deny",
22535
22586
  "pkill *": "deny",
22536
22587
  "nc *": "deny",
@@ -22550,15 +22601,14 @@ var SENSIBLE_DEFAULTS_RULES = {
22550
22601
  "userdel *": "deny",
22551
22602
  "iptables *": "deny"
22552
22603
  },
22553
- external_directory: "deny",
22554
22604
  doom_loop: "deny"
22555
22605
  };
22556
22606
  var MAX_AUTONOMY_RULES = {
22607
+ ...APPLICABLE_TO_ALL,
22557
22608
  "*": "allow",
22558
22609
  webfetch: "ask",
22559
22610
  websearch: "ask",
22560
22611
  codesearch: "ask",
22561
- external_directory: "deny",
22562
22612
  doom_loop: "deny"
22563
22613
  };
22564
22614
  function getPermissionRules(profile) {
@@ -22746,7 +22796,23 @@ async function runSetup(projectRoot, catalog) {
22746
22796
  To use the latest defaults, remove .ade/skills/ and re-run setup.`
22747
22797
  );
22748
22798
  }
22749
- 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
+ }
22750
22816
  if (logicalConfig.knowledge_sources.length > 0) {
22751
22817
  R2.info(
22752
22818
  "Knowledge sources selected. Initialize them separately:\n npx @codemcp/knowledge init"
@@ -22831,7 +22897,23 @@ async function runInstall(projectRoot, harnessIds) {
22831
22897
  To use the latest defaults, remove .ade/skills/ and re-run install.`
22832
22898
  );
22833
22899
  }
22834
- 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
+ }
22835
22917
  if (logicalConfig.knowledge_sources.length > 0) {
22836
22918
  R2.info(
22837
22919
  "Knowledge sources configured. Initialize them separately:\n npx @codemcp/knowledge init"
@@ -39,5 +39,5 @@
39
39
  "typescript": "catalog:",
40
40
  "vitest": "catalog:"
41
41
  },
42
- "version": "0.2.6"
42
+ "version": "0.3.0"
43
43
  }
@@ -8,9 +8,15 @@ vi.mock("@clack/prompts", () => ({
8
8
  outro: vi.fn(),
9
9
  select: vi.fn(),
10
10
  multiselect: vi.fn(),
11
- confirm: vi.fn(),
11
+ confirm: vi.fn().mockResolvedValue(true),
12
12
  isCancel: vi.fn().mockReturnValue(false),
13
13
  cancel: vi.fn(),
14
+ log: {
15
+ info: vi.fn(),
16
+ warn: vi.fn(),
17
+ error: vi.fn(),
18
+ success: vi.fn()
19
+ },
14
20
  spinner: vi.fn().mockReturnValue({ start: vi.fn(), stop: vi.fn() })
15
21
  }));
16
22
 
@@ -51,7 +51,25 @@ export async function runInstall(
51
51
  );
52
52
  }
53
53
 
54
- await installSkills(logicalConfig.skills, projectRoot);
54
+ if (logicalConfig.skills.length > 0) {
55
+ const confirmInstall = await clack.confirm({
56
+ message: `Install ${logicalConfig.skills.length} skill(s) now?`,
57
+ initialValue: true
58
+ });
59
+
60
+ if (typeof confirmInstall === "symbol") {
61
+ clack.cancel("Install cancelled.");
62
+ return;
63
+ }
64
+
65
+ if (confirmInstall) {
66
+ await installSkills(logicalConfig.skills, projectRoot);
67
+ } else {
68
+ clack.log.info(
69
+ "Skills not installed. Run manually when ready:\n npx @codemcp/skills experimental_install"
70
+ );
71
+ }
72
+ }
55
73
 
56
74
  if (logicalConfig.knowledge_sources.length > 0) {
57
75
  clack.log.info(
@@ -172,7 +172,25 @@ export async function runSetup(
172
172
  );
173
173
  }
174
174
 
175
- await installSkills(logicalConfig.skills, projectRoot);
175
+ if (logicalConfig.skills.length > 0) {
176
+ const confirmInstall = await clack.confirm({
177
+ message: `Install ${logicalConfig.skills.length} skill(s) now?`,
178
+ initialValue: true
179
+ });
180
+
181
+ if (typeof confirmInstall === "symbol") {
182
+ clack.cancel("Setup cancelled.");
183
+ return;
184
+ }
185
+
186
+ if (confirmInstall) {
187
+ await installSkills(logicalConfig.skills, projectRoot);
188
+ } else {
189
+ clack.log.info(
190
+ "Skills not installed. Run manually when ready:\n npx @codemcp/skills experimental_install"
191
+ );
192
+ }
193
+ }
176
194
 
177
195
  if (logicalConfig.knowledge_sources.length > 0) {
178
196
  clack.log.info(
@@ -38,5 +38,5 @@
38
38
  "typescript": "catalog:",
39
39
  "vitest": "catalog:"
40
40
  },
41
- "version": "0.2.6"
41
+ "version": "0.3.0"
42
42
  }
@@ -28,6 +28,7 @@
28
28
  "typecheck": "tsc --noEmit"
29
29
  },
30
30
  "dependencies": {
31
+ "@clack/prompts": "^1.1.0",
31
32
  "@codemcp/ade-core": "workspace:*",
32
33
  "@codemcp/skills": "^2.3.0"
33
34
  },
@@ -39,5 +40,5 @@
39
40
  "typescript": "catalog:",
40
41
  "vitest": "catalog:"
41
42
  },
42
- "version": "0.2.6"
43
+ "version": "0.3.0"
43
44
  }
@@ -0,0 +1,97 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
2
+ import { mkdtemp, rm, mkdir, readFile, stat } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import * as clack from "@clack/prompts";
6
+ import type { GitHook } from "@codemcp/ade-core";
7
+ import { writeGitHooks } from "./util.js";
8
+
9
+ describe("writeGitHooks", () => {
10
+ let dir: string;
11
+
12
+ beforeEach(async () => {
13
+ dir = await mkdtemp(join(tmpdir(), "ade-util-git-hooks-"));
14
+ vi.spyOn(clack.log, "warn").mockImplementation(() => undefined);
15
+ });
16
+
17
+ afterEach(async () => {
18
+ await rm(dir, { recursive: true, force: true });
19
+ vi.restoreAllMocks();
20
+ });
21
+
22
+ it("is a no-op when hooks is undefined", async () => {
23
+ await expect(writeGitHooks(undefined, dir)).resolves.toBeUndefined();
24
+ expect(clack.log.warn).not.toHaveBeenCalled();
25
+ });
26
+
27
+ it("is a no-op when hooks array is empty", async () => {
28
+ await expect(writeGitHooks([], dir)).resolves.toBeUndefined();
29
+ expect(clack.log.warn).not.toHaveBeenCalled();
30
+ });
31
+
32
+ it("warns and skips gracefully when .git directory does not exist", async () => {
33
+ const hooks: GitHook[] = [
34
+ { phase: "pre-commit", script: "#!/bin/sh\nnpx lint-staged" }
35
+ ];
36
+
37
+ await expect(writeGitHooks(hooks, dir)).resolves.toBeUndefined();
38
+
39
+ expect(clack.log.warn).toHaveBeenCalledOnce();
40
+ expect(clack.log.warn).toHaveBeenCalledWith(
41
+ expect.stringContaining("not a git repository")
42
+ );
43
+
44
+ // No .git/hooks directory should have been created
45
+ await expect(stat(join(dir, ".git"))).rejects.toThrow();
46
+ });
47
+
48
+ it("writes hook files when .git exists", async () => {
49
+ await mkdir(join(dir, ".git"), { recursive: true });
50
+
51
+ const script = "#!/bin/sh\nnpx lint-staged\n";
52
+ const hooks: GitHook[] = [{ phase: "pre-commit", script }];
53
+
54
+ await writeGitHooks(hooks, dir);
55
+
56
+ expect(clack.log.warn).not.toHaveBeenCalled();
57
+
58
+ const written = await readFile(
59
+ join(dir, ".git", "hooks", "pre-commit"),
60
+ "utf-8"
61
+ );
62
+ expect(written).toBe(script);
63
+ });
64
+
65
+ it("creates .git/hooks directory if it does not exist yet", async () => {
66
+ // .git exists but no hooks subdir
67
+ await mkdir(join(dir, ".git"), { recursive: true });
68
+
69
+ const hooks: GitHook[] = [{ phase: "pre-commit", script: "#!/bin/sh\n" }];
70
+ await writeGitHooks(hooks, dir);
71
+
72
+ const hookStat = await stat(join(dir, ".git", "hooks"));
73
+ expect(hookStat.isDirectory()).toBe(true);
74
+ });
75
+
76
+ it("writes multiple hooks", async () => {
77
+ await mkdir(join(dir, ".git"), { recursive: true });
78
+
79
+ const hooks: GitHook[] = [
80
+ { phase: "pre-commit", script: "#!/bin/sh\necho pre-commit\n" },
81
+ { phase: "pre-push", script: "#!/bin/sh\necho pre-push\n" }
82
+ ];
83
+
84
+ await writeGitHooks(hooks, dir);
85
+
86
+ const preCommit = await readFile(
87
+ join(dir, ".git", "hooks", "pre-commit"),
88
+ "utf-8"
89
+ );
90
+ const prePush = await readFile(
91
+ join(dir, ".git", "hooks", "pre-push"),
92
+ "utf-8"
93
+ );
94
+ expect(preCommit).toBe(hooks[0].script);
95
+ expect(prePush).toBe(hooks[1].script);
96
+ });
97
+ });
@@ -1,5 +1,6 @@
1
- import { mkdir, readFile, writeFile } from "node:fs/promises";
1
+ import { access, mkdir, readFile, writeFile } from "node:fs/promises";
2
2
  import { dirname, join } from "node:path";
3
+ import * as clack from "@clack/prompts";
3
4
  import type { GitHook, LogicalConfig, McpServerEntry } from "@codemcp/ade-core";
4
5
 
5
6
  // ---------------------------------------------------------------------------
@@ -169,15 +170,31 @@ export async function writeAgentMd(
169
170
  /**
170
171
  * Write git hook scripts to `.git/hooks/<phase>`.
171
172
  * Files are created with executable permissions (0o755).
172
- * No-op when the hooks array is empty.
173
+ * No-op when the hooks array is empty or undefined.
174
+ * Emits a warning and skips gracefully when the project root is not a git repository.
173
175
  */
174
176
  export async function writeGitHooks(
175
177
  hooks: GitHook[] | undefined,
176
178
  projectRoot: string
177
179
  ): Promise<void> {
178
- if (!hooks) return;
180
+ if (!hooks || hooks.length === 0) return;
181
+
182
+ const gitDir = join(projectRoot, ".git");
183
+ try {
184
+ await access(gitDir);
185
+ } catch {
186
+ clack.log.warn(
187
+ "Git hooks were configured but could not be installed: the project is not a git repository.\n" +
188
+ "Run `git init` and re-run setup to install the hooks."
189
+ );
190
+ return;
191
+ }
192
+
193
+ const hooksDir = join(gitDir, "hooks");
194
+ await mkdir(hooksDir, { recursive: true });
195
+
179
196
  for (const hook of hooks) {
180
- const hookPath = join(projectRoot, ".git", "hooks", hook.phase);
197
+ const hookPath = join(hooksDir, hook.phase);
181
198
  await writeFile(hookPath, hook.script, { mode: 0o755 });
182
199
  }
183
200
  }
@@ -102,17 +102,16 @@ describe("opencodeWriter", () => {
102
102
  expect(defaultsAgent).toContain('grep: "allow"');
103
103
  expect(defaultsAgent).toContain('list: "allow"');
104
104
  expect(defaultsAgent).toContain('lsp: "allow"');
105
- expect(defaultsAgent).toContain('task: "allow"');
105
+ expect(defaultsAgent).toContain('task: "deny"');
106
106
  expect(defaultsAgent).toContain('skill: "deny"');
107
107
  expect(defaultsAgent).toContain('todoread: "deny"');
108
108
  expect(defaultsAgent).toContain('todowrite: "deny"');
109
109
  expect(defaultsAgent).toContain('webfetch: "ask"');
110
110
  expect(defaultsAgent).toContain('websearch: "ask"');
111
111
  expect(defaultsAgent).toContain('codesearch: "ask"');
112
- expect(defaultsAgent).toContain('external_directory: "deny"');
112
+ expect(defaultsAgent).toContain('external_directory: "ask"');
113
113
  expect(defaultsAgent).toContain('doom_loop: "deny"');
114
114
  expect(defaultsAgent).toContain('"grep *": "allow"');
115
- expect(defaultsAgent).toContain('"cp *": "ask"');
116
115
  expect(defaultsAgent).toContain('"rm *": "deny"');
117
116
  expect(defaultsFrontmatter.permission).toMatchObject({
118
117
  edit: "allow",
@@ -120,21 +119,20 @@ describe("opencodeWriter", () => {
120
119
  grep: "allow",
121
120
  list: "allow",
122
121
  lsp: "allow",
123
- task: "allow",
122
+ task: "deny",
124
123
  skill: "deny",
125
124
  todoread: "deny",
126
125
  todowrite: "deny",
127
126
  webfetch: "ask",
128
127
  websearch: "ask",
129
128
  codesearch: "ask",
130
- external_directory: "deny",
129
+ external_directory: "ask",
131
130
  doom_loop: "deny"
132
131
  });
133
132
  const defaultsPermission = defaultsFrontmatter.permission as {
134
133
  bash: Record<string, string>;
135
134
  };
136
135
  expect(defaultsPermission.bash["grep *"]).toBe("allow");
137
- expect(defaultsPermission.bash["cp *"]).toBe("ask");
138
136
  expect(defaultsPermission.bash["rm *"]).toBe("deny");
139
137
 
140
138
  expect(maxAgent).toContain('"*": "allow"');
@@ -12,7 +12,26 @@ import { getAutonomyProfile } from "../permission-policy.js";
12
12
  type PermissionDecision = "ask" | "allow" | "deny";
13
13
  type PermissionRule = PermissionDecision | Record<string, PermissionDecision>;
14
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
+
15
33
  const RIGID_RULES: Record<string, PermissionRule> = {
34
+ ...APPLICABLE_TO_ALL,
16
35
  "*": "ask",
17
36
  webfetch: "ask",
18
37
  websearch: "ask",
@@ -22,31 +41,17 @@ const RIGID_RULES: Record<string, PermissionRule> = {
22
41
  };
23
42
 
24
43
  const SENSIBLE_DEFAULTS_RULES: Record<string, PermissionRule> = {
25
- read: {
26
- "*": "allow",
27
- "*.env": "deny",
28
- "*.env.*": "deny",
29
- "*.env.example": "allow"
30
- },
44
+ ...APPLICABLE_TO_ALL,
31
45
  edit: "allow",
32
- glob: "allow",
33
- grep: "allow",
34
- list: "allow",
35
- lsp: "allow",
36
- task: "allow",
37
- todoread: "deny",
38
- todowrite: "deny",
39
- skill: "deny",
40
46
  webfetch: "ask",
41
47
  websearch: "ask",
42
48
  codesearch: "ask",
43
49
  bash: {
44
- "*": "deny",
50
+ "*": "ask",
45
51
  "grep *": "allow",
46
52
  "rg *": "allow",
47
53
  "find *": "allow",
48
54
  "fd *": "allow",
49
- ls: "allow",
50
55
  "ls *": "allow",
51
56
  "cat *": "allow",
52
57
  "head *": "allow",
@@ -81,14 +86,7 @@ const SENSIBLE_DEFAULTS_RULES: Record<string, PermissionRule> = {
81
86
  "yq *": "allow",
82
87
  "mkdir *": "allow",
83
88
  "touch *": "allow",
84
- "cp *": "ask",
85
- "mv *": "ask",
86
- "ln *": "ask",
87
- "npm *": "ask",
88
- "node *": "ask",
89
- "pip *": "ask",
90
- "python *": "ask",
91
- "python3 *": "ask",
89
+ "kill *": "ask",
92
90
  "rm *": "deny",
93
91
  "rmdir *": "deny",
94
92
  "curl *": "deny",
@@ -109,7 +107,6 @@ const SENSIBLE_DEFAULTS_RULES: Record<string, PermissionRule> = {
109
107
  "mkfs *": "deny",
110
108
  "mount *": "deny",
111
109
  "umount *": "deny",
112
- "kill *": "deny",
113
110
  "killall *": "deny",
114
111
  "pkill *": "deny",
115
112
  "nc *": "deny",
@@ -129,16 +126,15 @@ const SENSIBLE_DEFAULTS_RULES: Record<string, PermissionRule> = {
129
126
  "userdel *": "deny",
130
127
  "iptables *": "deny"
131
128
  },
132
- external_directory: "deny",
133
129
  doom_loop: "deny"
134
130
  };
135
131
 
136
132
  const MAX_AUTONOMY_RULES: Record<string, PermissionRule> = {
133
+ ...APPLICABLE_TO_ALL,
137
134
  "*": "allow",
138
135
  webfetch: "ask",
139
136
  websearch: "ask",
140
137
  codesearch: "ask",
141
- external_directory: "deny",
142
138
  doom_loop: "deny"
143
139
  };
144
140
 
package/skills-lock.json CHANGED
@@ -4,13 +4,18 @@
4
4
  "adr-nygard": {
5
5
  "source": "/Users/oliverjaegle/projects/privat/codemcp/ade/.ade/skills/adr-nygard",
6
6
  "sourceType": "local",
7
- "computedHash": "13cd33eb604e9e090057cce458469b2a1b609a6db3313a03df88d91776095b19"
7
+ "computedHash": "d62ee4c175a38f91d98a0536f863396ceb48c7de4275787520b07870705b4367"
8
8
  },
9
9
  "commit": {
10
10
  "source": "mrsimpson/skills-coding",
11
11
  "sourceType": "github",
12
12
  "computedHash": "fc628c7d577d2d9cf3cb0a917d3c5e2e35b460fdc62c353595b7472b6f1c6548"
13
13
  },
14
+ "conventional-commits": {
15
+ "source": "/Users/oliverjaegle/projects/privat/codemcp/ade/.ade/skills/conventional-commits",
16
+ "sourceType": "local",
17
+ "computedHash": "49dd439dbd856412264fa345eaa9bbf2526095cb16457ffc7fb66a9d2f4d5f9d"
18
+ },
14
19
  "tdd": {
15
20
  "source": "mrsimpson/skills-coding",
16
21
  "sourceType": "github",