This commit is contained in:
sudacode committed 2026-10-07 22:57:23 -07:00
1 parent 232313dccb
commit 8db80dde1c
6 files changed
+28 -12

No files matched your search

+10 -1
View File
@@ -1,6 +1,6 @@
--- ---
name: subminer-live-test name: subminer-live-test
description: Build and install SubMiner, then verify changes, features, or fixes in the live Hyprland desktop using hyprland-computer-use and local anime videos. Use only in a SubMiner checkout or worktree when the user requests live testing or an implementation needs real installed-app verification. Clean up test-created Anki notes and stats sessions through the supported app paths. Do not invoke for read-only questions or headless unit checks. description: Build and install SubMiner, then verify changes, features, or fixes in the live Hyprland desktop using hyprland-computer-use and local anime videos. Use only in a SubMiner checkout or worktree when the user requests live testing, or when a change depends on something the headless e2e harness (`bun run test:e2e`) cannot show, such as Hyprland placement, stacking, fullscreen, click-through, focus, global shortcuts, the packaged AppImage, launcher, or mpv plugin, real media or dictionaries, or the real Anki collection and stats database. Clean up test-created Anki notes and stats sessions through the supported app paths. Do not invoke for read-only questions, headless unit checks, or behavior the e2e harness covers.
--- ---
# SubMiner live testing # SubMiner live testing
@@ -11,6 +11,15 @@ Run all repository commands and resolve all repository paths against the SubMine
The user authorizes building and installing the app for this workflow, and deleting the Anki notes and stats sessions created by the test. This applies to both user invocation and agent-selected live verification during implementation. Limit cleanup to artifacts whose ownership you can prove. Follow tool and sandbox approval requirements. The user authorizes building and installing the app for this workflow, and deleting the Anki notes and stats sessions created by the test. This applies to both user invocation and agent-selected live verification during implementation. Limit cleanup to artifacts whose ownership you can prove. Follow tool and sandbox approval requirements.
## Try the headless harness first
Unless the user explicitly asked for a live test, check the change with the headless e2e harness before building anything. It boots the built app against a real mpv, a synthetic clip, a fixture dictionary, and a fake AnkiConnect, isolated from the desktop, Anki collection, and stats database. See the "Headless End-to-End Harness" section of `docs/workflow/verification.md` in the checkout.
- Run `bun run build`, then `bun run test:e2e`. For a one-off check, use `bun run e2e start` and drive it with `bun run e2e eval|shot|mpv|app|anki`, then `bun run e2e stop`.
- It covers subtitle rendering and tokenization, seeking, lookup popups, modals, startup ordering, and mining up to the AnkiConnect request with generated media.
- Continue with this skill only for behavior it cannot show: Hyprland placement, stacking, fullscreen, click-through, focus handoff, and global shortcuts; the packaged AppImage, installed launcher, and mpv plugin auto-start; real media, ASS styling, the character dictionary, Jellyfin or stream sources; and the real Anki collection (note types, duplicates, field grouping) or stats aggregates and cleanup.
- If the harness was enough, report its result and stop. If not, say in the report which part of the behavior needed the live run and why.
## Prepare ## Prepare
1. Resolve the requested SubMiner checkout or worktree with `git rev-parse --show-toplevel` and confirm its `package.json` and repository instructions identify SubMiner. If invoked outside SubMiner without a specified checkout, ask which checkout to test. State the behavior to verify and the observable result that would demonstrate success. Inspect `git status --short` and the relevant diff in that checkout. Read `docs/workflow/verification.md` and use `subminer-change-verification` for the appropriate cheap checks before packaging. 1. Resolve the requested SubMiner checkout or worktree with `git rev-parse --show-toplevel` and confirm its `package.json` and repository instructions identify SubMiner. If invoked outside SubMiner without a specified checkout, ask which checkout to test. State the behavior to verify and the observable result that would demonstrate success. Inspect `git status --short` and the relevant diff in that checkout. Read `docs/workflow/verification.md` and use `subminer-change-verification` for the appropriate cheap checks before packaging.
+2 -2
View File
@@ -8,7 +8,7 @@ tool_output_token_limit = 25000
model_auto_compact_token_limit = 233000 model_auto_compact_token_limit = 233000
suppress_unstable_features_warning = true suppress_unstable_features_warning = true
sandbox_mode = "workspace-write" sandbox_mode = "workspace-write"
service_tier = "default" service_tier = "fast"
approvals_reviewer = "auto_review" approvals_reviewer = "auto_review"
[tui] [tui]
@@ -20,7 +20,7 @@ screen_reader_detection_done = true
"gpt-5.5" = 4 "gpt-5.5" = 4
"gpt-5.6-sol" = 4 "gpt-5.6-sol" = 4
gpt-6-astra = 4 gpt-6-astra = 4
"gpt-6.1-sol" = 3 "gpt-6.1-sol" = 4
[sandbox_workspace_write] [sandbox_workspace_write]
network_access = true network_access = true
+1 -1
View File
@@ -416,6 +416,6 @@ hl.on("hyprland.start", function()
hl.exec_cmd("uwsm app -sb -t service -- tailscale systray") hl.exec_cmd("uwsm app -sb -t service -- tailscale systray")
hl.exec_cmd("~/.local/bin/aria") hl.exec_cmd("~/.local/bin/aria")
end) end)
pcall(require, "/home/sudacode/.config/hypr/openwhispr-binds.lua")
hl.bind("SHIFT + SUPER + 4", hl.dsp.global("com.t3tools.T3Code:capture-window")) hl.bind("SHIFT + SUPER + 4", hl.dsp.global("com.t3tools.T3Code:capture-window"))
pcall(require, "/home/sudacode/.config/hypr/openwhispr-binds.lua")
+10 -4
View File
@@ -40,6 +40,8 @@ hl.bind(mainMod .. " + SHIFT + c", hl.dsp.window.center())
hl.bind("CTRL+ALT + j", hl.dsp.focus({ monitor = "r" })) hl.bind("CTRL+ALT + j", hl.dsp.focus({ monitor = "r" }))
hl.bind("CTRL+ALT + k", hl.dsp.focus({ monitor = "l" })) hl.bind("CTRL+ALT + k", hl.dsp.focus({ monitor = "l" }))
-- Keep workspace switching available in the default and GSM submaps.
local function bindWorkspaceSwitching()
-- Switch workspaces with mainMod + [0-9] -- Switch workspaces with mainMod + [0-9]
for i = 1, 10 do for i = 1, 10 do
local key = i % 10 local key = i % 10
@@ -51,6 +53,13 @@ for i = 1, 10 do
}) })
) )
end end
-- Scroll through existing workspaces with mainMod + scroll
hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
end
bindWorkspaceSwitching()
-- Move active window to a workspace with mainMod + SHIFT + [0-9] -- Move active window to a workspace with mainMod + SHIFT + [0-9]
for i = 1, 10 do for i = 1, 10 do
local key = i % 10 -- workspace 10 maps to key 0 local key = i % 10 -- workspace 10 maps to key 0
@@ -68,10 +77,6 @@ end
-- hl.bind("SUPER + S", hl.dsp.workspace.toggle_special("magic")) -- hl.bind("SUPER + S", hl.dsp.workspace.toggle_special("magic"))
-- hl.bind("CTRL + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" })) -- hl.bind("CTRL + SHIFT + S", hl.dsp.window.move({ workspace = "special:magic" }))
-- Scroll through existing workspaces with mainMod + scroll
hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
-- Move/resize windows with mainMod + LMB/RMB and dragging -- Move/resize windows with mainMod + LMB/RMB and dragging
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true }) hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true }) hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
@@ -211,6 +216,7 @@ hl.bind("ALT + g", hl.dsp.exec_cmd("/opt/mpv-yomitan/mpv-yomitan.AppImage --togg
hl.bind("SUPER + g", hl.dsp.submap("gsm")) hl.bind("SUPER + g", hl.dsp.submap("gsm"))
hl.define_submap("gsm", function() hl.define_submap("gsm", function()
bindWorkspaceSwitching()
hl.bind("ALT + f", hl.dsp.window.fullscreen("")) hl.bind("ALT + f", hl.dsp.window.fullscreen(""))
hl.bind("SUPER + SHIFT + s", hl.dsp.exec_cmd([[sh -c 'grim -g "$(slurp -d)" - | wl-copy']])) hl.bind("SUPER + SHIFT + s", hl.dsp.exec_cmd([[sh -c 'grim -g "$(slurp -d)" - | wl-copy']]))
hl.bind("CTRL + SHIFT + g", hl.dsp.exec_cmd("~/.local/bin/gsm-ocr-command menu_ocr")) hl.bind("CTRL + SHIFT + g", hl.dsp.exec_cmd("~/.local/bin/gsm-ocr-command menu_ocr"))
+2 -1
View File
@@ -310,12 +310,13 @@ hl.window_rule({
stay_focused = true, stay_focused = true,
}) })
-- Open the GSM overlay at its manually aligned screen position. -- Open the GSM overlay on workspace 6 at its manually aligned screen position.
hl.window_rule({ hl.window_rule({
match = { match = {
class = "com.beangate.gamesentenceminer", class = "com.beangate.gamesentenceminer",
title = "^GSM Overlay$", title = "^GSM Overlay$",
}, },
workspace = "6",
move = "4 3", move = "4 3",
no_initial_focus = false, no_initial_focus = false,
focus_on_activate = true, focus_on_activate = true,
+3 -3
View File
@@ -38,7 +38,7 @@ window {
anchor: center; anchor: center;
fullscreen: false; fullscreen: false;
width: 46.65%; width: 46.65%;
height: 44%; height: 50%;
x-offset: 0px; x-offset: 0px;
y-offset: 0px; y-offset: 0px;
@@ -61,14 +61,14 @@ mainbox {
imagebox { imagebox {
padding: 24px; padding: 24px;
background-color: transparent; background-color: transparent;
background-image: url("~/.config/rofi/images/oshinoko.png", both); background-image: url("~/.config/rofi/images/oshinoko-full-body.png", both);
orientation: vertical; orientation: vertical;
children: [ "inputbar", "dummy", "mode-switcher" ]; children: [ "inputbar", "dummy", "mode-switcher" ];
} }
listbox { listbox {
spacing: 20px; spacing: 20px;
padding: 20px; padding: 34px 20px 20px;
background-color: transparent; background-color: transparent;
orientation: vertical; orientation: vertical;
children: [ "message", "listview" ]; children: [ "message", "listview" ];