mirror of
https://github.com/moons-14/dotfiles.git
synced 2026-10-07 04:44:09 +09:00
Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9bb95535cf | ||
|
|
fcd0d75537 | ||
|
|
a8e9a4dce5 | ||
|
|
72ff60fb16 | ||
|
|
f65318b765 | ||
|
|
0257b2e2fd | ||
|
|
8fec0494ec | ||
|
|
89eeb23d1c | ||
|
|
bf94d1183f | ||
|
|
6bd05887db | ||
|
|
3e32c9874b | ||
|
|
684acef46c | ||
|
|
9061825c63 | ||
|
|
e703e1b31c | ||
|
|
79cc69045f | ||
|
|
5c2ff3cbcf | ||
|
|
c5d4de5a9d | ||
|
|
c58bdd30c3 | ||
|
|
9771a85e3f | ||
|
|
5b1bde7d90 | ||
|
|
1d82ab92b6 | ||
|
|
19bc309b8b | ||
|
|
e477c6bee8 | ||
|
|
0171582307 | ||
|
|
dd40b978dd |
@@ -1,260 +0,0 @@
|
||||
name: Update Flake Input
|
||||
description: Update one GitHub-backed Nix flake input and create a pull request
|
||||
inputs:
|
||||
input-name:
|
||||
description: Name of the flake input to update
|
||||
required: true
|
||||
github-token:
|
||||
description: Token used to query GitHub, push the update branch, and manage the pull request
|
||||
required: true
|
||||
base-branch:
|
||||
description: Branch targeted by the pull request
|
||||
required: false
|
||||
default: main
|
||||
minimum-release-age-days:
|
||||
description: Minimum age of the target commit in days
|
||||
required: false
|
||||
default: "3"
|
||||
skip-delay:
|
||||
description: Update to the latest revision without applying the minimum age
|
||||
required: false
|
||||
default: "false"
|
||||
auto-merge:
|
||||
description: Enable squash auto-merge on the pull request
|
||||
required: false
|
||||
default: "true"
|
||||
pr-labels:
|
||||
description: Comma-separated labels to add when they already exist in the repository
|
||||
required: false
|
||||
default: dependencies,automated
|
||||
outputs:
|
||||
updated:
|
||||
description: Whether flake.lock changed
|
||||
value: ${{ steps.update.outputs.updated }}
|
||||
current-version:
|
||||
description: Previous locked revision
|
||||
value: ${{ steps.update.outputs.current_version }}
|
||||
new-version:
|
||||
description: New locked revision
|
||||
value: ${{ steps.update.outputs.new_version }}
|
||||
pr-url:
|
||||
description: URL of the created or updated pull request
|
||||
value: ${{ steps.pull-request.outputs.pr_url }}
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Update flake input
|
||||
id: update
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ inputs.github-token }}
|
||||
INPUT_NAME: ${{ inputs.input-name }}
|
||||
MINIMUM_RELEASE_AGE_DAYS: ${{ inputs.minimum-release-age-days }}
|
||||
SKIP_DELAY: ${{ inputs.skip-delay }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
if [[ ! "$MINIMUM_RELEASE_AGE_DAYS" =~ ^[0-9]+$ ]]; then
|
||||
echo "::error::minimum-release-age-days must be a non-negative integer"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
node_key="$(
|
||||
jq -er --arg input "$INPUT_NAME" '
|
||||
.nodes.root.inputs[$input]
|
||||
| if type == "array" then .[0] else . end
|
||||
' flake.lock
|
||||
)"
|
||||
input_type="$(jq -r --arg node "$node_key" '.nodes[$node].locked.type // ""' flake.lock)"
|
||||
input_owner="$(jq -r --arg node "$node_key" '.nodes[$node].locked.owner // ""' flake.lock)"
|
||||
input_repo="$(jq -r --arg node "$node_key" '.nodes[$node].locked.repo // ""' flake.lock)"
|
||||
input_ref="$(jq -r --arg node "$node_key" '.nodes[$node].original.ref // ""' flake.lock)"
|
||||
current_rev="$(jq -er --arg node "$node_key" '.nodes[$node].locked.rev' flake.lock)"
|
||||
|
||||
if [ "$input_type" != "github" ] || [ -z "$input_owner" ] || [ -z "$input_repo" ]; then
|
||||
echo "::error::${INPUT_NAME} is not a GitHub-backed flake input"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Input: $INPUT_NAME"
|
||||
echo "Repository: ${input_owner}/${input_repo}"
|
||||
echo "Current revision: $current_rev"
|
||||
|
||||
if [ "$SKIP_DELAY" = "true" ]; then
|
||||
nix flake update "$INPUT_NAME"
|
||||
else
|
||||
cutoff="$(date --utc --date="${MINIMUM_RELEASE_AGE_DAYS} days ago" +%Y-%m-%dT%H:%M:%SZ)"
|
||||
api_args=(
|
||||
--method GET
|
||||
"repos/${input_owner}/${input_repo}/commits"
|
||||
-f "until=$cutoff"
|
||||
-f per_page=1
|
||||
)
|
||||
if [ -n "$input_ref" ]; then
|
||||
api_args+=(-f "sha=$input_ref")
|
||||
fi
|
||||
|
||||
echo "Selecting the newest commit no later than $cutoff"
|
||||
target_data="$(gh api "${api_args[@]}" --jq '.[0] | {sha: .sha, date: .commit.committer.date}')"
|
||||
target_rev="$(jq -er '.sha' <<< "$target_data")"
|
||||
target_date="$(jq -er '.date' <<< "$target_data")"
|
||||
|
||||
if [ "$target_rev" = "$current_rev" ]; then
|
||||
echo "The input is already at the newest eligible revision"
|
||||
{
|
||||
echo "updated=false"
|
||||
echo "current_version=$current_rev"
|
||||
echo "new_version=$current_rev"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
current_date="$(
|
||||
gh api "repos/${input_owner}/${input_repo}/commits/${current_rev}" \
|
||||
--jq '.commit.committer.date'
|
||||
)"
|
||||
current_timestamp="$(date --date="$current_date" +%s)"
|
||||
target_timestamp="$(date --date="$target_date" +%s)"
|
||||
|
||||
if [ "$target_timestamp" -lt "$current_timestamp" ]; then
|
||||
echo "The newest eligible revision is older than the current revision; skipping"
|
||||
{
|
||||
echo "updated=false"
|
||||
echo "current_version=$current_rev"
|
||||
echo "new_version=$current_rev"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
nix flake update "$INPUT_NAME" \
|
||||
--override-input "$INPUT_NAME" "github:${input_owner}/${input_repo}/${target_rev}"
|
||||
fi
|
||||
|
||||
if git diff --quiet -- flake.lock; then
|
||||
echo "No lock file changes were produced"
|
||||
{
|
||||
echo "updated=false"
|
||||
echo "current_version=$current_rev"
|
||||
echo "new_version=$current_rev"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
new_node_key="$(
|
||||
jq -er --arg input "$INPUT_NAME" '
|
||||
.nodes.root.inputs[$input]
|
||||
| if type == "array" then .[0] else . end
|
||||
' flake.lock
|
||||
)"
|
||||
new_rev="$(jq -er --arg node "$new_node_key" '.nodes[$node].locked.rev' flake.lock)"
|
||||
|
||||
echo "New revision: $new_rev"
|
||||
{
|
||||
echo "updated=true"
|
||||
echo "current_version=$current_rev"
|
||||
echo "new_version=$new_rev"
|
||||
echo "input_owner=$input_owner"
|
||||
echo "input_repo=$input_repo"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
- name: Create or update pull request
|
||||
id: pull-request
|
||||
if: steps.update.outputs.updated == 'true'
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{ inputs.github-token }}
|
||||
INPUT_NAME: ${{ inputs.input-name }}
|
||||
BASE_BRANCH: ${{ inputs.base-branch }}
|
||||
CURRENT_REV: ${{ steps.update.outputs.current_version }}
|
||||
NEW_REV: ${{ steps.update.outputs.new_version }}
|
||||
INPUT_OWNER: ${{ steps.update.outputs.input_owner }}
|
||||
INPUT_REPO: ${{ steps.update.outputs.input_repo }}
|
||||
MINIMUM_RELEASE_AGE_DAYS: ${{ inputs.minimum-release-age-days }}
|
||||
SKIP_DELAY: ${{ inputs.skip-delay }}
|
||||
AUTO_MERGE: ${{ inputs.auto-merge }}
|
||||
PR_LABELS: ${{ inputs.pr-labels }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
branch_suffix="$(tr -c 'A-Za-z0-9._-' '-' <<< "$INPUT_NAME" | sed 's/-$//')"
|
||||
branch="update-flake-${branch_suffix}"
|
||||
current_short="${CURRENT_REV:0:8}"
|
||||
new_short="${NEW_REV:0:8}"
|
||||
title="chore(nix): update ${INPUT_NAME} to ${new_short}"
|
||||
|
||||
if [ "$SKIP_DELAY" = "true" ]; then
|
||||
age_note="The minimum release age check was skipped for this manually requested update."
|
||||
else
|
||||
age_note="The target commit is at least ${MINIMUM_RELEASE_AGE_DAYS} days old."
|
||||
fi
|
||||
|
||||
body="$(
|
||||
printf '%s\n' \
|
||||
"Automated update of the \`${INPUT_NAME}\` flake input." \
|
||||
"" \
|
||||
"- Previous revision: [\`${current_short}\`](https://github.com/${INPUT_OWNER}/${INPUT_REPO}/commit/${CURRENT_REV})" \
|
||||
"- New revision: [\`${new_short}\`](https://github.com/${INPUT_OWNER}/${INPUT_REPO}/commit/${NEW_REV})" \
|
||||
"- Changes: [compare](https://github.com/${INPUT_OWNER}/${INPUT_REPO}/compare/${CURRENT_REV}...${NEW_REV})" \
|
||||
"" \
|
||||
"$age_note"
|
||||
)"
|
||||
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git add flake.lock
|
||||
git switch -C "$branch"
|
||||
git commit -m "$title"
|
||||
|
||||
git fetch origin "refs/heads/${branch}:refs/remotes/origin/${branch}" || true
|
||||
git push --force-with-lease origin "HEAD:refs/heads/${branch}"
|
||||
|
||||
label_args=()
|
||||
available_labels="$(gh label list --limit 100 --json name --jq '.[].name')"
|
||||
IFS=',' read -ra requested_labels <<< "$PR_LABELS"
|
||||
for label in "${requested_labels[@]}"; do
|
||||
label="$(xargs <<< "$label")"
|
||||
if [ -n "$label" ] && grep -Fxq "$label" <<< "$available_labels"; then
|
||||
label_args+=(--add-label "$label")
|
||||
elif [ -n "$label" ]; then
|
||||
echo "::warning::Skipping missing pull request label: $label"
|
||||
fi
|
||||
done
|
||||
|
||||
pr_number="$(
|
||||
gh pr list \
|
||||
--state open \
|
||||
--head "$branch" \
|
||||
--json number \
|
||||
--jq '.[0].number // empty'
|
||||
)"
|
||||
|
||||
if [ -n "$pr_number" ]; then
|
||||
gh pr edit "$pr_number" \
|
||||
--title "$title" \
|
||||
--body "$body" \
|
||||
"${label_args[@]}"
|
||||
else
|
||||
gh pr create \
|
||||
--base "$BASE_BRANCH" \
|
||||
--head "$branch" \
|
||||
--title "$title" \
|
||||
--body "$body"
|
||||
pr_number="$(
|
||||
gh pr list \
|
||||
--state open \
|
||||
--head "$branch" \
|
||||
--json number \
|
||||
--jq '.[0].number'
|
||||
)"
|
||||
if [ "${#label_args[@]}" -gt 0 ]; then
|
||||
gh pr edit "$pr_number" "${label_args[@]}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$AUTO_MERGE" = "true" ]; then
|
||||
gh pr merge "$pr_number" --auto --squash ||
|
||||
echo "::warning::Auto-merge could not be enabled; check the repository merge settings"
|
||||
fi
|
||||
|
||||
pr_url="$(gh pr view "$pr_number" --json url --jq '.url')"
|
||||
echo "pr_url=$pr_url" >> "$GITHUB_OUTPUT"
|
||||
echo "Pull request: $pr_url"
|
||||
@@ -1,150 +0,0 @@
|
||||
name: NixOS CI
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
permissions:
|
||||
contents: read
|
||||
concurrency:
|
||||
group: nixos-ci-${{ github.event.pull_request.number || github.run_id }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
jobs:
|
||||
validate:
|
||||
name: Validate flake
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
outputs:
|
||||
hosts: ${{ steps.hosts.outputs.hosts }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
|
||||
with:
|
||||
extra_nix_config: |
|
||||
experimental-features = nix-command flakes
|
||||
accept-flake-config = true
|
||||
access-tokens = github.com=${{ github.token }}
|
||||
- name: Check flake and evaluate all outputs
|
||||
run: nix flake check --all-systems --no-build --show-trace
|
||||
- name: Discover NixOS hosts
|
||||
id: hosts
|
||||
run: |
|
||||
hosts=$(nix eval --json '.#nixosConfigurations' --apply 'configs: builtins.attrNames configs')
|
||||
echo "hosts=$hosts" >> "$GITHUB_OUTPUT"
|
||||
echo "Discovered hosts: $hosts"
|
||||
build:
|
||||
name: Build ${{ matrix.host }}
|
||||
needs: validate
|
||||
if: ${{ needs.validate.outputs.hosts != '[]' }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 120
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
host: ${{ fromJSON(needs.validate.outputs.hosts) }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
|
||||
with:
|
||||
extra_nix_config: |
|
||||
experimental-features = nix-command flakes
|
||||
accept-flake-config = true
|
||||
access-tokens = github.com=${{ github.token }}
|
||||
- name: Build NixOS system
|
||||
run: |
|
||||
nix build ".#nixosConfigurations.${{ matrix.host }}.config.system.build.toplevel" \
|
||||
--no-link \
|
||||
--print-build-logs \
|
||||
--show-trace
|
||||
report-main-status:
|
||||
name: Report main status
|
||||
needs:
|
||||
- validate
|
||||
- build
|
||||
if: ${{ always() && !cancelled() && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
env:
|
||||
CI_FAILED: ${{ needs.validate.result == 'failure' || needs.build.result == 'failure' }}
|
||||
JOB_RESULTS: ${{ toJSON(needs) }}
|
||||
steps:
|
||||
- name: Create or resolve failure issue
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
|
||||
with:
|
||||
script: |
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
const title = "NixOS CI is failing on main";
|
||||
const marker = "<!-- nixos-ci-main-failure -->";
|
||||
const failed = process.env.CI_FAILED === "true";
|
||||
const jobs = JSON.parse(process.env.JOB_RESULTS);
|
||||
const failedJobs = Object.entries(jobs)
|
||||
.filter(([, job]) => job.result === "failure")
|
||||
.map(([name]) => `\`${name}\``)
|
||||
.join(", ");
|
||||
const runUrl = `${context.serverUrl}/${owner}/${repo}/actions/runs/${context.runId}`;
|
||||
const commitUrl = `${context.serverUrl}/${owner}/${repo}/commit/${context.sha}`;
|
||||
const issues = await github.paginate(github.rest.issues.listForRepo, {
|
||||
owner,
|
||||
repo,
|
||||
state: "open",
|
||||
per_page: 100,
|
||||
});
|
||||
const existing = issues.find(
|
||||
(issue) => !issue.pull_request && issue.title === title && issue.body?.includes(marker),
|
||||
);
|
||||
|
||||
if (failed) {
|
||||
const body = [
|
||||
marker,
|
||||
"The NixOS CI workflow failed after a push to `main`.",
|
||||
"",
|
||||
`- Failed jobs: ${failedJobs || "unknown"}`,
|
||||
`- Commit: [\`${context.sha.slice(0, 7)}\`](${commitUrl})`,
|
||||
`- Workflow run: [${context.runId}](${runUrl})`,
|
||||
"",
|
||||
"This issue is updated on subsequent failures and closed automatically after CI recovers.",
|
||||
].join("\n");
|
||||
|
||||
if (existing) {
|
||||
await github.rest.issues.update({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: existing.number,
|
||||
body,
|
||||
});
|
||||
} else {
|
||||
await github.rest.issues.create({ owner, repo, title, body });
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (existing) {
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: existing.number,
|
||||
body: `CI recovered in [workflow run ${context.runId}](${runUrl}).`,
|
||||
});
|
||||
await github.rest.issues.update({
|
||||
owner,
|
||||
repo,
|
||||
issue_number: existing.number,
|
||||
state: "closed",
|
||||
state_reason: "completed",
|
||||
});
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
name: Renovate
|
||||
on:
|
||||
schedule:
|
||||
# Every day at 03:00 JST (18:00 UTC on the previous day).
|
||||
- cron: "0 18 * * *"
|
||||
workflow_dispatch:
|
||||
permissions:
|
||||
contents: read
|
||||
concurrency:
|
||||
group: renovate
|
||||
cancel-in-progress: false
|
||||
jobs:
|
||||
renovate:
|
||||
name: Update GitHub Actions dependencies
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 60
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
# Use a PAT or GitHub App token so Renovate PRs trigger the other workflows.
|
||||
- name: Run Renovate
|
||||
uses: renovatebot/github-action@3064367f740a1a91cca218698a63902689cce200 # v46.1.20
|
||||
with:
|
||||
renovate-version: 43.262.1
|
||||
token: ${{ secrets.RENOVATE_TOKEN }}
|
||||
env:
|
||||
LOG_LEVEL: info
|
||||
RENOVATE_PLATFORM: github
|
||||
RENOVATE_REPOSITORIES: ${{ github.repository }}
|
||||
@@ -1,106 +0,0 @@
|
||||
name: Update Flake Inputs
|
||||
on:
|
||||
schedule:
|
||||
# Every day at 03:30 JST (18:30 UTC on the previous day).
|
||||
- cron: "30 18 * * *"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
input:
|
||||
description: Update only this flake input (empty updates all inputs)
|
||||
required: false
|
||||
type: string
|
||||
skip-delay:
|
||||
description: Update to the latest revision without the three-day delay
|
||||
required: false
|
||||
default: false
|
||||
type: boolean
|
||||
auto-merge:
|
||||
description: Enable auto-merge after required checks pass
|
||||
required: false
|
||||
default: true
|
||||
type: boolean
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
concurrency:
|
||||
group: update-flake-inputs
|
||||
cancel-in-progress: false
|
||||
jobs:
|
||||
discover:
|
||||
name: Discover flake inputs
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
outputs:
|
||||
matrix: ${{ steps.inputs.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Build update matrix
|
||||
id: inputs
|
||||
env:
|
||||
REQUESTED_INPUT: ${{ inputs.input }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
github_inputs="$(
|
||||
jq -c '
|
||||
. as $lock
|
||||
| [
|
||||
$lock.nodes.root.inputs
|
||||
| to_entries[]
|
||||
| .key as $name
|
||||
| (
|
||||
.value
|
||||
| if type == "array" then .[0] else . end
|
||||
) as $node
|
||||
| select($lock.nodes[$node].locked.type == "github")
|
||||
| $name
|
||||
]
|
||||
| sort
|
||||
' flake.lock
|
||||
)"
|
||||
|
||||
if [ -n "$REQUESTED_INPUT" ]; then
|
||||
if ! jq -e --arg input "$REQUESTED_INPUT" 'index($input) != null' <<< "$github_inputs" >/dev/null; then
|
||||
echo "::error::Unknown or unsupported flake input: $REQUESTED_INPUT"
|
||||
exit 1
|
||||
fi
|
||||
matrix="$(jq -cn --arg input "$REQUESTED_INPUT" '{input: [$input]}')"
|
||||
else
|
||||
matrix="$(jq -cn --argjson inputs "$github_inputs" '{input: $inputs}')"
|
||||
fi
|
||||
|
||||
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"
|
||||
echo "Update matrix: $matrix"
|
||||
update:
|
||||
name: Update ${{ matrix.input }}
|
||||
needs: discover
|
||||
if: ${{ needs.discover.outputs.matrix != '{"input":[]}' }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: 4
|
||||
matrix: ${{ fromJSON(needs.discover.outputs.matrix) }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.RENOVATE_TOKEN }}
|
||||
- name: Install Nix
|
||||
uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
|
||||
with:
|
||||
extra_nix_config: |
|
||||
experimental-features = nix-command flakes
|
||||
accept-flake-config = true
|
||||
access-tokens = github.com=${{ secrets.RENOVATE_TOKEN }}
|
||||
- name: Update input
|
||||
uses: ./.github/actions/update-flake-input
|
||||
with:
|
||||
input-name: ${{ matrix.input }}
|
||||
github-token: ${{ secrets.RENOVATE_TOKEN }}
|
||||
skip-delay: ${{ github.event_name == 'workflow_dispatch' && inputs.skip-delay }}
|
||||
auto-merge: ${{ github.event_name != 'workflow_dispatch' || inputs.auto-merge }}
|
||||
+14
-10
@@ -4,6 +4,7 @@
|
||||
!README.md
|
||||
!LICENSE
|
||||
!AGENTS.md
|
||||
!/docs/
|
||||
|
||||
!.github/
|
||||
!.gitea/
|
||||
@@ -14,15 +15,18 @@
|
||||
|
||||
!/flake.nix
|
||||
!/flake.lock
|
||||
!/renovate.json
|
||||
|
||||
!shells/
|
||||
!hosts/
|
||||
!overlays/
|
||||
!profiles/
|
||||
!modules/
|
||||
!docs/
|
||||
!images/
|
||||
!secrets/
|
||||
|
||||
!/shells/
|
||||
!/flake/
|
||||
!/overlays/
|
||||
|
||||
!/images/
|
||||
!/secrets/
|
||||
|
||||
!/hosts/
|
||||
|
||||
!/libs/
|
||||
|
||||
!/modules/
|
||||
|
||||
!/tests/
|
||||
|
||||
@@ -1,423 +1,574 @@
|
||||
# AGENTS.md
|
||||
# Repository Guidelines
|
||||
|
||||
NixOS + Home Manager flake (v2)。flake-parts ベース。
|
||||
## Project Structure and Ownership
|
||||
|
||||
## Commands
|
||||
This repository manages NixOS, nix-darwin, and Home Manager configurations as a
|
||||
flake. `flake.nix` defines inputs and delegates flake outputs through
|
||||
flake-parts. Keep configuration with the component that owns it, rather than in
|
||||
the root flake or an unrelated host.
|
||||
|
||||
```sh
|
||||
nix flake update # flake の更新
|
||||
nix fmt # フォーマット (treefmt: nixfmt, deadnix, statix, shfmt, shellcheck, prettier, yamlfmt, taplo, oxfmt)
|
||||
nix develop .#dotnix # 開発シェル (pre-commit hooks, sops, age 入り)
|
||||
sudo nixos-rebuild build --flake .#<host> # ビルド確認
|
||||
sudo nixos-rebuild switch --flake .#<host> # 適用
|
||||
```
|
||||
| Path | Responsibility |
|
||||
| ----------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
||||
| `modules/applications/` | One software component, including GUI applications, window managers, desktop environments, CLI tools, and editors |
|
||||
| `modules/systems/` | OS foundations such as Nix, boot, locale, Wayland, and networking |
|
||||
| `modules/services/` | Daemons, long-running services, and configuration that involves permissions or user groups |
|
||||
| `modules/hardwares/` | Reusable drivers, hardware families, and VM or WSL guest configuration |
|
||||
| `modules/users/` | User identity and the user's NixOS-, nix-darwin-, and Home Manager-specific definitions |
|
||||
| `modules/profiles/` | Purpose- or form-factor-oriented compositions of multiple units |
|
||||
| `hosts/` | Machine-specific facts and the profiles or applications selected for each machine |
|
||||
| `libs/` | Registry, unit discovery, and host construction logic |
|
||||
| `overlays/` | Package replacements and additions |
|
||||
| `shells/` | Development shells |
|
||||
| `flake/` | Supporting flake outputs such as formatters, checks, and Git hooks |
|
||||
|
||||
## Conventions
|
||||
Use **unit** as the generic internal term for a Registry-managed component and
|
||||
**profile** for a unit that composes multiple units. Do not introduce a
|
||||
`features/` layer. Window managers and desktop environments such as niri and
|
||||
GNOME belong in `modules/applications/`; do not create a separate `desktop/`
|
||||
module category.
|
||||
|
||||
- User: `moons`, locale: `ja_JP.UTF-8`, timezone: `Asia/Tokyo`
|
||||
- Commits: conventional commits (`feat:`, `chore:`, `fix:`, etc.)
|
||||
- リモート: `[email protected]:moons-14/dotfiles.git`
|
||||
- `environment.systemPackages` にパッケージを追加する際はパッケージ名の横に簡単な説明をコメントで追加する
|
||||
- 警告を抑制する設定は書かない。根本原因を調査して修正する
|
||||
- home-manager の `sharedModules` 内で `lib.hm.*` を使う場合は、そのモジュール関数の引数で `lib` を受け取る必要がある(NixOSモジュールの `lib` とは別スコープ)
|
||||
- `useGlobalPkgs = true` なので、home-manager 内で `nixpkgs.config` を設定しない(NixOSレベルで一括設定)
|
||||
- `allowUnfree` は `hosts/default.nix` でグローバルに設定済み。各モジュールで個別設定しない
|
||||
- pre-commit hooks が `git-hooks.nix` で設定済み(treefmt, gitleaks, deadnix, statix, shellcheck)。dev shell で自動有効化
|
||||
Before adding configuration, decide whether it is owned by an application,
|
||||
system foundation, service, hardware family, user, profile, or individual host.
|
||||
Prefer the following placements:
|
||||
|
||||
## Secrets
|
||||
| Configuration | Placement |
|
||||
| ---------------------------------------------------- | ------------------------------------------------ |
|
||||
| Nix settings shared by every system host | `modules/systems/nix/common.nix` |
|
||||
| NixOS-only boot configuration | `modules/systems/boot/.../nixos.nix` |
|
||||
| Ghostty-specific configuration | `modules/applications/ghostty/` |
|
||||
| niri-specific configuration | `modules/applications/niri/` |
|
||||
| Applications selected for the niri environment | `modules/profiles/interface/niri/meta.nix` |
|
||||
| GNOME itself | `modules/applications/gnome/` |
|
||||
| Docker daemon and Docker group membership | `modules/services/docker/nixos.nix` |
|
||||
| Reusable ThinkPad-family configuration | `modules/hardwares/thinkpad/` |
|
||||
| The laptop unit composition | `modules/profiles/platform/laptop/meta.nix` |
|
||||
| The development-environment unit composition | `modules/profiles/workload/development/meta.nix` |
|
||||
| A user's OS- and Home Manager-specific configuration | `modules/users/<name>/` |
|
||||
| x1g13-specific monitor layout | `hosts/x1g13/home.nix` |
|
||||
| x1g13-specific disk UUID | `hosts/x1g13/nixos.nix` |
|
||||
| Package replacement or addition | `overlays/` |
|
||||
| Formatter, checks, or Git hooks | `flake/` |
|
||||
|
||||
- **sops-nix** + **age** + **YubiKey** で秘密管理
|
||||
- `.sops.yaml` で暗号化ルール定義、`secrets/` に暗号化済み YAML を配置
|
||||
- `modules/system/sops.nix` で sops-nix を import、`services.pcscd` (YubiKey用) を有効化
|
||||
- `modules/system/secret.nix` で `sops.secrets` を宣言
|
||||
- 平文の秘密をコミットしない(gitleaks が pre-commit で検出)
|
||||
## Unit Discovery and Identity
|
||||
|
||||
## Architecture
|
||||
A directory below `modules/` is a unit if, and only if, it directly contains at
|
||||
least one reserved file. Directories used only for classification, such as
|
||||
`modules/applications/` or `modules/profiles/interface/`, are namespaces rather
|
||||
than units when they have no reserved file of their own.
|
||||
|
||||
```
|
||||
flake.nix
|
||||
├── hosts/default.nix # mkSystem でホスト構成を生成
|
||||
│ ├── modules/ # 全モジュール(常にインポートされる)
|
||||
│ │ ├── applications/ # アプリケーション設定
|
||||
│ │ ├── system/ # システム設定
|
||||
│ │ ├── drivers/ # ドライバ設定
|
||||
│ │ ├── features/ # 機能バンドル(application/systemを束ねる)
|
||||
│ │ └── integrations/ # home-manager 統合
|
||||
│ └── profiles/ # ホストごとに有効化するfeaturesの組み合わせ
|
||||
│ ├── interfaces/ # 操作インターフェース (CLI/GUI)
|
||||
│ ├── platforms/ # ハードウェア (desktop/laptop/thinkpad/vm)
|
||||
│ └── workloads/ # 用途 (dev/personal/srv/remote/secure-storage)
|
||||
├── overlays/ # nixpkgs オーバーレイ
|
||||
├── shells/ # devShells (dotnix)
|
||||
└── flake/ # formatter.nix, git-hooks.nix
|
||||
```
|
||||
The Registry recognizes exactly these five reserved filenames:
|
||||
|
||||
### 評価の流れ
|
||||
| File | Target and responsibility |
|
||||
| ------------ | -------------------------------------------------------------------------------- |
|
||||
| `common.nix` | System-side configuration fragment shared by NixOS and nix-darwin |
|
||||
| `nixos.nix` | NixOS-only configuration fragment |
|
||||
| `darwin.nix` | nix-darwin-only configuration fragment |
|
||||
| `home.nix` | Home Manager configuration fragment |
|
||||
| `meta.nix` | Registry descriptor for dependencies, external modules, and descriptive metadata |
|
||||
|
||||
```
|
||||
profile (featuresの有効化)
|
||||
→ features (application/systemの有効化 + パッケージ追加)
|
||||
→ applications (system.nix + home.nix)
|
||||
→ system (NixOS設定)
|
||||
```
|
||||
`common.nix` is never applied to Home Manager. OS-independent Home Manager
|
||||
configuration still belongs in `home.nix`.
|
||||
|
||||
## Layer Design
|
||||
The Registry derives a unit ID from the path relative to `modules/`, joining
|
||||
path components with dots. Category names remain plural. It also derives the
|
||||
enable option by prefixing the same components with `my` and appending `enable`.
|
||||
|
||||
### `modules/system/` — NixOS システム設定
|
||||
| Unit directory | Unit ID | Enable option |
|
||||
| ---------------------------------- | ------------------------- | ----------------------------------- |
|
||||
| `modules/applications/ghostty/` | `applications.ghostty` | `my.applications.ghostty.enable` |
|
||||
| `modules/applications/niri/` | `applications.niri` | `my.applications.niri.enable` |
|
||||
| `modules/systems/boot/uefi/` | `systems.boot.uefi` | `my.systems.boot.uefi.enable` |
|
||||
| `modules/services/docker/` | `services.docker` | `my.services.docker.enable` |
|
||||
| `modules/hardwares/qemu-guest/` | `hardwares.qemu-guest` | `my.hardwares.qemu-guest.enable` |
|
||||
| `modules/users/moons/` | `users.moons` | `my.users.moons.enable` |
|
||||
| `modules/profiles/interface/niri/` | `profiles.interface.niri` | `my.profiles.interface.niri.enable` |
|
||||
|
||||
OS全体に影響する設定。`config.my.system.*` namespace。
|
||||
|
||||
- audio, boot, camera, disko, fingerprint, fonts, gc, hardware, locale, network, nix, power, secure-boot, sops, user, version, secret
|
||||
- 常にインポートされるが、`enable` オプションで実効性を制御
|
||||
- home-manager の設定は含めない
|
||||
|
||||
### `modules/applications/` — アプリケーション設定
|
||||
|
||||
個別に有効/無効を切り替えたいアプリケーション。`config.my.applications.*` namespace。
|
||||
|
||||
- NixOS設定のみ、または NixOS + Home Manager の両方
|
||||
- Complex Module は system.nix と home.nix に分離
|
||||
|
||||
### `modules/drivers/` — ドライバ設定
|
||||
|
||||
ハードウェア固有のドライバ。`config.my.drivers.*` namespace。
|
||||
|
||||
### `modules/features/` — 機能バンドル
|
||||
|
||||
application や system より抽象度の高い「機能」単位で、複数の application/system を束ねて有効化する層。`config.my.features.*` namespace。
|
||||
|
||||
**features がやること:**
|
||||
|
||||
1. 複数の `my.applications.*.enable` / `my.system.*.enable` をまとめて有効化
|
||||
2. application/system に属さないパッケージや設定を直接記述(`environment.systemPackages`、`home.activation` 等)
|
||||
3. 追加オプションの受け渡し(例: tailscale の `acceptDns` を feature から application に passthrough)
|
||||
|
||||
**features がやらないこと:**
|
||||
|
||||
- 個別アプリケーションの詳細設定(これは applications 層の責務)
|
||||
|
||||
### `profiles/` — ホスト構成
|
||||
|
||||
features の `enable` を指定するだけの薄い層。ロジックは書かない。
|
||||
`profiles/` から `my.system.*.enable` / `my.applications.*.enable` を直接指定しない。
|
||||
必要な場合は必ず `modules/features/` に feature 層を作り、profile では `my.features.*.enable` のみ指定する。
|
||||
|
||||
| カテゴリ | 役割 | 例 |
|
||||
| ------------- | -------------------- | ------------------------------------------ |
|
||||
| `interfaces/` | 操作インターフェース | cli-minimal, cli-interactive, gui |
|
||||
| `platforms/` | ハードウェア固有設定 | desktop, laptop, thinkpad, vm |
|
||||
| `workloads/` | 用途・ワークロード | dev, personal, srv, remote, secure-storage |
|
||||
|
||||
profiles は継承可能:
|
||||
Represent option paths as attribute-path lists, never as Nix source encoded in
|
||||
strings or evaluated dynamically. Generate and read attributes with helpers such
|
||||
as `lib.setAttrByPath` and `lib.getAttrFromPath`:
|
||||
|
||||
```nix
|
||||
# cli-interactive.nix
|
||||
{
|
||||
imports = [ ./cli-minimal.nix ];
|
||||
my.features.cli.interactive.enable = true;
|
||||
}
|
||||
```
|
||||
id = "applications.ghostty";
|
||||
|
||||
### `hosts/` — ホスト定義
|
||||
|
||||
`mkSystem` でホストを定義。profiles のリストを指定:
|
||||
|
||||
```nix
|
||||
nix-example = mkSystem {
|
||||
host = "nix-example";
|
||||
system = "x86_64-linux";
|
||||
profiles = [
|
||||
"interfaces/cli-interactive"
|
||||
"platforms/vm"
|
||||
"workloads/dev"
|
||||
optionPath = [
|
||||
"my"
|
||||
"applications"
|
||||
"ghostty"
|
||||
"enable"
|
||||
];
|
||||
};
|
||||
|
||||
kind = "applications";
|
||||
name = "ghostty";
|
||||
|
||||
relativePath = [
|
||||
"applications"
|
||||
"ghostty"
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
`specialArgs` で `inputs`, `username`, `unstable`, `host` が全モジュールに渡される。
|
||||
For `modules/profiles/interface/niri/`, path inference additionally gives
|
||||
`kind = "profiles"`, `group = "interface"`, and `name = "niri"`. The path is
|
||||
always authoritative for identity. `meta.nix` may provide display metadata such
|
||||
as `description`, but it must not override or alias the unit ID.
|
||||
|
||||
**注意:** `installer` ホストは `mkSystem` を使わず直接 `nixosSystem` で定義(インストーラ用)。
|
||||
## Unit Files and Fragment Contract
|
||||
|
||||
## Module Patterns
|
||||
Only reserved files that a unit actually needs should exist. The Registry
|
||||
registers present fragments and does not require empty or placeholder files. All
|
||||
of the following are valid units:
|
||||
|
||||
### Simple Module(NixOS のみ)
|
||||
```text
|
||||
# Home Manager only
|
||||
modules/applications/ghostty/
|
||||
├── home.nix
|
||||
└── settings.nix
|
||||
|
||||
home-manager の設定を含まない。1ファイルで完結:
|
||||
# NixOS only
|
||||
modules/applications/gnome/
|
||||
└── nixos.nix
|
||||
|
||||
# nix-darwin only
|
||||
modules/systems/macos-defaults/
|
||||
└── darwin.nix
|
||||
|
||||
# NixOS and Home Manager, with metadata and helpers
|
||||
modules/applications/niri/
|
||||
├── nixos.nix
|
||||
├── home.nix
|
||||
├── meta.nix
|
||||
├── settings.nix
|
||||
└── keybindings.nix
|
||||
|
||||
# Metadata only, commonly a composition profile
|
||||
modules/profiles/interface/niri/
|
||||
└── meta.nix
|
||||
|
||||
# System configuration shared by NixOS and nix-darwin
|
||||
modules/systems/nix/
|
||||
└── common.nix
|
||||
```
|
||||
|
||||
If a unit has no `home.nix`, do not generate or apply a Home Manager module for
|
||||
it. The same rule applies independently to `common.nix`, `nixos.nix`, and
|
||||
`darwin.nix`.
|
||||
|
||||
### Configuration fragments
|
||||
|
||||
`common.nix`, `nixos.nix`, `darwin.nix`, and `home.nix` are configuration
|
||||
fragments to which the Registry adds the enable condition. They return the
|
||||
configuration for their class directly and must not define top-level `imports`,
|
||||
`options`, or `config` attributes:
|
||||
|
||||
```nix
|
||||
# modules/system/audio.nix
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
cfg = config.my.system.audio;
|
||||
in
|
||||
# modules/services/docker/nixos.nix
|
||||
{ primaryUser, ... }:
|
||||
{
|
||||
options.my.system.audio = {
|
||||
enable = lib.mkEnableOption "Audio support (PipeWire)";
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
autoPrune.enable = true;
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# NixOS設定をここに書く
|
||||
users.users.${primaryUser}.extraGroups = [
|
||||
"docker"
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
Conceptually, the Registry supplies a wrapper like this:
|
||||
|
||||
```nix
|
||||
{ config, lib, ... }@args:
|
||||
{
|
||||
config =
|
||||
lib.mkIf
|
||||
config.my.services.docker.enable
|
||||
(import dockerNixosPath args);
|
||||
}
|
||||
```
|
||||
|
||||
Do not add hand-written `mkEnableOption`, `cfg`, or `mkIf` boilerplate to each
|
||||
unit. The Registry generates the enable option from the unit path and guards the
|
||||
fragment.
|
||||
|
||||
### Helper files and directories
|
||||
|
||||
Every filename other than the five reserved names is an ordinary helper,
|
||||
regardless of its extension. The Registry neither discovers nor automatically
|
||||
imports helper files such as `settings.nix`, `keybindings.nix`, `packages.nix`,
|
||||
`colors.nix`, `rules.nix`, or `helpers.nix`. Import a helper explicitly from the
|
||||
reserved fragment that uses it:
|
||||
|
||||
```nix
|
||||
# modules/applications/niri/home.nix
|
||||
{ lib, ... }:
|
||||
let
|
||||
settings = import ./settings.nix;
|
||||
keybindings = import ./keybindings.nix;
|
||||
in
|
||||
{
|
||||
programs.niri.settings = lib.recursiveUpdate settings {
|
||||
binds = keybindings;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Simple Module(Home Manager のみ)
|
||||
|
||||
NixOS設定を含まず、home-manager のみ:
|
||||
Do not use a leading underscore to mark a file private; `_settings.nix` has no
|
||||
special meaning. Give helper files descriptive names instead. When helpers are
|
||||
configuration functions, pass the module arguments explicitly and combine them
|
||||
with normal Nix expressions:
|
||||
|
||||
```nix
|
||||
# modules/applications/zoom.nix
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
cfg = config.my.applications.zoom;
|
||||
in
|
||||
# modules/applications/example/home.nix
|
||||
{ lib, ... }@args:
|
||||
lib.mkMerge [
|
||||
(import ./packages.nix args)
|
||||
(import ./settings.nix args)
|
||||
]
|
||||
```
|
||||
|
||||
The same discovery rule applies recursively to helper directories:
|
||||
|
||||
```text
|
||||
modules/applications/niri/
|
||||
├── home.nix
|
||||
└── parts/
|
||||
├── appearance.nix
|
||||
└── keybindings.nix
|
||||
```
|
||||
|
||||
Here `parts/` is not a unit because it directly contains no reserved file. A
|
||||
helper directory that directly contains `home.nix` or another reserved file is
|
||||
itself discovered as a unit, so never use reserved filenames inside a directory
|
||||
that is intended to contain helpers only.
|
||||
|
||||
### Registry metadata
|
||||
|
||||
`meta.nix` is a Registry descriptor, not a NixOS, nix-darwin, or Home Manager
|
||||
module. It may declare `description`, `includes`, and class-specific external
|
||||
module imports:
|
||||
|
||||
```nix
|
||||
# modules/applications/niri/meta.nix
|
||||
{ inputs, ... }:
|
||||
{
|
||||
options.my.applications.zoom = {
|
||||
enable = lib.mkEnableOption "Zoom video conferencing";
|
||||
description = "Niri Wayland compositor";
|
||||
|
||||
includes = [
|
||||
"systems.wayland"
|
||||
"services.xdg-portal"
|
||||
];
|
||||
|
||||
imports.nixos = [
|
||||
inputs.niri-flake.nixosModules.niri
|
||||
];
|
||||
|
||||
imports.home = [
|
||||
inputs.niri-flake.homeModules.niri
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
External modules, including modules supplied by flake inputs, define Nix module
|
||||
options and therefore belong in `meta.nix` under `imports.nixos`,
|
||||
`imports.darwin`, or `imports.home`. Do not place them in a configuration
|
||||
fragment's top-level `imports`: the Nix module system resolves imports before a
|
||||
configuration-level enable condition.
|
||||
|
||||
`includes` lists units to enable whenever the declaring unit is enabled. Always
|
||||
use fully qualified unit IDs:
|
||||
|
||||
```nix
|
||||
# modules/profiles/interface/niri/meta.nix
|
||||
{
|
||||
includes = [
|
||||
"applications.niri"
|
||||
"applications.ghostty"
|
||||
"applications.noctalia"
|
||||
"applications.vicinae"
|
||||
"applications.nautilus"
|
||||
"services.xdg-portal"
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
Never omit a prefix such as `applications.` merely because the including unit is
|
||||
a profile. Fully qualified IDs make ownership explicit and allow moves, name
|
||||
collisions, and missing dependencies to be detected. Do not enable another unit
|
||||
by assigning to its enable option from a class fragment; declare the dependency
|
||||
in `meta.includes`.
|
||||
|
||||
Application metadata should include only dependencies technically required for
|
||||
the application to work. A profile owns the user's choice to adopt several
|
||||
otherwise independent applications together. For example, niri may include the
|
||||
Wayland foundation and xdg-desktop-portal as technical dependencies, while
|
||||
`profiles.interface.niri` selects Ghostty, Vicinae, Noctalia, and Nautilus.
|
||||
Ghostty must not depend on niri, and niri-specific keybindings remain owned by
|
||||
the niri unit.
|
||||
|
||||
## Profiles
|
||||
|
||||
Profiles compose units by purpose or form factor; they do not replace clear
|
||||
application, system, service, or hardware ownership. Suitable profile namespaces
|
||||
include:
|
||||
|
||||
```text
|
||||
modules/profiles/
|
||||
├── base/
|
||||
├── interface/
|
||||
│ ├── niri/
|
||||
│ ├── gnome/
|
||||
│ ├── cli-minimal/
|
||||
│ └── cli-interactive/
|
||||
├── platform/
|
||||
│ ├── laptop/
|
||||
│ ├── thinkpad/
|
||||
│ ├── desktop/
|
||||
│ ├── vm/
|
||||
│ └── wsl/
|
||||
├── workload/
|
||||
│ ├── development/
|
||||
│ ├── personal/
|
||||
│ ├── server/
|
||||
│ └── remote/
|
||||
└── security/
|
||||
└── secure-boot/
|
||||
```
|
||||
|
||||
The `desktop/` name above is a form-factor profile under `profiles/platform/`,
|
||||
not a top-level module category.
|
||||
|
||||
A profile may consist only of `meta.includes`. Small settings that belong only
|
||||
to the composition and have no useful independent identity may go directly in
|
||||
the profile's `nixos.nix`, `darwin.nix`, or `home.nix`. Extract configuration to
|
||||
an appropriate application, system, service, or hardware unit when any of these
|
||||
conditions holds:
|
||||
|
||||
- It should be independently enableable.
|
||||
- Multiple profiles reuse it.
|
||||
- It owns separate configuration files.
|
||||
- Its NixOS, nix-darwin, and Home Manager implementations differ.
|
||||
- Other units depend on it.
|
||||
- It involves a daemon, permissions, or user groups.
|
||||
|
||||
## Registry Responsibilities
|
||||
|
||||
Implement unit discovery with Nix standard functionality such as
|
||||
`builtins.readDir`. Do not depend on an external indiscriminate auto-import
|
||||
mechanism, and do not design the repository around `import-tree`. Registry logic
|
||||
has these responsibilities:
|
||||
|
||||
1. Recursively visit directories below `modules/`.
|
||||
2. Check only the five reserved filenames directly within each directory.
|
||||
3. Register a directory as a unit when at least one reserved file exists there.
|
||||
4. Derive the unit ID from the path relative to `modules/`.
|
||||
5. Record only class fragments that exist.
|
||||
6. Evaluate `meta.nix` as a descriptor only when it exists.
|
||||
7. Exclude non-reserved files from discovery and implicit imports.
|
||||
8. Generate every unit's `my.<unit path>.enable` option.
|
||||
9. Enable included units from `meta.includes`.
|
||||
10. Raise a clear evaluation error for a reference to a missing unit ID.
|
||||
11. Apply only the fragments appropriate to the current host class.
|
||||
12. Pass `home.nix` to Home Manager only for hosts that enable Home Manager.
|
||||
|
||||
A unit record may conceptually look like this; the implementation need not use
|
||||
this exact representation:
|
||||
|
||||
```nix
|
||||
{
|
||||
id = "applications.ghostty";
|
||||
directory = ./applications/ghostty;
|
||||
|
||||
fragments = {
|
||||
common = null;
|
||||
nixos = null;
|
||||
darwin = null;
|
||||
home = ./applications/ghostty/home.nix;
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home-manager.sharedModules = [
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
zoom-us # Video conferencing application
|
||||
];
|
||||
}
|
||||
meta = { };
|
||||
}
|
||||
```
|
||||
|
||||
Keep the custom Registry limited to unit discovery, enable-option generation,
|
||||
`includes`, and class dispatch. Do not reimplement general Nix imports or Nix
|
||||
module evaluation. In particular, never infer a unit ID from metadata or
|
||||
implicitly load a non-reserved file.
|
||||
|
||||
## Hosts and Class Dispatch
|
||||
|
||||
`hosts/` is outside Registry discovery. A host contains machine-specific facts,
|
||||
differences, and unit selection, not reusable shared configuration. Appropriate
|
||||
host-owned data includes:
|
||||
|
||||
- Generated `hardware-configuration.nix`.
|
||||
- Disk UUIDs and disko target devices.
|
||||
- Monitor identifiers, layout, and scale.
|
||||
- MAC addresses and static IP addresses.
|
||||
- Kernel parameters required by one machine only.
|
||||
- `system.stateVersion`.
|
||||
- Host-specific secret references.
|
||||
- The profiles, applications, and other units enabled on that host.
|
||||
|
||||
A host registry may use a specification like this:
|
||||
|
||||
```nix
|
||||
# hosts/default.nix
|
||||
{
|
||||
x1g13 = {
|
||||
system = "x86_64-linux";
|
||||
user = "moons";
|
||||
path = ./x1g13;
|
||||
|
||||
profiles = [
|
||||
"base"
|
||||
"platform.thinkpad"
|
||||
"interface.niri"
|
||||
"interface.gnome"
|
||||
"workload.development"
|
||||
"workload.personal"
|
||||
"security.secure-boot"
|
||||
];
|
||||
|
||||
applications = [
|
||||
"codex-desktop"
|
||||
];
|
||||
|
||||
units = [
|
||||
"services.tailscale"
|
||||
];
|
||||
};
|
||||
|
||||
macbook = {
|
||||
system = "aarch64-darwin";
|
||||
user = "moons";
|
||||
path = ./macbook;
|
||||
|
||||
profiles = [
|
||||
"base"
|
||||
"platform.laptop"
|
||||
"workload.development"
|
||||
"workload.personal"
|
||||
];
|
||||
|
||||
applications = [
|
||||
"ghostty"
|
||||
];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Complex Module(NixOS + Home Manager)
|
||||
|
||||
ディレクトリ構造で system と home を分離:
|
||||
|
||||
```
|
||||
modules/applications/<app>/
|
||||
├── default.nix # マスター enable + imports
|
||||
├── system.nix # NixOS 設定
|
||||
├── home.nix # Home Manager 設定
|
||||
└── (other files) # 設定ファイル等
|
||||
```
|
||||
|
||||
**default.nix** — `enable` のみ宣言。`system.enable`/`homeManager.enable` は sub-file に任せる:
|
||||
Treat entries in `profiles` and `applications` as IDs relative to their
|
||||
respective category roots. Add the category prefixes during host construction:
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.<name>;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.<name> = {
|
||||
enable = lib.mkEnableOption "<description>";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.<name>.system.enable = lib.mkDefault true;
|
||||
my.applications.<name>.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
selectedUnits =
|
||||
[ "users.${spec.user}" ]
|
||||
++ map (name: "profiles.${name}") spec.profiles
|
||||
++ map (name: "applications.${name}") spec.applications
|
||||
++ spec.units or [ ];
|
||||
```
|
||||
|
||||
**system.nix:**
|
||||
`units` is an escape hatch for fully qualified service, system, hardware, or
|
||||
other unit IDs. Prefer profiles for the main composition; do not make hosts list
|
||||
large numbers of low-level units directly.
|
||||
|
||||
```nix
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.<name>.system;
|
||||
in
|
||||
{
|
||||
options.my.applications.<name>.system = {
|
||||
enable = lib.mkEnableOption "<name> system configuration";
|
||||
};
|
||||
Host modules use normal Nix module semantics and are not Registry-guarded
|
||||
configuration fragments. For example:
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
<package> # Description
|
||||
];
|
||||
};
|
||||
}
|
||||
```text
|
||||
hosts/x1g13/
|
||||
├── nixos.nix
|
||||
├── home.nix
|
||||
├── hardware-configuration.nix
|
||||
└── disko.nix
|
||||
```
|
||||
|
||||
**home.nix** — `home-manager.sharedModules` を使用:
|
||||
`hosts/x1g13/nixos.nix` may explicitly load `hardware-configuration.nix` and
|
||||
`disko.nix` with the normal top-level Nix module `imports`. Do not confuse these
|
||||
host imports with the prohibition on top-level `imports` in unit configuration
|
||||
fragments.
|
||||
|
||||
```nix
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.<name>;
|
||||
hmCfg = config.my.applications.<name>.homeManager;
|
||||
in
|
||||
{
|
||||
options.my.applications.<name>.homeManager = {
|
||||
enable = lib.mkEnableOption "<name> home-manager configuration";
|
||||
};
|
||||
Derive the system class from the host's `system`:
|
||||
|
||||
config.home-manager.sharedModules = [
|
||||
{
|
||||
config = lib.mkIf hmCfg.enable {
|
||||
# home-manager 設定をここに書く
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
```
|
||||
- A Linux NixOS host receives `common.nix` and `nixos.nix`.
|
||||
- A nix-darwin host receives `common.nix` and `darwin.nix`.
|
||||
- A host with integrated Home Manager additionally receives `home.nix`.
|
||||
|
||||
**注意点:**
|
||||
Home Manager is additive, not a system class mutually exclusive with NixOS or
|
||||
nix-darwin. The supported combinations are NixOS plus Home Manager and
|
||||
nix-darwin plus Home Manager. If standalone Home Manager is supported later, add
|
||||
an explicit host kind because `system` alone cannot distinguish it from NixOS.
|
||||
|
||||
- `default.nix` では `enable` のみ宣言。`system.enable`/`homeManager.enable` は `system.nix`/`home.nix` で宣言する(重複宣言エラー回避)
|
||||
- home.nix で親の `cfg` を参照する場合は `cfg` と `hmCfg` の両方を let で定義
|
||||
- Complex Module の home-manager 設定は `home-manager.sharedModules` で記述(`home-manager.users.<user>` は使わない)
|
||||
Do not duplicate reusable settings in hosts, but do not force genuinely
|
||||
machine-specific values into a common unit merely to remove a host-local line.
|
||||
|
||||
### Feature Module
|
||||
## Coding Style and Implementation Rules
|
||||
|
||||
**application/system を束ねる場合:**
|
||||
Use two-space indentation in Nix files and let `nixfmt` decide layout. Prefer
|
||||
small units, explicit imports, and descriptive kebab-case names, for example
|
||||
`modules/services/media-server/nixos.nix`. Use camelCase for Nix attributes
|
||||
unless an upstream option dictates otherwise. Shell snippets must pass `shfmt`
|
||||
and `shellcheck`; YAML, TOML, and Markdown are formatted by the configured
|
||||
treefmt tools.
|
||||
|
||||
```nix
|
||||
# modules/features/services/container.nix
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
cfg = config.my.features.services.container;
|
||||
in
|
||||
{
|
||||
options.my.features.services.container = {
|
||||
enable = lib.mkEnableOption "Container runtime (Docker)";
|
||||
};
|
||||
When implementing or modifying modules:
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.docker.enable = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
- Do not create `features/` or a top-level `desktop/` module category.
|
||||
- Do not add per-unit `mkEnableOption`, `cfg`, or `mkIf` boilerplate; the Registry
|
||||
derives and guards enable options from paths.
|
||||
- Put unit dependencies in `meta.includes`, not in direct assignments to another
|
||||
unit's enable option from a class fragment.
|
||||
- Do not assume any non-reserved file is discovered or loaded automatically.
|
||||
- Do not require an `_` prefix for helper or private files.
|
||||
- Do not create unused `common.nix`, `nixos.nix`, `darwin.nix`, `home.nix`, or
|
||||
`meta.nix` files.
|
||||
- Do not override a path-derived unit ID from `meta.nix`.
|
||||
- Keep technical application dependencies separate from the applications a
|
||||
personal environment chooses to combine in a profile.
|
||||
- Do not rely on module-list ordering to override values. Use Nix module
|
||||
priorities such as `lib.mkDefault`, `lib.mkForce`, `lib.mkBefore`, or
|
||||
`lib.mkAfter` explicitly when required.
|
||||
- Keep Registry responsibilities narrow; use normal Nix imports and module
|
||||
evaluation for everything outside discovery, generated enables, includes, and
|
||||
class dispatch.
|
||||
|
||||
**パッケージを直接追加する場合(application/system に属さない):**
|
||||
## Build, Test, and Development Commands
|
||||
|
||||
```nix
|
||||
# modules/features/gui/capture.nix
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
cfg = config.my.features.gui.capture;
|
||||
in
|
||||
{
|
||||
options.my.features.gui.capture = {
|
||||
enable = lib.mkEnableOption "Screen capture tools";
|
||||
};
|
||||
- `nix develop .#dotnix` enters the main development shell and installs the
|
||||
repository's pre-commit hooks.
|
||||
- `nix develop .#android` provides Android platform tools such as `adb` and
|
||||
`fastboot`.
|
||||
- `nix fmt` formats all supported files through treefmt.
|
||||
- `nix flake check` evaluates flake outputs and runs configured checks.
|
||||
- `pre-commit run --all-files` runs formatting, dead-code and static Nix checks,
|
||||
shell linting, and secret scanning.
|
||||
- `nix flake update` refreshes pinned inputs in `flake.lock`; review lockfile
|
||||
changes before committing.
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
slurp # Tool for selecting a region of the screen
|
||||
grim # Screenshot tool for Wayland
|
||||
];
|
||||
};
|
||||
}
|
||||
```
|
||||
If direnv is installed, `direnv allow` activates the `dotnix` shell from `.envrc`
|
||||
automatically.
|
||||
|
||||
**オプションを passthrough する場合:**
|
||||
## Testing Guidelines
|
||||
|
||||
```nix
|
||||
# modules/features/network/tailscale.nix
|
||||
{
|
||||
options.my.features.network.tailscale = {
|
||||
enable = lib.mkEnableOption "Tailscale VPN";
|
||||
acceptDns = lib.mkOption { type = lib.types.bool; default = false; };
|
||||
};
|
||||
There is no separate unit-test suite. Before submitting changes, run
|
||||
`nix flake check` and `pre-commit run --all-files`. For system-specific changes,
|
||||
also build or evaluate the affected NixOS, nix-darwin, or Home Manager
|
||||
configuration without switching the live machine. Never commit generated
|
||||
secrets, `.age` plaintext, or local `.direnv/` state.
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.tailscale = {
|
||||
enable = true;
|
||||
inherit (cfg) acceptDns;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
For Registry changes, test discovery of each supported fragment combination,
|
||||
dependency closure through `meta.includes`, missing-unit errors, and class
|
||||
dispatch. Verify that helper files are ignored until explicitly imported and
|
||||
that directories without a directly contained reserved file remain namespaces.
|
||||
|
||||
**home.activation を使う場合(identity 等):**
|
||||
## Commit and Pull Request Guidelines
|
||||
|
||||
```nix
|
||||
# modules/features/identity/ssh-default-key.nix
|
||||
config.home-manager.sharedModules = [
|
||||
(
|
||||
{ lib, ... }:
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.activation.generateSshKey = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
|
||||
# shell script here
|
||||
'';
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
```
|
||||
|
||||
### Profile
|
||||
|
||||
features の有効化のみを記述:
|
||||
|
||||
```nix
|
||||
# profiles/platforms/laptop.nix
|
||||
{
|
||||
my.features = {
|
||||
boot.power.enable = true;
|
||||
connect = {
|
||||
wifi.enable = true;
|
||||
bluetooth.enable = true;
|
||||
};
|
||||
gui.camera.enable = true;
|
||||
identity.fingerprint.enable = true;
|
||||
network.tailscale.enable = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Adding New Features — Checklist
|
||||
|
||||
### 新しいアプリケーションを追加する場合
|
||||
|
||||
1. `modules/applications/` にモジュール作成(Simple or Complex)
|
||||
2. `modules/applications/default.nix` の `imports` に追加
|
||||
3. `modules/features/` の適切なカテゴリに feature を作成(既存の feature に追記でも可)
|
||||
4. `modules/features/<category>/default.nix` の `imports` に追加
|
||||
5. `profiles/` の適切な profile で feature を有効化
|
||||
|
||||
### 新しいシステム設定を追加する場合
|
||||
|
||||
1. `modules/system/` にモジュール作成(Simple Module)
|
||||
2. `modules/system/default.nix` の `imports` に追加
|
||||
3. `modules/features/` の適切なカテゴリに feature を作成
|
||||
4. `modules/features/<category>/default.nix` の `imports` に追加
|
||||
5. `profiles/` の適切な profile で feature を有効化
|
||||
|
||||
### 新しいホストを追加する場合
|
||||
|
||||
1. `hosts/<hostname>/default.nix` を作成(`hardware-configuration.nix` を import)
|
||||
2. `hosts/default.nix` の `flake.nixosConfigurations` に `mkSystem` で追加
|
||||
3. profiles のリストを指定
|
||||
|
||||
## Key Technical Notes
|
||||
|
||||
- **nixpkgs channel**: `nixos-26.05` (stable) + `nixpkgs-unstable`
|
||||
- **unstable パッケージ**: `specialArgs.unstable` 経由で参照(`unstable.<pkg>`)
|
||||
- **llm-agents**: `inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.<name>` で参照。overlay も `hosts/default.nix` でグローバルに適用
|
||||
- **nixvim**: `nixpkgs.source = pkgs.path` と `nixpkgs.config.allowUnfree = true` を vim/home/default.nix で設定
|
||||
- **home-manager**: `useGlobalPkgs = true`, `useUserPackages = true`, `backupFileExtension = "backup"`
|
||||
- **hostname**: `specialArgs.host` から `modules/system/network/default.nix` で `networking.hostName` に設定
|
||||
- **stateVersion**: `config.my.stateVersions.nixos` / `config.my.stateVersions.homeManager` で管理(`modules/system/version.nix`)
|
||||
- **disko**: `modules/system/disko.nix` で disk パーティション管理。ホスト固有の `disko.nix` を import
|
||||
- **stylix**: `inputs.stylix` でテーマ管理
|
||||
Recent history favors short, lowercase, imperative subjects such as `fix` and
|
||||
`update action`; automated dependency commits use `chore(deps): ...`. Prefer a
|
||||
specific summary that states the affected area, such as
|
||||
`shells: add deployment tools`. Keep commits focused. Pull requests should
|
||||
explain the motivation, list affected hosts or profiles, report validation
|
||||
commands, and note any manual migration or secret-management steps. Include
|
||||
screenshots only for visible desktop or application configuration changes.
|
||||
|
||||
@@ -1,191 +1,3 @@
|
||||
# dotfiles
|
||||
# moons14 dotfiles
|
||||
|
||||
My NixOS + Home Manager configurations built with flake-parts.
|
||||
|
||||
## Overview
|
||||
|
||||
- **OS**: NixOS 26.05 (stable) + nixpkgs-unstable
|
||||
- **Window Manager**: Niri (Wayland)
|
||||
- **Shell**: Zsh
|
||||
- **Terminal**: Ghostty
|
||||
- **Editor**: Neovim (nixvim), VSCode
|
||||
- **Launcher**: Vicinae
|
||||
- **Theme**: Stylix (Dracula)
|
||||
- **Secrets**: sops-nix + age + YubiKey
|
||||
|
||||
## Hosts
|
||||
|
||||
| Host | Description | Profiles |
|
||||
| ------------- | --------------- | -------------------------------------------- |
|
||||
| `x1g13` | ThinkPad laptop | gui, thinkpad, dev, personal, secure-storage |
|
||||
| `nix-example` | VM | cli-interactive, vm, dev, remote |
|
||||
| `installer` | NixOS installer | (standalone) |
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── flake.nix # Flake inputs and outputs
|
||||
├── flake/
|
||||
│ ├── formatter.nix # treefmt configuration (nixfmt, deadnix, statix, etc.)
|
||||
│ └── git-hooks.nix # pre-commit hooks
|
||||
├── hosts/
|
||||
│ ├── default.nix # mkSystem helper and host definitions
|
||||
│ ├── x1g13/ # ThinkPad host config
|
||||
│ ├── nix-example/ # VM host config
|
||||
│ └── installer/ # Installer ISO config
|
||||
├── modules/
|
||||
│ ├── applications/ # Application configs (NixOS + Home Manager)
|
||||
│ │ ├── niri/ # Wayland compositor
|
||||
│ │ ├── ghostty/ # Terminal emulator
|
||||
│ │ ├── vim/ # Neovim (nixvim)
|
||||
│ │ ├── vscode/ # VSCode
|
||||
│ │ ├── zsh/ # Shell
|
||||
│ │ ├── zellij/ # Terminal multiplexer
|
||||
│ │ ├── git/ # Git config
|
||||
│ │ ├── docker.nix # Container runtime
|
||||
│ │ ├── tailscale.nix # VPN
|
||||
│ │ ├── claude/ # Claude Code
|
||||
│ │ ├── opencode.nix # OpenCode
|
||||
│ │ └── ... # chrome, discord, zoom, slack, etc.
|
||||
│ ├── system/ # NixOS system configs
|
||||
│ │ ├── audio.nix # PipeWire
|
||||
│ │ ├── boot/ # Bootloader (systemd-boot, lanzaboote)
|
||||
│ │ ├── disko.nix # Disk partitioning
|
||||
│ │ ├── fonts.nix # Fonts
|
||||
│ │ ├── network/ # Networking
|
||||
│ │ ├── sops.nix # Secrets management
|
||||
│ │ ├── user/ # User accounts
|
||||
│ │ └── ...
|
||||
│ ├── features/ # Feature bundles (abstraction layer)
|
||||
│ │ ├── application/ # browser, communication
|
||||
│ │ ├── boot/ # UEFI
|
||||
│ │ ├── cli/ # base, interactive, shell
|
||||
│ │ ├── connect/ # WiFi, Bluetooth
|
||||
│ │ ├── dev/ # agent, nix, python, bun, java, arduino
|
||||
│ │ ├── gui/ # desktop, terminal, audio, editor, capture
|
||||
│ │ ├── identity/ # SSH key, fingerprint
|
||||
│ │ ├── network/ # Tailscale
|
||||
│ │ ├── services/ # container, KDE
|
||||
│ │ └── storage/ # disko
|
||||
│ ├── drivers/ # Hardware drivers (Intel)
|
||||
│ └── integrations/ # Home Manager integration
|
||||
├── profiles/
|
||||
│ ├── interfaces/ # cli-minimal, cli-interactive, gui
|
||||
│ ├── platforms/ # desktop, laptop, thinkpad, vm
|
||||
│ └── workloads/ # dev, personal, srv, remote, secure-storage
|
||||
├── overlays/ # nixpkgs overlays
|
||||
├── shells/ # devShells (pre-commit hooks, sops, age)
|
||||
├── secrets/ # Encrypted secrets (sops)
|
||||
└── docs/ # Documentation
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
profile (enable features)
|
||||
→ features (bundle applications/system + add packages)
|
||||
→ applications (system.nix + home.nix)
|
||||
→ system (NixOS config)
|
||||
```
|
||||
|
||||
### Module Patterns
|
||||
|
||||
**Simple Module** — Single file for NixOS-only or Home Manager-only configs:
|
||||
|
||||
```nix
|
||||
{ lib, config, ... }:
|
||||
let cfg = config.my.system.audio;
|
||||
in {
|
||||
options.my.system.audio.enable = lib.mkEnableOption "Audio";
|
||||
config = lib.mkIf cfg.enable { ... };
|
||||
}
|
||||
```
|
||||
|
||||
**Complex Module** — Directory with `default.nix`, `system.nix`, `home.nix`:
|
||||
|
||||
```
|
||||
modules/applications/<app>/
|
||||
├── default.nix # Master enable + imports
|
||||
├── system.nix # NixOS config
|
||||
└── home.nix # Home Manager config (sharedModules)
|
||||
```
|
||||
|
||||
**Feature Module** — Bundles multiple applications/system modules:
|
||||
|
||||
```nix
|
||||
{ lib, config, ... }:
|
||||
let cfg = config.my.features.gui.desktop;
|
||||
in {
|
||||
options.my.features.gui.desktop.enable = lib.mkEnableOption "Desktop";
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications = { niri.enable = true; gtk.enable = true; ... };
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
**Profile** — Thin layer that only enables features:
|
||||
|
||||
```nix
|
||||
{
|
||||
my.features = {
|
||||
gui.desktop.enable = true;
|
||||
dev.agent.enable = true;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Packages
|
||||
|
||||
### CLI
|
||||
|
||||
- **Shell**: Zsh with zoxide, direnv
|
||||
- **Terminal multiplexer**: Zellij
|
||||
- **Editor**: Neovim (nixvim)
|
||||
- **Tools**: ripgrep, curl, wget, htop, btop, fastfetch, unzip, unrar
|
||||
|
||||
### GUI
|
||||
|
||||
- **Compositor**: Niri
|
||||
- **Terminal**: Ghostty, Alacritty
|
||||
- **Editor**: VSCode
|
||||
- **Browser**: Chrome
|
||||
- **Launcher**: Vicinae
|
||||
- **File manager**: Nautilus
|
||||
- **Communication**: Discord, Zoom, Slack
|
||||
|
||||
### Development
|
||||
|
||||
- **AI agents**: Claude Code, Codex, OpenCode, Grok
|
||||
- **Languages**: Python, Bun (JavaScript/TypeScript), Java, Arduino
|
||||
- **Container**: Docker
|
||||
- **Nix**: nh, nixfmt, deadnix, statix
|
||||
|
||||
### System
|
||||
|
||||
- **VPN**: Tailscale
|
||||
- **Secrets**: sops-nix, age
|
||||
- **Boot**: systemd-boot, lanzaboote (Secure Boot)
|
||||
- **Disk**: disko
|
||||
- **Theme**: Stylix
|
||||
|
||||
## Commands
|
||||
|
||||
```sh
|
||||
nix flake update # Update flake inputs
|
||||
nix fmt # Format code
|
||||
nix develop .#dotnix # Enter dev shell
|
||||
sudo nixos-rebuild switch --flake .#<host> # Apply config
|
||||
sudo nixos-rebuild build --flake .#<host> # Build without applying
|
||||
```
|
||||
|
||||
## Inspired
|
||||
|
||||
- [Zaney/zaneyos](https://gitlab.com/Zaney/zaneyos)
|
||||
- [fa0311/.zshrc](https://gist.github.com/fa0311/d37d53ff39c73c54c883379e8e3732df)
|
||||
- [AsianLovesLinux/Niri](https://github.com/AsianLovesLinux/Niri)
|
||||
- [natsukium/dotfiles](https://github.com/natsukium/dotfiles)
|
||||
- [dracula](https://github.com/dracula)
|
||||
- [akazdayo/nix-configs](https://github.com/akazdayo/nix-configs)
|
||||
- [yutakobayashidev/dotnix](https://github.com/yutakobayashidev/dotnix)
|
||||
- [kawaemon/dotfiles](https://github.com/kawaemon/dotfiles)
|
||||
My NixOS + Home Manager configurations build with flake.
|
||||
|
||||
Generated
+80
-89
@@ -107,11 +107,11 @@
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784823421,
|
||||
"narHash": "sha256-/EM7Cr2Ai0VjNbKv+eIW0+iXT/NBW6WbPkCbf9w+u/o=",
|
||||
"lastModified": 1785087211,
|
||||
"narHash": "sha256-lmIZA1LPcCB7vPagN3lS5mcSwVgN5GAvOxHS7CjqWzI=",
|
||||
"owner": "ilysenko",
|
||||
"repo": "codex-desktop-linux",
|
||||
"rev": "efcf40b5ab41323c8fa8eef5526c6a50c45fd8cd",
|
||||
"rev": "bc7b92cf38c74b49dbff568257542eabbc62cf55",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -376,11 +376,11 @@
|
||||
"zon2nix": "zon2nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784838920,
|
||||
"narHash": "sha256-MTNHCKPqwjVcYh+DglaR3cQugMCz1kWDajV/nx2PDhw=",
|
||||
"lastModified": 1785080636,
|
||||
"narHash": "sha256-ACiF5qaL4yiLSMesIPi4+4Aftw5QiMSR2qzp+5hlMvo=",
|
||||
"owner": "moons-14",
|
||||
"repo": "ghostty",
|
||||
"rev": "5c258c2530878166893d805fba7079b9742f1fc5",
|
||||
"rev": "f11e5199a6bd2a2e1a536d3c225a7d9a39827ea4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -469,27 +469,6 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager_3": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nix-hazkey",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1778444552,
|
||||
"narHash": "sha256-f18pIiR9q/p1vHY93gmAum7aHhQOG49oGvAB9+lptRo=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "dcebe66f958673729896eec2de4abfd86ef22d21",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"lanzaboote": {
|
||||
"inputs": {
|
||||
"crane": "crane",
|
||||
@@ -522,11 +501,11 @@
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784838505,
|
||||
"narHash": "sha256-v9wgz4KSm259C+Yb9/Y/tPyylXto/bTyOQyiV599Ads=",
|
||||
"lastModified": 1785094920,
|
||||
"narHash": "sha256-RPhNusC9jaFUkdgb6COZofPz1QLqmm8k2k9Wh7KcQII=",
|
||||
"owner": "numtide",
|
||||
"repo": "llm-agents.nix",
|
||||
"rev": "b358b1d5b458d6bd9814d02b70fcd3c0cd61886f",
|
||||
"rev": "56dea2a2de7d50461c502db975e766c2c2d71e84",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -545,11 +524,11 @@
|
||||
"xwayland-satellite-unstable": "xwayland-satellite-unstable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784686714,
|
||||
"narHash": "sha256-6HCWRBQq/U2NPY2msnnysnWczZYzEzhS1UZURmrr2f0=",
|
||||
"lastModified": 1784874881,
|
||||
"narHash": "sha256-u4jhSIf/Un0qZB+Cn3hTTaHSI20XeAxYbA5o4faqdJs=",
|
||||
"owner": "sodiboo",
|
||||
"repo": "niri-flake",
|
||||
"rev": "4dfd38bad6150c07be6cc3fd7682787765092eea",
|
||||
"rev": "ef7a2a3d719af46b906c22a3ebfb7d65627b2cd2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -591,24 +570,24 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nix-hazkey": {
|
||||
"nix-darwin": {
|
||||
"inputs": {
|
||||
"home-manager": "home-manager_3",
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1779529080,
|
||||
"narHash": "sha256-CHa5L3I71NbPUNJp1gmmwbh91tKsZPyuRK50mLHjAVY=",
|
||||
"owner": "aster-void",
|
||||
"repo": "nix-hazkey",
|
||||
"rev": "24cb2926666836988e78ceebeb67ad6c5a387ac3",
|
||||
"lastModified": 1783744694,
|
||||
"narHash": "sha256-2cp6N3rrwnGYLTx9l6N+NI+kwrCWxvJUbj5WJhvB29A=",
|
||||
"owner": "nix-darwin",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "c3e90c89649b07d1a96e4b9dd6cd0d6e44b91a74",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "aster-void",
|
||||
"repo": "nix-hazkey",
|
||||
"owner": "nix-darwin",
|
||||
"ref": "nix-darwin-26.05",
|
||||
"repo": "nix-darwin",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
@@ -619,11 +598,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784440659,
|
||||
"narHash": "sha256-Q5kNLlWngt7TaIIZoxDKWMHjiSaNRVqr70FqWCRRfr4=",
|
||||
"lastModified": 1785046085,
|
||||
"narHash": "sha256-UiK+mmZJuLWQVhJ5b2wDzogIYWAesyRm6LA3h3Ulh3Y=",
|
||||
"owner": "nix-community",
|
||||
"repo": "nix-index-database",
|
||||
"rev": "4f8d52a3598b0dc7db7a5e7b419e3edd9d1ecfdb",
|
||||
"rev": "11665045df8b9938ef811a3bfdc65cffb02b4b70",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -735,11 +714,11 @@
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1784555310,
|
||||
"narHash": "sha256-/FCliTPgiuV1owejZFNx3Ch9irdvkOfOFl+HHZ+DrtM=",
|
||||
"lastModified": 1784963784,
|
||||
"narHash": "sha256-IZAjgNI19TdwYus6QUIMvU0cw0vWVb/5oYwpyxQXL1E=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "421eebfd0ec7bccd4abe826ce62d7e6e83129493",
|
||||
"rev": "38affae6a5768f9b61f81355c7558ee971b2afb1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -750,6 +729,22 @@
|
||||
}
|
||||
},
|
||||
"nixpkgs_10": {
|
||||
"locked": {
|
||||
"lastModified": 1770107345,
|
||||
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4533d9293756b63904b7238acb84ac8fe4c8c2c4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_11": {
|
||||
"locked": {
|
||||
"lastModified": 1772542754,
|
||||
"narHash": "sha256-WGV2hy+VIeQsYXpsLjdr4GvHv5eECMISX1zKLTedhdg=",
|
||||
@@ -765,7 +760,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_11": {
|
||||
"nixpkgs_12": {
|
||||
"locked": {
|
||||
"lastModified": 1778869304,
|
||||
"narHash": "sha256-30sZNZoA1cqF5JNO9fVX+wgiQYjB7HJqqJ4ztCDeBZE=",
|
||||
@@ -812,11 +807,11 @@
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1784555310,
|
||||
"narHash": "sha256-/FCliTPgiuV1owejZFNx3Ch9irdvkOfOFl+HHZ+DrtM=",
|
||||
"lastModified": 1784872115,
|
||||
"narHash": "sha256-THPEF2po0fsoH8gNtp+Ae0XFDJH3N/ol7xO3v6VMTJU=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "421eebfd0ec7bccd4abe826ce62d7e6e83129493",
|
||||
"rev": "335f0738cb2fa9708f3f428e39d2eae975d1338d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -828,11 +823,11 @@
|
||||
},
|
||||
"nixpkgs_5": {
|
||||
"locked": {
|
||||
"lastModified": 1784497964,
|
||||
"narHash": "sha256-vlHUuqAcbcH2RKmHbPiuQzbv1pnzzavXnI62RD0bqCU=",
|
||||
"lastModified": 1784796856,
|
||||
"narHash": "sha256-wWFrV5/Qbm+lyt5x20E/bSbfJiGKMo4RCxZV8cl/WZI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "241313f4e8e508cb9b13278c2b0fa25b9ca27163",
|
||||
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -873,11 +868,11 @@
|
||||
},
|
||||
"nixpkgs_8": {
|
||||
"locked": {
|
||||
"lastModified": 1784707089,
|
||||
"narHash": "sha256-2V/6imsUgB7mPZlHY54oeVBRDoZbPKnvzwkAHUSSufk=",
|
||||
"lastModified": 1784856561,
|
||||
"narHash": "sha256-J+Bx1Z6Oeoj2FgnBhRMKyUhhtDoOpTgXYaVLZpDjW4A=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "b3fe9581c9061c749abef42b6d4ee7b7c05c33fa",
|
||||
"rev": "597283ad8aa0b331c788e97c4c262d58877074ef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -889,18 +884,15 @@
|
||||
},
|
||||
"nixpkgs_9": {
|
||||
"locked": {
|
||||
"lastModified": 1770107345,
|
||||
"narHash": "sha256-tbS0Ebx2PiA1FRW8mt8oejR0qMXmziJmPaU1d4kYY9g=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4533d9293756b63904b7238acb84ac8fe4c8c2c4",
|
||||
"type": "github"
|
||||
"lastModified": 1784796856,
|
||||
"narHash": "sha256-vwxWgF+Gj276WznzGb1LxGsK/39HaQwgQXiU3EkC844=",
|
||||
"rev": "e2587caef70cea85dd97d7daab492899902dbf5d",
|
||||
"type": "tarball",
|
||||
"url": "https://releases.nixos.org/nixos/unstable/nixos-26.11pre1040357.e2587caef70c/nixexprs.tar.xz"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixpkgs-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
"type": "tarball",
|
||||
"url": "https://channels.nixos.org/nixos-unstable/nixexprs.tar.xz"
|
||||
}
|
||||
},
|
||||
"nixvim": {
|
||||
@@ -928,20 +920,19 @@
|
||||
},
|
||||
"noctalia": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
"nixpkgs": "nixpkgs_9"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784838755,
|
||||
"narHash": "sha256-aTAnFf29sIVE9hpolWePKscnJfkJRdyFxEkdeP4y9YQ=",
|
||||
"lastModified": 1785150509,
|
||||
"narHash": "sha256-9YohBD2ceAWQYoT/1/QZIuaqi99hgbiUgBWyV3z6/xM=",
|
||||
"owner": "noctalia-dev",
|
||||
"repo": "noctalia",
|
||||
"rev": "45ec7e33885540427d766c4a54e8f813dfdc9db9",
|
||||
"rev": "cf5c9a28fc27facf42309a558c075259e512ba66",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "noctalia-dev",
|
||||
"ref": "cachix",
|
||||
"repo": "noctalia",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -1004,7 +995,7 @@
|
||||
"lanzaboote": "lanzaboote",
|
||||
"llm-agents": "llm-agents",
|
||||
"niri-flake": "niri-flake",
|
||||
"nix-hazkey": "nix-hazkey",
|
||||
"nix-darwin": "nix-darwin",
|
||||
"nix-index-database": "nix-index-database",
|
||||
"nixos-hardware": "nixos-hardware",
|
||||
"nixos-wsl": "nixos-wsl",
|
||||
@@ -1079,7 +1070,7 @@
|
||||
},
|
||||
"soulver-cpp": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_11",
|
||||
"nixpkgs": "nixpkgs_12",
|
||||
"nixpkgs-libxml2": "nixpkgs-libxml2"
|
||||
},
|
||||
"locked": {
|
||||
@@ -1207,16 +1198,16 @@
|
||||
},
|
||||
"systems_6": {
|
||||
"locked": {
|
||||
"lastModified": 1689347949,
|
||||
"narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=",
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default-linux",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
@@ -1337,7 +1328,7 @@
|
||||
},
|
||||
"treefmt-nix_2": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_9"
|
||||
"nixpkgs": "nixpkgs_10"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784369104,
|
||||
@@ -1355,16 +1346,16 @@
|
||||
},
|
||||
"vicinae": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs_10",
|
||||
"nixpkgs": "nixpkgs_11",
|
||||
"soulver-cpp": "soulver-cpp",
|
||||
"systems": "systems_7"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784839524,
|
||||
"narHash": "sha256-B87U5HDB/6JPxSnNQwnIiwtqUWvyxzqs7lV/GPzva68=",
|
||||
"lastModified": 1785027961,
|
||||
"narHash": "sha256-F8yaTqRGGKzl5QTtMM+4I2zUCpOq4or7zuzTmXSiTMA=",
|
||||
"owner": "vicinaehq",
|
||||
"repo": "vicinae",
|
||||
"rev": "632ca79e9f8fc9721384921f28ec069ff48aaf53",
|
||||
"rev": "65c973b55df4b8f9a80e1663feeca570e3bf016c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1383,11 +1374,11 @@
|
||||
"vicinae": "vicinae_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1784504910,
|
||||
"narHash": "sha256-fzPBEJZiRvc/FNMdpbdcfaZzF01U4IQenHW9IQFzhos=",
|
||||
"lastModified": 1785084836,
|
||||
"narHash": "sha256-iww/OcxGK8isAgNh8k4E1IJkR5bGUvEK/K+q86g2ISk=",
|
||||
"owner": "vicinaehq",
|
||||
"repo": "extensions",
|
||||
"rev": "ca74eede9a778a9373c8f5fd221b0a5026dcd1ef",
|
||||
"rev": "2d5176bcb19498ff862ca1caa5eb97f03f60faac",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -11,6 +11,11 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
nix-darwin = {
|
||||
url = "github:nix-darwin/nix-darwin/nix-darwin-26.05";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
# Hardware / Platform
|
||||
nixos-hardware.url = "github:NixOS/nixos-hardware/master";
|
||||
nixos-wsl.url = "github:nix-community/NixOS-WSL";
|
||||
@@ -36,10 +41,7 @@
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
noctalia = {
|
||||
url = "github:noctalia-dev/noctalia";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
noctalia.url = "github:noctalia-dev/noctalia/cachix";
|
||||
|
||||
# Editor
|
||||
nixvim = {
|
||||
@@ -91,13 +93,7 @@
|
||||
};
|
||||
|
||||
# Systems
|
||||
systems.url = "github:nix-systems/default-linux";
|
||||
|
||||
# Japanese Input Method
|
||||
nix-hazkey = {
|
||||
url = "github:aster-void/nix-hazkey";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
systems.url = "github:nix-systems/default";
|
||||
};
|
||||
|
||||
outputs =
|
||||
@@ -111,10 +107,8 @@
|
||||
|
||||
imports = [
|
||||
./overlays
|
||||
./hosts
|
||||
./shells
|
||||
./flake/formatter.nix
|
||||
./flake/git-hooks.nix
|
||||
./flake
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
imports = [
|
||||
./formatter.nix
|
||||
./git-hooks.nix
|
||||
./registry.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
dotfilesLib = import ../libs {
|
||||
inherit inputs lib;
|
||||
root = ../.;
|
||||
};
|
||||
hostSpecsPath = ../hosts/default.nix;
|
||||
hostSpecs =
|
||||
if builtins.pathExists hostSpecsPath then
|
||||
let
|
||||
value = import hostSpecsPath;
|
||||
in
|
||||
if builtins.isFunction value then
|
||||
value (
|
||||
builtins.intersectAttrs (builtins.functionArgs value) {
|
||||
inherit inputs lib;
|
||||
}
|
||||
)
|
||||
else
|
||||
value
|
||||
else
|
||||
{ };
|
||||
configurations = dotfilesLib.hosts.mkConfigurations hostSpecs;
|
||||
in
|
||||
{
|
||||
flake = {
|
||||
inherit (configurations) darwinConfigurations nixosConfigurations;
|
||||
lib = dotfilesLib;
|
||||
};
|
||||
|
||||
perSystem =
|
||||
{ pkgs, system, ... }:
|
||||
let
|
||||
nixosChecks =
|
||||
lib.mapAttrs' (name: nixos: lib.nameValuePair "nixos-${name}" nixos.config.system.build.toplevel)
|
||||
(
|
||||
lib.filterAttrs (
|
||||
_: nixos: nixos.pkgs.stdenv.hostPlatform.system == system
|
||||
) configurations.nixosConfigurations
|
||||
);
|
||||
in
|
||||
{
|
||||
checks = {
|
||||
registry = import ../tests/registry.nix {
|
||||
inherit inputs lib pkgs;
|
||||
};
|
||||
}
|
||||
// nixosChecks;
|
||||
};
|
||||
}
|
||||
+26
-107
@@ -1,113 +1,32 @@
|
||||
{
|
||||
inputs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (inputs.nixpkgs.lib) nixosSystem;
|
||||
x1g9 = {
|
||||
system = "x86_64-linux";
|
||||
stateVersion = "26.05";
|
||||
user = "moons";
|
||||
path = ./x1g9;
|
||||
|
||||
username = "moons";
|
||||
|
||||
mkSystem =
|
||||
{
|
||||
host,
|
||||
system,
|
||||
profiles ? [ ],
|
||||
extraModules ? [ ],
|
||||
}:
|
||||
let
|
||||
unstable = import inputs.nixpkgs-unstable {
|
||||
inherit system;
|
||||
config = {
|
||||
allowUnfree = true;
|
||||
};
|
||||
};
|
||||
in
|
||||
assert lib.assertMsg (lib.elem system config.systems)
|
||||
"mkSystem: system '${system}' not in valid systems: ${lib.generators.toPretty { } config.systems}";
|
||||
nixosSystem {
|
||||
inherit system;
|
||||
modules = [
|
||||
{
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
nixpkgs.overlays = builtins.attrValues inputs.self.overlays;
|
||||
}
|
||||
../modules
|
||||
./${host}/default.nix
|
||||
]
|
||||
++ map (p: ../profiles/${p}.nix) profiles
|
||||
++ extraModules;
|
||||
specialArgs = {
|
||||
inherit
|
||||
inputs
|
||||
username
|
||||
unstable
|
||||
host
|
||||
;
|
||||
};
|
||||
};
|
||||
|
||||
nixosConfigurations = {
|
||||
nix-example = mkSystem {
|
||||
host = "nix-example";
|
||||
system = "x86_64-linux";
|
||||
profiles = [
|
||||
"interfaces/cli-interactive"
|
||||
"platforms/vm"
|
||||
"workloads/dev"
|
||||
"workloads/remote"
|
||||
];
|
||||
};
|
||||
ops = mkSystem {
|
||||
host = "ops";
|
||||
system = "x86_64-linux";
|
||||
profiles = [
|
||||
"interfaces/cli-interactive"
|
||||
"platforms/vm"
|
||||
"workloads/remote"
|
||||
];
|
||||
};
|
||||
|
||||
internal-app-01 = mkSystem {
|
||||
host = "internal-app-01";
|
||||
system = "x86_64-linux";
|
||||
profiles = [
|
||||
"interfaces/cli-interactive"
|
||||
"platforms/vm"
|
||||
"workloads/srv"
|
||||
];
|
||||
};
|
||||
x1g13 = mkSystem {
|
||||
host = "x1g13";
|
||||
system = "x86_64-linux";
|
||||
profiles = [
|
||||
"interfaces/gui"
|
||||
"platforms/thinkpad"
|
||||
"workloads/dev"
|
||||
"workloads/personal"
|
||||
"workloads/secure-storage"
|
||||
"workloads/tailscale/client"
|
||||
];
|
||||
};
|
||||
|
||||
installer = nixosSystem {
|
||||
system = "x86_64-linux";
|
||||
modules = [
|
||||
./installer/default.nix
|
||||
];
|
||||
specialArgs = {
|
||||
inherit inputs;
|
||||
};
|
||||
};
|
||||
profiles = [
|
||||
"base"
|
||||
"interface.cli"
|
||||
"platform.thinkpad-x1"
|
||||
"security.fingerprint"
|
||||
"security.secrets"
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
flake = {
|
||||
inherit nixosConfigurations;
|
||||
|
||||
checks.x86_64-linux = lib.mapAttrs' (
|
||||
name: nixos: lib.nameValuePair "nixos-${name}" nixos.config.system.build.toplevel
|
||||
) nixosConfigurations;
|
||||
m2 = {
|
||||
system = "aarch64-darwin";
|
||||
stateVersion = "26.05";
|
||||
user = "moons";
|
||||
path = ./m2;
|
||||
|
||||
profiles = [
|
||||
"base"
|
||||
"interface.cli"
|
||||
"security.fingerprint"
|
||||
"security.secrets"
|
||||
"workload.development"
|
||||
"workload.personal"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
"${modulesPath}/installer/cd-dvd/installation-cd-minimal.nix"
|
||||
];
|
||||
|
||||
boot.zfs.forceImportRoot = false;
|
||||
|
||||
networking = {
|
||||
hostName = "nixos-installer";
|
||||
|
||||
networkmanager = {
|
||||
enable = true;
|
||||
wifi.powersave = false;
|
||||
};
|
||||
};
|
||||
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PermitRootLogin = "prohibit-password";
|
||||
PasswordAuthentication = false;
|
||||
KbdInteractiveAuthentication = false;
|
||||
PubkeyAuthentication = "yes";
|
||||
};
|
||||
};
|
||||
|
||||
users.users.root.openssh.authorizedKeys.keys = [
|
||||
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIKhxDkucmeCor6CKoXAua7DgDSzuXrZOtpdkyzQxz5+aAAAABHNzaDo= moons@moons14.com"
|
||||
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIN6hZJyng/5LgFKPjR6uZAd/00UkO0vN0uQOoIvfSELdAAAABHNzaDo= moons@moons14.com"
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
git # Clone dotfiles repository
|
||||
disko # Disk partitioning
|
||||
sops # Secrets management
|
||||
age # Age encryption
|
||||
ssh-to-age # Convert SSH keys to age
|
||||
age-plugin-yubikey # YubiKey support
|
||||
yubikey-manager # YubiKey management
|
||||
pcsc-tools # Smart card tools
|
||||
mkpasswd # Password hash generation
|
||||
rsync # File synchronization
|
||||
vim # Text editor
|
||||
wget # Download files
|
||||
curl # HTTP client
|
||||
jq # JSON processor
|
||||
parted # Partition tools
|
||||
cryptsetup # LUKS encryption
|
||||
btrfs-progs # Btrfs filesystem tools
|
||||
];
|
||||
|
||||
services.pcscd.enable = true;
|
||||
|
||||
environment.etc."installer-help.txt".text = ''
|
||||
|
||||
╔══════════════════════════════════════════════════════════════╗
|
||||
║ NixOS Installer ISO ║
|
||||
╠══════════════════════════════════════════════════════════════╣
|
||||
║ ║
|
||||
║ SSH Access: ║
|
||||
║ ssh root@<ip-address> ║
|
||||
║ ║
|
||||
║ Network Setup: ║
|
||||
║ Wired: Auto-configured via DHCP ║
|
||||
║ WiFi: nmcli device wifi connect <SSID> --ask ║
|
||||
║ ║
|
||||
║ Installation Workflow: ║
|
||||
║ ║
|
||||
║ 1. Clone dotfiles: ║
|
||||
║ git clone git@github.com:moons-14/dotfiles.git ~/dotfiles║
|
||||
║ ║
|
||||
║ 2. Generate SSH host key for new host: ║
|
||||
║ ssh-keygen -t ed25519 -f /tmp/ssh_host_ed25519_key -N "" ║
|
||||
║ ║
|
||||
║ 3. Get age public key from SSH host key: ║
|
||||
║ ssh-to-age -i /tmp/ssh_host_ed25519_key.pub ║
|
||||
║ ║
|
||||
║ 4. Add age key to .sops.yaml: ║
|
||||
║ cd ~/dotfiles ║
|
||||
║ # Edit .sops.yaml and add the age key ║
|
||||
║ # Add new host entry to creation_rules ║
|
||||
║ ║
|
||||
║ 5. Re-encrypt secrets: ║
|
||||
║ sops updatekeys secrets/common/system.yaml ║
|
||||
║ sops updatekeys secrets/hosts/<host>/*.yaml ║
|
||||
║ ║
|
||||
║ 6. Create disko.nix for new host: ║
|
||||
║ # Check disk devices ║
|
||||
║ lsblk -f ║
|
||||
║ ║
|
||||
║ # Create hosts/<host>/disko.nix ║
|
||||
║ # Example: LUKS + btrfs ║
|
||||
║ # See hosts/x1g13/disko.nix for reference ║
|
||||
║ ║
|
||||
║ 7. Partition disk with disko: ║
|
||||
║ nix run github:nix-community/disko -- \ ║
|
||||
║ --mode disko hosts/<host>/disko.nix ║
|
||||
║ ║
|
||||
║ 8. Copy host key to installed system: ║
|
||||
║ mkdir -p /mnt/etc/ssh ║
|
||||
║ cp /tmp/ssh_host_ed25519_key* /mnt/etc/ssh/ ║
|
||||
║ chmod 600 /mnt/etc/ssh/ssh_host_ed25519_key ║
|
||||
║ ║
|
||||
║ 9. Install NixOS: ║
|
||||
║ nixos-install --flake ~/dotfiles#<host> ║
|
||||
║ ║
|
||||
║ Disko Configuration Examples: ║
|
||||
║ ║
|
||||
║ Simple (no encryption): ║
|
||||
║ disko.devices.disk.main = { ║
|
||||
║ type = "disk"; ║
|
||||
║ device = "/dev/sda"; ║
|
||||
║ content = { ║
|
||||
║ type = "gpt"; ║
|
||||
║ partitions = { ║
|
||||
║ ESP = { size = "512M"; type = "EF00"; ║
|
||||
║ content = { type = "filesystem"; ║
|
||||
║ format = "vfat"; mountpoint = "/boot"; }; }; ║
|
||||
║ root = { size = "100%"; ║
|
||||
║ content = { type = "filesystem"; ║
|
||||
║ format = "ext4"; mountpoint = "/"; }; }; ║
|
||||
║ }; ║
|
||||
║ }; ║
|
||||
║ }; ║
|
||||
║ ║
|
||||
║ LUKS + btrfs (see hosts/x1g13/disko.nix): ║
|
||||
║ - Use partuuid for device path ║
|
||||
║ - Set askPassword = true for LUKS ║
|
||||
║ - Configure btrfs subvolumes ║
|
||||
║ ║
|
||||
╚══════════════════════════════════════════════════════════════╝
|
||||
|
||||
'';
|
||||
|
||||
systemd.services.installer-banner = {
|
||||
description = "Display installer help on console";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.coreutils}/bin/cat /etc/installer-help.txt";
|
||||
StandardOutput = "tty";
|
||||
TTYPath = "/dev/tty1";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.display-ip = {
|
||||
description = "Display IP address on console";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network-online.target" ];
|
||||
wants = [ "network-online.target" ];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
ExecStart = pkgs.writeShellScript "display-ip" ''
|
||||
sleep 2
|
||||
echo ""
|
||||
echo "=== Network Interfaces ==="
|
||||
${pkgs.iproute2}/bin/ip -4 addr show | ${pkgs.gnugrep}/bin/grep inet
|
||||
echo ""
|
||||
echo "=== SSH Access ==="
|
||||
for ip in $(${pkgs.iproute2}/bin/ip -4 addr show | ${pkgs.gnugrep}/bin/grep -oP 'inet \K[\d.]+' | ${pkgs.gnugrep}/bin/grep -v '127.0.0.1'); do
|
||||
echo " ssh root@$ip"
|
||||
done
|
||||
echo ""
|
||||
'';
|
||||
StandardOutput = "tty";
|
||||
TTYPath = "/dev/tty1";
|
||||
};
|
||||
};
|
||||
|
||||
nix = {
|
||||
settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
trusted-users = [ "root" ];
|
||||
};
|
||||
|
||||
extraOptions = ''
|
||||
experimental-features = nix-command flakes
|
||||
'';
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
|
||||
system.stateVersion = "26.05";
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ lib, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"ata_piix"
|
||||
"uhci_hcd"
|
||||
"virtio_pci"
|
||||
"virtio_scsi"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/1b12ab98-2537-4207-a3f4-bb8ba7b53b00";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/8365-C778";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{ hostName, ... }:
|
||||
{
|
||||
# networking.hostName and networking.localHostName are derived from the
|
||||
# registry name; computerName controls the user-visible macOS name.
|
||||
networking.computerName = hostName;
|
||||
|
||||
# Keep this value stable after the first activation. It is independent of
|
||||
# the Home Manager stateVersion in hosts/default.nix.
|
||||
system.stateVersion = 7;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"ata_piix"
|
||||
"uhci_hcd"
|
||||
"virtio_pci"
|
||||
"virtio_scsi"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/8f0eaec6-5dc9-4821-aa8d-fb6809b5a5bf";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/201C-961B";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
networking = {
|
||||
useDHCP = false;
|
||||
|
||||
interfaces = {
|
||||
ens18 = {
|
||||
useDHCP = false;
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "10.50.128.20";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
ens19 = {
|
||||
useDHCP = false;
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "10.50.7.101";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
ens20 = {
|
||||
useDHCP = false;
|
||||
ipv4.routes = [
|
||||
{
|
||||
address = "10.50.64.0";
|
||||
prefixLength = 24;
|
||||
via = "10.50.82.1";
|
||||
}
|
||||
];
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "10.50.82.10";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
defaultGateway = {
|
||||
address = "10.50.128.1";
|
||||
interface = "ens18";
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"ata_piix"
|
||||
"uhci_hcd"
|
||||
"virtio_pci"
|
||||
"virtio_scsi"
|
||||
"sd_mod"
|
||||
"sr_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/69fa2193-1e4f-438a-8898-5de8a3f36e5b";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/D09B-4277";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
./disko.nix
|
||||
];
|
||||
|
||||
boot.initrd.luks.devices.cryptroot.device =
|
||||
"/dev/disk/by-partuuid/311d0f9c-f35f-42e6-b6fc-a4d67dd21b2e";
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
_:
|
||||
let
|
||||
espPart = "/dev/disk/by-partuuid/a53e3b19-67de-40de-9ded-3eac3117689a";
|
||||
|
||||
nixosPart = "/dev/disk/by-partuuid/311d0f9c-f35f-42e6-b6fc-a4d67dd21b2e";
|
||||
|
||||
btrfsMountOptions = [
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
"ssd"
|
||||
"space_cache=v2"
|
||||
];
|
||||
in
|
||||
{
|
||||
disko.enableConfig = true;
|
||||
|
||||
disko.devices.disk = {
|
||||
esp = {
|
||||
type = "disk";
|
||||
device = espPart;
|
||||
destroy = false;
|
||||
|
||||
content = {
|
||||
type = "filesystem";
|
||||
format = "vfat";
|
||||
mountpoint = "/boot";
|
||||
mountOptions = [
|
||||
"umask=0077"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
nixos = {
|
||||
type = "disk";
|
||||
device = nixosPart;
|
||||
destroy = false;
|
||||
|
||||
content = {
|
||||
type = "luks";
|
||||
name = "cryptroot";
|
||||
|
||||
askPassword = true;
|
||||
|
||||
settings = {
|
||||
allowDiscards = true;
|
||||
};
|
||||
|
||||
extraFormatArgs = [
|
||||
"--type"
|
||||
"luks2"
|
||||
"--pbkdf"
|
||||
"argon2id"
|
||||
"--label"
|
||||
"NixOS-LUKS"
|
||||
];
|
||||
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = [
|
||||
"-f"
|
||||
"-L"
|
||||
"NixOS"
|
||||
];
|
||||
|
||||
subvolumes = {
|
||||
"@root" = {
|
||||
mountpoint = "/";
|
||||
mountOptions = btrfsMountOptions;
|
||||
};
|
||||
|
||||
"@home" = {
|
||||
mountpoint = "/home";
|
||||
mountOptions = btrfsMountOptions;
|
||||
};
|
||||
|
||||
"@nix" = {
|
||||
mountpoint = "/nix";
|
||||
mountOptions = btrfsMountOptions;
|
||||
};
|
||||
|
||||
"@log" = {
|
||||
mountpoint = "/var/log";
|
||||
mountOptions = btrfsMountOptions;
|
||||
};
|
||||
|
||||
"@swap" = {
|
||||
mountpoint = "/.swapvol";
|
||||
mountOptions = [
|
||||
"noatime"
|
||||
];
|
||||
|
||||
swap.swapfile.size = "32G";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"thunderbolt"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"thunderbolt"
|
||||
"nvme"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/16b29578-6836-414b-a5e1-863bc21c5fc3";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/209A-C8C9";
|
||||
fsType = "vfat";
|
||||
options = [
|
||||
"fmask=0077"
|
||||
"dmask=0077"
|
||||
];
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp0s20f3.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
{ ... }:
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
inputs,
|
||||
lib ? inputs.nixpkgs.lib,
|
||||
root,
|
||||
}:
|
||||
let
|
||||
registry = import ./registry.nix {
|
||||
inherit inputs lib;
|
||||
modulesRoot = root + "/modules";
|
||||
};
|
||||
hosts = import ./hosts.nix {
|
||||
inherit inputs lib registry;
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit hosts registry;
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
registry,
|
||||
}:
|
||||
let
|
||||
ensure =
|
||||
condition: message: value:
|
||||
if condition then value else throw "host registry: ${message}";
|
||||
|
||||
isLinux = system: lib.hasSuffix "-linux" system;
|
||||
isDarwin = system: lib.hasSuffix "-darwin" system;
|
||||
|
||||
hostFile =
|
||||
spec: name:
|
||||
let
|
||||
path = spec.path + "/${name}";
|
||||
in
|
||||
if builtins.pathExists path then path else null;
|
||||
|
||||
selectedUnits =
|
||||
spec:
|
||||
[ "users.${spec.user}" ]
|
||||
++ map (name: "profiles.${name}") (spec.profiles or [ ])
|
||||
++ map (name: "applications.${name}") (spec.applications or [ ])
|
||||
++ (spec.units or [ ]);
|
||||
|
||||
validateSpec =
|
||||
name: spec:
|
||||
ensure (builtins.isAttrs spec) "${name}: host specification must be an attribute set" (
|
||||
ensure (spec ? system && builtins.isString spec.system) "${name}: system is required" (
|
||||
ensure (isLinux spec.system || isDarwin spec.system)
|
||||
"${name}: unsupported system '${spec.system}'; expected a Linux NixOS or Darwin system"
|
||||
(
|
||||
ensure (spec ? user && builtins.isString spec.user && spec.user != "") "${name}: user is required" (
|
||||
ensure (spec ? path && builtins.pathExists spec.path)
|
||||
"${name}: path must name an existing host directory"
|
||||
(
|
||||
ensure
|
||||
(
|
||||
spec ? stateVersion
|
||||
&& builtins.isString spec.stateVersion
|
||||
&& builtins.match "[0-9][0-9]\\.[0-9][0-9]" spec.stateVersion != null
|
||||
)
|
||||
"${name}: stateVersion is required and must have the form YY.MM"
|
||||
(
|
||||
ensure
|
||||
(lib.all
|
||||
(field: builtins.isList (spec.${field} or [ ]) && lib.all builtins.isString (spec.${field} or [ ]))
|
||||
[
|
||||
"profiles"
|
||||
"applications"
|
||||
"units"
|
||||
]
|
||||
)
|
||||
"${name}: profiles, applications, and units must be lists of strings"
|
||||
(ensure (builtins.isBool (spec.homeManager or true)) "${name}: homeManager must be a boolean" spec)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
mkSpecialArgs = name: spec: {
|
||||
inherit inputs registry;
|
||||
inherit (spec) system;
|
||||
hostName = name;
|
||||
primaryUser = spec.user;
|
||||
};
|
||||
|
||||
mkHomeManagerModule =
|
||||
name: spec: selected:
|
||||
let
|
||||
homePath = hostFile spec "home.nix";
|
||||
homeModules = [
|
||||
(registry.mkModule { class = "home"; })
|
||||
(registry.mkSelectionModule selected)
|
||||
{ home.stateVersion = spec.stateVersion; }
|
||||
]
|
||||
++ lib.optional (homePath != null) homePath;
|
||||
in
|
||||
{
|
||||
imports = [ inputs.home-manager.nixosModules.home-manager ];
|
||||
|
||||
home-manager = {
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
extraSpecialArgs = mkSpecialArgs name spec;
|
||||
users.${spec.user}.imports = homeModules;
|
||||
};
|
||||
};
|
||||
|
||||
mkDarwinHomeManagerModule =
|
||||
name: spec: selected:
|
||||
let
|
||||
homePath = hostFile spec "home.nix";
|
||||
homeModules = [
|
||||
(registry.mkModule { class = "home"; })
|
||||
(registry.mkSelectionModule selected)
|
||||
{ home.stateVersion = spec.stateVersion; }
|
||||
]
|
||||
++ lib.optional (homePath != null) homePath;
|
||||
in
|
||||
{
|
||||
imports = [ inputs.home-manager.darwinModules.home-manager ];
|
||||
|
||||
home-manager = {
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
extraSpecialArgs = mkSpecialArgs name spec;
|
||||
users.${spec.user}.imports = homeModules;
|
||||
};
|
||||
};
|
||||
|
||||
mkNixos =
|
||||
name: rawSpec:
|
||||
let
|
||||
spec = validateSpec name rawSpec;
|
||||
selected = registry.validateUnitIds (selectedUnits spec);
|
||||
nixosPath = hostFile spec "nixos.nix";
|
||||
modules = [
|
||||
(registry.mkModule { class = "nixos"; })
|
||||
(registry.mkSelectionModule selected)
|
||||
{
|
||||
networking.hostName = lib.mkDefault name;
|
||||
system.stateVersion = spec.stateVersion;
|
||||
}
|
||||
]
|
||||
++ lib.optional (spec.homeManager or true) (mkHomeManagerModule name spec selected)
|
||||
++ lib.optional (nixosPath != null) nixosPath;
|
||||
in
|
||||
inputs.nixpkgs.lib.nixosSystem {
|
||||
inherit (spec) system;
|
||||
specialArgs = mkSpecialArgs name spec;
|
||||
inherit modules;
|
||||
};
|
||||
|
||||
mkDarwin =
|
||||
name: rawSpec:
|
||||
let
|
||||
spec = validateSpec name rawSpec;
|
||||
selected = registry.validateUnitIds (selectedUnits spec);
|
||||
darwinPath = hostFile spec "darwin.nix";
|
||||
modules = [
|
||||
(registry.mkModule { class = "darwin"; })
|
||||
(registry.mkSelectionModule selected)
|
||||
{
|
||||
networking.hostName = lib.mkDefault name;
|
||||
system.primaryUser = lib.mkDefault spec.user;
|
||||
}
|
||||
]
|
||||
++ lib.optional (spec.homeManager or true) (mkDarwinHomeManagerModule name spec selected)
|
||||
++ lib.optional (darwinPath != null) darwinPath;
|
||||
in
|
||||
ensure (inputs ? nix-darwin) "${name}: the nix-darwin input is required" (
|
||||
inputs.nix-darwin.lib.darwinSystem {
|
||||
inherit (spec) system;
|
||||
specialArgs = mkSpecialArgs name spec;
|
||||
inherit modules;
|
||||
}
|
||||
);
|
||||
|
||||
mkConfigurations =
|
||||
hostSpecs:
|
||||
let
|
||||
validated = lib.mapAttrs validateSpec hostSpecs;
|
||||
in
|
||||
{
|
||||
nixosConfigurations = lib.mapAttrs mkNixos (
|
||||
lib.filterAttrs (_: spec: isLinux spec.system) validated
|
||||
);
|
||||
darwinConfigurations = lib.mapAttrs mkDarwin (
|
||||
lib.filterAttrs (_: spec: isDarwin spec.system) validated
|
||||
);
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit
|
||||
mkConfigurations
|
||||
mkDarwin
|
||||
mkNixos
|
||||
selectedUnits
|
||||
;
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
modulesRoot,
|
||||
}:
|
||||
let
|
||||
reservedFiles = {
|
||||
common = "common.nix";
|
||||
nixos = "nixos.nix";
|
||||
darwin = "darwin.nix";
|
||||
home = "home.nix";
|
||||
meta = "meta.nix";
|
||||
};
|
||||
|
||||
isFile = kind: kind == "regular" || kind == "symlink";
|
||||
|
||||
ensure =
|
||||
condition: message: value:
|
||||
if condition then value else throw "unit registry: ${message}";
|
||||
|
||||
callWithAvailableArgs =
|
||||
value: availableArgs:
|
||||
if builtins.isFunction value then
|
||||
value (builtins.intersectAttrs (builtins.functionArgs value) availableArgs)
|
||||
else
|
||||
value;
|
||||
|
||||
pathFor =
|
||||
relativePath:
|
||||
if relativePath == [ ] then
|
||||
modulesRoot
|
||||
else
|
||||
modulesRoot + "/${lib.concatStringsSep "/" relativePath}";
|
||||
|
||||
entryIsFile = entries: name: builtins.hasAttr name entries && isFile entries.${name};
|
||||
|
||||
normalizeMeta =
|
||||
unit:
|
||||
let
|
||||
metaPath = unit.fragments.meta;
|
||||
importedValue =
|
||||
if metaPath == null then
|
||||
{ }
|
||||
else
|
||||
callWithAvailableArgs (import metaPath) {
|
||||
inherit inputs lib unit;
|
||||
};
|
||||
imported =
|
||||
ensure (builtins.isAttrs importedValue) "${unit.id}: meta.nix must return an attribute set"
|
||||
importedValue;
|
||||
allowedKeys = [
|
||||
"description"
|
||||
"includes"
|
||||
"imports"
|
||||
];
|
||||
unknownKeys = lib.filter (name: !(builtins.elem name allowedKeys)) (builtins.attrNames imported);
|
||||
description = imported.description or null;
|
||||
includes = imported.includes or [ ];
|
||||
imports = imported.imports or { };
|
||||
allowedImportKeys = [
|
||||
"nixos"
|
||||
"darwin"
|
||||
"home"
|
||||
];
|
||||
unknownImportKeys =
|
||||
if builtins.isAttrs imports then
|
||||
lib.filter (name: !(builtins.elem name allowedImportKeys)) (builtins.attrNames imports)
|
||||
else
|
||||
[ ];
|
||||
normalized = {
|
||||
inherit description includes;
|
||||
imports = {
|
||||
nixos = imports.nixos or [ ];
|
||||
darwin = imports.darwin or [ ];
|
||||
home = imports.home or [ ];
|
||||
};
|
||||
};
|
||||
in
|
||||
ensure (unknownKeys == [ ])
|
||||
"${unit.id}: meta.nix has unsupported keys: ${lib.concatStringsSep ", " unknownKeys}"
|
||||
(
|
||||
ensure (description == null || builtins.isString description)
|
||||
"${unit.id}: meta.description must be a string"
|
||||
(
|
||||
ensure (builtins.isList includes && lib.all builtins.isString includes)
|
||||
"${unit.id}: meta.includes must be a list of fully qualified unit IDs"
|
||||
(
|
||||
ensure (lib.unique includes == includes) "${unit.id}: meta.includes contains duplicate unit IDs" (
|
||||
ensure (builtins.isAttrs imports) "${unit.id}: meta.imports must be an attribute set" (
|
||||
ensure (unknownImportKeys == [ ])
|
||||
"${unit.id}: meta.imports has unsupported classes: ${lib.concatStringsSep ", " unknownImportKeys}"
|
||||
(
|
||||
ensure (lib.all builtins.isList [
|
||||
normalized.imports.nixos
|
||||
normalized.imports.darwin
|
||||
normalized.imports.home
|
||||
]) "${unit.id}: every meta.imports.<class> value must be a list" normalized
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
makeUnit =
|
||||
relativePath: entries:
|
||||
let
|
||||
directory = pathFor relativePath;
|
||||
id = lib.concatStringsSep "." relativePath;
|
||||
fragments = lib.mapAttrs (
|
||||
_class: fileName: if entryIsFile entries fileName then directory + "/${fileName}" else null
|
||||
) reservedFiles;
|
||||
baseUnit = {
|
||||
inherit
|
||||
id
|
||||
directory
|
||||
fragments
|
||||
relativePath
|
||||
;
|
||||
optionPath = [ "my" ] ++ relativePath ++ [ "enable" ];
|
||||
kind = builtins.head relativePath;
|
||||
name = lib.last relativePath;
|
||||
}
|
||||
//
|
||||
lib.optionalAttrs (builtins.length relativePath > 2 && builtins.head relativePath == "profiles")
|
||||
{
|
||||
group = builtins.elemAt relativePath 1;
|
||||
};
|
||||
in
|
||||
ensure (relativePath != [ ]) "the modules root cannot itself be a unit" (
|
||||
ensure (lib.all (component: component != "" && !(lib.hasInfix "." component)) relativePath)
|
||||
"${id}: path components must be non-empty and must not contain dots"
|
||||
(baseUnit // { meta = normalizeMeta baseUnit; })
|
||||
);
|
||||
|
||||
walk =
|
||||
relativePath:
|
||||
let
|
||||
directory = pathFor relativePath;
|
||||
entries = builtins.readDir directory;
|
||||
hasReservedFile = lib.any (fileName: entryIsFile entries fileName) (
|
||||
builtins.attrValues reservedFiles
|
||||
);
|
||||
childDirectories = lib.filter (name: entries.${name} == "directory") (builtins.attrNames entries);
|
||||
current = lib.optional hasReservedFile (makeUnit relativePath entries);
|
||||
children = lib.concatMap (name: walk (relativePath ++ [ name ])) childDirectories;
|
||||
in
|
||||
current ++ children;
|
||||
|
||||
discoveredUnits =
|
||||
ensure (builtins.pathExists modulesRoot) "modules root does not exist: ${toString modulesRoot}"
|
||||
(walk [ ]);
|
||||
unitsById = builtins.listToAttrs (map (unit: lib.nameValuePair unit.id unit) discoveredUnits);
|
||||
|
||||
dependencyValidation = lib.foldl' (
|
||||
valid: unit:
|
||||
lib.foldl' (
|
||||
inner: includedId:
|
||||
if builtins.hasAttr includedId unitsById then
|
||||
inner
|
||||
else
|
||||
throw "unit registry: ${unit.id} includes missing unit '${includedId}'"
|
||||
) valid unit.meta.includes
|
||||
) true discoveredUnits;
|
||||
|
||||
units = builtins.seq dependencyValidation unitsById;
|
||||
unitIds = builtins.attrNames units;
|
||||
|
||||
getUnit =
|
||||
id: if builtins.hasAttr id units then units.${id} else throw "unit registry: unknown unit '${id}'";
|
||||
|
||||
validateUnitIds =
|
||||
ids:
|
||||
ensure (
|
||||
builtins.isList ids && lib.all builtins.isString ids
|
||||
) "selected units must be a list of strings" (map (id: builtins.seq (getUnit id) id) ids);
|
||||
|
||||
optionDefinitions = lib.foldl' lib.recursiveUpdate { } (
|
||||
map (
|
||||
unit:
|
||||
lib.setAttrByPath unit.optionPath (
|
||||
lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description =
|
||||
if unit.meta.description == null then
|
||||
"Whether to enable the ${unit.id} unit."
|
||||
else
|
||||
"Whether to enable ${unit.meta.description}.";
|
||||
}
|
||||
)
|
||||
) discoveredUnits
|
||||
);
|
||||
|
||||
enabled = config: unit: lib.getAttrFromPath unit.optionPath config;
|
||||
|
||||
enableUnit = id: lib.setAttrByPath (getUnit id).optionPath true;
|
||||
|
||||
includeConfig =
|
||||
config: unit: lib.mkIf (enabled config unit) (lib.mkMerge (map enableUnit unit.meta.includes));
|
||||
|
||||
fragmentClasses = {
|
||||
nixos = [
|
||||
"common"
|
||||
"nixos"
|
||||
];
|
||||
darwin = [
|
||||
"common"
|
||||
"darwin"
|
||||
];
|
||||
home = [ "home" ];
|
||||
};
|
||||
|
||||
applyFragment =
|
||||
{
|
||||
config,
|
||||
fragmentPath,
|
||||
options,
|
||||
specialArgs,
|
||||
unit,
|
||||
}:
|
||||
let
|
||||
fragment = import fragmentPath;
|
||||
directArgs = specialArgs // {
|
||||
inherit
|
||||
config
|
||||
lib
|
||||
options
|
||||
specialArgs
|
||||
unit
|
||||
;
|
||||
};
|
||||
fragmentArgSpec = builtins.functionArgs fragment;
|
||||
fragmentArgs = builtins.listToAttrs (
|
||||
lib.concatMap (
|
||||
name:
|
||||
if builtins.hasAttr name directArgs then
|
||||
[ (lib.nameValuePair name directArgs.${name}) ]
|
||||
else if fragmentArgSpec.${name} then
|
||||
[ ]
|
||||
else
|
||||
[ (lib.nameValuePair name config._module.args.${name}) ]
|
||||
) (builtins.attrNames fragmentArgSpec)
|
||||
);
|
||||
resultValue = if builtins.isFunction fragment then fragment fragmentArgs else fragment;
|
||||
result =
|
||||
ensure (builtins.isAttrs resultValue)
|
||||
"${unit.id}: ${builtins.baseNameOf fragmentPath} must return an attribute set"
|
||||
resultValue;
|
||||
forbiddenKeys = lib.filter (name: builtins.hasAttr name result) [
|
||||
"imports"
|
||||
"options"
|
||||
"config"
|
||||
];
|
||||
in
|
||||
ensure (forbiddenKeys == [ ])
|
||||
"${unit.id}: ${builtins.baseNameOf fragmentPath} is a configuration fragment and cannot define top-level ${lib.concatStringsSep ", " forbiddenKeys}"
|
||||
result;
|
||||
|
||||
externalImports = class: lib.concatMap (unit: unit.meta.imports.${class}) discoveredUnits;
|
||||
|
||||
mkModule =
|
||||
{ class }:
|
||||
ensure (builtins.hasAttr class fragmentClasses) "unsupported module class '${class}'" (
|
||||
builtins.seq dependencyValidation (
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
options,
|
||||
specialArgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
fragmentConfigs = lib.concatMap (
|
||||
unit:
|
||||
lib.filter (value: value != null) (
|
||||
map (
|
||||
fragmentClass:
|
||||
let
|
||||
fragmentPath = unit.fragments.${fragmentClass};
|
||||
in
|
||||
if fragmentPath == null then
|
||||
null
|
||||
else
|
||||
lib.mkIf (enabled config unit) (applyFragment {
|
||||
inherit
|
||||
config
|
||||
fragmentPath
|
||||
options
|
||||
specialArgs
|
||||
unit
|
||||
;
|
||||
})
|
||||
) fragmentClasses.${class}
|
||||
)
|
||||
) discoveredUnits;
|
||||
in
|
||||
{
|
||||
imports = externalImports class;
|
||||
options = optionDefinitions;
|
||||
config = lib.mkMerge ((map (includeConfig config) discoveredUnits) ++ fragmentConfigs);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
mkSelectionModule =
|
||||
selectedIds:
|
||||
let
|
||||
checkedIds = validateUnitIds (lib.unique selectedIds);
|
||||
in
|
||||
{
|
||||
config = lib.mkMerge (map enableUnit checkedIds);
|
||||
};
|
||||
in
|
||||
{
|
||||
inherit
|
||||
getUnit
|
||||
mkModule
|
||||
mkSelectionModule
|
||||
unitIds
|
||||
units
|
||||
validateUnitIds
|
||||
;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications."1password";
|
||||
in
|
||||
{
|
||||
options.my.applications."1password" = {
|
||||
enable = lib.mkEnableOption "1Password password manager";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs._1password.enable = true;
|
||||
programs._1password-gui = {
|
||||
enable = true;
|
||||
polkitPolicyOwners = [ "moons" ];
|
||||
};
|
||||
|
||||
programs.ssh.startAgent = lib.mkForce false;
|
||||
programs.gnupg.agent.enableSSHSupport = lib.mkForce false;
|
||||
|
||||
services.gnome.gcr-ssh-agent.enable = lib.mkForce false;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
# The macOS app must live in /Applications for its background integrations,
|
||||
# including the SSH agent, to work correctly.
|
||||
homebrew = {
|
||||
enable = true;
|
||||
casks = [ "1password" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [
|
||||
pkgs._1password-cli
|
||||
]
|
||||
++ pkgs.lib.optionals pkgs.stdenv.hostPlatform.isLinux [ pkgs._1password-gui ];
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{ primaryUser, lib, ... }:
|
||||
{
|
||||
programs._1password.enable = true;
|
||||
programs._1password-gui = {
|
||||
enable = true;
|
||||
polkitPolicyOwners = [ primaryUser ];
|
||||
};
|
||||
|
||||
programs.ssh.startAgent = lib.mkForce false;
|
||||
programs.gnupg.agent.enableSSHSupport = lib.mkForce false;
|
||||
services.gnome.gcr-ssh-agent.enable = lib.mkForce false;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.arduino;
|
||||
arduinoIdeX11 = pkgs.arduino-ide.overrideAttrs (old: {
|
||||
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
|
||||
|
||||
postFixup = (old.postFixup or "") + ''
|
||||
wrapProgram $out/bin/arduino-ide \
|
||||
--add-flags "--ozone-platform=x11"
|
||||
'';
|
||||
});
|
||||
in
|
||||
{
|
||||
options.my.applications.arduino = {
|
||||
enable = lib.mkEnableOption "Arduino development tools";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
arduino-cli # Arduino command-line interface
|
||||
arduinoIdeX11 # Arduino IDE with X11 support
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [ pkgs.arduino-cli ];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
arduinoIdeX11 = pkgs.arduino-ide.overrideAttrs (old: {
|
||||
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
|
||||
|
||||
postFixup = (old.postFixup or "") + ''
|
||||
wrapProgram $out/bin/arduino-ide \
|
||||
--add-flags "--ozone-platform=x11"
|
||||
'';
|
||||
});
|
||||
in
|
||||
{
|
||||
environment.systemPackages = [ arduinoIdeX11 ];
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.btop;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.btop = {
|
||||
enable = lib.mkEnableOption "btop system monitor";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.btop.system.enable = lib.mkDefault true;
|
||||
my.applications.btop.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#Bashtop theme with nord palette (https://www.nordtheme.com)
|
||||
#by Justin Zobel <[email protected]>
|
||||
# Bashtop theme with Nord palette (https://www.nordtheme.com)
|
||||
# by Justin Zobel <[email protected]>
|
||||
|
||||
# Colors should be in 6 or 2 character hexadecimal or single spaced rgb decimal: "#RRGGBB", "#BW" or "0-255 0-255 0-255"
|
||||
# example for white: "#ffffff", "#ff" or "255 255 255".
|
||||
@@ -18,7 +18,7 @@ theme[main_fg]="#BD93F9"
|
||||
# Title color for boxes
|
||||
theme[title]="#f8f8f2"
|
||||
|
||||
# Higlight color for keyboard shortcuts
|
||||
# Highlight color for keyboard shortcuts
|
||||
theme[hi_fg]="#ff79c6"
|
||||
|
||||
# Background color of selected item in processes box
|
||||
|
||||
@@ -1,25 +1,8 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.btop.homeManager;
|
||||
in
|
||||
{
|
||||
options.my.applications.btop.homeManager = {
|
||||
enable = lib.mkEnableOption "btop home-manager configuration";
|
||||
};
|
||||
programs.btop = {
|
||||
enable = true;
|
||||
|
||||
config.home-manager.sharedModules = [
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.btop = {
|
||||
enable = true;
|
||||
settings.color_theme = "dracula";
|
||||
themes.dracula = builtins.readFile ./dracula.theme;
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
settings.color_theme = "dracula";
|
||||
themes.dracula = builtins.readFile ./dracula.theme;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.btop.system;
|
||||
in
|
||||
{
|
||||
options.my.applications.btop.system = {
|
||||
enable = lib.mkEnableOption "btop system configuration";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
btop # Resource monitor that shows usage and stats
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.chrome;
|
||||
in
|
||||
{
|
||||
options.my.applications.chrome = {
|
||||
enable = lib.mkEnableOption "Google Chrome browser";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home-manager.sharedModules = [
|
||||
{
|
||||
home.packages = with pkgs; [
|
||||
google-chrome # Popular web browser from Google
|
||||
];
|
||||
|
||||
xdg.desktopEntries."google-chrome" = {
|
||||
name = "Google Chrome";
|
||||
genericName = "Web Browser";
|
||||
exec = "${pkgs.google-chrome}/bin/google-chrome-stable --enable-features=TouchpadOverscrollHistoryNavigation %U";
|
||||
terminal = false;
|
||||
icon = "google-chrome";
|
||||
categories = [
|
||||
"Network"
|
||||
"WebBrowser"
|
||||
];
|
||||
startupNotify = true;
|
||||
type = "Application";
|
||||
};
|
||||
|
||||
xdg.mimeApps.defaultApplications = {
|
||||
"text/html" = "google-chrome.desktop";
|
||||
"x-scheme-handler/http" = "google-chrome.desktop";
|
||||
"x-scheme-handler/https" = "google-chrome.desktop";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
homebrew = {
|
||||
enable = true;
|
||||
casks = [ "google-chrome" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{ lib, pkgs, ... }:
|
||||
lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
home.packages = [ pkgs.google-chrome ];
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
chromeLauncher = pkgs.makeDesktopItem {
|
||||
name = "google-chrome";
|
||||
desktopName = "Google Chrome";
|
||||
genericName = "Web Browser";
|
||||
exec = "${pkgs.google-chrome}/bin/google-chrome-stable --enable-features=TouchpadOverscrollHistoryNavigation %U";
|
||||
icon = "google-chrome";
|
||||
terminal = false;
|
||||
categories = [
|
||||
"Network"
|
||||
"WebBrowser"
|
||||
];
|
||||
startupNotify = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
environment.systemPackages = [ chromeLauncher ];
|
||||
|
||||
xdg.mime.defaultApplications = {
|
||||
"text/html" = "google-chrome.desktop";
|
||||
"x-scheme-handler/http" = "google-chrome.desktop";
|
||||
"x-scheme-handler/https" = "google-chrome.desktop";
|
||||
};
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.claude;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.claude = {
|
||||
enable = lib.mkEnableOption "Claude Code AI assistant";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.claude.system.enable = lib.mkDefault true;
|
||||
my.applications.claude.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -1,27 +1,18 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.claude.homeManager;
|
||||
in
|
||||
{
|
||||
options.my.applications.claude.homeManager = {
|
||||
enable = lib.mkEnableOption "Claude Code home-manager configuration";
|
||||
};
|
||||
|
||||
config.home-manager.sharedModules = [
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.file.".claude/settings.json".text = builtins.toJSON {
|
||||
statusLine = {
|
||||
type = "command";
|
||||
command = "bun x ccusage statusline --no-offline";
|
||||
padding = 0;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
home.packages = [
|
||||
inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.claude-code
|
||||
];
|
||||
|
||||
home.file.".claude/settings.json".text = builtins.toJSON {
|
||||
statusLine = {
|
||||
type = "command";
|
||||
command = "bun x ccusage statusline --no-offline";
|
||||
padding = 0;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.claude.system;
|
||||
in
|
||||
{
|
||||
options.my.applications.claude.system = {
|
||||
enable = lib.mkEnableOption "Claude Code system configuration";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [
|
||||
pkgs.llm-agents.claude-code # AI coding assistant
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
{
|
||||
inputs,
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.codexDesktop;
|
||||
codexCliPackage = pkgs.llm-agents.codex;
|
||||
codexDesktopPackage =
|
||||
inputs.codex-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.codex-desktop-computer-use-ui;
|
||||
codexDesktopLauncher = pkgs.makeDesktopItem {
|
||||
name = "codex";
|
||||
desktopName = "Codex";
|
||||
genericName = "ChatGPT Desktop";
|
||||
comment = "Run Codex Desktop on Linux";
|
||||
exec = "env CODEX_CLI_PATH=${lib.getExe' codexCliPackage "codex"} BAMF_DESKTOP_FILE_HINT=codex.desktop CHROME_DESKTOP=codex.desktop ${lib.getExe' codexDesktopPackage "codex-desktop"} %u";
|
||||
icon = "codex-desktop";
|
||||
terminal = false;
|
||||
categories = [ "Development" ];
|
||||
keywords = [
|
||||
"codex"
|
||||
"chatgpt"
|
||||
"openai"
|
||||
"ai"
|
||||
"assistant"
|
||||
];
|
||||
startupNotify = true;
|
||||
startupWMClass = "codex-desktop";
|
||||
actions = {
|
||||
new-window = {
|
||||
name = "New Window";
|
||||
exec = "env CODEX_CLI_PATH=${lib.getExe' codexCliPackage "codex"} BAMF_DESKTOP_FILE_HINT=codex.desktop CHROME_DESKTOP=codex.desktop CODEX_MULTI_LAUNCH=1 ${lib.getExe' codexDesktopPackage "codex-desktop"} --new-instance";
|
||||
};
|
||||
};
|
||||
extraConfig = {
|
||||
X-GNOME-WMClass = "codex-desktop";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
inputs.codex-desktop-linux.nixosModules.default
|
||||
];
|
||||
|
||||
options.my.applications.codexDesktop = {
|
||||
enable = lib.mkEnableOption "ChatGPT Desktop for Linux";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.codex.enable = true;
|
||||
|
||||
programs.codexDesktopLinux = {
|
||||
enable = true;
|
||||
package = codexDesktopPackage;
|
||||
cliPackage = codexCliPackage;
|
||||
computerUseUi.enable = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = [
|
||||
codexDesktopLauncher # Vicinae-searchable Codex Desktop launcher alias
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
# The former Codex app cask is deprecated in favor of ChatGPT, whose desktop
|
||||
# application includes the current Codex experience on macOS.
|
||||
homebrew = {
|
||||
enable = true;
|
||||
casks = [ "chatgpt" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
description = "Codex Desktop for Linux";
|
||||
|
||||
includes = [ "applications.codex" ];
|
||||
|
||||
imports.nixos = [
|
||||
inputs.codex-desktop-linux.nixosModules.default
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
inputs,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
codexCliPackage = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.codex;
|
||||
codexDesktopPackage =
|
||||
inputs.codex-desktop-linux.packages.${pkgs.stdenv.hostPlatform.system}.codex-desktop-computer-use-ui;
|
||||
launcher = pkgs.makeDesktopItem {
|
||||
name = "codex";
|
||||
desktopName = "Codex";
|
||||
genericName = "ChatGPT Desktop";
|
||||
comment = "Run Codex Desktop";
|
||||
exec = "env CODEX_CLI_PATH=${lib.getExe' codexCliPackage "codex"} BAMF_DESKTOP_FILE_HINT=codex.desktop CHROME_DESKTOP=codex.desktop ${lib.getExe' codexDesktopPackage "codex-desktop"} %u";
|
||||
icon = "codex-desktop";
|
||||
terminal = false;
|
||||
categories = [ "Development" ];
|
||||
startupNotify = true;
|
||||
startupWMClass = "codex-desktop";
|
||||
actions.new-window = {
|
||||
name = "New Window";
|
||||
exec = "env CODEX_CLI_PATH=${lib.getExe' codexCliPackage "codex"} BAMF_DESKTOP_FILE_HINT=codex.desktop CHROME_DESKTOP=codex.desktop CODEX_MULTI_LAUNCH=1 ${lib.getExe' codexDesktopPackage "codex-desktop"} --new-instance";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
programs.codexDesktopLinux = {
|
||||
enable = true;
|
||||
package = codexDesktopPackage;
|
||||
cliPackage = codexCliPackage;
|
||||
computerUseUi.enable = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = [ launcher ];
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.codex;
|
||||
in
|
||||
{
|
||||
options.my.applications.codex = {
|
||||
enable = lib.mkEnableOption "Codex AI coding assistant";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [
|
||||
pkgs.llm-agents.codex # OpenAI Codex CLI
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{ inputs, pkgs, ... }:
|
||||
{
|
||||
home.packages = [
|
||||
inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.codex
|
||||
];
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
{
|
||||
imports = [
|
||||
./1password.nix
|
||||
./arduino.nix
|
||||
./btop
|
||||
./chrome.nix
|
||||
./claude
|
||||
./codex-desktop.nix
|
||||
./codex.nix
|
||||
./direnv.nix
|
||||
./discord.nix
|
||||
./docker.nix
|
||||
./fcitx5
|
||||
./ghostty
|
||||
./git
|
||||
./gnupg
|
||||
./grok.nix
|
||||
./gnome.nix
|
||||
./greetd.nix
|
||||
./ly
|
||||
./gtk
|
||||
./java
|
||||
./kde.nix
|
||||
./nautilus.nix
|
||||
./nh.nix
|
||||
./niri
|
||||
./nix-index
|
||||
./noctalia
|
||||
./opencode.nix
|
||||
./openssh.nix
|
||||
./slack.nix
|
||||
./ssh
|
||||
./swayidle.nix
|
||||
./swaylock
|
||||
./tailscale.nix
|
||||
./vicinae.nix
|
||||
./vim
|
||||
./vscode
|
||||
./wayland.nix
|
||||
./yazi.nix
|
||||
./zed
|
||||
./zellij
|
||||
./zoom.nix
|
||||
./zoxide.nix
|
||||
./zsh
|
||||
];
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
cfg = config.my.applications.direnv;
|
||||
in
|
||||
{
|
||||
options.my.applications.direnv = {
|
||||
enable = lib.mkEnableOption "direnv environment variable manager";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
nix-direnv.enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
programs.direnv = {
|
||||
enable = true;
|
||||
nix-direnv.enable = true;
|
||||
};
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.discord;
|
||||
in
|
||||
{
|
||||
options.my.applications.discord = {
|
||||
enable = lib.mkEnableOption "Discord (Vesktop)";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home-manager.sharedModules = [
|
||||
{
|
||||
programs.vesktop = {
|
||||
enable = true;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
homebrew = {
|
||||
enable = true;
|
||||
casks = [ "vesktop" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{ lib, pkgs, ... }:
|
||||
lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
programs.vesktop.enable = true;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.docker;
|
||||
in
|
||||
{
|
||||
options.my.applications.docker = {
|
||||
enable = lib.mkEnableOption "Docker container runtime";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
virtualisation.docker = {
|
||||
enable = true;
|
||||
autoPrune = {
|
||||
enable = true;
|
||||
dates = "weekly";
|
||||
};
|
||||
daemon.settings = {
|
||||
ipv6 = true;
|
||||
"fixed-cidr-v6" = "fd00:30::/64";
|
||||
ip6tables = true;
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
docker # Container runtime
|
||||
oxker # Docker TUI Tool
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
homebrew = {
|
||||
enable = true;
|
||||
casks = [ "orbstack" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
home.packages = [
|
||||
pkgs.docker-client
|
||||
pkgs.oxker
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
description = "Docker command-line client and NixOS daemon";
|
||||
|
||||
includes = [ "services.docker" ];
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
homebrew = {
|
||||
enable = true;
|
||||
casks = [ "drawio" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{ lib, pkgs, ... }:
|
||||
lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
home.packages = [ pkgs.drawio ];
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.fcitx5;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.fcitx5 = {
|
||||
enable = lib.mkEnableOption "fcitx5 input method";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.fcitx5.system.enable = lib.mkDefault true;
|
||||
my.applications.fcitx5.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -1,24 +1,6 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.fcitx5.homeManager;
|
||||
in
|
||||
{
|
||||
options.my.applications.fcitx5.homeManager = {
|
||||
enable = lib.mkEnableOption "fcitx5 home-manager configuration";
|
||||
home.file.".config/fcitx5/config" = {
|
||||
recursive = true;
|
||||
source = ./config;
|
||||
};
|
||||
|
||||
config.home-manager.sharedModules = [
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.file.".config/fcitx5/config" = {
|
||||
recursive = true;
|
||||
source = ./config;
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
i18n.inputMethod = {
|
||||
enable = true;
|
||||
type = "fcitx5";
|
||||
|
||||
fcitx5 = {
|
||||
waylandFrontend = true;
|
||||
addons = with pkgs; [
|
||||
fcitx5-mozc-ut
|
||||
fcitx5-gtk
|
||||
kdePackages.fcitx5-qt
|
||||
qt6Packages.fcitx5-configtool
|
||||
];
|
||||
|
||||
settings.inputMethod = {
|
||||
GroupOrder."0" = "Default";
|
||||
"Groups/0" = {
|
||||
Name = "Default";
|
||||
"Default Layout" = "jp";
|
||||
DefaultIM = "mozc";
|
||||
};
|
||||
"Groups/0/Items/0" = {
|
||||
Name = "keyboard-jp";
|
||||
Layout = "";
|
||||
};
|
||||
"Groups/0/Items/1" = {
|
||||
Name = "mozc";
|
||||
Layout = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
system = pkgs.stdenv.hostPlatform.system;
|
||||
|
||||
cfg = config.my.applications.fcitx5.system;
|
||||
in
|
||||
{
|
||||
options.my.applications.fcitx5.system = {
|
||||
enable = lib.mkEnableOption "fcitx5 system configuration";
|
||||
};
|
||||
|
||||
imports = [
|
||||
inputs.nix-hazkey.nixosModules.hazkey
|
||||
];
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
||||
services.hazkey = {
|
||||
enable = true;
|
||||
server.package = inputs.nix-hazkey.packages.${system}.hazkey-server.override {
|
||||
enableVulkan = true;
|
||||
};
|
||||
installHazkeySettings = false;
|
||||
installFcitx5Addon = false;
|
||||
};
|
||||
|
||||
environment.systemPackages = [ inputs.nix-hazkey.packages.${system}.hazkey-settings ];
|
||||
|
||||
i18n.inputMethod = {
|
||||
enable = true;
|
||||
type = "fcitx5";
|
||||
fcitx5 = {
|
||||
waylandFrontend = true;
|
||||
addons = with pkgs; [
|
||||
inputs.nix-hazkey.packages.${system}.fcitx5-hazkey
|
||||
fcitx5-mozc-ut
|
||||
fcitx5-gtk
|
||||
kdePackages.fcitx5-qt
|
||||
qt6Packages.fcitx5-configtool
|
||||
];
|
||||
settings.inputMethod = {
|
||||
GroupOrder = {
|
||||
"0" = "Default";
|
||||
};
|
||||
"Groups/0" = {
|
||||
Name = "Default";
|
||||
"Default Layout" = "jp";
|
||||
DefaultIM = "mozc";
|
||||
};
|
||||
"Groups/0/Items/0" = {
|
||||
Name = "keyboard-jp";
|
||||
Layout = "";
|
||||
};
|
||||
"Groups/0/Items/1" = {
|
||||
Name = "mozc";
|
||||
Layout = "";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
theme = dracula
|
||||
background-blur-radius = 20
|
||||
background-opacity = 0.9
|
||||
font-family = BlexMono Nerd Font Mono
|
||||
mouse-hide-while-typing = true
|
||||
window-decoration = true
|
||||
|
||||
|
||||
# keybind
|
||||
|
||||
# Copy/Paste
|
||||
keybind = performable:ctrl+shift+c=copy_to_clipboard
|
||||
keybind = ctrl+shift+v=paste_from_clipboard
|
||||
|
||||
# create new tab
|
||||
keybind = ctrl+shift+t=new_tab
|
||||
|
||||
# move tabs
|
||||
keybind = ctrl+alt+left_bracket=previous_tab
|
||||
keybind = ctrl+alt+right_bracket=next_tab
|
||||
|
||||
# close tab
|
||||
keybind = ctrl+alt+q=close_window
|
||||
|
||||
# font size
|
||||
keybind = ctrl+shift+semicolon=increase_font_size:1
|
||||
keybind = ctrl+shift+minus=increase_font_size:1
|
||||
|
||||
|
||||
# quick terminal
|
||||
keybind = global:super+space=toggle_quick_terminal
|
||||
quick-terminal-position = top
|
||||
quick-terminal-size = 100%
|
||||
gtk-quick-terminal-layer = overlay
|
||||
quick-terminal-keyboard-interactivity = exclusive
|
||||
quick-terminal-autohide = false
|
||||
quit-after-last-window-closed = false
|
||||
|
||||
shell-integration-features = ssh-terminfo,ssh-env
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
homebrew = {
|
||||
enable = true;
|
||||
casks = [ "ghostty" ];
|
||||
};
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.ghostty;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.ghostty = {
|
||||
enable = lib.mkEnableOption "ghostty terminal emulator";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.ghostty.system.enable = lib.mkDefault true;
|
||||
my.applications.ghostty.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
# MIT License
|
||||
#
|
||||
#
|
||||
# Copyright (c) 2023 Dracula Theme
|
||||
#
|
||||
#
|
||||
# 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
|
||||
@@ -42,4 +42,3 @@ cursor-color = #f8f8f2
|
||||
cursor-text = #282a36
|
||||
selection-foreground = #f8f8f2
|
||||
selection-background = #44475a
|
||||
|
||||
|
||||
@@ -1,83 +1,49 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
inputs,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.ghostty.homeManager;
|
||||
|
||||
system = pkgs.stdenv.hostPlatform.system;
|
||||
|
||||
ghosttyPkg = inputs.ghostty.packages.${system}.ghostty-releasefast;
|
||||
package =
|
||||
if pkgs.stdenv.hostPlatform.isLinux then
|
||||
inputs.ghostty.packages.${pkgs.stdenv.hostPlatform.system}.ghostty-releasefast
|
||||
else
|
||||
null;
|
||||
in
|
||||
{
|
||||
options.my.applications.ghostty.homeManager = {
|
||||
enable = lib.mkEnableOption "ghostty home-manager configuration";
|
||||
programs.ghostty = {
|
||||
enable = true;
|
||||
inherit package;
|
||||
systemd.enable = pkgs.stdenv.hostPlatform.isLinux;
|
||||
|
||||
settings = {
|
||||
theme = "dracula";
|
||||
background-blur-radius = 20;
|
||||
background-opacity = 0.9;
|
||||
font-family = "BlexMono Nerd Font Mono";
|
||||
mouse-hide-while-typing = true;
|
||||
window-decoration = "auto";
|
||||
|
||||
keybind = [
|
||||
"performable:ctrl+shift+c=copy_to_clipboard"
|
||||
"ctrl+shift+v=paste_from_clipboard"
|
||||
"ctrl+shift+t=new_tab"
|
||||
"ctrl+alt+left_bracket=previous_tab"
|
||||
"ctrl+alt+right_bracket=next_tab"
|
||||
"ctrl+alt+q=close_window"
|
||||
"ctrl+shift+semicolon=increase_font_size:1"
|
||||
"ctrl+shift+minus=decrease_font_size:1"
|
||||
];
|
||||
|
||||
quick-terminal-position = "top";
|
||||
quick-terminal-size = "98%,100%";
|
||||
quick-terminal-autohide = false;
|
||||
quick-terminal-keyboard-interactivity = "on-demand";
|
||||
gtk-quick-terminal-layer = "top";
|
||||
quit-after-last-window-closed = false;
|
||||
shell-integration-features = "no-ssh-env,no-ssh-terminfo";
|
||||
};
|
||||
};
|
||||
|
||||
config.home-manager.sharedModules = [
|
||||
(
|
||||
{ lib, ... }:
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.ghostty = {
|
||||
enable = true;
|
||||
|
||||
package = ghosttyPkg;
|
||||
|
||||
systemd.enable = true;
|
||||
|
||||
settings = {
|
||||
theme = "dracula";
|
||||
|
||||
background-blur-radius = 20;
|
||||
background-opacity = 0.9;
|
||||
|
||||
font-family = "BlexMono Nerd Font Mono";
|
||||
|
||||
mouse-hide-while-typing = true;
|
||||
|
||||
window-decoration = "auto";
|
||||
|
||||
keybind = [
|
||||
# Copy/Paste
|
||||
"performable:ctrl+shift+c=copy_to_clipboard"
|
||||
"ctrl+shift+v=paste_from_clipboard"
|
||||
|
||||
# Create new tab
|
||||
"ctrl+shift+t=new_tab"
|
||||
|
||||
# Move tabs
|
||||
"ctrl+alt+left_bracket=previous_tab"
|
||||
"ctrl+alt+right_bracket=next_tab"
|
||||
|
||||
# Close window
|
||||
"ctrl+alt+q=close_window"
|
||||
|
||||
# Font size
|
||||
"ctrl+shift+semicolon=increase_font_size:1"
|
||||
"ctrl+shift+minus=decrease_font_size:1"
|
||||
];
|
||||
|
||||
# Quick terminal
|
||||
quick-terminal-position = "top";
|
||||
quick-terminal-size = "98%,100%";
|
||||
|
||||
quick-terminal-autohide = false;
|
||||
quick-terminal-keyboard-interactivity = "on-demand";
|
||||
gtk-quick-terminal-layer = "top";
|
||||
|
||||
quit-after-last-window-closed = false;
|
||||
|
||||
shell-integration-features = "no-ssh-env,no-ssh-terminfo";
|
||||
};
|
||||
};
|
||||
|
||||
xdg.configFile."ghostty/themes/dracula".source = ./dracula.theme;
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
xdg.configFile."ghostty/themes/dracula".source = ./dracula.theme;
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.ghostty.system;
|
||||
|
||||
system = pkgs.stdenv.hostPlatform.system;
|
||||
|
||||
ghosttyPkg = inputs.ghostty.packages.${system}.ghostty-releasefast;
|
||||
in
|
||||
{
|
||||
options.my.applications.ghostty.system = {
|
||||
enable = lib.mkEnableOption "ghostty system configuration";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [
|
||||
ghosttyPkg # A fast and minimal terminal emulator for Wayland
|
||||
ghosttyPkg.terminfo # Terminfo database for ghostty
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.git;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.git = {
|
||||
enable = lib.mkEnableOption "git version control";
|
||||
|
||||
userName = lib.mkOption {
|
||||
type = lib.types.singleLineStr;
|
||||
default = "moons";
|
||||
description = "Default Git user.name.";
|
||||
};
|
||||
|
||||
userEmail = lib.mkOption {
|
||||
type = lib.types.singleLineStr;
|
||||
default = "moons@moons14.com";
|
||||
description = "Default Git user.email.";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.git.system.enable = lib.mkDefault true;
|
||||
my.applications.git.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -1,13 +1,5 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
cfg = config.my.applications.git;
|
||||
hmCfg = config.my.applications.git.homeManager;
|
||||
|
||||
signingKeyPath = ".ssh/1password-git-signing.pub";
|
||||
signingKeyFile = "~/${signingKeyPath}";
|
||||
|
||||
@@ -35,77 +27,52 @@ let
|
||||
'';
|
||||
in
|
||||
{
|
||||
options.my.applications.git.homeManager = {
|
||||
enable = lib.mkEnableOption "git home-manager configuration";
|
||||
home.packages = [ pkgs.gh ];
|
||||
|
||||
signingPublicKey = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.singleLineStr;
|
||||
default = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLwReAiwhXoO34S2+MrvqUhi8IWp4IzUq4OSp3niJdq 1password-git-signing";
|
||||
example = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLwReAiwhXoO34S2+MrvqUhi8IWp4IzUq4OSp3niJdq 1password-git-signing";
|
||||
description = "SSH public key copied from the 1Password SSH key item used for Git signing.";
|
||||
};
|
||||
home.file.${signingKeyPath}.text = ''
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPLwReAiwhXoO34S2+MrvqUhi8IWp4IzUq4OSp3niJdq 1password-git-signing
|
||||
'';
|
||||
|
||||
signingKey = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = signingKeyFile;
|
||||
readOnly = true;
|
||||
description = "SSH public key path used for Git commit and tag signing.";
|
||||
};
|
||||
};
|
||||
programs.git = {
|
||||
enable = true;
|
||||
|
||||
config = lib.mkIf hmCfg.enable {
|
||||
assertions = [
|
||||
{
|
||||
assertion = hmCfg.signingPublicKey != null && hmCfg.signingPublicKey != "";
|
||||
message = "my.applications.git.homeManager.signingPublicKey must be set to the public key copied from 1Password.";
|
||||
}
|
||||
ignores = [
|
||||
".direnv/"
|
||||
".envrc"
|
||||
"!.envrc.example"
|
||||
];
|
||||
|
||||
home-manager.sharedModules = [
|
||||
{
|
||||
home.file.${signingKeyPath}.text = hmCfg.signingPublicKey + "\n";
|
||||
signing = {
|
||||
key = signingKeyFile;
|
||||
format = "ssh";
|
||||
signByDefault = true;
|
||||
};
|
||||
|
||||
programs.git = {
|
||||
enable = true;
|
||||
settings = {
|
||||
user = {
|
||||
name = "moons";
|
||||
email = "moons@moons14.com";
|
||||
};
|
||||
|
||||
ignores = [
|
||||
".direnv/"
|
||||
".envrc"
|
||||
"!.envrc.example"
|
||||
];
|
||||
push.default = "simple";
|
||||
credential.helper = "cache --timeout=7200";
|
||||
init.defaultBranch = "main";
|
||||
log.decorate = "full";
|
||||
log.date = "iso";
|
||||
merge.conflictStyle = "diff3";
|
||||
|
||||
signing = {
|
||||
key = hmCfg.signingKey;
|
||||
format = "ssh";
|
||||
signByDefault = true;
|
||||
};
|
||||
gpg.ssh.program = "${gitSshSign}";
|
||||
|
||||
settings = {
|
||||
user.name = cfg.userName;
|
||||
user.email = cfg.userEmail;
|
||||
|
||||
push.default = "simple";
|
||||
credential.helper = "cache --timeout=7200";
|
||||
init.defaultBranch = "main";
|
||||
log.decorate = "full";
|
||||
log.date = "iso";
|
||||
merge.conflictStyle = "diff3";
|
||||
|
||||
gpg.ssh.program = "${gitSshSign}";
|
||||
|
||||
alias = {
|
||||
br = "branch --sort=-committerdate";
|
||||
co = "checkout";
|
||||
df = "diff";
|
||||
com = "commit -a";
|
||||
gs = "stash";
|
||||
gp = "pull";
|
||||
lg = "log --graph --pretty=format:'%Cred%h%Creset - %C(yellow)%d%Creset %s %C(green)(%cr)%C(bold blue) <%an>%Creset' --abbrev-commit";
|
||||
st = "status";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
alias = {
|
||||
br = "branch --sort=-committerdate";
|
||||
co = "checkout";
|
||||
df = "diff";
|
||||
com = "commit -a";
|
||||
gs = "stash";
|
||||
gp = "pull";
|
||||
lg = "log --graph --pretty=format:'%Cred%h%Creset - %C(yellow)%d%Creset %s %C(green)(%cr)%C(bold blue) <%an>%Creset' --abbrev-commit";
|
||||
st = "status";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.git.system;
|
||||
in
|
||||
{
|
||||
options.my.applications.git.system = {
|
||||
enable = lib.mkEnableOption "git system configuration";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
git # Distributed version control system
|
||||
gh # GitHub CLI
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.gnome;
|
||||
in
|
||||
{
|
||||
options.my.applications.gnome = {
|
||||
enable = lib.mkEnableOption "GNOME desktop environment";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.desktopManager.gnome.enable = true;
|
||||
|
||||
# ly is the display manager for switching between installed sessions.
|
||||
services.displayManager.gdm.enable = lib.mkForce false;
|
||||
|
||||
home-manager.sharedModules = [
|
||||
{
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/sound" = {
|
||||
event-sounds = false;
|
||||
input-feedback-sounds = false;
|
||||
};
|
||||
|
||||
"org/gnome/desktop/wm/keybindings" = {
|
||||
close = [ "<Super>q" ];
|
||||
show-desktop = [ ];
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys" = {
|
||||
home = [ ];
|
||||
screensaver = [ "<Super>l" ];
|
||||
custom-keybindings = [
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom3/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom4/"
|
||||
];
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
|
||||
name = "Open Terminal";
|
||||
command = "ghostty";
|
||||
binding = "<Super>t";
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1" = {
|
||||
name = "Run Application";
|
||||
command = "vicinae toggle";
|
||||
binding = "<Super>d";
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2" = {
|
||||
name = "Open File Manager";
|
||||
command = "nautilus --new-window";
|
||||
binding = "<Super>e";
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom3" = {
|
||||
name = "Clipboard History";
|
||||
command = "vicinae vicinae://extensions/vicinae/clipboard/history";
|
||||
binding = "<Super>v";
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom4" = {
|
||||
name = "Log Out";
|
||||
command = "gnome-session-quit --logout --no-prompt";
|
||||
binding = "<Super><Shift>e";
|
||||
};
|
||||
|
||||
"org/gnome/shell" = {
|
||||
favorite-apps = [
|
||||
"google-chrome.desktop"
|
||||
"code.desktop"
|
||||
"com.mitchellh.ghostty.desktop"
|
||||
"slack.desktop"
|
||||
"vesktop.desktop"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
gnome-tweaks # GNOME desktop customization tool
|
||||
gnome-extension-manager # GNOME Shell extension manager
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
{ pkgs, lib, ... }:
|
||||
lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/sound" = {
|
||||
event-sounds = false;
|
||||
input-feedback-sounds = false;
|
||||
};
|
||||
"org/gnome/desktop/wm/keybindings" = {
|
||||
close = [ "<Super>q" ];
|
||||
show-desktop = [ ];
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys" = {
|
||||
home = [ ];
|
||||
screensaver = [ "<Super>l" ];
|
||||
custom-keybindings = [
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom3/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom4/"
|
||||
];
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0" = {
|
||||
name = "Open Terminal";
|
||||
command = "ghostty";
|
||||
binding = "<Super>t";
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1" = {
|
||||
name = "Run Application";
|
||||
command = "vicinae toggle";
|
||||
binding = "<Super>d";
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2" = {
|
||||
name = "Open File Manager";
|
||||
command = "nautilus --new-window";
|
||||
binding = "<Super>e";
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom3" = {
|
||||
name = "Clipboard History";
|
||||
command = "vicinae vicinae://extensions/vicinae/clipboard/history";
|
||||
binding = "<Super>v";
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom4" = {
|
||||
name = "Log Out";
|
||||
command = "gnome-session-quit --logout --no-prompt";
|
||||
binding = "<Super><Shift>e";
|
||||
};
|
||||
"org/gnome/shell".favorite-apps = [
|
||||
"google-chrome.desktop"
|
||||
"code.desktop"
|
||||
"com.mitchellh.ghostty.desktop"
|
||||
"slack.desktop"
|
||||
"vesktop.desktop"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{ pkgs, lib, ... }:
|
||||
{
|
||||
services.desktopManager.gnome.enable = true;
|
||||
services.displayManager.gdm.enable = lib.mkForce false;
|
||||
|
||||
environment.systemPackages = [
|
||||
pkgs.gnome-tweaks
|
||||
pkgs.gnome-extension-manager
|
||||
];
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.gnupg;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.gnupg = {
|
||||
enable = lib.mkEnableOption "GnuPG agent";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.gnupg.system.enable = lib.mkDefault true;
|
||||
my.applications.gnupg.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -1,22 +1,9 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
hmCfg = config.my.applications.gnupg.homeManager;
|
||||
in
|
||||
{
|
||||
options.my.applications.gnupg.homeManager = {
|
||||
enable = lib.mkEnableOption "GnuPG home-manager configuration";
|
||||
};
|
||||
home.packages = [ pkgs.gnupg ];
|
||||
|
||||
config.home-manager.sharedModules = [
|
||||
{
|
||||
config = lib.mkIf hmCfg.enable {
|
||||
services.gpg-agent.enable = false;
|
||||
services.gpg-agent.enableSshSupport = false;
|
||||
};
|
||||
}
|
||||
];
|
||||
services.gpg-agent = {
|
||||
enable = false;
|
||||
enableSshSupport = false;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
programs.gnupg.agent = {
|
||||
enable = true;
|
||||
enableSSHSupport = false;
|
||||
};
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.gnupg.system;
|
||||
in
|
||||
{
|
||||
options.my.applications.gnupg.system = {
|
||||
enable = lib.mkEnableOption "GnuPG system configuration";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.gnupg.agent = {
|
||||
enable = true;
|
||||
enableSSHSupport = false;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.greetd;
|
||||
in
|
||||
{
|
||||
options.my.applications.greetd = {
|
||||
enable = lib.mkEnableOption "greetd login manager";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
settings = {
|
||||
default_session = {
|
||||
user = "greeter";
|
||||
command = "${pkgs.tuigreet}/bin/tuigreet --time --remember --cmd niri-session";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.grok;
|
||||
|
||||
grok = pkgs.llm-agents.grok.overrideAttrs (_old: {
|
||||
versionCheckProgram = "${placeholder "out"}/libexec/grok/grok-launcher";
|
||||
});
|
||||
in
|
||||
{
|
||||
options.my.applications.grok = {
|
||||
enable = lib.mkEnableOption "Grok AI assistant";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = [
|
||||
grok
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{ inputs, pkgs, ... }:
|
||||
let
|
||||
grok = inputs.llm-agents.packages.${pkgs.stdenv.hostPlatform.system}.grok.overrideAttrs (_: {
|
||||
versionCheckProgram = "${placeholder "out"}/libexec/grok/grok-launcher";
|
||||
});
|
||||
in
|
||||
{
|
||||
home.packages = [ grok ];
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.gtk;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.gtk = {
|
||||
enable = lib.mkEnableOption "GTK theme configuration";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.gtk.system.enable = lib.mkDefault true;
|
||||
my.applications.gtk.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -1,36 +1,18 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.gtk.homeManager;
|
||||
in
|
||||
{
|
||||
options.my.applications.gtk.homeManager = {
|
||||
enable = lib.mkEnableOption "GTK home-manager configuration";
|
||||
gtk = {
|
||||
enable = true;
|
||||
theme = {
|
||||
name = "Dracula";
|
||||
package = pkgs.dracula-theme;
|
||||
};
|
||||
cursorTheme = {
|
||||
package = pkgs.adwaita-icon-theme;
|
||||
name = "Adwaita";
|
||||
};
|
||||
iconTheme = {
|
||||
package = pkgs.papirus-icon-theme;
|
||||
name = "Papirus-Dark";
|
||||
};
|
||||
};
|
||||
|
||||
config.home-manager.sharedModules = [
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
gtk = {
|
||||
enable = true;
|
||||
theme = {
|
||||
name = "Dracula";
|
||||
package = pkgs.dracula-theme;
|
||||
};
|
||||
cursorTheme = {
|
||||
package = pkgs.adwaita-icon-theme;
|
||||
name = "Adwaita";
|
||||
};
|
||||
iconTheme = {
|
||||
package = pkgs.papirus-icon-theme;
|
||||
name = "Papirus-Dark";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
programs.dconf.enable = true;
|
||||
programs.seahorse.enable = true;
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.gtk.system;
|
||||
in
|
||||
{
|
||||
options.my.applications.gtk.system = {
|
||||
enable = lib.mkEnableOption "GTK system configuration";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.dconf.enable = true;
|
||||
programs.seahorse.enable = true;
|
||||
|
||||
services.gnome.gnome-keyring.enable = true;
|
||||
};
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.java;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./home.nix
|
||||
./system.nix
|
||||
];
|
||||
|
||||
options.my.applications.java = {
|
||||
enable = lib.mkEnableOption "Java runtime";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
my.applications.java.system.enable = lib.mkDefault true;
|
||||
my.applications.java.homeManager.enable = lib.mkDefault true;
|
||||
};
|
||||
}
|
||||
@@ -1,23 +1,12 @@
|
||||
{ pkgs, ... }:
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.java.homeManager;
|
||||
in
|
||||
{
|
||||
options.my.applications.java.homeManager = {
|
||||
enable = lib.mkEnableOption "Java home-manager configuration";
|
||||
programs.java = {
|
||||
enable = true;
|
||||
package = pkgs.jdk25;
|
||||
};
|
||||
|
||||
config.home-manager.sharedModules = [
|
||||
{
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.java = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
home.packages = with pkgs; [
|
||||
maven
|
||||
gradle
|
||||
];
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.java.system;
|
||||
in
|
||||
{
|
||||
options.my.applications.java.system = {
|
||||
enable = lib.mkEnableOption "Java system configuration";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.java = {
|
||||
enable = true;
|
||||
package = pkgs.jdk25;
|
||||
};
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
jdk25 # Java Development Kit 25
|
||||
maven # Java Build Tool
|
||||
gradle # Java Build Tool
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.kde;
|
||||
in
|
||||
{
|
||||
options.my.applications.kde = {
|
||||
enable = lib.mkEnableOption "KDE Connect";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.kdeconnect = {
|
||||
enable = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
homebrew = {
|
||||
enable = true;
|
||||
casks = [ "kde-connect" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
programs.kdeconnect.enable = true;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.ly;
|
||||
indyzLinuxfire = pkgs.fetchurl {
|
||||
url = "https://codeberg.org/attachments/f336d6ac-8331-4323-91fc-0e4619803401";
|
||||
hash = "sha256-fRm0wlkq9/GdLrVBOzMEnQG/i2ng+uGIzq0u9hu3m9g=";
|
||||
};
|
||||
in
|
||||
{
|
||||
options.my.applications.ly = {
|
||||
enable = lib.mkEnableOption "ly TUI display manager";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
services.displayManager.defaultSession = lib.mkDefault "niri";
|
||||
|
||||
services.displayManager.ly = {
|
||||
enable = true;
|
||||
settings = {
|
||||
default_session = "niri";
|
||||
|
||||
animate = true;
|
||||
animation = "dur_file";
|
||||
dur_file_path = "${indyzLinuxfire}";
|
||||
dur_offset_alignment = "center";
|
||||
|
||||
full_color = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.nautilus;
|
||||
in
|
||||
{
|
||||
options.my.applications.nautilus = {
|
||||
enable = lib.mkEnableOption "Nautilus file manager";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.systemPackages = with pkgs; [
|
||||
nautilus # GNOME file manager
|
||||
gvfs # GNOME virtual file system
|
||||
sushi # Nautilus file previewer
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{ pkgs, lib, ... }:
|
||||
lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
|
||||
home.packages = [
|
||||
pkgs.nautilus
|
||||
pkgs.gvfs
|
||||
pkgs.sushi
|
||||
];
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
username,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my.applications.nh;
|
||||
in
|
||||
{
|
||||
options.my.applications.nh = {
|
||||
enable = lib.mkEnableOption "nh Nix CLI helper";
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
programs.nh = {
|
||||
enable = true;
|
||||
flake = "/home/${username}/dotfiles";
|
||||
|
||||
clean = {
|
||||
enable = true;
|
||||
dates = "weekly";
|
||||
extraArgs = "--keep-since 14d --keep 10";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user