Repository: ai/environment
Branch: main
Commit: 902886f2b8a4
Files: 66
Total size: 77.6 KB
Directory structure:
gitextract_8apgxoyr/
├── .editorconfig
├── .gitignore
├── .oxfmtrc.json
├── GNOME.md
├── Install.md
├── LICENSE
├── README.md
├── batconfig
├── bin/
│ ├── backup
│ ├── backup-gnome-extensions
│ ├── build-devcontainer
│ ├── clear
│ ├── clear-weather-city
│ ├── copy-env
│ ├── dev
│ ├── force-lock
│ ├── porn
│ ├── private
│ ├── restore-gnome-extensions
│ ├── susedko
│ ├── susedko-listener
│ ├── update
│ ├── update-devcontainer-configs
│ ├── update-dockerfile
│ ├── update-extension-lists
│ ├── zed-isolate
│ └── zoom
├── devcontainer/
│ ├── Dockerfile
│ ├── devcontainer.json
│ └── install-dotfiles
├── gitconfig
├── gitignore
├── hooks-trap/
│ ├── applypatch-msg
│ ├── commit-msg
│ ├── post-applypatch
│ ├── post-checkout
│ ├── post-commit
│ ├── post-merge
│ ├── post-rewrite
│ ├── pre-applypatch
│ ├── pre-auto-gc
│ ├── pre-commit
│ ├── pre-merge-commit
│ ├── pre-push
│ ├── pre-rebase
│ └── prepare-commit-msg
├── icons/
│ ├── Zoom.desktop
│ ├── backup.desktop
│ ├── com.mattjakeman.ExtensionManager.desktop
│ ├── com.nextcloud.desktopclient.nextcloud.desktop
│ ├── hu.irl.cameractrls.desktop
│ ├── porn.desktop
│ ├── private.desktop
│ ├── update.desktop
│ └── zed-isolate.desktop
├── micro.json
├── mimeapps.list
├── mpv-input.conf
├── mpv.conf
├── pnpm-config.yaml
├── ripgreprc
├── sshconfig
├── starship.toml
├── zed-keys.json
├── zed.json
└── zshrc
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[micro.json]
indent_size = 4
================================================
FILE: .gitignore
================================================
secrets.env
================================================
FILE: .oxfmtrc.json
================================================
{
"arrowParens": "avoid",
"jsxSingleQuote": false,
"quoteProps": "consistent",
"semi": false,
"singleQuote": true,
"sortImports": {
"groups": [
"side_effect",
"side_effect_style",
"style",
["builtin", "external", "unknown"],
["internal", "parent", "sibling", "index"]
],
"newlinesBetween": true,
"order": "asc"
},
"trailingComma": "none",
"printWidth": 80
}
================================================
FILE: GNOME.md
================================================
## GNOME Shell Extensions
- [All-in-One Clipboard](https://extensions.gnome.org/extension/8671/all-in-one-clipboard/)
- [Alphabetical App Grid](https://extensions.gnome.org/extension/4269/alphabetical-app-grid/)
- [App Hider](https://extensions.gnome.org/extension/5895/app-hider/)
- [Auto Power Profile](https://extensions.gnome.org/extension/6583/auto-power-profile/)
- [Autohide Battery](https://extensions.gnome.org/extension/595/autohide-battery/)
- [Battery Health Charging](https://extensions.gnome.org/extension/5724/battery-health-charging/)
- [Battery Power Mode Indicator](https://extensions.gnome.org/extension/9204/battery-power-mode-indicator/)
- [Battery time](https://extensions.gnome.org/extension/5425/battery-time/)
- [Battery Usage Wattmeter](https://extensions.gnome.org/extension/6278/battery-usage-wattmeter/)
- [Bluetooth Battery Monitor](https://extensions.gnome.org/extension/9308/bluetooth-battery-monitor/)
- [Blur my Shell](https://extensions.gnome.org/extension/3193/blur-my-shell/)
- [Dim Completed Calendar Events](https://extensions.gnome.org/extension/5979/dim-completed-calendar-events/)
- [Do Not Disturb While Screen Sharing Or Recording](https://extensions.gnome.org/extension/5985/do-not-disturb-while-screen-sharing-or-recording/)
- [Double Click Activities to App Grid](https://extensions.gnome.org/extension/9339/double-click-activities-to-app-grid/)
- [Dynamic Calendar, Clocks and Weather Icons ](https://extensions.gnome.org/extension/8640/dynamic-calendar-clocks-and-weather-icons-reborn/)
- [Dynamic Music Pill](https://extensions.gnome.org/extension/9334/dynamic-music-pill/)
- [Folder Search Provider](https://extensions.gnome.org/extension/8227/folder-search-provider/)
- [Forge](https://extensions.gnome.org/extension/4481/forge/)
- [Gnome 4x UI Improvements](https://extensions.gnome.org/extension/4158/gnome-40-ui-improvements/)
- [GSConnect](https://extensions.gnome.org/extension/1319/gsconnect/)
- [Hide Keyboard Layout](https://extensions.gnome.org/extension/2848/hide-keyboard-layout/)
- [Home Assistant Extension](https://extensions.gnome.org/extension/4170/home-assistant-extension/)
- [Launch New Instance](https://extensions.gnome.org/extension/600/launch-new-instance/)
- [Night Theme Switcher](https://extensions.gnome.org/extension/2236/night-theme-switcher/)
- [Quick Settings Tweaks](https://extensions.gnome.org/extension/5446/quick-settings-tweaker/)
- [Right Click Next](https://extensions.gnome.org/extension/7600/right-click-next/)
- [Screenshot OCR](https://extensions.gnome.org/extension/9338/screenshot-ocr/)
- [Top Panel Workspace Scroll](https://extensions.gnome.org/extension/701/top-panel-workspace-scroll/)
- [Tweaks & Extensions in System Menu](https://extensions.gnome.org/extension/1653/tweaks-in-system-menu/)
- [Weather O'Clock](https://extensions.gnome.org/extension/5470/weather-oclock/)
================================================
FILE: Install.md
================================================
## How I install my system
### Preparing
Download [Fedora image](https://getfedora.org/ru/workstation/)
and write it to the USB drive:
```sh
flatpak install flathub io.gitlab.adhami3310.Impression
```
Copy `.ssh` and `.local/share/gnupg` into `Документы/.Private`.
Clean `node_modules`:
```sh
rm -R ~/Dev/*/node_modules ~/Dev/*/*/node_modules ~/Dev/*/coverage ~/Dev/susedko/fedora-coreos.iso
```
Copy these files to external SDD:
- `Dev/`
- `Vídeos/*`
- `Документы/.Private/`
### BIOS
1. Boot to BIOS and set supervisor password.
2. Set Game Optimized iGPU.
3. Temporary enable USB boot.
### Install
Start installer:
1. Select English language.
2. Use entire disk mode with encryption.
Reboot to USB drive again. Mount laptop SSD.
Open `etc/fstab`.
Add `noatime,nodiratime` to root & home partitions.
Move `/tmp` and `/var/tmp` to RAM:
```
vartmp /var/tmp tmpfs defaults,noatime,nodiratime 0 0
vartmp /tmp tmpfs defaults,noatime,nodiratime 0 0
```
Reboot to BIOS. Block boot from USB.
Reboot to system. Set Russian language, name to `Andrey Sitnik` and login `ai`.
Set laptop name:
```sh
sudo hostnamectl set-hostname savoia
```
Reboot.
Copy `Dev/` and `Документы/.Private/` from external SDD and open `Install.md` locally.
Reduce swap usage by creating `/etc/sysctl.d/99-swappiness.conf` with:
```
vm.swappiness = 10
```
Fix booting video glitch:
```sh
sudo grubby --update-kernel=ALL --args="plymouth.use-simpledrm=0"
```
Enable `Rendimiento`, disable `Ahorro de energía automático`,
`Suspender automaticámente` in Energía settings.
### System Update
Set `KEYMAP=us` and `XKBLAYOUT=us` in `/etc/vconsole.conf`.
Remove unnecessary packages:
```sh
sudo dnf remove cheese rhythmbox gnome-boxesd orca gnome-contacts gnome-getting-started-docs nautilus-sendto gnome-shell-extension-* libreoffice-* gnome-characters gnome-maps gnome-photos simple-scan virtualbox-guest-additions gedit gnome-boxes gnome-tour gnome-connections mediawriter eog gnome-system-monitor baobab gnome-log gnome-calculator gnome-weather gnome-text-editor gnome-font-viewer gnome-clocks gnome-calendar evince totem ffmpeg-free snapshot intel-media-driver cups-browsed anaconda malcontent-control loupe
```
Run Software Center, disable `Fedora Flatpak` and enable Flathub and Chrome.
Add RPM Fusion (for codecs) and Terra (for Zed):
```sh
sudo dnf install --nogpgcheck http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
sudo dnf install --nogpgcheck --repofrompath 'terra,https://repos.fyralabs.com/terra$releasever' terra-release
```
Update system via Software Center.
Install software:
```sh
sudo dnf swap ffmpeg-free ffmpeg --allowerasing
sudo dnf swap mesa-va-drivers mesa-va-drivers-freeworld
sudo dnf swap mesa-vdpau-drivers mesa-vdpau-drivers-freeworld
sudo dnf copr enable atim/starship
sudo dnf copr enable dusansimic/themes
sudo dnf copr enable hyperreal/better_fonts
sudo dnf install xclip micro fuse-encfs zenity borgbackup openssl ffmpegthumbnailer nss-tools mosquitto ydotool amrnb amrwb faac faad2 flac gstreamer1-libav gstreamer1-plugins-bad-freeworld gstreamer-ffmpeg gstreamer-plugins-bad-nonfree gstreamer-plugins-espeak gstreamer-plugins-ugly lame libdca libmad libmatroska x264 x265 xvidcore gstreamer1-plugins-bad-free gstreamer1-plugins-base gstreamer1-plugins-good gstreamer-plugins-bad gstreamer1-plugins-ugly-free mpv ffmpeg xorg-x11-drv-intel intel-media-driver webp-pixbuf-loader heif-pixbuf-loader avif-pixbuf-loader libheif-freeworld ffmpeg-libs libva libva-utils gstreamer1-vaapi mozilla-openh264 libheif-tools unrar p7zip p7zip-plugins speech-dispatcher speech-dispatcher-utils google-chrome-stable nodejs podman git tig ripgrep xkill bat make difftastic nextcloud-client zsh util-linux-user starship sqlite morewaita-icon-theme nethogs fuse-sshfs logiops libgda libgda-sqlite playerctl cabextract xorg-x11-font-utils tesseract tesseract-devel zed
sudo rpm -ivh --nodigest --nofiledigest https://downloads.sourceforge.net/project/mscorefonts2/rpms/msttcore-fonts-installer-2.6-1.noarch.rpm
```
Set Flatpak languages:
```sh
flatpak config languages --set "es;en;ru"
sudo flatpak update
```
Install applications from Flatpak:
```sh
flatpak install flathub de.haeckerfelix.Fragments org.telegram.desktop org.nickvision.tubeconverter org.gnome.Loupe com.mattjakeman.ExtensionManager io.gitlab.adhami3310.Converter net.nokyan.Resources org.gnome.Calculator org.gnome.Logs org.gnome.Weather org.gnome.clocks org.gnome.Calendar org.gnome.Epiphany org.inkscape.Inkscape org.gnome.gitlab.YaLTeR.VideoTrimmer org.gnome.World.Iotas app.devsuite.Ptyxis hu.irl.cameractrls org.gnome.Snapshot org.gnome.Papers org.gimp.GIMP be.alexandervanhee.gradia com.github.PintaProject.Pinta com.yubico.yubioath org.gnome.font-viewer
```
Install [Zoom](https://zoom.us/download).
Remove default GNOME console.
Set `Ctrl + C` and `Ctrl + V` for copy/paste in new terminal settings.
Fix unnecessary folder creation in Zoom:
```sh
flatpak override --user us.zoom.Zoom --nofilesystem=~/Documents/Zoom
mkdir -p ~/.local/share/flatpak/exports/share/applications/
cp /var/lib/flatpak/exports/share/applications/us.zoom.Zoom.desktop ~/.local/share/flatpak/exports/share/applications/
```
Replace `Exec` to `/home/ai/Dev/environment/bin/zoom @@u %U @@` in `~/.local/share/flatpak/exports/share/applications/us.zoom.Zoom.desktop`.
Add Autostart and fingers to user settings.
Disable Software auto-update and notifications.
Set [color profile](https://www.notebookcheck.net/uploads/tx_nbc2/BOE0CB4.icm)
in `Color` settings.
Install `micro` and its plugins:
```sh
micro -plugin install editorconfig
sudo dnf remove nano
```
Disable waking up by mouse by creating `/etc/udev/rules.d/logitech-bolt.rules`:
```sh
ACTION=="add", SUBSYSTEM=="usb", DRIVERS=="usb", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c548", ATTR{power/wakeup}="disabled"
```
Disable file system scanning:
```sh
dconf write /org/freedesktop/tracker/miner/files/crawling-interval -2
```
### Personal Files
Copy `.ssh` and `.local/share/gnupg`:
```sh
~/Dev/environment/bin/private
```
Change permissions:
```sh
chmod 744 ~/.ssh
chmod 700 ~/.local/share/gnupg/
chmod 644 ~/.ssh/* ~/.local/share/gnupg/*
chmod 700 ~/.local/share/gnupg/private-keys-v1.d
chmod 600 ~/.ssh/id_* ~/.local/share/gnupg/private-keys-v1.d/*
```
Copy configs:
```sh
~/Dev/environment/bin/copy-env system
```
## Input
Set mouse buttons config at `/etc/logid.cfg`:
```
devices: ({
name: "MX Master 3S";
smartshift: { on: false; }
hiresscroll: { hires: false; invert: false; target: false; };
buttons: (
{
cid: 0x53; # Back
action = {
type: "Keypress";
keys: ["KEY_LEFTCTRL", "KEY_V"];
};
},
{
cid: 0x56; # Forward
action = {
type: "Keypress";
keys: ["KEY_LEFTCTRL", "KEY_C"];
};
}
);
});
```
Add `-c /etc/logid.cfg` to `Exec` field of `/usr/lib/systemd/system/logid.service`.
Enable mouse extensions:
```sh
sudo systemctl enable --now logid
```
Install custom universal keyboard layouts:
```sh
mkdir -p ~/.config/xkb/symbols/ ~/.config/xkb/rules/
wget -O ~/.config/xkb/symbols/universal_en https://raw.githubusercontent.com/ai/universal-layout/main/universal_en.xkb
wget -O ~/.config/xkb/symbols/universal_ru https://raw.githubusercontent.com/ai/universal-layout/main/universal_ru.xkb
wget -O ~/.config/xkb/rules/evdev.xml https://raw.githubusercontent.com/ai/universal-layout/main/evdev.xml
```
Set keyboard settings:
```sh
dconf write /org/gnome/desktop/input-sources/xkb-options "['grp_led:caps', 'lv3:ralt_switch', 'grp:shift_caps_switch']"
```
### Terminal
Install eza:
```sh
curl -sL https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-gnu.tar.gz | tar xz
chmod +x eza
mkdir -p ~/.local/bin/
mv eza ~/.local/bin
```
Install atuin:
```sh
curl -sL https://github.com/atuinsh/atuin/releases/download/v18.6.1/atuin-x86_64-unknown-linux-gnu.tar.gz | tar xz --strip-components=1 atuin-x86_64-unknown-linux-gnu/atuin
mv atuin ~/.local/bin
```
Install zsh:
```sh
mkdir -p ~/.local/share/history
chmod 700 ~/.local/share/history
git clone https://github.com/zsh-users/zsh-syntax-highlighting ~/.local/lib/zsh/zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-autosuggestions ~/.local/lib/zsh/zsh-autosuggestions
git clone https://github.com/jimhester/per-directory-history ~/.local/lib/zsh/per-directory-history
chsh -s /bin/zsh
```
Create `/root/.zshrc`:
```sh
eval "$(starship init zsh)"
```
Reboot.
Select `Russian Universal` and `English/Spanish/Catalan Universal` layouts.
```sh
rm ~/.bash*
```
Open backup and copy files from it.
```sh
mkdir ~/backup
borg mount "ai@susedko.local:/var/mnt/vault/ai/backup" ~/backup
```
Copy files.
```sh
borg umount ~/backup
rmdir ~/backup
```
Start copying `Vídeos/*` from SDD.
### Text Editors
Move Claude Code:
```bash
mkdir -p ~/.config/environment.d/
mkdir -p ~/.local/share/claude
echo "GNUPGHOME=$HOME/.local/share/gnupg" >> ~/.config/environment.d/90-clean-home.conf
echo "NODE_COMPILE_CACHE=$HOME/.cache/node" >> ~/.config/environment.d/90-clean-home.conf
echo "NPM_CONFIG_USERCONFIG=$HOME/.config/npmrc" >> ~/.config/environment.d/90-clean-home.conf
echo "CLAUDE_CONFIG_DIR=$HOME/.local/share/claude" >> ~/.config/environment.d/90-clean-home.conf
```
Sign-in into accounts in Zed.
Install Zed plugins: `ini`, `dockerfile`, `toml`, `svelte`, `make`, `adwaita-pastel`, `material icon theme`, `codebook`, `sql`, `nginx`, `git-firefly`, `pug`, `xml`, `po`, `env`, `oxc`.
Open Iotas app, log-in into Nextcloud account.
### GNOME Settings
Open Clock and add `Vladivostok`, `Moscow`, `Lisbon`, and `San Francisco`.
Run Weather app and set current location.
Install [Lilex](https://lilex.myrt.co).
```sh
mkdir -p ~/.local/share/fonts
# Copy variable fonts
fc-cache -f -v
gsettings set org.gnome.desktop.interface monospace-font-name "Lilex 12"
```
Open settings:
- **Appearance:** use standard GNOME wallpaper.
- **Notifications:** disable Notifications on lock screen.
- **Search:** keep only Calculator and Settings.
- **Multitask:** disable Active corners.
- **Online accounts:** add Google.
- **Power:** enable Show percentage and disable screen lock.
- **Mouse:** mouse speed to 75%, touchpad speed to 90%.
- **Date and time:** enable seconds and week day on top panel.
- **Privacy** → disable File History.
Boost volume over 100%:
```sh
gsettings set org.gnome.desktop.sound allow-volume-above-100-percent true
```
Login to NextCloud client to `sync.sitnik.es`.
Nautilus:
- Enable Sort folders before files.
- Enable Single click to open items.
- Enable preview, search, file numbers for remote folders.
Disable GNOME extension version check:
```sh
gsettings set org.gnome.shell disable-extension-version-validation true
```
Download the latest [`framework_tool`](https://github.com/FrameworkComputer/framework-system/actions?query=branch%3Amain), extract and copy to the system:
```sh
sudo cp ~/Descargas/framework_tool /usr/local/bin
```
Install tool for clipboard manager:
```bash
mkdir -p ~/.local/share/copyous@boerdereinar.dev/
curl https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/es/highlight.min.js > ~/.local/share/copyous@boerdereinar.dev/highlight.min.js
```
Install extensions from [`GNOME.md`](./GNOME.md).
Restore settings file from backup:
```sh
~/Dev/environment/bin/restore-gnome-extensions
```
Clean up applications list.
Add Iceland NordVPN.
[Disable](https://discussion.fedoraproject.org/t/please-enter-passphrase-for-disk-has-returned/150626/5) disk name in password prompt.
### Folders
Create empty file template:
```sh
mkdir ~/.local/share/desktop
mkdir ~/.local/share/templates
touch ~/.local/share/templates/Пустой\ файл
```
Fix folders at `~/.config/user-dirs.dirs`:
```sh
XDG_DESKTOP_DIR="$HOME/.local/share/desktop"
XDG_DOWNLOAD_DIR="$HOME/Загрузки"
XDG_TEMPLATES_DIR="$HOME/.local/share/templates"
XDG_PUBLICSHARE_DIR="$HOME/.local/share/desktop"
XDG_DOCUMENTS_DIR="$HOME/Документы"
XDG_MUSIC_DIR="$HOME"
XDG_PICTURES_DIR="$HOME"
XDG_VIDEOS_DIR="$HOME/Видео"
```
Clean bookmarks:
```sh
echo "" > ~/.config/gtk-3.0/bookmarks
```
Remove unnecessary folders:
```sh
mkdir "Снимки экрана"
```
Connect to server in Files by `sftp://ai@susedko.local/` and add `vault` to Favorites places. Add `Загрузки` and `Снимки экрана` to Favorites places.
Left only Telegram, Firefox, Nautilus, Terminal, Iotas, System Update, and
Backup in the dock.
Add icon theme:
```sh
gsettings set org.gnome.desktop.interface icon-theme 'MoreWaita'
```
Set icons:
- `/usr/share/icons/MoreWaita/scalable/places/folder-code.svg`
for `~/Dev/`.
- `/usr/share/icons/Adwaita/scalable/places/folder-pictures.svg`
for `~/Capturas de pantalla/`.
## Home Server
Add server’s certificate to the system:
```sh
mkdir -p ~/.pki/nssdb
certutil -N -d sql:$HOME/.pki/nssdb --empty-password
certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n sitnik -i ~/Dev/susedko/sitniks.crt
sudo cp ~/Dev/susedko/sitniks.crt /etc/pki/ca-trust/source/anchors/sitniks.pem
sudo update-ca-trust
```
Add service to `~/.config/systemd/user/force-lock.service`:
```ini
[Unit]
Description=Force Lock
[Service]
ExecStart=/home/ai/Dev/environment/bin/force-lock
Restart=on-failure
RestartSec=30s
[Install]
WantedBy=default.target
```
Add service to `~/.config/systemd/user/susedko-listener.service`:
```ini
[Unit]
Description=Susedko Listener
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/home/ai/Dev/environment/bin/susedko-listener
Restart=on-failure
RestartSec=30s
StartLimitBurst=5
[Install]
WantedBy=default.target
```
Add service to `/etc/systemd/system/ydotoold.service`:
```ini
[Unit]
Description=ydotool Daemon
[Service]
ExecStart=ydotoold --socket-path="/run/.ydotool_socket" --socket-own="1000:1000"
Restart=on-failure
RestartSec=30s
[Install]
WantedBy=default.target
```
Enable services:
```sh
sudo systemctl enable ydotoold.service
sudo systemctl start ydotoold.service
systemctl --user enable susedko-listener.service force-lock.service
systemctl --user start susedko-listener.service force-lock.service
```
### Development Tools
Install Node.js, TypeScript, and Dev Containers.
```sh
npm config set cache "$HOME/.cache/npm"
mkdir -p ~/.local/lib/node/
tee -a ~/.local/lib/node/package.json << EOM
{
"dependencies": {
"@devcontainers/cli": ">=0.80.1"
}
}
EOM
cd ~/.local/lib/node && npm install && cd
mkdir -p ~/.local/share/multiocular
mkdir -p ~/.local/share/history
chmod 700 ~/.local/share/history
podman volume create shell-history
podman volume create pnpm-store
~/Dev/environment/bin/build-devcontainer
cd ~/Dev/nanostores
devup
# Find container ID
podman exec -it --user root $container_id zsh
mkdir /home/ai/.local/share/pnpm/store/v11
chown ai:ai /home/ai/.local/share/pnpm/store/v11
chown ai:ai /home/ai/.local/share/history/histfile
```
Fix Dev Container with Podman in Zed:
```sh
sudo ln -s $(which podman) /usr/local/bin/docker
```
Install Keybase:
```sh
sudo dnf install https://prerelease.keybase.io/keybase_amd64.rpm
run_keybase
```
Disable autostart in Keybase settings and revoke old laptop.
## LanguageTool Server
Prepare [ngrams](https://languagetool.org/download/ngram-data/):
```sh
mkdir -p ~/.local/share/ngrams
cd ~/.local/share/ngrams
wget https://languagetool.org/download/ngram-data/ngrams-en-20150817.zip
wget https://languagetool.org/download/ngram-data/ngrams-es-20150915.zip
wget https://languagetool.org/download/ngram-data/untested/ngram-ru-20150914.zip
unzip ngrams-en-20150817.zip
unzip ngrams-es-20150915.zip
unzip ngram-ru-20150914.zip
rm ngram*.zip
```
```sh
mkdir -p ~/.config/systemd/user/
```
Create service unit `~/.config/systemd/user/languagetool.service`:
```ini
[Unit]
Description=LanguageTool Server
[Service]
ExecStart=podman run --rm --replace --name languagetool \
-p 8081:8010 \
-e langtool_languageModel=/ngrams \
-e Java_Xms=512m -e Java_Xmx=2g \
-v /home/ai/.local/share/fasttext:/fasttext:Z \
-v /home/ai/.local/share/ngrams:/ngrams:Z \
docker.io/erikvl87/languagetool:latest
[Install]
WantedBy=default.target
```
Install LanguageTool:
```sh
~/Dev/environment/bin/update-languagetool
```
Enable service.
```sh
systemctl --user daemon-reload
systemctl --user enable --now languagetool.service
systemctl --user start --now languagetool.service
```
================================================
FILE: LICENSE
================================================
The MIT License (MIT)
Copyright 2013 Andrey Sitnik <andrey@sitnik.es>
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
My home configs, scripts and [installation process](./Install.md).
See also [my keyboard layout](https://github.com/ai/universal-layout).
### Configs
- [GNOME Shell extensions](./GNOME.md)
- [`.gitconfig`](./gitconfig)
================================================
FILE: batconfig
================================================
--plain
================================================
FILE: bin/backup
================================================
#!/bin/sh
TITLE='\033[0;32m\033[1m'
GRAY='\033[0;90m'
NC='\033[0m'
hour=$(date +"%H")
if [[ hour -lt 9 || hour -ge 22 ]]; then
echo -e "${TITLE}Подготовка кровати ко сну${GRAY}"
~/Dev/environment/bin/susedko script/turn_on script.heat_bedroom
echo -e "${NC}\n"
fi
echo -e "${TITLE}Сохранение расширений GNOME${GRAY}"
~/Dev/environment/bin/backup-gnome-extensions
echo -e "${NC}\n"
echo -e "${TITLE}Сохранение домашнего сервера${GRAY}"
cd ~/Dev/susedko
make ha_backup
cd
echo -e "${NC}\n"
echo -e "${TITLE}Сохранение файлов${GRAY}"
export BORG_REPO=ai@susedko.local:/var/mnt/vault/ai/backup
SERVICE_NAME="BorgBackup"
USERNAME="backup"
BORG_PASSPHRASE=$(secret-tool lookup service "BorgBackup" username "ai")
if [ -z "$BORG_PASSPHRASE" ]; then
read -sp "Пароль от бэкапа: " BORG_PASSPHRASE
echo "$BORG_PASSPHRASE" | secret-tool store --label="Password for backup" service "BorgBackup" username "ai"
fi
export BORG_PASSPHRASE
borg create \
--verbose \
--filter AME \
--list \
--stats \
--show-rc \
--progress \
--compression lz4 \
--exclude-caches \
--exclude '*.iso' \
--exclude '**/node_modules' \
--exclude '**/.config/mozilla/**/lock' \
--exclude '**/.config/mozilla/**/crashes' \
--exclude '**/.config/mozilla/**/bookmarkbackups' \
--exclude '**/.config/mozilla/**/datareporting/archived' \
--exclude '**/.config/mozilla/**/weave/logs' \
--exclude '**/.config/mozilla/**/cache' \
--exclude '**/.config/mozilla/firefox/firefox-mpris' \
--exclude '**/.config/mozilla/firefox/Crash Reports' \
--exclude '**/.var/app/**/cache' \
--exclude '**/.var/app/**/Cache' \
--exclude '**/.var/app/**/media_cache' \
--exclude '**/.var/app/**/temp_data' \
--exclude '**/.var/app/**/cache_*' \
--exclude '**/.var/app/org.gnome.Epiphany' \
--exclude '**/.var/app/org.inkscape.Inkscape' \
--exclude '**/.var/app/io.missioncenter.MissionCenter' \
--exclude '**/.var/app/com.belmoussaoui.Decoder' \
--exclude '**/.var/app/us.zoom.Zoom/.zoom/data/Emojis' \
--exclude '**/.ld.so' \
--exclude '**/*.log' \
--exclude '**/sitnik.es/dist' \
::'{hostname}-{now}' \
~/Dev/susedko \
~/Dev/environment \
~/Dev/sitnik.es \
~/.ssh \
~/.local/share/gnupg \
~/Документы/.Private \
~/.config/mozilla \
~/.config/gsconnect \
~/.local/share/gnome-shell-extensions-settings \
~/.var/app
borg prune \
--list \
--show-rc \
--keep-last 14
borg compact
unset BORG_PASSPHRASE
echo -e "${NC}\n"
echo -e "${TITLE}Синхронизация видео${GRAY}"
rsync -a --delete --progress \
--no-perms --no-owner --no-group \
/home/ai/Видео/Эротика/ ai@susedko.local:/var/mnt/vault/ai/Selected
exit ${global_exit}
================================================
FILE: bin/backup-gnome-extensions
================================================
#!/bin/bash
backup_dir="$HOME/.local/share/gnome-shell-extensions-settings"
rm -r "$backup_dir"
mkdir -p "$backup_dir"
extensions=$(gsettings get org.gnome.shell enabled-extensions | tr -d "[],'")
for extension in $extensions; do
base_name=$(echo "$extension" | sed 's/@.*//')
output_file="$backup_dir/${extension}.ini"
settings=$(dconf dump "/org/gnome/shell/extensions/$base_name/")
if [ -n "$settings" ]; then
echo "$settings" > "$output_file"
echo "Настройки $extension сохранены"
fi
done
================================================
FILE: bin/build-devcontainer
================================================
#!/bin/bash
~/Dev/environment/bin/copy-env
podman build -t localhost/ai-opensource \
-f /home/ai/Dev/environment/devcontainer/Dockerfile \
/home/ai/Dev/environment
================================================
FILE: bin/clear
================================================
#!/bin/sh
echo "Было $(df -h / | tail -1 | awk '{print $4}')"
echo
podman rmi --all --force
pnpm store prune
yarn cache clean
npm cache clean -f
rm -Rf ~/.local/share/Trash/
echo
echo "Стало $(df -h / | tail -1 | awk '{print $4}')"
================================================
FILE: bin/clear-weather-city
================================================
#!/bin/sh
gsettings reset org.gnome.Weather locations
================================================
FILE: bin/copy-env
================================================
#!/bin/sh
# Copy config and scripts to or from repo
if [ "$1" == "system" ]; then
rm ~/.local/share/applications/*.{desktop,svg} -f
cp ~/Dev/environment/icons/* ~/.local/share/applications/
mkdir -p ~/.config/bat/
mkdir -p ~/.config/mpv/
mkdir -p ~/.config/git/
mkdir -p ~/.config/micro/
mkdir -p ~/.config/zed/
rm -f ~/.zshrc
ln ~/Dev/environment/zshrc ~/.zshrc
cp ~/Dev/environment/.oxfmtrc.json ~/.oxfmtrc.json
cp ~/Dev/environment/zed.json ~/.config/zed/settings.json
cp ~/Dev/environment/zed-keys.json ~/.config/zed/keymap.json
cp ~/Dev/environment/mpv.conf ~/.config/mpv/mpv.conf
cp ~/Dev/environment/ripgreprc ~/.config/ripgreprc
cp ~/Dev/environment/sshconfig ~/.ssh/config
cp ~/Dev/environment/batconfig ~/.config/bat/config
cp ~/Dev/environment/gitconfig ~/.config/git/config
cp ~/Dev/environment/gitignore ~/.config/git/ignore
cp ~/Dev/environment/starship.toml ~/.config/starship.toml
cp ~/Dev/environment/mimeapps.list ~/.config/mimeapps.list
cp ~/Dev/environment/mpv-input.conf ~/.config/mpv/input.conf
cp ~/Dev/environment/micro.json ~/.config/micro/settings.json
else
rm ~/Dev/environment/icons/*.{svg,desktop} -f
cp ~/.oxfmtrc.json ~/Dev/environment/.oxfmtrc.json
cp ~/.ssh/config ~/Dev/environment/sshconfig
cp ~/.config/ripgreprc ~/Dev/environment/ripgreprc
cp ~/.config/git/config ~/Dev/environment/gitconfig
cp ~/.config/git/ignore ~/Dev/environment/gitignore
cp ~/.config/bat/config ~/Dev/environment/batconfig
cp ~/.config/mpv/mpv.conf ~/Dev/environment/mpv.conf
cp ~/.config/starship.toml ~/Dev/environment/starship.toml
cp ~/.config/mpv/input.conf ~/Dev/environment/mpv-input.conf
cp ~/.config/mimeapps.list ~/Dev/environment/mimeapps.list
cp ~/.config/micro/settings.json ~/Dev/environment/micro.json
cp ~/.local/share/applications/*.{svg,desktop} ~/Dev/environment/icons/
cp ~/.config/zed/settings.json ~/Dev/environment/zed.json
cp ~/.config/zed/keymap.json ~/Dev/environment/zed-keys.json
rm ~/Dev/environment/icons/chrome-* -f
rm ~/Dev/environment/icons/userapp-* -f
rm ~/Dev/environment/icons/org.gnome.Shell.Extensions.* -f
~/Dev/environment/bin/update-extension-lists
fi
================================================
FILE: bin/dev
================================================
#!/bin/bash
set -e
function get_container_runtime() {
if command -v podman &> /dev/null; then
echo "podman"
elif command -v docker &> /dev/null; then
echo "docker"
else
echo "Error: Neither podman nor docker found" >&2
return 1
fi
}
function devcontainer_root() {
local dir=$PWD
while [ "$dir" != "/" ]; do
if [[ -f "$dir/.devcontainer.json" ]] || [[ -d "$dir/.devcontainer" ]]; then
echo $dir
return
fi
dir=$(dirname "$dir")
done
echo "No .devcontainer.json or .devcontainer/ found" >&2
return 1
}
function devcontainer_config() {
if [[ -f "$1/.devcontainer/podman/devcontainer.json" ]]; then
echo "$1/.devcontainer/podman/devcontainer.json"
elif [[ -f "$1/.devcontainer/devcontainer.json" ]]; then
echo "$1/.devcontainer/devcontainer.json"
else
echo "$1/.devcontainer.json"
fi
}
function get_container_id() {
local runtime=$(get_container_runtime)
$runtime ps -q --filter label=devcontainer.local_folder=$root
}
function get_username() {
local username=""
if [ -f "$root/.devcontainer/Dockerfile" ]; then
username=$(
awk -v IGNORECASE=1 '/^\s*USER\s+/{u=$2} END{print u}' "$root/.devcontainer/Dockerfile"
)
fi
echo "${username:-ai}"
}
if [ "$1" = "--isolate" ]; then
cp ~/Dev/environment/devcontainer/devcontainer.json .devcontainer.json
if [ -d .git ]; then
sed -i '/devcontainer/d' .git/info/exclude
echo '.devcontainer.json' >> .git/info/exclude
fi
exit
fi
root=$(devcontainer_root)
if [ "$root" = "" ]; then
echo "No .devcontainer.json or .devcontainer/ found" >&2
return 1
fi
if [ "$1" = "--up" ]; then
runtime=$(get_container_runtime)
devcontainer_args=(
"--docker-path" "$runtime"
"--mount" "type=bind,source=${SSH_AUTH_SOCK},target=/run/user/1000/gcr/ssh"
"--dotfiles-repository" "https://github.com/ai/environment.git"
"--dotfiles-install-command" "devcontainer/install-dotfiles"
"--workspace-folder" "$root"
"--config" "$(devcontainer_config $root)"
)
if [ -d /home/ai/.local/share/multiocular ]; then
devcontainer_args+=(
"--mount" "type=bind,source=/home/ai/.local/share/multiocular,target=/home/$(get_username)/.local/share/multiocular"
)
fi
if [ -d /home/ai/.local/share/claude ]; then
devcontainer_args+=(
"--mount" "type=bind,source=/home/ai/.local/share/claude,target=/home/$(get_username)/.local/share/claude"
"--mount" "type=bind,source=/home/ai/.local/share/claude,target=/home/$(get_username)/.claude"
)
fi
if [ -d /home/ai/.local/share/zed ]; then
devcontainer_args+=(
"--mount" "type=bind,source=/home/ai/.local/share/zed,target=/home/$(get_username)/.local/share/zed"
"--mount" "type=bind,source=/home/ai/.config/zed,target=/home/$(get_username)/.config/zed"
"--mount" "type=bind,source=/home/ai/.local/share/zed_server,target=/home/$(get_username)/.zed_server"
)
fi
devcontainer up "${devcontainer_args[@]}"
elif [ "$1" = "--down" ]; then
runtime=$(get_container_runtime)
container_id=$(get_container_id)
if [ "$container_id" == "" ]; then
echo "Container is not running"
else
$runtime kill $container_id
fi
elif [ "$1" = "--rebuild" ]; then
~/Dev/environment/bin/dev --up
container_id=$(~/Dev/environment/bin/dev --down)
runtime=$(get_container_runtime)
$runtime container rm $container_id
search_pattern="vsc-$(basename "$root")-[0-9a-f]\+-uid"
image_id=$($runtime image ls --format "{{.Repository}}:{{.Tag}}" | grep "$search_pattern" | awk '{print $1}')
if [ "$image_id" != "" ]; then
$runtime image rm --force $image_id
fi
~/Dev/environment/bin/dev --up
elif [ "$1" = "--port" ]; then
if [[ "$2" =~ ^[0-9]+$ ]]; then
# $2 is a number, use it as port
port="$2"
shift 2
args="$*"
else
# No port specified or $2 is not a number, generate random port
while true; do
port=$(shuf -i 1024-9999 -n 1)
if ! ss -tuln | grep -q ":${port}\s"; then
break
fi
done
shift 1
args="$* --port $port"
fi
runtime=$(get_container_runtime)
container_args=(
"--rm"
"-w" "/workspaces/$(basename $root)"
"-p" "${port}:${port}"
"--mount" "type=bind,source=$root,target=/workspaces/$(basename $root)"
"--security-opt" "label=disable"
"--userns=keep-id"
"--ulimit=host"
"--cap-add=NET_RAW"
)
if [ -d "/home/ai/.local/share/multiocular" ]; then
container_args+=(
"--mount" "type=bind,source=/home/ai/.local/share/multiocular,target=/home/$(get_username)/.local/share/multiocular"
)
fi
if [[ "$args" == pnpm\ multiocular* ]] && [ -f ~/Dev/multiocular/.env ]; then
container_args+=("--env-file")
container_args+=("/home/ai/Dev/multiocular/.env")
fi
$runtime run "${container_args[@]}" -it localhost/ai-opensource $args
else
runtime=$(get_container_runtime)
container_id=$(get_container_id)
if [ "$container_id" == "" ]; then
~/Dev/environment/bin/dev --up
container_id=$(get_container_id)
fi
subdir=""
if [ "$PWD" != "$root" ]; then
subdir="${PWD#$root/}"
fi
workdir="/workspaces/$(basename $root)/$subdir"
if [ -z "$1" ]; then
$runtime exec -w $workdir -it $container_id zsh
else
$runtime exec -w $workdir -it $container_id zsh -ic "$*"
fi
fi
================================================
FILE: bin/force-lock
================================================
#!/bin/bash
IDLE_TIME=240000
LANG=en
log() { echo "$(date '+%H:%M:%S') $*"; }
while true; do
CURRENT_IDLE=$(gdbus call --session \
--dest org.gnome.Mutter.IdleMonitor \
--object-path /org/gnome/Mutter/IdleMonitor/Core \
--method org.gnome.Mutter.IdleMonitor.GetIdletime \
| awk '{print $2}' | tr -d ',)')
if [ "$CURRENT_IDLE" -ge "$IDLE_TIME" ]; then
IS_ACTIVE=$(gdbus call --session \
--dest org.gnome.ScreenSaver \
--object-path /org/gnome/ScreenSaver \
--method org.gnome.ScreenSaver.GetActive)
if echo "$IS_ACTIVE" | grep -qPo "false"; then
LOCK_DISABLED=""
for player in $(playerctl --list-all); do
URL=$(playerctl --player="$player" metadata xesam:url 2>/dev/null)
IS_YOUTUBE=$(echo "$URL" | grep -q "youtube.com/watch" && echo true)
STATUS=$(playerctl --player="$player" status 2>/dev/null)
if [ "$IS_YOUTUBE" = "true" ] && [ "$STATUS" = "Playing" ]; then
log "YouTube playing, skipping lock"
LOCK_DISABLED="true"
break
fi
done
if pactl list sink-inputs | grep -qi "application\.name = \"mpv\""; then
log "mpv playing, skipping lock"
LOCK_DISABLED="true"
fi
if pactl list source-outputs | grep -q "Source Output #"; then
log "Ongoing call, skipping lock"
LOCK_DISABLED="true"
fi
if [ -z "$LOCK_DISABLED" ]; then
log "Locking session"
loginctl lock-session
fi
fi
fi
sleep 60
done
================================================
FILE: bin/porn
================================================
#!/bin/sh
# Run movies from specific category
if [[ "$1" == "--new" ]]; then
mkdir -p ~/.susedko_new
sshfs ai@susedko.local:/var/mnt/vault/ai/New/ ~/.susedko_new
mpv --shuffle --fullscreen --playlist=<(
find ~/.susedko_new -type f \
! -name '*.part' \
! -name '*.png' \
! -name '*.jpg' \
! -name '*.jpeg'
)
fusermount -u ~/.susedko_new
rmdir ~/.susedko_new
else
find /home/ai/Видео/Эротика -type f -print0 | tr '\0' '\n' | mpv --shuffle --fullscreen --playlist=-
fi
================================================
FILE: bin/private
================================================
#!/bin/sh
# Private encrypted folder
STORE=$HOME/Документы/.Private
LINK=$HOME/Private
if [ -e "$LINK" ]; then
# Lock
fusermount -u "$LINK"
rm -R "$LINK"
else
# Unlock
mkdir "$LINK"
encfs "$STORE" "$LINK" --extpass "zenity --password"
nautilus "$LINK"
fi
================================================
FILE: bin/restore-gnome-extensions
================================================
#!/bin/bash
backup_dir="$HOME/.local/share/gnome-shell-extensions-settings"
if [ ! -d "$backup_dir" ]; then
echo "Settings directory $backup_dir not found. Exiting."
exit 1
fi
extensions=$(gsettings get org.gnome.shell enabled-extensions | tr -d "[],'")
for settings in "$backup_dir"/*.ini; do
extension=$(basename "$settings" .ini)
base_name=$(echo "$extension" | sed 's/@.*//')
if [[ $extensions == *"$extension"* ]]; then
dconf load "/org/gnome/shell/extensions/$base_name/" < "$settings"
echo "Настройки $extension востановлены"
else
echo "Расширение $extension не установлено или не включено, пропускаем"
fi
done
================================================
FILE: bin/susedko
================================================
#!/bin/bash
if nmcli -t -f TYPE,STATE device | grep -q "^ethernet:connected"; then
home_ip=$(timeout 1 getent hosts home.local | awk '{ print $1 }')
if [[ "$home_ip" == "192.168.50.125" ]]; then
source ~/Dev/environment/secrets.env
curl -s \
-H "Authorization: Bearer $HA_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"entity_id\": \"$2\"}" \
"https://home.local/api/services/$1"
echo ""
fi
fi
================================================
FILE: bin/susedko-listener
================================================
#!/bin/bash
source ~/Dev/susedko/secrets.env
MQTT_BROKER="192.168.50.125"
mosquitto_sub -h "$MQTT_BROKER" -t ai_laptop -u home -P "$HOME_PASSWORD" | while read -r payload
do
if nmcli -t -f TYPE,STATE device | grep -q "^ethernet:connected"; then
case "$payload" in
"LOCK")
loginctl lock-session
;;
"WAKE")
was_locked=$(dbus-send --session --dest=org.gnome.Shell --print-reply /org/gnome/Shell org.gnome.Shell.GetScreenShieldLock)
if echo "$lock_status" | grep -q "boolean true"; then
YDOTOOL_SOCKET=/run/.ydotool_socket ydotool key 28:1 28:0
fi
;;
*)
echo "Unknown command: $payload"
;;
esac
fi
done
================================================
FILE: bin/update
================================================
#!/bin/zsh
set -e
TITLE='\033[0;32m\033[1m'
GRAY='\033[0;90m'
NC='\033[0m'
echo -e "${TITLE}Обновление системы${NC}"
pkexec dnf update --refresh -y
echo -e "\n${TITLE}Обновление приложений из Flatpak${NC}"
flatpak update -y
echo -e "\n${TITLE}Обновление Dev Container${NC}"
cd ~/.local/lib/node
npm update
~/Dev/environment/bin/update-dockerfile
echo -e "\n${TITLE}Обновление темы Firefox${GRAY}"
cd ~/.config/mozilla/firefox/iesxdh6c.default-release/chrome/firefox-gnome-theme
git pull origin master
echo -e "\n${TITLE}Обновление расширений GNOME${GRAY}"
gdbus call --session --dest org.gnome.Shell.Extensions \
--object-path /org/gnome/Shell/Extensions \
--method org.gnome.Shell.Extensions.CheckForUpdates
echo -e "\n${TITLE}Готово${NC}"
read
================================================
FILE: bin/update-devcontainer-configs
================================================
#!/bin/bash
for dir in ~/Dev/*/; do
target_file="${dir}.devcontainer.json"
if [[ -f "$target_file" ]]; then
if grep -q "localhost/ai-opensource" "$target_file"; then
echo "Replaced in $dir"
~/Dev/environment/bin/dev --isolate
fi
fi
done
podman image rm --all --force
================================================
FILE: bin/update-dockerfile
================================================
#!/bin/zsh
DOCKERFILE_PATH="/home/ai/Dev/environment/devcontainer/Dockerfile"
latest_node=$(curl -s "https://nodejs.org/dist/index.json" | jq -r '.[0].version' | sed 's/v//')
latest_pnpm=$(curl -s "https://api.github.com/repos/pnpm/pnpm/releases/latest" | jq -r '.tag_name' | sed 's/v//')
current_node=$(grep -oP 'NODE_VERSION=\K[^ \\]+' "$DOCKERFILE_PATH")
current_pnpm=$(grep -oP 'PNPM_VERSION=\K[^ \\]+' "$DOCKERFILE_PATH")
update_needed=false
RED='\033[0;31m'
GREEN='\033[0;32m'
GRAY='\033[0;90m'
NC='\033[0m'
if [[ "$current_node" != "$latest_node" ]] && [[ -n "$latest_node" ]]; then
echo -e "Обновление Node.js: ${RED}$current_node${NC} → ${GREEN}${latest_node}${NC}"
sed -i "s/NODE_VERSION=$current_node/NODE_VERSION=$latest_node/" "$DOCKERFILE_PATH"
update_needed=true
fi
if [[ "$current_pnpm" != "$latest_pnpm" ]] && [[ -n "$latest_pnpm" ]] && [[ "$latest_pnpm" != "null" ]]; then
echo -e "Обновление pnpm: ${RED}$current_pnpm${NC} to ${GREEN}${latest_pnpm}${NC}"
sed -i "s/PNPM_VERSION=$current_pnpm/PNPM_VERSION=$latest_pnpm/" "$DOCKERFILE_PATH"
update_needed=true
fi
if [ "$update_needed" = true ]; then
echo -e "Удаляем все старые образы"
podman rmi --all --force
echo -e "Перезапускаем LanguageTool"
systemctl restart --user languagetool.service
echo -e "${NC}Создаём новый базовый образ Dev Container${GRAY}"
~/Dev/environment/bin/build-devcontainer
else
echo -e "${GRAY}Нет обновлений для Dev Container${NC}"
fi
================================================
FILE: bin/update-extension-lists
================================================
#!/usr/bin/env node
let { readFile, writeFile } = require('fs/promises')
let { join } = require('path')
let { promisify } = require('util')
let { exec } = require('child_process')
exec = promisify(exec)
function gray(str) {
return `\x1b[90m${str}\x1b[39m`
}
async function updateGnome() {
let listFile = join(__dirname, '..', 'GNOME.md')
let [gnome, docs] = await Promise.all([
exec(`gnome-extensions list`),
readFile(listFile)
])
let meta = await Promise.all(
gnome.stdout
.trim()
.split('\n')
.map(async name => exec(`LANG=en gnome-extensions show ${name}`))
)
let details = await Promise.all(
meta
.map(result => {
let uuid = result.stdout.split('\n')[0]
let enabled = result.stdout.includes('State: ACTIVE')
let name = result.stdout.match(/Name: (.*)/)[1]
let hasRepo = result.stdout.match(/URL: (.*)/)
return { uuid, name, enabled, hasRepo }
})
.filter(({ enabled, hasRepo, name }) => {
if (!hasRepo) {
console.log(gray(`Игнорируем ${name}`))
}
return hasRepo
})
.map(async ({ name, uuid }) => {
let response = await fetch(
`https://extensions.gnome.org/extension-query/?` +
`sort=relevance&` +
`page=1&` +
`shell_version=all&` +
`search=${encodeURIComponent(name)}`
)
if (!response.ok) {
process.stderr.write(`Response ${response.status} for ${name}`)
process.stderr.write(gray(`\n${await response.text()}\n`))
response = await fetch(
`https://extensions.gnome.org/extension-query/?` +
`sort=relevance&` +
`page=1&` +
`shell_version=all&` +
`search=${encodeURIComponent(name)}`)
if (!response.ok) process.exit(1)
}
let json = await response.json()
let extension = json.extensions.find(i => i.uuid === uuid)
if (!extension) {
throw new Error(`Расширение не найдено: ${name} (${uuid})`)
}
return {
name: extension.name,
url: `https://extensions.gnome.org${extension.link}`
}
})
)
let extensions = details
.map(({ name, url }) => ({ url, name: name.replace(/\[.*\]\s*/, '') }))
.sort((a, b) => a.name.localeCompare(b.name))
.map(({ name, url }) => `- [${name}](${url})`)
.join('\n')
let cleaned = docs
.toString()
.split('\n')
.filter(line => line && !line.startsWith('-'))
.join('\n')
await writeFile(listFile, cleaned + '\n\n' + extensions + '\n')
}
updateGnome()
================================================
FILE: bin/zed-isolate
================================================
#!/bin/bash
set -e
LOG_FILE="/var/run/user/1000/zed-isolate.log"
show_error_log() {
if [ -f "$LOG_FILE" ]; then
zenity --text-info \
--title="Dev Container Error" \
--font="Lilex Regular 12" \
--width=800 \
--height=600 \
--filename="$LOG_FILE" 2>/dev/null
fi
exit 1
}
trap show_error_log ERR
exec > "$LOG_FILE" 2>&1
if [ "$1" != "" ]; then
cd "$1"
fi
if [ -f .devcontainer.json ]; then
config="$(pwd)/.devcontainer.json"
fi
if [ -f .devcontainer/devcontainer.json ]; then
config="$(pwd)/.devcontainer/devcontainer.json"
fi
if [ "$config" == "" ]; then
echo "Dev Container is disabled because of lack of Dev Container config"
zed --new ./
exit 0
fi
export PATH="/home/ai/.local/lib/node/node_modules/.bin/:$PATH"
echo "Starting Dev Container"
~/Dev/environment/bin/dev --up | \
zenity --progress --text="Starting" --title="Dev Container" --pulsate --auto-close --no-cancel
container_id=$(podman ps -q --filter label=devcontainer.local_folder=$(pwd))
if [ "$container_id" == "" ]; then
echo "ERROR: Running container was not found"
show_error_log
exit 1
fi
zed --new --dev-container . --wait
~/Dev/environment/bin/dev --down
================================================
FILE: bin/zoom
================================================
#!/bin/zsh
source ~/Dev/environment/secrets.env
call_scene() {
curl -s -S -f \
-H "Authorization: Bearer $HA_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"entity_id\": \"$1\"}" \
"https://home.local/api/services/scene/turn_on" || true
}
call_scene "scene.andrey_calling"
zoom "$@"
call_scene "scene.andrey_working_night"
================================================
FILE: devcontainer/Dockerfile
================================================
FROM registry.fedoraproject.org/fedora:44
ENV NODE_VERSION=25.9.0 \
PNPM_VERSION=11.0.0 \
NODE_24=24.15.0 \
NODE_22=22.22.2 \
DIFFT_VERSION=0.68.0 \
BAT_VERSION=0.26.1 \
RG_VERSION=15.1.0 \
ATUIN_VERSION=18.16.0 \
STARSHIP_VERSION=1.25.0 \
PNPM_COMPETITION_VERSION=0.5.5
ADD https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz /node.tar.xz
ADD https://nodejs.org/dist/v${NODE_24}/node-v${NODE_24}-linux-x64.tar.gz /node24.tar.xz
ADD https://nodejs.org/dist/v${NODE_22}/node-v${NODE_22}-linux-x64.tar.gz /node22.tar.xz
ADD https://github.com/pnpm/pnpm/releases/download/v$PNPM_VERSION/pnpm-linux-x64.tar.gz /pnpm.tar.gz
ADD https://github.com/eza-community/eza/releases/latest/download/eza_x86_64-unknown-linux-musl.tar.gz /eza.tar.gz
ADD https://github.com/Wilfred/difftastic/releases/download/$DIFFT_VERSION/difft-x86_64-unknown-linux-musl.tar.gz /difft.tar.gz
ADD https://github.com/sharkdp/bat/releases/download/v$BAT_VERSION/bat-v$BAT_VERSION-x86_64-unknown-linux-musl.tar.gz /bat.tar.gz
ADD https://github.com/BurntSushi/ripgrep/releases/download/$RG_VERSION/ripgrep-$RG_VERSION-x86_64-unknown-linux-musl.tar.gz /rg.tar.gz
ADD https://github.com/atuinsh/atuin/releases/download/v$ATUIN_VERSION/atuin-x86_64-unknown-linux-musl.tar.gz /atuin.tar.gz
ADD https://github.com/starship/starship/releases/download/v$STARSHIP_VERSION/starship-x86_64-unknown-linux-musl.tar.gz /starship.tar.gz
ADD https://github.com/g-plane/pnpm-shell-completion/releases/download/v$PNPM_COMPETITION_VERSION/pnpm-shell-completion_x86_64-unknown-linux-musl.tar.gz /pnpm-completion.tar.gz
RUN dnf install -yq zsh micro git tig make awk psmisc procps-ng curl \
bind-utils iputils iproute libatomic nss dbus-libs atk at-spi2-atk cups-libs \
libdrm libXcomposite libXdamage libXrandr mesa-libgbm pango alsa-lib \
&& dnf clean all \
&& rm -rf /var/cache/dnf
RUN mkdir /usr/local/share/pnpm \
&& tar -xz -f /pnpm.tar.gz -C /usr/local/share/pnpm \
&& ln -s /usr/local/share/pnpm/pnpm /usr/local/bin/pnpm \
&& rm /pnpm.tar.gz \
\
&& tar -xz -f /node.tar.xz -C /usr/local --remove-files --strip-components=1 \
--exclude='*.md' --exclude='LICENSE' \
--exclude='share' --exclude='bin/corepack' \
&& rm /node.tar.xz \
\
&& tar -xzf /node24.tar.xz -O "node-v$NODE_24-linux-x64/bin/node" > /usr/local/bin/node24 \
&& tar -xzf /node22.tar.xz -O "node-v$NODE_22-linux-x64/bin/node" > /usr/local/bin/node22 \
&& chmod a+rx /usr/local/bin/node24 \
&& chmod a+rx /usr/local/bin/node22 \
\
&& tar -xz -f /eza.tar.gz \
&& mv eza /usr/local/bin/eza \
&& chmod +x /usr/local/bin/eza \
&& rm /eza.tar.gz \
\
&& tar -xz -f /difft.tar.gz \
&& mv difft /usr/local/bin/difft \
&& chmod +x /usr/local/bin/difft \
&& rm /difft.tar.gz \
\
&& tar -xz -f /bat.tar.gz --strip-components=1 bat-v$BAT_VERSION-x86_64-unknown-linux-musl/bat \
&& mv bat /usr/local/bin/bat \
&& chmod +x /usr/local/bin/bat \
&& rm /bat.tar.gz \
\
&& tar -xz -f /rg.tar.gz --strip-components=1 ripgrep-$RG_VERSION-x86_64-unknown-linux-musl/rg \
&& mv rg /usr/local/bin/rg \
&& chmod +x /usr/local/bin/rg \
&& rm /rg.tar.gz \
\
&& tar -xz -f /atuin.tar.gz --strip-components=1 atuin-x86_64-unknown-linux-musl/atuin \
&& mv atuin /usr/local/bin/atuin \
&& chmod +x /usr/local/bin/atuin \
&& rm /atuin.tar.gz \
\
&& tar -xz -f /starship.tar.gz \
&& mv starship /usr/local/bin/starship \
&& chmod +x /usr/local/bin/starship \
&& rm /starship.tar.gz \
\
&& mkdir -p /usr/local/lib/zsh \
&& git clone -q https://github.com/zsh-users/zsh-syntax-highlighting /usr/local/lib/zsh/zsh-syntax-highlighting \
&& git clone https://github.com/zsh-users/zsh-autosuggestions /usr/local/lib/zsh/zsh-autosuggestions \
&& git clone https://github.com/jimhester/per-directory-history /usr/local/lib/zsh/per-directory-history \
&& mkdir -p /usr/local/lib/zsh/pnpm-shell-completion \
&& tar -xz -f /pnpm-completion.tar.gz -C /usr/local/lib/zsh/pnpm-shell-completion pnpm-shell-completion pnpm-shell-completion.plugin.zsh \
&& chmod a+x /usr/local/lib/zsh/pnpm-shell-completion/pnpm-shell-completion \
&& rm /pnpm-completion.tar.gz \
\
&& useradd -s /bin/zsh ai
RUN echo '{"arrowParens":"avoid","jsxSingleQuote":false,"quoteProps":"consistent","semi":false,"singleQuote":true,"sortImports":{"groups":["side_effect","side_effect_style","style",["builtin","external","unknown"],["internal","parent","sibling","index"]],"newlinesBetween":true,"order":"asc"},"trailingComma":"none","printWidth":80}' > /.oxfmtrc.json
USER ai
RUN micro -plugin install editorconfig \
&& mkdir -p /home/ai/.local/share/pnpm/
VOLUME /home/ai/.local/share/pnpm/store
VOLUME /home/ai/.shell-history
================================================
FILE: devcontainer/devcontainer.json
================================================
{
"image": "localhost/ai-opensource:latest",
"mounts": [
{
"source": "pnpm-store",
"target": "/home/ai/.local/share/pnpm/store",
"type": "volume",
},
{
"source": "shell-history",
"target": "/home/ai/.local/share/history/",
"type": "volume",
},
],
"runArgs": ["--net=bridge"],
}
================================================
FILE: devcontainer/install-dotfiles
================================================
#!/bin/sh
MICRO_VERSION="2.0.15"
DIFFT_VERSION="0.68.0"
BAT_VERSION="0.26.1"
RG_VERSION="15.1.0"
ATUIN_VERSION="18.13.3"
STARSHIP_VERSION="1.24.2"
PNPM_COMPETITION_VERSION="0.5.5"
ARCH=$(uname -m)
echo "Detected architecture: $ARCH"
case "$ARCH" in
x86_64)
ARCH_SUFFIX="x86_64-unknown-linux-musl"
;;
aarch64)
ARCH_SUFFIX="aarch64-unknown-linux-gnu"
;;
*)
echo "Unsupported architecture: $ARCH"
exit 1
;;
esac
mkdir -p ~/.config/micro
mkdir -p ~/.config/bat
mkdir -p ~/.config/git
mkdir -p ~/.config/pnpm
cp -f ~/dotfiles/zshrc ~/.zshrc
cp -f ~/dotfiles/gitconfig ~/.config/git/config
cp -f ~/dotfiles/ripgreprc ~/.config/ripgreprc
cp -f ~/dotfiles/micro.json ~/.config/micro/settings.json
cp -f ~/dotfiles/batconfig ~/.config/bat/config
cp -f ~/dotfiles/gitignore ~/.config/git/ignore
cp -f ~/dotfiles/starship.toml ~/.config/starship.toml
cp -f ~/dotfiles/pnpm-config.yaml ~/.config/pnpm/config.yaml
sed -i '/^\s*\$username\\/d;/^\s*\$hostname\\/d' ~/.config/starship.toml
git config set core.hooksPath ".git/hooks"
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl" > ~/.ssh/known_hosts
echo "github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg=" > ~/.ssh/known_hosts
echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk=" > ~/.ssh/known_hosts
chmod 600 ~/.ssh/known_hosts
mkdir -p ~/.local/share/history/
touch ~/.local/share/history/histfile
mkdir -p ~/.local/bin
cmd_exists() {
command -v "$1" >/dev/null 2>&1
}
miss_lib() {
[ ! -d ~/.local/lib/$1 ] && [ ! -d /usr/local/lib/$1 ]
}
if ! cmd_exists micro; then
if [ "$ARCH" = "x86_64" ]; then
MICRO_ARCH="linux64-static"
else
MICRO_ARCH="linux-arm64"
fi
curl -sL https://github.com/zyedidia/micro/releases/download/v$MICRO_VERSION/micro-$MICRO_VERSION-$MICRO_ARCH.tar.gz | tar xz
mv micro-$MICRO_VERSION/micro ~/.local/bin
chmod +x ~/.local/bin/micro
rm -rf micro-$MICRO_VERSION
fi
if [ ! -d ~/.config/micro/plug/editorconfig ]; then
if cmd_exists micro; then
micro -plugin install editorconfig
elif [ -f ~/.local/bin/micro ]; then
~/.local/bin/micro -plugin install editorconfig
fi
fi
if ! cmd_exists eza; then
curl -sL https://github.com/eza-community/eza/releases/latest/download/eza_$ARCH_SUFFIX.tar.gz | tar xz
chmod +x eza
mv eza ~/.local/bin
fi
if ! cmd_exists difft; then
curl -sL https://github.com/Wilfred/difftastic/releases/download/$DIFFT_VERSION/difft-$ARCH_SUFFIX.tar.gz | tar xz
chmod +x difft
mv difft ~/.local/bin
fi
if ! cmd_exists bat; then
curl -sL https://github.com/sharkdp/bat/releases/download/v$BAT_VERSION/bat-v$BAT_VERSION-$ARCH_SUFFIX.tar.gz | tar xz --strip-components=1 bat-v$BAT_VERSION-$ARCH_SUFFIX/bat
chmod +x bat
mv bat ~/.local/bin
fi
if ! cmd_exists rg; then
curl -sL https://github.com/BurntSushi/ripgrep/releases/download/$RG_VERSION/ripgrep-$RG_VERSION-$ARCH_SUFFIX.tar.gz | tar xz --strip-components=1 ripgrep-$RG_VERSION-$ARCH_SUFFIX/rg
chmod +x rg
mv rg ~/.local/bin
fi
if ! cmd_exists atuin; then
curl -sL https://github.com/atuinsh/atuin/releases/download/v$ATUIN_VERSION/atuin-$ARCH_SUFFIX.tar.gz | tar xz --strip-components=1 atuin-$ARCH_SUFFIX/atuin
chmod +x atuin
mv atuin ~/.local/bin
fi
if [ ! -f ~/.local/bin/starship ] && [ ! -f /usr/local/bin/starship ]; then
if [ "$ARCH" = "x86_64" ]; then
MICRO_ARCH="$ARCH_SUFFIX"
else
MICRO_ARCH="aarch64-unknown-linux-musl"
fi
curl -sL https://github.com/starship/starship/releases/download/v$STARSHIP_VERSION/starship-$MICRO_ARCH.tar.gz | tar xz
chmod +x starship
mv starship ~/.local/bin
fi
mkdir -p ~/.local/lib/zsh
if cmd_exists git && cmd_exists zsh; then
if miss_lib zsh/zsh-syntax-highlighting; then
git clone -q https://github.com/zsh-users/zsh-syntax-highlighting \
~/.local/lib/zsh/zsh-syntax-highlighting
fi
if miss_lib zsh/zsh-autosuggestions; then
git clone https://github.com/zsh-users/zsh-autosuggestions \
~/.local/lib/zsh/zsh-autosuggestions
fi
if miss_lib zsh/per-directory-history; then
git clone https://github.com/jimhester/per-directory-history \
~/.local/lib/zsh/per-directory-history
fi
if miss_lib zsh/pnpm-shell-completion; then
mkdir -p ~/.local/lib/zsh/pnpm-shell-completion
curl -sSL https://github.com/g-plane/pnpm-shell-completion/releases/download/v$PNPM_COMPETITION_VERSION/pnpm-shell-completion_$ARCH_SUFFIX.tar.gz > ~/pnpm-completion.tar.gz
tar -xzf ~/pnpm-completion.tar.gz \
-C ~/.local/lib/zsh/pnpm-shell-completion \
pnpm-shell-completion pnpm-shell-completion.plugin.zsh
chmod a+x ~/.local/lib/zsh/pnpm-shell-completion/pnpm-shell-completion
rm ~/pnpm-completion.tar.gz
fi
fi
================================================
FILE: gitconfig
================================================
[user]
name = Andrey Sitnik
email = andrey@sitnik.es
signingKey = key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHfKri8pwCoINL3A88gGpZDjt3jyfxrIoYfQ8gaY3AoQ andrey@sitnik.es
[alias]
current-branch = "!git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \\(.*\\)/\\1/'"
a = "!git add . && git s"
ch = "!echo 'Stop using git checkout' && false"
c = commit -S -m
s = status --short --branch
d = diff
l = "!git pull origin $(git current-branch) --rebase"
h = "!git push origin $(git current-branch)"
lh = "!git l && git h"
r = "!git rm $(git ls-files --deleted) && git status"
hf = push --force-with-lease
sw = switch
[color]
diff = auto
status = auto
branch = auto
[branch]
autosetuprebase = always
[core]
autocrlf = input
editor = micro
[init]
defaultBranch = main
[gpg]
format = ssh
[commit]
gpgsign = true
[push]
default = current
followtags = true
[rerere]
enabled = true
[diff]
external = difft
algorithm = histogram
colorMoved = true
indentHeuristic = true
================================================
FILE: gitignore
================================================
.pnpm-*.log
.npm-release/
.zed
.eslintcache
.claude
================================================
FILE: hooks-trap/applypatch-msg
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/applypatch-msg" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/applypatch-msg
fi
fi
================================================
FILE: hooks-trap/commit-msg
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/commit-msg" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/commit-msg
fi
fi
================================================
FILE: hooks-trap/post-applypatch
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/post-applypatch" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-applypatch
fi
fi
================================================
FILE: hooks-trap/post-checkout
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/post-checkout" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-checkout
fi
fi
================================================
FILE: hooks-trap/post-commit
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/post-commit" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-commit
fi
fi
================================================
FILE: hooks-trap/post-merge
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/post-merge" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-merge
fi
fi
================================================
FILE: hooks-trap/post-rewrite
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/post-rewrite" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/post-rewrite
fi
fi
================================================
FILE: hooks-trap/pre-applypatch
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/pre-applypatch" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-applypatch
fi
fi
================================================
FILE: hooks-trap/pre-auto-gc
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/pre-auto-gc" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-auto-gc
fi
fi
================================================
FILE: hooks-trap/pre-commit
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/pre-commit" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-commit
fi
fi
================================================
FILE: hooks-trap/pre-merge-commit
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/pre-merge-commit" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-merge-commit
fi
fi
================================================
FILE: hooks-trap/pre-push
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/pre-push" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-push
fi
fi
================================================
FILE: hooks-trap/pre-rebase
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/pre-rebase" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/pre-rebase
fi
fi
================================================
FILE: hooks-trap/prepare-commit-msg
================================================
#!/bin/bash
project_hooks=$(git config get --local core.hooksPath)
if [ -n "$project_hooks" ] && [ -d "$project_hooks" ]; then
if [ -x "$project_hooks/prepare-commit-msg" ]; then
/home/ai/Dev/environment/bin/dev CI=1 $project_hooks/prepare-commit-msg
fi
fi
================================================
FILE: icons/Zoom.desktop
================================================
[Desktop Entry]
Name=Zoom
Comment=Zoom Video Conference
Exec=/home/ai/Dev/environment/bin/zoom @@u %U @@
Icon=Zoom
Terminal=false
Type=Application
Encoding=UTF-8
Categories=Network;Application;
StartupWMClass=zoom
MimeType=x-scheme-handler/zoommtg;x-scheme-handler/zoomus;x-scheme-handler/tel;x-scheme-handler/callto;x-scheme-handler/zoomphonecall;x-scheme-handler/zoomphonesms;x-scheme-handler/zoomcontactcentercall;application/x-zoom
X-KDE-Protocols=zoommtg;zoomus;tel;callto;zoomphonecall;zoomphonesms;zoomcontactcentercall;
Name[en_US]=Zoom
================================================
FILE: icons/backup.desktop
================================================
[Desktop Entry]
Type=Application
Name=Резервное копирование
Comment=Backup
Icon=/home/ai/.local/share/applications/backup.svg
Exec=flatpak run app.devsuite.Ptyxis -- /home/ai/Dev/environment/bin/backup
PrefersNonDefaultGPU=false
Hidden=false
NoDisplay=false
StartupNotify=false
Terminal=false
================================================
FILE: icons/com.mattjakeman.ExtensionManager.desktop
================================================
[Desktop Entry]
Name=Расширения
Exec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=extension-manager --file-forwarding com.mattjakeman.ExtensionManager @@u %U @@
Icon=com.mattjakeman.ExtensionManager
Terminal=false
Type=Application
Categories=GTK;Utility
OnlyShowIn=GNOME;
StartupNotify=true
MimeType=x-scheme-handler/gnome-extensions;
Comment=Управление расширениями GNOME Shell
Keywords=extension;manager;shell;менеджер;расширение;
X-Flatpak=com.mattjakeman.ExtensionManager
PrefersNonDefaultGPU=false
Hidden=false
NoDisplay=false
================================================
FILE: icons/com.nextcloud.desktopclient.nextcloud.desktop
================================================
[Desktop Entry]
Categories=Utility;X-SuSE-SyncUtility;
Type=Application
Exec=nextcloud %u
Name=Nextcloud
Comment=Настольный клиент синхронизации Nextcloud
GenericName=Folder Sync
Icon=Nextcloud
Keywords=Nextcloud;syncing;file;sharing;
X-GNOME-Autostart-Delay=3
MimeType=application/vnd.nextcloud;x-scheme-handler/nc;
SingleMainWindow=true
Actions=Quit;
Implements=org.freedesktop.CloudProviders
PrefersNonDefaultGPU=false
Hidden=false
NoDisplay=false
StartupNotify=false
Terminal=false
[org.freedesktop.CloudProviders]
BusName=com.nextcloudgmbh.Nextcloud
ObjectPath=/com/nextcloudgmbh/Nextcloud
[Desktop Action Quit]
Exec=nextcloud --quit
Name=Quit Nextcloud
Icon=nextcloud
Name[ru]=Quit Nextcloud
Name[ru_RU]=Quit Nextcloud
Name[ru_RU.UTF-8]=Quit Nextcloud
================================================
FILE: icons/hu.irl.cameractrls.desktop
================================================
[Desktop Entry]
Type=Application
Version=1.0
Name=Настройки камеры
Comment=Camera controls for Linux
Exec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=cameractrlsgtk.py hu.irl.cameractrls
Icon=hu.irl.cameractrls
Terminal=false
Categories=Settings;AudioVideo;Video;Office;Utility;GNOME;GTK;
Keywords=picture;photos;camera;webcam;
X-Flatpak=hu.irl.cameractrls
PrefersNonDefaultGPU=false
Hidden=false
NoDisplay=false
StartupNotify=false
================================================
FILE: icons/porn.desktop
================================================
[Desktop Entry]
Type=Application
Name=Эротика
Comment=Play porn movies
Icon=strawberry
Exec=/home/ai/Dev/environment/bin/porn
Actions=New;
Name[ru]=Эротика
Name[ru_RU]=Эротика
Name[ru_RU.UTF-8]=Эротика
Comment[ru]=Play porn movies
Comment[ru_RU]=Play porn movies
Comment[ru_RU.UTF-8]=Play porn movies
PrefersNonDefaultGPU=false
Hidden=false
NoDisplay=false
StartupNotify=false
Terminal=false
[Desktop Action New]
Name=Новое
Exec=/home/ai/Dev/environment/bin/porn --new
================================================
FILE: icons/private.desktop
================================================
[Desktop Entry]
Type=Application
Name=Личная папка
Comment=Decrypt safe storage
Icon=/home/ai/.local/share/applications/private.svg
Exec=/home/ai/Dev/environment/bin/private
================================================
FILE: icons/update.desktop
================================================
[Desktop Entry]
Type=Application
Name=Обновление системы
Comment=Update RPM, Flatpak, and Mozilla Theme
Icon=org.fedoraproject.AnacondaInstaller
Exec=flatpak run app.devsuite.Ptyxis -- /home/ai/Dev/environment/bin/update
================================================
FILE: icons/zed-isolate.desktop
================================================
[Desktop Entry]
Type=Application
Name=Zed Dev Container
Icon=zed
Exec=/home/ai/Dev/environment/bin/zed-isolate %U
MimeType=inode/directory;
Categories=Utility;TextEditor;Development;IDE;
================================================
FILE: micro.json
================================================
{
"colorscheme": "simple",
"mkparents": true
}
================================================
FILE: mimeapps.list
================================================
[Added Associations]
x-scheme-handler/sms=org.gnome.Shell.Extensions.GSConnect.desktop;
x-scheme-handler/tel=org.gnome.Shell.Extensions.GSConnect.desktop;
image/jpeg=org.gimp.GIMP.desktop;org.gnome.Loupe.desktop;
image/avif=org.gnome.eog.desktop;org.gimp.GIMP.desktop;org.gnome.Loupe.desktop;
image/webp=org.gnome.eog.desktop;
image/svg+xml=zed.desktop;
application/x-bittorrent=io.github.TransmissionRemoteGtk.desktop;
image/png=org.gimp.GIMP.desktop;org.gnome.Loupe.desktop;
image/heif=org.gimp.GIMP.desktop;org.gnome.Loupe.desktop;
text/vnd.trolltech.linguist=mpv.desktop;zed.desktop;
font/ttf=org.gnome.font-viewer.desktop;
x-scheme-handler/http=org.mozilla.firefox.desktop;
text/html=org.mozilla.firefox.desktop;
application/xhtml+xml=org.mozilla.firefox.desktop;
x-scheme-handler/https=org.mozilla.firefox.desktop;
audio/aac=mpv.desktop;
audio/x-aac=mpv.desktop;
audio/vnd.dolby.heaac.1=mpv.desktop;
audio/vnd.dolby.heaac.2=mpv.desktop;
audio/aiff=mpv.desktop;
audio/x-aiff=mpv.desktop;
audio/m4a=mpv.desktop;
audio/x-m4a=mpv.desktop;
audio/mp1=mpv.desktop;
audio/x-mp1=mpv.desktop;
audio/mp2=mpv.desktop;
audio/x-mp2=mpv.desktop;
audio/mp3=mpv.desktop;
audio/x-mp3=mpv.desktop;
audio/mpeg=mpv.desktop;
audio/mpeg2=mpv.desktop;
audio/mpeg3=mpv.desktop;
audio/mpegurl=mpv.desktop;
audio/x-mpegurl=mpv.desktop;
audio/mpg=mpv.desktop;
audio/x-mpg=mpv.desktop;
audio/rn-mpeg=mpv.desktop;
audio/musepack=mpv.desktop;
audio/x-musepack=mpv.desktop;
audio/ogg=mpv.desktop;
audio/scpls=mpv.desktop;
audio/x-scpls=mpv.desktop;
audio/vnd.rn-realaudio=mpv.desktop;
audio/wav=mpv.desktop;
audio/x-pn-wav=mpv.desktop;
audio/x-pn-windows-pcm=mpv.desktop;
audio/x-realaudio=mpv.desktop;
audio/x-pn-realaudio=mpv.desktop;org.gnome.Totem.desktop;
audio/x-ms-wma=mpv.desktop;
audio/x-pls=mpv.desktop;
audio/x-wav=mpv.desktop;
audio/x-ms-asf=mpv.desktop;
audio/x-matroska=mpv.desktop;
audio/webm=mpv.desktop;
audio/vorbis=mpv.desktop;
audio/x-vorbis=mpv.desktop;
audio/x-shorten=mpv.desktop;
audio/x-ape=mpv.desktop;
audio/x-wavpack=mpv.desktop;
audio/x-tta=mpv.desktop;
audio/AMR=mpv.desktop;
audio/ac3=mpv.desktop;
audio/eac3=mpv.desktop;
audio/amr-wb=mpv.desktop;
audio/flac=mpv.desktop;
audio/mp4=mpv.desktop;
audio/x-pn-au=mpv.desktop;
audio/3gpp=mpv.desktop;
audio/3gpp2=mpv.desktop;
audio/dv=mpv.desktop;
audio/opus=mpv.desktop;
audio/vnd.dts=mpv.desktop;
audio/vnd.dts.hd=mpv.desktop;
audio/x-adpcm=mpv.desktop;
audio/m3u=mpv.desktop;
audio/x-vorbis+ogg=org.gnome.Totem.desktop;
video/x-mpeg2=mpv.desktop;
video/x-mpeg3=mpv.desktop;
video/mp4v-es=mpv.desktop;
video/x-m4v=mpv.desktop;
video/divx=mpv.desktop;
video/vnd.divx=mpv.desktop;
video/msvideo=mpv.desktop;
video/ogg=mpv.desktop;
video/vnd.rn-realvideo=mpv.desktop;
video/x-ms-afs=mpv.desktop;
video/x-ms-asf=mpv.desktop;
video/x-ms-wmx=mpv.desktop;
video/x-ms-wvxvideo=mpv.desktop;
video/x-avi=mpv.desktop;
video/avi=mpv.desktop;
video/x-flic=mpv.desktop;
video/fli=mpv.desktop;
video/x-flc=mpv.desktop;
video/flv=mpv.desktop;
video/x-theora=mpv.desktop;
video/x-theora+ogg=mpv.desktop;
video/mkv=mpv.desktop;
video/x-ogm=mpv.desktop;
video/vnd.mpegurl=mpv.desktop;
video/3gp=mpv.desktop;
video/3gpp2=mpv.desktop;
video/dv=mpv.desktop;
application/xml=zed.desktop;
application/zip=org.gnome.Nautilus.desktop;
application/pdf=org.gnome.Papers.desktop;
x-scheme-handler/gnome-extensions=com.mattjakeman.ExtensionManager.desktop;
application/vnd.nextcloud=com.nextcloud.desktopclient.nextcloud.desktop;
x-scheme-handler/nc=com.nextcloud.desktopclient.nextcloud.desktop;
text/x-opml+xml=zed.desktop;
application/atom+xml=zed.desktop;
application/rss+xml=zed.desktop;
[Default Applications]
video/x-matroska=mpv.desktop
video/mp4=mpv.desktop
video/x-ms-wmv=mpv.desktop
video/x-msvideo=mpv.desktop
video/x-flv=mpv.desktop
video/mpeg=mpv.desktop
video/mp2t=mpv.desktop
video/webm=mpv.desktop
video/quicktime=mpv.desktop
application/x-bittorrent=io.github.TransmissionRemoteGtk.desktop
text/vnd.trolltech.linguist=zed.desktop
image/jpeg=org.gnome.Loupe.desktop
image/avif=org.gnome.Loupe.desktop
image/png=org.gnome.Loupe.desktop
image/heif=org.gnome.Loupe.desktop
font/ttf=org.gnome.font-viewer.desktop
video/3gpp=mpv.desktop
x-scheme-handler/http=org.mozilla.firefox.desktop
text/html=org.mozilla.firefox.desktop
application/xhtml+xml=org.mozilla.firefox.desktop
x-scheme-handler/https=org.mozilla.firefox.desktop
audio/x-vorbis+ogg=org.gnome.Totem.desktop
audio/aac=mpv.desktop
audio/x-aac=mpv.desktop
audio/vnd.dolby.heaac.1=mpv.desktop
audio/vnd.dolby.heaac.2=mpv.desktop
audio/aiff=mpv.desktop
audio/x-aiff=mpv.desktop
audio/m4a=mpv.desktop
audio/x-m4a=mpv.desktop
audio/mp1=mpv.desktop
audio/x-mp1=mpv.desktop
audio/mp2=mpv.desktop
audio/x-mp2=mpv.desktop
audio/mp3=mpv.desktop
audio/x-mp3=mpv.desktop
audio/mpeg=mpv.desktop
audio/mpeg2=mpv.desktop
audio/mpeg3=mpv.desktop
audio/mpegurl=mpv.desktop
audio/x-mpegurl=mpv.desktop
audio/mpg=mpv.desktop
audio/x-mpg=mpv.desktop
audio/rn-mpeg=mpv.desktop
audio/musepack=mpv.desktop
audio/x-musepack=mpv.desktop
audio/ogg=mpv.desktop
audio/scpls=mpv.desktop
audio/x-scpls=mpv.desktop
audio/vnd.rn-realaudio=mpv.desktop
audio/wav=mpv.desktop
audio/x-pn-wav=mpv.desktop
audio/x-pn-windows-pcm=mpv.desktop
audio/x-realaudio=mpv.desktop
audio/x-pn-realaudio=org.gnome.Totem.desktop
audio/x-ms-wma=mpv.desktop
audio/x-pls=mpv.desktop
audio/x-wav=mpv.desktop
audio/x-ms-asf=mpv.desktop
audio/x-matroska=mpv.desktop
audio/webm=mpv.desktop
audio/vorbis=mpv.desktop
audio/x-vorbis=mpv.desktop
audio/x-shorten=mpv.desktop
audio/x-ape=mpv.desktop
audio/x-wavpack=mpv.desktop
audio/x-tta=mpv.desktop
audio/AMR=mpv.desktop
audio/ac3=mpv.desktop
audio/eac3=mpv.desktop
audio/amr-wb=mpv.desktop
audio/flac=mpv.desktop
audio/mp4=mpv.desktop
audio/x-pn-au=mpv.desktop
audio/3gpp=mpv.desktop
audio/3gpp2=mpv.desktop
audio/dv=mpv.desktop
audio/opus=mpv.desktop
audio/vnd.dts=mpv.desktop
audio/vnd.dts.hd=mpv.desktop
audio/x-adpcm=mpv.desktop
audio/m3u=mpv.desktop
video/x-ogm+ogg=mpv.desktop
video/x-mpeg2=mpv.desktop
video/x-mpeg3=mpv.desktop
video/mp4v-es=mpv.desktop
video/x-m4v=mpv.desktop
video/divx=mpv.desktop
video/vnd.divx=mpv.desktop
video/msvideo=mpv.desktop
video/ogg=mpv.desktop
video/vnd.rn-realvideo=mpv.desktop
video/x-ms-afs=mpv.desktop
video/x-ms-asf=mpv.desktop
video/x-ms-wmx=mpv.desktop
video/x-ms-wvxvideo=mpv.desktop
video/x-avi=mpv.desktop
video/avi=mpv.desktop
video/x-flic=mpv.desktop
video/fli=mpv.desktop
video/x-flc=mpv.desktop
video/flv=mpv.desktop
video/x-theora=mpv.desktop
video/x-theora+ogg=mpv.desktop
video/mkv=mpv.desktop
video/x-ogm=mpv.desktop
video/vnd.mpegurl=mpv.desktop
video/3gp=mpv.desktop
video/3gpp2=mpv.desktop
video/dv=mpv.desktop
application/xml=zed.desktop
application/pdf=org.gnome.Papers.desktop
text/x-opml+xml=zed.desktop
application/atom+xml=zed.desktop
application/rss+xml=zed.desktop
================================================
FILE: mpv-input.conf
================================================
й quit
а cycle fullscreen
MOUSE_BTN3 ignore
MOUSE_BTN4 ignore
================================================
FILE: mpv.conf
================================================
slang=ru
alang=jpn,ja,eng,en
================================================
FILE: pnpm-config.yaml
================================================
blockExoticSubdeps: true
minimumReleaseAge: 1440
storeDir: ~/.local/share/pnpm/store
trustPolicy: true
trustPolicyIgnoreAfter: true
================================================
FILE: ripgreprc
================================================
--smart-case
--glob=!.git/
--glob=!.yarn/
--hidden
--no-heading
================================================
FILE: sshconfig
================================================
Host *
ForwardAgent no
Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_ed25519
Host susedko.local
HostName susedko.local
User ai
IdentityFile ~/.ssh/id_ed25519
Host 127.0.0.1
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
Host *
AddKeysToAgent yes
IdentityFile ~/.ssh/id_ed25519
IdentityFile ~/.ssh/id_ed25519_ru
GSSAPIAuthentication no
TCPKeepAlive yes
ServerAliveInterval 3
================================================
FILE: starship.toml
================================================
format = """
$username\
$hostname\
$container\
$shlvl\
$directory\
$git_branch\
$git_commit\
$git_state\
$git_metrics\
$git_status\
$sudo\
$cmd_duration\
$line_break\
$jobs\
$status\
$shell\
$character"""
[container]
format = '[$symbol]($style) '
================================================
FILE: zed-keys.json
================================================
[
{
"bindings": {
"ctrl-q": null
}
},
{
"context": "Terminal",
"bindings": {
"ctrl-s": ["terminal::SendKeystroke", "ctrl-s"],
"ctrl-c": "terminal::Copy",
"ctrl-v": "terminal::Paste"
}
}
]
================================================
FILE: zed.json
================================================
{
"outline_panel": {
"dock": "left"
},
"collaboration_panel": {
"dock": "left"
},
"git_panel": {
"dock": "left"
},
"project_panel": {
"dock": "left"
},
"diff_view_style": "unified",
"agent_servers": {
"claude-acp": {
"default_config_options": {
"mode": "bypassPermissions"
},
"type": "registry"
}
},
"colorize_brackets": true,
"indent_guides": {
"coloring": "indent_aware",
"background_coloring": "disabled"
},
"prettier": {
"allowed": true
},
"use_podman": true,
"show_completions_on_input": true,
"buffer_font_family": "Lilex",
"agent": {
"dock": "right",
"tool_permissions": {
"default": "allow"
},
"default_profile": "write",
"notify_when_agent_waiting": "primary_screen",
"play_sound_when_agent_done": "always",
"model_parameters": [],
"default_model": {
"effort": "high",
"enable_thinking": true,
"provider": "zed.dev",
"model": "claude-sonnet-4-6"
}
},
"edit_predictions": {
"provider": "zed",
"mode": "subtle",
"copilot": {
"proxy": null,
"proxy_no_verify": null
}
},
"icon_theme": "Material Icon Theme",
"terminal": {
"dock": "right"
},
"soft_wrap": "preferred_line_length",
"preferred_line_length": 80,
"wrap_guides": [80],
"ui_font_size": 16,
"buffer_font_size": 16,
"theme": {
"mode": "system",
"light": "Adwaita Pastel Light",
"dark": "Adwaita Pastel Dark"
},
"git": {
"inline_blame": {
"enabled": false
}
},
"file_types": {
"XML": ["svg"],
"YAML": ["**/*.bu"],
"JSON": ["**/*.webmanifest"]
},
"lsp": {
"oxfmt": {
"initialization_options": {
"settings": {
"fmt.configPath": null
}
}
},
"oxlint": {
"initialization_options": {
"settings": {
"configPath": null,
"fixKind": "safe_fix",
"run": "onType",
"unusedDisableDirectives": "deny"
}
}
}
},
"languages": {
"JavaScript": {
"format_on_save": "on",
"prettier": {
"allowed": false
},
"language_servers": ["!eslint", "!tailwindcss-language-server", "..."],
"formatter": [
{
"language_server": {
"name": "oxfmt"
}
}
]
},
"Svelte": {
"code_actions_on_format": {
"source.fixAll.eslint": true
},
"language_servers": ["!tailwindcss-language-server", "..."]
},
"TypeScript": {
"format_on_save": "on",
"prettier": {
"allowed": false
},
"language_servers": ["!eslint", "!tailwindcss-language-server", "..."],
"formatter": [
{
"language_server": {
"name": "oxfmt"
}
}
]
},
"HTML": {
"format_on_save": "on",
"prettier": {
"allowed": false
},
"language_servers": ["!tailwindcss-language-server", "..."],
"formatter": [
{
"language_server": {
"name": "oxfmt"
}
}
]
},
"CSS": {
"format_on_save": "on",
"prettier": {
"allowed": false
},
"formatter": [
{
"language_server": {
"name": "oxfmt"
}
}
]
},
"JSON": {
"format_on_save": "on",
"prettier": {
"allowed": false
},
"formatter": [
{
"language_server": {
"name": "oxfmt"
}
}
]
},
"JSONC": {
"format_on_save": "on",
"prettier": {
"allowed": false
},
"formatter": [
{
"language_server": {
"name": "oxfmt"
}
}
]
},
"YAML": {
"format_on_save": "on",
"prettier": {
"allowed": false
},
"formatter": [
{
"language_server": {
"name": "oxfmt"
}
}
]
},
"Markdown": {
"format_on_save": "on",
"prettier": {
"allowed": false
},
"formatter": [
{
"language_server": {
"name": "oxfmt"
}
}
]
}
}
}
================================================
FILE: zshrc
================================================
# History
HISTSIZE=10000
SAVEHIST=10000
HISTFILE=~/.local/share/history/histfile
setopt appendhistory
setopt inc_append_history
setopt hist_ignore_all_dups
# Colors
autoload -U colors && colors
# Key bindings
bindkey -e
bindkey ';5D' backward-word # Ctrl+Left
bindkey ';5C' forward-word # Ctrl+Right
stty intr ^X # Replace Ctrl+C to Ctrl+X
stty susp undef # Disable Ctrl + Z
# Force keeping home folder clean
export XDG_CACHE_HOME="$HOME/.cache"
export XDG_CONFIG_HOME="$HOME/.config"
export XDG_DATA_HOME="$HOME/.local/share"
export GNUPGHOME="$XDG_DATA_HOME/gnupg"
export NODE_COMPILE_CACHE="$XDG_CACHE_HOME/node"
export NPM_CONFIG_USERCONFIG="$XDG_CONFIG_HOME/npmrc"
export RIPGREP_CONFIG_PATH="$XDG_CONFIG_HOME/ripgreprc"
export CLAUDE_CONFIG_DIR="$XDG_DATA_HOME/claude"
# Completion
zstyle :compinstall filename "$HOME/.zshrc"
autoload -Uz compinit
compinit -i -d "$XDG_CACHE_HOME/zcompcache"
# Zsh plugins
export HISTORY_BASE="$XDG_CACHE_HOME/zsh_directory_history"
for plugin in \
zsh-syntax-highlighting/zsh-syntax-highlighting.zsh \
zsh-autosuggestions/zsh-autosuggestions.zsh \
per-directory-history/per-directory-history.zsh \
pnpm-shell-completion/pnpm-shell-completion.plugin.zsh
do
for dir in ~/.local/lib/zsh /usr/local/lib/zsh; do
if [[ -f $dir/$plugin ]]; then
source $dir/$plugin
break
fi
done
done
# Local binaries
export PATH="$HOME/.local/bin:$PATH"
# Prompt
if command -v starship > /dev/null 2>&1; then
eval "$(starship init zsh)"
elif [ -f ~/.local/bin/starship ]; then
eval "$(~/.local/bin/starship init zsh)"
fi
# History
if [ -f ~/.local/bin/atuin ]; then
eval "$(~/.local/bin/atuin init zsh --disable-up-arrow)"
fi
# Rip Grep
# Console editor
export EDITOR=micro
# Fix Bat in light console
export BAT_THEME=ansi
# Release function
release() {
local VERSION=$(grep -oP '(?<="version": ")[^"]*' package.json)
if [ -z "$VERSION" ]; then
echo "Version not found in package.json"
return 1
fi
git add .
git commit -m "Release $VERSION version"
git tag -s "$VERSION" -m "$VERSION"
git push
}
# Aliases
alias g='git'
alias ..='cd ..'
alias l='ls --all'
alias ll='ls --long --all --git'
if command -v bat > /dev/null 2>&1; then
alias cat='bat'
fi
if command -v eza > /dev/null 2>&1; then
alias ls='eza'
fi
alias r='dev node --run'
alias t='dev node --run test'
alias pm='dev pnpm'
alias pnx='dev pnpm dlx'
alias pui='pnpm update --interactive --latest -r --include-workspace-root'
alias pu='pnpm update -r --include-workspace-root'
alias pui1='pnpm update --interactive --latest'
alias pu1='pnpm update'
if [ -n "$container" ]; then
if [ -d "$HOME/.local/share/pnpm" ]; then
export PNPM_HOME="$HOME/.local/share/pnpm"
export PATH="$PNPM_HOME/bin/:$PATH"
fi
alias dev='command'
if [ -z "$SSH_AUTH_SOCK" ] && [ -S "/run/user/1000/gcr/ssh" ]; then
export SSH_AUTH_SOCK="/run/user/1000/gcr/ssh"
fi
else
export PATH="/home/ai/.local/lib/node/node_modules/.bin/:$PATH"
alias dev='/home/ai/Dev/environment/bin/dev'
alias devup='dev --up'
alias devdown='dev --down'
alias pnpm='dev pnpm'
alias node='dev node'
alias multiocular='dev --port pnpm multiocular'
# Run git hooks inside Dev Container
export GIT_CONFIG_PARAMETERS="'core.hooksPath=/home/ai/Dev/environment/hooks-trap'"
# Fast way to Dev projects
if [ -d ~/Dev ]; then
cdpath=(. ~/Dev)
fi
# Zed
alias e='~/Dev/environment/bin/zed-isolate .'
# Development
alias p='dev pnpm clean-publish --temp-dir .npm-release --without-publish \
&& cd .npm-release \
&& npm publish --access public \
&& cd .. \
&& rm -R .npm-release'
fi
gitextract_8apgxoyr/ ├── .editorconfig ├── .gitignore ├── .oxfmtrc.json ├── GNOME.md ├── Install.md ├── LICENSE ├── README.md ├── batconfig ├── bin/ │ ├── backup │ ├── backup-gnome-extensions │ ├── build-devcontainer │ ├── clear │ ├── clear-weather-city │ ├── copy-env │ ├── dev │ ├── force-lock │ ├── porn │ ├── private │ ├── restore-gnome-extensions │ ├── susedko │ ├── susedko-listener │ ├── update │ ├── update-devcontainer-configs │ ├── update-dockerfile │ ├── update-extension-lists │ ├── zed-isolate │ └── zoom ├── devcontainer/ │ ├── Dockerfile │ ├── devcontainer.json │ └── install-dotfiles ├── gitconfig ├── gitignore ├── hooks-trap/ │ ├── applypatch-msg │ ├── commit-msg │ ├── post-applypatch │ ├── post-checkout │ ├── post-commit │ ├── post-merge │ ├── post-rewrite │ ├── pre-applypatch │ ├── pre-auto-gc │ ├── pre-commit │ ├── pre-merge-commit │ ├── pre-push │ ├── pre-rebase │ └── prepare-commit-msg ├── icons/ │ ├── Zoom.desktop │ ├── backup.desktop │ ├── com.mattjakeman.ExtensionManager.desktop │ ├── com.nextcloud.desktopclient.nextcloud.desktop │ ├── hu.irl.cameractrls.desktop │ ├── porn.desktop │ ├── private.desktop │ ├── update.desktop │ └── zed-isolate.desktop ├── micro.json ├── mimeapps.list ├── mpv-input.conf ├── mpv.conf ├── pnpm-config.yaml ├── ripgreprc ├── sshconfig ├── starship.toml ├── zed-keys.json ├── zed.json └── zshrc
Condensed preview — 66 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (88K chars).
[
{
"path": ".editorconfig",
"chars": 177,
"preview": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ni"
},
{
"path": ".gitignore",
"chars": 12,
"preview": "secrets.env\n"
},
{
"path": ".oxfmtrc.json",
"chars": 422,
"preview": "{\n \"arrowParens\": \"avoid\",\n \"jsxSingleQuote\": false,\n \"quoteProps\": \"consistent\",\n \"semi\": false,\n \"singleQuote\": t"
},
{
"path": "GNOME.md",
"chars": 2876,
"preview": "## GNOME Shell Extensions\n\n- [All-in-One Clipboard](https://extensions.gnome.org/extension/8671/all-in-one-clipboard/)\n-"
},
{
"path": "Install.md",
"chars": 16559,
"preview": "## How I install my system\n\n### Preparing\n\nDownload [Fedora image](https://getfedora.org/ru/workstation/)\nand write it t"
},
{
"path": "LICENSE",
"chars": 1095,
"preview": "The MIT License (MIT)\n\nCopyright 2013 Andrey Sitnik <andrey@sitnik.es>\n\nPermission is hereby granted, free of charge, to"
},
{
"path": "README.md",
"chars": 222,
"preview": "My home configs, scripts and [installation process](./Install.md).\n\nSee also [my keyboard layout](https://github.com/ai/"
},
{
"path": "batconfig",
"chars": 8,
"preview": "--plain\n"
},
{
"path": "bin/backup",
"chars": 3912,
"preview": "#!/bin/sh\n\nTITLE='\\033[0;32m\\033[1m'\nGRAY='\\033[0;90m'\nNC='\\033[0m'\n\nhour=$(date +\"%H\")\nif [[ hour -lt 9 || hour -ge 22 "
},
{
"path": "bin/backup-gnome-extensions",
"chars": 514,
"preview": "#!/bin/bash\n\nbackup_dir=\"$HOME/.local/share/gnome-shell-extensions-settings\"\nrm -r \"$backup_dir\"\nmkdir -p \"$backup_dir\"\n"
},
{
"path": "bin/build-devcontainer",
"chars": 170,
"preview": "#!/bin/bash\n\n~/Dev/environment/bin/copy-env\n\npodman build -t localhost/ai-opensource \\\n -f /home/ai/Dev/environment/dev"
},
{
"path": "bin/clear",
"chars": 235,
"preview": "#!/bin/sh\n\necho \"Было $(df -h / | tail -1 | awk '{print $4}')\"\necho\n\npodman rmi --all --force\npnpm store prune\nyarn cach"
},
{
"path": "bin/clear-weather-city",
"chars": 55,
"preview": "#!/bin/sh\n\ngsettings reset org.gnome.Weather locations\n"
},
{
"path": "bin/copy-env",
"chars": 2187,
"preview": "#!/bin/sh\n# Copy config and scripts to or from repo\n\nif [ \"$1\" == \"system\" ]; then\n rm ~/.local/share/applications/*.{d"
},
{
"path": "bin/dev",
"chars": 5307,
"preview": "#!/bin/bash\n\nset -e\n\nfunction get_container_runtime() {\n if command -v podman &> /dev/null; then\n echo \"podman\"\n el"
},
{
"path": "bin/force-lock",
"chars": 1520,
"preview": "#!/bin/bash\nIDLE_TIME=240000\nLANG=en\n\nlog() { echo \"$(date '+%H:%M:%S') $*\"; }\n\nwhile true; do\n CURRENT_IDLE=$(gdbus ca"
},
{
"path": "bin/porn",
"chars": 527,
"preview": "#!/bin/sh\n# Run movies from specific category\n\nif [[ \"$1\" == \"--new\" ]]; then\n mkdir -p ~/.susedko_new\n sshfs ai@sused"
},
{
"path": "bin/private",
"chars": 271,
"preview": "#!/bin/sh\n# Private encrypted folder\n\nSTORE=$HOME/Документы/.Private\nLINK=$HOME/Private\n\nif [ -e \"$LINK\" ]; then\n # Loc"
},
{
"path": "bin/restore-gnome-extensions",
"chars": 648,
"preview": "#!/bin/bash\n\nbackup_dir=\"$HOME/.local/share/gnome-shell-extensions-settings\"\n\nif [ ! -d \"$backup_dir\" ]; then\n echo \"Se"
},
{
"path": "bin/susedko",
"chars": 444,
"preview": "#!/bin/bash\n\nif nmcli -t -f TYPE,STATE device | grep -q \"^ethernet:connected\"; then\n home_ip=$(timeout 1 getent hosts h"
},
{
"path": "bin/susedko-listener",
"chars": 705,
"preview": "#!/bin/bash\n\nsource ~/Dev/susedko/secrets.env\nMQTT_BROKER=\"192.168.50.125\"\n\nmosquitto_sub -h \"$MQTT_BROKER\" -t ai_laptop"
},
{
"path": "bin/update",
"chars": 764,
"preview": "#!/bin/zsh\n\nset -e\n\nTITLE='\\033[0;32m\\033[1m'\nGRAY='\\033[0;90m'\nNC='\\033[0m'\n\necho -e \"${TITLE}Обновление системы${NC}\"\n"
},
{
"path": "bin/update-devcontainer-configs",
"chars": 294,
"preview": "#!/bin/bash\n\nfor dir in ~/Dev/*/; do\n target_file=\"${dir}.devcontainer.json\"\n if [[ -f \"$target_file\" ]]; then\n if "
},
{
"path": "bin/update-dockerfile",
"chars": 1463,
"preview": "#!/bin/zsh\n\nDOCKERFILE_PATH=\"/home/ai/Dev/environment/devcontainer/Dockerfile\"\n\nlatest_node=$(curl -s \"https://nodejs.or"
},
{
"path": "bin/update-extension-lists",
"chars": 2648,
"preview": "#!/usr/bin/env node\n\nlet { readFile, writeFile } = require('fs/promises')\nlet { join } = require('path')\nlet { promisify"
},
{
"path": "bin/zed-isolate",
"chars": 1207,
"preview": "#!/bin/bash\n\nset -e\n\nLOG_FILE=\"/var/run/user/1000/zed-isolate.log\"\n\nshow_error_log() {\n if [ -f \"$LOG_FILE\" ]; then\n "
},
{
"path": "bin/zoom",
"chars": 352,
"preview": "#!/bin/zsh\n\nsource ~/Dev/environment/secrets.env\n\ncall_scene() {\n curl -s -S -f \\\n -H \"Authorization: Bearer $HA_TOK"
},
{
"path": "devcontainer/Dockerfile",
"chars": 4742,
"preview": "FROM registry.fedoraproject.org/fedora:44\n\nENV NODE_VERSION=25.9.0 \\\n PNPM_VERSION=11.0.0 \\\n NODE_24=24.15.0 \\\n NODE_"
},
{
"path": "devcontainer/devcontainer.json",
"chars": 338,
"preview": "{\n \"image\": \"localhost/ai-opensource:latest\",\n \"mounts\": [\n {\n \"source\": \"pnpm-store\",\n \"target\": \"/home/"
},
{
"path": "devcontainer/install-dotfiles",
"chars": 5403,
"preview": "#!/bin/sh\n\nMICRO_VERSION=\"2.0.15\"\nDIFFT_VERSION=\"0.68.0\"\nBAT_VERSION=\"0.26.1\"\nRG_VERSION=\"15.1.0\"\nATUIN_VERSION=\"18.13.3"
},
{
"path": "gitconfig",
"chars": 1027,
"preview": "[user]\n name = Andrey Sitnik\n email = andrey@sitnik.es\n signingKey = key::ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHfKri"
},
{
"path": "gitignore",
"chars": 52,
"preview": ".pnpm-*.log\n.npm-release/\n.zed\n.eslintcache\n.claude\n"
},
{
"path": "hooks-trap/applypatch-msg",
"chars": 258,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/commit-msg",
"chars": 250,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/post-applypatch",
"chars": 260,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/post-checkout",
"chars": 256,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/post-commit",
"chars": 252,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/post-merge",
"chars": 250,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/post-rewrite",
"chars": 254,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/pre-applypatch",
"chars": 258,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/pre-auto-gc",
"chars": 252,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/pre-commit",
"chars": 250,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/pre-merge-commit",
"chars": 262,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/pre-push",
"chars": 246,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/pre-rebase",
"chars": 250,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "hooks-trap/prepare-commit-msg",
"chars": 266,
"preview": "#!/bin/bash\n\nproject_hooks=$(git config get --local core.hooksPath)\nif [ -n \"$project_hooks\" ] && [ -d \"$project_hooks\" "
},
{
"path": "icons/Zoom.desktop",
"chars": 545,
"preview": "[Desktop Entry]\nName=Zoom\nComment=Zoom Video Conference\nExec=/home/ai/Dev/environment/bin/zoom @@u %U @@\nIcon=Zoom\nTermi"
},
{
"path": "icons/backup.desktop",
"chars": 293,
"preview": "[Desktop Entry]\nType=Application\nName=Резервное копирование\nComment=Backup\nIcon=/home/ai/.local/share/applications/backu"
},
{
"path": "icons/com.mattjakeman.ExtensionManager.desktop",
"chars": 548,
"preview": "[Desktop Entry]\nName=Расширения\nExec=/usr/bin/flatpak run --branch=stable --arch=x86_64 --command=extension-manager --fi"
},
{
"path": "icons/com.nextcloud.desktopclient.nextcloud.desktop",
"chars": 760,
"preview": "[Desktop Entry]\nCategories=Utility;X-SuSE-SyncUtility;\nType=Application\nExec=nextcloud %u\nName=Nextcloud\nComment=Настоль"
},
{
"path": "icons/hu.irl.cameractrls.desktop",
"chars": 450,
"preview": "[Desktop Entry]\nType=Application\nVersion=1.0\nName=Настройки камеры\nComment=Camera controls for Linux\nExec=/usr/bin/flatp"
},
{
"path": "icons/porn.desktop",
"chars": 470,
"preview": "[Desktop Entry]\nType=Application\nName=Эротика\nComment=Play porn movies\nIcon=strawberry\nExec=/home/ai/Dev/environment/bin"
},
{
"path": "icons/private.desktop",
"chars": 174,
"preview": "[Desktop Entry]\nType=Application\nName=Личная папка\nComment=Decrypt safe storage\nIcon=/home/ai/.local/share/applications/"
},
{
"path": "icons/update.desktop",
"chars": 221,
"preview": "[Desktop Entry]\nType=Application\nName=Обновление системы\nComment=Update RPM, Flatpak, and Mozilla Theme\nIcon=org.fedorap"
},
{
"path": "icons/zed-isolate.desktop",
"chars": 187,
"preview": "[Desktop Entry]\nType=Application\nName=Zed Dev Container\nIcon=zed\nExec=/home/ai/Dev/environment/bin/zed-isolate %U\nMimeTy"
},
{
"path": "micro.json",
"chars": 55,
"preview": "{\n \"colorscheme\": \"simple\",\n \"mkparents\": true\n}\n"
},
{
"path": "mimeapps.list",
"chars": 6818,
"preview": "[Added Associations]\nx-scheme-handler/sms=org.gnome.Shell.Extensions.GSConnect.desktop;\nx-scheme-handler/tel=org.gnome.S"
},
{
"path": "mpv-input.conf",
"chars": 62,
"preview": "й quit\nа cycle fullscreen\nMOUSE_BTN3 ignore\nMOUSE_BTN4 ignore\n"
},
{
"path": "mpv.conf",
"chars": 29,
"preview": "slang=ru\nalang=jpn,ja,eng,en\n"
},
{
"path": "pnpm-config.yaml",
"chars": 132,
"preview": "blockExoticSubdeps: true\nminimumReleaseAge: 1440\nstoreDir: ~/.local/share/pnpm/store\ntrustPolicy: true\ntrustPolicyIgnore"
},
{
"path": "ripgreprc",
"chars": 64,
"preview": "--smart-case\n--glob=!.git/\n--glob=!.yarn/\n--hidden\n--no-heading\n"
},
{
"path": "sshconfig",
"chars": 450,
"preview": "Host *\n ForwardAgent no\n\nHost github.com\n HostName github.com\n User git\n IdentityFile ~/.ssh/id_ed25519\n\nHos"
},
{
"path": "starship.toml",
"chars": 248,
"preview": "format = \"\"\"\n$username\\\n$hostname\\\n$container\\\n$shlvl\\\n$directory\\\n$git_branch\\\n$git_commit\\\n$git_state\\\n$git_metrics\\\n$"
},
{
"path": "zed-keys.json",
"chars": 240,
"preview": "[\n {\n \"bindings\": {\n \"ctrl-q\": null\n }\n },\n {\n \"context\": \"Terminal\",\n \"bindings\": {\n \"ctrl-s\":"
},
{
"path": "zed.json",
"chars": 4284,
"preview": "{\n \"outline_panel\": {\n \"dock\": \"left\"\n },\n \"collaboration_panel\": {\n \"dock\": \"left\"\n },\n \"git_panel\": {\n \""
},
{
"path": "zshrc",
"chars": 3683,
"preview": "# History\nHISTSIZE=10000\nSAVEHIST=10000\nHISTFILE=~/.local/share/history/histfile\nsetopt appendhistory\nsetopt inc_append_"
}
]
About this extraction
This page contains the full source code of the ai/environment GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 66 files (77.6 KB), approximately 25.0k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.