Skip to content

fix(sdk): wire FSStorageProvider rootDir in resolveSquadState, fix teamRoot='.' sentinel (#1555) - #1695

Merged
bradygaster merged 2 commits into
devfrom
squad/1555-fs-storage-rootdir
Aug 23, 2026
Merged

fix(sdk): wire FSStorageProvider rootDir in resolveSquadState, fix teamRoot='.' sentinel (#1555)#1695
bradygaster merged 2 commits into
devfrom
squad/1555-fs-storage-rootdir

Conversation

@bradygaster

Copy link
Copy Markdown
Owner

Maintainer re-submission of #1666

Credit: This fix is entirely the work of @omercangumus. This PR is a maintainer-owned replacement opened solely because GitHub's update-branch API returns 403 for fork-based PRs, so the original branch could not be updated non-destructively. No code changes have been made — the contributor commit bbf97e1c is cherry-picked verbatim with original author attribution preserved (Author: Ömer Can Gümüş <omercangumus3@gmail.com>).

Supersedes: #1666 (do not merge #1666; it may be closed once this merges)


What

resolveSquadState() now constructs the local-backend FSStorageProvider with rootDir set, and resolveSquadPaths() treats config.teamRoot === '.' as local mode instead of remote mode.

Why

Closes #1555

Two independent defects in the same path, both live on dev, both hit by squad_decide/squad_state_* (the MCP state tools wired up in state-mcp.ts):

  1. resolveSquadState() built the local backend's storage as new FSStorageProvider() — no rootDir. FSStorageProvider's traversal guard is if (!this.rootDir) return filePath; — an unset rootDir makes it a no-op.
  2. resolveSquadPaths()'s remote-mode check is if (config && config.teamRoot). squad externalize writes teamRoot: '.' as its "no separate team root" marker — but '.' is truthy, so this resolved teamDir = path.resolve(projectRoot, '.') = one directory above .squad/.

How

  • resolution.ts resolveSquadState(): new FSStorageProvider(paths.teamDir)
  • resolution.ts resolveSquadPaths(): if (config && config.teamRoot && config.teamRoot !== '.')

Files changed

  • packages/squad-sdk/src/resolution.ts — product fix (2 lines changed)
  • test/state-backend.test.ts — regression tests (+46 lines)
  • .changeset/1555-fs-storage-rootdir.md — patch changeset for @bradygaster/squad-sdk

Validation (maintainer re-run on current dev base)

  • npx vitest run test/state-backend.test.ts147/147 passed
  • cd packages/squad-sdk && npm run buildclean
  • cd packages/squad-cli && npm run buildclean
  • Diff vs origin/dev: 3 files, 61 insertions, 3 deletions, no file deletions, single commit ✅

Co-authored-by: Ömer Can Gümüş omercangumus3@gmail.com
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

…amRoot='.' sentinel

Fixes #1555

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings August 12, 2026 23:51
@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit e92b5d8

PR Scope: 📦🔧 Mixed (product + infrastructure)

⚠️ 3 item(s) to address before review

Status Check Details
Single commit 2 commits — consider squashing before review
Not in draft Ready for review
Branch up to date dev is 2 commit(s) ahead — rebase recommended
Copilot review No Copilot review yet — it may still be processing
Changeset present Changeset file found
Scope clean No .squad/ or docs/proposals/ files
No merge conflicts No merge conflicts
Copilot threads resolved No Copilot review threads
CI passing All checks passing

Files Changed (3 files, +61 −3)

File +/−
.changeset/1555-fs-storage-rootdir.md +5 −0
packages/squad-sdk/src/resolution.ts +10 −2
test/state-backend.test.ts +46 −1

Total: +61 −3


This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.

@github-actions

Copy link
Copy Markdown
Contributor

🟡 Impact Analysis — PR #1695

Risk tier: 🟡 MEDIUM

📊 Summary

Metric Count
Files changed 3
Files added 1
Files modified 2
Files deleted 0
Modules touched 3

🎯 Risk Factors

  • 3 files changed (≤5 → LOW)
  • 3 modules touched (2-4 → MEDIUM)

📦 Modules Affected

root (1 file)
  • .changeset/1555-fs-storage-rootdir.md
squad-sdk (1 file)
  • packages/squad-sdk/src/resolution.ts
tests (1 file)
  • test/state-backend.test.ts

This report is generated automatically for every PR. See #733 for details.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes two related path-resolution defects in the Squad SDK’s state/tooling path so local-backend state writes are correctly confined under the resolved squad/team directory, including externalized projects using teamRoot: "." as a sentinel.

Changes:

  • Wire FSStorageProvider with rootDir = paths.teamDir when resolving local state storage.
  • Treat config.teamRoot === "." as local mode (not remote) during path resolution.
  • Add regression tests covering teamRoot: ".", traversal guarding, and an end-to-end squad_decide write via ToolRegistry.
Show a summary per file
File Description
packages/squad-sdk/src/resolution.ts Fixes teamRoot: "." mode detection and sets FSStorageProvider rootDir for local backend storage.
test/state-backend.test.ts Adds regression coverage ensuring teamDir is .squad/, traversal escapes are blocked, and squad_decide writes to .squad/decisions/inbox/.
.changeset/1555-fs-storage-rootdir.md Patch changeset documenting the bugfix and its impact on MCP state tools.

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Lite

@github-actions

Copy link
Copy Markdown
Contributor

👋 Friendly nudge — this PR has had no activity for 7 days.

What needs attention:

  • 🔴 1 CI check(s) failing: test. Fix these first.
  • 👀 No approving reviews yet. Request a review from a teammate.
  • ⬇️ 29 commits behind dev. Rebase to pick up latest changes.

If this PR is abandoned, please close it. If it's blocked on something external, leave a comment so the team knows.
This is an automated check that runs on weekdays. It won't nudge the same PR more than once per week.

Copilot stopped work on behalf of omercangumus due to an error August 20, 2026 18:38
@bradygaster
bradygaster merged commit 0842655 into dev Aug 23, 2026
17 checks passed
@bradygaster
bradygaster deleted the squad/1555-fs-storage-rootdir branch August 23, 2026 18:03
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.

FSStorageProvider constructed without rootDir in resolveSquadState() — state writes land in repo root instead of .squad/

3 participants