diff --git a/src/app/dashboard/[teamSlug]/terminal/page.tsx b/src/app/dashboard/[teamSlug]/terminal/page.tsx index 9aa4103ae..d2e70a3c9 100644 --- a/src/app/dashboard/[teamSlug]/terminal/page.tsx +++ b/src/app/dashboard/[teamSlug]/terminal/page.tsx @@ -13,7 +13,10 @@ import type { components as InfraComponents } from '@/core/shared/contracts/infr import { createSandboxManagementAuth } from '@/core/shared/sandbox-management-auth.server' import { SandboxIdSchema } from '@/core/shared/schemas/api' import DashboardTerminal from '@/features/dashboard/terminal/dashboard-terminal' -import { normalizeTerminalTemplate } from '@/features/dashboard/terminal/template' +import { + isPublicTemplateReference, + normalizeTerminalTemplate, +} from '@/features/dashboard/terminal/template' import { Button } from '@/ui/primitives/button' export const metadata: Metadata = { @@ -192,6 +195,10 @@ async function isTerminalTemplateAvailable({ return { ok: true as const, available: true } } + if (isPublicTemplateReference(template)) { + return { ok: true as const, available: true } + } + const defaultTemplatesRepository = createDefaultTemplatesRepository({ accessToken, }) diff --git a/src/features/dashboard/terminal/template.ts b/src/features/dashboard/terminal/template.ts index d320bc870..6ae414988 100644 --- a/src/features/dashboard/terminal/template.ts +++ b/src/features/dashboard/terminal/template.ts @@ -15,6 +15,12 @@ export function normalizeTerminalTemplate(template?: string) { return value } +export function isPublicTemplateReference(template: string) { + const [owner, name, ...rest] = template.split('/') + + return Boolean(owner && name && rest.length === 0) +} + export function resolveTerminalTemplateOverride( template: string | undefined, fallback: string diff --git a/tests/unit/dashboard-terminal.test.ts b/tests/unit/dashboard-terminal.test.ts index e8ab4b345..f383f4c95 100644 --- a/tests/unit/dashboard-terminal.test.ts +++ b/tests/unit/dashboard-terminal.test.ts @@ -12,6 +12,7 @@ import { writeStoredTerminalSession, } from '@/features/dashboard/terminal/storage' import { + isPublicTemplateReference, normalizeTerminalTemplate, resolveTerminalTemplateOverride, } from '@/features/dashboard/terminal/template' @@ -85,6 +86,21 @@ describe('dashboard terminal helpers', () => { }) }) + describe('isPublicTemplateReference', () => { + it('detects owner-qualified public template references', () => { + expect(isPublicTemplateReference('team-slug/python:default')).toBe(true) + expect( + isPublicTemplateReference('aiengineer-d56d/aiengineer-guide') + ).toBe(true) + }) + + it('does not treat bare or multi-path template names as public references', () => { + expect(isPublicTemplateReference('base')).toBe(false) + expect(isPublicTemplateReference('python_3.12-dev')).toBe(false) + expect(isPublicTemplateReference('owner/nested/template')).toBe(false) + }) + }) + describe('resolveTerminalTemplateOverride', () => { it('preserves the current template when no override is provided', () => { expect(resolveTerminalTemplateOverride(undefined, 'python')).toBe(