- 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>
95 lines
3.5 KiB
Common Lisp
95 lines
3.5 KiB
Common Lisp
(in-package :opencortex)
|
|
|
|
(defun utils-org-read-file (filepath)
|
|
"Reads an Org file into a string."
|
|
(uiop:read-file-string filepath))
|
|
|
|
(defun utils-org-write-file (filepath content)
|
|
"Writes content to an Org file."
|
|
(uiop:with-output-file (s filepath :if-exists :supersede)
|
|
(format s "~a" content)))
|
|
|
|
(defun utils-org-generate-id ()
|
|
"Generates a new UUID for an Org node."
|
|
(string-downcase (format nil "~a" (uuid:make-v4-uuid))))
|
|
|
|
(defun utils-org-id-format (id)
|
|
"Ensures the ID has the 'id:' prefix."
|
|
(if (uiop:string-prefix-p "id:" id)
|
|
id
|
|
(format nil "id:~a" id)))
|
|
|
|
(defun utils-org-set-property (ast target-id property value)
|
|
"Recursively sets a property on a headline with a matching ID in the AST."
|
|
(let ((type (getf ast :type))
|
|
(props (getf ast :properties))
|
|
(contents (getf ast :contents)))
|
|
(when (and (eq type :HEADLINE) (string= (getf props :ID) target-id))
|
|
(setf (getf (getf ast :properties) property) value)
|
|
(return-from utils-org-set-property t))
|
|
(dolist (child contents)
|
|
(when (listp child)
|
|
(when (utils-org-set-property child target-id property value)
|
|
(return-from utils-org-set-property t)))))
|
|
nil)
|
|
|
|
(defun utils-org-set-todo (ast target-id status)
|
|
"Sets the TODO status of a headline in the AST."
|
|
(utils-org-set-property ast target-id :TODO status))
|
|
|
|
(defun utils-org-add-headline (ast parent-id title)
|
|
"Adds a new headline as a child of the parent-id in the AST."
|
|
(let ((type (getf ast :type))
|
|
(props (getf ast :properties))
|
|
(id (getf props :ID))
|
|
(contents (getf ast :contents)))
|
|
(when (and (eq type :HEADLINE) (string= id parent-id))
|
|
(let ((new-node (list :type :HEADLINE
|
|
:properties (list :ID (utils-org-id-format (utils-org-generate-id))
|
|
:TITLE title)
|
|
:contents nil)))
|
|
(setf (getf ast :contents) (append contents (list new-node)))
|
|
(return-from utils-org-add-headline t)))
|
|
(dolist (child contents)
|
|
(when (listp child)
|
|
(when (utils-org-add-headline child parent-id title)
|
|
(return-from utils-org-add-headline t)))))
|
|
nil)
|
|
|
|
(defun utils-org-find-headline-by-id (ast id)
|
|
"Finds a headline by its ID in the AST."
|
|
(let ((props (getf ast :properties)))
|
|
(when (string= (getf props :ID) id)
|
|
(return-from utils-org-find-headline-by-id ast))
|
|
(dolist (child (getf ast :contents))
|
|
(when (listp child)
|
|
(let ((found (utils-org-find-headline-by-id child id)))
|
|
(when found (return-from utils-org-find-headline-by-id found)))))
|
|
nil))
|
|
|
|
(defun utils-org-find-headline-by-title (ast title)
|
|
"Finds a headline by its title in the AST."
|
|
(let ((props (getf ast :properties)))
|
|
(when (string-equal (getf props :TITLE) title)
|
|
(return-from utils-org-find-headline-by-title ast))
|
|
(dolist (child (getf ast :contents))
|
|
(when (listp child)
|
|
(let ((found (utils-org-find-headline-by-title child title)))
|
|
(when found (return-from utils-org-find-headline-by-title found)))))
|
|
nil))
|
|
|
|
(defun utils-org-modify (filepath id changes)
|
|
"Placeholder for Emacs-driven modification of a specific node."
|
|
(harness-log "UTILS-ORG: Applying changes to ~a in ~a" id filepath)
|
|
(declare (ignore changes))
|
|
t)
|
|
|
|
(defun utils-org-ast-to-org (ast)
|
|
"Minimal converter from AST back to Org text (Placeholder)."
|
|
(declare (ignore ast))
|
|
"* TITLE (Placeholder)")
|
|
|
|
(defskill :skill-utils-org
|
|
:priority 100
|
|
:trigger (lambda (ctx) (declare (ignore ctx)) nil))
|