diff --git a/.claude/settings.json##os.Linux b/.claude/settings.json##os.Linux index 9c9d9b1..2b8d257 100644 --- a/.claude/settings.json##os.Linux +++ b/.claude/settings.json##os.Linux @@ -4,9 +4,22 @@ "pr": "" }, "permissions": { + "allow": [ + "Bash(npm run lint)", + "Bash(npm run test *)", + "Read(~/.zshrc)", + "Bash(git * main)", + "Bash(ls *)", + "Bash(pnpm build *)" + ], "deny": [ - "Read(.env)", - "Read(~/.aws/**)" + "Bash(curl *)", + "Read(./.env)", + "Read(./.env.*)", + "Read(./secrets/**)", + "Read(~/.aws/**)", + "Bash(git push *)", + "Bash(yadm push *)" ] }, "hooks": { @@ -25,19 +38,20 @@ "enabledPlugins": { "pyright-lsp@claude-plugins-official": true, "typescript-lsp@claude-plugins-official": true, - "clangd-lsp@claude-plugins-official": true + "clangd-lsp@claude-plugins-official": true, + "claude-mem@thedotmack": true, + "frontend-design@claude-plugins-official": true, + "code-review@claude-plugins-official": true, + "code-simplifier@claude-plugins-official": true, + "playwright@claude-plugins-official": true }, "sandbox": { "enabled": false, "autoAllowBashIfSandboxed": true, "network": { - "allowUnixSockets": [ - "/var/run/docker.sock" - ], + "allowUnixSockets": ["/var/run/docker.sock"], "allowLocalBinding": true }, - "excludedCommands": [ - "docker" - ] + "excludedCommands": ["docker"] } } diff --git a/.config/btop/btop.conf b/.config/btop/btop.conf index 67dba71..66b81e6 100644 --- a/.config/btop/btop.conf +++ b/.config/btop/btop.conf @@ -2,7 +2,7 @@ #* Name of a btop++/bpytop/bashtop formatted ".theme" file, "Default" and "TTY" for builtin themes. #* Themes should be placed in "../share/btop/themes" relative to binary or "$HOME/.config/btop/themes" -color_theme = "TTY" +color_theme = "/home/sudacode/.config/btop/themes/catppuccin_macchiato.theme" #* If the theme set background should be shown, set to False if you want terminal background transparency. theme_background = true diff --git a/.config/hypr/hyprland.conf b/.config/hypr/hyprland.conf index f00a8b5..9c472b0 100644 --- a/.config/hypr/hyprland.conf +++ b/.config/hypr/hyprland.conf @@ -271,3 +271,10 @@ debug { disable_logs = true enable_stdout_logs = false } + + +layerrule { + name = fix-rofi + match:namespace = rofi + no_anim = true +} diff --git a/.config/hypr/keybindings.conf b/.config/hypr/keybindings.conf index f907b8a..36d0f2b 100644 --- a/.config/hypr/keybindings.conf +++ b/.config/hypr/keybindings.conf @@ -152,4 +152,3 @@ bind = $mainMod, a, exec, ~/.config/rofi/scripts/rofi-anki-script.sh bindl = , mouse:275, exec, xdotool key alt+w # top mouse to texthooker bindl = , mouse:276, exec, xdotool key alt+grave # bottom mouse to overlay bind = ALT, g, exec, /opt/mpv-yomitan/mpv-yomitan.AppImage --toggle -# bind = ALT SHIFT, Y, exec, "$HOME/.config/rofi/scripts/rofi-mpv-yomitan.sh" diff --git a/.config/mpv/scripts/animecards b/.config/mpv/scripts/animecards deleted file mode 120000 index e63d8d1..0000000 --- a/.config/mpv/scripts/animecards +++ /dev/null @@ -1 +0,0 @@ -../submodules/animecards/animecards \ No newline at end of file diff --git a/.config/mpv/scripts/jimaku.js b/.config/mpv/scripts/jimaku.js deleted file mode 100644 index a5b6142..0000000 --- a/.config/mpv/scripts/jimaku.js +++ /dev/null @@ -1,388 +0,0 @@ -// Go to https://jimaku.cc/login and create a new account. -// Then go to https://jimaku.cc/account and click the `Generate` button to create a new API key -// Click the `Copy` button and paste it below -var API_KEY = ""; - -// Configuration options -var CONFIG = { - // Filter the response to only have the specified episode - prompt_episode: true, - - // Subtitle suffix (e.g., ".JA" for Japanese subtitles) - subtitle_suffix: ".JA", - - // Preferred subtitle format (order matters, first is most preferred) - preferred_formats: ["ass", "srt", "vtt"], - - // Automatically load the subtitle after download - auto_load: true, - - // Default subtitle delay in seconds (can be positive or negative) - default_delay: 0, - - // Default subtitle font size - default_font_size: 16, - - // Automatically rename the subtitle file after download - auto_rename: true, - - // Automatically run autosubsync-mpv after downloading the subtitle - run_auto_subsync: true -}; - -// Keybindings -// var MANUAL_SEARCH_KEY = "g"; -var FILENAME_AUTO_SEARCH_KEY = "ctrl+J"; -var PARENT_FOLDER_AUTO_SEARCH_KEY = "n"; - -function api(url, extraArgs) { - var baseArgs = [ - "curl", - "-s", - "--url", - url, - "--header", - "Authorization: " + API_KEY - ]; - - var args = Array.prototype.concat.apply(baseArgs, extraArgs); - - var res = mp.command_native({ - name: "subprocess", - playback_only: false, - capture_stdout: true, - capture_stderr: true, - args: args - }); - - if (res.stdout) return JSON.parse(res.stdout); -} - -function downloadSub(sub) { - return api(sub.url, ["--output", sub.name]); -} - -function showMessage(message, persist) { - var ass_start = mp.get_property_osd("osd-ass-cc/0"); - var ass_stop = mp.get_property_osd("osd-ass-cc/1"); - - mp.osd_message( - ass_start + "{\\fs16}" + message + ass_stop, - persist ? 999 : 2 - ); -} - -// The timeout is neccessary due to a weird bug in mpv -function inputGet(args) { - mp.input.terminate(); - setTimeout(function () { - mp.input.get(args); - }, 1); -} - -// The timeout is neccessary due to a weird bug in mpv -function inputSelect(args) { - mp.input.terminate(); - setTimeout(function () { - mp.input.select(args); - }, 1); -} - -// Taken from mpv-subversive -// https://github.com/nairyosangha/mpv-subversive/blob/master/backend/backend.lua#L146 -function sanitize(text) { - var subPatterns = [ - /\.[a-zA-Z]+$/, // extension - /\./g, - /-/g, - /_/g, - /\[[^\]]+\]/g, // [] bracket - /\([^\)]+\)/g, // () bracket - /720[pP]/g, - /480[pP]/g, - /1080[pP]/g, - /[xX]26[45]/g, - /[bB]lu[-]?[rR]ay/g, - /^[\s]*/, - /[\s]*$/, - /1920x1080/g, - /1920X1080/g, - /Hi10P/g, - /FLAC/g, - /AAC/g - ]; - - var result = text; - - subPatterns.forEach(function (subPattern) { - var newResult = result.replace(subPattern, " "); - if (newResult.length > 0) { - result = newResult; - } - }); - - return result; -} - -// Adapted from mpv-subversive -// https://github.com/nairyosangha/mpv-subversive/blob/master/backend/backend.lua#L164 -function extractTitle(text) { - var matchers = [ - { regex: /^([\w\s\d]+)[Ss]\d+[Ee]?\d+/, group: 1 }, - { regex: /^([\w\s\d]+)-[\s]*\d+[\s]*[^\w]*$/, group: 1 }, - { regex: /^([\w\s\d]+)[Ee]?[Pp]?[\s]+\d+$/, group: 1 }, - { regex: /^([\w\s\d]+)[\s]\d+.*$/, group: 1 }, - { regex: /^\d+[\s]*(.+)$/, group: 1 } - ]; - - for (var i = 0; i < matchers.length; i++) { - var matcher = matchers[i]; - var match = text.match(matcher.regex); - if (match) { - return match[matcher.group].trim(); - } - } - - return text; -} - -function getNames(results) { - return results.map(function (item) { - return item.name; - }); -} - -function runAutoSubSyncMPV() { - try { - mp.command_native(["script-binding", "autosubsync-menu"]); - } catch (e) { - showMessage("autosubsync-mpv not installed"); - return; - } -} - -function selectSub(selectedSub) { - showMessage("Downloading: " + selectedSub.name); - - try { - downloadSub(selectedSub); - - // Get current video filename without extension - var videoPath = mp.get_property("path"); - if (!videoPath) { - throw new Error("No video file is currently playing"); - } - var videoName = videoPath.substring(0, videoPath.lastIndexOf(".")); - - // Get subtitle extension - var subExt = selectedSub.name.substring(selectedSub.name.lastIndexOf(".")); - - var newSubName = selectedSub.name; - if (CONFIG.auto_rename) { - // Create new subtitle filename - newSubName = videoName + CONFIG.subtitle_suffix + subExt; - - // Rename the downloaded subtitle file - var renameResult = mp.command_native({ - name: "subprocess", - playback_only: false, - args: ["mv", selectedSub.name, newSubName] - }); - - if (renameResult.error) { - throw new Error( - "Failed to rename subtitle file: " + renameResult.error - ); - } - - showMessage(newSubName + " downloaded and renamed"); - } else { - showMessage(newSubName + " downloaded"); - } - - if (CONFIG.auto_load) { - mp.commandv("sub_add", newSubName); - showMessage(newSubName + " added"); - - // Apply subtitle settings if configured - if (CONFIG.default_delay !== 0) { - mp.commandv("sub_delay", CONFIG.default_delay); - } - if (CONFIG.default_font_size !== 16) { - mp.commandv("sub_font_size", CONFIG.default_font_size); - } - } - - if (CONFIG.run_auto_subsync) { - runAutoSubSyncMPV(); - } - - mp.set_property("pause", "no"); - } catch (error) { - showMessage("Error: " + error.message, true); - mp.set_property("pause", "no"); - } -} - -function sortByPreferredFormat(files) { - return files.sort(function (a, b) { - var extA = a.name.substring(a.name.lastIndexOf(".") + 1).toLowerCase(); - var extB = b.name.substring(b.name.lastIndexOf(".") + 1).toLowerCase(); - - var indexA = CONFIG.preferred_formats.indexOf(extA); - var indexB = CONFIG.preferred_formats.indexOf(extB); - - if (indexA === -1) return 1; - if (indexB === -1) return -1; - return indexA - indexB; - }); -} - -function selectEpisode(anime, episode) { - mp.input.terminate(); - var episodeResults; - - if (episode) { - showMessage("Fetching subs for: " + anime.name + " episode " + episode); - episodeResults = api( - "https://jimaku.cc/api/entries/" + anime.id + "/files?episode=" + episode - ); - } else { - showMessage("Fetching all subs for: " + anime.name); - episodeResults = api( - "https://jimaku.cc/api/entries/" + anime.id + "/files" - ); - } - - if (episodeResults.error) { - showMessage("Error: " + animeResults.error); - return; - } - - if (episodeResults.length === 0) { - showMessage("No results found"); - return; - } - - // Sort results by preferred format - episodeResults = sortByPreferredFormat(episodeResults); - - if (episodeResults.length === 1) { - var selectedEpisode = episodeResults[0]; - selectSub(selectedEpisode); - return; - } - - var items = getNames(episodeResults); - - inputSelect({ - prompt: "Select episode: ", - items: items, - submit: function (id) { - var selectedEpisode = episodeResults[id - 1]; - selectSub(selectedEpisode); - } - }); -} - -function onAnimeSelected(anime) { - if (CONFIG.prompt_episode) { - inputGet({ - prompt: "Episode (leave blank for all): ", - submit: function (episode) { - selectEpisode(anime, episode); - } - }); - } else { - selectEpisode(anime); - } -} - -function search(searchTerm, isAuto) { - mp.input.terminate(); - showMessage('Searching for: "' + searchTerm + '"'); - - var animeResults = api( - encodeURI( - "https://jimaku.cc/api/entries/search?anime=true&query=" + searchTerm - ) - ); - - if (animeResults.error) { - showMessage("Error: " + animeResults.error); - return; - } - - if (animeResults.length === 0) { - showMessage("No results found"); - if (isAuto) { - manualSearch(searchTerm); - } - return; - } - - if (animeResults.length === 1) { - var selectedAnime = animeResults[0]; - onAnimeSelected(selectedAnime); - return; - } - - var items = getNames(animeResults); - - inputSelect({ - prompt: "Select anime: ", - items: items, - submit: function (id) { - var selectedAnime = animeResults[id - 1]; - showMessage(selectedAnime.name, true); - onAnimeSelected(selectedAnime); - } - }); -} - -function manualSearch(defaultText) { - inputGet({ - prompt: "Search term: ", - submit: search, - default_text: defaultText - }); - - mp.set_property("pause", "yes"); - showMessage("Manual Jimaku Search", true); -} - -function autoSearch() { - var filename = mp.get_property("filename"); - var sanitizedFilename = sanitize(filename); - var currentAnime = extractTitle(sanitizedFilename); - - mp.set_property("pause", "yes"); - - search(currentAnime, true); -} - -function autoSearchParentFolder() { - var path = mp.get_property("stream-open-filename"); - var pathSplit = path.split(path.indexOf("/") >= 0 ? "/" : "\\"); - var filename = - pathSplit.length === 1 ? pathSplit[0] : pathSplit[pathSplit.length - 2]; - - var sanitizedFilename = sanitize(filename); - var currentAnime = extractTitle(sanitizedFilename); - - mp.set_property("pause", "yes"); - - search(currentAnime, true); -} - -// mp.add_key_binding(MANUAL_SEARCH_KEY, "jimaku-manual-search", manualSearch); -mp.add_key_binding( - FILENAME_AUTO_SEARCH_KEY, - "jimaku-filename-auto-search", - autoSearch -); -mp.add_key_binding( - PARENT_FOLDER_AUTO_SEARCH_KEY, - "jimaku-parent-folder-auto-search", - autoSearchParentFolder -); diff --git a/.config/mpv/scripts/subs2srs b/.config/mpv/scripts/subs2srs deleted file mode 120000 index ed3f75a..0000000 --- a/.config/mpv/scripts/subs2srs +++ /dev/null @@ -1 +0,0 @@ -../submodules/mpvacious \ No newline at end of file diff --git a/.config/rofi/launchers/type-6/style-1.rasi b/.config/rofi/launchers/type-6/style-1.rasi index bceff08..051fe3a 100644 --- a/.config/rofi/launchers/type-6/style-1.rasi +++ b/.config/rofi/launchers/type-6/style-1.rasi @@ -37,7 +37,8 @@ window { location: center; anchor: center; fullscreen: false; - width: 37%; + width: 46.65%; + height: 44%; x-offset: 0px; y-offset: 0px; @@ -58,9 +59,9 @@ mainbox { } imagebox { - padding: 20px; + padding: 24px; background-color: transparent; - background-image: url("~/.config/rofi/images/oshinoko.png", height); + background-image: url("~/.config/rofi/images/oshinoko.png", both); orientation: vertical; children: [ "inputbar", "dummy", "mode-switcher" ]; } diff --git a/.config/subminer/config.jsonc b/.config/subminer/config.jsonc deleted file mode 100644 index e3a9d35..0000000 --- a/.config/subminer/config.jsonc +++ /dev/null @@ -1,129 +0,0 @@ -{ - "subtitlePosition": { - "yPercent": 17.38459152016546 - }, - "keybindings": [ - { - "key": "Space", - "command": [ - "cycle", - "pause" - ] - }, - { - "key": "ArrowRight", - "command": [ - "seek", - 5 - ] - }, - { - "key": "ArrowLeft", - "command": [ - "seek", - -5 - ] - }, - { - "key": "ArrowRight", - "command": [ - "seek", - 5 - ] - }, - { - "key": "ArrowUp", - "command": [ - "seek", - 60 - ] - }, - { - "key": "ArrowDown", - "command": [ - "seek", - -60 - ] - }, - { - "key": "KeyQ", - "command": [ - "quit" - ] - }, - { - "key": "Ctrl+KeyW", - "command": [ - "quit" - ] - } - ], - "texthooker": { - "openBrowser": false - }, - "websocket": { - "enabled": "auto", - "port": 6677 - }, - "ankiConnect": { - "enabled": true, - "url": "http://127.0.0.1:8765", - "deck": "Minecraft", - "pollingRate": 200, - "audioField": "ExpressionAudio", - "imageField": "Picture", - "sentenceField": "Sentence", - "generateAudio": true, - "generateImage": true, - "imageType": "avif", - "imageFormat": "webp", - "miscInfoPattern": "[mpv-yomitan] %f (%t)", - "overwriteAudio": false, - "overwriteImage": true, - "highlightWord": true, - "showNotificationOnUpdate": true, - "notificationType": "system", - "audioPadding": 0.5, - "fallbackDuration": 3, - "animatedFps": 24, - "animatedMaxWidth": 640, - "animatedMaxHeight": null, - "animatedCrf": 35, - "autoUpdateNewCards": false, - "sentenceCardModel": "Lapis Morph", - "sentenceCardSentenceField": "Sentence", - "sentenceCardAudioField": "SentenceAudio", - "isLapis": true, - "mediaInsertMode": "append", - "auto_start_overlay": false, - "secondarySub": { - "autoLoadSecondarySub": true, - "secondarySubLanguages": [ - "en", - "eng" - ] - } - }, - "subtitleStyle": { - "ontFamily": "Noto Sans CJK JP Regular, Noto Sans CJK JP, Arial Unicode MS, Arial, sans-serif", - "fontSize": 35, - "fontColor": "#cad3f5", - "fontWeight": "normal", - "fontStyle": "normal", - "backgroundColor": "rgb(30, 32, 48, 0.88)", - "secondary": { - "fontSize": 24, - "fontColor": "#cad3f5", - "backgroundColor": "transparent" - } - }, - "shortcuts": { - "copySubtitle": "CommandOrControl+C", - "copySubtitleMultiple": "CommandOrControl+Shift+C", - "updateLastCardFromClipboard": "CommandOrControl+V", - "mineSentence": "CommandOrControl+S", - "mineSentenceMultiple": "CommandOrControl+Shift+S", - "toggleSecondarySub": "CommandOrControl+Shift+V", - "multiCopyTimeoutMs": 3000 - } -} \ No newline at end of file diff --git a/.zsh/.zshrc##default b/.zsh/.zshrc##default index 3410acb..b1d8663 100644 --- a/.zsh/.zshrc##default +++ b/.zsh/.zshrc##default @@ -73,3 +73,5 @@ zstyle ':url-quote-magic:*' url-quotes '' # bind it to both typing and pasting zle -N self-insert url-quote-magic zle -N bracketed-paste bracketed-paste-magic + +alias claude-mem='bun "/home/sudacode/.claude/plugins/marketplaces/thedotmack/plugin/scripts/worker-service.cjs"'