Skip to content

feat(cli): add appclaw doctor environment preflight - #58

Merged
saikrishna321 merged 3 commits into
mainfrom
feat/doctor-command
Aug 17, 2026
Merged

feat(cli): add appclaw doctor environment preflight#58
saikrishna321 merged 3 commits into
mainfrom
feat/doctor-command

Conversation

@saikrishna321

Copy link
Copy Markdown
Contributor

New appclaw doctor subcommand runs the full setup checklist in seconds without starting an Appium session, so users see every problem at once with fix hints instead of discovering them one failed run at a time:

  • Node >= 22, .env/Zod config validity (reported as a failed check, not a crash), LLM credentials (real ping for Ollama), bundled appium-mcp version, cloud grid config
  • Android: adb on PATH, connected devices, unauthorized-device hints
  • iOS (macOS): Xcode CLT, booted simulators (skipped for DEVICE_TYPE=real)
  • --platform pins one platform as required (exit 1 on failure); with no platform pinned, doctor fails only when no usable target exists at all
  • --full additionally spawns appium-mcp and performs a real MCP handshake
  • --env-file loads a dotenv before config is read, mirroring the main CLI

Exports resolveAppiumMcp() from core so doctor reuses the existing resolution logic instead of duplicating it.

New `appclaw doctor` subcommand runs the full setup checklist in seconds
without starting an Appium session, so users see every problem at once
with fix hints instead of discovering them one failed run at a time:

- Node >= 22, .env/Zod config validity (reported as a failed check, not
  a crash), LLM credentials (real ping for Ollama), bundled appium-mcp
  version, cloud grid config
- Android: adb on PATH, connected devices, unauthorized-device hints
- iOS (macOS): Xcode CLT, booted simulators (skipped for DEVICE_TYPE=real)
- --platform pins one platform as required (exit 1 on failure); with no
  platform pinned, doctor fails only when no usable target exists at all
- --full additionally spawns appium-mcp and performs a real MCP handshake
- --env-file loads a dotenv before config is read, mirroring the main CLI

Exports resolveAppiumMcp() from core so doctor reuses the existing
resolution logic instead of duplicating it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Co-authored-by: Srinivasan Sekar <srinivasan.sekar1990@gmail.com>

@agently-crew agently-crew Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VERDICT: 3 actionable findings

Great work adding the environment preflight! The checks are robust and the logic for gracefully downgrading local toolchain failures to warnings when a cloud grid is configured is particularly elegant. I left a few minor comments regarding CLI argument parsing edge cases and an unused option.

Comment thread packages/cli/src/cli/doctor.ts Outdated
const a = args[i];
if (a === '--help' || a === '-h') parsed.help = true;
else if (a === '--full') parsed.full = true;
else if (a === '--platform') parsed.platform = args[++i] as Platform;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minors

--platform simply casts to Platform, allowing invalid values (e.g. --platform windows). → An invalid platform string causes both device checks to run as non-required warnings, and then bypasses the !target failure fallback, resulting in a false-positive "Ready to run" success even with no devices. → Validate the parsed platform is exactly 'android' or 'ios'.

Comment thread packages/cli/src/cli/doctor.ts Outdated
if (a === '--help' || a === '-h') parsed.help = true;
else if (a === '--full') parsed.full = true;
else if (a === '--platform') parsed.platform = args[++i] as Platform;
else if (a === '--env-file' || a === '--env-path') parsed.envFile = args[++i];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minors

If --env-file is provided as the final CLI argument, args[++i] evaluates to undefined. → The custom env path is silently ignored and the doctor falls back to checking the default .env instead of reporting a missing argument error. → Check that args[++i] is defined and report an error if missing.

Comment thread packages/cli/src/cli/doctor.ts Outdated
return 1;
}
const { config: loadDotenvFile } = await import('dotenv');
loadDotenvFile({ path: envPath, override: true, quiet: true });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplify

quiet: true is passed to loadDotenvFile(), but dotenv.config() does not support a quiet option. → The property is dead code and has no effect. → Remove quiet: true.

saikrishna321 and others added 2 commits August 17, 2026 10:40
Co-authored-by: Srinivasan Sekar <srinivasan.sekar1990@gmail.com>
Co-authored-by: Srinivasan Sekar <srinivasan.sekar1990@gmail.com>
@saikrishna321
saikrishna321 merged commit 3805170 into main Aug 17, 2026
7 checks passed
github-actions Bot pushed a commit that referenced this pull request Aug 17, 2026
## [2.4.0](v2.3.0...v2.4.0) (2026-08-17)

### Features

* **cli:** add appclaw doctor environment preflight ([#58](#58)) ([3805170](3805170))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.4.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant