diff --git a/modules/home/ai-agent/skills/managing-system-configuration/SKILL.md b/modules/home/ai-agent/skills/managing-system-configuration/SKILL.md new file mode 100644 index 0000000..fbabd71 --- /dev/null +++ b/modules/home/ai-agent/skills/managing-system-configuration/SKILL.md @@ -0,0 +1,58 @@ +--- +name: managing-system-configuration +description: "Routes operating-system, user-environment, installed-application, service, and application-configuration changes through ~/infra, then activates them with the appropriate NixOS, nix-darwin, or Home Manager command. Use when the user asks to install, remove, or configure system software; change shell, editor, desktop, or application settings; manage a service; or make another OS-level change on a managed machine. Do not use for project-local dependencies or repository configuration." +--- + +# Managing System Configuration + +Treat `~/infra` as the source of truth for system and user configuration. Do not use `apt`, `brew`, global language package managers, or generated local configuration files unless the user explicitly asks to bypass the managed configuration. + +## Start the change + +1. Change to `~/infra` before inspecting or modifying configuration. +2. Follow the `using-jujutsu` repository check before any version-control command. +3. Fetch the remote and start a described change from the remote main bookmark: + +```bash +cd "$HOME/infra" +jj git fetch +jj new main@origin -m "" +``` + +Do not use Git commands in this repository. Starting a new change preserves any previous working-copy commit, so do not rewrite or discard it. + +## Make the change + +Find the existing host, profile, or reusable module that owns the setting. Extend existing abstractions and patterns before adding a new module. Configure applications through Home Manager, NixOS, or nix-darwin rather than editing files in the home directory directly. + +Keep host-specific settings in the matching host configuration and reusable behavior in `modules/home` or `modules/system`. Use the smallest scope that represents the setting accurately. + +## Activate the change + +Identify the current hostname and find its output in `flake.nix`. Use exactly one matching activation path: + +- Host in `nixosConfigurations`: `sudo nixos-rebuild switch --flake ".#"` +- Host in `darwinConfigurations`: `darwin-rebuild switch --flake ".#"` +- User and host in `homeConfigurations`: `home-manager switch --flake ".#@"` + +Prefer the NixOS or nix-darwin output when Home Manager is integrated into that system configuration. Use standalone Home Manager only when the machine has a matching `homeConfigurations` output. + +Run the activation command after editing; do not stop after changing the files. If activation fails, diagnose and correct the managed configuration, then retry the same activation path. Do not fall back to an imperative installation or local configuration workaround. + +## Commit and publish + +The working copy created by `jj new` is already the Jujutsu commit. After a successful switch, review the final diff and ensure the description accurately summarizes it, then publish it: + +```bash +jj status +jj diff --stat +jj describe -m "" +commit_id=$(jj log -r @ --no-graph -T 'commit_id') +jj bookmark set main -r @ +jj git push +jj new +``` + +Do not push before activation succeeds. If the push is rejected because the remote advanced, do not force-push. Fetch, rebase the change onto `main@origin`, resolve any conflicts, repeat activation if the content changed, and push again. + +After the push succeeds, return a concise Markdown link to `https://tangled.org/bates64.com/infra/commit/`. Do not summarize the change or report which output was activated; the user can inspect the commit through the link. diff --git a/modules/home/ai-agent/skills/reading-source-code/SKILL.md b/modules/home/ai-agent/skills/reading-source-code/SKILL.md index d0256b3..7411643 100644 --- a/modules/home/ai-agent/skills/reading-source-code/SKILL.md +++ b/modules/home/ai-agent/skills/reading-source-code/SKILL.md @@ -1,12 +1,6 @@ --- name: reading-source-code -description: "Shallow-clones library source code into a tmpdir when documentation is unavailable or blocked. Use when WebFetch fails (bot protection, 403/429 errors), when docs are insufficient, or when you need to understand a library's internals." -allowed-tools: - - "Bash(git clone --depth 1 *)" - - "Bash(mktemp -d *)" - - "Bash(rm -rf /tmp/tmp.*)" -context: fork -agent: Explore +description: "Shallow-clones library source code into a temporary directory when documentation is unavailable, blocked, or insufficient. Use when documentation retrieval fails with errors such as 403 or 429, or when a task requires understanding a library's internals." --- # Reading Source Code @@ -15,8 +9,8 @@ When you can't find or access documentation for a library (e.g. the website reje ## When to use -- WebFetch returns an error or useless content (bot protection, paywall, Cloudflare challenge) -- Context7 has no results for the library +- Documentation retrieval returns an error or useless content, such as bot protection, a paywall, or a Cloudflare challenge +- Available documentation sources have no results for the library - You need to understand internals that aren't covered by docs - The library is small or niche and has no dedicated documentation site @@ -27,7 +21,7 @@ CLONE_DIR=$(mktemp -d) git clone --depth 1 https://github.com/owner/repo.git "$CLONE_DIR/repo" ``` -Then use Read, Grep, and Glob to explore the cloned source. +Then use the available file-reading and search tools to explore the cloned source. ## Cleanup diff --git a/modules/home/ai-agent/skills/resolving-issue-refs/SKILL.md b/modules/home/ai-agent/skills/resolving-issue-refs/SKILL.md index 936642f..ae27405 100644 --- a/modules/home/ai-agent/skills/resolving-issue-refs/SKILL.md +++ b/modules/home/ai-agent/skills/resolving-issue-refs/SKILL.md @@ -14,10 +14,14 @@ When you see `#N` (e.g. `#1`, `#42`) or `owner/repo#N`, resolve it by detecting ## Step 1: Detect the forge -Check git remotes to determine the hosting platform: +Check for a `.jj/` directory before inspecting remotes, as described by the `using-jujutsu` skill. Use the command that matches the repository type: ```bash -git remote -v 2>/dev/null || jj git remote list 2>/dev/null +# Jujutsu repository +jj git remote list + +# Git repository +git remote -v ``` **GitHub** remotes look like: @@ -48,15 +52,13 @@ If `gh issue view` returns "not found", try `gh pr view` and vice versa. ### Tangled -Extract OWNER and REPO from the remote URL, then use WebFetch. Try PRs first: -``` -WebFetch: https://tangled.org/OWNER/REPO/pulls/N -``` +Extract OWNER and REPO from the remote URL, then retrieve the web page with the available HTTP or web tool. Try PRs first: + +`https://tangled.org/OWNER/REPO/pulls/N` If that's not found, try issues: -``` -WebFetch: https://tangled.org/OWNER/REPO/issues/N -``` + +`https://tangled.org/OWNER/REPO/issues/N` For deeper data (individual comments, AT Protocol records), see the `using-tangled` skill. @@ -64,4 +66,4 @@ For deeper data (individual comments, AT Protocol records), see the `using-tangl For `owner/repo#N`, the owner/repo tells you where to look directly — you don't need to check the current repo's remotes. Determine the forge from context: - If `owner/repo` looks like a GitHub path (e.g. `bates64/star-rod`), use `gh issue view N -R owner/repo` -- If `owner/repo` looks like a tangled path (e.g. `starhaven.dev/rfcs`), use WebFetch on `https://tangled.org/owner/repo/pulls/N` +- If `owner/repo` looks like a Tangled path (e.g. `starhaven.dev/rfcs`), retrieve `https://tangled.org/owner/repo/pulls/N` with the available HTTP or web tool diff --git a/modules/home/ai-agent/skills/reviewing-changes/SKILL.md b/modules/home/ai-agent/skills/reviewing-changes/SKILL.md index 8ec5d87..22f3ae1 100644 --- a/modules/home/ai-agent/skills/reviewing-changes/SKILL.md +++ b/modules/home/ai-agent/skills/reviewing-changes/SKILL.md @@ -1,9 +1,6 @@ --- name: reviewing-changes description: "Reviews commits for issues. Reports problems but does not fix them. Use after finishing implementation." -argument-hint: "[revset]" -context: fork -agent: general-purpose --- # Reviewing Changes @@ -13,29 +10,23 @@ Review changes and report issues. Do not fix anything - just identify problems. ## Scope -Commits to review: +Use the revset requested by the user. If none was supplied, review `@`: ```bash -jj log -r "${ARGUMENTS:-@}" +jj log -r '' ``` ## For each commit -Edit into the commit to review it in context: +List the changed files, inspect the diff, and read each changed file at that revision in full. Reviewing the diff alone misses surrounding context: ```bash -jj edit +jj diff --stat -r +jj diff -r +jj file show -r ``` -List changed files and read them in full - reviewing the diff alone misses surrounding context: - -```bash -jj diff --stat -r @ -``` - -Then read each changed file to understand the changes within their full context. - -**Formatting:** if the project specifies an autoformatter (e.g. `nix fmt`, `cargo fmt`, `prettier`), run it. Check the diff with `jj diff` - if the formatter changed anything, note it. +**Formatting:** if the project specifies an autoformatter with a check-only mode, run it and report failures. Do not run a formatter that modifies files during a review. **Linting:** if the project has a linter (e.g. `cargo clippy`, `eslint`, `ruff`), run it and note any warnings. @@ -64,12 +55,6 @@ Then read each changed file to understand the changes within their full context. - Are there types/abstractions that have grown beyond their original purpose and should be split? - Are any abstractions redundant or overly complex? -## Return to original commit - -```bash -!`jj log -r @ --no-graph -T '"jj edit " ++ change_id' 2>/dev/null` -``` - ## Output Return a structured list of issues by priority: @@ -79,4 +64,3 @@ Return a structured list of issues by priority: 3. **Suggestions** (consider improving) If no issues found, say so. - diff --git a/modules/home/ai-agent/skills/reviewing-skills/SKILL.md b/modules/home/ai-agent/skills/reviewing-skills/SKILL.md index f8447f6..5ef14d5 100644 --- a/modules/home/ai-agent/skills/reviewing-skills/SKILL.md +++ b/modules/home/ai-agent/skills/reviewing-skills/SKILL.md @@ -1,20 +1,21 @@ --- name: reviewing-skills -description: "Reviews Claude Code skills against authoring best practices. Use when creating, editing, or reviewing a SKILL.md file." +description: "Reviews portable Agent Skills against the shared specification and authoring best practices. Use when creating, editing, or reviewing a SKILL.md file intended for more than one agent implementation." --- # Reviewing Skills -When writing or editing a skill, review it against these guidelines. Fetch the latest best practices from https://platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices before reviewing — do not rely on cached knowledge. +When writing or editing a skill, fetch the latest shared specification from https://agentskills.io/specification before reviewing. Do not rely on cached knowledge or implementation-specific extensions. ## Checklist ### Metadata -- [ ] `name`: lowercase, hyphens only, max 64 chars, gerund form preferred (e.g. `processing-pdfs`) +- [ ] `name`: matches its directory; uses lowercase letters, numbers, and single hyphens; max 64 characters - [ ] `description`: third person, includes what it does AND when to use it, max 1024 chars +- [ ] Frontmatter uses fields from the shared specification; avoid experimental or implementation-specific fields unless compatibility requires them ### Conciseness -- [ ] Only adds context Claude doesn't already have +- [ ] Only adds context a capable coding agent would not already have - [ ] Each paragraph justifies its token cost - [ ] Body under 500 lines; split into separate files if approaching limit @@ -23,6 +24,8 @@ When writing or editing a skill, review it against these guidelines. Fetch the l - [ ] Consistent terminology (one term per concept) - [ ] File references at most one level deep from SKILL.md - [ ] Interactive commands flagged — agent should not run them +- [ ] Instructions describe capabilities rather than implementation-specific tool names +- [ ] Commands use ordinary shell syntax rather than agent-specific interpolation or slash-command syntax ### Freedom level - [ ] High freedom for subjective/context-dependent tasks diff --git a/modules/home/ai-agent/skills/using-jujutsu/SKILL.md b/modules/home/ai-agent/skills/using-jujutsu/SKILL.md index ab62230..d17f453 100644 --- a/modules/home/ai-agent/skills/using-jujutsu/SKILL.md +++ b/modules/home/ai-agent/skills/using-jujutsu/SKILL.md @@ -1,13 +1,31 @@ --- name: using-jujutsu -description: "Provides jujutsu (jj) workflow patterns and best practices for version control. IMPORTANT: Must be invoked BEFORE running any version control commands when the working directory contains a .jj/ directory. jj repos also have a .git/ directory (jj uses git as a backend), so the system gitStatus showing git info does NOT mean git commands should be used. When in doubt, check for .jj/ first." -allowed-tools: - - "Bash(jj *)" +description: "Provides Jujutsu (jj) workflow patterns and best practices for version control. Use before running any git, jj, or other version-control command. First check the current directory and its parents for a .jj/ directory; if one exists, use jj exclusively because Jujutsu repositories also contain .git/. Repeat the check after changing directories or worktrees." --- # Using Jujutsu (jj) -When the working directory is a jj repo (has a `.jj/` directory), use `jj` commands instead of `git`. **NEVER run `git` commands in a jj repo** — not even `git status`, `git log`, or `git diff`. Always use the jj equivalent. +## Mandatory repository check + +Before running any version-control command, check the current directory and every parent directory for `.jj/`. This check must be the first repository-related command; do not start with `git status`, `git log`, or another Git command. + +```bash +repo_dir=$PWD +while [ ! -d "$repo_dir/.jj" ] && [ "$repo_dir" != / ]; do + repo_dir=${repo_dir%/*} + [ -n "$repo_dir" ] || repo_dir=/ +done + +if [ -d "$repo_dir/.jj" ]; then + printf 'jujutsu\n' +else + printf 'not-jujutsu\n' +fi +``` + +Run the check from the command's working directory. Repeat it whenever you change directories, switch worktrees, or begin operating on a different repository. + +If the result is `jujutsu`, use `jj` commands exclusively. **NEVER run `git` commands in a Jujutsu repository** -- not even `git status`, `git log`, or `git diff`. A `.git/` directory or Git status supplied by the environment does not prove that Git commands are appropriate because Jujutsu uses Git as a backend. ## Core Mental Model diff --git a/modules/home/ai-agent/skills/using-nix/SKILL.md b/modules/home/ai-agent/skills/using-nix/SKILL.md new file mode 100644 index 0000000..bfa47b5 --- /dev/null +++ b/modules/home/ai-agent/skills/using-nix/SKILL.md @@ -0,0 +1,68 @@ +--- +name: using-nix +description: "Applies shared Nix development conventions for entering development shells, scaffolding flakes, formatting Nix, and exposing project commands. Use when working with flake.nix, devShells, direnv, flake-parts, Nix formatting, project setup, or reproducible development dependencies in any repository." +--- + +# Using Nix + +Follow the repository's existing Nix, direnv, and command-runner conventions before applying these defaults. + +## Enter the development environment + +Inspect the nearest `.envrc` and `flake.nix` before running project tools. + +- If direnv has already activated an `.envrc` containing `use flake`, use the current environment. Do not nest another `nix develop` shell. +- If the flake provides a development shell and it is not active, run commands through `nix develop`, preferably as `nix develop -c ` for non-interactive work. +- If an `.envrc` contains `use flake` but is not trusted, run `direnv allow` in that directory before using it. + +Do not install a project tool globally when it belongs in the development shell. + +## Scaffold a flake + +Use `flake-parts` for a new flake unless the project already follows another structure. Keep the initial flake small: + +```nix +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + }; + + outputs = inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ "" ]; + perSystem = { pkgs, ... }: { + formatter = pkgs.nixfmt; + devShells.default = pkgs.mkShell { + packages = with pkgs; [ just ]; + }; + }; + }; +} +``` + +Choose only the systems the project supports. Add project tools to `devShells.default` and replace placeholders before validation. + +Create `.envrc` with: + +```bash +use flake +``` + +Then run `direnv allow` in the project directory. + +## Format and validate + +Use `nixpkgs#nixfmt` as the Nix formatter: + +```bash +nix run nixpkgs#nixfmt -- +``` + +When the flake exposes `formatter = pkgs.nixfmt`, `nix fmt` is also appropriate. Run `nix flake check` after changing flake structure or outputs. + +## Expose common commands + +Use a `justfile` for repeated build, test, run, lint, and formatting commands. Include `just` in the development shell when the project depends on it. + +Keep command implementations in recipes rather than duplicating a command catalog in the README. Use the README for context, prerequisites, and concepts; let `just --list` provide command discovery. diff --git a/modules/home/ai-agent/skills/using-tangled/SKILL.md b/modules/home/ai-agent/skills/using-tangled/SKILL.md index ad08e0f..799b45e 100644 --- a/modules/home/ai-agent/skills/using-tangled/SKILL.md +++ b/modules/home/ai-agent/skills/using-tangled/SKILL.md @@ -26,13 +26,13 @@ The pattern is `git@knot*.DOMAIN:OWNER/REPO`. The web URL is `https://tangled.or Tangled has no unified REST API. Data is stored as AT Protocol records across users' PDS instances. Use this workflow: -### Quickest approach: WebFetch the HTML page +### Quickest approach: retrieve the HTML page -For reading a PR or issue, the simplest method is to use WebFetch on the tangled.org URL: +For reading a PR or issue, retrieve the Tangled page with the available HTTP or web tool: ``` -WebFetch: https://tangled.org/OWNER/REPO/pulls/N -WebFetch: https://tangled.org/OWNER/REPO/pulls/N/round/0 -WebFetch: https://tangled.org/OWNER/REPO/issues/N +https://tangled.org/OWNER/REPO/pulls/N +https://tangled.org/OWNER/REPO/pulls/N/round/0 +https://tangled.org/OWNER/REPO/issues/N ``` ### Programmatic approach: AT Protocol records @@ -101,7 +101,7 @@ Records are under `.records[].value`. The `.uri` is the AT-URI for that record. ### Important: decentralised data Records are stored in the *author's* PDS, not the repo owner's. A comment by user X on repo Y is in X's PDS. To find all comments on a PR, you need to either: -1. WebFetch the tangled.org HTML page (easiest) +1. Retrieve the tangled.org HTML page with the available HTTP or web tool 2. Know all participants' DIDs and query each PDS ### Referencing a PR or issue from a tangled.org URL