From 3dbe6a1fb4ebb83eb817d69ea9a9530a5c78c618 Mon Sep 17 00:00:00 2001 From: Jeffrey Alan Scudder Date: Thu, 26 Mar 2026 11:59:57 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20CL=20piece=20launcher=20=E2=80=94=20typ?= =?UTF-8?q?e=20notepat.lisp=20to=20run=20CL=20notepat?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C binary detects .lisp pieces and execs /ac-swank --piece . SBCL takes over with DRM graphics + Swank REPL. notepat.lisp is the first CL piece, visible in the list command. Co-Authored-By: Claude Opus 4.6 (1M context) --- fedac/native/cl/main.lisp | 9 +++++++++ fedac/native/pieces/notepat.lisp | 7 +++++++ fedac/native/src/ac-native.c | 21 +++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 fedac/native/pieces/notepat.lisp diff --git a/fedac/native/cl/main.lisp b/fedac/native/cl/main.lisp index 811ec3cae..4b83e43df 100644 --- a/fedac/native/cl/main.lisp +++ b/fedac/native/cl/main.lisp @@ -342,6 +342,15 @@ When called with --swank-only, starts Swank server and blocks (no graphics)." (force-output *error-output*) (return-from main)))) + ;; --piece MODE: run a specific CL piece with graphics (launched by C binary) + (let ((piece-arg (second (member "--piece" (uiop:command-line-arguments) :test #'string=)))) + (when piece-arg + (format *error-output* "[cl] Running CL piece: ~A~%" piece-arg) + (force-output *error-output*) + ;; Go straight to native CL notepat (the only CL piece for now) + ;; Future: dispatch to different CL pieces based on piece-arg + (setf *js-fallback* t))) + ;; Determine piece: config.json > command-line arg > default (unless *js-fallback* (let* ((cfg (handler-case (ac-native.config:load-config) diff --git a/fedac/native/pieces/notepat.lisp b/fedac/native/pieces/notepat.lisp new file mode 100644 index 000000000..8f7961985 --- /dev/null +++ b/fedac/native/pieces/notepat.lisp @@ -0,0 +1,7 @@ +;;; notepat.lisp — Common Lisp notepat piece +;;; This is a marker file that tells the C runtime to hand off to /ac-swank +;;; which runs the native CL notepat (defined in cl/main.lisp). +;;; +;;; To run: type "notepat.lisp" at the prompt, or select it from the list. +;;; The C binary will exec /ac-swank --piece notepat, which launches +;;; the full CL notepat with DRM graphics, audio, and Swank REPL. diff --git a/fedac/native/src/ac-native.c b/fedac/native/src/ac-native.c index 15bb972ef..ec59e9914 100644 --- a/fedac/native/src/ac-native.c +++ b/fedac/native/src/ac-native.c @@ -3028,6 +3028,27 @@ int main(int argc, char *argv[]) { // NOTE: "claude" and "cc" aliases removed — claude.mjs handles auth curtain // before jumping to terminal:claude itself. + // Check for .lisp piece — hand off to SBCL + { + char lisp_path[256]; + // Strip .lisp suffix if present + char lisp_name[128]; + strncpy(lisp_name, rt->jump_target, sizeof(lisp_name) - 1); + lisp_name[sizeof(lisp_name) - 1] = 0; + char *dot = strstr(lisp_name, ".lisp"); + if (dot) *dot = 0; + snprintf(lisp_path, sizeof(lisp_path), "/pieces/%s.lisp", lisp_name); + if (access(lisp_path, F_OK) == 0 && access("/ac-swank", X_OK) == 0) { + ac_log("[ac-native] Launching CL piece: %s\n", lisp_name); + // Clean up before exec + if (logfile) { fflush(logfile); fsync(fileno(logfile)); } + sync(); + execl("/ac-swank", "ac-swank", "--piece", lisp_name, NULL); + // execl failed — fall through to JS path + ac_log("[ac-native] execl /ac-swank failed: %s\n", strerror(errno)); + } + } + // Construct piece path: /pieces/.mjs char jump_path[256]; snprintf(jump_path, sizeof(jump_path), "/pieces/%s.mjs", rt->jump_target); -- 2.51.2