Refusal leaves board data in the inspector, project tree, footer and scan line, and bus data in the Inbox count and the Ctrl+K palette. Gate green, 13 of 20 mutants killed, fonts match the upstream archive. Co-Authored-By: Claude Opus 5.5 <[email protected]>
32 lines
2.8 KiB
Python
32 lines
2.8 KiB
Python
# 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:wrap;overflow-x:visible;flex-basis:100%;gap:2px;padding-bottom:2px}", " .s1-sections{display:flex;flex-basis:100%;gap:2px;padding-bottom:2px}")],
|
|
"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")
|