Skip to content
Arxo Arxo

CLI and Integration

CLI usage, integrations, advanced features, and troubleshooting. For an overview, see Circular Dependencies.

Arxo also detects cycles at the function/call level:

{
"scc": {
"function": {
"cycle_count": 507,
"call_mass": 172,
"cycle_cut_candidates": 4
}
}
}

Use case: Find circular function calls within a module.

SCC supports cycle analysis modes via metric config:

metrics:
- id: scc
config:
edge_mode: all # all | runtime_only | structural_only
emit_findings: true # emit FindingType::CyclicDependency
max_cycles_in_ui: 50 # cap cycle microscope payload

Enable git history to enrich cycle details with churn and hotspot metrics:

metrics:
- id: scc
config:
use_git_history: true # Loads git history (slower but more actionable)

What changes:

  • Each node in scc_details gets a churn value (total commits touching that file)
  • Each node gets a hotspot_score (churn × centrality) indicating refactoring priority
  • The UI’s “Cycle Microscope” shows a sortable table ranking nodes by hotspot score

Example output:

{
"scc_details": [
{
"scc_idx": 2,
"nodes": ["src/document/builders/join.js", "src/document/utilities/assert-doc.js"],
"node_table": [
{
"node_id": "src/document/builders/join.js",
"centrality": 0.15,
"churn": 47,
"hotspot_score": 7.05 // High - prioritize this for refactoring
},
{
"node_id": "src/document/utilities/assert-doc.js",
"centrality": 0.08,
"churn": 12,
"hotspot_score": 0.96
}
]
}
]
}

Strategy: Refactor nodes with the highest hotspot_score first (biggest impact on both structural and evolution metrics).

Terminal window
# Detect cycles
arxo analyze
# JSON output
arxo analyze --format json
# Show only SCC metric
arxo analyze --metric scc
Terminal window
# Enforce zero-cycle policy
arxo analyze --config arxo.yml
# Exit code 1 if policy fails
echo $?
Terminal window
# Get cycle-cut candidates
arxo analyze --format json | jq '.ui_schemas.scc.issues.categories.cycle_cut_candidates.critical'
# List all cycles
arxo analyze --format json | jq '.ui_schemas.scc.scc_details[] | select((.nodes | length) > 1)'
# Find largest cycle
arxo analyze --format json | jq '.ui_schemas.scc.scc_details | max_by(.nodes | length)'
.pre-commit-config.yaml
repos:
- repo: local
hooks:
- id: arxo-scc
name: Check for circular dependencies
entry: arxo analyze --metric scc --format json
language: system
pass_filenames: false
.github/workflows/architecture.yml
name: Architecture Checks
on: [push, pull_request]
jobs:
cycles:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: arxo-dev/setup-arxo@v1
- run: arxo analyze --metric scc

The Arxo IDE shows cycles inline:

  • Red squiggles on imports that create cycles
  • Quick fix: “Show cycle path”
  • CodeLens: “N modules in cycle”

”No cycles detected” but code has circular imports

Section titled “”No cycles detected” but code has circular imports”

Cause: Grouping level might be too coarse.

Solution: Adjust grouping in config:

data:
import_graph:
group_by: file # Instead of folder

Cause: Cycle spans many intermediate modules.

Solution: Use detailed output:

Terminal window
arxo analyze --format json | jq '.ui_schemas.scc.scc_details[] | select((.nodes | length) > 10)'

Cause: Analysis is not cached.

Solution: Enable caching:

cache:
enabled: true

Cause: Git history is not being loaded.

Solution: Explicitly enable git history in metric config:

metrics:
- id: scc
config:
use_git_history: true # This is required for churn data

Debug: Set ARCH0_SCC_DEBUG=1 to see whether git history is being loaded:

Terminal window
ARCH0_SCC_DEBUG=1 arxo analyze

Output will show:

[scc] use_git_history=true git_history=Some

Understanding scc.module.* vs scc.* metrics

Section titled “Understanding scc.module.* vs scc.* metrics”

Both exist by design (module namespace mirror):

  • scc.component_count and scc.module.component_count are identical
  • scc.cycle_count and scc.module.cycle_count are identical
  • scc.max_cycle_size and scc.module.max_cycle_size are identical
  • scc.total_nodes_in_cycles and scc.module.total_nodes_in_cycles are identical

Which to use in policies? Either. scc.* is shorter and recommended.