diff --git a/web/storyforge-web-v4/assets/app.js b/web/storyforge-web-v4/assets/app.js index bfdd8d7..98f1756 100644 --- a/web/storyforge-web-v4/assets/app.js +++ b/web/storyforge-web-v4/assets/app.js @@ -3875,10 +3875,17 @@ function renderOneLinerActionRegistryPanel() {

OneLiner 动作注册表

-
当前后端还没返回动作注册表,先沿用默认动作。
+
当前项目还没有单独动作配置,OneLiner 会继续沿用系统默认动作。
+
+
+
+

当前沿用系统默认动作

+

你可以等真实使用场景稳定后,再回来给当前项目单独开关、改名或补充动作说明。

+
+ 系统默认仍可执行 + 当前项目未单独覆盖
-

暂未接入

/v2/oneliner/action-registry 可用后,这里会显示动作开关、描述和租户级配置。

`; } @@ -3923,8 +3930,20 @@ function renderTenantQuotaPanel() { if (!quota && !usage) { return `
-

租户额度与审计

当前后端还没接入 quota / usage。
-

暂未接入

等 live collector 同步 `/v2/tenant/quota` 和 `/v2/tenant/usage` 后,这里会展示本周期预算、动作配额和最近计量记录。

+
+
+

租户额度与审计

+
当前项目还没有额度配置,会先按默认不限额模式运行。
+
+
+
+

当前项目还没有额度配置

+

先给这个项目补预算、动作配额和存储上限,再逐步收紧风险控制。

+
+ 创建额度策略 + 默认不限额 +
+
`; } @@ -4236,8 +4255,24 @@ function renderPlatformAgentPanel() { if (!items.length) { return `
-

平台 Agent

当前后端还没接入平台 Agent 控制面。
-

暂未接入

等 live collector 同步 `/v2/platform-agents` 后,这里会切成真实视图。

+
+
+

平台 Agent

+
当前项目还没有平台 Agent 配置,先从最常用的平台补起。
+
+
+
+ ${ACTIVE_PLATFORMS.map((platformItem) => ` +
+
${escapeHtml(platformItem.label)} Agent
+
当前还没有单独配置,主 Agent 会先沿用系统默认平台方法论。
+
+ 未单独配置 + 开始配置 +
+
+ `).join("")} +
`; } diff --git a/web/storyforge-web-v4/tests/workbench-pages.test.mjs b/web/storyforge-web-v4/tests/workbench-pages.test.mjs index 9a03a9e..3540097 100644 --- a/web/storyforge-web-v4/tests/workbench-pages.test.mjs +++ b/web/storyforge-web-v4/tests/workbench-pages.test.mjs @@ -254,6 +254,23 @@ test("discovery, production, and admin screens use page tabs for heavy content", 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, /等 \/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("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()");