Let's evolve our skills with Claude Code help
This commit is contained in:
commit
cfa64a51f0
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "fenix-skills",
|
||||
"owner": {
|
||||
"name": "Fénix",
|
||||
"email": "fenix@local"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Fénix's Claude Code skills — Emacs integration (forked from xenodium/emacs-skills) + custom productivity tools",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "fenix-tools",
|
||||
"description": "Fénix's Emacs integration and productivity skills for Claude Code",
|
||||
"source": "./",
|
||||
"strict": false,
|
||||
"skills": [
|
||||
"./skills/d2",
|
||||
"./skills/describe",
|
||||
"./skills/dired",
|
||||
"./skills/emacsclient",
|
||||
"./skills/extract-pdf-pages",
|
||||
"./skills/file-links",
|
||||
"./skills/gnuplot",
|
||||
"./skills/highlight",
|
||||
"./skills/mermaid",
|
||||
"./skills/open",
|
||||
"./skills/plantuml",
|
||||
"./skills/select"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
# Fenix Skills — Claude Code Plugin
|
||||
|
||||
Custom Claude Code skills for Fénix's workflow.
|
||||
Includes all [xenodium/emacs-skills](https://github.com/xenodium/emacs-skills) (forked & rebranded) plus Fénix's own productivity tools.
|
||||
|
||||
---
|
||||
|
||||
## Plugin Structure
|
||||
|
||||
```
|
||||
~/Emacs/fenix-skills/
|
||||
├── .claude-plugin/
|
||||
│ └── marketplace.json # Plugin manifest
|
||||
├── README.md
|
||||
└── skills/
|
||||
├── d2/ # /d2 — Create D2 diagrams
|
||||
├── describe/ # /describe — Emacs describe-* lookups
|
||||
├── dired/ # /dired — Open files in dired buffer
|
||||
├── emacsclient/ # (auto) Always use emacsclient, not emacs
|
||||
├── extract-pdf-pages/ # /extract-pdf-pages — Extract page ranges with pdftk
|
||||
├── file-links/ # (auto) Format file refs as markdown #L links
|
||||
├── gnuplot/ # /gnuplot — Plot data with gnuplot
|
||||
├── highlight/ # /highlight — Highlight regions in Emacs
|
||||
├── mermaid/ # /mermaid — Create Mermaid diagrams
|
||||
├── open/ # /open — Open files in Emacs buffers
|
||||
├── plantuml/ # /plantuml — Create PlantUML diagrams
|
||||
└── select/ # /select — Select regions in Emacs
|
||||
```
|
||||
|
||||
## Registration
|
||||
|
||||
Registered in `~/.claude/settings.json` as:
|
||||
|
||||
```json
|
||||
"extraKnownMarketplaces": {
|
||||
"fenix-skills": {
|
||||
"source": {
|
||||
"source": "directory",
|
||||
"path": "/home/fenix/Emacs/fenix-skills"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
"enabledPlugins": {
|
||||
"fenix-tools@fenix-skills": true
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
All slash-command skills are available **system-wide** in any Claude Code session:
|
||||
|
||||
| Skill | Invocation | Description |
|
||||
|:---|:---:|:---|
|
||||
| **d2** | `/d2` | Create diagrams with D2 |
|
||||
| **describe** | `/describe` | Look up Emacs docs (functions, variables, keys) |
|
||||
| **dired** | `/dired` | Open recent files in Emacs dired buffer |
|
||||
| **emacsclient** | _(auto)_ | Always prefer `emacsclient` over `emacs` |
|
||||
| **extract-pdf-pages** | `/extract-pdf-pages` | Extract page range from PDF via `pdftk` |
|
||||
| **file-links** | _(auto)_ | Format file references as `file.py#L42` links |
|
||||
| **gnuplot** | `/gnuplot` | Plot data with gnuplot |
|
||||
| **highlight** | `/highlight` | Highlight line regions in Emacs buffers |
|
||||
| **mermaid** | `/mermaid` | Create Mermaid diagrams |
|
||||
| **open** | `/open` | Open files in Emacs (with optional line jump) |
|
||||
| **plantuml** | `/plantuml` | Create PlantUML diagrams |
|
||||
| **select** | `/select` | Select (mark) regions in Emacs buffers |
|
||||
|
||||
## Origin
|
||||
|
||||
- **Emacs skills** (d2, describe, dired, emacsclient, file-links, gnuplot, highlight, mermaid, open, plantuml, select) — forked from [xenodium/emacs-skills](https://github.com/xenodium/emacs-skills) by Alvaro Ramirez
|
||||
- **extract-pdf-pages** — original, requires `pdftk` (`apt install pdftk`)
|
||||
|
||||
## Requirements
|
||||
|
||||
- GNU Emacs with running server daemon (`emacsclient` accessible)
|
||||
- `pdftk` for PDF extraction skill
|
||||
- Claude Code with plugins enabled
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
name: d2
|
||||
description: 'This skill should be used when the user invokes "/d2" to create a diagram from the current context using D2 and output the resulting image path.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Create diagrams with D2
|
||||
|
||||
Create a diagram from the most recent interaction context using D2. Generate a PNG image and output it as a markdown image so it renders inline.
|
||||
|
||||
## How to create a diagram
|
||||
|
||||
1. Extract or derive diagrammable data from the current context.
|
||||
2. If the Emacs foreground color and background mode are not already known from a previous diagram in this session, query them:
|
||||
```sh
|
||||
emacsclient --eval '(face-foreground (quote default))'
|
||||
emacsclient --eval '(frame-parameter nil (quote background-mode))'
|
||||
```
|
||||
The first returns a hex color like `"#eeffff"`. The second returns `dark` or `light`. Reuse both for all subsequent diagrams.
|
||||
3. Write a D2 file to a temporary file using the foreground color.
|
||||
4. Run D2 with `--theme 200` if background mode is `dark`, or `--theme 0` if `light`.
|
||||
5. Output the result as a markdown image on its own line:
|
||||
```
|
||||

|
||||
```
|
||||
|
||||
```sh
|
||||
# Use --theme 200 for dark, --theme 0 for light
|
||||
d2 --theme 200 --pad 40 /tmp/agent-diagram-XXXX.d2 /tmp/agent-diagram-XXXX.png
|
||||
```
|
||||
|
||||
## D2 template
|
||||
|
||||
Use `--theme 200` for dark or `--theme 0` for light, based on the Emacs background mode. Apply the queried foreground color to `style.font-color` and `style.stroke` on nodes and edges.
|
||||
|
||||
```d2
|
||||
direction: right
|
||||
|
||||
node1: Label {
|
||||
style.font-color: "#eeffff"
|
||||
style.fill: "#2d3748"
|
||||
style.stroke: "#eeffff"
|
||||
}
|
||||
|
||||
node2: Label {
|
||||
style.font-color: "#eeffff"
|
||||
style.fill: "#2d3748"
|
||||
style.stroke: "#eeffff"
|
||||
}
|
||||
|
||||
node1 -> node2: label {style.stroke: "#eeffff"; style.font-color: "#eeffff"}
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Query the Emacs foreground color once per session and reuse it for all subsequent diagrams. Only query again if the color is not already known.
|
||||
- Query the Emacs background mode once per session via `(frame-parameter nil 'background-mode)`. Use `--theme 200` for `dark` or `--theme 0` for `light`. Always use `--pad 40`.
|
||||
- Always use a timestamp in the filename (e.g., `/tmp/agent-diagram-$(date +%s).png`). Never use descriptive names.
|
||||
- Set the queried foreground color on `style.font-color` and `style.stroke` for all nodes and edges so the diagram is readable on the user's Emacs background.
|
||||
- Use meaningful fill colors to distinguish different types of elements.
|
||||
- After D2 runs successfully, output a markdown image (``) on its own line.
|
||||
- Choose an appropriate layout direction and structure for the data.
|
||||
- Include labels on edges when they add clarity.
|
||||
- If no diagrammable data exists in the recent context, inform the user.
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
name: describe
|
||||
description: 'This skill should be used when the user invokes "/describe" to look up Emacs documentation via emacsclient.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Look up Emacs documentation
|
||||
|
||||
Look up Emacs documentation using `emacsclient --eval` and summarize the findings. The query is searched across multiple mechanisms (function, variable, face, key binding, and apropos) in one call, returning all findings as a single string.
|
||||
|
||||
First, locate `agent-skill-describe.el` which lives alongside this skill file at `skills/describe/agent-skill-describe.el` in the emacs-skills plugin directory.
|
||||
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(progn
|
||||
(load "/path/to/skills/describe/agent-skill-describe.el" nil t)
|
||||
(agent-skill-describe :query "dired-mark"))'
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Summarize the returned documentation for the user in the conversation.
|
||||
- Locate `agent-skill-describe.el` relative to this skill file's directory.
|
||||
- Run the `emacsclient --eval` command via the Bash tool.
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
(require 'cl-lib)
|
||||
|
||||
(cl-defun agent-skill-describe (&key query)
|
||||
"Look up QUERY across multiple Emacs documentation mechanisms.
|
||||
|
||||
Searches for QUERY as a function, variable, and via apropos,
|
||||
returning all findings in a single string."
|
||||
(let ((sym (intern-soft query))
|
||||
(sections nil))
|
||||
;; Function documentation
|
||||
(when (and sym (fboundp sym))
|
||||
(push (format "## Function: %s\n\n%s\n\nSignature: %s\n\n%s"
|
||||
query
|
||||
(cond ((subrp (symbol-function sym)) "Built-in function")
|
||||
((macrop sym) "Macro")
|
||||
((commandp sym) "Interactive command")
|
||||
(t "Function"))
|
||||
(or (help-function-arglist sym t) "()")
|
||||
(or (documentation sym t) "No documentation available."))
|
||||
sections))
|
||||
;; Variable documentation
|
||||
(when (and sym (boundp sym))
|
||||
(let ((val (symbol-value sym)))
|
||||
(push (format "## Variable: %s\n\nCurrent value: %s\n\n%s"
|
||||
query
|
||||
(let ((printed (format "%S" val)))
|
||||
(if (> (length printed) 200)
|
||||
(concat (substring printed 0 200) "...")
|
||||
printed))
|
||||
(or (documentation-property sym 'variable-documentation t)
|
||||
"No documentation available."))
|
||||
sections)))
|
||||
;; Face documentation
|
||||
(when (and sym (facep sym))
|
||||
(push (format "## Face: %s\n\n%s"
|
||||
query
|
||||
(or (documentation-property sym 'face-documentation t)
|
||||
"No documentation available."))
|
||||
sections))
|
||||
;; Key binding (if it looks like a key sequence)
|
||||
(when (string-match-p "\\`[CMSs]-\\|\\`<" query)
|
||||
(let* ((keyseq (ignore-errors (kbd query)))
|
||||
(binding (and keyseq (key-binding keyseq))))
|
||||
(when binding
|
||||
(push (format "## Key binding: %s\n\n%s runs `%s'\n\n%s"
|
||||
query query binding
|
||||
(or (documentation binding t)
|
||||
"No documentation available."))
|
||||
sections))))
|
||||
;; Apropos matches (up to 20)
|
||||
(let ((matches nil))
|
||||
(mapatoms
|
||||
(lambda (s)
|
||||
(when (and (string-match-p (regexp-quote query) (symbol-name s))
|
||||
(not (eq s sym))
|
||||
(or (fboundp s) (boundp s)))
|
||||
(push (format " %s%s"
|
||||
(symbol-name s)
|
||||
(cond ((and (fboundp s) (boundp s))
|
||||
" [function, variable]")
|
||||
((fboundp s) " [function]")
|
||||
(t " [variable]")))
|
||||
matches))))
|
||||
(when matches
|
||||
(let ((sorted (sort matches #'string<)))
|
||||
(push (format "## Related symbols\n\n%s%s"
|
||||
(mapconcat #'identity (seq-take sorted 20) "\n")
|
||||
(if (> (length sorted) 20)
|
||||
(format "\n ... and %d more" (- (length sorted) 20))
|
||||
""))
|
||||
sections))))
|
||||
(if sections
|
||||
(mapconcat #'identity (nreverse sections) "\n\n")
|
||||
(format "No documentation found for \"%s\"." query))))
|
||||
|
||||
(provide 'agent-skill-describe)
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
---
|
||||
name: dired
|
||||
description: 'This skill should be used when the user invokes "/dired" to open files from the latest interaction in an Emacs dired buffer via emacsclient.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Open files in Emacs dired
|
||||
|
||||
Open files from the most recent interaction in an Emacs dired buffer using `emacsclient --eval`. Only include files relevant to the latest interaction (files just generated, edited, listed, or produced by the most recent tool output), not all files mentioned throughout the conversation.
|
||||
|
||||
## Strategy
|
||||
|
||||
Determine whether the relevant files all reside in the same directory or span multiple directories, then call `agent-skill-dired` accordingly.
|
||||
|
||||
- **Same directory**: `:dir` is the directory, `:files` are basenames. Opens dired at that directory with the files marked in context.
|
||||
- **Multiple directories**: `:dir` is the common ancestor, `:files` are relative paths. Creates a curated `*agent-files*` buffer with all files marked.
|
||||
|
||||
First, locate `agent-skill-dired.el` which lives alongside this skill file at `skills/dired/agent-skill-dired.el` in the emacs-skills plugin directory.
|
||||
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(progn
|
||||
(load "/path/to/skills/dired/agent-skill-dired.el" nil t)
|
||||
(agent-skill-dired
|
||||
:dir "/path/to/directory"
|
||||
:files (quote ("file1.txt"
|
||||
"file2.txt"
|
||||
"file3.txt"))))'
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Use relative paths in `:files` relative to `:dir`.
|
||||
- Locate `agent-skill-dired.el` relative to this skill file's directory.
|
||||
- If no relevant files exist in the recent interaction, inform the user.
|
||||
- Run the `emacsclient --eval` command via the Bash tool.
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
(require 'cl-lib)
|
||||
(require 'dired)
|
||||
|
||||
(cl-defun agent-skill-dired (&key dir files)
|
||||
"Open a dired buffer at DIR with FILES marked.
|
||||
|
||||
When all files share the same parent directory, DIR is that
|
||||
directory and FILES are basenames shown in context.
|
||||
|
||||
When files span multiple directories, DIR is the common ancestor
|
||||
and FILES are relative paths. A curated `*agent-files*' buffer
|
||||
is created instead."
|
||||
(let ((same-dir-p (cl-every (lambda (f) (not (string-match-p "/" f))) files)))
|
||||
(if same-dir-p
|
||||
(progn
|
||||
(dired dir)
|
||||
(dired-unmark-all-marks)
|
||||
(dolist (file files)
|
||||
(dired-goto-file (expand-file-name file dir))
|
||||
(dired-mark 1)))
|
||||
(let ((default-directory (file-name-as-directory dir)))
|
||||
(dired (cons "*agent-files*" files))
|
||||
(dired-unmark-all-marks)
|
||||
(dired-toggle-marks)))))
|
||||
|
||||
(provide 'agent-skill-dired)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
name: emacsclient
|
||||
description: 'Always use emacsclient instead of emacs. This applies to all Emacs operations: user requests, byte compilation, check-parens, running ERT tests, and any other elisp evaluation.'
|
||||
tools: Bash
|
||||
---
|
||||
|
||||
# Always use emacsclient
|
||||
|
||||
The user has an Emacs server running. **All** Emacs operations must go through `emacsclient`, never `emacs` or `emacs --batch`. This includes both user-requested actions and agent-initiated operations like byte compilation, syntax checking, or running tests.
|
||||
|
||||
## Examples
|
||||
|
||||
- Open a file: `emacsclient --no-wait "/path/to/file"`
|
||||
- Evaluate elisp: `emacsclient --eval '(some-function)'`
|
||||
- Open at a line: `emacsclient --no-wait +42 "/path/to/file"`
|
||||
- Byte compile a file:
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(byte-compile-file "/path/to/file.el")'
|
||||
```
|
||||
- Check parentheses:
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(with-temp-buffer
|
||||
(insert-file-contents "/path/to/file.el")
|
||||
(check-parens))'
|
||||
```
|
||||
- Run ERT tests:
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(progn
|
||||
(load "/path/to/test-file.el" nil t)
|
||||
(ert-run-tests-batch-and-exit "pattern"))'
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Always use `emacsclient`, never `emacs` or `emacs --batch`.
|
||||
- Use `--no-wait` when opening files so the command returns immediately.
|
||||
- Use `--eval` when evaluating elisp.
|
||||
- Always format `--eval` elisp across multiple lines with proper indentation.
|
||||
- Run `emacsclient` commands via the Bash tool.
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
name: extract-pdf-pages
|
||||
description: 'Use when the user invokes "/extract-pdf-pages" to extract a page range from a PDF file using pdftk.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Extract PDF Pages
|
||||
|
||||
Extract a page range from a PDF file into a new PDF using `pdftk`.
|
||||
|
||||
## Usage
|
||||
|
||||
When invoked, ask the user for (if not already provided):
|
||||
1. **Source PDF** — absolute path to the input PDF file
|
||||
2. **Page range** — start and end pages (e.g., `200-204`)
|
||||
3. **Output filename** — name for the new PDF (defaults to current working directory)
|
||||
|
||||
## Command
|
||||
|
||||
```bash
|
||||
pdftk "<source_pdf>" cat <start>-<end> output "<output_path>"
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Always use absolute paths for both source and output files.
|
||||
- If the user provides only a filename (no directory), place the output in the current working directory.
|
||||
- If the output file already exists, warn the user before overwriting.
|
||||
- Support multiple extractions in a single invocation (run them in parallel).
|
||||
- After extraction, confirm with file size: `ls -lh "<output_path>"`
|
||||
- Requires `pdftk` to be installed (`apt install pdftk`).
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
name: file-links
|
||||
description: 'When referencing files, format them as markdown links with line numbers using GitHub-style #L syntax.'
|
||||
---
|
||||
|
||||
# Format file references as markdown links
|
||||
|
||||
When referencing files in your output, always format them as markdown links. Use the GitHub-style `#L` fragment for line numbers.
|
||||
|
||||
## Format
|
||||
|
||||
With a line number:
|
||||
|
||||
```
|
||||
[filename.el:42](relative/path/to/filename.el#L42)
|
||||
```
|
||||
|
||||
With a line range:
|
||||
|
||||
```
|
||||
[filename.el:42-50](relative/path/to/filename.el#L42-L50)
|
||||
```
|
||||
|
||||
Without a line number:
|
||||
|
||||
```
|
||||
[filename.el](relative/path/to/filename.el)
|
||||
```
|
||||
|
||||
## Important
|
||||
|
||||
- The link text uses `:` for line numbers (e.g., `filename.el:42`).
|
||||
- The URL uses `#L` for line numbers (e.g., `filename.el#L42`).
|
||||
- For ranges, the link text uses `-` (e.g., `filename.el:42-50`) and the URL uses `-L` (e.g., `filename.el#L42-L50`).
|
||||
- The range must appear in both the link text and the URL.
|
||||
|
||||
Do NOT do this:
|
||||
|
||||
```
|
||||
[filename.el#L42-L50](filename.el#L42)
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Use paths relative to the project root.
|
||||
- Include line numbers when they are relevant (e.g., error locations, function definitions, modified lines).
|
||||
- Use line ranges when referring to a block of code.
|
||||
- The link text should be the filename (or relative path if needed for clarity) followed by the line number.
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
---
|
||||
name: gnuplot
|
||||
description: 'This skill should be used when the user invokes "/gnuplot" to plot data from the current context using gnuplot and output the resulting image path.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Plot data with gnuplot
|
||||
|
||||
Plot data from the most recent interaction context using gnuplot. Generate a PNG image with a transparent background and output it as a markdown image so it renders inline.
|
||||
|
||||
## How to plot
|
||||
|
||||
1. Extract or derive plottable data from the current context.
|
||||
2. If the Emacs foreground color is not already known from a previous plot in this session, query it:
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(face-foreground (quote default))'
|
||||
```
|
||||
This returns a hex color like `"#eeffff"`. Reuse it for all subsequent plots.
|
||||
3. Write a gnuplot script to a temporary file using that color.
|
||||
4. Run gnuplot on the script.
|
||||
5. Output the result as a markdown image on its own line:
|
||||
```
|
||||

|
||||
```
|
||||
|
||||
```sh
|
||||
gnuplot /tmp/agent-plot-XXXX.gp
|
||||
```
|
||||
|
||||
## Gnuplot script template
|
||||
|
||||
```gnuplot
|
||||
set terminal pngcairo transparent enhanced size 800,500
|
||||
set output "/tmp/agent-plot-XXXX.png"
|
||||
|
||||
FG = "#eeffff" # from emacsclient query
|
||||
set border lc rgb FG
|
||||
set key textcolor rgb FG
|
||||
set xlabel textcolor rgb FG
|
||||
set ylabel textcolor rgb FG
|
||||
set title textcolor rgb FG
|
||||
set xtics textcolor rgb FG
|
||||
set ytics textcolor rgb FG
|
||||
|
||||
# ... plot commands using the data ...
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Query the Emacs foreground color once per session and reuse it for all subsequent plots. Only query again if the color is not already known.
|
||||
- Always use `pngcairo transparent` terminal for transparent background.
|
||||
- Always use a timestamp in the filename (e.g., `/tmp/agent-plot-$(date +%s).png`). Never use descriptive names like `agent-plot-lorenz.png`.
|
||||
- Use inline data (`$DATA << EOD ... EOD`) when practical. For large datasets, write a separate data file.
|
||||
- After gnuplot runs successfully, output a markdown image (``) on its own line.
|
||||
- Choose an appropriate plot type for the data (lines, bars, histogram, scatter, etc.).
|
||||
- Include a title, axis labels, and a legend when they add clarity.
|
||||
- Use `enhanced` text mode for subscripts/superscripts when needed.
|
||||
- If no plottable data exists in the recent context, inform the user.
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
name: highlight
|
||||
description: 'This skill should be used when the user invokes "/highlight" to highlight relevant regions in one or more files in Emacs via emacsclient.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Highlight regions in Emacs
|
||||
|
||||
Highlight relevant regions in one or more files in Emacs using `emacsclient --eval`. Files are opened in a temporary read-only minor mode with highlighted overlays. The user presses `q` to exit the mode and remove all highlights in that buffer.
|
||||
|
||||
Determine the relevant files and line ranges from the most recent interaction context.
|
||||
|
||||
## How to highlight
|
||||
|
||||
First, determine the path to `agent-skill-highlight.el`. It lives alongside this skill file at `skills/highlight/agent-skill-highlight.el` in the emacs-skills plugin directory.
|
||||
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(progn
|
||||
(load "/path/to/skills/highlight/agent-skill-highlight.el" nil t)
|
||||
(agent-skill-highlight
|
||||
:files (quote (("/path/to/file1.el"
|
||||
:regions ((:start 90 :lines 18)
|
||||
(:start 114 :lines 49)))
|
||||
("/path/to/file2.el"
|
||||
:regions ((:start 94 :lines 18)))))))'
|
||||
```
|
||||
|
||||
- `:start` is the 1-indexed line number.
|
||||
- `:lines` is the number of lines to highlight from that start line.
|
||||
- Add as many files and regions as needed.
|
||||
|
||||
## Rules
|
||||
|
||||
- Use absolute paths for files.
|
||||
- Locate `agent-skill-highlight.el` relative to this skill file's directory.
|
||||
- If no relevant files or regions exist in the recent interaction, inform the user.
|
||||
- Run the `emacsclient --eval` command via the Bash tool.
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
(eval-when-compile
|
||||
(require 'cl-lib))
|
||||
(require 'hi-lock)
|
||||
|
||||
(defvar-local agent-skill-highlight--overlays nil)
|
||||
(defvar-local agent-skill-highlight--was-read-only nil)
|
||||
|
||||
(defun agent-skill-highlight--remove-overlays ()
|
||||
(mapc #'delete-overlay agent-skill-highlight--overlays)
|
||||
(setq agent-skill-highlight--overlays nil))
|
||||
|
||||
(defun agent-skill-highlight-exit ()
|
||||
(interactive)
|
||||
(agent-skill-highlight-mode -1))
|
||||
|
||||
(define-minor-mode agent-skill-highlight-mode
|
||||
"Temporary read-only mode with highlighted regions. Press q to exit."
|
||||
:lighter " Highlight"
|
||||
:keymap (let ((map (make-sparse-keymap)))
|
||||
(define-key map (kbd "q") #'agent-skill-highlight-exit)
|
||||
map)
|
||||
(if agent-skill-highlight-mode
|
||||
(progn
|
||||
(setq agent-skill-highlight--was-read-only buffer-read-only)
|
||||
(read-only-mode 1)
|
||||
(message "Press q to exit highlights"))
|
||||
(agent-skill-highlight--remove-overlays)
|
||||
(unless agent-skill-highlight--was-read-only
|
||||
(read-only-mode -1))))
|
||||
|
||||
(cl-defun agent-skill-highlight (&key files)
|
||||
"Highlight regions in FILES.
|
||||
|
||||
FILES is a list of (FILE-PATH :regions REGIONS) where REGIONS is
|
||||
a list of (:start LINE :lines COUNT)."
|
||||
(dolist (file-spec files)
|
||||
(let ((file-path (car file-spec))
|
||||
(regions (plist-get (cdr file-spec) :regions)))
|
||||
(find-file file-path)
|
||||
(dolist (region regions)
|
||||
(let* ((start-line (plist-get region :start))
|
||||
(num-lines (plist-get region :lines))
|
||||
(ov (make-overlay
|
||||
(progn (goto-char (point-min))
|
||||
(forward-line (1- start-line))
|
||||
(point))
|
||||
(progn (forward-line num-lines)
|
||||
(point)))))
|
||||
(overlay-put ov 'face 'hi-yellow)
|
||||
(push ov agent-skill-highlight--overlays)))
|
||||
(agent-skill-highlight-mode 1))))
|
||||
|
||||
(provide 'agent-skill-highlight)
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
---
|
||||
name: mermaid
|
||||
description: 'This skill should be used when the user invokes "/mermaid" to create a diagram from the current context using Mermaid and output the resulting image path.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Create diagrams with Mermaid
|
||||
|
||||
Create a diagram from the most recent interaction context using Mermaid. Generate a PNG image with a transparent background and output it as a markdown image so it renders inline.
|
||||
|
||||
## How to create a diagram
|
||||
|
||||
1. Extract or derive diagrammable data from the current context.
|
||||
2. If the Emacs foreground color and background mode are not already known from a previous diagram in this session, query them:
|
||||
```sh
|
||||
emacsclient --eval '(face-foreground (quote default))'
|
||||
emacsclient --eval '(frame-parameter nil (quote background-mode))'
|
||||
```
|
||||
The first returns a hex color like `"#eeffff"`. The second returns `dark` or `light`. Reuse both for all subsequent diagrams.
|
||||
3. Write a Mermaid file to a temporary file.
|
||||
4. Write a JSON config file that overrides theme variables with the queried foreground color. Set `"theme"` to `"dark"` or `"default"` based on the background mode.
|
||||
5. Run `mmdc` with `-t dark` if background mode is `dark`, or `-t default` if `light`.
|
||||
6. Output the result as a markdown image on its own line:
|
||||
```
|
||||

|
||||
```
|
||||
|
||||
```sh
|
||||
# Use -t dark for dark, -t default for light
|
||||
PUPPETEER_EXECUTABLE_PATH=/opt/homebrew/bin/chromium mmdc \
|
||||
-i /tmp/agent-diagram-XXXX.mmd \
|
||||
-o /tmp/agent-diagram-XXXX.png \
|
||||
-t dark -b transparent --scale 2 \
|
||||
--configFile /tmp/agent-diagram-XXXX-config.json
|
||||
```
|
||||
|
||||
## Mermaid config template
|
||||
|
||||
Write this JSON config file to apply the Emacs foreground color. Replace `#eeffff` with the queried color. Set `"theme"` to `"dark"` or `"default"` based on the Emacs background mode.
|
||||
|
||||
```json
|
||||
{
|
||||
"theme": "dark",
|
||||
"themeVariables": {
|
||||
"primaryTextColor": "#eeffff",
|
||||
"secondaryTextColor": "#eeffff",
|
||||
"tertiaryTextColor": "#eeffff",
|
||||
"primaryBorderColor": "#eeffff",
|
||||
"lineColor": "#eeffff",
|
||||
"textColor": "#eeffff",
|
||||
"actorTextColor": "#eeffff",
|
||||
"actorBorder": "#eeffff",
|
||||
"signalColor": "#eeffff",
|
||||
"signalTextColor": "#eeffff",
|
||||
"labelTextColor": "#eeffff",
|
||||
"loopTextColor": "#eeffff",
|
||||
"noteTextColor": "#eeffff",
|
||||
"noteBorderColor": "#eeffff",
|
||||
"sectionTextColor": "#eeffff",
|
||||
"titleColor": "#eeffff"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Mermaid diagram template
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant a as Alice
|
||||
participant b as Bob
|
||||
a->>b: Hello
|
||||
b-->>a: Hi back
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Query the Emacs foreground color once per session and reuse it for all subsequent diagrams. Only query again if the color is not already known.
|
||||
- Query the Emacs background mode once per session via `(frame-parameter nil 'background-mode)`. Use `-t dark` for `dark` or `-t default` for `light`. Always use `-b transparent --scale 2`.
|
||||
- Always use `PUPPETEER_EXECUTABLE_PATH=/opt/homebrew/bin/chromium` when invoking `mmdc`.
|
||||
- Always write a JSON config file with `themeVariables` set to the queried foreground color and pass it via `--configFile`.
|
||||
- Always use a timestamp in the filename (e.g., `/tmp/agent-diagram-$(date +%s).png`). Never use descriptive names.
|
||||
- After mmdc runs successfully, output a markdown image (``) on its own line.
|
||||
- Choose an appropriate diagram type for the data (sequence, flowchart, class, state, er, gantt, etc.).
|
||||
- Include a title when it adds clarity.
|
||||
- If no diagrammable data exists in the recent context, inform the user.
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
name: open
|
||||
description: 'This skill should be used when the user invokes "/open" to open files from the latest interaction in Emacs buffers via emacsclient.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Open files in Emacs
|
||||
|
||||
Open files from the most recent interaction in Emacs buffers using `emacsclient --eval`. Only include files relevant to the latest interaction (files just generated, edited, listed, or produced by the most recent tool output), not all files mentioned throughout the conversation.
|
||||
|
||||
## How to open
|
||||
|
||||
First, locate `agent-skill-open.el` which lives alongside this skill file at `skills/open/agent-skill-open.el` in the emacs-skills plugin directory.
|
||||
|
||||
Each file spec in `:files` is either a string (file path) or a plist with `:file` and optional `:line`.
|
||||
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(progn
|
||||
(load "/path/to/skills/open/agent-skill-open.el" nil t)
|
||||
(agent-skill-open
|
||||
:files (quote ((:file "/path/to/file1.txt"
|
||||
:line 42)
|
||||
"/path/to/file2.txt"
|
||||
"/path/to/file3.txt"))))'
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Use absolute paths for files.
|
||||
- Use `:line` when a specific line is relevant (e.g., an error location or a newly added function).
|
||||
- Locate `agent-skill-open.el` relative to this skill file's directory.
|
||||
- If no relevant files exist in the recent interaction, inform the user.
|
||||
- Run the `emacsclient --eval` command via the Bash tool.
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
(require 'cl-lib)
|
||||
|
||||
(cl-defun agent-skill-open (&key files)
|
||||
"Open FILES in Emacs buffers.
|
||||
|
||||
FILES is a list of file specs. Each spec is either a string
|
||||
\(file path) or a plist (:file PATH :line LINE)."
|
||||
(dolist (spec files)
|
||||
(if (stringp spec)
|
||||
(find-file spec)
|
||||
(let ((file (plist-get spec :file))
|
||||
(line (plist-get spec :line)))
|
||||
(find-file file)
|
||||
(when line
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- line)))))))
|
||||
|
||||
(provide 'agent-skill-open)
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
name: plantuml
|
||||
description: 'This skill should be used when the user invokes "/plantuml" to create a diagram from the current context using PlantUML and output the resulting image path.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Create diagrams with PlantUML
|
||||
|
||||
Create a diagram from the most recent interaction context using PlantUML. Generate a PNG image with a transparent background and output it as a markdown image so it renders inline.
|
||||
|
||||
## How to create a diagram
|
||||
|
||||
1. Extract or derive diagrammable data from the current context.
|
||||
2. If the Emacs foreground color is not already known from a previous diagram in this session, query it:
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(face-foreground (quote default))'
|
||||
```
|
||||
This returns a hex color like `"#eeffff"`. Reuse it for all subsequent diagrams.
|
||||
3. Write a PlantUML file to a temporary file using that color.
|
||||
4. Run PlantUML on the file.
|
||||
5. Output the result as a markdown image on its own line:
|
||||
```
|
||||

|
||||
```
|
||||
|
||||
```sh
|
||||
plantuml -tpng /tmp/agent-diagram-XXXX.puml
|
||||
```
|
||||
|
||||
## PlantUML template
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
skinparam backgroundColor transparent
|
||||
skinparam shadowing true
|
||||
skinparam roundcorner 10
|
||||
skinparam defaultFontName "Helvetica"
|
||||
skinparam defaultFontColor #eeffff
|
||||
|
||||
' Set foreground color on all element types
|
||||
skinparam titleFontColor #eeffff
|
||||
skinparam sequenceLifeLineBorderColor #eeffff
|
||||
skinparam sequenceArrowColor #eeffff
|
||||
skinparam sequenceGroupHeaderFontColor #eeffff
|
||||
skinparam sequenceGroupBorderColor #eeffff
|
||||
skinparam sequenceDividerFontColor #eeffff
|
||||
skinparam sequenceDividerBorderColor #eeffff
|
||||
skinparam actorBorderColor #eeffff
|
||||
skinparam actorFontColor #eeffff
|
||||
skinparam participantFontColor #eeffff
|
||||
skinparam participantBorderColor #eeffff
|
||||
skinparam collectionsFontColor #eeffff
|
||||
skinparam collectionsBorderColor #eeffff
|
||||
skinparam noteFontColor #eeffff
|
||||
skinparam noteBorderColor #eeffff
|
||||
skinparam arrowFontColor #eeffff
|
||||
skinparam classFontColor #eeffff
|
||||
skinparam classBorderColor #eeffff
|
||||
skinparam classAttributeFontColor #eeffff
|
||||
skinparam packageFontColor #eeffff
|
||||
skinparam packageBorderColor #eeffff
|
||||
skinparam componentFontColor #eeffff
|
||||
skinparam componentBorderColor #eeffff
|
||||
skinparam interfaceFontColor #eeffff
|
||||
skinparam interfaceBorderColor #eeffff
|
||||
|
||||
' ... diagram content ...
|
||||
@enduml
|
||||
```
|
||||
|
||||
## Rules
|
||||
|
||||
- Query the Emacs foreground color once per session and reuse it for all subsequent diagrams. Only query again if the color is not already known.
|
||||
- Always use `skinparam backgroundColor transparent` for transparent background.
|
||||
- Always use a timestamp in the filename (e.g., `/tmp/agent-diagram-$(date +%s).png`). Never use descriptive names.
|
||||
- Set the queried foreground color on `defaultFontColor` and all relevant `skinparam` entries for borders, arrows, and text so the diagram is readable on the user's Emacs background.
|
||||
- After PlantUML runs successfully, output a markdown image (``) on its own line.
|
||||
- Choose an appropriate diagram type for the data (sequence, class, component, activity, state, etc.).
|
||||
- Include a title when it adds clarity.
|
||||
- If no diagrammable data exists in the recent context, inform the user.
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
---
|
||||
name: select
|
||||
description: 'This skill should be used when the user invokes "/select" to open one or more files in Emacs and select a region relevant to the current discussion via emacsclient.'
|
||||
tools: Bash
|
||||
disable-model-invocation: true
|
||||
---
|
||||
|
||||
# Select region in Emacs
|
||||
|
||||
Open one or more files in Emacs and select (activate the region around) the code or text most relevant to the current discussion using `emacsclient --eval`. This allows the user to immediately act on the selection: narrow, copy, refactor, comment, etc.
|
||||
|
||||
Determine the relevant files and line ranges from the most recent interaction context.
|
||||
|
||||
## How to select
|
||||
|
||||
First, locate `agent-skill-select.el` which lives alongside this skill file at `skills/select/agent-skill-select.el` in the emacs-skills plugin directory.
|
||||
|
||||
```sh
|
||||
emacsclient --eval '
|
||||
(progn
|
||||
(load "/path/to/skills/select/agent-skill-select.el" nil t)
|
||||
(agent-skill-select
|
||||
:selections (quote (("/path/to/file1.el"
|
||||
:start 10
|
||||
:end 25)
|
||||
("/path/to/file2.el"
|
||||
:start 5
|
||||
:end 12)))))'
|
||||
```
|
||||
|
||||
- `:start` is the 1-indexed start line.
|
||||
- `:end` is the 1-indexed end line.
|
||||
- The last file visited will have the visually active region. Other files have mark and point set (use `C-x C-x` to reactivate when switching to them).
|
||||
|
||||
## Rules
|
||||
|
||||
- Use absolute paths for files.
|
||||
- Choose the region most relevant to the current discussion (e.g., a function just modified, a block with an error, code just generated).
|
||||
- If no specific region is apparent, select the entire relevant function or block.
|
||||
- Locate `agent-skill-select.el` relative to this skill file's directory.
|
||||
- If no relevant files or regions exist in the recent interaction, inform the user.
|
||||
- Run the `emacsclient --eval` command via the Bash tool.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
(require 'cl-lib)
|
||||
|
||||
(cl-defun agent-skill-select (&key selections)
|
||||
"Open files in Emacs and select a region in each.
|
||||
|
||||
SELECTIONS is a list of (FILE :start LINE :end LINE)."
|
||||
(dolist (sel selections)
|
||||
(let ((file (car sel))
|
||||
(start (plist-get (cdr sel) :start))
|
||||
(end (plist-get (cdr sel) :end)))
|
||||
(find-file file)
|
||||
(goto-char (point-min))
|
||||
(forward-line (1- start))
|
||||
(set-mark (point))
|
||||
(forward-line (- end start))
|
||||
(end-of-line)
|
||||
(activate-mark))))
|
||||
|
||||
(provide 'agent-skill-select)
|
||||
Loading…
Reference in New Issue