Split the POSIX CLI into modules
linux/claude-mode was 3,035 lines. It is now 177: the paths and flags, a loader, and the command dispatch. Everything else moved, verbatim, into twelve files under linux/lib/, one per concern - output, core, preflight, sessions, switch, catalogue, commands, doctor, presets, menu, setup, repair. The move was done by line range with a check that every original line landed in exactly one file; the only thing that changed place is the switch's running-sessions question, which now sits with session detection. The CLI finds lib/, cm-json.py and cm-vault.sh beside itself, following the ~/.local/bin symlink, so a checkout runs its own code rather than the installed version's (it used to mix the two). The key helper path written into settings.json is still the installed one. linux/install.sh ships bin/lib/, clearing old modules first so a removed one cannot linger. The package build copies linux/ recursively, which a flat copy would not. tests/cli/test_install.sh runs the real installer into a sandbox home: every file lands, the symlink runs, a reinstall keeps edited presets and drops a stale module. docs/architecture.md lists the modules. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# shellcheck shell=bash
|
||||
# linux/lib/catalogue.sh - fetching a provider's model list, and the cache every fetch leaves.
|
||||
#
|
||||
# Part of the claude-mode CLI: sourced by linux/claude-mode, which sets the
|
||||
# CM_* paths, PY and JSON used here. Not meant to run on its own.
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Provider catalogues
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Every fetch leaves a copy behind for a reader that cannot afford the round
|
||||
# trip - the bar panel's model picker. It is written here, in the only places a
|
||||
# catalogue is ever fetched, so every command that already pays for the network
|
||||
# (models, doctor, setup, the menu's picker) keeps it fresh at no extra cost.
|
||||
cm_cache_catalogue() {
|
||||
"$PY" "$JSON" cache-models "$CM_MODELS_CACHE" "$1" "$2" "${3:-}" >/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
# One catalogue fetch, for any provider: fetched according to its
|
||||
# catalogue.kind, parsed to TSV, and left in the cache for the panel. Prints
|
||||
# the TSV; the status says whether the fetch itself worked. TSV columns by kind:
|
||||
#
|
||||
# openrouter id ctx $in $out lmstudio id state ctx
|
||||
# ollama id params quant family openai id
|
||||
# static id note (a list kept in providers.json)
|
||||
provider_catalogue() {
|
||||
local pid="$1" base="${2%/}" token="${3:-}" out rc
|
||||
case "$(prov_field "$pid" 10)" in
|
||||
openrouter)
|
||||
out="$(curl -fsS --max-time 30 https://openrouter.ai/api/v1/models 2>/dev/null \
|
||||
| "$PY" "$JSON" or-models 2>/dev/null)" ;;
|
||||
lmstudio)
|
||||
out="$(curl -fsS --max-time 10 ${token:+-H "Authorization: Bearer $token"} \
|
||||
"$base/api/v0/models" 2>/dev/null | "$PY" "$JSON" lms-models 2>/dev/null)" ;;
|
||||
ollama)
|
||||
out="$(curl -fsS --max-time 10 ${token:+-H "Authorization: Bearer $token"} \
|
||||
"$base/api/tags" 2>/dev/null | "$PY" "$JSON" ollama-models 2>/dev/null)" ;;
|
||||
openai)
|
||||
# Both header styles: a proxy in front of Anthropic wants
|
||||
# x-api-key, one in front of anything else wants Bearer.
|
||||
out="$(curl -fsS --max-time 15 ${token:+-H "Authorization: Bearer $token"} \
|
||||
${token:+-H "x-api-key: $token"} -H 'anthropic-version: 2023-06-01' \
|
||||
"$base/v1/models" 2>/dev/null | "$PY" "$JSON" openai-models 2>/dev/null)" ;;
|
||||
static)
|
||||
out="$("$PY" "$JSON" provider-static "$pid" 2>/dev/null)" ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
rc=$?
|
||||
cm_cache_catalogue "$pid" "$([ "$rc" -eq 0 ] && echo 1 || echo 0)" "$base" <<<"$out"
|
||||
[ -n "$out" ] && printf '%s\n' "$out"
|
||||
return "$rc"
|
||||
}
|
||||
|
||||
# The credential a preset would send. Empty when there is nothing to send.
|
||||
cm_preset_token() {
|
||||
local pf="$1" am ref
|
||||
am="$(jget "$pf" auth.mode)"; [ -z "$am" ] && am=vault
|
||||
if [ "$am" = "vault" ]; then
|
||||
ref="$(jget "$pf" auth.keyRef)"; [ -z "$ref" ] && ref=openrouter
|
||||
cm_vault_get "$ref" 2>/dev/null || true
|
||||
else
|
||||
jget "$pf" auth.token
|
||||
fi
|
||||
}
|
||||
|
||||
# The token passed to provider_catalogue is not optional decoration. A local
|
||||
# server with authentication switched on answers its model list with 401 like
|
||||
# anything else, so without it the catalogue comes back empty and every caller
|
||||
# silently believes the server has no models - on exactly the setups that need
|
||||
# the list most.
|
||||
Reference in New Issue
Block a user