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:

  1. It creates the project, named after the repository (or --name), in the team you choose (--team, by name, slug or ID).
  2. It connects the repository from its git remote. For a self-hosted remote, give the provider with --provider: github_enterprise, gitlab_private or gitea.
  3. It runs an AI discovery on --branch (default: the remote's default branch) and shows its progress live.
  4. It opens the review of what the discovery found, then draws the result as a diagram.
  5. 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. /help lists everything.
  • @file attaches 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. #element points the question at an element. Both complete as you type.
  • Enter sends; Shift+Enter (or Alt+Enter, Ctrl+J) starts a new line, and pasted text keeps its line breaks.
  • ↑ ↓ browse your history, Tab completes, Esc stops an answer, Ctrl-D leaves.

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:

  1. 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.
  2. Claude Code receives the briefing as an appended system prompt. Every agent finds ARCHYL_SESSION_ID and ARCHYL_BRIEFING_FILE in its environment.
  3. 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.
  4. When the agent exits, wrap reports 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:

  1. It runs the conformance check on the branch, like archyl check, and lets you pick the violations to fix.
  2. 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.
  3. 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
  • pull exports 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.
  • diff is 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-code exits 1 when there is any difference.
  • push creates 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; --yes skips 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