Skip to content

Commit f4fa651

Browse files
riglarclaude
andcommitted
fix(device): fit start's next steps to the session state
A queued or provisioning session can't be inspected yet, so start now suggests dcd device status first and points at --wait. It suggests install when no app was given, and ends with dcd device --help. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 36e37f6 commit f4fa651

2 files changed

Lines changed: 48 additions & 9 deletions

File tree

‎src/commands/device.ts‎

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,28 @@ export function platformOfModel(catalogue: DeviceCatalogue, model: string): 'and
234234
throw new CliError(`"${model}" is a model on both iOS and Android. Pass --platform ios or --platform android.`);
235235
}
236236

237+
/**
238+
* The "Next steps" `dcd device start` prints. They follow the session: a
239+
* device that isn't ready yet can't be inspected, so that comes first, and
240+
* a session with no app gets the install step.
241+
*/
242+
export function startNextSteps(session: DeviceSession, hasApp: boolean): [string, string][] {
243+
const { id } = session;
244+
const steps: [string, string][] = [];
245+
if (!USABLE_STATES.has(session.state)) {
246+
steps.push(['check it is ready', `dcd device status ${id}`]);
247+
}
248+
249+
if (!hasApp) steps.push(['install an app', `dcd device install ${id} <app>`]);
250+
steps.push(
251+
['inspect the screen', `dcd device inspect ${id}`],
252+
['run a flow', `dcd device run ${id} flow.yaml`],
253+
['stop', `dcd device stop ${id}`],
254+
['all commands', 'dcd device --help'],
255+
);
256+
return steps;
257+
}
258+
237259
const startSub = defineCommand({
238260
meta: { name: 'start', description: 'Start a device session' },
239261
args: {
@@ -373,15 +395,12 @@ const startSub = defineCommand({
373395
logger.log(ui.section('Device session'));
374396
printSession(session);
375397
logger.log(ui.section('Next steps'));
376-
logger.log(
377-
ui.branch(
378-
ui.fields([
379-
['inspect the screen', colors.highlight(`dcd device inspect ${session.id}`)],
380-
['run a flow', colors.highlight(`dcd device run ${session.id} flow.yaml`)],
381-
['stop', colors.highlight(`dcd device stop ${session.id}`)],
382-
]),
383-
),
384-
);
398+
const hasApp = Boolean(installedId ?? uploadedId);
399+
const steps = startNextSteps(session, hasApp);
400+
logger.log(ui.branch(ui.fields(steps.map(([label, cmd]) => [label, colors.highlight(cmd)]))));
401+
if (!USABLE_STATES.has(session.state)) {
402+
logger.log(ui.info('Next time, `dcd device start --wait` waits until the device is ready.'));
403+
}
385404
},
386405
};
387406
});

‎test/unit/device-command.test.ts‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
deviceCommand,
1212
newLogLines,
1313
parseEnvFlags,
14+
startNextSteps,
1415
} from '../../src/commands/device.js';
1516
import { DeviceApiError } from '../../src/gateways/device-gateway.js';
1617
import type { DeviceSession } from '../../src/types/domain/device-session.types.js';
@@ -730,6 +731,25 @@ describe('dcd device', () => {
730731
});
731732

732733
describe('helpers', () => {
734+
it('startNextSteps fits the session: check readiness first, install only with no app', () => {
735+
const cmds = (s: DeviceSession, hasApp: boolean) => startNextSteps(s, hasApp).map(([, cmd]) => cmd);
736+
737+
expect(cmds(session('a', { state: 'queued' }), false)).to.deep.equal([
738+
'dcd device status a',
739+
'dcd device install a <app>',
740+
'dcd device inspect a',
741+
'dcd device run a flow.yaml',
742+
'dcd device stop a',
743+
'dcd device --help',
744+
]);
745+
expect(cmds(session('a', { state: 'ready' }), true)).to.deep.equal([
746+
'dcd device inspect a',
747+
'dcd device run a flow.yaml',
748+
'dcd device stop a',
749+
'dcd device --help',
750+
]);
751+
});
752+
733753
it('formatWhen says how far off a time is', () => {
734754
const now = Date.parse('2026-10-19T10:00:00Z');
735755
expect(formatWhen('2026-10-19T10:12:00Z', now)).to.match(/^in 12m \(.+\)$/);

0 commit comments

Comments
 (0)