- NEW: org-skill-utils-lisp (consolidated from org-skill-lisp-utils) * 3-phase validation: structural, syntactic, semantic * Sandboxed eval, AST extraction/injection/wrapping * Format, list-definitions utilities - NEW: org-skill-utils-org (consolidated from org-skill-emacs-edit) * Read/update/delete org headlines * Property management, TODO state handling * ID-link and internal link support - DELETE: org-skill-lisp-utils (merged into utils-lisp) - DELETE: org-skill-emacs-edit (merged into utils-org) - RENAME: run-all-tests.lisp -> run-tests.lisp - HARDEN: Skill loader with improved lisp keyword handling - FIX: Package jailing issues with def-cognitive-tool macro conflicts - ADD: Setup wizard (opencortex setup) and doctor (opencortex doctor) - ADD: TUI client with Croatoan for native terminal rendering - REMOVE: Dynamic loading from opencortex.asd (use :force t instead) - CLEANUP: Test file consolidation (removed duplicate test suites) Co-authored-by: Agent <agent@memex>
82 lines
3.3 KiB
Common Lisp
82 lines
3.3 KiB
Common Lisp
(in-package :opencortex)
|
|
|
|
(defvar *doctor-required-binaries* '("sbcl" "emacs" "git" "socat" "nc")
|
|
"List of external binaries required for full system operation.")
|
|
|
|
(defun doctor-check-dependencies ()
|
|
"Verifies that required external binaries are available in the PATH via a shell probe."
|
|
(let ((all-ok t))
|
|
(harness-log "DOCTOR: Checking system dependencies...")
|
|
(dolist (dep *doctor-required-binaries*)
|
|
(let ((path (ignore-errors
|
|
(uiop:run-program (list "which" dep)
|
|
:output :string :ignore-error-status t))))
|
|
(if (and path (> (length path) 0))
|
|
(harness-log " [OK] Found ~a" dep)
|
|
(progn
|
|
(harness-log " [FAIL] Missing binary: ~a" dep)
|
|
(setf all-ok nil)))))
|
|
all-ok))
|
|
|
|
(defun doctor-check-env ()
|
|
"Validates XDG directories and environment configuration against the POSIX standard."
|
|
(harness-log "DOCTOR: Checking XDG environment...")
|
|
(let ((all-ok t)
|
|
(config-dir (uiop:getenv "OC_CONFIG_DIR"))
|
|
(data-dir (uiop:getenv "OC_DATA_DIR"))
|
|
(state-dir (uiop:getenv "OC_STATE_DIR"))
|
|
(memex-dir (uiop:getenv "MEMEX_DIR")))
|
|
|
|
(flet ((check-dir (name path critical)
|
|
(if (and path (> (length path) 0))
|
|
(if (uiop:directory-exists-p path)
|
|
(harness-log " [OK] ~a: ~a" name path)
|
|
(progn
|
|
(harness-log " [FAIL] ~a directory missing: ~a" name path)
|
|
(when critical (setf all-ok nil))))
|
|
(progn
|
|
(harness-log " [FAIL] ~a variable not set." name)
|
|
(when critical (setf all-ok nil))))))
|
|
|
|
(check-dir "Config (OC_CONFIG_DIR)" config-dir t)
|
|
(check-dir "Data (OC_DATA_DIR)" data-dir t)
|
|
(check-dir "State (OC_STATE_DIR)" state-dir t)
|
|
(check-dir "Memex (MEMEX_DIR)" memex-dir t))
|
|
all-ok))
|
|
|
|
(defun doctor-check-llm ()
|
|
"Tests connectivity to primary LLM providers. Non-critical fallback allowed."
|
|
(harness-log "DOCTOR: Checking LLM connectivity...")
|
|
(let ((openrouter-key (uiop:getenv "OPENROUTER_API_KEY")))
|
|
(if (and openrouter-key (> (length openrouter-key) 0))
|
|
(progn
|
|
(harness-log " [OK] OpenRouter API Key detected.")
|
|
t)
|
|
(progn
|
|
(harness-log " [WARN] No OpenRouter API Key. Falling back to local inference only.")
|
|
t))))
|
|
|
|
(defun doctor-run-all ()
|
|
"Executes the full diagnostic suite and returns T if system is healthy."
|
|
(harness-log "==================================================")
|
|
(harness-log " OPENCORTEX DOCTOR: Commencing Health Check")
|
|
(harness-log "==================================================")
|
|
(let ((dep-ok (doctor-check-dependencies))
|
|
(env-ok (doctor-check-env))
|
|
(llm-ok (doctor-check-llm)))
|
|
(declare (ignore llm-ok))
|
|
(harness-log "==================================================")
|
|
(if (and dep-ok env-ok)
|
|
(progn
|
|
(harness-log " ✓ SYSTEM HEALTHY: Ready for ignition.")
|
|
t)
|
|
(progn
|
|
(harness-log " ✗ SYSTEM UNHEALTHY: Fix the errors above.")
|
|
nil))))
|
|
|
|
(defun doctor-main ()
|
|
"Entry point for the 'doctor' CLI command."
|
|
(if (doctor-run-all)
|
|
(uiop:quit 0)
|
|
(uiop:quit 1)))
|