From 25624c9f2b1c01b49707d546b04c1942a005102e Mon Sep 17 00:00:00 2001 From: Joseph O'Brien Date: Wed, 8 Jul 2026 13:28:57 -0400 Subject: [PATCH] chore(nushell): move config payload out of tool repo --- notfiles.toml | 7 - nushell/.DS_Store | Bin 8196 -> 0 bytes nushell/.config/.DS_Store | Bin 8196 -> 0 bytes nushell/.config/nushell/.DS_Store | Bin 6148 -> 0 bytes nushell/.config/nushell/autoload/aliases.nu | 108 ----------- nushell/.config/nushell/autoload/audit.nu | 131 ------------- .../.config/nushell/autoload/did-you-mean.nu | 55 ------ nushell/.config/nushell/autoload/functions.nu | 168 ----------------- nushell/.config/nushell/autoload/nu_libs.nu | 10 - nushell/.config/nushell/autoload/nuenv.nu | 84 --------- .../.config/nushell/autoload/session-guard.nu | 51 ------ nushell/.config/nushell/autoload/settings.nu | 70 ------- .../.config/nushell/autoload/toolkit-hook.nu | 18 -- nushell/.config/nushell/config.nu | 94 ---------- nushell/.config/nushell/env.nu | 173 ------------------ 15 files changed, 969 deletions(-) delete mode 100644 notfiles.toml delete mode 100644 nushell/.DS_Store delete mode 100644 nushell/.config/.DS_Store delete mode 100644 nushell/.config/nushell/.DS_Store delete mode 100644 nushell/.config/nushell/autoload/aliases.nu delete mode 100644 nushell/.config/nushell/autoload/audit.nu delete mode 100644 nushell/.config/nushell/autoload/did-you-mean.nu delete mode 100644 nushell/.config/nushell/autoload/functions.nu delete mode 100644 nushell/.config/nushell/autoload/nu_libs.nu delete mode 100644 nushell/.config/nushell/autoload/nuenv.nu delete mode 100644 nushell/.config/nushell/autoload/session-guard.nu delete mode 100644 nushell/.config/nushell/autoload/settings.nu delete mode 100644 nushell/.config/nushell/autoload/toolkit-hook.nu delete mode 100644 nushell/.config/nushell/config.nu delete mode 100644 nushell/.config/nushell/env.nu diff --git a/notfiles.toml b/notfiles.toml deleted file mode 100644 index 194fdc1..0000000 --- a/notfiles.toml +++ /dev/null @@ -1,7 +0,0 @@ -[defaults] -target = "~" -ignore = [".git", ".DS_Store", "README.md", "LICENSE*", "notfiles.toml", ".notfiles-state.toml", ".nothooks-state.toml", "Cargo.toml", "Cargo.lock", "crates", "docs", "tests", "target", "scripts", "mise.toml", "deny.toml", "rustqual.toml", ".github", ".gitea", ".envrc", ".sccignore", ".codex", ".superpowers", ".remember", ".worktrees", ".ctx", "HANDOFF.md", "AGENTS.md", "preflight.md"] - -include = ["nushell"] - -[packages.nushell] diff --git a/nushell/.DS_Store b/nushell/.DS_Store deleted file mode 100644 index 8a9b3a7243799330581385b47370c47417d1712f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMTWl0n7(U;$&>1?=DHIr_g@vj_Y@jVrCC`eLGj8ZU{U24j3cP1M9_qAw;U_@6nm1Y4RILk#MiWX^xi ze>rE)Ki@ZJ&n#mM%{ilvF`Y3c)5WD$O4UUQxASXKkwOhOg5nuF$SgLH9`T0L_9X8} z5oI9CK$L+f15pN|3|tNwpgo%xd5V2sSfe`1K$L<1Wd`{BAx0OM@lcKn8N52E3XT9I zi%A_6YSTF&h>3+V9?EecgHRe%oE{K{B0OS1gp)nS-ATqnIWD9KXAt2G;min6CiD!?xx5wY8r?Dk`2fy+kgNOXdB^ zL3bqSr~I7PoXYOyy$;v4(}i{_-DR00eOg6}>-Z_lF|$E{Wtil$uiJ7Accj_PIffU+ zCWS#(WTj8jM@Q=$8){;!8XL!IVxx`qwKcKTs~X0}6nSp-$_?#(hwLH8y+P)qxv#YyD?bBxGX@RZ7 zzU4YzmzniQ_Gx7vC1P8~b=tBfw|8e;J2&KbeOh@YWoL4B$~T*AJ89iwlCI3lWL?{C zb3Ka>v!};5kNDg+$<)*9xmmv@7_7&l@r9R`^UQXW2DS2Lf`;}gCL{sMv03vgmt3`c zHD1^Pl+tCo9mY3p##@^22ts#>J0`wW_Umuv9R4DA(J2`oz&>H1!7X~~*Y z8?qdzuU@9B9Ud)GONEZt)~IU7A%cYF(Nz2fYwJ|K(@v#LTQd|9wx&VVyYnK?+Ky1U zzCzV|=!p)|QoK;N>3Us1z^C1r^8D6e)1g~>H=MhLY`xxKDr>fm5F|tG7SaZfj`Tce zvtjuzHwLR-r0!!V8D{#x63gl0K;izq;kPB20HM3$B6!Xv1TFBi?~H*b0} zXaxzaj@JscLfc&xt7i$ell8MK8)f&ghuKr?W%dp`!9HbQvG3VW>^A_@p9bZ zZ{U4=fDiEzKF3*njc@QH&PhyyG(#$tRB4{HSgMy+OKYSCX{{8Own^<$x706gT`G{S zSM&?Dl%m#zSBdTA=~E!5lyqzgN^RM?ZTpUY52en`5+s^CZ+?t3Yu(1C^B@$cEdcdG z_y?H(6H@}r2bh?E*VFofD;8E(sf!CtoXF5lB8z!M=G@dug!fYQN}0%_O%vT^>NPUa zM4K+UHI*x5BBmwibS`ja;+k35S{hvbqWztD;C`Bsjn=a;M`~|P!!3#DcwDCzNFejhPI=1T!kfp#k?sZ8^ zkr++q=l{)9fB(Ovb4G(j8Hh4)d1U~_iDaUg?rEwwjYPH>UHx?N!u`gD3__^lE?gfR o$4Q?5!;sps&=wEnxR7L_@{fNA;6K^^{!i*?|Bv?n|HS_P2SU!H*Z=?k diff --git a/nushell/.config/.DS_Store b/nushell/.config/.DS_Store deleted file mode 100644 index b65668a2ea5c52b29aebae688685e17e45939bb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMTWl0n7(U;$(3y6m(^6oNEi6Vsko#`u7msEN@;UrbE!Kj%ydwlw%)jD$JKIsZBT z?VSDR`{(4JWsIStWVJG8GR9QuoEkMWoS|_!?^Bu*ajJ-d>>0C}%UpMFYj4h=H8dmc#IGekQhs!$+yC%dFj zXGlpJk8uRz2uzItuidMd$4V?#J`GQn_@z5DGf^uip^|Opsv}Fsf6ND`-UqPv; zoH4UX)v9as3-rGJodbjVuu)%j?6K}b==ff+(=G-?hmG1`)F0cF^Sz#;&E*3*-!0|6 zVA!b3W!zlJ&4hNl>-IXg*u<+1az)>Dd;GxRZgvfZ_WqE|riccI0>2n`3TJ~3`IlNo zDX@3guJjOo{`v!?Wfk7GJ#ViWO_tbzHl7`>|T1u6}ldt`9ku?S;;bj$P~@ zbF6T5S0>2Wp5=IZ2g*+1WL>+@%jE4kG;7+idZVt^oNq2rjV5)lly&x%obZ6~)ws~q zueWILZNA05S;lLsCL~K1n&xgU=`7kbTB<78mn=2)zJPwDk%<&9Yu5F?n;p+G0@{in zu%%Tu``t{|b`49DW^F5VbD%8aY;1{`Ya4WPFz4s<^izU}xBeQ_+{3rsnhC=0g6+|f zK8W`2B-v0fnkm}dW1d}%xEqKo9v$(yQJ3X}J{O8#z0lmIs=K(ucFVFYalY;zZeciH z*$FB5^f-u=0^>7P)tV+AK~rj(oHo64(^Fz50@{>nk!+1FhDNrWrP)?C!iwxxc0YTB zJ=!9pHI zgeakmJ8>5d;cnc6hw&&L#}jxG&)_Azj92hBKElWN1fSwdoWQsE4nO0h!W1agN{yl` zbCpHPa%F|mrmR#}DJf->vO^hAM&!|z=&oWzay>CB8JbN_x}aQ;DWx2qCZ#rP+_ZVi zxsy`IXUQa*Gk0E+XV&UFV zsRra?t$wveiD*>HWuu> z*p6<(buap{2gAq^x;eHz6tE8gZo}<_?{OT&y|@n#;6Xe@7=MgV&N2Qhp2PEa0k7i? zyotB)F5bft9L0x(`p@w-zQ<4aZ4#EZO`up({5}=Sc|V<&SZ3<#1ATYgaPnyTnY65b zpj8;b!BiaY=;<4Wb+;D#~%9r~WXcd6HDQO)8?}k`jm7fBqpL OzW?LJ5S@X5R-#Es=_}+0CNd{TNdudeNU@P4h4kha+=h-@A>McflvP|H3WU&% zWWTZJWBW;K?+_6$55t0JPDCA=AdAuvnQofS%=rSyHOEMq9%vZ$>#>pOFHXtcJM8&D zPuTm>{`;Iq9O~3KJ}y@4yxr+(HqR}eZBD5lb1$}+ba_|a-)`D|!?*l)o8vWKk;=sx za0Z+KXTTZwDFgDnLAonN@0|f>z!~^rK< $cutoff) - } - - $rows | select ts hook commit file tier group label match_count -} - -# ── audit-summary ───────────────────────────────────────────────────────────── - -# Summarise audit log hits grouped by tier and group. -# Pass --since to limit to a recent window (e.g. "7day"). -def audit-summary [ - --since: string # Limit to entries newer than this duration (e.g. 7day) -] { - mut rows = _read_audit_log - - if ($since | is-not-empty) { - let cutoff = (date now) - ($since | into duration) - $rows = ($rows | where ts > $cutoff) - } - - if ($rows | is-empty) { - print "No audit entries found." - return - } - - $rows - | group-by tier - | transpose tier entries - | each { |t| - let total = ($t.entries | get match_count | math sum) - let by_group = ( - $t.entries - | group-by group - | transpose group rows - | each { |g| { group: $g.group, hits: ($g.rows | get match_count | math sum) } } - | sort-by hits -r - ) - { tier: $t.tier, total_hits: $total, breakdown: $by_group } - } - | sort-by total_hits -r -} - -# ── audit-scan ─────────────────────────────────────────────────────────────── - -# Scan files through the redaction auditor and log findings. -# With no args, scans staged git files (same as pre-commit hook). -# Pass file paths to scan specific files. -def audit-scan [ - ...files: string # Files to scan (default: staged git files) - --verbose (-v) # Print findings to terminal as well as logging -] { - let script = (_dotfiles | path join "scripts/redact-audit.sh") - - if not ($script | path exists) { - error make { msg: $"audit script not found: ($script)" } - } - - mut args = ["--hook", "manual"] - - if $verbose { $args = ($args | append "--verbose") } - - if ($files | is-empty) { - $args = ($args | append "--staged") - } else { - $args = ($args | append $files) - } - - ^bash $script ...$args -} - -# ── audit-top ───────────────────────────────────────────────────────────────── - -# Show the most frequently hit files in the audit log. -def audit-top [ - --n: int = 10 # Number of results to show - --since: string # Limit to entries newer than this duration (e.g. 7day) -] { - mut rows = _read_audit_log - - if ($since | is-not-empty) { - let cutoff = (date now) - ($since | into duration) - $rows = ($rows | where ts > $cutoff) - } - - $rows - | group-by file - | transpose file entries - | each { |f| { file: $f.file, hits: ($f.entries | get match_count | math sum), scans: ($f.entries | length) } } - | sort-by hits -r - | first $n -} diff --git a/nushell/.config/nushell/autoload/did-you-mean.nu b/nushell/.config/nushell/autoload/did-you-mean.nu deleted file mode 100644 index 251ed33..0000000 --- a/nushell/.config/nushell/autoload/did-you-mean.nu +++ /dev/null @@ -1,55 +0,0 @@ -# did-you-mean.nu — command_not_found hook -# Source: nushell/nu_scripts (nu-hooks/command_not_found) -# Suggests 3 closest commands from PATH when a command is not found. - -export def hook [] { - {|cmd| - let commands_in_path = ( - if ($nu.os-info.name == windows) { - $env.Path | each {|directory| - if ($directory | path exists) { - let cmd_exts = ( - $env.PATHEXT | str downcase | split row ';' | str trim --char . - ) - ls $directory - | get name - | path parse - | where {|it| - $cmd_exts | any {|ext| $ext == ($it.extension | str downcase)} - } - | get stem - } - } - } else { - $env.PATH | each {|directory| - if ($directory | path exists) { - ls $directory - | get name - | path parse - | update parent "" - | path join - } - } - } - | flatten - | wrap cmd - ) - - let closest_commands = ( - $commands_in_path - | insert distance {|it| $it.cmd | str distance $cmd} - | uniq - | sort-by distance - | get cmd - | first 3 - ) - - let pretty_commands = ( - $closest_commands | each {|cmd| - $" (ansi {fg: "default" attr: "di"})($cmd)(ansi reset)" - } - ) - - $"\ndid you mean?\n($pretty_commands | str join "\n")" - } -} diff --git a/nushell/.config/nushell/autoload/functions.nu b/nushell/.config/nushell/autoload/functions.nu deleted file mode 100644 index 202afee..0000000 --- a/nushell/.config/nushell/autoload/functions.nu +++ /dev/null @@ -1,168 +0,0 @@ -# Custom functions - -# ── nu_libs ────────────────────────────────────────────────────────────────── - -# Show all commands loaded from nu_libs, grouped by domain -def libs [ - --filter(-f): string = "" # filter by name substring -] { - let nu_libs_dir = "/Users/joe/dev/nu_libs/lib" - - # Build name→domain map by scanning export defs in each domain's files - let domain_map = ( - ls $nu_libs_dir - | where type == "dir" - | get name - | each {|dir| - let domain = $dir | path basename - let names = ( - glob $"($dir)/**/*.nu" - | each {|f| - open $f | lines - | where {|l| ($l | str starts-with "export def") or ($l | str starts-with "export alias")} - | each {|l| - # extract the command name: third or fourth word depending on flags - let parts = $l | split row " " | where {|p| ($p | str length) > 0} - # skip "export", "def"/"alias", and any --flags - $parts | skip 2 | where {|p| not ($p | str starts-with "-")} | first - } - | compact - } - | flatten - | compact - | each {|n| $n | str replace --all '"' "" | str replace --all "`" "" | str trim} - ) - $names | each {|n| {name: $n, domain: $domain}} - } - | flatten - | uniq-by name - | reduce -f {} {|x, acc| $acc | upsert $x.name $x.domain} - ) - - let nu_libs_names = $domain_map | columns - - help commands - | where command_type == "custom" - | where {|cmd| $cmd.name in $nu_libs_names} - | if ($filter | is-not-empty) { where name =~ $filter } else { $in } - | select name description - | each {|cmd| - $cmd | insert domain ($domain_map | get $cmd.name) - } - | sort-by domain name - | group-by domain - | transpose domain cmds - | each {|g| - print $"(ansi cyan_bold)── ($g.domain) ──(ansi reset)" - $g.cmds | select name description | print - } - null -} - -# ── Files ──────────────────────────────────────────────────────────────────── - -# Quick directory listing sorted by size -def dirsize [] { - ls | select name size type | sort-by size -r -} - -# Make a directory and cd into it -def --env mkcd [dir: string] { - mkdir $dir - cd $dir -} - -# ── Dotfiles ───────────────────────────────────────────────────────────────── - -# Run a mise task from the dotfiles repo -def dfr [...args: string] { - let root = ($env.HOME | path join "dotfiles") - ^mise --cd $root run ...$args -} - -# Run a just recipe from the dotfiles repo -def dfj [...args: string] { - let root = ($env.HOME | path join "dotfiles") - ^just --justfile $"($root)/Justfile" ...$args -} - -# ── Kubernetes ─────────────────────────────────────────────────────────────── - -# Tail logs across all namespaces (uses stern) -def klogs [pattern: string = "."] { - ^stern $pattern -A -} - -# ── Secrets / redaction ────────────────────────────────────────────────────── - -# Run a command and pipe its output through obfsck redact -def obfsrun [...args: string] { - let config = ($nu.home-path | path join "dotfiles/config/obfsck-secrets.yaml") - if (which obfsck | is-not-empty) { - ^$args.0 ...($args | skip 1) | ^obfsck --config $config - } else { - ^$args.0 ...($args | skip 1) - } -} - -# ── Docker / Colima ────────────────────────────────────────────────────────── - -def _colima_ensure_running [] { - if (which colima | is-empty) { return } - let profile = if ("COLIMA_PROFILE" in $env) { $env.COLIMA_PROFILE } else { "dev" } - let running = (^colima status --profile $profile | complete | get exit_code) == 0 - if not $running { - print $"[colima] Starting profile '($profile)' \(4 CPU, 6GB RAM, 60GB disk\)..." - ^colima start --profile $profile --cpu 4 --memory 6 --disk 60 --runtime docker - } -} - -def _colima_set_socket [] { - let dev_sock = ($env.HOME | path join ".colima/dev/docker.sock") - let default_sock = ($env.HOME | path join ".config/colima/default/docker.sock") - if ($dev_sock | path exists) { - $env.DOCKER_HOST = $"unix://($dev_sock)" - } else if ($default_sock | path exists) { - $env.DOCKER_HOST = $"unix://($default_sock)" - } -} - -def --wrapped docker [...args: string] { - _colima_ensure_running - _colima_set_socket - ^docker ...$args -} - -def --wrapped docker-compose [...args: string] { - _colima_ensure_running - _colima_set_socket - ^docker-compose ...$args -} - -def colima-restart [] { - colima-stop - colima-start -} - -# ── JS ─────────────────────────────────────────────────────────────────────── - -# Real npm bypass (bun alias doesn't cover maestro-ui which needs real npm) -def mnpm [...args: string] { - ^npm ...$args -} - -# ── Secrets helpers ────────────────────────────────────────────────────────── - -# Run a command with secrets injected from ~/.secrets via op run. -# Works around $HOME not being expanded by op CLI. -def oprun [...args: string] { - let secrets = ($env.HOME | path join ".secrets") - ^op run --account=my.1password.com $"--env-file=($secrets)" -- ...$args -} - -# ── Git helpers ────────────────────────────────────────────────────────────── - -# Push via gh credential helper -def _git_gh [...args: string] { - ^git -c credential.helper= -c "credential.helper=!/opt/homebrew/bin/gh auth git-credential" ...$args -} diff --git a/nushell/.config/nushell/autoload/nu_libs.nu b/nushell/.config/nushell/autoload/nu_libs.nu deleted file mode 100644 index 426a8eb..0000000 --- a/nushell/.config/nushell/autoload/nu_libs.nu +++ /dev/null @@ -1,10 +0,0 @@ -# nu_libs — load all lib/* modules on shell startup -# Managed by notfiles (nushell package). Link with: notfiles link nushell -# lib/ai is excluded from lib/mod.nu (requires runtime deps) — loaded separately below. -# lib/extensions is excluded (requires external project repos) — load manually as needed. - -const NU_LIBS = "/Users/joe/dev/nu_libs/lib/mod.nu" -const NU_LIBS_AI = "/Users/joe/dev/nu_libs/lib/ai/mod.nu" - -use $NU_LIBS * -use $NU_LIBS_AI * diff --git a/nushell/.config/nushell/autoload/nuenv.nu b/nushell/.config/nushell/autoload/nuenv.nu deleted file mode 100644 index 3a9005f..0000000 --- a/nushell/.config/nushell/autoload/nuenv.nu +++ /dev/null @@ -1,84 +0,0 @@ -# nuenv.nu — secure .env.nu loader (replaces direnv for Nu-native projects) -# Source: nushell/nu_scripts (nu-hooks/nuenv), adapted for local conventions. -# -# Usage: -# source autoload/nuenv.nu -# # In config.nu hooks section: -# $env.config.hooks.env_change.PWD = (... | append (nuenv-hook)) -# # Then in any project dir: -# nuenv allow # approve .env.nu (sha256 allowlist) -# nuenv disallow # revoke - -const NUENV_FILE = ($nu.cache-dir | path join 'nuenv' 'allowed.txt') - -def get-allowed []: [ nothing -> list ] { - if ($NUENV_FILE | path exists) { - open $NUENV_FILE | lines - } else { - [] - } -} - -# Returns the PWD-change hook record for use in env_change.PWD -export def nuenv-hook []: [ nothing -> record ] { - { - condition: {|_, after| $after | path join '.env.nu' | path exists } - code: $" - let allowed = if \('($NUENV_FILE)' | path exists\) { - open ($NUENV_FILE) | lines - } else { - [] - } - - if \(open .env.nu | hash sha256\) not-in $allowed { - error make --unspanned { - msg: $'\(ansi purple\)\('.env.nu' | path expand\)\(ansi reset\) is not allowed', - help: $'please run \(ansi default_dimmed\)nuenv allow\(ansi reset\) first', - } - } - - print $'[\(ansi yellow_bold\)nuenv\(ansi reset\)] loading \(ansi purple\)\('.env.nu' | path expand\)\(ansi reset\)' - source .env.nu - " - } -} - -def _log [msg: string, color: string] { - print $'[(ansi $color)nuenv(ansi reset)] (ansi purple)(".env.nu" | path expand)(ansi reset) ($msg)' -} - -def check-env-file [] { - if not (".env.nu" | path exists) { - error make --unspanned { - msg: $"(ansi red_bold)env file not found(ansi reset)", - help: $"no (ansi yellow).env.nu(ansi reset) in (ansi purple)(pwd)(ansi reset)", - } - } -} - -# Adds ./.env.nu to the allowlist -export def "nuenv allow" [] { - check-env-file - let allowed = get-allowed - let hash = open .env.nu | hash sha256 - if $hash in $allowed { - _log "is already allowed" "yellow_bold" - return - } - mkdir ($nu.cache-dir | path join "nuenv") - $hash | $in + "\n" out>> $NUENV_FILE - _log "has been allowed" "green_bold" -} - -# Removes ./.env.nu from the allowlist -export def "nuenv disallow" [] { - check-env-file - let allowed = get-allowed - let hash = open .env.nu | hash sha256 - if $hash not-in $allowed { - _log "is already disallowed" "yellow_bold" - return - } - $allowed | find --invert $hash | to text | save --force $NUENV_FILE - _log "has been disallowed" "green_bold" -} diff --git a/nushell/.config/nushell/autoload/session-guard.nu b/nushell/.config/nushell/autoload/session-guard.nu deleted file mode 100644 index 5e65bcc..0000000 --- a/nushell/.config/nushell/autoload/session-guard.nu +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env nu - -# Session Guard: Validates config/env file hashes and expected env keys at shell startup -# Runs at every nushell startup to detect configuration drift. - -def validate_session [] { - let baseline_path = $"($env.HOME)/.config/nushell/.session-baseline.json" - let files_to_check = [ - $"($env.HOME)/.config/nushell/env.nu" - $"($env.HOME)/.config/nushell/config.nu" - $"($env.HOME)/dev/.envrc" - $"($env.HOME)/dev/.env" - $"($env.HOME)/.mise.toml" - ] - let required_env_keys = [ - "ANTHROPIC_API_KEY" - "OPENAI_API_KEY" - "GITHUB_TOKEN" - ] - - # Check if baseline exists - if not ($baseline_path | path exists) { - print "[session-guard] No baseline found. Run session-baseline.nu to initialize." - return - } - - # Load baseline - let baseline = (open --raw $baseline_path | from json) - - # Check file hashes - for file_path in $files_to_check { - if ($file_path | path exists) { - let current_hash = (open --raw $file_path | hash sha256) - let file_name = ($file_path | path basename) - - if ($baseline.files | get -i $file_name) != $current_hash { - print $"[session-guard] DRIFT: ($file_name) hash changed" - } - } - } - - # Check required env vars - for key in $required_env_keys { - if ($env | get -i $key) == null { - print $"[session-guard] MISSING ENV: ($key)" - } - } -} - -# Run validation (silent if all OK) -validate_session diff --git a/nushell/.config/nushell/autoload/settings.nu b/nushell/.config/nushell/autoload/settings.nu deleted file mode 100644 index 36b29fb..0000000 --- a/nushell/.config/nushell/autoload/settings.nu +++ /dev/null @@ -1,70 +0,0 @@ -# Shell settings - -$env.config.show_banner = false -$env.config.history.file_format = "sqlite" -$env.config.history.max_size = 100_000 -$env.config.completions.external.enable = true -$env.config.edit_mode = "emacs" # or "vi" - -# ── Colors ─────────────────────────────────────────────────────────────────── -$env.config.color_config = { - separator: default - leading_trailing_space_bg: { attr: n } - header: green_bold - empty: blue - bool: light_cyan - int: default - filesize: cyan - duration: default - datetime: purple - range: default - float: default - string: default - nothing: default - binary: default - cell-path: default - row_index: green_bold - record: default - list: default - closure: green_bold - glob: cyan_bold - block: default - hints: dark_gray - search_result: { bg: red fg: default } - shape_binary: purple_bold - shape_block: blue_bold - shape_bool: light_cyan - shape_closure: green_bold - shape_custom: green - shape_datetime: cyan_bold - shape_directory: cyan - shape_external: cyan - shape_externalarg: green_bold - shape_external_resolved: light_yellow_bold - shape_filepath: cyan - shape_flag: blue_bold - shape_float: purple_bold - shape_glob_interpolation: cyan_bold - shape_globpattern: cyan_bold - shape_int: purple_bold - shape_internalcall: cyan_bold - shape_keyword: cyan_bold - shape_list: cyan_bold - shape_literal: blue - shape_match_pattern: green - shape_matching_brackets: { attr: u } - shape_nothing: light_cyan - shape_operator: yellow - shape_pipe: purple_bold - shape_range: yellow_bold - shape_record: cyan_bold - shape_redirection: purple_bold - shape_signature: green_bold - shape_string: green - shape_string_interpolation: cyan_bold - shape_table: blue_bold - shape_variable: purple - shape_vardecl: purple - shape_raw_string: light_purple - shape_garbage: { fg: default bg: red attr: b } -} diff --git a/nushell/.config/nushell/autoload/toolkit-hook.nu b/nushell/.config/nushell/autoload/toolkit-hook.nu deleted file mode 100644 index 8e241b9..0000000 --- a/nushell/.config/nushell/autoload/toolkit-hook.nu +++ /dev/null @@ -1,18 +0,0 @@ -# toolkit-hook.nu — auto-load toolkit.nu overlay on cd -# Source: nushell/nu_scripts (nu-hooks/toolkit) -# -# When you cd into a directory containing toolkit.nu, it loads as an overlay -# with the prefix "tk". Define project-local commands in toolkit.nu files. - -export def toolkit-hook [ - --name: string = "tk", - --color: string = "yellow_bold", -]: [ nothing -> record ] { - { - condition: {|_, after| $after | path join 'toolkit.nu' | path exists } - code: $" - print $'[\(ansi ($color)\)toolkit\(ansi reset\)] loading \(ansi purple\)toolkit.nu\(ansi reset\) as overlay' - overlay use --prefix toolkit.nu as ($name) - " - } -} diff --git a/nushell/.config/nushell/config.nu b/nushell/.config/nushell/config.nu deleted file mode 100644 index efb5ddb..0000000 --- a/nushell/.config/nushell/config.nu +++ /dev/null @@ -1,94 +0,0 @@ -# config.nu — main nushell configuration -# env.nu and autoload/ are sourced automatically by nushell before this file. - -# ── Vendor/autoload seeding ─────────────────────────────────────────────────── -# Generates tool init scripts into $nu.data-dir/vendor/autoload/ on every -# shell startup. Nushell auto-sources everything in that directory. - -let vendor = $nu.data-dir | path join "vendor/autoload" -mkdir $vendor - -# Ensure nix and mise are on PATH for vendor seeding — may already be set by env.nu -$env.PATH = ($env.PATH | prepend [ - ($env.HOME | path join ".nix-profile/bin") - ($env.HOME | path join ".local/share/mise/shims") -] | uniq) - -try { starship init nu | save -f ($vendor | path join "starship.nu") } -try { zoxide init nushell | save -f ($vendor | path join "zoxide.nu") } -try { ^mise activate nu | save -f ($vendor | path join "mise.nu") } -try { atuin init nu | save -f ($vendor | path join "atuin.nu") } -try { carapace _carapace nushell | save -f ($vendor | path join "carapace.nu") } - - -# ── User autoload ──────────────────────────────────────────────────────────── -# Sourced explicitly so they are available immediately (vendor/autoload is -# sourced before config.nu, so copying there only takes effect next session). -source autoload/settings.nu -source autoload/aliases.nu -source autoload/functions.nu -source autoload/audit.nu -source autoload/nuenv.nu -source autoload/did-you-mean.nu -source autoload/toolkit-hook.nu -source autoload/nu_libs.nu - -# ── Keybindings ─────────────────────────────────────────────────────────────── - -$env.config.keybindings = ($env.config.keybindings? | default [] | append [ - # Ctrl+F — fzf file picker, inserts selected path at cursor - { - name: fzf_file_picker - modifier: control - keycode: char_f - mode: [emacs, vi_insert] - event: { - send: executehostcommand - cmd: "commandline edit --insert (fd --type f | fzf | str trim)" - } - } -]) - -# ── Hooks ───────────────────────────────────────────────────────────────────── -# Prevent accumulation from repeated config.nu sourcing by tracking registration - -let pwd_hooks = [ - (nuenv-hook) - (toolkit-hook) - {|before, after| - let cache = ($env.HOME | path join ".cache/doob/status.json") - if not ($cache | path exists) { return } - let data = (open $cache | from json) - let overdue = ($data.overdue_total? | default 0) - if $overdue == 0 { return } - let repo = ($after | path basename) - let repo_count = ($data.overdue_by_repo? | default {} | get -o $repo | default 0) - if $repo_count > 0 { - print $"(ansi yellow)doob: ($repo_count) overdue in ($repo)(ansi reset)" - } else { - print $"(ansi dim)doob: ($overdue) overdue total(ansi reset)" - } - } -] - -# Guard against accumulation from repeated sourcing (e.g., user runs 'source config.nu') -if ($env.NUSHELL_CONFIG_SOURCED? == "true") { - # Already sourced in this session, skip hook registration -} else { - $env.config.hooks.env_change.PWD = $pwd_hooks - $env.NUSHELL_CONFIG_SOURCED = "true" -} - -# display_output: expand table columns on wide terminals -$env.config.hooks.display_output = {|| - if (term size).columns >= 100 { table -e } else { table } -} - -# command_not_found: fuzzy-match 3 closest commands from PATH -$env.config.hooks.command_not_found = (use autoload/did-you-mean.nu; hook) - -# go wrapper: install to $HOME/go/bin by default -def go [...args] { with-env { GOBIN: $"($env.HOME)/go/bin" } { ^go ...$args } } - -# naptrace: run from source checkout so prompts/ is found -def --wrapped naptrace [...args] { cd ~/dev/naptrace; ^naptrace ...$args } diff --git a/nushell/.config/nushell/env.nu b/nushell/.config/nushell/env.nu deleted file mode 100644 index a302d0b..0000000 --- a/nushell/.config/nushell/env.nu +++ /dev/null @@ -1,173 +0,0 @@ -# Environment variables - -# Guard: reset PWD to $HOME if inherited value is not an absolute path. -# if not ($env.PWD | str starts-with "/") { -# $env.PWD = $env.HOME -# } - -# ── PATH ──────────────────────────────────────────────────────────────────── -$env.PATH = ( - $env.PATH - | prepend ($env.HOME | path join ".local/bin") - | prepend ($env.HOME | path join ".local/share/mise/shims") - | prepend ($env.HOME | path join ".bun/bin") - | prepend "/opt/zerobrew/bin" - | prepend ($env.HOME | path join ".zerobrew/bin") - | prepend ($env.HOME | path join ".nix-profile/bin") - | prepend "/nix/var/nix/profiles/default/bin" - | prepend ($env.HOME | path join ".cargo/bin") - | prepend "/opt/homebrew/bin" - | prepend "/opt/homebrew/sbin" - | prepend "/opt/homebrew/opt/openjdk/bin" - | prepend "/opt/homebrew/share/google-cloud-sdk/bin" - | uniq -) - -# ── ENV_CONVERSIONS ────────────────────────────────────────────────────────── -# Teach nushell to handle colon-separated vars from external tools -$env.ENV_CONVERSIONS = { - PATH: { - from_string: { |s| $s | split row (char esep) | path expand -n } - to_string: { |v| $v | str join (char esep) } - } - XDG_DATA_DIRS: { - from_string: { |s| $s | split row (char esep) } - to_string: { |v| $v | str join (char esep) } - } -} - -# ── Core env ───────────────────────────────────────────────────────────────── -$env.SHLVL = 1 -$env.EDITOR = "vim" -$env.VISUAL = "zed --wait" -$env.BUN_INSTALL = ($env.HOME | path join ".bun") -$env.JAVA_HOME = "/opt/homebrew/opt/openjdk" -$env.RTK_HOOK_AUDIT = "1" - -# ── mise ───────────────────────────────────────────────────────────────────── -# Shims are on PATH above. Full activation (hooks, cd triggers) requires -# sourcing `mise activate nu` in config.nu — see settings.nu note. -$env.MISE_SHELL = "nu" - -# ── Secrets / SOPS ────────────────────────────────────────────────────────── -let age_key = ($env.HOME | path join ".config/sops/age/keys.txt") -# Populate keys.txt from 1Password if it's missing or contains only a placeholder -if (which op | is-not-empty) { - let needs_refresh = ( - not ($age_key | path exists) or - (open $age_key | str trim) == "AGE-SECRET-KEY-1TESTKEY" - ) - if $needs_refresh { - try { - op item get 6meypnchchq3tsb32mdnzxtlia --fields notesPlain - | str replace --all '"' '' - | lines - | where { |l| $l | str starts-with "AGE-SECRET-KEY" } - | str join "\n" - | save --force $age_key - } - } -} -if ($age_key | path exists) { - $env.SOPS_AGE_KEY_FILE = $age_key - $env.MISE_SOPS_AGE_KEY_FILE = $age_key -} - -# Bootstrap secrets (dotenv format, no op:// refs) -let bootstrap_secrets = ($env.HOME | path join ".config/dev-bootstrap/secrets.env") -if ($bootstrap_secrets | path exists) { - open $bootstrap_secrets - | lines - | where { |l| not ($l | str starts-with "#") and ($l | str trim | str length) > 0 } - | each { |l| $l | parse "{key}={value}" | first } - | each { |kv| load-env {($kv.key): $kv.value} } - | ignore -} - -# Cache dotenvx private key so nuenv .env.nu never re-prompts 1Password -if (which op | is-not-empty) and ($env.DOTENV_PRIVATE_KEY? | default "" | is-empty) { - try { - $env.DOTENV_PRIVATE_KEY = ( - op read "op://Personal/nihl7o2bojy53zy4aqtr7txyqi/password" - --account=my.1password.com - ) - } -} - -# ── Colima / Docker ────────────────────────────────────────────────────────── -let colima_dev_sock = ($env.HOME | path join ".colima/dev/docker.sock") -let colima_default_sock = ($env.HOME | path join ".config/colima/default/docker.sock") -if ($colima_dev_sock | path exists) { - $env.DOCKER_HOST = $"unix://($colima_dev_sock)" -} else if ($colima_default_sock | path exists) { - $env.DOCKER_HOST = $"unix://($colima_default_sock)" -} - -# ── Maestro ────────────────────────────────────────────────────────────────── -$env.MAESTRO_API_URL = "https://api.maestro-staging.toptal.net" -$env.MAESTRO_RESOURCE_PROFILE = "development" - - -# ── Homebrew ────────────────────────────────────────────────────────────────── -$env.HOMEBREW_PREFIX = "/opt/homebrew" -$env.HOMEBREW_CELLAR = "/opt/homebrew/Cellar" -$env.HOMEBREW_REPOSITORY = "/opt/homebrew" - -# ── Handon banner ──────────────────────────────────────────────────────────── -# Show top handoff items for current repo on shell start. -if (which handoff-detect | is-not-empty) { - let _result = (do { run-external "handoff-detect" $env.PWD } | complete) - if $_result.exit_code == 0 and ($_result.stdout | str trim | is-not-empty) { - print $"(ansi cyan)--- handoff ---" - print $_result.stdout - print (ansi reset) - } -} - -# ── SSH agent ──────────────────────────────────────────────────────────────── -# Prefer gpg-agent (YubiKey/OpenPGP), fall back to native macOS launchd agent. -$env.SSH_AUTH_SOCK = ( - [ - (^gpgconf --list-dirs agent-ssh-socket | str trim) - (glob "/var/run/com.apple.launchd.*/Listeners" | first | default "") - ] - | where { |it| $it | path exists } - | first - | default "" -) -$env.PATH = ($env.PATH | split row (char esep) | where { $in != "/Users/joe/Library/Application Support/carapace/bin" } | prepend "/Users/joe/Library/Application Support/carapace/bin") - -def --env get-env [name] { $env | get $name } -def --env set-env [name, value] { load-env { $name: $value } } -def --env unset-env [name] { hide-env $name } - -let carapace_completer = {|spans| - load-env { - CARAPACE_SHELL_BUILTINS: (help commands | where category != "" | get name | each { split row " " | first } | uniq | str join "\n") - CARAPACE_SHELL_FUNCTIONS: (help commands | where category == "" | get name | each { split row " " | first } | uniq | str join "\n") - } - - # if the current command is an alias, get it's expansion - let expanded_alias = (scope aliases | where name == $spans.0 | $in.0?.expansion?) - - # overwrite - let spans = (if $expanded_alias != null { - # put the first word of the expanded alias first in the span - $spans | skip 1 | prepend ($expanded_alias | split row " " | take 1) - } else { - $spans | skip 1 | prepend ($spans.0) - }) - - carapace $spans.0 nushell ...$spans - | from json -} - -mut current = (($env | default {} config).config | default {} completions) -$current.completions = ($current.completions | default {} external) -$current.completions.external = ($current.completions.external -| default true enable -# backwards compatible workaround for default, see nushell #15654 -| upsert completer { if $in == null { $carapace_completer } else { $in } }) - -$env.config = $current -