Files
storyforge/web/storyforge-web-v4/tests/workbench-pages.test.mjs
kris 88ccc62c71
Some checks failed
StoryForge CI / Baseline checks (push) Has been cancelled
StoryForge CI / Backend tests (push) Has been cancelled
StoryForge CI / Web tests (push) Has been cancelled
fix: preserve oneliner suggested action context
2026-04-05 06:36:29 +08:00

1253 lines
87 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import test from "node:test";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
const ROOT = path.resolve(process.cwd(), "web/storyforge-web-v4");
const HTML = fs.readFileSync(path.join(ROOT, "index.html"), "utf8");
const APP = fs.readFileSync(path.join(ROOT, "assets/app.js"), "utf8");
const CSS = fs.readFileSync(path.join(ROOT, "assets/styles.css"), "utf8");
function extractBetween(source, startToken, endToken) {
const start = source.indexOf(startToken);
assert.notEqual(start, -1, `Missing token: ${startToken}`);
const end = source.indexOf(endToken, start);
assert.notEqual(end, -1, `Missing token: ${endToken}`);
return source.slice(start, end);
}
test("settings navigation and screen are real routes", () => {
assert.match(HTML, /data-screen-target="settings"/);
assert.match(HTML, /data-screen="settings"/);
assert.match(APP, /function renderSettingsScreen\(/);
assert.match(APP, /screenMap\.settings\.innerHTML = renderSettingsScreen\(\);/);
assert.match(APP, /window\.addEventListener\("hashchange"/);
});
test("mobile shell includes a native-like header, drawer toggle, and bottom tab bar", () => {
assert.match(HTML, /<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/);
assert.match(HTML, /class="mobile-shell-bar"/);
assert.match(HTML, /class="mobile-workspace-strip"/);
assert.match(HTML, /data-role="mobile-workspace-project"/);
assert.match(HTML, /data-role="mobile-workspace-platforms"/);
assert.match(HTML, /data-action="open-mobile-sidebar"/);
assert.match(HTML, /class="mobile-tabbar"/);
assert.match(HTML, /class="mobile-sidebar-backdrop"/);
assert.match(HTML, /data-screen-target="dashboard"[\s\S]*mobile-tabbar-item/);
assert.match(HTML, /data-screen-target="intake"[\s\S]*mobile-tabbar-item/);
assert.match(HTML, /data-screen-target="discovery"[\s\S]*mobile-tabbar-item/);
assert.match(HTML, /data-screen-target="production"[\s\S]*mobile-tabbar-item/);
assert.match(HTML, /data-screen-target="playbook"[\s\S]*mobile-tabbar-item/);
});
test("mobile shell styling uses safe-area padding, drawer navigation, and fixed bottom navigation", () => {
assert.match(CSS, /padding-top:\s*max\(12px,\s*env\(safe-area-inset-top\)\)/);
assert.match(CSS, /\.mobile-shell-bar\s*\{[\s\S]*position:\s*sticky/);
assert.match(CSS, /\.mobile-tabbar\s*\{[\s\S]*position:\s*fixed/);
assert.match(CSS, /\.mobile-sidebar-backdrop\s*\{[\s\S]*position:\s*fixed/);
assert.match(CSS, /\.mobile-sidebar-backdrop\s*\{[\s\S]*z-index:\s*46/);
assert.match(CSS, /\.mobile-sidebar-open\s+\.sidebar\s*\{[\s\S]*transform:\s*translateX\(0\)/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.sidebar\s*\{[\s\S]*z-index:\s*47/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.mobile-sidebar-open \.mobile-tabbar,[\s\S]*\.mobile-sidebar-open \.mobile-shell-bar\s*\{[\s\S]*pointer-events:\s*none/);
assert.match(CSS, /\.content\s*\{[\s\S]*padding-bottom:\s*calc\(110px \+ env\(safe-area-inset-bottom\)\)/);
assert.match(CSS, /\.oneliner-fab\s*\{[\s\S]*bottom:\s*calc\(96px \+ env\(safe-area-inset-bottom\)\)/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.mobile-workspace-strip\s*\{[\s\S]*display:\s*grid/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.workspace-switch span\s*\{[\s\S]*display:\s*none/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.auth-status\s*\{[\s\S]*display:\s*none/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.oneliner-fab-text\s*\{[\s\S]*display:\s*none/);
});
test("mobile shell javascript syncs drawer state and active labels with the current screen", () => {
const shell = extractBetween(APP, "function renderAuthUi()", "function openAuthModal()");
const clicks = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(APP, /function setMobileSidebarOpen\(next\)/);
assert.match(APP, /function getScreenLabel\(screenId = appState\.screen\)/);
assert.match(APP, /function syncMobileShell\(\)/);
assert.match(APP, /const mobileWorkspaceProject = document\.querySelector\('\[data-role="mobile-workspace-project"\]'\)/);
assert.match(APP, /const mobileWorkspacePlatforms = document\.querySelector\('\[data-role="mobile-workspace-platforms"\]'\)/);
assert.match(shell, /syncMobileShell\(\);/);
assert.match(APP, /setMobileSidebarOpen\(false\);[\s\S]*appState\.screen = resolvedId;/);
assert.match(clicks, /name === "open-mobile-sidebar"/);
assert.match(clicks, /name === "close-mobile-sidebar"/);
assert.match(clicks, /action\.closest\("\.sidebar"\)/);
});
test("mobile workspace strip stays available for project and platform switching", () => {
const topbar = extractBetween(APP, "function renderTopbar()", "function syncRoleGatedNav()");
assert.match(topbar, /data-role="mobile-workspace-project"/);
assert.match(topbar, /data-role="mobile-workspace-platforms"/);
assert.match(topbar, /mobileWorkspaceProject\.dataset\.action = "open-dashboard-project-switcher"/);
assert.match(topbar, /data-action="select-platform"/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.mobile-workspace-strip\s*\{[\s\S]*display:\s*grid/);
});
test("mobile layout turns screen actions and page tabs into native-like horizontal rails", () => {
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.action-row\s*\{[\s\S]*flex-wrap:\s*nowrap/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.action-row\s*\{[\s\S]*overflow-x:\s*auto/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.page-detail-tabs\s*\{[\s\S]*overflow-x:\s*auto/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.page-detail-tabs\s*\{[\s\S]*scroll-snap-type:\s*x proximity/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.page-detail-tabs \.tab\s*\{[\s\S]*flex:\s*0 0 auto/);
});
test("mobile shell removes duplicated desktop topbar and collapses the main agent fab", () => {
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.topbar\s*\{[\s\S]*display:\s*none/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.oneliner-fab\s*\{[\s\S]*width:\s*52px/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.oneliner-fab\s*\{[\s\S]*justify-content:\s*center/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.oneliner-fab-text\s*\{[\s\S]*display:\s*none/);
});
test("mobile action sheets and oneliner runtime behave like bottom sheets", () => {
assert.match(APP, /class="sheet-handle"/);
assert.match(APP, /document\.body\.classList\.add\("sheet-open", "auth-sheet-open"\)/);
assert.match(APP, /document\.body\.classList\.remove\("sheet-open", "auth-sheet-open"\)/);
assert.match(APP, /document\.body\.classList\.add\("sheet-open", "action-sheet-open"\)/);
assert.match(APP, /document\.body\.classList\.remove\("sheet-open", "action-sheet-open"\)/);
assert.match(APP, /document\.body\.classList\.add\("sheet-open", "oneliner-open"\)/);
assert.match(APP, /document\.body\.classList\.remove\("sheet-open", "oneliner-open"\)/);
assert.match(CSS, /\.sheet-handle\s*\{/);
assert.match(CSS, /\.sheet-open \.mobile-tabbar\s*\{[\s\S]*opacity:\s*0/);
assert.match(CSS, /\.oneliner-open \.oneliner-fab\s*\{[\s\S]*opacity:\s*0/);
assert.match(CSS, /body\.sheet-open,\s*body\.mobile-sidebar-open\s*\{[\s\S]*overflow:\s*hidden/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.auth-modal,\s*[\s\S]*\.action-modal,\s*[\s\S]*\.oneliner-panel\s*\{[\s\S]*border-radius:\s*24px 24px 0 0/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.auth-actions\s*\{[\s\S]*position:\s*sticky/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.oneliner-composer\s*\{[\s\S]*position:\s*sticky/);
});
test("opening OneLiner clears the transient loading state after the panel is hydrated", () => {
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(actions, /name === "open-oneliner"[\s\S]*setBusy\(true,\s*"正在打开 OneLiner\.\.\."\)/);
assert.match(actions, /name === "open-oneliner"[\s\S]*finally \{[\s\S]*setBusy\(false,\s*""\);[\s\S]*renderAll\(\);[\s\S]*\}/);
});
test("project creation and switching use in-app sheets instead of browser prompts", () => {
const createProject = extractBetween(APP, "async function createProject()", "function openPreferredModelAction()");
const projectSwitcher = extractBetween(APP, "function openDashboardProjectSwitcher()", "function openDashboardActionReasonAction(");
assert.match(createProject, /openActionModal\(\{/);
assert.doesNotMatch(createProject, /window\.prompt/);
assert.doesNotMatch(createProject, /alert\(/);
assert.match(projectSwitcher, /type: "html"/);
assert.match(projectSwitcher, /最近任务/);
assert.match(projectSwitcher, /切换到这个项目/);
});
test("mobile project sheets support direct project picking and zoom-safe form controls", () => {
const projectSwitcher = extractBetween(APP, "function openDashboardProjectSwitcher()", "function openDashboardActionReasonAction(");
const applySelectedProject = extractBetween(APP, "async function applySelectedProject(projectId = \"\")", "function openDashboardProjectSwitcher()");
const clickHandler = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
const createProject = extractBetween(APP, "async function createProject()", "function openPreferredModelAction()");
assert.match(APP, /async function applySelectedProject\(projectId = ""\)/);
assert.match(APP, /function focusDashboardWorkspace\(anchorId = "dashboard-workspace-anchor"\)/);
assert.match(projectSwitcher, /data-project-choice=/);
assert.match(projectSwitcher, /hidden:\s*isMobileViewport/);
assert.match(projectSwitcher, /onOpen:\s*\(/);
assert.match(projectSwitcher, /select\.value = nextProjectId/);
assert.match(projectSwitcher, /window\.matchMedia\?\.\("\(max-width: 760px\)"\)\?\.matches/);
assert.match(projectSwitcher, /submit\.hidden = true/);
assert.match(projectSwitcher, /closeActionModal\(\);/);
assert.match(projectSwitcher, /await applySelectedProject\(nextProjectId\);/);
assert.match(APP, /if \(field\.hidden\) \{\s*return "";/);
assert.match(applySelectedProject, /loadStorageStatus\(appState\.selectedProjectId \|\| ""\)/);
assert.match(applySelectedProject, /loadAgentControlSurfaces\(appState\.selectedProjectId \|\| ""\)/);
assert.match(applySelectedProject, /focusDashboardWorkspace\("dashboard-workspace-anchor"\)/);
assert.match(clickHandler, /name === "select-project"[\s\S]*await applySelectedProject\(action\.dataset\.projectId \|\| ""\)/);
assert.match(APP, /id="dashboard-workspace-anchor"/);
assert.match(createProject, /onOpen:\s*\(/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.field-stack input,\s*[\s\S]*\.field-stack textarea,\s*[\s\S]*\.field-stack select\s*\{[\s\S]*min-height:\s*46px/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.field-stack input,\s*[\s\S]*\.field-stack textarea,\s*[\s\S]*\.field-stack select\s*\{[\s\S]*font-size:\s*16px/);
});
test("mobile touch targets raise tappable buttons, tabs, and action tags closer to native sizes", () => {
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.btn,\s*[\s\S]*\.tab,\s*[\s\S]*\.tag\.clickable-tag\s*\{[\s\S]*min-height:\s*44px/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.btn,\s*[\s\S]*\.tab,\s*[\s\S]*\.tag\.clickable-tag\s*\{[\s\S]*display:\s*inline-flex/);
});
test("mobile compact summaries scroll horizontally instead of stacking into a second row", () => {
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.compact-summary-row\s*\{[\s\S]*flex-wrap:\s*nowrap/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.compact-summary-row\s*\{[\s\S]*overflow-x:\s*auto/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.compact-summary-row::-webkit-scrollbar\s*\{[\s\S]*display:\s*none/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.compact-summary-row \.tag\s*\{[\s\S]*flex:\s*0 0 auto/);
});
test("action tags render interactive controls as buttons instead of passive spans", () => {
const actionTagSource = extractBetween(APP, "function actionTag(", "function renderPipelineButton(");
assert.match(actionTagSource, /if \(targetAction\) \{/);
assert.match(actionTagSource, /<button/);
assert.match(actionTagSource, /type="button"/);
assert.match(actionTagSource, /<span/);
});
test("mobile screen heads split the first action into a primary rail and keep the rest in a secondary strip", () => {
assert.match(APP, /function splitPrimaryAction\(actionsHtml\)/);
assert.match(APP, /class="action-row-primary"/);
assert.match(APP, /class="action-row-secondary"/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.action-row\s*\{[\s\S]*display:\s*grid/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.action-row-primary\s+\.btn\s*\{[\s\S]*width:\s*100%/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.action-row-secondary\s*\{[\s\S]*overflow-x:\s*auto/);
});
test("mobile screens with a focus card collapse the secondary action rail", () => {
assert.match(APP, /const hasMobileFocusCard = body\.includes\("mobile-flow-focus-card"\)/);
assert.match(APP, /screen-head-has-mobile-focus/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.screen-head\.screen-head-has-mobile-focus \.action-row-secondary\s*\{[\s\S]*display:\s*none/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.screen-head\.screen-head-has-mobile-focus p\s*\{[\s\S]*-webkit-line-clamp:\s*1/);
});
test("mobile bottom navigation stays highlighted for grouped related screens", () => {
assert.match(APP, /function getMobileTabGroup\(screenId = appState\.screen\)/);
assert.match(APP, /tracking:\s*"discovery"/);
assert.match(APP, /review:\s*"production"/);
assert.match(APP, /strategy:\s*"playbook"/);
assert.match(APP, /credits:\s*"dashboard"/);
assert.match(APP, /button\.classList\.toggle\("is-active", active \|\| mobileGroupActive\)/);
});
test("detail tab buttons expose the active state for touch navigation", () => {
const detailTabs = extractBetween(APP, "function renderDetailTabs(stateKey, tabs) {", "function renderDiscoveryOverviewSection(");
assert.match(detailTabs, /aria-pressed="\$\{tab\.value === active \? "true" : "false"\}"/);
});
test("strategy navigation and screen are real routes", () => {
assert.match(HTML, /data-screen-target="strategy"/);
assert.match(HTML, /data-screen="strategy"/);
assert.match(APP, /function renderStrategyScreen\(/);
assert.match(APP, /screenMap\.strategy\.innerHTML = renderStrategyScreen\(\);/);
});
test("strategy screen exposes a compact mobile summary for current governance state", () => {
const source = extractBetween(APP, "function renderStrategyScreen()", "function renderCreditsScreen()");
assert.match(source, /mobile-only compact-summary-row/);
assert.match(source, /mobile-only mobile-flow-focus-card/);
assert.match(source, /当前策略任务/);
assert.match(source, /当前生效/);
assert.match(source, /平台策略/);
});
test("automation screen stays user-facing and excludes admin-only panels", () => {
const source = extractBetween(APP, "function renderAutomationScreen()", "function renderOwnedScreen()");
assert.doesNotMatch(source, /renderTenantQuotaPanel\(/);
assert.doesNotMatch(source, /renderOneLinerActionRegistryPanel\(/);
assert.doesNotMatch(source, /renderAdminOpsPanel\(/);
assert.match(source, /renderDetailTabs\("automationDetailTab"/);
});
test("agent screen excludes quota and registry panels and uses page tabs", () => {
const source = extractBetween(APP, "function renderPlaybookScreen()", "function renderProductionScreen()");
assert.doesNotMatch(source, /renderTenantQuotaPanel\(/);
assert.doesNotMatch(source, /renderOneLinerActionRegistryPanel\(/);
assert.match(source, /renderDetailTabs\("playbookDetailTab"/);
assert.match(source, /mobile-only compact-summary-row/);
assert.match(source, /mobile-only mobile-flow-focus-card/);
assert.match(source, /当前 Agent 任务/);
assert.match(source, /renderGovernanceSummaryCard\(/);
assert.match(source, /open-user-global-policy/);
assert.match(source, /open-user-platform-policy/);
assert.match(source, /active_admin_override_notice/);
});
test("discovery, production, and admin screens use page tabs for heavy content", () => {
const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()");
const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");
const admin = extractBetween(APP, "function renderAdminWorkbenchScreen()", "function renderDashboardScreen()");
const strategy = extractBetween(APP, "function renderStrategyScreen()", "function renderCreditsScreen()");
assert.match(discovery, /renderDetailTabs\("discoveryDetailTab"/);
assert.match(production, /renderDetailTabs\("productionDetailTab"/);
assert.match(admin, /renderDetailTabs\("adminWorkbenchTab"/);
assert.match(admin, /renderAdminGovernanceSummaryPanel\(/);
assert.match(admin, /覆盖与审计/);
assert.match(strategy, /renderDetailTabs\("strategyDetailTab"/);
assert.match(strategy, /renderPolicyAuditFeed\(/);
});
test("governance and quota panels use real empty-state language instead of backend-sync placeholders", () => {
const actionRegistry = extractBetween(APP, "function renderOneLinerActionRegistryPanel()", "function renderTenantQuotaPanel()");
const tenantQuota = extractBetween(APP, "function renderTenantQuotaPanel()", "function policyScopeTagLabel(");
const platformAgents = extractBetween(APP, "function renderPlatformAgentPanel()", "function renderTrackingScreen()");
assert.doesNotMatch(actionRegistry, /等 <code>\/v2\/oneliner\/action-registry<\/code> 可用后/);
assert.match(actionRegistry, /当前项目还没有单独动作配置/);
assert.doesNotMatch(tenantQuota, /等 live collector 同步 `\/v2\/tenant\/quota` 和 `\/v2\/tenant\/usage` 后/);
assert.match(tenantQuota, /当前项目还没有额度配置/);
assert.match(tenantQuota, /data-action="open-tenant-quota"/);
assert.doesNotMatch(platformAgents, /等 live collector 同步 `\/v2\/platform-agents` 后/);
assert.match(platformAgents, /当前项目还没有平台 Agent 配置/);
assert.match(platformAgents, /open-platform-agent-profile/);
});
test("platform agent surfaces recent execution feedback from main agent runs", () => {
const platformAgents = extractBetween(APP, "function renderPlatformAgentPanel()", "function renderAdminOpsPanel()");
const detail = extractBetween(APP, "async function openPlatformAgentDetailAction(platform)", "function openPlatformSkillReviewAction(platform, skillId, accepted)");
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(platformAgents, /recent_execution/);
assert.match(platformAgents, /最近执行/);
assert.match(platformAgents, /配置 v/);
assert.match(platformAgents, /open-oneliner-run-result/);
assert.match(platformAgents, /open-oneliner-run-context/);
assert.match(detail, /最近执行/);
assert.match(detail, /recent_execution/);
assert.match(detail, /open-oneliner-run-result/);
assert.match(detail, /open-oneliner-run-context/);
assert.match(actions, /name === "open-oneliner-run-context"[\s\S]*openOneLinerRunContextAction/);
});
test("quota and review screens foreground live next-step guidance", () => {
const tenantQuota = extractBetween(APP, "function renderTenantQuotaPanel()", "function policyScopeTagLabel(");
const credits = extractBetween(APP, "function renderCreditsScreen()", "function renderSettingsScreen()");
const quotaAction = extractBetween(APP, "function openTenantQuotaAction()", "function openCreateAssistantAction()");
const review = extractBetween(APP, "function renderReviewScreen()", "function renderStrategyScreen()");
const storage = extractBetween(APP, "function renderStorageStatusPanel()", "function renderAutomationScreen()");
assert.match(tenantQuota, /先处理存储超限|先恢复额度保护|先补项目额度策略|先检查本周期消耗|先跑出第一条计量/);
assert.match(tenantQuota, /主要消耗/);
assert.match(tenantQuota, /周期 /);
assert.match(tenantQuota, /计量 /);
assert.doesNotMatch(review, /复盘能力暂未接入|还缺 \/v2\/reviews/);
assert.match(review, /先把最近完成任务写成复盘|先回看高频结论|先跑出第一条可复盘任务/);
assert.match(review, /高频结论/);
assert.match(review, /已发布/);
assert.doesNotMatch(storage, /后端暂未提供 \/v2\/storage\/status/);
assert.match(storage, /当前实例没有返回存储策略时/);
assert.doesNotMatch(credits, /后续再接真实套餐/);
assert.match(credits, /按项目阶段配置套餐/);
assert.match(credits, /预算、动作池和项目阶段绑定成正式套餐/);
assert.match(tenantQuota, /套餐档位/);
assert.match(tenantQuota, /预警阈值|预警 80%/);
assert.match(APP, /const TENANT_QUOTA_PACKAGE_PRESETS =/);
assert.match(APP, /function renderTenantQuotaPackagePreview/);
assert.match(quotaAction, /renderTenantQuotaPackagePreview/);
assert.match(APP, /预设已锁定|支持自定义/);
assert.match(quotaAction, /input\.disabled = Boolean\(preset\)/);
assert.match(quotaAction, /name: "packageLabel"/);
assert.match(quotaAction, /name: "warnThreshold"/);
assert.match(quotaAction, /package_label/);
assert.match(quotaAction, /warn_threshold/);
});
test("tracking refresh and top-video analysis flows expose async feedback inside the workbench", () => {
const tracking = extractBetween(APP, "function renderTrackingScreen()", "function renderAutomationScreen()");
const discovery = extractBetween(APP, "function renderDiscoveryOverviewSection(", "function renderDiscoveryRelationsSection(");
const accountWorkspaceLoad = extractBetween(APP, "async function loadPlatformAccount(", "async function bootstrap()");
const bootstrapSource = extractBetween(APP, "async function bootstrap()", "async function markTrackingDigestRead()");
const oneLinerHydrate = extractBetween(APP, "async function hydrateSelectedOneLinerRun()", "async function loadAgentControlSurfaces(");
const controlSurfaces = extractBetween(APP, "async function loadAgentControlSurfaces(", "async function loadOneLinerMessages(");
const oneLinerMessages = extractBetween(APP, "async function loadOneLinerMessages(", "async function ensureOneLinerSession(");
const trackingActions = extractBetween(APP, "async function markTrackingDigestRead()", "function createEmptyTrackingDigest(");
const oneLinerSession = extractBetween(APP, "async function ensureOneLinerSession()", "async function submitOneLinerMessage(");
const oneLinerRun = extractBetween(APP, "async function createOneLinerRun(", "async function confirmOneLinerRun(");
const oneLinerAction = extractBetween(APP, "async function executeOneLinerAction(", "function openCurrentOneLinerRunResultAction(");
const skillReview = extractBetween(APP, "function openPlatformSkillReviewAction(", "function openPlatformSkillRollbackAction(");
const agentDetail = extractBetween(APP, "async function openPlatformAgentDetailAction(", "function openPlatformSkillReviewAction(");
const topVideoAction = extractBetween(APP, "function openAnalyzeTopVideosAction()", "function openSimilaritySearchAction()");
const jobRecoverability = extractBetween(APP, "function getJobRecoverability(job) {", "function getJobRecoveryRequest(job) {");
const recoveryAction = extractBetween(APP, "async function recoverJobAction(", "function getRecoverableFailedJobs()");
const clickActions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(APP, /function summarizeTrackingRefreshPayload\(/);
assert.match(APP, /function rememberTrackingRefreshNotice\(/);
assert.match(APP, /function isMissingBackendCapability\(/);
assert.match(tracking, /批量同步已排队|单账号同步已排队|后台同步状态/);
assert.match(tracking, /去生产中心/);
assert.doesNotMatch(tracking, /这套后端还没有接入.*跟踪接口/);
assert.match(APP, /function getSelectedTopVideoAnalysisResult\(/);
assert.match(discovery, /最近高分拆解/);
assert.match(discovery, /这批结果已经回流到当前账号页/);
assert.doesNotMatch(trackingActions, /.*|.*|.*/s);
assert.doesNotMatch(accountWorkspaceLoad, /supportsAccountVideos|supportsAccountSnapshots|supportsCreatorFields|supportsAnalysisReports/);
assert.ok(!bootstrapSource.includes('backendSupports("/v2/integrations/health")'));
assert.ok(!bootstrapSource.includes('backendSupports("/v2/live-recorder/sources")'));
assert.ok(!oneLinerHydrate.includes('backendSupports("/v2/oneliner/runs/{run_id}")'));
assert.ok(!oneLinerMessages.includes('backendSupports("/v2/oneliner/sessions/{session_id}/messages")'));
assert.ok(!controlSurfaces.includes('backendSupports("/v2/oneliner/profile")'));
assert.ok(!controlSurfaces.includes('backendSupports("/v2/platform-agents")'));
assert.doesNotMatch(oneLinerSession, /当前后端还没有接入 OneLiner 会话接口/);
assert.doesNotMatch(oneLinerRun, /当前后端还没有接入主 Agent 运行层/);
assert.doesNotMatch(oneLinerAction, /当前后端还没有接入 OneLiner 动作执行器/);
assert.doesNotMatch(skillReview, /当前后端还没有接入平台技能验收接口/);
assert.ok(!agentDetail.includes('backendSupports("/v2/platform-agents/{platform}/skills/{skill_id}/versions")'));
assert.doesNotMatch(topVideoAction, /.*/s);
assert.doesNotMatch(topVideoAction, /当前实例未提供/);
assert.doesNotMatch(jobRecoverability, /暂时无法自动恢复/);
assert.doesNotMatch(jobRecoverability, /当前链路没有可自动恢复的模板/);
assert.ok(!jobRecoverability.includes('backendSupports("/v2/explore/jobs/{job_id}/retry") && uploadedPath'));
assert.doesNotMatch(recoveryAction, /暂不支持自动恢复|暂不支持恢复/);
assert.ok(!recoveryAction.includes('if (backendSupports("/v2/explore/jobs/{job_id}/retry"))'));
assert.ok(!clickActions.includes('else if (backendSupports("/v2/oneliner/sessions"))'));
});
test("discovery and production screens expose compact mobile flow summaries", () => {
const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()");
const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");
assert.match(discovery, /mobile-only compact-summary-row/);
assert.match(discovery, /当前对标/);
assert.match(discovery, /已接入/);
assert.match(production, /mobile-only compact-summary-row/);
assert.match(production, /处理中/);
assert.match(production, /失败/);
});
test("workbench copy uses direct live language instead of future-placeholder wording", () => {
assert.doesNotMatch(APP, /可选,不填则后续再补/);
assert.match(APP, /可选,可先留空,后面随时补充/);
assert.match(APP, /文案生成、对标绑定和复盘都会优先使用这里选中的 Agent/);
assert.match(APP, /导入分析、市场调研和风格学习都会优先使用这里设置的模型/);
assert.match(APP, /系统会自动生成更新日报/);
assert.match(APP, /把完成任务写成一条可追踪复盘,可按项目累计/);
assert.match(APP, /先绑定执行 Agent再完善任务目标和方法论/);
assert.match(APP, /先看真实作品,再继续整理文档与成片/);
assert.match(APP, /等待配置探测地址/);
});
test("discovery and production screens expose mobile focus cards with next-step actions", () => {
const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()");
const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");
const cssMobile = extractBetween(CSS, "@media (max-width: 760px) {", "@media (max-width: 560px) {");
assert.match(discovery, /mobile-only mobile-flow-focus-card/);
assert.match(discovery, /class="filters mobile-priority-filters"/);
assert.match(discovery, /下一步先做/);
assert.match(discovery, /导入当前对标/);
assert.match(discovery, /查相似/);
assert.match(production, /mobile-only mobile-flow-focus-card/);
assert.match(APP, /function renderProductionMobileTaskDeck\(/);
assert.match(APP, /mobile-only production-mobile-task-deck/);
assert.match(APP, /当前要先处理/);
assert.match(production, /当前工作流/);
assert.match(production, /批量恢复/);
assert.match(cssMobile, /\.mobile-flow-focus-card/);
assert.match(cssMobile, /\.production-mobile-task-deck/);
});
test("mobile discovery and production simplify duplicated top-level actions", () => {
const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()");
const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");
assert.match(APP, /function isMobileViewport\(\)/);
assert.match(discovery, /const isMobileUi = isMobileViewport\(\);/);
assert.match(discovery, /const discoveryActionsHtml = isMobileUi/);
assert.match(discovery, /button\("导入主页", "open-import-homepage"\)/);
assert.match(discovery, /button\("存对标", "open-benchmark-link"/);
assert.match(production, /const isMobileUi = isMobileViewport\(\);/);
assert.match(production, /const productionActionsHtml = isMobileUi/);
assert.match(production, /button\("交给主 Agent", "handoff-to-main-agent"/);
assert.match(production, /button\("去复盘", "goto-review", "primary"\)/);
});
test("mobile discovery prioritizes the selected-account task flow before the scrollable account list", () => {
const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()");
assert.match(discovery, /mobile-discovery-priority/);
assert.match(discovery, /mobile-discovery-selected-summary/);
assert.match(discovery, /mobile-account-list/);
assert.match(discovery, /mobile-discovery-priority[\s\S]*mobile-account-list/);
});
test("mobile heavy screens mark redundant desktop metric blocks for compact hiding", () => {
const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()");
const tracking = extractBetween(APP, "function renderTrackingScreen()", "function renderAutomationScreen()");
const automation = extractBetween(APP, "function renderAutomationScreen()", "function renderOwnedScreen()");
const owned = extractBetween(APP, "function renderOwnedScreen()", "function renderPlaybookScreen()");
const projects = extractBetween(APP, "function renderProjectsScreen()", "function getActiveDetailTab(");
const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");
const review = extractBetween(APP, "function renderReviewScreen()", "function renderStrategyScreen()");
const playbook = extractBetween(APP, "function renderPlaybookScreen()", "function renderProductionScreen()");
const strategy = extractBetween(APP, "function renderStrategyScreen()", "function renderCreditsScreen()");
const cssMobile = extractBetween(CSS, "@media (max-width: 760px) {", "@media (max-width: 560px) {");
assert.match(discovery, /discovery-selected-hero mobile-secondary-card/);
assert.match(tracking, /hero-card mobile-secondary-card/);
assert.match(automation, /hero-card mobile-secondary-card/);
assert.match(owned, /hero-card mobile-secondary-card/);
assert.match(projects, /hero-card mobile-secondary-card/);
assert.match(production, /production-queue-grid/);
assert.match(review, /hero-card mobile-secondary-card/);
assert.match(playbook, /hero-card mobile-secondary-card/);
assert.match(strategy, /hero-card mobile-secondary-card/);
assert.match(cssMobile, /\.discovery-selected-hero \.mini-grid/);
assert.match(cssMobile, /\.production-queue-grid/);
assert.match(cssMobile, /\.mobile-priority-filters \.filter:nth-child\(n\+3\)/);
assert.match(cssMobile, /\.mobile-secondary-card/);
});
test("remaining mobile workbench screens expose focus cards and compact summaries", () => {
const projects = extractBetween(APP, "function renderProjectsScreen()", "function getActiveDetailTab(");
const tracking = extractBetween(APP, "function renderTrackingScreen()", "function renderAutomationScreen()");
const automation = extractBetween(APP, "function renderAutomationScreen()", "function renderOwnedScreen()");
const owned = extractBetween(APP, "function renderOwnedScreen()", "function renderPlaybookScreen()");
const review = extractBetween(APP, "function renderReviewScreen()", "function renderStrategyScreen()");
const credits = extractBetween(APP, "function renderCreditsScreen()", "function renderSettingsScreen()");
const settings = extractBetween(APP, "function renderSettingsScreen()", "function renderTopbar()");
assert.match(projects, /mobile-only mobile-flow-focus-card/);
assert.match(projects, /当前项目任务/);
assert.match(projects, /mobile-only compact-summary-row/);
assert.match(projects, /当前项目/);
assert.match(tracking, /mobile-only mobile-flow-focus-card/);
assert.match(tracking, /当前跟踪任务/);
assert.match(tracking, /mobile-only compact-summary-row/);
assert.match(tracking, /日报/);
assert.match(automation, /mobile-only mobile-flow-focus-card/);
assert.match(automation, /当前自动流程任务/);
assert.match(automation, /mobile-only compact-summary-row/);
assert.match(automation, /AI 视频/);
assert.match(owned, /mobile-only mobile-flow-focus-card/);
assert.match(owned, /当前账号任务/);
assert.match(owned, /mobile-only compact-summary-row/);
assert.match(owned, /当前项目/);
assert.match(review, /mobile-only mobile-flow-focus-card/);
assert.match(review, /当前复盘任务/);
assert.match(review, /mobile-only compact-summary-row/);
assert.match(review, /已保存/);
assert.match(credits, /mobile-only mobile-flow-focus-card/);
assert.match(credits, /当前额度任务/);
assert.match(credits, /mobile-only compact-summary-row/);
assert.match(credits, /预算/);
assert.match(settings, /mobile-only mobile-flow-focus-card/);
assert.match(settings, /当前设置任务/);
assert.match(settings, /mobile-only compact-summary-row/);
assert.match(settings, /已自动连接/);
});
test("projects screen uses an adaptive project grid instead of a fixed three-column squeeze", () => {
const projects = extractBetween(APP, "function renderProjectsScreen()", "function getActiveDetailTab(");
assert.match(projects, /project-status-grid/);
assert.match(CSS, /\.project-status-grid\s*\{[\s\S]*repeat\(auto-fit,\s*minmax\(260px,\s*1fr\)\)/);
assert.match(CSS, /\.entity-card\.pad\s*\{[\s\S]*padding:\s*15px/);
});
test("ai video action exposes seedance provider controls and sends provider metadata", () => {
const source = extractBetween(APP, "function openCreateAiVideoAction(defaults = {})", "function openCreateRealCutAction(");
assert.match(source, /视频引擎/);
assert.match(source, /seedance2/);
assert.match(source, /seedance-2\.0-pro/);
assert.match(source, /cameraLanguage/);
assert.match(source, /motionRhythm/);
assert.match(source, /visualGuardrails/);
assert.match(source, /video_provider:\s*values\.videoProvider/);
assert.match(source, /video_model:\s*values\.videoModel/);
});
test("mobile typography clamps subtitles and dense card copy on small screens", () => {
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.panel-subtitle\s*\{[\s\S]*-webkit-line-clamp:\s*2/);
assert.match(CSS, /@media \(max-width: 760px\)[\s\S]*\.task-item p,[\s\S]*\.review-card p\s*\{[\s\S]*-webkit-line-clamp:\s*3/);
});
test("dashboard and project screens distinguish auto-connecting from truly disconnected", () => {
const dashboard = extractBetween(APP, "function renderDashboardScreen()", "function renderProjectsScreen()");
const projects = extractBetween(APP, "function renderProjectsScreen()", "function getActiveDetailTab(");
const helper = extractBetween(APP, "function isAutoConnectionPending()", "async function refreshFromAuthModal()");
assert.match(APP, /function isAutoConnectionPending\(\)/);
assert.match(APP, /function renderAutoConnectingScreen\(/);
assert.match(helper, /正在自动连接工作区/);
assert.match(dashboard, /isAutoConnectionPending\(\)/);
assert.match(dashboard, /renderAutoConnectingScreen\("项目总台"/);
assert.match(projects, /isAutoConnectionPending\(\)/);
assert.match(projects, /renderAutoConnectingScreen\("我的项目"/);
});
test("ensureAutoSession re-renders immediately when auto-connect starts", () => {
const source = extractBetween(APP, "async function ensureAutoSession(options = {})", "async function refreshFromAuthModal()");
assert.match(source, /appState\.autoConnectAttempted = true;/);
assert.match(source, /renderAll\(\);/);
});
test("bootstrap does not trust a stored session from a different backend", () => {
const helpers = extractBetween(APP, "function loadStoredSession()", "function compareDateDesc(");
const ensure = extractBetween(APP, "async function ensureAutoSession(options = {})", "async function refreshFromAuthModal()");
const bootstrap = extractBetween(APP, "async function bootstrap()", "async function markTrackingDigestRead()");
assert.match(helpers, /function normalizeBackendUrlValue\(/);
assert.match(helpers, /function hasSessionBackendMismatch\(/);
assert.match(ensure, /const backendMismatch = hasSessionBackendMismatch\(backendUrl\);/);
assert.match(ensure, /persistSession\(null\);/);
assert.match(bootstrap, /const backendMismatch = hasSessionBackendMismatch\(\);/);
assert.match(bootstrap, /await ensureAutoSession\(\{ force: backendMismatch \}\);/);
});
test("bootstrap only loads live recorder runtime endpoints when the integration is reachable", () => {
const bootstrap = extractBetween(APP, "async function bootstrap()", "async function markTrackingDigestRead()");
assert.match(bootstrap, /const liveRecorderIntegration = integrationHealth\?\.live_recorder \|\| null/);
assert.match(bootstrap, /const canLoadLiveRecorderRuntime = Boolean\(liveRecorderIntegration\?\.reachable\)/);
assert.doesNotMatch(bootstrap, /supportsLiveRecorderStatus|supportsLiveRecorderFiles|supportsLiveRecorderHealth/);
assert.match(bootstrap, /canLoadLiveRecorderRuntime \? storyforgeFetch\("\/v2\/live-recorder\/status"\)/);
assert.match(bootstrap, /canLoadLiveRecorderRuntime \? storyforgeFetch\("\/v2\/live-recorder\/files\?limit=16"\)/);
assert.match(bootstrap, /canLoadLiveRecorderRuntime \? storyforgeFetch\("\/v2\/live-recorder\/health"\)/);
});
test("oneliner submit failures stay inside the app instead of using a browser alert", () => {
assert.doesNotMatch(APP, /alert\("OneLiner 调度失败:/);
assert.match(APP, /presentActionFailure\(error,\s*"OneLiner 调度失败"\)/);
});
test("agent control surfaces load governance endpoints for user and admin summaries", () => {
const source = extractBetween(APP, "async function loadAgentControlSurfaces(projectId = \"\")", "async function loadOneLinerMessages(sessionId)");
assert.match(source, /\/v2\/oneliner\/governance\/effective/);
assert.match(source, /\/v2\/oneliner\/runs/);
assert.match(APP, /function hydrateSelectedOneLinerRun\(\)/);
assert.match(APP, /\/v2\/oneliner\/runs\/\$\{encodeURIComponent\(runId\)\}/);
assert.match(source, /\/v2\/oneliner\/governance\/user\/global/);
assert.match(source, /\/v2\/oneliner\/governance\/user\/platforms\/\$\{encodeURIComponent\(governancePlatform\)\}/);
assert.match(source, /\/v2\/admin\/oneliner\/governance\/system\/main-agent/);
assert.match(source, /\/v2\/admin\/oneliner\/governance\/system\/platforms\/\$\{encodeURIComponent\(item\.value\)\}/);
assert.match(source, /\/v2\/admin\/oneliner\/governance\/directory/);
assert.match(source, /\/v2\/admin\/oneliner\/governance\/overrides/);
assert.match(source, /Object\.prototype\.hasOwnProperty\.call\(existingTarget, "targetProjectId"\)/);
assert.match(source, /const requestedProjectId = hasExistingProjectTarget/);
assert.match(source, /const targetProjectId = requestedProjectId === ""/);
});
test("oneliner panel includes a dedicated runtime header for agent runs", () => {
const source = extractBetween(APP, "function ensureOneLinerUi()", "function renderOneLinerSessionTabs()");
const runtime = extractBetween(APP, "function renderOneLinerRunsHtml()", "function renderOneLinerMessagesHtml()");
assert.match(source, /data-role="oneliner-runs"/);
assert.match(runtime, /confirm-oneliner-run/);
assert.match(runtime, /cancel-oneliner-run/);
assert.match(runtime, /当前计划/);
assert.match(runtime, /recommended_preview_action/);
assert.match(runtime, /renderOneLinerExecutionPayloadHtml\(currentRun\.result\)/);
assert.match(runtime, /open-oneliner-run-result/);
assert.match(runtime, /recommended_action/);
});
test("confirm-oneliner-run opens a dedicated confirmation sheet before execution", () => {
const confirmSheet = extractBetween(APP, "function openConfirmOneLinerRunAction(runId = \"\")", "async function loadPlatformAccount(");
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(confirmSheet, /确认主 Agent 执行计划/);
assert.match(confirmSheet, /当前计划/);
assert.match(confirmSheet, /预计落点/);
assert.match(confirmSheet, /submitLabel: "确认执行"/);
assert.match(confirmSheet, /reason/);
assert.match(confirmSheet, /confirmOneLinerRun\(run\.id,\s*values\.reason/);
assert.match(actions, /openConfirmOneLinerRunAction\(action\.dataset\.runId \|\| ""\)/);
});
test("oneliner meta and action handlers expose governance entry points", () => {
const meta = extractBetween(APP, "function renderOneLinerUi()", "function openOneLinerPanel()");
const messages = extractBetween(APP, "function renderOneLinerMessagesHtml()", "function renderOneLinerUi()");
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
const runs = extractBetween(APP, "function renderOneLinerRunsHtml()", "function renderOneLinerMessagesHtml()");
assert.match(meta, /open-user-global-policy/);
assert.match(meta, /配置 v/);
assert.match(meta, /renderOneLinerRunsHtml\(\)/);
assert.match(meta, /policyScopeTagLabel/);
assert.match(messages, /active_admin_override_notice/);
assert.match(messages, /oneliner_profile_version/);
assert.match(runs, /oneliner_profile_version/);
assert.match(runs, /open-oneliner-profile-history/);
assert.match(actions, /name === "open-user-global-policy"/);
assert.match(actions, /name === "open-system-main-policy"/);
assert.match(actions, /name === "handoff-to-main-agent"/);
assert.match(actions, /name === "confirm-oneliner-run"/);
assert.match(actions, /name === "open-oneliner-run-result"/);
});
test("oneliner runtime remembers completed runs exactly once after hydration", () => {
const hydrate = extractBetween(APP, "async function hydrateSelectedOneLinerRun()", "async function loadAgentControlSurfaces(projectId = \"\")");
const state = extractBetween(APP, "const appState = {", "};\n\nlet PLATFORM_RUNTIME");
assert.match(state, /lastCompletedOnelinerRunId/);
assert.match(hydrate, /detail\.run_status === "done"/);
assert.match(hydrate, /appState\.lastCompletedOnelinerRunId !== detail\.id/);
assert.match(hydrate, /rememberAction\("主 Agent 已完成本轮"/);
});
test("system governance saves refresh control surfaces after persisting", () => {
const profile = extractBetween(APP, "function openOneLinerProfileAction()", "async function openOneLinerProfileHistoryAction(preferredVersionId = \"\")");
const userGlobal = extractBetween(APP, "function openUserGlobalPolicyAction()", "function openUserPlatformPolicyAction(platform)");
const userPlatform = extractBetween(APP, "function openUserPlatformPolicyAction(platform)", "function openSystemMainPolicyAction()");
const main = extractBetween(APP, "function openSystemMainPolicyAction()", "function openSystemPlatformPolicyAction(platform)");
const platform = extractBetween(APP, "function openSystemPlatformPolicyAction(platform)", "function openPlatformAgentProfileAction(platform)");
assert.match(profile, /renderPolicyVersionSummary\(profile/);
assert.match(profile, /name: "reason"/);
assert.match(profile, /appState\.onelinerProfile = saved;/);
assert.match(profile, /await loadAgentControlSurfaces\(project\.id\);/);
assert.match(profile, /saved\.current_version\?\.version_no/);
assert.match(userGlobal, /appState\.userGlobalPolicy = saved;/);
assert.match(userGlobal, /await loadAgentControlSurfaces\(project\.id\);/);
assert.match(userPlatform, /appState\.userCurrentPlatformPolicy = saved;/);
assert.match(userPlatform, /await loadAgentControlSurfaces\(project\.id\);/);
assert.match(main, /const projectId = getOneLinerProjectId\(\);/);
assert.match(main, /appState\.adminSystemMainPolicy = saved;/);
assert.match(main, /await loadAgentControlSurfaces\(projectId\);/);
assert.match(platform, /const projectId = getOneLinerProjectId\(\);/);
assert.match(platform, /appState\.adminSystemPlatformPolicies = safeArray\(appState\.adminSystemPlatformPolicies\)/);
assert.match(platform, /await loadAgentControlSurfaces\(projectId\);/);
});
test("oneliner profile history exposes rollback and audit entrypoints", () => {
const playbookFocusHelper = extractBetween(APP, "function focusPlaybookOneLinerWorkspace(anchorId = \"oneliner-profile-anchor\") {", "function openOneLinerProfileAction() {");
const profile = extractBetween(APP, "function openOneLinerProfileAction()", "function resolvePreferredVersionId(history, preferredVersionId = \"\")");
const profileHistory = extractBetween(APP, "async function openOneLinerProfileHistoryAction(preferredVersionId = \"\")", "function parsePolicyJsonField(rawValue, label = \"策略 JSON\")");
const playbook = extractBetween(APP, "function renderPlaybookScreen()", "function renderProductionScreen()");
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(playbookFocusHelper, /appState\.playbookDetailTab = "workspace"/);
assert.match(playbookFocusHelper, /setScreen\("playbook"\)/);
assert.match(playbookFocusHelper, /scrollIntoView/);
assert.match(profile, /focusPlaybookOneLinerWorkspace\("oneliner-profile-anchor"\)/);
assert.match(APP, /function resolvePreferredVersionId\(history, preferredVersionId = ""\)/);
assert.match(profileHistory, /\/v2\/oneliner\/profile\/versions/);
assert.match(profileHistory, /\/v2\/oneliner\/profile\/audits/);
assert.match(profileHistory, /\/v2\/oneliner\/profile\/rollback/);
assert.match(profileHistory, /resolvePreferredVersionId\(history, preferredVersionId\)/);
assert.match(profileHistory, /hideSubmit:\s*!selectedVersionId/);
assert.match(profileHistory, /focusPlaybookOneLinerWorkspace\("oneliner-profile-anchor"\)/);
assert.match(playbook, /open-oneliner-profile-history/);
assert.match(playbook, /id="oneliner-profile-anchor"/);
assert.match(actions, /name === "open-oneliner-profile-history"/);
assert.match(actions, /openOneLinerProfileHistoryAction\(action\.dataset\.versionId \|\| ""\)/);
});
test("governance UI exposes admin override target picker and history rollback entrypoints", () => {
const admin = extractBetween(APP, "function renderAdminGovernanceSummaryPanel()", "function renderPlatformAgentPanel()");
const targetPicker = extractBetween(APP, "async function openAdminOverrideTargetAction()", "function openAdminOverridePolicyAction()");
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(admin, /open-admin-override-target/);
assert.match(admin, /open-admin-override-policy/);
assert.match(admin, /open-admin-override-history/);
assert.match(admin, /open-system-main-policy-history/);
assert.match(admin, /open-system-platform-policy-history/);
assert.match(APP, /function syncAdminOverrideProjectOptions\(/);
assert.match(targetPicker, /onOpen: \(\) => \{/);
assert.match(targetPicker, /userSelect\.addEventListener\("change"/);
assert.match(targetPicker, /syncAdminOverrideProjectOptions\(userSelect\.value, ""\)/);
assert.match(actions, /name === "open-admin-override-target"/);
assert.match(actions, /name === "open-admin-override-policy"/);
assert.match(actions, /name === "open-admin-override-history"/);
assert.match(actions, /name === "open-system-main-policy-history"/);
assert.match(actions, /name === "open-system-platform-policy-history"/);
});
test("admin governance history actions stay read-only when there are no versions yet", () => {
const overrideHistory = extractBetween(APP, "async function openAdminOverrideHistoryAction(preferredVersionId = \"\")", "async function openSystemMainPolicyHistoryAction(preferredVersionId = \"\")");
const systemMainHistory = extractBetween(APP, "async function openSystemMainPolicyHistoryAction(preferredVersionId = \"\")", "async function openSystemPlatformPolicyHistoryAction(platform, preferredVersionId = \"\")");
const systemPlatformHistory = extractBetween(APP, "async function openSystemPlatformPolicyHistoryAction(platform, preferredVersionId = \"\")", "function openPlatformAgentProfileAction(platform)");
assert.match(overrideHistory, /hideSubmit:\s*!selectedVersionId/);
assert.match(systemMainHistory, /hideSubmit:\s*!selectedVersionId/);
assert.match(systemPlatformHistory, /hideSubmit:\s*!selectedVersionId/);
assert.match(overrideHistory, /\.\.\.\(selectedVersionId \? \[/);
assert.match(systemMainHistory, /\.\.\.\(selectedVersionId \? \[/);
assert.match(systemPlatformHistory, /\.\.\.\(selectedVersionId \? \[/);
});
test("admin governance actions apply local permission and empty-directory guards before mutating", () => {
const helpers = extractBetween(APP, "function ensureAdminGovernanceAccess()", "function openUserGlobalPolicyAction()");
const adminFocusHelper = extractBetween(APP, "function focusAdminGovernanceAgentsWorkspace(anchorId = \"admin-governance-anchor\") {", "function openSystemMainPolicyAction() {");
const targetPicker = extractBetween(APP, "async function openAdminOverrideTargetAction()", "function openAdminOverridePolicyAction()");
const systemMain = extractBetween(APP, "function openSystemMainPolicyAction()", "function openSystemPlatformPolicyAction(platform)");
const systemPlatform = extractBetween(APP, "function openSystemPlatformPolicyAction(platform)", "async function openAdminOverrideTargetAction()");
const systemMainHistory = extractBetween(APP, "async function openSystemMainPolicyHistoryAction(preferredVersionId = \"\")", "async function openSystemPlatformPolicyHistoryAction(platform, preferredVersionId = \"\")");
const systemPlatformHistory = extractBetween(APP, "async function openSystemPlatformPolicyHistoryAction(platform, preferredVersionId = \"\")", "function reopenPlatformAgentDetailSoon(platform)");
const actionRegistry = extractBetween(APP, "function openActionRegistryEditAction(actionKey)", "function openTenantQuotaAction()");
assert.match(helpers, /function ensureAdminGovernanceAccess\(\)/);
assert.match(helpers, /function ensureAdminOverrideTargetReady\(target\)/);
assert.match(adminFocusHelper, /appState\.adminWorkbenchTab = "agents"/);
assert.match(adminFocusHelper, /setScreen\("admin-workbench"\)/);
assert.match(adminFocusHelper, /scrollIntoView/);
assert.match(targetPicker, /hideSubmit:\s*!directoryItems\.length/);
assert.match(targetPicker, /focusAdminGovernanceAuditWorkspace\("admin-override-audit-anchor"\)/);
assert.match(systemMain, /if \(!ensureAdminGovernanceAccess\(\)\) return;/);
assert.match(systemPlatform, /if \(!ensureAdminGovernanceAccess\(\)\) return;/);
assert.match(systemMain, /focusAdminGovernanceAgentsWorkspace\("admin-governance-anchor"\)/);
assert.match(systemPlatform, /focusAdminGovernanceAgentsWorkspace\("admin-governance-anchor"\)/);
assert.match(systemMainHistory, /focusAdminGovernanceAgentsWorkspace\("admin-governance-anchor"\)/);
assert.match(systemPlatformHistory, /focusAdminGovernanceAgentsWorkspace\("admin-governance-anchor"\)/);
assert.match(actionRegistry, /focusAdminGovernanceAgentsWorkspace\("admin-action-registry-anchor"\)/);
});
test("user governance UI exposes personal history and rollback entrypoints", () => {
const helpers = extractBetween(APP, "function ensureAdminGovernanceAccess()", "function openSystemMainPolicyAction() {");
const playbook = extractBetween(APP, "function renderPlaybookScreen()", "function renderProductionScreen()");
const strategy = extractBetween(APP, "function renderStrategyScreen()", "function renderCreditsScreen()");
const automation = extractBetween(APP, "function renderAutomationScreen()", "function renderOwnedScreen()");
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
const userGlobal = extractBetween(APP, "function openUserGlobalPolicyAction()", "function openUserPlatformPolicyAction(platform) {");
const userPlatform = extractBetween(APP, "function openUserPlatformPolicyAction(platform)", "async function openUserGlobalPolicyHistoryAction(preferredVersionId = \"\")");
const userGlobalHistory = extractBetween(APP, "async function openUserGlobalPolicyHistoryAction(preferredVersionId = \"\")", "async function openUserPlatformPolicyHistoryAction(platform, preferredVersionId = \"\")");
const userPlatformHistory = extractBetween(APP, "async function openUserPlatformPolicyHistoryAction(platform, preferredVersionId = \"\")", "function focusAdminGovernanceAgentsWorkspace(anchorId = \"admin-governance-anchor\") {");
assert.match(helpers, /function focusUserGovernanceWorkspace\(tab = "effective", anchorId = "strategy-governance-anchor"\)/);
assert.match(helpers, /appState\.strategyDetailTab = tab/);
assert.match(helpers, /setScreen\("strategy"\)/);
assert.match(playbook, /open-user-global-policy-history/);
assert.match(playbook, /open-user-platform-policy-history/);
assert.match(playbook, /handoff-to-main-agent/);
assert.match(playbook, /playbook-main-agent-handoff/);
assert.match(strategy, /active_admin_override_notice/);
assert.match(strategy, /管理员覆盖生效中/);
assert.match(strategy, /handoff-to-main-agent/);
assert.match(strategy, /strategy-main-agent-handoff/);
assert.match(strategy, /id="strategy-governance-anchor"/);
assert.match(automation, /handoff-to-main-agent/);
assert.match(automation, /automation-main-agent-handoff/);
assert.match(userGlobal, /focusUserGovernanceWorkspace\("global", "strategy-governance-anchor"\)/);
assert.match(userPlatform, /focusUserGovernanceWorkspace\("platform", "strategy-governance-anchor"\)/);
assert.match(userGlobalHistory, /focusUserGovernanceWorkspace\("global", "strategy-governance-anchor"\)/);
assert.match(userPlatformHistory, /focusUserGovernanceWorkspace\("platform", "strategy-governance-anchor"\)/);
assert.match(actions, /name === "open-user-global-policy-history"/);
assert.match(actions, /name === "open-user-platform-policy-history"/);
});
test("admin override actions guard against missing governance targets", () => {
const override = extractBetween(APP, "function openAdminOverridePolicyAction()", "async function openAdminOverrideHistoryAction(preferredVersionId = \"\")");
const overrideHistory = extractBetween(APP, "async function openAdminOverrideHistoryAction(preferredVersionId = \"\")", "async function openSystemMainPolicyHistoryAction(preferredVersionId = \"\")");
const helpers = extractBetween(APP, "function ensureAdminGovernanceAccess()", "function openUserGlobalPolicyAction()");
assert.match(helpers, /function ensureAdminOverrideTargetReady\(target\)/);
assert.match(helpers, /当前治理目录里还没有可选用户/);
assert.match(helpers, /function focusAdminGovernanceAuditWorkspace\(anchorId = "admin-override-audit-anchor"\)/);
assert.match(override, /if \(!ensureAdminOverrideTargetReady\(target\)\) return;/);
assert.match(overrideHistory, /if \(!ensureAdminOverrideTargetReady\(target\)\) return;/);
assert.match(override, /focusAdminGovernanceAuditWorkspace\("admin-override-audit-anchor"\)/);
assert.match(overrideHistory, /focusAdminGovernanceAuditWorkspace\("admin-override-audit-anchor"\)/);
});
test("main agent result rendering offers a direct route back into the recommended screen", () => {
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
const lastAction = extractBetween(APP, "function renderLastActionCard()", "function getJobRecoveryCategory(job)");
const landing = extractBetween(APP, "function resolveMainAgentLandingScreen(target)", "function captureMainAgentLandingContext(action, targetScreen)");
assert.match(execution, /recommended_action/);
assert.match(execution, /result_sections/);
assert.match(execution, /当前焦点/);
assert.match(execution, /detail-grid/);
assert.match(execution, /本轮平台 Agent/);
assert.match(execution, /platform_agent_profile/);
assert.match(execution, /data-action="\$\{escapeHtml\(payload\.recommended_action\.action\)\}"/);
assert.match(lastAction, /open-oneliner-run-result/);
assert.match(lastAction, /recommended_action/);
assert.match(landing, /"goto-admin-workbench": "admin-workbench"/);
});
test("direct oneliner execution results preserve structured follow-up attrs", () => {
const helpers = extractBetween(APP, "function extractGeneratedCopy(payload)", "function renderLastActionCard()");
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
const lastAction = extractBetween(APP, "function renderLastActionCard()", "function getJobRecoveryCategory(job)");
assert.match(helpers, /function buildRecommendedActionAttrs\(recommendedAction, landing = \{\}\)/);
assert.match(helpers, /job_id: "data-job-id"/);
assert.match(helpers, /review_id: "data-review-id"/);
assert.match(helpers, /platform: "data-platform"/);
assert.match(helpers, /account_id: "data-account-id"/);
assert.match(helpers, /tracked_account_id: "data-tracked-account-id"/);
assert.match(helpers, /assistant_id: "data-assistant-id"/);
assert.match(helpers, /source_id: "data-source-id"/);
assert.match(execution, /const recommendedAction = payload\.recommended_action/);
assert.match(execution, /buildRecommendedActionAttrs\(recommendedAction/);
assert.match(execution, /actionTag\(recommendedAction\.label \|\| "看任务详情"/);
assert.match(execution, /actionTag\(recommendedAction\.label \|\| "打开复盘"/);
assert.match(execution, /actionTag\(recommendedAction\.label \|\| "打开录制控制"/);
assert.match(execution, /actionTag\(recommendedAction\.label \|\| "查看平台 Agent"/);
assert.match(lastAction, /buildRecommendedActionAttrs\(recommendedAction/);
assert.match(lastAction, /actionTag\(recommendedAction\.label \|\| "回到对应页面"/);
});
test("main agent runtime and platform recent execution preserve structured follow-up attrs", () => {
const runtime = extractBetween(APP, "function renderOneLinerRunsHtml()", "function renderOneLinerMessagesHtml()");
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
const playbook = extractBetween(APP, "function renderPlatformAgentPanel()", "function renderAdminOpsPanel()");
const detail = extractBetween(APP, "async function openPlatformAgentDetailAction(platform)", "function openPlatformSkillReviewAction(platform, skillId, accepted)");
assert.match(runtime, /const resultLandingAttrs = buildRecommendedActionAttrs\(recommendedAction/);
assert.match(runtime, /const doneLandingAttrs = buildRecommendedActionAttrs\(doneAction/);
assert.match(execution, /const landingAttrs = buildRecommendedActionAttrs\(payload\.recommended_action/);
assert.match(playbook, /buildRecommendedActionAttrs\(item\.recent_execution\.recommended_action/);
assert.match(detail, /buildRecommendedActionAttrs\(profile\.recent_execution\.recommended_action/);
});
test("platform agent profiles expose history, rollback, and execution version context", () => {
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
const reopenHelper = extractBetween(APP, "function reopenPlatformAgentDetailSoon(platform) {", "function openPlatformAgentProfileAction(platform) {");
const profileEditor = extractBetween(APP, "function openPlatformAgentProfileAction(platform)", "async function openPlatformAgentProfileHistoryAction(platform, preferredVersionId = \"\")");
const profileHistory = extractBetween(APP, "async function openPlatformAgentProfileHistoryAction(platform, preferredVersionId = \"\")", "function openPlatformAgentMemoryAction(platform)");
const memoryEditor = extractBetween(APP, "function openPlatformAgentMemoryAction(platform)", "function openPlatformAgentSkillAction(platform)");
const skillEditor = extractBetween(APP, "function openPlatformAgentSkillAction(platform)", "async function openPlatformAgentDetailAction(platform)");
const panel = extractBetween(APP, "function renderPlatformAgentPanel()", "function renderAdminOpsPanel()");
const detail = extractBetween(APP, "async function openPlatformAgentDetailAction(platform)", "function openPlatformSkillReviewAction(platform, skillId, accepted)");
const skillReview = extractBetween(APP, "function openPlatformSkillReviewAction(platform, skillId, accepted)", "function openPlatformSkillRollbackAction(platform, skillId, versionId)");
const skillRollback = extractBetween(APP, "function openPlatformSkillRollbackAction(platform, skillId, versionId)", "function openActionRegistryEditAction(actionKey)");
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
assert.match(reopenHelper, /setTimeout/);
assert.match(reopenHelper, /openPlatformAgentDetailAction/);
assert.match(profileEditor, /renderPolicyVersionSummary\(current,/);
assert.match(profileEditor, /name: "reason"/);
assert.match(profileEditor, /saved\.current_version\?\.version_no/);
assert.match(profileEditor, /reopenPlatformAgentDetailSoon\(platform\)/);
assert.match(profileHistory, /\/v2\/platform-agents\/\$\{encodeURIComponent\(normalizedPlatform\)\}\/profile\/versions/);
assert.match(profileHistory, /\/v2\/platform-agents\/\$\{encodeURIComponent\(normalizedPlatform\)\}\/profile\/audits/);
assert.match(profileHistory, /\/v2\/platform-agents\/\$\{encodeURIComponent\(normalizedPlatform\)\}\/profile\/rollback/);
assert.match(profileHistory, /renderPolicyVersionsHtml/);
assert.match(profileHistory, /renderPolicyAuditsHtml/);
assert.match(profileHistory, /reopenPlatformAgentDetailSoon\(normalizedPlatform\)/);
assert.match(memoryEditor, /reopenPlatformAgentDetailSoon\(platform\)/);
assert.match(skillEditor, /reopenPlatformAgentDetailSoon\(platform\)/);
assert.match(skillReview, /reopenPlatformAgentDetailSoon\(normalizedPlatform\)/);
assert.match(skillRollback, /reopenPlatformAgentDetailSoon\(normalizedPlatform\)/);
assert.match(panel, /open-platform-agent-profile-history/);
assert.match(detail, /open-platform-agent-profile-history/);
assert.match(panel, /data-version-id="\$\{escapeHtml\(item\.recent_execution\.platform_agent_profile_version_id \|\| ""\)\}"/);
assert.match(detail, /data-version-id="\$\{escapeHtml\(profile\.recent_execution\.platform_agent_profile_version_id \|\| ""\)\}"/);
assert.match(panel, /platform_agent_profile_version_no/);
assert.match(panel, /recent_execution\.recommended_action\?\.action/);
assert.match(panel, /recent_execution\.workstream_label/);
assert.match(detail, /platform_agent_profile_version_no/);
assert.match(detail, /recent_execution\.recommended_action\?\.action/);
assert.match(detail, /recent_execution\.workstream_label/);
assert.match(execution, /platformAgentProfile\.version_no/);
assert.match(actions, /name === "open-platform-agent-profile-history"/);
assert.match(actions, /openPlatformAgentProfileHistoryAction\(action\.dataset\.platform \|\| "", action\.dataset\.versionId \|\| ""\)/);
});
test("platform agent recent execution highlights when newer configs exist", () => {
const detail = extractBetween(APP, "async function openPlatformAgentDetailAction(platform)", "function openPlatformSkillReviewAction(platform, skillId, accepted)");
const panel = extractBetween(APP, "function renderPlatformAgentPanel()", "function renderAdminOpsPanel()");
assert.match(detail, /recentExecutionOnelinerConfigStale/);
assert.match(detail, /recentExecutionPlatformConfigStale/);
assert.match(detail, /主配置已更新/);
assert.match(detail, /Agent 已更新/);
assert.match(panel, /recentExecutionOnelinerConfigStale/);
assert.match(panel, /recentExecutionPlatformConfigStale/);
});
test("platform agent recent execution surfaces title, platform scope, and delivery mode", () => {
const detail = extractBetween(APP, "async function openPlatformAgentDetailAction(platform)", "function openPlatformSkillReviewAction(platform, skillId, accepted)");
const panel = extractBetween(APP, "function renderPlatformAgentPanel()", "function renderAdminOpsPanel()");
assert.match(detail, /recent_execution\.title/);
assert.match(detail, /recent_execution\.platform_scope/);
assert.match(detail, /recent_execution\.delivery_mode/);
assert.match(panel, /recent_execution\.title/);
assert.match(panel, /recent_execution\.platform_scope/);
assert.match(panel, /recent_execution\.delivery_mode/);
});
test("main agent route actions keep landing context and destination screens render a notice", () => {
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
const landingActions = extractBetween(APP, "function renderMainAgentLandingQuickActions(screenKey)", "function renderMainAgentLandingNotice(screenKey)");
const strategy = extractBetween(APP, "function renderStrategyScreen()", "function renderCreditsScreen()");
const landing = extractBetween(APP, "function renderMainAgentLandingNotice(screenKey)", "function renderEmptyState(title, description)");
const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");
assert.match(execution, /buildRecommendedActionAttrs\(payload\.recommended_action/);
assert.match(actions, /captureMainAgentLandingContext\(action,\s*"goto-production"/);
assert.match(actions, /captureMainAgentLandingContext\(action,\s*"goto-strategy"/);
assert.match(actions, /name === "dismiss-main-agent-landing"/);
assert.match(landingActions, /open-user-global-policy/);
assert.match(landingActions, /refresh-tracking/);
assert.match(landing, /result_sections/);
assert.match(landing, /renderMainAgentLandingQuickActions\(screenKey\)/);
assert.match(landing, /detail-grid/);
assert.match(strategy, /renderMainAgentLandingNotice\("strategy"\)/);
assert.match(production, /renderMainAgentLandingNotice\("production"\)/);
});
test("main agent landing notices expose a compact mobile follow-up strip", () => {
const landing = extractBetween(APP, "function renderMainAgentLandingNotice(screenKey)", "function renderEmptyState(title, description)");
assert.match(landing, /mobile-only compact-summary-row/);
assert.match(landing, /mobile-only mobile-flow-focus-card/);
assert.match(landing, /主 Agent 结果/);
assert.match(landing, /继续处理/);
});
test("key workbench screens expose contextual handoff-to-main-agent actions", () => {
const discovery = extractBetween(APP, "function renderDiscoveryScreen()", "function renderTrackingScreen()");
const tracking = extractBetween(APP, "function renderTrackingScreen()", "function renderAutomationScreen()");
const projects = extractBetween(APP, "function renderProjectsScreen()", "function getActiveDetailTab(");
const production = extractBetween(APP, "function renderProductionScreen()", "function renderReviewScreen()");
const review = extractBetween(APP, "function renderReviewScreen()", "function renderStrategyScreen()");
assert.match(discovery, /buildMainAgentHandoffAttrs\(\{/);
assert.match(discovery, /button\("交给主 Agent", "handoff-to-main-agent"/);
assert.match(discovery, /sourceScreen: "discovery"/);
assert.match(tracking, /buildMainAgentHandoffAttrs\(\{/);
assert.match(tracking, /button\("交给主 Agent", "handoff-to-main-agent"/);
assert.match(tracking, /sourceScreen: "tracking"/);
assert.match(projects, /buildMainAgentHandoffAttrs\(\{/);
assert.match(projects, /button\("交给主 Agent", "handoff-to-main-agent"/);
assert.match(projects, /sourceScreen: "intake"/);
assert.match(production, /buildMainAgentHandoffAttrs\(\{/);
assert.match(production, /button\("交给主 Agent", "handoff-to-main-agent"/);
assert.match(production, /sourceScreen: "production"/);
assert.match(review, /buildMainAgentHandoffAttrs\(\{/);
assert.match(review, /button\("交给主 Agent", "handoff-to-main-agent"/);
assert.match(review, /sourceScreen: "review"/);
});
test("tracked-account refresh opens the created sync task when the backend returns one", () => {
const refresh = extractBetween(APP, "async function refreshTrackedAccountAction(trackedAccountId)", "function getSelectedProject()");
assert.match(refresh, /sync_job_id/);
assert.match(refresh, /openJobDetailAction\(payload\.sync_job_id\)/);
});
test("job-creating workbench actions jump straight into the created job detail", () => {
const importHomepage = extractBetween(APP, "function openImportHomepageAction()", "function openImportSelectedAccountAction()");
const importSelected = extractBetween(APP, "function openImportSelectedAccountAction()", "function openTrackSelectedAccountAction()");
const importVideo = extractBetween(APP, "function openImportVideoLinkAction()", "function openImportTextAction()");
const importText = extractBetween(APP, "function openImportTextAction()", "function openUploadVideoAction()");
const uploadVideo = extractBetween(APP, "function openUploadVideoAction()", "function openOneLinerProfileAction()");
const aiVideo = extractBetween(APP, "function openCreateAiVideoAction(defaults = {})", "function openCreateRealCutAction(defaults = {})");
const realCut = extractBetween(APP, "function openCreateRealCutAction(defaults = {})", "function openLiveRecorderAction()");
assert.match(importHomepage, /if \(job\?\.id\) \{\s*openJobDetailAction\(job\.id\);/);
assert.match(importSelected, /if \(job\?\.id\) \{\s*openJobDetailAction\(job\.id\);/);
assert.match(importVideo, /if \(job\?\.id\) \{\s*openJobDetailAction\(job\.id\);/);
assert.match(importText, /if \(job\?\.id\) \{\s*openJobDetailAction\(job\.id\);/);
assert.match(uploadVideo, /if \(job\?\.id\) \{\s*openJobDetailAction\(job\.id\);/);
assert.match(aiVideo, /if \(job\?\.id\) \{\s*openJobDetailAction\(job\.id\);/);
assert.match(realCut, /if \(job\?\.id\) \{\s*openJobDetailAction\(job\.id\);/);
});
test("discovery analysis actions focus the most relevant detail tab after success", () => {
const analyzeAccount = extractBetween(APP, "function openAnalyzeSelectedAccountAction()", "function openAnalyzeTopVideosAction()");
const analyzeTopVideos = extractBetween(APP, "function openAnalyzeTopVideosAction()", "function openSimilaritySearchAction()");
const similaritySearch = extractBetween(APP, "function openSimilaritySearchAction()", "function openBenchmarkLinkAction(defaults = {})");
assert.match(APP, /function focusDiscoveryDetailTab\(tabValue\)/);
assert.match(APP, /function focusDiscoveryInsights\(\)/);
assert.match(APP, /function focusDiscoveryTopVideoInsights\(\)/);
assert.match(APP, /function focusDiscoveryRelations\(\)/);
assert.match(analyzeAccount, /focusDiscoveryInsights\(\)/);
assert.match(analyzeTopVideos, /focusDiscoveryTopVideoInsights\(\)/);
assert.match(similaritySearch, /focusDiscoveryRelations\(\)/);
});
test("tracking and benchmark actions land on the most relevant workbench area after success", () => {
const trackSelected = extractBetween(APP, "function openTrackSelectedAccountAction()", "function openImportVideoLinkAction()");
const saveCandidate = extractBetween(APP, "async function saveCandidateAsBenchmark(candidateIndex, relationType = \"benchmark\")", "function screenShell(title, subtitle, actionsHtml, bodyHtml)");
const openBenchmark = extractBetween(APP, "function openBenchmarkLinkAction(defaults = {})", "async function scanAdminOpsAction()");
const clickHandler = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(APP, /function focusTrackingWorkspace\(\)/);
assert.match(APP, /function focusDiscoveryRelations\(\)/);
assert.match(trackSelected, /focusTrackingWorkspace\(\)/);
assert.match(saveCandidate, /focusDiscoveryRelations\(\)/);
assert.match(openBenchmark, /focusDiscoveryRelations\(\)/);
assert.match(clickHandler, /name === "mark-tracking-read"[\s\S]*focusTrackingWorkspace\(\)/);
});
test("recovery and copy actions continue into the most useful result view", () => {
const singleRecover = extractBetween(APP, "function openRecoverJobAction(jobId)", "function openBatchRecoverJobsAction()");
const batchRecover = extractBetween(APP, "function openBatchRecoverJobsAction()", "function openGenerateCopyAction(defaults = {})");
const generateCopy = extractBetween(APP, "function openGenerateCopyAction(defaults = {})", "function openCreateAiVideoAction(defaults = {})");
const recoveryGuide = extractBetween(APP, "function getRecoverJobGuidance(job, recovery) {", "function getJobRecoveryRequest(job) {");
assert.match(APP, /function focusProductionDetailTab\(tabValue\)/);
assert.match(APP, /function focusRecentGeneratedCopy\(\)/);
assert.match(singleRecover, /if \(result\?\.created\?\.id\) \{\s*openJobDetailAction\(result\.created\.id\);/);
assert.match(singleRecover, /focusProductionDetailTab\("recovery"\)/);
assert.match(singleRecover, /失败任务处理建议/);
assert.match(singleRecover, /getRecoverJobGuidance\(job, recovery\)/);
assert.match(singleRecover, /renderRecoverJobGuidanceHtml\(job, recovery, guidance\)/);
assert.match(singleRecover, /sheet-html/);
assert.match(singleRecover, /先补信息,再继续推进/);
assert.match(recoveryGuide, /state === "blocked"/);
assert.match(recoveryGuide, /upload_video/);
assert.match(recoveryGuide, /real_cut/);
assert.match(recoveryGuide, /ai_video/);
assert.match(recoveryGuide, /content_source_sync/);
assert.match(recoveryGuide, /text/);
assert.match(recoveryGuide, /video_link/);
assert.match(recoveryGuide, /去导入主页/);
assert.match(recoveryGuide, /交给主 Agent/);
assert.match(recoveryGuide, /recover-job-handoff/);
assert.match(batchRecover, /if \(successes\[0\]\?\.result\?\.created\?\.id\) \{\s*openJobDetailAction\(successes\[0\]\.result\.created\.id\);/);
assert.match(batchRecover, /focusProductionDetailTab\("recovery"\)/);
assert.match(generateCopy, /focusRecentGeneratedCopy\(\)/);
});
test("review actions return to the review workspace with the saved review in focus", () => {
const reviewAction = extractBetween(APP, "function openReviewAction(defaults = {})", "document.addEventListener(\"click\", async (event) => {");
assert.match(APP, /function focusReviewWorkspace\(reviewId = ""\)/);
assert.match(reviewAction, /focusReviewWorkspace\(review\.id\)/);
assert.match(APP, /id="review-workspace-anchor"/);
assert.match(APP, /data-review-id="\$\{escapeHtml\(review\.id\)\}"/);
});
test("quota and admin ops mutations refocus the user into the most relevant workbench area", () => {
const quota = extractBetween(APP, "function openTenantQuotaAction()", "function openCreateAssistantAction()");
const scanOps = extractBetween(APP, "async function scanAdminOpsAction()", "function openAdminIncidentReviewAction(incidentId)");
const reviewIncident = extractBetween(APP, "function openAdminIncidentReviewAction(incidentId)", "function openAdminRepairPlanAction(incidentId)");
const repairPlan = extractBetween(APP, "function openAdminRepairPlanAction(incidentId)", "function openAdminFixRunDetailAction(runId)");
const auditFixRun = extractBetween(APP, "function openAdminFixRunAuditAction(runId)", "function openJobDetailAction(jobId)");
assert.match(APP, /function focusCreditsWorkspace\(anchorId = "credits-quota-anchor"\)/);
assert.match(APP, /function focusAdminOpsWorkspace\(anchorId = "admin-ops-anchor"\)/);
assert.match(APP, /id="credits-quota-anchor"/);
assert.match(APP, /id="admin-ops-anchor"/);
assert.match(quota, /focusCreditsWorkspace\("credits-quota-anchor"\)/);
assert.match(scanOps, /focusAdminOpsWorkspace\("admin-ops-anchor"\)/);
assert.match(reviewIncident, /focusAdminOpsWorkspace\("admin-ops-anchor"\)/);
assert.match(repairPlan, /focusAdminOpsWorkspace\("admin-ops-anchor"\)/);
assert.match(auditFixRun, /focusAdminOpsWorkspace\("admin-ops-anchor"\)/);
});
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()");
const clickHandler = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(APP, /function focusPlaybookWorkspace\(assistantId = ""\)/);
assert.match(createAssistant, /focusPlaybookWorkspace\(assistant\.id\)/);
assert.match(editAssistant, /focusPlaybookWorkspace\(updated\.id\)/);
assert.match(clickHandler, /name === "select-assistant"[\s\S]*focusPlaybookWorkspace\(appState\.selectedAssistantId\)/);
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)");
const runtime = extractBetween(APP, "function renderOneLinerRunsHtml()", "function renderOneLinerMessagesHtml()");
const execution = extractBetween(APP, "function renderOneLinerExecutionPayloadHtml(payload)", "function parseOneLinerActionPayloadValue(value)");
assert.match(messages, /const buildOnelinerActionAttrs = \(item\) =>/);
assert.match(messages, /actions\.map\(\(item\) => actionTag\(/);
assert.match(messages, /item\.label \|\| item\.executor_label \|\| item\.key \|\| "执行动作"/);
assert.match(messages, /buildOnelinerActionAttrs\(item\)/);
assert.doesNotMatch(messages, /actions\.map\(\(item\) => `<span class="tag clickable-tag" data-action="\$\{escapeHtml\(item\.key\)\}">\$\{escapeHtml\(item\.label\)\}<\/span>`\)/);
assert.match(messages, /data-action="open-oneliner-profile-history"/);
assert.match(messages, /data-action="open-platform-agent-profile-history"/);
assert.match(messages, /data-version-id="\$\{escapeHtml\(profileVersion\.version_id \|\| ""\)\}"/);
assert.match(messages, /data-version-id="\$\{escapeHtml\(platformAgentProfile\.version_id \|\| ""\)\}"/);
assert.match(messages, /actionTag\(\s*primaryAction\.label \|\| "执行下一步"/);
assert.match(messages, /buildOnelinerActionAttrs\(primaryAction\)/);
assert.match(runtime, /data-version-id="\$\{escapeHtml\(currentRunConfigVersion\.version_id \|\| ""\)\}"/);
assert.match(execution, /data-version-id="\$\{escapeHtml\(configVersion\.version_id \|\| ""\)\}"/);
assert.match(execution, /data-version-id="\$\{escapeHtml\(platformAgentProfile\.version_id \|\| ""\)\}"/);
});
test("oneliner runtime shows grouped run health summary above the current run card", () => {
const runtime = extractBetween(APP, "function renderOneLinerRunsHtml()", "function renderOneLinerMessagesHtml()");
assert.match(runtime, /近期运行概况/);
assert.match(runtime, /待确认/);
assert.match(runtime, /执行中/);
assert.match(runtime, /已完成/);
assert.match(runtime, /异常/);
assert.match(runtime, /最近完成/);
assert.match(runtime, /recentCompletedRuns/);
assert.match(runtime, /select-oneliner-run-filter/);
assert.match(runtime, /重点运行/);
assert.match(runtime, /已完成/);
assert.match(runtime, /异常运行/);
assert.match(runtime, /全部/);
assert.match(runtime, /problemRunCount/);
assert.match(runtime, /safeArray\(runs\)\.filter\(\(item\) => item\.run_status === "needs_confirmation"\)\.length/);
});
test("oneliner runtime exposes a compact mobile task strip for the current run", () => {
const runtime = extractBetween(APP, "function renderOneLinerRunsHtml()", "function renderOneLinerMessagesHtml()");
assert.match(runtime, /mobile-only compact-summary-row/);
assert.match(runtime, /mobile-only mobile-flow-focus-card/);
assert.match(runtime, /当前运行/);
assert.match(runtime, /继续这个任务/);
});
test("opening a main agent run result keeps that run selected in the floating runtime", () => {
const resultAction = extractBetween(APP, "function openCurrentOneLinerRunResultAction(runId = \"\")", "function openConfirmOneLinerRunAction(runId = \"\")");
assert.match(resultAction, /appState\.selectedOnelinerRunId = currentRun\.id/);
assert.match(resultAction, /appState\.onelinerRunFilter = currentRun\.run_status === "done" \? "done" : appState\.onelinerRunFilter/);
});
test("oneliner runtime exposes retry for retryable runs and wires the action handler", () => {
const runtime = extractBetween(APP, "function renderOneLinerRunsHtml()", "function renderOneLinerMessagesHtml()");
const actions = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.match(runtime, /retry-oneliner-run/);
assert.match(actions, /name === "retry-oneliner-run"/);
assert.match(actions, /await retryOneLinerRun\(action\.dataset\.runId \|\| "", "user requested retry"\)/);
});
test("oneliner runtime highlights stale configuration versions and suggests rerunning with current config", () => {
const runtime = extractBetween(APP, "function renderOneLinerRunsHtml()", "function renderOneLinerMessagesHtml()");
assert.match(APP, /function getVersionIdentity\(version = \{\}\)/);
assert.match(APP, /function isConfigurationVersionStale\(runVersion, currentVersion\)/);
assert.match(runtime, /currentRunOnelinerConfigStale/);
assert.match(runtime, /currentRunPlatformAgentConfigStale/);
assert.match(runtime, /主配置已更新/);
assert.match(runtime, /平台 Agent 已更新/);
assert.match(runtime, /按当前配置重跑/);
});
test("oneliner panel auto-polls active runs while the floating panel stays open", () => {
const render = extractBetween(APP, "function renderOneLinerUi()", "function openOneLinerPanel()");
const open = extractBetween(APP, "function openOneLinerPanel()", "function closeOneLinerPanel()");
const close = extractBetween(APP, "function closeOneLinerPanel()", "function readActionForm()");
assert.match(APP, /let onelinerRunPollTimer = null;/);
assert.match(APP, /function clearOneLinerRunPollTimer\(\)/);
assert.match(APP, /function syncOneLinerRunPolling\(\)/);
assert.match(render, /syncOneLinerRunPolling\(\);/);
assert.match(open, /syncOneLinerRunPolling\(\);/);
assert.match(close, /clearOneLinerRunPollTimer\(\);/);
assert.match(APP, /setTimeout\(async \(\) => \{/);
assert.match(APP, /await hydrateSelectedOneLinerRun\(\);/);
});
test("workbench interaction flow avoids browser alerts and keeps failures inside the product shell", () => {
const clicks = extractBetween(APP, "document.addEventListener(\"click\", async (event) => {", "document.addEventListener(\"submit\", async (event) => {");
assert.doesNotMatch(APP, /alert\(/);
assert.doesNotMatch(APP, /confirm\(/);
assert.match(clicks, /name === "show-disabled-reason"[\s\S]*rememberAction\("动作已拦截"/);
assert.match(clicks, /name === "auth-refresh" \|\| name === "refresh-data"[\s\S]*presentActionFailure\(error, "刷新数据失败"\)/);
});
test("live recorder delete uses an in-app confirmation sheet instead of browser confirm", () => {
const removeSource = extractBetween(APP, "async function deleteLiveRecorderSourceAction(sourceId)", "async function openLiveRecorderFileAction(fileId)");
assert.match(removeSource, /openActionModal\(\{/);
assert.match(removeSource, /title:\s*"确认删除录制源"/);
assert.match(removeSource, /submitLabel:\s*"确认删除"/);
assert.doesNotMatch(removeSource, /window\.confirm/);
});
test("live-first workbench flows no longer advertise stale missing-capability placeholders for active routes", () => {
assert.doesNotMatch(APP, /当前实例还没有开放 OneLiner 会话接口/);
assert.doesNotMatch(APP, /当前实例还没有开放主 Agent 运行层/);
assert.doesNotMatch(APP, /当前实例还没有开放 OneLiner 动作执行器/);
assert.doesNotMatch(APP, /当前实例还没有开放平台技能验收接口/);
assert.doesNotMatch(APP, /当前实例未提供/);
assert.doesNotMatch(APP, /等待接入重点对象/);
assert.doesNotMatch(APP, /动作待接入/);
assert.match(APP, /先挑一个重点对象开始跟进/);
assert.match(APP, /暂未识别当前动作/);
});
test("declared static workbench actions are wired into explicit handlers", () => {
const declared = new Set([...APP.matchAll(/data-action="([a-zA-Z0-9_-]+)"/g)].map((match) => match[1]));
const clickHandled = new Set([...APP.matchAll(/if \(name === "([a-zA-Z0-9_-]+)"\)/g)].map((match) => match[1]));
const knownNonClick = new Set(["submit-auth", "submit-oneliner", "submit-sheet", "close-sheet", "close-auth", "close-oneliner", "discovery-query", "refresh-data"]);
const missing = [...declared].filter((name) => !clickHandled.has(name) && !knownNonClick.has(name)).sort();
assert.deepEqual(missing, []);
});