Skip to content

NikanEidi/ax

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

16 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•—
β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•”β•
β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•—
β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•—
β•šβ•β•  β•šβ•β•β•šβ•β•  β•šβ•β•

⚑ AX β€” The Cybernetic Workflow Architect

"It sees your stack. It learns your structure. It writes what you'd spend hours crafting."

AX is a single-file, zero-dependency Bash utility that autonomously generates production-ready GitHub Actions CI/CD workflows. It scans your project's file tree, concurrently fingerprints every programming language present using its Hybrid Detection Engine, packages that intelligence into a structured prompt, and dispatches it to OpenAI GPT-4o β€” all while a live Cybernetic Eye animation renders in your terminal at 16 frames per second.

The result: a valid .github/workflows/main.yml tailored exactly to your stack, written in seconds, without you touching a YAML key.

Developer: Nikan Eidi β€” Computer Programming & Analysis Student


πŸ“‘ Table of Contents

  1. System Architecture & Logic
  2. Hybrid Detection Engine
  3. Pseudocode β€” Core Execution Flows
  4. Technical Features
  5. Public Documentation Directory
  6. Installation & Usage
  7. Technical Stack
  8. Author

🧠 System Architecture & Logic

AX executes through a strict, seven-state linear pipeline. A global STATE variable transitions from IDLE through each named phase, providing a deterministic execution trace auditable at any point. Every transition is reflected in the live animation label running in parallel.

IDLE β†’ SCANNING β†’ BUILDING β†’ REQUESTING β†’ PARSING β†’ WRITING β†’ DONE
                                                             ↕
                             ERROR ←──────────────── (any phase)

End-to-End Execution Flowchart

%%{init: {'theme': 'dark', 'themeVariables': {
  'primaryColor':       '#00fff7',
  'primaryTextColor':   '#ffffff',
  'primaryBorderColor': '#c724b1',
  'lineColor':          '#c724b1',
  'secondaryColor':     '#0d0d0d',
  'tertiaryColor':      '#0d0d0d',
  'background':         '#0d0d0d',
  'mainBkg':            '#0d0d0d',
  'nodeBorder':         '#00fff7'
}}}%%
flowchart TD
    ENTRY([⚑ ax β€” invoked from project root])
    ENTRY --> A

    subgraph P1 ["πŸ” PHASE 1 β€” TREE SCAN  β€’  STATE: SCANNING"]
        A["get_project_tree()\nfind . -maxdepth 3 -not -path '*/.*'\ngrep -vE node_modules Β· .git Β· build Β· dist Β· bin Β· obj Β· target Β· venv\nsed pipeline β†’ indented tree representation"]
    end

    subgraph P2 ["βš™οΈ PHASE 2 β€” HYBRID DETECTION  β€’  STATE: BUILDING"]
        B["get_context()\nConcurrent manifest + glob checks\nAccumulate all hits into tags[] array\nNode Β· Python Β· Go Β· Rust Β· Java Β· C++ Β· Ruby Β· Shell Β· Windows"]
    end

    subgraph P3 ["πŸ“¦ PHASE 3 β€” PAYLOAD PACKAGING  β€’  STATE: BUILDING"]
        C["create_payload()\npython3 -c json.dumps()\nInject system prompt with 8 directives\nax.sh explicitly excluded Β· temperature: 0.1"]
    end

    subgraph P4 ["πŸ€– PHASE 4 β€” AI CONSULTATION  β€’  STATE: REQUESTING"]
        D["request_ai()\ncurl -s -X POST api.openai.com/v1/chat/completions\nModel: gpt-4o  Β· --max-time 60  Β· --connect-timeout 10\nCapture body + HTTP status via -w flag\nFull curl-exit + HTTP error classification matrix"]
    end

    subgraph P5 ["🧹 PHASE 5 β€” YAML SANITISATION  β€’  STATE: PARSING"]
        E["parse_response()\npython3 json.load via stdin\nre.sub strip ``` opening fence with optional lang tag\nre.sub strip ``` closing fence\nRoute API_ERROR Β· PARSE_ERROR prefix strings"]
    end

    subgraph P6 ["πŸ’Ύ PHASE 6 β€” FILE WRITE  β€’  STATE: WRITING"]
        F["mkdir -p .github/workflows/\nValidate final_yaml non-empty\necho final_yaml > main.yml\nCheck write success"]
    end

    subgraph P7 ["πŸ”— PHASE 7 β€” GIT-SYNC PROMPT  β€’  STATE: DONE"]
        G["prompt_git_sync()\n8-line TUI panel  Β·  tput sc/rc scroll-safe\nArrow-key + y/n/Enter/ESC input loop\ncommand -v git-sync before dispatch"]
    end

    ENTRY --> P1 --> P2 --> P3 --> P4 --> P5 --> P6 --> P7
    A --> B --> C --> D --> E --> F --> G

    D -- "NETWORK_ERROR\nAUTH_ERROR · RATE_ERROR\nSERVER_ERROR · HTTP_ERROR" --> ERR(["⚑ stop_loader\ntput cnorm\nprintf error msg\nexit 1"])
    E -- "API_ERROR\nPARSE_ERROR\nempty output" --> ERR
    F -- "mkdir failure\nwrite failure" --> ERR

    G -- "YES + git-sync on PATH" --> SYNC["git-sync"]
    G -- "YES + git-sync absent"  --> MISS(["⚑ install hint\nexit 1"])
    G -- "NO Β· ESC Β· n"           --> OK(["βœ“ Graceful exit 0"])
    SYNC --> OK

    style P1 fill:#0d0d0d,stroke:#00fff7,color:#00fff7
    style P2 fill:#0d0d0d,stroke:#c724b1,color:#c724b1
    style P3 fill:#0d0d0d,stroke:#00fff7,color:#00fff7
    style P4 fill:#0d0d0d,stroke:#c724b1,color:#c724b1
    style P5 fill:#0d0d0d,stroke:#00fff7,color:#00fff7
    style P6 fill:#0d0d0d,stroke:#c724b1,color:#c724b1
    style P7 fill:#0d0d0d,stroke:#00fff7,color:#00fff7
    style ERR  fill:#3d0000,stroke:#ff0040,color:#ff4060
    style MISS fill:#3d0000,stroke:#ff0040,color:#ff4060
    style OK   fill:#001a00,stroke:#00ff88,color:#00ff88
Loading

βš™οΈ Hybrid Detection Engine

get_context() is AX's language fingerprinter. It performs a single-pass, non-exclusive concurrent check β€” every test runs independently, so matching Node.js never skips the Python or Go checks. Every hit appends a label to a local tags[] Bash array. The final ${tags[*]} expansion produces a space-separated context string that is passed verbatim into the GPT-4o user message.

# Exact source β€” get_context() in ax.sh
local tags=()

[ -f "package.json" ]                                                           && tags+=("Node.js")
([ -f "requirements.txt" ] || [ -f "pyproject.toml" ] || ls *.py  &>/dev/null) && tags+=("Python")
([ -f "go.mod" ]           || ls *.go  &>/dev/null)                            && tags+=("Go")
([ -f "Cargo.toml" ]       || ls *.rs  &>/dev/null)                            && tags+=("Rust")
([ -f "pom.xml" ] || [ -f "build.gradle" ] || ls *.java &>/dev/null)           && tags+=("Java")
(ls *.cpp &>/dev/null || ls *.c &>/dev/null || ls *.h &>/dev/null)             && tags+=("C/C++")
([ -f "Gemfile" ]          || ls *.rb  &>/dev/null)                            && tags+=("Ruby")
(ls *.sh  &>/dev/null)                                                          && tags+=("Shell")
(ls *.bat &>/dev/null || ls *.ps1 &>/dev/null)                                 && tags+=("Windows-Script")

if [ ${#tags[@]} -eq 0 ]; then
    echo "General/Single-File"
else
    echo "${tags[*]}"
fi

Detection Signal Matrix

Language Tag Manifest Signal Glob Signal Detection Logic
Node.js package.json β€” Manifest only
Python requirements.txt Β· pyproject.toml *.py Manifest OR glob
Go go.mod *.go Manifest OR glob
Rust Cargo.toml *.rs Manifest OR glob
Java pom.xml Β· build.gradle *.java Manifest OR glob
C/C++ β€” *.cpp Β· *.c Β· *.h Glob only
Ruby Gemfile *.rb Manifest OR glob
Shell β€” *.sh Glob only
Windows-Script β€” *.bat Β· *.ps1 Glob only

Fallback: If tags[] remains empty after all checks, the function returns "General/Single-File" β€” the AI generates a safe minimal skeleton rather than failing.

Example β€” polyglot monorepo with 5 stacks present:

Node.js Python Go Rust Shell

GPT-4o receives this string and produces a five-language hybrid workflow in a single API call.


πŸ“‹ Pseudocode β€” Core Execution Flows

main() β€” Primary Orchestration

PROCEDURE main():

  SET state ← SCANNING
  START background loader  WITH label "Scanning project structure..."

  SET progress ← 10%
  CALL get_project_tree()  β†’ structure
    ON FAILURE: stop loader · print "⚑ Failed to scan project tree." · EXIT 1

  CALL get_context()  β†’ context

  SET progress ← 30%,  label ← "Building AI payload [ {context} ]..."
  SET state ← BUILDING
  CALL create_payload(structure, context)  β†’ payload
    IF payload IS EMPTY: stop loader Β· print "⚑ Payload is empty β€” aborting." Β· EXIT 1

  SET progress ← 50%,  label ← "Consulting OpenAI [ gpt-4o ]..."
  SET state ← REQUESTING
  CALL request_ai(payload)  β†’ raw_response, req_status
    IF req_status != 0 OR raw_response MATCHES (*_ERROR:*):
        stop loader · print "⚑ {raw_response}" · SET state ERROR · EXIT 1

  SET progress ← 80%,  label ← "Parsing response..."
  SET state ← PARSING
  CALL parse_response(raw_response)  β†’ final_yaml
    IF final_yaml MATCHES "API_ERROR:*":  stop loader Β· print OpenAI error Β· EXIT 1
    IF final_yaml MATCHES "PARSE_ERROR*": stop loader Β· print parse error  Β· EXIT 1
    IF final_yaml IS EMPTY:               stop loader Β· print empty error   Β· EXIT 1

  SET progress ← 95%,  label ← "Writing workflow file..."
  SET state ← WRITING
  CREATE directory  .github/workflows/    ON FAIL: stop loader Β· EXIT 1
  WRITE  final_yaml β†’ .github/workflows/main.yml
    ON FAIL: stop loader · print "⚑ Failed to write main.yml" · EXIT 1

  SET progress ← 100%, label ← "Complete!"
  SET state ← DONE
  SLEEP 0.4 seconds
  STOP loader

  PRINT "[+] Success! .github/workflows/main.yml has been created."
  CALL prompt_git_sync()

END PROCEDURE

_loader_loop() β€” Background Animation Engine

PROCEDURE _loader_loop(stop_file, prog_file, label_file, line_count=18):

  HIDE terminal cursor                    β†’  tput civis
  PRINT line_count blank lines            β†’  reserve vertical space
  MOVE cursor UP line_count rows          β†’  \033[18A
  SAVE cursor position                    β†’  tput sc      ← scroll-safe absolute anchor

  SET frame ← 0

  WHILE stop_file DOES NOT EXIST:

    READ progress ← prog_file    (default: "0")
    READ label    ← label_file   (default: "Processing...")

    RESTORE cursor to saved anchor        β†’  tput rc

    COMPUTE blink_step ← frame MOD 16
    IF   blink_step IN {0..9, 13..15}    β†’  eye_state = OPEN
    ELIF blink_step IN {10, 12}          β†’  eye_state = HALF_CLOSED
    ELIF blink_step  = 11                β†’  eye_state = FULLY_CLOSED

    SELECT iris_glyph   ← ['β—‰','●','β—Ž','β—‰','β—ˆ','●','β—Ž','β—‰']  AT (frame MOD 8)
    SELECT sparkle_glyph← ['Β·','∘','Β·','Β°','Β·','∘','Β·','Β°']   AT (frame MOD 8)
    SELECT spinner      ← braille 10-glyph set                 AT (frame MOD 10)
    BUILD  progress_bar ← (progress Γ— 24 / 100) Γ— 'β–ˆ' + remainder Γ— 'β–‘'

    RENDER eye body     β†’  13 lines   (_eye_open / _eye_half / _eye_closed)
    RENDER blank line   β†’   1 line    (\033[2K)
    RENDER bar box top  β†’   1 line    (β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”)
    RENDER bar row      β†’   1 line    (β”‚ {bar} {progress}% β”‚)
    RENDER bar box bot  β†’   1 line    (β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜)
    RENDER label line   β†’   1 line    ({spinner}  {label})
    // Total = 18 lines β€” invariant must never drift

    frame ← frame + 1
    SLEEP 0.06 seconds                  β†’  β‰ˆ 16 fps

  END WHILE

  RESTORE cursor to anchor              β†’  tput rc
  ERASE 18 lines                        β†’  \033[2K\n Γ— 18
  RESTORE cursor to anchor              β†’  tput rc
  SHOW terminal cursor                  β†’  tput cnorm

END PROCEDURE

πŸ”¬ Technical Features


⚑ Cybernetic Eye Animation

The animation is a parallel background process that communicates with the parent process entirely through three shared tmpfiles. It renders an 18-line deterministic block at approximately 16fps using raw ANSI escape sequences and tput for all cursor operations.

Process & IPC Architecture

Parent Process (main)                  Background Subshell (_loader_loop &)
─────────────────────                  ──────────────────────────────────────
start_loader()
  mktemp β†’ /tmp/ci_stop.XXXXXX   ←→   Polls: while [ ! -f "$stop_file" ]
  mktemp β†’ /tmp/ci_prog.XXXXXX   β†’    Reads:  progress each frame
  mktemp β†’ /tmp/ci_label.XXXXXX  β†’    Reads:  label each frame
  rm -f  $_STOP_FILE                   Loop runs while stop file is ABSENT
  echo "0"      > $_PROG_FILE
  echo "$label" > $_LABEL_FILE
  _loader_loop ... &
  LOADER_PID=$!

set_loader_progress 80 "Parsing..."
  echo "80"       > $_PROG_FILE   β†’    Next frame reads "80" for bar render
  echo "Parsing"  > $_LABEL_FILE  β†’    Next frame reads new label text

stop_loader()
  touch "$_STOP_FILE"             β†’    Loop detects file Β· exits cleanly
  wait "$LOADER_PID"
  rm -f all three tmpfiles
  clear all global variables

No signals, no pipes, no subshell variable scope leakage β€” the entire IPC channel is three files in /tmp/.

The 18-Line Frame Budget

Every call to _draw_frame() emits exactly 18 lines. This invariant is what makes the tput rc cursor-rewind safe β€” if any frame emits 17 or 19 lines, all subsequent frames drift permanently.

Lines Component Emitted By
13 Eye body _eye_open() Β· _eye_half() Β· _eye_closed()
1 Blank separator printf '%s\n' "$CLR"
1 Bar box top β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
1 Bar row β”‚ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘β–‘ 50% β”‚
1 Bar box bottom β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
1 Animated label β Ή Consulting OpenAI [ gpt-4o ]...
18 Total β€” invariant

The 16-Step Blink Cycle

# Exact source β€” _draw_frame() in ax.sh
local step=$(( f % 16 ))

local eye_state="open"
[[ $step -eq 10 || $step -eq 12 ]] && eye_state="half"
[[ $step -eq 11 ]]                  && eye_state="closed"
Frame:  0  1  2  3  4  5  6  7  8  9  10    11      12   13 14 15
State: [──────────────── OPEN ────────────] [HALF] [SHUT] [HALF] [OPEN]

Three independent animation counters run simultaneously:

Glyph Set Array Cycle Counter
Iris center β—‰ ● β—Ž β—‰ β—ˆ ● β—Ž β—‰ 8 frames f % 8
Pupil sparkle · ∘ · ° · ∘ · ° 8 frames f % 8
Status spinner 10 Braille chars 10 frames f % 10

Each cycles independently of the 16-frame blink, producing organic asynchronous micro-animation across all eye states.

Why tput sc / tput rc and Not \033[nA

# FRAGILE β€” breaks on any terminal scroll event
printf "\033[18A"

# CORRECT β€” used throughout ax.sh
tput sc      # Saves absolute cursor address in terminal's own state memory
# ... render 18 lines ...
tput rc      # Restores that absolute address β€” unaffected by scroll

\033[nA (cursor-up N rows) is relative to the current viewport top. A single scroll event during the API call shifts the viewport, making the count wrong β€” all subsequent frames render at the wrong position with no recovery. tput sc stores an absolute cursor coordinate in the terminal emulator's own memory. tput rc retrieves it unconditionally regardless of how much the viewport has scrolled.

Eye Frame Sub-Renderers

Each sub-renderer prints exactly 13 lines β€” the contract that upholds the 18-line budget:

Function Eye State Frames Signature Visual
_eye_open() Fully open 0–9, 13–15 Tiered lashes Β· sclera dots Β· live iris ring Β· animated pupil
_eye_half() Half-closed 10, 12 Descending β–„β–„β–„ lid Β· iris arc peeking Β· drooping lashes
_eye_closed() Fully sealed 11 ╔═══╗ border Β· neon ━━━ seam Β· β–„β–„β–„/β–€β–€β–€ fill Β· flat lashes

_eye_open() receives the current frame number and applies an additional iris ring flicker: when f % 4 == 0, the ring color shifts to ${BOLD}${GLOW}, creating a 4-frame brightness pulse layered on top of all other animation cycles.

The Progress Bar

# Exact source β€” _build_bar() in ax.sh
local width=24
local filled=$(( prog * width / 100 ))
local empty=$(( width - filled ))
local bar="" spaces=""
for ((i=0; i<filled; i++)); do bar+="β–ˆ"; done
for ((i=0; i<empty;  i++)); do spaces+="β–‘"; done
printf "%s" "${CYAN}${BOLD}${bar}${R}${DIM}${MAG}${spaces}${R}"

A 24-character wide bar: filled blocks in ${CYAN}${BOLD}, empty blocks in ${DIM}${MAG}. Integer division ensures the bar never overflows.


πŸ”’ Ghost-Dependency Isolation

A ghost dependency is a CI step generated for a language that is not a genuine project requirement β€” introduced only because a build utility or AX itself happens to use that language.

AX prevents this at the system prompt level inside create_payload(). Three directives are injected into every GPT-4o call:

# Exact source β€” create_payload() embedded Python in ax.sh
system_prompt = (
    "You are a Senior DevOps Architect. Analyze the project tree and detected contexts. "
    "IDENTIFICATION: Identify the ACTUAL project types. If multiple languages are present, create a hybrid workflow. "
    "EXCLUSION: Completely IGNORE the file ax.sh. "
    "MINIMALISM: If the project has only shell scripts and no manifest files, "
    "generate a workflow with exactly two steps: "
    "step 1 β€” checkout code with actions/checkout@v4; "
    "step 2 β€” a step named Lint shell scripts that runs the following command exactly: "
    "find . -name SINGLEQUOTE*.shSINGLEQUOTE -not -path SINGLEQUOTE*/.*SINGLEQUOTE | xargs shellcheck --severity=warning "
    "In the final YAML output replace every token SINGLEQUOTE with an actual single-quote character. "
    "NO GHOST DEPENDENCIES: Never add setup steps for languages not evidenced by real source files. "
    "SINGLE FILE: If only one or two standalone files exist, create a minimalist CI for them. "
    "CLEAN OUTPUT: Output ONLY raw YAML β€” no markdown, no commentary, no preamble. "
    "STANDARDS: Always use runs-on: ubuntu-latest and actions/checkout@v4."
)

What each ghost-prevention directive solves:

Directive Ghost Scenario Prevented
EXCLUSION: Completely IGNORE the file ax.sh AX's own *.sh script triggers a shellcheck step in a pure Python project
MINIMALISM: If only shell scripts...exactly two steps Shell-only project gets a bloated multi-step workflow instead of just checkout + shellcheck
NO GHOST DEPENDENCIES: Never add setup steps... AI hallucinates Node.js or Java setup steps because the tree looks like it might need them

The SINGLEQUOTE token pattern: The MINIMALISM directive must embed find . -name '*.sh' inside the JSON payload string. Single quotes inside a Python sys.argv string create multi-layer quoting conflicts. AX uses a token substitution: the literal string SINGLEQUOTE is written in the prompt, and the AI is instructed to replace every occurrence with an actual ' character in its YAML output. This produces a syntactically correct find command in the workflow with no escaping complexity in the Bash or Python layers.

The temperature: 0.1 setting reinforces determinism: the same scanned structure produces functionally equivalent workflows across repeated runs.


πŸ•ΉοΈ TUI Arrow-Key Navigation

After a successful write, prompt_git_sync() renders an 8-line interactive confirmation panel using the same tput sc/rc scroll-safe cursor technique as the animation loop. It implements a complete raw keyboard event loop with IFS= read -rsn1.

Panel Layout (44-character inner width)

  ╔════════════════════════════════════════════╗
  β•‘  [!] EXECUTE GIT-SYNC?                     β•‘
  β•‘  Would you like to run git-sync now?       β•‘
  ╠════════════════╦═══════════════════════════╣
  β•‘   > YES <      β•‘           NO              β•‘   ← selected = 0
  ╠════════════════╩═══════════════════════════╣
  β•‘ ↑← YES  ↓→ NO  ↡ confirm  y/n quick        β•‘
  β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•

The box inner width is 44 characters β€” split into a 16-char left cell (YES) and a 27-char right cell (NO), joined by a ╦/β•© column divider. The active option is highlighted using ${BOLD}${REV} (reverse video), redrawing on every navigation event for immediate visual feedback.

Raw Input Event Loop

# Exact source β€” prompt_git_sync() event loop in ax.sh
IFS= read -rsn1 key                         # Read exactly 1 raw byte

if [[ "$key" == $'\033' ]]; then            # ESC detected (0x1B)
    IFS= read -rsn1 -t 0.05 seq            # Read 2nd byte (50ms timeout)
    if [[ "$seq" == '[' ]]; then
        IFS= read -rsn1 -t 0.05 key        # Read 3rd byte: direction char
        case "$key" in
            A|D)  selected=0 ;;            # ↑ Up  or ← Left  β†’ YES
            B|C)  selected=1 ;;            # ↓ Down or β†’ Right β†’ NO
        esac
        tput rc 2>/dev/null                 # Restore to panel top
        _draw_prompt "$selected"            # Immediate redraw
        continue
    fi
    selected=1; break                       # Lone ESC β†’ cancel = NO
fi

case "$key" in
    y|Y)            selected=0; break ;;    # Direct YES, no Enter needed
    n|N)            selected=1; break ;;    # Direct NO,  no Enter needed
    $'\n'|$'r'|'')  break             ;;    # Enter β†’ confirm current selection
esac

Complete Key Mapping

Key Input Raw Bytes Action
↑ Up arrow 1B 5B 41 (ESC [ A) Select YES
← Left arrow 1B 5B 44 (ESC [ D) Select YES
↓ Down arrow 1B 5B 42 (ESC [ B) Select NO
β†’ Right arrow 1B 5B 43 (ESC [ C) Select NO
y or Y 1 byte Confirm YES instantly (no Enter required)
n or N 1 byte Confirm NO instantly (no Enter required)
Enter / ↡ 0x0A Confirm current selection
ESC (lone) 0x1B + 50ms silence Cancel β†’ NO

The lone-ESC detection relies on a 50ms timeout on the follow-up read. If no second byte arrives within 50ms of the ESC, it is classified as a standalone Escape keypress (cancel β†’ NO), not the start of an arrow sequence. After any confirmation, the panel is wiped with 8Γ— \033[2K\n, the cursor is restored to the panel origin, and AX either runs git-sync (after a command -v guard) or exits gracefully with code 0.


πŸ“ Public Documentation Directory

The /public directory ships four companion reference documents providing complete engineering transparency for every layer of AX.


A structured mapping of every user-facing feature to its implementing function(s), execution phase, and dependencies. Covers 96 traced features across seven sections: Core Pipeline, State Machine, Animation System, Ghost-Dependency Prevention, TUI & Interaction, Error Handling, and Visual/ANSI.

Use this document for code review, regression auditing, and contributor onboarding.


A complete function-level API reference for every Bash function and embedded Python3 helper in ax.sh. Each entry documents: purpose, full signature, typed parameter table, return values, side effects, step-by-step execution sequence, error behaviour, and design rationale notes.

Includes a global variable reference table and the full ANSI 256-color variable reference.

All 21 functions documented: main Β· set_state Β· get_state Β· cleanup Β· on_error Β· start_loader Β· stop_loader Β· set_loader_progress Β· _loader_loop Β· _draw_frame Β· _build_bar Β· _eye_open Β· _eye_half Β· _eye_closed Β· get_project_tree Β· get_context Β· create_payload Β· request_ai Β· parse_response Β· prompt_git_sync Β· _draw_prompt


Formal test scenario specifications for 20 test cases covering the full surface area of AX β€” pipeline correctness, AI output quality, error handling, animation resilience, and TUI edge cases. Every case includes exact environment setup scripts, expected outputs, pass criteria, and fail indicators.

ID Name What It Validates
TC-001 The Chonk-Meter 5-language monorepo β†’ hybrid workflow Β· zero ghost steps
TC-002 Hybrid Stress Test Node + Python β†’ exact two-language workflow only
TC-003 Ghost-Dep Isolation Shell-only β†’ exactly 2 steps Β· ax.sh never referenced
TC-005 Auth Error Handling Missing key β†’ AUTH_ERROR: Β· exit 1 Β· clean terminal
TC-006 SIGINT Resilience Ctrl+C at any phase β†’ exit 130 Β· cursor restored Β· no orphan PIDs
TC-011 Fence Stripping 4 fence variants β†’ identical clean YAML output
TC-014 Animation Scroll Safety Viewport scroll during API call β†’ animation stays aligned

A deep-dive technical architecture reference covering every structural and design decision in ax.sh. Topics include: the 4-stage find | grep | sed tree scanner pipeline and why maxdepth 3, the hybrid detection array accumulation pattern, the SINGLEQUOTE token substitution design, the tmpfile IPC architecture, the tput sc/rc vs \033[nA rationale, the 3-byte ESC sequence input parser, the 18-line frame budget invariant, the temperature: 0.1 selection reasoning, the ERR trap $LINENO deferred expansion, and the complete external command dependency map.


πŸš€ Installation & Usage

Prerequisites

Requirement Minimum Version Role in AX
Bash 4.0+ Runtime β€” indexed array syntax requires v4
Python 3 3.7+ create_payload() and parse_response() β€” stdlib only (json, re, sys)
curl 7.x+ HTTP POST to OpenAI β€” -w status capture requires 7.x
OpenAI API Key β€” GPT-4o access
git-sync any (Optional) β€” only invoked if you confirm YES at the TUI prompt

Step 1 β€” Clone the Repository

git clone https://github.com/<your-username>/ax.git
cd ax

Step 2 β€” Install Globally to /usr/local/bin/ax

sudo cp ax.sh /usr/local/bin/ax
sudo chmod +x /usr/local/bin/ax

Verify the installation:

which ax
# β†’ /usr/local/bin/ax

Step 3 β€” Configure Your OpenAI API Key

Zsh (recommended):

echo 'export OPENAI_API_KEY="sk-your-key-here"' >> ~/.zshrc
source ~/.zshrc

Bash:

echo 'export OPENAI_API_KEY="sk-your-key-here"' >> ~/.bashrc
source ~/.bashrc

Confirm it is set:

echo $OPENAI_API_KEY
# β†’ sk-your-key-here

⚠️ Security: Never commit your API key to version control. For per-project key isolation, use direnv with a .envrc file added to your .gitignore.


Step 4 β€” Run AX from Any Project Root

cd /path/to/your/project
ax

AX will scan, detect, consult GPT-4o, sanitise the response, and write the workflow β€” all with the Cybernetic Eye animation tracking each phase. When complete, the TUI prompts for git-sync.

Generated output:

.github/
└── workflows/
    └── main.yml   ← production-ready, stack-accurate CI workflow

Updating AX

cd /path/to/ax-repo
git pull origin main
sudo cp ax.sh /usr/local/bin/ax

πŸ›  Technical Stack

Layer Technology Role in AX
Runtime Bash 4+ All orchestration, state machine, IPC, signal handling, TUI event loop
Data Serialisation Python 3 β€” json Β· re Β· sys create_payload(): json.dumps() for safe JSON build Β· parse_response(): re.sub() for fence stripping and json.load() for response parsing
AI Engine OpenAI GPT-4o (gpt-4o) Single completions call per run Β· temperature: 0.1 for determinism Β· system prompt with 8 behavioural directives
HTTP Transport curl 7.x -s -w dual-capture (body + HTTP code) Β· --max-time 60 Β· --connect-timeout 10 Β· full curl-exit-code + HTTP-status error matrix
Terminal Colour ANSI 256-color escapes \033[38;5;{n}m foreground palette β€” 10 named colors + DIM Β· BOLD Β· REV Β· CLR modifiers
Cursor Control tput (ncurses) tput sc/rc scroll-safe anchor Β· tput civis/cnorm cursor hide/show Β· tput rev reverse-video highlighting
Parallel Process Bash subshell & _loader_loop runs detached Β· LOADER_PID tracked Β· wait for clean join on stop
IPC mktemp tmpfiles Three files in /tmp/ β€” progress integer Β· label string Β· stop sentinel (existence-based signal)
Signal Handling trap INT TERM HUP β†’ cleanup() (exit 130) Β· ERR β†’ on_error $LINENO (exit original code)
Raw Input read -rsn1 3-byte ESC sequence detection for arrow keys Β· 50ms timeout for lone-ESC disambiguation

πŸ‘€ Author

Nikan Eidi Computer Programming & Analysis Student

"AX started as a workflow generator. It became a study in how far you can push a terminal."


⚑  See the structure.  Generate the workflow.  Own the pipeline.  ⚑

About

πŸ‘οΈβœ¨ AX: The Cybernetic Workflow Architect. A high-performance, AI-driven CLI tool that automates GitHub Actions generation. Featuring a hybrid language detection engine, tree-logic scanning, and a stunning cyberpunk ANSI interface. Built for DevOps speed.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages