@tourik/yeet 0.1.0-rc.1 → 0.1.0-rc.2
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 +144 -0
- package/package.json +5 -5
package/README.md
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# yeet
|
|
2
|
+
|
|
3
|
+
yeet hosts small apps that AI agents build, deploy and check on their own. An app is one folder
|
|
4
|
+
of TypeScript: a server with a database, sign-in and live queries, and a React page. This package
|
|
5
|
+
holds the `yeet` command and the SDK that apps import.
|
|
6
|
+
|
|
7
|
+
## Start an app
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npx @tourik/yeet init notes
|
|
11
|
+
cd notes
|
|
12
|
+
npx yeet dev
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
- `yeet init notes` creates the folder `notes` with a small todo app in it: a table, a search, a
|
|
16
|
+
query, two mutations and a React page. It installs the app's npm packages and starts a git
|
|
17
|
+
repository. `notes` is also the app's id, which names it on the server.
|
|
18
|
+
- The app's `package.json` holds this package under the name `yeet`. So the app imports
|
|
19
|
+
`yeet/server` and `yeet/react`, and `npx yeet` runs the command.
|
|
20
|
+
- `yeet dev` serves the app at the address it prints, and reloads on every save. It starts on an
|
|
21
|
+
empty database and deletes it when it stops.
|
|
22
|
+
|
|
23
|
+
Then open your coding agent in the folder and describe the app you want. `yeet init` wrote
|
|
24
|
+
`AGENTS.md`, which tells the agent how to write, run, check and deploy a yeet app, and a
|
|
25
|
+
`CLAUDE.md` that points Claude Code at it. `npx yeet agents-md` rewrites yeet's part of
|
|
26
|
+
`AGENTS.md` after an update.
|
|
27
|
+
|
|
28
|
+
Without a name, `yeet init` starts the app in the current folder, under the folder's name. It
|
|
29
|
+
keeps every file that is already there. If it kept a `package.json`, it prints the `npm install`
|
|
30
|
+
command for the packages that file lacks.
|
|
31
|
+
|
|
32
|
+
## What an app looks like
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
server/index.ts the tables, and the functions that clients call
|
|
36
|
+
client/ the web page: index.html, index.tsx, index.css, public/
|
|
37
|
+
shared/ TypeScript that both import
|
|
38
|
+
yeet.json the app's id
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The server, in `server/index.ts`:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import { defineSchema, defineTable, mutation, query, v } from "yeet/server";
|
|
45
|
+
|
|
46
|
+
export default defineSchema({
|
|
47
|
+
todos: defineTable({ owner: v.union(v.string(), v.null()), text: v.string() })
|
|
48
|
+
.index("by_owner", ["owner"]),
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
export const todos = query({
|
|
52
|
+
handler: (ctx) =>
|
|
53
|
+
ctx.db.query("todos").withIndex("by_owner", (q) => q.eq("owner", ctx.auth.userId)).collect(),
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export const addTodo = mutation({
|
|
57
|
+
args: { text: v.string() },
|
|
58
|
+
handler: (ctx, { text }) => ctx.db.insert("todos", { owner: ctx.auth.userId, text }),
|
|
59
|
+
});
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The page, in `client/index.tsx`:
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { createRoot } from "react-dom/client";
|
|
66
|
+
import { useMutation, useQuery, YeetProvider } from "yeet/react";
|
|
67
|
+
|
|
68
|
+
declare module "yeet/react" {
|
|
69
|
+
interface Register {
|
|
70
|
+
server: typeof import("../server/index");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function Todos() {
|
|
75
|
+
const todos = useQuery("todos");
|
|
76
|
+
const addTodo = useMutation("addTodo");
|
|
77
|
+
if (todos === undefined) return <p>Loading…</p>;
|
|
78
|
+
return (
|
|
79
|
+
<>
|
|
80
|
+
<button onClick={() => addTodo({ text: "Buy milk" })}>Add</button>
|
|
81
|
+
<ul>
|
|
82
|
+
{todos.map((todo) => (
|
|
83
|
+
<li key={todo._id}>{String(todo.text)}</li>
|
|
84
|
+
))}
|
|
85
|
+
</ul>
|
|
86
|
+
</>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
createRoot(document.getElementById("root")!).render(
|
|
91
|
+
<YeetProvider>
|
|
92
|
+
<Todos />
|
|
93
|
+
</YeetProvider>,
|
|
94
|
+
);
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
`useQuery` keeps its result up to date: when a mutation changes what a query read, every open
|
|
98
|
+
page gets the new result.
|
|
99
|
+
|
|
100
|
+
## The server API
|
|
101
|
+
|
|
102
|
+
The API resembles Convex's, but it is its own. `server.d.ts` in this package declares all of it.
|
|
103
|
+
|
|
104
|
+
- A `query` only reads. A `mutation` reads and writes in one transaction. An `action` can `fetch`
|
|
105
|
+
and wait, and reaches the data through `ctx.runQuery` and `ctx.runMutation`.
|
|
106
|
+
- `ctx.auth.userId` is the signed-in user's id, or `null`.
|
|
107
|
+
- Tables can have indexes and text search. Functions can run later (`ctx.scheduler`) or on a
|
|
108
|
+
timetable (`cronJobs()`). An app can answer plain HTTP under `/api/` (`httpRouter()`).
|
|
109
|
+
- Server code imports only `yeet/server` and its own files: no npm package. It runs in neither
|
|
110
|
+
Node nor a browser, so `crypto`, `TextEncoder`, `btoa` and `Buffer` do not exist. Client code
|
|
111
|
+
can import npm packages.
|
|
112
|
+
- There is no `v.any()`, `.filter()`, `.paginate()` or `ctx.auth.getUserIdentity()`: `yeet check`
|
|
113
|
+
reports each use with its line.
|
|
114
|
+
|
|
115
|
+
## Commands
|
|
116
|
+
|
|
117
|
+
Every command takes `--json`, and `npx yeet --help` lists them all.
|
|
118
|
+
|
|
119
|
+
| Command | What it does |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `yeet init [name]` | Starts a new app, in the new folder `<name>` or in the current one |
|
|
122
|
+
| `yeet dev` | Serves the app locally, on an empty database |
|
|
123
|
+
| `yeet run <name> '<json args>' --port <port>` | Calls a function on a running `yeet dev` |
|
|
124
|
+
| `yeet logs --port <port> --errors` | Shows the calls that failed, with their arguments |
|
|
125
|
+
| `yeet check` | Checks the types, the build, and the new code on a copy of the live data |
|
|
126
|
+
| `yeet deploy` | Builds the app and makes it live |
|
|
127
|
+
| `yeet deploy --preview <name>` | Serves the code at its own address, on a copy of the live data |
|
|
128
|
+
| `yeet status`, `yeet logs` | Show the deployed app |
|
|
129
|
+
| `yeet rollback` | Brings back the previous deploy |
|
|
130
|
+
| `yeet login` | Logs in through the browser |
|
|
131
|
+
| `yeet mcp` | Serves the main commands to an agent as MCP tools |
|
|
132
|
+
|
|
133
|
+
## Deploying
|
|
134
|
+
|
|
135
|
+
- Without a login, `npx yeet deploy` creates an unclaimed app at a random address under
|
|
136
|
+
`yeet.tourik.dev`. It expires 7 days after its last deploy, and it cannot `fetch` or keep
|
|
137
|
+
secrets.
|
|
138
|
+
- With an account, `npx yeet login` and then `npx yeet deploy` serve the app at
|
|
139
|
+
`https://<id>.yeet.tourik.dev`. `npx yeet claim` gives an unclaimed app to your account.
|
|
140
|
+
- Each deployed app has its own database. `npx yeet access` shows and sets who may sign in to it.
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tourik/yeet",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.2",
|
|
4
4
|
"description": "Small apps with a database, sign-in and live updates: the yeet command and its SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"exports": {
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"yeet": "bin/yeet.js"
|
|
21
21
|
},
|
|
22
22
|
"optionalDependencies": {
|
|
23
|
-
"@tourik/yeet-linux-x64": "0.1.0-rc.
|
|
24
|
-
"@tourik/yeet-linux-arm64": "0.1.0-rc.
|
|
25
|
-
"@tourik/yeet-darwin-arm64": "0.1.0-rc.
|
|
26
|
-
"@tourik/yeet-darwin-x64": "0.1.0-rc.
|
|
23
|
+
"@tourik/yeet-linux-x64": "0.1.0-rc.2",
|
|
24
|
+
"@tourik/yeet-linux-arm64": "0.1.0-rc.2",
|
|
25
|
+
"@tourik/yeet-darwin-arm64": "0.1.0-rc.2",
|
|
26
|
+
"@tourik/yeet-darwin-x64": "0.1.0-rc.2"
|
|
27
27
|
}
|
|
28
28
|
}
|