From e41c25068d0cec9434895a6d3e3a25d3a26f645f Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Tue, 23 Jun 2026 20:12:58 -0400 Subject: chore(ai): archive gptel and remove it from the live config I archived gptel to archive/gptel/ since I rarely use it. Moved there: the six gptel modules (ai-config, ai-conversations, ai-conversations-browser, ai-mcp, ai-quick-ask, ai-rewrite), the gptel-tools/ directory, custom/gptel-prompts.el, their test files and utilities, and the four gptel-only specs. Scrubbed from the live config: the ai-config require in init.el, which also drops the whole C-; a keymap; the gptel-mode emojify hook in font-config.el; the gptel-tools entries in the Makefile clean target and the coverage runner; and the gptel feature notes in README. Cancelled the open gptel tasks in todo.org (the AI Open Work issues, the feature-extension brainstorm, the velox gptel-magit bug). ai-term stays. It is the ghostel Claude launcher, independent of gptel. Verified: every module loads, a batch init launch reaches completion clean, and the full test suite shows only pre-existing coverage failures unrelated to this change. --- tests/testutil-filesystem.el | 180 ------------------------------------------- 1 file changed, 180 deletions(-) delete mode 100644 tests/testutil-filesystem.el (limited to 'tests/testutil-filesystem.el') diff --git a/tests/testutil-filesystem.el b/tests/testutil-filesystem.el deleted file mode 100644 index b1970b62d..000000000 --- a/tests/testutil-filesystem.el +++ /dev/null @@ -1,180 +0,0 @@ -;;; testutil-filesystem.el --- -*- coding: utf-8; lexical-binding: t; -*- -;; -;; Author: Craig Jennings -;; -;;; Commentary: -;; This library provides reusable helper functions for GPTel filesystem tools. -;; -;; It uses f.el and core Emacs libraries for path manipulation, directory listing, -;; file info retrieval, filtering, and recursive traversal. -;; -;; Designed to be used by multiple tools that operate on the filesystem. -;; -;;; Code: - -(require 'f) -(require 'cl-lib) -(require 'subr-x) - -;; Get directory entries in PATH. Returns list of absolute paths. -;; Default excludes hidden files and directories (name begins with dot). -;; Optional INCLUDE-HIDDEN to include hidden entries. -;; Optional FILTER-PREDICATE is a function called on each absolute path to filter. -(defun cj/get--directory-entries (path &optional include-hidden filter-predicate) - "Return a list of entries (absolute paths) in directory PATH. -Entries exclude '.' and '..'. -By default, hidden entries (starting with '.') are excluded unless -INCLUDE-HIDDEN is non-nil. FILTER-PREDICATE, if non-nil, is a predicate -function called on each entry's absolute path; only entries where it returns -non-nil are included." - ;; Convert 'path' to an absolute filename string - (let* ((expanded-path (expand-file-name path)) - ;; get absolute paths in expanded directory - (entries (directory-files expanded-path t nil t)) - ;; remove "." ".." entries - (filtered-entries - (cl-remove-if - (lambda (entry) - (or (member (f-filename entry) '("." "..")) - ;; and hidden files include-hidden is non-nil. - (and (not include-hidden) - (string-prefix-p "." (f-filename entry))))) - entries))) - ;; apply filtered predicate if provided - (if filter-predicate - (seq-filter filter-predicate filtered-entries) - ;; retun filtered-entries - filtered-entries))) - -(defun cj/get-file-info (path) - "Get file information for PATH. -Returned plist keys: -:success t or nil -:error string error message if :success is nil -:path absolute file path (string) -:size file size (integer) -:last-modified last modification time (time value) -:directory boolean: t if a directory -:permissions string with symbolic permissions, e.g. \"drwxr-xr-x\" -:executable boolean: t if executable file -:owner string: owner name or UID if name unavailable -:group string: group name or GID if name unavailable" - ;; handle errors during evaluation - (condition-case err - (let* ((expanded-path (expand-file-name path))) - (if (not (file-readable-p expanded-path)) - ;; Explicit permission denied check - (list :success nil :path expanded-path :error - (format "Permission denied: %s" expanded-path)) - (let* - ;; t = return string names for uid/gid - ((attrs (file-attributes expanded-path t)) - (size (file-attribute-size attrs)) - (mod (file-attribute-modification-time attrs)) - (dirp (eq t (file-attribute-type attrs))) - (modes (file-modes expanded-path)) - (perm (cj/-mode-to-permissions modes)) - (execp (file-executable-p expanded-path)) - (owner (file-attribute-user-id attrs)) ; Get owner - (group (file-attribute-group-id attrs))) ; Get group - (list :success t :path expanded-path :size size :last-modified mod - :directory dirp :permissions perm :executable execp - :owner (or owner "unknown") - :group (or group "unknown"))))) - ;; if error, return failure plist with error info - (error (list :success nil :path path :error (error-message-string err))))) - -(defun cj/format-file-info (file-info base-path) - "Format FILE-INFO plist relative to BASE-PATH as a string. -Handles missing keys gracefully by supplying default values." - (let ((permissions (or (plist-get file-info :permissions) "")) - (executable (if (plist-get file-info :executable) "*" " ")) - (size (file-size-human-readable (or (plist-get file-info :size) 0))) - (last-modified (or (plist-get file-info :last-modified) (current-time))) - (path (or (plist-get file-info :path) base-path))) - (format " %s%s %10s %s %s" - permissions - executable - size - (format-time-string "%Y-%m-%d %H:%M" last-modified) - (file-relative-name path base-path)))) - -;; Convert file mode bits integer to string like ls -l, e.g. drwxr-xr-x -(defun cj/-mode-to-permissions (mode) - "Convert file MODE (returned by `file-modes') to symbolic permission string." - (concat - (if (eq (logand #o40000 mode) #o40000) "d" "-") - (mapconcat - (lambda (bits) - (concat (if (/= 0 (logand bits 4)) "r" "-") - (if (/= 0 (logand bits 2)) "w" "-") - (if (/= 0 (logand bits 1)) "x" "-"))) - (list (logand (/ mode 64) 7) - (logand (/ mode 8) 7) - (logand mode 7)) - ""))) - -;; Filter a list of file info plists by extension (case insensitive). -;; Always includes directories. -(defun cj/filter-by-extension (file-info-list extension) - "Keep only directories and files with EXTENSION from FILE-INFO-LIST. -EXTENSION should not include leading dot, e.g. \"org\"." - ;; return full list if no extension - (if (not extension) - file-info-list - (cl-remove-if-not - (lambda (fi) - ;; always keep directories - (or (plist-get fi :directory) - ;; and successful file entries - (and (plist-get fi :success) - ;; and file extensions that match case-insensitively - (string-suffix-p (concat "." extension) - (f-filename (plist-get fi :path)) - t)))) - file-info-list))) - -(defun cj/list-directory-recursive (path &optional include-hidden filter-predicate max-depth) - "Recursively list files under PATH applying FILTER-PREDICATE. -PATH is the directory to list. -INCLUDE-HIDDEN if non-nil, includes hidden files (those starting with '.'). -FILTER-PREDICATE, if non-nil, is a function called on file info plist and -returns non-nil to include file. -MAX-DEPTH limits recursion depth (nil or 0 = unlimited)." - ;; set up cl-recursive function with path and current depth - (cl-labels ((recurse (path depth) - (let ((expanded-path (expand-file-name path)) - ;; empty list to accumulate file info plists - (file-info-list '())) - ;; ensure we're working with directories only - (when (not (file-directory-p expanded-path)) - (error "Not a directory: %s" expanded-path)) - - ;; loop over each file in the path - (dolist (file-entry - (cj/get--directory-entries expanded-path include-hidden)) - ;; get the metadata for the file - (let ((file-metadata (cj/get-file-info file-entry))) - ;; if retrieving metadata was successful - (when (and file-metadata (plist-get file-metadata :success)) - ;; if there's no custom filter or it matches, add it to the list - (when (or (not filter-predicate) - (funcall filter-predicate file-metadata)) - (push file-metadata file-info-list)) - ;; if it's a directory and we're not at the max-depth - (when (and (plist-get file-metadata :directory) - (or (not max-depth) (< depth (1- max-depth)))) - ;; gather all the files and recurse with that file - (setq file-info-list - (nconc file-info-list (recurse file-entry (1+ depth))))) - ;; warn if recursion returned received both a success and error - (when (and (plist-get file-metadata :success) - (plist-get file-metadata :error)) - (message "Warning: %s" (plist-get file-metadata :error)))))) - ;; restore the file order (as they were pushed into reverse order) - (nreverse file-info-list)))) - ;; start recursion at the top level - (recurse path 0))) - -(provide 'testutil-filesystem) -;;; testutil-filesystem.el ends here. -- cgit v1.2.3