Run the full dependency audit. Read-only. Returns structured results.
Returns the raw per-check dicts (``name``, ``status``, ``message``,
``fix_cmd``, ``instructions``, ``critical``) — NOT the formatted
``doctor`` table. Read ``status``/``fix_cmd``/``instructions`` per
issue; ``status="skipped"`` means a prerequisite is missing.
Args:
project_root: Project root directory. Auto-detected from CWD if omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
Returns:
list[dict]: one dict per check, ``DepCheckResult`` fields via ``asdict``.
Check whether the LLM backend is running and the configured embedding/chat model is installed.
Read-only: yes. No side effects. Call before smart_search,
semantic_search, or explain_symbol (when on-demand fallback is
expected — pre-computed analysis returns instantly without the LLM
backend).
Args:
project_root: Project root. Auto-detected if omitted. Used to
locate the project's LLM configuration.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
Returns:
dict: {ollama_enabled (bool), status (str — "ok"|"disabled"|
"not_configured"|"model_missing"|"embedding_unavailable"|"error"),
ollama_running (bool), ollama_url (str), configured_model (str),
num_ctx (int), installed_models (list[str]),
configured_embed_model (str), embedding_installed (bool),
message (str, on error/disabled), model_details (list[dict], when
Ollama running), suggest_cloud (bool), vec_available (bool),
vec_error (str, optional), debug_log (str, optional — only when
debug logging is enabled)}
Configure LLM settings for the current project.
Writes to ``<project>/.fw-context/local.toml`` ONLY (gitignored,
per-developer). Does NOT modify the global config or the shared
project ``config.toml``. After writing, tests the configuration
by making a simple API call (skipped when LLM is disabled).
IMPORTANT: When ``chat_api_base`` points to an external host, source
code snippets in chat prompts will be sent to that endpoint. Ensure
this complies with your organization's data security policies.
Consider using local Ollama or an internal API proxy first.
Args:
project_root: Project root directory. Auto-detected if omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
chat_api_base: Chat API URL (see description for format details).
chat_api_key: Bearer token for cloud/proxy APIs.
chat_api_format: Override auto-detection: "auto", "ollama", "openai".
model: Chat model name.
embed_model: Embedding model name (Ollama only).
auto_pull: Whether to auto-pull models on 404.
stream: Stream chat responses via SSE. True avoids reverse-proxy idle timeouts.
Returns:
dict: {status ("ok"|"error"), chat_api (dict — configured, endpoint,
format, model), model (str), auto_pull (bool), stream (bool),
test_latency_s (float, on success), test_response (str, on success),
compliance_warning (str, when chat_api_base is external),
message (str)}
MANDATORY FIRST CALL for C/C++ projects. Return metadata about the
most recently indexed build configuration — check index health before
using any other fw-context tools.
Read-only, and it spawns no subprocess — the startup daemon thread and
the file watcher own the background reindex.
Act on ``status``:
* ``"ready"`` — up to date. Continue.
* ``"reindexing"`` — background reindex running; queries stay accurate.
Continue. ``reindex_progress`` holds its last log line.
* ``"reindex_needed"`` — schema mismatch, changed compile_commands.json,
or a source file that compile_commands.json does not cover. Queries
still work on existing data. Read ``reindex_reasons``: a missing
source file needs ``fw-context index --build``, the other two need
only ``fw-context index``.
* ``"no_index"`` — initialized, never indexed. Run ``fw-context index``.
* ``"not_initialized"`` — run ``fw-context init``.
* ``"error"`` — DB corruption or access error. Use other tools.
Three conditions set ``reindex_needed``: an outdated schema, a changed
compile_commands.json, and a source file that is on disk but absent from
compile_commands.json. The third one needs a build, because only the
build system writes that file — a plain reindex has no translation unit
for the file and skips it without a word. Modified source files are
something else: they are handled per-query, and never set it.
``indexed_at`` and ``first_indexed_at`` are UTC; file mtimes are local
time. Never compare the two directly — in UTC+2 a correctly indexed
file looks 2 hours newer than ``indexed_at``. Call with ``fast=False``
to find modified files.
``analysis`` splits the LLM-analysis coverage into project and vendor
symbols:
* ``model`` — the model of the analysis, or None. One model only, even
when several were used.
* ``analyze_vendor`` — the value at index time, not the current config.
* ``project`` / ``vendor`` — ``{analyzed, skipped, total}``.
``skipped`` = tried, but not analyzable (body larger than the model
context, an unparseable answer, or a body that was not readable).
* ``complete`` — no work left: every project symbol is analyzed or
skipped. True exactly when ``reindex_reasons`` holds no "unanalyzed
symbols" entry. Vendor symbols excluded by ``analyze_vendor=False``
never block it, thus ``vendor.total`` large with ``vendor.analyzed=0``
is expected, not a defect.
Args:
project_root: Project root directory. Auto-detected from CWD if
omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
fast: When True (default), the header check reuses the cached
manifest hashes. Both modes run the per-file scan, thus
``modified_files_count`` is accurate either way — a tool that
reported "ready" while the search tools warned about the same
file gave the caller two readings and no way to choose.
False recomputes the header hashes and costs several times more.
Returns:
dict: {config_hash, project_id, project_root, build_system,
compile_commands, indexed_at (str — "YYYY-MM-DD HH:MM:SS" in UTC,
the completion time of the last full index), symbol_count, file_count,
reference_count, modified_files_count (int — files whose content no
longer matches the index; counted in both modes),
header_affected_tus (int — number of TUs with stale header
dependencies), manifest_verification (str —
"full" when manifest.json exists, "none" otherwise),
analysis (dict — LLM-analysis coverage split by project/vendor:
{model, analyze_vendor, project: {analyzed, skipped, total},
vendor: {analyzed, skipped, total}, complete}),
description (str), first_indexed_at (str — UTC, same format as
indexed_at),
vendor_paths (list[str] — config index.vendor_paths),
project_paths (list[str] — config index.project_paths),
bg_reindex_running (bool),
reindex_progress (str or None — last log line when reindex is running),
schema_version (int — DB schema version),
current_schema (int — code expects), status (str — "ready"|"reindexing"|
"reindex_needed"|"no_index"|"not_initialized"|"error"), reindex_needed (bool —
structural mismatch requiring a full reindex),
reindex_reasons (list[str] — why reindex is needed, empty when False.
One of them asks for `fw-context index --build` rather than a plain
reindex: when the tree is on a different branch than the index,
compile_commands.json belongs to the OLD branch and carries its file
list and its compiler flags, so only a build regenerates it. Read
the reason text — it names the command it needs),
stale (bool — True when reindex_needed or header_affected_tus > 0),
_warning (str, optional — when manifest verification is not "full"),
vec_available (bool), vec_error (str, optional),
index_message (str — human-readable summary of index state),
multi (bool — True for a multi-variant project),
variants (list[dict] — {name, description, board}),
images (list[dict] — {name, description, dir, type}),
variant_images (dict — variant name to its image names),
active_variant (str or None — [build] default_variant),
active_image (str or None — [build] default_image),
entry_point (str — the `ENTRY()` of the linker script of the build
that the other fields describe, empty when no script names one),
memory (list[dict] — the `MEMORY` regions of that build:
{name, attributes, origin, length, origin_value, length_value,
file_path, line})}
About ``memory``: ``origin`` and ``length`` hold the expression the
script writes, thus they differ by platform — an mbed script writes
`0xefe00` and a Zephyr script writes `((673792) - 0xe6)`.
``origin_value`` and ``length_value`` hold the number, and both are
None for an expression that names a symbol, such as
`ORIGIN(RAM) + LENGTH(RAM)`. The end of a region is
``origin_value + length_value``.
``memory`` and ``entry_point`` describe ONE build. For a
multi-variant project they follow ``config_hash``, which is the
build named by ``[build] default_variant``, and both are empty when
the config names no default. Use ``list_variants`` for the map of
every build.
``memory`` is empty for a build system that records no linker
script. A PlatformIO project is the measured case: SCons writes no
ninja file and no link command the index can read, and the map file
never names the script. An empty list means "not recorded", never
"no memory".
``defines`` (dict — the `-D` flags of that build) and
``defines_varying`` (int). ``defines`` holds only the names that
EVERY translation unit of the build carries with the same value, so
the tool never shows the defines of one file as the defines of the
build. ``defines_varying`` counts the names left out, thus a name
absent from ``defines`` is either not defined at all or not defined
everywhere — measured on the Mbed project: 27 names in all 881 units, 59
in only some, where the three assembly files get a shorter set.
This is the configuration the BUILD states, not every macro the
preprocessor saw. The second is three orders of magnitude larger —
27800 distinct names on the STM32 project — and almost all of it comes from the
headers and the compiler. A Zephyr build keeps its real
configuration in ``autoconf.h`` (740 `CONFIG_*` names) and passes
few `-D` flags, so ``defines`` says little there and a great deal on
an mbed build, where it holds `APPLICATION_ADDR`,
`APPLICATION_SIZE`, and `CMSIS_VECTAB_VIRTUAL`.
For a project that is not initialized, the result holds only
``status``, ``project_root``, and ``index_message``. When no index
exists, the result adds ``project_id``.
Return the complete project environment status in one call.
Read-only. Aggregates five domains into a single call so the LLM can
see everything at session start without extra round-trips:
- ``deps`` — dependency audit (``run_full_check``), each entry with an
optional ``action`` (``message`` + shell ``command``). ``status="skipped"``
means a prerequisite is missing (e.g. ``libclang-so`` skipped because
``libclang-python`` is absent) — not a failure.
- ``build_system`` — detected build system, ``None`` when unknown.
- ``compile_db`` — whether compile_commands.json exists and its entry count.
Reported as ``{"exists": false, ...}`` before init (no config to resolve
the path from, and loading one would create empty config files).
- ``index`` — the FULL ``get_active_build()`` result, unchanged (its action
lives in ``index_message``).
- ``llm`` — LLM backend status with an optional ``action``.
When the project is not initialized (``index.status == "not_initialized"``),
only the config-independent dependency subset runs (checks that do not need
a project config) — Ollama/model/db/build checks are skipped.
Args:
project_root: Project root directory. Auto-detected from CWD if omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
Returns:
dict: {init_status (str — "initialized" or "not_initialized"),
deps (list[dict] — name, status, message, and an optional action),
build_system (str or None),
compile_db (dict — {exists (bool), path (str or None),
entry_count (int or None — None before init, and when fw-context
cannot read the file)}),
index (dict — the full ``get_active_build`` result),
llm (dict — {enabled, ollama_running, chat_model, embed_model}, plus
``ollama_enabled`` when the LLM check ran, plus an optional
``action``)}.
Return project metadata (name, type, root_path) for a project ID.
Looks up the global project registry at ``~/.fw-context/projects.db``.
Use this to identify a project from its UUID4 — find out what build
system it uses, its name, and where it was last indexed.
Read-only. No side effects.
Args:
project_id: Project ID (UUID4 hex) to look up.
Returns:
dict: {project_id, name, project_type, root_path, created_at, updated_at}
or {"error": "..."} when the project_id is not registered.
On failure the dict holds only ``error`` with the reason.
List all indexed firmware projects with their statistics.
Read-only. No side effects. Use at session start to discover available
projects; use ``get_active_build`` for details on the currently active project.
``indexed_at`` and ``first_indexed_at`` are UTC, in ``"YYYY-MM-DD
HH:MM:SS"`` format — the same format that ``get_active_build`` returns.
``analysis`` holds the ``project`` and ``vendor`` counts only. For the
``model``, ``analyze_vendor``, and ``complete`` fields, call
``get_active_build`` for that project.
Args:
project_root: Project root. Auto-detected if omitted. Pass to
distinguish multiple indexed projects.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
Returns:
list of dicts, each with: project_id, name, root_path, build_system,
symbol_count, file_count, indexed_at (str — UTC), description (str),
first_indexed_at (str — UTC), schema_version, current_schema,
reindex_needed (bool), status (str — "ready" or "reindex_needed"),
db (path to SQLite database file),
variant_count (int — number of build variants),
image_count (int — number of sysbuild images),
analysis (dict — LLM-analysis coverage
{project: {analyzed, skipped, total},
vendor: {analyzed, skipped, total}}, or None when no build is
indexed).
When no project has an index, the result is a single dict with an
``info`` key. When fw-context cannot read a database, the result
holds a dict with ``db`` and ``error`` keys for that file.
List every indexed build with its (variant, image, board) identity.
Read-only diagnostic — shows what is actually indexed, not what the config
declares. Each row is one ``(variant, image)`` build with its own
``config_hash`` and symbol count. For single-project indexes this returns
one row with ``variant``/``image`` empty.
Use ``get_active_build`` for the mandatory first-call health check and the
human-readable ``variants``/``images`` discovery; use this tool to see the
per-build ``config_hash`` and symbol counts (authoritative per-build state).
Args:
project_root: Project root directory. Auto-detected from CWD if
omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
Returns:
dict: {builds (list[dict]), multi (bool — True when the config
declares variants or a build has a non-empty variant name)}.
Each build dict holds: variant (str — empty for a single-project
index), image (str — empty for a single-project index), board (str),
config_hash (str), symbol_count (int), file_count (int),
manifest_verification (str — "full" or "none"),
entry_point (str — the `ENTRY()` of the linker script of this build,
empty when no script names one),
memory (list[dict] — the `MEMORY` regions of this build:
{name, attributes, origin, length, origin_value, length_value,
file_path, line}). `origin` and `length` are the expression the
script writes; `origin_value` and `length_value` are numbers, and
they are None for an expression that names a symbol such as
`ORIGIN(RAM) + LENGTH(RAM)`. Empty for a build whose system
records no linker script — see the note below.
THIS is where a per-build memory map lives, not in the `images`
list of ``get_active_build``: that list holds one entry per image
NAME, and one name can belong to two variants with different
addresses.
When the project is not initialized, or has no index, the result is
{builds: [], multi: False, error (str)}.
Re-parse a single source file with libclang and update its symbols in the index.
Not read-only — uses the exact compiler flags from ``compile_commands.json``.
Use after editing a file to keep the index current without a full rebuild.
A source file must be listed in ``compile_commands.json``. A header is
not listed there, thus it is re-parsed through one unit that includes
it. That answer covers a single compilation context, thus the result
carries a ``warning`` — only a full ``fw-context index`` covers every
unit that includes the header.
Also regenerates LLM analysis and method override relationships for
affected symbols when those features are enabled in config. An
unchanged symbol keeps its stored analysis.
Args:
file_path: Path to the file to re-parse. A source file must be in
compile_commands.json; a header goes through one including unit.
project_root: Project root directory. Auto-detected if omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
Returns:
dict: {file, translation_units, symbols_updated, elapsed_s,
analysis_updated (if LLM enabled), or error}.
Re-parse a single source file with libclang and update its symbols in the index.
Not read-only — uses the exact compiler flags from ``compile_commands.json``.
Use after editing a file to keep the index current without a full rebuild.
A source file must be listed in ``compile_commands.json``. A header is
not listed there — compile_commands.json names translation units — so it
is re-parsed through one unit that includes it, taken from the manifest.
That answer describes a single compilation context, thus the result
carries a ``warning``: another unit can see the header under a different
set of ``#define`` values and still hold stale symbols. Only a full
``fw-context index`` covers every context. One unit and not all of them
is a cost decision — an application header reaches a median of 3 units
but as many as 266 on a real project, at tens of seconds each.
Also regenerates LLM analysis and method override relationships for
affected symbols when ``with_analysis=True``. The analysis is
content-addressed, thus an unchanged symbol is never re-analysed.
Args:
file_path: Path to the file to re-parse. A source file must be in
compile_commands.json; a header goes through one including unit.
project_root: Project root directory. Auto-detected if omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
with_analysis: When True (default), also regenerates LLM symbol analysis,
method override relationships, PageRank, and embeddings. Set False
for a fast symbol-only update (used by background auto-reindex).
Returns:
dict: {file, translation_units, symbols_updated, elapsed_s,
analysis_updated (if LLM enabled with analysis), or error}.
On failure the dict holds only ``error`` with the reason.
Delete the entire symbol index for a project.
Not read-only — permanently deletes the SQLite database and WAL files.
Call with ``confirm=False`` first (dry-run) to see what would be deleted.
Re-index with ``fw-context index`` afterwards.
Handles corrupt databases gracefully — you can delete a corrupt index
without needing to open it first.
Args:
project_root: Project root directory. Auto-detected if omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
confirm: Must be True to execute. Call without first as dry-run.
Returns:
dict: {project_root, db, project_id, action: "dry_run"|"deleted",
message, symbol_count, indexed_at (dry-run)}.
A ``warning`` key means that the database is corrupt — the
integrity check failed, thus the counts can be incomplete.
On failure the dict holds only ``error`` with the reason.
Look up a C/C++ symbol by name via libclang index — exact or prefix
matching. Finds symbols text-based search can miss: build-conditional
code, template instantiations, macro-expanded names. Macros are
extracted via ``clang -dM -E`` during indexing so ``#ifdef``-conditional
macros resolve correctly for the active build config. Prefer this over
search_code when you know the exact symbol name or a prefix
(``uart_`` finds all UART symbols). Use search_code for
keyword/concept search.
Read-only: yes. May auto-reindex stale files (non-blocking).
Args:
name: Symbol name (exact match) or prefix (set exact=False).
E.g. 'uart_init' finds the exact function; 'uart_' finds
all symbols starting with 'uart_'.
project_root: Project directory. Auto-detected if omitted.
project: Project name or project_id — call list_projects to get them.
Use it to ask about a project that is not the project of the
current directory. It is an alternative to project_root, which
takes a root path. Give one of the two, not both.
exact: True = exact name match, False = prefix LIKE match (default).
limit: Maximum results (default 50).
variant: Build variant (multi-project). Omit for the default
variant, ``"*"`` for all.
image: Sysbuild image in the variant. Omit for all images.
Returns:
list[dict]: Symbols with name, qualified_name, kind, file, line,
signature, docstring, is_definition, is_template, is_virtual,
is_pure_virtual fields. Enum constants include ``enum_value``
with the integer value. Macro results include ``kind="macro"``,
``value`` (raw definition), and ``expanded_value`` (preprocessor-
resolved value). May also include ``template_usr``,
``parent_usr``, and ``llm_analysis`` (``{summary, inputs,
outputs}``) when available. A model wrote the text in
``llm_analysis``, and the code did not — use it to find a symbol,
and quote ``signature``, ``docstring``, or ``get_source`` instead.
When no results found, may include ``_did_you_mean`` with suggested
symbol names. When no symbol matches, the list is empty —
this tool gives no ``info`` entry for an empty result.
**Note:** C++ constructors share their name with the enclosing
class, so ``lookup_symbol("Foo")`` may return both ``class Foo``
and ``constructor Foo::Foo()``. Use the ``kind`` field to
filter when you need a specific symbol type.
A symbol that comes from the relaxed prefix fallback carries
``_fallback: True`` — the name is not an exact match of *name*.
A list with one dict that holds an ``error`` key means that the
project has no index, or that the lookup failed. Read that key
before you read the result fields.
+27 more tools listed on main page