fix: derive plan path from feature.json in update-agent-context#3069
fix: derive plan path from feature.json in update-agent-context#3069amirreza225 wants to merge 5 commits into
Conversation
When `plan_path` is omitted, prefer `.specify/feature.json` (written by /speckit-specify) over the mtime heuristic. The old approach picked the most recently modified `specs/*/plan.md`, which could inject an unrelated plan into CLAUDE.md if another spec's plan was touched after the active feature directory was created but before its own plan.md existed. Bash: handle both relative and absolute feature_directory values, normalizing absolute paths back to project-relative for the context file. Fall back to mtime only when feature.json is absent or the derived plan.md does not yet exist. PowerShell: same logic, PS 5.1-compatible (nested Join-Path, IsPathRooted guard to avoid Unix Join-Path mis-joining absolute ChildPaths, manual prefix-strip instead of GetRelativePath). Fixes github#3067
There was a problem hiding this comment.
Pull request overview
This PR updates the agent-context extension’s context refresh scripts so that, when no explicit plan_path argument is provided, they derive the active plan.md from .specify/feature.json (written by /speckit-specify) and only fall back to the “most recently modified specs/*/plan.md” heuristic when that source is unavailable or not yet present. It also adds tests to validate the new feature.json-first behavior.
Changes:
- Bash: Prefer
.specify/feature.jsonto resolve the activeplan.md, with mtime fallback retained. - PowerShell: Implement the same “feature.json-first, mtime-second” selection logic and normalize feature paths.
- Tests: Add coverage ensuring feature.json overrides the mtime heuristic (bash + PowerShell where available).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
extensions/agent-context/scripts/bash/update-agent-context.sh |
Uses .specify/feature.json to select the active plan when plan_path isn’t provided; retains mtime fallback. |
extensions/agent-context/scripts/powershell/update-agent-context.ps1 |
Mirrors bash behavior in PowerShell, including absolute-path normalization and mtime fallback. |
tests/extensions/test_update_agent_context_feature_json.py |
Adds tests validating feature.json-first selection and stale-plan avoidance. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
- bash: add explicit encoding="utf-8" to feature.json open() call - powershell: replace GetRelativePath (.NET 5+ only) with manual prefix-strip in mtime fallback for PS 5.1 compatibility - tests: add coverage for absolute feature_directory values (under and outside PROJECT_ROOT)
|
All three Copilot comments have been addressed in commit 80600a2:
All 70 tests pass locally. |
Done |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| $fj = Get-Content -LiteralPath $FeatureJson -Raw -Encoding UTF8 | ConvertFrom-Json | ||
| $featureDir = $fj.feature_directory | ||
| if ($featureDir -is [string]) { $featureDir = $featureDir.TrimEnd('\\', '/') } | ||
| if ($featureDir) { |
Summary
update-agent-context.shandupdate-agent-context.ps1now prefer.specify/feature.json(written by/speckit-specify) over the mtime heuristic when no explicitplan_pathargument is givenspecs/*/plan.mdonly whenfeature.jsonis absent or the derivedplan.mddoes not exist yet (e.g./speckit-planhasn't run yet)feature_directoryvalues in both scripts, normalizing to project-relative paths for the context file outputJoin-Path,IsPathRootedguard (UnixJoin-Pathdoes not treat absolute ChildPaths as "wins"), and manual prefix-strip instead ofGetRelativePathFixes #3067
AI disclosure
This PR was written with AI assistance (Claude Code). All changes were reviewed, tested, and understood by me before submission.
Manual test results
Agent: Claude Code | OS/Shell: macOS/zsh
/speckit.specify→/speckit.planCLAUDE.mdreferences the correct active feature'splan.mdCLAUDE.mdstill points to active feature, not the stale oneTest plan
uv run pytest tests/extensions/test_update_agent_context_feature_json.py— 4 new bash tests pass (2 PS skipped, nopwshon CI)uv run pytest tests/test_agent_config_consistency.py tests/extensions/test_extension_agent_context.py— all 62 existing tests pass