Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .agents/plugins/marketplace.json
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
3 changes: 2 additions & 1 deletion .codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -18,6 +18,7 @@
"Local token accounting"
],
"defaultPrompt": [
"Use $setup-fusion to set up Fusion.",
"Use $fusion to implement this task."
]
},
Expand Down
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <task>`.
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 <task>`. 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:

Expand Down Expand Up @@ -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.
Expand Down
100 changes: 69 additions & 31 deletions docs/installation.md
Original file line number Diff line number Diff line change
@@ -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 <task>`.

## 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 <installed-plugin-root>/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.
2 changes: 1 addition & 1 deletion scripts/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
Expand Down
2 changes: 1 addition & 1 deletion scripts/model_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}

Expand Down
3 changes: 2 additions & 1 deletion skills/fusion/references/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ Before EVERY sidekick spawn or follow-up brief, run `python3 <plugin-root>/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.

Expand Down
31 changes: 31 additions & 0 deletions skills/setup-fusion/SKILL.md
Original file line number Diff line number Diff line change
@@ -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 <plugin-root>/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 <plugin-root>/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.
6 changes: 6 additions & 0 deletions skills/setup-fusion/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -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
Loading