Skip to content

Resolve symlinked AGENTS context files#65

Merged
Waishnav merged 2 commits into
mainfrom
codex/issue-58-agents-symlink
Jul 7, 2026
Merged

Resolve symlinked AGENTS context files#65
Waishnav merged 2 commits into
mainfrom
codex/issue-58-agents-symlink

Conversation

@Waishnav

@Waishnav Waishnav commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

  • reread initially loaded AGENTS/CLAUDE context files through their resolved filesystem target
  • avoid advertising a symlink target as an additional available AGENTS file when the symlink was already loaded
  • cover a symlinked global AGENTS.md in workspace tests

Fixes #58.

Tests

  • npx tsx src/workspaces.test.ts
  • npm run typecheck
  • npm test

Summary by CodeRabbit

  • Bug Fixes

    • Improved initial agent context loading to reliably handle symlinked files by resolving real paths and consistently filtering valid agent context files.
    • Prevented duplicate agent context entries when the same file is discovered through multiple paths.
    • Added safer fallback behavior if path resolution or reading fails.
  • Tests

    • Expanded workspace tests to cover nested directories, symlinks, and an “unsafe” agent directory scenario, with platform-specific handling for Windows.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Updates workspace agent-file loading to resolve symlinks before reading content, avoid duplicate discovery by resolved path, and extend tests for symlinked and unsafe AGENTS.md setups.

Changes

Symlink-aware AGENTS.md loading

Layer / File(s) Summary
Realpath reading helpers
src/workspaces.ts
Adds filesystem imports and helper functions for checking initial agent file paths, resolving realpaths, and reading resolved UTF-8 content with fallback behavior.
Async initial file loading
src/workspaces.ts
createWorkspaceContext awaits loadInitialAgentsFiles, and initial context files are loaded through realpath resolution before available agent discovery runs.
Realpath deduping and test coverage
src/workspaces.ts, src/workspaces.test.ts
findAvailableAgentsFiles skips discovered context files whose realpath matches an already loaded file, and tests create a symlinked AGENTS.md layout plus an unsafe outside-root symlink case.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

  • Waishnav/devspace#55 — Also changes createWorkspaceContext flow in src/workspaces.ts, but for loading and exposing agentProfiles.

Poem

A rabbit found a symlinked trail,
Then sniffed the realpath through the veil.
No double hops, no spooky blur,
Just honest words where agents were.
Hop hop! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: resolving symlinked AGENTS context files.
Linked Issues check ✅ Passed The PR resolves symlinked AGENTS.md targets and adds coverage for the global symlink case, matching #58's expected behavior.
Out of Scope Changes check ✅ Passed The changes stay focused on AGENTS symlink handling and related tests, with no obvious unrelated functionality added.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-58-agents-symlink

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/workspaces.ts`:
- Around line 249-264: The symlink handling in loadInitialAgentsFiles() can load
files outside the workspace because it resolves the path and reads it without
verifying the target stays under root or agentDir. Add a containment check after
resolve() and before readResolvedContextFile() using the existing
isInitialAgentsFilePath() flow, and skip or safely ignore any AGENTS.md target
that resolves outside the allowed roots.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3f0c2ec3-6447-4da6-a3ed-cd62c1f3cb39

📥 Commits

Reviewing files that changed from the base of the PR and between d031874 and 71d7f07.

📒 Files selected for processing (2)
  • src/workspaces.test.ts
  • src/workspaces.ts

Comment thread src/workspaces.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/workspaces.test.ts (1)

83-102: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider also asserting on availableAgentsFiles for the unsafe symlink case.

The test confirms the rejected symlink's content isn't loaded into agentsFiles, but doesn't verify whether unsafeWorkspace.availableAgentsFiles still surfaces unsafeAgentDir/AGENTS.md as a discoverable entry. Since the symlink is rejected rather than loaded, it's never added to loadedRealPaths in findAvailableAgentsFiles, so it may still appear in the discovered list. Asserting on this would close the loop on the "don't list an already-resolved symlink twice / expose stale/escaped paths" behavior described in the PR objective.

assert.deepEqual(
  unsafeWorkspace.agentsFiles.map((file) => file.content),
  ["root instructions\n"],
);
+assert.deepEqual(
+  unsafeWorkspace.availableAgentsFiles.map((file) => file.path),
+  [/* expected discovered paths */],
+);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/workspaces.test.ts` around lines 83 - 102, The unsafe symlink test only
verifies agentsFiles content, so extend it to also assert
unsafeWorkspace.availableAgentsFiles for the rejected symlink case. Use
WorkspaceRegistry.openWorkspace and findAvailableAgentsFiles behavior to confirm
whether the symlinked AGENTS.md is still discovered or intentionally excluded,
and update the expected discovered paths accordingly to cover the stale/escaped
path handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/workspaces.test.ts`:
- Around line 83-102: The unsafe symlink test only verifies agentsFiles content,
so extend it to also assert unsafeWorkspace.availableAgentsFiles for the
rejected symlink case. Use WorkspaceRegistry.openWorkspace and
findAvailableAgentsFiles behavior to confirm whether the symlinked AGENTS.md is
still discovered or intentionally excluded, and update the expected discovered
paths accordingly to cover the stale/escaped path handling.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a2650fb7-936c-409a-8581-5039d2619042

📥 Commits

Reviewing files that changed from the base of the PR and between 71d7f07 and 94afa09.

📒 Files selected for processing (2)
  • src/workspaces.test.ts
  • src/workspaces.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/workspaces.ts

@Waishnav Waishnav merged commit 8cb4c1d into main Jul 7, 2026
2 of 4 checks passed
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.

Global AGENTS.md symlink is surfaced as symlink blob instead of resolved file contents

1 participant