feat(cli): add checkly init command with skill-first onboarding#1267
feat(cli): add checkly init command with skill-first onboarding#1267thebiglabasky wants to merge 49 commits intomainfrom
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… installation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Agent mode: clean JSON-only output with error envelope - CI mode: skip prompts, run non-interactively - Graceful Ctrl+C handling across all prompts - Error handling for file I/O, malformed package.json, missing templates - Better copy: skill install context, platform picker wording - Conditional clipboard label in expand prompt - Footer: add --record flag - Sanitize scoped package names in logicalId - Re-init warning when checkly config exists Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ting without skill - Detect existing skill installation by scanning known platform directories - Existing Checkly projects: no boilerplate, no dep install, offer skill + AI prompt - Existing + skill already installed: refresh skill silently, show AI prompt directly - Brand new projects: separate prompts for boilerplate and dependency installation - Split boilerplate creation and dep install into independently callable functions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… parsing Detects PM via lockfiles, config files, runtime, and executables — not just npm_config_user_agent which is empty when running checkly directly.
… the skill matters
… projects Existing projects get contextual suggestions (test, deploy, skills) with a simple Enter to exit, instead of the new-user footer or a select menu.
… to npx checkly init
- Add AssertionBuilder method reference with all available methods (agents were guessing incorrect methods like .body()) - Add public URL requirement warnings to API checks, browser checks, and URL monitors (agents were generating localhost checks) - Add location/plan tier documentation to configure reference (agents were setting locations unavailable on free plans) - Promote env var auth as primary path in initialize reference (agents can't do browser OAuth) - Update npm create checkly references to npx checkly init Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lled - Skill installed path: show prompt + agent footer with platform hint - No boilerplate or deps prompts when skill is installed - Existing projects: no deps install (they already have Checkly) - Manual fallback always shown in dimmed text Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
🎉 Experimental release successfully published on npm |
| - If endpoints require authentication ask the user which authentication method to use and then generate a setupScript to authenticate the given requests. | ||
| - Referenced `setup-script.ts` and `teardown-script.ts` for API checks must be plain ts files and not export anything. | ||
| - Check in the code if API endpoints require authentication. | ||
| - **Important:** The target URL must be publicly accessible. Checks run on Checkly's cloud infrastructure, not locally. If the user is developing against localhost, suggest a tunneling tool (ngrok, cloudflare tunnel) or a preview/staging deployment. |
There was a problem hiding this comment.
works for me, just wondering if the dev workflow here was intentionally added
There was a problem hiding this comment.
This comes from me testing locally and getting checks generated on localhost by default, failing, then asking about it. That part however is something I think is a bit too ad hoc. I wonder if we couldn't just make this a global-ish rule
There was a problem hiding this comment.
Should we talk about the Checkly reporter instead? I always disliked the idea of bringing in a tunnel just for using the checkly stuff?
| `AssertionBuilder` provides methods to assert on API responses. Available methods: | ||
|
|
||
| - `AssertionBuilder.statusCode()` — Assert on HTTP status code. Example: `.equals(200)`, `.isGreaterThan(199)` | ||
| - `AssertionBuilder.jsonBody(path)` — Assert on JSON body using JSONPath. Example: `AssertionBuilder.jsonBody('$.id').isNotNull()` | ||
| - `AssertionBuilder.textBody()` — Assert on raw text body. Example: `.contains('OK')` | ||
| - `AssertionBuilder.headers(name)` — Assert on response headers. Example: `AssertionBuilder.headers('content-type').contains('application/json')` | ||
| - `AssertionBuilder.responseTime()` — Assert on response time in ms. Example: `.isLessThan(2000)` | ||
|
|
||
| Each method returns a chainable builder with comparison methods: `.equals()`, `.notEquals()`, `.contains()`, `.notContains()`, `.isGreaterThan()`, `.isLessThan()`, `.isEmpty()`, `.isNotEmpty()`, `.isNull()`, `.isNotNull()` |
There was a problem hiding this comment.
unrelated to this PR @thebiglabasky but since you mentioned CLI support for agentic checks.
we'll be able to do something similar
MichaelHogers
left a comment
There was a problem hiding this comment.
LGTM
Looks quite alright, not a ton of time to look at details
…mode hint - npx checkly init --target claude: installs skill non-interactively - CI mode now hints about skills install at the end - Examples in --help show --target and CI=true usage Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| successMessage: vi.fn((msg: string) => `OK ${msg}`), | ||
| })) | ||
| vi.mock('prompts', () => ({ default: vi.fn() })) | ||
| vi.mock('fs', async importOriginal => { |
There was a problem hiding this comment.
critical to ensure we don't overwrite stuff during tests
| @@ -0,0 +1 @@ | |||
| Initialize Checkly in this project at {{projectPath}}. Set up monitoring checks tailored to this codebase — look at the project structure, existing tests, and endpoints to create relevant API checks, browser checks, or URL monitors. | |||
There was a problem hiding this comment.
Out f curiosity, why do we focus on browser checks and not playwright checks?
|
|
||
| - **Option A: Interactive login** — The user runs `npx checkly login` themselves. This command opens a browser for OAuth authentication and cannot be completed by an AI agent. Tell the user to run the command, complete the browser flow, and let you know when they're done so you can re-run `npx checkly whoami` to verify. | ||
| - **Option B: Environment variables (recommended for agentic / CI use)** — The user sets `CHECKLY_API_KEY` and `CHECKLY_ACCOUNT_ID` as environment variables. They can create an API key in the Checkly dashboard under **User Settings > API Keys**. Once both variables are set, re-run `npx checkly whoami` to verify. | ||
| - **Option A: Environment variables (recommended)** — The user sets `CHECKLY_API_KEY` and `CHECKLY_ACCOUNT_ID` as environment variables. They can create an API key in the Checkly dashboard under **User Settings > API Keys**. This is the recommended approach as it works in all contexts (agentic, CI/CD, and interactive). Once both variables are set, re-run `npx checkly whoami` to verify. |
There was a problem hiding this comment.
can we add a URL to API keys to prompt the user directly?
| @@ -0,0 +1,15 @@ | |||
| import { UrlAssertionBuilder, UrlMonitor } from 'checkly/constructs' | |||
|
|
|||
There was a problem hiding this comment.
Nit: out of consistency would be nice to have a comment here too. 🫣
| || 'checkly-project' | ||
| } | ||
|
|
||
| async function detectPM (projectDir: string): Promise<{ name: string, installCmd: string }> { |
There was a problem hiding this comment.
hardcore nit: i'd appreciate detectPackageManager here. I see the variable name clash but would then rename the imported one and expose one with an expressive name. 🫣
| return [ | ||
| ...playwrightBlock(), | ||
| '', | ||
| chalk.cyan(` An AI agent can help configure this — run ${chalk.bold('npx checkly skills install')}`), |
There was a problem hiding this comment.
If I get the context correctly, this message isn't great. An "empty this" is never great and I'm unsure how npx checkly skills install helps directly. Shouldn't we be more explicit here?
| log: (msg: string) => void, | ||
| ): Promise<SkillInstallResult> { | ||
| log('') | ||
| log(` Checkly is an ${chalk.bold('AI-native monitoring as code')} platform.`) |
There was a problem hiding this comment.
| log(` Checkly is an ${chalk.bold('AI-native monitoring as code')} platform.`) | |
| log(` Checkly is an ${chalk.bold('AI-native Monitoring as Code')} platform.`) |
Here i actually care about the casing. :D
| "clean": "npm run clean:dist && npm run clean:gen", | ||
| "prepack": "npx oclif manifest", | ||
| "prepare:ai-context": "cross-env CHECKLY_SKIP_AUTH=1 CHECKLY_CLI_VERSION=99.0.0 ./bin/run import plan --root gen --debug-import-plan-input-file ./src/ai-context/context.fixtures.json && ts-node ./scripts/prepare-ai-context.ts", | ||
| "prepare:ai-context": "cross-env CHECKLY_SKIP_AUTH=1 CHECKLY_CLI_VERSION=99.0.0 ./bin/run import plan --root gen --debug-import-plan-input-file ./src/ai-context/context.fixtures.json && ts-node ./scripts/prepare-ai-context.ts && cp -r src/ai-context/onboarding-boilerplate dist/ai-context/onboarding-boilerplate && cp -r src/ai-context/onboarding-prompts dist/ai-context/onboarding-prompts", |
There was a problem hiding this comment.
Could we have the copy logic in prepare-ai-context? I think it already copies stuff around. :) Would also keep the package.json cleaner.
There was a problem hiding this comment.
Generally, I think it's very bold to touch the "standard" init flow in one go. Personally, I'd split this into two stages because you might get more feedback from a released init command. But yeah, no strong feelings if you wanna go fast.
stefanjudis
left a comment
There was a problem hiding this comment.
I've spent 30min reviewing the code. I'll play around with it to see how it feels and approve if everything feels great.








Summary
Adds
npx checkly init— a new onboarding command that replacesnpm create checkly@latestwith a streamlined, AI-agent-aware flow. The skill installation is front and center: install the skill, get a tailored prompt copied to your clipboard, hand off to your agent.npm create checkly@latestnow shows a deprecation notice pointing tonpx checkly initnpx checkly(no args) nudges towardinitandskills installwhen no config is detected.mdfiles insrc/ai-context/onboarding-prompts/— easy to review and tweak without touching TypeScriptpbcopy/xclip/xsel/clip) with silent fallback — no external dependencySupported paths (all tested)
Reuses existing CLI utilities
findPlaywrightConfigPathfromservices/util.ts(extended with.mts/.mjs)defaultFilenamesfromcheckly-config-loader.tsdetectPackageManagerfor robust PM detection (lockfiles, config, runtime, user agent)promptForPlatformTargetshared betweenskills installandinitlogSymbolsvia sharedsuccessMessage()helperPLATFORM_TARGETS— skill directories derived from it to prevent driftPoints of attention for reviewers
messages.ts(shared blocks) andonboarding-prompts/*.md(agent prompts). Easy to change in one place.src/ai-context/onboarding-boilerplate/are excluded from tsconfig (not compiled) and vitest (not test files) — they're copied to dist at build time.npm create checklyreferences updated tonpx checkly init.Test plan
CLAUDECODE=1 npx checkly initnpx checklywith no config — should show nudgenpm create checkly@latest— should show deprecation noticenpx vitest run— 740+ tests pass🤖 Generated with Claude Code