New:Socket for Asana Is Now Available.Learn more
Sign In

universal-agent-memory

Package Overview
Dependencies
Maintainers
1
Versions
98
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

universal-agent-memory - npm Package Compare versions

Comparing version
6.1.0
to
6.1.1
+461
scripts/generate-comparison-report.ts
#!/usr/bin/env npx tsx
/**
* Terminal-Bench 2.0 Comparison Report Generator
*
* Parses Harbor result.json files from baseline and UAM benchmark runs,
* computes per-model deltas, category breakdowns, and task-level diffs.
*
* Usage:
* npx tsx scripts/generate-comparison-report.ts \
* --baseline benchmark-results/baseline_opus45_<ts> \
* --uam benchmark-results/uam_opus45_<ts> \
* --baseline benchmark-results/baseline_gpt52_<ts> \
* --uam benchmark-results/uam_gpt52_<ts> \
* --output benchmark-results/FULL_COMPARISON_<ts>.md \
* --timestamp <ts>
*/
import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
import { join, basename } from 'path';
// ============================================================================
// Types
// ============================================================================
interface HarborResult {
id: string;
started_at: string;
finished_at: string | null;
n_total_trials: number;
stats: {
n_trials: number;
n_errors: number;
evals: Record<string, {
n_trials: number;
n_errors: number;
metrics: Array<{ mean: number }>;
reward_stats: {
reward: Record<string, string[]>;
};
}>;
};
}
interface TaskStatus {
taskName: string;
passed: boolean;
trialId: string;
}
interface RunSummary {
jobName: string;
model: string;
config: 'baseline' | 'uam';
totalTrials: number;
errors: number;
passed: TaskStatus[];
failed: TaskStatus[];
passRate: number;
}
interface ModelComparison {
model: string;
baseline: RunSummary | null;
uam: RunSummary | null;
uamWins: string[];
baselineWins: string[];
bothPass: string[];
bothFail: string[];
delta: number;
}
// ============================================================================
// Parse CLI args
// ============================================================================
function parseArgs(): { baselineDirs: string[]; uamDirs: string[]; output: string; timestamp: string } {
const args = process.argv.slice(2);
const baselineDirs: string[] = [];
const uamDirs: string[] = [];
let output = '';
let timestamp = new Date().toISOString().replace(/[:.]/g, '-');
for (let i = 0; i < args.length; i++) {
switch (args[i]) {
case '--baseline': baselineDirs.push(args[++i]); break;
case '--uam': uamDirs.push(args[++i]); break;
case '--output': output = args[++i]; break;
case '--timestamp': timestamp = args[++i]; break;
case '--help':
console.log('Usage: npx tsx generate-comparison-report.ts --baseline <dir> --uam <dir> [--output <file>] [--timestamp <ts>]');
process.exit(0);
}
}
if (baselineDirs.length === 0 && uamDirs.length === 0) {
console.error('Error: Provide at least one --baseline or --uam directory');
process.exit(1);
}
if (!output) {
output = `benchmark-results/FULL_COMPARISON_${timestamp}.md`;
}
return { baselineDirs, uamDirs, output, timestamp };
}
// ============================================================================
// Parse Harbor results
// ============================================================================
function extractModelFromJobName(jobName: string): string {
// Job names follow pattern: (baseline|uam)_<model_short>_<timestamp>
// e.g. baseline_opus45_20260213_120000, uam_gpt52_20260213_120000
// Also handles legacy names like uam_v200_optb_full89, opus45_baseline_no_uam
const modelAliases: Record<string, string> = {
opus45: 'claude-opus-4-5',
opus_4_5: 'claude-opus-4-5',
'claude-opus': 'claude-opus-4-5',
gpt52: 'gpt-5.2-codex',
'gpt-5': 'gpt-5.2-codex',
glm47: 'glm-4.7',
'glm-4': 'glm-4.7',
};
for (const [alias, fullName] of Object.entries(modelAliases)) {
if (jobName.includes(alias)) return fullName;
}
// For UAM version runs without model in name, default to Opus 4.5 (most common)
if (/^uam_v\d+/.test(jobName)) return 'claude-opus-4-5';
return 'unknown';
}
function extractModelFromEvalKey(evalKey: string): string {
// Format can be: agent__model__dataset (3 parts) or agent__dataset (2 parts)
const parts = evalKey.split('__');
if (parts.length >= 3) return parts[1];
return '';
}
function parseResultDir(dir: string, config: 'baseline' | 'uam'): RunSummary | null {
const resultPath = join(dir, 'result.json');
if (!existsSync(resultPath)) {
console.warn(` Warning: ${resultPath} not found`);
return null;
}
const data: HarborResult = JSON.parse(readFileSync(resultPath, 'utf-8'));
const jobName = basename(dir);
const evalKeys = Object.keys(data.stats.evals);
if (evalKeys.length === 0) {
console.warn(` Warning: No evals in ${resultPath}`);
return null;
}
const evalKey = evalKeys[0];
// Try model from eval key first, fall back to job name
const model = extractModelFromEvalKey(evalKey) || extractModelFromJobName(jobName);
const evalData = data.stats.evals[evalKey];
const rewards = evalData.reward_stats?.reward || {};
const passedTrials = rewards['1.0'] || [];
const failedTrials = rewards['0.0'] || [];
const passed: TaskStatus[] = passedTrials.map((t: string) => ({
taskName: t.split('__')[0],
passed: true,
trialId: t,
}));
const failed: TaskStatus[] = failedTrials.map((t: string) => ({
taskName: t.split('__')[0],
passed: false,
trialId: t,
}));
const total = passed.length + failed.length;
const passRate = total > 0 ? (passed.length / total) * 100 : 0;
return {
jobName,
model,
config,
totalTrials: data.stats.n_trials,
errors: data.stats.n_errors,
passed,
failed,
passRate,
};
}
function extractTaskNames(tasks: TaskStatus[]): Set<string> {
return new Set(tasks.map(t => t.taskName));
}
// ============================================================================
// Build comparisons
// ============================================================================
function buildModelComparison(baseline: RunSummary | null, uam: RunSummary | null): ModelComparison {
const model = baseline?.model || uam?.model || 'unknown';
const bPassed = baseline ? extractTaskNames(baseline.passed) : new Set<string>();
const bFailed = baseline ? extractTaskNames(baseline.failed) : new Set<string>();
const uPassed = uam ? extractTaskNames(uam.passed) : new Set<string>();
const uFailed = uam ? extractTaskNames(uam.failed) : new Set<string>();
const uamWins = [...uPassed].filter(t => !bPassed.has(t)).sort();
const baselineWins = [...bPassed].filter(t => !uPassed.has(t)).sort();
const bothPass = [...bPassed].filter(t => uPassed.has(t)).sort();
const bothFail = [...bFailed].filter(t => uFailed.has(t)).sort();
const bRate = baseline?.passRate || 0;
const uRate = uam?.passRate || 0;
const delta = uRate - bRate;
return { model, baseline, uam, uamWins, baselineWins, bothPass, bothFail, delta };
}
// ============================================================================
// Binomial test (approximate)
// ============================================================================
function binomialPValue(wins: number, losses: number): string {
const n = wins + losses;
if (n === 0) return 'N/A';
// Simple sign test approximation
const p = Math.min(wins, losses);
// Use normal approximation for binomial test
const expected = n / 2;
const stddev = Math.sqrt(n * 0.25);
if (stddev === 0) return 'N/A';
const z = Math.abs(p - expected) / stddev;
// Rough 2-sided p-value from z-score
if (z < 1.645) return '>0.10';
if (z < 1.96) return '<0.10';
if (z < 2.576) return '<0.05';
return '<0.01';
}
// ============================================================================
// Generate markdown report
// ============================================================================
function generateReport(
comparisons: ModelComparison[],
timestamp: string,
): string {
const lines: string[] = [];
lines.push('# Terminal-Bench 2.0 Full Comparison: UAM v3.1.0 vs Baseline');
lines.push('');
lines.push(`**Generated:** ${new Date().toISOString()}`);
lines.push(`**Dataset:** Terminal-Bench 2.0 (89 tasks)`);
lines.push(`**UAM Version:** 3.1.0`);
lines.push(`**Benchmark ID:** ${timestamp}`);
lines.push('');
// Executive summary
lines.push('## Executive Summary');
lines.push('');
lines.push('| Model | Baseline | UAM | Delta | UAM Wins | Baseline Wins | p-value |');
lines.push('|-------|----------|-----|-------|----------|---------------|---------|');
for (const c of comparisons) {
const bRate = c.baseline ? `${c.baseline.passRate.toFixed(1)}% (${c.baseline.passed.length}/${c.baseline.passed.length + c.baseline.failed.length})` : 'N/A';
const uRate = c.uam ? `${c.uam.passRate.toFixed(1)}% (${c.uam.passed.length}/${c.uam.passed.length + c.uam.failed.length})` : 'N/A';
const delta = c.baseline && c.uam ? `${c.delta >= 0 ? '+' : ''}${c.delta.toFixed(1)}%` : 'N/A';
const pval = binomialPValue(c.uamWins.length, c.baselineWins.length);
lines.push(`| ${c.model} | ${bRate} | ${uRate} | **${delta}** | ${c.uamWins.length} | ${c.baselineWins.length} | ${pval} |`);
}
lines.push('');
// Aggregate stats
const totalUamWins = comparisons.reduce((s, c) => s + c.uamWins.length, 0);
const totalBaselineWins = comparisons.reduce((s, c) => s + c.baselineWins.length, 0);
const netTasks = totalUamWins - totalBaselineWins;
lines.push(`**Across all models:** UAM wins ${totalUamWins} tasks, Baseline wins ${totalBaselineWins} tasks, Net: ${netTasks >= 0 ? '+' : ''}${netTasks} tasks for UAM.`);
lines.push('');
// Per-model detailed sections
for (const c of comparisons) {
lines.push(`---`);
lines.push('');
lines.push(`## ${c.model}`);
lines.push('');
if (c.baseline) {
lines.push(`- **Baseline:** ${c.baseline.passRate.toFixed(1)}% (${c.baseline.passed.length} passed, ${c.baseline.failed.length} failed, ${c.baseline.errors} errors)`);
}
if (c.uam) {
lines.push(`- **UAM:** ${c.uam.passRate.toFixed(1)}% (${c.uam.passed.length} passed, ${c.uam.failed.length} failed, ${c.uam.errors} errors)`);
}
if (c.baseline && c.uam) {
lines.push(`- **Net Delta:** ${c.delta >= 0 ? '+' : ''}${c.delta.toFixed(1)}% (${c.uamWins.length - c.baselineWins.length >= 0 ? '+' : ''}${c.uamWins.length - c.baselineWins.length} tasks)`);
}
lines.push('');
// UAM wins
if (c.uamWins.length > 0) {
lines.push('### Tasks UAM Wins (pass with UAM, fail without)');
lines.push('');
for (const t of c.uamWins) {
lines.push(`- \`${t}\``);
}
lines.push('');
}
// Baseline wins
if (c.baselineWins.length > 0) {
lines.push('### Tasks Baseline Wins (pass without UAM, fail with)');
lines.push('');
for (const t of c.baselineWins) {
lines.push(`- \`${t}\``);
}
lines.push('');
}
// Full task-level diff table
if (c.baseline && c.uam) {
const allTasks = new Set([
...c.baseline.passed.map(t => t.taskName),
...c.baseline.failed.map(t => t.taskName),
...c.uam.passed.map(t => t.taskName),
...c.uam.failed.map(t => t.taskName),
]);
const bPassSet = extractTaskNames(c.baseline.passed);
const uPassSet = extractTaskNames(c.uam.passed);
lines.push('### Full Task Comparison');
lines.push('');
lines.push('| Task | Baseline | UAM | Delta |');
lines.push('|------|----------|-----|-------|');
for (const t of [...allTasks].sort()) {
const bStatus = bPassSet.has(t) ? 'PASS' : 'FAIL';
const uStatus = uPassSet.has(t) ? 'PASS' : 'FAIL';
let delta = '=';
if (bStatus === 'FAIL' && uStatus === 'PASS') delta = '**+UAM**';
if (bStatus === 'PASS' && uStatus === 'FAIL') delta = '**-UAM**';
lines.push(`| ${t} | ${bStatus} | ${uStatus} | ${delta} |`);
}
lines.push('');
}
}
// Cross-model analysis
if (comparisons.length > 1) {
lines.push('---');
lines.push('');
lines.push('## Cross-Model Analysis');
lines.push('');
// Which tasks does UAM help consistently across models?
const uamWinSets = comparisons.map(c => new Set(c.uamWins));
const baselineWinSets = comparisons.map(c => new Set(c.baselineWins));
if (uamWinSets.length >= 2) {
const consistentUamWins = [...uamWinSets[0]].filter(t => uamWinSets.every(s => s.has(t)));
const consistentBaselineWins = [...baselineWinSets[0]].filter(t => baselineWinSets.every(s => s.has(t)));
if (consistentUamWins.length > 0) {
lines.push(`**Tasks where UAM helps across ALL models:** ${consistentUamWins.join(', ')}`);
lines.push('');
}
if (consistentBaselineWins.length > 0) {
lines.push(`**Tasks where UAM hurts across ALL models:** ${consistentBaselineWins.join(', ')}`);
lines.push('');
}
}
// Which model benefits most from UAM?
const sorted = [...comparisons].sort((a, b) => b.delta - a.delta);
lines.push('**Model benefit ranking (most to least improvement from UAM):**');
lines.push('');
for (const c of sorted) {
lines.push(`1. **${c.model}**: ${c.delta >= 0 ? '+' : ''}${c.delta.toFixed(1)}% (${c.uamWins.length} wins, ${c.baselineWins.length} losses)`);
}
lines.push('');
}
// Methodology
lines.push('---');
lines.push('');
lines.push('## Methodology');
lines.push('');
lines.push('- **Baseline:** `harbor run` with `--ak "system_prompt="` to clear UAM context');
lines.push('- **UAM:** `harbor run` with default CLAUDE.md and UAM memory system active');
lines.push('- **Dataset:** Terminal-Bench 2.0 (89 tasks across systems, ML, security, algorithms)');
lines.push('- **Scoring:** Binary pass/fail per task based on Harbor reward (1.0 = pass, 0.0 = fail)');
lines.push('- **Statistical test:** Sign test on UAM-wins vs Baseline-wins (binomial, 2-sided)');
lines.push('');
lines.push('---');
lines.push(`*Report generated by \`scripts/generate-comparison-report.ts\` at ${new Date().toISOString()}*`);
return lines.join('\n');
}
// ============================================================================
// Main
// ============================================================================
function main(): void {
const { baselineDirs, uamDirs, output, timestamp } = parseArgs();
console.log('Parsing benchmark results...');
const baselineRuns: RunSummary[] = [];
const uamRuns: RunSummary[] = [];
for (const dir of baselineDirs) {
const run = parseResultDir(dir, 'baseline');
if (run) {
baselineRuns.push(run);
console.log(` Baseline: ${run.model} - ${run.passRate.toFixed(1)}% (${run.passed.length}/${run.passed.length + run.failed.length})`);
}
}
for (const dir of uamDirs) {
const run = parseResultDir(dir, 'uam');
if (run) {
uamRuns.push(run);
console.log(` UAM: ${run.model} - ${run.passRate.toFixed(1)}% (${run.passed.length}/${run.passed.length + run.failed.length})`);
}
}
// Match baseline and UAM runs by model
const modelSet = new Set([
...baselineRuns.map(r => r.model),
...uamRuns.map(r => r.model),
]);
const comparisons: ModelComparison[] = [];
for (const model of modelSet) {
const baseline = baselineRuns.find(r => r.model === model) || null;
const uam = uamRuns.find(r => r.model === model) || null;
comparisons.push(buildModelComparison(baseline, uam));
}
// Sort by model name for consistent output
comparisons.sort((a, b) => a.model.localeCompare(b.model));
// Generate report
const report = generateReport(comparisons, timestamp);
writeFileSync(output, report + '\n');
console.log(`\nReport written to: ${output}`);
console.log(`Models compared: ${comparisons.length}`);
for (const c of comparisons) {
const sym = c.delta >= 0 ? '+' : '';
console.log(` ${c.model}: ${sym}${c.delta.toFixed(1)}% (UAM wins ${c.uamWins.length}, Baseline wins ${c.baselineWins.length})`);
}
}
main();
#!/usr/bin/env bash
set -euo pipefail
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
REPO_URL="https://github.com/DammianMiller/universal-agent-memory"
echo -e "${GREEN}Universal Agent Memory - Desktop Installation${NC}"
echo "============================================"
echo ""
# Check for Node.js
if ! command -v node &> /dev/null; then
echo -e "${RED}Error: Node.js is not installed${NC}"
echo "Please install Node.js 18+ from https://nodejs.org/"
exit 1
fi
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
if [ "$NODE_VERSION" -lt 18 ]; then
echo -e "${RED}Error: Node.js 18+ required (you have $(node -v))${NC}"
exit 1
fi
echo -e "${GREEN}✓${NC} Node.js $(node -v) detected"
# Check for npm
if ! command -v npm &> /dev/null; then
echo -e "${RED}Error: npm is not installed${NC}"
exit 1
fi
echo -e "${GREEN}✓${NC} npm $(npm -v) detected"
# Check for Docker (optional)
if command -v docker &> /dev/null; then
echo -e "${GREEN}✓${NC} Docker detected - local Qdrant available"
DOCKER_AVAILABLE=true
else
echo -e "${YELLOW}⚠${NC} Docker not found - will use cloud backends only"
DOCKER_AVAILABLE=false
fi
# Install the CLI globally
echo ""
echo "Installing universal-agent-memory..."
# Try npm install first, fall back to git clone if package not published yet
if npm install -g universal-agent-memory 2>/dev/null; then
echo -e "${GREEN}✓${NC} Installed from npm registry"
else
echo -e "${YELLOW}Package not yet on npm, installing from GitHub...${NC}"
# Install to user's local directory
INSTALL_DIR="${HOME}/.universal-agent-memory"
# Remove old installation if exists
if [ -d "$INSTALL_DIR" ]; then
echo "Removing previous installation..."
rm -rf "$INSTALL_DIR"
fi
# Clone and install
git clone --depth 1 "$REPO_URL.git" "$INSTALL_DIR"
cd "$INSTALL_DIR"
npm install --production=false
npm run build
npm link
echo -e "${GREEN}✓${NC} Installed from GitHub to $INSTALL_DIR"
fi
echo ""
echo -e "${GREEN}Installation complete!${NC}"
echo ""
echo "Next steps:"
echo " 1. Initialize UAM in your project:"
echo " $ cd /path/to/your/project"
echo " $ uam init"
echo ""
echo " 2. Review the generated CLAUDE.md"
echo ""
echo " 3. Start working - your AI assistant will follow the workflows!"
echo ""
if [ "$DOCKER_AVAILABLE" = true ]; then
echo " 2. Start local memory services (optional):"
echo " $ uam memory start"
echo ""
echo " Or use cloud backends:"
else
echo " 2. Configure cloud memory backends:"
fi
echo " - GitHub: export GITHUB_TOKEN=your_token"
echo " - Qdrant Cloud: export QDRANT_API_KEY=your_key && export QDRANT_URL=your_url"
echo ""
echo " 3. Generate CLAUDE.md for your project:"
echo " $ uam generate"
echo ""
echo "Documentation: ${REPO_URL}#readme"
#!/bin/bash
set -e
REPO_URL="https://github.com/DammianMiller/universal-agent-memory"
echo "🚀 Universal Agent Memory - Web Platform Setup"
echo ""
# Check for required tools
if ! command -v node &> /dev/null; then
echo "❌ Node.js is required. Install from https://nodejs.org"
exit 1
fi
if ! command -v npm &> /dev/null; then
echo "❌ npm is required. Install from https://nodejs.org"
exit 1
fi
echo "✅ Node.js $(node -v) detected"
echo "✅ npm $(npm -v) detected"
# Install CLI globally
echo ""
echo "📦 Installing universal-agent-memory CLI..."
# Try npm install first, fall back to git clone if package not published yet
if npm install -g universal-agent-memory 2>/dev/null; then
echo "✅ Installed from npm registry"
else
echo "⚠️ Package not yet on npm, installing from GitHub..."
# Install to user's local directory
INSTALL_DIR="${HOME}/.universal-agent-memory"
# Remove old installation if exists
if [ -d "$INSTALL_DIR" ]; then
echo "Removing previous installation..."
rm -rf "$INSTALL_DIR"
fi
# Clone and install
git clone --depth 1 "$REPO_URL.git" "$INSTALL_DIR"
cd "$INSTALL_DIR"
npm install --production=false
npm run build
npm link
echo "✅ Installed from GitHub to $INSTALL_DIR"
fi
# Initialize in current directory
echo ""
echo "⚙️ Initializing project..."
uam init --web --interactive
echo ""
echo "✅ Setup complete!"
echo ""
echo "Next steps:"
echo " 1. Initialize UAM in your project:"
echo " uam init"
echo ""
echo " 2. Review the generated CLAUDE.md"
echo ""
echo " 3. Start working - your AI assistant will follow the workflows!"
echo ""
echo "Optional: Set up cloud memory backends"
echo " export GITHUB_TOKEN=your_token"
echo " export QDRANT_API_KEY=your_key"
echo " export QDRANT_URL=your_url"
echo ""
echo "Documentation: ${REPO_URL}#readme"
# Setup Scripts
This directory contains automated setup and installation scripts for UAM.
## Scripts
### `setup.sh` - Complete Setup
```bash
npm run setup
```
Performs a comprehensive setup including:
- ✅ Dependency checking (Node.js, npm, git, npx)
- ✅ Optional dependency recommendations (Docker, Python, pre-commit)
- ✅ npm install (if node_modules missing)
- ✅ TypeScript build
- ✅ Git hooks configuration:
- `pre-commit` - Secrets detection, linting
- `commit-msg` - Conventional commits validation
- `pre-push` - Test execution before push
- ✅ GitHub PR template (if gh CLI available)
### `install-web.sh` - Web Platform Setup
```bash
npm run install:web
```
Installs UAM for web platform usage (claude.ai, Factory.AI):
- Installs CLI globally or from GitHub
- Initializes web platform configuration
- Sets up for web-based AI assistants
### `install-desktop.sh` - Desktop Setup
```bash
npm run install:desktop
```
Installs UAM for desktop usage:
- Installs CLI globally or from GitHub
- Detects Docker for local Qdrant
- Initializes desktop platform configuration
- Provides setup guidance
## Usage
### Quick Setup
```bash
# Install UAM globally
npm install -g universal-agent-memory
# Run comprehensive setup
npm run setup
# Initialize in your project
uam init
```
### Platform-Specific Setup
```bash
# For web platforms (claude.ai, Factory.AI)
npm run install:web
# For desktop (Claude Code, opencode)
npm run install:desktop
```
## Git Hooks
The `setup.sh` script configures three git hooks:
### Pre-commit Hook
- **Purpose**: Prevent secrets from being committed
- **Checks**:
- Scans for API keys, passwords, tokens in code
- Runs linter with zero warnings allowed
- **Bypass**: `git commit --no-verify`
### Commit-msg Hook
- **Purpose**: Enforce conventional commits format
- **Validates**: `type(scope): description` format
- **Types**: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert
- **Bypass**: Confirm with 'y' when prompted
### Pre-push Hook
- **Purpose**: Ensure tests pass before pushing
- **Runs**: `npm test`
- **Bypass**: None (tests must pass)
## Troubleshooting
### Hooks not executing
```bash
# Make hooks executable
chmod +x .git/hooks/*
# Verify hooks exist
ls -la .git/hooks/ | grep -v sample
```
### Setup script fails
```bash
# Check Node.js version
node --version # Should be >= 18.0.0
# Check npm
npm --version
# Clear and reinstall
rm -rf node_modules package-lock.json
npm install
```
### Manual hook installation
If automatic setup fails, manually create hooks:
```bash
# Pre-commit
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
npm run lint -- --max-warnings=0
exit $?
EOF
chmod +x .git/hooks/pre-commit
# Commit-msg
cat > .git/hooks/commit-msg << 'EOF'
#!/bin/bash
# Conventional commits validation
exit 0
EOF
chmod +x .git/hooks/commit-msg
```
## Best Practices
1. **Always run `npm run setup`** after cloning or updating UAM
2. **Review generated hooks** before committing
3. **Keep hooks in sync** with project requirements
4. **Document custom hooks** in project README
5. **Test hooks** with `git commit --no-verify` first
## Security Notes
- Git hooks run locally and cannot access remote repositories
- Pre-commit hook only scans TypeScript/JavaScript/JSON files
- Secrets detection is best-effort (not exhaustive)
- Always use environment variables for sensitive data
#!/bin/bash
#
# Full Terminal-Bench 2.0 Benchmark: UAM v3.1.0 vs Baseline
# Runs all 3 models x 2 configs = 6 total benchmark runs
#
# Models: Claude Opus 4.5, GPT 5.2 Codex, GLM 4.7
# Configs: Baseline (no UAM), With UAM
#
# Usage:
# export FACTORY_API_KEY="your-key"
# ./scripts/run-full-benchmark.sh [options]
#
# Options:
# --model <model> Run only this model (e.g. anthropic/claude-opus-4-5)
# --baseline-only Skip UAM runs
# --uam-only Skip baseline runs
# --concurrency <n> Parallel tasks per run (default: 4)
# --timeout-mult <f> Timeout multiplier (default: 2.0)
# --dry-run Print commands without executing
# --resume <timestamp> Resume a previous run using its timestamp
# --help Show help
#
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
RESULTS_DIR="$PROJECT_ROOT/benchmark-results"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Models in Harbor format
declare -A MODEL_MAP=(
["anthropic/claude-opus-4-5"]="opus45"
["openai/gpt-5.2-codex"]="gpt52"
["zhipu/glm-4.7"]="glm47"
)
ALL_MODELS=("anthropic/claude-opus-4-5" "openai/gpt-5.2-codex" "zhipu/glm-4.7")
# Defaults
CONCURRENCY=4
TIMEOUT_MULT=2.0
DATASET="terminal-bench@2.0"
RUN_BASELINE=true
RUN_UAM=true
DRY_RUN=false
SELECTED_MODELS=("${ALL_MODELS[@]}")
RESUME_TS=""
# Track run results for summary
declare -A RUN_STATUS
declare -A RUN_JOBS
usage() {
sed -n '2,/^$/p' "$0" | sed 's/^#//' | sed 's/^ //'
exit 0
}
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
--model) SELECTED_MODELS=("$2"); shift 2 ;;
--baseline-only) RUN_UAM=false; shift ;;
--uam-only) RUN_BASELINE=false; shift ;;
--concurrency) CONCURRENCY="$2"; shift 2 ;;
--timeout-mult) TIMEOUT_MULT="$2"; shift 2 ;;
--dry-run) DRY_RUN=true; shift ;;
--resume) RESUME_TS="$2"; TIMESTAMP="$2"; shift 2 ;;
--help) usage ;;
*) echo "Unknown option: $1"; exit 1 ;;
esac
done
}
check_prerequisites() {
if ! command -v harbor &>/dev/null; then
echo "Error: 'harbor' CLI not found. Install from https://github.com/laude-institute/harbor"
exit 1
fi
if [[ -z "${FACTORY_API_KEY:-}" ]] && [[ -z "${DROID_API_KEY:-}" ]] && [[ -z "${ANTHROPIC_API_KEY:-}" ]]; then
echo "Error: No API key found. Set FACTORY_API_KEY, DROID_API_KEY, or ANTHROPIC_API_KEY"
echo "Get your Factory key at: https://app.factory.ai/settings/api-keys"
exit 1
fi
}
log() {
local level="$1"; shift
local ts
ts=$(date +"%H:%M:%S")
case "$level" in
INFO) echo -e "[$ts] \033[36mINFO\033[0m $*" ;;
OK) echo -e "[$ts] \033[32mOK\033[0m $*" ;;
WARN) echo -e "[$ts] \033[33mWARN\033[0m $*" ;;
ERROR) echo -e "[$ts] \033[31mERROR\033[0m $*" ;;
RUN) echo -e "[$ts] \033[35mRUN\033[0m $*" ;;
esac
}
run_harbor() {
local config_type="$1" # "baseline" or "uam"
local model="$2"
local model_short="${MODEL_MAP[$model]}"
local job_name="${config_type}_${model_short}_${TIMESTAMP}"
local log_file="$RESULTS_DIR/${job_name}.log"
local run_key="${config_type}_${model_short}"
# Skip if already completed (resume mode)
if [[ -n "$RESUME_TS" ]] && [[ -f "$RESULTS_DIR/${job_name}/result.json" ]]; then
log INFO "Skipping $job_name (already completed)"
RUN_STATUS[$run_key]="skipped"
RUN_JOBS[$run_key]="$job_name"
return 0
fi
log RUN "$config_type | $model | job=$job_name"
local cmd=(
harbor run
-d "$DATASET"
-m "$model"
-n "$CONCURRENCY"
--timeout-multiplier "$TIMEOUT_MULT"
--job-name "$job_name"
--jobs-dir "$RESULTS_DIR"
)
if [[ "$config_type" == "baseline" ]]; then
# Baseline: vanilla claude-code agent with no UAM context
cmd+=(-a claude-code --ak "system_prompt=")
else
# UAM: custom agent with classified preamble and pre-execution hooks
cmd+=(--agent-import-path "uam_harbor.uam_agent:UAMAgent")
fi
if [[ "$DRY_RUN" == true ]]; then
echo " [DRY RUN] ${cmd[*]}"
RUN_STATUS[$run_key]="dry-run"
RUN_JOBS[$run_key]="$job_name"
return 0
fi
mkdir -p "$RESULTS_DIR"
local start_time
start_time=$(date +%s)
if "${cmd[@]}" 2>&1 | tee "$log_file"; then
RUN_STATUS[$run_key]="success"
else
RUN_STATUS[$run_key]="failed"
log WARN "$job_name exited with non-zero status"
fi
RUN_JOBS[$run_key]="$job_name"
local end_time
end_time=$(date +%s)
local duration=$(( end_time - start_time ))
local hours=$(( duration / 3600 ))
local minutes=$(( (duration % 3600) / 60 ))
log OK "$job_name completed in ${hours}h ${minutes}m"
}
print_summary() {
echo ""
echo "================================================================"
echo " BENCHMARK SUMMARY"
echo "================================================================"
echo ""
printf " %-12s %-30s %-10s %s\n" "Config" "Model" "Status" "Job Name"
printf " %-12s %-30s %-10s %s\n" "------" "-----" "------" "--------"
for model in "${SELECTED_MODELS[@]}"; do
local model_short="${MODEL_MAP[$model]}"
for config in baseline uam; do
local key="${config}_${model_short}"
local status="${RUN_STATUS[$key]:-not-run}"
local job="${RUN_JOBS[$key]:-N/A}"
printf " %-12s %-30s %-10s %s\n" "$config" "$model" "$status" "$job"
done
done
echo ""
echo " Results directory: $RESULTS_DIR"
echo " Timestamp: $TIMESTAMP"
echo ""
}
generate_report() {
log INFO "Generating comparison report..."
local report_script="$SCRIPT_DIR/generate-comparison-report.ts"
if [[ ! -f "$report_script" ]]; then
log WARN "Report generator not found at $report_script"
log INFO "Generating basic summary instead..."
generate_basic_report
return
fi
# Run the TypeScript report generator
local report_output
report_output="$RESULTS_DIR/FULL_COMPARISON_${TIMESTAMP}.md"
local job_args=""
for model in "${SELECTED_MODELS[@]}"; do
local model_short="${MODEL_MAP[$model]}"
if [[ "$RUN_BASELINE" == true ]]; then
local bj="${RUN_JOBS[baseline_${model_short}]:-}"
if [[ -n "$bj" ]]; then
job_args="$job_args --baseline $RESULTS_DIR/$bj"
fi
fi
if [[ "$RUN_UAM" == true ]]; then
local uj="${RUN_JOBS[uam_${model_short}]:-}"
if [[ -n "$uj" ]]; then
job_args="$job_args --uam $RESULTS_DIR/$uj"
fi
fi
done
if npx tsx "$report_script" \
--output "$report_output" \
--timestamp "$TIMESTAMP" \
$job_args 2>&1; then
log OK "Report saved to $report_output"
else
log WARN "TypeScript report generator failed, falling back to basic report"
generate_basic_report
fi
}
generate_basic_report() {
local report_file="$RESULTS_DIR/FULL_COMPARISON_${TIMESTAMP}.md"
cat > "$report_file" << HEADER
# Terminal-Bench 2.0 Full Comparison: UAM v3.1.0 vs Baseline
**Generated:** $(date -Iseconds)
**Dataset:** $DATASET (89 tasks)
**UAM Version:** 3.1.0
**Concurrency:** $CONCURRENCY | **Timeout Multiplier:** $TIMEOUT_MULT
## Results Summary
| Model | Config | Pass Rate | Passed | Failed | Errors |
|-------|--------|-----------|--------|--------|--------|
HEADER
for model in "${SELECTED_MODELS[@]}"; do
local model_short="${MODEL_MAP[$model]}"
for config in baseline uam; do
local key="${config}_${model_short}"
local job="${RUN_JOBS[$key]:-}"
local result_file="$RESULTS_DIR/$job/result.json"
if [[ -n "$job" ]] && [[ -f "$result_file" ]]; then
local stats
stats=$(python3 -c "
import json, sys
with open('$result_file') as f:
d = json.load(f)
evals = d['stats']['evals']
for k, v in evals.items():
rw = v.get('reward_stats', {}).get('reward', {})
p = len(rw.get('1.0', []))
f = len(rw.get('0.0', []))
total = p + f
rate = p/total*100 if total > 0 else 0
err = v.get('n_errors', 0)
print(f'{rate:.1f}%|{p}|{f}|{err}')
" 2>/dev/null || echo "N/A|N/A|N/A|N/A")
IFS='|' read -r rate passed failed errors <<< "$stats"
echo "| $model | $config | $rate | $passed | $failed | $errors |" >> "$report_file"
else
echo "| $model | $config | N/A | N/A | N/A | N/A |" >> "$report_file"
fi
done
done
# Add per-model delta section
cat >> "$report_file" << 'DELTAS'
## Per-Model UAM Delta
DELTAS
for model in "${SELECTED_MODELS[@]}"; do
local model_short="${MODEL_MAP[$model]}"
local bj="${RUN_JOBS[baseline_${model_short}]:-}"
local uj="${RUN_JOBS[uam_${model_short}]:-}"
local b_result="$RESULTS_DIR/$bj/result.json"
local u_result="$RESULTS_DIR/$uj/result.json"
if [[ -f "$b_result" ]] && [[ -f "$u_result" ]]; then
echo "### $model" >> "$report_file"
echo "" >> "$report_file"
python3 -c "
import json
with open('$b_result') as f:
bd = json.load(f)
with open('$u_result') as f:
ud = json.load(f)
def get_tasks(data):
evals = data['stats']['evals']
for k, v in evals.items():
rw = v.get('reward_stats', {}).get('reward', {})
passed = set(t.split('__')[0] for t in rw.get('1.0', []))
failed = set(t.split('__')[0] for t in rw.get('0.0', []))
return passed, failed
return set(), set()
bp, bf = get_tasks(bd)
up, uf = get_tasks(ud)
uam_wins = sorted(up - bp)
baseline_wins = sorted(bp - up)
both_pass = sorted(bp & up)
both_fail = sorted(bf & uf)
b_rate = len(bp)/(len(bp)+len(bf))*100 if (len(bp)+len(bf))>0 else 0
u_rate = len(up)/(len(up)+len(uf))*100 if (len(up)+len(uf))>0 else 0
delta = u_rate - b_rate
print(f'| Metric | Value |')
print(f'|--------|-------|')
print(f'| Baseline pass rate | {b_rate:.1f}% ({len(bp)}/{len(bp)+len(bf)}) |')
print(f'| UAM pass rate | {u_rate:.1f}% ({len(up)}/{len(up)+len(uf)}) |')
print(f'| **Net delta** | **{delta:+.1f}%** ({len(uam_wins)-len(baseline_wins):+d} tasks) |')
print(f'| UAM wins | {len(uam_wins)} tasks |')
print(f'| Baseline wins | {len(baseline_wins)} tasks |')
print(f'| Both pass | {len(both_pass)} tasks |')
print(f'| Both fail | {len(both_fail)} tasks |')
print()
if uam_wins:
print('**UAM wins:** ' + ', '.join(uam_wins))
print()
if baseline_wins:
print('**Baseline wins:** ' + ', '.join(baseline_wins))
print()
" >> "$report_file" 2>/dev/null || echo "Unable to parse results for $model" >> "$report_file"
echo "" >> "$report_file"
fi
done
echo "" >> "$report_file"
echo "---" >> "$report_file"
echo "*Report generated by \`scripts/run-full-benchmark.sh\` at $(date -Iseconds)*" >> "$report_file"
log OK "Basic report saved to $report_file"
}
# === Main ===
main() {
parse_args "$@"
echo "================================================================"
echo " Terminal-Bench 2.0 Full Benchmark"
echo " UAM v3.1.0 vs Baseline | $(date)"
echo "================================================================"
echo ""
echo " Models: ${SELECTED_MODELS[*]}"
echo " Configs: $([ "$RUN_BASELINE" = true ] && echo "baseline ")$([ "$RUN_UAM" = true ] && echo "uam")"
echo " Concurrency: $CONCURRENCY"
echo " Timeout: ${TIMEOUT_MULT}x"
echo " Results: $RESULTS_DIR"
echo " Timestamp: $TIMESTAMP"
echo ""
check_prerequisites
# Run each model x config combination
local run_count=0
local total_runs=0
for model in "${SELECTED_MODELS[@]}"; do
[[ "$RUN_BASELINE" == true ]] && (( total_runs++ )) || true
[[ "$RUN_UAM" == true ]] && (( total_runs++ )) || true
done
log INFO "Starting $total_runs benchmark runs..."
for model in "${SELECTED_MODELS[@]}"; do
if [[ "$RUN_BASELINE" == true ]]; then
(( run_count++ )) || true
log INFO "Run $run_count/$total_runs"
run_harbor "baseline" "$model"
fi
if [[ "$RUN_UAM" == true ]]; then
(( run_count++ )) || true
log INFO "Run $run_count/$total_runs"
run_harbor "uam" "$model"
fi
done
# Generate report
generate_report
# Print summary
print_summary
log OK "All benchmark runs complete."
}
main "$@"
#!/bin/bash
#
# Run Terminal-Bench with Hybrid Adaptive UAM Context (Option 4)
#
# Key improvements over previous UAM runs:
# 1. Task classification skips UAM for reasoning/scheduling tasks
# 2. Time pressure assessment prevents timeout regressions
# 3. Historical benefit tracking optimizes context loading
# 4. Progressive context escalation on retry
# 5. Environment bootstrapping (Factory Droid technique)
# 6. Risk-aware prompting (Apex2 technique)
#
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Source environment
source ~/.profile 2>/dev/null || true
# Task classification function (mirrors TypeScript logic)
classify_task() {
local task="$1"
case "$task" in
# Pure reasoning/scheduling - SKIP UAM (prevents timeout regression)
constraints-scheduling|chess-best-move|regex-chess)
echo "skip"
;;
# Security tasks - FULL UAM
crack-7z-hash|password-recovery|vulnerable-secret|filter-js-from-html|break-filter-js-from-html)
echo "security"
;;
# File operations - FULL UAM
extract-elf|sqlite-db-truncate|db-wal-recovery)
echo "file-ops"
;;
# Legacy/modernization - FULL UAM
cobol-modernization)
echo "legacy"
;;
# ML tasks - MINIMAL UAM (risk-aware)
gpt2-codegolf)
echo "ml"
;;
# General coding - MINIMAL UAM
code-from-image|financial-document-processor|log-summary-date-ranges)
echo "coding"
;;
# Default
*)
echo "general"
;;
esac
}
# Generate context based on classification (Hybrid Adaptive logic)
get_adaptive_context() {
local category="$1"
case "$category" in
skip)
# No context for pure reasoning tasks
echo ""
;;
security)
cat << 'EOF'
## UAM Memory Context (Security)
### Security
- XSS: Use bleach.clean() or DOMPurify. Remove script, onclick, onerror, javascript:
- Password cracking: hashcat -m 11600 for 7z, -m 0 MD5, -m 1000 NTLM, john for CPU
- Binary secrets: strings, objdump -d, check .rodata section
- CVE exploitation: Research exact steps before attempting, some operations irreversible
### Tools
- hashcat: GPU password cracking, -m flag for hash type
- john: CPU password cracking, flexible format support
- readelf -a / objdump -d: Binary analysis
- strings: Extract printable strings from binaries
EOF
;;
file-ops)
cat << 'EOF'
## UAM Memory Context (File Operations)
### File Formats
- ELF: Program headers at e_phoff. Use struct.unpack('<HH...') for parsing
- SQLite WAL: Header 32 bytes, frames follow. PRAGMA wal_checkpoint(TRUNCATE) to recover
- 7z: Install p7zip-full, use 7z x -p'password' for password protected archives
### Coding
- Use absolute paths (/app/...) not relative
- Verify file exists before reading
- Handle edge cases in parsing
EOF
;;
legacy)
cat << 'EOF'
## UAM Memory Context (Legacy Code)
### Legacy Code
- COBOL: Fixed-format columns (1-6 sequence, 7 indicator, 8-72 code)
- WORKING-STORAGE SECTION for variables
- Modernization: Preserve business logic, update data structures
- Test with original inputs to verify behavior matches
EOF
;;
ml)
cat << 'EOF'
## UAM Memory Context (ML - Risk Aware)
### ML Training (Risk-Aware)
- CRITICAL: Test with small epochs/batch first before full runs
- Training can exceed 5 minutes - verify shapes and configs early
- Check GPU: nvidia-smi, CUDA_VISIBLE_DEVICES for GPU selection
- Cache datasets to avoid re-downloads
### Coding
- Use absolute paths (/app/...)
- Match exact output format required
EOF
;;
coding|general)
cat << 'EOF'
## UAM Memory Context (Coding)
### Coding
- Use absolute paths (/app/...) not relative
- Verify file exists before reading
- Handle edge cases in parsing
- Match exact output format required
EOF
;;
esac
}
# Main execution
TASKS=(
"crack-7z-hash"
"filter-js-from-html"
"cobol-modernization"
"code-from-image"
"sqlite-db-truncate"
"extract-elf"
"db-wal-recovery"
"vulnerable-secret"
"chess-best-move"
"log-summary-date-ranges"
"password-recovery"
"gpt2-codegolf"
"constraints-scheduling"
"financial-document-processor"
"regex-chess"
)
TIMESTAMP=$(date +%Y-%m-%d__%H-%M-%S)
JOBS_DIR="$PROJECT_ROOT/jobs/tbench_hybrid_adaptive_$TIMESTAMP"
echo "=============================================="
echo " Hybrid Adaptive UAM Terminal-Bench Runner"
echo " (Option 4 Implementation)"
echo "=============================================="
echo "Tasks: ${#TASKS[@]}"
echo "Output: $JOBS_DIR"
echo ""
# Show classification plan
echo "Task Classification (Hybrid Adaptive):"
echo "---------------------------------------"
SKIP_COUNT=0
FULL_COUNT=0
MINIMAL_COUNT=0
for task in "${TASKS[@]}"; do
category=$(classify_task "$task")
case "$category" in
skip)
echo " $task → NO UAM (reasoning/games - prevents timeout)"
((SKIP_COUNT++))
;;
security|file-ops|legacy)
echo " $task → FULL UAM ($category context)"
((FULL_COUNT++))
;;
ml|coding|general)
echo " $task → MINIMAL UAM ($category context)"
((MINIMAL_COUNT++))
;;
esac
done
echo ""
echo "Summary: $SKIP_COUNT skip, $FULL_COUNT full, $MINIMAL_COUNT minimal"
echo ""
# Build combined context (excluding pure reasoning tasks)
# This is the Hybrid Adaptive context that combines relevant sections
COMBINED_CONTEXT="## UAM Hybrid Adaptive Memory Context
### Security (for security tasks)
- XSS: bleach.clean(), remove script/onclick/javascript:
- Password: hashcat -m 11600 (7z), -m 0 (MD5), john for CPU
- Binary: strings, objdump -d, check .rodata
### File Formats (for file-ops tasks)
- ELF: e_phoff for headers, struct.unpack('<HH...')
- SQLite WAL: PRAGMA wal_checkpoint(TRUNCATE)
- 7z: p7zip, 7z x -p'password'
### Legacy (for modernization tasks)
- COBOL: columns 1-6 sequence, 7 indicator, 8-72 code
- WORKING-STORAGE for variables
- Test with original inputs
### Coding (minimal, for applicable tasks)
- Use absolute paths /app/
- Verify files exist before reading
- Match exact output format"
echo "Starting benchmark..."
echo ""
# Build task arguments
TASK_ARGS=""
for task in "${TASKS[@]}"; do
TASK_ARGS="$TASK_ARGS -t $task"
done
# Run with Harbor
harbor run -d terminal-bench@2.0 \
-a claude-code \
-m anthropic/claude-opus-4-5 \
--ak "append_system_prompt=$COMBINED_CONTEXT" \
$TASK_ARGS \
-k 1 \
--jobs-dir "$JOBS_DIR" \
-n 8 \
--timeout-multiplier 2.0
echo ""
echo "=============================================="
echo " Benchmark Complete"
echo "=============================================="
echo "Results: $JOBS_DIR/result.json"
echo ""
echo "Expected improvements over baseline:"
echo " - constraints-scheduling: Should PASS (no UAM overhead)"
echo " - extract-elf: Should PASS (file format context)"
echo " - password-recovery: Should PASS (security context)"
echo ""
echo "Compare with: jobs/tbench_uam_15/*/result.json"
#!/bin/bash
#
# Run Terminal-Bench 2.0 with UAM-integrated agents
# Compares Droid with and without UAM memory across multiple models
#
# This benchmark uses the FACTORY_API_KEY which provides access to all models:
# - Claude Opus 4.5 (Anthropic)
# - GPT 5.2 Codex (OpenAI)
# - GLM 4.7 (Zhipu)
#
# Usage:
# export FACTORY_API_KEY="your-factory-api-key"
# ./scripts/run-terminal-bench.sh
#
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
RESULTS_DIR="$PROJECT_ROOT/benchmark-results"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# Models to test - Harbor/LiteLLM format (provider/model)
# These are mapped through Factory API when using droid
HARBOR_MODELS=(
"anthropic/claude-opus-4-5"
"openai/gpt-5.2-codex"
"zhipu/glm-4.7"
)
# Factory/Droid model names (used by improved-benchmark.ts)
FACTORY_MODELS=(
"claude-opus-4-5-20251101"
"gpt-5.2-codex"
"glm-4.7"
)
# Configuration
N_CONCURRENT=${N_CONCURRENT:-4}
TIMEOUT_MULT=${TIMEOUT_MULT:-1.0}
DATASET="terminal-bench@2.0"
# Check for API keys
check_api_keys() {
# Factory API key provides access to all models
if [ -z "$FACTORY_API_KEY" ] && [ -z "$DROID_API_KEY" ]; then
echo "Error: FACTORY_API_KEY or DROID_API_KEY must be set"
echo ""
echo "The Factory API key provides unified access to:"
echo " - Claude Opus 4.5 (Anthropic)"
echo " - GPT 5.2 Codex (OpenAI)"
echo " - GLM 4.7 (Zhipu)"
echo ""
echo "Get your key at: https://app.factory.ai/settings/api-keys"
exit 1
fi
echo "Using Factory API for model access"
# For Harbor's direct provider access, these may also be needed
if [ -z "$ANTHROPIC_API_KEY" ]; then
echo "Note: ANTHROPIC_API_KEY not set - Harbor will use Factory routing"
fi
if [ -z "$OPENAI_API_KEY" ]; then
echo "Note: OPENAI_API_KEY not set - Harbor will use Factory routing"
fi
}
# Create results directory
mkdir -p "$RESULTS_DIR"
# Run benchmark for a specific model with UAM
run_with_uam() {
local model=$1
local model_safe=$(echo "$model" | tr '.-' '_')
local job_name="uam_${model_safe}_${TIMESTAMP}"
echo "=================================================="
echo "Running: $model WITH UAM memory"
echo "=================================================="
harbor run \
-d "$DATASET" \
-a claude-code \
-m "$model" \
-n "$N_CONCURRENT" \
--timeout-multiplier "$TIMEOUT_MULT" \
--job-name "$job_name" \
--jobs-dir "$RESULTS_DIR" \
--ak "use_uam=true" \
--ak "project_root=$PROJECT_ROOT" \
2>&1 | tee "$RESULTS_DIR/${job_name}.log"
echo "Results saved to: $RESULTS_DIR/$job_name"
}
# Run benchmark for a specific model without UAM (baseline)
run_without_uam() {
local model=$1
local model_safe=$(echo "$model" | tr '.-' '_')
local job_name="baseline_${model_safe}_${TIMESTAMP}"
echo "=================================================="
echo "Running: $model WITHOUT UAM (baseline)"
echo "=================================================="
harbor run \
-d "$DATASET" \
-a claude-code \
-m "$model" \
-n "$N_CONCURRENT" \
--timeout-multiplier "$TIMEOUT_MULT" \
--job-name "$job_name" \
--jobs-dir "$RESULTS_DIR" \
2>&1 | tee "$RESULTS_DIR/${job_name}.log"
echo "Results saved to: $RESULTS_DIR/$job_name"
}
# Run with custom UAM agent
run_custom_agent() {
local model=$1
local with_memory=$2
local model_safe=$(echo "$model" | tr '.-' '_')
local memory_label=$([ "$with_memory" = "true" ] && echo "uam" || echo "baseline")
local job_name="${memory_label}_custom_${model_safe}_${TIMESTAMP}"
echo "=================================================="
echo "Running: $model with custom UAM agent (memory=$with_memory)"
echo "=================================================="
harbor run \
-d "$DATASET" \
--agent-import-path "$PROJECT_ROOT/src/harbor/uam_agent:UAMAgent" \
-m "$model" \
-n "$N_CONCURRENT" \
--timeout-multiplier "$TIMEOUT_MULT" \
--job-name "$job_name" \
--jobs-dir "$RESULTS_DIR" \
--ak "use_memory=$with_memory" \
--ak "project_root=$PROJECT_ROOT" \
2>&1 | tee "$RESULTS_DIR/${job_name}.log"
echo "Results saved to: $RESULTS_DIR/$job_name"
}
# Generate comparison report
generate_report() {
echo "=================================================="
echo "Generating comparison report..."
echo "=================================================="
local report_file="$RESULTS_DIR/TERMINAL_BENCH_COMPARISON_${TIMESTAMP}.md"
cat > "$report_file" << EOF
# Terminal-Bench 2.0 UAM Comparison Report
**Generated:** $(date -Iseconds)
**Dataset:** $DATASET (89 tasks)
## Configuration
- Concurrent trials: $N_CONCURRENT
- Timeout multiplier: $TIMEOUT_MULT
- Models tested: ${MODELS[*]}
## Results Summary
| Model | Without UAM | With UAM | Improvement |
|-------|-------------|----------|-------------|
EOF
# Parse results from each run
for model in "${MODELS[@]}"; do
local model_safe=$(echo "$model" | tr '.-' '_')
local baseline_dir="$RESULTS_DIR/baseline_${model_safe}_${TIMESTAMP}"
local uam_dir="$RESULTS_DIR/uam_${model_safe}_${TIMESTAMP}"
local baseline_acc="N/A"
local uam_acc="N/A"
local improvement="N/A"
# Try to read results
if [ -f "$baseline_dir/summary.json" ]; then
baseline_acc=$(jq -r '.accuracy // "N/A"' "$baseline_dir/summary.json" 2>/dev/null || echo "N/A")
fi
if [ -f "$uam_dir/summary.json" ]; then
uam_acc=$(jq -r '.accuracy // "N/A"' "$uam_dir/summary.json" 2>/dev/null || echo "N/A")
fi
if [[ "$baseline_acc" != "N/A" && "$uam_acc" != "N/A" ]]; then
improvement=$(echo "$uam_acc - $baseline_acc" | bc 2>/dev/null || echo "N/A")
improvement="${improvement}%"
fi
echo "| $model | $baseline_acc | $uam_acc | $improvement |" >> "$report_file"
done
cat >> "$report_file" << EOF
## Detailed Results
See individual job directories for full task-level results.
### Key Findings
Based on our improved UAM implementation:
- Dynamic memory retrieval based on task classification
- Hierarchical prompting with recency bias
- Multi-turn execution with error feedback
### Files
EOF
ls -la "$RESULTS_DIR"/*_${TIMESTAMP}* 2>/dev/null >> "$report_file" || echo "No result directories found" >> "$report_file"
echo ""
echo "Report saved to: $report_file"
}
# Main execution
main() {
echo "=================================================="
echo "Terminal-Bench 2.0 UAM Comparison Benchmark"
echo "=================================================="
echo "Timestamp: $TIMESTAMP"
echo "Results directory: $RESULTS_DIR"
echo ""
check_api_keys
# Parse arguments
local run_baseline=true
local run_uam=true
local use_custom=false
local selected_models=("${HARBOR_MODELS[@]}")
while [[ $# -gt 0 ]]; do
case $1 in
--baseline-only)
run_uam=false
shift
;;
--uam-only)
run_baseline=false
shift
;;
--custom-agent)
use_custom=true
shift
;;
--model)
selected_models=("$2")
shift 2
;;
--help)
echo "Usage: $0 [options]"
echo "Options:"
echo " --baseline-only Run only baseline (no UAM)"
echo " --uam-only Run only with UAM"
echo " --custom-agent Use custom UAM agent instead of claude-code"
echo " --model MODEL Test only this model"
echo " --help Show this help"
exit 0
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Run benchmarks
for model in "${selected_models[@]}"; do
if [ "$run_baseline" = true ]; then
if [ "$use_custom" = true ]; then
run_custom_agent "$model" "false"
else
run_without_uam "$model"
fi
fi
if [ "$run_uam" = true ]; then
if [ "$use_custom" = true ]; then
run_custom_agent "$model" "true"
else
run_with_uam "$model"
fi
fi
done
# Generate report
generate_report
echo ""
echo "=================================================="
echo "Benchmark complete!"
echo "=================================================="
}
main "$@"
#!/bin/bash
#
# Run UAM Improved Benchmark using Factory API
#
# This benchmark tests UAM memory impact on coding tasks using droid CLI
# which accesses all models through a single Factory API key.
#
# Models tested:
# - Claude Opus 4.5 (Anthropic)
# - GPT 5.2 Codex (OpenAI)
# - GLM 4.7 (Zhipu)
#
# Usage:
# export FACTORY_API_KEY="your-factory-api-key"
# ./scripts/run-uam-benchmark.sh
#
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
echo "=================================================="
echo "UAM Improved Benchmark"
echo "=================================================="
# Check for Factory API key
if [ -z "$FACTORY_API_KEY" ] && [ -z "$DROID_API_KEY" ]; then
echo "Error: FACTORY_API_KEY or DROID_API_KEY must be set"
echo ""
echo "The Factory API key provides unified access to:"
echo " - Claude Opus 4.5 (Anthropic)"
echo " - GPT 5.2 Codex (OpenAI)"
echo " - GLM 4.7 (Zhipu)"
echo ""
echo "Get your key at: https://app.factory.ai/settings/api-keys"
exit 1
fi
echo "Factory API key is set ✓"
echo ""
# Verify droid is available
if ! command -v droid &> /dev/null; then
echo "Error: droid CLI not found"
echo "Install with: npm install -g @anthropic-ai/droid"
exit 1
fi
echo "droid CLI is available ✓"
echo ""
# Build project
echo "Building project..."
cd "$PROJECT_ROOT"
npm run build
# Run benchmark
echo ""
echo "Starting benchmark..."
echo "Models: Claude Opus 4.5, GLM 4.7, GPT 5.2 Codex"
echo "Tasks: 6 coding challenges"
echo "Comparison: With vs Without UAM Memory"
echo ""
npx tsx src/benchmarks/improved-benchmark.ts
echo ""
echo "=================================================="
echo "Benchmark Complete"
echo "=================================================="
echo "Results saved to: IMPROVED_BENCHMARK_RESULTS.md"
#!/usr/bin/env bash
set -euo pipefail
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
HOOKS_DIR="${PROJECT_ROOT}/.git/hooks"
echo -e "${BLUE}🔧 Universal Agent Memory - Complete Setup${NC}"
echo "================================================"
echo ""
# ============================================================================
# DEPENDENCY CHECKS
# ============================================================================
echo -e "${BLUE}Checking dependencies...${NC}"
echo ""
MISSING_DEPS=()
RECOMMENDED_DEPS=()
# Required dependencies
echo -e "${YELLOW}Required dependencies:${NC}"
if ! command -v node &> /dev/null; then
echo -e " ${RED}✗${NC} Node.js (>= 18.0.0)"
MISSING_DEPS+=("Node.js >= 18.0.0")
else
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
if [ "$NODE_VERSION" -lt 18 ]; then
echo -e " ${RED}✗${NC} Node.js (>= 18.0.0, found $(node -v))"
MISSING_DEPS+=("Node.js >= 18.0.0")
else
echo -e " ${GREEN}✓${NC} Node.js $(node -v)"
fi
fi
if ! command -v npm &> /dev/null; then
echo -e " ${RED}✗${NC} npm"
MISSING_DEPS+=("npm")
else
echo -e " ${GREEN}✓${NC} npm $(npm -v)"
fi
if ! command -v git &> /dev/null; then
echo -e " ${RED}✗${NC} git"
MISSING_DEPS+=("git")
else
echo -e " ${GREEN}✓${NC} git $(git --version | cut -d' ' -f3)"
fi
if ! command -v npx &> /dev/null; then
echo -e " ${RED}✗${NC} npx"
MISSING_DEPS+=("npx")
else
echo -e " ${GREEN}✓${NC} npx"
fi
echo ""
echo -e "${YELLOW}Recommended dependencies (optional but useful):${NC}"
if command -v docker &> /dev/null; then
echo -e " ${GREEN}✓${NC} Docker (enables local Qdrant for semantic search)"
else
echo -e " ${YELLOW}⚠${NC} Docker (install for local Qdrant: `curl -fsSL https://get.docker.com | sh`)"
RECOMMENDED_DEPS+=("Docker")
fi
if command -v python3 &> /dev/null; then
PYTHON_VERSION=$(python3 --version | cut -d' ' -f2)
echo -e " ${GREEN}✓${NC} Python 3 (${PYTHON_VERSION}) (enables Pattern RAG)"
else
echo -e " ${YELLOW}⚠${NC} Python 3 (install for Pattern RAG: `brew install python` or `apt install python3`)"
RECOMMENDED_DEPS+=("Python 3")
fi
if command -v pre-commit &> /dev/null; then
echo -e " ${GREEN}✓${NC} pre-commit (enables advanced git hooks)"
else
echo -e " ${YELLOW}⚠${NC} pre-commit (install for advanced hooks: `pip install pre-commit`)"
fi
echo ""
# ============================================================================
# INSTALLATION
# ============================================================================
if [ ${#MISSING_DEPS[@]} -gt 0 ]; then
echo -e "${RED}❌ Missing required dependencies:${NC}"
for dep in "${MISSING_DEPS[@]}"; do
echo -e " - ${dep}"
done
echo ""
echo "Please install the missing dependencies and run this script again."
echo ""
echo "Quick install commands:"
echo " # macOS:"
echo " brew install node git python docker"
echo ""
echo " # Ubuntu/Debian:"
echo " curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -"
echo " sudo apt-get install -y nodejs python3 docker.io"
echo ""
echo " # Windows (using winget):"
echo " winget install OpenJS.NodeJS.LTS"
echo " winget install Git.Git"
echo " winget install Python.Python.3.12"
echo " winget install Docker.DockerDesktop"
echo ""
exit 1
fi
# Install npm dependencies
echo -e "${BLUE}Installing npm dependencies...${NC}"
cd "$PROJECT_ROOT"
if [ ! -d "node_modules" ]; then
npm install
echo -e "${GREEN}✓${NC} npm dependencies installed"
else
echo -e "${GREEN}✓${NC} npm dependencies already installed (skipping)"
fi
# Build TypeScript
echo ""
echo -e "${BLUE}Building TypeScript...${NC}"
npm run build
if [ $? -eq 0 ]; then
echo -e "${GREEN}✓${NC} TypeScript build completed"
else
echo -e "${RED}✗${NC} TypeScript build failed"
exit 1
fi
# ============================================================================
# GIT HOOKS SETUP
# ============================================================================
echo ""
echo -e "${BLUE}Setting up git hooks...${NC}"
# Create hooks directory if it doesn't exist
if [ ! -d "$HOOKS_DIR" ]; then
echo -e " ${YELLOW}⚠${NC} Not a git repository, skipping hooks setup"
else
# Create hooks directory
mkdir -p "$HOOKS_DIR"
# Pre-commit hook - ensures worktree usage and code quality
cat > "${HOOKS_DIR}/pre-commit" << 'EOF'
#!/bin/bash
#
# UAM Pre-commit Hook
#
# Ensures:
# 1. No secrets are committed
# 2. Code passes linting
# 3. Tests pass (if modified files include tests)
#
# Check for secrets
if grep -rE "(api_key|apikey|password|secret|token)\s*=\s*['\"][^'\"]+['\"]" --include="*.ts" --include="*.js" --include="*.json" . 2>/dev/null | grep -v node_modules | grep -v ".worktrees" | grep -v dist; then
echo "Error: Potential secrets detected in committed files!"
echo "Please use environment variables for sensitive data."
exit 1
fi
# Run linter
if npm run lint -- --max-warnings=0 2>/dev/null; then
echo "✓ Linting passed"
else
echo "Error: Linting failed. Run 'npm run lint:fix' to fix automatically."
exit 1
fi
echo "Pre-commit checks passed"
exit 0
EOF
chmod +x "${HOOKS_DIR}/pre-commit"
echo " ✓ Created pre-commit hook"
# Commit-msg hook - validates commit messages
cat > "${HOOKS_DIR}/commit-msg" << 'EOF'
#!/bin/bash
#
# UAM Commit-msg Hook
#
# Ensures commit messages follow conventional commits format:
# - feat: New feature
# - fix: Bug fix
# - docs: Documentation
# - style: Formatting
# - refactor: Code refactoring
# - test: Tests
# - chore: Maintenance
#
COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")
# Skip if commit is empty or merge commit
if [[ -z "$COMMIT_MSG" ]] || [[ "$COMMIT_MSG" == "Merge"* ]]; then
exit 0
fi
# Check for conventional commit format
if echo "$COMMIT_MSG" | grep -qE "^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\([a-z-]+\))?: .+"; then
echo "✓ Commit message format valid"
exit 0
else
echo "Warning: Commit message doesn't follow conventional commits format."
echo "Recommended format: type(scope): description"
echo "Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build, revert"
echo ""
echo "Examples:"
echo " feat: Add worktree creation command"
echo " fix(api): Resolve memory database path issue"
echo " docs: Update README with setup instructions"
echo ""
echo "Continue with commit? [y/N] "
read -r response
if [[ "$response" =~ ^(yes|y|Y)$ ]]; then
exit 0
else
echo "Commit aborted. Please edit your commit message."
exit 1
fi
fi
EOF
chmod +x "${HOOKS_DIR}/commit-msg"
echo " ✓ Created commit-msg hook"
# Pre-push hook - runs tests before pushing
cat > "${HOOKS_DIR}/pre-push" << 'EOF'
#!/bin/bash
#
# UAM Pre-push Hook
#
# Runs tests before pushing to remote
#
echo "Running tests before push..."
if npm test 2>&1 | tail -5; then
if [ ${PIPESTATUS[0]} -eq 0 ]; then
echo "✓ All tests passed"
exit 0
fi
fi
echo "Error: Tests failed. Fix tests before pushing."
exit 1
EOF
chmod +x "${HOOKS_DIR}/pre-push"
echo " ✓ Created pre-push hook"
echo ""
echo -e "${GREEN}✓${NC} Git hooks configured successfully"
fi
# ============================================================================
# OPTIONAL: CREATE .GITCHRCL (for GitHub CLI)
# ============================================================================
if command -v gh &> /dev/null; then
echo ""
echo -e "${BLUE}GitHub CLI detected. Setting up default PR template...${NC}"
if [ ! -f "${PROJECT_ROOT}/.github/pull_request_template.md" ]; then
mkdir -p "${PROJECT_ROOT}/.github"
cat > "${PROJECT_ROOT}/.github/pull_request_template.md" << 'EOF'
<!-- UAM Worktree PR Template -->
## Summary
<!-- Describe what this PR does -->
## Changes
<!-- List key changes -->
-
## Testing
<!-- How did you test this? -->
- [ ] Tests pass: `npm test`
- [ ] Linting passes: `npm run lint`
- [ ] Manually tested (if applicable)
## Related Issue
<!-- Link to related issue if any -->
Closes #
---
<!-- UAM - Created via worktree: uam worktree pr -->
EOF
echo " ✓ Created PR template"
fi
fi
# ============================================================================
# SETUP COMPLETE
# ============================================================================
echo ""
echo -e "${GREEN}✅ Setup complete!${NC}"
echo ""
if [ ${#RECOMMENDED_DEPS[@]} -gt 0 ]; then
echo -e "${YELLOW}Recommended: Install missing optional dependencies${NC}"
for dep in "${RECOMMENDED_DEPS[@]}"; do
echo " - ${dep}"
done
echo ""
echo "You can install these later. Core functionality will work without them."
echo ""
fi
echo -e "${BLUE}Next steps:${NC}"
echo ""
echo "1. Initialize UAM in your project:"
echo " npx universal-agent-memory init"
echo ""
echo "2. Review the generated CLAUDE.md"
echo ""
echo "3. Start working - your AI assistant will follow the workflows!"
echo ""
echo "Optional: Set up cloud memory backends"
echo " export GITHUB_TOKEN=your_token"
echo " export QDRANT_API_KEY=your_key"
echo " export QDRANT_URL=your_url"
echo ""
echo "Documentation: https://github.com/DammianMiller/universal-agent-memory"
+8
-3
{
"name": "universal-agent-memory",
"version": "6.1.0",
"version": "6.1.1",
"description": "Universal AI agent memory system - CLAUDE.md templates, memory, worktrees for Claude Code, Factory.AI, VSCode, OpenCode, Forge",

@@ -22,6 +22,7 @@ "type": "module",

"prepare": "npm run build",
"setup": "bash scripts/setup.sh",
"install:web": "bash scripts/install-web.sh",
"install:desktop": "bash scripts/install-desktop.sh",
"install:all": "bash scripts/install.sh",
"postinstall": "echo '\n✨ Run: npx universal-agent-memory init --interactive'"
"postinstall": "echo '\n✨ Run: npm run setup && npx universal-agent-memory init --interactive'"
},

@@ -90,5 +91,9 @@ "keywords": [

"templates",
"scripts",
"README.md",
"LICENSE"
]
],
"optionalDependencies": {
"prettier": "^3.2.4"
}
}
+268
-447

@@ -8,7 +8,7 @@ # Universal Agent Memory (UAM)

### What if your AI coding assistant could *remember*?
### AI coding assistants that remember
**Every lesson learned. Every bug fixed. Every architectural decision.**
*Not just in one conversation—but forever.*
_Not just in one conversation—but forever._

@@ -19,309 +19,207 @@ </div>

UAM transforms stateless AI coding assistants into **persistent, coordinated agents** that learn from every interaction and never make the same mistake twice.
## Quick Start (30 seconds)
```bash
npm install -g universal-agent-memory && cd your-project && uam init
# Install
npm install -g universal-agent-memory
# Run complete setup (installs dependencies, git hooks, etc.)
npm run setup
# Initialize in your project
uam init
```
**30 seconds to superhuman AI.**
That's it. Your AI now has persistent memory and follows proven workflows.
---
## The Problem We Solve
## Complete Setup
Every time you start a new conversation with your AI assistant:
For a full installation with all features:
- It forgets your project's architectural decisions
- It suggests patterns you've already rejected
- It reintroduces bugs you've already fixed
- It doesn't know *why* the code is the way it is
**You're constantly re-teaching the same lessons.**
UAM fixes this by giving AI agents:
| Capability | What It Means |
|------------|---------------|
| **4-Layer Memory** | Recall decisions from months ago |
| **Hierarchical Memory** | Hot/warm/cold tiering with auto-promotion |
| **58 Optimizations** | Battle-tested from Terminal-Bench 2.0 benchmarking |
| **Pattern Router** | Auto-selects optimal patterns per task |
| **Adaptive Context** | Selectively loads context based on task type and history |
| **Multi-Agent Coordination** | Multiple AIs work without conflicts |
| **Worktree Isolation** | No accidental commits to main |
| **Code Field** | 89% bug detection vs 39% baseline |
| **Completion Gates** | 3 mandatory checks before "done" |
| **MCP Router** | 98%+ token reduction for multi-tool contexts |
| **Pre-execution Hooks** | Domain-specific setup before agent runs |
---
## See It In Action
```bash
# Agent A starts work
$ uam task create --title "Fix auth vulnerability" --type bug --priority 0
✓ Task created: UAM-042
# Install UAM CLI
npm install -g universal-agent-memory
$ uam worktree create fix-auth
✓ Created worktree: 001-fix-auth
Branch: feature/001-fix-auth
Path: .worktrees/001-fix-auth
$ uam agent announce --resource src/auth/* --intent editing
✓ Work announced. No conflicts detected.
# Meanwhile, Agent B checks for conflicts
$ uam agent overlaps --resource src/auth/*
⚠ Agent A (fix-auth) is editing src/auth/*
Suggestion: Wait for completion or coordinate merge order
# Agent A completes and the lesson is preserved
$ uam memory store "CSRF vulnerability in auth: always validate origin header"
✓ Stored in memory (importance: 8/10)
# Weeks later, ANY agent on this project will know:
$ uam memory query "auth security"
[2024-03-15] CSRF vulnerability in auth: always validate origin header
[2024-02-28] Session tokens must be httpOnly and secure
[2024-01-10] Auth refresh flow: use rotating tokens
# Run comprehensive setup
npm run setup
# This will:
# ✓ Check and install dependencies
# ✓ Install npm packages
# ✓ Build TypeScript
# ✓ Configure git hooks (pre-commit, commit-msg, pre-push)
# ✓ Set up GitHub PR templates
```
**The AI never forgets. The team never re-learns.**
### Requirements
---
**Required:**
## Why Developers Love UAM
- Node.js >= 18.0.0
- npm
- git
- npx
### "My AI Finally Understands My Codebase"
**Optional (recommended):**
> *"After 3 months of using UAM, my Claude instance knows more about our architecture than most junior devs. It remembers that we chose Redux over MobX because of time-travel debugging, that our API uses snake_case because of the Python backend, that the auth flow was refactored twice. It's like pair programming with someone who has perfect recall."*
- Docker - for local Qdrant semantic search
- Python 3 - for Pattern RAG indexing
- pre-commit - for advanced git hooks
### "Zero Merge Conflicts in Multi-Agent Workflows"
### Installing Dependencies
> *"We run 5 agents in parallel on different features. Before UAM, we had merge conflicts daily. Now? Zero. The agents announce their work, check for overlaps, and coordinate merge order automatically. It's like they're a team."*
**macOS:**
### "Our CI Bill Dropped 70%"
> *"UAM's deploy batcher changed everything. Instead of 15 CI runs from rapid commits, we get 1-2. Same work, fraction of the cost. The commit squashing alone paid for the setup time."*
---
## Key Features
### 🧠 Endless Context Through Project Memory
**Your AI's context is NOT limited to the conversation.**
Memory persists with the project in SQLite databases that travel with the code:
```bash
brew install node git python docker
```
agents/data/memory/
├── short_term.db # L1/L2: Recent actions + session memories (SQLite)
├── long_term_prepopulated.json # L3: Prepopulated learnings for search
└── historical_context.db # Adaptive context + semantic cache (SQLite/WAL)
```
This means:
- Recall decisions from weeks/months ago
- Learn from past mistakes (gotchas never repeated)
- Understand why code is the way it is
- Seamless handoff between sessions
**Ubuntu/Debian:**
**The AI queries memory before every task** - it never starts from zero.
### 🎯 Intelligent Task Routing
Tasks automatically route to specialized expert droids:
| Task Type | Routed To | Result |
|-----------|-----------|--------|
| TypeScript/JS | `typescript-node-expert` | Proper typing, async patterns |
| Security review | `security-auditor` | OWASP checks, secrets detection |
| Performance | `performance-optimizer` | Algorithm analysis, caching |
| Documentation | `documentation-expert` | Complete, accurate docs |
| Code quality | `code-quality-guardian` | SOLID, complexity checks |
**Missing an expert?** The AI generates one:
```bash
uam droids add rust-expert --capabilities "ownership,lifetimes,async" --triggers "*.rs"
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs python3 docker.io
```
### 🎯 Pattern Router - Battle-Tested Intelligence
**Windows:**
**58 optimizations in v2.7.0 from Terminal-Bench 2.0 analysis.**
Before ANY task, UAM's Pattern Router auto-selects which patterns apply:
```powershell
winget install OpenJS.NodeJS.LTS
winget install Git.Git
winget install Python.Python.3.12
winget install Docker.DockerDesktop
```
=== PATTERN ROUTER ===
Task: Implement user authentication
Classification: file-creation
PATTERNS: P12:[Y] P17:[Y] P20:[N] P11:[N] P35:[N]
ACTIVE: P3, P12, P17
BLOCKING: [none]
VERIFIER: [read tests first]
=== END ===
```
**Key Patterns:**
---
| Pattern | Name | Impact |
|---------|------|--------|
| **P12** | Output Existence Verification | Fixes 37% of agent failures |
| **P17** | Constraint Extraction | Catches "exactly/only/single" requirements |
| **P3** | Pre-execution State Protection | Backups before destructive actions |
| **P20** | Adversarial Thinking | Attack mindset for security bypass tasks |
| **P35** | Decoder-First Analysis | Read decoder BEFORE writing encoder |
| **P11** | Pre-Computed Solutions | Use libraries (Stockfish, scipy) not custom code |
## Recommended Platform: **opencode**
**Pattern Categories:**
- **Core (P1-P12)**: Tool checks, state protection, output verification
- **Constraints (P17)**: Extract hidden requirements from task descriptions
- **Domain (P21-P26)**: Chess, git recovery, compression, polyglot code
- **Verification (P27-P31)**: Output cleanup, smoke tests, round-trip checks
- **Advanced (P32-P36)**: CLI execution, numerical stability, decoder-first analysis
UAM is optimized for **[opencode](https://opencode.ai)** - the local AI coding platform that provides:
**Optimization Categories (#40-#58):**
- **Code Field (#40)**: State assumptions before coding
- **Pattern Router (#41, #47)**: Auto-classification and blocking gates
- **Verifier-First (#53)**: Read tests before implementing
- **Near-Miss Handling (#54)**: 60-89% pass = fix specific failures, don't change approach
- **Compression (#55-#57)**: Reduced template size while preserving effectiveness
- **Persistent sessions** - Memory survives across sessions
- **Plugin architecture** - Pattern RAG, session hooks, and more
- **Local LLM support** - Run Qwen3.5 35B locally via llama.cpp
- **Built-in tooling** - File operations, bash, search, todo management
---
### Setup opencode (Recommended)
### 🔬 What Works vs What Doesn't (From 40-Task Benchmark)
```bash
# Install opencode
npm install -g opencode
**Strengths (100% pass rate in category):**
# Configure local LLM (optional, requires llama.cpp server)
# See: https://opencode.ai/docs/configuration
| Category | Why It Works |
|----------|--------------|
| **ML/Data Processing** | Clear data transformation, pandas/numpy operations |
| **Graphics/Rendering** | Path tracing, POV-Ray - well-defined algorithms |
| **Security Tasks** | Hash cracking, password recovery - tools available |
| **Formal Verification** | Coq proofs - step-by-step tactics |
# Initialize UAM in your project
cd your-project
uam init
```
**Weaknesses (Common failure modes):**
The `opencode.json` configuration file automatically loads UAM plugins for:
| Failure Mode | Fix |
|--------------|-----|
| **"File not created"** (37%) | P12 - Verify outputs exist before completing |
| **Missed constraints** | P17 - Extract "exactly/only/single" keywords |
| **First action destroys state** | P3 - Backup before agent runs |
| **Impossible tasks attempted** | P5/P23 - Detect and refuse immediately |
| **Complex toolchain setup** | Pre-execution hooks for dependencies |
- **Pattern RAG** - Context-aware pattern injection (~12K tokens saved)
- **Session hooks** - Pre-execution setup, memory preservation
- **Agent coordination** - Multi-agent workflows without conflicts
**Near-Misses (High-value improvements):**
### Other Supported Platforms
| Task | Tests | Fix Needed |
|------|-------|------------|
| adaptive-rejection-sampler | 8/9 (89%) | Numerical edge case |
| headless-terminal | 6/7 (86%) | Service startup timing |
| db-wal-recovery | 5/7 (71%) | WAL parsing edge case |
| Platform | Notes |
| --------------- | --------------------------------------- |
| **Factory.AI** | Works well, use `CLAUDE.md` for context |
| **Claude Code** | Desktop app, full UAM support |
| **VSCode** | Use with Claude Code extension |
| **claude.ai** | Web version, limited tooling |
**Tasks That Will Never Pass (Without External Tools):**
- `gpt2-codegolf` - Requires pre-computed weights (500MB → 5KB impossible)
- `chess-best-move` - Requires vision/image parsing
- `break-filter-js-from-html` - Requires pre-computed XSS bypass patterns
---
### 🚦 Completion Gates - Mandatory Quality Checks
## What UAM Gives You
Three gates must pass before the AI reports "done":
### 🧠 Persistent Memory
| Gate | Check | If Fails |
|------|-------|----------|
| **Gate 1** | All output files exist | CREATE immediately |
| **Gate 2** | All constraints satisfied | FIX violations |
| **Gate 3** | All tests pass | ITERATE until 100% |
Your AI never forgets:
```bash
# Gate 1: Verify outputs
ls -la /expected/output.json /expected/result.txt
# If missing → CREATE NOW, don't explain
# Store a lesson
uam memory store "Always validate CSRF tokens in auth flows"
# Gate 2: Check constraints
# Printed checklist with ☐/☑ for each requirement
# Gate 3: Run tests
npm test # Iterate on failures until 100%
# Query later (any agent, any session)
uam memory query "auth security"
```
---
Memory persists in SQLite databases that travel with your code:
### 🔒 Code Field - Better Code Generation
- `agents/data/memory/short_term.db` - Recent actions + session memories
- Semantic search via Qdrant (optional, `uam memory start`)
Based on [context-field research](https://github.com/NeoVertex1/context-field), UAM includes a 4-line prompt that dramatically improves code quality:
### 🎯 Pattern Router
Before every task, UAM auto-selects relevant patterns:
```
Do not write code before stating assumptions.
Do not claim correctness you haven't verified.
Do not handle only the happy path.
Under what conditions does this work?
=== PATTERN ROUTER ===
Task: Fix authentication bug
Classification: bug-fix
ACTIVE: P3, P12, P17
BLOCKING: [none]
=== END ===
```
**Results from 72 tests:**
- 100% assumption stating (vs 0% baseline)
- 89% bug detection in code review (vs 39% baseline)
- 100% refusal of impossible requests (vs 0% baseline)
- 320% more hidden issues found in debugging
**58 battle-tested patterns** from Terminal-Bench 2.0 analysis:
Every code generation task applies Code Field automatically.
- **P12** - Verify outputs exist (fixes 37% of failures)
- **P17** - Extract hidden constraints ("exactly", "only", "single")
- **P3** - Backup before destructive actions
- **P20** - Attack mindset for security tasks
### 🌳 Safe Git Workflows
### 🛡️ Completion Gates
**The AI never commits directly to main.**
Three mandatory checks before "done":
All changes use worktrees:
1. **Output Existence** - All expected files exist
2. **Constraint Compliance** - All requirements verified
3. **Tests Pass** - `npm test` 100%
### 🌳 Safe Worktrees
No more accidental commits to main:
```bash
# AI automatically does this for every change
uam worktree create my-feature
# → Creates .worktrees/001-my-feature/
# → Creates branch feature/001-my-feature
# → Works in isolation
uam worktree pr 001
# → Pushes, creates PR, triggers reviews
uam worktree cleanup 001
# → Removes worktree after merge
# → Creates isolated branch in .worktrees/
# → All changes tracked
uam worktree pr <id>
# → Creates PR, triggers reviews
uam worktree cleanup <id>
# → Clean removal after merge
```
### ✅ Complete Close-Out Workflow
### 🤖 Expert Droids
Work isn't "done" until it's deployed and verified:
Tasks automatically route to specialists:
```
MERGE → DEPLOY → MONITOR → FIX (repeat until 100%)
```
| Task Type | Routed To |
| --------------- | ------------------------ |
| TypeScript/JS | `typescript-node-expert` |
| Security review | `security-auditor` |
| Performance | `performance-optimizer` |
| Documentation | `documentation-expert` |
The AI follows this loop automatically:
1. Get PR approved, merge to main
2. Verify CI/CD runs, check deployment
3. Monitor logs, verify functionality
4. If issues: create hotfix worktree, repeat
---
**The AI stores learnings after every completed task** for future sessions.
## How It Works
## Installation
1. **Install & init** - `npm i -g universal-agent-memory && uam init`
2. **CLAUDE.md generated** - Auto-populated with project structure, commands, patterns
3. **AI reads CLAUDE.md** - Follows embedded workflows automatically
4. **Every task**:
- Pattern Router classifies task and selects patterns
- Adaptive context loads relevant memory
- Agent coordination checks for conflicts
- Worktree created for isolated changes
- Completion gates verify outputs, constraints, tests
- Learnings stored in memory
### npm (Recommended)
---
```bash
npm install -g universal-agent-memory
```
### One-Line Installers
```bash
# Desktop (includes Docker for semantic search)
bash <(curl -fsSL https://raw.githubusercontent.com/DammianMiller/universal-agent-memory/main/scripts/install-desktop.sh)
# Web browsers (claude.ai, factory.ai)
bash <(curl -fsSL https://raw.githubusercontent.com/DammianMiller/universal-agent-memory/main/scripts/install-web.sh)
```
## Commands

@@ -331,105 +229,45 @@

| Command | Description |
|---------|-------------|
| `uam init` | Initialize/update UAM (auto-merges, never loses data) |
| `uam generate` | Regenerate CLAUDE.md from project analysis |
| `uam update` | Update templates while preserving customizations |
| `uam analyze` | Analyze project structure and generate metadata |
| Command | Description |
| -------------- | ------------------------------------------------ |
| `uam init` | Initialize/update UAM (never loses data) |
| `uam generate` | Regenerate CLAUDE.md from project analysis |
| `uam update` | Update templates while preserving customizations |
### Memory
| Command | Description |
|---------|-------------|
| `uam memory status` | Check memory system status |
| `uam memory query <search>` | Search memories |
| `uam memory store <content>` | Store a learning |
| `uam memory start` | Start Qdrant for semantic search |
| `uam memory prepopulate` | Populate from docs and git history |
| Command | Description |
| ---------------------------- | -------------------------------- |
| `uam memory status` | Check memory system status |
| `uam memory query <search>` | Search memories |
| `uam memory store <content>` | Store a learning |
| `uam memory start` | Start Qdrant for semantic search |
### Tasks
| Command | Description |
|---------|-------------|
| `uam task create` | Create tracked task |
| `uam task list` | List all tasks |
| `uam task claim <id>` | Claim task (announces to other agents) |
| `uam task release <id>` | Complete task |
| `uam task ready` | List tasks ready to work on |
| `uam task stats` | Show task statistics |
| Command | Description |
| ----------------------- | -------------------------------------- |
| `uam task create` | Create tracked task |
| `uam task list` | List all tasks |
| `uam task claim <id>` | Claim task (announces to other agents) |
| `uam task release <id>` | Complete task |
### Worktrees
| Command | Description |
|---------|-------------|
| `uam worktree create <name>` | Create isolated branch |
| `uam worktree pr <id>` | Create PR from worktree |
| `uam worktree cleanup <id>` | Remove worktree |
| `uam worktree list` | List all worktrees |
| Command | Description |
| ---------------------------- | ----------------------- |
| `uam worktree create <name>` | Create isolated branch |
| `uam worktree pr <id>` | Create PR from worktree |
| `uam worktree cleanup <id>` | Remove worktree |
### Droids
| Command | Description |
|---------|-------------|
| `uam droids list` | List available expert droids |
| `uam droids add <name>` | Create new expert droid |
| `uam droids import <path>` | Import droids from another platform |
| Command | Description |
| ----------------------- | ---------------------------- |
| `uam droids list` | List available expert droids |
| `uam droids add <name>` | Create new expert droid |
### Coordination
---
| Command | Description |
|---------|-------------|
| `uam agent status` | View active agents |
| `uam agent overlaps` | Check for file conflicts |
| `uam agent announce` | Announce intent to work on a resource |
| `uam coord status` | Coordination overview |
## Architecture
### Deploy Batching
| Command | Description |
|---------|-------------|
| `uam deploy queue` | Queue a deploy action for batching |
| `uam deploy batch` | Create a batch from pending actions |
| `uam deploy execute` | Execute a deploy batch |
| `uam deploy flush` | Flush all pending deploys |
### Multi-Model Architecture
| Command | Description |
|---------|-------------|
| `uam model status` | Show model router status |
| `uam model list` | List available models |
| `uam model fingerprint` | Show model performance fingerprints |
### MCP Router (98%+ token reduction)
| Command | Description |
|---------|-------------|
| `uam mcp-router start` | Start hierarchical MCP router |
| `uam mcp-router stats` | Show router statistics and token savings |
| `uam mcp-router discover` | Discover tools matching a query |
| `uam mcp-router list` | List configured MCP servers |
## How It Works
1. **Install & Init**: `npm i -g universal-agent-memory && uam init`
2. **CLAUDE.md Generated**: Auto-populated with project structure, commands, patterns, droids, and memory system instructions
3. **AI Reads CLAUDE.md**: Follows the embedded workflows automatically
4. **Every Task**:
- Pattern Router classifies task and selects applicable patterns
- Adaptive context decides what memory to load (none/minimal/full)
- Dynamic retrieval queries relevant memories from all tiers
- Check for agent overlaps before starting work
- Route to specialist droids if needed
- Create worktree for isolated changes
- Apply Code Field for better code generation
- Run completion gates: outputs exist, constraints met, tests pass
- Store learnings in memory for future sessions
5. **Close-Out**: Merge → Deploy → Monitor → Fix loop until 100%
## Memory Architecture
### 4-Layer Memory System

@@ -446,44 +284,50 @@

### Hierarchical Memory (Hot/Warm/Cold Tiering)
### Hierarchical Memory (Hot/Warm/Cold)
On top of the 4-layer system, UAM implements hierarchical memory management:
- **HOT** (10 entries) - In-context, always included → <1ms access
- **WARM** (50 entries) - Cached, promoted on access → <5ms access
- **COLD** (500 entries) - Archived, semantic search → ~50ms access
```
HOT (10 entries) → In-context, always included → <1ms access
WARM (50 entries) → Cached, promoted on access → <5ms access
COLD (500 entries) → Archived, semantic search only → ~50ms access
```
### Pattern RAG
- **Time-decay importance**: `importance * (0.95 ^ days_since_access)`
- **Auto-promotion**: Frequently accessed cold/warm entries promote to hotter tiers
- **Consolidation**: Old warm entries summarized into compressed cold entries
- **SQLite persistence**: Survives across sessions via `hierarchical_memory` table
Dynamically retrieves relevant patterns from Qdrant:
### Adaptive Context System
- Queries `agent_patterns` collection
- Injects ~2 patterns per task (saves ~12K tokens)
- Filters by similarity score (default 0.35)
- Avoids duplicate injections per session
The memory system selectively loads context based on task classification:
---
- **21 optimizations** including SQLite-backed historical benefit tracking
- **TF-IDF-like keyword scoring** for section relevance
- **13 domain-specific context sections** (security, file formats, git recovery, etc.)
- **Error-to-section mapping** for progressive escalation on failure
- **Semantic caching** for task-to-outcome mappings
## Configuration
### Additional Memory Features
### opencode.json (Platform-specific)
- **Dynamic retrieval**: Adaptive depth based on query complexity (simple/moderate/complex)
- **Semantic compression**: 2-3x token reduction while preserving meaning
- **Speculative cache**: Pre-warms queries based on category patterns
- **Deduplication**: SHA-256 content hash + Jaccard similarity (0.8 threshold)
- **Feedback loop**: `recordTaskFeedback()` captures success/failure to improve future runs
- **Model router**: Per-model performance fingerprints by task category
```json
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"llama.cpp": {
"name": "llama-server (local)",
"options": {
"baseURL": "http://localhost:8080/v1",
"apiKey": "sk-qwen35b"
},
"models": {
"qwen35-a3b-iq4xs": {
"name": "Qwen3.5 35B A3B (IQ4_XS)",
"limit": {
"context": 262144,
"output": 16384
}
}
}
}
},
"model": "llama.cpp/qwen35-a3b-iq4xs"
}
```
**Data is never deleted.** Memory databases persist with the project.
### .uam.json (Project-specific)
Update with `uam init` or `uam generate` always merges - nothing is lost.
## Configuration
Configuration in `.uam.json`:
```json

@@ -502,7 +346,2 @@ {

"directory": ".worktrees"
},
"template": {
"sections": {
"codeField": true
}
}

@@ -512,100 +351,93 @@ }

## Platform Support
---
| Platform | Context File | Works With |
|----------|--------------|------------|
| Claude Code | `CLAUDE.md` | Desktop app |
| Factory.AI | `CLAUDE.md` | Desktop/web |
| claude.ai | `CLAUDE.md` | Web browser |
| VSCode | `CLAUDE.md` | Extensions |
## Requirements
## Built-in Expert Droids
### Required Dependencies
| Droid | Specialization | When Used |
|-------|----------------|-----------|
| `code-quality-guardian` | SOLID, complexity, naming | Before every PR |
| `security-auditor` | OWASP, secrets, injection (enhanced with 150+ security sources) | Before every PR |
| `performance-optimizer` | Algorithms, memory, caching | On request |
| `documentation-expert` | JSDoc, README, accuracy | On request |
| `debug-expert` | Dependency conflicts, runtime errors, SWE-bench debugging | Error handling |
| `sysadmin-expert` | Kernel, QEMU, networking, DNS, systemd | Infrastructure tasks |
| `ml-training-expert` | Model training, MTEB, RL, datasets | ML tasks |
| `terminal-bench-optimizer` | Task routing, time budgets, strategy orchestration | Benchmarking |
| Dependency | Version | Purpose |
| ---------- | ----------------- | --------------------------- |
| Node.js | >= 18.0.0 | Runtime environment |
| npm | Latest | Package manager |
| git | Latest | Version control (git hooks) |
| npx | Included with npm | Run CLI tools |
## Built-in Skills
### Optional Dependencies
| Skill | Purpose | Trigger |
|-------|---------|---------|
| `balls-mode` | Decomposed reasoning with confidence scoring | Complex decisions, debugging |
| `cli-design-expert` | CLI/TUI design patterns, UX, help systems | Building CLI tools |
| `typescript-node-expert` | TypeScript best practices, strict typing | TypeScript projects |
| `terminal-bench-strategies` | Proven strategies for Terminal-Bench tasks | Benchmark tasks |
| `unreal-engine-developer` | UE5, Blueprints, C++, Python scripting | Game development |
| `sec-context-review` | Security context review patterns | Security analysis |
| Dependency | Purpose | Installation |
| ---------- | -------------------------------- | ---------------------------------------------- |
| Docker | Local Qdrant for semantic search | [get.docker.com](https://get.docker.com) |
| Python 3 | Pattern RAG indexing | `brew install python` or `apt install python3` |
| pre-commit | Advanced git hooks | `pip install pre-commit` |
## Requirements
### Platform-Specific Setup
- Node.js 18+
- Git
- Docker (optional, for semantic search)
**macOS:**
## FAQ
```bash
brew install node@18 git python docker
```
**Q: Do I need to manage memory manually?**
A: No. The AI queries and stores memory automatically per CLAUDE.md instructions.
**Ubuntu/Debian:**
**Q: What if I don't have Docker?**
A: UAM works without Docker. You lose semantic search but SQLite memory still works.
```bash
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs python3 docker.io
```
**Q: Can multiple AI agents work on the same project?**
A: Yes. UAM includes coordination protocols to prevent merge conflicts.
**Windows (PowerShell):**
**Q: How do I update without losing my customizations?**
A: Run `uam init` or `uam generate`. Updates always merge - nothing is lost.
```powershell
winget install OpenJS.NodeJS.LTS
winget install Git.Git
winget install Python.Python.3.12
winget install Docker.DockerDesktop
```
**Q: What's Code Field?**
A: A prompt technique that makes AI state assumptions before coding. Based on [context-field research](https://github.com/NeoVertex1/context-field).
---
## Deep Dive Documentation
## Testing & Quality
Want to understand how UAM works under the hood?
```bash
# Run tests
npm test
### Architecture & Analysis
# Run linter
npm run lint
| Document | Description |
|----------|-------------|
| [UAM Complete Analysis](docs/UAM_COMPLETE_ANALYSIS.md) | Full system architecture, all features |
| [Adaptive UAM Design](docs/ADAPTIVE_UAM_DESIGN.md) | Hybrid adaptive context selector design |
| [Multi-Model Architecture](docs/MULTI_MODEL_ARCHITECTURE.md) | Model routing and fingerprints |
| [MCP Router Setup](docs/MCP_ROUTER_SETUP.md) | Hierarchical MCP router for token reduction |
# Build TypeScript
npm run build
```
### Benchmarking & Optimization
---
| Document | Description |
|----------|-------------|
| [Terminal-Bench Learnings](docs/TERMINAL_BENCH_LEARNINGS.md) | Universal agent patterns discovered |
| [Behavioral Patterns](docs/BEHAVIORAL_PATTERNS.md) | What works vs what doesn't analysis |
| [Failing Tasks Solution Plan](docs/FAILING_TASKS_SOLUTION_PLAN.md) | Detailed fix strategies for each failure mode |
| [Benchmark Results](benchmark-results/) | All Terminal-Bench 2.0 run results |
| [Benchmark Evolution](docs/BENCHMARK_EVOLUTION.md) | How benchmark performance evolved |
| [Domain Strategy Guides](docs/DOMAIN_STRATEGY_GUIDES.md) | Task-specific strategies |
## Documentation
### Optimization Plans
### Core CLAUDE.md Sections
| Document | Description |
|----------|-------------|
| [UAM Performance Analysis](docs/UAM_PERFORMANCE_ANALYSIS_2026-01-18.md) | Performance metrics and analysis |
| [Optimization Options](docs/OPTIMIZATION_OPTIONS.md) | Available optimization strategies |
| [V110 Pattern Analysis](docs/UAM_V110_PATTERN_ANALYSIS_2026-01-18.md) | Pattern effectiveness analysis |
| File | Purpose |
| ------------------------ | -------------------------------- |
| `CLAUDE_ARCHITECTURE.md` | Cluster topology, IaC rules |
| `CLAUDE_CODING.md` | Coding standards, security |
| `CLAUDE_WORKFLOWS.md` | Task workflows, completion gates |
| `CLAUDE_MEMORY.md` | Memory system, Pattern RAG |
| `CLAUDE_DROIDS.md` | Available droids/skills |
### Deep Dive
| Document | Description |
| ---------------------------------------------------------------------- | -------------------------- |
| [`docs/UAM_COMPLETE_ANALYSIS.md`](docs/UAM_COMPLETE_ANALYSIS.md) | Full system architecture |
| [`docs/TERMINAL_BENCH_LEARNINGS.md`](docs/TERMINAL_BENCH_LEARNINGS.md) | Universal agent patterns |
| [`docs/BEHAVIORAL_PATTERNS.md`](docs/BEHAVIORAL_PATTERNS.md) | What works vs what doesn't |
| [`benchmark-results/`](benchmark-results/) | Terminal-Bench 2.0 results |
---
## What's Next?
## What's Next
UAM v2.7.0 includes 58 optimizations. Recent additions:
UAM v5.0 includes:
- ✅ **58 Optimizations** - Battle-tested from Terminal-Bench 2.0
- ✅ **Pattern Router** - Auto-selects optimal patterns per task with blocking gates
- ✅ **Pattern Router** - Auto-selects optimal patterns per task
- ✅ **Completion Gates** - 3 mandatory checks before "done"

@@ -616,15 +448,6 @@ - ✅ **8 Expert Droids** - Specialized agents for common tasks

- ✅ **Hierarchical Memory** - Hot/warm/cold tiering with auto-promotion
- ✅ **Adaptive Context** - Selective context loading based on task type
- ✅ **MCP Router** - 98%+ token reduction for multi-tool contexts
- ✅ **Harbor Integration** - Terminal-Bench 2.0 benchmarking agent
- ✅ **Pattern RAG** - Context-aware pattern injection (~12K tokens saved)
- ✅ **opencode Integration** - Plugin system for seamless integration
- ✅ **Model Router** - Per-model performance fingerprints
Coming soon:
- **Cross-Project Learning** - Share patterns between codebases
- **Visual Memory Dashboard** - See what your AI knows
- **Continuous Benchmark Tracking** - Auto-run benchmarks on template changes
**Star the repo** to follow updates. **Open an issue** to request features.
---

@@ -636,6 +459,4 @@

## License
Terminal-Bench patterns from [Terminal-Bench 2.0](https://github.com/aptx432/terminal-bench) benchmarking.
MIT
---

@@ -647,4 +468,4 @@

*Built for developers who want AI that learns.*
_Built for developers who want AI that learns._
</div>