/home/techb158/trellopowerup.abdallabala.com/public
Edit: /home/techb158/trellopowerup.abdallabala.com/public/powerup.js (4185B)
const BASE_URL = window.COSMIC_API_BASE || window.location.origin;
const ICON_DARK = `${BASE_URL}/assets/icon-white.svg`;
const ICON_LIGHT = `${BASE_URL}/assets/icon-black.svg`;
const APP_KEY = window.COSMIC_TRELLO_API_KEY || 'replace_with_power_up_api_key';
const APP_NAME = window.COSMIC_APP_NAME || 'COSMIC AI-Risk Management';
function riskColor(status) {
return {
low: 'green',
medium: 'yellow',
high: 'orange',
critical: 'red'
}[status] || 'light-gray';
}
function readRisk(t) {
return t.get('card', 'shared', 'cosmicRisk').then((risk) => risk || null);
}
async function readLatestAssessment(t) {
const card = await t.card('id');
const board = await t.board('id');
const response = await fetch(`${BASE_URL}/api/boards/${board.id}/cards/${card.id}/assessments/latest`);
if (!response.ok) return null;
const data = await response.json();
return data.assessment || null;
}
async function readRiskContext(t) {
const [risk, assessment] = await Promise.all([
readRisk(t),
readLatestAssessment(t).catch(() => null)
]);
return {
risk: assessment?.score || risk,
assessment
};
}
function reviewNeeded(assessment) {
return assessment?.review?.needed === true;
}
function reviewText(assessment) {
return assessment?.review?.reasons?.join('; ') || 'Review needed';
}
function openRiskForm(t) {
return t.modal({
title: 'COSMIC Risk Assessment',
url: t.signUrl(`${BASE_URL}/risk-modal.html`),
height: 720,
fullscreen: false
});
}
function openDashboard(t) {
return t.modal({
title: 'COSMIC AI-Risk Dashboard',
url: t.signUrl(`${BASE_URL}/board-dashboard.html`),
fullscreen: true
});
}
function openSettings(t) {
return t.popup({
title: 'COSMIC Settings',
url: t.signUrl(`${BASE_URL}/settings.html`),
height: 380
});
}
window.TrelloPowerUp.initialize({
'authorization-status': function (t) {
return t.getRestApi().isAuthorized().then((authorized) => ({ authorized }));
},
'show-authorization': function (t) {
return t.popup({ title: 'Authorize COSMIC Risk', url: t.signUrl(`${BASE_URL}/authorize.html`), height: 220 });
},
'show-settings': function (t) {
return openSettings(t);
},
'board-buttons': function () {
return [{
icon: { dark: ICON_DARK, light: ICON_LIGHT },
text: 'COSMIC Risk',
condition: 'always',
callback: openDashboard
}];
},
'card-buttons': function () {
return [{
icon: ICON_LIGHT,
text: 'Assess AI Risk',
condition: 'edit',
callback: openRiskForm
}];
},
'card-badges': function (t) {
return readRiskContext(t).then(({ risk, assessment }) => {
if (!risk) return [];
const badges = [{
text: `Risk ${risk.score}/100`,
color: riskColor(risk.status),
refresh: 30
}];
if (reviewNeeded(assessment)) {
badges.push({
text: 'Review needed',
color: 'red',
refresh: 30
});
}
return badges;
});
},
'card-detail-badges': function (t) {
return readRiskContext(t).then(({ risk, assessment }) => {
if (!risk) return [];
const badges = [{
title: 'COSMIC Risk',
text: `${risk.status.toUpperCase()} ${risk.score}/100`,
color: riskColor(risk.status),
callback: openRiskForm,
refresh: 30
}, {
title: 'Deployment Gate',
text: risk.gate?.deploymentReady ? 'Ready' : 'Blocked',
color: risk.gate?.deploymentReady ? 'green' : 'red',
callback: openRiskForm,
refresh: 30
}];
if (reviewNeeded(assessment)) {
badges.push({
title: 'COSMIC Review',
text: reviewText(assessment),
color: 'red',
callback: openRiskForm,
refresh: 30
});
}
return badges;
});
},
'card-back-section': function (t) {
return {
title: 'COSMIC AI-Risk Assessment',
icon: ICON_LIGHT,
content: {
type: 'iframe',
url: t.signUrl(`${BASE_URL}/card-section.html`),
height: 420
}
};
}
}, {
appKey: APP_KEY,
appName: APP_NAME
});