v0.0.21 4dde650

args.go RawHistoryFolder

1package agent
2
3import (
4	"fmt"
5	"os"
6	"strings"
7)
8
9// Mode is the CLI run mode.
10type Mode string
11
12const (
13	ModeInteractive Mode = "interactive"
14	ModePrint       Mode = "print"
15	ModeJSON        Mode = "json"
16	ModeRPC         Mode = "rpc"
17)
18
19// Args holds parsed command-line options.
20type Args struct {
21	Mode     Mode
22	Provider string
23	Model    string
24	APIKey   string
25
26	BaseURL            string // override provider base URL (for tests/self-hosted)
27	SystemPrompt       string
28	AppendSystemPrompt []string
29	Reasoning          string
30
31	Continue bool
32	Resume   bool
33	Session  string
34	NoSess   bool
35
36	CWD      string
37	NoTools  bool
38	Tools    []string
39	MaxSteps int
40
41	ListModels bool
42	Help       bool
43	Version    bool
44
45	Prompt string // concatenated positional args
46}
47
48// ParseArgs parses the process arguments (excluding argv[0]).
49func ParseArgs(in []string) (Args, error) {
50	a := Args{Mode: ModeInteractive, MaxSteps: 50}
51	positional := []string{}
52
53	want := func(i *int, flag string) (string, error) {
54		*i++
55		if *i >= len(in) {
56			return "", fmt.Errorf("%s requires a value", flag)
57		}
58		return in[*i], nil
59	}
60
61	for i := 0; i < len(in); i++ {
62		arg := in[i]
63		switch arg {
64		case "-h", "--help":
65			a.Help = true
66		case "-v", "--version":
67			a.Version = true
68		case "-p", "--print":
69			a.Mode = ModePrint
70		case "--json":
71			a.Mode = ModeJSON
72		case "--rpc":
73			a.Mode = ModeRPC
74		case "-c", "--continue":
75			a.Continue = true
76		case "-r", "--resume":
77			a.Resume = true
78		case "--no-session":
79			a.NoSess = true
80		case "--no-tools":
81			a.NoTools = true
82		case "--list-models":
83			a.ListModels = true
84		case "--experimental-oauth":
85			// deprecated: subscription login is always available.
86			// accepted silently for backwards compatibility.
87		case "--provider":
88			v, err := want(&i, arg)
89			if err != nil {
90				return a, err
91			}
92			a.Provider = v
93		case "--model":
94			v, err := want(&i, arg)
95			if err != nil {
96				return a, err
97			}
98			a.Model = v
99		case "--api-key":
100			v, err := want(&i, arg)
101			if err != nil {
102				return a, err
103			}
104			a.APIKey = v
105		case "--base-url":
106			v, err := want(&i, arg)
107			if err != nil {
108				return a, err
109			}
110			a.BaseURL = v
111		case "--system-prompt":
112			v, err := want(&i, arg)
113			if err != nil {
114				return a, err
115			}
116			a.SystemPrompt = v
117		case "--append-system-prompt":
118			v, err := want(&i, arg)
119			if err != nil {
120				return a, err
121			}
122			a.AppendSystemPrompt = append(a.AppendSystemPrompt, v)
123		case "--reasoning":
124			v, err := want(&i, arg)
125			if err != nil {
126				return a, err
127			}
128			switch strings.ToLower(v) {
129			case "", "low", "medium", "high":
130				a.Reasoning = strings.ToLower(v)
131			default:
132				return a, fmt.Errorf("--reasoning must be low|medium|high")
133			}
134		case "--session":
135			v, err := want(&i, arg)
136			if err != nil {
137				return a, err
138			}
139			a.Session = v
140		case "--cwd":
141			v, err := want(&i, arg)
142			if err != nil {
143				return a, err
144			}
145			a.CWD = v
146		case "--tools":
147			v, err := want(&i, arg)
148			if err != nil {
149				return a, err
150			}
151			for _, t := range strings.Split(v, ",") {
152				t = strings.TrimSpace(t)
153				if t != "" {
154					a.Tools = append(a.Tools, t)
155				}
156			}
157		case "--max-steps":
158			v, err := want(&i, arg)
159			if err != nil {
160				return a, err
161			}
162			var n int
163			if _, err := fmt.Sscanf(v, "%d", &n); err != nil || n <= 0 {
164				return a, fmt.Errorf("--max-steps must be a positive integer")
165			}
166			a.MaxSteps = n
167		default:
168			if strings.HasPrefix(arg, "-") && arg != "-" {
169				return a, fmt.Errorf("unknown flag %q", arg)
170			}
171			positional = append(positional, arg)
172		}
173	}
174
175	if len(positional) > 0 {
176		a.Prompt = strings.Join(positional, " ")
177	}
178
179	if a.CWD == "" {
180		a.CWD, _ = os.Getwd()
181	}
182	return a, nil
183}
184
185// PrintHelp writes the help text to w (stderr by default).
186func PrintHelp(version string) {
187	fmt.Fprintf(os.Stderr, `zot %s — Yet another coding agent harness.
188
189usage:
190  zot                          interactive tui
191  zot "prompt"                 interactive, pre-filled prompt
192  zot -p "prompt"              print final text, exit
193  zot --json "prompt"          newline-delimited json events, exit
194  zot rpc                      json-rpc loop on stdin/stdout (see docs/rpc.md)
195  zot telegram-bot setup       configure a telegram bot (from BotFather)
196  zot telegram-bot run         foreground bridge (ctrl+c to stop)
197  zot telegram-bot start       background bridge (detached)
198  zot telegram-bot stop        stop the background bridge
199  zot telegram-bot logs [-f]   tail the background bridge's log
200  zot telegram-bot status      config + running state
201  zot telegram-bot reset       forget saved token
202  (short alias: zot tg ...)
203
204flags:
205  --provider  anthropic|openai
206  --model     model id (see --list-models)
207  --api-key   api key for this run (falls back to env and auth.json)
208  --base-url  override provider api base url (for testing/self-hosted)
209
210  --system-prompt TEXT         replace the default system prompt
211  --append-system-prompt TEXT  append to the system prompt (repeatable)
212  --reasoning low|medium|high  enable reasoning on supported models
213
214  -c, --continue               continue the most recent session for this cwd
215  -r, --resume                 pick a session to resume
216  --session PATH               resume a specific session file
217  --no-session                 do not read or write a session file
218
219  --cwd PATH                   treat PATH as the working directory
220  --no-tools                   disable all tools
221  --tools csv                  only enable the listed tools
222
223  --max-steps N                agent loop iteration cap (default 50)
224  --list-models                print known models and exit
225  -h, --help                   this message
226  -v, --version                version info
227`, version)
228}

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