diff --git a/src/commands/device.ts b/src/commands/device.ts index 4788bc9..eb96746 100644 --- a/src/commands/device.ts +++ b/src/commands/device.ts @@ -819,7 +819,9 @@ const typeSub = defineCommand({ args: { ...commonArgs, id: idArg, - text: { type: 'string', description: 'What to type', required: true }, + // Not `required`: citty would reject a missing value before runDeviceCommand, + // and --json would then print the top-level error instead of the envelope. + text: { type: 'string', description: 'What to type' }, sensitive: { type: 'boolean', default: false, diff --git a/test/unit/device-command.test.ts b/test/unit/device-command.test.ts index 028fbba..00f33f0 100644 --- a/test/unit/device-command.test.ts +++ b/test/unit/device-command.test.ts @@ -339,6 +339,16 @@ describe('dcd device', () => { expect(calls[1].body).to.deep.equal({ type: 'type', text: 'hello' }); }); + it('type without --text is a usage error inside the envelope, not a citty error', async () => { + const calls = stubFetch(ok); + const { exit, out } = await runJson('type', { id: 'a-b-c' }); + expect(exit).to.equal(DEVICE_EXIT.usage); + expect(out).to.have.keys('ok', 'session', 'data', 'error'); + expect(out.ok).to.equal(false); + expect((out.error as { message: string }).message).to.include('--text'); + expect(calls).to.have.length(0); + }); + it('swipe takes a direction as its only positional, or --from and --to', async () => { const calls = stubFetch((call) => call.url.endsWith('/device/sessions') ? { body: { sessions: [session('a-b-c')] } } : ok(),