From 93ea382c16877f7ba08a054c6f67791a82c3ed21 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 17 Oct 2026 16:47:26 +0000 Subject: [PATCH 1/2] fix(web): surface Act CTA and soften pricing Core copy Leftover after #2437: anonymous Studio can Act on this run without agent-workflow-ui, and pricing Core no longer claims durable/reviewed work. Closes #2440 Co-authored-by: KK --- apps/web/src/app/pricing/page.tsx | 4 +-- apps/web/src/components/OneLoopStudio.tsx | 11 ++++++ .../OneLoopStudio.three-panel.test.tsx | 2 ++ .../src/components/studio/StudioIdeOutput.tsx | 34 +++++++++++++++++-- .../StudioIdeOutput.playflow.test.tsx | 21 +++++++++++- .../__tests__/studio-pipeline-status.test.ts | 13 +++++++ apps/web/src/lib/studio-pipeline-status.ts | 6 +++- apps/web/src/lib/studio-playflow-PLAN.md | 2 ++ 8 files changed, 87 insertions(+), 6 deletions(-) diff --git a/apps/web/src/app/pricing/page.tsx b/apps/web/src/app/pricing/page.tsx index abdab754f..e6a9275ad 100644 --- a/apps/web/src/app/pricing/page.tsx +++ b/apps/web/src/app/pricing/page.tsx @@ -17,8 +17,8 @@ const CORE_CAPABILITIES = [ 'Evidence-gated YouTube analysis', 'Timed caption transcript', 'Visible source provenance', - 'Durable workflow run history', - 'Review-only action preparation', + 'Workflow run history', + 'Proposed work from a Video Pack', 'Export after quality verification', ]; diff --git a/apps/web/src/components/OneLoopStudio.tsx b/apps/web/src/components/OneLoopStudio.tsx index eebb07129..4b9c556f3 100644 --- a/apps/web/src/components/OneLoopStudio.tsx +++ b/apps/web/src/components/OneLoopStudio.tsx @@ -1033,6 +1033,15 @@ export default function OneLoopStudio({ ) : null}
+ + ) : null} + ) : ( <> {reviewActions.map((action, i) => { @@ -239,12 +258,23 @@ export default function StudioIdeOutput({ -
+

{card.statusLabel}

{card.title}

{card.detail}

+ {onAct ? ( + + ) : null}
diff --git a/apps/web/src/components/studio/__tests__/StudioIdeOutput.playflow.test.tsx b/apps/web/src/components/studio/__tests__/StudioIdeOutput.playflow.test.tsx index fa67b7c34..8f39608cb 100644 --- a/apps/web/src/components/studio/__tests__/StudioIdeOutput.playflow.test.tsx +++ b/apps/web/src/components/studio/__tests__/StudioIdeOutput.playflow.test.tsx @@ -1,7 +1,7 @@ // @vitest-environment jsdom import React from 'react'; import { cleanup, fireEvent, render, screen } from '@testing-library/react'; -import { afterEach, describe, expect, it } from 'vitest'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import StudioIdeOutput from '@/components/studio/StudioIdeOutput'; import type { Video } from '@/store/dashboard-types'; @@ -56,4 +56,23 @@ describe('StudioIdeOutput playflow', () => { expect(card.textContent).toMatch(/needs review/i); expect(card.textContent).toMatch(/Review evidence/); }); + + it('renders review_action as a proposed card with Act on this run', () => { + const onAct = vi.fn(); + render( + , + ); + + fireEvent.click(screen.getByTestId('studio-ide-output-tab-intent')); + expect(screen.getByTestId('studio-review-action-card').textContent).toMatch(/Review this result/); + expect(screen.getByTestId('studio-action-cta').textContent).toBe('Act on this run'); + fireEvent.click(screen.getByTestId('studio-action-cta')); + expect(onAct).toHaveBeenCalledTimes(1); + }); }); diff --git a/apps/web/src/lib/__tests__/studio-pipeline-status.test.ts b/apps/web/src/lib/__tests__/studio-pipeline-status.test.ts index 05167ecba..6d91bd176 100644 --- a/apps/web/src/lib/__tests__/studio-pipeline-status.test.ts +++ b/apps/web/src/lib/__tests__/studio-pipeline-status.test.ts @@ -546,7 +546,13 @@ describe('studio-pipeline-status', () => { expect(shell).toContain('data-testid="studio-ide-toolbar"'); expect(studio).toContain('StudioIdeShell'); expect(pricing).not.toMatch(/reviewed plan dispatches backend agents/); + expect(pricing).not.toMatch(/Durable workflow run history/); + expect(pricing).not.toMatch(/reviewed actions/i); + expect(pricing).toContain('Proposed work from a Video Pack'); + expect(pricing).toContain('Workflow run history'); expect(apiDocs).not.toMatch(/durable Studio analysis workflow/); + expect(studio).toContain('data-testid="studio-act-button"'); + expect(studio).toContain('Act on this run'); }); it('renders review_action as a card with status, title, and detail', () => { @@ -559,18 +565,25 @@ describe('studio-pipeline-status', () => { expect(review.title).toMatch(/review this result/i); expect(review.statusLabel).toBe('Needs review'); expect(review.detail).toBe('Review evidence'); + expect(review.ctaLabel).toBe('Act on this run'); + + const proposed = studioActionCard({ tool: 'review_action', status: 'proposed' }); + expect(proposed.detail).toMatch(/Proposed finding/); const tool = studioActionCard({ tool: 'persist_insight', status: 'completed' }); expect(tool.kind).toBe('tool'); expect(tool.title).toMatch(/persist insight/i); expect(tool.statusLabel).toBe('Done'); expect(tool.detail).toMatch(/no detail/i); + expect(tool.ctaLabel).toBe('Keep on this page'); const studio = readFileSync(join(process.cwd(), 'src/components/OneLoopStudio.tsx'), 'utf8'); const output = readFileSync(join(process.cwd(), 'src/components/studio/StudioIdeOutput.tsx'), 'utf8'); expect(studio).toContain('studioActionCard'); expect(output).toContain('studioActionCard'); expect(output).toContain('data-testid="studio-review-action-card"'); + expect(output).toContain('data-testid="studio-action-cta"'); + expect(studio).toContain('data-testid="studio-act-button"'); // IDE: actions surface in the output pane Intent tab. expect(output).toContain("{ id: 'intent', label: 'Intent' }"); }); diff --git a/apps/web/src/lib/studio-pipeline-status.ts b/apps/web/src/lib/studio-pipeline-status.ts index 2bd869c7e..16d0d8731 100644 --- a/apps/web/src/lib/studio-pipeline-status.ts +++ b/apps/web/src/lib/studio-pipeline-status.ts @@ -637,6 +637,7 @@ export function studioActionCard(action: { statusLabel: string; detail: string; kind: 'review' | 'tool'; + ctaLabel: string; } { const isReview = action.tool === 'review_action'; const statusLabel = @@ -656,12 +657,15 @@ export function studioActionCard(action: { .join(' '); const detail = action.result?.trim() || - (isReview ? 'Open the evidence on this page before you act.' : 'No detail from this tool.'); + (isReview + ? 'Proposed finding — open the evidence on this page before you act.' + : 'No detail from this tool.'); return { title, statusLabel, detail, kind: isReview ? 'review' : 'tool', + ctaLabel: isReview ? 'Act on this run' : 'Keep on this page', }; } diff --git a/apps/web/src/lib/studio-playflow-PLAN.md b/apps/web/src/lib/studio-playflow-PLAN.md index ab68c22ec..db662b14c 100644 --- a/apps/web/src/lib/studio-playflow-PLAN.md +++ b/apps/web/src/lib/studio-playflow-PLAN.md @@ -17,6 +17,7 @@ - [x] Transcript retry control when `studioCanRetryTranscript` - [x] Export toast no longer uses sticky-footer `bottom-20` - [x] Focused Vitest +- [x] Leftover after #2437: pricing Core copy (G) + ungated Act CTA on review cards (E) ## 3. Definition of Done (Success Verification) * **Expected Outcome:** Anonymous Studio on a seadance/cluely pack can click **Ship this** (ZIP export). Stack checks read skip/unknown and do not disable the button. No live hostname claim. Transcript retry and review cards are visible. @@ -27,3 +28,4 @@ * **What was done:** Restored a discoverable **Ship this** toolbar CTA that downloads the pack ZIP. Anonymous/unknown SeaDance/Cluely stack checks render as skip/unknown and never disable the button. Intent tab renders `review_action` cards. Transcript retry is visible on retryable failure. Export toast sits at `bottom-4` (no sticky footer). Origin deploy button was not restored. * **Why it was needed:** IDE shell left playflow helpers unwired; dogfood kill F was a disabled Deploy with no Ship this. * **How it was tested:** Focused Vitest (49 + 16), type-check, eslint. No production live claim. GitHub issue create was 403 so this cut has no new issue number. +* **Leftover after #2437 (this PR):** Pricing Core copy no longer says durable/reviewed; Act on this run is a toolbar + Intent CTA without `agent-workflow-ui`. Focused Vitest 5 files / 53 passed plus 3 related files / 15 passed. Canonical leftover issue #2440. From 5585afc591646027f09a916a9b1ef35dd7b6af1a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Sat, 17 Oct 2026 20:33:48 +0000 Subject: [PATCH 2/2] test(web): lock Act CTA outside agent-workflow-ui Retriggers Require issue closer on a new head after the PR body already Closes #2440. The prior synchronize run failed because the body still closed #2435. Closes #2440 Co-authored-by: KK --- apps/web/src/lib/__tests__/studio-pipeline-status.test.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/web/src/lib/__tests__/studio-pipeline-status.test.ts b/apps/web/src/lib/__tests__/studio-pipeline-status.test.ts index 6d91bd176..ff1125c60 100644 --- a/apps/web/src/lib/__tests__/studio-pipeline-status.test.ts +++ b/apps/web/src/lib/__tests__/studio-pipeline-status.test.ts @@ -584,6 +584,9 @@ describe('studio-pipeline-status', () => { expect(output).toContain('data-testid="studio-review-action-card"'); expect(output).toContain('data-testid="studio-action-cta"'); expect(studio).toContain('data-testid="studio-act-button"'); + expect(studio).not.toMatch( + /showAgentWorkflowUi[\s\S]{0,400}data-testid="studio-act-button"/, + ); // IDE: actions surface in the output pane Intent tab. expect(output).toContain("{ id: 'intent', label: 'Intent' }"); });