Skip to main content

Config Repo Guide

Your config repo is where your agent becomes yours. It layers personalization on top of Attaché's base platform — extra packages, shell config, workspace files, custom Ansible playbooks, and bootstrap scripts.

Getting Started

Create a new GitHub repo. It can be:

Public repos work well for shared team configurations that don't include workspace files or secrets. Name it something like yourorg/attache-config and let everyone on the team reference it.

Private repos are for a specific agent's full setup — workspace files, skills, Ansible playbooks, everything. Name it after the agent (e.g., username/evie) and keep it locked down with SSH key access.

Directory Structure

All directories are optional. Attaché discovers and applies whatever it finds.

my-agent/
├── attache.config.json # Feature flags and variable overrides
├── Brewfile # Additional Homebrew packages
├── mise/
│ └── config.toml # Additional mise tools
├── shell/
│ ├── zshrc.local # Sourced at end of .zshrc
│ └── starship.toml # Prompt configuration
├── skills/ # Shared across workspaces → ~/.openclaw/skills/
│ ├── code-review/
│ ├── knowledge/
│ └── sonarqube/
├── workspace/ # Maps to ~/.openclaw/workspaces/main/
│ ├── SOUL.md # Agent personality
│ ├── USER.md # About the human
│ ├── AGENTS.md # Workspace conventions
│ ├── TOOLS.md # Local tool notes
│ ├── IDENTITY.md # Agent identity
│ ├── HEARTBEAT.md # Periodic task checklist
│ ├── memory/
│ │ └── MEMORY.md # Long-term memory seed
│ └── knowledge/ # Entity profiles (basic-memory backed)
│ ├── people/
│ ├── organizations/
│ └── research/
├── ansible/
│ ├── group_vars/
│ │ └── all.yml # Variable overrides (deep-merged with base)
│ ├── playbooks/ # Custom playbooks (run after base)
│ └── roles/ # Custom roles (available to your playbooks)
├── scripts/ # Shell scripts (run in alphabetical order)
└── credentials/
└── README.md # Setup instructions (no actual secrets)

attache.config.json Reference

{
"agent_name": "Evie",

"backends": {
"secrets": "onepassword",
"tunnel": "tailscale",
"database": "supabase"
},

"coding_agents": {
"claude_code": {
"max_sessions": 4,
"default_model": "claude-sonnet-4-20250514"
},
"codex": true
},

"homebrew_extra": [
"ffmpeg", "sox", "imagemagick", "ripgrep", "pandoc-crossref"
],

"homebrew_casks_extra": ["1password"],

"mise_extra": {
"python": "3.13.3",
"rust": "1.82.0"
},

"git": {
"user_name": "Evie (Attaché)",
"user_email": "[email protected]"
}
}

backends

Each backend tells Attaché what you need, and Attaché handles the how:

BackendValueWhat Attaché does
secretsonepasswordInstalls 1Password CLI, stores service account token in macOS Keychain, configures op for non-interactive use
tunneltailscaleInstalls Tailscale, prompts for auth key or interactive login
databasesupabaseRuns local Supabase via Docker Compose (pgvector, pg_trgm enabled)

Future backend options are planned but not yet implemented. For secrets, HashiCorp Vault and Doppler are on the roadmap. For tunneling, Cloudflare Tunnel is the likely next addition.

Shell configuration

Attaché's base ensures zsh is the default shell and sources ~/.zshrc.local if it exists. Beyond that, shell config is entirely yours — put your zshrc, zprofile, and zshenv files in your config repo's shell/ directory.

The base does not install Oh My Zsh, Starship, or any shell framework. If you want them, add the installation to your Brewfile, scripts/, or Ansible playbooks in the config repo.

Workspace Files

Everything in workspace/ gets copied to ~/.openclaw/workspaces/main/ on the target. Everything in skills/ gets copied to ~/.openclaw/skills/ (shared across all workspaces).

At minimum, you'll want two files. SOUL.md defines who the agent is — its personality, voice, and boundaries. USER.md describes the human it's working for — name, preferences, timezone, context. These two files give the agent enough to be useful from its first session.

Three more files round out a well-configured workspace. AGENTS.md establishes workspace conventions and behavioral rules. TOOLS.md holds notes about local tool configurations — camera names, SSH hosts, voice preferences. IDENTITY.md captures the agent's name, emoji, and avatar metadata.

Skills

Skills live at the config repo root in skills/, not inside workspace/. This is intentional — skills are shared resources that can be linked into multiple workspaces.

During bootstrap, Ansible copies skills/ to ~/.openclaw/skills/. If you later add additional workspaces, they can all reference the same skill set.

Custom Ansible

Your config repo can include full Ansible playbooks and roles. These run after the base bootstrap completes, so you can assume all base tooling is available.

Example: Credentials Playbook

# ansible/playbooks/credentials.yml
---
- name: Set up agent credentials
hosts: all
roles:
- role: onepassword-bootstrap
tags: [credentials]
# ansible/roles/onepassword-bootstrap/tasks/main.yml
---
- name: Sign in to 1Password CLI
ansible.builtin.shell: |
eval $(op signin)
environment:
OP_SERVICE_ACCOUNT_TOKEN: "{{ op_service_account_token }}"

- name: Extract GitHub token
ansible.builtin.shell: |
op read "op://Openclaw/EVIE - GitHub PAT/credential"
register: github_token

- name: Configure npmrc for GitHub Packages
ansible.builtin.template:
src: npmrc.j2
dest: "{{ ansible_env.HOME }}/.npmrc"
mode: "0600"

Example: group_vars Override

# ansible/group_vars/all.yml
# These values are deep-merged with the base group_vars.
# Your values win on conflict.

node_version: "22"
openclaw_version: "latest"

# Add packages to the base list
homebrew_packages:
- git
- jq
- gh
- mise
- tailscale
- trash
# Your additions:
- ffmpeg
- ripgrep
- sox

Bootstrap Scripts

Shell scripts in scripts/ run in alphabetical order after Ansible completes. Use numeric prefixes to control order:

#!/usr/bin/env bash
# scripts/01-tailscale.sh
# Join the tailnet (requires auth key)

tailscale up --authkey="${TAILSCALE_AUTH_KEY}"
#!/usr/bin/env bash
# scripts/02-github-auth.sh
# Authenticate GitHub CLI

gh auth login --with-token <<< "${GITHUB_TOKEN}"

Public vs Private Repos

Public ConfigPrivate Config
Use caseShared team defaultsSpecific agent setup
Contains workspace filesUsually notYes (SOUL.md, skills, etc.)
Contains credentialsNeverNever (use 1Password/vault)
Example namemyorg/attache-configusername/agent-name
Auth requiredNoYes (SSH key or GH token)

Template Repository

We provide a template config repo you can fork as a starting point:

gh repo create my-agent --template Spantree/attache-config-template --private

(Template coming soon)