npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mertyalti/agentia-graph-cli

v0.1.3

Published

oclif plugin that exposes agentia graph commands. Depends on @mertyalti/agentia-graph. No library CLI.

Readme

@mertyalti/agentia-graph-cli

oclif plugin that adds graph commands to the agentia host. It extracts a Salesforce metadata relationship graph from a working tree, writes reports, and inspects nodes and paths. It depends on @mertyalti/agentia-graph and does not put a CLI inside that library.

oclif Version Downloads/week

Independent personal project by mert yaltı. Not developed, endorsed, supported or warranted by Copado. Copado and Agentia are trademarks of Copado.

Usage

$ npm install -g @mertyalti/agentia-graph-cli
$ agentia COMMAND
running command...
$ agentia (--version)
@mertyalti/agentia-graph-cli/0.1.2 darwin-arm64 node-v25.9.0
$ agentia --help [COMMAND]
USAGE
  $ agentia COMMAND
...

Requires Node.js 18 or newer and Agentia CLI (@copado/agentia-cli / Agentia Headless) >= 1.0.0. This package has no npm bin; the host command is agentia. Proprietary software: see LICENSE.md.

Install

Install the plugin into a host that already provides agentia:

$ agentia plugins install @mertyalti/agentia-graph-cli
$ agentia graph --help

Or install the package from the public registry, then install the plugin:

$ npm install @mertyalti/[email protected]
$ agentia plugins install @mertyalti/agentia-graph-cli

This plugin depends on @mertyalti/[email protected] from npm. The @mertyalti scope resolves to the public npm registry by default.

Sibling checkout (local development)

In a checkout next to agentia-graph:

$ npm ci
$ npm run build
$ agentia plugins link .
$ agentia graph --help

npm run build compiles this plugin and copies the HTML page into dist/lib; run npm run build:graph first if ../agentia-graph is not built yet. Packing never builds: npm run build compiles this plugin only, and prepack is a guard that fails fast if dist/ or oclif.manifest.json is missing or stale. Build the sibling ../agentia-graph explicitly with npm run build:graph when you need it (the typecheck step and check still do). To pack, run npm run pack:ci: npm run build, then npm run manifest (oclif manifest through scripts/oclif.mjs, which sets OCLIF_SKIP_NEW_VERSION_CHECK=true for every oclif call, including docs:readme, and sends oclif output to stderr), then npm pack --ignore-scripts. Add -- --json for clean JSON on stdout, or -- --dry-run to list files. Run it from a clean clone or a gate pair, never from a primary or a shared worktree. Never run oclif (or these scripts) with DEBUG=* or DEBUG=update-check in CI: the oclif update check's debug output prints the npm auth header. npm run build (so npm test, check and lint too) first runs scripts/ensure-graph.mjs as prebuild, which runs build:graph only when ../agentia-graph/dist is missing; pack:ci builds with --ignore-scripts, so packing never builds the sibling (on a clone whose graph is not built, pack:ci fails instead). Use npm run --silent pack:ci -- --json for JSON on stdout: without --silent, npm prints its > script banners there. pack:ci leaves oclif.manifest.json in the working tree on purpose (it is gitignored, and a later plain npm pack reuses it); the prepack guard rejects it if it is missing, malformed, for another version, or its command IDs differ from dist/commands. For day-to-day linking you can temporarily use "@mertyalti/agentia-graph": "file:../agentia-graph" instead of the published version.

Ship bar

| Script | What it runs | |---|---| | npm run check | build → format:check → lint → typecheck → test:unit → test:contract → test:e2e → verify:core. Builds ../agentia-graph and the plugin once, up front. scripts/check-suites.mjs runs unit/contract/e2e without their pre-build hooks, with AGENTIA_GOLDEN_REPO removed (the fixture UCs UC-03/04/05 and UC-11 run, golden-repo rows stay pending), and with HOME, TMPDIR and XDG_* inside a temp work dir it removes afterwards; it fails if a *.test.* file is outside test/unit, test/contract and test/e2e. golden-path and mcp-smoke run once (in test:e2e / test:contract; test:usecases is their subset). For a gate, run from a nested pair (<gate>/agentia-graph + <gate>/agentia-graph-cli) so a shared ../agentia-graph dist is never rebuilt under another run. | | npm test | every suite under test/ (test:unit ∪ test:contract ∪ test:e2e) | | npm run test:unit / test:contract / test:e2e | mocha over test/unit, test/contract, test/e2e (contract, e2e, and usecases build first via their pre hooks) | | npm run test:usecases | golden-path use cases on the sf-repo fixture: UC-03/04/05 (test/e2e/golden-path.test.ts) and UC-11 (test/contract/mcp-smoke.test.ts). Golden-repo rows run only with AGENTIA_GOLDEN_REPO=<path to a private golden repository checkout> (45 min golden timeouts). | | npm run verify:core | links the built plugin into a pristine Agentia Headless export (git archive of ../cli at origin/main into a temp dir; override with --core/--ref or AGENTIA_HEADLESS_REPO) and runs the graph workflow through the real agentia binary, with HOME/TMPDIR/XDG_* in the temp dir. Never checks out, installs or builds in the checkout; never installs from the registry unless --allow-install. The last line is Core compatibility: OK (zero core modifications required; node_modules drift: none), or the missing/mismatched counts (node_modules drift: 71 missing, 22 version mismatches; NOTE above) when the checkout's tree differs from the lockfile at the ref. |

Without linking, the local oclif entry (not an npm bin) is:

$ node bin/run.js graph --help

Working-tree graph vs documentation graph

agentia graph generate writes <project root>/.agentia/agentia-graph/graphs/graph.json (the project root is the git top level of --dir; --out overrides) and does not commit. The first write under .agentia/ creates .agentia/.gitignore ignoring only /agentia-graph/ and /.gitignore, so the outputs stay out of git and the tree stays clean; an existing .agentia/.gitignore and your own .gitignore are never edited. built_at_commit is git rev-parse HEAD. A folder with no HEAD fails; the command does not invent a hash.

agentia docs graph, from @mertyalti/agentia-docs, is a different command: it rebuilds a graph from the base revision and can commit that file onto doc/<source revision> inside the repository you are documenting.

Concrete commands:

$ agentia graph generate
$ agentia graph report --format both
$ agentia graph open

That path never commits. For a graph committed on the documentation branch instead:

$ agentia docs graph
$ agentia docs draft

Both plugins call @mertyalti/agentia-graph. Choose graph generate for local inspection; choose docs graph when the documentation workflow should own the file on doc/<source revision>.

Quickstart

From a Salesforce metadata working tree with at least one commit:

$ agentia graph generate
Graph generated (not committed)
  Nodes         N
  Edges         N
  Unresolved    N
  Time          N.NN s
Wrote
  /path/to/repo/.agentia/agentia-graph/graphs/graph.json
built_at_commit
  <40 hex characters>
$ agentia graph report --format both
$ agentia graph open

--json is accepted on every command except open.

Typical inspection:

$ agentia graph query Account
$ agentia graph path Account BillingService
$ agentia graph report --json

Report contents

agentia graph report writes Markdown (for agents; default --format markup), HTML (for architects and developers; --format html), or both (--format both). --out is the Markdown path; the HTML file sits beside it (GRAPH_REPORT.md → GRAPH_REPORT.html).

The report includes headline counts, hubs, unresolved tokens grouped by rule, and (when present) communities. When nodes have no community ids, the same deterministic undirected clustering used by graph open assigns them for the report; existing ids are kept. This is not Leiden.

Additional insight sections (Markdown and HTML):

  • Blast radius — hottest inbound reference targets, with a test-vs-production caller name heuristic (defines edges are not counted as inbound references)
  • Cross-type coupling — objects linked across metadata types / namespace boundaries
  • Permission concentration — share of reference edges that start from a Profile or PermissionSet (access inventory, not design coupling)
  • Orphans and single points — orphans plus hubs ranked by distinct neighbor metadata types
  • Unresolved review list — platform-looking tokens vs missing metadata
  • Freshness — built commit, graph source, and known extraction skips

Other HTML sections include the pipeline object model, reference edges by source/target type, and components by metadata type.

Files written

| File | Command | Committed by this plugin | | --- | --- | --- | | .agentia/agentia-graph/graphs/graph.json (or --out) | graph generate | No (ignored by .agentia/.gitignore) | | .agentia/agentia-graph/reports/GRAPH_REPORT.md (or --out) | graph report | No (ignored by .agentia/.gitignore) | | GRAPH_REPORT.html beside the markdown | graph report --format html or --format both | No | | graph.html | graph open | No | | reference facts file (only with --facts-out FILE) | graph generate --facts --facts-out FILE | No | | field dictionary file (only with --out FILE) | graph reference dictionary --out FILE | No | | .git/hooks/post-commit, post-merge, post-checkout (post-rewrite with --hook) | graph setup hooks (opt-in) | No (git dir) | | .git/agentia-graph/hook.log, refresh-*.lock, refresh-*.pending (per worktree) | graph watch --once from hooks / graph watch | No (git dir) | | .{agents,cursor,claude}/skills/agentia-graph/**, .cursor/rules/agentia-graph.mdc, managed block in AGENTS.md / CLAUDE.md | graph setup skills (see Local MCP and skills) | No |

When refreshing an existing graph.json, agentia graph generate --update wires G7-LIB path deltas against the prior graph at --out. v1 always full-rebuilds over the final path set so the digest matches a cold extract over the same paths and bodies — it is not a per-file splice and is not faster-than-full until lib mode can be incremental. Real warm speedup remains the shared-cache hit on clean-tree generate. Runtime budgets: docs/perf-budgets.md.

The walk for generate skips .git, .idea, .sf, .sfdx, coverage, dist, node_modules, and tmp, and it skips symbolic links. When --out is inside that tree, that file is not read as source.

Some standard platform names stay unresolved. They are names with no matching component in the repository, not a failed parse. The graph file shape is the version-2 document from @mertyalti/agentia-graph. Extraction limitations are documented on that package.

Reference facts and the field dictionary

Reference facts are the declared properties of objects, fields, validation rules, record types and global value sets (types, labels, required/unique/external id, lengths, reference targets, picklist values and their record type restrictions). They are opt-in and never change graph.json:

  • agentia graph generate --facts collects them in the same extract pass. On a strictly clean tree (nothing in git status, untracked files included) the graph and its facts are cached together in the shared cache, keyed on HEAD^{tree}. On a dirty tree they stay in memory and nothing is cached. The command's own outputs inside the tree (--out, --facts-out, reference dictionary --out, and their .<pid>.tmp files) do not count as dirty when reading the cache, so a rerun that writes into the tree still gets a cache hit; a cache write still needs a strictly clean tree. Without --facts, generate behaves exactly as before.
  • --facts-out FILE (requires --facts) also writes the sealed facts to FILE. It is the only facts file the plugin writes; it is skipped by the extract walk and is never read as source.
  • agentia graph watch --facts [--facts-out FILE] and agentia graph setup hooks --facts [--facts-out FILE] pass the same options to every refresh (the hooks bake them in like --dir/--out; a hooks --facts-out must be inside the repository and is resolved per worktree). The sidecar is an own output: watch never reacts to it and it does not block the cache read. Without --facts, hooks and watch behave exactly as before (a hook written without --facts is byte-identical to an A7 hook).
  • agentia graph reference dictionary [--object Name ...] renders a field dictionary per object (Markdown, or --json; --object names ignore case, so account matches Account; an exact match wins, and a name matching several objects that differ only in case exits 1 with the candidates): field properties, readers and writers from graph edges with their evidence, validation rules and the fields their formulas use, record types and their picklist restrictions, and inbound lookups and master-detail relationships. Without --graph/--facts it reads the cached pair for HEAD; when the facts are not cached, or the tree is dirty, it extracts now (cached only on a clean tree) and prints one Note: line on stderr. With --graph FILE --facts FILE it reads exactly those files, which must pair (same built_at_commit and graph_digest).
  • graph generate --out / --facts-out, graph reference dictionary --out, and graph setup hooks / graph watch --out / --facts-out refuse a file git tracks (CONFIGURATION_INVALID) before anything is read or written. The path is resolved to its on-disk spelling first (fs.realpathSync.native of the deepest existing ancestor), so a case variant of a tracked file is refused on a case-insensitive filesystem. generate and reference dictionary exit 1, like their other configuration errors; setup hooks and watch exit 2, like their other refusals (nothing changed), with the same exit under --json. The shared-cache content key carries an #r1d3 suffix, so entries written before this guard (when a tracked --out was skipped by the walk) are never read; the first run per tree re-extracts.
  • Exit codes (the same with --json, where the error envelope carries the code): an object name that is not in the facts exits 2; files that do not pair, unreadable files, an --out that is a directory, or an --out that is a file tracked by git exit 1 (CONFIGURATION_INVALID); a facts file that holds a secret exits 1 (SECRET_DETECTED) and prints nothing. Error lines show control (ESC, newline), bidirectional and zero-width characters as escapes (\u{1B}, \n, \u{202E}). The dictionary JSON shape is documented in the @mertyalti/agentia-graph README; --json prints the lib renderer's bytes, with DEL and C1 controls, bidirectional, zero-width and separator characters as \uXXXX escapes.
  • Known gap: quick-action-field binds are not currently produced by the extractor, so fields used only in object-specific quick actions are missing from reader and writer counts (the counts may under-report). Every dictionary lists this first in its limitations (JSON limitations and the Markdown footer).

There is no MCP tool for reference facts yet.

Keeping graph.json fresh: opt-in hooks and watch

Nothing here is on by default. Pick one when you want graph.json to follow the tree without running generate by hand.

Watch while you edit (explicit start; Ctrl-C stops it):

$ agentia graph watch
$ agentia graph watch --debounce 3000 --out graph.json

Or install git hooks that refresh after commit, merge/pull, and checkout:

$ agentia graph setup hooks
$ agentia graph setup hooks --status
$ agentia graph setup hooks --uninstall
  • Both call agentia graph watch --once, which runs the G7 generate --update path. When the tree is clean apart from the graph outputs themselves (graph.json, GRAPH_REPORT.*, graph.html), it reads the shared cache first. The digest is the same as a manual generate --update or a cold generate on the same tree.
  • Cost: v1 --update is still a full extract over the final path set, and watch inherits that. It is not a per-file splice. The real warm speedup is a shared-cache hit on a clean tree. Adding graph.json to .gitignore is still recommended.
  • Hooks are shared by linked worktrees. Each hook refreshes the graph of the worktree that fired it (--dir/--out are stored relative to the top level, so they must be inside the repo).
  • post-checkout refreshes on branch checkouts only. Hooks skip while a rebase, git am, or cherry-pick sequence is running; add --hook post-rewrite to refresh once at the end of a rebase.
  • At most one refresh runs and one waits per worktree; extra triggers exit at once.
  • Hooks run in the background by default, detached from git's stdout/stderr: git exits right away, and callers reading its output ($(git commit), IDEs, agents) do not wait for the refresh. --sync waits, with no time limit. They log to .git/agentia-graph/hook.log (truncated past 1 MB). Set AGENTIA_GRAPH_HOOKS=0 to skip a refresh for one git command. --status shows each hook's command and out, and warns when the command is not on PATH. Install warns when --out is not gitignored.
  • --command is trusted: it is written verbatim into the hook files.
  • Install is idempotent. It refuses to touch an existing hook it did not write, unless you pass --chain: the original moves to <hook>.agentia-graph-orig and runs first. --uninstall removes only managed hooks and puts chained originals back. A core.hooksPath outside the repository git dir (husky, a global hooks folder) is refused.
  • Hooks and watch never commit or push.

Details and design choices: docs/hooks-and-watch.md.

Local MCP and skills

This plugin runs its own stdio MCP server (plugins cannot inject tools into the host Agentia MCP). Copado AI runs inside Cline, so setup mcp registers the server in Cline's MCP settings:

$ agentia graph setup mcp
$ agentia graph setup mcp --dry-run --json

That adds (or updates) one agentia-graph stdio entry in Cline's global settings file:

{
  "type": "stdio",
  "command": "agentia",
  "args": ["graph", "mcp", "start"],
  "env": { "AGENTIA_PROJECT_ROOT": "/absolute/path/to/your/repo" }
}
  • Where. Cline (4.0 and later, in VS Code, JetBrains, and the CLI) reads one file. Setup uses the same precedence as Cline: CLINE_MCP_SETTINGS_PATH (the file itself), then CLINE_DATA_DIR/settings/cline_mcp_settings.json, then CLINE_DIR/data/settings/cline_mcp_settings.json, then ~/.cline/data/settings/cline_mcp_settings.json. An empty or whitespace-only variable counts as unset. A value is never trimmed: one that is relative, contains a control character, or starts or ends with whitespace (Cline would trim it and read a different file) is refused with CONFIGURATION_INVALID (exit 2). These variables must be set in the shell that runs setup and in Cline's environment. Pre-4.0 Cline paths are never written.
  • Global, last setup wins. Cline has no per-project MCP file and does not expand ${workspaceFolder}, so the entry carries an absolute AGENTIA_PROJECT_ROOT: the exact git top-level of the current directory (the current directory outside git). Every Cline window uses the repository you ran setup in last. Text output says so, and --json reports global: true, lastSetupWins: true, previousRoot (the root our entry had before, or null), and rootChanged. Run setup again in the repository you switch to.
  • Only our entry changes. Other servers and keys are kept byte for byte: setup splices only the agentia-graph value into the existing text (same indentation, colon spacing, and line endings) and checks that the result parses to exactly the expected settings. Only when the file has duplicate mcpServers / agentia-graph keys, or that check fails, would the whole file have to be re-serialized with 2-space indentation (Cline's own format). That is refused by default (SETUP_MCP_REWRITE_REFUSED, exit 2, nothing written) because it can change other servers' entries; pass --allow-rewrite to accept it. In a rewrite duplicate keys collapse to the last one, number spelling can change (1.0 → 1, 1e3 → 1000, very large integers are rounded), and \u escapes become characters. --json reports layout (new-file, splice, reserialized, or none). On our own entry, your disabled, autoApprove, timeout, cwd, extra env keys, and other fields are kept; type, command, args, and env.AGENTIA_PROJECT_ROOT are set. Setup never prints other entries' contents (they can hold tokens), not even in errors or --json.
  • Refusals (exit 2, nothing written, always with a code). SETUP_MCP_NAME_CONFLICT: agentia-graph holds a server that does not run agentia graph mcp start. SETUP_MCP_INVALID_JSON: the file is not strict JSON in UTF-8 (comments, trailing commas, a BOM, invalid UTF-8) or mcpServers is not an object; the message names the file only. SETUP_MCP_CONCURRENT_EDIT: the file changed (size, mtime, or identity) between the read and the rename, or Cline's lock directory (<file>.lock, younger than 10 s) stays held for 10 s while setup waits to take it; rerun. Setup takes the same lock as Cline for the write, so the two never write at once. A held lock at preflight is not a refusal: setup waits, --dry-run reports lockHeld: true without waiting, and a run with nothing to change is unchanged without taking the lock. SETUP_PATH_ESCAPES_ROOT: a symlinked .cline, settings directory, or settings file leaves the base directory (your home, or the override), or the directory was swapped during the run. SETUP_PATH_IN_GIT_DIR, SETUP_DANGLING_SYMLINK, SETUP_NOT_A_FILE, SETUP_NOT_A_DIRECTORY, SETUP_NOT_WRITABLE, SETUP_ROOT_INSIDE_GIT_DIR, CONFIGURATION_INVALID, and SETUP_USAGE_INVALID (an invalid flag value). Setup writes one file with one rename, so it never ends in a partial write: exit 1 (SETUP_WRITE_FAILED) is not produced.
  • Backup. Before an existing file is replaced, setup copies it to <file>.bak next to it (the real file's directory for a symlinked file), mode 0600 whatever the umask, with a temp file and a rename. The backup is only one level deep: each run overwrites the previous .bak, so it always holds the file as it was right before the latest update. The path is printed (Backup: …) and returned as backupPath in --json (null for a new file or an unchanged entry; --dry-run names the path it would use and writes nothing). If the backup cannot be written, setup refuses with SETUP_MCP_BACKUP_FAILED (exit 2) and the settings file is not touched.
  • Safe write. Missing directories are created (mode 0700) only below the base directory; CLINE_DIR, CLINE_DATA_DIR, and the directory of CLINE_MCP_SETTINGS_PATH must already exist. A new file gets mode 0600; an existing file keeps its mode. A settings file that is a symlink inside the base directory is written through and stays a link. The new text goes to a temp file in the same directory and replaces the file with a rename after the re-checks; on any failure the temp file and the directories setup created are removed. --dry-run writes nothing and gives the same refusals.
  • Cursor. --target cursor (and the old --scope local|global) is deprecated: it writes nothing, exits 0, and prints manual instructions (--json: deprecated: true, written: []). Existing .cursor/mcp.json entries are left untouched and keep working.
  • After setup, restart the agentia-graph server in Cline (or reload the window).
  • Breaking (0.x). The Cline target writes the agentia-graph entry into Cline's global MCP settings file: CLINE_MCP_SETTINGS_PATH, else CLINE_DATA_DIR, else CLINE_DIR, else ~/.cline/data/settings/cline_mcp_settings.json.

Start the server: agentia graph mcp start (stdout is reserved for MCP framing; enableJsonFlag is false).

AGENTIA_PROJECT_ROOT is used exactly as given (never trimmed); empty or whitespace-only counts as unset and the current directory is used. A value that is not an absolute path to an existing directory, or that contains a newline or another control character, stops the server with CONFIGURATION_INVALID on stderr (exit 2). setup skills and setup hooks refuse a project root (git top-level, or the current directory outside git for setup skills) whose path contains a control character with the same code (exit 2, nothing written); the message shows the root with control characters escaped. Installed hooks resolve the top level exactly and skip the refresh (exit 1, message on stderr) when it contains a control character or belongs to a different repository. setup hooks --uninstall still works in such a repository, so old managed hooks can be removed.

Install the agent skill and the always-on GRAPH_REPORT rule (agents / cursor / claude targets):

$ agentia graph setup skills
$ agentia graph setup skills --target agents --target cursor --target claude
$ agentia graph setup skills --target cursor --dry-run
$ agentia graph setup skills --no-rules

Files written per target (paths are relative to the project root):

| Target | Skill (always) | Rule (default; skipped with --no-rules) | | --- | --- | --- | | agents (default) | .agents/skills/agentia-graph/** | managed block in AGENTS.md | | cursor | .cursor/skills/agentia-graph/** | .cursor/rules/agentia-graph.mdc (alwaysApply: true, whole file owned by the plugin) | | claude | .claude/skills/agentia-graph/** | managed block in CLAUDE.md |

The rule tells agents to read .agentia/agentia-graph/reports/GRAPH_REPORT.md in the repository root (git rev-parse --show-toplevel), or the agentia://graph/report MCP resource when the agentia-graph server is connected, before metadata impact, relationship, or dependency work. If the report is missing, its Freshness commit differs from HEAD, or the tree is dirty, they run agentia graph generate --update (or a full agentia graph generate) and then agentia graph report. They run both from the repository root, because graph.json and GRAPH_REPORT.md default to the current directory. From anywhere else, they pass --dir <root> --out <root>/graph.json to generate and --graph <root>/graph.json --out <root>/GRAPH_REPORT.md to report; report has no --dir flag. They do not commit GRAPH_REPORT.*.

  • Project root. Skills and rules are written at the git top-level (git rev-parse --show-toplevel, run from the current directory), so running from a subdirectory installs at the repository root. Outside a git work tree the current directory is used. Earlier versions always used the current directory. The resolved root is printed, and --json includes root and rootSource (git or cwd).
  • Managed blocks. In AGENTS.md / CLAUDE.md the rule lives between <!-- agentia-graph:managed:start --> and <!-- agentia-graph:managed:end --> (a marker counts only at the start of a line and outside fenced code blocks, ``` or ~~~; indented, mid-line, or fenced marker text is ordinary content and is kept byte for byte). The block is appended after a blank line when absent and replaced in place when present. Bytes outside the markers and the file's line endings (LF or CRLF) are kept. The Agentia Headless <!-- agentia:managed:start --> … <!-- agentia:managed:end --> block is never edited. Setup stops if there is more than one live block (SETUP_MARKER_AMBIGUOUS), or if the markers are unbalanced, out of order, nested in that host block, or the file ends inside an unclosed code fence (SETUP_MALFORMED_MARKERS).
  • Safety. Every target is checked before anything is written. An unmanaged SKILL.md or .cursor/rules/agentia-graph.mdc (no Agentia Graph marker) is refused unless you pass --force; a malformed managed block is always refused. If any check fails, nothing is written. Each file is written through a temp file and a rename in the same directory. Byte-identical files are left alone and reported as unchanged. If a later write fails, the error lists the files already written; the run is not a transaction. Writes that would resolve outside the repository (through a symlinked AGENTS.md, CLAUDE.md, rule file, skill file, or any parent directory such as .cursor or .agents) are always refused, even with --force. So are writes whose real path lands in the repository's git dir or git common dir (for example AGENTS.md -> .git/hooks/pre-commit, or a linked worktree's main .git). So are dangling symlinks, read-only targets that would change, and running from inside .git. Exit 2 means setup refused and wrote nothing. That covers every refusal, including a broken package (SETUP_PACKAGE_INVALID). Exit 1 means only a partial write: a write failed partway through the run (SETUP_WRITE_FAILED). With --json, the error envelope carries a stable code (for example SETUP_PATH_ESCAPES_ROOT or SETUP_PATH_IN_GIT_DIR), a problems list, and written (the files already written, for SETUP_WRITE_FAILED).
  • --dry-run reports each planned file and status and writes nothing.
  • Output. Text lists every file with its status (Created, Updated, Unchanged; Would create / Would update on a dry run). --json returns root, rootSource, dryRun, rules, files ({path, status, kind: skill|rule, target}), and written (the paths actually written by this run).

MCP tools (call lib helpers; they do not spawn agentia graph …): graph_generate, graph_report, graph_query, graph_path, graph_explain, graph_communities, graph_wiki, graph_surprises, graph_open. MCP resource: agentia://graph/report (the Markdown report). Prefer MCP when connected; otherwise agentia graph … --json. graph_open defaults openBrowser: false on MCP.

This is the working-tree graph plugin. Do not confuse it with agentia docs graph (documentation branch).

License

Copyright (c) mert yaltı. All rights reserved. See LICENSE.md. Permission is granted to install and use this software with Agentia Headless; redistribution, sublicensing, and modification require prior written permission.

Commands

agentia graph communities [ID]

List communities or show one community’s members

USAGE
  $ agentia graph communities [ID] [--json] [--graph <value>] [--algorithm louvain|louvain-refine] [--limit <value>]

ARGUMENTS
  [ID]  Community id to show members for

FLAGS
  --algorithm=<option>  [default: louvain] Clustering when community ids are missing: louvain (default) or
                        louvain-refine (Louvain + connectivity refine; not multilevel Leiden / not Graphify)
                        <options: louvain|louvain-refine>
  --graph=<value>       Graph file to read (default: <project root>/.agentia/agentia-graph/graphs/graph.json)
  --limit=<value>       Max communities to list (default all)

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  List communities or show one community’s members

  First-class communities surface. When nodes lack community ids, runs deterministic clustering.
  --algorithm louvain (default) is the existing Louvain-style partition.
  --algorithm louvain-refine runs that partition plus a connectivity refinement step (not multilevel Leiden; not
  Graphify).

EXAMPLES
  $ agentia graph communities

  $ agentia graph communities 0

  $ agentia graph communities --algorithm louvain-refine --json

agentia graph explain NAME

Explain one node and why its edges exist

USAGE
  $ agentia graph explain NAME [--json] [--graph <value>]

ARGUMENTS
  NAME  Metadata name

FLAGS
  --graph=<value>  Graph file to read (default: <project root>/.agentia/agentia-graph/graphs/graph.json)

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Explain one node and why its edges exist

  Resolves a metadata name and lists its incident edges with relation, rule, evidence, line, and confidence when present
  on the graph (text: grouped summary; --limit, --rule, --direction, --all). This is the graph explain surface (not change impact).

EXAMPLES
  $ agentia graph explain Account

agentia graph generate

Extract the working tree and write graph.json

USAGE
  $ agentia graph generate [--json] [--dir <value>] [--facts-out <value> --facts] [--out <value>] [--update]

FLAGS
  --dir=<value>        [default: .] Working tree to extract
  --facts              Also collect reference facts (object, field, validation rule, record type and global value set
                       properties) in the same pass. Opt-in; graph.json is unchanged. Cached with the graph only on a
                       strictly clean tree.
  --facts-out=<value>  Also write the reference facts to this file (the only sidecar; must differ from --out). Requires
                       --facts. Skipped by the extract walk.
  --out=<value>        Graph file to write (default: <project root>/.agentia/agentia-graph/graphs/graph.json;
                       .agentia/.gitignore is created with * on first write). Not committed. With --update, also the
                       prior graph to read when present.
  --update             Refresh via G7-LIB path deltas vs prior graph at --out. v1: digest-identical full extract over
                       final paths (not a per-file splice; not faster-than-full until mode=incremental).

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Extract the working tree and write graph.json

  Walks the working tree, calls @mertyalti/agentia-graph extractSalesforceMetadata with a file reader, and writes
  graph.json. Does not commit. built_at_commit is git HEAD. A folder with no HEAD fails instead of inventing a hash.
  With --update, refreshes via extractSalesforceMetadataIncremental using path deltas against a prior graph at --out (if
  present). v1 always performs a digest-identical full extract over the final path set — it does not claim per-file
  splice or faster-than-full until lib mode can be incremental. Shared-cache warm hits remain the non-update clean-tree
  path. With --facts, the same pass also collects reference facts (opt-in; graph.json is unchanged): cached beside the
  graph on a strictly clean tree, kept in memory on a dirty tree, and written to a file only with --facts-out.

EXAMPLES
  $ agentia graph generate

  $ agentia graph generate --json

  $ agentia graph generate --update

  $ agentia graph generate --update --out graph.json

  $ agentia graph generate --facts

  $ agentia graph generate --facts --facts-out reference-facts.json

agentia graph mcp start

Start the local Agentia Graph MCP server over stdio

USAGE
  $ agentia graph mcp start

DESCRIPTION
  Start the local Agentia Graph MCP server over stdio

EXAMPLES
  $ agentia graph mcp start

  $ agentia graph mcp start # long-running stdio MCP server for Cursor and other clients

agentia graph open

Write graph.html and open it

USAGE
  $ agentia graph open [--graph <value>] [--out <value>]

FLAGS
  --graph=<value>  Graph file to read (default: <project root>/.agentia/agentia-graph/graphs/graph.json)
  --out=<value>    [default: graph.html] HTML file to write and open

DESCRIPTION
  Write graph.html and open it

  Writes a vis-network 9.1.6 page (full height, search, node sidebar, legend that shows or hides a community) and opens
  it. Nodes without community ids are clustered on the undirected graph first. Graphs over 5000 nodes are drawn as one
  node per community, not the full edge list. Does not accept --json.

EXAMPLES
  $ agentia graph open

agentia graph path FROM TO

Shortest path between two metadata names

USAGE
  $ agentia graph path FROM TO [--json] [--graph <value>]

ARGUMENTS
  FROM  Metadata name
  TO    Metadata name

FLAGS
  --graph=<value>  Graph file to read (default: <project root>/.agentia/agentia-graph/graphs/graph.json)

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Shortest path between two metadata names

  Undirected shortest path. Two components connect only through the files that define or reference them.

EXAMPLES
  $ agentia graph path Account BillingService

agentia graph query NAME

Show one node and its neighbors

USAGE
  $ agentia graph query NAME [--json] [--graph <value>] [--depth <value>] [--dfs] [--relation <value>]

ARGUMENTS
  NAME  Metadata name

FLAGS
  --depth=<value>     Max edge hops from the seed (default 1)
  --dfs               Traverse depth-first instead of breadth-first
  --graph=<value>     Graph file to read (default: <project root>/.agentia/agentia-graph/graphs/graph.json)
  --relation=<value>  Keep only edges whose relation matches (case-insensitive)

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Show one node and its neighbors

  Resolves a metadata name (exact id, then component API name, then label, then file path). Default is a 1-hop BFS
  neighborhood. Use --depth for multi-hop traversal and --dfs for depth-first order. Optional --relation filters edges
  by relation name.

EXAMPLES
  $ agentia graph query Account

  $ agentia graph query Account --depth 2

  $ agentia graph query Account --dfs --depth 3 --relation references

agentia graph reference dictionary

Field dictionary per object from the graph and its reference facts

USAGE
  $ agentia graph reference dictionary [--json] [--dir <value>] [--facts <value> --graph <value>] [--object <value>...] [--out
    <value>]

FLAGS
  --dir=<value>        [default: .] Working tree to read (cache or extract) when --graph and --facts are not given
  --facts=<value>      Reference facts file to read (from graph generate --facts --facts-out). Requires --graph.
  --graph=<value>      graph.json to read. Requires --facts; the two must pair.
  --object=<value>...  Object API name to include (case-insensitive: account matches Account; an exact match wins).
                       Repeat for more. Default: every object.
  --out=<value>        Write the dictionary to this file instead of stdout (Markdown, or JSON with --json).

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Field dictionary per object from the graph and its reference facts

  Builds a field dictionary for each Salesforce object: field properties from the reference facts (type, label,
  required, unique, external id, length, precision, reference targets, picklist values, formula), who reads and writes
  each field (graph edges, with their evidence and line), validation rules and the fields their formulas use, record
  types and the picklist values they restrict, and inbound lookups and master-detail relationships.

  Without --graph and --facts, reads the graph and reference facts cached for HEAD on a strictly clean tree. When they
  are not cached, or the tree has uncommitted changes, it extracts them now (cached only on a strictly clean tree) and
  prints one note on stderr.

  With --graph and --facts, reads exactly those files (graph generate --facts --facts-out writes the facts file). They
  must pair: same built_at_commit and graph_digest; otherwise exits 1.

  Markdown by default; --json prints the dictionary JSON (shape in the @mertyalti/agentia-graph README). --object
  ignores case (account matches Account; an exact match wins); a name that matches several objects differing only in
  case exits 1 (CONFIGURATION_INVALID, the candidates listed). An object name that is not in the reference facts exits
  2. Does not commit.

EXAMPLES
  $ agentia graph reference dictionary --object Account

  $ agentia graph reference dictionary --object Account --object Contact --json

  $ agentia graph reference dictionary --out FIELD_DICTIONARY.md

  $ agentia graph reference dictionary --graph graph.json --facts reference-facts.json --object Account

agentia graph reference erd

Entity-relationship diagram of objects from the graph and its reference facts

USAGE
  $ agentia graph reference erd [--json] [--depth <value>] [--dir <value>] [--facts <value> --graph <value>] [--format
    md|mermaid|json|html] [--object <value>...] [--out <value>]

FLAGS
  --depth=<value>      Hops from the --object set (integer >= 0, default 2). Master-detail edges are followed past it.
  --dir=<value>        [default: .] Working tree to read (cache or extract) when --graph and --facts are not given
  --facts=<value>      Reference facts file to read (from graph generate --facts --facts-out). Requires --graph.
  --format=<option>    Output: md (Markdown with diagram, default), mermaid (erDiagram text), json (same as --json) or
                       html (self-contained offline page).
                       <options: md|mermaid|json|html>
  --graph=<value>      graph.json to read. Requires --facts; the two must pair.
  --object=<value>...  Object API name to start from (case-insensitive: order__c matches Order__c; an exact match wins).
                       Repeat for more. Default: whole-repo index.
  --out=<value>        Write the output to this file instead of stdout (must not be a git-tracked file).

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Entity-relationship diagram of objects from the graph and its reference facts

  Builds the entity-relationship model of Salesforce objects from relationship fields in the reference facts:
  master-detail (identifying) and lookup-style edges, with delete constraint, reparentable and evidence (file and line).
  Standard objects referenced but not in the repository are stub nodes. Polymorphic and unresolved targets are listed as
  limitations, never guessed.

  Without --object: a whole-repository index (one row per object: in-edges, out-edges, stub), no diagram. With --object
  (case-insensitive, exact match first; repeatable): the objects within --depth hops (default 2), following
  master-detail edges past it, capped at 50 objects, with a Mermaid erDiagram.

  Without --graph and --facts, reads the graph and reference facts cached for HEAD on a strictly clean tree. When they
  are not cached, or the tree has uncommitted changes, it extracts them now (cached only on a strictly clean tree) and
  prints one note on stderr.

  With --graph and --facts, reads exactly those files (graph generate --facts --facts-out writes the facts file). They
  must pair: same built_at_commit and graph_digest; otherwise exits 1.

  --format md (default) is Markdown with the diagram and tables; mermaid is the erDiagram text only; json (same bytes as
  --json) is the ERD JSON with a stable digest (shape in the @mertyalti/agentia-graph README); html is one
  self-contained offline HTML file that draws the diagram with an inlined, vendored Mermaid (MIT notice kept), a strict
  Content-Security-Policy with a per-file script nonce, and the object and relationship tables (the whole-repo index has
  tables only). A name that matches several objects differing only in case exits 1 (CONFIGURATION_INVALID, the
  candidates listed); an object name that is not in the graph exits 2. The JSON query echoes the declared names. Does
  not commit.

EXAMPLES
  $ agentia graph reference erd --object Order__c

  $ agentia graph reference erd --object Order__c --depth 1 --json

  $ agentia graph reference erd --object Order__c --format mermaid

  $ agentia graph reference erd --format json --out erd.json

  $ agentia graph reference erd --object Order__c --format html --out erd.html

agentia graph report

Write a graph report as markup, HTML, or both

USAGE
  $ agentia graph report [--json] [--graph <value>] [--out <value>] [--title <value>] [--facts <value>]
    [--relationships] [--format html|markup|both]

FLAGS
  --facts=<value>    Reference facts file for --relationships (from graph generate --facts --facts-out); must pair with
                     --graph. Without --relationships: CONFIGURATION_INVALID, exit 1.
  --format=<option>  [default: markup] markup writes only the markdown (default). html writes only the HTML report. both
                     writes the markdown and the HTML file beside it.
                     <options: html|markup|both>
  --graph=<value>    Graph file to read (default: <project root>/.agentia/agentia-graph/graphs/graph.json)
  --out=<value>      Markdown report path (default: <project root>/.agentia/agentia-graph/reports/GRAPH_REPORT.md). HTML
                     is written beside it, with .html instead of .md.
  --relationships    Add the Relationships section (entity-relationship index and diagrams) to the HTML report.
  --title=<value>    Report title. Defaults to the working directory name.

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Write a graph report as markup, HTML, or both

  Counts, hubs, unresolved buckets, and communities. When nodes have no community ids, the same deterministic undirected
  clustering as graph open assigns them. Existing ids are kept. This is not Leiden clustering.

  --format markup (the default) writes only the markdown report, for agents. --format html writes only the HTML report,
  for architects and developers. --format both writes both. --out is the markdown path. The HTML file sits beside it:
  GRAPH_REPORT.md becomes GRAPH_REPORT.html. Markup is not written unless the format is markup or both.

  --relationships adds a Relationships section to the HTML (after Cross-type coupling): the whole-repo
  entity-relationship index, the Mermaid erDiagram source of the top 5 objects by relationship edges (static text, no
  script), and the ERD limitations, from the reference facts in --facts (graph generate --facts --facts-out writes them;
  they must pair with --graph). Without --facts the section says that facts are not available. Without --relationships
  the HTML is unchanged.

EXAMPLES
  $ agentia graph report

  $ agentia graph report --format markup

  $ agentia graph report --format html

  $ agentia graph report --format both

  $ agentia graph report --json

agentia graph setup hooks

Opt in to git hooks that refresh graph.json after commit, merge, and checkout

USAGE
  $ agentia graph setup hooks [--json] [--chain | --uninstall | --status] [--command <value>] [--dir <value>]
    [--facts-out <value> --facts] [--hook post-commit|post-merge|post-checkout|post-rewrite...] [--out <value>] [--sync]

FLAGS
  --chain              Keep existing non-Agentia hooks: move each to <hook>.agentia-graph-orig and run it first
  --command=<value>    [default: agentia] Shell command prefix the hooks use to reach the host CLI (for example `npx
                       agentia`). Trusted: written verbatim into the hook files
  --dir=<value>        [default: .] Extract root for the hooks. Must be inside the repository; stored relative to the
                       top level and resolved per worktree
  --facts              Refresh with `graph watch --once --facts`: reference facts are collected and cached beside the
                       graph on a strictly clean tree. Off by default. Install only (ignored by --status and
                       --uninstall)
  --facts-out=<value>  Also write the reference facts to this file on each refresh. Must be inside the repository;
                       resolved per worktree like --out
  --hook=<option>...   Hooks to manage. Install default: post-commit, post-merge, post-checkout. Uninstall/status
                       default: all supported
                       <options: post-commit|post-merge|post-checkout|post-rewrite>
  --out=<value>        Graph file the hooks refresh (default: .agentia/agentia-graph/graphs/graph.json). Must be inside
                       the repository; stored relative to the top level and resolved per worktree
  --status             Show hook state without changing anything
  --sync               Run the refresh in the foreground: git waits for it, with no time limit. Default runs it in the
                       background, detached from git stdio
  --uninstall          Remove managed hooks and restore chained originals

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Opt in to git hooks that refresh graph.json after commit, merge, and checkout

  Writes managed post-commit, post-merge, and post-checkout hooks (post-rewrite with --hook) into this repository's
  hooks dir. Each hook runs `agentia graph watch --once` for the worktree that fired it (hooks are shared by linked
  worktrees; --dir/--out resolve against each worktree's top level). post-checkout refreshes on branch checkouts only,
  and hooks skip while a rebase, am, or cherry-pick sequence is running (post-rewrite covers the end of a rebase). The
  refresh uses the G7 `generate --update` path plus the shared cache on a clean tree, in the background by default.
  Nothing is installed unless you run this command. Rerunning is idempotent. An existing hook that Agentia Graph did not
  write is never overwritten: the install is refused unless you pass --chain, which moves it to
  <hook>.agentia-graph-orig and runs it first. --uninstall removes only the managed hooks and moves chained originals
  back. Refuses to install or uninstall in a core.hooksPath outside the repository git dir (--status still reports it).
  Background refreshes are fully detached from git's stdout/stderr, so callers reading git's output do not wait for
  them; --sync has no time limit. Never commits or pushes.

EXAMPLES
  $ agentia graph setup hooks

  $ agentia graph setup hooks --chain

  $ agentia graph setup hooks --hook post-commit --hook post-rewrite --sync

  $ agentia graph setup hooks --status --json

  $ agentia graph setup hooks --uninstall

agentia graph setup mcp

Register the Agentia Graph MCP server in Cline's global MCP settings (~/.cline/data/settings/cline_mcp_settings.json) with this project as AGENTIA_PROJECT_ROOT. Cline's config is global: the last setup wins. Only the agentia-graph entry is changed; other servers are kept byte for byte where possible. Before an existing file is replaced, it is copied to .bak (0600); the backup is only one level deep: each run overwrites the previous .bak. --target cursor is deprecated and writes nothing.

USAGE
  $ agentia graph setup mcp [--json] [--allow-rewrite] [--dry-run] [--scope local|global] [--target cline|cursor]

FLAGS
  --allow-rewrite    Allow a full rewrite of the settings file when our entry cannot be updated in place (duplicate
                     keys, or a layout setup cannot splice). A rewrite can change other servers' entries: integers above
                     2^53 lose precision, number spellings such as 1.50 become 1.5, and duplicate keys keep only the
                     last value. Without this flag that case is refused with SETUP_MCP_REWRITE_REFUSED and nothing is
                     written
  --dry-run          Report what would change, with the same refusals, without writing anything
  --scope=<option>   Deprecated (Cursor only): implies --target cursor, which writes nothing
                     <options: local|global>
  --target=<option>  cline (default): Cline global MCP settings. cursor: deprecated, writes nothing and prints manual
                     instructions
                     <options: cline|cursor>

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Register the Agentia Graph MCP server in Cline's global MCP settings (~/.cline/data/settings/cline_mcp_settings.json)
  with this project as AGENTIA_PROJECT_ROOT. Cline's config is global: the last setup wins. Only the agentia-graph entry
  is changed; other servers are kept byte for byte where possible. Before an existing file is replaced, it is copied to
  <file>.bak (0600); the backup is only one level deep: each run overwrites the previous .bak. --target cursor is
  deprecated and writes nothing.

EXAMPLES
  $ agentia graph setup mcp

  $ agentia graph setup mcp --dry-run --json

  CLINE_DIR=/opt/cline agentia graph setup mcp

agentia graph setup skills

Install the Agentia Graph agent skill and always-on GRAPH_REPORT rule into this project

USAGE
  $ agentia graph setup skills [--json] [--dry-run] [--force] [--rules] [--target agents|cursor|claude...]

FLAGS
  --dry-run             Report the planned files and statuses without writing anything
  --force               Replace skill files and the Cursor rule file when they are not managed by Agentia Graph
  --[no-]rules          Also write the always-on GRAPH_REPORT rule: .cursor/rules/agentia-graph.mdc (cursor), a managed
                        block in AGENTS.md (agents) or CLAUDE.md (claude)
  --target=<option>...  [default: agents] Skill root to install into
                        <options: agents|cursor|claude>

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Install the Agentia Graph agent skill and always-on GRAPH_REPORT rule into this project

EXAMPLES
  $ agentia graph setup skills

  $ agentia graph setup skills --target cursor --target claude

  $ agentia graph setup skills --target agents --target cursor --target claude --dry-run

  $ agentia graph setup skills --no-rules

agentia graph watch

Keep graph.json fresh while you edit (explicit start; opt-in)

USAGE
  $ agentia graph watch [--json] [--debounce <value>] [--dir <value>] [--facts-out <value> --facts] [--initial]
    [--once] [--out <value>]

FLAGS
  --debounce=<value>   [default: 1500] Quiet period in ms after the last change before refreshing
  --dir=<value>        [default: .] Working tree to watch and extract
  --facts              Also collect reference facts on each refresh (as `generate --facts`); cached beside the graph on
                       a strictly clean tree. Off by default
  --facts-out=<value>  Also write the reference facts to this file on each refresh. Never watched.
  --[no-]initial       Refresh once at start so graph.json matches the tree being watched
  --once               Run one refresh and exit (used by git hooks)
  --out=<value>        Graph file to refresh (default: <project root of
                       --dir>/.agentia/agentia-graph/graphs/graph.json). Not committed. Never watched.

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Keep graph.json fresh while you edit (explicit start; opt-in)

  Watches the working tree and, after a debounce, refreshes graph.json through the G7 `generate --update` path. On a
  clean tree the shared cache is read first (a hit is the stored cold extract for HEAD^{tree}); otherwise v1 `--update`
  runs a full extract over the final path set, so each refresh costs about as much as a cold extract. The digest always
  matches a manual `generate --update` / cold generate on the same tree. Ignores the output graph, .git*, and the
  generate skip dirs. Never commits or pushes. Stop with Ctrl-C. --once runs a single refresh and exits (this is what
  `graph setup hooks` hooks call).

EXAMPLES
  $ agentia graph watch

  $ agentia graph watch --debounce 3000 --out graph.json

  $ agentia graph watch --once --json

agentia graph wiki

Export a markdown wiki of communities and hubs

USAGE
  $ agentia graph wiki [--json] [--graph <value>] [--out <value>] [--algorithm louvain|louvain-refine] [--title
    <value>]

FLAGS
  --algorithm=<option>  [default: louvain] Clustering when community ids are missing. louvain is the default
                        deterministic partition; louvain-refine adds connectivity refinement. Not multilevel Leiden; not
                        Graphify.
                        <options: louvain|louvain-refine>
  --graph=<value>       Graph file to read (default: <project root>/.agentia/agentia-graph/graphs/graph.json)
  --out=<value>         [default: wiki] Directory to write wiki markdown into
  --title=<value>       Wiki index title. Defaults to the working directory name.

GLOBAL FLAGS
  --json  Format output as json.

DESCRIPTION
  Export a markdown wiki of communities and hubs

  Writes index.md, one article per community, and god-node articles under --out.
  Layout caps keep large graphs readable (max communities 200, members 25, cross-links 12, god nodes 30). Graphify is a
  shape reference only; this does not vendor Graphify.

EXAMPLES
  $ agentia graph wiki

  $ agentia graph wiki --out wiki --algorithm louvain