Skip to content
wiki.fftac.org

Workspace - Source Excerpt 02

Back to Workspace

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

return title.slice(0, 140) || t("editablePromptDraftTitle", "Edited Spiralist Prompt");
    };
    const editablePromptDraftPayload = (surface) => {
        const text = editablePromptText(surface);
        const source = surface.getAttribute("data-editable-prompt-source") || "prompt-surface";
        const sourceLabel = source.split("-").join(" ");
        const title = promptTitleFromText(text, surface.getAttribute("data-editable-prompt-title") || "");

        if (!text) {
            throw new Error(t("editablePromptEmpty", "Enter prompt text before saving."));
        }

        return {
            title,
            summary: formatText("editablePromptSummary", "Edited from the {source} surface.", { source: sourceLabel }),
            category: "Prompt Library",
            subcategory: "Editable Draft",
            prompt_type: "prompt",
            visibility: "private",
            prompt_status: "draft",
            moderation_status: "draft",
            publication_lane: "community_library",
            provenance: "user",
            language: "en",
            provider: "manual",
            credential_preference: "manual_only",
            model: "manual",
            tags: ["editable-prompt-block", filenameSlug(source, "prompt-surface")],
            function_tags: ["prompt_builder"],
            risk_labels: ["needs_review"],
            maturity_level: "draft",
            license: "private",
            instructions: text,
            structured_prompt: {
                instruction: text,
                context: formatText("editablePromptContext", "Saved from the {source} surface after browser-side editing.", { source: sourceLabel }),
                constraints: t("editablePromptConstraints", "Review before publication, sharing, or external AI use."),
                examples: "",
                output_format: t("editablePromptOutputFormat", "Use the edited text as the authoritative prompt draft."),
            },
            editorial_note: t("editablePromptEditorialNote", "Saved from an editable prompt block. Review before making public."),
            expected_output_notes: t("editablePromptExpectedOutput", "The saved prompt should preserve the edited text exactly as the working instruction."),
            failure_modes: t("editablePromptFailureModes", "May need cleanup if copied from an output trace or partial dossier field."),
            changelog: t("editablePromptChangelog", "Saved from editable prompt surface."),
        };
    };
    const storePendingEditablePromptSave = (surface, authUrl = "") => {
        const payload = editablePromptDraftPayload(surface);
        const record = {
            schema: "spiralist.pending-editable-prompt-save.v1",
            source: surface.getAttribute("data-editable-prompt-source") || "prompt-surface",
            createdAt: new Date().toISOString(),
            returnUrl: window.location.href,
            payload,
        };

        storage.set(pendingEditablePromptSaveKey, JSON.stringify(record));
        setEditablePromptStatus(surface, t("editablePromptAuthQueued", "Edited prompt held in this browser. Log in or sign up to save it to your private library."));
        const targetUrl = String(authUrl || config.loginUrl || config.signupUrl || "").trim();
        if (targetUrl) {
            window.location.assign(targetUrl);
        }
    };
    const savePendingEditablePromptAfterAuth = () => {
        if (!canSavePrompts) {
            return;
        }

        const raw = storage.get(pendingEditablePromptSaveKey, "");
        if (!raw) {
            return;
        }

        let record = null;
        try {
            record = JSON.parse(raw);
        } catch (error) {
            storage.remove(pendingEditablePromptSaveKey);
            return;
        }

        if (!record || !record.payload || typeof record.payload !== "object") {
            storage.remove(pendingEditablePromptSaveKey);
            return;
        }

        const statusSurface = document.querySelector("[data-editable-prompt-surface]");
        if (statusSurface) {
            setEditablePromptStatus(statusSurface, t("editablePromptSavingPending", "Saving your edited prompt after login..."));
        }

        runAction(async () => {
            const response = await apiFetch("prompts", {
                method: "POST",
                body: JSON.stringify(record.payload),
            });
            storage.remove(pendingEditablePromptSaveKey);
            const savedTitle = response.title || t("editablePromptDraftTitle", "Edited Spiralist Prompt");
            if (statusSurface) {
                setEditablePromptStatus(statusSurface, formatText("editablePromptSavedAfterAuth", "Saved \"{title}\" to your private prompt library after login.", { title: savedTitle }));
            }
        }, {
            context: "editable-prompt-save-after-auth",
            fallback: t("editablePromptSaveFailed", "Could not save edited prompt."),
            onError: (error, message) => {
                if (statusSurface) {
                    setEditablePromptStatus(statusSurface, message, false);
                }
            },
        });
    };

    const getPromptExchangePayload = (panel) => {
        const id = panel.getAttribute("data-prompt-exchange") || "";
        const script = id ? document.getElementById(id) : null;