Cc-skills mise-configuration

Configure environment variables and project settings using mise [env] as the single source of truth. Use whenever the user needs to set up mise.toml, centralize environment variables, configure Python venvs through mise, use mise templates, or structure hub-spoke and monorepo mise configurations with subfolder overrides. Do NOT use for mise task orchestration (use mise-tasks instead) or for runtime version management unrelated to environment configuration.

install
source · Clone the upstream repo
git clone https://github.com/terrylica/cc-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/terrylica/cc-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/itp/skills/mise-configuration" ~/.claude/skills/terrylica-cc-skills-mise-configuration && rm -rf "$T"
manifest: plugins/itp/skills/mise-configuration/SKILL.md
source content

mise Configuration as Single Source of Truth

Use mise

[env]
as centralized configuration with backward-compatible defaults.

Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.

When to Use This Skill

Use this skill when:

  • Centralizing environment variables in mise.toml
  • Setting up Python venv auto-creation with mise
  • Implementing hub-spoke configuration for monorepos
  • Creating backward-compatible environment patterns

Core Principle

Define all configurable values in

.mise.toml
[env]
section. Scripts read via environment variables with fallback defaults. Same code path works WITH or WITHOUT mise installed.

Key insight: mise auto-loads

[env]
values when shell has
mise activate
configured. Scripts using
os.environ.get("VAR", "default")
pattern work identically whether mise is present or not.

Quick Reference

Language Patterns

LanguagePatternNotes
Python
os.environ.get("VAR", "default")
Returns string, cast if int
Bash
${VAR:-default}
Standard POSIX expansion
JavaScript
process.env.VAR || "default"
Falsy check, watch for "0"
Go
os.Getenv("VAR")
with default
Empty string if unset
Rust
std::env::var("VAR").unwrap_or()
Returns Result<String>

Special Directives

DirectivePurposeExample
_.file
Load from .env files
_.file = ".env"
_.path
Extend PATH
_.path = ["bin", "node_modules/.bin"]
_.source
Execute bash scripts
_.source = "./scripts/env.sh"
_.python.venv
Auto-create Python venv
_.python.venv = { path = ".venv", create = true }

For detailed directive examples with options (redact, tools, multi-file): Code Patterns

Python Venv Auto-Creation (Critical)

Auto-create and activate Python virtual environments:

[env]
_.python.venv = { path = ".venv", create = true }

This pattern is used in ALL projects. When entering the directory with mise activated:

  1. Creates
    .venv
    if it doesn't exist
  2. Activates the venv automatically
  3. Works with
    uv
    for fast venv creation

Alternative via [settings]:

[settings]
python.uv_venv_auto = true

Hub-Spoke Architecture (CRITICAL)

Keep root

mise.toml
lean by delegating domain-specific tasks to subfolder
mise.toml
files. Applies to monorepos, ML/research projects, infrastructure, and data pipelines.

Key rules:

  • Hub owns
    [tools]
    and orchestration tasks
  • Spokes inherit hub's
    [tools]
    automatically
  • Spoke
    [env]
    extends hub's
    [env]
    (can override per domain)
  • .mise.local.toml
    applies at directory level (secrets stay local)

Full guide with directory structures, examples, and anti-patterns: Hub-Spoke Architecture

Wiki Reference: Pattern-mise-Configuration

Monorepo Workspace Pattern

For Python monorepos using

uv
workspaces, the venv is created at the workspace root. Dev dependencies should be hoisted to root
pyproject.toml
using
[dependency-groups]
(PEP 735).

Full guide: Monorepo Workspace Pattern

Template Syntax (Tera)

mise uses Tera templating. Delimiters:

{{ }}
expressions,
{% %}
statements,
{# #}
comments.

Built-in Variables

VariableDescription
{{config_root}}
Directory containing .mise.toml
{{cwd}}
Current working directory
{{env.VAR}}
Environment variable
{{mise_bin}}
Path to mise binary
{{mise_pid}}
mise process ID
{{xdg_cache_home}}
XDG cache directory
{{xdg_config_home}}
XDG config directory
{{xdg_data_home}}
XDG data directory

For functions (

get_env
,
exec
,
arch
,
read_file
,
hash_file
), filters (
snakecase
,
trim
,
absolute
), and conditionals: Code Patterns - Template Syntax

Required & Redacted Variables

[env]
# Required - fails if not set
DATABASE_URL = { required = true }
API_KEY = { required = "Get from https://example.com/api-keys" }

# Redacted - hides from output
SECRET = { value = "my_secret", redact = true }
_.file = { path = ".env.secrets", redact = true }

# Pattern-based redactions
redactions = ["*_TOKEN", "*_KEY", "PASSWORD"]

For combined patterns and detailed examples: Code Patterns - Required & Redacted

Lazy Evaluation (
tools = true
)

By default, env vars resolve BEFORE tools install. Use

tools = true
to access tool-generated paths:

[env]
GEM_BIN = { value = "{{env.GEM_HOME}}/bin", tools = true }
_.file = { path = ".env", tools = true }

[settings] and [tools]

[settings]
experimental = true
python.uv_venv_auto = true

[tools]
python = "<version>"
node = "latest"
uv = "latest"
rust = { version = "<version>", profile = "minimal" }

# SSoT-OK: mise min_version directive, not a package version
min_version = "2024.9.5"

For full settings reference and version pinning options: Code Patterns - Settings & Tools

Implementation Steps

  1. Identify hardcoded values - timeouts, paths, thresholds, feature flags
  2. Create
    .mise.toml
    - add
    [env]
    section with documented variables
  3. Add venv auto-creation -
    _.python.venv = { path = ".venv", create = true }
  4. Update scripts - use env vars with original values as defaults
  5. Add ADR reference - comment:
    # ADR: 2025-12-08-mise-env-centralized-config
  6. Test without mise - verify script works using defaults
  7. Test with mise - verify activated shell uses
    .mise.toml
    values

GitHub Token Multi-Account Patterns {#github-token-multi-account-patterns}

For multi-account GitHub setups, mise

[env]
provides per-directory token configuration that overrides gh CLI's global authentication.

Rule: Always set BOTH

GH_TOKEN
and
GITHUB_TOKEN
pointing to the same token file.

VariableUsage Context
GH_TOKEN
mise [env], Doppler, verification tasks
GITHUB_TOKEN
npm scripts, GitHub Actions, semantic-release

Full guide with templates, verification, and 1Password integration: GitHub Token Patterns

Anti-Patterns

Anti-PatternWhyInstead
mise exec -- script.py
Forces mise dependencyUse env vars with defaults
Secrets in
.mise.toml
Visible in repoUse Doppler or
redact = true
No defaults in scriptsBreaks without miseAlways provide fallback
[env]
secrets for pueue jobs
Pueue runs clean shell, no miseUse
python-dotenv
+
.env
file
__MISE_DIFF
leaks via SSH
Remote trust errors
unset __MISE_DIFF
before SSH

Critical detail on non-interactive shell secrets: Anti-Patterns Guide

Task Orchestration Integration

When detecting multi-step project workflows during mise configuration, invoke the

mise-tasks
skill for task definitions with dependency management.

Detection triggers: multi-step workflows, repeatable commands, dependency chains, file-tracked builds.

Full guide with examples: Task Orchestration | mise-tasks skill


Additional Resources

ADR Reference: When implementing mise configuration, create an ADR at

docs/adr/YYYY-MM-DD-mise-env-centralized-config.md
in your project.


Troubleshooting

IssueCauseSolution
Env vars not loadingmise not activatedAdd mise activate to shell rc file
Venv not createdPython not installedRun
mise install python
Tasks not foundWrong mise.toml locationEnsure mise.toml is in project root
PATH not updatedShims not in PATHAdd mise shims to ~/.zshenv
.file not loading.env file missingCreate .env file or remove .file directive
Subfolder config ignoredMissing min_versionAdd min_version to subfolder mise.toml

Post-Execution Reflection

After this skill completes, check before closing:

  1. Did the command succeed? — If not, fix the instruction or error table that caused the failure.
  2. Did parameters or output change? — If the underlying tool's interface drifted, update Usage examples and Parameters table to match.
  3. Was a workaround needed? — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround.

Only update if the issue is real and reproducible — not speculative.