diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json new file mode 100644 index 0000000..019d3d5 --- /dev/null +++ b/.agents/plugins/marketplace.json @@ -0,0 +1,20 @@ +{ + "name": "fusion-marketplace", + "interface": { + "displayName": "Fusion" + }, + "plugins": [ + { + "name": "fusion", + "source": { + "source": "local", + "path": "./" + }, + "policy": { + "installation": "AVAILABLE", + "authentication": "ON_INSTALL" + }, + "category": "Developer Tools" + } + ] +} diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index acd560a..d459803 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "fusion", - "version": "0.1.0+codex.20260913052559", + "version": "0.1.0+codex.20260913053047", "description": "Independent Fusion-style orchestration for Codex: one persistent sidekick, precise briefs, and main-agent review.", "author": { "name": "Fusion contributors" @@ -18,6 +18,7 @@ "Local token accounting" ], "defaultPrompt": [ + "Use $setup-fusion to set up Fusion.", "Use $fusion to implement this task." ] }, diff --git a/README.md b/README.md index 22d364d..15d29ce 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,24 @@ An independent implementation of Cognition's Fusion orchestration pattern as a C A capable main agent plans and reviews. One persistent sidekick implements bounded briefs and verifies the results. This project is not affiliated with Cognition. It does not include the Devin binary or proprietary prompts. -## Use - -Install the plugin from its personal marketplace entry. Initialize the live model file once: +## Install and set up ```sh -python3 scripts/model_config.py init +codex plugin marketplace add nahuelb/codex-fusion-plugin +codex plugin add fusion@fusion-marketplace ``` -Start a fresh Codex task and invoke `Use $fusion to implement `. -Use `fusion:fusion` when the short name is ambiguous. +Git must have access to the repository. Start a fresh Codex task, then send: + +```text +Use $setup-fusion to set up Fusion. +``` + +Setup creates your live model file if missing and preserves existing choices. +Then use `Use $fusion to implement `. The namespaced skills are `fusion:setup-fusion` and `fusion:fusion`. +See [installation](docs/installation.md) for prerequisites, updates, local checkouts, and optional hooks. + +## Model settings Edit `~/.config/codex-fusion/models.json` at any time: @@ -53,7 +61,7 @@ Ask to stop Fusion to close and release the sidekick and deactivate the current ## Included -- Explicit Fusion skill, runtime adapter, brief format, and sidekick contract. +- Fusion workflow and setup skills, runtime adapter, brief format, and sidekick contract. - Opt-in session state and a single-sidekick registration constraint. - Advisory reminders after edits, on follow-up input, and on resume/compaction. - Live lead/sidekick JSON registry and explicit spawn arguments, without model-pinned custom agents. diff --git a/docs/installation.md b/docs/installation.md index 66e58b2..cadd292 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -1,46 +1,84 @@ -# Installation and local reload +# Install Fusion -The personal marketplace entry uses `~/plugins/fusion`. -On the development machine, that directory is a tracked-file export of reviewed `main` from `~/Projects/codex-fusion-plugin`. -The default personal marketplace file is `~/.agents/plugins/marketplace.json`. -Do not add the default personal marketplace explicitly with a marketplace-add command. +Use a Codex version with plugin and subagent support. Python 3.10 or newer must be available as `python3`. +Git must be able to read the repository. Private repositories require Git authentication and repository access. -## Initial setup +## Install from GitHub -Use the plugin-creator scaffold workflow to add the personal entry when installing on another machine. -Populate its local source from a clean tracked-file export of this checkout. Preserve existing marketplace entries. -Run `python3 scripts/model_config.py init` once. This preserves an existing valid live registry. +```sh +codex plugin marketplace add nahuelb/codex-fusion-plugin +codex plugin add fusion@fusion-marketplace +``` + +The first command registers the repository's marketplace. The second installs Fusion from that marketplace. +Start a fresh Codex task after installation. Then send: + +```text +Use $setup-fusion to set up Fusion. +``` + +You can also ask Codex to “set up Fusion.” The `fusion:setup-fusion` skill initializes the external model registry. +It preserves an existing valid configuration. Setup does not activate the coding workflow or start agents. +After setup, send `Use $fusion to implement `. -## Reload plugin code +The default sidekick is Luna at xhigh. Direct invocation keeps the current main model. +The configured Astra lead is used when another agent delegates a Fusion run. +Configured models must be available in your Codex runtime. Setup validates configuration, not model access. -1. Complete the required review and validation before pushing. -2. Confirm `main` and the marketplace source contain the intended reviewed commit with no uncommitted source changes. -3. Resolve the marketplace name with the plugin-creator helper: +## Update ```sh -python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/plugin-creator/scripts/read_marketplace_name.py" -codex plugin list --marketplace personal --available --json +codex plugin marketplace upgrade fusion-marketplace +codex plugin add fusion@fusion-marketplace ``` -Use the returned marketplace name if it differs from `personal`. -Update the cachebuster before the reviewed commit as described in `AGENTS.md`. -Export the reviewed commit into a fresh directory, then replace the old plugin source only after checking its ownership. -Use `git archive HEAD` to include tracked files only. Preserve the external live model registry. -Reinstall only when the source is correct: +Start a fresh task to load updated plugin code. Model settings remain in the external registry. +Do not run setup again unless you want to inspect or change those settings. + +## Install a local checkout ```sh -codex plugin add fusion@personal +git clone https://github.com/nahuelb/codex-fusion-plugin.git +cd codex-fusion-plugin +codex plugin marketplace add . +codex plugin add fusion@fusion-marketplace +``` + +Choose either the GitHub source or the local source for `fusion-marketplace`. +If that marketplace name is already registered, inspect `codex plugin marketplace list` before switching its source. +A local source reads the checkout. Reinstall after pulling reviewed changes; marketplace upgrade is for Git sources. + +## Models and hooks + +`$setup-fusion` uses `~/.config/codex-fusion/models.json`, or `FUSION_MODELS_FILE` when set on the Codex host. +Edit that file or ask setup to change specific model fields. Existing unrelated settings are preserved. +No cachebuster, reinstall, or new task is needed for model edits. +The lead reads the file before each handoff. Model or effort changes replace the sidekick after its current handoff finishes. +Lead changes apply to the next delegated run. + +Hooks require Codex hook trust. Review the plugin hooks through `/hooks` if you want the advisory reminders. +The core skill works without hooks. Setup does not enable hook trust automatically. + +## Maintainer reloads + +Complete review and checks before publishing. Update the plugin cachebuster before the final reviewed commit, as described in `AGENTS.md`. +Use the installation's existing marketplace instead of changing its source to conceal unmerged changes. + +For a personal development installation, resolve the actual marketplace name and source: + +```sh +python3 "${CODEX_HOME:-$HOME/.codex}/skills/.system/plugin-creator/scripts/read_marketplace_name.py" +codex plugin list --marketplace personal --available --json ``` -Compare the installed files and manifest version with the reviewed source. -Start a fresh task and invoke `fusion:fusion` to verify discovery after runtime changes. -Hook execution also requires Codex hook trust; review the hooks through `/hooks` as needed. -Do not claim live hook delivery from unit tests alone. +The default personal marketplace is discovered implicitly. Do not register it through marketplace-add. +Refresh its plugin source from a clean tracked-file export of reviewed `main`, using `git archive HEAD`. +Preserve the external registry. Then run `codex plugin add fusion@personal`, substituting the resolved marketplace name when needed. +Compare installed files and the manifest version with that reviewed source. +Verify the skill in a fresh task. An existing task or a registry listing does not prove the update loaded. -## Change models without reloading +The underlying initialization command remains available for automation: +`python3 /scripts/model_config.py init`. +Normal interactive setup uses `$setup-fusion`. -Edit `~/.config/codex-fusion/models.json`. No cachebuster, commit, reinstall, or new task is needed for these edits. -Run `python3 scripts/model_config.py show` to validate the file and see its revision. -The lead reads it before each handoff through `fusion.py dispatch`. -Model or effort changes replace the sidekick after the current handoff finishes. -Lead settings apply to the next delegated run; the current main model remains selected by default. +See [official Codex plugin guidance](https://learn.chatgpt.com/docs/plugins) for the plugin lifecycle. diff --git a/scripts/check.py b/scripts/check.py index bcb0ee8..cb44c47 100644 --- a/scripts/check.py +++ b/scripts/check.py @@ -10,7 +10,7 @@ def main(): root = Path(__file__).resolve().parents[1] for path in [*root.glob('scripts/*.py'), *root.glob('tests/*.py')]: compile(path.read_text(), str(path), 'exec') - for path in (root / '.codex-plugin/plugin.json', root / 'hooks/hooks.json', root / 'config/models.default.json'): + for path in (root / '.codex-plugin/plugin.json', root / 'hooks/hooks.json', root / 'config/models.default.json', root / '.agents/plugins/marketplace.json'): json.loads(path.read_text()) import model_config model_config.validate(json.loads((root / 'config/models.default.json').read_text())) diff --git a/scripts/model_config.py b/scripts/model_config.py index 0ba2375..b6e33e4 100644 --- a/scripts/model_config.py +++ b/scripts/model_config.py @@ -37,7 +37,7 @@ def read(): try: data = validate(json.loads(path.read_text())) except FileNotFoundError as exc: - raise ValueError(f'No live model file at {path}. Run model_config.py init once.') from exc + raise ValueError(f'No live model file at {path}. Run $setup-fusion in Codex (or model_config.py init).') from exc revision = hashlib.sha256(json.dumps(data, sort_keys=True).encode()).hexdigest()[:16] return {'path': str(path.resolve()), 'revision': revision, 'models': data} diff --git a/skills/fusion/references/runtime.md b/skills/fusion/references/runtime.md index ba25895..d442939 100644 --- a/skills/fusion/references/runtime.md +++ b/skills/fusion/references/runtime.md @@ -14,7 +14,8 @@ Before EVERY sidekick spawn or follow-up brief, run `python3 /scrip This reads `~/.config/codex-fusion/models.json` afresh. It returns an action and exact `spawn_args`. Never use a model-pinned custom agent; use `agent_type: "default"` with the returned model and reasoning effort. The live user registry selects the model. Do not substitute a model from another workflow or copy a remembered default. -If the file is missing or invalid, stop new dispatches and report the error. Already running work can finish safely. +If the file is missing, direct the user to `$setup-fusion` before dispatching. +If the file is invalid, stop new dispatches and report the error. Already running work can finish safely. If the runtime rejects the selected model or effort, report that mismatch without silently falling back. A newer explicit user instruction takes precedence; update the live registry when asked, then resolve it again. diff --git a/skills/setup-fusion/SKILL.md b/skills/setup-fusion/SKILL.md new file mode 100644 index 0000000..f37c2aa --- /dev/null +++ b/skills/setup-fusion/SKILL.md @@ -0,0 +1,31 @@ +--- +name: setup-fusion +description: Initialize or inspect Fusion's live model settings when the user asks to set up Fusion, configure Fusion, or invokes $setup-fusion. Preserve existing settings unless the user requests changes. +--- + +# Set up Fusion + +Resolve the installed plugin root as two directories above this skill directory. +Use that absolute root for helper commands; do not assume the user's working directory contains the plugin source. + +Run `python3 /scripts/model_config.py init`. +This initializes a missing registry from shipped defaults and validates an existing registry without overwriting it. +Honor `FUSION_MODELS_FILE` when set. Otherwise the registry is `~/.config/codex-fusion/models.json`. +If the registry is invalid, report the specific error. Preserve the file until the user authorizes a repair. +If the sandbox blocks the selected directory, use the normal approval path. Do not relocate settings or change permissions to bypass it. +If access remains blocked, provide the exact initialization command with the installed absolute helper path. + +If the user supplied model choices, apply only those requested fields to the live registry. +Validate the candidate with the helper's `validate` function before replacing the file atomically. +Preserve other fields and do not write local choices into the plugin, its cache, or shipped defaults. +Do not substitute another model identifier or claim runtime support from schema validation alone. + +Run `python3 /scripts/model_config.py show` to confirm the resulting file and settings. +Explain that the current conversation keeps its model by default; the configured lead applies to delegated Fusion runs. +Sidekick changes take effect at the next handoff without reinstalling the plugin. +Report the registry path, effective configured roles, and whether setup created or preserved the file. +Only claim a file was newly created if its absence was observed before initialization; otherwise report that it is ready. + +Tell the user to invoke `$fusion` for a coding task. Setup itself does not activate Fusion or start agents. +Hooks are optional advisory reminders. If the user wants them, direct them to review the plugin hooks through `/hooks`. +Do not enable or bypass hook trust, reinstall plugins, change global model defaults, or launch model probes as part of setup. diff --git a/skills/setup-fusion/agents/openai.yaml b/skills/setup-fusion/agents/openai.yaml new file mode 100644 index 0000000..7363e45 --- /dev/null +++ b/skills/setup-fusion/agents/openai.yaml @@ -0,0 +1,6 @@ +interface: + display_name: "Set up Fusion" + short_description: "Initialize or inspect live Fusion model settings" + default_prompt: "Use $setup-fusion to set up Fusion." +policy: + allow_implicit_invocation: true