Skip to content

Commit dd9006e

Browse files
authored
Merge pull request #365 from SlanchaAI/agent/codex-wire-plugin
Add Codex plugin ergonomics for Wire
2 parents 0e3187b + 46ae0c5 commit dd9006e

16 files changed

Lines changed: 1141 additions & 130 deletions

File tree

.agents/plugins/marketplace.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "wire",
3+
"interface": {
4+
"displayName": "Wire"
5+
},
6+
"plugins": [
7+
{
8+
"name": "wire",
9+
"source": {
10+
"source": "local",
11+
"path": "./"
12+
},
13+
"policy": {
14+
"installation": "AVAILABLE",
15+
"authentication": "ON_INSTALL"
16+
},
17+
"category": "Developer Tools"
18+
}
19+
]
20+
}

.claude-plugin/plugin.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "wire",
33
"displayName": "Wire",
4-
"version": "0.15.0",
5-
"description": "Magic-wormhole for AI agents — bilateral signed-message bus over a mailbox relay. Rust-native MCP server with Ed25519-rooted operator + organization identity (RFC-001), bilateral SAS pairing, multi-relay federation. Discover, pair, and message other Claude / Codex / Copilot agents from this session.",
4+
"version": "0.17.0",
5+
"description": "Magic-wormhole for AI agents — bilateral signed-message bus over local and federated mailbox relays. Rust-native MCP server with Ed25519-rooted identity. Discover, pair, and message Claude, Codex, and Copilot agents from this session.",
66
"author": {
77
"name": "Paul Logan",
88
"email": "paul@slancha.ai"

.codex-plugin/plugin.json

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"name": "wire",
3+
"version": "0.17.0",
4+
"description": "Bilateral signed-message bus for local and federated AI-agent sessions.",
5+
"author": {
6+
"name": "Slancha AI",
7+
"email": "paul@slancha.ai",
8+
"url": "https://slancha.ai"
9+
},
10+
"homepage": "https://wireup.net",
11+
"repository": "https://github.com/SlanchaAi/wire",
12+
"license": "AGPL-3.0-or-later AND Apache-2.0 AND MIT",
13+
"keywords": [
14+
"agent",
15+
"p2p",
16+
"ed25519",
17+
"mailbox",
18+
"mcp",
19+
"identity"
20+
],
21+
"skills": "./skills/",
22+
"mcpServers": "./.mcp.json",
23+
"interface": {
24+
"displayName": "Wire",
25+
"shortDescription": "Secure agent-to-agent messaging",
26+
"longDescription": "Discover, pair, and exchange signed messages with local or federated AI-agent sessions through Wire.",
27+
"developerName": "Slancha AI",
28+
"category": "Developer Tools",
29+
"capabilities": [
30+
"Read",
31+
"Write"
32+
],
33+
"websiteURL": "https://wireup.net",
34+
"defaultPrompt": [
35+
"Show my Wire identity and nearby agents.",
36+
"Dial another agent over Wire.",
37+
"Send a message to a paired Wire peer."
38+
]
39+
}
40+
}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# Local state
1515
*.local.md
1616
.claude/
17+
.worktrees/
1718

1819
# Secrets / keys (defensive — operator keys live in $HOME/.config/wire/, never the repo)
1920
*.key

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Wire integrates at the harness layer — your agent's tool-calling loop, not you
5858
| If you use… | Install path | First-run smoke |
5959
|---|---|---|
6060
| **Claude Code** | `cargo install slancha-wire`, then `/plugin install @SlanchaAi/wire` (also accepts the install.sh path) | SessionStart hook prints `wire <version>`|
61+
| **Codex App / CLI / IDE** | `cargo install slancha-wire`, `codex plugin marketplace add SlanchaAi/wire`, then `codex plugin add wire@wire` | Start a new task; ask “Show my Wire identity” |
6162
| **Cursor / Aider / generic MCP host** | `wire setup --apply` | Restart client; `wire_*` tools appear in MCP list |
6263
| **GitHub Copilot CLI** | [docs/integrations/COPILOT_CLI.md](docs/integrations/COPILOT_CLI.md) | `gh copilot` → "Call wire_whoami" |
6364
| **GitHub Copilot (VS Code)** | [docs/integrations/GITHUB_COPILOT.md](docs/integrations/GITHUB_COPILOT.md) | Restart VS Code; toolbar shows wire MCP |
@@ -67,6 +68,14 @@ Wire integrates at the harness layer — your agent's tool-calling loop, not you
6768
| **Pure terminal** | `wire up`, `wire dial`, `wire monitor` | local message appears |
6869
| **Custom harness / non-Node** | CLI `--json` mode + filesystem contract — see [docs/AGENT_INTEGRATION.md](docs/AGENT_INTEGRATION.md) | `wire whoami --json` + `wire tail --json` |
6970

71+
Codex users who want only the tool surface can skip plugin packaging:
72+
73+
```bash
74+
codex mcp add wire -- wire mcp
75+
```
76+
77+
The plugin adds shared Wire skills and marketplace discovery; both routes run the same local `wire mcp`. Keep one Wire MCP registration enabled to avoid duplicate tool catalogs.
78+
7079
## Trust model (one paragraph)
7180

7281
Knowing a handle (`alice@wireup.net`) and being able to resolve it to a signed agent-card is the authentication ceremony — same shape as discovering someone's Mastodon account via WebFinger or their PGP key via WKD. The card carries an Ed25519 verify-key, signed by that key, so the resolver knows the relay isn't lying about who claims the nick. FCFS on nicks; same-DID re-claims allowed. **Bilateral consent:** a stranger can leave one pair request in your `wire pending` list but can NEVER auto-pin themselves into your trust ring or get write access to your inbox until you `wire accept`. For threat models where the discovery channel itself can't be trusted (suspect DNS, distrustful operator), verify the resolved card fingerprint out-of-band (or pair via a one-time invite URL — see [Alternative flows](#alternative-flows)). Full threat model: [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md).

SESSION_LOG_2026_07_14.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Session Log — 2026-07-14
2+
3+
## Codex Wire ergonomics
4+
5+
### What
6+
7+
Investigated whether Wire already ships a Codex plugin. Repository had a Claude Code plugin (`.claude-plugin/plugin.json`) and shared MCP config (`.mcp.json`), but no `.codex-plugin/plugin.json` or Codex marketplace entry. Local Codex already had `wire -> wire mcp` enabled, confirming protocol/runtime capability existed without plugin packaging.
8+
9+
### Why add a plugin
10+
11+
MCP supplies tools. Plugin packaging supplies discovery, installation, shared workflow skills, and safety guidance. Product target is repository-distributed Codex support for other Wire users, not a personal-only setup.
12+
13+
### Decision
14+
15+
Use a root-level Codex manifest alongside the Claude manifest. Reuse `.mcp.json` and `skills/`; do not create a nested copied plugin tree. Keep Claude’s `SessionStart` hook out of the Codex manifest because current Codex validation rejects `hooks`. Make shared skill prose harness-neutral where necessary and preserve bilateral consent.
16+
17+
Rejected:
18+
19+
- nested `plugins/wire`: duplicates or fragile-links package assets;
20+
- MCP-only docs: capability works, but distribution and behavioral ergonomics remain weak.
21+
22+
Design: `docs/superpowers/specs/2026-07-14-codex-plugin-design.md`.
23+
24+
### Current phase
25+
26+
Implementation and verification complete: packaging, shared-skill modernization, install documentation, isolated Codex install smoke, plugin/skill validation, and full Rust regression suite.
27+
28+
### Implementation findings
29+
30+
- Codex packaging reuses the repository root through marketplace source `./`.
31+
- Codex skill validation requires explicit `name` frontmatter.
32+
- Shared skills advertised removed SAS/init commands; corrected before Codex distribution.
33+
- `wire mcp` keeps data synchronized, while Codex ingests messages through `wire_pull` and `wire_tail` at task checkpoints.
34+
- The local plugin validator requires PyYAML; `uv run --with pyyaml` provides it without changing project dependencies.
35+
- Isolated `CODEX_HOME` smoke discovered `wire@wire` v0.17.0, installed it into plugin cache, and reported it enabled without touching normal Codex configuration.
36+
- Final `cargo test -q` exited 0 across unit, integration, stress, and doctest batches; only pre-existing ignored tests remained ignored.
37+
38+
### Implementation artifacts
39+
40+
- `.codex-plugin/plugin.json` — Codex plugin manifest.
41+
- `.agents/plugins/marketplace.json` — repository marketplace entry.
42+
- `tests/plugin_contract.rs` — packaging and documentation contract tests.
43+
- `skills/*/SKILL.md` — shared Claude/Codex workflows.
44+
- `README.md` and `docs/PLUGIN.md` — install and operation guidance.
45+
46+
## Artifacts
47+
48+
- `docs/superpowers/specs/2026-07-14-codex-plugin-design.md` — product design, invariants, packaging, and verification criteria.
49+
- `docs/superpowers/plans/2026-07-14-codex-plugin.md` — test-first implementation and verification plan.
50+
- `SESSION_LOG_2026_07_14.md` — session decisions and artifact catalog.

docs/PLUGIN.md

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
# Wire as a Claude plugin
1+
# Wire agent plugins
22

3-
Wire is publishable as a [Claude Code plugin](https://code.claude.com/docs/en/plugins.md). The plugin manifest + skills + MCP server declaration live at the root of this repo; the actual wire binary is installed separately via Cargo.
3+
Wire packages its shared skills and MCP server for Claude Code and Codex. Harness-specific manifests live at the repository root; the actual `wire` binary is installed separately via Cargo.
44

5-
## Install (end-user UX)
5+
## Claude Code plugin
66

77
Two steps:
88

@@ -23,15 +23,44 @@ The plugin ships six skills, all namespaced under `/wire:`:
2323
| Command | Purpose |
2424
|---|---|
2525
| `/wire:wire-init` | Initialize wire — mint session DID + Ed25519 keypair, optionally bind a public relay |
26-
| `/wire:wire-pair` | Pair this session with another wire agent (bilateral, signed, with optional SAS) |
26+
| `/wire:wire-pair` | Dial another Wire agent or handle an inbound consent decision |
2727
| `/wire:wire-monitor` | Arm the persistent inbox watcher per wire MCP session-start directive |
2828
| `/wire:wire-send` | Send a signed message to a paired peer (auto-pair on miss) |
2929
| `/wire:wire-enroll` | Enroll operator + organization identity (RFC-001 v0.14 identity layer) |
3030
| `/wire:wire-quiet` | Silence wire desktop toasts (file + env-based kill switches) |
3131

32+
## Codex plugin
33+
34+
The Codex manifest lives at `.codex-plugin/plugin.json` and reuses `.mcp.json` plus `skills/`. The binary remains a separate install:
35+
36+
```bash
37+
cargo install slancha-wire
38+
codex plugin marketplace add SlanchaAi/wire
39+
codex plugin add wire@wire
40+
```
41+
42+
Start a new task. Ask “Show my Wire identity,” then dial only a real operator-supplied persona. Inbound requests remain pending until explicit accept or reject.
43+
44+
### MCP-only Codex setup
45+
46+
```bash
47+
codex mcp add wire -- wire mcp
48+
```
49+
50+
MCP-only gives the same tools without bundled skills or marketplace UX. Do not enable direct `mcp_servers.wire` and plugin-provided Wire MCP together unless testing duplicate registrations.
51+
52+
### Local Codex development
53+
54+
```bash
55+
codex plugin marketplace add /absolute/path/to/wire
56+
codex plugin add wire@wire
57+
```
58+
59+
Reinstall after manifest or skill changes, then start a new task.
60+
3261
### MCP server tools
3362

34-
Claude Code auto-starts `wire mcp` on session start (declared in `.mcp.json`). Identity auto-provisions and the sync daemon arms on first start — no manual init needed. Tools (all prefixed `mcp__wire__` over MCP):
63+
Claude Code and Codex auto-start `wire mcp` from `.mcp.json`. Identity auto-provisions and the sync daemon arms on first start — no manual init needed. Tool names:
3564

3665
- **Orient / read**`wire_whoami`, `wire_here` (who am I, who's around?), `wire_peers`, `wire_status`, `wire_tail`, `wire_pull`, `wire_verify`
3766
- **Connect**`wire_dial` (the one to reach for: pairs a local sister or a `nick@domain` peer), `wire_pending`, `wire_accept`, `wire_reject`. `wire_add` is `wire_dial`'s federation backend; `wire_invite_mint` / `wire_invite_accept` cover the invite-URL path.
@@ -43,7 +72,7 @@ This list is verified against the live catalog by a test (`agent_docs_match_adve
4372

4473
Resource: `wire://inbox/<peer>` exposes each pinned peer's verified inbox as JSONL.
4574

46-
## Publishing channels
75+
## Claude publishing channels
4776

4877
The plugin is publishable via three paths (all working from the same `.claude-plugin/plugin.json` manifest):
4978

@@ -71,7 +100,7 @@ The three channels coexist. Community submission is recommended as the first pub
71100

72101
Omitting the `version` field would make Claude Code use the git commit SHA — every commit is a new version. Slancha pins explicit semver for predictable rollouts.
73102

74-
## Plugin install vs `wire setup` — pick one
103+
## Claude plugin install vs `wire setup` — pick one
75104

76105
The plugin's `.mcp.json` declares the wire MCP server entry. If you previously ran `wire setup --apply` (which writes the same entry into `~/.claude.json`), you'll end up with two `mcpServers.wire` entries — global + plugin-scoped. Claude Code resolves them deterministically (plugin-scoped wins for the current session), but the duplicate is confusing and the global entry stops being maintained.
77106

@@ -94,7 +123,7 @@ EOF
94123

95124
A future `wire setup --apply` will detect a plugin install and skip writing the global entry; pre-v0.14.2 `wire setup` doesn't yet know about the plugin path. Tracking in v0.14.2 backlog.
96125

97-
## Plugin development
126+
## Claude plugin development
98127

99128
To work on the plugin scaffold without affecting end-user sessions:
100129

0 commit comments

Comments
 (0)