v2.6.0: pluggable workspace backend + S3-compatible storage#31
Merged
Conversation
Introduces a workspace capability abstraction so built-in tools (read,
write, edit, patch, ls, bash, grep, glob, git, git_stash, git_worktree)
route through trait-based providers instead of hard-coded local
filesystem calls. The default LocalWorkspaceBackend preserves existing
behavior; future remote/browser/DFS/container backends can plug in via
WorkspaceServicesBuilder without changing tool schemas.
Key changes:
- Split workspace.rs into workspace/{mod.rs, local.rs}: trait definitions
+ LocalWorkspaceBackend in separate files (CLAUDE.md file-size rule).
- New traits: WorkspaceFileSystem, WorkspaceCommandRunner, WorkspaceSearch,
WorkspaceGit (slim core) + optional WorkspaceGitStashProvider and
WorkspaceGitWorktreeProvider, CommandOutputObserver.
- WorkspaceServices: assembled via WorkspaceServicesBuilder; auto-downgrades
capabilities when matching providers are missing; carries an optional
per-operation timeout enforced by run_with_timeout helper.
- Capability gating: register_builtins(registry, &capabilities) only
registers tools whose required capability is provided — bash, grep,
glob, git can be hidden from the model when the backend lacks them.
- Local backend now implements WorkspaceCommandRunner (no more
bash-specific local fallback in the tool).
- CommandRequest carries Arc<dyn CommandOutputObserver> instead of leaking
ToolEventSender into the abstraction.
- ChildRunContext propagates workspace_services to child runs.
- New Session direct-tool APIs: write_file, ls, edit_file, patch_file.
- WorkspaceFileSystemExt policy: future trait extensions go to a
separate extension trait (additive only).
- Removed dead WorkspaceCapabilities flags (watch, atomic_write),
unreachable bash fallback branch, set_workspace_services mutation
hazard, redundant ToolExecutor private constructors.
- Deprecated ToolContext::resolve_path / resolve_path_for_write under
non-local backends.
Tests:
- 17 new unit + integration tests in workspace + tools modules.
- All 1553 lib tests + integration tests pass.
- cargo clippy --all-targets --all-features -D warnings clean.
Adds S3WorkspaceBackend behind the new `s3` Cargo feature. The backend implements WorkspaceFileSystem against any S3-compatible endpoint (AWS S3, MinIO, RustFS, Cloudflare R2, Backblaze B2, ...) via the AWS Rust SDK. It deliberately does NOT implement WorkspaceCommandRunner, WorkspaceSearch, or any git provider trait — capability gating then prevents bash/grep/glob/git from being registered when the backend is in use, so the model never sees tools the backend cannot service. Includes: - core/src/workspace/s3.rs: S3WorkspaceBackend + S3BackendConfig builder (endpoint / region / session_token / force_path_style / request_timeout), with_client() injection for tests. - WorkspaceServices::s3(config) and WorkspaceServices::from_s3_backend() factories with a 60s default per-operation timeout. - 11 unit tests covering key/prefix derivation, list prefix handling, capability matrix, and config builder. - core/tests/test_s3_backend.rs: env-gated end-to-end integration test that exercises the full session executor (read/write/edit/patch/ls, asserting bash/git/grep/glob are not registered) against a real S3-compatible endpoint; auto-cleans the per-run UUID prefix. - Node and Python SDKs expose S3WorkspaceBackend alongside LocalWorkspaceBackend via the same workspaceBackend / workspace_backend option surface; both SDK Rust crates depend on a3s-code-core with the s3 feature enabled. - README documents the new backend with cross-language usage examples. The new feature is fully optional: building a3s-code-core without `--features s3` keeps the dependency tree slim and excludes the AWS SDK.
Aligns the release surface for v2.6.0:
- core/Cargo.toml, sdk/node/Cargo.toml, sdk/python/Cargo.toml: package
version + a3s-code-core dependency version.
- sdk/python/pyproject.toml: project version.
- sdk/node/package.json: root version + all 6 optionalDependencies
(@a3s-lab/code-{darwin-arm64,linux-{x64,arm64}-{gnu,musl},win32-x64-msvc}).
- sdk/node/package-lock.json and sdk/node/examples/package-lock.json.
- Cargo.lock: a3s-code-core / a3s-code-node / a3s-code-py entries.
- CHANGELOG.md: v2.6.0 entry covering the workspace abstraction refactor
and the new S3WorkspaceBackend feature.
scripts/check_release_versions.sh 2.6.0 → pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Release v2.6.0 of a3s-code: introduces a pluggable workspace backend
abstraction, ships a native S3-compatible backend behind an optional Cargo
feature, and bundles 16 architectural refinements to the surrounding
workspace / capability-gating subsystem.
Built-in file tools (
read,write,edit,patch,ls,bash,grep,glob,git) now route through trait-based capability providers insteadof hard-coded local filesystem calls. Local behaviour is unchanged.
DFS / browser / container / remote backends become drop-in extensions.
Commits
refactor(workspace): pluggable backend abstraction + 16 optimizationsworkspace.rsintoworkspace/{mod.rs, local.rs}(CLAUDE.mdfile-size rule).
WorkspaceFileSystem,WorkspaceCommandRunner,WorkspaceSearch,WorkspaceGit(slim core) + optionalWorkspaceGitStashProvider/WorkspaceGitWorktreeProvider+CommandOutputObserver.WorkspaceServicesbuilder, capability auto-downgrade, defaultoperation_timeout+run_with_timeouthelper.bash/grep/glob/gitare hidden from the model unless the backend declaresmatching capability.
LocalWorkspaceBackendnow implementsWorkspaceCommandRunner(no bash-specific fallback in the tool).
CommandRequestcarriesArc<dyn CommandOutputObserver>, droppingthe previous
ToolEventSenderleak from the abstraction.ChildRunContextpropagatesworkspace_servicesto child runs.Session:write_file,ls,edit_file,patch_file.WorkspaceCapabilitiesflags(
watch/atomic_write), unreachable bash fallback branch,unused
Registry::set_workspace_services, redundantToolExecutorprivate constructors.ToolContext::resolve_path/resolve_path_for_writeunder non-local backends (fail-closed when called against a
virtual backend).
feat(workspace): S3-compatible workspace backendcore/src/workspace/s3.rsbehind thes3Cargo feature.S3WorkspaceBackend+S3BackendConfigbuilder(endpoint / region / session_token / force_path_style /
request_timeout);
with_client()for test injection.WorkspaceServices::s3(cfg)+from_s3_backend(arc)factorieswith 60s default per-operation timeout.
matrix); env-gated end-to-end integration test exercising the
full session executor.
S3WorkspaceBackendalongsideLocalWorkspaceBackendvia the sameworkspaceBackend/workspace_backendoption surface.Backblaze B2 / RustFS interchangeably.
chore: bump all SDK versions to 2.6.0 + CHANGELOGcore/Cargo.toml,sdk/node/Cargo.toml,sdk/python/Cargo.toml,sdk/python/pyproject.toml,sdk/node/package.json(+ 6 optionalDependencies),two
package-lock.jsonfiles, andCargo.lock.scripts/check_release_versions.sh 2.6.0→ pass.Test plan
cargo fmt -p a3s-code-core --check— cleancargo clippy -p a3s-code-core --all-targets -- -D warnings— cleancargo clippy -p a3s-code-core --all-targets --features s3 -- -D warnings— cleancargo test -p a3s-code-core --lib(no s3) — 1553 passed / 0 failedcargo test -p a3s-code-core --lib --features s3— 1564 passed / 0 failedcargo test -p a3s-code-core --tests --features s3— all green (env-gated S3 e2e ignored by default)cargo test— 16 passed / 0 failed (+2 new for S3 dispatch)cargo test— 9 passed / 0 failed (+1 new for S3 dispatch)bash scripts/check_release_versions.sh 2.6.0— versions consistentAfter merge, push tag
v2.6.0to triggerrelease.yml.