Archyl CLI
archyl connects a repository to its architecture in Archyl. From your terminal you can find where a file sits in the C4 model, see what your branch affects and who to tell, brief coding agents before they touch code, and guard what they write.
$ archyl impact
◆ archyl impact vs origin/main · 14 changed files
▍ Touched
◉ HTTP Handlers 3 files Archyl / Backend
◉ Harness Service 3 files Archyl / Backend
◉ Task Context 1 file Archyl / Backend
▍ Blast radius
◉ Harness Service
├── ◉ HTTP Handlers calls · 1 hop @platform
├── ◉ MCP Server calls · 1 hop
╰── ▣ Frontend calls · 2 hops @web
▍ Notify
@platform · @web · ada@example.com
The CLI is open source under the MIT license: github.com/archyl-com/cli.
Install
# Homebrew (macOS, Linux)
brew install archyl-com/tap/archyl
# Install script (macOS, Linux): checks the archive's checksum
curl -fsSL https://raw.githubusercontent.com/archyl-com/cli/main/install.sh | sh
# Go (1.26 or later)
go install github.com/archyl-com/cli/cmd/archyl@latest
You can also download a binary from the releases page. Archives are checksummed, signed with cosign and ship with an SBOM.
Check the installation with archyl --version.
Get started
From the root of your repository:
archyl login # sign in through your browser
archyl init # link this repository to its Archyl project
archyl status # alignment score, your branch, active agents
archyl login opens your browser and signs you in with OAuth 2.1 and PKCE. The session is stored in the OS keychain and refreshes itself; you sign in again only after a month without use.
archyl init writes .archyl.json at the repository root so every archyl command, and the Guard hook, knows which project this code belongs to. When the repository's remote is connected to a project in Archyl, that project is picked for you; otherwise you choose it from a list. Commit the file: it holds no secret, and your team and CI then share the link.
{
"projectId": "3f2a9c4e-…",
"projectName": "Checkout",
"organizationId": "8b1d…",
"apiUrl": "https://api.archyl.com"
}
Run archyl init --force to relink a repository to another project.
No project yet? archyl init --new starts one without leaving the terminal:
- It creates the project, named after the repository (or
--name), in the team you choose (--team, by name, slug or ID). - It connects the repository from its git remote. For a self-hosted remote, give the provider with
--provider:github_enterprise,gitlab_privateorgitea. - It runs an AI discovery on
--branch(default: the remote's default branch) and shows its progress live. - It opens the review of what the discovery found, then draws the result as a diagram.
- It offers to connect your coding agents.
Plain archyl init offers the same when no project matches the repository's remote. --no-discover only creates and links the project, --no-setup skips the last step, and --yes takes every default without asking, including approving what the discovery finds.
archyl init --new
archyl init --new --name "Checkout" --team platform
archyl init --new --yes --json
The session
Run archyl on its own to open a session: a prompt where you ask about the architecture in plain language or type commands, with answers flowing into your terminal like any other output.
$ archyl
◆ archyl
Checkout · feature/refunds · alignment 86
Ask anything about the architecture. / commands · @ files · # elements
› which elements does my branch touch, and who should I tell?
⏺ archyl impact
Touched ◉ Payments 4 files in Checkout / API
… +12 lines
Your branch changes Payments, which Checkout Web calls and the Refund
Worker reads. Tell @payments before merging.
› /run last
- Plain language goes to the assistant. It answers from the architecture, and when the answer depends on your code or on what is happening right now, it runs the matching command here —
impact,check,brief,show,runs… — and shows each one (⏺) before using its output. Read-only commands run side by side; commands that change something, such as approving a run's plan or recording a memory, ask you first (y/n). /commands run directly:/impact,/review,/brief <files>,/show <element>,/runs,/activity… Full-screen views (/map,/search,/run,/agents) take the screen and give it back when you quit them./helplists everything.@fileattaches the file's content to the question, with its architecture brief: up to 400 lines or 24 KB per file; binary files and paths outside the repository are skipped.#elementpoints the question at an element. Both complete as you type.Entersends;Shift+Enter(orAlt+Enter,Ctrl+J) starts a new line, and pasted text keeps its line breaks.↑↓browse your history,Tabcompletes,Escstops an answer,Ctrl-Dleaves.
Conversations are kept per repository: archyl -c (--continue) reopens the last one, /resume picks an earlier one from a list, and /new starts a fresh one.
The first time, the session tells you what is missing: signing in (/login), linking the repository (/init). The assistant is available on plans that include AI chat; / commands work on every plan. With OpenAI and Anthropic models it calls the commands as native tools; with other providers it goes through a text protocol, and you see no difference.
doctor
archyl doctor checks everything the CLI depends on and says how to fix what is not right: your version, profile, sign-in, API latency, repository, project link, connected agents, the Guard hook and the pre-push hook. It exits 1 when something must be fixed.
Explore the architecture
activity
archyl activity is one feed of what happens on the project: elements created and changed (with the fields that changed), change requests opened and merged, agent runs queued, waiting on someone and finished, work sessions opened and closed. --follow keeps it open and prints events as they happen, like tail -f; add --notify for a desktop notification when an agent waits for you.
archyl activity --follow --notify
archyl activity --element "Payments"
map
archyl map opens a full-screen explorer of the C4 model: systems, containers, components and code in a tree, with each element's description, technologies, relationships in both directions and blast radius. Name an element to open on it: archyl map "Payments".
| Key | Action |
|---|---|
↑ ↓ or j k |
Move |
→ or Enter |
Open an element |
← |
Close it, or go to its parent |
/ |
Filter by name (fuzzy) |
u / b |
Jump to what it uses / what uses it |
o |
Open it in the web app |
y |
Copy its ID |
E / C |
Expand / collapse everything |
d |
Show the level as a diagram |
f |
Show a diagram centred on the element |
q |
Quit |
d shows the current level as a diagram, and f a diagram centred on the element. Tab and Shift+Tab select an element, the arrows or h j k l scroll, Enter drills down into the selection, f centres on it, Backspace or u goes back up (from a centred diagram, to the level the element sits in), o opens it in the web app, y copies its ID, and d or Esc returns to the tree.
diagram
archyl diagram draws the system context by default. Name an element of any level (system, container, component or code) and the diagram is centred on it: the element in the middle, accented, with everything its relationships reach in both directions. Relationships of the element's children count as its own. A neighbour deeper than the element is drawn as its ancestor at the element's level, so a component sees the components, containers and systems around it, never their code, and a neighbour from another parent names that parent.
--inside draws the C4 view inside the element instead: a system's containers, or a container's components, with the elements around them dashed.
archyl diagram # the system context
archyl diagram Checkout # centred on Checkout and its neighbours
archyl diagram "Orders DB" --depth 2 # two hops around it
archyl diagram Billing --inside # the containers of the Billing system
archyl diagram "Billing API" -o billing-api.png
archyl diagram --format mermaid > context.mmd
archyl diagram Billing --json | jq '.nodes[].name'
In Kitty, Ghostty, WezTerm and iTerm2 the diagram is an inline image. In other terminals, and when the output is piped, it is drawn with box-drawing characters:
┌─────────────────┐ ┌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┐ ┌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┐
│ ▣ Storefront │ ╎ ◆ Warehouse ╎ ╎ ◆ Mailgun ╎
│ web app · React │ ╎ software system ╎ ╎ software system ╎
└────────┬────────┘ └╌╌╌╌╌╌╌╌┬╌╌╌╌╌╌╌╌┘ └╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┘
│ │
└───────────────┐ │ updates stock
places orders ×2 │ │
▼ ▼
┌─────────────────┐
│ ▣ Shop API 4 ◉ │
│ api · Go │
└─────┬─────┬─────┘
charges cards │ │ reads from ×2
▼ ▼
| Flag | Purpose |
|---|---|
--format |
text, image (inline in the terminal), png, svg or mermaid. Default: image in a terminal that shows images, text elsewhere |
-o, --output |
Write to a file; the extension picks the format (.png, .svg, .mmd, .md, .txt) |
--depth |
Hops around the named element, from 1 (default) to 3 |
--inside |
Draw what the element contains instead of centring on it |
--json |
The laid-out nodes and edges, for scripts |
In archyl map, d shows the level the selection sits in and f centres the diagram on it.
Inside tmux, images need set -g allow-passthrough on and a terminal that speaks the iTerm2 image protocol. Set ARCHYL_IMAGES=0 to always draw text.
search
archyl search searches everything you can see in Archyl: elements, decisions, documentation, API contracts, event channels, flows and projects. Results update as you type, with a preview; Enter shows the pick, ctrl+o opens it in the web app. Piped or with --json, archyl search invoice prints the hits.
show
archyl show <element> prints an element with its path, description, technologies, relationships, linked decisions and blast radius. archyl show ADR-12 renders a decision record. Elements are found by name (exact, then partial) or ID.
open
archyl open opens the project in the web app; archyl open "Payments" selects an element on the diagram, archyl open ADR-12 unfolds a decision. The web app's address is the API host with api. replaced by app.; when it is elsewhere, sign in with --app-url or set ARCHYL_APP_URL.
ask
archyl ask "<question>" asks the AI assistant about the project's architecture. The answer is rendered as markdown while it is being written. Anything you pipe in is added to the question:
archyl ask "Which services write to the orders database?"
git diff main | archyl ask "Does this break any of our decisions?"
The assistant is available on plans that include AI chat.
adr
archyl adr lists the project's decisions. archyl adr new records one: in a terminal, a form asks for the title, status, context, decision and consequences; in scripts, pass them as flags.
archyl adr new "Use slog for structured logging" --status accepted \
--context "Three logging libraries are in use" --decision "slog everywhere"
discover
archyl discover starts an AI discovery on the repositories linked to the project and follows it, with its progress on stderr. What it finds does not join the model straight away: it waits for review, which opens on its own when the discovery ends in a terminal. Each linked repository counts as one AI discovery against your plan's quota.
archyl discover
archyl discover --repo acme/payments --branch develop
archyl discover --no-wait --json
| Flag | Purpose |
|---|---|
--repo |
Repository to discover, as owner/name (default: every linked repository) |
--branch |
Branch to read (default: the repository's default branch) |
--wait / --no-wait |
Follow the discovery until it ends (the default), or start it and return its job |
--no-review |
Do not open the review when the discovery ends |
archyl discover review lists the elements discoveries propose, grouped by C4 level, with the selected element's details on the side:
| Key | Action |
|---|---|
↑ ↓ or j k |
Move |
Space |
Select |
a / r |
Approve / reject the selection, or the current element |
A |
Approve everything listed |
/ |
Filter (fuzzy) |
q |
Quit |
Outside a terminal it prints the list; --approve-all or --reject-all settles everything at once, and --json prints it for scripts.
Architecture commands
tour
archyl tour walks a newcomer through the codebase in a few minutes. It opens with the big picture, then visits the parts worth meeting first, in the order work flows: the systems when the project has several of its own, otherwise the containers, starting where outside systems send work in. Shared infrastructure (queues, caches, databases, storage, shared libraries) is listed in the big picture and never takes a stop. Name an element to tour only that part: a system's containers, or a container and its components.
Archyl's AI writes the story from the model: what the system does, its main flows, the role of each stop in them, and a piece of work to follow through the code. It is told to use only the model's facts, and it counts against your AI quota; --no-ai skips it. Under the story, each stop lists facts from Archyl and your repository: its key parts, what it uses and what uses it, who owns it, the files to read first (the paths the model records, then entry points and recently changed files in the folder named after it, without build, deployment or generated files), the decisions that apply, what people and agents remembered about it, the rules that guard it, and a small diagram centred on it.
archyl tour # full screen in a terminal
archyl tour "Video Workflow" # only that system's containers
archyl tour --markdown > ONBOARDING.md
archyl tour --no-ai --json | jq '.stops[].name'
| Key | Action |
|---|---|
n, →, Space |
Next stop (on the last one, finish) |
p, ← |
Previous stop |
1–9 |
Jump to a stop |
j k, PgUp PgDn |
Scroll |
o |
Open the stop in the web app |
q |
Quit |
Piped, the tour prints compact Markdown, which is what a coding agent reads before its first task. --markdown adds a Mermaid diagram per stop, for a document to commit. --stops sets how many stops to visit (default 6). Without AI, the stops and their order come from the model alone, so the same model always gives the same tour; with AI, the story may reorder them.
history
archyl history [from..to] [element] shows how the architecture changed between two points of its history: the elements and relationships added, removed and modified, as lists and as a diagram with the changes marked. Use it for release notes, retrospectives, or a README animation.
archyl history # the version before the latest → now
archyl history v1.2.0..v2.0.0 # between two releases
archyl history 30d.. Billing # the last 30 days, in and around Billing
archyl history v1.2.0.. --markdown >> RELEASE_NOTES.md
archyl history 2026-09-01..now -o changes.png
archyl history ..now --play # replay every version full screen
archyl history 12..15 --json | jq '.summary'
A range is from..to, and either side may be left out: v1.2.0.. runs to now, ..v2.0.0 starts at the oldest version kept. A single point means from it to now. Without a range, the history compares the version before the latest with now, so the latest edits and anything not yet recorded both show. Each point is one of:
| Point | Means |
|---|---|
now |
The model as it is |
12, rev12, r12 |
A version number |
v1.2.0 |
A release, as archyl release recorded it: the latest version created at or before it went out. 1.2.0 finds v1.2.0; an unknown release lists the closest ones |
2026-09-01 |
The end of that day, in your time zone |
30d, 2w, 12h, 3mo, 1y |
That long ago |
Archyl records a version of the model when it is edited in the web app or through the API, merging the edits one person makes within a few minutes, and keeps the most recent ones; the time-lapse replays the same versions. The comparison is computed by the CLI, so now always works. Elements are matched by ID, then by their path of names from the system down, so an element recreated under the same name is the same element. Each one is listed as added, removed or modified, with what changed: renamed, moved to another parent, its type, its description, external or not. An element removed with its children counts once ("Mailer and its 3 children"), and the relationships that went with it are folded into one line.
The diagram merges both ends: what is there now, with what was removed put back where it was. It shows the containers when they all sit in one system, else the system context, and gives a box to every change even when no arrow reaches it. Added boxes and arrows are green with +, changed ones amber with ~, removed ones dashed and dim with −; a box whose own element is unchanged but holds changed elements counts as changed. Name an element to centre the diagram on it and list only the changes in and around it; --inside draws what it contains instead. Large views keep the changed boxes first.
◆ archyl history v1.0.0 (REV 1, 2026-09-01) → now
elements: 2 added, 1 modified; relationships: 2 added
┏━ ~ ━━━━━━━━━━┓
┃ ▣ Orders API ┃
┃ api ┃
┗━━━━┯━━━━┯━━━━┛
│ │
┌─────┘ └─────┐
│ charges cards │
▼ queues jobs ▼
┏━ + ━━━━━━━━┓ ┌╌╌╌╌╌╌╌╌╌╌╌╌┐
┃ ▣ Worker ┃ ╎ ◆ Stripe ╎
┃ worker ┃ ╎ system ╎
┗━━━━━━━┯━━━━┛ └╌╌╌╌╌╌╌╌╌╌╌╌┘
│
│ sends receipts
▼
┏━ + ━━━━━━━━┓
┃ ◆ Mailgun ┃
┃ system ┃
┗━━━━━━━━━━━━┛
+ added ~ changed − removed
Added
+ ◆ Mailgun system
+ ▣ Worker container in Shop
Modified
~ ▣ Orders API container in Shop
renamed from "API"
Piped, it prints Markdown for release notes: a ## Architecture changes v1.2.0 → v2.0.0 heading, the counts, and bullet lists of what was added, removed and modified. --markdown prints the same in a terminal and adds a Mermaid diagram with the changes classed added, changed and removed.
--play replays every version of the range full screen, like the web app's time-lapse: each frame is the model at a version, with what changed since the frame before marked, under a header with the version's number, date, author and description. A replay holds at most 60 frames: past that, it plays the first version and the latest ones, and says so.
| Key | Action |
|---|---|
Space |
Pause or resume (at the end, play again from the start) |
← → |
Step back or forward |
+ - |
Faster or slower |
j k |
Scroll a tall diagram |
q |
Quit |
| Flag | Purpose |
|---|---|
--markdown |
Print Markdown with a Mermaid diagram, for release notes |
--format |
Write the diagram alone: text, image, png, svg or mermaid |
-o, --output |
Write the diagram to a file; the extension picks the format (.png, .svg, .mmd, .md, .txt) |
--inside |
Draw what the element contains instead of centring on it |
--play |
Replay every version in the range full screen |
--interval |
How long --play shows each version (default 1.5s) |
--json |
The two ends, the counts, every change with its fields, and the diagram's nodes and edges with their change |
Versions record no technologies, so technology changes do not show.
where
archyl where <path>… places files in the C4 model: the element each one belongs to, who owns it and what depends on it. Directories expand to the files git knows about.
archyl where internal/billing/invoice.go
archyl where src/checkout/
why
archyl why <file[:line]> is git blame for the architecture. For a file, it shows the elements it belongs to, the decisions that apply (accepted ones first), who owns it, what agents and people remembered about it, the latest model changes to those elements and the conformance rules aimed at it. With a line number, it also finds the commit that last changed the line and ties it to the decisions made around the same time.
archyl why internal/billing/invoice.go
archyl why internal/billing/invoice.go:42
archyl why --json src/checkout/cart.ts | jq '.decisions[].title'
In a terminal the answer renders; piped or run by an agent, it prints compact markdown.
impact
archyl impact compares your working tree with a base branch, places every changed file in the architecture, and walks the relationships to find what depends on it, with the owners to notify. It covers committed, staged, unstaged and untracked changes, so you can run it before you even commit.
| Flag | Default | Purpose |
|---|---|---|
--base |
origin's default branch | Branch to compare with |
--depth |
2 |
How many relationship hops to follow (1 to 6) |
--diagram |
— | Draw the affected part of the architecture, touched elements highlighted |
archyl impact --base origin/develop --depth 3
archyl impact --diagram
Each file counts toward its most specific match only: a file mapped to a component does not also drag in its whole container.
incident
archyl incident <element> is the screen to open when something is on fire. For an element of any level, it shows who owns it (or its closest owned ancestor), who depends on it, grouped by distance with each dependent's owners, and what it depends on, since a failing dependency is often the real cause. It adds the latest model changes and releases, the documentation, decisions and pitfalls linked to it or its ancestors, and everyone to tell.
archyl incident "Orders API"
archyl incident Payments --depth 3
archyl incident "Orders API" --slack --copy # a message for the incident channel
No AI is involved, so it answers fast and the same way every time. The API calls run together under a short timeout; a section whose call fails says so and the rest still shows. --slack prints only a ready-to-paste message with plain names and emails to ping, --copy puts it on the clipboard, --depth (1 to 4, default 2) sets how far the blast radius goes, and --no-diagram leaves out the diagram. Piped, the report is Markdown; --json gives it to scripts.
status
archyl status fits the project on one screen: model-to-code alignment, your branch and the agents working on the project right now.
context
archyl context prints the project's architecture as markdown tuned for coding agents: systems, containers, components, relationships, decisions and rules. Pipe it, or write it to the file your agent reads.
archyl context > ARCHITECTURE.md
archyl context -o .archyl/context.md
Coding agents
The CLI is the quickest way to put a coding agent under the Archyl Harness.
setup
archyl setup
archyl setup configures Claude Code, Cursor, VS Code and Codex to use Archyl's MCP server with the coding tool profile, installs the Guard hook and teaches the agents the CLI. Restrict it with --agent (repeatable: claude-code, cursor, vscode, codex); skip parts with --no-guard, --no-instructions or --no-statusline.
archyl setup also offers to install shell completion; --no-completion skips it.
| Agent | File written |
|---|---|
| Claude Code | .mcp.json; the Guard hook and the status line in .claude/settings.json; the CLI block in CLAUDE.md |
| Cursor, VS Code, Codex | The CLI block in AGENTS.md |
| Cursor | .cursor/mcp.json |
| VS Code | .vscode/mcp.json |
| Codex | ~/.codex/config.toml |
Existing files are merged, not overwritten.
By default (--transport cli), each agent starts archyl mcp, which reaches Archyl's MCP server with the CLI's own session: sign in once with archyl login and every agent is connected, with no OAuth flow per agent and no key in a file. With --transport http, the configuration holds only the server URL and each agent signs in through Archyl itself. Either way the repository files hold no secret and are safe to commit.
mcp
archyl mcp serves Archyl's MCP tools to an agent over stdio, authenticated as you. archyl setup configures it; by hand, for any MCP client:
{ "mcpServers": { "archyl": { "command": "archyl", "args": ["mcp"] } } }
It uses the coding tool profile; --tools full exposes every tool.
The CLI block is a short section between <!-- archyl:start --> and <!-- archyl:end --> markers that tells the agent which archyl commands to run and when: plan before a non-trivial change, brief before editing files, check and radar check before finishing, remember and recall for what the code cannot show. Running setup again refreshes the block and leaves the rest of the file alone. A status line already set in Claude Code is never replaced.
plan
archyl plan "<task>" returns an implementation plan grounded in the architecture: the steps, the element each one touches, the decisions and rules to respect, and what previous sessions learned.
archyl plan "Add partial refunds to the payments flow"
brief
archyl brief <files> tells you, or an agent, what to know before editing those files: the elements they belong to, what those elements use and what depends on them, the decisions that apply to them or their parents, their owners, and what Archyl remembers about them. Without paths, it covers every file the branch changes.
Like plan, recall and context, it renders in a terminal and prints compact markdown when an agent runs it from its shell, so the agent reads structure, not escape codes.
remember and recall
archyl remember records a fact the code cannot show on the element it is about; every future work session on that element is briefed with it. archyl recall finds what Archyl remembers, by topic, element or kind.
archyl remember "Refund amounts are in minor units; never use floats" \
--element "Payments" --kind pitfall
archyl recall refunds
archyl recall --element "Payments" --kind convention
| Kind | Use it for |
|---|---|
convention |
How things are done here |
pitfall |
What bit someone, so it does not bite the next one |
note |
Anything else worth knowing |
The memory is attributed to the agent that wrote it when the CLI runs inside Claude Code, Codex or Cursor; set ARCHYL_AGENT to name it yourself.
agents
archyl agents is a live view of the agents at work on the project: which agent, on what task, on which elements, with which files changed. Elements leased by more than one agent are flagged so two agents do not collide on the same code. Press a to include recently ended sessions. Piped or with --json, it prints the sessions once.
statusline
archyl statusline is a status line for Claude Code: the project, its alignment score, the agents at work and whether the current session runs under the harness. archyl setup installs it; by hand, in .claude/settings.json:
{ "statusLine": { "type": "command", "command": "archyl statusline" } }
runs
archyl runs lists the project's managed agent runs, with the ones waiting on you flagged. archyl runs view follows one live: the agent's messages, its tool calls and the files it changes in the feed, its plan with each step's progress, the time, tokens and cost on the side. And you act on it without leaving the terminal:
| Key | When | Action |
|---|---|---|
Enter or 1–9 |
The agent asks a question | Answer it, or pick one of its options |
a / c |
The agent proposes a plan | Approve it, or ask for changes |
a |
The run is held for approval | Let it start |
s |
The run is running | Steer the agent with a message |
x |
The run is running | Cancel it (asks to confirm) |
n |
The run has ended | Continue its work in a new run, on the same branch and pull request |
o |
The run opened a pull request | Open it |
The same actions exist as commands, for scripts and for agents supervising agents. Runs are named by the first characters of their ID, or last:
archyl runs start "Add partial refunds" --profile backend-fixer
archyl runs view last
archyl runs answer 3f2a9c4e "Keep the v1 endpoint"
archyl runs approve 3f2a9c4e
archyl runs request-changes 3f2a9c4e "Split the migration from the API change"
archyl runs steer 3f2a9c4e "Use the ledger service, not the orders table"
archyl runs continue 3f2a9c4e "Add tests for the edge cases"
archyl runs cancel 3f2a9c4e
Managed agent runs are available on plans that include them.
decide
archyl decide writes the Architecture Decision Record while the decision is fresh. It reads your branch (the commits since --base and the uncommitted changes), places them in the architecture, and has Archyl's AI draft the record from those facts only: title, context, decision, consequences, the alternatives the change shows, and the touched elements it is about. Without an argument, the decision is inferred from the diff.
archyl decide "Publish order events through an outbox table"
archyl decide # infer the decision from the diff
archyl decide --no-ai "Use slog for logging"
archyl decide --print > decision.md
In a terminal the draft is shown, then you create it, edit it in $VISUAL or $EDITOR (front matter for title, status and elements, then the sections), or drop it. It is recorded with the status proposed and linked to its elements; if a link fails, the record is kept and the command says how to add the link. Piped, or with --print, the draft is printed as Markdown and nothing is created unless --yes. The draft counts against your AI quota; --no-ai starts from a template filled with the files and elements instead.
wrap
archyl wrap -- claude # asks what the task is
archyl wrap --task "Add PDF export to invoices" -- claude
archyl wrap --agent codex --exclusive -- codex "fix the flaky checkout test"
archyl wrap runs any agent inside a work session:
- It opens a session for the task. Archyl picks the relevant elements, decisions and rules, leases the elements so two agents do not collide, and returns a briefing with the gate verdict.
- Claude Code receives the briefing as an appended system prompt. Every agent finds
ARCHYL_SESSION_IDandARCHYL_BRIEFING_FILEin its environment. - While the agent works, the session is kept alive with a heartbeat every 10 minutes, and the Guard hook attributes each edited file to it.
- When the agent exits,
wrapreports the files that changed, closes the session and offers to open a draft Architecture Change Request so a human reviews how the model should catch up.
| Flag | Purpose |
|---|---|
-t, --task |
What the agent is about to do (asked when omitted) |
--agent |
Agent name recorded on the session (default: the command name) |
--exclusive |
Refuse to start when another session holds a lease on the same elements |
--change-request |
Open the draft change request without asking |
--no-change-request |
Never ask to open a change request |
If Archyl is unreachable, wrap warns and runs the agent anyway.
fix
archyl fix
archyl fix --severity high --agent codex
archyl fix --print | pbcopy
archyl fix -- claude --model opus
archyl fix puts a coding agent to work on your branch's rule violations, under the harness:
- It runs the conformance check on the branch, like
archyl check, and lets you pick the violations to fix. - It opens a work session and hands the agent each violation with its rule, severity, location and suggestion, along with the brief of the elements the files belong to and the decisions that apply.
- When the agent exits, it runs the check again and shows what is left, for example "3 violations → 0".
Nothing is committed: review the changes with git diff. The agent is the first one installed among Claude Code and Codex, or the one --agent names. After --, any command runs instead; it reads the task from the file named in ARCHYL_FIX_TASK_FILE.
| Flag | Purpose |
|---|---|
--agent |
claude, codex or gemini (default: the first one installed) |
--severity |
Lowest severity to fix: critical, high, medium or low (default low) |
--base |
Ref to compare with (default: the pull request's target, or origin's default branch) |
-y, --yes |
Fix every violation without asking |
--print |
Print the task prompt instead of running an agent, to hand it to any other agent |
--change-request |
Open a draft Architecture Change Request when the session closes |
lsp
archyl lsp is a Language Server over stdio for any editor with an LSP client. It runs next to the language's own server:
| Feature | What you get |
|---|---|
| Diagnostics | The conformance rules, run on a file when you open or save it. Critical and high findings are errors, medium ones warnings, low ones information |
| Hover | The file's element: its place in the C4 model, owners, how many elements depend on it, the decisions that apply |
| Code actions | Ask Archyl why asks the assistant why a rule exists, or why the file is built the way it is; Open in Archyl opens the element in the browser |
It uses the CLI's session (archyl login or ARCHYL_API_KEY) and the repository's .archyl.json. When Archyl cannot be reached, it writes one warning to the editor's LSP log and shows no diagnostics. Diagnostics follow saves, not keystrokes.
Neovim 0.11 and later:
vim.lsp.config("archyl", {
cmd = { "archyl", "lsp" },
root_markers = { ".archyl.json", ".git" },
filetypes = { "go", "typescript", "python", "java", "rust" },
})
vim.lsp.enable("archyl")
Helix, in languages.toml:
[language-server.archyl]
command = "archyl"
args = ["lsp"]
[[language]]
name = "go"
language-servers = ["gopls", "archyl"]
VS Code goes through the Generic LSP Client extension, and Zed through a small dev extension. The setup for each editor is in docs/lsp.md.
guard
archyl guard is the Claude Code PreToolUse hook that archyl setup installs. It reads the hook payload on stdin, runs the project's conformance rules on the file as it would be after the edit, and answers with a decision: critical violations block the edit, high ones warn. Set ARCHYL_GUARD_BLOCK to high to block high violations too, or off to only warn.
When the agent edits a dependency manifest (go.mod, package.json, pom.xml…), the Guard also checks it against the technology radar and blocks a dependency the radar puts on hold, with the alternative its note suggests. Dependencies on hold that were already there do not block the edit.
The Guard always fails open: no credential, no network or an unknown tool lets the edit through, so it can never break your workflow.
session
archyl session gives low-level access to the work-session protocol, for scripts or agents that drive it themselves. Most of the time archyl wrap does all of this for you.
archyl session start --task "Migrate invoices to the new ledger" --exclusive
archyl session heartbeat <session-id>
archyl session finish --summary "Ledger migration done" \
--decision "Invoices are written through the ledger service only" \
--follow-up "Backfill invoices older than 2024" \
--change-request
archyl session list --all
archyl session cancel <session-id>
finish takes the session ID as an argument or from ARCHYL_SESSION_ID. Put only ADR-worthy choices in --decision: each one becomes memory replayed to future sessions on the same elements. Everything situational goes in --follow-up.
Checks and CI
The same commands run on your laptop, in a git hook and in any CI. In CI they pick the base branch, the commit and the report format from the environment: GitHub Actions, GitLab CI, Bitbucket Pipelines and Azure Pipelines are recognised.
check
archyl check runs the project's conformance rules on every file that differs from the base branch and exits 1 when a violation reaches --fail-on.
$ archyl check
CRITICAL Forbidden pattern found: fmt.Println (use slog) No printing in services
╭─ internal/billing/invoice.go:42
42 │ fmt.Println("total", total)
╰─ → Remove usage of the forbidden pattern: fmt.Println (use slog)
✗ 1 violation in 3 changed files · 1 critical
| Flag | Default | Purpose |
|---|---|---|
--base |
the pull request target, else origin's default branch | Ref to compare with |
--fail-on |
high |
Lowest severity that fails: critical, high, medium, low or never |
--format |
auto |
pretty, json, github, gitlab or sarif |
-o, --output |
stdout | File for the gitlab or sarif report |
--fail-open |
off | Exit 0 when the check cannot run (offline, signed out); only violations fail |
With --format auto, the output follows the CI:
| Where | What you get |
|---|---|
| GitHub Actions | Inline annotations on the pull request, plus a table in the job summary |
| GitLab CI | A Code Quality report in gl-code-quality-report.json, shown in the merge request |
| Anywhere else | The terminal view above |
--format sarif writes a SARIF 2.1.0 log for GitHub code scanning, Azure DevOps or any security dashboard.
CI checkouts are often shallow. Fetch the history so the base branch exists, otherwise check stops and tells you so.
# GitHub Actions
- uses: actions/checkout@v4
with:
fetch-depth: 0
- run: archyl check
env:
ARCHYL_API_KEY: ${{ secrets.ARCHYL_API_KEY }}
# GitLab CI
archyl:
variables:
GIT_DEPTH: 0
script:
- archyl check
artifacts:
reports:
codequality: gl-code-quality-report.json
review
archyl review is the pass to run before you open a pull request. It combines the rule violations your branch introduces, the elements it touches with what depends on them, who to notify, and the current alignment score. It exits 1 when a violation reaches --fail-on (default high).
With --comment, the review is posted on the pull or merge request, and edited in place on every later push so the request keeps a single Archyl comment: the verdict, the violations with their file and line, the elements touched with what depends on them, and the owners to loop in. GitHub needs GITHUB_TOKEN with pull-requests: write; GitLab needs GITLAB_TOKEN with the api scope, since CI_JOB_TOKEN cannot comment.
The comment includes the impact as a Mermaid flowchart, which GitHub and GitLab render. archyl review --diagram prints the same flowchart locally, to paste into a description or a document.
The quickest setup on GitHub is the Archyl action, which installs the CLI and runs a command:
name: Architecture
on: pull_request
permissions:
contents: read
pull-requests: write
jobs:
archyl:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: archyl-com/cli@v1
with:
api-key: ${{ secrets.ARCHYL_API_KEY }}
command: review --comment
Leave command empty to only install the CLI and call it in later steps.
hooks
archyl hooks install # blocks critical violations on git push
archyl hooks install --fail-on high
archyl hooks uninstall
archyl hooks install adds a git pre-push hook that runs archyl check --fail-open. A push that brings a violation at or above --fail-on (default critical) is refused; without archyl on the PATH, offline or signed out, the push goes through. Skip it once with git push --no-verify. The hook honours core.hooksPath, and a pre-push hook archyl did not write is never replaced unless you pass --force.
drift
archyl drift shows how well the documented model matches the code: 100 means every documented element was found in the code. --compute re-analyses the connected repository first and waits for the result; --fail-under turns it into a quality gate.
archyl drift --compute --fail-under 80
codeowners
archyl codeowners writes the owners of your systems, containers and components into CODEOWNERS, one line per folder, so reviews go to the people Archyl says own the code.
archyl codeowners # print the file as it would be
archyl codeowners --write # update it, after showing the diff
archyl codeowners --check # in CI: exit 1 when it is out of date
An element's folders are the ones holding the files the model records for it, else the folder named after it, else, for a container or system, the deepest folder holding everything its components record. An element without owners of its own takes those of its closest owned ancestor. A team is written @<org>/<team-slug>, the org being --org, else codeowners.org in .archyl.json, else the owner of the git remote; a person is written as their email. Other handles are mapped in .archyl.json:
{
"codeowners": {
"org": "acme",
"teams": { "platform": "@acme/video-platform" },
"users": { "ada@example.com": "@ada" }
}
}
The generated lines live between # BEGIN archyl codeowners and # END archyl codeowners; everything outside the block is yours and kept. The file is the first of .github/CODEOWNERS, CODEOWNERS, docs/CODEOWNERS and .gitlab/CODEOWNERS that exists, else .github/CODEOWNERS (.gitlab/ for a GitLab remote). Elements with owners but no folder, and owners with no handle, are reported.
dsl
archyl dsl keeps an architecture-as-code file and the project's model in step. Every subcommand works on archyl.yaml at the repository root unless you pass --file.
archyl dsl pull # write the project's model to archyl.yaml
archyl dsl diff # what pushing the file would change
archyl dsl diff --exit-code # in CI: fail when the file and the model differ
archyl dsl push # import the file into the project
pullexports the model (elements, relationships, technologies, decisions, docs, contracts, environments and releases). It asks before overwriting the file, unless you pass--yes;--file -prints it instead.diffis a dry run on the server, without writing anything: the elements and relationships a push would add (+) or change (~), grouped by C4 level, and those only Archyl has (−).--exit-codeexits 1 when there is any difference.pushcreates new elements and relationships and updates existing ones, matched by name. It never deletes: what only Archyl has stays. In a terminal it shows the diff and asks first;--yesskips the question.
diff and push also send every file the include directives reach, read from your working tree. Includes resolve against the directory of the file that declares them and must stay inside the repository; a missing one stops the command before anything is sent.
$ archyl dsl diff
▍ Containers
+ Refund Worker
~ Payments API
description "Card payments" → "Card and wallet payments"
− Legacy Billing only in Archyl, push keeps it
archyl.yaml vs the model: 1 to add · 1 to change · 1 only in Archyl
archyl sync [file] is the same as archyl dsl push.
release
archyl release records a release, to correlate architecture changes with what shipped and feed the DORA metrics. The version defaults to the tag being built in CI, then to the tag on HEAD; the link defaults to the CI run.
archyl release v2.4.0 --environment production
| Flag | Purpose |
|---|---|
--environment |
Environment it shipped to |
--status |
Release status (default deployed) |
--changelog |
Release notes |
--system, --container |
Element the release belongs to |
--url |
Link to the release or pipeline |
radar
archyl radar shows the organization's technologies by governance ring (adopt, trial, assess, hold) with how much of the architecture uses each. archyl radar check reads the repository's dependency manifests, matches each dependency to the radar and exits 1 when one is on hold, with the same CI output as archyl check.
$ archyl radar check
HOLD github.com/sirupsen/logrus 1.9.3 go.mod
→ Use log/slog from the standard library
ASSESS go.uber.org/zap 1.27.0 go.mod
✗ 1 dependency on hold · 4 dependencies in 1 manifest · 1 adopt · 0 trial · 1 assess · 1 hold · 1 unclassified
| Flag | Default | Purpose |
|---|---|---|
--fail-on |
hold |
Ring that fails: hold, assess or never |
--changed |
off | Only manifests changed against the base |
--format |
auto |
pretty, json, github, gitlab or sarif |
cr
archyl cr lists the project's Architecture Change Requests — often opened by agents at the end of a work session — and lets you review them without leaving the terminal.
archyl cr # list
archyl cr show 12 # the request and its changes
archyl cr approve 12
archyl cr request-changes 12 -m "Keep the ledger behind the Payments API"
archyl cr open 12 # in the web app
Accounts and profiles
| Command | What it does |
|---|---|
archyl login |
Browser sign-in. --host targets another Archyl instance, --with-token reads an API key from stdin |
archyl logout |
Forget the stored credential |
archyl cache clear |
Delete the cached models of the active profile; --all clears every profile's |
archyl whoami |
Who you are, on which host, organization and project |
archyl profile |
List profiles; archyl profile use <name> switches |
archyl inbox |
Your notifications: mentions, reviews, agent runs, tasks. In a terminal, pick one to act on it: review a change request, answer an agent, or open it in the web app. --watch stays open with desktop notifications; --read marks everything read |
A profile is one Archyl host and organization with its own credential. Create one by signing in with a name, which is also how you connect to a self-hosted Archyl:
archyl login --host https://archyl.example.com --profile work
archyl profile use work
Shell prompt
archyl prompt prints the project's alignment score and active agents in a few characters for your shell prompt. It never waits on the network: it prints the last known state and refreshes it in the background every ten minutes. With Starship:
[custom.archyl]
command = "archyl prompt"
when = "test -f .archyl.json"
format = "[$output]($style) "
style = "purple"
Model cache
map, show, open, element completion and the session's # suggestions answer from a local copy of the model, so they start instantly. There is one copy per profile, host, organization, identity and project, in your user cache directory, readable only by you. A copy less than 30 seconds old is used without calling the API; an older one is refreshed, and when the API takes more than 1.5 seconds the command answers from the copy and says so on stderr. Commands that change the model, such as dsl push or approving discoveries, drop the copy.
Skip the cache for one command with --no-cache, or everywhere with ARCHYL_NO_CACHE=1. archyl login and archyl logout clear the profile's copies; archyl cache clear does it by hand.
Updates
When a newer release is out, the CLI says so once a command has finished. The check runs in the background at most once a day, never in CI or scripts; set ARCHYL_NO_UPDATE_NOTIFIER to turn it off.
archyl upgrade updates the CLI the way you installed it: brew upgrade for Homebrew, the go install command for a build from source, and otherwise in place: it downloads the release archive for your platform, checks it against the release's checksums.txt (and its cosign signature when cosign is on your PATH), and swaps it in for the running binary. --check only reports whether a newer release is out.
archyl upgrade
archyl upgrade --check
Global flags
| Flag | Purpose |
|---|---|
--json |
Machine-readable output. Every command that prints a result supports it |
-p, --project |
Project ID, overriding .archyl.json |
--profile |
Profile to use |
--no-cache |
Fetch the model from the API instead of the local cache |
Status messages and spinners go to stderr, results to stdout, so pipes only ever see the result:
archyl where --json . | jq '.files[].elements[0].name'
archyl impact --json | jq '.impact.notify'
CI and scripts
No login needed: create an API key in Profile → API Keys and set it in the environment.
export ARCHYL_API_KEY=arch_…
export ARCHYL_PROJECT_ID=… # or commit .archyl.json
archyl impact --json | jq '.impact.notify'
archyl dsl diff --exit-code # fails when archyl.yaml and the model differ
To store an API key as a credential instead, pipe it to archyl login --with-token.
| Variable | Purpose |
|---|---|
ARCHYL_API_KEY |
API key; skips stored credentials |
ARCHYL_HOST |
API URL for self-hosted Archyl (default https://api.archyl.com); ARCHYL_API_URL is also read |
ARCHYL_PROJECT_ID |
Project, overriding .archyl.json |
ARCHYL_ORG_ID |
Organization |
ARCHYL_PROFILE |
Profile to use, like --profile |
ARCHYL_GUARD_BLOCK |
critical (default), high or off |
ARCHYL_SESSION_ID |
Work session the Guard and session finish attach to (set by wrap) |
ARCHYL_FIX_TASK_FILE |
File holding the task, for a command run with archyl fix -- <command> (set by fix) |
ARCHYL_CONFIG_DIR |
Configuration directory |
ARCHYL_NO_KEYRING |
Store credentials in a file readable only by you (mode 0600) instead of the OS keychain |
ARCHYL_AGENT |
Name recorded on memories and sessions, when the CLI cannot tell which agent runs it |
GITHUB_TOKEN, GITLAB_TOKEN |
Token review --comment posts with |
ARCHYL_APP_URL |
Web app URL, when it is not the API host with api. replaced by app. |
ARCHYL_THEME |
dark or light, to skip asking the terminal for its background |
ARCHYL_IMAGES |
0 to draw diagrams as text, even in a terminal that shows images |
ARCHYL_CACHE_DIR |
Cache directory (model cache, prompt state, update check) |
ARCHYL_NO_CACHE |
1 to never use the local model cache, like --no-cache |
ARCHYL_NO_UPDATE_NOTIFIER |
Never mention new releases |
NO_COLOR |
Plain output |
Shell completion
archyl completion install writes the completion script where your shell loads it from: a directory of zsh's fpath you own (or ~/.zfunc), ~/.config/fish/completions or ~/.local/share/bash-completion/completions. Run it again to update the script. It changes your shell's startup file only when it has to (zsh without a fpath directory of yours, PowerShell) and you agree. archyl setup offers it too.
archyl completion install
archyl completion install --shell fish
To write the script yourself:
archyl completion zsh > "${fpath[1]}/_archyl"
archyl completion bash > /etc/bash_completion.d/archyl
archyl completion fish > ~/.config/fish/completions/archyl.fish