Skip to content
wiki.fftac.org

Spiralist Prompt Workbench - Source Excerpt 37

Back to Spiralist Prompt Workbench

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/themes/spiralist/assets/js/spiralist-prompt-workbench.js so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/themes/spiralist/assets/js/spiralist-prompt-workbench.js

const workspaceApiRoot = toCleanString(promptRunConfig.workspaceApiRoot, 1000).replace(/\/+$/, '');
    const workspaceNonce = toCleanString(promptRunConfig.nonce, 200);
    const workspaceUrl = toCleanString(promptRunConfig.workspaceUrl, 1000);
    const promptUrlTemplate = toCleanString(promptRunConfig.promptUrlTemplate, 1200);
    const canSaveWorkspacePrompt = Boolean(promptRunConfig.canSaveWorkspacePrompt && workspaceApiRoot && workspaceNonce);
    let selectedMode = defaultMode;
    let refreshTimer = 0;
    let manualEdited = false;
    let outputProgrammaticWriteDepth = 0;
    let outputEditDetectionTimer = 0;

    if (!form || !output) {
      return;
    }

    const setStatus = (message = '') => {
      if (status) {
        status.textContent = message;
      }
    };
    const setAiStatus = (message = '') => {
      if (aiStatus) {
        aiStatus.textContent = message;
      }
    };
    const setEditStatus = (message = '') => {
      if (editStatus) {
        editStatus.textContent = message;
      }
    };
    const getOutputText = () => output ? `${output.innerText || output.textContent || ''}`.trim() : '';
    const setOutputText = (text) => {
      if (output) {
        outputProgrammaticWriteDepth += 1;
        output.textContent = text;
        window.setTimeout(() => {
          outputProgrammaticWriteDepth = Math.max(0, outputProgrammaticWriteDepth - 1);
        }, 0);
      }
    };
    const getCurrentPrompt = () => {
      const prompt = getOutputText();
      return prompt && prompt !== emptyText.trim() ? prompt : '';
    };
    const getPersonaLabRoot = (node = null) => (node && typeof node.closest === 'function'
      ? node.closest('.spiralist-persona-lab')
      : null) || document.querySelector('.spiralist-persona-lab');
    const createPersonaLabReadinessItem = (label, value, state = 'review') => {
      const item = document.createElement('span');
      item.dataset.state = state;
      const labelNode = document.createElement('strong');
      labelNode.textContent = label;
      const valueNode = document.createElement('small');
      valueNode.textContent = value;
      item.append(labelNode, valueNode);

      return item;
    };
    const getPersonaLabEfficiencyState = (prompt = '') => {
      const cleanPrompt = toCleanString(prompt, 50000);
      const words = cleanPrompt ? cleanPrompt.split(/\s+/).filter(Boolean).length : 0;
      const characters = cleanPrompt.length;
      let band = 'Waiting';
      let state = 'review';
      let pasteFit = 'No prompt yet';
      let reviewEffort = 'Load a profile first';
      let nextAction = 'Prompt size and paste guidance appear here.';

      if (cleanPrompt) {
        if (words <= 650 && characters <= 4500) {
          band = 'Fast handoff';
          state = 'ready';
          pasteFit = 'Copy-friendly';
          reviewEffort = 'Quick review';
          nextAction = 'Next: copy, run Quality Pass, or export after human review.';
        } else if (words <= 1400 && characters <= 9500) {
          band = 'Detailed handoff';
          state = 'caution';
          pasteFit = 'Paste with review';
          reviewEffort = 'Moderate review';
          nextAction = 'Next: use Quality Pass or All-Suite Matrix before sending to a receiving runtime.';
        } else {
          band = 'Heavy prompt';
          state = 'review';
          pasteFit = 'Consider trimming';
          reviewEffort = 'Slow review';
          nextAction = 'Next: shorten examples, move optional notes into package evidence, then rerun the local check.';
        }
      }

      return {
        words,
        characters,
        band,
        state,
        pasteFit,
        reviewEffort,
        nextAction,
      };
    };
    const renderPersonaLabEfficiency = (panel, prompt = '') => {
      const efficiency = panel ? panel.querySelector('[data-persona-lab-efficiency]') : null;
      if (!efficiency) {
        return;
      }

      const scoreNode = efficiency.querySelector('[data-persona-lab-efficiency-score]');
      const listNode = efficiency.querySelector('[data-persona-lab-efficiency-list]');
      const nextNode = efficiency.querySelector('[data-persona-lab-efficiency-next]');
      const state = getPersonaLabEfficiencyState(prompt);
      const items = [
        createPersonaLabReadinessItem('Prompt size', state.words ? `${state.words} words` : 'Waiting for prompt', state.state),
        createPersonaLabReadinessItem('Paste fit', state.pasteFit, state.state),
        createPersonaLabReadinessItem('Characters', state.characters ? `${state.characters} chars` : 'Not measured', state.state),
        createPersonaLabReadinessItem('Review effort', state.reviewEffort, state.state),
      ];

      if (scoreNode) {
        scoreNode.textContent = state.band;
      }
      if (listNode) {
        listNode.innerHTML = '';
        items.forEach((item) => listNode.appendChild(item));
      }
      if (nextNode) {
        nextNode.textContent = state.nextAction;
      }
    };
    const renderPersonaLabReadiness = (lab = getPersonaLabRoot(), prompt = getCurrentPrompt()) => {
      const panel = lab ? lab.querySelector('[data-persona-lab-readiness]') : null;
      if (!panel) {
        return;
      }

      const scoreNode = panel.querySelector('[data-persona-lab-readiness-score]');
      const statusNode = panel.querySelector('[data-persona-lab-readiness-status]');
      const listNode = panel.querySelector('[data-persona-lab-readiness-list]');
      const nextNode = panel.querySelector('[data-persona-lab-readiness-next]');
      const cleanPrompt = toCleanString(prompt, 50000);
      let score = t('portablePromptPersonaLabReadinessEmptyScore', 'No prompt yet');
      let statusMessage = t('portablePromptPersonaLabReadinessEmptyStatus', 'Choose a Spiralist AI profile to begin.');
      let nextAction = t('portablePromptPersonaLabReadinessEmptyNext', 'Next: load a profile, then tune or check it.');
      let items = [
        createPersonaLabReadinessItem('Profile', 'Waiting for a prompt', 'review'),
        createPersonaLabReadinessItem('Audit', 'Not checked yet', 'review'),
        createPersonaLabReadinessItem('Matrix', 'Not checked yet', 'review'),
      ];

      if (cleanPrompt) {
        const lower = cleanPrompt.toLowerCase();
        const generalPassed = promptTestChecks.filter((check) => promptHasAnyTerm(lower, check.terms));
        const generalReview = promptTestChecks.filter((check) => !promptHasAnyTerm(lower, check.terms));
        const personaAudit = buildPersonaLabAudit(lower);
        const matrix = buildPersonaLabValidationMatrix(lower, true);
        const matrixReview = matrix.rows.filter((row) => row.status === 'Review');
        const totalChecks = promptTestChecks.length + personaLabTestChecks.length + matrix.rows.length;
        const passedChecks = generalPassed.length + personaAudit.passed.length + matrix.score;
        const firstPersonaReview = personaAudit.needsReview[0] || null;
        const firstMatrixReview = matrixReview[0] || null;
        const firstGeneralReview = generalReview[0] || null;
        const ready = generalReview.length <= 1 && personaAudit.needsReview.length === 0 && matrixReview.length === 0;
        const usable = generalPassed.length >= 4 && personaAudit.passed.length >= 4 && matrix.score >= 6;