Some checks failed
Deploy-Agent-V15-Stdin / JOB-V15-STDIN (push) Failing after 2s
- Audited Reactive Signal Pipeline. - Finalized Unified Envelope & Provider-Agnosticism. - Completed workspace cleanup and documentation. - Hardened installer for VM/Docker deployment.
102 lines
4.2 KiB
Org Mode
102 lines
4.2 KiB
Org Mode
:PROPERTIES:
|
|
:ID: cli-gateway-skill
|
|
:CREATED: [2026-04-13 Mon 17:00]
|
|
:END:
|
|
#+TITLE: SKILL: CLI Gateway (Universal Literate Note)
|
|
#+STARTUP: content
|
|
#+FILETAGS: :gateway:cli:io:autonomy:
|
|
|
|
* Overview
|
|
The *CLI Gateway* is the primary sensory and actuating interface for human interaction. It implements a TCP-based S-expression protocol that allows multiple clients (terminal, Emacs, web) to establish secure bidirectional channels with the Brain.
|
|
|
|
* Implementation
|
|
|
|
#+begin_src lisp
|
|
(in-package :cl-user)
|
|
(defpackage :opencortex.skills.org-skill-cli-gateway
|
|
(:use :cl :opencortex))
|
|
(in-package :opencortex.skills.org-skill-cli-gateway)
|
|
|
|
(defvar *cli-port* 9105)
|
|
(defvar *cli-server-socket* nil)
|
|
(defvar *cli-server-thread* nil)
|
|
|
|
(defun execute-cli-action (action context)
|
|
"Sends a framed message back to the connected CLI client."
|
|
(let* ((payload (proto-get action :PAYLOAD))
|
|
(meta (getf context :meta))
|
|
(stream (getf meta :reply-stream)))
|
|
(handler-case
|
|
(if (and stream (open-stream-p stream))
|
|
(progn
|
|
(format stream "~a" (frame-message action))
|
|
(finish-output stream)
|
|
(format stream "~a" (frame-message '(:TYPE :STATUS :SCRIBE :IDLE :GARDENER :SLEEPING)))
|
|
(finish-output stream))
|
|
(harness-log "CLI ERROR: No active or open reply stream for signal."))
|
|
(error (c) (harness-log "CLI ACTUATOR ERROR: ~a" c)))))
|
|
|
|
(defun handle-cli-slash-command (cmd stream)
|
|
(cond
|
|
((string= cmd "/exit") (return-from handle-cli-slash-command :exit))
|
|
(t (format stream "~a" (frame-message (list :TYPE :REQUEST :PAYLOAD (list :ACTION :MESSAGE :TEXT (format nil "Unknown command: ~a" cmd))))))))
|
|
|
|
(defun handle-cli-client (stream)
|
|
"Reads framed messages from a CLI client and injects them as stimuli."
|
|
(harness-log "CLI: Client connected.")
|
|
(handler-case
|
|
(progn
|
|
;; 1. Send Handshake
|
|
(format stream "~a" (frame-message (make-hello-message "0.1.0")))
|
|
(finish-output stream)
|
|
(format stream "~a" (frame-message '(:TYPE :STATUS :SCRIBE :IDLE :GARDENER :SLEEPING)))
|
|
(finish-output stream)
|
|
|
|
;; 2. Communication Loop
|
|
(loop
|
|
(let ((msg (read-framed-message stream)))
|
|
(cond ((eq msg :eof) (return))
|
|
((eq msg :error) (return))
|
|
(t (let* ((payload (proto-get msg :payload))
|
|
(text (proto-get payload :text))
|
|
(meta (proto-get msg :meta)))
|
|
(if (and text (stringp text) (char= (char text 0) #\/))
|
|
(when (eq (handle-cli-slash-command text stream) :exit) (return))
|
|
(progn
|
|
;; Default meta if missing
|
|
(unless meta
|
|
(setf (getf msg :meta) (list :SOURCE :CLI :SESSION-ID "default")))
|
|
(harness-log "CLI: Received input -> ~s" msg)
|
|
(inject-stimulus msg :stream stream)))))))))
|
|
(error (c) (harness-log "CLI CLIENT DISCONNECT: ~a" c)))
|
|
(harness-log "CLI: Client disconnected."))
|
|
|
|
(defun start-cli-gateway (&optional (port *cli-port*))
|
|
"Starts the TCP listener for local CLI clients."
|
|
(setf *cli-server-socket* (usocket:socket-listen "0.0.0.0" port :reuse-address t))
|
|
(setf *cli-server-thread*
|
|
(bt:make-thread
|
|
(lambda ()
|
|
(unwind-protect
|
|
(loop
|
|
(let* ((socket (usocket:socket-accept *cli-server-socket*))
|
|
(stream (usocket:socket-stream socket)))
|
|
(bt:make-thread (lambda ()
|
|
(unwind-protect (handle-cli-client stream)
|
|
(usocket:socket-close socket)))
|
|
:name "opencortex-cli-client-handler")))
|
|
(usocket:socket-close *cli-server-socket*)))
|
|
:name "opencortex-cli-gateway"))
|
|
(harness-log "CLI: Gateway listening on port ~a" port))
|
|
|
|
(register-actuator :CLI #'execute-cli-action)
|
|
|
|
(defskill :skill-gateway-cli
|
|
:priority 200
|
|
:trigger (lambda (ctx) (declare (ignore ctx)) nil)
|
|
:probabilistic nil
|
|
:deterministic (lambda (action ctx) (declare (ignore ctx)) action))
|
|
|
|
(start-cli-gateway)
|
|
#+end_src
|