From 8d8225388db5ab58c1f3b2be9e4e01ebe1fc8fa1 Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Fri, 12 Jun 2026 23:09:22 -0700 Subject: [PATCH] Show task source account labels Co-authored-by: Orca --- .../host-context-implementation-checklist.md | 3 +- .../task-source-context-summary.test.ts | 35 +++++++++++++++++++ .../components/task-source-context-summary.ts | 11 ++++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/notes/host-context-implementation-checklist.md b/notes/host-context-implementation-checklist.md index dee522f517b..6b696a5f824 100644 --- a/notes/host-context-implementation-checklist.md +++ b/notes/host-context-implementation-checklist.md @@ -46,7 +46,7 @@ Done means: if Machine A and Machine B have different provider accounts, every l - [x] Add an explicit source-context picker or display for Tasks that can represent host, provider account, and project/source. - [x] Decide and implement the default Tasks view when a logical project exists on multiple hosts. - [x] Support switching the task source without changing the current run host. -- [~] Show enough account/host metadata to make mismatched GitHub/GitLab/Linear/Jira accounts understandable. +- [x] Show enough account/host metadata to make mismatched GitHub/GitLab/Linear/Jira accounts understandable. - [x] Persist task source context in task drawer URLs/state so refresh, deep links, and reopen preserve the same source. - [x] Ensure task drawer actions reuse the drawer item source context, not a global provider default. - [x] Add disabled/auth-needed/disconnected states for source hosts. @@ -259,3 +259,4 @@ Done means: reviewers and future agents can understand the vision, implementatio - [x] 2026-06-12: Marked repo-id/path compatibility adapters complete after hardening the renderer project-host selector to merge repo-derived compatibility rows when hydrated project/setup arrays are empty or partial, alongside existing shared projection, persistence backfill/sync, automation context migration, and pending worktree context coverage. Verified with selector/projection tests, persistence tests, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`. - [x] 2026-06-12: Marked the Host copy audit complete after replacing remaining visible stale SSH/project wording in paired-web project creation errors, Settings SSH search entries, AI Vault SSH-host workspace copy, and SSH shutdown errors. Verified with a stale-copy scan showing only comments/tests/technical internals, focused SSH IPC tests, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`. - [x] 2026-06-12: Completed Settings ownership/account rows by adding a shared provider Host scope control with a Change Host action that opens Settings > Active Server from GitHub/GitLab/Linear/Jira account surfaces and GitHub/GitLab API budget panels. Existing ownership diagnostics still distinguish desktop-client versus remote-server credentials, and rate-limit panels show the budget Host scope. Verified with settings ownership, RuntimeEnvironmentsPane, provider account, source-control card, task-tracker card, Jira card, and rate-limit panel tests, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`. +- [x] 2026-06-12: Completed Tasks account/host metadata by showing repo-backed account labels in source summaries when GitHub/GitLab accounts differ by Host, while preserving host labels, provider identities, Linear workspace names, Jira site names, and unavailable-host status in labels/titles. Verified with source-summary and repo picker tests, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`. diff --git a/src/renderer/src/components/task-source-context-summary.test.ts b/src/renderer/src/components/task-source-context-summary.test.ts index cac6f0d0917..a54be26949e 100644 --- a/src/renderer/src/components/task-source-context-summary.test.ts +++ b/src/renderer/src/components/task-source-context-summary.test.ts @@ -27,6 +27,41 @@ describe('task source context summary', () => { expect(summary.title).toBe('GitHub · Host: devbox · Source: stablyai/orca') }) + it('shows repo-backed provider account labels when accounts can differ by host', () => { + const summary = getTaskSourceContextSummary({ + provider: 'github', + providerLabel: 'GitHub', + selectedRepoCount: 2, + repoContexts: [ + { + kind: 'task-source', + provider: 'github', + projectId: 'github:stablyai/orca', + hostId: 'local', + projectHostSetupId: 'setup-local', + repoId: 'repo-local', + providerIdentity: { provider: 'github', owner: 'stablyai', repo: 'orca' }, + accountLabel: 'personal-gh' + }, + { + kind: 'task-source', + provider: 'github', + projectId: 'github:stablyai/orca', + hostId: 'ssh:builder', + projectHostSetupId: 'setup-builder', + repoId: 'repo-builder', + providerIdentity: { provider: 'github', owner: 'stablyai', repo: 'orca' }, + accountLabel: 'work-gh' + } + ] + }) + + expect(summary.label).toBe('GitHub · Local Mac, builder · personal-gh, work-gh') + expect(summary.title).toBe( + 'GitHub · Host: Local Mac, builder · Account: personal-gh, work-gh · Source: stablyai/orca · 2 selected projects' + ) + }) + it('shows disconnected source-host availability for a single SSH repo source', () => { const summary = getTaskSourceContextSummary({ provider: 'github', diff --git a/src/renderer/src/components/task-source-context-summary.ts b/src/renderer/src/components/task-source-context-summary.ts index bc6fbbef6f7..5543d19645d 100644 --- a/src/renderer/src/components/task-source-context-summary.ts +++ b/src/renderer/src/components/task-source-context-summary.ts @@ -87,12 +87,16 @@ function getRepoBackedTaskSourceSummary(args: { const identityLabels = uniqueLabels( contexts.map((context) => getProviderIdentityLabel(context.providerIdentity)) ) + const accountLabels = uniqueLabels(contexts.map((context) => context.accountLabel)) const repoCount = args.selectedRepoCount ?? contexts.length const hostLabel = hostLabels.length === 0 ? 'No host' : formatShortList(hostLabels) + const accountLabel = accountLabels.length > 0 ? `Account: ${formatLongList(accountLabels)}` : null const targetLabel = - repoCount > 1 - ? `${repoCount} projects` - : (identityLabels[0] ?? contexts[0]?.accountLabel ?? 'Selected project') + accountLabels.length > 1 + ? formatShortList(accountLabels) + : repoCount > 1 + ? `${repoCount} projects` + : (identityLabels[0] ?? contexts[0]?.accountLabel ?? 'Selected project') const titleParts = [ args.providerLabel, hostLabels.length > 0 ? `Host: ${formatLongList(hostLabels)}` : null, @@ -101,6 +105,7 @@ function getRepoBackedTaskSourceSummary(args: { unavailableHosts.map((host) => `${host.hostLabel} ${host.statusLabel}`) )}` : null, + accountLabel, identityLabels.length > 0 ? `Source: ${formatLongList(identityLabels)}` : null, repoCount > 1 ? `${repoCount} selected projects` : null ].filter((part): part is string => Boolean(part))