API reference for all 7 Ix tools. Each tool calls the ix CLI and returns a formatted markdown string.
- Input: structured JSON parameters validated by OpenCode's parameter schema
- Output: formatted markdown string — never raw JSON, never structured objects
- Fallback: if
ixis unavailable, return a helpful error with recovery steps rather than throwing - Ix error records: since Ix v0.12.0 a read that cannot answer prints an error record on stdout and exits 1 —
{"error":"<code>","message":"…"}in JSON,error code=<code> message="…"in llm. Tools recognise it withruntime/ix-error.tsand returnIx returned an errorwith the code, the message and Ix's own fix, never a "nothing found" or "clean" result. Forworkspace_not_mapped, or agraph.statusofempty/degraded, the text says the project is not mapped and to runix mapfrom the project root (orix-ingestwithrefresh: true). This is distinct from rule 3: there Ix said nothing (not installed, timed out, no output) and the tool reportsix unavailable. - Depth scaling: heavier analysis phases run only when lighter phases indicate they're needed
- Directory: all
ixCLI calls run intoolCwd(context)(runtime/paths.ts):context.directory, the directory the session was opened in. OpenCode'sworktreeis/for a project outside git, so it is only a fallback whendirectoryis missing, and never when it is a filesystem root. - Fields: tools read the fields
ix --format jsonactually emits;tests/success-fixtures.test.tsdrives every tool through real CLI output (tests/fixtures/ix-v0.12.0/success/).
The string-only output constraint comes from the OpenCode runtime. Returning objects from tools has caused runtime issues in practice.
Purpose: Look up a symbol, class, file, or subsystem in the Ix graph. Returns role, connections, and importance without reading source code.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
symbol |
string | yes | Symbol name, file path, or subsystem to look up |
kind |
enum | no | Narrow to: function, class, file, module |
path |
string | no | Narrow results to a specific directory path |
Behavior:
- Runs
ix locate <symbol>— resolves the entity - Runs
ix explain <entity>— gets role, importance, caller/callee counts - Returns formatted summary
If ix locate returns multiple matches, returns the first result plus a note to narrow with --kind or --path.
Example output:
## ix-query: UserService
**Name:** `UserService`
**Kind:** class
**File:** src/services/user.ts
**Subsystem:** auth
**Role:** orchestrator
**Importance:** high
**Callers:** 14
**Callees:** 7
Manages user lifecycle — creation, authentication state, and session binding. Central to the auth subsystem.
Fallback (ix unavailable):
## ix-query: UserService
**ix unavailable.** The Ix graph service is not running or not installed.
command -v ix # check installation
ix status # check connection
ix map # build graph if needed
Error: <error message>
Purpose: Get the neighborhood of a symbol: who calls it, what it calls, and what depends on it. Purely graph-based.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
symbol |
string | yes | — | Symbol, class, or file to get neighbors for |
direction |
enum | no | all |
callers, callees, depends, imported-by, all |
limit |
number | no | 15 |
Max results per direction (capped at 30) |
depth |
number | no | 2 |
Traversal depth for depends (max 3) |
Behavior:
- Runs the appropriate
ix callers,ix callees,ix depends, orix imported-bycommands direction: "all"runs callers + callees in parallel- Results grouped by direction with counts
Example output:
## ix-neighbors: AuthController
**Callers** (3 total, showing 3):
- `UserRouter` (class) [api] — src/api/user_router.ts
- `SessionRouter` (class) [api] — src/api/session_router.ts
- `AdminRouter` (class) [api] — src/api/admin_router.ts
**Callees** (8 total, showing 8):
- `UserService` (class) [auth] — src/services/user.ts
- `SessionManager` (class) [auth] — src/services/session.ts
- `TokenValidator` (function) [auth] — src/auth/tokens.ts
...
Purpose: Analyze the blast radius and change risk for a symbol or file. Depth scales with detected risk level.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
target |
string | yes | Symbol name or file path to assess |
Behavior:
- Runs
ix impact <target> --format json— readsriskLevel,riskSummary,atRiskBehavior,propagationBuckets[].region, and the counts undersummary:callers/calleesfor a function,directImporters/directDependents/memberLevelCallers/membersfor a file or other container. "Total reaching it" is their sum. - Low risk + < 3 reaching it: stops here, returns safe-to-proceed verdict
- Medium/high/critical: for a function, also runs
ix callers <target> --limit 20(results[]) for key callers; for a file, lists Ix'stopImpactedMembers - Returns risk report with verdict and recommended action
Risk levels: low → SAFE TO PROCEED, medium → REVIEW CALLERS FIRST, high/critical → NEEDS CHANGE PLAN. A withheld riskLevel: "unknown" (hollow or empty graph) → CANNOT ASSESS, with Ix's graph verdict and fix.
Example output:
## Impact: runtime/cli.ts
**Risk level:** HIGH
**Verdict:** NEEDS CHANGE PLAN
**Summary:** High risk — widely shared dependency affecting the tools layer and impact analysis layer.
**Blast radius:**
- Direct importers: 18
- Direct dependents: 0
- Callers of its members: 33
- Members: 4
- Total reaching it: 51
- Subsystems affected: Runtime, Explain, Plugins, Impact
**Key callers:**
- `safeRun` (12 callers) — runtime/cli.ts
- `runIx` (11 callers) — runtime/cli.ts
- `failureDetail` (10 callers) — runtime/cli.ts
**At-risk behaviors:**
- Multiple callers across different subsystems
- Cross-module behavior consistency
**Recommended action:**
- Run `/ix-plan` before editing. This change needs a sequenced plan.
Purpose: Get the architectural map of the codebase: all subsystems, cohesion/coupling scores, and codebase stats. Use for orientation before deeper exploration.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
scope |
string | no | — | Scope to a specific subsystem name or path prefix |
include_stats |
boolean | no | true |
Include codebase stats (file count, nodes, edges) |
Behavior:
- Runs
ix subsystems,ix subsystems --list, andix statsin parallel - Builds a subsystem table from
regions[](label,label_kind,level,files,cohesion,coupling,confidence); withscope, renders thetargetregion and itschildreninstead - Lists
scores[]fromix subsystems --listas subsystem health - Takes the file count from
stats.nodes.byKind(kindfile) and totals fromnodes.total/edges.total - Flags multi-file subsystems with low cohesion (< 0.4) with ⚠. Ix's
couplingis an edge-weight count, not a 0–1 ratio, so it is shown but not judged
Example output:
## ix-map
**Codebase:** 55 files · 870 nodes · 1745 edges
**Subsystems** (11, 38 files):
| Subsystem | Kind | Level | Files | Cohesion | Coupling | Confidence |
|-----------|------|-------|-------|----------|----------|------------|
| Explain | module | 1 | 7 | 0.45 | 28.98 | 0.38 |
| Impact | module | 1 | 5 | 0.67 | 33.74 | 0.34 |
| Runtime | module | 1 | 8 | 0.40 | 29.16 | 0.40 |
| Tools ⚠ | system | 5 | 24 | 0.31 | 0 | 0.78 |
**Subsystem health:** Tools (0.63), Agents (0.59), Runtime (0.52), Explain (0.51), Impact (0.50)
Purpose: Check the Ix graph ingestion status. Can optionally trigger a graph rebuild.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
refresh |
boolean | no | false |
If true, trigger ix map to rebuild the graph |
silent |
boolean | no | true |
If refreshing: use ix map --silent |
Behavior (status check):
- Runs
ix status --format jsonif available - Falls back to probing
ix subsystems --listifix statusis unavailable - Reads
backend,graphCompleted,mapCompleted,currentRev,lastIngestAt,staleFiles,sampleChangedFiles;graphCompleted: falseis reported as not mapped - The probe reads
scores[].namefromix subsystems --list
Behavior (refresh):
- Runs
ix map(orix map --silent) - Returns confirmation when complete
Example output (status):
## ix-ingest: status
**Backend:** ok
**Graph:** ingested (rev 1)
**Last ingest:** 2026-10-02T01:14:41.855Z
**Freshness:** current
Example output (refresh):
## ix-ingest: graph refresh
**Status:** Graph refresh complete.
The Ix graph has been rebuilt. Graph data is now current.
Example output (ix unavailable):
## ix-ingest: status
**ix CLI not found.** Install Ix to enable graph-aware features.
command -v ix # check if installed
ix docker start # start the local backend
ix map # build initial graph
Purpose: Get change history, recorded decisions, and known bugs for a symbol or workspace. Requires Ix Pro. Returns empty results gracefully if Pro is unavailable.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
topic |
string | no | — | Symbol or topic to filter history/decisions to |
include |
array | no | ["briefing"] |
What to fetch: decisions, bugs, changes, briefing |
Behavior:
- Runs
ix briefing --format jsonto check Pro availability - If Pro is unavailable, returns a graceful message explaining what requires Pro
- If Pro is available, fetches the requested data sections
- With
topic, runsix decisions --topic <topic>for filtered decisions
Pro features:
decisions— recorded architectural decisionsbugs— open bug reportschanges— recent code changesbriefing— all of the above plus active goals and plans
Example output (Pro available):
## ix-history: AuthService
**Revision:** rev-4821
**Recent decisions** (2):
- Move session storage to Redis — 2026-03-15
Motivated by horizontal scaling requirements; sessions now must be stateless.
- Deprecate legacy token format — 2026-02-28
New tokens use JWT; legacy tokens still accepted until v3.0.
**Open bugs** (1):
- Session expires early on mobile [high] — affects `SessionManager`
Example output (Pro unavailable):
## ix-history
**Ix Pro not available.** History, decisions, and bug tracking require Ix Pro.
Graph-based features (ix-query, ix-neighbors, ix-impact, ix-map) work without Pro.
Purpose: Get a condensed architectural context summary for a symbol, subsystem, or file. Use to inject graph context before making changes — not the same as the /ix-docs skill (which writes full documentation).
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
target |
string | yes | — | Symbol name, file path, or subsystem to summarize |
depth |
enum | no | standard |
brief, standard, full |
Depth behavior:
| Depth | What runs |
|---|---|
brief |
ix locate + ix overview only |
standard |
above + ix stats, and ix explain for the first 5 of overview's keyItems |
full |
above + ix impact for change risk context |
Example output (standard):
## Context: runtime/cli.ts
_55 files · 870 nodes_
**Kind:** file
**Path:** runtime/cli.ts
**Subsystem:** Tools › Impact
**Contains:** 1 interface, 3 functions
**Key Components:**
- `safeRun` (12 callers) — shared-utility
- `runIx` (11 callers) — shared-utility
- `failureDetail` (10 callers) — shared-utility
Purpose: Text/pattern search across the indexed codebase. Use when you have a keyword or pattern rather than an exact symbol name.
Parameters: pattern (required), limit (default 20, max 100), path (optional), language (optional)
CLI: ix text <pattern> --limit <n> [--path P] [--language L] --format json
Purpose: Full symbol explanation — role, importance level, caller/callee counts, top dependents, and a plain-English description.
Parameters: symbol (required)
CLI: ix explain <symbol> --format json
Purpose: Rank symbols by a graph metric to surface hotspots and high-centrality components.
Parameters: by (default dependents; callers, importers, members), kind (default class), top (default 10, max 50), path (optional)
CLI: ix rank --by <by> --kind <kind> --top <n> [--path P] --format json
Purpose: Graph-wide node/edge counts, file count, and health status. Verify the graph is indexed before running expensive queries.
Parameters: none
CLI: ix stats --format json
Purpose: Detailed subsystem listing with file counts, hierarchy levels, confidence signals, and interface counts.
Parameters: none
CLI: ix subsystems --format json
Purpose: Enumerate files or symbols within a directory path scope from the graph.
Parameters: path (required), kind (default file; class, function, interface, module)
CLI: ix inventory --kind <kind> --path <path> --format json
Purpose: Trace full execution paths through a symbol — upstream callers and downstream callees. Use for complete call chains, not just immediate neighbors.
Parameters: symbol (required), to (optional target for path tracing)
CLI: ix trace <symbol> [--to <target>] --format json
Purpose: Pre-edit policy verdict (ALLOW / REVIEW / BLOCK) with required actions and blast radius evidence.
Parameters: touched_paths (required array), intent (default edit), risk_tolerance (default medium)
CLI: ix impact <path> --format json per touched file (first 5) — synthesizes a conservative verdict from riskLevel and the dependent counts under summary (directImporters + directDependents + memberLevelCallers for a file, callers for a function: the same total Ix's risk inference uses). Subsystems come from propagationBuckets[].region.
Fails closed. ALLOW is only given when every touched path has a parsed impact record with a real risk level and dependent counts.
| Situation | Verdict |
|---|---|
any path riskLevel: critical, or total dependents ≥ 20 (×0.5 / ×2 for risk_tolerance low / high) |
BLOCK |
ix not installed, timed out, or exited with nothing on stdout |
REVIEW |
an Ix error record (workspace_not_mapped, unresolved_target, ambiguous_target, …) |
REVIEW |
output that does not parse, or JSON without riskLevel / dependent counts |
REVIEW |
riskLevel: unknown or a graph block whose status is not ok (Ix withholds risk on a hollow graph) |
REVIEW |
| more than 5 paths (the rest are not checked), or no paths | REVIEW |
any path riskLevel: high or medium, or total dependents ≥ 5 (scaled as above) |
REVIEW |
every path assessed, all low, total dependents below the REVIEW threshold |
ALLOW |
BLOCK outranks the REVIEW rows: a critical path is BLOCK even if another path could not be assessed. A REVIEW for a path Ix could not assess lists that path, the reason, and Ix's own fix.
Purpose: Check CLI availability and graph index state.
Parameters: none
CLI: ix status --format json (with ix --version fallback)
Purpose: Report the architecture smells (orphan files, god modules, weak components) for the workspace's graph.
Parameters: limit (default 50, max 200); detect (default false) re-runs detection instead of reading stored claims. ix smells has no path filter; it always covers the whole workspace.
CLI:
ix smells --list(llm, else--format json:{count, smells:[{smell, entity_id, confidence}]}) reads the claims a previous detection run stored.- When none are stored and the graph is confirmed mapped, or when
detectis true, the tool runsix smells(llm, else--format json:{rev, count, candidates:[{file, smell, confidence, signals}]}). Detection stores smell claims for this workspace only; the output says that it ran.
Zero claims is not "clean". Before running detection the tool checks graph health (ix status → graphCompleted, ix stats → nodes.total). An unmapped graph, or one Ix cannot confirm is mapped, gets that answer and no detection run. "No smells detected" is reported only after a detection run on a mapped graph finds none.
To add a tool to the plugin:
-
Create
tools/<name>.tsfollowing this template:import { runIx } from "../runtime/cli.ts"; import { toolCwd } from "../runtime/paths.ts"; export const name = "ix-<name>"; export const description = "..."; export const parameters = { type: "object", properties: { ... }, required: [...] } as const; type Params = { ... }; type Context = { directory: string; worktree?: string }; export async function execute(params: Params, context: Context): Promise<string> { const dir = toolCwd(context); // call ix CLI, format output as markdown string // always return a string — never throw on ix errors }
-
Import and register in
plugins/ix-plugin.ts:import * as ixNewTool from "../tools/ix-new-tool"; // Add to plugin.tools array
-
Follow the contract:
- Always return a string
- Handle
ixunavailability gracefully - Use
toolCwd(context)as the working directory (never a barecontext.worktree, which is/outside git) - Add a test that drives the tool through real
ixoutput (tests/success-fixtures.test.ts) - Format output as structured markdown (headers, bullets, tables)
- Include the tool name and target in the first heading:
## ix-<name>: <target>