Archon/docs/configuration.md
Rasmus Widing 090e5fd812
feat: Runtime loading of default commands/workflows (#324)
* feat: Runtime loading of default commands/workflows

Instead of copying default commands and workflows to target repos on
clone, load them at runtime from the app's bundled defaults directory.

Changes:
- Fix getAppArchonBasePath() to resolve to repo root (not packages/core)
- Add loadDefaultCommands and loadDefaultWorkflows config options
- Update workflow loader to search app defaults then repo (repo wins)
- Update command executor to search app defaults after repo paths
- Remove copyDefaultsToRepo() calls from /clone and GitHub adapter
- Fix lint-staged to not warn on ignored test files

Benefits:
- Defaults always up-to-date (no sync issues)
- Clean repos (no 24+ files copied per clone)
- User's local clone stays in sync with what Archon uses

Closes #322

* docs: Update documentation for runtime loading of defaults

- Update CLAUDE.md to explain runtime loading behavior
- Fix README.md example output and note about defaults
- Update docs/configuration.md with new config options
- Mark copyDefaults as deprecated in favor of loadDefaultCommands/loadDefaultWorkflows

* fix: Address PR review findings for runtime loading

- Fix silent error swallowing in loadConfig catch blocks (loader.ts, executor.ts)
  - Now logs warning with context before falling back to defaults
  - Users will know when their config has syntax errors

- Fix config merging bug in mergeRepoConfig
  - Now includes loadDefaultCommands and loadDefaultWorkflows in merge
  - Repo config opt-out now works correctly

- Add consistent empty file handling for app defaults
  - Returns explicit empty_file error instead of falling through

- Add debug logging for ENOENT cases
  - Helps troubleshoot when app defaults aren't found

- Add startup validation for app defaults paths
  - validateAppDefaultsPaths() checks and logs verification status
  - Called during server startup after logArchonPaths()

- Add comprehensive tests for app defaults command loading
  - Test loading from app defaults when not in repo
  - Test repo commands override app defaults
  - Test loadDefaultCommands: false opt-out
  - Test empty file handling
  - Test graceful handling of missing paths
  - Test config error fallback behavior

* fix: Use namespace imports for archonPaths to fix test mocking in CI

The loader.ts used destructured imports for getDefaultWorkflowsPath and
getWorkflowFolderSearchPaths, but the tests use spyOn which only works
with namespace imports (import * as). This caused the mocks to not work
in CI where tests run in parallel, causing 48 test failures.

* fix: Restore spyOn approach with namespace imports for loader tests

The key fix is that loader.ts uses namespace imports (import * as archonPaths)
which shares the same module instance with the test file. This allows spyOn
to work correctly without using mock.module() which pollutes other tests.

* fix: Use loadDefaultWorkflows: false to avoid app defaults in tests

Instead of mocking archon-paths (which pollutes other tests), we:
1. Only mock config-loader with loadDefaultWorkflows: false by default
2. This prevents app defaults from being loaded during tests
3. For multi-source loading tests, enable loadDefaultWorkflows: true
   and use spyOn to set the path to a temp directory

* fix: Use namespace imports and spyOn for all loader dependencies

Key changes:
1. loader.ts now uses namespace imports for both archonPaths and configLoader
2. loader.test.ts uses spyOn instead of mock.module
3. This avoids polluting other test files (archon-paths.test.ts, config-loader.test.ts)

The spyOn approach works because:
- Both loader.ts and loader.test.ts import the modules as namespaces
- They share the same module instance in Bun's module cache
- spyOn modifies the shared namespace object

* fix: Use namespace imports in executor.ts for test mocking

Change executor.ts to use namespace imports for archon-paths and
config-loader, matching the fix already applied to loader.ts.

The previous fix commits (491fa94, c3a68dd) only updated loader.ts
but missed executor.ts, which has the same pattern of tests using
spyOn() that requires namespace imports to work correctly.

Changes:
- import * as archonPaths from '../utils/archon-paths'
- import * as configLoader from '../config/config-loader'
- Update all usage sites to use namespace prefix

* refactor: Prefix app defaults with archon-* and simplify override logic

Changes:
- Rename all default workflow files to archon-*.yaml
- Rename all default command files to archon-*.md
- Update workflow name: fields to match filenames
- Update command references in workflows to use archon-* names
- Simplify loader.ts to use exact filename match for overrides (not workflow name)
- Remove path mocking from tests - use real app defaults instead
- Simplify tests to be more reliable in CI

Benefits:
- No accidental collisions with user workflows/commands
- Clear intent when users override (must use exact filename)
- Simpler deduplication logic (filename-based)
- More reliable tests (no spyOn issues in CI parallel execution)

* feat: Add deprecation warning for old defaults and update docs

- Add warning in loader.ts when old non-prefixed defaults found in repo
- Update CLAUDE.md with migration instructions for old repos
- Document the archon-* prefix naming convention
- Document exact filename match override behavior

* docs: Move migration docs to docs/migration-guide.md

- Revert CLAUDE.md changes (keep it focused on development)
- Create dedicated migration guide for version upgrades
- Document runtime loading defaults migration steps
- Add commands for full fresh start cleanup

* docs: Add getting started section after cleanup

* docs: Fix stale references to command loading behavior

- Update CLAUDE.md to say 'auto-detected' instead of 'loaded via /clone (auto)'
- Clarify in architecture.md that defaults are loaded at runtime, not copied
- Update GitHub webhook flow to say 'detect and register' instead of 'load commands'

* refactor: Use early return in validateAppDefaultsPaths for cleaner flow

* fix: Improve error handling for silent failure cases

- Add ENOENT check to empty catch block in loader.ts (critical)
- Distinguish between 'not found' and other errors in validateAppDefaultsPaths
- Add errorType to config load fallback logging in loader.ts and executor.ts
2026-01-21 23:08:23 +02:00

4.9 KiB

Configuration Guide

Archon supports a layered configuration system with sensible defaults, optional YAML config files, and environment variable overrides.

Directory Structure

User-Level (~/.archon/)

~/.archon/
├── workspaces/     # Cloned repositories
│   └── owner/repo/
├── worktrees/      # Git worktrees for isolation
│   └── repo-name/
│       └── branch-name/
├── archon.db       # SQLite database (when DATABASE_URL not set)
└── config.yaml     # Global configuration (optional)

Repository-Level (.archon/)

.archon/
├── commands/       # Custom command templates
│   └── plan.md
├── workflows/      # Future: workflow definitions
└── config.yaml     # Repo-specific configuration (optional)

Configuration Priority

Settings are loaded in this order (later overrides earlier):

  1. Defaults - Sensible built-in defaults
  2. Global Config - ~/.archon/config.yaml
  3. Repo Config - .archon/config.yaml in repository
  4. Environment Variables - Always highest priority

Global Configuration

Create ~/.archon/config.yaml for user-wide preferences:

# Default AI assistant
defaultAssistant: claude # or 'codex'

# Streaming preferences per platform
streaming:
  telegram: stream # 'stream' or 'batch'
  discord: batch
  slack: batch
  github: batch

# Custom paths (usually not needed)
paths:
  workspaces: ~/.archon/workspaces
  worktrees: ~/.archon/worktrees

# Concurrency limits
concurrency:
  maxConversations: 10

Repository Configuration

Create .archon/config.yaml in any repository for project-specific settings:

# AI assistant for this project (used as default provider for workflows)
assistant: claude

# Commands configuration
commands:
  folder: .archon/commands
  autoLoad: true

# Worktree settings
worktree:
  baseBranch: main
  copyFiles:  # Optional: Additional files to copy to worktrees
    - .env.example -> .env  # Rename during copy
    - .vscode               # Copy entire directory

# Defaults configuration
defaults:
  loadDefaultCommands: true   # Load app's bundled default commands at runtime
  loadDefaultWorkflows: true  # Load app's bundled default workflows at runtime
  copyDefaults: false         # Deprecated: use loadDefaultCommands/loadDefaultWorkflows instead

Default behavior: The .archon/ directory is always copied to worktrees automatically (contains artifacts, plans, workflows). Use copyFiles only for additional files like .env or .vscode.

Defaults behavior: The app's bundled default commands and workflows are loaded at runtime and merged with repo-specific ones. Repo commands/workflows override app defaults by name. Set defaults.loadDefaultCommands: false or defaults.loadDefaultWorkflows: false to disable runtime loading.

Environment Variables

Environment variables override all other configuration:

Variable Description Default
DATABASE_URL PostgreSQL connection (optional) SQLite at ~/.archon/archon.db if not set
ARCHON_HOME Base directory for Archon ~/.archon
DEFAULT_AI_ASSISTANT Default AI assistant claude
TELEGRAM_STREAMING_MODE Telegram streaming stream
DISCORD_STREAMING_MODE Discord streaming batch
SLACK_STREAMING_MODE Slack streaming batch
GITHUB_STREAMING_MODE GitHub streaming batch
MAX_CONCURRENT_CONVERSATIONS Concurrency limit 10

Docker Configuration

In Docker containers, paths are automatically set:

/.archon/
├── workspaces/
└── worktrees/

Environment variables still work and override defaults.

Command Folder Detection

When cloning or switching repositories, Archon looks for commands in this priority order:

  1. .archon/commands/ - Always searched first
  2. Configured folder from commands.folder in .archon/config.yaml (if specified)

Example .archon/config.yaml:

commands:
  folder: .claude/commands/archon  # Additional folder to search
  autoLoad: true

Examples

Minimal Setup (Using Defaults)

No configuration needed! Archon works out of the box with:

  • ~/.archon/ for all managed files
  • Claude as default AI assistant
  • Platform-appropriate streaming modes

Custom AI Preference

# ~/.archon/config.yaml
defaultAssistant: codex

Project-Specific Settings

# .archon/config.yaml in your repo
assistant: claude  # Workflows inherit this provider unless they specify their own
commands:
  autoLoad: true

Docker with Custom Volume

docker run -v /my/data:/.archon ghcr.io/dynamous-community/remote-coding-agent