From d06a623a310e10116acf2d75e43f4e37df19709c Mon Sep 17 00:00:00 2001 From: brennanb2025 Date: Thu, 28 May 2026 15:55:05 -0700 Subject: [PATCH] Remove workspace creation contextual tour Co-authored-by: Orca --- .../feature-education-retention-analytics.md | 3 +- .../components/NewWorkspaceComposerCard.tsx | 4 +-- .../components/NewWorkspaceComposerModal.tsx | 2 -- .../contextual-tour-gate.test.ts | 7 ++--- .../contextual-tours/use-contextual-tour.ts | 3 +- .../components/sidebar/AddRepoCreateStep.tsx | 13 ++------- .../src/components/sidebar/AddRepoDialog.tsx | 15 ++-------- .../components/sidebar/AddRepoSetupStep.tsx | 11 ++----- .../src/components/sidebar/AddRepoSteps.tsx | 6 ++-- src/renderer/src/store/slices/ui.test.ts | 10 ++----- src/shared/contextual-tours.test.ts | 15 +++------- src/shared/contextual-tours.ts | 29 +------------------ src/shared/feature-education-telemetry.ts | 6 +--- .../e2e-completed-onboarding-profile.ts | 3 +- 14 files changed, 23 insertions(+), 104 deletions(-) diff --git a/docs/reference/feature-education-retention-analytics.md b/docs/reference/feature-education-retention-analytics.md index 51e338fb7e1..1478ab46fb6 100644 --- a/docs/reference/feature-education-retention-analytics.md +++ b/docs/reference/feature-education-retention-analytics.md @@ -32,7 +32,7 @@ Emitted once when a contextual tour first renders a measured target. Payload: -- `tour_id`: `workspace-board`, `browser`, `tasks`, `automations`, or `workspace-creation` +- `tour_id`: `workspace-board`, `browser`, `tasks`, or `automations` - `source`: bounded source enum from `src/shared/feature-education-telemetry.ts` - `was_feature_previously_interacted`: boolean from local education state at the moment the tour is shown @@ -122,7 +122,6 @@ Question: Do users later use the feature taught by the tour? Build funnels from tour events to real product events: -- `workspace-creation`: `contextual_tour_outcome` -> `workspace_created` - `tasks`: `contextual_tour_outcome` -> workspace creation from task-linked flows where existing telemetry exposes the source; if the current event is insufficient, add a targeted task-started-workspace event. - `browser`: `contextual_tour_outcome` -> browser grab/annotation events. If these do not exist, add targeted events for the concrete actions, not a broad feature-interaction event. - `automations`: `contextual_tour_outcome` -> automation creation/run events. If these do not exist, add targeted events for create/run. diff --git a/src/renderer/src/components/NewWorkspaceComposerCard.tsx b/src/renderer/src/components/NewWorkspaceComposerCard.tsx index b4c4035d3fe..d0403ba91df 100644 --- a/src/renderer/src/components/NewWorkspaceComposerCard.tsx +++ b/src/renderer/src/components/NewWorkspaceComposerCard.tsx @@ -307,7 +307,7 @@ export default function NewWorkspaceComposerCard({ )} >
-
+
@@ -452,7 +452,6 @@ export default function NewWorkspaceComposerCard({ size="sm" onClick={onToggleAdvanced} className="-ml-2 text-xs" - data-contextual-tour-target="workspace-creation-setup" > Advanced {creating ? : null} {primaryActionLabel} diff --git a/src/renderer/src/components/NewWorkspaceComposerModal.tsx b/src/renderer/src/components/NewWorkspaceComposerModal.tsx index d924ace58c8..02bf3bd0b47 100644 --- a/src/renderer/src/components/NewWorkspaceComposerModal.tsx +++ b/src/renderer/src/components/NewWorkspaceComposerModal.tsx @@ -8,7 +8,6 @@ import { AGENT_CATALOG } from '@/lib/agent-catalog' import type { LinkedWorkItemSummary } from '@/lib/new-workspace' import { shouldAllowComposerEnterSubmitTarget } from '@/lib/new-workspace-enter-guard' import { isScreenSubmitShortcut } from '@/lib/screen-submit-shortcut' -import { useContextualTour } from '@/components/contextual-tours/use-contextual-tour' import type { TuiAgent, WorkspaceCreateTelemetrySource, @@ -99,7 +98,6 @@ function QuickTabBody({ onClose: () => void active: boolean }): React.JSX.Element { - useContextualTour('workspace-creation', active, 'workspace_creation_modal') const settings = useAppStore((s) => s.settings) const { cardProps, composerRef, nameInputRef, submitQuick, createDisabled } = useComposerState({ initialName: modalData.prefilledName ?? '', diff --git a/src/renderer/src/components/contextual-tours/contextual-tour-gate.test.ts b/src/renderer/src/components/contextual-tours/contextual-tour-gate.test.ts index 8e8451cb5d3..46a325a4955 100644 --- a/src/renderer/src/components/contextual-tours/contextual-tour-gate.test.ts +++ b/src/renderer/src/components/contextual-tours/contextual-tour-gate.test.ts @@ -14,15 +14,12 @@ import { import { getContextualTourPanelCssPosition } from './contextual-tour-panel-position' describe('contextual tour gate', () => { - it('allows workspace creation only over its own creation modals', () => { - const workspaceCreation = getContextualTour('workspace-creation') + it('blocks tours while another modal is active', () => { const tasks = getContextualTour('tasks') - expect(isContextualTourAllowedForModal(workspaceCreation, 'new-workspace-composer')).toBe(true) - expect(isContextualTourAllowedForModal(workspaceCreation, 'add-repo')).toBe(true) - expect(isContextualTourAllowedForModal(workspaceCreation, 'quick-open')).toBe(false) expect(isContextualTourAllowedForModal(tasks, 'none')).toBe(true) expect(isContextualTourAllowedForModal(tasks, 'new-workspace-composer')).toBe(false) + expect(isContextualTourAllowedForModal(tasks, 'add-repo')).toBe(false) }) it('does not start when the required first target is missing', () => { diff --git a/src/renderer/src/components/contextual-tours/use-contextual-tour.ts b/src/renderer/src/components/contextual-tours/use-contextual-tour.ts index 7603505bf54..d18282042ff 100644 --- a/src/renderer/src/components/contextual-tours/use-contextual-tour.ts +++ b/src/renderer/src/components/contextual-tours/use-contextual-tour.ts @@ -7,8 +7,7 @@ const TOUR_SOURCES = { 'workspace-board': 'workspace_board_visible', browser: 'browser_visible', tasks: 'tasks_open', - automations: 'automations_open', - 'workspace-creation': 'workspace_creation_visible' + automations: 'automations_open' } satisfies Record export function useContextualTour( diff --git a/src/renderer/src/components/sidebar/AddRepoCreateStep.tsx b/src/renderer/src/components/sidebar/AddRepoCreateStep.tsx index 7bfc34c4c51..97187f9a703 100644 --- a/src/renderer/src/components/sidebar/AddRepoCreateStep.tsx +++ b/src/renderer/src/components/sidebar/AddRepoCreateStep.tsx @@ -320,10 +320,7 @@ export function CreateStep({ (= content size), so a long path inside the Location row would blow out the dialog width even with flex + truncate on the row itself. min-w-0 here caps the grid track at the dialog's max-width. */} -
+
{/* Kind toggle. Real radiogroup so screen readers announce it as a choice. */}
)} -
diff --git a/src/renderer/src/components/sidebar/AddRepoDialog.tsx b/src/renderer/src/components/sidebar/AddRepoDialog.tsx index abd96712d5e..647ea521154 100644 --- a/src/renderer/src/components/sidebar/AddRepoDialog.tsx +++ b/src/renderer/src/components/sidebar/AddRepoDialog.tsx @@ -43,7 +43,6 @@ import { effectiveExternalWorktreeVisibility, isLegacyRepoForExternalWorktreeVisibility } from '../../../../shared/worktree-ownership' -import { useContextualTour } from '@/components/contextual-tours/use-contextual-tour' function defaultProjectGroupNameForPath(path: string): string { return ( @@ -200,11 +199,6 @@ const AddRepoDialog = React.memo(function AddRepoDialog() { const isOpen = activeModal === 'add-repo' const projectId = addedRepo?.id ?? '' const isRuntimeEnvironmentActive = Boolean(settings?.activeRuntimeEnvironmentId?.trim()) - useContextualTour( - 'workspace-creation', - isOpen && step === 'setup', - 'workspace_creation_add_project' - ) const worktrees = useMemo(() => { return worktreesByRepo[projectId] ?? [] @@ -782,7 +776,7 @@ const AddRepoDialog = React.memo(function AddRepoDialog() { -
+