Jump to content

Sharing a LISP (Codebase Packer) + Thoughts on modern CAD environment governance


Recommended Posts

Posted

Hi everyone,

 

I'm Vico, an architectural designer with about 12 years in the industry. I'm based in China and have mostly been active in local developer forums, but I've always respected the open-source spirit here. I wanted to share a quick tool I wrote and also get your feedback on an idea.

 

Codebase Packer — a LISP for AI-assisted work

 

Over the past months I've been building a web-based side-project for CAD. The frontend work forced me to lean heavily on AI assistants (Claude, ChatGPT). The biggest bottleneck was always the context window: opening and pasting 30+ files manually drove me crazy.

 

So I solved it with a little LISP routine. Codebase Packer lets you point at a folder and aggregate every file inside into a single .txt, ready for an LLM prompt.

 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;                                                                        ;;;
;;;          Command CPK (Codebase Packer) - Version 1.0 Release           ;;;
;;;                                                                        ;;;
;;;    Features:                                                           ;;;
;;;    Efficiently extracts the directory structure and file contents      ;;;
;;;    of a project. Features smart character encoding detection and       ;;;
;;;    automatically saves the packed file as UTF-8 alongside the          ;;;
;;;    project folder for AI-friendly integration.                         ;;;
;;;                                                                        ;;;
;;;    Author: Vico Wang                                                   ;;;
;;;    Compatibility: AutoCAD 2006+ (Visual LISP / ActiveX)                ;;;
;;;                                                                        ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(vl-load-com)

(defun cpk:getdate ( / cd )
  (setq cd (rtos (getvar 'cdate) 2 6))
  (strcat (substr cd 1 4) (substr cd 5 2) (substr cd 7 2))
)

(defun cpk:read ( fn / ext charset stm text err )
  (setq ext (strcase (vl-filename-extension fn) t)
        charset (if (member ext '(".lsp" ".dcl" ".mnl" ".bat" ".ini")) "GBK" "UTF-8")
        text ""
  )
  (if (setq stm (vlax-create-object "adodb.stream"))
    (progn
      (setq err
        (vl-catch-all-apply
          '(lambda ()
             (vlax-put-property stm 'type 2)
             (vlax-put-property stm 'mode 3)
             (vlax-put-property stm 'charset charset)
             (vlax-invoke stm 'open)
             (vlax-invoke stm 'loadfromfile fn)
             (if (> (vlax-get-property stm 'size) 0)
               (setq text (vlax-invoke stm 'readtext -1))
             )
           )
        )
      )
      (if (= 'vla-object (type stm))
        (progn
          (vl-catch-all-apply '(lambda () (vlax-invoke stm 'close)))
          (vlax-release-object stm)
        )
      )
      (if (vl-catch-all-error-p err)
        (strcat "// Note: Error reading file - " (vl-catch-all-error-message err))
        (if (= "" text) "// Note: File is empty or extraction failed" text)
      )
    )
    "// Note: ADODB.Stream component missing"
  )
)

(defun cpk:traverse ( fso dir prefix islast root / fobj subdirs files items i cnt name rel )
  (if (setq fobj (vl-catch-all-apply 'vlax-invoke (list fso 'getfolder dir)))
    (if (not (vl-catch-all-error-p fobj))
      (progn
        (if (/= (strcase dir) (strcase root))
          (setq name (vlax-get fobj 'name)
                rel  (vl-string-translate "\\" "/" (substr dir (+ 2 (strlen root))))
                out-tree (cons (strcat prefix (if islast "©¸©¤©¤ " "©À©¤©¤ ") name "/   # " rel) out-tree)
          )
        )
        
        (setq items nil)
        (vlax-for x (vlax-get fobj 'subfolders) (setq items (cons (cons x t) items)))
        (vlax-for x (vlax-get fobj 'files)      (setq items (cons (cons x nil) items)))
        (setq items (reverse items)
              cnt   (length items)
              i     0
        )
        
        (setq prefix (if (= (strcase dir) (strcase root)) "" (strcat prefix (if islast "    " "©¦   "))))
        
        (foreach item items
          (setq i (1+ i)
                name (vlax-get (car item) 'name)
          )
          (if (cdr item)
            (cpk:traverse fso (vlax-get (car item) 'path) prefix (= i cnt) root)
            (progn
              (setq rel (vl-string-translate "\\" "/" (substr (vlax-get (car item) 'path) (+ 2 (strlen root)))))
              (setq out-tree (cons (strcat prefix (if (= i cnt) "©¸©¤©¤ " "©À©¤©¤ ") name "   # maps to /" rel) out-tree))
              (setq out-files (cons (list (vlax-get (car item) 'path) name rel) out-files))
            )
          )
        )
        (vlax-release-object fobj)
      )
    )
  )
)

(defun c:cpk ( / *error* old-cmd out-tree out-files fso shl fld root-dir root-name lst fn rel sv-dir sv-path stm cnt err )
  
  (defun *error* ( msg )
    (foreach obj (list fso shl fld stm)
      (if (and obj (= 'vla-object (type obj)) (not (vlax-object-released-p obj)))
        (vl-catch-all-apply 'vlax-release-object (list obj))
      )
    )
    (if old-cmd (setvar 'cmdecho old-cmd))
    (if (and msg (not (wcmatch (strcase msg t) "*break*,*cancel*,*exit*")))
      (princ (strcat "\nCPK Error: " msg))
    )
    (princ)
  )

  (setq old-cmd (getvar 'cmdecho))
  (setvar 'cmdecho 0)
  
  (princ "\nSelect root folder to pack...")
  (if (setq shl (vlax-create-object "shell.application"))
    (progn
      (if (setq fld (vlax-invoke shl 'browseforfolder 0 "Select project root folder (Codebase Packer)" 0 0))
        (setq root-dir (vlax-get (vlax-get fld 'self) 'path))
      )
      (vlax-release-object shl)
    )
  )
  
  (if root-dir
    (progn
      (setq fso (vlax-create-object "scripting.filesystemobject")
            root-name (vlax-get (vlax-invoke fso 'getfolder root-dir) 'name)
            out-tree (list (strcat root-name "/               # [Root Directory] " root-dir) "")
      )
      
      ;; Automatically uses out-tree and out-files via LISP dynamic scoping
      (cpk:traverse fso root-dir "" t root-dir)
      
      (setq lst (list "Part A: Overall Folder and File Structure\n"))
      (foreach x (reverse out-tree)
        (setq lst (cons (strcat x "\n") lst))
      )
      (setq lst (cons "\n\nPart B: Specific File Contents\n" lst)
            out-files (reverse out-files)
            cnt (length out-files)
      )
      
      (foreach x out-files
        (setq fn  (car x)
              rel (caddr x)
        )
        (setq lst (cons (strcat "\n------------------------------------------------------------\n"
                                "File location: " rel "\n"
                                "File name:     " (cadr x) "\n"
                                "------------------------------------------------------------\n\n"
                                (cpk:read fn)
                                "\n")
                        lst)
        )
      )
      (setq lst (reverse lst))
      
      (setq sv-dir (vl-catch-all-apply 'vlax-invoke (list fso 'getparentfoldername root-dir)))
      (if (or (vl-catch-all-error-p sv-dir) (= "" sv-dir))
        (setq sv-dir root-dir)
      )
      (if (/= "\\" (substr sv-dir (strlen sv-dir)))
        (setq sv-dir (strcat sv-dir "\\"))
      )
      
      (if (setq sv-path (getfiled "Save Packed File" (strcat sv-dir root-name "-Packed-" (cpk:getdate) ".txt") "txt" 1))
        (if (setq stm (vlax-create-object "adodb.stream"))
          (progn
            (setq err
              (vl-catch-all-apply
                '(lambda ()
                   (vlax-put-property stm 'type 2)
                   (vlax-put-property stm 'mode 3)
                   (vlax-put-property stm 'charset "utf-8")
                   (vlax-invoke stm 'open)
                   (foreach x lst (vlax-invoke stm 'writetext x))
                   (vlax-invoke stm 'savetofile sv-path 2)
                   (vlax-invoke stm 'close)
                 )
              )
            )
            (vlax-release-object stm)
            (if (vl-catch-all-error-p err)
              (alert "\nUnable to write file. Please check permissions or file path.")
              (alert (strcat "Processing complete!\n\nProcessed " (itoa cnt) " files.\nFile saved (UTF-8) to:\n" sv-path))
            )
          )
        )
      )
      (vlax-release-object fso)
    )
  )
  
  (*error* nil)
  (princ)
)

(princ "\nCodebase Packer (Version 1.0 Release, Author: Vico Wang) loaded. Type CPK to start.")
(princ)

 

The story behind this tool

 

That web frontend I mentioned? It turned into VedaCAD — an experiment in modernising how we manage CAD environments. We're all still copying .arg profiles and fixing broken Support paths like it's 1999. I wanted something simpler: wrap your scripts and configs into 6-character ShareCodes, Then type the ID in the VC panel and pull it down to use it directly.

 

There is a fully free tier (BASE mode works offline, FREE tier allows sync up to 3MB per file). For creators, I'm experimenting with some tools like push-updates and a tip-jar (0% commission), but honestly the platform is still young and I'm here mostly to listen.

 

If you'd like to try the Codebase Packer without copy-pasting, you can install it into AutoCAD using ShareCode 0FBGZB  (whatever that means for you — no pressure).

 

I'd genuinely appreciate any thoughts, especially from the veterans. Is "environment sync" a real pain point for you? Am I solving a problem that's just mine?

 

Cheers,
Vico

Posted
13分钟前,SLW210说:

欢迎来到CADTutor!

Thank you. I am very happy to join this community that keeps pace with the times. It is my honor. I have seen your discussion about AI. As long as you put the master and the slave, not blind, they are just tools to make things better and faster.

  • Like 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...