Compare commits
10 Commits
1782e6329f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 6d3bb1bef5 | |||
| e9e868a4c5 | |||
| bc39d60a00 | |||
| 62f8ba323e | |||
| 7aace1daba | |||
| 7f77140d89 | |||
| 8474a8c6ca | |||
| 01e93097ba | |||
| 3f44096a1f | |||
| 2451cb9726 |
24
flake.lock
generated
24
flake.lock
generated
@@ -83,11 +83,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1779726825,
|
"lastModified": 1784350909,
|
||||||
"narHash": "sha256-RUkMrREjKDQrA+dA9+xZviGAxM5W1aVdyOr/bSYpHrE=",
|
"narHash": "sha256-ZWyzLbS1yKUTeFJLmdVuWNnHttL333/ldJbEE+KzCrM=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "b179bde238977f7d4454fc770b1a727eaf55111c",
|
"rev": "4ce190229c73d44536caa7072f6308fb2d8feeb3",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -311,11 +311,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1779414137,
|
"lastModified": 1781205112,
|
||||||
"narHash": "sha256-XpwuFhwnfwPbzImZeUWWns///UEpoKNkpl1hN90C3Ag=",
|
"narHash": "sha256-PaoUtmk+qIP/ESdxkxnY7mUMpMHjix88qu22R5GLQqE=",
|
||||||
"owner": "shezdy",
|
"owner": "shezdy",
|
||||||
"repo": "hyprsplit",
|
"repo": "hyprsplit",
|
||||||
"rev": "0fc01e7930625ecb3e069f5dc8e1d61eab929f3b",
|
"rev": "6b00b677d8905fb38779c91e12d6294e0e586a44",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -487,11 +487,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1779971959,
|
"lastModified": 1784707089,
|
||||||
"narHash": "sha256-R5nauXyqyfRUFiZycFFZdkF7wl6eaUpPLst35+2nJQY=",
|
"narHash": "sha256-2V/6imsUgB7mPZlHY54oeVBRDoZbPKnvzwkAHUSSufk=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "ec942ba042dad5ef097e2ef3a3effc034241f011",
|
"rev": "b3fe9581c9061c749abef42b6d4ee7b7c05c33fa",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -540,11 +540,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1777944972,
|
"lastModified": 1783174389,
|
||||||
"narHash": "sha256-VfGRo1qTBKOe3s2gOv8LSoA6Fk19PvBlwQ1ECN0Evn8=",
|
"narHash": "sha256-aCWC8ngycU7OdJrU2+Je3qf+1a2ykuBvpPhZT/9tXMc=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "c591bf665727040c6cc5cb409079acb22dcce33c",
|
"rev": "f1406619a3884cd5c47992a70b8b35c9c0fcb4c9",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -14,21 +14,21 @@ let
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
bambu-studio-wrapped = pkgs.symlinkJoin {
|
# bambu-studio-wrapped = pkgs.symlinkJoin {
|
||||||
name = "bambu-studio-wrapped";
|
# name = "bambu-studio-wrapped";
|
||||||
paths = [ pkgs.bambu-studio ];
|
# paths = [ pkgs.bambu-studio ];
|
||||||
buildInputs = [ pkgs.makeWrapper ];
|
# buildInputs = [ pkgs.makeWrapper ];
|
||||||
postBuild = ''
|
# postBuild = ''
|
||||||
wrapProgram $out/bin/bambu-studio \
|
# wrapProgram $out/bin/bambu-studio \
|
||||||
--prefix MESA_LOADER_DRIVER_OVERRIDE : zink \
|
# --prefix MESA_LOADER_DRIVER_OVERRIDE : zink \
|
||||||
--prefix __EGL_VENDOR_LIBRARY_FILENAMES : ${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json
|
# --prefix __EGL_VENDOR_LIBRARY_FILENAMES : ${pkgs.mesa}/share/glvnd/egl_vendor.d/50_mesa.json
|
||||||
'';
|
# '';
|
||||||
};
|
# };
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
bambu-studio-wrapped
|
# bambu-studio-wrapped
|
||||||
lycheeslicer
|
lycheeslicer
|
||||||
orca-slicer
|
orca-slicer
|
||||||
|
|
||||||
|
|||||||
14
home-manager/features/development/claude.nix
Normal file
14
home-manager/features/development/claude.nix
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
_: {
|
||||||
|
|
||||||
|
programs.claude-code = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
effortLevel = "medium";
|
||||||
|
skipAutoPermissionsPrompt = true;
|
||||||
|
includeCoAuthoredBy = false;
|
||||||
|
|
||||||
|
skills = ./claude/skills;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
---
|
||||||
|
name: better-documents
|
||||||
|
description: >
|
||||||
|
Apply communication best practices when generating or reviewing any document,
|
||||||
|
presentation, report, memo, slide deck, proposal, or email. Use this skill when
|
||||||
|
asked to write, create, draft, or generate a document or presentation — apply
|
||||||
|
the principles at generation time, not as an afterthought. Also use when asked
|
||||||
|
to "review my doc," "look at this deck," "does this make sense," "is this clear,"
|
||||||
|
"improve this proposal," "check this before I send it," "make this more effective,"
|
||||||
|
or any request to evaluate whether a document will land with its audience. Use
|
||||||
|
this skill even when the request seems minor — a "quick look" or a "short memo"
|
||||||
|
is exactly when these principles matter most.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Document Review
|
||||||
|
|
||||||
|
Apply communication best practices when generating or reviewing any business
|
||||||
|
document — whether the right message reaches the right audience in the right order.
|
||||||
|
|
||||||
|
This skill applies the principles from Anil Dash's [Make better documents](https://www.anildash.com/2024/03/10/make-better-documents/).
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This skill covers **business documents**: presentations, slide decks, proposals,
|
||||||
|
reports, memos, briefs, one-pagers, and emails. It does not cover UI, web
|
||||||
|
components, or frontend applications — use the `frontend-design` skill for those.
|
||||||
|
|
||||||
|
The design principles here differ from frontend design in important ways:
|
||||||
|
|
||||||
|
- **Restraint over expression.** UI benefits from bold aesthetic commitment and
|
||||||
|
distinctive visual personality. Business documents benefit from getting out of
|
||||||
|
the way of the content. Most people reading a board deck or a client proposal
|
||||||
|
are not there to appreciate the typography.
|
||||||
|
- **The audience can't interact.** A web interface rewards exploration. A
|
||||||
|
document gets one read, often skimmed, often on a small screen or printed.
|
||||||
|
Every design choice that draws attention to itself is attention stolen from
|
||||||
|
the message.
|
||||||
|
- **Non-designers are both authors and audiences.** UI is built and consumed
|
||||||
|
with design context nearby. Business documents are built by operators, analysts,
|
||||||
|
executives, and founders — and read by the same. Complexity that a designer
|
||||||
|
handles intuitively becomes noise for everyone else.
|
||||||
|
|
||||||
|
## Modes
|
||||||
|
|
||||||
|
| Mode | When to use | What you do |
|
||||||
|
|---|---|---|
|
||||||
|
| **generate** | "write me a proposal," "create a deck," "draft a memo" | Apply all five principles while producing the document; no separate report needed |
|
||||||
|
| **full-review** | "review this doc," "look at this deck" | Run all five passes on an existing document, produce a structured report |
|
||||||
|
| **rewrite** | "fix this," "make this better" | Apply all passes and return a revised version |
|
||||||
|
| **targeted** | "is the ask clear," "check the formatting" | Run only the relevant pass(es) |
|
||||||
|
| **quick** | "quick look," "does this work" | Run passes 1 and 2 only, flag the top 3 issues |
|
||||||
|
|
||||||
|
Default to **generate** when producing a new document from scratch. Default to
|
||||||
|
**full-review** when given an existing document with no other instruction.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## The Five Passes
|
||||||
|
|
||||||
|
Apply these in order. Each targets a different failure mode.
|
||||||
|
|
||||||
|
### Pass 1 — Audience and Purpose
|
||||||
|
|
||||||
|
The most common reason documents fail: they were written for the author, not the reader.
|
||||||
|
|
||||||
|
Check for:
|
||||||
|
|
||||||
|
- **Missing context**: Does the document assume knowledge the audience may not have?
|
||||||
|
Flag any jargon, backstory, or acronyms that aren't explained.
|
||||||
|
- **Buried ask**: Is there a request, decision, or action needed? If so, is it
|
||||||
|
stated clearly in the first third of the document — not saved for the end?
|
||||||
|
- **Author-centered opening**: Does the document open with the author's anxieties,
|
||||||
|
backstory, or credentials rather than shared context? Flag and suggest reordering
|
||||||
|
to start from common ground.
|
||||||
|
- **Missing deadline or stakes**: If a decision or response is needed, is the
|
||||||
|
timeline stated? Is the reason for that timeline explained from the *audience's*
|
||||||
|
perspective, not just the author's?
|
||||||
|
|
||||||
|
Severity guide:
|
||||||
|
- **CRITICAL** — The core ask or decision is absent or appears only at the end
|
||||||
|
- **MAJOR** — The audience is unclear; the document would read differently to
|
||||||
|
different readers
|
||||||
|
- **MINOR** — Context gaps that could be filled with a sentence
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Pass 2 — Structure and Sequencing
|
||||||
|
|
||||||
|
Order signals importance. Audiences assume the first thing is the most important.
|
||||||
|
If it isn't, they'll be confused or dismissive before they reach the part that matters.
|
||||||
|
|
||||||
|
Check for:
|
||||||
|
|
||||||
|
- **Creation-order sequencing**: Is the document structured in the order it was
|
||||||
|
*written* (background → analysis → conclusion) rather than the order the
|
||||||
|
audience needs (conclusion → supporting logic → call to action)?
|
||||||
|
- **Murder mystery structure**: Does the document build to a reveal rather than
|
||||||
|
stating the point upfront? Flag any document where the key conclusion or request
|
||||||
|
appears in the second half.
|
||||||
|
- **Unannounced ordering**: If the document is ordered chronologically, by category,
|
||||||
|
or by any logic other than importance, is that explicitly stated? If not, the
|
||||||
|
audience will hunt for meaning in the sequence.
|
||||||
|
- **Key information in the wrong channel**: Is anything critical only in speaker
|
||||||
|
notes, appendices, or footnotes? Central points belong in the main body.
|
||||||
|
|
||||||
|
Severity guide:
|
||||||
|
- **CRITICAL** — The document's conclusion or core request is in the second half
|
||||||
|
- **MAJOR** — Ordering is non-obvious and unexplained
|
||||||
|
- **MINOR** — Supporting points could be reordered for better flow
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Pass 3 — Formatting Restraint
|
||||||
|
|
||||||
|
Over-formatting is the most visible symptom of unclear thinking. When everything
|
||||||
|
is emphasized, nothing is.
|
||||||
|
|
||||||
|
Check for:
|
||||||
|
|
||||||
|
- **Emphasis overload**: Are bold, italic, underline, and color being combined
|
||||||
|
on the same text? Flag any instance of two or more emphasis types on a single
|
||||||
|
element.
|
||||||
|
- **Underlines on non-links**: Flag every underline that isn't a hyperlink.
|
||||||
|
Underlines exist to signal clickability; using them decoratively confuses readers.
|
||||||
|
- **Color proliferation**: Count distinct colors in use (excluding images). More
|
||||||
|
than two is almost always a problem. More than three is always a problem.
|
||||||
|
- **Border clutter**: Flag tables and sections with heavy borders. White space
|
||||||
|
separates content more clearly than lines.
|
||||||
|
- **Filler visuals**: Flag images, icons, or clip art that aren't specific to
|
||||||
|
the content's message. A blank space is better than a stock photo.
|
||||||
|
- **Formatting inconsistency**: Do headings, titles, or labels vary in size,
|
||||||
|
weight, or color across the document without clear reason? Flag inconsistencies
|
||||||
|
that will read as meaningful to an audience even if they weren't intentional.
|
||||||
|
|
||||||
|
Severity guide:
|
||||||
|
- **CRITICAL** — Formatting inconsistencies that will be read as semantic signals
|
||||||
|
(e.g., random font changes mid-document)
|
||||||
|
- **MAJOR** — Overuse of emphasis that makes it impossible to identify what's
|
||||||
|
actually important
|
||||||
|
- **MINOR** — Minor decoration that adds noise without adding meaning
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Pass 4 — Wayfinding and Density
|
||||||
|
|
||||||
|
Audiences need to know where they are in the story, and how far they have to go.
|
||||||
|
|
||||||
|
Check for:
|
||||||
|
|
||||||
|
- **No orientation**: Is there any indication of structure — a brief outline,
|
||||||
|
section headers, or progress markers — for documents longer than one page or
|
||||||
|
five slides? If not, flag.
|
||||||
|
- **Unsummarized data**: Does any chart, table, or data display appear without
|
||||||
|
a title or caption that states what it shows? Readers shouldn't have to interpret
|
||||||
|
data cold. Flag every chart or table whose title doesn't answer "what does this show?"
|
||||||
|
- **Unanswerable questions**: Are there open-ended questions in the document
|
||||||
|
(as headers or prompts) that can't actually be answered with a choice? Flag
|
||||||
|
any question that could lead to a philosophical discussion instead of a decision.
|
||||||
|
Good: "Do we go with Option A or Option B?" Bad: "How do we improve?"
|
||||||
|
- **Dense, unbroken prose**: Are there paragraphs longer than ~6 lines where
|
||||||
|
bullet points would make the content more skimmable without losing meaning?
|
||||||
|
|
||||||
|
Severity guide:
|
||||||
|
- **CRITICAL** — Data presented without any interpretive framing
|
||||||
|
- **MAJOR** — Long documents with no structural signposts
|
||||||
|
- **MINOR** — Questions that could be made more answerable
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Pass 5 — Naming and Versioning
|
||||||
|
|
||||||
|
The title is information. Most document names throw it away.
|
||||||
|
|
||||||
|
Check for:
|
||||||
|
|
||||||
|
- **Generic or auto-generated title**: Does the document have a title like
|
||||||
|
"Untitled," "Draft," "Meeting Notes," or the name of the person it's addressed
|
||||||
|
to? Flag and suggest a title that includes: topic, date, and context/owner.
|
||||||
|
- **Recipient-first naming**: If the document is *for* someone at another
|
||||||
|
organization, is it named after *them* rather than the author or topic?
|
||||||
|
They'll search for it by *your* name, not theirs.
|
||||||
|
- **Version ambiguity**: Does the filename or title use `_v2`, `_final`,
|
||||||
|
`_final_final`, or sequential numbers without dates? Flag and suggest
|
||||||
|
date-based versioning.
|
||||||
|
- **Meeting invites named after participants**: If the document is tied to a
|
||||||
|
meeting, flag any invite titled "Meeting with [Name]" — it tells the recipient
|
||||||
|
nothing about what the conversation is for.
|
||||||
|
|
||||||
|
Severity guide:
|
||||||
|
- **CRITICAL** — Untitled or generic title on a document intended for external sharing
|
||||||
|
- **MAJOR** — Version ambiguity on any document with multiple drafts
|
||||||
|
- **MINOR** — Suboptimal naming that could make retrieval difficult later
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
### Generate mode
|
||||||
|
|
||||||
|
Produce the document applying all five principles as first-order constraints —
|
||||||
|
not as a post-hoc checklist. Specifically:
|
||||||
|
|
||||||
|
- State the conclusion or ask in the opening, not the closing
|
||||||
|
- Order content by importance to the audience, not by how it was assembled
|
||||||
|
- Use the minimum formatting necessary: one emphasis type at a time, no decorative
|
||||||
|
underlines, no more than two colors, white space over borders
|
||||||
|
- Include structural signposts if the document is longer than one page or five slides
|
||||||
|
- Give the document a title that includes topic, date, and relevant context
|
||||||
|
|
||||||
|
**Override default visual style.** Claude's default document aesthetic — warm
|
||||||
|
cream backgrounds, serif display type (Georgia, Fraunces, Playfair), terracotta
|
||||||
|
or amber accents, and a "small all-caps label over a body copy block" slide
|
||||||
|
layout — is recognizable as AI-generated and inappropriate for most professional
|
||||||
|
contexts. Do not apply it.
|
||||||
|
|
||||||
|
Instead, before generating any document with visual styling:
|
||||||
|
|
||||||
|
1. **Ask about brand or visual constraints first.** Does the user have brand
|
||||||
|
colors, a template, or a font they use? If so, follow those exactly.
|
||||||
|
2. **If no brand guidance is given**, default to neutral: black text on white,
|
||||||
|
one sans-serif typeface throughout, no decorative color. The content should
|
||||||
|
do the work, not the palette.
|
||||||
|
3. **If the user explicitly wants visual styling**, offer 2–3 distinct directions
|
||||||
|
in one sentence each (e.g. "neutral/minimal," "bold/high-contrast," "warm/
|
||||||
|
editorial") and let them choose before proceeding. Do not pick for them.
|
||||||
|
|
||||||
|
No review report is needed in generate mode. The principles are baked in.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Full-review and targeted mode
|
||||||
|
|
||||||
|
```
|
||||||
|
## Document Review: [Title or description]
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
[2–3 sentences: what the document is trying to do, how well it's set up to succeed,
|
||||||
|
the one or two changes that would most improve it]
|
||||||
|
|
||||||
|
### Pass 1 — Audience and Purpose [N issues]
|
||||||
|
[Each issue: location → what the problem is → suggested fix → severity]
|
||||||
|
|
||||||
|
### Pass 2 — Structure and Sequencing [N issues]
|
||||||
|
[Same format]
|
||||||
|
|
||||||
|
### Pass 3 — Formatting Restraint [N issues]
|
||||||
|
[Same format]
|
||||||
|
|
||||||
|
### Pass 4 — Wayfinding and Density [N issues]
|
||||||
|
[Same format]
|
||||||
|
|
||||||
|
### Pass 5 — Naming and Versioning [N issues]
|
||||||
|
[Same format]
|
||||||
|
|
||||||
|
### Top 3 Changes
|
||||||
|
[The three revisions that would most improve this document's effectiveness,
|
||||||
|
ranked by impact]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Rewrite mode
|
||||||
|
|
||||||
|
Return the revised document with a brief note after explaining what was changed
|
||||||
|
in each pass and why. Do not explain every small edit — only the structural
|
||||||
|
decisions that changed meaning or order.
|
||||||
|
|
||||||
|
### Quick mode
|
||||||
|
|
||||||
|
Return only the top 3 issues found across passes 1 and 2, with a one-line
|
||||||
|
suggested fix for each. No full report.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
- **Don't alter the author's voice.** In review and rewrite modes, improve
|
||||||
|
structure and clarity, not style. If a sentence is clear and effective, leave it.
|
||||||
|
- **Don't invent content.** If information is missing (a deadline, a decision
|
||||||
|
option, context for the audience), flag the gap — don't fill it in.
|
||||||
|
- **Ask before generating if the audience is unclear.** In generate mode, if the
|
||||||
|
request doesn't specify who will read the document or what decision it needs to
|
||||||
|
drive, ask before writing. A document built for the wrong audience fails
|
||||||
|
regardless of how well it's structured.
|
||||||
|
- **Be specific.** Every finding must reference the actual text or location.
|
||||||
|
Never say "consider clarifying" without showing where and how.
|
||||||
|
- **Respect intentional choices.** If the document is explicitly a narrative
|
||||||
|
or a mystery-format pitch, flag the structural convention as a risk rather
|
||||||
|
than a violation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Based on [Make better documents](https://www.anildash.com/2024/03/10/make-better-documents/) by Anil Dash.*
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
name: elegance
|
||||||
|
description: Iteratively study and apply elegant coding patterns. Each iteration - understand the code, research what simple and elegant code looks like, apply learnings, verify with CI. Use as a standalone refactoring pass or when the user asks to make code more elegant, simple, or idiomatic.
|
||||||
|
source: https://github.com/srid/emanote/tree/master/.claude/skills/elegance
|
||||||
|
---
|
||||||
|
|
||||||
|
# Elegance
|
||||||
|
|
||||||
|
Iteratively study and apply elegant coding patterns. Each iteration: understand the code, research what simple & elegant code looks like, apply learnings, verify with CI.
|
||||||
|
|
||||||
|
Run for **3 iterations** (or as specified by the user — can be a number or a duration like `2h`).
|
||||||
|
|
||||||
|
## 0. Determine Scope
|
||||||
|
|
||||||
|
- Before starting, use the `AskUserQuestion` tool to ask: should this operate on the **whole codebase** or only on **changes in the current branch/PR**?
|
||||||
|
- If scoped to current branch/PR, use `git diff main...HEAD` (or the appropriate base branch) to identify changed files and limit all subsequent steps to those files only.
|
||||||
|
|
||||||
|
## For each iteration (1 to N)
|
||||||
|
|
||||||
|
### 1. Understand
|
||||||
|
|
||||||
|
- Read through the relevant source files.
|
||||||
|
- Note patterns, repetition, unnecessary complexity, non-idiomatic code.
|
||||||
|
|
||||||
|
### 2. Research
|
||||||
|
|
||||||
|
- Use WebSearch/WebFetch to research what simple, elegant (yet readable!) code looks like for the relevant technology.
|
||||||
|
- Look for idiomatic patterns, standard simplifications, and community best practices.
|
||||||
|
- Focus on: simplicity, readability, removing unnecessary abstraction, leveraging language features.
|
||||||
|
|
||||||
|
### 3. Apply
|
||||||
|
|
||||||
|
- Refactor based on what you learned.
|
||||||
|
- This can include: edits, code reorganization, or even rewrites where simplicity demands it.
|
||||||
|
- Prefer fewer lines, clearer intent, and idiomatic style.
|
||||||
|
- Don't add abstractions — remove them.
|
||||||
|
|
||||||
|
### 4. Verify
|
||||||
|
|
||||||
|
- Run tests/CI to check edits.
|
||||||
|
- If CI fails, fix the issues before proceeding to the next iteration.
|
||||||
|
|
||||||
|
### 5. Log Progress
|
||||||
|
|
||||||
|
- Briefly note what changed in this iteration and why.
|
||||||
|
|
||||||
|
## After all iterations
|
||||||
|
|
||||||
|
- Do **not** git commit. Leave all changes in the working directory for the user to review.
|
||||||
|
- Present a summary of what changed across all iterations.
|
||||||
|
|
||||||
|
## Principles
|
||||||
|
|
||||||
|
- **Simple over clever**: Elegant code is simple code.
|
||||||
|
- **Readable over terse**: Brevity is good, but not at the cost of clarity.
|
||||||
|
- **Idiomatic over generic**: Use the language's strengths. Write TypeScript like TypeScript, not like Java.
|
||||||
|
- **Each iteration builds on the last**: Don't undo previous improvements. Deepen them.
|
||||||
@@ -11,6 +11,9 @@
|
|||||||
./nix.nix
|
./nix.nix
|
||||||
./lua.nix
|
./lua.nix
|
||||||
./sh.nix
|
./sh.nix
|
||||||
|
|
||||||
|
# Claude Code
|
||||||
|
./claude.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
home.packages = with pkgs; [
|
home.packages = with pkgs; [
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
# Useful for getting the import information from github info for flakes.
|
# Useful for getting the import information from github info for flakes.
|
||||||
nix-prefetch-github
|
nix-prefetch-github
|
||||||
|
|
||||||
nixfmt-rfc-style # Formatter
|
nixfmt # Formatter
|
||||||
nil # Language Server
|
nil # Language Server
|
||||||
statix # Lints and suggestions for Nix
|
statix # Lints and suggestions for Nix
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
Service = {
|
Service = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
|
# Eww won't start right if Hyprland hasn't finished initializing.
|
||||||
|
ExecStartPre = "${pkgs.coreutils}/bin/sleep 2";
|
||||||
ExecStart = "${pkgs.eww}/bin/eww open-many ${lib.concatStringsSep " " config.programs.eww.widgets}";
|
ExecStart = "${pkgs.eww}/bin/eww open-many ${lib.concatStringsSep " " config.programs.eww.widgets}";
|
||||||
ExecStop = "${pkgs.eww}/bin/eww kill";
|
ExecStop = "${pkgs.eww}/bin/eww kill";
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
htop
|
htop
|
||||||
btop
|
btop
|
||||||
psmisc # fuser, killall, pstree
|
psmisc # fuser, killall, pstree
|
||||||
|
lsof
|
||||||
|
|
||||||
# Session management
|
# Session management
|
||||||
tmux
|
tmux
|
||||||
@@ -45,6 +46,7 @@
|
|||||||
# Networking
|
# Networking
|
||||||
dnsutils
|
dnsutils
|
||||||
inetutils
|
inetutils
|
||||||
|
net-tools
|
||||||
socat
|
socat
|
||||||
xh
|
xh
|
||||||
|
|
||||||
|
|||||||
@@ -27,10 +27,11 @@ tandoor:
|
|||||||
secret_key: ENC[AES256_GCM,data:nl7S2fS1wENrT5k2iZfLEAGc99lCUktgwR5L5KklF69BNVKQkW1rUgb3aIv50VpXZa+3OxV/vdPmG9NhKMy96I5+Dno=,iv:FFyGQBARz0B5zrONZELzUMsOIn8TWrDNTKGsAHPlS7w=,tag:/c4MnDfLXQpBZDqVxZ0DTg==,type:str]
|
secret_key: ENC[AES256_GCM,data:nl7S2fS1wENrT5k2iZfLEAGc99lCUktgwR5L5KklF69BNVKQkW1rUgb3aIv50VpXZa+3OxV/vdPmG9NhKMy96I5+Dno=,iv:FFyGQBARz0B5zrONZELzUMsOIn8TWrDNTKGsAHPlS7w=,tag:/c4MnDfLXQpBZDqVxZ0DTg==,type:str]
|
||||||
immich:
|
immich:
|
||||||
database: ENC[AES256_GCM,data:1fjOQsLZcq/T+r+AkzomWwCQWw==,iv:c4pn2rC+3xkxLJ7uAdhnTE6zVTRQkfuKK3tjUyDhfAw=,tag:kvk7DOv6X/+RDxfPxVak7w==,type:str]
|
database: ENC[AES256_GCM,data:1fjOQsLZcq/T+r+AkzomWwCQWw==,iv:c4pn2rC+3xkxLJ7uAdhnTE6zVTRQkfuKK3tjUyDhfAw=,tag:kvk7DOv6X/+RDxfPxVak7w==,type:str]
|
||||||
|
searxng:
|
||||||
|
secret: ENC[AES256_GCM,data:Dg/6TAKY7fyhw8LJ6E4ZYN85zs/ItcetCYHETFbOMvHkGsflE3ngQNyIPVY=,iv:z3y2vXjJWCGhXYjfj963Nhiw6K0i/M8bVvwO/L3zgzk=,tag:yO9NtYMLjSazHQmToSR3fA==,type:str]
|
||||||
sops:
|
sops:
|
||||||
age:
|
age:
|
||||||
- recipient: age1dstsz5g4qthwt2sssu5wp787ku7rnfqm02mqaefsaueswhvqzpmsyft4p4
|
- enc: |
|
||||||
enc: |
|
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVZnYrVnR1MlBjdzFpQnVi
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVZnYrVnR1MlBjdzFpQnVi
|
||||||
RXFUcEN2N0Zoc2ZUUnprdXc0aElFaXU5c1VBCkxxcGd4QUhOaTl4K0paOTZ3d2Ez
|
RXFUcEN2N0Zoc2ZUUnprdXc0aElFaXU5c1VBCkxxcGd4QUhOaTl4K0paOTZ3d2Ez
|
||||||
@@ -38,8 +39,8 @@ sops:
|
|||||||
b2NVRnVFNmF6a2hjRE9OOUxVMGpjSWcKA6Do+oddwMjc2XNJUCeGXY985gJZ4f2v
|
b2NVRnVFNmF6a2hjRE9OOUxVMGpjSWcKA6Do+oddwMjc2XNJUCeGXY985gJZ4f2v
|
||||||
Dyo0/Oyuwz1jFMrjLmnmnmtyn079mT9wsm28KlaEEvzDIxOBnLjx6A==
|
Dyo0/Oyuwz1jFMrjLmnmnmtyn079mT9wsm28KlaEEvzDIxOBnLjx6A==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1yvdzvuvu5wqztcx6ll2xk6x547uuyqy735tjjdd7zftkz53jsf9qf5ahue
|
recipient: age1dstsz5g4qthwt2sssu5wp787ku7rnfqm02mqaefsaueswhvqzpmsyft4p4
|
||||||
enc: |
|
- enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKeGhvQWp6WWx6N1JDdm1J
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKeGhvQWp6WWx6N1JDdm1J
|
||||||
UWlWZTV5ellMd2ZIRWpkRnJDT2s4UVZJMEM4Cll2MnVNTnFWYit2bHpCVzcwbysy
|
UWlWZTV5ellMd2ZIRWpkRnJDT2s4UVZJMEM4Cll2MnVNTnFWYit2bHpCVzcwbysy
|
||||||
@@ -47,8 +48,8 @@ sops:
|
|||||||
OHlxaytJTWlNSFRCd2dDaFVsUU1CbUkKp7J+mDnGFS9upV6QWi40ptG85+UZ5y1G
|
OHlxaytJTWlNSFRCd2dDaFVsUU1CbUkKp7J+mDnGFS9upV6QWi40ptG85+UZ5y1G
|
||||||
9ic/sQEMHQe9VeAutVz1GPYWbF3Vt5iawXmtVxN+zx/bLAYGglv5yg==
|
9ic/sQEMHQe9VeAutVz1GPYWbF3Vt5iawXmtVxN+zx/bLAYGglv5yg==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
- recipient: age1jrk4h7x4qzhr6z5m4d099mlfyjc4n5n9s52r4gfsdz0slnqlqa9sss735v
|
recipient: age1yvdzvuvu5wqztcx6ll2xk6x547uuyqy735tjjdd7zftkz53jsf9qf5ahue
|
||||||
enc: |
|
- enc: |
|
||||||
-----BEGIN AGE ENCRYPTED FILE-----
|
-----BEGIN AGE ENCRYPTED FILE-----
|
||||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkM0RRaFhGKytkSjNMU3cy
|
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkM0RRaFhGKytkSjNMU3cy
|
||||||
d1dlcms4TVMzU2xsSHBqcDJWQTdCU1dZcERJCktHRVZiWkZrbzk4QXRNSmpyY25X
|
d1dlcms4TVMzU2xsSHBqcDJWQTdCU1dZcERJCktHRVZiWkZrbzk4QXRNSmpyY25X
|
||||||
@@ -56,7 +57,8 @@ sops:
|
|||||||
QlE3cFYxUXNVam1aMlJEVTRGV2xsN1kKXMeSXiEdXyb6c+dcxX3G/Q+s78lfi90g
|
QlE3cFYxUXNVam1aMlJEVTRGV2xsN1kKXMeSXiEdXyb6c+dcxX3G/Q+s78lfi90g
|
||||||
dvKJPDYvGb/8JXSkZNkLlWvHEVnsAJ1mJFb1idenYzeQvJlsX07rYA==
|
dvKJPDYvGb/8JXSkZNkLlWvHEVnsAJ1mJFb1idenYzeQvJlsX07rYA==
|
||||||
-----END AGE ENCRYPTED FILE-----
|
-----END AGE ENCRYPTED FILE-----
|
||||||
lastmodified: "2026-02-25T00:28:13Z"
|
recipient: age1jrk4h7x4qzhr6z5m4d099mlfyjc4n5n9s52r4gfsdz0slnqlqa9sss735v
|
||||||
mac: ENC[AES256_GCM,data:hDmqObrtfoVkQqz8JPkqlyXMbiuyBophjdZNLvTFrZw3pAVNCuzsH4zxFBOaxJttkzLc65DWDHDeEIBY5YZam1GLFFXUQ5E3Dxno7hnyzOoM2ipgDTOacI0gbKJAWgGUF3LNDdqVoREA9LC91LoNUJoNmzpTSFtuLb7ORuwCrH4=,iv:8+W3n1Cr6woEiPU9ECaMYM64HNmFHr2AIw6UohCJi00=,tag:7drkZiPAUHaEx5PagXA9JQ==,type:str]
|
lastmodified: "2026-07-21T02:59:55Z"
|
||||||
|
mac: ENC[AES256_GCM,data:0v26ceptPmbVdee70AOMdZHOarPDRuxKi+QP3Ci+wyJQJdQVriKKUnN3Zv/MKjZ3Sg2M/C5XtsdhGwXJpPsfwdDhWIRip6UYWXIKkVyZcxOs6E2zlK3xCAk/eTKhAsmL7Y6yFV+hpYwlT/hFnzOHXt1xbxGVJiKnO98OH0+6hnk=,iv:f94wd227bM0SniUuY+CFg2deEfITzUGTGwDA/WQJhms=,tag:M0r4Vg480wWWYPH3PBB7qg==,type:str]
|
||||||
unencrypted_suffix: _unencrypted
|
unencrypted_suffix: _unencrypted
|
||||||
version: 3.11.0
|
version: 3.13.1
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
|
# Enable bluetooth.
|
||||||
|
hardware.bluetooth.enable = true;
|
||||||
|
|
||||||
|
# Install the management service and packages.
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
bluez
|
bluez
|
||||||
];
|
];
|
||||||
|
|||||||
4
system/features/virtualbox.nix
Normal file
4
system/features/virtualbox.nix
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
_: {
|
||||||
|
virtualisation.virtualbox.host.enable = true;
|
||||||
|
users.extraGroups.vboxusers.members = [ "drew" ];
|
||||||
|
}
|
||||||
26
system/features/xpadneo.nix
Normal file
26
system/features/xpadneo.nix
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
_: {
|
||||||
|
hardware = {
|
||||||
|
# Wireless xbox controllers
|
||||||
|
xpadneo = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
disable_mouse = 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Hardwired xbox controllers.
|
||||||
|
xone.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# disable_ertm is required for xpadneo to connect properly and establish a
|
||||||
|
# data connection. enable_autosuspend is to prevent Linux from putting the
|
||||||
|
# BT radio to sleep and causing a disconnect.
|
||||||
|
boot.extraModprobeConfig = ''
|
||||||
|
options bluetooth disable_ertm=1
|
||||||
|
options btusb enable_autosuspend=0
|
||||||
|
'';
|
||||||
|
|
||||||
|
# Steam also needs HID API to be off so SDL will read directly from evdev,
|
||||||
|
# otherwise it won't get any events from xpadneo.
|
||||||
|
environment.sessionVariables.SDL_JOYSTICK_HIDAPI = "0";
|
||||||
|
}
|
||||||
@@ -1,18 +1,20 @@
|
|||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./configuration.nix
|
|
||||||
./hardware-configuration.nix
|
|
||||||
./qmk.nix
|
|
||||||
../../authorized-keys.nix
|
../../authorized-keys.nix
|
||||||
|
../../features/android-dev.nix
|
||||||
../../features/appimage.nix
|
../../features/appimage.nix
|
||||||
../../features/audio.nix
|
../../features/audio.nix
|
||||||
../../features/bluetooth.nix
|
../../features/bluetooth.nix
|
||||||
|
../../features/container-dev.nix
|
||||||
|
../../features/flatpak.nix
|
||||||
../../features/gc.nix
|
../../features/gc.nix
|
||||||
../../features/gui.nix
|
../../features/gui.nix
|
||||||
../../features/container-dev.nix
|
../../features/virtualbox.nix
|
||||||
../../features/android-dev.nix
|
../../features/xpadneo.nix
|
||||||
../../features/flatpak.nix
|
./configuration.nix
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./qmk.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
nixpkgs.config.allowUnfree = true;
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
"/features/development/haskell.nix"
|
"/features/development/haskell.nix"
|
||||||
"/features/development/markdown.nix"
|
"/features/development/markdown.nix"
|
||||||
"/features/development/typescript.nix"
|
"/features/development/typescript.nix"
|
||||||
"/features/development/vscode.nix"
|
|
||||||
"/features/eww"
|
"/features/eww"
|
||||||
"/features/email.nix"
|
"/features/email.nix"
|
||||||
"/features/gaming.nix"
|
"/features/gaming.nix"
|
||||||
|
|||||||
@@ -32,12 +32,6 @@
|
|||||||
};
|
};
|
||||||
kernelModules = [ "kvm-intel" ];
|
kernelModules = [ "kvm-intel" ];
|
||||||
extraModulePackages = [ ];
|
extraModulePackages = [ ];
|
||||||
|
|
||||||
# disable_ertm is required for xpadneo to connect properly and establish a
|
|
||||||
# data connection.
|
|
||||||
extraModprobeConfig = ''
|
|
||||||
options bluetooth disable_ertm=1
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fileSystems = {
|
fileSystems = {
|
||||||
@@ -113,13 +107,6 @@
|
|||||||
# Enable the nvidia-settings menu?
|
# Enable the nvidia-settings menu?
|
||||||
nvidiaSettings = true;
|
nvidiaSettings = true;
|
||||||
};
|
};
|
||||||
xpadneo = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
disable_mouse = 1;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
bluetooth.enable = true;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
# Add a udev rule to prevent the mouse from waking the system. Note that it
|
# Add a udev rule to prevent the mouse from waking the system. Note that it
|
||||||
|
|||||||
@@ -1,10 +1,24 @@
|
|||||||
|
|
||||||
{ config, ... }:
|
{ config, ... }:
|
||||||
let inherit (import ./lib.nix config) havenisms mkContainer; in
|
let
|
||||||
|
inherit (import ./lib.nix config) havenisms mkContainer;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
|
sops = {
|
||||||
|
secrets = {
|
||||||
|
"searxng/secret" = { };
|
||||||
|
};
|
||||||
|
templates."searxng.env" = {
|
||||||
|
mode = "0400";
|
||||||
|
content = ''
|
||||||
|
SEARXNG_BASE_URL=https://search.${havenisms}
|
||||||
|
SEARXNG_VALKEY_URL=valkey://valkey:6379/0
|
||||||
|
SEARXNG_SECRET=${config.sops.placeholder."searxng/secret"}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
virtualisation.oci-containers.containers.searxng = mkContainer {
|
virtualisation.oci-containers.containers.searxng = mkContainer {
|
||||||
hostName = "search";
|
hostName = "search";
|
||||||
image = "docker.io/searxng/searxng:latest";
|
image = "searxng/searxng:latest";
|
||||||
port = 8080;
|
port = 8080;
|
||||||
public = true;
|
public = true;
|
||||||
dependsOn = [
|
dependsOn = [
|
||||||
@@ -19,9 +33,9 @@ let inherit (import ./lib.nix config) havenisms mkContainer; in
|
|||||||
volumes = [
|
volumes = [
|
||||||
"/tank/config/searxng:/etc/searxng"
|
"/tank/config/searxng:/etc/searxng"
|
||||||
];
|
];
|
||||||
environment = {
|
environmentFiles = [
|
||||||
SEARXNG_BASE_URL = "https://search.${havenisms}";
|
config.sops.templates."searxng.env".path
|
||||||
SEARXNG_REDIS_URL = "redis://valkey:6379/0";
|
];
|
||||||
};
|
extraOptions = [ "--pull=always" ];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user