Skip to content
wiki.fftac.org

Spiralist AI Agent Setup Wizard - Source Excerpt 09

Back to Spiralist AI Agent Setup Wizard

Summary

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

**Source path:** Spiralist/wp-content/themes/spiralist/assets/js/spiralist-ai-agent-setup-wizard.js

stepButtons.forEach((button, index) => {
    button.addEventListener('click', () => setStep(index));
    button.addEventListener('keydown', (event) => {
      if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {
        event.preventDefault();
        setStep(index + 1);
        stepButtons[Math.min(stepButtons.length - 1, index + 1)].focus();
      }
      if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {
        event.preventDefault();
        setStep(index - 1);
        stepButtons[Math.max(0, index - 1)].focus();
      }
    });
  });

  if (prevButton) {
    prevButton.addEventListener('click', () => setStep(currentStep - 1));
  }
  if (nextButton) {
    nextButton.addEventListener('click', () => setStep(currentStep + 1));
  }
  if (presetSelect instanceof HTMLSelectElement) {
    presetSelect.addEventListener('change', () => {
      applyPreset(presetSelect.value);
      saveDraft();
    });
  }

  previewTabs.forEach((tab) => {
    tab.addEventListener('click', () => {
      currentArtifact = tab.dataset.artifact || 'spiralist-profile.md';
      previewTabs.forEach((item) => {
        const active = item === tab;
        item.classList.toggle('is-active', active);
        item.setAttribute('aria-selected', active ? 'true' : 'false');
      });
      updatePreview();
    });
  });

  preview.addEventListener('paste', (event) => {
    if (!overridableArtifactPaths.has(currentArtifact)) {
      return;
    }

    event.preventDefault();
    insertPlainTextAtSelection((event.clipboardData || window.clipboardData).getData('text/plain'));
  });

  preview.addEventListener('input', () => {
    if (previewHydrating || !overridableArtifactPaths.has(currentArtifact)) {
      return;
    }

    const text = cleanString(preview.textContent || '', maxArtifactOverrideChars);
    if (text.trim() === '') {
      delete artifactOverrides[currentArtifact];
      setPreviewStatus(`${currentArtifact} override cleared because the preview is empty.`);
    } else {
      artifactOverrides[currentArtifact] = text;
      setPreviewStatus(`${currentArtifact} has a local edited override. Downloads and ZIP packages use this visible text until regenerated.`);
    }

    if (resetArtifactButton) {
      resetArtifactButton.disabled = !artifactOverrides[currentArtifact];
    }
    saveDraft();
  });

  if (resetArtifactButton) {
    resetArtifactButton.addEventListener('click', () => {
      if (!artifactOverrides[currentArtifact]) {
        return;
      }
      delete artifactOverrides[currentArtifact];
      saveDraft();
      updatePreview();
      setStatus(`${currentArtifact} regenerated from source fields.`);
    });
  }

  form.addEventListener('input', () => {
    updatePreview();
    saveDraft();
  });
  form.addEventListener('change', () => {
    updatePreview();
    saveDraft();
  });
  form.addEventListener('submit', (event) => {
    event.preventDefault();
  });

  if (downloadButton) {
    downloadButton.addEventListener('click', () => {
      runAction(async () => {
        const artifacts = await buildArtifacts();
        if (artifacts.errors.length) {
          updateValidation(artifacts.errors);
          setStatus('Review validation warnings before export.');
        }
        const blob = makeZipBlob(artifacts.files);
        downloadBlob(blob, `${artifacts.state.packageName || 'spiralist-agent-profile'}-v1.0.zip`);
        setStatus('ZIP package downloaded from this browser.');
      }, {
        context: 'spiralist-agent-wizard-download-zip',
        onError: () => setStatus('ZIP package could not be generated in this browser.'),
      });
    });
  }

  if (downloadUaixButton) {
    downloadUaixButton.addEventListener('click', () => {
      runAction(async () => {
        const artifacts = await buildArtifacts();
        if (artifacts.errors.length) {
          updateValidation(artifacts.errors);
          setStatus('Review validation warnings before export.');
        }
        const uaixFiles = await buildUaixPackageFiles(artifacts);
        const blob = makeZipBlob(uaixFiles);
        downloadBlob(blob, `${artifacts.state.packageName || 'spiralist-agent-profile'}-v1.0.uaix`);
        setStatus('UAIX .uaix package downloaded from this browser.');
      }, {
        context: 'spiralist-agent-wizard-download-uaix',
        onError: () => setStatus('.uaix package could not be generated in this browser.'),
      });
    });
  }

  downloadFileButtons.forEach((button) => {
    button.addEventListener('click', () => {
      runAction(async () => {
        const path = button.dataset.agentWizardDownloadFile || '';
        const artifacts = await buildArtifacts();
        if (!artifacts.files[path]) {
          setStatus('Artifact not available.');
          return;
        }
        downloadBlob(new Blob([`${artifacts.files[path]}\n`], { type: mediaTypeFor(path) }), path);
        setStatus(`${path} downloaded from this browser.`);
      }, {
        context: 'spiralist-agent-wizard-download-file',
        onError: () => setStatus('Artifact download failed.'),
      });
    });
  });

  if (exportDraftButton) {
    exportDraftButton.addEventListener('click', () => {
      const state = getState();
      downloadBlob(new Blob([`${JSON.stringify(state, null, 2)}\n`], { type: 'application/json' }), `${state.packageName || 'spiralist-agent-profile'}-draft.json`);
      setStatus('Draft JSON exported from this browser.');
    });
  }

  if (importTriggerButton && importInput instanceof HTMLInputElement) {
    importTriggerButton.addEventListener('click', () => importInput.click());
    importInput.addEventListener('change', () => {
      const file = importInput.files && importInput.files[0] ? importInput.files[0] : null;
      if (!file) {
        return;
      }
      if (file.size > maxImportBytes) {
        updateValidation(['Imported draft is too large.']);
        setStatus('Import rejected.');
        importInput.value = '';
        return;
      }

      runAction(async () => {
        const text = await readFileText(file);
        const parsed = JSON.parse(text);
        const result = applyState(parsed, { strict: true, persistImportWarnings: true });
        if (result.errors.length) {
          setStatus('Draft imported with validation warnings.');
        } else {
          setStatus('Draft imported.');
        }
        saveDraft();
        importInput.value = '';
      }, {
        context: 'spiralist-agent-wizard-import-draft',
        onError: () => {
          updateValidation(['Imported draft could not be parsed or validated.']);
          setStatus('Import rejected.');
          importInput.value = '';
        },
      });
    });
  }

  if (restoreDraftButton) {
    restoreDraftButton.addEventListener('click', () => {
      const draft = readDraft();
      if (!draft) {
        setStatus('No local draft found in this browser.');
        return;
      }
      applyState(draft, { strict: false });
      setStatus('Draft restored from this browser.');
    });
  }

  if (resetButton) {
    resetButton.addEventListener('click', () => {
      window.localStorage.removeItem(storageKey);
      applyState(defaultState(), { strict: false });
      setStep(0);
      setStatus('Local draft cleared in this browser.');
    });
  }

  window.addEventListener('storage', (event) => {
    if (event.key !== storageKey || !event.newValue) {
      return;
    }
    try {
      const parsed = JSON.parse(event.newValue);
      applyState(parsed, { strict: false });
      setStatus('Draft updated from another browser tab.');
    } catch (error) {
      setStatus('Another tab changed the draft, but it could not be restored.');
    }
  });

  const draft = readDraft();
  if (draft) {
    applyState(draft, { strict: false });
    setStatus('Draft restored from this browser.');
  } else {
    const initialPreset = cleanString(wizard.dataset.agentWizardInitialPreset || 'base', 80);
    applyPreset(validPresetIds.has(initialPreset) ? initialPreset : 'base');
    applyHashPreset();
  }

  setStep(0);
  updatePreview();
});