################################################################################
# llmenv example configuration — phaedrus@personal-laptop.local
#
# This is a *sanitized copy* of a real personal llmenv setup. It is meant to be
# read as documentation, not just data. Every section below explains why the
# setting exists, how it interacts with other settings, and what assumptions it
# encodes about scopes and engines.
#
# Layout this file expects:
#   config.yaml         — top-level schema (cache, capabilities, scopes, bundles,
#                         marketplaces, plugin-collections, MCP servers, memory)
#   bundles/<name>/     — per-bundle directories containing AGENTS.md, rules/,
#                         skills/, commands/, hooks/, and an optional bundle.yaml
#                         capability fragment.
#
# How to test changes:
#   LLMENV_CONFIG_DIR=/Users/phaedrus/git/my-llmenv llmenv doctor
#   LLMENV_CONFIG_DIR=/Users/phaedrus/git/my-llmenv llmenv status
#   LLMENV_CONFIG_DIR=/Users/phaedrus/git/my-llmenv llmenv export
#
# See also:
#   - RELEASING.md (branch/version policy for the llmenv project itself)
#   - docs/design/engine-capabilities.md (how top-level + bundle fragments merge)
#   - crates/llmenv-config/src/schema.rs (the actual serde schema)
################################################################################

# Cache topology.
#
# llmenv keeps downloaded marketplaces, plugin manifests, and materialized
# engine configs under a single root. A one-hour sync interval is aggressive
# enough for daily work without cloning marketplaces on every session start.
# Seven-day retention means stale plugin tarballs die automatically; normal
# hashing keeps the cache comparable across hosts that share the same source.
cache:
  cache_dir: "~/.cache/llmenv"
  sync_interval_minutes: 60
  cache_retention_hours: 168
  hashing: normal

################################################################################
# Session logging.
#
# llmenv records session activity into a single event stream that fans out to
# two independent sinks: a local JSONL file and ICM's transcript store (via the
# ICM MCP — works even when this host is not the primary ICM host).
#
#   transcript: true   ICM transcript (default ON). Discoverable later by tag
#                      via `icm_transcript_search "llmenv-tag:<tag>"`.
#   file: false        Mirror the same stream to a local JSONL file.
#   verbose: false     Also capture per-hook prompts and tool use, not just the
#                      scope header + lifecycle. WARNING: captures raw prompt
#                      and tool content unredacted, including any secrets you
#                      paste — treat the resulting log like shell history.
#
# Omitting this block entirely is equivalent to `transcript: true` (ICM only).
# This is NOT the same thing as the `bundles/base/hooks/session-log.sh` example
# hook, which is a user-authored bundle hook unrelated to this built-in feature.
################################################################################
session_log:
  transcript: true
  file: false
  verbose: false

################################################################################
# Engine-agnostic capabilities.
#
# This block defines permissions, native-permission passthrough, hooks, and
# plugins that are *universal* (selected by the `user-phaedrus` tag in the
# bundle section below). Bundle-contributed fragments in bundles/*/bundle.yaml
# use the same shape and are merged by llmenv at materialize time:
#   - list values concatenate and deduplicate
#   - scalar values resolve by scope precedence (host > user > network > project)
#
# That merge model is why host-specific tools (plexctl, security, etc.) live in
# bundles/personal-laptop-host/bundle.yaml instead of here: they only make sense
# on one machine. The base bundle (bundles/base/bundle.yaml) contributes the
# session-log hook + codebase-memory MCP server for every session that selects the
# user scope.
#
# For the schema, see llmenv's crates/llmenv-config/src/schema.rs and the
# engine-capabilities design doc in the main repo.
################################################################################
capabilities:
  permissions:
    # default_mode is a fallback used when no explicit allow/deny matches.
    # We default to "default" rather than "ask" because the `deny:` list below
    # catches the really dangerous patterns; everything else can be decided by
    # the engine's own prompt gating.
    default_mode: default

    # Universal Bash allow patterns. These commands are safe enough to permit
    # on every host. The engine still validates the literal command string, so
    # wildcards must be explicit; this is not a shell interpreter.
    #
    # Git commands are grouped here because nearly every project interaction
    # needs status, diff, log, branch, checkout, pull, push, fetch, merge, and
    # merge-base. `git add` is allow-listed with a colon suffix so it does not
    # catch unrelated commands.
    allow:
      # --- GitHub CLI (read-only project plumbing) ---------------------------
      - { tool: Bash, pattern: "gh pr *" }
      - { tool: Bash, pattern: "gh issue *" }
      - { tool: Bash, pattern: "gh run *" }
      - { tool: Bash, pattern: "gh api *" }

      # --- core git workflow --------------------------------------------------
      - { tool: Bash, pattern: "git status" }
      - { tool: Bash, pattern: "git diff *" }
      - { tool: Bash, pattern: "git log *" }
      - { tool: Bash, pattern: "git branch *" }
      - { tool: Bash, pattern: "git checkout *" }
      - { tool: Bash, pattern: "git pull *" }
      - { tool: Bash, pattern: "git push *" }
      - { tool: Bash, pattern: "git fetch *" }
      - { tool: Bash, pattern: "git merge *" }
      - { tool: Bash, pattern: "git add:*" }
      - { tool: Bash, pattern: "git merge-base:*" }

      # --- local productivity scripts -----------------------------------------
      # rtk (Rust Token Killer) intercepts expensive Bash calls and proxies them
      # through a token-saving filter. It is defined as a PreToolUse hook in
      # bundles/personal-laptop-host/bundle.yaml because it is host-specific.
      - { tool: Bash, pattern: "rtk *" }
      - { tool: Bash, pattern: "yx *" }
      - { tool: Bash, pattern: "wc *" }
      - { tool: Bash, pattern: "ls ~/**" }
      - { tool: Bash, pattern: "trash *" }
      - { tool: Bash, pattern: "shellcheck *" }
      - { tool: Bash, pattern: "grep *" }
      - { tool: Bash, pattern: "semgrep *" }
      # slop-scan is a custom bundle hook for catching low-quality output.
      - { tool: Bash, pattern: "/Users/phaedrus/git/my-llmenv/bundles/base/scripts/slop-scan.sh *" }
      - { tool: Bash, pattern: "just ci" }

      # --- safe scratch space -------------------------------------------------
      # Reading/writing under ./.tmp is allowed so plans and temporary artifacts
      # can live next to the project without escaping into arbitrary paths.
      - { tool: Read, pattern: "./.tmp/**" }
      - { tool: Write, pattern: "./.tmp/**" }

      # --- web search (no domain restriction at top level) --------------------
      - { tool: WebSearch }

    # Deny patterns are evaluated before allow patterns (deny wins). Keep the
    # list small and unambiguous: anything matching these is blocked outright
    # rather than prompt-gated.
    deny:
      # Destructive system commands.
      - { tool: Bash, pattern: "rm -rf *" }
      - { tool: Bash, pattern: "rm -fr *" }
      - { tool: Bash, pattern: "sudo *" }
      - { tool: Bash, pattern: "mkfs *" }
      - { tool: Bash, pattern: "dd *" }

      # Piped-to-shell installers are almost always the wrong thing to run.
      - { tool: Bash, pattern: "curl *|bash*" }
      - { tool: Bash, pattern: "wget *|bash*" }

      # Git history destruction.
      - { tool: Bash, pattern: "git push --force*" }
      - { tool: Bash, pattern: "git push *--force*" }
      - { tool: Bash, pattern: "git reset --hard*" }

      # Shell rc files must never be edited automatically; they outlive any
      # single project and are not version-controlled by llmenv.
      - { tool: Edit, paths: ["~/.bashrc", "~/.zshrc"] }
      - { tool: Edit, paths: ["~/.ssh/**"] }

      # Credential stores are never readable.
      - { tool: Read, paths: ["~/.ssh/**"] }
      - { tool: Read, paths: ["~/.gnupg/**"] }
      - { tool: Read, paths: ["~/.aws/**"] }
      - { tool: Read, paths: ["~/.azure/**"] }
      - { tool: Read, paths: ["~/.config/gh/**"] }
      - { tool: Read, paths: ["~/.git-credentials"] }
      - { tool: Read, paths: ["~/.docker/config.json"] }
      - { tool: Read, paths: ["~/.kube/**"] }
      - { tool: Read, paths: ["~/.npmrc"] }
      - { tool: Read, paths: ["~/.npm/**"] }
      - { tool: Read, paths: ["~/.pypirc"] }
      - { tool: Read, paths: ["~/.gem/credentials"] }

      # macOS-specific: keychains and crypto wallet stores.
      - { tool: Read, paths: ["~/Library/Keychains/**"] }
      - { tool: Read, paths: ["~/Library/Application Support/**/metamask*/**"] }
      - { tool: Read, paths: ["~/Library/Application Support/**/electrum*/**"] }
      - { tool: Read, paths: ["~/Library/Application Support/**/exodus*/**"] }
      - { tool: Read, paths: ["~/Library/Application Support/**/phantom*/**"] }
      - { tool: Read, paths: ["~/Library/Application Support/**/solflare*/**"] }

  # Per-engine raw permission strings. Use only when the neutral vocabulary
  # cannot express the grant: MCP tool wildcards, domain-bound WebFetch, and
  # engine-specific skills are the canonical cases.
  native_permissions:
    claude_code:
      allow:
        # Context7 / long-term memory / context-mode plugin families.
        - "mcp__context7__*"
        - "mcp__icm__*"
        - "mcp__plugin_context-mode_context-mode__*"
        # GitHub MCP connector from the Claude plugin market.
        - "mcp__plugin_github_github__*"
        # Domain-locked fetches for package docs and reference sites.
        - "WebFetch(domain:pub.dev)"
        - "WebFetch(domain:getsongbpm.com)"
        - "WebFetch(domain:godot-rust.github.io)"
        # Engine skill: sharp-edges flags risky patterns during refinement.
        - "Skill(sharp-edges)"

  # IMPORTANT: context-mode's hooks are NOT duplicated here. The context-mode
  # plugin (plugin-collection `core` → context-mode:context-mode) ships its own
  # hooks/hooks.json, where ${CLAUDE_PLUGIN_ROOT} resolves correctly. Copying
  # those entries into native_hooks pushes them into top-level settings.json,
  # where ${CLAUDE_PLUGIN_ROOT} cannot resolve and produces a SessionStart hook
  # error. Let the plugin own its own hooks.

  # Universal hooks (every host). Host- and project-scoped hooks live in the
  # bundle.yaml of bundles tagged for those scopes (see bundles/base and
  # bundles/personal-laptop-host).
  hooks:
    # Block recursive `rm -rf` / `rm -r -f` invocations before they reach the
    # shell. This is intentionally a guard, not a permission: `trash` is the
    # preferred recoverable delete on macOS.
    - event: PreToolUse
      matcher: Bash
      handler:
        type: command
        command: |
          CMD=$(jq -r '.tool_input.command'); if echo "$CMD" | grep -qE 'rm[[:space:]]+-[^[:space:]]*r[^[:space:]]*f'; then echo 'BLOCKED: Use trash instead of rm -rf' >&2; exit 2; fi

  # Top-level plugins list is empty because all plugins are selected through
  # `plugin-collection:` below. Keeping it explicit documents that the list is
  # intentionally unused.
  plugins: []

# Per-engine native passthrough. These values are written verbatim into the
# engine's own configuration file (settings.json for Claude Code).
#
# WARNING: bundle-level `native:` blocks are currently dropped at materialize
# time (llmenv 1.0.2). Put engine-native settings here if they must survive.
native:
  claude_code:
    # Long cleanup horizon for ephemeral session artifacts.
    cleanupPeriodDays: 365

    # Status line configuration lives here (top-level native), not in bundles,
    # because llmenv only merges the top-level `native:` block for Claude Code.
    statusLine:
      type: command
      command: "/usr/local/bin/rusty-claude-status"

    # Environment variables injected into every Claude Code session.
    env:
      # Cap Bash tool output so the context window is not swamped accidentally.
      BASH_MAX_OUTPUT_LENGTH: "10000"

      # Autocompact when context crosses the halfway mark.
      CLAUDE_AUTOCOMPACT_PCT_OVERRIDE: "50"

      # Disable background tasks, feedback surveys, and non-essential traffic so
      # the local sessions are deterministic and quiet.
      CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: "1"
      CLAUDE_CODE_DISABLE_FEEDBACK_SURVEY: "1"
      CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1"

      # Enable agent teams and a fixed subagent model (sonnet-4-6) for
      # predictable multi-agent behavior.
      CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: "1"
      CLAUDE_CODE_SUBAGENT_MODEL: "claude-sonnet-4-6"

      # Telemetry off. These are paired with the user-level config choice.
      DISABLE_ERROR_REPORTING: "1"
      DISABLE_TELEMETRY: "1"

      # Exclude claude.ai account MCP connectors from this config dir. They are
      # account-synced (not llmenv-managed) and inject a large tool catalog
      # (~45k tokens) of irrelevant connectors into every session.
      ENABLE_CLAUDEAI_MCP_SERVERS: "false"

      # Hour-long prompt caching window for repeated tool schemas and skills.
      ENABLE_PROMPT_CACHING_1H: "1"

      # Bound MCP server output to avoid surprise context exhaustion.
      MAX_MCP_OUTPUT_TOKENS: "10000"

      # Keep context-mode's session/memory state outside the llmenv cache dir
      # (CLAUDE_CONFIG_DIR), which is regenerated on every config-hash change.
      # Without this, context-mode loses its history each time the hash moves.
      CONTEXT_MODE_DATA_DIR: "~/.context-mode"

################################################################################
# Scopes — conditions that activate tags.
#
# A scope is a predicate (hostname, SSID, user, project tag, etc.). When a
# predicate matches, its tags are added to the active tag set. Bundles and
# plugin-collections then fire based on `when:` tag intersection:
#   when: [tag-a, tag-b]  → fires only if BOTH tags are active.
#
# Host scopes are evaluated first, then user, network, and the tags from a
# project's local `.llmenv.yaml` take effect inside that project directory.
# Because the bundle `when:` list is an intersection, use broad tags like
# `personal` or `work` to group bundles, and narrow tags like `host-fixed` for
# one-machine-only capabilities.
################################################################################
scope:
  # --- Host scopes -----------------------------------------------------------
  # Each host maps its hostname to a set of tags. `personal-laptop` and `fixed`
  # are both personal machines; they share the `personal` tag so bundles that
  # should run on both declare `when: [personal]`. Host-specific bundles
  # (e.g. personal-laptop-host) use the narrower host tag.
  host:
    - id: personal-laptop
      match: { hostname: "personal-laptop.local" }
      tags: [host-personal-laptop, personal]

    - id: fixed
      match: { hostname: "fixed" }
      tags: [host-fixed, personal]

    - id: work-laptop
      match: { hostname: "work-laptop.local" }
      tags: [host-work-laptop, work]

  # --- User scopes -----------------------------------------------------------
  user:
    - id: phaedrus
      match: { user: "phaedrus" }
      tags: [user-phaedrus]

  # --- Network scopes --------------------------------------------------------
  # Home network is identified by SSID. The `home` tag enables the `home` bundle
  # (plex skill), and `trusted-network` can be used to relax settings that
  # should only run on a known LAN.
  network:
    - id: home
      match: { ssid: "MyWifiSSID" }
      tags: [home, trusted-network]

################################################################################
# Bundles — content + (via bundle.yaml) capability fragments.
#
# Order does not matter for selection, but it matters for documentation: list
# base first, then host, then project-type bundles. A bundle only fires when
# every tag in its `when:` list is active. The content it carries
# (AGENTS.md/rules/skills/commands) is loaded by the engine's prompt system;
# its bundle.yaml fragment is merged into capabilities.
################################################################################
bundle:
  # Base bundle: universal rules, skills, commands, and the context-mode
  # cache-heal hook. Selected by the `user-phaedrus` tag so it loads for every
  # session run as this user. See bundles/base/bundle.yaml.
  - name: base
    when: [user-phaedrus]

  # Host bundle for the personal laptop. Contains macOS-specific permissions
  # (security, plutil, homebrew tooling), the rtk hook, and the claude-control
  # status hooks. See bundles/personal-laptop-host/bundle.yaml.
  - name: personal-laptop-host
    when: [host-personal-laptop]

  # Personal / non-work bundle. A placeholder for rules and skills that should
  # only run outside the work-laptop host scope. Currently no directory exists
  # because the personal rules are still in base; this tag is reserved.
  - name: personal
    when: [personal]

  # Work profile: fires on the `work` tag emitted by the work-laptop host
  # scope. Pairs with the `work` plugin-collection below, which wires the
  # official Slack MCP plugin (claude-plugins-official:slack). See
  # bundles/work/bundle.yaml for the read-only grid-MCP grants.
  - name: work
    when: [work]

  # Home network bundle: fires on the `home` tag (SSID "MyWifiSSID"). Carries
  # the plex skill because the local media server is only reachable at home.
  - name: home
    when: [home]

  # Language and framework bundles. These are activated by tags emitted from a
  # project's local `.llmenv.yaml` (see llmenv issue #164). Each bundle carries
  # style rules, commands, and any language-specific plugin collections.
  - name: rust-dev
    when: [lang-rust]

  - name: python-dev
    when: [lang-python]

  - name: lang-c-cpp
    when: [lang-c, lang-cpp]

  # Windows PowerShell 5.1 (Desktop edition) baseline; includes PSScriptAnalyzer
  # hook, security hardening rules, and style conventions.
  - name: lang-powershell
    when: [lang-powershell]

  # Web/TypeScript project defaults. Shares the `web` tag with the typescript-lsp
  # plugin collection and the playwright MCP server.
  - name: web-dev
    when: [web]

  # Kubernetes project rules — manifests/workload conventions plus Rust
  # operator and CRD-design rules.
  - name: kubernetes
    when: [kubernetes]

  # Docker build rules — multi-stage build hygiene and image hardening.
  - name: docker
    when: [docker]

  # Finance bundle: carries the InvestSkill plugin (US-stock analysis
  # frameworks). Fires on the `finance` tag.
  - name: finance
    when: [finance]

################################################################################
# Plugin marketplaces.
#
# Each marketplace is cloned into ~/.cache/llmenv/marketplaces/<name>/ and
# referenced by `plugin-collection` entries as `<name>:<plugin>`. The `name:`
# here is a local alias; it does not have to match the repo name.
#
# Private Git host aliases (e.g. github-phaedrus) are resolved by the user's
# SSH config and keep the marketplace source portable between machines that
# share the same alias definitions.
################################################################################
marketplace:
  - name: claude-plugins-official
    source: "https://github.com/anthropics/claude-plugins-official"

  - name: trailofbits
    source: "https://github-phaedrus/trailofbits/skills"

  - name: skills-curated
    source: "https://github-phaedrus/trailofbits/skills-curated"

  # Personal commons repo. Holds private/team plugins and the `llmenv-dev`
  # workflow plugin used by the `llmenv` plugin-collection below.
  - name: llmenv-commons
    source: "git@github-phaedrus:phaedrus1992/llmenv-commons"

  - name: context-mode
    source: "https://github-phaedrus/mksglu/context-mode"

  - name: agent-browser
    source: "https://github.com/vercel-labs/agent-browser"

  - name: caveman
    source: "https://github.com/JuliusBrussee/caveman"

  - name: rust-skills
    source: "https://github-phaedrus/actionbook/rust-skills"

  - name: godot-claude-skills
    source: "https://github-phaedrus/alexmeckes/godot-claude-skills"

  - name: fullstack-dev-skills
    source: "https://github-phaedrus/jeffallan/claude-skills"

  - name: invest-skill
    source: "https://github.com/yennanliu/InvestSkill"

  - name: i-have-adhd
    source: "https://github.com/ayghri/i-have-adhd"

  - name: ponytail
    source: "https://github.com/DietrichGebert/ponytail"

  - name: ghcp-dev-plugin
    source: "https://github.com/shouenlee/ghcp-dev-plugin"

################################################################################
# Plugin collections — selected onto scopes by tag intersection.
#
# Each collection is a named set of plugins from the marketplaces above. The
# `when:` tags work the same way as bundles: all listed tags must be active for
# the collection to load. Plugins are referenced as `<marketplace>:<plugin>`.
#
# Ordering here is mostly for documentation. Within a collection, plugins are
# loaded in list order and later duplicates are deduplicated.
################################################################################
plugin-collection:
  # Core dev plugins. Tagged for `user-phaedrus` so they activate everywhere
  # this user runs a session.
  - name: core
    when: [user-phaedrus]
    plugins:
      # - "caveman:caveman"  # currently disabled pending upstream cleanup
      - "claude-plugins-official:commit-commands"
      - "claude-plugins-official:code-review"
      - "claude-plugins-official:code-simplifier"
      - "claude-plugins-official:feature-dev"
      - "claude-plugins-official:plugin-dev"
      - "claude-plugins-official:pr-review-toolkit"
      - "claude-plugins-official:superpowers"
      # context-mode is now wired by the built-in `features.context_mode`
      # toggle (see the features: block below), so it no longer needs a manual
      # entry here. Declaring it both ways emits a redundant-declaration warning.
      # - "context-mode:context-mode"
      - "i-have-adhd:i-have-adhd"
      - "ponytail:ponytail"
      - "trailofbits:gh-cli"
      - "trailofbits:git-cleanup"
      - "ghcp-dev-plugin:deep-review"

  # Disabled extras kept as a reference for what can be opted into later.
  # - name: extra-dev-disabled
  #   tags: []
  #   plugins:
  #     - "claude-plugins-official:context7"
  #     - "claude-plugins-official:github"
  #     - "claude-plugins-official:claude-md-management"
  #     - "claude-plugins-official:security-guidance"
  #     - "claude-plugins-official:skill-creator"

  # Frontend plugins. Activated by the `web` tag from web-dev bundles or a
  # project's `.llmenv.yaml`.
  - name: frontend
    when: [web]
    plugins:
      - "claude-plugins-official:frontend-design"
      - "agent-browser:agent-browser"

  # Work profile plugins. Fires on the `work` tag (work-laptop host).
  # The official Slack integration (slackapi/slack-mcp-plugin) ships its own
  # .mcp.json, so enabling the plugin wires up the Slack MCP server.
  - name: work
    when: [work]
    plugins:
      - "claude-plugins-official:slack"

  # Trail of Bits security + skill tooling. Activated by the `security` tag.
  - name: security
    when: [security]
    plugins:
      - "trailofbits:agentic-actions-auditor"
      - "trailofbits:ask-questions-if-underspecified"
      - "trailofbits:differential-review"
      - "trailofbits:dimensional-analysis"
      - "trailofbits:entry-point-analyzer"
      - "trailofbits:insecure-defaults"
      - "trailofbits:modern-python"
      - "trailofbits:mutation-testing"
      - "trailofbits:property-based-testing"
      - "trailofbits:sharp-edges"
      - "trailofbits:skill-improver"
      - "trailofbits:static-analysis"
      - "trailofbits:variant-analysis"

  # llmenv Labs / personal workflow plugins from the commons marketplace.
  - name: llmenv
    when: [user-phaedrus]
    plugins:
      - "llmenv-commons:llmenv-dev"

  # Language-server plugins, scoped by language tag.
  - name: rust-lsp
    when: [lang-rust]
    plugins:
      - "claude-plugins-official:rust-analyzer-lsp"
      - "rust-skills:rust-skills"

  - name: typescript-lsp
    when: [lang-typescript, web]
    plugins:
      - "claude-plugins-official:typescript-lsp"
      - "fullstack-dev-skills:fullstack-dev-skills"

  - name: swift-lsp
    when: [lang-swift]
    plugins:
      - "claude-plugins-official:swift-lsp"

  - name: clangd
    when: [lang-c, lang-cpp]
    plugins:
      - "claude-plugins-official:clangd-lsp"

  - name: godot
    when: [godot]
    plugins:
      - "godot-claude-skills:godot-claude-skills"

  # InvestSkill — US-stock analysis frameworks.
  - name: finance
    when: [finance]
    plugins:
      - "invest-skill:us-stock-analysis"

################################################################################
# MCP servers — selected by tag, rendered into the agent's MCP config.
#
# These are external tool servers started on demand. The `playwright` server
# is only loaded when the `web` tag is active, keeping non-web sessions lean.
#
# The `icm` server is llmenv's memory backend; it is configured under the
# `memory:` / `host:` blocks below, not here, because the config needs both a
# server_host and listen_host.
################################################################################
mcp:
  - name: playwright
    when: [web]
    type: stdio
    command: npx
    args: ["@playwright/mcp@latest"]

################################################################################
# LSP servers — selected by tag, rendered into the agent's LSP config.
#
# Only engines with an LSP surface render these (Crush, Claude Code); it's a
# silent no-op elsewhere, so it's safe to declare alongside engine-neutral
# bundles. `filetypes`/`root_markers` are Crush-only; `extension_to_language`
# is Claude Code-only (and required there — see configuration.md#lsp).
################################################################################
lsp:
  - name: rust-analyzer
    when: [rust]
    command: rust-analyzer
    filetypes: ["rust"]
    root_markers: ["Cargo.toml"]
    extension_to_language:
      ".rs": rust

################################################################################
# Memory backend (llmenv's ICM topology).
#
# `personal-laptop` runs the daemon; every selected host points at it. The `host:`
# mapping resolves the abstract server_host name to a reachable address.
#
# Why `listen_host: 0.0.0.0` on a personal laptop? Because other local agents
# (multi-agent workflows spawned in separate worktrees) may connect back to the
# same daemon. Binding only loopback would prevent those cross-process reads.
# Port 9092 is the conventional default used by the ICM CLI.
################################################################################
host:
  personal-laptop:
    addr: "personal-laptop.local"

features:
  memory:
    - server_host: personal-laptop
      listen_host: 0.0.0.0
      port: 9092
      when: [user-phaedrus]

  # Built-in context-saving (#490). Enabling this wires the context-mode plugin
  # automatically: marketplace + plugin + durable CONTEXT_MODE_DATA_DIR + the MCP
  # permission grant. Replaces the manual plugin-collection / state / permission
  # boilerplate. context-mode is loaded as a *plugin* (not an MCP) so its hooks
  # resolve ${CLAUDE_PLUGIN_ROOT}.
  context_mode:
    enabled: true
