Andrey's Blog

Arch Linux Setup and Configuration

This is my collection of Arch Linux configurations and commands that I use to maintain and optimize my system.

Battery Management

Charge Control Thresholds

To extend battery lifespan, you can configure charge thresholds that prevent the battery from charging to 100% when plugged in constantly:

echo 45 | sudo tee /sys/class/power_supply/BAT0/charge_control_start_threshold
echo 55 | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold

This configuration starts charging at 45% and stops at 55%, ideal for a laptop that stays plugged in most of the time.

Convenience Functions for .bashrc

Add these functions to your ~/.bashrc file for quick threshold switching:

setbattery50() {
    echo 45 | sudo tee /sys/class/power_supply/BAT0/charge_control_start_threshold > /dev/null
    echo 55 | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold > /dev/null
    echo "Charging range set from 45% to 55%"
}
setbattery100() {
    echo 0 | sudo tee /sys/class/power_supply/BAT0/charge_control_start_threshold > /dev/null
    echo 100 | sudo tee /sys/class/power_supply/BAT0/charge_control_end_threshold > /dev/null
    echo "Charging range set from 0% to 100%"
}

Usage:

After adding these to .bashrc, run source ~/.bashrc to load them, then simply type setbattery50 or setbattery100 in your terminal.

Check Power Status

To check if your laptop is currently plugged in or running on battery:

cat /sys/class/power_supply/AC/online

Returns:

Hyprland Monitor Configuration

Monitor Setup (monitors.conf)

Omarchy sources monitor settings from ~/.config/hypr/monitors.conf. Example setup for a laptop with an external 1440p display above:

env = GDK_SCALE,1.333334
monitor=,preferred,0x0,1
monitor=DP-4,2560x1440,0x-1440,1
monitor=eDP-1,preferred,auto,1

Use hyprctl monitors to list connected monitors and their names.

Auto-Disable Laptop Screen on Lid Close

Instead of permanently disabling the laptop screen with monitor=eDP-1,disable, you can use Hyprland’s bindl to dynamically toggle it based on the lid switch. Add this to ~/.config/hypr/bindings.conf:

# Lid switch: disable laptop screen when closed, re-enable when opened
bindl = , switch:on:Lid Switch, exec, hyprctl keyword monitor "eDP-1,disable"
bindl = , switch:off:Lid Switch, exec, hyprctl keyword monitor "eDP-1,preferred,0x0,1"

How it works:

Verify your switch name with hyprctl devices — look under the “Switches” section. It’s usually Lid Switch but may differ on some hardware.

Omarchy Config File Hierarchy

Omarchy uses a layered “last wins” approach for Hyprland configuration:

  1. Defaults (~/.local/share/omarchy/default/hypr/) — managed by Omarchy, don’t edit directly
  2. Theme (~/.config/omarchy/current/theme/hyprland.conf) — theme-specific overrides
  3. User (~/.config/hypr/) — your personal configs, always take precedence

All user customizations go in ~/.config/hypr/ to persist across Omarchy updates.

System Maintenance

Package Cache Cleanup

Regular cleanup of package caches helps free up disk space:

yay -Sc && sudo pacman -Sc

This removes old and uninstalled packages from both AUR (yay) and official repository (pacman) caches.

VPN Configuration

Wireguard VPN Setup

Wireguard is a fast, modern VPN protocol. Here’s how to set it up on Arch:

Installation:

sudo pacman -S wireguard-tools openresolv

Configuration:

sudo cp ~/Documents/VPN-Andrey-Laptop.conf /etc/wireguard/vpn.conf
sudo chmod 600 /etc/wireguard/vpn.conf

Usage:

# Start VPN
sudo wg-quick up vpn

# Check connection status
sudo wg show

# Stop VPN
sudo wg-quick down vpn

Optional DNS resolution update:

sudo resolvconf -u

Xray VLESS+Reality Setup

Xray is a powerful proxy tool that creates an encrypted tunnel to your VPS server, useful for bypassing censorship and improving privacy.

What is Xray?

Installation

yay -S xray
sudo mkdir -p /etc/xray
sudo nvim /etc/xray/config.json

Configuration Requirements

Information needed from your server:

Key configuration sections:

Configuration Template

Create /etc/xray/config.json with the following template:

{
  "log": {
    "loglevel": "warning"
  },
  "inbounds": [
    {
      "port": 10808,
      "listen": "127.0.0.1",
      "protocol": "socks",
      "settings": {
        "udp": true
      },
      "tag": "socks-in"
    },
    {
      "port": 10809,
      "listen": "127.0.0.1",
      "protocol": "http",
      "tag": "http-in"
    }
  ],
  "outbounds": [
    {
      "protocol": "vless",
      "settings": {
        "vnext": [
          {
            "address": "YOUR_SERVER_IP_OR_DOMAIN",
            "port": 443,
            "users": [
              {
                "id": "YOUR_UUID",
                "encryption": "none",
                "flow": "xtls-rprx-vision"
              }
            ]
          }
        ]
      },
      "streamSettings": {
        "network": "tcp",
        "security": "reality",
        "realitySettings": {
          "show": false,
          "fingerprint": "chrome",
          "serverName": "www.microsoft.com",
          "publicKey": "YOUR_REALITY_PUBLIC_KEY",
          "shortId": "YOUR_SHORT_ID",
          "spiderX": ""
        }
      },
      "tag": "proxy"
    },
    {
      "protocol": "freedom",
      "tag": "direct"
    }
  ],
  "routing": {
    "rules": [
      {
        "type": "field",
        "outboundTag": "direct",
        "domain": ["geosite:private"]
      },
      {
        "type": "field",
        "outboundTag": "proxy",
        "network": "tcp,udp"
      }
    ]
  }
}

Starting the Service

# Test configuration first
sudo xray run -c /etc/xray/config.json

# If it works, enable as service
sudo systemctl enable xray@config
sudo systemctl start xray@config

# Check status
sudo systemctl status xray@config

# View logs
sudo journalctl -u xray@config -f

Usage Options

1. Browser only (recommended):

2. System-wide:

3. Per-app:

proxychains <command>

4. Terminal sessions:

export all_proxy="socks5://127.0.0.1:10808"

LibreWolf is a privacy-focused Firefox fork that’s perfect for use with proxies:

sudo pacman -S librewolf

Configuration:

Testing Your Setup

# Check your real IP
curl ifconfig.me

# Check IP through proxy (should show VPS IP)
curl --socks5 127.0.0.1:10808 ifconfig.me

Security Verification

Test for leaks at:

Technical Notes

AI Agent Configuration Management

Centralized configs for AI coding agents (Copilot, Claude Code, Codex), symlinked into projects via GNU stow.

Why?

Directory Structure

Mirror the target project layout so stow can symlink directly:

~/Work/agents-configs/
├── project-name/
│   ├── AGENTS.md                          → project root
│   └── .github/
│       ├── copilot-instructions.md        → .github/
│       └── skills/                        → .github/skills/
│           ├── planning-docs/
│           │   ├── SKILL.md
│           │   └── references/
│           │       └── planning-template.md
│           ├── git-workflow/
│           │   └── SKILL.md
│           ├── laravel-testing/
│           │   └── SKILL.md
│           └── ...
├── another-project/
│   ├── AGENTS.md
│   └── .github/
│       └── ...
└── README.md

What goes where

FilePurposeLoaded
AGENTS.mdCritical rules, always-on guardrailsAlways
copilot-instructions.mdArchitecture overview, conventionsAlways
.github/skills/*/SKILL.mdTask-specific workflows and knowledgeOn demand

Keep AGENTS.md and copilot-instructions.md short (under ~200 lines total). Move procedural details into skills — they only load when relevant, saving context tokens.

Setup with GNU stow

sudo pacman -S stow   # Arch Linux

Stow creates symlinks for each item inside a folder, without overwriting existing files (like .github/workflows/).

# Link everything into your project
cd ~/Work/project-name
stow -d ~/Work/agents-configs -t . project-name

# Remove all symlinks
stow -d ~/Work/agents-configs -t . -D project-name

Verify:

ls -la AGENTS.md .github/copilot-instructions.md .github/skills
# Should show arrows → pointing to agents-configs/

.gitignore

Prevent symlinks from being committed:

# AI agent configs (symlinked from agents-configs repo)
AGENTS.md
.github/copilot-instructions.md
.github/skills/

Or set globally for all projects:

echo -e "AGENTS.md\n.github/copilot-instructions.md\n.github/skills/" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global

Troubleshooting

# Check if something is a symlink
file AGENTS.md
# → "symbolic link to ..." = good
# → "ASCII text" = regular file, not linked

# Broken symlink (shows red in ls)?
ls -la ~/Work/agents-configs/project-name/AGENTS.md   # check source exists
stow -d ~/Work/agents-configs -t . -R project-name     # restow

# "File exists" error?
# Stow won't overwrite existing files. Remove the conflict first, then restow.

Agent Skills Reference

Skills live in .github/skills/<name>/SKILL.md. Format:

---
name: skill-name
description: What it does and when to use it (max 1024 chars)
---

## Instructions

Detailed steps, examples, code snippets...

Optional subdirectories: references/, scripts/, assets/ — loaded only when the agent references them.

Skills are supported by Copilot (VS Code), Codex, and Claude Code. Personal skills (shared across all projects) go in ~/.copilot/skills/.

Last updated: February 8, 2026