@ovrdev/cli 0.1.0-alpha.16

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/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # Override (`ovr`)
2
+
3
+ **Development environments as code.** One command boots your whole multi-repo local stack —
4
+ every service, every port, every worktree — wired together and health-gated from a single typed
5
+ config.
6
+
7
+ > **Agents drive fast; don't let them crash.** Multiple agents (or people) work the same project in
8
+ > parallel, each in its own isolated workspace, without fighting over ports, hand-managing
9
+ > worktrees, or stepping on each other. The tool handles it.
10
+
11
+ > ⚠️ Alpha. APIs may still shift between `0.1.0-alpha.*` releases.
12
+
13
+ ## Quickstart
14
+
15
+ The fastest way to see it is the [ovr-guestbook](https://github.com/msanchezdev/ovr-guestbook) demo —
16
+ two zero-dependency services booted by one command:
17
+
18
+ ```bash
19
+ git clone https://github.com/msanchezdev/ovr-guestbook && cd ovr-guestbook
20
+ npm install
21
+ npx ovr run
22
+ ```
23
+
24
+ Open the `web` URL it prints, then quit (`qq`) and `npx ovr run` again — your data is still there.
25
+
26
+ ### In your own repo
27
+
28
+ ```bash
29
+ npm i -D @ovrdev/cli
30
+ ```
31
+
32
+ Add an `ovr.config.mts`:
33
+
34
+ ```ts
35
+ import { defineConfig, waitHttp } from "@ovrdev/cli"
36
+
37
+ export default defineConfig(({ workspace, kind }) => ({
38
+ services: {
39
+ api: kind.shell({
40
+ prepare: async ({ ports }) => ({ port: await ports.alloc() }), // a free port, sticky
41
+ command: ({ port }) => `PORT=${port} node server.mjs`,
42
+ exports: ({ port }) => ({ url: `http://localhost:${port}`, port }),
43
+ ready: ({ port }) => waitHttp(`http://localhost:${port}/health`),
44
+ }),
45
+ web: kind.shell({
46
+ prepare: async ({ ports }) => ({ port: await ports.alloc() }),
47
+ command: ({ port }) => `PORT=${port} vite`,
48
+ env: { API_URL: workspace.services.api.url }, // auto-wired to api's real port
49
+ }),
50
+ },
51
+ }))
52
+ ```
53
+
54
+ Then `npx ovr run`. In a fresh folder ovr auto-onboards it — no setup step.
55
+
56
+ ## Concepts
57
+
58
+ - **workspace** — a named, runnable config: which repos, at which worktrees, with which env. A
59
+ **fork** is just another workspace that shares repos on new branches (isolation for a ticket or
60
+ an agent). **repos** feed a workspace; a base repo runs **in place** (your folder), fork worktrees
61
+ live under the ovr root.
62
+ - **services & kinds** — a service is declared with a *kind*: `kind.shell` (a process) builtin, plus
63
+ plugin kinds (`kind.docker.*`, supabase, …). `prepare(ctx)` reserves resources and returns a
64
+ "bag"; `command`/`env`/`exports` are pure functions of it.
65
+ - **zero fixed ports** — every service allocates its own port; cross-service **refs**
66
+ (`workspace.services.x.url`, `workspace.repos["y"].services.z.url`) resolve to the real
67
+ allocations, known before anything starts. Refs carry any JSON value.
68
+ - **readiness** — `ready: waitHttp(...)` gates dependents; `waitFor: [x.ready]` for explicit edges.
69
+ - **provisioning helpers** in `prepare` — everything sticky per environment: `ports`, `secrets`
70
+ (generated passwords/tokens), `paths` (data dirs that survive restarts), `scratch` (ephemeral),
71
+ `keys` (crypto keypairs → `.jwks()`/`.ssh()`), `files.render` (templated config), `once`
72
+ (run-once provisioning), `env` (fail-fast base-env access).
73
+ - **shared services** — `ovr run` runs every repo with a config and **reuses** anything already up
74
+ (`ovr ps` to see across sessions); a shared service stays up until its last consumer leaves
75
+ (`ovr stop` to force it).
76
+ - **discovery** — a service pushes to another: `x.announce({ redirect: url })`; the provider
77
+ reconciles the live set via `discovery: (anns) => …` (allowlists, CORS, redirect URIs).
78
+ - **env sources** — base env from plugins: `dotenv()` builtin, `@ovrdev/plugin-infisical`,
79
+ … layered per repo. `ovr run --env <name>` picks the environment (sticky per workspace).
80
+ - **interactive actions** — TUI actions with typed input forms: `action.session`/`action.fn`/
81
+ `action.handover` + `input.*`; `login: true` runs through your shell profile.
82
+
83
+ ## CLI
84
+
85
+ ```
86
+ ovr run [-w <workspace>] [--env <name>] boot the workspace (auto-onboards a fresh repo)
87
+ ovr ps services running across all sessions
88
+ ovr stop <name|--all> stop running services
89
+ ovr workspace new|ls|use|rm (alias: ws) manage workspaces
90
+ ovr fork <name> [--repos a,b|--all] fork a workspace, pick repos to materialize
91
+ ovr repo add|override|rm manage a workspace's repos
92
+ ```
93
+
94
+ ## Packages
95
+
96
+ | package | what |
97
+ | --- | --- |
98
+ | [`@ovrdev/cli`](https://npmjs.com/package/@ovrdev/cli) | the framework + `ovr` CLI + TUI |
99
+ | [`@ovrdev/plugin-portless`](https://npmjs.com/package/@ovrdev/plugin-portless) | stable `https://*.localhost` URLs |
100
+ | [`@ovrdev/plugin-docker`](https://npmjs.com/package/@ovrdev/plugin-docker) | compose / container kinds |
101
+ | [`@ovrdev/plugin-infisical`](https://npmjs.com/package/@ovrdev/plugin-infisical) | Infisical hosted env source |
102
+ | [`@ovrdev/plugin-supabase`](https://npmjs.com/package/@ovrdev/plugin-supabase) | local Supabase stack kind (`kind.supabase.stack`) |
103
+ | [`@ovrdev/plugin-js`](https://npmjs.com/package/@ovrdev/plugin-js) | ensure deps + run package scripts (`node()`) |
104
+ | [`@ovrdev/plugin-postgres`](https://npmjs.com/package/@ovrdev/plugin-postgres) | local Postgres kind + SQL action builders |
105
+
106
+ Built into the cli (no extra install): `kind.shell` — the one universal service kind. Everything
107
+ heavier (docker, Supabase, Postgres, …) lives in a plugin, so the core stays primitive.
108
+
109
+ ## License
110
+
111
+ TBD.