@sebastienrousseau/dotfiles 0.2.519 → 0.2.521
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 +200 -0
- package/LICENSE-APACHE +190 -0
- package/{LICENSE → LICENSE-MIT} +1 -1
- package/README.md +1172 -166
- package/install.sh +77 -11
- package/package.json +8 -8
- package/tools/README.md +49 -0
- package/tools/ci/install-chezmoi-verified.sh +68 -0
- package/docs/.vitepress/reports/localization-readability-audit.md +0 -73
- package/docs/AI.md +0 -179
- package/docs/CNAME +0 -1
- package/docs/CONFIG_STRATEGY.md +0 -124
- package/docs/COPYRIGHT +0 -7
- package/docs/GOVERNANCE.md +0 -98
- package/docs/MAINTAINERS.md +0 -41
- package/docs/NAMING_CONVENTIONS.md +0 -102
- package/docs/OPENCODE.md +0 -127
- package/docs/README.md +0 -84
- package/docs/STRUCTURE.md +0 -102
- package/docs/adr/ADR-001-ci-cd-pipeline.md +0 -118
- package/docs/adr/ADR-002-shell-performance.md +0 -130
- package/docs/adr/ADR-003-security-first.md +0 -158
- package/docs/adr/ADR-004-cli-architecture.md +0 -171
- package/docs/adr/ADR-005-chezmoi-choice.md +0 -99
- package/docs/adr/ADR-006-shell-selection.md +0 -124
- package/docs/adr/ADR-007-multi-shell-parity.md +0 -62
- package/docs/adr/ADR-008-alias-system-architecture.md +0 -95
- package/docs/adr/ADR-009-wallpaper-driven-theming.md +0 -131
- package/docs/adr/ADR-010-starship-transient-prompt.md +0 -144
- package/docs/adr/ADR-011-nushell-tier3-keep.md +0 -144
- package/docs/adr/ADR-012-ai-fleet-local-proxy.md +0 -79
- package/docs/adr/README.md +0 -40
- package/docs/architecture/AI_COST_OPTIMIZATION.md +0 -144
- package/docs/architecture/ARCHITECTURE.md +0 -117
- package/docs/architecture/INTEROP.md +0 -44
- package/docs/architecture/REPO_LAYOUT.md +0 -241
- package/docs/architecture/WALKTHROUGH.md +0 -86
- package/docs/architecture/fleet-deployment.md +0 -77
- package/docs/archive/EUXIS_2026_REVIEW.md +0 -127
- package/docs/archive/LEGACY_ROADMAP.md +0 -6
- package/docs/archive/MILESTONE_v0.2.493.md +0 -47
- package/docs/archive/PLAN.md +0 -199
- package/docs/archive/REPO_AUDIT.md +0 -31
- package/docs/articles/.pages +0 -6
- package/docs/articles/2026-07-05-custom-mkdocs-material-dark-theme.md +0 -216
- package/docs/articles/2026-07-05-fish-startup-abbr.md +0 -153
- package/docs/articles/2026-07-05-master-to-main-rename-runbook.md +0 -128
- package/docs/articles/index.md +0 -36
- package/docs/guides/INSTALL.md +0 -144
- package/docs/guides/NEOVIM_IDE_GUIDE.md +0 -61
- package/docs/guides/THEMING.md +0 -230
- package/docs/guides/TROUBLESHOOTING.md +0 -176
- package/docs/guides/WSL2_NIX_TROUBLESHOOTING.md +0 -792
- package/docs/index.md +0 -132
- package/docs/interop/A2A.md +0 -39
- package/docs/interop/POWERSHELL.md +0 -102
- package/docs/manual/00-introduction.md +0 -89
- package/docs/manual/01-concepts/01-architecture.md +0 -138
- package/docs/manual/01-concepts/02-trust-model.md +0 -183
- package/docs/manual/01-concepts/03-theme-engine.md +0 -186
- package/docs/manual/01-concepts/04-fleet.md +0 -148
- package/docs/manual/01-concepts/05-self-healing.md +0 -204
- package/docs/manual/02-tutorials/01-first-install.md +0 -197
- package/docs/manual/02-tutorials/02-add-wallpaper.md +0 -216
- package/docs/manual/02-tutorials/03-create-profile.md +0 -244
- package/docs/manual/02-tutorials/04-encrypt-secret.md +0 -281
- package/docs/manual/02-tutorials/05-deploy-fleet.md +0 -283
- package/docs/manual/03-reference/01-dot-cli.md +0 -450
- package/docs/manual/03-reference/02-config-files.md +0 -265
- package/docs/manual/03-reference/03-environment.md +0 -124
- package/docs/manual/03-reference/04-templates.md +0 -190
- package/docs/manual/03-reference/05-feature-flags.md +0 -187
- package/docs/manual/04-cookbook/01-recipes.md +0 -285
- package/docs/manual/04-cookbook/02-troubleshooting.md +0 -351
- package/docs/manual/04-cookbook/03-faq.md +0 -175
- package/docs/manual/05-appendices/A-platform-matrix.md +0 -101
- package/docs/manual/05-appendices/B-security-checklist.md +0 -85
- package/docs/manual/05-appendices/C-glossary.md +0 -40
- package/docs/manual/05-appendices/D-bibliography.md +0 -58
- package/docs/manual/05-appendices/E-license.md +0 -38
- package/docs/manual/_toc.yml +0 -58
- package/docs/manual/command-index.md +0 -155
- package/docs/manual/concept-index.md +0 -168
- package/docs/manual/index.md +0 -66
- package/docs/operations/ARCHITECTURE_ROADMAP.md +0 -7
- package/docs/operations/ATTESTATION.md +0 -44
- package/docs/operations/CI_CADENCE.md +0 -107
- package/docs/operations/CI_COMPOSITES.md +0 -156
- package/docs/operations/COMPLETIONS.md +0 -123
- package/docs/operations/COVERAGE.md +0 -204
- package/docs/operations/DRIFT.md +0 -107
- package/docs/operations/HARD_AUDIT_2026.md +0 -631
- package/docs/operations/MAINTENANCE.md +0 -63
- package/docs/operations/MANIFEST.md +0 -127
- package/docs/operations/MIGRATION.md +0 -109
- package/docs/operations/OPERATIONS.md +0 -188
- package/docs/operations/PERFORMANCE.md +0 -133
- package/docs/operations/REGISTRY.md +0 -90
- package/docs/operations/RELEASE_PIPELINE.md +0 -128
- package/docs/operations/RELIABILITY.md +0 -122
- package/docs/operations/RFC_v0_2_503_reorganization.md +0 -280
- package/docs/operations/ROADMAP.md +0 -10
- package/docs/operations/ROADMAP_2026.md +0 -7
- package/docs/operations/ROADMAP_V0_2_503.md +0 -10
- package/docs/operations/TESTING.md +0 -216
- package/docs/operations/TRACEABILITY.md +0 -43
- package/docs/operations/TRUSTED_AGENT_WORKSTATION.md +0 -65
- package/docs/operations/VERSION_SYNC.md +0 -393
- package/docs/reference/ALIASES.md +0 -131
- package/docs/reference/ALIASES_CHEATSHEET.md +0 -32
- package/docs/reference/ALIASES_DEPRECATIONS.md +0 -13
- package/docs/reference/FEATURES.md +0 -66
- package/docs/reference/FONTS.md +0 -112
- package/docs/reference/POWERSHELL_PARITY.md +0 -82
- package/docs/reference/PROFILES.md +0 -69
- package/docs/reference/SCREENSHOTS.md +0 -121
- package/docs/reference/SCRIPTS.md +0 -71
- package/docs/reference/SUPPORT_MATRIX.md +0 -80
- package/docs/reference/THEMES.md +0 -117
- package/docs/reference/TOOLS.md +0 -110
- package/docs/reference/UTILS.md +0 -242
- package/docs/registry.json +0 -6
- package/docs/schema/dot-env-v1.json +0 -110
- package/docs/schema/dot-registry-v1.json +0 -33
- package/docs/security/AI_ACT_COMPLIANCE.md +0 -94
- package/docs/security/AUDIT_BYPASS.md +0 -103
- package/docs/security/AUTOMATION_SECRETS.md +0 -26
- package/docs/security/CI_EGRESS_ALLOWLIST.md +0 -127
- package/docs/security/CI_PINNING.md +0 -129
- package/docs/security/COMMIT_SIGNING.md +0 -138
- package/docs/security/COMPLIANCE.md +0 -458
- package/docs/security/DEPS_DEV_EXCEPTIONS.md +0 -86
- package/docs/security/DISCLOSURE.md +0 -130
- package/docs/security/ENCRYPTION.md +0 -57
- package/docs/security/FMEA.md +0 -159
- package/docs/security/FUZZING.md +0 -114
- package/docs/security/HISTORY_FILTERING.md +0 -132
- package/docs/security/INCIDENT_RESPONSE.md +0 -579
- package/docs/security/INSTALL_VERIFICATION.md +0 -122
- package/docs/security/KEYS.md +0 -49
- package/docs/security/KEY_ROTATION.md +0 -303
- package/docs/security/MCP_POLICY.md +0 -78
- package/docs/security/POLICY_RELEASES.md +0 -37
- package/docs/security/README.md +0 -28
- package/docs/security/SCORECARD.md +0 -195
- package/docs/security/SECRETS.md +0 -158
- package/docs/security/SECURITY.md +0 -45
- package/docs/security/SECURITY_CHECKLIST.md +0 -55
- package/docs/security/SHELL_EXEMPTIONS.md +0 -145
- package/docs/security/SOUP_REGISTER.md +0 -36
- package/docs/security/THREAT_MODEL.md +0 -130
- package/docs/security/VERIFICATION_VALIDATION.md +0 -228
- package/docs/security/VERIFY_RELEASE.md +0 -201
- package/docs/security/security-pubkey.asc +0 -15
- package/docs/stylesheets/extra.css +0 -444
- package/docs/themes/README.md +0 -10
- package/docs/themes/VISUAL_INTEGRITY_REPORT.md +0 -30
- package/docs/themes/hero-shot.svg +0 -78
- package/scripts/README.md +0 -123
- package/scripts/ci/check-copyright-headers.sh +0 -8
- package/scripts/ci/check-shell-preamble.sh +0 -8
- package/scripts/ci/guard-gitleaks-checkout.sh +0 -8
- package/scripts/demo/record.sh +0 -43
- package/scripts/diagnostics/a2a-conformance.sh +0 -163
- package/scripts/diagnostics/alias-governance.sh +0 -138
- package/scripts/diagnostics/aliases-cheatsheet.sh +0 -74
- package/scripts/diagnostics/aliases-manifest.sh +0 -77
- package/scripts/diagnostics/benchmark.sh +0 -408
- package/scripts/diagnostics/conflicts.sh +0 -73
- package/scripts/diagnostics/doctor-unified.sh +0 -39
- package/scripts/diagnostics/doctor.sh +0 -751
- package/scripts/diagnostics/drift-dashboard.sh +0 -202
- package/scripts/diagnostics/health.sh +0 -623
- package/scripts/diagnostics/history-analysis.sh +0 -86
- package/scripts/diagnostics/mcp-doctor.sh +0 -582
- package/scripts/diagnostics/perf.sh +0 -453
- package/scripts/diagnostics/scorecard.sh +0 -119
- package/scripts/diagnostics/secret-governance.sh +0 -65
- package/scripts/diagnostics/security-score.sh +0 -467
- package/scripts/diagnostics/smoke-test.sh +0 -88
- package/scripts/diagnostics/snapshot.sh +0 -90
- package/scripts/diagnostics/verify.sh +0 -108
- package/scripts/diagnostics/verify_state.sh +0 -73
- package/scripts/diagnostics/version-locks.sh +0 -94
- package/scripts/diagnostics/workstation-attestation.sh +0 -187
- package/scripts/dot/commands/agent.sh +0 -485
- package/scripts/dot/commands/agents.sh +0 -336
- package/scripts/dot/commands/ai.sh +0 -587
- package/scripts/dot/commands/aliases.sh +0 -277
- package/scripts/dot/commands/appearance.sh +0 -110
- package/scripts/dot/commands/completion.sh +0 -134
- package/scripts/dot/commands/core.sh +0 -217
- package/scripts/dot/commands/diagnostics.sh +0 -265
- package/scripts/dot/commands/env-emit.sh +0 -203
- package/scripts/dot/commands/fleet.sh +0 -688
- package/scripts/dot/commands/init.sh +0 -185
- package/scripts/dot/commands/lint.sh +0 -208
- package/scripts/dot/commands/manual.sh +0 -169
- package/scripts/dot/commands/meta.sh +0 -333
- package/scripts/dot/commands/patterns.sh +0 -55
- package/scripts/dot/commands/registry.sh +0 -419
- package/scripts/dot/commands/restore.sh +0 -232
- package/scripts/dot/commands/secrets.sh +0 -296
- package/scripts/dot/commands/security.sh +0 -102
- package/scripts/dot/commands/tools.sh +0 -556
- package/scripts/dot/data/alias-deprecations.tsv +0 -2
- package/scripts/dot/powershell/Dot.psm1 +0 -319
- package/scripts/fonts/install-nerd-fonts.sh +0 -75
- package/scripts/fonts/patch-fonts.sh +0 -36
- package/scripts/git-hooks/install.sh +0 -12
- package/scripts/git-hooks/pre-commit +0 -12
- package/scripts/git-hooks/pre-commit-audit.sh +0 -146
- package/scripts/git-hooks/pre-push +0 -105
- package/scripts/git-hooks/prepare-commit-msg +0 -29
- package/scripts/lib/secrets_provider.sh +0 -185
- package/scripts/ops/ai-setup.sh +0 -71
- package/scripts/ops/bundle.sh +0 -104
- package/scripts/ops/chaos.sh +0 -50
- package/scripts/ops/chezmoi-apply.sh +0 -333
- package/scripts/ops/chezmoi-diff.sh +0 -16
- package/scripts/ops/chezmoi-remove.sh +0 -46
- package/scripts/ops/chezmoi-update.sh +0 -63
- package/scripts/ops/heal-chezmoi.sh +0 -87
- package/scripts/ops/heal-system.sh +0 -129
- package/scripts/ops/heal-tools.sh +0 -297
- package/scripts/ops/heal.sh +0 -223
- package/scripts/ops/post-apply-repair.sh +0 -107
- package/scripts/ops/prewarm.sh +0 -128
- package/scripts/ops/release.sh +0 -262
- package/scripts/ops/rollback.sh +0 -604
- package/scripts/ops/setup.sh +0 -138
- package/scripts/ops/teleport.sh +0 -34
- package/scripts/qa/check-version-consistency.sh +0 -124
- package/scripts/qa/coverage-baseline.sh +0 -61
- package/scripts/qa/docs-coverage.sh +0 -112
- package/scripts/qa/examples-coverage.sh +0 -94
- package/scripts/qa/powershell-contract.ps1 +0 -95
- package/scripts/qa/reliability-audit.sh +0 -139
- package/scripts/qa/scorecard-snapshot.sh +0 -128
- package/scripts/qa/traceability-coverage.sh +0 -117
- package/scripts/qa/validate-examples.sh +0 -27
- package/scripts/qa/wsl-contract.sh +0 -12
- package/scripts/secrets/age-init.sh +0 -82
- package/scripts/secrets/create-secrets-file.sh +0 -46
- package/scripts/secrets/encrypt-ssh-key.sh +0 -44
- package/scripts/security/backup.sh +0 -58
- package/scripts/security/check-disclosure-key-expiry.sh +0 -111
- package/scripts/security/dns-doh.sh +0 -52
- package/scripts/security/encryption-check.sh +0 -55
- package/scripts/security/enforce-policies.sh +0 -335
- package/scripts/security/firewall.sh +0 -91
- package/scripts/security/lock-configs.sh +0 -67
- package/scripts/security/lock-screen.sh +0 -56
- package/scripts/security/manage-secrets.sh +0 -429
- package/scripts/security/ssh-cert.sh +0 -204
- package/scripts/security/telemetry-kill.sh +0 -51
- package/scripts/security/usb-safety.sh +0 -52
- package/scripts/theme/apply-gnome-theme.sh +0 -333
- package/scripts/theme/extract-heic-frames.sh +0 -115
- package/scripts/theme/extract-theme.py +0 -742
- package/scripts/theme/install-boot-logo.sh +0 -63
- package/scripts/theme/install-catppuccin-themes.sh +0 -371
- package/scripts/theme/install-cursors.sh +0 -26
- package/scripts/theme/install-file-icons.sh +0 -27
- package/scripts/theme/install-grub-theme.sh +0 -62
- package/scripts/theme/install-lock-icon.sh +0 -31
- package/scripts/theme/merge-wallpaper.sh +0 -146
- package/scripts/theme/rebuild-themes.sh +0 -544
- package/scripts/theme/switch.sh +0 -449
- package/scripts/theme/wallpaper-rotate.sh +0 -137
- package/scripts/theme/wallpaper-sync.sh +0 -690
- package/scripts/tools/cmatrix.sh +0 -22
- package/scripts/tools/detect-collisions.py +0 -103
- package/scripts/tools/emoji-picker.sh +0 -49
- package/scripts/tools/figlet-banner.sh +0 -19
- package/scripts/tools/log-rotate.sh +0 -31
- package/scripts/tools/lolcat-wrap.sh +0 -20
- package/scripts/tools/pipes.sh +0 -49
- package/scripts/tuning/linux.sh +0 -186
- package/scripts/tuning/macos.sh +0 -56
- package/scripts/uninstall.sh +0 -86
- package/scripts/version-sync.sh +0 -654
- package/templates/chezmoi-data/geekom-a9.toml.example +0 -21
- package/templates/chezmoi-data/mac-m1.toml.example +0 -16
- package/templates/chezmoi-data/mac-t2-linux.toml.example +0 -21
- package/templates/chezmoi-data/surface-pro-7p.toml.example +0 -21
- package/templates/projects/go/.github/workflows/ci.yml +0 -31
- package/templates/projects/go/README.md +0 -7
- package/templates/projects/go/cmd/__PROJECT_NAME__/main.go +0 -8
- package/templates/projects/go/go.mod +0 -3
- package/templates/projects/go/go.sum +0 -0
- package/templates/projects/molecule/README.md +0 -7
- package/templates/projects/molecule/converge.yml +0 -7
- package/templates/projects/molecule/molecule.yml +0 -16
- package/templates/projects/node/.github/workflows/ci.yml +0 -30
- package/templates/projects/node/README.md +0 -7
- package/templates/projects/node/package-lock.json +0 -12
- package/templates/projects/node/package.json +0 -10
- package/templates/projects/node/src/index.js +0 -3
- package/templates/projects/packer/README.md +0 -15
- package/templates/projects/packer/main.pkr.hcl +0 -15
- package/templates/projects/python/.github/workflows/ci.yml +0 -34
- package/templates/projects/python/README.md +0 -7
- package/templates/projects/python/pyproject.toml +0 -25
- package/templates/projects/python/src/__PROJECT_NAME__/__init__.py +0 -2
- package/templates/projects/python/tests/test_basic.py +0 -3
|
@@ -1,467 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
## Security Score Assessment.
|
|
5
|
-
##
|
|
6
|
-
## Evaluates system security posture across encryption, SSH, Git, system
|
|
7
|
-
## hardening, and secrets management. Returns a letter grade (A+ to F) with
|
|
8
|
-
## actionable recommendations.
|
|
9
|
-
##
|
|
10
|
-
## # Usage
|
|
11
|
-
## dot security-score [--verbose|-v] [--json|-j] [--quiet|-q]
|
|
12
|
-
##
|
|
13
|
-
## # Dependencies
|
|
14
|
-
## - age: Encryption tool check
|
|
15
|
-
## - sops: Secrets manager check
|
|
16
|
-
## - gpg: Key management check
|
|
17
|
-
## - git: Commit signing verification
|
|
18
|
-
##
|
|
19
|
-
## # Platform Notes
|
|
20
|
-
## - macOS: Checks socketfilterfw, FileVault, Little Snitch
|
|
21
|
-
## - Linux: Checks ufw/firewalld, LUKS encryption
|
|
22
|
-
## - WSL: Checks host encryption, virtualization detection
|
|
23
|
-
##
|
|
24
|
-
## # Security
|
|
25
|
-
## Does not modify system state. Read-only checks only.
|
|
26
|
-
##
|
|
27
|
-
## # Idempotency
|
|
28
|
-
## Safe to run repeatedly. No side effects.
|
|
29
|
-
|
|
30
|
-
set -euo pipefail
|
|
31
|
-
set +o xtrace 2>/dev/null || true
|
|
32
|
-
|
|
33
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
34
|
-
# shellcheck source=../../lib/dot/ui.sh
|
|
35
|
-
# shellcheck disable=SC1091
|
|
36
|
-
source "$SCRIPT_DIR/../../lib/dot/ui.sh"
|
|
37
|
-
|
|
38
|
-
# Parse arguments
|
|
39
|
-
VERBOSE=true
|
|
40
|
-
JSON_OUTPUT=false
|
|
41
|
-
while [[ $# -gt 0 ]]; do
|
|
42
|
-
case "$1" in
|
|
43
|
-
--verbose | -v)
|
|
44
|
-
VERBOSE=true
|
|
45
|
-
shift
|
|
46
|
-
;;
|
|
47
|
-
--quiet | -q)
|
|
48
|
-
VERBOSE=false
|
|
49
|
-
shift
|
|
50
|
-
;;
|
|
51
|
-
--json | -j)
|
|
52
|
-
JSON_OUTPUT=true
|
|
53
|
-
shift
|
|
54
|
-
;;
|
|
55
|
-
*) shift ;;
|
|
56
|
-
esac
|
|
57
|
-
done
|
|
58
|
-
|
|
59
|
-
ui_init
|
|
60
|
-
NC="${NORMAL}"
|
|
61
|
-
RED="${RED:-}"
|
|
62
|
-
GREEN="${GREEN:-}"
|
|
63
|
-
YELLOW="${YELLOW:-}"
|
|
64
|
-
|
|
65
|
-
# Scoring
|
|
66
|
-
TOTAL_POINTS=0
|
|
67
|
-
MAX_POINTS=0
|
|
68
|
-
# Parallel indexed arrays instead of `declare -A` (bash 4+; macOS ships
|
|
69
|
-
# bash 3.2). CAT_NAMES[i] holds a category name, CAT_SCORES[i] its running
|
|
70
|
-
# total. Category names can contain spaces, so an emulation via dynamic
|
|
71
|
-
# variable names wouldn't work — a linear scan over the handful of
|
|
72
|
-
# categories is fine.
|
|
73
|
-
CAT_NAMES=()
|
|
74
|
-
CAT_SCORES=()
|
|
75
|
-
|
|
76
|
-
_cat_add() {
|
|
77
|
-
local name="$1" pts="$2" i
|
|
78
|
-
for ((i = 0; i < ${#CAT_NAMES[@]}; i++)); do
|
|
79
|
-
if [[ "${CAT_NAMES[$i]}" == "$name" ]]; then
|
|
80
|
-
CAT_SCORES[i]=$((CAT_SCORES[i] + pts))
|
|
81
|
-
return 0
|
|
82
|
-
fi
|
|
83
|
-
done
|
|
84
|
-
CAT_NAMES+=("$name")
|
|
85
|
-
CAT_SCORES+=("$pts")
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
add_points() {
|
|
89
|
-
local category="$1"
|
|
90
|
-
local points="$2"
|
|
91
|
-
local max="$3"
|
|
92
|
-
local description="$4"
|
|
93
|
-
|
|
94
|
-
TOTAL_POINTS=$((TOTAL_POINTS + points))
|
|
95
|
-
MAX_POINTS=$((MAX_POINTS + max))
|
|
96
|
-
_cat_add "$category" "$points"
|
|
97
|
-
|
|
98
|
-
if ! $JSON_OUTPUT && $VERBOSE; then
|
|
99
|
-
local icon
|
|
100
|
-
local color=""
|
|
101
|
-
if [[ $points -eq $max ]]; then
|
|
102
|
-
icon="✓"
|
|
103
|
-
color="$GREEN"
|
|
104
|
-
elif [[ $points -gt 0 ]]; then
|
|
105
|
-
icon="◐"
|
|
106
|
-
color="$YELLOW"
|
|
107
|
-
else
|
|
108
|
-
icon="✗"
|
|
109
|
-
color="$RED"
|
|
110
|
-
fi
|
|
111
|
-
|
|
112
|
-
if [[ "$UI_ENABLED" = "1" ]]; then
|
|
113
|
-
ui_status "$icon" "[OK]" "$description" "$points/$max pts" "$color"
|
|
114
|
-
else
|
|
115
|
-
ui_bullet "$description ($points/$max pts)"
|
|
116
|
-
fi
|
|
117
|
-
fi
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
print_header() {
|
|
121
|
-
if ! $JSON_OUTPUT; then
|
|
122
|
-
echo ""
|
|
123
|
-
ui_dot_banner "Diagnostics"
|
|
124
|
-
ui_header "Security Score Assessment"
|
|
125
|
-
echo ""
|
|
126
|
-
fi
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
section() {
|
|
130
|
-
if ! $JSON_OUTPUT; then
|
|
131
|
-
echo ""
|
|
132
|
-
ui_section "$1"
|
|
133
|
-
if [[ "$UI_ENABLED" != "1" ]]; then
|
|
134
|
-
echo "───────────────────────────────────────────────"
|
|
135
|
-
fi
|
|
136
|
-
fi
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
# === Security Checks ===
|
|
140
|
-
|
|
141
|
-
check_encryption() {
|
|
142
|
-
section "Encryption (30 pts max)"
|
|
143
|
-
|
|
144
|
-
# Age encryption tool
|
|
145
|
-
if command -v age >/dev/null 2>&1; then
|
|
146
|
-
add_points "encryption" 5 5 "Age encryption installed"
|
|
147
|
-
else
|
|
148
|
-
add_points "encryption" 0 5 "Age encryption installed"
|
|
149
|
-
fi
|
|
150
|
-
|
|
151
|
-
# Age key exists
|
|
152
|
-
if [[ -f "${HOME}/.config/chezmoi/key.txt" ]]; then
|
|
153
|
-
add_points "encryption" 5 5 "Age encryption key present"
|
|
154
|
-
|
|
155
|
-
# Check key permissions
|
|
156
|
-
local perms
|
|
157
|
-
perms=$(stat -c "%a" "${HOME}/.config/chezmoi/key.txt" 2>/dev/null || stat -f "%OLp" "${HOME}/.config/chezmoi/key.txt" 2>/dev/null)
|
|
158
|
-
if [[ "$perms" == "600" ]]; then
|
|
159
|
-
add_points "encryption" 5 5 "Key file permissions (600)"
|
|
160
|
-
else
|
|
161
|
-
add_points "encryption" 2 5 "Key file permissions (600)"
|
|
162
|
-
fi
|
|
163
|
-
else
|
|
164
|
-
add_points "encryption" 0 10 "Age encryption configured"
|
|
165
|
-
fi
|
|
166
|
-
|
|
167
|
-
# SOPS available
|
|
168
|
-
if command -v sops >/dev/null 2>&1; then
|
|
169
|
-
add_points "encryption" 5 5 "SOPS secrets manager"
|
|
170
|
-
else
|
|
171
|
-
add_points "encryption" 0 5 "SOPS secrets manager"
|
|
172
|
-
fi
|
|
173
|
-
|
|
174
|
-
# Signing key material: this repo uses SSH ED25519 signing by default, with
|
|
175
|
-
# GPG still accepted for users who prefer it.
|
|
176
|
-
local signing_format signing_key
|
|
177
|
-
signing_format="$(git config --global gpg.format 2>/dev/null || true)"
|
|
178
|
-
signing_key="$(git config --global user.signingkey 2>/dev/null || true)"
|
|
179
|
-
signing_key="${signing_key/#\~/$HOME}"
|
|
180
|
-
if command -v gpg >/dev/null 2>&1 && gpg --list-secret-keys 2>/dev/null | grep -q sec; then
|
|
181
|
-
add_points "encryption" 10 10 "Signing key configured (GPG)"
|
|
182
|
-
elif [[ "$signing_format" == "ssh" && -n "$signing_key" && -f "$signing_key" ]]; then
|
|
183
|
-
add_points "encryption" 10 10 "Signing key configured (SSH)"
|
|
184
|
-
elif command -v gpg >/dev/null 2>&1; then
|
|
185
|
-
add_points "encryption" 3 10 "Signing key configured"
|
|
186
|
-
else
|
|
187
|
-
add_points "encryption" 0 10 "Signing key configured"
|
|
188
|
-
fi
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
check_ssh() {
|
|
192
|
-
section "SSH Security (25 pts max)"
|
|
193
|
-
|
|
194
|
-
# SSH directory permissions
|
|
195
|
-
if [[ -d "${HOME}/.ssh" ]]; then
|
|
196
|
-
local ssh_perms
|
|
197
|
-
ssh_perms=$(stat -c "%a" "${HOME}/.ssh" 2>/dev/null || stat -f "%OLp" "${HOME}/.ssh" 2>/dev/null)
|
|
198
|
-
if [[ "$ssh_perms" == "700" ]]; then
|
|
199
|
-
add_points "ssh" 5 5 "SSH directory permissions (700)"
|
|
200
|
-
else
|
|
201
|
-
add_points "ssh" 2 5 "SSH directory permissions (700)"
|
|
202
|
-
fi
|
|
203
|
-
else
|
|
204
|
-
add_points "ssh" 0 5 "SSH directory exists"
|
|
205
|
-
fi
|
|
206
|
-
|
|
207
|
-
# ED25519 key (preferred over RSA)
|
|
208
|
-
if [[ -f "${HOME}/.ssh/id_ed25519" ]]; then
|
|
209
|
-
add_points "ssh" 10 10 "ED25519 SSH key (modern)"
|
|
210
|
-
elif [[ -f "${HOME}/.ssh/id_rsa" ]]; then
|
|
211
|
-
add_points "ssh" 5 10 "SSH key present (RSA)"
|
|
212
|
-
else
|
|
213
|
-
add_points "ssh" 0 10 "SSH key present"
|
|
214
|
-
fi
|
|
215
|
-
|
|
216
|
-
# SSH agent
|
|
217
|
-
if [[ -n "${SSH_AUTH_SOCK:-}" ]] || pgrep -x ssh-agent >/dev/null 2>&1; then
|
|
218
|
-
add_points "ssh" 5 5 "SSH agent running"
|
|
219
|
-
else
|
|
220
|
-
add_points "ssh" 0 5 "SSH agent running"
|
|
221
|
-
fi
|
|
222
|
-
|
|
223
|
-
# SSH config exists
|
|
224
|
-
if [[ -f "${HOME}/.ssh/config" ]]; then
|
|
225
|
-
add_points "ssh" 5 5 "SSH config present"
|
|
226
|
-
else
|
|
227
|
-
add_points "ssh" 2 5 "SSH config present"
|
|
228
|
-
fi
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
check_git() {
|
|
232
|
-
section "Git Security (20 pts max)"
|
|
233
|
-
|
|
234
|
-
# Git installed
|
|
235
|
-
if ! command -v git >/dev/null 2>&1; then
|
|
236
|
-
add_points "git" 0 20 "Git installed"
|
|
237
|
-
return
|
|
238
|
-
fi
|
|
239
|
-
|
|
240
|
-
# Commit signing
|
|
241
|
-
if git config --global commit.gpgsign 2>/dev/null | grep -q true; then
|
|
242
|
-
add_points "git" 10 10 "Commit signing enabled"
|
|
243
|
-
else
|
|
244
|
-
add_points "git" 0 10 "Commit signing enabled"
|
|
245
|
-
fi
|
|
246
|
-
|
|
247
|
-
# User identity configured
|
|
248
|
-
if git config --global user.email >/dev/null 2>&1 && git config --global user.name >/dev/null 2>&1; then
|
|
249
|
-
add_points "git" 5 5 "Git identity configured"
|
|
250
|
-
else
|
|
251
|
-
add_points "git" 0 5 "Git identity configured"
|
|
252
|
-
fi
|
|
253
|
-
|
|
254
|
-
# Credential helper
|
|
255
|
-
if git config --global credential.helper >/dev/null 2>&1; then
|
|
256
|
-
add_points "git" 5 5 "Credential helper configured"
|
|
257
|
-
else
|
|
258
|
-
add_points "git" 0 5 "Credential helper configured"
|
|
259
|
-
fi
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
check_system() {
|
|
263
|
-
section "System Security (15 pts max)"
|
|
264
|
-
|
|
265
|
-
# Firewall (macOS or Linux)
|
|
266
|
-
if [[ "$(uname)" == "Darwin" ]]; then
|
|
267
|
-
if /usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate 2>/dev/null | grep -q enabled; then
|
|
268
|
-
add_points "system" 5 5 "Firewall enabled"
|
|
269
|
-
elif pgrep -x "Little Snitch" >/dev/null 2>&1 || [[ -d "/Applications/Little Snitch.app" ]]; then
|
|
270
|
-
add_points "system" 5 5 "Firewall enabled (Little Snitch)"
|
|
271
|
-
else
|
|
272
|
-
add_points "system" 0 5 "Firewall enabled"
|
|
273
|
-
fi
|
|
274
|
-
else
|
|
275
|
-
# Check ufw via systemctl (doesn't need sudo) or sudo ufw status
|
|
276
|
-
local fw_enabled=false
|
|
277
|
-
if systemctl is-active --quiet ufw 2>/dev/null; then
|
|
278
|
-
fw_enabled=true
|
|
279
|
-
elif command -v ufw >/dev/null 2>&1 && sudo -n ufw status 2>/dev/null | grep -q "Status: active"; then
|
|
280
|
-
fw_enabled=true
|
|
281
|
-
elif command -v firewall-cmd >/dev/null 2>&1 && firewall-cmd --state 2>/dev/null | grep -q running; then
|
|
282
|
-
fw_enabled=true
|
|
283
|
-
fi
|
|
284
|
-
|
|
285
|
-
if $fw_enabled; then
|
|
286
|
-
add_points "system" 5 5 "Firewall enabled"
|
|
287
|
-
else
|
|
288
|
-
add_points "system" 0 5 "Firewall enabled"
|
|
289
|
-
fi
|
|
290
|
-
fi
|
|
291
|
-
|
|
292
|
-
# Disk encryption (LUKS, FileVault, or ecryptfs)
|
|
293
|
-
if [[ "$(uname)" == "Darwin" ]]; then
|
|
294
|
-
if fdesetup status 2>/dev/null | grep -q "FileVault is On"; then
|
|
295
|
-
add_points "system" 10 10 "Disk encryption (FileVault)"
|
|
296
|
-
elif diskutil apfs list 2>/dev/null | grep -q "FileVault:[[:space:]]*Yes"; then
|
|
297
|
-
add_points "system" 10 10 "Disk encryption (APFS FileVault)"
|
|
298
|
-
else
|
|
299
|
-
add_points "system" 0 10 "Disk encryption (FileVault)"
|
|
300
|
-
fi
|
|
301
|
-
else
|
|
302
|
-
local encryption_found=false
|
|
303
|
-
# Check LUKS
|
|
304
|
-
if lsblk 2>/dev/null | grep -q crypt || [[ -d /sys/block/dm-0 ]]; then
|
|
305
|
-
encryption_found=true
|
|
306
|
-
add_points "system" 10 10 "Disk encryption (LUKS)"
|
|
307
|
-
# Check Apple T2 chip (hardware SSD encryption)
|
|
308
|
-
elif lspci 2>/dev/null | grep -qi "T2.*Secure Enclave"; then
|
|
309
|
-
encryption_found=true
|
|
310
|
-
add_points "system" 10 10 "Hardware encryption (Apple T2)"
|
|
311
|
-
# Check ecryptfs (encrypted home)
|
|
312
|
-
elif mount 2>/dev/null | grep -q ecryptfs || [[ -d "$HOME/.ecryptfs" ]]; then
|
|
313
|
-
encryption_found=true
|
|
314
|
-
add_points "system" 10 10 "Home encryption (ecryptfs)"
|
|
315
|
-
# Check if running in encrypted VM/container
|
|
316
|
-
elif [[ -f /sys/class/dmi/id/product_name ]] && grep -qiE "virtual|vmware|kvm|qemu" /sys/class/dmi/id/product_name 2>/dev/null; then
|
|
317
|
-
encryption_found=true
|
|
318
|
-
add_points "system" 10 10 "Virtualized (host encryption)"
|
|
319
|
-
fi
|
|
320
|
-
|
|
321
|
-
if ! $encryption_found; then
|
|
322
|
-
add_points "system" 0 10 "Disk encryption"
|
|
323
|
-
fi
|
|
324
|
-
fi
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
check_secrets() {
|
|
328
|
-
section "Secrets Management (10 pts max)"
|
|
329
|
-
|
|
330
|
-
# No secrets in dotfiles repo
|
|
331
|
-
if [[ -d "${HOME}/.dotfiles" ]]; then
|
|
332
|
-
local secrets_found=false
|
|
333
|
-
local match=""
|
|
334
|
-
# Check for common secret patterns, ignore templates/placeholders and variable expansions.
|
|
335
|
-
match=$(grep -rE "^[[:space:]]*(export[[:space:]]+)?[A-Za-z_]*(api_key|api_secret|password|token)[A-Za-z_]*[[:space:]]*=[[:space:]]*['\"][^'\"]+['\"]" \
|
|
336
|
-
"${HOME}/.dotfiles" --include="*.sh" --include="*.zsh" --include="*.toml" 2>/dev/null |
|
|
337
|
-
grep -v "example\\|template\\|placeholder" | grep -F -v "\${" | head -1 || true)
|
|
338
|
-
if [[ -n "$match" ]]; then
|
|
339
|
-
secrets_found=true
|
|
340
|
-
fi
|
|
341
|
-
|
|
342
|
-
if $secrets_found; then
|
|
343
|
-
add_points "secrets" 0 5 "No hardcoded secrets"
|
|
344
|
-
else
|
|
345
|
-
add_points "secrets" 5 5 "No hardcoded secrets"
|
|
346
|
-
fi
|
|
347
|
-
else
|
|
348
|
-
add_points "secrets" 5 5 "No hardcoded secrets"
|
|
349
|
-
fi
|
|
350
|
-
|
|
351
|
-
# Environment variables for secrets
|
|
352
|
-
if [[ -f "${HOME}/.config/secrets/api-keys.env" ]] || [[ -d "${HOME}/.config/secrets" ]]; then
|
|
353
|
-
add_points "secrets" 5 5 "Secrets in dedicated location"
|
|
354
|
-
else
|
|
355
|
-
add_points "secrets" 2 5 "Secrets management setup"
|
|
356
|
-
fi
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
print_summary() {
|
|
360
|
-
local score=$((TOTAL_POINTS * 100 / MAX_POINTS))
|
|
361
|
-
|
|
362
|
-
if $JSON_OUTPUT; then
|
|
363
|
-
echo "{"
|
|
364
|
-
echo " \"score\": $score,"
|
|
365
|
-
echo " \"points\": $TOTAL_POINTS,"
|
|
366
|
-
echo " \"max_points\": $MAX_POINTS,"
|
|
367
|
-
echo " \"grade\": \"$(get_grade $score)\","
|
|
368
|
-
echo " \"categories\": {"
|
|
369
|
-
local first=true
|
|
370
|
-
local _ci
|
|
371
|
-
for ((_ci = 0; _ci < ${#CAT_NAMES[@]}; _ci++)); do
|
|
372
|
-
$first || echo ","
|
|
373
|
-
first=false
|
|
374
|
-
printf " \"%s\": %d" "${CAT_NAMES[$_ci]}" "${CAT_SCORES[$_ci]}"
|
|
375
|
-
done
|
|
376
|
-
echo ""
|
|
377
|
-
echo " }"
|
|
378
|
-
echo "}"
|
|
379
|
-
return
|
|
380
|
-
fi
|
|
381
|
-
|
|
382
|
-
echo ""
|
|
383
|
-
ui_header "Security Score"
|
|
384
|
-
echo ""
|
|
385
|
-
|
|
386
|
-
local bar_width=28
|
|
387
|
-
local filled=$((score * bar_width / 100))
|
|
388
|
-
local empty=$((bar_width - filled))
|
|
389
|
-
local block="#"
|
|
390
|
-
local pad="-"
|
|
391
|
-
|
|
392
|
-
local grade
|
|
393
|
-
grade=$(get_grade $score)
|
|
394
|
-
|
|
395
|
-
printf " Score: "
|
|
396
|
-
if [[ $score -ge 80 ]]; then
|
|
397
|
-
printf '%s' "${GREEN}"
|
|
398
|
-
elif [[ $score -ge 60 ]]; then
|
|
399
|
-
printf '%s' "${YELLOW}"
|
|
400
|
-
else
|
|
401
|
-
printf '%s' "${RED}"
|
|
402
|
-
fi
|
|
403
|
-
printf "%${filled}s" | tr ' ' "$block"
|
|
404
|
-
printf '%s' "${NC}"
|
|
405
|
-
printf "%${empty}s" | tr ' ' "$pad"
|
|
406
|
-
printf " %s%% Grade: %s\n" "${score}" "${grade}"
|
|
407
|
-
|
|
408
|
-
printf '%b\n' "\n Points: ${TOTAL_POINTS}/${MAX_POINTS}"
|
|
409
|
-
echo ""
|
|
410
|
-
|
|
411
|
-
# Recommendations
|
|
412
|
-
if [[ $score -lt 100 ]]; then
|
|
413
|
-
ui_header "Recommendations"
|
|
414
|
-
if ! command -v age >/dev/null 2>&1; then
|
|
415
|
-
ui_bullet "Install age for encryption: brew install age"
|
|
416
|
-
fi
|
|
417
|
-
if ! command -v sops >/dev/null 2>&1; then
|
|
418
|
-
ui_bullet "Install SOPS for secrets: brew install sops"
|
|
419
|
-
fi
|
|
420
|
-
if ! git config --global commit.gpgsign 2>/dev/null | grep -q true; then
|
|
421
|
-
ui_bullet "Enable commit signing: git config --global commit.gpgsign true"
|
|
422
|
-
fi
|
|
423
|
-
if [[ ! -f "${HOME}/.ssh/id_ed25519" ]]; then
|
|
424
|
-
ui_bullet "Generate ED25519 SSH key: ssh-keygen -t ed25519"
|
|
425
|
-
fi
|
|
426
|
-
echo ""
|
|
427
|
-
fi
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
get_grade() {
|
|
431
|
-
local score=$1
|
|
432
|
-
if [[ $score -ge 95 ]]; then
|
|
433
|
-
echo "A+"
|
|
434
|
-
elif [[ $score -ge 90 ]]; then
|
|
435
|
-
echo "A"
|
|
436
|
-
elif [[ $score -ge 85 ]]; then
|
|
437
|
-
echo "A-"
|
|
438
|
-
elif [[ $score -ge 80 ]]; then
|
|
439
|
-
echo "B+"
|
|
440
|
-
elif [[ $score -ge 75 ]]; then
|
|
441
|
-
echo "B"
|
|
442
|
-
elif [[ $score -ge 70 ]]; then
|
|
443
|
-
echo "B-"
|
|
444
|
-
elif [[ $score -ge 65 ]]; then
|
|
445
|
-
echo "C+"
|
|
446
|
-
elif [[ $score -ge 60 ]]; then
|
|
447
|
-
echo "C"
|
|
448
|
-
elif [[ $score -ge 55 ]]; then
|
|
449
|
-
echo "C-"
|
|
450
|
-
elif [[ $score -ge 50 ]]; then
|
|
451
|
-
echo "D"
|
|
452
|
-
else
|
|
453
|
-
echo "F"
|
|
454
|
-
fi
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
# Main
|
|
458
|
-
export LANG="${LANG:-en_US.UTF-8}"
|
|
459
|
-
export LC_ALL="${LC_ALL:-en_US.UTF-8}"
|
|
460
|
-
|
|
461
|
-
print_header
|
|
462
|
-
check_encryption
|
|
463
|
-
check_ssh
|
|
464
|
-
check_git
|
|
465
|
-
check_system
|
|
466
|
-
check_secrets
|
|
467
|
-
print_summary
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
# Smoke tests to quickly verify toolchain health after installation/updates.
|
|
5
|
-
|
|
6
|
-
set -euo pipefail
|
|
7
|
-
|
|
8
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
-
# shellcheck source=../../lib/dot/ui.sh
|
|
10
|
-
# shellcheck disable=SC1091
|
|
11
|
-
source "$SCRIPT_DIR/../../lib/dot/ui.sh"
|
|
12
|
-
ui_init
|
|
13
|
-
|
|
14
|
-
ui_header "Dotfiles Smoke Tests"
|
|
15
|
-
|
|
16
|
-
declare -i passed=0
|
|
17
|
-
declare -i failed=0
|
|
18
|
-
|
|
19
|
-
check_cmd() {
|
|
20
|
-
local cmd="$1"
|
|
21
|
-
if command -v "$cmd" >/dev/null 2>&1; then
|
|
22
|
-
return 0
|
|
23
|
-
fi
|
|
24
|
-
if command -v mise >/dev/null 2>&1; then
|
|
25
|
-
if mise ls --installed 2>/dev/null | grep -qE "($cmd|aqua:.*$cmd)"; then
|
|
26
|
-
return 0
|
|
27
|
-
fi
|
|
28
|
-
fi
|
|
29
|
-
return 1
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
verify_cmd() {
|
|
33
|
-
local cmd="$1"
|
|
34
|
-
local expected_output="${2:-}"
|
|
35
|
-
|
|
36
|
-
if ! check_cmd "$cmd"; then
|
|
37
|
-
ui_err "$cmd" "not found"
|
|
38
|
-
failed+=1
|
|
39
|
-
return 1
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
if [[ -n "$expected_output" ]]; then
|
|
43
|
-
local output
|
|
44
|
-
# shellcheck disable=SC2015
|
|
45
|
-
output=$($cmd --version 2>&1 || $cmd version 2>&1 || true)
|
|
46
|
-
if echo "$output" | grep -q "$expected_output"; then
|
|
47
|
-
ui_ok "$cmd"
|
|
48
|
-
passed+=1
|
|
49
|
-
else
|
|
50
|
-
ui_err "$cmd" "output mismatch"
|
|
51
|
-
failed+=1
|
|
52
|
-
fi
|
|
53
|
-
else
|
|
54
|
-
ui_ok "$cmd"
|
|
55
|
-
passed+=1
|
|
56
|
-
fi
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
# Core utilities
|
|
60
|
-
verify_cmd "git" "git version"
|
|
61
|
-
verify_cmd "zsh" "zsh"
|
|
62
|
-
verify_cmd "chezmoi" "chezmoi version"
|
|
63
|
-
|
|
64
|
-
# Rust Toolchain / Frontier
|
|
65
|
-
verify_cmd "rg" "ripgrep"
|
|
66
|
-
verify_cmd "bat" "bat"
|
|
67
|
-
verify_cmd "eza" "eza"
|
|
68
|
-
verify_cmd "zoxide" "zoxide"
|
|
69
|
-
verify_cmd "zellij" "zellij"
|
|
70
|
-
verify_cmd "shfmt" "3."
|
|
71
|
-
|
|
72
|
-
# Process management
|
|
73
|
-
verify_cmd "pueue" "pueue"
|
|
74
|
-
|
|
75
|
-
# AI Tools
|
|
76
|
-
# Prevent sgpt from prompting for a key by piping empty string
|
|
77
|
-
export OPENAI_API_KEY="sk-placeholder-for-testing"
|
|
78
|
-
verify_cmd "sgpt" "ShellGPT"
|
|
79
|
-
verify_cmd "copilot" "copilot"
|
|
80
|
-
verify_cmd "kiro-cli" "kiro-cli"
|
|
81
|
-
|
|
82
|
-
echo ""
|
|
83
|
-
if [[ $failed -eq 0 ]]; then
|
|
84
|
-
ui_ok "All $passed tests passed"
|
|
85
|
-
else
|
|
86
|
-
ui_err "$failed failed" "$passed passed"
|
|
87
|
-
exit 1
|
|
88
|
-
fi
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# SPDX-License-Identifier: MIT
|
|
3
|
-
# Copyright (c) 2015-2026 Sebastien Rousseau
|
|
4
|
-
# Snapshot current system/tooling state
|
|
5
|
-
# Usage: dot snapshot [--baseline|-b] [--force|-f]
|
|
6
|
-
|
|
7
|
-
set -euo pipefail
|
|
8
|
-
|
|
9
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
10
|
-
# shellcheck source=../../lib/dot/ui.sh
|
|
11
|
-
# shellcheck disable=SC1091
|
|
12
|
-
source "$SCRIPT_DIR/../../lib/dot/ui.sh"
|
|
13
|
-
|
|
14
|
-
ui_init
|
|
15
|
-
|
|
16
|
-
BASELINE=false
|
|
17
|
-
FORCE=false
|
|
18
|
-
while [[ $# -gt 0 ]]; do
|
|
19
|
-
case "$1" in
|
|
20
|
-
--baseline | -b)
|
|
21
|
-
BASELINE=true
|
|
22
|
-
shift
|
|
23
|
-
;;
|
|
24
|
-
--force | -f)
|
|
25
|
-
FORCE=true
|
|
26
|
-
shift
|
|
27
|
-
;;
|
|
28
|
-
*) shift ;;
|
|
29
|
-
esac
|
|
30
|
-
done
|
|
31
|
-
|
|
32
|
-
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/dotfiles/snapshots"
|
|
33
|
-
mkdir -p "$STATE_DIR"
|
|
34
|
-
|
|
35
|
-
if $BASELINE; then
|
|
36
|
-
output="$STATE_DIR/baseline.json"
|
|
37
|
-
else
|
|
38
|
-
output="$STATE_DIR/snapshot_$(date +%Y%m%d_%H%M%S).json"
|
|
39
|
-
fi
|
|
40
|
-
|
|
41
|
-
if [[ -f "$output" && "$FORCE" != "true" ]]; then
|
|
42
|
-
ui_warn "Snapshot" "${output} already exists (use --force)"
|
|
43
|
-
exit 0
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
safe() { printf '%s' "$1" | sed 's/"/\\"/g'; }
|
|
47
|
-
|
|
48
|
-
get_version() {
|
|
49
|
-
local cmd="$1"
|
|
50
|
-
if command -v "$cmd" >/dev/null 2>&1; then
|
|
51
|
-
"$cmd" --version 2>/dev/null | head -1 | awk '{print $NF}'
|
|
52
|
-
else
|
|
53
|
-
echo ""
|
|
54
|
-
fi
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
os_name=$(uname -s 2>/dev/null || echo "unknown")
|
|
58
|
-
kernel=$(uname -r 2>/dev/null || echo "unknown")
|
|
59
|
-
shell_name=$(basename "${SHELL:-}" 2>/dev/null || echo "")
|
|
60
|
-
|
|
61
|
-
dot_version=""
|
|
62
|
-
if [[ -f "$SCRIPT_DIR/../../package.json" ]]; then
|
|
63
|
-
dot_version=$(sed -n 's/^[[:space:]]*"version"[[:space:]]*:[[:space:]]*"\([0-9.]*\)".*/\1/p' "$SCRIPT_DIR/../../package.json" | head -1)
|
|
64
|
-
fi
|
|
65
|
-
|
|
66
|
-
cat >"$output" <<JSON
|
|
67
|
-
{
|
|
68
|
-
"timestamp": "$(date -Iseconds)",
|
|
69
|
-
"os": "$(safe "$os_name")",
|
|
70
|
-
"kernel": "$(safe "$kernel")",
|
|
71
|
-
"shell": "$(safe "$shell_name")",
|
|
72
|
-
"dotfiles_version": "$(safe "$dot_version")",
|
|
73
|
-
"tools": {
|
|
74
|
-
"chezmoi": "$(safe "$(get_version chezmoi)")",
|
|
75
|
-
"git": "$(safe "$(get_version git)")",
|
|
76
|
-
"zsh": "$(safe "$(get_version zsh)")",
|
|
77
|
-
"node": "$(safe "$(get_version node)")",
|
|
78
|
-
"python": "$(safe "$(python3 --version 2>/dev/null | awk '{print $2}')")",
|
|
79
|
-
"rustc": "$(safe "$(rustc --version 2>/dev/null | awk '{print $2}')")",
|
|
80
|
-
"go": "$(safe "$(go version 2>/dev/null | awk '{print $3}')")",
|
|
81
|
-
"nvim": "$(safe "$(nvim --version 2>/dev/null | head -1 | awk '{print $2}')")",
|
|
82
|
-
"tmux": "$(safe "$(tmux -V 2>/dev/null | awk '{print $2}')")",
|
|
83
|
-
"starship": "$(safe "$(get_version starship)")",
|
|
84
|
-
"mise": "$(safe "$(get_version mise)")"
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
JSON
|
|
88
|
-
|
|
89
|
-
ui_dot_banner "Diagnostics"
|
|
90
|
-
ui_ok "Snapshot" "$output"
|