Skip to content

Commit aa23595

Browse files
authored
Merge branch 'main' into michelle/red-71-soft-diagnostics-for-logicalid-validation
2 parents d3cd678 + 04cc5a2 commit aa23595

File tree

30 files changed

+1897
-17
lines changed

30 files changed

+1897
-17
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import config from 'config'
2+
import { describe, it, expect } from 'vitest'
3+
4+
import { runChecklyCli } from '../run-checkly'
5+
6+
describe('checkly account plan', () => {
7+
it('should show plan summary with default output', async () => {
8+
const result = await runChecklyCli({
9+
args: ['account', 'plan'],
10+
apiKey: config.get('apiKey'),
11+
accountId: config.get('accountId'),
12+
})
13+
expect(result.status).toBe(0)
14+
expect(result.stdout).toContain('Plan:')
15+
expect(result.stdout).toContain('Metered entitlements')
16+
expect(result.stdout).toContain('additional features enabled')
17+
})
18+
19+
it('should output valid JSON with --output json', async () => {
20+
const result = await runChecklyCli({
21+
args: ['account', 'plan', '--output', 'json'],
22+
apiKey: config.get('apiKey'),
23+
accountId: config.get('accountId'),
24+
})
25+
expect(result.status).toBe(0)
26+
const parsed = JSON.parse(result.stdout)
27+
expect(parsed).toHaveProperty('plan')
28+
expect(parsed).toHaveProperty('planDisplayName')
29+
expect(parsed).toHaveProperty('addons')
30+
expect(parsed).toHaveProperty('entitlements')
31+
expect(Array.isArray(parsed.entitlements)).toBe(true)
32+
expect(parsed.entitlements.length).toBeGreaterThan(0)
33+
expect(parsed.entitlements[0]).toHaveProperty('key')
34+
expect(parsed.entitlements[0]).toHaveProperty('type')
35+
expect(parsed.entitlements[0]).toHaveProperty('enabled')
36+
})
37+
38+
it('should output markdown with --output md', async () => {
39+
const result = await runChecklyCli({
40+
args: ['account', 'plan', '--output', 'md'],
41+
apiKey: config.get('apiKey'),
42+
accountId: config.get('accountId'),
43+
})
44+
expect(result.status).toBe(0)
45+
expect(result.stdout).toContain('# Plan:')
46+
expect(result.stdout).toContain('| Name | Limit |')
47+
})
48+
49+
it('should show detail view for a specific entitlement key', async () => {
50+
const result = await runChecklyCli({
51+
args: ['account', 'plan', 'BROWSER_CHECKS'],
52+
apiKey: config.get('apiKey'),
53+
accountId: config.get('accountId'),
54+
})
55+
expect(result.status).toBe(0)
56+
expect(result.stdout).toContain('BROWSER_CHECKS')
57+
expect(result.stdout).toContain('Browser checks')
58+
})
59+
60+
it('should output single entitlement as JSON', async () => {
61+
const result = await runChecklyCli({
62+
args: ['account', 'plan', 'BROWSER_CHECKS', '--output', 'json'],
63+
apiKey: config.get('apiKey'),
64+
accountId: config.get('accountId'),
65+
})
66+
expect(result.status).toBe(0)
67+
const parsed = JSON.parse(result.stdout)
68+
expect(parsed.key).toBe('BROWSER_CHECKS')
69+
expect(parsed.type).toBe('metered')
70+
})
71+
72+
it('should filter by --type metered', async () => {
73+
const result = await runChecklyCli({
74+
args: ['account', 'plan', '--type', 'metered'],
75+
apiKey: config.get('apiKey'),
76+
accountId: config.get('accountId'),
77+
})
78+
expect(result.status).toBe(0)
79+
expect(result.stdout).toContain('LIMIT')
80+
expect(result.stdout).toContain('entitlement')
81+
})
82+
83+
it('should filter by --type flag', async () => {
84+
const result = await runChecklyCli({
85+
args: ['account', 'plan', '--type', 'flag'],
86+
apiKey: config.get('apiKey'),
87+
accountId: config.get('accountId'),
88+
})
89+
expect(result.status).toBe(0)
90+
expect(result.stdout).toContain('ENABLED')
91+
expect(result.stdout).toContain('entitlement')
92+
})
93+
94+
it('should filter by --search', async () => {
95+
const result = await runChecklyCli({
96+
args: ['account', 'plan', '--search', 'browser'],
97+
apiKey: config.get('apiKey'),
98+
accountId: config.get('accountId'),
99+
})
100+
expect(result.status).toBe(0)
101+
expect(result.stdout).toContain('Browser')
102+
expect(result.stdout).toContain('entitlement')
103+
})
104+
105+
it('should fail for unknown entitlement key', async () => {
106+
const result = await runChecklyCli({
107+
args: ['account', 'plan', 'NONEXISTENT_KEY'],
108+
apiKey: config.get('apiKey'),
109+
accountId: config.get('accountId'),
110+
})
111+
expect(result.status).toBe(2)
112+
expect(result.stderr).toContain('not found')
113+
})
114+
115+
it('should fail when combining key with --type', async () => {
116+
const result = await runChecklyCli({
117+
args: ['account', 'plan', 'BROWSER_CHECKS', '--type', 'metered'],
118+
apiKey: config.get('apiKey'),
119+
accountId: config.get('accountId'),
120+
})
121+
expect(result.status).not.toBe(0)
122+
})
123+
124+
it('should show REQUIRED UPGRADE column in summary view', async () => {
125+
const result = await runChecklyCli({
126+
args: ['account', 'plan'],
127+
apiKey: config.get('apiKey'),
128+
accountId: config.get('accountId'),
129+
})
130+
expect(result.status).toBe(0)
131+
expect(result.stdout).toContain('REQUIRED UPGRADE')
132+
})
133+
134+
it('should show billing checkout link', async () => {
135+
const result = await runChecklyCli({
136+
args: ['account', 'plan'],
137+
apiKey: config.get('apiKey'),
138+
accountId: config.get('accountId'),
139+
})
140+
expect(result.status).toBe(0)
141+
expect(result.stdout).toContain('billing/checkout')
142+
})
143+
144+
it('should include checkoutUrl and contactSalesUrl in JSON output', async () => {
145+
const result = await runChecklyCli({
146+
args: ['account', 'plan', '--output', 'json'],
147+
apiKey: config.get('apiKey'),
148+
accountId: config.get('accountId'),
149+
})
150+
expect(result.status).toBe(0)
151+
const parsed = JSON.parse(result.stdout)
152+
expect(parsed).toHaveProperty('checkoutUrl')
153+
expect(parsed.checkoutUrl).toContain('billing/checkout')
154+
expect(parsed).toHaveProperty('contactSalesUrl')
155+
expect(parsed.contactSalesUrl).toContain('contact-sales')
156+
})
157+
158+
it('should filter with --disabled flag', async () => {
159+
const result = await runChecklyCli({
160+
args: ['account', 'plan', '--disabled'],
161+
apiKey: config.get('apiKey'),
162+
accountId: config.get('accountId'),
163+
})
164+
expect(result.status).toBe(0)
165+
expect(result.stdout).toContain('entitlement')
166+
})
167+
168+
it('should combine --disabled with --type', async () => {
169+
const result = await runChecklyCli({
170+
args: ['account', 'plan', '--disabled', '--type', 'flag'],
171+
apiKey: config.get('apiKey'),
172+
accountId: config.get('accountId'),
173+
})
174+
expect(result.status).toBe(0)
175+
expect(result.stdout).toContain('REQUIRED UPGRADE')
176+
})
177+
178+
it('should fail when combining key with --disabled', async () => {
179+
const result = await runChecklyCli({
180+
args: ['account', 'plan', 'BROWSER_CHECKS', '--disabled'],
181+
apiKey: config.get('apiKey'),
182+
accountId: config.get('accountId'),
183+
})
184+
expect(result.status).not.toBe(0)
185+
})
186+
})

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ describe('help', () => {
4949
trigger Trigger your existing checks on Checkly.`)
5050

5151
expect(stdout).toContain(`ADDITIONAL COMMANDS
52+
account View and manage your Checkly account.
5253
checks List and inspect checks in your Checkly account.
5354
destroy Destroy your project with all its related resources.
5455
env Manage Checkly environment variables.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ describe('whomai', () => {
1111
accountId: config.get('accountId'),
1212
})
1313
expect(stdout).toContain(config.get('accountName'))
14+
expect(stdout).toContain('Plan:')
1415
})
1516
})

packages/cli/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@
6464
"message": "<%= config.name %> update available from <%= chalk.greenBright(config.version) %> to <%= chalk.greenBright(latest) %>. To update, run `npm install -D checkly@latest`"
6565
},
6666
"topics": {
67+
"account": {
68+
"description": "View and manage your Checkly account."
69+
},
6770
"checks": {
6871
"description": "List and inspect checks in your Checkly account."
6972
},
@@ -76,9 +79,6 @@
7679
"import": {
7780
"description": "Import existing resources from your Checkly account to your project."
7881
},
79-
"skills": {
80-
"description": "Explore Checkly AI agent skills, actions and reference documentation."
81-
},
8282
"status-pages": {
8383
"description": "List and manage status pages in your Checkly account."
8484
}

packages/cli/src/ai-context/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ Agent Skills are a standardized format for giving AI agents specialized knowledg
2626
- Build dashboards and status pages
2727
- Follow monitoring-as-code best practices with the Checkly CLI
2828

29+
## Installing This Skill
30+
31+
Run `npx checkly skills install` to install the skill into your project. The command supports Claude Code, Cursor, Codex and more out of the box, or you can specify a custom path.
32+
2933
## Using This Skill
3034

3135
AI agents can load this skill to gain expertise in Checkly monitoring. The skill follows the [Agent Skills specification](https://agentskills.io) with:

packages/cli/src/ai-context/context.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ export const COMMUNICATE_REFERENCES = [
6363
},
6464
] as const
6565

66+
export const MANAGE_REFERENCES = [
67+
{
68+
id: 'manage-plan',
69+
description: 'Check account plan, entitlements, feature limits, and available locations (`account plan`)',
70+
},
71+
] as const
72+
6673
export const SKILL = {
6774
name: 'checkly',
6875
description: 'Get all the information and context to let your agent initialize, set up, create, test and manage your monitoring checks using the Checkly CLI.',
@@ -88,6 +95,11 @@ export const ACTIONS = [
8895
description: 'Open incidents and lead customer communications via status pages.',
8996
references: COMMUNICATE_REFERENCES,
9097
},
98+
{
99+
id: 'manage',
100+
description: 'Understand your account plan, entitlements, and feature limits.',
101+
references: MANAGE_REFERENCES,
102+
},
91103
] as const
92104

93105
interface ExampleConfig {

packages/cli/src/ai-context/references/communicate-incidents.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,13 @@ Flags:
6767

6868
## Status pages
6969

70-
Use `npx checkly status-pages list` to find status page IDs and their services. Use `--output json` to get machine-readable service IDs for incident creation.
70+
Use `npx checkly status-pages list` to find status page IDs, and `npx checkly status-pages get` for full details including cards and services.
7171

7272
```bash
7373
npx checkly status-pages list
7474
npx checkly status-pages list --output json
75+
npx checkly status-pages get <status-page-id>
76+
npx checkly status-pages get <status-page-id> --output json
7577
```
78+
79+
Use `--output json` to get machine-readable service IDs for incident creation.

packages/cli/src/ai-context/references/configure.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ If the Checkly CLI is installed (`npx checkly version`), use `npx checkly skills
4646

4747
<!-- REFERENCE_COMMANDS -->
4848

49+
## Check Locations and Plan Entitlements
50+
51+
Not all features and locations are available on all plans. **Before configuring checks, run:**
52+
53+
```bash
54+
npx checkly account plan --output json
55+
```
56+
57+
This returns your exact entitlements and available locations. Use only locations where `available` is `true` in the `locations.all` array. If a feature is disabled, the response includes an `upgradeUrl` to share with the user.
58+
59+
Run `npx checkly skills manage plan` for the full reference.
60+
4961
## Testing and Debugging
5062

5163
- Test checks using the `npx checkly test` command. Pass environment variables with the `-e` flag, use `--record` to persist results, and use `--verbose` to see all errors.

packages/cli/src/ai-context/references/initialize.md

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,25 @@ Run `npx checkly skills configure alert-channels` to access up-to-date informati
7070
- **next to the resource** — place the `check.ts` files next to page routes, api endpoints etc.
7171
7272
73-
#### Step 3 — Create the config file
73+
#### Step 3 — Check your account plan
74+
75+
Before writing checks, verify what your account can do:
76+
77+
```bash
78+
npx checkly account plan --output json
79+
```
80+
81+
This shows your entitlements, limits, and available locations. Use this data when creating the config:
82+
83+
- **Only use locations** from `locations.all` where `available` is `true`. Using unavailable locations will cause deploy failures.
84+
- **Check feature availability** before configuring constructs like private locations, advanced alert channels, or higher-frequency schedules.
85+
- **Respect metered limits** — the `quantity` field shows maximums for each metered feature.
86+
87+
If a feature the user wants is disabled, the response includes an `upgradeUrl` — share it so they can upgrade their plan.
88+
89+
Run `npx checkly skills manage plan` for the full reference.
90+
91+
#### Step 4 — Create the config file
7492
7593
Run the following command to retrieve the configure skill reference:
7694
@@ -80,13 +98,13 @@ npx checkly skills configure
8098
8199
Use the output to create a `checkly.config.ts` (or `checkly.config.js` if the user chose JavaScript) in the project root.
82100
83-
Adjust the `checkMatch` property according to previous selection.
101+
Adjust the `checkMatch` property according to previous selection. Use only locations verified as available in the previous step.
84102
85103
Present the generated configuration to the user and ask if it looks correct. Allow the user to make changes.
86104
87105
Congratulate the user on completing the config. Now it's time to test the configuration and turn everything into monitoring!
88106

89-
#### Step 4: Log in to Checkly CLI
107+
#### Step 5: Log in to Checkly CLI
90108

91109
To use the Checkly CLI the user needs to be logged in. Run the following command:
92110

@@ -101,7 +119,7 @@ If the user is NOT logged in, present two options:
101119
- **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.
102120
- **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.
103121

104-
#### Step 5: Summarize and test the new monitoring configuration
122+
#### Step 6: Summarize and test the new monitoring configuration
105123

106124
Read the generated `checkly.config.ts` (or `checkly.config.js`) and summarize the configured checks, locations, and frequencies.
107125

packages/cli/src/ai-context/references/investigate-checks.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,28 @@ npx checkly checks get <check-id> --result <result-id>
3737
npx checkly checks get <check-id> --error-group <error-group-id>
3838
```
3939

40+
## Check analytics and stats
41+
42+
```bash
43+
npx checkly checks stats
44+
npx checkly checks stats --range last7Days --tag production
45+
npx checkly checks stats <check-id-1> <check-id-2>
46+
npx checkly checks stats --output json
47+
```
48+
49+
Shows availability, response times, error counts, and other metrics for your checks.
50+
51+
Flags:
52+
- `-r, --range <range>` — time range: `last24Hours` (default), `last7Days`, `thisWeek`, `lastWeek`, `lastMonth`
53+
- `-t, --tag <tag>` — filter by tag (repeat for multiple)
54+
- `--type <type>` — filter by check type
55+
- `-s, --search <name>` — filter by name
56+
- `-l, --limit <n>` — max checks to return (1-100, default 25)
57+
- `-p, --page <n>` — page number
58+
- `-o, --output <format>``table` (default), `json`, or `md`
59+
60+
Pass one or more check IDs as positional arguments to get stats for specific checks only.
61+
4062
## Trigger checks
4163

4264
```bash

0 commit comments

Comments
 (0)