Skip to content

fix(cloud-agent-next): stabilize and filter the sidebar Remote rows - #7040

Open
maphew wants to merge 11 commits into
Kilo-Org:mainfrom
maphew:fix/sidebar-remote-section
Open

maphew wants to merge 11 commits into
Kilo-Org:mainfrom
maphew:fix/sidebar-remote-section

Conversation

@maphew

@maphew maphew commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Fix the Cloud Agent sidebar's Remote (live) section: stop the rows reshuffling on every CLI heartbeat, and stop them ignoring the sidebar's platform, project, and search filters.

Two open issues, one area, one change:

  • Cloud Agent session list: [Remote] entries continuously reorder every few seconds #7034 — Remote rows swap positions every few seconds. applyActiveSessionsHeartbeat prepended the heartbeating connection's sessions ahead of every other connection, so two or more live connections flipped the order on alternating heartbeats. The merge now keeps each row where it was and appends only ids the heartbeat introduces. Rows a heartbeat stops reporting are still dropped, and a row another connection takes over is replaced in place instead of being kept alongside its new row.
  • Cloud Agent in browser still shows Remote sessions when only Cloud selected #6813 — Remote rows stayed visible with only Cloud selected. The live rows never saw the platform, project, and search selections (the stored list is filtered server-side, these were not filtered at all). They now go through filterLiveSidebarSessions, which mirrors the stored list's query and the mobile live-session filter:
    • platform families collapse through one shared map (cloud-agent covers cloud-agent-web, extension covers vscode and agent-manager), and other means every origin outside KNOWN_PLATFORMS, as addCreatedOnPlatformConditions defines it
    • the repository comparison uses the same normalizeGitUrl the server query uses
    • text matches the id, title, repository, and branch, which is where the stored list's
      search arms end for a live row: its remaining arms need a pull request or a worktree,
      and a row that is not in the stored list has neither
    • a row that reports no origin is claimed by no platform selection, the same rule mobile applies: a filtered sidebar never shows a session it cannot attribute

Supporting changes:

  • A WebSocket row replaced the cached row wholesale, dropping every field activeSessions.list enriches from cli_sessions_v2 — including the origin the new filter reads. The merge now keeps the cached title, origin, and timestamps, so a filtered sidebar does not drop and re-add rows on each heartbeat.
  • The platform-family mapping moved out of CloudSidebarLayout into live-sidebar-sessions.ts, so the server query and the client filter cannot drift.

Known gap, deliberately left alone: the live list is not scoped by organization, so the Remote section can show another scope's rows. Scoping it client-side is not possible — the connection payload carries no organization id — and scoping the query alone breaks session-deletion.ts, which writes to the unscoped query key. Fixing it needs an org id on the wire from UserConnectionDO.aggregateSessions.

Verification: apps/web typecheck, oxlint, oxfmt, and the cloud-agent-next jest suites (62 suites, 1640 tests) pass. The full web jest suite needs the repository Postgres, which is not available in this environment, so only the pure-unit suites were run. Three adversarial review rounds ran against the diff; the findings that mattered (the platform field being the client OS tag, the other bucket, ownership takeover, and the org-scoping regressions) are fixed or reverted as described above.

Rebased onto main: the Remote ordering #6938 introduced composes with the filter rather
than competing with it, so the rebase filters first and then orders attention-first. The
post-rebase review round also fixed a query that trims to nothing (#, whitespace)
matching every live row, and a per-row rebuild of the platform selection.

Refs #7034, #6813

maphew added a commit to maphew/kilo-cloud that referenced this pull request Sep 30, 2026
…ilter

Adversarial review round on Kilo-Org#7040:

- the live list answered every organization plus personal, so switching to an
  org still showed another scope's Remote rows; scope it like the stored list
- a session another connection takes over was kept alongside its new row,
  rendering it twice; replace it in place
- the wire 'platform' field is the client the CLI runs in, not the origin, so
  it must not claim a platform filter
- 'other' has to mean every origin outside KNOWN_PLATFORMS, as the stored
  query defines it, and the search has to match only title and id
- keep the cached organization attribution, where null means personal

Refs Kilo-Org#7034, Kilo-Org#6813
maphew added a commit to maphew/kilo-cloud that referenced this pull request Sep 30, 2026
Review round three on Kilo-Org#7040: the connection payload carries no organization
id, so scoping the live list client-side leaked another scope's rows into a
personal view and hid a new row in an org view until the next poll, and the
scoped query key silently broke the deletion cache write. The live list stays
unscoped, as before; scoping it needs an org id on the wire.

Also import the live row type from the hook instead of duplicating it, and
make the takeover test fail on the old merge.

Refs Kilo-Org#7034, Kilo-Org#6813
@maphew
maphew marked this pull request as ready for review September 30, 2026 21:01

maphew commented Sep 30, 2026

Copy link
Copy Markdown
Contributor Author

Sweep notes: of the ten open issues authored by @maphew in Kilo-Org/cloud, eight already have a PR (6994→#6997, 6663→#6817, 6595/6167/5901/5900→#6800/#6978, 6248→#6786, 6186→#6784). #7034 and #6813 had none and are the same defect area — the Remote (live) section of the sidebar — so this PR fixes both.

Adjacent gap found while working on this, left for a follow-up: the live list is not organization-scoped, so the Remote section can show another scope's rows. Fixing it needs an organization id on the connection payload from UserConnectionDO.aggregateSessions; scoping the query alone also breaks session-deletion.ts, which writes to the unscoped activeSessions.list query key.


/** Matches what the stored list matches: the session id and its title. */
function matchesLiveSearch(session: LiveSidebarSession, needle: string): boolean {
return session.title.toLowerCase().includes(needle) || session.id.toLowerCase().includes(needle);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: The live search is narrower than the stored-list search this claims to mirror

The server search procedure matches title, session_id, git_url, git_branch, PR title, PR number, and worktree name (apps/web/src/routers/cli-sessions-v2-router.ts:1224-1247), but this client-side matcher only checks title and id. useSidebarSessions swaps to the server search results whenever the query is non-empty (useSidebarSessions.ts:650), so with a repository or branch search a not-yet-ingested Remote row is hidden here even though the stored list shows the identical session. This regresses the earlier matcher in this PR (which searched title, id, gitUrl, gitBranch) and contradicts the code/test claim that the stored list does not search the repository (see live-sidebar-sessions.test.ts:116). The server also strips a leading # before matching (cli-sessions-v2-router.ts:1215); the client does not. Consider matching gitUrl/gitBranch again, or correcting the stated parity.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The six changed web files are clean at HEAD (1fceafce3): both prior warnings remain fixed and the heartbeat merge, live filter, and subscription cleanup introduce no new bug or leak.

The two prior warnings are resolved at HEAD. matchesLiveSearch again matches the session id, title, gitUrl, and gitBranch — the arms the server cliSessionsV2.search resolves for a live-only row — and mirrors the server's trim/toLowerCase/single-leading-# strip (apps/web/src/routers/cli-sessions-v2-router.ts:1335-1342). A query that reduces to an empty needle (#, whitespace) now matches zero live rows for both the live filter and the stored search (live-sidebar-sessions.ts:99-115), instead of showing every Remote row. The platform selection is hoisted to one Set per filter call (live-sidebar-sessions.ts:105-109) rather than rebuilt per row.

The heartbeat/list merge (useActiveSessions.ts:114-150) preserves cached order, replaces a takeover in place without duplicating the row, appends only newly reported ids, and carries cached enrichment (title, origin, timestamps) through both payload kinds. The live query stays unscoped (useActiveSessions()), matching the activeSessions.list.queryKey() written by session-deletion.ts, so the deletion cache write remains consistent. The subscription effect returns the SDK unsubscribe, so no memory leak is introduced. The documented org-scoping gap is pre-existing and out of scope.

Files Reviewed (6 files)
  • apps/web/src/components/cloud-agent-next/ChatSidebar.tsx
  • apps/web/src/components/cloud-agent-next/CloudSidebarLayout.tsx
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.ts
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.test.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.test.ts
Previous Review Summaries (6 snapshots, latest commit 1c6cc96)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 1c6cc96)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The six changed web files are clean at HEAD (1c6cc967f): the two prior warnings are resolved, and the heartbeat merge, filter, and subscription cleanup introduce no new bug or leak.

The prior warnings are fixed at HEAD. matchesLiveSearch now matches the session id, title, gitUrl, and gitBranch — the arms the server cliSessionsV2.search resolves for a live-only row — and mirrors the server's trim/toLowerCase/single-leading-# strip. A query that reduces to an empty needle (#, whitespace) now matches zero live rows for both the live filter and the stored search (apps/web/src/routers/cli-sessions-v2-router.ts:1335-1342), instead of showing every Remote row. The hoisted platform selection (live-sidebar-sessions.ts:104-115) is computed once per filter call rather than per row.

The heartbeat/list merge (useActiveSessions.ts:114-150) preserves cached order, replaces a takeover in place without duplicating the row, appends only newly reported ids, and carries cached enrichment (title, origin, timestamps) through both payload kinds. The live query is again unscoped (useActiveSessions()), matching the activeSessions.list.queryKey() written by session-deletion.ts:76, so the deletion cache write stays consistent. The subscription effect returns the SDK unsubscribe, so no memory leak is introduced. The documented org-scoping gap is pre-existing and out of scope.

Files Reviewed (6 files)
  • apps/web/src/components/cloud-agent-next/ChatSidebar.tsx
  • apps/web/src/components/cloud-agent-next/CloudSidebarLayout.tsx
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.ts
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.test.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.test.ts

Previous review (commit da2c542)

Status: No Issues Found | Recommendation: Merge

No new findings. The six changed web files are blob-identical to the previously reviewed revision (9c064b69), and the two prior warnings remain fixed at HEAD: matchesLiveSearch matches the repository and branch again, and a query that trims/strips to an empty needle (#, whitespace) matches zero live rows, mirroring the stored search in apps/web/src/routers/cli-sessions-v2-router.ts:1214-1249. The heartbeat merge preserves cached order, replaces takeovers in place without duplicates, carries cached enrichment through both payload kinds, and the subscription effect returns the SDK unsubscribe (no memory leak).

Files Reviewed (6 files)
  • apps/web/src/components/cloud-agent-next/ChatSidebar.tsx
  • apps/web/src/components/cloud-agent-next/CloudSidebarLayout.tsx
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.ts
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.test.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.test.ts

Previous review (commit 9c064b6)

Status: No Issues Found | Recommendation: Merge

No unresolved issues in the six changed files. The two prior warnings are fixed at HEAD: matchesLiveSearch matches repository and branch again, and a query that trims/strips to an empty needle now matches zero live rows, mirroring the stored search in apps/web/src/routers/cli-sessions-v2-router.ts:1214-1221. The heartbeat merge preserves cached order, replaces takeovers in place without duplicates, carries cached enrichment through both payload kinds, and the subscription effect returns the SDK unsubscribe (no memory leak).

Files Reviewed (6 files)
  • apps/web/src/components/cloud-agent-next/ChatSidebar.tsx
  • apps/web/src/components/cloud-agent-next/CloudSidebarLayout.tsx
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.ts
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.test.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.test.ts

Previous review (commit 31146bb)

Status: No Issues Found | Recommendation: Merge

No unresolved issues in the six changed files. The prior empty-needle warning is fixed: a query that trims/strips # down to nothing now matches zero live rows, matching the stored search. The repository/branch search gap is closed, the heartbeat merge preserves row order and replaces takeovers in place, cached enrichment survives both payloads, and the subscription effect cleans up correctly (no leak).

Known gap (not introduced here): the live list stays unscoped by organization, so the Remote section can show another scope's rows. This is pre-existing and explicitly documented in the PR.

Files Reviewed (6 files)
  • apps/web/src/components/cloud-agent-next/ChatSidebar.tsx
  • apps/web/src/components/cloud-agent-next/CloudSidebarLayout.tsx
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.ts
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.test.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.test.ts

Previous review (commit f94472f)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts 75 matchesLiveSearch returns true when a #-only query reduces to an empty needle, so the Remote section shows every live row while the stored-list search deliberately matches zero.
Files Reviewed (6 files)
  • apps/web/src/components/cloud-agent-next/ChatSidebar.tsx - 0 issues
  • apps/web/src/components/cloud-agent-next/CloudSidebarLayout.tsx - 0 issues
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.ts - 0 issues
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.test.ts - 0 issues
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts - 1 issue
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.test.ts - 0 issues

Fix these issues in Kilo Cloud

Previous review (commit 0b8c968)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts 73 matchesLiveSearch matches only title/id, but the server search query also matches git_url, git_branch, PR title/number, and worktree name, so live Remote rows vanish on a repository/branch search while stored rows remain.
Files Reviewed (6 files)
  • apps/web/src/components/cloud-agent-next/ChatSidebar.tsx - 0 issues
  • apps/web/src/components/cloud-agent-next/CloudSidebarLayout.tsx - 0 issues
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.ts - 0 issues
  • apps/web/src/components/cloud-agent-next/hooks/useActiveSessions.test.ts - 0 issues
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.ts - 1 issue
  • apps/web/src/components/cloud-agent-next/live-sidebar-sessions.test.ts - 0 issues

Fix these issues in Kilo Cloud

The merge logic (applyActiveSessionsHeartbeat/applyActiveSessionsList/mergeCachedEnrichment) correctly preserves cached order, replaces takeovers in place without duplicates, and carries enriched fields; no memory leak was introduced (the effect returns the SDK unsubscribe). The org-scoping gap for live rows is pre-existing and explicitly documented in the PR, so it is not counted here.


Reviewed by deepseek-v4.1-flash · Input: 85.9K · Output: 15.7K · Cached: 1.4M

Review guidance: REVIEW.md from base branch main

maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 2, 2026
…ilter

Adversarial review round on Kilo-Org#7040:

- the live list answered every organization plus personal, so switching to an
  org still showed another scope's Remote rows; scope it like the stored list
- a session another connection takes over was kept alongside its new row,
  rendering it twice; replace it in place
- the wire 'platform' field is the client the CLI runs in, not the origin, so
  it must not claim a platform filter
- 'other' has to mean every origin outside KNOWN_PLATFORMS, as the stored
  query defines it, and the search has to match only title and id
- keep the cached organization attribution, where null means personal

Refs Kilo-Org#7034, Kilo-Org#6813
@maphew
maphew force-pushed the fix/sidebar-remote-section branch from 0b8c968 to f94472f Compare October 2, 2026 04:49
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 2, 2026
Review round three on Kilo-Org#7040: the connection payload carries no organization
id, so scoping the live list client-side leaked another scope's rows into a
personal view and hid a new row in an org view until the next poll, and the
scoped query key silently broke the deletion cache write. The live list stays
unscoped, as before; scoping it needs an org id on the wire.

Also import the live row type from the hook instead of duplicating it, and
make the takeover test fail on the old merge.

Refs Kilo-Org#7034, Kilo-Org#6813
/** Matches what the stored list matches: id, title, repository, and branch. */
function matchesLiveSearch(session: LiveSidebarSession, needle: string): boolean {
const normalizedNeedle = needle.startsWith('#') ? needle.slice(1) : needle;
if (normalizedNeedle.length === 0) return true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: A #-only search shows every Remote row instead of none

filterLiveSidebarSessions trims the query before calling this matcher, so searchQuery: '#' arrives here as needle === '#'. This line strips the leading # to an empty string and returns true, so every live row passes the search clause. The stored-list search deliberately does the opposite: cli-sessions-v2-router.ts:1220-1221 pushes a literal false predicate when the needle is empty after the same strip, matching zero stored rows. A sidebar search of # therefore shows all Remote rows while the stored list shows none. Return false for the empty needle; the outer !needle check in filterLiveSidebarSessions already covers a genuinely empty query.

Suggested change
if (normalizedNeedle.length === 0) return true;
if (normalizedNeedle.length === 0) return false;

Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@maphew
maphew force-pushed the fix/sidebar-remote-section branch from f94472f to 31146bb Compare October 3, 2026 05:12
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 3, 2026
…ilter

Adversarial review round on Kilo-Org#7040:

- the live list answered every organization plus personal, so switching to an
  org still showed another scope's Remote rows; scope it like the stored list
- a session another connection takes over was kept alongside its new row,
  rendering it twice; replace it in place
- the wire 'platform' field is the client the CLI runs in, not the origin, so
  it must not claim a platform filter
- 'other' has to mean every origin outside KNOWN_PLATFORMS, as the stored
  query defines it, and the search has to match only title and id
- keep the cached organization attribution, where null means personal

Refs Kilo-Org#7034, Kilo-Org#6813
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 3, 2026
Review round three on Kilo-Org#7040: the connection payload carries no organization
id, so scoping the live list client-side leaked another scope's rows into a
personal view and hid a new row in an org view until the next poll, and the
scoped query key silently broke the deletion cache write. The live list stays
unscoped, as before; scoping it needs an org id on the wire.

Also import the live row type from the hook instead of duplicating it, and
make the takeover test fail on the old merge.

Refs Kilo-Org#7034, Kilo-Org#6813

@maphew maphew left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebased onto main (4 conflicts, all in ChatSidebar.tsx) and reviewed the result. Three things worth recording, plus one correction to the description.

1. Conflict resolution: main's Remote ordering is preserved, not dropped

main (#6938, 74cc4d6b8) orders the Remote section attention-first → working → id. The filter change replaced that block wholesale, so taking the incoming side would have silently dropped shipped behaviour. The two fixes compose rather than compete — heartbeats no longer move rows, and the order is then decided once in the component — so the rebase keeps both: filter first, then order (43821093b).

2. Fixed: a query that trims away to nothing showed every live row

cli-sessions-v2-router.ts strips one leading #, then resolves an empty needle to zero rows, because position('' in …) would otherwise match every stored row. filterLiveSidebarSessions matched every live row for the same input, so typing a bare # — or whitespace — emptied the stored list while the Remote section stayed fully visible: the exact class of bug this PR exists to fix. Normalization (trim, lower-case, one leading #) now happens once per call, and an empty needle matches nothing, mirroring the stored search (31146bb17).

3. Fixed: the platform selection was rebuilt per row

matchesLivePlatformFilter called platformFilterValues and allocated a Set for every row, on every filter pass — and the pass re-runs on every heartbeat. Hoisted to one Set per call, with the "no selection means no filter" short-circuit preserved (31146bb17).

Correction to the description's known gap

The org-scoping gap is real, but narrower than the body states. activeSessions.list does carry a per-row organizationId — mapEnrichedHeartbeatSession sets it, null for a never-ingested row. What is missing is that the WebSocket heartbeat row carries none and ENRICHED_FIELDS does not preserve the cached value, so the id is dropped again on the next heartbeat. Client-side scoping is therefore already possible for rows that have been ingested; the wire change from UserConnectionDO.aggregateSessions is only needed for rows that have not.

Verification

  • oxlint and oxfmt clean; both changed suites pass (22 tests).
  • apps/web typecheck cannot complete in this environment: @kilocode/trpc's build fails on a missing @simplewebauthn/server install. The identical failure reproduces on an unmodified main, with the same error count and the same per-file distribution, so nothing here is attributable to this branch.
  • The full web jest suite needs the repository Postgres, unavailable here, so only the pure-unit suites ran. The cloud-agent-next suites that fail without the DB-backed setup fail identically on main (9 suites / 6 tests, before and after).

@maphew
maphew force-pushed the fix/sidebar-remote-section branch from 31146bb to 9c064b6 Compare October 3, 2026 16:40
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 3, 2026
…ilter

Adversarial review round on Kilo-Org#7040:

- the live list answered every organization plus personal, so switching to an
  org still showed another scope's Remote rows; scope it like the stored list
- a session another connection takes over was kept alongside its new row,
  rendering it twice; replace it in place
- the wire 'platform' field is the client the CLI runs in, not the origin, so
  it must not claim a platform filter
- 'other' has to mean every origin outside KNOWN_PLATFORMS, as the stored
  query defines it, and the search has to match only title and id
- keep the cached organization attribution, where null means personal

Refs Kilo-Org#7034, Kilo-Org#6813
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 3, 2026
Review round three on Kilo-Org#7040: the connection payload carries no organization
id, so scoping the live list client-side leaked another scope's rows into a
personal view and hid a new row in an org view until the next poll, and the
scoped query key silently broke the deletion cache write. The live list stays
unscoped, as before; scoping it needs an org id on the wire.

Also import the live row type from the hook instead of duplicating it, and
make the takeover test fail on the old merge.

Refs Kilo-Org#7034, Kilo-Org#6813
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 4, 2026
…ilter

Adversarial review round on Kilo-Org#7040:

- the live list answered every organization plus personal, so switching to an
  org still showed another scope's Remote rows; scope it like the stored list
- a session another connection takes over was kept alongside its new row,
  rendering it twice; replace it in place
- the wire 'platform' field is the client the CLI runs in, not the origin, so
  it must not claim a platform filter
- 'other' has to mean every origin outside KNOWN_PLATFORMS, as the stored
  query defines it, and the search has to match only title and id
- keep the cached organization attribution, where null means personal

Refs Kilo-Org#7034, Kilo-Org#6813
@maphew
maphew force-pushed the fix/sidebar-remote-section branch from 9c064b6 to da2c542 Compare October 4, 2026 03:00
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 4, 2026
Review round three on Kilo-Org#7040: the connection payload carries no organization
id, so scoping the live list client-side leaked another scope's rows into a
personal view and hid a new row in an org view until the next poll, and the
scoped query key silently broke the deletion cache write. The live list stays
unscoped, as before; scoping it needs an org id on the wire.

Also import the live row type from the hook instead of duplicating it, and
make the takeover test fail on the old merge.

Refs Kilo-Org#7034, Kilo-Org#6813
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 13, 2026
…ilter

Adversarial review round on Kilo-Org#7040:

- the live list answered every organization plus personal, so switching to an
  org still showed another scope's Remote rows; scope it like the stored list
- a session another connection takes over was kept alongside its new row,
  rendering it twice; replace it in place
- the wire 'platform' field is the client the CLI runs in, not the origin, so
  it must not claim a platform filter
- 'other' has to mean every origin outside KNOWN_PLATFORMS, as the stored
  query defines it, and the search has to match only title and id
- keep the cached organization attribution, where null means personal

Refs Kilo-Org#7034, Kilo-Org#6813
maphew added a commit to maphew/kilo-cloud that referenced this pull request Oct 13, 2026
Review round three on Kilo-Org#7040: the connection payload carries no organization
id, so scoping the live list client-side leaked another scope's rows into a
personal view and hid a new row in an org view until the next poll, and the
scoped query key silently broke the deletion cache write. The live list stays
unscoped, as before; scoping it needs an org id on the wire.

Also import the live row type from the hook instead of duplicating it, and
make the takeover test fail on the old merge.

Refs Kilo-Org#7034, Kilo-Org#6813
@maphew
maphew force-pushed the fix/sidebar-remote-section branch from 8627af8 to 1c6cc96 Compare October 13, 2026 20:29
maphew and others added 6 commits October 13, 2026 14:56
Live sessions bypassed the sidebar's platform, project, and search filters,
so the Remote section kept showing CLI rows while only Cloud was selected,
and every CLI heartbeat prepended its connection's rows, so two or more live
connections reshuffled the section every few seconds.

Filter the live rows with the same selections the stored list gets, keep the
cached order when a heartbeat merges in, and preserve the enriched fields a
wire row lacks.

Refs Kilo-Org#7034, Kilo-Org#6813
…ilter

Adversarial review round on Kilo-Org#7040:

- the live list answered every organization plus personal, so switching to an
  org still showed another scope's Remote rows; scope it like the stored list
- a session another connection takes over was kept alongside its new row,
  rendering it twice; replace it in place
- the wire 'platform' field is the client the CLI runs in, not the origin, so
  it must not claim a platform filter
- 'other' has to mean every origin outside KNOWN_PLATFORMS, as the stored
  query defines it, and the search has to match only title and id
- keep the cached organization attribution, where null means personal

Refs Kilo-Org#7034, Kilo-Org#6813
Review round three on Kilo-Org#7040: the connection payload carries no organization
id, so scoping the live list client-side leaked another scope's rows into a
personal view and hid a new row in an org view until the next poll, and the
scoped query key silently broke the deletion cache write. The live list stays
unscoped, as before; scoping it needs an org id on the wire.

Also import the live row type from the hook instead of duplicating it, and
make the takeover test fail on the old merge.

Refs Kilo-Org#7034, Kilo-Org#6813
The heartbeat merge now leaves every row where it was, so the Remote
section still needs the ordering main ships: attention first, then
working, then id. Apply it after the live filter instead of instead of
it, so a filtered sidebar keeps the order an unfiltered one has.
A query that trims away to nothing — a bare `#`, or whitespace — leaves
the stored list empty, because the search resolves an empty needle to
zero rows. The live filter returned every row for it instead, so the
Remote section ignored the query the rest of the sidebar had applied.

Hoist the platform selection out of the row loop at the same time: it was
rebuilt per row, on every heartbeat.
@maphew
maphew force-pushed the fix/sidebar-remote-section branch from 1c6cc96 to 1fceafc Compare October 13, 2026 21:56

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant