agent-guild 1.3.0__tar.gz → 1.3.2__tar.gz

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 (31) hide show
  1. {agent_guild-1.3.0 → agent_guild-1.3.2}/CHANGELOG.md +15 -0
  2. {agent_guild-1.3.0 → agent_guild-1.3.2}/PKG-INFO +42 -20
  3. {agent_guild-1.3.0 → agent_guild-1.3.2}/README.md +40 -19
  4. {agent_guild-1.3.0 → agent_guild-1.3.2}/docs/manual_installation.md +1 -1
  5. {agent_guild-1.3.0 → agent_guild-1.3.2}/pyproject.toml +2 -2
  6. {agent_guild-1.3.0 → agent_guild-1.3.2}/src/agent_guild/cli.py +14 -5
  7. {agent_guild-1.3.0 → agent_guild-1.3.2}/src/agent_guild/files.py +31 -12
  8. {agent_guild-1.3.0 → agent_guild-1.3.2}/src/agent_guild/installer.py +210 -76
  9. {agent_guild-1.3.0 → agent_guild-1.3.2}/src/agent_guild/specialists.py +13 -13
  10. {agent_guild-1.3.0 → agent_guild-1.3.2}/src/agent_guild/vendors.py +48 -13
  11. {agent_guild-1.3.0 → agent_guild-1.3.2}/templates/agents-rules.md +1 -1
  12. agent_guild-1.3.2/tests/test_cli.py +947 -0
  13. agent_guild-1.3.2/uv.lock +138 -0
  14. agent_guild-1.3.0/tests/test_cli.py +0 -553
  15. agent_guild-1.3.0/uv.lock +0 -79
  16. {agent_guild-1.3.0 → agent_guild-1.3.2}/.github/workflows/ci.yml +0 -0
  17. {agent_guild-1.3.0 → agent_guild-1.3.2}/.github/workflows/release.yml +0 -0
  18. {agent_guild-1.3.0 → agent_guild-1.3.2}/.gitignore +0 -0
  19. {agent_guild-1.3.0 → agent_guild-1.3.2}/LICENSE +0 -0
  20. {agent_guild-1.3.0 → agent_guild-1.3.2}/agents/architect.md +0 -0
  21. {agent_guild-1.3.0 → agent_guild-1.3.2}/agents/code-grader.md +0 -0
  22. {agent_guild-1.3.0 → agent_guild-1.3.2}/agents/coder.md +0 -0
  23. {agent_guild-1.3.0 → agent_guild-1.3.2}/agents/utility.md +0 -0
  24. {agent_guild-1.3.0 → agent_guild-1.3.2}/development-workflow.md +0 -0
  25. {agent_guild-1.3.0 → agent_guild-1.3.2}/scripts/release_notes.py +0 -0
  26. {agent_guild-1.3.0 → agent_guild-1.3.2}/src/agent_guild/__init__.py +0 -0
  27. {agent_guild-1.3.0 → agent_guild-1.3.2}/templates/coders/python.md +0 -0
  28. {agent_guild-1.3.0 → agent_guild-1.3.2}/templates/coders/swift.md +0 -0
  29. {agent_guild-1.3.0 → agent_guild-1.3.2}/templates/coders/typescript.md +0 -0
  30. {agent_guild-1.3.0 → agent_guild-1.3.2}/templates/memory-bank-rules.md +0 -0
  31. {agent_guild-1.3.0 → agent_guild-1.3.2}/templates/sdd-rules.md +0 -0
@@ -2,6 +2,21 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.3.2] - 2026-10-22
6
+
7
+ - Cursor and Codex agent copies now refer only to `AGENTS.md` instead of "`CLAUDE.md` / `AGENTS.md`"; Claude Code copies are unchanged.
8
+ - Keep CRLF line endings when appending the rules sections to an existing `AGENTS.md`/`CLAUDE.md`, instead of rewriting the file with LF.
9
+
10
+ ## [1.3.1] - 2026-10-22
11
+
12
+ - Install Codex skills into the supported `.agents/skills/` discovery path. Reuse existing project skill copies,
13
+ including supporting files, when adding Codex; legacy `.codex/skills/` installs are preserved as a migration source.
14
+ - Migrate shared rules from `CLAUDE.md` into `AGENTS.md` when adding Cursor or Codex, preserving project customizations,
15
+ Claude-only sections and the Claude import shim. Warn on conflicting duplicate sections. Dry runs remain read-only.
16
+ - Reuse existing project MCP arguments and environment settings when adding a Codex server, while preserving existing
17
+ Codex entries. Generated shared rules explicitly tell every tool to read the workflow file.
18
+ - Quote language-coder descriptions as valid YAML, and decode quoted values before converting to Cursor or Codex.
19
+
5
20
  ## [1.3.0] - 2026-10-22
6
21
 
7
22
  - Cursor and Codex support. The installer detects the tools a project uses (`.claude/` or `CLAUDE.md`, `.cursor/`,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: agent-guild
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: A multi-agent setup for Claude Code, Cursor and Codex (orchestrator + architect, coder, grader, utility subagents) with memory-bank, jevmem and Spec-Driven Development wired in, installed into a project with one command.
5
5
  Project-URL: Homepage, https://github.com/illescasDaniel/agent-guild
6
6
  Project-URL: Issues, https://github.com/illescasDaniel/agent-guild/issues
@@ -15,6 +15,7 @@ Classifier: Programming Language :: Python :: 3
15
15
  Classifier: Programming Language :: Python :: 3.11
16
16
  Classifier: Topic :: Software Development
17
17
  Requires-Python: >=3.11
18
+ Requires-Dist: pyyaml<7,>=6.0.3
18
19
  Description-Content-Type: text/markdown
19
20
 
20
21
  # agent-guild
@@ -34,7 +35,8 @@ utility), and three features come wired in:
34
35
  - [jev-mem](https://github.com/illescasDaniel/jev-mem): *long-term facts*, recalled by relevance through an MCP
35
36
  server and session hooks.
36
37
  - **Spec-Driven Development (SDD)**, via [sdd-feature](https://github.com/illescasDaniel/sdd-feature-skill): specs,
37
- design, interfaces, implementation and grading, with approval gates between phases. Opt-in per project.
38
+ design, interfaces, implementation and grading, with approval gates between phases. Included by default; omit it
39
+ with `--without sdd`.
38
40
 
39
41
  ```bash
40
42
  uvx agent-guild /path/to/project
@@ -60,7 +62,7 @@ uvx agent-guild /path/to/project
60
62
 
61
63
  | File | Install to (Claude Code) | Role |
62
64
  |---|---|---|
63
- | [development-workflow.md](development-workflow.md) | imported from `~/.claude/CLAUDE.md` | Orchestrator rules: knowledge layers, routing, SDD phase → agent map, briefs, memory protocol |
65
+ | [development-workflow.md](development-workflow.md) | `.agents/development-workflow.md` | Orchestrator rules: knowledge layers, routing, SDD phase → agent map, briefs, memory protocol |
64
66
  | [agents/architect.md](agents/architect.md) | `~/.claude/agents/` | Opus, read-only. Plans, SDD Phase 1 design decisions, Phase 2 interfaces, root causes |
65
67
  | [agents/coder.md](agents/coder.md) | `~/.claude/agents/` | Sonnet. Scoped implementation; parallel-safe |
66
68
  | [agents/code-grader.md](agents/code-grader.md) | `~/.claude/agents/` | Opus, read-only. SDD Phase 5. Body identical to the sdd-feature skill's grader; only the frontmatter differs |
@@ -73,7 +75,10 @@ These are the Claude Code sources; the installer converts them for Cursor and Co
73
75
  ### Quick: the installer (per project)
74
76
 
75
77
  `agent-guild` copies everything into a project (plain copies, not links, so the project can edit them) and is
76
- safe to re-run: files that differ from the shipped version are skipped unless you pass `--force`.
78
+ safe to re-run: existing files that differ from the selected source are skipped unless you pass `--force`.
79
+ It resolves and validates all sources and configuration in an in-memory plan before writing project files.
80
+ `--dry-run` builds the same plan (including downloads into a temporary directory), without writing to the project.
81
+ Preflight failures leave the project unchanged; filesystem errors during the final writes can still leave a partial install.
77
82
 
78
83
  ```bash
79
84
  uvx agent-guild /path/to/project --dry-run
@@ -86,21 +91,27 @@ uvx agent-guild /path/to/project
86
91
  It does, in the project, for each coding tool it finds (see **Tools** below):
87
92
 
88
93
  - copies the agents in that tool's format and folder (`.claude/agents/*.md`; `.cursor/agents/*.md` with `readonly`
89
- instead of `disallowedTools`; `.codex/agents/*.toml`), and one shared `development-workflow.md` next to the first
90
- tool's agents;
94
+ instead of `disallowedTools`; `.codex/agents/*.toml`), and one shared
95
+ `.agents/development-workflow.md`, explicitly read by Claude Code, Cursor and Codex;
91
96
  - copies the `memory-bank`, `jev-memory` and `sdd-feature` skills into that tool's skills folder (`.claude/skills/`,
92
- `.cursor/skills/`, `.codex/skills/` for Codex), cloned from GitHub, or from local clones with `--sources-dir DIR`;
93
- - adds three removable sections to `AGENTS.md`: *Agents and delegation*, *Memory bank* and *Phase Gate Protocol*. If the
94
- project has only a `CLAUDE.md`, they go there instead; with neither, `AGENTS.md` is created. When Claude Code is one
95
- of the tools, `CLAUDE.md` gets an `@AGENTS.md` import (Claude Code doesn't read `AGENTS.md`). A section that either
96
- file already has is not added again;
97
+ `.cursor/skills/`, `.agents/skills/` for Codex), cloned from GitHub, or from local clones with `--sources-dir DIR`;
98
+ - adds three removable sections: *Agents and delegation*, *Memory bank* and *Phase Gate Protocol*. If `AGENTS.md`
99
+ exists, that is the target. If only `CLAUDE.md` exists and only Claude Code is selected, it is the target instead.
100
+ Otherwise, creates `AGENTS.md`. Existing sections in the target are preserved; conflicts with sections in the
101
+ other instruction file produce warnings. **No developer rules are moved, deleted or migrated between files.**
102
+ Modern Claude Code (v2.1.277+, with built-in AGENTS support enabled) can read `AGENTS.md` directly when no
103
+ project/local `CLAUDE.md` takes precedence. Use `--claude-compat` to add an `@AGENTS.md` import for older versions
104
+ or sessions that prefer `CLAUDE.md`; meaningful existing Claude content is retained. With both files present,
105
+ the installer warns if Claude may not load the new shared instructions. See [Claude's instruction loading docs](https://code.claude.com/docs/en/memory#agentsmd);
97
106
  - adds the pinned jevmem server to the tool's MCP config (`.mcp.json`, `.cursor/mcp.json`, `.codex/config.toml`),
98
- merging into existing files;
99
- - for Claude Code only: adds the jevmem hooks to `.claude/settings.json`, sets `autoMemoryEnabled: false` and the
100
- project's model to `sonnet`.
107
+ merging into existing files. New Codex servers reuse matching project entries from `.mcp.json`, then
108
+ `.cursor/mcp.json`, before falling back to defaults; existing Codex entries always win;
109
+ - for Claude Code only: adds the jevmem hooks to `.claude/settings.json`. It preserves existing project/local model
110
+ and auto-memory preferences; only absent preferences default to `sonnet` and `autoMemoryEnabled: false`.
111
+ `--model` and `--disable-auto-memory` explicitly override the corresponding destination settings.
101
112
 
102
113
  **Tools.** The installer detects what the project uses: `.claude/` or `CLAUDE.md` → Claude Code, `.cursor/` → Cursor,
103
- `.codex/` or `.agents/` → Codex; with several, it installs for all of them, and with none, for Claude Code. Override
114
+ `.codex/` or `.agents/skills/` → Codex; with several, it installs for all of them, and with none, for Claude Code. Override
104
115
  with `--tools claude,cursor,codex`. Cursor and Codex agents don't carry the Claude model tiering (Cursor gets
105
116
  `model: inherit`, Codex inherits the session model) and Codex has no read-only switch for an agent, so the read-only
106
117
  agents say it in their instructions. Cursor also reads `.claude/` and `.agents/` folders, so with several tools
@@ -112,12 +123,14 @@ installed it may list a skill twice.
112
123
  | `--with coder-python` / `coder-swift` / `coder-typescript` | Add a language coder (repeatable): the generic coder, required to use that language's code-navigation MCP ([codenav-mcp](https://github.com/illescasDaniel/codenav-mcp), [codenav-swift-mcp](https://github.com/illescasDaniel/codenav-swift-mcp), [webnav-ts-mcp](https://github.com/illescasDaniel/webnav-ts-mcp)). Also adds the MCP server to `.mcp.json` (an existing entry is kept) and an `AGENTS.md` rule that routes that language's work to it. The MCP's own prerequisites (uv, a Swift toolchain, Node) are printed after the install |
113
124
  | `--coders-only` | With `--with`: install only the language coders (agent, MCP server, `AGENTS.md` rule) and nothing else. After a normal install, the tool detects Python, Swift and TypeScript/JS projects and prints this command for the coders you don't have yet |
114
125
  | `--without sdd` / `memory-bank` / `jevmem` | Leave a component out. `sdd` also drops `code-grader` and the gate section; `jevmem` drops its skill, server, hooks and the auto-memory switch |
115
- | `--model ALIAS` | Project main-session model; default `sonnet` (the per-project alternative to the global setting below), `none` leaves it unset |
126
+ | `--model ALIAS` | Explicitly set the Claude project model. When omitted, preserve project/local preferences and default to `sonnet` only if absent; `none` does not set a model |
127
+ | `--claude-compat` | Add a `CLAUDE.md` import of `AGENTS.md` for older Claude Code or sessions that prefer Claude instruction files. Off by default |
128
+ | `--disable-auto-memory` | Explicitly set `autoMemoryEnabled: false`; otherwise preserve an existing project/local preference |
116
129
  | `--import-cursor-skills` | Also copy the project's `.cursor/skills/*` into `.claude/skills/` (needs `claude` among the tools); skills that already exist are kept |
117
130
  | `--personal-settings` | Put `--model` and `autoMemoryEnabled` in the git-ignored `.claude/settings.local.json` |
118
131
  | `--import-auto-memory` | First import the project's existing auto-memory notes into jevmem |
119
132
  | `--keep-auto-memory` | Don't switch auto-memory off |
120
- | `--sources-dir DIR` | Use local clones named `memory-bank/`, `jev-mem/`, `sdd-feature-skill/` instead of GitHub |
133
+ | `--sources-dir DIR` | Use local clones named `memory-bank/`, `jev-mem/`, `sdd-feature-skill/` instead of the pinned upstream revisions; this is an explicit reproducibility override |
121
134
  | `--git-exclude` | List the files this run *creates* in `.git/info/exclude` (local to your clone, never committed), so you can try the setup without it showing in `git status`. Off by default: files are added normally and your git settings apply. Edits to files git already tracks (e.g. an existing `.mcp.json`) can't be hidden; the tool warns about them |
122
135
  | `--force`, `--dry-run` | Overwrite edited copies; show the plan without writing |
123
136
 
@@ -145,6 +158,15 @@ or `CLAUDE.md` already has), so it is safe to run on a project with its own agen
145
158
  - **Skipped files are yours.** Anything the log marks `skipped ... differs` keeps your version. If it is an older or
146
159
  customised copy of a shipped one (the `sdd-feature` skill, `code-grader`, `jev-memory`), diff it against the shipped
147
160
  file and merge what you want by hand. `--force` replaces it instead.
161
+ - **All tools reuse project sources.** For agents, choose the first existing copy in Claude, Cursor, Codex order;
162
+ convert it for missing tool copies. Language coders inherit the project's generic coder body. For skills, choose
163
+ `.claude/skills`, `.cursor/skills`, `.agents/skills`, then legacy `.codex/skills`, and use that source for every
164
+ tool. Full supporting trees are copied. Existing divergent copies stay protected and produce drift warnings.
165
+ The selected source is printed, including in dry-runs. These are plain copies; later edits are not synchronized.
166
+ `--force` deliberately uses shipped sources instead. Codex discovers project skills under `.agents/skills`.
167
+ - **Upstream skills are pinned.** Each release selects exact Git commits in `SKILL_REVISIONS`; fetching verifies
168
+ the resolved commit. `.agents/skill-sources.json` records the upstream URLs, revisions and content hashes.
169
+ `--sources-dir` records `local` plus content hashes instead, so local edits are visible in provenance.
148
170
  - **New files can land next to yours.** A skill folder you already have keeps its `SKILL.md`, but the shipped files
149
171
  that are missing (templates, scripts) are added beside it. If `.claude/skills` is a symlink to `.cursor/skills`, the
150
172
  log says so, and the skills are written there.
@@ -175,9 +197,9 @@ or `CLAUDE.md` already has), so it is safe to run on a project with its own agen
175
197
  changes.
176
198
  - **The grader runs on Opus.** The code it grades was written by Sonnet coders, so a different, stronger model gives
177
199
  a more independent review.
178
- - **SDD is opt-in.** The global workflow uses SDD only when a project's `AGENTS.md` / `CLAUDE.md` adopts the Phase Gate
179
- Protocol, or when you ask for the `sdd-feature` skill directly. Projects that don't want gates just leave the rule
180
- out.
200
+ - **SDD is included by default.** A standard installation adds its skill, grader and Phase Gate Protocol.
201
+ Pass `--without sdd` to omit those additions. Existing developer-owned files and rules are not removed by this
202
+ flag. The workflow activates SDD when the project adopts the protocol or explicitly invokes the skill.
181
203
  - **Gates and gate status.** SDD gates stay between the orchestrator and the user. The gate status is recorded in
182
204
  `memory/activeContext.md`, so a new session resumes at the right gate.
183
205
 
@@ -15,7 +15,8 @@ utility), and three features come wired in:
15
15
  - [jev-mem](https://github.com/illescasDaniel/jev-mem): *long-term facts*, recalled by relevance through an MCP
16
16
  server and session hooks.
17
17
  - **Spec-Driven Development (SDD)**, via [sdd-feature](https://github.com/illescasDaniel/sdd-feature-skill): specs,
18
- design, interfaces, implementation and grading, with approval gates between phases. Opt-in per project.
18
+ design, interfaces, implementation and grading, with approval gates between phases. Included by default; omit it
19
+ with `--without sdd`.
19
20
 
20
21
  ```bash
21
22
  uvx agent-guild /path/to/project
@@ -41,7 +42,7 @@ uvx agent-guild /path/to/project
41
42
 
42
43
  | File | Install to (Claude Code) | Role |
43
44
  |---|---|---|
44
- | [development-workflow.md](development-workflow.md) | imported from `~/.claude/CLAUDE.md` | Orchestrator rules: knowledge layers, routing, SDD phase → agent map, briefs, memory protocol |
45
+ | [development-workflow.md](development-workflow.md) | `.agents/development-workflow.md` | Orchestrator rules: knowledge layers, routing, SDD phase → agent map, briefs, memory protocol |
45
46
  | [agents/architect.md](agents/architect.md) | `~/.claude/agents/` | Opus, read-only. Plans, SDD Phase 1 design decisions, Phase 2 interfaces, root causes |
46
47
  | [agents/coder.md](agents/coder.md) | `~/.claude/agents/` | Sonnet. Scoped implementation; parallel-safe |
47
48
  | [agents/code-grader.md](agents/code-grader.md) | `~/.claude/agents/` | Opus, read-only. SDD Phase 5. Body identical to the sdd-feature skill's grader; only the frontmatter differs |
@@ -54,7 +55,10 @@ These are the Claude Code sources; the installer converts them for Cursor and Co
54
55
  ### Quick: the installer (per project)
55
56
 
56
57
  `agent-guild` copies everything into a project (plain copies, not links, so the project can edit them) and is
57
- safe to re-run: files that differ from the shipped version are skipped unless you pass `--force`.
58
+ safe to re-run: existing files that differ from the selected source are skipped unless you pass `--force`.
59
+ It resolves and validates all sources and configuration in an in-memory plan before writing project files.
60
+ `--dry-run` builds the same plan (including downloads into a temporary directory), without writing to the project.
61
+ Preflight failures leave the project unchanged; filesystem errors during the final writes can still leave a partial install.
58
62
 
59
63
  ```bash
60
64
  uvx agent-guild /path/to/project --dry-run
@@ -67,21 +71,27 @@ uvx agent-guild /path/to/project
67
71
  It does, in the project, for each coding tool it finds (see **Tools** below):
68
72
 
69
73
  - copies the agents in that tool's format and folder (`.claude/agents/*.md`; `.cursor/agents/*.md` with `readonly`
70
- instead of `disallowedTools`; `.codex/agents/*.toml`), and one shared `development-workflow.md` next to the first
71
- tool's agents;
74
+ instead of `disallowedTools`; `.codex/agents/*.toml`), and one shared
75
+ `.agents/development-workflow.md`, explicitly read by Claude Code, Cursor and Codex;
72
76
  - copies the `memory-bank`, `jev-memory` and `sdd-feature` skills into that tool's skills folder (`.claude/skills/`,
73
- `.cursor/skills/`, `.codex/skills/` for Codex), cloned from GitHub, or from local clones with `--sources-dir DIR`;
74
- - adds three removable sections to `AGENTS.md`: *Agents and delegation*, *Memory bank* and *Phase Gate Protocol*. If the
75
- project has only a `CLAUDE.md`, they go there instead; with neither, `AGENTS.md` is created. When Claude Code is one
76
- of the tools, `CLAUDE.md` gets an `@AGENTS.md` import (Claude Code doesn't read `AGENTS.md`). A section that either
77
- file already has is not added again;
77
+ `.cursor/skills/`, `.agents/skills/` for Codex), cloned from GitHub, or from local clones with `--sources-dir DIR`;
78
+ - adds three removable sections: *Agents and delegation*, *Memory bank* and *Phase Gate Protocol*. If `AGENTS.md`
79
+ exists, that is the target. If only `CLAUDE.md` exists and only Claude Code is selected, it is the target instead.
80
+ Otherwise, creates `AGENTS.md`. Existing sections in the target are preserved; conflicts with sections in the
81
+ other instruction file produce warnings. **No developer rules are moved, deleted or migrated between files.**
82
+ Modern Claude Code (v2.1.277+, with built-in AGENTS support enabled) can read `AGENTS.md` directly when no
83
+ project/local `CLAUDE.md` takes precedence. Use `--claude-compat` to add an `@AGENTS.md` import for older versions
84
+ or sessions that prefer `CLAUDE.md`; meaningful existing Claude content is retained. With both files present,
85
+ the installer warns if Claude may not load the new shared instructions. See [Claude's instruction loading docs](https://code.claude.com/docs/en/memory#agentsmd);
78
86
  - adds the pinned jevmem server to the tool's MCP config (`.mcp.json`, `.cursor/mcp.json`, `.codex/config.toml`),
79
- merging into existing files;
80
- - for Claude Code only: adds the jevmem hooks to `.claude/settings.json`, sets `autoMemoryEnabled: false` and the
81
- project's model to `sonnet`.
87
+ merging into existing files. New Codex servers reuse matching project entries from `.mcp.json`, then
88
+ `.cursor/mcp.json`, before falling back to defaults; existing Codex entries always win;
89
+ - for Claude Code only: adds the jevmem hooks to `.claude/settings.json`. It preserves existing project/local model
90
+ and auto-memory preferences; only absent preferences default to `sonnet` and `autoMemoryEnabled: false`.
91
+ `--model` and `--disable-auto-memory` explicitly override the corresponding destination settings.
82
92
 
83
93
  **Tools.** The installer detects what the project uses: `.claude/` or `CLAUDE.md` → Claude Code, `.cursor/` → Cursor,
84
- `.codex/` or `.agents/` → Codex; with several, it installs for all of them, and with none, for Claude Code. Override
94
+ `.codex/` or `.agents/skills/` → Codex; with several, it installs for all of them, and with none, for Claude Code. Override
85
95
  with `--tools claude,cursor,codex`. Cursor and Codex agents don't carry the Claude model tiering (Cursor gets
86
96
  `model: inherit`, Codex inherits the session model) and Codex has no read-only switch for an agent, so the read-only
87
97
  agents say it in their instructions. Cursor also reads `.claude/` and `.agents/` folders, so with several tools
@@ -93,12 +103,14 @@ installed it may list a skill twice.
93
103
  | `--with coder-python` / `coder-swift` / `coder-typescript` | Add a language coder (repeatable): the generic coder, required to use that language's code-navigation MCP ([codenav-mcp](https://github.com/illescasDaniel/codenav-mcp), [codenav-swift-mcp](https://github.com/illescasDaniel/codenav-swift-mcp), [webnav-ts-mcp](https://github.com/illescasDaniel/webnav-ts-mcp)). Also adds the MCP server to `.mcp.json` (an existing entry is kept) and an `AGENTS.md` rule that routes that language's work to it. The MCP's own prerequisites (uv, a Swift toolchain, Node) are printed after the install |
94
104
  | `--coders-only` | With `--with`: install only the language coders (agent, MCP server, `AGENTS.md` rule) and nothing else. After a normal install, the tool detects Python, Swift and TypeScript/JS projects and prints this command for the coders you don't have yet |
95
105
  | `--without sdd` / `memory-bank` / `jevmem` | Leave a component out. `sdd` also drops `code-grader` and the gate section; `jevmem` drops its skill, server, hooks and the auto-memory switch |
96
- | `--model ALIAS` | Project main-session model; default `sonnet` (the per-project alternative to the global setting below), `none` leaves it unset |
106
+ | `--model ALIAS` | Explicitly set the Claude project model. When omitted, preserve project/local preferences and default to `sonnet` only if absent; `none` does not set a model |
107
+ | `--claude-compat` | Add a `CLAUDE.md` import of `AGENTS.md` for older Claude Code or sessions that prefer Claude instruction files. Off by default |
108
+ | `--disable-auto-memory` | Explicitly set `autoMemoryEnabled: false`; otherwise preserve an existing project/local preference |
97
109
  | `--import-cursor-skills` | Also copy the project's `.cursor/skills/*` into `.claude/skills/` (needs `claude` among the tools); skills that already exist are kept |
98
110
  | `--personal-settings` | Put `--model` and `autoMemoryEnabled` in the git-ignored `.claude/settings.local.json` |
99
111
  | `--import-auto-memory` | First import the project's existing auto-memory notes into jevmem |
100
112
  | `--keep-auto-memory` | Don't switch auto-memory off |
101
- | `--sources-dir DIR` | Use local clones named `memory-bank/`, `jev-mem/`, `sdd-feature-skill/` instead of GitHub |
113
+ | `--sources-dir DIR` | Use local clones named `memory-bank/`, `jev-mem/`, `sdd-feature-skill/` instead of the pinned upstream revisions; this is an explicit reproducibility override |
102
114
  | `--git-exclude` | List the files this run *creates* in `.git/info/exclude` (local to your clone, never committed), so you can try the setup without it showing in `git status`. Off by default: files are added normally and your git settings apply. Edits to files git already tracks (e.g. an existing `.mcp.json`) can't be hidden; the tool warns about them |
103
115
  | `--force`, `--dry-run` | Overwrite edited copies; show the plan without writing |
104
116
 
@@ -126,6 +138,15 @@ or `CLAUDE.md` already has), so it is safe to run on a project with its own agen
126
138
  - **Skipped files are yours.** Anything the log marks `skipped ... differs` keeps your version. If it is an older or
127
139
  customised copy of a shipped one (the `sdd-feature` skill, `code-grader`, `jev-memory`), diff it against the shipped
128
140
  file and merge what you want by hand. `--force` replaces it instead.
141
+ - **All tools reuse project sources.** For agents, choose the first existing copy in Claude, Cursor, Codex order;
142
+ convert it for missing tool copies. Language coders inherit the project's generic coder body. For skills, choose
143
+ `.claude/skills`, `.cursor/skills`, `.agents/skills`, then legacy `.codex/skills`, and use that source for every
144
+ tool. Full supporting trees are copied. Existing divergent copies stay protected and produce drift warnings.
145
+ The selected source is printed, including in dry-runs. These are plain copies; later edits are not synchronized.
146
+ `--force` deliberately uses shipped sources instead. Codex discovers project skills under `.agents/skills`.
147
+ - **Upstream skills are pinned.** Each release selects exact Git commits in `SKILL_REVISIONS`; fetching verifies
148
+ the resolved commit. `.agents/skill-sources.json` records the upstream URLs, revisions and content hashes.
149
+ `--sources-dir` records `local` plus content hashes instead, so local edits are visible in provenance.
129
150
  - **New files can land next to yours.** A skill folder you already have keeps its `SKILL.md`, but the shipped files
130
151
  that are missing (templates, scripts) are added beside it. If `.claude/skills` is a symlink to `.cursor/skills`, the
131
152
  log says so, and the skills are written there.
@@ -156,9 +177,9 @@ or `CLAUDE.md` already has), so it is safe to run on a project with its own agen
156
177
  changes.
157
178
  - **The grader runs on Opus.** The code it grades was written by Sonnet coders, so a different, stronger model gives
158
179
  a more independent review.
159
- - **SDD is opt-in.** The global workflow uses SDD only when a project's `AGENTS.md` / `CLAUDE.md` adopts the Phase Gate
160
- Protocol, or when you ask for the `sdd-feature` skill directly. Projects that don't want gates just leave the rule
161
- out.
180
+ - **SDD is included by default.** A standard installation adds its skill, grader and Phase Gate Protocol.
181
+ Pass `--without sdd` to omit those additions. Existing developer-owned files and rules are not removed by this
182
+ flag. The workflow activates SDD when the project adopts the protocol or explicitly invokes the skill.
162
183
  - **Gates and gate status.** SDD gates stay between the orchestrator and the user. The gate status is recorded in
163
184
  `memory/activeContext.md`, so a new session resumes at the right gate.
164
185
 
@@ -22,7 +22,7 @@ printf '\n@/path/to/agent-guild/development-workflow.md\n' >> ~/.claude/CLAUDE.m
22
22
 
23
23
  Orchestrator model: either globally, in `~/.claude/settings.json`, replace `"model": "opusplan"` with
24
24
  `"model": "sonnet"`; or only for a project, with `"model": "sonnet"` in its `.claude/settings.json` (or
25
- `.claude/settings.local.json` to keep it personal). The installer does the latter by default.
25
+ `.claude/settings.local.json` to keep it personal). The installer defaults an absent project model to Sonnet and preserves existing project/local preferences.
26
26
 
27
27
  jevmem's own settings (API key or local model, `~/.jevmem/config.jsonc`) and its embedding model are per machine
28
28
  either way:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agent-guild"
3
- version = "1.3.0"
3
+ version = "1.3.2"
4
4
  description = "A multi-agent setup for Claude Code, Cursor and Codex (orchestrator + architect, coder, grader, utility subagents) with memory-bank, jevmem and Spec-Driven Development wired in, installed into a project with one command."
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -16,7 +16,7 @@ classifiers = [
16
16
  "Topic :: Software Development",
17
17
  ]
18
18
  requires-python = ">=3.11"
19
- dependencies = []
19
+ dependencies = ["PyYAML>=6.0.3,<7"]
20
20
 
21
21
  [project.urls]
22
22
  Homepage = "https://github.com/illescasDaniel/agent-guild"
@@ -51,7 +51,7 @@ def build_parser() -> argparse.ArgumentParser:
51
51
  p.add_argument("project", type=Path, help="path to the project's root")
52
52
  p.add_argument("--tools", metavar="LIST",
53
53
  help=f"comma-separated tools to install for: {', '.join(TOOLS)}. Default: the ones the project already "
54
- "uses (.claude/ or CLAUDE.md, .cursor/, .codex/ or .agents/), or claude when none is found. Each gets "
54
+ "uses (.claude/ or CLAUDE.md, .cursor/, .codex/ or .agents/skills/), or claude when none is found. Each gets "
55
55
  "agents and skills in its own format and folder, and an MCP config")
56
56
  p.add_argument("--without", action="append", default=[], choices=COMPONENTS, metavar="COMPONENT",
57
57
  help=f"leave a component out (repeatable): {', '.join(COMPONENTS)}. "
@@ -64,11 +64,17 @@ def build_parser() -> argparse.ArgumentParser:
64
64
  p.add_argument("--coders-only", action="store_true",
65
65
  help="with --with: install only the language coders (agent, MCP server, routing rule) and leave "
66
66
  "everything else in the project untouched")
67
- p.add_argument("--model", default="sonnet", metavar="ALIAS",
68
- help="the project's main-session model (default: sonnet; 'none' leaves it unset)")
67
+ p.add_argument("--model", metavar="ALIAS",
68
+ help="explicitly set the Claude model; otherwise preserve existing settings, defaulting to sonnet "
69
+ "only when absent; 'none' leaves it unset")
70
+ p.add_argument("--claude-compat", action="store_true",
71
+ help="add a CLAUDE.md @AGENTS.md import for older Claude Code or sessions preferring CLAUDE.md")
69
72
  p.add_argument("--personal-settings", action="store_true",
70
73
  help="write --model and autoMemoryEnabled to .claude/settings.local.json instead of the committed settings.json")
71
- p.add_argument("--keep-auto-memory", action="store_true", help="don't set autoMemoryEnabled=false")
74
+ memory = p.add_mutually_exclusive_group()
75
+ memory.add_argument("--keep-auto-memory", action="store_true", help="don't set autoMemoryEnabled=false")
76
+ memory.add_argument("--disable-auto-memory", action="store_true",
77
+ help="explicitly set autoMemoryEnabled=false; otherwise preserve an existing preference")
72
78
  p.add_argument("--import-auto-memory", action="store_true",
73
79
  help="first import the project's existing Claude auto-memory notes into jevmem (needs jevmem configured)")
74
80
  p.add_argument("--import-cursor-skills", action="store_true",
@@ -102,7 +108,10 @@ def main(argv: list[str] | None = None) -> int:
102
108
  without=frozenset(args.without),
103
109
  with_coders=frozenset(args.with_coders),
104
110
  coders_only=args.coders_only,
105
- model=None if args.model.lower() == "none" else args.model,
111
+ model=None if args.model is None or args.model.lower() == "none" else args.model,
112
+ set_default_model=args.model is None,
113
+ claude_compat=args.claude_compat,
114
+ disable_auto_memory=args.disable_auto_memory,
106
115
  keep_auto_memory=args.keep_auto_memory,
107
116
  personal_settings=args.personal_settings,
108
117
  import_auto_memory=args.import_auto_memory,
@@ -17,6 +17,29 @@ class Ctx:
17
17
  warnings: list[str] = field(default_factory=list)
18
18
  new_paths: list[tuple[Path, bool]] = field(default_factory=list) # (topmost new path, is a directory)
19
19
  edited_existing: list[Path] = field(default_factory=list)
20
+ pending: dict[Path, bytes] = field(default_factory=dict)
21
+
22
+ def exists(self, path: Path) -> bool:
23
+ return path in self.pending or path.exists()
24
+
25
+ def read(self, path: Path) -> bytes:
26
+ return self.pending[path] if path in self.pending else path.read_bytes()
27
+
28
+ def write(self, path: Path, data: bytes):
29
+ if path.exists() and not path.is_file():
30
+ raise SystemExit(f"error: {path} must be a file")
31
+ for parent in path.parents:
32
+ if parent.exists() and not parent.is_dir():
33
+ raise SystemExit(f"error: {parent} must be a directory")
34
+ self.pending[path] = data
35
+
36
+ def apply(self):
37
+ """Apply only after every source and generated configuration has been checked."""
38
+ if self.dry_run:
39
+ return
40
+ for path, data in self.pending.items():
41
+ path.parent.mkdir(parents=True, exist_ok=True)
42
+ path.write_bytes(data)
20
43
 
21
44
  def log(self, status: str, path: Path | str, note: str = "") -> None:
22
45
  shown = path
@@ -43,8 +66,8 @@ class Ctx:
43
66
 
44
67
  def write_bytes(ctx: Ctx, dest: Path, data: bytes) -> str:
45
68
  """Create `dest`, or replace it only with --force. Never overwrites a file that differs by default."""
46
- if dest.exists():
47
- if dest.read_bytes() == data:
69
+ if ctx.exists(dest):
70
+ if ctx.read(dest) == data:
48
71
  ctx.log("unchanged", dest)
49
72
  return "unchanged"
50
73
  if not ctx.force:
@@ -55,9 +78,7 @@ def write_bytes(ctx: Ctx, dest: Path, data: bytes) -> str:
55
78
  else:
56
79
  status = "created"
57
80
  ctx.track_new(dest)
58
- if not ctx.dry_run:
59
- dest.parent.mkdir(parents=True, exist_ok=True)
60
- dest.write_bytes(data)
81
+ ctx.write(dest, data)
61
82
  ctx.log(status if not ctx.dry_run else f"would {status.removesuffix('d')}", dest)
62
83
  return status
63
84
 
@@ -69,11 +90,11 @@ def copy_tree(ctx: Ctx, src: Path, dest: Path) -> None:
69
90
  write_bytes(ctx, dest / item.relative_to(src), item.read_bytes())
70
91
 
71
92
 
72
- def read_json(path: Path) -> tuple[dict[str, Any], str]:
93
+ def read_json(path: Path, ctx: Ctx | None = None) -> tuple[dict[str, Any], str]:
73
94
  """Return (data, indent). Missing file -> ({}, two spaces). Matches the file's existing indent style."""
74
- if not path.exists():
95
+ if not (ctx.exists(path) if ctx else path.exists()):
75
96
  return {}, " "
76
- text = path.read_text(encoding="utf-8")
97
+ text = ctx.read(path).decode("utf-8") if ctx else path.read_text(encoding="utf-8")
77
98
  if not text.strip():
78
99
  return {}, " "
79
100
  try:
@@ -90,12 +111,10 @@ def write_json(ctx: Ctx, path: Path, data: dict[str, Any], indent: str, changes:
90
111
  if not changes:
91
112
  ctx.log("unchanged", path)
92
113
  return
93
- verb = "edit" if path.exists() else "create"
114
+ verb = "edit" if ctx.exists(path) else "create"
94
115
  if verb == "edit":
95
116
  ctx.edited_existing.append(path)
96
117
  else:
97
118
  ctx.track_new(path)
98
- if not ctx.dry_run:
99
- path.parent.mkdir(parents=True, exist_ok=True)
100
- path.write_text(json.dumps(data, indent=indent, ensure_ascii=False) + "\n", encoding="utf-8")
119
+ ctx.write(path, (json.dumps(data, indent=indent, ensure_ascii=False) + "\n").encode("utf-8"))
101
120
  ctx.log(f"would {verb}" if ctx.dry_run else ("edited" if verb == "edit" else "created"), path, "+ " + ", ".join(changes))