Monorepo for Aesthetic.Computer
aesthetic.computer
Git Commit Status Indicator for Prompt Curtain#
Overview#
Add a visual indicator to the prompt.mjs curtain UI showing whether the deployed site is on the latest git commit or behind, with the commit hash displayed.
Visual Design#
- Location: Below "X HANDLES SET" text on the login curtain
- Font: MatrixChunky8 (same as handles counter)
- Colors:
- 🟢 Green (
[0, 255, 0]) = Site is up-to-date with latest commit - 🟠 Orange (
[255, 165, 0]) = Site is behind (shows how many commits)
- 🟢 Green (
- Format Examples:
✓ 37da247(current)↑ 2 behind (37da247)(behind by 2 commits)
Implementation Steps#
1. Create Build-Time Version File#
File: system/public/version.json (generated at build time)
Add to netlify.toml build command:
command = "rm -f public/index.html && echo '{\"commit\":\"'$COMMIT_REF'\",\"timestamp\":\"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'\"}' > public/version.json"
This creates a file like:
{"commit":"37da2475abc123...","timestamp":"2026-01-11T22:34:06Z"}
2. Create Netlify Function: /api/version#
File: system/netlify/functions/version.mjs
// Fetches latest commit from GitHub and compares to deployed version
export default async (request) => {
const deployedCommit = process.env.COMMIT_REF || "unknown";
try {
// Fetch latest commit from GitHub (public, no auth needed)
const res = await fetch(
"https://api.github.com/repos/whistlegraph/aesthetic-computer/commits?per_page=50",
{ headers: { "User-Agent": "aesthetic-computer" } }
);
const commits = await res.json();
const latestCommit = commits[0]?.sha;
// Find how many commits behind
let behindBy = 0;
if (deployedCommit !== "unknown" && latestCommit) {
const idx = commits.findIndex(c => c.sha.startsWith(deployedCommit.slice(0, 7)));
behindBy = idx === -1 ? 50 : idx; // -1 means very old
}
const status = behindBy === 0 ? "current" : "behind";
return Response.json({
deployed: deployedCommit.slice(0, 7),
latest: latestCommit?.slice(0, 7),
status,
behindBy,
timestamp: new Date().toISOString()
});
} catch (e) {
return Response.json({
deployed: deployedCommit.slice(0, 7),
status: "unknown",
error: e.message
});
}
};
export const config = { path: "/api/version" };
3. Add Redirect in netlify.toml#
[[redirects]]
from = "/api/version"
to = "/.netlify/functions/version"
status = 200
4. Update prompt.mjs#
A. Add State Variables (~line 230)#
let versionInfo = null; // { deployed, latest, status, behindBy }
B. Fetch in boot() (~line 640, after handles fetch)#
// Fetch commit/version status
const fetchVersion = async () => {
try {
const res = await fetch("/api/version");
versionInfo = await res.json();
needsPaint();
} catch (e) {
console.warn("Could not fetch version info:", e);
}
};
fetchVersion();
// Refresh every 5 minutes
setInterval(fetchVersion, 5 * 60 * 1000);
C. Render in paint() (~line 6081, after handles text)#
// Git commit status indicator
if (versionInfo && screen.height >= 120) {
const versionY = handlesY + 12;
let versionText, versionColor;
if (versionInfo.status === "current") {
versionColor = [0, 255, 0]; // Green
versionText = `✓ ${versionInfo.deployed}`;
} else if (versionInfo.status === "behind") {
versionColor = [255, 165, 0]; // Orange
versionText = `↑ ${versionInfo.behindBy} behind (${versionInfo.deployed})`;
} else {
versionColor = [128, 128, 128]; // Gray for unknown
versionText = `? ${versionInfo.deployed || "unknown"}`;
}
ink(versionColor).write(
versionText,
{ center: "x", y: versionY },
undefined, undefined, false, "MatrixChunky8"
);
}
File Changes Summary#
| File | Change |
|---|---|
system/netlify.toml |
Update build command to generate version.json; add redirect |
system/netlify/functions/version.mjs |
New function (create) |
system/public/aesthetic.computer/disks/prompt.mjs |
Add state var, boot fetch, paint render |
Technical Notes#
GitHub API#
- Endpoint:
GET https://api.github.com/repos/whistlegraph/aesthetic-computer/commits - Rate limit: 60 requests/hour unauthenticated (sufficient with 5-min polling + server-side caching)
- No auth required for public repos
Netlify Environment Variables#
COMMIT_REF- Full SHA of the commit being deployed (available at build/function time)BUILD_ID- Unique build identifier
Caching Strategy#
The Netlify function can add cache headers to reduce GitHub API calls:
return new Response(JSON.stringify(data), {
headers: {
"Content-Type": "application/json",
"Cache-Control": "public, max-age=60" // Cache for 1 minute
}
});
Future Enhancements#
- Click on commit hash to open GitHub commit page
- Show commit message preview on hover
- Add "Update available" notification badge
- Track deploy history / show last N deploys