Finish host copy audit

Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
Jinwoo-H
2026-06-12 22:54:03 -07:00
co-authored by Orca
parent ed6cf82183
commit dcad5f497d
6 changed files with 8 additions and 13 deletions
@@ -20,7 +20,7 @@ The target model is:
- [x] Add a shared TaskSourceContext type that captures provider, host/source target, logical project id, optional projectHostSetupId, and provider-specific identity such as owner/repo, GitLab project id, Linear workspace/team, or Jira site/project.
- [x] Add a shared run-target type or selector for RunHostContext / WorkspaceRunContext so workspace creation, agent launch, automations, and remote execution use the same vocabulary.
- [~] Audit user-facing copy so the product says **Host** for Local Mac, SSH hosts, remote servers, and future cloud VMs, while preserving technical labels only where useful.
- [x] Audit user-facing copy so the product says **Host** for Local Mac, SSH hosts, remote servers, and future cloud VMs, while preserving technical labels only where useful.
- [x] Document the invariant that task source context and run host are separate choices.
- [x] Add compatibility adapters for existing repo-id/path-based callers so old data can be read while new code moves to explicit contexts.
- [x] Add schema migration notes for old automations, cached task selections, pending worktree requests, and any persisted task drawer state.
@@ -257,3 +257,4 @@ Done means: reviewers and future agents can understand the vision, implementatio
- [x] 2026-06-12: Marked PR/MR base resolution complete based on `useComposerState-host-context-boundaries.test.ts`, which asserts GitHub PR and GitLab MR base lookup uses the selected run repo instead of the provider item's source repo while preserving source item metadata separately.
- [x] 2026-06-12: Extracted and tested external automation source availability copy so local missing tooling, disconnected SSH sources, connecting SSH sources, and connected SSH hosts with missing remote tooling get distinct states; verified with focused automation availability tests, targeted oxlint, and full `pnpm run typecheck`.
- [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`.
+1 -1
View File
@@ -879,7 +879,7 @@ describe('SSH IPC handlers', () => {
await expect(
handlers.get('ssh:terminateSessions')!(null, { targetId: 'ssh-1' })
).rejects.toThrow('Failed to terminate remote SSH sessions')
).rejects.toThrow('Failed to terminate SSH host sessions')
expect(mockStore.markSshRemotePtyLease).not.toHaveBeenCalledWith('ssh-1', 'pty-1', 'terminated')
expect(mockConnectionManager.disconnect).not.toHaveBeenCalledWith('ssh-1')
})
+1 -1
View File
@@ -850,7 +850,7 @@ export function registerSshHandlers(
if (shutdownFailures.length > 0) {
// Why: a failed relay shutdown can leave the remote process alive in the
// grace window. Keep the lease/session intact so the user can retry.
throw new Error(`Failed to terminate remote SSH sessions: ${shutdownFailures.join('; ')}`)
throw new Error(`Failed to terminate SSH host sessions: ${shutdownFailures.join('; ')}`)
}
if (session) {
await portForwardManager!.removeAllForwards(args.targetId)
@@ -247,7 +247,7 @@ export default function AiVaultPanel(): React.JSX.Element {
<div className="border-b border-sidebar-border px-3 py-2 text-[11px] leading-4 text-muted-foreground">
{translate(
'auto.components.right.sidebar.AiVaultPanel.remoteBrowseLocalHistory',
'Remote workspaces can browse local history. Resume actions run from local workspaces.'
'SSH-host workspaces can browse local history. Resume actions run from Local Mac workspaces.'
)}
</div>
) : null}
@@ -5,10 +5,7 @@ import { createLocalizedCatalog } from '@/i18n/localized-catalog'
export const getSshPaneSearchEntries = createLocalizedCatalog(() => [
{
title: translate('auto.components.settings.ssh.search.380a788da7', 'SSH Connections'),
description: translate(
'auto.components.settings.ssh.search.74c6d90d78',
'Manage remote SSH targets.'
),
description: translate('auto.components.settings.ssh.search.74c6d90d78', 'Manage SSH hosts.'),
keywords: [
...translateSearchKeyword('auto.components.settings.ssh.search.7efd17e816', 'ssh'),
...translateSearchKeyword('auto.components.settings.ssh.search.d4bcd497c7', 'remote'),
@@ -19,10 +16,7 @@ export const getSshPaneSearchEntries = createLocalizedCatalog(() => [
},
{
title: translate('auto.components.settings.ssh.search.f5a691bb6c', 'Add SSH Target'),
description: translate(
'auto.components.settings.ssh.search.62826efbe9',
'Add a new remote SSH target.'
),
description: translate('auto.components.settings.ssh.search.62826efbe9', 'Add a new SSH host.'),
keywords: [
...translateSearchKeyword('auto.components.settings.ssh.search.7efd17e816', 'ssh'),
...translateSearchKeyword('auto.components.settings.ssh.search.f7b6383aec', 'add'),
+1 -1
View File
@@ -1019,7 +1019,7 @@ function createReposApi(): NonNullable<Partial<PreloadApi>['repos']> {
createRemote: async () => {
// Why: SSH relay project creation is owned by the desktop main process;
// paired web clients cannot create folders through local SSH IPC.
throw new Error('SSH project creation is unavailable in paired web clients.')
throw new Error('Creating projects on SSH hosts is unavailable in paired web clients.')
},
cloneAbort: () => Promise.resolve(),
addRemote: async ({ remotePath, displayName, kind }) => {