Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
131f1e9
feat(connections): let a connection be tried before it has to be save…
deveshk0 Sep 8, 2026
8bc5168
fix(connections): close the three ways the save offer could mislead (…
deveshk0 Sep 8, 2026
64b48e4
fix(connections): give back a connection nobody is waiting for (#369 …
deveshk0 Sep 8, 2026
4030f18
test(indexes): wait for the schema fields, not just for the call (#36…
deveshk0 Sep 8, 2026
9f1edcc
fix(connections): stop an unsaved connection leaking into places it c…
deveshk0 Sep 8, 2026
da23591
fix(connections): keep an unsaved tab out of the mirrored split, and …
deveshk0 Sep 8, 2026
204169b
Revert "split_pane" half of da23591 — it needs a product decision, no…
deveshk0 Sep 8, 2026
41887aa
fix(connections): let the offer describe the connection that was made…
deveshk0 Sep 8, 2026
9f31a2f
fix(sidebar): refuse a shortcut that could not survive a restart (#36…
deveshk0 Sep 8, 2026
7c49485
fix(connections): show the URI that was connected, and decide shortcu…
deveshk0 Sep 8, 2026
c866ab2
fix(connections): stop an unsaved session answering to a saved profil…
deveshk0 Sep 8, 2026
c5bc1fb
fix(connections): keep an unsaved session out of a saved profile's qu…
deveshk0 Sep 8, 2026
a377e30
fix(connections): take Math.random out of an id that now keys storage…
deveshk0 Sep 8, 2026
b6d91fd
fix(connections): finish isolating an unsaved session's query, chat a…
deveshk0 Sep 8, 2026
6b48634
fix(connections): let only the current attempt release the Connect bu…
deveshk0 Sep 8, 2026
7385899
fix(connections): isolate history writes and the shell assistant, and…
deveshk0 Sep 8, 2026
1a08ba1
fix(connections): read ephemeral from the profile, and release a sess…
deveshk0 Sep 8, 2026
6d29038
fix(connections): make the post-await ownership checks actually able …
deveshk0 Sep 8, 2026
aa66bd5
fix(connections): retarget a trial connection's chats under its own i…
deveshk0 Sep 8, 2026
c942548
fix(connections): stop the name suggestion renaming a profile called …
deveshk0 Sep 9, 2026
29c33ff
fix(connections): advance the attempt generation when the editor clos…
deveshk0 Sep 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ import {
} from './workspace/workspaceStore';
import {
toPersistedTab,
isEphemeralProfileId,
toDisconnectedSnapshot,
rebindConnection,
toProfileSpaceId,
Expand Down Expand Up @@ -1127,7 +1128,13 @@ function Workspace() {

const handleQuickConnect = async (profile: ConnectionProfile): Promise<string | null> => {
const existing = activeConnections.find(
(c) => c.profileId === profile.id || c.name === profile.name,
(c) =>
c.profileId === profile.id ||
// Matching on name is a convenience for a profile reconnecting under a
// new session id. An unsaved connection must not answer to it: its name
// is editable and can be set to this profile's, and quick-connect would
// then hand back a session pointing at a different server (#369 review).
(c.name === profile.name && !isEphemeralProfileId(c.profileId)),
);
if (existing) return existing.id;
try {
Expand Down Expand Up @@ -1434,6 +1441,25 @@ function Workspace() {
const connectionNameFor = (connectionId: string): string =>
activeConnections.find((c) => c.id === connectionId)?.name || connectionId;

/**
* The key a connection's saved queries, default query and history live under.
*
* Normally the display name, which is what these stores have always been
* keyed on. An unsaved connection gets its own ephemeral id instead: its name
* is editable and can be a saved profile's, and sharing a namespace would
* mean opening a collection ran the saved profile's default query against the
* trial server, while the trial's own history wrote back into the saved
* profile's (#369 review).
*
* Its entries are orphaned when the session ends, which is the right outcome
* for a connection the user declined to keep.
*/
const connectionQueryKeyFor = (connectionId: string): string => {
const conn = activeConnections.find((c) => c.id === connectionId);
if (!conn) return connectionId;
return isEphemeralProfileId(conn.profileId) ? conn.profileId! : conn.name;
Comment thread
deveshk0 marked this conversation as resolved.
Comment thread
deveshk0 marked this conversation as resolved.
};

// Never sit on a blank canvas — if every tab is closed, bring back Quick
// Start. Main-window-only (Phase 3 Task 4): a secondary window has no
// quickstart concept — the spec says an emptied secondary window closes
Expand Down Expand Up @@ -1576,7 +1602,7 @@ function Workspace() {
let def: QueryDef | null = (savedQuery as QueryDef | undefined) ?? null;
if (!def) {
try {
const cq = await loadCollectionQueries(connectionNameFor(connectionId), dbName, collName);
const cq = await loadCollectionQueries(connectionQueryKeyFor(connectionId), dbName, collName);
def = (cq.default as QueryDef | null) ?? null;
} catch {
def = null;
Expand Down Expand Up @@ -4520,6 +4546,7 @@ function Workspace() {
key={tab.id}
connectionId={tab.connectionId}
connectionName={connectionName}
queryStoreKey={connectionQueryKeyFor(tab.connectionId)}
Comment thread
deveshk0 marked this conversation as resolved.
connectionUser={connectionUser}
databaseName={tab.db}
collectionName={tab.collection}
Expand Down
Loading