Skip to content

Commit fe4ada8

Browse files
feat(cli): add checkly init command with skill-first onboarding (#1267)
Offer people to get a AI Agent guided onboarding experience, ensure they install the Checkly skill, or fall back to a more traditional onboarding experience that's more streamlined than the currently existing one. This does not replace yet the `npm create checkly@latest` equivalent, which will get replaced in the marketing materials and then be deprecated fully.
1 parent 471229a commit fe4ada8

47 files changed

Lines changed: 2727 additions & 118 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/cli/e2e/__tests__/help.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ describe('help', () => {
4444
})
4545
expect(stdout).toContain(`CORE COMMANDS
4646
deploy Deploy your project to your Checkly account.
47+
init Initialize Checkly in your project
4748
pw-test Test your Playwright Tests on Checkly.
4849
test Test your checks on Checkly.
4950
trigger Trigger your existing checks on Checkly.`)

packages/cli/scripts/prepare-ai-context.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { mkdir, readFile, writeFile } from 'fs/promises'
1+
import { cp, mkdir, readFile, writeFile } from 'fs/promises'
22
import { join } from 'path'
33
import { ACTIONS, EXAMPLE_CONFIGS } from '../src/ai-context/context'
44

@@ -170,6 +170,13 @@ async function prepareContext () {
170170
// Copy README
171171
const readme = await readFile(join(AI_CONTEXT_DIR, 'README.md'), 'utf8')
172172
await writeOutput(readme, PUBLIC_SKILL_DIR, 'README.md')
173+
174+
// Copy onboarding assets to dist
175+
for (const dir of ['onboarding-boilerplate', 'onboarding-prompts']) {
176+
await cp(join(AI_CONTEXT_DIR, dir), join(RULES_OUTPUT_DIR, dir), { recursive: true })
177+
// eslint-disable-next-line no-console
178+
console.log(`Copied ${dir} to ${join(RULES_OUTPUT_DIR, dir)}`)
179+
}
173180
} catch (error) {
174181
// eslint-disable-next-line no-console
175182
console.error('❌ Failed to prepare AI context:', error)

packages/cli/src/ai-context/context.fixtures.json

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,7 @@
6161
"scriptPath": null,
6262
"setupScriptPath": null,
6363
"tearDownScriptPath": null,
64-
"retryStrategy": {
65-
"type": "LINEAR",
66-
"maxRetries": 2,
67-
"sameRegion": true,
68-
"baseBackoffSeconds": 60,
69-
"maxDurationSeconds": 600
70-
},
64+
"retryStrategy": null,
7165
"requestCount": 0,
7266
"runParallel": true,
7367
"playwrightConfig": null,
@@ -152,13 +146,7 @@
152146
"scriptPath": null,
153147
"setupScriptPath": null,
154148
"tearDownScriptPath": null,
155-
"retryStrategy": {
156-
"type": "LINEAR",
157-
"maxRetries": 2,
158-
"sameRegion": true,
159-
"baseBackoffSeconds": 60,
160-
"maxDurationSeconds": 600
161-
},
149+
"retryStrategy": null,
162150
"requestCount": 0,
163151
"runParallel": true,
164152
"playwrightConfig": null,
@@ -252,13 +240,7 @@
252240
"scriptPath": null,
253241
"setupScriptPath": null,
254242
"tearDownScriptPath": null,
255-
"retryStrategy": {
256-
"type": "LINEAR",
257-
"maxRetries": 2,
258-
"sameRegion": true,
259-
"baseBackoffSeconds": 60,
260-
"maxDurationSeconds": 600
261-
},
243+
"retryStrategy": null,
262244
"requestCount": 0,
263245
"runParallel": true,
264246
"playwrightConfig": null,
@@ -420,13 +402,7 @@
420402
"scriptPath": null,
421403
"setupScriptPath": null,
422404
"tearDownScriptPath": null,
423-
"retryStrategy": {
424-
"type": "LINEAR",
425-
"maxRetries": 2,
426-
"sameRegion": true,
427-
"baseBackoffSeconds": 60,
428-
"maxDurationSeconds": 600
429-
},
405+
"retryStrategy": null,
430406
"requestCount": 0,
431407
"runParallel": true,
432408
"playwrightConfig": null,
@@ -529,13 +505,7 @@
529505
"scriptPath": null,
530506
"setupScriptPath": null,
531507
"tearDownScriptPath": null,
532-
"retryStrategy": {
533-
"type": "LINEAR",
534-
"maxRetries": 2,
535-
"sameRegion": true,
536-
"baseBackoffSeconds": 60,
537-
"maxDurationSeconds": 600
538-
},
508+
"retryStrategy": null,
539509
"requestCount": 0,
540510
"runParallel": true,
541511
"playwrightConfig": null,
@@ -638,13 +608,7 @@
638608
"scriptPath": null,
639609
"setupScriptPath": null,
640610
"tearDownScriptPath": null,
641-
"retryStrategy": {
642-
"type": "LINEAR",
643-
"maxRetries": 2,
644-
"sameRegion": true,
645-
"baseBackoffSeconds": 60,
646-
"maxDurationSeconds": 600
647-
},
611+
"retryStrategy": null,
648612
"requestCount": 0,
649613
"runParallel": true,
650614
"playwrightConfig": null,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { ApiCheck, AssertionBuilder } from 'checkly/constructs'
2+
3+
// API checks send an HTTP request to a URL endpoint and validate the response. Read more at:
4+
// https://www.checklyhq.com/docs/api-checks/
5+
6+
new ApiCheck('books-api-check-1', {
7+
name: 'Books API',
8+
alertChannels: [],
9+
degradedResponseTime: 10000, // milliseconds
10+
maxResponseTime: 20000,
11+
request: {
12+
url: 'https://danube-web.shop/api/books',
13+
method: 'GET',
14+
followRedirects: true,
15+
skipSSL: false,
16+
assertions: [
17+
AssertionBuilder.statusCode().equals(200),
18+
AssertionBuilder.jsonBody('$[0].id').isNotNull(),
19+
],
20+
},
21+
runParallel: false,
22+
})
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { HeartbeatMonitor } from 'checkly/constructs'
2+
3+
// Heartbeat monitors allow you to monitor jobs or recurring tasks.
4+
// After you deploy this check, you'll get a ping URL for your check
5+
// from the Checkly CLI. This check will generate alerts if it's not
6+
// getting pings at the generated URL, so it's deactivated for now.
7+
// Further documentation: https://www.checklyhq.com/docs/heartbeat-monitors/
8+
9+
new HeartbeatMonitor('heartbeat-1', {
10+
name: 'Send weekly newsletter job',
11+
activated: false,
12+
period: 1,
13+
periodUnit: 'hours',
14+
grace: 30,
15+
graceUnit: 'minutes',
16+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { test, expect } from '@playwright/test'
2+
3+
// This test is being used as a Browser check
4+
// See browserCheck.testMatch in your checkly.config.ts to configure
5+
6+
test('Visit webshop homepage', async ({ page }) => {
7+
// The baseURL for Browser checks can be set in the playwrightConfig of your checkly.config.ts
8+
const response = await page.goto('/')
9+
expect(response?.status()).toBeLessThan(400)
10+
await expect(page).toHaveTitle(/Danube WebShop/)
11+
await page.screenshot({ path: 'homepage.jpg' })
12+
})
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { UrlAssertionBuilder, UrlMonitor } from 'checkly/constructs'
2+
3+
// URL monitors check a URL endpoint for availability and response time. Read more at:
4+
// https://www.checklyhq.com/docs/url-monitors/
5+
6+
new UrlMonitor('books-url-check', {
7+
name: 'Books URL',
8+
activated: true,
9+
maxResponseTime: 10000,
10+
degradedResponseTime: 5000,
11+
request: {
12+
url: 'https://www.danube-web.shop/',
13+
followRedirects: true,
14+
assertions: [
15+
UrlAssertionBuilder.statusCode().equals(200),
16+
],
17+
},
18+
})
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { defineConfig } from 'checkly'
2+
3+
/**
4+
* See https://www.checklyhq.com/docs/cli/project-structure/
5+
*/
6+
const config = defineConfig({
7+
/* A human friendly name for your project */
8+
projectName: '{{projectName}}',
9+
/** A logical ID that needs to be unique across your Checkly account,
10+
* See https://www.checklyhq.com/docs/cli/constructs/ to learn more about logical IDs.
11+
*/
12+
logicalId: '{{logicalId}}',
13+
/* Sets default values for Checks */
14+
checks: {
15+
/* A default for how often your Check should run in minutes */
16+
frequency: 10,
17+
/* Checkly data centers to run your Checks as monitors */
18+
locations: ['us-east-1', 'eu-central-1'],
19+
/** The Checkly Runtime identifier, determining npm packages and the Node.js version available at runtime.
20+
* See https://www.checklyhq.com/docs/cli/npm-packages/
21+
*/
22+
runtimeId: '2025.04',
23+
/* A glob pattern that matches the Checks inside your repo, see https://www.checklyhq.com/docs/constructs/including-checks/#checks-checkmatch */
24+
checkMatch: '**/__checks__/**/*.check.ts',
25+
/* Global configuration option for Browser and Multistep checks. See https://www.checklyhq.com/docs/browser-checks/playwright-test/#global-configuration */
26+
playwrightConfig: {
27+
timeout: 30000,
28+
use: {
29+
baseURL: 'https://www.danube-web.shop',
30+
viewport: { width: 1280, height: 720 },
31+
},
32+
},
33+
browserChecks: {
34+
/* A glob pattern matches any Playwright .spec.ts files and automagically creates a Browser Check. This way, you
35+
* can just write Playwright code. See https://www.checklyhq.com/docs/constructs/including-checks/#browserchecks-testmatch
36+
* */
37+
testMatch: '**/__checks__/**/*.spec.ts',
38+
},
39+
},
40+
cli: {
41+
/* The default datacenter location to use when running npx checkly test */
42+
runLocation: 'eu-central-1',
43+
/* An array of default reporters to use when a reporter is not specified with the "--reporter" flag */
44+
reporters: ['list'],
45+
/* How many times to retry a failing test run when running `npx checkly test` or `npx checkly trigger` (max. 3) */
46+
retries: 0,
47+
},
48+
})
49+
50+
export default config
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Initialize Checkly in this project at {{projectPath}}. I already have a Playwright test suite with a config at {{playwrightConfigPath}} — analyze them to identify what can be reused as a Checkly Playwright Check Suites to monitor critical flows of my application. Also inspect the project structure and endpoints for relevant API checks or URL monitors.

0 commit comments

Comments
 (0)