Wireframe Annotated
nexu-io/open-design
An annotated / redline lo-fi wireframe — a desktop landing/marketing page drawn as flat greyboxes inside a browser chrome frame, overlaid with numbered annotation pins (①②③④⑤) in a single accent…
Analyse a project's source code and generate a simply-annotate database file with LLM-created annotations categorised by tag: defun for functions and large syntactical blocks, line for smaller…
$ npx skills add captainflasmr/ollama-buddy --skill annotate-project -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install captainflasmr/ollama-buddy annotate-project --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/captainflasmr/ollama-buddy.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.agents/skills/annotate-project .claude/skills/annotate-project && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "annotate-project" agent skill from https://github.com/captainflasmr/ollama-buddy/tree/main/.agents/skills/annotate-project into .claude/skills/annotate-project/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "annotate-project", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/captainflasmr/ollama-buddy/tree/main/.agents/skills/annotate-projectType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add captainflasmr/ollama-buddy --skill annotate-project -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install captainflasmr/ollama-buddy annotate-project --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/captainflasmr/ollama-buddy.git skills-src && mkdir -p .agents/skills && cp -r skills-src/.agents/skills/annotate-project .agents/skills/annotate-project && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "annotate-project" agent skill from https://github.com/captainflasmr/ollama-buddy/tree/main/.agents/skills/annotate-project into .agents/skills/annotate-project/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "annotate-project", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add captainflasmr/ollama-buddy --skill annotate-project -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install captainflasmr/ollama-buddy annotate-project --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/captainflasmr/ollama-buddy.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/.agents/skills/annotate-project .cursor/skills/annotate-project && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "annotate-project" agent skill from https://github.com/captainflasmr/ollama-buddy/tree/main/.agents/skills/annotate-project into .cursor/skills/annotate-project/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "annotate-project", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/captainflasmr/ollama-buddy.git --path .agents/skills/annotate-project--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add captainflasmr/ollama-buddy --skill annotate-project -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install captainflasmr/ollama-buddy annotate-project --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/captainflasmr/ollama-buddy.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/.agents/skills/annotate-project .gemini/skills/annotate-project && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "annotate-project" agent skill from https://github.com/captainflasmr/ollama-buddy/tree/main/.agents/skills/annotate-project into .gemini/skills/annotate-project/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "annotate-project", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install captainflasmr/ollama-buddy annotate-projectInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add captainflasmr/ollama-buddy --skill annotate-project -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/captainflasmr/ollama-buddy.git skills-src && mkdir -p .github/skills && cp -r skills-src/.agents/skills/annotate-project .github/skills/annotate-project && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "annotate-project" agent skill from https://github.com/captainflasmr/ollama-buddy/tree/main/.agents/skills/annotate-project into .github/skills/annotate-project/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "annotate-project", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add captainflasmr/ollama-buddy --skill annotate-project -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install captainflasmr/ollama-buddy annotate-project --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/captainflasmr/ollama-buddy.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/.agents/skills/annotate-project .opencode/skills/annotate-project && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "annotate-project" agent skill from https://github.com/captainflasmr/ollama-buddy/tree/main/.agents/skills/annotate-project into .opencode/skills/annotate-project/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "annotate-project", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
annotate-projectAnalyse a project's source code and generate a simply-annotate database file with LLM-created annotations categorised by tag: defun for functions and large syntactical blocks, line for smaller…
Annotate Project is an agent skill from captainflasmr/ollama-buddy. Analyse a project's source code and generate a simply-annotate database file with LLM-created annotations categorised by tag: defun for functions and large syntactical blocks, line for smaller sub-blocks. File-wide narrative lives in a sibling .org overview file, not in an overlay. Use this skill when the user asks to annotate a project, generate code descriptions, or create a simply-annotate database for a codebase. Trigger on phrases like "annotate this project", "generate annotations", "describe this…
Its SKILL.md is about 6.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
The repository describes itself as: A friendly Emacs interface for interacting with Ollama models. The licence is GPL-3.0.
10 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit 12eaf7f. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are bash, elisp, json and org).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Annotate Project loads about 6.2k tokens when it runs. Until then it costs about 149 tokens; SKILL.md has 1,553 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from captainflasmr/ollama-buddy at commit 12eaf7f, republished under its GPL-3.0 licence (© captainflasmr). 1,553 words, ~6,213 tokens.
.claude/skills/annotate-project/SKILL.md (or your agent's skills folder).You are generating a simply-annotate database file that describes a
project's source code using two tag categories — defun (functions, classes,
types, and other major syntactical blocks) and line (smaller sub-blocks worth
calling out). When the user opens files in Emacs with simply-annotate-mode,
they see these as tagged annotations they can filter and step through.
Important: simply-annotate's annotation model is tag-based, not
level-based. The legacy level field (file/defun/line) no longer
exists as a first-class concept — what used to be a level is now a tag on a
thread-format annotation. File-wide overview annotations (overlays spanning
the whole buffer) are not produced; that narrative lives exclusively in
the sibling directory overview .org file created in Step 9.
If the user provides a specific directory or glob argument (e.g.
/annotate-project src/ or /annotate-project java/cuis-server), scan only
that scope. Otherwise scan the project root.
Use the Glob tool to find files matching common source extensions:
**/*.el **/*.py **/*.js **/*.ts **/*.tsx **/*.jsx**/*.rs **/*.go **/*.java **/*.c **/*.cpp **/*.h**/*.rb **/*.lua **/*.sh **/*.clj **/*.hs **/*.protoRespect .gitignore and always skip these directories/patterns:
node_modules, vendor, dist, build, target, .git, __pycache__,
.elc, .classgenerated, gensrc, gen, auto-generatedthird_party, thirdparty, extern, depsAfter discovering files, count them and report the total to the user before doing any reading or annotation. Include:
generated, gensrc,
gen, proto/generated, pb.go, .pb.h, etc.) — flag these and ask
whether to include them.If the file count exceeds 100 files, warn the user:
Found N source files. Annotating all of them will take a while. Would you like to proceed, or narrow the scope to a specific subdirectory?
Wait for confirmation before continuing. If the user narrows scope, re-discover within that scope.
If the count is ≤ 100, proceed automatically.
Annotations are stored in a project-local database file by default. This keeps each project's annotations self-contained, makes them shareable via version control if desired, and avoids one giant global database growing unbounded.
Resolve the database path in this order:
Project-local (default). Find the project root by walking up from the
current working directory looking for one of: .git, .hg, .svn,
package.json, Cargo.toml, pyproject.toml, go.mod, pom.xml,
build.gradle, build.gradle.kts, Makefile. Use that directory. If
nothing is found, use the current working directory itself.
Database path: <project-root>/.simply-annotations.el
Global fallback. Only use ~/.emacs.d/simply-annotations.el if the
user explicitly asks for the global database (e.g. "use the global db",
"save to ~/.emacs.d/...").
Use the resolved path consistently in all subsequent steps (backup,
generate, validate). Refer to it below as $DB_PATH.
Since the annotations target Emacs, use a native elisp batch script to convert line numbers to Emacs point positions. This guarantees byte offsets match what Emacs sees — no manual conversion needed.
The script produces annotations in the current thread-alist format used by simply-annotate:
((start . N)
(end . N)
(text . ((id . "thread-...")
(created . "...")
(status . "open")
(priority . "normal")
(tags . ("defun"))
(comments . (((id . "comment-...")
(parent-id . nil)
(author . "Claude")
(timestamp . "...")
(text . "The actual annotation text")
(type . "comment")))))))It also accepts an optional project root third argument. When supplied,
the DB keys are rewritten to project-relative paths (src/foo.ts rather than
/home/user/project/src/foo.ts) — this is required for project-local
databases, because simply-annotate's simply-annotate--file-key returns a
project-relative path when looking up annotations, and a DB keyed by absolute
paths will silently find nothing.
Write the following script verbatim to /tmp/gen_annotations.el at the
start of the session. Do not modify it — it is tested and known to work.
;;; gen_annotations.el --- Convert line-based annotation JSON to simply-annotate (thread-tag format) -*- lexical-binding: t; -*-
;; Usage: emacs --batch -l /tmp/gen_annotations.el /tmp/annotations.json $DB_PATH [PROJECT_ROOT]
;;
;; When PROJECT_ROOT is supplied, keys are rewritten to project-relative paths.
;; This is REQUIRED for project-local databases.
;;
;; Input JSON shape (per file):
;; { "/abs/path/file.ts": [
;; {"sl": 8, "el": 52, "text": "...", "tag": "defun"},
;; {"sl": 32, "el": 51, "text": "...", "tag": "line"}
;; ] }
(require 'json)
(require 'cl-lib)
(defvar gen-annotations--counter 0)
(defun gen-annotations--uid (prefix)
"Return a stable unique id with PREFIX."
(setq gen-annotations--counter (1+ gen-annotations--counter))
(format "%s-%s-%06d"
prefix
(format-time-string "%s")
gen-annotations--counter))
(defun gen-annotations--make-thread (text tag)
"Wrap TEXT into a minimal thread alist tagged with TAG."
(let ((now (format-time-string "%Y-%m-%dT%H:%M:%S%z")))
`((id . ,(gen-annotations--uid "thread"))
(created . ,now)
(status . "open")
(priority . "normal")
(tags . (,tag))
(comments . (((id . ,(gen-annotations--uid "comment"))
(parent-id . nil)
(author . "Claude")
(timestamp . ,now)
(text . ,text)
(type . "comment")))))))
(defun gen-annotations--line-to-point (buf line-number)
"In BUF, return the point at the beginning of LINE-NUMBER (1-based)."
(with-current-buffer buf
(save-excursion
(goto-char (point-min))
(if (and (> line-number 0)
(zerop (forward-line (1- line-number))))
(point)
(point-max)))))
(defun gen-annotations--end-of-line-region (buf line-number)
"In BUF, return the point at end of LINE-NUMBER (1-based)."
(with-current-buffer buf
(save-excursion
(goto-char (point-min))
(if (and (> line-number 0)
(zerop (forward-line (1- line-number))))
(line-end-position)
(point-max)))))
(defun gen-annotations--convert-file (filepath annotations)
"Convert ANNOTATIONS for FILEPATH from line numbers to point positions.
Each input annotation has keys sl, el, text, tag."
(if (not (file-exists-p filepath))
(progn
(message "WARNING: File not found, skipping: %s" filepath)
nil)
(let ((buf (generate-new-buffer " *gen-ann-temp*"))
result)
(unwind-protect
(progn
(with-current-buffer buf
(insert-file-contents filepath))
(dolist (ann annotations)
(let* ((sl (alist-get 'sl ann))
(el (alist-get 'el ann))
(text (alist-get 'text ann))
(tag (alist-get 'tag ann))
(start (gen-annotations--line-to-point buf sl))
(end (if (= el -1)
(with-current-buffer buf (point-max))
(gen-annotations--end-of-line-region buf el)))
(thread (gen-annotations--make-thread text tag)))
(push `((start . ,start)
(end . ,end)
(text . ,thread))
result))))
(kill-buffer buf))
;; Sort by start position, ascending.
(sort (nreverse result)
(lambda (a b) (< (alist-get 'start a) (alist-get 'start b)))))))
(defun gen-annotations--load-existing (output-path)
"Load existing database from OUTPUT-PATH if it exists."
(when (file-exists-p output-path)
(with-temp-buffer
(insert-file-contents output-path)
(let ((content (string-trim (buffer-string))))
(unless (string-empty-p content)
(condition-case err
(car (read-from-string content))
(error
(message "WARNING: Could not parse existing database: %s"
(error-message-string err))
nil)))))))
(defun gen-annotations--db-key (filepath project-root)
"Return the DB key for FILEPATH, made project-relative when PROJECT-ROOT is set."
(if (and project-root
(stringp project-root)
(> (length project-root) 0)
(string-prefix-p (file-name-as-directory project-root) filepath))
(substring filepath (length (file-name-as-directory project-root)))
filepath))
(defun gen-annotations--main ()
"Main entry point for batch annotation generation."
(let* ((args (last command-line-args 3))
(json-path (nth 0 args))
(output-path (and (nth 1 args) (expand-file-name (nth 1 args))))
(project-root (and (nth 2 args)
(file-name-as-directory
(expand-file-name (nth 2 args))))))
(unless (and json-path output-path)
(error "Usage: emacs --batch -l gen_annotations.el /tmp/annotations.json output.el [project-root]"))
(let* ((json-object-type 'alist)
(json-array-type 'list)
(json-key-type 'symbol)
(annotations (with-temp-buffer
(insert-file-contents json-path)
(json-read)))
(existing-db (gen-annotations--load-existing output-path))
(new-db existing-db)
(file-count 0))
(dolist (entry annotations)
(let* ((filepath (symbol-name (car entry)))
(db-key (gen-annotations--db-key filepath project-root))
(file-annotations (cdr entry))
;; Read from absolute filepath for line-to-point conversion;
;; only the DB key is made relative.
(converted (gen-annotations--convert-file filepath file-annotations)))
(when converted
(cl-incf file-count)
(if (assoc db-key new-db #'string=)
(setcdr (assoc db-key new-db #'string=) converted)
(push (cons db-key converted) new-db)))))
(setq new-db (sort new-db (lambda (a b) (string< (car a) (car b)))))
(with-temp-file output-path
(insert ";;; Simply Annotate Database\n")
(insert ";;; This file is auto-generated. Do not edit manually.\n\n")
(let ((print-level nil)
(print-length nil))
(prin1 new-db (current-buffer)))
(insert "\n"))
(message "Generated annotations for %d files -> %s" file-count output-path))))
(gen-annotations--main)For each source file, read the contents and produce annotations under two
tags: defun and line. Record annotations using line numbers (sl/el)
— the helper script will convert to byte offsets.
Do not produce file-wide overlay annotations. In the previous model there
was a file level covering the whole buffer (sl: 1, el: -1). That overlay
is no longer part of the new format — a single annotation spanning the whole
file overlaps every other annotation and confuses tag filtering. The file's
high-level narrative belongs in the sibling .org overview file created in
Step 9, where it can be read as prose.
defunOne annotation per major syntactical block:
defun, defmacro, defvar, defcustom, defclass,
define-minor-mode, use-package blocksdef, class, top-level decoratorsfunction, class, arrow function assignments,
export default, React componentsfn, impl, struct, enum, trait, modfunc, type, interfacestruct/class/enum definitionsdef, class, modulemessage, enum, service, rpc definitionsThe annotation sl and el should span the full block (from the first line of
the definition to the closing delimiter line). Write a description covering:
what it does, parameters/return values (briefly), key side effects, and how it
relates to the rest of the file. 1-3 sentences.
Skip defun-tagged annotations for trivial files (< 30 lines, or pure boilerplate like single-exception classes, simple data holders, or marker interfaces).
lineAnnotations for smaller but meaningful sub-blocks within defun-tagged regions:
let/let* binding blocksif/cond/pcase/match/switch)condition-case, try/catch/except)Do NOT annotate every line — focus on blocks where a reader would benefit from
context. Aim for roughly 3-8 line-tagged annotations per defun-tagged
block, fewer for simple functions. Skip line annotations entirely for
simple functions.
Collect all annotations into a single JSON object. Use absolute paths as the keys (the helper script will rewrite them to project-relative paths using the project-root argument in Step 7):
{
"/absolute/path/to/file.java": [
{"sl": 25, "el": 80, "text": "Class description...", "tag": "defun"},
{"sl": 42, "el": 55, "text": "Key conditional...", "tag": "line"}
]
}Note there is no file-wide entry (sl: 1, el: -1) — that narrative goes
into the .org overview file in Step 9.
Write this JSON to /tmp/annotations.json.
Before generating, always back up the current database if it exists.
Use the $DB_PATH resolved in Step 2:
cp "$DB_PATH" "$DB_PATH.bak" 2>/dev/null || trueThis ensures the user can recover if the generation or merge corrupts the file.
If something goes wrong, restore with: cp "$DB_PATH.bak" "$DB_PATH".
Run the elisp helper script (written in Step 3) against $DB_PATH. Pass
the project root as a third argument so keys are written as project-relative
paths — without this, simply-annotate will fail to find the annotations when
the user opens a file:
emacs --batch -l /tmp/gen_annotations.el /tmp/annotations.json "$DB_PATH" "$PROJECT_ROOT"Where $PROJECT_ROOT is the directory resolved in Step 2 (the one containing
.simply-annotations.el). Omit the project-root argument only when using
the global database under ~/.emacs.d/, which keys by absolute path.
The script handles everything:
PROJECT_ROOT is supplied, absolute paths inside
that root become project-relative (e.g. src/index.ts).text is a full thread alist with
tags, matching the current simply-annotate on-disk format.prin1, matching
simply-annotate--save-database format — a raw alist readable by
read-from-string. No (setq ...) wrapper.After generating, always run the validation script to confirm the database
is well-formed and won't break simply-annotate-mode. Write the following
verbatim to /tmp/validate_annotations.el and run it against $DB_PATH.
;;; validate_annotations.el --- Validate a simply-annotate thread-tag database -*- lexical-binding: t; -*-
;; Usage: emacs --batch -l /tmp/validate_annotations.el $DB_PATH
(require 'cl-lib)
(defun validate-annotations--thread-p (obj)
"Return non-nil if OBJ looks like a simply-annotate thread alist."
(and (listp obj)
(listp (car-safe obj))
(assq 'id obj)
(assq 'comments obj)))
(defun validate-annotations--main ()
"Validate the simply-annotate database file."
(let* ((db-path (expand-file-name (car (last command-line-args))))
(errors 0)
(warnings 0)
(total-annotations 0)
(tag-counts (make-hash-table :test 'equal))
db)
(unless (file-exists-p db-path)
(message "FAIL: Database file does not exist: %s" db-path)
(kill-emacs 1))
;; Step 1: Can we read it?
(condition-case err
(with-temp-buffer
(insert-file-contents db-path)
(setq db (car (read-from-string (string-trim (buffer-string))))))
(error
(message "FAIL: Cannot parse database: %s" (error-message-string err))
(kill-emacs 1)))
;; Step 2: Is it a list?
(unless (listp db)
(message "FAIL: Database is not a list (got %s)" (type-of db))
(kill-emacs 1))
;; Step 3: Validate each entry
(dolist (entry db)
(let ((filepath (car entry))
(annotations (cdr entry)))
(unless (stringp filepath)
(message "ERROR: Entry key is not a string: %S" filepath)
(cl-incf errors))
(unless (listp annotations)
(message "ERROR: Annotations for %s is not a list" filepath)
(cl-incf errors))
;; File-existence check: project-relative keys won't exist as absolute
;; paths, so skip the check for non-absolute keys.
(when (and (stringp filepath)
(file-name-absolute-p filepath)
(not (file-exists-p filepath)))
(message "WARNING: File does not exist: %s" filepath)
(cl-incf warnings))
(dolist (ann annotations)
(cl-incf total-annotations)
(let ((start (alist-get 'start ann))
(end (alist-get 'end ann))
(text (alist-get 'text ann)))
(unless (and start end text)
(message "ERROR: %s: annotation missing required fields: %S" filepath ann)
(cl-incf errors))
(when (and start (not (and (integerp start) (> start 0))))
(message "ERROR: %s: invalid start: %S" filepath start)
(cl-incf errors))
(when (and end (not (and (integerp end) (> end 0))))
(message "ERROR: %s: invalid end: %S" filepath end)
(cl-incf errors))
(when (and start end (integerp start) (integerp end) (> start end))
(message "ERROR: %s: start (%d) > end (%d)" filepath start end)
(cl-incf errors))
;; text must be a string OR a thread alist.
(unless (or (stringp text)
(validate-annotations--thread-p text))
(message "ERROR: %s: text is neither a string nor a thread alist: %S"
filepath text)
(cl-incf errors))
;; Accumulate tag counts for reporting.
(when (validate-annotations--thread-p text)
(dolist (tag (alist-get 'tags text))
(puthash tag (1+ (gethash tag tag-counts 0)) tag-counts)))))))
;; Report
(message "Validation complete: %d files, %d annotations, %d errors, %d warnings"
(length db) total-annotations errors warnings)
(when (> (hash-table-count tag-counts) 0)
(message "Tag breakdown:")
(maphash (lambda (tag count) (message " %s: %d" tag count)) tag-counts))
(if (> errors 0)
(progn
(message "FAIL: Database has %d errors. Restore backup with:" errors)
(message " cp %s.bak %s" db-path db-path)
(kill-emacs 1))
(message "OK: Database is valid.")
(kill-emacs 0))))
(validate-annotations--main)Run with:
emacs --batch -l /tmp/validate_annotations.el "$DB_PATH"If validation fails, immediately restore the backup:
cp "$DB_PATH.bak" "$DB_PATH"Then investigate the /tmp/annotations.json for the bad data and re-run
generation.
For the annotated directory, create an org file alongside it with the same
name as the directory. For example, annotating /project/java/client creates
/project/java/client.org.
The org file should contain:
#+TITLE: <directory-name> — Directory Overview
#+AUTO_TANGLE: nil
* Purpose
<2-4 sentence overview of what this directory/module does and its role in the
wider project.>
* Structure
<Brief description of how the directory is organised — subdirectories, key
groupings of files, and the relationships between them.>
** <subdirectory-or-grouping-1>
<1-2 sentences on what this group of files does.>
** <subdirectory-or-grouping-2>
...
* Key Files
| File | Description |
|------+-------------|
| file1.java | One-line summary |
| file2.java | One-line summary |
| ... | ... |
List ALL source files in the directory scope, not just the "important" ones.
Group by subdirectory if the directory has subdirectories.
* Important Notes
<Bullet points covering anything a newcomer should know: key patterns used,
auto-generated files to ignore, non-obvious conventions, gotchas, entry points,
important interfaces, etc. Skip this section if there is nothing noteworthy.>java/client, create java/client.org. If they annotate java/cuis-server,
create java/cuis-server.org.Key Files table and Structure section are the primary home for
file-wide narrative (since there is no file-level overlay annotation). Each
file's one-line summary here is what a file-level annotation used to
provide.gensrc/), note
them in Important Notes.After writing, report:
defun and line)simply-annotate-mode
(or use simply-annotate-show-all for the global overview)defun-tagged descriptions 1-3 sentences; line-tagged
1 sentence. File-wide overview prose lives in the .org overview file
(2-4 sentences per file in the Key Files table).© captainflasmr, GPL-3.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in .agents/skills/annotate-project of captainflasmr/ollama-buddy.
Open the folder on GitHubat commit 12eaf7f
Annotate Project next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Annotate Project this skillcaptainflasmr/ollama-buddy | 103 | — | ~6.2k | Automated safety check: Pass | GPL-3.0 | |
| Wireframe Annotatednexu-io/open-design | 100k | — | ~960 | Automated safety check: Pass | Apache-2.0 | |
| Arize Annotationgithub/awesome-copilot | 40k | 1 repos | ~2.7k | Automated safety check: Notes | MIT | |
| Image Annotationsgithub/awesome-copilot | 40k | — | ~6k | Automated safety check: Pass | MIT | |
| Plannotator Annotatebacknotprop/plannotator | 9.2k | — | ~163 | Automated safety check: Pass | Apache-2.0 | |
| Bio Genome Annotation Annotation QcGPTomics/bioSkills | 1.2k | 1 repos | ~3.6k | Automated safety check: Pass | MIT |
nexu-io/open-design
An annotated / redline lo-fi wireframe — a desktop landing/marketing page drawn as flat greyboxes inside a browser chrome frame, overlaid with numbered annotation pins (①②③④⑤) in a single accent…
github/awesome-copilot
Creates and manages annotation configs (categorical, continuous, freeform label schemas) and annotation queues (human review workflows) on Arize.
github/awesome-copilot
Annotate screenshots, diagrams, and images with callout rectangles, arrows, labels, and color-coded highlights using PIL.
backnotprop/plannotator
Open Plannotator's annotation UI for a file, folder, or URL, then address the returned annotations.
GPTomics/bioSkills
Assesses the quality and completeness of a genome annotation with BUSCO (conserved single-copy ortholog recovery), OMArk (proteome completeness, consistency, and contamination), CheckM2 (prokaryotic…
GPTomics/bioSkills
Transfers gene annotations between genome assemblies via coordinate liftover (UCSC liftOver, CrossMap for same-species version updates) or feature/sequence projection (Liftoff for same/close…
captainflasmr/ollama-buddy
Write an Emacs blog post in James Dyer's voice for www.emacs.dyerdwelling.family.
captainflasmr/ollama-buddy
Assist with Emacs Lisp (elisp) development, debugging, and parenthesis matching.
captainflasmr/ollama-buddy
Review Emacs Lisp (elisp) packages for bugs, style/convention violations, and optimisation opportunities.
captainflasmr/ollama-buddy
Write an r/emacs Reddit post in James Dyer's voice for announcing or discussing an Emacs package.
captainflasmr/ollama-buddy
Expert code refactoring and optimization with analysis, improvements, and documentation.
captainflasmr/ollama-buddy
Review Emacs blog posts for technical accuracy, naming conventions, and correct Emacs idioms.
Analyse a project's source code and generate a simply-annotate database file with LLM-created annotations categorised by tag: defun for functions and large syntactical blocks, line for smaller…. Annotate Project is an agent skill from captainflasmr/ollama-buddy. Analyse a project's source code and generate a simply-annotate database file with LLM-created annotations categorised by tag: defun for functions and large syntactical blocks, line for smaller sub-blocks.
Annotate Project fits situations like: the user asks to annotate a project; generate code descriptions; create a simply-annotate database for a codebase; phrases like annotate this project.
Run `npx skills add captainflasmr/ollama-buddy --skill annotate-project -a claude-code`. Or copy the skill folder (.agents/skills/annotate-project in captainflasmr/ollama-buddy) into .claude/skills/annotate-project in your project. Claude Code loads it when a task matches its description.
Run `npx skills add captainflasmr/ollama-buddy --skill annotate-project -a codex`. Or copy the skill folder (.agents/skills/annotate-project in captainflasmr/ollama-buddy) into .agents/skills/annotate-project in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add captainflasmr/ollama-buddy --skill annotate-project -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/annotate-project, .gemini/skills/annotate-project, .github/skills/annotate-project and .opencode/skills/annotate-project in your project.
SKILL.md names no scripts, command-line tools or credentials: Annotate Project is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Annotate Project is published under the GPL-3.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.2k tokens (SKILL.md is roughly 25k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Annotate Project: Wireframe Annotated (nexu-io/open-design, 100k stars), Arize Annotation (github/awesome-copilot, 40k stars), Image Annotations (github/awesome-copilot, 40k stars) and Plannotator Annotate (backnotprop/plannotator, 9.2k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
captainflasmr (a GitHub user) maintains it in captainflasmr/ollama-buddy, which has 103 GitHub stars. The repository holds 12 skills in this directory. The repository was last updated on September 10, 2026.
Source: captainflasmr/ollama-buddy on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.