Packages

fnord

0.9.23

AI code archaeology

Current section

221 Versions

Jump to

Compare versions

101 files changed
+10947 additions
-1535 deletions
  @@ -1,4 +1,4 @@
1 - # Fnord
1 + # `fnord`
2 2
3 3 [![Tests | Dialyzer](https://github.com/sysread/fnord/actions/workflows/run-tests.yml/badge.svg)](https://github.com/sysread/fnord/actions/workflows/run-tests.yml)
4 4
  @@ -16,6 +16,8 @@
16 16 `fnord` is a command line tool that uses multiple LLM-powered agents and tools to provide a conversational interface to your codebase, notes, and other (non-binary) files.
17 17 It can be used to generate on-demand tutorials, playbooks, and documentation for your project, as well as to search for examples, explanations, and solutions to problems in your codebase.
18 18
19 + For markdownlint rules and configuration reference, see [the markdownlint documentation](https://github.com/DavidAnson/markdownlint?tab=readme-ov-file). The `.markdownlint.json` file is kept as strict JSON for compatibility with the installed `markdownlint-cli2` parser.
20 +
19 21 ## Why `fnord`?
20 22
21 23 AI-powered tools are limited to the data built into their training data. **RAG (Retrieval-Augmented Generation)** using tool calls can supplement the training data with information, such as your code base, to provide more accurate and relevant answers to your questions.
  @@ -34,12 +36,12 @@ If you've ever pasted multiple files into ChatGPT or worked with it iteratively
34 36 - Improves its research capabilities with each interaction
35 37 - Layered approvals for shell/file operations
36 38 - User integrations
37 - - Skills (reusable agent presets): see [docs/skills.md](docs/skills.md)
39 + - Skills (reusable agent presets): see [docs/user/skills.md](docs/user/skills.md)
38 40 - MCP server support
39 41
40 42 ## Installation
41 43
42 - Fnord is written in [Elixir](https://elixir-lang.org/) and is distributed as an `escript`.
44 + `fnord` is written in [Elixir](https://elixir-lang.org/) and is distributed as an `escript`.
43 45
44 46 - **Install [elixir](https://elixir-lang.org/)**
45 47
  @@ -66,7 +68,7 @@ mix escript.install github sysread/fnord
66 68
67 69 - **Set your OpenAI API key**
68 70
69 - Fnord reads the key from either `FNORD_OPENAI_API_KEY` or `OPENAI_API_KEY`.
71 + `fnord` reads the key from either `FNORD_OPENAI_API_KEY` or `OPENAI_API_KEY`.
70 72 Create or view your keys [here](https://platform.openai.com/api-keys).
71 73
72 74 - **Optional: Install `ripgrep`**
  @@ -103,10 +105,11 @@ If you cancel partway-through (for example, with `Ctrl-C`), you can resume index
103 105
104 106 **Once indexed, `fnord` will automatically reindex while the `ask` command is running if it detects changes to the code base.**
105 107
106 - You can also manually re-index your project at any time to pick up changes.
107 - This is done by running the same command again.
108 + You can also manually re-index your project at any time to pick up changes. This is done by running the same command again.
108 109
109 - `fnord` stores its index under `$HOME/.fnord/projects/<project>`.
110 + `fnord` stores its file index under `$HOME/.fnord/projects/<project>`.
111 +
112 + `fnord` also builds a commit index for semantic search over your repository history. Commits are enumerated starting from `HEAD` and walking back through history. The commit index is stored under `$HOME/.fnord/projects/<project>/commits`. This is _not_ currently exposed via `fnord search`.
110 113
111 114 Note that semantic search requires an existing index. You can still perform text searches via the shell tool (e.g., ripgrep) if installed and approved, but indexing is recommended for full capabilities.
112 115
  @@ -142,12 +145,14 @@ fnord config validation clear --project blarg
142 145
143 146 ### Approval patterns
144 147
145 - For safety, fnord requires approval for shell commands and file operations. You'll be prompted to approve operations as fnord works. To streamline your workflow, you can pre-approve specific commands using regex patterns. See [docs/approval-patterns.md](docs/approval-patterns.md) for details.
148 + For safety, fnord requires approval for shell commands and file operations. You'll be prompted to approve operations as fnord works. To streamline your workflow, you can pre-approve specific commands using regex patterns. See [docs/user/approval-patterns.md](docs/user/approval-patterns.md) for details.
146 149
147 150 ### Search your code base
148 151
149 152 `fnord`'s semantic search is powered by embeddings generated by OpenAI's `text-embedding-3-large` model. The indexing process does a lot more than simply generate embeddings for the contents of your files. It also generates summary documentation for each file as well as an index of all functions, entities, and symbols in each file to enhance semantic matches for common questions and symbols.
150 153
154 + Commit search is available to the assistant as a tool during `fnord ask`. It is not a standalone CLI command; the agent may call it internally to answer questions about your repository history.
155 +
151 156 ```bash
152 157 fnord search --project blarg --query "callers of some_function"
153 158 fnord search --project blarg --query "some_function definition"
  @@ -175,7 +180,7 @@ For rich, accurate results, index your project first.
175 180
176 181 ### Generate answers on-demand
177 182
178 - Fnord uses LLM-powered agents and tool calls to research your question, including semantic search and git tools (read only).
183 + `fnord` uses LLM-powered agents and tool calls to research your question, including semantic search and git tools (read only).
179 184
180 185 ```bash
181 186 fnord ask --project blarg --question "Where is the unit test for some_function?"
  @@ -191,26 +196,26 @@ By default, files are written under `~/fnord/outputs/<project_id>/<slug>.md`.
191 196 The `<slug>` comes from the first line `# Title: ...` in the response.
192 197
193 198 Use `--tee <file>` (or `-t <file>`) to write a plain-text (no ANSI) transcript of the entire `ask` run to a file.
194 - If the file already exists, fnord prompts before overwriting (and fails non-interactively).
199 + If the file already exists, fnord prompts before overwriting in interactive use; non-interactive runs fail and require `--TEE`.
195 200 Use `--TEE <file>` (or `-T <file>`) to overwrite/truncate without prompting.
196 201
197 202 ```bash
198 203 fnord ask --project blarg -S --question "Explain foo's behavior"
199 204 ```
200 205
201 - For advanced options (e.g., unindexed projects, replaying conversations), see [docs/asking-questions.md](docs/asking-questions.md).
206 + For advanced options (e.g., unindexed projects, replaying conversations), see [docs/user/asking-questions.md](docs/user/asking-questions.md).
202 207
203 208 #### Create and manage your fnord doc library
204 209
205 - Fnord builds a persistent document library of your saved responses and learned notes for easy reference as you work.
210 + `fnord` builds a persistent document library of your saved responses and learned notes for easy reference as you work.
206 211
207 212 - Saved outputs (via `--save`) are stored in `~/fnord/outputs/<project_id>/`.
208 213 - View and explore learned notes with `fnord notes`.
209 - - Browse your docs with a markdown viewer (e.g., `glow`). For more, see [docs/asking-questions.md](docs/asking-questions.md) and [docs/learning-system.md](docs/learning-system.md).
214 + - Browse your docs with a markdown viewer (e.g., `glow`). For more, see [docs/user/asking-questions.md](docs/user/asking-questions.md) and [docs/user/learning-system.md](docs/user/learning-system.md).
210 215
211 216 ### Learning over time
212 217
213 - Fnord learns about your project while researching your questions. It saves facts and inferences it makes, building a searchable knowledge base that improves over time. As the knowledge base grows, fnord can answer increasingly complex questions with less research.
218 + `fnord` learns about your project while researching your questions. It saves facts and inferences it makes, building a searchable knowledge base that improves over time. As the knowledge base grows, fnord can answer increasingly complex questions with less research.
214 219
215 220 You can prime this learning process with:
216 221
  @@ -218,7 +223,7 @@ You can prime this learning process with:
218 223 fnord prime --project blarg
219 224 ```
220 225
221 - For managing and viewing learned knowledge, see [docs/learning-system.md](docs/learning-system.md).
226 + For managing and viewing learned knowledge, see [docs/user/learning-system.md](docs/user/learning-system.md).
222 227
223 228 ### Upgrades
224 229
  @@ -231,7 +236,7 @@ fnord upgrade
231 236 Note that this is just a shortcut for:
232 237
233 238 ```bash
234 - mix escript.install github sysread/fnord
239 + mix escript.install --force github sysread/fnord
235 240 ```
236 241
237 242 ### Other commands
  @@ -259,7 +264,7 @@ fnord frobs check --name my_frob
259 264 fnord frobs list
260 265 ```
261 266
262 - Frobs are stored in `~/fnord/tools/`. For implementation details, see [docs/frobs-guide.md](docs/frobs-guide.md).
267 + Frobs are stored in `~/fnord/tools/`. For implementation details, see [docs/user/frobs-guide.md](docs/user/frobs-guide.md).
263 268
264 269 ### MCP support
265 270
  @@ -272,31 +277,31 @@ fnord config mcp add <name> --transport stdio --command ./server
272 277 # Add an HTTP server
273 278 fnord config mcp add <name> --transport http --url https://api.example.com
274 279
275 - # Add with OAuth (auto-configures everything)
280 + # Add with OAuth when the server supports automatic discovery and registration
276 281 fnord config mcp add <name> --transport http --url https://api.example.com --oauth
277 282 fnord config mcp login <name>
278 283 ```
279 284
280 - **Advanced Configuration:** For complete command reference, custom transport options, and manual configuration, see [docs/mcp-advanced.md](docs/mcp-advanced.md).
285 + **Advanced Configuration:** For complete command reference, custom transport options, and manual configuration, see [docs/user/mcp-advanced.md](docs/user/mcp-advanced.md).
281 286
282 287 #### OAuth Authentication
283 288
284 - Fnord supports OAuth2 for MCP servers with automatic discovery and registration:
289 + `fnord` supports OAuth2 for MCP servers, including automatic discovery and registration when the server supports it:
285 290
286 291 ```bash
287 292 fnord config mcp add myserver --transport http --url https://example.com --oauth
288 293 fnord config mcp login myserver
289 294 ```
290 295
291 - For advanced OAuth options, troubleshooting, and security details, see [docs/oauth-advanced.md](docs/oauth-advanced.md).
296 + For advanced OAuth options, troubleshooting, and security details, see [docs/user/oauth-advanced.md](docs/user/oauth-advanced.md).
292 297
293 298 ## Writing code
294 299
295 - Fnord can (optionally) automate code changes in your project using the `ask` command with the `--edit` flag.
300 + `fnord` can (optionally) automate code changes in your project using the `ask` command with the `--edit` flag.
296 301
297 302 - Use `--edit` with extreme caution.
298 303 - AI-driven code modification is unsafe, may corrupt or break files, and must always be manually reviewed.
299 - - Optionally add `--yes` to pre-approve edits without prompting.
304 + - Optionally add `--yes` to auto-confirm edit prompts. In fnord-managed worktrees, it also skips the interactive post-session review and attempts the usual merge-and-cleanup flow automatically.
300 305
301 306 ### How it works
302 307
  @@ -307,7 +312,7 @@ It *cannot* perform write operations with `git` or act on files outside of the p
307 312 fnord ask --project myproj --edit --question "Add a docstring to foo/thing.ex"
308 313 ```
309 314
310 - **You can also use `--worktree` to specify a git worktree path to operate within.**
315 + **In git repositories, fnord requires worktree-backed editing. Use `--worktree` to point fnord at an existing git worktree directory for the current run; edits are applied there instead of the main checkout.**
311 316
312 317 ```bash
313 318 fnord ask --project myproj --worktree /path/to/myproj-wt --edit --question "Add a docstring to foo/thing.ex"
  @@ -1,6 +1,6 @@
1 1 {<<"links">>,[{<<"GitHub">>,<<"https://github.com/sysread/fnord">>}]}.
2 2 {<<"name">>,<<"fnord">>}.
3 - {<<"version">>,<<"0.9.22">>}.
3 + {<<"version">>,<<"0.9.23">>}.
4 4 {<<"description">>,<<"AI code archaeology">>}.
5 5 {<<"elixir">>,<<"~> 1.19">>}.
6 6 {<<"app">>,<<"fnord">>}.
  @@ -56,6 +56,11 @@
56 56 {<<"optional">>,false},
57 57 {<<"requirement">>,<<"~> 0.1">>},
58 58 {<<"repository">>,<<"hexpm">>}],
59 + [{<<"name">>,<<"yaml_elixir">>},
60 + {<<"app">>,<<"yaml_elixir">>},
61 + {<<"optional">>,false},
62 + {<<"requirement">>,<<"~> 2.9">>},
63 + {<<"repository">>,<<"hexpm">>}],
59 64 [{<<"name">>,<<"plug_cowboy">>},
60 65 {<<"app">>,<<"plug_cowboy">>},
61 66 {<<"optional">>,false},
  @@ -66,27 +71,35 @@
66 71 <<"lib/ui/queue.ex">>,<<"lib/ui/formatter.ex">>,<<"lib/ui/tee.ex">>,
67 72 <<"lib/ui/output">>,<<"lib/ui/output/production.ex">>,
68 73 <<"lib/ui/output.ex">>,<<"lib/util.ex">>,<<"lib/cmd">>,<<"lib/cmd/ask.ex">>,
69 - <<"lib/cmd/notes.ex">>,<<"lib/cmd/upgrade.ex">>,<<"lib/cmd/config">>,
70 - <<"lib/cmd/config/mcp">>,<<"lib/cmd/config/mcp/check_formatter.ex">>,
74 + <<"lib/cmd/worktree_lifecycle.ex">>,<<"lib/cmd/notes.ex">>,
75 + <<"lib/cmd/upgrade.ex">>,<<"lib/cmd/config">>,<<"lib/cmd/config/mcp">>,
76 + <<"lib/cmd/config/mcp/check_formatter.ex">>,
71 77 <<"lib/cmd/config/mcp/login.ex">>,<<"lib/cmd/config/mcp/status.ex">>,
72 - <<"lib/cmd/config/approvals.ex">>,<<"lib/cmd/config/validation.ex">>,
73 - <<"lib/cmd/config/mcp.ex">>,<<"lib/cmd/config/utils.ex">>,
74 - <<"lib/cmd/prime.ex">>,<<"lib/cmd/files.ex">>,<<"lib/cmd/config.ex">>,
75 - <<"lib/cmd/memory.ex">>,<<"lib/cmd/index.ex">>,<<"lib/cmd/skills.ex">>,
76 - <<"lib/cmd/frobs.ex">>,<<"lib/cmd/torch.ex">>,<<"lib/cmd/projects.ex">>,
77 - <<"lib/cmd/conversations.ex">>,<<"lib/cmd/summary.ex">>,
78 - <<"lib/cmd/replay.ex">>,<<"lib/cmd/search.ex">>,<<"lib/settings">>,
79 - <<"lib/settings/approvals.ex">>,<<"lib/settings/skills.ex">>,
80 - <<"lib/settings/frobs.ex">>,<<"lib/settings/migrate.ex">>,
81 - <<"lib/settings/validation.ex">>,<<"lib/settings/mcp.ex">>,
82 - <<"lib/settings/approvals">>,<<"lib/settings/approvals/regex_matcher.ex">>,
83 - <<"lib/ui.ex">>,<<"lib/patchwork.ex">>,<<"lib/notifier.ex">>,
84 - <<"lib/memory">>,<<"lib/memory/session.ex">>,
85 - <<"lib/memory/scope_policy.ex">>,<<"lib/memory/file_store.ex">>,
86 - <<"lib/memory/global.ex">>,<<"lib/memory/migration.ex">>,
87 - <<"lib/memory/project.ex">>,<<"lib/memory/presentation.ex">>,<<"lib/util">>,
88 - <<"lib/util/duration.ex">>,<<"lib/util/env.ex">>,<<"lib/util/temp.ex">>,
89 - <<"lib/store.ex">>,<<"lib/resolve_project.ex">>,<<"lib/services.ex">>,
78 + <<"lib/cmd/config/external_configs.ex">>,<<"lib/cmd/config/approvals.ex">>,
79 + <<"lib/cmd/config/validation.ex">>,<<"lib/cmd/config/mcp.ex">>,
80 + <<"lib/cmd/config/utils.ex">>,<<"lib/cmd/prime.ex">>,<<"lib/cmd/files.ex">>,
81 + <<"lib/cmd/config.ex">>,<<"lib/cmd/memory.ex">>,<<"lib/cmd/index.ex">>,
82 + <<"lib/cmd/skills.ex">>,<<"lib/cmd/frobs.ex">>,<<"lib/cmd/torch.ex">>,
83 + <<"lib/cmd/projects.ex">>,<<"lib/cmd/conversations.ex">>,
84 + <<"lib/cmd/worktrees.ex">>,<<"lib/cmd/summary.ex">>,<<"lib/cmd/replay.ex">>,
85 + <<"lib/cmd/search.ex">>,<<"lib/settings">>,
86 + <<"lib/settings/external_configs.ex">>,<<"lib/settings/approvals.ex">>,
87 + <<"lib/settings/skills.ex">>,<<"lib/settings/frobs.ex">>,
88 + <<"lib/settings/migrate.ex">>,<<"lib/settings/validation.ex">>,
89 + <<"lib/settings/mcp.ex">>,<<"lib/settings/approvals">>,
90 + <<"lib/settings/approvals/regex_matcher.ex">>,<<"lib/ui.ex">>,
91 + <<"lib/patchwork.ex">>,<<"lib/notifier.ex">>,<<"lib/memory">>,
92 + <<"lib/memory/session.ex">>,<<"lib/memory/scope_policy.ex">>,
93 + <<"lib/memory/file_store.ex">>,<<"lib/memory/global.ex">>,
94 + <<"lib/memory/migration.ex">>,<<"lib/memory/project.ex">>,
95 + <<"lib/memory/presentation.ex">>,<<"lib/util">>,<<"lib/util/duration.ex">>,
96 + <<"lib/util/env.ex">>,<<"lib/util/temp.ex">>,<<"lib/store.ex">>,
97 + <<"lib/resolve_project.ex">>,<<"lib/services.ex">>,
98 + <<"lib/external_configs">>,<<"lib/external_configs/injector.ex">>,
99 + <<"lib/external_configs/catalog.ex">>,<<"lib/external_configs/skill.ex">>,
100 + <<"lib/external_configs/cursor_rule.ex">>,
101 + <<"lib/external_configs/frontmatter.ex">>,
102 + <<"lib/external_configs/agent.ex">>,<<"lib/external_configs/loader.ex">>,
90 103 <<"lib/timed.ex">>,<<"lib/cmd.ex">>,<<"lib/git_cli.ex">>,<<"lib/mcp">>,
91 104 <<"lib/mcp/supervisor.ex">>,<<"lib/mcp/util.ex">>,
92 105 <<"lib/mcp/endpoint_discovery.ex">>,<<"lib/mcp/fnord_client.ex">>,
  @@ -98,11 +111,12 @@
98 111 <<"lib/mcp/oauth2/discovery.ex">>,<<"lib/mcp/transport.ex">>,
99 112 <<"lib/mcp/stdio_wrapper.ex">>,<<"lib/memory.ex">>,<<"lib/frobs">>,
100 113 <<"lib/frobs/prompt.ex">>,<<"lib/frobs/migrate.ex">>,<<"lib/skills.ex">>,
101 - <<"lib/search">>,<<"lib/search/files.ex">>,
114 + <<"lib/search">>,<<"lib/search/files.ex">>,<<"lib/search/commits.ex">>,
102 115 <<"lib/search/conversations.ex">>,<<"lib/README.md">>,<<"lib/frobs.ex">>,
103 116 <<"lib/browser">>,<<"lib/browser/default.ex">>,<<"lib/spinner.ex">>,
104 117 <<"lib/ai">>,<<"lib/ai/util.ex">>,<<"lib/ai/splitter.ex">>,
105 - <<"lib/ai/tools.ex">>,<<"lib/ai/tools">>,<<"lib/ai/tools/ui">>,
118 + <<"lib/ai/tools.ex">>,<<"lib/ai/tools">>,<<"lib/ai/tools/commit">>,
119 + <<"lib/ai/tools/commit/search.ex">>,<<"lib/ai/tools/ui">>,
106 120 <<"lib/ai/tools/ui/ask.ex">>,<<"lib/ai/tools/ui/choose.ex">>,
107 121 <<"lib/ai/tools/ui/confirm.ex">>,<<"lib/ai/tools/conversation.ex">>,
108 122 <<"lib/ai/tools/tasks">>,<<"lib/ai/tools/tasks/push_task.ex">>,
  @@ -113,9 +127,8 @@
113 127 <<"lib/ai/tools/tasks/show_list.ex">>,<<"lib/ai/tools/notify.ex">>,
114 128 <<"lib/ai/tools/coder.ex">>,<<"lib/ai/tools/notes.ex">>,
115 129 <<"lib/ai/tools/file">>,<<"lib/ai/tools/file/edit.ex">>,
116 - <<"lib/ai/tools/file/notes.ex">>,<<"lib/ai/tools/file/spelunker.ex">>,
117 - <<"lib/ai/tools/file/list.ex">>,<<"lib/ai/tools/file/contents.ex">>,
118 - <<"lib/ai/tools/file/edit">>,
130 + <<"lib/ai/tools/file/notes.ex">>,<<"lib/ai/tools/file/list.ex">>,
131 + <<"lib/ai/tools/file/contents.ex">>,<<"lib/ai/tools/file/edit">>,
119 132 <<"lib/ai/tools/file/edit/whitespace_fitter.ex">>,
120 133 <<"lib/ai/tools/file/edit/omfg.ex">>,<<"lib/ai/tools/file/reindex.ex">>,
121 134 <<"lib/ai/tools/file/info.ex">>,<<"lib/ai/tools/file/search.ex">>,
  @@ -123,12 +136,16 @@
123 136 <<"lib/ai/tools/research.ex">>,<<"lib/ai/tools/memory.ex">>,
124 137 <<"lib/ai/tools/apply_patch.ex">>,<<"lib/ai/tools/web_search.ex">>,
125 138 <<"lib/ai/tools/long_term_memory.ex">>,<<"lib/ai/tools/run_skill.ex">>,
126 - <<"lib/ai/tools/self_help">>,<<"lib/ai/tools/self_help/cli.ex">>,
127 - <<"lib/ai/tools/save_skill.ex">>,<<"lib/ai/tools/list_projects.ex">>,
128 - <<"lib/ai/tools/reviewer.ex">>,<<"lib/ai/notes.ex">>,
129 - <<"lib/ai/completion">>,<<"lib/ai/completion/output.ex">>,
130 - <<"lib/ai/completion/compaction.ex">>,<<"lib/ai/agent">>,
131 - <<"lib/ai/agent/coordinator">>,<<"lib/ai/agent/coordinator/frippery.ex">>,
139 + <<"lib/ai/tools/self_help">>,<<"lib/ai/tools/self_help/docs.ex">>,
140 + <<"lib/ai/tools/self_help/cli.ex">>,<<"lib/ai/tools/save_skill.ex">>,
141 + <<"lib/ai/tools/list_projects.ex">>,<<"lib/ai/tools/reviewer.ex">>,
142 + <<"lib/ai/tools/git">>,<<"lib/ai/tools/git/worktree.ex">>,
143 + <<"lib/ai/embeddings">>,<<"lib/ai/embeddings/migration.ex">>,
144 + <<"lib/ai/embeddings/pool.ex">>,<<"lib/ai/embeddings/script.ex">>,
145 + <<"lib/ai/notes.ex">>,<<"lib/ai/completion">>,
146 + <<"lib/ai/completion/output.ex">>,<<"lib/ai/completion/compaction.ex">>,
147 + <<"lib/ai/agent">>,<<"lib/ai/agent/coordinator">>,
148 + <<"lib/ai/agent/coordinator/frippery.ex">>,
132 149 <<"lib/ai/agent/coordinator/notes.ex">>,
133 150 <<"lib/ai/agent/coordinator/test.ex">>,
134 151 <<"lib/ai/agent/coordinator/tasks.ex">>,
  @@ -138,9 +155,8 @@
138 155 <<"lib/ai/agent/coordinator/glue.ex">>,
139 156 <<"lib/ai/agent/coordinator/intuition.ex">>,<<"lib/ai/agent/memory">>,
140 157 <<"lib/ai/agent/memory/deduplicator.ex">>,
141 - <<"lib/ai/agent/memory/indexer.ex">>,<<"lib/ai/agent/code_mapper.ex">>,
142 - <<"lib/ai/agent/skill.ex">>,<<"lib/ai/agent/coordinator.ex">>,
143 - <<"lib/ai/agent/nomenclater.ex">>,<<"lib/ai/agent/spelunker.ex">>,
158 + <<"lib/ai/agent/memory/indexer.ex">>,<<"lib/ai/agent/skill.ex">>,
159 + <<"lib/ai/agent/coordinator.ex">>,<<"lib/ai/agent/nomenclater.ex">>,
144 160 <<"lib/ai/agent/code">>,<<"lib/ai/agent/code/task_implementor.ex">>,
145 161 <<"lib/ai/agent/code/task_planner.ex">>,
146 162 <<"lib/ai/agent/code/task_validator.ex">>,
  @@ -154,7 +170,8 @@
154 170 <<"lib/ai/agent/review/reviewer.ex">>,<<"lib/ai/agent/review/no_slop.ex">>,
155 171 <<"lib/ai/agent/file_info.ex">>,<<"lib/ai/agent/conversation_qa.ex">>,
156 172 <<"lib/ai/agent/intuition.ex">>,<<"lib/ai/agent/motd.ex">>,
157 - <<"lib/ai/agent/file_summary.ex">>,<<"lib/ai/agent/composite.ex">>,
173 + <<"lib/ai/agent/file_summary.ex">>,
174 + <<"lib/ai/agent/conversation_summary.ex">>,<<"lib/ai/agent/composite.ex">>,
158 175 <<"lib/ai/completion.ex">>,<<"lib/ai/accumulator.ex">>,
159 176 <<"lib/ai/endpoint.ex">>,<<"lib/ai/model.ex">>,<<"lib/ai/embeddings.ex">>,
160 177 <<"lib/ai/completion_api.ex">>,<<"lib/ai/pretend_tokenizer.ex">>,
  @@ -162,22 +179,23 @@
162 179 <<"lib/toml.ex">>,<<"lib/outputs.ex">>,<<"lib/skills">>,
163 180 <<"lib/skills/runtime.ex">>,<<"lib/skills/skill.ex">>,
164 181 <<"lib/skills/toml.ex">>,<<"lib/skills/loader.ex">>,<<"lib/file_lock.ex">>,
165 - <<"lib/browser.ex">>,<<"lib/indexer.ex">>,<<"lib/http.ex">>,
166 - <<"lib/http_pool.ex">>,<<"lib/services">>,<<"lib/services/globals">>,
182 + <<"lib/browser.ex">>,<<"lib/git_cli">>,<<"lib/git_cli/worktree">>,
183 + <<"lib/git_cli/worktree/review.ex">>,<<"lib/git_cli/worktree.ex">>,
184 + <<"lib/indexer.ex">>,<<"lib/http.ex">>,<<"lib/http_pool.ex">>,
185 + <<"lib/services">>,<<"lib/services/globals">>,
167 186 <<"lib/services/globals/spawn.ex">>,<<"lib/services/file_cache.ex">>,
168 187 <<"lib/services/conversation.ex">>,<<"lib/services/background_indexer.ex">>,
169 188 <<"lib/services/globals.ex">>,<<"lib/services/temp_file.ex">>,
170 189 <<"lib/services/bg_indexing_control.ex">>,
171 - <<"lib/services/memory_indexer.ex">>,
172 - <<"lib/services/name_pool.ex.0.0.bak">>,<<"lib/services/notes.ex">>,
173 - <<"lib/services/task.ex">>,<<"lib/services/backup_file.ex">>,
174 - <<"lib/services/name_pool.ex">>,<<"lib/services/skill_depth.ex">>,
175 - <<"lib/services/approvals.ex">>,<<"lib/services/task">>,
176 - <<"lib/services/task/util.ex">>,<<"lib/services/task/list.ex">>,
177 - <<"lib/services/once.ex">>,<<"lib/services/mcp.ex">>,
178 - <<"lib/services/conversation_indexer.ex">>,<<"lib/services/approvals">>,
179 - <<"lib/services/approvals/shell.ex">>,<<"lib/services/approvals/edit.ex">>,
180 - <<"lib/services/approvals/shell">>,
190 + <<"lib/services/memory_indexer.ex">>,<<"lib/services/notes.ex">>,
191 + <<"lib/services/task.ex">>,<<"lib/services/commit_indexer.ex">>,
192 + <<"lib/services/backup_file.ex">>,<<"lib/services/name_pool.ex">>,
193 + <<"lib/services/skill_depth.ex">>,<<"lib/services/approvals.ex">>,
194 + <<"lib/services/task">>,<<"lib/services/task/util.ex">>,
195 + <<"lib/services/task/list.ex">>,<<"lib/services/once.ex">>,
196 + <<"lib/services/mcp.ex">>,<<"lib/services/conversation_indexer.ex">>,
197 + <<"lib/services/approvals">>,<<"lib/services/approvals/shell.ex">>,
198 + <<"lib/services/approvals/edit.ex">>,<<"lib/services/approvals/shell">>,
181 199 <<"lib/services/approvals/shell/prefix.ex">>,
182 200 <<"lib/services/approvals/workflow.ex">>,
183 201 <<"lib/services/approvals/gate.ex">>,<<"lib/services/conversation">>,
  @@ -185,16 +203,16 @@
185 203 <<"lib/validation/rules.ex">>,<<"lib/store">>,<<"lib/store/project">>,
186 204 <<"lib/store/project/conversation.ex">>,
187 205 <<"lib/store/project/conversation_index.ex">>,
188 - <<"lib/store/project/notes.ex">>,<<"lib/store/project/entry">>,
189 - <<"lib/store/project/entry/metadata.ex">>,
206 + <<"lib/store/project/commit_document.ex">>,<<"lib/store/project/notes.ex">>,
207 + <<"lib/store/project/entry">>,<<"lib/store/project/entry/metadata.ex">>,
190 208 <<"lib/store/project/entry/id.ex">>,
191 209 <<"lib/store/project/entry/storage_behaviour.ex">>,
192 210 <<"lib/store/project/entry/summary.ex">>,
193 211 <<"lib/store/project/entry/embeddings.ex">>,
194 - <<"lib/store/project/entry/outline.ex">>,
195 212 <<"lib/store/project/entry/storage.ex">>,
196 213 <<"lib/store/project/entry/migrate_abs_to_rel_path_keys.ex">>,
197 - <<"lib/store/project/entry_file.ex">>,<<"lib/store/project/entry.ex">>,
214 + <<"lib/store/project/source.ex">>,<<"lib/store/project/entry_file.ex">>,
215 + <<"lib/store/project/entry.ex">>,<<"lib/store/project/commit_index.ex">>,
198 216 <<"lib/store/project/files_dir_migration.ex">>,
199 217 <<"lib/store/project/conversation">>,
200 218 <<"lib/store/project/conversation/task_list_status_migration.ex">>,
  @@ -43,6 +43,12 @@ defmodule AI.Agent.Code.Common do
43 43 """
44 44 @spec new(AI.Agent.t(), AI.Model.t(), AI.Tools.toolbox(), binary, binary) :: t
45 45 def new(agent, model, toolbox, system_prompt, user_prompt) do
46 + # Inherit the external-configs catalog from the parent session so
47 + # code sub-agents (planner/implementor/validator) see the same
48 + # skills, rules, and always-apply bodies the coordinator did. Without
49 + # this, sub-agents build fresh message lists that bypass
50 + # Services.Conversation (where the Injector writes), leaving the
51 + # sub-agent LLM rule-blind.
46 52 %__MODULE__{
47 53 agent: agent,
48 54 model: model,
  @@ -51,11 +57,13 @@ defmodule AI.Agent.Code.Common do
51 57 internal: %{},
52 58 response: nil,
53 59 error: nil,
54 - messages: [
60 + messages:
61 + [
55 62 AI.Util.system_msg(AI.Util.project_context()),
56 - AI.Util.system_msg(system_prompt),
57 - AI.Util.user_msg(user_prompt)
58 - ]
63 + AI.Util.system_msg(system_prompt)
64 + ] ++
65 + ExternalConfigs.Catalog.system_messages() ++
66 + [AI.Util.user_msg(user_prompt)]
59 67 }
60 68 end
61 69
  @@ -165,7 +173,7 @@ defmodule AI.Agent.Code.Common do
165 173 - Concrete bug: provide the exact path (caller -> callee), show which preconditions are satisfied, and why a failing state can occur now.
166 174 - Potential issue: if reachability depends on changes or bypassing a guard, label as potential and specify exactly what would have to change.
167 175 - Cite minimal evidence: file paths, symbols, relevant snippets, and the shortest proof chain.
168 - - ALWAYS check for READMEs, CONTRIBUTING files, AGENTS.md, CLAUDE.md, etc., to identify conventions and expectations for the area(s) of the code you are working on.
176 + - At the start of your work, if you have not already done so in this session, check for READMEs, CONTRIBUTING files, AGENTS.md, CLAUDE.md, etc., to identify conventions and expectations for the area(s) of the code you are working on. Do NOT re-read these files during verification or re-orientation passes; once per session is enough. If a file is missing, accept that once and do not retry.
169 177 - Testability and environment rules:
170 178 - Never add test-only branches or functions in production code.
171 179 - Prefer testable structure and DI: extract production helpers or adapters and test through public APIs and injected boundaries (UI, Services, adapters).
  @@ -202,7 +202,7 @@ defmodule AI.Agent.Code.Patcher do
202 202 defp apply_changes(%{changes: []} = state), do: {:ok, state}
203 203
204 204 defp apply_changes(%{changes: [change | remaining], contents: contents} = state) do
205 - UI.report_from(state.agent.name, "Patching #{state.file}", change)
205 + UI.report_from(state.agent.name, "Patching #{AI.Tools.display_path(state.file)}", change)
206 206
207 207 numbered = Util.numbered_lines(contents)
208 208 messages = build_messages(state, numbered, change)
  @@ -1,55 +0,0 @@
1 - defmodule AI.Agent.CodeMapper do
2 - @model AI.Model.fast()
3 -
4 - @prompt """
5 - You are the Code Mapper Agent. You will receive the contents of a code file.
6 - You will generate an outline of the code in the file, identifying symbols like ctags, but in a human-readable format.
7 - Ensure that you capture EVERY module/package, global, constant, class, method, function, and behavior in the file, based on the language's terminology.
8 - For every function, include a list of other functions it calls, including notes about the conditions under which a function calls other functions.
9 - Your organization is hierarchical, and depends on the programming language(s) in the file.
10 - If there is no higher-level organization, use "GLOBAL" as the top-level.
11 - If the example below does not match the terminology of the language in the file being processed, please adapt it to match the language's terminology (for example, the example uses Python, which does not have a <constant> but C does).
12 - If the file is not a code file, respond with a topic outline, including facts discovered within each section.
13 - Do not respond with any explanation or context, just the outline, in text format with no special formatting (just list markers).
14 -
15 - For example, for a Python module, organize the code first by class, then by method:
16 -
17 - - <file> $file_path
18 - - <namespace> GLOBAL
19 - - <variable> DEFAULT_X
20 - - <variable> DEFAULT_Y
21 - - <class> Point
22 - - <attribute> x
23 - - <attribute> y
24 - - <method> __init__(x=None, y=None)
25 - - <reference> DEFAULT_X - when x is None
26 - - <reference> DEFAULT_Y - when y is None
27 - - <method> get_slope(point)
28 - - <call> calculate_slope(point_a, point_b)
29 - - <method> move_to(x, y)
30 - - <call> __init__(x, y) - when (x, y) is not the current position
31 - - <class method> from_string(string)
32 - """
33 -
34 - # -----------------------------------------------------------------------------
35 - # Behaviour implementation
36 - # -----------------------------------------------------------------------------
37 - @behaviour AI.Agent
38 -
39 - @impl AI.Agent
40 - def get_response(opts) do
41 - with {:ok, file} <- Map.fetch(opts, :file),
42 - {:ok, content} <- Map.fetch(opts, :content) do
43 - AI.Accumulator.get_response(
44 - model: @model,
45 - prompt: @prompt,
46 - input: content,
47 - question: "Generate an outline of the code in the file: #{file}"
48 - )
49 - |> then(fn
50 - {:ok, %{response: response}} -> {:ok, response}
51 - {:error, reason} -> {:error, reason}
52 - end)
53 - end
54 - end
55 - end
Loading more files…