BharatCode

Usage

Built-in Tools

BharatCode ships with a full toolbox the agent calls to do real work — reading, editing, and patching files; LSP-backed navigation (go to definition, find references, rename, format); searching the codebase; running shell commands and background jobs; and reaching the web. The tools that change your machine — including edit, write, patch, rename, and bash — pass through the permission gate before they run.

Overview

A tool is a capability the model can invoke during a turn. Instead of only producing text, the agent emits a tool call — view a file, grep for a symbol, run bash — BharatCode executes it, and the result is fed back into the conversation. That loop is how the agent actually reads and changes your project rather than just describing what you should do.

The built-in tools group into six categories — editing, search & navigation (several backed by the language server), execution, web, reasoning, and jobs. Most are read-only and run without interruption. The ones that modify files or your system are permission-gated: by default the agent asks before they execute. See the Permissions page for how the ask / allow / deny gate and approval modes work.

  • Permission-gated — the call goes through the approval gate before it runs. The rest are read-only and execute directly.
ToolCategoryWhat it doesAgent uses it whenGate
viewEditingRead a file (optionally a line range) into context.before editing, to ground changes in the real file contents.
editEditingReplace an exact string in a file with new text.making a single, surgical change to a file.Gated
multieditEditingApply several string replacements to one file in one call.several related edits land in the same file at once.Gated
writeEditingCreate a new file or overwrite an existing one.scaffolding a new file or fully rewriting one.Gated
patchEditingApply a multi-file unified diff atomically — all hunks land or none do.a coordinated change spans several files at once.Gated
notebook_editEditingEdit a cell in a Jupyter (.ipynb) notebook.changing code or markdown inside a notebook.Gated
lsSearch & navList the entries in a directory.orienting in an unfamiliar tree or confirming a path exists.
globSearch & navFind files by glob pattern (e.g. **/*.go).locating files by name or extension across the project.
grepSearch & navSearch file contents with a regular expression.finding where a string or pattern appears textually.
symbolsSearch & nav (LSP)Look up symbols across the workspace or within one file (LSP).finding a function, type, or method by name, not by text.
navigateSearch & nav (LSP)Go to definition / declaration / references / implementation, plus hover & call hierarchy (LSP).tracing how code is wired by meaning, not by string match.
codeactionsSearch & nav (LSP)List and apply the language server’s quick-fixes and refactors.applying an LSP-suggested fix or refactor at a location.Gated
formatSearch & nav (LSP)Format a file with the language server’s formatter.normalizing style after edits, without shelling out.Gated
renameSearch & nav (LSP)Rename a symbol everywhere it is used, workspace-wide (LSP).renaming safely across files instead of text-replacing.Gated
diagnosticsSearch & nav (LSP)Read LSP diagnostics (errors, warnings) for the workspace.checking whether an edit introduced or cleared problems.
bashExecutionRun a shell command; can launch background jobs.building, testing, running, or any task the file tools cannot do.Gated
web_fetchWebFetch a URL and read its content.a specific page (docs, an issue, an API spec) is needed.
web_searchWebSearch the web for current information.recent or external facts are needed before acting.
todoReasoningMaintain a structured task list for the current work.planning and tracking progress on a multi-step task.
job_outputJobsRead new output from a running background job.watching a server’s logs or waiting for a build to finish.
job_listJobsList the background jobs and their status.checking what is still running before acting on it.
job_killJobsStop a running background job.shutting a server down once it is no longer needed.

Offline mode withholds the web tools

The two web tools are the only ones that leave your machine. In --offline mode BharatCode drops web_fetch and web_search from the registry entirely — the agent cannot call them even by name, so your code has no path off the box. Every other tool keeps working.

Editing — view, edit, multiedit, write, patch, notebook_edit

These tools are how the agent reads and changes source files. view is read-only and unrestricted; the rest modify files and are permission-gated.

  • view reads a file into context, optionally a specific line range. The agent uses it before editing so changes are grounded in the file's actual contents rather than a guess.
  • edit replaces one exact string in a file with new text. It is the go-to for a single, surgical change — rename a symbol, fix a line, tweak a value.
  • multiedit applies several string replacements to the same file in one call. The agent reaches for it when a set of related edits all land in one file, so they apply atomically.
  • write creates a new file or overwrites an existing one wholesale. Used for scaffolding a new file, or when a rewrite is cleaner than a pile of edits.
  • patch applies a multi-file unified diff in a single call. Every hunk is validated before anything is written, so a malformed patch aborts cleanly — either the whole change lands or none of it does. The agent reaches for it when one logical change touches several files at once.
  • notebook_edit edits a single cell in a Jupyter .ipynb notebook — replacing, inserting, or deleting code or markdown without rewriting the whole document.

A typical edit flow is read, then change: view the file, then edit it. The edit surfaces as a diff you approve (unless you are in an auto-approving mode):

TUItext
> rename the Timeout field to RequestTimeout in config.go   • view  config.go  • edit  config.go   (awaiting approval)   - Timeout    time.Duration  + RequestTimeout time.Duration

You can inspect the most recent changes at any time with the /diff slash command.

Before the agent can change code it has to find it. These three read-only tools are how it explores a repository:

  • ls lists the entries in a directory — used to orient in an unfamiliar tree or confirm a path exists.
  • glob finds files by pattern, such as **/*.go or cmd/**/main.go — used to locate files by name or extension across the project.
  • grep searches file contents with a regular expression — used to find every place a string or pattern appears textually. For tracing code by meaning rather than text, the LSP tools below are sharper.

These three are read-only and never gated, so the agent can explore your codebase freely without prompting you for approval.

Navigation via LSP — symbols, navigate, codeactions, format, rename, diagnostics

Text search finds strings; the language server understands code. When a language server is configured for the project, these tools let the agent move and refactor by symbol — the same go-to-definition and rename your editor offers, available to the agent:

  • symbols looks up symbols — functions, types, methods — across the whole workspace or within a single file, so the agent can jump to a definition by name instead of grepping for it.
  • navigate follows the relationships the LSP knows: go to definition, declaration, type definition, implementation, references, incoming / outgoing call hierarchy, hover (the server's type and doc for a symbol), and signature help. It is the precise way to trace how code is wired together.
  • codeactions lists and applies the language server's quick-fixes and refactors at a location — the lightbulb actions your editor surfaces. Because it edits files, it is permission-gated.
  • format formats a file with the language server's own formatter, so style stays consistent without shelling out to a separate tool. Mutating, so it is gated.
  • rename renames a symbol everywhere it is used, workspace-wide, via the LSP's rename — safer than a textual find-and-replace because it follows scope, not strings. Gated.
  • diagnostics reads the errors and warnings the language server reports for the workspace. The agent uses it to confirm an edit compiles cleanly — or to see exactly what broke — without running a full build.

Falls back gracefully

These tools depend on a configured language server. If none is wired up for a language, the agent simply leans on grep and edit instead. See LSP integration for how servers are configured.

Execution — bash (with background jobs)

bash runs a shell command and returns its output. It is the agent's catch-all for anything the file and search tools cannot do — building, running tests, installing dependencies, git operations, code generators, and more.

bash is permission-gated

Because a shell command can do anything your user can, bash always passes through the permission gate. In the default read-only mode the agent asks before each command; you can grant approval for once, the session, the project, or forever, or switch to an auto-approving mode when you trust the work.

Background jobs

Long-running commands — a dev server, a file watcher, a test runner in watch mode — would block the turn if run in the foreground. Instead, bash can launch them as background jobs that keep running while the agent continues. Three helper tools manage them:

  • job_output reads the new output a background job has produced since it was last checked — used to watch a server's logs or wait for a build to finish.
  • job_list lists the running background jobs and their status — used to see what is still alive before acting on it.
  • job_kill stops a running background job — used to shut a server down once it is no longer needed.

For example, the agent might start a dev server in the background, poll its output until it is ready, run a check against it, then kill it:

TUItext
> start the dev server, hit /health once it's up, then stop it   • bash        npm run dev   (background job #1)  • job_output  job #1        "listening on :3000"  • bash        curl -s localhost:3000/health   → {"ok":true}  • job_kill    job #1        stopped

Web — web_fetch, web_search

Two tools let the agent reach beyond your machine when the answer is not in the codebase:

  • web_fetch retrieves a specific URL and reads its content — used when the agent already knows the page it needs, such as a library's docs, a GitHub issue, or an API specification.
  • web_search runs a web search and returns results — used to find current or external information before acting, when the exact source is not known up front.

These are the only tools that leave the box

Web tools make outbound requests to the URLs and search engines they target. They do not send your source code anywhere on their own, and you can govern them through the permission system like any other tool. For a hard guarantee, run BharatCode with --offline: the web tools are withheld from the registry entirely, so there is no path off the machine at all.

Reasoning — todo

The todo tool keeps the agent grounded in its own plan: it maintains a structured task list for the work in progress. On a multi-step task the agent writes out the steps, then checks them off as it goes, so both you and it can see what is done and what remains.

Read alongside it, diagnostics (covered above with the LSP tools) keeps the agent grounded in the real state of the code — together they let it plan, act, and verify within a single turn.

Tools and permissions

Tools are the surface the permission system governs. The read-only tools — view, ls, glob, grep, symbols, navigate, diagnostics, web_fetch, web_search, todo, and the job_* controls — do not change your machine, so they run directly. The mutating tools — edit, multiedit, write, patch, notebook_edit, codeactions, format, rename, and bash — go through the gate.

Which gated tools actually prompt you depends on the active approval mode: read-only asks for every mutating call, auto auto-approves a safe subset, and full approves everything. The /permissions slash command switches modes, and --yolo (or /yolo in the TUI) bypasses the gate entirely for a trusted run.

terminalbash
bharatcode run --yolo "format the repo and run the test suite"

Tighten further with hooks

Beyond approval modes, you can intercept any tool call with lifecycle hooks PreToolUse can inspect a call's JSON payload and block it by glob or regex match, giving you policy control on top of the permission gate.