Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions 404.html
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta content="width=device-width,initial-scale=1" name=viewport> <meta content=#333333 name=theme-color> <base href=/ > <link href=manifest.json rel=manifest crossorigin=use-credentials> <script>__SAPPER__={baseUrl:"",preloaded:[void 0]};if('serviceWorker' in navigator)navigator.serviceWorker.register('/service-worker.js');(function(){try{eval("async function x(){}");var main="/client/client.9b2e11fb.js"}catch(e){main="/client/legacy/client.532031ad.js"};var s=document.createElement("script");try{new Function("if(0)import('')")();s.src=main;s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="/client/shimport@2.0.5.js";s.setAttribute("data-main",main);}document.head.appendChild(s);}());</script> <link href=client/client-31a52aa5.css rel=stylesheet><link href=client/createOctokit-a85f76c7.css rel=stylesheet><link href=client/index-b0b6455a.css rel=stylesheet> <script>// If `prefers-color-scheme` is not supported, fall back to light mode.
<!DOCTYPE html> <html lang=en> <head> <meta charset=utf-8> <meta content="width=device-width,initial-scale=1" name=viewport> <meta content=#000000 name=theme-color> <base href=/ > <link href=manifest.json rel=manifest crossorigin=use-credentials> <script>__SAPPER__={baseUrl:"",preloaded:[void 0]};if('serviceWorker' in navigator)navigator.serviceWorker.register('/service-worker.js');(function(){try{eval("async function x(){}");var main="/client/client.9b2e11fb.js"}catch(e){main="/client/legacy/client.532031ad.js"};var s=document.createElement("script");try{new Function("if(0)import('')")();s.src=main;s.type="module";s.crossOrigin="use-credentials";}catch(e){s.src="/client/shimport@2.0.5.js";s.setAttribute("data-main",main);}document.head.appendChild(s);}());</script> <link href=client/client-31a52aa5.css rel=stylesheet><link href=client/createOctokit-a85f76c7.css rel=stylesheet><link href=client/index-b0b6455a.css rel=stylesheet> <script>// If `prefers-color-scheme` is not supported, fall back to light mode.
// In this case, light.css will be downloaded with `highest` priority.
if (typeof window !== "undefined" && typeof document !== "undefined" && "matchMedia" in window && window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
document.documentElement.style.display = 'none';
document.head.insertAdjacentHTML(
'beforeend',
'<link rel="stylesheet" href={`${config.path}/themes/light.css`} onload="document.documentElement.style.display = \'\'">',
);
} </script> <link href=https://status.commandcode.ai/themes/light.css rel=stylesheet media=(prefers-color-scheme:light)> <link href=https://status.commandcode.ai/themes/dark.css rel=stylesheet media=(prefers-color-scheme:dark)><link href=https://status.commandcode.ai/global.css rel=stylesheet><link href=https://raw.githubusercontent.com/CommandCodeAI/commandcode-status/master/assets/favicon.svg rel=icon type=image/svg><link href=/logo-192.png rel=icon type=image/png> <link href=/client/client.9b2e11fb.js rel=modulepreload as=script crossorigin=use-credentials><link href=/client/client-31a52aa5.css rel=preload as=style><link href=/client/index.1e36db55.js rel=modulepreload as=script crossorigin=use-credentials><link href=/client/createOctokit.5dd4437e.js rel=modulepreload as=script crossorigin=use-credentials><link href=/client/inject_styles.803b7e80.js rel=modulepreload as=script crossorigin=use-credentials><link href=/client/createOctokit-a85f76c7.css rel=preload as=style><link href=/client/index-b0b6455a.css rel=preload as=style></head> <body> <div id=sapper> <nav class=svelte-a08hsz><div class="svelte-a08hsz container"><div><a class="svelte-a08hsz logo" href=https://status.commandcode.ai><img alt="" class=svelte-a08hsz src=https://raw.githubusercontent.com/CommandCodeAI/docs-images/refs/heads/main/design/logo/logo-symbol.svg> <div>Command Code Status</div></a></div> <ul class=svelte-a08hsz><li><a class=svelte-a08hsz href=https://commandcode.ai target=_self>Command Code</a> <li><a class=svelte-a08hsz href=/ target=_self>Status</a> <li><a class=svelte-a08hsz href=https://github.com/CommandCodeAI/commandcode-status/issues target=_self>Subscribe on GitHub</a> </li> </ul></div> </nav> <main class=container></main> <footer class=svelte-jbr799><p></p> </footer></div> <script> try {
} </script> <link href=/themes/light.css rel=stylesheet media=(prefers-color-scheme:light)> <link href=/themes/dark.css rel=stylesheet media=(prefers-color-scheme:dark)><link href=/global.css rel=stylesheet><link href=https://raw.githubusercontent.com/CommandCodeAI/commandcode-status/master/assets/favicon.svg rel=icon type=image/svg><link href=/logo-192.png rel=icon type=image/png> <link href=/client/client.9b2e11fb.js rel=modulepreload as=script crossorigin=use-credentials><link href=/client/client-31a52aa5.css rel=preload as=style><link href=/client/index.1e36db55.js rel=modulepreload as=script crossorigin=use-credentials><link href=/client/createOctokit.5dd4437e.js rel=modulepreload as=script crossorigin=use-credentials><link href=/client/inject_styles.803b7e80.js rel=modulepreload as=script crossorigin=use-credentials><link href=/client/createOctokit-a85f76c7.css rel=preload as=style><link href=/client/index-b0b6455a.css rel=preload as=style></head> <body> <div id=sapper> <nav class=svelte-a08hsz><div class="svelte-a08hsz container"><div><a class="svelte-a08hsz logo" href=https://status.commandcode.ai><img alt="" class=svelte-a08hsz src=https://commandcode.ai/logov2/logo-bg-transparent-fg-dark.svg> <div>Status</div></a></div> <ul class=svelte-a08hsz><li><a class=svelte-a08hsz href=https://commandcode.ai target=_self>Command Code</a> <li><a class=svelte-a08hsz href=/ target=_self>Status</a> <li><a class=svelte-a08hsz href=https://github.com/CommandCodeAI/commandcode-status/issues target=_self>Subscribe on GitHub</a> </li> </ul></div> </nav> <main class=container></main> <footer class=svelte-jbr799><p></p> </footer></div> <script> try {
if (typeof window !== "undefined" && window.navigator && navigator.serviceWorker) {
navigator.serviceWorker.getRegistrations().then(function (registrations) {
for (let registration of registrations) {
Expand Down
2 changes: 1 addition & 1 deletion client/client.9b2e11fb.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion client/legacy/client.532031ad.js

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions client/nav-label-fix.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(function () {
"use strict";

var LABEL = "Status";

function fix() {
var el = document.querySelector(".logo div");
if (el && el.textContent !== LABEL) el.textContent = LABEL;
}

fix();
document.addEventListener("DOMContentLoaded", fix);
window.addEventListener("load", fix);

// The Sapper bundle re-renders the nav on hydration, overwriting
// the static label — watch for that and correct it back.
var target = document.querySelector(".logo");
if (target && window.MutationObserver) {
new MutationObserver(fix).observe(target, {
childList: true,
subtree: true,
characterData: true,
});
}
})();
211 changes: 211 additions & 0 deletions client/system-status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
(function () {
"use strict";

var OWNER = "CommandCodeAI";
var REPO = "commandcode-status";
var RAW_BASE = "https://raw.githubusercontent.com/" + OWNER + "/" + REPO + "/master/history/";
var ISSUES_URL = "https://api.github.com/repos/" + OWNER + "/" + REPO + "/issues?state=all&per_page=100";
var WINDOW_DAYS = 90;
var DAY_MS = 24 * 60 * 60 * 1000;
var MONTH_NAMES = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];

var root = document.getElementById("system-status-rows");
var rangeLabel = document.getElementById("system-status-range");
var prevBtn = document.querySelector('.status-nav-btn[data-dir="prev"]');
var nextBtn = document.querySelector('.status-nav-btn[data-dir="next"]');
if (!root) return;

function toDateOnly(d) {
return new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
}

function addDays(d, n) {
return new Date(d.getTime() + n * DAY_MS);
}

function formatRange(start, end) {
var s = MONTH_NAMES[start.getUTCMonth()] + " " + start.getUTCFullYear();
var e = MONTH_NAMES[end.getUTCMonth()] + " " + end.getUTCFullYear();
return s === e ? s : s + " – " + e;
}

function fetchJson(url) {
return fetch(url, { headers: { Accept: "application/vnd.github+json" } }).then(function (res) {
if (!res.ok) throw new Error("Request failed: " + res.status);
return res.json();
});
}

function parseFrontMatterDate(body, key) {
var m = body && body.match(new RegExp(key + ":\\s*([^\\n]+)"));
return m ? new Date(m[1].trim()) : null;
}

// Turn incident/maintenance issues into day-level severity windows.
function classifyIssue(issue) {
var labels = (issue.labels || []).map(function (l) {
return typeof l === "string" ? l : l.name;
});
var isStatus = labels.indexOf("status") !== -1;
var isMaintenance = labels.indexOf("maintenance") !== -1;
if (!isStatus && !isMaintenance) return null;

var body = issue.body || "";
var start = parseFrontMatterDate(body, "start") || new Date(issue.created_at);
var end = parseFrontMatterDate(body, "end") || (issue.state === "closed" ? new Date(issue.closed_at) : new Date());

var severity;
if (/expectedDown/i.test(body)) severity = "down";
else if (/expectedDegraded/i.test(body)) severity = "degraded";
else if (/degrad|latency|slow/i.test(issue.title + " " + body)) severity = "degraded";
else severity = "down";

// Maintenance windows are shown as degraded (amber), never down (red).
if (isMaintenance && severity === "down") severity = "degraded";

return { start: toDateOnly(start), end: toDateOnly(end), severity: severity };
}

function severityOnDay(day, events) {
var rank = { up: 0, degraded: 1, down: 2 };
var worst = "up";
for (var i = 0; i < events.length; i++) {
var ev = events[i];
if (day >= ev.start && day <= ev.end && rank[ev.severity] > rank[worst]) {
worst = ev.severity;
}
}
return worst;
}

function statusLabel(status) {
if (status === "down") return "Down";
if (status === "degraded") return "Degraded performance";
return "Operational";
}

function el(tag, className, text) {
var node = document.createElement(tag);
if (className) node.className = className;
if (text != null) node.textContent = text;
return node;
}

function renderRow(site, events, siteStart, windowStart, windowEnd) {
var row = el("article", "status-row " + site.status);

var head = el("div", "status-row-head");
head.appendChild(el("span", "status-dot"));
head.appendChild(el("span", "status-name", site.name));
head.appendChild(el("span", "status-label", statusLabel(site.status)));

var bar = el("div", "status-bar");
bar.setAttribute("role", "img");

var dataDays = 0;
var downDays = 0;
var cursor = windowStart;
while (cursor <= windowEnd) {
var cell = el("span", "status-cell");
if (siteStart && cursor < siteStart) {
cell.className += " no-data";
cell.title = "No data";
} else {
var sev = severityOnDay(cursor, events);
cell.className += " " + sev;
var dateStr = cursor.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric", timeZone: "UTC" });
cell.title = dateStr + " — " + statusLabel(sev);
dataDays++;
if (sev === "down") downDays++;
}
bar.appendChild(cell);
cursor = addDays(cursor, 1);
}

var uptimePct = dataDays > 0 ? (((dataDays - downDays) / dataDays) * 100).toFixed(2) : "100.00";
head.appendChild(el("span", "status-uptime", uptimePct + "% uptime"));

row.appendChild(head);
row.appendChild(bar);
return row;
}

function init(sites, issuesBySlug, startBySlug) {
var today = toDateOnly(new Date());
var windowEnd = today;

function render() {
var windowStart = addDays(windowEnd, -(WINDOW_DAYS - 1));
root.innerHTML = "";
sites.forEach(function (site) {
var events = issuesBySlug[site.slug] || [];
var siteStart = startBySlug[site.slug] || null;
root.appendChild(renderRow(site, events, siteStart, windowStart, windowEnd));
});
rangeLabel.textContent = formatRange(windowStart, windowEnd);

var earliestStart = sites.reduce(function (min, site) {
var s = startBySlug[site.slug];
if (!s) return min;
return !min || s < min ? s : min;
}, null);
prevBtn.disabled = !!earliestStart && windowStart <= earliestStart;
nextBtn.disabled = windowEnd >= today;
}

prevBtn.addEventListener("click", function () {
windowEnd = addDays(windowEnd, -WINDOW_DAYS);
render();
});
nextBtn.addEventListener("click", function () {
windowEnd = addDays(windowEnd, WINDOW_DAYS);
if (windowEnd > today) windowEnd = today;
render();
});

render();
}

fetchJson(RAW_BASE + "summary.json")
.then(function (sites) {
var startBySlug = {};
var startFetches = sites.map(function (site) {
return fetch(RAW_BASE + site.slug + ".yml")
.then(function (res) {
return res.ok ? res.text() : "";
})
.then(function (text) {
var m = text.match(/startTime:\s*([^\n]+)/);
if (m) startBySlug[site.slug] = toDateOnly(new Date(m[1].trim()));
})
.catch(function () {});
});

var issuesBySlug = {};
var issuesFetch = fetchJson(ISSUES_URL)
.then(function (issues) {
var events = issues.map(classifyIssue).filter(Boolean);
// Single-monitor setup: attribute all events to every site.
sites.forEach(function (site) {
issuesBySlug[site.slug] = events;
});
})
.catch(function () {
// Rate-limited or offline — fall back to an all-green bar.
sites.forEach(function (site) {
issuesBySlug[site.slug] = [];
});
});

return Promise.all(startFetches.concat([issuesFetch])).then(function () {
init(sites, issuesBySlug, startBySlug);
});
})
.catch(function () {
root.innerHTML = "";
root.appendChild(el("p", "status-error", "Status data is unavailable right now."));
rangeLabel.textContent = "";
prevBtn.disabled = true;
nextBtn.disabled = true;
});
})();
Loading