How Workspace Configurations Are Stored and Managed in Craft Agents

Craft Agents stores workspace configurations as self-contained folders under ~/.craft-agent/workspaces/, with each workspace containing a config.json file alongside dedicated directories for sources, skills, themes, and an automations.json file for automation definitions.

Craft Agents OSS (craft-ai-agents/craft-agents-oss) persists workspace configurations using a file-system-based approach that treats each workspace as a portable, self-contained directory. This architecture ensures that skills, themes, sources, and automations remain centralized and version-controllable outside the application runtime.

File System Structure of a Workspace

Every workspace in Craft Agents exists as a self-contained folder under the default directory ~/.craft-agent/workspaces/. Inside each workspace folder, the following structure organizes configuration and runtime data:

  • config.json – Core workspace metadata including name, slug, defaults, and local MCP settings
  • sources/ – Source definitions (e.g., GitHub, Slack, Linear) with each source in its own sub-folder containing config.json and optional guide.md
  • skills/ – Skill packages containing markdown and TypeScript files that expose commands
  • themes/ – UI theme overrides stored as theme.json files for workspace-specific customization
  • automations.json – Automation definitions for cron-style triggers and event-based scripts
  • sessions/ – Runtime data created by agents including plans, logs, and attachments
  • .claude-plugin/ – Minimal SDK manifest enabling the workspace to function as an importable plugin

Core Storage Utilities and Path Resolution

The packages/shared/src/workspaces/storage.ts module provides the foundational API for workspace file system operations. Path resolution starts with getDefaultWorkspacesDir(), which returns ~/.craft-agent/workspaces/, and getWorkspacePath(id), which constructs the full path to a specific workspace folder.

Dedicated path helpers ensure consistent folder access:

  • getWorkspaceSourcesPath(rootPath) – Returns the absolute path to the sources/ directory
  • getWorkspaceSkillsPath(rootPath) – Returns the absolute path to the skills/ directory
  • getWorkspaceThemesPath(rootPath) – Returns the absolute path to the themes/ directory
  • getWorkspaceSessionsPath(rootPath) – Returns the absolute path to the sessions/ directory

Loading and Saving Configuration Data

Configuration persistence relies on two primary functions in packages/shared/src/workspaces/storage.ts:

  • loadWorkspaceConfig(rootPath) – Reads config.json, expands portable paths, normalizes legacy fields like permissionMode and thinkingLevel, and returns a typed WorkspaceConfig object
  • saveWorkspaceConfig(rootPath, config) – Writes configuration using atomicWriteFileSync to prevent corruption and converts absolute paths to portable form via toPortablePath

This atomic write pattern ensures that workspace configurations remain intact even if the process terminates unexpectedly during a save operation.

Theme Management at the Workspace Level

Workspace-level theme overrides allow users to customize the UI without affecting global settings. The theme identifier is stored in config.defaults.colorTheme within the workspace's config.json.

Two utilities manage this functionality:

  • getWorkspaceColorTheme(rootPath) – Retrieves the current theme identifier from the workspace configuration
  • setWorkspaceColorTheme(rootPath, themeId) – Validates the theme identifier, updates the configuration, and persists changes to disk

Automation Export and Import

Automations reside in a fixed filename defined in packages/shared/src/automations/constants.ts as automations.json. The resource bundle system in packages/shared/src/resources/resource-bundle.ts handles bulk operations:

  • exportAutomations(workspaceRootPath, selector, warnings) – Reads automations.json and returns a clean bundle entry for export
  • importAutomations(workspaceRootPath, entries, mode) – Validates incoming automation definitions and merges or overwrites existing automations.json based on the specified import mode

This bundling approach allows users to migrate automations between workspaces or share them as version-controlled resources.

Workspace Discovery and Validation

The storage layer provides utilities for workspace enumeration and health checks:

  • discoverWorkspacesInDefaultLocation() – Scans ~/.craft-agent/workspaces/ for folders containing valid config.json files and returns their absolute paths
  • isValidWorkspace(rootPath) – Verifies workspace integrity by checking for the presence of config.json

These functions enable the application to present available workspaces on startup and validate workspace integrity before loading.

Practical Code Examples

import { 
  getDefaultWorkspacesDir,
  createWorkspaceAtPath,
  loadWorkspaceConfig,
  setWorkspaceColorTheme,
  getWorkspaceColorTheme,
  getWorkspaceSourcesPath,
  getWorkspaceSkillsPath,
} from '@/shared/src/workspaces/storage';
import { join } from 'path';

// 1. Create a new workspace under the default location
const defaultDir = getDefaultWorkspacesDir();
const wsPath = join(defaultDir, 'my-first-workspace');
const wsConfig = createWorkspaceAtPath(wsPath, 'My First Workspace');

// 2. Load configuration later
const loaded = loadWorkspaceConfig(wsPath);
console.log('Loaded name:', loaded?.name);

// 3. Set workspace-specific UI theme
setWorkspaceColorTheme(wsPath, 'my-dark-theme');
console.log('Current theme:', getWorkspaceColorTheme(wsPath));

// 4. Resolve resource directories
const sourcesDir = getWorkspaceSourcesPath(wsPath);
const skillsDir = getWorkspaceSkillsPath(wsPath);
console.log('Sources:', sourcesDir);
console.log('Skills:', skillsDir);

Summary

  • Craft Agents stores workspace configurations as self-contained folders under ~/.craft-agent/workspaces/
  • The config.json file contains core metadata managed by loadWorkspaceConfig and saveWorkspaceConfig in packages/shared/src/workspaces/storage.ts
  • Dedicated directories organize sources (sources/), skills (skills/), themes (themes/), and runtime data (sessions/)
  • Automations persist in automations.json and import/export through the resource bundle system in packages/shared/src/resources/resource-bundle.ts
  • Path helpers like getWorkspaceSourcesPath and getWorkspaceSkillsPath provide consistent file system abstraction
  • Theme overrides and workspace validation utilities ensure each workspace remains portable and integrity-checked

Frequently Asked Questions

Where does Craft Agents store workspace configuration files?

Craft Agents stores workspace configurations in the ~/.craft-agent/workspaces/ directory by default. Each workspace exists as a separate folder containing a config.json file and subdirectories for sources, skills, themes, and sessions. The getDefaultWorkspacesDir() function in packages/shared/src/workspaces/storage.ts returns this path.

How are automations stored and migrated between workspaces?

Automations are stored in an automations.json file located at the workspace root, defined in packages/shared/src/automations/constants.ts. The resource-bundle.ts module provides exportAutomations and importAutomations functions that validate, serialize, and merge automation definitions when migrating between workspaces or importing from external bundles.

What prevents config.json corruption during writes?

The saveWorkspaceConfig function uses atomicWriteFileSync to write configuration data atomically, ensuring that the existing config.json is never in a partially written state. This prevents corruption if the application crashes or loses power during a save operation.

How does Craft Agents validate that a folder is a valid workspace?

The isValidWorkspace(rootPath) function checks for the presence of a config.json file within the directory. Additionally, discoverWorkspacesInDefaultLocation() scans the default workspaces directory and returns only paths that contain valid configuration files, filtering out incomplete or corrupted workspace folders.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →