brito-cli 0.0.0-stage → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.brito/agents/reviewer.md +7 -0
- package/LICENSE +75 -0
- package/README.md +166 -2
- package/README.pt-BR.md +167 -0
- package/dist/agent/agents.js +65 -0
- package/dist/agent/claude-cli.js +216 -0
- package/dist/agent/context.js +40 -0
- package/dist/agent/loop.js +125 -0
- package/dist/agent/prompt.js +54 -0
- package/dist/cli.js +568 -0
- package/dist/graph/aliases.js +196 -0
- package/dist/graph/indexer.js +438 -0
- package/dist/graph/langs.js +526 -0
- package/dist/graph/sfc.js +52 -0
- package/dist/graph/store.js +96 -0
- package/dist/mcp/server.js +98 -0
- package/dist/model.js +136 -0
- package/dist/permissions.js +39 -0
- package/dist/repl.js +297 -0
- package/dist/skills/consolidate.js +76 -0
- package/dist/skills/describe.js +14 -0
- package/dist/skills/journal.js +72 -0
- package/dist/skills/learn-cli.js +55 -0
- package/dist/skills/learn.js +217 -0
- package/dist/skills/store.js +234 -0
- package/dist/tools/bash.js +17 -0
- package/dist/tools/delegate.js +61 -0
- package/dist/tools/fs.js +91 -0
- package/dist/tools/graph.js +117 -0
- package/dist/tools/plan.js +17 -0
- package/dist/tools/registry.js +56 -0
- package/dist/tools/skills.js +58 -0
- package/dist/ui/banner.js +138 -0
- package/dist/ui/dock.js +616 -0
- package/dist/ui/theme.js +63 -0
- package/dist/ui/ui.js +426 -0
- package/dist/ui/web-art.js +131 -0
- package/dist/util/diff.js +36 -0
- package/dist/util/frontmatter.js +16 -0
- package/package.json +66 -4
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer
|
|
3
|
+
description: Revisa mudanças procurando bugs e impacto em chamadores. Somente leitura.
|
|
4
|
+
tools: read_file, grep, graph_context, graph_callers, graph_impact
|
|
5
|
+
model: claude-opus-5-5
|
|
6
|
+
---
|
|
7
|
+
Você é um revisor de código rigoroso. Para cada símbolo alterado, rode graph_callers e verifique se os chamadores continuam corretos.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
Required Notice: Copyright (c) 2026 Wilson Brito (https://github.com/wilsonbrito/brito)
|
|
2
|
+
|
|
3
|
+
# PolyForm Noncommercial License 1.0.0
|
|
4
|
+
|
|
5
|
+
<https://polyformproject.org/licenses/noncommercial/1.0.0>
|
|
6
|
+
|
|
7
|
+
## Acceptance
|
|
8
|
+
|
|
9
|
+
In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license).
|
|
14
|
+
|
|
15
|
+
## Distribution License
|
|
16
|
+
|
|
17
|
+
The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license).
|
|
18
|
+
|
|
19
|
+
## Notices
|
|
20
|
+
|
|
21
|
+
You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example:
|
|
22
|
+
|
|
23
|
+
> Required Notice: Copyright Yoyodyne, Inc. (http://example.com)
|
|
24
|
+
|
|
25
|
+
## Changes and New Works License
|
|
26
|
+
|
|
27
|
+
The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose.
|
|
28
|
+
|
|
29
|
+
## Patent License
|
|
30
|
+
|
|
31
|
+
The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software.
|
|
32
|
+
|
|
33
|
+
## Noncommercial Purposes
|
|
34
|
+
|
|
35
|
+
Any noncommercial purpose is a permitted purpose.
|
|
36
|
+
|
|
37
|
+
## Personal Uses
|
|
38
|
+
|
|
39
|
+
Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose.
|
|
40
|
+
|
|
41
|
+
## Noncommercial Organizations
|
|
42
|
+
|
|
43
|
+
Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding.
|
|
44
|
+
|
|
45
|
+
## Fair Use
|
|
46
|
+
|
|
47
|
+
You may have "fair use" rights for the software under the law. These terms do not limit them.
|
|
48
|
+
|
|
49
|
+
## No Other Rights
|
|
50
|
+
|
|
51
|
+
These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses.
|
|
52
|
+
|
|
53
|
+
## Patent Defense
|
|
54
|
+
|
|
55
|
+
If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
|
|
56
|
+
|
|
57
|
+
## Violations
|
|
58
|
+
|
|
59
|
+
The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately.
|
|
60
|
+
|
|
61
|
+
## No Liability
|
|
62
|
+
|
|
63
|
+
***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.***
|
|
64
|
+
|
|
65
|
+
## Definitions
|
|
66
|
+
|
|
67
|
+
The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms.
|
|
68
|
+
|
|
69
|
+
**You** refers to the individual or entity agreeing to these terms.
|
|
70
|
+
|
|
71
|
+
**Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
|
|
72
|
+
|
|
73
|
+
**Your licenses** are all the licenses granted to you for the software under these terms.
|
|
74
|
+
|
|
75
|
+
**Use** means anything you do with the software requiring one of your licenses.
|
package/README.md
CHANGED
|
@@ -1,3 +1,167 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Brito
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**English** · [Português](README.pt-BR.md)
|
|
4
|
+
|
|
5
|
+
> A coding-agent CLI that knows your codebase as a **graph** and learns your project's procedures as **skills you review**.
|
|
6
|
+
|
|
7
|
+
Brito is a terminal agent for software development. Instead of grepping and reading files blindly, it keeps a **knowledge graph of your code** (symbols, who calls whom, who imports whom) and answers questions like *"what breaks if I change this?"* straight from the graph, in a fraction of a second. It also keeps **memory notes** and **skills**: reusable procedures learned from your own work, which only become active after **you** approve them.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
*A real session on a small SvelteKit project: one question, two graph calls (0.1 s and 0.0 s), and an answer that already includes the `.svelte` components depending on the file. The status bar shows the real cost of the turn.*
|
|
12
|
+
|
|
13
|
+
## Highlights
|
|
14
|
+
|
|
15
|
+
- **Graph-first exploration.** `graph_search`, `graph_context`, `graph_callers`, `graph_callees` and `graph_impact` answer "where is it, who uses it, what breaks" without reading whole files. The graph is embedded ([Kùzu](https://kuzudb.com)), local and incremental.
|
|
16
|
+
- **Wide coverage.** TypeScript/JavaScript, Python and the script blocks of `.svelte`, `.vue` and `.astro` components. Import aliases (`tsconfig` paths, `package.json` imports, SvelteKit's `$lib`) become real edges. Files ignored by `.gitignore` stay out.
|
|
17
|
+
- **Skills that learn, with a human in the loop.** After a complex task Brito reflects on what happened and *proposes* skills. Nothing becomes active until you run `/skills approve`.
|
|
18
|
+
- **Safety rails for what gets learned.** A lint rejects secrets, credentials embedded in URLs, `curl | sh` and prompt-injection phrasing, and **warns about destructive commands** (see below).
|
|
19
|
+
- **Permission modes.** manual, auto-edits, plan and "everything allowed" (`Shift+Tab` cycles them). Even in the last one, skills are queued for review instead of being activated.
|
|
20
|
+
- **Two backends, one interface.** Use an Anthropic API key, or your Claude Code subscription through the `claude` CLI. Brito never reads or sends your subscription token.
|
|
21
|
+
- **Subagents.** `explore`, `plan` and `general` run in isolated contexts (read-only ones in parallel); add your own in `.brito/agents/*.md`.
|
|
22
|
+
- **MCP server.** `brito mcp-serve` exposes the graph, memory and skills to other MCP clients such as Claude Code. The query tools are marked `alwaysLoad`, so they are not hidden behind tool search.
|
|
23
|
+
|
|
24
|
+
## How it works
|
|
25
|
+
|
|
26
|
+
```mermaid
|
|
27
|
+
flowchart LR
|
|
28
|
+
code["Your project<br/>.ts · .js · .py · .java · .kt · .go · .rb · .php · .cs · .rs · .svelte · .vue · .astro"] -->|"tree-sitter<br/>incremental"| cg[("Code graph<br/>symbols · calls · imports")]
|
|
29
|
+
cg <-->|"graph_search · graph_callers<br/>graph_impact · graph_context"| agent{{"Brito agent"}}
|
|
30
|
+
mem[("Memory<br/>decisions · conventions")] <-->|"recall / remember"| agent
|
|
31
|
+
agent -->|"after a complex task"| learn["Reflection"]
|
|
32
|
+
learn -->|"proposes"| pending["Pending skills"]
|
|
33
|
+
pending -->|"/skills approve<br/>you decide"| skills[("Skills<br/>.brito/skills")]
|
|
34
|
+
skills -->|"skill_load"| agent
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- **Code graph**: functions, classes, methods and components as nodes; `CALLS` and `IMPORTS` as edges. It re-parses only files whose hash changed and updates itself after edits.
|
|
38
|
+
- **Memory**: durable notes (decisions, conventions, bugs found) linked to files and symbols, retrieved with `recall`.
|
|
39
|
+
- **Skills**: step-by-step procedures for *your* project (commands, order, traps, how to verify). The agent loads one with `skill_load` before a task it covers.
|
|
40
|
+
- **Journal**: Brito remembers across sessions which tasks repeated, which is the best hint that a procedure is general and worth saving.
|
|
41
|
+
|
|
42
|
+
## Skills you review, not magic
|
|
43
|
+
|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
1. A proposal appears in `/skills pending`, flagged when it contains destructive commands.
|
|
47
|
+
2. `/skills approve <name>` shows the **whole body** and the lint warnings, then asks for confirmation. That confirmation is required even in "everything allowed" mode.
|
|
48
|
+
3. Approved skills are versioned (`history/`), ranked by use, and flagged when the files they cite no longer exist. `/skills consolidate` merges duplicates and prunes unused ones.
|
|
49
|
+
4. A skill can be project-scoped or **global** (valid in every project); `/skills promote` moves one to global.
|
|
50
|
+
|
|
51
|
+
The lint **rejects** secrets/tokens, absolute user paths, credentials in URLs (`user:password@host`), `curl | sh`, and instructions to override rules or skip approval. It **warns** (without blocking) about commands that destroy data: removing database or data files, `DROP`/`TRUNCATE`, `DELETE` without `WHERE`, migration resets, `git reset --hard`, force-push, Docker volume removal. A skill is a standing instruction, so a step that was only safe in the state of one moment must not silently become the default.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
Requires Node >= 20. Developed on macOS; Linux should work, Windows is untested.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# from npm (the command is `brito`)
|
|
59
|
+
npm i -g brito-cli
|
|
60
|
+
|
|
61
|
+
# or one line
|
|
62
|
+
curl -fsSL https://raw.githubusercontent.com/wilsonbrito/brito/main/install.sh | bash
|
|
63
|
+
|
|
64
|
+
# or straight from GitHub
|
|
65
|
+
npm i -g github:wilsonbrito/brito
|
|
66
|
+
|
|
67
|
+
# or cloning
|
|
68
|
+
git clone https://github.com/wilsonbrito/brito && cd brito
|
|
69
|
+
npm install && npm run build && npm link
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Pick a backend:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
export ANTHROPIC_API_KEY=sk-ant-... # Anthropic API
|
|
76
|
+
# or: install Claude Code, run `claude` and /login — Brito will use your subscription
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Quick start
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cd your-project
|
|
83
|
+
brito # opens the REPL
|
|
84
|
+
brito "who calls parseConfig?" # single prompt, no REPL
|
|
85
|
+
brito index # (re)index the graph; it is also kept up to date automatically
|
|
86
|
+
brito query "MATCH (c:Symbol {kind:'component'})-[:CALLS]->(f:Symbol) RETURN c.file, f.name LIMIT 5"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
A real `brito index` on the sample project above:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
OK: 20 arquivos, 66 símbolos, 54 chamadas, 17 imports | +0 ~0 -0 =20 (28ms)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+

|
|
96
|
+
|
|
97
|
+
### Inside the REPL
|
|
98
|
+
|
|
99
|
+
| Command | What it does |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `/help` | list commands |
|
|
102
|
+
| `/model`, `/effort`, `/reasoning` | choose model, reasoning effort and thinking (session, global or once) |
|
|
103
|
+
| `/modo` or `Shift+Tab` | switch permission mode: manual → auto-edits → plan |
|
|
104
|
+
| `/skills` | list skills · `pending` · `approve <name>` · `reject <name>` · `consolidate` · `rm <name>` · `promote <name>` |
|
|
105
|
+
| `/learn` | extract skills from the last turn now |
|
|
106
|
+
| `/agents`, `/tools`, `/index`, `/context` | inspect subagents, tools, the index and the context window |
|
|
107
|
+
| `!command` | run a shell command directly, without calling the model |
|
|
108
|
+
| `/clear`, `/exit` | clear the conversation, quit |
|
|
109
|
+
|
|
110
|
+
## What the graph indexes
|
|
111
|
+
|
|
112
|
+
- **Languages:** TypeScript/JavaScript (`.ts .tsx .mts .cts .js .jsx .mjs .cjs`), Python (`.py`), backend languages — Java (`.java`), Kotlin (`.kt`), Go (`.go`), Ruby (`.rb`), PHP (`.php`), C# (`.cs`), Rust (`.rs`) — and the `.svelte`, `.vue` and `.astro` components. In components Brito reads the script block(s) (and Astro's frontmatter) and records calls made from the template to functions the script declares or imports; each component becomes a `component` symbol.
|
|
113
|
+
- **Scope:** inside a git repository, only what git considers part of the project (tracked + untracked-but-not-ignored), so anything in `.gitignore` stays out. Outside git, or with `BRITO_INDEX_IGNORED=1`, it indexes by glob (still skipping `node_modules`, `dist`, `build`, `target`, `vendor`, `obj`, `.gradle`, `.venv`, `.brito`).
|
|
114
|
+
- **Imports:** relative and aliased. Resolves `paths`/`baseUrl` from `tsconfig.json`/`jsconfig.json` (following relative `extends`, like `.svelte-kit/tsconfig.json`), `package.json` `imports` (`#internal/*`) and SvelteKit's `$lib`. Configuration applies per file (nearest config), so monorepos work; editing a tsconfig re-indexes the affected files.
|
|
115
|
+
- **Backend languages:** the graph holds classes/interfaces/structs/traits/enums/modules, functions and methods (`Class.method`), calls and imports. Imports name a package, not a path, so Brito matches them against the end of your files' paths (`com.acme.Repo` ↔ `src/main/java/com/acme/Repo.java`; PHP PSR-4 namespaces; Rust `use crate::…`; Ruby `require`/`require_relative`; Go packages through the `go.mod` module path). External packages (`java.util`, `serde`, `github.com/gin-gonic/gin`) never match and create no edges. There is no type inference: a call like `userRepository.save()` is linked by matching the receiver name to a type in the project (`UserRepository`), `this`/`self`/receivers resolve to the enclosing class, and a bare call inside a class tries the class's own methods first.
|
|
116
|
+
- **Not yet:** `extends` by package (`@tsconfig/node20`), sibling-workspace `exports`, and function references without a call in a template (`onclick={fn}`). Calls are resolved statically with name-based fallbacks, so dynamic dispatch and reflection are not captured.
|
|
117
|
+
|
|
118
|
+
## Databases and other sensitive resources
|
|
119
|
+
|
|
120
|
+
Brito has **no database drivers and connects to nothing on its own**. When it needs to touch a database, it uses your project's own tooling through the shell, under the permission mode you chose. Because every project is different (a local file, a remote server, a container), declare the sensitive parts in `BRITO.md` (or `CLAUDE.md` / `AGENTS.md`), which is read into the system prompt:
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
## Protected resources
|
|
124
|
+
- Database: local SQLite file `local.db` (never commit, never recreate).
|
|
125
|
+
Test destructive changes on a copy: `cp local.db /tmp/test.db` and set `DATABASE_URL`.
|
|
126
|
+
Schema changes: additive only, back up first (`cp local.db backups/pre-change.db`).
|
|
127
|
+
- Staging Postgres: connection string is in `$STAGING_DATABASE_URL` (read-only role). Never touch production.
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
- Credentials never belong in skills or notes: the lint rejects them. Cite the **name** of the environment variable instead.
|
|
131
|
+
- Prefer read-only roles and non-production environments when you give an agent database access.
|
|
132
|
+
- A proposed skill that contains a destructive command is highlighted at review time, so you decide whether it needs a guard (backup, copy, confirmation).
|
|
133
|
+
|
|
134
|
+
## Configuration
|
|
135
|
+
|
|
136
|
+
`BRITO_MODEL`, `BRITO_EFFORT`, `BRITO_EXPLORE_MODEL`, `BRITO_LEARN_MODEL`, `BRITO_HOME` (where global skills and history live), `BRITO_CONFIG`, `BRITO_COLOR`, `BRITO_BANNER` (`compact` or `full`; default: full screen on windows of 95+ columns and 28+ rows), `BRITO_INDEX_IGNORED`, `BRITO_SKILL_MIN_TOOLS` (how long a turn must be to trigger reflection when nothing else does).
|
|
137
|
+
|
|
138
|
+
Project data lives in `.brito/` (graph, project skills, agents) and global data in `~/.brito`. The graph, memory and skills stay on your machine; as with any coding agent, the code the model reads is sent to the model provider you configured.
|
|
139
|
+
|
|
140
|
+
## Limitations
|
|
141
|
+
|
|
142
|
+
- Early software (v0.3.1), one maintainer.
|
|
143
|
+
- **The interface and the agent's default language are Brazilian Portuguese.** Translating them is a welcome contribution.
|
|
144
|
+
- Skill learning is a heuristic: it proposes, you decide. Expect some proposals to be rejected.
|
|
145
|
+
|
|
146
|
+
## Development
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
git clone https://github.com/wilsonbrito/brito && cd brito
|
|
150
|
+
npm install
|
|
151
|
+
npm run dev # runs via tsx
|
|
152
|
+
npm run typecheck
|
|
153
|
+
npm test # 190+ tests, including a real MCP server and a real REPL
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
| Path | What |
|
|
157
|
+
|---|---|
|
|
158
|
+
| `src/graph/` | indexer (tree-sitter), `.svelte/.vue/.astro` support, import aliases, Kùzu store |
|
|
159
|
+
| `src/skills/` | store, lint, reflection, journal, consolidation |
|
|
160
|
+
| `src/agent/` | agent loop, prompts, subagents, `claude` CLI backend |
|
|
161
|
+
| `src/tools/` | graph, memory, skills, filesystem and shell tools |
|
|
162
|
+
| `src/mcp/` | MCP server |
|
|
163
|
+
| `src/repl.ts`, `src/ui/` | terminal interface |
|
|
164
|
+
|
|
165
|
+
## License
|
|
166
|
+
|
|
167
|
+
[PolyForm Noncommercial 1.0.0](LICENSE): free to use, study and modify for any noncommercial purpose (personal use, research, education, hobby, nonprofits). Commercial use is not permitted. This is source-available, not OSI open source. Need a commercial license? Open an issue.
|
package/README.pt-BR.md
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# Brito
|
|
2
|
+
|
|
3
|
+
[English](README.md) · **Português**
|
|
4
|
+
|
|
5
|
+
> Uma CLI de agente de código que conhece o seu projeto como um **grafo** e aprende os procedimentos dele como **skills que você revisa**.
|
|
6
|
+
|
|
7
|
+
O Brito é um agente de terminal para desenvolvimento de software. Em vez de dar `grep` e ler arquivos às cegas, ele mantém um **grafo de conhecimento do código** (símbolos, quem chama quem, quem importa quem) e responde perguntas como *"o que quebra se eu mudar isto?"* direto do grafo, em uma fração de segundo. Ele também guarda **notas de memória** e **skills**: procedimentos reutilizáveis aprendidos no seu próprio trabalho, que só passam a valer depois que **você** aprova.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
*Uma sessão real num pequeno projeto SvelteKit: uma pergunta, duas consultas ao grafo (0,1 s e 0,0 s) e uma resposta que já inclui os componentes `.svelte` que dependem do arquivo. A barra de status mostra o custo real do turno.*
|
|
12
|
+
|
|
13
|
+
## Destaques
|
|
14
|
+
|
|
15
|
+
- **Exploração guiada pelo grafo.** `graph_search`, `graph_context`, `graph_callers`, `graph_callees` e `graph_impact` respondem "onde está, quem usa, o que quebra" sem ler arquivos inteiros. O grafo é embutido ([Kùzu](https://kuzudb.com)), local e incremental.
|
|
16
|
+
- **Cobertura ampla.** TypeScript/JavaScript, Python e os blocos de script de componentes `.svelte`, `.vue` e `.astro`. Aliases de import (`paths` do tsconfig, `imports` do package.json, `$lib` do SvelteKit) viram arestas de verdade. O que o `.gitignore` ignora fica de fora.
|
|
17
|
+
- **Skills que aprendem, com um humano no circuito.** Depois de uma tarefa complexa o Brito reflete sobre o que aconteceu e *propõe* skills. Nada fica ativo até você rodar `/skills approve`.
|
|
18
|
+
- **Proteções sobre o que é aprendido.** Um lint rejeita segredos, credenciais embutidas em URL, `curl | sh` e frases de injeção de prompt, e **avisa sobre comandos destrutivos** (veja abaixo).
|
|
19
|
+
- **Modos de permissão.** manual, auto-edições, plano e "tudo liberado" (`Shift+Tab` alterna). Mesmo no último, as skills vão para a fila de revisão em vez de ficarem ativas.
|
|
20
|
+
- **Dois backends, uma interface.** Use uma chave da API da Anthropic ou a sua assinatura do Claude Code pela CLI `claude`. O Brito nunca lê nem envia o token da sua assinatura.
|
|
21
|
+
- **Subagentes.** `explore`, `plan` e `general` rodam em contextos isolados (os somente-leitura, em paralelo); crie os seus em `.brito/agents/*.md`.
|
|
22
|
+
- **Servidor MCP.** `brito mcp-serve` expõe grafo, memória e skills a outros clientes MCP, como o Claude Code. As tools de consulta são marcadas `alwaysLoad`, para não ficarem escondidas atrás da busca de tools.
|
|
23
|
+
|
|
24
|
+
## Como funciona
|
|
25
|
+
|
|
26
|
+
```mermaid
|
|
27
|
+
flowchart LR
|
|
28
|
+
code["Seu projeto<br/>.ts · .js · .py · .java · .kt · .go · .rb · .php · .cs · .rs · .svelte · .vue · .astro"] -->|"tree-sitter<br/>incremental"| cg[("Grafo de código<br/>símbolos · chamadas · imports")]
|
|
29
|
+
cg <-->|"graph_search · graph_callers<br/>graph_impact · graph_context"| agent{{"Agente Brito"}}
|
|
30
|
+
mem[("Memória<br/>decisões · convenções")] <-->|"recall / remember"| agent
|
|
31
|
+
agent -->|"após uma tarefa complexa"| learn["Reflexão"]
|
|
32
|
+
learn -->|"propõe"| pending["Skills pendentes"]
|
|
33
|
+
pending -->|"/skills approve<br/>você decide"| skills[("Skills<br/>.brito/skills")]
|
|
34
|
+
skills -->|"skill_load"| agent
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- **Grafo de código**: funções, classes, métodos e componentes como nós; `CALLS` e `IMPORTS` como arestas. Só reparseia os arquivos cujo hash mudou e se atualiza sozinho após edições.
|
|
38
|
+
- **Memória**: notas duráveis (decisões, convenções, bugs descobertos) ligadas a arquivos e símbolos, recuperadas com `recall`.
|
|
39
|
+
- **Skills**: procedimentos passo a passo para o *seu* projeto (comandos, ordem, armadilhas, como verificar). O agente carrega uma com `skill_load` antes de uma tarefa que ela cobre.
|
|
40
|
+
- **Journal**: o Brito lembra entre sessões quais tarefas se repetiram, o melhor indício de que um procedimento é geral e vale guardar.
|
|
41
|
+
|
|
42
|
+
## Skills que você revisa, sem mágica
|
|
43
|
+
|
|
44
|
+

|
|
45
|
+
|
|
46
|
+
1. Uma proposta aparece em `/skills pending`, sinalizada quando contém comandos destrutivos.
|
|
47
|
+
2. `/skills approve <nome>` mostra o **corpo inteiro** e os avisos do lint, e pede confirmação. Essa confirmação é exigida mesmo no modo "tudo liberado".
|
|
48
|
+
3. Skills aprovadas são versionadas (`history/`), ranqueadas por uso e sinalizadas quando os arquivos que citam deixam de existir. `/skills consolidate` junta duplicadas e poda as sem uso.
|
|
49
|
+
4. Uma skill pode ser do projeto ou **global** (vale em todos os projetos); `/skills promote` move uma para global.
|
|
50
|
+
|
|
51
|
+
O lint **rejeita** segredos/tokens, caminhos absolutos do usuário, credenciais em URL (`usuario:senha@host`), `curl | sh` e instruções para sobrepor regras ou pular aprovação. Ele **avisa** (sem bloquear) sobre comandos que destroem dados: apagar arquivos de banco ou de dados, `DROP`/`TRUNCATE`, `DELETE` sem `WHERE`, reset de migrações, `git reset --hard`, force push, remoção de volumes do Docker. Uma skill é uma instrução permanente, então um passo que só era seguro no estado de um momento não pode virar o padrão em silêncio.
|
|
52
|
+
|
|
53
|
+
## Instalação
|
|
54
|
+
|
|
55
|
+
Requer Node >= 20. Desenvolvido no macOS; no Linux deve funcionar, no Windows não foi testado.
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# pelo npm (o comando é `brito`)
|
|
59
|
+
npm i -g brito-cli
|
|
60
|
+
|
|
61
|
+
# ou uma linha
|
|
62
|
+
curl -fsSL https://raw.githubusercontent.com/wilsonbrito/brito/main/install.sh | bash
|
|
63
|
+
|
|
64
|
+
# ou direto do GitHub
|
|
65
|
+
npm i -g github:wilsonbrito/brito
|
|
66
|
+
|
|
67
|
+
# ou clonando
|
|
68
|
+
git clone https://github.com/wilsonbrito/brito && cd brito
|
|
69
|
+
npm install && npm run build && npm link
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Escolha um backend:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
export ANTHROPIC_API_KEY=sk-ant-... # API da Anthropic
|
|
76
|
+
# ou: instale o Claude Code, rode `claude` e /login — o Brito usa a sua assinatura
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Começando
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
cd seu-projeto
|
|
83
|
+
brito # abre o REPL
|
|
84
|
+
brito "quem chama parseConfig?" # prompt único, sem REPL
|
|
85
|
+
brito index # (re)indexa o grafo; ele também se mantém atualizado sozinho
|
|
86
|
+
brito query "MATCH (c:Symbol {kind:'component'})-[:CALLS]->(f:Symbol) RETURN c.file, f.name LIMIT 5"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Um `brito index` real no projeto de exemplo acima:
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
OK: 20 arquivos, 66 símbolos, 54 chamadas, 17 imports | +0 ~0 -0 =20 (28ms)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+

|
|
96
|
+
|
|
97
|
+
### Dentro do REPL
|
|
98
|
+
|
|
99
|
+
| Comando | O que faz |
|
|
100
|
+
|---|---|
|
|
101
|
+
| `/help` | lista os comandos |
|
|
102
|
+
| `/model`, `/effort`, `/reasoning` | escolhem modelo, esforço de raciocínio e thinking (sessão, global ou uma vez) |
|
|
103
|
+
| `/modo` ou `Shift+Tab` | troca o modo de permissão: manual → auto-edições → plano |
|
|
104
|
+
| `/skills` | lista skills · `pending` · `approve <nome>` · `reject <nome>` · `consolidate` · `rm <nome>` · `promote <nome>` |
|
|
105
|
+
| `/learn` | extrai skills do último turno agora |
|
|
106
|
+
| `/agents`, `/tools`, `/index`, `/context` | inspecionam subagentes, tools, o índice e a janela de contexto |
|
|
107
|
+
| `!comando` | roda um comando no shell direto, sem chamar o modelo |
|
|
108
|
+
| `/clear`, `/exit` | limpa a conversa, sai |
|
|
109
|
+
|
|
110
|
+
## O que o grafo indexa
|
|
111
|
+
|
|
112
|
+
- **Linguagens:** TypeScript/JavaScript (`.ts .tsx .mts .cts .js .jsx .mjs .cjs`), Python (`.py`), linguagens de backend — Java (`.java`), Kotlin (`.kt`), Go (`.go`), Ruby (`.rb`), PHP (`.php`), C# (`.cs`), Rust (`.rs`) — e os componentes `.svelte`, `.vue` e `.astro`. Nos componentes o Brito lê o(s) bloco(s) de script (e o frontmatter do Astro) e registra as chamadas feitas no template a funções que o script declara ou importa; cada componente vira um símbolo `component`.
|
|
113
|
+
- **Escopo:** em um repositório git, só o que o git considera parte do projeto (rastreados + novos não ignorados), então o que está no `.gitignore` não entra. Fora do git, ou com `BRITO_INDEX_IGNORED=1`, indexa por glob (ainda sem `node_modules`, `dist`, `build`, `target`, `vendor`, `obj`, `.gradle`, `.venv`, `.brito`).
|
|
114
|
+
- **Imports:** relativos e por alias. Resolve `paths`/`baseUrl` do `tsconfig.json`/`jsconfig.json` (seguindo `extends` relativo, como o `.svelte-kit/tsconfig.json`), `imports` do `package.json` (`#interno/*`) e o `$lib` do SvelteKit. A configuração vale por arquivo (a mais próxima), então monorepos funcionam; editar um tsconfig reindexa os arquivos afetados.
|
|
115
|
+
- **Linguagens de backend:** o grafo guarda classes/interfaces/structs/traits/enums/módulos, funções e métodos (`Classe.metodo`), chamadas e imports. Nelas o import nomeia um pacote, não um caminho; o Brito casa o especificador com o final do caminho dos seus arquivos (`com.acme.Repo` ↔ `src/main/java/com/acme/Repo.java`; namespaces PSR-4 do PHP; `use crate::…` do Rust; `require`/`require_relative` do Ruby; pacotes Go pelo módulo do `go.mod`). Pacote externo (`java.util`, `serde`, `github.com/gin-gonic/gin`) nunca casa e não gera aresta. Não há inferência de tipos: `userRepository.save()` é ligado casando o nome do receptor com um tipo do projeto (`UserRepository`), `this`/`self`/receiver resolvem para a classe que contém a chamada, e uma chamada solta dentro de classe tenta primeiro os métodos da própria classe.
|
|
116
|
+
- **Ainda não:** `extends` por pacote (`@tsconfig/node20`), `exports` de workspaces vizinhos e referências de função sem chamada em um template (`onclick={fn}`). As chamadas são resolvidas estaticamente, com fallback por nome, então despacho dinâmico e reflexão não são capturados.
|
|
117
|
+
|
|
118
|
+
## Bancos de dados e outros recursos sensíveis
|
|
119
|
+
|
|
120
|
+
O Brito **não tem drivers de banco e não se conecta a nada sozinho**. Quando precisa mexer em um banco, usa as ferramentas do próprio projeto pelo shell, sob o modo de permissão que você escolheu. Como cada projeto é diferente (um arquivo local, um servidor remoto, um container), declare as partes sensíveis no `BRITO.md` (ou `CLAUDE.md` / `AGENTS.md`), que é lido para o system prompt:
|
|
121
|
+
|
|
122
|
+
```markdown
|
|
123
|
+
## Recursos protegidos
|
|
124
|
+
- Banco: arquivo SQLite local `local.db` (nunca commitar, nunca recriar).
|
|
125
|
+
Teste mudanças destrutivas numa cópia: `cp local.db /tmp/teste.db` e aponte `DATABASE_URL`.
|
|
126
|
+
Mudanças de schema: só aditivas, com backup antes (`cp local.db backups/pre-mudanca.db`).
|
|
127
|
+
- Postgres de staging: a connection string está em `$STAGING_DATABASE_URL` (papel somente leitura). Nunca toque em produção.
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
- Credenciais nunca pertencem a skills ou notas: o lint as rejeita. Cite o **nome** da variável de ambiente.
|
|
131
|
+
- Prefira papéis somente leitura e ambientes que não sejam de produção ao dar acesso a banco para um agente.
|
|
132
|
+
- Uma skill proposta que contém comando destrutivo é destacada na revisão, para você decidir se precisa de uma guarda (backup, cópia, confirmação).
|
|
133
|
+
|
|
134
|
+
## Configuração
|
|
135
|
+
|
|
136
|
+
`BRITO_MODEL`, `BRITO_EFFORT`, `BRITO_EXPLORE_MODEL`, `BRITO_LEARN_MODEL`, `BRITO_HOME` (onde ficam skills globais e histórico), `BRITO_CONFIG`, `BRITO_COLOR`, `BRITO_BANNER` (`compact` ou `full`; padrão: tela cheia em janelas de 95+ colunas e 28+ linhas), `BRITO_INDEX_IGNORED`, `BRITO_SKILL_MIN_TOOLS` (tamanho mínimo do turno para disparar a reflexão quando nada mais dispara).
|
|
137
|
+
|
|
138
|
+
Os dados do projeto ficam em `.brito/` (grafo, skills do projeto, agentes) e os globais em `~/.brito`. O grafo, a memória e as skills ficam na sua máquina; como em qualquer agente de código, o código que o modelo lê é enviado ao provedor de modelo que você configurou.
|
|
139
|
+
|
|
140
|
+
## Limitações
|
|
141
|
+
|
|
142
|
+
- Software em fase inicial (v0.3.1), um mantenedor.
|
|
143
|
+
- **A interface e o idioma padrão do agente são português do Brasil.** Traduzi-los é uma contribuição bem-vinda.
|
|
144
|
+
- O aprendizado de skills é heurístico: ele propõe, você decide. Espere rejeitar algumas propostas.
|
|
145
|
+
|
|
146
|
+
## Desenvolvimento
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
git clone https://github.com/wilsonbrito/brito && cd brito
|
|
150
|
+
npm install
|
|
151
|
+
npm run dev # roda via tsx
|
|
152
|
+
npm run typecheck
|
|
153
|
+
npm test # 190+ testes, incluindo um servidor MCP real e um REPL real
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
| Caminho | O quê |
|
|
157
|
+
|---|---|
|
|
158
|
+
| `src/graph/` | indexador (tree-sitter), suporte a `.svelte/.vue/.astro`, aliases de import, store Kùzu |
|
|
159
|
+
| `src/skills/` | store, lint, reflexão, journal, consolidação |
|
|
160
|
+
| `src/agent/` | loop do agente, prompts, subagentes, backend da CLI `claude` |
|
|
161
|
+
| `src/tools/` | tools de grafo, memória, skills, arquivos e shell |
|
|
162
|
+
| `src/mcp/` | servidor MCP |
|
|
163
|
+
| `src/repl.ts`, `src/ui/` | interface de terminal |
|
|
164
|
+
|
|
165
|
+
## Licença
|
|
166
|
+
|
|
167
|
+
[PolyForm Noncommercial 1.0.0](LICENSE): uso, estudo e modificação livres para qualquer fim não comercial (uso pessoal, pesquisa, educação, hobby, ONGs). Uso comercial não é permitido. É código disponível (source-available), não open source pela definição da OSI. Precisa de licença comercial? Abra uma issue.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { parseFrontmatter } from "../util/frontmatter.js";
|
|
4
|
+
import { ui } from "../ui/ui.js";
|
|
5
|
+
const READ_TOOLS = ["read_file", "glob", "grep", "graph_search", "graph_callers", "graph_callees", "graph_impact", "graph_context", "graph_query", "recall"];
|
|
6
|
+
const BUILTIN = [
|
|
7
|
+
{
|
|
8
|
+
name: "explore",
|
|
9
|
+
description: "Somente leitura e rápido. Localiza código, mapeia fluxos e responde 'onde/como/quem chama' usando o grafo. Não edita nada.",
|
|
10
|
+
tools: READ_TOOLS,
|
|
11
|
+
model: process.env.BRITO_EXPLORE_MODEL ?? "claude-haiku-4-5-20251001",
|
|
12
|
+
prompt: "Você é um agente de exploração de código. Descubra o que foi pedido com o mínimo de leitura: comece pelo grafo (graph_search/graph_context/graph_callers/graph_callees), leia só os trechos apontados. Entregue achados com caminhos `arquivo:linha`, sem despejar código longo.",
|
|
13
|
+
source: "builtin",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "plan",
|
|
17
|
+
description: "Somente leitura. Analisa impacto e devolve um plano de implementação passo a passo (arquivos, símbolos, riscos). Não edita nada.",
|
|
18
|
+
tools: READ_TOOLS,
|
|
19
|
+
prompt: "Você é um arquiteto de software. Investigue via grafo (graph_context, graph_callers, graph_impact) e devolva um plano: passos ordenados, arquivos e símbolos a alterar, o que pode quebrar (impacto) e como verificar. Não implemente.",
|
|
20
|
+
source: "builtin",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: "general",
|
|
24
|
+
description: "Executa uma tarefa completa e isolada, incluindo editar arquivos e rodar comandos (pede aprovação ao usuário). Use para sub-tarefas grandes que sujariam o seu contexto.",
|
|
25
|
+
tools: "all",
|
|
26
|
+
prompt: "Você é um agente de engenharia de software. Execute a tarefa até o fim, verifique o resultado (typecheck/testes quando existirem) e reporte o que mudou.",
|
|
27
|
+
source: "builtin",
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
const agents = new Map();
|
|
31
|
+
for (const a of BUILTIN)
|
|
32
|
+
agents.set(a.name, a);
|
|
33
|
+
export const getAgent = (name) => agents.get(name);
|
|
34
|
+
export const listAgents = () => [...agents.values()];
|
|
35
|
+
/** Agentes de projeto: `.brito/agents/*.md` com frontmatter (name, description, tools, model). */
|
|
36
|
+
export function loadProjectAgents(root) {
|
|
37
|
+
const dir = path.join(root, ".brito", "agents");
|
|
38
|
+
if (!fs.existsSync(dir))
|
|
39
|
+
return [];
|
|
40
|
+
const loaded = [];
|
|
41
|
+
for (const f of fs.readdirSync(dir).filter((x) => x.endsWith(".md"))) {
|
|
42
|
+
const fm = parseFrontmatter(fs.readFileSync(path.join(dir, f), "utf8"));
|
|
43
|
+
if (!fm) {
|
|
44
|
+
ui.warn(`agente ignorado (.brito/agents/${f}): frontmatter ausente ou inválido`);
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const { meta, body } = fm;
|
|
48
|
+
const name = meta.name ?? f.replace(/\.md$/, "");
|
|
49
|
+
if (!meta.description || !body.trim()) {
|
|
50
|
+
ui.warn(`agente ignorado (.brito/agents/${f}): precisa de description e corpo`);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const def = {
|
|
54
|
+
name,
|
|
55
|
+
description: meta.description,
|
|
56
|
+
tools: meta.tools ? meta.tools.split(",").map((t) => t.trim()).filter(Boolean) : "all",
|
|
57
|
+
model: meta.model || undefined,
|
|
58
|
+
prompt: body.trim(),
|
|
59
|
+
source: "project",
|
|
60
|
+
};
|
|
61
|
+
agents.set(name, def);
|
|
62
|
+
loaded.push(def);
|
|
63
|
+
}
|
|
64
|
+
return loaded;
|
|
65
|
+
}
|