Skip to content

agent-jit/AgentJIT

Repository files navigation

                                                
                                                
▄████▄  ▄▄▄▄ ▄▄▄▄▄ ▄▄  ▄▄ ▄▄▄▄▄▄   ██ ██ ██████ 
██▄▄██ ██ ▄▄ ██▄▄  ███▄██   ██     ██ ██   ██   
██  ██ ▀███▀ ██▄▄▄ ██ ▀██   ██  ████▀ ██   ██   
                                                                         

the daemon that compiles your workflows into existence

"We are what we repeatedly do. Excellence, then, is not an act, but a habit."Aristotle, Nicomachean Ethics

Your AI agent repeats the same multi-step workflows hundreds of times — kubectl logs, then grep, then edit, then apply — burning tokens on what has already become muscle memory. AJ watches these habits form, and in quiet moments of reflection, distills them into instinct.

Like an artisan whose hands move before conscious thought arrives, the agent simply knows what to do next. Ten thousand tokens of deliberation become two hundred tokens of certainty. The stochastic becomes deterministic. Repetition becomes skill.


What is AJ?

A background JIT compiler for autonomous coding agents. It operates silently via Claude Code hooks, observes recurring tool-use patterns across sessions, and compiles them into zero-token parameterized skills — no manual configuration required.

flowchart LR
    subgraph hooks["Hook Events"]
        H1(["PostToolUse"])
        H2(["SessionStart"])
        H3(["SessionEnd"])
    end

    subgraph daemon["AJ Daemon"]
        direction TB
        D1["Ingest & Log"]
        D2["Trigger Compile"]
        D3["Emit Skills"]
        D1 --> D2 --> D3
    end

    subgraph skills["Compiled Skills"]
        S1[/"Parameterized"/]
        S2[/"Deterministic"/]
        S3[/"Zero-token"/]
    end

    subgraph runtime["Runtime Execution"]
        direction TB
        R1["Execute Skill"]
        R2{"Success?"}
        R3["Fallback to\nOriginal Workflow"]
        R4["aj stats record"]
        R1 --> R2
        R2 -- "No" --> R3
        R2 -- "Yes / No" --> R4
    end

    hooks -- "stdin (JSON)" --> daemon
    daemon -- "~/.aj/skills/" --> skills
    skills --> runtime
    runtime -- "success rates +\nexisting skills\nas context" --> daemon

    style hooks fill:#4a5568,stroke:#a0aec0,color:#e2e8f0
    style daemon fill:#2b6cb0,stroke:#63b3ed,color:#e2e8f0
    style skills fill:#276749,stroke:#68d391,color:#e2e8f0
    style runtime fill:#744210,stroke:#ecc94b,color:#fefcbf
Loading

The Self-Improvement Loop

The arrow from Runtime back to the Daemon is the key: compiled skills are not static artifacts — they live inside a continuous feedback loop.

  • Runtime Fallback — If a compiled shell script fails during execution, the agent silently falls back to the original uncompiled workflow. The user perceives no interruption; the skill simply steps aside.
  • Success Rate Auditing — Execution outcomes are tracked via aj stats record. If a skill's success rate declines, that signal is fed into the next compilation cycle, where the compiler can deprecate or refactor it. Skills uninvoked for 20+ consecutive sessions are automatically flagged for deprecation.
  • Iterative Recompilation — The current skill library is fed as context to the compiler each cycle. It doesn't start from scratch — it examines existing skills, evaluates whether underlying patterns have shifted, and updates, merges, or replaces them accordingly. Like a JIT engine re-optimizing hot paths with fresh profiling data.

The Numbers

Before After
~10,000 tokens per routine task ~200 token skill invocation
>30s stochastic reasoning <1s deterministic execution
Manual skill authoring Automatic pattern compilation

Supported Agent Harnesses

AJ's ingestion layer is designed to work across multiple agent harnesses. Currently Claude Code is fully supported, with more coming soon.

Harness Status Hook Mechanism Notes
Claude Code Supported Native hooks (PostToolUse, SessionStart, SessionEnd) Full support via aj init
Codex Planned
Gemini CLI Planned
GitHub Copilot Planned
Cursor Planned

Want support for another harness? Open an issue.

Installation

Homebrew (macOS / Linux)

brew install agent-jit/tap/aj

Shell Script (macOS / Linux)

curl -fsSL https://raw.githubusercontent.com/agent-jit/AgentJIT/main/install.sh | sh

Manual Download

Download the latest binary from Releases and place it on your PATH:

# macOS (Apple Silicon)
curl -Lo aj.tar.gz https://github.com/agent-jit/AgentJIT/releases/latest/download/aj_$(curl -s https://api.github.com/repos/agent-jit/AgentJIT/releases/latest | grep tag_name | cut -d '"' -f4 | tr -d v)_darwin_arm64.tar.gz
tar xzf aj.tar.gz aj
sudo mv aj /usr/local/bin/
rm aj.tar.gz

# macOS (Intel)
curl -Lo aj.tar.gz https://github.com/agent-jit/AgentJIT/releases/latest/download/aj_$(curl -s https://api.github.com/repos/agent-jit/AgentJIT/releases/latest | grep tag_name | cut -d '"' -f4 | tr -d v)_darwin_amd64.tar.gz
tar xzf aj.tar.gz aj
sudo mv aj /usr/local/bin/
rm aj.tar.gz

# Linux (x86_64)
curl -Lo aj.tar.gz https://github.com/agent-jit/AgentJIT/releases/latest/download/aj_$(curl -s https://api.github.com/repos/agent-jit/AgentJIT/releases/latest | grep tag_name | cut -d '"' -f4 | tr -d v)_linux_amd64.tar.gz
tar xzf aj.tar.gz aj
sudo mv aj /usr/local/bin/
rm aj.tar.gz

Windows (PowerShell):

$release = Invoke-RestMethod "https://api.github.com/repos/agent-jit/AgentJIT/releases/latest"
$version = $release.tag_name -replace '^v', ''
$url = "https://github.com/agent-jit/AgentJIT/releases/latest/download/aj_${version}_windows_amd64.zip"
Invoke-WebRequest -Uri $url -OutFile aj.zip
Expand-Archive aj.zip -DestinationPath .
Move-Item aj.exe "$env:LOCALAPPDATA\Microsoft\WindowsApps\aj.exe" -Force
Remove-Item aj.zip

Go Install

go install github.com/agent-jit/agentjit/cmd/aj@latest

Build from Source

git clone https://github.com/agent-jit/AgentJIT.git
cd AgentJIT
make install    # builds and copies to /usr/local/bin/aj

Quick Start

# Initialize AJ — creates ~/.aj/, installs Claude Code hooks
aj init

# Or install hooks into a specific project only
aj init --local

# Start the background daemon
aj daemon start

# Trigger a compilation manually
aj compile

# Import historical Claude Code transcripts
aj bootstrap --since 2026-03-01

# View generated skills
aj skills list

# Adjust configuration
aj config get --all
aj config set compile.trigger_mode interval

Architecture

AJ is three loosely-coupled layers in a single Go binary:

flowchart TB
    subgraph cli["CLI · Cobra"]
        direction LR

        subgraph ingestion["Ingestion Layer"]
            direction TB
            I1["Hook stdin"]
            I2["Normalize"]
            I3["JSONL logs"]
            I1 --> I2 --> I3
        end

        subgraph trigger["Trigger Layer"]
            direction TB
            T1["Event count"]
            T2["Interval timer"]
            T3["Manual fire"]
        end

        subgraph compiler["Compiler Layer"]
            direction TB
            C1["Claude Code CLI"]
            C2["Pattern detect"]
            C3["Skill generation"]
            C1 --> C2 --> C3
        end

        ingestion --> trigger --> compiler
    end

    subgraph infra["Infrastructure"]
        direction LR
        U["IPC Transport<br/>(Unix socket / Windows named pipe)"]
        P["PID Lifecycle Mgmt"]
        F["~/.aj/ filesystem"]
    end

    cli --> infra

    style cli fill:#2b6cb0,stroke:#63b3ed,color:#e2e8f0
    style ingestion fill:#2c5282,stroke:#90cdf4,color:#e2e8f0
    style trigger fill:#2c5282,stroke:#90cdf4,color:#e2e8f0
    style compiler fill:#2c5282,stroke:#90cdf4,color:#e2e8f0
    style infra fill:#4a5568,stroke:#a0aec0,color:#e2e8f0
Loading

Design philosophy: The Go binary is a dumb pipe. It handles I/O, lifecycle, and configuration. All intelligence lives in the compiler prompt that Claude executes during compile cycles.

Data Flow

  1. Ingest — Claude Code hooks fire on every tool use, piping JSON to aj ingest via stdin
  2. Normalize — Events are normalized into a canonical schema and appended to date/session-partitioned JSONL logs
  3. Trigger — The daemon monitors event counts or timers and fires the compilation sequence
  4. Compile — Claude Code reads the logs, identifies recurring multi-step patterns, and generates parameterized skills
  5. Emit — Skills are written to ~/.aj/skills/ and become available immediately

Filesystem Layout

~/.aj/
├── config.json                 # Configuration with sensible defaults
├── daemon.pid                  # Daemon process ID
├── daemon.sock                 # IPC endpoint (Unix socket; named pipe on Windows)
├── logs/                       # Date/session-partitioned JSONL
│   └── 2026-04-01/
│       └── session_abc123.jsonl
├── skills/                     # Compiled skills (auto-generated)
├── stats.jsonl                 # Token usage and skill execution metrics
├── compile-log.jsonl           # Compiler activity log
└── last_compile_marker         # Timestamp of last compile run

Configuration

Defaults are designed to work out of the box:

{
  "daemon": { "idle_timeout_minutes": 30 },
  "ingestion": { "max_response_bytes": 512, "log_retention_days": 30 },
  "compile": {
    "trigger_mode": "manual",
    "trigger_interval_minutes": 30,
    "trigger_event_threshold": 100,
    "min_pattern_frequency": 3,
    "min_token_savings": 500
  },
  "scope": {
    "global_cli_tools": ["kubectl", "docker", "gh", "aws", "terraform"],
    "cross_project_threshold": 2
  }
}

Use dot-notation to get/set any value:

aj config get compile.trigger_mode
aj config set compile.min_pattern_frequency 5
aj config reset

CLI Reference

Command Description
aj init Create ~/.aj/, install hooks, write config
aj init --local Install hooks into project-local settings
aj init uninstall Remove hooks and optionally delete data
aj daemon start Start background daemon
aj daemon stop Stop daemon gracefully
aj daemon status Show PID, uptime, event count
aj compile Manually trigger compilation
aj trace Interactive TUI for exploring trace graph and hot paths
aj bootstrap Import historical Claude Code transcripts
aj config get [KEY] Read config values
aj config set KEY VAL Write config values
aj skills list List generated skills with ROI stats
aj skills remove NAME Remove a compiled skill
aj stats Show token usage statistics and ROI
aj stats --json Output stats as JSON
aj stats reset Clear recorded statistics
aj ingest Internal: receive hook JSON from stdin

Development

make build        # Build binary to ./aj
make test         # Run all tests
make clean        # Remove build artifacts
make install      # Install to $GOPATH/bin

Requirements: Go 1.22+

How It Works — The Compile Cycle

When the daemon triggers a compile (by event threshold, timer, or manual invocation), it orchestrates a reflection cycle:

  1. Gather — Collect JSONL logs since the last compile marker
  2. Analyze — Pass logs to Claude with the compiler prompt
  3. Identify — Claude detects recurring multi-step tool-use patterns (≥3 occurrences)
  4. Parameterize — Variable parts (file paths, namespaces, pod names) become parameters
  5. Evaluate — Calculate token savings; reject patterns below the min_token_savings threshold
  6. Compile — Generate deterministic skill files with metadata and ROI tracking
  7. Register — Skills become immediately available for future sessions

The agent doesn't learn to do new things. It learns to stop thinking about things it already knows how to do.

License

MIT


"The energy of the mind is the essence of life." — Aristotle

About

A Just-In-Time compiler for autonomous agents. AgentJIT silently observes execution traces and compiles repetitive stochastic workflows into deterministic, zero-token skills.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages