diff --git a/docs/ai-and-plans/PRs/documentdb-quickstart/ux-review.md b/docs/ai-and-plans/PRs/documentdb-quickstart/ux-review.md
new file mode 100644
index 000000000..44edc661d
--- /dev/null
+++ b/docs/ai-and-plans/PRs/documentdb-quickstart/ux-review.md
@@ -0,0 +1,1144 @@
+# DocumentDB Local Quick Start — UX Review Pack
+
+> **Who this is for:** anyone about to do a hands-on UX review of the **Local Quick Start** feature
+> (installing/running a local DocumentDB container from inside VS Code), or anyone triaging the
+> findings.
+> **What this is:** a single catch-up document that captures a round of runtime UX feedback, states
+> what the code _actually does today_ (verified against the current branch), and — for each item —
+> offers a **suggestion** and a **status**. Items are **sorted by priority** (P0 → P3). Almost every
+> item is **Open**: the operator must choose the direction.
+
+- **Feature area:** `src/services/localQuickStart/`, `src/commands/localQuickStart/`,
+ `src/tree/connections-view/LocalQuickStart/`, `src/webviews/documentdb/localQuickStart/`
+- **Working branch:** `dev/tnaum/documentdb-quickstart-ux-review`
+- **Related design docs:** [local-quickstart-v2.md](../../local-quickstart/local-quickstart-v2.md),
+ [local-quickstart-poc/](../local-quickstart-poc/),
+ [local-quickstart-multi-instance/](../local-quickstart-multi-instance/)
+- **Scope:** the UX-facing surface (tree structure, wording, icons, the provisioning webview,
+ lifecycle actions, error recovery). Backend/state-machine internals appear only where they explain
+ a user-visible symptom.
+- **Review date:** 2026-07-09
+
+## How this review was run
+
+A person exercised the real feature (install → run → stop → delete → break-it-externally) and dictated
+observations; an AI assistant did the code-checking, root-cause tracing, and write-up. Each finding is
+backed by the exact code path that produces the behavior, so a later implementation pass doesn't have
+to re-derive it. Items are grouped and ordered **by priority**; each carries an **Observation** (what
+the reviewer saw), a **Finding** (what the code does and why), a **Suggestion**, and a **Status**.
+Heavier design questions with real trade-offs are pulled into [Open ideas](#open-ideas--options-pros--cons).
+
+## Legend
+
+### Priority
+
+| Priority | Meaning |
+| -------- | -------------------------------------------------- |
+| **P0** | Blocking — the user gets stuck |
+| **P1** | Broken / misleading, or a consistency & safety gap |
+| **P2** | Polish, expectation, or a smaller feature gap |
+| **P3** | Nice-to-have / cosmetic / acknowledged |
+
+### Status
+
+| Status | Meaning |
+| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
+| 🟠 **Open** | Recorded + analyzed; carries a **TN recommendation** ("TN leans towards …") but stays **Open** — a _suggestion_ the team may revisit / replace |
+| 🟡 **Open (soft)** | Open, but the recommendation depends on a **technical investigation** (item 25) or is a **soft "leave as-is"** (item 27) |
+| ✅ **Implemented** | A change was made on this branch and verified |
+
+### Markers (inline)
+
+| Marker | Meaning |
+| ----------------- | ------------------------------------------------------- |
+| ⚠️ **Flag** | Confirmed gap or bug |
+| 💡 **Suggestion** | A design/wording recommendation to react to |
+| 🔍 **Answered** | A "how does this work?" question answered from the code |
+
+> **For the operator:** almost everything below is **Open**. Each item records a **TN recommendation**
+> ("TN leans towards … because …") — but these are **suggestions, not final decisions**: the team may
+> revisit and propose another approach. **TN is open to discussion — if you disagree with a
+> recommendation, raise it.** Where there are real trade-offs, see the matching entry under
+> [Open ideas](#open-ideas--options-pros--cons). Exactly **one** item is already **Implemented**
+> (item 30).
+
+---
+
+## The story in one paragraph
+
+Local Quick Start adds a **`DocumentDB Local - Quick Start`** root node to the Connections view. From
+an empty state a user clicks one row to open a **setup webview**, which checks Docker, pulls the image,
+creates + starts a container, waits for readiness, and seeds sample data — reporting progress as a
+stage checklist. Once running, the instance appears **inline** in the tree as a browsable cluster with
+a Quick-Start-specific context menu (Start/Stop/Restart/Delete/Copy/View Logs). On upgrade, pre-existing
+local "emulator" connections are migrated once into a regular folder. This review hammered the
+_presentation and robustness_ of that journey. The two **P0** bugs are lifecycle dead ends (a
+restart-time credential dead end and a silent no-op on Start after an external delete). The **P1** set
+is the real header bug, two error-presentation anti-patterns (tree nodes and the webview hero both used
+to display errors), plus destructive-action consistency and safety. The rest is polish, expectation,
+data-model, and enhancement work. See [Appendix A](#appendix-a--current-webview-flow-reference) for the
+webview flow.
+
+---
+
+## Priority index
+
+| # | Priority | Item | Status |
+| --- | -------- | ----------------------------------------------------- | -------------- |
+| 1 | **P0** | Credential-missing state is a restart dead end | 🟠 Open |
+| 2 | **P0** | External container delete → silent no-op on Start | 🟠 Open |
+| 3 | **P1** | Webview header stuck on "Setting up…" | 🟠 Open |
+| 4 | **P1** | Tree nodes misused to display errors | 🟠 Open |
+| 5 | **P1** | Error/status messages hijack the hero | 🟠 Open |
+| 6 | **P1** | "Delete deletes data" vs "recreate/recover" clash | 🟠 Open |
+| 7 | **P1** | Copy Connection String silently copies the password | 🟠 Open |
+| 8 | **P1** | Delete bypasses the shared confirmation (+ em dashes) | 🟠 Open |
+| 9 | **P1** | Only ever delete containers we created | 🟠 Open |
+| 10 | **P2** | Legacy migration folder hides in the sort | 🟠 Open |
+| 11 | **P2** | Phase out the "local connection" concept | 🟠 Open |
+| 12 | **P2** | "Checking Docker" is a bare spinner | 🟠 Open |
+| 13 | **P2** | Advanced: creds toggle + ambiguous placeholders | 🟠 Open |
+| 14 | **P2** | "Cancel" implies a rollback it doesn't do | 🟠 Open |
+| 15 | **P2** | No "What was done" summary on completion | 🟠 Open |
+| 16 | **P2** | No upfront "first run takes a few minutes" | 🟠 Open |
+| 17 | **P2** | "Load sample data" is all-or-nothing | 🟠 Open\* |
+| 18 | **P2** | "Waiting…" static for minutes | 🟠 Open\* |
+| 19 | **P2** | No image-pull progress | 🟠 Open\* |
+| 20 | **P2** | Running row lacks regular cluster commands | 🟠 Open |
+| 21 | **P2** | Credential storage is a bespoke plainer path | 🟠 Open |
+| 22 | **P2** | Always persistent — no ephemeral option | 🟠 Open |
+| 23 | **P2** | User delete must always drop the volume | 🟠 Open |
+| 24 | **P2** | Volumes not structurally linked to the image | 🟠 Open |
+| 25 | **P2** | Container keeps running after VS Code closes | 🟡 Open\* |
+| 26 | **P2** | Tree state changes not announced (accessibility) | 🟠 Open |
+| 27 | **P3** | Docker prereq only revealed after the click | 🟡 Open\* |
+| 28 | **P3** | Generic `$(plug)` icon, no distinct identity | 🟠 Open |
+| 29 | **P3** | "Open terminal in the container" | 🟠 Open |
+| 30 | **P1\*** | Empty-state tree row reworded / "Learn more" dropped | ✅ Implemented |
+
+> \* Item 30 was a P1-ish wording nit; it's the one item already shipped on this branch, so it's parked
+> at the end under Implemented.
+>
+> **Status key:** every item is **🟠 Open** (a few are **🟡 Open (soft)**), plus one **✅ Implemented**
+> (item 30). Each Open item carries a **TN recommendation** recorded inline as _"TN leans towards …"_ —
+> **a suggestion, not a decision**; the team may revisit. An **Open\*** (items 17, 18, 19) means the
+> recommended _direction_ is set but an **investigation** is required before/while implementing (data
+> source, real progress signal). **🟡 Open\*** (item 25) means the recommendation (keep always-on) holds
+> pending a technical check. **TN is open to discussion — disagree freely.**
+
+---
+
+## P0 — Blocking (the user gets stuck)
+
+### 1. Credential-missing state after a restart is a UI dead end (the demo incident) ⚠️
+
+**Priority:** P0 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards Delete-only** (no Recreate here) — keep it **clean and simple**. Communicate
+> clearly to the user that this is a **corrupted / unusable state that needs to be removed**, and offer
+> a single **Delete** action. _Because a lost-secret state is rare, and a clear "this is broken, remove
+> it and start over" reads better than trying to recover onto an opaque on-disk volume._
+
+**Observation (real incident, mid-review):** An instance was created via Quick Start, then stopped,
+then its container/image were removed outside VS Code. After a **VS Code restart** the Quick Start node
+showed the rocket _"Click here to start DocumentDB Local"_ row **plus** a warning row _"DocumentDB Local
+has data on disk but its saved credentials are missing…"_ (truncated in the tree). There was **no way
+from the UI** to delete the leftover container/volume or to start cleanly — no Delete node, no recreate
+action. Recovery required manually removing the container and its volume with Docker, then refreshing.
+
+**Finding:**
+
+- On activation, `reconcile()` → `reconcileAlias()` hits **"Case 4"**: a labelled container (or a
+ `ready` record) exists but the stored secret is unrecoverable, so it calls
+ `setStatus(alias, InstanceState.Error, undefined, CREDENTIAL_UNAVAILABLE_MESSAGE)` with
+ **`metadata: undefined`**. By design it **never** removes the container or volume (R2 data-safety: a
+ lost secret doesn't prove the volume is disposable — the user must choose the wipe).
+- Because `metadata` is `undefined`, `LocalQuickStartItem.getChildren()` skips every `metadata && …`
+ branch and falls through to the **NotInstalled** branch, which renders the rocket action row **plus** a
+ passive `treeItem_quickStartError` warning row carrying the message.
+- ⚠️ That warning row has **no command and no context menu**, and the Delete command's `when` requires
+ `treeItem_quickStartInstance` + a `state_*` token — which this surfaced state never carries. So
+ **Delete is unreachable**, and unlike the true `Missing` row (which at least says "click to recreate")
+ no recovery action is offered. The user is genuinely stuck.
+- ⚠️ **Restart behavior specifically:** in-memory state is rebuilt from durable state on every reload, so
+ this dead end **reproduces on every restart** — not a transient glitch. Clicking the rocket to "start
+ fresh" doesn't help either: the on-disk volume + missing credentials block a clean provision, and
+ item 2's silent-return path compounds it.
+- **How we recovered (runbook):** removed the labelled container and its data volume directly with Docker
+ (`docker rm -f vscode-documentdb-local` + `docker volume rm vscode-documentdb-local-data`), then
+ refreshed; reconcile found nothing and returned to the clean NotInstalled empty state.
+
+💡 **Suggestion:** The credential-unavailable state must be **actionable**, not a passive warning. Render
+it like the `Missing` row — a real instance row (`treeItem_quickStartInstance` + a dedicated
+`state_credentialsMissing` token) that exposes **Delete Container** (clean slate: container + volume +
+stale records, via `deleteContainer()`, cf. item 23) and, where safe, **Recreate**. Keep R2 (never
+_auto_-wipe) — but give the user a one-click way to _choose_ the wipe. Shares the recovery UX in Open
+idea O4; a direct instance of item 4's principle.
+
+### 2. A container deleted _outside_ VS Code isn't handled on Start (silent no-op) ⚠️
+
+**Priority:** P0 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards "show as Missing + a Delete/Remove action"** (not a silent removal) so the user
+> **notices something happened**; put the extra detail in the **tooltip**. Keep it **good-enough and
+> low-cost** — it's an edge case, so the fix should be solid but not expensive. _Because the goal is
+> visible feedback plus a clear way out, not a polished recovery flow._
+
+**Observation (repro):** Created an instance via Quick Start, stopped it, then deleted the _container_
+directly via Docker. Back in VS Code, clicking Start on the still-"Stopped"-looking row does nothing
+visible — no dialog, no tree update — only the raw Docker error appears in the output channel:
+
+```
+$ docker container inspect --format '{{json .}}' 57f8311fd9ec…
+Error response from daemon: No such container: 57f8311fd9ec…
+```
+
+**Finding — a specific, reproducible gap:**
+
+- `ContainerRuntime.inspectContainer()` wraps the CLI call in `try { … } catch { return undefined; }`,
+ swallowing "No such container" into `undefined`. But the shared `makeRunner()` still logs the command
+ and streams the daemon's stderr to the channel — that's exactly the two lines the user saw (the
+ extension's own inspect call, not a manual terminal session).
+- `start()` calls `isManaged(id)` first, which returns `false` both when the container **isn't ours**
+ _and_ when it's **gone** (`inspectContainer` → `undefined`). ⚠️ **`isManaged()` cannot distinguish
+ "missing" from "not ours."**
+- `start()`'s guard is `if (!id || !isManaged || !liveStateGuard(…)) return;`. Because `isManaged` already
+ returned `false`, the `||` short-circuits and **`liveStateGuard()` never runs** — the very code that
+ _would_ have handled this gracefully (it detects a `'missing'` live state, calls `refreshLiveState()`,
+ and shows an info message). That path is well-built for the multi-window / external-stop case; it's just
+ unreachable here.
+- Net effect: `start()` early-returns silently, `setStatus` never fires, the tree never refreshes, and the
+ stale "Stopped" row persists until something else (e.g. collapsing/expanding the node) triggers
+ `refreshLiveState()` independently.
+- There's already a good pattern for the related case: `refreshLiveState()` _does_ set `entry.missing = true`
+ and the tree renders `Missing · click to recreate`. The gap is that the **lifecycle actions**
+ (`start`/`stop`/`restart`) don't funnel through that missing-detection before giving up.
+
+💡 **Suggestion:** Teach `start`/`stop`/`restart` to distinguish "no container found" from "found but not
+ours" (a small change to `isManaged`, or a check ahead of it) and, on "missing," do what `liveStateGuard`
+already does — refresh state to the `Missing` badge and surface a message with next steps: **Delete** and/or
+**Recreate with same settings** (the existing `Missing` recreate flow + `getReusableCredentials()` likely
+covers most of it — confirm once reachable). Options in Open idea O4.
+
+---
+
+## P1 — Broken / misleading, or consistency & safety
+
+### 3. The webview header changes with state and gets stuck on "Setting up…" ⚠️
+
+**Priority:** P1 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards a fixed header area** — static across all phases; all state lives in the body /
+> subtitle. _Because the header jumping (and sticking on "Setting up…") is unexpected; a constant
+> header is calmer and removes the stuck-text bug outright._
+
+**Observation:** The header should be static. Today it changes with status/progress/errors, and it
+sometimes stays on "Setting up DocumentDB Local…" even when setup is actually complete.
+
+**Finding** (in [LocalQuickStart.tsx](../../../../src/webviews/documentdb/localQuickStart/LocalQuickStart.tsx)):
+the header ("hero") is rendered by a local `hero(title, subtitle)` helper called with **three different
+literal titles** depending on `phase`: `'Docker is required'` (dockerNotReady), `'Setting up DocumentDB
+Local…'` (**provisioning, success, _and_ failed all share this one call**), and `'Start DocumentDB Local'`
+(review). Both halves of the observation are confirmed:
+
+- ⚠️ The title genuinely changes across phases (three strings), reading as a jumpy header.
+- ⚠️ **The "stuck" complaint is a real bug:** `success` and `failed` reuse the `provisioning` title
+ verbatim, so "Setting up DocumentDB Local…" is still shown even once the instance is running or has
+ definitively failed. Only the body below reflects the outcome — the header never catches up. (A
+ phase/stage-aware `provisioningStatusMessage` exists but is only piped to a screen-reader-only live
+ region, not shown visually.)
+
+💡 **Suggestion:** Make the header a **single static string** for the whole panel lifecycle (e.g.
+"DocumentDB Local"), and let the subtitle/body carry all state (elapsed timer, success/failure boxes
+already exist). That satisfies "header should be static" and eliminates the stuck-text bug in one move. If
+a dynamic header is preferred, it must at minimum branch on `success`/`failed` the way `dockerNotReady`
+already does.
+
+### 4. Tree nodes are misused to display errors (they should be actions, not dialogs) ⚠️💡
+
+**Priority:** P1 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards unifying** — adopt the rule feature-wide: errors go to a **modal** (+ the output
+> channel for detail), and tree rows stay **actionable only**. _Because it matches the rest of the
+> extension (the Kubernetes feature already did this) and removes the passive error rows at the root,
+> which also fixes item 1's dead end._
+
+**Observation:** A broader pattern problem exposed by the incident (item 1) — we render an **error message
+as a tree node**. Leaf/error nodes should be **actions the user can take**, not a substitute for a dialog
+or a status surface.
+
+**Finding:**
+
+- Several Quick Start states render a passive, non-actionable row purely to display text:
+ `treeItem_quickStartError` (the credential-unavailable / error message, item 1), and the empty state also
+ **appends** an error row when `status.state === Error && errorMessage`. These rows have no command and no
+ menu — they exist only to show a string, which then **truncates** in the tree (the incident's "…saved
+ credentials are miss…"), can't be copied, and competes visually with the real action row.
+- This contradicts where the rest of the extension landed. The **Kubernetes discovery** review reached
+ exactly this conclusion and reversed it: classified in-tree error-summary nodes were **removed** in favor
+ of a **modal** (`showErrorMessage(…, { modal: true })`) plus a single actionable retry node. Quick Start
+ currently repeats the anti-pattern the K8s feature already retired.
+
+💡 **Suggestion:** Adopt the same rule feature-wide: **tree rows are actions; errors are dialogs / status.**
+(a) surface an error/credential-unavailable condition as a **modal** (detail in the output channel), and
+(b) keep **only actionable rows** in the tree (Delete / Recreate / Retry / "Click here to…"). This removes
+the passive `treeItem_quickStartError` and the error-append row and directly fixes item 1's dead end. It
+also rhymes with item 3 (the webview header carrying status it shouldn't) — the same "don't overload one
+surface with state it isn't meant to hold" theme.
+
+### 5. Error/status messages must leave the hero — show a content-area card; run a small UX experiment ⚠️💡
+
+**Priority:** P1 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards static hero + inline error card** (this was my original suggestion when I reported
+> the issue). Prototype variants **A/B/C** and pick per-state, with **Retry on the card**. _Because the
+> message belongs in the content area as an actionable card, not in the hero._
+
+**Observation:** We have error/status states (e.g. Docker missing). The core requirement: these messages
+**must not live in the hero section** — the hero stays constant and the message becomes a **card in the
+content area** with the actions the user can perform. Query Insights already has good building blocks — not
+just the `MessageBar`, but the **richer composed card** shown when an RU user opens the Query Insights tab;
+the two **could be combined**. Because it isn't obvious which shape reads best, whoever implements this
+should **render a few options to compare**. We also need to decide **where Retry lives**.
+
+**Finding:**
+
+- ⚠️ Today an error is handled by switching to a **dedicated phase that replaces the hero**: `dockerNotReady`
+ swaps the hero to _"Docker is required"_ and renders a bespoke full-screen layout (three readiness cards +
+ a "How to fix" card + a bottom `Retry`); the `failed` phase similarly shows an error box with the hero
+ **stuck** on _"Setting up…"_ (item 3). So the message is **coupled to the hero**.
+- 🔍 **Query Insights ships two reusable shapes**, both leaving the header/title untouched:
+ - **Concise inline `MessageBar`.**
+ [`GetPerformanceInsightsCard.tsx`](../../../../src/webviews/documentdb/collectionView/components/queryInsightsTab/components/optimizationCards/custom/GetPerformanceInsightsCard.tsx)
+ renders a Fluent `MessageBar` when `errorMessage` is set and **relabels its primary button to "Retry"**:
+ `{errorMessage ? l10n.t('Retry') : l10n.t('Get AI Performance Insights')}`. The card title never changes.
+ [`ImprovementCard.tsx`](../../../../src/webviews/documentdb/collectionView/components/queryInsightsTab/components/optimizationCards/ImprovementCard.tsx)
+ uses the same `MessageBar intent="warning"` / `"success"` blocks for per-action state.
+ - **Richer composed card (the RU-tab card).**
+ [`QueryInsightsTab.tsx`](../../../../src/webviews/documentdb/collectionView/components/queryInsightsTab/QueryInsightsTab.tsx)
+ (the `QUERY_INSIGHTS_PLATFORM_NOT_SUPPORTED_RU` branch) renders a **`MarkdownCardEx`** — icon + title +
+ markdown body + a call-to-action — and **nests a `MessageBar` inside it** for the concise status line. So
+ "card" and "message bar" are **already combined** there.
+
+💡 **Suggestion:**
+
+1. **Get the message out of the hero.** Keep the hero **static** (item 3) and render error/status as a
+ **content-area card**, never as a hero swap or a full-screen phase. Applies to docker-not-ready and `failed`.
+2. **Combine the two shapes, and experiment.** Render a few candidate variants to compare, e.g.: **A** plain
+ `MessageBar` + inline Retry (lightest); **B** composed card (`MarkdownCardEx`-style: icon + title + body +
+ actions); **C** combined (composed card **containing** a `MessageBar`, matching the RU tab). Test A/B/C
+ against the real states (Docker missing, provisioning failed, readiness timeout) and pick per-state.
+3. **Retry placement:** put `Retry` **on the chosen card**, next to the other recovery actions, following the
+ Query Insights convention of relabeling the card's primary action to "Retry." The retry logic already
+ exists (`loadDockerStatus` / `handleStart`); only its home changes.
+4. Pairs with item 4 (tree side) — the same principle applied to the webview.
+
+### 6. "Delete deletes data" vs "Recreate / recover" — resolve the contradiction ⚠️💡
+
+**Priority:** P1 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards no recovery at all** — **Delete always wipes everything**; there is no "keep data"
+> / Recreate-onto-surviving-volume path. Keep the code **and** the UX simple. Advanced data-retention
+> scenarios are **out of scope** — users who want to retain data can manage their local instances with
+> the Docker CLI/tools directly. Missing/error copy just states the instance is gone and should be
+> removed; no contradiction because there is no recovery to promise. _Because edge cases should stay
+> simple and cheap, not grow a recovery subsystem._
+
+**Observation:** We tell the user that **deleting deletes the data** — so then what does **recreate /
+recovery** mean? The two messages appear to contradict each other.
+
+**Finding / the tension:**
+
+- **Delete Container** is a permanent wipe: it removes the container **and the data volume** and all stored
+ creds/records (items 8 / 23) — "this cannot be undone."
+- The recovery flows for `Missing` / credential-unavailable (items 1 / 2) offer **"Recreate with same
+ settings,"** meaningful only because the **data volume is kept** and stored credentials are reused
+ (`getReusableCredentials`). "Recreate" = "the container vanished but your data on the volume survived;
+ rebuild the container onto it."
+- Both are true but the vocabulary collides: **Delete** = destroy the data (no recovery); **Recreate** =
+ recover _because_ the data was not deleted (the container went away, not the volume).
+
+💡 **Discussion / suggestion:** Make the model explicit by separating **container** from **data**:
+
+- **Option (a) — one Delete that always wipes both (current).** Then "recreate" appears **only** when the
+ _container_ was lost externally but the volume remains, and its copy must say _"your data on disk is intact
+ — this rebuilds the container onto it,"_ never implying it undoes a Delete.
+- **Option (b) — split the verbs:** **Remove container (keep data)** vs **Delete everything (container +
+ data).** Then "recreate" pairs naturally with the keep-data path; no contradiction. Cleaner, more surface.
+
+> Whichever is chosen, never present "recreate / recover" and "deleting deletes your data" as if they act on
+> the **same** object. Pairs with Open idea O4 (recovery affordance) and O6 (volume model).
+
+### 7. "Copy Connection String" is a separate impl and silently includes the password ⚠️
+
+**Priority:** P1 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards reuse** — use the standard `copyConnectionString()` with/without-password QuickPick
+> for parity, instead of the separate silent-copy path. _Because it's a plaintext secret going to the
+> clipboard; consistency with every other connection wins._
+
+**Observation:** Copy Connection String seems reimplemented for Quick Start and behaves slightly differently
+— it doesn't ask whether to include the password.
+
+**Finding:** Regular clusters use `copyConnectionString()`
+([copyConnectionString.ts](../../../../src/commands/copyConnectionString/copyConnectionString.ts)), which
+prompts via `showQuickPick` ("with password" vs "without password", gated by `canIncludeNativePassword()`)
+and is well-tested. Quick Start uses a **separate, shorter** `copyQuickStartConnectionString()`
+([localQuickStartCommands.ts](../../../../src/commands/localQuickStart/localQuickStartCommands.ts)) that
+copies `metadata.connectionString` (password already embedded) **with no prompt** — a genuine behavioral
+difference. ⚠️ A plaintext password always lands on the clipboard silently, which stands out given how
+careful the rest of the feature is about credentials (masked logging, env-file instead of CLI args). There
+is a _separate_ `copyQuickStartPassword()` command, but the connection-string action itself never asks.
+
+💡 **Suggestion:** Reuse the regular command's QuickPick confirmation for parity (Quick Start always uses
+native auth, so no extra branching is needed), or — if the extra click is unwanted for a one-click-local
+flow — at minimum make the two commands' behavior a **conscious, documented** choice rather than an
+incidental divergence.
+
+### 8. "Delete Container" bypasses the shared confirmation and uses em dashes ⚠️
+
+**Priority:** P1 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards switching** to `getConfirmationAsInSettings()` (so it honors the user's
+> confirmation style) **and updating the wording** — including the feature-wide em-dash sweep. _Because
+> a destructive action should match every other destructive command in the extension._
+
+**Observation:** The Delete Container modal is fine conceptually, but it should use the same delete
+confirmation code path as other destructive actions (like in Settings), and shouldn't use em dashes.
+
+**Finding:**
+
+- ⚠️ Every other destructive command — [removeConnection](../../../../src/commands/removeConnection/removeConnection.ts),
+ [deleteCollection](../../../../src/commands/deleteCollection/deleteCollection.ts),
+ [deleteDatabase](../../../../src/commands/deleteDatabase/deleteDatabase.ts),
+ [folder delete](../../../../src/commands/connections-view/deleteFolder/ConfirmDeleteStep.ts) — calls
+ **`getConfirmationAsInSettings()`** ([getConfirmation.ts](../../../../src/utils/dialogs/getConfirmation.ts)),
+ which honors the user's `confirmationStyle` setting (type-the-word / number challenge / click).
+ `deleteQuickStartInstance()` instead calls **`getConfirmationWithClick()`** directly, ignoring that
+ setting — the only _destructive_ command that does (the other direct callers are non-destructive:
+ `hideIndex`/`unhideIndex`).
+- ⚠️ Its two confirmation `detail` strings both contain a literal **em dash** ("…This cannot be undone — you
+ can recreate…"). The character also appears across the feature's other strings (`LocalQuickStart.tsx`
+ next-steps bullets, the item 18 timeout message).
+
+💡 **Suggestion:** Switch Delete Container to **`getConfirmationAsInSettings()`** for consistency (decide the
+confirmation word — a simple `delete` matches the other delete flows). Separately, do a **one-pass em-dash
+sweep** of the whole feature's user-facing strings rather than fixing only the delete dialog.
+
+### 9. We should only ever delete containers we created (pre-release safety) ⚠️
+
+**Priority:** P1 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards a hard label precondition on every removal, no exceptions.** Re-verify the
+> `vscode.documentdb.quickstart` label immediately before `removeContainer`/`removeVolume`. If a
+> container is **not** ours, **do not delete it** — show a warning that it can't be removed because it
+> was **created outside the extension**. _Because we must never remove a container/volume we didn't
+> create._
+
+**Observation:** Not urgent now, but must be addressed **before final release**: we should be allowed to
+delete **only** the containers we created.
+
+**Finding:** 🔍 Removal is already label-guarded in the normal path — `deleteContainer()` only removes when
+`entry.missing || isManaged(id)`, and `isManaged()` verifies the `vscode.documentdb.quickstart` label. But
+there are softer spots: on `entry.missing` the label re-check is **skipped** (the id comes from metadata /
+`findManagedContainer`, which filters by label, so it is _currently_ safe but relies on that invariant), and
+`ContainerRuntime.removeContainer()` itself does **no** label check. As the feature grows (multi-instance,
+user-named containers, more recovery flows), an id-based delete without a label re-verify is a latent risk.
+
+💡 **Suggestion:** Before final release, make "ours" a **hard precondition on every removal** — re-verify the
+`vscode.documentdb.quickstart` label immediately before `removeContainer` / `removeVolume`, regardless of the
+`missing` shortcut, so no code path can ever remove a container or volume the extension didn't create.
+
+---
+
+## P2 — Polish, expectation, or feature gap
+
+### 10. Legacy emulator connections migrate to a folder that can hide in the sort order ⚠️🔍
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards the cheap `_`-prefix only** (Open idea O1 · E) — rename the folder to
+> `_Local Connections (Legacy)` so it floats to the top with zero sort/render code. **No toast, no
+> badge** for now. _Because the user base is still small; this isn't worth a bigger investment yet._
+
+**Observation:** Is the one-time migration of original "DocumentDB Local" emulator connections still
+happening? What's the folder called? Sorting could place it somewhere unexpected.
+
+**Finding:**
+
+- 🔍 Yes, it's still active. The migration lives in
+ [legacyEmulatorMigration.ts](../../../../src/services/legacyEmulatorMigration.ts), invoked from
+ [ClustersExtension.ts](../../../../src/documentdb/ClustersExtension.ts) on every activation
+ (`migrateLegacyEmulatorConnections`), guarded by a `globalState` flag so it runs once.
+- 🔍 The destination folder is **`Local Connections (Legacy)`** (`LEGACY_FOLDER_BASE_NAME`), deterministic id
+ `vscode-documentdb.legacyLocalConnectionsFolder`; a name clash is suffixed `(2)`, `(3)`, … It is a **normal**
+ renamable/movable folder under the Clusters zone. Emulators-zone sub-folders are intentionally **flattened**
+ into this one folder. The old `Emulators` zone/`LocalEmulatorsItem` node is kept as a read-only rollback
+ until migration succeeds, then retired.
+- ⚠️ **Why it can surprise:** root items are assembled Quick Start node → legacy emulator node (if un-migrated)
+ → **all folders, alphabetically** → ungrouped connections → New Connection. Folders sort with a single
+ `localeCompare(..., { numeric: true })` pass with **no special-casing**, so the legacy folder lands wherever
+ "L…" falls — easy to miss right after an upgrade. No migration toast surfaced in this pass.
+
+💡 **Suggestion:** Make the destination discoverable: (a) a **one-time toast** with a "Reveal" action; and/or
+(b) a distinct badge/icon; and/or (c) pin it; the cheapest code-free option is (e) prefix the name with `_`.
+See Open idea O1.
+
+### 11. Phase out the "local connection" concept — a localhost connection is just a connection 💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN suggests deferring to a follow-up issue (the team may revisit).
+
+> **TN leans towards a separate follow-up issue** — this is a larger cleanup and **should not be part of
+> this PR.** Track it independently and sequence it after the Quick Start bugs land. _Because bundling a
+> broad deprecation into this PR would balloon its scope._
+
+**Observation:** Ideally we **phase out** the notion of a special "local connection" entirely. A connection to
+`localhost` is just a **regular connection that happens to point at localhost**. Once that lands there is no
+separate "Local Connections" bucket, no emulator zone, no special-casing — which requires a **sweep of the
+documentation, menus, commands, and wording**.
+
+**Finding / scope:**
+
+- Today the code still carries the legacy split: an `Emulators` storage zone, `LocalEmulatorsItem`,
+ `emulatorConfiguration.isEmulator`, the migration to `Local Connections (Legacy)` (item 10), and the Quick
+ Start managed instance (a bespoke non-standard node, item 20). Several menus / `when`-clauses key off
+ `treeItem_LocalEmulators` and `isEmulator`.
+- End state: a localhost connection is a normal `DocumentDBClusterItem` in the regular Clusters zone;
+ "emulator-ness" (e.g. allow-invalid-TLS) becomes a **property of the connection**, not a separate class /
+ zone / tree node.
+
+💡 **Suggestion:** Track as an explicit **deprecation/cleanup epic**: (a) inventory every place that
+special-cases "local/emulator"; (b) collapse them onto "a regular connection to localhost"; (c) keep only the
+minimal per-connection flags a local target needs. Item 10's legacy folder and the Quick Start node (item 20)
+both fold into this end state.
+
+### 12. The initial "Checking Docker" loading should render chrome + skeleton cards (reuse the metric card) ⚠️💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards both** — render the chrome + skeleton cards immediately (fill independently) **and**
+> reuse + relocate the accessible Query Insights `MetricBase`. _Because it fixes the snap-in jump and
+> gives us one shared, accessible metric card._
+
+**Observation:** The initial `loading` ("Checking Docker") state should behave like the **Query Insights**
+view: the chrome renders immediately (title + header), and the cards behave like our **metrics cards** — a
+**loading skeleton** while status resolves, then fill **independently** (backend split not needed now). Worth
+**reusing the existing metric card** — it's accessible and has tooltip support.
+
+**Finding:**
+
+- ⚠️ The `loading` phase renders **only** `` in an otherwise empty panel —
+ no hero, no cards (see Appendix A). When `getDockerStatus` resolves, the panel **snaps** to the full layout.
+- 🔍 The readiness/config cards use a **local, simplified** `MetricCard` inline in `LocalQuickStart.tsx` — no
+ skeleton, no tooltip, weaker a11y.
+- 🔍 Query Insights ships a purpose-built, accessible card: **`MetricBase`** at
+ [MetricBase.tsx](../../../../src/webviews/documentdb/collectionView/components/queryInsightsTab/components/metricsRow/MetricBase.tsx)
+ — **loading skeleton** (`value === undefined` → `SkeletonItem`), null/unavailable placeholder, **tooltip
+ explanations**, and a solid **accessibility** pattern (focusable card, aria-label, aria-hidden children).
+
+💡 **Suggestion:** (1) Rework `loading` to render the **hero immediately** and the readiness cards in
+**skeleton** state, each flipping to its value independently. (2) **Reuse `MetricBase`** instead of the local
+`MetricCard` — it needs a small **extension** (a badge slot for the ✓/! readiness badge) and **relocation to a
+shared** location (it's currently buried under `collectionView/queryInsightsTab/`; importing it into Quick
+Start is the wrong dependency direction). Worth it: one accessible, tooltip-capable card shared across features.
+
+### 13. Advanced panel: credentials should sit behind a toggle, and "placeholder = default" is ambiguous ⚠️💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards: (1) credentials behind an "override" toggle**, and **(2) placeholder Option A** —
+> the default lives **only in the hint line**, with an explanation that **the default is applied when the
+> field is left empty** (no literal-value ghost text). Apply the same convention to every Advanced field.
+> _Because "blank = default" only reads honestly when the box actually looks empty._
+
+**Observation:** Username + password should be grouped **behind a toggle** — the user flips "override the
+default" and only then specifies them. The ghost text **"auto"** is confusing (is it the default _value_?).
+And the panel label says _"Leave any field blank to keep the automatic default,"_ yet the **Image tag** field
+shows **"latest"** as ghost text — so how does the user "keep it blank"?
+
+**Finding** (`renderAdvanced()` in `LocalQuickStart.tsx`):
+
+- On a fresh provision (`!isRecreate`) the panel renders Port, Image tag, Username, Password (always visible) +
+ a "Load sample data" switch, under "Leave any field blank to keep the automatic default."
+- ⚠️ **Placeholder means two different things.** Port's placeholder is the literal default (`10260`), Image
+ tag's is the literal default tag (`latest`) — but Username/Password use **`'auto'`**, a _description of
+ behavior_. So "latest" reads as a set value, while "auto" reads as a mode; combined with "leave blank," the
+ greyed-in `latest` makes it unclear whether the field is pre-filled or empty.
+- 🔍 The credentials already follow a **both-or-neither** rule in `advValidation`; a toggle would encode that
+ structurally.
+- 🔍 On a recreate the credential/tag fields are already hidden — so this only concerns fresh provisioning.
+
+💡 **Suggestion:** (1) **Group credentials behind a toggle** ("Override generated credentials," off by
+default; off → a read-only "Auto-generated, stored securely" note; on → reveal both fields, required
+together) — removes the `'auto'` ghost text entirely. (2) **Resolve the placeholder ambiguity**, options to
+weigh: **A** drop literal-value placeholders and keep the default only in the `hint` line (cheapest, most
+consistent); **B** pre-fill the actual default value and drop the "blank" concept; **C** a per-field "Use
+default" affordance (heavier). Leaning **A**. Whichever is chosen, apply the **same** convention to every
+Advanced field.
+
+### 14. What does "Cancel" do mid-provision? Consider the verb "Abort" (no full rollback promise) ⚠️💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards the "Abort" wording**, and — **even on abort** — **show the "what was done" summary**
+> (cf. item 15) so there's full clarity about what happened (e.g. the image was kept). _Because "Abort"
+> sets honest expectations and the summary removes any ambiguity about residual state._
+
+**Observation:** Investigate what **Cancel** does while provisioning is in progress. Do we **delete an image
+that started downloading**, or just abort? A clean rollback is hard to promise, so **"Abort"** may be a cleaner
+verb — "Cancel" implies cancel-and-roll-back.
+
+**Finding** (traced in `provision()`, `QuickStartService.ts`): **abort, with partial cleanup — but the image is
+kept.** On cancel (Cancel → `AbortSignal` → `onAbort` fires `cts.cancel()`):
+
+- 🔍 The in-flight Docker command is **aborted** via the cancellation token — a `docker pull` stops promptly.
+- 🔍 In `finally`, cleanup is **container-scoped only** (D12): a created container is stopped + removed; an
+ uncaptured-id orphan is swept by label; the temp env-file is deleted; state resets `Provisioning →
+NotInstalled`.
+- ⚠️ **The image is never deleted.** Nothing calls `removeImage`; already-fetched layers **stay in Docker's
+ cache** (by design — a resumable/cached pull makes the next attempt fast). So Cancel is a **partial** rollback:
+ the container is removed, the image download is retained.
+
+💡 **Suggestion:** (1) **Rename to "Abort"** (or "Stop setup") — "Cancel" over-promises. (2) **Say what's kept**
+by the button ("Stops setup. The downloaded image is kept so a retry is faster."). (3) **Confirm per phase**
+(pull/creating/starting/waiting) that nothing orphans besides the intentional image cache. (4) If a full
+"remove everything incl. image" is ever wanted, make it a **separate explicit** action, never the default.
+
+### 15. On completion, show a "What was done" summary card — below the content ⚠️💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards yes** — mirror the review screen: **"what we'll do" → "what was done."** It must be
+> easy to grasp at a glance (users are busy). _Because the symmetry makes the outcome obvious and
+> surfaces the real bound port/creds._
+
+**Observation:** When a deployment completes, the info card should render **below** the other content (not
+above), and carry a **summary of what was done** — a table-ish block like the review screen's "what we'll do"
+summary, but framed as **"What was done."**
+
+**Finding:**
+
+- The `review` phase already renders a summary (`renderSummary()` in `LocalQuickStart.tsx`) — a labeled
+ key/value block (image, port, data, credentials, lifetime). The `success` phase instead shows a free-text
+ success box + a "Next steps" list, with **no structured recap**, and that content sits high in the layout.
+- Because the real values are only known **after** provisioning (a **port fallback** may have moved the
+ instance off 10260), a recap is the natural place to surface them — today the actual port / credentials /
+ connection string aren't summarized anywhere in-panel.
+
+💡 **Suggestion:** Add a **"What was done"** summary card mirroring `renderSummary()`, rendered **below** the
+next-steps / actions, listing the **actual** result: image + resolved tag, **actual bound port** (flag if it
+differs from the default), data mode (persistent/ephemeral), credentials (auto/custom, stored securely), and
+the connection string with its copy affordance. Gives a clean "review → result" symmetry and finally surfaces
+the real port.
+
+### 16. Set an upfront "the first run can take a few minutes" expectation 💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards yes** — have the one-liner ready (review screen and/or provisioning subtitle),
+> distinguishing first-run from a restart. _Because it reframes a long cold start from "stuck" to
+> "expected."_
+
+**Observation:** Whatever we can do to set expectations up front — a cold first run is genuinely long.
+
+**Finding:** A first provision does a lot — Docker pull, container create/start, a readiness wait of up to
+`READINESS_TIMEOUT_MS = 180_000` (3 min, item 18), plus first-run TLS cert generation and sample-data seeding.
+The only time cue today is the elapsed counter ticking up.
+
+💡 **Suggestion:** State the expectation before / at the start of provisioning — a one-liner on the review
+screen ("The first run downloads the image and initializes the database; this can take a few minutes") and/or
+a provisioning subtitle. Later runs are fast (image cached, item 14), so the copy can distinguish "first run"
+from a restart.
+
+### 17. "Load sample data" is all-or-nothing — add a choice of test data ⚠️💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning; needs investigation (the team may revisit).
+
+> **TN leans towards a multiselect dropdown** of datasets to preload — **but the data source needs
+> discussion.** The current tiny "5 docs per container" sample is weak; consider a **custom-file picker**
+> (the Docker image may support loading one). **Whoever implements this must investigate** where the data
+> should come from and what the image supports. _Because a real, richer, choosable dataset is far more
+> useful than a fixed toy sample._
+
+**Observation:** The sample-data option is all-or-nothing today. We'll have to add **options to choose the test
+data** (which dataset, or none).
+
+**Finding:** `AdvancedQuickStartOptions.loadSampleData` is a single boolean; when true the image's built-in
+init seeds one fixed `sampledb` (users / products / orders / analytics) once, post-readiness (exec-once).
+There's no way to pick a dataset, see what it contains, or reseed later.
+
+💡 **Suggestion:** Replace the boolean with a **dataset choice** (None / the current sample / future named sets),
+ideally with a one-line description of each. Keep exec-once semantics per dataset; sets up a later
+"reset/reseed." Scope depends on what datasets the image can provide — confirm with the image owners.
+
+### 18. "Waiting for DocumentDB to accept connections" can sit static for minutes ⚠️
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning; needs investigation (the team may revisit).
+
+> **TN leans towards no fake sub-timer / no simulated progress** (it doesn't help). Prefer **real
+> signal**; if none is available, iterate a **rotating one-liner** (toggle ~every 2 s) that explains
+> what's happening in general — e.g. _"waiting for the container to initialize"_, _"waiting for data to
+> preload"_, _"waiting for network config…"_ — to keep the user engaged. **Real data would be truly
+> better — investigative task.** _Because honest signal beats a spinner, and simulated progress is
+> worse than none._
+
+**Observation:** This message could be reworded, or show intermediate progress as sub-info, since it can take a
+while.
+
+**Finding:** The stage label is `'Waiting for DocumentDB to accept connections'`. It wraps `waitForReadiness()`
+in `QuickStartService.ts`, which polls the wire protocol with a **`READINESS_TIMEOUT_MS = 180_000` (3 min)**
+budget and a 3 s per-attempt timeout. During that window the stage row shows only a spinner + the same static
+label — ⚠️ **no in-panel sub-status**. Logs stream to the output channel via `followLogs` the whole time, just
+not in the panel. On timeout a distinct `ReadinessTimeoutError` (kept separate so the container is preserved for
+"Wait longer") shows the `failed`/`timedOut` message (contains an em dash — item 8).
+
+💡 **Suggestion:** Add a lightweight **sub-info line** while active — an **in-stage elapsed timer** and/or a
+rotating reassurance after N seconds ("first run generates TLS certs, this can take a minute"). Consider
+surfacing "View Docker output" _during_ this stage (it currently only appears at the bottom).
+
+### 19. No structured progress while the image downloads ⚠️
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning; needs investigation (the team may revisit).
+
+> **TN leans towards keeping the spinner** (we already show one per sub-progress stage) and adding
+> **extra info** rather than a fake intermediate bar. Ask the implementer to **experiment**: an
+> **N-of-M layers** progress bar could still help even though **M is a moving target** (our knowledge of
+> the layer count grows during the pull); or better, a **megabytes-downloaded counter** — showing data
+> flowing is a strong "something is happening" signal. **Investigate** what real numbers Docker gives us
+> (layer counts and/or byte totals). _Because real throughput/bytes beats a decorative bar._
+
+**Observation:** Do we track progress while the image is pulled? It's a long-running op too.
+
+**Finding:** ⚠️ No. `provision()` yields one `active` event (`'Pulling the official image…'`), awaits
+`pullImage()`, then one `done` event — nothing in between. `ContainerRuntime.pullImage()`
+([ContainerRuntime.ts](../../../../src/services/localQuickStart/ContainerRuntime.ts)) runs `docker pull`
+through the shared CLI shell-runner, piping stdout/stderr **only** to the output channel. Docker's per-layer
+progress is visible only as raw channel text, never in the webview — a spinner + static label for the whole
+pull, same as item 18.
+
+💡 **Suggestion:** Give the pull an **indeterminate but alive** treatment — a Fluent UI **indeterminate
+`ProgressBar`** + a small live **"N of M layers"** sub-label (count distinct layer ids vs. `Pull complete`
+lines). Full options in Open idea O2.
+
+### 20. The running-instance row doesn't share regular cluster context commands 🔍
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards keeping the replaced contextValue** rather than filtering Quick Start out of every
+> menu. Adding `&& not quickstart` to every generic cluster command is worse than adding `|| quickstart`
+> to the **few** we want (e.g. Open in Shell). Model the Quick Start row as a **sub-view** of the
+> connections view: **replace the connections-view context entry with a sub-view marker**, then
+> **explicitly opt specific commands in via `or`**. Ask the implementer to **spend time getting this
+> simple and maintainable** for future maintainers (the extra `view`/sub-view layer adds complexity if
+> done carelessly). _Because opt-in on a short allowlist is cleaner than opt-out on everything._
+
+**Observation:** The running managed instance doesn't share context-menu commands with regular clusters. Do we
+still extend the cluster base class? If not, what would break if we did?
+
+**Finding:**
+
+- 🔍 Yes — `QuickStartClusterItem extends DocumentDBClusterItem`. It overrides `getTreeItem()` only to force the
+ state-aware description and reuses the base for icon/tooltip/browsing.
+- 🔍 Regular commands don't appear because the **contextValue is fully replaced, not extended:** the constructor
+ sets `contextValue = createContextValue([INSTANCE_CONTEXT, stateToken])` — `treeItem_quickStartInstance` +
+ `state_running` — discarding the base's `treeitem_documentdbcluster` token every regular-cluster `when`-clause
+ matches on. Deliberate (show Quick Start lifecycle actions "instead of the generic cluster menus").
+- 🔍 **What would break if kept too:** the generic commands assume a **stored** connection (`removeConnection`,
+ `moveItems`/`renameConnection`, `update*` all hit storage). The Quick Start instance is **in-memory only**, so
+ those would act on a record that doesn't exist — silent no-ops/exceptions — unless each special-cased this row.
+ So full replacement avoids a bug class, but throws out useful storage-independent commands (e.g. "Open in Shell").
+
+💡 **Suggestion:** Keep the curated menu, but **add back storage-independent commands explicitly** ("Open in
+Shell" / "New Query"). The clean version is splitting the base contextValue into storage vs connection subsets —
+Open idea O3.
+
+### 21. Credential storage: reuse the extension's secure-storage patterns 💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards attempting to reuse** the `ConnectionStorageService` secure-storage patterns. Can
+> be a follow-up, but **better in this release** so we don't have to deal with a connection/credential
+> **migration** later. _Because doing it now avoids a migration debt._
+
+**Observation:** Flag the plaintext-password posture. Everything else is careful (masked logs, env-files), yet
+the generated password is embedded in the stored connection string and is one-click copyable/visible. **Think
+about clean storage** — can we use our **storage services**? There's solid secret-management already; we can
+**replicate / copy** those patterns. No big refactor needed.
+
+**Finding:**
+
+- Quick Start stores its connection string (credentials embedded) via `ext.secretStorage` under a per-alias key
+ (`secretKey(alias)`) and primes `CredentialCache` from it — a bespoke path, separate from how regular
+ connections handle secrets.
+- The extension already has a mature secure-storage layer (`ConnectionStorageService` + its credential/secret
+ handling), with established patterns for storing/retrieving credentials cleanly and gating exposure. Quick
+ Start doesn't reuse it (by design it's "not stored in any zone," item 20), so it re-implements a thinner version.
+
+💡 **Suggestion:** Align Quick Start's credential handling with the existing secure-storage patterns — reuse
+`ConnectionStorageService`'s secret mechanisms or **copy the same approach** (replicating is fine). Goal: one
+consistent, audited way to store/expose local credentials. Ties into item 11: if local instances become regular
+connections, they inherit this storage naturally.
+
+### 22. Persistence is always on — there's no "ephemeral / no-persistence" option 💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards adding the ephemeral toggle** ("Persist data across restarts," default on). _Because
+> more options here are easy for the user and genuinely helpful for throwaway trials._
+
+**Observation:** Our default is a persistent data volume. That should be a **toggle** — sometimes a user wants a
+throwaway instance with no persistence.
+
+**Finding:** 🔍 `AdvancedQuickStartOptions`
+([quickStartTypes.ts](../../../../src/services/localQuickStart/quickStartTypes.ts)) exposes `port`, `username`,
+`password`, `imageTag`, `loadSampleData` — but **no persistence flag**. `createAndRunContainer()` **always**
+mounts a named volume (`volumeName(alias)` at `QUICK_START_DATA_PATH`). Every instance is persistent by
+construction; no way to opt out.
+
+💡 **Suggestion:** Add an Advanced toggle **"Persist data across restarts"** (default **on**). When **off**,
+create the container **without** the named-volume mount so data lives only in the writable layer and is gone on
+delete — good for throwaway trials. Trade-offs in Open idea O6.
+
+### 23. A user-initiated delete must always delete the data volume ⚠️
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards always dropping the volume** on a user delete (every user-initiated delete routes
+> through `deleteContainer()`). _Because minimizing moving parts lowers the user's mental load — fewer
+> things to understand, more happiness._
+
+**Observation:** When the user deletes a container, we should for sure delete the persisted volume as well.
+
+**Finding:** 🔍 The explicit **Delete Container** path already does this: `deleteContainer()` calls
+`removeVolume(volumeName(alias))` alongside the secret / globalState / registry cleanup — an intentional "full
+clean slate." Two caveats: (a) the credential-unavailable **reconcile** path deliberately does **not** touch the
+volume (R2, item 1), correct for an automatic path but it means the _user-initiated_ delete must remain the thing
+that wipes it; (b) once item 1 makes the credential-unavailable state actionable, its Delete must route through
+this same volume-removing path.
+
+💡 **Suggestion:** Keep explicit Delete = remove container **+ volume** (already the case). Ensure every
+**user-initiated** delete surface funnels through `deleteContainer()` so a volume is never orphaned. Automatic /
+reconcile paths keep R2 (never auto-wipe without the user choosing it).
+
+### 24. Data volumes should be linked to the image — no shared data volumes 💡
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards structural image↔volume linkage, no cross-image sharing.** _Because it keeps the
+> model simple to understand for the user (one image, one volume)._
+
+**Observation:** Our persisted volumes should be **linked to the image**. We won't share data volumes across
+images; advanced users can do that themselves.
+
+**Finding:** 🔍 Today the volume is keyed to the **alias** (`${alias}-data`), independent of the image. To stay
+safe, the service **pins the image to the volume**: on a recreate it reuses the stored `imageRef` rather than
+the user's requested tag, and custom image/creds are ignored on a Missing-recreate — so an existing volume isn't
+opened by a different image version that could corrupt it. So the intent ("one image ↔ one volume") is enforced
+by _runtime pinning_, but the volume is not _named/keyed_ by image.
+
+💡 **Suggestion:** Make the linkage **structural** — key or label the volume by its image so "one image ↔ one
+data volume" is guaranteed even if the pinning logic changes. Do **not** implement cross-image volume sharing;
+leave that to advanced users operating Docker directly.
+
+### 25. The container keeps running after VS Code closes — decide the desired behavior ⚠️💡
+
+**Priority:** P2 · **Status:** 🟡 Open · investigate first — TN leans to keeping always-on (the team may revisit).
+
+> **TN leans towards always-on** for now. The "stop on exit" setting is **worrying**: on extension
+> **deactivation** we may not get enough time to clean up before the process is killed — this could be a
+> real problem. **Investigate first** how much time VS Code actually gives us on deactivate. Only if we
+> truly have that control should we consider a **modal on quit** ("keep the container running?"). The
+> suspicion is that we **don't** have that level of control in extensions, so the default stays
+> always-on. _Because promising a clean stop we can't guarantee is worse than a clear always-on._
+
+**Observation:** Non-standard for an extension-managed local resource (a user may expect it to stop like a dev
+server), and can leave an orphaned container holding a port + RAM.
+
+**Finding:** By design the instance is durable across window reloads — `reconcile()` re-adopts a still-running
+container on activation (item 1) — and the success screen explicitly says it "keeps running after VS Code
+closes." There's no "stop on exit" option and no prompt on close.
+
+💡 **Suggestion:** Treat as an **open decision** — pros/cons in Open idea O7. Don't change behavior without
+deciding; whatever is chosen should be **explicit** (a setting and/or clear copy) rather than implicit.
+
+### 26. Tree state transitions aren't announced — accessibility work item (post-redesign; discuss with Tomasz) ⚠️
+
+**Priority:** P2 · **Status:** 🟠 Open — TN leaning; post-redesign a11y work item (the team may revisit).
+
+> **TN leans towards confirmed** — keep this as a **sequenced post-webview-redesign** accessibility work
+> item, applying past accessibility-testing learnings; **owner/approach to be agreed with Tomasz.** No
+> change now.
+
+**Observation:** The webview is carefully accessible, but the **tree** state rows (Starting / Stopping / Missing
+/ Running) change only their `description` text + icon, with no live-region announcement, so screen-reader users
+don't hear the instance change state. This should be worked on **once the webview redesigns finish**, applying
+our **learnings from past accessibility testing**. **Discuss with Tomasz.**
+
+**Finding:** State changes fire `onDidChangeStatus` → `refresh()`, re-rendering the row, but VS Code tree views
+have no built-in live region, so a `description` change (e.g. "Starting…" → "Running · localhost:10260") is
+silent to assistive tech. The webview, by contrast, uses `Announcer` / `aria-live` deliberately.
+
+💡 **Suggestion (requirement, sequenced):** After the webview redesign lands, do a dedicated accessibility pass on
+the tree — announce meaningful state transitions (within VS Code tree API limits), carry state in accessible
+labels, and apply the patterns from prior accessibility testing. **Owner / priority / approach to be agreed with
+Tomasz** before implementation.
+
+---
+
+## P3 — Nice-to-have / cosmetic / acknowledged
+
+### 27. Docker prerequisite is only revealed after opening the webview 🔍
+
+**Priority:** P3 · **Status:** 🟡 Open — TN suggests leaving as-is, no tooltip (the team may revisit).
+
+> **TN leans towards no tooltip** — users will open the webview and find out that Docker is required,
+> which is **good enough**. A prerequisite hint may matter more in the future if we add **other container
+> runtimes** beyond Docker. _Because it's a cheap-but-unnecessary hint for a single-runtime feature
+> today._
+
+**Observation:** The empty-state row invites "Click here to start DocumentDB Local," but the hard **Docker
+requirement** only surfaces once the webview opens (the `dockerNotReady` screen). Recorded so it isn't
+re-discovered later as a surprise.
+
+**Finding:** The tree node / action row carries no hint that Docker is required; the prerequisite check
+(`getDockerStatus`) runs only after the panel opens, so a user without Docker commits to the click before
+learning they need it.
+
+💡 **Suggestion (acknowledged / not planned now):** If ever revisited, signal the prerequisite earlier — a node
+tooltip / description ("Requires Docker") or a hover.
+
+### 28. Icons are all inherited/generic — nothing marks "this is the Quick Start instance" 🔍💡
+
+**Priority:** P3 · **Status:** 🟠 Open — TN leaning (a suggestion; the team may revisit).
+
+> **TN leans towards a better, distinct icon set** — use the **rocket for user-created Quick Start
+> instances** (so they're easy to tell apart) and **something else** for other/ambient images that just
+> happen to be around. _Because the icon should signal "this is the one you created via Quick Start."_
+
+**Observation:** How are the icons chosen for the Quick Start instances?
+
+**Finding:** 🔍 No bespoke icon set. **Root node:** the extension's product icon. **Running row:** no override —
+inherits `DocumentDBClusterItem`'s logic, which picks `$(plug)` when `emulatorConfiguration.isEmulator` is true
+(always, for Quick Start), so it gets **the same `$(plug)`** as any other "emulator" connection (including the
+item 10 migrated legacy connections). **State rows:** generic `ThemeIcon`s (`loading~spin`, `circle-outline`,
+`warning`). **Empty-state rows:** `rocket` and `link-external`.
+
+💡 **Suggestion:** Give the managed instance a **distinct, state-independent identity** — e.g. reuse the
+**rocket** (the feature's motif) for the instance row, so users can tell "the Quick-Start-managed one" apart at
+a glance. Low priority, but cheap.
+
+### 29. "Open terminal in the container" — feasible, no blocker 🔍💡
+
+**Priority:** P3 · **Status:** 🟠 Open — TN leaning; do it if cheap, else file an issue (the team may revisit).
+
+> **TN leans towards doing it if cheap** (it helps advanced users) — the standard `createTerminal` +
+> `docker exec -it` (bash → sh fallback), gated on `state_running`. If it turns out non-trivial,
+> **file a new `enhancement`-tagged issue and move on.** _Because it's a nice power-user affordance, not
+> a blocker._
+
+**Observation:** Would a command to open a terminal inside the Docker container make sense? Can we do it?
+
+**Finding:** 🔍 Feasible, no blocker. The repo already uses `vscode.window.createTerminal(...)`; for a plain
+"shell into the container" the standard pattern is
+`createTerminal({ name, shellPath: 'docker', shellArgs: ['exec', '-it', containerId, '/bin/bash'] })` (with a
+`/bin/sh` fallback) — Docker drives the TTY, no custom pty required. The container id is already tracked
+(`metadata.containerId`), and Docker is already a hard dependency.
+
+💡 **Suggestion:** Add an **"Open in Terminal"** context-menu command gated on `state_running`, trying `bash`
+then falling back to `sh`. Details in Open idea O5.
+
+---
+
+## Implemented
+
+### 30. Empty-state tree rows: reword the action, drop "Learn more" ✅
+
+**Priority:** P1\* (wording) · **Status:** ✅ Implemented on this branch.
+
+**Observation:** The rows shown when there's no managed instance yet should be reworded — the action row should
+read like "Click here to…" — and "Learn more" could be dropped from the list.
+
+**Finding:** Both rows were built in `LocalQuickStartItem.getChildren()`
+([LocalQuickStartItem.ts](../../../../src/tree/connections-view/LocalQuickStart/LocalQuickStartItem.ts)) for the
+`NotInstalled` state: an action row (rocket, `treeItem_quickStartAction`) and a separate "Learn more…" row
+(`link-external`, `treeItem_quickStartLearnMore`, opening `https://github.com/microsoft/documentdb`). No
+`view/item/context` entry existed for either, so there was **no existing context-menu** to move "Learn more"
+into.
+
+✅ **Implemented (updated 2026-07-09):**
+
+- The action row is now labeled **`'Click here to start DocumentDB Local'`** (the wording was iterated a couple
+ of times: `'Quick Start — Install & try DocumentDB locally'` → `'Click here to install & try DocumentDB
+locally'` → the current, shorter **`'Click here to start DocumentDB Local'`**). Verified against the current
+ code in `getChildren()`'s `NotInstalled` branch.
+- The `'Learn more…'` row (`treeItem_quickStartLearnMore`) was **removed** from the empty state. It is **not**
+ relocated to a context menu (no menu plumbing exists yet), so the external repo link is no longer reachable
+ from the tree.
+- Files: [LocalQuickStartItem.ts](../../../../src/tree/connections-view/LocalQuickStart/LocalQuickStartItem.ts),
+ [l10n/bundle.l10n.json](../../../../l10n/bundle.l10n.json). Verified via `l10n` / `prettier` / `lint` / full
+ Jest suite / `build`.
+
+💡 **Remaining (Open, low priority):** Decide whether "Learn more" comes back as a context-menu entry on the
+parent `DocumentDB Local - Quick Start` node (a new `view/item/context` gated on `treeItem_localQuickStart`), or
+is dropped for good in favor of the walkthrough/README.
+
+---
+
+## Open ideas — options, pros & cons
+
+Genuinely open design questions with real trade-offs. Recommendations are suggestions to react to, not decisions.
+
+### O1. Surfacing the legacy migration folder (item 10)
+
+| Option | Pros | Cons |
+| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
+| **A. One-time toast + "Reveal" action** | Loud exactly once, at the moment it matters; non-blocking | Transient; a user who dismisses it still has to find the folder |
+| **B. Distinct folder icon/description badge** | Persistent visual marker; no extra flow | Adds a special-case to folder rendering; mild clutter |
+| **C. Pin to a fixed position (first/last)** | Predictable location regardless of name | Breaks the pure-alphabetical model; users may still not notice it |
+| **D. Do nothing (current)** | Zero code | Folder hides in the alphabetical sort; confusing post-upgrade |
+| **E. Prefix the folder name with `_`** | Dead-cheap: `_` sorts before letters, so `_Local Connections (Legacy)` floats to the top of the alphabetical list with **zero** rendering/sort changes | Cosmetic leading `_` in the name; a user can rename it away; not as loud as a toast |
+
+> 💡 **Suggested:** **A**, optionally with **B**. If a code-free quick win is preferred first, **E** (prefix the
+> name with `_`) reliably pins it to the top of the existing `localeCompare(..., { numeric: true })` order with
+> no sort/render changes, and composes fine with A/B.
+
+### O2. Image-pull progress indicator (item 19)
+
+| Option | Pros | Cons |
+| -------------------------------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------ |
+| **A. Spinner + static label (current)** | Zero work | Looks frozen for tens of seconds on a cold pull |
+| **B. Indeterminate `ProgressBar` + "N of M layers" sub-label** | Alive + honest; reuses existing components; modest plumbing | Layer count parsed from free-form CLI text (small regex); no true % |
+| **C. Docker Engine API / `dockerode` structured pull** | Real per-layer byte totals → an actual percentage | Larger change; new dependency/route away from the CLI-wrapper approach |
+| **D. "Dot per completed layer" row** | Visually pleasant for small bounded step counts | Total layer count unknown until pull starts → row grows/shrinks, reads jittery |
+
+> 💡 **Suggested:** **B** near-term (alive UI without the C rework), with **C** as the "if we want a real
+> percentage" follow-up. Avoid **D** — the unknown-until-runtime layer count makes the dot row jitter.
+
+### O3. Cluster commands on the Quick Start row (item 20)
+
+| Option | Pros | Cons |
+| ----------------------------------------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------ |
+| **A. Curated menu only (current)** | No risk of storage commands acting on an in-memory item | Loses genuinely useful storage-independent commands (e.g. Open in Shell) |
+| **B. Add specific storage-independent commands explicitly** | Gains the useful ones; still no storage-command risk | Each command re-declared with a Quick-Start `when`-clause |
+| **C. Split base contextValue into storage vs connection subsets** | Clean, reusable; Quick Start opts into the connection-only subset | Touches the base cluster item + every command's `when`; larger refactor |
+
+> 💡 **Suggested:** **B** now (add "Open in Shell"/"New Query"), keep **C** as the eventual clean-up if more
+> items want the same split.
+
+### O4. External-delete / Missing recovery affordance (items 1 & 2)
+
+| Option | Pros | Cons |
+| ------------------------------------------------------------------ | ---------------------------------------------------------------- | ---------------------------------------------------------------------- |
+| **A. Silent early-return (current)** | — | Looks broken; stale row; error only in the output channel |
+| **B. Detect missing → set Missing badge + info message** | Reuses the existing `Missing` rendering + `liveStateGuard` style | User still has to choose the next step |
+| **C. B + actionable prompt: Delete / Recreate with same settings** | One-click recovery; matches the "click to recreate" Missing row | Slightly more logic; must confirm `getReusableCredentials()` covers it |
+
+> 💡 **Suggested:** **C**. Turns a silent dead-end into self-service recovery; most machinery already exists —
+> the work is mainly routing `start`/`stop`/`restart` into it instead of early-returning.
+
+### O5. Open terminal in container (item 29)
+
+| Option | Pros | Cons |
+| -------------------------------------------------------- | ---------------------------------------------- | ---------------------------------------------------------- |
+| **A. `createTerminal` with `docker exec -it … bash`** | Simplest; Docker drives the TTY; no custom pty | Assumes `bash` in the image |
+| **B. A + `/bin/sh` fallback** | Works even on minimal images | Two-attempt logic (or a probe) |
+| **C. Custom `Pseudoterminal` like the integrated shell** | Full control over I/O | Overkill for "just give me a shell"; more code to maintain |
+
+> 💡 **Suggested:** **B** — the standard, low-maintenance pattern, gated on `state_running`. Reserve **C** only if
+> we later want to parse/relay the shell I/O.
+
+### O6. Persistence & the volume model (items 22 / 23 / 24)
+
+Three related choices about the on-disk data volume. They interact: an "ephemeral" option only makes sense once
+delete reliably wipes the volume, and both are cleaner if the volume is tied to its image.
+
+| Question | Options | Suggested |
+| -------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
+| **Persist vs ephemeral** | (A) Always persist (current). (B) Advanced toggle, default persist. (C) Prompt each run. | **B** — a default-on "Persist data across restarts" toggle; no mount when off. |
+| **Delete → volume** | (A) Delete container only. (B) Delete container **+ volume** on user delete (current explicit path). | **B**, applied to _every_ user-initiated delete (incl. the future credential-missing Delete). |
+| **Volume ↔ image linkage** | (A) Alias-keyed volume + runtime image pinning (current). (B) Structurally key/label volume by image. | **B** — make "one image ↔ one volume" structural; no cross-image sharing (advanced users only). |
+
+> 💡 **Suggested overall:** default stays "persistent, clean-delete, image-pinned" so the zero-decision path is
+> unchanged; add the **ephemeral toggle**, make the **volume↔image link structural**, and never share data
+> volumes across images. Pre-release, pair with item 9 (only ever remove containers/volumes we created).
+
+### O7. Should the container stop when VS Code closes? (item 25)
+
+| Option | Pros | Cons |
+| ------------------------------------- | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
+| **A. Keep running (current)** | Survives reloads/crashes; instant to resume; matches "a local server you manage" | Orphaned container holds a port + RAM after close; surprising for users expecting tool-scoped lifetime; can pile up over time |
+| **B. Stop on VS Code exit** | Tool-scoped lifetime (like a dev server); no orphans; frees the port | Loses "always-on local DB"; restart cost each session; needs a reliable shutdown hook (VS Code exit cleanup isn't guaranteed) |
+| **C. Setting, default keep (+ copy)** | User chooses; safe default; makes the current behavior explicit | A setting adds surface |
+
+> 💡 **Suggested (for evaluation):** Lean **C** — keep the always-on default (safer, data-preserving, and
+> `reconcile()` already relies on it), but add a **setting** ("Stop the local instance when VS Code closes") and
+> make the always-on behavior **explicit** in the UI. Genuinely open — evaluate against how users actually treat
+> the instance (throwaway vs always-on).
+
+---
+
+## Appendix A — current webview flow (reference)
+
+The setup panel is one React component driven by a `Phase` state machine
+(`'loading' | 'review' | 'dockerNotReady' | 'provisioning' | 'success' | 'failed'` in
+[LocalQuickStart.tsx](../../../../src/webviews/documentdb/localQuickStart/LocalQuickStart.tsx)). On open it
+queries `getDockerStatus`, then branches:
+
+```text
+ panel opens
+ |
+ v
+ +-----------------+ getDockerStatus()
+ | loading |------------------------------.
+ | (BARE spinner: | |
+ | "Checking | Docker not ready v
+ | Docker..." | +----------------------------+
+ | no hero/cards) |--------->| dockerNotReady |
+ +-----------------+ | hero "Docker is required" |
+ | | 3 readiness cards |
+ Docker ready | (CLI / daemon / platform) |
+ | | + "How to fix" + [Retry] ---+ (re-query)
+ | +----------------------------+
+ |
+ ready & canResumeReadiness? --- yes --> jump to [failed / timedOut] (resume a prior
+ | timed-out container: Wait longer / Start over)
+ | no
+ v
+ +-----------------+ [Start DocumentDB Local]
+ | review |----------------------------.
+ | hero "Start | |
+ | DocumentDB | v
+ | Local" | +----------------------+
+ | 4 config cards | | provisioning |
+ | (Image / Port / | | hero "Setting up..." |
+ | Data / Security| | elapsed timer |
+ | + Advanced | <-- [Edit | stage checklist: |
+ | (collapsed)) | settings] --| checking > pulling > |
+ | + [Start] | | creating > starting >|
+ +-----------------+ | waiting > done |
+ ^ | [Cancel] [View output]|
+ | +----------+-----------+
+ | [Start over] success | | failed / timeout
+ | v v
+ | +-----------+ +----------------------+
+ +------------------- | success | | failed |
+ | Next steps| | error box |
+ | [Open] [Copy] | [Retry][Edit] OR |
+ | [Close] | | [Wait longer][Start |
+ +-----------+ | over] (on timeout) |
+ +----------------------+
+```
+
+Phase-by-phase:
+
+- **loading** — **only** a full-panel `` (no hero/cards; item 12).
+- **dockerNotReady** — `hero("Docker is required")` + three readiness cards (Docker CLI / daemon / Platform, each
+ with a ✓/! badge) + a "How to fix" card + `Retry`.
+- **review** — `hero("Start DocumentDB Local")` + four config cards (Image / Port / Data / Security) + a summary +
+ a collapsed **Advanced** panel + `Start DocumentDB Local`.
+- **provisioning** — `hero("Setting up DocumentDB Local…")` + elapsed timer + the stage checklist (checking →
+ pulling → creating → starting → waiting → done) + `Cancel` + `View Docker output`.
+- **success** — header still reads "Setting up…" (bug, item 3) + a success box + Next steps + `Open Connection` /
+ `Copy Connection String` / `Close`.
+- **failed** — header still reads "Setting up…" (item 3) + an error box + either `Retry` / `Edit settings`, or (on
+ a readiness timeout) `Wait longer` / `Start over`.
diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json
index b49088d6b..c142fa86f 100644
--- a/l10n/bundle.l10n.json
+++ b/l10n/bundle.l10n.json
@@ -317,6 +317,7 @@
"Clear Query": "Clear Query",
"Click here to open the shell": "Click here to open the shell",
"Click here to retry": "Click here to retry",
+ "Click here to start DocumentDB locally": "Click here to start DocumentDB locally",
"Click here to update credentials": "Click here to update credentials",
"Click to view resource": "Click to view resource",
"Clipboard does not contain a recognizable find() query.": "Clipboard does not contain a recognizable find() query.",
@@ -1155,7 +1156,6 @@
"Query took {0}ms to complete.\n\nThis may impact user experience.\n\nConsider adding indexes or optimizing your query structure.": "Query took {0}ms to complete.\n\nThis may impact user experience.\n\nConsider adding indexes or optimizing your query structure.",
"Query took {0}s to complete.\n\nThis significantly impacts performance and user experience.\n\nImmediate optimization is recommended.": "Query took {0}s to complete.\n\nThis significantly impacts performance and user experience.\n\nImmediate optimization is recommended.",
"Quick Actions": "Quick Actions",
- "Quick Start — Install & try DocumentDB locally": "Quick Start — Install & try DocumentDB locally",
"Reachable": "Reachable",
"Reads a kubeconfig YAML file from disk and links to it by path.": "Reads a kubeconfig YAML file from disk and links to it by path.",
"Reads clipboard content and saves a copy as a kubeconfig source.": "Reads clipboard content and saves a copy as a kubeconfig source.",
diff --git a/src/tree/connections-view/LocalQuickStart/LocalQuickStartItem.ts b/src/tree/connections-view/LocalQuickStart/LocalQuickStartItem.ts
index 1ca4a0dd9..4ebcb0bed 100644
--- a/src/tree/connections-view/LocalQuickStart/LocalQuickStartItem.ts
+++ b/src/tree/connections-view/LocalQuickStart/LocalQuickStartItem.ts
@@ -54,8 +54,8 @@ class QuickStartClusterItem extends DocumentDBClusterItem {
* Root node "DocumentDB Local - Quick Start" (WI-6). Renders unconditionally
* (even with zero saved connections — handled in ConnectionsBranchDataProvider).
*
- * - No managed instance → a rocket empty-state row that opens the Quick Start
- * webview, plus a "Learn more…" link.
+ * - No managed instance → a single rocket empty-state row that opens the Quick
+ * Start webview (UX review #3).
* - A managed instance → the inline cluster (Running, expand to browse) or a
* state row (Stopped/Starting/Stopping/Missing/Error) carrying lifecycle menus.
*/
@@ -167,23 +167,17 @@ export class LocalQuickStartItem implements TreeElement, TreeElementWithContextV
];
}
- // NotInstalled (no metadata) → empty-state rocket + learn more.
+ // NotInstalled (no metadata) → single empty-state action row (UX review #3:
+ // reworded to an explicit "Click here to…" call to action; the separate
+ // "Learn more…" row was dropped as an extra, rarely-used list item).
const children: TreeElement[] = [
createGenericElementWithContext({
id: `${this.id}/start`,
contextValue: 'treeItem_quickStartAction',
- label: l10n.t('Quick Start — Install & try DocumentDB locally'),
+ label: l10n.t('Click here to start DocumentDB Local'),
iconPath: new vscode.ThemeIcon('rocket'),
commandId: 'vscode-documentdb.command.localQuickStart.open',
}),
- createGenericElementWithContext({
- id: `${this.id}/learnMore`,
- contextValue: 'treeItem_quickStartLearnMore',
- label: l10n.t('Learn more…'),
- iconPath: new vscode.ThemeIcon('link-external'),
- commandId: 'vscode.open',
- commandArgs: [vscode.Uri.parse('https://github.com/microsoft/documentdb')],
- }),
];
if (status.state === InstanceState.Error && status.errorMessage) {