diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d00fbef..add40a8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,12 +22,6 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends zsh jq shellcheck - - name: Run OSS audit - shell: bash - env: - OSS_AUDIT_FORBIDDEN_REGEX: ${{ vars.OSS_AUDIT_FORBIDDEN_REGEX }} - run: scripts/oss-audit.sh - - name: Validate shell syntax shell: bash run: | diff --git a/.gitignore b/.gitignore index b2dea8c..834bb3f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # Configuración local (paths, tokens, datos personales) local/env.zsh -.oss-audit-denylist.local # macOS .DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index 90d9f4a..5fa8227 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ - Initial OSS-safe `cortex-dots` snapshot. - Generalized private paths and navigation defaults. - Removed custom font binary and private brand assets. -- Added MIT license, security policy, third-party notices, release checklist, and OSS audit script. +- Added MIT license, security policy, third-party notices, release checklist, and automated installer tests. ## 0.1.1 - 2026-07-04 @@ -17,11 +17,8 @@ - `scripts/test-install.sh` — automated installer tests (copy, symlink, stale-opposite scenarios). - `scripts/check-agent-state.sh` — agent-state validator for release checklist. -- `.oss-audit-denylist.local` — untracked personal denylist for OSS audit (one regex per line). -- `OSS_AUDIT_FORBIDDEN_REGEX` CI variable support — configure repo-level denylist without committing. +- Supply chain security rules — external tools must be pinned to specific versions, 15+ days old. ### Changed -- OSS audit script — externalized forbidden identifiers to env var + local denylist; no longer hardcodes private terms. -- CI — added installer integration tests step; passes `OSS_AUDIT_FORBIDDEN_REGEX` from repo vars. -- `.gitignore` — added `.oss-audit-denylist.local`. +- CI — added installer integration tests step. diff --git a/CLAUDE.md b/CLAUDE.md index 9a33567..d98df22 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -48,11 +48,9 @@ dotfiles/ │ └── shaders/ # 4 cursor shaders (glsl) ├── herdr/config.toml # Multiplexor → ~/.config/herdr/config.toml ├── claude/ -│ ├── statusline.sh # Statusline para Claude Code -│ └── themes/ # Temas Claude Code (cortex.json, cortex-green.json) +│ └── statusline.sh # Statusline para Claude Code ├── opencode/ -│ ├── tui.json # TUI config → ~/.config/opencode/tui.json -│ └── themes/ # Temas OpenCode +│ └── tui.json # TUI config → ~/.config/opencode/tui.json ├── lazygit/config.yml # LazyGit → ~/.config/lazygit/config.yml ├── local/ │ └── env.zsh.example # Template para ~/.config/cortex-dots/local/env.zsh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aeb2fe5..3e58b5e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -28,9 +28,28 @@ All changes to `main` require maintainer review. This is especially important fo - Do not commit secrets, tokens, private keys, real emails, private hostnames, private IPs, customer names, or machine-specific paths. - Put local/private values in `~/.config/cortex-dots/local/env.zsh`. - Keep examples generic and placeholder-based. -- Run `scripts/oss-audit.sh` before opening a PR. - Run the validation commands listed in `README.md` when touching scripts or config formats. +## Supply Chain Security + +Any external tool, CLI, or dependency installed by `install.sh` or referenced in scripts must be pinned to a specific version. Do not use `latest`, `^ SemVer` ranges, or unpinned references in installation commands. Versions must be at least 15 days old before adoption — supply chain attacks typically target newly published releases. + +```bash +# Good — pinned version, 15+ days old +curl -fsSL https://starship.rs/install.sh | sh -s -- -b "$HOME/.local/bin" -y --commit abc123 + +# Good — pinned package manager version +npm install -g some-cli@2.4.1 + +# Bad — no version pinning +curl -fsSL https://example.com/install | bash + +# Bad — latest tag +npm install -g some-cli@latest +``` + +For GitHub Actions in workflows, always use explicit commit SHAs (`@commit-sha`) or pinned minor versions (`@v4`). Avoid `${{ github.sha }}` or floating tags in production workflows. + ## Pull Request Expectations Every PR should include: diff --git a/README.md b/README.md index b6dd6b2..566c828 100644 --- a/README.md +++ b/README.md @@ -118,29 +118,16 @@ Transparency depends on your Linux compositor/window manager. Shaders are opt-in in `ghostty/config`; uncomment one `custom-shader` line only after confirming your GPU/driver handles it well. -## OSS Audit - -Run before publishing or packaging: - -```bash -scripts/oss-audit.sh -``` - -The audit scans tracked files only and fails on configured private identifiers, private paths, and email-shaped strings. -Set `OSS_AUDIT_FORBIDDEN_REGEX` or create an untracked `.oss-audit-denylist.local` file with one regex per line to add private denylist terms locally. -For CI, configure the repository variable `OSS_AUDIT_FORBIDDEN_REGEX` with private denylist terms instead of committing them. - ## Validation ```bash -scripts/oss-audit.sh scripts/test-install.sh scripts/test-install.sh --symlink scripts/test-install.sh --seed-stale-opposite scripts/test-install.sh --symlink --seed-stale-opposite bash -n install.sh zsh -n zsh/zshrc -for path in opencode/*.json opencode/**/*.json claude/themes/*.json; do jq . "$path" >/dev/null 2>&1 || echo "invalid: $path"; done +for path in opencode/*.json; do jq . "$path" >/dev/null 2>&1 || echo "invalid: $path"; done python3 - <<'PY' import pathlib, tomllib for path in pathlib.Path('.').rglob('*.toml'): diff --git a/claude/themes/cortex-green.json b/claude/themes/cortex-green.json deleted file mode 100644 index c6b9bbe..0000000 --- a/claude/themes/cortex-green.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "Cortex Green", - "base": "dark-ansi", - "overrides": { - "claude": "#3FB950", - "claudeShimmer": "#4CC55E", - "text": "#F6F8FA", - "inverseText": "#0F1419", - "inactive": "#A8B3C1", - "inactiveShimmer": "#A8B3C1", - "subtle": "#A8B3C1", - "suggestion": "#2D333B", - "permission": "#3FB950", - "permissionShimmer": "#4CC55E", - "remember": "#58A6FF", - "success": "#3FB950", - "error": "#FF7B72", - "warning": "#D29922", - "warningShimmer": "#E3B341", - "merged": "#A78BFA", - "promptBorder": "#3FB950", - "promptBorderShimmer": "#4CC55E", - "planMode": "#58A6FF", - "autoAccept": "#3FB950", - "bashBorder": "#D29922", - "ide": "#58A6FF", - "fastMode": "#58A6FF", - "fastModeShimmer": "#58A6FF", - "diffAdded": "#12301F", - "diffRemoved": "#331317", - "diffAddedDimmed": "#1C2128", - "diffRemovedDimmed": "#1C2128", - "diffAddedWord": "#3FB950", - "diffRemovedWord": "#FF7B72", - "userMessageBackground": "#1C2128", - "userMessageBackgroundHover": "#2D333B", - "messageActionsBackground": "#2D333B", - "bashMessageBackgroundColor": "#1C2128", - "memoryBackgroundColor": "#12301F", - "selectionBg": "#12301F", - "rate_limit_fill": "#3FB950", - "rate_limit_empty": "#2D333B", - "briefLabelYou": "#58A6FF", - "briefLabelClaude": "#3FB950", - "blue_FOR_SUBAGENTS_ONLY": "#58A6FF", - "green_FOR_SUBAGENTS_ONLY": "#3FB950", - "cyan_FOR_SUBAGENTS_ONLY": "#58A6FF", - "yellow_FOR_SUBAGENTS_ONLY": "#D29922", - "red_FOR_SUBAGENTS_ONLY": "#FF7B72", - "purple_FOR_SUBAGENTS_ONLY": "#A78BFA" - } -} diff --git a/claude/themes/cortex.json b/claude/themes/cortex.json deleted file mode 100644 index 66fa556..0000000 --- a/claude/themes/cortex.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "Cortex", - "base": "dark-daltonized", - "overrides": { - "claude": "#FB923C", - "claudeShimmer": "#FDBA74", - "text": "#F8F1E7", - "inverseText": "#0B0B0A", - "inactive": "#B9AD9C", - "inactiveShimmer": "#B9AD9C", - "subtle": "#B9AD9C", - "suggestion": "#7A3500", - "permission": "#FB923C", - "permissionShimmer": "#FDBA74", - "remember": "#60A5FA", - "success": "#10B981", - "error": "#F87171", - "warning": "#FBBF24", - "warningShimmer": "#FCD34D", - "merged": "#A78BFA", - "promptBorder": "#FB923C", - "promptBorderShimmer": "#FDBA74", - "planMode": "#FB923C", - "autoAccept": "#10B981", - "bashBorder": "#FBBF24", - "ide": "#60A5FA", - "fastMode": "#10B981", - "fastModeShimmer": "#34D399", - "diffAdded": "#0D2A20", - "diffRemoved": "#2C1210", - "diffAddedDimmed": "#171512", - "diffRemovedDimmed": "#171512", - "diffAddedWord": "#10B981", - "diffRemovedWord": "#F87171", - "userMessageBackground": "#171512", - "userMessageBackgroundHover": "#211F1A", - "messageActionsBackground": "#211F1A", - "bashMessageBackgroundColor": "#171512", - "memoryBackgroundColor": "#27231D", - "selectionBg": "#7A3500", - "rate_limit_fill": "#FB923C", - "rate_limit_empty": "#27231D", - "briefLabelYou": "#FB923C", - "briefLabelClaude": "#FB923C", - "blue_FOR_SUBAGENTS_ONLY": "#60A5FA", - "green_FOR_SUBAGENTS_ONLY": "#10B981", - "cyan_FOR_SUBAGENTS_ONLY": "#38BDF8", - "yellow_FOR_SUBAGENTS_ONLY": "#FBBF24", - "red_FOR_SUBAGENTS_ONLY": "#F87171", - "purple_FOR_SUBAGENTS_ONLY": "#A78BFA" - } -} diff --git a/docs/keymaps.md b/docs/keymaps.md index 69c6c70..5a2e2dd 100644 --- a/docs/keymaps.md +++ b/docs/keymaps.md @@ -47,7 +47,7 @@ This table favors the shortcuts used by these dotfiles and Herdr defaults. It is | OpenCode | `oc [path]` | Start OpenCode in the current or given directory. | | OpenCode | `ocb [path]` | Alias for `oc`, preserving default flags. | -Claude Code and OpenCode keybindings are mostly app-native. This repo adds launch helpers, themes/statusline config, and Herdr integration so sessions survive terminal detach/reattach. +Claude Code and OpenCode keybindings are mostly app-native. This repo adds launch helpers, statusline config, and Herdr integration so sessions survive terminal detach/reattach. ## Collision Notes diff --git a/install.sh b/install.sh index 783716d..b71780e 100755 --- a/install.sh +++ b/install.sh @@ -253,9 +253,7 @@ PY check_install_target "$DOTFILES/ghostty/config" "$HOME/.config/ghostty/config" check_install_target "$DOTFILES/ghostty/shaders" "$HOME/.config/ghostty/shaders" check_install_target "$DOTFILES/opencode/tui.json" "$HOME/.config/opencode/tui.json" - check_install_target "$DOTFILES/opencode/themes" "$HOME/.config/opencode/themes" check_install_target "$DOTFILES/claude/statusline.sh" "$HOME/.claude/statusline.sh" - check_install_target "$DOTFILES/claude/themes" "$HOME/.claude/themes" check_install_target "$DOTFILES/lazygit/config.yml" "$HOME/.config/lazygit/config.yml" echo "" @@ -266,7 +264,7 @@ PY for path in "$DOTFILES"/zsh/scripts/*.zsh; do check_shell "$path" zsh done - for path in "$DOTFILES"/opencode/*.json "$DOTFILES"/opencode/**/*.json "$DOTFILES"/claude/themes/*.json; do + for path in "$DOTFILES"/opencode/*.json; do check_json "$path" done check_toml "$DOTFILES/starship/starship.toml" @@ -799,9 +797,7 @@ backup_if_exists "$HOME/.config/herdr/config.toml" backup_if_exists "$HOME/.config/ghostty/config" backup_if_exists "$HOME/.config/herdr/config.toml" backup_if_exists "$HOME/.config/opencode/tui.json" -backup_if_exists "$HOME/.config/opencode/themes" backup_if_exists "$HOME/.claude/statusline.sh" -backup_if_exists "$HOME/.claude/themes" backup_if_exists "$HOME/.config/lazygit/config.yml" # --- Instalar configs --- @@ -880,10 +876,8 @@ install_target "$DOTFILES/herdr/config.toml" "$HOME/.config/herdr/config.to install_target "$DOTFILES/ghostty/config" "$HOME/.config/ghostty/config" install_target "$DOTFILES/ghostty/shaders" "$HOME/.config/ghostty/shaders" install_target "$DOTFILES/opencode/tui.json" "$HOME/.config/opencode/tui.json" -install_target "$DOTFILES/opencode/themes" "$HOME/.config/opencode/themes" install_target "$DOTFILES/claude/statusline.sh" "$HOME/.claude/statusline.sh" run_or_plan "chmod +x $HOME/.claude/statusline.sh" chmod +x "$HOME/.claude/statusline.sh" -install_target "$DOTFILES/claude/themes" "$HOME/.claude/themes" install_target "$DOTFILES/lazygit/config.yml" "$HOME/.config/lazygit/config.yml" if [[ "$GHOSTTY_DEFER_WORKER_NEEDED" == true ]]; then diff --git a/opencode/themes/cortex-green.json b/opencode/themes/cortex-green.json deleted file mode 100644 index 5506c2f..0000000 --- a/opencode/themes/cortex-green.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "$schema": "https://opencode.ai/theme.json", - "defs": { - "bg": "#0F1419", - "panel": "#1C2128", - "element": "#2D333B", - "text": "#F6F8FA", - "muted": "#A8B3C1", - "subtle": "#57606A", - "blue": "#58A6FF", - "blueHover": "#1a68ff", - "info": "#58A6FF", - "green": "#3FB950", - "greenHover": "#4CC55E", - "warning": "#D29922", - "error": "#FF7B72", - "purple": "#A78BFA" - }, - "theme": { - "primary": "blue", - "secondary": "info", - "accent": "green", - "error": "error", - "warning": "warning", - "success": "green", - "info": "info", - "text": "text", - "textMuted": "muted", - "background": "bg", - "backgroundPanel": "panel", - "backgroundElement": "element", - "border": "muted", - "borderActive": "blue", - "borderSubtle": "muted", - "diffAdded": "green", - "diffRemoved": "error", - "diffContext": "muted", - "diffHunkHeader": "info", - "diffHighlightAdded": "greenHover", - "diffHighlightRemoved": "error", - "diffAddedBg": "#12301F", - "diffRemovedBg": "#331317", - "diffContextBg": "panel", - "diffLineNumber": "muted", - "diffAddedLineNumberBg": "#12301F", - "diffRemovedLineNumberBg": "#331317", - "markdownText": "text", - "markdownHeading": "blue", - "markdownLink": "info", - "markdownLinkText": "green", - "markdownCode": "green", - "markdownBlockQuote": "muted", - "markdownEmph": "warning", - "markdownStrong": "text", - "markdownHorizontalRule": "muted", - "markdownListItem": "info", - "markdownListEnumeration": "green", - "markdownImage": "info", - "markdownImageText": "green", - "markdownCodeBlock": "text", - "syntaxComment": "muted", - "syntaxKeyword": "blue", - "syntaxFunction": "info", - "syntaxVariable": "text", - "syntaxString": "green", - "syntaxNumber": "purple", - "syntaxType": "green", - "syntaxOperator": "info", - "syntaxPunctuation": "muted" - } -} diff --git a/opencode/themes/cortex.json b/opencode/themes/cortex.json deleted file mode 100644 index 389e334..0000000 --- a/opencode/themes/cortex.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "$schema": "https://opencode.ai/theme.json", - "defs": { - "bg": "#0B0B0A", - "panel": "#171512", - "element": "#211F1A", - "text": "#F8F1E7", - "muted": "#B9AD9C", - "subtle": "#7D7468", - "info": "#60A5FA", - "orange": "#F97316", - "orangeHover": "#FB923C", - "warning": "#FBBF24", - "success": "#10B981", - "error": "#F87171", - "purple": "#A78BFA" - }, - "theme": { - "primary": "orange", - "secondary": "info", - "accent": "orange", - "error": "error", - "warning": "warning", - "success": "success", - "info": "info", - "text": "text", - "textMuted": "muted", - "background": "bg", - "backgroundPanel": "panel", - "backgroundElement": "element", - "border": "muted", - "borderActive": "orange", - "borderSubtle": "muted", - "diffAdded": "success", - "diffRemoved": "error", - "diffContext": "muted", - "diffHunkHeader": "info", - "diffHighlightAdded": "success", - "diffHighlightRemoved": "error", - "diffAddedBg": "#0D2A20", - "diffRemovedBg": "#2C1210", - "diffContextBg": "panel", - "diffLineNumber": "muted", - "diffAddedLineNumberBg": "#0D2A20", - "diffRemovedLineNumberBg": "#2C1210", - "markdownText": "text", - "markdownHeading": "orange", - "markdownLink": "info", - "markdownLinkText": "orange", - "markdownCode": "orangeHover", - "markdownBlockQuote": "muted", - "markdownEmph": "orange", - "markdownStrong": "text", - "markdownHorizontalRule": "muted", - "markdownListItem": "info", - "markdownListEnumeration": "info", - "markdownImage": "info", - "markdownImageText": "orange", - "markdownCodeBlock": "text", - "syntaxComment": "muted", - "syntaxKeyword": "orange", - "syntaxFunction": "info", - "syntaxVariable": "text", - "syntaxString": "success", - "syntaxNumber": "purple", - "syntaxType": "orangeHover", - "syntaxOperator": "muted", - "syntaxPunctuation": "muted" - } -} diff --git a/scripts/oss-audit.sh b/scripts/oss-audit.sh deleted file mode 100755 index 755addc..0000000 --- a/scripts/oss-audit.sh +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then - printf '%s\n' 'FAIL oss-audit must run inside a git worktree' >&2 - exit 1 -fi - -forbidden_regex="${OSS_AUDIT_FORBIDDEN_REGEX:-}" -email_regex='[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+[.][A-Za-z]{2,}' -failed=0 - -if [[ -f .oss-audit-denylist.local ]]; then - while IFS= read -r pattern; do - [[ -n "$pattern" && "$pattern" != \#* ]] || continue - if [[ -n "$forbidden_regex" ]]; then - forbidden_regex+="|$pattern" - else - forbidden_regex="$pattern" - fi - done < .oss-audit-denylist.local -fi - -if [[ -n "$forbidden_regex" ]]; then - set +e - LC_ALL=C grep -Eq "$forbidden_regex" /dev/null 2>/tmp/cortex-dots-oss-audit-regex-error - regex_status=$? - set -e - if [[ "$regex_status" -eq 2 ]]; then - printf '%s\n' 'FAIL invalid forbidden identifier regex' >&2 - cat /tmp/cortex-dots-oss-audit-regex-error >&2 - rm -f /tmp/cortex-dots-oss-audit-regex-error - exit 1 - fi -fi - -while IFS= read -r -d '' file; do - if [[ -n "$forbidden_regex" ]] && LC_ALL=C grep -nEI "$forbidden_regex" "$file" >/tmp/cortex-dots-oss-audit-match 2>/dev/null; then - printf 'FAIL forbidden identifier in %s\n' "$file" >&2 - cat /tmp/cortex-dots-oss-audit-match >&2 - failed=1 - fi - - if LC_ALL=C grep -nEI "$email_regex" "$file" >/tmp/cortex-dots-oss-audit-match 2>/dev/null; then - printf 'FAIL email-shaped string in %s\n' "$file" >&2 - cat /tmp/cortex-dots-oss-audit-match >&2 - failed=1 - fi -done < <(git ls-files -z) - -rm -f /tmp/cortex-dots-oss-audit-match /tmp/cortex-dots-oss-audit-regex-error - -if [[ "$failed" -ne 0 ]]; then - exit 1 -fi - -printf '%s\n' 'PASS oss-audit'