Spiralist Prompt Workbench - Source Excerpt 85
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 range = selection.getRangeAt(0);
range.deleteContents();
range.insertNode(document.createTextNode(text));
selection.collapseToEnd();
};
const scheduleRefresh = () => {
window.clearTimeout(refreshTimer);
refreshTimer = window.setTimeout(() => {
buildPortablePrompt({ quiet: true });
}, 120);
};
const restoreSharedState = () => {
const params = new URLSearchParams(window.location.search);
const hasQueryState = ['mode', 'subject', 'task', 'goal', 'context', 'tone', 'format', 'guardrails', 'constraints'].some((key) => params.has(key));
const legacyHash = window.location.hash && window.location.hash.slice(1).startsWith('builder?')
? new URLSearchParams(window.location.hash.slice('builder?'.length + 1))
: null;
if (!hasQueryState && !legacyHash) {
return false;
}
selectMode(params.get('mode') || (legacyHash ? legacyHash.get('m') : '') || defaultMode);
setFieldValue('subject', params.get('subject') || (legacyHash ? legacyHash.get('s') : '') || '');
setFieldValue('task', params.get('task') || params.get('goal') || (legacyHash ? legacyHash.get('g') : '') || '');
setFieldValue('context', params.get('context') || (legacyHash ? legacyHash.get('c') : '') || '');
setFieldValue('tone', params.get('tone') || (legacyHash ? legacyHash.get('r') : '') || '');
setFieldValue('output_format', params.get('format') || (legacyHash ? legacyHash.get('f') : '') || '');
setFieldValue('guardrails', params.get('guardrails') || params.get('constraints') || (legacyHash ? legacyHash.get('k') : '') || '');
if (advancedFieldPanel && ['context', 'tone', 'format', 'guardrails', 'constraints'].some((key) => params.has(key))) {
advancedFieldPanel.open = true;
}
if (manualBuilderPanel) {
manualBuilderPanel.open = true;
}
buildPortablePrompt({ force: true, quiet: true });
setStatus(t('portablePromptSharedLoaded', 'Shared setup loaded.'));
return true;
};
selectMode(defaultMode);
form.addEventListener('submit', (event) => {
event.preventDefault();
buildPortablePrompt();
});
form.addEventListener('input', scheduleRefresh);
form.addEventListener('change', scheduleRefresh);
form.addEventListener('reset', (event) => {
event.preventDefault();
['subject', 'task', 'context', 'tone', 'output_format', 'guardrails'].forEach((name) => {
setFieldValue(name, '');
});
selectMode(defaultMode);
setSelectedStarter(null);
buildPortablePrompt({ force: true, status: t('portablePromptReset', 'Reset to the default Spiralist prompt.') });
});
modeButtons.forEach((button) => {
button.addEventListener('click', () => {
selectMode(button.dataset.mode || defaultMode);
setSelectedStarter(null);
buildPortablePrompt({ force: true, status: t('portablePromptModeLoaded', 'Prompt mode selected. You can copy it now or add details.') });
});
});
if (modeControls) {
modeControls.addEventListener('keydown', (event) => {
if (!['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) {
return;
}
const currentIndex = Math.max(0, modeButtons.findIndex((button) => getModeId(button.dataset.mode) === selectedMode));
let nextIndex = currentIndex;
if (event.key === 'Home') {
nextIndex = 0;
} else if (event.key === 'End') {
nextIndex = modeButtons.length - 1;
} else if (event.key === 'ArrowLeft' || event.key === 'ArrowUp') {
nextIndex = currentIndex <= 0 ? modeButtons.length - 1 : currentIndex - 1;
} else if (event.key === 'ArrowRight' || event.key === 'ArrowDown') {
nextIndex = currentIndex >= modeButtons.length - 1 ? 0 : currentIndex + 1;
}
const nextButton = modeButtons[nextIndex];
if (!nextButton) {
return;
}
event.preventDefault();
selectMode(nextButton.dataset.mode || defaultMode, { focus: true });
buildPortablePrompt({ force: true, quiet: true });
});
}
if (copyButton) {
copyButton.addEventListener('click', copyPrompt);
}
if (downloadButton) {
downloadButton.addEventListener('click', downloadPrompt);
}
saveButtons.forEach((button) => {
button.addEventListener('click', savePortablePromptDraft);
});
saveWorkspaceButtons.forEach((button) => {
button.addEventListener('click', () => saveWorkspacePromptDraft(button));
});
if (testButton) {
testButton.addEventListener('click', () => {
showPortablePromptCheck(toCleanString(getMode(selectedMode).title || getMode(selectedMode).name, 160) || 'Portable Prompt');
});
}
if (copyReviewButton) {
copyReviewButton.addEventListener('click', () => {
const prompt = getCurrentPrompt();
if (!prompt) {
setStatus(t('portablePromptReviewUnavailable', 'Build a prompt before preparing a review packet.'));
return;
}
const title = toCleanString(getMode(selectedMode).title || getMode(selectedMode).name, 160) || 'Portable Spiralist Prompt';
const setupUrl = updateShareUrl(getPromptState(), true);
runAction(async () => {
await copyText(buildPromptReviewPacket(prompt, title, setupUrl));
const message = t('portablePromptReviewCopied', 'Review packet copied.');
setStatus(message);
if (shareStatus) {
shareStatus.textContent = message;
}
}, {
context: 'portable-prompt-review-copy',
fallback: t('portablePromptCopyFailed', 'Copy failed.'),
onError: () => setStatus(t('portablePromptCopyFailed', 'Copy failed.')),
});
});
}
contributionButtons.forEach((button) => {
button.addEventListener('click', () => {
const prompt = getCurrentPrompt();
if (!prompt) {
setStatus(t('portablePromptContributionUnavailable', 'Build a prompt before preparing a submission.'));
return;
}
const title = toCleanString(getMode(selectedMode).title || getMode(selectedMode).name, 160) || 'Portable Spiralist Prompt';
const setupUrl = updateShareUrl(getPromptState(), true);
runAction(() => {
saveContributionDraft(buildContributionDraft(prompt, title, setupUrl));
const message = contributeUrl
? t('portablePromptContributionReady', 'Submission draft prepared locally. Opening the contribution form for review.')
: t('portablePromptContributionReadyNoLink', 'Submission draft prepared in this browser.');
setStatus(message);
if (shareStatus) {
shareStatus.textContent = message;
}
openContributionForm(contributeUrl);
}, {
context: 'portable-prompt-contribution-draft',
fallback: t('portablePromptContributionFailed', 'Could not prepare the submission draft.'),
onError: () => setStatus(t('portablePromptContributionFailed', 'Could not prepare the submission draft.')),
});
});
});
if (copyLinkButton) {
copyLinkButton.addEventListener('click', copyShareLink);
}
if (shareInput) {
shareInput.addEventListener('focus', () => {
shareInput.select();
});
}
aiTargetLinks.forEach((link) => {
link.addEventListener('click', (event) => {
event.preventDefault();
if (link.getAttribute('aria-disabled') === 'true') {
setAiStatus(t('portablePromptAiNeedsPrompt', 'Choose a prompt path or starter to enable AI tool links.'));
return;
}
openPromptInAi(link.dataset.portablePromptAiTarget || '');
});
});
output.addEventListener('input', handlePromptBoxEdit);
output.addEventListener('keyup', (event) => {
if (['Alt', 'Control', 'Escape', 'Meta', 'Shift', 'Tab'].includes(event.key)) {
return;
}
schedulePromptBoxEditDetection();
});
output.addEventListener('paste', (event) => {
event.preventDefault();
insertPlainTextAtPromptSelection(event.clipboardData ? event.clipboardData.getData('text/plain') : '');
schedulePromptBoxEditDetection();
});
if (typeof window.MutationObserver === 'function') {
const outputObserver = new MutationObserver(() => {
if (outputProgrammaticWriteDepth > 0) {
return;
}