@downcity/workspace
Project resources, private storage capability, file tools, environment, and Shell.
@downcity/workspace defines the resource boundary in which an Agent performs work. It owns the
project path, rooted file access, file and search tools, environment variables, private storage
capability, and an optional Shell. It does not own Agent identity, Plugins, Sessions, or model calls.
pnpm add @downcity/workspace @downcity/agentimport { Agent } from "@downcity/agent";
import { Shell, Workspace } from "@downcity/workspace";
import { MacOsSeatbeltSandbox } from "@downcity/sandbox-macos";
const workspace = new Workspace({
id: "project",
path: process.cwd(),
env: { NODE_ENV: "development" },
shell: new Shell({ sandbox: new MacOsSeatbeltSandbox() }),
});
const city = new City({ workspaces: [workspace] });
const agent = new Agent({ id: "repo-helper", model, plugins });
city.agents.add(agent);
const session = await agent.sessions.create({ workspace });Ownership
Workspaceowns project resources and the optional Shell.Agentowns identity, instruction, model, custom tools, and Plugin registration.AgentWorkspaceis an internal execution scope created by the Agent, including Sessions, logs, scheduled actions, contextual Plugin lifecycle, and private runtime state.- Shell is a Workspace capability. There is no separate
@downcity/shellpackage.
An Agent can create Sessions in multiple City Workspaces. A Workspace is owned by City and can be shared by multiple Agents; Agent-private Session and Plugin data remain isolated.
Storage
The local Workspace resolves its private storage provider internally. Callers do not pass a data root path. Runtime state is centralized outside project directories:
~/.downcity/agents/<agent_id>/workspaces/<workspace_id>/WorkspaceStorageProvider is intentionally domain-neutral. AgentWorkspace chooses the
agents/<agent_id>/workspaces/<workspace_id> scope and creates the SessionStore there. Project
File/Search tools remain rooted at the real project path and cannot read this private state.
Edge adapters should import WorkspaceBase and protocol types from @downcity/workspace/protocol
so they do not load Node.js filesystem, PTY, or local Shell implementations.