feat(agent): isolate agent cwd in .ideai/run/<id> to kill convention-file collisions
ARCHITECTURE §14.1: an agent's PTY cwd is now its own
`<project_root>/.ideai/run/<agent-id>/` directory, never the project root, so
N agents of the same profile no longer collide on a single conventional file
(CLAUDE.md/AGENTS.md/...).
- profile: cwd_template is now "{agentRunDir}" (built-in catalogue + docs).
- runtime: resolve_cwd substitutes {agentRunDir} (legacy {projectRoot} kept).
- LaunchAgent: computes + creates the run dir via FileSystem::create_dir_all,
passes it as the cwd base to the pure prepare_invocation. Contract chosen:
pass run_dir as the `cwd` argument (no PreparedContext change) — keeps
prepare_invocation pure, I/O stays in the use case.
- convention file is generated by IdeA inside the run dir via a pure
compose_convention_file(project_root, agent_md): absolute project-root header
+ agent persona (extensible for skills, §14.2).
- .gitignore: ignore .ideai/run/.
- run-dir cleanup left as a TODO (FileSystem port exposes no delete).
Tests: anti-collision (2 agents -> 2 distinct cwd, 2 distinct convention files,
none at root), run-dir creation order, composed convention file; pure unit
tests for agent_run_dir + compose_convention_file; runtime {agentRunDir}
substitution. cargo test --workspace + clippy -D warnings green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -53,7 +53,7 @@ pub fn reference_profiles() -> Vec<AgentProfile> {
|
||||
ContextInjection::convention_file("CLAUDE.md")
|
||||
.expect("CLAUDE.md is a valid convention target"),
|
||||
Some("claude --version".to_owned()),
|
||||
"{projectRoot}",
|
||||
"{agentRunDir}",
|
||||
)
|
||||
.expect("claude reference profile is valid"),
|
||||
AgentProfile::new(
|
||||
@ -64,7 +64,7 @@ pub fn reference_profiles() -> Vec<AgentProfile> {
|
||||
ContextInjection::convention_file("AGENTS.md")
|
||||
.expect("AGENTS.md is a valid convention target"),
|
||||
Some("codex --version".to_owned()),
|
||||
"{projectRoot}",
|
||||
"{agentRunDir}",
|
||||
)
|
||||
.expect("codex reference profile is valid"),
|
||||
AgentProfile::new(
|
||||
@ -75,7 +75,7 @@ pub fn reference_profiles() -> Vec<AgentProfile> {
|
||||
ContextInjection::convention_file("GEMINI.md")
|
||||
.expect("GEMINI.md is a valid convention target"),
|
||||
Some("gemini --version".to_owned()),
|
||||
"{projectRoot}",
|
||||
"{agentRunDir}",
|
||||
)
|
||||
.expect("gemini reference profile is valid"),
|
||||
AgentProfile::new(
|
||||
@ -86,7 +86,7 @@ pub fn reference_profiles() -> Vec<AgentProfile> {
|
||||
ContextInjection::flag("--message-file {path}")
|
||||
.expect("aider flag template is non-empty"),
|
||||
Some("aider --version".to_owned()),
|
||||
"{projectRoot}",
|
||||
"{agentRunDir}",
|
||||
)
|
||||
.expect("aider reference profile is valid"),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user