Review everything shipped this weekend, and fix what the reviewers caught

Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
This commit is contained in:
Gabriel Brown
2026-08-24 13:29:42 -04:00
parent ffce48964e
commit 07db1068f1
42 changed files with 959 additions and 219 deletions
@@ -238,27 +238,29 @@ function normalizeStoredProfile(value) {
return result;
}
// The id is the identity here, and every custom id is custom-* namespaced, so
// it can never collide with a shipped one by accident; a repeat inside the
// stored list is a genuine duplicate and is dropped.
//
// A NAME is only a label, and a colliding one is renamed rather than dropped.
// Dropping was data loss on a delay: this list is also what gets written back
// to the preference, so a custom theme whose name a later Panama release
// happened to ship was silently deleted at the user's next theme edit.
function validCustomProfiles(values, shipped) {
if (!Array.isArray(values))
return [];
var catalog = shippedList(shipped);
var ids = {};
var names = {};
shippedList(shipped).forEach(function(profile) {
ids[profile.id] = true;
names[profile.name.toLowerCase()] = true;
});
catalog.forEach(function(profile) { ids[profile.id] = true; });
var result = [];
values.forEach(function(value) {
var profile = normalizeStoredProfile(value);
if (!profile)
return;
var foldedName = profile.name.toLowerCase();
if (ids[profile.id] || names[foldedName])
if (!profile || ids[profile.id])
return;
ids[profile.id] = true;
names[foldedName] = true;
profile.name = uniqueName(profile.name, catalog.concat(result));
result.push(profile);
});
return result;
@@ -537,7 +539,11 @@ function resaturatePalette(palette, factor) {
var next = clamp(hsv.s * (1 + (scale - 1) * strength), 0, 100);
result[key] = hsvToHex(hsv.h, next, hsv.v);
});
return result;
// Validated on the way out like every other palette this module builds: a
// factor that is not a number survives clamp() as NaN and turns every token
// into a string no palette reader can use. Returning null makes that a
// rejection the caller can see instead of a corrupt theme it stores.
return normalizePalette(result);
}
// Terminal colors for a custom theme that has none of its own: semantic