Weekly Maker Asset Review
The /ops/funnel-review page is a browser-local dashboard that
renders one week of maker activity — build attempts, triple deposits,
hardware coverage, and espctl tool usage — and emits a Markdown
work-report you can paste into a blog post, a group chat, or an
email.
The page never talks to a server. It reads a single JSON snapshot
out of localStorage and computes everything else from there.
Clearing your browser storage clears the snapshot.
Data flow
+-------------------+ pushed via +----------------------+
| local espctl / | -- chrome-mcp --> | window.aegis |
| chrome-mcp / | evaluate_script | .importMakerStats()|
| playwright-mcp | | |
+-------------------+ +----------+-----------+
|
v
localStorage:
aegis.maker-stats.snapshot
|
v
/ops/funnel-review reads it
on mount and on the
`aegis:maker-stats:updated`
event.
Three ways to populate the snapshot:
- Browser-driving MCP agent (recommended). chrome-mcp or
playwright-mcp opens
https://esphome.cloud/ops/funnel-review(or your local dev URL) and callswindow.aegis.importMakerStats(snapshot)viaevaluate_script. - Manual paste. Open
/ops/settings, paste a JSON snapshot in the Maker Data Asset · Import section, click Import. - Direct localStorage write. Any browser tool that can write
localStorage.aegis.maker-stats.snapshotworks; the page picks up the change via thestorageevent.
There is no server-side ingestion. Two browsers on the same machine
see different snapshots because they each have their own
localStorage.
localStorage is a cache, not the source of truth. This is by design. The source of truth lives in
~/maker-assets/{public,private,asset}/triples/— the ledger thatespctl depositwrites. The browser-side snapshot is just a derived view that an agent pushes in. Clearing the browser cache, switching browsers, or hopping devices all lose the view, never the asset. To restore the view: re-runespctl deposit list --since/--until --json, aggregate, and callwindow.aegis.importMakerStats(...)again.
Agent maintenance contract — refresh on every visit
This is the protocol an agent should follow whenever it navigates a
browser tab to any /ops/* URL on this site. Treat localStorage
as if it were just cleared; don’t assume yesterday’s snapshot is
still there or still current.
- Before opening the tab (or right after
navigate_page), the agent runsespctl deposit list --since <start of current week> --until <today> --jsonon the user’s machine and aggregates the resulting triples (plus its own tool-call counts) into a freshMakerStatsSnapshot. - Inside the tab, the agent calls
window.aegis.importMakerStats(snapshot)viaevaluate_script. - Verify the page reacted to
aegis:maker-stats:updated— check that the snapshot block in the DOM (orwindow.aegis.getMakerStats()) reflects the freshly pushedgeneratedAttimestamp.
Why every visit, not just once a week:
- The browser may have evicted localStorage under storage pressure (default quota is not persistent unless requested).
- The user may have cleared site data between visits.
- The user may have opened the tab in a different browser, an incognito window, or on a different machine.
- The maker may have run new builds since the last push; a stale view is worse than no view.
A correctly-behaving agent treats /ops/* as render-on-arrival
— it does not assume any state from a previous session. The push
is cheap (single evaluate_script with a JSON object); pushing
unnecessarily is harmless because the validator drops invalid
snapshots and dispatches aegis:maker-stats:updated only on
successful writes.
Snapshot schema
interface MakerStatsSnapshot {
generatedAt: string; // ISO timestamp, when this snapshot was produced
windowStart: string; // ISO; first day of the week being summarized
windowEnd: string; // ISO; last day of the week being summarized
buildAttempts: number;
buildSuccesses: number;
triplesDeposited: number;
hardwareMix: Array<{
platform: string; // e.g. 'esp32-s3', 'stm32g4'
attempts: number;
successes: number;
}>;
topEspctlTools: Array<{
tool: string; // e.g. 'espctl.build', 'espctl.deposit.add'
count: number;
}>;
notes?: string; // free text from the agent
}
importMakerStats validates strict types:
- All counts must be finite non-negative numbers.
platformandtoolmust be non-empty strings.- Unknown keys are dropped silently; missing required keys reject
with
{ ok: false, error: 'schema mismatch — ...' }.
Browser API contract
The page exposes three functions on window.aegis. They are
installed once when any route mounts (via installMakerStatsWindowApi
in src/lib/user-settings/maker-stats.ts):
| Function | Returns | Notes |
|---|---|---|
window.aegis.importMakerStats(jsonOrObject) | { ok: boolean, error?, snapshot? } | Accepts a JSON string or a parsed object. Persists + dispatches aegis:maker-stats:updated. |
window.aegis.getMakerStats() | MakerStatsSnapshot | null | Reads the current snapshot, or null if none. |
window.aegis.clearMakerStats() | void | Removes the snapshot. The page swaps back to the empty state. |
Listen for snapshot changes with:
window.addEventListener('aegis:maker-stats:updated', (event) => {
console.log('new snapshot', event.detail);
});
Producing a snapshot from espctl
There is no first-party espctl stats --json command yet. Until
that lands, build the snapshot in your agent. A minimal recipe:
# count this week's builds + outcomes from the local triple ledger
espctl deposit list --since 2026-05-17 --until 2026-05-24 --json > week.json
espctl skills --format json > skills.json
A browser-driving agent can then aggregate these into a snapshot and push it:
// pseudocode the agent runs after collecting the JSON above
const snapshot = aggregate(weekJson, skillsJson);
const result = await chromeMcp.evaluateScript(
`window.aegis.importMakerStats(${JSON.stringify(snapshot)})`,
);
if (!result.ok) throw new Error(result.error);
What /ops/funnel-review derives
Once a snapshot is loaded the page computes:
- Six numeric tiles — build attempts, successes (with pass rate hint), triples (with yield hint), hardware platform count, espctl tool variety, total tool calls.
- Hardware mix bar chart — per-platform attempts vs successes.
- Top espctl tools bar chart — horizontal frequency chart of
the tools reported in
topEspctlTools. - Five decision checks — build activity, pass rate, triple
yield, hardware diversity, tool depth. Each is
pass/watch/attention. - One overall badge —
Keep going/Watch/Roll back/ handle, derived from the worst of the five checks. - Markdown work report — a copy-pasteable summary with maker
name, window, builds, hardware breakdown, top tools, and the
optional
notesfield. The Copy Markdown button writes it to the clipboard.
Empty state
If the snapshot is missing or fails to parse, the page renders a
short empty-state with a link to /ops/settings so you can paste
one manually. The empty state and the populated state share no
layout — the page either renders one or the other in full.
Related
espctl deposit— where the triple counts come from.- CLI Utilities — the
--json/--quietglobal flags you’ll use when shelling out from an agent. - Tool Index — every
espctlsubcommand you might want to count intopEspctlTools.