From 35b5b09c6d6069d9d7c70406b937dafa9031c1a8 Mon Sep 17 00:00:00 2001 From: Rune Olsen Date: Fri, 14 Aug 2026 10:54:54 +0200 Subject: [PATCH] Harden the CLI Access shell snippet against unquoted glob characters An unquoted prompt containing ?/*/[...] (e.g. `ai Who are you?`) was getting glob-expanded by zsh before the ai() function ever ran, aborting with "no matches found" and never reaching the socket server. A plain function can't protect its own call site from this - filename generation happens during command-line parsing, before the shell dispatches to a function. Switched the recommended snippet to `alias ai='noglob _ai_impl'`, which suppresses globbing for the whole command line via noglob as a precommand modifier. Quoting remains the fully robust habit for other shell metacharacters, but this covers the specific mistake a user is most likely to make by accident. --- oAI/Views/Screens/SettingsView.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/oAI/Views/Screens/SettingsView.swift b/oAI/Views/Screens/SettingsView.swift index a907bba..9ce5b10 100644 --- a/oAI/Views/Screens/SettingsView.swift +++ b/oAI/Views/Screens/SettingsView.swift @@ -1235,13 +1235,21 @@ It's better to admit "I need more information" or "I cannot do that" than to fak } } + // `noglob` (applied via the alias, not inside the function) stops zsh from trying to glob-expand + // an unquoted prompt containing `?`/`*`/`[...]` — e.g. `ai Who are you?` — before `_ai_impl` ever + // runs. A plain `ai() { ... }` function can't protect its own call site this way: filename + // generation happens during command-line parsing, before the shell has even decided this is a + // function call. Quoting the prompt is still the fully robust habit for other shell metacharacters + // (`;`, `|`, backticks, `$()`), but this covers the specific class of crash users are most likely + // to hit by accident (an unquoted question ending in "?"). private static let cliShellFunctionSnippet = """ - ai() { + _ai_impl() { curl -s --unix-socket "$HOME/Library/Application Support/oAI/cli.sock" \\ -H "Content-Type: application/json" \\ -d "$(jq -n --arg p "$*" '{prompt: $p}')" \\ http://localhost/ | jq -r 'if .error then "Error: " + .error else .response end' } + alias ai='noglob _ai_impl' """ private func loadCLIModels() async {