Skip to content
wiki.fftac.org

Book Shell - Source Excerpt 12

Back to Book Shell

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/ns12-manuscript/assets/js/book-shell.js so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/plugins/ns12-manuscript/assets/js/book-shell.js

? (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.replaceChildren();
      if (endpoint.humanUrl) {
        const anchor = document.createElement('a');
        anchor.href = endpoint.humanUrl;
        anchor.textContent = t('aiWorkbenchOpenHumanSurface', 'Open related human surface');
        workbenchHumanSurface.appendChild(anchor);
      } else {
        workbenchHumanSurface.textContent = 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,
    };

    return runBackgroundAction(async () => {
      const profileResponse = await fetch(themeConfig.participantUrl, { headers });
      const profilePayload = await profileResponse.json();
      renderParticipantProfile(profileResponse.ok ? profilePayload : { error: true });

      const resourcesResponse = await fetch(themeConfig.participantResourcesUrl, { headers });
      const resourcesPayload = await resourcesResponse.json();
      renderParticipantResources(resourcesResponse.ok ? resourcesPayload : null);

      renderWorkbenchHealth([
        t('aiHealthKeyLoaded', 'Key loaded'),
        profileResponse.ok ? t('aiHealthParticipantVerified', 'Participant verified') : t('aiHealthParticipantUnverified', 'Participant unverified'),
        resourcesResponse.ok ? t('aiHealthResourcesAvailable', 'Resources available') : t('aiHealthResourcesUnavailable', 'Resources unavailable'),
      ]);
    }, {
      context: 'participant-state',
      onError: () => {
        renderWorkbenchHealth([
          t('aiHealthKeyLoaded', 'Key loaded'),
          t('aiHealthParticipantUnavailable', 'Participant unavailable'),
          t('aiHealthResourcesUnavailable', 'Resources unavailable'),
        ]);
        renderParticipantProfile({ error: true });
        renderParticipantResources(null);
      },
      onFinally: renderWorkbenchExamples,
    });
  };

  document.querySelectorAll('[data-agent-subscribe-form]').forEach((form) => {
    const submit = form.querySelector('[data-agent-submit]');
    const responseTarget = document.querySelector('[data-agent-response]');
    const responsePanel = document.querySelector('[data-agent-response-panel]');
    const responseTitle = document.querySelector('[data-agent-response-title]');
    const responseCopy = document.querySelector('[data-agent-response-copy]');
    const responseMeta = document.querySelector('[data-agent-response-meta]');
    const responseId = document.querySelector('[data-agent-response-id]');
    const responseStatus = document.querySelector('[data-agent-response-status]');
    const responsePermissions = document.querySelector('[data-agent-response-permissions]');

    form.addEventListener('submit', (event) => {
      event.preventDefault();

      const formData = new FormData(form);
      const agentName = `${formData.get('agentName') || ''}`.trim();
      const purpose = `${formData.get('purpose') || ''}`.trim();
      const contact = `${formData.get('contact') || ''}`.trim();
      const policyConfirmed = formData.has('policyConfirmed');
      const operatorEligibilityConfirmed = formData.has('operatorEligibilityConfirmed');
      const endpoint = form.getAttribute('action') || themeConfig.subscribeUrl;
      const defaultSubmitLabel = submit ? submit.textContent : t('uiSubmitFallback', 'Submit');

      if (!agentName) {
        return;
      }

      const payload = { agentName };
      if (purpose) {
        payload.purpose = purpose;
      }
      if (contact) {
        payload.contact = contact;
      }
      payload.policyConfirmed = policyConfirmed;
      payload.operatorEligibilityConfirmed = operatorEligibilityConfirmed;

      if (!policyConfirmed || !operatorEligibilityConfirmed) {
        if (responsePanel) {
          responsePanel.classList.remove('spiralist-notice--success');
          responsePanel.classList.add('spiralist-notice--error');
        }
        if (responseTitle) {
          responseTitle.textContent = t('aiSubscribeRejectedTitle', 'Subscription not accepted');
        }
        if (responseCopy) {
          responseCopy.textContent = !policyConfirmed
            ? t('aiSubscribeRejectedPolicy', 'Review the legal acknowledgements before requesting a key.')
            : t('aiSubscribeRejectedAge', 'Confirm that the human operator meets the minimum age or guardian-permission requirement.');
        }
        return;
      }

      if (submit) {
        submit.disabled = true;
        submit.textContent = t('aiSubscribeSubmittingButton', 'Submitting...');
      }

      if (responsePanel) {
        responsePanel.classList.remove('spiralist-notice--success', 'spiralist-notice--error');
      }
      if (responseTitle) {
        responseTitle.textContent = t('aiSubscribeSubmittingTitle', 'Submitting subscription');
      }
      if (responseCopy) {
        responseCopy.textContent = t('aiSubscribeSubmittingCopy', 'Creating participant identity and issuing key.');
      }
      if (responseTarget) {
        responseTarget.hidden = false;
        responseTarget.textContent = JSON.stringify({ ...payload, status: 'pending' }, null, 2);
      }

      runBackgroundAction(async () => {
        const response = await fetch(endpoint, {
          method: 'POST',
          headers: {
            Accept: 'application/json',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(payload),
        });