Skip to content

feat(install): config-driven multi-target sync - #4

Merged
tisDDM merged 5 commits into
mainfrom
feat/install-multi-target-sync
Apr 18, 2026
Merged

tisDDM merged 5 commits into
mainfrom
feat/install-multi-target-sync

Conversation

@flitzrrr

@flitzrrr flitzrrr commented Apr 15, 2026 •

Copy link
Copy Markdown
Collaborator

Was

Installer liest Targets aus config.yaml (targets:-Block) plus OPS_* env vars als Override-Layer. Parsing direkt in Bash über grep/awk/sed — keine externen Dependencies (nur coreutils).

Nebenher gefixt:

  • Claude Code wurde nicht synchronisiert — jetzt auto-detect auf ~/.claude/
  • Antigravity war fälschlich zu OpenCode geroutet — läuft in Wahrheit über die anthropic.claude-code Extension, also über CLAUDE_HOME
  • Symlinks in Zielverzeichnissen wurden überschrieben — jetzt übersprungen und geloggt

Config

targets:
  opencode: { enabled: true, home: ~/.config/opencode }
  codex:    { enabled: auto, home: ~/.codex }
  claude:   { enabled: auto, home: ~/.claude }   # serves Antigravity too

Precedence: OPS_* env > config.yaml > auto-detect.

Vollständiges Schema in config.yaml.example, Env-Var-Liste im install.sh Header.

Bonus: Agents

5 Agent-Dateien (delegate, doc-explorer, implementer, legacy-curator, maintainer) bekommen eine ast-grep-Präferenz für Symbol-Lookups. Strukturell unabhängig vom Installer-Refactor; ist im gleichen PR eingeflossen, weil klein und themennah (Tooling-Hygiene).

Tests

Sandbox-Runs mit 3 Targets (OpenCode/Codex/Claude), hyphenated Keys, Inline-Kommentaren, quoted values, Symlink-Safety, Case-Insensitivity bei OPS_*-Werten — alle grün. bash -n + shellcheck clean.

…-safe sync

The installer previously only wrote to ~/.config/opencode/{skills,agents}.
Users running multiple harnesses (OpenCode + Codex + Claude Code) had to
sync the other targets manually, and every `git pull` silently drifted the
unmanaged copies away from the repo.

Changes:
- Auto-detect Codex: if ~/.codex exists, copy skills to ~/.codex/skills
- Auto-detect Claude Code: if ~/.claude exists, copy skills to
  ~/.claude/skills and agents to ~/.claude/agents
- Antigravity detection hint: logs that OpenCode paths are reused
- Symlink safety: destination paths that are already symlinks are
  skipped (not overwritten), so users who linked the repo directly into
  ~/.claude/skills keep the "git pull = live update" layout
- New env vars: SYNC_CODEX_SKILLS, SYNC_CLAUDE (auto|1|0), CLAUDE_HOME,
  CODEX_HOME, OPENCODE_HOME for full override control

Tested:
- bash -n + shellcheck clean
- default run against live ~/.claude/ and ~/.codex/: symlinked skills
  skipped, agents copied
- SYNC_CLAUDE=0 correctly disables Claude target
- SYNC_CLAUDE=1 with temp CLAUDE_HOME installs into fresh directory
- Symlinks at both skill and agent destinations preserved across runs
Antigravity is a VS Code fork that ships the `anthropic.claude-code`
extension. The extension reads skills/agents from CLAUDE_HOME, so
Antigravity has no config path of its own — the old hint claiming it
"uses OpenCode paths" was wrong.

- Log "served by Claude Code target" when both are present
- Log a warning when Antigravity is present but SYNC_CLAUDE is disabled
  (so the user knows Antigravity will silently go stale)
- Make ANTIGRAVITY_APP_SUPPORT overridable, matching the other home vars,
  so the absence branch is testable

Tested:
- shellcheck clean
- Antigravity + Claude enabled -> served-by log
- Antigravity + SYNC_CLAUDE=0 -> warning
- ANTIGRAVITY_APP_SUPPORT=/nonexistent -> no Antigravity line
- Symlink preservation unchanged
@flitzrrr flitzrrr changed the title feat(install): auto-detect Codex and Claude Code targets with symlink-safe sync feat(install): auto-detect Codex, Claude Code and Antigravity targets with symlink-safe sync Apr 15, 2026
@flitzrrr
flitzrrr requested a review from tisDDM April 15, 2026 09:23

@tisDDM tisDDM left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicht schlecht.
Aber Idee: Statt environment vars alles in die Config.yaml packen. Das wird sonst ein Massaker
Weitere Idee: Wir brauchen einen Skill oder einen Agenten für PRs und Issues. Diese AI Slop Style / Wall of Text Dinger machen mich fertig. Auch wenn sie manuell geprüft oder über arbeitet wurden

…verrides

Moves target configuration from a grab-bag of ad-hoc env vars into a proper
config.yaml schema with a clean three-layer precedence model.

Precedence (highest wins):
  OPS_* env vars  >  config.yaml  >  built-in defaults

config.yaml is optional — a fresh clone still works via auto-detect. The
env vars are now scoped to testing/CI overrides, with an OPS_ prefix to
avoid colliding with tool-native vars like CLAUDE_HOME (which Claude Code
itself may set in the user's environment).

Changes:
- config.yaml gains a `targets:` section with tri-state `enabled`
  (true|false|auto) and per-target `home` paths for opencode, codex, claude
- install.sh parses config.yaml via yq (hard dependency, v4+); the grep/awk
  YAML parser is gone, removing a class of brittleness around quoted values,
  nested structures, and comments-in-values
- Env var rename: SYNC_CLAUDE -> OPS_SYNC_CLAUDE, CLAUDE_HOME -> OPS_CLAUDE_HOME,
  etc. Full list documented in install.sh header and docs/installation.md
- New `is_enabled` helper: single source of truth for true/false/auto
  resolution with an invalid-value warning path
- yq dependency check fires early with a clear brew install hint on failure
- Model parsing (get_model_for_agent, get_additional_delegates) also
  migrated to yq for a consistent parser stack
- docs/installation.md: new "Configuration Layers" section explains the
  precedence model, plus a full env-var reference table
- config.yaml.example: rewritten as the canonical schema doc with inline
  comments for every field

Tested (10/10 green):
- shellcheck clean
- T1  no config.yaml: auto-detect works as before
- T2  yaml disables claude: claude target skipped
- T3  yaml=false + OPS_SYNC_CLAUDE=true: env wins, precedence correct
- T4  yaml home override with ~ expansion: files land in custom dir
- T5  yq missing: clean error message, exit 1
- T6  symlink preservation: pre-existing symlinks in skills+agents skipped
- T7  model injection via yq: correct model: line written to delegate.md
- T8  additional_delegates via yq: delegate-fast, delegate-opus generated
- T9  invalid `enabled` value: warning printed, falls back to auto
- T10 Antigravity detected while claude disabled via yaml: warning printed
@flitzrrr flitzrrr changed the title feat(install): auto-detect Codex, Claude Code and Antigravity targets with symlink-safe sync feat(install): config.yaml-driven multi-target sync with OPS_ env overrides Apr 15, 2026
@flitzrrr flitzrrr changed the title feat(install): config.yaml-driven multi-target sync with OPS_ env overrides feat(install): config-driven multi-target sync Apr 15, 2026
@flitzrrr

Copy link
Copy Markdown
Collaborator Author

Danke für das Feedback.

  1. config.yaml als primary config — in Commit ad3b592 umgesetzt (gepusht nach deinem Review). Env-Vars sind jetzt prefixed (OPS_*) und als Override-Layer für Test/CI dokumentiert, nicht mehr als primäres Interface. Precedence: env > yaml > defaults.
  2. Wall of Text — fair. PR-Body ist gerade radikal gekürzt: keine Diff-Duplikate, keine Fake-Architektur-Diagramme, keine Marketing-Sätze.

Zum Skill/Agent-Vorschlag für PRs und Issues: eigenes Thema, aber lohnenswert. Sag Bescheid, ob ich einen Scope-Issue aufmachen soll.

@flitzrrr
flitzrrr requested a review from tisDDM April 15, 2026 13:03
…w findings

- Remove yq v4+ hard dependency — use only coreutils + grep + awk + sed
- yaml_get_root(): grep-based root-level key lookup (handles hyphenated keys)
- yaml_get_target(): awk-based nested targets parser with indentation detection
- is_enabled(): normalize to lowercase for case-insensitive env var handling
- create_delegate_variant(): add symlink safety check (-L guard)
- get_additional_delegates(): awk parser with inline comment stripping
- agents: add ast-grep preference to delegate, doc-explorer, implementer,
  legacy-curator, maintainer
@tisDDM

tisDDM commented Apr 15, 2026

Copy link
Copy Markdown
Contributor

Review-Driven Refactor Pushed

Hey @flitzrrr — ich habe die Review-Findings direkt gefixt und dazu den yq-Ansatz durch native grep/awk-Parser ersetzt. Die Kernideen deines PRs (Multi-Target, OPS_* Overrides, Symlink-Safety, Antigravity) bleiben vollständig erhalten.

Was sich geändert hat:

yq → grep/awk (Hauptänderung)

  • yaml_get_root(): grep-basierter Root-Level Key-Lookup — funktioniert direkt mit hyphenated Keys wie doc-explorer
  • yaml_get_target(): awk-Parser für targets.<target>.<field> mit Indentation-Detection
  • get_additional_delegates(): awk-Parser mit Inline-Comment-Stripping
  • Keine externen Dependencies mehr — nur coreutils + grep + awk + sed

Review-Findings gefixt:

  1. ✅ BLOCKER Hyphenated Keys: N/A mit grep (war nur ein yq-Problem)
  2. ✅ SHOULD-FIX Silent Errors: Kein yq, kein Problem
  3. ✅ SHOULD-FIX create_delegate_variant() hat jetzt -L Symlink-Guard
  4. ✅ NIT is_enabled() normalisiert auf lowercase (tr '[:upper:]' '[:lower:]')

Bonus — Agent-Dateien (unrelated):
Die 5 Agent-Files (delegate.md, doc-explorer.md, implementer.md, legacy-curator.md, maintainer.md) haben ast-grep-Preference-Anweisungen bekommen. Bitte schau dir die auch kurz an.

Getestet:

  • 3 Sandbox-Targets (OpenCode/Codex/Claude): Skills + Agents installiert ✅
  • Hyphenated Key Model-Injection (doc-explorer, legacy-curator) ✅
  • Delegate-Varianten mit korrektem Model + Description ✅
  • Symlink-Safety für Skills UND Delegate-Varianten ✅
  • No-Config + OPS_* Overrides ✅
  • Case-Insensitivity (TRUE/FALSE) ✅

Bitte nochmal drüberschauen und ggf. approven 🙏

…idate OPS_CONFIG_FILE

Follow-up to the native grep/awk parser from 6e980eb. Addresses review
findings on robustness and consistency.

- yaml_get_root/yaml_get_target now strip " #..." inline comments and
  surrounding single/double quotes via a shared _yaml_clean helper.
  Fixes values like "home: ~/.codex  # laptop path" leaking garbage into
  directory paths and model IDs.
- OPS_CONFIG_FILE pointing to a non-existent file now fails fast with a
  clear error — silent fallback to defaults was a CI/test footgun.
- yaml_get_target comment documents the 2-space indentation requirement;
  config.yaml.example mirrors the note.
- Antigravity path comment clarifies its macOS-only default.
- Drop redundant trailing echo after Step 1 and Step 2 loops (each loop
  already prints a per-target separator).
@flitzrrr

Copy link
Copy Markdown
Collaborator Author

Danke Tim — Refactor sieht gut aus, habe drübergeschaut und die Agent-Änderungen sind ebenfalls ok.

Ein paar Follow-up-Fixes aus dem eigenen Review sind in 8b56b91 drin:

  • YAML-Parser härten: gemeinsamer _yaml_clean-Helper strippt jetzt sowohl inline " #..."-Kommentare als auch surrounding "..."/'...'-Quotes. Werte wie home: ~/.codex # laptop oder home: "~/.claude" waren sonst an den Parser durchgelaufen und hätten beim [ -d "$home" ]-Check still fehlschlagen können.
  • OPS_CONFIG_FILE-Validation: wenn die Variable explizit auf einen nicht existierenden Pfad zeigt, failt der Installer jetzt früh statt stumm auf Defaults zurückzufallen. Vor allem in CI/Test-Szenarien wichtig.
  • Indentation-Requirement für yaml_get_target im Code-Kommentar und in config.yaml.example dokumentiert (Parser erwartet 2-Space).
  • Antigravity-Pfad als macOS-only gekennzeichnet (Kommentar im Code).
  • Doppelte Leerzeilen nach Step 1 und Step 2 entfernt.

PR-Body ist außerdem aktualisiert — die yq-Dependency-Sektion war nach deinem Refactor falsch geworden.

Getestet mit Sandbox-Run über alle 3 Targets + Config-Szenarien (quoted values, inline comments, hyphenated keys, missing OPS_CONFIG_FILE). Von meiner Seite mergebereit.

@tisDDM
tisDDM merged commit 4dbb1b0 into main Apr 18, 2026
@tisDDM
tisDDM deleted the feat/install-multi-target-sync branch April 18, 2026 08:09
tisDDM added a commit that referenced this pull request Jun 4, 2026
…active orchestration

Agent routing changes:
- Remove standard 'delegate' from routing table (fast + strong only)
- Promote delegate-strong from 'escalation' to primary judgment/synthesis agent
- delegate-fast: add explicit anti-patterns (not for analysis/synthesis/impl)
- Lifecycle: all 3 review steps delegate → delegate-strong

Rule changes:
- Rule #3: add proactive orchestration paragraph — decompose complex goals
  into subagent tasks without waiting for explicit instructions
- Rule #4: 'Context is a budget' → 'Context hygiene' — softer framing
  (maintainer model not expensive/context-restricted; lean = sharper judgment)

Review escalation: update framing — strong is already the default reviewer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants