Workspace - Source Excerpt 06
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/assets/js/workspace.js so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/assets/js/workspace.js
const initRunForms = () => {
document.querySelectorAll("[data-run-form]").forEach((form) => {
form.addEventListener("submit", (event) => {
event.preventDefault();
setResult(form, t("runRunning", "Rendering prompt packet..."));
const output = form.querySelector("[data-run-output]");
const outputCopy = form.querySelector("[data-run-output-copy]");
if (outputCopy) {
outputCopy.hidden = true;
}
runFormAction(form, async () => {
const payload = formDataToObject(form);
const promptId = parseInt(form.getAttribute("data-prompt-id") || "0", 10);
const response = await apiFetch("prompts/" + promptId + "/run", {
method: "POST",
body: JSON.stringify(payload),
});
setResult(form, t("runCompleted", "Prompt packet rendered."));
const link = form.querySelector("[data-run-link]");
if (output) {
output.textContent = response.output_text || t("runNoOutput", "No prompt packet returned.");
output.hidden = false;
}
if (outputCopy) {
outputCopy.hidden = !(output && !output.hidden && String(output.textContent || "").trim());
}
if (link) {
link.hidden = true;
link.removeAttribute("href");
}
if (link && response.id && parseInt(response.user_id || "0", 10) > 0) {
link.href = buildRoute("run/" + response.id);
link.hidden = false;
}
}, t("runFailed", "Prompt packet rendering failed."), "prompt-run");
});
});
};
const initConversationStartForms = () => {
document.querySelectorAll("[data-start-conversation-form]").forEach((form) => {
form.addEventListener("submit", (event) => {
event.preventDefault();
setResult(form, t("conversationStarting", "Starting conversation..."));
runFormAction(form, async () => {
const payload = formDataToObject(form);
const promptId = parseInt(form.getAttribute("data-prompt-id") || "0", 10);
const response = await apiFetch("prompts/" + promptId + "/conversation", {
method: "POST",
body: JSON.stringify(payload),
});
const conversation = response.conversation || {};
if (conversation.id) {
const shell = form.parentElement?.querySelector("[data-inline-conversation]");
if (shell) {
shell.hidden = false;
form.hidden = true;
updateConversationShell(shell, response);
setResult(form, t("conversationStarted", "Conversation started."));
shell.scrollIntoView({ behavior: "smooth", block: "start" });
return;
}
setResult(form, t("conversationStarted", "Conversation started."));
return;
}
setResult(form, t("conversationStartedNoId", "Conversation started, but no conversation id was returned."), false);
}, t("conversationStartFailed", "Conversation start failed."), "conversation-start");
});
});
};
const initConversationForms = () => {
document.addEventListener("submit", (event) => {
const form = closestTarget(event.target, "[data-conversation-form]");
if (!form) {
return;
}
event.preventDefault();
setResult(form, t("messageSending", "Sending..."));
const submitButton = form.querySelector('[type="submit"]');
if (submitButton) {
submitButton.disabled = true;
}
runFormAction(form, async () => {
const payload = formDataToObject(form);
const conversationId = parseInt(form.getAttribute("data-conversation-id") || "0", 10);
if (conversationId <= 0) {
throw new Error(t("conversationNotReady", "Conversation is not ready yet."));
}
if (!String(payload.message || "").trim()) {
throw new Error(t("messageRequired", "Enter a message before sending."));
}
const response = await apiFetch("conversations/" + conversationId + "/messages", {
method: "POST",
body: JSON.stringify(payload),
});
const shell = form.closest("[data-fullscreen-chat]") || document;
updateConversationShell(shell, response);
form.reset();
setResult(form, t("messageSent", "Message sent."));
}, t("messageFailed", "Message failed."), "conversation-message", {
onFinally: () => setDisabled(submitButton, false),
});
});
};
const initConversationMemoryActions = () => {
document.querySelectorAll("[data-condense-conversation]").forEach((button) => {
button.addEventListener("click", () => {
const conversationId = parseInt(button.getAttribute("data-conversation-id") || "0", 10);
const panel = button.closest("[data-memory-panel]") || document;
const buttons = panel.querySelectorAll("[data-condense-conversation]");
const credentialPreference = button.getAttribute("data-credential-preference") || "site_default";
setInlineResult(panel, t("memoryCondensing", "Preparing checkpoint prompt..."));
buttons.forEach((item) => {
item.disabled = true;
});
runInlineAction(panel, async () => {
const response = await apiFetch("conversations/" + conversationId + "/condense", {
method: "POST",
body: JSON.stringify({ credential_preference: credentialPreference }),
});
const shell = button.closest("[data-fullscreen-chat]") || document;
updateConversationShell(shell, response);
setInlineResult(panel, t("memoryCondensed", "Checkpoint prompt prepared."));
}, t("memoryCondenseFailed", "Checkpoint prompt preparation failed."), "conversation-condense", {
onFinally: () => setDisabled(buttons, false),
});
});
});
document.querySelectorAll("[data-download-conversation-prompt]").forEach((button) => {
button.addEventListener("click", () => {
const conversationId = parseInt(button.getAttribute("data-conversation-id") || "0", 10);
const panel = button.closest("[data-memory-panel]") || document;
setInlineResult(panel, t("promptDownloadPreparing", "Preparing prompt..."));
button.disabled = true;
runInlineAction(panel, async () => {
const response = await apiFetch("conversations/" + conversationId + "/portable-prompt");
downloadTextFile(
response.filename || "conversation-prompt.md",
response.prompt || "",
response.content_type || "text/markdown"
);
setInlineResult(panel, t("promptDownloaded", "Prompt downloaded."));
}, t("promptDownloadFailed", "Prompt download failed."), "conversation-prompt-download", {
onFinally: () => setDisabled(button, false),
});
});
});
};
const initShareForms = () => {
document.querySelectorAll("[data-share-form]").forEach((form) => {
form.addEventListener("submit", (event) => {
event.preventDefault();
setResult(form, t("shareSharing", "Sharing..."));