# Corentic Package Manager (CPM) Ein **CPM-Package** ist ein Agent-Package bestehend aus einem [APM](https://microsoft.github.io/apm/)-Manifest plus Team-Konfiguration (`team-profile.yaml`). Der Corentic Package Manager übersetzt dieses Package in die native Konfiguration eines Ziel-Harnesses. Übersetzungsziele: | Ziel-Harness | Status | |---|---| | [oh-my-opencode-slim](https://ohmyopencodeslim.com/) | ✅ implementiert | | oh-my-pi | geplant | | Codex / Claude / Copilot | Vision | Deterministisch – der CPM rät nicht. Er nimmt keine Verfügbarkeit an und wählt keine Modelle automatisch aus. ``` CPM-Package Nutzer Runtime apm.yml + + model-mapping.yaml → cpm render → .opencode/ team-profile.yaml (Modellklasse → oh-my-opencode-slim.json (Rollen, Modell- konkrete Modell-ID) (oder künftig: natives klassen, MCPs/Skills) Config eines anderen Harness) ``` ## Voraussetzungen - Python 3.10+ mit PyYAML (`pip install pyyaml`) - OpenCode mit installiertem Plugin [oh-my-opencode-slim](https://github.com/alvinunreal/oh-my-opencode-slim) - Ein CPM-Package mit `team-profile.yaml` ## Schnellstart ```bash # 1. Modell-Mapping anlegen – interaktiv, mit Auswahl aus deinen opencode-Modellen python3 cpm.py init --fill # 2. Geführt: Team-Profil lesen, Mapping prüfen/auffüllen, rendern cd python3 /pfad/zu/cpm.py setup --package /pfad/zum/package # 3. Aktivieren opencode # Projekt-Config wird geladen /preset acme-job-applications # Reload OpenCode → Team aktiv (by Design: kein Hot-Swap) ``` Alternativ manuell: ```bash # 1. Modell-Mapping einmalig anlegen mkdir -p ~/.config/cpm cp examples/model-mapping.yaml ~/.config/cpm/model-mapping.yaml $EDITOR ~/.config/cpm/model-mapping.yaml # an eigene Modelle anpassen # 2. Validieren (Dry-Run) python3 cpm.py check --package examples/package # 3. Rendern cd python3 /pfad/zu/cpm.py render --package /pfad/zum/package ``` ## Die drei Dateien | Datei | Gehört | Zweck | Manuell editieren? | |---|---|---|---| | `team-profile.yaml` | Package-Autor | Rollen, Modellklassen, MCP-/Skill-Allowlists pro Rolle | Ja (Autor) | | `~/.config/cpm/model-mapping.yaml` | Nutzer | Modellklasse → konkrete Modell-ID (+ optional variant/temperature) | Ja (Nutzer) | | `.opencode/oh-my-opencode-slim.json` | generiert | Preset mit konkreten Modell-IDs | **Nein** – immer neu rendern | Dazu eine Provenance-Datei `.opencode/oh-my-opencode-slim.cpm-provenance.json`, die dokumentiert, welche Rolle welches Modell erhalten hat. ## Kommandoreferenz ```bash python3 cpm.py init [--mapping FILE] [--fill] # Mapping anlegen/füllen python3 cpm.py setup --package DIR [--mapping F] ... # geführter Ablauf python3 cpm.py render --package DIR [--mapping F] [--output F] [--dry-run] python3 cpm.py check --package DIR [--mapping F] # Dry-Run-Validierung ``` ### `init` – Mapping anlegen Erstellt `~/.config/cpm/model-mapping.yaml` (falls nicht vorhanden). Mit `--fill` werden alle `PLACEHOLDER`-Klassen interaktiv abgefragt: der CPM listet alle Modelle aus deiner `opencode.json(c)` auf, du wählst per Nummer oder gibst eine Modell-ID manuell ein. ### `setup` – Geführter Ablauf Der Ein-Kommando-Weg: zeigt das Team-Profil verständlich an, legt fehlendes Mapping an, fragt fehlende Modellklassen interaktiv ab (gleiche Auswahl wie `init --fill`), rendert und gibt die Aktivierungsschritte aus. ### `render` / `check` | Option | Default | Bedeutung | |---|---|---| | `--package` | `.` | CPM-Package-Verzeichnis mit `team-profile.yaml` | | `--mapping` | `~/.config/cpm/model-mapping.yaml` | Lokale Mapping-Tabelle | | `--output` | `/.opencode/oh-my-opencode-slim.json` | Zieldatei | | `--team-file` | `team-profile.yaml` (alternativ `team.yaml`) | Alternativer Profilname | **Merge-Verhalten:** Existierende Presets in der Zieldatei bleiben unberührt; nur das Preset der Team-ID wird ersetzt. Mehrere Packages koexistieren damit im selben Projekt. Aktiviert wird explizit per `/preset `. ## Team-Profil-Schema (`corentic.team-profile/v1`) ```yaml schema: corentic.team-profile/v1 id: acme.job-applications # wird zum Preset-Namen (namespaced) description: ... roles: - id: researcher # fachliche Rolle purpose: ... # wird zu Prompt/Description für Custom Agents runtime_agent: librarian # optional: Harness-Builtin oder 'custom' # (Default: role-id als Custom Agent) model_class: fast-research # Pflicht, muss im Mapping existieren capabilities: mcps: [websearch, openviking] # MCP-Allowlist ([] = keine) skills: [job-application] # Skill-Allowlist ([] = keine) ``` Das Feld `runtime_agent` ist bewusst harness-neutral benannt: Der Adapter entscheidet, wie die Rolle im Ziel-Harness repräsentiert wird. Erkannte Builtins des oh-my-opencode-slim-Adapters: `orchestrator`, `oracle`, `librarian`, `explorer`, `fixer`, `designer`, `council`, `observer`. Alles andere (oder `runtime_agent: custom`) erzeugt einen Custom Agent inklusive `prompt` und `orchestratorPrompt` aus dem `purpose`-Feld. ### Mapping-Formate ```yaml model_classes: fast-research: ollama/qwen3.5:9b # einfach high-reasoning: # erweitert model: ollama/qwen3.6:35b-a3b-q4_K_M variant: thinking temperature: 0.3 ``` Alle Zusatzfelder werden 1:1 in den Agent-Eintrag des Presets übernommen. ## Was der CPM prüft 1. Team-Profil vorhanden, Schema bekannt, `id` und `roles` vorhanden 2. Jede `model_class` hat einen Mapping-Eintrag (sonst Fehler mit Lösungshinweis) 3. MCPs gegen `~/.config/opencode/opencode.json(c)` abgleichen (**Warnung**, kein Abbruch) 4. Rollen ohne MCPs/Skills → Hinweis ## Beispiele | Beispiel | Basis | Team | |---|---|---| | `examples/package/` | Eigenes `job-application`-Package (OpenViking + ShareLaTeX) | `acme.job-applications` – Researcher, Writer, Checker, Notifier | | `examples/microsoft-design-review/` | Offizielles [microsoft/apm-sample-package](https://github.com/microsoft/apm-sample-package) | `acme.design-review` – Reviewer (Oracle), Style-Checker (Fixer), Accessibility-Auditor | | `examples/microsoft-issue-autopilot/` | Offizielles [`apm-issue-autopilot`](https://github.com/microsoft/apm/tree/main/packages/apm-issue-autopilot) aus dem microsoft/apm-Repo | `acme.issue-autopilot` – Triager, Shepherd, PR-Writer, Reviewer (+ GitHub-MCP) | Die beiden Microsoft-Beispiele sind dünne CPM-Wrapper: Das eigene `apm.yml` zieht das offizielle Package als versionierte APM-Dependency (`microsoft/apm-sample-package#v1.0.0` bzw. Monorepo-Subpath `microsoft/apm/packages/apm-issue-autopilot`) und liefert nur die Team-Empfehlung dazu. ```bash cd corentic-package-manager/examples # Trockenlauf: was würde generiert? python3 ../cpm.py check --package package --mapping model-mapping.yaml python3 ../cpm.py check --package microsoft-design-review --mapping model-mapping.yaml python3 ../cpm.py check --package microsoft-issue-autopilot --mapping model-mapping.yaml # Rendern in das Beispiel-Projekt python3 ../cpm.py render --package package \ --mapping model-mapping.yaml \ --output package/.opencode/oh-my-opencode-slim.json ``` Erwartetes Ergebnis: Preset `acme-job-applications` mit fünf Agenten – `orchestrator`, `librarian` (Alias `researcher`), Custom Agent `writer`, `oracle` (Alias `checker`), Custom Agent `notifier`. Der Researcher erhält keinen LaTeX-Zugang, der Writer keine Job-Suchtools, der Notifier gar keine externen Zugriffe. Danach: ```bash cd package && opencode /preset acme-job-applications ``` ## Troubleshooting | Problem | Ursache/Lösung | |---|---| | `Modellklasse X ist nicht gemappt` | Mapping ergänzen, erneut rendern | | `Warnung: MCP ... nicht konfiguriert` | MCP in `opencode.jsonc` einrichten oder aus dem Profil entfernen | | `/preset` zeigt nichts Neues | OpenCode nach dem Render neu laden; Preset greift nicht mid-session | | Preset weg nach manuellem Editieren | Datei ist generiert – Änderungen gehören ins Mapping oder Team-Profil | | YAML-Fehler | Zeilenangabe aus der Fehlermeldung folgen | ## Grenzen (bewusst) - Der CPM startet keine Agenten und orchestriert nichts zur Laufzeit – das macht der Ziel-Harness. - MCP-/Skill-Allowlists sind Capability Scoping, keine Sandbox. Irreversible Aktionen brauchen serverseitige Autorisierung + Human Approval. - Die Modellverfügbarkeit wird gegen die opencode.jsonc-Namen geprüft, nicht per API-Healthcheck.