APM-Packages/corentic-package-manager/README.md
Tobias J. Endres 0df9cec833 docs(cpm): translate all CPM project files to English
CPM is an international project; only the blogpost stays German.
Translated: cpm.py docstring/messages/help texts, README.md,
cpm-setup skill, all team-profile.yaml files (incl. runtime_agent
comments), example apm.yml wrappers and the model-mapping template.
Also fixes DEFAULT_MAPPING_PATH pointing to ~/.config/apm-team
instead of ~/.config/cpm.
2026-08-23 17:56:09 +02:00

186 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Corentic Package Manager (CPM)
A **CPM package** is an agent package consisting of an [APM](https://microsoft.github.io/apm/) manifest plus a team configuration (`team-profile.yaml`). The Corentic Package Manager translates this package into the native configuration of a target harness.
Translation targets:
| Target harness | Status |
|---|---|
| [oh-my-opencode-slim](https://ohmyopencodeslim.com/) | ✅ implemented |
| oh-my-pi | planned |
| Codex / Claude / Copilot | vision |
Deterministic the CPM does not guess. It assumes no availability and never picks models automatically.
```
CPM package User Runtime
apm.yml + + model-mapping.yaml → cpm render → .opencode/
team-profile.yaml (model class → oh-my-opencode-slim.json
(roles, model concrete model ID) (or later: native config
classes, MCPs/skills) of another harness)
```
## Prerequisites
- Python 3.10+ with PyYAML (`pip install pyyaml`)
- OpenCode with the [oh-my-opencode-slim](https://github.com/alvinunreal/oh-my-opencode-slim) plugin installed
- A CPM package with a `team-profile.yaml`
## Quickstart
```bash
# 1. Create the model mapping interactively, choosing from your opencode models
python3 cpm.py init --fill
# 2. Guided: read team profile, check/fill mapping, render
cd <project>
python3 /path/to/cpm.py setup --package /path/to/package
# 3. Activate
opencode # project config gets loaded
/preset acme-job-applications
# Reload OpenCode -> team is active (by design: no hot-swap)
```
Alternatively manually:
```bash
# 1. Create the model mapping once
mkdir -p ~/.config/cpm
cp examples/model-mapping.yaml ~/.config/cpm/model-mapping.yaml
$EDITOR ~/.config/cpm/model-mapping.yaml # adapt to your own models
# 2. Validate (dry run)
python3 cpm.py check --package examples/package
# 3. Render
cd <project>
python3 /path/to/cpm.py render --package /path/to/package
```
## The three files
| File | Owned by | Purpose | Edit manually? |
|---|---|---|---|
| `team-profile.yaml` | Package author | Roles, model classes, MCP/skill allowlists per role | Yes (author) |
| `~/.config/cpm/model-mapping.yaml` | User | Model class → concrete model ID (+ optional variant/temperature) | Yes (user) |
| `.opencode/oh-my-opencode-slim.json` | generated | Preset with concrete model IDs | **No** always re-render |
Plus a provenance file `.opencode/oh-my-opencode-slim.cpm-provenance.json` documenting which role received which model.
## Command reference
```bash
python3 cpm.py init [--mapping FILE] [--fill] # create/fill mapping
python3 cpm.py setup --package DIR [--mapping F] ... # guided flow
python3 cpm.py render --package DIR [--mapping F] [--output F] [--dry-run]
python3 cpm.py check --package DIR [--mapping F] # dry-run validation
```
### `init` create the mapping
Creates `~/.config/cpm/model-mapping.yaml` (if not present). With `--fill`, all `PLACEHOLDER` classes are asked interactively: the CPM lists every model from your `opencode.json(c)`, you pick by number or enter a model ID manually.
### `setup` guided flow
The one-command path: shows the team profile in plain language, creates a missing mapping, interactively asks for missing model classes (same selection as `init --fill`), renders and prints the activation steps.
### `render` / `check`
| Option | Default | Meaning |
|---|---|---|
| `--package` | `.` | CPM package directory containing `team-profile.yaml` |
| `--mapping` | `~/.config/cpm/model-mapping.yaml` | Local mapping table |
| `--output` | `<package>/.opencode/oh-my-opencode-slim.json` | Target file |
| `--team-file` | `team-profile.yaml` (alternatively `team.yaml`) | Alternative profile filename |
**Merge behavior:** Existing presets in the target file remain untouched; only the preset for this team ID is replaced. Multiple packages coexist in the same project. Activation is explicit via `/preset <name>`.
## Team profile schema (`corentic.team-profile/v1`)
```yaml
schema: corentic.team-profile/v1
id: acme.job-applications # becomes the preset name (namespaced)
description: ...
roles:
- id: researcher # domain role
purpose: ... # becomes prompt/description for custom agents
runtime_agent: librarian # optional: harness builtin or 'custom'
# (default: role id as custom agent)
model_class: fast-research # required, must exist in the mapping
capabilities:
mcps: [websearch, openviking] # MCP allowlist ([] = none)
skills: [job-application] # skill allowlist ([] = none)
```
The `runtime_agent` field is deliberately harness-neutral: the adapter decides how the role is represented in the target harness. Builtins recognized by the oh-my-opencode-slim adapter: `orchestrator`, `oracle`, `librarian`, `explorer`, `fixer`, `designer`, `council`, `observer`. Everything else (or `runtime_agent: custom`) creates a custom agent including `prompt` and `orchestratorPrompt` derived from the `purpose` field.
### Mapping formats
```yaml
model_classes:
fast-research: ollama/qwen3.5:9b # simple
high-reasoning: # extended
model: ollama/qwen3.6:35b-a3b-q4_K_M
variant: thinking
temperature: 0.3
```
All extra fields are passed through 1:1 into the agent entry of the preset.
## What the CPM checks
1. Team profile present, schema known, `id` and `roles` present
2. Every `model_class` has a mapping entry (otherwise error with fix hint)
3. MCPs matched against `~/.config/opencode/opencode.json(c)` (**warning**, not fatal)
4. Roles without MCPs/skills -> note
## Examples
| Example | Based on | Team |
|---|---|---|
| `examples/package/` | Own `job-application` package (OpenViking + ShareLaTeX) | `acme.job-applications` Researcher, Writer, Checker, Notifier |
| `examples/microsoft-design-review/` | Official [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/` | Official [`apm-issue-autopilot`](https://github.com/microsoft/apm/tree/main/packages/apm-issue-autopilot) from the microsoft/apm repo | `acme.issue-autopilot` Triager, Shepherd, PR-Writer, Reviewer (+ GitHub MCP) |
The two Microsoft examples are thin CPM wrappers: their own `apm.yml` pulls the official package as a versioned APM dependency (`microsoft/apm-sample-package#v1.0.0` or monorepo subpath `microsoft/apm/packages/apm-issue-autopilot`) and only adds the team recommendation.
```bash
cd corentic-package-manager/examples
# Dry run: what would be generated?
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
# Render into the example project
python3 ../cpm.py render --package package \
--mapping model-mapping.yaml \
--output package/.opencode/oh-my-opencode-slim.json
```
Expected result: preset `acme-job-applications` with five agents `orchestrator`, `librarian` (alias `researcher`), custom agent `writer`, `oracle` (alias `checker`), custom agent `notifier`. The researcher gets no LaTeX access, the writer sees no job-search tools, the notifier gets no external access at all.
Then:
```bash
cd package && opencode
/preset acme-job-applications
```
## Troubleshooting
| Problem | Cause/Fix |
|---|---|
| `Model class X is not mapped` | Add to the mapping, re-render |
| `Warning: MCP ... not configured` | Set up the MCP in `opencode.jsonc` or remove it from the profile |
| `/preset` does not show anything new | Reload OpenCode after rendering; presets do not apply mid-session |
| Preset lost after manual editing | The file is generated changes belong in the mapping or team profile |
| YAML errors | Follow the line number in the error message |
## Deliberate limits
- The CPM does not start agents and orchestrates nothing at runtime that is the job of the target harness.
- MCP/skill allowlists are capability scoping, not a sandbox. Irreversible actions need server-side authorization + human approval.
- Model availability is checked against opencode.json(c) names, not via API health checks.