turbo-editors/turbo-corepublic Fork 0
main
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

2026-09-15-acp-commands-mentions.md · 37 lines · 4.8 KBmarkdown Blame HistoryRaw
🛟 Updated. 28d5985 k33g 11h ago1# Handoff — 2026-09-15 — `/` commands and `@` mentions in agent windows
2
3## State
4
5**Done, tested, gate green, documented, not committed.** Working tree on `main` (v0.7.0 + this), 12 files changed and 9 new, nothing staged. The five editors carry the documentation and the starter-file change, also uncommitted; their code is unchanged and their suites pass.
6
7What was built: typing `/` as the first character of an agent window's box lists the agent's `available_commands_update` commands with descriptions and hints; typing `@` anywhere lists the project's files. `↑↓` move, `Tab` completes, `Enter` completes-or-sends, `Esc` closes until the text changes, a click takes a line. A command is sent as text (`/web query`); a mention is sent as an embedded `resource` when the agent declared `promptCapabilities.embeddedContext`, a `resource_link` otherwise, in place of the name, with text blocks either side.
8
9## In flight
10
11**Why does mini-me's command list not show?** (2026-09-16.) The user typed `/` in a window on mini-me and saw nothing. Their binary has the feature (checked: `go version -m` shows turbo-core `(devel)`, the label string is in it). Added `TURBO_ACP_TRACE` and the unreadable-update line in Agent status so the next step is possible. **Next step is theirs**: run `TURBO_ACP_TRACE=/tmp/acp.log ./bin/turbo-go`, open mini-me, type a prompt, then open **Agent ▸ Agent status** and send the log. Three outcomes: (1) no `available_commands_update` in the trace → mini-me does not send it over ACP and the question moves to mini-me; (2) it is there and the status says it could not be read → fix the decoding to that shape, and replay it in `fakeagent_test.go`; (3) it is there and decoded → the picker itself, `Session.Commands()` non-empty but `choices()` returning nothing; check `onInput`, `cursor == 0`, single line.
12
13## Next steps
14
151. **Read the diff**`acp/picker.go`, `acp/picker_draw.go`, `acp/mention.go` are new and small; the rest is threading.
162. **Try it against a real agent that announces commands.** The user's `mini-me` (`mm -acp`, `AGENT_CONFIG=…/agent.llamacpp.yaml`) is the obvious one — an `[[agent]]` block for it is `command = "mm"`, `args = ["-acp"]`, `env = { AGENT_CONFIG = "…" }`. Watch for: does its `available_commands_update` arrive before `session/new` returns (the client stores it either way, but the rule label only updates on the next frame), and does it declare `embeddedContext`.
173. **Then the release order**: turbo-core tag → each editor `go get``GOWORK=off make check` → tag. The editors' docs already describe the new behaviour, so they are ahead of the binary until then.
184. Decide about a branch. Previous cycles used `feature/acp`; this one sits on `main` because nobody was there to ask.
19
20## Open questions
21
22- **Should `Enter` on a command that takes input but has none typed send anyway?** It does now (`/web` + `Enter` sends `/web`). Zed inserts and waits. The hint in the popup is the only nudge.
23- **Should the popup also list files when `@` is typed with the transcript focused?** No — the picker is the box's. Nobody has asked.
24- **Is 5 000 files / 200 shown the right cap?** Guessed, not measured. A monorepo will tell.
25
26## Watch out for
27
28- **The picker's list is recomputed on every key and every frame** — `refresh()` is the single entry point and both `handlePickerKey` and `drawPicker` go through it, so the highlighted index can never refer to a different list than the one drawn. If you add a stored list, you will reintroduce exactly the desynchronisation this avoids.
29- **`Files()` is called once per opening of the `@` list, and the answer cached in `picker.files` while the word keeps its `@`.** Calling it per frame walks the project sixty times a second. `refresh()` drops the cache when the word stops being an `@` word.
30- **`HandleKey` wraps everything in a before/after `Input()` comparison** to lift `Esc`'s dismissal. It is cheap (one `strings.Join`) but it runs on every key.
31- **`mentions()` on `Send` consults `fileList()`**, which walks the project if the list is not cached — so a prompt with an `@` word sent without the popup having opened costs one walk. Acceptable; noted.
32- **`cp` is still corrupt for fresh inodes in this sandbox**, and this time recreating the files did not help. `release_test.go` fails on it; nothing else does. Do not chase it as a code defect. Use `cat a > b`, never `cp`.
33- **`drawLine` has seven parameters and the gate did not flag it; `drawChoice` had six and was flagged.** The rule is not simply "> 5" — do not reason from the count alone, run the measurement.
34
35## Never touched by a human
36
37Everything: the popup on a real terminal, its colours under the eight themes, `Tab` vs `Enter` on a real keyboard, a mention of a file with unsaved changes reaching a real agent, a command actually being *answered* by an agent.