v0.0.5 8e546bd

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

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 477

↑↓ moveenter openesc close