chs: re-add drifted files

This commit is contained in:
Prad Nukala committed 2026-08-15 19:00:25 -04:00
1 parent 3ba7b5fb55
commit 31ff6c0fa6
30 files changed
+742 -27

No files matched your search

+4 -4
View File
@@ -131,9 +131,9 @@
"sourceType": "github",
"sourceUrl": "https://github.com/vercel-labs/json-render.git",
"skillPath": "skills/react/SKILL.md",
"skillFolderHash": "de4cf00b0cdcdfab52fe03fb7a832d6f18a9575a",
"skillFolderHash": "9c588f4ee3abe16fc959c4ddea65f43c786edc2c",
"installedAt": "2026-03-13T21:55:40.915Z",
"updatedAt": "2026-08-14T01:06:47.841Z"
"updatedAt": "2026-08-15T20:19:34.630Z"
},
"react-pdf": {
"source": "vercel-labs/json-render",
@@ -347,9 +347,9 @@
"sourceType": "github",
"sourceUrl": "https://github.com/remix-run/remix.git",
"skillPath": ".agents/skills/remix/SKILL.md",
"skillFolderHash": "b83968c33a93974421b86f9b70dae71b68414b25",
"skillFolderHash": "f4a5b113c626d7b17834af0bad6bfdb6b41cbf0f",
"installedAt": "2026-05-23T19:11:24.642Z",
"updatedAt": "2026-08-14T01:06:55.674Z"
"updatedAt": "2026-08-15T20:19:36.456Z"
},
"typescript-expert": {
"source": "remix-run/remix",
+1
View File
@@ -119,6 +119,7 @@ Any prop value can be a data-driven expression resolved by the renderer before c
- **`{ "$bindState": "/path" }`** - two-way binding: reads from state and enables write-back. Use on the natural value prop (value, checked, pressed, etc.) of form components.
- **`{ "$bindItem": "field" }`** - two-way binding to a repeat item field. Use inside repeat scopes.
- **Filtered lists**: `repeat` plus an `$item` visible condition on the same container renders only matching items: `{ "repeat": { "statePath": "/tasks", "key": "id" }, "visible": { "$item": "status", "eq": "todo" }, "children": ["task-card"] }`. AND-composed `$state` conjuncts gate the container shell; `$item`/`$index` conjuncts filter items.
- **Nested lists**: inside a repeat, use `{ "repeat": { "statePath": { "$item": "comments" }, "key": "id" } }` to iterate an array on the enclosing item.
- **`{ "$cond": <condition>, "$then": <value>, "$else": <value> }`** - conditional value
- **`{ "$template": "Hello, ${/name}!" }`** - interpolates state values into strings
- **`{ "$computed": "fn", "args": { ... } }`** - calls registered functions with resolved args
@@ -84,7 +84,7 @@ let entryPreloads = await assetServer.getPreloads('app/actions/public/entry.ts')
Use this when rendering documents or layouts that boot browser behavior with a known client entry.
When resolving hydrated client entries during server rendering, pass the source entry ID from `clientEntry(import.meta.url, ...)` to `getHref()` inside `resolveClientEntry`. Keep export-name resolution in that render helper, and avoid hard-coding public asset URLs in source-owned component modules.
When resolving hydrated client entries during server rendering, pass the source entry ID from `clientEntry(import.meta.url, ...)` to `getHref()` and `getPreloads()` inside `resolveClientEntry`. Return those preload hrefs through the entry's `preloads` property so the browser can fetch the module graph without walking it serially. Keep this resolution in the shared render helper rather than hard-coding public asset URLs in source-owned component modules.
## Development vs Deployment
@@ -76,9 +76,15 @@ let stream = renderToStream(<App />, {
throw new Error(`Unable to resolve client entry export for ${entryId}`)
}
let [href, preloads] = await Promise.all([
assetServer.getHref(entryId),
assetServer.getPreloads(entryId),
])
return {
href: await assetServer.getHref(entryId),
href,
exportName,
preloads,
}
},
})
@@ -90,6 +96,8 @@ On the server, `clientEntry` components render like any other component. The ser
Client entry props must be serializable: strings, numbers, booleans, `null`, `undefined`, plain objects/arrays of the above, JSX elements, and `<Frame>` elements. Functions and class instances cannot be passed.
The resolved `preloads` array contains browser module hrefs. During server rendering these are emitted as `<link rel="modulepreload">` tags, including preloads discovered in blocking frames. When a later frame response introduces a client entry, its preloads start before the entry module is loaded.
## Booting the Client
Use `run` to start the client runtime. It scans the document for client entry markers, loads modules, and hydrates each one:
@@ -1,13 +1,42 @@
# Aliases — generated from .chezmoidata/aliases.yaml (shared with bash/zsh
# via ~/.config/shell/aliases.sh). Add shell-agnostic aliases in the YAML;
# fish-only bits live below the generated block.
{{- range .aliases }}
# {{ .section }}
{{- range .items }}
alias {{ .name }} {{ if contains " " .cmd }}'{{ .cmd }}'{{ else }}{{ .cmd }}{{ end }}
{{- end }}
{{- end }}
# Editors / file managers
alias e nvim
alias e.d 'cd ~/.config/dotstate/storage/Rogz/.config && yazi'
alias e.f 'cd ~/.config/fish && yazi'
alias e.k 'yazi ~/.config/kitty'
alias e.n 'yazi ~/.config/niri'
alias e.v 'yazi ~/.config/nvim/lua'
alias e.y 'yazi ~/.config/yazi'
alias e.t 'nvim ~/.config/tmux/tmux.conf'
alias hx helix
# Quick directory jumps
alias cdc 'cd ~/.config && yazi'
alias cdd 'cd ~/Developer && yazi'
alias cdk 'cd ~/Documents/Knowledge && obsidian'
alias cdl 'cd ~/.local && yazi'
alias cds 'cd ~/.local/share/services && ls'
alias cdw 'cd ~/Downloads && yazi'
# Tools
alias dd lazydocker
alias gg lazygit
alias ff 'exec fish'
alias npx bunx
alias sm 'sudo micro'
alias sd 'ssh prad@192.168.1.68'
alias oc opencode
alias gop 'gh repo view --web'
alias dss 'dotstate sync'
alias fabric fabric-ai
alias bk bead-kanban
alias sua 'shelly upgrade-all -n'
alias lc leetcode
alias tk task
alias .. 'cd ..'
# Clipboard
if command -v wl-copy >/dev/null 2>&1
+2
View File
@@ -0,0 +1,2 @@
source "$HOME/.atuin/bin/env.fish"
@@ -0,0 +1,4 @@
# >>> oh-my-opencode-slim background subagents >>>
set -gx OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS true
set -gx OPENCODE_ENABLE_EXA 1
# <<< oh-my-opencode-slim background subagents <<<
@@ -0,0 +1,27 @@
# Config is split into autoloaded files (see `man fish` → Configuration files):
# conf.d/00-path.fish PATH entries
# conf.d/10-env.fish environment + fish_greeting + fzf theme
# conf.d/20-aliases.fish aliases
# conf.d/40-tools.fish starship / zoxide / mise / hishtory init
# conf.d/50-terminal-title.fish tmux window title
# conf.d/secrets.fish API keys (gitignored)
# functions/ one autoloaded function per file
# functions/fish_user_key_bindings.fish key bindings
#
# Nothing needs to live here; keep it empty so startup stays fast.
function starship_transient_prompt_func
starship module character
end
function starship_transient_rprompt_func
starship module time
end
starship init fish | source
enable_transience
# Pin the prompt to the bottom of the terminal (FISH_BOTTOM_PROMPT=1, the
# default from conf.d/10-env.fish; set 0 for the normal top prompt).
# functions/clear.fish and the ctrl-l binding re-pin it after clearing.
status is-interactive; and test "$FISH_BOTTOM_PROMPT" = 1; and tput cup $LINES 0
+13
View File
@@ -0,0 +1,13 @@
function ai --description 'Choose and launch an AI CLI via gum'
set -l choice (gum choose --header 'AI CLI' claude opencode codex hermes fractal)
test -n "$choice"; or return # cancelled (Esc / Ctrl-C) → bail out
switch $choice
case claude
claude --dangerously-skip-permissions
case '*'
# labels match the binary names, so just run it
# add a dedicated `case` here if another tool needs flags
$choice
end
end
+3
View File
@@ -0,0 +1,3 @@
function c2p --description "Code2Prompt with fuzzy-search template"
fd --type f --extension hbs . $HOME/.config/code2prompt | fzf | xargs code2prompt --template
end
+43
View File
@@ -0,0 +1,43 @@
function cp-appid --description "Fuzzy-pick a desktop app ID and copy to clipboard"
set -l search_dirs \
/usr/share/applications \
/usr/local/share/applications \
$HOME/.local/share/applications \
/var/lib/flatpak/exports/share/applications \
$HOME/.local/share/flatpak/exports/share/applications \
/var/lib/snapd/desktop/applications
set -l existing_dirs
for d in $search_dirs
test -d $d; and set -a existing_dirs $d
end
test (count $existing_dirs) -eq 0
and echo "No application directories found." >&2
and return 1
set -l chosen (
fd --type f --extension desktop . $existing_dirs \
| while read -l f
set -l app_id (basename $f .desktop)
set -l name (rg -m1 '^Name=' $f | string replace 'Name=' '')
test -z "$name"; and set name $app_id
echo "$name\t$app_id"
end \
| sort -u -t\t -k1 \
| fzf \
--delimiter='\t' \
--with-nth=1,2 \
--prompt="App ID › " \
--height=50% \
--layout=reverse \
--border=rounded \
--info=inline
)
test -z "$chosen"; and return 0
set -l app_id (string split '\t' $chosen)[2]
echo -n $app_id | wl-copy
echo "Copied: $app_id"
end
+37
View File
@@ -0,0 +1,37 @@
function czs --description 'chezmoi: re-add drifted files, then commit + push the source repo'
# Optional targets scope both the status view and the re-add,
# e.g. `chs ~/.config/fish`. No args = all managed files.
set -l drift (chezmoi status $argv)
or return
if test -n "$drift"
printf '%s\n' $drift
# re-add takes the local (destination) contents as truth for modified
# files; templates are never overwritten, non-file entries are ignored.
chezmoi re-add $argv
or return
else
echo "chs: in sync — nothing to re-add"
end
# Commit + sync the source repo (~/.local/share/chezmoi).
set -l src (chezmoi source-path)
if test -n "$(git -C $src status --porcelain)"
git -C $src add -A
and git -C $src commit --quiet -m 'chs: re-add drifted files'
or return
echo "chs: committed "(git -C $src rev-parse --short HEAD)
end
# Push anything unpushed — covers this commit AND leftovers from a
# previously failed push. --autostash tolerates post-commit hooks
# (beads export) re-dirtying the tree mid-sync.
set -l ahead (git -C $src rev-list --count @{upstream}..HEAD 2>/dev/null; or echo 0)
if test $ahead -gt 0
git -C $src pull --rebase --autostash --quiet
and git -C $src push --quiet
and echo "chs: pushed $ahead commit(s) to "(git -C $src remote get-url origin)
else
echo "chs: remote up to date"
end
end
@@ -0,0 +1,18 @@
function extract_agents -d "Copy all AGENTS.md files to a target directory while preserving structure"
set -l out_dir $argv[1]
# Validate input
if test -z "$out_dir"
echo "Error: Output directory required."
echo "Usage: extract_agents <absolute_or_relative_output_path>"
return 1
end
# Ensure output directory exists
mkdir -p $out_dir
# Find and copy preserving relative paths
fd -t f -g "AGENTS.md" -x cp --parents "{}" $out_dir
echo "Extraction complete. Check $out_dir."
end
+40
View File
@@ -0,0 +1,40 @@
function fab -d "Fuzzy find and execute a Fabric pattern"
set -l json_file ~/.config/fabric/pattern_explainations.json
if not test -f $json_file
set_color red; echo "Error: $json_file not found."; set_color normal
return 1
end
# 1. Safely capture piped input (if any) to a temp file
# This preserves all formatting, newlines, and avoids variable escaping issues
set -l temp_input (mktemp)
if not isatty stdin
cat > $temp_input
end
# 2. Parse JSON to TSV -> fzf (Name in list, Description in preview) -> Extract Name
set -l selection (jq -r '.[] | "\(.name)\t\(.description)"' $json_file | \
fzf --delimiter '\t' \
--with-nth 1 \
--preview 'echo {2}' \
--preview-window 'right:60%:wrap' \
--prompt 'Pattern > ' \
--info inline \
--bind 'ctrl-/:toggle-preview')
# 3. Execute with or without the piped data
if test -n "$selection"
set -l pattern (string split -f 1 \t "$selection")
# If our temp file has data (-s), pipe it. Otherwise, run bare.
if test -s $temp_input
cat $temp_input | fabric --pattern "$pattern"
else
fabric --pattern "$pattern"
end
end
# 4. Clean up
rm -f $temp_input
end
+9
View File
@@ -0,0 +1,9 @@
function gdc --description "Discard all git changes with gum confirmation"
if gum confirm "Discard all uncommitted changes? This is irreversible."
git reset --hard HEAD
git clean -fd
echo "Changes wiped."
else
echo "Operation aborted."
end
end
@@ -0,0 +1,151 @@
#!/usr/bin/env fish
# sonr-consolidate.fish
# Migrates all repos from orgs matching "sonr" into sonr-io,
# prompting via gum for renames on collision, then deletes emptied orgs.
#
# Requires: gh (authenticated as org owner on all orgs), gum, jq
set -g TARGET_ORG sonr-io
# ── Preflight ────────────────────────────────────────────────────────────────
for bin in gh gum jq
if not command -q $bin
echo (set_color red)"missing dependency: $bin"(set_color normal)
exit 1
end
end
if not gh auth status &>/dev/null
echo (set_color red)"gh is not authenticated"(set_color normal)
exit 1
end
# ── Discover source orgs ─────────────────────────────────────────────────────
# All orgs the user belongs to whose login contains "sonr", excluding target.
set -l source_orgs (gh api user/orgs --paginate --jq '.[].login' \
| string match -r '.*sonr.*' \
| string match -v $TARGET_ORG)
if test (count $source_orgs) -eq 0
echo "No source orgs found. Nothing to do."
exit 0
end
echo (set_color cyan)"Source orgs:"(set_color normal)
printf ' %s\n' $source_orgs
echo (set_color cyan)"Target org:"(set_color normal)" $TARGET_ORG"
echo
# Let the user confirm / trim the list interactively
set -l selected_orgs (printf '%s\n' $source_orgs | gum choose --no-limit \
--header "Select orgs to migrate into $TARGET_ORG (space to toggle, enter to confirm)")
if test (count $selected_orgs) -eq 0
echo "Nothing selected. Exiting."
exit 0
end
# ── Helpers ──────────────────────────────────────────────────────────────────
function repo_exists_in_target
gh api "repos/$TARGET_ORG/$argv[1]" --silent &>/dev/null
end
function transfer_repo
# $1 = source org, $2 = repo name, $3 = (optional) new name
set -l src $argv[1]
set -l repo $argv[2]
set -l args -f new_owner=$TARGET_ORG
if set -q argv[3]; and test -n "$argv[3]"
set -a args -f new_name=$argv[3]
end
gh api -X POST "repos/$src/$repo/transfer" $args --silent
end
# ── Migration ────────────────────────────────────────────────────────────────
set -g failed_transfers
for org in $selected_orgs
echo
echo (set_color --bold cyan)"── $org ──"(set_color normal)
set -l repos (gh api "orgs/$org/repos" --paginate --jq '.[].name')
if test (count $repos) -eq 0
echo " (no repos)"
continue
end
for repo in $repos
set -l new_name ""
if repo_exists_in_target $repo
echo (set_color yellow)" ⚠ $repo already exists in $TARGET_ORG"(set_color normal)
while true
set new_name (gum input \
--header "New name for $org/$repo (exists in $TARGET_ORG)" \
--placeholder "$org-$repo" \
--value "$org-$repo")
if test -z "$new_name"
echo " skipped $org/$repo"
set new_name __SKIP__
break
end
if repo_exists_in_target $new_name
echo (set_color yellow)" $new_name also exists — pick another"(set_color normal)
else
break
end
end
test "$new_name" = __SKIP__; and continue
end
set -l label "$org/$repo → $TARGET_ORG/"(test -n "$new_name"; and echo $new_name; or echo $repo)
if transfer_repo $org $repo $new_name
echo (set_color green)" ✓ $label"(set_color normal)
else
echo (set_color red)" ✗ failed: $label"(set_color normal)
set -a failed_transfers "$org/$repo"
end
end
end
if test (count $failed_transfers) -gt 0
echo
echo (set_color red)"Failed transfers (orgs containing these will NOT be deleted):"(set_color normal)
printf ' %s\n' $failed_transfers
end
# ── Wait for transfers to settle ─────────────────────────────────────────────
# GitHub repo transfers are asynchronous; give them time to drain.
echo
gum spin --title "Waiting 30s for transfers to settle..." -- sleep 30
# ── Delete emptied orgs ──────────────────────────────────────────────────────
echo
for org in $selected_orgs
# Skip orgs with failed transfers
if string match -q "$org/*" -- $failed_transfers
echo (set_color yellow)"skipping delete: $org (had failures)"(set_color normal)
continue
end
set -l remaining (gh api "orgs/$org/repos" --paginate --jq '. | length' | jq -s 'add // 0')
if test "$remaining" -gt 0
echo (set_color yellow)"skipping delete: $org still has $remaining repo(s) (transfer pending?)"(set_color normal)
continue
end
if gum confirm "Delete empty org $org?"
if gh api -X DELETE "orgs/$org" --silent
echo (set_color green)"✓ deleted $org"(set_color normal)
else
echo (set_color red)"✗ could not delete $org (API delete requires org owner; may need manual deletion in Settings)"(set_color normal)
end
else
echo "kept $org"
end
end
echo
echo (set_color --bold green)"Done."(set_color normal)
@@ -0,0 +1,22 @@
function git-summary --description "Aggregate all AGENTS.md files in the current git repo via code2prompt"
# Resolve the repo root so it works from any subdirectory
set -l repo_root (git rev-parse --show-toplevel 2>/dev/null)
if test -z "$repo_root"
echo "git-summary: not inside a git repository" >&2
return 1
end
set -l template ~/.config/code2prompt/agents-md.hbs
if not test -f $template
echo "git-summary: template not found at $template" >&2
return 1
end
# Pass through any extra flags (e.g. --output-file, --tokens)
code2prompt $repo_root \
--include "AGENTS.md" \
--include "**/AGENTS.md" \
--template $template \
$argv
end
+160
View File
@@ -0,0 +1,160 @@
# ~/.config/fish/functions/gtm.fish
# Migrate GitHub repos → prad.codes (Gitea) via tea.
# Usage: gtm [<owner>/<repo> | <github-url>] — no arg: multi-select via fzf
function gtm --description "Migrate GitHub repo(s) to a prad.codes org via tea"
# -- Preflight ------------------------------------------------------------
for bin in gh tea gum jq
if not command -q $bin
echo "gtm: missing dependency: $bin" >&2
return 1
end
end
set -l gh_token (gh auth token 2>/dev/null)
if test -z "$gh_token"
echo "gtm: gh not authenticated (run: gh auth login)" >&2
return 1
end
# -- Resolve source repos -------------------------------------------------
# Each entry: nameWithOwner \t isPrivate
set -l repos
if test (count $argv) -ge 1
# Direct mode: accepts owner/repo, https://…, ssh://…, git@host:…
# Same normalization as ghg-clone: strip scheme, user@, scp colon, .git
set -l rel (
printf '%s\n' $argv[1] \
| sed -E 's#^[[:alnum:]]+://##; s#^[^@/]+@##; s#:#/#; s#\.git$##; s#/+$##'
)
# Reduce to owner/repo: take the last two path segments
set -l parts (string split / -- $rel | string match -rv '^$')
if test (count $parts) -lt 2
echo "usage: gtm [<owner>/<repo> | <github-url>]" >&2
return 1
end
# If a host segment is present, it must be github.com — that's the
# only source this migrator pulls from (clone-url is hardcoded to it)
if test (count $parts) -gt 2; and test "$parts[-3]" != github.com
echo "gtm: source must be a github.com repo, got host: $parts[-3]" >&2
return 1
end
set -l nwo "$parts[-2]/$parts[-1]"
if not string match -qr '^[\w.-]+/[\w.-]+$' -- $nwo
echo "gtm: could not parse owner/repo from: $argv[1]" >&2
return 1
end
set -l meta (
gh repo view $nwo \
--json nameWithOwner,isPrivate \
--jq '[.nameWithOwner, (.isPrivate|tostring)] | @tsv' 2>/dev/null
)
if test -z "$meta"
echo "gtm: repo not found or inaccessible: $nwo" >&2
return 1
end
set repos $meta
else
# Interactive mode: fzf multi-select
if not command -q fzf
echo "gtm: missing dependency: fzf" >&2
return 1
end
set repos (
gh repo list --limit 200 \
--json nameWithOwner,isPrivate,description \
--jq '.[] | [.nameWithOwner, (.isPrivate|tostring), .description // ""] | @tsv' \
| fzf --multi \
--delimiter '\t' \
--with-nth 1,3 \
--prompt 'migrate> ' \
--header 'TAB: multi-select · ENTER: confirm' \
--preview 'gh repo view {1}' \
--preview-window 'right:50%:wrap'
)
if test (count $repos) -eq 0
echo "gtm: nothing selected" >&2
return 1
end
end
# -- Select target org on prad.codes --------------------------------------
set -l owner (
tea organizations list -o simple \
| string trim \
| string match -rv '^$' \
| gum choose --header "Target org on prad.codes"
)
if test -z "$owner"
echo "gtm: no target org selected" >&2
return 1
end
# -- Options --------------------------------------------------------------
set -l extras (
gum choose --no-limit \
--header "Migration options (space to toggle)" \
"wiki" "issues" "labels" "pull-requests" "releases" "milestones" "lfs" "mirror"
)
set -l extra_flags
for opt in $extras
set -a extra_flags "--$opt"
end
# -- Migrate --------------------------------------------------------------
set -l failed
set -l migrated # repo names successfully landed on prad.codes/$owner
for line in $repos
set -l fields (string split \t -- $line)
set -l nwo $fields[1]
set -l is_private $fields[2]
set -l name (string split -m1 / -- $nwo)[2]
set -l flags --name $name --owner $owner \
--clone-url "https://github.com/$nwo.git" \
--service git \
--auth-token $gh_token \
$extra_flags
if test "$is_private" = true
set -a flags --private
end
echo "→ migrating $nwo → prad.codes/$owner/$name"
if tea repos migrate $flags
set -a migrated $name
else
set -a failed $nwo
echo "✗ failed: $nwo" >&2
end
end
# -- Optional local clone -------------------------------------------------
if test (count $migrated) -gt 0
and gum confirm "Clone "(count $migrated)" migrated repo(s) locally via ghg-clone?"
set -l last_dir
for name in $migrated
set -l dir (ghg-clone "https://prad.codes/$owner/$name")
if test -n "$dir"
set last_dir $dir
else
echo "✗ clone failed: $owner/$name" >&2
end
end
# Single repo → drop into it (function runs in-shell, so cd sticks)
if test (count $migrated) -eq 1 -a -n "$last_dir"
cd $last_dir
end
end
# -- Summary --------------------------------------------------------------
if test (count $failed) -gt 0
echo
echo "gtm: "(count $failed)" migration(s) failed:" >&2
printf ' %s\n' $failed >&2
return 1
end
echo
echo "✓ done — "(count $repos)" repo(s) migrated to $owner"
end
@@ -0,0 +1,16 @@
function launch_omp_livediff_overlay --description "Overlay omp on the current kitty window with a livediff split beside it"
# kitty appends -PID to config-file listen_on sockets, so a hardcoded
# --to unix:@kitty-local never matches. kitty @ resolves the real
# address from $KITTY_LISTEN_ON on its own.
if not set -q KITTY_LISTEN_ON
echo "launch_omp_livediff_overlay: no kitty remote-control socket (KITTY_LISTEN_ON unset)" >&2
return 1
end
# omp overlays the current window; capture its window id
set -l wid (kitty @ launch --type=overlay-main --cwd=current omp)
or return
# livediff side by side in the same tab; keep focus on omp
kitty @ launch --match id:$wid --location=vsplit --keep-focus --cwd=current livediff
end
+16
View File
@@ -0,0 +1,16 @@
function lc-elir -d "fzf-pick LeetCode solution files and run /leetcode-eli5 on each via omp"
set -l root (count $argv > /dev/null; and echo $argv[1]; or echo .)
# Match only numbered problem files: 1365.some-slug.js anywhere in the tree
set -l files (fd --type f '^\d+\..+\.(js|ts)$' $root \
| fzf --multi \
--prompt='eli5> ' \
--delimiter=/ \
--with-nth=-3.. \
--preview 'bat --color=always --line-range=:40 {}' \
--preview-window=right:60%)
test -z "$files"; and return 1
for f in $files
echo "── /leetcode-eli5 $f"
omp -p "/leetcode-eli5 $f"
end
end
+8
View File
@@ -0,0 +1,8 @@
function mdcp -a url
if test -z "$url"
echo "usage: mdcp <url>" >&2
return 1
end
curl.md $url | cpy
pst | mdfried
end
+10
View File
@@ -0,0 +1,10 @@
# ~/.config/fish/functions/mdv.fish
function mdp -d "Interactive Markdown selector and previewer"
# Find markdown files up to 3 directories deep
set -l file (fd --type f --extension md --max-depth 3 | fzf --preview 'mdfried {}' --preview-window=right:60%:wrap)
# Execute mdfried on the selected file if one was chosen
if test -n "$file"
mdfried "$file"
end
end
+86
View File
@@ -0,0 +1,86 @@
function pj --description "fzf package.json script runner with auto-detected package manager"
# ── Locate nearest package.json (walk up) ──────────────────────────
set -l dir (pwd)
set -l pkg ""
while true
if test -f "$dir/package.json"
set pkg "$dir/package.json"
break
end
test "$dir" = / && break
set dir (path dirname $dir)
end
if test -z "$pkg"
echo "pj: no package.json found in this tree" >&2
return 1
end
set -l root (path dirname $pkg)
# ── Detect package manager ─────────────────────────────────────────
# Priority: packageManager field (corepack) → lockfiles (walking up
# past $root to catch monorepo-root locks) → npm fallback
set -l pm (jq -r '.packageManager // empty' $pkg | string split '@')[1]
if test -z "$pm"
set -l d $root
while test -z "$pm"
if test -f "$d/bun.lockb" -o -f "$d/bun.lock"
set pm bun
else if test -f "$d/pnpm-lock.yaml"
set pm pnpm
else if test -f "$d/yarn.lock"
set pm yarn
else if test -f "$d/package-lock.json"
set pm npm
end
test "$d" = / && break
set d (path dirname $d)
end
test -z "$pm" && set pm npm
end
# ── Pick a script ──────────────────────────────────────────────────
set -l script (jq -r '.scripts // {} | keys[]' $pkg | fzf \
--prompt="$pm run ❯ " \
--header="$root" \
--height=40% --layout=reverse --border \
--preview="jq -r --arg s {} '.scripts[\$s]' $pkg" \
--preview-window=up:2:wrap)
test -z "$script" && return 0
# ── Run (npm needs `--` to forward extra args) ────────────────────
set -l extra $argv
if test "$pm" = npm -a (count $extra) -gt 0
set extra -- $extra
end
# Wrap long-running server scripts in openlogs (live log tail for agents).
# Matches dev/start/serve and namespaced variants like dev:web, start:api.
set -l wrapper
if string match -qr '^(dev|start|serve|watch)(:.*)?$' -- $script
# Resolve the binary: PATH → mise resolution → mise installs glob
set -l ol (command -s openlogs)
if test -z "$ol"; and command -sq mise
set ol (mise which openlogs 2>/dev/null)
end
if test -z "$ol"
set ol ~/.local/share/mise/installs/node/*/bin/openlogs
set ol $ol[1]
end
if test -n "$ol" -a -x "$ol"
set wrapper $ol
else
echo "pj: openlogs not found, running unwrapped" >&2
end
end
if test -n "$wrapper"
echo "→ $wrapper $pm run $script $argv" >&2
$wrapper $pm run $script $extra
else
echo "→ $pm run $script $argv" >&2
$pm run $script $extra
end
end
+8
View File
@@ -0,0 +1,8 @@
function y
set tmp (mktemp -t "yazi-cwd.XXXXXX")
command yazi $argv --cwd-file="$tmp"
if read -z cwd < "$tmp"; and [ "$cwd" != "$PWD" ]; and test -d "$cwd"
builtin cd -- "$cwd"
end
command rm -f -- "$tmp"
end
+2 -1
View File
@@ -5,7 +5,7 @@
# prefix byte is the shift variant (\x02N == prefix+shift+n).
# ── base / appearance ──
font_size 12.5
font_size 11.5
font_family VictorMono Nerd Font
bold_italic_font auto
window_padding_width 8
@@ -19,6 +19,7 @@ cursor_trail 10
cursor_trail_start_threshold 0
cursor_trail_decay 0.01 0.05
cursor_blink_interval 0
class kitty-herdr
# herdr renders its own sidebar/tab strip — no kitty chrome
tab_bar_style hidden
+3 -3
View File
@@ -1,5 +1,5 @@
# ── base.conf · shared ──
font_size 12.5
font_size 13.5
font_family VictorMono Nerd Font
bold_italic_font auto
window_padding_width 8
@@ -49,9 +49,9 @@ map ctrl+shift+f toggle_layout stack
map super+z toggle_layout stack
map ctrl+shift+e launch_tb nvim
# herdr host: a *separate* kitty process, own config (launch cannot take --config)
map ctrl+shift+a launch --type=background --cwd=current kitty --config ~/.config/kitty/herdr.conf
map ctrl+shift+a launch --type=background --cwd=current kitty --class=kitty-herdr --config ~/.config/kitty/herdr.conf
# tmux host: same trick — kitty stays dumb, tmux owns panes/windows/sessions
map ctrl+shift+t launch --type=background --cwd=current kitty --config ~/.config/kitty/tmux.conf
map ctrl+shift+t launch --type=background --cwd=current kitty --class=kitty-tmux --config ~/.config/kitty/tmux.conf
map ctrl+shift+p launch_hs atuin-pick
# Misc
+1 -1
View File
@@ -7,7 +7,7 @@
# Launched from the default config with ctrl+shift+t.
# ── base / appearance (kitty.conf parity) ──
font_size 12.5
font_size 11.5
font_family VictorMono Nerd Font
bold_italic_font auto
window_padding_width 8
@@ -91,6 +91,14 @@ window-rule {
// open-on-output "HDMI-A-1"
}
window-rule {
match app-id="kitty"
match app-id="zed"
match app-id="obsidian"
open-on-output "Apple Computer Inc StudioDisplay 0x984262A7"
}
window-rule {
match app-id="sticky-notest-canvas"
match title="Sticky Notes"
@@ -103,14 +111,9 @@ window-rule {
match app-id="com.anthropic.Claude"
match app-id="Hermes"
match app-id="chromium"
match app-id="kitty-herdr"
match app-id="kitty-tmux"
open-on-output "eDP-1"
}
window-rule {
match app-id="kitty"
match app-id="zed"
match app-id="obsidian"
open-on-output "Apple Computer Inc StudioDisplay 0x984262A7"
}
+2 -2
View File
@@ -25,8 +25,8 @@ hash = "7de446280b1ba8c49ffd86dbc24bbbe6"
[[plugin.deps]]
use = "mikavilpas/easyjump.yazi:easyjump"
rev = "a2a7373"
hash = "6f8b9e41dde4ae29d958d4cdc829c121"
rev = "da7e2d1"
hash = "49625b69287597c3b8093c9f1a2f7241"
[[plugin.deps]]
use = "cap153/tv"
+1 -1
View File
@@ -4,4 +4,4 @@ symbolPreset: nerd
setupVersion: 1
hideThinkingBlock: true
modelRoles:
default: opencode-zen/claude-opus-5
default: anthropic/claude-fable-5:high