From e28945a07658bc383c6f9a2540b97c5895fce973 Mon Sep 17 00:00:00 2001 From: Nathan Slaven Date: Sun, 24 May 2026 15:35:00 +0000 Subject: [PATCH] Add LinaAI terminal command --- Docs/AI/SelfHostedAiDevelopmentStack.md | 11 ++ Scripts/linaai_task.sh | 2 +- Scripts/linaai_terminal.sh | 175 ++++++++++++++++++++++++ 3 files changed, 187 insertions(+), 1 deletion(-) create mode 100755 Scripts/linaai_terminal.sh diff --git a/Docs/AI/SelfHostedAiDevelopmentStack.md b/Docs/AI/SelfHostedAiDevelopmentStack.md index b6f4f7a..bae18cf 100644 --- a/Docs/AI/SelfHostedAiDevelopmentStack.md +++ b/Docs/AI/SelfHostedAiDevelopmentStack.md @@ -65,6 +65,17 @@ Scripts/linaai_bootstrap_context.sh Scripts/linaai_task.sh "your task here" ``` +For a terminal conversation that feels closer to this Codex workflow, use: + +```bash +linaai +``` + +That opens an interactive prompt. Each instruction is routed through +`Scripts/linaai_task.sh`, so Qwen preflight, Aider local edits, and Codex +fallback still apply. Use `/status`, `/refresh`, `/dry on`, `/codex on`, and +`/exit` inside the prompt. + To test automatic escalation without editing files: ```bash diff --git a/Scripts/linaai_task.sh b/Scripts/linaai_task.sh index 79dfe1f..e21271a 100755 --- a/Scripts/linaai_task.sh +++ b/Scripts/linaai_task.sh @@ -178,7 +178,7 @@ PY )" fi -high_risk_regex='(save/load|save system|multiplayer|replication|networking|AGR|wallet|payment|marketplace|auth|security|migration|core architecture|engine source|broad refactor|private key|secret)' +high_risk_regex='(save/load|save system|multiplayer|replication|networking|\bAGR\b|wallet|payment|marketplace|auth|security|migration|core architecture|engine source|broad refactor|private key|secret)' keyword_escalate=0 if printf '%s' "$TASK" | grep -Eiq "$high_risk_regex"; then keyword_escalate=1 diff --git a/Scripts/linaai_terminal.sh b/Scripts/linaai_terminal.sh new file mode 100755 index 0000000..18c6027 --- /dev/null +++ b/Scripts/linaai_terminal.sh @@ -0,0 +1,175 @@ +#!/usr/bin/env bash +set -euo pipefail + +DEFAULT_REPO="${LINAAI_REPO:-$HOME/repos/AgrarianGame}" +REPO="$DEFAULT_REPO" +DRY_RUN=0 +FORCE_ESCALATE=0 + +usage() { + cat >&2 <<'EOF' +Usage: + linaai [--repo PATH] [--dry-run] [--force-escalate] [task text...] + +Without task text, opens an interactive LinaAI terminal prompt. Each instruction +is routed through Scripts/linaai_task.sh from the selected repo. + +Examples: + linaai + linaai --dry-run "Confirm repo access and list LinaAI docs." + linaai "Update docs for the current deployment workflow." + +Interactive commands: + /help Show commands. + /repo PATH Change repo path. + /status Show git status for current repo. + /refresh Refresh LinaAI knowledge cache. + /dry on|off Toggle dry-run mode. + /codex on|off Toggle forced Codex escalation. + /exit Quit. +EOF +} + +run_status() { + cd "$REPO" + printf 'Repo: %s\n' "$REPO" + git branch --show-current 2>/dev/null || true + git status --short +} + +refresh_context() { + cd "$REPO" + if [[ -x Scripts/linaai_refresh_knowledge.sh ]]; then + Scripts/linaai_refresh_knowledge.sh + fi + if [[ -x Scripts/linaai_bootstrap_context.sh ]]; then + Scripts/linaai_bootstrap_context.sh + fi +} + +run_task() { + local task="$1" + cd "$REPO" + if [[ ! -x Scripts/linaai_task.sh ]]; then + echo "Missing Scripts/linaai_task.sh in ${REPO}" >&2 + return 2 + fi + + local args=() + if [[ "$DRY_RUN" -eq 1 ]]; then + args+=(--dry-run) + fi + if [[ "$FORCE_ESCALATE" -eq 1 ]]; then + args+=(--force-escalate) + fi + + Scripts/linaai_task.sh "${args[@]}" "$task" +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --repo) + REPO="${2:-}" + shift 2 + ;; + --dry-run) + DRY_RUN=1 + shift + ;; + --force-escalate) + FORCE_ESCALATE=1 + shift + ;; + -h|--help) + usage + exit 0 + ;; + --) + shift + break + ;; + -*) + echo "Unknown option: $1" >&2 + usage + exit 2 + ;; + *) + break + ;; + esac +done + +if [[ ! -d "$REPO" ]]; then + echo "Repo does not exist: ${REPO}" >&2 + exit 2 +fi + +if [[ $# -gt 0 ]]; then + run_task "$*" + exit $? +fi + +cat < ' + if ! IFS= read -r line; then + printf '\n' + break + fi + + [[ -z "${line// }" ]] && continue + + case "$line" in + /exit|/quit) + break + ;; + /help) + usage + ;; + /status) + run_status + ;; + /refresh) + refresh_context + ;; + /dry\ on) + DRY_RUN=1 + echo "Dry run on." + ;; + /dry\ off) + DRY_RUN=0 + echo "Dry run off." + ;; + /codex\ on) + FORCE_ESCALATE=1 + echo "Forced Codex escalation on." + ;; + /codex\ off) + FORCE_ESCALATE=0 + echo "Forced Codex escalation off." + ;; + /repo\ *) + next_repo="${line#/repo }" + if [[ -d "$next_repo" ]]; then + REPO="$next_repo" + echo "Repo set to ${REPO}" + else + echo "Repo does not exist: ${next_repo}" >&2 + fi + ;; + /*) + echo "Unknown command: ${line}" >&2 + ;; + *) + run_task "$line" + ;; + esac +done +