@sebastienrousseau/dotfiles 0.2.500 → 0.2.501
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +77 -0
- package/README.md +82 -44
- package/docs/.vitepress/reports/localization-readability-audit.md +4 -0
- package/docs/AI.md +8 -2
- package/docs/CNAME +1 -0
- package/docs/COPYRIGHT +1 -1
- package/docs/NAMING_CONVENTIONS.md +7 -0
- package/docs/README.md +4 -0
- package/docs/_config.yml +59 -0
- package/docs/adr/ADR-001-ci-cd-pipeline.md +17 -0
- package/docs/adr/ADR-002-shell-performance.md +9 -0
- package/docs/adr/ADR-003-security-first.md +18 -0
- package/docs/adr/ADR-004-cli-architecture.md +14 -0
- package/docs/adr/ADR-005-chezmoi-choice.md +10 -0
- package/docs/adr/ADR-006-shell-selection.md +9 -0
- package/docs/adr/ADR-007-multi-shell-parity.md +10 -1
- package/docs/adr/ADR-008-alias-system-architecture.md +10 -0
- package/docs/adr/ADR-009-wallpaper-driven-theming.md +131 -0
- package/docs/adr/ADR-010-starship-transient-prompt.md +144 -0
- package/docs/adr/ADR-011-nushell-tier3-keep.md +144 -0
- package/docs/adr/README.md +7 -0
- package/docs/architecture/ARCHITECTURE.md +4 -0
- package/docs/architecture/INTEROP.md +8 -0
- package/docs/architecture/REPO_LAYOUT.md +5 -1
- package/docs/architecture/WALKTHROUGH.md +4 -0
- package/docs/architecture/fleet-deployment.md +4 -0
- package/docs/archive/EUXIS_2026_REVIEW.md +11 -3
- package/docs/archive/LEGACY_ROADMAP.md +45 -27
- package/docs/archive/MILESTONE_v0.2.493.md +4 -0
- package/docs/archive/PLAN.md +46 -8
- package/docs/archive/REPO_AUDIT.md +8 -0
- package/docs/guides/INSTALL.md +4 -0
- package/docs/guides/NEOVIM_IDE_GUIDE.md +9 -0
- package/docs/guides/THEMING.md +8 -0
- package/docs/guides/TROUBLESHOOTING.md +28 -0
- package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +70 -1
- package/docs/index.md +6 -2
- package/docs/interop/A2A.md +7 -0
- package/docs/interop/POWERSHELL.md +102 -0
- package/docs/manual/00-introduction.md +5 -1
- package/docs/manual/01-concepts/01-architecture.md +4 -0
- package/docs/manual/01-concepts/02-trust-model.md +6 -2
- package/docs/manual/01-concepts/03-theme-engine.md +4 -0
- package/docs/manual/01-concepts/04-fleet.md +7 -1
- package/docs/manual/01-concepts/05-self-healing.md +8 -1
- package/docs/manual/02-tutorials/01-first-install.md +5 -0
- package/docs/manual/02-tutorials/02-add-wallpaper.md +5 -0
- package/docs/manual/02-tutorials/03-create-profile.md +6 -0
- package/docs/manual/02-tutorials/04-encrypt-secret.md +6 -0
- package/docs/manual/02-tutorials/05-deploy-fleet.md +5 -1
- package/docs/manual/03-reference/01-dot-cli.md +4 -0
- package/docs/manual/03-reference/02-config-files.md +8 -2
- package/docs/manual/03-reference/03-environment.md +4 -0
- package/docs/manual/03-reference/04-templates.md +7 -1
- package/docs/manual/03-reference/05-feature-flags.md +10 -0
- package/docs/manual/04-cookbook/01-recipes.md +4 -0
- package/docs/manual/04-cookbook/02-troubleshooting.md +32 -0
- package/docs/manual/04-cookbook/03-faq.md +8 -0
- package/docs/manual/05-appendices/A-platform-matrix.md +4 -0
- package/docs/manual/05-appendices/B-security-checklist.md +6 -0
- package/docs/manual/05-appendices/C-glossary.md +4 -0
- package/docs/manual/05-appendices/D-bibliography.md +5 -1
- package/docs/manual/05-appendices/E-license.md +4 -0
- package/docs/manual/_toc.yml +1 -1
- package/docs/manual/command-index.md +4 -0
- package/docs/manual/concept-index.md +4 -0
- package/docs/operations/ATTESTATION.md +5 -0
- package/docs/operations/CI_CADENCE.md +107 -0
- package/docs/operations/CI_COMPOSITES.md +156 -0
- package/docs/operations/COMPLETIONS.md +123 -0
- package/docs/operations/COVERAGE.md +148 -0
- package/docs/operations/DRIFT.md +107 -0
- package/docs/operations/MAINTENANCE.md +5 -1
- package/docs/operations/MIGRATION.md +14 -6
- package/docs/operations/OPERATIONS.md +24 -0
- package/docs/operations/PERFORMANCE.md +133 -0
- package/docs/operations/RELIABILITY.md +6 -0
- package/docs/operations/ROADMAP.md +36 -18
- package/docs/operations/TESTING.md +4 -0
- package/docs/operations/TRACEABILITY.md +4 -0
- package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +4 -0
- package/docs/operations/VERSION_SYNC.md +54 -5
- package/docs/reference/ALIASES.md +7 -0
- package/docs/reference/ALIASES_CHEATSHEET.md +5 -1
- package/docs/reference/ALIASES_DEPRECATIONS.md +5 -1
- package/docs/reference/FEATURES.md +4 -0
- package/docs/reference/FONTS.md +4 -0
- package/docs/reference/PROFILES.md +4 -0
- package/docs/reference/SCREENSHOTS.md +4 -0
- package/docs/reference/SCRIPTS.md +4 -0
- package/docs/reference/SUPPORT_MATRIX.md +10 -4
- package/docs/reference/THEMES.md +4 -0
- package/docs/reference/TOOLS.md +4 -0
- package/docs/reference/UTILS.md +16 -12
- package/docs/security/AI_ACT_COMPLIANCE.md +4 -0
- package/docs/security/AUDIT_BYPASS.md +103 -0
- package/docs/security/AUTOMATION_SECRETS.md +4 -0
- package/docs/security/CI_EGRESS_ALLOWLIST.md +127 -0
- package/docs/security/COMPLIANCE.md +5 -0
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +86 -0
- package/docs/security/ENCRYPTION.md +5 -0
- package/docs/security/FMEA.md +4 -0
- package/docs/security/HISTORY_FILTERING.md +132 -0
- package/docs/security/INCIDENT_RESPONSE.md +4 -0
- package/docs/security/INSTALL_VERIFICATION.md +122 -0
- package/docs/security/KEYS.md +4 -0
- package/docs/security/KEY_ROTATION.md +4 -0
- package/docs/security/MCP_POLICY.md +9 -0
- package/docs/security/POLICY_RELEASES.md +4 -0
- package/docs/security/README.md +4 -0
- package/docs/security/SCORECARD.md +80 -0
- package/docs/security/SECRETS.md +12 -0
- package/docs/security/SECURITY.md +4 -0
- package/docs/security/SECURITY_CHECKLIST.md +11 -0
- package/docs/security/SHELL_EXEMPTIONS.md +145 -0
- package/docs/security/SOUP_REGISTER.md +4 -0
- package/docs/security/THREAT_MODEL.md +10 -0
- package/docs/security/VERIFICATION_VALIDATION.md +5 -1
- package/docs/themes/README.md +4 -0
- package/docs/themes/VISUAL_INTEGRITY_REPORT.md +4 -0
- package/dot_config/ai/identity.md +3 -0
- package/dot_config/ai/patterns/architect.md +2 -0
- package/dot_config/ai/patterns/hardener.md +2 -0
- package/dot_config/ai/patterns/refactor.md +2 -0
- package/dot_config/alacritty/alacritty.toml.tmpl +3 -3
- package/dot_config/atuin/config.toml.tmpl +47 -0
- package/dot_config/dotfiles/agent-card.json +1 -1
- package/dot_config/dotfiles/boot/README.md +2 -0
- package/dot_config/dotfiles/grub/README.md +2 -0
- package/dot_config/dotfiles/lock/README.md +2 -0
- package/dot_config/fish/conf.d/init.fish.tmpl +21 -0
- package/dot_config/fish/functions/_cached_eval.fish +84 -11
- package/dot_config/fish/functions/_cached_eval_clear.fish +17 -0
- package/dot_config/foot/foot.ini.tmpl +3 -3
- package/dot_config/fuzzel/fuzzel.ini.tmpl +2 -2
- package/dot_config/ghostty/config.tmpl +3 -3
- package/dot_config/git/hooks/executable_commit-msg +146 -0
- package/dot_config/goose/config.yaml +2 -2
- package/dot_config/gtk-3.0/gtk.css.tmpl +2 -2
- package/dot_config/gtk-3.0/settings.ini.tmpl +2 -2
- package/dot_config/gtk-4.0/gtk.css.tmpl +2 -2
- package/dot_config/gtk-4.0/settings.ini.tmpl +2 -2
- package/dot_config/kitty/kitty.conf.tmpl +3 -3
- package/dot_config/mise/config.toml +1 -1
- package/dot_config/niri/config.kdl.tmpl +2 -2
- package/dot_config/nushell/cached_eval.nu +80 -0
- package/dot_config/nushell/env.nu.tmpl +21 -13
- package/dot_config/shell/00-core-paths.sh.tmpl +1 -0
- package/dot_config/shell/05-core-safety.sh +1 -0
- package/dot_config/shell/10-secrets.sh +1 -0
- package/dot_config/shell/40-fzf-defaults.sh.tmpl +1 -0
- package/dot_config/shell/40-ls-colors.sh +1 -0
- package/dot_config/shell/50-logic-functions-core.sh.tmpl +1 -0
- package/dot_config/shell/50-logic-functions.sh.tmpl +1 -0
- package/dot_config/shell/51-logic-functions-extra.sh.tmpl +1 -0
- package/dot_config/shell/90-ux-aliases.sh.tmpl +1 -0
- package/dot_config/shell/91-ux-aliases-lazy.sh.tmpl +1 -0
- package/dot_config/shell/README.md +25 -8
- package/dot_config/starship.toml.tmpl +2 -2
- package/dot_config/tmux/tmux.conf.tmpl +3 -3
- package/dot_config/user-dirs.dirs +1 -0
- package/dot_config/vscode/settings.json.tmpl +2 -2
- package/dot_config/waybar/config.jsonc.tmpl +2 -2
- package/dot_config/waybar/style.css.tmpl +2 -2
- package/dot_config/wezterm/wezterm.lua.tmpl +3 -3
- package/dot_config/zsh/dot_zshrc.tmpl +154 -17
- package/dot_config/zsh/rc.d/00-alias-shims.zsh +28 -6
- package/dot_config/zsh/rc.d/30-options.zsh.tmpl +26 -6
- package/dot_local/bin/executable_bm +2 -0
- package/dot_local/bin/executable_dot +9 -2
- package/dot_local/bin/executable_dot-load-benchmark +1 -1
- package/dot_local/bin/executable_notify +2 -0
- package/dot_local/bin/executable_open +2 -0
- package/dot_local/bin/executable_tour +4 -2
- package/dot_local/bin/executable_up +3 -1
- package/install.sh +12 -4
- package/package.json +1 -1
- package/scripts/ci/check-dangerous-chmod.sh +19 -0
- package/scripts/ci/check-deps-dev.sh +236 -0
- package/scripts/ci/check-insecure-tls.sh +61 -0
- package/scripts/ci/check-regression-traceability.sh +67 -0
- package/scripts/ci/check-shell-preamble.sh +106 -0
- package/scripts/ci/run-coverage.sh +362 -0
- package/scripts/ci/validate-chezmoidata.sh +25 -0
- package/scripts/diagnostics/doctor.sh +173 -5
- package/scripts/diagnostics/drift-dashboard.sh +177 -13
- package/scripts/diagnostics/health.sh +21 -4
- package/scripts/diagnostics/perf.sh +304 -77
- package/scripts/diagnostics/workstation-attestation.sh +6 -1
- package/scripts/dot/commands/agent.sh +14 -5
- package/scripts/dot/commands/ai.sh +75 -10
- package/scripts/dot/lib/bento.sh +2 -1
- package/scripts/dot/lib/log.sh +6 -0
- package/scripts/dot/lib/platform.sh +1 -0
- package/scripts/dot/lib/ui.sh +11 -0
- package/scripts/dot/lib/utils.sh +5 -0
- package/scripts/git-hooks/pre-commit-audit.sh +1 -1
- package/scripts/git-hooks/pre-push +66 -3
- package/scripts/ops/heal-chezmoi.sh +41 -6
- package/scripts/qa/powershell-contract.ps1 +95 -0
- package/scripts/theme/merge-wallpaper.sh +4 -0
- package/scripts/theme/switch.sh +20 -10
- package/dot_config/atuin/config.toml +0 -40
- package/dot_local/bin/__pycache__/executable_dot-load-benchmark-ptycpython-312.pyc +0 -0
|
@@ -9,6 +9,9 @@ set -euo pipefail
|
|
|
9
9
|
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
11
|
REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
|
|
12
|
+
# Export so child processes (the mcp-doctor subprocess below) inherit it
|
|
13
|
+
# without the env-prefix dance that confuses shellcheck (SC2097/SC2098).
|
|
14
|
+
export REPO_ROOT
|
|
12
15
|
|
|
13
16
|
# shellcheck source=../dot/lib/ui.sh
|
|
14
17
|
source "$SCRIPT_DIR/../dot/lib/ui.sh"
|
|
@@ -91,7 +94,9 @@ if [[ -z "$current_profile" ]] && [[ -f "$agent_profile_file" ]]; then
|
|
|
91
94
|
current_profile="$(jq -r '.defaultProfile // "ask"' "$agent_profile_file")"
|
|
92
95
|
fi
|
|
93
96
|
|
|
94
|
-
|
|
97
|
+
MCP_CONFIG="$REPO_ROOT/dot_config/claude/mcp_servers.json"
|
|
98
|
+
export MCP_CONFIG
|
|
99
|
+
mcp_summary="$(bash "$REPO_ROOT/scripts/diagnostics/mcp-doctor.sh" --strict --json)"
|
|
95
100
|
|
|
96
101
|
attestation_json="$(
|
|
97
102
|
jq -n \
|
|
@@ -76,11 +76,20 @@ _agent_checkpoint_file() {
|
|
|
76
76
|
_agent_apply_profile_env() {
|
|
77
77
|
local name="$1"
|
|
78
78
|
export DOT_AGENT_PROFILE="$name"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
# Split declare-and-assign to avoid masking the field-getter's exit
|
|
80
|
+
# code (SC2155). If the profile JSON is malformed, the assignment
|
|
81
|
+
# now fails the function instead of silently exporting an empty value.
|
|
82
|
+
local approval filesystem network mcp_profile max_steps
|
|
83
|
+
approval="$(_agent_profile_field "$name" "approval")"
|
|
84
|
+
filesystem="$(_agent_profile_field "$name" "filesystem")"
|
|
85
|
+
network="$(_agent_profile_field "$name" "network")"
|
|
86
|
+
mcp_profile="$(_agent_profile_field "$name" "mcpProfile")"
|
|
87
|
+
max_steps="$(_agent_profile_field "$name" "maxSteps")"
|
|
88
|
+
export DOT_AGENT_APPROVAL="$approval"
|
|
89
|
+
export DOT_AGENT_FILESYSTEM="$filesystem"
|
|
90
|
+
export DOT_AGENT_NETWORK="$network"
|
|
91
|
+
export DOT_AGENT_MCP_PROFILE="$mcp_profile"
|
|
92
|
+
export DOT_AGENT_MAX_STEPS="$max_steps"
|
|
84
93
|
}
|
|
85
94
|
|
|
86
95
|
_agent_rbac_enforcement() {
|
|
@@ -28,9 +28,10 @@ if [[ ! -d "$PATTERN_DIR" ]]; then
|
|
|
28
28
|
fi
|
|
29
29
|
|
|
30
30
|
_show_ai_bridge_usage() {
|
|
31
|
-
echo "Usage: dot cl|copilot|gemini|kiro|autohand|vibe|qwen|zai --pattern [name] \"prompt\""
|
|
31
|
+
echo "Usage: dot cl|codex|copilot|gemini|goose|kiro|autohand|vibe|qwen|zai --pattern [name] \"prompt\""
|
|
32
32
|
echo ""
|
|
33
33
|
echo "Available Patterns:"
|
|
34
|
+
# shellcheck disable=SC2012
|
|
34
35
|
ls -1 "$PATTERN_DIR" 2>/dev/null | sed 's/\.md$//' | sed 's/^/ - /' || echo " (none)"
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -57,18 +58,72 @@ _ai_refresh_status_cache() {
|
|
|
57
58
|
tmp_file="$(mktemp)"
|
|
58
59
|
mkdir -p "$AI_CACHE_DIR"
|
|
59
60
|
|
|
60
|
-
local
|
|
61
|
+
local total=${#ai_entries[@]}
|
|
62
|
+
|
|
63
|
+
# Cold-cache refresh runs `$bin --version` for every tool — node-
|
|
64
|
+
# based ones are slow to start, so the total can hit 15-30s. Show a
|
|
65
|
+
# spinner so the user has feedback.
|
|
66
|
+
ui_spinner_start "Probing $total AI tools (cached for ${AI_STATUS_TTL}s)"
|
|
67
|
+
|
|
68
|
+
local jobs="${DOTFILES_AI_PROBE_JOBS:-$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 4)}"
|
|
69
|
+
local probe_dir
|
|
70
|
+
probe_dir="$(mktemp -d)"
|
|
71
|
+
|
|
72
|
+
# Probe via xargs -P. The probe logic lives INLINE in the bash -c
|
|
73
|
+
# string rather than as an exported function, because `export -f`
|
|
74
|
+
# doesn't always survive across bash invocations on every platform
|
|
75
|
+
# (notably macOS bash 3.2 needs the BASH_FUNC_*() env-var format,
|
|
76
|
+
# which subtly breaks for some shells in PATH). Inlining sidesteps
|
|
77
|
+
# the inheritance question entirely.
|
|
78
|
+
local i=0
|
|
79
|
+
local entry
|
|
80
|
+
local indexed=()
|
|
61
81
|
for entry in "${ai_entries[@]}"; do
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
82
|
+
indexed+=("$i|$entry")
|
|
83
|
+
i=$((i + 1))
|
|
84
|
+
done
|
|
85
|
+
# shellcheck disable=SC2016
|
|
86
|
+
local probe_script='
|
|
87
|
+
payload="$1"
|
|
88
|
+
out_dir="$2"
|
|
89
|
+
i="${payload%%|*}"
|
|
90
|
+
entry="${payload#*|}"
|
|
91
|
+
IFS="|" read -r category role name bin desc <<<"$entry"
|
|
92
|
+
if command -v "$bin" >/dev/null 2>&1; then
|
|
93
|
+
output=$("$bin" --version 2>/dev/null | head -1) || true
|
|
94
|
+
version=$(printf "%s" "$output" | sed "s/^[^0-9]*//" | sed "s/[[:space:]]*$//" | sed "s/\.$//")
|
|
95
|
+
printf "%s\t1\t%s\n" "$bin" "$version" >"$out_dir/$i"
|
|
66
96
|
else
|
|
67
|
-
|
|
68
|
-
version=""
|
|
97
|
+
printf "%s\t0\t\n" "$bin" >"$out_dir/$i"
|
|
69
98
|
fi
|
|
70
|
-
|
|
99
|
+
'
|
|
100
|
+
# NOTE: `-I{}` already implies one input line per invocation. Adding
|
|
101
|
+
# `-n1` on top triggers a BSD-xargs quirk where the input line is
|
|
102
|
+
# word-split on whitespace ("0|Agents (autonomous)|..." → multiple
|
|
103
|
+
# entries). Use only `-I{}`.
|
|
104
|
+
#
|
|
105
|
+
# ALSO: feed null-delimited records (`-0`) so apostrophes and
|
|
106
|
+
# other quote-like characters in the descriptions ("Block's coding
|
|
107
|
+
# agent") don't trigger xargs's "unterminated quote" parser.
|
|
108
|
+
printf '%s\0' "${indexed[@]}" |
|
|
109
|
+
xargs -0 -I{} -P"$jobs" \
|
|
110
|
+
bash -c "$probe_script" _ {} "$probe_dir" \
|
|
111
|
+
2>/dev/null || true
|
|
112
|
+
|
|
113
|
+
# Re-assemble in original entry order.
|
|
114
|
+
local n
|
|
115
|
+
for ((n = 0; n < i; n++)); do
|
|
116
|
+
[[ -f "$probe_dir/$n" ]] && cat "$probe_dir/$n" >>"$tmp_file"
|
|
71
117
|
done
|
|
118
|
+
rm -rf "$probe_dir"
|
|
119
|
+
|
|
120
|
+
# Guard with `|| true` because ui_spinner_stop's last line evaluates
|
|
121
|
+
# to rc=1 when stdout is a TTY (the `[[ ! -t 1 ]] && printf` short-
|
|
122
|
+
# circuit). Under `set -euo pipefail` that rc would kill the script
|
|
123
|
+
# right before we get to write the cache, leaving the user with a
|
|
124
|
+
# silent broken cold-cache run. Defence in depth — the function
|
|
125
|
+
# now also has an explicit `return 0` upstream.
|
|
126
|
+
ui_spinner_stop || true
|
|
72
127
|
|
|
73
128
|
mv "$tmp_file" "$AI_STATUS_CACHE_FILE"
|
|
74
129
|
}
|
|
@@ -81,7 +136,9 @@ _ai_get_cached_status() {
|
|
|
81
136
|
_ai_mise_pkg() {
|
|
82
137
|
case "$1" in
|
|
83
138
|
claude) echo "npm:@anthropic-ai/claude-code" ;;
|
|
139
|
+
codex) echo "npm:@openai/codex" ;;
|
|
84
140
|
copilot) echo "npm:@github/copilot" ;;
|
|
141
|
+
goose) echo "pipx:goose-ai" ;;
|
|
85
142
|
aider) echo "pipx:aider-chat" ;;
|
|
86
143
|
opencode) echo "npm:opencode-ai" ;;
|
|
87
144
|
sgpt) echo "pipx:shell-gpt" ;;
|
|
@@ -102,7 +159,9 @@ cmd_ai_status() {
|
|
|
102
159
|
# category|role|name|binary|description
|
|
103
160
|
local -a ai_clis=(
|
|
104
161
|
"Agents (autonomous)|agent|Claude Code|claude|Anthropic CLI agent"
|
|
162
|
+
"Agents (autonomous)|agent|Codex CLI|codex|OpenAI Codex agent"
|
|
105
163
|
"Agents (autonomous)|agent|Copilot CLI|copilot|GitHub Copilot CLI"
|
|
164
|
+
"Agents (autonomous)|agent|Goose|goose|Block's coding agent"
|
|
106
165
|
"Coding (interactive)|coding|Aider|aider|AI pair programmer"
|
|
107
166
|
"Coding (interactive)|coding|OpenCode|opencode|Terminal coding assistant"
|
|
108
167
|
"Coding (interactive)|coding|Autohand Code|autohand|Autohand coding agent"
|
|
@@ -350,12 +409,18 @@ ${prompt}"
|
|
|
350
409
|
cl | claude)
|
|
351
410
|
printf "%s" "$full_prompt" | claude
|
|
352
411
|
;;
|
|
412
|
+
codex)
|
|
413
|
+
printf "%s" "$full_prompt" | codex
|
|
414
|
+
;;
|
|
353
415
|
copilot)
|
|
354
416
|
copilot -sp "$full_prompt"
|
|
355
417
|
;;
|
|
356
418
|
gemini)
|
|
357
419
|
printf "%s" "$full_prompt" | gemini chat
|
|
358
420
|
;;
|
|
421
|
+
goose)
|
|
422
|
+
printf "%s" "$full_prompt" | goose session start
|
|
423
|
+
;;
|
|
359
424
|
kiro | kiro-cli)
|
|
360
425
|
printf "%s" "$full_prompt" | kiro-cli chat
|
|
361
426
|
;;
|
|
@@ -404,7 +469,7 @@ case "${1:-}" in
|
|
|
404
469
|
shift
|
|
405
470
|
cmd_ai_query "$@"
|
|
406
471
|
;;
|
|
407
|
-
cl | claude | copilot | gemini | kiro | sgpt | ollama | opencode | aider | autohand | vibe | qwen | zai)
|
|
472
|
+
cl | claude | codex | copilot | gemini | goose | kiro | sgpt | ollama | opencode | aider | autohand | vibe | qwen | zai)
|
|
408
473
|
tool="$1"
|
|
409
474
|
shift
|
|
410
475
|
run_ai_with_context "$tool" "$@"
|
package/scripts/dot/lib/bento.sh
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Copyright (c) 2015-2026 Dotfiles. All rights reserved.
|
|
3
|
+
# Sourced by scripts/dot/commands/*.sh and dot_local/bin/executable_dot; inherits set -euo pipefail.
|
|
3
4
|
# Dotfiles 2026: Atomic Intelligence Surface
|
|
4
5
|
# High-fidelity, perfectly aligned, and professional.
|
|
5
6
|
|
|
@@ -30,7 +31,7 @@ _dotfiles_bento_render() {
|
|
|
30
31
|
|
|
31
32
|
# Render a fixed-width card (42 cols) so output aligns in any terminal width
|
|
32
33
|
printf "\n"
|
|
33
|
-
printf " ${c_cyan}${c_bold}💎 D O T F I L E S${c_reset} ${c_slate}[v0.2.
|
|
34
|
+
printf " ${c_cyan}${c_bold}💎 D O T F I L E S${c_reset} ${c_slate}[v0.2.501]${c_reset}\n"
|
|
34
35
|
printf " ${c_slate}──────────────────────────────────────────${c_reset}\n"
|
|
35
36
|
|
|
36
37
|
# Key system properties at a glance — answers "is my env healthy?" in 1 second
|
package/scripts/dot/lib/log.sh
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Copyright (c) 2015-2026 Dotfiles. All rights reserved.
|
|
3
|
+
# Sourced by scripts/dot/commands/*.sh and scripts/diagnostics/*; inherits set -euo pipefail.
|
|
3
4
|
# Structured JSON logging and metrics library.
|
|
4
5
|
# Source this file to emit machine-readable logs and performance metrics.
|
|
5
6
|
#
|
|
@@ -8,6 +9,11 @@
|
|
|
8
9
|
# dot_log info "apply_start" "source=chezmoi"
|
|
9
10
|
# dot_metric "shell_startup" 142 ms
|
|
10
11
|
|
|
12
|
+
# Re-source guard: re-sourcing would mint a new DOT_TRACE_ID and break
|
|
13
|
+
# correlation across modules that already captured the original.
|
|
14
|
+
[[ "${_DOT_LIB_LOG_LOADED:-0}" == "1" ]] && return 0
|
|
15
|
+
_DOT_LIB_LOG_LOADED=1
|
|
16
|
+
|
|
11
17
|
# Correlation ID for tracing across commands in a single invocation
|
|
12
18
|
DOT_TRACE_ID="${DOT_TRACE_ID:-$(date +%s%N 2>/dev/null | tail -c 12 || date +%s)}"
|
|
13
19
|
export DOT_TRACE_ID
|
package/scripts/dot/lib/ui.sh
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Copyright (c) 2015-2026 Dotfiles. All rights reserved.
|
|
3
|
+
# Sourced by scripts/dot/commands/*.sh, scripts/diagnostics/*, scripts/ops/*; inherits set -euo pipefail.
|
|
3
4
|
## Dotfiles CLI UI Component Library — Single Source of Truth.
|
|
4
5
|
##
|
|
5
6
|
## All CLI output MUST go through these primitives. No raw printf with
|
|
@@ -30,6 +31,11 @@
|
|
|
30
31
|
## ui_header "Section Title"
|
|
31
32
|
## ui_ok "Operation succeeded"
|
|
32
33
|
|
|
34
|
+
# Re-source guard: re-sourcing would zero out the BOLD/RED/etc colour
|
|
35
|
+
# variables that ui_init() populated, breaking already-rendered output.
|
|
36
|
+
[[ "${_DOT_LIB_UI_LOADED:-0}" == "1" ]] && return 0
|
|
37
|
+
_DOT_LIB_UI_LOADED=1
|
|
38
|
+
|
|
33
39
|
# ═══════════════════════════════════════════════════════════════════════
|
|
34
40
|
# State — all zeroed before ui_init
|
|
35
41
|
# ═══════════════════════════════════════════════════════════════════════
|
|
@@ -265,7 +271,12 @@ ui_spinner_stop() {
|
|
|
265
271
|
fi
|
|
266
272
|
ui_clear_line
|
|
267
273
|
ui_show_cursor
|
|
274
|
+
# The newline is only needed when stdout is NOT a TTY. We must return
|
|
275
|
+
# 0 either way — without the explicit `return 0`, the function's exit
|
|
276
|
+
# status comes from the trailing `[[ ! -t 1 ]] && printf` chain, which
|
|
277
|
+
# is rc=1 on a TTY and breaks every caller running under `set -e`.
|
|
268
278
|
[[ ! -t 1 ]] && printf "\n"
|
|
279
|
+
return 0
|
|
269
280
|
}
|
|
270
281
|
|
|
271
282
|
# ═══════════════════════════════════════════════════════════════════════
|
package/scripts/dot/lib/utils.sh
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# Copyright (c) 2015-2026 Dotfiles. All rights reserved.
|
|
3
|
+
# Sourced by scripts/dot/commands/*.sh and dot_local/bin/executable_dot; inherits set -euo pipefail.
|
|
3
4
|
# Dotfiles CLI Utilities
|
|
4
5
|
# Shared functions for dot command modules
|
|
5
6
|
|
|
7
|
+
# Re-source guard: cheap short-circuit when sourced from multiple modules.
|
|
8
|
+
[[ "${_DOT_LIB_UTILS_LOADED:-0}" == "1" ]] && return 0
|
|
9
|
+
_DOT_LIB_UTILS_LOADED=1
|
|
10
|
+
|
|
6
11
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
12
|
# shellcheck source=ui.sh
|
|
8
13
|
source "$SCRIPT_DIR/ui.sh"
|
|
@@ -140,6 +140,6 @@ if [[ $FAILED -eq 1 ]]; then
|
|
|
140
140
|
printf '%b\\n' " (Use --no-verify to bypass if absolutely necessary)"
|
|
141
141
|
exit 1
|
|
142
142
|
else
|
|
143
|
-
printf '%b\n' "${GREEN}${BOLD}✅ Audit passed.${NC} v0.2.
|
|
143
|
+
printf '%b\n' "${GREEN}${BOLD}✅ Audit passed.${NC} v0.2.501 standards maintained."
|
|
144
144
|
exit 0
|
|
145
145
|
fi
|
|
@@ -1,8 +1,26 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
+
# Copyright (c) 2015-2026 Dotfiles. All rights reserved.
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# pre-push hook
|
|
5
|
+
#
|
|
6
|
+
# 1. Refuses to push any commit that is not GPG/SSH-signed.
|
|
7
|
+
# 2. Runs `scripts/qa/reliability-audit.sh --quick`. The audit is mandatory
|
|
8
|
+
# by default; explicit per-push bypass requires `DOTFILES_ALLOW_UNSKIPPED_PUSH=1`,
|
|
9
|
+
# and every bypass is logged to `~/.local/share/dotfiles/audit-bypass.log`.
|
|
10
|
+
#
|
|
11
|
+
# The legacy `DOTFILES_SKIP_PRE_PUSH_AUDIT=1` env var (opt-out) is rejected
|
|
12
|
+
# with a migration message. The new variable is intentionally awkwardly
|
|
13
|
+
# named so that setting it requires deliberate intent. See
|
|
14
|
+
# `docs/security/AUDIT_BYPASS.md`.
|
|
15
|
+
# =============================================================================
|
|
16
|
+
|
|
2
17
|
set -euo pipefail
|
|
3
18
|
|
|
4
19
|
repo_root="$(git rev-parse --show-toplevel)"
|
|
5
20
|
|
|
21
|
+
# -----------------------------------------------------------------------------
|
|
22
|
+
# Step 1 — signed-commit enforcement (unchanged)
|
|
23
|
+
# -----------------------------------------------------------------------------
|
|
6
24
|
while read -r local_ref local_sha remote_ref remote_sha; do
|
|
7
25
|
[ "$local_sha" = "0000000000000000000000000000000000000000" ] && continue
|
|
8
26
|
|
|
@@ -18,12 +36,57 @@ while read -r local_ref local_sha remote_ref remote_sha; do
|
|
|
18
36
|
|
|
19
37
|
for c in $(git rev-list "$range"); do
|
|
20
38
|
if ! git verify-commit "$c" >/dev/null 2>&1; then
|
|
21
|
-
echo "Blocked: unsigned commit $c"
|
|
39
|
+
echo "Blocked: unsigned commit $c" >&2
|
|
22
40
|
exit 1
|
|
23
41
|
fi
|
|
24
42
|
done
|
|
25
43
|
done
|
|
26
44
|
|
|
27
|
-
|
|
28
|
-
|
|
45
|
+
# -----------------------------------------------------------------------------
|
|
46
|
+
# Step 2 — reject the legacy opt-out variable
|
|
47
|
+
# -----------------------------------------------------------------------------
|
|
48
|
+
if [ "${DOTFILES_SKIP_PRE_PUSH_AUDIT:-}" = "1" ]; then
|
|
49
|
+
cat >&2 <<'EOF'
|
|
50
|
+
ERROR: DOTFILES_SKIP_PRE_PUSH_AUDIT is no longer honored.
|
|
51
|
+
|
|
52
|
+
The pre-push audit was previously opt-out — setting one env var was enough
|
|
53
|
+
to skip it. That made bypass invisible and routine. Effective with #871,
|
|
54
|
+
the policy is fail-closed: the audit always runs unless you explicitly
|
|
55
|
+
authorize a bypass for this single push.
|
|
56
|
+
|
|
57
|
+
To bypass for one push:
|
|
58
|
+
DOTFILES_ALLOW_UNSKIPPED_PUSH=1 git push
|
|
59
|
+
|
|
60
|
+
Every bypass is recorded to ~/.local/share/dotfiles/audit-bypass.log
|
|
61
|
+
and surfaced by `dot doctor` if any are recent.
|
|
62
|
+
|
|
63
|
+
See: docs/security/AUDIT_BYPASS.md
|
|
64
|
+
EOF
|
|
65
|
+
exit 1
|
|
29
66
|
fi
|
|
67
|
+
|
|
68
|
+
# -----------------------------------------------------------------------------
|
|
69
|
+
# Step 3 — run the audit (or log + skip if explicitly bypassed)
|
|
70
|
+
# -----------------------------------------------------------------------------
|
|
71
|
+
if [ "${DOTFILES_ALLOW_UNSKIPPED_PUSH:-}" = "1" ]; then
|
|
72
|
+
bypass_log_dir="${XDG_STATE_HOME:-$HOME/.local/state}/dotfiles"
|
|
73
|
+
# The audit-bypass log lives under XDG_STATE_HOME (user state — never
|
|
74
|
+
# checked in, never deployed by chezmoi to other locations).
|
|
75
|
+
mkdir -p "$bypass_log_dir"
|
|
76
|
+
bypass_log="$bypass_log_dir/audit-bypass.log"
|
|
77
|
+
|
|
78
|
+
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
79
|
+
branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
|
|
80
|
+
remote="$(git remote get-url --push @{upstream} 2>/dev/null ||
|
|
81
|
+
git config --get remote.origin.url 2>/dev/null ||
|
|
82
|
+
echo unknown)"
|
|
83
|
+
reason="${DOTFILES_BYPASS_REASON:-no reason given}"
|
|
84
|
+
|
|
85
|
+
printf '%s\tbranch=%s\tremote=%s\treason=%s\n' \
|
|
86
|
+
"$ts" "$branch" "$remote" "$reason" >>"$bypass_log"
|
|
87
|
+
|
|
88
|
+
echo "WARN: pre-push audit bypassed (logged to $bypass_log)" >&2
|
|
89
|
+
exit 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
bash "$repo_root/scripts/qa/reliability-audit.sh" --quick
|
|
@@ -37,15 +37,50 @@ heal_chezmoi_drift() {
|
|
|
37
37
|
return 0
|
|
38
38
|
fi
|
|
39
39
|
|
|
40
|
+
# Partition the drift: column 2 is what `chezmoi apply` would fix
|
|
41
|
+
# (destination differs from source). Column 1 is source-only drift
|
|
42
|
+
# (unstaged edits in the chezmoi source tree). Apply can't help with
|
|
43
|
+
# the second case — that needs `git commit` in the source repo.
|
|
44
|
+
local applicable
|
|
45
|
+
local source_only
|
|
46
|
+
applicable=$(printf '%s\n' "$status_output" | awk 'substr($0,2,1)!=" "' | wc -l | tr -d ' ')
|
|
47
|
+
source_only=$(printf '%s\n' "$status_output" | awk 'substr($0,1,1)!=" " && substr($0,2,1)==" "' | wc -l | tr -d ' ')
|
|
48
|
+
|
|
40
49
|
ISSUES_FOUND=$((ISSUES_FOUND + 1))
|
|
41
50
|
|
|
42
51
|
if [[ "$DRY_RUN" == "1" ]]; then
|
|
43
|
-
log_dry "run 'chezmoi apply --force' to re-sync"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
log_dry "run 'chezmoi apply --force' to re-sync ($applicable file(s))"
|
|
53
|
+
return 0
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Skip the apply if every file is source-only drift; nothing to fix.
|
|
57
|
+
if [[ "$applicable" -eq 0 ]]; then
|
|
58
|
+
printf ' \033[38;5;220m⚠\033[0m chezmoi state %s file(s) modified in source only — commit or revert in the source repo\n' "$source_only"
|
|
59
|
+
return 0
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
# Capture apply output so we can surface failure reasons.
|
|
63
|
+
local apply_log
|
|
64
|
+
apply_log=$(mktemp)
|
|
65
|
+
if chezmoi apply --force >"$apply_log" 2>&1; then
|
|
66
|
+
FIXES_APPLIED=$((FIXES_APPLIED + 1))
|
|
67
|
+
CHEZMOI_APPLIED=1
|
|
68
|
+
persist_log "HEAL: chezmoi apply --force"
|
|
69
|
+
|
|
70
|
+
# Verify: did apply actually clean the drift?
|
|
71
|
+
local remaining
|
|
72
|
+
remaining=$(chezmoi status 2>/dev/null | awk 'substr($0,2,1)!=" "' | wc -l | tr -d ' ')
|
|
73
|
+
if [[ "$remaining" -eq 0 ]]; then
|
|
74
|
+
printf ' \033[38;5;42m✓\033[0m chezmoi re-apply %s file(s) synced\n' "$applicable"
|
|
75
|
+
else
|
|
76
|
+
# shellcheck disable=SC2016
|
|
77
|
+
printf ' \033[38;5;220m⚠\033[0m chezmoi re-apply %s applied, %s still drifted — run `chezmoi diff` to inspect\n' \
|
|
78
|
+
"$((applicable - remaining))" "$remaining"
|
|
49
79
|
fi
|
|
80
|
+
else
|
|
81
|
+
printf ' \033[38;5;196m✗\033[0m chezmoi re-apply failed; see %s\n' "$apply_log"
|
|
82
|
+
tail -5 "$apply_log" | sed 's/^/ /'
|
|
83
|
+
return 1
|
|
50
84
|
fi
|
|
85
|
+
rm -f "$apply_log"
|
|
51
86
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Copyright (c) 2015-2026 Dotfiles. All rights reserved.
|
|
2
|
+
#
|
|
3
|
+
# PowerShell parity contract — smoke test for the dotfiles PowerShell
|
|
4
|
+
# profile. Run by the windows-latest CI job (#860). Asserts that:
|
|
5
|
+
#
|
|
6
|
+
# 1. The profile parses + loads without throwing.
|
|
7
|
+
# 2. Core function shims (`dot`, `ll`, `la`, `cat`) are defined.
|
|
8
|
+
# 3. PSScriptAnalyzer reports no errors against the profile (warnings
|
|
9
|
+
# surface but don't fail the gate; tighten later).
|
|
10
|
+
#
|
|
11
|
+
# Exit codes:
|
|
12
|
+
# 0 contract intact.
|
|
13
|
+
# 1 any check failed; details printed to host.
|
|
14
|
+
|
|
15
|
+
$ErrorActionPreference = 'Stop'
|
|
16
|
+
$Failures = New-Object System.Collections.Generic.List[string]
|
|
17
|
+
|
|
18
|
+
$RepoRoot = if ($env:GITHUB_WORKSPACE) { $env:GITHUB_WORKSPACE } else { (Get-Location).Path }
|
|
19
|
+
$ProfileSrc = Join-Path $RepoRoot 'dot_config/powershell/Microsoft.PowerShell_profile.ps1.tmpl'
|
|
20
|
+
|
|
21
|
+
if (-not (Test-Path $ProfileSrc)) {
|
|
22
|
+
Write-Output "FAIL: profile source not found at $ProfileSrc"
|
|
23
|
+
exit 1
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# Step 1 — chezmoi-render the template into a real .ps1 we can dot-source.
|
|
27
|
+
# In CI, chezmoi is on PATH (installed by setup-chezmoi composite).
|
|
28
|
+
$Rendered = Join-Path $env:TEMP 'Microsoft.PowerShell_profile.ps1'
|
|
29
|
+
if (Get-Command chezmoi -ErrorAction SilentlyContinue) {
|
|
30
|
+
& chezmoi execute-template --init --promptString version=0.2.501 `
|
|
31
|
+
--in $ProfileSrc | Set-Content -Path $Rendered -NoNewline
|
|
32
|
+
} else {
|
|
33
|
+
# Fallback: strip chezmoi template syntax with a simple regex so the
|
|
34
|
+
# contract still runs locally without chezmoi installed.
|
|
35
|
+
(Get-Content $ProfileSrc -Raw) -replace '\{\{[^}]+\}\}', '0.0.0-fallback' |
|
|
36
|
+
Set-Content -Path $Rendered -NoNewline
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (-not (Test-Path $Rendered)) {
|
|
40
|
+
$Failures.Add("profile template did not render to $Rendered")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Step 2 — dot-source the rendered profile and verify it didn't throw.
|
|
44
|
+
$loadOk = $false
|
|
45
|
+
try {
|
|
46
|
+
. $Rendered
|
|
47
|
+
$loadOk = $true
|
|
48
|
+
Write-Output "OK: profile dot-sourced"
|
|
49
|
+
} catch {
|
|
50
|
+
Write-Output "FAIL: profile threw during load: $_"
|
|
51
|
+
$Failures.Add("profile load: $_")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Step 3 — verify required function shims are defined.
|
|
55
|
+
$RequiredFunctions = @('dot', 'd', 'll', 'la', 'cat')
|
|
56
|
+
foreach ($fn in $RequiredFunctions) {
|
|
57
|
+
if (Get-Command $fn -CommandType Function -ErrorAction SilentlyContinue) {
|
|
58
|
+
Write-Output "OK: function $fn defined"
|
|
59
|
+
} else {
|
|
60
|
+
Write-Output "FAIL: function $fn not defined"
|
|
61
|
+
$Failures.Add("missing function: $fn")
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# Step 4 — PSScriptAnalyzer (static analysis). Pre-installed on the
|
|
66
|
+
# windows-latest GitHub-hosted runner; install on demand if missing.
|
|
67
|
+
if (-not (Get-Module -ListAvailable -Name PSScriptAnalyzer)) {
|
|
68
|
+
Write-Output "Installing PSScriptAnalyzer..."
|
|
69
|
+
Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser -ErrorAction SilentlyContinue | Out-Null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (Get-Module -ListAvailable -Name PSScriptAnalyzer) {
|
|
73
|
+
Import-Module PSScriptAnalyzer -Force
|
|
74
|
+
$Findings = Invoke-ScriptAnalyzer -Path $Rendered -Severity 'Error' -ErrorAction SilentlyContinue
|
|
75
|
+
if ($Findings) {
|
|
76
|
+
foreach ($f in $Findings) {
|
|
77
|
+
Write-Output "FAIL: PSScriptAnalyzer error: $($f.RuleName) at line $($f.Line): $($f.Message)"
|
|
78
|
+
$Failures.Add("PSScriptAnalyzer error: $($f.RuleName)")
|
|
79
|
+
}
|
|
80
|
+
} else {
|
|
81
|
+
Write-Output "OK: PSScriptAnalyzer clean (Error severity)"
|
|
82
|
+
}
|
|
83
|
+
} else {
|
|
84
|
+
Write-Output "WARN: PSScriptAnalyzer not available — static analysis skipped"
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
Write-Output ""
|
|
88
|
+
if ($Failures.Count -eq 0) {
|
|
89
|
+
Write-Output "PowerShell contract: PASS"
|
|
90
|
+
exit 0
|
|
91
|
+
} else {
|
|
92
|
+
Write-Output "PowerShell contract: FAIL ($($Failures.Count) issue(s))"
|
|
93
|
+
foreach ($f in $Failures) { Write-Output " - $f" }
|
|
94
|
+
exit 1
|
|
95
|
+
}
|
|
@@ -81,6 +81,10 @@ merge_pair() {
|
|
|
81
81
|
|
|
82
82
|
local tmpdir
|
|
83
83
|
tmpdir="$(mktemp -d)"
|
|
84
|
+
# Single-quotes prevent the variable expanding at trap-definition time;
|
|
85
|
+
# `$tmpdir` resolves when the trap fires (still scoped to this function
|
|
86
|
+
# because RETURN is per-function).
|
|
87
|
+
# shellcheck disable=SC2064 # intentionally expand $tmpdir at trap time within this function scope
|
|
84
88
|
trap "rm -rf '$tmpdir'" RETURN
|
|
85
89
|
|
|
86
90
|
# Convert both to JPEG for heif-enc input (it handles JPEG best)
|
package/scripts/theme/switch.sh
CHANGED
|
@@ -184,7 +184,7 @@ pick_theme() {
|
|
|
184
184
|
fi
|
|
185
185
|
|
|
186
186
|
local current
|
|
187
|
-
|
|
187
|
+
current="$(current_theme)"
|
|
188
188
|
|
|
189
189
|
if [[ ! -f "$THEMES_FILE" ]]; then
|
|
190
190
|
ui_err "Missing" "$THEMES_FILE"
|
|
@@ -234,7 +234,8 @@ pick_theme() {
|
|
|
234
234
|
}
|
|
235
235
|
|
|
236
236
|
list_themes() {
|
|
237
|
-
local current
|
|
237
|
+
local current
|
|
238
|
+
current="$(current_theme)"
|
|
238
239
|
local current_family="${current%-dark}"
|
|
239
240
|
[[ "$current_family" != "$current" ]] || current_family="${current%-light}"
|
|
240
241
|
|
|
@@ -260,7 +261,8 @@ list_themes() {
|
|
|
260
261
|
|
|
261
262
|
# Toggle between light and dark within the same family, or switch families
|
|
262
263
|
toggle_theme() {
|
|
263
|
-
local current
|
|
264
|
+
local current
|
|
265
|
+
current="$(current_theme)"
|
|
264
266
|
|
|
265
267
|
if is_dark_theme "$current"; then
|
|
266
268
|
if [[ "$current" == *-dark ]]; then
|
|
@@ -279,8 +281,9 @@ toggle_theme() {
|
|
|
279
281
|
|
|
280
282
|
# Switch to the next wallpaper family while preserving mode.
|
|
281
283
|
switch_family() {
|
|
282
|
-
local current
|
|
283
|
-
|
|
284
|
+
local current family
|
|
285
|
+
current="$(current_theme)"
|
|
286
|
+
family="$(get_theme_family "$current")"
|
|
284
287
|
local mode="dark"
|
|
285
288
|
local families=()
|
|
286
289
|
local idx=0
|
|
@@ -316,8 +319,9 @@ switch_family() {
|
|
|
316
319
|
|
|
317
320
|
# Show current theme info
|
|
318
321
|
show_current() {
|
|
319
|
-
local current
|
|
320
|
-
|
|
322
|
+
local current family
|
|
323
|
+
current="$(current_theme)"
|
|
324
|
+
family="$(get_theme_family "$current")"
|
|
321
325
|
local mode="dark"
|
|
322
326
|
if ! is_dark_theme "$current" 2>/dev/null; then
|
|
323
327
|
mode="light"
|
|
@@ -338,8 +342,13 @@ sync_theme() {
|
|
|
338
342
|
;;
|
|
339
343
|
Linux)
|
|
340
344
|
if command -v gsettings >/dev/null 2>&1; then
|
|
341
|
-
# Check GNOME color scheme
|
|
342
|
-
local scheme=scheme=$(
|
|
345
|
+
# Check GNOME color scheme. Fixes a long-standing bug where the
|
|
346
|
+
# variable was declared as `local scheme=scheme=$(...)` — the
|
|
347
|
+
# extra `scheme=` prefix made the value always start with that
|
|
348
|
+
# literal, so the `prefer-light` test below could never match
|
|
349
|
+
# and the system always fell through to the dark branch.
|
|
350
|
+
local scheme
|
|
351
|
+
scheme=$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | tr -d "'")
|
|
343
352
|
if [[ "$scheme" == "prefer-light" ]]; then
|
|
344
353
|
os_mode="light"
|
|
345
354
|
else
|
|
@@ -349,7 +358,8 @@ sync_theme() {
|
|
|
349
358
|
;;
|
|
350
359
|
esac
|
|
351
360
|
|
|
352
|
-
local current
|
|
361
|
+
local current
|
|
362
|
+
current="$(current_theme)"
|
|
353
363
|
if is_dark_theme "$current" && [[ "$os_mode" == "light" ]]; then
|
|
354
364
|
ui_info "Sync" "System is light, switching dotfiles to light..."
|
|
355
365
|
toggle_theme
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Atuin Configuration (~/.config/atuin/config.toml)
|
|
2
|
-
# https://atuin.sh/docs/config
|
|
3
|
-
|
|
4
|
-
# Core
|
|
5
|
-
update_check = false
|
|
6
|
-
db_path = "~/.local/share/atuin/history.db"
|
|
7
|
-
key_path = "~/.local/share/atuin/key"
|
|
8
|
-
session_path = "~/.local/share/atuin/session"
|
|
9
|
-
|
|
10
|
-
# Sync
|
|
11
|
-
auto_sync = true
|
|
12
|
-
sync_frequency = "10m"
|
|
13
|
-
sync_address = "https://api.atuin.sh"
|
|
14
|
-
|
|
15
|
-
# UI
|
|
16
|
-
style = "compact"
|
|
17
|
-
inline_height = 20
|
|
18
|
-
show_preview = true
|
|
19
|
-
enter_accept = true
|
|
20
|
-
|
|
21
|
-
# Search
|
|
22
|
-
search_mode = "fuzzy"
|
|
23
|
-
filter_mode = "global"
|
|
24
|
-
workspaces = true
|
|
25
|
-
|
|
26
|
-
# Privacy: skip commands that may contain secrets
|
|
27
|
-
history_filter = [
|
|
28
|
-
"^export (SECRET|TOKEN|PASSWORD|API_KEY|AWS_)",
|
|
29
|
-
"^PASSWORD=",
|
|
30
|
-
"^ssh-keygen",
|
|
31
|
-
"^(aws|gcloud|az|kubectl).*(configure|auth|login|-k |--kubeconfig)",
|
|
32
|
-
"curl.*-H.*[Aa]uthorization",
|
|
33
|
-
"git clone.*https://.*:.*@",
|
|
34
|
-
"^vault ",
|
|
35
|
-
"^op (read|inject|run)",
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
# Skip ephemeral directories
|
|
39
|
-
secrets_filter = true
|
|
40
|
-
network_timeout = 30
|