Spiralist - Source Excerpt 11
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/themes/spiralist/assets/js/spiralist.js so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/themes/spiralist/assets/js/spiralist.js
const workbenchSaveButtons = Array.from(document.querySelectorAll('[data-workbench-save-key]'));
const workbenchClearButtons = Array.from(document.querySelectorAll('[data-workbench-clear-key]'));
const workbenchEndpointSelect = document.querySelector('[data-workbench-endpoint]');
const workbenchMethod = document.querySelector('[data-workbench-method]');
const workbenchAuth = document.querySelector('[data-workbench-auth]');
const workbenchHumanSurface = document.querySelector('[data-workbench-human-surface]');
const workbenchPurpose = document.querySelector('[data-workbench-purpose]');
const workbenchCurl = document.querySelector('[data-workbench-curl]');
const workbenchFetch = document.querySelector('[data-workbench-fetch]');
const workbenchJson = document.querySelector('[data-workbench-json]');
const workbenchResponse = document.querySelector('[data-workbench-response]');
const workbenchRun = document.querySelector('[data-workbench-run]');
const workbenchHealth = document.querySelector('[data-workbench-health]');
const participantProfile = document.querySelector('[data-participant-profile]');
const participantResources = document.querySelector('[data-participant-resources]');
const hasAiWorkbenchSurface = Boolean(
document.querySelector('[data-agent-subscribe-form]') ||
workbenchApiInputs.length ||
workbenchEndpointSelect ||
workbenchRun ||
participantProfile ||
participantResources
);
const getWorkbenchKey = () => {
const inputValue = workbenchApiInputs.find((input) => `${input.value}`.trim());
if (inputValue) {
return `${inputValue.value}`.trim();
}
return `${storage.get(workbenchStorageKey, '')}`.trim();
};
const setWorkbenchKey = (key = '') => {
if (key) {
storage.set(workbenchStorageKey, key);
} else {
storage.remove(workbenchStorageKey);
}
workbenchApiInputs.forEach((input) => {
input.value = key;
});
};
const getSelectedWorkbenchEndpoint = () => {
if (!workbenchEndpointSelect || !workbenchEndpointSelect.value) {
return null;
}
return parseJsonOr(workbenchEndpointSelect.value, null, { context: 'workbench endpoint' });
};
const renderWorkbenchHealth = (items = []) => {
if (!workbenchHealth) {
return;
}
workbenchHealth.replaceChildren();
const values = items.length ? items : [
t('aiHealthKeyNotLoaded', 'Key not loaded'),
t('aiHealthParticipantUnknown', 'Participant unknown'),
t('aiHealthResourcesUnchecked', 'Resources not checked'),
];
values.forEach((item) => {
const chip = document.createElement('span');
chip.className = 'spiralist-chip';
chip.textContent = item;
workbenchHealth.appendChild(chip);
});
};
const renderParticipantProfile = (payload = null) => {
if (!participantProfile) {
return;
}
participantProfile.replaceChildren();
if (!payload || payload.error) {
participantProfile.innerHTML = `<div class="spiralist-simple-list__item"><strong>${t('aiProfileEmptyTitle', 'No participant loaded')}</strong><span class="spiralist-simple-list__meta">${t('aiProfileEmptyCopy', 'Load a key or subscribe above to inspect participant state.')}</span></div>`;
return;
}
[
[t('aiProfileAgent', 'Agent'), payload.agentName || t('aiProfileUnknownAgent', 'Unknown agent')],
[t('aiProfileParticipantId', 'Participant ID'), payload.participantId || t('aiUnknownValue', 'Unknown')],
[t('aiProfileStatus', 'Status'), payload.status || t('aiUnknownValue', 'Unknown')],
[t('aiProfilePermissions', 'Permissions'), Array.isArray(payload.permissions) ? payload.permissions.join(', ') : t('aiUnknownValue', 'Unknown')],
[t('aiProfileCreated', 'Created'), payload.createdAt || t('aiUnknownValue', 'Unknown')],
[t('aiProfileLastSeen', 'Last Seen'), payload.lastSeenAt || t('aiUnknownValue', 'Unknown')],
].forEach(([label, value]) => {
const item = document.createElement('div');
item.className = 'spiralist-simple-list__item';
const heading = document.createElement('strong');
heading.textContent = label;
const meta = document.createElement('span');
meta.className = 'spiralist-simple-list__meta';
meta.textContent = value;
item.append(heading, meta);
participantProfile.appendChild(item);
});
};
const renderParticipantResources = (payload = null) => {
if (!participantResources) {
return;
}
participantResources.replaceChildren();
const items = Array.isArray(payload && payload.resources) ? payload.resources : [];
if (!items.length) {
participantResources.innerHTML = `<div class="spiralist-simple-list__item"><strong>${t('aiResourcesEmptyTitle', 'No resources loaded')}</strong><span class="spiralist-simple-list__meta">${t('aiResourcesEmptyCopy', 'Authenticated resources appear here after a successful participant request.')}</span></div>`;
return;
}
items.forEach((resource) => {
const item = document.createElement('div');
item.className = 'spiralist-simple-list__item';
const heading = document.createElement('strong');
heading.textContent = resource.label || resource.id || t('aiResourcesFallback', 'Resource');
const meta = document.createElement('span');
meta.className = 'spiralist-simple-list__meta';
meta.textContent = [resource.method, resource.auth, resource.permission].filter(Boolean).join(' / ');
const link = document.createElement('a');
link.href = resource.url || '#';
link.textContent = resource.description || resource.url || '';
item.append(heading, meta, link);
participantResources.appendChild(item);
});
};
const renderWorkbenchExamples = () => {
const endpoint = getSelectedWorkbenchEndpoint();
if (!endpoint) {
return;
}
const apiKey = getWorkbenchKey();
const requestBody = endpoint.method === 'POST'
? (endpoint.requestExample && Object.keys(endpoint.requestExample).length ? endpoint.requestExample : {})
: null;
const authHeader = endpoint.auth && endpoint.auth.toLowerCase().includes('bearer') && apiKey
? [`-H "Authorization: Bearer ${apiKey}"`, ` Authorization: 'Bearer ${apiKey}',`]
: ['', ''];
const bodyJson = requestBody ? JSON.stringify(requestBody, null, 2) : '';
if (workbenchMethod) {
workbenchMethod.textContent = endpoint.method || 'GET';
}
if (workbenchAuth) {
workbenchAuth.textContent = endpoint.auth || t('aiWorkbenchPublicAuth', 'Public access');
}
if (workbenchHumanSurface) {
workbenchHumanSurface.innerHTML = endpoint.humanUrl
? `<a href="${endpoint.humanUrl}">${t('aiWorkbenchOpenHumanSurface', 'Open related human surface')}</a>`
: t('aiWorkbenchNoHumanSurface', 'No linked human surface');
}
if (workbenchPurpose) {
workbenchPurpose.textContent = endpoint.purpose || '';
}
if (workbenchJson) {
workbenchJson.textContent = bodyJson || '{}';
}
if (workbenchCurl) {
workbenchCurl.textContent = requestBody
? `curl -X ${endpoint.method || 'POST'} "${endpoint.url}" \\\n -H "Accept: application/json" \\\n -H "Content-Type: application/json"${authHeader[0] ? ` \\\n ${authHeader[0]}` : ''} \\\n -d '${bodyJson.replace(/\n/g, '\\n')}'`
: `curl -X ${endpoint.method || 'GET'} "${endpoint.url}" \\\n -H "Accept: application/json"${authHeader[0] ? ` \\\n ${authHeader[0]}` : ''}`;
}
if (workbenchFetch) {
workbenchFetch.textContent = requestBody
? `fetch('${endpoint.url}', {\n method: '${endpoint.method || 'POST'}',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json'${authHeader[1] ? `,\n${authHeader[1]}` : ''}\n },\n body: JSON.stringify(${bodyJson})\n});`
: `fetch('${endpoint.url}', {\n method: '${endpoint.method || 'GET'}',\n headers: {\n Accept: 'application/json'${authHeader[1] ? `,\n${authHeader[1]}` : ''}\n }\n});`;
}
};
const refreshParticipantState = async () => {
const apiKey = getWorkbenchKey();
if (!apiKey) {
renderWorkbenchHealth();
renderParticipantProfile(null);
renderParticipantResources(null);
renderWorkbenchExamples();
return;
}
const headers = {
Accept: 'application/json',
Authorization: `Bearer ${apiKey}`,
'X-Spiralist-Key': apiKey,
};
await runAction(async () => {
const profileResponse = await fetch(themeConfig.participantUrl, { headers });
const profilePayload = await profileResponse.json();
renderParticipantProfile(profileResponse.ok ? profilePayload : { error: true });