diff --git a/docs/content/en/guide/concepts.md b/docs/content/en/guide/concepts.md index 98332943..2fb9a077 100644 --- a/docs/content/en/guide/concepts.md +++ b/docs/content/en/guide/concepts.md @@ -30,7 +30,7 @@ In the pending-gates inbox, only **human_gate** cards (and the visual preview to ### Temporary review links (Inbox kind=review / app_preview) -Inbox **pending review** and **app preview** cards reuse the same management panel and token rules (`ShareLinkKindReview`), but authenticated APIs live under `/api/runs/:id/reviews/:nodeId/share-link*` — not `/gates/...`, and no fake Gate row is created. In-product entries: card **Copy temp link**, app-preview workbench toolbar **Share approval**, and the Agent sidebar **Open share panel**. The public page is labeled **External review**; hot sessions support multi-turn ReAct. For `productKind=app_preview` the stage is a read-only placeholder — **no noVNC / picking** (the signed-in workbench for the same item still has remote desktop and picking). The only footer action is **Confirm and advance**. Run-detail review tabs and the logged-in review composer do not add a temp-link entry; `proposal_select` and pending clarify stay out of scope. +Inbox **pending review** and **app preview** cards reuse the same management panel and token rules (`ShareLinkKindReview`), but authenticated APIs live under `/api/runs/:id/reviews/:nodeId/share-link*` — not `/gates/...`, and no fake Gate row is created. In-product entries: card **Copy temp link** and app-preview workbench toolbar **Share approval**. The public page is labeled **External review**; hot sessions support multi-turn ReAct. For `productKind=app_preview` the stage is a read-only placeholder — **no noVNC / picking** (the signed-in workbench for the same item still has remote desktop and picking). The only footer action is **Confirm and advance**. Run-detail review tabs and the logged-in review composer do not add a temp-link entry; `proposal_select` and pending clarify stay out of scope. ## Real Docker sandboxes diff --git a/docs/content/guide/concepts.md b/docs/content/guide/concepts.md index a4d1f7bd..7e9306c7 100644 --- a/docs/content/guide/concepts.md +++ b/docs/content/guide/concepts.md @@ -31,7 +31,7 @@ Approving 把 coding agent 变成工作流里的步骤。你在有限状态机 ### 待复审临时链接(Inbox kind=review / app_preview / clarify) -Inbox **待复审**、**应用预览**与 **待澄清**卡片使用同一套管理面板与令牌规则(`ShareLinkKindReview`),认证 API 走 `/api/runs/:id/reviews/:nodeId/share-link*`,不复用 `/gates/...`,也不伪造 Gate 行。站内入口:卡片「复制临时链接」、移动端详情顶栏同名按钮、应用预览工作台工具栏「分享审批」、右侧 Agent 区「打开分享面板」。公开页:待复审标识为「外部复审」;待澄清标识为「待澄清 / 外部澄清」。热态可多轮 ReAct(发送 / 流式轮询 / 取消);`productKind=app_preview` 时产物区为只读占位说明,**不提供 noVNC / 取点**(登录态同一项仍可远程桌面与取点)。底栏仅「确认并流转」(无驳回、无姓名意见)。澄清确认走 Agent 收尾写入结构化需求,取消仅清当前轮并保留队列。运行详情澄清/复审 Tab / 登录侧复审面板 / 产物预览工具条不提供临时链接入口;`proposal_select` 没有此入口。 +Inbox **待复审**、**应用预览**与 **待澄清**卡片使用同一套管理面板与令牌规则(`ShareLinkKindReview`),认证 API 走 `/api/runs/:id/reviews/:nodeId/share-link*`,不复用 `/gates/...`,也不伪造 Gate 行。站内入口:卡片「复制临时链接」、移动端详情顶栏同名按钮、应用预览工作台工具栏「分享审批」。公开页:待复审标识为「外部复审」;待澄清标识为「待澄清 / 外部澄清」。热态可多轮 ReAct(发送 / 流式轮询 / 取消);`productKind=app_preview` 时产物区为只读占位说明,**不提供 noVNC / 取点**(登录态同一项仍可远程桌面与取点)。底栏仅「确认并流转」(无驳回、无姓名意见)。澄清确认走 Agent 收尾写入结构化需求,取消仅清当前轮并保留队列。运行详情澄清/复审 Tab / 登录侧复审面板 / 产物预览工具条不提供临时链接入口;`proposal_select` 没有此入口。 ## 真实 Docker 沙箱 diff --git a/web/e2e/gate-share-link-main.ts b/web/e2e/gate-share-link-main.ts index 0c2df1ff..9c8028fb 100644 --- a/web/e2e/gate-share-link-main.ts +++ b/web/e2e/gate-share-link-main.ts @@ -382,10 +382,6 @@ const Fixture = defineComponent({ turns: [], done: false, active: true, - showSharePanel: true, - onOpenShare: () => { - open.value = true - }, }), ]) : null, diff --git a/web/e2e/gate-share-link.spec.ts b/web/e2e/gate-share-link.spec.ts index 3e6a2ae6..9816b046 100644 --- a/web/e2e/gate-share-link.spec.ts +++ b/web/e2e/gate-share-link.spec.ts @@ -189,7 +189,7 @@ test.describe('human_gate 临时审批链接', () => { expect(copied).toContain('/public/gate-approvals#t=') }) - test('待澄清 Inbox 三处入口可生成临时链接', async ({ page }) => { + test('待澄清 Inbox 两处入口可生成临时链接', async ({ page }) => { await page.addInitScript(() => { Object.defineProperty(navigator, 'clipboard', { configurable: true, @@ -204,7 +204,7 @@ test.describe('human_gate 临时审批链接', () => { await page.goto('/gate-share-link.html?scene=inbox-clarify') await expect(page.getByTestId('gate-share-copy-btn')).toBeVisible({ timeout: 10_000 }) await expect(page.getByTestId('gate-share-copy-btn-detail')).toBeVisible() - await expect(page.getByTestId('review-composer-open-share')).toBeVisible() + await expect(page.getByTestId('review-composer-open-share')).toHaveCount(0) await expect(page.getByTestId('html-preview-share-link')).toHaveCount(0) await page.getByTestId('gate-share-copy-btn').click() await expect(page.getByTestId('gate-share-panel-body')).toBeVisible() diff --git a/web/src/components/run/ReviewComposer.test.ts b/web/src/components/run/ReviewComposer.test.ts index dce73cf7..d804225c 100644 --- a/web/src/components/run/ReviewComposer.test.ts +++ b/web/src/components/run/ReviewComposer.test.ts @@ -291,8 +291,8 @@ describe('ReviewComposer gate review semantics (send + confirm)', () => { }) }) -describe('ReviewComposer app_preview share panel entry', () => { - it('shows open-share when showSharePanel is true (plan g2.4)', async () => { +describe('ReviewComposer share panel entry removed', () => { + it('does not render Agent-area open-share entry (plan g1.1 / g3.1)', async () => { const i18n = createI18n({ legacy: false, locale: 'zh-CN', @@ -307,7 +307,6 @@ describe('ReviewComposer app_preview share panel entry', () => { turns: [], done: false, active: true, - showSharePanel: true, }, global: { plugins: [i18n], @@ -315,16 +314,15 @@ describe('ReviewComposer app_preview share panel entry', () => { }, }) await flushPromises() - expect(wrapper.find('[data-testid="review-composer-share-panel"]').exists()).toBe(true) - expect(wrapper.get('[data-testid="review-composer-open-share"]').text()).toContain('打开分享面板') - await wrapper.get('[data-testid="review-composer-open-share"]').trigger('click') - expect(wrapper.emitted('open-share')).toHaveLength(1) + expect(wrapper.find('[data-testid="review-composer-share-panel"]').exists()).toBe(false) + expect(wrapper.find('[data-testid="review-composer-open-share"]').exists()).toBe(false) wrapper.unmount() }) - it('hides share panel for clarify without showSharePanel', async () => { + it('clarify mode also has no Agent-area share entry', async () => { const wrapper = mountClarify() await flushPromises() + expect(wrapper.find('[data-testid="review-composer-share-panel"]').exists()).toBe(false) expect(wrapper.find('[data-testid="review-composer-open-share"]').exists()).toBe(false) wrapper.unmount() }) diff --git a/web/src/components/run/ReviewComposer.vue b/web/src/components/run/ReviewComposer.vue index 0605444b..96a703f2 100644 --- a/web/src/components/run/ReviewComposer.vue +++ b/web/src/components/run/ReviewComposer.vue @@ -59,8 +59,6 @@ const props = withDefaults( interrupted?: boolean /** ISO when turn completed normally — drives restrained「已完成」footnote. */ streamCompletedAt?: string | null - /** Inbox 待澄清 / 待复审 / 应用预览: show「打开分享面板」above composer body. */ - showSharePanel?: boolean }>(), { iteration: 1, @@ -84,7 +82,6 @@ const props = withDefaults( streamThought: '', interrupted: false, streamCompletedAt: null, - showSharePanel: false, }, ) @@ -92,7 +89,6 @@ const emit = defineEmits<{ (e: 'send', text: string, images: ClarifyImage[], annotations: ReactAnnotation[]): void (e: 'finish'): void (e: 'cancel'): void - (e: 'open-share'): void }>() const chatRef = ref<{ @@ -184,24 +180,6 @@ function onConfirm() { class="flex h-full min-h-0 flex-col" data-testid="review-composer-shell" > -
-

- {{ t('pages.gatesInbox.share.appPreviewShareHint') }} -

- -
{ return n?.type === 'app_preview' }) -/** Inbox composer share entry: 待澄清 / 待复审 / 应用预览 (plan g1.3). */ -const inboxShowSharePanel = computed(() => isShareableInboxItem(active.value)) - // Mirror RunDetailView.reviewActive: post-run product review on a non-react // producer (backend only seeds clarify sessions for ReviewCapable nodes). // Inbox API type stays "clarify"; mode is decided from the loaded graph. @@ -1661,11 +1658,9 @@ function itemSecondary(it: InboxItem) { :done="activeClarify.done" :active="clarifyInputActive" :confirm-error="clarifyConfirmError" - :show-share-panel="inboxShowSharePanel" @send="onClarifySend" @finish="onClarifyFinish" @cancel="onClarifyCancel" - @open-share="openSharePanel(active)" /> @@ -1777,11 +1772,9 @@ function itemSecondary(it: InboxItem) { :done="activeClarify.done" :active="clarifyInputActive" :confirm-error="clarifyConfirmError" - :show-share-panel="inboxShowSharePanel" @send="onClarifySend" @finish="onClarifyFinish" @cancel="onClarifyCancel" - @open-share="openSharePanel(active)" />