rename: agent name Sage → Hecate (Cobb pick)

Greek goddess of magic, crossroads (decisions/planning), and herbs.
Three-for-three thematic fit for a meal planner. Internal field names
(sonnet_decision etc) unchanged — those are data, not user-facing.
This commit is contained in:
Kayos 2026-04-30 21:47:06 -07:00
parent a6a28ef6e4
commit f2705e4dd5
6 changed files with 14 additions and 14 deletions

View file

@ -67,7 +67,7 @@
<h1>foods <span class="accent">consolidate</span></h1> <h1>foods <span class="accent">consolidate</span></h1>
<div class="lede"> <div class="lede">
scan your mealie household foods, cluster lookalikes by similarity, scan your mealie household foods, cluster lookalikes by similarity,
let sage pick the survivor + the rest become aliases on it. mealie let hecate pick the survivor + the rest become aliases on it. mealie
rewrites every recipe ingredient to point at the canonical row. rewrites every recipe ingredient to point at the canonical row.
</div> </div>
</div> </div>
@ -83,7 +83,7 @@
<p>no run yet. kick one off?</p> <p>no run yet. kick one off?</p>
<button class="btn btn-purple" id="start-btn" type="button" onclick="startRun()">🪄 scan + cluster mealie foods</button> <button class="btn btn-purple" id="start-btn" type="button" onclick="startRun()">🪄 scan + cluster mealie foods</button>
<p class="muted" style="margin-top:8px;"> <p class="muted" style="margin-top:8px;">
walks your household catalog, clusters by name similarity, asks sage for the survivor of each cluster. walks your household catalog, clusters by name similarity, asks hecate for the survivor of each cluster.
first run might take 5-15 min depending on cluster count. first run might take 5-15 min depending on cluster count.
</p> </p>
</div> </div>

View file

@ -60,7 +60,7 @@
<div class="crumb">// dedupe · find duplicate recipes</div> <div class="crumb">// dedupe · find duplicate recipes</div>
<h1>recipe <span class="accent">dedupe</span></h1> <h1>recipe <span class="accent">dedupe</span></h1>
<div class="lede"> <div class="lede">
scan your household recipes for duplicates by name similarity. sage scan your household recipes for duplicates by name similarity. hecate
looks at ingredients + step counts + source URLs to decide whether looks at ingredients + step counts + source URLs to decide whether
similar-named recipes are actually the same dish. you confirm per similar-named recipes are actually the same dish. you confirm per
cluster — DELETE in Mealie is permanent. cluster — DELETE in Mealie is permanent.
@ -77,7 +77,7 @@
<div id="empty-pane" style="display:none;"> <div id="empty-pane" style="display:none;">
<p>no run yet. scan now?</p> <p>no run yet. scan now?</p>
<button class="btn btn-purple" id="start-btn" type="button" onclick="startRun()">🪄 scan recipes for duplicates</button> <button class="btn btn-purple" id="start-btn" type="button" onclick="startRun()">🪄 scan recipes for duplicates</button>
<p class="muted" style="margin-top:8px;">walks your household recipes, clusters by name similarity, asks sage which clusters are real dupes. apply path uses Mealie's DELETE endpoint — irreversible. user-confirms per cluster.</p> <p class="muted" style="margin-top:8px;">walks your household recipes, clusters by name similarity, asks hecate which clusters are real dupes. apply path uses Mealie's DELETE endpoint — irreversible. user-confirms per cluster.</p>
</div> </div>
<div id="progress-pane" style="display:none;"> <div id="progress-pane" style="display:none;">
@ -244,7 +244,7 @@
meta.className = 'cluster-meta'; meta.className = 'cluster-meta';
meta.textContent = dec.duplicates meta.textContent = dec.duplicates
? `delete ${(dec.delete_slugs||[]).length}, keep 1` ? `delete ${(dec.delete_slugs||[]).length}, keep 1`
: `keep all ${cluster.length} (sage says distinct)`; : `keep all ${cluster.length} (hecate says distinct)`;
left.appendChild(nm); left.appendChild(meta); left.appendChild(nm); left.appendChild(meta);
const tog = document.createElement('button'); const tog = document.createElement('button');

View file

@ -23,7 +23,7 @@
<div class="crumb">// enrich · per-recipe metadata for smarter planning</div> <div class="crumb">// enrich · per-recipe metadata for smarter planning</div>
<h1>recipe <span class="accent">enrich</span></h1> <h1>recipe <span class="accent">enrich</span></h1>
<div class="lede"> <div class="lede">
walk every household recipe and have sage generate structured metadata — walk every household recipe and have hecate generate structured metadata —
cuisine, complexity, macros, meal type, primary protein + carb, cuisine, complexity, macros, meal type, primary protein + carb,
comfort tier, one-line summary. the plan generator uses this so comfort tier, one-line summary. the plan generator uses this so
"high protein week" actually filters the pool, not just biases the vibe. "high protein week" actually filters the pool, not just biases the vibe.

View file

@ -57,13 +57,13 @@
</div> </div>
<p class="muted">mealie's parser is per-recipe; this kicks off a bulk pass over your whole library. review proposals, apply the good ones.</p> <p class="muted">mealie's parser is per-recipe; this kicks off a bulk pass over your whole library. review proposals, apply the good ones.</p>
<p><a class="btn" href="/sterilize">🪄 bulk sterilize recipes →</a></p> <p><a class="btn" href="/sterilize">🪄 bulk sterilize recipes →</a></p>
<p class="muted" style="margin-top:14px;">scan your foods table for dupes, ask sage to pick canonicals, merge in mealie. one-time cleanup; aliases get attached to the survivors so the parser fuzzy-matches variants from now on.</p> <p class="muted" style="margin-top:14px;">scan your foods table for dupes, ask hecate to pick canonicals, merge in mealie. one-time cleanup; aliases get attached to the survivors so the parser fuzzy-matches variants from now on.</p>
<p><a class="btn" href="/consolidate">🔮 consolidate foods table →</a></p> <p><a class="btn" href="/consolidate">🔮 consolidate foods table →</a></p>
<p class="muted" style="margin-top:14px;">find duplicate recipes by name + ingredient similarity. sage picks the canonical to keep; you confirm per cluster before mealie deletes the others. permanent — review carefully.</p> <p class="muted" style="margin-top:14px;">find duplicate recipes by name + ingredient similarity. hecate picks the canonical to keep; you confirm per cluster before mealie deletes the others. permanent — review carefully.</p>
<p><a class="btn" href="/dedupe-recipes">🌀 dedupe recipes →</a></p> <p><a class="btn" href="/dedupe-recipes">🌀 dedupe recipes →</a></p>
<p class="muted" style="margin-top:14px;">have sage generate per-recipe metadata — cuisine, complexity, macros, primary protein/carb, comfort tier, summary. the plan generator reads this so "high protein week" is a real query, not just a vibe.</p> <p class="muted" style="margin-top:14px;">have hecate generate per-recipe metadata — cuisine, complexity, macros, primary protein/carb, comfort tier, summary. the plan generator reads this so "high protein week" is a real query, not just a vibe.</p>
<p><a class="btn" href="/enrich-recipes">✨ enrich recipes →</a></p> <p><a class="btn" href="/enrich-recipes">✨ enrich recipes →</a></p>
</section> </section>
{% endif %} {% endif %}

View file

@ -337,7 +337,7 @@
<div class="pref-readout">excluding: <em>{{ plan.exclusions_label }}</em></div> <div class="pref-readout">excluding: <em>{{ plan.exclusions_label }}</em></div>
{% endif %} {% endif %}
{% elif not plan.slots %} {% elif not plan.slots %}
<p>no plan yet. summon sage to build one from the {{ pick_count }} pinned pick{{ '' if pick_count == 1 else 's' }} + the rest of the grimoire.</p> <p>no plan yet. summon hecate to build one from the {{ pick_count }} pinned pick{{ '' if pick_count == 1 else 's' }} + the rest of the grimoire.</p>
<div class="pref-block"> <div class="pref-block">
<label class="pref-label">meals to plan</label> <label class="pref-label">meals to plan</label>
@ -412,7 +412,7 @@
</div> </div>
<button class="gen-cta" type="button" id="gen-btn" onclick="generatePlan(this)">🪄 generate this week's plan</button> <button class="gen-cta" type="button" id="gen-btn" onclick="generatePlan(this)">🪄 generate this week's plan</button>
<div class="gen-meta" id="gen-meta">sage · ~30s</div> <div class="gen-meta" id="gen-meta">hecate · ~30s</div>
{% else %} {% else %}
<p>plan's set.</p> <p>plan's set.</p>
{% if plan.preference_prompt %} {% if plan.preference_prompt %}
@ -573,7 +573,7 @@ async function generatePlan(btn) {
btn.disabled = true; btn.disabled = true;
btn.innerHTML = '🪄 summoning…'; btn.innerHTML = '🪄 summoning…';
const meta = document.getElementById('gen-meta'); const meta = document.getElementById('gen-meta');
if (meta) meta.textContent = 'sage building plan — hold tight'; if (meta) meta.textContent = 'hecate building plan — hold tight';
try { try {
const r = await fetch('/api/plan/generate', { const r = await fetch('/api/plan/generate', {
method: 'POST', method: 'POST',

View file

@ -106,7 +106,7 @@
<h1>bulk <span class="accent">sterilize</span></h1> <h1>bulk <span class="accent">sterilize</span></h1>
<div class="lede"> <div class="lede">
walk every recipe in the household, send the unparsed ingredients to walk every recipe in the household, send the unparsed ingredients to
sage, review the proposals, apply the good ones. mealie's food hecate, review the proposals, apply the good ones. mealie's food
table gets cleaner; the shopping list math gets sharper. table gets cleaner; the shopping list math gets sharper.
</div> </div>
</div> </div>
@ -378,7 +378,7 @@
<tbody>${rows}</tbody>`; <tbody>${rows}</tbody>`;
card.appendChild(tbl); card.appendChild(tbl);
} else { } else {
// All rows were identity matches — sage thinks this recipe is // All rows were identity matches — hecate thinks this recipe is
// already clean. Show a marker; user can still skip/approve as // already clean. Show a marker; user can still skip/approve as
// a no-op apply (which will be cheap, just refreshes food.id // a no-op apply (which will be cheap, just refreshes food.id
// resolution if any food row got renamed in Mealie). // resolution if any food row got renamed in Mealie).