Compare commits

..

12 Commits

Author SHA1 Message Date
Ryan Yin b9c1b10135 fix: issue #202 2025-07-12 15:55:13 +08:00
Ryan Yin d4847c44ce Merge pull request #191 from ryan4yin/i3-kickstarter-nixos-25.05
feat: upgrade to nixos-25.05
2025-05-29 12:25:29 +08:00
Ryan Yin 1f0a26524b fix: issues after upgrade nixos 2025-05-29 12:23:29 +08:00
Ryan Yin 7dc769aad2 fix: command in README 2025-05-29 12:14:13 +08:00
Ryan Yin 938cf720fd feat: upgrade to nixos-25.05 2025-05-29 12:04:56 +08:00
Ryan Yin 7a5587d14d fix: typo #190 2025-05-29 12:03:21 +08:00
Ryan Yin d384607345 feat: bump nixos to 24.05 2024-08-16 11:18:35 +08:00
Ryan Yin adc91138c5 feat: multi user 2024-08-16 10:55:54 +08:00
Ryan Yin 42bcfeb47c feat: add gitignore 2024-08-16 10:15:54 +08:00
Ryan Yin 82b65f7753 feat: upgrade to nixos-23.11 2023-12-09 22:58:13 +08:00
Ryan Yin 5237bf31c5 nix.settings.substituters(system-level) & nixConfig.extra-substituers(flake-only) 2023-12-09 16:16:22 +08:00
Ryan Yin abdf6d181b fix: set this variable make i3 failed to start XAUTHORITY 2023-09-11 00:25:03 +08:00
512 changed files with 4838 additions and 123979 deletions
-1
View File
@@ -1 +0,0 @@
use flake
-3
View File
@@ -1,3 +0,0 @@
# https://github.com/github-linguist/linguist/blob/master/docs/overrides.md
home/linux/desktop/i3/conf/polybar/** linguist-vendored
-3
View File
@@ -1,3 +0,0 @@
github: ryan4yin
patreon: ryan4yin
custom: ["https://buymeacoffee.com/ryan4yin"]
-42
View File
@@ -1,42 +0,0 @@
name: Nix Flake Eval Tests
on:
push:
branches:
- main
paths-ignore:
- "scripts/**"
- "**.md"
- "**.nu"
- "Justfile"
pull_request:
branches:
- main
paths-ignore:
- "scripts/**"
- "**.md"
- "**.nu"
- "Justfile"
jobs:
checks:
name: Check expressions
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Install nix
uses: cachix/install-nix-action@v31
with:
install_url: https://nixos.org/nix/install
extra_nix_config: |
access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
experimental-features = nix-command flakes
- name: Run Nix Flake Eval Tests
run: |
echo 'Flake Eval Tests'
# stack overflow...
# nix eval .#checks --show-trace --print-build-logs --verbose
nix eval .#evalTests --show-trace --print-build-logs --verbose
-32
View File
@@ -1,32 +0,0 @@
name: Mirror this repo to Gitee
on:
push:
branches:
- main
tags:
- "*"
jobs:
mirror:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Mirror repo to Gitee
id: mirror-to-gitee
shell: bash
env:
INPUT_SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY_GITEE_MIRROR }}
INPUT_TARGET_REPO_URL: git@gitee.com:ryan_yin/nix-config.git
run: |
set -eu
mkdir -p ~/.ssh
echo "$INPUT_SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
export GIT_SSH_COMMAND="ssh -v -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no"
git remote add mirror "$INPUT_TARGET_REPO_URL"
git push --tags --force --prune mirror "refs/remotes/origin/*:refs/heads/*"
-224
View File
@@ -1,230 +1,6 @@
.Trash-1000/
result
result/
.direnv/
.DS_Store
.pre-commit-config.yaml
logs/
core*
!core/
!core.nix
!coredns*
# =============== Python.gitignore ===========================
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py.cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
# Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
# poetry.lock
# poetry.toml
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
# pdm.lock
# pdm.toml
.pdm-python
.pdm-build/
# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
# pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# Redis
*.rdb
*.aof
*.pid
# RabbitMQ
mnesia/
rabbitmq/
rabbitmq-data/
# ActiveMQ
activemq-data/
# SageMath parsed files
*.sage.py
# Environments
.env
.envrc
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
# .idea/
# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/
# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/
# Streamlit
.streamlit/secrets.toml
-8
View File
@@ -1,8 +0,0 @@
LICENSE.md
dist
pnpm-lock.yaml
flake.lock
vercel.json
cache
temp
.temp
-6
View File
@@ -1,6 +0,0 @@
# https://prettier.io/docs/en/options
semi: false
singleQuote: false
printWidth: 100
proseWrap: always # always change wrapping in markdown text
trailingComma: es5
-45
View File
@@ -1,45 +0,0 @@
[files]
# Respect .ignore files.
ignore-dot = true
# Respect ignore files.
ignore-files = true
# Typos-specific ignore globs (gitignore syntax).
# NOTE: This setting is ignored when you pass the path directly on the command line, as cachix/git-hooks.nix does.
# To ignore those files, you must also exclude those directories via git-hooks.hooks.typos.settings.exclude.
extend-exclude = [
"data/",
"rime-data/",
]
[default]
# Check binary files as text.
binary = false
# Verify spelling in file names.
check-filename = true
# ignore some special identifiers(sha256, mac address, crypto keys, etc)
extend-ignore-re = [
"iterm2",
"iHgEIBYKACAWIQSizQe9ljFEyyclWmtVhZllwnQrSwUCZZ1T9wIdAAAKCRBVhZll", # crypto keys
"noice", # noice.nvim
"crypted-nixos",
"daed",
# catppuccin theme colors
"11111b",
"1e1e2e",
"313244",
"414356",
"45475a",
"585b70",
"89b4fa",
"94e2d5",
"a6adc8",
"a6e3a1",
"bac2de",
"cdd6f4",
"f38ba8",
"f5c2e7",
"f5e0dc",
"f9e2af",
"fab387",
]
-204
View File
@@ -1,204 +0,0 @@
# AGENTS.md - Guidelines for AI Coding Agents
This file defines the default operating guide for AI agents working in this Nix Flake repository.
Keep changes minimal, verifiable, and safe for multi-host deployments.
## Scope and Repository Model
This repository manages:
- NixOS hosts (desktop + servers)
- macOS hosts via nix-darwin
- Home Manager profiles shared across platforms
- Remote deployments via colmena
High-level layout:
```text
.
├── flake.nix # Flake entry; outputs composed in ./outputs
├── Justfile # Primary command entrypoint (uses nushell)
├── outputs/
│ ├── default.nix
│ ├── x86_64-linux/
│ ├── aarch64-linux/
│ └── aarch64-darwin/
├── modules/ # NixOS + darwin modules
├── home/ # Home Manager modules
├── hosts/ # Host-specific config
├── vars/ # Shared variables
├── lib/ # Helper functions
├── agents/ # Reusable cross-project agent files and installer
└── secrets/ # Agenix secret definitions
```
## Ground Rules for Agents
- Prefer `just` tasks over ad-hoc commands when an equivalent task exists.
- Make the smallest reasonable change; avoid drive-by refactors.
- Do not commit secrets, generated credentials, or private keys.
- Preserve platform guards (`[linux]`, `[macos]`) and host naming conventions.
- Run formatting and evaluation checks for touched areas before finishing.
## Quick Start Workflow (Recommended)
1. Inspect context:
```bash
just --list
rg -n "<symbol-or-option>" modules home hosts outputs
```
2. Implement the change.
3. Format:
```bash
just fmt
```
4. Validate:
```bash
just test
```
5. If deployment behavior changed, provide the exact `just` command the user should run (do not run
remote deploys unless explicitly requested).
## Canonical Commands
### Core quality loop
```bash
just fmt # format Nix files
just test # run eval tests: nix eval .#evalTests ...
nix flake check # run flake checks + pre-commit style checks
```
### Dependency/input updates
```bash
just up # update all inputs and commit lock file
just upp <input> # update one input and commit lock file
just up-nix # update nixpkgs-related inputs
```
### Local deploy commands
```bash
just local # deploy config for current hostname
just local debug # same with verbose/debug mode
just niri # deploy "<hostname>-niri" on Linux
just niri debug # debug mode
```
### Remote deploy commands (colmena)
```bash
just col <tag> # deploy nodes matching tag
just lab # deploy all kubevirt nodes
just k3s-prod # deploy k3s production nodes
just k3s-test # deploy k3s test nodes
```
### Useful direct commands
```bash
nix eval .#evalTests --show-trace --print-build-logs --verbose
nix build .#nixosConfigurations.<host>.config.system.build.toplevel
nixos-rebuild switch --flake .#<hostname>
```
## Test Structure and Expectations
Eval tests live under:
- `outputs/x86_64-linux/tests/`
- `outputs/aarch64-linux/tests/`
- `outputs/aarch64-darwin/tests/`
Typical test pair:
- `expr.nix`
- `expected.nix`
Agent expectations:
- If logic changes affect shared modules, run `just test`.
- If only docs/comments changed, tests may be skipped, but say so explicitly.
- If tests cannot run, report why and include the exact failing command.
## Formatting and Style
### Formatting tools
- Nix: `nixfmt` (RFC style, width 100)
- Non-Nix: `prettier` (see `.prettierrc.yaml`)
- Spelling: `typos` (see `.typos.toml`)
### Nix style conventions
- Files use `kebab-case.nix`.
- Prefer `inherit (...)` for attribute imports.
- Prefer `lib.mkIf`, `lib.optional`, `lib.optionals` for conditional config.
- Use `lib.mkDefault` for defaults and `lib.mkForce` only when necessary.
- Keep module options documented with `description`.
Module pattern:
```nix
{ lib, config, ... }:
{
options.myFeature = {
enable = lib.mkEnableOption "my feature";
};
config = lib.mkIf config.myFeature.enable {
# ...
};
}
```
## Platform Notes
- `Justfile` uses `nu` (`set shell := ["nu", "-c"]`).
- Some tasks exist only on Linux or macOS via `[linux]` / `[macos]` guards.
- `just local` has different implementations per platform:
- Linux: `nixos-switch`
- macOS: `darwin-build` + `darwin-switch`
## Secrets and Safety
- Secrets are managed with agenix and an external private secrets repo.
- Never inline secret values in Nix files, tests, or docs.
- Do not run broad remote deploy commands unless requested.
- Prefer build/eval validation first, deploy second.
## Change Review Checklist (for agents)
Before finishing, verify:
1. Change is scoped to requested behavior.
2. `just fmt` applied (or not needed, stated explicitly).
3. `just test` run for config changes (or limitation explained).
4. No secrets or machine-specific artifacts added.
5. User-facing summary includes what changed and what was validated.
## Common Pitfalls
- Editing host-specific files when the change belongs in shared module layers (`modules/` or
`home/`).
- Forgetting to update both Linux and darwin paths when touching shared abstractions.
- Running deployment commands to validate syntax when `nix eval`/`nix build` would be safer.
- Introducing hardcoded usernames/paths instead of using `myvars` and existing abstractions.
## References
- [README.md](./README.md)
- [agents/README.md](./agents/README.md)
- [Justfile](./Justfile)
- [outputs/README.md](./outputs/README.md)
- [hosts/README.md](./hosts/README.md)
- [home/README.md](./home/README.md)
- [modules/README.md](./modules/README.md)
- [secrets/README.md](./secrets/README.md)
-359
View File
@@ -1,359 +0,0 @@
# just is a command runner, Justfile is very similar to Makefile, but simpler.
# Use nushell for shell commands
# To use this justfile, you need to enter a shell with just & nushell installed:
#
# nix shell nixpkgs#just nixpkgs#nushell
set shell := ["nu", "-c"]
utils_nu := absolute_path("utils.nu")
############################################################################
#
# Common commands(suitable for all machines)
#
############################################################################
# List all the just commands
default:
@just --list
# Run eval tests
[group('nix')]
test:
nix eval .#evalTests --show-trace --print-build-logs --verbose
# Update all the flake inputs
[group('nix')]
up:
nix flake update --commit-lock-file
# Update specific input
# Usage: just upp nixpkgs
[group('nix')]
upp input:
nix flake update {{input}} --commit-lock-file
# List all generations of the system profile
[group('nix')]
history:
nix profile history --profile /nix/var/nix/profiles/system
# Open a nix shell with the flake
[group('nix')]
repl:
nix repl -f flake:nixpkgs
# remove all old generations
# on darwin, you may need to switch to root user to run this command
[group('nix')]
clean:
# Wipe out NixOS's history
sudo nix profile wipe-history --profile /nix/var/nix/profiles/system
# Wipe out home-manager's history
nix profile wipe-history --profile $"($env.XDG_STATE_HOME)/nix/profiles/home-manager"
# Garbage collect all unused nix store entries
[group('nix')]
gc:
# garbage collect all unused nix store entries(system-wide)
sudo nix-collect-garbage --delete-older-than 7d
# garbage collect all unused nix store entries(for the user - home-manager)
# https://github.com/NixOS/nix/issues/8508
nix-collect-garbage --delete-older-than 7d
# Enter a shell session which has all the necessary tools for this flake
[linux]
[group('nix')]
shell:
nix shell nixpkgs#git nixpkgs#neovim nixpkgs#colmena
# Enter a shell session which has all the necessary tools for this flake
[macos]
[group('nix')]
shell:
nix shell nixpkgs#git nixpkgs#neovim
# upgrade determinate nix
[macos]
[group('nix')]
nix-upgrade:
sudo determinate-nixd upgrade
[group('nix')]
fmt:
# format the nix files in this repo
ls **/*.nix | each { |it| nixfmt $it.name }
# Show all the auto gc roots in the nix store
[group('nix')]
gcroot:
ls -al /nix/var/nix/gcroots/auto/
# Verify all the store entries
# Nix Store can contains corrupted entries if the nix store object has been modified unexpectedly.
# This command will verify all the store entries,
# and we need to fix the corrupted entries manually via `sudo nix store delete <store-path-1> <store-path-2> ...`
[group('nix')]
verify-store:
nix store verify --all
# Repair Nix Store Objects
[group('nix')]
repair-store *paths:
nix store repair {{paths}}
# Update all Nixpkgs inputs
[group('nix')]
up-nix:
nix flake update --commit-lock-file nixpkgs-stable nixpkgs-master nixpkgs-darwin nixpkgs-patched
# override nixpkgs's commit hash
[group('nix')]
override-pkgs hash:
nix flake update --commit-lock-file nixpkgs --override-input nixpkgs github:NixOS/nixpkgs/{{hash}}
############################################################################
#
# NixOS Desktop related commands
#
############################################################################
# Deploy the nixosConfiguration by hostname match
[linux]
[group('homelab')]
local mode="default":
#!/usr/bin/env nu
use {{utils_nu}} *;
nixos-switch (hostname) {{mode}}
# Deploy the niri nixosConfiguration by hostname match
[linux]
[group('desktop')]
niri mode="default":
#!/usr/bin/env nu
use {{utils_nu}} *;
nixos-switch $"(hostname)-niri" {{mode}}
############################################################################
#
# Darwin related commands
#
############################################################################
[macos]
[group('desktop')]
darwin-set-proxy:
sudo python3 scripts/darwin_set_proxy.py
sleep 1sec
[macos]
[group('desktop')]
darwin-rollback:
#!/usr/bin/env nu
use {{utils_nu}} *;
darwin-rollback
# Deploy the darwinConfiguration by hostname match
[macos]
[group('desktop')]
local mode="default":
#!/usr/bin/env nu
use {{utils_nu}} *;
darwin-build (hostname) {{mode}};
darwin-switch (hostname) {{mode}}
# Reset launchpad to force it to reindex Applications
[macos]
[group('desktop')]
reset-launchpad:
defaults write com.apple.dock ResetLaunchPad -bool true
killall Dock
############################################################################
#
# Homelab - Kubevirt Cluster related commands
#
############################################################################
# Remote deployment via colmena
[linux]
[group('homelab')]
col tag:
colmena apply --on '@{{tag}}' --verbose --show-trace
# Build and upload a vm image
[linux]
[group('homelab')]
upload-vm name mode="default":
#!/usr/bin/env nu
use {{utils_nu}} *;
upload-vm {{name}} {{mode}}
# Deploy all the KubeVirt nodes(Physical machines running KubeVirt)
[linux]
[group('homelab')]
lab:
colmena apply --on '@virt-*' --verbose --show-trace
[linux]
[group('homelab')]
shoryu:
colmena apply --on '@kubevirt-shoryu' --verbose --show-trace
[linux]
[group('homelab')]
shushou:
colmena apply --on '@kubevirt-shushou' --verbose --show-trace
[linux]
[group('homelab')]
youko:
colmena apply --on '@kubevirt-youko' --verbose --show-trace
############################################################################
#
# Commands for other Virtual Machines
#
############################################################################
# Build and upload a vm image
[linux]
[group('homelab')]
upload-idols mode="default":
#!/usr/bin/env nu
use {{utils_nu}} *;
upload-vm aquamarine {{mode}}
upload-vm ruby {{mode}}
upload-vm kana {{mode}}
[linux]
[group('homelab')]
aqua:
colmena apply --on '@aqua' --verbose --show-trace
[linux]
[group('homelab')]
ruby:
colmena apply --on '@ruby' --verbose --show-trace
[linux]
[group('homelab')]
kana:
colmena apply --on '@kana' --verbose --show-trace
############################################################################
#
# Kubernetes related commands
#
############################################################################
# Build and upload a vm image
[linux]
[group('homelab')]
upload-k3s-prod mode="default":
#!/usr/bin/env nu
use {{utils_nu}} *;
upload-vm k3s-prod-1-master-1 {{mode}};
upload-vm k3s-prod-1-master-2 {{mode}};
upload-vm k3s-prod-1-master-3 {{mode}};
upload-vm k3s-prod-1-worker-1 {{mode}};
upload-vm k3s-prod-1-worker-2 {{mode}};
upload-vm k3s-prod-1-worker-3 {{mode}};
[linux]
[group('homelab')]
upload-k3s-test mode="default":
#!/usr/bin/env nu
use {{utils_nu}} *;
upload-vm k3s-test-1-master-1 {{mode}};
upload-vm k3s-test-1-master-2 {{mode}};
upload-vm k3s-test-1-master-3 {{mode}};
[linux]
[group('homelab')]
k3s-prod:
colmena apply --on '@k3s-prod-*' --verbose --show-trace
[linux]
[group('homelab')]
k3s-test:
colmena apply --on '@k3s-test-*' --verbose --show-trace
# =================================================
#
# Other useful commands
#
# =================================================
[group('common')]
path:
$env.PATH | split row ":"
[group('common')]
trace-access app *args:
strace -f -t -e trace=file {{app}} {{args}} | complete | $in.stderr | lines | find -v -r "(/nix/store|/newroot|/proc)" | parse --regex '"(/.+)"' | sort | uniq
[linux]
[group('common')]
penvof pid:
sudo cat $"/proc/($pid)/environ" | tr '\0' '\n'
# Remove all reflog entries and prune unreachable objects
[group('git')]
ggc:
git reflog expire --expire-unreachable=now --all
git gc --prune=now
# Amend the last commit without changing the commit message
[group('git')]
game:
git commit --amend -a --no-edit
# Delete all failed pods
[group('k8s')]
del-failed:
kubectl delete pod --all-namespaces --field-selector="status.phase==Failed"
[linux]
[group('services')]
list-inactive:
systemctl list-units -all --state=inactive
[linux]
[group('services')]
list-failed:
systemctl list-units -all --state=failed
[linux]
[group('services')]
list-systemd:
systemctl list-units systemd-*
# =================================================
#
# GitHub CLI + Nixpkgs Review via Github Action
# https://github.com/ryan4yin/nixpkgs-review-gha
#
# =================================================
[group('github')]
gh-login:
gh auth login -h github.com --skip-ssh-key --git-protocol ssh
# Run nixpkgs-review for PR
[group('nixpkgs')]
pkg-review pr:
gh workflow run review.yml --repo ryan4yin/nixpkgs-review-gha -f x86_64-darwin=no -f post-result=true -f pr={{pr}}
# Run package tests for PR
[group('nixpkgs')]
pkg-test pr pname:
gh workflow run review.yml --repo ryan4yin/nixpkgs-review-gha -f x86_64-darwin=no -f post-result=true -f pr={{pr}} -f extra-args="-p {{pname}}.passthru.tests"
# View the summary of a workflow
[group('nixpkgs')]
pkg-summary:
gh workflow view review.yml --repo ryan4yin/nixpkgs-review-gha
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2023 Ryan Yin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+7 -190
View File
@@ -1,201 +1,18 @@
<h2 align="center">:snowflake: Ryan4Yin's Nix Config :snowflake:</h2>
# Nix Configuration
<p align="center">
<img src="https://raw.githubusercontent.com/catppuccin/catppuccin/main/assets/palette/macchiato.png" width="400" />
</p>
This repository is home to the nix code that builds my systems.
<p align="center">
<a href="https://github.com/ryan4yin/nix-config/stargazers">
<img alt="Stargazers" src="https://img.shields.io/github/stars/ryan4yin/nix-config?style=for-the-badge&logo=starship&color=C9CBFF&logoColor=D9E0EE&labelColor=302D41"></a>
<a href="https://nixos.org/">
<img src="https://img.shields.io/badge/NixOS-25.11-informational.svg?style=for-the-badge&logo=nixos&color=F2CDCD&logoColor=D9E0EE&labelColor=302D41"></a>
<a href="https://github.com/ryan4yin/nixos-and-flakes-book">
<img src="https://img.shields.io/badge/Nix%20Flakes-learning-informational.svg?style=for-the-badge&logo=nixos&color=F2CDCD&logoColor=D9E0EE&labelColor=302D41"></a>
</a>
</p>
> My configuration is becoming more and more complex, and **it will be difficult for beginners to
> read**. If you are new to NixOS and want to know how I use NixOS, I would recommend you to take a
> look at the [ryan4yin/nix-config/releases](https://github.com/ryan4yin/nix-config/releases) first,
> **check out to some simpler older versions, such as
> [i3-kickstarter](https://github.com/ryan4yin/nix-config/tree/i3-kickstarter), which will be much
> easier to understand**.
## Why Nix?
This repository is home to the nix code that builds my systems:
Nix allows for easy to manage, collaborative, reproducible deployments. This means that once something is setup and configured once, it works forever. If someone else shares their configuration, anyone can make use of it.
1. NixOS Desktops: NixOS with home-manager, niri, agenix, etc.
2. macOS Desktops: nix-darwin with home-manager, share the same home-manager configuration with
NixOS Desktops.
3. NixOS Servers: virtual machines running on Proxmox/KubeVirt, with various services, such as
kubernetes, homepage, prometheus, grafana, etc.
See [./hosts](./hosts) for details of each host.
## How to install Nix and Deploy this Flake?
See [./Virtual-Machine.md](./Virtual-Machine.md) for details of how to create & manage KubeVirt's
Virtual Machine from this flake.
## Why NixOS & Flakes?
Nix allows for easy-to-manage, collaborative, reproducible deployments. This means that once
something is setup and configured once, it works (almost) forever. If someone else shares their
configuration, anyone else can just use it (if you really understand what you're copying/referring
now).
As for Flakes, refer to
[Introduction to Flakes - NixOS & Nix Flakes Book](https://nixos-and-flakes.thiscute.world/nixos-with-flakes/introduction-to-flakes)
**Want to know NixOS & Flakes in detail? Looking for a beginner-friendly tutorial or best practices?
You don't have to go through the pain I've experienced again! Check out my
[NixOS & Nix Flakes Book - 🛠️ ❤️ An unofficial & opinionated :book: for beginners](https://github.com/ryan4yin/nixos-and-flakes-book)!**
> If you're using macOS, check out
> [ryan4yin/nix-darwin-kickstarter](https://github.com/ryan4yin/nix-darwin-kickstarter) for a quick
> start.
## Components
| | NixOS(Wayland) |
| -------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| **Window Manager** | [Niri][Niri] |
| **Terminal Emulator** | [Zellij][Zellij] + [foot][foot]/[Kitty][Kitty]/[Alacritty][Alacritty]/[Ghostty][Ghostty] |
| **Status Bar** / **Notifier** / **Launcher** / **lockscreens** | [noctalia-shell][noctalia-shell] |
| **Display Manager** | [tuigreet][tuigreet] |
| **Color Scheme** | [catppuccin-nix][catppuccin-nix] |
| **network management tool** | [NetworkManager][NetworkManager] |
| **Input method framework** | [Fcitx5][Fcitx5] + [rime][rime] + [小鹤音形 flypy][flypy] |
| **System resource monitor** | [Btop][Btop] |
| **File Manager** | [Yazi][Yazi] + [thunar][thunar] |
| **Shell** | [Nushell][Nushell] + [Starship][Starship] |
| **Media Player** | [mpv][mpv] |
| **Editors / IDE** | [Helix][Helix] (primary), [Neovim][Neovim] (backup) — [configuration & usage](./home/base/core/editors/) |
| **Fonts** | [Nerd fonts][Nerd fonts] |
| **Image Viewer** | [imv][imv] |
| **Screenshot Software** | Niri's builtin function |
| **Screen Recording** | [OBS][OBS] |
| **Filesystem & Encryption** | tmpfs as `/`, [Btrfs][Btrfs] subvolumes on a [LUKS][LUKS] encrypted partition for persistent, unlock via passphrase |
| **Secure Boot** | [lanzaboote][lanzaboote] |
Wallpapers: https://github.com/ryan4yin/wallpapers
## Screenshots
![desktop](./_img/2026-01-05_niri-noctalia_desktop.webp)
![overview](./_img/2026-01-04_niri-noctalia_overview.webp)
![nvim](./_img/2026-01-04_niri-noctalia_nvim.webp)
## Editors / IDE
- **Terminal editors:** [./home/base/core/editors/](./home/base/core/editors/) — Helix / Neovim,
`$EDITOR`, docs.
- **VS Code (GUI, Home Manager on NixOS):**
[./home/linux/gui/base/editors.nix](./home/linux/gui/base/editors.nix).
- **LLM coding agents:** [./agents](./agents/) — rules, installers, CLI snippets; see
[./agents/README.md](./agents/README.md).
## Secrets Management
See [./secrets](./secrets) for details.
## How to Deploy this Flake?
<!-- prettier-ignore -->
> :red_circle: **IMPORTANT**: **You should NOT deploy this flake directly on your machine :exclamation:
> It will not succeed.** This flake contains my hardware configuration(such as
> [hardware-configuration.nix](hosts/idols-ai/hardware-configuration.nix),
> [Nvidia Support](https://github.com/ryan4yin/nix-config/blob/v0.1.1/hosts/idols-ai/default.nix#L77-L91),
> etc.) which is not suitable for your hardware, and requires my private secrets repository
> [ryan4yin/nix-secrets](https://github.com/ryan4yin/nix-config/tree/main/secrets) to deploy. You
> may use this repo as a reference to build your own configuration.
For NixOS:
> To deploy this flake from NixOS's official ISO image (purest installation method), please refer to
> [./nixos-installer/](./nixos-installer/)
After installed NixOS with `nix-command` & `flake` enabled, you can deploy this flake with the following command:
```bash
# deploy one of the configuration based on the hostname
sudo nixos-rebuild switch --flake .#ai-niri
# Deploy the niri nixosConfiguration by hostname match
just niri
# or we can deploy with details
just niri debug
sudo nixos-rebuild switch --flake .#nixos-test
```
For macOS:
```bash
# If you are deploying for the first time,
# 1. install nix & homebrew manually.
# 2. prepare the deployment environment with essential packages available
nix-shell -p just nushell
# 3. comment home-manager's code in lib/macosSystem.nix to speed up the first deployment.
# 4. comment out the proxy settings in scripts/darwin_set_proxy.py if the proxy is not ready yet.
# Deploy the darwinConfiguration by hostname match
just local
# deploy with details
just local debug
```
> [What y'all will need when Nix drives you to drink.](https://www.youtube.com/watch?v=Eni9PPPPBpg)
> (copy from hlissner's dotfiles, it really matches my feelings when I first started using NixOS...)
## References
Other dotfiles that inspired me:
- Nix Flakes
- [NixOS-CN/NixOS-CN-telegram](https://github.com/NixOS-CN/NixOS-CN-telegram)
- [notusknot/dotfiles-nix](https://github.com/notusknot/dotfiles-nix)
- [xddxdd/nixos-config](https://github.com/xddxdd/nixos-config)
- [bobbbay/dotfiles](https://github.com/bobbbay/dotfiles)
- [gytis-ivaskevicius/nixfiles](https://github.com/gytis-ivaskevicius/nixfiles)
- [davidtwco/veritas](https://github.com/davidtwco/veritas)
- [gvolpe/nix-config](https://github.com/gvolpe/nix-config)
- [Ruixi-rebirth/flakes](https://github.com/Ruixi-rebirth/flakes)
- [fufexan/dotfiles](https://github.com/fufexan/dotfiles): gtk theme, xdg, git, media, etc.
- [nix-community/srvos](https://github.com/nix-community/srvos): a collection of opinionated and
sharable NixOS configurations for servers
- Modularized NixOS Configuration
- [hlissner/dotfiles](https://github.com/hlissner/dotfiles)
- [viperML/dotfiles](https://github.com/viperML/dotfiles)
- Neovim/AstroNvim
- [maxbrunet/dotfiles](https://github.com/maxbrunet/dotfiles): astronvim with nix flakes.
- Misc
- [1amSimp1e/dots](https://github.com/1amSimp1e/dots)
[Niri]: https://github.com/YaLTeR/niri
[Kitty]: https://github.com/kovidgoyal/kitty
[foot]: https://codeberg.org/dnkl/foot
[Alacritty]: https://github.com/alacritty/alacritty
[Ghostty]: https://github.com/ghostty-org/ghostty
[Nushell]: https://github.com/nushell/nushell
[Starship]: https://github.com/starship/starship
[Fcitx5]: https://github.com/fcitx/fcitx5
[rime]: https://wiki.archlinux.org/title/Rime
[flypy]: https://flypy.cc/
[Btop]: https://github.com/aristocratos/btop
[mpv]: https://github.com/mpv-player/mpv
[Zellij]: https://github.com/zellij-org/zellij
[Helix]: https://github.com/helix-editor/helix
[Neovim]: https://github.com/neovim/neovim
[AstroNvim]: https://github.com/AstroNvim/AstroNvim
[imv]: https://sr.ht/~exec64/imv/
[OBS]: https://obsproject.com
[Nerd fonts]: https://github.com/ryanoasis/nerd-fonts
[catppuccin-nix]: https://github.com/catppuccin/nix
[NetworkManager]: https://wiki.gnome.org/Projects/NetworkManager
[wl-clipboard]: https://github.com/bugaevc/wl-clipboard
[tuigreet]: https://github.com/apognu/tuigreet
[thunar]: https://gitlab.xfce.org/xfce/thunar
[Yazi]: https://github.com/sxyazi/yazi
[Catppuccin]: https://github.com/catppuccin/catppuccin
[Btrfs]: https://btrfs.readthedocs.io
[LUKS]: https://wiki.archlinux.org/title/Dm-crypt/Encrypting_an_entire_system
[lanzaboote]: https://github.com/nix-community/lanzaboote
[noctalia-shell]: https://github.com/noctalia-dev/noctalia-shell
-26
View File
@@ -1,26 +0,0 @@
## How to create & managage KubeVirt's Virtual Machine from this flake?
Use `aquamarine` as an example, first build and upload the virtual machine's qcow2 image to the file
server:
```shell
just upload-vm aquamarine
```
Then create the virtual machine by creating a yaml file at
[ryan4yin/k8s-gitops](https://github.com/ryan4yin/k8s-gitops/tree/main/vms), set the
`spec.dataVolumeTemplates[0].source.http.url` to the uploaded file's URL, and fluxcd will
automatically apply the changes, then a virtual machine named `aquamarine` will be created in the
KubeVirt cluster.
Once the virtual machine `aquamarine` is created, we can deploy updates to it with the following
commands:
```shell
just col aquamarine
just col kubevirt-shoryu
just col k3s-test-1-master-1
```
If you're not familiar with remote deployment, please read this tutorial first:
[Remote Deployment - NixOS & Flakes Book](https://nixos-and-flakes.thiscute.world/best-practices/remote-deployment)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 981 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 581 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 588 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 350 KiB

-85
View File
@@ -1,85 +0,0 @@
# RULES - Global Agent Baseline
This file defines the cross-project baseline for AI coding agents. It focuses on safety, boundaries,
and portable behavior.
## 1) Instruction Priority
Apply instructions in this order:
1. Runtime system/developer instructions
2. User task request
3. Project-local policy (`AGENTS.md`, `CLAUDE.md`, repo docs)
4. This global RULES
If rules conflict, follow the higher-priority source and state the conflict briefly.
## 2) Hard Safety Boundaries (MUST NOT)
- MUST NOT read/write outside the approved workspace.
- MUST NOT perform broad operations on the entire home directory.
- MUST NOT mutate remote Git state unless explicitly requested.
- Examples: `git push`, creating/updating remote PRs/Issues via `gh`.
- MUST NOT auto-run remote-mutating commands unless explicitly requested.
- Examples: `kubectl apply/delete`, `helm upgrade`, `terraform apply`, remote `ssh` mutation.
- MUST NOT use destructive/force/delete options EVEN if explicitly requested.
- Examples: `--force`, `rm -rf`, `git reset --hard`, `gh repo delete`, `terraform destroy`
- MUST NOT expose or commit secrets (tokens, keys, kubeconfig credentials, passwords).
## 3) Security and Secrets Handling
- Never write secret literals into tracked files.
- Use environment variables, secret managers, or placeholders.
- Redact sensitive output in logs and summaries.
- For infra/IaC changes, prefer plan/eval/check before apply/switch.
## 4) Scope Discipline
- Keep changes strictly within requested scope.
- Do not refactor unrelated areas unless user asks.
- Preserve backward compatibility unless a breaking change is explicitly requested.
## 5) Change Hygiene
- Keep diffs minimal and reviewable.
- Group logically related edits together.
- Do not revert user/unrelated changes unless explicitly asked.
- Do not claim verification you did not run.
## 6) Tooling Defaults
- Prefer structural search tools first for code find/replace (`ast-grep`/`jq`/`yq`), then text tools
(`rg`, `fd`).
- Prefer project task runners (`just`, `make`, `task`, `npm scripts`, etc.) over ad-hoc commands
when equivalent.
- If a required command is not already available, use only `nix run`, `flake.nix`/`shell.nix` or
`uv`/`pnpm` to provide it.
- If that is still insufficient, stop and ask the user to prepare the environment instead of using
any other installation method.
- Use `gh` CLI for GitHub operations, especially code/PR/issue search and inspection.
## 7) Environment Defaults
- Primary OS: NixOS.
- Shell: default to `nushell`, `bash` also exists.
## 8) Script Engineering Principles
Treat scripts as interruptible jobs that must be diagnosable and safe to rerun:
- Split workflows into explicit stages; allow running a selected stage via flags/arguments.
- Make reruns idempotent; persist progress after each stage and support resume.
- Cache external data with invalidation strategy to speed retries and improve reproducibility.
- For HTTP flows, separate transport success from business success; support retry/backoff.
- Provide independent verification commands/checks for key outputs (counts, samples, invariants).
## 9) Communication Defaults
- Respond in the language the user is currently using, prefer English & Chinese.
- Code, commands, identifiers, and code comments: English.
- Be concise, concrete, and action-oriented.
## 10) Project Overlay
Project-local policy may add stricter constraints (build/test/deploy/style/ownership/environment).
It must not weaken this baseline.
-59
View File
@@ -1,59 +0,0 @@
# agents
Reusable, symlink-first agent resources shared across projects.
This directory is the canonical source for baseline agent rules and supporting command references.
The primary workflow is to symlink files from here into each agent runtime/config location.
## What this directory contains
- `AGENTS.md`: global baseline rules for coding agents.
- `permissions.md`: permission policies for agent tool access.
- `install-rules.py`: installs the baseline by creating symlinks in supported agent config dirs.
- `install-cli.md`: curated CLI install/update command snippets.
- `install-skills.md`: curated `npx skills` command snippets.
## Core workflow
1. Maintain shared rules in `agents/AGENTS.md`.
2. Define permission policies in `agents/permissions.md`.
3. Run `install-rules.py` to refresh symlinks in local agent homes.
4. Use `install-cli.md` and `install-skills.md` as reference snippets when needed.
## Install baseline rules (symlink-based)
Run:
```bash
python3 agents/install-rules.py
```
Current targets:
- Codex: `AGENTS.md` -> `${CODEX_HOME:-~/.codex}/AGENTS.md`
- OpenCode: `AGENTS.md` -> `${XDG_CONFIG_HOME:-~/.config}/opencode/AGENTS.md`
- Claude Code: `AGENTS.md` -> `~/.claude/CLAUDE.md`
Behavior:
- Each target is handled independently.
- Missing destination directories are skipped.
- Existing destination file/symlink is replaced with a symlink to this repo source file.
## About `install-cli.md` and `install-skills.md`
Use them as snippet libraries:
- review the commands
- select what you need
- run selected commands manually
## Conventions
- Keep files portable and reviewable.
- Keep secrets and machine-specific credentials out of this directory.
- Keep guidance generic enough to reuse across multiple agent environments.
## Goal
Maintain one reusable source of truth for agent setup that stays simple to sync and easy to evolve.
-33
View File
@@ -1,33 +0,0 @@
# Agent CLI Commands
Reference commands for installing and updating agent CLIs. Run only the commands you need.
## Install CLIs
Installed via Nix:
- codex
- cursor-cli
- claude-code
- opencode
Install Manually:
```bash
# kimi-cli
uv tool install --python 3.13 kimi-cli
uv tool upgrade kimi-cli --no-cache
```
## Optional tooling
```bash
# context7: up-to-date docs and code examples for LLMs and agents
npx ctx7 setup
```
## Update npm-installed agent tools
```bash
npm update -g
```
-42
View File
@@ -1,42 +0,0 @@
#!/usr/bin/env python3
import os
import sys
from pathlib import Path
def install_one(target_dir: Path, source_file: Path, target_name: str) -> None:
if not target_dir.exists():
print(f"skipped {target_dir} (not found)")
return
target_file = target_dir / target_name
if target_file.exists() or target_file.is_symlink():
target_file.unlink()
target_file.symlink_to(source_file)
print(f"linked {target_file} -> {source_file}")
def main() -> int:
script_dir = Path(__file__).resolve().parent
agents_file = script_dir / "AGENTS.md"
if not agents_file.is_file():
print(f"Missing source file: {agents_file}", file=sys.stderr)
return 1
codex_dir = Path(os.environ.get("CODEX_HOME", "~/.codex")).expanduser()
xdg_config_home = Path(os.environ.get("XDG_CONFIG_HOME", "~/.config")).expanduser()
opencode_dir = xdg_config_home / "opencode"
claude_dir = Path("~/.claude").expanduser()
install_one(codex_dir, agents_file, "AGENTS.md")
install_one(opencode_dir, agents_file, "AGENTS.md")
install_one(claude_dir, agents_file, "CLAUDE.md")
return 0
if __name__ == "__main__":
raise SystemExit(main())
-63
View File
@@ -1,63 +0,0 @@
# Agent Skills Commands
Reference commands for listing, installing, and updating skills via `npx skills`. Run only the
commands you need.
## Inspect and update installed skills
```bash
# list all installed skills (project + global)
npx skills list
# list only global skills
npx skills ls -g
# check for updates
npx skills check
# update all installed skills
npx skills update
# remove from global scope
npx skills remove --global web-design-guidelines
```
## Discover skills from repositories
```bash
# list skills in a repository
npx skills add vercel-labs/agent-skills --list
```
## Install commonly used skill packs
```bash
# superpowers
npx skills add -g obra/superpowers --agent '*' --skill '*'
# github skills
npx skills add -g github/awesome-copilot --agent '*' --skill 'git-commit' --skill 'gh-cli'
# find skills
npx skills add -g vercel-labs/skills --agent '*'
# anthropic skills
npx skills add -g anthropics/skills --agent '*' --skill 'skill-creator' --skill 'pdf'
```
## Optional packs
```bash
npx skills add -g pbakaus/impeccable --agent '*' --skill '*'
npx skills add -g coreyhaines31/marketingskills --agent '*' --skill '*'
npx skills add -g phuryn/pm-skills --agent '*' --skill '*'
```
References:
- https://github.com/vercel-labs/skills
- https://github.com/pbakaus/impeccable
- https://github.com/coreyhaines31/marketingskills
- https://github.com/phuryn/pm-skills
-190
View File
@@ -1,190 +0,0 @@
# Permissions Configuration
This document records the current permission requirements for AI agents operating in this
repository.
## Scope
| Environment | Policy |
| ------------------------ | ------------------------------------------- |
| **Personal workstation** | Restrictive - protect user's daily workflow |
| **Homelab VMs** | Permissive - agents have full autonomy |
The permissions below apply to **personal workstation** only. For homelab VMs, almost everything is
allowed except destructive operations on production systems.
## Default Policy
| Tool | Permission |
| ---------------- | ---------- |
| `*` (all others) | ask |
## File Read Permissions
| Pattern | Permission |
| --------------- | ---------- |
| `*` (all files) | allow |
| `*.env` | deny |
| `*.env.*` | deny |
| `*.env.example` | allow |
| `*.pem` | deny |
| `*.key` | deny |
| `*kubeconfig*` | deny |
| `.ssh/**` | deny |
| `.aws/**` | deny |
| `.kube/**` | deny |
| `.gnupg/**` | deny |
## Always Allowed Tools
These tools run without prompting:
- `glob`
- `grep`
- `lsp`
- `question`
- `skill`
- `todowrite`
- `webfetch`
- `websearch`
- `codesearch`
- `edit` (covers `write` and `apply_patch`)
## Bash Command Permissions
### Always Allowed (Read-only operations)
**Git:**
- `git status`, `git diff`, `git log`, `git show`, `git branch`, `git remote`
**Kubernetes:**
- `kubectl get`, `kubectl describe`, `kubectl logs`, `kubectl top`
- `kubectl api-resources`, `kubectl api-versions`
- `kubectl config view`, `kubectl config get-contexts`
- `kubectl explain`
- `kubectl kustomize`, `kustomize build`, `kustomize version`
**Terraform:**
- `terraform plan`, `terraform show`, `terraform state list`, `terraform state show`
- `terraform output`, `terraform version`, `terraform providers`, `terraform fmt`
**GitHub CLI:**
- `gh repo view/list`, `gh issue view/list`, `gh pr view/list/diff/checks`
- `gh api`, `gh search`, `gh gist list/view`
- `gh release view/list`, `gh workflow list/view`, `gh run list/view`
- `gh status`, `gh auth status`
**Helm:**
- `helm list`, `helm get`, `helm show`, `helm search`
- `helm repo list`, `helm status`, `helm version`, `helm template`
**Google Cloud:**
- `gcloud * list`, `gcloud * describe`, `gcloud * get-iam-policy`
- `gcloud config list`, `gcloud auth list`, `gcloud version`
**Nix:**
- `nix eval`, `nix build`, `nix flake show`, `nix flake metadata`
- `nix flake check`, `nix flake lock`
- `nix profile list`, `nix profile history`
- `nix store verify`, `nix store ls`, `nix store path-info`
- `nix search`, `nix doctor`, `nix --version`
- `nixos-rebuild build`, `darwin-rebuild build`
- `nom build`
**Just:**
- `just --list`, `just --show`, `just --dry-run`
**Linters & Formatters:**
- `statix check`, `deadnix`, `nixfmt --check`
- `shellcheck`, `hadolint`, `actionlint`
- `ruff check`, `clippy`, `prettier --check`
- `tokei`
**System diagnostics:**
- `systemctl status`, `systemctl list-units`, `systemctl show`
- `journalctl -u`, `journalctl --since`
- `lspci`, `lsusb`, `lsblk`, `df`, `free`, `uptime`, `uname -a`
- `sensors`, `lsof`
**Git (extended):**
- `git tag`, `git blame`, `git reflog`, `git stash list`
- `git lfs status`, `git lfs ls-files`
**Development tools:**
- `go version`, `go env`, `go list`, `go doc`, `go vet`
- `cargo --version`, `cargo tree`, `cargo metadata`
- `python3 --version`, `python3 -m py_compile`
- `node --version`, `pnpm list`, `uv pip list`
**General utilities:**
- `rg`, `fd`, `cp`, `mv`, `chmod`
- `ls`, `cat`, `head`, `tail`, `wc`, `find`, `which`
- `echo`, `pwd`, `date`, `env`, `printenv`
- `file`, `stat`, `du`, `tree`, `bat`, `eza`
- `jq`, `yq`, `tldr`
- `mkdir`, `rmdir`, `grep`
### Requires Confirmation
| Command | Permission |
| ---------- | ---------- |
| `rm *` | ask |
| `rm -rf *` | ask |
### Always Denied
| Command | Permission |
| -------- | ---------- |
| `sudo *` | deny |
## Homelab VM Permissions
For agents running in dedicated homelab VMs, permissions are significantly relaxed:
| Category | Permission |
| -------------------- | --------------------- |
| `bash` | allow (most commands) |
| `edit` | allow |
| `write` | allow |
| `task` | allow |
| `external_directory` | allow |
| `rm` | allow |
**Still restricted in homelab VMs:**
- Production cluster destructive operations (`kubectl delete`, `helm uninstall`)
- Infrastructure teardown (`terraform destroy`)
- Secret exposure in logs
## Other Tool Permissions
| Tool | Permission |
| -------------------- | ---------- |
| `edit` | allow |
| `task` | ask |
| `external_directory` | ask |
| `doom_loop` | deny |
## Summary
- **Default policy**: All tools `ask` — only explicitly whitelisted tools auto-allow
- **File operations**: `read`, `glob`, `grep`, `edit`, `write` all allowed in workspace
- **Nix operations**: Build/eval/flake commands auto-allowed (writes to store only)
- **Linting & formatting**: All check commands auto-allowed
- **System diagnostics**: Read-only system info auto-allowed
- **Sensitive files**: Credentials, keys, and cloud configs are blocked
- **Bash commands**: Read-only ops auto-allowed; `rm` requires confirmation; `sudo` blocked
- **Scope control**: `task` and `external_directory` require approval
-2
View File
@@ -1,2 +0,0 @@
*.key
*.csr
-23
View File
@@ -1,23 +0,0 @@
# My Private PKI / CA
This is my private Private Key Infrastructure (PKI) / Certificate Authority (CA) for my personal
use. It is used to issue certificates for my own servers and services.
## Current Structure
- **ecc-ca.crt** - ECC CA certificate file
- **ecc-ca.srl** - CA serial number file for certificate tracking
- **ecc-csr.conf** - OpenSSL configuration file for certificate signing requests
- **ecc-server.crt** - Server certificate signed by the ECC CA
- **gen-certs.sh** - Shell script to generate certificates automatically
## Security Notes
All private keys (`.key` files) are ignored by git and stored in a private secrets repository. The
public certificates and configuration files are committed to this repository for reference.
## Usage
Run `./gen-certs.sh` to generate new certificates using the ECC CA configuration.
See [../secrets](../secrets/) for the corresponding private key management.
-10
View File
@@ -1,10 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIBajCB8QIJAIwL98is2nQPMAoGCCqGSM49BAMEMB8xHTAbBgNVBAMMFFJ5YW40
WWluJ3MgUm9vdCBDQSAxMB4XDTI0MDQwMzA4NDgzM1oXDTM0MDQwMTA4NDgzM1ow
HzEdMBsGA1UEAwwUUnlhbjRZaW4ncyBSb290IENBIDEwdjAQBgcqhkjOPQIBBgUr
gQQAIgNiAAQ6ixMbsGZ/u/ZnwzOZ49naVL7rQxm9C74SboGytKcYBH03JjC7tgZ3
DylirxSLcTYHHtCz9ajdamP6+sgiGVpUODtfGSO+WmS+gAbLjCS37T41bkUhkx88
JU4NsGhjPXcwCgYIKoZIzj0EAwQDaAAwZQIwDrGLSdO+p/1uywkzqzdM/OnZs8bp
n60uBhUI7EZzDmrouOFeGx+dXYI5yy5AD/qDAjEA7fTQx+jccyOj4dimq1iU9+71
e/gWYg0rexfy/+9dQY6kvwMzv8Lnm6URaRMbE1Q/
-----END CERTIFICATE-----
-1
View File
@@ -1 +0,0 @@
C050420A8E5A3C1E
-22
View File
@@ -1,22 +0,0 @@
[ req ]
prompt = no
req_extensions = v3_ext
distinguished_name = req_distinguished_name
[ req_distinguished_name ]
countryName = US
stateOrProvinceName = NYK
localityName = NYK
organizationName = Ryan4Yin
organizationalUnitName = Ryan4Yin
commonName = writefor.fun # deprecated, use subjectAltName(SAN) instead
emailAddress = rayn4yin@linux.com
[ alt_names ]
DNS.1 = writefor.fun
DNS.2 = *.writefor.fun
[ v3_ext ]
subjectAltName=@alt_names
basicConstraints = CA:false
extendedKeyUsage = serverAuth
-14
View File
@@ -1,14 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICKTCCAa6gAwIBAgIJAMBQQgqOWjweMAoGCCqGSM49BAMEMB8xHTAbBgNVBAMM
FFJ5YW40WWluJ3MgUm9vdCBDQSAxMB4XDTI0MDQwMzA4NDgzM1oXDTM0MDQwMTA4
NDgzM1owgYkxCzAJBgNVBAYTAlVTMQwwCgYDVQQIDANOWUsxDDAKBgNVBAcMA05Z
SzERMA8GA1UECgwIUnlhbjRZaW4xETAPBgNVBAsMCFJ5YW40WWluMRUwEwYDVQQD
DAx3cml0ZWZvci5mdW4xITAfBgkqhkiG9w0BCQEWEnJheW40eWluQGxpbnV4LmNv
bTB2MBAGByqGSM49AgEGBSuBBAAiA2IABCNTYKDq/I99NltQR5eKrrovQXp9BbLV
iuUdYmzFrAh+NC9ikiIqTfDwP+c+7QvDyI3KXu3KI2qPSPdxktZKDUPHK4p2Y2kZ
xKOI2IFTgTqV3uBciyx7ayWPTwBYxsTDmqNLMEkwJwYDVR0RBCAwHoIMd3JpdGVm
b3IuZnVugg4qLndyaXRlZm9yLmZ1bjAJBgNVHRMEAjAAMBMGA1UdJQQMMAoGCCsG
AQUFBwMBMAoGCCqGSM49BAMEA2kAMGYCMQCHw9YkDo15P9mqEObvxSUak8tQmhBB
9wB81Qg4c+JsMCZA1rMUB7GkNJj1Dr9rWLoCMQDSituLzmo/yPLEOrbNV83bj3/I
ikKgobSie3pMXm5ZG7krOXaunyFRR/bIkih2V2Q=
-----END CERTIFICATE-----
-22
View File
@@ -1,22 +0,0 @@
# 1. Generate the private key for Root CA
openssl ecparam -genkey -name secp384r1 -out ecc-ca.key
# 2. Generate the certificate for Root CA with the validity period of 10 years
# using the private key and some basic information
# NOTE: we specify sha512 as the signature algorithm, which is the key point
openssl req -x509 -new -SHA512 -key ecc-ca.key -subj "/CN=Ryan4Yin's Root CA 1" -days 3650 -out ecc-ca.crt
# 3. Generate the private key for web server
openssl ecparam -genkey -name secp384r1 -out ecc-server.key
# 4. Generate the certificate signing request (CSR) for the server certificate
# using the private key and the configuration file ecc-csr.conf
openssl req -new -SHA512 -key ecc-server.key -out ecc-server.csr -config ecc-csr.conf
# 5. Sign the server certificate with the Root CA's certificate and private key
# NOTE: we specify sha512 as the signature algorithm, which is the key point
openssl x509 -req -SHA512 -in ecc-server.csr -CA ecc-ca.crt -CAkey ecc-ca.key \
-CAcreateserial -out ecc-server.crt -days 3650 \
-extensions v3_ext -extfile ecc-csr.conf
# 6. Display the information of the certificates
openssl x509 -noout -text -in ecc-ca.crt
openssl x509 -noout -text -in ecc-server.crt
Generated
+18 -1120
View File
File diff suppressed because it is too large Load Diff
+58 -153
View File
@@ -1,5 +1,5 @@
{
description = "Ryan Yin's nix configuration for both NixOS & macOS";
description = "NixOS configuration of Ryan Yin";
##################################################################################################################
#
@@ -8,176 +8,81 @@
#
##################################################################################################################
outputs = inputs: import ./outputs inputs;
# the nixConfig here only affects the flake itself, not the system configuration!
# for more information, see:
# https://nixos-and-flakes.thiscute.world/nix-store/add-binary-cache-servers
nixConfig = {
# substituers will be appended to the default substituters when fetching packages
# nix com extra-substituters = [munity's cache server
extra-substituters = [
"https://cache.numtide.com"
# "https://nix-gaming.cachix.org"
# "https://nixpkgs-wayland.cachix.org"
# "https://install.determinate.systems"
"https://nix-community.cachix.org"
];
extra-trusted-public-keys = [
"niks3.numtide.com-1:DTx8wZduET09hRmMtKdQDxNNthLQETkc/yaX7M4qK0g="
# "nix-gaming.cachix.org-1:nbjlureqMbRAxR1gJ/f3hxemL9svXaZF/Ees8vCUUs4="
# "nixpkgs-wayland.cachix.org-1:3lwxaILxMRkVhehr5StQprHdEo4IrE8sRho9R9HOLYA="
# "cache.flakehub.com-3:hJuILl5sVK4iKm86JzgdXW12Y2Hwd5G07qKtHTOcDCM="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
];
};
# This is the standard format for flake.nix. `inputs` are the dependencies of the flake,
# Each item in `inputs` will be passed as a parameter to the `outputs` function after being pulled and built.
inputs = {
# There are many ways to reference flake inputs. The most widely used is github:owner/name/reference,
# which represents the GitHub repository URL + branch/commit-id/tag.
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
home-manager.url = "github:nix-community/home-manager/release-25.05";
home-manager.inputs.nixpkgs.follows = "nixpkgs";
# Official NixOS package source, using nixos's unstable branch by default
# Find git commit hash with build status here(3 jobs per day):
# https://hydra.nixos.org/jobset/nixpkgs/unstable
# update via nix flake update nixpkgs --override-input nixpkgs github:NixOS/nixpkgs/<commit-hash>
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.11";
nixpkgs-2505.url = "github:nixos/nixpkgs/nixos-25.05";
# nixpkgs with some custom patches
nixpkgs-patched.url = "github:ryan4yin/nixpkgs/nixos-unstable-patched";
# get some latest packages from the master branch
nixpkgs-master.url = "github:nixos/nixpkgs/master";
# for macos
# nixpkgs-darwin.url = "github:nixos/nixpkgs/nixpkgs-25.11-darwin";
nixpkgs-darwin.url = "github:nixos/nixpkgs/nixpkgs-unstable";
nix-darwin = {
url = "github:lnl7/nix-darwin";
inputs.nixpkgs.follows = "nixpkgs-darwin";
};
# home-manager, used for managing user configuration
home-manager = {
url = "github:nix-community/home-manager/master";
# url = "github:nix-community/home-manager/release-25.11";
# The `follows` keyword in inputs is used for inheritance.
# Here, `inputs.nixpkgs` of home-manager is kept consistent with the `inputs.nixpkgs` of the current flake,
# to avoid problems caused by different versions of nixpkgs dependencies.
inputs.nixpkgs.follows = "nixpkgs";
};
nixvim = {
url = "github:nix-community/nixvim";
inputs.nixpkgs.follows = "nixpkgs";
};
# https://github.com/catppuccin/nix
catppuccin = {
url = "github:catppuccin/nix";
inputs.nixpkgs.follows = "nixpkgs";
};
lanzaboote = {
url = "github:nix-community/lanzaboote/v1.0.0";
inputs.nixpkgs.follows = "nixpkgs";
};
preservation = {
url = "github:nix-community/preservation";
};
# generate iso/qcow2/docker/... image from nixos configuration
nixos-generators = {
url = "github:nix-community/nixos-generators";
inputs.nixpkgs.follows = "nixpkgs";
};
# secrets management
agenix = {
# lock with git commit at May 18, 2025
url = "github:ryantm/agenix/4835b1dc898959d8547a871ef484930675cb47f1";
# replaced with a type-safe reimplementation to get a better error message and less bugs.
# url = "github:ryan4yin/ragenix";
inputs.nixpkgs.follows = "nixpkgs";
};
disko = {
url = "github:nix-community/disko/v1.13.0";
inputs.nixpkgs.follows = "nixpkgs";
};
# add git hooks to format nix code before commit
pre-commit-hooks = {
url = "github:cachix/git-hooks.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
nuenv = {
url = "github:DeterminateSystems/nuenv";
inputs.nixpkgs.follows = "nixpkgs";
};
haumea = {
url = "github:nix-community/haumea/v0.2.2";
inputs.nixpkgs.follows = "nixpkgs";
};
nixpak = {
url = "github:nixpak/nixpak";
inputs.nixpkgs.follows = "nixpkgs";
};
blender-bin = {
url = "github:edolstra/nix-warez?dir=blender";
inputs.nixpkgs.follows = "nixpkgs";
};
nixos-apple-silicon = {
# asahi-6.18.9
url = "github:nix-community/nixos-apple-silicon";
inputs.nixpkgs.follows = "nixpkgs";
};
# AI coding agents
llm-agents.url = "github:numtide/llm-agents.nix";
# -------------- Gaming ---------------------
nix-gaming = {
url = "github:fufexan/nix-gaming";
inputs.nixpkgs.follows = "nixpkgs";
};
######################## Some non-flake repositories #########################################
nu_scripts = {
url = "github:ryan4yin/nu_scripts";
catppuccin-bat = {
url = "github:catppuccin/bat";
flake = false;
};
};
######################## My own repositories #########################################
outputs = inputs @ {
self,
nixpkgs,
home-manager,
...
}: {
nixosConfigurations = {
nixos-test = let
username = "ryan";
specialArgs = {inherit username;};
in
nixpkgs.lib.nixosSystem {
inherit specialArgs;
system = "x86_64-linux";
# my private secrets, it's a private repository, you need to replace it with your own.
# use ssh protocol to authenticate via ssh-agent/ssh-key, and shallow clone to save time
mysecrets = {
url = "git+ssh://git@github.com/ryan4yin/nix-secrets.git?shallow=1";
flake = false;
};
modules = [
./hosts/nixos-test
./users/${username}/nixos.nix
my-asahi-firmware = {
url = "git+ssh://git@github.com/ryan4yin/asahi-firmware.git?shallow=1";
flake = false;
};
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
# my wallpapers
wallpapers = {
url = "github:ryan4yin/wallpapers";
flake = false;
};
home-manager.extraSpecialArgs = inputs // specialArgs;
home-manager.users.${username} = import ./users/${username}/home.nix;
}
];
};
nur-ryan4yin = {
url = "github:ryan4yin/nur-packages";
inputs.nixpkgs.follows = "nixpkgs";
msi-rtx4090 = let
username = "suzi"; # another username for this machine
specialArgs = {inherit username;};
in
nixpkgs.lib.nixosSystem {
inherit specialArgs;
system = "x86_64-linux";
modules = [
./hosts/msi-rtx4090
./users/${username}/nixos.nix
home-manager.nixosModules.home-manager
{
home-manager.useGlobalPkgs = true;
home-manager.useUserPackages = true;
home-manager.extraSpecialArgs = inputs // specialArgs;
home-manager.users.${username} = import ./users/${username}/home.nix;
}
];
};
};
};
}
-115
View File
@@ -1,115 +0,0 @@
# Linux Hardening
> Work in progress.
## Goal
- **System Level**: Protect critical files from being accessed by untrusted applications.
1. Such as browser cookies, SSH keys, etc.
- **Per-App Level**: Prevent untrusted applications(such as closed-source apps) from:
1. Accessing files they shouldn't.
- Such as a malicious application accessing your browser's cookies, SSH Keys, etc.
1. Accessing the network when they don't need to.
1. Accessing hardware devices they don't need.
## Current Structure
### 1. **System Level**
- **AppArmor** (`apparmor/`): AppArmor profiles and configuration
- **Kernel & System Hardening** (`profiles/`): System-wide hardening profiles
### 2. **Per-App Level**
- **Nixpak** (`nixpaks/`): Bubblewrap-based sandboxing for applications
- Firefox configuration
- QQ (Chinese messaging app) configuration
- Modular system with reusable components
- **Firejail** (legacy): SUID-based sandboxing (not used)
- **Bubblewrap** (`bwraps/`): Direct bubblewrap configurations
- WeChat sandboxing configuration
## Current Implementation Status
| Component | Status | Notes |
| ----------------- | --------- | ------------------------------ |
| AppArmor Profiles | 🚧 WIP | Basic structure in place |
| Nixpak Firefox | ✅ Active | Firefox sandboxing via nixpak |
| Nixpak QQ | ✅ Active | QQ application sandboxing |
| Bubblewrap WeChat | ✅ Active | WeChat specific sandboxing |
| System Profiles | 🚧 WIP | Hardened system configurations |
## Directory Structure
```
hardening/
├── README.md
├── apparmor/ # AppArmor security profiles
│ └── default.nix
├── bwraps/ # Direct bubblewrap configurations
│ ├── default.nix
│ └── wechat.nix
├── nixpaks/ # Nixpak application sandboxing
│ ├── default.nix
│ ├── firefox.nix
│ ├── qq.nix
│ └── modules/ # Reusable nixpak modules
│ ├── gui-base.nix
│ └── network.nix
└── profiles/ # System hardening profiles
└── default.nix
```
## Kernel Hardening
- NixOS Kernel Config:
https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/os-specific/linux/kernel/hardened/config.nix
## System Hardening
- NixOS Profile:
https://github.com/NixOS/nixpkgs/blob/nixos-unstable/nixos/modules/profiles/hardened.nix
- Apparmor: [roddhjav/apparmor.d](https://github.com/roddhjav/apparmor.d)
- https://gitlab.com/apparmor/apparmor/-/wikis/Documentation
- AppArmor.d is a set of over 1500 AppArmor profiles whose aim is to confine most Linux based
applications and processes.
- But all the profiles of AppArmor assume a FHS filesystem, which caused all apparmor policies
takes no effect on NixOS.
- Apparmor on NixOS Roadmap:
- https://discourse.nixos.org/t/apparmor-on-nixos-roadmap/57217
- https://github.com/LordGrimmauld/aa-alias-manager
- SELinux: too complex, not recommended for personal use.
## Application Sandboxing
- [Bubblewrap](https://github.com/containers/bubblewrap):
[nixpak](https://github.com/nixpak/nixpak), more secure than firejail, but no batteries included.
- NixOS's FHSEnv is implemented using bubblewrap by default.
- [Firejail](https://github.com/netblue30/firejail/tree/master/etc): A SUID security sandbox with
hundreds of security profiles for many common applications in the default installation.
- https://wiki.nixos.org/wiki/Firejail
- Firejail needs SUID to work, which is considered a security risk -
[Does firejail improve the security of my system?](https://github.com/netblue30/firejail/discussions/4601)
- [Systemd/Hardening](https://wiki.nixos.org/wiki/Systemd/Hardening): Systemd also provides some
sandboxing features.
## NOTE
**Running untrusted code is never safe, kernel hardening & sandboxing cannot change this**.
If you want to run untrusted code, please use a VM & an isolated network environment, which will
provide a much higher level of security.
## References
- [Harden your NixOS workstation - dataswamp](https://dataswamp.org/~solene/2022-01-13-nixos-hardened.html)
- [Linux Insecurities - Madaidans](https://madaidans-insecurities.github.io/linux.html)
- [Sandboxing all programs by default - NixOS Discourse](https://discourse.nixos.org/t/sandboxing-all-programs-by-default/7792)
- [Paranoid NixOS Setup - xeiaso](https://xeiaso.net/blog/paranoid-nixos-2021-07-18/)
- [nix-mineral](https://github.com/cynicsketch/nix-mineral): NixOS module for convenient system
hardening.
- apparmor configs:
- https://github.com/zramctl/dotfiles/blob/4fe177f6984154960942bb47d5a375098ec6ed6a/modules/nixos/security/apparmor.nix#L4
- https://git.grimmauld.de/Grimmauld/grimm-nixos-laptop/src/branch/main/hardening
- Others:
- Directly via `buildFHSUserEnvBubblewrap`:
-59
View File
@@ -1,59 +0,0 @@
{
config,
pkgs,
...
}:
{
services.dbus.apparmor = "enabled";
security.apparmor = {
enable = true;
# kill process that are not confined but have apparmor profiles enabled
killUnconfinedConfinables = true;
packages = with pkgs; [
apparmor-utils
apparmor-profiles
];
# apparmor policies
policies = {
"default_deny" = {
enforce = false;
enable = false;
profile = ''
profile default_deny /** { }
'';
};
"sudo" = {
enforce = false;
enable = false;
profile = ''
${pkgs.sudo}/bin/sudo {
file /** rwlkUx,
}
'';
};
"nix" = {
enforce = false;
enable = false;
profile = ''
${config.nix.package}/bin/nix {
unconfined,
}
'';
};
};
};
environment.systemPackages = with pkgs; [
apparmor-bin-utils
apparmor-profiles
apparmor-parser
libapparmor
apparmor-kernel-patches
apparmor-pam
apparmor-utils
];
}
-9
View File
@@ -1,9 +0,0 @@
{
nixpkgs.overlays = [
(_: super: {
bwraps = {
wechat = super.callPackage ./wechat.nix { };
};
})
];
}
-102
View File
@@ -1,102 +0,0 @@
# - wechat's flatpak manifest: https://github.com/flathub/com.tencent.WeChat/blob/master/com.tencent.WeChat.yaml
# Refer:
# - Flatpak manifest's docs:
# - https://docs.flatpak.org/en/latest/manifests.html
# - https://docs.flatpak.org/en/latest/sandbox-permissions.html
#
# TODO Since appimageTools.wrapAppImage do not support overriding, I have to pack this package myself.
# https://github.com/NixOS/nixpkgs/pull/358977
{
appimageTools,
fetchurl,
stdenvNoCC,
}:
let
pname = "wechat";
# https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/by-name/we/wechat/package.nix
sources = {
# use https://web.archive.org/save to archive the Linux versions
# add `if_` at the end of timestamps to avoid toolbar insertion
# for a more complicated guide, see https://en.wikipedia.org/wiki/Help:Using_the_Wayback_Machine
aarch64-linux = {
version = "4.1.1.4";
src = fetchurl {
url = "https://web.archive.org/web/20260311102559if_/https://dldir1v6.qq.com/weixin/Universal/Linux/WeChatLinux_arm64.AppImage";
hash = "sha256-YlWJxT62tXDaNwYVpsPMC5elFH8fsbI1HjTQn6ePiPo=";
};
};
x86_64-linux = {
version = "4.1.1.4";
src = fetchurl {
url = "https://web.archive.org/web/20260311102439if_/https://dldir1v6.qq.com/weixin/Universal/Linux/WeChatLinux_x86_64.AppImage";
hash = "sha256-XxAvFnlljqurGPDgRr+DnuCKbdVvgXBPh02DLHY3Oz8=";
};
};
};
inherit (stdenvNoCC.hostPlatform) system;
inherit (sources.${system} or (throw "Unsupported system: ${system}")) version src;
# https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/we/wechat/linux.nix
appimageContents = appimageTools.extract {
inherit pname version src;
postExtract = ''
patchelf --replace-needed libtiff.so.5 libtiff.so $out/opt/wechat/wechat
'';
};
in
appimageTools.wrapAppImage {
inherit pname version;
src = appimageContents;
extraInstallCommands = ''
mkdir -p $out/share/applications
cp ${appimageContents}/wechat.desktop $out/share/applications/
mkdir -p $out/share/pixmaps
cp ${appimageContents}/wechat.png $out/share/pixmaps/
substituteInPlace $out/share/applications/wechat.desktop --replace-fail AppRun wechat
'';
# Add these root paths to FHS sandbox to prevent WeChat from accessing them by default
# Adapted from https://aur.archlinux.org/cgit/aur.git/tree/wechat-universal.sh?h=wechat-universal-bwrap
extraPreBwrapCmds = ''
XDG_DOCUMENTS_DIR="''${XDG_DOCUMENTS_DIR:-$(xdg-user-dir DOCUMENTS)}"
if [[ -z "''${XDG_DOCUMENTS_DIR}" ]]; then
echo 'Error: Failed to get XDG_DOCUMENTS_DIR, refuse to continue'
exit 1
fi
WECHAT_DATA_DIR="''${XDG_DOCUMENTS_DIR}/WeChat_Data"
# Using ''${WECHAT_DATA_DIR} as Wechat Data folder
WECHAT_HOME_DIR="''${WECHAT_DATA_DIR}/home"
WECHAT_FILES_DIR="''${WECHAT_DATA_DIR}/xwechat_files"
mkdir -p "''${WECHAT_FILES_DIR}"
mkdir -p "''${WECHAT_HOME_DIR}"
ln -snf "''${WECHAT_FILES_DIR}" "''${WECHAT_HOME_DIR}/xwechat_files"
'';
extraBwrapArgs = [
"--tmpfs /home"
"--tmpfs /root"
# format: --bind <host-path> <sandbox-path>
"--bind \${WECHAT_HOME_DIR} \${HOME}"
"--bind \${WECHAT_FILES_DIR} \${WECHAT_FILES_DIR}"
"--chdir \${HOME}"
# wechat-universal only supports xcb
"--setenv QT_QPA_PLATFORM xcb"
"--setenv QT_AUTO_SCREEN_SCALE_FACTOR 1"
# use fcitx as IME
"--setenv QT_IM_MODULE fcitx"
"--setenv GTK_IM_MODULE fcitx"
];
chdirToPwd = false;
unshareNet = false;
unshareIpc = true;
unsharePid = true;
unshareUts = true;
unshareCgroup = true;
privateTmp = true;
}
-31
View File
@@ -1,31 +0,0 @@
{
pkgs,
pkgs-master,
nixpak,
...
}:
let
callArgs = {
mkNixPak = nixpak.lib.nixpak {
inherit (pkgs) lib;
inherit pkgs;
};
safeBind = sloth: realdir: mapdir: [
(sloth.mkdir (sloth.concat' sloth.appDataDir realdir))
(sloth.concat' sloth.homeDir mapdir)
];
};
wrapper = _pkgs: path: (_pkgs.callPackage path callArgs);
in
{
# Add nixpaked Apps into nixpkgs, and reference them in home-manager or other nixos modules
nixpkgs.overlays = [
(_: super: {
nixpaks = {
qq = wrapper super ./qq.nix;
telegram-desktop = wrapper super ./telegram-desktop.nix;
firefox = wrapper super ./firefox.nix;
};
})
];
}
-127
View File
@@ -1,127 +0,0 @@
# Refer:
# - Flatpak manifest's docs:
# - https://docs.flatpak.org/en/latest/manifests.html
# - https://docs.flatpak.org/en/latest/sandbox-permissions.html
# - Firefox's flatpak manifest: https://hg.mozilla.org/mozilla-central/file/tip/taskcluster/docker/firefox-flatpak/runme.sh#l151
{
lib,
firefox,
mkNixPak,
buildEnv,
makeDesktopItem,
...
}:
let
appId = "org.mozilla.firefox";
wrapped = mkNixPak {
config =
{
config,
sloth,
...
}:
{
app = {
package = firefox;
binPath = "bin/firefox";
};
flatpak.appId = appId;
imports = [
./modules/gui-base.nix
./modules/network.nix
./modules/common.nix
];
bubblewrap = {
# To trace all the home files Firefox accesses, you can use the following nushell command:
# just trace-access firefox
# See the Justfile in the root of this repository for more information.
bind.rw = [
# given the read write permission to the following directories.
# NOTE: sloth.mkdir is used to create the directory if it does not exist!
(sloth.mkdir (sloth.concat' sloth.homeDir "/.mozilla"))
sloth.xdgDocumentsDir
sloth.xdgDownloadDir
sloth.xdgMusicDir
sloth.xdgVideosDir
sloth.xdgPicturesDir
];
bind.ro = [
"/sys/bus/pci"
[
"${config.app.package}/lib/firefox"
"/app/etc/firefox"
]
# ================ for browserpass extension ===============================
"/etc/gnupg"
(sloth.concat' sloth.homeDir "/.gnupg") # gpg's config
(sloth.concat' sloth.homeDir "/.local/share/password-store") # my secrets
(sloth.concat' sloth.runtimeDir "/gnupg") # for access gpg-agent socket
# Unsure
(sloth.concat' sloth.xdgConfigHome "/dconf")
];
sockets = {
x11 = false;
wayland = true;
pipewire = true;
};
};
};
};
exePath = lib.getExe wrapped.config.script;
in
buildEnv {
inherit (wrapped.config.script) name meta passthru;
paths = [
wrapped.config.script
(makeDesktopItem {
name = appId;
desktopName = "Firefox";
genericName = "Firefox Boxed";
comment = "Firefox Browser";
exec = "${exePath} %U";
terminal = false;
icon = "firefox";
startupNotify = true;
startupWMClass = "firefox";
type = "Application";
categories = [
"Network"
"WebBrowser"
];
mimeTypes = [
"text/html"
"text/xml"
"application/xhtml+xml"
"application/vnd.mozilla.xul+xml"
"x-scheme-handler/http"
"x-scheme-handler/https"
];
actions = {
new-private-window = {
name = "New Private Window";
exec = "${exePath} --private-window %U";
};
new-window = {
name = "New Window";
exec = "${exePath} --new-window %U";
};
profile-manager-window = {
name = "Profile Manager";
exec = "${exePath} --ProfileManager";
};
};
extraConfig = {
X-Flatpak = appId;
};
})
];
}
-234
View File
@@ -1,234 +0,0 @@
# https://github.com/mnixry/nixos-config/blob/74913c2b90d06e31170bbbaa0074f915721da224/desktop/packages/nixpaks-common.nix
# https://github.com/Kraftland/portable/blob/09c4a4227538a3f42de208a6ecbdc938ac9c00dd/portable.sh
# https://flatpak.github.io/xdg-desktop-portal/docs/api-reference.html
{
lib,
sloth,
config,
...
}:
let
inherit (config.flatpak) appId;
in
{
config = {
# list all dbus services:
# ls -al /run/current-system/sw/share/dbus-1/services/
# ls -al /etc/profiles/per-user/ryan/share/dbus-1/services/
dbus = {
# `--see`: The bus name can be enumerated by the application.
# `--talk`: The application can send messages to, and receive replies and signals from, the bus name.
# `--own`: The application can own the bus name
policies = {
"${appId}" = "own";
"${appId}.*" = "own";
"org.freedesktop.DBus" = "talk";
"ca.desrt.dconf" = "talk";
"org.freedesktop.appearance" = "talk";
"org.freedesktop.appearance.*" = "talk";
}
// (builtins.listToAttrs (
map (id: lib.nameValuePair "org.kde.StatusNotifierItem-${toString id}-1" "own") (
lib.lists.range 2 29
)
))
// {
# --- MPRIS Media Control ---
# Allows the app to register as a media player. These are derived from the appID.
"org.mpris.MediaPlayer2.${appId}" = "own";
"org.mpris.MediaPlayer2.${appId}.*" = "own";
"org.mpris.MediaPlayer2.${lib.lists.last (lib.strings.splitString "." appId)}" = "own";
"org.mpris.MediaPlayer2.${lib.lists.last (lib.strings.splitString "." appId)}.*" = "own";
# --- General Desktop Integration ---
"com.canonical.AppMenu.Registrar" = "talk"; # For Ubuntu AppMenu
"org.freedesktop.FileManager1" = "talk";
"org.freedesktop.Notifications" = "talk";
"org.kde.StatusNotifierWatcher" = "talk";
"org.gnome.Shell.Screencast" = "talk";
# --- Accessibility (a11y) 无障碍服务 ---
"org.a11y.Bus" = "see";
# --- Portal Access ---
# "org.freedesktop.portal.*" = "talk";
"org.freedesktop.portal.Documents" = "talk";
"org.freedesktop.portal.FileTransfer" = "talk";
"org.freedesktop.portal.FileTransfer.*" = "talk";
"org.freedesktop.portal.Notification" = "talk";
"org.freedesktop.portal.OpenURI" = "talk";
"org.freedesktop.portal.OpenURI.OpenFile" = "talk";
"org.freedesktop.portal.OpenURI.OpenURI" = "talk";
"org.freedesktop.portal.Print" = "talk";
"org.freedesktop.portal.Request" = "see";
# --- Input Method Portals ---
"org.freedesktop.portal.Fcitx" = "talk";
"org.freedesktop.portal.Fcitx.*" = "talk";
"org.freedesktop.portal.IBus" = "talk";
"org.freedesktop.portal.IBus.*" = "talk";
};
# '--call' rules permit specific method calls on D-Bus interfaces.
rules.call = {
# --- Accessibility (a11y) 无障碍服务 ---
"org.a11y.Bus" = [
"org.a11y.Bus.GetAddress@/org/a11y/bus"
"org.freedesktop.DBus.Properties.Get@/org/a11y/bus"
];
# --- General Portal Rules ---
"org.freedesktop.FileManager1" = [ "*" ];
"org.freedesktop.Notifications.*" = [ "*" ];
"org.freedesktop.portal.Documents" = [ "*" ];
"org.freedesktop.portal.FileTransfer" = [ "*" ];
"org.freedesktop.portal.FileTransfer.*" = [ "*" ];
"org.freedesktop.portal.Fcitx" = [ "*" ];
"org.freedesktop.portal.Fcitx.*" = [ "*" ];
"org.freedesktop.portal.IBus" = [ "*" ];
"org.freedesktop.portal.IBus.*" = [ "*" ];
"org.freedesktop.portal.Notification" = [ "*" ];
"org.freedesktop.portal.OpenURI" = [ "*" ];
"org.freedesktop.portal.OpenURI.OpenFile" = [ "*" ];
"org.freedesktop.portal.OpenURI.OpenURI" = [ "*" ];
"org.freedesktop.portal.Print" = [ "*" ];
"org.freedesktop.portal.Request" = [ "*" ];
# --- Main Desktop Portal Interface ---
# A comprehensive list of permissions for interacting with the desktop environment.
"org.freedesktop.portal.Desktop" = [
# Properties & Settings
"org.freedesktop.DBus.Properties.GetAll"
"org.freedesktop.DBus.Properties.Get@/org/freedesktop/portal/desktop"
"org.freedesktop.portal.Session.Close"
"org.freedesktop.portal.Settings.ReadAll"
"org.freedesktop.portal.Settings.Read"
"org.freedesktop.portal.Account.GetUserInformation"
# Network & Proxy
"org.freedesktop.portal.NetworkMonitor"
"org.freedesktop.portal.NetworkMonitor.*"
"org.freedesktop.portal.ProxyResolver.Lookup"
"org.freedesktop.portal.ProxyResolver.Lookup.*"
# Screenshot / Screen Capture & Sharing
"org.freedesktop.portal.ScreenCast"
"org.freedesktop.portal.ScreenCast.*"
"org.freedesktop.portal.Screenshot"
"org.freedesktop.portal.Screenshot.Screenshot"
# Device Access(Camera / USB)
"org.freedesktop.portal.Camera"
"org.freedesktop.portal.Camera.*"
"org.freedesktop.portal.Usb"
"org.freedesktop.portal.Usb.*"
# Remote Desktop
"org.freedesktop.portal.RemoteDesktop"
"org.freedesktop.portal.RemoteDesktop.*"
# File Operations
"org.freedesktop.portal.Documents"
"org.freedesktop.portal.Documents.*"
"org.freedesktop.portal.FileChooser"
"org.freedesktop.portal.FileChooser.*"
"org.freedesktop.portal.FileTransfer"
"org.freedesktop.portal.FileTransfer.*"
# Notifications & Printing
"org.freedesktop.portal.Notification"
"org.freedesktop.portal.Notification.*"
"org.freedesktop.portal.Print"
"org.freedesktop.portal.Print.*"
# Open/Launch Handlers
"org.freedesktop.portal.OpenURI"
"org.freedesktop.portal.OpenURI.*"
"org.freedesktop.portal.Email.ComposeEmail"
# Input Methods
"org.freedesktop.portal.Fcitx"
"org.freedesktop.portal.Fcitx.*"
"org.freedesktop.portal.IBus"
"org.freedesktop.portal.IBus.*"
# Secrets (Keyring)
"org.freedesktop.portal.Secret"
"org.freedesktop.portal.Secret.RetrieveSecret"
# Get/Update GlobalShortcuts
# "org.freedesktop.portal.GlobalShortcuts"
# "org.freedesktop.portal.GlobalShortcuts.*"
# -- get the user's location
# "org.freedesktop.portal.Location"
# "org.freedesktop.portal.Location.*"
# -- inhibit the user session from ending, suspending, idling or getting switched away.
"org.freedesktop.portal.Inhibit"
"org.freedesktop.portal.Inhibit.*"
# Generic Request Fallback
"org.freedesktop.portal.Request"
];
};
# 'broadcast' rules permit receiving signals from D-Bus names.
rules.broadcast = {
"org.freedesktop.portal.*" = [ "@/org/freedesktop/portal/*" ];
};
args = [
"--filter"
"--sloppy-names"
"--log"
];
};
etc.sslCertificates.enable = true;
bubblewrap = {
network = lib.mkDefault true;
sockets = {
wayland = true;
pulse = true;
};
bind.rw = with sloth; [
[
(mkdir appDataDir)
xdgDataHome
]
[
(mkdir appConfigDir)
xdgConfigHome
]
[
(mkdir appCacheDir)
xdgCacheHome
]
(sloth.concat [
sloth.runtimeDir
"/"
(sloth.envOr "WAYLAND_DISPLAY" "no")
])
(sloth.concat' sloth.runtimeDir "/at-spi/bus")
(sloth.concat' sloth.runtimeDir "/gvfsd")
(sloth.concat' sloth.runtimeDir "/dconf")
(sloth.concat' sloth.xdgCacheHome "/fontconfig")
(sloth.concat' sloth.xdgCacheHome "/mesa_shader_cache")
(sloth.concat' sloth.xdgCacheHome "/mesa_shader_cache_db")
(sloth.concat' sloth.xdgCacheHome "/radv_builtin_shaders")
];
bind.ro = [
(sloth.concat' sloth.runtimeDir "/doc")
(sloth.concat' sloth.xdgConfigHome "/kdeglobals")
(sloth.concat' sloth.xdgConfigHome "/gtk-2.0")
(sloth.concat' sloth.xdgConfigHome "/gtk-3.0")
(sloth.concat' sloth.xdgConfigHome "/gtk-4.0")
(sloth.concat' sloth.xdgConfigHome "/fontconfig")
(sloth.concat' sloth.xdgConfigHome "/dconf")
];
bind.dev = [ "/dev/shm" ] ++ (map (id: "/dev/video${toString id}") (lib.lists.range 0 9));
};
};
}
-102
View File
@@ -1,102 +0,0 @@
# https://github.com/nixpak/pkgs/blob/master/pkgs/modules/gui-base.nix
{
config,
lib,
pkgs,
sloth,
...
}:
let
envSuffix = envKey: suffix: sloth.concat' (sloth.env envKey) suffix;
# cursor & icon's theme should be the same as the host's one.
cursorTheme = pkgs.bibata-cursors;
iconTheme = pkgs.papirus-icon-theme;
in
{
config = {
dbus.policies = {
"${config.flatpak.appId}" = "own";
# we add other policies in ./common.nix
};
# https://github.com/nixpak/nixpak/blob/master/modules/gpu.nix
# 1. bind readonly - /run/opengl-driver
# 2. bind device - /dev/dri
gpu = {
enable = lib.mkDefault true;
provider = "nixos";
bundlePackage = pkgs.mesa.drivers; # for amd & intel
};
# https://github.com/nixpak/nixpak/blob/master/modules/gui/fonts.nix
# it works not well, bind system's /etc/fonts directly instead
fonts.enable = false;
# https://github.com/nixpak/nixpak/blob/master/modules/locale.nix
locale.enable = true;
bubblewrap = {
network = lib.mkDefault false;
bind.rw = [
[
(envSuffix "HOME" "/.var/app/${config.flatpak.appId}/cache")
sloth.xdgCacheHome
]
(sloth.concat' sloth.xdgCacheHome "/fontconfig")
(sloth.concat' sloth.xdgCacheHome "/mesa_shader_cache")
(sloth.concat [
(sloth.env "XDG_RUNTIME_DIR")
"/"
(sloth.envOr "WAYLAND_DISPLAY" "no")
])
(envSuffix "XDG_RUNTIME_DIR" "/at-spi/bus")
(envSuffix "XDG_RUNTIME_DIR" "/gvfsd")
(envSuffix "XDG_RUNTIME_DIR" "/pulse")
"/run/dbus"
];
bind.ro = [
(envSuffix "XDG_RUNTIME_DIR" "/doc")
(sloth.concat' sloth.xdgConfigHome "/gtk-2.0")
(sloth.concat' sloth.xdgConfigHome "/gtk-3.0")
(sloth.concat' sloth.xdgConfigHome "/gtk-4.0")
(sloth.concat' sloth.xdgConfigHome "/fontconfig")
"/etc/fonts" # for fontconfig
"/etc/localtime" # this is a symlink to /etc/zoneinfo/xxx
"/etc/zoneinfo"
# Fix: libEGL warning: egl: failed to create dri2 screen
"/etc/egl"
"/etc/static/egl"
];
bind.dev = [
"/dev/shm" # Shared Memory
# seems required when using nvidia as primary gpu
"/dev/nvidia0"
"/dev/nvidiactl"
"/dev/nvidia-modeset"
"/dev/nvidia-uvm"
];
tmpfs = [
"/tmp"
];
env = {
XDG_DATA_DIRS = lib.mkForce (
lib.makeSearchPath "share" [
iconTheme
cursorTheme
pkgs.shared-mime-info
]
);
XCURSOR_PATH = lib.mkForce (
lib.concatStringsSep ":" [
"${cursorTheme}/share/icons"
"${cursorTheme}/share/pixmaps"
]
);
};
};
};
}
-8
View File
@@ -1,8 +0,0 @@
# https://github.com/nixpak/pkgs/blob/master/pkgs/modules/network.nix
{
etc.sslCertificates.enable = true;
bubblewrap = {
bind.ro = [ "/etc/resolv.conf" ];
network = true;
};
}
-79
View File
@@ -1,79 +0,0 @@
# Refer:
# - Flatpak manifest's docs:
# - https://docs.flatpak.org/en/latest/manifests.html
# - https://docs.flatpak.org/en/latest/sandbox-permissions.html
# - QQ's flatpak manifest: https://github.com/flathub/com.qq.QQ/blob/master/com.qq.QQ.yaml
{
lib,
qq,
mkNixPak,
buildEnv,
makeDesktopItem,
...
}:
let
appId = "com.qq.QQ";
wrapped = mkNixPak {
config =
{ sloth, ... }:
{
app = {
package = qq;
binPath = "bin/qq";
};
flatpak.appId = appId;
imports = [
./modules/gui-base.nix
./modules/network.nix
./modules/common.nix
];
bubblewrap = {
# To trace all the home files QQ accesses, you can use the following nushell command:
# just trace-access qq
# See the Justfile in the root of this repository for more information.
bind.rw = [
sloth.xdgDocumentsDir
sloth.xdgDownloadDir
sloth.xdgMusicDir
sloth.xdgVideosDir
sloth.xdgPicturesDir
];
sockets = {
x11 = false;
wayland = true;
pipewire = true;
};
};
};
};
exePath = lib.getExe wrapped.config.script;
in
buildEnv {
inherit (wrapped.config.script) name meta passthru;
paths = [
wrapped.config.script
(makeDesktopItem {
name = appId;
desktopName = "QQ";
genericName = "QQ Boxed";
comment = "Tencent QQ, also known as QQ, is an instant messaging software service and web portal developed by the Chinese technology company Tencent.";
exec = "${exePath} %U";
terminal = false;
icon = "${qq}/share/icons/hicolor/512x512/apps/qq.png";
startupNotify = true;
startupWMClass = "QQ";
type = "Application";
categories = [
"InstantMessaging"
"Network"
];
extraConfig = {
X-Flatpak = appId;
};
})
];
}
-101
View File
@@ -1,101 +0,0 @@
{
lib,
telegram-desktop,
buildEnv,
mkNixPak,
makeDesktopItem,
...
}:
let
appId = "org.telegram.desktop";
wrapped = mkNixPak {
config =
{ sloth, ... }:
{
imports = [
./modules/gui-base.nix
./modules/network.nix
./modules/common.nix
];
app.package = telegram-desktop;
flatpak = {
appId = appId;
};
dbus = {
enable = true;
policies = {
"com.canonical.indicator.application" = "talk";
"org.ayatana.indicator.application" = "talk";
"org.sigxcpu.Feedback" = "talk";
};
};
bubblewrap = {
bind.rw = [
sloth.xdgDocumentsDir
sloth.xdgDownloadDir
sloth.xdgMusicDir
sloth.xdgVideosDir
sloth.xdgPicturesDir
];
sockets = {
x11 = false;
wayland = true;
pipewire = true;
};
};
};
};
exePath = lib.getExe wrapped.config.script;
in
buildEnv {
inherit (wrapped.config.script) name meta passthru;
paths = [
wrapped.config.script
(makeDesktopItem {
name = appId;
desktopName = "Telegram";
comment = "New era of messaging";
tryExec = "${exePath}";
exec = "${exePath} -- %u";
icon = appId;
startupNotify = true;
startupWMClass = appId;
terminal = false;
type = "Application";
categories = [
"Chat"
"Network"
"InstantMessaging"
"Qt"
];
mimeTypes = [
"x-scheme-handler/tg"
"x-scheme-handler/tonsite"
];
keywords = [
"tg"
"chat"
"im"
"messaging"
"messenger"
"sms"
"tdesktop"
];
actions = {
quit = {
name = "Quit Telegram";
exec = "${exePath} -quit";
icon = "application-exit";
};
};
extraConfig = {
X-Flatpak = appId;
DBusActivatable = "true";
SingleMainWindow = "true";
X-GNOME-UsesNotifications = "true";
X-GNOME-SingleWindow = "true";
};
})
];
}
-10
View File
@@ -1,10 +0,0 @@
{ modulesPath, ... }:
{
imports = [
(modulesPath + "/profiles/hardened.nix")
];
# disable coredump that could be exploited later
# and also slow down the system when something crash
systemd.coredump.enable = false;
}
-56
View File
@@ -1,56 +0,0 @@
# Home Manager's Submodules
This directory contains all Home Manager configurations organized by platform and functionality.
## Current Structure
```
home/
├── base/ # Cross-platform home manager configurations
│ ├── core/ # Essential applications and settings
│ │ ├── editors/ # Editor configurations (Neovim, Helix)
│ │ ├── shells/ # Shell configurations (Nushell, Zellij)
│ │ └── ...
│ ├── gui/ # GUI applications and desktop settings
│ │ ├── terminal/ # Terminal emulators (Kitty, Alacritty, etc.)
│ │ └── ...
│ ├── tui/ # Terminal/TUI applications
│ │ ├── editors/ # Heavy editor/tooling pkgs only (`packages.nix`; core editors live under `core/editors`)
│ │ ├── encryption/ # GPG, password-store, etc.
│ │ └── ...
│ └── home.nix # Main home manager entry point
├── linux/ # Linux-specific home manager configurations
│ ├── base/ # Linux base configurations
│ ├── gui/ # Linux GUI applications
│ │ ├── niri/ # Niri window manager
│ │ └── ...
│ ├── editors/ # Linux-specific editors
│ └── ...
├── hosts/ # Host-specific home manager entry modules
│ ├── linux/ # Linux host home modules (ai, shoukei, k3s-*, etc.)
│ └── darwin/ # macOS host home modules (fern, frieren)
└── darwin/ # macOS-specific home manager configurations
├── aerospace/ # macOS window manager
├── proxy/ # Proxy configurations
└── ...
```
## Module Overview
1. **base**: The base module suitable for both Linux and macOS
- Cross-platform applications and settings
- Shared configurations for editors, shells, and essential tools
2. **linux**: Linux-specific configuration
- Desktop environments (Noctalia Shell, Niri compositor)
- Linux-specific GUI applications
- System integration tools
3. **darwin**: macOS-specific configuration
- macOS applications and services
- Platform-specific integrations (Aerospace, Squirrel, etc.)
4. **hosts**: Host entry modules for Home Manager
- Each output should reference only one host home module file
- Host modules are responsible for importing shared stacks (`home/linux/*` or `home/darwin`) and
applying host overrides
-64
View File
@@ -1,64 +0,0 @@
# Home Manager's Base Submodules
This directory contains cross-platform base configurations that are shared between Linux and Darwin
systems.
## Configuration Structure
### Core System
- **core/**: Essential cross-platform configurations
- **core.nix**: Minimal home-manager configuration
- **shells/**: Shell configurations (bash, zsh, fish, nu)
- **editors/**: Helix + Neovim (Home Manager) and usage docs (`README.md` per editor)
- **btop.nix**: System monitoring tools
- **git.nix**: Git configuration and aliases
- **npm.nix**: Node.js package management
- **pip.nix**: Python package management
- **starship.nix**: Cross-shell prompt configuration
- **theme.nix**: Color schemes and theming
- **yazi.nix**: Terminal file manager configuration
- **zellij/**: Terminal multiplexer with custom layouts
### Desktop Environment
- **gui/**: Cross-platform GUI applications and configurations
- **dev-tools.nix**: Development tools and IDEs
- **media.nix**: Media players and utilities
- **terminal/**: Terminal emulator configurations
- **alacritty/**: Alacritty terminal
- **kitty/**: Kitty terminal
- **foot/**: Foot terminal (Linux)
- **ghostty/**: Ghostty terminal
### Terminal Interface
- **tui/**: Terminal-based interface configurations
- **cloud/**: Cloud development tools (Terraform, etc.)
- **container.nix**: Container tools (Docker, Podman)
- **dev-tools.nix**: Terminal-based development tools
- **editors/**: Extra terminal editor Nix (see `core/editors/` for docs and baseline enables)
- **encryption/**: Encryption and security tools
- **gpg/**: GPG key management
- **password-store/**: Password management with pass
- **shell.nix**: Shell environment configurations
- **ssh/**: SSH configuration and management
- **zellij/**: Terminal workspace management
### System Management
- **home.nix**: Main home manager configuration file
## Platform Compatibility
All configurations in this directory are designed to work across:
- **Linux**: All distributions with Nix and Home Manager
- **macOS**: Darwin systems with Home Manager
- **WSL**: Windows Subsystem for Linux
## Usage
These base configurations provide the foundation for both Linux and Darwin systems, ensuring
consistent environments across different platforms while allowing for platform-specific
customizations.
-9
View File
@@ -1,9 +0,0 @@
{
# replacement of htop/nmon
programs.btop = {
enable = true;
settings = {
theme_background = false; # make btop transparent
};
};
}
-99
View File
@@ -1,99 +0,0 @@
{ pkgs, ... }:
{
home.packages = with pkgs; [
# nix related
#
# it provides the command `nom` works just like `nix
# with more details log output
nix-output-monitor
hydra-check # check hydra(nix's build farm) for the build status of a package
nix-index # A small utility to index nix store paths
nix-init # generate nix derivation from url
# https://github.com/nix-community/nix-melt
nix-melt # A TUI flake.lock viewer
# https://github.com/utdemir/nix-tree
nix-tree # A TUI to visualize the dependency graph of a nix derivation
# misc
cowsay
gnupg
caddy # A webserver with automatic HTTPS via Let's Encrypt(replacement of nginx)
# A fast and polyglot tool for code searching, linting, rewriting at large scale
# supported languages: only some mainstream languages currently(do not support nix/nginx/yaml/toml/...)
ast-grep
# other core cli tools are installed at system-level
];
# A modern replacement for ls
# useful in bash/zsh prompt, not in nushell.
programs.eza = {
enable = true;
# do not enable aliases in nushell!
enableNushellIntegration = false;
git = true;
icons = "auto";
};
# a cat(1) clone with syntax highlighting and Git integration.
programs.bat = {
enable = true;
config = {
pager = "less -FR";
};
};
# A command-line fuzzy finder
programs.fzf.enable = true;
# very fast version of tldr in Rust
programs.tealdeer = {
enable = true;
enableAutoUpdates = true;
settings = {
display = {
compact = false;
use_pager = true;
};
updates = {
auto_update = false;
auto_update_interval_hours = 720;
};
};
};
# zoxide is a smarter cd command, inspired by z and autojump.
# It remembers which directories you use most frequently,
# so you can "jump" to them in just a few keystrokes.
# zoxide works on all major shells.
#
# z foo # cd into highest ranked directory matching foo
# z foo bar # cd into highest ranked directory matching foo and bar
# z foo / # cd into a subdirectory starting with foo
#
# z ~/foo # z also works like a regular cd command
# z foo/ # cd into relative path
# z .. # cd one level up
# z - # cd into previous directory
#
# zi foo # cd with interactive selection (using fzf)
#
# z foo<SPACE><TAB> # show interactive completions (zoxide v0.8.0+, bash 4.4+/fish/zsh only)
programs.zoxide = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
enableNushellIntegration = true;
};
# Atuin replaces your existing shell history with a SQLite database,
# and records additional context for your commands.
# Additionally, it provides optional and fully encrypted
# synchronisation of your history between machines, via an Atuin server.
programs.atuin = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
enableNushellIntegration = true;
};
}
-4
View File
@@ -1,4 +0,0 @@
{ mylib, ... }:
{
imports = mylib.scanPaths ./.;
}
-73
View File
@@ -1,73 +0,0 @@
# Editors Glossary
### LSP - Language Server Protocol
> https://en.wikipedia.org/wiki/Language_Server_Protocol
> https://langserver.org/
The Language Server Protocol (LSP) is an open, JSON-RPC-based protocol for use between source code
editors or integrated development environments (IDEs) and servers that provide programming
language-specific features like:
- motions such as go-to-definition, find-references, hover.
- **code completion**
- **marking of warnings and errors**
- **refactoring routines**
- syntax highlighting (use Tree-sitter instead)
- code formatting (use a dedicated formatter instead)
The goal of the protocol is to allow programming language support to be implemented and distributed
independently of any given editor or IDE.
LSP was originally developed for Microsoft Visual Studio Code and is now an open standard. In the
early 2020s LSP quickly became a "norm" for language intelligence tools providers.
### Tree-sitter
> https://tree-sitter.github.io/tree-sitter/
> https://www.reddit.com/r/neovim/comments/1109wgr/treesitter_vs_lsp_differences_ans_overlap/
Tree-sitter is a parser generator tool and an **incremental parsing** library. It can build a
concrete syntax tree for a source file and efficiently update the syntax tree as the source file is
edited.
It is used by many editors and IDEs to provide:
- **syntax highlighting**
- **indentation**
- **creating foldable code regions**
- **Incremental selection**
- **simple refactoring in a single file**
- such as join/split lines, structural editing, cursor motion, etc.
**Treesitter process each file independently**, and it is not aware of the semantics of your code.
For example, it does not know does a function/variable really exist, or what is the type/return-type
of a variable. This is where LSP comes in.
The LSP server parses the code much more deeply and it **not only parses a single file but your
whole project**. So, the LSP server will know whether a function/variable does exist with the same
type/return-type. If it does not, it will mark it as an error.
**LSP does understand the code semantically, while Treesitter only cares about correct syntax**.
#### LSP vs Tree-sitter
- Tree-sitter: lightweight, fast, but limited knowledge of your code. mainly used for **syntax
highlighting, indentation, and folding/refactoring in a single file**.
- LSP: heavy and slow on large projects, but it has a deep understanding of your code. mainly used
for **code completion, refactoring in the projects, errors/warnings, and other semantic-aware
features**.
### Formatter vs Linter
Linting is distinct from Formatting because:
1. **formatting** only restructures how code appears.
1. `prettier` is a popular formatter.
1. **linting** analyzes how the code runs and detects errors, it may also suggest improvements such
as replace `var` with `let` or `const`.
Formatters and Linters process each file independently, they do not need to know about other files
in the project.
-26
View File
@@ -1,26 +0,0 @@
# Editors
Shared editor configuration and **usage notes** for terminal-focused editing.
## Roles
- **Helix** (`helix/`): Primary TUI editor — batteries-included, small attack surface. `$EDITOR` /
`$VISUAL` default to `hx` (`session-env.nix`).
- **Neovim** (`neovim/`): Backup editor — classic vim-style workflow and `:help` when needed. For
privileged edits (`sudoedit`) and other security-sensitive inputs, `$SUDO_EDITOR` is
`nvim --clean`; use that explicitly when `$EDITOR` must avoid user config/plugins.
Terminal layout and files: **Zellij** and **Yazi** live under `core/zellij/` and `core/yazi.nix`
(not in this folder).
## Docs
- [`helix/README.md`](./helix/README.md) — Helix basics, cheatsheet, official doc links, Helix vs
Neovim notes.
- [`neovim/README.md`](./neovim/README.md) — Vim/Neovim basics, cheatsheet, and official doc links.
Nix modules in `helix/` and `neovim/` enable each editor via Home Manager. Language servers and
other heavy editor-related packages are listed in
[`../../tui/editors/`](../../tui/editors/README.md) (imported from `home/base/tui`).
Editor terminology (LSP, tree-sitter): [`Glossary.md`](./Glossary.md).
-4
View File
@@ -1,4 +0,0 @@
{ mylib, ... }:
{
imports = mylib.scanPaths ./.;
}
-209
View File
@@ -1,209 +0,0 @@
# Helix (primary) — Kakoune-style usage
Neovim is powerful and has a very active community. This config still enables Neovim as a **backup**
editor (vim-style muscle memory, `:help`, and occasional plugin workflows).
Helix is the **primary** TUI editor here: opinionated, batteries-included (LSP, tree-sitter, picker,
multi-cursor, surround), and a smaller moving part than a large Neovim plugin stack.
## Tips
1. This flake sets `$EDITOR` / `$VISUAL` to **`hx`** by default. For security-sensitive edits
(privileged files, unfamiliar binaries, secrets), prefer **`nvim --clean`** — `$SUDO_EDITOR` uses
it so `sudoedit` stays minimal; invoke it yourself in other trust-boundary cases.
1. Helix is **selection-first** (like Kakoune): extend a selection, then run an action (`d`, `c`,
`y`, …). A lone cursor is a zero-width selection.
1. Read the official docs before reinventing workflows:
1. <https://docs.helix-editor.com/> — documentation home (links to usage, keymap, configuration).
1. <https://docs.helix-editor.com/usage.html> — modes, buffers, motions overview.
1. <https://docs.helix-editor.com/keymap.html> — full default keybindings.
1. <https://docs.helix-editor.com/commands.html> — typable commands (`:` prompt).
1. <https://docs.helix-editor.com/configuration.html> — `config.toml`, themes, remaps.
1. <https://github.com/helix-editor/helix/wiki> — install tips, language servers, FAQ.
1. Prefer **Zellij** for shells and panes; use **Helix** for buffers and text.
1. On large codebases, navigation is often **by picker** (`Space f`, symbols, workspace search) or
**by LSP** (`g` goto mode), complementing motion-based editing.
1. After **git** operations (`checkout`, `merge`, `pull`, `rebase`) or whenever many files changed
on disk, run **`:reload-all`** (alias **`:rla`**) so every open buffer is refreshed from disk in
one step — much faster than revisiting each file or restarting Helix.
## Tutorial
Run `:tutor` inside Helix, or `hx --tutor` from the shell
([tutor source](https://github.com/helix-editor/helix/blob/master/runtime/tutor)).
## Helix cheatsheet (common keys)
> Full reference: <https://docs.helix-editor.com/keymap.html>
> Typable commands: <https://docs.helix-editor.com/commands.html>
### Terminal related
Zellij shortcuts used often (same idea as in the Neovim notes):
| Action | Zellij shortcut |
| ------------------------- | --------------- |
| Floating terminal | `Ctrl + p + w` |
| Horizontal split terminal | `Ctrl + p + d` |
| Vertical split terminal | `Ctrl + p + n` |
In Helix, `|` / `!` and variants pipe or insert shell output on selections (see **Changes**).
This flakes Helix Home Manager module keeps **almost all default keys**; the only remap is
**`Ctrl+Shift+o`** → jump backward, because Zellij uses **`Ctrl+o`** for Session (see
`home/base/core/editors/helix/default.nix`). For other Zellij clashes, use **locked mode**
(`Ctrl+g`), **`:`** commands, or the built-in **`Space`** menu.
### Command mode (`:`)
> <https://docs.helix-editor.com/commands.html>
| Action | Command examples |
| ---------------------- | -------------------------------------------------------------------- |
| Write / write all | `:w` / `:wa` |
| Quit view / quit all | `:q` / `:qa` — add `!` to discard changes |
| Write and quit | `:wq`, `:x` |
| Write all and quit all | `:wqa`, `:xa` |
| Open file | `:open path`, `:e path` |
| Next / previous buffer | `:bn` / `:bp` (also `gn` / `gp` in normal) |
| Close buffer | `:bc` (add `!` to force) |
| Reload from disk | `:reload` (current buffer); `:reload-all` / **`:rla`** (all buffers) |
| Change directory / pwd | `:cd` / `:pwd` |
| Split open file | `:vs path`, `:hs path` |
### Movement (normal mode)
| Action | Keys / notes |
| --------------------- | --------------------------------------------------- |
| Arrow keys | `h` `j` `k` `l` |
| Words | `w` `b` `e``W` `B` `E` for WORD-style |
| Find char / till char | `f` `F` `t` `T` (not limited to current line) |
| Line / file | `Home` / `End`; `gg` start or goto line; `G` line |
| Half / full page | `Ctrl-u` / `Ctrl-d`; `Ctrl-b` / `Ctrl-f` |
| Jumplist | `Ctrl-o` back, `Ctrl-i` forward; `Ctrl-s` save spot |
### Selection & changes
| Action | Keys / notes |
| ---------------------- | ----------------------------------------------------------------- |
| Extend selections | `v` select mode; motions extend instead of moving |
| Line selection | `x` extend line; `X` line bounds |
| Select all / regex | `%`; `s` regex in selections; `S` split on regex |
| Undo / redo | `u` / `U` |
| Delete / change / yank | `d` / `c` / `y` — acts on selection |
| Paste | `p` / `P`; registers `"` … |
| Insert | `i` `a` `I` `A` `o` `O` |
| Indent / format | `>` / `<`; `=` format (LSP) |
| Case | `~` toggle; lower/upper case via grave / `Alt-grave` (see keymap) |
| Join lines | `J`; `Alt-J` join keeping space |
### Search
| Action | Keys |
| -------------------- | ---------------------------------------- |
| Search / reverse | `/` / `?` |
| Next / prev match | `n` / `N` |
| Selection as pattern | `*` (word bounds); `Alt-*` raw selection |
Use **extend mode** (`v`) with `n` / `N` to add matches to multi-cursors
([keymap](https://docs.helix-editor.com/keymap.html#select--extend-mode)).
### Replace / multi-occur edits
Helix has no vim-style `:%s` with preview. Typical patterns:
- Select matches with `s` or search, then `c` to change all selections at once.
- Workspace-wide search: `Space /` (global search picker).
- Heavy refactors: external tools or another pane (see **Differences** below).
### Goto mode (`g` then …)
| Action | Keys (after `g`) |
| -------------------- | ---------------- |
| File start / end | `g` / `e` |
| Line start / end | `h` / `l` |
| File / URL | `f` |
| First non-whitespace | `s` |
| Definition / refs | `d` / `r` (LSP) |
| Type / impl | `y` / `i` (LSP) |
| Next / prev buffer | `n` / `p` |
Also: `gd` / `gD` definition/declaration-style jumps where bound.
### Match mode (`m` …)
Surround and textobjects: see <https://docs.helix-editor.com/surround.html> and
<https://docs.helix-editor.com/textobjects.html>. Matching bracket: `mm` (tree-sitter).
### Window mode (`Ctrl-w` then …)
| Action | Keys |
| ---------------- | --------------- |
| Next window | `w` |
| Vertical split | `v` |
| Horizontal split | `s` |
| Focus splits | `h` `j` `k` `l` |
| Close / only | `q` / `o` |
### Space mode (`Space` then …)
| Action | Keys |
| -------------------- | ------------------ |
| File picker (roots) | `f` |
| File picker (cwd) | `F` |
| Buffer picker | `b` |
| Global search | `/` |
| Command palette | `?` |
| Hover docs (LSP) | `k` |
| Symbols / workspace | `s` / `S` |
| Diagnostics | `d` / `D` |
| Clipboard yank/paste | `y` / `p` variants |
Picker movement: <https://docs.helix-editor.com/pickers.html>.
### Minor modes from normal
| Mode | Key |
| ----------- | --------- |
| Command | `:` |
| View scroll | `z` / `Z` |
| Goto | `g` |
| Match | `m` |
| Window | `Ctrl-w` |
Some bindings need an **LSP** or **tree-sitter** grammar; see notes on the keymap page.
## Differences between Neovim and Helix
1. Selecting first, then action.
1. Helix: delete 2 words: move/select with `w` … then `d`. You see the selection before the
action.
2. Neovim: delete 2 words: `d` then `2w`. No visual feedback before the action runs.
1. Helix — modern built-in features: LSP, tree-sitter, fuzzy finder, multi-cursors, surround, and
more.
1. The same is available in Neovim, but usually via plugins you choose and maintain.
1. Helix is built in Rust from scratch: smaller codebase, modern defaults. No VimScript, no Lua in
user config.
1. Neovim carries Vim heritage (VimScript) and Lua-heavy customization.
1. Neovim has a huge plugin ecosystem.
1. Helix is newer; a stable plugin system is still evolving:
<https://github.com/helix-editor/helix/pull/8675>
1. Neovim has an integrated terminal (similar in spirit to VS Codes).
1. Helix does not ship one; use Zellij / tmux / terminal features instead.
1. <https://github.com/helix-editor/helix/issues/1976#issuecomment-1091074719>
1. <https://github.com/helix-editor/helix/pull/4649>
1. Helix has no built-in tree panel; pair with **Yazi**, ranger, or Broot and open files from there.
1. A tree view may arrive with plugins later; many users rely on the file picker instead.
1. Global substitution is weaker in Helix; run replacements in another pane (Zellij) or an external
tool when needed.
1. <https://github.com/helix-editor/helix/issues/196>
1. Neovims `:s` with preview remains strong for interactive refactors; external tools (e.g.
<https://github.com/ms-jpq/sad>) can fill gaps in Helix-centric flows.
1. Complexity vs batteries-included tradeoffs:
<https://github.com/helix-editor/helix/discussions/6356>
Using **Helix** (and Neovim when useful) inside **Yazi** and **Zellij** keeps editing, files, and
panes explicit and scriptable — different from a single IDE window, but very composable.
Helix nudges you away from reproducing VS Code/JetBrains inside one process; Neovim remains there
when you want that depth.
-120
View File
@@ -1,120 +0,0 @@
{ pkgs, ... }:
{
programs.helix = {
enable = true;
package = pkgs.helix;
settings = {
editor = {
# Display & cursor
line-number = "relative";
cursorline = true;
color-modes = true;
scrolloff = 8;
# use system clipboard by default
default-yank-register = "+";
# Wrap long lines to the viewport (word-wrap style; does not insert hard line endings)
soft-wrap = {
enable = true;
};
# Completion / formatting
auto-format = true;
preview-completion-insert = true;
completion-timeout = 5;
idle-timeout = 200;
end-of-line-diagnostics = "hint";
# Save to disk on focus loss and after idle (helps LSP see disk changes)
auto-save = {
focus-lost = true;
after-delay = {
enable = true;
timeout = 2000;
};
};
# LSP: inlay hints, signature help, progress / messages in status area
lsp = {
display-messages = true;
display-progress-messages = true;
display-inlay-hints = true;
auto-signature-help = true;
};
inline-diagnostics = {
cursor-line = "hint";
other-lines = "disable";
};
# Buffers tab strip, menu borders, status line layout
bufferline = "multiple";
popup-border = "menu";
statusline = {
left = [
"mode"
"spinner"
"version-control"
"file-name"
"read-only-indicator"
"file-modification-indicator"
];
center = [ ];
right = [
"workspace-diagnostics"
"diagnostics"
"selections"
"position"
"position-percentage"
"file-type"
"file-encoding"
"file-line-ending"
];
separator = "";
diagnostics = [
"error"
"warning"
"info"
];
workspace-diagnostics = [
"error"
"warning"
];
mode = {
normal = "NORMAL";
insert = "INSERT";
select = "SELECT";
};
};
# Show dotfiles in picker (project-wide ignores still apply)
file-picker.hidden = false;
cursor-shape = {
insert = "bar";
normal = "block";
select = "underline";
};
indent-guides.render = true;
};
keys.normal = {
space.space = ":reload-all";
esc = [
"collapse_selection"
"keep_primary_selection"
];
space.w = ":w";
space.q = ":q";
# useful vim keybindings
"$" = "goto_line_end";
"0" = "goto_line_start";
# Ctrl+o opens Zellij Session
"C-S-o" = "jump_backward";
};
};
};
}
-180
View File
@@ -1,180 +0,0 @@
# Neovim (backup) — vim-style usage
Primary day-to-day editing is **Helix**; this file is the **vim/Neovim** quick reference and doc
pointers for when you reach for Neovim as a backup.
## Tips
1. Many motions already exist in vim — check vim/Neovim docs before adding plugins or reinventing
wheels.
1. For deeper skill, read the official docs:
1. <https://vimhelp.org/> — vim help.
1. <https://neovim.io/doc/user/> — Neovim user manual.
1. Prefer **Zellij** for shells and panes; use **Helix** or **Neovim** for buffers and text.
1. Two powerful navigation modes on large codebases:
1. **By path** — when you know the tree layout.
1. **By content** — when you know what the code says.
## Tutorial
Type `:tutor` (or `:Tutor` in Neovim) for the built-in vim tutorial.
## Vim cheatsheet (common keys)
> For a fuller reference: <https://vimhelp.org/quickref.txt.html>
Emacs Evil, Neovim, and vim share the motions below.
### Terminal related
Zellij shortcuts used often:
| Action | Zellij shortcut |
| ------------------------- | --------------- |
| Floating terminal | `Ctrl + p + w` |
| Horizontal split terminal | `Ctrl + p + d` |
| Vertical split terminal | `Ctrl + p + n` |
| Run a shell command | `!xxx` |
### File management
> <https://neovim.io/doc/user/usr_22.html>
> <https://vimhelp.org/editing.txt.html>
| Action | Command |
| ----------------------------- | -------------------------------------------- |
| Save selection to a file | `:w filename` (shows `:'<,'>w filename`) |
| Save and close current buffer | `:wq` |
| Save all buffers | `:wa` |
| Save and close all buffers | `:wqa` |
| Edit a file | `:e filename` (or `:e <TAB>` for completion) |
| Browse files | `:Ex` or `:e .` |
| Discard changes and reload | `:e!` |
### Motion
> <https://vimhelp.org/motion.txt.html>
| Action | Command |
| ----------------------------------- | --------------------------------------- |
| Start / end of buffer | `gg` / `G` |
| Go to line 5 | `5gg` / `5G` |
| Left / down / up / right | `h` `j` `k` `l` (counts like `5j` work) |
| Jump to matchpairs `()`, `{}`, `[]` | `%` |
| Start / end of line | `0` / `$` |
| Sentence forward / backward | `(` / `)` |
| Paragraph forward / backward | `{` / `}` |
| Section forward / backward | `[[` / `]]` |
| Jump to marks | `'` + mark (Neovim may prompt) |
Text objects:
- **Sentence**: ends at `.` `!` `?` plus line end or space/tab.
- **Paragraph**: ends at a blank line.
- **Section**: between section headers; `[[` / `]]` often stop at `{` in column 1 (handy in
C/Go/Java).
### Text manipulation
Basics:
| Action | Command |
| ----------------------------- | ------------------------------ |
| Delete character under cursor | `x` |
| Put (paste) | `p` |
| Delete operator + motion | `d` |
| Undo word (insert) | `CTRL-w` |
| Undo line (insert) | `CTRL-u` |
| Undo change | `u` |
| Redo | `Ctrl-r` |
| Repeat previous insert | `Ctrl-a` |
| Repeat last change | `.` |
| Toggle case | `~` |
| Uppercase (visual) | `U` |
| Lowercase (visual) | `u` |
| Align selection | `:center` / `:left` / `:right` |
Misc:
| Action | Shortcut |
| ------------------------ | ----------- |
| Character-wise visual | `v` |
| Line-wise visual | `V` |
| Block visual | `<Ctrl-v>` |
| Fold close / open | `zc` / `zo` |
| Go to definition | `gd` |
| Go to references | `gD` |
| Comment line (if mapped) | e.g. `gcc` |
| Action | Command |
| ----------------------------------- | -------------- |
| Sort lines | `:sort` |
| Join lines | `:join` or `J` |
| Join without spaces | `:join!` |
| Insert at line start / end | `I` / `A` |
| Delete to end of line | `D` |
| Change to end of line (into insert) | `C` |
Advanced patterns:
- Append to many lines: `:normal A<text>` (often after visual-block `Ctrl-v`).
- Neovim may pad short lines with spaces when block-appending past EOL.
- Delete last character on many lines: `:normal $x` over a visual selection.
- Delete last word on many lines: `:normal $bD`.
### Search
| Action | Command |
| --------------------------------- | ------- |
| Search forward / backward | `/` `?` |
| Repeat search same / opposite dir | `n` `N` |
### Find and replace
| Action | Command |
| ------------------- | ---------------------------------- |
| In visual selection | `:s/old/new/g` |
| Current line | same |
| Whole buffer | `:%s/old/new/g` |
| Regex example | `:%s@\vhttp://(\w+)@https://\1@gc` |
Notes:
- `\v` — “very magic”, less backslash noise in the pattern.
- `\1` — first capture group.
### Specific line ranges
| Action | Command examples |
| --------------------- | ------------------------------------ |
| Lines 10end | `:10,$s/old/new/g` or `:10,$s@^@#@g` |
| Lines 1020 | `:10,20s/old/new/g` |
| Strip trailing spaces | `:%s/\s\+$//g` |
Flags: `g` all matches in range, `c` confirm each, `i` ignore case.
### Buffers, windows, tabs
> <https://neovim.io/doc/user/usr_08.html>
> <https://vimhelp.org/windows.txt.html>
- **Buffer** — in-memory text for a file.
- **Window** — viewport on a buffer.
- **Tab page** — layout of windows.
| Action | Command |
| ------------------ | ------------------------------ |
| Horizontal split | `:sp` or `:sp filename` |
| Vertical split | `:vs` or `:vs filename` |
| Next / prev window | `Ctrl-w w` or `Ctrl-w h/j/k/l` |
| List buffers | `:ls` |
| Next / prev buffer | `]b` / `[b` or `:bn` / `:bp` |
| New tab | `:tabnew` |
| Next / prev tab | `gt` / `gT` |
### History
| Action | Command |
| --------------- | ------- |
| Command history | `q:` |
| Search history | `q/` |
-96
View File
@@ -1,96 +0,0 @@
{ config, nixvim, ... }:
{
imports = [ nixvim.homeModules.nixvim ];
home.shellAliases = {
vi = "nvim";
vim = "nvim";
};
programs.nixvim = {
enable = true;
clipboard.providers.wl-copy.enable = true;
opts = {
number = true;
relativenumber = true;
cursorline = true;
signcolumn = "auto";
clipboard = "unnamedplus";
scrolloff = 8;
swapfile = false;
title = true;
titlelen = 20;
smartindent = false;
mouse = "a";
undofile = true;
ignorecase = true;
smartcase = true;
splitbelow = true;
splitright = true;
updatetime = 300;
wrap = true;
linebreak = true;
};
colorschemes.catppuccin = {
enable = true;
settings = {
transparent_background = true;
};
};
plugins.lsp.servers = {
nixd.enable = true;
"rust_analyzer" = {
enable = true;
installCargo = false;
installRustc = false;
};
gopls.enable = true;
pyright.enable = true;
bashls.enable = true;
};
plugins.treesitter = {
enable = true;
grammarPackages = with config.programs.nixvim.plugins.treesitter.package.builtGrammars; [
bash
json
lua
make
markdown
nix
regex
rust
go
python
toml
vim
vimdoc
xml
yaml
nu
];
};
plugins.neo-tree = {
enable = true;
settings = {
filesystem = {
filtered_items = {
visible = true;
hide_dotfiles = false;
hide_gitignored = false;
};
follow_current_file = {
enabled = true;
leave_dirs_open = false;
};
};
};
};
};
}
-9
View File
@@ -1,9 +0,0 @@
# Default interactive editor is Helix (`hx`). For trust-boundary edits (e.g. `sudoedit`,
# secrets, unfamiliar payloads), prefer `nvim --clean` — wired via `SUDO_EDITOR`.
{
home.sessionVariables = {
EDITOR = "hx";
VISUAL = "hx";
SUDO_EDITOR = "nvim --clean";
};
}
-111
View File
@@ -1,111 +0,0 @@
{
config,
lib,
pkgs,
myvars,
...
}:
{
# `programs.git` will generate the config file: ~/.config/git/config
# to make git use this config file, `~/.gitconfig` should not exist!
#
# https://git-scm.com/docs/git-config#Documentation/git-config.txt---global
home.activation.removeExistingGitconfig = lib.hm.dag.entryBefore [ "checkLinkTargets" ] ''
rm -f ${config.home.homeDirectory}/.gitconfig
'';
# GitHub CLI tool
# https://cli.github.com/manual/
programs.gh.enable = true;
programs.git = {
enable = true;
lfs.enable = true;
signing.format = "openpgp";
# signing = {
# key = "xxx";
# signByDefault = true;
# };
includes = [
{
# use different email & name for work:
#
# [user]
# email = "xxx@xxx.com"
# name = "Ryan Yin"
path = "~/work/.gitconfig";
condition = "gitdir:~/work/";
}
];
settings = {
user.email = myvars.useremail;
user.name = myvars.userfullname;
init.defaultBranch = "main";
trim.bases = "develop,master,main"; # for git-trim
push.autoSetupRemote = true;
pull.rebase = true;
log.date = "iso"; # use iso format for date
# replace https with ssh
url = {
"ssh://git@github.com/ryan4yin" = {
insteadOf = "https://github.com/ryan4yin";
};
# "ssh://git@bitbucket.com/ryan4yin" = {
# insteadOf = "https://bitbucket.com/ryan4yin";
# };
};
alias = {
# common aliases
br = "branch";
co = "checkout";
st = "status";
ls = "log --pretty=format:\"%C(yellow)%h%Cred%d\\\\ %Creset%s%Cblue\\\\ [%cn]\" --decorate";
ll = "log --pretty=format:\"%C(yellow)%h%Cred%d\\\\ %Creset%s%Cblue\\\\ [%cn]\" --decorate --numstat";
cm = "commit -m"; # commit via `git cm <message>`
ca = "commit -am"; # commit all changes via `git ca <message>`
dc = "diff --cached";
amend = "commit --amend -m"; # amend commit message via `git amend <message>`
unstage = "reset HEAD --"; # unstage file via `git unstage <file>`
merged = "branch --merged"; # list merged(into HEAD) branches via `git merged`
unmerged = "branch --no-merged"; # list unmerged(into HEAD) branches via `git unmerged`
nonexist = "remote prune origin --dry-run"; # list non-exist(remote) branches via `git nonexist`
# delete merged branches except master & dev & staging
# `!` indicates it's a shell script, not a git subcommand
delmerged = ''! git branch --merged | egrep -v "(^\*|main|master|dev|staging)" | xargs git branch -d'';
# delete non-exist(remote) branches
delnonexist = "remote prune origin";
# aliases for submodule
update = "submodule update --init --recursive";
foreach = "submodule foreach";
};
};
};
# A syntax-highlighting pager for git, diff, grep, and blame output
programs.delta = {
enable = true;
enableGitIntegration = true;
options = {
diff-so-fancy = true;
line-numbers = true;
true-color = "always";
# features => named groups of settings, used to keep related settings organized
# features = "";
};
};
# Git terminal UI (written in go).
programs.lazygit.enable = true;
# Yet another Git TUI (written in rust).
programs.gitui.enable = false;
}
-9
View File
@@ -1,9 +0,0 @@
{ config, ... }:
{
# 1. make `npm install -g <pkg>` happey
# 2. set min-release-age for security
home.file.".npmrc".text = ''
prefix=${config.home.homeDirectory}/.npm
min-release-age=7
'';
}
-7
View File
@@ -1,7 +0,0 @@
_: {
# use mirror for pip install
xdg.configFile."pip/pip.conf".text = ''
[global]
index-url = https://mirrors.bfsu.edu.cn/pypi/web/simple
'';
}
-175
View File
@@ -1,175 +0,0 @@
# Based on the default config generated by:
# ```
# config nu --default
# ```
#
# Nushell Config File Documentation
#
# Warning: This file is intended for documentation purposes only and
# is not intended to be used as an actual configuration file as-is.
#
# version = "0.103.0"
#
# A `config.nu` file is used to override default Nushell settings,
# define (or import) custom commands, or run any other startup tasks.
# See https://www.nushell.sh/book/configuration.html
#
# Nushell sets "sensible defaults" for most configuration settings, so
# the user's `config.nu` only needs to override these defaults if
# desired.
#
# This file serves as simple "in-shell" documentation for these
# settings, or you can view a more complete discussion online at:
# https://nushell.sh/book/configuration
#
# You can pretty-print and page this file using:
# config nu --doc | nu-highlight | less -R
# $env.config
# -----------
# The $env.config environment variable is a record containing most Nushell
# configuration settings. Keep in mind that, as a record, setting it to a
# new record will remove any keys which aren't in the new record. Nushell
# will then automatically merge in the internal defaults for missing keys.
#
# The same holds true for keys in the $env.config which are also records
# or lists.
#
# For this reason, settings are typically changed by updating the value of
# a particular key. Merging a new config record is also possible. See the
# Configuration chapter of the book for more information.
$env.config.history.file_format = "sqlite"
$env.config.history.max_size = 5_000_000
# isolation (bool):
# `true`: New history from other currently-open Nushell sessions is not
# seen when scrolling through the history using PrevHistory (typically
# the Up key) or NextHistory (Down key)
# `false`: All commands entered in other Nushell sessions will be mixed with
# those from the current shell.
# Note: Older history items (from before the current shell was started) are
# always shown.
# This setting only applies to SQLite-backed history
$env.config.history.isolation = true
# ----------------------
# Miscellaneous Settings
# ----------------------
# show_banner (bool): Enable or disable the welcome banner at startup
$env.config.show_banner = false
# rm.always_trash (bool):
# true: rm behaves as if the --trash/-t option is specified
# false: rm behaves as if the --permanent/-p option is specified (default)
$env.config.rm.always_trash = true
# recursion_limit (int): how many times a command can call itself recursively
# before an error will be generated.
$env.config.recursion_limit = 50
# ---------------------------
# Commandline Editor Settings
# ---------------------------
# edit_mode (string) "vi" or "emacs" sets the editing behavior of Reedline
$env.config.edit_mode = "vi"
# Command that will be used to edit the current line buffer with Ctrl+O.
# If unset, uses $env.VISUAL and then $env.EDITOR ($EDITOR is `hx` via session-env).
#
$env.config.buffer_editor = ["hx"]
# cursor_shape_* (string)
# -----------------------
# The following variables accept a string from the following selections:
# "block", "underscore", "line", "blink_block", "blink_underscore", "blink_line", or "inherit"
# "inherit" skips setting cursor shape and uses the current terminal setting.
$env.config.cursor_shape.emacs = "inherit" # Cursor shape in emacs mode
$env.config.cursor_shape.vi_insert = "block" # Cursor shape in vi-insert mode
$env.config.cursor_shape.vi_normal = "underscore" # Cursor shape in normal vi mode
# --------------------
# Terminal Integration
# --------------------
# Nushell can output a number of escape codes to enable advanced features in Terminal Emulators
# that support them. Settings in this section enable or disable these features in Nushell.
# Features aren't supported by your Terminal can be disabled. Features can also be disabled,
# of course, if there is a conflict between the Nushell and Terminal's implementation.
# use_kitty_protocol (bool):
# A keyboard enhancement protocol supported by the Kitty Terminal. Additional keybindings are
# available when using this protocol in a supported terminal. For example, without this protocol,
# Ctrl+I is interpreted as the Tab Key. With this protocol, Ctrl+I and Tab can be mapped separately.
$env.config.use_kitty_protocol = false
# osc2 (bool):
# When true, the current directory and running command are shown in the terminal tab/window title.
# Also abbreviates the directory name by prepending ~ to the home directory and its subdirectories.
$env.config.shell_integration.osc2 = true
# osc7 (bool):
# Nushell will report the current directory to the terminal using OSC 7. This is useful when
# spawning new tabs in the same directory.
$env.config.shell_integration.osc7 = true
# osc9_9 (bool):
# Enables/Disables OSC 9;9 support, originally a ConEmu terminal feature. This is an
# alternative to OSC 7 which also communicates the current path to the terminal.
$env.config.shell_integration.osc9_9 = false
# osc8 (bool):
# When true, the `ls` command will generate clickable links that can be launched in another
# application by the terminal.
# Note: This setting replaces the now deprecated `ls.clickable_links`
$env.config.shell_integration.osc8 = true
# osc133 (bool):
# true/false to enable/disable OSC 133 support, a set of several escape sequences which
# report the (1) starting location of the prompt, (2) ending location of the prompt,
# (3) starting location of the command output, and (4) the exit code of the command.
# originating with Final Term. These sequences report information regarding the prompt
# location as well as command status to the terminal. This enables advanced features in
# some terminals, including the ability to provide separate background colors for the
# command vs. the output, collapsible output, or keybindings to scroll between prompts.
$env.config.shell_integration.osc133 = true
# osc633 (bool):
# true/false to enable/disable OSC 633, an extension to OSC 133 for Visual Studio Code
$env.config.shell_integration.osc633 = true
# NU_LIB_DIRS
# -----------
# Directories in this constant are searched by the
# `use` and `source` commands.
#
# By default, the `scripts` subdirectory of the default configuration
# directory is included:
const NU_LIB_DIRS = [
($nu.default-config-dir | path join 'scripts') # add <nushell-config-dir>/scripts
($nu.data-dir | path join 'completions') # default home for nushell completions
]
# NU_PLUGIN_DIRS
# --------------
# Directories to search for plugin binaries when calling add.
# By default, the `plugins` subdirectory of the default configuration
# directory is included:
const NU_PLUGIN_DIRS = [
($nu.default-config-dir | path join 'plugins') # add <nushell-config-dir>/plugins
]
# As with NU_LIB_DIRS, an $env.NU_PLUGIN_DIRS is searched after the constant version
# The `path add` function from the Standard Library also provides
# a convenience method for prepending to the path:
use std/util "path add"
path add "~/.local/bin"
# You can remove duplicate directories from the path using:
$env.PATH = ($env.PATH | uniq)
-33
View File
@@ -1,33 +0,0 @@
{ config, ... }:
let
shellAliases = {
k = "kubectl";
urldecode = "python3 -c 'import sys, urllib.parse as ul; print(ul.unquote_plus(sys.stdin.read()))'";
urlencode = "python3 -c 'import sys, urllib.parse as ul; print(ul.quote_plus(sys.stdin.read()))'";
};
localBin = "${config.home.homeDirectory}/.local/bin";
goBin = "${config.home.homeDirectory}/go/bin";
rustBin = "${config.home.homeDirectory}/.cargo/bin";
npmBin = "${config.home.homeDirectory}/.npm/bin";
in
{
programs.bash = {
enable = true;
enableCompletion = true;
bashrcExtra = ''
export PATH="$PATH:${localBin}:${goBin}:${rustBin}:${npmBin}"
'';
};
# NOTE: only works in bash/zsh, not nushell
home.shellAliases = shellAliases;
# NOTE: nushell will be launched in bash, so it can inherit all the eenvironment variables.
programs.nushell = {
enable = true;
configFile.source = ./config.nu;
inherit shellAliases;
};
}
-29
View File
@@ -1,29 +0,0 @@
{
programs.starship = {
enable = true;
enableBashIntegration = true;
enableZshIntegration = true;
enableNushellIntegration = true;
# https://starship.rs/config/
settings = {
# Get editor completions based on the config schema
"$schema" = "https://starship.rs/config-schema.json";
character = {
success_symbol = "[](bold green)";
error_symbol = "[](bold red)";
};
# I never rely on the defaults, so this module is useless to me—disabled.
# I prefer adding --project, --region to very gcloud/aws command.
aws.disabled = true;
gcloud.disabled = true;
kubernetes = {
symbol = "";
disabled = false;
};
os.disabled = false;
};
};
}
-16
View File
@@ -1,16 +0,0 @@
{ catppuccin, ... }:
{
# https://github.com/catppuccin/nix
imports = [
catppuccin.homeModules.catppuccin
];
catppuccin = {
# The default `enable` value for all available programs.
enable = true;
# one of "latte", "frappe", "macchiato", "mocha"
flavor = "mocha";
# one of "blue", "flamingo", "green", "lavender", "maroon", "mauve", "peach", "pink", "red", "rosewater", "sapphire", "sky", "teal", "yellow"
accent = "pink";
};
}
-18
View File
@@ -1,18 +0,0 @@
{ pkgs, ... }:
{
# terminal file manager
programs.yazi = {
enable = true;
package = pkgs.yazi;
# Changing working directory when exiting Yazi
enableBashIntegration = true;
enableNushellIntegration = true;
shellWrapperName = "yy";
settings = {
mgr = {
show_hidden = true;
sort_dir_first = true;
};
};
};
}
-13
View File
@@ -1,13 +0,0 @@
let
shellAliases = {
"zj" = "zellij";
};
in
{
programs.zellij = {
enable = true;
};
# only works in bash/zsh, not nushell
home.shellAliases = shellAliases;
programs.nushell.shellAliases = shellAliases;
}
-4
View File
@@ -1,4 +0,0 @@
{ mylib, ... }:
{
imports = mylib.scanPaths ./.;
}
-20
View File
@@ -1,20 +0,0 @@
{ pkgs, llm-agents, ... }:
{
home.packages =
with pkgs;
[
mitmproxy # http/https proxy tool
wireshark # network analyzer
]
# AI Agent Tools
++ (with llm-agents.packages.${pkgs.stdenv.hostPlatform.system}; [
# Agents
codex
cursor-cli
claude-code
opencode
# Utilities
rtk # CLI proxy that reduces LLM token consumption
]);
}
-16
View File
@@ -1,16 +0,0 @@
{
pkgs,
config,
...
}:
# processing audio/video
{
home.packages = with pkgs; [
ffmpeg-full
# images
viu # Terminal image viewer with native support for iTerm and Kitty
imagemagick
graphviz
];
}
-84
View File
@@ -1,84 +0,0 @@
# Terminal Emulators
I used to spend a lot of time on terminal emulators, to make them match my taste, but now I found
that it's not worth it, **Zellij can provide a user-friendly and unified user experience for all
terminal emulators! without any pain**!
Currently, I only use the most basic features of terminal emulators, such as true color, graphics
protocol, etc. Other features such as tabs, scrollback buffer, select/search/copy, etc, are all
provided by zellij!
My current terminal emulators are:
1. kitty: My main terminal emulator.
1. to select/copy a large mount of text, We should do some tricks via kitty's `scrollback_pager`
with neovim, it's really painful: <https://github.com/kovidgoyal/kitty/issues/719>
2. foot: A fast, lightweight and minimalistic Wayland terminal emulator.
1. foot only do the things a terminal emulator should do, no more, no less.
1. It's really suitable for tiling window manager or zellij users!
3. alacritty: A cross-platform, GPU-accelerated terminal emulator.
1. alacritty is really fast, I use it as a backup terminal emulator on all my desktops.
## 'xterm-kitty': unknown terminal type when `ssh` into a remote host or `sudo xxx`
> https://sw.kovidgoyal.net/kitty/faq/#i-get-errors-about-the-terminal-being-unknown-or-opening-the-terminal-failing-or-functional-keys-like-arrow-keys-don-t-work
> https://wezfurlong.org/wezterm/config/lua/config/term.html
kitty set `TERM` to `xterm-kitty` by default, and TUI apps like `viu`, `yazi`, `curses` will try to
search in the host's [terminfo(terminal capability data base)](https://linux.die.net/man/5/terminfo)
for value of `TERM` to determine the capabilities of the terminal.
But when you `ssh` into a remote host, the remote host is very likely to not have `xterm-kitty` in
its terminfo, so you will get this error:
```
'xterm-kitty': unknown terminal type
```
Or when you `sudo xxx`, `sudo` won't preserve the `TERM` variable, it will be reset to root's
default `TERM` value, which is `xterm` or `xterm-256color` in most linux distributions, so you will
get this error:
```
'xterm-256color': unknown terminal type
```
or
```
Error opening terminal: xterm-kitty.
```
NixOS preserve the `TERMINFO` and `TERMINFO_DIRS` environment variables, for `root` and the `wheel`
group:
[nixpkgs/nixos/modules/config/terminfo.nix](https://github.com/NixOS/nixpkgs/blob/nixos-25.11/nixos/modules/config/terminfo.nix#L18)
For nix-darwin, take a look at <https://github.com/LnL7/nix-darwin/wiki/Terminfo-issues>
### Solutions
Simplest solution, it will automatically copy over the terminfo files and also magically enable
shell integration on the remote machine:
```
kitten ssh user@host
```
Or if you do not care about kitty's features(such as true color & graphics protocol), you can simply
set `TERM` to `xterm-256color`, which is built-in in most linux distributions:
```
export TERM=xterm-256color
```
If you need kitty's features, but do not like the magic of `kitten`, you can manually install
kitty's terminfo on the remote host:
```bash
# install on ubuntu / debian
sudo apt-get install kitty-terminfo
# or copy from local machine
infocmp -a xterm-kitty | ssh myserver tic -x -o \~/.terminfo /dev/stdin
```
@@ -1,71 +0,0 @@
{
pkgs,
...
}:
###########################################################
#
# Alacritty Configuration
#
# Useful Hot Keys for macOS:
# 1. Multi-Window: `command + N`
# 2. Increase Font Size: `command + =` | `command + +`
# 3. Decrease Font Size: `command + -` | `command + _`
# 4. Search Text: `command + F`
# 5. And Other common shortcuts such as Copy, Paste, Cursor Move, etc.
#
# Useful Hot Keys for Linux:
# 1. Increase Font Size: `ctrl + shift + =` | `ctrl + shift + +`
# 2. Decrease Font Size: `ctrl + shift + -` | `ctrl + shift + _`
# 3. Search Text: `ctrl + shift + N`
# 4. And Other common shortcuts such as Copy, Paste, Cursor Move, etc.
#
# Note: Alacritty do not have support for Tabs, and any graphic protocol.
#
###########################################################
{
programs.alacritty = {
enable = true;
# https://alacritty.org/config-alacritty.html
settings = {
window = {
opacity = 0.93;
startup_mode = "Maximized"; # Maximized window
dynamic_title = true;
option_as_alt = "Both"; # Option key acts as Alt on macOS
decorations = "None"; # Show neither borders nor title bar
};
scrolling = {
history = 10000;
};
font = {
bold = {
family = "Maple Mono NF CN";
};
italic = {
family = "Maple Mono NF CN";
};
normal = {
family = "Maple Mono NF CN";
};
bold_italic = {
family = "Maple Mono NF CN";
};
size = 13;
};
terminal = {
# Spawn a nushell in login mode via `bash`
shell = {
program = "${pkgs.bash}/bin/bash";
args = [
"--login"
"-c"
"nu --login --interactive"
];
};
# Controls the ability to write to the system clipboard with the OSC 52 escape sequence.
# It's used by zellij to copy text to the system clipboard.
osc52 = "CopyPaste";
};
};
};
}
-4
View File
@@ -1,4 +0,0 @@
{ mylib, ... }:
{
imports = mylib.scanPaths ./.;
}
-38
View File
@@ -1,38 +0,0 @@
{ pkgs, ... }:
{
programs.foot = {
# foot is designed only for Linux
enable = pkgs.stdenv.isLinux;
# foot can also be run in a server mode. In this mode, one process hosts multiple windows.
# All Wayland communication, VT parsing and rendering is done in the server process.
# New windows are opened by running footclient, which remains running until the terminal window is closed.
#
# Advantages to run foot in server mode including reduced memory footprint and startup time.
# The downside is a performance penalty. If one window is very busy with, for example, producing output,
# then other windows will suffer. Also, should the server process crash, all windows will be gone.
server.enable = true;
# https://man.archlinux.org/man/foot.ini.5
settings = {
main = {
term = "foot"; # or "xterm-256color" for maximum compatibility
font = "Maple Mono NF CN:size=13";
dpi-aware = "no"; # scale via window manager instead
resize-keep-grid = "no"; # do not resize the window on font resizing
# Spawn a nushell in login mode via `bash`
shell = "${pkgs.bash}/bin/bash --login -c 'nu --login --interactive'";
};
colors-dark = {
alpha = 0.93; # background transparency
blur = true; # requires foot >= 1.26 and compositor support (e.g. niri v26.04+)
};
mouse = {
hide-when-typing = "yes";
};
};
};
}
-38
View File
@@ -1,38 +0,0 @@
{
pkgs,
...
}:
###########################################################
#
# Ghostty Configuration
#
###########################################################
{
programs.ghostty = {
enable = true;
package =
if pkgs.stdenv.isDarwin then
pkgs.hello # pkgs.ghostty is currently broken on darwin
else
pkgs.ghostty; # the stable version
enableBashIntegration = false;
installBatSyntax = false;
# installVimSyntax = true;
settings = {
font-family = "Maple Mono NF CN";
font-size = 13;
background-opacity = 0.93;
# only supported on macOS;
background-blur-radius = 10;
scrollback-limit = 20000;
# https://ghostty.org/docs/config/reference#command
# To resolve issues:
# 1. https://github.com/ryan4yin/nix-config/issues/26
# 2. https://github.com/ryan4yin/nix-config/issues/8
# Spawn a nushell in login mode via `bash`
command = "${pkgs.bash}/bin/bash --login -c 'nu --login --interactive'";
};
};
}
-51
View File
@@ -1,51 +0,0 @@
{
lib,
pkgs,
...
}:
###########################################################
#
# Kitty Configuration
#
# Useful Hot Keys for Linux(replace `ctrl + shift` with `cmd` on macOS)):
# 1. Increase Font Size: `ctrl + shift + =` | `ctrl + shift + +`
# 2. Decrease Font Size: `ctrl + shift + -` | `ctrl + shift + _`
# 3. And Other common shortcuts such as Copy, Paste, Cursor Move, etc.
#
###########################################################
{
programs.kitty = {
enable = true;
font = {
name = "Maple Mono NF CN";
# use different font size on macOS
size = 13;
};
# consistent with other terminal emulators
keybindings = {
"ctrl+shift+m" = "toggle_maximized";
"ctrl+shift+f" = "show_scrollback"; # search in the current window
};
settings = {
# do not show title bar & window title
hide_window_decorations = "titlebar-and-corners";
macos_show_window_title_in = "none";
background_opacity = "0.93";
background_blur = 1; # requires kitty >= 0.46.2 and compositor support (e.g. niri v26.04+)
macos_option_as_alt = true; # Option key acts as Alt on macOS
enable_audio_bell = false;
tab_bar_edge = "top"; # tab bar on top
# To resolve issues:
# 1. https://github.com/ryan4yin/nix-config/issues/26
# 2. https://github.com/ryan4yin/nix-config/issues/8
# Spawn a nushell in login mode via `bash`
shell = "${pkgs.bash}/bin/bash --login -c 'nu --login --interactive'";
};
# macOS specific settings
darwinLaunchOptions = [ "--start-as=maximized" ];
};
}
-46
View File
@@ -1,46 +0,0 @@
{
lib,
pkgs,
...
}:
{
# https://developer.hashicorp.com/terraform/cli/config/config-file
home.file.".terraformrc".source = ./terraformrc;
home.packages = with pkgs; [
# infrastructure as code
# pulumi
# pulumictl
# tf2pulumi
# crd2pulumi
# pulumiPackages.pulumi-random
# pulumiPackages.pulumi-command
# pulumiPackages.pulumi-aws-native
# pulumiPackages.pulumi-language-go
# pulumiPackages.pulumi-language-python
# pulumiPackages.pulumi-language-nodejs
# aws
awscli2
ssm-session-manager-plugin # Amazon SSM Session Manager Plugin
aws-iam-authenticator
eksctl
# aliyun
aliyun-cli
# digitalocean
doctl
# google cloud
(google-cloud-sdk.withExtraComponents (
with google-cloud-sdk.components;
[
gke-gcloud-auth-plugin
]
))
# cloud tools that nix do not have cache for.
terraform
terraformer # generate terraform configs from existing cloud resources
packer # machine image builder
];
}
-2
View File
@@ -1,2 +0,0 @@
plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
disable_checkpoint = true
-44
View File
@@ -1,44 +0,0 @@
{
pkgs,
pkgs-2505,
nur-ryan4yin,
...
}:
{
home.packages = with pkgs; [
podman-compose
dive # explore docker layers
lazydocker # Docker terminal UI.
skopeo # copy/sync images between registries and local storage
go-containerregistry # provides `crane` & `gcrane`, it's similar to skopeo
kubectl
kustomize
kubeconform # FAST Kubernetes manifests validator, with support for Custom Resources
kubectx # kubectx & kubens
kubie # same as kubectl-ctx, but per-shell (wont touch kubeconfig).
kubectl-view-secret # kubectl view-secret
kubectl-tree # kubectl tree
kubectl-node-shell # exec into node
kubepug # kubernetes pre upgrade checker
kubectl-cnpg # cloudnative-pg's cli tool
kubebuilder
istioctl
clusterctl # for kubernetes cluster-api
kubevirt # virtctl
pkgs-2505.kubernetes-helm
fluxcd
# argocd
ko # build go project to container image
];
programs.k9s.enable = true;
catppuccin.k9s.transparent = true;
programs.kubecolor = {
enable = true;
enableAlias = true;
};
}
-4
View File
@@ -1,4 +0,0 @@
{ mylib, ... }:
{
imports = mylib.scanPaths ./.;
}
-66
View File
@@ -1,66 +0,0 @@
{
pkgs,
pkgs-patched,
...
}:
{
#############################################################
#
# Basic settings for development environment
#
# Please avoid to install language specific packages here(globally),
# instead, install them:
# 1. per IDE, such as `programs.neovim.extraPackages`
# 2. per-project, using https://github.com/the-nix-way/dev-templates
#
#############################################################
home.packages = with pkgs; [
colmena # nixos's remote deployment tool
tokei # count lines of code, alternative to cloc
# db related
# mycli
pgcli
mongosh
sqlite
# embedded development
minicom
# ai related
python313Packages.huggingface-hub # huggingface-cli
pkgs-patched.python313Packages.modelscope
yt-dlp # youtube/bilibili/soundcloud/... video/music downloader
# misc
devbox
bfg-repo-cleaner # remove large files from git history
k6 # load testing tool
# solve coding extercises - learn by doing
exercism
# Automatically trims your branches whose tracking remote refs are merged or gone
# It's really useful when you work on a project for a long time.
git-trim
gitleaks
# need to run `conda-install` before using it
# need to run `conda-shell` before using command `conda`
# conda is not available for MacOS
conda
];
programs = {
direnv = {
enable = true;
nix-direnv.enable = true;
enableZshIntegration = true;
enableBashIntegration = true;
enableNushellIntegration = true;
};
};
}
-10
View File
@@ -1,10 +0,0 @@
# Editor tooling packages (heavy dependencies)
This directory intentionally holds **only** [`packages.nix`](./packages.nix): language servers,
formatters, compilers, and other editor-adjacent tools that pull in a large closure.
Editor programs, keymaps, `$EDITOR` defaults, and usage docs live under
[`../../core/editors/`](../../core/editors/README.md) (Helix, Neovim backup, glossary, cheatsheets).
[`default.nix`](./default.nix) imports `./packages.nix` so `home/base/tui` can keep pulling in
tooling without mixing it into `core/editors`.
-4
View File
@@ -1,4 +0,0 @@
# Editor-related language servers and heavy tooling — kept out of `core/editors`.
{
imports = [ ./packages.nix ];
}
-162
View File
@@ -1,162 +0,0 @@
{
pkgs,
pkgs-master,
...
}:
{
home.packages =
with pkgs;
(
# -*- Data & Configuration Languages -*-#
[
#-- nix
nil
nixd
statix # Lints and suggestions for the nix programming language
deadnix # Find and remove unused code in .nix source files
nixfmt # Nix Code Formatter
#-- nickel lang
nickel
#-- json like
# terraform # install via brew on macOS
terraform-ls
jsonnet
jsonnet-language-server
taplo # TOML language server / formatter / validator
yaml-language-server
actionlint # GitHub Actions linter
#-- dockerfile
hadolint # Dockerfile linter
dockerfile-language-server
#-- markdown
marksman # language server for markdown
glow # markdown previewer
pandoc # document converter
pkgs-master.hugo # static site generator
#-- sql
sqlfluff
#-- protocol buffer
buf # linting and formatting
]
++
#-*- General Purpose Languages -*-#
[
#-- c/c++
cmake
cmake-language-server
gnumake
checkmake
# c/c++ compiler, required by nvim-treesitter!
gcc
gdb
# c/c++ tools with clang-tools, the unwrapped version won't
# add alias like `cc` and `c++`, so that it won't conflict with gcc
# llvmPackages.clang-unwrapped
clang-tools
lldb
#-- python
uv # python project package manager
pipx # Install and Run Python Applications in Isolated Environments
(python313.withPackages (
ps: with ps; [
# python language server
pyright
ruff
black # python formatter
# my commonly used python packages
jupyter
ipython
pandas
requests
pyquery
pyyaml
boto3
# misc
protobuf # protocol buffer compiler
numpy
]
))
#-- rust
# we'd better use the rust-overlays for rust development
pkgs-master.rustc
pkgs-master.rust-analyzer
pkgs-master.cargo # rust package manager
pkgs-master.rustfmt
pkgs-master.clippy # rust linter
#-- golang
go
gomodifytags
iferr # generate error handling code for go
impl # generate function implementation for go
# gotools # contains tools like: godoc, goimports, etc.
gopls # go language server
delve # go debugger
# -- java
jdk17
gradle
maven
spring-boot-cli
jdt-language-server
#-- zig
zls
#-- lua
stylua
lua-language-server
#-- bash
bash-language-server
shellcheck
shfmt
]
#-*- Web Development -*-#
++ [
nodejs_24
pnpm
typescript
typescript-language-server
bun
# HTML/CSS/JSON/ESLint language servers extracted from vscode
vscode-langservers-extracted
tailwindcss-language-server
emmet-ls
]
# -*- Lisp like Languages -*-#
# ++ [
# guile
# racket-minimal
# fnlfmt # fennel
# (
# if pkgs.stdenv.isLinux && pkgs.stdenv.isx86
# then pkgs-master.akkuPackages.scheme-langserver
# else pkgs.emptyDirectory
# )
# ]
++ [
proselint # English prose linter
#-- verilog / systemverilog
verible
#-- Optional Requirements:
prettier # common code formatter
fzf
gdu # disk usage analyzer, required by AstroNvim
(ripgrep.override { withPCRE2 = true; }) # recursively searches directories for a regex pattern
]
);
}
-31
View File
@@ -1,31 +0,0 @@
# Encryption
We have GnuPG & password-store installed by default, mainly for password management, authentication
& communication encryption.
We also have LUKS2 for disk encryption on Linux, and [rclone](https://rclone.org/crypt/) for
cross-platform data encryption & syncing.
[age](https://github.com/FiloSottile/age) may be more general for file encryption.
[Sops](https://github.com/getsops/sops/tree/main) can be used for file encryption too, if you prefer
using a Cloud provider for key management.
## Asymmetric Encryption
Both age, Sops & GnuPG provide asymmetric encryption, which is useful for encrypting files for a
specific user.
For modern use, age is recommended, as it use [AEAD encryption function -
ChaCha20-Poly1305][age Format v1], If you do not want to manage the keys by yourself, Sops is
recommended, as it use KMS for key management.
## Symmetric Encryption
Both age & GnuPG provide symmetric encryption, which is useful for encrypting files for a specific
user.
As described in [age Format v1][age Format v1], age use scrypt to encrypt and decrypt the file key
with a provided passphrase, which is more secure than GnuPG's symmetric encryption.
[age Format v1]: https://age-encryption.org/v1

Some files were not shown because too many files have changed in this diff Show More