Documentation
¶
Overview ¶
Package repl is the interactive layer: readline input with slash commands, double-Ctrl-C chords, and live-rendered markdown streaming via internal/render.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsCommand ¶
IsCommand reports whether name (without the slash) is a REPL command. Script mode uses it to tell a command it cannot run from text that merely starts with a slash, such as a path.
func UserInterruptSignal ¶
UserInterruptSignal reports the signal the REPL and script mode treat as a stop-the-send interrupt, for a caller wiring its own signal.NotifyContext — main, which has no REPL to subscribe for it.
Types ¶
type Options ¶
type Options struct {
Coder *coder.Coder
Config *config.Config
ModelAlias string // alias of the active model, for /model display
// ResumeNote is a banner line naming what a previous session left pinned,
// "" when nothing was restored. The banner lists the files either way; this
// says where they came from, so restored context is never invisible.
ResumeNote string
// SaveResume records what a resume would restore, called after any command
// that changes it. nil when the session leaves no trace (--no-history), so
// the REPL needs no flag of its own.
SaveResume func(alias string)
// Git enables /undo and /diff; nil outside a repository (--no-git).
Git *gitrepo.Repo
// Sessions is what /session needs from the host: a project's
// conversations and the operations that move between them. nil disables
// the command, which is what a session leaving no trace wants — there is
// nowhere for another conversation to be.
Sessions *SessionOps
// Notes returns the current session notes for /notes. nil disables the
// command.
Notes func() string
// GenerateNotes regenerates notes from the transcript into memory.
// Called by /notes generate. nil when notes are unavailable.
GenerateNotes func(ctx context.Context) error
// DropNotes discards the notes for this session.
DropNotes func()
// MakeClient builds a client when /model switches providers.
MakeClient func(*config.Model) llm.ModelClient
// RefreshCommitMessage rebuilds the git commit-message generator when the
// active model changes. It is nil in sessions without git integration.
RefreshCommitMessage func(*config.Model)
// ConsultScope is how much of the session /consult shows the advisor. The
// zero value is coder.ConsultNothing — the binary sets this from
// --consult-scope, whose default is where the shipped behaviour lives,
// because the ladder's order is what makes `scope >= ConsultFiles` read
// correctly and "none" is the bottom of it.
ConsultScope coder.ConsultScope
// ReloadConfig re-reads config.star for /reload, using the same options as
// the initial load. nil disables /reload.
ReloadConfig func() (*config.Config, error)
// ApplyEgress rebuilds the fetch and search ports from a reloaded config.
// A closure because building them needs the proxy transport and the version
// string, which are the binary's business rather than the REPL's — the same
// reason MakeClient is one. Without it, /reload leaves both ports as they
// were at startup, which is how a proxy fix could be applied, reloaded, and
// silently ignored.
ApplyEgress func(*coder.Coder, *config.Config)
// Rediscover re-runs skill discovery for /reload, reopening the trust
// store so a `strument trust` run in another window takes effect. A
// closure for the same reason ApplyEgress is one: where the trust store
// lives is the binary's business. nil leaves the session's skills alone.
Rediscover func() []skill.Skill
Color bool
HistoryFile string
// Version fills the opening banner's "Strument v…" line.
Version string
// Theme is the color palette; the zero value defaults to DefaultTheme.
Theme render.Theme
// GetSize reports the terminal width for the horizontal rules (and is
// shared with readline so its completion grid wraps at the same width).
// nil falls back to 80 columns.
GetSize func() (width, height int)
Stdin io.Reader // default os.Stdin
Stdout io.Writer // default os.Stdout
Stderr io.Writer // default os.Stderr
// IsTerminal overrides terminal detection (readline renders line
// editing only on real terminals).
IsTerminal func() bool
// StdinIsTerminal reports whether there is someone at the keyboard, and
// gates the two places the harness asks a question mid-turn. nil means
// yes, which is what the tests want and what the REPL assumed before this
// existed.
//
// Separate from IsTerminal, which is about *rendering* and is true only
// when both ends are a terminal. Redirecting output alone — `strument |
// tee log` — leaves a human perfectly able to answer a prompt, and folding
// the two questions together would refuse to ask them.
StdinIsTerminal func() bool
// MakeRaw/ExitRaw override raw-mode handling; readline's default
// operates on the process's stdin, which tests replace with a pty.
MakeRaw func() error
ExitRaw func() error
// Notify subscribes ch to SIGINT and the user-space interrupt
// (interruptSignal) for the duration of a turn and returns the
// unsubscribe. Default: os/signal.
Notify func(ch chan<- os.Signal) (stop func())
// Exit ends the process on the second in-turn Ctrl-C. Default: os.Exit.
Exit func(code int)
// Now is the chord clock. Default: time.Now.
Now func() time.Time
// RunEditor opens argv — an editor command with the file to edit last —
// and waits for it, for /editor and Ctrl-X Ctrl-E. Default: editor.Run.
RunEditor func(argv []string) error
}
Options configures a REPL. Zero values mean production defaults; the seams (Stdin/Stdout, IsTerminal, Notify, Exit, Now) exist for the pty tests.
type REPL ¶
type REPL struct {
// contains filtered or unexported fields
}
REPL is the interactive session driver.
func New ¶
New builds the REPL, wires the coder's Out to the live renderer, and prepares readline. Close releases the terminal.
func (*REPL) Asker ¶
Asker returns a coder.Asker that asks questions on this REPL's terminal. Unlike Confirmer there is no AutoConfirmer to wrap it in: --yes and --yes answers permission prompts, and a question is not one.
func (*REPL) Config ¶
Config is the configuration the session is running on now: the one it started with, or the last one /reload read. Code outside the REPL that was handed the startup config holds a copy /reload never touches.
type SessionOps ¶
type SessionOps struct {
// Current is the conversation in use.
Current func() string
// List is every conversation the project holds, newest use first.
List func() ([]history.Session, error)
// Switch opens another conversation; create says whether it is expected
// to be new. It returns the lines to show.
//
// alias is the model alias the user typed, which the REPL owns because
// /model changes it. The host writes it into the new session's record
// header and its resume file, and has no other way to know it.
Switch func(name string, create bool, alias string) (string, error)
// Fork starts a new conversation carrying this one's notes.
Fork func(name, alias string) (string, error)
// Rename renames one, following the process into it when it is the one in
// use.
Rename func(from, to string) error
// Delete removes one that is not in use.
Delete func(name string) error
}
SessionOps are the host's session operations, for /session.
The REPL knows a conversation by name and nothing else. Where one lives, what it restores and how its record is opened are the host's, for the same reason SaveResume and GenerateNotes are: neither the coder nor the REPL learns the layout of the state directory.