From ffec9e25a0e3e46b9fdd3f9cd0793ed548dcb545 Mon Sep 17 00:00:00 2001 From: Steve Beaulac Date: Sat, 18 Jul 2026 12:19:17 -0400 Subject: [PATCH] chore: update dotfiles with new tool configs and pi settings - Add configs for goose, herdr, ostt, fabric, zero, gnupg - Restructure pi models.json (dupont, obelix, bianca, cloudflare) - Update pi settings with new provider lineup, subagent overrides - Add pi permission system, search config - Add desktop entries (RampClient, terminal, tmux) - Add tmux-open script, rename battery.sh -> battery - Refactor fish config (simplify conditionals, fix nvim aliases) - Switch worktrunk commit command from opencode to pi - Update mise.toml with new tool symlinks - Fix mise auth.json path reference --- config/agents/AGENTS.md | 2 + config/agents/prompts/.empty | 0 config/fabric/config.yaml | 32 +++ config/fish/config.fish | 19 +- config/foot/foot.ini | 2 +- config/gnupg/common.conf | 1 + config/gnupg/gpg-agent.conf | 3 + config/gnupg/gpg.conf | 2 + config/goose/config.yaml | 189 ++++++++++++++++++ config/herdr/config.toml | 15 ++ config/mise/config.toml | 9 +- config/ostt/ostt.toml | 21 ++ .../pi-permission-system/config.json | 24 +++ config/pi/agent/models.json | 161 +++++++++------ config/pi/agent/search-config.json | 13 ++ config/pi/agent/settings.json | 57 +++++- config/ssh/config.d/default | 2 - config/worktrunk/config.toml | 2 +- config/zero/config.json | 20 ++ desktop/RampClient.desktop | 10 + desktop/terminal.desktop | 11 + desktop/tmux.desktop | 9 + mise.toml | 14 ++ script/{battery.sh => battery} | 0 script/tmux-open | 115 +++++++++++ 25 files changed, 651 insertions(+), 82 deletions(-) create mode 100644 config/agents/prompts/.empty create mode 100644 config/fabric/config.yaml create mode 100644 config/gnupg/common.conf create mode 100644 config/gnupg/gpg-agent.conf create mode 100644 config/gnupg/gpg.conf create mode 100644 config/goose/config.yaml create mode 100644 config/herdr/config.toml create mode 100644 config/ostt/ostt.toml create mode 100644 config/pi/agent/extensions/pi-permission-system/config.json create mode 100644 config/pi/agent/search-config.json create mode 100644 config/zero/config.json create mode 100644 desktop/RampClient.desktop create mode 100644 desktop/terminal.desktop create mode 100644 desktop/tmux.desktop rename script/{battery.sh => battery} (100%) create mode 100755 script/tmux-open diff --git a/config/agents/AGENTS.md b/config/agents/AGENTS.md index e69de29..e20b6be 100644 --- a/config/agents/AGENTS.md +++ b/config/agents/AGENTS.md @@ -0,0 +1,2 @@ +- When reporting information to me, be extremely concise and sacrifice grammar for the sake of concision. +- My obsidian vault is located a /home/sjb/Documents/sjb-brain diff --git a/config/agents/prompts/.empty b/config/agents/prompts/.empty new file mode 100644 index 0000000..e69de29 diff --git a/config/fabric/config.yaml b/config/fabric/config.yaml new file mode 100644 index 0000000..425c5c6 --- /dev/null +++ b/config/fabric/config.yaml @@ -0,0 +1,32 @@ +#this is an example yaml config file for fabric + +# use fabric pattern names +# pattern: ai + +# or use a filename +# pattern: ~/testpattern.md + +# model: openai/gpt-5.2 + +# for models that support context length +modelContextLength: 6000 + +#frequencypenalty: 0.5 +#presencepenalty: 0.5 +#topp: 0.67 +#topp: 0.0 +#seed: 42 +#temperature: 0.88 +#temperature: 1.0 + +stream: true +raw: true + +# suppress vendor thinking output +suppressThink: false +thinkStartTag: "" +thinkEndTag: "" + +# OpenAI Responses API settings +# (use this for llama-server or other OpenAI-compatible local servers) +disableResponsesAPI: true diff --git a/config/fish/config.fish b/config/fish/config.fish index 9875c9b..b837c4d 100644 --- a/config/fish/config.fish +++ b/config/fish/config.fish @@ -32,6 +32,7 @@ if status is-interactive if command -q fzf /usr/bin/fzf --fish | source end + command -q nmcli && alias nmlist "nmcli device wifi list" if command -q tree @@ -50,13 +51,10 @@ if status is-interactive if command -q nvim set -gx EDITOR nvim - end - - if command -q v alias oo="cd ~/Documents/nca-notes/" - alias on="v +Obsidian new" - alias os="v +Obsidian search" - end + alias on="nvim +Obsidian new" + alias os="nvim +Obsidian search" + end command -q jj && alias rev "jj log -G -T 'commit_id.short(8)'" @@ -80,13 +78,8 @@ if status is-interactive alias ls="eza -al --color=always --group-directories-first" end - if command -q bat - alias cat="bat" - end - - if command -q git - alias g=git - end + command -q bat && alias cat="bat" + command -q git && alias g=git set -gx VISUAL $EDITOR diff --git a/config/foot/foot.ini b/config/foot/foot.ini index 3bd1f40..3b4ea93 100644 --- a/config/foot/foot.ini +++ b/config/foot/foot.ini @@ -4,7 +4,7 @@ term=xterm-256color pad=6x6 initial-window-mode=windowed workers=0 -include=~/.local/share/themes/current/theme/foot.ini +include=~/.config/omarchy/current/theme/foot.ini [scrollback] lines=10000 diff --git a/config/gnupg/common.conf b/config/gnupg/common.conf new file mode 100644 index 0000000..5add401 --- /dev/null +++ b/config/gnupg/common.conf @@ -0,0 +1 @@ +use-keyboxd diff --git a/config/gnupg/gpg-agent.conf b/config/gnupg/gpg-agent.conf new file mode 100644 index 0000000..774efd5 --- /dev/null +++ b/config/gnupg/gpg-agent.conf @@ -0,0 +1,3 @@ +enable-ssh-support +default-cache-ttl 60 +max-cache-ttl 120 diff --git a/config/gnupg/gpg.conf b/config/gnupg/gpg.conf new file mode 100644 index 0000000..221abf7 --- /dev/null +++ b/config/gnupg/gpg.conf @@ -0,0 +1,2 @@ +utf8-strings +use-agent diff --git a/config/goose/config.yaml b/config/goose/config.yaml new file mode 100644 index 0000000..d2fb342 --- /dev/null +++ b/config/goose/config.yaml @@ -0,0 +1,189 @@ +extensions: + extensionmanager: + enabled: true + type: platform + name: Extension Manager + description: Enable extension management tools for discovering, enabling, and disabling extensions + display_name: Extension Manager + bundled: true + available_tools: [] + chatrecall: + enabled: false + type: platform + name: chatrecall + description: Search past conversations and load session summaries for contextual memory + display_name: Chat Recall + bundled: true + available_tools: [] + skills: + enabled: true + type: platform + name: skills + description: Discover and provide skill instructions from filesystem and builtins + display_name: Skills + bundled: true + available_tools: [] + todo: + enabled: true + type: platform + name: todo + description: Enable a todo list for goose so it can keep track of what it is doing + display_name: Todo + bundled: true + available_tools: [] + code_execution: + enabled: true + type: platform + name: code_execution + description: Goose will make extension calls through code execution, saving tokens + display_name: Code Mode + bundled: true + available_tools: [] + memory: + enabled: true + type: builtin + name: memory + description: Tools to save and retrieve durable memories + display_name: Memory + timeout: 300 + bundled: true + available_tools: [] + computercontroller: + enabled: true + type: builtin + name: computercontroller + description: controls for webscraping, file caching, and automations + display_name: Computer Controller + timeout: 300 + bundled: true + available_tools: [] + developer: + enabled: true + type: platform + name: developer + description: Write and edit files, and execute shell commands + display_name: Developer + bundled: true + available_tools: [] + apps: + enabled: true + type: platform + name: apps + description: Create and manage custom Goose apps through chat. Apps are HTML/CSS/JavaScript and run in sandboxed windows. + display_name: Apps + bundled: true + available_tools: [] + tom: + enabled: true + type: platform + name: tom + description: Inject custom context into every turn via GOOSE_MOIM_MESSAGE_TEXT and GOOSE_MOIM_MESSAGE_FILE environment variables + display_name: Top Of Mind + bundled: true + available_tools: [] + summon: + enabled: true + type: platform + name: summon + description: Load knowledge and delegate tasks to subagents + display_name: Summon + bundled: true + available_tools: [] + analyze: + enabled: true + type: platform + name: analyze + description: 'Analyze code structure with tree-sitter: directory overviews, file details, symbol call graphs' + display_name: Analyze + bundled: true + available_tools: [] + summarize: + enabled: false + type: platform + name: summarize + description: Load files/directories and get an LLM summary in a single call + display_name: Summarize + bundled: true + available_tools: [] + orchestrator: + enabled: false + type: platform + name: orchestrator + description: 'Manage agent sessions: list, view, start, send messages, interrupt, and stop agents' + display_name: Orchestrator + bundled: true + available_tools: [] + autovisualiser: + enabled: false + type: builtin + name: autovisualiser + description: Data visualization and UI generation tools + display_name: Auto Visualiser + timeout: 300 + bundled: true + available_tools: [] + tutorial: + enabled: false + type: builtin + name: tutorial + description: Access interactive tutorials and guides + display_name: Tutorial + timeout: 300 + bundled: true + available_tools: [] +GOOSE_TELEMETRY_ENABLED: false +OLLAMA_HOST: 192.168.33.74:11434 +CHATGPT_CODEX_REASONING_EFFORT: medium +providers: + chatgpt_codex: + enabled: true + model: gpt-5.5 + configured: true + github_copilot: + enabled: true + model: gpt-5-mini + configured: true + custom_opencode_zen: + enabled: true + model: north-mini-code-free + configured: true + ollama: + enabled: true + model: qwen3.6:35b + configured: true + custom_sagacity: + enabled: true + model: gemma4:31b + configured: true + custom_opencode_go: + enabled: true + model: mimo-v2.5-pro + configured: true + opencode_go: + enabled: true + model: deepseek-v4-flash + configured: true + custom_allears: + enabled: true + model: qwen3.6:35b + configured: true + custom_obelix: + enabled: true + model: north-mini-code-1.0 + configured: true + custom_dupont: + enabled: true + model: north-mini-code-1.0 + configured: true +active_provider: opencode_go +GOOSE_THINKING_EFFORT: off +voice_dictation_provider: openai +GOOSE_MODE: auto +OLLAMA_TIMEOUT: '600' +SECURITY_PROMPT_ENABLED: false +SECURITY_PROMPT_CLASSIFIER_ENABLED: false +SECURITY_PROMPT_CLASSIFIER_MODEL: '' +OPENAI_BASE_URL: https://opencode.ai/zen/go/ +OPENAI_HOST: https://api.openai.com +OPENAI_BASE_PATH: v1/chat/completions +OPENAI_TIMEOUT: '600' diff --git a/config/herdr/config.toml b/config/herdr/config.toml new file mode 100644 index 0000000..02b77fd --- /dev/null +++ b/config/herdr/config.toml @@ -0,0 +1,15 @@ +onboarding = false +[ui] +show_agent_labels_on_pane_borders = true +pane_gaps = false +pane_borders = true + +[experimental] +pane_history = true + +[theme] +name = "gruvbox" +auto_switch = false + +[keys] +prefix = "ctrl+space" diff --git a/config/mise/config.toml b/config/mise/config.toml index b500ce8..b0c3b35 100644 --- a/config/mise/config.toml +++ b/config/mise/config.toml @@ -10,6 +10,7 @@ copilot-cli = "latest" "github:danielmiessler/fabric" = "latest" "github:mrusme/reader" = "latest" "github:ulyssa/iamb" = "latest" +"github:zed-industries/codex-acp" = "latest" herdr = "latest" "npm:@earendil-works/pi-coding-agent" = "latest" "npm:mermaid-cli" = "latest" @@ -25,10 +26,16 @@ run = [ 'pi install npm:@tintinweb/pi-subagents', 'pi install npm:context-mode', 'pi install npm:@gotgenes/pi-permission-system', - 'test -x /usr/bin/pass && /usr/bin/pass show agent/pi/auth.json > ~/.pi/agent/auth.json' + 'test -x /usr/bin/pass && /usr/bin/pass show config/pi/auth.json > ~/.pi/agent/auth.json' ] [tasks.setup_nvim] run = [ 'uv tool install vectorcode' ] + +[tasks.skills] +run = [ + 'npx skills add SjB/skills', + 'npx skills add mattpocock/skills' +] diff --git a/config/ostt/ostt.toml b/config/ostt/ostt.toml new file mode 100644 index 0000000..f4f4f7a --- /dev/null +++ b/config/ostt/ostt.toml @@ -0,0 +1,21 @@ +config_version = "0.0.25" + +[transcription] +provider = "whisper" +model = "small" + +[audio] +device = "default" +output_format = "mp3 -ab 16k -ar 12000" +peak_volume_threshold = 90 +reference_level_db = -20 +visualization = "spectrum" + +[popup] +#terminal = "foot" +borderless = true +font_size = 25 +height = 15 +width = 90 +x = 630 +y = 790 diff --git a/config/pi/agent/extensions/pi-permission-system/config.json b/config/pi/agent/extensions/pi-permission-system/config.json new file mode 100644 index 0000000..81bfaa0 --- /dev/null +++ b/config/pi/agent/extensions/pi-permission-system/config.json @@ -0,0 +1,24 @@ +{ + "permission": { + "*": "ask", + "path": { + "./*": "allow", + "./.*": "allow", + "~/.ssh/*": "deny", + "*.env": "deny", + "*.env.*": "deny", + "*.env.example": "allow" + }, + "bash": { + "*": "ask", + "rm -rf *": "deny", + "sudo *": "ask" + }, + "external_directory": { + "*": "deny" + } + }, + "debugLog": false, + "permissionReviewLog": true, + "yoloMode": true +} diff --git a/config/pi/agent/models.json b/config/pi/agent/models.json index c1f95d8..a39587a 100644 --- a/config/pi/agent/models.json +++ b/config/pi/agent/models.json @@ -1,61 +1,108 @@ { - "providers": { - "dupont": { - "baseUrl": "http://172.25.11.30/v1", - "api": "openai-completions", - "models": [ - { - "id": "north-mini-code", - "name": "north-mini-code", - "reasoning": true, - "input": ["text"], - "contextWindow": 128000, - "maxTokens": 128000, - "cost": { "input": 1, "output": 1, "cacheRead": 1, "cacheWrite": 1 } + "providers": { + "dupont": { + "baseUrl": "http://172.25.11.30/v1", + "api": "openai-completions", + "models": [ + { + "id": "glm-4.7-flash", + "name": "glm-4.7-flash", + "reasoning": true, + "input": [ + "text" + ], + "contextWindow": 131072, + "maxTokens": 131072, + "cost": { + "input": 1, + "output": 1, + "cacheRead": 1, + "cacheWrite": 1 + } + } + ], + "compat": { + "supportsDeveloperRole": true, + "supportsReasoningEffort": true + } + }, + "obelix": { + "baseUrl": "http://172.25.11.32/v1", + "api": "openai-completions", + "models": [ + { + "id": "ornith-1.0-35B", + "name": "ornith-1.0-35B", + "reasoning": true, + "input": [ + "text" + ], + "contextWindow": 131072, + "maxTokens": 131072, + "cost": { + "input": 1, + "output": 1, + "cacheRead": 1, + "cacheWrite": 1 + } + } + ], + "compat": { + "supportsDeveloperRole": true, + "supportsReasoningEffort": true + } + }, + "bianca": { + "baseUrl": "http://172.25.11.33/v1", + "api": "openai-completions", + "models": [ + { + "id": "gemma-4-12B-coder", + "name": "gemma-4-12B-coder", + "reasoning": true, + "input": [ + "text" + ], + "contextWindow": 128000, + "maxTokens": 65536, + "cost": { + "input": 1, + "output": 1, + "cacheRead": 1, + "cacheWrite": 1 + } + } + ], + "compat": { + "supportsDeveloperRole": true, + "supportsReasoningEffort": true + } + }, + "cloudflare": { + "baseUrl": "https://api.cloudflare.com/client/v4/accounts/e54fa0b493ef3bef55746b1de8d33693/ai/v1", + "api": "openai-completions", + "models": [ + { + "id": "@cf/zai-org/glm-5.2", + "name": "@cf/zai-org/glm-5.2", + "reasoning": true, + "input": [ + "text" + ], + "contextWindow": 256000, + "maxTokens": 256000, + "cost": { + "input": 1, + "output": 1, + "cacheRead": 1, + "cacheWrite": 1 + } + } + ], + "compat": { + "supportsDeveloperRole": true, + "supportsReasoningEffort": true + } } - ], - "compat": { - "supportsDeveloperRole": true, - "supportsReasoningEffort": true - } - }, - "bianca": { - "baseUrl": "http://172.25.11.33/v1", - "api": "openai-completions", - "models": [ - { - "id": "gemma-4-12B-coder", - "name": "gemma-4-12B-coder", - "reasoning": true, - "input": ["text"], - "contextWindow": 128000, - "maxTokens": 65536, - "cost": { "input": 1, "output": 1, "cacheRead": 1, "cacheWrite": 1 } - } - ], - "compat": { - "supportsDeveloperRole": true, - "supportsReasoningEffort": true - } - }, - "cloudflare": { - "baseUrl": "https://api.cloudflare.com/client/v4/accounts/e54fa0b493ef3bef55746b1de8d33693/ai/v1", - "api": "openai-completions", - "models": [ - { - "id": "@cf/zai-org/glm-5.2", - "name": "@cf/zai-org/glm-5.2", - "reasoning": true, - "input": ["text"], - "contextWindow": 256000, - "maxTokens": 256000, - "cost": { "input": 1, "output": 1, "cacheRead": 1, "cacheWrite": 1 } - } - ], - "compat": { - "supportsDeveloperRole": true, - "supportsReasoningEffort": true - } } - } } diff --git a/config/pi/agent/search-config.json b/config/pi/agent/search-config.json new file mode 100644 index 0000000..ad731b7 --- /dev/null +++ b/config/pi/agent/search-config.json @@ -0,0 +1,13 @@ +{ + "enabled": true, + "searchEnabled": true, + "fetchEnabled": true, + "providerOverrides": { + "claude-bridge": { + "searchEnabled": false + }, + "opencode": { + "searchEnabled": true + } + } +} \ No newline at end of file diff --git a/config/pi/agent/settings.json b/config/pi/agent/settings.json index e9348c2..1ba271e 100644 --- a/config/pi/agent/settings.json +++ b/config/pi/agent/settings.json @@ -1,19 +1,62 @@ { - "lastChangelogVersion": "0.80.10", + "lastChangelogVersion": "0.80.7", "theme": "light/dark", - "defaultProvider": "opencode-go", - "defaultModel": "deepseek-v4-flash", - "defaultThinkingLevel": "high", + "defaultProvider": "github-copilot", + "defaultModel": "gpt-5-mini", + "defaultThinkingLevel": "minimal", "hideThinkingBlock": true, "compaction": { "enabled": true }, + "thinkingLevelMap": { + "minimal": null, + "low": "low", + "medium": "medium", + "high": "high", + "xhigh": null, + "max": "max" + }, "enableInstallTelemetry": false, + "enabledModels": [ + "opencode-go/qwen3.7-plus", + "opencode-go/deepseek-v4-pro", + "opencode-go/deepseek-v4-flash", + "opencode-go/kimi-k2.7-code", + "openai-codex/gpt-5.4", + "openai-codex/gpt-5.4-mini", + "openai-codex/gpt-5.3-codex-spark", + "obelix/ornith-1.0-35B", + "dupont/glm-4.7-flash", + "github-copilot/gpt-5-mini", + "github-copilot/mai-code-1-flash-picker" + ], "packages": [ "npm:pi-lens", + "npm:@gotgenes/pi-permission-system", "npm:pi-native-search", - "npm:@tintinweb/pi-subagents", "npm:context-mode", - "npm:@gotgenes/pi-permission-system" - ] + "npm:@tintinweb/pi-subagents" + ], + "subagents": { + "agentOverrides": { + "reviewer": { + "model": "opencode-go/mimo-v2.5-pro", + "fallbackModels": [ + "openai/gpt-5-mini" + ] + }, + "planner": { + "model": "opencode-go/qwen3.7-plus" + }, + "worker": { + "model": "opencode-go/kimi-k2.7-code" + }, + "oracle": { + "model": "opencode-go/qwen3.7-max", + "thinking": "high" + } + } + }, + "quietStartup": true, + "steeringMode": "all" } \ No newline at end of file diff --git a/config/ssh/config.d/default b/config/ssh/config.d/default index 64727bd..befea6d 100644 --- a/config/ssh/config.d/default +++ b/config/ssh/config.d/default @@ -1,3 +1 @@ SetEnv TERM=xterm-256color - - diff --git a/config/worktrunk/config.toml b/config/worktrunk/config.toml index e0674e2..5503fdb 100644 --- a/config/worktrunk/config.toml +++ b/config/worktrunk/config.toml @@ -2,7 +2,7 @@ worktree-path = "{{ repo_path }}/../wt-{{ branch | sanitize }}" [commit.generation] -command = "opencode run -m github-copilot/gpt-5-mini --variant fast" +command = "pi --model github-copilot/gpt-5-mini -p" [post-create] misetrust = "mise trust" diff --git a/config/zero/config.json b/config/zero/config.json new file mode 100644 index 0000000..f621539 --- /dev/null +++ b/config/zero/config.json @@ -0,0 +1,20 @@ +{ + "activeProvider": "chatgpt", + "providers": [ + { + "name": "chatgpt", + "provider_kind": "openai-compatible", + "catalogID": "chatgpt", + "baseURL": "https://chatgpt.com/backend-api/codex", + "apiFormat": "chat-completions", + "model": "gpt-5.5" + } + ], + "mcp": {}, + "sandbox": {}, + "notify": {}, + "tools": {}, + "swarm": {}, + "preferences": {}, + "keybindings": {} +} diff --git a/desktop/RampClient.desktop b/desktop/RampClient.desktop new file mode 100644 index 0000000..9377ed3 --- /dev/null +++ b/desktop/RampClient.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=RampClient PRD +GenericName=Java Web Start Application +Comment=RampClient PRD +Categories=Network;Desktop;Java;Javaws; +Type=Application +Icon=/home/sjb/.config/icedtea-web/icons/b1bfbd7f-6c3e-40cf-8023-752cc6c45b66 +X-Vendor=UWO +Exec="/opt/OpenWebStart/javaws" "https://wts.uwo.ca/ramp/prd/rampclient-prd.jnlp" diff --git a/desktop/terminal.desktop b/desktop/terminal.desktop new file mode 100644 index 0000000..cd9268b --- /dev/null +++ b/desktop/terminal.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Type=Application +Exec=foot +Icon=foot +Terminal=false +Categories=System;TerminalEmulator; +Keywords=shell;prompt;command;commandline; + +Name=Terminal +GenericName=Terminal +Comment=A wayland native terminal emulator diff --git a/desktop/tmux.desktop b/desktop/tmux.desktop new file mode 100644 index 0000000..d721324 --- /dev/null +++ b/desktop/tmux.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Name=Tmux Terminal +Comment=Tmux Terminal +Exec=foot tmux new -A -s main +Terminal=false +Type=Application +Icon=tmux +StartupNotify=true diff --git a/mise.toml b/mise.toml index 5dab48f..ac937dd 100644 --- a/mise.toml +++ b/mise.toml @@ -16,6 +16,7 @@ dotfiles.default_mode = "symlink-each" "~/.config/btop/themes/current.theme" = { source = "~/.config/omarchy/current/theme/btop.theme", mode = "symlink" } "~/.config/emacs" = "config/emacs" "~/.config/environment.d" = "config/environment.d" +"~/.gnupg" = "config/gnupg" "~/.config/environment.d/dotfiles.conf" = { source = "templates/dofiles.conf.tmpl", template = "tera", mode = "template" } "~/.config/fish" = "config/fish" # check if we really need the fisher plugins "~/.config/gdb" = "config/gdb" @@ -23,6 +24,10 @@ dotfiles.default_mode = "symlink-each" "~/.config/ghostty/theme" = { source = "~/.config/omarchy/current/theme/ghostty.conf", mode = "symlink" } "~/.config/git" = "config/git" "~/.config/git/local" = { source = "templates/git-local.tmpl", mode = "template", template = "tera" } +"~/.config/goose" = "config/goose" +"~/.config/herdr" = "config/herdr" +"~/.config/ostt" = "config/ostt" +"~/.config/fabric" = "config/fabric" "~/.config/fontconfig" = { source = "config/fontconfig", mode = "copy" } "~/.config/foot" = "config/foot" "~/.config/hypr" = "config/hypr" @@ -48,15 +53,24 @@ dotfiles.default_mode = "symlink-each" "~/.config/worktrunck" = "config/worktrunk" "~/.config/chromium-flags.conf" = { source = "config/chromium-flags.conf", mode = "symlink" } "~/.profile" = { source = "config/profile", mode = "symlink" } +"~/.config/zero" = "config/zero" "~/.local/share/fonts/" = { source = "fonts", mode = "copy" } +# Desktop files +"~/.local/share/applications/RampClient.desktop" = { source = "desktop/RampClient.desktop", mode = "symlink" } +"~/.local/share/applications/terminal.desktop" = { source = "desktop/terminal.desktop", mode = "symlink" } +"~/.local/share/applications/tmux.desktop" = { source = "desktop/tmux.desktop", mode = "symlink" } + # scripts. "~/.local/bin/hyprland-activeworkspace" = { source = "script/hyprland-activeworkspace", mode = "symlink" } "~/.local/bin/hyprland-keybindings" = { source = "script/hyprland-keybindings", mode = "symlink" } "~/.local/bin/hyprland-fetch-client" = { source = "script/hyprland-fetch-client", mode = "symlink" } "~/.local/bin/hyprland-focus-client" = { source = "script/hyprland-focus-client", mode = "symlink" } +"~/.local/bin/battery" = { source = "script/battery", mode = "symlink" } +# "~/.config/bin/ec" = { source = "script/ec", mode = "symlink" } +"~/.local/bin/tmux-open" = { source = "script/tmux-open", mode = "symlink" } "~/.local/bin/active-workspace" = { source = "script/active-workspace", mode = "symlink" } "~/.local/bin/avr-flash" = { source = "script/avr-flash", mode = "symlink" } "~/.local/bin/dfu-flash" = { source = "script/dfu-flash", mode = "symlink" } diff --git a/script/battery.sh b/script/battery similarity index 100% rename from script/battery.sh rename to script/battery diff --git a/script/tmux-open b/script/tmux-open new file mode 100755 index 0000000..6b50930 --- /dev/null +++ b/script/tmux-open @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +set -euo pipefail + +# tmux-open — open a new tmux window (or session) and run a command +# Usage: tmux-open [-k|--keep] [-h|--help] [args...] + +usage() { + cat <<'EOF' +Usage: tmux-open [-k|--keep] [-h|--help] [args...] + +Open a new tmux window in the current session and run a command. +If not inside tmux, create a new session named after the window and attach. + +Positional arguments: + window-name Name for the new tmux window (and session, if creating one) + start-dir Working directory for the new window + cmd [args...] Command to run (variadic) + +Options: + -k, --keep After the command exits, keep the pane visible (remain-on-exit) + so you can inspect output. Default: pane closes when command exits. + -h, --help Show this help message + +If `mise` is on PATH, the command runs under `mise x`. + +Errors: + - tmux not installed + - fewer than 3 positional args + - start-dir does not exist + - a window with the same name already exists in the current session +EOF +} + +# --- Flag parsing --- +keep_shell=0 +while (( $# > 0 )); do + case "$1" in + -k|--keep) keep_shell=1; shift ;; + -h|--help) usage; exit 0 ;; + --) shift; break ;; + -*) echo "error: unknown option: $1" >&2; usage >&2; exit 1 ;; + *) break ;; + esac +done + +# --- Positional arg validation --- +if (( $# < 3 )); then + echo "error: expected at least 3 positional arguments (window-name, start-dir, cmd)" >&2 + usage >&2 + exit 1 +fi + +window_name="$1"; shift +start_dir="$1"; shift +cmd_args=("$@") + +# --- Pre-flight checks --- +if ! command -v tmux >/dev/null 2>&1; then + echo "error: tmux is not installed or not on PATH" >&2 + exit 1 +fi + +if [[ ! -d "$start_dir" ]]; then + echo "error: directory does not exist: $start_dir" >&2 + exit 1 +fi + +if (( ${#cmd_args[@]} == 0 )); then + echo "error: no command specified" >&2 + exit 1 +fi + +# Duplicate window name check (only relevant inside tmux) +if [[ -n "${TMUX:-}" ]]; then + if tmux list-windows -F '#{window_name}' | grep -Fxq "$window_name"; then + echo "error: a window named '$window_name' already exists in the current session" >&2 + exit 1 + fi +fi + +# --- Detect mise --- +has_mise=0 +if command -v mise >/dev/null 2>&1; then + has_mise=1 +fi + +# --- Build the command for the new window --- +# We need to construct a single shell command string for tmux. +# The command runs; pane closes on exit (or stays visible with --keep via remain-on-exit). + +# Build the inner command based on mode and mise availability +# For argv mode, quote each argument +quoted_args=() +for arg in "${cmd_args[@]}"; do + quoted_args+=("$(printf '%q' "$arg")") +done +if (( has_mise )); then + inner_cmd="mise x -- ${quoted_args[*]}" +else + inner_cmd="${quoted_args[*]}" +fi + +# --- Create window or session --- +if [[ -n "${TMUX:-}" ]]; then + tmux new-window -n "$window_name" -c "$start_dir" "$inner_cmd" + if (( keep_shell )); then + tmux set-option remain-on-exit on + fi +else + tmux new-session -d -n "$window_name" -s "$window_name" -c "$start_dir" "$inner_cmd" + if (( keep_shell )); then + tmux set-option -t "$window_name" remain-on-exit on + fi + tmux attach-session -t "$window_name" +fi