id = "otty" name = "Otty" homepage = "https://otty.sh" description = "A native, beautiful terminal app." # Otty's own mark, as otty.sh publishes it — the same file this site already # serves as its favicon (web/src/otty-face.svg, copied from the Otty repo's # packages/homepage-web/public/otty-face.svg). icon = "https://otty.sh/otty-face.svg" # `otty` is the command-line tool (`otty ssh …`, `otty jump …`). On macOS the # bundle's executables are Otty.app/Contents/MacOS/Otty and otty-cli, on this # machine. executables = ["otty"] [dotfiles] # No `platforms`: Otty ships for macOS, Linux and Windows. # https://doc.otty.sh/customization/config-file — "Where it is: # ~/.config/otty/config.toml". The directory is Config::config_dir() in the # Otty repo (packages/config/src/lib.rs): `~/.config/otty` "on every platform", # with `~` resolved through %USERPROFILE% on Windows — "deliberately NOT # %APPDATA%" — and $XDG_CONFIG_HOME never consulted. So these are literal `~/` # paths. [configHome] would have followed $XDG_CONFIG_HOME on macOS and Linux # and meant %APPDATA%\otty on Windows, and Otty opens neither. # # The list is the one Otty's own Data Sync carries (otty_scope.rs in # packages/sync-dotfiles): # config.toml — the settings, flat `key = value` # themes/ — "drop custom .toml themes into ~/.config/otty/themes/" # (https://doc.otty.sh/reference/configuration) # recipes/ — saved recipes, .ottyrecipe # (views/recipe/store.rs in packages/app-linux-gpui) # profiles/ — one launch profile per file, .toml # (packages/config/src/profile.rs) # views/ — "names the view's folder under ~/.config/otty/views/" # (https://doc.otty.sh/reference/configuration) # ssh_config — Otty's own SSH hosts, read by `otty ssh` # (packages/cli/src/commands/ssh.rs) # fonts/ — fonts added through Settings paths = [ "~/.config/otty/config.toml", "~/.config/otty/themes/", "~/.config/otty/recipes/", "~/.config/otty/profiles/", "~/.config/otty/views/", "~/.config/otty/ssh_config", "~/.config/otty/fonts/", ] # fonts/font-*.png are the Settings panel's preview renders of each font — # regenerated on demand, so not worth a byte of sync. Otty's own sync leaves # them out for the same reason. Machine state (state.db, logs) lives in a # separate directory, never under ~/.config/otty. exclude = [ "~/.config/otty/fonts/font-*.png", ] # No credential files are included. secret = [] # https://doc.otty.sh/customization/config-file, "Reloading": "Saving the file # applies the changes immediately to every open window — no restart, no # signal. Otty watches the file and hot-reloads it." side_effect = false # self_sync stays at its default, false: Otty's Data Sync is a consumer of this # catalog, not a second copy of these files kept somewhere else. # The config.toml keys that describe this machine rather than the user's taste # — the nine Otty's own sync holds back (MACHINE_KEYS in otty_scope.rs): apps # installed here, hotkeys registered here, panel and window sizes for this # display, what this keyboard's Option key does, which local shells skip # integration, and the shell binary to launch. # # prefix, not key_path. config.toml is TOML's flat subset but not strict TOML: # open-with-app repeats, one line per app, and a strict parser rejects the # duplicate key. Otty matches the whole key, though, and a bare "command" # prefix would also catch any longer key that starts with it. So each key is # written twice — followed by a space, and followed directly by `=` — which is # exactly the lines that set that key, since Otty's reader takes either # spelling (https://doc.otty.sh/reference/config-file-format: "Whitespace # around `=` is optional"). Otty also holds back its own # `# key = value (reset to default)` markers for these keys; those are # comments, so they are left out. # # No scope: Otty keeps these lines in a local overlay and never uploads them, # which is `local`, the default. [[dotfiles.machine_lines]] file = "~/.config/otty/config.toml" match = { prefix = [ "open-with-app ", "open-with-app=", "global-hotkey-open-window ", "global-hotkey-open-window=", "global-hotkey-toggle-visibility ", "global-hotkey-toggle-visibility=", "sidebar-width ", "sidebar-width=", "details-panel-width ", "details-panel-width=", "window-columns ", "window-columns=", "macos-option-as-alt ", "macos-option-as-alt=", "shell-integration-disabled-shells ", "shell-integration-disabled-shells=", "command ", "command=", ] } # A launch profile's shell, working directory and environment are the user's # own choices, but they name paths on this disk. Worth keeping so the user can # see and restore them, not worth applying to a machine whose disk differs: # backup, as Otty's own rule has it. # # Two departures from Otty's rule, both forced: # - Otty names profiles/*.toml. A rule here names a literal file (the fixture # check does not expand globs, and no entry uses one), so this is the profile # Otty seeds on macOS and Linux, profiles/login-shell.toml # (platform_seeds() in packages/config/src/profile.rs). Profiles the user # adds, and the ones Windows seeds per discovered shell, are not reached. # - The keys sit under `[launch]` in the file Otty writes (LaunchSection in the # same file), so the paths are launch.shell, launch.cwd and launch.env. [[dotfiles.machine_lines]] file = "~/.config/otty/profiles/login-shell.toml" match = { key_path = ["launch.shell", "launch.cwd", "launch.env"] } scope = "backup" # ssh_config(5) syntax. IdentityFile, ProxyCommand, ProxyJump and Include name # keys, commands, hosts and files that exist on this machine. Keep them # readable, never push them onto another host: backup, as Otty's own rule has # it. [[dotfiles.machine_lines]] file = "~/.config/otty/ssh_config" match = { prefix = ["IdentityFile", "ProxyCommand", "ProxyJump", "Include"] } scope = "backup" [commands] format = 1 label = "Otty" description = "Open files or URLs inside an Otty pane. Other subcommands are left out." quality = "ai-draft" base = "fig:otty" parser = { end_of_options = "--", interleave = "permute", long_equals = true, short_attached = true, short_bundles = false } [[commands.source]] id = "fig" kind = "completion" url = "https://github.com/withfig/autocomplete/blob/master/src/otty.ts" license = "MIT" [[commands.subcommand]] path = ["view"] label = "View a file or URL" description = "Open a file or http(s) URL in a pane, read-only by default." [[commands.subcommand.source]] id = "fig" kind = "completion" url = "https://github.com/withfig/autocomplete/blob/master/src/otty.ts" license = "MIT" [[commands.subcommand.field]] id = "target" label = "File or URL" type = "path" position = 0 path = { kind = "any", role = "input", must_exist = false } sources = ["fig"] [[commands.subcommand.field]] id = "mode" label = "Mode" type = "enum" option = ["--mode"] choices = [{ value = "view", label = "View" }, { value = "edit", label = "Edit" }] sources = ["fig"] [[commands.subcommand.field]] id = "new_tab" label = "New tab" type = "boolean" option = ["--new-tab"] sources = ["fig"] [[commands.subcommand.field]] id = "new_window" label = "New window" type = "boolean" option = ["--new-window"] sources = ["fig"] [[commands.subcommand.field]] id = "left" label = "Split left" type = "boolean" option = ["--left"] sources = ["fig"] [[commands.subcommand.field]] id = "right" label = "Split right" type = "boolean" option = ["--right"] sources = ["fig"] [[commands.subcommand.field]] id = "top" label = "Split top" type = "boolean" option = ["--top"] sources = ["fig"] [[commands.subcommand.field]] id = "bottom" label = "Split bottom" type = "boolean" option = ["--bottom"] sources = ["fig"] [[commands.subcommand.task]] id = "view" label = "View" fields = ["target", "mode", "new_tab", "new_window"] required = ["target"] [[commands.subcommand.task]] id = "split" label = "Open in a split" fields = ["target", "left", "right", "top", "bottom"] required = ["target"] [[commands.subcommand.group]] id = "basic" label = "Basic" fields = ["target", "mode", "new_tab", "new_window", "left", "right", "top", "bottom"]