${escapeHtml(assistant.name)}
${escapeHtml(assistant.description || assistant.generation_goal || "暂无说明")}
@@ -9804,6 +9828,7 @@ function openCreateAssistantAction() {
appState.selectedAssistantId = assistant.id;
rememberAction("Agent 已创建", `已创建 Agent「${assistant.name}」。`, "green", assistant);
await bootstrap();
+ focusPlaybookWorkspace(assistant.id);
}
});
}
@@ -9842,6 +9867,7 @@ function openEditAssistantAction(assistantId = "") {
appState.selectedAssistantId = updated.id;
rememberAction("Agent 已更新", `已更新 Agent「${updated.name}」。`, "green", updated);
await bootstrap();
+ focusPlaybookWorkspace(updated.id);
}
});
}
@@ -10626,11 +10652,7 @@ function openCreateRealCutAction(defaults = {}) {
}
function openLiveRecorderAction() {
- setScreen("production");
- renderAll();
- window.requestAnimationFrame(() => {
- document.getElementById("live-recorder-maintenance-anchor")?.scrollIntoView({ behavior: "smooth", block: "start" });
- });
+ focusLiveRecorderMaintenance();
}
function openLiveRecorderCreateAction() {
@@ -10677,6 +10699,7 @@ function openLiveRecorderCreateAction() {
}
rememberAction("直播录制已下发", "当前租户的直播源已经保存到服务端并同步到 NAS。", "green", { saved, started });
await bootstrap();
+ focusLiveRecorderMaintenance();
}
});
}
@@ -10731,6 +10754,7 @@ function openLiveRecorderSourceAction(sourceId) {
});
rememberAction("录制源已更新", `已保存「${saved.item?.title || source.title || "录制源"}」。`, "green", saved);
await bootstrap();
+ focusLiveRecorderMaintenance();
}
});
}
@@ -10763,6 +10787,7 @@ function openLiveRecorderImportAction() {
});
rememberAction("URL 配置已导入", `已导入 ${formatNumber(saved.count || 0)} 条录制源。`, "green", saved);
await bootstrap();
+ focusLiveRecorderMaintenance();
}
});
}
@@ -10784,6 +10809,7 @@ async function toggleLiveRecorderSourceAction(sourceId, nextEnabled) {
});
rememberAction(nextEnabled ? "录制源已启用" : "录制源已停用", `${source.title || source.source_url || "录制源"} 已更新。`, "green");
await bootstrap();
+ focusLiveRecorderMaintenance();
} finally {
setBusy(false, "");
}
@@ -10808,6 +10834,7 @@ async function deleteLiveRecorderSourceAction(sourceId) {
});
rememberAction("录制源已删除", `${source.title || source.source_url || "录制源"} 已从租户视图中移除。`, "green");
await bootstrap();
+ focusLiveRecorderMaintenance();
} finally {
setBusy(false, "");
}
diff --git a/web/storyforge-web-v4/tests/workbench-pages.test.mjs b/web/storyforge-web-v4/tests/workbench-pages.test.mjs
index ca273e0..e2cdca9 100644
--- a/web/storyforge-web-v4/tests/workbench-pages.test.mjs
+++ b/web/storyforge-web-v4/tests/workbench-pages.test.mjs
@@ -906,6 +906,30 @@ test("review actions return to the review workspace with the saved review in foc
assert.match(APP, /data-review-id="\$\{escapeHtml\(review\.id\)\}"/);
});
+test("assistant actions return to the playbook workspace with the saved assistant in focus", () => {
+ const createAssistant = extractBetween(APP, "function openCreateAssistantAction()", "function openEditAssistantAction(assistantId = \"\")");
+ const editAssistant = extractBetween(APP, "function openEditAssistantAction(assistantId = \"\")", "function openAnalyzeSelectedAccountAction()");
+ assert.match(APP, /function focusPlaybookWorkspace\(assistantId = ""\)/);
+ assert.match(createAssistant, /focusPlaybookWorkspace\(assistant\.id\)/);
+ assert.match(editAssistant, /focusPlaybookWorkspace\(updated\.id\)/);
+ assert.match(APP, /id="current-agent-anchor"/);
+ assert.match(APP, /data-assistant-id="\$\{escapeHtml\(assistant\.id\)\}"/);
+});
+
+test("live recorder mutations return to the recorder maintenance panel after success", () => {
+ const createSource = extractBetween(APP, "function openLiveRecorderCreateAction()", "function openLiveRecorderSourceAction(sourceId)");
+ const editSource = extractBetween(APP, "function openLiveRecorderSourceAction(sourceId)", "function openLiveRecorderImportAction()");
+ const importSource = extractBetween(APP, "function openLiveRecorderImportAction()", "async function toggleLiveRecorderSourceAction(sourceId, nextEnabled)");
+ const toggleSource = extractBetween(APP, "async function toggleLiveRecorderSourceAction(sourceId, nextEnabled)", "async function deleteLiveRecorderSourceAction(sourceId)");
+ const deleteSource = extractBetween(APP, "async function deleteLiveRecorderSourceAction(sourceId)", "async function openLiveRecorderFileAction(fileId)");
+ assert.match(APP, /function focusLiveRecorderMaintenance\(\)/);
+ assert.match(createSource, /focusLiveRecorderMaintenance\(\)/);
+ assert.match(editSource, /focusLiveRecorderMaintenance\(\)/);
+ assert.match(importSource, /focusLiveRecorderMaintenance\(\)/);
+ assert.match(toggleSource, /focusLiveRecorderMaintenance\(\)/);
+ assert.match(deleteSource, /focusLiveRecorderMaintenance\(\)/);
+});
+
test("main agent execution cards can jump to oneliner and platform profile history", () => {
const messages = extractBetween(APP, "function renderOneLinerMessagesHtml()", "function renderAutoConnectingScreen(screenTitle, nextStepText)");
assert.match(messages, /data-action="open-oneliner-profile-history"/);