Spaces:
Running on Zero
Running on Zero
fix: restore export state after reload
Browse filesCo-authored-by: Codex <noreply@openai.com>
- static/app.js +30 -6
static/app.js
CHANGED
|
@@ -108,6 +108,7 @@ async function runTurn(message) {
|
|
| 108 |
ink.classList.remove("bleed", "gold");
|
| 109 |
corrections.textContent = "";
|
| 110 |
planEl.innerHTML = "";
|
|
|
|
| 111 |
startTurnWatchdog();
|
| 112 |
|
| 113 |
try {
|
|
@@ -184,6 +185,8 @@ function applyDemoSession(data) {
|
|
| 184 |
session = data.session || {};
|
| 185 |
session.profile = session.profile || {};
|
| 186 |
session.targets = Array.isArray(session.targets) ? session.targets : [];
|
|
|
|
|
|
|
| 187 |
currentArtifact = data.artifact || session.last_artifact || null;
|
| 188 |
ink.textContent = data.response || "Demo rehearsal loaded.";
|
| 189 |
ink.classList.remove("thinking");
|
|
@@ -208,7 +211,7 @@ function applyDemoSession(data) {
|
|
| 208 |
exportButton.disabled = !currentArtifact;
|
| 209 |
setButtonDisabled(exportNotesButton, !(session.trace?.length));
|
| 210 |
setButtonDisabled(exportChapterButton, !(session.ideas?.length));
|
| 211 |
-
corrections.textContent =
|
| 212 |
saveSession();
|
| 213 |
}
|
| 214 |
|
|
@@ -226,8 +229,11 @@ function renderRestoredSession(data) {
|
|
| 226 |
const score = currentArtifact?.seal || idea?.score || null;
|
| 227 |
if (score) {
|
| 228 |
renderScore(score);
|
| 229 |
-
|
|
|
|
| 230 |
overallEl.textContent = Number(currentArtifact?.overall || score.overall || 0).toFixed(1);
|
|
|
|
|
|
|
| 231 |
renderWoodMap(currentArtifact?.wood_map || null);
|
| 232 |
if (score.echoes?.length) {
|
| 233 |
renderCitations(score.echoes);
|
|
@@ -245,6 +251,7 @@ function renderRestoredSession(data) {
|
|
| 245 |
renderPlan(session.last_plan || []);
|
| 246 |
setButtonDisabled(exportNotesButton, !(session.trace?.length));
|
| 247 |
setButtonDisabled(exportChapterButton, !(session.ideas?.length));
|
|
|
|
| 248 |
}
|
| 249 |
|
| 250 |
function readSavedSession() {
|
|
@@ -272,9 +279,18 @@ function normalizeSession(savedSession, defaultSession) {
|
|
| 272 |
if (savedSession.current_whitespace) normalized.current_whitespace = savedSession.current_whitespace;
|
| 273 |
if (savedSession.last_tool_resolution) normalized.last_tool_resolution = savedSession.last_tool_resolution;
|
| 274 |
if (savedSession.last_artifact) normalized.last_artifact = savedSession.last_artifact;
|
|
|
|
|
|
|
| 275 |
return normalized;
|
| 276 |
}
|
| 277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
function normalizeTargetProfiles(profiles, options) {
|
| 279 |
const byId = new Map(
|
| 280 |
profiles
|
|
@@ -380,6 +396,8 @@ function handleEvent(event) {
|
|
| 380 |
session = event.state || {};
|
| 381 |
session.profile = session.profile || {};
|
| 382 |
session.targets = Array.isArray(session.targets) ? session.targets : [];
|
|
|
|
|
|
|
| 383 |
if (event.score?.echoes?.length) {
|
| 384 |
renderCitations(event.score.echoes);
|
| 385 |
} else if (event.projects?.length) {
|
|
@@ -473,7 +491,8 @@ function selectIdea(ideaId) {
|
|
| 473 |
renderTargets(session.targets || []);
|
| 474 |
renderIdeas(session.ideas);
|
| 475 |
renderPlan([]);
|
| 476 |
-
|
|
|
|
| 477 |
saveSession();
|
| 478 |
}
|
| 479 |
|
|
@@ -684,7 +703,9 @@ async function exportMarkdown({ endpoint, filename, button, busyLabel, pendingLa
|
|
| 684 |
const idleLabel = button.textContent;
|
| 685 |
button.disabled = true;
|
| 686 |
button.textContent = busyLabel;
|
| 687 |
-
|
|
|
|
|
|
|
| 688 |
try {
|
| 689 |
const client = await clientPromise;
|
| 690 |
const result = await client.predict(endpoint, {
|
|
@@ -694,10 +715,13 @@ async function exportMarkdown({ endpoint, filename, button, busyLabel, pendingLa
|
|
| 694 |
const text = String(data || "");
|
| 695 |
if (!text.trim()) throw new Error("empty export");
|
| 696 |
downloadText(filename, text, "text/markdown;charset=utf-8");
|
| 697 |
-
|
|
|
|
| 698 |
} catch (error) {
|
| 699 |
-
|
|
|
|
| 700 |
} finally {
|
|
|
|
| 701 |
button.textContent = idleLabel;
|
| 702 |
setCommandDisabled(false);
|
| 703 |
}
|
|
|
|
| 108 |
ink.classList.remove("bleed", "gold");
|
| 109 |
corrections.textContent = "";
|
| 110 |
planEl.innerHTML = "";
|
| 111 |
+
delete session.ui_status;
|
| 112 |
startTurnWatchdog();
|
| 113 |
|
| 114 |
try {
|
|
|
|
| 185 |
session = data.session || {};
|
| 186 |
session.profile = session.profile || {};
|
| 187 |
session.targets = Array.isArray(session.targets) ? session.targets : [];
|
| 188 |
+
session.last_response = data.response || session.last_response || "";
|
| 189 |
+
session.ui_status = `example loaded: ${data.turn_count || 0} advisor turns`;
|
| 190 |
currentArtifact = data.artifact || session.last_artifact || null;
|
| 191 |
ink.textContent = data.response || "Demo rehearsal loaded.";
|
| 192 |
ink.classList.remove("thinking");
|
|
|
|
| 211 |
exportButton.disabled = !currentArtifact;
|
| 212 |
setButtonDisabled(exportNotesButton, !(session.trace?.length));
|
| 213 |
setButtonDisabled(exportChapterButton, !(session.ideas?.length));
|
| 214 |
+
corrections.textContent = session.ui_status;
|
| 215 |
saveSession();
|
| 216 |
}
|
| 217 |
|
|
|
|
| 229 |
const score = currentArtifact?.seal || idea?.score || null;
|
| 230 |
if (score) {
|
| 231 |
renderScore(score);
|
| 232 |
+
const verdict = currentArtifact?.verdict || score.verdict || "UNWRITTEN";
|
| 233 |
+
verdictEl.textContent = verdict;
|
| 234 |
overallEl.textContent = Number(currentArtifact?.overall || score.overall || 0).toFixed(1);
|
| 235 |
+
ink.classList.toggle("bleed", verdict.startsWith("ECHO"));
|
| 236 |
+
ink.classList.toggle("gold", verdict.startsWith("UNWRITTEN"));
|
| 237 |
renderWoodMap(currentArtifact?.wood_map || null);
|
| 238 |
if (score.echoes?.length) {
|
| 239 |
renderCitations(score.echoes);
|
|
|
|
| 251 |
renderPlan(session.last_plan || []);
|
| 252 |
setButtonDisabled(exportNotesButton, !(session.trace?.length));
|
| 253 |
setButtonDisabled(exportChapterButton, !(session.ideas?.length));
|
| 254 |
+
restoreSessionCopy();
|
| 255 |
}
|
| 256 |
|
| 257 |
function readSavedSession() {
|
|
|
|
| 279 |
if (savedSession.current_whitespace) normalized.current_whitespace = savedSession.current_whitespace;
|
| 280 |
if (savedSession.last_tool_resolution) normalized.last_tool_resolution = savedSession.last_tool_resolution;
|
| 281 |
if (savedSession.last_artifact) normalized.last_artifact = savedSession.last_artifact;
|
| 282 |
+
if (typeof savedSession.last_response === "string") normalized.last_response = savedSession.last_response;
|
| 283 |
+
if (typeof savedSession.ui_status === "string") normalized.ui_status = savedSession.ui_status;
|
| 284 |
return normalized;
|
| 285 |
}
|
| 286 |
|
| 287 |
+
function restoreSessionCopy() {
|
| 288 |
+
const response = typeof session.last_response === "string" ? session.last_response.trim() : "";
|
| 289 |
+
if (response) ink.textContent = response;
|
| 290 |
+
const status = typeof session.ui_status === "string" ? session.ui_status.trim() : "";
|
| 291 |
+
if (status) corrections.textContent = status;
|
| 292 |
+
}
|
| 293 |
+
|
| 294 |
function normalizeTargetProfiles(profiles, options) {
|
| 295 |
const byId = new Map(
|
| 296 |
profiles
|
|
|
|
| 396 |
session = event.state || {};
|
| 397 |
session.profile = session.profile || {};
|
| 398 |
session.targets = Array.isArray(session.targets) ? session.targets : [];
|
| 399 |
+
session.last_response = event.response || session.last_response || "";
|
| 400 |
+
delete session.ui_status;
|
| 401 |
if (event.score?.echoes?.length) {
|
| 402 |
renderCitations(event.score.echoes);
|
| 403 |
} else if (event.projects?.length) {
|
|
|
|
| 491 |
renderTargets(session.targets || []);
|
| 492 |
renderIdeas(session.ideas);
|
| 493 |
renderPlan([]);
|
| 494 |
+
session.ui_status = `selected: ${idea.title}`;
|
| 495 |
+
corrections.textContent = session.ui_status;
|
| 496 |
saveSession();
|
| 497 |
}
|
| 498 |
|
|
|
|
| 703 |
const idleLabel = button.textContent;
|
| 704 |
button.disabled = true;
|
| 705 |
button.textContent = busyLabel;
|
| 706 |
+
session.ui_status = pendingLabel;
|
| 707 |
+
corrections.textContent = session.ui_status;
|
| 708 |
+
saveSession();
|
| 709 |
try {
|
| 710 |
const client = await clientPromise;
|
| 711 |
const result = await client.predict(endpoint, {
|
|
|
|
| 715 |
const text = String(data || "");
|
| 716 |
if (!text.trim()) throw new Error("empty export");
|
| 717 |
downloadText(filename, text, "text/markdown;charset=utf-8");
|
| 718 |
+
session.ui_status = `${successLabel}: ${filename}`;
|
| 719 |
+
corrections.textContent = session.ui_status;
|
| 720 |
} catch (error) {
|
| 721 |
+
session.ui_status = `Export failed: ${error.message}`;
|
| 722 |
+
corrections.textContent = session.ui_status;
|
| 723 |
} finally {
|
| 724 |
+
saveSession();
|
| 725 |
button.textContent = idleLabel;
|
| 726 |
setCommandDisabled(false);
|
| 727 |
}
|