# ShortcutXL

A native Excel add-in (`.xll`) written in C that turns Excel into a programmable surface for an AI agent. The agent runs locally on Windows as a TypeScript/Node.js CLI with a terminal TUI. It controls Excel through two channels: writing Python files for custom functions, and sending code blocks over HTTP for direct manipulation.

See `../agent/PLAN.md` for the agent architecture (loop, multiagent, session management).

---

## Architecture

```
┌─ Windows ──────────────────────────────────────────┐
│                                                     │
│  Terminal (PowerShell / Windows Terminal)            │
│  └─ AgentController CLI (Node.js, TypeScript)                 │
│     ├─ TUI (shortcutxl)                          │
│     ├─ Supervisor agent loop                        │
│     │   ├─ POST /exec → localhost:8080 ────────────┼──► HTTP
│     │   ├─ writes .py → modules/ ──────────────────┼──► filesystem
│     │   └─ Task tool → spawns worker agents         │
│     └─ shortcutxl (Anthropic, OpenAI, Google)   │
│                                                     │
│  Excel.exe                                          │
│  └─ ShortcutXL (in-process)                        │
│     ├─ HTTP server (:8080)                          │
│     │   ├─ GET /config (paths)                      │
│     │   └─ POST /exec (run Python)                  │
│     ├─ fs_watcher (hot-reload)                      │
│     ├─ CPython 3.13 (embedded)                      │
│     └─ COM → all open workbooks                     │
│                                                     │
└─────────────────────────────────────────────────────┘
```

On startup the agent calls `GET /config` to discover the `modules/` path and is ready to go. Both agent and Excel run natively on Windows — no WSL boundary, no filesystem translation.

---

## Two Channels

### 1. `POST /exec` — imperative actions

AgentController sends a Python code block. The XLL runs it in the embedded runtime with full COM access to Excel. The result (stdout + stderr) is returned.

```
POST http://localhost:8080/exec
{"code": "from shortcut_xl import xl_app\napp = xl_app()\napp.Range('A1:D1').Value = [['Name','Revenue','Growth','Status']]\napp.Range('A1:D1').Font.Bold = True"}

→ {"ok": true, "output": ""}
```

Use this for: writing cells, reading data, formatting, creating charts, any one-shot action.

### 2. Filesystem — custom functions

AgentController writes `.py` files with `@xl_func` decorators to `modules/`. The XLL watches the directory, hot-reloads within ~200ms, and registers them as native Excel formulas.

```python
# modules/dashboard.py
from shortcut_xl import xl_func

@xl_func
def revenue_ytd(region):
    return {"EMEA": 1.2e6, "NA": 3.4e6}.get(region, 0)
```

In Excel: `=revenue_ytd("EMEA")` → `1200000`

Use this for: custom worksheet functions that Excel's calc engine calls repeatedly, tick loops, animations.

### Why two channels

| Need                        | Channel    | Reason                                     |
| --------------------------- | ---------- | ------------------------------------------ |
| Write cells, format, charts | `/exec`    | One-shot, result discarded after execution |
| Custom formulas (`=foo()`)  | filesystem | Excel calls them on every recalculation    |
| Tick loops, animations      | filesystem | Persistent code running on a timer         |

HTTP gives the agent a simple request/response interface for one-shot operations. The filesystem channel handles the only thing HTTP can't: registering functions with Excel's calc engine via `xlfRegister`, which requires in-process code that persists between calls.

---

## What Runs Where

| Component                                           | Where                     | Why                                                      |
| --------------------------------------------------- | ------------------------- | -------------------------------------------------------- |
| AgentController CLI (LLM calls, orchestration, TUI) | Windows, Node.js process  | Native filesystem + HTTP to Excel, no cross-OS friction  |
| ShortcutXL (HTTP, fs_watcher, Python, COM)          | Windows, inside excel.exe | In-process access to Excel's internals                   |
| `modules/*.py`                                      | Windows filesystem        | AgentController writes directly, XLL watches for changes |

---

## Installation

**Installer (recommended):** MSI drops `ShortcutXL.xll` + embedded Python runtime. Writes registry key:

```
HKCU\Software\Microsoft\Office\<version>\Excel\Options
  OPEN = /R "C:\Program Files\Shortcut\ShortcutXL.xll"
```

Excel loads it automatically on every startup.

**Manual:** Excel → File → Options → Add-ins → Manage: Excel Add-ins → Browse → select `ShortcutXL.xll`.

---

## Platform

Windows only. The XLL API is a Windows DLL interface. The custom spreadsheet engine (see `new-sheet-spec.md`) is the cross-platform path.
