diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..fd3b16e --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,176 @@ +# AGENTS.md — OpenCode Tool Usage Guide + +This file tells AI coding agents which tools are available and when to use them. +It is read by agents working on the Memex / Passepartout project. + +## Development Workflow (Must Follow) + +All development MUST follow this cycle, beginning to end: + +1. **Start in REPL** — Everything begins and ends in the Passepartout REPL (port 9105) +2. **TDD in REPL**: + 1. Write a test (use `passepartout: deftest` or equivalent) + 2. Run the test → it should FAIL + 3. Develop code in REPL to make the test pass + 4. Use lisp-structural-check to validate code while developing + 5. Evaluate forms with `eval-defun` or equivalent + 6. Run tests again → they should PASS + 7. Repeat until feature is complete +3. **Reflect in Org** — Once code works in REPL, reflect it in the .org literate source file +4. **Tangle with Emacs** — Use `org-babel-tangle` to generate .lisp from .org +5. **Validate tangled lisp** — Run `lisp-structural-check` on the result +6. **Commit** — Only after validation passes + +**When tools fail**: +- If any recommended tool fails, you MUST explain: + - Why it failed (specific error, missing dependency, etc.) + - How we can make it work (fix, configuration, alternative approach) +- Then **PAUSE** and ask for permission before trying a different method + +**Rule**: Do not leave the REPL to develop. If something can't be done in REPL, explain why and ask before proceeding otherwise. + +--- + +## Available Tools — Use These First + +### 1. Passepartout REPL (port 9105) +The daemon runs with ALL skills loaded. Use it instead of the deploy-crash-cycle. + +**Send forms via Python bridge:** +```python +import socket +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(("127.0.0.1", 9105)) +msg = '(:type :event :payload (:sensor :repl-eval :code "(+ 1 2)"))' +s.sendall(f"{len(msg):06x}".encode() + msg.encode()) +``` + +**Or via SBCL directly (attached to daemon):** +```lisp +(sb-bsd-sockets:socket-send sock payload len) +``` + +**Key functions available:** +- `(passepartout:lisp-structural-check "code-string")` — returns (values t nil) or (values nil "error") +- `(passepartout:lisp-validate "code-string" :semantic t)` — full validation +- `(passepartout:log-message "format ~a" arg)` — write to daemon log +- Any exported symbol from `passepartout` package + +### 2. Lisp Structural Tools (pre-deploy validation) +**ALWAYS run these before tangling/deploying Lisp changes.** + +`lisp-structural-check` works on ANY Lisp string, not just Org blocks: +```lisp +;; Via REPL — send to port 9105: +(passepartout:lisp-structural-check "") +;; Returns: (values t nil) on success, (values nil "error details") on failure +``` + +For Org files: +```lisp +(passepartout:literate-block-balance-check "/path/to/file.org") +``` + +These catch paren mismatches in <1 second vs. the 60-second deploy-crash cycle. + +### 3. Emacs Interactive +Use Emacs for interactive Lisp development: +- `forward-sexp` / `backward-sexp` — navigate balanced expressions +- `show-paren-mode` — visual paren matching +- `eval-defun` (C-M-x) — evaluate the current top-level form +- `eval-region` — evaluate selected region +- `org-babel-tangle` — tangle a single file: `M-x org-babel-tangle` +- Batch tangle: `emacs --batch --eval "(progn (require 'org) (find-file \"file.org\") (org-babel-tangle) (kill-buffer))"` + +### 4. Tmux (for TUI testing) +```bash +# Start TUI in detached session +tmux new-session -d -s test "passepartout tui 2>&1 | tee /tmp/tui.log" + +# Send keys +tmux send-keys -t test "hello world" Enter + +# Capture output +tmux capture-pane -t test -p -S -200 + +# Clean up +tmux kill-session -t test +``` + +### 5. Pre-Commit Hook +Validates staged org files by tangling + compiling in daemon: +``` +ln -sf ../../scripts/pre-commit-repl-check .git/hooks/pre-commit +``` +Run manually: `passepartout setup` or `git commit` (hook auto-runs). + +### 6. TUI REPL (via /eval + Swank) +The TUI process has its own REPL for live development: + +**Built-in /eval command** — type in the TUI input: +- `/eval (+ 1 2)` → `=> 3` displayed in chat +- `/eval *state*` → inspect full TUI state plist +- `/eval (view-status sw)` → force status bar re-render +- `/eval (add-msg :system "test")` → inject a test message + +**Emacs + Swank REPL** — connect Emacs to the TUI process: +1. Start TUI: `passepartout tui` +2. In Emacs: `M-x slime-connect RET 127.0.0.1 RET 4006` +3. `C-M-x` any form from `org/gateway-tui.org` → evaluates in live TUI process +4. Configure port: `export TUI_SWANK_PORT=4009` (default: 4006) + +**Croatoan note**: Rendering functions (`view-status`, `view-chat`, `view-input`) write to the terminal and can't be fully tested from Emacs. Inspect return values instead, and test rendering with `/eval` commands in the TUI itself. + +--- + +## Commands + +- Validate code: Send to REPL at port 9105 using socket bridge (see Development Workflow) +- Run tests: `(passepartout:run-tests)` in REPL +- Tangle org: `emacs --batch --eval "(progn (require 'org) (find-file \"file.org\") (org-babel-tangle) (kill-buffer))"` + +## Project Structure + +- Source (literate): `org/` +- Source (tangled): `lisp/` +- Tests: `tests/` +- Scripts: `scripts/` +- Deployment: `~/.local/share/passepartout/` +- TODO tracking: `docs/ROADMAP.org` + +## When Done Means + +- Tests pass: `(passepartout:run-tests)` returns success +- Code validated: `lisp-structural-check` returns `(values t nil)` +- Org reflected: Code exists in .org source file +- Org tangled: .lisp generated from .org +- Committed: Only after all above pass + +## Boundaries + +- **Always do**: Use REPL first for all development, use TDD, validate with lisp-structural-check +- **Ask first**: Before editing .lisp directly (skip org), before deploying, before git commit +- **Never do**: Edit .lisp files manually (they're autogenerated), skip validation before commit + +## Iteration + +When the agent makes the same mistake twice, add a rule to this file to prevent recurrence. + +--- + +## Project Architecture + +- **Thin harness, fat skills** — core provides hooks (`defskill`, `register-actuator`, `*probabilistic-backends*`), skills provide handlers +- **Org is source of truth** — `.org` files tangle to `.lisp`. Never edit `.lisp` directly +- **Package:** `passepartout` exports all symbols in `lisp/core-defpackage.lisp` +- **XDG data dir:** `~/.local/share/passepartout/` (deployed lisp/org files) +- **Config:** `~/.config/passepartout/.env` + +--- + +## Key Libraries + +- **Croatoan** — 0-based coordinates, `(setf (cursor-position win) '(y x))` for cursor, `add-string` with `:y`/`:x` keyword args. Source: `~/quicklisp/dists/quicklisp/software/croatoan-20241012-git/src/` +- **Babel** — string encoding/decoding +- **usocket** — TCP sockets +- **bordeaux-threads** — threading primitives