Files
memex/AGENTS.md

6.6 KiB

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:

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):

(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:

;; Via REPL — send to port 9105:
(passepartout:lisp-structural-check "<lisp-code-string>")
;; Returns: (values t nil) on success, (values nil "error details") on failure

For Org files:

(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)

# 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