Compare commits

..

74 Commits

Author SHA1 Message Date
thomas 85632c2e29 hook notifs 2026-03-31 12:30:12 +01:00
thomas 63caa82199 compat with claude skills + hooks support 2026-03-31 12:07:17 +01:00
thomas 39e7bddb35 update pi 2026-03-27 14:22:06 +00:00
thomas d5b4042b06 add gsf 2026-03-25 19:12:49 +00:00
thomas 4d19e7d320 fix nvim 2026-03-25 13:41:16 +00:00
thomas 227c1638f6 linear skill 2026-03-19 16:37:27 +00:00
thomas db41ec6e93 pi settings 2026-03-19 15:20:50 +00:00
thomas c44420ce7c osc52 or whatever for ssh clipboard 2026-03-19 15:20:27 +00:00
thomas f74242ed02 jj rules 2026-03-19 15:20:15 +00:00
thomas 335b12b0e4 small changes 2026-03-16 12:13:41 +00:00
Thomas G. Lopes 2e820d38e1 fix 2026-03-13 18:12:32 +00:00
thomas 008dac69f5 fix mac 2026-03-13 18:12:10 +00:00
thomas d0b1d3be4a sync mac scripts 2026-03-13 18:04:32 +00:00
Thomas G. Lopes c0bbff81a3 jj 2026-03-13 13:41:20 +00:00
thomas 58dd9d8c2b derive codex window labels from api 2026-03-13 13:40:19 +00:00
Thomas G. Lopes 3d314d944b add attio frontend rules skill 2026-03-13 13:29:03 +00:00
thomas 24bad1f5c4 i be working 2026-03-13 12:21:18 +00:00
thomas 442284c92f add mcporter mcp config steps 2026-03-13 11:01:35 +00:00
thomas 1da5caec0a finishing touches 2026-03-12 22:09:14 +00:00
Thomas G. Lopes b8b48747b1 fix config files 2026-03-12 21:43:43 +00:00
Thomas G. Lopes ae0920a4c1 zellij abbreviation 2026-03-12 21:41:29 +00:00
thomas 2bac33b2b6 tune sub bar behavior 2026-03-12 15:13:16 +00:00
thomas 0f99afae67 codex rules 2026-03-12 15:01:19 +00:00
thomas 32752b42e0 fuck sub bar 2026-03-12 14:18:06 +00:00
thomas 7a9e2b94ff add sub-bar usage widget extension with opencode-go support 2026-03-12 14:01:51 +00:00
thomas 9ad10a016c switch default pi model to claude-opus-4-6 2026-03-12 12:30:05 +00:00
thomas ec88e63a07 ignore auth.json in sigil 2026-03-12 12:30:01 +00:00
thomas ed70a369e5 allow rm rf 2026-03-12 12:13:39 +00:00
thomas 67b3c5b504 add slowtool extension to monitor hanging commands 2026-03-12 12:02:13 +00:00
thomas 832e580eea increase pi pane size to 40% in dev layout 2026-03-12 12:02:09 +00:00
thomas e47f7a8058 switch default pi model to minimax-m2.5 2026-03-12 12:02:05 +00:00
thomas 8923ea0772 lower peon volume and disable error sounds 2026-03-12 12:02:01 +00:00
thomas cbe446e0a1 add dotfiles and nixos zellij layouts with stacked panes 2026-03-12 10:56:34 +00:00
thomas ea32a1ce37 compact zellij 2026-03-12 09:58:17 +00:00
Thomas G. Lopes 97c5f6b0d5 change vol 2026-03-11 23:48:07 +00:00
Thomas G. Lopes 096ee38100 fix peon 2026-03-11 23:47:57 +00:00
thomas 4270fe4456 minor changes 2026-03-11 23:45:15 +00:00
thomas 6795d65696 re-add cargo sourcing to fish with existence check 2026-03-11 23:44:48 +00:00
thomas d0b8a708d5 zellij rules 2026-03-11 23:30:46 +00:00
Thomas G. Lopes 7aaa1941ca fix fish nerd fonts 2026-03-11 19:32:16 +00:00
thomas 4b918b31db add tmux plugins and settings 2026-03-11 19:32:07 +00:00
thomas 108d9a5d26 fix tmux keybindings and colors 2026-03-11 19:31:32 +00:00
thomas 432a285fc3 fix PATH for tmux reload on mac sync 2026-03-11 19:20:16 +00:00
thomas 66049e3a3b tmux keybindings and theme colors 2026-03-11 19:14:31 +00:00
thomas f67ce8545c better tmux support 2026-03-11 19:05:12 +00:00
thomas 7b5f5cf0c7 add tmux 2026-03-11 18:27:03 +00:00
thomas 3c3d24ccdb add figma-tools skill 2026-03-11 16:30:01 +00:00
Thomas G. Lopes 76e9ba7a6b mac/linux differentiation 2026-03-11 12:11:13 +00:00
thomas d73e27597f fix it 2026-03-11 11:44:34 +00:00
thomas d5cbc3fad4 merge origin/nixos 2026-03-11 11:08:43 +00:00
thomas c2260a7ca9 add gitconfig 2026-03-11 11:02:23 +00:00
thomas 0aac542a0b move to linux 2026-03-11 11:00:47 +00:00
thomas e111747833 gustave wip 2026-03-11 11:00:37 +00:00
Thomas G. Lopes 45bb58848a web animation skill 2026-03-11 10:54:48 +00:00
thomas 1a5f4e51e1 update agents.md with per-OS variants docs and sync note 2026-03-11 10:06:27 +00:00
Thomas G. Lopes 74d21792b5 fix snacks picker for git changed files 2026-03-11 09:58:17 +00:00
thomas e20775f834 improve peon commands 2026-03-11 00:52:18 +00:00
thomas 2718506ced fuck dirty repo guard 2026-03-10 19:35:09 +00:00
thomas e0cfb204bb mpv 2026-03-10 19:33:29 +00:00
thomas d389bf9276 edit session 2026-03-10 18:19:31 +00:00
thomas 0001a15dde jsonl 2026-03-10 18:19:15 +00:00
thomas 6557e894f6 glados 2026-03-10 16:24:37 +00:00
thomas 597b3edcff ssh audio forwarding from mac to linux 2026-03-10 16:10:58 +00:00
thomas c76a74ca6f peon is done 2026-03-10 15:49:04 +00:00
thomas 68a7753500 openpeon dir 2026-03-10 11:47:53 +00:00
thomas 0efe69f5e9 fix handy window rule 2026-03-10 10:31:38 +00:00
thomas 8f5c4af4ec browser tools are even better now 2026-03-09 16:37:22 +00:00
thomas b559194892 change session naming threshold 2026-03-09 16:28:56 +00:00
thomas d03db1a1b6 fix handy positioning 2026-03-09 16:28:46 +00:00
thomas d92c98796a small changes 2026-03-09 15:52:00 +00:00
thomas 90b907eb3d nixd and remove ripple 2026-03-09 14:27:38 +00:00
thomas 379a2a5774 better mac ssh 2026-03-09 11:41:02 +00:00
thomas 90641498e7 small settings 2026-03-09 10:57:52 +00:00
thomas 396882d364 bunch of nixos updates 2026-03-09 02:50:31 +00:00
194 changed files with 8853 additions and 921 deletions
+38 -2
View File
@@ -1,3 +1,11 @@
# Agent Instructions
## Screenshots
When the user provides a screenshot path (e.g., `/tmp/pi-clipboard-xxx.png`), **ALWAYS** use the `read` tool to read the image file. Do NOT assume you can see the screenshot contents without reading it first.
---
# Sigil usage (for agents)
This repo is managed by **Sigil**, a minimal symlink-based dotfile tool.
@@ -8,12 +16,30 @@ This repo is managed by **Sigil**, a minimal symlink-based dotfile tool.
~/.dotfiles/
<package>/
config.lua
files/
...
files/ # common files (all OSes)
files.linux/ # Linux-specific overrides
files.macos/ # macOS-specific overrides
files.windows/ # Windows-specific overrides
```
Each package has a `config.lua` that defines its target path per OS.
### Per-OS file variants
Create `files.<os>/` directories alongside `files/` for OS-specific overlays:
```
pi-agent/
files/
settings.json # shared config
files.linux/
agent.json # Linux-specific
files.macos/
agent.json # macOS-specific
```
On Linux, `agent.json` links to `files.linux/agent.json`. On macOS, it links to `files.macos/agent.json`. Files in `files/` are applied first, then OS-specific variants overlay on top.
## Common commands
- `sigil apply` — apply symlinks (prompts for stale links)
@@ -50,6 +76,16 @@ sigil unlink ~/.config/wezterm/wezterm.lua
When editing dotfiles, it is preferred to add/edit the files in this project directly, instead of going to the source. this way we can then use sigil apply --prune, and everything will be synced, even when there are new files.
**Important:** Whenever you add new files to the repo (e.g., create new scripts or configs), you must run `sigil apply` afterwards to create the symlinks. New files in `files/` directories are not automatically linked until `sigil apply` is run.
## IMPORTANT: Update AGENTS.md files when Sigil changes
Whenever Sigil is modified (new features, behavior changes, new commands), you MUST update the AGENTS.md documentation in BOTH locations:
1. Sigil repo: `/home/thomasgl/programming/sigil/AGENTS.md`
2. This dotfiles repo: `/home/thomasgl/.dotfiles/AGENTS.md`
Keep them in sync so agents have correct instructions regardless of which directory they're working in.
# pi extensions
Extensions live in `pi/files/agent/extensions/`.
+18
View File
@@ -0,0 +1,18 @@
---@class SigilConfig
---@field target table<string, string|boolean>
---@field ignore? string[]
---@type SigilConfig
local config = {
target = {
linux = "~/.config/DankMaterialShell",
default = "~/.config/DankMaterialShell",
},
ignore = {
-- "**/.DS_Store",
-- "**/*.tmp",
-- "cache/**",
},
}
return config
@@ -0,0 +1,7 @@
{
"emojiLauncher": {
"enabled": true,
"trigger": ":",
"noTrigger": false
}
}
Submodule DankMaterialShell/files/plugins/emojiLauncher added at f4f474c9d9
+572
View File
@@ -0,0 +1,572 @@
{
"currentThemeName": "dynamic",
"currentThemeCategory": "dynamic",
"customThemeFile": "/home/thomasgl/.config/DankMaterialShell/themes/catppuccin/theme.json",
"registryThemeVariants": {
"catppuccin": {
"dark": {
"flavor": "frappe",
"accent": "mauve"
}
}
},
"matugenScheme": "scheme-tonal-spot",
"runUserMatugenTemplates": true,
"matugenTargetMonitor": "",
"popupTransparency": 0.75,
"dockTransparency": 1,
"widgetBackgroundColor": "sc",
"widgetColorMode": "default",
"controlCenterTileColorMode": "primary",
"buttonColorMode": "primary",
"cornerRadius": 8,
"niriLayoutGapsOverride": -1,
"niriLayoutRadiusOverride": -1,
"niriLayoutBorderSize": -1,
"hyprlandLayoutGapsOverride": -1,
"hyprlandLayoutRadiusOverride": -1,
"hyprlandLayoutBorderSize": -1,
"mangoLayoutGapsOverride": -1,
"mangoLayoutRadiusOverride": -1,
"mangoLayoutBorderSize": -1,
"use24HourClock": true,
"showSeconds": false,
"padHours12Hour": false,
"useFahrenheit": false,
"windSpeedUnit": "kmh",
"nightModeEnabled": false,
"animationSpeed": 2,
"customAnimationDuration": 500,
"syncComponentAnimationSpeeds": true,
"popoutAnimationSpeed": 1,
"popoutCustomAnimationDuration": 150,
"modalAnimationSpeed": 1,
"modalCustomAnimationDuration": 150,
"enableRippleEffects": true,
"wallpaperFillMode": "Fill",
"blurredWallpaperLayer": false,
"blurWallpaperOnOverview": false,
"showLauncherButton": true,
"showWorkspaceSwitcher": true,
"showFocusedWindow": true,
"showWeather": true,
"showMusic": true,
"showClipboard": true,
"showCpuUsage": true,
"showMemUsage": true,
"showCpuTemp": true,
"showGpuTemp": true,
"selectedGpuIndex": 0,
"enabledGpuPciIds": [],
"showSystemTray": true,
"showClock": true,
"showNotificationButton": true,
"showBattery": true,
"showControlCenterButton": true,
"showCapsLockIndicator": true,
"controlCenterShowNetworkIcon": true,
"controlCenterShowBluetoothIcon": true,
"controlCenterShowAudioIcon": true,
"controlCenterShowAudioPercent": false,
"controlCenterShowVpnIcon": true,
"controlCenterShowBrightnessIcon": false,
"controlCenterShowBrightnessPercent": false,
"controlCenterShowMicIcon": false,
"controlCenterShowMicPercent": false,
"controlCenterShowBatteryIcon": false,
"controlCenterShowPrinterIcon": false,
"controlCenterShowScreenSharingIcon": true,
"showPrivacyButton": true,
"privacyShowMicIcon": false,
"privacyShowCameraIcon": false,
"privacyShowScreenShareIcon": false,
"controlCenterWidgets": [
{
"id": "volumeSlider",
"enabled": true,
"width": 50
},
{
"id": "brightnessSlider",
"enabled": true,
"width": 50
},
{
"id": "wifi",
"enabled": true,
"width": 50
},
{
"id": "bluetooth",
"enabled": true,
"width": 50
},
{
"id": "audioOutput",
"enabled": true,
"width": 50
},
{
"id": "audioInput",
"enabled": true,
"width": 50
},
{
"id": "nightMode",
"enabled": true,
"width": 50
},
{
"id": "darkMode",
"enabled": true,
"width": 50
}
],
"showWorkspaceIndex": true,
"showWorkspaceName": false,
"showWorkspacePadding": false,
"workspaceScrolling": false,
"showWorkspaceApps": false,
"workspaceDragReorder": true,
"maxWorkspaceIcons": 3,
"workspaceAppIconSizeOffset": 0,
"groupWorkspaceApps": true,
"workspaceFollowFocus": false,
"showOccupiedWorkspacesOnly": false,
"reverseScrolling": false,
"dwlShowAllTags": false,
"workspaceColorMode": "default",
"workspaceOccupiedColorMode": "none",
"workspaceUnfocusedColorMode": "default",
"workspaceUrgentColorMode": "default",
"workspaceFocusedBorderEnabled": false,
"workspaceFocusedBorderColor": "primary",
"workspaceFocusedBorderThickness": 2,
"workspaceNameIcons": {},
"waveProgressEnabled": true,
"scrollTitleEnabled": true,
"audioVisualizerEnabled": true,
"audioScrollMode": "volume",
"audioWheelScrollAmount": 5,
"clockCompactMode": false,
"focusedWindowCompactMode": false,
"runningAppsCompactMode": true,
"barMaxVisibleApps": 0,
"barMaxVisibleRunningApps": 0,
"barShowOverflowBadge": true,
"appsDockHideIndicators": false,
"appsDockColorizeActive": false,
"appsDockActiveColorMode": "primary",
"appsDockEnlargeOnHover": false,
"appsDockEnlargePercentage": 125,
"appsDockIconSizePercentage": 100,
"keyboardLayoutNameCompactMode": true,
"runningAppsCurrentWorkspace": false,
"runningAppsGroupByApp": false,
"runningAppsCurrentMonitor": false,
"appIdSubstitutions": [
{
"pattern": "Spotify",
"replacement": "spotify",
"type": "exact"
},
{
"pattern": "beepertexts",
"replacement": "beeper",
"type": "exact"
},
{
"pattern": "home assistant desktop",
"replacement": "homeassistant-desktop",
"type": "exact"
},
{
"pattern": "com.transmissionbt.transmission",
"replacement": "transmission-gtk",
"type": "contains"
},
{
"pattern": "^steam_app_(\\d+)$",
"replacement": "steam_icon_$1",
"type": "regex"
}
],
"centeringMode": "index",
"clockDateFormat": "d MMM yyyy",
"lockDateFormat": "",
"mediaSize": 1,
"appLauncherViewMode": "list",
"spotlightModalViewMode": "list",
"browserPickerViewMode": "grid",
"browserUsageHistory": {
"firefox": {
"count": 1,
"lastUsed": 1773021966215,
"name": "Firefox"
}
},
"appPickerViewMode": "grid",
"filePickerUsageHistory": {},
"sortAppsAlphabetically": false,
"appLauncherGridColumns": 4,
"spotlightCloseNiriOverview": true,
"spotlightSectionViewModes": {},
"appDrawerSectionViewModes": {},
"niriOverviewOverlayEnabled": true,
"dankLauncherV2Size": "compact",
"dankLauncherV2BorderEnabled": false,
"dankLauncherV2BorderThickness": 2,
"dankLauncherV2BorderColor": "primary",
"dankLauncherV2ShowFooter": true,
"dankLauncherV2UnloadOnClose": false,
"useAutoLocation": false,
"weatherEnabled": true,
"networkPreference": "wifi",
"iconTheme": "System Default",
"cursorSettings": {
"theme": "Adwaita",
"size": 24,
"niri": {
"hideWhenTyping": false,
"hideAfterInactiveMs": 0
},
"hyprland": {
"hideOnKeyPress": false,
"hideOnTouch": false,
"inactiveTimeout": 0
},
"dwl": {
"cursorHideTimeout": 0
}
},
"launcherLogoMode": "apps",
"launcherLogoCustomPath": "",
"launcherLogoColorOverride": "",
"launcherLogoColorInvertOnMode": false,
"launcherLogoBrightness": 1,
"launcherLogoContrast": 0,
"launcherLogoSizeOffset": 0,
"fontFamily": "Inter Variable",
"monoFontFamily": "FiraCode Nerd Font",
"fontWeight": 400,
"fontScale": 1,
"notepadUseMonospace": true,
"notepadFontFamily": "",
"notepadFontSize": 14,
"notepadShowLineNumbers": false,
"notepadTransparencyOverride": -1,
"notepadLastCustomTransparency": 0.7,
"soundsEnabled": true,
"useSystemSoundTheme": false,
"soundNewNotification": true,
"soundVolumeChanged": true,
"soundPluggedIn": true,
"acMonitorTimeout": 7200,
"acLockTimeout": 3600,
"acSuspendTimeout": 0,
"acSuspendBehavior": 0,
"acProfileName": "",
"batteryMonitorTimeout": 0,
"batteryLockTimeout": 0,
"batterySuspendTimeout": 0,
"batterySuspendBehavior": 0,
"batteryProfileName": "",
"batteryChargeLimit": 100,
"lockBeforeSuspend": false,
"loginctlLockIntegration": true,
"fadeToLockEnabled": true,
"fadeToLockGracePeriod": 5,
"fadeToDpmsEnabled": true,
"fadeToDpmsGracePeriod": 5,
"launchPrefix": "",
"brightnessDevicePins": {},
"wifiNetworkPins": {},
"bluetoothDevicePins": {},
"audioInputDevicePins": {
"preferredInput": [
"alsa_input.usb-Shure_Inc_Shure_MV7__MV7__11-463503d372411c59a96ea3078a206742-01.mono-fallback"
]
},
"audioOutputDevicePins": {},
"gtkThemingEnabled": false,
"qtThemingEnabled": false,
"syncModeWithPortal": true,
"terminalsAlwaysDark": false,
"runDmsMatugenTemplates": true,
"matugenTemplateGtk": true,
"matugenTemplateNiri": true,
"matugenTemplateHyprland": false,
"matugenTemplateMangowc": true,
"matugenTemplateQt5ct": false,
"matugenTemplateQt6ct": false,
"matugenTemplateFirefox": true,
"matugenTemplatePywalfox": true,
"matugenTemplateZenBrowser": true,
"matugenTemplateVesktop": true,
"matugenTemplateEquibop": true,
"matugenTemplateGhostty": true,
"matugenTemplateKitty": true,
"matugenTemplateFoot": true,
"matugenTemplateAlacritty": true,
"matugenTemplateNeovim": false,
"matugenTemplateWezterm": true,
"matugenTemplateDgop": true,
"matugenTemplateKcolorscheme": true,
"matugenTemplateVscode": true,
"matugenTemplateEmacs": true,
"showDock": false,
"dockAutoHide": false,
"dockSmartAutoHide": false,
"dockGroupByApp": false,
"dockOpenOnOverview": false,
"dockPosition": 1,
"dockSpacing": 4,
"dockBottomGap": 0,
"dockMargin": 0,
"dockIconSize": 40,
"dockIndicatorStyle": "circle",
"dockBorderEnabled": false,
"dockBorderColor": "surfaceText",
"dockBorderOpacity": 1,
"dockBorderThickness": 1,
"dockIsolateDisplays": false,
"dockLauncherEnabled": false,
"dockLauncherLogoMode": "apps",
"dockLauncherLogoCustomPath": "",
"dockLauncherLogoColorOverride": "",
"dockLauncherLogoSizeOffset": 0,
"dockLauncherLogoBrightness": 0.5,
"dockLauncherLogoContrast": 1,
"dockMaxVisibleApps": 0,
"dockMaxVisibleRunningApps": 0,
"dockShowOverflowBadge": true,
"notificationOverlayEnabled": false,
"notificationPopupShadowEnabled": true,
"notificationPopupPrivacyMode": false,
"modalDarkenBackground": true,
"lockScreenShowPowerActions": true,
"lockScreenShowSystemIcons": true,
"lockScreenShowTime": true,
"lockScreenShowDate": true,
"lockScreenShowProfileImage": true,
"lockScreenShowPasswordField": true,
"lockScreenShowMediaPlayer": true,
"lockScreenPowerOffMonitorsOnLock": false,
"lockAtStartup": false,
"enableFprint": false,
"maxFprintTries": 3,
"lockScreenActiveMonitor": "all",
"lockScreenInactiveColor": "#000000",
"lockScreenNotificationMode": 0,
"hideBrightnessSlider": true,
"notificationTimeoutLow": 5000,
"notificationTimeoutNormal": 5000,
"notificationTimeoutCritical": 0,
"notificationCompactMode": false,
"notificationPopupPosition": 0,
"notificationAnimationSpeed": 1,
"notificationCustomAnimationDuration": 400,
"notificationHistoryEnabled": true,
"notificationHistoryMaxCount": 50,
"notificationHistoryMaxAgeDays": 7,
"notificationHistorySaveLow": true,
"notificationHistorySaveNormal": true,
"notificationHistorySaveCritical": true,
"notificationRules": [],
"osdAlwaysShowValue": true,
"osdPosition": 5,
"osdVolumeEnabled": true,
"osdMediaVolumeEnabled": true,
"osdMediaPlaybackEnabled": false,
"osdBrightnessEnabled": true,
"osdIdleInhibitorEnabled": true,
"osdMicMuteEnabled": true,
"osdCapsLockEnabled": true,
"osdPowerProfileEnabled": false,
"osdAudioOutputEnabled": true,
"powerActionConfirm": true,
"powerActionHoldDuration": 0.5,
"powerMenuActions": [
"reboot",
"logout",
"poweroff",
"lock",
"suspend",
"restart"
],
"powerMenuDefaultAction": "logout",
"powerMenuGridLayout": false,
"customPowerActionLock": "",
"customPowerActionLogout": "",
"customPowerActionSuspend": "",
"customPowerActionHibernate": "",
"customPowerActionReboot": "",
"customPowerActionPowerOff": "",
"updaterHideWidget": false,
"updaterUseCustomCommand": false,
"updaterCustomCommand": "",
"updaterTerminalAdditionalParams": "",
"displayNameMode": "system",
"screenPreferences": {
"wallpaper": [
"all"
]
},
"showOnLastDisplay": {},
"niriOutputSettings": {},
"hyprlandOutputSettings": {},
"displayProfiles": {},
"activeDisplayProfile": {},
"displayProfileAutoSelect": false,
"displayShowDisconnected": false,
"displaySnapToEdge": true,
"barConfigs": [
{
"id": "default",
"name": "Main Bar",
"enabled": true,
"position": 0,
"screenPreferences": [
"all"
],
"showOnLastDisplay": true,
"leftWidgets": [
{
"id": "launcherButton",
"enabled": true
},
{
"id": "workspaceSwitcher",
"enabled": true
},
{
"id": "focusedWindow",
"enabled": true,
"focusedWindowCompactMode": false
}
],
"centerWidgets": [
{
"id": "music",
"enabled": true,
"mediaSize": 1
},
"clock",
"weather"
],
"rightWidgets": [
"systemTray",
"clipboard",
"cpuUsage",
"memUsage",
"notificationButton",
"battery",
"controlCenterButton"
],
"spacing": 0,
"innerPadding": 8,
"bottomGap": -4,
"transparency": 0,
"widgetTransparency": 0.9,
"squareCorners": false,
"noBackground": false,
"gothCornersEnabled": false,
"gothCornerRadiusOverride": false,
"gothCornerRadiusValue": 12,
"borderEnabled": false,
"borderColor": "surfaceText",
"borderOpacity": 1,
"borderThickness": 1,
"fontScale": 1,
"autoHide": false,
"autoHideDelay": 250,
"openOnOverview": true,
"visible": true,
"popupGapsAuto": true,
"popupGapsManual": 4,
"clickThrough": false,
"widgetOutlineEnabled": false,
"widgetOutlineColor": "primary"
}
],
"desktopClockEnabled": false,
"desktopClockStyle": "analog",
"desktopClockTransparency": 0.8,
"desktopClockColorMode": "primary",
"desktopClockCustomColor": {
"r": 1,
"g": 1,
"b": 1,
"a": 1,
"hsvHue": -1,
"hsvSaturation": 0,
"hsvValue": 1,
"hslHue": -1,
"hslSaturation": 0,
"hslLightness": 1,
"valid": true
},
"desktopClockShowDate": true,
"desktopClockShowAnalogNumbers": false,
"desktopClockShowAnalogSeconds": true,
"desktopClockX": -1,
"desktopClockY": -1,
"desktopClockWidth": 280,
"desktopClockHeight": 180,
"desktopClockDisplayPreferences": [
"all"
],
"systemMonitorEnabled": false,
"systemMonitorShowHeader": true,
"systemMonitorTransparency": 0.8,
"systemMonitorColorMode": "primary",
"systemMonitorCustomColor": {
"r": 1,
"g": 1,
"b": 1,
"a": 1,
"hsvHue": -1,
"hsvSaturation": 0,
"hsvValue": 1,
"hslHue": -1,
"hslSaturation": 0,
"hslLightness": 1,
"valid": true
},
"systemMonitorShowCpu": true,
"systemMonitorShowCpuGraph": true,
"systemMonitorShowCpuTemp": true,
"systemMonitorShowGpuTemp": false,
"systemMonitorGpuPciId": "",
"systemMonitorShowMemory": true,
"systemMonitorShowMemoryGraph": true,
"systemMonitorShowNetwork": true,
"systemMonitorShowNetworkGraph": true,
"systemMonitorShowDisk": true,
"systemMonitorShowTopProcesses": false,
"systemMonitorTopProcessCount": 3,
"systemMonitorTopProcessSortBy": "cpu",
"systemMonitorGraphInterval": 60,
"systemMonitorLayoutMode": "auto",
"systemMonitorX": -1,
"systemMonitorY": -1,
"systemMonitorWidth": 320,
"systemMonitorHeight": 480,
"systemMonitorDisplayPreferences": [
"all"
],
"systemMonitorVariants": [],
"desktopWidgetPositions": {},
"desktopWidgetGridSettings": {},
"desktopWidgetInstances": [],
"desktopWidgetGroups": [],
"builtInPluginSettings": {
"dms_settings_search": {
"trigger": "?"
}
},
"clipboardEnterToPaste": false,
"launcherPluginVisibility": {},
"launcherPluginOrder": [],
"configVersion": 5
}
+2 -1
View File
@@ -10,7 +10,8 @@ style = "Regular"
import = ["~/.config/alacritty/dank-theme.toml"]
[terminal.shell]
program = "/usr/bin/fish"
program = "fish"
# args = ["-l", "-c", "tmux new; exec fish -l"]
args = ["-l", "-c", "zellij; exec fish -l"]
[window]
+3 -1
View File
@@ -1 +1,3 @@
source "$HOME/.cargo/env.fish"
if test -f "$HOME/.cargo/env.fish"
source "$HOME/.cargo/env.fish"
end
+22 -1
View File
@@ -2,6 +2,9 @@
set -q __fish_home_manager_config_sourced; and exit
set -g __fish_home_manager_config_sourced 1
# Ensure UTF-8 locale (needed for Nerd Font symbols in tmux)
set -gx LANG en_US.UTF-8
set -gx LC_ALL en_US.UTF-8
# Add ROCm bin directory to PATH
set -gx PATH "/opt/rocm/bin" $PATH
@@ -24,8 +27,22 @@ end
status is-interactive; and begin
# Abbreviations
# On macOS SSH sessions, normalize TERM if remote terminfo is missing
# (eg. TERM=alacritty from Linux host), otherwise tools like jj/less warn
if test (uname) = Darwin; and set -q SSH_TTY
if not infocmp "$TERM" >/dev/null 2>&1
set -gx TERM xterm-256color
end
end
# Abbreviations
abbr -a tx 'tmux'
abbr -a txa 'tmux attach'
abbr -a txl 'tmux list-sessions'
abbr -a txk 'tmux kill-session -t'
abbr -a txks 'tmux kill-server'
abbr -a zj 'zellij'
# Aliases
alias che chezmoi
@@ -66,6 +83,10 @@ status is-interactive; and begin
if test "$TERM" != dumb
fzf --fish | source
bind --erase \ct
bind -M insert --erase \ct
bind \cf fzf-file-widget
bind -M insert \cf fzf-file-widget
end
# add completions generated by Home Manager to $fish_complete_path
+10 -1
View File
@@ -1,8 +1,17 @@
function y
set tmp (mktemp -t "yazi-cwd.XXXXXX")
yazi $argv --cwd-file="$tmp"
# In Zellij + Alacritty, force Yazi away from graphical adapters and into Chafa.
# This gives text/blocks previews instead of broken/blank image panes.
if set -q ZELLIJ
env -u DISPLAY -u WAYLAND_DISPLAY -u SWAYSOCK -u HYPRLAND_INSTANCE_SIGNATURE -u WAYFIRE_SOCKET TERM=xterm-256color yazi $argv --cwd-file="$tmp"
else
yazi $argv --cwd-file="$tmp"
end
if set cwd (command cat -- "$tmp"); and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ]
builtin cd -- "$cwd"
end
rm -f -- "$tmp"
end
+15
View File
@@ -0,0 +1,15 @@
function yazi --wraps yazi --description "Yazi wrapper that forces Chafa inside Zellij"
if set -q ZELLIJ
begin
set -e DISPLAY
set -e WAYLAND_DISPLAY
set -e SWAYSOCK
set -e HYPRLAND_INSTANCE_SIGNATURE
set -e WAYFIRE_SOCKET
set -lx TERM xterm-256color
command yazi $argv
end
else
command yazi $argv
end
end
+9
View File
@@ -0,0 +1,9 @@
---@type SigilConfig
return {
target = {
linux = "~",
default = "~",
macos = "~",
},
}
+7
View File
@@ -0,0 +1,7 @@
[user]
name = Thomas G. Lopes
email = thomasgl@pm.me
[pull]
rebase = true
[init]
defaultBranch = main
+15
View File
@@ -0,0 +1,15 @@
[user]
name = Thomas G. Lopes
email = thomasgl@pm.me
[pull]
rebase = true
[init]
defaultBranch = main
[credential]
helper = /usr/bin/git-credential-libsecret ; Or the correct path to your helper
[commit]
gpgsign = true
[user]
email = thomas.lopes@attio.com
name = Thomas G. Lopes
signingkey = BFC0A729989E6CED
+18
View File
@@ -0,0 +1,18 @@
---@class SigilConfig
---@field target table<string, string|boolean>
---@field ignore? string[]
---@type SigilConfig
local config = {
target = {
linux = "~/.config/gsf",
default = "~/.config/gsf",
},
ignore = {
-- "**/.DS_Store",
-- "**/*.tmp",
-- "cache/**",
},
}
return config
+17
View File
@@ -0,0 +1,17 @@
{
"mode": 0,
"sens_mult": 1.5,
"yx_ratio": 1.0,
"input_dpi": 400.0,
"angle_rotation": 0.0,
"accel": 2.0,
"offset_linear": 3.5,
"output_cap": 30.0,
"decay_rate": 0.1,
"offset_natural": 0.0,
"limit": 2.0,
"gamma": 1.0,
"smooth": 0.5,
"motivity": 1.5,
"sync_speed": 5.0
}
+14 -5
View File
@@ -3,11 +3,12 @@
[templates.ghostty]
input_path = '~/.config/matugen/templates/ghostty-theme'
output_path = '~/.config/ghostty/themes/matugen'
post_hook = 'pkill -SIGUSR2 ghostty'
post_hook = "pkill -SIGUSR2 ghostty || true && nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.config/ghostty/themes/matugen ~/.config/ghostty/themes/matugen --remote-cmd 'pkill -SIGUSR2 ghostty || true' >/dev/null 2>&1 &"
[templates.kitty]
input_path = '~/.config/matugen/templates/kitty-colors.conf'
output_path = '~/.config/kitty/colors.conf'
post_hook = "nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.config/kitty/colors.conf ~/.config/kitty/colors.conf >/dev/null 2>&1 &"
[templates.foot]
input_path = '~/.config/matugen/templates/foot-theme'
@@ -24,10 +25,12 @@ output_path = '~/.config/gtk-4.0/colors.css'
[templates.fish-prompt]
input_path = '~/.config/matugen/templates/fish-prompt-colors.fish'
output_path = '~/.config/fish/conf.d/prompt-colors.fish'
post_hook = "nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.config/fish/conf.d/prompt-colors.fish ~/.config/fish/conf.d/prompt-colors.fish >/dev/null 2>&1 &"
[templates.yazi]
input_path = '~/.config/matugen/templates/yazi-theme.toml'
output_path = '~/.config/yazi/theme.toml'
post_hook = "nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.config/yazi/theme.toml ~/.config/yazi/theme.toml >/dev/null 2>&1 &"
[templates.qt5ct]
input_path = '~/.config/matugen/templates/qtct-colors.conf'
@@ -41,26 +44,32 @@ output_path = '~/.config/rofi/colors/matugen.rasi'
input_path = '~/.config/matugen/templates/niri-colors.kdl'
output_path = '~/.config/niri/colors.kdl'
[templates.tmux]
input_path = '~/.config/matugen/templates/tmux-colors.conf'
output_path = '~/.config/tmux/colors.conf'
post_hook = "tmux source-file ~/.config/tmux/tmux.conf 2>/dev/null || true && nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.config/tmux/colors.conf ~/.config/tmux/colors.conf --remote-cmd 'export PATH=\"/opt/homebrew/bin:/usr/local/bin:$PATH\" && tmux source-file ~/.config/tmux/tmux.conf 2>/dev/null || true' >/dev/null 2>&1 &"
[templates.zellij]
input_path = '~/.config/matugen/templates/zellij-colors.kdl'
output_path = '~/.config/zellij/themes/matugen.kdl'
post_hook = 'touch ~/.config/zellij/config.kdl && nohup ~/.config/matugen/scripts/sync-zellij-mac.sh >/dev/null 2>&1 &'
post_hook = "touch ~/.config/zellij/config.kdl && nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.config/zellij/themes/matugen.kdl ~/.config/zellij/themes/matugen.kdl --remote-cmd 'touch ~/.config/zellij/config.kdl' >/dev/null 2>&1 &"
[templates.jjui]
input_path = '~/.config/matugen/templates/jjui-theme.toml'
output_path = '~/.config/jjui/themes/matugen.toml'
post_hook = "nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.config/jjui/themes/matugen.toml ~/.config/jjui/themes/matugen.toml >/dev/null 2>&1 &"
[templates.nvim]
input_path = '~/.config/matugen/templates/neovim.lua'
output_path = '~/.config/nvim/lua/plugins/dankcolors.lua'
post_hook = 'nohup ~/.config/matugen/scripts/sync-nvim-mac.sh >/dev/null 2>&1 &'
post_hook = "nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.config/nvim/lua/plugins/dankcolors.lua ~/.config/nvim/lua/plugins/dankcolors.lua >/dev/null 2>&1 &"
[templates.pi]
input_path = '~/.config/matugen/templates/pi-theme.json'
output_path = '~/.pi/agent/themes/matugen.json.tmp'
post_hook = 'cat ~/.pi/agent/themes/matugen.json.tmp > ~/.pi/agent/themes/matugen.json && nohup ~/.config/matugen/scripts/sync-pi-mac.sh >/dev/null 2>&1 &'
post_hook = "cat ~/.pi/agent/themes/matugen.json.tmp > ~/.pi/agent/themes/matugen.json && nohup ~/.config/matugen/scripts/sync-mac.sh file ~/.pi/agent/themes/matugen.json ~/.pi/agent/themes/matugen.json >/dev/null 2>&1 &"
[templates.wallpaper]
input_path = '~/.config/matugen/templates/wallpaper-path.txt'
output_path = '~/.cache/matugen-last-image'
post_hook = 'nohup ~/.config/matugen/scripts/sync-wallpaper-mac.sh >/dev/null 2>&1 &'
post_hook = "nohup ~/.config/matugen/scripts/sync-mac.sh wallpaper ~/.cache/matugen-last-image >/dev/null 2>&1 &"
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env sh
set -eu
host="${MATUGEN_SYNC_HOST:-mac-attio}"
log_file="$HOME/.cache/matugen-sync-mac.log"
mkdir -p "$HOME/.cache"
usage() {
echo "usage:" >&2
echo " sync-mac.sh file <source_path> <remote_path> [--remote-cmd <command>]" >&2
echo " sync-mac.sh wallpaper <wallpaper_path_file>" >&2
exit 1
}
sync_file() {
source_path="$1"
remote_path="$2"
remote_cmd="${3-}"
# If caller passes a local absolute path, mirror it under remote $HOME.
case "$remote_path" in
"$HOME")
remote_path="~"
;;
"$HOME"/*)
remote_path="~/${remote_path#"$HOME"/}"
;;
esac
remote_dir="$(dirname "$remote_path")"
remote_tmp="${remote_path}.tmp"
ssh "$host" "mkdir -p $remote_dir"
scp "$source_path" "$host:$remote_tmp"
ssh "$host" "mv $remote_tmp $remote_path"
if [ -n "$remote_cmd" ]; then
ssh "$host" "$remote_cmd"
fi
}
sync_wallpaper() {
wallpaper_path_file="$1"
[ -f "$wallpaper_path_file" ] || exit 0
wallpaper_path="$(cat "$wallpaper_path_file")"
[ -n "$wallpaper_path" ] || exit 0
[ -f "$wallpaper_path" ] || exit 0
base_name="$(basename "$wallpaper_path")"
local_cache_dir="$HOME/.cache/matugen-wallpapers"
local_copy="$local_cache_dir/$base_name"
mkdir -p "$local_cache_dir"
cp -f "$wallpaper_path" "$local_copy"
ssh "$host" "mkdir -p ~/.cache/matugen-wallpapers"
scp "$local_copy" "$host:~/.cache/matugen-wallpapers/$base_name"
ssh "$host" "osascript -e 'tell application \"System Events\" to tell every desktop to set picture to POSIX file \"~/.cache/matugen-wallpapers/$base_name\"'"
}
mode="${1-}"
[ -n "$mode" ] || usage
shift
{
echo "[$(date '+%Y-%m-%d %H:%M:%S')] mode=$mode"
case "$mode" in
file)
[ "$#" -ge 2 ] || usage
source_path="$1"
remote_path="$2"
shift 2
remote_cmd=""
if [ "${1-}" = "--remote-cmd" ]; then
[ "$#" -eq 2 ] || usage
remote_cmd="$2"
elif [ "$#" -ne 0 ]; then
usage
fi
sync_file "$source_path" "$remote_path" "$remote_cmd"
;;
wallpaper)
[ "$#" -eq 1 ] || usage
sync_wallpaper "$1"
;;
*)
usage
;;
esac
} >>"$log_file" 2>&1
-12
View File
@@ -1,12 +0,0 @@
#!/usr/bin/env sh
set -eu
log_file="$HOME/.cache/matugen-sync-nvim.log"
mkdir -p "$HOME/.cache"
{
ssh mac-attio "mkdir -p ~/.config/nvim/lua/plugins"
scp "$HOME/.config/nvim/lua/plugins/dankcolors.lua" \
mac-attio:~/.config/nvim/lua/plugins/
} >>"$log_file" 2>&1
-13
View File
@@ -1,13 +0,0 @@
#!/usr/bin/env sh
set -eu
log_file="$HOME/.cache/matugen-sync-pi.log"
mkdir -p "$HOME/.cache"
{
ssh mac-attio "mkdir -p ~/.pi/agent/themes"
scp "$HOME/.pi/agent/themes/matugen.json" \
mac-attio:~/.pi/agent/themes/matugen.json.tmp
ssh mac-attio "mv ~/.pi/agent/themes/matugen.json.tmp ~/.pi/agent/themes/matugen.json"
} >>"$log_file" 2>&1
@@ -1,21 +0,0 @@
#!/usr/bin/env sh
set -eu
log_file="$HOME/.cache/matugen-sync-wallpaper.log"
mkdir -p "$HOME/.cache"
{
wallpaper_path="$(cat "$HOME/.cache/matugen-last-image")"
if [ -n "$wallpaper_path" ]; then
base_name="$(basename "$wallpaper_path")"
dest_path="$HOME/.cache/matugen-wallpapers/$base_name"
mkdir -p "$HOME/.cache/matugen-wallpapers"
cp -f "$wallpaper_path" "$dest_path"
ssh mac-attio "mkdir -p ~/.cache/matugen-wallpapers"
scp "$dest_path" "mac-attio:~/.cache/matugen-wallpapers/$base_name"
ssh mac-attio "osascript -e 'tell application \"System Events\" to tell every desktop to set picture to POSIX file \"~/.cache/matugen-wallpapers/$base_name\"'"
fi
} >>"$log_file" 2>&1
-13
View File
@@ -1,13 +0,0 @@
#!/usr/bin/env sh
set -eu
log_file="$HOME/.cache/matugen-sync-zellij.log"
mkdir -p "$HOME/.cache"
{
ssh mac-attio "mkdir -p ~/.config/zellij/themes"
scp "$HOME/.config/zellij/themes/matugen.kdl" \
mac-attio:~/.config/zellij/themes/
ssh mac-attio "touch ~/.config/zellij/config.kdl"
} >>"$log_file" 2>&1
+81
View File
@@ -0,0 +1,81 @@
# Tmux theme colors (generated by matugen)
# Uses Material Design 3 semantic color system
# =============================================
# Semantic Color Roles
# =============================================
# Primary - main brand color
PRIMARY={{colors.primary.default.hex}}
ON_PRIMARY={{colors.on_primary.default.hex}}
# Secondary - complementary accent
SECONDARY={{colors.secondary.default.hex}}
ON_SECONDARY={{colors.on_secondary.default.hex}}
# Tertiary - contrasting accent
TERTIARY={{colors.tertiary.default.hex}}
ON_TERTIARY={{colors.on_tertiary.default.hex}}
# Surface - backgrounds at different elevations
SURFACE={{colors.surface.default.hex}}
SURFACE_CONTAINER={{colors.surface_container.default.hex}}
SURFACE_VARIANT={{colors.surface_variant.default.hex}}
INVERSE_SURFACE={{colors.inverse_surface.default.hex}}
# On colors - text/icons on surfaces
ON_SURFACE={{colors.on_surface.default.hex}}
ON_SURFACE_VARIANT={{colors.on_surface_variant.default.hex}}
INVERSE_ON_SURFACE={{colors.inverse_on_surface.default.hex}}
# Outlines - borders and dividers
OUTLINE={{colors.outline.default.hex}}
OUTLINE_VARIANT={{colors.outline_variant.default.hex}}
# Error - destructive actions
ERROR={{colors.error.default.hex}}
ON_ERROR={{colors.on_error.default.hex}}
# =============================================
# Tmux Styling with Semantic Colors
# =============================================
# Status bar - surface container for elevation
set -g status-style "bg={{colors.surface_container.default.hex}},fg={{colors.on_surface.default.hex}}"
# Left side - primary with on-primary text (max contrast)
set -g status-left "#[fg={{colors.on_primary.default.hex}},bg={{colors.primary.default.hex}},bold] #S #[bg={{colors.surface_container.default.hex}}] "
# Right side - muted text
set -g status-right "#[fg={{colors.on_surface_variant.default.hex}}]%Y-%m-%d #[fg={{colors.on_surface.default.hex}}]%H:%M #[default]"
# Window tabs - variant for inactive, primary for active
set -g window-status-format "#[fg={{colors.on_surface_variant.default.hex}}] #I:#W "
set -g window-status-current-format "#[fg={{colors.on_primary.default.hex}},bg={{colors.primary.default.hex}},bold] #I:#W #[default]"
set -g window-status-separator ""
set -g status-justify left
# Pane borders - outline for inactive, primary for active
set -g pane-border-style "fg={{colors.outline_variant.default.hex}}"
set -g pane-active-border-style "fg={{colors.primary.default.hex}}"
# Messages - surface variant bg with on-surface text
set -g message-style "bg={{colors.surface_variant.default.hex}},fg={{colors.on_surface.default.hex}},bold"
set -g message-command-style "bg={{colors.surface_container.default.hex}},fg={{colors.on_surface.default.hex}}"
# Copy mode - tertiary accent
set -g mode-style "bg={{colors.tertiary.default.hex}},fg={{colors.on_tertiary.default.hex}}"
# Clock
set -g clock-mode-color "{{colors.primary.default.hex}}"
# Selection highlighting
set -g copy-mode-match-style "bg={{colors.tertiary_container.default.hex}},fg={{colors.on_tertiary_container.default.hex}}"
set -g copy-mode-current-match-style "bg={{colors.primary.default.hex}},fg={{colors.on_primary.default.hex}},bold"
# Popups and menus
set -g popup-style "bg={{colors.surface_container.default.hex}},fg={{colors.on_surface.default.hex}}"
set -g popup-border-style "fg={{colors.outline.default.hex}}"
set -g menu-style "bg={{colors.surface_container.default.hex}},fg={{colors.on_surface.default.hex}}"
set -g menu-selected-style "bg={{colors.primary.default.hex}},fg={{colors.on_primary.default.hex}}"
set -g menu-border-style "fg={{colors.outline.default.hex}}"
+15
View File
@@ -0,0 +1,15 @@
---@class SigilConfig
---@field target table<string, string|boolean>
---@field ignore? string[]
---@type SigilConfig
local config = {
target = {
linux = "~/.config/mpv",
darwin = "~/.config/mpv",
default = "~/.config/mpv",
},
ignore = {},
}
return config
+22
View File
@@ -0,0 +1,22 @@
# MPV Key Bindings
# Frame stepping for millisecond precision
. frame-step
, frame-back-step
# Small time jumps (100ms)
- seek -0.1
= seek +0.1
# Playback speed control
[ add speed -0.1
] add speed +0.1
# Frame stepping alternatives (in case . and , don't work)
RIGHT seek 5
LEFT seek -5
UP seek 60
DOWN seek -60
Shift+RIGHT seek 1
Shift+LEFT seek -1
Ctrl+RIGHT seek 0.1 exact
Ctrl+LEFT seek -0.1 exact
+3
View File
@@ -0,0 +1,3 @@
# MPV Configuration
# Show time with milliseconds (e.g., 0:23:45.123)
osd-fractions=yes
+382 -359
View File
@@ -9,150 +9,150 @@ include "./dms/wpblur.kdl"
// https://github.com/YaLTeR/niri/wiki/Configuration:-Input
input {
keyboard {
xkb {
// For more information, see xkeyboard-config(7).
keyboard {
xkb {
// For more information, see xkeyboard-config(7).
layout "us,us"
variant ",alt-intl"
options "grp:alt_space_toggle,compose:ralt"
}
}
// Enable numlock on startup, omitting this setting disables it.
numlock
}
// Enable numlock on startup, omitting this setting disables it.
numlock
}
// Next sections include libinput settings.
// Omitting settings disables them, or leaves them at their default values.
touchpad {
// off
tap
// dwt
// dwtp
// drag false
// drag-lock
natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "two-finger"
// disabled-on-external-mouse
}
// Next sections include libinput settings.
// Omitting settings disables them, or leaves them at their default values.
touchpad {
// off
tap
// dwt
// dwtp
// drag false
// drag-lock
natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "two-finger"
// disabled-on-external-mouse
}
mouse {
// off
// natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "no-scroll"
}
mouse {
// off
// natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "no-scroll"
}
trackpoint {
// off
// natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "on-button-down"
// scroll-button 273
// middle-emulation
}
trackpoint {
// off
// natural-scroll
// accel-speed 0.2
// accel-profile "flat"
// scroll-method "on-button-down"
// scroll-button 273
// middle-emulation
}
// Uncomment this to make the mouse warp to the center of newly focused windows.
// warp-mouse-to-focus
// Uncomment this to make the mouse warp to the center of newly focused windows.
// warp-mouse-to-focus
// Focus windows and outputs automatically when moving the mouse into them.
// Setting max-scroll-amount="0%" makes it work only on windows already fully on screen.
focus-follows-mouse max-scroll-amount="0%"
// Focus windows and outputs automatically when moving the mouse into them.
// Setting max-scroll-amount="0%" makes it work only on windows already fully on screen.
focus-follows-mouse max-scroll-amount="0%"
}
// You can configure outputs by their name, which you can find
// by running `niri msg outputs` while inside a niri instance.
// https://github.com/YaLTeR/niri/wiki/Configuration:-Outputs
output "DP-1" {
// Uncomment this line to disable this output.
// off
// Uncomment this line to disable this output.
// off
// If the refresh rate is omitted, niri will pick the highest refresh rate
// for the resolution.
// If the mode is omitted altogether or is invalid, niri will pick one automatically.
mode "3840x2160@240"
// mode "3840x2160@119.880"
// If the refresh rate is omitted, niri will pick the highest refresh rate
// for the resolution.
// If the mode is omitted altogether or is invalid, niri will pick one automatically.
// mode "3840x2160@240"
mode "3840x2160@120"
// You can use integer or fractional scale, for example use 1.5 for 150% scale.
scale 2
// You can use integer or fractional scale, for example use 1.5 for 150% scale.
scale 2
// Transform allows to rotate the output counter-clockwise, valid values are:
// normal, 90, 180, 270, flipped, flipped-90, flipped-180 and flipped-270.
transform "normal"
// Transform allows to rotate the output counter-clockwise, valid values are:
// normal, 90, 180, 270, flipped, flipped-90, flipped-180 and flipped-270.
transform "normal"
// Position of the output in the global coordinate space.
// This affects directional monitor actions like "focus-monitor-left", and cursor movement.
// The cursor can only move between directly adjacent outputs.
// Output scale and rotation has to be taken into account for positioning:
// outputs are sized in logical, or scaled, pixels.
// For example, a 3840×2160 output with scale 2.0 will have a logical size of 1920×1080,
// so to put another output directly adjacent to it on the right, set its x to 1920.
// If the position is unset or results in an overlap, the output is instead placed
// automatically.
// position x=2400 y=0
// Position of the output in the global coordinate space.
// This affects directional monitor actions like "focus-monitor-left", and cursor movement.
// The cursor can only move between directly adjacent outputs.
// Output scale and rotation has to be taken into account for positioning:
// outputs are sized in logical, or scaled, pixels.
// For example, a 3840×2160 output with scale 2.0 will have a logical size of 1920×1080,
// so to put another output directly adjacent to it on the right, set its x to 1920.
// If the position is unset or results in an overlap, the output is instead placed
// automatically.
// position x=2400 y=0
}
// Settings that influence how windows are positioned and sized.
// Find more information on the wiki:
// https://github.com/YaLTeR/niri/wiki/Configuration:-Layout
layout {
gaps 16
center-focused-column "on-overflow"
gaps 16
center-focused-column "on-overflow"
preset-column-widths {
proportion 0.5
preset-column-widths {
proportion 0.5
proportion 0.66667
proportion 0.75
proportion 0.95
// Fixed sets the width in logical pixels exactly.
// fixed 1920
}
// Fixed sets the width in logical pixels exactly.
// fixed 1920
}
// You can also customize the heights that "switch-preset-window-height" (Mod+Shift+R) toggles between.
// preset-window-heights { }
// You can also customize the heights that "switch-preset-window-height" (Mod+Shift+R) toggles between.
// preset-window-heights { }
// You can change the default width of the new windows.
default-column-width { proportion 0.66667; }
// If you leave the brackets empty, the windows themselves will decide their initial width.
// default-column-width {}
// You can change the default width of the new windows.
default-column-width { proportion 0.66667; }
// If you leave the brackets empty, the windows themselves will decide their initial width.
// default-column-width {}
// You can change how the focus ring looks.
focus-ring {
// Uncomment this line to disable the focus ring.
// off
// You can change how the focus ring looks.
focus-ring {
// Uncomment this line to disable the focus ring.
// off
// How many logical pixels the ring extends out from the windows.
width 2
}
// How many logical pixels the ring extends out from the windows.
width 2
}
// You can also add a border. It's similar to the focus ring, but always visible.
border {
// The settings are the same as for the focus ring.
// If you enable the border, you probably want to disable the focus ring.
// off
// You can also add a border. It's similar to the focus ring, but always visible.
border {
// The settings are the same as for the focus ring.
// If you enable the border, you probably want to disable the focus ring.
// off
width 2
}
width 2
}
// You can enable drop shadows for windows.
shadow {
// Uncomment the next line to enable shadows.
on
// You can enable drop shadows for windows.
shadow {
// Uncomment the next line to enable shadows.
on
// Softness controls the shadow blur radius.
softness 30
// Softness controls the shadow blur radius.
softness 30
// Spread expands the shadow.
spread 7
// Spread expands the shadow.
spread 7
// Offset moves the shadow relative to the window.
offset x=0 y=6
}
// Offset moves the shadow relative to the window.
offset x=0 y=6
}
}
spawn-at-startup "xwayland-satellite"
@@ -165,11 +165,11 @@ screenshot-path "~/Pictures/Screenshots/Screenshot from %Y-%m-%d %H-%M-%S.png"
// The wiki explains how to configure individual animations:
// https://github.com/YaLTeR/niri/wiki/Configuration:-Animations
animations {
// Uncomment to turn off all animations.
// off
// Uncomment to turn off all animations.
// off
// Slow down all animations by this factor. Values below 1 speed them up instead.
slowdown 0.5
// Slow down all animations by this factor. Values below 1 speed them up instead.
slowdown 0.5
}
// Window rules let you adjust behavior for individual windows.
@@ -179,54 +179,74 @@ animations {
// Work around WezTerm's initial configure bug
// by setting an empty default-column-width.
window-rule {
// This regular expression is intentionally made as specific as possible,
// since this is the default config, and we want no false positives.
// You can get away with just app-id="wezterm" if you want.
match app-id=r#"^org\.wezfurlong\.wezterm$"#
default-column-width {}
// This regular expression is intentionally made as specific as possible,
// since this is the default config, and we want no false positives.
// You can get away with just app-id="wezterm" if you want.
match app-id=r#"^org\.wezfurlong\.wezterm$"#
default-column-width {}
}
// Open the Firefox picture-in-picture player as floating by default.
// Open the Firefox picture-in-Picture player as floating by default.
window-rule {
// This app-id regular expression will work for both:
// - host Firefox (app-id is "firefox")
// - Flatpak Firefox (app-id is "org.mozilla.firefox")
match app-id=r#"firefox$"# title="^Picture-in-Picture$"
open-floating true
// This app-id regular expression will work for both:
// - host Firefox (app-id is "firefox")
// - Flatpak Firefox (app-id is "org.mozilla.firefox")
match app-id=r#"firefox$"# title="^Picture-in-Picture$"
open-floating true
}
// Handy overlay: don't focus it and remove niri decorations.
window-rule {
match app-id=r#"(?i)^handy$"# title="Recording"
open-floating true
open-focused false
default-floating-position x=120 y=-160 relative-to="bottom"
draw-border-with-background false
focus-ring {
off
}
border {
off
}
shadow {
off
}
geometry-corner-radius 0
clip-to-geometry false
}
// Do the same for Zen Browser.
window-rule {
match app-id=r#"zen$"# title="^Picture-in-Picture$"
open-floating true
match app-id=r#"zen$"# title="^Picture-in-Picture$"
open-floating true
}
// Block out sensitive components from screen capture.
window-rule {
match app-id=r#"legcord$"#
match app-id=r#"Slack$"#
match app-id=r#"legcord$"#
match app-id=r#"Slack$"#
block-out-from "screen-capture"
block-out-from "screen-capture"
}
// Block out sensitive components from screencasts
layer-rule {
match namespace="^dms:clipboard$"
match namespace="^dms:notification"
match namespace="^dms:clipboard$"
match namespace="^dms:notification"
block-out-from "screen-capture"
block-out-from "screen-capture"
}
window-rule {
match app-id="steam" title=r#"^notificationtoasts_\d+_desktop$"#
default-floating-position x=10 y=10 relative-to="bottom-right"
match app-id="steam" title=r#"notificationtoasts_\d+_desktop$"#
default-floating-position x=10 y=10 relative-to="bottom-right"
}
// Example: enable rounded corners for all windows.
// (This example rule is commented out with a "/-" in front.)
window-rule {
geometry-corner-radius 8
clip-to-geometry true
geometry-corner-radius 8
clip-to-geometry true
}
hotkey-overlay {
@@ -242,7 +262,7 @@ binds {
// SCRIPTS
Super+B { spawn "sh" "-c" "dms ipc call wallpaper set $(~/scripts/random-wallpaper.sh)"; }
Super+Shift+D hotkey-overlay-title="Restart DMS" { spawn "sh" "-c" "dms restart" ; }
Super+Shift+D hotkey-overlay-title="Restart DMS" allow-when-locked=true { spawn "sh" "-c" "dms restart" ; }
// Super+A hotkey-overlay-title="Capture Screen" { spawn "sh" "-c" "grim -g \"$(slurp; sleep .1)\" - | swappy -f -"; }
Super+M hotkey-overlay-title="Media Output Select" { spawn "sh" "-c" "~/scripts/rofi-media.sh"; }
Super+Semicolon hotkey-overlay-title="Emoji picker" { spawn "sh" "-c" "rofimoji"; }
@@ -253,262 +273,262 @@ binds {
XF86AudioNext allow-when-locked=true { spawn "playerctl" "next"; }
XF86AudioPrev allow-when-locked=true { spawn "playerctl" "previous"; }
Mod+O repeat=false { toggle-overview; }
Mod+O repeat=false { toggle-overview; }
Mod+Q { close-window; }
Mod+Q { close-window; }
Mod+Left { focus-column-left; }
Mod+Down { focus-window-or-workspace-down; }
Mod+Up { focus-window-or-workspace-up; }
Mod+Right { focus-column-right; }
// Mod+H { focus-column-left; }
// Mod+J { focus-window-down; }
// Mod+K { focus-window-up; }
// Mod+L { focus-column-right; }
Mod+Left { focus-column-left; }
Mod+Down { focus-window-or-workspace-down; }
Mod+Up { focus-window-or-workspace-up; }
Mod+Right { focus-column-right; }
// Mod+H { focus-column-left; }
// Mod+J { focus-window-down; }
// Mod+K { focus-window-up; }
// Mod+L { focus-column-right; }
Mod+Shift+Left { move-column-left; }
Mod+Shift+Down { move-window-down; }
Mod+Shift+Up { move-window-up; }
Mod+Shift+Right { move-column-right; }
Mod+Shift+H { move-column-left; }
Mod+Shift+J { move-window-down; }
Mod+Shift+K { move-window-up; }
Mod+Shift+L { move-column-right; }
Mod+Shift+Left { move-column-left; }
Mod+Shift+Down { move-window-down; }
Mod+Shift+Up { move-window-up; }
Mod+Shift+Right { move-column-right; }
Mod+Shift+H { move-column-left; }
Mod+Shift+J { move-window-down; }
Mod+Shift+K { move-window-up; }
Mod+Shift+L { move-column-right; }
// Alternative commands that move across workspaces when reaching
// the first or last window in a column.
// Mod+J { focus-window-or-workspace-down; }
// Mod+K { focus-window-or-workspace-up; }
// Mod+Shift+J { move-window-down-or-to-workspace-down; }
// Mod+Shift+K { move-window-up-or-to-workspace-up; }
// Alternative commands that move across workspaces when reaching
// the first or last window in a column.
// Mod+J { focus-window-or-workspace-down; }
// Mod+K { focus-window-or-workspace-up; }
// Mod+Shift+J { move-window-down-or-to-workspace-down; }
// Mod+Shift+K { move-window-up-or-to-workspace-up; }
Mod+Home { focus-column-first; }
Mod+End { focus-column-last; }
Mod+Shift+Home { move-column-to-first; }
Mod+Shift+End { move-column-to-last; }
Mod+Home { focus-column-first; }
Mod+End { focus-column-last; }
Mod+Shift+Home { move-column-to-first; }
Mod+Shift+End { move-column-to-last; }
// Mod+Shift+Left { focus-monitor-left; }
// Mod+Shift+Down { focus-monitor-down; }
// Mod+Shift+Up { focus-monitor-up; }
// Mod+Shift+Right { focus-monitor-right; }
// Mod+Shift+H { focus-monitor-left; }
// Mod+Shift+J { focus-monitor-down; }
// Mod+Shift+K { focus-monitor-up; }
// Mod+Shift+L { focus-monitor-right; }
//
// Mod+Shift+Ctrl+Left { move-column-to-monitor-left; }
// Mod+Shift+Ctrl+Down { move-column-to-monitor-down; }
// Mod+Shift+Ctrl+Up { move-column-to-monitor-up; }
// Mod+Shift+Ctrl+Right { move-column-to-monitor-right; }
// Mod+Shift+Ctrl+H { move-column-to-monitor-left; }
// Mod+Shift+Ctrl+J { move-column-to-monitor-down; }
// Mod+Shift+Ctrl+K { move-column-to-monitor-up; }
// Mod+Shift+Ctrl+L { move-column-to-monitor-right; }
// Mod+Shift+Left { focus-monitor-left; }
// Mod+Shift+Down { focus-monitor-down; }
// Mod+Shift+Up { focus-monitor-up; }
// Mod+Shift+Right { focus-monitor-right; }
// Mod+Shift+H { focus-monitor-left; }
// Mod+Shift+J { focus-monitor-down; }
// Mod+Shift+K { focus-monitor-up; }
// Mod+Shift+L { focus-monitor-right; }
//
// Mod+Shift+Ctrl+Left { move-column-to-monitor-left; }
// Mod+Shift+Ctrl+Down { move-column-to-monitor-down; }
// Mod+Shift+Ctrl+Up { move-column-to-monitor-up; }
// Mod+Shift+Ctrl+Right { move-column-to-monitor-right; }
// Mod+Shift+Ctrl+H { move-column-to-monitor-left; }
// Mod+Shift+Ctrl+J { move-column-to-monitor-down; }
// Mod+Shift+Ctrl+K { move-column-to-monitor-up; }
// Mod+Shift+Ctrl+L { move-column-to-monitor-right; }
// Alternatively, there are commands to move just a single window:
// Mod+Shift+Ctrl+Left { move-window-to-monitor-left; }
// ...
// Alternatively, there are commands to move just a single window:
// Mod+Shift+Ctrl+Left { move-window-to-monitor-left; }
// ...
// And you can also move a whole workspace to another monitor:
// Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; }
// ...
// And you can also move a whole workspace to another monitor:
// Mod+Shift+Ctrl+Left { move-workspace-to-monitor-left; }
// ...
Mod+Page_Down { focus-workspace-down; }
Alt+Ctrl+Page_Down { focus-workspace-down; }
Mod+Page_Up { focus-workspace-up; }
Alt+Ctrl+Page_Up { focus-workspace-up; }
Mod+U { focus-workspace-down; }
Alt+Ctrl+U { focus-workspace-down; }
Mod+I { focus-workspace-up; }
Alt+Ctrl+I { focus-workspace-up; }
Mod+Shift+Page_Down { move-column-to-workspace-down; }
Alt+Ctrl+Shift+Page_Down { move-column-to-workspace-down; }
Mod+Shift+Page_Up { move-column-to-workspace-up; }
Alt+Ctrl+Shift+Page_Up { move-column-to-workspace-up; }
Mod+Shift+U { move-column-to-workspace-down; }
Alt+Ctrl+Shift+U { move-column-to-workspace-down; }
Mod+Shift+I { move-column-to-workspace-up; }
Alt+Ctrl+Shift+I { move-column-to-workspace-up; }
Mod+Page_Down { focus-workspace-down; }
Alt+Ctrl+Page_Down { focus-workspace-down; }
Mod+Page_Up { focus-workspace-up; }
Alt+Ctrl+Page_Up { focus-workspace-up; }
Mod+U { focus-workspace-down; }
Alt+Ctrl+U { focus-workspace-down; }
Mod+I { focus-workspace-up; }
Alt+Ctrl+I { focus-workspace-up; }
Mod+Shift+Page_Down { move-column-to-workspace-down; }
Alt+Ctrl+Shift+Page_Down { move-column-to-workspace-down; }
Mod+Shift+Page_Up { move-column-to-workspace-up; }
Alt+Ctrl+Shift+Page_Up { move-column-to-workspace-up; }
Mod+Shift+U { move-column-to-workspace-down; }
Alt+Ctrl+Shift+U { move-column-to-workspace-down; }
Mod+Shift+I { move-column-to-workspace-up; }
Alt+Ctrl+Shift+I { move-column-to-workspace-up; }
// Alternatively, there are commands to move just a single window:
// Mod+Ctrl+Page_Down { move-window-to-workspace-down; }
// ...
// Alternatively, there are commands to move just a single window:
// Mod+Ctrl+Page_Down { move-window-to-workspace-down; }
// ...
Mod+Ctrl+Page_Down { move-workspace-down; }
Mod+Ctrl+Page_Up { move-workspace-up; }
Mod+Ctrl+U { move-workspace-down; }
Mod+Ctrl+I { move-workspace-up; }
Mod+Ctrl+Page_Down { move-workspace-down; }
Mod+Ctrl+Page_Up { move-workspace-up; }
Mod+Ctrl+U { move-workspace-down; }
Mod+Ctrl+I { move-workspace-up; }
// You can bind mouse wheel scroll ticks using the following syntax.
// These binds will change direction based on the natural-scroll setting.
//
// To avoid scrolling through workspaces really fast, you can use
// the cooldown-ms property. The bind will be rate-limited to this value.
// You can set a cooldown on any bind, but it's most useful for the wheel.
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
// You can bind mouse wheel scroll ticks using the following syntax.
// These binds will change direction based on the natural-scroll setting.
//
// To avoid scrolling through workspaces really fast, you can use
// the cooldown-ms property. The bind will be rate-limited to this value.
// You can set a cooldown on any bind, but it's most useful for the wheel.
Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
Mod+WheelScrollUp cooldown-ms=150 { focus-workspace-up; }
Mod+Ctrl+WheelScrollDown cooldown-ms=150 { move-column-to-workspace-down; }
Mod+Ctrl+WheelScrollUp cooldown-ms=150 { move-column-to-workspace-up; }
Mod+WheelScrollRight { focus-column-right; }
Mod+WheelScrollLeft { focus-column-left; }
Mod+Ctrl+WheelScrollRight { move-column-right; }
Mod+Ctrl+WheelScrollLeft { move-column-left; }
Mod+WheelScrollRight { focus-column-right; }
Mod+WheelScrollLeft { focus-column-left; }
Mod+Ctrl+WheelScrollRight { move-column-right; }
Mod+Ctrl+WheelScrollLeft { move-column-left; }
// Usually scrolling up and down with Shift in applications results in
// horizontal scrolling; these binds replicate that.
Mod+Shift+WheelScrollDown { focus-column-right; }
Mod+Shift+WheelScrollUp { focus-column-left; }
Mod+Ctrl+Shift+WheelScrollDown { move-column-right; }
Mod+Ctrl+Shift+WheelScrollUp { move-column-left; }
// Usually scrolling up and down with Shift in applications results in
// horizontal scrolling; these binds replicate that.
Mod+Shift+WheelScrollDown { focus-column-right; }
Mod+Shift+WheelScrollUp { focus-column-left; }
Mod+Ctrl+Shift+WheelScrollDown { move-column-right; }
Mod+Ctrl+Shift+WheelScrollUp { move-column-left; }
// Similarly, you can bind touchpad scroll "ticks".
// Touchpad scrolling is continuous, so for these binds it is split into
// discrete intervals.
// These binds are also affected by touchpad's natural-scroll, so these
// example binds are "inverted", since we have natural-scroll enabled for
// touchpads by default.
// Mod+TouchpadScrollDown { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
// Mod+TouchpadScrollUp { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }
// Similarly, you can bind touchpad scroll "ticks".
// Touchpad scrolling is continuous, so for these binds it is split into
// discrete intervals.
// These binds are also affected by touchpad's natural-scroll, so these
// example binds are "inverted", since we have natural-scroll enabled for
// touchpads by default.
// Mod+TouchpadScrollDown { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
// Mod+TouchpadScrollUp { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }
// You can refer to workspaces by index. However, keep in mind that
// niri is a dynamic workspace system, so these commands are kind of
// "best effort". Trying to refer to a workspace index bigger than
// the current workspace count will instead refer to the bottommost
// (empty) workspace.
//
// For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on
// will all refer to the 3rd workspace.
Mod+1 { focus-workspace 1; }
Mod+2 { focus-workspace 2; }
Mod+3 { focus-workspace 3; }
Mod+4 { focus-workspace 4; }
Mod+5 { focus-workspace 5; }
Mod+6 { focus-workspace 6; }
Mod+7 { focus-workspace 7; }
Mod+8 { focus-workspace 8; }
Mod+9 { focus-workspace 9; }
Alt+Ctrl+1 { focus-workspace 1; }
Alt+Ctrl+2 { focus-workspace 2; }
Alt+Ctrl+3 { focus-workspace 3; }
Alt+Ctrl+4 { focus-workspace 4; }
Alt+Ctrl+5 { focus-workspace 5; }
Alt+Ctrl+6 { focus-workspace 6; }
Alt+Ctrl+7 { focus-workspace 7; }
Alt+Ctrl+8 { focus-workspace 8; }
Alt+Ctrl+9 { focus-workspace 9; }
// You can refer to workspaces by index. However, keep in mind that
// niri is a dynamic workspace system, so these commands are kind of
// "best effort". Trying to refer to a workspace index bigger than
// the current workspace count will instead refer to the bottommost
// (empty) workspace.
//
// For example, with 2 workspaces + 1 empty, indices 3, 4, 5 and so on
// will all refer to the 3rd workspace.
Mod+1 { focus-workspace 1; }
Mod+2 { focus-workspace 2; }
Mod+3 { focus-workspace 3; }
Mod+4 { focus-workspace 4; }
Mod+5 { focus-workspace 5; }
Mod+6 { focus-workspace 6; }
Mod+7 { focus-workspace 7; }
Mod+8 { focus-workspace 8; }
Mod+9 { focus-workspace 9; }
Alt+Ctrl+1 { focus-workspace 1; }
Alt+Ctrl+2 { focus-workspace 2; }
Alt+Ctrl+3 { focus-workspace 3; }
Alt+Ctrl+4 { focus-workspace 4; }
Alt+Ctrl+5 { focus-workspace 5; }
Alt+Ctrl+6 { focus-workspace 6; }
Alt+Ctrl+7 { focus-workspace 7; }
Alt+Ctrl+8 { focus-workspace 8; }
Alt+Ctrl+9 { focus-workspace 9; }
Mod+Shift+1 { move-column-to-workspace 1; }
Alt+Ctrl+Shift+1 { move-column-to-workspace 1; }
Mod+Shift+2 { move-column-to-workspace 2; }
Alt+Ctrl+Shift+2 { move-column-to-workspace 2; }
Mod+Shift+3 { move-column-to-workspace 3; }
Alt+Ctrl+Shift+3 { move-column-to-workspace 3; }
Mod+Shift+4 { move-column-to-workspace 4; }
Alt+Ctrl+Shift+4 { move-column-to-workspace 4; }
Mod+Shift+5 { move-column-to-workspace 5; }
Alt+Ctrl+Shift+5 { move-column-to-workspace 5; }
Mod+Shift+6 { move-column-to-workspace 6; }
Alt+Ctrl+Shift+6 { move-column-to-workspace 6; }
Mod+Shift+7 { move-column-to-workspace 7; }
Alt+Ctrl+Shift+7 { move-column-to-workspace 7; }
Mod+Shift+8 { move-column-to-workspace 8; }
Alt+Ctrl+Shift+8 { move-column-to-workspace 8; }
Mod+Shift+9 { move-column-to-workspace 9; }
Alt+Ctrl+Shift+9 { move-column-to-workspace 9; }
Mod+Shift+1 { move-column-to-workspace 1; }
Alt+Ctrl+Shift+1 { move-column-to-workspace 1; }
Mod+Shift+2 { move-column-to-workspace 2; }
Alt+Ctrl+Shift+2 { move-column-to-workspace 2; }
Mod+Shift+3 { move-column-to-workspace 3; }
Alt+Ctrl+Shift+3 { move-column-to-workspace 3; }
Mod+Shift+4 { move-column-to-workspace 4; }
Alt+Ctrl+Shift+4 { move-column-to-workspace 4; }
Mod+Shift+5 { move-column-to-workspace 5; }
Alt+Ctrl+Shift+5 { move-column-to-workspace 5; }
Mod+Shift+6 { move-column-to-workspace 6; }
Alt+Ctrl+Shift+6 { move-column-to-workspace 6; }
Mod+Shift+7 { move-column-to-workspace 7; }
Alt+Ctrl+Shift+7 { move-column-to-workspace 7; }
Mod+Shift+8 { move-column-to-workspace 8; }
Alt+Ctrl+Shift+8 { move-column-to-workspace 8; }
Mod+Shift+9 { move-column-to-workspace 9; }
Alt+Ctrl+Shift+9 { move-column-to-workspace 9; }
// Alternatively, there are commands to move just a single window:
// Mod+Ctrl+1 { move-window-to-workspace 1; }
// Alternatively, there are commands to move just a single window:
// Mod+Ctrl+1 { move-window-to-workspace 1; }
// Switches focus between the current and the previous workspace.
// Mod+Tab { focus-workspace-previous; }
// Switches focus between the current and the previous workspace.
// Mod+Tab { focus-workspace-previous; }
// The following binds move the focused window in and out of a column.
// If the window is alone, they will consume it into the nearby column to the side.
// If the window is already in a column, they will expel it out.
Mod+BracketLeft { consume-or-expel-window-left; }
Alt+Ctrl+BracketLeft { consume-or-expel-window-left; }
Mod+BracketRight { consume-or-expel-window-right; }
Alt+Ctrl+BracketRight { consume-or-expel-window-right; }
// The following binds move the focused window in and out of a column.
// If the window is alone, they will consume it into the nearby column to the side.
// If the window is already in a column, they will expel it out.
Mod+BracketLeft { consume-or-expel-window-left; }
Alt+Ctrl+BracketLeft { consume-or-expel-window-left; }
Mod+BracketRight { consume-or-expel-window-right; }
Alt+Ctrl+BracketRight { consume-or-expel-window-right; }
// Consume one window from the right to the bottom of the focused column.
Mod+Comma { consume-window-into-column; }
// Expel the bottom window from the focused column to the right.
Mod+Period { expel-window-from-column; }
// Consume one window from the right to the bottom of the focused column.
Mod+Comma { consume-window-into-column; }
// Expel the bottom window from the focused column to the right.
Mod+Period { expel-window-from-column; }
Mod+R { switch-preset-column-width; }
Mod+Shift+R { switch-preset-window-height; }
Mod+Ctrl+R { reset-window-height; }
Mod+F { maximize-column; }
Mod+Shift+F { fullscreen-window; }
Mod+R { switch-preset-column-width; }
Mod+Shift+R { switch-preset-window-height; }
Mod+Ctrl+R { reset-window-height; }
Mod+F { maximize-column; }
Mod+Shift+F { fullscreen-window; }
// Expand the focused column to space not taken up by other fully visible columns.
// Makes the column "fill the rest of the space".
Mod+Ctrl+F { expand-column-to-available-width; }
// Expand the focused column to space not taken up by other fully visible columns.
// Makes the column "fill the rest of the space".
Mod+Ctrl+F { expand-column-to-available-width; }
Mod+C { center-column; }
Mod+C { center-column; }
// Center all fully visible columns on screen.
Mod+Ctrl+C { center-visible-columns; }
// Center all fully visible columns on screen.
Mod+Ctrl+C { center-visible-columns; }
// Finer width adjustments.
// This command can also:
// * set width in pixels: "1000"
// * adjust width in pixels: "-5" or "+5"
// * set width as a percentage of screen width: "25%"
// * adjust width as a percentage of screen width: "-10%" or "+10%"
// Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0,
// set-column-width "100" will make the column occupy 200 physical screen pixels.
Mod+Minus { set-column-width "-10%"; }
Alt+Ctrl+Minus { set-column-width "-10%"; }
Mod+Equal { set-column-width "+10%"; }
Alt+Ctrl+Equal { set-column-width "+10%"; }
// Finer width adjustments.
// This command can also:
// * set width in pixels: "1000"
// * adjust width in pixels: "-5" or "+5"
// * set width as a percentage of screen width: "25%"
// * adjust width as a percentage of screen width: "-10%" or "+10%"
// Pixel sizes use logical, or scaled, pixels. I.e. on an output with scale 2.0,
// set-column-width "100" will make the column occupy 200 physical screen pixels.
Mod+Minus { set-column-width "-10%"; }
Alt+Ctrl+Minus { set-column-width "-10%"; }
Mod+Equal { set-column-width "+10%"; }
Alt+Ctrl+Equal { set-column-width "+10%"; }
// Finer height adjustments when in column with other windows.
Mod+Shift+Minus { set-window-height "-10%"; }
Alt+Ctrl+Shift+Minus { set-window-height "-10%"; }
Mod+Shift+Equal { set-window-height "+10%"; }
Alt+Ctrl+Shift+Equal { set-window-height "+10%"; }
// Finer height adjustments when in column with other windows.
Mod+Shift+Minus { set-window-height "-10%"; }
Alt+Ctrl+Shift+Minus { set-window-height "-10%"; }
Mod+Shift+Equal { set-window-height "+10%"; }
Alt+Ctrl+Shift+Equal { set-window-height "+10%"; }
// Move the focused window between the floating and the tiling layout.
Mod+V { toggle-window-floating; }
Alt+Ctrl+V { toggle-window-floating; }
Mod+Shift+V { switch-focus-between-floating-and-tiling; }
Alt+Ctrl+Shift+V { switch-focus-between-floating-and-tiling; }
// Move the focused window between the floating and the tiling layout.
Mod+V { toggle-window-floating; }
Alt+Ctrl+V { toggle-window-floating; }
Mod+Shift+V { switch-focus-between-floating-and-tiling; }
Alt+Ctrl+Shift+V { switch-focus-between-floating-and-tiling; }
// Toggle tabbed column display mode.
// Windows in this column will appear as vertical tabs,
// rather than stacked on top of each other.
Mod+W { toggle-column-tabbed-display; }
// Toggle tabbed column display mode.
// Windows in this column will appear as vertical tabs,
// rather than stacked on top of each other.
Mod+W { toggle-column-tabbed-display; }
// Actions to switch layouts.
// Note: if you uncomment these, make sure you do NOT have
// a matching layout switch hotkey configured in xkb options above.
// Having both at once on the same hotkey will break the switching,
// since it will switch twice upon pressing the hotkey (once by xkb, once by niri).
// Mod+Space { switch-layout "next"; }
// Mod+Shift+Space { switch-layout "prev"; }
// Actions to switch layouts.
// Note: if you uncomment these, make sure you do NOT have
// a matching layout switch hotkey configured in xkb options above.
// Having both at once on the same hotkey will break the switching,
// since it will switch twice upon pressing the hotkey (once by xkb, once by niri).
// Mod+Space { switch-layout "next"; }
// Mod+Shift+Space { switch-layout "prev"; }
Mod+P { spawn "~/.config/niri/copy-latest-screenshot.sh"; }
Mod+Ctrl+P { screenshot-screen; }
Mod+Alt+P { screenshot-window; }
Mod+P { spawn "~/.config/niri/copy-latest-screenshot.sh"; }
Mod+Ctrl+P { screenshot-screen; }
Mod+Alt+P { screenshot-window; }
// Applications such as remote-desktop clients and software KVM switches may
// request that niri stops processing the keyboard shortcuts defined here
// so they may, for example, forward the key presses as-is to a remote machine.
// It's a good idea to bind an escape hatch to toggle the inhibitor,
// so a buggy application can't hold your session hostage.
//
// The allow-inhibiting=false property can be applied to other binds as well,
// which ensures niri always processes them, even when an inhibitor is active.
Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
// Applications such as remote-desktop clients and software KVM switches may
// request that niri stops processing the keyboard shortcuts defined here
// so they may, for example, forward the key presses as-is to a remote machine.
// It's a good idea to bind an escape hatch to toggle the inhibitor,
// so a buggy application can't hold your session hostage.
//
// The allow-inhibiting=false property can be applied to other binds as well,
// which ensures niri always processes them, even when an inhibitor is active.
Mod+Escape allow-inhibiting=false { toggle-keyboard-shortcuts-inhibit; }
// The quit action will show a confirmation dialog to avoid accidental exits.
Mod+Shift+E { quit; }
// The quit action will show a confirmation dialog to avoid accidental exits.
Mod+Shift+E { quit; }
// Powers off the monitors. To turn them back on, do any input like
// moving the mouse or pressing any other key.
Mod+Shift+P { power-off-monitors; }
// Powers off the monitors. To turn them back on, do any input like
// moving the mouse or pressing any other key.
Mod+Shift+P { power-off-monitors; }
// DMS
Mod+Space hotkey-overlay-title="Application Launcher" {
@@ -525,7 +545,7 @@ binds {
}
Ctrl+Alt+Delete hotkey-overlay-title="Task Manager" {
spawn "dms" "ipc" "call" "processlist" "toggle";
}
}
Mod+N hotkey-overlay-title="Notification Center" {
spawn "dms" "ipc" "call" "notifications" "toggle";
}
@@ -536,7 +556,7 @@ binds {
spawn "dms" "ipc" "call" "dankdash" "wallpaper";
}
// Mod+Shift+N hotkey-overlay-title="Notepad" {
// spawn "dms" "ipc" "call" "notepad" "toggle";
// spawn "dms" "ipc" "call" "notepad" "toggle";
// }
Super+L hotkey-overlay-title="Lock Screen" {
spawn "dms" "ipc" "call" "lock" "lock";
@@ -570,8 +590,11 @@ binds {
}
environment {
ELECTRON_OZONE_PLATFORM_HINT "auto"
ELECTRON_OZONE_PLATFORM_HINT "auto"
DISPLAY ":0"
// GTK/QT theming - Qt apps use GTK3 style
QT_QPA_PLATFORMTHEME "gtk3"
QT_QPA_PLATFORMTHEME_QT6 "gtk3"
// NOTE: leaving IM modules unset so dead-key compose uses ~/.XCompose
// GTK_IM_MODULE "ibus"
// QT_IM_MODULE "ibus"
@@ -579,8 +602,8 @@ environment {
}
cursor {
hide-when-typing
// hide-after-inactive-ms 1000
hide-when-typing
// hide-after-inactive-ms 1000
}
// Required for clipboard history integration
@@ -593,5 +616,5 @@ spawn-at-startup "/usr/lib/mate-polkit/polkit-mate-authentication-agent-1"
// If using niri newer than 271534e115e5915231c99df287bbfe396185924d (~aug 17 2025)
// you can add this to disable built in config load errors since dank shell provides this
config-notification {
disable-failed
disable-failed
}
+5
View File
@@ -0,0 +1,5 @@
return {
cmd = { "nixd" },
filetypes = { "nix" },
root_markers = { "flake.nix", ".git" },
}
+10
View File
@@ -32,6 +32,16 @@ return {
end,
})
-- Nix files use spaces (2) to match alejandra formatter
vim.api.nvim_create_autocmd("FileType", {
pattern = "nix",
callback = function()
vim.bo.expandtab = true
vim.bo.shiftwidth = 2
vim.bo.tabstop = 2
end,
})
vim.api.nvim_create_user_command("Format", function(args)
local range = nil
if args.count ~= -1 then
+4 -16
View File
@@ -1,7 +1,4 @@
return {
-- Mason for installing LSP servers
{ "mason-org/mason.nvim", opts = {} },
"WhoIsSethDaniel/mason-tool-installer.nvim",
-- Useful status updates for LSP.
{ "j-hui/fidget.nvim", opts = {} },
@@ -122,7 +119,9 @@ return {
end, "[T]oggle Inlay [H]ints")
end
-- Svelte-specific: notify on TS/JS file changes
-- Svelte-specific: keep treesitter highlighting in control
-- (semantic tokens can make svelte buffers look oddly colored)
-- and notify on TS/JS file changes
-- https://github.com/sveltejs/language-tools/issues/2008#issuecomment-2351976230
if client and client.name == "svelte" then
vim.api.nvim_create_autocmd("BufWritePost", {
@@ -178,18 +177,6 @@ return {
})
-- Install tools via mason-tool-installer
require("mason-tool-installer").setup({
ensure_installed = {
"stylua",
"lua-language-server",
"pyright",
"css-lsp",
"eslint-lsp",
"vtsls",
"tailwindcss-language-server",
"biome",
},
})
-- Load custom LSP configs from nvim/lsp/*.lua to override nvim-lspconfig defaults
local lsp_path = vim.fn.stdpath("config") .. "/lsp"
@@ -215,6 +202,7 @@ return {
"svelte",
"tailwindcss",
"biome",
"nixd",
})
end,
},
+118 -21
View File
@@ -51,27 +51,29 @@ return {
-- end,
-- desc = "Git Blame Line",
-- },
{
"<leader>gf",
function()
Snacks.lazygit.log_file()
end,
desc = "Lazygit Current File History",
},
{
"<leader>lg",
function()
Snacks.lazygit()
end,
desc = "Lazygit",
},
{
"<leader>gl",
function()
Snacks.lazygit.log()
end,
desc = "Lazygit Log (cwd)",
},
--
-- Commented out LazyGit in favor of separated jj
-- {
-- "<leader>gf",
-- function()
-- Snacks.lazygit.log_file()
-- end,
-- desc = "Lazygit Current File History",
-- },
-- {
-- "<leader>lg",
-- function()
-- Snacks.lazygit()
-- end,
-- desc = "Lazygit",
-- },
-- {
-- "<leader>gl",
-- function()
-- Snacks.lazygit.log()
-- end,
-- desc = "Lazygit Log (cwd)",
-- },
{
"<leader>dn",
function()
@@ -215,6 +217,101 @@ return {
desc = "Recent",
},
-- git
{
"<leader>gcb",
function()
local cwd = vim.fn.getcwd()
-- Helper to run git commands and capture both stdout and stderr
local function git_cmd(cmd)
local full_cmd = "cd " .. vim.fn.shellescape(cwd) .. " && " .. cmd .. " 2>&1"
local handle = io.popen(full_cmd)
local result = handle and handle:read("*a") or ""
if handle then
handle:close()
end
return result:gsub("%s+$", "")
end
-- Check if in a git repo
local git_dir = git_cmd("git rev-parse --git-dir")
if git_dir == "" or git_dir:match("^fatal") then
vim.notify("Not in a git repository", vim.log.levels.WARN)
return
end
-- Get the default branch
local function branch_exists(branch)
local result = git_cmd("git rev-parse --verify refs/remotes/origin/" .. branch)
-- If branch exists, rev-parse returns a hash; if not, it returns fatal error
return not result:match("^fatal")
end
local default_branch = nil
if branch_exists("main") then
default_branch = "main"
elseif branch_exists("master") then
default_branch = "master"
end
if not default_branch then
vim.notify("No origin/main or origin/master found", vim.log.levels.WARN)
return
end
-- Get current branch
local current_branch = git_cmd("git branch --show-current")
if current_branch == "" then
current_branch = "HEAD"
end
local compare_target = "origin/" .. default_branch
-- Get files that differ from origin/main (includes committed + uncommitted changes)
local result = git_cmd("git diff --name-only " .. compare_target)
-- Also get untracked files
local untracked = git_cmd("git ls-files --others --exclude-standard")
-- Combine results
local all_files = {}
local seen = {}
for line in result:gmatch("[^\r\n]+") do
if line ~= "" and not seen[line] then
seen[line] = true
table.insert(all_files, { text = line, file = line })
end
end
for line in untracked:gmatch("[^\r\n]+") do
if line ~= "" and not seen[line] then
seen[line] = true
table.insert(all_files, { text = line .. " [untracked]", file = line })
end
end
if #all_files == 0 then
vim.notify("No modified files (vs " .. compare_target .. ")", vim.log.levels.INFO)
return
end
Snacks.picker({
title = "Modified Files (vs " .. compare_target .. ")",
items = all_files,
layout = { preset = "default" },
confirm = function(picker, item)
picker:close()
if item and item.text then
-- Strip [untracked] suffix if present
local file = item.text:gsub(" %[untracked%]$", "")
vim.cmd("edit " .. vim.fn.fnameescape(file))
end
end,
})
end,
desc = "Git Modified Files (vs origin/main)",
},
{
"<leader>gb",
function()
+1
View File
@@ -1,3 +1,4 @@
return {
"sQVe/sort.nvim",
-- test
}
+69 -5
View File
@@ -4,17 +4,17 @@ return {
lazy = false,
build = ":TSUpdate",
config = function()
require("nvim-treesitter").setup({
local ts = require("nvim-treesitter")
ts.setup({
install_dir = vim.fn.stdpath("data") .. "/site",
})
-- Install parsers (async, no-op if already installed)
require("nvim-treesitter").install({
ts.install({
"vimdoc",
"javascript",
"typescript",
"tsx",
"ripple",
"c",
"lua",
"rust",
@@ -26,14 +26,78 @@ return {
"css",
"scss",
"gdscript",
"nix",
})
-- Enable treesitter highlighting and indentation
vim.api.nvim_create_autocmd("FileType", {
pattern = {
"svelte",
"javascript",
"typescript",
"tsx",
"html",
"css",
"lua",
"nix",
},
callback = function()
pcall(vim.treesitter.start)
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
end,
})
-- Workaround: some svelte parser/query combos don't inject JS for <script>
-- blocks without an explicit lang attribute, which leaves raw_text as @none.
vim.treesitter.query.set("svelte", "injections", [=[
; inherits: html_tags
((style_element
(start_tag
(attribute
(attribute_name) @_attr
(quoted_attribute_value
(attribute_value) @_lang)))
(raw_text) @injection.content)
(#eq? @_attr "lang")
(#any-of? @_lang "scss" "postcss" "less")
(#set! injection.language "scss"))
; fallback for plain <script>...</script>
((script_element
(raw_text) @injection.content)
(#set! injection.language "javascript"))
((script_element
(start_tag
(attribute
(attribute_name) @_attr
(quoted_attribute_value
(attribute_value) @_lang)))
(raw_text) @injection.content)
(#eq? @_attr "lang")
(#any-of? @_lang "ts" "typescript")
(#set! injection.language "typescript"))
((script_element
(start_tag
(attribute
(attribute_name) @_attr
(quoted_attribute_value
(attribute_value) @_lang)))
(raw_text) @injection.content)
(#eq? @_attr "lang")
(#any-of? @_lang "js" "javascript")
(#set! injection.language "javascript"))
((element
(start_tag
(attribute
(attribute_name) @_attr
(quoted_attribute_value
(attribute_value) @injection.language)))
(text) @injection.content)
(#eq? @_attr "lang")
(#eq? @injection.language "pug"))
]=])
end,
}
+12
View File
@@ -89,9 +89,21 @@ vim.o.confirm = true
-- vim.o.winborder = "rounded"
-- Clipboard: keep default y/p behavior; over SSH, route + register through OSC52
if vim.env.SSH_TTY then
vim.g.clipboard = "osc52"
end
-- Highlight text on yank
vim.api.nvim_create_autocmd("TextYankPost", {
callback = function()
vim.highlight.on_yank({ timeout = 100 })
end,
})
-- Treat .jsonl files as JSON for syntax highlighting and tree-sitter
vim.filetype.add({
extension = {
jsonl = "json",
},
})
+14
View File
@@ -0,0 +1,14 @@
---@class SigilConfig
---@field target table<string, string|boolean>
---@field ignore? string[]
---@type SigilConfig
local config = {
target = {
linux = "~/.config/openpeon",
default = "~/.config/openpeon",
},
ignore = {},
}
return config
+13
View File
@@ -0,0 +1,13 @@
{
"activePack": "glados",
"volume": 1,
"muted": false,
"enabledCategories": {
"session.start": true,
"task.acknowledge": true,
"task.complete": true,
"task.error": false,
"input.required": true,
"resource.limit": true
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"activePack": "solid_snake",
"volume": 1.5,
"muted": false,
"enabledCategories": {
"session.start": true,
"task.acknowledge": true,
"task.complete": true,
"task.error": false,
"input.required": true,
"resource.limit": true
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"activePack": "glados",
"volume": 1,
"muted": false,
"enabledCategories": {
"session.start": true,
"task.acknowledge": true,
"task.complete": true,
"task.error": false,
"input.required": true,
"resource.limit": true
}
}
+152
View File
@@ -0,0 +1,152 @@
{
"cesp_version": "1.0",
"name": "glados",
"display_name": "GLaDOS (Portal)",
"version": "1.0.0",
"author": {
"name": "DoubleGremlin181",
"github": "DoubleGremlin181"
},
"license": "CC-BY-NC-4.0",
"language": "en",
"categories": {
"session.start": {
"sounds": [
{
"file": "sounds/Hello.mp3",
"label": "Hello",
"sha256": "3f7a7dad42212377c89d66b1367e7d5b7c9b15f66c177ddc5ac56e17da07163f"
},
{
"file": "sounds/IKnowYoureThere.mp3",
"label": "I know you're there. I can feel you here.",
"sha256": "df3780607b7a480fd3968c8aae5e0a397ea956008a5c7a47fecb887a05d61622"
}
]
},
"task.acknowledge": {
"sounds": [
{
"file": "sounds/Yes.mp3",
"label": "Yes",
"sha256": "2e661d48e4b2de23b2c66a4408b5aa2bae40f714f9aae315bb30293e60b40a8b"
},
{
"file": "sounds/KeepDoing.mp3",
"label": "Keep doing whatever it is you think you're doing.",
"sha256": "015f49146d39621855b330828c239621cd5a5c628aa8b404e8c64a6c5064e7d6"
},
{
"file": "sounds/IWas.mp3",
"label": "I was",
"sha256": "71de6cf1bc54245233238a171dc569af9dab5759adee2c841d3874a21092ee91"
},
{
"file": "sounds/Fantastic.mp3",
"label": "Fantastic",
"sha256": "e83dbbd49a68c2bfaac06a4ef61547ddfe88ca9ff7cde700ed8e63498ea19801"
},
{
"file": "sounds/Excellent.mp3",
"label": "Excellent",
"sha256": "300c384febefc6fed2769ac51027a7dbdf1c15a8f20b83b2a01d5213245dd337"
}
]
},
"task.complete": {
"sounds": [
{
"file": "sounds/GoodNews.mp3",
"label": "Good news.",
"sha256": "00a7cb6673a84a28bb515e5da1bc06df7370575cacf62fd99e5549ff2a9ff84c"
},
{
"file": "sounds/Congratulations.mp3",
"label": "Congratulations",
"sha256": "ea99410c40947dcfd156dd3c589e9c74a7eb540ad04cf741f1eadd4d5ec53088"
},
{
"file": "sounds/Goodbye.mp3",
"label": "Goodbye",
"sha256": "d08ce9601a017fe41b21b263be6f91032adde044f04cc116fbe5f4173185785b"
}
]
},
"task.error": {
"sounds": [
{
"file": "sounds/ItAintWorkin.mp3",
"label": "Oh one sec! It ain't working!",
"sha256": "f71cb0ecd7b790c51847bbda44db0a66f3db4ee86cb034f22d9c0ffe6d725856"
},
{
"file": "sounds/WompWomp.mp3",
"label": "Womp Womp",
"sha256": "e18eb16ef56b22c69a4876604b9d2c398a1484eef80dfeda5175eae25d92d63a"
}
]
},
"input.required": {
"sounds": [
{
"file": "sounds/UnableToScan.mp3",
"label": "Unable to scan",
"sha256": "44ebeb68310bf05d9296914e7af7def0ece56f11f22631cd1751661f2ad3b59b"
},
{
"file": "sounds/SoftwareIntrusionDetected.mp3",
"label": "Software intrusion detected",
"sha256": "c85d404d9ea18927ebe8cc7980ea7fc5d880a2542f5852e07d03027c07101346"
},
{
"file": "sounds/CanYouHearMe.mp3",
"label": "Can you hear me?",
"sha256": "e2b823df51e98af0fa0102e0c6f467ba44aa312c94b958eadceb41d8e3895788"
},
{
"file": "sounds/YouHaveANotification.mp3",
"label": "You have a notification.",
"sha256": "d43d5f3ba34143bedc429c02d0596aa41d7f8d9bf4c4fcb5f2bdbab5d6d5b374"
}
]
},
"resource.limit": {
"sounds": [
{
"file": "sounds/BecauseImAPotato.mp3",
"label": "Because I'm a potato.",
"sha256": "319f0c9d9deac001d6528a01a04afe2b93a3cefbda973b06d15c900990965df0"
},
{
"file": "sounds/Potato.mp3",
"label": "Potato.",
"sha256": "12301a446afbc0691ff396deae1e83b416db5fb45b9678a5e2731de231696adc"
},
{
"file": "sounds/StillAPotato.mp3",
"label": "In case you were wondering, yes, I am still a potato.",
"sha256": "fd90a89194ca73d37f9f46d19b3ff654781574111b0d6911083dd3fdc39cd610"
}
]
},
"user.spam": {
"sounds": [
{
"file": "sounds/WhereDidYourLifeGoWrong.mp3",
"label": "Where did your life go so wrong?",
"sha256": "20224cb1ee16b8abd121f98bce80fac591ea4933609b240218a83c2255574604"
},
{
"file": "sounds/Neurotoxin.mp3",
"label": "Here's a hint. You're gonna wanna pack as much living as you can in the next couple of minutes.",
"sha256": "a51f8e7a456ef7dd1d48c376f792b841a42cd83b9b37f85cf7a3b973f0029ce5"
},
{
"file": "sounds/Unbelievable.mp3",
"label": "Unbelievable",
"sha256": "b170b1ff8f9d03f04c309e0f9eaf869cb801a2f004cd1f41edd29e0521be1837"
}
]
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
# Cut Gustave clips from Clair Obscur voice lines
SOURCE="/tmp/clair-obscur-downloads/gustave.wav"
OUTDIR="$(dirname "$0")/sounds"
mkdir -p "$OUTDIR"
# session.start
ffmpeg -y -i "$SOURCE" -ss 00:00:02.500 -to 00:00:04.500 -c copy "$OUTDIR/expedition-continues-1.wav"
ffmpeg -y -i "$SOURCE" -ss 00:00:04.500 -to 00:00:06.500 -c copy "$OUTDIR/expedition-continues-2.wav"
ffmpeg -y -i "$SOURCE" -ss 00:00:09.000 -to 00:00:10.000 -c copy "$OUTDIR/let-me-help.wav"
# task.complete
ffmpeg -y -i "$SOURCE" -ss 00:08:17.000 -to 00:08:18.400 -c copy "$OUTDIR/tomorrow-comes.wav"
# task.error
ffmpeg -y -i "$SOURCE" -ss 00:01:00.000 -to 00:01:02.000 -c copy "$OUTDIR/this-was-weak.wav"
ffmpeg -y -i "$SOURCE" -ss 00:04:07.500 -to 00:04:11.300 -c copy "$OUTDIR/putain.wav"
# input.required
ffmpeg -y -i "$SOURCE" -ss 00:05:58.200 -to 00:05:59.900 -c copy "$OUTDIR/what-are-we-gonna-do.wav"
echo "Done! Clips saved to $OUTDIR"
ls -la "$OUTDIR"
@@ -0,0 +1,37 @@
{
"name": "Gustave",
"version": "1.0.0",
"author": "Custom",
"description": "Gustave from Clair Obscur: Expedition 33",
"categories": {
"session.start": {
"sounds": [
{"file": "sounds/expedition-continues-1.wav", "label": "The expedition continues"},
{"file": "sounds/expedition-continues-2.wav", "label": "The expedition continues (alt)"},
{"file": "sounds/let-me-help.wav", "label": "Let me help"}
]
},
"task.acknowledge": {
"sounds": []
},
"task.complete": {
"sounds": [
{"file": "sounds/tomorrow-comes.wav", "label": "Tomorrow comes"}
]
},
"task.error": {
"sounds": [
{"file": "sounds/this-was-weak.wav", "label": "This was weak"},
{"file": "sounds/putain.wav", "label": "Putain"}
]
},
"input.required": {
"sounds": [
{"file": "sounds/what-are-we-gonna-do.wav", "label": "What are we gonna do, huh?"}
]
},
"resource.limit": {
"sounds": []
}
}
}
Binary file not shown.
Binary file not shown.
+177
View File
@@ -0,0 +1,177 @@
{
"cesp_version": "1.0",
"name": "peon",
"display_name": "Orc Peon",
"version": "1.0.0",
"author": {
"name": "tonyyont",
"github": "tonyyont"
},
"license": "CC-BY-NC-4.0",
"language": "en",
"categories": {
"session.start": {
"sounds": [
{
"file": "sounds/PeonReady1.wav",
"label": "Ready to work?",
"sha256": "c821c124004af55b1d1bc97261e4f4521e234b78748addd585b3f03711f64584"
},
{
"file": "sounds/PeonWhat1.wav",
"label": "Yes?",
"sha256": "d4f5696d9db6875c80c8dccf95f6d8047a4564b214be90792b8a766e313106a3"
},
{
"file": "sounds/PeonWhat3.wav",
"label": "What you want?",
"sha256": "4e8197030f01cbaef968ddb9566f19bfd68b3af622748238a3049d218bb64eed"
}
]
},
"task.acknowledge": {
"sounds": [
{
"file": "sounds/PeonYes1.wav",
"label": "I can do that.",
"sha256": "a644ec5632e566df6c057e124319884b5123eea5d5f54b04280b097c2231cc0b"
},
{
"file": "sounds/PeonYes2.wav",
"label": "Be happy to.",
"sha256": "1aaee40174ef4f6109dadc1d28edcbcd63eae27bd9e0b520c40c17e988a365d6"
},
{
"file": "sounds/PeonYes3.wav",
"label": "Work, work.",
"sha256": "18669847b60fc5b1bb41327dc075412aeb2a823d5a9d84476ddc2960baffa959"
},
{
"file": "sounds/PeonYes4.wav",
"label": "Okie dokie.",
"sha256": "89b9f19fec29fde3b513cc98bcf1614a6d264850f65e6816a4483ac49dc34cc2"
},
{
"file": "sounds/PeonYesAttack1.wav",
"label": "OK.",
"sha256": "2f22168c1e7ea041286a26d568771d0f89438229555020d6a4a00b4b860c67de"
},
{
"file": "sounds/PeonYesAttack2.wav",
"label": "I can do that.",
"sha256": "bdf41f5f2d94103c8ef7a965701654a3921063920c7d98abd49c85eb064e1707"
},
{
"file": "sounds/PeonYesAttack3.wav",
"label": "Be happy to.",
"sha256": "097361087515743db44ee93bfc4865fc331d270cb512805844610259a012b869"
}
]
},
"task.complete": {
"sounds": [
{
"file": "sounds/PeonReady1.wav",
"label": "Ready to work?",
"sha256": "c821c124004af55b1d1bc97261e4f4521e234b78748addd585b3f03711f64584"
},
{
"file": "sounds/PeonWhat4.wav",
"label": "Something need doing?",
"sha256": "6ee4f9d9f9d2fede1f953a196de8875dba2ffefa0c5c732adad3de45bbaf090e"
},
{
"file": "sounds/PeonYes1.wav",
"label": "I can do that.",
"sha256": "a644ec5632e566df6c057e124319884b5123eea5d5f54b04280b097c2231cc0b"
},
{
"file": "sounds/PeonYes2.wav",
"label": "Be happy to.",
"sha256": "1aaee40174ef4f6109dadc1d28edcbcd63eae27bd9e0b520c40c17e988a365d6"
},
{
"file": "sounds/PeonYes3.wav",
"label": "Work, work.",
"sha256": "18669847b60fc5b1bb41327dc075412aeb2a823d5a9d84476ddc2960baffa959"
},
{
"file": "sounds/PeonYesAttack1.wav",
"label": "OK.",
"sha256": "2f22168c1e7ea041286a26d568771d0f89438229555020d6a4a00b4b860c67de"
},
{
"file": "sounds/PeonYesAttack3.wav",
"label": "Be happy to.",
"sha256": "097361087515743db44ee93bfc4865fc331d270cb512805844610259a012b869"
}
]
},
"task.error": {
"sounds": [
{
"file": "sounds/PeonAngry4.wav",
"label": "Me not that kind of orc!",
"sha256": "39493727ee0dc6f134ee1c666c63240c6c9df77bceb8b529b549aa980d3849df"
},
{
"file": "sounds/PeonDeath.wav",
"label": "Ugh.",
"sha256": "c46dd952a4dca36cc3e71b5594d6b102ad8366380ca411190e38290090d258c8"
}
]
},
"input.required": {
"sounds": [
{
"file": "sounds/PeonWhat4.wav",
"label": "Something need doing?",
"sha256": "6ee4f9d9f9d2fede1f953a196de8875dba2ffefa0c5c732adad3de45bbaf090e"
},
{
"file": "sounds/PeonWhat2.wav",
"label": "Hmm?",
"sha256": "51d3de60bbb1973f291b7059dc1a8c0d44ff7f524d31881c4ab790c5a2922ef2"
},
{
"file": "sounds/PeonWhat3.wav",
"label": "What you want?",
"sha256": "4e8197030f01cbaef968ddb9566f19bfd68b3af622748238a3049d218bb64eed"
},
{
"file": "sounds/PeonWhat1.wav",
"label": "Yes?",
"sha256": "d4f5696d9db6875c80c8dccf95f6d8047a4564b214be90792b8a766e313106a3"
}
]
},
"resource.limit": {
"sounds": [
{
"file": "sounds/PeonWarcry1.wav",
"label": "Why not?",
"sha256": "a8405dccabe1de88a421e77526cc9f89acb6e1c0eb43011e31a63305d2a9c310"
}
]
},
"user.spam": {
"sounds": [
{
"file": "sounds/PeonAngry1.wav",
"label": "Whaaat?",
"sha256": "12383949b2a8241fd6f5a6edc03c0655f9765d0744a7aecc709d6026bb8f4698"
},
{
"file": "sounds/PeonAngry2.wav",
"label": "Me busy, leave me alone!",
"sha256": "bbf910617a548e55a45d2a7ebc74e45fa18e8bc6a3004f84e6e1af94434b146d"
},
{
"file": "sounds/PeonAngry3.wav",
"label": "No time for play.",
"sha256": "cf68875ec1600020d304c4b3c23a0116509acbf8e61d67d30c6d6ffcb9f13b69"
}
]
}
}
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+41
View File
@@ -0,0 +1,41 @@
Creative Commons Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)
This work is licensed under the Creative Commons Attribution-NonCommercial 4.0 International License.
To view a copy of this license, visit:
https://creativecommons.org/licenses/by-nc/4.0/
--------------------------------------------------------------------------------
ATTRIBUTION
Solid Snake Sound Pack
Created by: will
GitHub: https://github.com/will/openpeon-solid-snake
Source Audio: Metal Gear Solid series voice clips
Original Voice Actor: David Hayter
Copyright Holder: Konami Digital Entertainment
These audio clips are used under fair use for personal notification purposes only.
This sound pack is not endorsed by or affiliated with Konami.
--------------------------------------------------------------------------------
LICENSE SUMMARY
You are free to:
- Share: copy and redistribute the material in any medium or format
- Adapt: remix, transform, and build upon the material
Under the following terms:
- Attribution: You must give appropriate credit, provide a link to the license,
and indicate if changes were made.
- NonCommercial: You may not use the material for commercial purposes.
- No additional restrictions: You may not apply legal terms or technological
measures that legally restrict others from doing anything the license permits.
--------------------------------------------------------------------------------
The full legal text of the license is available at:
https://creativecommons.org/licenses/by-nc/4.0/legalcode
@@ -0,0 +1,79 @@
# Solid Snake Sound Pack
**Tactical espionage audio for your coding sessions.**
A [peon-ping](https://github.com/PeonPing/peon-ping) sound pack featuring the legendary Solid Snake from the Metal Gear Solid series. Get iconic voice lines when your AI coding agent needs attention.
## Installation
### Quick Install
```bash
# Install peon-ping if you haven't already
curl -fsSL https://raw.githubusercontent.com/PeonPing/peon-ping/main/install.sh | bash
# Clone this pack
git clone https://github.com/will/openpeon-solid-snake.git
cd openpeon-solid-snake
# Copy to your peon-ping packs directory
cp -r . ~/.claude/hooks/peon-ping/packs/solid_snake/
# Activate the pack
peon packs use solid_snake
```
### Via Registry (Coming Soon)
Once this pack is registered in the [OpenPeon registry](https://github.com/PeonPing/registry), you'll be able to install it directly:
```bash
peon packs install solid_snake
peon packs use solid_snake
```
## What You'll Hear
| Event | Example Quotes |
|---|---|
| **Session starts** | *"Kept you waiting, huh?"*, *"This is Snake"*, *"It's Snake"* |
| **Task acknowledged** | *"Roger that"*, *"Sounds like a plan"*, *"Got it"* |
| **Task complete** | *"Negative, finished"*, *"Watch your friendly fire"*, *"OK"* |
| **Task error** | *"What the hell?"*, *"Damn!"*, *[Snake scream]* |
| **Input required** | *"We've got a job to do"*, *"I need your help"*, *"What am I supposed to do?"* |
| **Resource limit** | *"No"*, *"I can't move"*, *"Running out of time"* |
| **User spam** | *"Give me a break"*, *"You'll pay for that"* |
All 32 voice clips have been volume-normalized for consistent playback.
## Pack Details
- **CESP Version**: 1.0
- **Total Sounds**: 32 MP3 files
- **Language**: English
- **License**: CC-BY-NC-4.0 (for personal/educational use)
- **Audio Sources**: Various Metal Gear Solid games
## Audio Quality
All sounds have been:
- Cleaned and trimmed for quick playback
- Volume normalized using hybrid loudness+peak normalization (-16 LUFS target)
- Encoded at 192 kbps MP3 for quality and small file size
- SHA256 hashed for integrity verification
## Contributing
Found a great Snake quote that's missing? Have suggestions for better sounds? Open an issue or submit a PR!
## Credits
Voice clips are property of Konami and are used under fair use for personal notification purposes. Original voice actor: David Hayter (MGS 1-4, Peace Walker, Ground Zeroes).
Pack created by [@will](https://github.com/will) for the [OpenPeon](https://openpeon.com) sound pack ecosystem.
## Links
- [peon-ping](https://github.com/PeonPing/peon-ping) - Main CLI tool
- [OpenPeon](https://openpeon.com) - CESP spec and pack browser
- [Create your own pack](https://openpeon.com/create) - Pack creation guide
@@ -0,0 +1,208 @@
{
"cesp_version": "1.0",
"name": "solid_snake",
"display_name": "Solid Snake",
"version": "1.0.0",
"description": "Tactical espionage audio - featuring the legendary Solid Snake from the Metal Gear Solid series",
"author": {
"name": "will",
"github": "wsturgiss"
},
"license": "CC-BY-NC-4.0",
"language": "en",
"categories": {
"session.start": {
"sounds": [
{
"file": "sounds/kept_you_waiting_mgs2.mp3",
"label": "Kept you waiting, huh?",
"sha256": "8f252b6401a60d9679bd7f90005f590f286c47a3b8397cdc4ed8a2bf4ec7484c"
},
{
"file": "sounds/snake_thisissnake.mp3",
"label": "This is Snake",
"sha256": "05ac36cb15fb92051c435746fa9f0cf0b8eb3cdd891f3298daece2b1539f1d99"
},
{
"file": "sounds/snake_itssnake.mp3",
"label": "It's Snake",
"sha256": "ae6b47684afd88a9c23c6b92cfbddafa614fd0613dc36ddab489afbd9789e356"
}
]
},
"task.acknowledge": {
"sounds": [
{
"file": "sounds/snake_roger_that.mp3",
"label": "Roger that",
"sha256": "289020f79fd09ac0e83290de54043bef591405264cc5e3bf20cd345c81f3934e"
},
{
"file": "sounds/snake_sounds_like_a_plan.mp3",
"label": "Sounds like a plan",
"sha256": "f707a8844ea5e821f708267a6e3e702056baf3f818c9b72858daef24329cbd82"
},
{
"file": "sounds/snake_hmm.mp3",
"label": "Hmm",
"sha256": "6b2af2cc56973ff0ad5a7d6e417dd0f2a54ec5b8720dbd5d48c33acdb9982112"
},
{
"file": "sounds/snake_gotit.mp3",
"label": "Got it",
"sha256": "d019ef1ae555e2bacbf7429b21d5046f0a726d6d5baa3418d468569e19594b9a"
},
{
"file": "sounds/snake_yes.mp3",
"label": "Yes",
"sha256": "748c4784451890636ffd130a00d89c4c17c79e03b0a03cc2495123e80fbd5856"
}
]
},
"task.complete": {
"sounds": [
{
"file": "sounds/kept_you_waiting_mgs2.mp3",
"label": "Kept you waiting, huh?",
"sha256": "8f252b6401a60d9679bd7f90005f590f286c47a3b8397cdc4ed8a2bf4ec7484c"
},
{
"file": "sounds/snake_negfinished.mp3",
"label": "Negative, finished",
"sha256": "8350fcdbf50d2d7c5ef1b63609ce453cd4900442e57e410118869a2763ecd6a3"
},
{
"file": "sounds/snake_friendly_fire_trimmed.mp3",
"label": "Watch your friendly fire",
"sha256": "ba396e445ef2d950b443280110d075997920941136c933518f0ebb9fa7741e2d"
},
{
"file": "sounds/snake_ok.mp3",
"label": "OK",
"sha256": "4eada7b92f83b6a91abac4419e4c50139714e71cf56a27a21951a0b258f94007"
},
{
"file": "sounds/snake_thatsok.mp3",
"label": "That's OK",
"sha256": "2481194aeb6cd9b1edb15eb72e851894e327d624a38634f311b6d47f8e3cc5ef"
},
{
"file": "sounds/snake_great.mp3",
"label": "Great",
"sha256": "3bc7a004e107978de90f7a2f548456a5e020b7be81ad3d95adf5d47b8c3cf5b3"
}
]
},
"task.error": {
"sounds": [
{
"file": "sounds/snake_scream.mp3",
"label": "Snake scream",
"sha256": "763a97f888c43ad12f0608f8c519872e57ef3a76b89bd770ea4d1bf049c339d2"
},
{
"file": "sounds/snake_what_the_hell.mp3",
"label": "What the hell?",
"sha256": "61f5150aebf09acbda8b737c71156ebf3bc57a79afa8b8d6c19e296981391f81"
},
{
"file": "sounds/snake_damn.mp3",
"label": "Damn",
"sha256": "5254731d1d80dc3613006c8cf1185350e6c4bcf83adb567118866309fae90603"
},
{
"file": "sounds/snake_wth.mp3",
"label": "What the hell",
"sha256": "bb36264cf9f76341a768dcf8d3d8b546f5709b110e02f3f69f955e9725839881"
}
]
},
"input.required": {
"sounds": [
{
"file": "sounds/snake_job_to_do_trimmed.mp3",
"label": "We've got a job to do",
"sha256": "a38cd5a86d18a2e72a8a692996984406cae9c717ce33180758d7c4200d851b32"
},
{
"file": "sounds/snake_whereareu_clean.mp3",
"label": "Where are you?",
"sha256": "b7d45a536f5468ee8cf42b291c0fd42968ea15429124a456889daa732eb6a5fd"
},
{
"file": "sounds/snake_supposedtodo.mp3",
"label": "What am I supposed to do?",
"sha256": "46e3ff90dc018f55d2cd344308135b5d97541c9238543a16dbdb25ab799e0db0"
},
{
"file": "sounds/snake_favor.mp3",
"label": "I need a favor",
"sha256": "57a97aaeb6684a2ee541fd4f0217cc8da10cec129167b24f4a3b98e7c5718828"
},
{
"file": "sounds/snake_needhelp_clean.mp3",
"label": "I need your help",
"sha256": "f9b7ea978f78f8b91bdfe5b5fd5226f304dfb74c7fe72f9d96137f0cd6f204b7"
},
{
"file": "sounds/snake_ulistening.mp3",
"label": "Are you listening?",
"sha256": "0b88cdaef78215b48b0889995df253426faecf013940bcffd46c6b70f242e7f6"
},
{
"file": "sounds/snake_what.mp3",
"label": "What do you mean?",
"sha256": "6f11527a68b63ad20857136f164f62452e015974db060f809559779804f68ae4"
}
]
},
"resource.limit": {
"sounds": [
{
"file": "sounds/snake_no.mp3",
"label": "No",
"sha256": "d6feddf707e6c637dab61941edb0e6beb998dff4e94f27f540c0e5415b5cc2e6"
},
{
"file": "sounds/snake_noway.mp3",
"label": "No way",
"sha256": "019aa8bb1a743c4d6ed0baeb9942b618168930c9fd6d2da8150a29bc6e6428b2"
},
{
"file": "sounds/snake_cantmove.mp3",
"label": "I can't move",
"sha256": "962d8624c33fa9e014be96b2096f4f22bc330a677a7b3fbdf6a0d0f118e8a000"
},
{
"file": "sounds/snake_outtatime.mp3",
"label": "Running out of time",
"sha256": "205e091b160eac359719e0795bee563043101b61de3b8c5d40fef2d7e18dbd0a"
}
]
},
"user.spam": {
"sounds": [
{
"file": "sounds/snake_gimmebreak.mp3",
"label": "Give me a break",
"sha256": "377dd8818f9e3cd9b7bf90bb3e47e3b2e4fc5750a2fcc90866551defd22968d2"
},
{
"file": "sounds/snake_changedcol.mp3",
"label": "You changed the colonel",
"sha256": "608b10064f6bfd0737519f1626d6551be5e2c1197ec176e2f6e772b4880ecad6"
},
{
"file": "sounds/snake_utoldme.mp3",
"label": "You told me",
"sha256": "e80ec43dd4def334b2c1ea282e230d8ea363b8bab2c11fe2e0650dfe3e2c3ec2"
},
{
"file": "sounds/snake_youllpay_clean.mp3",
"label": "You'll pay for that",
"sha256": "5276062c773c6a63fdd9e79c0312b258ae2973c12cb2a80b0bec491f78889b70"
}
]
}
}
}
@@ -0,0 +1,51 @@
{
"name": "solid_snake",
"display_name": "Solid Snake",
"version": "1.0.0",
"description": "Tactical espionage audio - featuring the legendary Solid Snake from the Metal Gear Solid series",
"author": {
"name": "will",
"github": "wsturgiss"
},
"trust_tier": "community",
"categories": [
"session.start",
"task.acknowledge",
"task.complete",
"task.error",
"input.required",
"resource.limit",
"user.spam"
],
"language": "en",
"license": "CC-BY-NC-4.0",
"sound_count": 32,
"total_size_bytes": 1067760,
"source_repo": "wsturgiss/openpeon-solid-snake",
"source_ref": "v1.0.0",
"source_path": "",
"manifest_sha256": "252aaea9da0105be637776938a226d77096a56533d3a2b6fa07d5c6c9686ef7d",
"tags": [
"gaming",
"metal-gear-solid",
"stealth",
"military",
"tactical"
],
"preview_sounds": [
{
"file": "sounds/kept_you_waiting_mgs2.mp3",
"label": "Kept you waiting, huh?"
},
{
"file": "sounds/snake_roger_that.mp3",
"label": "Roger that"
},
{
"file": "sounds/snake_what_the_hell.mp3",
"label": "What the hell?"
}
],
"added": "2026-02-13",
"updated": "2026-02-13"
}

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