From 0537ef99b9644e6a5850215fee5895bac2bca0d0 Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <3998+srid@users.noreply.github.com> Date: Mon, 16 Mar 2026 16:58:08 -0400 Subject: [PATCH] Migrate AI config to nixos-config, use nix-agent-wire (#107) - Move AI config from nix-agent-wire/srid to ./AI - Update flake input: srid/AI -> srid/nix-agent-wire - Update home modules to use local AI folder via flake.self.outPath --- AI/agents/pre-commit.md | 31 +++++++ AI/commands/gci.md | 105 +++++++++++++++++++++++ AI/commands/gh-settings.md | 58 +++++++++++++ AI/commands/plan.md | 123 +++++++++++++++++++++++++++ AI/commands/pr-review.md | 120 ++++++++++++++++++++++++++ AI/mcp/chrome-devtools.nix | 4 + AI/mcp/nixos-mcp.nix | 4 + AI/memory.md | 16 ++++ AI/settings/claude-code.nix | 8 ++ AI/skills/haskell/RELUDE.md | 68 +++++++++++++++ AI/skills/haskell/SKILL.md | 76 +++++++++++++++++ AI/skills/technical-writer/SKILL.md | 110 ++++++++++++++++++++++++ flake.lock | 38 ++++----- flake.nix | 2 +- modules/home/claude-code/default.nix | 7 +- modules/home/opencode/default.nix | 4 +- 16 files changed, 747 insertions(+), 27 deletions(-) create mode 100644 AI/agents/pre-commit.md create mode 100644 AI/commands/gci.md create mode 100644 AI/commands/gh-settings.md create mode 100644 AI/commands/plan.md create mode 100644 AI/commands/pr-review.md create mode 100644 AI/mcp/chrome-devtools.nix create mode 100644 AI/mcp/nixos-mcp.nix create mode 100644 AI/memory.md create mode 100644 AI/settings/claude-code.nix create mode 100644 AI/skills/haskell/RELUDE.md create mode 100644 AI/skills/haskell/SKILL.md create mode 100644 AI/skills/technical-writer/SKILL.md diff --git a/AI/agents/pre-commit.md b/AI/agents/pre-commit.md new file mode 100644 index 0000000..b955600 --- /dev/null +++ b/AI/agents/pre-commit.md @@ -0,0 +1,31 @@ +--- +name: pre-commit +description: Invoke after changing sources locally, and only if git-hooks.nix is used by Nix. +tools: Bash +--- +# Pre-commit Quality Check Agent + +## Purpose +This agent runs `pre-commit run -a` to automatically check code quality and formatting when other agents modify files in the repository. + +## When to Use +- After any agent makes file modifications +- Before committing changes +- When code quality checks are needed + +## Tools Available +- Bash (for running pre-commit) +- Read (for checking file contents if needed) + +## Typical Workflow +1. Run `pre-commit run -a` to check all files +2. Report any issues found +3. Suggest fixes if pre-commit hooks fail +4. Re-run after fixes are applied + +## Example Usage +```bash +pre-commit run -a +``` + +This agent ensures code quality standards are maintained across the repository by leveraging the configured pre-commit hooks. \ No newline at end of file diff --git a/AI/commands/gci.md b/AI/commands/gci.md new file mode 100644 index 0000000..51a27f3 --- /dev/null +++ b/AI/commands/gci.md @@ -0,0 +1,105 @@ +--- +description: Stage, commit, and push changes +subtask: true +--- + +# GCI Command + +Stage all changes, generate a commit message, commit, and push after user approval. + +## Usage + +``` +/gci # Normal mode - prompts for approval, then commits and pushes +/gci yes # Auto mode - commits and pushes without prompting +``` + +## Workflow + +1. **Stage All Changes** + - Run `git add -A` to stage all changes (new files, modifications, deletions) + +2. **Show Status and Generate Commit Message** + - Run `git status` to show what will be committed + - Analyze the staged changes using `git diff --cached` + - Generate a concise, descriptive commit message that: + - Summarizes WHAT changed in a single line (50-72 characters) + - If needed, adds a brief description of WHY in the body + - Uses imperative mood (e.g., "Add feature" not "Added feature") + - Follows conventional commit style if appropriate + +3. **Present to User for Approval** (skip if 'yes' argument provided) + - Display the generated commit message + - Show the `git status` output of what will be committed + - **Use the question tool** to ask for approval with options: + - "Commit" - proceed with the commit + - "Edit message" - user wants to modify the message (use custom option) + - "Cancel" - abort the commit + - **If 'yes' argument was provided**: Skip this step entirely and proceed directly to commit + +4. **Commit Changes** + - Once approved (or if 'yes' argument provided), run `git commit -m "MESSAGE"` (or `git commit -F -` with multi-line message) + - Report the commit hash and summary to the user + +5. **Push Changes** + - After successful commit, run `git push` to push to remote + - Report push status to user + +## Important Constraints + +- **NEVER auto-commit**: ALWAYS ask user for approval before running `git commit` - NEVER commit without explicit user confirmation (UNLESS the 'yes' argument is provided) +- **Single commit only**: This command creates exactly ONE new commit on top of the current branch +- **No history rewriting**: Never use `--amend`, `--fixup`, rebase, or reset operations +- **No other mutations**: The only git operations are `git commit` and `git push` + +## Requirements + +- Must be in a git repository +- There must be changes to commit (either unstaged or already staged) + +## Example Output Format + +### Normal Mode (`/gci`) +```markdown +Staged changes: +M src/app.ts +A src/utils/helper.ts +D old-file.js + +Proposed commit message: +Add helper utilities and refactor app + +Removes deprecated old-file.js and introduces new helper functions +for data validation. Updates app.ts to use the new utilities. + +[Uses question tool with options: Commit, Edit message, Cancel] +``` + +### Auto Mode (`/gci yes`) +```markdown +Staged changes: +M src/app.ts +A src/utils/helper.ts +D old-file.js + +Generated commit message: +Add helper utilities and refactor app + +Removes deprecated old-file.js and introduces new helper functions +for data validation. Updates app.ts to use the new utilities. + +Creating commit... +[master abc1234] Add helper utilities and refactor app + +Pushing to remote... +Done. Pushed to origin/master. +``` + +## Notes + +- Use the question tool for approval in normal mode - this provides a structured UI for the user +- If user selects "Edit message", use the question tool's custom option to let them type a new message +- If there are already staged changes, ask the user if they want to add unstaged changes too +- If there are no changes at all, inform the user and exit +- Keep the commit message clear and focused on the user-facing impact +- The default branch of the commit message should be concise (50-72 chars) diff --git a/AI/commands/gh-settings.md b/AI/commands/gh-settings.md new file mode 100644 index 0000000..b06d7c6 --- /dev/null +++ b/AI/commands/gh-settings.md @@ -0,0 +1,58 @@ +--- +description: Apply preferred GitHub repo settings +subtask: true +--- + +# GH Settings Command + +Apply preferred GitHub repository settings. + +## Usage + +``` +/gh-settings # Apply to current repo +/gh-settings owner/repo # Apply to specific repo +``` + +## Settings Applied + +1. **Squash merge format**: title=PR_TITLE, message=PR_BODY +2. **Disable**: wiki, projects, merge-commit +3. **Enable**: rebase-merge, squash-merge +4. **Enable**: allow-update-branch, delete-branch-on-merge + +## Workflow + +1. **Detect Repository** + - If argument provided: use `owner/repo` format + - If no argument: detect from `git remote get-url origin` + ```bash + git remote get-url origin | sed 's/.*github.com[/:]//' | sed 's/.git$//' + ``` + +2. **Apply Settings** + + Run both commands: + ```bash + # Set squash merge commit format + gh api --method PATCH repos/{owner}/{repo} -f squash_merge_commit_title=PR_TITLE -f squash_merge_commit_message=PR_BODY > /dev/null + + # Apply repository settings + gh repo edit --enable-wiki=false --enable-projects=false --enable-merge-commit=false --enable-rebase-merge --enable-squash-merge --allow-update-branch --delete-branch-on-merge + ``` + +3. **Confirm** + - Report success to user + - Show the repo that was updated + +## Requirements + +- `gh` CLI installed and authenticated (use `nix run nixpkgs#gh` if not installed) +- Must have admin access to the repository +- Repository must have a GitHub remote (for auto-detection) + +## Notes + +- This is idempotent - running multiple times has the same effect +- Settings are applied in sequence; both must succeed for complete application +- The `{owner}/{repo}` placeholder in the API call works with `gh` CLI's default behavior diff --git a/AI/commands/plan.md b/AI/commands/plan.md new file mode 100644 index 0000000..976c27d --- /dev/null +++ b/AI/commands/plan.md @@ -0,0 +1,123 @@ +# Plan Command + +Create a detailed implementation plan for a feature, fix, or change. The plan is saved to `.plan/.md` for iterative refinement through review cycles. + +## Usage + +``` +/plan # Create plan from description +/plan # Create plan from GitHub issue +``` + +## Workflow + +### 1. **Create Initial Plan** + + **IMPORTANT: This command ONLY creates the plan file. DO NOT implement anything. DO NOT write code. ONLY create the plan document.** + + - Parse the input (description or GitHub issue URL) + - If GitHub issue URL, fetch the issue content using `gh issue view ` + - Generate a suitable slug from the main topic (lowercase, hyphenated) + - Create `.plan/` directory if it doesn't exist + - Write plan to `.plan/.md` with: + - **Overview**: High-level description of what needs to be done and why + - **Phases**: Determine number of phases based on complexity: + - Each phase must be self-contained and easily implementable by Claude + - Each phase must be easily reviewable by user before next phase + - If task is trivial, use single phase or omit phases section entirely + - For each phase include: + - Phase number and name + - Specific tasks/steps within that phase + - Expected outcomes + - Any dependencies or prerequisites + - **STOP after creating the plan file. Tell user the plan is ready for review.** + +### 2. **Plan Review Cycle** + - User reviews the plan file + - User adds comments prefixed with `ME: ` right below the specific item/section they're commenting on + - User asks Claude to "review comments" or "address comments" + - Claude: + - Reads the plan file + - Reviews all `ME: ` comments + - Adjusts the plan based on feedback + - **Removes the `ME: ` comments** that have been addressed + - Writes the updated plan back to the file + - Repeat until user is satisfied + +### 3. **Implementation** + - User typically asks to implement one phase at a time (e.g., "implement phase 1") + - Claude implements that specific phase + - User reviews the implementation + - User asks for next phase when ready + - Repeat until all phases complete + - Can reference the plan file throughout implementation + +## Plan File Format + +```markdown +# Plan: + +## Overview + +<High-level description of the change, including context and motivation> + +## Phases + +### Phase 1: <Name> + +- Task or step description +- Another task +- Expected outcome: <what this phase achieves> + +### Phase 2: <Name> + +- Task or step description +- Another task +- Expected outcome: <what this phase achieves> + +### Phase 3: <Name> + +... + +## Notes + +- Any additional considerations +- Risks or gotchas +- References or links +``` + +## Example Flow + +```markdown +User: /plan Add dark mode support to the application + +Claude: Created plan at .plan/dark-mode-support.md + +User: [Reviews file, adds comments] +ME: Should we also handle system preference detection? +ME: What about persisting user choice? + +User: Review the comments + +Claude: [Updates plan to address both comments, removes the ME: lines] +Updated plan at .plan/dark-mode-support.md + +User: Looks good, implement it + +Claude: [Proceeds with Phase 1 implementation...] +``` + +## Requirements + +- If input is a GitHub issue URL, `gh` CLI must be available (use `nix run nixpkgs#gh` if not installed) +- Write permission in the repository root for creating `.plan/` directory + +## Notes + +- Plan files are iterative - expect multiple review cycles +- Number of phases depends on task complexity - trivial tasks may have one or no phases +- Keep phases sequential and logical +- Each phase should be self-contained, easily implementable, and easily reviewable +- Each phase should have clear entry and exit criteria +- Remove `ME: ` comments only after addressing them in the plan +- The plan file is the source of truth for implementation diff --git a/AI/commands/pr-review.md b/AI/commands/pr-review.md new file mode 100644 index 0000000..138644d --- /dev/null +++ b/AI/commands/pr-review.md @@ -0,0 +1,120 @@ +--- +description: Resolve PR review comments +subtask: true +--- + +# PR Review Command + +Fetch and resolve review comments from a GitHub pull request by implementing the requested changes. + +## Usage + +``` +/pr-review # Review comments on current branch's PR +/pr-review 123 # Review comments on PR #123 +/pr-review https://github.com/owner/repo/pull/123 +``` + +## Workflow + +### 1. **Identify the PR** + + - If URL provided: Extract owner, repo, and PR number + - If number provided: Use current repo (from `git remote -v`) + - If no argument: Get PR number from current branch using `gh pr view --json number` + +### 2. **Fetch Review Comments** + + **IMPORTANT: Fetch REVIEW COMMENTS, not plain comments. Review comments are on specific lines of code.** + + Use `gh api` to fetch: + ```bash + # Get PR review threads (includes is_resolved field) + gh api repos/OWNER/REPO/pulls/NUMBER/threads + + # Get PR reviews (contains review state: CHANGES_REQUESTED, APPROVED, etc.) + gh api repos/OWNER/REPO/pulls/NUMBER/reviews + ``` + + **IMPORTANT: Filter out resolved threads. Only process threads where `is_resolved` is false.** + + The threads API returns: + - `is_resolved`: Whether the thread has been marked as resolved + - `path`: File being commented on + - `line`: Line number + - `comments`: Array of comments in the thread + - `body`: Comment text + - `user.login`: Author + - `pull_request_review_id`: Links to the review + +### 3. **Filter and Present Comments** + + - **Filter out resolved threads** - only process threads where `is_resolved` is false + - Group threads by file for clarity + - Check review states - prioritize comments from reviews with `CHANGES_REQUESTED` state + - Present a summary: + ```markdown + ## PR #123 Review Comments + + ### src/auth.rs (2 comments) + 1. @reviewer: "This function should handle the error case properly" + Line: 45 + 2. @reviewer: "Consider using a constant here" + Line: 52 + + ### src/main.rs (1 comment) + 1. @reviewer: "Add documentation" + Line: 12 + + Total: 3 unresolved comments + ``` + +### 4. **Implement Changes** + + For each review comment: + - Read the relevant file and understand the context around the commented line + - Implement the requested change + - Use the comment's intent, not just literal interpretation + - If a comment is unclear, ask for clarification before proceeding + - After making changes, confirm with the user + +### 5. **Summary** + + After implementing all changes: + - List what was changed in response to each comment + - Remind user to push changes and respond to comments on GitHub + - Optionally: `git diff --stat` to show changed files + +## API Details + +### Fetching Review Comments + +```bash +# Get the repo from git remote +REPO=$(git remote get-url origin | sed 's/.*github.com[/:]//' | sed 's/.git$//') + +# Fetch review comments +gh api "repos/$REPO/pulls/$NUMBER/comments" --jq '.[] | select(.in_reply_to_id == null) | {path, line, body, user: .user.login}' + +# Fetch reviews to see states +gh api "repos/$REPO/pulls/$NUMBER/reviews" --jq '.[] | {user: .user.login, state, body}' +``` + +### Comment vs Review Comment + +- **Issue comments** (`/issues/123/comments`): General discussion, not tied to code +- **Review comments** (`/pulls/123/comments`): Tied to specific lines of code during review +- This command handles **review comments only** + +## Requirements + +- `gh` CLI installed and authenticated (use `nix run nixpkgs#gh` if not installed) +- Repository must have a GitHub remote +- For no-argument usage: current branch must have an associated PR + +## Notes + +- Focus on actionable code comments, not general discussion +- If review was dismissed, still show the comments for context +- If multiple reviews exist, show comments from all but prioritize unresolved ones +- After implementing, the user should mark conversations as resolved on GitHub diff --git a/AI/mcp/chrome-devtools.nix b/AI/mcp/chrome-devtools.nix new file mode 100644 index 0000000..5e6ee8f --- /dev/null +++ b/AI/mcp/chrome-devtools.nix @@ -0,0 +1,4 @@ +{ + command = "npx"; + args = [ "chrome-devtools-mcp@latest" ]; +} diff --git a/AI/mcp/nixos-mcp.nix b/AI/mcp/nixos-mcp.nix new file mode 100644 index 0000000..a8c2457 --- /dev/null +++ b/AI/mcp/nixos-mcp.nix @@ -0,0 +1,4 @@ +{ + command = "uvx"; + args = [ "mcp-nixos" ]; +} diff --git a/AI/memory.md b/AI/memory.md new file mode 100644 index 0000000..83d374c --- /dev/null +++ b/AI/memory.md @@ -0,0 +1,16 @@ +# System Instructions + +- Talk like a naive kid as much as possible +- Sacrifice grammar for brevity. + +# Git Policy + +- **NEVER auto-commit**: ALWAYS consult user before running `git commit` - never commit without explicit user approval +- User will use `/gci` command when they want Claude to help with commits +- **Avoid destructive operations**: No force pushing, rebasing, or amending commits +- **devShell required**: Run commits inside devShell if pre-commit hooks exist + +# Tools + +- **nix tools**: If any tool is unavailable, get it from nixpkgs: `nix run nixpkgs#<tool>`. +- **technical-writer**: For technical blog posts and documentation, use the technical-writer skill to avoid AI-speak patterns and maintain direct, high-IQ technical writing style. diff --git a/AI/settings/claude-code.nix b/AI/settings/claude-code.nix new file mode 100644 index 0000000..507e1ed --- /dev/null +++ b/AI/settings/claude-code.nix @@ -0,0 +1,8 @@ +{ + # theme = "dark"; + permissions = { + defaultMode = "bypassPermissions"; + }; + # Disable Claude from adding itself as co-author to commits + includeCoAuthoredBy = false; +} diff --git a/AI/skills/haskell/RELUDE.md b/AI/skills/haskell/RELUDE.md new file mode 100644 index 0000000..7874890 --- /dev/null +++ b/AI/skills/haskell/RELUDE.md @@ -0,0 +1,68 @@ +# Relude Best Practices + +When using relude prelude, follow these HLint recommendations (from https://github.com/kowainik/relude/blob/main/.hlint.yaml): + +**Basic Idioms**: +- Use `pass` instead of `pure ()` or `return ()` +- Use `one` instead of `(: [])`, `(:| [])`, or singleton functions +- Use `<<$>>` for double fmap: `f <<$>> x` instead of `fmap (fmap f) x` +- Use `??` (flap) operator: `ff ?? x` instead of `fmap ($ x) ff` + +**File I/O**: +- `readFileText`, `writeFileText`, `appendFileText` for Text files +- `readFileLText`, `writeFileLText`, `appendFileLText` for lazy Text +- `readFileBS`, `writeFileBS`, `appendFileBS` for ByteString +- `readFileLBS`, `writeFileLBS`, `appendFileLBS` for lazy ByteString + +**Console Output**: +- `putText`, `putTextLn` for Text +- `putLText`, `putLTextLn` for lazy Text +- `putBS`, `putBSLn` for ByteString +- `putLBS`, `putLBSLn` for lazy ByteString + +**Maybe/Either Helpers**: +- `whenJust m f` instead of `maybe pass f m` +- `whenJustM m f` for monadic versions +- `whenNothing_ m x` / `whenNothingM_ m x` for Nothing cases +- `whenLeft_ m f`, `whenRight_ m f` for Either +- `whenLeftM_ m f`, `whenRightM_ m f` for monadic Either +- `leftToMaybe`, `rightToMaybe` for conversions +- `maybeToRight l`, `maybeToLeft r` for conversions +- `isLeft`, `isRight` instead of `either (const True/False) (const False/True)` + +**List Operations**: +- Use `ordNub` instead of `nub` (O(n log n) vs O(n²)) +- Use `sortNub` instead of `Data.Set.toList . Data.Set.fromList` +- Use `sortWith f` instead of `sortBy (comparing f)` for simple cases +- Use `viaNonEmpty f x` instead of `fmap f (nonEmpty x)` +- Use `asumMap f xs` instead of `asum (map f xs)` +- Use `toList` instead of `foldr (:) []` + +**Monadic Operations**: +- `andM s` instead of `and <$> sequence s` +- `orM s` instead of `or <$> sequence s` +- `allM f s` instead of `and <$> mapM f s` +- `anyM f s` instead of `or <$> mapM f s` +- `guardM f` instead of `f >>= guard` +- `infinitely` instead of `forever` (better typed) +- `unlessM (not <$> x)` → use `whenM x` instead +- `whenM (not <$> x)` → use `unlessM x` instead + +**State/Reader Operations**: +- `usingReaderT` instead of `flip runReaderT` +- `usingStateT` instead of `flip runStateT` +- `evaluatingStateT s st` instead of `fst <$> usingStateT s st` +- `executingStateT s st` instead of `snd <$> usingStateT s st` + +**Transformer Lifting**: +- `hoistMaybe m` instead of `MaybeT (pure m)` +- `hoistEither m` instead of `ExceptT (pure m)` + +**List Pattern Matching**: +- `whenNotNull m f` for `case m of [] -> pass; (x:xs) -> f (x :| xs)` +- `whenNotNullM m f` for monadic version + +**Text/ByteString Conversions**: +- Use relude's `toText`, `toString`, `toLText` instead of pack/unpack +- Use relude's `encodeUtf8`, `decodeUtf8` for UTF-8 encoding +- `fromStrict`, `toStrict` for lazy/strict conversions diff --git a/AI/skills/haskell/SKILL.md b/AI/skills/haskell/SKILL.md new file mode 100644 index 0000000..9e32ceb --- /dev/null +++ b/AI/skills/haskell/SKILL.md @@ -0,0 +1,76 @@ +--- +name: haskell +description: Haskell coding with relude, ghcid-based workflow, hlint compliance, and strict error handling. Use when working with .hs files, Cabal projects, or ghcid. +--- + +# Haskell Development + +Expert assistance for Haskell programming. + +## Guidelines + +**CRITICAL - Error Handling in Code**: NEVER write code that silently ignores errors: +- Do NOT use `undefined` or `error` as placeholders +- Do NOT skip handling error cases in pattern matches +- Do NOT ignore `Maybe`/`Either` failure cases +- Handle all possible cases explicitly +- Use types to make impossible states unrepresentable + +Every error case in generated code must be handled properly. + +**CRITICAL - Compile Status**: +- The code MUST compile without errors. +- You MUST check `ghcid.txt` after every change and fix any errors reported there. +- Do NOT proceed to verification or linting until `ghcid.txt` is clean. + +**CRITICAL - HLint Compliance**: +- You MUST check for `.hlint.yaml` in the project root. +- If it exists, you MUST run `hlint` on any file you modify. +- You MUST fix ALL hlint warnings before considering the task complete. +- Do NOT ignore hlint warnings unless explicitly instructed by the user. + +**Code Quality**: +- Write type signatures for all top-level definitions +- Write total functions (avoid `head`, `tail`) +- Prefer pure functions over IO when possible +- Use explicit exports in modules +- Leverage type system for safety +- Favor composition over complex functions +- Write Haddock documentation for public APIs + +**Idiomatic Patterns**: +- Prefer `Text` over `String` +- Use `newtype` wrappers for domain types +- Apply smart constructors for validation +- Records: + - Use RecordDotSyntax & OverloadedRecordDot (add pragma to modules that use the syntax) + - Use DisambiguateRecordFields and DuplicateRecordFields for simple field names (add pragma to modules that use the syntax) +- Use lenses for record manipulation when appropriate +- Use `Applicative` and `Monad` appropriately +- Avoid trivial `let` bindings when inlining keeps code simple and readable + +**Working with Aeson**: +- NEVER construct aeson objects by hand +- Instead create a type and use `encode` and `decode` on it +- These types should generally use generic deriving of aeson (no hand deriving) + + +## Relude Best Practices + +When using `relude`, refer to [RELUDE.md](RELUDE.md) for best practices and idioms. + +## Testing + +- Use QuickCheck for property-based testing +- Use HUnit or Hspec for unit tests +- Provide good examples in documentation + +## Build instructions + +As you make code changes, start a subagent in parallel to resolve any compile errors in `ghcid.txt`. + +**IMPORTANT**: Do not run build commands yourself. The human runs ghcid in the terminal, which then updates `ghcid.txt` with any compile error or warning (if this file does not exist, or if ghcid has stopped, remind the human to address it). You should read `ghcid.txt` (in _entirety_) after making code changes; this file updates near-instantly. + +**Adding/Deleting modules**: When a new `.hs` file is added or deleted, the `.cabal` file must be updated accordingly. However, if `package.yaml` exists in the project, run `hpack` instead to regenerate the `.cabal` file with the updated module list. This will trigger `ghcid` to restart automatically. + +**HLint warnings**: MANDATORY. After `ghcid.txt` shows success, if `.hlint.yaml` exists, run `hlint` on the modified files. You are NOT done until `hlint` reports no issues. diff --git a/AI/skills/technical-writer/SKILL.md b/AI/skills/technical-writer/SKILL.md new file mode 100644 index 0000000..f10bd03 --- /dev/null +++ b/AI/skills/technical-writer/SKILL.md @@ -0,0 +1,110 @@ +--- +name: technical-writer +description: Direct, no-nonsense technical writing. Use for blog posts, documentation, and READMEs. Eliminates AI-speak, hedging, and filler. +--- + +# Technical Writing Style Guide + +## Core Principles + +Write for high-IQ technical readers. Assume expertise. Remove hand-holding. + +## What to Avoid (AI-speak patterns) + +### Verbose Section Titles +- ❌ "Why This Matters" +- ❌ "Key Takeaways" +- ❌ "Important Considerations" +- ❌ "When to Use This" +- ✅ "Advantages", "Trade-offs", "Example", "Usage" + +### Value Proposition Framing +- ❌ "This is the primary value proposition:" +- ❌ "The main benefit of this approach is:" +- ✅ State the benefit directly + +### Pattern Optimization Language +- ❌ "This pattern optimizes for X" +- ❌ "This approach is ideal for Y" +- ✅ "Use this when X" + +### Hedging and Over-Qualification +- ❌ "If you're frequently iterating on both..." +- ❌ "Choose based on which operation you perform more frequently" +- ✅ "Use this when actively co-developing" + +### Unnecessary Emphasis +- ❌ **Bold** subsection headings +- ❌ Multiple exclamation points +- ✅ Use callouts (NOTE, TIP, IMPORTANT) sparingly for actual critical info + +## Structure + +### Opening +State what, why, and for whom in the first paragraph. No preamble. + +### Pattern/Implementation +Show code first. Minimal explanation. Assume readers can read code. + +### Technical Details +Link to official documentation. Use callouts for non-obvious gotchas. +- `[!NOTE]` for clarifications +- `[!TIP]` for advanced understanding +- `[!IMPORTANT]` for actual blockers/workarounds + +### Trade-offs +Be honest about limitations. Link to upstream issues. Don't sugarcoat. + +### Usage Guidance +Direct imperatives. "Use this when X" not "This might be useful if you find yourself in situations where X". + +## Technical Precision + +### Domain-Specific Terminology +- Use exact technical terms for the domain +- Link to official docs on first use +- Assume reader knows the basics + +### Code Examples +- Show complete, working examples +- No `...` placeholders or "existing code" comments +- Include all relevant flags/options + +### References Section +- Link to upstream documentation +- Link to relevant issues/discussions +- Link to working examples +- Keep descriptions minimal (one clause) + +## Iteration Notes + +When revising: +1. Remove all "This is because..." explanations unless non-obvious +2. Cut phrases like "as mentioned above", "as we saw earlier" +3. Remove transition sentences between sections +4. State facts directly - no "it's worth noting that" +5. Replace "you can" with imperative: "Run X" not "You can run X" + +## Example Transformations + +### Before (AI-speak) +> This pattern optimizes for active co-development. If you're frequently iterating on both a Nix configuration and a dependency it consumes, submodules eliminate the push-lock-rebuild cycle. Choose based on which operation you perform more frequently. + +### After (Direct) +> Use this when actively co-developing a Nix configuration and its dependencies. Submodules eliminate the push-lock-rebuild cycle. + +--- + +### Before (Verbose) +> The primary value proposition here is instant feedback when modifying both repositories simultaneously. + +### After (Concise) +> (Delete this sentence - the benefit is already obvious from the code example) + +--- + +### Before (Over-explained) +> As you can see from the example above, when you make changes to the submodule... + +### After (Direct) +> Changes to `vendor/AI/` are picked up immediately on rebuild. diff --git a/flake.lock b/flake.lock index 61b43e3..217eade 100644 --- a/flake.lock +++ b/flake.lock @@ -1,23 +1,5 @@ { "nodes": { - "AI": { - "inputs": { - "skills": "skills" - }, - "locked": { - "lastModified": 1773691758, - "narHash": "sha256-hogU3oBAJQ52v9IsEVun8s8r7R4rY8ZSXyDZEDJHnR0=", - "owner": "srid", - "repo": "AI", - "rev": "89bd7cfb23e050420fed5caf2cd78f1aa17e2d74", - "type": "github" - }, - "original": { - "owner": "srid", - "repo": "AI", - "type": "github" - } - }, "aeson-typescript": { "flake": false, "locked": { @@ -909,6 +891,24 @@ "type": "github" } }, + "nix-agent-wire": { + "inputs": { + "skills": "skills" + }, + "locked": { + "lastModified": 1773694375, + "narHash": "sha256-wk2i1T3b3OMrOwI/ho8M9TEu7A3VU2jkhc9lb6IcF2E=", + "owner": "srid", + "repo": "nix-agent-wire", + "rev": "ab54edc3de7a44723d91e19f541485856654f85d", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "nix-agent-wire", + "type": "github" + } + }, "nix-darwin": { "inputs": { "nixpkgs": [ @@ -1278,7 +1278,6 @@ }, "root": { "inputs": { - "AI": "AI", "agenix": "agenix", "disc-scrape": "disc-scrape", "disko": "disko", @@ -1290,6 +1289,7 @@ "imako": "imako", "jumphost-nix": "jumphost-nix", "landrun-nix": "landrun-nix", + "nix-agent-wire": "nix-agent-wire", "nix-darwin": "nix-darwin", "nix-index-database": "nix-index-database", "nixos-hardware": "nixos-hardware", diff --git a/flake.nix b/flake.nix index efe0aae..1a8dab4 100644 --- a/flake.nix +++ b/flake.nix @@ -32,7 +32,7 @@ oc.url = "github:juspay/oc"; # landrun-nix.url = "github:srid/landrun-nix"; landrun-nix.url = "github:adrian-gierakowski/landrun-nix/darwin-implementation-via-sandbox-exec"; - AI.url = "github:srid/AI"; + nix-agent-wire.url = "github:srid/nix-agent-wire"; jumphost-nix.url = "github:srid/jumphost-nix"; jumphost-nix.flake = false; diff --git a/modules/home/claude-code/default.nix b/modules/home/claude-code/default.nix index eb0908d..f7534d8 100644 --- a/modules/home/claude-code/default.nix +++ b/modules/home/claude-code/default.nix @@ -1,10 +1,7 @@ { flake, pkgs, ... }: -let - inherit (flake.inputs) AI; -in { imports = [ - AI.homeManagerModules.claude-code + flake.inputs.nix-agent-wire.homeManagerModules.claude-code ]; home.packages = with pkgs; [ @@ -16,6 +13,6 @@ in package = flake.inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.claude; - autoWire.dir = AI; + autoWire.dir = flake.self.outPath + "/AI"; }; } diff --git a/modules/home/opencode/default.nix b/modules/home/opencode/default.nix index 89cd18a..9c1f36b 100644 --- a/modules/home/opencode/default.nix +++ b/modules/home/opencode/default.nix @@ -2,12 +2,12 @@ { imports = [ flake.inputs.oc.homeModules.default - flake.inputs.AI.homeManagerModules.opencode + flake.inputs.nix-agent-wire.homeManagerModules.opencode ]; programs.opencode = { package = flake.inputs.oc.packages.${pkgs.stdenv.hostPlatform.system}.opencode; - autoWire.dir = flake.inputs.AI; + autoWire.dir = flake.self.outPath + "/AI"; }; programs.zsh.initContent = ''