Skip to content

Commit 6987859

Browse files
Cranotholive
authored andcommitted
Change project name to 'Roam Code'
Updated project name and enhanced description in README.
1 parent 6d66f05 commit 6987859

2 files changed

Lines changed: 17 additions & 261 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div align="center">
22

3-
# roam
3+
# Roam Code
44

55
**The architectural intelligence layer for AI coding agents. Structural graph, architecture governance, multi-agent orchestration, vulnerability mapping, runtime analysis -- one CLI, zero API keys.**
66

src/roam/mcp_server.py

Lines changed: 16 additions & 260 deletions
Original file line numberDiff line numberDiff line change
@@ -166,60 +166,19 @@ def _run_roam(args: list[str], root: str = ".") -> dict:
166166

167167
@_tool(name="roam_understand")
168168
def understand(root: str = ".") -> dict:
169-
"""Get a full codebase briefing in a single call.
170-
171-
WHEN TO USE: Call this FIRST when you start working with a new or
172-
unfamiliar repository. Do NOT use Glob/Grep/Read to explore the
173-
codebase manually -- this tool gives you everything in one shot.
174-
175-
Returns: tech stack, architecture overview (layers, clusters, entry
176-
points, key abstractions), health score, hotspots, naming conventions,
177-
design patterns, and a suggested file reading order.
178-
179-
Output is ~2,000-4,000 tokens of structured JSON. After calling this,
180-
use `search_symbol` or `context` to drill into specific areas.
181-
"""
169+
"""Get a full codebase briefing in a single call. Call this FIRST when starting work on a new or unfamiliar codebase. Covers tech stack, architecture (layers, clusters, entry points), health score, hotspots, conventions, and patterns. ~2-4K token output. Do NOT explore manually with Glob/Grep/Read -- use this instead. Follow with search_symbol or context to drill into specifics."""
182170
return _run_roam(["understand"], root)
183171

184172

185173
@_tool(name="roam_health")
186174
def health(root: str = ".") -> dict:
187-
"""Get the codebase health score (0-100) with issue breakdown.
188-
189-
WHEN TO USE: Call this to assess overall code quality before deciding
190-
where to focus refactoring effort, or to check whether recent changes
191-
degraded health. Do NOT call this if you already called `understand`
192-
(which includes health data) or `preflight` (which includes it per-symbol).
193-
194-
Returns: composite health score, cycle count, god-component count,
195-
bottleneck symbols, dead-export count, layer violations, per-file
196-
health scores, and tangle ratio.
197-
"""
175+
"""Codebase health score (0-100) with issue breakdown. Call this to assess overall code quality before deciding where to focus refactoring, or to check whether recent changes degraded health. Skip if you already called understand (includes health) or preflight (includes it per-symbol)."""
198176
return _run_roam(["health"], root)
199177

200178

201179
@_tool(name="roam_preflight")
202180
def preflight(target: str = "", staged: bool = False, root: str = ".") -> dict:
203-
"""Pre-change safety check. Call this BEFORE modifying any symbol or file.
204-
205-
WHEN TO USE: Always call this before making code changes. It replaces
206-
5-6 separate tool calls by combining blast radius, affected tests,
207-
complexity, coupling, convention checks, and fitness violations into
208-
one response. Do NOT call `context`, `impact`, `affected_tests`, or
209-
`complexity_report` separately if preflight covers your need.
210-
211-
Parameters
212-
----------
213-
target:
214-
Symbol name or file path to check. If empty, checks all
215-
currently changed (unstaged) files.
216-
staged:
217-
If True, check staged (git add-ed) changes instead.
218-
219-
Returns: risk level, blast radius (affected symbols and files),
220-
test files to run, complexity metrics, coupling data, and any
221-
fitness rule violations.
222-
"""
181+
"""Pre-change safety check. Call this BEFORE modifying any symbol or file. Combines blast radius, affected tests, complexity, coupling, and fitness violations in one call. Replaces 5-6 separate tool calls. Do NOT call context, impact, affected_tests, or complexity_report separately if preflight covers your need."""
223182
args = ["preflight"]
224183
if target:
225184
args.append(target)
@@ -230,48 +189,13 @@ def preflight(target: str = "", staged: bool = False, root: str = ".") -> dict:
230189

231190
@_tool(name="roam_search_symbol")
232191
def search_symbol(query: str, root: str = ".") -> dict:
233-
"""Find symbols by name (case-insensitive substring match).
234-
235-
WHEN TO USE: Call this when you know part of a symbol name and need
236-
the exact qualified name, file location, or kind. Use this before
237-
calling `context` or `impact` to get the correct symbol identifier.
238-
Do NOT use Grep to search for function definitions -- this is faster
239-
and returns structured data with PageRank importance.
240-
241-
Parameters
242-
----------
243-
query:
244-
Name substring to search for (e.g., "auth", "User", "handle_request").
245-
246-
Returns: matching symbols with kind (function/class/method), file path,
247-
line number, signature, export status, and PageRank importance score.
248-
"""
192+
"""Find symbols by name (case-insensitive substring match). Call this when you know part of a symbol name and need the exact qualified name, file location, or kind. Use before context or impact to get the correct identifier. Do NOT use Grep for function definitions -- this is faster and returns structured data with PageRank importance."""
249193
return _run_roam(["search", query], root)
250194

251195

252196
@_tool(name="roam_context")
253197
def context(symbol: str, task: str = "", root: str = ".") -> dict:
254-
"""Get the minimal context needed to work with a specific symbol.
255-
256-
WHEN TO USE: Call this when you need to understand or modify a
257-
specific function, class, or method. Returns the exact files and
258-
line ranges to read -- much more targeted than `understand`.
259-
For pre-change safety checks, prefer `preflight` instead (it
260-
includes context data plus blast radius and tests).
261-
262-
Parameters
263-
----------
264-
symbol:
265-
Qualified or short name of the symbol to inspect.
266-
task:
267-
Optional hint: "refactor", "debug", "extend", "review", or
268-
"understand". Tailors output (e.g., adds complexity details
269-
for refactor, test coverage for debug).
270-
271-
Returns: symbol definition, direct callers and callees, file location
272-
with line ranges, related tests, graph metrics (PageRank, fan-in/out,
273-
betweenness), and complexity metrics.
274-
"""
198+
"""Get the minimal context needed to work with a specific symbol. Call this when you need to understand or modify a function, class, or method. Returns exact files and line ranges to read. More targeted than understand. For pre-change safety checks, prefer preflight instead (includes context plus blast radius and tests)."""
275199
args = ["context", symbol]
276200
if task:
277201
args.extend(["--task", task])
@@ -280,63 +204,19 @@ def context(symbol: str, task: str = "", root: str = ".") -> dict:
280204

281205
@_tool(name="roam_trace")
282206
def trace(source: str, target: str, root: str = ".") -> dict:
283-
"""Find the shortest dependency path between two symbols.
284-
285-
WHEN TO USE: Call this when you need to understand HOW a change in
286-
one symbol could affect another. Shows each hop along the path with
287-
symbol names, edge types, and locations.
288-
289-
Parameters
290-
----------
291-
source:
292-
Starting symbol name.
293-
target:
294-
Destination symbol name.
295-
296-
Returns: path hops (symbol name, kind, location, edge type), total
297-
hop count, coupling classification (strong/moderate/weak), and any
298-
hub nodes encountered.
299-
"""
207+
"""Find the shortest dependency path between two symbols. Call this to understand HOW a change in one symbol could affect another. Shows path hops with symbol names, edge types, locations, and coupling strength."""
300208
return _run_roam(["trace", source, target], root)
301209

302210

303211
@_tool(name="roam_impact")
304212
def impact(symbol: str, root: str = ".") -> dict:
305-
"""Show the blast radius of changing a symbol.
306-
307-
WHEN TO USE: Call this when you need to know everything that would
308-
break if a symbol's signature or behavior changed. For pre-change
309-
checks, prefer `preflight` which includes impact data plus tests
310-
and fitness checks.
311-
312-
Parameters
313-
----------
314-
symbol:
315-
Symbol to analyze.
316-
317-
Returns: affected symbols grouped by hop distance, affected files,
318-
total affected count, and severity assessment.
319-
"""
213+
"""Show the blast radius of changing a symbol -- everything that would break if its signature or behavior changed. Affected symbols by hop distance, affected files, severity. For pre-change checks, prefer preflight (includes impact plus tests and fitness)."""
320214
return _run_roam(["impact", symbol], root)
321215

322216

323217
@_tool(name="roam_file_info")
324218
def file_info(path: str, root: str = ".") -> dict:
325-
"""Show a file skeleton: every symbol definition with its signature.
326-
327-
WHEN TO USE: Call this when you need to understand what a file
328-
contains without reading the full source. Returns a structured
329-
outline that is more useful than Read for getting an overview.
330-
331-
Parameters
332-
----------
333-
path:
334-
File path relative to the project root.
335-
336-
Returns: all symbols in the file (functions, classes, methods) with
337-
kind, line range, signature, export status, and parent relationships.
338-
Also includes per-kind counts and the file's detected language.
339-
"""
219+
"""Show a file skeleton: every symbol definition with its signature. Call this to understand what a file contains without reading the full source. More useful than Read for getting a file overview."""
340220
return _run_roam(["file", path], root)
341221

342222

@@ -347,21 +227,7 @@ def file_info(path: str, root: str = ".") -> dict:
347227

348228
@_tool(name="roam_pr_risk")
349229
def pr_risk(staged: bool = False, root: str = ".") -> dict:
350-
"""Compute a risk score (0-100) for pending changes.
351-
352-
WHEN TO USE: Call this before committing or creating a PR to assess
353-
risk. Analyzes the current diff and produces a risk rating (LOW /
354-
MODERATE / HIGH / CRITICAL) with specific risk factors.
355-
356-
Parameters
357-
----------
358-
staged:
359-
If True, analyze staged changes instead of working-tree diff.
360-
361-
Returns: risk score, risk level, per-file breakdown (symbols changed,
362-
blast radius, churn), suggested reviewers, coupling surprises, and
363-
any new dead exports created.
364-
"""
230+
"""Compute a risk score (0-100) for pending changes. Call this before committing or creating a PR. Produces LOW/MODERATE/HIGH/CRITICAL rating with per-file breakdown, risk factors, and suggested reviewers."""
365231
args = ["pr-risk"]
366232
if staged:
367233
args.append("--staged")
@@ -390,23 +256,7 @@ def breaking_changes(target: str = "HEAD~1", root: str = ".") -> dict:
390256

391257
@_tool(name="roam_affected_tests")
392258
def affected_tests(target: str = "", staged: bool = False, root: str = ".") -> dict:
393-
"""Find test files that exercise the changed code.
394-
395-
WHEN TO USE: Call this to know which tests to run after making
396-
changes. Walks reverse dependency edges from changed code to find
397-
test files. For a full pre-change check, prefer `preflight` which
398-
includes affected tests plus blast radius and fitness checks.
399-
400-
Parameters
401-
----------
402-
target:
403-
Symbol name or file path. If empty, uses all currently changed files.
404-
staged:
405-
If True, start from staged changes.
406-
407-
Returns: test files with the symbols that link them to the change
408-
and the hop distance.
409-
"""
259+
"""Find test files that exercise changed code. Call this to know which tests to run after making changes. Walks reverse dependency edges from changed code to find test files. For a full pre-change check, prefer preflight (includes affected tests plus blast radius and fitness)."""
410260
args = ["affected-tests"]
411261
if target:
412262
args.append(target)
@@ -471,35 +321,13 @@ def dark_matter(min_npmi: float = 0.3, min_cochanges: int = 3, root: str = ".")
471321

472322
@_tool(name="roam_dead_code")
473323
def dead_code(root: str = ".") -> dict:
474-
"""List unreferenced exported symbols (dead code candidates).
475-
476-
WHEN TO USE: Call this to find code that can be safely removed.
477-
Finds exported symbols with zero incoming edges, filtering out
478-
known entry points and framework lifecycle hooks.
479-
480-
Returns: each dead symbol with kind, location, file, and a safety
481-
verdict indicating confidence level.
482-
"""
324+
"""List unreferenced exported symbols (dead code candidates). Call this to find code that can be safely removed. Finds symbols with zero incoming edges, filtering out known entry points and framework lifecycle hooks. Includes safety verdict per symbol."""
483325
return _run_roam(["dead"], root)
484326

485327

486328
@_tool(name="roam_complexity_report")
487329
def complexity_report(threshold: int = 15, root: str = ".") -> dict:
488-
"""Rank functions by cognitive complexity.
489-
490-
WHEN TO USE: Call this to find the most complex functions that
491-
should be refactored. Only symbols at or above the threshold are
492-
included. For checking a single symbol, prefer `context` or
493-
`preflight` which include complexity data.
494-
495-
Parameters
496-
----------
497-
threshold:
498-
Minimum cognitive-complexity score to include (default 15).
499-
500-
Returns: symbols ranked by complexity with score, nesting depth,
501-
parameter count, line count, severity label, and file location.
502-
"""
330+
"""Rank functions by cognitive complexity. Call this to find the most complex functions that should be refactored. For checking a single symbol, prefer context or preflight which include complexity data."""
503331
return _run_roam(["complexity", "--threshold", str(threshold)], root)
504332

505333

@@ -597,25 +425,7 @@ def visualize(
597425

598426
@_tool(name="roam_diagnose")
599427
def diagnose(symbol: str, depth: int = 2, root: str = ".") -> dict:
600-
"""Root cause analysis for a failing symbol.
601-
602-
WHEN TO USE: Call this when debugging a bug or test failure and you
603-
need to find the likely root cause. Ranks upstream callers and
604-
downstream callees by a composite risk score combining git churn,
605-
cognitive complexity, file health, and co-change entropy. Much
606-
faster than manually tracing call chains.
607-
608-
Parameters
609-
----------
610-
symbol:
611-
The symbol suspected of being involved in the bug.
612-
depth:
613-
How many hops upstream/downstream to analyze (default 2).
614-
615-
Returns: target symbol metrics, upstream suspects ranked by risk,
616-
downstream suspects ranked by risk, co-change partners, recent
617-
git commits, and a verdict naming the top suspect.
618-
"""
428+
"""Root cause analysis for a failing symbol or test. Call this when debugging a bug or test failure to find the likely root cause. Ranks upstream/downstream suspects by risk (git churn, complexity, health, co-change entropy). Faster than manually tracing call chains. Returns verdict naming top suspect."""
619429
args = ["diagnose", symbol, "--depth", str(depth)]
620430
return _run_roam(args, root)
621431

@@ -1622,27 +1432,7 @@ def search_semantic(query: str, top: int = 10, threshold: float = 0.05,
16221432

16231433
@_tool(name="roam_diff")
16241434
def roam_diff(commit_range: str = "", staged: bool = False, root: str = ".") -> dict:
1625-
"""Blast radius of uncommitted or committed changes.
1626-
1627-
WHEN TO USE: call after making code changes to see what's affected
1628-
BEFORE committing. Shows affected symbols, files, tests, coupling
1629-
warnings, and fitness violations.
1630-
1631-
WHEN NOT TO USE: for pre-PR analysis use roam_pr_risk instead.
1632-
1633-
Parameters
1634-
----------
1635-
commit_range:
1636-
Git range like ``HEAD~3..HEAD`` or ``main..feature``.
1637-
Empty = uncommitted working tree changes.
1638-
staged:
1639-
If True, analyze git-staged changes only.
1640-
root:
1641-
Working directory (project root).
1642-
1643-
Returns: changed files, affected symbols, blast radius metrics,
1644-
per-file breakdown.
1645-
"""
1435+
"""Blast radius of uncommitted or committed changes. Call this after making code changes to see what's affected BEFORE committing. Shows affected symbols, files, tests, coupling warnings, and fitness violations. For pre-PR analysis, use pr_risk instead."""
16461436
args = ["diff"]
16471437
if commit_range:
16481438
args.append(commit_range)
@@ -1679,24 +1469,7 @@ def roam_symbol(name: str, full: bool = False, root: str = ".") -> dict:
16791469

16801470
@_tool(name="roam_deps")
16811471
def roam_deps(path: str, full: bool = False, root: str = ".") -> dict:
1682-
"""File-level import/imported-by relationships.
1683-
1684-
WHEN TO USE: to understand a file's dependencies -- what it imports
1685-
and what imports it. File-level granularity. Use for module boundary
1686-
analysis and refactoring impact.
1687-
1688-
Parameters
1689-
----------
1690-
path:
1691-
File path relative to project root.
1692-
full:
1693-
Show all dependencies without truncation.
1694-
root:
1695-
Working directory (project root).
1696-
1697-
Returns: file path, imports list (paths, symbol counts), importers
1698-
list (files that import this one).
1699-
"""
1472+
"""File-level import/imported-by relationships. Call this to understand a file's dependencies -- what it imports and what imports it. Use for module boundary analysis and refactoring impact."""
17001473
args = ["deps", path]
17011474
if full:
17021475
args.append("--full")
@@ -1705,24 +1478,7 @@ def roam_deps(path: str, full: bool = False, root: str = ".") -> dict:
17051478

17061479
@_tool(name="roam_uses")
17071480
def roam_uses(name: str, full: bool = False, root: str = ".") -> dict:
1708-
"""All consumers of a symbol: callers, importers, inheritors.
1709-
1710-
WHEN TO USE: to find ALL places using a symbol, grouped by edge type
1711-
(calls, imports, inheritance, trait usage). Broader than roam_impact.
1712-
Use for planning API changes.
1713-
1714-
Parameters
1715-
----------
1716-
name:
1717-
Symbol name. Supports partial matching.
1718-
full:
1719-
Show all consumers without truncation.
1720-
root:
1721-
Working directory (project root).
1722-
1723-
Returns: symbol name, total_consumers, total_files, consumers
1724-
grouped by edge kind with name, kind, and location.
1725-
"""
1481+
"""All consumers of a symbol: callers, importers, inheritors grouped by edge type (calls, imports, inheritance, trait usage). Broader than impact. Use for planning API changes."""
17261482
args = ["uses", name]
17271483
if full:
17281484
args.append("--full")

0 commit comments

Comments
 (0)