Skip to content

Add agents_md profile field for AGENTS.md content appending - #82

Merged
wpfleger96 merged 5 commits into
mainfrom
worktree-wpfleger-agents-md-profile-merge
Jun 4, 2026
Merged

Add agents_md profile field for AGENTS.md content appending#82
wpfleger96 merged 5 commits into
mainfrom
worktree-wpfleger-agents-md-profile-merge

Conversation

@wpfleger96

@wpfleger96 wpfleger96 commented Jun 4, 2026

Copy link
Copy Markdown
Owner

This PR adds an agents_md field to profiles that appends profile-specific content to the base AGENTS.md at install time, enabling per-profile agent hints (e.g., work VPN instructions, team-specific tooling).

AGENTS.md was previously a pure symlink to a static base file shared identically across all profiles. There was no way to add profile-specific context without editing the base file directly. Content accumulates through the inheritance chain (parent first, child appends) so default → personal → work layering works naturally.

  • Add agents_md: str = "" to Profile with inheritance accumulation, validation, and display in profile show --resolved
  • SharedAgent builds a merged file (base AGENTS.md + profile content) at ~/.ai-agent-rules/cache/shared/AGENTS.md and redirects ~/AGENTS.md there when agents_md is truthy; all other agents resolve transitively via @~/AGENTS.md includes
  • New AgentsMdComponent manages the cache lifecycle (build, staleness detection via content comparison, diff display, uninstall) as infrastructure before ConfigComponent, consistent with SettingsComponent
  • Config.cleanup_orphaned_cache internally protects cache/shared/ from deletion when agents_md is set
  • Fix CodexAgent to use config/codex/AGENTS.md containing @~/AGENTS.md, aligning it with the indirection pattern every other agent already uses
  • Auto-include SharedAgent in filtered installs (--agents codex) since all agents depend on ~/AGENTS.md transitively
  • Extract format_unified_diff() in symlinks.py as a shared helper for Rich-formatted unified diffs, replacing duplicated formatting loops in get_content_diff(), get_cache_diff(), and McpManager.format_diff()
  • Fix MCP format_diff argument order (installed→expected) and restore dropped server name header; fix ctx.consoleconsole for output buffering
  • Add work profile agents_md content with VPN/uv package resolution hints

The base AGENTS.md is shared across all agents and profiles with no way
to add profile-specific context (e.g., work VPN hints, team tooling).

New `agents_md` field on profiles accumulates through the inheritance
chain (parent first, child appends) and is merged with the base file at
install time, written atomically to `~/.ai-agent-rules/cache/shared/AGENTS.md`,
and symlinked from `~/AGENTS.md`. All other agents resolve transitively
through `~/AGENTS.md` via `@` includes so no per-agent changes are needed.
Also fixes CodexAgent, which was the only agent pointing its AGENTS.md
symlink directly at the base file instead of using `@~/AGENTS.md` like
every other agent.
Mypy flagged `get_merged_agents_md_path()` returning `Path | None` in
the `symlinks` property — assert non-None when `needs_agents_md_cache`
is true (the two conditions are logically equivalent). E2E fixture was
missing `codex/AGENTS.md` in the config dir, same gap already fixed in
the unit conftest.
@wpfleger96
wpfleger96 force-pushed the worktree-wpfleger-agents-md-profile-merge branch from 1f565d2 to 76e1551 Compare June 4, 2026 16:51
@wpfleger96
wpfleger96 marked this pull request as ready for review June 4, 2026 16:51
wpfleger96 and others added 3 commits June 4, 2026 13:42
…che diff

The Rich-formatted unified diff logic was duplicated verbatim between
get_content_diff() and get_cache_diff(). Extract into a single
format_unified_diff() helper in symlinks.py, refactor all three
callers (symlinks, targets, MCP), and wire up AgentsMdComponent to
show actual content diffs instead of just "stale." MCP diffs now get
the same green/red coloring as all other components.

Also adds agents_md content to the work profile for VPN/uv hints.
- Fix MCP format_diff argument order (installed→expected, not reversed)
  and restore dropped server name header in diff output
- Fix ctx.console → console in MCP status to respect output buffering
- Extract get_expected_agents_md_content() on SharedAgent, eliminating
  3x duplicated merge logic and handling empty base AGENTS.md correctly
- Simplify is_agents_md_cache_stale() to pure content comparison,
  removing mtime checks with parent-profile blind spot
- Auto-include SharedAgent in filtered installs (--agents codex) since
  all agents depend on ~/AGENTS.md via @-includes
- Add agents_md to README profile key documentation
- Fix ruff format-check CI failure
@wpfleger96
wpfleger96 merged commit 169407f into main Jun 4, 2026
9 checks passed
@wpfleger96
wpfleger96 deleted the worktree-wpfleger-agents-md-profile-merge branch June 4, 2026 18:33
wpfleger96 added a commit that referenced this pull request Jun 4, 2026
* feat: add Sprout persona pack symlink management

The Sprout persona pack living in src/ai_rules/config/sprout/ had no
install logic — the pack only reached Sprout via manual UI import, which
copies files and breaks the single-source-of-truth managed by ai-rules.

Adds a SproutTool target that symlinks the pack directory into both the
production (xyz.block.sprout.app) and dev (xyz.block.sprout.app.dev)
Sprout Application Support paths on macOS. Worktree dev builds inherit
automatically via Sprout's own shared-agent-data symlink mechanism, so
no additional targets are needed.

Also fixes _is_specialized_path() in ConfigComponent to gate on
isinstance(target_owner, Agent) rather than substring-matching path
strings — the old check would have silently filtered Sprout's pack
paths (which contain /agents/) from the config install pipeline.

* Add agents_md profile field for AGENTS.md content appending (#82)

* feat: add agents_md profile field for AGENTS.md content appending

The base AGENTS.md is shared across all agents and profiles with no way
to add profile-specific context (e.g., work VPN hints, team tooling).

New `agents_md` field on profiles accumulates through the inheritance
chain (parent first, child appends) and is merged with the base file at
install time, written atomically to `~/.ai-agent-rules/cache/shared/AGENTS.md`,
and symlinked from `~/AGENTS.md`. All other agents resolve transitively
through `~/AGENTS.md` via `@` includes so no per-agent changes are needed.
Also fixes CodexAgent, which was the only agent pointing its AGENTS.md
symlink directly at the base file instead of using `@~/AGENTS.md` like
every other agent.

* fix: resolve CI failures from agents_md feature

Mypy flagged `get_merged_agents_md_path()` returning `Path | None` in
the `symlinks` property — assert non-None when `needs_agents_md_cache`
is true (the two conditions are logically equivalent). E2E fixture was
missing `codex/AGENTS.md` in the config dir, same gap already fixed in
the unit conftest.

* refactor: extract shared format_unified_diff and wire up AGENTS.md cache diff

The Rich-formatted unified diff logic was duplicated verbatim between
get_content_diff() and get_cache_diff(). Extract into a single
format_unified_diff() helper in symlinks.py, refactor all three
callers (symlinks, targets, MCP), and wire up AgentsMdComponent to
show actual content diffs instead of just "stale." MCP diffs now get
the same green/red coloring as all other components.

Also adds agents_md content to the work profile for VPN/uv hints.

* fix: address crossfire review feedback for agents_md PR

- Fix MCP format_diff argument order (installed→expected, not reversed)
  and restore dropped server name header in diff output
- Fix ctx.console → console in MCP status to respect output buffering
- Extract get_expected_agents_md_content() on SharedAgent, eliminating
  3x duplicated merge logic and handling empty base AGENTS.md correctly
- Simplify is_agents_md_cache_stale() to pure content comparison,
  removing mtime checks with parent-profile blind spot
- Auto-include SharedAgent in filtered installs (--agents codex) since
  all agents depend on ~/AGENTS.md via @-includes
- Add agents_md to README profile key documentation
- Fix ruff format-check CI failure

* refactor: read Sprout pack ID from plugin.json instead of hardcoding

The pack ID was hardcoded as SPROUT_PACK_ID in platform.py, coupling
ai-rules to a specific pack. Now SproutTool reads the id field from
.plugin/plugin.json at runtime, so any pack definition dropped into
config/sprout/ works without code changes. Gracefully returns no
symlinks if the manifest is missing or malformed.

* style: apply ruff formatting to sprout.py

* chore: remove unused avatar PNG source files from sprout pack

Avatars are already base64-encoded inline in the persona .persona.md
frontmatter. The raw PNGs in avatars/ were unreferenced by any pack
file and added 756 KB of dead weight.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants