Files
memex/AGENTS.md

6.9 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 — Red-Green-Refactor cycle:
    1. Write a FAILING test first (use (passepartout:deftest name ...) or fiveam:test)
    2. Prove RED: Run (passepartout:run-test 'test-name) — it MUST fail. If it passes before code exists, the test is broken or testing nothing. Record the failure output.
    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

  • Red proof recorded: Test was run and confirmed FAILING before implementation code existed
  • 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, prove tests fail FIRST before writing code, 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