detached ce80627

feat(tui): /study slash command to prime the agent on the current project

New built-in /study command that runs a single canned prompt:
"Read and understand everything in the current directory." The
first thing most sessions need is project context, and typing
the full sentence every time is friction; /study turns that
into one keystroke-saving shortcut.

Dispatched through the same queue-or-start path as a typed
prompt, so it behaves identically:

  - idle  -> startTurn(studyPrompt)
  - busy  -> queued behind the running turn, delivered next

Also added to the README slash-commands table so /help output
and the top-level docs stay in sync with slashCatalog.
commit
ce806272e0ee869ce19ff8371e96928b1a8120d9
author
patriceckhart · · 2026-04-21 06:59 UTC
parent
51fd11f
signature
unsigned
refs
tag: v0.0.76
3 files · +18 -0
M README.md +1 -0
@@ -187,6 +187,7 @@ Type `/` in the TUI to open the autocomplete popup. Available commands:
187187 | `/btw` | Side chat with full context that doesn't add to the main thread. |
188188 | `/skills` | List discovered skills (SKILL.md files) and preview their bodies. |
189189 | `/compact` | Summarize the transcript into one message to free up context. |
190+| `/study` | Run the canned prompt "Read and understand everything in the current directory." so the agent has full project context before you start asking targeted questions. |
190191 | `/jail` | Confine tools to the current directory. |
191192 | `/unjail` | Allow tools to touch paths outside again. |
192193 | `/reload-ext` | Hot-reload all extensions (re-read manifests, respawn subprocesses, rebuild tool registry). |
@@ -187,6 +187,7 @@ Type `/` in the TUI to open the autocomplete popup. Available commands:
187 | `/btw` | Side chat with full context that doesn't add to the main thread. |187 | `/btw` | Side chat with full context that doesn't add to the main thread. |
188 | `/skills` | List discovered skills (SKILL.md files) and preview their bodies. |188 | `/skills` | List discovered skills (SKILL.md files) and preview their bodies. |
189 | `/compact` | Summarize the transcript into one message to free up context. |189 | `/compact` | Summarize the transcript into one message to free up context. |
190+| `/study` | Run the canned prompt "Read and understand everything in the current directory." so the agent has full project context before you start asking targeted questions. |
190 | `/jail` | Confine tools to the current directory. |191 | `/jail` | Confine tools to the current directory. |
191 | `/unjail` | Allow tools to touch paths outside again. |192 | `/unjail` | Allow tools to touch paths outside again. |
192 | `/reload-ext` | Hot-reload all extensions (re-read manifests, respawn subprocesses, rebuild tool registry). |193 | `/reload-ext` | Hot-reload all extensions (re-read manifests, respawn subprocesses, rebuild tool registry). |
M internal/agent/modes/interactive.go +16 -0
@@ -1452,6 +1452,22 @@ func (i *Interactive) runSlash(ctx context.Context, cmd string) (done bool) {
14521452 i.openSkillsDialog()
14531453 case "/compact":
14541454 i.runCompact(ctx, false)
1455+ case "/study":
1456+ // Canned prompt that tells the agent to read every file
1457+ // in the current directory so its later turns have the
1458+ // whole project in context. Dispatched through the normal
1459+ // queue-or-start path so it behaves identically to
1460+ // typing the prompt by hand.
1461+ const studyPrompt = "Read and understand everything in the current directory."
1462+ i.mu.Lock()
1463+ if i.busy {
1464+ i.queued = append(i.queued, studyPrompt)
1465+ i.mu.Unlock()
1466+ i.invalidate()
1467+ break
1468+ }
1469+ i.mu.Unlock()
1470+ i.startTurn(ctx, studyPrompt)
14551471 case "/jail":
14561472 if i.cfg.Sandbox == nil {
14571473 i.mu.Lock()
@@ -1452,6 +1452,22 @@ func (i *Interactive) runSlash(ctx context.Context, cmd string) (done bool) {
1452 i.openSkillsDialog()1452 i.openSkillsDialog()
1453 case "/compact":1453 case "/compact":
1454 i.runCompact(ctx, false)1454 i.runCompact(ctx, false)
1455+ case "/study":
1456+ // Canned prompt that tells the agent to read every file
1457+ // in the current directory so its later turns have the
1458+ // whole project in context. Dispatched through the normal
1459+ // queue-or-start path so it behaves identically to
1460+ // typing the prompt by hand.
1461+ const studyPrompt = "Read and understand everything in the current directory."
1462+ i.mu.Lock()
1463+ if i.busy {
1464+ i.queued = append(i.queued, studyPrompt)
1465+ i.mu.Unlock()
1466+ i.invalidate()
1467+ break
1468+ }
1469+ i.mu.Unlock()
1470+ i.startTurn(ctx, studyPrompt)
1455 case "/jail":1471 case "/jail":
1456 if i.cfg.Sandbox == nil {1472 if i.cfg.Sandbox == nil {
1457 i.mu.Lock()1473 i.mu.Lock()
M internal/agent/modes/slash_suggest.go +1 -0
@@ -40,6 +40,7 @@ var slashCatalog = []slashCommand{
4040 {Name: "/session", Desc: "export the current session to a .zotsession file, or import one"},
4141 {Name: "/jump", Desc: "scroll the chat to a previous turn (or /jump <text>)"},
4242 {Name: "/compact", Desc: "summarize and replace the transcript to free up context"},
43+ {Name: "/study", Desc: "read every file in the current directory so the agent has full project context"},
4344 {Name: "/btw", Desc: "side-chat that doesn't add to the main thread (saves tokens)"},
4445 {Name: "/jail", Desc: "confine tools to the current directory"},
4546 {Name: "/skills", Desc: "list discovered skills (SKILL.md files)"},
@@ -40,6 +40,7 @@ var slashCatalog = []slashCommand{
40 {Name: "/session", Desc: "export the current session to a .zotsession file, or import one"},40 {Name: "/session", Desc: "export the current session to a .zotsession file, or import one"},
41 {Name: "/jump", Desc: "scroll the chat to a previous turn (or /jump <text>)"},41 {Name: "/jump", Desc: "scroll the chat to a previous turn (or /jump <text>)"},
42 {Name: "/compact", Desc: "summarize and replace the transcript to free up context"},42 {Name: "/compact", Desc: "summarize and replace the transcript to free up context"},
43+ {Name: "/study", Desc: "read every file in the current directory so the agent has full project context"},
43 {Name: "/btw", Desc: "side-chat that doesn't add to the main thread (saves tokens)"},44 {Name: "/btw", Desc: "side-chat that doesn't add to the main thread (saves tokens)"},
44 {Name: "/jail", Desc: "confine tools to the current directory"},45 {Name: "/jail", Desc: "confine tools to the current directory"},
45 {Name: "/skills", Desc: "list discovered skills (SKILL.md files)"},46 {Name: "/skills", Desc: "list discovered skills (SKILL.md files)"},

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 476

↑↓ moveenter openesc close