keepgreen 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +135 -64
- package/SECURITY.md +7 -1
- package/action.yml +10 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +41 -6
- package/dist/cli.js.map +1 -1
- package/dist/explore.d.ts +8 -0
- package/dist/explore.js +38 -7
- package/dist/explore.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/price.d.ts +13 -0
- package/dist/price.js +42 -0
- package/dist/price.js.map +1 -0
- package/package.json +2 -2
- package/selfhost/docker-compose.yml +1 -1
- package/templates/keepgreen-explore.yml +46 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
- AutoHeal 0.13.0 inside (healing and test writing): OpenRouter works in AutoHeal's heal Action (`api-key` input), OpenRouter prices are looked up for healing too, and the engine is playwright-e2e-mcp 0.16.1 (Playwright 1.65, GitHub tokens kept out of test processes).
|
|
6
|
+
- The self-host bundle builds the AutoHeal dashboard from v0.13.0.
|
|
7
|
+
|
|
8
|
+
## 0.2.0
|
|
9
|
+
|
|
10
|
+
Fixes from a full audit, plus the most-asked-for features.
|
|
11
|
+
|
|
12
|
+
- **Explore a deployed app.** `--url` (and `url:`) now accepts any http(s) address, such as a staging or preview deployment. 0.1.x refused anything but localhost with a message about `start-url`. An app KeepGreen starts itself (`start-command`) must still be on this machine. Point it at a test environment, not production.
|
|
13
|
+
- **Name the flows yourself.** `keepgreen explore --flow "A shopper adds the mug to the cart and the cart shows 1"` skips the AI planning and writes a test for each flow you name (repeat `--flow`). The Action has a `flows` input (one per line) and the workflow template a `flows` box (separated by `;`).
|
|
14
|
+
- **No more lost tests from name clashes.** Test file names were the first six words of the flow, so two flows starting "A visitor opens the home page..." got the same name and AutoHeal refused the second one. Names now skip filler words (`keepgreen-opens-home-clicks-account-link-lands.spec.ts`) and get `-2`, `-3` when a name is already taken, on disk or earlier in the run.
|
|
15
|
+
- **max-usd works on OpenRouter without setting prices.** For an OpenRouter `base-url`, KeepGreen looks up the model's price in OpenRouter's public model list. Before, a model with no listed price ran with only a token cap. When no price can be found, explore now says so up front.
|
|
16
|
+
- **Weekly runs don't pile up.** A scheduled explore run stops when a KeepGreen PR is still open, instead of planning the same flows again. Manual runs always go ahead.
|
|
17
|
+
- **CI runs on KeepGreen's PRs.** GitHub starts no workflows on a PR opened with the built-in token. Add an optional `KEEPGREEN_PR_TOKEN` secret (a fine-grained token for this repo) and the publish job uses it, so your checks run. Re-running the publish job no longer fails on an existing branch.
|
|
18
|
+
- **PR bodies can't ping people.** `@name` in AI-written flow text is defused before it goes into the report.
|
|
19
|
+
- `summary.json` now lists each flow's result (status, file, reason) and whether the spend is priced.
|
|
20
|
+
|
|
3
21
|
## 0.1.1
|
|
4
22
|
|
|
5
23
|
- OpenRouter and other OpenAI-compatible endpoints in the GitHub Action: new `base-url`, `api-key`, `price-in` and `price-out` inputs (the template shows them commented out). The README has an OpenRouter section.
|
package/README.md
CHANGED
|
@@ -1,27 +1,75 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/xsignon-secure/keepgreen/main/docs/logo.png" alt="KeepGreen logo: a green check inside a looping arrow" width="140">
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">KeepGreen</h1>
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
covers every run.
|
|
7
|
+
<p align="center"><b>The AI test agent that writes, fixes and keeps your end-to-end tests green.</b><br>
|
|
8
|
+
It finds the user flows nobody tests, writes a test for each, and fixes tests when your UI changes.<br>
|
|
9
|
+
Every test it keeps <b>proved itself</b>: real assertions, green run after run.</p>
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
<p align="center">
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
finds stable locators, runs tests and reads failures.
|
|
14
|
-
- [AutoHeal](https://github.com/xsignon-secure/AutoHeal-AI) is the guarded fixer and test writer,
|
|
15
|
-
with its anti-cheat guard and stability proof.
|
|
13
|
+
[](https://www.npmjs.com/package/keepgreen) [](https://www.npmjs.com/package/keepgreen) [](https://github.com/xsignon-secure/keepgreen/actions/workflows/ci.yml) [](https://www.npmjs.com/package/keepgreen#provenance) [](LICENSE) [](#-free-forever)
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center">⭐ <b>If KeepGreen saves you a test-writing afternoon, <a href="https://github.com/xsignon-secure/keepgreen">a star</a> helps other teams find it.</b></p>
|
|
18
|
+
|
|
19
|
+
<p align="center">
|
|
20
|
+
<a href="#-quick-start">Quick start</a> ·
|
|
21
|
+
<a href="#-github-actions">GitHub Actions</a> ·
|
|
22
|
+
<a href="#-how-explore-works">How it works</a> ·
|
|
23
|
+
<a href="#%EF%B8%8F-settings">Settings</a> ·
|
|
24
|
+
<a href="#-security">Security</a> ·
|
|
25
|
+
<a href="CHANGELOG.md">Changelog</a>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
KeepGreen runs **on your own CI runner or laptop, with your own AI key**: Anthropic, OpenAI,
|
|
29
|
+
OpenRouter, or any OpenAI-compatible endpoint including local models. There is no KeepGreen
|
|
30
|
+
server, no account and no telemetry. You pay only your AI provider, and one spend cap covers
|
|
31
|
+
every run.
|
|
32
|
+
|
|
33
|
+
## ❌ Without it / ✅ With it
|
|
21
34
|
|
|
22
|
-
|
|
35
|
+
**Without it**, the checkout page ships with no end-to-end test because nobody had time to write
|
|
36
|
+
one. When a test does exist, a renamed button turns CI red and someone spends an hour patching
|
|
37
|
+
selectors, or an AI "fixes" it by deleting the assertion that mattered.
|
|
23
38
|
|
|
24
|
-
|
|
39
|
+
**With it**, KeepGreen opens your app, sees which important flows have no test, writes one for
|
|
40
|
+
each and opens **one pull request** with only the tests that passed every run. When the UI
|
|
41
|
+
changes, it fixes the broken test and proves the fix. When the app is really broken, it tells you
|
|
42
|
+
it's an app bug instead of "fixing" the test.
|
|
43
|
+
|
|
44
|
+
> **Real run, real cost.** On our [demo shop](https://github.com/xsignon-secure/autoheal-demo),
|
|
45
|
+
> one KeepGreen run inspected 3 pages, planned 2 untested flows and opened
|
|
46
|
+
> [a PR with 2 new tests](https://github.com/xsignon-secure/autoheal-demo/pull/9). Each passed
|
|
47
|
+
> 3 runs in a row and the anti-cheat guard. Total AI spend: **about $0.04**.
|
|
48
|
+
|
|
49
|
+
## ✨ What you get
|
|
50
|
+
|
|
51
|
+
| Recipe | What it does | Command |
|
|
52
|
+
| --- | --- | --- |
|
|
53
|
+
| 🔍 **Explore** | Looks at your app, picks the most important user flows that have **no test yet**, and writes a test for each. A test is kept only if it makes real assertions and passes every run (5 by default). | `npx keepgreen explore` |
|
|
54
|
+
| 🎯 **Explore one flow** | Skip the planning: name the flow, get the test. | `npx keepgreen explore --flow "..."` |
|
|
55
|
+
| 🩹 **Heal** | Runs your tests, finds what broke, fixes it and proves the fix. App bugs are reported, not "fixed". | `npx keepgreen heal` (local) · AutoHeal workflow (CI) |
|
|
56
|
+
|
|
57
|
+
- **Anti-cheat guard.** Tests without real assertions, or with skips, faked network answers,
|
|
58
|
+
fixed waits, forced clicks or retries, are thrown away.
|
|
59
|
+
- **Proven, not hoped.** A new test must pass `runs` times in a row before it's kept.
|
|
60
|
+
- **Your style.** Tests follow your project's imports, fixtures and locator style.
|
|
61
|
+
- **One PR, only new files.** In CI, the publish step accepts nothing but new test files.
|
|
62
|
+
- **One spend cap.** `max-usd` covers planning plus every flow. OpenRouter prices are looked up
|
|
63
|
+
for you.
|
|
64
|
+
- **Works with** Playwright Test and pytest-playwright. Healing also covers Cypress and
|
|
65
|
+
WebdriverIO.
|
|
66
|
+
|
|
67
|
+
KeepGreen joins two XSignOn projects into one agent:
|
|
68
|
+
[playwright-e2e-mcp](https://github.com/xsignon-secure/E2E) is the toolbox (opens pages, finds
|
|
69
|
+
stable locators, runs tests, reads failures) and [AutoHeal](https://github.com/xsignon-secure/AutoHeal-AI)
|
|
70
|
+
is the guarded fixer and test writer.
|
|
71
|
+
|
|
72
|
+
## ⚡ Quick start
|
|
25
73
|
|
|
26
74
|
```bash
|
|
27
75
|
npm install -D keepgreen # or use npx keepgreen ... without installing
|
|
@@ -30,63 +78,95 @@ npx keepgreen init # writes .keepgreen.yml + workflows, check
|
|
|
30
78
|
npx keepgreen explore --url http://localhost:3000
|
|
31
79
|
```
|
|
32
80
|
|
|
33
|
-
Explore prints a table of the flows it tried and which tests it kept. New files are named
|
|
34
|
-
`tests/keepgreen
|
|
35
|
-
|
|
36
|
-
Try it without writing anything first:
|
|
81
|
+
Explore prints a table of the flows it tried and which tests it kept. New files are named after
|
|
82
|
+
the flow, such as `tests/keepgreen-adds-coffee-mug-cart-count-shows.spec.ts`. Review them with
|
|
83
|
+
`git diff` and commit the ones you like.
|
|
37
84
|
|
|
38
85
|
```bash
|
|
39
|
-
|
|
40
|
-
|
|
86
|
+
# Plan only: show the flows it would test, write nothing
|
|
87
|
+
npx keepgreen explore --url http://localhost:3000 --dry-run
|
|
41
88
|
|
|
42
|
-
|
|
89
|
+
# Test the flows you name (repeat --flow for more)
|
|
90
|
+
npx keepgreen explore --url http://localhost:3000 \
|
|
91
|
+
--flow "A shopper adds the coffee mug to the cart and the cart count shows 1"
|
|
43
92
|
|
|
44
|
-
|
|
93
|
+
# Let KeepGreen start your app
|
|
45
94
|
npx keepgreen explore --start-command "npm run dev" --start-url http://localhost:3000
|
|
46
|
-
```
|
|
47
95
|
|
|
48
|
-
|
|
96
|
+
# A deployed staging or preview app works too (use a test environment, not production)
|
|
97
|
+
npx keepgreen explore --url https://staging.example.com
|
|
49
98
|
|
|
50
|
-
|
|
51
|
-
npx keepgreen heal
|
|
99
|
+
# Fix broken tests; changes stay in your working tree for review
|
|
100
|
+
npx keepgreen heal
|
|
52
101
|
```
|
|
53
102
|
|
|
54
|
-
##
|
|
103
|
+
## 🤖 GitHub Actions
|
|
55
104
|
|
|
56
105
|
`npx keepgreen init` writes two workflows:
|
|
57
106
|
|
|
58
107
|
- **`.github/workflows/keepgreen-explore.yml`** runs from *Actions > KeepGreen explore > Run
|
|
59
108
|
workflow*, or weekly if you uncomment the schedule. It opens **one PR** with the new tests that
|
|
60
|
-
passed.
|
|
61
|
-
|
|
109
|
+
passed. The explore job runs the AI-written tests with a read-only token. The publish job
|
|
110
|
+
accepts the result only if it just adds test files, then opens the PR. A scheduled run skips
|
|
111
|
+
itself while an earlier KeepGreen PR is still open.
|
|
62
112
|
- **`.github/workflows/autoheal.yml`** is written by AutoHeal's own `init`. It runs after your
|
|
63
113
|
test workflow fails and opens a fix PR.
|
|
64
114
|
|
|
65
115
|
Then:
|
|
66
116
|
|
|
67
117
|
1. Add `ANTHROPIC_API_KEY` as a repository secret. For OpenAI, add `OPENAI_API_KEY` and a
|
|
68
|
-
repository variable `AUTOHEAL_MODEL`.
|
|
118
|
+
repository variable `AUTOHEAL_MODEL`. For OpenRouter, see [below](#openrouter-or-any-openai-compatible-endpoint).
|
|
69
119
|
2. Go to *Settings > Actions > General > Workflow permissions* and tick "Allow GitHub Actions to
|
|
70
120
|
create and approve pull requests".
|
|
71
121
|
3. Make the explore job's install steps match your test workflow (Node or Python, browsers,
|
|
72
122
|
services).
|
|
123
|
+
4. Optional: add a fine-grained token (this repo only; Contents and Pull requests: read and
|
|
124
|
+
write) as the secret `KEEPGREEN_PR_TOKEN`. GitHub runs no CI on PRs opened with the built-in
|
|
125
|
+
token; with this one, your checks run on KeepGreen's PRs.
|
|
73
126
|
|
|
74
|
-
|
|
127
|
+
Or use the action directly:
|
|
75
128
|
|
|
76
129
|
```yaml
|
|
77
|
-
- uses: xsignon-secure/keepgreen@v0.
|
|
130
|
+
- uses: xsignon-secure/keepgreen@v0.2.1
|
|
78
131
|
with:
|
|
79
132
|
url: http://localhost:3000
|
|
80
133
|
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
134
|
+
# flows: | # optional: skip planning
|
|
135
|
+
# A visitor logs in and sees the dashboard
|
|
81
136
|
# leaves keepgreen-out/ (report.md, summary.json, new-tests.patch); output `written` = tests kept
|
|
82
137
|
```
|
|
83
138
|
|
|
84
|
-
##
|
|
139
|
+
## 🔍 How explore works
|
|
140
|
+
|
|
141
|
+
```mermaid
|
|
142
|
+
flowchart LR
|
|
143
|
+
A["👀 Look<br/>inspect your pages"] --> B["🧭 Plan<br/>flows with no test yet"]
|
|
144
|
+
B --> C["✍️ Write<br/>one test per flow, your style"]
|
|
145
|
+
C --> D{"🛡️ Prove<br/>guard + N green runs"}
|
|
146
|
+
D -->|passes| E["✅ kept, in one PR"]
|
|
147
|
+
D -->|fails or cheats| F["🗑️ thrown away"]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
1. **Look.** It opens your app's start page and every path in `pages:` with playwright-e2e-mcp's
|
|
151
|
+
`inspect-page`, which lists the interactive elements and their locators.
|
|
152
|
+
2. **Plan.** It reads the titles of your existing tests and asks your AI for the most important
|
|
153
|
+
user flows that have no test yet. Flows that pay money, send email or delete data are skipped.
|
|
154
|
+
With `--flow`, this step is skipped.
|
|
155
|
+
3. **Write.** For each flow, AutoHeal's `cover` explores the pages, checks every locator, and
|
|
156
|
+
writes one test in your project's own style.
|
|
157
|
+
4. **Prove.** The new-test guard rejects tests that cannot fail, or that use skips, faked network
|
|
158
|
+
answers, fixed waits, forced clicks or retries. The test must then pass every run in a row.
|
|
159
|
+
Anything less is thrown away.
|
|
160
|
+
|
|
161
|
+
One `max-usd` cap covers the whole run. Each flow gets an even share of what is left, so money one
|
|
162
|
+
flow saves goes to the next.
|
|
163
|
+
|
|
164
|
+
## ⚙️ Settings
|
|
85
165
|
|
|
86
166
|
`.keepgreen.yml` at the repo root. Command-line flags override it.
|
|
87
167
|
|
|
88
168
|
```yaml
|
|
89
|
-
url: http://localhost:3000 # the running app, or:
|
|
169
|
+
url: http://localhost:3000 # the running app (local, staging or preview), or:
|
|
90
170
|
# start-command: npm run dev
|
|
91
171
|
# start-url: http://localhost:3000
|
|
92
172
|
pages: # extra pages to look at when choosing flows
|
|
@@ -106,20 +186,22 @@ AI settings use AutoHeal's variables:
|
|
|
106
186
|
| `OPENAI_API_KEY` + `AUTOHEAL_MODEL` | Use OpenAI |
|
|
107
187
|
| `AUTOHEAL_BASE_URL` + `AUTOHEAL_MODEL` (+ `AUTOHEAL_API_KEY`) | Any OpenAI-compatible endpoint: OpenRouter, or Ollama at `http://localhost:11434/v1` |
|
|
108
188
|
| `AUTOHEAL_EFFORT` | Anthropic effort: `low` … `max` (default `medium`) |
|
|
109
|
-
| `AUTOHEAL_PRICE_IN` / `AUTOHEAL_PRICE_OUT` | USD per 1M tokens, for models without a
|
|
189
|
+
| `AUTOHEAL_PRICE_IN` / `AUTOHEAL_PRICE_OUT` | USD per 1M tokens, for models without a known price |
|
|
110
190
|
|
|
111
191
|
### OpenRouter (or any OpenAI-compatible endpoint)
|
|
112
192
|
|
|
113
193
|
```bash
|
|
114
194
|
export AUTOHEAL_BASE_URL=https://openrouter.ai/api/v1
|
|
115
195
|
export AUTOHEAL_API_KEY=sk-or-... # your OpenRouter key; give it a credit limit
|
|
116
|
-
export AUTOHEAL_MODEL
|
|
117
|
-
export AUTOHEAL_PRICE_IN=3 AUTOHEAL_PRICE_OUT=15 # USD per 1M tokens of that model, so max-usd is enforced
|
|
196
|
+
export AUTOHEAL_MODEL=anthropic/claude-sonnet-5.5
|
|
118
197
|
npx keepgreen explore --url http://localhost:3000
|
|
119
198
|
```
|
|
120
199
|
|
|
121
|
-
|
|
122
|
-
|
|
200
|
+
KeepGreen looks up the model's price in OpenRouter's public model list, so `max-usd` is enforced.
|
|
201
|
+
For other endpoints, set `AUTOHEAL_PRICE_IN` and `AUTOHEAL_PRICE_OUT`.
|
|
202
|
+
|
|
203
|
+
In the Action: `base-url: https://openrouter.ai/api/v1`, `api-key: ${{ secrets.OPENROUTER_API_KEY }}`
|
|
204
|
+
and `model: ...`.
|
|
123
205
|
|
|
124
206
|
### Playwright `webServer`
|
|
125
207
|
|
|
@@ -130,35 +212,21 @@ If your `playwright.config` starts the app with `webServer`, and KeepGreen start
|
|
|
130
212
|
webServer: { command: 'npm run start', url: 'http://127.0.0.1:3000/', reuseExistingServer: !process.env.CI || !!process.env.KEEPGREEN },
|
|
131
213
|
```
|
|
132
214
|
|
|
133
|
-
##
|
|
134
|
-
|
|
135
|
-
1. **Look.** It opens your app's start page and every path in `pages:` with playwright-e2e-mcp's
|
|
136
|
-
`inspect-page`, which lists the interactive elements and their locators.
|
|
137
|
-
2. **Plan.** It reads the titles of your existing tests and asks your AI for the most important
|
|
138
|
-
user flows that have no test yet. Flows that pay money, send email or delete data are skipped.
|
|
139
|
-
3. **Write.** For each flow, AutoHeal's `cover` explores the pages, checks every locator, and
|
|
140
|
-
writes one test in your project's own style.
|
|
141
|
-
4. **Prove.** The new-test guard rejects tests that cannot fail, or that use skips, faked network
|
|
142
|
-
answers, fixed waits, forced clicks or retries. The test must then pass every run in a row.
|
|
143
|
-
Anything less is thrown away.
|
|
144
|
-
|
|
145
|
-
One `max-usd` cap covers the whole run. Each flow gets an even share of what is left, so money one
|
|
146
|
-
flow saves goes to the next.
|
|
147
|
-
|
|
148
|
-
## All commands
|
|
215
|
+
## 📖 All commands
|
|
149
216
|
|
|
150
217
|
```
|
|
151
218
|
keepgreen init [--force] [--dry-run]
|
|
152
219
|
keepgreen doctor
|
|
153
220
|
keepgreen explore [--url <app>] [--start-command <cmd> --start-url <url>] [--pages /a,/b]
|
|
154
|
-
[--max-flows 3] [--max-usd 3] [--runs 5]
|
|
221
|
+
[--flow "<sentence>" ...] [--max-flows 3] [--max-usd 3] [--runs 5]
|
|
222
|
+
[--dry-run] [--out <dir>]
|
|
155
223
|
keepgreen heal [AutoHeal fix options]
|
|
156
224
|
keepgreen autoheal <command> [...] # any AutoHeal command: learn, metrics, dashboard, ...
|
|
157
225
|
keepgreen check-patch <file> # CI publish step
|
|
158
226
|
keepgreen --version
|
|
159
227
|
```
|
|
160
228
|
|
|
161
|
-
## Self-host bundle (optional)
|
|
229
|
+
## 🏠 Self-host bundle (optional)
|
|
162
230
|
|
|
163
231
|
KeepGreen needs no server. If you want **test history across all CI runs** (flaky ranking, the
|
|
164
232
|
commit where a test went bad) and **AutoHeal's dashboard** (fixes, blocked cheats, AI spend),
|
|
@@ -168,12 +236,15 @@ commit where a test went bad) and **AutoHeal's dashboard** (fixes, blocked cheat
|
|
|
168
236
|
cd selfhost && sh make-env.sh your-org/your-repo && docker compose up -d --build
|
|
169
237
|
```
|
|
170
238
|
|
|
171
|
-
## Security
|
|
239
|
+
## 🔒 Security
|
|
172
240
|
|
|
173
241
|
See [SECURITY.md](SECURITY.md). In short: your key goes only to your AI provider, AI-written tests
|
|
174
242
|
never run with a write token or your AI key, the publish step only accepts new test files, and
|
|
175
|
-
every change arrives as a PR for a person to review.
|
|
243
|
+
every change arrives as a PR for a person to review. Forks never get your secrets.
|
|
244
|
+
|
|
245
|
+
## 💚 Free forever
|
|
176
246
|
|
|
177
|
-
|
|
247
|
+
MIT licensed. Free for any use, with no paid tier, no account and no telemetry. Releases are
|
|
248
|
+
published from CI with [npm provenance](https://www.npmjs.com/package/keepgreen#provenance).
|
|
178
249
|
|
|
179
|
-
|
|
250
|
+
Issues and pull requests are welcome. If KeepGreen helps you, ⭐ the repo so others can find it.
|
package/SECURITY.md
CHANGED
|
@@ -24,7 +24,13 @@ every prompt marks such text as data.
|
|
|
24
24
|
one of `runs` runs in a row. The scans are pattern based, so every test still arrives as a PR
|
|
25
25
|
for a person to review.
|
|
26
26
|
- **Pages stay on your app.** Planning only opens the app URL and the paths you list in
|
|
27
|
-
`pages:`; `cover` only opens pages on the same origin.
|
|
27
|
+
`pages:`; `cover` only opens pages on the same origin. An app KeepGreen starts must be on the
|
|
28
|
+
same machine; an app that is already running (`url:`) may be a staging or preview deployment.
|
|
29
|
+
Point KeepGreen at a test environment, never production: the tests it writes really click.
|
|
30
|
+
- **No pings from AI text.** `@name` in AI-written flow text is defused before it goes into a PR.
|
|
31
|
+
- **Optional PR token.** `KEEPGREEN_PR_TOKEN` (so your CI runs on KeepGreen's PRs) is only given
|
|
32
|
+
to the publish job, which never runs your project's code. Make it fine-grained, for this repo
|
|
33
|
+
only, with Contents and Pull requests access.
|
|
28
34
|
- **Spend cap.** One `max-usd` limit covers a whole explore run (planning plus every flow).
|
|
29
35
|
|
|
30
36
|
## Your part
|
package/action.yml
CHANGED
|
@@ -23,6 +23,10 @@ inputs:
|
|
|
23
23
|
description: Address to wait for after start-command
|
|
24
24
|
required: false
|
|
25
25
|
default: ""
|
|
26
|
+
flows:
|
|
27
|
+
description: Flows to write tests for, one sentence per line (skips planning; blank = let the AI pick)
|
|
28
|
+
required: false
|
|
29
|
+
default: ""
|
|
26
30
|
max-flows:
|
|
27
31
|
description: New tests to try (1-10; blank = .keepgreen.yml or 3)
|
|
28
32
|
required: false
|
|
@@ -70,7 +74,7 @@ inputs:
|
|
|
70
74
|
version:
|
|
71
75
|
description: keepgreen version from npm
|
|
72
76
|
required: false
|
|
73
|
-
default: "0.
|
|
77
|
+
default: "0.2.1"
|
|
74
78
|
|
|
75
79
|
outputs:
|
|
76
80
|
written:
|
|
@@ -98,6 +102,7 @@ runs:
|
|
|
98
102
|
KG_MAX_FLOWS: ${{ inputs.max-flows }}
|
|
99
103
|
KG_MAX_USD: ${{ inputs.max-usd }}
|
|
100
104
|
KG_RUNS: ${{ inputs.runs }}
|
|
105
|
+
KG_FLOWS: ${{ inputs.flows }}
|
|
101
106
|
OUT: ${{ github.workspace }}/keepgreen-out
|
|
102
107
|
run: |
|
|
103
108
|
[ -n "$ANTHROPIC_API_KEY" ] || unset ANTHROPIC_API_KEY
|
|
@@ -117,6 +122,10 @@ runs:
|
|
|
117
122
|
[ -n "$KG_MAX_FLOWS" ] && args+=(--max-flows "$KG_MAX_FLOWS")
|
|
118
123
|
[ -n "$KG_MAX_USD" ] && args+=(--max-usd "$KG_MAX_USD")
|
|
119
124
|
[ -n "$KG_RUNS" ] && args+=(--runs "$KG_RUNS")
|
|
125
|
+
while IFS= read -r line; do
|
|
126
|
+
line="${line#"${line%%[![:space:]]*}"}"
|
|
127
|
+
[ -n "$line" ] && args+=(--flow "$line")
|
|
128
|
+
done <<< "$KG_FLOWS"
|
|
120
129
|
set +e
|
|
121
130
|
npx -y "keepgreen@$KG_VERSION" "${args[@]}"
|
|
122
131
|
code=$?
|
package/dist/cli.d.ts
CHANGED
|
@@ -9,4 +9,6 @@
|
|
|
9
9
|
export declare const USAGE: string;
|
|
10
10
|
/** Path of AutoHeal's CLI inside the installed xsignon-autoheal package. */
|
|
11
11
|
export declare function autohealCli(): string;
|
|
12
|
+
/** A running app to explore: any http(s) address without a user name or password in it. */
|
|
13
|
+
export declare function checkRemoteUrl(url: string): URL;
|
|
12
14
|
export declare function main(argv: string[]): Promise<number>;
|
package/dist/cli.js
CHANGED
|
@@ -18,6 +18,7 @@ import { existingTitles, explore, exploreReport } from './explore.js';
|
|
|
18
18
|
import { init } from './init.js';
|
|
19
19
|
import { newFilesPatch } from './newfiles.js';
|
|
20
20
|
import { checkPatch } from './patch.js';
|
|
21
|
+
import { lookupPrice } from './price.js';
|
|
21
22
|
import { VERSION } from './version.js';
|
|
22
23
|
export const USAGE = `keepgreen ${VERSION}: free, self-hosted AI test agent. It writes new end-to-end tests
|
|
23
24
|
for your app and fixes the ones that break, with your own AI key (Anthropic, OpenAI or any
|
|
@@ -28,9 +29,11 @@ OpenAI-compatible endpoint). Built on playwright-e2e-mcp and AutoHeal. MIT, no a
|
|
|
28
29
|
keepgreen doctor
|
|
29
30
|
check this project and machine
|
|
30
31
|
keepgreen explore [--url <app>] [--start-command <cmd> --start-url <url>] [--pages /a,/b]
|
|
31
|
-
[--max-flows 3] [--max-usd 3] [--runs 5]
|
|
32
|
+
[--flow "<sentence>" ...] [--max-flows 3] [--max-usd 3] [--runs 5]
|
|
33
|
+
[--dry-run] [--out <dir>]
|
|
32
34
|
find important user flows with no test yet and write a test for each; a test is kept
|
|
33
|
-
only if it makes real assertions and passes --runs times in a row
|
|
35
|
+
only if it makes real assertions and passes --runs times in a row. --flow skips the
|
|
36
|
+
planning and writes a test for the flow you name (repeat it for more)
|
|
34
37
|
keepgreen heal [AutoHeal fix options]
|
|
35
38
|
run your tests, fix what broke, leave the changes for you to review
|
|
36
39
|
keepgreen autoheal <command> [...]
|
|
@@ -84,12 +87,13 @@ async function cmdExplore(argv) {
|
|
|
84
87
|
framework: { type: 'string' },
|
|
85
88
|
project: { type: 'string' },
|
|
86
89
|
out: { type: 'string' },
|
|
90
|
+
flow: { type: 'string', multiple: true },
|
|
87
91
|
'dry-run': { type: 'boolean' },
|
|
88
92
|
},
|
|
89
93
|
strict: true,
|
|
90
94
|
});
|
|
91
95
|
const projectRoot = path.resolve(values.project ?? '.');
|
|
92
|
-
const { project: _p, out: _o, 'dry-run': _d, ...flags } = values;
|
|
96
|
+
const { project: _p, out: _o, 'dry-run': _d, flow: _f, ...flags } = values;
|
|
93
97
|
const config = resolveConfig(await loadConfigFile(projectRoot), flags);
|
|
94
98
|
const env = process.env;
|
|
95
99
|
// Lets playwright.config tell a KeepGreen run apart, e.g.
|
|
@@ -114,7 +118,15 @@ async function cmdExplore(argv) {
|
|
|
114
118
|
}
|
|
115
119
|
if (!appUrl)
|
|
116
120
|
throw new ConfigError('Tell KeepGreen where your app runs: --url http://localhost:3000, or url: in .keepgreen.yml (or start-command + start-url).');
|
|
117
|
-
|
|
121
|
+
// An app KeepGreen starts must be on this machine (startApp checks it). An app that is
|
|
122
|
+
// already running may be anywhere, such as a staging or preview deployment.
|
|
123
|
+
if (app)
|
|
124
|
+
checkAppUrl(appUrl);
|
|
125
|
+
else
|
|
126
|
+
checkRemoteUrl(appUrl);
|
|
127
|
+
const price = priceFor(provider.model, env) ?? (await lookupPrice(provider.model, env.AUTOHEAL_BASE_URL, { log }));
|
|
128
|
+
if (!price)
|
|
129
|
+
log(`No price is known for ${provider.model}, so max-usd cannot be enforced (only a token cap). Set AUTOHEAL_PRICE_IN and AUTOHEAL_PRICE_OUT (USD per 1M tokens).`);
|
|
118
130
|
log(`KeepGreen ${VERSION}: exploring ${appUrl} (${framework}, ${provider.name} ${provider.model}, limit $${config.maxUsd})`);
|
|
119
131
|
engine = await McpTools.start(projectRoot);
|
|
120
132
|
runner = framework === 'cypress' ? new CypressTools(projectRoot, { log }) : framework === 'webdriverio' ? new WdioTools(projectRoot, { log }) : engine;
|
|
@@ -129,11 +141,12 @@ async function cmdExplore(argv) {
|
|
|
129
141
|
maxFlows: config.maxFlows,
|
|
130
142
|
maxUsd: config.maxUsd,
|
|
131
143
|
runs: config.runs,
|
|
132
|
-
price
|
|
144
|
+
price,
|
|
133
145
|
framework,
|
|
134
146
|
cover,
|
|
135
147
|
log,
|
|
136
148
|
dryRun: values['dry-run'] === true,
|
|
149
|
+
...(values.flow?.length ? { flows: values.flow } : {}),
|
|
137
150
|
});
|
|
138
151
|
const report = exploreReport(result, config.runs);
|
|
139
152
|
process.stdout.write(`\n${report}\n`);
|
|
@@ -142,7 +155,14 @@ async function cmdExplore(argv) {
|
|
|
142
155
|
const out = path.resolve(values.out);
|
|
143
156
|
await mkdir(out, { recursive: true });
|
|
144
157
|
await writeFile(path.join(out, 'report.md'), `${report}\n`);
|
|
145
|
-
await writeFile(path.join(out, 'summary.json'), `${JSON.stringify({
|
|
158
|
+
await writeFile(path.join(out, 'summary.json'), `${JSON.stringify({
|
|
159
|
+
version: VERSION,
|
|
160
|
+
written,
|
|
161
|
+
flows: result.flows,
|
|
162
|
+
results: result.results.map(({ flow, result: r }) => ({ flow: flow.flow, status: r.status, file: r.file, explanation: r.explanation })),
|
|
163
|
+
usd: result.usd,
|
|
164
|
+
priced: result.priced,
|
|
165
|
+
}, null, 2)}\n`);
|
|
146
166
|
await writeFile(path.join(out, 'new-tests.patch'), await newFilesPatch(projectRoot, written));
|
|
147
167
|
log(`Wrote ${path.relative(process.cwd(), out) || '.'}/report.md, summary.json and new-tests.patch`);
|
|
148
168
|
}
|
|
@@ -157,6 +177,21 @@ async function cmdExplore(argv) {
|
|
|
157
177
|
await app?.stop().catch(() => undefined);
|
|
158
178
|
}
|
|
159
179
|
}
|
|
180
|
+
/** A running app to explore: any http(s) address without a user name or password in it. */
|
|
181
|
+
export function checkRemoteUrl(url) {
|
|
182
|
+
let u;
|
|
183
|
+
try {
|
|
184
|
+
u = new URL(url);
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
throw new ConfigError(`url is not a URL: ${url}`);
|
|
188
|
+
}
|
|
189
|
+
if (u.protocol !== 'http:' && u.protocol !== 'https:')
|
|
190
|
+
throw new ConfigError('url must start with http:// or https://');
|
|
191
|
+
if (u.username || u.password)
|
|
192
|
+
throw new ConfigError('Do not put a user name or password in url.');
|
|
193
|
+
return u;
|
|
194
|
+
}
|
|
160
195
|
async function cmdInit(argv) {
|
|
161
196
|
const { values } = parseArgs({ args: argv, options: { project: { type: 'string' }, force: { type: 'boolean' }, 'dry-run': { type: 'boolean' } }, strict: true });
|
|
162
197
|
const root = path.resolve(values.project ?? '.');
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/explore.d.ts
CHANGED
|
@@ -57,10 +57,18 @@ export interface ExploreOptions extends Omit<PlanOptions, 'budget'> {
|
|
|
57
57
|
cover: (options: CoverOptions) => Promise<CoverResult>;
|
|
58
58
|
/** Plan only, write nothing. */
|
|
59
59
|
dryRun?: boolean;
|
|
60
|
+
/** Flows named by the user: skip planning and write a test for each. */
|
|
61
|
+
flows?: string[];
|
|
60
62
|
}
|
|
61
63
|
/** Plan, then write one test per flow. The spend cap covers the whole run. */
|
|
62
64
|
export declare function explore(options: ExploreOptions): Promise<ExploreResult>;
|
|
63
65
|
/** tests/keepgreen-<words>.spec.ts (pytest: tests/test_keepgreen_<words>.py), so KeepGreen's tests are easy to spot. */
|
|
64
66
|
export declare function testFileFor(flow: string, framework: NonNullable<CoverOptions['framework']>): string;
|
|
67
|
+
/**
|
|
68
|
+
* testFileFor, plus -2, -3 ... when that name is already used by a file on
|
|
69
|
+
* disk or by an earlier flow of this run. AutoHeal's cover refuses to write
|
|
70
|
+
* over an existing file, so two flows with the same name used to lose one.
|
|
71
|
+
*/
|
|
72
|
+
export declare function uniqueTestFile(flow: string, framework: NonNullable<CoverOptions['framework']>, root: string, taken: Set<string>): Promise<string>;
|
|
65
73
|
/** Markdown summary for the terminal, the job summary and the PR body. */
|
|
66
74
|
export declare function exploreReport(result: ExploreResult, runs: number): string;
|
package/dist/explore.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*
|
|
11
11
|
* The AI key is the user's own. Nothing here talks to an XSignOn server.
|
|
12
12
|
*/
|
|
13
|
-
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
13
|
+
import { access, readdir, readFile, stat } from 'node:fs/promises';
|
|
14
14
|
import path from 'node:path';
|
|
15
15
|
import { Budget, ProviderError, coverFile } from 'xsignon-autoheal';
|
|
16
16
|
const PLAN_PROMPT = `You are KeepGreen, a senior test engineer planning end-to-end test coverage for a web app.
|
|
@@ -158,9 +158,13 @@ export async function existingTitles(root) {
|
|
|
158
158
|
export async function explore(options) {
|
|
159
159
|
const log = options.log ?? (() => undefined);
|
|
160
160
|
const planBudget = new Budget({ maxUsd: Math.min(0.5, options.maxUsd * 0.15), maxTokens: 400_000, maxSteps: 3 }, options.price);
|
|
161
|
-
const
|
|
161
|
+
const given = options.flows?.length ? cleanFlows(options.flows.map((flow) => ({ flow, why: 'named by you' })), options.maxFlows) : null;
|
|
162
|
+
if (options.flows?.length && !given?.length)
|
|
163
|
+
throw new Error('Each --flow must be one sentence of 10 to 500 characters.');
|
|
164
|
+
const flows = given ?? (await planFlows({ ...options, budget: planBudget }));
|
|
162
165
|
let spent = planBudget.snapshot().usd;
|
|
163
|
-
let priced = planBudget.snapshot().priced;
|
|
166
|
+
let priced = given ? options.price !== null : planBudget.snapshot().priced;
|
|
167
|
+
const taken = new Set();
|
|
164
168
|
const results = [];
|
|
165
169
|
if (!flows.length)
|
|
166
170
|
log('The AI found no untested flows to add.');
|
|
@@ -184,7 +188,7 @@ export async function explore(options) {
|
|
|
184
188
|
result = await options.cover({
|
|
185
189
|
projectRoot: options.projectRoot,
|
|
186
190
|
flow: flow.flow,
|
|
187
|
-
file:
|
|
191
|
+
file: await uniqueTestFile(flow.flow, options.framework, options.projectRoot, taken),
|
|
188
192
|
appUrl: options.appUrl,
|
|
189
193
|
provider: options.provider,
|
|
190
194
|
budget,
|
|
@@ -205,12 +209,39 @@ export async function explore(options) {
|
|
|
205
209
|
}
|
|
206
210
|
return { flows, results, usd: spent, priced };
|
|
207
211
|
}
|
|
212
|
+
// Words that say nothing about the flow. Most flows start "A visitor opens the
|
|
213
|
+
// home page...", so without this every file name would start the same way.
|
|
214
|
+
const FILLER = new Set(['a', 'an', 'the', 'and', 'then', 'or', 'to', 'of', 'on', 'in', 'at', 'from', 'with', 'where', 'that', 'is', 'are', 'it', 'its', 'their', 'his', 'her', 'they', 'user', 'users', 'visitor', 'visitors', 'shopper', 'customer', 'someone', 'person', 'sees', 'see', 'can', 'least', 'for', 'page']);
|
|
208
215
|
/** tests/keepgreen-<words>.spec.ts (pytest: tests/test_keepgreen_<words>.py), so KeepGreen's tests are easy to spot. */
|
|
209
216
|
export function testFileFor(flow, framework) {
|
|
210
|
-
|
|
217
|
+
const words = flow.toLowerCase().replace(/[^a-z0-9]+/g, ' ').trim().split(' ').filter(Boolean);
|
|
218
|
+
const meaningful = [...new Set(words.filter((w) => !FILLER.has(w)))];
|
|
219
|
+
const named = (meaningful.length >= 2 ? meaningful : words).join(' ');
|
|
220
|
+
return coverFile(named || flow, framework).replace(/autoheal-/, 'keepgreen-').replace(/test_autoheal_/, 'test_keepgreen_');
|
|
211
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* testFileFor, plus -2, -3 ... when that name is already used by a file on
|
|
224
|
+
* disk or by an earlier flow of this run. AutoHeal's cover refuses to write
|
|
225
|
+
* over an existing file, so two flows with the same name used to lose one.
|
|
226
|
+
*/
|
|
227
|
+
export async function uniqueTestFile(flow, framework, root, taken) {
|
|
228
|
+
const base = testFileFor(flow, framework);
|
|
229
|
+
const dot = base.search(/(?:\.spec|\.cy|\.e2e)?\.[a-z]+$/);
|
|
230
|
+
for (let n = 1; n < 100; n++) {
|
|
231
|
+
const file = n === 1 ? base : `${base.slice(0, dot)}${framework === 'pytest' ? '_' : '-'}${n}${base.slice(dot)}`;
|
|
232
|
+
if (taken.has(file))
|
|
233
|
+
continue;
|
|
234
|
+
const onDisk = await access(path.join(root, file)).then(() => true, () => false);
|
|
235
|
+
if (onDisk)
|
|
236
|
+
continue;
|
|
237
|
+
taken.add(file);
|
|
238
|
+
return file;
|
|
239
|
+
}
|
|
240
|
+
throw new Error(`Too many test files named like ${base}.`);
|
|
241
|
+
}
|
|
242
|
+
/** One table cell. AI text goes into a PR body, so @mentions are defused (no one gets pinged). */
|
|
212
243
|
function cell(text) {
|
|
213
|
-
return text.replace(/\|/g, '\\|').replace(/\s+/g, ' ').trim();
|
|
244
|
+
return text.replace(/\|/g, '\\|').replace(/\s+/g, ' ').replace(/@(?=[A-Za-z0-9_-])/g, '@\u200b').trim();
|
|
214
245
|
}
|
|
215
246
|
/** Markdown summary for the terminal, the job summary and the PR body. */
|
|
216
247
|
export function exploreReport(result, runs) {
|
|
@@ -231,7 +262,7 @@ export function exploreReport(result, runs) {
|
|
|
231
262
|
lines.push('');
|
|
232
263
|
}
|
|
233
264
|
else if (result.flows.length) {
|
|
234
|
-
lines.push('Planned flows (dry run, nothing written):', '', ...result.flows.map((f, i) => `${i + 1}. ${f.flow} (${f.why})`), '');
|
|
265
|
+
lines.push('Planned flows (dry run, nothing written):', '', ...result.flows.map((f, i) => `${i + 1}. ${cell(f.flow)} (${cell(f.why)})`), '');
|
|
235
266
|
}
|
|
236
267
|
lines.push(`AI spend: ${result.priced ? `about $${result.usd.toFixed(2)}` : 'unknown (model price not listed; set AUTOHEAL_PRICE_IN / AUTOHEAL_PRICE_OUT)'}, billed by your own AI provider.`);
|
|
237
268
|
lines.push('', 'Review each test like any other change before you merge it.');
|
package/dist/explore.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explore.js","sourceRoot":"","sources":["../src/explore.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"explore.js","sourceRoot":"","sources":["../src/explore.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { explore, planFlows, cleanFlows, existingTitles, listTestFiles, exploreReport, testFileFor, type Flow, type ExploreOptions, type ExploreResult, type PlanOptions } from './explore.js';
|
|
1
|
+
export { explore, planFlows, cleanFlows, existingTitles, listTestFiles, exploreReport, testFileFor, uniqueTestFile, type Flow, type ExploreOptions, type ExploreResult, type PlanOptions } from './explore.js';
|
|
2
2
|
export { parseConfig, resolveConfig, loadConfigFile, CONFIG_FILE, DEFAULTS, ConfigFileError, type KeepGreenConfig } from './config.js';
|
|
3
3
|
export { checkPatch, type PatchCheck } from './patch.js';
|
|
4
4
|
export { addFilePatch, newFilesPatch } from './newfiles.js';
|
|
5
5
|
export { init, type InitResult } from './init.js';
|
|
6
|
+
export { lookupPrice } from './price.js';
|
|
6
7
|
export { VERSION } from './version.js';
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
export { explore, planFlows, cleanFlows, existingTitles, listTestFiles, exploreReport, testFileFor } from './explore.js';
|
|
1
|
+
export { explore, planFlows, cleanFlows, existingTitles, listTestFiles, exploreReport, testFileFor, uniqueTestFile } from './explore.js';
|
|
2
2
|
export { parseConfig, resolveConfig, loadConfigFile, CONFIG_FILE, DEFAULTS, ConfigFileError } from './config.js';
|
|
3
3
|
export { checkPatch } from './patch.js';
|
|
4
4
|
export { addFilePatch, newFilesPatch } from './newfiles.js';
|
|
5
5
|
export { init } from './init.js';
|
|
6
|
+
export { lookupPrice } from './price.js';
|
|
6
7
|
export { VERSION } from './version.js';
|
|
7
8
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAwE,MAAM,cAAc,CAAC;AAC/
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,cAAc,EAAwE,MAAM,cAAc,CAAC;AAC/M,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAwB,MAAM,aAAa,CAAC;AACvI,OAAO,EAAE,UAAU,EAAmB,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,IAAI,EAAmB,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/price.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prices for models AutoHeal's table does not list. OpenRouter publishes the
|
|
3
|
+
* price of every model it serves, so for an OpenRouter base URL KeepGreen
|
|
4
|
+
* looks the model up instead of running with no dollar cap. It is a plain GET
|
|
5
|
+
* of the public model list: no key and nothing about your project goes with it.
|
|
6
|
+
*/
|
|
7
|
+
export interface LookupOptions {
|
|
8
|
+
fetchFn?: typeof fetch;
|
|
9
|
+
log?: (line: string) => void;
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}
|
|
12
|
+
/** USD per 1M tokens [in, out], or null when unknown. */
|
|
13
|
+
export declare function lookupPrice(model: string, baseUrl: string | undefined, options?: LookupOptions): Promise<[number, number] | null>;
|
package/dist/price.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prices for models AutoHeal's table does not list. OpenRouter publishes the
|
|
3
|
+
* price of every model it serves, so for an OpenRouter base URL KeepGreen
|
|
4
|
+
* looks the model up instead of running with no dollar cap. It is a plain GET
|
|
5
|
+
* of the public model list: no key and nothing about your project goes with it.
|
|
6
|
+
*/
|
|
7
|
+
/** USD per 1M tokens [in, out], or null when unknown. */
|
|
8
|
+
export async function lookupPrice(model, baseUrl, options = {}) {
|
|
9
|
+
if (!baseUrl || !model)
|
|
10
|
+
return null;
|
|
11
|
+
let host;
|
|
12
|
+
try {
|
|
13
|
+
host = new URL(baseUrl).hostname;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
if (host !== 'openrouter.ai' && !host.endsWith('.openrouter.ai'))
|
|
19
|
+
return null;
|
|
20
|
+
const fetchFn = options.fetchFn ?? fetch;
|
|
21
|
+
try {
|
|
22
|
+
const res = await fetchFn('https://openrouter.ai/api/v1/models', { signal: AbortSignal.timeout(options.timeoutMs ?? 10_000) });
|
|
23
|
+
if (!res.ok)
|
|
24
|
+
return null;
|
|
25
|
+
const body = (await res.json());
|
|
26
|
+
const entry = body.data?.find((m) => m.id === model);
|
|
27
|
+
const pin = Number(entry?.pricing?.prompt);
|
|
28
|
+
const pout = Number(entry?.pricing?.completion);
|
|
29
|
+
if (!entry || !Number.isFinite(pin) || !Number.isFinite(pout) || pin < 0 || pout < 0)
|
|
30
|
+
return null;
|
|
31
|
+
const price = [round(pin * 1e6), round(pout * 1e6)];
|
|
32
|
+
options.log?.(`OpenRouter price for ${model}: $${price[0]} in / $${price[1]} out per 1M tokens`);
|
|
33
|
+
return price;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function round(n) {
|
|
40
|
+
return Math.round(n * 1e6) / 1e6;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=price.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"price.js","sourceRoot":"","sources":["../src/price.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,yDAAyD;AACzD,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,OAA2B,EAAE,UAAyB,EAAE;IACvG,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACpC,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,KAAK,eAAe,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9E,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,qCAAqC,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC;QAC/H,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA0F,CAAC;QACzH,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;QACrD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAClG,MAAM,KAAK,GAAqB,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,EAAE,CAAC,wBAAwB,KAAK,MAAM,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC;QACjG,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,KAAK,CAAC,CAAS;IACtB,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;AACnC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keepgreen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Free, self-hosted AI test agent: explores your app and writes new Playwright tests, and fixes the ones that break, with your own AI key. Built on playwright-e2e-mcp and AutoHeal.",
|
|
5
5
|
"author": "xsignon-secure (https://github.com/xsignon-secure)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"prepublishOnly": "npm test"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"xsignon-autoheal": "0.
|
|
61
|
+
"xsignon-autoheal": "0.13.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@types/node": "^22.10.0",
|
|
@@ -32,7 +32,7 @@ services:
|
|
|
32
32
|
|
|
33
33
|
dashboard:
|
|
34
34
|
build:
|
|
35
|
-
context: https://github.com/xsignon-secure/AutoHeal-AI.git#v0.
|
|
35
|
+
context: https://github.com/xsignon-secure/AutoHeal-AI.git#v0.13.0
|
|
36
36
|
restart: unless-stopped
|
|
37
37
|
environment:
|
|
38
38
|
AUTOHEAL_DASHBOARD_SECRET: ${AUTOHEAL_DASHBOARD_SECRET:?set AUTOHEAL_DASHBOARD_SECRET in .env}
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
# "Allow GitHub Actions to create and approve pull requests".
|
|
27
27
|
# 5. Run it from Actions > KeepGreen explore > Run workflow, or turn on the
|
|
28
28
|
# weekly schedule below.
|
|
29
|
+
# Optional: GitHub does not start your CI on a PR opened with the built-in
|
|
30
|
+
# token. To get checks on KeepGreen's PRs, add a fine-grained token (this
|
|
31
|
+
# repo only; Contents + Pull requests: read and write) as the secret
|
|
32
|
+
# KEEPGREEN_PR_TOKEN. Only the publish job sees it.
|
|
29
33
|
#
|
|
30
34
|
# Your AI key is in the explore job, where the new tests run. Use a key with
|
|
31
35
|
# a spend limit.
|
|
@@ -41,6 +45,9 @@ on:
|
|
|
41
45
|
max-flows:
|
|
42
46
|
description: New tests to try (1-10; blank = .keepgreen.yml)
|
|
43
47
|
required: false
|
|
48
|
+
flows:
|
|
49
|
+
description: Optional. Flows to test, separated by ";" (blank = the AI picks)
|
|
50
|
+
required: false
|
|
44
51
|
# schedule:
|
|
45
52
|
# - cron: "0 6 * * 1" # every Monday 06:00 UTC
|
|
46
53
|
|
|
@@ -57,23 +64,53 @@ jobs:
|
|
|
57
64
|
timeout-minutes: 60
|
|
58
65
|
permissions:
|
|
59
66
|
contents: read
|
|
67
|
+
pull-requests: read
|
|
60
68
|
outputs:
|
|
61
69
|
written: ${{ steps.keepgreen.outputs.written }}
|
|
62
70
|
steps:
|
|
71
|
+
# A KeepGreen PR still waiting for review means the same flows would be
|
|
72
|
+
# planned again, so a scheduled run stops here. A manual run goes ahead.
|
|
73
|
+
- name: Skip if a KeepGreen PR is still open
|
|
74
|
+
id: open
|
|
75
|
+
if: github.event_name == 'schedule'
|
|
76
|
+
env:
|
|
77
|
+
GH_TOKEN: ${{ github.token }}
|
|
78
|
+
REPO: ${{ github.repository }}
|
|
79
|
+
run: |
|
|
80
|
+
n="$(gh pr list --repo "$REPO" --state open --json headRefName --jq '[.[] | select(.headRefName | startswith("keepgreen/explore-"))] | length')"
|
|
81
|
+
echo "count=$n" >> "$GITHUB_OUTPUT"
|
|
82
|
+
[ "$n" = "0" ] || echo "::notice::A KeepGreen PR is still open; review or close it first. Skipping this run."
|
|
63
83
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
84
|
+
if: steps.open.outputs.count == '0' || steps.open.outputs.count == ''
|
|
64
85
|
with:
|
|
65
86
|
persist-credentials: false
|
|
66
87
|
- uses: actions/setup-node@949feb2413d6458794dcd2491c4babbbce0c15c1 # v7.1.0
|
|
88
|
+
if: steps.open.outputs.count == '0' || steps.open.outputs.count == ''
|
|
67
89
|
with:
|
|
68
90
|
node-version: 22
|
|
69
91
|
# Your install steps (same as your test workflow):
|
|
70
|
-
-
|
|
71
|
-
|
|
92
|
+
- if: steps.open.outputs.count == '0' || steps.open.outputs.count == ''
|
|
93
|
+
run: npm ci
|
|
94
|
+
- if: steps.open.outputs.count == '0' || steps.open.outputs.count == ''
|
|
95
|
+
run: npx playwright install --with-deps chromium
|
|
96
|
+
- name: Flows you named
|
|
97
|
+
id: flows
|
|
98
|
+
if: inputs.flows != ''
|
|
99
|
+
env:
|
|
100
|
+
FLOWS: ${{ inputs.flows }}
|
|
101
|
+
run: |
|
|
102
|
+
{
|
|
103
|
+
echo 'list<<KEEPGREEN_EOF'
|
|
104
|
+
printf '%s\n' "$FLOWS" | tr ';' '\n'
|
|
105
|
+
echo 'KEEPGREEN_EOF'
|
|
106
|
+
} >> "$GITHUB_OUTPUT"
|
|
72
107
|
- id: keepgreen
|
|
108
|
+
if: steps.open.outputs.count == '0' || steps.open.outputs.count == ''
|
|
73
109
|
uses: xsignon-secure/keepgreen@v{{VERSION}}
|
|
74
110
|
with:
|
|
75
111
|
url: ${{ inputs.url }}
|
|
76
112
|
max-flows: ${{ inputs.max-flows }}
|
|
113
|
+
flows: ${{ steps.flows.outputs.list }}
|
|
77
114
|
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
78
115
|
openai-api-key: ${{ secrets.OPENAI_API_KEY }}
|
|
79
116
|
model: ${{ vars.AUTOHEAL_MODEL }}
|
|
@@ -83,7 +120,7 @@ jobs:
|
|
|
83
120
|
# price-in: "3" # USD per 1M tokens of your model, so max-usd is enforced
|
|
84
121
|
# price-out: "15"
|
|
85
122
|
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
86
|
-
if: steps.keepgreen.outputs.written != '0'
|
|
123
|
+
if: steps.keepgreen.outputs.written != '0' && steps.keepgreen.outputs.written != ''
|
|
87
124
|
with:
|
|
88
125
|
name: keepgreen-out
|
|
89
126
|
path: keepgreen-out/
|
|
@@ -100,6 +137,10 @@ jobs:
|
|
|
100
137
|
pull-requests: write
|
|
101
138
|
steps:
|
|
102
139
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
140
|
+
with:
|
|
141
|
+
# With KEEPGREEN_PR_TOKEN the push and the PR start your CI; the
|
|
142
|
+
# built-in token works too, but GitHub then runs no checks on the PR.
|
|
143
|
+
token: ${{ secrets.KEEPGREEN_PR_TOKEN || github.token }}
|
|
103
144
|
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
104
145
|
with:
|
|
105
146
|
name: keepgreen-out
|
|
@@ -114,9 +155,9 @@ jobs:
|
|
|
114
155
|
run: npx -y keepgreen@{{VERSION}} check-patch "$OUT/new-tests.patch"
|
|
115
156
|
- name: Open the pull request
|
|
116
157
|
env:
|
|
117
|
-
GH_TOKEN: ${{ github.token }}
|
|
158
|
+
GH_TOKEN: ${{ secrets.KEEPGREEN_PR_TOKEN || github.token }}
|
|
118
159
|
OUT: ${{ runner.temp }}/keepgreen-out
|
|
119
|
-
BRANCH: keepgreen/explore-${{ github.run_id }}
|
|
160
|
+
BRANCH: keepgreen/explore-${{ github.run_id }}-${{ github.run_attempt }}
|
|
120
161
|
run: |
|
|
121
162
|
git -c core.hooksPath=/dev/null apply --check "$OUT/new-tests.patch"
|
|
122
163
|
git -c core.hooksPath=/dev/null apply "$OUT/new-tests.patch"
|