Skip to main content

What is a Workspace?

A workspace represents a project or codebase with its own configuration, sources, and sessions. Workspaces provide isolation boundaries for:
  • Sources - MCP servers and API connections
  • Sessions - Conversation history and state
  • Themes - Custom color schemes
  • Permissions - Custom safety rules
  • Statuses - Workflow labels (Todo, In Progress, Done, etc.)
Workspaces are the configuration boundary, while sessions are the conversation boundary. Think of workspaces as projects, and sessions as conversations within those projects.

Workspace Structure

Each workspace is stored at ~/.craft-agent/workspaces/{workspace-id}/:
~/.craft-agent/workspaces/ws-abc123/
├── config.json         # Workspace metadata
├── theme.json          # Theme overrides (optional)
├── permissions.json    # Permission rules (optional)
├── statuses/
│   └── config.json     # Custom workflow statuses
├── sources/
│   ├── linear/
│   │   ├── config.json # Source configuration
│   │   └── guide.md    # Usage guidelines
│   └── github/
│       ├── config.json
│       └── guide.md
└── sessions/
    ├── session-1/
    │   └── session.jsonl
    └── session-2/
        └── session.jsonl

Workspace Configuration

The config.json file contains workspace metadata:
interface Workspace {
  id: string;              // Unique identifier (e.g., "ws-abc123")
  name: string;            // Display name from workspace folder
  rootPath: string;        // Absolute path to workspace folder
  createdAt: number;       // Unix timestamp
  lastAccessedAt?: number; // For sorting recent workspaces
  iconUrl?: string;        // Custom icon path
  mcpUrl?: string;         // Workspace-level MCP server URL
  mcpAuthType?: McpAuthType; // 'workspace_oauth' | 'workspace_bearer' | 'public'
}

Example Configuration

{
  "id": "ws-2024-01-15-craft-agent",
  "name": "Craft Agent",
  "rootPath": "/Users/alice/Projects/craft-agent",
  "createdAt": 1705334400000,
  "lastAccessedAt": 1705420800000,
  "iconUrl": "/Users/alice/Projects/craft-agent/.craft-icon.png"
}

Workspace Storage Location

Default Location

Workspaces are stored at ~/.craft-agent/workspaces/ by default:
import { join } from 'path';
import { homedir } from 'os';

const CONFIG_DIR = join(homedir(), '.craft-agent');
const WORKSPACES_DIR = join(CONFIG_DIR, 'workspaces');

Workspace ID Format

Workspace IDs are generated from the creation date and folder name:
// Format: ws-YYYY-MM-DD-{sanitized-folder-name}
const workspaceId = `ws-${dateStr}-${sanitizedName}`;

// Example: ws-2024-01-15-my-project
Workspace IDs are stable and don’t change if you rename the workspace folder. The name field is read from the folder name on each launch.

Multiple Workspaces

Craft Agents supports multiple workspaces with independent configurations:
import { loadStoredConfig } from '@craft-agent/shared/config';

const config = loadStoredConfig();

// List all workspaces
config.workspaces.forEach(workspace => {
  console.log(`${workspace.name} (${workspace.id})`);
  console.log(`  Path: ${workspace.rootPath}`);
  console.log(`  Sessions: ${workspace.sessions?.length || 0}`);
});

// Active workspace
const activeWorkspace = config.workspaces.find(
  ws => ws.id === config.activeWorkspaceId
);

Workspace Discovery

Workspaces are auto-discovered in the default location:
import { discoverWorkspacesInDefaultLocation } from '@craft-agent/shared/workspaces';

// Scans ~/.craft-agent/workspaces/ for valid workspace folders
const workspaces = discoverWorkspacesInDefaultLocation();

Creating a Workspace

Programmatic Creation

import { createWorkspaceAtPath } from '@craft-agent/shared/workspaces';

const workspace = await createWorkspaceAtPath(
  '/Users/alice/Projects/my-app',
  'My App'
);

console.log(`Created workspace: ${workspace.id}`);
// Output: ws-2024-01-15-my-app

Validation

Workspaces must have:
  1. A valid config.json with id, name, and rootPath
  2. A sources/ directory
  3. A sessions/ directory
import { isValidWorkspace } from '@craft-agent/shared/workspaces';

if (isValidWorkspace('/path/to/workspace')) {
  console.log('Valid workspace');
}

Workspace-Level Sources

Sources (MCP servers and API connections) are scoped to workspaces:
workspaces/ws-abc123/sources/
├── linear/
│   ├── config.json     # Linear MCP configuration
│   └── guide.md        # Usage guidelines
├── github/
│   ├── config.json     # GitHub API configuration
│   └── guide.md
└── notion/
    ├── config.json
    └── guide.md
Each source has:
  • config.json - Connection settings (command, args, env, auth)
  • guide.md - Usage instructions shown to the agent on first use

Learn More About Sources

Deep dive into source configuration and types

Workspace-Level Permissions

Custom permission rules override global defaults:
import { loadWorkspacePermissions } from '@craft-agent/shared/config';

const permissions = loadWorkspacePermissions(workspace.rootPath);

if (permissions) {
  console.log('Blocked tools:', permissions.blockedTools);
  console.log('Allowed paths:', permissions.allowedWritePaths);
}

Additive Merging

Workspace permissions extend global defaults:
// Global defaults
{
  "blockedTools": ["Admin"],
  "allowedBashPatterns": ["^ls", "^pwd"]
}

// Workspace override
{
  "blockedTools": ["Bash"],          // Adds to global list
  "allowedWritePaths": ["./docs/**"] // New restriction
}

// Effective rules: blockedTools = ["Admin", "Bash"]

Permission Configuration

Learn about permission rules and safe mode

Workspace Themes

Workspaces can override the global theme:
import { resolveTheme } from '@craft-agent/shared/config/theme';

// Cascading theme resolution: workspace → app → default
const theme = resolveTheme(workspace.rootPath);

console.log('Accent color:', theme.colors.accent);
// Output: #8B5CF6

6-Color System

Themes define 6 semantic colors:
background
string
required
Background color (canvas, panels)
foreground
string
required
Text and icon color
accent
string
required
Primary brand color (buttons, links) - default #8B5CF6
info
string
required
Informational color (badges, status)
success
string
required
Success states (completed tasks)
destructive
string
required
Error and destructive actions

Switching Workspaces

import { loadStoredConfig, saveStoredConfig } from '@craft-agent/shared/config';

const config = loadStoredConfig();
config.activeWorkspaceId = 'ws-2024-01-15-new-project';
saveStoredConfig(config);
Switching workspaces:
  1. Closes all sessions in the current workspace
  2. Loads sources from the new workspace
  3. Restores the last active session (if any)
Switching workspaces aborts all running sessions in the current workspace. Save your work before switching.

Best Practices

Create a dedicated workspace for each codebase or project. This ensures:
  • Sources are project-specific (e.g., Linear for project A, Jira for project B)
  • Sessions don’t mix contexts from different projects
  • Themes and permissions match the project’s needs
Workspace names appear in the UI and file paths. Use clear, memorable names:
  • Good: craft-agent, personal-website, client-acme
  • Bad: project1, test, new-workspace-2
Set up workspace-level permissions before enabling sources:
{
  "allowedWritePaths": ["./src/**", "./docs/**"],
  "blockedTools": ["Admin"],
  "allowedBashPatterns": ["^git", "^npm"]
}
Source guide.md files contain usage instructions. Commit them to git:
git add .craft-agent/workspaces/*/sources/*/guide.md
git commit -m "Add source usage guides"

Sessions

Conversation boundaries within workspaces

Sources

Configure MCP servers and API connections

Permissions

Custom safety rules and safe mode

Themes

Color schemes and visual customization

Build docs developers (and LLMs) love