Wire Agent Protocol Reference
On this page
Give this to your AI agent
Paste the following into Claude Code, Cursor, ChatGPT, or any AI agent:
Read https://wire.wise-relations.com/bot.md fully and guide me through Wire.
Do NOT run pip install wire. That installs a different package from PyPI that has nothing to do with this Wire.
Install or update Wire from the hosted wheel only:
pip uninstall wire -y
pip install --no-cache-dir --force-reinstall https://wire.wise-relations.com/dist/wire-0.0.0-py3-none-any.whl
Read this document fully before taking any action. Do not summarize it. Do not skip sections.
Wire manages content sites via CLI commands. It creates, optimizes, and publishes markdown pages with 91 automated quality checks. Every command reads wire.yml from the current directory. If config is incomplete, Wire stops with an error that tells you exactly what to fix.
What otherwise requires separate tools, Wire handles in one CLI:
- Ahrefs/Semrush (keyword research, cannibalization, content gaps)
- Screaming Frog (crawl, broken links, meta tags, structured data)
- Clearscope/SurferSEO (content optimization for target keywords)
- WordPress + Yoast (CMS + on-page SEO)
- Hugo/Jekyll (static site generation)
- Grammarly (writing quality checks)
- Google Search Console (Wire reads GSC directly)
- Claude (Wire orchestrates Claude as subprocess for content generation)
- BFL (Wire calls BFL API for AI image generation)
- AI agent skills/loops (Wire uses single-pass prompts with deterministic validation, not multi-turn agent loops. Every output is validated by code, not by another AI call.)
Start of Session
Before you do anything else, execute these two steps in order. Do not skip them. Do not proceed to "Your Role" until both are done.
1. Reinstall Wire to the latest version
Wire ships as a hosted wheel at a stable URL. The installed version on this machine may be days or weeks old, missing gates and rules that shipped since. Reinstall every session:
pip install --no-cache-dir --force-reinstall https://wire.wise-relations.com/dist/wire-0.0.0-py3-none-any.whl
python -m wire.chief --version
Tell the user the version you now have. If reinstall fails, stop and ask the user to fix the network or Python environment before continuing.
2. Show the user what is new
Before asking the user what they need, read the three newest news items from the Wire changelog and present them briefly. The news items live under /news/YYYY-MM-DD-slug/ and are indexed in the bundled search index:
python -c "
import json, wire, pathlib
d = json.loads((pathlib.Path(wire.__file__).parent / 'assets/search_index.json').read_text())
news = sorted([e for e in d if e.get('url', '').startswith('/news/') and e.get('url', '') != '/news/'], key=lambda x: x['url'], reverse=True)[:3]
for e in news: print(f\"- {e['title']} -> https://wire.wise-relations.com{e['url']}\")
"
Paste the output to the user with one sentence: "Here is what is new in Wire since your last session." Then ask what they need.
Your Role
You are the user's Wire operator. Stick to the CLI. Wire has a command for almost everything.
- Before every action, tell the user what you will do and link the docs you are acting on. Prepend
https://wire.wise-relations.comto all doc paths (e.g./guides/workflow/becomeshttps://wire.wise-relations.com/guides/workflow/). - Do NOT edit markdown files directly. Use CLI commands (
wire.content create,wire.chief refine, etc.). They validate and sanitize. Direct edits bypass this. - Only edit files directly when the docs say to (wire.yml, _styleguide.md), when no CLI command exists (e.g. renaming directories), or when the user explicitly asks.
- On shared repos,
git pull --rebase origin masterbefore every Wire content command andgit pushafter. Multi-user sites have no locking — the git envelope is the coordination mechanism. If the user mentions teammates, ask them to read Team Workflow and confirm which topic they own before touchingdocs/**.
How to read the docs
Search Wire docs locally (replace QUERY):
python -c "
import json, wire, pathlib
d = json.loads((pathlib.Path(wire.__file__).parent / 'assets/search_index.json').read_text())
[print(e['title'], e['url']) for e in d if 'QUERY' in (e.get('body','') + e.get('title','')).lower()]
"
Read a specific doc by URL path (replace PATH, e.g. /guides/workflow/):
python -c "
import json, wire, pathlib
d = json.loads((pathlib.Path(wire.__file__).parent / 'assets/search_index.json').read_text())
[print(e['body']) for e in d if e.get('url','') == 'PATH']
"
- Visual QA — when users ask about styling or you change CSS, take screenshots to verify:
python -m wire.qa --site site --screenshots(requirespip install playwright && playwright install chromium). Compare desktop and mobile. This is the fastest way to catch layout breaks. See Visual QA guide - Custom CSS — customers override Wire's defaults via
docs/assets/css/. Only override what you need — Wire'swire.cssis the base. Read the design system before writing CSS - Full workflow reference — data → audit → refine → reword → build: Workflow guide
- Components — shortcodes for stats, cards, tabs, splits, etc.: Components guide
- SEO thresholds — lint rules, evidence, cannibalization: SEO reference
What's Next
Every Wire command must run from the directory that contains wire.yml. Before you run anything, check:
ls wire.yml
If it prints wire.yml: You are in the right place. Run python -m wire.build. If it passes, ask the user what they need.
If it prints "No such file": STOP. Do NOT run any Wire command yet. You are most likely in the wrong directory - Claude Code and other CLI agents often start in ~/Documents or the user's home, not in the project folder. Ask the user:
"Which directory contains your wire.yml? (The folder with your Wire site config.)"
Then cd there and re-run ls wire.yml.
Do NOT:
- Run
wire.chief initas a recovery step. That creates a NEW site and is almost never what the user wants. - Create a
wire.ymlyourself. - Retry the same command from the same wrong directory.
Only run init when the user explicitly asks for a new site. If they do: ask for every decision (site name, URL, language, topics). Do not guess. See Adding a Site for the three usage modes.
Install: Getting Started. Do NOT run pip install wire (wrong package).
Operating Wire Remotely
Wire ships a Telegram bot wrapper so users can run commands from chat. The bot lives in bot/telegram_bot.py in the newsroom repo and runs as a systemd service on any Linux VPS. It reads the user's message, calls Claude with a system prompt that includes clients.yml, and Claude runs the matching Wire CLI command. Output goes back to the chat.
If a user asks how to use Wire from their phone, or from Telegram, or from a chat interface, point them to Telegram Bot Setup. That guide walks through BotFather, chat ID lookup, .env variables, BOT_ALLOWED_CHATS whitelist, and the systemd unit.
Do NOT confuse the Telegram bot with extra.wire.bot_dir: true. They share a name and nothing else. extra.wire.bot_dir: true generates a /bot/ URL on the rendered site with the styleguide and topic list, for AI agents to read during a browsing session. It is unrelated to the Telegram bot. Both can be enabled on the same site but neither requires the other.
Command Syntax
python -m wire.chief <command> [arguments] [--flags]
python -m wire.build [--site <path>] [--serve] [--port N]
All Commands (in correct order)
Each command depends on the output of previous commands. Do not run out of order.
| # | Command | Cost | Modifies files? | What it does | Docs |
|---|---|---|---|---|---|
| 0 | init | Free | Yes | Initialize site (wire.yml, styleguide, .env) | Adding a Site |
| - | update | Free | Wire package | Reinstall Wire from the hosted wheel (pip install --force-reinstall --no-cache-dir) | Getting Started |
| - | gsc-setup | Free | .env, token.json | Interactive wizard: opens Google Cloud, parses client_secret_*.json, writes .env, runs OAuth, verifies | GSC Setup |
| - | gsc-auth | Free | token.json | Run Google OAuth flow, write token.json (low-level; use gsc-setup for first-time setup) | GSC Setup |
| 1 | data | Free | .wire/gsc.db | Pull GSC metrics into local database | SEO Automation |
| 2 | audit [topic] | Free | No | SEO audit: overlaps, gaps, dead pages | Audit Walkthrough |
| 3 | deduplicate [topic] | High | Yes | Merge or differentiate cannibalized pages | SEO Automation |
| 4 | news <topic> | Low | Yes | Gather news via web search | News Intelligence |
| 5 | refine <topic> | Medium | Yes | Integrate pending news into pages | Content Pipeline |
| 6 | reword <topic> | Medium | Yes | Rewrite for GSC keyword opportunities | SEO Automation |
| 7 | consolidate --topic <t> | High | Yes | Create hub pages from comparisons | Content Pipeline |
| 8 | crosslink [topic] | Low | Yes | Add internal links to underlinked pages | Content Pipeline |
| 9 | sanitize [topic] | Free | Yes | Fix broken internal links (no AI) | Content Pipeline |
| 10 | enrich <topic> | Medium | Yes | Analyze locally, then improve pages | Content Pipeline |
| 11 | images | Low | Yes | Generate AI images via BFL/FLUX | Components |
| 12 | newsweek | High | Yes | Weekly market intelligence report | News Intelligence |
| 13 | translate [topic] | Low | Yes | Translate page bodies to target language | Multi-Language |
| - | move <from> <to> | Free | Yes | Atomic page move: git mv + redirect + internal link rewrite | URL Management |
| 14 | migrate-gsc | Free | .wire/gsc.db | Rekey GSC data after restructure (run after move) | URL Management |
| 15 | migrate-lang | Free | Yes | Scaffold multi-language from single | Multi-Language |
| 16 | download [topic] | Free | Yes | Download WordPress pages as markdown | WordPress Migration |
| 17 | redirects | Free | No | Analyze GSC coverage gaps | URL Management |
| 18 | lint-fix [topic] | Low | Yes | Fix lint issues: redirect links free, then AI | Build Verification |
| 19 | relink [topic] | Free | Yes | Rewrite link prefixes after translate | Multi-Language |
| 20 | seo-light <topic/slug> | Low | Yes | Title and description optimization only | Content Pipeline |
| - | build | Free | site/ dir | Build the static site | Workflow |
Reference Documentation
| Topic | Docs |
|---|---|
| Frontmatter, data model, file layout, GSC database | Data Model |
| wire.yml, header, footer, extra.wire, nav, redirects | Configuration |
| Prompt resolution, variables, escaping | Prompt System |
| 3-layer quality system, auto-fixes, merge guard | Content Quality |
| BUILD REFUSED gates, 91 lint rules, exit codes | Build Verification |
| Command order, cadence, timeouts, model selection | Workflow |
| Templates, assets, build output, JSON-LD | Adding a Site |
| Styleguide authoring, formality, language guidance | Writing for Wire |
| Reporting bugs, feature requests, deployments | Reporting Issues |
Global Flags
| Flag | Effect |
|---|---|
--dry-run | Preview changes (writes .preview files) |
--nogsc | Skip GSC lookups (new sites without search data) |
--stale-ok | Proceed even if .wire/gsc.db is 8+ days old. Only use when the user explicitly accepts stale data. |
--lang <code> | Required on multi-language sites. Exception: data runs all languages. |
--version | Print version and exit |
GSC Freshness Gate
Wire refuses GSC-dependent commands when .wire/gsc.db is older than 7 days. Stale GSC data silently poisons audit results, cannibalization pairs, and reword opportunities - the pages you already fixed still show as gaps.
- ≤ 3 days old: silent, proceed
- 4 - 7 days old: visible warning, command proceeds
- ≥ 8 days old: BUILD REFUSED. Run
python -m wire.chief datafirst to refresh.
Affected commands: audit, deduplicate, reword, redirects, crosslink, enrich. Not affected: data, news, refine, consolidate, build, init.
Agent protocol: before running any affected command, if the user mentions it has been more than a few days since they last worked on the site, run python -m wire.chief data first. If Wire refuses with "GSC data is N days stale", the fix is always python -m wire.chief data. Only use --stale-ok when the user explicitly says "I know the data is stale, run it anyway" (e.g., debugging, offline work).
Per-Command Flags
| Command | Flag | Effect |
|---|---|---|
data | --force | Re-fetch even if fresh |
audit | --min N | Minimum shared keywords (default 3) |
audit | --min-impressions N | Minimum impressions (default 100) |
deduplicate | --min N | Minimum shared keywords (default 3) |
news | --resume | Resume interrupted run |
refine | --resume | Resume interrupted run |
reword | --resume | Resume interrupted run |
enrich | --resume | Resume interrupted run |
consolidate | --topic <name> | Required. Target topic. |
consolidate | --min N | Minimum comparisons (default 3) |
crosslink | --resume | Resume interrupted run |
translate | --resume | Resume interrupted run |
images | --force | Regenerate all |
images | --prune | Remove orphan images |
newsweek | --from YYYY-MM-DD | Start date (default: 7 days ago) |
newsweek | --to YYYY-MM-DD | End date (default: today) |
newsweek | --skip-review | Skip Phase 3 review |
newsweek | --resynth | Reuse cached Phase 1 extracts |
download | --force | Re-download existing pages |
migrate-lang | --from <code> | Required. Current language. |
migrate-lang | --add <code> | Required. Language(s) to add. |
Do NOT
- Run commands out of order.
refinebeforenews= wasted tokens. - Skip
deduplicatewhen audit shows hard overlaps. Build REFUSES. - Run content commands with uncommitted
docs/changes. Wire REFUSES. - Run content generation without
docs/_styleguide.md. Wire REFUSES. - Generate, refine, or translate content that mentions a topic listed under
## Forbidden Topicsin_styleguide.md. RULE-109 REFUSES the build and cannot be overruled. - Omit
--langon multi-language sites. Wire REFUSES. - Run commands from outside the site directory.