diff --git a/notes/host-context-implementation-checklist.md b/notes/host-context-implementation-checklist.md index 6b696a5f824..362726d205c 100644 --- a/notes/host-context-implementation-checklist.md +++ b/notes/host-context-implementation-checklist.md @@ -260,3 +260,4 @@ Done means: reviewers and future agents can understand the vision, implementatio - [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`. +- [x] 2026-06-12: Continued the automation project-id migration by changing CLI automation show output to foreground explicit `runContext` fields (`runProjectId`, `runHostId`, `projectHostSetupId`, `runRepoId`, `runPath`) and label the old repo id as `legacyRepoId`. The checklist row remains partial because the shared `Automation.projectId` compatibility field still exists. Verified with CLI format/index tests, targeted oxlint, full `pnpm run typecheck`, and `git diff --check`. diff --git a/src/cli/format.test.ts b/src/cli/format.test.ts index 3d6c9df9aea..cd614976015 100644 --- a/src/cli/format.test.ts +++ b/src/cli/format.test.ts @@ -6,6 +6,7 @@ import { quoteCliCommandArgument } from './shell-command-quote' import { RuntimeRpcFailureError } from './runtime-client' import { formatCliError, + formatAutomationShow, formatComputerAction, formatGetAppState, formatTerminalRead, @@ -13,6 +14,7 @@ import { printResult } from './format' import type { ComputerActionResult, RuntimeWorktreeRecord } from '../shared/runtime-types' +import type { Automation } from '../shared/automations-types' let testScreenshotDir: string | null = null @@ -140,6 +142,59 @@ describe('formatWorktreeList', () => { }) }) +describe('formatAutomationShow', () => { + function automation(overrides: Partial = {}): Automation { + return { + id: 'auto-1', + name: 'Nightly', + prompt: 'Run checks', + precheck: null, + agentId: 'codex', + projectId: 'repo-legacy', + executionTargetType: 'local', + executionTargetId: 'local', + schedulerOwner: 'local_host_service', + workspaceMode: 'new_per_run', + workspaceId: null, + baseBranch: null, + reuseSession: false, + timezone: 'UTC', + rrule: 'FREQ=DAILY;BYHOUR=9;BYMINUTE=0', + dtstart: 0, + enabled: true, + nextRunAt: 0, + missedRunPolicy: 'run_once_within_grace', + missedRunGraceMinutes: 720, + createdAt: 0, + updatedAt: 0, + ...overrides + } + } + + it('shows explicit run context before the legacy repo id', () => { + const output = formatAutomationShow({ + automation: automation({ + runContext: { + kind: 'workspace-run', + projectId: 'github:stablyai/orca', + hostId: 'runtime:gpu', + projectHostSetupId: 'setup-gpu', + repoId: 'repo-gpu', + path: '/srv/orca' + } + }) + }) + + expect(output).toContain('runProjectId: github:stablyai/orca') + expect(output).toContain('runHostId: runtime:gpu') + expect(output).toContain('projectHostSetupId: setup-gpu') + expect(output).toContain('runRepoId: repo-gpu') + expect(output).toContain('runPath: /srv/orca') + expect(output).toContain('legacyRepoId: repo-legacy') + expect(output).not.toContain('projectId: repo-legacy') + }) +}) + describe('formatTerminalRead', () => { it('warns limited cursor reads to continue with the next cursor', () => { const output = formatTerminalRead({ diff --git a/src/cli/workspace-format.ts b/src/cli/workspace-format.ts index 27d02d82891..95ad2cf4607 100644 --- a/src/cli/workspace-format.ts +++ b/src/cli/workspace-format.ts @@ -178,6 +178,17 @@ export function formatAutomationList(result: { automations: Automation[] }): str export function formatAutomationShow(result: { automation: Automation }): string { const automation = result.automation + const runContext = automation.runContext ?? null + const projectLines = runContext + ? [ + `runProjectId: ${runContext.projectId}`, + `runHostId: ${runContext.hostId}`, + `projectHostSetupId: ${runContext.projectHostSetupId}`, + `runRepoId: ${runContext.repoId}`, + `runPath: ${runContext.path}`, + `legacyRepoId: ${automation.projectId}` + ] + : [`legacyRepoId: ${automation.projectId}`] return [ `id: ${automation.id}`, `name: ${automation.name}`, @@ -193,7 +204,7 @@ export function formatAutomationShow(result: { automation: Automation }): string : 'none' }`, `nextRunAt: ${new Date(automation.nextRunAt).toISOString()}`, - `projectId: ${automation.projectId}`, + ...projectLines, `workspaceMode: ${automation.workspaceMode}`, `workspaceId: ${automation.workspaceId ?? 'null'}`, `baseBranch: ${automation.baseBranch ?? 'null'}`,