From 7f16c98bdc95ebbbd59130eecf65233fda3ea86c Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Tue, 17 Feb 2026 08:22:30 +0200 Subject: Convert commands and context to skills, add skills symlinks to Rexfile Move purge-file-from-git, compose-blog-post, increment-version-and-push from commands to skills format, and convert go-best-practices from context to a skill. Update Rexfile home_prompts task to symlink both commands and skills directories for cursor, claude, agents, and opencode. Co-Authored-By: Claude Opus 4.6 --- Rexfile | 21 +++--- prompts/commands/compose-blog-post.md | 18 ----- prompts/commands/increment-version-and-push.md | 3 - prompts/commands/purge-file-from-git.md | 53 -------------- prompts/context/go-best-practices.md | 85 ---------------------- prompts/skills/compose-blog-post/SKILL.md | 29 ++++++++ prompts/skills/foo-summarizer/SKILL.md | 16 ++++ prompts/skills/go-best-practices/SKILL.md | 81 +++++++++++++++++++++ prompts/skills/increment-version-and-push/SKILL.md | 21 ++++++ prompts/skills/purge-file-from-git/SKILL.md | 52 +++++++++++++ 10 files changed, 210 insertions(+), 169 deletions(-) delete mode 100644 prompts/commands/compose-blog-post.md delete mode 100644 prompts/commands/increment-version-and-push.md delete mode 100644 prompts/commands/purge-file-from-git.md delete mode 100644 prompts/context/go-best-practices.md create mode 100644 prompts/skills/compose-blog-post/SKILL.md create mode 100644 prompts/skills/foo-summarizer/SKILL.md create mode 100644 prompts/skills/go-best-practices/SKILL.md create mode 100644 prompts/skills/increment-version-and-push/SKILL.md create mode 100644 prompts/skills/purge-file-from-git/SKILL.md diff --git a/Rexfile b/Rexfile index 2c85049..c29bcea 100644 --- a/Rexfile +++ b/Rexfile @@ -145,23 +145,24 @@ task 'home_helix', sub { ensure "$DOT/helix/*" => "$HOME/.config/helix/" }; desc 'Install ~/.config/ghostty'; task 'home_ghostty', sub { ensure "$DOT/ghostty/*" => "$HOME/.config/ghostty/" }; -desc 'Install promps links for AI tools'; +desc 'Install prompt links for AI tools'; task 'home_prompts', sub { if ( -d "$HOME/Notes/Prompts/commands" ) { Rex::Logger::info("Installing prompt links"); - # Install to ~/.cursor/commands/ for Cursor - file "$HOME/.cursor" => ensure => 'directory', mode => '0750'; - symlink "$HOME/Notes/Prompts/commands" => "$HOME/.cursor/commands" or die "Could not create symlink: $!"; + my @tool_dirs = ( '.cursor', '.claude', '.agents', '.opencode' ); - file "$HOME/.claude" => ensure => 'directory', mode => '0750'; - symlink "$HOME/Notes/Prompts/commands" => "$HOME/.claude/commands" or die "Could not create symlink: $!"; + for my $tool_dir (@tool_dirs) { + file "$HOME/$tool_dir" => ensure => 'directory', mode => '0750'; - file "$HOME/.agents" => ensure => 'directory', mode => '0750'; - symlink "$HOME/Notes/Prompts/commands" => "$HOME/.agents/commands" or die "Could not create symlink: $!"; + # Symlink commands directory + symlink "$HOME/Notes/Prompts/commands" => "$HOME/$tool_dir/commands" + or die "Could not create commands symlink for $tool_dir: $!"; - file "$HOME/.opencode" => ensure => 'directory', mode => '0750'; - symlink "$HOME/Notes/Prompts/commands" => "$HOME/.opencode/commands" or die "Could not create symlink: $!"; + # Symlink skills directory + symlink "$HOME/Notes/Prompts/skills" => "$HOME/$tool_dir/skills" + or die "Could not create skills symlink for $tool_dir: $!"; + } } else { Rex::Logger::info("Not installing prompt links"); diff --git a/prompts/commands/compose-blog-post.md b/prompts/commands/compose-blog-post.md deleted file mode 100644 index 7af3d55..0000000 --- a/prompts/commands/compose-blog-post.md +++ /dev/null @@ -1,18 +0,0 @@ -# Compose blog post - -Compose a blog post in ~/git/foo.zone-content/gemtext/gemfeed/ in gemtext format. - -1. Read 2-3 recent blog posts from the gemfeed directory to match the existing style (title, published date, TOC, links, closing). -2. Use the filename format: `YYYY-MM-DD-slug.gmi.tpl` (ask for the date and slug if not specified). -3. Follow the gemtext conventions from existing posts: - - `# Title` as first line - - `> Published at` with ISO 8601 timestamp and timezone - - `<< template::inline::toc` after the intro paragraph - - `=> ./slug/image.ext Description` for images (create an asset directory named after the slug if images are needed) - - `=> URL Description` for external links - - Section headers with `##` and `###` - - Code blocks with triple backticks - - Closing with `E-Mail your comments to paul@nospam.buetow.org :-)` and related posts index - - `=> ../ Back to the main site` as the last line -4. Ask what the blog post should be about if no topic is given. -5. Show a preview before writing the file. diff --git a/prompts/commands/increment-version-and-push.md b/prompts/commands/increment-version-and-push.md deleted file mode 100644 index 015038b..0000000 --- a/prompts/commands/increment-version-and-push.md +++ /dev/null @@ -1,3 +0,0 @@ -# Increment version and push - -Increment the version of the project, tag it in git, commit, and push. For Go-based projects, look for the internal/version.go file. For bug fixes, increment only the minor version. We are using semantic versioning, e.g., x.y.z, where z is the minor version. For new features, increment y. Never increment x (the major version) unless specified. diff --git a/prompts/commands/purge-file-from-git.md b/prompts/commands/purge-file-from-git.md deleted file mode 100644 index 67736cc..0000000 --- a/prompts/commands/purge-file-from-git.md +++ /dev/null @@ -1,53 +0,0 @@ -# /purge-file-from-git - -**Description:** Completely remove a file from git history using git-filter-repo. This is a destructive operation that rewrites history and requires force-pushing. - -**Parameters:** -- file_path: The relative path to the file to purge from git history (e.g., "secrets.env", "large-file.bin", "./config/passwords.txt") - -**Example usage:** -- `/purge-file-from-git secrets.env` -- `/purge-file-from-git config/api-keys.json` -- `/purge-file-from-git data/large-dataset.csv` - ---- - -## Prompt - -I'll purge `{{file_path}}` from the entire git history. This is a **destructive operation** that will: - -1. **Rewrite all commits** in the repository's history -2. **Change commit hashes** for affected commits and their descendants -3. **Require a force-push** if already pushed to remote -4. **Potentially cause issues** for collaborators who have cloned the repo - -**Before proceeding, I need to confirm:** - -1. **Is this branch shared with others?** If so, they'll need to re-clone or carefully rebase after this operation. -2. **Have you pushed this branch to a remote?** If yes, you'll need to force-push afterward. -3. **Do you want to proceed with rewriting the git history?** - -Once confirmed, I will: - -### Process: - -1. **Verify prerequisites**: - - Check if `git-filter-repo` is installed (install if needed) - - Check current git status - -2. **Execute purge**: - - Clean any previous filter-repo state - - Use `git filter-repo --path {{file_path}} --invert-paths --force` - - Restore the origin remote (filter-repo removes it as a safety measure) - -3. **Ask about .gitignore**: - - Prompt: "Would you like to add `{{file_path}}` to .gitignore to prevent future accidental commits?" - - If yes: Add the file to .gitignore and commit the change - - If no: Skip this step - -4. **Provide next steps**: - - Explain how to force-push: `git push --force origin ` - - Warn about impact on collaborators - - Provide recovery instructions for team members - -Let me know if you want to proceed with purging `{{file_path}}` from git history. diff --git a/prompts/context/go-best-practices.md b/prompts/context/go-best-practices.md deleted file mode 100644 index b20f2f0..0000000 --- a/prompts/context/go-best-practices.md +++ /dev/null @@ -1,85 +0,0 @@ -# Go Best Practices - -Context for Go project structure, style, and conventions. Load with `/load-context go-best-practices`. - ---- - -## Semantics and receivers - -* Prefer value semantics over pointer semantics if feasible -* Have either pointer or value receivers, not both, for methods on a type - ---- - -## File layout and order - -* Constants, global variables, and type definitions always at the top of the file, before functions and methods -* Public functions and methods before private ones in the file -* Constructors must be the first functions in a file (before all methods), immediately after type definitions—even if non-public - ---- - -## Project structure - -* Binary is in `./cmd/NAME/main.go` -* Main file should be fairly small: argument/flags parsing and calling functions from the internal package only -* Internal code is in `./internal` -* Version of the app is a constant in `./internal/version.go`; a `-version` flag in main.go prints it out - ---- - -## Dependencies and I/O - -* Avoid package-level variables unless absolutely necessary; prefer dependency injection -* Use `context.Context` as the first parameter for functions that may block, perform I/O, or be canceled -* Use `defer` to close resources (files, connections) as soon as they are opened - ---- - -## Errors and interfaces - -* Use error wrapping (`fmt.Errorf` with `%w`) to provide context for errors -* Prefer explicit interface satisfaction for public types: `var _ MyInterface = (*MyType)(nil)` -* Keep interfaces small and focused; accept interfaces, return concrete types - ---- - -## Formatting and documentation - -* Use `gofmt` and `goimports` to enforce formatting and import order -* Document all exported identifiers with comments starting with the identifier's name -* Avoid stutter in package and type names (e.g. `foo.FooType` → `foo.Type`) - ---- - -## Naming and constants - -* Short variable names for short-lived variables, longer names for longer-lived ones -* Use `iota` for related constant values - ---- - -## Testing and robustness - -* Use table-driven tests for unit testing -* Aim for unit test coverage of 60% -* Avoid `panic` except for truly unrecoverable errors (e.g. programmer errors) -* Avoid large functions; split into smaller, focused helpers (max ~50 lines per function) -* Avoid code duplication where reasonable - ---- - -## Build system - -Use Mage (Magefile.go) for build, install and test targets (and deinstall/uninstall when needed). - -### Magefile.go structure - -* **Build tag and package:** `//go:build mage` at top; `package main`. Brief comment describing the project and that targets follow the same style as other projects (e.g. hexai) if applicable. -* **Imports:** `github.com/magefile/mage/mg`, `github.com/magefile/mage/sh`; plus stdlib as needed (`fmt`, `os`, `path/filepath`). -* **Constants:** Define `binaryName` (or equivalent) for the built binary. -* **Default target:** `Default()` calls `mg.Deps(Build)` so `mage` with no args builds. -* **Build:** `Build()` runs `go build -o ./cmd/` via `sh.RunV`. -* **Test:** `Test()` runs `go test ./...` via `sh.RunV`. -* **Install:** `Install()` depends on `Build` via `mg.Deps(Build)`; resolves GOPATH (default `~/go` when unset); ensures `GOPATH/bin` exists with `os.MkdirAll`; copies the binary there with `cp -v`. Use `fmt.Errorf` with `%w` for errors (e.g. resolving home). -* **Other targets:** Add Uninstall/Deinstall or custom targets as needed; keep the same style (mg.Deps for ordering, sh.RunV for external commands). diff --git a/prompts/skills/compose-blog-post/SKILL.md b/prompts/skills/compose-blog-post/SKILL.md new file mode 100644 index 0000000..1fc60a7 --- /dev/null +++ b/prompts/skills/compose-blog-post/SKILL.md @@ -0,0 +1,29 @@ +--- +name: compose-blog-post +description: Compose a blog post in gemtext format for foo.zone. +--- + +# Compose blog post + +Compose a blog post in ~/git/foo.zone-content/gemtext/gemfeed/ in gemtext format. + +## When to Use + +- Use this skill when the user wants to write or draft a new blog post for foo.zone. + +## Instructions + +1. Read 2-3 recent blog posts from the gemfeed directory to match the existing style (title, published date, TOC, links, closing). +2. Use the filename format: `YYYY-MM-DD-slug.gmi.tpl` (ask for the date and slug if not specified). +3. Follow the gemtext conventions from existing posts: + - `# Title` as first line + - `> Published at` with ISO 8601 timestamp and timezone + - `<< template::inline::toc` after the intro paragraph + - `=> ./slug/image.ext Description` for images (create an asset directory named after the slug if images are needed) + - `=> URL Description` for external links + - Section headers with `##` and `###` + - Code blocks with triple backticks + - Closing with `E-Mail your comments to paul@nospam.buetow.org :-)` and related posts index + - `=> ../ Back to the main site` as the last line +4. Ask what the blog post should be about if no topic is given. +5. Show a preview before writing the file. diff --git a/prompts/skills/foo-summarizer/SKILL.md b/prompts/skills/foo-summarizer/SKILL.md new file mode 100644 index 0000000..5c3fc1a --- /dev/null +++ b/prompts/skills/foo-summarizer/SKILL.md @@ -0,0 +1,16 @@ +--- +name: foo-summarizer +description: Summarize the last blog post on https://foo.zone in Bulgarian. +--- + +# Foo summarizer + +I want to summarize the latest blog post on https://foo.zone. + +## When to Use + +- Use this skill when i want the latest news in Bulgarian. + +## Instructions + +Go to https://foo.zone and check out the latest blog post and summarize it in Bulgarian. diff --git a/prompts/skills/go-best-practices/SKILL.md b/prompts/skills/go-best-practices/SKILL.md new file mode 100644 index 0000000..d5a8f19 --- /dev/null +++ b/prompts/skills/go-best-practices/SKILL.md @@ -0,0 +1,81 @@ +--- +name: go-best-practices +description: Enforce Go best practices for project structure, style, and conventions in the current codebase. +--- + +# Go Best Practices + +Enforce Go project structure, style, and conventions in the current codebase. + +## When to Use + +- Use this skill when working on a Go project to ensure the code follows the established best practices. +- Use this skill to review or refactor existing Go code for compliance. + +## Instructions + +When writing or modifying Go code in the current project, follow all of the conventions below. + +### Semantics and receivers + +* Prefer value semantics over pointer semantics if feasible +* Have either pointer or value receivers, not both, for methods on a type + +### File layout and order + +* Constants, global variables, and type definitions always at the top of the file, before functions and methods +* Public functions and methods before private ones in the file +* Constructors must be the first functions in a file (before all methods), immediately after type definitions—even if non-public + +### Project structure + +* Binary is in `./cmd/NAME/main.go` +* Main file should be fairly small: argument/flags parsing and calling functions from the internal package only +* Internal code is in `./internal` +* Version of the app is a constant in `./internal/version.go`; a `-version` flag in main.go prints it out + +### Dependencies and I/O + +* Avoid package-level variables unless absolutely necessary; prefer dependency injection +* Use `context.Context` as the first parameter for functions that may block, perform I/O, or be canceled +* Use `defer` to close resources (files, connections) as soon as they are opened + +### Errors and interfaces + +* Use error wrapping (`fmt.Errorf` with `%w`) to provide context for errors +* Prefer explicit interface satisfaction for public types: `var _ MyInterface = (*MyType)(nil)` +* Keep interfaces small and focused; accept interfaces, return concrete types + +### Formatting and documentation + +* Use `gofmt` and `goimports` to enforce formatting and import order +* Document all exported identifiers with comments starting with the identifier's name +* Avoid stutter in package and type names (e.g. `foo.FooType` → `foo.Type`) + +### Naming and constants + +* Short variable names for short-lived variables, longer names for longer-lived ones +* Use `iota` for related constant values + +### Testing and robustness + +* Use table-driven tests for unit testing +* Aim for unit test coverage of 60% +* Avoid `panic` except for truly unrecoverable errors (e.g. programmer errors) +* Avoid large functions; split into smaller, focused helpers (max ~50 lines per function) +* Avoid code duplication where reasonable + +### Build system + +Use Mage (Magefile.go) for build, install and test targets (and deinstall/uninstall when needed). + +#### Magefile.go structure + +* **Build tag and package:** `//go:build mage` at top; `package main`. Brief comment describing the project and that targets follow the same style as other projects (e.g. hexai) if applicable. +* **Imports:** `github.com/magefile/mage/mg`, `github.com/magefile/mage/sh`; plus stdlib as needed (`fmt`, `os`, `path/filepath`). +* **Constants:** Define `binaryName` (or equivalent) for the built binary. +* **Default target:** `Default()` calls `mg.Deps(Build)` so `mage` with no args builds. +* **Build:** `Build()` runs `go build -o ./cmd/` via `sh.RunV`. +* **Test:** `Test()` runs `go test ./...` via `sh.RunV`. +* **Install:** `Install()` depends on `Build` via `mg.Deps(Build)`; resolves GOPATH (default `~/go` when unset); ensures `GOPATH/bin` exists with `os.MkdirAll`; copies the binary there with `cp -v`. Use `fmt.Errorf` with `%w` for errors (e.g. resolving home). +* **Other targets:** Add Uninstall/Deinstall or custom targets as needed; keep the same style (mg.Deps for ordering, sh.RunV for external commands). diff --git a/prompts/skills/increment-version-and-push/SKILL.md b/prompts/skills/increment-version-and-push/SKILL.md new file mode 100644 index 0000000..81b8729 --- /dev/null +++ b/prompts/skills/increment-version-and-push/SKILL.md @@ -0,0 +1,21 @@ +--- +name: increment-version-and-push +description: Increment the project version, tag it in git, commit, and push. +--- + +# Increment version and push + +Increment the version of the project, tag it in git, commit, and push. + +## When to Use + +- Use this skill when the user wants to bump the version and release/push a project. + +## Instructions + +- For Go-based projects, look for the `internal/version.go` file. +- We use semantic versioning: `x.y.z`. + - For bug fixes, increment only `z` (the patch version). + - For new features, increment `y` (the minor version) and reset `z` to 0. + - Never increment `x` (the major version) unless explicitly specified. +- Commit the version change, create a git tag matching the new version, and push both the commit and the tag. diff --git a/prompts/skills/purge-file-from-git/SKILL.md b/prompts/skills/purge-file-from-git/SKILL.md new file mode 100644 index 0000000..e37ef90 --- /dev/null +++ b/prompts/skills/purge-file-from-git/SKILL.md @@ -0,0 +1,52 @@ +--- +name: purge-file-from-git +description: Completely remove a file from git history using git-filter-repo. +--- + +# Purge file from git + +Completely remove a file from git history using git-filter-repo. This is a destructive operation that rewrites history and requires force-pushing. + +## When to Use + +- Use this skill when a file needs to be completely purged from the entire git history (e.g., secrets, large binaries, sensitive data). + +## Instructions + +The user will provide a file path (e.g., "secrets.env", "large-file.bin", "config/passwords.txt"). + +I'll purge the specified file from the entire git history. This is a **destructive operation** that will: + +1. **Rewrite all commits** in the repository's history +2. **Change commit hashes** for affected commits and their descendants +3. **Require a force-push** if already pushed to remote +4. **Potentially cause issues** for collaborators who have cloned the repo + +**Before proceeding, confirm with the user:** + +1. **Is this branch shared with others?** If so, they'll need to re-clone or carefully rebase after this operation. +2. **Have you pushed this branch to a remote?** If yes, you'll need to force-push afterward. +3. **Do you want to proceed with rewriting the git history?** + +Once confirmed: + +### Process: + +1. **Verify prerequisites**: + - Check if `git-filter-repo` is installed (install if needed) + - Check current git status + +2. **Execute purge**: + - Clean any previous filter-repo state + - Use `git filter-repo --path --invert-paths --force` + - Restore the origin remote (filter-repo removes it as a safety measure) + +3. **Ask about .gitignore**: + - Prompt: "Would you like to add the file to .gitignore to prevent future accidental commits?" + - If yes: Add the file to .gitignore and commit the change + - If no: Skip this step + +4. **Provide next steps**: + - Explain how to force-push: `git push --force origin ` + - Warn about impact on collaborators + - Provide recovery instructions for team members -- cgit v1.2.3