This fixes a regression where sandboxed environments (like Windows bwrap) would crash when attempting to bind the plans directory if it was lazily created after the sandbox was initialized. Additionally, documented the sticky extension context logic in AppContainer to address code review feedback.
Resolves conflict in packages/core/src/tools/enter-plan-mode.test.ts by removing an assertion for directory creation, which has been centralized in config.ts in this branch.
Adds a hard limit to the while(true) loop in claimNewSlug to prevent tests from hanging indefinitely when fs.existsSync is mocked improperly. Refines error typing in the rename retry block to strictly use isNodeError.
Introduces a retry mechanism for fs.promises.rename when saving the project registry. This resolves a known concurrency issue on Windows CI runners where multiple processes spinning up simultaneously during E2E tests cause file lock contention.
Moves the getErrorMessage import to the top of config.ts to avoid circularity-induced TS2304 in some environments. Also fixes a TypeError in sandbox_command.js when modern object-style sandbox settings are used in settings.json.
Addressed reviewer feedback by replacing process.stderr.write with debugLogger.error in config.ts and using isNodeError in storage.ts to adhere to codebase standards.
Address review bot feedback to prevent EACCES errors during startup by restricting filesystem mutation and workspace context registration to when the user is actively in an interactive plan session. Non-plan tool registration now uses the safely resolved path without attempting to create the directory.
This addresses a potential TOCTOU vulnerability and edge case identified during review. The redundant `fs.existsSync` check in `getPlansDir` has been removed, allowing `fs.mkdirSync(..., { recursive: true })` to safely handle directory idempotency.
By relying directly on `mkdirSync`, we ensure that if a non-directory file already exists at the target path, the system will correctly throw an `EEXIST` error rather than silently treating the file as a directory and crashing later during workspace registration.
This commit addresses two bugs identified during review:
1. Cleared the sticky `activeExtensionContext` when the standard `/plan` command is executed, ensuring subsequent prompts correctly target the default global plan directory.
2. Fixed a path resolution regression in `Storage.getPlansDir()` by constructing the fallback ENOENT path directly against the real project root. This prevents `isSubpath` validation failures and potential traversal vulnerabilities when the project root is a symlink.
Updates prompts and tool implementations (edit, write-file, enter/exit plan mode) to route through Config.getPlansDir() instead of Storage.getPlansDir(). This ensures the plan directory is lazily created exactly when these features attempt to use it, preventing ENOENT failures.
Introduces active extension context tracking in config to support dynamic switching of plan directories. Resolves circular dependency in storage by deferring plan directory creation until on-demand use, preventing ENOENT errors on non-existent paths.