Files
stack/agents/darkwing/work/queue-53-review/r2/mut/mutate.py
T

49 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# mutate.py <id>: apply one named mutant to the candidate (exact text, must match once). Run from the tree root.
import sys
B, A, C, S, H = "packages/webui/src/public/bus.js", "packages/webui/src/public/app.js", "packages/webui/src/public/shell.css", "packages/webui/src/serve.mjs", "packages/webui/src/public/index.html"
M = {
"M01": [(B, "err.status === 403 || ['not-configured', 'no-bus-host'].includes(err.code);", "err.status === 403;")],
"M02": [(A, "const refused = err.status === 403;", "const refused = false;")],
"M03": [(A, "document.body.classList.toggle('board-refused', refused);", "")],
"M04": [(B, "<b>refused: <code>${txt(err.code)}</code>.</b> ", "<b>refused: ${txt(err.code)}.</b> ")],
"M05": [(B, "${state === 'stale' ? ' · <span class=\"warn\">stale: the last read failed</span>' : ''}", "")],
"M06": [(A, "if (mode === 'system') delete document.documentElement.dataset.mode; else document.documentElement.dataset.mode = mode;", "document.documentElement.dataset.mode = mode;")],
"M07": [(B, "t.innerHTML = `<span>${esc(text)}</span>", "t.innerHTML = `<span>${text}</span>")],
"M08": [(B, "<span>${txt(i.label)}</span><span class=\"g\">", "<span>${i.label}</span><span class=\"g\">")],
"M09": [(C, ":focus-visible{outline:2px solid var(--focus);outline-offset:2px}", ":focus-visible{outline:2px solid var(--focus);outline-offset:0}")],
"M10": [(C, ":focus-visible{outline:2px solid var(--focus);outline-offset:2px}", ":focus-visible{outline:1px solid var(--focus);outline-offset:2px}")],
"M11": [(C, " .s1-sections{display:flex;flex-wrap:nowrap;overflow-x:auto;", " .s1-sections{display:flex;flex-wrap:wrap;overflow-x:visible;")],
"M21": [(B, "function forget() { last.clear(); inboxCount = null; }", "function forget() {}")],
"M22": [(B, "catch (err) { if (refusal(err)) { forget(); if (g === gen) sections(path); } }", "catch {}")],
"M23": [(B, " if (refusal(err)) forget();\n", "")],
"M24": [(B, "if (rs.some(r => r.status === 'rejected' && refusal(r.reason))) { forget(); sections(routeOf().split('?')[0]); }", "")],
"M25": [(A, "data = null; selected = null; project = null;", "data = null; project = null;")],
"M26": [(A, "failed === 'refused' ? 'Board <span class=\"warn\">not read: refused</span>' : ", "")],
"M27": [(A, " $('footer').textContent = 'Board not read: refused';\n", "")],
"M28": [(A, " $('status').textContent = 'Not read: the board refused the read';\n", "")],
"M29": [(A, " $('projects').innerHTML = '<p class=\"muted\">Not read: the board refused the read.</p>';\n", "")],
"M30": [(A, " for (const id of ['waiting-count', 'seen-count', 'session-count']) $(id).textContent = '–';\n", "")],
"M31": [(B, "state === 'refused' ? 'Bus <span class=\"warn\">not read: refused</span>' : ", "")],
"M32": [(C, ".toast:not(.on){width:1px;height:1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;box-shadow:none}", ".toast:not(.on){display:none}")],
"M33": [(B, "function forget() { last.clear(); inboxCount = null; }", "function forget() { last.clear(); }")],
"M34": [(B, "function forget() { last.clear(); inboxCount = null; }", "function forget() { inboxCount = null; }")],
"M35": [(A, "`${new Date(at).toISOString().slice(11, 19)} UTC`", "new Date(at).toLocaleTimeString([], { hour12: false })")],
"M36": [(C, " .s1-sections{display:flex;flex-wrap:nowrap;overflow-x:auto;", " .s1-sections{display:flex;flex-wrap:nowrap;overflow-x:visible;")],
"M37": [(C, " .s1-sections{display:flex;flex-wrap:nowrap;overflow-x:auto;", " .s1-sections{display:flex;flex-wrap:wrap;overflow-x:auto;")],
"M12": [(B, "<svg class=\"i\" aria-hidden=\"true\"><use href=\"/icons.svg#i-${icon}\"/></svg>", "")],
"M13": [(A, " $('board-refused').hidden = true; document.body.classList.remove('board-refused');\n", "")],
"M14": [(B, "links[i + (e.key === 'ArrowDown' ? 1 : -1)]?.focus();", "links[i + (e.key === 'ArrowDown' ? -1 : 1)]?.focus();")],
"M15": [(S, "['/icons.svg', ['icons.svg', 'image/svg+xml']],", "['/icons.svg', ['icons.svg', 'text/plain']],")],
"M16": [(C, ".count,td,.s1-twhen,time,.fresh,.kv dd{font-variant-numeric:tabular-nums}", "")],
"M17": [(A, "try { localStorage.setItem('mosaic-console-appearance',", "try { localStorage.setItem('mosaic-console-look',")],
"M18": [(C, "body.board-refused #board-view{display:none}", "")],
"M19": [(B, "if (refusal(err)) throw err; html = await view(kept,", "html = await view(kept,")],
"M20": [(A, "$('error').className = refused ? 'banner ref' : 'banner err';", "$('error').className = 'banner err';")],
}
for f, old, new in M[sys.argv[1]]:
s = open(f).read()
n = s.count(old)
if n != 1: sys.exit(f"{sys.argv[1]}: {n} matches in {f}")
open(f, "w").write(s.replace(old, new))
print(sys.argv[1], "applied")