- 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>
4.4 KiB
4.4 KiB
SKILL: Utils Org (org-skill-utils-org.org)
Overview
The Utils Org skill provides advanced structural manipulation for Org-mode files and their AST representation.
Implementation
Reading Files
(defun utils-org-read-file (filepath)
"Reads an Org file into a string."
(uiop:read-file-string filepath))
Writing Files
(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)))
ID Generation
(defun utils-org-generate-id ()
"Generates a new UUID for an Org node."
(string-downcase (format nil "~a" (uuid:make-v4-uuid))))
ID Formatting
(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)))
Setting Properties (Recursive)
(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)
Setting TODO Status
(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))
Adding Headlines
(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)
Searching Headlines (by ID)
(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))
Searching Headlines (by Title)
(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))
Placeholder for External Edits
(defun utils-org-modify (filepath id changes)
"Placeholder for Emacs-driven modification of a specific node."
(declare (ignore changes))
(harness-log "UTILS-ORG: Applying changes to ~a in ~a" id filepath)
t)
Placeholder for AST to Org conversion
(defun utils-org-ast-to-org (ast)
"Minimal converter from AST back to Org text (Placeholder)."
(declare (ignore ast))
"* TITLE (Placeholder)")
Skill Registration
(defskill :skill-utils-org
:priority 100
:trigger (lambda (ctx) (declare (ignore ctx)) nil))