// Allowlisted display fields and scalar aggregates, never session identities or path/runtime objects.
function projectMetadata(status, access, users) {
if (!status || status.isMate || !access || access.error) return null;
var owner = access.ownerId && users.findUserById(access.ownerId);
return {
slug: status.slug,
project: status.title || status.project || status.slug,
title: status.title || status.project || status.slug,
projectOwnerId: owner ? owner.id : null,
ownerName: owner ? (owner.displayName || owner.username) : "Ownership needs recovery",
visibility: access.visibility,
contentAccess: false,
administrativeAccess: true,
ownershipRecovery: access.ownershipRecovery === "required" || !owner,
runtimeHealth: "Registered",
icon: typeof status.icon === 'string' ? status.icon : null,
isWorktree: status.isWorktree === true,
parentSlug: status.isWorktree === true && typeof status.parentSlug === 'string' ? status.parentSlug : null,
sessions: Number.isSafeInteger(status.sessions) && status.sessions >= 0 ? status.sessions : null,
clients: Number.isSafeInteger(status.clients) && status.clients >= 0 ? status.clients : null,
isProcessing: typeof status.isProcessing === 'boolean' ? status.isProcessing : null,
};
}
function metadataFor(user, status, access, users) {
if (!user || !users.findUserById(user.id) || user.role !== "admin" || !status || status.isMate || /^mate-/.test(status.slug)) return null;
return projectMetadata(status, access, users);
}
function escape(value) {
return String(value || "").replace(/[&<>"']/g, function (character) {
return { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[character];
});
}
function page(metadata, projects) {
var privacyText = metadata.ownershipRecovery
? "Content remains restricted because no verified owner is available. Ask the server operator to verify the account’s OS UID and real home/project mapping, then use the Access recovery check."
: "Conversations, files and terminals are private. Ask the owner to share project access.";
var accessText = metadata.ownershipRecovery
? "Ownership needs recovery. The server operator must independently verify or repair the authoritative account-to-OS mapping before ownership repair can succeed. Use the recovery checks below; ambiguous records stay restricted."
: "Only the project owner can change ownership, visibility and sharing. Administrator status does not grant access to private content.";
var navigation = projects.filter(function (project) { return !project.isMate; }).map(function (project) {
return { slug: project.slug, title: project.title || project.project || project.slug, icon: typeof project.icon === 'string' ? project.icon : null,
isWorktree: project.isWorktree === true, parentSlug: project.parentSlug || null, contentAccess: project.contentAccess !== false };
});
var payload = JSON.stringify({ project: metadata, projects: navigation }).replace(/
' + escape(label) + ' ' + escape(value === null ? 'Unavailable' : String(value)) + ' '; }
return '' + escape(metadata.title) + ' · Clay ' +
' ' +
'' +
'
' +
'
Project overview
' + escape(metadata.title) + '
Content restricted ' +
'
Overview Access
' +
'
' + fact('Owner', metadata.ownerName) + fact('Visibility', metadata.visibility) + fact('Registration', metadata.runtimeHealth) + fact('Sessions', metadata.sessions) + fact('Connected clients', metadata.clients) + fact('Agent activity', metadata.isProcessing === null ? null : metadata.isProcessing ? 'Active turn reported' : 'No active turn reported') + ' Session and activity counts reflect this page load.
' +
'
Storage Refresh usage
Project allocated —
Files —
Volume available —
Volume capacity — Measuring storage…
Allocated filesystem blocks, including dependencies. Nested registered projects are counted separately; hard links shared across projects are excluded. Volume space is shared, not a project quota.
' +
'Administrative metadata only ' + escape(privacyText) + '
' +
'
Administrative metadata only ' + escape(accessText) + '
' + fact('Owner', metadata.ownerName) + fact('Your access', 'Administrative metadata only') + ' ' +
'';
}
module.exports = { metadataFor: metadataFor, page: page };