diff --git a/src/web/schemas.ts b/src/web/schemas.ts index 10ef069a..b24fce25 100644 --- a/src/web/schemas.ts +++ b/src/web/schemas.ts @@ -867,6 +867,8 @@ const RemoteCommandOverridesSchema = z pi: z.string().min(1).max(300).optional(), grok: z.string().min(1).max(300).optional(), deepseek: z.string().min(1).max(300).optional(), + omp: z.string().min(1).max(300).optional(), + copilot: z.string().min(1).max(300).optional(), }) .strict() .optional(); diff --git a/test/remote-hosts.test.ts b/test/remote-hosts.test.ts index 8606d5d1..5e091b8e 100644 --- a/test/remote-hosts.test.ts +++ b/test/remote-hosts.test.ts @@ -2,6 +2,7 @@ import { mkdtempSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { afterEach, describe, expect, it } from 'vitest'; +import { listClis } from '../src/config/cli-registry/registry.js'; import { defaultRemoteCommandForMode, readRemoteCases, @@ -13,7 +14,7 @@ import { writeRemoteCases, writeRemoteHosts, } from '../src/remote-hosts.js'; -import { RemoteHostSchema } from '../src/web/schemas.js'; +import { DockerHostSchema, RemoteHostSchema } from '../src/web/schemas.js'; describe('remote-hosts domain', () => { let dir: string | null = null; @@ -126,6 +127,27 @@ describe('remote-hosts domain', () => { }); }); + describe('per-mode command overrides', () => { + const modes = ['shell', ...listClis().map((cli) => cli.id)]; + + // `.strict()` refuses an unknown key, so a mode missing here cannot take an override, and + // `commands.*` is the documented way out for a login shell the stock launch cannot run. + it.each(modes)('accepts a %s override on a remote host and a docker host', (mode) => { + const commands = { [mode]: 'exec my-agent' }; + const remote = { id: 'h', label: 'H', host: '10.0.0.1', username: 'u', commands }; + const docker = { id: 'h', label: 'H', image: 'codeman/agent:base', commands }; + expect(RemoteHostSchema.safeParse(remote).success).toBe(true); + expect(DockerHostSchema.safeParse(docker).success).toBe(true); + }); + + it('still refuses a key that is no mode', () => { + const commands = { nope: 'exec my-agent' }; + expect(RemoteHostSchema.safeParse({ id: 'h', label: 'H', host: '10.0.0.1', username: 'u', commands }).success).toBe( + false + ); + }); + }); + describe('rehydrateRemoteHostFields', () => { const persisted = { hostId: 'hufflepuff',