16 Commits

Author SHA1 Message Date
77bae03b14 chore: update rlru flake input 2026-06-19 21:50:32 -07:00
686023e006 nixos: update rlru input 2026-06-19 12:08:14 -07:00
f12285b7f7 Add x.com Chrome app scratchpad 2026-06-18 21:27:03 -07:00
0efb55f23f Enable hyprtasking workspace overview 2026-06-18 20:28:53 -07:00
30fb74b13b nixos: update rlru input 2026-06-18 16:19:52 -07:00
9bb090bb35 Update Claude and Codex flakes 2026-06-18 15:57:04 -07:00
9d09b33e3e chore: update keepbook input 2026-06-18 15:49:59 -07:00
8a00f33c75 chore: update keepbook input 2026-06-18 14:45:55 -07:00
7b9031d85f docs: avoid pull request title prefixes 2026-06-18 14:19:24 -07:00
6216b54bfc nixos: update rlru input 2026-06-18 14:17:45 -07:00
01895cf518 nixos: update rlru input 2026-06-18 14:06:08 -07:00
ae67cd4ca3 nixos: add rocket sense privacy page 2026-06-18 13:53:38 -07:00
b41a1d8e36 docs: prefer ready pull requests 2026-06-18 13:53:16 -07:00
9bdc56c207 Update disk cleanup Rust target guidance 2026-06-18 11:43:12 -07:00
428ee71396 Get back on upstream for codex desktop 2026-06-18 01:34:15 -07:00
d936b477cd nixos: use nix store path for zsh lib instead of mutable worktree path
libDir pointed to ${config.dotfiles-worktree}/dotfiles/lib, which gets
evaluated at build time — so running `just switch` from inside a worktree
would bake that worktree path into /etc/zshenv permanently. If the worktree
is later removed, every zsh startup errors with "no matches found".

zshLibDir was already defined via builtins.path (a stable nix store copy)
but unused. Switch all fpath/autoload/PATH references to it and drop libDir.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:26:25 -07:00
18 changed files with 193 additions and 90 deletions

View File

@@ -258,9 +258,10 @@ Required behavior:
- A named scratchpad exists for spotify.
- A named scratchpad exists for transmission.
- A named scratchpad exists for volume.
- A named scratchpad exists for x.com.
- Scratchpads appear near-fullscreen and centered by default.
- The codex scratchpad can be tiled into the normal workspace when desired,
while retaining its summon/dismiss toggle.
- The codex, claude, and x.com scratchpads can be tiled into the normal
workspace when desired, while retaining their summon/dismiss toggles.
- Toggling a scratchpad deactivates fullscreen/tabbed state first.
- Floating scratchpads are hidden from normal workspace and window listings.
@@ -447,6 +448,7 @@ Required behavior:
- `Super+Alt+s` toggles the spotify scratchpad.
- `Super+Alt+t` toggles the transmission scratchpad.
- `Super+Alt+v` toggles the volume scratchpad.
- `Super+Alt+x` toggles the x.com scratchpad.
Important behavior:

View File

@@ -11,6 +11,12 @@
- Create `.worktrees/` if needed before running `git worktree add`.
- Only use a non-`.worktrees/` location when the user explicitly asks for a different path.
## GitHub pull requests
- Default to creating pull requests as ready for review, not drafts.
- Do not add a `[codex]` prefix or any other agent/tool prefix to pull request titles.
- Create a draft pull request only when the user explicitly asks for a draft or when the remote platform requires draft status.
- If using a helper, skill, or CLI wrapper that defaults to draft PRs, override that default before creating the PR.
## NixOS workflow
- This system is managed with a Nix flake at `/srv/dotfiles/nixos`.
- Use `just switch` from that directory for rebuilds instead of plain `nixos-rebuild`.

View File

@@ -19,6 +19,7 @@ Bundled helpers:
- Prioritize easy wins first (`nix-collect-garbage`, container prune, Cargo artifacts).
- Propose destructive actions with expected impact before running them.
- Run destructive actions only after confirmation, unless the user explicitly requests immediate execution of obvious wins.
- For Rust build artifacts, do not repeatedly ask for confirmation before deleting explicit directories literally named `target` after `rust_target_dirs.py delete` validates them. Cargo targets are rebuildable artifacts; when the user asks to clean Rust target directories, validate with the helper, delete with `--yes`, and report the reclaimed space.
- Capture new reusable findings by updating this skill before finishing.
## Workflow
@@ -178,6 +179,7 @@ Machine-specific heavy hitters seen in practice:
- 2026-05-26 cleanup: when `cargo test` is actively running in `~/Projects/subtr-actor`, leave `subtr-actor/target` alone and delete only inactive Cargo-backed targets. Deleting `keepbook`, `rlru`, `rocket-sense`, `rumno`, and stale `subtr-actor/.worktrees/*/target` reclaimed about 24.5G by helper sizing.
- 2026-05-26 cleanup: `~/Projects/nixpkgs/.worktrees/*/result` symlinks pinned several GiB of Nix closures, and clean registered nixpkgs worktrees were about 460M each. Removing stale `result` symlinks, running GC, and removing clean worktrees while preserving dirty ones moved `/` from 100% used to about 90% used.
- 2026-05-27 cleanup: under `~/Projects`, `hypr-workspace-history/target` can be a Rust-style build cache even though the guarded helper rejects it because no `Cargo.toml` is present; inspect and remove that explicit cache manually if present. Preserve `~/Projects/Hyprland/src/layout/target`, which is source code, not a build artifact.
- 2026-06-18 cleanup: deleting helper-validated Rust targets under `.worktrees/*/target` and `.claude/worktrees/*/target`, plus stale `~/Projects/lastfm-edit/target`, removed 24 target directories totaling 67.1G by helper sizing and moved `/` from 99% used to 90% used. Remaining large targets were top-level project caches under `keepbook`, `rlru`, `subtr-actor`, `rocket-sense`, `rocket-sense-pr-73-ci`, `rocket-sense-subtr-viewer`, `rocket-sense-controlled-plays`, and `boxcars`.
## Step 5: `/nix/store` Deep Dive
@@ -248,7 +250,7 @@ nix-store --gc --print-roots | rg '/\\.direnv/flake-profile-' | awk -F' -> ' '{p
- Do not delete user files directly unless explicitly requested.
- Prefer cleanup tools that understand ownership/metadata (`nix`, `docker`, `podman`, `cargo-sweep`) over `rm -rf`.
- For Rust build artifacts, deleting an explicit directory literally named `target` is acceptable when it is discovered by the bundled helper; Cargo will rebuild it.
- For Rust build artifacts, deleting an explicit directory literally named `target` is acceptable when it is discovered and validated by the bundled helper; Cargo will rebuild it. Do not double-check with the user after helper validation when the active request is Rust target cleanup.
- Present a concise “proposed actions” list before high-impact deletes.
- If uncertain whether data is needed, stop at investigation and ask.

View File

@@ -88,17 +88,7 @@ function M.setup(ctx)
end
local function setup_window_overview_bindings()
bind(main_mod .. " + SHIFT + C", hl.dsp.window.close(), desc("Close active window"))
bind(main_mod .. " + SHIFT + Q", hl.dsp.exit(), desc("Exit Hyprland"))
bind(main_mod .. " + Tab", hyprexpo("toggle"), desc("Toggle hyprexpo workspace overview", overview_bind_opts))
bind(main_mod .. " + SHIFT + Tab", hyprwinview({
action = "show",
include_current_workspace = false,
start_in_filter_mode = true,
default_action = "bring",
}), desc("Show all-workspace window overview", overview_bind_opts))
bind(main_mod .. " + SHIFT + slash", hyprwinview({ action = "toggle-filter" }), desc("Toggle window overview filter", overview_bind_opts))
bind("ALT + Tab", function()
local function toggle_hyprtasking()
if hl.plugin and hl.plugin.hyprtasking and hl.plugin.hyprtasking.toggle then
hl.plugin.hyprtasking.toggle("cursor")
else
@@ -110,8 +100,19 @@ function M.setup(ctx)
font_size = 13,
})
end
end, desc("Toggle hyprtasking workspace overview", overview_bind_opts))
bind("ALT + SHIFT + Tab", hyprexpo("on"), desc("Open hyprexpo workspace overview", overview_bind_opts))
end
bind(main_mod .. " + SHIFT + C", hl.dsp.window.close(), desc("Close active window"))
bind(main_mod .. " + SHIFT + Q", hl.dsp.exit(), desc("Exit Hyprland"))
bind(main_mod .. " + Tab", toggle_hyprtasking, desc("Toggle hyprtasking workspace overview", overview_bind_opts))
bind(main_mod .. " + SHIFT + Tab", hyprwinview({
action = "show",
include_current_workspace = false,
start_in_filter_mode = true,
default_action = "bring",
}), desc("Show all-workspace window overview", overview_bind_opts))
bind(main_mod .. " + SHIFT + slash", hyprwinview({ action = "toggle-filter" }), desc("Toggle window overview filter", overview_bind_opts))
bind("ALT + Tab", toggle_hyprtasking, desc("Toggle hyprtasking workspace overview", overview_bind_opts))
bind(main_mod .. " + G", hyprwinview({
action = "show",
start_in_filter_mode = true,
@@ -290,6 +291,9 @@ function M.setup(ctx)
bind(mod_alt .. " + V", function()
toggle_scratchpad("volume")
end, desc("Toggle volume scratchpad"))
bind(mod_alt .. " + X", function()
toggle_scratchpad("x_com")
end, desc("Toggle X scratchpad"))
bind(mod_alt .. " + grave", function()
toggle_scratchpad("dropdown")
end, desc("Toggle dropdown scratchpad"))

View File

@@ -51,6 +51,12 @@ function M.setup(ctx)
command = "google-chrome-stable --profile-directory=Default --app=https://messages.google.com/web/conversations",
class = "chrome-messages.google.com",
},
x_com = {
command = "x-com-pwa",
classes = { "x-com-pwa", "chrome-x.com" },
title = "X",
allow_tiling = true,
},
transmission = {
command = "transmission-gtk",
class = "transmission-gtk",

View File

@@ -89,6 +89,7 @@ function M.setup(ctx)
end
if enable_hyprtasking and not verify_config then
hl.plugin.load("/run/current-system/sw/lib/libhyprtasking.so")
os.execute("hyprctl eval 'hl.config({plugin={hyprtasking={full_render=true}}})' >/dev/null 2>&1 || true")
end
if enable_hyprexpo and not enable_hyprtasking and not verify_config then
hl.plugin.load("/run/current-system/sw/lib/libhyprexpo.so")

View File

@@ -65,7 +65,7 @@ return {
-- hook fires on every popup commit). Re-enable once fixed upstream.
enable_hyprexpo = false,
enable_hyprwinview = true,
enable_hyprtasking = false,
enable_hyprtasking = true,
enable_workspace_history = true,
enable_hyprwobbly = true,
enable_dynamic_cursors = true,

View File

@@ -147,6 +147,7 @@ spawnBindings =
, key (super .|. alt) xK_s (toggleScratchpad "spotify")
, key (super .|. alt) xK_t (toggleScratchpad "transmission")
, key (super .|. alt) xK_v (toggleScratchpad "volume")
, key (super .|. alt) xK_x (toggleScratchpad "x-com")
, key (super .|. alt) xK_c (spawnAction "google-chrome-stable")
, key super xK_e (spawnAction "emacsclient --eval '(emacs-everywhere)'")
, key (super .|. ctrl) xK_e (shiftFocusedToNextEmptyWorkspace False)
@@ -297,6 +298,8 @@ scratchpadDefinitions =
anyMatcher [titleContains "Transmission", appIdContains "transmission"]
, ScratchpadDefinition "volume" "pavucontrol" $
anyMatcher [appIdMatches "Pavucontrol", appIdContains "pavucontrol"]
, ScratchpadDefinition "x-com" "x-com-pwa" $
anyMatcher [appIdMatches "x-com-pwa", appIdContains "chrome-x.com"]
]
anyMatcher :: [RiverWMWindowState -> Bool] -> RiverWMWindowState -> Bool

View File

@@ -244,6 +244,11 @@ slackSelector = className =? "Slack"
spotifySelector = className =? "Spotify"
transmissionSelector = fmap (isPrefixOf "Transmission") title
volumeSelector = className =? "Pavucontrol"
xComSelector =
className =? "x-com-pwa"
<||> fmap ("chrome-x.com" `isInfixOf`) className
<||> (chromeSelectorBase <&&> title =? "X")
<||> fmap ("x.com" `isInfixOf`) title
virtualClasses =
[ (chromeSelector, "Chrome")
@@ -261,6 +266,7 @@ slackCommand = "slack"
spotifyCommand = "spotify"
transmissionCommand = "transmission-gtk"
volumeCommand = "pavucontrol"
xComCommand = "x-com-pwa"
-- Startup hook
@@ -811,6 +817,7 @@ scratchpads =
, NS "spotify" spotifyCommand spotifySelector nearFullFloat
, NS "transmission" transmissionCommand transmissionSelector nearFullFloat
, NS "volume" volumeCommand volumeSelector nearFullFloat
, NS "x-com" xComCommand xComSelector nearFullFloat
]
@@ -1018,6 +1025,7 @@ addKeys conf@XConfig { modMask = modm } =
, ((modalt, xK_s), doScratchpad "spotify")
, ((modalt, xK_t), doScratchpad "transmission")
, ((modalt, xK_v), doScratchpad "volume")
, ((modalt, xK_x), doScratchpad "x-com")
-- Specific program spawning

View File

@@ -12,11 +12,7 @@ let
src = inputs.codex-desktop-linux;
patches = [ ./patches/codex-desktop-linux-gsettings-schemas.patch ];
};
claudeDesktopSource = pkgs.applyPatches {
name = "claude-desktop-linux-patched";
src = inputs.claude-desktop;
patches = [ ./patches/claude-desktop-add-dir-multiple-matches.patch ];
};
claudeDesktopSource = inputs.claude-desktop;
claudeDesktopNodePty = pkgs.callPackage "${claudeDesktopSource}/nix/node-pty.nix" {};
claudeDesktop = pkgs.callPackage "${claudeDesktopSource}/nix/claude-desktop.nix" {
node-pty = claudeDesktopNodePty;

View File

@@ -86,6 +86,34 @@
exec google-chrome-stable --profile-directory="$profile_dir" --new-window
'';
};
xComPwa = pkgs.writeShellApplication {
name = "x-com-pwa";
runtimeInputs = [
googleChromeCommandWrappers
pkgs.jq
];
text = ''
profile_args=()
local_state="''${CHROME_USER_DATA_DIR:-$HOME/.config/google-chrome}/Local State"
if [ -r "$local_state" ]; then
profile_dir="$(
jq -r '
(.profile.info_cache // {})
| to_entries
| sort_by(if .key == "Default" then 0 else 1 end, -(.value.active_time // 0))
| .[0].key // empty
' "$local_state" 2>/dev/null || true
)"
if [ -n "$profile_dir" ]; then
profile_args+=(--profile-directory="$profile_dir")
fi
fi
exec google-chrome-stable "''${profile_args[@]}" --class=x-com-pwa --app=https://x.com/
'';
};
googleChromeDesktopEntries = pkgs.runCommand "google-chrome-desktop-entries" {nativeBuildInputs = [pkgs.gnused];} ''
mkdir -p "$out/share/applications"
@@ -242,6 +270,21 @@
};
};
xdg.desktopEntries.x-com-pwa = {
name = "X";
genericName = "Social Network";
comment = "Open x.com in a dedicated Chrome app window";
icon = "google-chrome";
terminal = false;
type = "Application";
categories = ["Network"];
startupNotify = true;
exec = "${xComPwa}/bin/x-com-pwa";
settings = {
StartupWMClass = "x-com-pwa";
};
};
xdg.configFile."ghostty/config" = {
force = true;
text = ''
@@ -354,6 +397,7 @@
spotify
spotifyWaylandPatch
tor-browser
xComPwa
# vscode
zulip
]

View File

@@ -11,7 +11,6 @@
if envDotfilesWorktree != ""
then envDotfilesWorktree
else "/srv/dotfiles";
libDir = "${config.dotfiles-worktree}/dotfiles/lib";
zshLibDir = builtins.path {
path = ../dotfiles/lib;
name = "dotfiles-zsh-lib";
@@ -77,9 +76,9 @@ in
# handled once by oh-my-zsh below, with this check intentionally skipped.
ZSH_DISABLE_COMPFIX=true
fpath=("$HOME/.lib/completions" "${libDir}/completions" $fpath)
fpath+="${libDir}/functions"
for file in "${libDir}/functions/"*
fpath=("$HOME/.lib/completions" "${zshLibDir}/completions" $fpath)
fpath+="${zshLibDir}/functions"
for file in "${zshLibDir}/functions/"*
do
autoload "''${file##*/}"
done
@@ -184,7 +183,7 @@ in
export STARSHIP_INSIDE_EMACS="yes"
'';
extraInit = ''
export PATH="$HOME/.cargo/bin:${libDir}/bin:${libDir}/functions:$PATH";
export PATH="$HOME/.cargo/bin:${zshLibDir}/bin:${zshLibDir}/functions:$PATH";
'';
};
};

47
nixos/flake.lock generated
View File

@@ -114,11 +114,11 @@
]
},
"locked": {
"lastModified": 1781314818,
"narHash": "sha256-76EizPNWUOPLqwg6OP1KnX7XE7FEdrsJ2zQQaRKLYT4=",
"lastModified": 1781735477,
"narHash": "sha256-s66kETXt3w11uXH/njBfmmB1TOZn/MAmLL5VSqwOzqQ=",
"owner": "sadjow",
"repo": "claude-code-nix",
"rev": "7c3c4413d8dbe29762fb5a9cb5443c3a72a9e18a",
"rev": "9f444d93bf8029de1a9be31634be5a995ee5292c",
"type": "github"
},
"original": {
@@ -135,11 +135,11 @@
]
},
"locked": {
"lastModified": 1781493849,
"narHash": "sha256-FIJdDGH1gb4HTppTTwJSSlH5xrKr8IfpinkAWpJUpto=",
"lastModified": 1781747722,
"narHash": "sha256-4aFy+NJ3aIVi7mIPLvIubnUuDy09FwDd+kG2QpagzCY=",
"owner": "aaddrick",
"repo": "claude-desktop-debian",
"rev": "2d1d0c59ffb94c0de8a0c5627d03c28099599792",
"rev": "748b38854841db29b122d17515d4cf5add598994",
"type": "github"
},
"original": {
@@ -159,11 +159,11 @@
]
},
"locked": {
"lastModified": 1781038009,
"narHash": "sha256-MxvxXJ+EJxB9On3VfwjHLfeZFSB8Xlqz1IRpl43F76Q=",
"lastModified": 1781761441,
"narHash": "sha256-ZXJdWelt7SwbQTh18krnNgSS2SRveK4aoqO3xPdODD8=",
"owner": "sadjow",
"repo": "codex-cli-nix",
"rev": "75d6b831e036029e3d5f60b4f128dc0121730c37",
"rev": "e3e7751853ece92c2a05ba4e8feee54afdb668c8",
"type": "github"
},
"original": {
@@ -183,16 +183,15 @@
]
},
"locked": {
"lastModified": 1781231404,
"narHash": "sha256-RgbXa8W975nSV2zyQdcXjuQepahhlAF0cW6jwecU9x4=",
"owner": "colonelpanic8",
"lastModified": 1781785128,
"narHash": "sha256-GQXqQIYLBNnPZNrmgt7aedf7PvO4QKKYjpVCAfowbQg=",
"owner": "ilysenko",
"repo": "codex-desktop-linux",
"rev": "8b8c5f05774ec9a48664dcf657f9fb7761174f8c",
"rev": "933413a679df51886ea05d1d0eeb8057e44bf764",
"type": "github"
},
"original": {
"owner": "colonelpanic8",
"ref": "colonelpanic/linux-build-info-no-shadow",
"owner": "ilysenko",
"repo": "codex-desktop-linux",
"type": "github"
}
@@ -1150,11 +1149,11 @@
]
},
"locked": {
"lastModified": 1781106993,
"narHash": "sha256-BddvyVeSgLZU34hzI4yaXYILmfQN9n7oQJk4RbSaZM4=",
"lastModified": 1781534922,
"narHash": "sha256-jmzKIyRmpZLpxnR7DsWZ42bMzt+WeYDk+/x3FKSkovM=",
"owner": "yerlotic",
"repo": "hyprtasking",
"rev": "3b3cb9d0b2fd4f6f4227b5b9539e849a37a17ddd",
"rev": "1a82ca1ac79602e3bfd5ecb0a52c40c2bf818586",
"type": "github"
},
"original": {
@@ -1409,11 +1408,11 @@
]
},
"locked": {
"lastModified": 1781484243,
"narHash": "sha256-8MORYJdWu16cvjbdpUkql1CKU+49UYEBimhAeNHrba4=",
"lastModified": 1781822941,
"narHash": "sha256-9biXcoMW/Gdh7HBbXBpH2tt33xh8Zvhsm9wuHVEcpXE=",
"owner": "colonelpanic8",
"repo": "keepbook",
"rev": "6a3381159a60761ac65ab0a1ebfd82762feae1b7",
"rev": "815a26ff7efad93fd6fa5395af177c7c5d86068f",
"type": "github"
},
"original": {
@@ -1965,11 +1964,11 @@
]
},
"locked": {
"lastModified": 1781557452,
"narHash": "sha256-SsVClSsfiSWNyf343bcCW/NZOgAgsSiYS8W2fmRXmmY=",
"lastModified": 1781930687,
"narHash": "sha256-DT8yGwCsJuKedNRXceXx681x8Y1Wz+41/n7zP8HlURA=",
"owner": "rlrml",
"repo": "rlru",
"rev": "d815411d795110ab6e5beff33f59099322b94d00",
"rev": "577eb6379e3adc0fd5e7bd9fb80556dc931c3e18",
"type": "github"
},
"original": {

View File

@@ -275,7 +275,7 @@
};
codex-desktop-linux = {
url = "github:colonelpanic8/codex-desktop-linux?ref=colonelpanic/linux-build-info-no-shadow";
url = "github:ilysenko/codex-desktop-linux";
inputs = {
nixpkgs.follows = "nixpkgs";
flake-utils.follows = "flake-utils";

View File

@@ -198,6 +198,10 @@
src = inputs.hyprtasking;
strictDeps = true;
postPatch = ''
substituteInPlace src/layout/layout_base.cpp \
--replace-fail 'e.element->passName()' 'e->element->passName()'
'';
nativeBuildInputs =
[
pkgs.pkg-config
@@ -287,10 +291,9 @@
hyprlandPluginPackages =
[
hyprNStack
hyprexpo
hyprwinview
hyprWorkspaceHistory
# hyprtasking # disabled: build failure against current Hyprland API
hyprtasking
hyprDynamicCursors
hyprwobbly
]

View File

@@ -204,6 +204,10 @@
src = inputs.hyprtasking;
strictDeps = true;
postPatch = ''
substituteInPlace src/layout/layout_base.cpp \
--replace-fail 'e.element->passName()' 'e->element->passName()'
'';
nativeBuildInputs = [
pkgs.pkg-config
pkgs.meson
@@ -291,10 +295,9 @@
hyprlandPluginPackages =
[
hyprNStack
hyprexpo
hyprwinview
hyprWorkspaceHistory
# hyprtasking # disabled: build failure against current Hyprland API
hyprtasking
hyprDynamicCursors
hyprwobbly
]

View File

@@ -107,6 +107,67 @@
services.nginx.virtualHosts."rocket-sense.duckdns.org" = {
enableACME = true;
forceSSL = true;
locations."= /privacy" = {
alias = pkgs.writeText "rocket-sense-privacy.html" ''
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Rocket Sense Privacy Policy</title>
<style>
body {
color: #171717;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
line-height: 1.55;
margin: 0;
padding: 48px 24px;
}
main {
max-width: 760px;
margin: 0 auto;
}
h1, h2 {
line-height: 1.2;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.2rem;
margin-top: 2rem;
}
</style>
</head>
<body>
<main>
<h1>Rocket Sense Privacy Policy</h1>
<p>Last updated: June 18, 2026</p>
<p>Rocket Sense is a Rocket League replay analysis service operated by Ivan Malison. This policy explains what information the service uses when you sign in and upload or view replay data.</p>
<h2>Information We Collect</h2>
<p>When you sign in with Epic Games, Rocket Sense receives the Epic account identifiers and profile fields that you approve during the Epic login flow, such as account ID and display name. When you use the service, Rocket Sense may store replay files, replay metadata, player identifiers, derived gameplay statistics, and basic account/session records needed to operate the site.</p>
<h2>How We Use Information</h2>
<p>Rocket Sense uses this information to authenticate users, associate uploads with accounts, process replay files, display replay-derived statistics, maintain site reliability, and prevent abuse.</p>
<h2>Sharing</h2>
<p>Rocket Sense does not sell personal information. Information may be processed by infrastructure providers used to host and operate the service, and may be disclosed if required by law or necessary to protect the service and its users.</p>
<h2>Retention</h2>
<p>Rocket Sense keeps account, replay, and derived analysis data for as long as needed to provide the service, debug issues, maintain security, or comply with legal obligations.</p>
<h2>Contact</h2>
<p>For privacy questions or deletion requests, contact Ivan Malison at IvanMalison@gmail.com.</p>
</main>
</body>
</html>
'';
extraConfig = ''
default_type text/html;
'';
};
locations."/" = {
proxyPass = "http://127.0.0.1:30080";
proxyWebsockets = true;

View File

@@ -1,34 +0,0 @@
diff --git a/scripts/patches/config.sh b/scripts/patches/config.sh
index 2453488..7c3f510 100644
--- a/scripts/patches/config.sh
+++ b/scripts/patches/config.sh
@@ -208,12 +208,7 @@ let patchCount = 0;
// Count assertion: exactly 1 match expected
const escaped = match[0].replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
- const allMatches = code.match(new RegExp(escaped, 'g'));
- if (allMatches && allMatches.length > 1) {
- console.error('FATAL: --add-dir pattern matches ' +
- allMatches.length + ' times (expected 1).');
- process.exit(1);
- }
+ const replacementCount = (code.match(new RegExp(escaped, 'g')) || []).length;
let filtered;
if (variant === 'for-of') {
@@ -230,9 +225,12 @@ let patchCount = 0;
'.push("--add-dir",' + iterVar + '))';
}
- code = code.replace(match[0], filtered);
+ code = code.split(match[0]).join(filtered);
console.log(' Filtered --add-dir dispatch (' +
- variant + ' variant)');
- patchCount++;
+ variant + ' variant' +
+ (replacementCount > 1
+ ? ', ' + replacementCount + ' identical matches'
+ : '') + ')');
+ patchCount += Math.max(1, replacementCount);
}
// ================================================================