105 lines
3.6 KiB
Org Mode
105 lines
3.6 KiB
Org Mode
:PROPERTIES:
|
|
:ID: 59ac52fb-2310-4a9d-8e4e-0263af15181c
|
|
:CREATED: [2026-03-30 Mon 21:16]
|
|
:EDITED: [2026-04-07 Tue 13:42]
|
|
:END:
|
|
#+TITLE: SKILL: Emacs Bridge Agent (Universal Literate Note)
|
|
#+STARTUP: content
|
|
#+FILETAGS: :bridge:emacs:io:system:psf:
|
|
|
|
* Overview
|
|
The *Emacs Bridge Agent* is the primary sensory and motor interface to Emacs. It abstracts TCP socket management, allowing the core kernel to interact with buffers as native data structures.
|
|
|
|
* Phase A: Demand (PRD)
|
|
:PROPERTIES:
|
|
:STATUS: FROZEN
|
|
:END:
|
|
|
|
** 1. Purpose
|
|
Define the transport layer for Org-Agent Communication Protocol (Harness Protocol).
|
|
|
|
** 2. User Needs
|
|
- *Isolation:* Kernel remains transport-agnostic.
|
|
- *Persistence:* Multi-client server support for simultaneous sessions.
|
|
- *Dispatch:* Reliable routing of actions to actuators and sensors to the kernel.
|
|
|
|
** 3. Success Criteria
|
|
*** TODO Socket Listener Initialization
|
|
*** TODO Multi-client Connection Handling
|
|
*** TODO Harness Protocol Message Framing Verification
|
|
|
|
* Phase B: Blueprint (PROTOCOL)
|
|
:PROPERTIES:
|
|
:STATUS: SIGNED
|
|
:END:
|
|
|
|
** 1. Architectural Intent
|
|
Interfaces for TCP I/O and protocol framing. Source of truth is the Harness Protocol specification.
|
|
|
|
** 2. Semantic Interfaces
|
|
#+begin_src lisp
|
|
(defun start-emacs-server (&key (port 9105))
|
|
"Starts the Harness Protocol listener.")
|
|
|
|
(defun broadcast-to-emacs (action-plist)
|
|
"Sends a framed message to all connected clients.")
|
|
#+end_src
|
|
|
|
* Phase D: Build (Implementation)
|
|
|
|
** TCP Sensory Layer
|
|
#+begin_src lisp :tangle ../projects/org-skill-emacs-bridge/src/bridge-logic.lisp
|
|
(defun handle-emacs-client (stream)
|
|
;; Logic for parsing length-prefixed Harness Protocol messages
|
|
(format nil "Handling client on stream: ~a" stream))
|
|
#+end_src
|
|
|
|
** Outbound Actuation
|
|
#+begin_src lisp :tangle ../projects/org-skill-emacs-bridge/src/bridge-logic.lisp
|
|
(defun stream-to-emacs (stream action-plist)
|
|
"Streams a chunk of data to a specific Emacs client over Harness Protocol using framing."
|
|
(let* ((type (or (getf action-plist :type) :request))
|
|
(payload (getf action-plist :payload))
|
|
;; Ensure Emacs always receives a :payload drawer
|
|
(envelope (if (and (getf action-plist :type) payload)
|
|
action-plist
|
|
(let ((clean-payload (copy-list action-plist)))
|
|
(remf clean-payload :type)
|
|
(remf clean-payload :id)
|
|
(list :type type
|
|
:id (or (getf action-plist :id) (get-universal-time))
|
|
:payload clean-payload))))
|
|
(msg (prin1-to-string envelope))
|
|
(len (length msg))
|
|
(framed (format nil "~6,'0x~a" len msg)))
|
|
(handler-case
|
|
(progn
|
|
(write-string framed stream)
|
|
(finish-output stream))
|
|
(error (c)
|
|
(kernel-log "BRIDGE - Lost client: ~a" stream)
|
|
(org-agent:unregister-emacs-client stream)))))
|
|
|
|
(defun broadcast-to-emacs (action-plist context)
|
|
"Sends a framed message back to the client that sent the stimulus, or all clients if async."
|
|
(let ((stream (getf context :reply-stream)))
|
|
(if stream
|
|
(stream-to-emacs stream action-plist)
|
|
(progn
|
|
(kernel-log "BRIDGE - Async broadcast to all clients...")
|
|
(bt:with-lock-held (org-agent:*clients-lock*)
|
|
(dolist (s org-agent:*emacs-clients*)
|
|
(stream-to-emacs s action-plist)))))))
|
|
#+end_src
|
|
|
|
* Registration
|
|
#+begin_src lisp
|
|
(org-agent:register-actuator :emacs #'broadcast-to-emacs)
|
|
|
|
(defskill :skill-emacs-bridge
|
|
:priority 100
|
|
:trigger (lambda (context) nil)
|
|
:neuro (lambda (context) nil)
|
|
:symbolic (lambda (action context) action))
|
|
#+end_src
|