Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 11 additions & 6 deletions agent/agentcontext/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,17 @@
// "RFC: Workspace Context Sources for Coder Agents". It owns:
//
// - User-declared scan roots (Sources) layered on top of
// built-in defaults.
// - A resolver that classifies files under each scan root into
// typed Resources (instruction files, skills, MCP configs,
// MCP servers).
// - A unified recursive fsnotify watcher that signals a
// re-resolve when any recognized file changes.
// built-in defaults and the working directory.
// - A resolver that classifies files at fixed locations under
// each scan root into typed Resources (instruction files,
// skills, MCP configs, MCP servers). Discovery is shallow:
// instruction files (AGENTS.md, CLAUDE.md, .cursorrules) and
// .mcp.json are read only at a scan root's top level, skills
// only from fixed container directories (skills, .agents/skills,
// .claude/skills, .codex/skills), and the resolver never walks
// the tree downward or up to a parent directory.
// - A fixed-location fsnotify watcher that signals a re-resolve
// when any recognized file changes.
// - An HTTP API at /api/v0/context/sources for source CRUD
// and /api/v0/context/resync for synchronous push barriers.
// - A Pusher abstraction so the latest Snapshot can be shipped
Expand Down
8 changes: 7 additions & 1 deletion agent/agentcontext/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ func (m *Manager) Run(ctx context.Context) error {
Logger: m.logger.Named("watcher"),
Clock: m.clock,
Debounce: m.debounce,
MaxDepth: m.resolver.MaxDepth,
OnChange: m.signal,
})
if err != nil {
Expand Down Expand Up @@ -561,6 +560,13 @@ func (m *Manager) scanRootsLocked() []ScanRoot {
out := make([]ScanRoot, 0, 1+len(builtinRoots)+len(m.sources))
if m.workingDir != nil {
if wd := strings.TrimSpace(m.workingDir()); wd != "" {
// The working directory is a single scan root. The
// resolver reads its top-level instruction files and
// .mcp.json plus the fixed skill containers under it;
// it neither descends into subdirectories nor climbs
// to parent directories. Additional directories are
// added explicitly as Sources or via the seeding env
// vars.
out = append(out, ScanRoot{Path: wd})
}
}
Expand Down
31 changes: 31 additions & 0 deletions agent/agentcontext/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,3 +437,34 @@ func TestManager_MCPResourcesAppliesToSnapshot(t *testing.T) {
}
require.True(t, found, "expected MCP server resource in snapshot")
}

// TestManager_WorkingDirScannedShallow confirms the working
// directory is a single scan root: its top-level instruction files
// are read, but the resolver neither climbs to an ancestor (no
// walk-up to a .git project root) nor descends into subdirectories.
func TestManager_WorkingDirScannedShallow(t *testing.T) {
t.Parallel()
root := testutil.TempDirResolved(t)
require.NoError(t, os.MkdirAll(filepath.Join(root, ".git"), 0o755))
mustWriteFile(t, filepath.Join(root, "AGENTS.md"), "root rules")
cwd := filepath.Join(root, "service")
require.NoError(t, os.MkdirAll(cwd, 0o755))
mustWriteFile(t, filepath.Join(cwd, "AGENTS.md"), "service rules")
// A subdirectory below the working dir must not be descended.
mustWriteFile(t, filepath.Join(cwd, "nested", "AGENTS.md"), "nested rules")

m := newTestManager(t, agentcontext.ManagerOptions{
WorkingDir: func() string { return cwd },
})

snap := m.Snapshot()
var sources []string
for _, r := range snap.Resources {
if r.Kind == agentcontext.KindInstructionFile {
sources = append(sources, r.Source)
}
}
// Only the working directory's own AGENTS.md is present: the
// ancestor root and the nested subdirectory are both excluded.
require.Equal(t, []string{filepath.Join(cwd, "AGENTS.md")}, sources)
}
Loading
Loading