Skip to content

Conversation

@ammar-agent
Copy link
Collaborator

@ammar-agent ammar-agent commented Oct 26, 2025

Problem Statement

Recent runtime refactoring broke AGENTS.md forwarding. The real issue: SSH workspaces may not have AGENTS.md cloned yet, causing instruction loading to fail.

Solution

Workspace-first with project fallback using Runtime abstraction:

  1. Try reading AGENTS.md from workspace via Runtime.readFile() (supports SSH)
  2. Fallback to project root AGENTS.md if workspace doesn't exist
  3. Always layer global instructions (~/.cmux/AGENTS.md)

Key Design Decisions

Instruction Layering

  • Global: Always included (layered)
  • Project: Either workspace OR project AGENTS.md (mutually exclusive, not layered)
  • Workspace instructions replace project instructions when they exist

Unified FileReader Abstraction

Created a single abstraction that eliminates duplication between local filesystem and Runtime:

  • readInstructionSet() - for local directories
  • readInstructionSetFromRuntime() - for Runtime-based access (SSH support)
  • Both share the same implementation via FileReader interface

Code Quality Improvements

  • -113 lines total (-28%)
  • systemMessage.ts: 237 → 120 lines (-49%)
  • Eliminated ~60 lines of duplicated helper functions
  • Cleaner architecture with centralized file reading logic

Testing

  • ✅ All tests passing (16/16 with 26 assertions)
  • ✅ Static checks (lint/typecheck/fmt)
  • ✅ Documentation updated

Generated with cmux

Design decision: Read AGENTS.md from projectPath (project root) instead of
workspacePath (individual workspace/worktree directories).

Rationale:
- Ensures consistent instructions across all workspaces for a project
- Simplifies mental model: one AGENTS.md per project, not per branch
- Aligns with typical workflow where instructions are project-level context
- Still allows workspace-specific overrides via AGENTS.local.md (gitignored)

Changes:
- buildSystemMessage() now reads AGENTS.md from metadata.projectPath
- Environment context still uses workspacePath (where code executes)
- Updated docs/instruction-files.md to reflect project-level instructions
- Updated all tests to use projectDir instead of workspaceDir
- Renamed test variables for clarity

Breaking change: Branch-specific AGENTS.md files will no longer be read.
Migration: Move workspace-specific instructions to project root AGENTS.md,
or use AGENTS.local.md for personal/workspace-specific overrides.
Add Runtime abstraction support for reading AGENTS.md from workspaces,
with graceful fallback to project root when workspace file doesn't exist.

Problem:
- SSH workspaces are on remote machines, can't use local fs.readFile()
- AGENTS.md may not be cloned into SSH workspace yet
- Need to support both local worktrees and remote SSH workspaces

Solution:
- Add runtime parameter to buildSystemMessage()
- Read workspace AGENTS.md using Runtime.readFile() (works for SSH)
- Fall back to project root AGENTS.md if workspace doesn't have one
- Preserves branch-specific instructions for local workspaces
- Provides sensible defaults for SSH workspaces during clone

Changes:
- buildSystemMessage() now accepts Runtime parameter
- New readInstructionSetFromRuntime() uses runtime to read workspace files
- Instruction priority: global → workspace (if exists) → project (fallback)
- Mode section priority: workspace → project → global
- Updated docs/instruction-files.md to reflect fallback behavior
- Updated all tests to pass runtime parameter
- Updated aiService.ts to pass runtime to buildSystemMessage()

This preserves existing test behavior (workspace-specific instructions work)
while adding robustness for SSH workspaces where files may not exist yet.
@ammar-agent ammar-agent force-pushed the rt-agents-md branch 3 times, most recently from 363d879 to d58b67b Compare October 26, 2025 21:02
Make it clear that workspace and project instructions are mutually exclusive:
- Global instructions are always layered
- Workspace instructions REPLACE project instructions (not layered)
- Project instructions are only used as fallback when workspace doesn't exist

Changes:
- Simplified logic to only read project if workspace doesn't exist
- Updated comments to emphasize replacement vs layering
- Updated documentation to make behavior crystal clear
- Mode extraction only checks workspace OR project, not both
Extract readFileWithLocalVariantFromRuntime() to match the pattern used
by readFileWithLocalVariant() for local files. This eliminates code
duplication and makes the runtime-based reading follow the same structure.
- Created FileReader interface to eliminate duplication between fs and Runtime
- Moved all instruction reading logic to instructionFiles.ts
- Removed 117 lines from systemMessage.ts (-49%)
- Simplified helper function structure with shared implementation
- Removed redundant tests for private helpers (covered by public API)

Net change: -113 lines across 3 files (-28%)
All tests passing (16/16)
@ammar-agent ammar-agent changed the title 🤖 Change AGENTS.md to read from project root, not workspace refactor: workspace-first AGENTS.md loading with unified file reader Oct 27, 2025
@ammario ammario merged commit c564e72 into main Oct 27, 2025
15 checks passed
@ammario ammario deleted the rt-agents-md branch October 27, 2025 01:33
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