ripplo 0.6.1 → 0.7.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/LICENSE.md ADDED
@@ -0,0 +1 @@
1
+ © Ripplo LLC. All rights reserved. Use is subject to Ripplo's [Terms of Service](https://ripplo.ai/terms).
package/README.md CHANGED
@@ -1,12 +1,29 @@
1
1
  # ripplo
2
2
 
3
- CLI for [Ripplo](https://ripplo.ai). Typed end-to-end tests with real backend state.
3
+ Describe how your app should behave. Ripplo proves it does.
4
4
 
5
- Run via `npx ripplo <command>` so you always pick up the latest version. No global install needed.
5
+ You declare your app's state model and user flows in TypeScript. Ripplo seeds real data, drives a real browser, and checks the result against the model: the UI you asserted on and the rows that should have changed underneath it.
6
6
 
7
- ## Recommended setup: Claude Code plugin
7
+ ```ts
8
+ export const createTask = test("Create a task", () => {
9
+ const { me, project } = ownedProject();
10
+ return {
11
+ given: [me, project],
12
+ steps: [
13
+ goto`/projects/${project.id}/tasks`.expect(visible(button("New"))),
14
+ click(button("New")).expect(visible(textbox("Title"))),
15
+ fill(textbox("Title"), "Buy milk"),
16
+ click(button("Create")).expect(Task.created({ title: "Buy milk", projectId: project.id })),
17
+ ],
18
+ };
19
+ });
20
+ ```
21
+
22
+ `ownedProject()` describes the starting state; Ripplo seeds it fresh for every run. `Task.created(...)` is checked against your actual database through a small engine you write once per entity.
8
23
 
9
- If you use Claude Code, this is the shortest path. The plugin handles auth, scaffolding, and adapter wiring, and adds hooks that keep tests in sync with code changes.
24
+ ## Setup with Claude Code
25
+
26
+ If you use Claude Code, this is the shortest path. The plugin handles auth, scaffolding, and adapter wiring, and adds hooks that keep tests in sync as the agent changes your code.
10
27
 
11
28
  ```
12
29
  /plugin marketplace add ripplo/claude-plugin
@@ -14,62 +31,74 @@ If you use Claude Code, this is the shortest path. The plugin handles auth, scaf
14
31
  /ripplo:setup
15
32
  ```
16
33
 
17
- That's it. Skip the rest of this README unless you want to know what `/ripplo:setup` is doing under the hood, or you're not on Claude Code.
34
+ Skip the rest of this section unless you want to know what `/ripplo:setup` does, or you're not on Claude Code.
18
35
 
19
- ## Manual setup
36
+ ## Setup by hand
20
37
 
21
- Three steps: authenticate, scaffold, mount the adapter in your app server.
38
+ Three steps: authenticate, scaffold, mount the engine adapter in your app server.
22
39
 
23
40
  ```sh
24
41
  npx ripplo auth login # device-code flow, opens a browser
25
42
  npx ripplo init # scaffolds .ripplo/ and writes RIPPLO_* env vars
26
43
  ```
27
44
 
28
- `ripplo init` is interactive. It creates `.ripplo/{index.ts, project.json, preconditions/, observers/, tests/}`, appends `RIPPLO_APP_URL`, `RIPPLO_ENGINE_URL`, and `RIPPLO_WEBHOOK_SECRET` to your env file, and installs `@ripplo/testing`.
45
+ `ripplo init` creates `.ripplo/` (entities, worlds, tests, plus a `project.json`), appends `RIPPLO_APP_URL`, `RIPPLO_ENGINE_URL`, and `RIPPLO_WEBHOOK_SECRET` to your env file, and installs [`@ripplo/testing`](https://www.npmjs.com/package/@ripplo/testing).
29
46
 
30
- Then mount the adapter in your app server. Next.js App Router:
47
+ Then mount the adapter. This is the one piece of code that lives in your app: a signed-webhook endpoint Ripplo calls to seed and read state, active only when you flip the env var.
31
48
 
32
49
  ```ts
33
- // app/ripplo/[action]/route.ts
34
- import { createNextHandler } from "@ripplo/testing/nextjs";
35
- import { engine } from "@/server/test/engine";
36
-
37
- export const PUT = createNextHandler({
38
- enabled: process.env.ENABLE_RIPPLO_TESTING === "true",
39
- engine,
40
- });
50
+ // Express
51
+ import { createEngineHandler } from "@ripplo/testing/express";
52
+ import { engine } from "./test/engine.js";
53
+
54
+ app.use(
55
+ "/ripplo",
56
+ createEngineHandler({ enabled: process.env.ENABLE_RIPPLO_TESTING === "true", engine }),
57
+ );
41
58
  ```
42
59
 
43
- For Express, Fastify, Hono, Koa, NestJS, or Elysia, see [`@ripplo/testing`](https://www.npmjs.com/package/@ripplo/testing).
60
+ `engine` is where you implement `seed` and `read` for each entity you declared; TypeScript flags any entity you forgot. More framework adapters are coming; any server that can mount an Express router works today.
61
+
62
+ Last, preload [`@ripplo/instrument`](https://www.npmjs.com/package/@ripplo/instrument) in your dev server so test runs capture your backend spans alongside browser actions:
44
63
 
45
- `engine` is what you write in `src/test/engine.ts` to provide the implementations for the preconditions and observers you defined in `.ripplo/`. The DSL reference covers it.
64
+ ```sh
65
+ node --import @ripplo/instrument server.js # or NODE_OPTIONS="--import @ripplo/instrument" next dev
66
+ ```
67
+
68
+ It exports spans to the local daemon during runs and stays dormant otherwise, so it's safe to leave in your dev script permanently.
46
69
 
47
70
  ## Running tests
48
71
 
49
- In one terminal, start the local executor:
72
+ Start the daemon in one terminal and leave it running next to your dev server:
50
73
 
51
74
  ```sh
52
- npx ripplo watch
75
+ npx ripplo daemon
53
76
  ```
54
77
 
55
- Leave it running alongside your dev server. It subscribes to run requests and drives Playwright against your local app.
56
-
57
- In another, run tests:
78
+ It keeps a warm browser pool and executes runs in parallel as they come in. Then:
58
79
 
59
80
  ```sh
60
- npx ripplo run # scope + dirty tests
81
+ npx ripplo run # tests in scope + tests affected by your changes
61
82
  npx ripplo run --all # everything
62
- npx ripplo run my-test # by id
83
+ npx ripplo run my-test # one test by id
63
84
  ```
64
85
 
65
- Commit `.ripplo/ripplo.lock`. The Ripplo server reads it on every push webhook; `ripplo compile --check` in a pre-commit hook keeps it fresh.
86
+ `run` connects to the daemon and streams results; if a daemon is absent it starts one for you.
87
+
88
+ ## The lockfile
89
+
90
+ `.ripplo/` compiles to `.ripplo/ripplo.lock`. Commit it. The Ripplo server reads the lockfile on every push, so your dashboard and CI always reflect what's actually in the branch. `npx ripplo compile --check` in a pre-commit hook (installed by setup) keeps it fresh.
66
91
 
67
92
  ## Worktrees
68
93
 
69
- Ripplo is built for parallel feature work via `git worktree`. Each worktree gets its own dev session, scope, debug artifacts, and lockfile checkout your auth token, projectId, and webhook secret are shared globally, so a fresh worktree needs no re-auth or re-init. Spin up as many as you want and run them concurrently.
94
+ Ripplo is built for parallel feature work via `git worktree`. Each worktree gets its own dev session, scope, debug artifacts, and lockfile checkout, while auth and project config are shared globally, so a fresh worktree is ready to run as-is.
70
95
 
71
- Two things to know: env files are usually gitignored, so copy your `.env.local` into the new worktree (or point `envFiles` in `.ripplo/project.json` at a shared file outside the tree), and pick a distinct dev-server port update both `RIPPLO_APP_URL` and `RIPPLO_ENGINE_URL` to match. `ripplo doctor` flags both.
96
+ Two things to handle per worktree: copy your gitignored env file in (or point `envFiles` in `.ripplo/project.json` at a shared path outside the tree), and pick a distinct dev-server port, updating `RIPPLO_APP_URL` and `RIPPLO_ENGINE_URL` to match. `ripplo doctor` flags both if you forget.
72
97
 
73
98
  ## Other commands
74
99
 
75
- `npx ripplo --help` lists everything. The ones you'll use beyond setup: `lint` (compile + typecheck), `doctor` (auth/env/lockfile health), `scope` (manage what the current session is testing), `flake-detect` (run a test in parallel N times).
100
+ `npx ripplo --help` lists everything. Beyond setup you'll mostly use `lint` (compile + typecheck your `.ripplo/`), `doctor` (auth, env, and lockfile health), and `scope` (manage which flows the current session is responsible for).
101
+
102
+ ## License
103
+
104
+ © Ripplo LLC. All rights reserved. Use is subject to Ripplo's [Terms of Service](https://ripplo.ai/terms).
@@ -0,0 +1 @@
1
+ "use strict";(()=>{var s=globalThis.fetch;function t(e){return Array.from(crypto.getRandomValues(new Uint8Array(e)),r=>r.toString(16).padStart(2,"0")).join("")}globalThis.fetch=(e,r)=>{let o=r?.headers??(e instanceof Request?e.headers:void 0),n=new Headers(o);n.has("traceparent")||n.set("traceparent",`00-${t(16)}-${t(8)}-01`);let a=globalThis.__ripploRunId;return a!=null&&!n.has("baggage")&&n.set("baggage",`ripplo.run=${encodeURIComponent(a)}`),s(e,{...r,headers:n})};})();