Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/content/en/guide/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion docs/content/guide/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 沙箱

Expand Down
4 changes: 0 additions & 4 deletions web/e2e/gate-share-link-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,10 +382,6 @@ const Fixture = defineComponent({
turns: [],
done: false,
active: true,
showSharePanel: true,
onOpenShare: () => {
open.value = true
},
}),
])
: null,
Expand Down
4 changes: 2 additions & 2 deletions web/e2e/gate-share-link.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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()
Expand Down
14 changes: 6 additions & 8 deletions web/src/components/run/ReviewComposer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -307,24 +307,22 @@ describe('ReviewComposer app_preview share panel entry', () => {
turns: [],
done: false,
active: true,
showSharePanel: true,
},
global: {
plugins: [i18n],
stubs: { Icon: true, ParagraphInput: true, AnnotationChip: true, ClarifyChat: true },
},
})
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()
})
Expand Down
22 changes: 0 additions & 22 deletions web/src/components/run/ReviewComposer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -84,15 +82,13 @@ const props = withDefaults(
streamThought: '',
interrupted: false,
streamCompletedAt: null,
showSharePanel: false,
},
)

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<{
Expand Down Expand Up @@ -184,24 +180,6 @@ function onConfirm() {
class="flex h-full min-h-0 flex-col"
data-testid="review-composer-shell"
>
<div
v-if="showSharePanel"
class="shrink-0 border-b border-line bg-elevated/40 px-3 py-2"
data-testid="review-composer-share-panel"
>
<p class="mb-2 text-[11px] text-txt3">
{{ t('pages.gatesInbox.share.appPreviewShareHint') }}
</p>
<button
type="button"
class="inline-flex min-h-9 w-full items-center justify-center border border-accent/40 bg-accent/10 px-3 py-1.5 text-[12px] font-medium text-accent-2 hover:bg-accent/20"
data-testid="review-composer-open-share"
:aria-label="t('pages.gatesInbox.share.openSharePanelAria')"
@click="emit('open-share')"
>
{{ t('pages.gatesInbox.share.openSharePanel') }}
</button>
</div>
<ClarifyChat
ref="chatRef"
class="min-h-0 flex-1"
Expand Down
3 changes: 0 additions & 3 deletions web/src/locales/en/pages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1093,9 +1093,6 @@
"copyLinkAria": "Copy temporary approval link",
"shareApproval": "Share approval",
"shareApprovalAria": "Open share-approval link manager",
"openSharePanel": "Open share panel",
"openSharePanelAria": "Open share-approval panel",
"appPreviewShareHint": "Same policy as pending review · public page has no remote desktop",
"createCopy": "Create and copy link",
"createCopyAria": "Create a temporary approval link and copy it",
"panelTitle": "Temporary approval link",
Expand Down
3 changes: 0 additions & 3 deletions web/src/locales/zh-CN/pages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1093,9 +1093,6 @@
"copyLinkAria": "复制临时审批链接",
"shareApproval": "分享审批",
"shareApprovalAria": "打开分享审批链接管理",
"openSharePanel": "打开分享面板",
"openSharePanelAria": "打开分享审批面板",
"appPreviewShareHint": "与待复审同策略 · 公开页不含远程桌面",
"createCopy": "创建并复制链接",
"createCopyAria": "创建临时审批链接并复制",
"panelTitle": "临时审批链接",
Expand Down
7 changes: 0 additions & 7 deletions web/src/views/GatesInboxView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -1116,9 +1116,6 @@ const inboxAppPreviewActive = computed(() => {
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.
Expand Down Expand Up @@ -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)"
/>
</template>
</ReviewShell>
Expand Down Expand Up @@ -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)"
/>
</template>
</ReviewShell>
Expand Down
Loading