Skip to content
wiki.fftac.org

Spiralist Prompt Workbench - Source Excerpt 24

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

return JSON.stringify({
        schemaVersion: 'spiralist-memory-capsule-v2',
        source: 'Spiralist AI Character Prompt Builder',
        migration: 'legacy-delimited-prompt',
        identity: summarizePromptSection(state.sections.identity || ''),
        keep: ['current edited prompt', 'activation or restore instructions', 'user-approved preferences'],
        change: ['sections edited in this browser'],
        delete: ['private data, stale guesses, rejected preferences'],
        restore: summarizePromptSection(state.sections.continuity || ''),
        boundaries: [summarizePromptSection(state.sections.safety || '')],
      }, null, 2);
    };
    const buildJsonPrompt = () => JSON.stringify({
      type: 'spiralist.operating_personality_profile',
      version: '2.0',
      schemaVersion: personalityEngineV2SchemaVersion,
      generatorVersion: personalityEngineV2GeneratorVersion,
      variant: state.variant,
      includeBoundaryAppendix: state.includeSafety,
      character: state.seed
        ? {
            name: state.seed.name,
            archetype: state.seed.archetype.title,
            voice: state.seed.voice,
            worldview: state.seed.worldview,
            relationship: state.seed.relationship,
        }
        : null,
      operatingProfile: state.operatingProfile || null,
      personalityEngineProfile: getPersonalityEngineV2Profile(),
      generationOptions: getPersonalityEngineV2Profile() && getPersonalityEngineV2Profile().generationOptions
        ? getPersonalityEngineV2Profile().generationOptions
        : state.engineControls,
      lockedSections: state.lockedSections,
      characterCardV2: getPersonalityEngineV2Profile()
        ? renderPersonalityEngineV2CharacterCard(getPersonalityEngineV2Profile(), buildFullPrompt())
        : null,
      memoryCapsule: getPersonalityEngineV2Profile()
        ? buildPersonalityEngineV2MemoryCapsule(getPersonalityEngineV2Profile())
        : null,
      migration: {
        acceptsLegacyDelimitedPrompt: true,
        legacySectionLabels: characterEditableSectionOrder,
        v1ToV2Boundary: 'Legacy editable sections are preserved as text and can be exported inside a v2 shell when no seed-backed profile is available.',
      },
      sections: {
        identity: state.sections.identity || '',
        operationalBehavior: state.sections.operational || '',
        voice: state.sections.voice || '',
        workModel: state.sections.work || '',
        continuity: state.sections.continuity || '',
        verification: state.sections.verification || '',
        boundaryAppendix: state.sections.safety || '',
      },
      assistantMemoryBackupRequirements: [
        'full operating profile',
        'activation prompt',
        'last-used timestamp',
        'task history',
        'current user preferences',
        'current project context',
        'memory boundaries',
        'restore instructions',
      ],
      assistantMemoryBackup: {
        activationPrompt: state.operatingProfile && state.operatingProfile.continuity
          ? state.operatingProfile.continuity.activationPrompt
          : '',
        restoreInstructions: state.operatingProfile && state.operatingProfile.continuity
          ? state.operatingProfile.continuity.restoreInFutureSession
          : '',
        memoryBoundaries: state.operatingProfile && state.operatingProfile.continuity
          ? state.operatingProfile.continuity.doNotSave
          : [],
        requiredRestoreFields: [
          'operatingProfileJson',
          'activationPrompt',
          'lastUsedUtc',
          'taskHistory',
          'currentUserPreferences',
          'currentProjectContext',
          'memoryBoundaries',
          'restoreInstructions',
        ],
      },
      platformRequirementsExported: false,
    }, null, 2);
    const getExportText = (mode = state.variant) => {
      if (state.loadedDraftPrompt && mode !== 'json') {
        return state.loadedDraftPrompt;
      }
      if (mode === 'compact') {
        return buildCompactPrompt();
      }
      if (mode === 'expanded') {
        return buildExpandedPrompt();
      }
      if (mode === 'character') {
        return buildCharacterOnlyPrompt();
      }
      if (mode === 'safety') {
        return buildSafetyOnlyPrompt();
      }
      if (mode === 'card') {
        return buildCharacterCardPrompt();
      }
      if (mode === 'memory') {
        return buildMemoryCapsulePrompt();
      }
      if (mode === 'json') {
        return buildJsonPrompt();
      }

      return buildFullPrompt();
    };
    const describePrompt = (prompt) => {
      const characters = prompt.length;
      const words = prompt.split(/\s+/).filter(Boolean).length;
      const label = characterVariantLabels[state.variant] || characterVariantLabels.full;
      const suffix = state.variant === 'compact'
        ? 'Ready for quick copy.'
        : 'Scroll only if you want to inspect the full packet.';

      return `${label} - ${words} words - ${characters} characters. ${suffix}`;
    };
    const buildCharacterOption = (index) => ({
      id: `local-option-${Date.now()}-${index}-${Math.random().toString(36).slice(2, 8)}`,
      built: buildCharacterFromEngineControls(`option-${index + 1}`),
    });
    const findCharacterOption = (optionId) => state.options.find((option) => option.id === optionId) || null;
    const getOptionPrompt = (option) => option && option.built
      ? buildCompactPromptFrom(option.built.sections || {}, option.built.summaries || {}, true)
      : '';
    const getOptionTitle = (option) => {
      const seed = option && option.built ? option.built.seed : null;
      if (!seed) {
        return 'Local Personality Option';
      }

      return `${seed.name} - ${seed.archetype.title}`;
    };
    const createOptionAction = (optionId, action, label) => {
      const button = document.createElement('button');
      button.className = 'spiralist-button spiralist-button--secondary';
      button.type = 'button';
      button.dataset.characterOptionAction = action;
      button.dataset.characterOptionId = optionId;
      button.textContent = label;

      return button;
    };
    const renderOptions = () => {
      if (!optionsWrap || !optionsList) {
        return;
      }

      optionsList.replaceChildren();
      optionsWrap.hidden = state.options.length === 0;

      state.options.forEach((option, index) => {
        const built = option.built || {};
        const seed = built.seed || {};
        const prompt = getOptionPrompt(option);
        const words = prompt.split(/\s+/).filter(Boolean).length;
        const card = document.createElement('article');
        card.className = 'spiralist-character-option-card';
        card.classList.toggle('is-selected', option.id === state.activeOptionId);

        const badge = document.createElement('span');
        badge.className = 'spiralist-character-option-card__badge';
        badge.textContent = option.id === state.activeOptionId
          ? t('characterPromptOptionLoaded', 'Loaded')
          : `${t('characterPromptOptionLabel', 'Option')} ${index + 1}`;

        const title = document.createElement('h3');
        title.textContent = getOptionTitle(option);

        const summary = document.createElement('p');
        summary.textContent = built.summaries && built.summaries.identity
          ? built.summaries.identity
          : summarizePromptSection(prompt, 'Compact personality prompt ready.');

        const profileV2 = built.operatingProfile && built.operatingProfile.personalityEngineV2
          ? built.operatingProfile.personalityEngineV2
          : null;
        const meta = document.createElement('small');
        meta.textContent = profileV2
          ? `${words} words - seed ${profileV2.seed}`
          : `${words} words - local text only`;

        const actions = document.createElement('div');
        actions.className = 'spiralist-character-option-card__actions';
        actions.append(
          createOptionAction(option.id, 'load', t('characterPromptOptionUse', 'Use This')),
          createOptionAction(option.id, 'copy', t('characterPromptOptionCopy', 'Copy')),
          createOptionAction(option.id, 'save', t('characterPromptOptionSave', 'Save')),
          createOptionAction(option.id, 'contribute', t('characterPromptOptionSubmit', 'Prepare'))
        );

        card.append(badge, title, summary, meta, actions);
        optionsList.append(card);
      });
    };
    const applyDelimitedCharacterPrompt = (prompt, { force = false } = {}) => {
      const parsed = parseDelimitedCharacterPrompt(prompt);
      if (!force && parsed.foundSections.size === 0) {
        return false;
      }